diff options
75 files changed, 1604 insertions, 2059 deletions
diff --git a/nl_examples/cdelay.c b/nl_examples/cdelay.c index 6f396e8ca07..927a7cfe0a4 100644 --- a/nl_examples/cdelay.c +++ b/nl_examples/cdelay.c @@ -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) /* diff --git a/scripts/src/netlist.lua b/scripts/src/netlist.lua index fffb0e89d54..c038f14a28e 100644 --- a/scripts/src/netlist.lua +++ b/scripts/src/netlist.lua @@ -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", diff --git a/src/devices/machine/netlist.cpp b/src/devices/machine/netlist.cpp index 8cfba776257..bd65d0b2eef 100644 --- a/src/devices/machine/netlist.cpp +++ b/src/devices/machine/netlist.cpp @@ -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", ""); diff --git a/src/devices/machine/netlist.h b/src/devices/machine/netlist.h index c4b64204390..8eba71f8ba1 100644 --- a/src/devices/machine/netlist.h +++ b/src/devices/machine/netlist.h @@ -569,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) @@ -680,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: diff --git a/src/lib/netlist/analog/nld_bjt.cpp b/src/lib/netlist/analog/nld_bjt.cpp index a2fcc817371..80b6ffe107b 100644 --- a/src/lib/netlist/analog/nld_bjt.cpp +++ b/src/lib/netlist/analog/nld_bjt.cpp @@ -30,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: diff --git a/src/lib/netlist/analog/nld_opamps.cpp b/src/lib/netlist/analog/nld_opamps.cpp index 60eccba7457..932232a9ecb 100644 --- a/src/lib/netlist/analog/nld_opamps.cpp +++ b/src/lib/netlist/analog/nld_opamps.cpp @@ -60,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); diff --git a/src/lib/netlist/analog/nld_twoterm.cpp b/src/lib/netlist/analog/nld_twoterm.cpp index def0730b5aa..9a526c4c174 100644 --- a/src/lib/netlist/analog/nld_twoterm.cpp +++ b/src/lib/netlist/analog/nld_twoterm.cpp @@ -19,7 +19,7 @@ namespace netlist // generic_diode // ---------------------------------------------------------------------------------------- -ATTR_COLD generic_diode::generic_diode() +generic_diode::generic_diode() { m_Vd = 0.7; set_param(1e-15, 1, 1e-15); @@ -27,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"); @@ -69,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(); @@ -88,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; diff --git a/src/lib/netlist/analog/nld_twoterm.h b/src/lib/netlist/analog/nld_twoterm.h index 5eecdb05299..d94b1498a53 100644 --- a/src/lib/netlist/analog/nld_twoterm.h +++ b/src/lib/netlist/analog/nld_twoterm.h @@ -121,19 +121,19 @@ NETLIB_OBJECT(twoterm) 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); @@ -311,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) @@ -326,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; } @@ -334,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; diff --git a/src/lib/netlist/build/makefile b/src/lib/netlist/build/makefile index 93e54f0e517..c1729cc0c39 100644 --- a/src/lib/netlist/build/makefile +++ b/src/lib/netlist/build/makefile @@ -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 \ diff --git a/src/lib/netlist/devices/net_lib.cpp b/src/lib/netlist/devices/net_lib.cpp index 2a481daaf5d..15ae8bfed71 100644 --- a/src/lib/netlist/devices/net_lib.cpp +++ b/src/lib/netlist/devices/net_lib.cpp @@ -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)") diff --git a/src/lib/netlist/devices/nld_4020.cpp b/src/lib/netlist/devices/nld_4020.cpp index 31fd7ffae85..93916c344bc 100644 --- a/src/lib/netlist/devices/nld_4020.cpp +++ b/src/lib/netlist/devices/nld_4020.cpp @@ -20,8 +20,8 @@ namespace netlist 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_Q(*this, {{"Q1", "_Q2", "_Q3", "Q4", "Q5", "Q6", "Q7", "Q8", "Q9", + "Q10", "Q11", "Q12", "Q13", "Q14"}}) , m_cnt(0) { save(NLNAME(m_cnt)); @@ -36,7 +36,7 @@ namespace netlist NETLIB_UPDATEI(); public: - ATTR_HOT void update_outputs(const UINT16 cnt); + void update_outputs(const UINT16 cnt); logic_input_t m_IP; object_array_t<logic_output_t, 14> m_Q; diff --git a/src/lib/netlist/devices/nld_74107.cpp b/src/lib/netlist/devices/nld_74107.cpp index 27b81e14beb..4dfa8b9aa8a 100644 --- a/src/lib/netlist/devices/nld_74107.cpp +++ b/src/lib/netlist/devices/nld_74107.cpp @@ -41,7 +41,7 @@ namespace netlist netlist_sig_t m_Q2; netlist_sig_t m_F; - ATTR_HOT void newstate(const netlist_sig_t state); + void newstate(const netlist_sig_t state); }; @@ -123,7 +123,7 @@ namespace netlist m_F = 0; } - ATTR_HOT inline void NETLIB_NAME(74107Asub)::newstate(const netlist_sig_t state) + inline void NETLIB_NAME(74107Asub)::newstate(const netlist_sig_t state) { const netlist_time delay[2] = { NLTIME_FROM_NS(25), NLTIME_FROM_NS(40) }; @@ -133,7 +133,7 @@ namespace netlist NETLIB_UPDATE(74107Asub) { - const netlist_sig_t t = m_Q.net().as_logic().Q(); + 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(); diff --git a/src/lib/netlist/devices/nld_74153.cpp b/src/lib/netlist/devices/nld_74153.cpp index 2dffd34e1ef..32497c627e3 100644 --- a/src/lib/netlist/devices/nld_74153.cpp +++ b/src/lib/netlist/devices/nld_74153.cpp @@ -20,7 +20,7 @@ namespace netlist NETLIB_OBJECT(74153sub) { NETLIB_CONSTRUCTOR(74153sub) - , m_C(*this, {"C0", "C1", "C2", "C3"}) + , m_C(*this, {{"C0", "C1", "C2", "C3"}}) , m_G(*this, "G") , m_Y(*this, "AY") //FIXME: Change netlists , m_chan(0) diff --git a/src/lib/netlist/devices/nld_74175.cpp b/src/lib/netlist/devices/nld_74175.cpp index 22edfb7d5ad..79c4fb85d1a 100644 --- a/src/lib/netlist/devices/nld_74175.cpp +++ b/src/lib/netlist/devices/nld_74175.cpp @@ -16,8 +16,8 @@ namespace netlist { NETLIB_CONSTRUCTOR(74175_sub) , m_CLK(*this, "CLK") - , m_Q(*this, {"Q1", "Q2", "Q3", "Q4"}) - , m_QQ(*this, {"Q1Q", "Q2Q", "Q3Q", "Q4Q"}) + , m_Q(*this, {{"Q1", "Q2", "Q3", "Q4"}}) + , m_QQ(*this, {{"Q1Q", "Q2Q", "Q3Q", "Q4Q"}}) , m_data(0) { save(NLNAME(m_clrq)); @@ -40,7 +40,7 @@ namespace netlist { NETLIB_CONSTRUCTOR(74175) , m_sub(*this, "sub") - , m_D(*this, {"D1", "D2", "D3", "D4"}) + , m_D(*this, {{"D1", "D2", "D3", "D4"}}) , m_CLRQ(*this, "CLRQ") { register_subalias("CLK", m_sub.m_CLK); @@ -93,8 +93,8 @@ namespace netlist } }; - 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) }; + 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) { diff --git a/src/lib/netlist/devices/nld_74192.cpp b/src/lib/netlist/devices/nld_74192.cpp index 3b4a15ea090..cc0260fd99a 100644 --- a/src/lib/netlist/devices/nld_74192.cpp +++ b/src/lib/netlist/devices/nld_74192.cpp @@ -24,15 +24,7 @@ namespace netlist { } - NETLIB_RESETI() - { - #if 0 - m_A.inactivate(); - m_B.inactivate(); - m_C.inactivate(); - m_D.inactivate(); - #endif - } + //NETLIB_RESETI() //NETLIB_UPDATEI(); public: @@ -41,7 +33,7 @@ namespace netlist logic_input_t m_C; logic_input_t m_D; - ATTR_HOT inline UINT8 read_ABCD() const + 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); @@ -56,7 +48,7 @@ namespace netlist , m_LOADQ(*this, "LOADQ") , m_CU(*this, "CU") , m_CD(*this, "CD") - , m_Q(*this, {"QA", "QB", "QC", "QD"}) + , m_Q(*this, {{"QA", "QB", "QC", "QD"}}) , m_BORROWQ(*this, "BORROWQ") , m_CARRYQ(*this, "CARRYQ") { @@ -119,7 +111,7 @@ namespace netlist } // FIXME: Timing - /* static */ const netlist_time delay[4] = + static const netlist_time delay[4] = { NLTIME_FROM_NS(40), NLTIME_FROM_NS(40), diff --git a/src/lib/netlist/devices/nld_74193.cpp b/src/lib/netlist/devices/nld_74193.cpp index da52e321a14..0742ff1ce54 100644 --- a/src/lib/netlist/devices/nld_74193.cpp +++ b/src/lib/netlist/devices/nld_74193.cpp @@ -28,7 +28,7 @@ namespace netlist , m_cnt(0) , m_last_CU(0) , m_last_CD(0) - , m_Q(*this, {"QA", "QB", "QC", "QD"}) + , m_Q(*this, {{"QA", "QB", "QC", "QD"}}) , m_BORROWQ(*this, "BORROWQ") , m_CARRYQ(*this, "CARRYQ") { diff --git a/src/lib/netlist/devices/nld_74279.cpp b/src/lib/netlist/devices/nld_74279.cpp index f5eec9b384e..7fb75f946fb 100644 --- a/src/lib/netlist/devices/nld_74279.cpp +++ b/src/lib/netlist/devices/nld_74279.cpp @@ -6,6 +6,7 @@ */ #include "nld_74279.h" +#include "nld_truthtable.h" namespace netlist { diff --git a/src/lib/netlist/devices/nld_74279.h b/src/lib/netlist/devices/nld_74279.h index a77578f0d8d..be1b0fcce23 100644 --- a/src/lib/netlist/devices/nld_74279.h +++ b/src/lib/netlist/devices/nld_74279.h @@ -36,18 +36,7 @@ #ifndef NLD_74279_H_ #define NLD_74279_H_ -#include "nld_truthtable.h" - #define TTL_74279_DIP(name) \ NET_REGISTER_DEV(TTL_74279_DIP, name) -namespace netlist -{ - namespace devices - { - - - } //namespace devices -} // namespace netlist - #endif /* NLD_74279_H_ */ diff --git a/src/lib/netlist/devices/nld_7448.cpp b/src/lib/netlist/devices/nld_7448.cpp index d34a0316eb6..edb11783d2e 100644 --- a/src/lib/netlist/devices/nld_7448.cpp +++ b/src/lib/netlist/devices/nld_7448.cpp @@ -6,6 +6,7 @@ */ #include "nld_7448.h" +#include "nld_truthtable.h" namespace netlist { @@ -15,6 +16,7 @@ namespace netlist /* * FIXME: Using truthtable is a lot slower than the explicit device + * in breakout. Performance drops by 20%. */ #define USE_TRUTHTABLE_7448 (0) @@ -36,7 +38,7 @@ namespace netlist , m_BIQ(*this, "BIQ") , m_RBIQ(*this, "RBIQ") , m_state(0) - , m_Q(*this, {"a", "b", "c", "d", "e", "f", "g"}) + , m_Q(*this, {{"a", "b", "c", "d", "e", "f", "g"}}) { save(NLNAME(m_state)); } @@ -45,7 +47,7 @@ namespace netlist NETLIB_UPDATEI(); public: - ATTR_HOT void update_outputs(UINT8 v); + void update_outputs(UINT8 v); static const UINT8 tab7448[16][7]; logic_input_t m_A; @@ -62,8 +64,6 @@ namespace netlist }; - #endif - NETLIB_OBJECT_DERIVED(7448_dip, 7448) { NETLIB_CONSTRUCTOR_DERIVED(7448_dip, 7448) @@ -85,6 +85,8 @@ namespace netlist register_subalias("15", m_Q[5]); // f } }; + #endif + #if (USE_TRUTHTABLE_7448 && USE_TRUTHTABLE) nld_7448::truthtable_t nld_7448::m_ttbl; @@ -108,7 +110,7 @@ namespace netlist " 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. + // 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 @@ -118,26 +120,27 @@ namespace netlist "" }; - NETLIB_START(7448_dip) + NETLIB_OBJECT_DERIVED(7448_dip, 7448) { - 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 - } + 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 diff --git a/src/lib/netlist/devices/nld_7448.h b/src/lib/netlist/devices/nld_7448.h index e7c2bda94ed..d9532b55cdb 100644 --- a/src/lib/netlist/devices/nld_7448.h +++ b/src/lib/netlist/devices/nld_7448.h @@ -25,7 +25,6 @@ #define NLD_7448_H_ #include "nl_base.h" -#include "nld_truthtable.h" #define TTL_7448(name, cA0, cA1, cA2, cA3, cLTQ, cBIQ, cRBIQ) \ NET_REGISTER_DEV(TTL_7448, name) \ diff --git a/src/lib/netlist/devices/nld_7474.cpp b/src/lib/netlist/devices/nld_7474.cpp index 9d145e91899..55355d83cad 100644 --- a/src/lib/netlist/devices/nld_7474.cpp +++ b/src/lib/netlist/devices/nld_7474.cpp @@ -33,7 +33,7 @@ namespace netlist logic_output_t m_QQ; INT8 m_nextD; - ATTR_HOT inline void newstate(const UINT8 stateQ, const UINT8 stateQQ); + inline void newstate(const UINT8 stateQ, const UINT8 stateQQ); private: @@ -95,7 +95,7 @@ namespace netlist NETLIB_SUB(7474) m_2; }; - ATTR_HOT inline void NETLIB_NAME(7474sub)::newstate(const UINT8 stateQ, const UINT8 stateQQ) + inline void NETLIB_NAME(7474sub)::newstate(const UINT8 stateQ, const UINT8 stateQQ) { // 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) }; diff --git a/src/lib/netlist/devices/nld_7490.cpp b/src/lib/netlist/devices/nld_7490.cpp index 4cb207e971b..c47cc1d94a9 100644 --- a/src/lib/netlist/devices/nld_7490.cpp +++ b/src/lib/netlist/devices/nld_7490.cpp @@ -24,7 +24,7 @@ namespace netlist , m_cnt(0) , m_last_A(0) , m_last_B(0) - , m_Q(*this, {"QA", "QB", "QC", "QD"}) + , m_Q(*this, {{"QA", "QB", "QC", "QD"}}) { save(NLNAME(m_cnt)); save(NLNAME(m_last_A)); @@ -35,7 +35,7 @@ namespace netlist NETLIB_RESETI(); protected: - ATTR_HOT void update_outputs(); + void update_outputs(); logic_input_t m_A; logic_input_t m_B; diff --git a/src/lib/netlist/devices/nld_74ls629.cpp b/src/lib/netlist/devices/nld_74ls629.cpp index fc847beda2d..eb9fbd7f712 100644 --- a/src/lib/netlist/devices/nld_74ls629.cpp +++ b/src/lib/netlist/devices/nld_74ls629.cpp @@ -54,7 +54,7 @@ namespace netlist , m_Y(*this, "Y") , m_enableq(1) , m_out(0) - , m_inc(netlist_time::zero) + , m_inc(netlist_time::zero()) { connect_late(m_FB, m_Y); @@ -67,7 +67,7 @@ namespace netlist { m_enableq = 1; m_out = 0; - m_inc = netlist_time::zero; + m_inc = netlist_time::zero(); } NETLIB_UPDATEI(); @@ -216,7 +216,7 @@ namespace netlist // 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.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)); diff --git a/src/lib/netlist/devices/nld_82S16.cpp b/src/lib/netlist/devices/nld_82S16.cpp index 7a766ff2004..9b3e32cd291 100644 --- a/src/lib/netlist/devices/nld_82S16.cpp +++ b/src/lib/netlist/devices/nld_82S16.cpp @@ -15,7 +15,7 @@ namespace netlist NETLIB_OBJECT(82S16) { NETLIB_CONSTRUCTOR(82S16) - , m_A(*this, { "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7" }) + , m_A(*this, {{"A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7" }}) , m_CE1Q(*this, "CE1Q") , m_CE2Q(*this, "CE2Q") , m_CE3Q(*this, "CE3Q") diff --git a/src/lib/netlist/devices/nld_9310.cpp b/src/lib/netlist/devices/nld_9310.cpp index 06b5715090a..97c2d2b0a7f 100644 --- a/src/lib/netlist/devices/nld_9310.cpp +++ b/src/lib/netlist/devices/nld_9310.cpp @@ -33,7 +33,7 @@ namespace netlist logic_input_t m_C; logic_input_t m_D; - ATTR_HOT inline UINT8 read_ABCD() const + 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); @@ -61,8 +61,8 @@ namespace netlist 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); + 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; @@ -148,12 +148,6 @@ namespace netlist NETLIB_RESET(9310_subABCD) { - #if 0 - m_A.inactivate(); - m_B.inactivate(); - m_C.inactivate(); - m_D.inactivate(); - #endif } NETLIB_RESET(9310_sub) @@ -168,11 +162,6 @@ namespace netlist { if (m_loadq) { - #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) { case MAXCNT - 1: @@ -189,7 +178,6 @@ namespace netlist m_cnt++; update_outputs(m_cnt); } - #endif } else { diff --git a/src/lib/netlist/devices/nld_9312.cpp b/src/lib/netlist/devices/nld_9312.cpp index 8affb42a12f..2fa5dcdf26f 100644 --- a/src/lib/netlist/devices/nld_9312.cpp +++ b/src/lib/netlist/devices/nld_9312.cpp @@ -106,7 +106,7 @@ namespace netlist NETLIB_SUB(9312) m_sub; }; - #if (1 && USE_TRUTHTABLE) + #if (USE_TRUTHTABLE) nld_9312::truthtable_t nld_9312::m_ttbl; /* FIXME: Data changes are propagating faster than changing selects A,B,C @@ -143,7 +143,7 @@ namespace netlist const UINT8 G = INPLOGIC(m_G); if (G) { - /* static */ const netlist_time delay[2] = { NLTIME_FROM_NS(33), NLTIME_FROM_NS(19) }; + 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]); @@ -161,7 +161,7 @@ namespace netlist m_B.activate(); m_C.activate(); } - /* static */ const netlist_time delay[2] = { NLTIME_FROM_NS(33), NLTIME_FROM_NS(28) }; + 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) { diff --git a/src/lib/netlist/devices/nld_9316.cpp b/src/lib/netlist/devices/nld_9316.cpp index 0943a81be93..287a9b6669d 100644 --- a/src/lib/netlist/devices/nld_9316.cpp +++ b/src/lib/netlist/devices/nld_9316.cpp @@ -24,15 +24,7 @@ namespace netlist { } - NETLIB_RESETI() - { - #if 0 - m_A.inactivate(); - m_B.inactivate(); - m_C.inactivate(); - m_D.inactivate(); - #endif - } + //NETLIB_RESETI() //NETLIB_UPDATEI(); public: @@ -41,7 +33,7 @@ namespace netlist logic_input_t m_C; logic_input_t m_D; - ATTR_HOT inline UINT8 read_ABCD() const + 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); @@ -72,8 +64,8 @@ namespace netlist 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); + 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; diff --git a/src/lib/netlist/devices/nld_mm5837.cpp b/src/lib/netlist/devices/nld_mm5837.cpp index b58cdff3374..9624bec2621 100644 --- a/src/lib/netlist/devices/nld_mm5837.cpp +++ b/src/lib/netlist/devices/nld_mm5837.cpp @@ -28,6 +28,7 @@ namespace netlist /* clock */ , m_feedback(*this, "FB") , m_Q(*this, "Q") + , m_inc(0, 1) , m_is_timestep(false) { m_inc = netlist_time::from_hz(56000); @@ -81,7 +82,7 @@ namespace netlist NETLIB_UPDATE(MM5837_dip) { - OUTLOGIC(m_Q, !m_Q.net().as_logic().new_Q(), m_inc ); + OUTLOGIC(m_Q, !m_Q.net().new_Q(), m_inc ); /* shift register * diff --git a/src/lib/netlist/devices/nld_system.cpp b/src/lib/netlist/devices/nld_system.cpp index ee3d381d422..c7467f7e3cc 100644 --- a/src/lib/netlist/devices/nld_system.cpp +++ b/src/lib/netlist/devices/nld_system.cpp @@ -30,7 +30,7 @@ namespace netlist NETLIB_UPDATE(clock) { - OUTLOGIC(m_Q, !m_Q.net().as_logic().new_Q(), m_inc ); + OUTLOGIC(m_Q, !m_Q.net().new_Q(), m_inc ); } // ---------------------------------------------------------------------------------------- @@ -40,29 +40,15 @@ namespace netlist NETLIB_RESET(extclock) { m_cnt = 0; - m_off = netlist_time::from_double(m_offset.Value()); + m_off = netlist_time(m_offset.Value()); //m_Q.initial(0); } NETLIB_UPDATE(extclock) { - #if 0 - if (m_off == netlist_time::zero) - { - OUTLOGIC(m_Q, (m_cnt & 1) ^ 1, m_inc[m_cnt]); - m_cnt = (m_cnt + 1) % m_size; - } - else - { - OUTLOGIC(m_Q, (m_cnt & 1) ^ 1, m_inc[0] + m_off); - m_cnt = 1; - m_off = netlist_time::zero; - } - #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 + m_off = netlist_time::zero(); } // ---------------------------------------------------------------------------------------- @@ -71,8 +57,7 @@ namespace netlist NETLIB_RESET(logic_input) { - //FIXME: causes issues in breakout (lots of pings after first player 1 start) - //m_Q.initial(m_IN.Value() & 1); + m_Q.initial(0); } NETLIB_UPDATE(logic_input) @@ -90,7 +75,7 @@ namespace netlist NETLIB_RESET(analog_input) { - // m_Q.initial(m_IN.Value() * 0.999); + m_Q.initial(0.0); } NETLIB_UPDATE(analog_input) diff --git a/src/lib/netlist/devices/nld_truthtable.cpp b/src/lib/netlist/devices/nld_truthtable.cpp index e4249713df4..5aaa14c0fef 100644 --- a/src/lib/netlist/devices/nld_truthtable.cpp +++ b/src/lib/netlist/devices/nld_truthtable.cpp @@ -13,37 +13,55 @@ namespace netlist namespace devices { -unsigned truthtable_desc_t::count_bits(UINT32 v) + 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) { - unsigned ret = 0; + uint64_t ret = 0; for (; v != 0; v = v >> 1) { - if (v & 1) - ret++; + ret += (v & 1); } return ret; } -UINT32 truthtable_desc_t::set_bits(UINT32 v, UINT32 b) +uint64_t truthtable_desc_t::set_bits(uint64_t v, uint64_t b) { - UINT32 ret = 0; - int i = 0; - for (; v != 0; v = v >> 1) + uint64_t ret = 0; + for (size_t i = 0; v != 0; v = v >> 1, ++i) { if (v & 1) { ret |= ((b&1)<<i); b = b >> 1; } - i++; } return ret; } -UINT32 truthtable_desc_t::get_ignored_simple(UINT32 i) +uint64_t truthtable_desc_t::get_ignored_simple(uint64_t i) { - UINT32 m_enable = 0; - for (UINT32 j=0; j<m_size; j++) + uint64_t m_enable = 0; + for (size_t j=0; j<m_size; j++) { if (m_outs[j] != m_outs[i]) { @@ -53,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); } // ---------------------------------------------------------------------------------------- @@ -103,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; @@ -137,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]; } @@ -160,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("")) { @@ -178,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++) { @@ -189,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); @@ -204,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); - - for (UINT32 j=0; j < m_size; j++) - ign[j] = ~0U; + std::vector<uint64_t> ign(m_size, all_set); - for (UINT32 i=0; i<m_size; i++) + for (size_t i=0; i<m_size; i++) { - if (ign[i] == ~0U) + if (ign[i] == all_set) { int tign; if (0) @@ -225,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; diff --git a/src/lib/netlist/devices/nld_truthtable.h b/src/lib/netlist/devices/nld_truthtable.h index 5f9f1fc8cb1..d5772907df6 100644 --- a/src/lib/netlist/devices/nld_truthtable.h +++ b/src/lib/netlist/devices/nld_truthtable.h @@ -11,6 +11,7 @@ #define NLD_TRUTHTABLE_H_ #include <new> +#include <cstdint> #include "nl_base.h" #include "nl_factory.h" @@ -51,320 +52,372 @@ namespace netlist namespace devices { -#if 0 -static inline UINT32 remove_first_bit(UINT32 v) -{ - for (int i=0; i<32; i++) - if (v & (1<<i)) - return v & ~(1<<i); - return v; -} -#endif - -struct truthtable_desc_t -{ - truthtable_desc_t(int NO, int NI, int has_state, bool *initialized, - 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)) + template<unsigned bits> + struct need_bytes_for_bits { - } + enum { value = + bits <= 8 ? 1 : + bits <= 16 ? 2 : + bits <= 32 ? 4 : + 8 + }; + }; - void setup(const plib::pstring_vector_t &desc, UINT32 disabled_ignore); + 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; }; -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); + struct packed_int + { + template<typename C> + packed_int(C *data) + : m_data(data) + , m_size(sizeof(C)) + {} - unsigned m_NO; - unsigned m_NI; - //int m_has_state; - bool *m_initialized; - UINT32 *m_outs; - UINT8 *m_timing; - netlist_time *m_timing_nt; + void set(const size_t pos, const uint64_t val) + { + switch (m_size) + { + case 1: ((uint8_t *) m_data)[pos] = val; break; + case 2: ((uint16_t *) m_data)[pos] = val; break; + case 4: ((uint32_t *) m_data)[pos] = val; break; + case 8: ((uint64_t *) m_data)[pos] = val; break; + default: { } + } + } - /* additional values */ + UINT64 operator[] (size_t pos) const + { + 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 + } + } - const UINT32 m_num_bits; - const UINT32 m_size; + uint64_t adjust(uint64_t val) const + { + switch (m_size) + { + case 1: return ((uint8_t) val); break; + case 2: return ((uint16_t) val); break; + case 4: return ((uint32_t) val); break; + case 8: return ((uint64_t) val); break; + default: + return 0; //should never happen + } + } + private: + void *m_data; + size_t m_size; + }; -}; + struct truthtable_desc_t + { + truthtable_desc_t(int NO, int NI, int has_state, bool *initialized, + packed_int outs, UINT8 *timing, netlist_time *timing_nt) + : m_NO(NO), m_NI(NI), /*m_has_state(has_state),*/ m_initialized(initialized), + m_outs(outs), m_timing(timing), m_timing_nt(timing_nt), + m_num_bits(m_NI + has_state * (m_NI + m_NO)), + m_size(1 << (m_num_bits)) + { + } -template<unsigned m_NI, unsigned m_NO, int has_state> -NETLIB_OBJECT(truthtable_t) -{ -private: - family_setter_t m_fam; -public: + void setup(const plib::pstring_vector_t &desc, UINT32 disabled_ignore); - static const int m_num_bits = m_NI + has_state * (m_NI + m_NO); - static const int m_size = (1 << (m_num_bits)); + private: + void help(unsigned cur, plib::pstring_vector_t list, + uint64_t state, uint64_t val, std::vector<uint8_t> &timing_index); + static unsigned count_bits(uint64_t v); + static uint64_t set_bits(uint64_t v, uint64_t b); + uint64_t get_ignored_simple(uint64_t i); + uint64_t get_ignored_extended(uint64_t i); + + unsigned m_NO; + unsigned m_NI; + bool *m_initialized; + packed_int m_outs; + uint8_t *m_timing; + netlist_time *m_timing_nt; + + /* additional values */ + + const std::size_t m_num_bits; + const std::size_t m_size; - struct truthtable_t - { - 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; }; - 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 m_NI, unsigned m_NO, int m_has_state> + NETLIB_OBJECT(truthtable_t) { - while (*desc != nullptr && **desc != 0 ) + private: + family_setter_t m_fam; + public: + + static const int m_num_bits = m_NI + m_has_state * (m_NI + m_NO); + static const int m_size = (1 << (m_num_bits)); + + struct truthtable_t + { + truthtable_t() + : 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++) { - m_desc.push_back(*desc); - desc++; + 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); + } } - 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(); - } + m_ign = 0; - void startxx() - { - pstring header = m_desc[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); - 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"); + desc.setup(m_desc, disabled_ignore * 0); - for (unsigned i=0; i < m_NI; i++) + #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() { - //new (&m_I[i]) logic_input_t(); - inout[i] = inout[i].trim(); - m_I.emplace(i, *this, inout[i]); + 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; } - for (unsigned i=0; i < m_NO; i++) + + NETLIB_UPDATEI() { - //new (&m_Q[i]) logic_output_t(); - out[i] = out[i].trim(); - m_Q.emplace(i, *this, out[i]); - //enregister(out[i], m_Q[i]); + process<true>(); } - // 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++) + + public: + void inc_active() override { - 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); - } + nl_assert(netlist().use_deactivate()); + if (m_NI > 1 && m_has_state == 0) + if (++m_active == 1) + { + process<false>(); + } } - 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)); - } + 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; + } + } - 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; - } + //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; - NETLIB_UPDATEI() - { - process<true>(); - } + protected: -public: - ATTR_HOT void inc_active() override - { - nl_assert(netlist().use_deactivate()); - if (has_state == 0) - if (++m_active == 1) + private: + + template<bool doOUT> + inline void process() + { + netlist_time mt = netlist_time::zero(); + + uint64_t state = 0; + if (m_NI > 1 && !m_has_state) { - process<false>(); + 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); + } } - } - - 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) + else { - for (unsigned i = 0; i< m_NI; i++) - m_I[i].inactivate(); - m_ign = (1<<m_NI)-1; + 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; - //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; + if (m_has_state) + nstate |= (m_last_state << m_NI); -protected: + const auto outstate = m_ttp->m_outs[nstate]; + const auto out = outstate & ((1 << m_NO) - 1); -private: + m_ign = outstate >> m_NO; - template<bool doOUT> - inline void process() - { - netlist_time mt = netlist_time::zero; + const auto timebase = nstate * m_NO; - UINT32 state = 0; - if (m_NI > 1 && !has_state) - for (unsigned i = 0; i < m_NI; i++) + if (doOUT) { - if (!doOUT || (m_ign & (1<<i))) - m_I[i].activate(); + for (std::size_t i = 0; i < m_NO; i++) + OUTLOGIC(m_Q[i], (out >> i) & 1, m_ttp->m_timing_nt[m_ttp->m_timing[timebase + i]]); } + else + for (std::size_t i = 0; i < m_NO; i++) + m_Q[i].net().set_Q_time((out >> i) & 1, mt + m_ttp->m_timing_nt[m_ttp->m_timing[timebase + i]]); + + if (m_has_state) + m_last_state = (state << m_NO) | out; - if (!doOUT) - for (unsigned i = 0; i < m_NI; i++) + if (m_NI > 1 && !m_has_state) { - state |= (INPLOGIC(m_I[i]) << i); - mt = std::max(this->m_I[i].net().time(), mt); + auto ign(m_ign); + for (std::size_t i = 0; ign != 0; ign >>= 1, i++) + if (ign & 1) + m_I[i].inactivate(); } - 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) - { - 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]]); } - 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) - { - for (unsigned i = 0; i < m_NI; i++) - if (m_ign & (1 << i)) - m_I[i].inactivate(); - } - } + UINT32 m_last_state; + UINT32 m_ign; + INT32 m_active; - UINT32 m_last_state; - UINT32 m_ign; - INT32 m_active; - - truthtable_t *m_ttp; - plib::pstring_vector_t m_desc; -}; + 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() + class netlist_base_factory_truthtable_t : public base_factory_t { - } - - plib::pstring_vector_t m_desc; - const logic_family_desc_t *m_family; -}; - + 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() + { + } -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::pstring_vector_t m_desc; + const logic_family_desc_t *m_family; + }; - plib::owned_ptr<device_t> Create(netlist_t &anetlist, const pstring &name) override - { - typedef nld_truthtable_t<m_NI, m_NO, has_state> tt_type; - return plib::owned_ptr<device_t>::Create<tt_type>(anetlist, name, m_family, &m_ttbl, m_desc); - } -private: - typename nld_truthtable_t<m_NI, m_NO, has_state>::truthtable_t m_ttbl; -}; - -plib::owned_ptr<netlist_base_factory_truthtable_t> nl_tt_factory_create(const unsigned ni, const unsigned no, - const unsigned has_state, - const pstring &name, const pstring &classname, - const pstring &def_param); + plib::owned_ptr<netlist_base_factory_truthtable_t> nl_tt_factory_create(const unsigned ni, const unsigned no, + const unsigned has_state, + const pstring &name, const pstring &classname, + const pstring &def_param); } //namespace devices } // namespace netlist diff --git a/src/lib/netlist/devices/nlid_cmos.h b/src/lib/netlist/devices/nlid_cmos.h index 7ca6cc29783..d776f96c3b3 100644 --- a/src/lib/netlist/devices/nlid_cmos.h +++ b/src/lib/netlist/devices/nlid_cmos.h @@ -27,8 +27,8 @@ namespace netlist NETLIB_RESETI() {}; public: - ATTR_HOT inline nl_double vdd() { return INPANALOG(m_vdd); } - ATTR_HOT inline nl_double vss() { return INPANALOG(m_vss); } + 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; diff --git a/src/lib/netlist/devices/nlid_system.h b/src/lib/netlist/devices/nlid_system.h index e650950bd17..8547fcfe22f 100644 --- a/src/lib/netlist/devices/nlid_system.h +++ b/src/lib/netlist/devices/nlid_system.h @@ -54,7 +54,7 @@ namespace netlist NETLIB_RESETI() { - m_Q.net().set_time(netlist_time::zero); + m_Q.net().set_time(netlist_time::zero()); } NETLIB_UPDATE_PARAMI() @@ -64,7 +64,7 @@ namespace netlist NETLIB_UPDATEI() { - logic_net_t &net = m_Q.net().as_logic(); + logic_net_t &net = m_Q.net(); // this is only called during setup ... net.toggle_new_Q(); net.set_time(netlist().time() + m_inc); @@ -76,7 +76,7 @@ namespace netlist param_double_t m_freq; netlist_time m_inc; - ATTR_HOT inline static void mc_update(logic_net_t &net); + inline static void mc_update(logic_net_t &net); }; // ----------------------------------------------------------------------------- @@ -126,18 +126,18 @@ namespace netlist { 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()); + m_off = netlist_time(m_offset.Value()); int pati[256]; m_size = pat.size(); int total = 0; - for (int i=0; i<m_size; i++) + for (unsigned 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++) + 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]; @@ -158,8 +158,8 @@ namespace netlist logic_input_t m_feedback; logic_output_t m_Q; - UINT32 m_cnt; - UINT32 m_size; + unsigned m_cnt; + unsigned m_size; netlist_time m_inc[32]; netlist_time m_off; }; @@ -311,7 +311,7 @@ namespace netlist , m_Q(*this, "Q") { - for (int i=0; i < m_N; i++) + 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(), " "); @@ -540,7 +540,7 @@ namespace netlist NETLIB_UPDATEI(); private: - analog_output_t m_GNDHack; // FIXME: LOng term, we need to connect proxy gnd to device gnd + 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; @@ -552,7 +552,7 @@ namespace netlist P_PREVENT_COPYING(factory_lib_entry_t) public: - ATTR_COLD factory_lib_entry_t(setup_t &setup, const pstring &name, const pstring &classname, + 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) { } diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp index dc610a99db9..6c1df62290d 100644 --- a/src/lib/netlist/nl_base.cpp +++ b/src/lib/netlist/nl_base.cpp @@ -5,21 +5,22 @@ * */ +#include <cstring> + #include "solver/nld_matrix_solver.h" +#include "solver/nld_solver.h" +#include "plib/putil.h" #include "plib/palloc.h" #include "nl_base.h" #include "devices/nlid_system.h" -#include "nl_util.h" - -const netlist::netlist_time netlist::netlist_time::zero = netlist::netlist_time(0); namespace netlist { #if (NL_USE_MEMPOOL) -static plib::pmempool p(65536, 16); +static plib::mempool p(65536, 8); void * object_t::operator new (size_t size) { @@ -67,7 +68,6 @@ public: } }; -//FIXME: set to proper values class logic_family_cd4xxx_t : public logic_family_desc_t { public: @@ -115,20 +115,20 @@ queue_t::queue_t(netlist_t &nl) void queue_t::register_state(plib::pstate_manager_t &manager, const pstring &module) { netlist().log().debug("register_state\n"); - manager.save_item(m_qsize, this, module + "." + "qsize"); - manager.save_item(&m_times[0], this, module + "." + "times", m_times.size()); - manager.save_item(&(m_names[0].m_buf[0]), this, module + "." + "names", m_names.size() * sizeof(names_t)); + manager.save_item(this, m_qsize, module + "." + "qsize"); + manager.save_item(this, &m_times[0], module + "." + "times", m_times.size()); + manager.save_item(this, &(m_names[0].m_buf[0]), module + "." + "names", m_names.size() * sizeof(names_t)); } void queue_t::on_pre_save() { netlist().log().debug("on_pre_save\n"); - m_qsize = this->count(); + m_qsize = this->size(); netlist().log().debug("current time {1} qsize {2}\n", netlist().time().as_double(), m_qsize); for (int i = 0; i < m_qsize; i++ ) { - m_times[i] = this->listptr()[i].exec_time().as_raw(); - pstring p = this->listptr()[i].object()->name(); + m_times[i] = this->listptr()[i].m_exec_time.as_raw(); + pstring p = this->listptr()[i].m_object->name(); int n = p.len(); n = std::min(63, n); std::strncpy(m_names[i].m_buf, p.cstr(), n); @@ -146,7 +146,7 @@ void queue_t::on_post_load() net_t *n = netlist().find_net(m_names[i].m_buf); //log().debug("Got {1} ==> {2}\n", qtemp[i].m_name, n)); //log().debug("schedule time {1} ({2})\n", n->time().as_double(), netlist_time::from_raw(m_times[i]).as_double())); - this->push(queue_t::entry_t(netlist_time::from_raw(m_times[i]), n)); + this->push(netlist_time::from_raw(m_times[i]), n); } } @@ -154,18 +154,18 @@ void queue_t::on_post_load() // object_t // ---------------------------------------------------------------------------------------- -ATTR_COLD object_t::object_t(netlist_t &nl, const pstring &aname, const type_t atype) -: m_name(aname) -, m_objtype(atype) -, m_netlist(&nl) +object_t::object_t(netlist_t &nl, const pstring &aname, const type_t atype) + : m_netlist(nl) + , m_name(aname) + , m_objtype(atype) { } -ATTR_COLD object_t::~object_t() +object_t::~object_t() { } -ATTR_COLD const pstring &object_t::name() const +const pstring &object_t::name() const { return m_name; } @@ -174,9 +174,9 @@ ATTR_COLD const pstring &object_t::name() const // device_object_t // ---------------------------------------------------------------------------------------- -ATTR_COLD device_object_t::device_object_t(core_device_t &dev, const pstring &aname, const type_t atype) +device_object_t::device_object_t(core_device_t &dev, const pstring &aname, const type_t atype) : object_t(dev.netlist(), aname, atype) -, m_device(&dev) +, m_device(dev) { } @@ -187,8 +187,8 @@ ATTR_COLD device_object_t::device_object_t(core_device_t &dev, const pstring &an netlist_t::netlist_t(const pstring &aname) : pstate_manager_t(), - m_stop(netlist_time::zero), - m_time(netlist_time::zero), + m_stop(netlist_time::zero()), + m_time(netlist_time::zero()), m_use_deactivate(0), m_queue(*this), m_mainclock(nullptr), @@ -200,8 +200,8 @@ netlist_t::netlist_t(const pstring &aname) m_log(this), m_lib(nullptr) { - save_item(static_cast<plib::pstate_callback_t &>(m_queue), this, "m_queue"); - save_item(m_time, this, "m_time"); + save_item(this, static_cast<plib::pstate_callback_t &>(m_queue), "m_queue"); + save_item(this, m_time, "m_time"); } netlist_t::~netlist_t() @@ -214,16 +214,16 @@ netlist_t::~netlist_t() pstring::resetmem(); } -ATTR_HOT nl_double netlist_t::gmin() const +nl_double netlist_t::gmin() const { return solver()->gmin(); } -ATTR_COLD void netlist_t::start() +void netlist_t::start() { /* load the library ... */ - pstring libpath = nl_util::environment("NL_BOOSTLIB", nl_util::buildpath({".", "nlboost.so"})); + pstring libpath = plib::util::environment("NL_BOOSTLIB", plib::util::buildpath({".", "nlboost.so"})); m_lib = plib::palloc<plib::dynlib>(libpath); @@ -237,7 +237,7 @@ ATTR_COLD void netlist_t::start() || setup().factory().is_class<devices::NETLIB_NAME(netlistparams)>(e.second)) { auto dev = plib::owned_ptr<device_t>(e.second->Create(*this, e.first)); - setup().register_dev_s(std::move(dev)); + setup().register_dev(std::move(dev)); } } @@ -260,13 +260,13 @@ ATTR_COLD void netlist_t::start() && !setup().factory().is_class<devices::NETLIB_NAME(netlistparams)>(e.second)) { auto dev = plib::owned_ptr<device_t>(e.second->Create(*this, e.first)); - setup().register_dev_s(std::move(dev)); + setup().register_dev(std::move(dev)); } } } -ATTR_COLD void netlist_t::stop() +void netlist_t::stop() { /* find the main clock and solver ... */ @@ -275,7 +275,7 @@ ATTR_COLD void netlist_t::stop() dev->stop_dev(); } -ATTR_COLD net_t *netlist_t::find_net(const pstring &name) +net_t *netlist_t::find_net(const pstring &name) { for (auto & net : m_nets) if (net->name() == name) @@ -284,25 +284,25 @@ ATTR_COLD net_t *netlist_t::find_net(const pstring &name) return nullptr; } -ATTR_COLD void netlist_t::rebuild_lists() +void netlist_t::rebuild_lists() { for (auto & net : m_nets) net->rebuild_list(); } -ATTR_COLD void netlist_t::reset() +void netlist_t::reset() { - m_time = netlist_time::zero; + m_time = netlist_time::zero(); m_queue.clear(); if (m_mainclock != nullptr) - m_mainclock->m_Q.net().set_time(netlist_time::zero); + m_mainclock->m_Q.net().set_time(netlist_time::zero()); //if (m_solver != nullptr) // m_solver->do_reset(); // Reset all nets once ! - for (std::size_t i = 0; i < m_nets.size(); i++) - m_nets[i]->do_reset(); + for (auto & n : m_nets) + n->reset(); // Reset all devices once ! for (auto & dev : m_devices) @@ -329,33 +329,33 @@ ATTR_COLD void netlist_t::reset() } -ATTR_HOT void netlist_t::process_queue(const netlist_time &delta) +void netlist_t::process_queue(const netlist_time &delta) { m_stop = m_time + delta; if (m_mainclock == nullptr) { - while ( (m_time < m_stop) && (m_queue.is_not_empty())) + while ( (m_time < m_stop) & (!m_queue.empty())) { - const queue_t::entry_t &e = m_queue.pop(); - m_time = e.exec_time(); - e.object()->update_devs(); + const queue_t::entry_t e(m_queue.pop()); + m_time = e.m_exec_time; + e.m_object->update_devs(); add_to_stat(m_perf_out_processed, 1); } - if (m_queue.is_empty()) + if (m_queue.empty()) m_time = m_stop; } else { - logic_net_t &mc_net = m_mainclock->m_Q.net().as_logic(); + logic_net_t &mc_net = m_mainclock->m_Q.net(); const netlist_time inc = m_mainclock->m_inc; netlist_time mc_time(mc_net.time()); while (m_time < m_stop) { - if (m_queue.is_not_empty()) + if (!m_queue.empty()) { - while (m_queue.top().exec_time() > mc_time) + while (m_queue.top().m_exec_time > mc_time) { m_time = mc_time; mc_time += inc; @@ -365,8 +365,8 @@ ATTR_HOT void netlist_t::process_queue(const netlist_time &delta) } const queue_t::entry_t &e = m_queue.pop(); - m_time = e.exec_time(); - e.object()->update_devs(); + m_time = e.m_exec_time; + e.m_object->update_devs(); } else { m_time = mc_time; @@ -386,13 +386,15 @@ void netlist_t::print_stats() const { #if (NL_KEEP_STATISTICS) { - for (std::size_t i = 0; i < m_devices.size(); i++) + for (auto & entry : m_devices) { - core_device_t *entry = m_devices[i].get(); - printf("Device %20s : %12d %12d %15ld\n", entry->name().cstr(), entry->stat_call_count, entry->stat_update_count, (long int) entry->stat_total_time / (entry->stat_update_count + 1)); + log().verbose("Device {1:20} : {2:12} {3:12} {4:15}", entry->name(), + entry->stat_call_count, entry->stat_update_count, + (long int) entry->stat_total_time / (entry->stat_update_count + 1)); } - printf("Queue Pushes %15d\n", queue().m_prof_call); - printf("Queue Moves %15d\n", queue().m_prof_sortmove); + + log().verbose("Queue Pushes {1:15}", queue().m_prof_call); + log().verbose("Queue Moves {1:15}", queue().m_prof_sortmove); } #endif } @@ -422,7 +424,7 @@ template class param_template_t<pstring, param_t::MODEL>; // core_device_t // ---------------------------------------------------------------------------------------- -ATTR_COLD core_device_t::core_device_t(netlist_t &owner, const pstring &name) +core_device_t::core_device_t(netlist_t &owner, const pstring &name) : object_t(owner, name, DEVICE), logic_family_t() #if (NL_KEEP_STATISTICS) , stat_total_time(0) @@ -434,7 +436,7 @@ ATTR_COLD core_device_t::core_device_t(netlist_t &owner, const pstring &name) set_logic_family(family_TTL()); } -ATTR_COLD core_device_t::core_device_t(core_device_t &owner, const pstring &name) +core_device_t::core_device_t(core_device_t &owner, const pstring &name) : object_t(owner.netlist(), owner.name() + "." + name, DEVICE) , logic_family_t() #if (NL_KEEP_STATISTICS) @@ -449,15 +451,12 @@ ATTR_COLD core_device_t::core_device_t(core_device_t &owner, const pstring &name owner.netlist().m_devices.push_back(plib::owned_ptr<core_device_t>(this, false)); } -ATTR_COLD core_device_t::~core_device_t() +core_device_t::~core_device_t() { } -ATTR_COLD void core_device_t::set_delegate_pointer() +void core_device_t::set_delegate_pointer() { -#if (NL_KEEP_STATISTICS) - netlist().m_started_devices.push_back(this); -#endif #if (NL_PMF_TYPE == NL_PMF_TYPE_GNUC_PMF) void (core_device_t::* pFunc)() = &core_device_t::update; m_static_update = pFunc; @@ -469,14 +468,14 @@ ATTR_COLD void core_device_t::set_delegate_pointer() #endif } -ATTR_COLD void core_device_t::stop_dev() +void core_device_t::stop_dev() { #if (NL_KEEP_STATISTICS) #endif //stop(); } -ATTR_HOT netlist_sig_t core_device_t::INPLOGIC_PASSIVE(logic_input_t &inp) +netlist_sig_t core_device_t::INPLOGIC_PASSIVE(logic_input_t &inp) { if (inp.state() != logic_t::STATE_INP_PASSIVE) return inp.Q(); @@ -499,23 +498,23 @@ device_t::~device_t() //log().debug("~net_device_t\n"); } -ATTR_COLD setup_t &device_t::setup() +setup_t &device_t::setup() { return netlist().setup(); } -ATTR_COLD void device_t::register_subalias(const pstring &name, core_terminal_t &term) +void device_t::register_subalias(const pstring &name, core_terminal_t &term) { pstring alias = this->name() + "." + name; // everything already fully qualified setup().register_alias_nofqn(alias, term.name()); - if (term.isType(terminal_t::INPUT) || term.isType(terminal_t::TERMINAL)) + if (term.is_type(terminal_t::INPUT) || term.is_type(terminal_t::TERMINAL)) m_terminals.push_back(alias); } -ATTR_COLD void device_t::register_subalias(const pstring &name, const pstring &aliased) +void device_t::register_subalias(const pstring &name, const pstring &aliased) { pstring alias = this->name() + "." + name; pstring aliased_fqn = this->name() + "." + aliased; @@ -528,17 +527,12 @@ ATTR_COLD void device_t::register_subalias(const pstring &name, const pstring &a // m_terminals.add(name); } -ATTR_COLD void device_t::register_p(const pstring &name, object_t &obj) -{ - setup().register_object(obj); -} - -ATTR_COLD void device_t::connect_late(core_terminal_t &t1, core_terminal_t &t2) +void device_t::connect_late(core_terminal_t &t1, core_terminal_t &t2) { setup().register_link_fqn(t1.name(), t2.name()); } -ATTR_COLD void device_t::connect_late(const pstring &t1, const pstring &t2) +void device_t::connect_late(const pstring &t1, const pstring &t2) { setup().register_link_fqn(name() + "." + t1, name() + "." + t2); } @@ -546,7 +540,7 @@ ATTR_COLD void device_t::connect_late(const pstring &t1, const pstring &t2) /* FIXME: this is only used by solver code since matrix solvers are started in * post_start. */ -ATTR_COLD void device_t::connect_post_start(core_terminal_t &t1, core_terminal_t &t2) +void device_t::connect_post_start(core_terminal_t &t1, core_terminal_t &t2) { if (!setup().connect(t1, t2)) netlist().log().fatal("Error connecting {1} to {2}\n", t1.name(), t2.name()); @@ -578,14 +572,14 @@ struct do_nothing_deleter{ }; -ATTR_COLD net_t::net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr) +net_t::net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr) : object_t(nl, aname, NET) , m_new_Q(0) , m_cur_Q (0) - , m_railterminal(nullptr) - , m_time(netlist_time::zero) + , m_time(netlist_time::zero()) , m_active(0) , m_in_queue(2) + , m_railterminal(nullptr) , m_cur_Analog(0.0) { m_railterminal = mr; @@ -602,21 +596,21 @@ ATTR_COLD net_t::net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr) save(NLNAME(m_new_Q)); } -ATTR_COLD net_t::~net_t() +net_t::~net_t() { netlist().remove_save_items(this); } -ATTR_HOT void net_t::inc_active(core_terminal_t &term) +void net_t::inc_active(core_terminal_t &term) { m_active++; - m_list_active.insert(term); + m_list_active.push_front(&term); nl_assert(m_active <= num_cons()); if (m_active == 1) { if (netlist().use_deactivate()) { - railterminal().device().inc_active(); + railterminal().device().do_inc_active(); //m_cur_Q = m_new_Q; } if (m_in_queue == 0) @@ -637,64 +631,59 @@ ATTR_HOT void net_t::inc_active(core_terminal_t &term) } } -ATTR_HOT void net_t::dec_active(core_terminal_t &term) +void net_t::dec_active(core_terminal_t &term) { - m_active--; + --m_active; nl_assert(m_active >= 0); - m_list_active.remove(term); + m_list_active.remove(&term); if (m_active == 0 && netlist().use_deactivate()) - railterminal().device().dec_active(); + railterminal().device().do_dec_active(); } -ATTR_COLD void net_t::rebuild_list() +void net_t::rebuild_list() { /* rebuild m_list */ unsigned cnt = 0; m_list_active.clear(); - for (core_terminal_t *term : m_core_terms) + for (auto & term : m_core_terms) if (term->state() != logic_t::STATE_INP_PASSIVE) { - m_list_active.add(*term); + m_list_active.push_back(term); cnt++; } m_active = cnt; } -ATTR_HOT /* inline */ void net_t::update_devs() +void net_t::update_devs() { //assert(m_num_cons != 0); nl_assert(this->isRailNet()); - const int masks[4] = { 1, 5, 3, 1 }; - const int mask = masks[ (m_cur_Q << 1) | m_new_Q ]; + static const unsigned masks[4] = + { + 0, + core_terminal_t::STATE_INP_LH | core_terminal_t::STATE_INP_ACTIVE, + core_terminal_t::STATE_INP_HL | core_terminal_t::STATE_INP_ACTIVE, + 0 + }; + + const unsigned mask = masks[ m_cur_Q * 2 + m_new_Q ]; m_in_queue = 2; /* mark as taken ... */ m_cur_Q = m_new_Q; -#if 1 - for (core_terminal_t *p = m_list_active.first(); p != nullptr; p = p->next()) + for (auto & p : m_list_active) { - inc_stat(p->device().stat_call_count); - if ((p->state() & mask) != 0) - p->device().update_dev(); + inc_stat(p.device().stat_call_count); + if ((p.state() & mask) != 0) + p.device().update_dev(); } -#else - for (auto p = &m_list_active.m_head; *p != nullptr; ) - { - auto pn = &((*p)->m_next); - inc_stat(p->device().stat_call_count); - if (((*p)->state() & mask) != 0) - (*p)->device().update_dev(); - p = pn; - } - -#endif } -ATTR_COLD void net_t::reset() +void net_t::reset() { - m_time = netlist_time::zero; + m_time = netlist_time::zero(); m_active = 0; m_in_queue = 2; @@ -706,17 +695,17 @@ ATTR_COLD void net_t::reset() m_list_active.clear(); for (core_terminal_t *ct : m_core_terms) - m_list_active.add(*ct); + m_list_active.push_back(ct); for (core_terminal_t *ct : m_core_terms) - ct->do_reset(); + ct->reset(); for (core_terminal_t *ct : m_core_terms) if (ct->state() != logic_t::STATE_INP_PASSIVE) m_active++; } -ATTR_COLD void net_t::register_con(core_terminal_t &terminal) +void net_t::register_con(core_terminal_t &terminal) { terminal.set_net(this); @@ -726,7 +715,7 @@ ATTR_COLD void net_t::register_con(core_terminal_t &terminal) m_active++; } -ATTR_COLD void net_t::move_connections(net_t *dest_net) +void net_t::move_connections(net_t *dest_net) { for (core_terminal_t *ct : m_core_terms) dest_net->register_con(*ct); @@ -734,7 +723,7 @@ ATTR_COLD void net_t::move_connections(net_t *dest_net) m_active = 0; } -ATTR_COLD void net_t::merge_net(net_t *othernet) +void net_t::merge_net(net_t *othernet) { netlist().log().debug("merging nets ...\n"); if (othernet == nullptr) @@ -765,33 +754,23 @@ ATTR_COLD void net_t::merge_net(net_t *othernet) // logic_net_t // ---------------------------------------------------------------------------------------- -ATTR_COLD logic_net_t::logic_net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr) +logic_net_t::logic_net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr) : net_t(nl, aname, mr) { } -ATTR_COLD void logic_net_t::reset() -{ - net_t::reset(); -} - // ---------------------------------------------------------------------------------------- // analog_net_t // ---------------------------------------------------------------------------------------- -ATTR_COLD analog_net_t::analog_net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr) +analog_net_t::analog_net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr) : net_t(nl, aname, mr) , m_solver(nullptr) { } -ATTR_COLD void analog_net_t::reset() -{ - net_t::reset(); -} - -ATTR_COLD bool analog_net_t::already_processed(plib::pvector_t<list_t> &groups) +bool analog_net_t::already_processed(plib::pvector_t<list_t> &groups) { if (isRailNet()) return true; @@ -803,7 +782,7 @@ ATTR_COLD bool analog_net_t::already_processed(plib::pvector_t<list_t> &groups) return false; } -ATTR_COLD void analog_net_t::process_net(plib::pvector_t<list_t> &groups) +void analog_net_t::process_net(plib::pvector_t<list_t> &groups) { if (num_cons() == 0) return; @@ -811,7 +790,7 @@ ATTR_COLD void analog_net_t::process_net(plib::pvector_t<list_t> &groups) groups.back().push_back(this); for (core_terminal_t *p : m_core_terms) { - if (p->isType(terminal_t::TERMINAL)) + if (p->is_type(terminal_t::TERMINAL)) { terminal_t *pt = static_cast<terminal_t *>(p); analog_net_t *other_net = &pt->m_otherterm->net(); @@ -826,21 +805,29 @@ ATTR_COLD void analog_net_t::process_net(plib::pvector_t<list_t> &groups) // core_terminal_t // ---------------------------------------------------------------------------------------- -ATTR_COLD core_terminal_t::core_terminal_t(core_device_t &dev, const pstring &aname, const type_t atype) +core_terminal_t::core_terminal_t(core_device_t &dev, const pstring &aname, const type_t atype) : device_object_t(dev, dev.name() + "." + aname, atype) -, plinkedlist_element_t() +, plib::linkedlist_t<core_terminal_t>::element_t() , m_net(nullptr) , m_state(STATE_NONEX) { save(NLNAME(m_state)); } -ATTR_COLD void core_terminal_t::set_net(net_t::ptr_t anet) +void core_terminal_t::reset() +{ + if (is_type(OUTPUT)) + set_state(STATE_OUT); + else + set_state(STATE_INP_ACTIVE); +} + +void core_terminal_t::set_net(net_t::ptr_t anet) { m_net = anet; } -ATTR_COLD void core_terminal_t::clear_net() + void core_terminal_t::clear_net() { m_net = nullptr; } @@ -850,43 +837,34 @@ ATTR_COLD void core_terminal_t::clear_net() // terminal_t // ---------------------------------------------------------------------------------------- -ATTR_COLD terminal_t::terminal_t(core_device_t &dev, const pstring &aname) +terminal_t::terminal_t(core_device_t &dev, const pstring &aname) : analog_t(dev, aname, TERMINAL) , m_otherterm(nullptr) , m_Idr1(nullptr) , m_go1(nullptr) , m_gt1(nullptr) { - netlist().setup().register_object(*this); + netlist().setup().register_term(*this); save(NLNAME(m_Idr1)); save(NLNAME(m_go1)); save(NLNAME(m_gt1)); } -ATTR_HOT void terminal_t::schedule_solve() +void terminal_t::schedule_solve() { // FIXME: Remove this after we found a way to remove *ALL* twoterms connected to railnets only. if (net().solver() != nullptr) net().solver()->update_forced(); } -ATTR_HOT void terminal_t::schedule_after(const netlist_time &after) +void terminal_t::schedule_after(const netlist_time &after) { // FIXME: Remove this after we found a way to remove *ALL* twoterms connected to railnets only. if (net().solver() != nullptr) net().solver()->update_after(after); } -ATTR_COLD void terminal_t::reset() -{ - set_state(STATE_INP_ACTIVE); - set_ptr(m_Idr1, 0.0); - set_ptr(m_go1, netlist().gmin()); - set_ptr(m_gt1, netlist().gmin()); -} - - // ---------------------------------------------------------------------------------------- // net_input_t // ---------------------------------------------------------------------------------------- @@ -899,48 +877,48 @@ ATTR_COLD void terminal_t::reset() // logic_output_t // ---------------------------------------------------------------------------------------- -ATTR_COLD logic_output_t::logic_output_t(core_device_t &dev, const pstring &aname) +logic_output_t::logic_output_t(core_device_t &dev, const pstring &aname) : logic_t(dev, aname, OUTPUT) , m_my_net(dev.netlist(), name() + ".net", this) { set_state(STATE_OUT); this->set_net(&m_my_net); set_logic_family(dev.logic_family()); - netlist().setup().register_object(*this); + netlist().setup().register_term(*this); } -ATTR_COLD void logic_output_t::initial(const netlist_sig_t val) +void logic_output_t::initial(const netlist_sig_t val) { - net().as_logic().initial(val); + net().initial(val); } // ---------------------------------------------------------------------------------------- // analog_input_t // ---------------------------------------------------------------------------------------- -ATTR_COLD analog_input_t::analog_input_t(core_device_t &dev, const pstring &aname) +analog_input_t::analog_input_t(core_device_t &dev, const pstring &aname) : analog_t(dev, aname, INPUT) { set_state(STATE_INP_ACTIVE); - netlist().setup().register_object(*this); + netlist().setup().register_term(*this); } // ---------------------------------------------------------------------------------------- // analog_output_t // ---------------------------------------------------------------------------------------- -ATTR_COLD analog_output_t::analog_output_t(core_device_t &dev, const pstring &aname) - : analog_t(dev, aname, OUTPUT), m_proxied_net(nullptr) +analog_output_t::analog_output_t(core_device_t &dev, const pstring &aname) + : analog_t(dev, aname, OUTPUT) , m_my_net(dev.netlist(), name() + ".net", this) { this->set_net(&m_my_net); set_state(STATE_OUT); net().m_cur_Analog = NL_FCONST(0.0); - netlist().setup().register_object(*this); + netlist().setup().register_term(*this); } -ATTR_COLD void analog_output_t::initial(const nl_double val) +void analog_output_t::initial(const nl_double val) { net().m_cur_Analog = val; } @@ -949,25 +927,25 @@ ATTR_COLD void analog_output_t::initial(const nl_double val) // logic_input_t // ----------------------------------------------------------------------------- -ATTR_COLD logic_input_t::logic_input_t(core_device_t &dev, const pstring &aname) +logic_input_t::logic_input_t(core_device_t &dev, const pstring &aname) : logic_t(dev, aname, INPUT) { set_state(STATE_INP_ACTIVE); set_logic_family(dev.logic_family()); - netlist().setup().register_object(*this); + netlist().setup().register_term(*this); } // ---------------------------------------------------------------------------------------- // param_t & friends // ---------------------------------------------------------------------------------------- -ATTR_COLD param_t::param_t(const param_type_t atype, device_t &device, const pstring &name) +param_t::param_t(const param_type_t atype, device_t &device, const pstring &name) : device_object_t(device, name, PARAM) , m_param_type(atype) { } -ATTR_COLD const pstring param_model_t::model_type() +const pstring param_model_t::model_type() { if (m_map.size() == 0) netlist().setup().model_parse(this->Value(), m_map); @@ -975,14 +953,14 @@ ATTR_COLD const pstring param_model_t::model_type() } -ATTR_COLD const pstring param_model_t::model_value_str(const pstring &entity) +const pstring param_model_t::model_value_str(const pstring &entity) { if (m_map.size() == 0) netlist().setup().model_parse(this->Value(), m_map); return netlist().setup().model_value_str(m_map, entity); } -ATTR_COLD nl_double param_model_t::model_value(const pstring &entity) +nl_double param_model_t::model_value(const pstring &entity) { if (m_map.size() == 0) netlist().setup().model_parse(this->Value(), m_map); @@ -1000,7 +978,7 @@ namespace netlist // mainclock // ---------------------------------------------------------------------------------------- - ATTR_HOT /* inline */ void NETLIB_NAME(mainclock)::mc_update(logic_net_t &net) + void NETLIB_NAME(mainclock)::mc_update(logic_net_t &net) { net.toggle_new_Q(); net.update_devs(); diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index 14e0ad5bb54..6e6b938408d 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -160,7 +160,6 @@ #include "nl_lists.h" #include "nl_time.h" -#include "nl_util.h" #include "plib/pdynlib.h" #include "plib/pstate.h" #include "plib/pfmtlog.h" @@ -190,51 +189,51 @@ class NETLIB_NAME(name) : public device_t #define NETLIB_CONSTRUCTOR_DERIVED(cname, pclass) \ private: family_setter_t m_famsetter; \ - public: template <class CLASS> ATTR_COLD NETLIB_NAME(cname)(CLASS &owner, const pstring name) \ + public: template <class CLASS> NETLIB_NAME(cname)(CLASS &owner, const pstring name) \ : NETLIB_NAME(pclass)(owner, name) #define NETLIB_CONSTRUCTOR(cname) \ private: family_setter_t m_famsetter; \ - public: template <class CLASS> ATTR_COLD NETLIB_NAME(cname)(CLASS &owner, const pstring name) \ + public: template <class CLASS> NETLIB_NAME(cname)(CLASS &owner, const pstring name) \ : device_t(owner, name) -#define NETLIB_DESTRUCTOR(name) public: ATTR_HOT virtual ~NETLIB_NAME(name)() +#define NETLIB_DESTRUCTOR(name) public: virtual ~NETLIB_NAME(name)() #define NETLIB_CONSTRUCTOR_EX(cname, ...) \ private: family_setter_t m_famsetter; \ - public: template <class CLASS> ATTR_COLD NETLIB_NAME(cname)(CLASS &owner, const pstring name, __VA_ARGS__) \ + public: template <class CLASS> NETLIB_NAME(cname)(CLASS &owner, const pstring name, __VA_ARGS__) \ : device_t(owner, name) #define NETLIB_DYNAMIC() \ - public: ATTR_HOT virtual bool is_dynamic1() const override { return true; } + public: virtual bool is_dynamic() const override { return true; } #define NETLIB_TIMESTEP() \ - public: ATTR_HOT virtual bool is_timestep() const override { return true; } \ - public: ATTR_HOT virtual void step_time(const nl_double step) override + public: virtual bool is_timestep() const override { return true; } \ + public: virtual void step_time(const nl_double step) override #define NETLIB_UPDATE_AFTER_PARAM_CHANGE() \ - public: ATTR_HOT virtual bool needs_update_after_param_change() const override { return true; } + public: virtual bool needs_update_after_param_change() const override { return true; } #define NETLIB_FAMILY(family) , m_famsetter(*this, family) -#define NETLIB_UPDATE_TERMINALSI() public: ATTR_HOT virtual void update_terminals() override -#define NETLIB_UPDATEI() protected: ATTR_HOT virtual void update() NOEXCEPT override -#define NETLIB_UPDATE_PARAMI() public: ATTR_HOT virtual void update_param() override -#define NETLIB_RESETI() protected: ATTR_HOT virtual void reset() override +#define NETLIB_UPDATE_TERMINALSI() public: virtual void update_terminals() override +#define NETLIB_UPDATEI() protected: virtual void update() NOEXCEPT override +#define NETLIB_UPDATE_PARAMI() public: virtual void update_param() override +#define NETLIB_RESETI() protected: virtual void reset() override #define NETLIB_SUB(chip) nld_ ## chip #define NETLIB_SUBXX(chip) std::unique_ptr< nld_ ## chip > -#define NETLIB_UPDATE(chip) ATTR_HOT void NETLIB_NAME(chip) :: update(void) NOEXCEPT +#define NETLIB_UPDATE(chip) void NETLIB_NAME(chip) :: update(void) NOEXCEPT -#define NETLIB_RESET(chip) ATTR_COLD void NETLIB_NAME(chip) :: reset(void) +#define NETLIB_RESET(chip) void NETLIB_NAME(chip) :: reset(void) -#define NETLIB_STOP(chip) ATTR_COLD void NETLIB_NAME(chip) :: stop(void) +#define NETLIB_STOP(chip) void NETLIB_NAME(chip) :: stop(void) -#define NETLIB_UPDATE_PARAM(chip) ATTR_HOT void NETLIB_NAME(chip) :: update_param(void) -#define NETLIB_FUNC_VOID(chip, name, params) ATTR_HOT void NETLIB_NAME(chip) :: name params +#define NETLIB_UPDATE_PARAM(chip) void NETLIB_NAME(chip) :: update_param(void) +#define NETLIB_FUNC_VOID(chip, name, params) void NETLIB_NAME(chip) :: name params -#define NETLIB_UPDATE_TERMINALS(chip) ATTR_HOT void NETLIB_NAME(chip) :: update_terminals(void) +#define NETLIB_UPDATE_TERMINALS(chip) void NETLIB_NAME(chip) :: update_terminals(void) //============================================================ // Asserts @@ -322,8 +321,8 @@ namespace netlist logic_family_t() : m_logic_family(nullptr) {} ~logic_family_t() { } - ATTR_HOT const logic_family_desc_t *logic_family() const { return m_logic_family; } - ATTR_COLD void set_logic_family(const logic_family_desc_t *fam) { m_logic_family = fam; } + const logic_family_desc_t *logic_family() const { return m_logic_family; } + void set_logic_family(const logic_family_desc_t *fam) { m_logic_family = fam; } protected: const logic_family_desc_t *m_logic_family; @@ -359,36 +358,23 @@ namespace netlist QUEUE = 6 }; - ATTR_COLD object_t(netlist_t &nl, const pstring &aname, const type_t atype); + object_t(netlist_t &nl, const pstring &aname, const type_t atype); + ~object_t(); - virtual ~object_t(); + const pstring &name() const; - ATTR_COLD const pstring &name() const; + plib::pstate_manager_t &state_manager(); - ATTR_COLD inline plib::pstate_manager_t *state_manager(); + type_t type() const { return m_objtype; } + bool is_type(const type_t atype) const { return (m_objtype == atype); } - ATTR_HOT type_t type() const { return m_objtype; } - - ATTR_HOT bool isType(const type_t atype) const { return (m_objtype == atype); } - - ATTR_HOT netlist_t & netlist() { return *m_netlist; } - ATTR_HOT const netlist_t & netlist() const { return *m_netlist; } - - ATTR_COLD void do_reset() - { - reset(); - } - - protected: - - virtual void reset() { } - // must call parent save_register ! - //virtual void save_register() { } + netlist_t & netlist() { return m_netlist; } + const netlist_t & netlist() const { return m_netlist; } private: + netlist_t & m_netlist; pstring m_name; const type_t m_objtype; - netlist_t * m_netlist; public: void * operator new (size_t size, void *ptr) { return ptr; } @@ -405,10 +391,10 @@ namespace netlist { P_PREVENT_COPYING(device_object_t) public: - ATTR_COLD device_object_t(core_device_t &dev, const pstring &aname, const type_t atype); - ATTR_HOT core_device_t &device() const { return *m_device; } + device_object_t(core_device_t &dev, const pstring &aname, const type_t atype); + core_device_t &device() const { return m_device; } private: - core_device_t * m_device; + core_device_t & m_device; }; @@ -416,7 +402,7 @@ namespace netlist // core_terminal_t // ----------------------------------------------------------------------------- - class core_terminal_t : public device_object_t, public plib::plinkedlist_element_t<core_terminal_t> + class core_terminal_t : public device_object_t, public plib::linkedlist_t<core_terminal_t>::element_t { P_PREVENT_COPYING(core_terminal_t) public: @@ -434,26 +420,29 @@ namespace netlist STATE_NONEX = 256 }; - ATTR_COLD core_terminal_t(core_device_t &dev, const pstring &aname, const type_t atype); + core_terminal_t(core_device_t &dev, const pstring &aname, const type_t atype); + virtual ~core_terminal_t() { } - ATTR_COLD void set_net(net_t *anet); - ATTR_COLD void clear_net(); - ATTR_COLD bool is_logic() const; - ATTR_COLD bool is_analog() const; + void set_net(net_t *anet); + void clear_net(); + bool has_net() const { return (m_net != nullptr); } - ATTR_HOT bool has_net() const { return (m_net != nullptr); } + const net_t & net() const { return *m_net;} + net_t & net() { return *m_net;} - ATTR_HOT const net_t & net() const { return *m_net;} - ATTR_HOT net_t & net() { return *m_net;} + bool is_logic() const; + bool is_analog() const; - ATTR_HOT bool is_state(const state_e astate) const { return (m_state == astate); } - ATTR_HOT const state_e &state() const { return m_state; } - ATTR_HOT void set_state(const state_e astate) + bool is_state(const state_e astate) const { return (m_state == astate); } + state_e state() const { return m_state; } + void set_state(const state_e astate) { nl_assert(astate != STATE_NONEX); m_state = astate; } + void reset(); + private: net_t * m_net; state_e m_state; @@ -467,21 +456,13 @@ namespace netlist { public: - ATTR_COLD analog_t(core_device_t &dev, const pstring &aname, const type_t atype) + analog_t(core_device_t &dev, const pstring &aname, const type_t atype) : core_terminal_t(dev, aname, atype) { } - virtual void reset() override - { - } - - ATTR_HOT inline const analog_net_t & net() const; - ATTR_HOT inline analog_net_t & net(); - - protected: - - private: + const analog_net_t & net() const; + analog_net_t & net(); }; // ----------------------------------------------------------------------------- @@ -495,33 +476,33 @@ namespace netlist using list_t = plib::pvector_t<terminal_t *>; - ATTR_COLD terminal_t(core_device_t &dev, const pstring &aname); + terminal_t(core_device_t &dev, const pstring &aname); terminal_t *m_otherterm; - ATTR_HOT void set(const nl_double G) + void set(const nl_double G) { set_ptr(m_Idr1, 0); set_ptr(m_go1, G); set_ptr(m_gt1, G); } - ATTR_HOT void set(const nl_double GO, const nl_double GT) + void set(const nl_double GO, const nl_double GT) { set_ptr(m_Idr1, 0); set_ptr(m_go1, GO); set_ptr(m_gt1, GT); } - ATTR_HOT void set(const nl_double GO, const nl_double GT, const nl_double I) + void set(const nl_double GO, const nl_double GT, const nl_double I) { set_ptr(m_Idr1, I); set_ptr(m_go1, GO); set_ptr(m_gt1, GT); } - ATTR_HOT void schedule_solve(); - ATTR_HOT void schedule_after(const netlist_time &after); + void schedule_solve(); + void schedule_after(const netlist_time &after); void set_ptrs(nl_double *gt, nl_double *go, nl_double *Idr) { @@ -530,10 +511,8 @@ namespace netlist m_Idr1 = Idr; } - protected: - virtual void reset() override; private: - ATTR_HOT void set_ptr(nl_double *ptr, const nl_double val) + void set_ptr(nl_double *ptr, const nl_double val) { if (ptr != nullptr && *ptr != val) { @@ -545,7 +524,7 @@ namespace netlist nl_double *m_go1; // conductance for Voltage from other term nl_double *m_gt1; // conductance for total conductance -}; + }; // ----------------------------------------------------------------------------- @@ -555,19 +534,18 @@ namespace netlist class logic_t : public core_terminal_t, public logic_family_t { public: - ATTR_COLD logic_t(core_device_t &dev, const pstring &aname, const type_t atype) + logic_t(core_device_t &dev, const pstring &aname, const type_t atype) : core_terminal_t(dev, aname, atype), logic_family_t(), m_proxy(nullptr) { } - virtual void reset() override - { - } + bool has_proxy() const { return (m_proxy != nullptr); } + devices::nld_base_proxy *get_proxy() const { return m_proxy; } + void set_proxy(devices::nld_base_proxy *proxy) { m_proxy = proxy; } - ATTR_COLD bool has_proxy() const { return (m_proxy != nullptr); } - ATTR_COLD devices::nld_base_proxy *get_proxy() const { return m_proxy; } - ATTR_COLD void set_proxy(devices::nld_base_proxy *proxy) { m_proxy = proxy; } + logic_net_t & net(); + const logic_net_t & net() const; protected: @@ -582,21 +560,14 @@ namespace netlist class logic_input_t : public logic_t { public: - ATTR_COLD logic_input_t(core_device_t &dev, const pstring &aname); + logic_input_t(core_device_t &dev, const pstring &aname); - ATTR_HOT netlist_sig_t Q() const; + netlist_sig_t Q() const; - ATTR_HOT void inactivate(); - ATTR_HOT void activate(); - ATTR_HOT void activate_hl(); - ATTR_HOT void activate_lh(); - - protected: - virtual void reset() override - { - logic_t::reset(); - set_state(STATE_INP_ACTIVE); - } + void inactivate(); + void activate(); + void activate_hl(); + void activate_lh(); }; @@ -607,15 +578,10 @@ namespace netlist class analog_input_t : public analog_t { public: - ATTR_COLD analog_input_t(core_device_t &dev, const pstring &aname); - ATTR_HOT nl_double Q_Analog() const; + analog_input_t(core_device_t &dev, const pstring &aname); + + nl_double Q_Analog() const; - protected: - virtual void reset() override - { - analog_t::reset(); - set_state(STATE_INP_ACTIVE); - } }; // ----------------------------------------------------------------------------- @@ -630,73 +596,55 @@ namespace netlist using ptr_t = net_t *; using list_t = plib::pvector_t<std::shared_ptr<net_t>>; - ATTR_COLD net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr = nullptr); + net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr = nullptr); virtual ~net_t(); - ATTR_COLD void register_con(core_terminal_t &terminal); - ATTR_COLD void merge_net(net_t *othernet); + void reset(); - ATTR_COLD bool is_logic() const; - ATTR_COLD bool is_analog() const; + void register_con(core_terminal_t &terminal); + void merge_net(net_t *othernet); - ATTR_HOT logic_net_t & as_logic(); - ATTR_HOT const logic_net_t & as_logic() const; + bool is_logic() const; + bool is_analog() const; - ATTR_HOT analog_net_t & as_analog(); - ATTR_HOT const analog_net_t & as_analog() const; + void toggle_new_Q() { m_new_Q ^= 1; } - ATTR_HOT void update_devs(); + void push_to_queue(const netlist_time delay) NOEXCEPT; + void reschedule_in_queue(const netlist_time delay) NOEXCEPT; + bool is_queued() const { return m_in_queue == 1; } - ATTR_HOT const netlist_time time() const { return m_time; } - ATTR_HOT void set_time(const netlist_time &ntime) { m_time = ntime; } + void update_devs(); - ATTR_HOT bool isRailNet() const { return !(m_railterminal == nullptr); } - ATTR_HOT core_terminal_t & railterminal() const { return *m_railterminal; } + const netlist_time time() const { return m_time; } + void set_time(const netlist_time ntime) { m_time = ntime; } - ATTR_HOT void push_to_queue(const netlist_time &delay) NOEXCEPT; - ATTR_HOT void reschedule_in_queue(const netlist_time &delay) NOEXCEPT; - ATTR_HOT bool is_queued() const { return m_in_queue == 1; } + bool isRailNet() const { return !(m_railterminal == nullptr); } + core_terminal_t & railterminal() const { return *m_railterminal; } - ATTR_HOT int num_cons() const { return m_core_terms.size(); } + int num_cons() const { return m_core_terms.size(); } - ATTR_HOT void inc_active(core_terminal_t &term); - ATTR_HOT void dec_active(core_terminal_t &term); + void inc_active(core_terminal_t &term); + void dec_active(core_terminal_t &term); - ATTR_COLD void rebuild_list(); /* rebuild m_list after a load */ + void rebuild_list(); /* rebuild m_list after a load */ - ATTR_COLD void move_connections(net_t *new_net); + void move_connections(net_t *new_net); plib::pvector_t<core_terminal_t *> m_core_terms; // save post-start m_list ... - ATTR_HOT void set_Q_time(const netlist_sig_t &newQ, const netlist_time &at) - { - if (newQ != m_new_Q) - { - m_in_queue = 0; - m_time = at; - } - m_cur_Q = m_new_Q = newQ; - } - - protected: //FIXME: needed by current solver code - - virtual void reset() override; - + protected: netlist_sig_t m_new_Q; netlist_sig_t m_cur_Q; - private: - - core_terminal_t * m_railterminal; - plib::linkedlist_t<core_terminal_t> m_list_active; - netlist_time m_time; INT32 m_active; - UINT8 m_in_queue; /* 0: not in queue, 1: in queue, 2: last was taken */ + UINT8 m_in_queue; /* 0: not in queue, 1: in queue, 2: last was taken */ + + private: + plib::linkedlist_t<core_terminal_t> m_list_active; + core_terminal_t * m_railterminal; public: - // We have to have those on one object. Dividing those does lead - // to a significant performance hit // FIXME: Have to fix the public at some time nl_double m_cur_Analog; @@ -709,55 +657,40 @@ namespace netlist using list_t = plib::pvector_t<logic_net_t *>; - ATTR_COLD logic_net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr = nullptr); + logic_net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr = nullptr); virtual ~logic_net_t() { }; - ATTR_HOT netlist_sig_t Q() const - { - return m_cur_Q; - } - - ATTR_HOT netlist_sig_t new_Q() const - { - return m_new_Q; - } + netlist_sig_t Q() const { return m_cur_Q; } + netlist_sig_t new_Q() const { return m_new_Q; } + void initial(const netlist_sig_t val) { m_cur_Q = m_new_Q = val; } - ATTR_HOT void set_Q(const netlist_sig_t &newQ, const netlist_time &delay) NOEXCEPT + void set_Q(const netlist_sig_t newQ, const netlist_time delay) NOEXCEPT { - if (newQ != m_new_Q) + if (newQ != m_new_Q) { m_new_Q = newQ; push_to_queue(delay); } } - ATTR_HOT void toggle_new_Q() - { - m_new_Q ^= 1; - } - - ATTR_COLD void initial(const netlist_sig_t val) + void set_Q_time(const netlist_sig_t newQ, const netlist_time at) { - m_cur_Q = val; - m_new_Q = val; + if (newQ != m_new_Q) + { + m_in_queue = 0; + m_time = at; + } + m_cur_Q = m_new_Q = newQ; } /* internal state support * FIXME: get rid of this and implement export/import in MAME */ - ATTR_COLD netlist_sig_t &Q_state_ptr() - { - return m_cur_Q; - } - - protected: //FIXME: needed by current solver code - - virtual void reset() override; + netlist_sig_t &Q_state_ptr() { return m_cur_Q; } + protected: private: - public: - }; class analog_net_t : public net_t @@ -767,40 +700,26 @@ namespace netlist using list_t = plib::pvector_t<analog_net_t *>; - ATTR_COLD analog_net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr = nullptr); + analog_net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr = nullptr); virtual ~analog_net_t() { }; - ATTR_HOT const nl_double &Q_Analog() const - { - return m_cur_Analog; - } + nl_double Q_Analog() const { return m_cur_Analog; } + nl_double &Q_Analog_state_ptr() { return m_cur_Analog; } - ATTR_COLD nl_double &Q_Analog_state_ptr() - { - return m_cur_Analog; - } - - ATTR_HOT devices::matrix_solver_t *solver() { return m_solver; } - - ATTR_COLD bool already_processed(plib::pvector_t<list_t> &groups); - ATTR_COLD void process_net(plib::pvector_t<list_t> &groups); - - protected: - - virtual void reset() override; + //FIXME: needed by current solver code + devices::matrix_solver_t *solver() { return m_solver; } + void set_solver(devices::matrix_solver_t *solver) { m_solver = solver; } + bool already_processed(plib::pvector_t<list_t> &groups); + void process_net(plib::pvector_t<list_t> &groups); private: - - public: - - //FIXME: needed by current solver code devices::matrix_solver_t *m_solver; }; // ----------------------------------------------------------------------------- - // net_output_t + // logic_output_t // ----------------------------------------------------------------------------- class logic_output_t : public logic_t @@ -808,18 +727,13 @@ namespace netlist P_PREVENT_COPYING(logic_output_t) public: - ATTR_COLD logic_output_t(core_device_t &dev, const pstring &aname); - - virtual void reset() override - { - set_state(STATE_OUT); - } + logic_output_t(core_device_t &dev, const pstring &aname); - ATTR_COLD void initial(const netlist_sig_t val); + void initial(const netlist_sig_t val); - ATTR_HOT void set_Q(const netlist_sig_t newQ, const netlist_time &delay) NOEXCEPT + void set_Q(const netlist_sig_t newQ, const netlist_time delay) NOEXCEPT { - net().as_logic().set_Q(newQ, delay); + m_my_net.set_Q(newQ, delay); // take the shortcut } private: @@ -831,18 +745,10 @@ namespace netlist P_PREVENT_COPYING(analog_output_t) public: - ATTR_COLD analog_output_t(core_device_t &dev, const pstring &aname); - - virtual void reset() override - { - set_state(STATE_OUT); - } - - ATTR_COLD void initial(const nl_double val); + analog_output_t(core_device_t &dev, const pstring &aname); - ATTR_HOT void set_Q(const nl_double newQ); - - analog_net_t *m_proxied_net; // only for proxy nets in analog input logic + void initial(const nl_double val); + void set_Q(const nl_double newQ); private: analog_net_t m_my_net; @@ -867,13 +773,10 @@ namespace netlist LOGIC }; - ATTR_COLD param_t(const param_type_t atype, device_t &device, const pstring &name); - - ATTR_HOT param_type_t param_type() const { return m_param_type; } - - protected: + param_t(const param_type_t atype, device_t &device, const pstring &name); + virtual ~param_t() {} - virtual void reset() override { } + param_type_t param_type() const { return m_param_type; } private: const param_type_t m_param_type; @@ -888,9 +791,9 @@ namespace netlist operator const C() const { return Value(); } - ATTR_HOT void setTo(const C ¶m); - ATTR_COLD void initial(const C &val) { m_param = val; } - ATTR_HOT C Value() const { return m_param; } + void setTo(const C ¶m); + void initial(const C &val) { m_param = val; } + C Value() const { return m_param; } protected: virtual void changed() { } @@ -907,13 +810,13 @@ namespace netlist class param_model_t : public param_str_t { public: - ATTR_COLD param_model_t(device_t &device, const pstring name, const pstring val) + param_model_t(device_t &device, const pstring name, const pstring val) : param_str_t(device, name, val) { } /* these should be cached! */ - ATTR_COLD nl_double model_value(const pstring &entity); - ATTR_COLD const pstring model_value_str(const pstring &entity); - ATTR_COLD const pstring model_type(); + nl_double model_value(const pstring &entity); + const pstring model_value_str(const pstring &entity); + const pstring model_type(); protected: void changed() override { @@ -934,12 +837,12 @@ namespace netlist using list_t = plib::pvector_t<core_device_t *>; - ATTR_COLD core_device_t(netlist_t &owner, const pstring &name); - ATTR_COLD core_device_t(core_device_t &owner, const pstring &name); + core_device_t(netlist_t &owner, const pstring &name); + core_device_t(core_device_t &owner, const pstring &name); virtual ~core_device_t(); - ATTR_HOT void update_dev() + void update_dev() { begin_timing(stat_total_time); inc_stat(stat_update_count); @@ -947,7 +850,7 @@ namespace netlist end_timing(stat_total_time); } - ATTR_HOT void do_update() NOEXCEPT + void do_update() NOEXCEPT { #if (NL_PMF_TYPE == NL_PMF_TYPE_GNUC_PMF) (this->*m_static_update)(); @@ -958,34 +861,24 @@ namespace netlist #endif } - ATTR_COLD void set_delegate_pointer(); - ATTR_COLD void stop_dev(); + void set_delegate_pointer(); + void stop_dev(); - ATTR_HOT netlist_sig_t INPLOGIC_PASSIVE(logic_input_t &inp); + void do_inc_active() { inc_active(); } + void do_dec_active() { dec_active(); } + void do_reset() { reset(); } - ATTR_HOT netlist_sig_t INPLOGIC(const logic_input_t &inp) const + netlist_sig_t INPLOGIC_PASSIVE(logic_input_t &inp); + netlist_sig_t INPLOGIC(const logic_input_t &inp) const { nl_assert(inp.state() != logic_t::STATE_INP_PASSIVE); return inp.Q(); } - ATTR_HOT void OUTLOGIC(logic_output_t &out, const netlist_sig_t val, const netlist_time &delay) NOEXCEPT - { - out.set_Q(val, delay); - } - - ATTR_HOT nl_double INPANALOG(const analog_input_t &inp) const { return inp.Q_Analog(); } - - ATTR_HOT nl_double TERMANALOG(const terminal_t &term) const { return term.net().Q_Analog(); } - - ATTR_HOT void OUTANALOG(analog_output_t &out, const nl_double val) - { - out.set_Q(val); - } - - ATTR_HOT virtual void inc_active() { } - - ATTR_HOT virtual void dec_active() { } + void OUTLOGIC(logic_output_t &out, const netlist_sig_t val, const netlist_time delay) NOEXCEPT; + nl_double INPANALOG(const analog_input_t &inp) const { return inp.Q_Analog(); } + nl_double TERMANALOG(const terminal_t &term) const { return term.net().Q_Analog(); } + void OUTANALOG(analog_output_t &out, const nl_double val) { out.set_Q(val); } #if (NL_KEEP_STATISTICS) /* stats */ @@ -996,17 +889,20 @@ namespace netlist protected: - ATTR_HOT virtual void update() NOEXCEPT { } - ATTR_HOT virtual void stop() { } + virtual void update() NOEXCEPT { } + virtual void inc_active() { } + virtual void dec_active() { } + virtual void stop() { } + virtual void reset() { } public: - ATTR_HOT virtual void step_time(ATTR_UNUSED const nl_double st) { } - ATTR_HOT virtual void update_terminals() { } + virtual void step_time(ATTR_UNUSED const nl_double st) { } + virtual void update_terminals() { } - ATTR_HOT virtual void update_param() {} - ATTR_HOT virtual bool is_dynamic1() const { return false; } - ATTR_HOT virtual bool is_timestep() const { return false; } - ATTR_HOT virtual bool needs_update_after_param_change() const { return false; } + virtual void update_param() {} + virtual bool is_dynamic() const { return false; } + virtual bool is_timestep() const { return false; } + virtual bool needs_update_after_param_change() const { return false; } private: @@ -1047,12 +943,12 @@ namespace netlist public: template <class C> - ATTR_COLD device_t(C &owner, const pstring &name) + device_t(C &owner, const pstring &name) : core_device_t(owner, name) { } virtual ~device_t(); - ATTR_COLD setup_t &setup(); + setup_t &setup(); #if 1 template<class C> @@ -1062,17 +958,12 @@ namespace netlist } #endif - ATTR_COLD void register_subalias(const pstring &name, core_terminal_t &term); - ATTR_COLD void register_subalias(const pstring &name, const pstring &aliased); - //ATTR_COLD void register_term(const pstring &name, terminal_t &port) { register_p(name, port); } - //ATTR_COLD void enregister(const pstring &name, analog_output_t &out) { register_p(name, out); }; - //ATTR_COLD void enregister(const pstring &name, logic_output_t &out) { register_p(name, out); }; - //ATTR_COLD void enregister(const pstring &name, analog_input_t &in) { register_p(name, in); }; - //ATTR_COLD void enregister(const pstring &name, logic_input_t &in) { register_p(name, in); }; + void register_subalias(const pstring &name, core_terminal_t &term); + void register_subalias(const pstring &name, const pstring &aliased); - ATTR_COLD void connect_late(const pstring &t1, const pstring &t2); - ATTR_COLD void connect_late(core_terminal_t &t1, core_terminal_t &t2); - ATTR_COLD void connect_post_start(core_terminal_t &t1, core_terminal_t &t2); + void connect_late(const pstring &t1, const pstring &t2); + void connect_late(core_terminal_t &t1, core_terminal_t &t2); + void connect_post_start(core_terminal_t &t1, core_terminal_t &t2); plib::pvector_t<pstring> m_terminals; @@ -1081,12 +972,9 @@ namespace netlist NETLIB_UPDATEI() { } NETLIB_UPDATE_TERMINALSI() { } - template <class C, class T> - ATTR_COLD void register_param(const pstring &sname, C ¶m, const T initialVal); - private: - ATTR_COLD void register_p(const pstring &name, object_t &obj); - ATTR_COLD void register_sub_p(device_t &dev); + void register_p(const pstring &name, object_t &obj); + void register_sub_p(device_t &dev); }; // ----------------------------------------------------------------------------- @@ -1123,8 +1011,6 @@ namespace netlist protected: - void reset() override {} - void register_state(plib::pstate_manager_t &manager, const pstring &module) override; void on_pre_save() override; void on_post_load() override; @@ -1132,8 +1018,8 @@ namespace netlist private: struct names_t { char m_buf[64]; }; int m_qsize; - plib::array_t<netlist_time::INTERNALTYPE> m_times; - plib::array_t<names_t> m_names; + std::vector<netlist_time::INTERNALTYPE> m_times; + std::vector<names_t> m_names; }; // ----------------------------------------------------------------------------- @@ -1151,33 +1037,33 @@ namespace netlist pstring name() const { return m_name; } - ATTR_COLD void start(); - ATTR_COLD void stop(); + void start(); + void stop(); - ATTR_HOT const queue_t &queue() const { return m_queue; } - ATTR_HOT queue_t &queue() { return m_queue; } - ATTR_HOT const netlist_time time() const { return m_time; } - ATTR_HOT devices::NETLIB_NAME(solver) *solver() const { return m_solver; } - ATTR_HOT devices::NETLIB_NAME(gnd) *gnd() const { return m_gnd; } - ATTR_HOT nl_double gmin() const; + const queue_t &queue() const { return m_queue; } + queue_t &queue() { return m_queue; } + const netlist_time time() const { return m_time; } + devices::NETLIB_NAME(solver) *solver() const { return m_solver; } + devices::NETLIB_NAME(gnd) *gnd() const { return m_gnd; } + nl_double gmin() const; - ATTR_HOT void push_to_queue(net_t &out, const netlist_time &attime) NOEXCEPT; - ATTR_HOT void remove_from_queue(net_t &out); + void push_to_queue(net_t &out, const netlist_time attime) NOEXCEPT; + void remove_from_queue(net_t &out); - ATTR_HOT void process_queue(const netlist_time &delta); - ATTR_HOT void abort_current_queue_slice() { m_stop = netlist_time::zero; } + void process_queue(const netlist_time &delta); + void abort_current_queue_slice() { m_stop = netlist_time::zero(); } - ATTR_HOT const bool &use_deactivate() const { return m_use_deactivate; } + bool use_deactivate() const { return m_use_deactivate; } - ATTR_COLD void rebuild_lists(); /* must be called after post_load ! */ + void rebuild_lists(); /* must be called after post_load ! */ - ATTR_COLD void set_setup(setup_t *asetup) { m_setup = asetup; } - ATTR_COLD setup_t &setup() { return *m_setup; } + void set_setup(setup_t *asetup) { m_setup = asetup; } + setup_t &setup() { return *m_setup; } - ATTR_COLD net_t *find_net(const pstring &name); + net_t *find_net(const pstring &name); template<class device_class> - ATTR_COLD plib::pvector_t<device_class *> get_device_list() + plib::pvector_t<device_class *> get_device_list() { plib::pvector_t<device_class *> tmp; for (auto &d : m_devices) @@ -1190,7 +1076,7 @@ namespace netlist } template<class device_class> - ATTR_COLD device_class *get_single_device(const char *classname) + device_class *get_single_device(const char *classname) { device_class *ret = nullptr; for (auto &d : m_devices) @@ -1207,16 +1093,12 @@ namespace netlist return ret; } - #if (NL_KEEP_STATISTICS) - pvector_t<core_device_t *> m_started_devices; - #endif - - ATTR_COLD plib::plog_base<NL_DEBUG> &log() { return m_log; } - ATTR_COLD const plib::plog_base<NL_DEBUG> &log() const { return m_log; } + plib::plog_base<NL_DEBUG> &log() { return m_log; } + const plib::plog_base<NL_DEBUG> &log() const { return m_log; } virtual void reset(); - ATTR_COLD plib::dynlib &lib() { return *m_lib; } + plib::dynlib &lib() { return *m_lib; } void print_stats() const; @@ -1279,13 +1161,13 @@ protected: // inline implementations // ----------------------------------------------------------------------------- - ATTR_COLD inline plib::pstate_manager_t *object_t::state_manager() + inline plib::pstate_manager_t &object_t::state_manager() { return m_netlist; } template <class C, param_t::param_type_t T> - ATTR_HOT inline void param_template_t<C, T>::setTo(const C ¶m) + inline void param_template_t<C, T>::setTo(const C ¶m) { if (m_param != param) { @@ -1297,89 +1179,63 @@ protected: } } - ATTR_COLD inline bool core_terminal_t::is_logic() const + inline bool core_terminal_t::is_logic() const { return dynamic_cast<const logic_t *>(this) != nullptr; } - ATTR_COLD inline bool core_terminal_t::is_analog() const + inline bool core_terminal_t::is_analog() const { return dynamic_cast<const analog_t *>(this) != nullptr; } - ATTR_COLD inline bool net_t::is_logic() const + inline bool net_t::is_logic() const { return dynamic_cast<const logic_net_t *>(this) != nullptr; } - ATTR_COLD inline bool net_t::is_analog() const + inline bool net_t::is_analog() const { return dynamic_cast<const analog_net_t *>(this) != nullptr; } - ATTR_HOT inline logic_net_t & net_t::as_logic() - { - nl_assert(is_logic()); - return reinterpret_cast<logic_net_t &>(*this); - } - - ATTR_HOT inline const logic_net_t & net_t::as_logic() const - { - nl_assert(is_logic()); - return reinterpret_cast<const logic_net_t &>(*this); - } - - ATTR_HOT inline analog_net_t & net_t::as_analog() + inline void logic_input_t::inactivate() { - nl_assert(is_analog()); - return reinterpret_cast<analog_net_t &>(*this); - } - - ATTR_HOT inline const analog_net_t & net_t::as_analog() const - { - nl_assert(is_analog()); - return reinterpret_cast<const analog_net_t &>(*this); - } - - - ATTR_HOT inline void logic_input_t::inactivate() - { - if (EXPECTED(!is_state(STATE_INP_PASSIVE))) + if (!is_state(STATE_INP_PASSIVE)) { set_state(STATE_INP_PASSIVE); - net().as_logic().dec_active(*this); + net().dec_active(*this); } } - ATTR_HOT inline void logic_input_t::activate() + inline void logic_input_t::activate() { if (is_state(STATE_INP_PASSIVE)) { - net().as_logic().inc_active(*this); + net().inc_active(*this); set_state(STATE_INP_ACTIVE); } } - ATTR_HOT inline void logic_input_t::activate_hl() + inline void logic_input_t::activate_hl() { if (is_state(STATE_INP_PASSIVE)) { - net().as_logic().inc_active(*this); + net().inc_active(*this); set_state(STATE_INP_HL); } } - ATTR_HOT inline void logic_input_t::activate_lh() + inline void logic_input_t::activate_lh() { if (is_state(STATE_INP_PASSIVE)) { - net().as_logic().inc_active(*this); + net().inc_active(*this); set_state(STATE_INP_LH); } } - - ATTR_HOT inline void net_t::push_to_queue(const netlist_time &delay) NOEXCEPT + inline void net_t::push_to_queue(const netlist_time delay) NOEXCEPT { if (!is_queued() && (num_cons() > 0)) { @@ -1392,59 +1248,75 @@ protected: } } - ATTR_HOT inline void net_t::reschedule_in_queue(const netlist_time &delay) NOEXCEPT + inline void net_t::reschedule_in_queue(const netlist_time delay) NOEXCEPT { if (is_queued()) netlist().remove_from_queue(*this); m_time = netlist().time() + delay; m_in_queue = (m_active > 0); /* queued ? */ - if (EXPECTED(m_in_queue)) + if (m_in_queue) { netlist().push_to_queue(*this, m_time); } } - ATTR_HOT inline const analog_net_t & analog_t::net() const + inline const analog_net_t & analog_t::net() const { - return core_terminal_t::net().as_analog(); + return static_cast<const analog_net_t &>(core_terminal_t::net()); } - ATTR_HOT inline analog_net_t & analog_t::net() + inline analog_net_t & analog_t::net() { - return core_terminal_t::net().as_analog(); + return static_cast<analog_net_t &>(core_terminal_t::net()); } + inline logic_net_t & logic_t::net() + { + return *static_cast<logic_net_t *>(&core_terminal_t::net()); + } + + inline const logic_net_t & logic_t::net() const + { + return static_cast<const logic_net_t &>(core_terminal_t::net()); + } - ATTR_HOT inline netlist_sig_t logic_input_t::Q() const + inline netlist_sig_t logic_input_t::Q() const { - return net().as_logic().Q(); + return net().Q(); } - ATTR_HOT inline nl_double analog_input_t::Q_Analog() const + inline nl_double analog_input_t::Q_Analog() const { - return net().as_analog().Q_Analog(); + return net().Q_Analog(); } - ATTR_HOT inline void analog_output_t::set_Q(const nl_double newQ) + inline void analog_output_t::set_Q(const nl_double newQ) { if (newQ != net().Q_Analog()) { net().m_cur_Analog = newQ; + net().toggle_new_Q(); net().push_to_queue(NLTIME_FROM_NS(1)); } } - ATTR_HOT inline void netlist_t::push_to_queue(net_t &out, const netlist_time &attime) NOEXCEPT + inline void netlist_t::push_to_queue(net_t &out, const netlist_time attime) NOEXCEPT { - m_queue.push(queue_t::entry_t(attime, &out)); + m_queue.push(attime, &out); } - ATTR_HOT inline void netlist_t::remove_from_queue(net_t &out) + inline void netlist_t::remove_from_queue(net_t &out) { m_queue.remove(&out); } + inline void core_device_t::OUTLOGIC(logic_output_t &out, const netlist_sig_t val, const netlist_time delay) NOEXCEPT + { + out.set_Q(val, delay); + } + + } NETLIST_SAVE_TYPE(netlist::core_terminal_t::state_e, pstate_data_type_e::DT_INT); diff --git a/src/lib/netlist/nl_config.h b/src/lib/netlist/nl_config.h index 6ca57b864f5..68a60ece8e4 100644 --- a/src/lib/netlist/nl_config.h +++ b/src/lib/netlist/nl_config.h @@ -40,7 +40,7 @@ * * 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. diff --git a/src/lib/netlist/nl_dice_compat.h b/src/lib/netlist/nl_dice_compat.h index d70b8d8494d..e163b637f4c 100644 --- a/src/lib/netlist/nl_dice_compat.h +++ b/src/lib/netlist/nl_dice_compat.h @@ -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; } diff --git a/src/lib/netlist/nl_factory.cpp b/src/lib/netlist/nl_factory.cpp index 545e2c3a601..43f83b39374 100644 --- a/src/lib/netlist/nl_factory.cpp +++ b/src/lib/netlist/nl_factory.cpp @@ -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(); diff --git a/src/lib/netlist/nl_factory.h b/src/lib/netlist/nl_factory.h index d1bd0b6f728..780408cd285 100644 --- a/src/lib/netlist/nl_factory.h +++ b/src/lib/netlist/nl_factory.h @@ -13,6 +13,7 @@ #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) >; diff --git a/src/lib/netlist/nl_lists.h b/src/lib/netlist/nl_lists.h index bedfc002588..b3443ed2297 100644 --- a/src/lib/netlist/nl_lists.h +++ b/src/lib/netlist/nl_lists.h @@ -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--) - { - *(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()) + entry_t * i = m_end; + for (; t > (i - 1)->m_exec_time; --i) { *(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); - } - - ATTR_HOT const entry_t & top() const NOEXCEPT - { - return *(m_end-1); - } + entry_t pop() NOEXCEPT { return *(--m_end); } + 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 + +}; } diff --git a/src/lib/netlist/nl_parser.cpp b/src/lib/netlist/nl_parser.cpp index c001a6c0fd6..14aabdf4a0e 100644 --- a/src/lib/netlist/nl_parser.cpp +++ b/src/lib/netlist/nl_parser.cpp @@ -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); diff --git a/src/lib/netlist/nl_parser.h b/src/lib/netlist/nl_parser.h index dc30ff056a0..7338fb01abd 100644 --- a/src/lib/netlist/nl_parser.h +++ b/src/lib/netlist/nl_parser.h @@ -9,7 +9,6 @@ #define NL_PARSER_H_ #include "nl_setup.h" -#include "nl_util.h" #include "plib/pparser.h" namespace netlist diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp index c072e917240..b311e4b1a68 100644 --- a/src/lib/netlist/nl_setup.cpp +++ b/src/lib/netlist/nl_setup.cpp @@ -10,10 +10,10 @@ #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/nlid_system.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; @@ -181,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()) { @@ -218,7 +218,7 @@ void setup_t::register_and_set_param(pstring name, param_t ¶m) 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: @@ -227,13 +227,13 @@ void setup_t::register_and_set_param(pstring name, param_t ¶m) 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: @@ -244,46 +244,22 @@ void setup_t::register_and_set_param(pstring name, param_t ¶m) log().fatal("Error adding parameter {1} to parameter list\n", name); } -void setup_t::register_object(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)) - { - } - else if (term.isType(terminal_t::INPUT)) - { - static_cast<device_t &>(term.device()).m_terminals.push_back(obj.name()); - } - else - { - static_cast<device_t &>(term.device()).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(obj), obj.name()); - log().debug("{1} {2}\n", objtype_as_astr(obj), obj.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", obj.name()); - break; - case terminal_t::QUEUE: - log().fatal("QUEUE registration not yet supported - {1}\n", obj.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) @@ -362,7 +338,6 @@ void setup_t::register_frontier(const pstring attach, const double r_IN, const d void setup_t::register_param(const pstring ¶m, const double value) { - // FIXME: there should be a better way register_param(param, plib::pfmt("{1}").e(value,".9")); } @@ -486,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)) @@ -499,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; } @@ -517,7 +492,7 @@ void setup_t::connect_input_output(core_terminal_t &in, core_terminal_t &out) 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()) @@ -560,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 { @@ -640,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; @@ -655,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; @@ -676,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); } @@ -748,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"); } @@ -792,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"); @@ -825,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 != "") { @@ -837,11 +807,10 @@ void setup_t::start_devices() 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(); } diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h index f9f8721e911..ebf989cb20f 100644 --- a/src/lib/netlist/nl_setup.h +++ b/src/lib/netlist/nl_setup.h @@ -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,14 +114,7 @@ namespace netlist void register_and_set_param(pstring name, param_t ¶m); - void register_object(object_t &obj); - - template<class NETLIST_X> - void register_dev_s(plib::owned_ptr<NETLIST_X> dev) - { - register_dev(std::move(dev)); - } - + void register_term(core_terminal_t &obj); void register_dev(plib::owned_ptr<device_t> dev); void register_dev(const pstring &classname, 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); diff --git a/src/lib/netlist/nl_time.h b/src/lib/netlist/nl_time.h index 7949f68e132..ed28cedc932 100644 --- a/src/lib/netlist/nl_time.h +++ b/src/lib/netlist/nl_time.h @@ -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,110 +34,105 @@ 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; - - 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; - - 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); - - 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; } - - ATTR_HOT INTERNALTYPE as_raw() const { return m_time; } - ATTR_HOT double as_double() const { return (double) m_time / (double) RESOLUTION; } + static constexpr INTERNALTYPE RESOLUTION = NETLIST_INTERNAL_RES; + + constexpr netlist_time() NOEXCEPT : m_time(0) {} + netlist_time(const netlist_time &rhs) NOEXCEPT = default; + netlist_time(netlist_time &&rhs) NOEXCEPT = default; + + 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)) { } + + + 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; } + 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; } - - 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); } + INTERNALTYPE *get_internaltype_ptr() { return &m_time; } - 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); - } } namespace plib { -template<> ATTR_COLD inline void pstate_manager_t::save_item(netlist::netlist_time &nlt, const void *owner, const pstring &stname) +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); } } diff --git a/src/lib/netlist/nl_util.h b/src/lib/netlist/nl_util.h deleted file mode 100644 index 54e0090119d..00000000000 --- a/src/lib/netlist/nl_util.h +++ /dev/null @@ -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_ */ diff --git a/src/lib/netlist/plib/palloc.cpp b/src/lib/netlist/plib/palloc.cpp index f58da749792..b6d0f37b7ef 100644 --- a/src/lib/netlist/plib/palloc.cpp +++ b/src/lib/netlist/plib/palloc.cpp @@ -52,7 +52,7 @@ int mempool::new_block() 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) diff --git a/src/lib/netlist/plib/palloc.h b/src/lib/netlist/plib/palloc.h index 6b79d410bc8..154656602a6 100644 --- a/src/lib/netlist/plib/palloc.h +++ b/src/lib/netlist/plib/palloc.h @@ -157,8 +157,8 @@ 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; diff --git a/src/lib/netlist/plib/pconfig.h b/src/lib/netlist/plib/pconfig.h index 7634c663123..506c77c6f8d 100644 --- a/src/lib/netlist/plib/pconfig.h +++ b/src/lib/netlist/plib/pconfig.h @@ -90,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__)) diff --git a/src/lib/netlist/plib/pfmtlog.cpp b/src/lib/netlist/plib/pfmtlog.cpp index 40ab47209ba..b10ab7f6a2b 100644 --- a/src/lib/netlist/plib/pfmtlog.cpp +++ b/src/lib/netlist/plib/pfmtlog.cpp @@ -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; @@ -166,4 +142,3 @@ void pfmt::format_element(const char *f, const char *l, const char *fmt_spec, . } -#endif diff --git a/src/lib/netlist/plib/pfmtlog.h b/src/lib/netlist/plib/pfmtlog.h index 603e623c103..af899c35a26 100644 --- a/src/lib/netlist/plib/pfmtlog.h +++ b/src/lib/netlist/plib/pfmtlog.h @@ -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)); } diff --git a/src/lib/netlist/plib/plists.h b/src/lib/netlist/plib/plists.h index 718aab95cb8..be36dd8fb2d 100644 --- a/src/lib/netlist/plib/plists.h +++ b/src/lib/netlist/plib/plists.h @@ -11,81 +11,16 @@ #define PLISTS_H_ #include <algorithm> -#include <stack> #include <vector> #include <type_traits> +//#include <cstring> +//#include <array> #include "palloc.h" #include "pstring.h" namespace plib { -// ---------------------------------------------------------------------------------------- -// parray_t: dynamic array -// ---------------------------------------------------------------------------------------- - -template <class LC> -class array_t -{ -public: - - ATTR_COLD array_t(std::size_t numElements) - : m_list(0), m_capacity(0) - { - set_capacity(numElements); - } - - ATTR_COLD array_t(const array_t &rhs) - : m_list(0), m_capacity(0) - { - set_capacity(rhs.size()); - for (std::size_t i=0; i<m_capacity; i++) - m_list[i] = rhs[i]; - } - - ATTR_COLD array_t &operator=(const array_t &rhs) - { - set_capacity(rhs.size()); - for (std::size_t i=0; i<m_capacity; i++) - m_list[i] = rhs[i]; - return *this; - } - - ~array_t() - { - if (m_list != nullptr) - pfree_array(m_list); - m_list = nullptr; - } - - 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) - { - set_capacity(new_size); - } - -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; -}; - /* ---------------------------------------------------------------------------------------- * uninitialised_array_t: * fixed size array allowing to override constructor and initialize @@ -145,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()); @@ -164,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; @@ -192,240 +118,78 @@ public: // ---------------------------------------------------------------------------------------- template <class LC> -class linkedlist_t; - -#if 1 - -template <class LC> -struct plinkedlist_element_t +class linkedlist_t { public: - friend class linkedlist_t<LC>; + struct element_t + { + public: - plinkedlist_element_t() : m_next(nullptr) {} + friend class linkedlist_t<LC>; - LC *next() const { return m_next; } -//private: - LC * m_next; -}; + element_t() : m_next(nullptr) {} -template <class LC> -class linkedlist_t -{ -public: + 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) - { - 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) + + iter_t begin() const { return iter_t(m_head); } + constexpr iter_t end() const { return iter_t(nullptr); } + + void push_front(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 @@ -645,7 +409,7 @@ private: } pvector_t<element_t> m_values; - array_t<int> m_hash; + std::vector<int> m_hash; }; // ---------------------------------------------------------------------------------------- diff --git a/src/lib/netlist/plib/poptions.h b/src/lib/netlist/plib/poptions.h index ea48598d5f5..8a66000053c 100644 --- a/src/lib/netlist/plib/poptions.h +++ b/src/lib/netlist/plib/poptions.h @@ -14,6 +14,7 @@ #include "pstring.h" #include "plists.h" +#include "putil.h" namespace plib { @@ -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; } diff --git a/src/lib/netlist/plib/pparser.cpp b/src/lib/netlist/plib/pparser.cpp index ad60a91b4b1..359e4415d72 100644 --- a/src/lib/netlist/plib/pparser.cpp +++ b/src/lib/netlist/plib/pparser.cpp @@ -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; diff --git a/src/lib/netlist/plib/pparser.h b/src/lib/netlist/plib/pparser.h index dd08d781313..610f524b5e3 100644 --- a/src/lib/netlist/plib/pparser.h +++ b/src/lib/netlist/plib/pparser.h @@ -11,6 +11,7 @@ #include "pconfig.h" #include "pstring.h" #include "plists.h" +#include "putil.h" #include "pstream.h" namespace plib { @@ -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 diff --git a/src/lib/netlist/plib/pstate.cpp b/src/lib/netlist/plib/pstate.cpp index bd16ee172e2..c8c4c5725c6 100644 --- a/src/lib/netlist/plib/pstate.cpp +++ b/src/lib/netlist/plib/pstate.cpp @@ -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[] = { @@ -42,7 +42,7 @@ ATTR_COLD void pstate_manager_t::save_state_ptr(const pstring &stname, const pst 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,21 +54,21 @@ 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; diff --git a/src/lib/netlist/plib/pstate.h b/src/lib/netlist/plib/pstate.h index 846bad2cc68..12115678b3a 100644 --- a/src/lib/netlist/plib/pstate.h +++ b/src/lib/netlist/plib/pstate.h @@ -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,21 +169,21 @@ 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); } }; diff --git a/src/lib/netlist/plib/pstring.cpp b/src/lib/netlist/plib/pstring.cpp index 7dadb9e6240..cb8011734b4 100644 --- a/src/lib/netlist/plib/pstring.cpp +++ b/src/lib/netlist/plib/pstring.cpp @@ -11,6 +11,7 @@ #include <cstdlib> #include <cstdio> #include <algorithm> +#include <stack> #include "pstring.h" #include "palloc.h" @@ -131,8 +132,6 @@ const pstring_t<F> pstring_t<F>::substr(int start, int count) const ret.pcopy(p, 0); else { - //FIXME: Trait to tell which one - //ret.pcopy(cstr() + start, count); // find start for (int i=0; i<start; i++) p += F::codelen(p); @@ -149,7 +148,7 @@ const pstring_t<F> pstring_t<F>::ucase() const { pstring_t ret = *this; ret.pcopy(cstr(), blen()); - for (unsigned i=0; i<ret.len(); i++) + for (std::size_t i=0; i<ret.len(); i++) ret.m_ptr->str()[i] = toupper((unsigned) ret.m_ptr->str()[i]); return ret; } @@ -160,11 +159,11 @@ int pstring_t<F>::find_first_not_of(const pstring_t &no) const char *t = m_ptr->str(); unsigned nolen = no.len(); unsigned tlen = len(); - for (unsigned i=0; i < tlen; i++) + for (std::size_t i=0; i < tlen; i++) { char *n = no.m_ptr->str(); bool f = true; - for (unsigned j=0; j < nolen; j++) + for (std::size_t j=0; j < nolen; j++) { if (F::code(t) == F::code(n)) f = false; @@ -184,11 +183,11 @@ int pstring_t<F>::find_last_not_of(const pstring_t &no) const unsigned nolen = no.len(); unsigned tlen = len(); int last_found = -1; - for (unsigned i=0; i < tlen; i++) + for (std::size_t i=0; i < tlen; i++) { char *n = no.m_ptr->str(); bool f = true; - for (unsigned j=0; j < nolen; j++) + for (std::size_t j=0; j < nolen; j++) { if (F::code(t) == F::code(n)) f = false; @@ -394,7 +393,7 @@ void pstring_t<F>::resetmem() { if (stk != nullptr) { - for (unsigned i=0; i<=16; i++) + for (std::size_t i=0; i<=16; i++) { for (; stk[i].size() > 0; ) { @@ -450,7 +449,7 @@ int pstring_t<F>::find(const pstring_t &search, unsigned start) const const char *s = search.cstr(); const unsigned startt = std::min(start, tlen); const char *t = cstr(); - for (unsigned i=0; i<startt; i++) + for (std::size_t i=0; i<startt; i++) t += F::codelen(t); for (int i=0; i <= (int) tlen - (int) startt - (int) slen; i++) { @@ -479,7 +478,7 @@ int pstring_t<F>::find(const mem_t *search, unsigned start) const const char *s = search; const unsigned startt = std::min(start, tlen); const char *t = cstr(); - for (unsigned i=0; i<startt; i++) + for (std::size_t i=0; i<startt; i++) t += F::codelen(t); for (int i=0; i <= (int) tlen - (int) startt - (int) slen; i++) { diff --git a/src/lib/netlist/plib/ptypes.h b/src/lib/netlist/plib/ptypes.h index 06246846d0e..af8e16a2253 100644 --- a/src/lib/netlist/plib/ptypes.h +++ b/src/lib/netlist/plib/ptypes.h @@ -13,68 +13,16 @@ namespace plib { -//============================================================ -// penum - strongly typed enumeration -//============================================================ + //============================================================ + // penum - strongly typed enumeration + //============================================================ -struct enum_base -{ -protected: - static int from_string_int(const char *str, const char *x) + struct enum_base { - int cnt = 0; - const char *cur = str; - int lx = strlen(x); - while (*str) - { - if (*str == ',') - { - int l = str-cur; - if (l == lx) - if (strncmp(cur, x, lx) == 0) - return cnt; - } - else if (*str == ' ') - { - cur = str + 1; - cnt++; - } - str++; - } - int l = str-cur; - if (l == lx) - if (strncmp(cur, x, lx) == 0) - return cnt; - return -1; - } - static pstring nthstr(int n, const char *str) - { - char buf[64]; - char *bufp = buf; - int cur = 0; - while (*str) - { - if (cur == n) - { - if (*str == ',') - { - *bufp = 0; - return pstring(buf); - } - else if (*str != ' ') - *bufp++ = *str; - } - else - { - if (*str == ',') - cur++; - } - str++; - } - *bufp = 0; - return pstring(buf); - } -}; + protected: + static int from_string_int(const char *str, const char *x); + static pstring nthstr(int n, const char *str); + }; } diff --git a/src/lib/netlist/plib/putil.cpp b/src/lib/netlist/plib/putil.cpp new file mode 100644 index 00000000000..3e5cecc0081 --- /dev/null +++ b/src/lib/netlist/plib/putil.cpp @@ -0,0 +1,161 @@ +// license:GPL-2.0+ +// copyright-holders:Couriersud + +#include <cstring> +#include <cstdlib> +#include <algorithm> +#include <initializer_list> + +#include "plib/putil.h" +#include "plib/ptypes.h" +#include "plib/plists.h" + +namespace plib +{ + namespace util + { + 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; + } + + const pstring environment(const pstring &var, const pstring &default_val) + { + if (getenv(var.cstr()) == nullptr) + return default_val; + else + return pstring(getenv(var.cstr())); + } + } + + pstring_vector_t::pstring_vector_t(const pstring &str, const pstring &onstr, bool ignore_empty) + : 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::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); + } + + + int enum_base::from_string_int(const char *str, const char *x) + { + int cnt = 0; + const char *cur = str; + int lx = strlen(x); + while (*str) + { + if (*str == ',') + { + int l = str-cur; + if (l == lx) + if (strncmp(cur, x, lx) == 0) + return cnt; + } + else if (*str == ' ') + { + cur = str + 1; + cnt++; + } + str++; + } + int l = str-cur; + if (l == lx) + if (strncmp(cur, x, lx) == 0) + return cnt; + return -1; + } + pstring enum_base::nthstr(int n, const char *str) + { + char buf[64]; + char *bufp = buf; + int cur = 0; + while (*str) + { + if (cur == n) + { + if (*str == ',') + { + *bufp = 0; + return pstring(buf); + } + else if (*str != ' ') + *bufp++ = *str; + } + else + { + if (*str == ',') + cur++; + } + str++; + } + *bufp = 0; + return pstring(buf); + } +} // namespace plib + + + diff --git a/src/lib/netlist/plib/putil.h b/src/lib/netlist/plib/putil.h new file mode 100644 index 00000000000..db5510178c0 --- /dev/null +++ b/src/lib/netlist/plib/putil.h @@ -0,0 +1,38 @@ +// license:GPL-2.0+ +// copyright-holders:Couriersud +/* + * putil.h + * + */ + +#ifndef P_UTIL_H_ +#define P_UTIL_H_ + +#include <initializer_list> + +#include "plib/pstring.h" +#include "plib/plists.h" + +namespace plib +{ + namespace util + { + const pstring buildpath(std::initializer_list<pstring> list ); + const pstring environment(const pstring &var, const pstring &default_val = ""); + } + + // ---------------------------------------------------------------------------------------- + // 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); + pstring_vector_t(const pstring &str, const pstring_vector_t &onstrl); + }; + +} + +#endif /* P_UTIL_H_ */ diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp index ed96b517192..302f1d12184 100644 --- a/src/lib/netlist/prg/nltool.cpp +++ b/src/lib/netlist/prg/nltool.cpp @@ -9,6 +9,7 @@ ****************************************************************************/ #include <cstdio> +#include <cstdlib> #ifdef PSTANDALONE #if (PSTANDALONE) @@ -16,7 +17,7 @@ #endif #endif -#include <plib/poptions.h> +#include "plib/poptions.h" #include "plib/pstring.h" #include "plib/plists.h" #include "plib/ptypes.h" @@ -112,11 +113,11 @@ public: { log().debug("Creating dynamic logs ...\n"); plib::pstring_vector_t ll(m_opts ? m_opts->opt_logs() : "" , ":"); - for (unsigned i=0; i < ll.size(); i++) + for (auto & log : ll) { - pstring name = "log_" + ll[i]; + pstring name = "log_" + log; /*netlist_device_t *nc = */ m_setup->register_dev("LOG", name); - m_setup->register_link(name + ".I", ll[i]); + m_setup->register_link(name + ".I", log); } } @@ -161,7 +162,7 @@ struct input_t int e = sscanf(line.cstr(), "%lf,%[^,],%lf", &t, buf, &m_value); if ( e!= 3) throw netlist::fatalerror_e(plib::pfmt("error {1} scanning line {2}\n")(e)(line)); - m_time = netlist::netlist_time::from_double(t); + m_time = netlist::netlist_time(t); m_param = netlist->setup().find_param(buf, true); } @@ -233,16 +234,16 @@ static void run(tool_options_t &opts) t = plib::ticks(); unsigned pos = 0; - netlist::netlist_time nlt = netlist::netlist_time::zero; + netlist::netlist_time nlt = netlist::netlist_time::zero(); - while (pos < inps->size() && (*inps)[pos].m_time < netlist::netlist_time::from_double(ttr)) + while (pos < inps->size() && (*inps)[pos].m_time < netlist::netlist_time(ttr)) { nt.process_queue((*inps)[pos].m_time - nlt); (*inps)[pos].setparam(); nlt = (*inps)[pos].m_time; pos++; } - nt.process_queue(netlist::netlist_time::from_double(ttr) - nlt); + nt.process_queue(netlist::netlist_time(ttr) - nlt); nt.stop(); pfree(inps); @@ -284,18 +285,16 @@ static void listdevices() nt.setup().start_devices(); nt.setup().resolve_inputs(); - for (unsigned i=0; i < list.size(); i++) + for (auto & f : list) { - auto &f = list[i]; pstring out = plib::pfmt("{1} {2}(<id>")(f->classname(),"-20")(f->name()); pstring terms(""); - auto d = f->Create(nt.setup().netlist(), plib::pfmt("dummy{1}")(i)); + auto d = f->Create(nt.setup().netlist(), "dummy"); // get the list of terminals ... - for (unsigned j=0; j < d->m_terminals.size(); j++) + for (auto & inp : d->m_terminals) { - pstring inp = d->m_terminals[j]; if (inp.startsWith(d->name() + ".")) inp = inp.substr(d->name().len() + 1); terms += "," + inp; diff --git a/src/lib/netlist/prg/nlwav.cpp b/src/lib/netlist/prg/nlwav.cpp index 8b53ea8f428..d822b78d231 100644 --- a/src/lib/netlist/prg/nlwav.cpp +++ b/src/lib/netlist/prg/nlwav.cpp @@ -13,15 +13,6 @@ class nlwav_options_t : public plib::options public: nlwav_options_t() : plib::options(), -#if 0 - opt_ttr ("t", "time_to_run", 1.0, "time to run the emulation (seconds)", this), - opt_name("n", "name", "", "netlist in file to run; default is first one", this), - opt_logs("l", "logs", "", "colon separated list of terminals to log", this), - opt_file("f", "file", "-", "file to process (default is stdin)", this), - opt_type("y", "type", "spice", "spice:eagle", "type of file to be converted: spice,eagle", this), - opt_cmd ("c", "cmd", "run", "run|convert|listdevices", this), - opt_inp( "i", "input", "", "input file to process (default is none)", this), -#endif opt_inp( "i", "input", "", "input file", this), opt_out( "o", "output", "", "output file", this), opt_amp( "a", "amp", 10000.0, "amplification after mean correction", this), @@ -29,14 +20,6 @@ public: opt_quiet("q", "quiet", "be quiet - no warnings", this), opt_help("h", "help", "display help", this) {} -#if 0 - option_double opt_ttr; - option_str opt_name; - option_str opt_logs; - option_str opt_file; - poption_str_limit opt_type; - option_str opt_cmd; -#endif plib::option_str opt_inp; plib::option_str opt_out; plib::option_double opt_amp; @@ -67,7 +50,7 @@ public: void write_sample(int sample) { m_data.len += m_fmt.block_align; - short ps = sample; /* 16 bit sample, FIXME: powerpc? */ + short ps = sample; /* 16 bit sample, FIXME: Endianess? */ m_f.write(&ps, sizeof(ps)); } diff --git a/src/lib/netlist/solver/nld_matrix_solver.h b/src/lib/netlist/solver/nld_matrix_solver.h index fcd503daa08..7504191a356 100644 --- a/src/lib/netlist/solver/nld_matrix_solver.h +++ b/src/lib/netlist/solver/nld_matrix_solver.h @@ -10,7 +10,8 @@ #include <type_traits> -#include "solver/nld_solver.h" +//#include "solver/nld_solver.h" +#include "nl_base.h" #include "plib/pstream.h" namespace netlist @@ -18,19 +19,37 @@ namespace netlist namespace devices { + /* FIXME: these should become proper devices */ + + struct solver_parameters_t + { + int m_pivot; + nl_double m_accuracy; + nl_double m_lte; + nl_double m_min_timestep; + nl_double m_max_timestep; + nl_double m_sor; + bool m_dynamic; + int m_gs_loops; + int m_nr_loops; + netlist_time m_nt_sync_delay; + bool m_log_stats; + }; + + class terms_t { P_PREVENT_COPYING(terms_t) public: - ATTR_COLD terms_t() + terms_t() : m_railstart(0) , m_last_V(0.0) , m_DD_n_m_1(0.0) , m_h_n_m_1(1e-6) {} - ATTR_COLD void clear() + void clear() { m_term.clear(); m_net_other.clear(); @@ -40,7 +59,7 @@ public: m_other_curanalog.clear(); } - ATTR_COLD void add(terminal_t *term, int net_other, bool sorted); + void add(terminal_t *term, int net_other, bool sorted); inline unsigned count() { return m_term.size(); } @@ -51,7 +70,7 @@ public: inline nl_double *Idr() { return m_Idr.data(); } inline nl_double **other_curanalog() { return m_other_curanalog.data(); } - ATTR_COLD void set_pointers(); + void set_pointers(); unsigned m_railstart; @@ -74,6 +93,19 @@ private: }; +class proxied_analog_output_t : public analog_output_t +{ +public: + + proxied_analog_output_t(core_device_t &dev, const pstring &aname) + : analog_output_t(dev, aname) + , m_proxied_net(nullptr) + { } + + analog_net_t *m_proxied_net; // only for proxy nets in analog input logic +}; + + class matrix_solver_t : public device_t { public: @@ -96,6 +128,7 @@ public: m_iterative_fail(0), m_iterative_total(0), m_params(*params), + m_last_step(0, 1), m_cur_ts(0), m_fb_sync(*this, "FB_sync"), m_Q_sync(*this, "Q_sync"), @@ -126,6 +159,7 @@ public: void update_forced(); void update_after(const netlist_time &after) { + m_Q_sync.net().toggle_new_Q(); m_Q_sync.net().reschedule_in_queue(after); } @@ -134,7 +168,7 @@ public: NETLIB_RESETI(); public: - ATTR_COLD int get_net_idx(net_t *net); + int get_net_idx(net_t *net); plib::plog_base<NL_DEBUG> &log() { return netlist().log(); } @@ -147,7 +181,7 @@ public: protected: - ATTR_COLD void setup_base(analog_net_t::list_t &nets); + void setup_base(analog_net_t::list_t &nets); void update_dynamic(); virtual void vsetup(analog_net_t::list_t &nets) = 0; @@ -168,7 +202,7 @@ protected: plib::pvector_t<terms_t *> m_terms; plib::pvector_t<analog_net_t *> m_nets; - plib::pvector_t<analog_output_t *> m_inps; + std::vector<std::unique_ptr<proxied_analog_output_t>> m_inps; plib::pvector_t<terms_t *> m_rails_temp; @@ -212,7 +246,7 @@ T matrix_solver_t::delta(const T * RESTRICT V) const unsigned iN = this->m_terms.size(); T cerr = 0; for (unsigned i = 0; i < iN; i++) - cerr = nl_math::max(cerr, nl_math::abs(V[i] - (T) this->m_nets[i]->m_cur_Analog)); + cerr = std::max(cerr, std::abs(V[i] - (T) this->m_nets[i]->m_cur_Analog)); return cerr; } diff --git a/src/lib/netlist/solver/nld_ms_direct.h b/src/lib/netlist/solver/nld_ms_direct.h index 519693af885..f8514867f6e 100644 --- a/src/lib/netlist/solver/nld_ms_direct.h +++ b/src/lib/netlist/solver/nld_ms_direct.h @@ -194,7 +194,7 @@ matrix_solver_direct_t<m_N, storage_N>::~matrix_solver_direct_t() } template <unsigned m_N, unsigned storage_N> -ATTR_COLD void matrix_solver_direct_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets) +void matrix_solver_direct_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets) { if (m_dim < nets.size()) log().fatal("Dimension {1} less than {2}", m_dim, nets.size()); @@ -310,7 +310,7 @@ void matrix_solver_direct_t<m_N, storage_N>::LE_solve() { x_i[p] = i; x_start[p] = chunks * p; - x_stop[p] = nl_math::min(chunks*(p+1), eb); + x_stop[p] = std::min(chunks*(p+1), eb); if (p<num_thr && x_start[p] < x_stop[p]) thr_process(p, this, nullptr); } if (x_start[num_thr] < x_stop[num_thr]) diff --git a/src/lib/netlist/solver/nld_ms_direct_lu.h b/src/lib/netlist/solver/nld_ms_direct_lu.h index b45e23d42ec..47bb95c2855 100644 --- a/src/lib/netlist/solver/nld_ms_direct_lu.h +++ b/src/lib/netlist/solver/nld_ms_direct_lu.h @@ -189,8 +189,8 @@ nl_double matrix_solver_direct_t<m_N, storage_N>::compute_next_timestep() n->m_h_n_m_1 = hn; n->m_DD_n_m_1 = DD_n; - if (nl_math::abs(DD2) > NL_FCONST(1e-30)) // avoid div-by-zero - new_net_timestep = nl_math::sqrt(m_params.m_lte / nl_math::abs(NL_FCONST(0.5)*DD2)); + if (std::abs(DD2) > NL_FCONST(1e-30)) // avoid div-by-zero + new_net_timestep = std::sqrt(m_params.m_lte / std::abs(NL_FCONST(0.5)*DD2)); else new_net_timestep = m_params.m_max_timestep; @@ -206,7 +206,7 @@ nl_double matrix_solver_direct_t<m_N, storage_N>::compute_next_timestep() } template <unsigned m_N, unsigned storage_N> -ATTR_COLD void matrix_solver_direct_t<m_N, storage_N>::add_term(int k, terminal_t *term) +void matrix_solver_direct_t<m_N, storage_N>::add_term(int k, terminal_t *term) { if (term->m_otherterm->net().isRailNet()) { @@ -230,7 +230,7 @@ ATTR_COLD void matrix_solver_direct_t<m_N, storage_N>::add_term(int k, terminal_ template <unsigned m_N, unsigned storage_N> -ATTR_COLD void matrix_solver_direct_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets) +void matrix_solver_direct_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets) { if (m_dim < nets.size()) netlist().error("Dimension {1} less than {2}", m_dim,nets.size()); @@ -550,7 +550,7 @@ nl_double matrix_solver_direct_t<m_N, storage_N>::delta( const unsigned iN = this->N(); nl_double cerr = 0; for (unsigned i = 0; i < iN; i++) - cerr = std::fmax(cerr, nl_math::abs(V[i] - this->m_nets[i]->m_cur_Analog)); + cerr = std::fmax(cerr, std::abs(V[i] - this->m_nets[i]->m_cur_Analog)); return cerr; } diff --git a/src/lib/netlist/solver/nld_ms_gmres.h b/src/lib/netlist/solver/nld_ms_gmres.h index e4ee5fe0cb8..e4c42b2e098 100644 --- a/src/lib/netlist/solver/nld_ms_gmres.h +++ b/src/lib/netlist/solver/nld_ms_gmres.h @@ -121,7 +121,7 @@ int matrix_solver_GMRES_t<m_N, storage_N>::vsolve_non_dynamic(const bool newton_ * * and estimate using * - * omega = 2.0 / (1.0 + nl_math::sqrt(1-rho)) + * omega = 2.0 / (1.0 + std::sqrt(1-rho)) */ //nz_num = 0; @@ -172,7 +172,7 @@ int matrix_solver_GMRES_t<m_N, storage_N>::vsolve_non_dynamic(const bool newton_ int mr = iN; if (iN > 3 ) mr = (int) sqrt(iN) * 2; - int iter = nl_math::max(1, this->m_params.m_gs_loops); + int iter = std::max(1, this->m_params.m_gs_loops); int gsl = solve_ilu_gmres(new_V, RHS, iter, mr, accuracy); int failed = mr * iter; @@ -262,12 +262,12 @@ int matrix_solver_GMRES_t<m_N, storage_N>::solve_ilu_gmres (nl_double * RESTRICT mat.mult_vec(m_A, t, Ax); mat.solveLUx(m_LU, Ax); - const nl_double rho_to_accuracy = nl_math::sqrt(vecmult2(n, Ax)) / accuracy; + const nl_double rho_to_accuracy = std::sqrt(vecmult2(n, Ax)) / accuracy; rho_delta = accuracy * rho_to_accuracy; } else - rho_delta = accuracy * nl_math::sqrt((double) n) * m_accuracy_mult; + rho_delta = accuracy * std::sqrt((double) n) * m_accuracy_mult; for (unsigned itr = 0; itr < restart_max; itr++) { @@ -287,7 +287,7 @@ int matrix_solver_GMRES_t<m_N, storage_N>::solve_ilu_gmres (nl_double * RESTRICT mat.solveLUx(m_LU, residual); } - rho = nl_math::sqrt(vecmult2(n, residual)); + rho = std::sqrt(vecmult2(n, residual)); vec_mult_scalar(n, residual, NL_FCONST(1.0) / rho, m_v[0]); @@ -311,7 +311,7 @@ int matrix_solver_GMRES_t<m_N, storage_N>::solve_ilu_gmres (nl_double * RESTRICT m_ht[j][k] = vecmult(n, m_v[k1], m_v[j]); vec_add_mult_scalar(n, m_v[j], -m_ht[j][k], m_v[k1]); } - m_ht[k1][k] = nl_math::sqrt(vecmult2(n, m_v[k1])); + m_ht[k1][k] = std::sqrt(vecmult2(n, m_v[k1])); if (m_ht[k1][k] != 0.0) vec_scale(n, m_v[k1], NL_FCONST(1.0) / m_ht[k1][k]); @@ -319,7 +319,7 @@ int matrix_solver_GMRES_t<m_N, storage_N>::solve_ilu_gmres (nl_double * RESTRICT for (unsigned j = 0; j < k; j++) givens_mult(m_c[j], m_s[j], m_ht[j][k], m_ht[j+1][k]); - mu = nl_math::hypot(m_ht[k][k], m_ht[k1][k]); + mu = std::hypot(m_ht[k][k], m_ht[k1][k]); m_c[k] = m_ht[k][k] / mu; m_s[k] = -m_ht[k1][k] / mu; @@ -328,7 +328,7 @@ int matrix_solver_GMRES_t<m_N, storage_N>::solve_ilu_gmres (nl_double * RESTRICT givens_mult(m_c[k], m_s[k], m_g[k], m_g[k1]); - rho = nl_math::abs(m_g[k1]); + rho = std::abs(m_g[k1]); itr_used = itr_used + 1; diff --git a/src/lib/netlist/solver/nld_ms_sm.h b/src/lib/netlist/solver/nld_ms_sm.h index 331161751f9..7ed72bcd575 100644 --- a/src/lib/netlist/solver/nld_ms_sm.h +++ b/src/lib/netlist/solver/nld_ms_sm.h @@ -121,7 +121,7 @@ matrix_solver_sm_t<m_N, storage_N>::~matrix_solver_sm_t() } template <unsigned m_N, unsigned storage_N> -ATTR_COLD void matrix_solver_sm_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets) +void matrix_solver_sm_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets) { if (m_dim < nets.size()) log().fatal("Dimension {1} less than {2}", m_dim, nets.size()); diff --git a/src/lib/netlist/solver/nld_ms_sor.h b/src/lib/netlist/solver/nld_ms_sor.h index 5ccb7af6bc0..a198fa6bf57 100644 --- a/src/lib/netlist/solver/nld_ms_sor.h +++ b/src/lib/netlist/solver/nld_ms_sor.h @@ -66,7 +66,7 @@ int matrix_solver_SOR_t<m_N, storage_N>::vsolve_non_dynamic(const bool newton_ra * * and estimate using * - * omega = 2.0 / (1.0 + nl_math::sqrt(1-rho)) + * omega = 2.0 / (1.0 + std::sqrt(1-rho)) */ const nl_double ws = this->m_params.m_sor; @@ -104,7 +104,7 @@ int matrix_solver_SOR_t<m_N, storage_N>::vsolve_non_dynamic(const bool newton_ra if (USE_GABS) { for (unsigned i = 0; i < term_count; i++) - gabs_t = gabs_t + nl_math::abs(go[i]); + gabs_t = gabs_t + std::abs(go[i]); gabs_t *= NL_FCONST(0.5); // derived by try and error if (gabs_t <= gtot_t) @@ -149,7 +149,7 @@ int matrix_solver_SOR_t<m_N, storage_N>::vsolve_non_dynamic(const bool newton_ra const nl_double new_val = new_V[k] * one_m_w[k] + (Idrive + RHS[k]) * w[k]; - err = nl_math::max(nl_math::abs(new_val - new_V[k]), err); + err = std::max(std::abs(new_val - new_V[k]), err); new_V[k] = new_val; } diff --git a/src/lib/netlist/solver/nld_ms_sor_mat.h b/src/lib/netlist/solver/nld_ms_sor_mat.h index e828d1a6c31..8fa871d83f4 100644 --- a/src/lib/netlist/solver/nld_ms_sor_mat.h +++ b/src/lib/netlist/solver/nld_ms_sor_mat.h @@ -108,7 +108,7 @@ nl_double matrix_solver_SOR_mat_t<m_N, storage_N>::vsolve() // FIXME: used to be 1e90, but this would not be compatible with float if (sqo > NL_FCONST(1e-20)) - m_lp_fact = nl_math::min(nl_math::sqrt(sq/sqo), (nl_double) 2.0); + m_lp_fact = std::min(std::sqrt(sq/sqo), (nl_double) 2.0); else m_lp_fact = NL_FCONST(0.0); } @@ -149,16 +149,16 @@ int matrix_solver_SOR_mat_t<m_N, storage_N>::vsolve_non_dynamic(const bool newto for (int k = 0; k < iN; k++) { #if 0 - nl_double akk = nl_math::abs(this->m_A[k][k]); + nl_double akk = std::abs(this->m_A[k][k]); if ( akk > lambdaN) lambdaN = akk; if (akk < lambda1) lambda1 = akk; #else - nl_double akk = nl_math::abs(this->m_A[k][k]); + nl_double akk = std::abs(this->m_A[k][k]); nl_double s = 0.0; for (int i=0; i<iN; i++) - s = s + nl_math::abs(this->m_A[k][i]); + s = s + std::abs(this->m_A[k][i]); akk = s / akk - 1.0; if ( akk > lambdaN) lambdaN = akk; @@ -192,7 +192,7 @@ int matrix_solver_SOR_mat_t<m_N, storage_N>::vsolve_non_dynamic(const bool newto Idrive = Idrive + this->A(k,p[i]) * new_v[p[i]]; const nl_double delta = m_omega * (this->RHS(k) - Idrive) / this->A(k,k); - cerr = nl_math::max(cerr, nl_math::abs(delta)); + cerr = std::max(cerr, std::abs(delta)); new_v[k] += delta; } diff --git a/src/lib/netlist/solver/nld_ms_w.h b/src/lib/netlist/solver/nld_ms_w.h index cd70d82024b..19c84ef80bc 100644 --- a/src/lib/netlist/solver/nld_ms_w.h +++ b/src/lib/netlist/solver/nld_ms_w.h @@ -130,7 +130,7 @@ matrix_solver_w_t<m_N, storage_N>::~matrix_solver_w_t() } template <unsigned m_N, unsigned storage_N> -ATTR_COLD void matrix_solver_w_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets) +void matrix_solver_w_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets) { if (m_dim < nets.size()) log().fatal("Dimension {1} less than {2}", m_dim, nets.size()); @@ -360,8 +360,8 @@ int matrix_solver_w_t<m_N, storage_N>::solve_non_dynamic(ATTR_UNUSED const bool { tmp += A(i,j) * new_V[j]; } - if (nl_math::abs(tmp-RHS(i)) > 1e-6) - printf("%s failed on row %d: %f RHS: %f\n", this->name().cstr(), i, nl_math::abs(tmp-RHS(i)), RHS(i)); + if (std::abs(tmp-RHS(i)) > 1e-6) + printf("%s failed on row %d: %f RHS: %f\n", this->name().cstr(), i, std::abs(tmp-RHS(i)), RHS(i)); } if (newton_raphson) { diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp index 8a639db596a..0a9d6360dc8 100644 --- a/src/lib/netlist/solver/nld_solver.cpp +++ b/src/lib/netlist/solver/nld_solver.cpp @@ -37,6 +37,7 @@ #include "omp.h" #endif +#include "plib/putil.h" #include "nld_solver.h" #include "nld_matrix_solver.h" @@ -59,7 +60,7 @@ namespace netlist namespace devices { -ATTR_COLD void terms_t::add(terminal_t *term, int net_other, bool sorted) +void terms_t::add(terminal_t *term, int net_other, bool sorted) { if (sorted) for (unsigned i=0; i < m_net_other.size(); i++) @@ -83,7 +84,7 @@ ATTR_COLD void terms_t::add(terminal_t *term, int net_other, bool sorted) m_other_curanalog.push_back(nullptr); } -ATTR_COLD void terms_t::set_pointers() +void terms_t::set_pointers() { for (unsigned i = 0; i < count(); i++) { @@ -96,9 +97,8 @@ ATTR_COLD void terms_t::set_pointers() // matrix_solver // ---------------------------------------------------------------------------------------- -ATTR_COLD matrix_solver_t::~matrix_solver_t() +matrix_solver_t::~matrix_solver_t() { - m_inps.clear_and_free(); for (unsigned k = 0; k < m_terms.size(); k++) { plib::pfree(m_terms[k]); @@ -106,7 +106,7 @@ ATTR_COLD matrix_solver_t::~matrix_solver_t() } -ATTR_COLD void matrix_solver_t::setup_base(analog_net_t::list_t &nets) +void matrix_solver_t::setup_base(analog_net_t::list_t &nets) { log().debug("New solver setup\n"); @@ -122,11 +122,11 @@ ATTR_COLD void matrix_solver_t::setup_base(analog_net_t::list_t &nets) for (std::size_t k = 0; k < nets.size(); k++) { - log().debug("setting up net\n"); - analog_net_t *net = nets[k]; - net->m_solver = this; + log().debug("setting up net\n"); + + net->set_solver(this); for (core_terminal_t *p : net->m_core_terms) { @@ -137,7 +137,7 @@ ATTR_COLD void matrix_solver_t::setup_base(analog_net_t::list_t &nets) if (p->device().is_timestep()) if (!m_step_devices.contains(&p->device())) m_step_devices.push_back(&p->device()); - if (p->device().is_dynamic1()) + if (p->device().is_dynamic()) if (!m_dynamic_devices.contains(&p->device())) m_dynamic_devices.push_back(&p->device()); { @@ -148,11 +148,11 @@ ATTR_COLD void matrix_solver_t::setup_base(analog_net_t::list_t &nets) break; case terminal_t::INPUT: { - analog_output_t *net_proxy_output = nullptr; + proxied_analog_output_t *net_proxy_output = nullptr; for (auto & input : m_inps) - if (input->m_proxied_net == &p->net().as_analog()) + if (input->m_proxied_net == &p->net()) { - net_proxy_output = input; + net_proxy_output = input.get(); break; } @@ -161,9 +161,11 @@ ATTR_COLD void matrix_solver_t::setup_base(analog_net_t::list_t &nets) //net_proxy_output = palloc(analog_output_t(*this, // this->name() + "." + plib::pfmt("m{1}")(m_inps.size()))); - net_proxy_output = plib::palloc<analog_output_t>(*this, this->name() + "." + plib::pfmt("m{1}")(m_inps.size())); - m_inps.push_back(net_proxy_output); - net_proxy_output->m_proxied_net = &p->net().as_analog(); + auto net_proxy_output_u = plib::make_unique<proxied_analog_output_t>(*this, this->name() + "." + plib::pfmt("m{1}")(m_inps.size())); + net_proxy_output = net_proxy_output_u.get(); + m_inps.push_back(std::move(net_proxy_output_u)); + nl_assert(p->net().is_analog()); + net_proxy_output->m_proxied_net = static_cast<analog_net_t *>(&p->net()); } net_proxy_output->net().register_con(*p); // FIXME: repeated @@ -183,7 +185,7 @@ ATTR_COLD void matrix_solver_t::setup_base(analog_net_t::list_t &nets) setup_matrix(); } -ATTR_COLD void matrix_solver_t::setup_matrix() +void matrix_solver_t::setup_matrix() { const unsigned iN = m_nets.size(); @@ -379,25 +381,31 @@ void matrix_solver_t::update_dynamic() m_dynamic_devices[i]->update_terminals(); } -ATTR_COLD void matrix_solver_t::reset() +void matrix_solver_t::reset() { - m_last_step = netlist_time::zero; + m_last_step = netlist_time::zero(); } -ATTR_COLD void matrix_solver_t::update() NOEXCEPT +void matrix_solver_t::update() NOEXCEPT { const netlist_time new_timestep = solve(); - if (m_params.m_dynamic && has_timestep_devices() && new_timestep > netlist_time::zero) + if (m_params.m_dynamic && has_timestep_devices() && new_timestep > netlist_time::zero()) + { + m_Q_sync.net().toggle_new_Q(); m_Q_sync.net().reschedule_in_queue(new_timestep); + } } -ATTR_COLD void matrix_solver_t::update_forced() +void matrix_solver_t::update_forced() { ATTR_UNUSED const netlist_time new_timestep = solve(); if (m_params.m_dynamic && has_timestep_devices()) - m_Q_sync.net().reschedule_in_queue(netlist_time::from_double(m_params.m_min_timestep)); + { + m_Q_sync.net().toggle_new_Q(); + m_Q_sync.net().reschedule_in_queue(netlist_time(m_params.m_min_timestep)); + } } void matrix_solver_t::step(const netlist_time &delta) @@ -427,6 +435,7 @@ const netlist_time matrix_solver_t::solve_base() if (this_resched > 1 && !m_Q_sync.net().is_queued()) { log().warning("NEWTON_LOOPS exceeded on net {1}... reschedule", this->name()); + m_Q_sync.net().toggle_new_Q(); m_Q_sync.net().reschedule_in_queue(m_params.m_nt_sync_delay); } } @@ -459,7 +468,7 @@ const netlist_time matrix_solver_t::solve() return next_time_step; } -ATTR_COLD int matrix_solver_t::get_net_idx(net_t *net) +int matrix_solver_t::get_net_idx(net_t *net) { for (std::size_t k = 0; k < m_nets.size(); k++) if (m_nets[k] == net) @@ -467,7 +476,7 @@ ATTR_COLD int matrix_solver_t::get_net_idx(net_t *net) return -1; } -ATTR_COLD void matrix_solver_t::add_term(int k, terminal_t *term) +void matrix_solver_t::add_term(int k, terminal_t *term) { if (term->m_otherterm->net().isRailNet()) { @@ -512,8 +521,8 @@ netlist_time matrix_solver_t::compute_next_timestep() t->m_h_n_m_1 = hn; t->m_DD_n_m_1 = DD_n; - if (nl_math::abs(DD2) > NL_FCONST(1e-30)) // avoid div-by-zero - new_net_timestep = nl_math::sqrt(m_params.m_lte / nl_math::abs(NL_FCONST(0.5)*DD2)); + if (std::abs(DD2) > NL_FCONST(1e-30)) // avoid div-by-zero + new_net_timestep = std::sqrt(m_params.m_lte / std::abs(NL_FCONST(0.5)*DD2)); else new_net_timestep = m_params.m_max_timestep; @@ -527,7 +536,7 @@ netlist_time matrix_solver_t::compute_next_timestep() } //if (new_solver_timestep > 10.0 * hn) // new_solver_timestep = 10.0 * hn; - return netlist_time::from_double(new_solver_timestep); + return netlist_time(new_solver_timestep); } @@ -577,7 +586,6 @@ NETLIB_STOP(solver) NETLIB_NAME(solver)::~NETLIB_NAME(solver)() { - m_mat_solvers.clear_and_free(); } NETLIB_UPDATE(solver) @@ -620,18 +628,19 @@ NETLIB_UPDATE(solver) /* step circuit */ if (!m_Q_step.net().is_queued()) { - m_Q_step.net().push_to_queue(netlist_time::from_double(m_params.m_max_timestep)); + m_Q_step.net().toggle_new_Q(); + m_Q_step.net().push_to_queue(netlist_time(m_params.m_max_timestep)); } } template <int m_N, int storage_N> -matrix_solver_t * NETLIB_NAME(solver)::create_solver(int size, const bool use_specific) +std::unique_ptr<matrix_solver_t> NETLIB_NAME(solver)::create_solver(int size, const bool use_specific) { pstring solvername = plib::pfmt("Solver_{1}")(m_mat_solvers.size()); if (use_specific && m_N == 1) - return plib::palloc<matrix_solver_direct1_t>(netlist(), solvername, &m_params); + return plib::make_unique<matrix_solver_direct1_t>(netlist(), solvername, &m_params); else if (use_specific && m_N == 2) - return plib::palloc<matrix_solver_direct2_t>(netlist(), solvername, &m_params); + return plib::make_unique<matrix_solver_direct2_t>(netlist(), solvername, &m_params); else { if (size >= m_gs_threshold) @@ -639,39 +648,39 @@ matrix_solver_t * NETLIB_NAME(solver)::create_solver(int size, const bool use_sp if (pstring("SOR_MAT").equals(m_iterative_solver)) { typedef matrix_solver_SOR_mat_t<m_N,storage_N> solver_sor_mat; - return plib::palloc<solver_sor_mat>(netlist(), solvername, &m_params, size); + return plib::make_unique<solver_sor_mat>(netlist(), solvername, &m_params, size); } else if (pstring("MAT_CR").equals(m_iterative_solver)) { typedef matrix_solver_GCR_t<m_N,storage_N> solver_mat; - return plib::palloc<solver_mat>(netlist(), solvername, &m_params, size); + return plib::make_unique<solver_mat>(netlist(), solvername, &m_params, size); } else if (pstring("MAT").equals(m_iterative_solver)) { typedef matrix_solver_direct_t<m_N,storage_N> solver_mat; - return plib::palloc<solver_mat>(netlist(), solvername, &m_params, size); + return plib::make_unique<solver_mat>(netlist(), solvername, &m_params, size); } else if (pstring("SM").equals(m_iterative_solver)) { /* Sherman-Morrison Formula */ typedef matrix_solver_sm_t<m_N,storage_N> solver_mat; - return plib::palloc<solver_mat>(netlist(), solvername, &m_params, size); + return plib::make_unique<solver_mat>(netlist(), solvername, &m_params, size); } else if (pstring("W").equals(m_iterative_solver)) { /* Woodbury Formula */ typedef matrix_solver_w_t<m_N,storage_N> solver_mat; - return plib::palloc<solver_mat>(netlist(), solvername, &m_params, size); + return plib::make_unique<solver_mat>(netlist(), solvername, &m_params, size); } else if (pstring("SOR").equals(m_iterative_solver)) { typedef matrix_solver_SOR_t<m_N,storage_N> solver_GS; - return plib::palloc<solver_GS>(netlist(), solvername, &m_params, size); + return plib::make_unique<solver_GS>(netlist(), solvername, &m_params, size); } else if (pstring("GMRES").equals(m_iterative_solver)) { typedef matrix_solver_GMRES_t<m_N,storage_N> solver_GMRES; - return plib::palloc<solver_GMRES>(netlist(), solvername, &m_params, size); + return plib::make_unique<solver_GMRES>(netlist(), solvername, &m_params, size); } else { @@ -682,12 +691,12 @@ matrix_solver_t * NETLIB_NAME(solver)::create_solver(int size, const bool use_sp else { typedef matrix_solver_direct_t<m_N,storage_N> solver_D; - return plib::palloc<solver_D>(netlist(), solvername, &m_params, size); + return plib::make_unique<solver_D>(netlist(), solvername, &m_params, size); } } } -ATTR_COLD void NETLIB_NAME(solver)::post_start() +void NETLIB_NAME(solver)::post_start() { plib::pvector_t<analog_net_t::list_t> groups; const bool use_specific = true; @@ -696,7 +705,7 @@ ATTR_COLD void NETLIB_NAME(solver)::post_start() m_params.m_accuracy = m_accuracy.Value(); m_params.m_gs_loops = m_gs_loops.Value(); m_params.m_nr_loops = m_nr_loops.Value(); - m_params.m_nt_sync_delay = netlist_time::from_double(m_sync_delay.Value()); + m_params.m_nt_sync_delay = netlist_time(m_sync_delay.Value()); m_params.m_lte = m_lte.Value(); m_params.m_sor = m_sor.Value(); @@ -714,7 +723,7 @@ ATTR_COLD void NETLIB_NAME(solver)::post_start() } // Override log statistics - pstring p = nl_util::environment("NL_STATS"); + pstring p = plib::util::environment("NL_STATS"); if (p != "") m_params.m_log_stats = (bool) p.as_long(); else @@ -728,7 +737,8 @@ ATTR_COLD void NETLIB_NAME(solver)::post_start() if (!net->isRailNet()) { netlist().log().debug(" ==> not a rail net\n"); - analog_net_t *n = &net->as_analog(); + /* Must be an analog net */ + analog_net_t *n = static_cast<analog_net_t *>(net.get()); if (!n->already_processed(groups)) { groups.push_back(analog_net_t::list_t()); @@ -741,7 +751,7 @@ ATTR_COLD void NETLIB_NAME(solver)::post_start() netlist().log().verbose("Found {1} net groups in {2} nets\n", groups.size(), netlist().m_nets.size()); for (auto & grp : groups) { - matrix_solver_t *ms; + std::unique_ptr<matrix_solver_t> ms; std::size_t net_count = grp.size(); switch (net_count) @@ -825,8 +835,6 @@ ATTR_COLD void NETLIB_NAME(solver)::post_start() ms->set_delegate_pointer(); ms->setup(grp); - m_mat_solvers.push_back(ms); - netlist().log().verbose("Solver {1}", ms->name()); netlist().log().verbose(" ==> {2} nets", grp.size()); netlist().log().verbose(" has {1} elements", ms->has_dynamic_devices() ? "dynamic" : "no dynamic"); @@ -839,6 +847,8 @@ ATTR_COLD void NETLIB_NAME(solver)::post_start() netlist().log().verbose(" {1}", pcore->name()); } } + + m_mat_solvers.push_back(std::move(ms)); } } diff --git a/src/lib/netlist/solver/nld_solver.h b/src/lib/netlist/solver/nld_solver.h index ba604352aac..a02a6e69311 100644 --- a/src/lib/netlist/solver/nld_solver.h +++ b/src/lib/netlist/solver/nld_solver.h @@ -11,6 +11,7 @@ #include "nl_setup.h" #include "nl_base.h" #include "plib/pstream.h" +#include "solver/nld_matrix_solver.h" //#define ATTR_ALIGNED(N) __attribute__((aligned(N))) #define ATTR_ALIGNED(N) ATTR_ALIGN @@ -34,23 +35,6 @@ namespace netlist class NETLIB_NAME(solver); -/* FIXME: these should become proper devices */ - -struct solver_parameters_t -{ - int m_pivot; - nl_double m_accuracy; - nl_double m_lte; - nl_double m_min_timestep; - nl_double m_max_timestep; - nl_double m_sor; - bool m_dynamic; - int m_gs_loops; - int m_nr_loops; - netlist_time m_nt_sync_delay; - bool m_log_stats; -}; - class matrix_solver_t; @@ -122,13 +106,13 @@ protected: param_logic_t m_log_stats; - plib::pvector_t<matrix_solver_t *> m_mat_solvers; + std::vector<std::unique_ptr<matrix_solver_t>> m_mat_solvers; private: solver_parameters_t m_params; template <int m_N, int storage_N> - matrix_solver_t *create_solver(int size, bool use_specific); + std::unique_ptr<matrix_solver_t> create_solver(int size, bool use_specific); }; } //namespace devices diff --git a/src/lib/netlist/solver/vector_base.h b/src/lib/netlist/solver/vector_base.h index b721596e44d..3f0c53c8ade 100644 --- a/src/lib/netlist/solver/vector_base.h +++ b/src/lib/netlist/solver/vector_base.h @@ -103,7 +103,7 @@ inline double vec_maxabs(const std::size_t & n, const double * RESTRICT v) { double ret = 0.0; for ( std::size_t i = 0; i < n; i++ ) - ret = nl_math::max(ret, nl_math::abs(v[i])); + ret = std::max(ret, std::abs(v[i])); return ret; } diff --git a/src/mame/machine/nl_pong.cpp b/src/mame/machine/nl_pong.cpp index 5192b2ec1c7..456448ab067 100644 --- a/src/mame/machine/nl_pong.cpp +++ b/src/mame/machine/nl_pong.cpp @@ -12,30 +12,10 @@ #define FAST_CLOCK (1) #ifndef __PLIB_PREPROCESSOR__ -#if 0 -#define TTL_7400A_NAND(_name, _A, _B) TTL_7400_NAND(_name, _A, _B) -#else -#define TTL_7400A_NAND(_name, _A, _B) \ - NET_REGISTER_DEV(TTL_7400A_NAND, _name) \ - NET_CONNECT(_name, A, _A) \ - NET_CONNECT(_name, B, _B) -#endif #endif -NETLIST_START(lib) - TRUTHTABLE_START(TTL_7400A_NAND, 2, 1, 0, "A,B") - TT_HEAD(" A , B | Q ") - TT_LINE(" 0 , X | 1 |22") - TT_LINE(" X , 0 | 1 |22") - TT_LINE(" 1 , 1 | 0 |15") - TRUTHTABLE_END() -NETLIST_END() - NETLIST_START(pong_fast) - LOCAL_SOURCE(lib) - - INCLUDE(lib) SOLVER(Solver, 48000) PARAM(Solver.PARALLEL, 0) // Don't do parallel solvers PARAM(Solver.ACCURACY, 1e-4) // works and is sufficient @@ -144,7 +124,7 @@ NETLIST_START(pong_fast) /* hit logic */ TTL_7404_INVERT(hitQ, hit) - TTL_7400A_NAND(hit, hit1Q, hit2Q) + TTL_7400_NAND(hit, hit1Q, hit2Q) TTL_7402_NOR(attractQ, StopG, runQ) TTL_7404_INVERT(attract, attractQ) @@ -152,22 +132,22 @@ NETLIST_START(pong_fast) TTL_7420_NAND(ic_h6a, hvidQ, hvidQ, hvidQ, hvidQ) ALIAS(hvid, ic_h6a.Q) - TTL_7400A_NAND(ic_e6c, hvid, hblank) + TTL_7400_NAND(ic_e6c, hvid, hblank) ALIAS(MissQ, ic_e6c.Q) TTL_7404_INVERT(ic_d1e, MissQ) - TTL_7400A_NAND(ic_e1a, ic_d1e.Q, attractQ) + TTL_7400_NAND(ic_e1a, ic_d1e.Q, attractQ) ALIAS(Missed, ic_e1a.Q) - TTL_7400A_NAND(rstspeed, SRSTQ, MissQ) - TTL_7400A_NAND(StopG, StopG1Q, StopG2Q) + TTL_7400_NAND(rstspeed, SRSTQ, MissQ) + TTL_7400_NAND(StopG, StopG1Q, StopG2Q) ALIAS(L, ic_h3b.Q) ALIAS(R, ic_h3b.QQ) - TTL_7400A_NAND(hit1Q, pad1, ic_g1b.Q) - TTL_7400A_NAND(hit2Q, pad2, ic_g1b.Q) + TTL_7400_NAND(hit1Q, pad1, ic_g1b.Q) + TTL_7400_NAND(hit2Q, pad2, ic_g1b.Q) - TTL_7400A_NAND(ic_g3c, 128H, ic_h3a.QQ) + TTL_7400_NAND(ic_g3c, 128H, ic_h3a.QQ) TTL_7427_NOR(ic_g2c, ic_g3c.Q, 256H, vpad1Q) ALIAS(pad1, ic_g2c.Q) TTL_7427_NOR(ic_g2a, ic_g3c.Q, 256HQ, vpad2Q) @@ -217,15 +197,15 @@ NETLIST_START(pong_fast) // hblank flip flop // ---------------------------------------------------------------------------------------- - TTL_7400A_NAND(ic_g5b, 16H, 64H) + TTL_7400_NAND(ic_g5b, 16H, 64H) // the time critical one - TTL_7400A_NAND(ic_h5c, ic_h5b.Q, hresetQ) - TTL_7400A_NAND(ic_h5b, ic_h5c.Q, ic_g5b.Q) + TTL_7400_NAND(ic_h5c, ic_h5b.Q, hresetQ) + TTL_7400_NAND(ic_h5b, ic_h5c.Q, ic_g5b.Q) ALIAS(hblank, ic_h5c.Q) ALIAS(hblankQ, ic_h5b.Q) - TTL_7400A_NAND(hsyncQ, hblank, 32H) + TTL_7400_NAND(hsyncQ, hblank, 32H) // ---------------------------------------------------------------------------------------- // vblank flip flop @@ -236,7 +216,7 @@ NETLIST_START(pong_fast) ALIAS(vblank, ic_f5d.Q) ALIAS(vblankQ, ic_f5c.Q) - TTL_7400A_NAND(ic_h5a, 8V, 8V) + TTL_7400_NAND(ic_h5a, 8V, 8V) TTL_7410_NAND(ic_g5a, vblank, 4V, ic_h5a.Q) ALIAS(vsyncQ, ic_g5a.Q) @@ -244,31 +224,31 @@ NETLIST_START(pong_fast) // move logic // ---------------------------------------------------------------------------------------- - TTL_7400A_NAND(ic_e1d, hit_sound, ic_e1c.Q) - TTL_7400A_NAND(ic_e1c, ic_f1.QC, ic_f1.QD) + TTL_7400_NAND(ic_e1d, hit_sound, ic_e1c.Q) + TTL_7400_NAND(ic_e1c, ic_f1.QC, ic_f1.QD) TTL_7493(ic_f1, ic_e1d.Q, ic_f1.QA, rstspeed, rstspeed) TTL_7402_NOR(ic_g1d, ic_f1.QC, ic_f1.QD) - TTL_7400A_NAND(ic_h1a, ic_g1d.Q, ic_g1d.Q) - TTL_7400A_NAND(ic_h1d, ic_e1c.Q, ic_h1a.Q) + TTL_7400_NAND(ic_h1a, ic_g1d.Q, ic_g1d.Q) + TTL_7400_NAND(ic_h1d, ic_e1c.Q, ic_h1a.Q) - TTL_7400A_NAND(ic_h1c, ic_h1d.Q, vreset) - TTL_7400A_NAND(ic_h1b, ic_h1a.Q, vreset) + TTL_7400_NAND(ic_h1c, ic_h1d.Q, vreset) + TTL_7400_NAND(ic_h1b, ic_h1a.Q, vreset) TTL_7402_NOR(ic_g1c, 256HQ, vreset) TTL_74107(ic_h2a, ic_g1c.Q, ic_h2b.Q, low, ic_h1b.Q) TTL_74107(ic_h2b, ic_g1c.Q, high, move, ic_h1c.Q) - TTL_7400A_NAND(ic_h4a, ic_h2b.Q, ic_h2a.Q) + TTL_7400_NAND(ic_h4a, ic_h2b.Q, ic_h2a.Q) ALIAS(move, ic_h4a.Q) - TTL_7400A_NAND(ic_c1d, SC, attract) + TTL_7400_NAND(ic_c1d, SC, attract) TTL_7404_INVERT(ic_d1a, ic_c1d.Q) TTL_7474(ic_h3b, ic_d1a.Q, ic_h3b.QQ, hit1Q, hit2Q) - TTL_7400A_NAND(ic_h4d, ic_h3b.Q, move) - TTL_7400A_NAND(ic_h4b, ic_h3b.QQ, move) - TTL_7400A_NAND(ic_h4c, ic_h4d.Q, ic_h4b.Q) + TTL_7400_NAND(ic_h4d, ic_h3b.Q, move) + TTL_7400_NAND(ic_h4b, ic_h3b.QQ, move) + TTL_7400_NAND(ic_h4c, ic_h4d.Q, ic_h4b.Q) ALIAS(Aa, ic_h4c.Q) ALIAS(Ba, ic_h4b.Q) @@ -276,7 +256,7 @@ NETLIST_START(pong_fast) // hvid circuit // ---------------------------------------------------------------------------------------- - TTL_7400A_NAND(hball_resetQ, Serve, attractQ) + TTL_7400_NAND(hball_resetQ, Serve, attractQ) TTL_9316(ic_g7, clk, high, hblankQ, hball_resetQ, ic_g5c.Q, Aa, Ba, low, high) TTL_9316(ic_h7, clk, ic_g7.RC, high, hball_resetQ, ic_g5c.Q, low, low, low, high) @@ -291,7 +271,7 @@ NETLIST_START(pong_fast) TTL_9316(ic_b3, hsyncQ, high, vblankQ, high, ic_b2b.Q, a6, b6, c6, d6) TTL_9316(ic_a3, hsyncQ, ic_b3.RC, high, high, ic_b2b.Q, low, low, low, low) - TTL_7400A_NAND(ic_b2b, ic_a3.RC, ic_b3.RC) + TTL_7400_NAND(ic_b2b, ic_a3.RC, ic_b3.RC) TTL_7410_NAND(ic_e2b, ic_a3.RC, ic_b3.QC, ic_b3.QD) ALIAS(vvidQ, ic_e2b.Q) TTL_7404_INVERT(vvid, vvidQ) // D2D @@ -383,12 +363,12 @@ NETLIST_START(pong_fast) NET_C(GND, ic_g4_C.2) ALIAS(hit_sound_en, ic_c2a.QQ) - TTL_7400A_NAND(hit_sound, hit_sound_en, vpos16) - TTL_7400A_NAND(score_sound, SC, vpos32) - TTL_7400A_NAND(topbothitsound, ic_f3_topbot.Q, vpos32) + TTL_7400_NAND(hit_sound, hit_sound_en, vpos16) + TTL_7400_NAND(score_sound, SC, vpos32) + TTL_7400_NAND(topbothitsound, ic_f3_topbot.Q, vpos32) TTL_7410_NAND(ic_c4b, topbothitsound, hit_sound, score_sound) - TTL_7400A_NAND(ic_c1b, ic_c4b.Q, attractQ) + TTL_7400_NAND(ic_c1b, ic_c4b.Q, attractQ) ALIAS(sound, ic_c1b.Q) @@ -422,9 +402,9 @@ NETLIST_START(pong_fast) NET_C(GND, ic_b9_C.2) TTL_7404_INVERT(ic_c9b, ic_b9.OUT) - TTL_7400A_NAND(ic_b7b, ic_a7b.Q, hsyncQ) + TTL_7400_NAND(ic_b7b, ic_a7b.Q, hsyncQ) TTL_7493(ic_b8, ic_b7b.Q, ic_b8.QA, ic_b9.OUT, ic_b9.OUT) - TTL_7400A_NAND(ic_b7a, ic_c9b.Q, ic_a7b.Q) + TTL_7400_NAND(ic_b7a, ic_c9b.Q, ic_a7b.Q) TTL_7420_NAND(ic_a7b, ic_b8.QA, ic_b8.QB, ic_b8.QC, ic_b8.QD) ALIAS(vpad1Q, ic_b7a.Q) @@ -462,9 +442,9 @@ NETLIST_START(pong_fast) NET_C(GND, ic_a9_C.2) TTL_7404_INVERT(ic_c9a, ic_a9.OUT) - TTL_7400A_NAND(ic_b7c, ic_a7a.Q, hsyncQ) + TTL_7400_NAND(ic_b7c, ic_a7a.Q, hsyncQ) TTL_7493(ic_a8, ic_b7c.Q, ic_a8.QA, ic_a9.OUT, ic_a9.OUT) - TTL_7400A_NAND(ic_b7d, ic_c9a.Q, ic_a7a.Q) + TTL_7400_NAND(ic_b7d, ic_c9a.Q, ic_a7a.Q) TTL_7420_NAND(ic_a7a, ic_a8.QA, ic_a8.QB, ic_a8.QC, ic_a8.QD) ALIAS(vpad2Q, ic_b7d.Q) @@ -544,8 +524,8 @@ NETLIST_START(pong_fast) TTL_7427_NOR(ic_e5c, ic_e4b.Q, 8H, 4H) ALIAS(scoreFE, ic_e5c.Q) - TTL_7400A_NAND(ic_c3d, 8H, 4H) - //TTL_7400A_NAND(ic_c3d, 4H, 8H) + TTL_7400_NAND(ic_c3d, 8H, 4H) + //TTL_7400_NAND(ic_c3d, 4H, 8H) TTL_7402_NOR(ic_d2b, ic_e4b.Q, ic_c3d.Q) ALIAS(scoreBC, ic_d2b.Q) @@ -571,7 +551,7 @@ NETLIST_START(pong_fast) // net TTL_74107(ic_f3b, clk, 256H, 256HQ, high) - TTL_7400A_NAND(ic_g3b, ic_f3b.QQ, 256H) + TTL_7400_NAND(ic_g3b, ic_f3b.QQ, 256H) TTL_7427_NOR(ic_g2b, ic_g3b.Q, vblank, 4V) ALIAS(net, ic_g2b.Q) |