mirror of
https://github.com/holub/mame
synced 2025-04-19 15:11:37 +03:00
Document that inlining not automatically helps performance. Template
specialized implementations outperform the inlined code. (nw)
This commit is contained in:
parent
498a560ec7
commit
7a302cebb3
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "nld_74279.h"
|
||||
#include "nld_truthtable.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
@ -53,8 +54,8 @@ namespace netlist
|
||||
NETLIB_SUB(74279A) m_4;
|
||||
};
|
||||
|
||||
nld_74279A::truthtable_t nld_74279A::m_ttbl;
|
||||
nld_74279B::truthtable_t nld_74279B::m_ttbl;
|
||||
nld_74279A::truthtable_t nld_74279A::m_ttbl(3,1,0);
|
||||
nld_74279B::truthtable_t nld_74279B::m_ttbl(4,1,0);
|
||||
|
||||
const char *nld_74279A::m_desc[] = {
|
||||
"S,R,_Q|Q",
|
||||
|
@ -36,18 +36,7 @@
|
||||
#ifndef NLD_74279_H_
|
||||
#define NLD_74279_H_
|
||||
|
||||
#include "nld_truthtable.h"
|
||||
|
||||
#define TTL_74279_DIP(name) \
|
||||
NET_REGISTER_DEV(TTL_74279_DIP, name)
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
namespace devices
|
||||
{
|
||||
|
||||
|
||||
} //namespace devices
|
||||
} // namespace netlist
|
||||
|
||||
#endif /* NLD_74279_H_ */
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "nld_7448.h"
|
||||
#include "nld_truthtable.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
|
@ -25,7 +25,6 @@
|
||||
#define NLD_7448_H_
|
||||
|
||||
#include "nl_base.h"
|
||||
#include "nld_truthtable.h"
|
||||
|
||||
#define TTL_7448(name, cA0, cA1, cA2, cA3, cLTQ, cBIQ, cRBIQ) \
|
||||
NET_REGISTER_DEV(TTL_7448, name) \
|
||||
|
@ -107,7 +107,7 @@ namespace netlist
|
||||
};
|
||||
|
||||
#if (1 && USE_TRUTHTABLE)
|
||||
nld_9312::truthtable_t nld_9312::m_ttbl;
|
||||
nld_9312::truthtable_t nld_9312::m_ttbl(12,2,0);
|
||||
|
||||
/* FIXME: Data changes are propagating faster than changing selects A,B,C
|
||||
* Please refer to data sheet.
|
||||
|
@ -13,6 +13,25 @@ namespace netlist
|
||||
namespace devices
|
||||
{
|
||||
|
||||
template<unsigned m_NI, unsigned m_NO, int has_state>
|
||||
class netlist_factory_truthtable_t : public netlist_base_factory_truthtable_t
|
||||
{
|
||||
P_PREVENT_COPYING(netlist_factory_truthtable_t)
|
||||
public:
|
||||
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
|
||||
{
|
||||
typedef nld_truthtable_t<m_NI, m_NO, has_state> tt_type;
|
||||
return plib::owned_ptr<device_t>::Create<tt_type>(anetlist, name, m_family, &m_ttbl, m_desc);
|
||||
}
|
||||
private:
|
||||
typename nld_truthtable_t<m_NI, m_NO, has_state>::truthtable_t m_ttbl;
|
||||
};
|
||||
|
||||
unsigned truthtable_desc_t::count_bits(UINT32 v)
|
||||
{
|
||||
unsigned ret = 0;
|
||||
|
@ -11,6 +11,7 @@
|
||||
#define NLD_TRUTHTABLE_H_
|
||||
|
||||
#include <new>
|
||||
#include <cstdint>
|
||||
|
||||
#include "nl_base.h"
|
||||
#include "nl_factory.h"
|
||||
@ -51,6 +52,66 @@ namespace netlist
|
||||
namespace devices
|
||||
{
|
||||
|
||||
class dyn_bitset
|
||||
{
|
||||
dyn_bitset(const std::size_t size)
|
||||
: m_size(size)
|
||||
, m_data_size((m_data_bits - 1 + size) / m_data_bits)
|
||||
{
|
||||
m_d = new data_type[m_data_size];
|
||||
for (std::size_t i=0; i<m_data_size; i++)
|
||||
m_d[i] = 0;
|
||||
}
|
||||
|
||||
~dyn_bitset()
|
||||
{
|
||||
delete [] m_d;
|
||||
}
|
||||
|
||||
void set()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
#if 0
|
||||
static inline UINT32 remove_first_bit(UINT32 v)
|
||||
{
|
||||
@ -64,7 +125,7 @@ static inline UINT32 remove_first_bit(UINT32 v)
|
||||
struct truthtable_desc_t
|
||||
{
|
||||
truthtable_desc_t(int NO, int NI, int has_state, bool *initialized,
|
||||
UINT32 *outs, UINT8 *timing, netlist_time *timing_nt)
|
||||
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)),
|
||||
@ -86,7 +147,7 @@ private:
|
||||
unsigned m_NI;
|
||||
//int m_has_state;
|
||||
bool *m_initialized;
|
||||
UINT32 *m_outs;
|
||||
UINT16 *m_outs;
|
||||
UINT8 *m_timing;
|
||||
netlist_time *m_timing_nt;
|
||||
|
||||
@ -97,23 +158,25 @@ private:
|
||||
|
||||
};
|
||||
|
||||
template<unsigned m_NI, unsigned m_NO, int has_state>
|
||||
#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 + has_state * (m_NI + m_NO);
|
||||
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()
|
||||
truthtable_t(size_t NI, size_t NO, bool has_state)
|
||||
: m_initialized(false)
|
||||
, m_desc(m_NO, m_NI, has_state, &m_initialized, m_outs, m_timing, m_timing_nt) {}
|
||||
, m_desc(NO, NI, has_state, &m_initialized, m_outs, m_timing, m_timing_nt) {}
|
||||
bool m_initialized;
|
||||
UINT32 m_outs[m_size];
|
||||
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;
|
||||
@ -230,7 +293,7 @@ public:
|
||||
void inc_active() override
|
||||
{
|
||||
nl_assert(netlist().use_deactivate());
|
||||
if (has_state == 0)
|
||||
if (m_has_state == 0)
|
||||
if (++m_active == 1)
|
||||
{
|
||||
process<false>();
|
||||
@ -246,7 +309,7 @@ public:
|
||||
* can decide for each individual gate whether it is benefitial to
|
||||
* ignore deactivation.
|
||||
*/
|
||||
if (m_NI > 1 && has_state == 0)
|
||||
if (m_NI > 1 && m_has_state == 0)
|
||||
if (--m_active == 0)
|
||||
{
|
||||
for (std::size_t i = 0; i< m_NI; i++)
|
||||
@ -270,12 +333,22 @@ private:
|
||||
netlist_time mt = netlist_time::zero();
|
||||
|
||||
UINT32 state = 0;
|
||||
if (m_NI > 1 && !has_state)
|
||||
for (std::size_t i = 0; i < m_NI; i++)
|
||||
if (m_NI > 1 && !m_has_state)
|
||||
{
|
||||
|
||||
if (!doOUT)
|
||||
{
|
||||
if (!doOUT || (m_ign & (1<<i)))
|
||||
for (std::size_t i = 0; i < m_NI; i++)
|
||||
m_I[i].activate();
|
||||
}
|
||||
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++)
|
||||
@ -287,14 +360,18 @@ private:
|
||||
for (std::size_t i = 0; i < m_NI; i++)
|
||||
state |= (INPLOGIC(m_I[i]) << i);
|
||||
|
||||
const UINT32 nstate = state | (has_state ? (m_last_state << m_NI) : 0);
|
||||
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;
|
||||
if (has_state)
|
||||
m_last_state = (state << m_NO) | out;
|
||||
|
||||
const UINT32 timebase = nstate * m_NO;
|
||||
|
||||
if (doOUT)
|
||||
{
|
||||
for (std::size_t i = 0; i < m_NO; i++)
|
||||
@ -304,10 +381,14 @@ private:
|
||||
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_NI > 1 && !has_state)
|
||||
if (m_has_state)
|
||||
m_last_state = (state << m_NO) | out;
|
||||
|
||||
if (m_NI > 1 && !m_has_state)
|
||||
{
|
||||
for (std::size_t i = 0; i < m_NI; i++)
|
||||
if (m_ign & (1 << i))
|
||||
auto ign(m_ign);
|
||||
for (std::size_t i = 0; ign != 0; ign >>= 1, i++)
|
||||
if (ign & 1)
|
||||
m_I[i].inactivate();
|
||||
}
|
||||
}
|
||||
@ -320,6 +401,286 @@ private:
|
||||
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();
|
||||
}
|
||||
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);
|
||||
|
||||
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;
|
||||
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)
|
||||
@ -337,25 +698,6 @@ public:
|
||||
const logic_family_desc_t *m_family;
|
||||
};
|
||||
|
||||
|
||||
template<unsigned m_NI, unsigned m_NO, int has_state>
|
||||
class netlist_factory_truthtable_t : public netlist_base_factory_truthtable_t
|
||||
{
|
||||
P_PREVENT_COPYING(netlist_factory_truthtable_t)
|
||||
public:
|
||||
netlist_factory_truthtable_t(const pstring &name, const pstring &classname,
|
||||
const pstring &def_param)
|
||||
: netlist_base_factory_truthtable_t(name, classname, def_param) { }
|
||||
|
||||
plib::owned_ptr<device_t> Create(netlist_t &anetlist, const pstring &name) override
|
||||
{
|
||||
typedef nld_truthtable_t<m_NI, m_NO, has_state> tt_type;
|
||||
return plib::owned_ptr<device_t>::Create<tt_type>(anetlist, name, m_family, &m_ttbl, m_desc);
|
||||
}
|
||||
private:
|
||||
typename nld_truthtable_t<m_NI, m_NO, has_state>::truthtable_t m_ttbl;
|
||||
};
|
||||
|
||||
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,
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include "nl_base.h"
|
||||
#include "devices/nlid_system.h"
|
||||
#include "devices/nld_truthtable.h"
|
||||
#include "nl_util.h"
|
||||
|
||||
namespace netlist
|
||||
@ -430,6 +431,7 @@ 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());
|
||||
}
|
||||
@ -443,6 +445,7 @@ 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());
|
||||
@ -675,7 +678,15 @@ void net_t::update_devs()
|
||||
{
|
||||
inc_stat(p.device().stat_call_count);
|
||||
if ((p.state() & mask) != 0)
|
||||
p.device().update_dev();
|
||||
{
|
||||
//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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -888,6 +888,7 @@ namespace netlist
|
||||
INT32 stat_call_count;
|
||||
#endif
|
||||
|
||||
bool m_is_truthtable;
|
||||
protected:
|
||||
|
||||
virtual void update() NOEXCEPT { }
|
||||
|
@ -12,30 +12,10 @@
|
||||
#define FAST_CLOCK (1)
|
||||
|
||||
#ifndef __PLIB_PREPROCESSOR__
|
||||
#if 0
|
||||
#define TTL_7400A_NAND(_name, _A, _B) TTL_7400_NAND(_name, _A, _B)
|
||||
#else
|
||||
#define TTL_7400A_NAND(_name, _A, _B) \
|
||||
NET_REGISTER_DEV(TTL_7400A_NAND, _name) \
|
||||
NET_CONNECT(_name, A, _A) \
|
||||
NET_CONNECT(_name, B, _B)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
NETLIST_START(lib)
|
||||
TRUTHTABLE_START(TTL_7400A_NAND, 2, 1, 0, "A,B")
|
||||
TT_HEAD(" A , B | Q ")
|
||||
TT_LINE(" 0 , X | 1 |22")
|
||||
TT_LINE(" X , 0 | 1 |22")
|
||||
TT_LINE(" 1 , 1 | 0 |15")
|
||||
TRUTHTABLE_END()
|
||||
NETLIST_END()
|
||||
|
||||
NETLIST_START(pong_fast)
|
||||
|
||||
LOCAL_SOURCE(lib)
|
||||
|
||||
INCLUDE(lib)
|
||||
SOLVER(Solver, 48000)
|
||||
PARAM(Solver.PARALLEL, 0) // Don't do parallel solvers
|
||||
PARAM(Solver.ACCURACY, 1e-4) // works and is sufficient
|
||||
@ -144,7 +124,7 @@ NETLIST_START(pong_fast)
|
||||
/* hit logic */
|
||||
|
||||
TTL_7404_INVERT(hitQ, hit)
|
||||
TTL_7400A_NAND(hit, hit1Q, hit2Q)
|
||||
TTL_7400_NAND(hit, hit1Q, hit2Q)
|
||||
|
||||
TTL_7402_NOR(attractQ, StopG, runQ)
|
||||
TTL_7404_INVERT(attract, attractQ)
|
||||
@ -152,22 +132,22 @@ NETLIST_START(pong_fast)
|
||||
TTL_7420_NAND(ic_h6a, hvidQ, hvidQ, hvidQ, hvidQ)
|
||||
ALIAS(hvid, ic_h6a.Q)
|
||||
|
||||
TTL_7400A_NAND(ic_e6c, hvid, hblank)
|
||||
TTL_7400_NAND(ic_e6c, hvid, hblank)
|
||||
ALIAS(MissQ, ic_e6c.Q)
|
||||
|
||||
TTL_7404_INVERT(ic_d1e, MissQ)
|
||||
TTL_7400A_NAND(ic_e1a, ic_d1e.Q, attractQ)
|
||||
TTL_7400_NAND(ic_e1a, ic_d1e.Q, attractQ)
|
||||
ALIAS(Missed, ic_e1a.Q)
|
||||
|
||||
TTL_7400A_NAND(rstspeed, SRSTQ, MissQ)
|
||||
TTL_7400A_NAND(StopG, StopG1Q, StopG2Q)
|
||||
TTL_7400_NAND(rstspeed, SRSTQ, MissQ)
|
||||
TTL_7400_NAND(StopG, StopG1Q, StopG2Q)
|
||||
ALIAS(L, ic_h3b.Q)
|
||||
ALIAS(R, ic_h3b.QQ)
|
||||
|
||||
TTL_7400A_NAND(hit1Q, pad1, ic_g1b.Q)
|
||||
TTL_7400A_NAND(hit2Q, pad2, ic_g1b.Q)
|
||||
TTL_7400_NAND(hit1Q, pad1, ic_g1b.Q)
|
||||
TTL_7400_NAND(hit2Q, pad2, ic_g1b.Q)
|
||||
|
||||
TTL_7400A_NAND(ic_g3c, 128H, ic_h3a.QQ)
|
||||
TTL_7400_NAND(ic_g3c, 128H, ic_h3a.QQ)
|
||||
TTL_7427_NOR(ic_g2c, ic_g3c.Q, 256H, vpad1Q)
|
||||
ALIAS(pad1, ic_g2c.Q)
|
||||
TTL_7427_NOR(ic_g2a, ic_g3c.Q, 256HQ, vpad2Q)
|
||||
@ -217,15 +197,15 @@ NETLIST_START(pong_fast)
|
||||
// hblank flip flop
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
TTL_7400A_NAND(ic_g5b, 16H, 64H)
|
||||
TTL_7400_NAND(ic_g5b, 16H, 64H)
|
||||
|
||||
// the time critical one
|
||||
TTL_7400A_NAND(ic_h5c, ic_h5b.Q, hresetQ)
|
||||
TTL_7400A_NAND(ic_h5b, ic_h5c.Q, ic_g5b.Q)
|
||||
TTL_7400_NAND(ic_h5c, ic_h5b.Q, hresetQ)
|
||||
TTL_7400_NAND(ic_h5b, ic_h5c.Q, ic_g5b.Q)
|
||||
|
||||
ALIAS(hblank, ic_h5c.Q)
|
||||
ALIAS(hblankQ, ic_h5b.Q)
|
||||
TTL_7400A_NAND(hsyncQ, hblank, 32H)
|
||||
TTL_7400_NAND(hsyncQ, hblank, 32H)
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// vblank flip flop
|
||||
@ -236,7 +216,7 @@ NETLIST_START(pong_fast)
|
||||
ALIAS(vblank, ic_f5d.Q)
|
||||
ALIAS(vblankQ, ic_f5c.Q)
|
||||
|
||||
TTL_7400A_NAND(ic_h5a, 8V, 8V)
|
||||
TTL_7400_NAND(ic_h5a, 8V, 8V)
|
||||
TTL_7410_NAND(ic_g5a, vblank, 4V, ic_h5a.Q)
|
||||
ALIAS(vsyncQ, ic_g5a.Q)
|
||||
|
||||
@ -244,31 +224,31 @@ NETLIST_START(pong_fast)
|
||||
// move logic
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
TTL_7400A_NAND(ic_e1d, hit_sound, ic_e1c.Q)
|
||||
TTL_7400A_NAND(ic_e1c, ic_f1.QC, ic_f1.QD)
|
||||
TTL_7400_NAND(ic_e1d, hit_sound, ic_e1c.Q)
|
||||
TTL_7400_NAND(ic_e1c, ic_f1.QC, ic_f1.QD)
|
||||
TTL_7493(ic_f1, ic_e1d.Q, ic_f1.QA, rstspeed, rstspeed)
|
||||
|
||||
TTL_7402_NOR(ic_g1d, ic_f1.QC, ic_f1.QD)
|
||||
TTL_7400A_NAND(ic_h1a, ic_g1d.Q, ic_g1d.Q)
|
||||
TTL_7400A_NAND(ic_h1d, ic_e1c.Q, ic_h1a.Q)
|
||||
TTL_7400_NAND(ic_h1a, ic_g1d.Q, ic_g1d.Q)
|
||||
TTL_7400_NAND(ic_h1d, ic_e1c.Q, ic_h1a.Q)
|
||||
|
||||
TTL_7400A_NAND(ic_h1c, ic_h1d.Q, vreset)
|
||||
TTL_7400A_NAND(ic_h1b, ic_h1a.Q, vreset)
|
||||
TTL_7400_NAND(ic_h1c, ic_h1d.Q, vreset)
|
||||
TTL_7400_NAND(ic_h1b, ic_h1a.Q, vreset)
|
||||
TTL_7402_NOR(ic_g1c, 256HQ, vreset)
|
||||
|
||||
TTL_74107(ic_h2a, ic_g1c.Q, ic_h2b.Q, low, ic_h1b.Q)
|
||||
TTL_74107(ic_h2b, ic_g1c.Q, high, move, ic_h1c.Q)
|
||||
|
||||
TTL_7400A_NAND(ic_h4a, ic_h2b.Q, ic_h2a.Q)
|
||||
TTL_7400_NAND(ic_h4a, ic_h2b.Q, ic_h2a.Q)
|
||||
ALIAS(move, ic_h4a.Q)
|
||||
|
||||
TTL_7400A_NAND(ic_c1d, SC, attract)
|
||||
TTL_7400_NAND(ic_c1d, SC, attract)
|
||||
TTL_7404_INVERT(ic_d1a, ic_c1d.Q)
|
||||
TTL_7474(ic_h3b, ic_d1a.Q, ic_h3b.QQ, hit1Q, hit2Q)
|
||||
|
||||
TTL_7400A_NAND(ic_h4d, ic_h3b.Q, move)
|
||||
TTL_7400A_NAND(ic_h4b, ic_h3b.QQ, move)
|
||||
TTL_7400A_NAND(ic_h4c, ic_h4d.Q, ic_h4b.Q)
|
||||
TTL_7400_NAND(ic_h4d, ic_h3b.Q, move)
|
||||
TTL_7400_NAND(ic_h4b, ic_h3b.QQ, move)
|
||||
TTL_7400_NAND(ic_h4c, ic_h4d.Q, ic_h4b.Q)
|
||||
ALIAS(Aa, ic_h4c.Q)
|
||||
ALIAS(Ba, ic_h4b.Q)
|
||||
|
||||
@ -276,7 +256,7 @@ NETLIST_START(pong_fast)
|
||||
// hvid circuit
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
TTL_7400A_NAND(hball_resetQ, Serve, attractQ)
|
||||
TTL_7400_NAND(hball_resetQ, Serve, attractQ)
|
||||
|
||||
TTL_9316(ic_g7, clk, high, hblankQ, hball_resetQ, ic_g5c.Q, Aa, Ba, low, high)
|
||||
TTL_9316(ic_h7, clk, ic_g7.RC, high, hball_resetQ, ic_g5c.Q, low, low, low, high)
|
||||
@ -291,7 +271,7 @@ NETLIST_START(pong_fast)
|
||||
|
||||
TTL_9316(ic_b3, hsyncQ, high, vblankQ, high, ic_b2b.Q, a6, b6, c6, d6)
|
||||
TTL_9316(ic_a3, hsyncQ, ic_b3.RC, high, high, ic_b2b.Q, low, low, low, low)
|
||||
TTL_7400A_NAND(ic_b2b, ic_a3.RC, ic_b3.RC)
|
||||
TTL_7400_NAND(ic_b2b, ic_a3.RC, ic_b3.RC)
|
||||
TTL_7410_NAND(ic_e2b, ic_a3.RC, ic_b3.QC, ic_b3.QD)
|
||||
ALIAS(vvidQ, ic_e2b.Q)
|
||||
TTL_7404_INVERT(vvid, vvidQ) // D2D
|
||||
@ -383,12 +363,12 @@ NETLIST_START(pong_fast)
|
||||
NET_C(GND, ic_g4_C.2)
|
||||
|
||||
ALIAS(hit_sound_en, ic_c2a.QQ)
|
||||
TTL_7400A_NAND(hit_sound, hit_sound_en, vpos16)
|
||||
TTL_7400A_NAND(score_sound, SC, vpos32)
|
||||
TTL_7400A_NAND(topbothitsound, ic_f3_topbot.Q, vpos32)
|
||||
TTL_7400_NAND(hit_sound, hit_sound_en, vpos16)
|
||||
TTL_7400_NAND(score_sound, SC, vpos32)
|
||||
TTL_7400_NAND(topbothitsound, ic_f3_topbot.Q, vpos32)
|
||||
|
||||
TTL_7410_NAND(ic_c4b, topbothitsound, hit_sound, score_sound)
|
||||
TTL_7400A_NAND(ic_c1b, ic_c4b.Q, attractQ)
|
||||
TTL_7400_NAND(ic_c1b, ic_c4b.Q, attractQ)
|
||||
ALIAS(sound, ic_c1b.Q)
|
||||
|
||||
|
||||
@ -422,9 +402,9 @@ NETLIST_START(pong_fast)
|
||||
NET_C(GND, ic_b9_C.2)
|
||||
|
||||
TTL_7404_INVERT(ic_c9b, ic_b9.OUT)
|
||||
TTL_7400A_NAND(ic_b7b, ic_a7b.Q, hsyncQ)
|
||||
TTL_7400_NAND(ic_b7b, ic_a7b.Q, hsyncQ)
|
||||
TTL_7493(ic_b8, ic_b7b.Q, ic_b8.QA, ic_b9.OUT, ic_b9.OUT)
|
||||
TTL_7400A_NAND(ic_b7a, ic_c9b.Q, ic_a7b.Q)
|
||||
TTL_7400_NAND(ic_b7a, ic_c9b.Q, ic_a7b.Q)
|
||||
TTL_7420_NAND(ic_a7b, ic_b8.QA, ic_b8.QB, ic_b8.QC, ic_b8.QD)
|
||||
ALIAS(vpad1Q, ic_b7a.Q)
|
||||
|
||||
@ -462,9 +442,9 @@ NETLIST_START(pong_fast)
|
||||
NET_C(GND, ic_a9_C.2)
|
||||
|
||||
TTL_7404_INVERT(ic_c9a, ic_a9.OUT)
|
||||
TTL_7400A_NAND(ic_b7c, ic_a7a.Q, hsyncQ)
|
||||
TTL_7400_NAND(ic_b7c, ic_a7a.Q, hsyncQ)
|
||||
TTL_7493(ic_a8, ic_b7c.Q, ic_a8.QA, ic_a9.OUT, ic_a9.OUT)
|
||||
TTL_7400A_NAND(ic_b7d, ic_c9a.Q, ic_a7a.Q)
|
||||
TTL_7400_NAND(ic_b7d, ic_c9a.Q, ic_a7a.Q)
|
||||
TTL_7420_NAND(ic_a7a, ic_a8.QA, ic_a8.QB, ic_a8.QC, ic_a8.QD)
|
||||
ALIAS(vpad2Q, ic_b7d.Q)
|
||||
|
||||
@ -544,8 +524,8 @@ NETLIST_START(pong_fast)
|
||||
TTL_7427_NOR(ic_e5c, ic_e4b.Q, 8H, 4H)
|
||||
ALIAS(scoreFE, ic_e5c.Q)
|
||||
|
||||
TTL_7400A_NAND(ic_c3d, 8H, 4H)
|
||||
//TTL_7400A_NAND(ic_c3d, 4H, 8H)
|
||||
TTL_7400_NAND(ic_c3d, 8H, 4H)
|
||||
//TTL_7400_NAND(ic_c3d, 4H, 8H)
|
||||
TTL_7402_NOR(ic_d2b, ic_e4b.Q, ic_c3d.Q)
|
||||
ALIAS(scoreBC, ic_d2b.Q)
|
||||
|
||||
@ -571,7 +551,7 @@ NETLIST_START(pong_fast)
|
||||
|
||||
// net
|
||||
TTL_74107(ic_f3b, clk, 256H, 256HQ, high)
|
||||
TTL_7400A_NAND(ic_g3b, ic_f3b.QQ, 256H)
|
||||
TTL_7400_NAND(ic_g3b, ic_f3b.QQ, 256H)
|
||||
TTL_7427_NOR(ic_g2b, ic_g3b.Q, vblank, 4V)
|
||||
ALIAS(net, ic_g2b.Q)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user