Merge remote-tracking branch 'origin/netlist_dev'

This commit is contained in:
couriersud 2016-06-07 21:55:15 +02:00
commit 0728b09483
123 changed files with 6489 additions and 6973 deletions

View File

@ -7,6 +7,17 @@
#include "netlist/devices/net_lib.h"
NETLIST_START(perf)
SOLVER(Solver, 48000)
PARAM(Solver.ACCURACY, 1e-20)
MAINCLOCK(clk, 50000000)
TTL_7400_NAND(n1,clk,clk)
NETLIST_END()
NETLIST_START(7400_astable)
/*

View File

@ -27,7 +27,6 @@ project "netlist"
MAME_DIR .. "src/lib/netlist/nl_dice_compat.h",
MAME_DIR .. "src/lib/netlist/nl_lists.h",
MAME_DIR .. "src/lib/netlist/nl_time.h",
MAME_DIR .. "src/lib/netlist/nl_util.h",
MAME_DIR .. "src/lib/netlist/nl_base.cpp",
MAME_DIR .. "src/lib/netlist/nl_base.h",
MAME_DIR .. "src/lib/netlist/nl_parser.cpp",
@ -56,6 +55,8 @@ project "netlist"
MAME_DIR .. "src/lib/netlist/plib/pstream.cpp",
MAME_DIR .. "src/lib/netlist/plib/pstream.h",
MAME_DIR .. "src/lib/netlist/plib/ptypes.h",
MAME_DIR .. "src/lib/netlist/plib/putil.cpp",
MAME_DIR .. "src/lib/netlist/plib/putil.h",
MAME_DIR .. "src/lib/netlist/tools/nl_convert.cpp",
MAME_DIR .. "src/lib/netlist/tools/nl_convert.h",
MAME_DIR .. "src/lib/netlist/analog/nld_bjt.cpp",
@ -136,9 +137,10 @@ project "netlist"
MAME_DIR .. "src/lib/netlist/devices/nld_log.h",
MAME_DIR .. "src/lib/netlist/devices/nld_system.cpp",
MAME_DIR .. "src/lib/netlist/devices/nld_system.h",
MAME_DIR .. "src/lib/netlist/devices/nld_cmos.h",
MAME_DIR .. "src/lib/netlist/devices/nld_truthtable.cpp",
MAME_DIR .. "src/lib/netlist/devices/nld_truthtable.h",
MAME_DIR .. "src/lib/netlist/devices/nlid_cmos.h",
MAME_DIR .. "src/lib/netlist/devices/nlid_system.h",
MAME_DIR .. "src/lib/netlist/macro/nlm_ttl74xx.cpp",
MAME_DIR .. "src/lib/netlist/macro/nlm_ttl74xx.h",
MAME_DIR .. "src/lib/netlist/macro/nlm_cd4xxx.cpp",

View File

@ -100,7 +100,7 @@ void netlist_mame_analog_output_t::custom_netlist_additions(netlist::setup_t &se
pstring dname = "OUT_" + m_in;
m_delegate.bind_relative_to(owner()->machine().root_device());
plib::powned_ptr<netlist::device_t> dev = plib::powned_ptr<netlist::device_t>::Create<NETLIB_NAME(analog_callback)>(setup.netlist(), setup.build_fqn(dname));
plib::owned_ptr<netlist::device_t> dev = plib::owned_ptr<netlist::device_t>::Create<NETLIB_NAME(analog_callback)>(setup.netlist(), setup.build_fqn(dname));
static_cast<NETLIB_NAME(analog_callback) *>(dev.get())->register_callback(m_delegate);
setup.register_dev(std::move(dev));
setup.register_link(dname + ".IN", m_in);
@ -264,7 +264,7 @@ ADDRESS_MAP_END
netlist_mame_device_t::netlist_mame_device_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, NETLIST_CORE, "Netlist core device", tag, owner, clock, "netlist_core", __FILE__),
m_icount(0),
m_old(netlist::netlist_time::zero),
m_old(netlist::netlist_time::zero()),
m_netlist(nullptr),
m_setup(nullptr),
m_setup_func(nullptr)
@ -274,7 +274,7 @@ netlist_mame_device_t::netlist_mame_device_t(const machine_config &mconfig, cons
netlist_mame_device_t::netlist_mame_device_t(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *file)
: device_t(mconfig, type, name, tag, owner, clock, shortname, file),
m_icount(0),
m_old(netlist::netlist_time::zero),
m_old(netlist::netlist_time::zero()),
m_netlist(nullptr),
m_setup(nullptr),
m_setup_func(nullptr)
@ -322,14 +322,14 @@ void netlist_mame_device_t::device_start()
m_setup->start_devices();
m_setup->resolve_inputs();
netlist().save_item(m_rem, this, "m_rem");
netlist().save_item(m_div, this, "m_div");
netlist().save_item(m_old, this, "m_old");
netlist().save_item(this, m_rem, "m_rem");
netlist().save_item(this, m_div, "m_div");
netlist().save_item(this, m_old, "m_old");
save_state();
m_old = netlist::netlist_time::zero;
m_rem = netlist::netlist_time::zero;
m_old = netlist::netlist_time::zero();
m_rem = netlist::netlist_time::zero();
LOG_DEV_CALLS(("device_start exit %s\n", tag()));
}
@ -344,8 +344,8 @@ void netlist_mame_device_t::device_clock_changed()
void netlist_mame_device_t::device_reset()
{
LOG_DEV_CALLS(("device_reset\n"));
m_old = netlist::netlist_time::zero;
m_rem = netlist::netlist_time::zero;
m_old = netlist::netlist_time::zero();
m_rem = netlist::netlist_time::zero();
netlist().reset();
}
@ -511,12 +511,12 @@ ATTR_COLD offs_t netlist_mame_cpu_device_t::disasm_disassemble(char *buffer, off
//char tmp[16];
unsigned startpc = pc;
int relpc = pc - m_genPC;
if (relpc >= 0 && relpc < netlist().queue().count())
if (relpc >= 0 && relpc < netlist().queue().size())
{
int dpc = netlist().queue().count() - relpc - 1;
int dpc = netlist().queue().size() - relpc - 1;
// FIXME: 50 below fixes crash in mame-debugger. It's based on try on error.
snprintf(buffer, 50, "%c %s @%10.7f", (relpc == 0) ? '*' : ' ', netlist().queue()[dpc].object()->name().cstr(),
netlist().queue()[dpc].exec_time().as_double());
snprintf(buffer, 50, "%c %s @%10.7f", (relpc == 0) ? '*' : ' ', netlist().queue()[dpc].m_object->name().cstr(),
netlist().queue()[dpc].m_exec_time.as_double());
}
else
sprintf(buffer, "%s", "");

View File

@ -504,9 +504,11 @@ class NETLIB_NAME(analog_callback) : public netlist::device_t
{
public:
NETLIB_NAME(analog_callback)(netlist::netlist_t &anetlist, const pstring &name)
: device_t(anetlist, name), m_cpu_device(nullptr), m_last(0)
: device_t(anetlist, name)
, m_in(*this, "IN")
, m_cpu_device(nullptr)
, m_last(0)
{
enregister("IN", m_in);
m_cpu_device = downcast<netlist_mame_cpu_device_t *>(&downcast<netlist_mame_t &>(netlist()).parent());
save(NLNAME(m_last));
}
@ -555,8 +557,8 @@ public:
, m_channel(*this, "CHAN", 0)
, m_mult(*this, "MULT", 1000.0)
, m_offset(*this, "OFFSET", 0.0)
, m_in(*this, "IN")
{
enregister("IN", m_in);
m_sample = netlist::netlist_time::from_hz(1); //sufficiently big enough
save(NAME(m_last_buffer));
}
@ -567,7 +569,7 @@ public:
{
m_cur = 0.0;
m_last_pos = 0;
m_last_buffer = netlist::netlist_time::zero;
m_last_buffer = netlist::netlist_time::zero();
}
ATTR_HOT void sound_update(const netlist::netlist_time &upto)
@ -624,11 +626,11 @@ class NETLIB_NAME(sound_in) : public netlist::device_t
{
public:
NETLIB_NAME(sound_in)(netlist::netlist_t &anetlist, const pstring &name)
: netlist::device_t(anetlist, name)
: netlist::device_t(anetlist, name)
, m_feedback(*this, "FB") // clock part
, m_Q(*this, "Q")
{
// clock part
enregister("Q", m_Q);
enregister("FB", m_feedback);
connect_late(m_feedback, m_Q);
m_inc = netlist::netlist_time::from_nsec(1);
@ -678,7 +680,7 @@ public:
m_param[i]->setTo(v * m_param_mult[i]->Value() + m_param_offset[i]->Value());
}
m_pos++;
OUTLOGIC(m_Q, !m_Q.net().as_logic().new_Q(), m_inc );
OUTLOGIC(m_Q, !m_Q.net().new_Q(), m_inc );
}
public:

View File

@ -9,7 +9,10 @@
#include "analog/nld_bjt.h"
#include "nl_setup.h"
NETLIB_NAMESPACE_DEVICES_START()
namespace netlist
{
namespace devices
{
class diode
{
@ -27,9 +30,9 @@ public:
m_VT = 0.0258 * n;
m_VT_inv = 1.0 / m_VT;
}
nl_double I(const nl_double V) const { return m_Is * nl_math::exp(V * m_VT_inv) - m_Is; }
nl_double g(const nl_double V) const { return m_Is * m_VT_inv * nl_math::exp(V * m_VT_inv); }
nl_double V(const nl_double I) const { return nl_math::e_log1p(I / m_Is) * m_VT; } // log1p(x)=log(1.0 + x)
nl_double I(const nl_double V) const { return m_Is * std::exp(V * m_VT_inv) - m_Is; }
nl_double g(const nl_double V) const { return m_Is * m_VT_inv * std::exp(V * m_VT_inv); }
nl_double V(const nl_double I) const { return std::log1p(I / m_Is) * m_VT; } // log1p(x)=log(1.0 + x)
nl_double gI(const nl_double I) const { return m_VT_inv * (I + m_Is); }
private:
@ -187,4 +190,5 @@ NETLIB_UPDATE_PARAM(QBJT_EB)
m_gD_BC.set_param(IS / m_alpha_r, NR, netlist().gmin());
}
NETLIB_NAMESPACE_DEVICES_END()
} //namespace devices
} // namespace netlist

View File

@ -24,7 +24,10 @@
NETDEV_PARAMI(name, MODEL, model)
NETLIB_NAMESPACE_DEVICES_START()
namespace netlist
{
namespace devices
{
// -----------------------------------------------------------------------------
// nld_Q - Base classes
@ -96,21 +99,21 @@ private:
NETLIB_OBJECT_DERIVED(QBJT_switch, QBJT)
{
NETLIB_CONSTRUCTOR_DERIVED(QBJT_switch, QBJT)
, m_RB(owner, "m_RB")
, m_RC(owner, "m_RC")
, m_BC_dummy(owner, "m_BC")
, m_RB(*this, "m_RB", true)
, m_RC(*this, "m_RC", true)
, m_BC_dummy(*this, "m_BC", true)
, m_gB(NETLIST_GMIN_DEFAULT)
, m_gC(NETLIST_GMIN_DEFAULT)
, m_V(0.0)
, m_state_on(0)
{
enregister("B", m_RB.m_P);
enregister("E", m_RB.m_N);
enregister("C", m_RC.m_P);
enregister("_E1", m_RC.m_N);
register_subalias("B", m_RB.m_P);
register_subalias("E", m_RB.m_N);
register_subalias("C", m_RC.m_P);
//register_term("_E1", m_RC.m_N);
enregister("_B1", m_BC_dummy.m_P);
enregister("_C1", m_BC_dummy.m_N);
//register_term("_B1", m_BC_dummy.m_P);
//register_term("_C1", m_BC_dummy.m_N);
connect_late(m_RB.m_N, m_RC.m_N);
@ -152,20 +155,20 @@ NETLIB_OBJECT_DERIVED(QBJT_EB, QBJT)
{
public:
NETLIB_CONSTRUCTOR_DERIVED(QBJT_EB, QBJT)
, m_D_CB(owner, "m_D_CB")
, m_D_EB(owner, "m_D_EB")
, m_D_EC(owner, "m_D_EC")
, m_D_CB(*this, "m_D_CB", true)
, m_D_EB(*this, "m_D_EB", true)
, m_D_EC(*this, "m_D_EC", true)
, m_alpha_f(0)
, m_alpha_r(0)
{
enregister("E", m_D_EB.m_P); // Cathode
enregister("B", m_D_EB.m_N); // Anode
register_subalias("E", m_D_EB.m_P); // Cathode
register_subalias("B", m_D_EB.m_N); // Anode
enregister("C", m_D_CB.m_P); // Cathode
enregister("_B1", m_D_CB.m_N); // Anode
register_subalias("C", m_D_CB.m_P); // Cathode
//register_term("_B1", m_D_CB.m_N); // Anode
enregister("_E1", m_D_EC.m_P);
enregister("_C1", m_D_EC.m_N);
//register_term("_E1", m_D_EC.m_P);
//register_term("_C1", m_D_EC.m_N);
connect_late(m_D_EB.m_P, m_D_EC.m_P);
connect_late(m_D_EB.m_N, m_D_CB.m_N);
@ -185,6 +188,7 @@ protected:
generic_diode m_gD_BC;
generic_diode m_gD_BE;
private:
nld_twoterm m_D_CB; // gcc, gce - gcc, gec - gcc, gcc - gce | Ic
nld_twoterm m_D_EB; // gee, gec - gee, gce - gee, gee - gec | Ie
nld_twoterm m_D_EC; // 0, -gec, -gcc, 0 | 0
@ -192,9 +196,9 @@ protected:
nl_double m_alpha_f;
nl_double m_alpha_r;
private:
};
NETLIB_NAMESPACE_DEVICES_END()
} //namespace devices
} // namespace netlist
#endif /* NLD_BJT_H_ */

View File

@ -9,7 +9,10 @@
#include "nld_fourterm.h"
#include "nl_setup.h"
NETLIB_NAMESPACE_DEVICES_START()
namespace netlist
{
namespace devices
{
// ----------------------------------------------------------------------------------------
// nld_VCCS
@ -117,4 +120,5 @@ NETLIB_RESET(VCVS)
m_ON2.set(NL_FCONST(1.0) / m_RO.Value());
}
NETLIB_NAMESPACE_DEVICES_END()
} //namespace devices
} // namespace netlist

View File

@ -28,7 +28,10 @@
#define LVCCS(name) \
NET_REGISTER_DEV(LVCCS, name)
NETLIB_NAMESPACE_DEVICES_START()
namespace netlist
{
namespace devices
{
// ----------------------------------------------------------------------------------------
// nld_VCCS
@ -57,17 +60,14 @@ public:
NETLIB_CONSTRUCTOR(VCCS)
, m_G(*this, "G", 1.0)
, m_RI(*this, "RI", NL_FCONST(1.0) / netlist().gmin())
, m_OP(*this, "OP")
, m_ON(*this, "ON")
, m_IP(*this, "IP")
, m_IN(*this, "IN")
, m_OP1(*this, "_OP1")
, m_ON1(*this, "_ON1")
, m_gfac(1.0)
{
enregister("IP", m_IP);
enregister("IN", m_IN);
enregister("OP", m_OP);
enregister("ON", m_ON);
enregister("_OP1", m_OP1);
enregister("_ON1", m_ON1);
m_IP.m_otherterm = &m_IN; // <= this should be NULL and terminal be filtered out prior to solving...
m_IN.m_otherterm = &m_IP; // <= this should be NULL and terminal be filtered out prior to solving...
@ -202,12 +202,11 @@ NETLIB_OBJECT_DERIVED(VCVS, VCCS)
{
public:
NETLIB_CONSTRUCTOR_DERIVED(VCVS, VCCS)
, m_RO(*this, "RO",1.0)
, m_RO(*this, "RO", 1.0)
, m_OP2(*this, "_OP2")
, m_ON2(*this, "_ON2")
{
enregister("_OP2", m_OP2);
enregister("_ON2", m_ON2);
m_OP2.m_otherterm = &m_ON2;
m_ON2.m_otherterm = &m_OP2;
@ -227,7 +226,8 @@ protected:
};
NETLIB_NAMESPACE_DEVICES_END()
} //namespace devices
} // namespace netlist
#endif /* NLD_FOURTERM_H_ */

View File

@ -38,7 +38,10 @@ NETLIST_START(opamp_lm3900)
NETLIST_END()
NETLIB_NAMESPACE_DEVICES_START()
namespace netlist
{
namespace devices
{
/*
* Type = 0: Impedance changer
@ -57,7 +60,7 @@ NETLIB_UPDATE(OPAMP)
{
const double cVt = 0.0258 * 1.0; // * m_n;
const double cId = m_model.model_value("DAB"); // 3 mA
const double cVd = cVt * nl_math::log(cId / 1e-15 + 1.0);
const double cVd = cVt * std::log(cId / 1e-15 + 1.0);
m_VH.set_Q(INPANALOG(m_VCC) - m_model.model_value("VLH") - cVd);
m_VL.set_Q(INPANALOG(m_GND) + m_model.model_value("VLL") + cVd);
m_VREF.set_Q((INPANALOG(m_VCC) + INPANALOG(m_GND)) / 2.0);
@ -113,4 +116,5 @@ NETLIB_DEVICE_WITH_PARAMS(OPAMPx,
);
*/
NETLIB_NAMESPACE_DEVICES_END()
} //namespace devices
} // namespace netlist

View File

@ -32,25 +32,26 @@
NETLIST_EXTERNAL(opamp_lm3900)
NETLIB_NAMESPACE_DEVICES_START()
namespace netlist
{
namespace devices
{
NETLIB_OBJECT(OPAMP)
{
NETLIB_CONSTRUCTOR(OPAMP)
, m_RP(*this, "RP1")
, m_G1(*this, "G1")
, m_VCC(*this, "VCC")
, m_GND(*this, "GND")
, m_model(*this, "MODEL", "")
, m_VH(*this, "VH")
, m_VL(*this, "VL")
, m_VREF(*this, "VREF")
{
m_type = m_model.model_value("TYPE");
enregister("VCC", m_VCC);
enregister("GND", m_GND);
enregister("VL", m_VL);
enregister("VH", m_VH);
enregister("VREF", m_VREF);
if (m_type == 1)
{
register_subalias("PLUS", "G1.IP");
@ -121,6 +122,7 @@ private:
unsigned m_type;
};
NETLIB_NAMESPACE_DEVICES_END()
} //namespace devices
} // namespace netlist
#endif /* NLD_OPAMPS_H_ */

View File

@ -11,7 +11,10 @@
#define R_OFF (1.0 / netlist().gmin())
#define R_ON 0.01
NETLIB_NAMESPACE_DEVICES_START()
namespace netlist
{
namespace devices
{
// ----------------------------------------------------------------------------------------
// SWITCH
@ -74,4 +77,5 @@ NETLIB_UPDATE_PARAM(switch2)
update();
}
NETLIB_NAMESPACE_DEVICES_END()
} //namespace devices
} // namespace netlist

View File

@ -27,7 +27,10 @@
// Devices ...
// ----------------------------------------------------------------------------------------
NETLIB_NAMESPACE_DEVICES_START()
namespace netlist
{
namespace devices
{
NETLIB_OBJECT(switch1)
{
@ -71,6 +74,7 @@ NETLIB_OBJECT(switch2)
param_int_t m_POS;
};
NETLIB_NAMESPACE_DEVICES_END()
} //namespace devices
} // namespace netlist
#endif /* NLD_SWITCHES_H_ */

View File

@ -10,13 +10,16 @@
#include "nld_twoterm.h"
NETLIB_NAMESPACE_DEVICES_START()
namespace netlist
{
namespace devices
{
// ----------------------------------------------------------------------------------------
// generic_diode
// ----------------------------------------------------------------------------------------
ATTR_COLD generic_diode::generic_diode()
generic_diode::generic_diode()
{
m_Vd = 0.7;
set_param(1e-15, 1, 1e-15);
@ -24,20 +27,20 @@ ATTR_COLD generic_diode::generic_diode()
m_Id = 0.0;
}
ATTR_COLD void generic_diode::set_param(const nl_double Is, const nl_double n, nl_double gmin)
void generic_diode::set_param(const nl_double Is, const nl_double n, nl_double gmin)
{
static const double csqrt2 = nl_math::sqrt(2.0);
static const double csqrt2 = std::sqrt(2.0);
m_Is = Is;
m_n = n;
m_gmin = gmin;
m_Vt = 0.0258 * m_n;
m_Vcrit = m_Vt * nl_math::log(m_Vt / m_Is / csqrt2);
m_Vcrit = m_Vt * std::log(m_Vt / m_Is / csqrt2);
m_VtInv = 1.0 / m_Vt;
}
ATTR_COLD void generic_diode::save(pstring name, object_t &parent)
void generic_diode::save(pstring name, object_t &parent)
{
parent.save(m_Vd, name + ".m_Vd");
parent.save(m_Id, name + ".m_Id");
@ -50,10 +53,6 @@ ATTR_COLD void generic_diode::save(pstring name, object_t &parent)
NETLIB_UPDATE(twoterm)
{
/* FIXME: some proxies created seem to be disconnected again
* or not even properly connected.
* Example: pong proxy_da_c9c.Q_1.RV
*/
/* only called if connected to a rail net ==> notify the solver to recalculate */
/* we only need to call the non-rail terminal */
if (m_P.has_net() && !m_P.net().isRailNet())
@ -70,7 +69,7 @@ NETLIB_UPDATE_PARAM(POT)
{
nl_double v = m_Dial.Value();
if (m_DialIsLog.Value())
v = (nl_math::exp(v) - 1.0) / (nl_math::exp(1.0) - 1.0);
v = (std::exp(v) - 1.0) / (std::exp(1.0) - 1.0);
m_R1.update_dev();
m_R2.update_dev();
@ -89,7 +88,7 @@ NETLIB_UPDATE_PARAM(POT2)
nl_double v = m_Dial.Value();
if (m_DialIsLog.Value())
v = (nl_math::exp(v) - 1.0) / (nl_math::exp(1.0) - 1.0);
v = (std::exp(v) - 1.0) / (std::exp(1.0) - 1.0);
if (m_Reverse.Value())
v = 1.0 - v;
@ -172,4 +171,5 @@ NETLIB_UPDATE(CS)
NETLIB_NAME(twoterm)::update();
}
NETLIB_NAMESPACE_DEVICES_END()
} //namespace devices
} // namespace netlist

View File

@ -94,7 +94,10 @@
// Implementation
// -----------------------------------------------------------------------------
NETLIB_NAMESPACE_DEVICES_START()
namespace netlist
{
namespace devices
{
// -----------------------------------------------------------------------------
// nld_twoterm
@ -102,8 +105,9 @@ NETLIB_NAMESPACE_DEVICES_START()
NETLIB_OBJECT(twoterm)
{
public:
NETLIB_CONSTRUCTOR(twoterm)
NETLIB_CONSTRUCTOR_EX(twoterm, bool terminals_owned = false)
, m_P(bselect(terminals_owned, owner, *this), (terminals_owned ? name + "." : "") + "1")
, m_N(bselect(terminals_owned, owner, *this), (terminals_owned ? name + "." : "") + "2")
{
m_P.m_otherterm = &m_N;
m_N.m_otherterm = &m_P;
@ -112,24 +116,24 @@ public:
terminal_t m_P;
terminal_t m_N;
NETLIB_UPDATE_TERMINALSI() { }
NETLIB_RESETI() { }
//NETLIB_UPDATE_TERMINALSI() { }
//NETLIB_RESETI() { }
NETLIB_UPDATEI();
public:
ATTR_HOT /* inline */ void set(const nl_double G, const nl_double V, const nl_double I)
/* inline */ void set(const nl_double G, const nl_double V, const nl_double I)
{
/* GO, GT, I */
m_P.set( G, G, ( V) * G - I);
m_N.set( G, G, ( -V) * G + I);
}
ATTR_HOT /* inline */ nl_double deltaV() const
/* inline */ nl_double deltaV() const
{
return m_P.net().as_analog().Q_Analog() - m_N.net().as_analog().Q_Analog();
return m_P.net().Q_Analog() - m_N.net().Q_Analog();
}
ATTR_HOT void set_mat(nl_double a11, nl_double a12, nl_double a21, nl_double a22, nl_double r1, nl_double r2)
void set_mat(nl_double a11, nl_double a12, nl_double a21, nl_double a22, nl_double r1, nl_double r2)
{
/* GO, GT, I */
m_P.set(-a12, a11, -r1);
@ -137,8 +141,15 @@ public:
}
private:
template <class C>
static core_device_t &bselect(bool b, C &d1, core_device_t &d2)
{
core_device_t *h = dynamic_cast<core_device_t *>(&d1);
return b ? *h : d2;
}
};
// -----------------------------------------------------------------------------
// nld_R
// -----------------------------------------------------------------------------
@ -147,8 +158,6 @@ NETLIB_OBJECT_DERIVED(R_base, twoterm)
{
NETLIB_CONSTRUCTOR_DERIVED(R_base, twoterm)
{
enregister("1", m_P);
enregister("2", m_N);
}
public:
@ -269,8 +278,8 @@ public:
, m_C(*this, "C", 1e-6)
, m_GParallel(0.0)
{
enregister("1", m_P);
enregister("2", m_N);
//register_term("1", m_P);
//register_term("2", m_N);
}
NETLIB_TIMESTEP()
@ -302,9 +311,9 @@ private:
class generic_diode
{
public:
ATTR_COLD generic_diode();
generic_diode();
ATTR_HOT inline void update_diode(const nl_double nVd)
inline void update_diode(const nl_double nVd)
{
#if 1
if (nVd < NL_FCONST(-5.0) * m_Vt)
@ -317,7 +326,7 @@ public:
{
m_Vd = nVd;
//m_Vd = m_Vd + 10.0 * m_Vt * std::tanh((nVd - m_Vd) / 10.0 / m_Vt);
const nl_double eVDVt = nl_math::exp(m_Vd * m_VtInv);
const nl_double eVDVt = std::exp(m_Vd * m_VtInv);
m_Id = m_Is * (eVDVt - NL_FCONST(1.0));
m_G = m_Is * m_VtInv * eVDVt + m_gmin;
}
@ -325,33 +334,33 @@ public:
{
#if 1
const nl_double a = std::max((nVd - m_Vd) * m_VtInv, NL_FCONST(0.5) - NL_FCONST(1.0));
m_Vd = m_Vd + nl_math::e_log1p(a) * m_Vt;
m_Vd = m_Vd + std::log1p(a) * m_Vt;
#else
m_Vd = m_Vd + 10.0 * m_Vt * std::tanh((nVd - m_Vd) / 10.0 / m_Vt);
#endif
const nl_double eVDVt = nl_math::exp(m_Vd * m_VtInv);
const nl_double eVDVt = std::exp(m_Vd * m_VtInv);
m_Id = m_Is * (eVDVt - NL_FCONST(1.0));
m_G = m_Is * m_VtInv * eVDVt + m_gmin;
}
#else
m_Vd = m_Vd + 20.0 * m_Vt * std::tanh((nVd - m_Vd) / 20.0 / m_Vt);
const nl_double eVDVt = nl_math::exp(m_Vd * m_VtInv);
const nl_double eVDVt = std::exp(m_Vd * m_VtInv);
m_Id = m_Is * (eVDVt - NL_FCONST(1.0));
m_G = m_Is * m_VtInv * eVDVt + m_gmin;
#endif
}
ATTR_COLD void set_param(const nl_double Is, const nl_double n, nl_double gmin);
void set_param(const nl_double Is, const nl_double n, nl_double gmin);
ATTR_HOT inline nl_double I() const { return m_Id; }
ATTR_HOT inline nl_double G() const { return m_G; }
ATTR_HOT inline nl_double Ieq() const { return (m_Id - m_Vd * m_G); }
ATTR_HOT inline nl_double Vd() const { return m_Vd; }
inline nl_double I() const { return m_Id; }
inline nl_double G() const { return m_G; }
inline nl_double Ieq() const { return (m_Id - m_Vd * m_G); }
inline nl_double Vd() const { return m_Vd; }
/* owning object must save those ... */
ATTR_COLD void save(pstring name, object_t &parent);
void save(pstring name, object_t &parent);
private:
nl_double m_Vd;
@ -377,8 +386,8 @@ public:
NETLIB_CONSTRUCTOR_DERIVED(D, twoterm)
, m_model(*this, "MODEL", "")
{
enregister("A", m_P);
enregister("K", m_N);
register_subalias("A", m_P);
register_subalias("K", m_N);
m_D.save("m_D", *this);
}
@ -412,8 +421,8 @@ public:
, m_V(*this, "V", 0.0)
{
enregister("P", m_P);
enregister("N", m_N);
register_subalias("P", m_P);
register_subalias("N", m_N);
}
protected:
@ -434,8 +443,8 @@ public:
NETLIB_CONSTRUCTOR_DERIVED(CS, twoterm)
, m_I(*this, "I", 1.0)
{
enregister("P", m_P);
enregister("N", m_N);
register_subalias("P", m_P);
register_subalias("N", m_N);
}
NETLIB_UPDATEI();
@ -446,6 +455,7 @@ protected:
};
NETLIB_NAMESPACE_DEVICES_END()
} //namespace devices
} // namespace netlist
#endif /* NLD_TWOTERM_H_ */

View File

@ -14,13 +14,13 @@ SRC = ..
#-fuse-ld=gold -Wpedantic -march=native -march=native
# LTO = -flto=4 -fuse-linker-plugin -flto-partition=balanced -Wodr
LTO = -flto=4 -fuse-linker-plugin -flto-partition=balanced -Wodr
CDEFS = -DPSTANDALONE=1 -DPTR64=1
#-Werror
#CFLAGS = $(LTO) -g -O3 -std=c++98 -Doverride="" -march=native -msse4.2 -Wall -Wpedantic -Wsign-compare -Wextra -Wno-long-long -Wno-unused-parameter -Wno-unused-result -Wno-variadic-macros -I..
#LDFLAGS = $(LTO) -g -O3 -std=c++98
CFLAGS = $(LTO) -g -O3 -std=c++11 -march=native -I.. -Wall -Wpedantic -Wsign-compare -Wextra -Wno-unused-parameter
CFLAGS = $(LTO) -g -O3 -std=c++11 -march=native -I.. -Wall -Wpedantic -Wsign-compare -Wextra -Wno-unused-parameter
LDFLAGS = $(LTO) -g -O3 -std=c++11 -lpthread -ldl
CC = @g++-5
@ -49,11 +49,12 @@ OBJS = $(POBJS) $(NLOBJS)
POBJS := \
$(POBJ)/pstring.o \
$(POBJ)/palloc.o \
$(POBJ)/pdynlib.o \
$(POBJ)/pfmtlog.o \
$(POBJ)/pparser.o \
$(POBJ)/pstate.o \
$(POBJ)/pstream.o \
$(POBJ)/pfmtlog.o \
$(POBJ)/pdynlib.o \
$(POBJ)/putil.o \
NLOBJS := \
$(NLOBJ)/nl_base.o \

View File

@ -11,6 +11,7 @@
#include "net_lib.h"
#include "nld_system.h"
#include "nl_factory.h"
#include "solver/nld_solver.h"
NETLIST_START(diode_models)
NET_MODEL("D _(IS=1e-15 N=1)")
@ -61,7 +62,15 @@ NETLIST_END()
#define ENTRY1(nic, name, defparam) factory.register_device<nic>( # name, xstr(nic), defparam );
#define ENTRY(nic, name, defparam) ENTRY1(NETLIB_NAME(nic), name, defparam)
NETLIB_NAMESPACE_DEVICES_START()
#define NETLIB_DEVICE_DECL(chip) extern factory_creator_ptr_t decl_ ## chip;
#define ENTRYX1(nic, name, defparam, decl) factory.register_device( decl (# name, xstr(nic), defparam) );
#define ENTRYX(nic, name, defparam) { NETLIB_DEVICE_DECL(nic) ENTRYX1(NETLIB_NAME(nic), name, defparam, decl_ ## nic) }
namespace netlist
{
namespace devices
{
void initialize_factory(factory_list_t &factory)
{
@ -77,78 +86,79 @@ void initialize_factory(factory_list_t &factory)
ENTRY(VS, VS, "V")
ENTRY(CS, CS, "I")
ENTRY(OPAMP, OPAMP, "MODEL")
ENTRY(dummy_input, DUMMY_INPUT, "-")
ENTRY(frontier, FRONTIER_DEV, "+I,G,Q") // not intended to be used directly
ENTRY(function, AFUNC, "N,FUNC") // only for macro devices - NO FEEDBACK loops
ENTRYX(dummy_input, DUMMY_INPUT, "-")
ENTRYX(frontier, FRONTIER_DEV, "+I,G,Q") // not intended to be used directly
ENTRYX(function, AFUNC, "N,FUNC") // only for macro devices - NO FEEDBACK loops
ENTRY(QBJT_EB, QBJT_EB, "MODEL")
ENTRY(QBJT_switch, QBJT_SW, "MODEL")
ENTRY(logic_input, TTL_INPUT, "IN")
ENTRY(logic_input, LOGIC_INPUT, "IN,FAMILY")
ENTRY(analog_input, ANALOG_INPUT, "IN")
ENTRY(log, LOG, "+I")
ENTRY(logD, LOGD, "+I,I2")
ENTRY(clock, CLOCK, "FREQ")
ENTRY(extclock, EXTCLOCK, "FREQ")
ENTRY(mainclock, MAINCLOCK, "FREQ")
ENTRY(gnd, GND, "-")
ENTRY(netlistparams, PARAMETER, "-")
ENTRYX(logic_input, TTL_INPUT, "IN")
ENTRYX(logic_input, LOGIC_INPUT, "IN,FAMILY")
ENTRYX(analog_input, ANALOG_INPUT, "IN")
ENTRYX(log, LOG, "+I")
ENTRYX(logD, LOGD, "+I,I2")
ENTRYX(clock, CLOCK, "FREQ")
ENTRYX(extclock, EXTCLOCK, "FREQ")
ENTRYX(mainclock, MAINCLOCK, "FREQ")
ENTRYX(gnd, GND, "-")
ENTRYX(netlistparams, PARAMETER, "-")
ENTRY(solver, SOLVER, "FREQ")
ENTRY(res_sw, RES_SWITCH, "+IN,P1,P2")
ENTRYX(res_sw, RES_SWITCH, "+IN,P1,P2")
ENTRY(switch1, SWITCH, "-")
ENTRY(switch2, SWITCH2, "-")
ENTRY(nicRSFF, NETDEV_RSFF, "+S,R")
ENTRY(nicDelay, NETDEV_DELAY, "-")
ENTRY(7450, TTL_7450_ANDORINVERT, "+A,B,C,D")
ENTRY(7448, TTL_7448, "+A,B,C,D,LTQ,BIQ,RBIQ")
ENTRY(7474, TTL_7474, "+CLK,D,CLRQ,PREQ")
ENTRY(7483, TTL_7483, "+A1,A2,A3,A4,B1,B2,B3,B4,C0")
ENTRY(7490, TTL_7490, "+A,B,R1,R2,R91,R92")
ENTRY(7493, TTL_7493, "+CLKA,CLKB,R1,R2")
ENTRY(74107, TTL_74107, "+CLK,J,K,CLRQ")
ENTRY(74107A, TTL_74107A, "+CLK,J,K,CLRQ")
ENTRY(74123, TTL_74123, "-")
ENTRY(74153, TTL_74153, "+C0,C1,C2,C3,A,B,G")
ENTRY(74175, TTL_74175, "-")
ENTRY(74192, TTL_74192, "-")
ENTRY(74193, TTL_74193, "-")
ENTRYX(nicRSFF, NETDEV_RSFF, "+S,R")
ENTRYX(nicDelay, NETDEV_DELAY, "-")
ENTRYX(7450, TTL_7450_ANDORINVERT, "+A,B,C,D")
ENTRYX(7448, TTL_7448, "+A,B,C,D,LTQ,BIQ,RBIQ")
ENTRYX(7474, TTL_7474, "+CLK,D,CLRQ,PREQ")
ENTRYX(7483, TTL_7483, "+A1,A2,A3,A4,B1,B2,B3,B4,C0")
ENTRYX(7490, TTL_7490, "+A,B,R1,R2,R91,R92")
ENTRYX(7493, TTL_7493, "+CLKA,CLKB,R1,R2")
ENTRYX(74107, TTL_74107, "+CLK,J,K,CLRQ")
ENTRYX(74107A, TTL_74107A, "+CLK,J,K,CLRQ")
ENTRYX(74123, TTL_74123, "-")
ENTRYX(74153, TTL_74153, "+C0,C1,C2,C3,A,B,G")
ENTRYX(74175, TTL_74175, "-")
ENTRYX(74192, TTL_74192, "-")
ENTRYX(74193, TTL_74193, "-")
//ENTRY(74279, TTL_74279, "-") // only dip available
ENTRY(SN74LS629, SN74LS629, "CAP")
ENTRY(82S16, TTL_82S16, "-")
ENTRY(9310, TTL_9310, "-")
ENTRY(9312, TTL_9312, "-")
ENTRY(9316, TTL_9316, "+CLK,ENP,ENT,CLRQ,LOADQ,A,B,C,D")
ENTRY(CD4020, CD4020, "")
ENTRY(CD4066_GATE, CD4066_GATE, "")
ENTRYX(SN74LS629, SN74LS629, "CAP")
ENTRYX(82S16, TTL_82S16, "-")
ENTRYX(9310, TTL_9310, "-")
ENTRYX(9312, TTL_9312, "-")
ENTRYX(9316, TTL_9316, "+CLK,ENP,ENT,CLRQ,LOADQ,A,B,C,D")
ENTRYX(CD4020, CD4020, "")
ENTRYX(CD4066_GATE, CD4066_GATE, "")
/* entries with suffix WI are legacy only */
ENTRY(CD4020, CD4020_WI, "+IP,RESET,VDD,VSS")
ENTRYX(CD4020, CD4020_WI, "+IP,RESET,VDD,VSS")
//ENTRY(4066, CD_4066, "+A,B")
ENTRY(NE555, NE555, "-")
ENTRY(r2r_dac, R2R_DAC, "+VIN,R,N")
ENTRY(4538_dip, CD4538_DIP, "-")
ENTRY(7448_dip, TTL_7448_DIP, "-")
ENTRY(7450_dip, TTL_7450_DIP, "-")
ENTRY(7474_dip, TTL_7474_DIP, "-")
ENTRY(7483_dip, TTL_7483_DIP, "-")
ENTRY(7490_dip, TTL_7490_DIP, "-")
ENTRY(7493_dip, TTL_7493_DIP, "-")
ENTRY(74107_dip, TTL_74107_DIP, "-")
ENTRY(74123_dip, TTL_74123_DIP, "-")
ENTRY(74153_dip, TTL_74153_DIP, "-")
ENTRY(74175_dip, TTL_74175_DIP, "-")
ENTRY(74192_dip, TTL_74192_DIP, "-")
ENTRY(74193_dip, TTL_74193_DIP, "-")
ENTRY(74279_dip, TTL_74279_DIP, "-")
ENTRY(82S16_dip, TTL_82S16_DIP, "-")
ENTRY(9602_dip, TTL_9602_DIP, "-")
ENTRY(9310_dip, TTL_9310_DIP, "-")
ENTRY(9312_dip, TTL_9312_DIP, "-")
ENTRY(9316_dip, TTL_9316_DIP, "-")
ENTRY(SN74LS629_dip, SN74LS629_DIP, "1.CAP1,2.CAP2")
ENTRY(NE555_dip, NE555_DIP, "-")
ENTRY(MM5837_dip, MM5837_DIP, "-")
ENTRYX(NE555, NE555, "-")
ENTRYX(r2r_dac, R2R_DAC, "+VIN,R,N")
ENTRYX(4538_dip, CD4538_DIP, "-")
ENTRYX(7448_dip, TTL_7448_DIP, "-")
ENTRYX(7450_dip, TTL_7450_DIP, "-")
ENTRYX(7474_dip, TTL_7474_DIP, "-")
ENTRYX(7483_dip, TTL_7483_DIP, "-")
ENTRYX(7490_dip, TTL_7490_DIP, "-")
ENTRYX(7493_dip, TTL_7493_DIP, "-")
ENTRYX(74107_dip, TTL_74107_DIP, "-")
ENTRYX(74123_dip, TTL_74123_DIP, "-")
ENTRYX(74153_dip, TTL_74153_DIP, "-")
ENTRYX(74175_dip, TTL_74175_DIP, "-")
ENTRYX(74192_dip, TTL_74192_DIP, "-")
ENTRYX(74193_dip, TTL_74193_DIP, "-")
ENTRYX(74279_dip, TTL_74279_DIP, "-")
ENTRYX(82S16_dip, TTL_82S16_DIP, "-")
ENTRYX(9602_dip, TTL_9602_DIP, "-")
ENTRYX(9310_dip, TTL_9310_DIP, "-")
ENTRYX(9312_dip, TTL_9312_DIP, "-")
ENTRYX(9316_dip, TTL_9316_DIP, "-")
ENTRYX(SN74LS629_dip, SN74LS629_DIP, "1.CAP1,2.CAP2")
ENTRYX(NE555_dip, NE555_DIP, "-")
ENTRYX(MM5837_dip, MM5837_DIP, "-")
}
NETLIB_NAMESPACE_DEVICES_END()
} //namespace devices
} // namespace netlist
namespace netlist
{

View File

@ -5,49 +5,120 @@
*
*/
#include <devices/nlid_cmos.h>
#include "nld_4020.h"
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_UPDATE(CD4020_sub)
namespace netlist
{
UINT8 cnt = m_cnt;
cnt = ( cnt + 1) & 0x3fff;
update_outputs(cnt);
m_cnt = cnt;
}
NETLIB_UPDATE(CD4020)
{
if (INPLOGIC(m_RESET))
namespace devices
{
m_sub.m_cnt = 0;
m_sub.m_IP.inactivate();
/* static */ const netlist_time reset_time = netlist_time::from_nsec(140);
OUTLOGIC(m_sub.m_Q[0], 0, reset_time);
for (int i=3; i<14; i++)
OUTLOGIC(m_sub.m_Q[i], 0, reset_time);
}
else
m_sub.m_IP.activate_hl();
}
inline NETLIB_FUNC_VOID(CD4020_sub, update_outputs, (const UINT16 cnt))
{
/* static */ const netlist_time out_delayQn[14] = {
NLTIME_FROM_NS(180), NLTIME_FROM_NS(280),
NLTIME_FROM_NS(380), NLTIME_FROM_NS(480),
NLTIME_FROM_NS(580), NLTIME_FROM_NS(680),
NLTIME_FROM_NS(780), NLTIME_FROM_NS(880),
NLTIME_FROM_NS(980), NLTIME_FROM_NS(1080),
NLTIME_FROM_NS(1180), NLTIME_FROM_NS(1280),
NLTIME_FROM_NS(1380), NLTIME_FROM_NS(1480),
NETLIB_OBJECT(CD4020_sub)
{
NETLIB_CONSTRUCTOR(CD4020_sub)
NETLIB_FAMILY("CD4XXX")
, m_IP(*this, "IP")
, m_Q(*this, {{"Q1", "_Q2", "_Q3", "Q4", "Q5", "Q6", "Q7", "Q8", "Q9",
"Q10", "Q11", "Q12", "Q13", "Q14"}})
, m_cnt(0)
{
save(NLNAME(m_cnt));
}
NETLIB_RESETI()
{
m_IP.set_state(logic_t::STATE_INP_HL);
m_cnt = 0;
}
NETLIB_UPDATEI();
public:
void update_outputs(const UINT16 cnt);
logic_input_t m_IP;
object_array_t<logic_output_t, 14> m_Q;
UINT16 m_cnt;
};
OUTLOGIC(m_Q[0], 0, out_delayQn[0]);
for (int i=3; i<14; i++)
OUTLOGIC(m_Q[i], (cnt >> i) & 1, out_delayQn[i]);
}
NETLIB_OBJECT(CD4020)
{
NETLIB_CONSTRUCTOR(CD4020)
NETLIB_FAMILY("CD4XXX")
, m_sub(*this, "sub")
, m_supply(*this, "supply")
, m_RESET(*this, "RESET")
{
register_subalias("IP", m_sub.m_IP);
register_subalias("Q1", m_sub.m_Q[0]);
register_subalias("Q4", m_sub.m_Q[3]);
register_subalias("Q5", m_sub.m_Q[4]);
register_subalias("Q6", m_sub.m_Q[5]);
register_subalias("Q7", m_sub.m_Q[6]);
register_subalias("Q8", m_sub.m_Q[7]);
register_subalias("Q9", m_sub.m_Q[8]);
register_subalias("Q10", m_sub.m_Q[9]);
register_subalias("Q11", m_sub.m_Q[10]);
register_subalias("Q12", m_sub.m_Q[11]);
register_subalias("Q13", m_sub.m_Q[12]);
register_subalias("Q14", m_sub.m_Q[13]);
register_subalias("VDD", m_supply.m_vdd);
register_subalias("VSS", m_supply.m_vss);
}
NETLIB_RESETI() { }
NETLIB_UPDATEI();
NETLIB_NAMESPACE_DEVICES_END()
private:
NETLIB_SUB(CD4020_sub) m_sub;
NETLIB_SUB(vdd_vss) m_supply;
logic_input_t m_RESET;
};
NETLIB_UPDATE(CD4020_sub)
{
UINT8 cnt = m_cnt;
cnt = ( cnt + 1) & 0x3fff;
update_outputs(cnt);
m_cnt = cnt;
}
NETLIB_UPDATE(CD4020)
{
if (INPLOGIC(m_RESET))
{
m_sub.m_cnt = 0;
m_sub.m_IP.inactivate();
/* static */ const netlist_time reset_time = netlist_time::from_nsec(140);
OUTLOGIC(m_sub.m_Q[0], 0, reset_time);
for (int i=3; i<14; i++)
OUTLOGIC(m_sub.m_Q[i], 0, reset_time);
}
else
m_sub.m_IP.activate_hl();
}
inline NETLIB_FUNC_VOID(CD4020_sub, update_outputs, (const UINT16 cnt))
{
/* static */ const netlist_time out_delayQn[14] = {
NLTIME_FROM_NS(180), NLTIME_FROM_NS(280),
NLTIME_FROM_NS(380), NLTIME_FROM_NS(480),
NLTIME_FROM_NS(580), NLTIME_FROM_NS(680),
NLTIME_FROM_NS(780), NLTIME_FROM_NS(880),
NLTIME_FROM_NS(980), NLTIME_FROM_NS(1080),
NLTIME_FROM_NS(1180), NLTIME_FROM_NS(1280),
NLTIME_FROM_NS(1380), NLTIME_FROM_NS(1480),
};
OUTLOGIC(m_Q[0], cnt & 1, out_delayQn[0]);
for (int i=3; i<14; i++)
OUTLOGIC(m_Q[i], (cnt >> i) & 1, out_delayQn[i]);
}
NETLIB_DEVICE_IMPL(CD4020)
} //namespace devices
} // namespace netlist

View File

@ -27,97 +27,17 @@
#ifndef NLD_4020_H_
#define NLD_4020_H_
#include "nl_base.h"
#include "nld_cmos.h"
#include "nl_setup.h"
/* FIXME: only used in mario.c */
#define CD4020_WI(name, cIP, cRESET, cVDD, cVSS) \
NET_REGISTER_DEV(CD4020_WI, name) \
NET_CONNECT(name, IP, cIP) \
NET_CONNECT(name, RESET, cRESET) \
NET_CONNECT(name, VDD, cVDD) \
#define CD4020_WI(name, cIP, cRESET, cVDD, cVSS) \
NET_REGISTER_DEV(CD4020_WI, name) \
NET_CONNECT(name, IP, cIP) \
NET_CONNECT(name, RESET, cRESET) \
NET_CONNECT(name, VDD, cVDD) \
NET_CONNECT(name, VSS, cVSS)
#define CD4020(name) \
#define CD4020(name) \
NET_REGISTER_DEV(CD4020, name)
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_OBJECT(CD4020_sub)
{
NETLIB_CONSTRUCTOR(CD4020_sub)
NETLIB_FAMILY("CD4XXX")
, m_cnt(0)
{
enregister("IP", m_IP);
enregister("Q1", m_Q[0]);
enregister("Q4", m_Q[3]);
enregister("Q5", m_Q[4]);
enregister("Q6", m_Q[5]);
enregister("Q7", m_Q[6]);
enregister("Q8", m_Q[7]);
enregister("Q9", m_Q[8]);
enregister("Q10", m_Q[9]);
enregister("Q11", m_Q[10]);
enregister("Q12", m_Q[11]);
enregister("Q13", m_Q[12]);
enregister("Q14", m_Q[13]);
save(NLNAME(m_cnt));
}
NETLIB_RESETI()
{
m_IP.set_state(logic_t::STATE_INP_HL);
m_cnt = 0;
}
NETLIB_UPDATEI();
public:
ATTR_HOT void update_outputs(const UINT16 cnt);
logic_input_t m_IP;
logic_output_t m_Q[14];
UINT16 m_cnt;
};
NETLIB_OBJECT(CD4020)
{
NETLIB_CONSTRUCTOR(CD4020)
NETLIB_FAMILY("CD4XXX")
, m_sub(*this, "sub")
, m_supply(*this, "supply")
{
enregister("RESET", m_RESET);
register_subalias("IP", m_sub.m_IP);
register_subalias("Q1", m_sub.m_Q[0]);
register_subalias("Q4", m_sub.m_Q[3]);
register_subalias("Q5", m_sub.m_Q[4]);
register_subalias("Q6", m_sub.m_Q[5]);
register_subalias("Q7", m_sub.m_Q[6]);
register_subalias("Q8", m_sub.m_Q[7]);
register_subalias("Q9", m_sub.m_Q[8]);
register_subalias("Q10", m_sub.m_Q[9]);
register_subalias("Q11", m_sub.m_Q[10]);
register_subalias("Q12", m_sub.m_Q[11]);
register_subalias("Q13", m_sub.m_Q[12]);
register_subalias("Q14", m_sub.m_Q[13]);
register_subalias("VDD", m_supply.m_vdd);
register_subalias("VSS", m_supply.m_vss);
}
NETLIB_RESETI() { }
NETLIB_UPDATEI();
private:
NETLIB_SUB(CD4020_sub) m_sub;
NETLIB_SUB(vdd_vss) m_supply;
logic_input_t m_RESET;
};
NETLIB_NAMESPACE_DEVICES_END()
#endif /* NLD_4020_H_ */

View File

@ -5,43 +5,72 @@
*
*/
#include <devices/nlid_cmos.h>
#include "analog/nld_twoterm.h"
#include "nld_4066.h"
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_UPDATE(CD4066_GATE)
namespace netlist
{
nl_double sup = (m_supply.vdd() - m_supply.vss());
nl_double low = NL_FCONST(0.45) * sup;
nl_double high = NL_FCONST(0.55) * sup;
nl_double in = INPANALOG(m_control) - m_supply.vss();
nl_double rON = m_base_r * NL_FCONST(5.0) / sup;
nl_double R = -1.0;
namespace devices
{
if (in < low)
NETLIB_OBJECT(CD4066_GATE)
{
R = NL_FCONST(1.0) / netlist().gmin();
}
else if (in > high)
{
R = rON;
}
if (R > NL_FCONST(0.0))
{
// We only need to update the net first if this is a time stepping net
if (1) // m_R.m_P.net().as_analog().solver().is_timestep())
NETLIB_CONSTRUCTOR(CD4066_GATE)
NETLIB_FAMILY("CD4XXX")
, m_supply(*this, "PS")
, m_R(*this, "R")
, m_control(*this, "CTL")
, m_base_r(*this, "BASER", 270.0)
{
m_R.update_dev();
m_R.set_R(R);
m_R.m_P.schedule_after(NLTIME_FROM_NS(1));
}
else
NETLIB_RESETI() { }
NETLIB_UPDATEI();
public:
NETLIB_SUB(vdd_vss) m_supply;
NETLIB_SUB(R) m_R;
analog_input_t m_control;
param_double_t m_base_r;
};
NETLIB_UPDATE(CD4066_GATE)
{
nl_double sup = (m_supply.vdd() - m_supply.vss());
nl_double low = NL_FCONST(0.45) * sup;
nl_double high = NL_FCONST(0.55) * sup;
nl_double in = INPANALOG(m_control) - m_supply.vss();
nl_double rON = m_base_r * NL_FCONST(5.0) / sup;
nl_double R = -1.0;
if (in < low)
{
m_R.set_R(R);
m_R.update_dev();
R = NL_FCONST(1.0) / netlist().gmin();
}
else if (in > high)
{
R = rON;
}
if (R > NL_FCONST(0.0))
{
// We only need to update the net first if this is a time stepping net
if (1) // m_R.m_P.net().as_analog().solver().is_timestep())
{
m_R.update_dev();
m_R.set_R(R);
m_R.m_P.schedule_after(NLTIME_FROM_NS(1));
}
else
{
m_R.set_R(R);
m_R.update_dev();
}
}
}
}
NETLIB_DEVICE_IMPL(CD4066_GATE)
NETLIB_NAMESPACE_DEVICES_END()
} //namespace devices
} // namespace netlist

View File

@ -24,36 +24,9 @@
#ifndef NLD_4066_H_
#define NLD_4066_H_
#include "nl_base.h"
#include "nld_cmos.h"
#include "nl_setup.h"
#define CD4066_GATE(name) \
#define CD4066_GATE(name) \
NET_REGISTER_DEV(CD4066_GATE, name)
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_OBJECT(CD4066_GATE)
{
NETLIB_CONSTRUCTOR(CD4066_GATE)
NETLIB_FAMILY("CD4XXX")
, m_supply(*this, "PS")
, m_R(*this, "R")
, m_base_r(*this, "BASER", 270.0)
{
enregister("CTL", m_control);
}
NETLIB_RESETI() { }
NETLIB_UPDATEI();
public:
NETLIB_SUB(vdd_vss) m_supply;
NETLIB_SUB(R) m_R;
analog_input_t m_control;
param_double_t m_base_r;
};
NETLIB_NAMESPACE_DEVICES_END()
#endif /* NLD_4066_H_ */

View File

@ -7,74 +7,181 @@
#include "nld_74107.h"
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_RESET(74107Asub)
namespace netlist
{
m_clk.set_state(logic_t::STATE_INP_HL);
//m_Q.initial(0);
//m_QQ.initial(1);
m_Q1 = 0;
m_Q2 = 0;
m_F = 0;
}
ATTR_HOT inline void NETLIB_NAME(74107Asub)::newstate(const netlist_sig_t state)
{
const netlist_time delay[2] = { NLTIME_FROM_NS(25), NLTIME_FROM_NS(40) };
OUTLOGIC(m_Q, state, delay[state]);
OUTLOGIC(m_QQ, state ^ 1, delay[state ^ 1]);
}
NETLIB_UPDATE(74107Asub)
{
const netlist_sig_t t = m_Q.net().as_logic().Q();
newstate(((t ^ 1) & m_Q1) | (t & m_Q2) | m_F);
if (m_Q1 ^ 1)
m_clk.inactivate();
}
NETLIB_UPDATE(74107A)
{
const UINT8 JK = (INPLOGIC(m_J) << 1) | INPLOGIC(m_K);
switch (JK)
namespace devices
{
case 0:
m_sub.m_Q1 = 0;
m_sub.m_Q2 = 1;
m_sub.m_F = 0;
NETLIB_OBJECT(74107Asub)
{
NETLIB_CONSTRUCTOR(74107Asub)
, m_clk(*this, "CLK")
, m_Q(*this, "Q")
, m_QQ(*this, "QQ")
, m_Q1(0)
, m_Q2(0)
, m_F(0)
{
save(NLNAME(m_Q1));
save(NLNAME(m_Q2));
save(NLNAME(m_F));
}
NETLIB_RESETI();
NETLIB_UPDATEI();
public:
logic_input_t m_clk;
logic_output_t m_Q;
logic_output_t m_QQ;
netlist_sig_t m_Q1;
netlist_sig_t m_Q2;
netlist_sig_t m_F;
void newstate(const netlist_sig_t state);
};
NETLIB_OBJECT(74107A)
{
NETLIB_CONSTRUCTOR(74107A)
, m_sub(*this, "sub")
, m_J(*this, "J")
, m_K(*this, "K")
, m_clrQ(*this, "CLRQ")
{
register_subalias("CLK", m_sub.m_clk);
register_subalias("Q", m_sub.m_Q);
register_subalias("QQ", m_sub.m_QQ);
}
//NETLIB_RESETI();
NETLIB_UPDATEI();
public:
NETLIB_SUB(74107Asub) m_sub;
logic_input_t m_J;
logic_input_t m_K;
logic_input_t m_clrQ;
};
NETLIB_OBJECT_DERIVED(74107, 74107A)
{
public:
NETLIB_CONSTRUCTOR_DERIVED(74107, 74107A) { }
};
NETLIB_OBJECT(74107_dip)
{
NETLIB_CONSTRUCTOR(74107_dip)
, m_1(*this, "1")
, m_2(*this, "2")
{
register_subalias("1", m_1.m_J);
register_subalias("2", m_1.m_sub.m_QQ);
register_subalias("3", m_1.m_sub.m_Q);
register_subalias("4", m_1.m_K);
register_subalias("5", m_2.m_sub.m_Q);
register_subalias("6", m_2.m_sub.m_QQ);
// register_subalias("7", ); ==> GND
register_subalias("8", m_2.m_J);
register_subalias("9", m_2.m_sub.m_clk);
register_subalias("10", m_2.m_clrQ);
register_subalias("11", m_2.m_K);
register_subalias("12", m_1.m_sub.m_clk);
register_subalias("13", m_1.m_clrQ);
// register_subalias("14", ); ==> VCC
}
//NETLIB_RESETI();
//NETLIB_UPDATEI();
private:
NETLIB_SUB(74107) m_1;
NETLIB_SUB(74107) m_2;
};
NETLIB_RESET(74107Asub)
{
m_clk.set_state(logic_t::STATE_INP_HL);
//m_Q.initial(0);
//m_QQ.initial(1);
m_Q1 = 0;
m_Q2 = 0;
m_F = 0;
}
inline void NETLIB_NAME(74107Asub)::newstate(const netlist_sig_t state)
{
const netlist_time delay[2] = { NLTIME_FROM_NS(25), NLTIME_FROM_NS(40) };
OUTLOGIC(m_Q, state, delay[state]);
OUTLOGIC(m_QQ, state ^ 1, delay[state ^ 1]);
}
NETLIB_UPDATE(74107Asub)
{
const netlist_sig_t t = m_Q.net().Q();
newstate(((t ^ 1) & m_Q1) | (t & m_Q2) | m_F);
if (m_Q1 ^ 1)
m_clk.inactivate();
}
NETLIB_UPDATE(74107A)
{
const UINT8 JK = (INPLOGIC(m_J) << 1) | INPLOGIC(m_K);
switch (JK)
{
case 0:
m_sub.m_Q1 = 0;
m_sub.m_Q2 = 1;
m_sub.m_F = 0;
m_sub.m_clk.inactivate();
break;
case 1: // (!INPLOGIC(m_J) & INPLOGIC(m_K))
m_sub.m_Q1 = 0;
m_sub.m_Q2 = 0;
m_sub.m_F = 0;
break;
case 2: // (INPLOGIC(m_J) & !INPLOGIC(m_K))
m_sub.m_Q1 = 0;
m_sub.m_Q2 = 0;
m_sub.m_F = 1;
break;
case 3: // (INPLOGIC(m_J) & INPLOGIC(m_K))
m_sub.m_Q1 = 1;
m_sub.m_Q2 = 0;
m_sub.m_F = 0;
break;
default:
break;
}
if (!INPLOGIC(m_clrQ))
{
m_sub.m_clk.inactivate();
break;
case 1: // (!INPLOGIC(m_J) & INPLOGIC(m_K))
m_sub.m_Q1 = 0;
m_sub.m_Q2 = 0;
m_sub.m_F = 0;
break;
case 2: // (INPLOGIC(m_J) & !INPLOGIC(m_K))
m_sub.m_Q1 = 0;
m_sub.m_Q2 = 0;
m_sub.m_F = 1;
break;
case 3: // (INPLOGIC(m_J) & INPLOGIC(m_K))
m_sub.m_Q1 = 1;
m_sub.m_Q2 = 0;
m_sub.m_F = 0;
break;
default:
break;
m_sub.newstate(0);
}
else if (!m_sub.m_Q2)
m_sub.m_clk.activate_hl();
}
if (!INPLOGIC(m_clrQ))
{
m_sub.m_clk.inactivate();
m_sub.newstate(0);
}
else if (!m_sub.m_Q2)
m_sub.m_clk.activate_hl();
}
NETLIB_DEVICE_IMPL(74107)
NETLIB_DEVICE_IMPL(74107A)
NETLIB_DEVICE_IMPL(74107_dip)
NETLIB_NAMESPACE_DEVICES_END()
} //namespace devices
} // namespace netlist

View File

@ -59,125 +59,19 @@
#ifndef NLD_74107_H_
#define NLD_74107_H_
#include "nl_base.h"
#include "nl_setup.h"
#define TTL_74107A(name, cCLK, cJ, cK, cCLRQ) \
NET_REGISTER_DEV(TTL_74107A, name) \
NET_CONNECT(name, CLK, cCLK) \
NET_CONNECT(name, J, cJ) \
NET_CONNECT(name, K, cK) \
#define TTL_74107A(name, cCLK, cJ, cK, cCLRQ) \
NET_REGISTER_DEV(TTL_74107A, name) \
NET_CONNECT(name, CLK, cCLK) \
NET_CONNECT(name, J, cJ) \
NET_CONNECT(name, K, cK) \
NET_CONNECT(name, CLRQ, cCLRQ)
#define TTL_74107(name, cCLK, cJ, cK, cCLRQ) \
#define TTL_74107(name, cCLK, cJ, cK, cCLRQ) \
TTL_74107A(name, cCLK, cJ, cK, cCLRQ)
#define TTL_74107_DIP(name) \
#define TTL_74107_DIP(name) \
NET_REGISTER_DEV(TTL_74107_DIP, name)
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_OBJECT(74107Asub)
{
NETLIB_CONSTRUCTOR(74107Asub)
, m_Q1(0)
, m_Q2(0)
, m_F(0)
{
enregister("CLK", m_clk);
enregister("Q", m_Q);
enregister("QQ", m_QQ);
save(NLNAME(m_Q1));
save(NLNAME(m_Q2));
save(NLNAME(m_F));
}
NETLIB_RESETI();
NETLIB_UPDATEI();
public:
logic_input_t m_clk;
logic_output_t m_Q;
logic_output_t m_QQ;
netlist_sig_t m_Q1;
netlist_sig_t m_Q2;
netlist_sig_t m_F;
ATTR_HOT void newstate(const netlist_sig_t state);
};
NETLIB_OBJECT(74107A)
{
NETLIB_CONSTRUCTOR(74107A)
, m_sub(*this, "sub")
{
register_subalias("CLK", m_sub.m_clk);
enregister("J", m_J);
enregister("K", m_K);
enregister("CLRQ", m_clrQ);
register_subalias("Q", m_sub.m_Q);
register_subalias("QQ", m_sub.m_QQ);
}
//NETLIB_RESETI();
NETLIB_UPDATEI();
public:
NETLIB_SUB(74107Asub) m_sub;
logic_input_t m_J;
logic_input_t m_K;
logic_input_t m_clrQ;
};
NETLIB_OBJECT_DERIVED(74107, 74107A)
{
public:
NETLIB_CONSTRUCTOR_DERIVED(74107, 74107A) { }
};
NETLIB_OBJECT(74107_dip)
{
NETLIB_CONSTRUCTOR(74107_dip)
, m_1(*this, "1")
, m_2(*this, "2")
{
register_subalias("1", m_1.m_J);
register_subalias("2", m_1.m_sub.m_QQ);
register_subalias("3", m_1.m_sub.m_Q);
register_subalias("4", m_1.m_K);
register_subalias("5", m_2.m_sub.m_Q);
register_subalias("6", m_2.m_sub.m_QQ);
// register_subalias("7", ); ==> GND
register_subalias("8", m_2.m_J);
register_subalias("9", m_2.m_sub.m_clk);
register_subalias("10", m_2.m_clrQ);
register_subalias("11", m_2.m_K);
register_subalias("12", m_1.m_sub.m_clk);
register_subalias("13", m_1.m_clrQ);
// register_subalias("14", ); ==> VCC
}
//NETLIB_RESETI();
//NETLIB_UPDATEI();
private:
NETLIB_SUB(74107) m_1;
NETLIB_SUB(74107) m_2;
};
NETLIB_NAMESPACE_DEVICES_END()
#endif /* NLD_74107_H_ */

View File

@ -7,135 +7,312 @@
#include "nld_74123.h"
#include "nlid_system.h"
#include "analog/nld_twoterm.h"
#define R_OFF (1E20)
#define R_ON (m_RI.Value())
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_UPDATE(74123)
namespace netlist
{
netlist_sig_t m_trig;
netlist_sig_t res = !INPLOGIC(m_CLRQ);
netlist_time t_AB_to_Q = NLTIME_FROM_NS(10);
netlist_time t_C_to_Q = NLTIME_FROM_NS(10);
if (m_dev_type == 74123)
namespace devices
{
m_trig = (INPLOGIC(m_A) ^ 1) & INPLOGIC(m_B) & INPLOGIC(m_CLRQ);
}
else if (m_dev_type == 9602)
{
m_trig = (INPLOGIC(m_A) ^ 1) | INPLOGIC(m_B);
}
else // 4538
{
m_trig = (INPLOGIC(m_B) ^ 1) | INPLOGIC(m_A);
// The line below is from the datasheet truthtable ... doesn't make sense at all
//res = res | INPLOGIC(m_A) | (INPLOGIC(m_B) ^ 1);
t_AB_to_Q = NLTIME_FROM_NS(300);
t_C_to_Q = NLTIME_FROM_NS(250);
}
if (res)
NETLIB_OBJECT(74123)
{
OUTLOGIC(m_Q, 0, t_C_to_Q);
OUTLOGIC(m_QQ, 1, t_C_to_Q);
/* quick charge until trigger */
/* FIXME: SGS datasheet shows quick charge to 5V,
* though schematics indicate quick charge to Vhigh only.
*/
OUTLOGIC(m_RP_Q, 1, t_C_to_Q); // R_ON
OUTLOGIC(m_RN_Q, 0, t_C_to_Q); // R_OFF
m_state = 2; //charging (quick)
}
else if (!m_last_trig && m_trig)
{
// FIXME: Timing!
OUTLOGIC(m_Q, 1, t_AB_to_Q);
OUTLOGIC(m_QQ, 0,t_AB_to_Q);
OUTLOGIC(m_RN_Q, 1, t_AB_to_Q); // R_ON
OUTLOGIC(m_RP_Q, 0, t_AB_to_Q); // R_OFF
m_state = 1; // discharging
}
m_last_trig = m_trig;
if (m_state == 1)
{
const nl_double vLow = m_KP * TERMANALOG(m_RP.m_R.m_P);
if (INPANALOG(m_CV) < vLow)
NETLIB_CONSTRUCTOR_EX(74123, int dev_type = 74123)
, m_dev_type(dev_type)
, m_RP(*this, "RP")
, m_RN(*this, "RN")
, m_RP_Q(*this, "_RP_Q")
, m_RN_Q(*this, "_RN_Q")
, m_A(*this, "A")
, m_B(*this, "B")
, m_CLRQ(*this, "CLRQ")
, m_Q(*this, "Q")
, m_QQ(*this, "QQ")
, m_CV(*this, "_CV") // internal
, m_K(*this, "K", (m_dev_type == 4538) ? 0.4 : 0.4)
, m_RI(*this, "RI", 400.0) // around 250 for HC series, 400 on LS/TTL, estimated from datasheets
{
OUTLOGIC(m_RN_Q, 0, NLTIME_FROM_NS(10)); // R_OFF
m_state = 2; // charging
if ((m_dev_type != 9602) && (m_dev_type != 4538) )
m_dev_type = 74123;
register_subalias("GND", m_RN.m_R.m_N);
register_subalias("VCC", m_RP.m_R.m_P);
register_subalias("C", m_RN.m_R.m_N);
register_subalias("RC", m_RN.m_R.m_P);
connect_late(m_RP_Q, m_RP.m_I);
connect_late(m_RN_Q, m_RN.m_I);
connect_late(m_RN.m_R.m_P, m_RP.m_R.m_N);
connect_late(m_CV, m_RN.m_R.m_P);
save(NLNAME(m_last_trig));
save(NLNAME(m_state));
save(NLNAME(m_KP));
}
NETLIB_RESETI();
NETLIB_UPDATEI();
private:
int m_dev_type;
public:
NETLIB_SUB(res_sw) m_RP;
NETLIB_SUB(res_sw) m_RN;
logic_output_t m_RP_Q;
logic_output_t m_RN_Q;
logic_input_t m_A;
logic_input_t m_B;
logic_input_t m_CLRQ;
logic_output_t m_Q;
logic_output_t m_QQ;
analog_input_t m_CV;
netlist_sig_t m_last_trig;
UINT8 m_state;
double m_KP;
param_double_t m_K;
param_double_t m_RI;
};
NETLIB_OBJECT(74123_dip)
{
NETLIB_CONSTRUCTOR(74123_dip)
, m_1(*this, "1", 74123)
, m_2(*this, "2", 74123)
{
register_subalias("1", m_1.m_A);
register_subalias("2", m_1.m_B);
register_subalias("3", m_1.m_CLRQ);
register_subalias("4", m_1.m_QQ);
register_subalias("5", m_2.m_Q);
register_subalias("6", m_2.m_RN.m_R.m_N);
register_subalias("7", m_2.m_RN.m_R.m_P);
register_subalias("8", m_1.m_RN.m_R.m_N);
connect_late(m_1.m_RN.m_R.m_N, m_2.m_RN.m_R.m_N);
register_subalias("9", m_2.m_A);
register_subalias("10", m_2.m_B);
register_subalias("11", m_2.m_CLRQ);
register_subalias("12", m_2.m_QQ);
register_subalias("13", m_1.m_Q);
register_subalias("14", m_1.m_RN.m_R.m_N);
register_subalias("15", m_1.m_RN.m_R.m_P);
register_subalias("16", m_1.m_RP.m_R.m_P);
connect_late(m_1.m_RP.m_R.m_P, m_2.m_RP.m_R.m_P);
}
NETLIB_RESETI();
NETLIB_UPDATEI();
private:
NETLIB_SUB(74123) m_1;
NETLIB_SUB(74123) m_2;
};
NETLIB_OBJECT(9602_dip)
{
NETLIB_CONSTRUCTOR(9602_dip)
, m_1(*this, "1", 9602)
, m_2(*this, "2", 9602)
{
register_subalias("1", m_1.m_RN.m_R.m_N); // C1
register_subalias("2", m_1.m_RN.m_R.m_P); // RC1
register_subalias("3", m_1.m_CLRQ);
register_subalias("4", m_1.m_B);
register_subalias("5", m_1.m_A);
register_subalias("6", m_1.m_Q);
register_subalias("7", m_1.m_QQ);
register_subalias("8", m_1.m_RN.m_R.m_N);
connect_late(m_1.m_RN.m_R.m_N, m_2.m_RN.m_R.m_N);
register_subalias("9", m_2.m_QQ);
register_subalias("10", m_2.m_Q);
register_subalias("11", m_2.m_A);
register_subalias("12", m_2.m_B);
register_subalias("13", m_2.m_CLRQ);
register_subalias("14", m_2.m_RN.m_R.m_P); // RC2
register_subalias("15", m_2.m_RN.m_R.m_N); // C2
register_subalias("16", m_1.m_RP.m_R.m_P);
connect_late(m_1.m_RP.m_R.m_P, m_2.m_RP.m_R.m_P);
}
NETLIB_RESETI();
NETLIB_UPDATEI();
private:
NETLIB_SUB(74123) m_1;
NETLIB_SUB(74123) m_2;
};
NETLIB_OBJECT(4538_dip)
{
NETLIB_CONSTRUCTOR(4538_dip)
NETLIB_FAMILY("CD4XXX")
, m_1(*this, "1", 4538)
, m_2(*this, "2", 4538)
{
register_subalias("1", m_1.m_RN.m_R.m_N); // C1
register_subalias("2", m_1.m_RN.m_R.m_P); // RC1
register_subalias("3", m_1.m_CLRQ);
register_subalias("4", m_1.m_A);
register_subalias("5", m_1.m_B);
register_subalias("6", m_1.m_Q);
register_subalias("7", m_1.m_QQ);
register_subalias("8", m_1.m_RN.m_R.m_N);
connect_late(m_1.m_RN.m_R.m_N, m_2.m_RN.m_R.m_N);
register_subalias("9", m_2.m_QQ);
register_subalias("10", m_2.m_Q);
register_subalias("11", m_2.m_B);
register_subalias("12", m_2.m_A);
register_subalias("13", m_2.m_CLRQ);
register_subalias("14", m_2.m_RN.m_R.m_P); // RC2
register_subalias("15", m_2.m_RN.m_R.m_N); // C2
register_subalias("16", m_1.m_RP.m_R.m_P);
connect_late(m_1.m_RP.m_R.m_P, m_2.m_RP.m_R.m_P);
}
NETLIB_RESETI();
NETLIB_UPDATEI();
private:
NETLIB_SUB(74123) m_1;
NETLIB_SUB(74123) m_2;
};
NETLIB_UPDATE(74123)
{
netlist_sig_t m_trig;
netlist_sig_t res = !INPLOGIC(m_CLRQ);
netlist_time t_AB_to_Q = NLTIME_FROM_NS(10);
netlist_time t_C_to_Q = NLTIME_FROM_NS(10);
if (m_dev_type == 74123)
{
m_trig = (INPLOGIC(m_A) ^ 1) & INPLOGIC(m_B) & INPLOGIC(m_CLRQ);
}
else if (m_dev_type == 9602)
{
m_trig = (INPLOGIC(m_A) ^ 1) | INPLOGIC(m_B);
}
else // 4538
{
m_trig = (INPLOGIC(m_B) ^ 1) | INPLOGIC(m_A);
// The line below is from the datasheet truthtable ... doesn't make sense at all
//res = res | INPLOGIC(m_A) | (INPLOGIC(m_B) ^ 1);
t_AB_to_Q = NLTIME_FROM_NS(300);
t_C_to_Q = NLTIME_FROM_NS(250);
}
if (res)
{
OUTLOGIC(m_Q, 0, t_C_to_Q);
OUTLOGIC(m_QQ, 1, t_C_to_Q);
/* quick charge until trigger */
/* FIXME: SGS datasheet shows quick charge to 5V,
* though schematics indicate quick charge to Vhigh only.
*/
OUTLOGIC(m_RP_Q, 1, t_C_to_Q); // R_ON
OUTLOGIC(m_RN_Q, 0, t_C_to_Q); // R_OFF
m_state = 2; //charging (quick)
}
else if (!m_last_trig && m_trig)
{
// FIXME: Timing!
OUTLOGIC(m_Q, 1, t_AB_to_Q);
OUTLOGIC(m_QQ, 0,t_AB_to_Q);
OUTLOGIC(m_RN_Q, 1, t_AB_to_Q); // R_ON
OUTLOGIC(m_RP_Q, 0, t_AB_to_Q); // R_OFF
m_state = 1; // discharging
}
m_last_trig = m_trig;
if (m_state == 1)
{
const nl_double vLow = m_KP * TERMANALOG(m_RP.m_R.m_P);
if (INPANALOG(m_CV) < vLow)
{
OUTLOGIC(m_RN_Q, 0, NLTIME_FROM_NS(10)); // R_OFF
m_state = 2; // charging
}
}
if (m_state == 2)
{
const nl_double vHigh = TERMANALOG(m_RP.m_R.m_P) * (1.0 - m_KP);
if (INPANALOG(m_CV) > vHigh)
{
OUTLOGIC(m_RP_Q, 0, NLTIME_FROM_NS(10)); // R_OFF
OUTLOGIC(m_Q, 0, NLTIME_FROM_NS(10));
OUTLOGIC(m_QQ, 1, NLTIME_FROM_NS(10));
m_state = 0; // waiting
}
}
}
if (m_state == 2)
NETLIB_RESET(74123)
{
const nl_double vHigh = TERMANALOG(m_RP.m_R.m_P) * (1.0 - m_KP);
if (INPANALOG(m_CV) > vHigh)
{
OUTLOGIC(m_RP_Q, 0, NLTIME_FROM_NS(10)); // R_OFF
m_KP = 1.0 / (1.0 + exp(m_K.Value()));
OUTLOGIC(m_Q, 0, NLTIME_FROM_NS(10));
OUTLOGIC(m_QQ, 1, NLTIME_FROM_NS(10));
m_state = 0; // waiting
}
m_RP.do_reset();
m_RN.do_reset();
//m_RP.set_R(R_OFF);
//m_RN.set_R(R_OFF);
m_last_trig = 0;
m_state = 0;
}
}
NETLIB_RESET(74123)
{
m_KP = 1.0 / (1.0 + exp(m_K.Value()));
NETLIB_UPDATE(74123_dip)
{
/* only called during startup */
//_1.update_dev();
//m_2.update_dev();
}
m_RP.do_reset();
m_RN.do_reset();
NETLIB_RESET(74123_dip)
{
//m_1.do_reset();
//m_2.do_reset();
}
//m_RP.set_R(R_OFF);
//m_RN.set_R(R_OFF);
NETLIB_UPDATE(9602_dip)
{
/* only called during startup */
//m_1.update_dev();
//m_2.update_dev();
}
m_last_trig = 0;
m_state = 0;
}
NETLIB_RESET(9602_dip)
{
//m_1.do_reset();
//m_2.do_reset();
}
NETLIB_UPDATE(74123_dip)
{
/* only called during startup */
//_1.update_dev();
//m_2.update_dev();
}
NETLIB_UPDATE(4538_dip)
{
/* only called during startup */
//m_1.update_dev();
//m_2.update_dev();
}
NETLIB_RESET(74123_dip)
{
//m_1.do_reset();
//m_2.do_reset();
}
NETLIB_RESET(4538_dip)
{
m_1.do_reset();
m_2.do_reset();
}
NETLIB_UPDATE(9602_dip)
{
/* only called during startup */
//m_1.update_dev();
//m_2.update_dev();
}
NETLIB_DEVICE_IMPL(74123)
NETLIB_DEVICE_IMPL(74123_dip)
NETLIB_DEVICE_IMPL(4538_dip)
NETLIB_DEVICE_IMPL(9602_dip)
NETLIB_RESET(9602_dip)
{
//m_1.do_reset();
//m_2.do_reset();
}
NETLIB_UPDATE(4538_dip)
{
/* only called during startup */
//m_1.update_dev();
//m_2.update_dev();
}
NETLIB_RESET(4538_dip)
{
m_1.do_reset();
m_2.do_reset();
}
NETLIB_NAMESPACE_DEVICES_END()
} //namespace devices
} // namespace netlist

View File

@ -49,201 +49,26 @@
#ifndef NLD_74123_H_
#define NLD_74123_H_
#include "nl_base.h"
#include "nld_system.h"
#include "analog/nld_twoterm.h"
#include "nl_setup.h"
#define TTL_74123(name) \
#define TTL_74123(name) \
NET_REGISTER_DEV(TTL_74123, name)
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_OBJECT(74123)
{
NETLIB_CONSTRUCTOR_EX(74123, int dev_type = 74123)
, m_dev_type(dev_type)
, m_RP(*this, "RP")
, m_RN(*this, "RN")
, m_K(*this, "K", (m_dev_type == 4538) ? 0.4 : 0.4)
, m_RI(*this, "RI", 400.0) // around 250 for HC series, 400 on LS/TTL, estimated from datasheets
{
if ((m_dev_type != 9602) && (m_dev_type != 4538) )
m_dev_type = 74123;
enregister("A", m_A);
enregister("B", m_B);
enregister("CLRQ", m_CLRQ);
enregister("Q", m_Q);
enregister("QQ", m_QQ);
enregister("_RP_Q", m_RP_Q); // internal
enregister("_RN_Q", m_RN_Q); // internal
enregister("_CV", m_CV); // internal
register_subalias("GND", m_RN.m_R.m_N);
register_subalias("VCC", m_RP.m_R.m_P);
register_subalias("C", m_RN.m_R.m_N);
register_subalias("RC", m_RN.m_R.m_P);
connect_late(m_RP_Q, m_RP.m_I);
connect_late(m_RN_Q, m_RN.m_I);
connect_late(m_RN.m_R.m_P, m_RP.m_R.m_N);
connect_late(m_CV, m_RN.m_R.m_P);
save(NLNAME(m_last_trig));
save(NLNAME(m_state));
save(NLNAME(m_KP));
}
NETLIB_RESETI();
NETLIB_UPDATEI();
private:
int m_dev_type;
public:
NETLIB_SUB(res_sw) m_RP;
NETLIB_SUB(res_sw) m_RN;
logic_output_t m_RP_Q;
logic_output_t m_RN_Q;
logic_input_t m_A;
logic_input_t m_B;
logic_input_t m_CLRQ;
logic_output_t m_Q;
logic_output_t m_QQ;
analog_input_t m_CV;
netlist_sig_t m_last_trig;
UINT8 m_state;
double m_KP;
param_double_t m_K;
param_double_t m_RI;
};
#define TTL_74123_DIP(name) \
#define TTL_74123_DIP(name) \
NET_REGISTER_DEV(TTL_74123_DIP, name)
NETLIB_OBJECT(74123_dip)
{
NETLIB_CONSTRUCTOR(74123_dip)
, m_1(*this, "1", 74123)
, m_2(*this, "2", 74123)
{
register_subalias("1", m_1.m_A);
register_subalias("2", m_1.m_B);
register_subalias("3", m_1.m_CLRQ);
register_subalias("4", m_1.m_QQ);
register_subalias("5", m_2.m_Q);
register_subalias("6", m_2.m_RN.m_R.m_N);
register_subalias("7", m_2.m_RN.m_R.m_P);
register_subalias("8", m_1.m_RN.m_R.m_N);
connect_late(m_1.m_RN.m_R.m_N, m_2.m_RN.m_R.m_N);
register_subalias("9", m_2.m_A);
register_subalias("10", m_2.m_B);
register_subalias("11", m_2.m_CLRQ);
register_subalias("12", m_2.m_QQ);
register_subalias("13", m_1.m_Q);
register_subalias("14", m_1.m_RN.m_R.m_N);
register_subalias("15", m_1.m_RN.m_R.m_P);
register_subalias("16", m_1.m_RP.m_R.m_P);
connect_late(m_1.m_RP.m_R.m_P, m_2.m_RP.m_R.m_P);
}
NETLIB_RESETI();
NETLIB_UPDATEI();
private:
NETLIB_SUB(74123) m_1;
NETLIB_SUB(74123) m_2;
};
/* The 9602 is very similar to the 123. Input triggering is slightly different
* THe 9602 uses an OR gate instead of an AND gate.
* The 9602 uses an OR gate instead of an AND gate.
*/
#define TTL_9602_DIP(name) \
#define TTL_9602_DIP(name) \
NET_REGISTER_DEV(TTL_9602_DIP, name)
NETLIB_OBJECT(9602_dip)
{
NETLIB_CONSTRUCTOR(9602_dip)
, m_1(*this, "1", 9602)
, m_2(*this, "2", 9602)
{
register_subalias("1", m_1.m_RN.m_R.m_N); // C1
register_subalias("2", m_1.m_RN.m_R.m_P); // RC1
register_subalias("3", m_1.m_CLRQ);
register_subalias("4", m_1.m_B);
register_subalias("5", m_1.m_A);
register_subalias("6", m_1.m_Q);
register_subalias("7", m_1.m_QQ);
register_subalias("8", m_1.m_RN.m_R.m_N);
connect_late(m_1.m_RN.m_R.m_N, m_2.m_RN.m_R.m_N);
register_subalias("9", m_2.m_QQ);
register_subalias("10", m_2.m_Q);
register_subalias("11", m_2.m_A);
register_subalias("12", m_2.m_B);
register_subalias("13", m_2.m_CLRQ);
register_subalias("14", m_2.m_RN.m_R.m_P); // RC2
register_subalias("15", m_2.m_RN.m_R.m_N); // C2
register_subalias("16", m_1.m_RP.m_R.m_P);
connect_late(m_1.m_RP.m_R.m_P, m_2.m_RP.m_R.m_P);
}
NETLIB_RESETI();
NETLIB_UPDATEI();
private:
NETLIB_SUB(74123) m_1;
NETLIB_SUB(74123) m_2;
};
/*
* The CD4538 is pretty similar to the 9602
*/
#define CD4538_DIP(name) \
#define CD4538_DIP(name) \
NET_REGISTER_DEV(CD4538_DIP, name)
NETLIB_OBJECT(4538_dip)
{
NETLIB_CONSTRUCTOR(4538_dip)
NETLIB_FAMILY("CD4XXX")
, m_1(*this, "1", 4538)
, m_2(*this, "2", 4538)
{
register_subalias("1", m_1.m_RN.m_R.m_N); // C1
register_subalias("2", m_1.m_RN.m_R.m_P); // RC1
register_subalias("3", m_1.m_CLRQ);
register_subalias("4", m_1.m_A);
register_subalias("5", m_1.m_B);
register_subalias("6", m_1.m_Q);
register_subalias("7", m_1.m_QQ);
register_subalias("8", m_1.m_RN.m_R.m_N);
connect_late(m_1.m_RN.m_R.m_N, m_2.m_RN.m_R.m_N);
register_subalias("9", m_2.m_QQ);
register_subalias("10", m_2.m_Q);
register_subalias("11", m_2.m_B);
register_subalias("12", m_2.m_A);
register_subalias("13", m_2.m_CLRQ);
register_subalias("14", m_2.m_RN.m_R.m_P); // RC2
register_subalias("15", m_2.m_RN.m_R.m_N); // C2
register_subalias("16", m_1.m_RP.m_R.m_P);
connect_late(m_1.m_RP.m_R.m_P, m_2.m_RP.m_R.m_P);
}
NETLIB_RESETI();
NETLIB_UPDATEI();
private:
NETLIB_SUB(74123) m_1;
NETLIB_SUB(74123) m_2;
};
NETLIB_NAMESPACE_DEVICES_END()
#endif /* NLD_74123_H_ */

View File

@ -7,46 +7,135 @@
#include "nld_74153.h"
NETLIB_NAMESPACE_DEVICES_START()
namespace netlist
{
namespace devices
{
/* FIXME: timing is not 100% accurate, Strobe and Select inputs have a
* slightly longer timing.
* Convert this to sub-devices at some time.
*/
NETLIB_RESET(74153sub)
{
m_chan = 0;
}
NETLIB_UPDATE(74153sub)
{
const netlist_time delay[2] = { NLTIME_FROM_NS(23), NLTIME_FROM_NS(18) };
if (!INPLOGIC(m_G))
NETLIB_OBJECT(74153sub)
{
UINT8 t = INPLOGIC(m_C[m_chan]);
OUTLOGIC(m_Y, t, delay[t] );
}
else
NETLIB_CONSTRUCTOR(74153sub)
, m_C(*this, {{"C0", "C1", "C2", "C3"}})
, m_G(*this, "G")
, m_Y(*this, "AY") //FIXME: Change netlists
, m_chan(0)
{
save(NLNAME(m_chan));
}
NETLIB_RESETI();
NETLIB_UPDATEI();
public:
object_array_t<logic_input_t, 4> m_C;
logic_input_t m_G;
logic_output_t m_Y;
int m_chan;
};
NETLIB_OBJECT(74153)
{
OUTLOGIC(m_Y, 0, delay[0]);
NETLIB_CONSTRUCTOR(74153)
, m_sub(*this, "sub")
, m_A(*this, "A")
, m_B(*this, "B")
{
register_subalias("C0", m_sub.m_C[0]);
register_subalias("C1", m_sub.m_C[1]);
register_subalias("C2", m_sub.m_C[2]);
register_subalias("C3", m_sub.m_C[3]);
register_subalias("G", m_sub.m_G);
register_subalias("AY", m_sub.m_Y); //FIXME: Change netlists
}
NETLIB_RESETI() { }
NETLIB_UPDATEI();
public:
NETLIB_SUB(74153sub) m_sub;
logic_input_t m_A;
logic_input_t m_B;
};
NETLIB_OBJECT(74153_dip)
{
NETLIB_CONSTRUCTOR(74153_dip)
, m_1(*this, "1")
, m_2(*this, "2")
, m_A(*this, "14") // m_2.m_B
, m_B(*this, "2") // m_2.m_B
{
register_subalias("1", m_1.m_G);
register_subalias("3", m_1.m_C[3]);
register_subalias("4", m_1.m_C[2]);
register_subalias("5", m_1.m_C[1]);
register_subalias("6", m_1.m_C[0]);
register_subalias("7", m_1.m_Y);
register_subalias("9", m_2.m_Y);
register_subalias("10", m_2.m_C[0]);
register_subalias("11", m_2.m_C[1]);
register_subalias("12", m_2.m_C[2]);
register_subalias("13", m_2.m_C[3]);
register_subalias("15", m_2.m_G);
}
//NETLIB_RESETI();
NETLIB_UPDATEI();
protected:
NETLIB_SUB(74153sub) m_1;
NETLIB_SUB(74153sub) m_2;
logic_input_t m_A;
logic_input_t m_B;
};
NETLIB_RESET(74153sub)
{
m_chan = 0;
}
NETLIB_UPDATE(74153sub)
{
const netlist_time delay[2] = { NLTIME_FROM_NS(23), NLTIME_FROM_NS(18) };
if (!INPLOGIC(m_G))
{
UINT8 t = INPLOGIC(m_C[m_chan]);
OUTLOGIC(m_Y, t, delay[t] );
}
else
{
OUTLOGIC(m_Y, 0, delay[0]);
}
}
}
NETLIB_UPDATE(74153)
{
m_sub.m_chan = (INPLOGIC(m_A) | (INPLOGIC(m_B)<<1));
m_sub.do_update();
}
NETLIB_UPDATE(74153)
{
m_sub.m_chan = (INPLOGIC(m_A) | (INPLOGIC(m_B)<<1));
m_sub.do_update();
}
NETLIB_UPDATE(74153_dip)
{
m_2.m_chan = m_1.m_chan = (INPLOGIC(m_A) | (INPLOGIC(m_B)<<1));
m_1.do_update();
m_2.do_update();
}
NETLIB_UPDATE(74153_dip)
{
m_2.m_chan = m_1.m_chan = (INPLOGIC(m_A) | (INPLOGIC(m_B)<<1));
m_1.do_update();
m_2.do_update();
}
NETLIB_NAMESPACE_DEVICES_END()
NETLIB_DEVICE_IMPL(74153)
NETLIB_DEVICE_IMPL(74153_dip)
} //namespace devices
} // namespace netlist

View File

@ -45,110 +45,19 @@
#ifndef NLD_74153_H_
#define NLD_74153_H_
#include "nl_base.h"
#include "nl_setup.h"
#define TTL_74153(name, cC0, cC1, cC2, cC3, cA, cB, cG) \
NET_REGISTER_DEV(TTL_74153, name) \
NET_CONNECT(name, C0, cC0) \
NET_CONNECT(name, C1, cC1) \
NET_CONNECT(name, C2, cC2) \
NET_CONNECT(name, C3, cC3) \
NET_CONNECT(name, A, cA) \
NET_CONNECT(name, B, cB) \
#define TTL_74153(name, cC0, cC1, cC2, cC3, cA, cB, cG) \
NET_REGISTER_DEV(TTL_74153, name) \
NET_CONNECT(name, C0, cC0) \
NET_CONNECT(name, C1, cC1) \
NET_CONNECT(name, C2, cC2) \
NET_CONNECT(name, C3, cC3) \
NET_CONNECT(name, A, cA) \
NET_CONNECT(name, B, cB) \
NET_CONNECT(name, G, cG)
#define TTL_74153_DIP(name) \
#define TTL_74153_DIP(name) \
NET_REGISTER_DEV(TTL_74153_DIP, name)
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_OBJECT(74153sub)
{
NETLIB_CONSTRUCTOR(74153sub)
, m_chan(0)
{
enregister("C0", m_C[0]);
enregister("C1", m_C[1]);
enregister("C2", m_C[2]);
enregister("C3", m_C[3]);
enregister("G", m_G);
enregister("AY", m_Y); //FIXME: Change netlists
save(NLNAME(m_chan));
}
NETLIB_RESETI();
NETLIB_UPDATEI();
public:
logic_input_t m_C[4];
logic_input_t m_G;
logic_output_t m_Y;
int m_chan;
};
NETLIB_OBJECT(74153)
{
NETLIB_CONSTRUCTOR(74153)
, m_sub(*this, "sub")
{
register_subalias("C0", m_sub.m_C[0]);
register_subalias("C1", m_sub.m_C[1]);
register_subalias("C2", m_sub.m_C[2]);
register_subalias("C3", m_sub.m_C[3]);
enregister("A", m_A);
enregister("B", m_B);
register_subalias("G", m_sub.m_G);
register_subalias("AY", m_sub.m_Y); //FIXME: Change netlists
}
NETLIB_RESETI() { }
NETLIB_UPDATEI();
public:
NETLIB_SUB(74153sub) m_sub;
logic_input_t m_A;
logic_input_t m_B;
};
NETLIB_OBJECT(74153_dip)
{
NETLIB_CONSTRUCTOR(74153_dip)
, m_1(*this, "1")
, m_2(*this, "2")
{
register_subalias("1", m_1.m_G);
enregister("2", m_B); // m_2.m_B
register_subalias("3", m_1.m_C[3]);
register_subalias("4", m_1.m_C[2]);
register_subalias("5", m_1.m_C[1]);
register_subalias("6", m_1.m_C[0]);
register_subalias("7", m_1.m_Y);
register_subalias("9", m_2.m_Y);
register_subalias("10", m_2.m_C[0]);
register_subalias("11", m_2.m_C[1]);
register_subalias("12", m_2.m_C[2]);
register_subalias("13", m_2.m_C[3]);
enregister("14", m_A); // m_2.m_B
register_subalias("15", m_2.m_G);
}
//NETLIB_RESETI();
NETLIB_UPDATEI();
protected:
NETLIB_SUB(74153sub) m_1;
NETLIB_SUB(74153sub) m_2;
logic_input_t m_A;
logic_input_t m_B;
};
NETLIB_NAMESPACE_DEVICES_END()
#endif /* NLD_74153_H_ */

View File

@ -7,59 +7,147 @@
#include "nld_74175.h"
NETLIB_NAMESPACE_DEVICES_START()
static const netlist_time delay[2] = { NLTIME_FROM_NS(25), NLTIME_FROM_NS(25) };
static const netlist_time delay_clear[2] = { NLTIME_FROM_NS(40), NLTIME_FROM_NS(25) };
NETLIB_RESET(74175_sub)
namespace netlist
{
m_CLK.set_state(logic_t::STATE_INP_LH);
m_clrq = 0;
m_data = 0xFF;
}
NETLIB_UPDATE(74175_sub)
{
if (m_clrq)
namespace devices
{
NETLIB_OBJECT(74175_sub)
{
NETLIB_CONSTRUCTOR(74175_sub)
, m_CLK(*this, "CLK")
, m_Q(*this, {{"Q1", "Q2", "Q3", "Q4"}})
, m_QQ(*this, {{"Q1Q", "Q2Q", "Q3Q", "Q4Q"}})
, m_data(0)
{
save(NLNAME(m_clrq));
save(NLNAME(m_data));
}
NETLIB_RESETI();
NETLIB_UPDATEI();
public:
logic_input_t m_CLK;
object_array_t<logic_output_t, 4> m_Q;
object_array_t<logic_output_t, 4> m_QQ;
netlist_sig_t m_clrq;
UINT8 m_data;
};
NETLIB_OBJECT(74175)
{
NETLIB_CONSTRUCTOR(74175)
, m_sub(*this, "sub")
, m_D(*this, {{"D1", "D2", "D3", "D4"}})
, m_CLRQ(*this, "CLRQ")
{
register_subalias("CLK", m_sub.m_CLK);
register_subalias("Q1", m_sub.m_Q[0]);
register_subalias("Q1Q", m_sub.m_QQ[0]);
register_subalias("Q2", m_sub.m_Q[1]);
register_subalias("Q2Q", m_sub.m_QQ[1]);
register_subalias("Q3", m_sub.m_Q[2]);
register_subalias("Q3Q", m_sub.m_QQ[2]);
register_subalias("Q4", m_sub.m_Q[3]);
register_subalias("Q4Q", m_sub.m_QQ[3]);
}
NETLIB_RESETI();
NETLIB_UPDATEI();
protected:
NETLIB_SUB(74175_sub) m_sub;
object_array_t<logic_input_t, 4> m_D;
logic_input_t m_CLRQ;
};
NETLIB_OBJECT_DERIVED(74175_dip, 74175)
{
NETLIB_CONSTRUCTOR_DERIVED(74175_dip, 74175)
{
register_subalias("9", m_sub.m_CLK);
register_subalias("1", m_CLRQ);
register_subalias("4", m_D[0]);
register_subalias("2", m_sub.m_Q[0]);
register_subalias("3", m_sub.m_QQ[0]);
register_subalias("5", m_D[1]);
register_subalias("7", m_sub.m_Q[1]);
register_subalias("6", m_sub.m_QQ[1]);
register_subalias("12", m_D[2]);
register_subalias("10", m_sub.m_Q[2]);
register_subalias("11", m_sub.m_QQ[2]);
register_subalias("13", m_D[3]);
register_subalias("15", m_sub.m_Q[3]);
register_subalias("14", m_sub.m_QQ[3]);
}
};
const netlist_time delay[2] = { NLTIME_FROM_NS(25), NLTIME_FROM_NS(25) };
const netlist_time delay_clear[2] = { NLTIME_FROM_NS(40), NLTIME_FROM_NS(25) };
NETLIB_RESET(74175_sub)
{
m_CLK.set_state(logic_t::STATE_INP_LH);
m_clrq = 0;
m_data = 0xFF;
}
NETLIB_UPDATE(74175_sub)
{
if (m_clrq)
{
for (int i=0; i<4; i++)
{
UINT8 d = (m_data >> i) & 1;
OUTLOGIC(m_Q[i], d, delay[d]);
OUTLOGIC(m_QQ[i], d ^ 1, delay[d ^ 1]);
}
m_CLK.inactivate();
}
}
NETLIB_UPDATE(74175)
{
UINT8 d = 0;
for (int i=0; i<4; i++)
{
UINT8 d = (m_data >> i) & 1;
OUTLOGIC(m_Q[i], d, delay[d]);
OUTLOGIC(m_QQ[i], d ^ 1, delay[d ^ 1]);
d |= (INPLOGIC(m_D[i]) << i);
}
m_CLK.inactivate();
}
}
NETLIB_UPDATE(74175)
{
UINT8 d = 0;
for (int i=0; i<4; i++)
{
d |= (INPLOGIC(m_D[i]) << i);
}
m_sub.m_clrq = INPLOGIC(m_CLRQ);
if (!m_sub.m_clrq)
{
for (int i=0; i<4; i++)
m_sub.m_clrq = INPLOGIC(m_CLRQ);
if (!m_sub.m_clrq)
{
OUTLOGIC(m_sub.m_Q[i], 0, delay_clear[0]);
OUTLOGIC(m_sub.m_QQ[i], 1, delay_clear[1]);
for (int i=0; i<4; i++)
{
OUTLOGIC(m_sub.m_Q[i], 0, delay_clear[0]);
OUTLOGIC(m_sub.m_QQ[i], 1, delay_clear[1]);
}
m_sub.m_data = 0;
} else if (d != m_sub.m_data)
{
m_sub.m_data = d;
m_sub.m_CLK.activate_lh();
}
m_sub.m_data = 0;
} else if (d != m_sub.m_data)
{
m_sub.m_data = d;
m_sub.m_CLK.activate_lh();
}
}
NETLIB_RESET(74175)
{
//m_sub.do_reset();
}
NETLIB_RESET(74175)
{
//m_sub.do_reset();
}
NETLIB_NAMESPACE_DEVICES_END()
NETLIB_DEVICE_IMPL(74175)
NETLIB_DEVICE_IMPL(74175_dip)
} //namespace devices
} // namespace netlist

View File

@ -36,107 +36,12 @@
#ifndef NLD_74175_H_
#define NLD_74175_H_
#include "nl_base.h"
#include "nl_setup.h"
#define TTL_74175(name) \
NET_REGISTER_DEV(TTL_74175, name)
#define TTL_74175_DIP(name) \
NET_REGISTER_DEV(TTL_74175_DIP, name)
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_OBJECT(74175_sub)
{
NETLIB_CONSTRUCTOR(74175_sub)
, m_data(0)
{
enregister("CLK", m_CLK);
enregister("Q1", m_Q[0]);
enregister("Q1Q", m_QQ[0]);
enregister("Q2", m_Q[1]);
enregister("Q2Q", m_QQ[1]);
enregister("Q3", m_Q[2]);
enregister("Q3Q", m_QQ[2]);
enregister("Q4", m_Q[3]);
enregister("Q4Q", m_QQ[3]);
save(NLNAME(m_clrq));
save(NLNAME(m_data));
}
NETLIB_RESETI();
NETLIB_UPDATEI();
public:
logic_input_t m_CLK;
logic_output_t m_Q[4];
logic_output_t m_QQ[4];
netlist_sig_t m_clrq;
UINT8 m_data;
};
NETLIB_OBJECT(74175)
{
NETLIB_CONSTRUCTOR(74175)
, m_sub(*this, "sub")
{
register_subalias("CLK", m_sub.m_CLK);
enregister("CLRQ", m_CLRQ);
enregister("D1", m_D[0]);
register_subalias("Q1", m_sub.m_Q[0]);
register_subalias("Q1Q", m_sub.m_QQ[0]);
enregister("D2", m_D[1]);
register_subalias("Q2", m_sub.m_Q[1]);
register_subalias("Q2Q", m_sub.m_QQ[1]);
enregister("D3", m_D[2]);
register_subalias("Q3", m_sub.m_Q[2]);
register_subalias("Q3Q", m_sub.m_QQ[2]);
enregister("D4", m_D[3]);
register_subalias("Q4", m_sub.m_Q[3]);
register_subalias("Q4Q", m_sub.m_QQ[3]);
}
NETLIB_RESETI();
NETLIB_UPDATEI();
protected:
NETLIB_SUB(74175_sub) m_sub;
logic_input_t m_D[4];
logic_input_t m_CLRQ;
};
NETLIB_OBJECT_DERIVED(74175_dip, 74175)
{
NETLIB_CONSTRUCTOR_DERIVED(74175_dip, 74175)
{
register_subalias("9", m_sub.m_CLK);
register_subalias("1", m_CLRQ);
register_subalias("4", m_D[0]);
register_subalias("2", m_sub.m_Q[0]);
register_subalias("3", m_sub.m_QQ[0]);
register_subalias("5", m_D[1]);
register_subalias("7", m_sub.m_Q[1]);
register_subalias("6", m_sub.m_QQ[1]);
register_subalias("12", m_D[2]);
register_subalias("10", m_sub.m_Q[2]);
register_subalias("11", m_sub.m_QQ[2]);
register_subalias("13", m_D[3]);
register_subalias("15", m_sub.m_Q[3]);
register_subalias("14", m_sub.m_QQ[3]);
}
};
NETLIB_NAMESPACE_DEVICES_END()
#endif /* NLD_74175_H_ */

View File

@ -9,67 +9,163 @@
#include "nld_74192.h"
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_RESET(74192)
namespace netlist
{
m_cnt = 0;
m_last_CU = 0;
m_last_CD = 0;
}
namespace devices
{
// FIXME: Timing
/* static */ const netlist_time delay[4] =
{
NLTIME_FROM_NS(40),
NLTIME_FROM_NS(40),
NLTIME_FROM_NS(40),
NLTIME_FROM_NS(40)
};
NETLIB_OBJECT(74192_subABCD)
{
NETLIB_CONSTRUCTOR(74192_subABCD)
, m_A(*this, "A")
, m_B(*this, "B")
, m_C(*this, "C")
, m_D(*this, "D")
{
}
NETLIB_UPDATE(74192)
{
int tCarry = 1;
int tBorrow = 1;
if (INPLOGIC(m_CLEAR))
//NETLIB_RESETI()
//NETLIB_UPDATEI();
public:
logic_input_t m_A;
logic_input_t m_B;
logic_input_t m_C;
logic_input_t m_D;
inline UINT8 read_ABCD() const
{
//return (INPLOGIC_PASSIVE(m_D) << 3) | (INPLOGIC_PASSIVE(m_C) << 2) | (INPLOGIC_PASSIVE(m_B) << 1) | (INPLOGIC_PASSIVE(m_A) << 0);
return (INPLOGIC(m_D) << 3) | (INPLOGIC(m_C) << 2) | (INPLOGIC(m_B) << 1) | (INPLOGIC(m_A) << 0);
}
};
NETLIB_OBJECT(74192)
{
NETLIB_CONSTRUCTOR(74192)
, m_ABCD(*this, "subABCD")
, m_CLEAR(*this, "CLEAR")
, m_LOADQ(*this, "LOADQ")
, m_CU(*this, "CU")
, m_CD(*this, "CD")
, m_Q(*this, {{"QA", "QB", "QC", "QD"}})
, m_BORROWQ(*this, "BORROWQ")
, m_CARRYQ(*this, "CARRYQ")
{
register_subalias("A", m_ABCD.m_A);
register_subalias("B", m_ABCD.m_B);
register_subalias("C", m_ABCD.m_C);
register_subalias("D", m_ABCD.m_D);
save(NLNAME(m_cnt));
save(NLNAME(m_last_CU));
save(NLNAME(m_last_CD));
}
NETLIB_RESETI();
NETLIB_UPDATEI();
protected:
NETLIB_SUB(74192_subABCD) m_ABCD;
logic_input_t m_CLEAR;
logic_input_t m_LOADQ;
logic_input_t m_CU;
logic_input_t m_CD;
INT8 m_cnt;
UINT8 m_last_CU;
UINT8 m_last_CD;
object_array_t<logic_output_t, 4> m_Q;
logic_output_t m_BORROWQ;
logic_output_t m_CARRYQ;
};
NETLIB_OBJECT_DERIVED(74192_dip, 74192)
{
NETLIB_CONSTRUCTOR_DERIVED(74192_dip, 74192)
{
register_subalias("1", m_ABCD.m_B);
register_subalias("2", m_Q[1]);
register_subalias("3", m_Q[0]);
register_subalias("4", m_CD);
register_subalias("5", m_CU);
register_subalias("6", m_Q[2]);
register_subalias("7", m_Q[3]);
register_subalias("9", m_ABCD.m_D);
register_subalias("10", m_ABCD.m_C);
register_subalias("11", m_LOADQ);
register_subalias("12", m_CARRYQ);
register_subalias("13", m_BORROWQ);
register_subalias("14", m_CLEAR);
register_subalias("15", m_ABCD.m_A);
}
};
NETLIB_RESET(74192)
{
m_cnt = 0;
m_last_CU = 0;
m_last_CD = 0;
}
else if (!INPLOGIC(m_LOADQ))
// FIXME: Timing
static const netlist_time delay[4] =
{
m_cnt = m_ABCD.read_ABCD();
}
else
NLTIME_FROM_NS(40),
NLTIME_FROM_NS(40),
NLTIME_FROM_NS(40),
NLTIME_FROM_NS(40)
};
NETLIB_UPDATE(74192)
{
if (INPLOGIC(m_CD) && !m_last_CU && INPLOGIC(m_CU))
int tCarry = 1;
int tBorrow = 1;
if (INPLOGIC(m_CLEAR))
{
m_cnt++;
if (m_cnt > MAXCNT)
m_cnt = 0;
m_cnt = 0;
}
if (INPLOGIC(m_CU) && !m_last_CD && INPLOGIC(m_CD))
else if (!INPLOGIC(m_LOADQ))
{
if (m_cnt > 0)
m_cnt--;
else
m_cnt = MAXCNT;
m_cnt = m_ABCD.read_ABCD();
}
else
{
if (INPLOGIC(m_CD) && !m_last_CU && INPLOGIC(m_CU))
{
m_cnt++;
if (m_cnt > MAXCNT)
m_cnt = 0;
}
if (INPLOGIC(m_CU) && !m_last_CD && INPLOGIC(m_CD))
{
if (m_cnt > 0)
m_cnt--;
else
m_cnt = MAXCNT;
}
}
if (!INPLOGIC(m_CU) && (m_cnt == MAXCNT))
tCarry = 0;
if (!INPLOGIC(m_CD) && (m_cnt == 0))
tBorrow = 0;
m_last_CD = INPLOGIC(m_CD);
m_last_CU = INPLOGIC(m_CU);
for (int i=0; i<4; i++)
OUTLOGIC(m_Q[i], (m_cnt >> i) & 1, delay[i]);
OUTLOGIC(m_BORROWQ, tBorrow, NLTIME_FROM_NS(20)); //FIXME
OUTLOGIC(m_CARRYQ, tCarry, NLTIME_FROM_NS(20)); //FIXME
}
if (!INPLOGIC(m_CU) && (m_cnt == MAXCNT))
tCarry = 0;
NETLIB_DEVICE_IMPL(74192)
NETLIB_DEVICE_IMPL(74192_dip)
if (!INPLOGIC(m_CD) && (m_cnt == 0))
tBorrow = 0;
m_last_CD = INPLOGIC(m_CD);
m_last_CU = INPLOGIC(m_CU);
for (int i=0; i<4; i++)
OUTLOGIC(m_Q[i], (m_cnt >> i) & 1, delay[i]);
OUTLOGIC(m_BORROWQ, tBorrow, NLTIME_FROM_NS(20)); //FIXME
OUTLOGIC(m_CARRYQ, tCarry, NLTIME_FROM_NS(20)); //FIXME
}
NETLIB_NAMESPACE_DEVICES_END()
} //namespace devices
} // namespace netlist

View File

@ -29,84 +29,12 @@
#ifndef NLD_74192_H_
#define NLD_74192_H_
#include "nl_base.h"
#include "nld_9316.h"
#include "nl_setup.h"
#define TTL_74192(name) \
#define TTL_74192(name) \
NET_REGISTER_DEV(TTL_74192, name)
#define TTL_74192_DIP(name) \
#define TTL_74192_DIP(name) \
NET_REGISTER_DEV(TTL_74192_DIP, name)
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_OBJECT(74192)
{
NETLIB_CONSTRUCTOR(74192)
, m_ABCD(*this, "subABCD")
{
register_subalias("A", m_ABCD.m_A);
register_subalias("B", m_ABCD.m_B);
register_subalias("C", m_ABCD.m_C);
register_subalias("D", m_ABCD.m_D);
enregister("CLEAR", m_CLEAR);
enregister("LOADQ", m_LOADQ);
enregister("CU", m_CU);
enregister("CD", m_CD);
enregister("QA", m_Q[0]);
enregister("QB", m_Q[1]);
enregister("QC", m_Q[2]);
enregister("QD", m_Q[3]);
enregister("BORROWQ", m_BORROWQ);
enregister("CARRYQ", m_CARRYQ);
save(NLNAME(m_cnt));
save(NLNAME(m_last_CU));
save(NLNAME(m_last_CD));
}
NETLIB_RESETI();
NETLIB_UPDATEI();
protected:
NETLIB_SUB(9316_subABCD) m_ABCD;
logic_input_t m_CLEAR;
logic_input_t m_LOADQ;
logic_input_t m_CU;
logic_input_t m_CD;
INT8 m_cnt;
UINT8 m_last_CU;
UINT8 m_last_CD;
logic_output_t m_Q[4];
logic_output_t m_BORROWQ;
logic_output_t m_CARRYQ;
};
NETLIB_OBJECT_DERIVED(74192_dip, 74192)
{
NETLIB_CONSTRUCTOR_DERIVED(74192_dip, 74192)
{
register_subalias("1", m_ABCD.m_B);
register_subalias("2", m_Q[1]);
register_subalias("3", m_Q[0]);
register_subalias("4", m_CD);
register_subalias("5", m_CU);
register_subalias("6", m_Q[2]);
register_subalias("7", m_Q[3]);
register_subalias("9", m_ABCD.m_D);
register_subalias("10", m_ABCD.m_C);
register_subalias("11", m_LOADQ);
register_subalias("12", m_CARRYQ);
register_subalias("13", m_BORROWQ);
register_subalias("14", m_CLEAR);
register_subalias("15", m_ABCD.m_A);
}
};
NETLIB_NAMESPACE_DEVICES_END()
#endif /* NLD_74192_H_ */

View File

@ -9,69 +9,144 @@
#include "nld_74193.h"
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_RESET(74193)
namespace netlist
{
m_cnt = 0;
m_last_CU = 0;
m_last_CD = 0;
}
namespace devices
{
// FIXME: Timing
static const netlist_time delay[4] =
{
NLTIME_FROM_NS(40),
NLTIME_FROM_NS(40),
NLTIME_FROM_NS(40),
NLTIME_FROM_NS(40)
};
NETLIB_OBJECT(74193)
{
NETLIB_CONSTRUCTOR(74193)
, m_A(*this, "A")
, m_B(*this, "B")
, m_C(*this, "C")
, m_D(*this, "D")
, m_CLEAR(*this, "CLEAR")
, m_LOADQ(*this, "LOADQ")
, m_CU(*this, "CU")
, m_CD(*this, "CD")
, m_cnt(0)
, m_last_CU(0)
, m_last_CD(0)
, m_Q(*this, {{"QA", "QB", "QC", "QD"}})
, m_BORROWQ(*this, "BORROWQ")
, m_CARRYQ(*this, "CARRYQ")
{
NETLIB_UPDATE(74193)
{
int tCarry = 1;
int tBorrow = 1;
if (INPLOGIC(m_CLEAR))
save(NLNAME(m_cnt));
save(NLNAME(m_last_CU));
save(NLNAME(m_last_CD));
}
NETLIB_RESETI();
NETLIB_UPDATEI();
protected:
logic_input_t m_A;
logic_input_t m_B;
logic_input_t m_C;
logic_input_t m_D;
logic_input_t m_CLEAR;
logic_input_t m_LOADQ;
logic_input_t m_CU;
logic_input_t m_CD;
INT8 m_cnt;
UINT8 m_last_CU;
UINT8 m_last_CD;
object_array_t<logic_output_t, 4> m_Q;
logic_output_t m_BORROWQ;
logic_output_t m_CARRYQ;
};
NETLIB_OBJECT_DERIVED(74193_dip, 74193)
{
NETLIB_CONSTRUCTOR_DERIVED(74193_dip, 74193)
{
register_subalias("1", m_B);
register_subalias("2", m_Q[1]);
register_subalias("3", m_Q[0]);
register_subalias("4", m_CD);
register_subalias("5", m_CU);
register_subalias("6", m_Q[2]);
register_subalias("7", m_Q[3]);
register_subalias("9", m_D);
register_subalias("10", m_C);
register_subalias("11", m_LOADQ);
register_subalias("12", m_CARRYQ);
register_subalias("13", m_BORROWQ);
register_subalias("14", m_CLEAR);
register_subalias("15", m_A);
}
};
NETLIB_RESET(74193)
{
m_cnt = 0;
m_last_CU = 0;
m_last_CD = 0;
}
else if (!INPLOGIC(m_LOADQ))
// FIXME: Timing
static const netlist_time delay[4] =
{
m_cnt = (INPLOGIC(m_D) << 3) | (INPLOGIC(m_C) << 2)
| (INPLOGIC(m_B) << 1) | (INPLOGIC(m_A) << 0);
}
else
NLTIME_FROM_NS(40),
NLTIME_FROM_NS(40),
NLTIME_FROM_NS(40),
NLTIME_FROM_NS(40)
};
NETLIB_UPDATE(74193)
{
if (INPLOGIC(m_CD) && !m_last_CU && INPLOGIC(m_CU))
int tCarry = 1;
int tBorrow = 1;
if (INPLOGIC(m_CLEAR))
{
m_cnt++;
if (m_cnt > MAXCNT)
m_cnt = 0;
m_cnt = 0;
}
if (INPLOGIC(m_CU) && !m_last_CD && INPLOGIC(m_CD))
else if (!INPLOGIC(m_LOADQ))
{
if (m_cnt > 0)
m_cnt--;
else
m_cnt = MAXCNT;
m_cnt = (INPLOGIC(m_D) << 3) | (INPLOGIC(m_C) << 2)
| (INPLOGIC(m_B) << 1) | (INPLOGIC(m_A) << 0);
}
else
{
if (INPLOGIC(m_CD) && !m_last_CU && INPLOGIC(m_CU))
{
m_cnt++;
if (m_cnt > MAXCNT)
m_cnt = 0;
}
if (INPLOGIC(m_CU) && !m_last_CD && INPLOGIC(m_CD))
{
if (m_cnt > 0)
m_cnt--;
else
m_cnt = MAXCNT;
}
}
if (!INPLOGIC(m_CU) && (m_cnt == MAXCNT))
tCarry = 0;
if (!INPLOGIC(m_CD) && (m_cnt == 0))
tBorrow = 0;
m_last_CD = INPLOGIC(m_CD);
m_last_CU = INPLOGIC(m_CU);
for (int i=0; i<4; i++)
OUTLOGIC(m_Q[i], (m_cnt >> i) & 1, delay[i]);
OUTLOGIC(m_BORROWQ, tBorrow, NLTIME_FROM_NS(20)); //FIXME
OUTLOGIC(m_CARRYQ, tCarry, NLTIME_FROM_NS(20)); //FIXME
}
if (!INPLOGIC(m_CU) && (m_cnt == MAXCNT))
tCarry = 0;
NETLIB_DEVICE_IMPL(74193)
NETLIB_DEVICE_IMPL(74193_dip)
if (!INPLOGIC(m_CD) && (m_cnt == 0))
tBorrow = 0;
m_last_CD = INPLOGIC(m_CD);
m_last_CU = INPLOGIC(m_CU);
for (int i=0; i<4; i++)
OUTLOGIC(m_Q[i], (m_cnt >> i) & 1, delay[i]);
OUTLOGIC(m_BORROWQ, tBorrow, NLTIME_FROM_NS(20)); //FIXME
OUTLOGIC(m_CARRYQ, tCarry, NLTIME_FROM_NS(20)); //FIXME
}
NETLIB_NAMESPACE_DEVICES_END()
} //namespace devices
} // namespace netlist

View File

@ -26,89 +26,12 @@
#ifndef NLD_74193_H_
#define NLD_74193_H_
#include "nl_base.h"
#include "nl_setup.h"
#define TTL_74193(name) \
#define TTL_74193(name) \
NET_REGISTER_DEV(TTL_74193, name)
#define TTL_74193_DIP(name) \
#define TTL_74193_DIP(name) \
NET_REGISTER_DEV(TTL_74193_DIP, name)
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_OBJECT(74193)
{
NETLIB_CONSTRUCTOR(74193)
, m_cnt(0)
, m_last_CU(0)
, m_last_CD(0)
{
enregister("A", m_A);
enregister("B", m_B);
enregister("C", m_C);
enregister("D", m_D);
enregister("CLEAR", m_CLEAR);
enregister("LOADQ", m_LOADQ);
enregister("CU", m_CU);
enregister("CD", m_CD);
enregister("QA", m_Q[0]);
enregister("QB", m_Q[1]);
enregister("QC", m_Q[2]);
enregister("QD", m_Q[3]);
enregister("BORROWQ", m_BORROWQ);
enregister("CARRYQ", m_CARRYQ);
save(NLNAME(m_cnt));
save(NLNAME(m_last_CU));
save(NLNAME(m_last_CD));
}
NETLIB_RESETI();
NETLIB_UPDATEI();
protected:
logic_input_t m_A;
logic_input_t m_B;
logic_input_t m_C;
logic_input_t m_D;
logic_input_t m_CLEAR;
logic_input_t m_LOADQ;
logic_input_t m_CU;
logic_input_t m_CD;
INT8 m_cnt;
UINT8 m_last_CU;
UINT8 m_last_CD;
logic_output_t m_Q[4];
logic_output_t m_BORROWQ;
logic_output_t m_CARRYQ;
};
NETLIB_OBJECT_DERIVED(74193_dip, 74193)
{
NETLIB_CONSTRUCTOR_DERIVED(74193_dip, 74193)
{
register_subalias("1", m_B);
register_subalias("2", m_Q[1]);
register_subalias("3", m_Q[0]);
register_subalias("4", m_CD);
register_subalias("5", m_CU);
register_subalias("6", m_Q[2]);
register_subalias("7", m_Q[3]);
register_subalias("9", m_D);
register_subalias("10", m_C);
register_subalias("11", m_LOADQ);
register_subalias("12", m_CARRYQ);
register_subalias("13", m_BORROWQ);
register_subalias("14", m_CLEAR);
register_subalias("15", m_A);
}
};
NETLIB_NAMESPACE_DEVICES_END()
#endif /* NLD_74193_H_ */

View File

@ -6,134 +6,79 @@
*/
#include "nld_74279.h"
#include "nld_truthtable.h"
NETLIB_NAMESPACE_DEVICES_START()
nld_74279A::truthtable_t nld_74279A::m_ttbl;
nld_74279B::truthtable_t nld_74279B::m_ttbl;
#if 0
const char *nld_74279A::m_desc[] = {
"S,R,PQ,PS,PR|Q",
"0,0,X,X,X|1|22",
"0,1,X,X,X|1|22",
"1,0,X,X,X|0|15",
"1,1,0,X,X|0|15",
"1,1,1,X,X|1|22",
""
};
const char *nld_74279B::m_desc[] = {
"S1,S2,R,PQ,PS1,PS2,PR|Q",
"0,X,0,X,X,X,X|1|22",
"X,0,0,X,X,X,X|1|22",
"0,X,1,X,X,X,X|1|22",
"X,0,1,X,X,X,X|1|22",
"1,1,0,X,X,X,X|0|15",
"1,1,1,0,X,X,X|0|15",
"1,1,1,1,X,X,X|1|22",
""
};
#else
#if 1
const char *nld_74279A::m_desc[] = {
"S,R,_Q|Q",
"0,X,X|1|22",
"1,0,X|0|27",
"1,1,0|0|27", //15
"1,1,1|1|22",
""
};
const char *nld_74279B::m_desc[] = {
"S1,S2,R,_Q|Q",
"0,X,X,X|1|22",
"X,0,X,X|1|22",
"1,1,0,X|0|27",
"1,1,1,0|0|27", // 15
"1,1,1,1|1|22",
""
};
#else
const char *nld_74279A::m_desc[] = {
" S, R,_Q,_QR|Q,QR",
" 0, 0, 0, 0 |1, 1|20,22",
" 1, 0, 0, 0 |1, 1|20,22",
" 0, 1, 0, 0 |1, 1|20,22",
" 1, 1, 0, 0 |1, 1|20,22",
" 0, 0, 1, 0 |1, 1|20,22",
" 1, 0, 1, 0 |1, 1|20,22",
" 0, 1, 1, 0 |1, 0|22,15",
" 1, 1, 1, 0 |1, 0|22,15",
" 0, 0, 0, 1 |1, 1|20,22",
" 1, 0, 0, 1 |0, 1|15,22",
" 0, 1, 0, 1 |1, 1|20,22",
" 1, 1, 0, 1 |0, 1|15,22",
" 0, 0, 1, 1 |1, 1|20,22",
" 1, 0, 1, 1 |0, 1|15,22",
" 0, 1, 1, 1 |1, 0|22,15",
" 1, 1, 1, 1 |0, 0|13,15",
""
};
const char *nld_74279B::m_desc[] = {
"S1,S2,R,_Q,_QR|Q,QR",
"0,0,0,0,0|1,1|20,22",
"1,0,0,0,0|1,1|20,22",
"0,1,0,0,0|1,1|20,22",
"1,1,0,0,0|1,1|20,22",
"0,0,1,0,0|1,1|20,22",
"1,0,1,0,0|1,1|20,22",
"0,1,1,0,0|1,1|20,22",
"1,1,1,0,0|1,1|20,22",
"0,0,0,1,0|1,1|20,22",
"1,0,0,1,0|1,1|20,22",
"0,1,0,1,0|1,1|20,22",
"1,1,0,1,0|1,1|20,22",
"0,0,1,1,0|1,0|22,15",
"1,0,1,1,0|1,0|22,15",
"0,1,1,1,0|1,0|22,15",
"1,1,1,1,0|1,0|22,15",
"0,0,0,0,1|1,1|20,22",
"1,0,0,0,1|1,1|20,22",
"0,1,0,0,1|1,1|20,22",
"1,1,0,0,1|0,1|15,22",
"0,0,1,0,1|1,1|20,22",
"1,0,1,0,1|1,1|20,22",
"0,1,1,0,1|1,1|20,22",
"1,1,1,0,1|0,1|15,22",
"0,0,0,1,1|1,1|20,22",
"1,0,0,1,1|1,1|20,22",
"0,1,0,1,1|1,1|20,22",
"1,1,0,1,1|0,1|15,22",
"0,0,1,1,1|1,0|22,15",
"1,0,1,1,1|1,0|22,15",
"0,1,1,1,1|1,0|22,15",
"1,1,1,1,1|0,0|13,15",
""
};
#endif
#endif
NETLIB_UPDATE(74279_dip)
namespace netlist
{
/* only called during startup */
//m_1.update_dev();
//m_2.update_dev();
//m_3.update_dev();
//m_4.update_dev();
}
namespace devices
{
NETLIB_RESET(74279_dip)
{
//m_1.do_reset();
//m_2.do_reset();
//m_3.do_reset();
//m_4.do_reset();
}
NETLIB_TRUTHTABLE(74279A, 3, 1, 0);
NETLIB_TRUTHTABLE(74279B, 4, 1, 0);
NETLIB_NAMESPACE_DEVICES_END()
NETLIB_OBJECT(74279_dip)
{
NETLIB_CONSTRUCTOR(74279_dip)
, m_1(*this, "1")
, m_2(*this, "2")
, m_3(*this, "3")
, m_4(*this, "4")
{
register_subalias("1", m_1.m_I[2]); //R
register_subalias("2", m_1.m_I[0]);
register_subalias("3", m_1.m_I[1]);
register_subalias("4", m_1.m_Q[0]);
register_subalias("5", m_2.m_I[1]); //R
register_subalias("6", m_2.m_I[0]);
register_subalias("7", m_2.m_Q[0]);
register_subalias("9", m_3.m_Q[0]);
register_subalias("10", m_3.m_I[2]); //R
register_subalias("11", m_3.m_I[0]);
register_subalias("12", m_3.m_I[1]);
register_subalias("13", m_4.m_Q[0]);
register_subalias("14", m_4.m_I[1]); //R
register_subalias("15", m_4.m_I[0]);
}
//NETLIB_RESETI();
//NETLIB_UPDATEI();
protected:
NETLIB_SUB(74279B) m_1;
NETLIB_SUB(74279A) m_2;
NETLIB_SUB(74279B) m_3;
NETLIB_SUB(74279A) m_4;
};
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",
"0,X,X|1|22",
"1,0,X|0|27",
"1,1,0|0|27", //15
"1,1,1|1|22",
""
};
const char *nld_74279B::m_desc[] = {
"S1,S2,R,_Q|Q",
"0,X,X,X|1|22",
"X,0,X,X|1|22",
"1,1,0,X|0|27",
"1,1,1,0|0|27", // 15
"1,1,1,1|1|22",
""
};
NETLIB_DEVICE_IMPL(74279_dip)
} //namespace devices
} // namespace netlist

View File

@ -36,61 +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)
NETLIB_NAMESPACE_DEVICES_START()
#if 0
NETLIB_TRUTHTABLE(74279A, 2, 1, 1);
NETLIB_TRUTHTABLE(74279B, 3, 1, 1);
#else
NETLIB_TRUTHTABLE(74279A, 3, 1, 0);
NETLIB_TRUTHTABLE(74279B, 4, 1, 0);
//NETLIB_TRUTHTABLE(74279A, 4, 2, 0);
//NETLIB_TRUTHTABLE(74279B, 5, 2, 0);
#endif
NETLIB_OBJECT(74279_dip)
{
NETLIB_CONSTRUCTOR(74279_dip)
, m_1(*this, "1")
, m_2(*this, "2")
, m_3(*this, "3")
, m_4(*this, "4")
{
register_subalias("1", m_1.m_I[2]); //R
register_subalias("2", m_1.m_I[0]);
register_subalias("3", m_1.m_I[1]);
register_subalias("4", m_1.m_Q[0]);
register_subalias("5", m_2.m_I[1]); //R
register_subalias("6", m_2.m_I[0]);
register_subalias("7", m_2.m_Q[0]);
register_subalias("9", m_3.m_Q[0]);
register_subalias("10", m_3.m_I[2]); //R
register_subalias("11", m_3.m_I[0]);
register_subalias("12", m_3.m_I[1]);
register_subalias("13", m_4.m_Q[0]);
register_subalias("14", m_4.m_I[1]); //R
register_subalias("15", m_4.m_I[0]);
}
NETLIB_RESETI();
NETLIB_UPDATEI();
protected:
NETLIB_SUB(74279B) m_1;
NETLIB_SUB(74279A) m_2;
NETLIB_SUB(74279B) m_3;
NETLIB_SUB(74279A) m_4;
};
NETLIB_NAMESPACE_DEVICES_END()
#endif /* NLD_74279_H_ */

View File

@ -6,135 +6,223 @@
*/
#include "nld_7448.h"
#include "nld_truthtable.h"
NETLIB_NAMESPACE_DEVICES_START()
#if (USE_TRUTHTABLE_7448 && USE_TRUTHTABLE)
nld_7448::truthtable_t nld_7448::m_ttbl;
const char *nld_7448::m_desc[] = {
" LTQ,BIQ,RBIQ, A , B , C , D | a, b, c, d, e, f, g",
" 1, 1, 1, 0, 0, 0, 0 | 1, 1, 1, 1, 1, 1, 0|100,100,100,100,100,100,100",
" 1, 1, X, 1, 0, 0, 0 | 0, 1, 1, 0, 0, 0, 0|100,100,100,100,100,100,100",
" 1, 1, X, 0, 1, 0, 0 | 1, 1, 0, 1, 1, 0, 1|100,100,100,100,100,100,100",
" 1, 1, X, 1, 1, 0, 0 | 1, 1, 1, 1, 0, 0, 1|100,100,100,100,100,100,100",
" 1, 1, X, 0, 0, 1, 0 | 0, 1, 1, 0, 0, 1, 1|100,100,100,100,100,100,100",
" 1, 1, X, 1, 0, 1, 0 | 1, 0, 1, 1, 0, 1, 1|100,100,100,100,100,100,100",
" 1, 1, X, 0, 1, 1, 0 | 0, 0, 1, 1, 1, 1, 1|100,100,100,100,100,100,100",
" 1, 1, X, 1, 1, 1, 0 | 1, 1, 1, 0, 0, 0, 0|100,100,100,100,100,100,100",
" 1, 1, X, 0, 0, 0, 1 | 1, 1, 1, 1, 1, 1, 1|100,100,100,100,100,100,100",
" 1, 1, X, 1, 0, 0, 1 | 1, 1, 1, 0, 0, 1, 1|100,100,100,100,100,100,100",
" 1, 1, X, 0, 1, 0, 1 | 0, 0, 0, 1, 1, 0, 1|100,100,100,100,100,100,100",
" 1, 1, X, 1, 1, 0, 1 | 0, 0, 1, 1, 0, 0, 1|100,100,100,100,100,100,100",
" 1, 1, X, 0, 0, 1, 1 | 0, 1, 0, 0, 0, 1, 1|100,100,100,100,100,100,100",
" 1, 1, X, 1, 0, 1, 1 | 1, 0, 0, 1, 0, 1, 1|100,100,100,100,100,100,100",
" 1, 1, X, 0, 1, 1, 1 | 0, 0, 0, 1, 1, 1, 1|100,100,100,100,100,100,100",
" 1, 1, X, 1, 1, 1, 1 | 0, 0, 0, 0, 0, 0, 0|100,100,100,100,100,100,100",
// BI/RBO is input output. In the next case it is used as an output will go low.
" 1, 1, 0, 0, 0, 0, 0 | 0, 0, 0, 0, 0, 0, 0|100,100,100,100,100,100,100", // RBI
" 0, 1, X, X, X, X, X | 1, 1, 1, 1, 1, 1, 1|100,100,100,100,100,100,100", // LT
// This condition has precedence
" X, 0, X, X, X, X, X | 0, 0, 0, 0, 0, 0, 0|100,100,100,100,100,100,100", // BI
""
};
NETLIB_START(7448_dip)
namespace netlist
{
NETLIB_NAME(7448)::start();
register_subalias("1", m_I[4]); // B
register_subalias("2", m_I[5]); // C
register_subalias("3", m_I[0]); // LTQ
register_subalias("4", m_I[1]); // BIQ
register_subalias("5", m_I[2]); // RBIQ
register_subalias("6", m_I[6]); // D
register_subalias("7", m_I[3]); // A
register_subalias("9", m_Q[4]); // e
register_subalias("10", m_Q[3]); // d
register_subalias("11", m_Q[2]); // c
register_subalias("12", m_Q[1]); // b
register_subalias("13", m_Q[0]); // a
register_subalias("14", m_Q[6]); // g
register_subalias("15", m_Q[5]); // f
}
#else
NETLIB_UPDATE(7448)
{
if (INPLOGIC(m_BIQ) && !INPLOGIC(m_LTQ))
namespace devices
{
m_sub.update_outputs(8);
}
else if (!INPLOGIC(m_BIQ))
/*
* FIXME: Using truthtable is a lot slower than the explicit device
* in breakout. Performance drops by 20%.
*/
#define USE_TRUTHTABLE_7448 (0)
#if (USE_TRUTHTABLE_7448 && USE_TRUTHTABLE)
NETLIB_TRUTHTABLE(7448, 7, 7, 0);
#else
NETLIB_OBJECT(7448)
{
m_sub.update_outputs(15);
NETLIB_CONSTRUCTOR(7448)
, m_A(*this, "A")
, m_B(*this, "B")
, m_C(*this, "C")
, m_D(*this, "D")
, m_LTQ(*this, "LTQ")
, m_BIQ(*this, "BIQ")
, m_RBIQ(*this, "RBIQ")
, m_state(0)
, m_Q(*this, {{"a", "b", "c", "d", "e", "f", "g"}})
{
save(NLNAME(m_state));
}
NETLIB_RESETI();
NETLIB_UPDATEI();
public:
void update_outputs(UINT8 v);
static const UINT8 tab7448[16][7];
logic_input_t m_A;
logic_input_t m_B;
logic_input_t m_C;
logic_input_t m_D;
logic_input_t m_LTQ;
logic_input_t m_BIQ;
logic_input_t m_RBIQ;
UINT8 m_state;
object_array_t<logic_output_t, 7> m_Q; /* a .. g */
};
NETLIB_OBJECT_DERIVED(7448_dip, 7448)
{
NETLIB_CONSTRUCTOR_DERIVED(7448_dip, 7448)
{
register_subalias("1", m_B);
register_subalias("2", m_C);
register_subalias("3", m_LTQ);
register_subalias("4", m_BIQ);
register_subalias("5",m_RBIQ);
register_subalias("6", m_D);
register_subalias("7", m_A);
register_subalias("9", m_Q[4]); // e
register_subalias("10", m_Q[3]); // d
register_subalias("11", m_Q[2]); // c
register_subalias("12", m_Q[1]); // b
register_subalias("13", m_Q[0]); // a
register_subalias("14", m_Q[6]); // g
register_subalias("15", m_Q[5]); // f
}
};
#endif
#if (USE_TRUTHTABLE_7448 && USE_TRUTHTABLE)
nld_7448::truthtable_t nld_7448::m_ttbl;
const char *nld_7448::m_desc[] = {
" LTQ,BIQ,RBIQ, A , B , C , D | a, b, c, d, e, f, g",
" 1, 1, 1, 0, 0, 0, 0 | 1, 1, 1, 1, 1, 1, 0|100,100,100,100,100,100,100",
" 1, 1, X, 1, 0, 0, 0 | 0, 1, 1, 0, 0, 0, 0|100,100,100,100,100,100,100",
" 1, 1, X, 0, 1, 0, 0 | 1, 1, 0, 1, 1, 0, 1|100,100,100,100,100,100,100",
" 1, 1, X, 1, 1, 0, 0 | 1, 1, 1, 1, 0, 0, 1|100,100,100,100,100,100,100",
" 1, 1, X, 0, 0, 1, 0 | 0, 1, 1, 0, 0, 1, 1|100,100,100,100,100,100,100",
" 1, 1, X, 1, 0, 1, 0 | 1, 0, 1, 1, 0, 1, 1|100,100,100,100,100,100,100",
" 1, 1, X, 0, 1, 1, 0 | 0, 0, 1, 1, 1, 1, 1|100,100,100,100,100,100,100",
" 1, 1, X, 1, 1, 1, 0 | 1, 1, 1, 0, 0, 0, 0|100,100,100,100,100,100,100",
" 1, 1, X, 0, 0, 0, 1 | 1, 1, 1, 1, 1, 1, 1|100,100,100,100,100,100,100",
" 1, 1, X, 1, 0, 0, 1 | 1, 1, 1, 0, 0, 1, 1|100,100,100,100,100,100,100",
" 1, 1, X, 0, 1, 0, 1 | 0, 0, 0, 1, 1, 0, 1|100,100,100,100,100,100,100",
" 1, 1, X, 1, 1, 0, 1 | 0, 0, 1, 1, 0, 0, 1|100,100,100,100,100,100,100",
" 1, 1, X, 0, 0, 1, 1 | 0, 1, 0, 0, 0, 1, 1|100,100,100,100,100,100,100",
" 1, 1, X, 1, 0, 1, 1 | 1, 0, 0, 1, 0, 1, 1|100,100,100,100,100,100,100",
" 1, 1, X, 0, 1, 1, 1 | 0, 0, 0, 1, 1, 1, 1|100,100,100,100,100,100,100",
" 1, 1, X, 1, 1, 1, 1 | 0, 0, 0, 0, 0, 0, 0|100,100,100,100,100,100,100",
// BI/RBO is input output. In the next case it is used as an input will go low.
" 1, 1, 0, 0, 0, 0, 0 | 0, 0, 0, 0, 0, 0, 0|100,100,100,100,100,100,100", // RBI
" 0, 1, X, X, X, X, X | 1, 1, 1, 1, 1, 1, 1|100,100,100,100,100,100,100", // LT
// This condition has precedence
" X, 0, X, X, X, X, X | 0, 0, 0, 0, 0, 0, 0|100,100,100,100,100,100,100", // BI
""
};
NETLIB_OBJECT_DERIVED(7448_dip, 7448)
{
NETLIB_CONSTRUCTOR_DERIVED(7448_dip, 7448)
{
register_subalias("1", m_I[4]); // B
register_subalias("2", m_I[5]); // C
register_subalias("3", m_I[0]); // LTQ
register_subalias("4", m_I[1]); // BIQ
register_subalias("5", m_I[2]); // RBIQ
register_subalias("6", m_I[6]); // D
register_subalias("7", m_I[3]); // A
register_subalias("9", m_Q[4]); // e
register_subalias("10", m_Q[3]); // d
register_subalias("11", m_Q[2]); // c
register_subalias("12", m_Q[1]); // b
register_subalias("13", m_Q[0]); // a
register_subalias("14", m_Q[6]); // g
register_subalias("15", m_Q[5]); // f
}
};
#else
NETLIB_UPDATE(7448)
{
if (!INPLOGIC(m_BIQ) || (INPLOGIC(m_BIQ) && !INPLOGIC(m_LTQ)))
{
m_A.inactivate();
m_B.inactivate();
m_C.inactivate();
m_D.inactivate();
m_RBIQ.inactivate();
if (INPLOGIC(m_BIQ) && !INPLOGIC(m_LTQ))
{
update_outputs(8);
}
else if (!INPLOGIC(m_BIQ))
{
update_outputs(15);
}
} else {
m_RBIQ.activate();
m_D.activate();
m_C.activate();
m_B.activate();
m_A.activate();
UINT8 v;
v = (INPLOGIC(m_A) << 0) | (INPLOGIC(m_B) << 1) | (INPLOGIC(m_C) << 2) | (INPLOGIC(m_D) << 3);
if ((!INPLOGIC(m_RBIQ) && (v==0)))
v = 15;
update_outputs(v);
}
}
if (!INPLOGIC(m_BIQ) || (INPLOGIC(m_BIQ) && !INPLOGIC(m_LTQ)))
NETLIB_RESET(7448)
{
m_sub.m_A.inactivate();
m_sub.m_B.inactivate();
m_sub.m_C.inactivate();
m_sub.m_D.inactivate();
m_sub.m_RBIQ.inactivate();
} else {
m_sub.m_RBIQ.activate();
m_sub.m_D.activate();
m_sub.m_C.activate();
m_sub.m_B.activate();
m_sub.m_A.activate();
m_sub.do_update();
m_state = 0;
m_A.inactivate();
m_B.inactivate();
m_C.inactivate();
m_D.inactivate();
m_RBIQ.inactivate();
}
}
NETLIB_UPDATE(7448_sub)
{
UINT8 v;
v = (INPLOGIC(m_A) << 0) | (INPLOGIC(m_B) << 1) | (INPLOGIC(m_C) << 2) | (INPLOGIC(m_D) << 3);
if ((!INPLOGIC(m_RBIQ) && (v==0)))
v = 15;
update_outputs(v);
}
NETLIB_FUNC_VOID(7448_sub, update_outputs, (UINT8 v))
{
nl_assert(v<16);
if (v != m_state)
NETLIB_FUNC_VOID(7448, update_outputs, (UINT8 v))
{
// max transfer time is 100 NS */
nl_assert(v<16);
if (v != m_state)
{
// max transfer time is 100 NS */
for (int i=0; i<7; i++)
OUTLOGIC(m_Q[i], tab7448[v][i], NLTIME_FROM_NS(100));
m_state = v;
for (int i=0; i<7; i++)
OUTLOGIC(m_Q[i], tab7448[v][i], NLTIME_FROM_NS(100));
m_state = v;
}
}
}
const UINT8 NETLIB_NAME(7448_sub)::tab7448[16][7] =
{
{ 1, 1, 1, 1, 1, 1, 0 }, /* 00 - not blanked ! */
{ 0, 1, 1, 0, 0, 0, 0 }, /* 01 */
{ 1, 1, 0, 1, 1, 0, 1 }, /* 02 */
{ 1, 1, 1, 1, 0, 0, 1 }, /* 03 */
{ 0, 1, 1, 0, 0, 1, 1 }, /* 04 */
{ 1, 0, 1, 1, 0, 1, 1 }, /* 05 */
{ 0, 0, 1, 1, 1, 1, 1 }, /* 06 */
{ 1, 1, 1, 0, 0, 0, 0 }, /* 07 */
{ 1, 1, 1, 1, 1, 1, 1 }, /* 08 */
{ 1, 1, 1, 0, 0, 1, 1 }, /* 09 */
{ 0, 0, 0, 1, 1, 0, 1 }, /* 10 */
{ 0, 0, 1, 1, 0, 0, 1 }, /* 11 */
{ 0, 1, 0, 0, 0, 1, 1 }, /* 12 */
{ 1, 0, 0, 1, 0, 1, 1 }, /* 13 */
{ 0, 0, 0, 1, 1, 1, 1 }, /* 14 */
{ 0, 0, 0, 0, 0, 0, 0 }, /* 15 */
};
#endif
const UINT8 NETLIB_NAME(7448)::tab7448[16][7] =
{
{ 1, 1, 1, 1, 1, 1, 0 }, /* 00 - not blanked ! */
{ 0, 1, 1, 0, 0, 0, 0 }, /* 01 */
{ 1, 1, 0, 1, 1, 0, 1 }, /* 02 */
{ 1, 1, 1, 1, 0, 0, 1 }, /* 03 */
{ 0, 1, 1, 0, 0, 1, 1 }, /* 04 */
{ 1, 0, 1, 1, 0, 1, 1 }, /* 05 */
{ 0, 0, 1, 1, 1, 1, 1 }, /* 06 */
{ 1, 1, 1, 0, 0, 0, 0 }, /* 07 */
{ 1, 1, 1, 1, 1, 1, 1 }, /* 08 */
{ 1, 1, 1, 0, 0, 1, 1 }, /* 09 */
{ 0, 0, 0, 1, 1, 0, 1 }, /* 10 */
{ 0, 0, 1, 1, 0, 0, 1 }, /* 11 */
{ 0, 1, 0, 0, 0, 1, 1 }, /* 12 */
{ 1, 0, 0, 1, 0, 1, 1 }, /* 13 */
{ 0, 0, 0, 1, 1, 1, 1 }, /* 14 */
{ 0, 0, 0, 0, 0, 0, 0 }, /* 15 */
};
#endif
NETLIB_NAMESPACE_DEVICES_END()
NETLIB_DEVICE_IMPL(7448)
NETLIB_DEVICE_IMPL(7448_dip)
} //namespace devices
} // namespace netlist

View File

@ -25,132 +25,18 @@
#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) \
NET_CONNECT(name, A, cA0) \
NET_CONNECT(name, B, cA1) \
NET_CONNECT(name, C, cA2) \
NET_CONNECT(name, D, cA3) \
NET_CONNECT(name, LTQ, cLTQ) \
NET_CONNECT(name, BIQ, cBIQ) \
#define TTL_7448(name, cA0, cA1, cA2, cA3, cLTQ, cBIQ, cRBIQ) \
NET_REGISTER_DEV(TTL_7448, name) \
NET_CONNECT(name, A, cA0) \
NET_CONNECT(name, B, cA1) \
NET_CONNECT(name, C, cA2) \
NET_CONNECT(name, D, cA3) \
NET_CONNECT(name, LTQ, cLTQ) \
NET_CONNECT(name, BIQ, cBIQ) \
NET_CONNECT(name, RBIQ, cRBIQ)
#define TTL_7448_DIP(name) \
#define TTL_7448_DIP(name) \
NET_REGISTER_DEV(TTL_7448_DIP, name)
NETLIB_NAMESPACE_DEVICES_START()
/*
* FIXME: Using truthtable is a lot slower than the explicit device
*/
#define USE_TRUTHTABLE_7448 (0)
#if (USE_TRUTHTABLE_7448 && USE_TRUTHTABLE)
NETLIB_TRUTHTABLE(7448, 7, 7, 0);
#else
NETLIB_OBJECT(7448_sub)
{
NETLIB_CONSTRUCTOR(7448_sub)
, m_state(0)
{
enregister("A0", m_A);
enregister("A1", m_B);
enregister("A2", m_C);
enregister("A3", m_D);
enregister("RBIQ", m_RBIQ);
enregister("a", m_Q[0]);
enregister("b", m_Q[1]);
enregister("c", m_Q[2]);
enregister("d", m_Q[3]);
enregister("e", m_Q[4]);
enregister("f", m_Q[5]);
enregister("g", m_Q[6]);
save(NLNAME(m_state));
}
NETLIB_RESETI() { m_state = 0; }
NETLIB_UPDATEI();
public:
ATTR_HOT void update_outputs(UINT8 v);
static const UINT8 tab7448[16][7];
logic_input_t m_A;
logic_input_t m_B;
logic_input_t m_C;
logic_input_t m_D;
logic_input_t m_RBIQ;
UINT8 m_state;
logic_output_t m_Q[7]; /* a .. g */
};
NETLIB_OBJECT(7448)
{
NETLIB_CONSTRUCTOR(7448)
, m_sub(*this, "sub")
{
register_subalias("A", m_sub.m_A);
register_subalias("B", m_sub.m_B);
register_subalias("C", m_sub.m_C);
register_subalias("D", m_sub.m_D);
enregister("LTQ", m_LTQ);
enregister("BIQ", m_BIQ);
register_subalias("RBIQ",m_sub.m_RBIQ);
register_subalias("a", m_sub.m_Q[0]);
register_subalias("b", m_sub.m_Q[1]);
register_subalias("c", m_sub.m_Q[2]);
register_subalias("d", m_sub.m_Q[3]);
register_subalias("e", m_sub.m_Q[4]);
register_subalias("f", m_sub.m_Q[5]);
register_subalias("g", m_sub.m_Q[6]);
}
NETLIB_RESETI() { m_sub.do_reset(); }
NETLIB_UPDATEI();
public:
NETLIB_SUB(7448_sub) m_sub;
logic_input_t m_LTQ;
logic_input_t m_BIQ;
};
#endif
NETLIB_OBJECT_DERIVED(7448_dip, 7448)
{
NETLIB_CONSTRUCTOR_DERIVED(7448_dip, 7448)
{
register_subalias("1", m_sub.m_B);
register_subalias("2", m_sub.m_C);
register_subalias("3", m_LTQ);
register_subalias("4", m_BIQ);
register_subalias("5",m_sub.m_RBIQ);
register_subalias("6", m_sub.m_D);
register_subalias("7", m_sub.m_A);
register_subalias("9", m_sub.m_Q[4]); // e
register_subalias("10", m_sub.m_Q[3]); // d
register_subalias("11", m_sub.m_Q[2]); // c
register_subalias("12", m_sub.m_Q[1]); // b
register_subalias("13", m_sub.m_Q[0]); // a
register_subalias("14", m_sub.m_Q[6]); // g
register_subalias("15", m_sub.m_Q[5]); // f
}
};
NETLIB_NAMESPACE_DEVICES_END()
#endif /* NLD_7448_H_ */

View File

@ -7,40 +7,97 @@
#include "nld_7450.h"
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_UPDATE(7450)
namespace netlist
{
m_A.activate();
m_B.activate();
m_C.activate();
m_D.activate();
UINT8 t1 = INPLOGIC(m_A) & INPLOGIC(m_B);
UINT8 t2 = INPLOGIC(m_C) & INPLOGIC(m_D);
const netlist_time times[2] = { NLTIME_FROM_NS(22), NLTIME_FROM_NS(15) };
UINT8 res = 0;
if (t1 ^ 1)
namespace devices
{
if (t2 ^ 1)
NETLIB_OBJECT(7450)
{
NETLIB_CONSTRUCTOR(7450)
, m_A(*this, "A")
, m_B(*this, "B")
, m_C(*this, "C")
, m_D(*this, "D")
, m_Q(*this, "Q")
{
res = 1;
}
else
//NETLIB_RESETI();
NETLIB_UPDATEI();
public:
logic_input_t m_A;
logic_input_t m_B;
logic_input_t m_C;
logic_input_t m_D;
logic_output_t m_Q;
};
NETLIB_OBJECT(7450_dip)
{
NETLIB_CONSTRUCTOR(7450_dip)
, m_1(*this, "1")
, m_2(*this, "2")
{
m_A.inactivate();
m_B.inactivate();
register_subalias("1", m_1.m_A);
register_subalias("2", m_2.m_A);
register_subalias("3", m_2.m_B);
register_subalias("4", m_2.m_C);
register_subalias("5", m_2.m_D);
register_subalias("6", m_2.m_Q);
//register_subalias("7",); GND
register_subalias("8", m_1.m_Q);
register_subalias("9", m_1.m_C);
register_subalias("10", m_1.m_D);
//register_subalias("11", m_1.m_X1);
//register_subalias("12", m_1.m_X1Q);
register_subalias("13", m_1.m_B);
//register_subalias("14",); VCC
}
} else {
if (t2 ^ 1)
//NETLIB_RESETI();
//NETLIB_UPDATEI();
NETLIB_SUB(7450) m_1;
NETLIB_SUB(7450) m_2;
};
NETLIB_UPDATE(7450)
{
m_A.activate();
m_B.activate();
m_C.activate();
m_D.activate();
UINT8 t1 = INPLOGIC(m_A) & INPLOGIC(m_B);
UINT8 t2 = INPLOGIC(m_C) & INPLOGIC(m_D);
const netlist_time times[2] = { NLTIME_FROM_NS(22), NLTIME_FROM_NS(15) };
UINT8 res = 0;
if (t1 ^ 1)
{
m_C.inactivate();
m_D.inactivate();
if (t2 ^ 1)
{
res = 1;
}
else
{
m_A.inactivate();
m_B.inactivate();
}
} else {
if (t2 ^ 1)
{
m_C.inactivate();
m_D.inactivate();
}
}
OUTLOGIC(m_Q, res, times[1 - res]);// ? 22000 : 15000);
}
OUTLOGIC(m_Q, res, times[1 - res]);// ? 22000 : 15000);
}
NETLIB_DEVICE_IMPL(7450)
NETLIB_DEVICE_IMPL(7450_dip)
NETLIB_NAMESPACE_DEVICES_END()
} //namespace devices
} // namespace netlist

View File

@ -24,71 +24,16 @@
#ifndef NLD_7450_H_
#define NLD_7450_H_
#include "nl_base.h"
#include "nl_setup.h"
#define TTL_7450_ANDORINVERT(name, cI1, cI2, cI3, cI4) \
NET_REGISTER_DEV(TTL_7450_ANDORINVERT, name) \
NET_CONNECT(name, A, cI1) \
NET_CONNECT(name, B, cI2) \
NET_CONNECT(name, C, cI3) \
#define TTL_7450_ANDORINVERT(name, cI1, cI2, cI3, cI4) \
NET_REGISTER_DEV(TTL_7450_ANDORINVERT, name) \
NET_CONNECT(name, A, cI1) \
NET_CONNECT(name, B, cI2) \
NET_CONNECT(name, C, cI3) \
NET_CONNECT(name, D, cI4)
#define TTL_7450_DIP(name) \
#define TTL_7450_DIP(name) \
NET_REGISTER_DEV(TTL_7450_DIP, name)
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_OBJECT(7450)
{
NETLIB_CONSTRUCTOR(7450)
{
enregister("A", m_A);
enregister("B", m_B);
enregister("C", m_C);
enregister("D", m_D);
enregister("Q", m_Q);
}
//NETLIB_RESETI();
NETLIB_UPDATEI();
public:
logic_input_t m_A;
logic_input_t m_B;
logic_input_t m_C;
logic_input_t m_D;
logic_output_t m_Q;
};
NETLIB_OBJECT(7450_dip)
{
NETLIB_CONSTRUCTOR(7450_dip)
, m_1(*this, "1")
, m_2(*this, "2")
{
register_subalias("1", m_1.m_A);
register_subalias("2", m_2.m_A);
register_subalias("3", m_2.m_B);
register_subalias("4", m_2.m_C);
register_subalias("5", m_2.m_D);
register_subalias("6", m_2.m_Q);
//register_subalias("7",); GND
register_subalias("8", m_1.m_Q);
register_subalias("9", m_1.m_C);
register_subalias("10", m_1.m_D);
//register_subalias("11", m_1.m_X1);
//register_subalias("12", m_1.m_X1Q);
register_subalias("13", m_1.m_B);
//register_subalias("14",); VCC
}
//NETLIB_RESETI();
//NETLIB_UPDATEI();
NETLIB_SUB(7450) m_1;
NETLIB_SUB(7450) m_2;
};
NETLIB_NAMESPACE_DEVICES_END()
#endif /* NLD_7450_H_ */

View File

@ -7,75 +7,165 @@
#include "nld_7474.h"
NETLIB_NAMESPACE_DEVICES_START()
ATTR_HOT inline void NETLIB_NAME(7474sub)::newstate(const UINT8 stateQ, const UINT8 stateQQ)
namespace netlist
{
// 0: High-to-low 40 ns, 1: Low-to-high 25 ns
const netlist_time delay[2] = { NLTIME_FROM_NS(40), NLTIME_FROM_NS(25) };
OUTLOGIC(m_Q, stateQ, delay[stateQ]);
OUTLOGIC(m_QQ, stateQQ, delay[stateQQ]);
}
NETLIB_UPDATE(7474sub)
{
//if (INP_LH(m_CLK))
namespace devices
{
newstate(m_nextD, !m_nextD);
m_CLK.inactivate();
}
}
NETLIB_UPDATE(7474)
{
if (INPLOGIC(m_PREQ) && INPLOGIC(m_CLRQ))
NETLIB_OBJECT(7474sub)
{
m_D.activate();
sub.m_nextD = INPLOGIC(m_D);
sub.m_CLK.activate_lh();
}
else if (!INPLOGIC(m_PREQ))
NETLIB_CONSTRUCTOR(7474sub)
, m_CLK(*this, "CLK")
, m_Q(*this, "Q")
, m_QQ(*this, "QQ")
, m_nextD(0)
{
save(NLNAME(m_nextD));
}
NETLIB_RESETI();
NETLIB_UPDATEI();
public:
logic_input_t m_CLK;
logic_output_t m_Q;
logic_output_t m_QQ;
INT8 m_nextD;
inline void newstate(const UINT8 stateQ, const UINT8 stateQQ);
private:
};
NETLIB_OBJECT(7474)
{
sub.newstate(1, 0);
sub.m_CLK.inactivate();
m_D.inactivate();
}
else if (!INPLOGIC(m_CLRQ))
NETLIB_CONSTRUCTOR(7474)
, sub(*this, "sub")
, m_D(*this, "D")
, m_CLRQ(*this, "CLRQ")
, m_PREQ(*this, "PREQ")
{
register_subalias("CLK", sub.m_CLK);
register_subalias("Q", sub.m_Q);
register_subalias("QQ", sub.m_QQ);
}
NETLIB_RESETI();
NETLIB_UPDATEI();
public:
NETLIB_SUB(7474sub) sub;
logic_input_t m_D;
logic_input_t m_CLRQ;
logic_input_t m_PREQ;
};
NETLIB_OBJECT(7474_dip)
{
sub.newstate(0, 1);
sub.m_CLK.inactivate();
m_D.inactivate();
}
else
NETLIB_CONSTRUCTOR(7474_dip)
, m_1(*this, "1")
, m_2(*this, "2")
{
register_subalias("1", m_1.m_CLRQ);
register_subalias("2", m_1.m_D);
register_subalias("3", m_1.sub.m_CLK);
register_subalias("4", m_1.m_PREQ);
register_subalias("5", m_1.sub.m_Q);
register_subalias("6", m_1.sub.m_QQ);
// register_subalias("7", ); ==> GND
register_subalias("8", m_2.sub.m_QQ);
register_subalias("9", m_2.sub.m_Q);
register_subalias("10", m_2.m_PREQ);
register_subalias("11", m_2.sub.m_CLK);
register_subalias("12", m_2.m_D);
register_subalias("13", m_2.m_CLRQ);
// register_subalias("14", ); ==> VCC
}
NETLIB_UPDATEI();
NETLIB_RESETI();
private:
NETLIB_SUB(7474) m_1;
NETLIB_SUB(7474) m_2;
};
inline void NETLIB_NAME(7474sub)::newstate(const UINT8 stateQ, const UINT8 stateQQ)
{
sub.newstate(1, 1);
sub.m_CLK.inactivate();
m_D.inactivate();
// 0: High-to-low 40 ns, 1: Low-to-high 25 ns
const netlist_time delay[2] = { NLTIME_FROM_NS(40), NLTIME_FROM_NS(25) };
OUTLOGIC(m_Q, stateQ, delay[stateQ]);
OUTLOGIC(m_QQ, stateQQ, delay[stateQQ]);
}
}
NETLIB_RESET(7474)
{
sub.do_reset();
}
NETLIB_UPDATE(7474sub)
{
//if (INP_LH(m_CLK))
{
newstate(m_nextD, !m_nextD);
m_CLK.inactivate();
}
}
NETLIB_RESET(7474sub)
{
m_CLK.set_state(logic_t::STATE_INP_LH);
NETLIB_UPDATE(7474)
{
if (INPLOGIC(m_PREQ) && INPLOGIC(m_CLRQ))
{
m_D.activate();
sub.m_nextD = INPLOGIC(m_D);
sub.m_CLK.activate_lh();
}
else if (!INPLOGIC(m_PREQ))
{
sub.newstate(1, 0);
sub.m_CLK.inactivate();
m_D.inactivate();
}
else if (!INPLOGIC(m_CLRQ))
{
sub.newstate(0, 1);
sub.m_CLK.inactivate();
m_D.inactivate();
}
else
{
sub.newstate(1, 1);
sub.m_CLK.inactivate();
m_D.inactivate();
}
}
m_nextD = 0;
}
NETLIB_RESET(7474)
{
sub.do_reset();
}
NETLIB_RESET(7474_dip)
{
// m_1.do_reset();
//m_2.do_reset();
}
NETLIB_RESET(7474sub)
{
m_CLK.set_state(logic_t::STATE_INP_LH);
NETLIB_UPDATE(7474_dip)
{
//m_1.update_dev();
//m_2.update_dev();
}
m_nextD = 0;
}
NETLIB_NAMESPACE_DEVICES_END()
NETLIB_RESET(7474_dip)
{
// m_1.do_reset();
//m_2.do_reset();
}
NETLIB_UPDATE(7474_dip)
{
//m_1.update_dev();
//m_2.update_dev();
}
NETLIB_DEVICE_IMPL(7474)
NETLIB_DEVICE_IMPL(7474_dip)
} //namespace devices
} // namespace netlist

View File

@ -42,104 +42,16 @@
#ifndef NLD_7474_H_
#define NLD_7474_H_
#include "nl_base.h"
#include "nl_setup.h"
#define TTL_7474(name, cCLK, cD, cCLRQ, cPREQ) \
NET_REGISTER_DEV(TTL_7474, name) \
NET_CONNECT(name, CLK, cCLK) \
NET_CONNECT(name, D, cD) \
NET_CONNECT(name, CLRQ, cCLRQ) \
#define TTL_7474(name, cCLK, cD, cCLRQ, cPREQ) \
NET_REGISTER_DEV(TTL_7474, name) \
NET_CONNECT(name, CLK, cCLK) \
NET_CONNECT(name, D, cD) \
NET_CONNECT(name, CLRQ, cCLRQ) \
NET_CONNECT(name, PREQ, cPREQ)
#define TTL_7474_DIP(name) \
#define TTL_7474_DIP(name) \
NET_REGISTER_DEV(TTL_7474_DIP, name)
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_OBJECT(7474sub)
{
NETLIB_CONSTRUCTOR(7474sub)
, m_nextD(0)
{
enregister("CLK", m_CLK);
enregister("Q", m_Q);
enregister("QQ", m_QQ);
save(NLNAME(m_nextD));
}
NETLIB_RESETI();
NETLIB_UPDATEI();
public:
logic_input_t m_CLK;
logic_output_t m_Q;
logic_output_t m_QQ;
INT8 m_nextD;
ATTR_HOT inline void newstate(const UINT8 stateQ, const UINT8 stateQQ);
private:
};
NETLIB_OBJECT(7474)
{
NETLIB_CONSTRUCTOR(7474)
, sub(*this, "sub")
{
register_subalias("CLK", sub.m_CLK);
enregister("D", m_D);
enregister("CLRQ", m_CLRQ);
enregister("PREQ", m_PREQ);
register_subalias("Q", sub.m_Q);
register_subalias("QQ", sub.m_QQ);
}
NETLIB_RESETI();
NETLIB_UPDATEI();
public:
NETLIB_SUB(7474sub) sub;
logic_input_t m_D;
logic_input_t m_CLRQ;
logic_input_t m_PREQ;
};
NETLIB_OBJECT(7474_dip)
{
NETLIB_CONSTRUCTOR(7474_dip)
, m_1(*this, "1")
, m_2(*this, "2")
{
register_subalias("1", m_1.m_CLRQ);
register_subalias("2", m_1.m_D);
register_subalias("3", m_1.sub.m_CLK);
register_subalias("4", m_1.m_PREQ);
register_subalias("5", m_1.sub.m_Q);
register_subalias("6", m_1.sub.m_QQ);
// register_subalias("7", ); ==> GND
register_subalias("8", m_2.sub.m_QQ);
register_subalias("9", m_2.sub.m_Q);
register_subalias("10", m_2.m_PREQ);
register_subalias("11", m_2.sub.m_CLK);
register_subalias("12", m_2.m_D);
register_subalias("13", m_2.m_CLRQ);
// register_subalias("14", ); ==> VCC
}
NETLIB_UPDATEI();
NETLIB_RESETI();
private:
NETLIB_SUB(7474) m_1;
NETLIB_SUB(7474) m_2;
};
NETLIB_NAMESPACE_DEVICES_END()
#endif /* NLD_7474_H_ */

View File

@ -7,29 +7,107 @@
#include "nld_7483.h"
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_RESET(7483)
namespace netlist
{
m_lastr = 0;
}
NETLIB_UPDATE(7483)
{
UINT8 a = (INPLOGIC(m_A1) << 0) | (INPLOGIC(m_A2) << 1) | (INPLOGIC(m_A3) << 2) | (INPLOGIC(m_A4) << 3);
UINT8 b = (INPLOGIC(m_B1) << 0) | (INPLOGIC(m_B2) << 1) | (INPLOGIC(m_B3) << 2) | (INPLOGIC(m_B4) << 3);
UINT8 r = a + b + INPLOGIC(m_C0);
if (r != m_lastr)
namespace devices
{
m_lastr = r;
OUTLOGIC(m_S1, (r >> 0) & 1, NLTIME_FROM_NS(23));
OUTLOGIC(m_S2, (r >> 1) & 1, NLTIME_FROM_NS(23));
OUTLOGIC(m_S3, (r >> 2) & 1, NLTIME_FROM_NS(23));
OUTLOGIC(m_S4, (r >> 3) & 1, NLTIME_FROM_NS(23));
OUTLOGIC(m_C4, (r >> 4) & 1, NLTIME_FROM_NS(23));
}
}
NETLIB_NAMESPACE_DEVICES_END()
NETLIB_OBJECT(7483)
{
NETLIB_CONSTRUCTOR(7483)
, m_C0(*this, "C0")
, m_A1(*this, "A1")
, m_A2(*this, "A2")
, m_A3(*this, "A3")
, m_A4(*this, "A4")
, m_B1(*this, "B1")
, m_B2(*this, "B2")
, m_B3(*this, "B3")
, m_B4(*this, "B4")
, m_lastr(0)
, m_S1(*this, "S1")
, m_S2(*this, "S2")
, m_S3(*this, "S3")
, m_S4(*this, "S4")
, m_C4(*this, "C4")
{
save(NLNAME(m_lastr));
}
NETLIB_RESETI();
NETLIB_UPDATEI();
protected:
logic_input_t m_C0;
logic_input_t m_A1;
logic_input_t m_A2;
logic_input_t m_A3;
logic_input_t m_A4;
logic_input_t m_B1;
logic_input_t m_B2;
logic_input_t m_B3;
logic_input_t m_B4;
UINT8 m_lastr;
logic_output_t m_S1;
logic_output_t m_S2;
logic_output_t m_S3;
logic_output_t m_S4;
logic_output_t m_C4;
};
NETLIB_OBJECT_DERIVED(7483_dip, 7483)
{
NETLIB_CONSTRUCTOR_DERIVED(7483_dip, 7483)
{
register_subalias("1", m_A4);
register_subalias("2", m_S3);
register_subalias("3", m_A3);
register_subalias("4", m_B3);
// register_subalias("5", ); --> VCC
register_subalias("6", m_S2);
register_subalias("7", m_B2);
register_subalias("8", m_A2);
register_subalias("9", m_S1);
register_subalias("10", m_A1);
register_subalias("11", m_B1);
// register_subalias("12", ); --> GND
register_subalias("13", m_C0);
register_subalias("14", m_C4);
register_subalias("15", m_S4);
register_subalias("16", m_B4);
}
//NETLIB_RESETI();
//NETLIB_UPDATEI();
};
NETLIB_RESET(7483)
{
m_lastr = 0;
}
NETLIB_UPDATE(7483)
{
UINT8 a = (INPLOGIC(m_A1) << 0) | (INPLOGIC(m_A2) << 1) | (INPLOGIC(m_A3) << 2) | (INPLOGIC(m_A4) << 3);
UINT8 b = (INPLOGIC(m_B1) << 0) | (INPLOGIC(m_B2) << 1) | (INPLOGIC(m_B3) << 2) | (INPLOGIC(m_B4) << 3);
UINT8 r = a + b + INPLOGIC(m_C0);
if (r != m_lastr)
{
m_lastr = r;
OUTLOGIC(m_S1, (r >> 0) & 1, NLTIME_FROM_NS(23));
OUTLOGIC(m_S2, (r >> 1) & 1, NLTIME_FROM_NS(23));
OUTLOGIC(m_S3, (r >> 2) & 1, NLTIME_FROM_NS(23));
OUTLOGIC(m_S4, (r >> 3) & 1, NLTIME_FROM_NS(23));
OUTLOGIC(m_C4, (r >> 4) & 1, NLTIME_FROM_NS(23));
}
}
NETLIB_DEVICE_IMPL(7483)
NETLIB_DEVICE_IMPL(7483_dip)
} //namespace devices
} // namespace netlist

View File

@ -27,98 +27,21 @@
#ifndef NLD_7483_H_
#define NLD_7483_H_
#include "nl_base.h"
#include "nl_setup.h"
#define TTL_7483(name, cA1, cA2, cA3, cA4, cB1, cB2, cB3, cB4, cCI) \
NET_REGISTER_DEV(TTL_7483, name) \
NET_CONNECT(name, A1, cA1) \
NET_CONNECT(name, A2, cA2) \
NET_CONNECT(name, A3, cA3) \
NET_CONNECT(name, A4, cA4) \
NET_CONNECT(name, B1, cB1) \
NET_CONNECT(name, B2, cB2) \
NET_CONNECT(name, B3, cB3) \
NET_CONNECT(name, B4, cB4) \
#define TTL_7483(name, cA1, cA2, cA3, cA4, cB1, cB2, cB3, cB4, cCI) \
NET_REGISTER_DEV(TTL_7483, name) \
NET_CONNECT(name, A1, cA1) \
NET_CONNECT(name, A2, cA2) \
NET_CONNECT(name, A3, cA3) \
NET_CONNECT(name, A4, cA4) \
NET_CONNECT(name, B1, cB1) \
NET_CONNECT(name, B2, cB2) \
NET_CONNECT(name, B3, cB3) \
NET_CONNECT(name, B4, cB4) \
NET_CONNECT(name, C0, cCI)
#define TTL_7483_DIP(name) \
#define TTL_7483_DIP(name) \
NET_REGISTER_DEV(TTL_7483_DIP, name)
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_OBJECT(7483)
{
NETLIB_CONSTRUCTOR(7483)
, m_lastr(0)
{
enregister("A1", m_A1);
enregister("A2", m_A2);
enregister("A3", m_A3);
enregister("A4", m_A4);
enregister("B1", m_B1);
enregister("B2", m_B2);
enregister("B3", m_B3);
enregister("B4", m_B4);
enregister("C0", m_C0);
enregister("S1", m_S1);
enregister("S2", m_S2);
enregister("S3", m_S3);
enregister("S4", m_S4);
enregister("C4", m_C4);
save(NLNAME(m_lastr));
}
NETLIB_RESETI();
NETLIB_UPDATEI();
protected:
logic_input_t m_C0;
logic_input_t m_A1;
logic_input_t m_A2;
logic_input_t m_A3;
logic_input_t m_A4;
logic_input_t m_B1;
logic_input_t m_B2;
logic_input_t m_B3;
logic_input_t m_B4;
UINT8 m_lastr;
logic_output_t m_S1;
logic_output_t m_S2;
logic_output_t m_S3;
logic_output_t m_S4;
logic_output_t m_C4;
};
NETLIB_OBJECT_DERIVED(7483_dip, 7483)
{
NETLIB_CONSTRUCTOR_DERIVED(7483_dip, 7483)
{
register_subalias("1", m_A4);
register_subalias("2", m_S3);
register_subalias("3", m_A3);
register_subalias("4", m_B3);
// register_subalias("5", ); --> VCC
register_subalias("6", m_S2);
register_subalias("7", m_B2);
register_subalias("8", m_A2);
register_subalias("9", m_S1);
register_subalias("10", m_A1);
register_subalias("11", m_B1);
// register_subalias("12", ); --> GND
register_subalias("13", m_C0);
register_subalias("14", m_C4);
register_subalias("15", m_S4);
register_subalias("16", m_B4);
}
//NETLIB_RESETI();
//NETLIB_UPDATEI();
};
NETLIB_NAMESPACE_DEVICES_END()
#endif /* NLD_7483_H_ */

View File

@ -7,60 +7,129 @@
#include "nld_7490.h"
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_RESET(7490)
namespace netlist
{
m_cnt = 0;
m_last_A = 0;
m_last_B = 0;
}
static const netlist_time delay[4] =
{
NLTIME_FROM_NS(18),
NLTIME_FROM_NS(36) - NLTIME_FROM_NS(18),
NLTIME_FROM_NS(54) - NLTIME_FROM_NS(18),
NLTIME_FROM_NS(72) - NLTIME_FROM_NS(18)};
NETLIB_UPDATE(7490)
{
const netlist_sig_t new_A = INPLOGIC(m_A);
const netlist_sig_t new_B = INPLOGIC(m_B);
if (INPLOGIC(m_R91) & INPLOGIC(m_R92))
namespace devices
{
m_cnt = 9;
update_outputs();
}
else if (INPLOGIC(m_R1) & INPLOGIC(m_R2))
NETLIB_OBJECT(7490)
{
NETLIB_CONSTRUCTOR(7490)
, m_A(*this, "A")
, m_B(*this, "B")
, m_R1(*this, "R1")
, m_R2(*this, "R2")
, m_R91(*this, "R91")
, m_R92(*this, "R92")
, m_cnt(0)
, m_last_A(0)
, m_last_B(0)
, m_Q(*this, {{"QA", "QB", "QC", "QD"}})
{
save(NLNAME(m_cnt));
save(NLNAME(m_last_A));
save(NLNAME(m_last_B));
}
NETLIB_UPDATEI();
NETLIB_RESETI();
protected:
void update_outputs();
logic_input_t m_A;
logic_input_t m_B;
logic_input_t m_R1;
logic_input_t m_R2;
logic_input_t m_R91;
logic_input_t m_R92;
UINT8 m_cnt;
UINT8 m_last_A;
UINT8 m_last_B;
object_array_t<logic_output_t, 4> m_Q;
};
NETLIB_OBJECT_DERIVED(7490_dip, 7490)
{
NETLIB_CONSTRUCTOR_DERIVED(7490_dip, 7490)
{
register_subalias("1", m_B);
register_subalias("2", m_R1);
register_subalias("3", m_R2);
// register_subalias("4", ); --> NC
// register_subalias("5", ); --> VCC
register_subalias("6", m_R91);
register_subalias("7", m_R92);
register_subalias("8", m_Q[2]);
register_subalias("9", m_Q[1]);
// register_subalias("10", ); --> GND
register_subalias("11", m_Q[3]);
register_subalias("12", m_Q[0]);
// register_subalias("13", ); --> NC
register_subalias("14", m_A);
}
};
NETLIB_RESET(7490)
{
m_cnt = 0;
update_outputs();
m_last_A = 0;
m_last_B = 0;
}
else
static const netlist_time delay[4] =
{
if (m_last_A && !new_A) // High - Low
NLTIME_FROM_NS(18),
NLTIME_FROM_NS(36) - NLTIME_FROM_NS(18),
NLTIME_FROM_NS(54) - NLTIME_FROM_NS(18),
NLTIME_FROM_NS(72) - NLTIME_FROM_NS(18)};
NETLIB_UPDATE(7490)
{
const netlist_sig_t new_A = INPLOGIC(m_A);
const netlist_sig_t new_B = INPLOGIC(m_B);
if (INPLOGIC(m_R91) & INPLOGIC(m_R92))
{
m_cnt ^= 1;
OUTLOGIC(m_Q[0], m_cnt & 1, delay[0]);
}
if (m_last_B && !new_B) // High - Low
{
m_cnt += 2;
if (m_cnt >= 10)
m_cnt &= 1; /* Output A is not reset! */
m_cnt = 9;
update_outputs();
}
else if (INPLOGIC(m_R1) & INPLOGIC(m_R2))
{
m_cnt = 0;
update_outputs();
}
else
{
if (m_last_A && !new_A) // High - Low
{
m_cnt ^= 1;
OUTLOGIC(m_Q[0], m_cnt & 1, delay[0]);
}
if (m_last_B && !new_B) // High - Low
{
m_cnt += 2;
if (m_cnt >= 10)
m_cnt &= 1; /* Output A is not reset! */
update_outputs();
}
}
m_last_A = new_A;
m_last_B = new_B;
}
m_last_A = new_A;
m_last_B = new_B;
}
NETLIB_FUNC_VOID(7490, update_outputs, (void))
{
for (int i=0; i<4; i++)
OUTLOGIC(m_Q[i], (m_cnt >> i) & 1, delay[i]);
}
NETLIB_FUNC_VOID(7490, update_outputs, (void))
{
for (int i=0; i<4; i++)
OUTLOGIC(m_Q[i], (m_cnt >> i) & 1, delay[i]);
}
NETLIB_NAMESPACE_DEVICES_END()
NETLIB_DEVICE_IMPL(7490)
NETLIB_DEVICE_IMPL(7490_dip)
} //namespace devices
} // namespace netlist

View File

@ -55,7 +55,7 @@
#ifndef NLD_7490_H_
#define NLD_7490_H_
#include "nl_base.h"
#include "nl_setup.h"
#define TTL_7490(name, cA, cB, cR1, cR2, cR91, cR92) \
NET_REGISTER_DEV(TTL_7490, name) \
@ -69,75 +69,4 @@
#define TTL_7490_DIP(name) \
NET_REGISTER_DEV(TTL_7490_DIP, name)
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_OBJECT(7490)
{
NETLIB_CONSTRUCTOR(7490)
, m_cnt(0)
, m_last_A(0)
, m_last_B(0)
{
enregister("A", m_A);
enregister("B", m_B);
enregister("R1", m_R1);
enregister("R2", m_R2);
enregister("R91", m_R91);
enregister("R92", m_R92);
enregister("QA", m_Q[0]);
enregister("QB", m_Q[1]);
enregister("QC", m_Q[2]);
enregister("QD", m_Q[3]);
save(NLNAME(m_cnt));
save(NLNAME(m_last_A));
save(NLNAME(m_last_B));
}
NETLIB_UPDATEI();
NETLIB_RESETI();
protected:
ATTR_HOT void update_outputs();
logic_input_t m_R1;
logic_input_t m_R2;
logic_input_t m_R91;
logic_input_t m_R92;
logic_input_t m_A;
logic_input_t m_B;
UINT8 m_cnt;
UINT8 m_last_A;
UINT8 m_last_B;
logic_output_t m_Q[4];
};
NETLIB_OBJECT_DERIVED(7490_dip, 7490)
{
NETLIB_CONSTRUCTOR_DERIVED(7490_dip, 7490)
{
register_subalias("1", m_B);
register_subalias("2", m_R1);
register_subalias("3", m_R2);
// register_subalias("4", ); --> NC
// register_subalias("5", ); --> VCC
register_subalias("6", m_R91);
register_subalias("7", m_R92);
register_subalias("8", m_Q[2]);
register_subalias("9", m_Q[1]);
// register_subalias("10", ); --> GND
register_subalias("11", m_Q[3]);
register_subalias("12", m_Q[0]);
// register_subalias("13", ); --> NC
register_subalias("14", m_A);
}
};
NETLIB_NAMESPACE_DEVICES_END()
#endif /* NLD_7490_H_ */

View File

@ -8,47 +8,133 @@
#include "nld_7493.h"
#include "nl_setup.h"
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_RESET(7493ff)
namespace netlist
{
m_reset = 1;
m_state = 0;
m_I.set_state(logic_t::STATE_INP_HL);
}
NETLIB_UPDATE(7493ff)
{
const netlist_time out_delay = NLTIME_FROM_NS(18);
if (m_reset != 0)
namespace devices
{
m_state ^= 1;
OUTLOGIC(m_Q, m_state, out_delay);
}
}
NETLIB_UPDATE(7493)
{
const netlist_sig_t r = INPLOGIC(m_R1) & INPLOGIC(m_R2);
if (r)
NETLIB_OBJECT(7493ff)
{
A.m_I.inactivate();
B.m_I.inactivate();
OUTLOGIC(A.m_Q, 0, NLTIME_FROM_NS(40));
OUTLOGIC(B.m_Q, 0, NLTIME_FROM_NS(40));
OUTLOGIC(C.m_Q, 0, NLTIME_FROM_NS(40));
OUTLOGIC(D.m_Q, 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;
}
else
{
A.m_I.activate_hl();
B.m_I.activate_hl();
A.m_reset = B.m_reset = C.m_reset = D.m_reset = 1;
}
}
NETLIB_CONSTRUCTOR(7493ff)
, m_I(*this, "CLK")
, m_Q(*this, "Q")
{
NETLIB_NAMESPACE_DEVICES_END()
save(NLNAME(m_reset));
save(NLNAME(m_state));
}
NETLIB_RESETI();
NETLIB_UPDATEI();
public:
logic_input_t m_I;
logic_output_t m_Q;
UINT8 m_reset;
UINT8 m_state;
};
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")
{
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_late(C.m_I, B.m_Q);
connect_late(D.m_I, C.m_Q);
}
NETLIB_RESETI() { }
NETLIB_UPDATEI();
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;
};
NETLIB_OBJECT_DERIVED(7493_dip, 7493)
{
NETLIB_CONSTRUCTOR_DERIVED(7493_dip, 7493)
{
register_subalias("1", B.m_I);
register_subalias("2", m_R1);
register_subalias("3", m_R2);
// register_subalias("4", ); --> NC
// register_subalias("5", ); --> VCC
// register_subalias("6", ); --> NC
// register_subalias("7", ); --> NC
register_subalias("8", C.m_Q);
register_subalias("9", B.m_Q);
// register_subalias("10", ); -. GND
register_subalias("11", D.m_Q);
register_subalias("12", A.m_Q);
// register_subalias("13", ); -. NC
register_subalias("14", A.m_I);
}
};
NETLIB_RESET(7493ff)
{
m_reset = 1;
m_state = 0;
m_I.set_state(logic_t::STATE_INP_HL);
}
NETLIB_UPDATE(7493ff)
{
const netlist_time out_delay = NLTIME_FROM_NS(18);
if (m_reset != 0)
{
m_state ^= 1;
OUTLOGIC(m_Q, m_state, out_delay);
}
}
NETLIB_UPDATE(7493)
{
const netlist_sig_t r = INPLOGIC(m_R1) & INPLOGIC(m_R2);
if (r)
{
A.m_I.inactivate();
B.m_I.inactivate();
OUTLOGIC(A.m_Q, 0, NLTIME_FROM_NS(40));
OUTLOGIC(B.m_Q, 0, NLTIME_FROM_NS(40));
OUTLOGIC(C.m_Q, 0, NLTIME_FROM_NS(40));
OUTLOGIC(D.m_Q, 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;
}
else
{
A.m_I.activate_hl();
B.m_I.activate_hl();
A.m_reset = B.m_reset = C.m_reset = D.m_reset = 1;
}
}
NETLIB_DEVICE_IMPL(7493)
NETLIB_DEVICE_IMPL(7493_dip)
} //namespace devices
} // namespace netlist

View File

@ -57,100 +57,16 @@
#ifndef NLD_7493_H_
#define NLD_7493_H_
#include "nl_base.h"
#include "nl_setup.h"
#define TTL_7493(name, cCLKA, cCLKB, cR1, cR2) \
NET_REGISTER_DEV(TTL_7493, name) \
NET_CONNECT(name, CLKA, cCLKA) \
NET_CONNECT(name, CLKB, cCLKB) \
NET_CONNECT(name, R1, cR1) \
#define TTL_7493(name, cCLKA, cCLKB, cR1, cR2) \
NET_REGISTER_DEV(TTL_7493, name) \
NET_CONNECT(name, CLKA, cCLKA) \
NET_CONNECT(name, CLKB, cCLKB) \
NET_CONNECT(name, R1, cR1) \
NET_CONNECT(name, R2, cR2)
#define TTL_7493_DIP(name) \
#define TTL_7493_DIP(name) \
NET_REGISTER_DEV(TTL_7493_DIP, name)
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_OBJECT(7493ff)
{
NETLIB_CONSTRUCTOR(7493ff)
{
enregister("CLK", m_I);
enregister("Q", m_Q);
save(NLNAME(m_reset));
save(NLNAME(m_state));
}
NETLIB_RESETI();
NETLIB_UPDATEI();
public:
logic_input_t m_I;
logic_output_t m_Q;
UINT8 m_reset;
UINT8 m_state;
};
NETLIB_OBJECT(7493)
{
NETLIB_CONSTRUCTOR(7493)
, A(*this, "A")
, B(*this, "B")
, C(*this, "C")
, D(*this, "D")
{
register_subalias("CLKA", A.m_I);
register_subalias("CLKB", B.m_I);
enregister("R1", m_R1);
enregister("R2", m_R2);
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_late(C.m_I, B.m_Q);
connect_late(D.m_I, C.m_Q);
}
NETLIB_RESETI() { }
NETLIB_UPDATEI();
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;
};
NETLIB_OBJECT_DERIVED(7493_dip, 7493)
{
NETLIB_CONSTRUCTOR_DERIVED(7493_dip, 7493)
{
register_subalias("1", B.m_I);
register_subalias("2", m_R1);
register_subalias("3", m_R2);
// register_subalias("4", ); --> NC
// register_subalias("5", ); --> VCC
// register_subalias("6", ); --> NC
// register_subalias("7", ); --> NC
register_subalias("8", C.m_Q);
register_subalias("9", B.m_Q);
// register_subalias("10", ); -. GND
register_subalias("11", D.m_Q);
register_subalias("12", A.m_Q);
// register_subalias("13", ); -. NC
register_subalias("14", A.m_I);
}
};
NETLIB_NAMESPACE_DEVICES_END()
#endif /* NLD_7493_H_ */

View File

@ -40,84 +40,204 @@
#include "nld_74ls629.h"
#include "nl_setup.h"
#include "analog/nld_twoterm.h"
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_UPDATE(SN74LS629clk)
namespace netlist
{
if (!m_enableq)
namespace devices
{
m_out = m_out ^ 1;
OUTLOGIC(m_Y, m_out, m_inc);
}
else
NETLIB_OBJECT(SN74LS629clk)
{
OUTLOGIC(m_Y, 1, m_inc);
}
}
NETLIB_CONSTRUCTOR(SN74LS629clk)
, m_FB(*this, "FB")
, m_Y(*this, "Y")
, m_enableq(1)
, m_out(0)
, m_inc(netlist_time::zero())
{
connect_late(m_FB, m_Y);
NETLIB_UPDATE(SN74LS629)
{
save(NLNAME(m_enableq));
save(NLNAME(m_inc));
save(NLNAME(m_out));
}
NETLIB_RESETI()
{
m_enableq = 1;
m_out = 0;
m_inc = netlist_time::zero();
}
NETLIB_UPDATEI();
public:
logic_input_t m_FB;
logic_output_t m_Y;
netlist_sig_t m_enableq;
netlist_sig_t m_out;
netlist_time m_inc;
};
NETLIB_OBJECT(SN74LS629)
{
// recompute
nl_double freq;
nl_double v_freq_2, v_freq_3, v_freq_4;
nl_double v_freq = INPANALOG(m_FC);
nl_double v_rng = INPANALOG(m_RNG);
NETLIB_CONSTRUCTOR(SN74LS629)
, m_clock(*this, "OSC")
, m_R_FC(*this, "R_FC")
, m_R_RNG(*this, "R_RNG")
, m_ENQ(*this, "ENQ")
, m_RNG(*this, "RNG")
, m_FC(*this, "FC")
, m_CAP(*this, "CAP", 1e-6)
{
register_subalias("GND", m_R_FC.m_N);
/* coefficients */
const nl_double k1 = 1.9904769024796283E+03;
const nl_double k2 = 1.2070059213983407E+03;
const nl_double k3 = 1.3266985579561108E+03;
const nl_double k4 = -1.5500979825922698E+02;
const nl_double k5 = 2.8184536266938172E+00;
const nl_double k6 = -2.3503421582744556E+02;
const nl_double k7 = -3.3836786704527788E+02;
const nl_double k8 = -1.3569136703258670E+02;
const nl_double k9 = 2.9914575453819188E+00;
const nl_double k10 = 1.6855569086173170E+00;
connect_late(m_FC, m_R_FC.m_P);
connect_late(m_RNG, m_R_RNG.m_P);
connect_late(m_R_FC.m_N, m_R_RNG.m_N);
/* scale due to input resistance */
register_subalias("Y", m_clock.m_Y);
}
/* Polyfunctional3D_model created by zunzun.com using sum of squared absolute error */
NETLIB_RESETI()
{
m_R_FC.set_R(90000.0);
m_R_RNG.set_R(90000.0);
m_clock.do_reset();
}
NETLIB_UPDATEI();
v_freq_2 = v_freq * v_freq;
v_freq_3 = v_freq_2 * v_freq;
v_freq_4 = v_freq_3 * v_freq;
freq = k1;
freq += k2 * v_freq;
freq += k3 * v_freq_2;
freq += k4 * v_freq_3;
freq += k5 * v_freq_4;
freq += k6 * v_rng;
freq += k7 * v_rng * v_freq;
freq += k8 * v_rng * v_freq_2;
freq += k9 * v_rng * v_freq_3;
freq += k10 * v_rng * v_freq_4;
NETLIB_UPDATE_PARAMI() { update_dev(); }
freq *= NL_FCONST(0.1e-6) / m_CAP;
public:
NETLIB_SUB(SN74LS629clk) m_clock;
NETLIB_SUB(R_base) m_R_FC;
NETLIB_SUB(R_base) m_R_RNG;
// FIXME: we need a possibility to remove entries from queue ...
// or an exact model ...
m_clock.m_inc = netlist_time::from_double(0.5 / (double) freq);
//m_clock.update();
logic_input_t m_ENQ;
analog_input_t m_RNG;
analog_input_t m_FC;
//NL_VERBOSE_OUT(("{1} {2} {3} {4}\n", name(), v_freq, v_rng, freq));
param_double_t m_CAP;
};
NETLIB_OBJECT(SN74LS629_dip)
{
NETLIB_CONSTRUCTOR(SN74LS629_dip)
, m_1(*this, "1")
, m_2(*this, "2")
{
register_subalias("1", m_2.m_FC);
register_subalias("2", m_1.m_FC);
register_subalias("3", m_1.m_RNG);
register_subalias("6", m_1.m_ENQ);
register_subalias("7", m_1.m_clock.m_Y);
register_subalias("8", m_1.m_R_FC.m_N);
register_subalias("9", m_1.m_R_FC.m_N);
connect_late(m_1.m_R_FC.m_N, m_2.m_R_FC.m_N);
register_subalias("10", m_2.m_clock.m_Y);
register_subalias("11", m_2.m_ENQ);
register_subalias("14", m_2.m_RNG);
}
NETLIB_UPDATEI() { }
NETLIB_RESETI()
{
m_1.do_reset();
m_2.do_reset();
}
private:
NETLIB_SUB(SN74LS629) m_1;
NETLIB_SUB(SN74LS629) m_2;
};
NETLIB_UPDATE(SN74LS629clk)
{
if (!m_enableq)
{
m_out = m_out ^ 1;
OUTLOGIC(m_Y, m_out, m_inc);
}
else
{
OUTLOGIC(m_Y, 1, m_inc);
}
}
if (!m_clock.m_enableq && INPLOGIC(m_ENQ))
NETLIB_UPDATE(SN74LS629)
{
m_clock.m_enableq = 1;
m_clock.m_out = m_clock.m_out ^ 1;
OUTLOGIC(m_clock.m_Y, m_clock.m_out, netlist_time::from_nsec(1));
}
else if (m_clock.m_enableq && !INPLOGIC(m_ENQ))
{
m_clock.m_enableq = 0;
m_clock.m_out = m_clock.m_out ^ 1;
OUTLOGIC(m_clock.m_Y, m_clock.m_out, netlist_time::from_nsec(1));
}
}
{
// recompute
nl_double freq;
nl_double v_freq_2, v_freq_3, v_freq_4;
nl_double v_freq = INPANALOG(m_FC);
nl_double v_rng = INPANALOG(m_RNG);
NETLIB_NAMESPACE_DEVICES_END()
/* coefficients */
const nl_double k1 = 1.9904769024796283E+03;
const nl_double k2 = 1.2070059213983407E+03;
const nl_double k3 = 1.3266985579561108E+03;
const nl_double k4 = -1.5500979825922698E+02;
const nl_double k5 = 2.8184536266938172E+00;
const nl_double k6 = -2.3503421582744556E+02;
const nl_double k7 = -3.3836786704527788E+02;
const nl_double k8 = -1.3569136703258670E+02;
const nl_double k9 = 2.9914575453819188E+00;
const nl_double k10 = 1.6855569086173170E+00;
/* scale due to input resistance */
/* Polyfunctional3D_model created by zunzun.com using sum of squared absolute error */
v_freq_2 = v_freq * v_freq;
v_freq_3 = v_freq_2 * v_freq;
v_freq_4 = v_freq_3 * v_freq;
freq = k1;
freq += k2 * v_freq;
freq += k3 * v_freq_2;
freq += k4 * v_freq_3;
freq += k5 * v_freq_4;
freq += k6 * v_rng;
freq += k7 * v_rng * v_freq;
freq += k8 * v_rng * v_freq_2;
freq += k9 * v_rng * v_freq_3;
freq += k10 * v_rng * v_freq_4;
freq *= NL_FCONST(0.1e-6) / m_CAP;
// FIXME: we need a possibility to remove entries from queue ...
// or an exact model ...
m_clock.m_inc = netlist_time(0.5 / (double) freq);
//m_clock.update();
//NL_VERBOSE_OUT(("{1} {2} {3} {4}\n", name(), v_freq, v_rng, freq));
}
if (!m_clock.m_enableq && INPLOGIC(m_ENQ))
{
m_clock.m_enableq = 1;
m_clock.m_out = m_clock.m_out ^ 1;
OUTLOGIC(m_clock.m_Y, m_clock.m_out, netlist_time::from_nsec(1));
}
else if (m_clock.m_enableq && !INPLOGIC(m_ENQ))
{
m_clock.m_enableq = 0;
m_clock.m_out = m_clock.m_out ^ 1;
OUTLOGIC(m_clock.m_Y, m_clock.m_out, netlist_time::from_nsec(1));
}
}
NETLIB_DEVICE_IMPL(SN74LS629)
NETLIB_DEVICE_IMPL(SN74LS629_dip)
} //namespace devices
} // namespace netlist

View File

@ -28,134 +28,15 @@
#ifndef NLD_74LS629_H_
#define NLD_74LS629_H_
#include "nl_base.h"
#include "analog/nld_twoterm.h"
#include "nl_setup.h"
#define SN74LS629(name, p_cap) \
NET_REGISTER_DEV(SN74LS629, name) \
#define SN74LS629(name, p_cap) \
NET_REGISTER_DEV(SN74LS629, name) \
NETDEV_PARAMI(name, CAP, p_cap)
#define SN74LS629_DIP(name, p_cap1, p_cap2) \
NET_REGISTER_DEV(SN74LS629_DIP, name) \
NETDEV_PARAMI(name, 1.CAP, p_cap1) \
#define SN74LS629_DIP(name, p_cap1, p_cap2) \
NET_REGISTER_DEV(SN74LS629_DIP, name) \
NETDEV_PARAMI(name, 1.CAP, p_cap1) \
NETDEV_PARAMI(name, 2.CAP, p_cap2)
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_OBJECT(SN74LS629clk)
{
NETLIB_CONSTRUCTOR(SN74LS629clk)
, m_enableq(1)
, m_out(0)
, m_inc(netlist_time::zero)
{
enregister("FB", m_FB);
enregister("Y", m_Y);
connect_late(m_FB, m_Y);
save(NLNAME(m_enableq));
save(NLNAME(m_inc));
save(NLNAME(m_out));
}
NETLIB_RESETI()
{
m_enableq = 1;
m_out = 0;
m_inc = netlist_time::zero;
}
NETLIB_UPDATEI();
public:
logic_input_t m_FB;
logic_output_t m_Y;
netlist_sig_t m_enableq;
netlist_sig_t m_out;
netlist_time m_inc;
};
NETLIB_OBJECT(SN74LS629)
{
NETLIB_CONSTRUCTOR(SN74LS629)
, m_clock(*this, "OSC")
, m_R_FC(*this, "R_FC")
, m_R_RNG(*this, "R_RNG")
, m_CAP(*this, "CAP", 1e-6)
{
enregister("ENQ", m_ENQ);
enregister("RNG", m_RNG);
enregister("FC", m_FC);
register_subalias("GND", m_R_FC.m_N);
connect_late(m_FC, m_R_FC.m_P);
connect_late(m_RNG, m_R_RNG.m_P);
connect_late(m_R_FC.m_N, m_R_RNG.m_N);
register_subalias("Y", m_clock.m_Y);
}
NETLIB_RESETI()
{
m_R_FC.set_R(90000.0);
m_R_RNG.set_R(90000.0);
m_clock.do_reset();
}
NETLIB_UPDATEI();
NETLIB_UPDATE_PARAMI() { update_dev(); }
public:
NETLIB_SUB(SN74LS629clk) m_clock;
NETLIB_SUB(R_base) m_R_FC;
NETLIB_SUB(R_base) m_R_RNG;
logic_input_t m_ENQ;
analog_input_t m_RNG;
analog_input_t m_FC;
param_double_t m_CAP;
};
NETLIB_OBJECT(SN74LS629_dip)
{
NETLIB_CONSTRUCTOR(SN74LS629_dip)
, m_1(*this, "1")
, m_2(*this, "2")
{
register_subalias("1", m_2.m_FC);
register_subalias("2", m_1.m_FC);
register_subalias("3", m_1.m_RNG);
register_subalias("6", m_1.m_ENQ);
register_subalias("7", m_1.m_clock.m_Y);
register_subalias("8", m_1.m_R_FC.m_N);
register_subalias("9", m_1.m_R_FC.m_N);
connect_late(m_1.m_R_FC.m_N, m_2.m_R_FC.m_N);
register_subalias("10", m_2.m_clock.m_Y);
register_subalias("11", m_2.m_ENQ);
register_subalias("14", m_2.m_RNG);
}
NETLIB_UPDATEI() { }
NETLIB_RESETI()
{
m_1.do_reset();
m_2.do_reset();
}
private:
NETLIB_SUB(SN74LS629) m_1;
NETLIB_SUB(SN74LS629) m_2;
};
NETLIB_NAMESPACE_DEVICES_END()
#endif /* NLD_74LS629_H_ */

View File

@ -7,42 +7,103 @@
#include "nld_82S16.h"
NETLIB_NAMESPACE_DEVICES_START()
// FIXME: timing!
// FIXME: optimize device (separate address decoder!)
NETLIB_UPDATE(82S16)
namespace netlist
{
if (INPLOGIC(m_CE1Q) || INPLOGIC(m_CE2Q) || INPLOGIC(m_CE3Q))
namespace devices
{
// FIXME: Outputs are tristate. This needs to be properly implemented
OUTLOGIC(m_DOUTQ, 1, NLTIME_FROM_NS(20));
//for (int i=0; i<8; i++)
//m_A[i].inactivate();
}
else
NETLIB_OBJECT(82S16)
{
unsigned int adr = 0;
for (int i=0; i<8; i++)
NETLIB_CONSTRUCTOR(82S16)
, m_A(*this, {{"A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7" }})
, m_CE1Q(*this, "CE1Q")
, m_CE2Q(*this, "CE2Q")
, m_CE3Q(*this, "CE3Q")
, m_WEQ(*this, "WEQ")
, m_DIN(*this, "DIN")
, m_DOUTQ(*this, "DOUTQ")
{
//m_A[i].activate();
adr |= (INPLOGIC(m_A[i]) << i);
save(NLNAME(m_ram));
}
if (!INPLOGIC(m_WEQ))
{
m_ram[adr >> 6] = (m_ram[adr >> 6] & ~((UINT64) 1 << (adr & 0x3f))) | ((UINT64) INPLOGIC(m_DIN) << (adr & 0x3f));
}
OUTLOGIC(m_DOUTQ, ((m_ram[adr >> 6] >> (adr & 0x3f)) & 1) ^ 1, NLTIME_FROM_NS(20));
}
}
NETLIB_RESETI();
NETLIB_UPDATEI();
NETLIB_RESET(82S16)
{
for (int i=0; i<4; i++)
protected:
object_array_t<logic_input_t, 8> m_A;
logic_input_t m_CE1Q;
logic_input_t m_CE2Q;
logic_input_t m_CE3Q;
logic_input_t m_WEQ;
logic_input_t m_DIN;
logic_output_t m_DOUTQ;
//netlist_state_t<UINT8[256]> m_ram;
UINT64 m_ram[4]; // 256 bits
};
NETLIB_OBJECT_DERIVED(82S16_dip, 82S16)
{
m_ram[i] = 0;
}
}
NETLIB_CONSTRUCTOR_DERIVED(82S16_dip, 82S16)
{
register_subalias("2", m_A[0]);
register_subalias("1", m_A[1]);
register_subalias("15", m_A[2]);
register_subalias("14", m_A[3]);
register_subalias("7", m_A[4]);
register_subalias("9", m_A[5]);
register_subalias("10", m_A[6]);
register_subalias("11", m_A[7]);
NETLIB_NAMESPACE_DEVICES_END()
register_subalias("3", m_CE1Q);
register_subalias("4", m_CE2Q);
register_subalias("5", m_CE3Q);
register_subalias("12", m_WEQ);
register_subalias("13", m_DIN);
register_subalias("6", m_DOUTQ);
}
};
// FIXME: timing!
// FIXME: optimize device (separate address decoder!)
NETLIB_UPDATE(82S16)
{
if (INPLOGIC(m_CE1Q) || INPLOGIC(m_CE2Q) || INPLOGIC(m_CE3Q))
{
// FIXME: Outputs are tristate. This needs to be properly implemented
OUTLOGIC(m_DOUTQ, 1, NLTIME_FROM_NS(20));
//for (int i=0; i<8; i++)
//m_A[i].inactivate();
}
else
{
unsigned int adr = 0;
for (int i=0; i<8; i++)
{
//m_A[i].activate();
adr |= (INPLOGIC(m_A[i]) << i);
}
if (!INPLOGIC(m_WEQ))
{
m_ram[adr >> 6] = (m_ram[adr >> 6] & ~((UINT64) 1 << (adr & 0x3f))) | ((UINT64) INPLOGIC(m_DIN) << (adr & 0x3f));
}
OUTLOGIC(m_DOUTQ, ((m_ram[adr >> 6] >> (adr & 0x3f)) & 1) ^ 1, NLTIME_FROM_NS(20));
}
}
NETLIB_RESET(82S16)
{
for (int i=0; i<4; i++)
{
m_ram[i] = 0;
}
}
NETLIB_DEVICE_IMPL(82S16)
NETLIB_DEVICE_IMPL(82S16_dip)
} //namespace devices
} // namespace netlist

View File

@ -24,81 +24,11 @@
#ifndef NLD_82S16_H_
#define NLD_82S16_H_
#include "nl_base.h"
#include "nl_setup.h"
#define TTL_82S16(name) \
NET_REGISTER_DEV(TTL_82S16, name)
#define TTL_82S16_DIP(name) \
NET_REGISTER_DEV(TTL_82S16_DIP, name)
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_OBJECT(82S16)
{
NETLIB_CONSTRUCTOR(82S16)
{
enregister("A0", m_A[0]);
enregister("A1", m_A[1]);
enregister("A2", m_A[2]);
enregister("A3", m_A[3]);
enregister("A4", m_A[4]);
enregister("A5", m_A[5]);
enregister("A6", m_A[6]);
enregister("A7", m_A[7]);
enregister("CE1Q", m_CE1Q);
enregister("CE2Q", m_CE2Q);
enregister("CE3Q", m_CE3Q);
enregister("WEQ", m_WEQ);
enregister("DIN", m_DIN);
enregister("DOUTQ",m_DOUTQ);
save(NLNAME(m_ram));
}
NETLIB_RESETI();
NETLIB_UPDATEI();
protected:
logic_input_t m_A[8];
logic_input_t m_CE1Q;
logic_input_t m_CE2Q;
logic_input_t m_CE3Q;
logic_input_t m_WEQ;
logic_input_t m_DIN;
logic_output_t m_DOUTQ;
//netlist_state_t<UINT8[256]> m_ram;
UINT64 m_ram[4]; // 256 bits
};
NETLIB_OBJECT_DERIVED(82S16_dip, 82S16)
{
NETLIB_CONSTRUCTOR_DERIVED(82S16_dip, 82S16)
{
enregister("2", m_A[0]);
enregister("1", m_A[1]);
enregister("15", m_A[2]);
enregister("14", m_A[3]);
enregister("7", m_A[4]);
enregister("9", m_A[5]);
enregister("10", m_A[6]);
enregister("11", m_A[7]);
enregister("3", m_CE1Q);
enregister("4", m_CE2Q);
enregister("5", m_CE3Q);
enregister("12", m_WEQ);
enregister("13", m_DIN);
enregister("6", m_DOUTQ);
}
};
NETLIB_NAMESPACE_DEVICES_END()
#endif /* NLD_82S16_H_ */

View File

@ -9,142 +9,263 @@
#define MAXCNT 9
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_RESET(9310)
namespace netlist
{
sub.do_reset();
subABCD.do_reset();
}
NETLIB_RESET(9310_subABCD)
{
#if 0
m_A.inactivate();
m_B.inactivate();
m_C.inactivate();
m_D.inactivate();
#endif
}
NETLIB_RESET(9310_sub)
{
m_CLK.set_state(logic_t::STATE_INP_LH);
m_cnt = 0;
m_loadq = 1;
m_ent = 1;
}
NETLIB_UPDATE(9310_sub)
{
if (m_loadq)
namespace devices
{
#if 0
m_cnt = (m_cnt < MAXCNT) ? m_cnt + 1 : 0;
update_outputs(m_cnt);
OUTLOGIC(m_RC, m_ent & (m_cnt == MAXCNT), NLTIME_FROM_NS(20));
#else
switch (m_cnt)
NETLIB_OBJECT(9310_subABCD)
{
NETLIB_CONSTRUCTOR(9310_subABCD)
, m_A(*this, "A")
, m_B(*this, "B")
, m_C(*this, "C")
, m_D(*this, "D")
{
case MAXCNT - 1:
m_cnt = MAXCNT;
OUTLOGIC(m_RC, m_ent, NLTIME_FROM_NS(20));
OUTLOGIC(m_QA, 1, NLTIME_FROM_NS(20));
}
NETLIB_RESETI();
//NETLIB_UPDATEI();
public:
logic_input_t m_A;
logic_input_t m_B;
logic_input_t m_C;
logic_input_t m_D;
inline UINT8 read_ABCD() const
{
//return (INPLOGIC_PASSIVE(m_D) << 3) | (INPLOGIC_PASSIVE(m_C) << 2) | (INPLOGIC_PASSIVE(m_B) << 1) | (INPLOGIC_PASSIVE(m_A) << 0);
return (INPLOGIC(m_D) << 3) | (INPLOGIC(m_C) << 2) | (INPLOGIC(m_B) << 1) | (INPLOGIC(m_A) << 0);
}
};
NETLIB_OBJECT(9310_sub)
{
NETLIB_CONSTRUCTOR(9310_sub)
, m_CLK(*this, "CLK")
, m_ABCD(nullptr)
, m_QA(*this, "QA")
, m_QB(*this, "QB")
, m_QC(*this, "QC")
, m_QD(*this, "QD")
, m_RC(*this, "RC")
, m_cnt(0)
, m_loadq(0)
, m_ent(0)
{
save(NLNAME(m_cnt));
save(NLNAME(m_loadq));
save(NLNAME(m_ent));
}
NETLIB_RESETI();
NETLIB_UPDATEI();
public:
inline void update_outputs_all(const UINT8 cnt, const netlist_time out_delay);
inline void update_outputs(const UINT8 cnt);
logic_input_t m_CLK;
NETLIB_NAME(9310_subABCD) *m_ABCD;
logic_output_t m_QA;
logic_output_t m_QB;
logic_output_t m_QC;
logic_output_t m_QD;
logic_output_t m_RC;
UINT8 m_cnt;
netlist_sig_t m_loadq;
netlist_sig_t m_ent;
};
NETLIB_OBJECT(9310)
{
NETLIB_CONSTRUCTOR(9310)
, subABCD(*this, "subABCD")
, sub(*this, "sub")
, m_ENP(*this, "ENP")
, m_ENT(*this, "ENT")
, m_CLRQ(*this, "CLRQ")
, m_LOADQ(*this, "LOADQ")
{
sub.m_ABCD = &(subABCD);
register_subalias("CLK", sub.m_CLK);
register_subalias("A", subABCD.m_A);
register_subalias("B", subABCD.m_B);
register_subalias("C", subABCD.m_C);
register_subalias("D", subABCD.m_D);
register_subalias("QA", sub.m_QA);
register_subalias("QB", sub.m_QB);
register_subalias("QC", sub.m_QC);
register_subalias("QD", sub.m_QD);
register_subalias("RC", sub.m_RC);
}
NETLIB_RESETI();
NETLIB_UPDATEI();
public:
NETLIB_SUB(9310_subABCD) subABCD;
NETLIB_SUB(9310_sub) sub;
logic_input_t m_ENP;
logic_input_t m_ENT;
logic_input_t m_CLRQ;
logic_input_t m_LOADQ;
};
NETLIB_OBJECT_DERIVED(9310_dip, 9310)
{
NETLIB_CONSTRUCTOR_DERIVED(9310_dip, 9310)
{
register_subalias("1", m_CLRQ);
register_subalias("2", sub.m_CLK);
register_subalias("3", subABCD.m_A);
register_subalias("4", subABCD.m_B);
register_subalias("5", subABCD.m_C);
register_subalias("6", subABCD.m_D);
register_subalias("7", m_ENP);
// register_subalias("8", ); -. GND
register_subalias("9", m_LOADQ);
register_subalias("10", m_ENT);
register_subalias("11", sub.m_QD);
register_subalias("12", sub.m_QC);
register_subalias("13", sub.m_QB);
register_subalias("14", sub.m_QA);
register_subalias("15", sub.m_RC);
// register_subalias("16", ); -. VCC
}
};
NETLIB_RESET(9310)
{
sub.do_reset();
subABCD.do_reset();
}
NETLIB_RESET(9310_subABCD)
{
}
NETLIB_RESET(9310_sub)
{
m_CLK.set_state(logic_t::STATE_INP_LH);
m_cnt = 0;
m_loadq = 1;
m_ent = 1;
}
NETLIB_UPDATE(9310_sub)
{
if (m_loadq)
{
switch (m_cnt)
{
case MAXCNT - 1:
m_cnt = MAXCNT;
OUTLOGIC(m_RC, m_ent, NLTIME_FROM_NS(20));
OUTLOGIC(m_QA, 1, NLTIME_FROM_NS(20));
break;
case MAXCNT:
OUTLOGIC(m_RC, 0, NLTIME_FROM_NS(20));
m_cnt = 0;
update_outputs_all(m_cnt, NLTIME_FROM_NS(20));
break;
default:
m_cnt++;
update_outputs(m_cnt);
}
}
else
{
m_cnt = m_ABCD->read_ABCD();
update_outputs_all(m_cnt, NLTIME_FROM_NS(22));
OUTLOGIC(m_RC, m_ent & (m_cnt == MAXCNT), NLTIME_FROM_NS(27));
}
}
NETLIB_UPDATE(9310)
{
sub.m_loadq = INPLOGIC(m_LOADQ);
sub.m_ent = INPLOGIC(m_ENT);
const netlist_sig_t clrq = INPLOGIC(m_CLRQ);
if ((!sub.m_loadq || (sub.m_ent & INPLOGIC(m_ENP))) && clrq)
{
sub.m_CLK.activate_lh();
OUTLOGIC(sub.m_RC, sub.m_ent & (sub.m_cnt == MAXCNT), NLTIME_FROM_NS(27));
}
else
{
sub.m_CLK.inactivate();
if (!clrq && (sub.m_cnt>0))
{
sub.update_outputs_all(0, NLTIME_FROM_NS(36));
sub.m_cnt = 0;
//return;
}
OUTLOGIC(sub.m_RC, sub.m_ent & (sub.m_cnt == MAXCNT), NLTIME_FROM_NS(27));
}
}
inline NETLIB_FUNC_VOID(9310_sub, update_outputs_all, (const UINT8 cnt, const netlist_time out_delay))
{
OUTLOGIC(m_QA, (cnt >> 0) & 1, out_delay);
OUTLOGIC(m_QB, (cnt >> 1) & 1, out_delay);
OUTLOGIC(m_QC, (cnt >> 2) & 1, out_delay);
OUTLOGIC(m_QD, (cnt >> 3) & 1, out_delay);
}
inline NETLIB_FUNC_VOID(9310_sub, update_outputs, (const UINT8 cnt))
{
/* static */ const netlist_time out_delay = NLTIME_FROM_NS(20);
#if 0
// for (int i=0; i<4; i++)
// OUTLOGIC(m_Q[i], (cnt >> i) & 1, delay[i]);
OUTLOGIC(m_QA, (cnt >> 0) & 1, out_delay);
OUTLOGIC(m_QB, (cnt >> 1) & 1, out_delay);
OUTLOGIC(m_QC, (cnt >> 2) & 1, out_delay);
OUTLOGIC(m_QD, (cnt >> 3) & 1, out_delay);
#else
if ((cnt & 1) == 1)
OUTLOGIC(m_QA, 1, out_delay);
else
{
OUTLOGIC(m_QA, 0, out_delay);
switch (cnt)
{
case 0x00:
OUTLOGIC(m_QB, 0, out_delay);
OUTLOGIC(m_QC, 0, out_delay);
OUTLOGIC(m_QD, 0, out_delay);
break;
case MAXCNT:
OUTLOGIC(m_RC, 0, NLTIME_FROM_NS(20));
m_cnt = 0;
update_outputs_all(m_cnt, NLTIME_FROM_NS(20));
case 0x02:
case 0x06:
case 0x0A:
case 0x0E:
OUTLOGIC(m_QB, 1, out_delay);
break;
default:
m_cnt++;
update_outputs(m_cnt);
case 0x04:
case 0x0C:
OUTLOGIC(m_QB, 0, out_delay);
OUTLOGIC(m_QC, 1, out_delay);
break;
case 0x08:
OUTLOGIC(m_QB, 0, out_delay);
OUTLOGIC(m_QC, 0, out_delay);
OUTLOGIC(m_QD, 1, out_delay);
break;
}
}
#endif
#endif
}
else
{
m_cnt = m_ABCD->read_ABCD();
update_outputs_all(m_cnt, NLTIME_FROM_NS(22));
OUTLOGIC(m_RC, m_ent & (m_cnt == MAXCNT), NLTIME_FROM_NS(27));
}
}
NETLIB_UPDATE(9310)
{
sub.m_loadq = INPLOGIC(m_LOADQ);
sub.m_ent = INPLOGIC(m_ENT);
const netlist_sig_t clrq = INPLOGIC(m_CLRQ);
NETLIB_DEVICE_IMPL(9310)
NETLIB_DEVICE_IMPL(9310_dip)
if ((!sub.m_loadq || (sub.m_ent & INPLOGIC(m_ENP))) && clrq)
{
sub.m_CLK.activate_lh();
OUTLOGIC(sub.m_RC, sub.m_ent & (sub.m_cnt == MAXCNT), NLTIME_FROM_NS(27));
}
else
{
sub.m_CLK.inactivate();
if (!clrq && (sub.m_cnt>0))
{
sub.update_outputs_all(0, NLTIME_FROM_NS(36));
sub.m_cnt = 0;
//return;
}
OUTLOGIC(sub.m_RC, sub.m_ent & (sub.m_cnt == MAXCNT), NLTIME_FROM_NS(27));
}
}
inline NETLIB_FUNC_VOID(9310_sub, update_outputs_all, (const UINT8 cnt, const netlist_time out_delay))
{
OUTLOGIC(m_QA, (cnt >> 0) & 1, out_delay);
OUTLOGIC(m_QB, (cnt >> 1) & 1, out_delay);
OUTLOGIC(m_QC, (cnt >> 2) & 1, out_delay);
OUTLOGIC(m_QD, (cnt >> 3) & 1, out_delay);
}
inline NETLIB_FUNC_VOID(9310_sub, update_outputs, (const UINT8 cnt))
{
/* static */ const netlist_time out_delay = NLTIME_FROM_NS(20);
#if 0
// for (int i=0; i<4; i++)
// OUTLOGIC(m_Q[i], (cnt >> i) & 1, delay[i]);
OUTLOGIC(m_QA, (cnt >> 0) & 1, out_delay);
OUTLOGIC(m_QB, (cnt >> 1) & 1, out_delay);
OUTLOGIC(m_QC, (cnt >> 2) & 1, out_delay);
OUTLOGIC(m_QD, (cnt >> 3) & 1, out_delay);
#else
if ((cnt & 1) == 1)
OUTLOGIC(m_QA, 1, out_delay);
else
{
OUTLOGIC(m_QA, 0, out_delay);
switch (cnt)
{
case 0x00:
OUTLOGIC(m_QB, 0, out_delay);
OUTLOGIC(m_QC, 0, out_delay);
OUTLOGIC(m_QD, 0, out_delay);
break;
case 0x02:
case 0x06:
case 0x0A:
case 0x0E:
OUTLOGIC(m_QB, 1, out_delay);
break;
case 0x04:
case 0x0C:
OUTLOGIC(m_QB, 0, out_delay);
OUTLOGIC(m_QC, 1, out_delay);
break;
case 0x08:
OUTLOGIC(m_QB, 0, out_delay);
OUTLOGIC(m_QC, 0, out_delay);
OUTLOGIC(m_QD, 1, out_delay);
break;
}
}
#endif
}
NETLIB_NAMESPACE_DEVICES_END()
} //namespace devices
} // namespace netlist

View File

@ -45,152 +45,21 @@
#ifndef NLD_9310_H_
#define NLD_9310_H_
#include "nl_base.h"
#include "nl_setup.h"
#define TTL_9310(name, cCLK, cENP, cENT, cCLRQ, cLOADQ, cA, cB, cC, cD) \
NET_REGISTER_DEV(TTL_9310, name) \
NET_CONNECT(name, CLK, cCLK) \
NET_CONNECT(name, ENP, cENP) \
NET_CONNECT(name, ENT, cENT) \
NET_CONNECT(name, CLRQ, cCLRQ) \
NET_CONNECT(name, LOADQ,_LOADQ) \
NET_CONNECT(name, A, cA) \
NET_CONNECT(name, B, cB) \
NET_CONNECT(name, C, cC) \
#define TTL_9310(name, cCLK, cENP, cENT, cCLRQ, cLOADQ, cA, cB, cC, cD) \
NET_REGISTER_DEV(TTL_9310, name) \
NET_CONNECT(name, CLK, cCLK) \
NET_CONNECT(name, ENP, cENP) \
NET_CONNECT(name, ENT, cENT) \
NET_CONNECT(name, CLRQ, cCLRQ) \
NET_CONNECT(name, LOADQ,_LOADQ) \
NET_CONNECT(name, A, cA) \
NET_CONNECT(name, B, cB) \
NET_CONNECT(name, C, cC) \
NET_CONNECT(name, D, cD)
#define TTL_9310_DIP(name) \
#define TTL_9310_DIP(name) \
NET_REGISTER_DEV(TTL_9310_DIP, name)
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_OBJECT(9310_subABCD)
{
NETLIB_CONSTRUCTOR(9310_subABCD)
{
enregister("A", m_A);
enregister("B", m_B);
enregister("C", m_C);
enregister("D", m_D);
}
NETLIB_RESETI();
//NETLIB_UPDATEI();
public:
logic_input_t m_A;
logic_input_t m_B;
logic_input_t m_C;
logic_input_t m_D;
ATTR_HOT inline UINT8 read_ABCD() const
{
//return (INPLOGIC_PASSIVE(m_D) << 3) | (INPLOGIC_PASSIVE(m_C) << 2) | (INPLOGIC_PASSIVE(m_B) << 1) | (INPLOGIC_PASSIVE(m_A) << 0);
return (INPLOGIC(m_D) << 3) | (INPLOGIC(m_C) << 2) | (INPLOGIC(m_B) << 1) | (INPLOGIC(m_A) << 0);
}
};
NETLIB_OBJECT(9310_sub)
{
NETLIB_CONSTRUCTOR(9310_sub)
, m_cnt(0)
, m_ABCD(nullptr)
, m_loadq(0)
, m_ent(0)
{
enregister("CLK", m_CLK);
enregister("QA", m_QA);
enregister("QB", m_QB);
enregister("QC", m_QC);
enregister("QD", m_QD);
enregister("RC", m_RC);
save(NLNAME(m_cnt));
save(NLNAME(m_loadq));
save(NLNAME(m_ent));
}
NETLIB_RESETI();
NETLIB_UPDATEI();
public:
ATTR_HOT inline void update_outputs_all(const UINT8 cnt, const netlist_time out_delay);
ATTR_HOT inline void update_outputs(const UINT8 cnt);
logic_input_t m_CLK;
UINT8 m_cnt;
NETLIB_NAME(9310_subABCD) *m_ABCD;
netlist_sig_t m_loadq;
netlist_sig_t m_ent;
logic_output_t m_QA;
logic_output_t m_QB;
logic_output_t m_QC;
logic_output_t m_QD;
logic_output_t m_RC;
};
NETLIB_OBJECT(9310)
{
NETLIB_CONSTRUCTOR(9310)
, subABCD(*this, "subABCD")
, sub(*this, "sub")
{
sub.m_ABCD = &(subABCD);
register_subalias("CLK", sub.m_CLK);
enregister("ENP", m_ENP);
enregister("ENT", m_ENT);
enregister("CLRQ", m_CLRQ);
enregister("LOADQ", m_LOADQ);
register_subalias("A", subABCD.m_A);
register_subalias("B", subABCD.m_B);
register_subalias("C", subABCD.m_C);
register_subalias("D", subABCD.m_D);
register_subalias("QA", sub.m_QA);
register_subalias("QB", sub.m_QB);
register_subalias("QC", sub.m_QC);
register_subalias("QD", sub.m_QD);
register_subalias("RC", sub.m_RC);
}
NETLIB_RESETI();
NETLIB_UPDATEI();
public:
NETLIB_SUB(9310_subABCD) subABCD;
NETLIB_SUB(9310_sub) sub;
logic_input_t m_ENP;
logic_input_t m_ENT;
logic_input_t m_CLRQ;
logic_input_t m_LOADQ;
};
NETLIB_OBJECT_DERIVED(9310_dip, 9310)
{
NETLIB_CONSTRUCTOR_DERIVED(9310_dip, 9310)
{
register_subalias("1", m_CLRQ);
register_subalias("2", sub.m_CLK);
register_subalias("3", subABCD.m_A);
register_subalias("4", subABCD.m_B);
register_subalias("5", subABCD.m_C);
register_subalias("6", subABCD.m_D);
register_subalias("7", m_ENP);
// register_subalias("8", ); -. GND
register_subalias("9", m_LOADQ);
register_subalias("10", m_ENT);
register_subalias("11", sub.m_QD);
register_subalias("12", sub.m_QC);
register_subalias("13", sub.m_QB);
register_subalias("14", sub.m_QA);
register_subalias("15", sub.m_RC);
// register_subalias("16", ); -. VCC
}
};
NETLIB_NAMESPACE_DEVICES_END()
#endif /* NLD_9310_H_ */

View File

@ -21,107 +21,193 @@
* +---+---+---+---++---+---+
*/
#include "nld_9312.h"
#include "nld_truthtable.h"
NETLIB_NAMESPACE_DEVICES_START()
#if (1 && 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.
* This would require a state machine, thus we do not
* do this right now.
*/
const char *nld_9312::m_desc[] = {
" C, B, A, G,D0,D1,D2,D3,D4,D5,D6,D7| Y,YQ",
" X, X, X, 1, X, X, X, X, X, X, X, X| 0, 1|33,19",
" 0, 0, 0, 0, 0, X, X, X, X, X, X, X| 0, 1|33,28",
" 0, 0, 0, 0, 1, X, X, X, X, X, X, X| 1, 0|33,28",
" 0, 0, 1, 0, X, 0, X, X, X, X, X, X| 0, 1|33,28",
" 0, 0, 1, 0, X, 1, X, X, X, X, X, X| 1, 0|33,28",
" 0, 1, 0, 0, X, X, 0, X, X, X, X, X| 0, 1|33,28",
" 0, 1, 0, 0, X, X, 1, X, X, X, X, X| 1, 0|33,28",
" 0, 1, 1, 0, X, X, X, 0, X, X, X, X| 0, 1|33,28",
" 0, 1, 1, 0, X, X, X, 1, X, X, X, X| 1, 0|33,28",
" 1, 0, 0, 0, X, X, X, X, 0, X, X, X| 0, 1|33,28",
" 1, 0, 0, 0, X, X, X, X, 1, X, X, X| 1, 0|33,28",
" 1, 0, 1, 0, X, X, X, X, X, 0, X, X| 0, 1|33,28",
" 1, 0, 1, 0, X, X, X, X, X, 1, X, X| 1, 0|33,28",
" 1, 1, 0, 0, X, X, X, X, X, X, 0, X| 0, 1|33,28",
" 1, 1, 0, 0, X, X, X, X, X, X, 1, X| 1, 0|33,28",
" 1, 1, 1, 0, X, X, X, X, X, X, X, 0| 0, 1|33,28",
" 1, 1, 1, 0, X, X, X, X, X, X, X, 1| 1, 0|33,28",
""
};
#else
NETLIB_UPDATE(9312)
namespace netlist
{
const UINT8 G = INPLOGIC(m_G);
if (G)
namespace devices
{
/* static */ const netlist_time delay[2] = { NLTIME_FROM_NS(33), NLTIME_FROM_NS(19) };
OUTLOGIC(m_Y, 0, delay[0]);
OUTLOGIC(m_YQ, 1, delay[1]);
m_A.inactivate();
m_B.inactivate();
m_C.inactivate();
m_last_G = G;
}
else
#if (USE_TRUTHTABLE)
/* The truthtable implementation is a lot faster than
* the carefully crafted code :-(
*/
NETLIB_TRUTHTABLE(9312, 12, 2, 0);
#else
NETLIB_DEVICE(9312,
public:
// C, B, A, G,D0,D1,D2,D3,D4,D5,D6,D7| Y,YQ
logic_input_t m_A;
logic_input_t m_B;
logic_input_t m_C;
logic_input_t m_G;
logic_input_t m_D[8];
logic_output_t m_Y;
logic_output_t m_YQ;
UINT8 m_last_chan;
UINT8 m_last_G;
);
#endif
NETLIB_OBJECT(9312_dip)
{
if (m_last_G)
NETLIB_CONSTRUCTOR(9312_dip)
, m_sub(*this, "1")
{
#if (1 && USE_TRUTHTABLE)
register_subalias("13", m_sub.m_I[0]);
register_subalias("12", m_sub.m_I[1]);
register_subalias("11", m_sub.m_I[2]);
register_subalias("10", m_sub.m_I[3]);
register_subalias("1", m_sub.m_I[4]);
register_subalias("2", m_sub.m_I[5]);
register_subalias("3", m_sub.m_I[6]);
register_subalias("4", m_sub.m_I[7]);
register_subalias("5", m_sub.m_I[8]);
register_subalias("6", m_sub.m_I[9]);
register_subalias("7", m_sub.m_I[10]);
register_subalias("9", m_sub.m_I[11]);
register_subalias("15", m_sub.m_Q[0]); // Y
register_subalias("14", m_sub.m_Q[1]); // YQ
#else
register_subalias("13", m_sub.m_C);
register_subalias("12", m_sub.m_B);
register_subalias("11", m_sub.m_A);
register_subalias("10", m_sub.m_G);
register_subalias("1", m_sub.m_D[0]);
register_subalias("2", m_sub.m_D[1]);
register_subalias("3", m_sub.m_D[2]);
register_subalias("4", m_sub.m_D[3]);
register_subalias("5", m_sub.m_D[4]);
register_subalias("6", m_sub.m_D[5]);
register_subalias("7", m_sub.m_D[6]);
register_subalias("9", m_sub.m_D[7]);
register_subalias("15", m_sub.m_Y); // Y
register_subalias("14", m_sub.m_YQ); // YQ
#endif
}
//NETLIB_RESETI();
//NETLIB_UPDATEI();
protected:
NETLIB_SUB(9312) m_sub;
};
#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.
* This would require a state machine, thus we do not
* do this right now.
*/
const char *nld_9312::m_desc[] = {
" C, B, A, G,D0,D1,D2,D3,D4,D5,D6,D7| Y,YQ",
" X, X, X, 1, X, X, X, X, X, X, X, X| 0, 1|33,19",
" 0, 0, 0, 0, 0, X, X, X, X, X, X, X| 0, 1|33,28",
" 0, 0, 0, 0, 1, X, X, X, X, X, X, X| 1, 0|33,28",
" 0, 0, 1, 0, X, 0, X, X, X, X, X, X| 0, 1|33,28",
" 0, 0, 1, 0, X, 1, X, X, X, X, X, X| 1, 0|33,28",
" 0, 1, 0, 0, X, X, 0, X, X, X, X, X| 0, 1|33,28",
" 0, 1, 0, 0, X, X, 1, X, X, X, X, X| 1, 0|33,28",
" 0, 1, 1, 0, X, X, X, 0, X, X, X, X| 0, 1|33,28",
" 0, 1, 1, 0, X, X, X, 1, X, X, X, X| 1, 0|33,28",
" 1, 0, 0, 0, X, X, X, X, 0, X, X, X| 0, 1|33,28",
" 1, 0, 0, 0, X, X, X, X, 1, X, X, X| 1, 0|33,28",
" 1, 0, 1, 0, X, X, X, X, X, 0, X, X| 0, 1|33,28",
" 1, 0, 1, 0, X, X, X, X, X, 1, X, X| 1, 0|33,28",
" 1, 1, 0, 0, X, X, X, X, X, X, 0, X| 0, 1|33,28",
" 1, 1, 0, 0, X, X, X, X, X, X, 1, X| 1, 0|33,28",
" 1, 1, 1, 0, X, X, X, X, X, X, X, 0| 0, 1|33,28",
" 1, 1, 1, 0, X, X, X, X, X, X, X, 1| 1, 0|33,28",
""
};
#else
NETLIB_UPDATE(9312)
{
const UINT8 G = INPLOGIC(m_G);
if (G)
{
const netlist_time delay[2] = { NLTIME_FROM_NS(33), NLTIME_FROM_NS(19) };
OUTLOGIC(m_Y, 0, delay[0]);
OUTLOGIC(m_YQ, 1, delay[1]);
m_A.inactivate();
m_B.inactivate();
m_C.inactivate();
m_last_G = G;
m_A.activate();
m_B.activate();
m_C.activate();
}
/* static */ const netlist_time delay[2] = { NLTIME_FROM_NS(33), NLTIME_FROM_NS(28) };
const UINT8 chan = INPLOGIC(m_A) | (INPLOGIC(m_B)<<1) | (INPLOGIC(m_C)<<2);
if (m_last_chan != chan)
else
{
m_D[m_last_chan].inactivate();
m_D[chan].activate();
if (m_last_G)
{
m_last_G = G;
m_A.activate();
m_B.activate();
m_C.activate();
}
const netlist_time delay[2] = { NLTIME_FROM_NS(33), NLTIME_FROM_NS(28) };
const UINT8 chan = INPLOGIC(m_A) | (INPLOGIC(m_B)<<1) | (INPLOGIC(m_C)<<2);
if (m_last_chan != chan)
{
m_D[m_last_chan].inactivate();
m_D[chan].activate();
}
const UINT8 val = INPLOGIC(m_D[chan]);
OUTLOGIC(m_Y, val, delay[val]);
OUTLOGIC(m_YQ, !val, delay[!val]);
m_last_chan = chan;
}
const UINT8 val = INPLOGIC(m_D[chan]);
OUTLOGIC(m_Y, val, delay[val]);
OUTLOGIC(m_YQ, !val, delay[!val]);
m_last_chan = chan;
}
}
NETLIB_START(9312)
{
register_input("G", m_G);
register_input("A", m_A);
register_input("B", m_B);
register_input("C", m_C);
NETLIB_START(9312)
{
register_input("G", m_G);
register_input("A", m_A);
register_input("B", m_B);
register_input("C", m_C);
register_input("D0", m_D[0]);
register_input("D1", m_D[1]);
register_input("D2", m_D[2]);
register_input("D3", m_D[3]);
register_input("D4", m_D[4]);
register_input("D5", m_D[5]);
register_input("D6", m_D[6]);
register_input("D7", m_D[7]);
register_input("D0", m_D[0]);
register_input("D1", m_D[1]);
register_input("D2", m_D[2]);
register_input("D3", m_D[3]);
register_input("D4", m_D[4]);
register_input("D5", m_D[5]);
register_input("D6", m_D[6]);
register_input("D7", m_D[7]);
register_output("Y", m_Y);
register_output("YQ", m_YQ);
register_output("Y", m_Y);
register_output("YQ", m_YQ);
m_last_chan = 0;
m_last_G = 0;
m_last_chan = 0;
m_last_G = 0;
save(NLNAME(m_last_chan));
save(NLNAME(m_last_G));
}
save(NLNAME(m_last_chan));
save(NLNAME(m_last_G));
}
NETLIB_RESET(9312)
{
}
#endif
NETLIB_RESET(9312)
{
}
#endif
NETLIB_NAMESPACE_DEVICES_END()
NETLIB_DEVICE_IMPL(9312)
NETLIB_DEVICE_IMPL(9312_dip)
} //namespace devices
} // namespace netlist

View File

@ -37,94 +37,12 @@
#ifndef NLD_9312_H_
#define NLD_9312_H_
#include "nld_truthtable.h"
#include "nl_setup.h"
#define TTL_9312(name) \
#define TTL_9312(name) \
NET_REGISTER_DEV(TTL_9312, name)
#define TTL_9312_DIP(name) \
#define TTL_9312_DIP(name) \
NET_REGISTER_DEV(TTL_9312_DIP, name)
NETLIB_NAMESPACE_DEVICES_START()
#if (USE_TRUTHTABLE)
/* The truthtable implementation is a lot faster than
* the carefully crafted code :-(
*/
NETLIB_TRUTHTABLE(9312, 12, 2, 0);
#else
NETLIB_DEVICE(9312,
public:
// C, B, A, G,D0,D1,D2,D3,D4,D5,D6,D7| Y,YQ
logic_input_t m_A;
logic_input_t m_B;
logic_input_t m_C;
logic_input_t m_G;
logic_input_t m_D[8];
logic_output_t m_Y;
logic_output_t m_YQ;
UINT8 m_last_chan;
UINT8 m_last_G;
);
#endif
NETLIB_OBJECT(9312_dip)
{
NETLIB_CONSTRUCTOR(9312_dip)
, m_sub(*this, "1")
{
#if (1 && USE_TRUTHTABLE)
register_subalias("13", m_sub.m_I[0]);
register_subalias("12", m_sub.m_I[1]);
register_subalias("11", m_sub.m_I[2]);
register_subalias("10", m_sub.m_I[3]);
register_subalias("1", m_sub.m_I[4]);
register_subalias("2", m_sub.m_I[5]);
register_subalias("3", m_sub.m_I[6]);
register_subalias("4", m_sub.m_I[7]);
register_subalias("5", m_sub.m_I[8]);
register_subalias("6", m_sub.m_I[9]);
register_subalias("7", m_sub.m_I[10]);
register_subalias("9", m_sub.m_I[11]);
register_subalias("15", m_sub.m_Q[0]); // Y
register_subalias("14", m_sub.m_Q[1]); // YQ
#else
register_subalias("13", m_sub.m_C);
register_subalias("12", m_sub.m_B);
register_subalias("11", m_sub.m_A);
register_subalias("10", m_sub.m_G);
register_subalias("1", m_sub.m_D[0]);
register_subalias("2", m_sub.m_D[1]);
register_subalias("3", m_sub.m_D[2]);
register_subalias("4", m_sub.m_D[3]);
register_subalias("5", m_sub.m_D[4]);
register_subalias("6", m_sub.m_D[5]);
register_subalias("7", m_sub.m_D[6]);
register_subalias("9", m_sub.m_D[7]);
register_subalias("15", m_sub.m_Y); // Y
register_subalias("14", m_sub.m_YQ); // YQ
#endif
}
//NETLIB_RESETI();
//NETLIB_UPDATEI();
protected:
NETLIB_SUB(9312) m_sub;
};
NETLIB_NAMESPACE_DEVICES_END()
#endif /* NLD_9312_H_ */

View File

@ -9,137 +9,263 @@
#define MAXCNT 15
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_RESET(9316)
namespace netlist
{
sub.do_reset();
subABCD.do_reset();
}
NETLIB_RESET(9316_subABCD)
{
#if 0
m_A.inactivate();
m_B.inactivate();
m_C.inactivate();
m_D.inactivate();
#endif
}
NETLIB_RESET(9316_sub)
{
m_CLK.set_state(logic_t::STATE_INP_LH);
m_cnt = 0;
m_loadq = 1;
m_ent = 1;
}
NETLIB_UPDATE(9316_sub)
{
if (m_loadq)
namespace devices
{
switch (m_cnt)
NETLIB_OBJECT(9316_subABCD)
{
NETLIB_CONSTRUCTOR(9316_subABCD)
, m_A(*this, "A")
, m_B(*this, "B")
, m_C(*this, "C")
, m_D(*this, "D")
{
case MAXCNT - 1:
m_cnt = MAXCNT;
OUTLOGIC(m_RC, m_ent, NLTIME_FROM_NS(27));
OUTLOGIC(m_QA, 1, NLTIME_FROM_NS(20));
break;
case MAXCNT:
OUTLOGIC(m_RC, 0, NLTIME_FROM_NS(27));
m_cnt = 0;
update_outputs_all(m_cnt, NLTIME_FROM_NS(20));
break;
default:
m_cnt++;
update_outputs(m_cnt);
break;
}
}
else
{
m_cnt = m_ABCD->read_ABCD();
OUTLOGIC(m_RC, m_ent & (m_cnt == MAXCNT), NLTIME_FROM_NS(27));
update_outputs_all(m_cnt, NLTIME_FROM_NS(22));
}
}
NETLIB_UPDATE(9316)
{
sub.m_loadq = INPLOGIC(m_LOADQ);
sub.m_ent = INPLOGIC(m_ENT);
const netlist_sig_t clrq = INPLOGIC(m_CLRQ);
if (((sub.m_loadq ^ 1) | (sub.m_ent & INPLOGIC(m_ENP))) & clrq)
{
sub.m_CLK.activate_lh();
OUTLOGIC(sub.m_RC, sub.m_ent & (sub.m_cnt == MAXCNT), NLTIME_FROM_NS(27));
}
else
{
sub.m_CLK.inactivate();
if (!clrq && (sub.m_cnt>0))
{
sub.update_outputs_all(0, NLTIME_FROM_NS(36));
sub.m_cnt = 0;
//return;
}
OUTLOGIC(sub.m_RC, sub.m_ent & (sub.m_cnt == MAXCNT), NLTIME_FROM_NS(27));
}
}
inline NETLIB_FUNC_VOID(9316_sub, update_outputs_all, (const UINT8 cnt, const netlist_time out_delay))
{
OUTLOGIC(m_QA, (cnt >> 0) & 1, out_delay);
OUTLOGIC(m_QB, (cnt >> 1) & 1, out_delay);
OUTLOGIC(m_QC, (cnt >> 2) & 1, out_delay);
OUTLOGIC(m_QD, (cnt >> 3) & 1, out_delay);
}
inline NETLIB_FUNC_VOID(9316_sub, update_outputs, (const UINT8 cnt))
{
/* static */ const netlist_time out_delay = NLTIME_FROM_NS(20);
#if 0
// for (int i=0; i<4; i++)
// OUTLOGIC(m_Q[i], (cnt >> i) & 1, delay[i]);
OUTLOGIC(m_QA, (cnt >> 0) & 1, out_delay);
OUTLOGIC(m_QB, (cnt >> 1) & 1, out_delay);
OUTLOGIC(m_QC, (cnt >> 2) & 1, out_delay);
OUTLOGIC(m_QD, (cnt >> 3) & 1, out_delay);
#else
if ((cnt & 1) == 1)
OUTLOGIC(m_QA, 1, out_delay);
else
{
OUTLOGIC(m_QA, 0, out_delay);
switch (cnt)
{
case 0x00:
OUTLOGIC(m_QB, 0, out_delay);
OUTLOGIC(m_QC, 0, out_delay);
OUTLOGIC(m_QD, 0, out_delay);
break;
case 0x02:
case 0x06:
case 0x0A:
case 0x0E:
OUTLOGIC(m_QB, 1, out_delay);
break;
case 0x04:
case 0x0C:
OUTLOGIC(m_QB, 0, out_delay);
OUTLOGIC(m_QC, 1, out_delay);
break;
case 0x08:
OUTLOGIC(m_QB, 0, out_delay);
OUTLOGIC(m_QC, 0, out_delay);
OUTLOGIC(m_QD, 1, out_delay);
break;
}
}
#endif
}
//NETLIB_RESETI()
//NETLIB_UPDATEI();
NETLIB_NAMESPACE_DEVICES_END()
public:
logic_input_t m_A;
logic_input_t m_B;
logic_input_t m_C;
logic_input_t m_D;
inline UINT8 read_ABCD() const
{
//return (INPLOGIC_PASSIVE(m_D) << 3) | (INPLOGIC_PASSIVE(m_C) << 2) | (INPLOGIC_PASSIVE(m_B) << 1) | (INPLOGIC_PASSIVE(m_A) << 0);
return (INPLOGIC(m_D) << 3) | (INPLOGIC(m_C) << 2) | (INPLOGIC(m_B) << 1) | (INPLOGIC(m_A) << 0);
}
};
NETLIB_OBJECT(9316_sub)
{
NETLIB_CONSTRUCTOR(9316_sub)
, m_CLK(*this, "CLK")
, m_QA(*this, "QA")
, m_QB(*this, "QB")
, m_QC(*this, "QC")
, m_QD(*this, "QD")
, m_RC(*this, "RC")
, m_cnt(0)
, m_ABCD(nullptr)
, m_loadq(0)
, m_ent(0)
{
save(NLNAME(m_cnt));
save(NLNAME(m_loadq));
save(NLNAME(m_ent));
}
NETLIB_RESETI();
NETLIB_UPDATEI();
public:
inline void update_outputs_all(const UINT8 cnt, const netlist_time out_delay);
inline void update_outputs(const UINT8 cnt);
logic_input_t m_CLK;
logic_output_t m_QA;
logic_output_t m_QB;
logic_output_t m_QC;
logic_output_t m_QD;
logic_output_t m_RC;
UINT8 m_cnt;
NETLIB_NAME(9316_subABCD) *m_ABCD;
netlist_sig_t m_loadq;
netlist_sig_t m_ent;
};
NETLIB_OBJECT(9316)
{
NETLIB_CONSTRUCTOR(9316)
, sub(*this, "sub")
, subABCD(*this, "subABCD")
, m_ENP(*this, "ENP")
, m_ENT(*this, "ENT")
, m_CLRQ(*this, "CLRQ")
, m_LOADQ(*this, "LOADQ")
{
sub.m_ABCD = &(subABCD);
register_subalias("CLK", sub.m_CLK);
register_subalias("A", subABCD.m_A);
register_subalias("B", subABCD.m_B);
register_subalias("C", subABCD.m_C);
register_subalias("D", subABCD.m_D);
register_subalias("QA", sub.m_QA);
register_subalias("QB", sub.m_QB);
register_subalias("QC", sub.m_QC);
register_subalias("QD", sub.m_QD);
register_subalias("RC", sub.m_RC);
}
NETLIB_RESETI();
NETLIB_UPDATEI();
protected:
NETLIB_SUB(9316_sub) sub;
NETLIB_SUB(9316_subABCD) subABCD;
logic_input_t m_ENP;
logic_input_t m_ENT;
logic_input_t m_CLRQ;
logic_input_t m_LOADQ;
};
NETLIB_OBJECT_DERIVED(9316_dip, 9316)
{
NETLIB_CONSTRUCTOR_DERIVED(9316_dip, 9316)
{
register_subalias("1", m_CLRQ);
register_subalias("2", sub.m_CLK);
register_subalias("3", subABCD.m_A);
register_subalias("4", subABCD.m_B);
register_subalias("5", subABCD.m_C);
register_subalias("6", subABCD.m_D);
register_subalias("7", m_ENP);
// register_subalias("8", ); -. GND
register_subalias("9", m_LOADQ);
register_subalias("10", m_ENT);
register_subalias("11", sub.m_QD);
register_subalias("12", sub.m_QC);
register_subalias("13", sub.m_QB);
register_subalias("14", sub.m_QA);
register_subalias("15", sub.m_RC);
// register_subalias("16", ); -. VCC
}
};
NETLIB_RESET(9316)
{
sub.do_reset();
subABCD.do_reset();
}
NETLIB_RESET(9316_sub)
{
m_CLK.set_state(logic_t::STATE_INP_LH);
m_cnt = 0;
m_loadq = 1;
m_ent = 1;
}
NETLIB_UPDATE(9316_sub)
{
if (m_loadq)
{
switch (m_cnt)
{
case MAXCNT - 1:
m_cnt = MAXCNT;
OUTLOGIC(m_RC, m_ent, NLTIME_FROM_NS(27));
OUTLOGIC(m_QA, 1, NLTIME_FROM_NS(20));
break;
case MAXCNT:
OUTLOGIC(m_RC, 0, NLTIME_FROM_NS(27));
m_cnt = 0;
update_outputs_all(m_cnt, NLTIME_FROM_NS(20));
break;
default:
m_cnt++;
update_outputs(m_cnt);
break;
}
}
else
{
m_cnt = m_ABCD->read_ABCD();
OUTLOGIC(m_RC, m_ent & (m_cnt == MAXCNT), NLTIME_FROM_NS(27));
update_outputs_all(m_cnt, NLTIME_FROM_NS(22));
}
}
NETLIB_UPDATE(9316)
{
sub.m_loadq = INPLOGIC(m_LOADQ);
sub.m_ent = INPLOGIC(m_ENT);
const netlist_sig_t clrq = INPLOGIC(m_CLRQ);
if (((sub.m_loadq ^ 1) | (sub.m_ent & INPLOGIC(m_ENP))) & clrq)
{
sub.m_CLK.activate_lh();
OUTLOGIC(sub.m_RC, sub.m_ent & (sub.m_cnt == MAXCNT), NLTIME_FROM_NS(27));
}
else
{
sub.m_CLK.inactivate();
if (!clrq && (sub.m_cnt>0))
{
sub.update_outputs_all(0, NLTIME_FROM_NS(36));
sub.m_cnt = 0;
//return;
}
OUTLOGIC(sub.m_RC, sub.m_ent & (sub.m_cnt == MAXCNT), NLTIME_FROM_NS(27));
}
}
inline NETLIB_FUNC_VOID(9316_sub, update_outputs_all, (const UINT8 cnt, const netlist_time out_delay))
{
OUTLOGIC(m_QA, (cnt >> 0) & 1, out_delay);
OUTLOGIC(m_QB, (cnt >> 1) & 1, out_delay);
OUTLOGIC(m_QC, (cnt >> 2) & 1, out_delay);
OUTLOGIC(m_QD, (cnt >> 3) & 1, out_delay);
}
inline NETLIB_FUNC_VOID(9316_sub, update_outputs, (const UINT8 cnt))
{
/* static */ const netlist_time out_delay = NLTIME_FROM_NS(20);
#if 0
// for (int i=0; i<4; i++)
// OUTLOGIC(m_Q[i], (cnt >> i) & 1, delay[i]);
OUTLOGIC(m_QA, (cnt >> 0) & 1, out_delay);
OUTLOGIC(m_QB, (cnt >> 1) & 1, out_delay);
OUTLOGIC(m_QC, (cnt >> 2) & 1, out_delay);
OUTLOGIC(m_QD, (cnt >> 3) & 1, out_delay);
#else
if ((cnt & 1) == 1)
OUTLOGIC(m_QA, 1, out_delay);
else
{
OUTLOGIC(m_QA, 0, out_delay);
switch (cnt)
{
case 0x00:
OUTLOGIC(m_QB, 0, out_delay);
OUTLOGIC(m_QC, 0, out_delay);
OUTLOGIC(m_QD, 0, out_delay);
break;
case 0x02:
case 0x06:
case 0x0A:
case 0x0E:
OUTLOGIC(m_QB, 1, out_delay);
break;
case 0x04:
case 0x0C:
OUTLOGIC(m_QB, 0, out_delay);
OUTLOGIC(m_QC, 1, out_delay);
break;
case 0x08:
OUTLOGIC(m_QB, 0, out_delay);
OUTLOGIC(m_QC, 0, out_delay);
OUTLOGIC(m_QD, 1, out_delay);
break;
}
}
#endif
}
NETLIB_DEVICE_IMPL(9316)
NETLIB_DEVICE_IMPL(9316_dip)
} //namespace devices
} // namespace netlist

View File

@ -49,7 +49,7 @@
#ifndef NLD_9316_H_
#define NLD_9316_H_
#include "nl_base.h"
#include "nl_setup.h"
#define TTL_9316(name, cCLK, cENP, cENT, cCLRQ, cLOADQ, cA, cB, cC, cD) \
NET_REGISTER_DEV(TTL_9316, name) \
@ -63,142 +63,7 @@
NET_CONNECT(name, C, cC) \
NET_CONNECT(name, D, cD)
#define TTL_9316_DIP(name) \
#define TTL_9316_DIP(name) \
NET_REGISTER_DEV(TTL_9316_DIP, name)
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_OBJECT(9316_subABCD)
{
NETLIB_CONSTRUCTOR(9316_subABCD)
{
enregister("A", m_A);
enregister("B", m_B);
enregister("C", m_C);
enregister("D", m_D);
}
NETLIB_RESETI();
//NETLIB_UPDATEI();
public:
logic_input_t m_A;
logic_input_t m_B;
logic_input_t m_C;
logic_input_t m_D;
ATTR_HOT inline UINT8 read_ABCD() const
{
//return (INPLOGIC_PASSIVE(m_D) << 3) | (INPLOGIC_PASSIVE(m_C) << 2) | (INPLOGIC_PASSIVE(m_B) << 1) | (INPLOGIC_PASSIVE(m_A) << 0);
return (INPLOGIC(m_D) << 3) | (INPLOGIC(m_C) << 2) | (INPLOGIC(m_B) << 1) | (INPLOGIC(m_A) << 0);
}
};
NETLIB_OBJECT(9316_sub)
{
NETLIB_CONSTRUCTOR(9316_sub)
, m_cnt(0)
, m_ABCD(nullptr)
, m_loadq(0)
, m_ent(0)
{
enregister("CLK", m_CLK);
enregister("QA", m_QA);
enregister("QB", m_QB);
enregister("QC", m_QC);
enregister("QD", m_QD);
enregister("RC", m_RC);
save(NLNAME(m_cnt));
save(NLNAME(m_loadq));
save(NLNAME(m_ent));
}
NETLIB_RESETI();
NETLIB_UPDATEI();
public:
ATTR_HOT inline void update_outputs_all(const UINT8 cnt, const netlist_time out_delay);
ATTR_HOT inline void update_outputs(const UINT8 cnt);
logic_input_t m_CLK;
logic_output_t m_QA;
logic_output_t m_QB;
logic_output_t m_QC;
logic_output_t m_QD;
logic_output_t m_RC;
UINT8 m_cnt;
NETLIB_NAME(9316_subABCD) *m_ABCD;
netlist_sig_t m_loadq;
netlist_sig_t m_ent;
};
NETLIB_OBJECT(9316)
{
NETLIB_CONSTRUCTOR(9316)
, sub(*this, "sub")
, subABCD(*this, "subABCD")
{
sub.m_ABCD = &(subABCD);
register_subalias("CLK", sub.m_CLK);
enregister("ENP", m_ENP);
enregister("ENT", m_ENT);
enregister("CLRQ", m_CLRQ);
enregister("LOADQ", m_LOADQ);
register_subalias("A", subABCD.m_A);
register_subalias("B", subABCD.m_B);
register_subalias("C", subABCD.m_C);
register_subalias("D", subABCD.m_D);
register_subalias("QA", sub.m_QA);
register_subalias("QB", sub.m_QB);
register_subalias("QC", sub.m_QC);
register_subalias("QD", sub.m_QD);
register_subalias("RC", sub.m_RC);
}
NETLIB_RESETI();
NETLIB_UPDATEI();
protected:
NETLIB_SUB(9316_sub) sub;
NETLIB_SUB(9316_subABCD) subABCD;
logic_input_t m_ENP;
logic_input_t m_ENT;
logic_input_t m_CLRQ;
logic_input_t m_LOADQ;
};
NETLIB_OBJECT_DERIVED(9316_dip, 9316)
{
NETLIB_CONSTRUCTOR_DERIVED(9316_dip, 9316)
{
register_subalias("1", m_CLRQ);
register_subalias("2", sub.m_CLK);
register_subalias("3", subABCD.m_A);
register_subalias("4", subABCD.m_B);
register_subalias("5", subABCD.m_C);
register_subalias("6", subABCD.m_D);
register_subalias("7", m_ENP);
// register_subalias("8", ); -. GND
register_subalias("9", m_LOADQ);
register_subalias("10", m_ENT);
register_subalias("11", sub.m_QD);
register_subalias("12", sub.m_QC);
register_subalias("13", sub.m_QB);
register_subalias("14", sub.m_QA);
register_subalias("15", sub.m_RC);
// register_subalias("16", ); -. VCC
}
};
NETLIB_NAMESPACE_DEVICES_END()
#endif /* NLD_9316_H_ */

View File

@ -1,37 +0,0 @@
// license:GPL-2.0+
// copyright-holders:Couriersud
/*
* nld_cmos.h
*
*/
#ifndef NLD_CMOS_H_
#define NLD_CMOS_H_
#include "nl_base.h"
#include "analog/nld_twoterm.h"
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_OBJECT(vdd_vss)
{
NETLIB_CONSTRUCTOR(vdd_vss)
{
enregister("VDD", m_vdd);
enregister("VSS", m_vss);
}
NETLIB_UPDATEI() {};
NETLIB_RESETI() {};
public:
ATTR_HOT inline nl_double vdd() { return INPANALOG(m_vdd); }
ATTR_HOT inline nl_double vss() { return INPANALOG(m_vss); }
analog_input_t m_vdd;
analog_input_t m_vss;
};
NETLIB_NAMESPACE_DEVICES_END()
#endif /* NLD_CMOS_H_ */

View File

@ -8,47 +8,102 @@
#include "nld_legacy.h"
#include "nl_setup.h"
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_RESET(nicRSFF)
namespace netlist
{
m_Q.initial(0);
m_QQ.initial(1);
}
NETLIB_UPDATE(nicRSFF)
{
if (!INPLOGIC(m_S))
namespace devices
{
OUTLOGIC(m_Q, 1, NLTIME_FROM_NS(20));
OUTLOGIC(m_QQ, 0, NLTIME_FROM_NS(20));
}
else if (!INPLOGIC(m_R))
{
OUTLOGIC(m_Q, 0, NLTIME_FROM_NS(20));
OUTLOGIC(m_QQ, 1, NLTIME_FROM_NS(20));
}
}
NETLIB_RESET(nicDelay)
{
//m_Q.initial(0);
}
NETLIB_UPDATE(nicDelay)
{
netlist_sig_t nval = INPLOGIC(m_I);
if (nval && !m_last)
NETLIB_OBJECT(nicRSFF)
{
// L_to_H
OUTLOGIC(m_Q, 1, NLTIME_FROM_NS(m_L_to_H.Value()));
}
else if (!nval && m_last)
{
// H_to_L
OUTLOGIC(m_Q, 0, NLTIME_FROM_NS(m_H_to_L.Value()));
}
m_last = nval;
}
NETLIB_CONSTRUCTOR(nicRSFF)
, m_S(*this, "S")
, m_R(*this, "R")
, m_Q(*this, "Q")
, m_QQ(*this, "QQ")
{
}
NETLIB_NAMESPACE_DEVICES_END()
NETLIB_RESETI();
NETLIB_UPDATEI();
protected:
logic_input_t m_S;
logic_input_t m_R;
logic_output_t m_Q;
logic_output_t m_QQ;
};
NETLIB_OBJECT(nicDelay)
{
NETLIB_CONSTRUCTOR(nicDelay)
, m_I(*this, "1")
, m_Q(*this, "2")
, m_L_to_H(*this, "L_TO_H", 10)
, m_H_to_L(*this, "H_TO_L", 10)
, m_last(0)
{
save(NLNAME(m_last));
}
//NETLIB_UPDATE_PARAMI();
NETLIB_RESETI();
NETLIB_UPDATEI();
protected:
logic_input_t m_I;
logic_output_t m_Q;
param_int_t m_L_to_H;
param_int_t m_H_to_L;
UINT8 m_last;
};
NETLIB_RESET(nicRSFF)
{
m_Q.initial(0);
m_QQ.initial(1);
}
NETLIB_UPDATE(nicRSFF)
{
if (!INPLOGIC(m_S))
{
OUTLOGIC(m_Q, 1, NLTIME_FROM_NS(20));
OUTLOGIC(m_QQ, 0, NLTIME_FROM_NS(20));
}
else if (!INPLOGIC(m_R))
{
OUTLOGIC(m_Q, 0, NLTIME_FROM_NS(20));
OUTLOGIC(m_QQ, 1, NLTIME_FROM_NS(20));
}
}
NETLIB_RESET(nicDelay)
{
//m_Q.initial(0);
}
NETLIB_UPDATE(nicDelay)
{
netlist_sig_t nval = INPLOGIC(m_I);
if (nval && !m_last)
{
// L_to_H
OUTLOGIC(m_Q, 1, NLTIME_FROM_NS(m_L_to_H.Value()));
}
else if (!nval && m_last)
{
// H_to_L
OUTLOGIC(m_Q, 0, NLTIME_FROM_NS(m_H_to_L.Value()));
}
m_last = nval;
}
NETLIB_DEVICE_IMPL(nicRSFF)
NETLIB_DEVICE_IMPL(nicDelay)
} //namespace devices
} // namespace netlist

View File

@ -13,74 +13,28 @@
#ifndef NLD_LEGACY_H_
#define NLD_LEGACY_H_
#include "nl_base.h"
NETLIB_NAMESPACE_DEVICES_START()
#include "nl_setup.h"
// ----------------------------------------------------------------------------------------
// Macros
// ----------------------------------------------------------------------------------------
#define NETDEV_RSFF(name) \
#define NETDEV_RSFF(name) \
NET_REGISTER_DEV(NETDEV_RSFF, name)
#define NETDEV_DELAY(name) \
#define NETDEV_DELAY(name) \
NET_REGISTER_DEV(NETDEV_DELAY, name)
// ----------------------------------------------------------------------------------------
// Devices ...
// ----------------------------------------------------------------------------------------
NETLIB_OBJECT(nicRSFF)
namespace netlist
{
NETLIB_CONSTRUCTOR(nicRSFF)
namespace devices
{
enregister("S", m_S);
enregister("R", m_R);
enregister("Q", m_Q);
enregister("QQ", m_QQ);
}
NETLIB_RESETI();
NETLIB_UPDATEI();
protected:
logic_input_t m_S;
logic_input_t m_R;
logic_output_t m_Q;
logic_output_t m_QQ;
};
NETLIB_OBJECT(nicDelay)
{
NETLIB_CONSTRUCTOR(nicDelay)
, m_L_to_H(*this, "L_TO_H", 10)
, m_H_to_L(*this, "H_TO_L", 10)
, m_last(0)
{
enregister("1", m_I);
enregister("2", m_Q);
save(NLNAME(m_last));
}
//NETLIB_UPDATE_PARAMI();
NETLIB_RESETI();
NETLIB_UPDATEI();
protected:
logic_input_t m_I;
logic_output_t m_Q;
param_int_t m_L_to_H;
param_int_t m_H_to_L;
UINT8 m_last;
};
NETLIB_NAMESPACE_DEVICES_END()
} //namespace devices
} // namespace netlist
#endif /* NLD_LEGACY_H_ */

View File

@ -5,49 +5,94 @@
*
*/
#include <memory>
#include "nl_base.h"
#include "plib/pstream.h"
#include "plib/pfmtlog.h"
#include "nld_log.h"
//#include "sound/wavwrite.h"
NETLIB_NAMESPACE_DEVICES_START()
//FIXME: what to do with save states?
NETLIB_UPDATE(log)
namespace netlist
{
/* use pstring::sprintf, it is a LOT faster */
m_strm->writeline(plib::pfmt("{1} {2}").e(netlist().time().as_double(),".9").e((nl_double) INPANALOG(m_I)));
}
namespace devices
{
NETLIB_NAME(log)::~NETLIB_NAME(log)()
{
m_strm->close();
}
NETLIB_OBJECT(log)
{
NETLIB_CONSTRUCTOR(log)
, m_I(*this, "I")
{
NETLIB_UPDATE(logD)
{
m_strm->writeline(plib::pfmt("{1} {2}").e(netlist().time().as_double(),".9").e((nl_double) (INPANALOG(m_I) - INPANALOG(m_I2))));
}
pstring filename = plib::pfmt("{1}.log")(this->name());
m_strm = plib::make_unique<plib::pofilestream>(filename);
}
// FIXME: Implement wav later, this must be clock triggered device where the input to be written
// is on a subdevice ..
#if 0
NETLIB_START(wav)
{
enregister("I", m_I);
NETLIB_UPDATEI()
{
/* use pstring::sprintf, it is a LOT faster */
m_strm->writeline(plib::pfmt("{1} {2}").e(netlist().time().as_double(),".9").e((nl_double) INPANALOG(m_I)));
}
pstring filename = "netlist_" + name() + ".wav";
m_file = wav_open(filename, sample_rate(), active_inputs()/2)
}
NETLIB_RESETI() { }
protected:
analog_input_t m_I;
std::unique_ptr<plib::pofilestream> m_strm;
};
NETLIB_UPDATE(wav)
{
fprintf(m_file, "%e %e\n", netlist().time().as_double(), INPANALOG(m_I));
}
NETLIB_OBJECT_DERIVED(logD, log)
{
NETLIB_CONSTRUCTOR_DERIVED(logD, log)
, m_I2(*this, "I2")
{
}
NETLIB_NAME(log)::~NETLIB_NAME(wav)()
{
fclose(m_file);
}
#endif
NETLIB_UPDATEI()
{
m_strm->writeline(plib::pfmt("{1} {2}").e(netlist().time().as_double(),".9").e((nl_double) (INPANALOG(m_I) - INPANALOG(m_I2))));
}
NETLIB_NAMESPACE_DEVICES_END()
NETLIB_RESETI() { }
analog_input_t m_I2;
};
#if 0
NETLIB_DEVICE(wav,
~NETLIB_NAME(wav)();
analog_input_t m_I;
private:
// FIXME: rewrite sound/wavwrite.h to be an object ...
void *m_file;
);
#endif
//FIXME: what to do with save states?
// FIXME: Implement wav later, this must be clock triggered device where the input to be written
// is on a subdevice ..
#if 0
NETLIB_START(wav)
{
enregister("I", m_I);
pstring filename = "netlist_" + name() + ".wav";
m_file = wav_open(filename, sample_rate(), active_inputs()/2)
}
NETLIB_UPDATE(wav)
{
fprintf(m_file, "%e %e\n", netlist().time().as_double(), INPANALOG(m_I));
}
NETLIB_NAME(log)::~NETLIB_NAME(wav)()
{
fclose(m_file);
}
#endif
NETLIB_DEVICE_IMPL(log)
NETLIB_DEVICE_IMPL(logD)
} //namespace devices
} // namespace netlist

View File

@ -18,10 +18,7 @@
#ifndef NLD_LOG_H_
#define NLD_LOG_H_
#include <memory>
#include "nl_base.h"
#include "plib/pstream.h"
#include "plib/pfmtlog.h"
#include "nl_setup.h"
#define LOG(name, cI) \
NET_REGISTER_DEV(??PG, name) \
@ -32,47 +29,4 @@
NET_CONNECT(name, I, cI) \
NET_CONNECT(name, I2, cI2)
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_OBJECT(log)
{
NETLIB_CONSTRUCTOR(log)
{
enregister("I", m_I);
pstring filename = plib::pfmt("{1}.log")(this->name());
m_strm = plib::pmake_unique<plib::pofilestream>(filename);
}
NETLIB_DESTRUCTOR(log);
NETLIB_UPDATEI();
NETLIB_RESETI() { }
protected:
analog_input_t m_I;
std::unique_ptr<plib::pofilestream> m_strm;
};
NETLIB_OBJECT_DERIVED(logD, log)
{
NETLIB_CONSTRUCTOR_DERIVED(logD, log)
{
enregister("I2", m_I2);
}
NETLIB_UPDATEI();
NETLIB_RESETI() { };
analog_input_t m_I2;
};
#if 0
NETLIB_DEVICE(wav,
~NETLIB_NAME(wav)();
analog_input_t m_I;
private:
// FIXME: rewrite sound/wavwrite.h to be an object ...
void *m_file;
);
#endif
NETLIB_NAMESPACE_DEVICES_END()
#endif /* NLD_LOG_H_ */

View File

@ -5,54 +5,111 @@
*
*/
#include <solver/nld_matrix_solver.h>
#include "nld_mm5837.h"
#include "nl_setup.h"
#include <solver/nld_matrix_solver.h>
#include "analog/nld_twoterm.h"
#define R_LOW (1000)
#define R_HIGH (1000)
#define R_LOW (1000.0)
#define R_HIGH (1000.0)
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_RESET(MM5837_dip)
namespace netlist
{
//m_V0.initial(0.0);
//m_RV.do_reset();
m_RV.set(NL_FCONST(1.0) / R_LOW, 0.0, 0.0);
m_shift = 0x1ffff;
m_is_timestep = m_RV.m_P.net().solver()->is_timestep();
}
NETLIB_UPDATE(MM5837_dip)
{
OUTLOGIC(m_Q, !m_Q.net().as_logic().new_Q(), m_inc );
/* shift register
*
* 17 bits, bits 17 & 14 feed back to input
*
*/
const UINT32 last_state = m_shift & 0x01;
/* shift */
m_shift = (m_shift >> 1) | (((m_shift & 0x01) ^ ((m_shift >> 3) & 0x01)) << 16);
const UINT32 state = m_shift & 0x01;
if (state != last_state)
namespace devices
{
const nl_double R = state ? R_HIGH : R_LOW;
const nl_double V = state ? INPANALOG(m_VDD) : INPANALOG(m_VSS);
// We only need to update the net first if this is a time stepping net
if (m_is_timestep)
m_RV.update_dev();
m_RV.set(NL_FCONST(1.0) / R, V, 0.0);
m_RV.m_P.schedule_after(NLTIME_FROM_NS(1));
NETLIB_OBJECT(MM5837_dip)
{
NETLIB_CONSTRUCTOR(MM5837_dip)
, m_RV(*this, "RV")
, m_VDD(*this, "1")
, m_VGG(*this, "2")
, m_VSS(*this, "4")
, m_V0(*this, "_Q")
/* clock */
, m_feedback(*this, "FB")
, m_Q(*this, "Q")
, m_inc(0, 1)
, m_is_timestep(false)
{
m_inc = netlist_time::from_hz(56000);
connect_late(m_feedback, m_Q);
/* output */
//register_term("_RV1", m_RV.m_P);
//register_term("_RV2", m_RV.m_N);
connect_late(m_RV.m_N, m_V0);
/* device */
register_subalias("3", m_RV.m_P);
save(NLNAME(m_shift));
}
NETLIB_RESETI();
NETLIB_UPDATEI();
protected:
NETLIB_SUB(twoterm) m_RV;
analog_input_t m_VDD;
analog_input_t m_VGG;
analog_input_t m_VSS;
/* output stage */
analog_output_t m_V0; /* could be gnd as well */
/* clock stage */
logic_input_t m_feedback;
logic_output_t m_Q;
netlist_time m_inc;
/* state */
UINT32 m_shift;
/* cache */
bool m_is_timestep;
};
NETLIB_RESET(MM5837_dip)
{
//m_V0.initial(0.0);
//m_RV.do_reset();
m_RV.set(NL_FCONST(1.0) / R_LOW, 0.0, 0.0);
m_shift = 0x1ffff;
m_is_timestep = m_RV.m_P.net().solver()->is_timestep();
}
}
NETLIB_UPDATE(MM5837_dip)
{
OUTLOGIC(m_Q, !m_Q.net().new_Q(), m_inc );
/* shift register
*
* 17 bits, bits 17 & 14 feed back to input
*
*/
const UINT32 last_state = m_shift & 0x01;
/* shift */
m_shift = (m_shift >> 1) | (((m_shift & 0x01) ^ ((m_shift >> 3) & 0x01)) << 16);
const UINT32 state = m_shift & 0x01;
NETLIB_NAMESPACE_DEVICES_END()
if (state != last_state)
{
const nl_double R = state ? R_HIGH : R_LOW;
const nl_double V = state ? INPANALOG(m_VDD) : INPANALOG(m_VSS);
// We only need to update the net first if this is a time stepping net
if (m_is_timestep)
m_RV.update_dev();
m_RV.set(NL_FCONST(1.0) / R, V, 0.0);
m_RV.m_P.schedule_after(NLTIME_FROM_NS(1));
}
}
NETLIB_DEVICE_IMPL(MM5837_dip)
} //namespace devices
} // namespace netlist

View File

@ -19,65 +19,9 @@
#ifndef NLD_MM5837_H_
#define NLD_MM5837_H_
#include "nl_base.h"
#include "analog/nld_twoterm.h"
#include "nl_setup.h"
#define MM5837_DIP(name) \
NET_REGISTER_DEV(MM5837_DIP, name)
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_OBJECT(MM5837_dip)
{
NETLIB_CONSTRUCTOR(MM5837_dip)
,m_RV(*this, "RV")
{
/* clock */
enregister("Q", m_Q);
enregister("FB", m_feedback);
m_inc = netlist_time::from_hz(56000);
connect_late(m_feedback, m_Q);
/* output */
enregister("_RV1", m_RV.m_P);
enregister("_RV2", m_RV.m_N);
enregister("_Q", m_V0);
connect_late(m_RV.m_N, m_V0);
/* device */
enregister("1", m_VDD);
enregister("2", m_VGG);
register_subalias("3", m_RV.m_P);
enregister("4", m_VSS);
save(NLNAME(m_shift));
}
NETLIB_RESETI();
NETLIB_UPDATEI();
protected:
NETLIB_SUB(twoterm) m_RV;
analog_input_t m_VDD;
analog_input_t m_VGG;
analog_input_t m_VSS;
/* output stage */
analog_output_t m_V0; /* could be gnd as well */
/* clock stage */
logic_input_t m_feedback;
logic_output_t m_Q;
netlist_time m_inc;
/* state */
UINT32 m_shift;
/* cache */
bool m_is_timestep;
};
NETLIB_NAMESPACE_DEVICES_END()
#endif /* NLD_MM5837_H_ */

View File

@ -5,76 +5,147 @@
*
*/
#include <solver/nld_solver.h>
#include "nld_ne555.h"
#include "nl_setup.h"
#include "analog/nld_twoterm.h"
#include <solver/nld_solver.h>
#define R_OFF (1E20)
#define R_ON (25) // Datasheet states a maximum discharge of 200mA, R = 5V / 0.2
NETLIB_NAMESPACE_DEVICES_START()
inline nl_double NETLIB_NAME(NE555)::clamp(const nl_double v, const nl_double a, const nl_double b)
namespace netlist
{
nl_double ret = v;
nl_double vcc = TERMANALOG(m_R1.m_P);
if (ret > vcc - a)
ret = vcc - a;
if (ret < b)
ret = b;
return ret;
}
NETLIB_RESET(NE555)
{
m_R1.do_reset();
m_R2.do_reset();
m_R3.do_reset();
m_RDIS.do_reset();
m_R1.set_R(5000);
m_R2.set_R(5000);
m_R3.set_R(5000);
m_RDIS.set_R(R_OFF);
m_last_out = true;
}
NETLIB_UPDATE(NE555)
{
// FIXME: assumes GND is connected to 0V.
nl_double vt = clamp(TERMANALOG(m_R2.m_P), 0.7, 1.4);
bool bthresh = (INPANALOG(m_THRES) > vt);
bool btrig = (INPANALOG(m_TRIG) > clamp(TERMANALOG(m_R2.m_N), 0.7, 1.4));
if (!btrig)
namespace devices
{
m_ff = true;
}
else if (bthresh)
NETLIB_OBJECT(NE555)
{
m_ff = false;
NETLIB_CONSTRUCTOR(NE555)
, m_R1(*this, "R1")
, m_R2(*this, "R2")
, m_R3(*this, "R3")
, m_RDIS(*this, "RDIS")
, m_RESET(*this, "RESET") // Pin 4
, m_THRES(*this, "THRESH") // Pin 6
, m_TRIG(*this, "TRIG") // Pin 2
, m_OUT(*this, "OUT") // Pin 3
, m_last_out(false)
, m_ff(false)
{
register_subalias("GND", m_R3.m_N); // Pin 1
register_subalias("CONT", m_R1.m_N); // Pin 5
register_subalias("DISCH", m_RDIS.m_P); // Pin 7
register_subalias("VCC", m_R1.m_P); // Pin 8
connect_late(m_R1.m_N, m_R2.m_P);
connect_late(m_R2.m_N, m_R3.m_P);
connect_late(m_RDIS.m_N, m_R3.m_N);
save(NLNAME(m_last_out));
save(NLNAME(m_ff));
}
NETLIB_UPDATEI();
NETLIB_RESETI();
protected:
NETLIB_SUB(R) m_R1;
NETLIB_SUB(R) m_R2;
NETLIB_SUB(R) m_R3;
NETLIB_SUB(R) m_RDIS;
logic_input_t m_RESET;
analog_input_t m_THRES;
analog_input_t m_TRIG;
analog_output_t m_OUT;
private:
bool m_last_out;
bool m_ff;
inline nl_double clamp(const nl_double v, const nl_double a, const nl_double b);
};
NETLIB_OBJECT_DERIVED(NE555_dip, NE555)
{
NETLIB_CONSTRUCTOR_DERIVED(NE555_dip, NE555)
{
register_subalias("1", m_R3.m_N); // Pin 1
register_subalias("2", m_TRIG); // Pin 2
register_subalias("3", m_OUT); // Pin 3
register_subalias("4", m_RESET); // Pin 4
register_subalias("5", m_R1.m_N); // Pin 5
register_subalias("6", m_THRES); // Pin 6
register_subalias("7", m_RDIS.m_P); // Pin 7
register_subalias("8", m_R1.m_P); // Pin 8
}
};
inline nl_double NETLIB_NAME(NE555)::clamp(const nl_double v, const nl_double a, const nl_double b)
{
nl_double ret = v;
nl_double vcc = TERMANALOG(m_R1.m_P);
if (ret > vcc - a)
ret = vcc - a;
if (ret < b)
ret = b;
return ret;
}
bool out = (!INPLOGIC(m_RESET) ? false : m_ff);
NETLIB_RESET(NE555)
{
m_R1.do_reset();
m_R2.do_reset();
m_R3.do_reset();
m_RDIS.do_reset();
if (m_last_out && !out)
{
m_RDIS.update_dev();
OUTANALOG(m_OUT, TERMANALOG(m_R3.m_N));
m_RDIS.set_R(R_ON);
}
else if (!m_last_out && out)
{
m_RDIS.update_dev();
// FIXME: Should be delayed by 100ns
OUTANALOG(m_OUT, TERMANALOG(m_R1.m_P));
m_R1.set_R(5000);
m_R2.set_R(5000);
m_R3.set_R(5000);
m_RDIS.set_R(R_OFF);
m_last_out = true;
}
m_last_out = out;
}
NETLIB_UPDATE(NE555)
{
// FIXME: assumes GND is connected to 0V.
NETLIB_NAMESPACE_DEVICES_END()
nl_double vt = clamp(TERMANALOG(m_R2.m_P), 0.7, 1.4);
bool bthresh = (INPANALOG(m_THRES) > vt);
bool btrig = (INPANALOG(m_TRIG) > clamp(TERMANALOG(m_R2.m_N), 0.7, 1.4));
if (!btrig)
{
m_ff = true;
}
else if (bthresh)
{
m_ff = false;
}
bool out = (!INPLOGIC(m_RESET) ? false : m_ff);
if (m_last_out && !out)
{
m_RDIS.update_dev();
OUTANALOG(m_OUT, TERMANALOG(m_R3.m_N));
m_RDIS.set_R(R_ON);
}
else if (!m_last_out && out)
{
m_RDIS.update_dev();
// FIXME: Should be delayed by 100ns
OUTANALOG(m_OUT, TERMANALOG(m_R1.m_P));
m_RDIS.set_R(R_OFF);
}
m_last_out = out;
}
NETLIB_DEVICE_IMPL(NE555)
NETLIB_DEVICE_IMPL(NE555_dip)
} //namespace devices
} // namespace netlist

View File

@ -19,82 +19,12 @@
#ifndef NLD_NE555_H_
#define NLD_NE555_H_
#include "nl_base.h"
#include "analog/nld_twoterm.h"
#include "nl_setup.h"
#define NE555(name) \
#define NE555(name) \
NET_REGISTER_DEV(NE555, name)
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_OBJECT(NE555)
{
NETLIB_CONSTRUCTOR(NE555)
, m_R1(*this, "R1")
, m_R2(*this, "R2")
, m_R3(*this, "R3")
, m_RDIS(*this, "RDIS")
, m_last_out(false)
, m_ff(false)
{
register_subalias("GND", m_R3.m_N); // Pin 1
enregister("TRIG", m_TRIG); // Pin 2
enregister("OUT", m_OUT); // Pin 3
enregister("RESET", m_RESET); // Pin 4
register_subalias("CONT", m_R1.m_N); // Pin 5
enregister("THRESH", m_THRES); // Pin 6
register_subalias("DISCH", m_RDIS.m_P); // Pin 7
register_subalias("VCC", m_R1.m_P); // Pin 8
connect_late(m_R1.m_N, m_R2.m_P);
connect_late(m_R2.m_N, m_R3.m_P);
connect_late(m_RDIS.m_N, m_R3.m_N);
save(NLNAME(m_last_out));
save(NLNAME(m_ff));
}
NETLIB_UPDATEI();
NETLIB_RESETI();
protected:
NETLIB_SUB(R) m_R1;
NETLIB_SUB(R) m_R2;
NETLIB_SUB(R) m_R3;
NETLIB_SUB(R) m_RDIS;
logic_input_t m_RESET;
analog_input_t m_THRES;
analog_input_t m_TRIG;
analog_output_t m_OUT;
private:
bool m_last_out;
bool m_ff;
inline nl_double clamp(const nl_double v, const nl_double a, const nl_double b);
};
#define NE555_DIP(name) \
NET_REGISTER_DEV(NE555_DIP, name)
NETLIB_OBJECT_DERIVED(NE555_dip, NE555)
{
NETLIB_CONSTRUCTOR_DERIVED(NE555_dip, NE555)
{
register_subalias("1", m_R3.m_N); // Pin 1
register_subalias("2", m_TRIG); // Pin 2
register_subalias("3", m_OUT); // Pin 3
register_subalias("4", m_RESET); // Pin 4
register_subalias("5", m_R1.m_N); // Pin 5
register_subalias("6", m_THRES); // Pin 6
register_subalias("7", m_RDIS.m_P); // Pin 7
register_subalias("8", m_R1.m_P); // Pin 8
}
};
NETLIB_NAMESPACE_DEVICES_END()
#endif /* NLD_NE555_H_ */

View File

@ -6,16 +6,47 @@
*/
#include "nld_r2r_dac.h"
#include "analog/nld_twoterm.h"
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_UPDATE_PARAM(r2r_dac)
namespace netlist
{
update_dev();
namespace devices
{
nl_double V = m_VIN.Value() / (nl_double) (1 << m_num.Value()) * (nl_double) m_val.Value();
NETLIB_OBJECT_DERIVED(r2r_dac, twoterm)
{
NETLIB_CONSTRUCTOR_DERIVED(r2r_dac, twoterm)
, m_VIN(*this, "VIN", 1.0)
, m_R(*this, "R", 1.0)
, m_num(*this, "N", 1)
, m_val(*this, "VAL", 1)
{
register_subalias("VOUT", m_P);
register_subalias("VGND", m_N);
}
this->set(1.0 / m_R.Value(), V, 0.0);
}
NETLIB_UPDATE_PARAMI();
//NETLIB_RESETI();
//NETLIB_UPDATEI();
NETLIB_NAMESPACE_DEVICES_END()
protected:
param_double_t m_VIN;
param_double_t m_R;
param_int_t m_num;
param_int_t m_val;
};
NETLIB_UPDATE_PARAM(r2r_dac)
{
update_dev();
nl_double V = m_VIN.Value() / (nl_double) (1 << m_num.Value()) * (nl_double) m_val.Value();
this->set(1.0 / m_R.Value(), V, 0.0);
}
NETLIB_DEVICE_IMPL(r2r_dac)
} //namespace devices
} // namespace netlist

View File

@ -46,41 +46,12 @@
#ifndef NLD_R2R_DAC_H_
#define NLD_R2R_DAC_H_
#include "nl_base.h"
#include "analog/nld_twoterm.h"
#include "nl_setup.h"
#define R2R_DAC(name, p_VIN, p_R, p_N) \
NET_REGISTER_DEV(R2R_DAC, name) \
NETDEV_PARAMI(name, VIN, p_VIN) \
NETDEV_PARAMI(name, R, p_R) \
#define R2R_DAC(name, p_VIN, p_R, p_N) \
NET_REGISTER_DEV(R2R_DAC, name) \
NETDEV_PARAMI(name, VIN, p_VIN) \
NETDEV_PARAMI(name, R, p_R) \
NETDEV_PARAMI(name, N, p_N)
NETLIB_NAMESPACE_DEVICES_START()
NETLIB_OBJECT_DERIVED(r2r_dac, twoterm)
{
NETLIB_CONSTRUCTOR_DERIVED(r2r_dac, twoterm)
, m_VIN(*this, "VIN", 1.0)
, m_R(*this, "R", 1.0)
, m_num(*this, "N", 1)
, m_val(*this, "VAL", 1)
{
enregister("VOUT", m_P);
enregister("VGND", m_N);
}
NETLIB_UPDATE_PARAMI();
//NETLIB_RESETI();
//NETLIB_UPDATEI();
protected:
param_double_t m_VIN;
param_double_t m_R;
param_int_t m_num;
param_int_t m_val;
};
NETLIB_NAMESPACE_DEVICES_END()
#endif /* NLD_R2R_DAC_H_ */

View File

@ -7,207 +7,208 @@
#include <solver/nld_solver.h>
#include <solver/nld_matrix_solver.h>
#include "nld_system.h"
#include "nlid_system.h"
NETLIB_NAMESPACE_DEVICES_START()
// ----------------------------------------------------------------------------------------
// netlistparams
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// clock
// ----------------------------------------------------------------------------------------
NETLIB_UPDATE_PARAM(clock)
namespace netlist
{
m_inc = netlist_time::from_hz(m_freq.Value()*2);
}
NETLIB_UPDATE(clock)
{
OUTLOGIC(m_Q, !m_Q.net().as_logic().new_Q(), m_inc );
}
// ----------------------------------------------------------------------------------------
// extclock
// ----------------------------------------------------------------------------------------
NETLIB_RESET(extclock)
{
m_cnt = 0;
m_off = netlist_time::from_double(m_offset.Value());
//m_Q.initial(0);
}
NETLIB_UPDATE(extclock)
{
#if 0
if (m_off == netlist_time::zero)
namespace devices
{
OUTLOGIC(m_Q, (m_cnt & 1) ^ 1, m_inc[m_cnt]);
// ----------------------------------------------------------------------------------------
// netlistparams
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// clock
// ----------------------------------------------------------------------------------------
NETLIB_UPDATE_PARAM(clock)
{
m_inc = netlist_time::from_hz(m_freq.Value()*2);
}
NETLIB_UPDATE(clock)
{
OUTLOGIC(m_Q, !m_Q.net().new_Q(), m_inc );
}
// ----------------------------------------------------------------------------------------
// extclock
// ----------------------------------------------------------------------------------------
NETLIB_RESET(extclock)
{
m_cnt = 0;
m_off = netlist_time(m_offset.Value());
//m_Q.initial(0);
}
NETLIB_UPDATE(extclock)
{
OUTLOGIC(m_Q, (m_cnt & 1) ^ 1, m_inc[m_cnt] + m_off);
m_cnt = (m_cnt + 1) % m_size;
m_off = netlist_time::zero();
}
else
// ----------------------------------------------------------------------------------------
// logic_input
// ----------------------------------------------------------------------------------------
NETLIB_RESET(logic_input)
{
OUTLOGIC(m_Q, (m_cnt & 1) ^ 1, m_inc[0] + m_off);
m_cnt = 1;
m_off = netlist_time::zero;
m_Q.initial(0);
}
#else
OUTLOGIC(m_Q, (m_cnt & 1) ^ 1, m_inc[m_cnt] + m_off);
m_cnt = (m_cnt + 1) % m_size;
m_off = netlist_time::zero;
#endif
}
// ----------------------------------------------------------------------------------------
// logic_input
// ----------------------------------------------------------------------------------------
NETLIB_RESET(logic_input)
{
//FIXME: causes issues in breakout (lots of pings after first player 1 start)
//m_Q.initial(m_IN.Value() & 1);
}
NETLIB_UPDATE(logic_input)
{
OUTLOGIC(m_Q, m_IN.Value() & 1, netlist_time::from_nsec(1));
}
NETLIB_UPDATE_PARAM(logic_input)
{
}
// ----------------------------------------------------------------------------------------
// analog_input
// ----------------------------------------------------------------------------------------
NETLIB_RESET(analog_input)
{
// m_Q.initial(m_IN.Value() * 0.999);
}
NETLIB_UPDATE(analog_input)
{
OUTANALOG(m_Q, m_IN.Value());
}
NETLIB_UPDATE_PARAM(analog_input)
{
}
// ----------------------------------------------------------------------------------------
// nld_d_to_a_proxy
// ----------------------------------------------------------------------------------------
void nld_d_to_a_proxy::reset()
{
//m_Q.initial(0.0);
m_last_state = -1;
m_RV.do_reset();
m_is_timestep = m_RV.m_P.net().solver()->has_timestep_devices();
m_RV.set(NL_FCONST(1.0) / logic_family().m_R_low, logic_family().m_low_V, 0.0);
}
NETLIB_UPDATE(d_to_a_proxy)
{
const int state = INPLOGIC(m_I);
if (state != m_last_state)
NETLIB_UPDATE(logic_input)
{
m_last_state = state;
const nl_double R = state ? logic_family().m_R_high : logic_family().m_R_low;
const nl_double V = state ? logic_family().m_high_V : logic_family().m_low_V;
// We only need to update the net first if this is a time stepping net
if (m_is_timestep)
{
m_RV.update_dev();
}
m_RV.set(NL_FCONST(1.0) / R, V, 0.0);
m_RV.m_P.schedule_after(NLTIME_FROM_NS(1));
OUTLOGIC(m_Q, m_IN.Value() & 1, netlist_time::from_nsec(1));
}
}
// -----------------------------------------------------------------------------
// nld_res_sw
// -----------------------------------------------------------------------------
NETLIB_UPDATE(res_sw)
{
const int state = INPLOGIC(m_I);
if (state != m_last_state)
NETLIB_UPDATE_PARAM(logic_input)
{
m_last_state = state;
const nl_double R = state ? m_RON.Value() : m_ROFF.Value();
}
// We only need to update the net first if this is a time stepping net
if (0) // m_R->m_P.net().as_analog().solver()->is_timestep())
// ----------------------------------------------------------------------------------------
// analog_input
// ----------------------------------------------------------------------------------------
NETLIB_RESET(analog_input)
{
m_Q.initial(0.0);
}
NETLIB_UPDATE(analog_input)
{
OUTANALOG(m_Q, m_IN.Value());
}
NETLIB_UPDATE_PARAM(analog_input)
{
}
// ----------------------------------------------------------------------------------------
// nld_d_to_a_proxy
// ----------------------------------------------------------------------------------------
void nld_d_to_a_proxy::reset()
{
//m_Q.initial(0.0);
m_last_state = -1;
m_RV.do_reset();
m_is_timestep = m_RV.m_P.net().solver()->has_timestep_devices();
m_RV.set(NL_FCONST(1.0) / logic_family().m_R_low, logic_family().m_low_V, 0.0);
}
NETLIB_UPDATE(d_to_a_proxy)
{
const int state = INPLOGIC(m_I);
if (state != m_last_state)
{
m_R.update_dev();
m_R.set_R(R);
m_R.m_P.schedule_after(NLTIME_FROM_NS(1));
}
else
{
m_R.set_R(R);
m_R.m_P.schedule_after(NLTIME_FROM_NS(1));
//m_R->update_dev();
m_last_state = state;
const nl_double R = state ? logic_family().m_R_high : logic_family().m_R_low;
const nl_double V = state ? logic_family().m_high_V : logic_family().m_low_V;
// We only need to update the net first if this is a time stepping net
if (m_is_timestep)
{
m_RV.update_dev();
}
m_RV.set(NL_FCONST(1.0) / R, V, 0.0);
m_RV.m_P.schedule_after(NLTIME_FROM_NS(1));
}
}
}
/* -----------------------------------------------------------------------------
* nld_function
* ----------------------------------------------------------------------------- */
NETLIB_RESET(function)
{
//m_Q.initial(0.0);
}
// -----------------------------------------------------------------------------
// nld_res_sw
// -----------------------------------------------------------------------------
NETLIB_UPDATE(function)
{
//nl_double val = INPANALOG(m_I[0]) * INPANALOG(m_I[1]) * 0.2;
//OUTANALOG(m_Q, val);
nl_double stack[20];
unsigned ptr = 0;
unsigned e = m_precompiled.size();
for (unsigned i = 0; i<e; i++)
NETLIB_UPDATE(res_sw)
{
rpn_inst &rc = m_precompiled[i];
switch (rc.m_cmd)
const int state = INPLOGIC(m_I);
if (state != m_last_state)
{
case ADD:
ptr--;
stack[ptr-1] = stack[ptr] + stack[ptr-1];
break;
case MULT:
ptr--;
stack[ptr-1] = stack[ptr] * stack[ptr-1];
break;
case SUB:
ptr--;
stack[ptr-1] = stack[ptr-1] - stack[ptr];
break;
case DIV:
ptr--;
stack[ptr-1] = stack[ptr-1] / stack[ptr];
break;
case PUSH_INPUT:
stack[ptr++] = INPANALOG(m_I[(int) rc.m_param]);
break;
case PUSH_CONST:
stack[ptr++] = rc.m_param;
break;
m_last_state = state;
const nl_double R = state ? m_RON.Value() : m_ROFF.Value();
// We only need to update the net first if this is a time stepping net
if (0) // m_R->m_P.net().as_analog().solver()->is_timestep())
{
m_R.update_dev();
m_R.set_R(R);
m_R.m_P.schedule_after(NLTIME_FROM_NS(1));
}
else
{
m_R.set_R(R);
m_R.m_P.schedule_after(NLTIME_FROM_NS(1));
//m_R->update_dev();
}
}
}
OUTANALOG(m_Q, stack[ptr-1]);
}
/* -----------------------------------------------------------------------------
* nld_function
* ----------------------------------------------------------------------------- */
NETLIB_RESET(function)
{
//m_Q.initial(0.0);
}
NETLIB_UPDATE(function)
{
//nl_double val = INPANALOG(m_I[0]) * INPANALOG(m_I[1]) * 0.2;
//OUTANALOG(m_Q, val);
nl_double stack[20];
unsigned ptr = 0;
unsigned e = m_precompiled.size();
for (unsigned i = 0; i<e; i++)
{
rpn_inst &rc = m_precompiled[i];
switch (rc.m_cmd)
{
case ADD:
ptr--;
stack[ptr-1] = stack[ptr] + stack[ptr-1];
break;
case MULT:
ptr--;
stack[ptr-1] = stack[ptr] * stack[ptr-1];
break;
case SUB:
ptr--;
stack[ptr-1] = stack[ptr-1] - stack[ptr];
break;
case DIV:
ptr--;
stack[ptr-1] = stack[ptr-1] / stack[ptr];
break;
case PUSH_INPUT:
stack[ptr++] = INPANALOG(m_I[(int) rc.m_param]);
break;
case PUSH_CONST:
stack[ptr++] = rc.m_param;
break;
}
}
OUTANALOG(m_Q, stack[ptr-1]);
}
NETLIB_NAMESPACE_DEVICES_END()
NETLIB_DEVICE_IMPL(dummy_input)
NETLIB_DEVICE_IMPL(frontier)
NETLIB_DEVICE_IMPL(function)
NETLIB_DEVICE_IMPL(logic_input)
NETLIB_DEVICE_IMPL(analog_input)
NETLIB_DEVICE_IMPL(clock)
NETLIB_DEVICE_IMPL(extclock)
NETLIB_DEVICE_IMPL(res_sw)
NETLIB_DEVICE_IMPL(mainclock)
NETLIB_DEVICE_IMPL(gnd)
NETLIB_DEVICE_IMPL(netlistparams)
} //namespace devices
} // namespace netlist

View File

@ -10,637 +10,66 @@
#define NLD_SYSTEM_H_
#include "nl_setup.h"
#include "nl_base.h"
#include "nl_factory.h"
#include "analog/nld_twoterm.h"
// -----------------------------------------------------------------------------
// Macros
// -----------------------------------------------------------------------------
#define TTL_INPUT(name, v) \
NET_REGISTER_DEV(TTL_INPUT, name) \
#define TTL_INPUT(name, v) \
NET_REGISTER_DEV(TTL_INPUT, name) \
PARAM(name.IN, v)
#define LOGIC_INPUT(name, v, family) \
NET_REGISTER_DEV(LOGIC_INPUT, name) \
PARAM(name.IN, v) \
#define LOGIC_INPUT(name, v, family) \
NET_REGISTER_DEV(LOGIC_INPUT, name) \
PARAM(name.IN, v) \
PARAM(name.FAMILY, family)
#define ANALOG_INPUT(name, v) \
NET_REGISTER_DEV(ANALOG_INPUT, name) \
#define ANALOG_INPUT(name, v) \
NET_REGISTER_DEV(ANALOG_INPUT, name) \
PARAM(name.IN, v)
#define MAINCLOCK(name, freq) \
NET_REGISTER_DEV(MAINCLOCK, name) \
#define MAINCLOCK(name, freq) \
NET_REGISTER_DEV(MAINCLOCK, name) \
PARAM(name.FREQ, freq)
#define CLOCK(name, freq) \
NET_REGISTER_DEV(CLOCK, name) \
#define CLOCK(name, freq) \
NET_REGISTER_DEV(CLOCK, name) \
PARAM(name.FREQ, freq)
#define EXTCLOCK(name, freq, pattern) \
NET_REGISTER_DEV(EXTCLOCK, name) \
PARAM(name.FREQ, freq) \
#define EXTCLOCK(name, freq, pattern) \
NET_REGISTER_DEV(EXTCLOCK, name) \
PARAM(name.FREQ, freq) \
PARAM(name.PATTERN, pattern)
#define GNDA() \
#define GNDA() \
NET_REGISTER_DEV(GNDA, GND)
#define DUMMY_INPUT(name) \
#define DUMMY_INPUT(name) \
NET_REGISTER_DEV(DUMMY_INPUT, name)
//FIXME: Usage discouraged, use OPTIMIZE_FRONTIER instead
#define FRONTIER_DEV(name, cIN, cG, cOUT) \
NET_REGISTER_DEV(FRONTIER_DEV, name) \
NET_C(cIN, name.I) \
NET_C(cG, name.G) \
#define FRONTIER_DEV(name, cIN, cG, cOUT) \
NET_REGISTER_DEV(FRONTIER_DEV, name) \
NET_C(cIN, name.I) \
NET_C(cG, name.G) \
NET_C(cOUT, name.Q)
#define OPTIMIZE_FRONTIER(attach, r_in, r_out) \
#define OPTIMIZE_FRONTIER(attach, r_in, r_out) \
setup.register_frontier(# attach, r_in, r_out);
#define RES_SWITCH(name, cIN, cP1, cP2) \
NET_REGISTER_DEV(RES_SWITCH, name) \
NET_C(cIN, name.I) \
NET_C(cP1, name.1) \
#define RES_SWITCH(name, cIN, cP1, cP2) \
NET_REGISTER_DEV(RES_SWITCH, name) \
NET_C(cIN, name.I) \
NET_C(cP1, name.1) \
NET_C(cP2, name.2)
/* Default device to hold netlist parameters */
#define PARAMETERS(name) \
#define PARAMETERS(name) \
NET_REGISTER_DEV(PARAMETERS, name)
#define AFUNC(name, p_N, p_F) \
NET_REGISTER_DEV(AFUNC, name) \
PARAM(name.N, p_N) \
NET_REGISTER_DEV(AFUNC, name) \
PARAM(name.N, p_N) \
PARAM(name.FUNC, p_F)
NETLIB_NAMESPACE_DEVICES_START()
// -----------------------------------------------------------------------------
// netlistparams
// -----------------------------------------------------------------------------
NETLIB_OBJECT(netlistparams)
{
NETLIB_CONSTRUCTOR(netlistparams)
, m_use_deactivate(*this, "USE_DEACTIVATE", 0)
{
}
NETLIB_UPDATEI() { }
//NETLIB_RESETI() { }
//NETLIB_UPDATE_PARAMI() { }
public:
param_logic_t m_use_deactivate;
};
// -----------------------------------------------------------------------------
// mainclock
// -----------------------------------------------------------------------------
NETLIB_OBJECT(mainclock)
{
NETLIB_CONSTRUCTOR(mainclock)
, m_freq(*this, "FREQ", 7159000.0 * 5)
{
enregister("Q", m_Q);
m_inc = netlist_time::from_hz(m_freq.Value()*2);
}
NETLIB_RESETI()
{
m_Q.net().set_time(netlist_time::zero);
}
NETLIB_UPDATE_PARAMI()
{
m_inc = netlist_time::from_hz(m_freq.Value()*2);
}
NETLIB_UPDATEI()
{
logic_net_t &net = m_Q.net().as_logic();
// this is only called during setup ...
net.toggle_new_Q();
net.set_time(netlist().time() + m_inc);
}
public:
logic_output_t m_Q;
param_double_t m_freq;
netlist_time m_inc;
ATTR_HOT inline static void mc_update(logic_net_t &net);
};
// -----------------------------------------------------------------------------
// clock
// -----------------------------------------------------------------------------
NETLIB_OBJECT(clock)
{
NETLIB_CONSTRUCTOR(clock)
, m_freq(*this, "FREQ", 7159000.0 * 5.0)
{
enregister("Q", m_Q);
enregister("FB", m_feedback);
m_inc = netlist_time::from_hz(m_freq.Value()*2);
connect_late(m_feedback, m_Q);
}
NETLIB_UPDATEI();
//NETLIB_RESETI();
NETLIB_UPDATE_PARAMI();
protected:
logic_input_t m_feedback;
logic_output_t m_Q;
param_double_t m_freq;
netlist_time m_inc;
};
// -----------------------------------------------------------------------------
// extclock
// -----------------------------------------------------------------------------
NETLIB_OBJECT(extclock)
{
NETLIB_CONSTRUCTOR(extclock)
, m_freq(*this, "FREQ", 7159000.0 * 5.0)
, m_pattern(*this, "PATTERN", "1,1")
, m_offset(*this, "OFFSET", 0.0)
{
enregister("Q", m_Q);
enregister("FB", m_feedback);
m_inc[0] = netlist_time::from_hz(m_freq.Value()*2);
connect_late(m_feedback, m_Q);
{
netlist_time base = netlist_time::from_hz(m_freq.Value()*2);
plib::pstring_vector_t pat(m_pattern.Value(),",");
m_off = netlist_time::from_double(m_offset.Value());
int pati[256];
m_size = pat.size();
int total = 0;
for (int i=0; i<m_size; i++)
{
pati[i] = pat[i].as_long();
total += pati[i];
}
netlist_time ttotal = netlist_time::zero;
for (int i=0; i<m_size - 1; i++)
{
m_inc[i] = base * pati[i];
ttotal += m_inc[i];
}
m_inc[m_size - 1] = base * total - ttotal;
}
save(NLNAME(m_cnt));
save(NLNAME(m_off));
}
NETLIB_UPDATEI();
NETLIB_RESETI();
//NETLIB_UPDATE_PARAMI();
protected:
param_double_t m_freq;
param_str_t m_pattern;
param_double_t m_offset;
logic_input_t m_feedback;
logic_output_t m_Q;
UINT32 m_cnt;
UINT32 m_size;
netlist_time m_inc[32];
netlist_time m_off;
};
// -----------------------------------------------------------------------------
// Special support devices ...
// -----------------------------------------------------------------------------
NETLIB_OBJECT(logic_input)
{
NETLIB_CONSTRUCTOR(logic_input)
, m_IN(*this, "IN", 0)
/* make sure we get the family first */
, m_FAMILY(*this, "FAMILY", "FAMILY(TYPE=TTL)")
{
set_logic_family(netlist().setup().family_from_model(m_FAMILY.Value()));
enregister("Q", m_Q);
}
NETLIB_UPDATE_AFTER_PARAM_CHANGE()
NETLIB_UPDATEI();
NETLIB_RESETI();
NETLIB_UPDATE_PARAMI();
protected:
logic_output_t m_Q;
param_logic_t m_IN;
param_model_t m_FAMILY;
};
NETLIB_OBJECT(analog_input)
{
NETLIB_CONSTRUCTOR(analog_input)
, m_IN(*this, "IN", 0.0)
{
enregister("Q", m_Q);
}
NETLIB_UPDATE_AFTER_PARAM_CHANGE()
NETLIB_UPDATEI();
NETLIB_RESETI();
NETLIB_UPDATE_PARAMI();
protected:
analog_output_t m_Q;
param_double_t m_IN;
};
// -----------------------------------------------------------------------------
// nld_gnd
// -----------------------------------------------------------------------------
NETLIB_OBJECT(gnd)
{
NETLIB_CONSTRUCTOR(gnd)
{
enregister("Q", m_Q);
}
NETLIB_UPDATEI()
{
OUTANALOG(m_Q, 0.0);
}
NETLIB_RESETI() { }
protected:
analog_output_t m_Q;
};
// -----------------------------------------------------------------------------
// nld_dummy_input
// -----------------------------------------------------------------------------
NETLIB_OBJECT_DERIVED(dummy_input, base_dummy)
{
public:
NETLIB_CONSTRUCTOR_DERIVED(dummy_input, base_dummy)
{
enregister("I", m_I);
}
protected:
NETLIB_RESETI() { }
NETLIB_UPDATEI() { }
private:
analog_input_t m_I;
};
// -----------------------------------------------------------------------------
// nld_frontier
// -----------------------------------------------------------------------------
NETLIB_OBJECT_DERIVED(frontier, base_dummy)
{
public:
NETLIB_CONSTRUCTOR_DERIVED(frontier, base_dummy)
, m_RIN(netlist(), "m_RIN")
, m_ROUT(netlist(), "m_ROUT")
, m_p_RIN(*this, "RIN", 1.0e6)
, m_p_ROUT(*this, "ROUT", 50.0)
{
enregister("_I", m_I);
enregister("I",m_RIN.m_P);
enregister("G",m_RIN.m_N);
connect_late(m_I, m_RIN.m_P);
enregister("_Q", m_Q);
enregister("_OP",m_ROUT.m_P);
enregister("Q",m_ROUT.m_N);
connect_late(m_Q, m_ROUT.m_P);
}
NETLIB_RESETI()
{
m_RIN.set(1.0 / m_p_RIN.Value(),0,0);
m_ROUT.set(1.0 / m_p_ROUT.Value(),0,0);
}
NETLIB_UPDATEI()
{
OUTANALOG(m_Q, INPANALOG(m_I));
}
private:
NETLIB_NAME(twoterm) m_RIN;
NETLIB_NAME(twoterm) m_ROUT;
analog_input_t m_I;
analog_output_t m_Q;
param_double_t m_p_RIN;
param_double_t m_p_ROUT;
};
/* -----------------------------------------------------------------------------
* nld_function
*
* FIXME: Currently a proof of concept to get congo bongo working
* ----------------------------------------------------------------------------- */
NETLIB_OBJECT(function)
{
NETLIB_CONSTRUCTOR(function)
, m_N(*this, "N", 2)
, m_func(*this, "FUNC", "")
{
enregister("Q", m_Q);
for (int i=0; i < m_N; i++)
enregister(plib::pfmt("A{1}")(i), m_I[i]);
plib::pstring_vector_t cmds(m_func.Value(), " ");
m_precompiled.clear();
for (std::size_t i=0; i < cmds.size(); i++)
{
pstring cmd = cmds[i];
rpn_inst rc;
if (cmd == "+")
rc.m_cmd = ADD;
else if (cmd == "-")
rc.m_cmd = SUB;
else if (cmd == "*")
rc.m_cmd = MULT;
else if (cmd == "/")
rc.m_cmd = DIV;
else if (cmd.startsWith("A"))
{
rc.m_cmd = PUSH_INPUT;
rc.m_param = cmd.substr(1).as_long();
}
else
{
bool err = false;
rc.m_cmd = PUSH_CONST;
rc.m_param = cmd.as_double(&err);
if (err)
netlist().log().fatal("nld_function: unknown/misformatted token <{1}> in <{2}>", cmd, m_func.Value());
}
m_precompiled.push_back(rc);
}
}
protected:
NETLIB_RESETI();
NETLIB_UPDATEI();
private:
enum rpn_cmd
{
ADD,
MULT,
SUB,
DIV,
PUSH_CONST,
PUSH_INPUT
};
struct rpn_inst
{
rpn_inst() : m_cmd(ADD), m_param(0.0) { }
rpn_cmd m_cmd;
nl_double m_param;
};
param_int_t m_N;
param_str_t m_func;
analog_output_t m_Q;
analog_input_t m_I[10];
plib::pvector_t<rpn_inst> m_precompiled;
};
// -----------------------------------------------------------------------------
// nld_res_sw
// -----------------------------------------------------------------------------
NETLIB_OBJECT(res_sw)
{
public:
NETLIB_CONSTRUCTOR(res_sw)
, m_R(*this, "R")
, m_RON(*this, "RON", 1.0)
, m_ROFF(*this, "ROFF", 1.0E20)
, m_last_state(0)
{
enregister("I", m_I);
register_subalias("1", m_R.m_P);
register_subalias("2", m_R.m_N);
save(NLNAME(m_last_state));
}
NETLIB_SUB(R) m_R;
logic_input_t m_I;
param_double_t m_RON;
param_double_t m_ROFF;
NETLIB_RESETI()
{
m_last_state = 0;
m_R.set_R(m_ROFF.Value());
}
//NETLIB_UPDATE_PARAMI();
NETLIB_UPDATEI();
private:
UINT8 m_last_state;
};
// -----------------------------------------------------------------------------
// nld_base_proxy
// -----------------------------------------------------------------------------
NETLIB_OBJECT(base_proxy)
{
public:
nld_base_proxy(netlist_t &anetlist, const pstring &name, logic_t *inout_proxied, core_terminal_t *proxy_inout)
: device_t(anetlist, name)
{
m_logic_family = inout_proxied->logic_family();
m_term_proxied = inout_proxied;
m_proxy_term = proxy_inout;
}
virtual ~nld_base_proxy() {}
logic_t &term_proxied() const { return *m_term_proxied; }
core_terminal_t &proxy_term() const { return *m_proxy_term; }
protected:
virtual const logic_family_desc_t &logic_family() const
{
return *m_logic_family;
}
private:
const logic_family_desc_t *m_logic_family;
logic_t *m_term_proxied;
core_terminal_t *m_proxy_term;
};
// -----------------------------------------------------------------------------
// nld_a_to_d_proxy
// -----------------------------------------------------------------------------
NETLIB_OBJECT_DERIVED(a_to_d_proxy, base_proxy)
{
public:
nld_a_to_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *in_proxied)
: nld_base_proxy(anetlist, name, in_proxied, &m_I)
{
enregister("I", m_I);
enregister("Q", m_Q);
}
virtual ~nld_a_to_d_proxy() {}
analog_input_t m_I;
logic_output_t m_Q;
protected:
NETLIB_RESETI() { }
NETLIB_UPDATEI()
{
if (m_I.Q_Analog() > logic_family().m_high_thresh_V)
OUTLOGIC(m_Q, 1, NLTIME_FROM_NS(1));
else if (m_I.Q_Analog() < logic_family().m_low_thresh_V)
OUTLOGIC(m_Q, 0, NLTIME_FROM_NS(1));
else
{
// do nothing
}
}
private:
};
// -----------------------------------------------------------------------------
// nld_base_d_to_a_proxy
// -----------------------------------------------------------------------------
NETLIB_OBJECT_DERIVED(base_d_to_a_proxy, base_proxy)
{
public:
virtual ~nld_base_d_to_a_proxy() {}
virtual logic_input_t &in() { return m_I; }
protected:
nld_base_d_to_a_proxy(netlist_t &anetlist, const pstring &name, logic_output_t *out_proxied, core_terminal_t &proxy_out)
: nld_base_proxy(anetlist, name, out_proxied, &proxy_out)
{
enregister("I", m_I);
}
logic_input_t m_I;
private:
};
NETLIB_OBJECT_DERIVED(d_to_a_proxy, base_d_to_a_proxy)
{
public:
nld_d_to_a_proxy(netlist_t &anetlist, const pstring &name, logic_output_t *out_proxied)
: nld_base_d_to_a_proxy(anetlist, name, out_proxied, m_RV.m_P)
, m_RV(*this, "RV")
, m_last_state(-1)
, m_is_timestep(false)
{
//register_sub(m_RV);
enregister("1", m_RV.m_P);
enregister("2", m_RV.m_N);
enregister("_Q", m_Q);
register_subalias("Q", m_RV.m_P);
connect_late(m_RV.m_N, m_Q);
save(NLNAME(m_last_state));
}
virtual ~nld_d_to_a_proxy() {}
protected:
NETLIB_RESETI();
NETLIB_UPDATEI();
private:
analog_output_t m_Q;
NETLIB_SUB(twoterm) m_RV;
int m_last_state;
bool m_is_timestep;
};
class factory_lib_entry_t : public base_factory_t
{
P_PREVENT_COPYING(factory_lib_entry_t)
public:
ATTR_COLD factory_lib_entry_t(setup_t &setup, const pstring &name, const pstring &classname,
const pstring &def_param)
: base_factory_t(name, classname, def_param), m_setup(setup) { }
class wrapper : public device_t
{
public:
wrapper(const pstring &devname, netlist_t &anetlist, const pstring &name)
: device_t(anetlist, name), m_devname(devname)
{
anetlist.setup().namespace_push(name);
anetlist.setup().include(m_devname);
anetlist.setup().namespace_pop();
}
protected:
NETLIB_RESETI() { }
NETLIB_UPDATEI() { }
pstring m_devname;
};
plib::powned_ptr<device_t> Create(netlist_t &anetlist, const pstring &name) override
{
return plib::powned_ptr<device_t>::Create<wrapper>(this->name(), anetlist, name);
}
private:
setup_t &m_setup;
};
NETLIB_NAMESPACE_DEVICES_END()
#endif /* NLD_SYSTEM_H_ */

View File

@ -8,39 +8,60 @@
#include "nld_truthtable.h"
#include "plib/plists.h"
NETLIB_NAMESPACE_DEVICES_START()
unsigned truthtable_desc_t::count_bits(UINT32 v)
namespace netlist
{
unsigned ret = 0;
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)
{ }
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;
};
static const uint64_t all_set = ~((uint64_t) 0);
unsigned truthtable_desc_t::count_bits(uint64_t v)
{
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])
{
@ -50,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));
plib::array_t<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);
}
// ----------------------------------------------------------------------------------------
@ -100,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, plib::array_t<UINT8> &timing_index)
uint64_t state, uint64_t val, std::vector<uint8_t> &timing_index)
{
pstring elem = list[cur].trim();
int start = 0;
@ -134,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];
}
@ -157,10 +178,10 @@ 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;
m_timing_nt[j] = netlist_time::zero();
while (!ttline.equals(""))
{
@ -175,7 +196,7 @@ void truthtable_desc_t::setup(const plib::pstring_vector_t &truthtable, UINT32 d
nl_assert_always(times.size() == m_NO, "timing count not matching");
UINT16 val = 0;
plib::array_t<UINT8> tindex(m_NO);
std::vector<UINT8> tindex;
for (unsigned j=0; j<m_NO; j++)
{
@ -186,10 +207,10 @@ void truthtable_desc_t::setup(const plib::pstring_vector_t &truthtable, UINT32 d
nl_assert_always(outs.equals("0"), "Unknown value (not 0 or 1");
netlist_time t = netlist_time::from_nsec(times[j].trim().as_long());
int k=0;
while (m_timing_nt[k] != netlist_time::zero && m_timing_nt[k] != t)
while (m_timing_nt[k] != netlist_time::zero() && m_timing_nt[k] != t)
k++;
m_timing_nt[k] = t;
tindex[j] = k;
tindex.push_back(k); //[j] = k;
}
help(0, inout, 0 , val, tindex);
@ -201,14 +222,11 @@ void truthtable_desc_t::setup(const plib::pstring_vector_t &truthtable, UINT32 d
}
// determine ignore
plib::array_t<UINT32> ign(m_size);
std::vector<uint64_t> ign(m_size, all_set);
for (UINT32 j=0; j < m_size; j++)
ign[j] = ~0U;
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)
@ -222,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;
@ -243,13 +261,13 @@ void truthtable_desc_t::setup(const plib::pstring_vector_t &truthtable, UINT32 d
#define ENTRYX(n, m, h) case (n * 1000 + m * 10 + h): \
{ using xtype = netlist_factory_truthtable_t<n, m, h>; \
return plib::powned_ptr<netlist_base_factory_truthtable_t>::Create<xtype>(name,classname,def_param); } break
return plib::owned_ptr<netlist_base_factory_truthtable_t>::Create<xtype>(name,classname,def_param); } break
#define ENTRYY(n, m) ENTRYX(n, m, 0); ENTRYX(n, m, 1)
#define ENTRY(n) ENTRYY(n, 1); ENTRYY(n, 2); ENTRYY(n, 3); ENTRYY(n, 4); ENTRYY(n, 5); ENTRYY(n, 6)
plib::powned_ptr<netlist_base_factory_truthtable_t> nl_tt_factory_create(const unsigned ni, const unsigned no,
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)
@ -273,4 +291,5 @@ plib::powned_ptr<netlist_base_factory_truthtable_t> nl_tt_factory_create(const u
//return nullptr;
}
NETLIB_NAMESPACE_DEVICES_END()
} //namespace devices
} // namespace netlist

View File

@ -10,8 +10,12 @@
#ifndef NLD_TRUTHTABLE_H_
#define NLD_TRUTHTABLE_H_
#include <new>
#include <cstdint>
#include "nl_base.h"
#include "nl_factory.h"
#include "plib/plists.h"
#define NETLIB_TRUTHTABLE(cname, nIN, nOUT, state) \
class NETLIB_NAME(cname) : public nld_truthtable_t<nIN, nOUT, state> \
@ -43,319 +47,380 @@
setup.factory().register_device(std::move(ttd)); \
}
NETLIB_NAMESPACE_DEVICES_START()
#if 0
static inline UINT32 remove_first_bit(UINT32 v)
namespace netlist
{
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,
UINT32 *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))
namespace devices
{
}
void setup(const plib::pstring_vector_t &desc, UINT32 disabled_ignore);
private:
void help(unsigned cur, plib::pstring_vector_t list,
UINT64 state,UINT16 val, plib::array_t<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;
UINT32 *m_outs;
UINT8 *m_timing;
netlist_time *m_timing_nt;
/* additional values */
const UINT32 m_num_bits;
const UINT32 m_size;
};
template<unsigned m_NI, unsigned m_NO, int 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_size = (1 << (m_num_bits));
struct truthtable_t
template<unsigned bits>
struct need_bytes_for_bits
{
truthtable_t()
: m_initialized(false)
, m_desc(m_NO, m_NI, has_state, &m_initialized, m_outs, m_timing, m_timing_nt) {}
bool m_initialized;
UINT32 m_outs[m_size];
UINT8 m_timing[m_size * m_NO];
netlist_time m_timing_nt[16];
truthtable_desc_t m_desc;
enum { value =
bits <= 8 ? 1 :
bits <= 16 ? 2 :
bits <= 32 ? 4 :
8
};
};
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)
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
{
while (*desc != nullptr && **desc != 0 )
template<typename C>
packed_int(C *data)
: m_data(data)
, m_size(sizeof(C))
{}
void set(const size_t pos, const uint64_t val)
{
switch (m_size)
{
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 (unsigned i=0; i < m_NI; i++)
{
inout[i] = inout[i].trim();
enregister(inout[i], m_I[i]);
}
for (unsigned i=0; i < m_NO; i++)
{
out[i] = out[i].trim();
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 (unsigned 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);
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: { }
}
}
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 (unsigned i = 0; i < m_NI; i++)
m_I[i].activate();
for (unsigned 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:
ATTR_HOT void inc_active() override
{
nl_assert(netlist().use_deactivate());
if (has_state == 0)
if (++m_active == 1)
{
process<false>();
}
}
ATTR_HOT 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 && has_state == 0)
if (--m_active == 0)
{
for (unsigned 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];
protected:
private:
template<bool doOUT>
inline void process()
{
netlist_time mt = netlist_time::zero;
UINT32 state = 0;
if (m_NI > 1 && !has_state)
for (unsigned i = 0; i < m_NI; i++)
{
if (!doOUT || (m_ign & (1<<i)))
m_I[i].activate();
}
if (!doOUT)
for (unsigned i = 0; i < m_NI; i++)
{
state |= (INPLOGIC(m_I[i]) << i);
mt = std::max(this->m_I[i].net().time(), mt);
}
else
for (unsigned i = 0; i < m_NI; i++)
state |= (INPLOGIC(m_I[i]) << i);
const UINT32 nstate = state | (has_state ? (m_last_state << m_NI) : 0);
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;
#if 0
for (int i = 0; i < m_NI; i++)
if (m_ign & (1 << i))
m_I[i].inactivate();
#endif
const UINT32 timebase = nstate * m_NO;
if (doOUT)
UINT64 operator[] (size_t pos) const
{
for (unsigned i = 0; i < m_NO; i++)
OUTLOGIC(m_Q[i], (out >> i) & 1, m_ttp->m_timing_nt[m_ttp->m_timing[timebase + i]]);
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
}
}
else
for (unsigned 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)
uint64_t adjust(uint64_t val) const
{
for (unsigned i = 0; i < m_NI; i++)
if (m_ign & (1 << i))
m_I[i].inactivate();
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;
};
UINT32 m_last_state;
UINT32 m_ign;
INT32 m_active;
truthtable_t *m_ttp;
plib::pstring_vector_t m_desc;
};
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()
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))
{
}
plib::pstring_vector_t m_desc;
const logic_family_desc_t *m_family;
};
void setup(const plib::pstring_vector_t &desc, UINT32 disabled_ignore);
private:
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);
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) { }
unsigned m_NO;
unsigned m_NI;
bool *m_initialized;
packed_int m_outs;
uint8_t *m_timing;
netlist_time *m_timing_nt;
plib::powned_ptr<device_t> Create(netlist_t &anetlist, const pstring &name) override
/* additional values */
const std::size_t m_num_bits;
const std::size_t m_size;
};
template<unsigned m_NI, unsigned m_NO, int m_has_state>
NETLIB_OBJECT(truthtable_t)
{
typedef nld_truthtable_t<m_NI, m_NO, has_state> tt_type;
return plib::powned_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;
};
private:
family_setter_t m_fam;
public:
plib::powned_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);
static const int m_num_bits = m_NI + m_has_state * (m_NI + m_NO);
static const int m_size = (1 << (m_num_bits));
NETLIB_NAMESPACE_DEVICES_END()
struct truthtable_t
{
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)
{
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 *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();
}
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++)
{
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
{
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 (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)
{
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;
};
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);
} //namespace devices
} // namespace netlist

View File

@ -0,0 +1,40 @@
// license:GPL-2.0+
// copyright-holders:Couriersud
/*
* nld_cmos.h
*
*/
#ifndef NLID_CMOS_H_
#define NLID_CMOS_H_
#include "nl_base.h"
namespace netlist
{
namespace devices
{
NETLIB_OBJECT(vdd_vss)
{
NETLIB_CONSTRUCTOR(vdd_vss)
, m_vdd(*this, "VDD")
, m_vss(*this, "VSS")
{
}
NETLIB_UPDATEI() {};
NETLIB_RESETI() {};
public:
inline nl_double vdd() { return INPANALOG(m_vdd); }
inline nl_double vss() { return INPANALOG(m_vss); }
analog_input_t m_vdd;
analog_input_t m_vss;
};
} //namespace devices
} // namespace netlist
#endif /* NLID_CMOS_H_ */

View File

@ -0,0 +1,589 @@
// license:GPL-2.0+
// copyright-holders:Couriersud
/*
* nlid_system.h
*
* netlist devices defined in the core
*
* This file contains internal headers
*/
#ifndef NLID_SYSTEM_H_
#define NLID_SYSTEM_H_
#include "nl_setup.h"
#include "nl_base.h"
#include "nl_factory.h"
#include "analog/nld_twoterm.h"
namespace netlist
{
namespace devices
{
// -----------------------------------------------------------------------------
// netlistparams
// -----------------------------------------------------------------------------
NETLIB_OBJECT(netlistparams)
{
NETLIB_CONSTRUCTOR(netlistparams)
, m_use_deactivate(*this, "USE_DEACTIVATE", 0)
{
}
NETLIB_UPDATEI() { }
//NETLIB_RESETI() { }
//NETLIB_UPDATE_PARAMI() { }
public:
param_logic_t m_use_deactivate;
};
// -----------------------------------------------------------------------------
// mainclock
// -----------------------------------------------------------------------------
NETLIB_OBJECT(mainclock)
{
NETLIB_CONSTRUCTOR(mainclock)
, m_Q(*this, "Q")
, m_freq(*this, "FREQ", 7159000.0 * 5)
{
m_inc = netlist_time::from_hz(m_freq.Value()*2);
}
NETLIB_RESETI()
{
m_Q.net().set_time(netlist_time::zero());
}
NETLIB_UPDATE_PARAMI()
{
m_inc = netlist_time::from_hz(m_freq.Value()*2);
}
NETLIB_UPDATEI()
{
logic_net_t &net = m_Q.net();
// this is only called during setup ...
net.toggle_new_Q();
net.set_time(netlist().time() + m_inc);
}
public:
logic_output_t m_Q;
param_double_t m_freq;
netlist_time m_inc;
inline static void mc_update(logic_net_t &net);
};
// -----------------------------------------------------------------------------
// clock
// -----------------------------------------------------------------------------
NETLIB_OBJECT(clock)
{
NETLIB_CONSTRUCTOR(clock)
, m_feedback(*this, "FB")
, m_Q(*this, "Q")
, m_freq(*this, "FREQ", 7159000.0 * 5.0)
{
m_inc = netlist_time::from_hz(m_freq.Value()*2);
connect_late(m_feedback, m_Q);
}
NETLIB_UPDATEI();
//NETLIB_RESETI();
NETLIB_UPDATE_PARAMI();
protected:
logic_input_t m_feedback;
logic_output_t m_Q;
param_double_t m_freq;
netlist_time m_inc;
};
// -----------------------------------------------------------------------------
// extclock
// -----------------------------------------------------------------------------
NETLIB_OBJECT(extclock)
{
NETLIB_CONSTRUCTOR(extclock)
, m_freq(*this, "FREQ", 7159000.0 * 5.0)
, m_pattern(*this, "PATTERN", "1,1")
, m_offset(*this, "OFFSET", 0.0)
, m_feedback(*this, "FB")
, m_Q(*this, "Q")
{
m_inc[0] = netlist_time::from_hz(m_freq.Value()*2);
connect_late(m_feedback, m_Q);
{
netlist_time base = netlist_time::from_hz(m_freq.Value()*2);
plib::pstring_vector_t pat(m_pattern.Value(),",");
m_off = netlist_time(m_offset.Value());
int pati[256];
m_size = pat.size();
int total = 0;
for (unsigned i=0; i<m_size; i++)
{
pati[i] = pat[i].as_long();
total += pati[i];
}
netlist_time ttotal = netlist_time::zero();
for (unsigned i=0; i<m_size - 1; i++)
{
m_inc[i] = base * pati[i];
ttotal += m_inc[i];
}
m_inc[m_size - 1] = base * total - ttotal;
}
save(NLNAME(m_cnt));
save(NLNAME(m_off));
}
NETLIB_UPDATEI();
NETLIB_RESETI();
//NETLIB_UPDATE_PARAMI();
protected:
param_double_t m_freq;
param_str_t m_pattern;
param_double_t m_offset;
logic_input_t m_feedback;
logic_output_t m_Q;
unsigned m_cnt;
unsigned m_size;
netlist_time m_inc[32];
netlist_time m_off;
};
// -----------------------------------------------------------------------------
// Special support devices ...
// -----------------------------------------------------------------------------
NETLIB_OBJECT(logic_input)
{
NETLIB_CONSTRUCTOR(logic_input)
, m_Q(*this, "Q")
, m_IN(*this, "IN", 0)
/* make sure we get the family first */
, m_FAMILY(*this, "FAMILY", "FAMILY(TYPE=TTL)")
{
set_logic_family(netlist().setup().family_from_model(m_FAMILY.Value()));
}
NETLIB_UPDATE_AFTER_PARAM_CHANGE()
NETLIB_UPDATEI();
NETLIB_RESETI();
NETLIB_UPDATE_PARAMI();
protected:
logic_output_t m_Q;
param_logic_t m_IN;
param_model_t m_FAMILY;
};
NETLIB_OBJECT(analog_input)
{
NETLIB_CONSTRUCTOR(analog_input)
, m_Q(*this, "Q")
, m_IN(*this, "IN", 0.0)
{
}
NETLIB_UPDATE_AFTER_PARAM_CHANGE()
NETLIB_UPDATEI();
NETLIB_RESETI();
NETLIB_UPDATE_PARAMI();
protected:
analog_output_t m_Q;
param_double_t m_IN;
};
// -----------------------------------------------------------------------------
// nld_gnd
// -----------------------------------------------------------------------------
NETLIB_OBJECT(gnd)
{
NETLIB_CONSTRUCTOR(gnd)
, m_Q(*this, "Q")
{
}
NETLIB_UPDATEI()
{
OUTANALOG(m_Q, 0.0);
}
NETLIB_RESETI() { }
protected:
analog_output_t m_Q;
};
// -----------------------------------------------------------------------------
// nld_dummy_input
// -----------------------------------------------------------------------------
NETLIB_OBJECT_DERIVED(dummy_input, base_dummy)
{
public:
NETLIB_CONSTRUCTOR_DERIVED(dummy_input, base_dummy)
, m_I(*this, "I")
{
}
protected:
NETLIB_RESETI() { }
NETLIB_UPDATEI() { }
private:
analog_input_t m_I;
};
// -----------------------------------------------------------------------------
// nld_frontier
// -----------------------------------------------------------------------------
NETLIB_OBJECT_DERIVED(frontier, base_dummy)
{
public:
NETLIB_CONSTRUCTOR_DERIVED(frontier, base_dummy)
, m_RIN(*this, "m_RIN")
, m_ROUT(*this, "m_ROUT", true)
, m_I(*this, "_I")
, m_Q(*this, "_Q")
, m_p_RIN(*this, "RIN", 1.0e6)
, m_p_ROUT(*this, "ROUT", 50.0)
{
register_subalias("I", m_RIN.m_P);
register_subalias("G", m_RIN.m_N);
connect_late(m_I, m_RIN.m_P);
register_subalias("_OP", m_ROUT.m_P);
register_subalias("Q", m_ROUT.m_N);
connect_late(m_Q, m_ROUT.m_P);
}
NETLIB_RESETI()
{
m_RIN.set(1.0 / m_p_RIN.Value(),0,0);
m_ROUT.set(1.0 / m_p_ROUT.Value(),0,0);
}
NETLIB_UPDATEI()
{
OUTANALOG(m_Q, INPANALOG(m_I));
}
private:
NETLIB_NAME(twoterm) m_RIN;
/* Fixme: only works if the device is time-stepped - need to rework */
NETLIB_NAME(twoterm) m_ROUT;
analog_input_t m_I;
analog_output_t m_Q;
param_double_t m_p_RIN;
param_double_t m_p_ROUT;
};
/* -----------------------------------------------------------------------------
* nld_function
*
* FIXME: Currently a proof of concept to get congo bongo working
* ----------------------------------------------------------------------------- */
NETLIB_OBJECT(function)
{
NETLIB_CONSTRUCTOR(function)
, m_N(*this, "N", 2)
, m_func(*this, "FUNC", "")
, m_Q(*this, "Q")
{
for (std::size_t i=0; i < m_N; i++)
m_I.emplace(i, *this, plib::pfmt("A{1}")(i));
plib::pstring_vector_t cmds(m_func.Value(), " ");
m_precompiled.clear();
for (std::size_t i=0; i < cmds.size(); i++)
{
pstring cmd = cmds[i];
rpn_inst rc;
if (cmd == "+")
rc.m_cmd = ADD;
else if (cmd == "-")
rc.m_cmd = SUB;
else if (cmd == "*")
rc.m_cmd = MULT;
else if (cmd == "/")
rc.m_cmd = DIV;
else if (cmd.startsWith("A"))
{
rc.m_cmd = PUSH_INPUT;
rc.m_param = cmd.substr(1).as_long();
}
else
{
bool err = false;
rc.m_cmd = PUSH_CONST;
rc.m_param = cmd.as_double(&err);
if (err)
netlist().log().fatal("nld_function: unknown/misformatted token <{1}> in <{2}>", cmd, m_func.Value());
}
m_precompiled.push_back(rc);
}
}
protected:
NETLIB_RESETI();
NETLIB_UPDATEI();
private:
enum rpn_cmd
{
ADD,
MULT,
SUB,
DIV,
PUSH_CONST,
PUSH_INPUT
};
struct rpn_inst
{
rpn_inst() : m_cmd(ADD), m_param(0.0) { }
rpn_cmd m_cmd;
nl_double m_param;
};
param_int_t m_N;
param_str_t m_func;
analog_output_t m_Q;
plib::uninitialised_array_t<analog_input_t, 10> m_I;
plib::pvector_t<rpn_inst> m_precompiled;
};
// -----------------------------------------------------------------------------
// nld_res_sw
// -----------------------------------------------------------------------------
NETLIB_OBJECT(res_sw)
{
public:
NETLIB_CONSTRUCTOR(res_sw)
, m_R(*this, "R")
, m_I(*this, "I")
, m_RON(*this, "RON", 1.0)
, m_ROFF(*this, "ROFF", 1.0E20)
, m_last_state(0)
{
register_subalias("1", m_R.m_P);
register_subalias("2", m_R.m_N);
save(NLNAME(m_last_state));
}
NETLIB_SUB(R) m_R;
logic_input_t m_I;
param_double_t m_RON;
param_double_t m_ROFF;
NETLIB_RESETI()
{
m_last_state = 0;
m_R.set_R(m_ROFF.Value());
}
//NETLIB_UPDATE_PARAMI();
NETLIB_UPDATEI();
private:
UINT8 m_last_state;
};
// -----------------------------------------------------------------------------
// nld_base_proxy
// -----------------------------------------------------------------------------
NETLIB_OBJECT(base_proxy)
{
public:
nld_base_proxy(netlist_t &anetlist, const pstring &name, logic_t *inout_proxied, core_terminal_t *proxy_inout)
: device_t(anetlist, name)
{
m_logic_family = inout_proxied->logic_family();
m_term_proxied = inout_proxied;
m_proxy_term = proxy_inout;
}
virtual ~nld_base_proxy() {}
logic_t &term_proxied() const { return *m_term_proxied; }
core_terminal_t &proxy_term() const { return *m_proxy_term; }
protected:
virtual const logic_family_desc_t &logic_family() const
{
return *m_logic_family;
}
private:
const logic_family_desc_t *m_logic_family;
logic_t *m_term_proxied;
core_terminal_t *m_proxy_term;
};
// -----------------------------------------------------------------------------
// nld_a_to_d_proxy
// -----------------------------------------------------------------------------
NETLIB_OBJECT_DERIVED(a_to_d_proxy, base_proxy)
{
public:
nld_a_to_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *in_proxied)
: nld_base_proxy(anetlist, name, in_proxied, &m_I)
, m_I(*this, "I")
, m_Q(*this, "Q")
{
}
virtual ~nld_a_to_d_proxy() {}
analog_input_t m_I;
logic_output_t m_Q;
protected:
NETLIB_RESETI() { }
NETLIB_UPDATEI()
{
if (m_I.Q_Analog() > logic_family().m_high_thresh_V)
OUTLOGIC(m_Q, 1, NLTIME_FROM_NS(1));
else if (m_I.Q_Analog() < logic_family().m_low_thresh_V)
OUTLOGIC(m_Q, 0, NLTIME_FROM_NS(1));
else
{
// do nothing
}
}
private:
};
// -----------------------------------------------------------------------------
// nld_base_d_to_a_proxy
// -----------------------------------------------------------------------------
NETLIB_OBJECT_DERIVED(base_d_to_a_proxy, base_proxy)
{
public:
virtual ~nld_base_d_to_a_proxy() {}
virtual logic_input_t &in() { return m_I; }
protected:
nld_base_d_to_a_proxy(netlist_t &anetlist, const pstring &name, logic_output_t *out_proxied, core_terminal_t &proxy_out)
: nld_base_proxy(anetlist, name, out_proxied, &proxy_out)
, m_I(*this, "I")
{
}
logic_input_t m_I;
private:
};
NETLIB_OBJECT_DERIVED(d_to_a_proxy, base_d_to_a_proxy)
{
public:
nld_d_to_a_proxy(netlist_t &anetlist, const pstring &name, logic_output_t *out_proxied)
: nld_base_d_to_a_proxy(anetlist, name, out_proxied, m_RV.m_P)
, m_GNDHack(*this, "_Q")
, m_RV(*this, "RV")
, m_last_state(-1)
, m_is_timestep(false)
{
//register_sub(m_RV);
//register_term("1", m_RV.m_P);
//register_term("2", m_RV.m_N);
register_subalias("Q", m_RV.m_P);
connect_late(m_RV.m_N, m_GNDHack);
save(NLNAME(m_last_state));
}
virtual ~nld_d_to_a_proxy() {}
protected:
NETLIB_RESETI();
NETLIB_UPDATEI();
private:
analog_output_t m_GNDHack; // FIXME: Long term, we need to connect proxy gnd to device gnd
NETLIB_SUB(twoterm) m_RV;
int m_last_state;
bool m_is_timestep;
};
class factory_lib_entry_t : public base_factory_t
{
P_PREVENT_COPYING(factory_lib_entry_t)
public:
factory_lib_entry_t(setup_t &setup, const pstring &name, const pstring &classname,
const pstring &def_param)
: base_factory_t(name, classname, def_param), m_setup(setup) { }
class wrapper : public device_t
{
public:
wrapper(const pstring &devname, netlist_t &anetlist, const pstring &name)
: device_t(anetlist, name), m_devname(devname)
{
anetlist.setup().namespace_push(name);
anetlist.setup().include(m_devname);
anetlist.setup().namespace_pop();
}
protected:
NETLIB_RESETI() { }
NETLIB_UPDATEI() { }
pstring m_devname;
};
plib::owned_ptr<device_t> Create(netlist_t &anetlist, const pstring &name) override
{
return plib::owned_ptr<device_t>::Create<wrapper>(this->name(), anetlist, name);
}
private:
setup_t &m_setup;
};
} //namespace devices
} // namespace netlist
#endif /* NLD_SYSTEM_H_ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -14,8 +14,6 @@
// SETUP
//============================================================
#define NOEXCEPT noexcept
/*
* The following options determine how object::update is called.
* NL_PMF_TYPE_VIRTUAL
@ -42,17 +40,12 @@
*
* The whole exercise was done to avoid virtual calls. In prior versions of
* netlist, the INTERNAL and GNUC_PMF_CONV approach provided significant improvement.
* Since than, ATTR_COLD was removed from functions declared as virtual.
* Since than, was removed from functions declared as virtual.
* This may explain that the recent benchmarks show no difference at all.
*
* Disappointing is the GNUC_PMF performance.
*/
/* FIXME: Currently, we are not registering subdevices and thus these will not
* be started and the internal method will not be initialized.
*/
// This will be autodetected
//#define NL_PMF_TYPE 0
@ -73,38 +66,26 @@
#pragma GCC diagnostic ignored "-Wpmf-conversions"
#endif
#define USE_TRUTHTABLE (1)
// The following adds about 10% performance ...
#if !defined(USE_OPENMP)
#define USE_OPENMP (0)
#endif // !defined(USE_OPENMP)
// Use nano-second resolution - Sufficient for now
#define NETLIST_INTERNAL_RES (U64(1000000000))
//#define NETLIST_INTERNAL_RES (U64(1000000000000))
#define NETLIST_CLOCK (NETLIST_INTERNAL_RES)
#define NETLIST_GMIN_DEFAULT (1e-9)
//#define nl_double float
//#define NL_FCONST(x) (x ## f)
#define nl_double double
#define NL_FCONST(x) x
//============================================================
// GENERAL
//============================================================
#define NL_USE_MEMPOOL (0)
#define USE_TRUTHTABLE (1)
//============================================================
// Solver defines
//============================================================
#define USE_MATRIX_GS (0)
#define USE_GABS (1)
#define USE_MATRIX_GS (0)
#define USE_GABS (1)
// savings are eaten up by effort
// FIXME: Convert into solver parameter
#define USE_LINEAR_PREDICTION (0)
#define USE_LINEAR_PREDICTION (0)
#define NETLIST_GMIN_DEFAULT (1e-9)
//============================================================
@ -140,9 +121,34 @@
#define end_timing(v) do { } while (0)
#endif
//============================================================
// General
//============================================================
// this macro passes an item followed by a string version of itself as two consecutive parameters
#define NLNAME(x) x, #x
#define NOEXCEPT noexcept
// The following adds about 10% performance ...
#if !defined(USE_OPENMP)
#define USE_OPENMP (0)
#endif // !defined(USE_OPENMP)
// Use nano-second resolution - Sufficient for now
#define NETLIST_INTERNAL_RES (U64(1000000000))
//#define NETLIST_INTERNAL_RES (U64(1000000000000))
#define NETLIST_CLOCK (NETLIST_INTERNAL_RES)
//#define nl_double float
//#define NL_FCONST(x) (x ## f)
#define nl_double double
#define NL_FCONST(x) x
//============================================================
// WARNINGS
//============================================================

View File

@ -200,7 +200,7 @@ inline int CAPACITOR_tc_hl(const double c, const double r)
* Vt = (VH-VL)*exp(-t/RC)
* ln(Vt/(VH-VL))*RC = -t
*/
static const double TIME_CONSTANT = -nl_math::log(2.0 / (3.7-0.3));
static const double TIME_CONSTANT = -std::log(2.0 / (3.7-0.3));
int ret = (int) (TIME_CONSTANT * (130.0 + r) * c * 1e9);
return ret;
}
@ -211,7 +211,7 @@ inline int CAPACITOR_tc_lh(const double c, const double r)
* Vt = (VH-VL)*(1-exp(-t/RC))
* -t=ln(1-Vt/(VH-VL))*RC
*/
static const double TIME_CONSTANT = -nl_math::log(1.0 - 0.8 / (3.7-0.3));
static const double TIME_CONSTANT = -std::log(1.0 - 0.8 / (3.7-0.3));
int ret = (int) (TIME_CONSTANT * (1.0 + r) * c * 1e9);
return ret;
}

View File

@ -10,6 +10,7 @@
#include "nl_factory.h"
#include "nl_setup.h"
#include "plib/putil.h"
namespace netlist
{
@ -18,7 +19,7 @@ namespace netlist
// net_device_t_base_factory
// ----------------------------------------------------------------------------------------
ATTR_COLD const plib::pstring_vector_t base_factory_t::term_param_list()
const plib::pstring_vector_t base_factory_t::term_param_list()
{
if (m_def_param.startsWith("+"))
return plib::pstring_vector_t(m_def_param.substr(1), ",");
@ -26,7 +27,7 @@ ATTR_COLD const plib::pstring_vector_t base_factory_t::term_param_list()
return plib::pstring_vector_t();
}
ATTR_COLD const plib::pstring_vector_t base_factory_t::def_params()
const plib::pstring_vector_t base_factory_t::def_params()
{
if (m_def_param.startsWith("+") || m_def_param.equals("-"))
return plib::pstring_vector_t();
@ -45,34 +46,11 @@ factory_list_t::~factory_list_t()
clear();
}
#if 0
device_t *factory_list_t::new_device_by_classname(const pstring &classname) const
{
for (std::size_t i=0; i < m_list.size(); i++)
{
base_factory_t *p = m_list[i];
if (p->classname() == classname)
{
device_t *ret = p->Create();
return ret;
}
p++;
}
return nullptr; // appease code analysis
}
#endif
void factory_list_t::error(const pstring &s)
{
m_setup.log().fatal("{1}", s);
}
plib::powned_ptr<device_t> factory_list_t::new_device_by_name(const pstring &devname, netlist_t &anetlist, const pstring &name)
{
base_factory_t *f = factory_by_name(devname);
return f->Create(anetlist, name);
}
base_factory_t * factory_list_t::factory_by_name(const pstring &devname)
{
for (auto & e : *this)

View File

@ -13,10 +13,14 @@
#include "nl_config.h"
#include "plib/plists.h"
#include "plib/putil.h"
#include "nl_base.h"
#define NETLIB_DEVICE_IMPL(chip) factory_creator_ptr_t decl_ ## chip = factory_creator_t< NETLIB_NAME(chip) >;
namespace netlist
{
// -----------------------------------------------------------------------------
// net_dev class factory
// -----------------------------------------------------------------------------
@ -32,7 +36,7 @@ namespace netlist
virtual ~base_factory_t() {}
virtual plib::powned_ptr<device_t> Create(netlist_t &anetlist, const pstring &name) = 0;
virtual plib::owned_ptr<device_t> Create(netlist_t &anetlist, const pstring &name) = 0;
const pstring &name() const { return m_name; }
const pstring &classname() const { return m_classname; }
@ -46,7 +50,7 @@ namespace netlist
pstring m_def_param; /* default parameter */
};
template <class device_class>
template <class C>
class factory_t : public base_factory_t
{
P_PREVENT_COPYING(factory_t)
@ -55,14 +59,13 @@ namespace netlist
const pstring &def_param)
: base_factory_t(name, classname, def_param) { }
plib::powned_ptr<device_t> Create(netlist_t &anetlist, const pstring &name) override
plib::owned_ptr<device_t> Create(netlist_t &anetlist, const pstring &name) override
{
return plib::powned_ptr<device_t>::Create<device_class>(anetlist, name);
return plib::owned_ptr<device_t>::Create<C>(anetlist, name);
}
};
class factory_list_t : public plib::pvector_t<plib::powned_ptr<base_factory_t>>
class factory_list_t : public plib::pvector_t<plib::owned_ptr<base_factory_t>>
{
public:
factory_list_t(setup_t &m_setup);
@ -72,10 +75,10 @@ namespace netlist
void register_device(const pstring &name, const pstring &classname,
const pstring &def_param)
{
register_device(plib::powned_ptr<base_factory_t>::Create<factory_t<device_class>>(name, classname, def_param));
register_device(plib::owned_ptr<base_factory_t>::Create<factory_t<device_class>>(name, classname, def_param));
}
void register_device(plib::powned_ptr<base_factory_t> factory)
void register_device(plib::owned_ptr<base_factory_t> factory)
{
for (auto & e : *this)
if (e->name() == factory->name())
@ -83,9 +86,6 @@ namespace netlist
push_back(std::move(factory));
}
//ATTR_COLD device_t *new_device_by_classname(const pstring &classname) const;
// FIXME: legacy, should use factory_by_name
plib::powned_ptr<device_t> new_device_by_name(const pstring &devname, netlist_t &anetlist, const pstring &name);
base_factory_t * factory_by_name(const pstring &devname);
template <class C>
@ -100,6 +100,20 @@ namespace netlist
setup_t &m_setup;
};
// -----------------------------------------------------------------------------
// factory_creator_ptr_t
// -----------------------------------------------------------------------------
using factory_creator_ptr_t = plib::owned_ptr<base_factory_t> (*)(const pstring &name, const pstring &classname,
const pstring &def_param);
template <typename T>
plib::owned_ptr<base_factory_t> factory_creator_t(const pstring &name, const pstring &classname,
const pstring &def_param)
{
return plib::owned_ptr<base_factory_t>::Create<factory_t<T>>(name, classname, def_param);
}
}
#endif /* NLFACTORY_H_ */

View File

@ -28,35 +28,18 @@ namespace netlist
P_PREVENT_COPYING(timed_queue)
public:
class entry_t
struct entry_t
{
public:
ATTR_HOT entry_t()
: m_exec_time(), m_object() {}
#if 0
ATTR_HOT entry_t(entry_t &&right) NOEXCEPT
: m_exec_time(right.m_exec_time), m_object(right.m_object) {}
ATTR_HOT entry_t(const entry_t &right) NOEXCEPT
: m_exec_time(right.m_exec_time), m_object(right.m_object) {}
#endif
ATTR_HOT entry_t(const Time &atime, const Element &elem) NOEXCEPT
: m_exec_time(atime), m_object(elem) {}
ATTR_HOT const Time &exec_time() const { return m_exec_time; }
ATTR_HOT const Element &object() const { return m_object; }
#if 0
ATTR_HOT entry_t &operator=(const entry_t &right) NOEXCEPT {
m_exec_time = right.m_exec_time;
m_object = right.m_object;
return *this;
}
#endif
private:
Time m_exec_time;
Element m_object;
};
timed_queue(unsigned list_size)
: m_list(list_size)
#if (NL_KEEP_STATISTICS)
, m_prof_sortmove(0)
, m_prof_call(0)
#endif
{
#if HAS_OPENMP && USE_OPENMP
m_lock = 0;
@ -64,36 +47,23 @@ namespace netlist
clear();
}
ATTR_HOT std::size_t capacity() const { return m_list.size(); }
ATTR_HOT bool is_empty() const { return (m_end == &m_list[1]); }
ATTR_HOT bool is_not_empty() const { return (m_end > &m_list[1]); }
std::size_t capacity() const { return m_list.size(); }
bool empty() const { return (m_end == &m_list[1]); }
ATTR_HOT void push(const entry_t e) NOEXCEPT
void push(const Time t, Element o) NOEXCEPT
{
#if HAS_OPENMP && USE_OPENMP
/* Lock */
while (m_lock.exchange(1)) { }
#endif
#if 1
const Time t = e.exec_time();
entry_t * i = m_end++;
for (; t > (i - 1)->exec_time(); i--)
entry_t * i = m_end;
for (; t > (i - 1)->m_exec_time; --i)
{
*(i) = *(i-1);
//i--;
inc_stat(m_prof_sortmove);
}
*i = e;
#else
entry_t * i = m_end++;
while (e.exec_time() > (i - 1)->exec_time())
{
*(i) = *(i-1);
--i;
inc_stat(m_prof_sortmove);
}
*i = e;
#endif
*i = { t, o };
++m_end;
inc_stat(m_prof_call);
#if HAS_OPENMP && USE_OPENMP
m_lock = 0;
@ -101,17 +71,10 @@ namespace netlist
//nl_assert(m_end - m_list < Size);
}
ATTR_HOT const entry_t & pop() NOEXCEPT
{
return *(--m_end);
}
entry_t pop() NOEXCEPT { return *(--m_end); }
entry_t top() const NOEXCEPT { return *(m_end-1); }
ATTR_HOT const entry_t & top() const NOEXCEPT
{
return *(m_end-1);
}
ATTR_HOT void remove(const Element &elem) NOEXCEPT
void remove(const Element &elem) NOEXCEPT
{
/* Lock */
#if HAS_OPENMP && USE_OPENMP
@ -119,13 +82,13 @@ namespace netlist
#endif
for (entry_t * i = m_end - 1; i > &m_list[0]; i--)
{
if (i->object() == elem)
if (i->m_object == elem)
{
m_end--;
while (i < m_end)
{
*i = *(i+1);
i++;
++i;
}
#if HAS_OPENMP && USE_OPENMP
m_lock = 0;
@ -138,28 +101,22 @@ namespace netlist
#endif
}
ATTR_COLD void clear()
void clear()
{
m_end = &m_list[0];
/* put an empty element with maximum time into the queue.
* the insert algo above will run into this element and doesn't
* need a comparison with queue start.
*/
m_list[0] = entry_t(Time::from_raw(~0), Element(0));
m_list[0] = { Time::never(), Element(0) };
m_end++;
}
// save state support & mame disasm
ATTR_COLD const entry_t *listptr() const { return &m_list[1]; }
ATTR_HOT int count() const { return m_end - &m_list[1]; }
ATTR_HOT const entry_t & operator[](const int & index) const { return m_list[1+index]; }
#if (NL_KEEP_STATISTICS)
// profiling
INT32 m_prof_sortmove;
INT32 m_prof_call;
#endif
const entry_t *listptr() const { return &m_list[1]; }
std::size_t size() const { return m_end - &m_list[1]; }
const entry_t & operator[](const std::size_t index) const { return m_list[ 1 + index]; }
private:
@ -167,8 +124,16 @@ namespace netlist
volatile std::atomic<int> m_lock;
#endif
entry_t * m_end;
plib::array_t<entry_t> m_list;
};
std::vector<entry_t> m_list;
public:
#if (NL_KEEP_STATISTICS)
// profiling
std::size_t m_prof_sortmove;
std::size_t m_prof_call;
#endif
};
}

View File

@ -15,7 +15,7 @@ namespace netlist
// A netlist parser
// ----------------------------------------------------------------------------------------
ATTR_COLD void parser_t::verror(const pstring &msg, int line_num, const pstring &line)
void parser_t::verror(const pstring &msg, int line_num, const pstring &line)
{
m_setup.log().fatal("line {1}: error: {2}\n\t\t{3}\n", line_num,
msg, line);
@ -158,7 +158,7 @@ void parser_t::net_truthtable_start()
pstring def_param = get_string();
require_token(m_tok_param_right);
plib::powned_ptr<netlist::devices::netlist_base_factory_truthtable_t> ttd = netlist::devices::nl_tt_factory_create(ni, no, hs,
plib::owned_ptr<netlist::devices::netlist_base_factory_truthtable_t> ttd = netlist::devices::nl_tt_factory_create(ni, no, hs,
name, name, "+" + def_param);
while (true)

View File

@ -9,7 +9,6 @@
#define NL_PARSER_H_
#include "nl_setup.h"
#include "nl_util.h"
#include "plib/pparser.h"
namespace netlist

View File

@ -10,13 +10,13 @@
#include "solver/nld_solver.h"
#include "plib/palloc.h"
#include "plib/putil.h"
#include "nl_base.h"
#include "nl_setup.h"
#include "nl_parser.h"
#include "nl_util.h"
#include "nl_factory.h"
#include "devices/net_lib.h"
#include "devices/nld_system.h"
#include "devices/nlid_system.h"
#include "analog/nld_twoterm.h"
#include "solver/nld_solver.h"
@ -76,7 +76,7 @@ setup_t::~setup_t()
pstring::resetmem();
}
ATTR_COLD pstring setup_t::build_fqn(const pstring &obj_name) const
pstring setup_t::build_fqn(const pstring &obj_name) const
{
if (m_namespace_stack.empty())
//return netlist().name() + "." + obj_name;
@ -100,12 +100,11 @@ void setup_t::namespace_pop()
}
void setup_t::register_dev(plib::powned_ptr<device_t> dev)
void setup_t::register_dev(plib::owned_ptr<device_t> dev)
{
for (auto & d : netlist().m_devices)
if (d->name() == dev->name())
log().fatal("Error adding {1} to device list. Duplicate name \n", d->name());
netlist().m_devices.push_back(std::move(dev));
}
@ -182,7 +181,7 @@ void setup_t::register_dippins_arr(const pstring &terms)
}
}
pstring setup_t::objtype_as_astr(object_t &in) const
pstring setup_t::objtype_as_str(object_t &in) const
{
switch (in.type())
{
@ -219,7 +218,7 @@ void setup_t::register_and_set_param(pstring name, param_t &param)
double vald = 0;
if (sscanf(val.cstr(), "%lf", &vald) != 1)
log().fatal("Invalid number conversion {1} : {2}\n", name, val);
dynamic_cast<param_double_t &>(param).initial(vald);
static_cast<param_double_t &>(param).initial(vald);
}
break;
case param_t::INTEGER:
@ -228,13 +227,13 @@ void setup_t::register_and_set_param(pstring name, param_t &param)
double vald = 0;
if (sscanf(val.cstr(), "%lf", &vald) != 1)
log().fatal("Invalid number conversion {1} : {2}\n", name, val);
dynamic_cast<param_int_t &>(param).initial((int) vald);
static_cast<param_int_t &>(param).initial((int) vald);
}
break;
case param_t::STRING:
case param_t::MODEL:
{
dynamic_cast<param_str_t &>(param).initial(val);
static_cast<param_str_t &>(param).initial(val);
}
break;
default:
@ -245,64 +244,22 @@ void setup_t::register_and_set_param(pstring name, param_t &param)
log().fatal("Error adding parameter {1} to parameter list\n", name);
}
void setup_t::register_object(device_t &dev, const pstring &name, object_t &obj)
void setup_t::register_term(core_terminal_t &term)
{
switch (obj.type())
if (term.is_type(terminal_t::OUTPUT))
{
case terminal_t::TERMINAL:
case terminal_t::INPUT:
case terminal_t::OUTPUT:
{
core_terminal_t &term = dynamic_cast<core_terminal_t &>(obj);
if (term.isType(terminal_t::OUTPUT))
{
if (term.is_logic())
{
logic_output_t &port = dynamic_cast<logic_output_t &>(term);
port.set_logic_family(dev.logic_family());
dynamic_cast<logic_output_t &>(term).init_object(dev, dev.name() + "." + name);
}
else if (term.is_analog())
dynamic_cast<analog_output_t &>(term).init_object(dev, dev.name() + "." + name);
else
log().fatal("Error adding {1} {2} to terminal list, neither LOGIC nor ANALOG\n", objtype_as_astr(term), term.name());
}
else if (term.isType(terminal_t::INPUT))
{
if (term.is_logic())
{
logic_input_t &port = dynamic_cast<logic_input_t &>(term);
port.set_logic_family(dev.logic_family());
}
term.init_object(dev, dev.name() + "." + name);
dev.m_terminals.push_back(obj.name());
}
else
{
term.init_object(dev, dev.name() + "." + name);
dev.m_terminals.push_back(obj.name());
}
if (!m_terminals.add(term.name(), &term))
log().fatal("Error adding {1} {2} to terminal list\n", objtype_as_astr(term), term.name());
log().debug("{1} {2}\n", objtype_as_astr(term), name);
}
break;
case terminal_t::NET:
break;
case terminal_t::PARAM:
{
//register_and_set_param(name, dynamic_cast<param_t &>(obj));
log().fatal("should use register_param");
}
break;
case terminal_t::DEVICE:
log().fatal("Device registration not yet supported - {1}\n", name);
break;
case terminal_t::QUEUE:
log().fatal("QUEUE registration not yet supported - {1}\n", name);
break;
}
else if (term.is_type(terminal_t::INPUT))
{
static_cast<device_t &>(term.device()).m_terminals.push_back(term.name());
}
else
{
static_cast<device_t &>(term.device()).m_terminals.push_back(term.name());
}
if (!m_terminals.add(term.name(), &term))
log().fatal("Error adding {1} {2} to terminal list\n", objtype_as_str(term), term.name());
log().debug("{1} {2}\n", objtype_as_str(term), term.name());
}
void setup_t::register_link_arr(const pstring &terms)
@ -381,7 +338,6 @@ void setup_t::register_frontier(const pstring attach, const double r_IN, const d
void setup_t::register_param(const pstring &param, const double value)
{
// FIXME: there should be a better way
register_param(param, plib::pfmt("{1}").e(value,".9"));
}
@ -505,7 +461,7 @@ devices::nld_base_proxy *setup_t::get_d_a_proxy(core_terminal_t &out)
/* connect all existing terminals to new net */
for (core_terminal_t *p : out.net().m_core_terms)
for (auto & p : out.net().m_core_terms)
{
p->clear_net(); // de-link from all nets ...
if (!connect(new_proxy->proxy_term(), *p))
@ -518,7 +474,7 @@ devices::nld_base_proxy *setup_t::get_d_a_proxy(core_terminal_t &out)
proxy = new_proxy.get();
register_dev_s(std::move(new_proxy));
register_dev(std::move(new_proxy));
}
return proxy;
}
@ -529,14 +485,14 @@ void setup_t::connect_input_output(core_terminal_t &in, core_terminal_t &out)
{
logic_input_t &incast = dynamic_cast<logic_input_t &>(in);
pstring x = plib::pfmt("proxy_ad_{1}_{2}")(in.name())( m_proxy_cnt);
auto proxy = plib::powned_ptr<devices::nld_a_to_d_proxy>::Create(netlist(), x, &incast);
auto proxy = plib::owned_ptr<devices::nld_a_to_d_proxy>::Create(netlist(), x, &incast);
incast.set_proxy(proxy.get());
m_proxy_cnt++;
proxy->m_Q.net().register_con(in);
out.net().register_con(proxy->m_I);
register_dev_s(std::move(proxy));
register_dev(std::move(proxy));
}
else if (out.is_logic() && in.is_analog())
@ -567,7 +523,7 @@ void setup_t::connect_terminal_input(terminal_t &term, core_terminal_t &inp)
logic_input_t &incast = dynamic_cast<logic_input_t &>(inp);
log().debug("connect_terminal_input: connecting proxy\n");
pstring x = plib::pfmt("proxy_ad_{1}_{2}")(inp.name())(m_proxy_cnt);
auto proxy = plib::powned_ptr<devices::nld_a_to_d_proxy>::Create(netlist(), x, &incast);
auto proxy = plib::owned_ptr<devices::nld_a_to_d_proxy>::Create(netlist(), x, &incast);
incast.set_proxy(proxy.get());
m_proxy_cnt++;
@ -579,7 +535,7 @@ void setup_t::connect_terminal_input(terminal_t &term, core_terminal_t &inp)
else
proxy->m_Q.net().register_con(inp);
register_dev_s(std::move(proxy));
register_dev(std::move(proxy));
}
else
{
@ -659,9 +615,9 @@ bool setup_t::connect_input_input(core_terminal_t &t1, core_terminal_t &t2)
ret = connect(t2, t1.net().railterminal());
if (!ret)
{
for (core_terminal_t *t : t1.net().m_core_terms)
for (auto & t : t1.net().m_core_terms)
{
if (t->isType(core_terminal_t::TERMINAL))
if (t->is_type(core_terminal_t::TERMINAL))
ret = connect(t2, *t);
if (ret)
break;
@ -674,9 +630,9 @@ bool setup_t::connect_input_input(core_terminal_t &t1, core_terminal_t &t2)
ret = connect(t1, t2.net().railterminal());
if (!ret)
{
for (core_terminal_t *t : t2.net().m_core_terms)
for (auto & t : t2.net().m_core_terms)
{
if (t->isType(core_terminal_t::TERMINAL))
if (t->is_type(core_terminal_t::TERMINAL))
ret = connect(t1, *t);
if (ret)
break;
@ -695,39 +651,39 @@ bool setup_t::connect(core_terminal_t &t1_in, core_terminal_t &t2_in)
core_terminal_t &t2 = resolve_proxy(t2_in);
bool ret = true;
if (t1.isType(core_terminal_t::OUTPUT) && t2.isType(core_terminal_t::INPUT))
if (t1.is_type(core_terminal_t::OUTPUT) && t2.is_type(core_terminal_t::INPUT))
{
if (t2.has_net() && t2.net().isRailNet())
log().fatal("Input {1} already connected\n", t2.name());
connect_input_output(t2, t1);
}
else if (t1.isType(core_terminal_t::INPUT) && t2.isType(core_terminal_t::OUTPUT))
else if (t1.is_type(core_terminal_t::INPUT) && t2.is_type(core_terminal_t::OUTPUT))
{
if (t1.has_net() && t1.net().isRailNet())
log().fatal("Input {1} already connected\n", t1.name());
connect_input_output(t1, t2);
}
else if (t1.isType(core_terminal_t::OUTPUT) && t2.isType(core_terminal_t::TERMINAL))
else if (t1.is_type(core_terminal_t::OUTPUT) && t2.is_type(core_terminal_t::TERMINAL))
{
connect_terminal_output(dynamic_cast<terminal_t &>(t2), t1);
}
else if (t1.isType(core_terminal_t::TERMINAL) && t2.isType(core_terminal_t::OUTPUT))
else if (t1.is_type(core_terminal_t::TERMINAL) && t2.is_type(core_terminal_t::OUTPUT))
{
connect_terminal_output(dynamic_cast<terminal_t &>(t1), t2);
}
else if (t1.isType(core_terminal_t::INPUT) && t2.isType(core_terminal_t::TERMINAL))
else if (t1.is_type(core_terminal_t::INPUT) && t2.is_type(core_terminal_t::TERMINAL))
{
connect_terminal_input(dynamic_cast<terminal_t &>(t2), t1);
}
else if (t1.isType(core_terminal_t::TERMINAL) && t2.isType(core_terminal_t::INPUT))
else if (t1.is_type(core_terminal_t::TERMINAL) && t2.is_type(core_terminal_t::INPUT))
{
connect_terminal_input(dynamic_cast<terminal_t &>(t1), t2);
}
else if (t1.isType(core_terminal_t::TERMINAL) && t2.isType(core_terminal_t::TERMINAL))
else if (t1.is_type(core_terminal_t::TERMINAL) && t2.is_type(core_terminal_t::TERMINAL))
{
connect_terminals(dynamic_cast<terminal_t &>(t1), dynamic_cast<terminal_t &>(t2));
}
else if (t1.isType(core_terminal_t::INPUT) && t2.isType(core_terminal_t::INPUT))
else if (t1.is_type(core_terminal_t::INPUT) && t2.is_type(core_terminal_t::INPUT))
{
ret = connect_input_input(t1, t2);
}
@ -767,8 +723,8 @@ void setup_t::resolve_inputs()
}
if (tries == 0)
{
for (std::size_t i = 0; i < m_links.size(); i++ )
log().warning("Error connecting {1} to {2}\n", m_links[i].first, m_links[i].second);
for (auto & link : m_links)
log().warning("Error connecting {1} to {2}\n", link.first, link.second);
log().fatal("Error connecting -- bailing out\n");
}
@ -811,17 +767,12 @@ void setup_t::resolve_inputs()
log().verbose("looking for two terms connected to rail nets ...\n");
// FIXME: doesn't find internal devices. This needs to be more clever
for (std::size_t i=0; i < netlist().m_devices.size(); i++)
for (auto & t : netlist().get_device_list<devices::NETLIB_NAME(twoterm)>())
{
devices::NETLIB_NAME(twoterm) *t = dynamic_cast<devices::NETLIB_NAME(twoterm) *>(netlist().m_devices[i].get());
if (t != nullptr)
{
has_twoterms = true;
if (t->m_N.net().isRailNet() && t->m_P.net().isRailNet())
log().warning("Found device {1} connected only to railterminals {2}/{3}\n",
t->name(), t->m_N.net().name(), t->m_P.net().name());
}
has_twoterms = true;
if (t->m_N.net().isRailNet() && t->m_P.net().isRailNet())
log().warning("Found device {1} connected only to railterminals {2}/{3}\n",
t->name(), t->m_N.net().name(), t->m_P.net().name());
}
log().verbose("initialize solver ...\n");
@ -844,7 +795,7 @@ void setup_t::resolve_inputs()
void setup_t::start_devices()
{
pstring env = nl_util::environment("NL_LOGS");
pstring env = plib::util::environment("NL_LOGS");
if (env != "")
{
@ -853,14 +804,13 @@ void setup_t::start_devices()
for (pstring ll : loglist)
{
pstring name = "log_" + ll;
auto nc = factory().new_device_by_name("LOG", netlist(), name);
auto nc = factory().factory_by_name("LOG")->Create(netlist(), name);
register_link(name + ".I", ll);
log().debug(" dynamic link {1}: <{2}>\n",ll, name);
register_dev_s(std::move(nc));
register_dev(std::move(nc));
}
}
netlist().start();
}
@ -872,10 +822,10 @@ class logic_family_std_proxy_t : public logic_family_desc_t
{
public:
logic_family_std_proxy_t() { }
virtual plib::powned_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_t &anetlist,
virtual plib::owned_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_t &anetlist,
const pstring &name, logic_output_t *proxied) const override
{
return plib::powned_ptr<devices::nld_base_d_to_a_proxy>::Create<devices::nld_d_to_a_proxy>(anetlist, name, proxied);
return plib::owned_ptr<devices::nld_base_d_to_a_proxy>::Create<devices::nld_d_to_a_proxy>(anetlist, name, proxied);
}
};

View File

@ -9,6 +9,7 @@
#define NLSETUP_H_
#include <memory>
#include <stack>
#include "nl_base.h"
#include "nl_factory.h"
@ -46,10 +47,10 @@
#define NETLIST_NAME(name) netlist ## _ ## name
#define NETLIST_EXTERNAL(name) \
ATTR_COLD void NETLIST_NAME(name)(netlist::setup_t &setup);
void NETLIST_NAME(name)(netlist::setup_t &setup);
#define NETLIST_START(name) \
ATTR_COLD void NETLIST_NAME(name)(netlist::setup_t &setup) \
void NETLIST_NAME(name)(netlist::setup_t &setup) \
{
#define NETLIST_END() }
@ -113,16 +114,9 @@ namespace netlist
void register_and_set_param(pstring name, param_t &param);
void register_object(device_t &dev, const pstring &name, object_t &obj);
void register_term(core_terminal_t &obj);
template<class NETLIST_X>
void register_dev_s(plib::powned_ptr<NETLIST_X> dev)
{
register_dev(std::move(dev));
}
void register_dev(plib::powned_ptr<device_t> dev);
void register_dev(plib::owned_ptr<device_t> dev);
void register_dev(const pstring &classname, const pstring &name);
void register_lib_entry(const pstring &name);
@ -202,7 +196,7 @@ namespace netlist
bool connect_input_input(core_terminal_t &t1, core_terminal_t &t2);
// helpers
pstring objtype_as_astr(object_t &in) const;
pstring objtype_as_str(object_t &in) const;
const pstring resolve_alias(const pstring &name) const;
devices::nld_base_proxy *get_d_a_proxy(core_terminal_t &out);

View File

@ -17,18 +17,15 @@
#define NLTIME_FROM_NS(t) netlist_time::from_nsec(t)
#define NLTIME_FROM_US(t) netlist_time::from_usec(t)
#define NLTIME_FROM_MS(t) netlist_time::from_msec(t)
#define NLTIME_IMMEDIATE netlist_time::from_nsec(1)
#define NLTIME_IMMEDIATE netlist_time::from_nsec(1)
// ----------------------------------------------------------------------------------------
// net_list_time
// netlist_time
// ----------------------------------------------------------------------------------------
#undef ATTR_HOT
#define ATTR_HOT
namespace netlist
{
struct netlist_time
struct netlist_time final
{
public:
@ -37,111 +34,106 @@ namespace netlist
static const pstate_data_type_e STATETYPE = DT_INT128;
#else
using INTERNALTYPE = UINT64;
static const pstate_data_type_e STATETYPE = pstate_data_type_e::DT_INT64;
static constexpr pstate_data_type_e STATETYPE = pstate_data_type_e::DT_INT64;
#endif
static const INTERNALTYPE RESOLUTION = NETLIST_INTERNAL_RES;
static constexpr INTERNALTYPE RESOLUTION = NETLIST_INTERNAL_RES;
ATTR_HOT netlist_time() : m_time(0) {}
//ATTR_HOT netlist_time(const netlist_time &rhs) NOEXCEPT : m_time(rhs.m_time) {}
//ATTR_HOT netlist_time(netlist_time &&rhs) NOEXCEPT : m_time(rhs.m_time) {}
ATTR_HOT netlist_time(const netlist_time &rhs) NOEXCEPT = default;
ATTR_HOT netlist_time(netlist_time &&rhs) NOEXCEPT = default;
constexpr netlist_time() NOEXCEPT : m_time(0) {}
netlist_time(const netlist_time &rhs) NOEXCEPT = default;
netlist_time(netlist_time &&rhs) NOEXCEPT = default;
ATTR_HOT friend const netlist_time operator-(const netlist_time &left, const netlist_time &right);
ATTR_HOT friend const netlist_time operator+(const netlist_time &left, const netlist_time &right);
ATTR_HOT friend const netlist_time operator*(const netlist_time &left, const UINT64 factor);
ATTR_HOT friend UINT64 operator/(const netlist_time &left, const netlist_time &right);
ATTR_HOT friend bool operator>(const netlist_time &left, const netlist_time &right);
ATTR_HOT friend bool operator<(const netlist_time &left, const netlist_time &right);
ATTR_HOT friend bool operator>=(const netlist_time &left, const netlist_time &right);
ATTR_HOT friend bool operator<=(const netlist_time &left, const netlist_time &right);
ATTR_HOT friend bool operator!=(const netlist_time &left, const netlist_time &right);
ATTR_HOT friend bool operator==(const netlist_time &left, const netlist_time &right);
constexpr explicit netlist_time(const double t)
: m_time((INTERNALTYPE) ( t * (double) RESOLUTION)) { }
constexpr explicit netlist_time(const INTERNALTYPE nom, const INTERNALTYPE den)
: m_time(nom * (RESOLUTION / den)) { }
ATTR_HOT const netlist_time &operator=(const netlist_time &right) { m_time = right.m_time; return *this; }
ATTR_HOT const netlist_time &operator+=(const netlist_time &right) { m_time += right.m_time; return *this; }
netlist_time &operator=(const netlist_time rhs) { m_time = rhs.m_time; return *this; }
ATTR_HOT INTERNALTYPE as_raw() const { return m_time; }
ATTR_HOT double as_double() const { return (double) m_time / (double) RESOLUTION; }
netlist_time &operator+=(const netlist_time &rhs) { m_time += rhs.m_time; return *this; }
netlist_time &operator-=(const netlist_time &rhs) { m_time -= rhs.m_time; return *this; }
friend netlist_time operator-(netlist_time lhs, const netlist_time &rhs)
{
lhs -= rhs;
return lhs;
}
friend netlist_time operator+(netlist_time lhs, const netlist_time &rhs)
{
lhs += rhs;
return lhs;
}
friend netlist_time operator*(netlist_time lhs, const UINT64 factor)
{
lhs.m_time *= static_cast<INTERNALTYPE>(factor);
return lhs;
}
friend UINT64 operator/(const netlist_time &lhs, const netlist_time &rhs)
{
return static_cast<UINT64>(lhs.m_time / rhs.m_time);
}
friend bool operator<(const netlist_time &lhs, const netlist_time &rhs)
{
return (lhs.m_time < rhs.m_time);
}
friend bool operator>(const netlist_time &lhs, const netlist_time &rhs)
{
return rhs < lhs;
}
friend bool operator<=(const netlist_time &lhs, const netlist_time &rhs)
{
return !(lhs > rhs);
}
friend bool operator>=(const netlist_time &lhs, const netlist_time &rhs)
{
return !(lhs < rhs);
}
friend bool operator==(const netlist_time &lhs, const netlist_time &rhs)
{
return lhs.m_time == rhs.m_time;
}
friend bool operator!=(const netlist_time &lhs, const netlist_time &rhs)
{
return lhs.m_time != rhs.m_time;
}
INTERNALTYPE as_raw() const { return m_time; }
double as_double() const { return (double) m_time / (double) RESOLUTION; }
// for save states ....
ATTR_HOT INTERNALTYPE *get_internaltype_ptr() { return &m_time; }
INTERNALTYPE *get_internaltype_ptr() { return &m_time; }
ATTR_HOT static const netlist_time from_nsec(const INTERNALTYPE ns) { return netlist_time(ns * (RESOLUTION / U64(1000000000))); }
ATTR_HOT static const netlist_time from_usec(const INTERNALTYPE us) { return netlist_time(us * (RESOLUTION / U64(1000000))); }
ATTR_HOT static const netlist_time from_msec(const INTERNALTYPE ms) { return netlist_time(ms * (RESOLUTION / U64(1000))); }
ATTR_HOT static const netlist_time from_hz(const INTERNALTYPE hz) { return netlist_time(RESOLUTION / hz); }
ATTR_HOT static const netlist_time from_double(const double t) { return netlist_time((INTERNALTYPE) ( t * (double) RESOLUTION)); }
ATTR_HOT static const netlist_time from_raw(const INTERNALTYPE raw) { return netlist_time(raw); }
static const netlist_time zero;
protected:
ATTR_HOT netlist_time(const INTERNALTYPE val) : m_time(val) {}
static inline netlist_time from_nsec(const INTERNALTYPE ns) { return netlist_time(ns, U64(1000000000)); }
static inline netlist_time from_usec(const INTERNALTYPE us) { return netlist_time(us, U64(1000000)); }
static inline netlist_time from_msec(const INTERNALTYPE ms) { return netlist_time(ms, U64(1000)); }
static inline netlist_time from_hz(const INTERNALTYPE hz) { return netlist_time(1 , hz); }
static inline netlist_time from_raw(const INTERNALTYPE raw) { return netlist_time(raw, RESOLUTION); }
static inline netlist_time zero() { return netlist_time(0, RESOLUTION); }
static inline netlist_time quantum() { return netlist_time(1, RESOLUTION); }
static inline netlist_time never() { return netlist_time(std::numeric_limits<netlist_time::INTERNALTYPE>::max(), RESOLUTION); }
private:
INTERNALTYPE m_time;
};
ATTR_HOT inline const netlist_time operator-(const netlist_time &left, const netlist_time &right)
{
return netlist_time(left.m_time - right.m_time);
}
ATTR_HOT inline const netlist_time operator*(const netlist_time &left, const UINT64 factor)
{
return netlist_time(left.m_time * factor);
}
ATTR_HOT inline UINT64 operator/(const netlist_time &left, const netlist_time &right)
{
return left.m_time / right.m_time;
}
ATTR_HOT inline const netlist_time operator+(const netlist_time &left, const netlist_time &right)
{
return netlist_time(left.m_time + right.m_time);
}
ATTR_HOT inline bool operator<(const netlist_time &left, const netlist_time &right)
{
return (left.m_time < right.m_time);
}
ATTR_HOT inline bool operator>(const netlist_time &left, const netlist_time &right)
{
return (left.m_time > right.m_time);
}
ATTR_HOT inline bool operator<=(const netlist_time &left, const netlist_time &right)
{
return (left.m_time <= right.m_time);
}
ATTR_HOT inline bool operator>=(const netlist_time &left, const netlist_time &right)
{
return (left.m_time >= right.m_time);
}
ATTR_HOT inline bool operator!=(const netlist_time &left, const netlist_time &right)
{
return (left.m_time != right.m_time);
}
ATTR_HOT inline bool operator==(const netlist_time &left, const netlist_time &right)
{
return (left.m_time == right.m_time);
}
}
PLIB_NAMESPACE_START()
template<> ATTR_COLD inline void pstate_manager_t::save_item(netlist::netlist_time &nlt, const void *owner, const pstring &stname)
namespace plib {
template<> inline void pstate_manager_t::save_item(const void *owner, netlist::netlist_time &nlt, const pstring &stname)
{
save_state_ptr(stname, netlist::netlist_time::STATETYPE, owner, sizeof(netlist::netlist_time::INTERNALTYPE), 1, nlt.get_internaltype_ptr(), false);
save_state_ptr(owner, stname, netlist::netlist_time::STATETYPE, sizeof(netlist::netlist_time::INTERNALTYPE), 1, nlt.get_internaltype_ptr(), false);
}
}
PLIB_NAMESPACE_END()
#endif /* NLTIME_H_ */

View File

@ -1,128 +0,0 @@
// license:GPL-2.0+
// copyright-holders:Couriersud
/*
* nl_util.h
*
*/
#ifndef NL_UTIL_H_
#define NL_UTIL_H_
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <initializer_list>
#include "plib/pstring.h"
#include "plib/plists.h"
class nl_util
{
// this is purely static
private:
nl_util() {};
public:
static const pstring buildpath(std::initializer_list<pstring> list )
{
pstring ret = "";
for( auto elem : list )
{
if (ret == "")
ret = elem;
else
#ifdef WIN32
ret = ret + '\\' + elem;
#else
ret = ret + '/' + elem;
#endif
}
return ret;
}
static const pstring environment(const pstring &var, const pstring &default_val = "")
{
if (getenv(var.cstr()) == nullptr)
return default_val;
else
return pstring(getenv(var.cstr()));
}
};
class nl_math
{
// this is purely static
private:
nl_math() {};
public:
template <typename T>
static T abs(const T &x) { return std::abs(x); }
template <typename T>
static T max(const T &x, const T &y) { return std::max(x, y); }
template <typename T>
static T min(const T &x, const T &y) { return std::min(x, y); }
template <typename T>
static T log(const T &x) { return std::log(x); }
#if defined(MSC_VER) && MSC_VER < 1800
ATTR_HOT inline static double e_log1p(const double &x) { return nl_math::log(1.0 + x); }
ATTR_HOT inline static float e_log1p(const float &x) { return nl_math::log(1.0 + x); }
#else
template <typename T>
static T e_log1p(const T &x) { return log1p(x); }
#endif
template <typename T>
static T sqrt(const T &x) { return std::sqrt(x); }
template <typename T>
static T hypot(const T &x, const T &y) { return std::hypot(x, y); }
// this one has an accuracy of better than 5%. That's enough for our purpose
// add c3 and it'll be better than 1%
#if 0
ATTR_HOT inline static float exp(const float &x) { return std::exp(x); }
inline static double fastexp_h(const double &x)
{
/* static */ const double ln2r = 1.442695040888963387;
/* static */ const double ln2 = 0.693147180559945286;
/* static */ const double c3 = 0.166666666666666667;
/* static */ const double c4 = 1.0 / 24.0;
/* static */ const double c5 = 1.0 / 120.0;
const double y = x * ln2r;
const UINT32 t = y;
const double z = (x - ln2 * (double) t);
const double e = (1.0 + z * (1.0 + z * (0.5 + z * (c3 + z * (c4 + c5*z)))));
if (t < 63)
//return (double)((UINT64) 1 << t)*(1.0 + z + 0.5 * zz + c3 * zzz+c4*zzzz+c5*zzzzz);
return (double)((UINT64) 1 << t) * e;
else
return pow(2.0, t)*e;
}
ATTR_HOT inline static double exp(const double &x)
{
if (x<0)
return 1.0 / fastexp_h(-x);
else
return fastexp_h(x);
}
#else
template <typename T>
static double exp(const T &x) { return std::exp(x); }
#endif
};
#endif /* NL_UTIL_H_ */

View File

@ -10,7 +10,7 @@
#include "pconfig.h"
#include "palloc.h"
PLIB_NAMESPACE_START()
namespace plib {
//============================================================
// Exceptions
@ -22,11 +22,11 @@ pexception::pexception(const pstring &text)
fprintf(stderr, "%s\n", m_text.cstr());
}
pmempool::pmempool(int min_alloc, int min_align)
mempool::mempool(int min_alloc, int min_align)
: m_min_alloc(min_alloc), m_min_align(min_align)
{
}
pmempool::~pmempool()
mempool::~mempool()
{
for (auto & b : m_blocks)
{
@ -37,7 +37,7 @@ pmempool::~pmempool()
m_blocks.clear();
}
int pmempool::new_block()
int mempool::new_block()
{
block b;
b.data = new char[m_min_alloc];
@ -49,10 +49,10 @@ int pmempool::new_block()
}
void *pmempool::alloc(size_t size)
void *mempool::alloc(size_t size)
{
size_t rs = (size + sizeof(info) + m_min_align - 1) & ~(m_min_align - 1);
for (int bn=0; bn < m_blocks.size(); bn++)
for (size_t bn=0; bn < m_blocks.size(); bn++)
{
auto &b = m_blocks[bn];
if (b.m_free > rs)
@ -79,7 +79,7 @@ void *pmempool::alloc(size_t size)
}
}
void pmempool::free(void *ptr)
void mempool::free(void *ptr)
{
char *p = (char *) ptr;
@ -95,4 +95,4 @@ void pmempool::free(void *ptr)
b->m_num_alloc--;
}
PLIB_NAMESPACE_END()
}

View File

@ -36,7 +36,7 @@
#endif
PLIB_NAMESPACE_START()
namespace plib {
//============================================================
// exception base
@ -77,7 +77,7 @@ template<typename T>
void pfree_array(T *ptr) { delete [] ptr; }
template<typename T, typename... Args>
std::unique_ptr<T> pmake_unique(Args&&... args) {
std::unique_ptr<T> make_unique(Args&&... args) {
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
@ -89,19 +89,19 @@ static std::unique_ptr<BC> make_unique_base(Args&&... args)
}
template <typename SC>
class powned_ptr
class owned_ptr
{
private:
powned_ptr()
owned_ptr()
: m_ptr(nullptr), m_is_owned(true) { }
public:
powned_ptr(SC *p, bool owned)
owned_ptr(SC *p, bool owned)
: m_ptr(p), m_is_owned(owned)
{ }
powned_ptr(const powned_ptr &r) = delete;
powned_ptr & operator =(const powned_ptr &r) = delete;
owned_ptr(const owned_ptr &r) = delete;
owned_ptr & operator =(const owned_ptr &r) = delete;
powned_ptr(powned_ptr &&r)
owned_ptr(owned_ptr &&r)
{
m_is_owned = r.m_is_owned;
m_ptr = r.m_ptr;
@ -110,7 +110,7 @@ public:
}
template<typename DC>
powned_ptr(powned_ptr<DC> &&r)
owned_ptr(owned_ptr<DC> &&r)
{
SC *dest_ptr = &dynamic_cast<SC &>(*r.get());
bool o = r.is_owned();
@ -119,24 +119,24 @@ public:
m_ptr = dest_ptr;
}
~powned_ptr()
~owned_ptr()
{
if (m_is_owned)
delete m_ptr;
}
template<typename DC, typename... Args>
static powned_ptr Create(Args&&... args)
static owned_ptr Create(Args&&... args)
{
powned_ptr a;
owned_ptr a;
DC *x = new DC(std::forward<Args>(args)...);
a.m_ptr = static_cast<SC *>(x);
return a;
}
template<typename... Args>
static powned_ptr Create(Args&&... args)
static owned_ptr Create(Args&&... args)
{
powned_ptr a;
owned_ptr a;
a.m_ptr = new SC(std::forward<Args>(args)...);
return a;
}
@ -149,7 +149,7 @@ public:
bool is_owned() const { return m_is_owned; }
template<typename DC>
powned_ptr<DC> & operator =(powned_ptr<DC> &r)
owned_ptr<DC> & operator =(owned_ptr<DC> &r)
{
m_is_owned = r.m_is_owned;
m_ptr = r.m_ptr;
@ -157,15 +157,15 @@ public:
r.m_ptr = nullptr;
return *this;
}
SC * operator ->() { return m_ptr; }
SC & operator *() { return *m_ptr; }
SC * operator ->() const { return m_ptr; }
SC & operator *() const { return *m_ptr; }
SC * get() const { return m_ptr; }
private:
SC *m_ptr;
bool m_is_owned;
};
class pmempool
class mempool
{
private:
struct block
@ -186,8 +186,8 @@ private:
};
public:
pmempool(int min_alloc, int min_align);
~pmempool();
mempool(int min_alloc, int min_align);
~mempool();
void *alloc(size_t size);
void free(void *ptr);
@ -198,6 +198,6 @@ public:
std::vector<block> m_blocks;
};
PLIB_NAMESPACE_END()
}
#endif /* PALLOC_H_ */

View File

@ -27,9 +27,6 @@ typedef _uint128_t UINT128;
typedef _int128_t INT128;
#endif
#define PLIB_NAMESPACE_START() namespace plib {
#define PLIB_NAMESPACE_END() }
#if !(PSTANDALONE)
#include "osdcomm.h"
//#include "eminline.h"
@ -93,13 +90,7 @@ typedef _int128_t INT128;
#define MEMBER_ABI
#endif
/* not supported in GCC prior to 4.4.x */
#define ATTR_HOT __attribute__((hot))
#define ATTR_COLD __attribute__((cold))
#define RESTRICT __restrict__
#define EXPECTED(x) (x)
#define UNEXPECTED(x) (x)
#define ATTR_PRINTF(x,y) __attribute__((format(printf, x, y)))
#define ATTR_UNUSED __attribute__((__unused__))
@ -139,7 +130,7 @@ typedef int64_t INT64;
#endif
PLIB_NAMESPACE_START()
namespace plib {
using ticks_t = INT64;
@ -171,59 +162,59 @@ static inline ticks_t profile_ticks() { return ticks(); }
*/
#if (PHAS_PMF_INTERNAL)
class mfp
{
public:
// construct from any member function pointer
class generic_class;
using generic_function = void (*)();
template<typename MemberFunctionType>
mfp(MemberFunctionType mftp)
: m_function(0), m_this_delta(0)
class mfp
{
*reinterpret_cast<MemberFunctionType *>(this) = mftp;
}
public:
// construct from any member function pointer
class generic_class;
using generic_function = void (*)();
// binding helper
template<typename FunctionType, typename ObjectType>
FunctionType update_after_bind(ObjectType *object)
{
return reinterpret_cast<FunctionType>(
convert_to_generic(reinterpret_cast<generic_class *>(object)));
}
template<typename FunctionType, typename MemberFunctionType, typename ObjectType>
static FunctionType get_mfp(MemberFunctionType mftp, ObjectType *object)
{
mfp mfpo(mftp);
return mfpo.update_after_bind<FunctionType>(object);
}
template<typename MemberFunctionType>
mfp(MemberFunctionType mftp)
: m_function(0), m_this_delta(0)
{
*reinterpret_cast<MemberFunctionType *>(this) = mftp;
}
private:
// extract the generic function and adjust the object pointer
generic_function convert_to_generic(generic_class * object) const
{
// apply the "this" delta to the object first
generic_class * o_p_delta = reinterpret_cast<generic_class *>(reinterpret_cast<std::uint8_t *>(object) + m_this_delta);
// binding helper
template<typename FunctionType, typename ObjectType>
FunctionType update_after_bind(ObjectType *object)
{
return reinterpret_cast<FunctionType>(
convert_to_generic(reinterpret_cast<generic_class *>(object)));
}
template<typename FunctionType, typename MemberFunctionType, typename ObjectType>
static FunctionType get_mfp(MemberFunctionType mftp, ObjectType *object)
{
mfp mfpo(mftp);
return mfpo.update_after_bind<FunctionType>(object);
}
// if the low bit of the vtable index is clear, then it is just a raw function pointer
if (!(m_function & 1))
return reinterpret_cast<generic_function>(m_function);
private:
// extract the generic function and adjust the object pointer
generic_function convert_to_generic(generic_class * object) const
{
// apply the "this" delta to the object first
generic_class * o_p_delta = reinterpret_cast<generic_class *>(reinterpret_cast<std::uint8_t *>(object) + m_this_delta);
// otherwise, it is the byte index into the vtable where the actual function lives
std::uint8_t *vtable_base = *reinterpret_cast<std::uint8_t **>(o_p_delta);
return *reinterpret_cast<generic_function *>(vtable_base + m_function - 1);
}
// if the low bit of the vtable index is clear, then it is just a raw function pointer
if (!(m_function & 1))
return reinterpret_cast<generic_function>(m_function);
// actual state
uintptr_t m_function; // first item can be one of two things:
// if even, it's a pointer to the function
// if odd, it's the byte offset into the vtable
int m_this_delta; // delta to apply to the 'this' pointer
};
// otherwise, it is the byte index into the vtable where the actual function lives
std::uint8_t *vtable_base = *reinterpret_cast<std::uint8_t **>(o_p_delta);
return *reinterpret_cast<generic_function *>(vtable_base + m_function - 1);
}
// actual state
uintptr_t m_function; // first item can be one of two things:
// if even, it's a pointer to the function
// if odd, it's the byte offset into the vtable
int m_this_delta; // delta to apply to the 'this' pointer
};
#endif
PLIB_NAMESPACE_END()
}
#endif /* PCONFIG_H_ */

View File

@ -12,7 +12,7 @@
#include <dlfcn.h>
#endif
PLIB_NAMESPACE_START()
namespace plib {
dynlib::dynlib(const pstring libname)
: m_isLoaded(false), m_lib(nullptr)
@ -96,4 +96,4 @@ void *dynlib::getsym_p(const pstring name)
#endif
}
PLIB_NAMESPACE_END()
}

View File

@ -13,7 +13,7 @@
#include "pconfig.h"
#include "pstring.h"
PLIB_NAMESPACE_START()
namespace plib {
// ----------------------------------------------------------------------------------------
// pdynlib: dynamic loading of libraries ...
@ -40,6 +40,6 @@ private:
void *m_lib;
};
PLIB_NAMESPACE_END()
}
#endif /* PSTRING_H_ */

View File

@ -16,7 +16,7 @@
#include "pfmtlog.h"
#include "palloc.h"
PLIB_NAMESPACE_START()
namespace plib {
pfmt::pfmt(const pstring &fmt)
: m_str(m_str_buf), m_allocated(0), m_arg(0)
@ -48,30 +48,6 @@ pfmt::~pfmt()
pfree_array(m_str);
}
#if 0
void pformat::format_element(const char *f, const char *l, const char *fmt_spec, ...)
{
va_list ap;
va_start(ap, fmt_spec);
char fmt[30] = "%";
char search[10] = "";
char buf[1024];
strcat(fmt, f);
strcat(fmt, l);
strcat(fmt, fmt_spec);
int nl = vsprintf(buf, fmt, ap);
m_arg++;
int sl = sprintf(search, "%%%d", m_arg);
char *p = strstr(m_str, search);
if (p != nullptr)
{
// Make room
memmove(p+nl, p+sl, strlen(p) + 1 - sl);
memcpy(p, buf, nl);
}
va_end(ap);
}
#else
void pfmt::format_element(const char *f, const char *l, const char *fmt_spec, ...)
{
va_list ap;
@ -164,6 +140,5 @@ void pfmt::format_element(const char *f, const char *l, const char *fmt_spec, .
va_end(ap);
}
PLIB_NAMESPACE_END()
}
#endif

View File

@ -14,7 +14,7 @@
#include "pstring.h"
#include "ptypes.h"
PLIB_NAMESPACE_START()
namespace plib {
template <typename T>
struct ptype_treats
@ -108,21 +108,21 @@ public:
virtual ~pformat_base() { }
ATTR_COLD P &operator ()(const double x, const char *f = "") { format_element(f, "", "f", x); return static_cast<P &>(*this); }
ATTR_COLD P & e(const double x, const char *f = "") { format_element(f, "", "e", x); return static_cast<P &>(*this); }
ATTR_COLD P & g(const double x, const char *f = "") { format_element(f, "", "g", x); return static_cast<P &>(*this); }
P &operator ()(const double x, const char *f = "") { format_element(f, "", "f", x); return static_cast<P &>(*this); }
P & e(const double x, const char *f = "") { format_element(f, "", "e", x); return static_cast<P &>(*this); }
P & g(const double x, const char *f = "") { format_element(f, "", "g", x); return static_cast<P &>(*this); }
ATTR_COLD P &operator ()(const float x, const char *f = "") { format_element(f, "", "f", x); return static_cast<P &>(*this); }
ATTR_COLD P & e(const float x, const char *f = "") { format_element(f, "", "e", x); return static_cast<P &>(*this); }
ATTR_COLD P & g(const float x, const char *f = "") { format_element(f, "", "g", x); return static_cast<P &>(*this); }
P &operator ()(const float x, const char *f = "") { format_element(f, "", "f", x); return static_cast<P &>(*this); }
P & e(const float x, const char *f = "") { format_element(f, "", "e", x); return static_cast<P &>(*this); }
P & g(const float x, const char *f = "") { format_element(f, "", "g", x); return static_cast<P &>(*this); }
ATTR_COLD P &operator ()(const char *x, const char *f = "") { format_element(f, "", "s", x); return static_cast<P &>(*this); }
ATTR_COLD P &operator ()(char *x, const char *f = "") { format_element(f, "", "s", x); return static_cast<P &>(*this); }
ATTR_COLD P &operator ()(const void *x, const char *f = "") { format_element(f, "", "p", x); return static_cast<P &>(*this); }
ATTR_COLD P &operator ()(const pstring &x, const char *f = "") { format_element(f, "", "s", x.cstr() ); return static_cast<P &>(*this); }
P &operator ()(const char *x, const char *f = "") { format_element(f, "", "s", x); return static_cast<P &>(*this); }
P &operator ()(char *x, const char *f = "") { format_element(f, "", "s", x); return static_cast<P &>(*this); }
P &operator ()(const void *x, const char *f = "") { format_element(f, "", "p", x); return static_cast<P &>(*this); }
P &operator ()(const pstring &x, const char *f = "") { format_element(f, "", "s", x.cstr() ); return static_cast<P &>(*this); }
template<typename T>
ATTR_COLD P &operator ()(const T x, const char *f = "")
P &operator ()(const T x, const char *f = "")
{
if (ptype_treats<T>::is_signed)
format_element(f, ptype_treats<T>::size_specifier(), "d", ptype_treats<T>::cast(x));
@ -132,14 +132,14 @@ public:
}
template<typename T>
ATTR_COLD P &x(const T x, const char *f = "")
P &x(const T x, const char *f = "")
{
format_element(f, ptype_treats<T>::size_specifier(), "x", x);
return static_cast<P &>(*this);
}
template<typename T>
ATTR_COLD P &o(const T x, const char *f = "")
P &o(const T x, const char *f = "")
{
format_element(f, ptype_treats<T>::size_specifier(), "o", x);
return static_cast<P &>(*this);
@ -191,37 +191,37 @@ public:
pfmt_writer_t() : m_enabled(true) { }
virtual ~pfmt_writer_t() { }
ATTR_COLD void operator ()(const char *fmt) const
void operator ()(const char *fmt) const
{
if (build_enabled && m_enabled) vdowrite(fmt);
}
template<typename T1>
ATTR_COLD void operator ()(const char *fmt, const T1 &v1) const
void operator ()(const char *fmt, const T1 &v1) const
{
if (build_enabled && m_enabled) vdowrite(pfmt(fmt)(v1));
}
template<typename T1, typename T2>
ATTR_COLD void operator ()(const char *fmt, const T1 &v1, const T2 &v2) const
void operator ()(const char *fmt, const T1 &v1, const T2 &v2) const
{
if (build_enabled && m_enabled) vdowrite(pfmt(fmt)(v1)(v2));
}
template<typename T1, typename T2, typename T3>
ATTR_COLD void operator ()(const char *fmt, const T1 &v1, const T2 &v2, const T3 &v3) const
void operator ()(const char *fmt, const T1 &v1, const T2 &v2, const T3 &v3) const
{
if (build_enabled && m_enabled) vdowrite(pfmt(fmt)(v1)(v2)(v3));
}
template<typename T1, typename T2, typename T3, typename T4>
ATTR_COLD void operator ()(const char *fmt, const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4) const
void operator ()(const char *fmt, const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4) const
{
if (build_enabled && m_enabled) vdowrite(pfmt(fmt)(v1)(v2)(v3)(v4));
}
template<typename T1, typename T2, typename T3, typename T4, typename T5>
ATTR_COLD void operator ()(const char *fmt, const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5) const
void operator ()(const char *fmt, const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5) const
{
if (build_enabled && m_enabled) vdowrite(pfmt(fmt)(v1)(v2)(v3)(v4)(v5));
}
@ -295,7 +295,7 @@ void plog_channel<L, build_enabled>::vdowrite(const pstring &ls) const
m_base->vlog(L, ls);
}
PLIB_NAMESPACE_END()
}
#endif /* PSTRING_H_ */

View File

@ -10,81 +10,64 @@
#ifndef PLISTS_H_
#define PLISTS_H_
#include <cstring>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <type_traits>
//#include <cstring>
//#include <array>
#include "palloc.h"
#include "pstring.h"
PLIB_NAMESPACE_START()
namespace plib {
// ----------------------------------------------------------------------------------------
// parray_t: dynamic array
// ----------------------------------------------------------------------------------------
/* ----------------------------------------------------------------------------------------
* uninitialised_array_t:
* fixed size array allowing to override constructor and initialize
* members by placement new.
*
* Use with care. This template is provided to improve locality of storage
* in high frequency applications. It should not be used for anything else.
* ---------------------------------------------------------------------------------------- */
template <class LC>
class array_t
template <class C, std::size_t N>
class uninitialised_array_t
{
public:
ATTR_COLD array_t(std::size_t numElements)
: m_list(0), m_capacity(0)
uninitialised_array_t()
{
set_capacity(numElements);
}
ATTR_COLD array_t(const array_t &rhs)
: m_list(0), m_capacity(0)
~uninitialised_array_t()
{
set_capacity(rhs.size());
for (std::size_t i=0; i<m_capacity; i++)
m_list[i] = rhs[i];
for (std::size_t i=0; i<N; i++)
(*this)[i].~C();
}
ATTR_COLD array_t &operator=(const array_t &rhs)
size_t size() { return N; }
C& operator[](const std::size_t &index)
{
set_capacity(rhs.size());
for (std::size_t i=0; i<m_capacity; i++)
m_list[i] = rhs[i];
return *this;
return *reinterpret_cast<C *>(&m_buf[index]);
}
~array_t()
const C& operator[](const std::size_t &index) const
{
if (m_list != nullptr)
pfree_array(m_list);
m_list = nullptr;
return *reinterpret_cast<C *>(&m_buf[index]);
}
ATTR_HOT LC& operator[](const std::size_t index) { return m_list[index]; }
ATTR_HOT const LC& operator[](const std::size_t index) const { return m_list[index]; }
ATTR_HOT std::size_t size() const { return m_capacity; }
void resize(const std::size_t new_size)
template<typename... Args>
void emplace(const std::size_t index, Args&&... args)
{
set_capacity(new_size);
new (&m_buf[index]) C(std::forward<Args>(args)...);
}
protected:
ATTR_COLD void set_capacity(const std::size_t new_capacity)
{
if (m_list != nullptr)
pfree_array(m_list);
if (new_capacity > 0)
m_list = palloc_array<LC>(new_capacity);
else
m_list = nullptr;
m_capacity = new_capacity;
}
private:
LC * m_list;
int m_capacity;
/* ensure proper alignment */
typename std::aligned_storage<sizeof(C), alignof(C)>::type m_buf[N];
};
// ----------------------------------------------------------------------------------------
@ -97,15 +80,6 @@ class pvector_t : public std::vector<LC>
public:
pvector_t() : std::vector<LC>() {}
void clear_and_free()
{
for (LC i : *this)
{
pfree(i);
}
this->clear();
}
bool contains(const LC &elem) const
{
return (std::find(this->begin(), this->end(), elem) != this->end());
@ -116,19 +90,19 @@ public:
this->erase(std::remove(this->begin(), this->end(), elem), this->end());
}
ATTR_HOT void insert_at(const std::size_t index, const LC &elem)
void insert_at(const std::size_t index, const LC &elem)
{
this->insert(this->begin() + index, elem);
}
ATTR_HOT void remove_at(const std::size_t pos)
void remove_at(const std::size_t pos)
{
this->erase(this->begin() + pos);
}
int indexof(const LC &elem) const
{
for (unsigned i = 0; i < this->size(); i++)
for (std::size_t i = 0; i < this->size(); i++)
{
if (this->at(i) == elem)
return i;
@ -143,241 +117,79 @@ public:
// the list allows insertions / deletions if used properly
// ----------------------------------------------------------------------------------------
template <class LC>
class linkedlist_t;
#if 1
template <class LC>
struct plinkedlist_element_t
{
public:
friend class linkedlist_t<LC>;
plinkedlist_element_t() : m_next(nullptr) {}
LC *next() const { return m_next; }
//private:
LC * m_next;
};
template <class LC>
class linkedlist_t
{
public:
struct element_t
{
public:
friend class linkedlist_t<LC>;
element_t() : m_next(nullptr) {}
LC *next() const { return m_next; }
private:
LC * m_next;
};
struct iter_t final : public std::iterator<std::forward_iterator_tag, LC>
{
LC* p;
public:
constexpr iter_t(LC* x) noexcept : p(x) {}
iter_t(const iter_t &rhs) noexcept = default;
iter_t(iter_t &&rhs) noexcept = default;
iter_t& operator++() noexcept {p = p->next();return *this;}
iter_t operator++(int) noexcept {iter_t tmp(*this); operator++(); return tmp;}
bool operator==(const iter_t& rhs) noexcept {return p==rhs.p;}
bool operator!=(const iter_t& rhs) noexcept {return p!=rhs.p;}
LC& operator*() noexcept {return *p;}
LC* operator->() noexcept {return p;}
};
linkedlist_t() : m_head(nullptr) {}
#if 0
ATTR_HOT void insert(const LC &before, LC &elem)
iter_t begin() const { return iter_t(m_head); }
constexpr iter_t end() const { return iter_t(nullptr); }
void push_front(LC *elem)
{
if (m_head == &before)
{
elem.m_next = m_head;
m_head = &elem;
}
else
{
LC *p = m_head;
while (p != nullptr)
{
if (p->m_next == &before)
{
elem->m_next = &before;
p->m_next = &elem;
return;
}
p = p->m_next;
}
//throw pexception("element not found");
}
}
#endif
ATTR_HOT void insert(LC &elem)
{
elem.m_next = m_head;
m_head = &elem;
elem->m_next = m_head;
m_head = elem;
}
ATTR_HOT void add(LC &elem)
void push_back(LC *elem)
{
LC **p = &m_head;
while (*p != nullptr)
{
p = &((*p)->m_next);
}
*p = &elem;
elem.m_next = nullptr;
*p = elem;
elem->m_next = nullptr;
}
ATTR_HOT void remove(const LC &elem)
void remove(const LC *elem)
{
LC **p;
for (p = &m_head; *p != &elem; p = &((*p)->m_next))
auto p = &m_head;
for ( ; *p != elem; p = &((*p)->m_next))
{
//nl_assert(*p != nullptr);
}
(*p) = elem.m_next;
(*p) = elem->m_next;
}
ATTR_HOT LC *first() const { return m_head; }
ATTR_HOT void clear() { m_head = nullptr; }
ATTR_HOT bool is_empty() const { return (m_head == nullptr); }
LC *front() const { return m_head; }
void clear() { m_head = nullptr; }
bool empty() const { return (m_head == nullptr); }
//private:
LC *m_head;
};
#else
template <class LC>
struct plinkedlist_element_t
{
public:
friend class linkedlist_t<LC>;
plinkedlist_element_t() : m_next(nullptr), m_prev(nullptr) {}
LC *next() const { return m_next; }
private:
LC * m_next;
LC * m_prev;
};
template <class LC>
class linkedlist_t
{
public:
linkedlist_t() : m_head(nullptr), m_tail(nullptr) {}
ATTR_HOT void insert(LC &elem)
{
if (m_head != nullptr)
m_head->m_prev = &elem;
elem.m_next = m_head;
elem.m_prev = nullptr;
m_head = &elem;
if (m_tail == nullptr)
m_tail = &elem;
}
ATTR_HOT void add(LC &elem)
{
if (m_tail != nullptr)
m_tail->m_next = &elem;
elem.m_prev = m_tail;
m_tail = &elem;
elem.m_next = nullptr;
if (m_head == nullptr)
m_head = &elem;
}
ATTR_HOT void remove(const LC &elem)
{
if (prev(elem) == nullptr)
{
m_head = next(elem);
if (m_tail == &elem)
m_tail = nullptr;
}
else
prev(elem)->m_next = next(elem);
if (next(elem) == nullptr)
{
m_tail = prev(elem);
if (m_head == &elem)
m_head = nullptr;
}
else
next(elem)->m_prev = prev(elem);
}
ATTR_HOT static LC *next(const LC &elem) { return static_cast<LC *>(elem.m_next); }
ATTR_HOT static LC *next(const LC *elem) { return static_cast<LC *>(elem->m_next); }
ATTR_HOT static LC *prev(const LC &elem) { return static_cast<LC *>(elem.m_prev); }
ATTR_HOT static LC *prev(const LC *elem) { return static_cast<LC *>(elem->m_prev); }
ATTR_HOT LC *first() const { return m_head; }
ATTR_HOT void clear() { m_head = m_tail = nullptr; }
ATTR_HOT bool is_empty() const { return (m_head == nullptr); }
private:
LC *m_head;
LC *m_tail;
};
#endif
// ----------------------------------------------------------------------------------------
// string list
// ----------------------------------------------------------------------------------------
class pstring_vector_t : public pvector_t<pstring>
{
public:
pstring_vector_t() : pvector_t<pstring>() { }
pstring_vector_t(const pstring &str, const pstring &onstr, bool ignore_empty = false)
: pvector_t<pstring>()
{
int p = 0;
int pn;
pn = str.find(onstr, p);
while (pn>=0)
{
pstring t = str.substr(p, pn - p);
if (!ignore_empty || t.len() != 0)
this->push_back(t);
p = pn + onstr.len();
pn = str.find(onstr, p);
}
if (p < (int) str.len())
{
pstring t = str.substr(p);
if (!ignore_empty || t.len() != 0)
this->push_back(t);
}
}
pstring_vector_t(const pstring &str, const pstring_vector_t &onstrl)
: pvector_t<pstring>()
{
pstring col = "";
unsigned i = 0;
while (i<str.blen())
{
int p = -1;
for (std::size_t j=0; j < onstrl.size(); j++)
{
if (std::memcmp(onstrl[j].cstr(), &(str.cstr()[i]), onstrl[j].blen())==0)
{
p = j;
break;
}
}
if (p>=0)
{
if (col != "")
this->push_back(col);
col = "";
this->push_back(onstrl[p]);
i += onstrl[p].blen();
}
else
{
pstring::traits::code_t c = pstring::traits::code(str.cstr() + i);
col += c;
i+=pstring::traits::codelen(c);
}
}
if (col != "")
this->push_back(col);
}
};
// ----------------------------------------------------------------------------------------
// hashmap list
@ -597,7 +409,7 @@ private:
}
pvector_t<element_t> m_values;
array_t<int> m_hash;
std::vector<int> m_hash;
};
// ----------------------------------------------------------------------------------------
@ -617,6 +429,6 @@ static inline void sort_list(T &sl)
}
}
PLIB_NAMESPACE_END()
}
#endif /* PLISTS_H_ */

View File

@ -14,8 +14,9 @@
#include "pstring.h"
#include "plists.h"
#include "putil.h"
PLIB_NAMESPACE_START()
namespace plib {
/***************************************************************************
Options
@ -82,7 +83,7 @@ public:
pstring operator ()() { return m_val; }
private:
pstring m_val;
pstring_vector_t m_limit;
plib::pstring_vector_t m_limit;
};
class option_bool : public option
@ -182,9 +183,8 @@ public:
{
pstring ret;
for (std::size_t i=0; i<m_opts.size(); i++ )
for (auto & opt : m_opts )
{
option *opt = m_opts[i];
pstring line = "";
if (opt->m_short != "")
line += " -" + opt->m_short;
@ -207,19 +207,19 @@ private:
option *getopt_short(pstring arg)
{
for (std::size_t i=0; i < m_opts.size(); i++)
for (auto & opt : m_opts)
{
if (m_opts[i]->m_short == arg)
return m_opts[i];
if (opt->m_short == arg)
return opt;
}
return nullptr;
}
option *getopt_long(pstring arg)
{
for (std::size_t i=0; i < m_opts.size(); i++)
for (auto & opt : m_opts)
{
if (m_opts[i]->m_long == arg)
return m_opts[i];
if (opt->m_long == arg)
return opt;
}
return nullptr;
}
@ -235,6 +235,6 @@ option::option(pstring ashort, pstring along, pstring help, bool has_argument, o
parent->register_option(this);
}
PLIB_NAMESPACE_END()
}
#endif /* POPTIONS_H_ */

View File

@ -9,7 +9,7 @@
#include "pparser.h"
PLIB_NAMESPACE_START()
namespace plib {
// ----------------------------------------------------------------------------------------
// A simple tokenizer
// ----------------------------------------------------------------------------------------
@ -243,7 +243,7 @@ ptokenizer::token_t ptokenizer::get_token_internal()
}
ATTR_COLD void ptokenizer::error(const pstring &errs)
void ptokenizer::error(const pstring &errs)
{
verror("Error: " + errs, currentline_no(), currentline_str());
//throw error;
@ -360,13 +360,13 @@ pstring ppreprocessor::replace_macros(const pstring &line)
{
pstring_vector_t elems(line, m_expr_sep);
pstringbuffer ret = "";
for (std::size_t i=0; i<elems.size(); i++)
for (auto & elem : elems)
{
define_t *def = get_define(elems[i]);
define_t *def = get_define(elem);
if (def != nullptr)
ret.cat(def->m_replace);
else
ret.cat(elems[i]);
ret.cat(elem);
}
return ret;
}
@ -374,9 +374,9 @@ pstring ppreprocessor::replace_macros(const pstring &line)
static pstring catremainder(const pstring_vector_t &elems, std::size_t start, pstring sep)
{
pstringbuffer ret = "";
for (std::size_t i=start; i<elems.size(); i++)
for (auto & elem : elems)
{
ret.cat(elems[i]);
ret.cat(elem);
ret.cat(sep);
}
return ret;
@ -470,4 +470,4 @@ postream & ppreprocessor::process_i(pistream &istrm, postream &ostrm)
return ostrm;
}
PLIB_NAMESPACE_END()
}

View File

@ -11,9 +11,10 @@
#include "pconfig.h"
#include "pstring.h"
#include "plists.h"
#include "putil.h"
#include "pstream.h"
PLIB_NAMESPACE_START()
namespace plib {
class ptokenizer
{
@ -176,7 +177,7 @@ protected:
postream &process_i(pistream &istrm, postream &ostrm);
double expr(const pstring_vector_t &sexpr, std::size_t &start, int prio);
double expr(const plib::pstring_vector_t &sexpr, std::size_t &start, int prio);
define_t *get_define(const pstring &name);
@ -189,7 +190,7 @@ private:
pstring process_line(const pstring &line);
hashmap_t<pstring, define_t> m_defines;
pstring_vector_t m_expr_sep;
plib::pstring_vector_t m_expr_sep;
//pstringbuffer m_ret;
UINT32 m_ifflag; // 31 if levels
@ -197,6 +198,6 @@ private:
int m_lineno;
};
PLIB_NAMESPACE_END()
}
#endif /* PPARSER_H_ */

View File

@ -7,7 +7,7 @@
#include "pstate.h"
PLIB_NAMESPACE_START()
namespace plib {
pstate_manager_t::pstate_manager_t()
{
@ -20,7 +20,7 @@ pstate_manager_t::~pstate_manager_t()
ATTR_COLD void pstate_manager_t::save_state_ptr(const pstring &stname, const pstate_data_type_e dt, const void *owner, const int size, const int count, void *ptr, bool is_ptr)
void pstate_manager_t::save_state_ptr(const void *owner, const pstring &stname, const pstate_data_type_e dt, const int size, const int count, void *ptr, bool is_ptr)
{
pstring fullname = stname;
ATTR_UNUSED pstring ts[] = {
@ -38,11 +38,11 @@ ATTR_COLD void pstate_manager_t::save_state_ptr(const pstring &stname, const pst
"DT_FLOAT"
};
auto p = pmake_unique<pstate_entry_t>(stname, dt, owner, size, count, ptr, is_ptr);
auto p = plib::make_unique<pstate_entry_t>(stname, dt, owner, size, count, ptr, is_ptr);
m_save.push_back(std::move(p));
}
ATTR_COLD void pstate_manager_t::remove_save_items(const void *owner)
void pstate_manager_t::remove_save_items(const void *owner)
{
unsigned i = 0;
while (i < m_save.size())
@ -54,27 +54,27 @@ ATTR_COLD void pstate_manager_t::remove_save_items(const void *owner)
}
}
ATTR_COLD void pstate_manager_t::pre_save()
void pstate_manager_t::pre_save()
{
for (std::size_t i=0; i < m_save.size(); i++)
if (m_save[i]->m_dt == DT_CUSTOM)
m_save[i]->m_callback->on_pre_save();
for (auto & s : m_save)
if (s->m_dt == DT_CUSTOM)
s->m_callback->on_pre_save();
}
ATTR_COLD void pstate_manager_t::post_load()
void pstate_manager_t::post_load()
{
for (std::size_t i=0; i < m_save.size(); i++)
if (m_save[i]->m_dt == DT_CUSTOM)
m_save[i]->m_callback->on_post_load();
for (auto & s : m_save)
if (s->m_dt == DT_CUSTOM)
s->m_callback->on_post_load();
}
template<> ATTR_COLD void pstate_manager_t::save_item(pstate_callback_t &state, const void *owner, const pstring &stname)
template<> void pstate_manager_t::save_item(const void *owner, pstate_callback_t &state, const pstring &stname)
{
//save_state_ptr(stname, DT_CUSTOM, 0, 1, &state);
pstate_callback_t *state_p = &state;
auto p = pmake_unique<pstate_entry_t>(stname, owner, state_p);
auto p = plib::make_unique<pstate_entry_t>(stname, owner, state_p);
m_save.push_back(std::move(p));
state.register_state(*this, stname);
}
PLIB_NAMESPACE_END()
}

View File

@ -68,7 +68,7 @@ NETLIST_SAVE_TYPE(UINT16, DT_INT16);
NETLIST_SAVE_TYPE(INT16, DT_INT16);
//NETLIST_SAVE_TYPE(std::size_t, DT_INT64);
PLIB_NAMESPACE_START()
namespace plib {
class pstate_manager_t;
@ -124,34 +124,34 @@ public:
pstate_manager_t();
~pstate_manager_t();
template<typename C> ATTR_COLD void save_item(C &state, const void *owner, const pstring &stname)
template<typename C> void save_item(const void *owner, C &state, const pstring &stname)
{
save_state_ptr(stname, pstate_datatype<C>::type, owner, sizeof(C), 1, &state, pstate_datatype<C>::is_ptr);
save_state_ptr( owner, stname, pstate_datatype<C>::type, sizeof(C), 1, &state, pstate_datatype<C>::is_ptr);
}
template<typename C, std::size_t N> ATTR_COLD void save_item(C (&state)[N], const void *owner, const pstring &stname)
template<typename C, std::size_t N> void save_item(const void *owner, C (&state)[N], const pstring &stname)
{
save_state_ptr(stname, pstate_datatype<C>::type, owner, sizeof(state[0]), N, &(state[0]), false);
save_state_ptr(owner, stname, pstate_datatype<C>::type, sizeof(state[0]), N, &(state[0]), false);
}
template<typename C> ATTR_COLD void save_item(C *state, const void *owner, const pstring &stname, const int count)
template<typename C> void save_item(const void *owner, C *state, const pstring &stname, const int count)
{
save_state_ptr(stname, pstate_datatype<C>::type, owner, sizeof(C), count, state, false);
save_state_ptr(owner, stname, pstate_datatype<C>::type, sizeof(C), count, state, false);
}
template<typename C>
void save_item(std::vector<C> &v, const void *owner, const pstring &stname)
void save_item(const void *owner, std::vector<C> &v, const pstring &stname)
{
save_state(v.data(), owner, stname, v.size());
}
ATTR_COLD void pre_save();
ATTR_COLD void post_load();
ATTR_COLD void remove_save_items(const void *owner);
void pre_save();
void post_load();
void remove_save_items(const void *owner);
const pstate_entry_t::list_t &save_list() const { return m_save; }
ATTR_COLD void save_state_ptr(const pstring &stname, const pstate_data_type_e, const void *owner, const int size, const int count, void *ptr, bool is_ptr);
void save_state_ptr(const void *owner, const pstring &stname, const pstate_data_type_e, const int size, const int count, void *ptr, bool is_ptr);
protected:
@ -159,7 +159,7 @@ private:
pstate_entry_t::list_t m_save;
};
template<> ATTR_COLD void pstate_manager_t::save_item(pstate_callback_t &state, const void *owner, const pstring &stname);
template<> void pstate_manager_t::save_item(const void *owner, pstate_callback_t &state, const pstring &stname);
template <typename T>
class pstate_interface_t
@ -169,24 +169,24 @@ public:
template<typename C> void save(C &state, const pstring &stname)
{
pstate_manager_t *manager = static_cast<T*>(this)->state_manager();
pstate_manager_t &manager = static_cast<T*>(this)->state_manager();
pstring module = static_cast<T*>(this)->name();
manager->save_item(state, this, module + "." + stname);
manager.save_item(this, state, module + "." + stname);
}
template<typename C, std::size_t N> ATTR_COLD void save(C (&state)[N], const pstring &stname)
template<typename C, std::size_t N> void save(C (&state)[N], const pstring &stname)
{
pstate_manager_t *manager = static_cast<T*>(this)->state_manager();
pstate_manager_t &manager = static_cast<T*>(this)->state_manager();
pstring module = static_cast<T*>(this)->name();
manager->save_state_ptr(module + "." + stname, pstate_datatype<C>::type, this, sizeof(state[0]), N, &(state[0]), false);
manager.save_state_ptr(this, module + "." + stname, pstate_datatype<C>::type, sizeof(state[0]), N, &(state[0]), false);
}
template<typename C> ATTR_COLD void save(C *state, const pstring &stname, const int count)
template<typename C> void save(C *state, const pstring &stname, const int count)
{
pstate_manager_t *manager = static_cast<T*>(this)->state_manager();
pstate_manager_t &manager = static_cast<T*>(this)->state_manager();
pstring module = static_cast<T*>(this)->name();
manager->save_state_ptr(module + "." + stname, pstate_datatype<C>::type, this, sizeof(C), count, state, false);
manager.save_state_ptr(this, module + "." + stname, pstate_datatype<C>::type, sizeof(C), count, state, false);
}
};
PLIB_NAMESPACE_END()
}
#endif /* PSTATE_H_ */

View File

@ -13,7 +13,7 @@
#include "pstream.h"
#include "palloc.h"
PLIB_NAMESPACE_START()
namespace plib {
// -----------------------------------------------------------------------------
// pistream: input stream
@ -363,4 +363,4 @@ pstream::pos_type pomemstream::vtell()
return m_pos;
}
PLIB_NAMESPACE_END()
}

Some files were not shown because too many files have changed in this diff Show More