mirror of
https://github.com/holub/mame
synced 2025-06-06 04:43:45 +03:00
Truthtable cleanup. (nw)
This commit is contained in:
parent
7a302cebb3
commit
b77ab1bdef
@ -54,8 +54,8 @@ namespace netlist
|
||||
NETLIB_SUB(74279A) m_4;
|
||||
};
|
||||
|
||||
nld_74279A::truthtable_t nld_74279A::m_ttbl(3,1,0);
|
||||
nld_74279B::truthtable_t nld_74279B::m_ttbl(4,1,0);
|
||||
nld_74279A::truthtable_t nld_74279A::m_ttbl;
|
||||
nld_74279B::truthtable_t nld_74279B::m_ttbl;
|
||||
|
||||
const char *nld_74279A::m_desc[] = {
|
||||
"S,R,_Q|Q",
|
||||
|
@ -106,8 +106,8 @@ namespace netlist
|
||||
NETLIB_SUB(9312) m_sub;
|
||||
};
|
||||
|
||||
#if (1 && USE_TRUTHTABLE)
|
||||
nld_9312::truthtable_t nld_9312::m_ttbl(12,2,0);
|
||||
#if (USE_TRUTHTABLE)
|
||||
nld_9312::truthtable_t nld_9312::m_ttbl;
|
||||
|
||||
/* FIXME: Data changes are propagating faster than changing selects A,B,C
|
||||
* Please refer to data sheet.
|
||||
|
@ -21,7 +21,7 @@ namespace netlist
|
||||
netlist_factory_truthtable_t(const pstring &name, const pstring &classname,
|
||||
const pstring &def_param)
|
||||
: netlist_base_factory_truthtable_t(name, classname, def_param)
|
||||
, m_ttbl(m_NI, m_NO, has_state){ }
|
||||
{ }
|
||||
|
||||
plib::owned_ptr<device_t> Create(netlist_t &anetlist, const pstring &name) override
|
||||
{
|
||||
@ -32,37 +32,36 @@ namespace netlist
|
||||
typename nld_truthtable_t<m_NI, m_NO, has_state>::truthtable_t m_ttbl;
|
||||
};
|
||||
|
||||
unsigned truthtable_desc_t::count_bits(UINT32 v)
|
||||
static const uint64_t all_set = ~((uint64_t) 0);
|
||||
|
||||
unsigned truthtable_desc_t::count_bits(uint64_t v)
|
||||
{
|
||||
unsigned ret = 0;
|
||||
uint64_t ret = 0;
|
||||
for (; v != 0; v = v >> 1)
|
||||
{
|
||||
if (v & 1)
|
||||
ret++;
|
||||
ret += (v & 1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
UINT32 truthtable_desc_t::set_bits(UINT32 v, UINT32 b)
|
||||
uint64_t truthtable_desc_t::set_bits(uint64_t v, uint64_t b)
|
||||
{
|
||||
UINT32 ret = 0;
|
||||
int i = 0;
|
||||
for (; v != 0; v = v >> 1)
|
||||
uint64_t ret = 0;
|
||||
for (size_t i = 0; v != 0; v = v >> 1, ++i)
|
||||
{
|
||||
if (v & 1)
|
||||
{
|
||||
ret |= ((b&1)<<i);
|
||||
b = b >> 1;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
UINT32 truthtable_desc_t::get_ignored_simple(UINT32 i)
|
||||
uint64_t truthtable_desc_t::get_ignored_simple(uint64_t i)
|
||||
{
|
||||
UINT32 m_enable = 0;
|
||||
for (UINT32 j=0; j<m_size; j++)
|
||||
uint64_t m_enable = 0;
|
||||
for (size_t j=0; j<m_size; j++)
|
||||
{
|
||||
if (m_outs[j] != m_outs[i])
|
||||
{
|
||||
@ -72,49 +71,49 @@ UINT32 truthtable_desc_t::get_ignored_simple(UINT32 i)
|
||||
return m_enable ^ (m_size - 1);
|
||||
}
|
||||
|
||||
UINT32 truthtable_desc_t::get_ignored_extended(UINT32 i)
|
||||
uint64_t truthtable_desc_t::get_ignored_extended(uint64_t state)
|
||||
{
|
||||
// Determine all inputs which may be ignored ...
|
||||
UINT32 nign = 0;
|
||||
uint64_t ignore = 0;
|
||||
for (unsigned j=0; j<m_NI; j++)
|
||||
{
|
||||
if (m_outs[i] == m_outs[i ^ (1 << j)])
|
||||
nign |= (1<<j);
|
||||
if (m_outs[state] == m_outs[state ^ (1 << j)])
|
||||
ignore |= (1<<j);
|
||||
}
|
||||
/* Check all permutations of ign
|
||||
* We have to remove those where the ignored inputs
|
||||
* may change the output
|
||||
*/
|
||||
UINT32 bits = (1<<count_bits(nign));
|
||||
std::vector<int> t(bits);
|
||||
uint64_t bits = (1<<count_bits(ignore));
|
||||
std::vector<bool> t(bits);
|
||||
|
||||
for (UINT32 j=1; j<bits; j++)
|
||||
for (size_t j=1; j<bits; j++)
|
||||
{
|
||||
UINT32 tign = set_bits(nign, j);
|
||||
uint64_t tign = set_bits(ignore, j);
|
||||
t[j] = 0;
|
||||
UINT32 bitsk=(1<<count_bits(tign));
|
||||
for (UINT32 k=0; k<bitsk; k++)
|
||||
uint64_t bitsk=(1<<count_bits(tign));
|
||||
for (size_t k=0; k<bitsk; k++)
|
||||
{
|
||||
UINT32 b=set_bits(tign, k);
|
||||
if (m_outs[i] != m_outs[(i & ~tign) | b])
|
||||
uint64_t b=set_bits(tign, k);
|
||||
if (m_outs[state] != m_outs[(state & ~tign) | b])
|
||||
{
|
||||
t[j] = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
UINT32 jb=0;
|
||||
UINT32 jm=0;
|
||||
size_t jb=0;
|
||||
size_t jm=0;
|
||||
for (UINT32 j=1; j<bits; j++)
|
||||
{
|
||||
unsigned nb = count_bits(j);
|
||||
if ((t[j] == 0)&& (nb>jb))
|
||||
size_t nb = count_bits(j);
|
||||
if ((t[j] == 0) && (nb>jb))
|
||||
{
|
||||
jb = nb;
|
||||
jm = j;
|
||||
}
|
||||
}
|
||||
return set_bits(nign, jm);
|
||||
return set_bits(ignore, jm);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -122,7 +121,7 @@ UINT32 truthtable_desc_t::get_ignored_extended(UINT32 i)
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
void truthtable_desc_t::help(unsigned cur, plib::pstring_vector_t list,
|
||||
UINT64 state,UINT16 val, std::vector<UINT8> &timing_index)
|
||||
uint64_t state, uint64_t val, std::vector<uint8_t> &timing_index)
|
||||
{
|
||||
pstring elem = list[cur].trim();
|
||||
int start = 0;
|
||||
@ -156,10 +155,10 @@ void truthtable_desc_t::help(unsigned cur, plib::pstring_vector_t list,
|
||||
else
|
||||
{
|
||||
// cutoff previous inputs and outputs for ignore
|
||||
if (m_outs[nstate] != ~0U && m_outs[nstate] != val)
|
||||
if (m_outs[nstate] != m_outs.adjust(all_set) && m_outs[nstate] != val)
|
||||
fatalerror_e(plib::pfmt("Error in truthtable: State {1} already set, {2} != {3}\n")
|
||||
.x(nstate,"04")(m_outs[nstate])(val) );
|
||||
m_outs[nstate] = val;
|
||||
m_outs.set(nstate, val);
|
||||
for (unsigned j=0; j<m_NO; j++)
|
||||
m_timing[nstate * m_NO + j] = timing_index[j];
|
||||
}
|
||||
@ -179,7 +178,7 @@ void truthtable_desc_t::setup(const plib::pstring_vector_t &truthtable, UINT32 d
|
||||
line++;
|
||||
|
||||
for (unsigned j=0; j < m_size; j++)
|
||||
m_outs[j] = ~0L;
|
||||
m_outs.set(j, all_set);
|
||||
|
||||
for (int j=0; j < 16; j++)
|
||||
m_timing_nt[j] = netlist_time::zero();
|
||||
@ -223,11 +222,11 @@ void truthtable_desc_t::setup(const plib::pstring_vector_t &truthtable, UINT32 d
|
||||
}
|
||||
|
||||
// determine ignore
|
||||
std::vector<UINT32> ign(m_size, ~0U);
|
||||
std::vector<uint64_t> ign(m_size, all_set);
|
||||
|
||||
for (UINT32 i=0; i<m_size; i++)
|
||||
for (size_t i=0; i<m_size; i++)
|
||||
{
|
||||
if (ign[i] == ~0U)
|
||||
if (ign[i] == all_set)
|
||||
{
|
||||
int tign;
|
||||
if (0)
|
||||
@ -241,20 +240,20 @@ void truthtable_desc_t::setup(const plib::pstring_vector_t &truthtable, UINT32 d
|
||||
|
||||
ign[i] = tign;
|
||||
/* don't need to recalculate similar ones */
|
||||
UINT32 bitsk=(1<<count_bits(tign));
|
||||
for (UINT32 k=0; k<bitsk; k++)
|
||||
uint64_t bitsk=(1<<count_bits(tign));
|
||||
for (uint64_t k=0; k<bitsk; k++)
|
||||
{
|
||||
UINT32 b=set_bits(tign, k);
|
||||
uint64_t b=set_bits(tign, k);
|
||||
ign[(i & ~tign) | b] = tign;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (UINT32 i=0; i<m_size; i++)
|
||||
for (size_t i=0; i<m_size; i++)
|
||||
{
|
||||
if (m_outs[i] == ~0U)
|
||||
if (m_outs[i] == m_outs.adjust(all_set))
|
||||
throw fatalerror_e(plib::pfmt("truthtable: found element not set {1}\n").x(i) );
|
||||
m_outs[i] |= ((ign[i] & ~disabled_ignore) << m_NO);
|
||||
m_outs.set(i, m_outs[i] | ((ign[i] & ~disabled_ignore) << m_NO));;
|
||||
}
|
||||
*m_initialized = true;
|
||||
|
||||
|
@ -52,656 +52,372 @@ namespace netlist
|
||||
namespace devices
|
||||
{
|
||||
|
||||
class dyn_bitset
|
||||
template<unsigned bits>
|
||||
struct need_bytes_for_bits
|
||||
{
|
||||
dyn_bitset(const std::size_t size)
|
||||
: m_size(size)
|
||||
, m_data_size((m_data_bits - 1 + size) / m_data_bits)
|
||||
enum { value =
|
||||
bits <= 8 ? 1 :
|
||||
bits <= 16 ? 2 :
|
||||
bits <= 32 ? 4 :
|
||||
8
|
||||
};
|
||||
};
|
||||
|
||||
template<unsigned bits> struct uint_for_size;
|
||||
template<> struct uint_for_size<1> { typedef uint8_t type; };
|
||||
template<> struct uint_for_size<2> { typedef uint16_t type; };
|
||||
template<> struct uint_for_size<4> { typedef uint32_t type; };
|
||||
template<> struct uint_for_size<8> { typedef uint64_t type; };
|
||||
|
||||
struct packed_int
|
||||
{
|
||||
template<typename C>
|
||||
packed_int(C *data)
|
||||
: m_data(data)
|
||||
, m_size(sizeof(C))
|
||||
{}
|
||||
|
||||
void set(const size_t pos, const uint64_t val)
|
||||
{
|
||||
m_d = new data_type[m_data_size];
|
||||
for (std::size_t i=0; i<m_data_size; i++)
|
||||
m_d[i] = 0;
|
||||
switch (m_size)
|
||||
{
|
||||
case 1: ((uint8_t *) m_data)[pos] = val; break;
|
||||
case 2: ((uint16_t *) m_data)[pos] = val; break;
|
||||
case 4: ((uint32_t *) m_data)[pos] = val; break;
|
||||
case 8: ((uint64_t *) m_data)[pos] = val; break;
|
||||
default: { }
|
||||
}
|
||||
}
|
||||
|
||||
~dyn_bitset()
|
||||
UINT64 operator[] (size_t pos) const
|
||||
{
|
||||
delete [] m_d;
|
||||
switch (m_size)
|
||||
{
|
||||
case 1: return ((uint8_t *) m_data)[pos]; break;
|
||||
case 2: return ((uint16_t *) m_data)[pos]; break;
|
||||
case 4: return ((uint32_t *) m_data)[pos]; break;
|
||||
case 8: return ((uint64_t *) m_data)[pos]; break;
|
||||
default:
|
||||
return 0; //should never happen
|
||||
}
|
||||
}
|
||||
|
||||
void set()
|
||||
uint64_t adjust(uint64_t val) const
|
||||
{
|
||||
switch (m_size)
|
||||
{
|
||||
case 1: return ((uint8_t) val); break;
|
||||
case 2: return ((uint16_t) val); break;
|
||||
case 4: return ((uint32_t) val); break;
|
||||
case 8: return ((uint64_t) val); break;
|
||||
default:
|
||||
return 0; //should never happen
|
||||
}
|
||||
}
|
||||
private:
|
||||
void *m_data;
|
||||
size_t m_size;
|
||||
};
|
||||
|
||||
struct truthtable_desc_t
|
||||
{
|
||||
truthtable_desc_t(int NO, int NI, int has_state, bool *initialized,
|
||||
packed_int outs, UINT8 *timing, netlist_time *timing_nt)
|
||||
: m_NO(NO), m_NI(NI), /*m_has_state(has_state),*/ m_initialized(initialized),
|
||||
m_outs(outs), m_timing(timing), m_timing_nt(timing_nt),
|
||||
m_num_bits(m_NI + has_state * (m_NI + m_NO)),
|
||||
m_size(1 << (m_num_bits))
|
||||
{
|
||||
for (std::size_t i=0; i<m_data_size; i++)
|
||||
m_d[i] = ~0;
|
||||
}
|
||||
|
||||
void set(std::size_t pos)
|
||||
{
|
||||
const std::size_t bytepos = (pos >> m_data_shift);
|
||||
const std::size_t bitpos = (pos & m_data_mask);
|
||||
m_d[bytepos] |= (1 << bitpos);
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
for (std::size_t i=0; i<m_data_size; i++)
|
||||
m_d[i] = 0;
|
||||
}
|
||||
|
||||
void reset(std::size_t pos)
|
||||
{
|
||||
const std::size_t bytepos = (pos >> m_data_shift);
|
||||
const std::size_t bitpos = (pos & m_data_mask);
|
||||
m_d[bytepos] &= ~(1 << bitpos);
|
||||
}
|
||||
|
||||
bool operator[] (size_t pos) const
|
||||
{
|
||||
const std::size_t bytepos = (pos >> m_data_shift);
|
||||
const std::size_t bitpos = (pos & m_data_mask);
|
||||
return (m_d[bytepos] >> bitpos) & 1;
|
||||
}
|
||||
void setup(const plib::pstring_vector_t &desc, UINT32 disabled_ignore);
|
||||
|
||||
private:
|
||||
typedef std::uint64_t data_type;
|
||||
static constexpr std::size_t m_data_bits = sizeof(data_type) * 8;
|
||||
static constexpr std::size_t m_data_shift = 6;
|
||||
static constexpr std::size_t m_data_mask = (1<< m_data_shift) - 1;
|
||||
std::size_t m_size;
|
||||
std::size_t m_data_size;
|
||||
data_type *m_d;
|
||||
void help(unsigned cur, plib::pstring_vector_t list,
|
||||
uint64_t state, uint64_t val, std::vector<uint8_t> &timing_index);
|
||||
static unsigned count_bits(uint64_t v);
|
||||
static uint64_t set_bits(uint64_t v, uint64_t b);
|
||||
uint64_t get_ignored_simple(uint64_t i);
|
||||
uint64_t get_ignored_extended(uint64_t i);
|
||||
|
||||
unsigned m_NO;
|
||||
unsigned m_NI;
|
||||
bool *m_initialized;
|
||||
packed_int m_outs;
|
||||
uint8_t *m_timing;
|
||||
netlist_time *m_timing_nt;
|
||||
|
||||
/* additional values */
|
||||
|
||||
const std::size_t m_num_bits;
|
||||
const std::size_t m_size;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#if 0
|
||||
static inline UINT32 remove_first_bit(UINT32 v)
|
||||
{
|
||||
for (int i=0; i<32; i++)
|
||||
if (v & (1<<i))
|
||||
return v & ~(1<<i);
|
||||
return v;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct truthtable_desc_t
|
||||
{
|
||||
truthtable_desc_t(int NO, int NI, int has_state, bool *initialized,
|
||||
UINT16 *outs, UINT8 *timing, netlist_time *timing_nt)
|
||||
: m_NO(NO), m_NI(NI), /*m_has_state(has_state),*/ m_initialized(initialized),
|
||||
m_outs(outs), m_timing(timing), m_timing_nt(timing_nt),
|
||||
m_num_bits(m_NI + has_state * (m_NI + m_NO)),
|
||||
m_size(1 << (m_num_bits))
|
||||
template<unsigned m_NI, unsigned m_NO, int m_has_state>
|
||||
NETLIB_OBJECT(truthtable_t)
|
||||
{
|
||||
}
|
||||
private:
|
||||
family_setter_t m_fam;
|
||||
public:
|
||||
|
||||
void setup(const plib::pstring_vector_t &desc, UINT32 disabled_ignore);
|
||||
static const int m_num_bits = m_NI + m_has_state * (m_NI + m_NO);
|
||||
static const int m_size = (1 << (m_num_bits));
|
||||
|
||||
private:
|
||||
void help(unsigned cur, plib::pstring_vector_t list,
|
||||
UINT64 state,UINT16 val, std::vector<UINT8> &timing_index);
|
||||
static unsigned count_bits(UINT32 v);
|
||||
static UINT32 set_bits(UINT32 v, UINT32 b);
|
||||
UINT32 get_ignored_simple(UINT32 i);
|
||||
UINT32 get_ignored_extended(UINT32 i);
|
||||
|
||||
unsigned m_NO;
|
||||
unsigned m_NI;
|
||||
//int m_has_state;
|
||||
bool *m_initialized;
|
||||
UINT16 *m_outs;
|
||||
UINT8 *m_timing;
|
||||
netlist_time *m_timing_nt;
|
||||
|
||||
/* additional values */
|
||||
|
||||
const UINT32 m_num_bits;
|
||||
const UINT32 m_size;
|
||||
|
||||
};
|
||||
|
||||
#if 1
|
||||
template<unsigned m_NI, unsigned m_NO, int m_has_state>
|
||||
NETLIB_OBJECT(truthtable_t)
|
||||
{
|
||||
private:
|
||||
family_setter_t m_fam;
|
||||
public:
|
||||
|
||||
static const int m_num_bits = m_NI + m_has_state * (m_NI + m_NO);
|
||||
static const int m_size = (1 << (m_num_bits));
|
||||
|
||||
struct truthtable_t
|
||||
{
|
||||
truthtable_t(size_t NI, size_t NO, bool has_state)
|
||||
: m_initialized(false)
|
||||
, m_desc(NO, NI, has_state, &m_initialized, m_outs, m_timing, m_timing_nt) {}
|
||||
bool m_initialized;
|
||||
UINT16 m_outs[m_size];
|
||||
//UINT32 m_outs[m_size];
|
||||
UINT8 m_timing[m_size * m_NO];
|
||||
netlist_time m_timing_nt[16];
|
||||
truthtable_desc_t m_desc;
|
||||
};
|
||||
|
||||
template <class C>
|
||||
nld_truthtable_t(C &owner, const pstring &name, const logic_family_desc_t *fam,
|
||||
truthtable_t *ttbl, const char *desc[])
|
||||
: device_t(owner, name)
|
||||
, m_fam(*this, fam)
|
||||
, m_last_state(0)
|
||||
, m_ign(0)
|
||||
, m_active(1)
|
||||
, m_ttp(ttbl)
|
||||
{
|
||||
while (*desc != nullptr && **desc != 0 )
|
||||
{
|
||||
m_desc.push_back(*desc);
|
||||
desc++;
|
||||
}
|
||||
startxx();
|
||||
}
|
||||
|
||||
template <class C>
|
||||
nld_truthtable_t(C &owner, const pstring &name, const logic_family_desc_t *fam,
|
||||
truthtable_t *ttbl, const plib::pstring_vector_t &desc)
|
||||
: device_t(owner, name)
|
||||
, m_fam(*this, fam)
|
||||
, m_last_state(0)
|
||||
, m_ign(0)
|
||||
, m_active(1)
|
||||
, m_ttp(ttbl)
|
||||
{
|
||||
m_desc = desc;
|
||||
startxx();
|
||||
}
|
||||
|
||||
void startxx()
|
||||
{
|
||||
pstring header = m_desc[0];
|
||||
|
||||
plib::pstring_vector_t io(header,"|");
|
||||
// checks
|
||||
nl_assert_always(io.size() == 2, "too many '|'");
|
||||
plib::pstring_vector_t inout(io[0], ",");
|
||||
nl_assert_always(inout.size() == m_num_bits, "bitcount wrong");
|
||||
plib::pstring_vector_t out(io[1], ",");
|
||||
nl_assert_always(out.size() == m_NO, "output count wrong");
|
||||
|
||||
for (std::size_t i=0; i < m_NI; i++)
|
||||
struct truthtable_t
|
||||
{
|
||||
//new (&m_I[i]) logic_input_t();
|
||||
inout[i] = inout[i].trim();
|
||||
m_I.emplace(i, *this, inout[i]);
|
||||
}
|
||||
for (std::size_t i=0; i < m_NO; i++)
|
||||
truthtable_t()
|
||||
: m_initialized(false)
|
||||
{}
|
||||
bool m_initialized;
|
||||
typename uint_for_size<need_bytes_for_bits<m_NO + m_NI>::value>::type m_outs[m_size];
|
||||
UINT8 m_timing[m_size * m_NO];
|
||||
netlist_time m_timing_nt[16];
|
||||
};
|
||||
|
||||
template <class C>
|
||||
nld_truthtable_t(C &owner, const pstring &name, const logic_family_desc_t *fam,
|
||||
truthtable_t *ttp, const char *desc[])
|
||||
: device_t(owner, name)
|
||||
, m_fam(*this, fam)
|
||||
, m_last_state(0)
|
||||
, m_ign(0)
|
||||
, m_active(1)
|
||||
, m_ttp(ttp)
|
||||
{
|
||||
//new (&m_Q[i]) logic_output_t();
|
||||
out[i] = out[i].trim();
|
||||
m_Q.emplace(i, *this, out[i]);
|
||||
//enregister(out[i], m_Q[i]);
|
||||
}
|
||||
// Connect output "Q" to input "_Q" if this exists
|
||||
// This enables timed state without having explicit state ....
|
||||
UINT32 disabled_ignore = 0;
|
||||
for (std::size_t i=0; i < m_NO; i++)
|
||||
{
|
||||
pstring tmp = "_" + out[i];
|
||||
const int idx = inout.indexof(tmp);
|
||||
if (idx>=0)
|
||||
{
|
||||
connect_late(m_Q[i], m_I[idx]);
|
||||
// disable ignore for this inputs altogether.
|
||||
// FIXME: This shouldn't be necessary
|
||||
disabled_ignore |= (1<<idx);
|
||||
}
|
||||
while (*desc != nullptr && **desc != 0 )
|
||||
{
|
||||
m_desc.push_back(*desc);
|
||||
desc++;
|
||||
}
|
||||
startxx();
|
||||
}
|
||||
|
||||
m_ign = 0;
|
||||
|
||||
m_ttp->m_desc.setup(m_desc, disabled_ignore * 0);
|
||||
|
||||
#if 0
|
||||
printf("%s\n", name().cstr());
|
||||
for (int j=0; j < m_size; j++)
|
||||
printf("%05x %04x %04x %04x\n", j, m_ttp->m_outs[j] & ((1 << m_NO)-1),
|
||||
m_ttp->m_outs[j] >> m_NO, m_ttp->m_timing[j * m_NO + 0]);
|
||||
for (int k=0; m_ttp->m_timing_nt[k] != netlist_time::zero(); k++)
|
||||
printf("%d %f\n", k, m_ttp->m_timing_nt[k].as_double() * 1000000.0);
|
||||
#endif
|
||||
save(NLNAME(m_last_state));
|
||||
save(NLNAME(m_ign));
|
||||
save(NLNAME(m_active));
|
||||
}
|
||||
|
||||
NETLIB_RESETI()
|
||||
{
|
||||
m_active = 0;
|
||||
m_ign = 0;
|
||||
for (std::size_t i = 0; i < m_NI; i++)
|
||||
m_I[i].activate();
|
||||
for (std::size_t i=0; i<m_NO;i++)
|
||||
if (this->m_Q[i].net().num_cons()>0)
|
||||
m_active++;
|
||||
m_last_state = 0;
|
||||
}
|
||||
|
||||
NETLIB_UPDATEI()
|
||||
{
|
||||
process<true>();
|
||||
}
|
||||
|
||||
public:
|
||||
void inc_active() override
|
||||
{
|
||||
nl_assert(netlist().use_deactivate());
|
||||
if (m_has_state == 0)
|
||||
if (++m_active == 1)
|
||||
{
|
||||
process<false>();
|
||||
}
|
||||
}
|
||||
|
||||
void dec_active() override
|
||||
{
|
||||
nl_assert(netlist().use_deactivate());
|
||||
/* FIXME:
|
||||
* Based on current measurements there is no point to disable
|
||||
* 1 input devices. This should actually be a parameter so that we
|
||||
* can decide for each individual gate whether it is benefitial to
|
||||
* ignore deactivation.
|
||||
*/
|
||||
if (m_NI > 1 && m_has_state == 0)
|
||||
if (--m_active == 0)
|
||||
{
|
||||
for (std::size_t i = 0; i< m_NI; i++)
|
||||
m_I[i].inactivate();
|
||||
m_ign = (1<<m_NI)-1;
|
||||
}
|
||||
}
|
||||
|
||||
//logic_input_t m_I[m_NI];
|
||||
//logic_output_t m_Q[m_NO];
|
||||
plib::uninitialised_array_t<logic_input_t, m_NI> m_I;
|
||||
plib::uninitialised_array_t<logic_output_t, m_NO> m_Q;
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
|
||||
template<bool doOUT>
|
||||
inline void process()
|
||||
{
|
||||
netlist_time mt = netlist_time::zero();
|
||||
|
||||
UINT32 state = 0;
|
||||
if (m_NI > 1 && !m_has_state)
|
||||
template <class C>
|
||||
nld_truthtable_t(C &owner, const pstring &name, const logic_family_desc_t *fam,
|
||||
truthtable_t *ttp, const plib::pstring_vector_t &desc)
|
||||
: device_t(owner, name)
|
||||
, m_fam(*this, fam)
|
||||
, m_last_state(0)
|
||||
, m_ign(0)
|
||||
, m_active(1)
|
||||
, m_ttp(ttp)
|
||||
{
|
||||
m_desc = desc;
|
||||
startxx();
|
||||
}
|
||||
|
||||
if (!doOUT)
|
||||
void startxx()
|
||||
{
|
||||
pstring header = m_desc[0];
|
||||
|
||||
plib::pstring_vector_t io(header,"|");
|
||||
// checks
|
||||
nl_assert_always(io.size() == 2, "too many '|'");
|
||||
plib::pstring_vector_t inout(io[0], ",");
|
||||
nl_assert_always(inout.size() == m_num_bits, "bitcount wrong");
|
||||
plib::pstring_vector_t out(io[1], ",");
|
||||
nl_assert_always(out.size() == m_NO, "output count wrong");
|
||||
|
||||
for (std::size_t i=0; i < m_NI; i++)
|
||||
{
|
||||
for (std::size_t i = 0; i < m_NI; i++)
|
||||
m_I[i].activate();
|
||||
inout[i] = inout[i].trim();
|
||||
m_I.emplace(i, *this, inout[i]);
|
||||
}
|
||||
for (std::size_t i=0; i < m_NO; i++)
|
||||
{
|
||||
out[i] = out[i].trim();
|
||||
m_Q.emplace(i, *this, out[i]);
|
||||
}
|
||||
// Connect output "Q" to input "_Q" if this exists
|
||||
// This enables timed state without having explicit state ....
|
||||
UINT32 disabled_ignore = 0;
|
||||
for (std::size_t i=0; i < m_NO; i++)
|
||||
{
|
||||
pstring tmp = "_" + out[i];
|
||||
const int idx = inout.indexof(tmp);
|
||||
if (idx>=0)
|
||||
{
|
||||
connect_late(m_Q[i], m_I[idx]);
|
||||
// disable ignore for this inputs altogether.
|
||||
// FIXME: This shouldn't be necessary
|
||||
disabled_ignore |= (1<<idx);
|
||||
}
|
||||
}
|
||||
|
||||
m_ign = 0;
|
||||
|
||||
truthtable_desc_t desc(m_NO, m_NI, m_has_state,
|
||||
&m_ttp->m_initialized, packed_int(m_ttp->m_outs), m_ttp->m_timing, m_ttp->m_timing_nt);
|
||||
|
||||
desc.setup(m_desc, disabled_ignore * 0);
|
||||
|
||||
#if 0
|
||||
printf("%s\n", name().cstr());
|
||||
for (int j=0; j < m_size; j++)
|
||||
printf("%05x %04x %04x %04x\n", j, m_ttp.m_outs[j] & ((1 << m_NO)-1),
|
||||
m_ttp.m_outs[j] >> m_NO, m_ttp.m_timing[j * m_NO + 0]);
|
||||
for (int k=0; m_ttp.m_timing_nt[k] != netlist_time::zero(); k++)
|
||||
printf("%d %f\n", k, m_ttp.m_timing_nt[k].as_double() * 1000000.0);
|
||||
#endif
|
||||
save(NLNAME(m_last_state));
|
||||
save(NLNAME(m_ign));
|
||||
save(NLNAME(m_active));
|
||||
}
|
||||
|
||||
NETLIB_RESETI()
|
||||
{
|
||||
m_active = 0;
|
||||
m_ign = 0;
|
||||
for (std::size_t i = 0; i < m_NI; i++)
|
||||
m_I[i].activate();
|
||||
for (std::size_t i=0; i<m_NO;i++)
|
||||
if (this->m_Q[i].net().num_cons()>0)
|
||||
m_active++;
|
||||
m_last_state = 0;
|
||||
}
|
||||
|
||||
NETLIB_UPDATEI()
|
||||
{
|
||||
process<true>();
|
||||
}
|
||||
|
||||
public:
|
||||
void inc_active() override
|
||||
{
|
||||
nl_assert(netlist().use_deactivate());
|
||||
if (m_NI > 1 && m_has_state == 0)
|
||||
if (++m_active == 1)
|
||||
{
|
||||
process<false>();
|
||||
}
|
||||
}
|
||||
|
||||
void dec_active() override
|
||||
{
|
||||
nl_assert(netlist().use_deactivate());
|
||||
/* FIXME:
|
||||
* Based on current measurements there is no point to disable
|
||||
* 1 input devices. This should actually be a parameter so that we
|
||||
* can decide for each individual gate whether it is benefitial to
|
||||
* ignore deactivation.
|
||||
*/
|
||||
if (m_NI > 1 && m_has_state == 0)
|
||||
if (--m_active == 0)
|
||||
{
|
||||
for (std::size_t i = 0; i< m_NI; i++)
|
||||
m_I[i].inactivate();
|
||||
m_ign = (1<<m_NI)-1;
|
||||
}
|
||||
}
|
||||
|
||||
//logic_input_t m_I[m_NI];
|
||||
//logic_output_t m_Q[m_NO];
|
||||
plib::uninitialised_array_t<logic_input_t, m_NI> m_I;
|
||||
plib::uninitialised_array_t<logic_output_t, m_NO> m_Q;
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
|
||||
template<bool doOUT>
|
||||
inline void process()
|
||||
{
|
||||
netlist_time mt = netlist_time::zero();
|
||||
|
||||
uint64_t state = 0;
|
||||
if (m_NI > 1 && !m_has_state)
|
||||
{
|
||||
auto ign = m_ign;
|
||||
if (!doOUT)
|
||||
for (std::size_t i = 0; i < m_NI; i++)
|
||||
{
|
||||
m_I[i].activate();
|
||||
state |= (INPLOGIC(m_I[i]) << i);
|
||||
mt = std::max(this->m_I[i].net().time(), mt);
|
||||
}
|
||||
else
|
||||
for (std::size_t i = 0; i < m_NI; ign >>= 1, i++)
|
||||
{
|
||||
if ((ign & 1))
|
||||
m_I[i].activate();
|
||||
state |= (INPLOGIC(m_I[i]) << i);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto ign(m_ign);
|
||||
for (std::size_t i = 0; ign != 0; ign >>= 1, i++)
|
||||
if ((ign & 1))
|
||||
m_I[i].activate();
|
||||
if (!doOUT)
|
||||
for (std::size_t i = 0; i < m_NI; i++)
|
||||
{
|
||||
state |= (INPLOGIC(m_I[i]) << i);
|
||||
mt = std::max(this->m_I[i].net().time(), mt);
|
||||
}
|
||||
else
|
||||
for (std::size_t i = 0; i < m_NI; i++)
|
||||
state |= (INPLOGIC(m_I[i]) << i);
|
||||
}
|
||||
}
|
||||
auto nstate = state;
|
||||
|
||||
if (!doOUT)
|
||||
for (std::size_t i = 0; i < m_NI; i++)
|
||||
if (m_has_state)
|
||||
nstate |= (m_last_state << m_NI);
|
||||
|
||||
const auto outstate = m_ttp->m_outs[nstate];
|
||||
const auto out = outstate & ((1 << m_NO) - 1);
|
||||
|
||||
m_ign = outstate >> m_NO;
|
||||
|
||||
const auto timebase = nstate * m_NO;
|
||||
|
||||
if (doOUT)
|
||||
{
|
||||
state |= (INPLOGIC(m_I[i]) << i);
|
||||
mt = std::max(this->m_I[i].net().time(), mt);
|
||||
}
|
||||
else
|
||||
for (std::size_t i = 0; i < m_NI; i++)
|
||||
state |= (INPLOGIC(m_I[i]) << i);
|
||||
|
||||
UINT32 nstate = state;
|
||||
|
||||
if (m_has_state)
|
||||
nstate |= (m_last_state << m_NI);
|
||||
|
||||
const UINT32 outstate = m_ttp->m_outs[nstate];
|
||||
const UINT32 out = outstate & ((1 << m_NO) - 1);
|
||||
|
||||
m_ign = outstate >> m_NO;
|
||||
|
||||
const UINT32 timebase = nstate * m_NO;
|
||||
|
||||
if (doOUT)
|
||||
{
|
||||
for (std::size_t i = 0; i < m_NO; i++)
|
||||
OUTLOGIC(m_Q[i], (out >> i) & 1, m_ttp->m_timing_nt[m_ttp->m_timing[timebase + i]]);
|
||||
}
|
||||
else
|
||||
for (std::size_t i = 0; i < m_NO; i++)
|
||||
m_Q[i].net().set_Q_time((out >> i) & 1, mt + m_ttp->m_timing_nt[m_ttp->m_timing[timebase + i]]);
|
||||
|
||||
if (m_has_state)
|
||||
m_last_state = (state << m_NO) | out;
|
||||
|
||||
if (m_NI > 1 && !m_has_state)
|
||||
{
|
||||
auto ign(m_ign);
|
||||
for (std::size_t i = 0; ign != 0; ign >>= 1, i++)
|
||||
if (ign & 1)
|
||||
m_I[i].inactivate();
|
||||
}
|
||||
}
|
||||
|
||||
UINT32 m_last_state;
|
||||
UINT32 m_ign;
|
||||
INT32 m_active;
|
||||
|
||||
truthtable_t *m_ttp;
|
||||
plib::pstring_vector_t m_desc;
|
||||
};
|
||||
|
||||
#else
|
||||
NETLIB_OBJECT(xtruthtable_t)
|
||||
{
|
||||
private:
|
||||
family_setter_t m_fam;
|
||||
public:
|
||||
|
||||
struct truthtable_t
|
||||
{
|
||||
truthtable_t(size_t NI, size_t NO, bool has_state)
|
||||
: m_initialized(false)
|
||||
, m_num_bits(NI + has_state * (NI + NO))
|
||||
, m_size(1 << (m_num_bits))
|
||||
{
|
||||
m_timing = new UINT8[m_size * NO];
|
||||
m_outs = new UINT16[m_size];
|
||||
m_desc = new truthtable_desc_t(NO, NI, has_state, &m_initialized, m_outs, m_timing, m_timing_nt);
|
||||
}
|
||||
bool m_initialized;
|
||||
UINT16 *m_outs;
|
||||
//UINT32 m_outs[m_size];
|
||||
UINT8 *m_timing;
|
||||
netlist_time m_timing_nt[16];
|
||||
truthtable_desc_t *m_desc;
|
||||
int m_num_bits;
|
||||
int m_size;
|
||||
};
|
||||
|
||||
template <class C>
|
||||
nld_xtruthtable_t(size_t NI, size_t NO, bool has_state, C &owner, const pstring &name, const logic_family_desc_t *fam,
|
||||
truthtable_t *ttbl, const char *desc[])
|
||||
: device_t(owner, name)
|
||||
, m_fam(*this, fam)
|
||||
, m_last_state(0)
|
||||
, m_ign(0)
|
||||
, m_active(1)
|
||||
, m_ttp(ttbl)
|
||||
, m_NI(NI)
|
||||
, m_NO(NO)
|
||||
, m_has_state(has_state)
|
||||
{
|
||||
m_is_truthtable = true;
|
||||
while (*desc != nullptr && **desc != 0 )
|
||||
{
|
||||
m_desc.push_back(*desc);
|
||||
desc++;
|
||||
}
|
||||
startxx();
|
||||
}
|
||||
|
||||
template <class C>
|
||||
nld_xtruthtable_t(size_t NI, size_t NO, bool has_state, C &owner, const pstring &name, const logic_family_desc_t *fam,
|
||||
truthtable_t *ttbl, const plib::pstring_vector_t &desc)
|
||||
: device_t(owner, name)
|
||||
, m_fam(*this, fam)
|
||||
, m_last_state(0)
|
||||
, m_ign(0)
|
||||
, m_active(1)
|
||||
, m_ttp(ttbl)
|
||||
, m_NI(NI)
|
||||
, m_NO(NO)
|
||||
, m_has_state(has_state)
|
||||
{
|
||||
m_is_truthtable = true;
|
||||
m_desc = desc;
|
||||
startxx();
|
||||
}
|
||||
|
||||
void startxx()
|
||||
{
|
||||
pstring header = m_desc[0];
|
||||
|
||||
plib::pstring_vector_t io(header,"|");
|
||||
// checks
|
||||
nl_assert_always(io.size() == 2, "too many '|'");
|
||||
plib::pstring_vector_t inout(io[0], ",");
|
||||
nl_assert_always(inout.size() == m_ttp->m_num_bits, "bitcount wrong");
|
||||
plib::pstring_vector_t out(io[1], ",");
|
||||
nl_assert_always(out.size() == m_NO, "output count wrong");
|
||||
|
||||
for (std::size_t i=0; i < m_NI; i++)
|
||||
{
|
||||
//new (&m_I[i]) logic_input_t();
|
||||
inout[i] = inout[i].trim();
|
||||
m_I.emplace(i, *this, inout[i]);
|
||||
}
|
||||
for (std::size_t i=0; i < m_NO; i++)
|
||||
{
|
||||
//new (&m_Q[i]) logic_output_t();
|
||||
out[i] = out[i].trim();
|
||||
m_Q.emplace(i, *this, out[i]);
|
||||
//enregister(out[i], m_Q[i]);
|
||||
}
|
||||
// Connect output "Q" to input "_Q" if this exists
|
||||
// This enables timed state without having explicit state ....
|
||||
UINT32 disabled_ignore = 0;
|
||||
for (std::size_t i=0; i < m_NO; i++)
|
||||
{
|
||||
pstring tmp = "_" + out[i];
|
||||
const int idx = inout.indexof(tmp);
|
||||
if (idx>=0)
|
||||
{
|
||||
connect_late(m_Q[i], m_I[idx]);
|
||||
// disable ignore for this inputs altogether.
|
||||
// FIXME: This shouldn't be necessary
|
||||
disabled_ignore |= (1<<idx);
|
||||
}
|
||||
}
|
||||
|
||||
m_ign = 0;
|
||||
|
||||
m_ttp->m_desc->setup(m_desc, disabled_ignore * 0);
|
||||
|
||||
#if 0
|
||||
printf("%s\n", name().cstr());
|
||||
for (int j=0; j < m_size; j++)
|
||||
printf("%05x %04x %04x %04x\n", j, m_ttp->m_outs[j] & ((1 << m_NO)-1),
|
||||
m_ttp->m_outs[j] >> m_NO, m_ttp->m_timing[j * m_NO + 0]);
|
||||
for (int k=0; m_ttp->m_timing_nt[k] != netlist_time::zero(); k++)
|
||||
printf("%d %f\n", k, m_ttp->m_timing_nt[k].as_double() * 1000000.0);
|
||||
#endif
|
||||
save(NLNAME(m_last_state));
|
||||
save(NLNAME(m_ign));
|
||||
save(NLNAME(m_active));
|
||||
}
|
||||
|
||||
NETLIB_RESETI()
|
||||
{
|
||||
m_active = 0;
|
||||
m_ign = 0;
|
||||
for (std::size_t i = 0; i < m_NI; i++)
|
||||
m_I[i].activate();
|
||||
for (std::size_t i=0; i<m_NO;i++)
|
||||
if (this->m_Q[i].net().num_cons()>0)
|
||||
m_active++;
|
||||
m_last_state = 0;
|
||||
}
|
||||
|
||||
public:
|
||||
void update() noexcept override final
|
||||
{
|
||||
process<true>();
|
||||
}
|
||||
|
||||
public:
|
||||
void inc_active() override
|
||||
{
|
||||
nl_assert(netlist().use_deactivate());
|
||||
if (m_has_state == 0)
|
||||
if (++m_active == 1)
|
||||
{
|
||||
process<false>();
|
||||
}
|
||||
}
|
||||
|
||||
void dec_active() override
|
||||
{
|
||||
nl_assert(netlist().use_deactivate());
|
||||
/* FIXME:
|
||||
* Based on current measurements there is no point to disable
|
||||
* 1 input devices. This should actually be a parameter so that we
|
||||
* can decide for each individual gate whether it is benefitial to
|
||||
* ignore deactivation.
|
||||
*/
|
||||
if (m_NI > 1 && m_has_state == 0)
|
||||
if (--m_active == 0)
|
||||
{
|
||||
for (std::size_t i = 0; i< m_NI; i++)
|
||||
m_I[i].inactivate();
|
||||
m_ign = (1<<m_NI)-1;
|
||||
}
|
||||
}
|
||||
|
||||
//logic_input_t m_I[m_NI];
|
||||
//logic_output_t m_Q[m_NO];
|
||||
plib::uninitialised_array_t<logic_input_t, 16> m_I;
|
||||
plib::uninitialised_array_t<logic_output_t, 8> m_Q;
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
|
||||
template<bool doOUT>
|
||||
inline void process()
|
||||
{
|
||||
netlist_time mt = netlist_time::zero();
|
||||
|
||||
UINT32 state = 0;
|
||||
if (m_NI > 1 && !m_has_state)
|
||||
{
|
||||
|
||||
if (!doOUT)
|
||||
{
|
||||
for (std::size_t i = 0; i < m_NI; i++)
|
||||
m_I[i].activate();
|
||||
for (std::size_t i = 0; i < m_NO; i++)
|
||||
OUTLOGIC(m_Q[i], (out >> i) & 1, m_ttp->m_timing_nt[m_ttp->m_timing[timebase + i]]);
|
||||
}
|
||||
else
|
||||
for (std::size_t i = 0; i < m_NO; i++)
|
||||
m_Q[i].net().set_Q_time((out >> i) & 1, mt + m_ttp->m_timing_nt[m_ttp->m_timing[timebase + i]]);
|
||||
|
||||
if (m_has_state)
|
||||
m_last_state = (state << m_NO) | out;
|
||||
|
||||
if (m_NI > 1 && !m_has_state)
|
||||
{
|
||||
auto ign(m_ign);
|
||||
for (std::size_t i = 0; ign != 0; ign >>= 1, i++)
|
||||
if ((ign & 1))
|
||||
m_I[i].activate();
|
||||
if (ign & 1)
|
||||
m_I[i].inactivate();
|
||||
}
|
||||
}
|
||||
|
||||
if (!doOUT)
|
||||
for (std::size_t i = 0; i < m_NI; i++)
|
||||
{
|
||||
state |= (INPLOGIC(m_I[i]) << i);
|
||||
mt = std::max(this->m_I[i].net().time(), mt);
|
||||
}
|
||||
else
|
||||
for (std::size_t i = 0; i < m_NI; i++)
|
||||
state |= (INPLOGIC(m_I[i]) << i);
|
||||
UINT32 m_last_state;
|
||||
UINT32 m_ign;
|
||||
INT32 m_active;
|
||||
|
||||
UINT32 nstate = state;
|
||||
truthtable_t *m_ttp;
|
||||
plib::pstring_vector_t m_desc;
|
||||
};
|
||||
|
||||
if (m_has_state)
|
||||
nstate |= (m_last_state << m_NI);
|
||||
class netlist_base_factory_truthtable_t : public base_factory_t
|
||||
{
|
||||
P_PREVENT_COPYING(netlist_base_factory_truthtable_t)
|
||||
public:
|
||||
netlist_base_factory_truthtable_t(const pstring &name, const pstring &classname,
|
||||
const pstring &def_param)
|
||||
: base_factory_t(name, classname, def_param), m_family(family_TTL())
|
||||
{}
|
||||
|
||||
const UINT32 outstate = m_ttp->m_outs[nstate];
|
||||
const UINT32 out = outstate & ((1 << m_NO) - 1);
|
||||
|
||||
m_ign = outstate >> m_NO;
|
||||
|
||||
const UINT32 timebase = nstate * m_NO;
|
||||
|
||||
if (doOUT)
|
||||
virtual ~netlist_base_factory_truthtable_t()
|
||||
{
|
||||
for (std::size_t i = 0; i < m_NO; i++)
|
||||
OUTLOGIC(m_Q[i], (out >> i) & 1, m_ttp->m_timing_nt[m_ttp->m_timing[timebase + i]]);
|
||||
}
|
||||
else
|
||||
for (std::size_t i = 0; i < m_NO; i++)
|
||||
m_Q[i].net().set_Q_time((out >> i) & 1, mt + m_ttp->m_timing_nt[m_ttp->m_timing[timebase + i]]);
|
||||
|
||||
if (m_has_state)
|
||||
m_last_state = (state << m_NO) | out;
|
||||
plib::pstring_vector_t m_desc;
|
||||
const logic_family_desc_t *m_family;
|
||||
};
|
||||
|
||||
if (m_NI > 1 && !m_has_state)
|
||||
{
|
||||
auto ign(m_ign);
|
||||
for (std::size_t i = 0; ign != 0; ign >>= 1, i++)
|
||||
if (ign & 1)
|
||||
m_I[i].inactivate();
|
||||
}
|
||||
}
|
||||
|
||||
UINT32 m_last_state;
|
||||
UINT32 m_ign;
|
||||
INT32 m_active;
|
||||
|
||||
truthtable_t *m_ttp;
|
||||
size_t m_NI;
|
||||
size_t m_NO;
|
||||
bool m_has_state;
|
||||
plib::pstring_vector_t m_desc;
|
||||
};
|
||||
|
||||
template<unsigned NI, unsigned NO, int has_state>
|
||||
NETLIB_OBJECT_DERIVED(truthtable_t, xtruthtable_t)
|
||||
{
|
||||
public:
|
||||
template <class C>
|
||||
nld_truthtable_t(C &owner, const pstring &name, const logic_family_desc_t *fam,
|
||||
truthtable_t *ttbl, const char *desc[])
|
||||
: nld_xtruthtable_t(NI, NO, has_state, owner, name, fam, ttbl, desc)
|
||||
{
|
||||
}
|
||||
|
||||
template <class C>
|
||||
nld_truthtable_t(C &owner, const pstring &name, const logic_family_desc_t *fam,
|
||||
truthtable_t *ttbl, const plib::pstring_vector_t &desc)
|
||||
: nld_xtruthtable_t(NI, NO, has_state, owner, name, fam, ttbl, desc)
|
||||
{
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
class netlist_base_factory_truthtable_t : public base_factory_t
|
||||
{
|
||||
P_PREVENT_COPYING(netlist_base_factory_truthtable_t)
|
||||
public:
|
||||
netlist_base_factory_truthtable_t(const pstring &name, const pstring &classname,
|
||||
const pstring &def_param)
|
||||
: base_factory_t(name, classname, def_param), m_family(family_TTL())
|
||||
{}
|
||||
|
||||
virtual ~netlist_base_factory_truthtable_t()
|
||||
{
|
||||
}
|
||||
|
||||
plib::pstring_vector_t m_desc;
|
||||
const logic_family_desc_t *m_family;
|
||||
};
|
||||
|
||||
plib::owned_ptr<netlist_base_factory_truthtable_t> nl_tt_factory_create(const unsigned ni, const unsigned no,
|
||||
const unsigned has_state,
|
||||
const pstring &name, const pstring &classname,
|
||||
const pstring &def_param);
|
||||
plib::owned_ptr<netlist_base_factory_truthtable_t> nl_tt_factory_create(const unsigned ni, const unsigned no,
|
||||
const unsigned has_state,
|
||||
const pstring &name, const pstring &classname,
|
||||
const pstring &def_param);
|
||||
|
||||
} //namespace devices
|
||||
} // namespace netlist
|
||||
|
@ -12,7 +12,6 @@
|
||||
|
||||
#include "nl_base.h"
|
||||
#include "devices/nlid_system.h"
|
||||
#include "devices/nld_truthtable.h"
|
||||
#include "nl_util.h"
|
||||
|
||||
namespace netlist
|
||||
@ -431,7 +430,6 @@ core_device_t::core_device_t(netlist_t &owner, const pstring &name)
|
||||
, stat_call_count(0)
|
||||
#endif
|
||||
{
|
||||
m_is_truthtable = false;
|
||||
if (logic_family() == nullptr)
|
||||
set_logic_family(family_TTL());
|
||||
}
|
||||
@ -445,7 +443,6 @@ core_device_t::core_device_t(core_device_t &owner, const pstring &name)
|
||||
, stat_call_count(0)
|
||||
#endif
|
||||
{
|
||||
m_is_truthtable = false;
|
||||
set_logic_family(owner.logic_family());
|
||||
if (logic_family() == nullptr)
|
||||
set_logic_family(family_TTL());
|
||||
@ -678,15 +675,7 @@ void net_t::update_devs()
|
||||
{
|
||||
inc_stat(p.device().stat_call_count);
|
||||
if ((p.state() & mask) != 0)
|
||||
{
|
||||
//if (0 && p.device().m_is_truthtable)
|
||||
{
|
||||
/* inlining doesn't help, this kills performance */
|
||||
//reinterpret_cast<devices::nld_xtruthtable_t &>(p.device()).update();
|
||||
}
|
||||
//else
|
||||
p.device().update_dev();
|
||||
}
|
||||
p.device().update_dev();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -888,7 +888,6 @@ namespace netlist
|
||||
INT32 stat_call_count;
|
||||
#endif
|
||||
|
||||
bool m_is_truthtable;
|
||||
protected:
|
||||
|
||||
virtual void update() NOEXCEPT { }
|
||||
|
Loading…
Reference in New Issue
Block a user