Optimized 7493 device. Gives some 5 to 10% improvement to pong.

7493 also is an example on how to use multiple handlers on a device
makes design easier. (nw)
This commit is contained in:
couriersud 2017-02-16 02:12:37 +01:00
parent 32aca6c398
commit 73b4115c19
4 changed files with 89 additions and 79 deletions

View File

@ -12,59 +12,66 @@ namespace netlist
{
namespace devices
{
NETLIB_OBJECT(7493ff)
{
NETLIB_CONSTRUCTOR(7493ff)
, m_I(*this, "CLK")
, m_Q(*this, "Q")
, m_reset(*this, "m_reset", 0)
, m_state(*this, "m_state", 0)
{
}
NETLIB_RESETI();
NETLIB_UPDATEI();
public:
logic_input_t m_I;
logic_output_t m_Q;
state_var<netlist_sig_t> m_reset;
state_var<netlist_sig_t> m_state;
};
static constexpr netlist_time out_delay = NLTIME_FROM_NS(18);
static constexpr netlist_time out_delay2 = NLTIME_FROM_NS(36);
static constexpr netlist_time out_delay3 = NLTIME_FROM_NS(54);
NETLIB_OBJECT(7493)
{
NETLIB_CONSTRUCTOR(7493)
, m_R1(*this, "R1")
, m_R2(*this, "R2")
, A(*this, "A")
, B(*this, "B")
, C(*this, "C")
, D(*this, "D")
, m_CLKA(*this, "CLKA", NETLIB_DELEGATE(7493, updA))
, m_CLKB(*this, "CLKB", NETLIB_DELEGATE(7493, updB))
, m_QA(*this, "QA")
, m_QB(*this, "QB")
, m_QC(*this, "QC")
, m_QD(*this, "QD")
, m_reset(*this, "_m_reset", 0)
, m_a(*this, "_m_a", 0)
, m_bcd(*this, "_m_b", 0)
{
register_subalias("CLKA", A.m_I);
register_subalias("CLKB", B.m_I);
register_subalias("QA", A.m_Q);
register_subalias("QB", B.m_Q);
register_subalias("QC", C.m_Q);
register_subalias("QD", D.m_Q);
connect(C.m_I, B.m_Q);
connect(D.m_I, C.m_Q);
}
NETLIB_RESETI() { }
NETLIB_RESETI();
NETLIB_UPDATEI();
NETLIB_HANDLERI(updA)
{
if (m_reset)
{
m_a ^= 1;
m_QA.push(m_a, out_delay);
}
}
NETLIB_HANDLERI(updB)
{
if (m_reset)
{
m_bcd = (m_bcd + 1) & 0x07;
m_QB.push(m_bcd & 1, out_delay);
m_QC.push((m_bcd >> 1) & 1, out_delay2);
m_QD.push((m_bcd >> 2) & 1, out_delay3);
}
}
private:
logic_input_t m_R1;
logic_input_t m_R2;
NETLIB_SUB(7493ff) A;
NETLIB_SUB(7493ff) B;
NETLIB_SUB(7493ff) C;
NETLIB_SUB(7493ff) D;
logic_input_t m_CLKA;
logic_input_t m_CLKB;
logic_output_t m_QA;
logic_output_t m_QB;
logic_output_t m_QC;
logic_output_t m_QD;
state_var_u8 m_reset;
state_var_u8 m_a;
state_var_u8 m_bcd;
};
NETLIB_OBJECT_DERIVED(7493_dip, 7493)
@ -72,8 +79,8 @@ namespace netlist
NETLIB_CONSTRUCTOR_DERIVED(7493_dip, 7493)
{
register_subalias("1", "CLKB");
register_subalias("2", m_R1);
register_subalias("3", m_R2);
register_subalias("2", "R1");
register_subalias("3", "R2");
// register_subalias("4", ); --> NC
// register_subalias("5", ); --> VCC
@ -90,43 +97,32 @@ namespace netlist
}
};
NETLIB_RESET(7493ff)
NETLIB_RESET(7493)
{
m_reset = 1;
m_state = 0;
m_I.set_state(logic_t::STATE_INP_HL);
}
NETLIB_UPDATE(7493ff)
{
static constexpr netlist_time out_delay = NLTIME_FROM_NS(18);
if (m_reset)
{
m_state ^= 1;
m_Q.push(m_state, out_delay);
}
m_a = m_bcd = 0;
m_CLKA.set_state(logic_t::STATE_INP_HL);
m_CLKB.set_state(logic_t::STATE_INP_HL);
}
NETLIB_UPDATE(7493)
{
const netlist_sig_t r = m_R1() & m_R2();
m_reset = (m_R1() & m_R2()) ^ 1;
if (r)
if (m_reset)
{
A.m_I.inactivate();
B.m_I.inactivate();
A.m_Q.push(0, NLTIME_FROM_NS(40));
B.m_Q.push(0, NLTIME_FROM_NS(40));
C.m_Q.push(0, NLTIME_FROM_NS(40));
D.m_Q.push(0, NLTIME_FROM_NS(40));
A.m_reset = B.m_reset = C.m_reset = D.m_reset = 0;
A.m_state = B.m_state = C.m_state = D.m_state = 0;
m_CLKA.activate_hl();
m_CLKB.activate_hl();
}
else
{
A.m_I.activate_hl();
B.m_I.activate_hl();
A.m_reset = B.m_reset = C.m_reset = D.m_reset = 1;
m_CLKA.inactivate();
m_CLKB.inactivate();
m_QA.push(0, NLTIME_FROM_NS(40));
m_QB.push(0, NLTIME_FROM_NS(40));
m_QC.push(0, NLTIME_FROM_NS(40));
m_QD.push(0, NLTIME_FROM_NS(40));
m_a = m_bcd = 0;
}
}

View File

@ -687,7 +687,8 @@ core_device_t::~core_device_t()
void core_device_t::set_default_delegate(detail::core_terminal_t &term)
{
term.m_delegate.set(&core_device_t::update, this);
if (!term.m_delegate.is_set())
term.m_delegate.set(&core_device_t::update, this);
}
plib::plog_base<NL_DEBUG> &core_device_t::log()
@ -957,14 +958,14 @@ analog_net_t::~analog_net_t()
// core_terminal_t
// ----------------------------------------------------------------------------------------
detail::core_terminal_t::core_terminal_t(core_device_t &dev, const pstring &aname, const state_e state)
detail::core_terminal_t::core_terminal_t(core_device_t &dev, const pstring &aname,
const state_e state, nldelegate delegate)
: device_object_t(dev, dev.name() + "." + aname)
, plib::linkedlist_t<core_terminal_t>::element_t()
, m_delegate(delegate)
, m_net(nullptr)
, m_state(*this, "m_state", state)
{
//m_delegate.set(&core_device_t::update, &dev);
//m_delegate.set(&core_device_t::update_dev, &dev);
}
detail::core_terminal_t::~core_terminal_t()
@ -998,8 +999,9 @@ analog_t::~analog_t()
{
}
logic_t::logic_t(core_device_t &dev, const pstring &aname, const state_e state)
: core_terminal_t(dev, aname, state)
logic_t::logic_t(core_device_t &dev, const pstring &aname, const state_e state,
nldelegate delegate)
: core_terminal_t(dev, aname, state, delegate)
, logic_family_t()
, m_proxy(nullptr)
{
@ -1119,8 +1121,9 @@ void analog_output_t::initial(const nl_double val)
// logic_input_t
// -----------------------------------------------------------------------------
logic_input_t::logic_input_t(core_device_t &dev, const pstring &aname)
: logic_t(dev, aname, STATE_INP_ACTIVE)
logic_input_t::logic_input_t(core_device_t &dev, const pstring &aname,
nldelegate delegate)
: logic_t(dev, aname, STATE_INP_ACTIVE, delegate)
{
set_logic_family(dev.logic_family());
netlist().setup().register_term(*this);

View File

@ -132,7 +132,10 @@ class NETLIB_NAME(name) : public device_t
#define NETLIB_FAMILY(family) , m_famsetter(*this, family)
#define NETLIB_DELEGATE(chip, name) nldelegate(&NETLIB_NAME(chip) :: name, this)
#define NETLIB_UPDATE_TERMINALSI() public: virtual void update_terminals() override
#define NETLIB_HANDLERI(name) private: virtual void name() NL_NOEXCEPT
#define NETLIB_UPDATEI() protected: virtual void update() NL_NOEXCEPT override
#define NETLIB_UPDATE_PARAMI() public: virtual void update_param() override
#define NETLIB_RESETI() protected: virtual void reset() override
@ -142,7 +145,10 @@ class NETLIB_NAME(name) : public device_t
#define NETLIB_SUB(chip) nld_ ## chip
#define NETLIB_SUBXX(ns, chip) std::unique_ptr< ns :: nld_ ## chip >
#define NETLIB_UPDATE(chip) void NETLIB_NAME(chip) :: update(void) NL_NOEXCEPT
#define NETLIB_HANDLER(chip, name) void NETLIB_NAME(chip) :: name(void) NL_NOEXCEPT
#define NETLIB_UPDATE(chip) NETLIB_HANDLER(chip, update)
// FIXME: NETLIB_PARENT_UPDATE should disappear
#define NETLIB_PARENT_UPDATE(chip) NETLIB_NAME(chip) :: update();
#define NETLIB_RESET(chip) void NETLIB_NAME(chip) :: reset(void)
@ -469,7 +475,8 @@ namespace netlist
* All terminals are derived from this class.
*
*/
class detail::core_terminal_t : public device_object_t, public plib::linkedlist_t<core_terminal_t>::element_t
class detail::core_terminal_t : public device_object_t,
public plib::linkedlist_t<core_terminal_t>::element_t
{
public:
@ -484,7 +491,8 @@ namespace netlist
STATE_BIDIR = 256
};
core_terminal_t(core_device_t &dev, const pstring &aname, const state_e state);
core_terminal_t(core_device_t &dev, const pstring &aname,
const state_e state, nldelegate delegate = nldelegate());
virtual ~core_terminal_t();
/*! The object type.
@ -600,7 +608,8 @@ namespace netlist
class logic_t : public detail::core_terminal_t, public logic_family_t
{
public:
logic_t(core_device_t &dev, const pstring &aname, const state_e state);
logic_t(core_device_t &dev, const pstring &aname,
const state_e state, nldelegate delegate = nldelegate());
virtual ~logic_t();
bool has_proxy() const { return (m_proxy != nullptr); }
@ -623,7 +632,8 @@ namespace netlist
class logic_input_t : public logic_t
{
public:
logic_input_t(core_device_t &dev, const pstring &aname);
logic_input_t(core_device_t &dev, const pstring &aname,
nldelegate delegate = nldelegate());
virtual ~logic_input_t();
netlist_sig_t Q() const NL_NOEXCEPT;

View File

@ -228,6 +228,7 @@ namespace plib {
template<typename MemberFunctionType, typename O>
pmfp(MemberFunctionType mftp, O *object)
: pmfp_base<R, Targs...>()
{
this->set(mftp, object);
}