summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib
diff options
context:
space:
mode:
author couriersud <couriersud@users.noreply.github.com>2022-06-20 20:01:03 +0200
committer GitHub <noreply@github.com>2022-06-20 20:01:03 +0200
commit0dad442511fc3e96bae721c38fe8040a222cc21a (patch)
treeb0eb0732f9e7f438a41a889621d36193d16d6e1b /src/lib
parent3fbfe0b1d76573ee8971eaaee6b37b4024575624 (diff)
netlist: fix bug, prepare for future changes and improve readability (#9947)
* netlist: fix bug, prepare for future changes and improve readability - fix a bug where a net processing error may trigger a nullptr access - applied some clang-tidy recommendations - add no_return to plib::terminate - properly encapsulate dynamic_cast usage - more review of noexcept - added a clang-format file. Over time, all source files will be processed with clang-format - Used clang format on a number of files - Rewrote 74174 - all device constructors now use a struct to pass data on to base classes. Neither netlist state nor the name are intended to be used in a constructor. After the base class was constructed, they can be accessed by state() and name(). - The device construction macros can now be removed. Changes to the core will not need to be reflected in constructors. - Change truth table macros so that going forward NETLIST_END and TRUTH_TABLE_END can be replaced by a closing curly brace. netlists can than use curly braces enclosed blocks. - more clang-format - removed some macros completely - all derived classes from base_device_t now don't use macros any longer. - as a result, delegator_t was removed. This class was only used to support macros :-(
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/netlist/analog/nld_bjt.cpp75
-rw-r--r--src/lib/netlist/analog/nld_mosfet.cpp66
-rw-r--r--src/lib/netlist/analog/nld_opamps.cpp22
-rw-r--r--src/lib/netlist/analog/nld_switches.cpp52
-rw-r--r--src/lib/netlist/analog/nlid_fourterm.cpp204
-rw-r--r--src/lib/netlist/analog/nlid_fourterm.h81
-rw-r--r--src/lib/netlist/analog/nlid_twoterm.cpp134
-rw-r--r--src/lib/netlist/analog/nlid_twoterm.h376
-rw-r--r--src/lib/netlist/build/.clang-format102
-rw-r--r--src/lib/netlist/build/makefile19
-rw-r--r--src/lib/netlist/core/analog.h99
-rw-r--r--src/lib/netlist/core/base_objects.h157
-rw-r--r--src/lib/netlist/core/core_device.h119
-rw-r--r--src/lib/netlist/core/device.h83
-rw-r--r--src/lib/netlist/core/device_macros.h106
-rw-r--r--src/lib/netlist/core/devices.h71
-rw-r--r--src/lib/netlist/core/exec.h57
-rw-r--r--src/lib/netlist/core/logic.h66
-rw-r--r--src/lib/netlist/core/logic_family.h107
-rw-r--r--src/lib/netlist/core/netlist_state.h135
-rw-r--r--src/lib/netlist/core/nets.h169
-rw-r--r--src/lib/netlist/core/param.h127
-rw-r--r--src/lib/netlist/core/queue.h50
-rw-r--r--src/lib/netlist/core/setup.h16
-rw-r--r--src/lib/netlist/core/state_var.h81
-rw-r--r--src/lib/netlist/devices/nld_4020.cpp62
-rw-r--r--src/lib/netlist/devices/nld_4053.cpp38
-rw-r--r--src/lib/netlist/devices/nld_4066.cpp6
-rw-r--r--src/lib/netlist/devices/nld_4316.cpp18
-rw-r--r--src/lib/netlist/devices/nld_74113.cpp6
-rw-r--r--src/lib/netlist/devices/nld_74123.cpp12
-rw-r--r--src/lib/netlist/devices/nld_74174.cpp101
-rw-r--r--src/lib/netlist/devices/nld_7473.cpp5
-rw-r--r--src/lib/netlist/devices/nld_74ls629.cpp8
-rw-r--r--src/lib/netlist/devices/nld_8277.cpp12
-rw-r--r--src/lib/netlist/devices/nld_am2847.cpp8
-rw-r--r--src/lib/netlist/devices/nld_log.cpp8
-rw-r--r--src/lib/netlist/devices/nld_mm5837.cpp8
-rw-r--r--src/lib/netlist/devices/nld_ne555.cpp38
-rw-r--r--src/lib/netlist/devices/nld_r2r_dac.cpp33
-rw-r--r--src/lib/netlist/devices/nld_roms.cpp10
-rw-r--r--src/lib/netlist/devices/nld_schmitt.cpp24
-rw-r--r--src/lib/netlist/devices/nlid_proxy.cpp71
-rw-r--r--src/lib/netlist/devices/nlid_proxy.h21
-rw-r--r--src/lib/netlist/devices/nlid_system.h48
-rw-r--r--src/lib/netlist/devices/nlid_truthtable.cpp20
-rw-r--r--src/lib/netlist/macro/nlm_ttl74xx_lib.cpp23
-rw-r--r--src/lib/netlist/nl_base.cpp637
-rw-r--r--src/lib/netlist/nl_config.h224
-rw-r--r--src/lib/netlist/nl_errstr.h1
-rw-r--r--src/lib/netlist/nl_factory.cpp43
-rw-r--r--src/lib/netlist/nl_factory.h165
-rw-r--r--src/lib/netlist/nl_interface.h382
-rw-r--r--src/lib/netlist/nl_parser.cpp89
-rw-r--r--src/lib/netlist/nl_parser.h15
-rw-r--r--src/lib/netlist/nl_setup.cpp914
-rw-r--r--src/lib/netlist/nl_setup.h31
-rw-r--r--src/lib/netlist/nltypes.h161
-rw-r--r--src/lib/netlist/plib/pexception.cpp2
-rw-r--r--src/lib/netlist/plib/pexception.h2
-rw-r--r--src/lib/netlist/plib/pfmtlog.cpp8
-rw-r--r--src/lib/netlist/plib/pfmtlog.h2
-rw-r--r--src/lib/netlist/plib/pgsl.h53
-rw-r--r--src/lib/netlist/plib/pmatrix_cr.h2
-rw-r--r--src/lib/netlist/plib/poptions.h2
-rw-r--r--src/lib/netlist/plib/ppmf.cpp2
-rw-r--r--src/lib/netlist/plib/ppmf.h2
-rw-r--r--src/lib/netlist/plib/psource.h10
-rw-r--r--src/lib/netlist/plib/ptests.h17
-rw-r--r--src/lib/netlist/plib/ptokenizer.cpp40
-rw-r--r--src/lib/netlist/plib/putil.h87
-rw-r--r--src/lib/netlist/solver/nld_matrix_solver.cpp16
-rw-r--r--src/lib/netlist/solver/nld_matrix_solver.h4
-rw-r--r--src/lib/netlist/solver/nld_matrix_solver_ext.h2
-rw-r--r--src/lib/netlist/solver/nld_ms_gcr.h2
-rw-r--r--src/lib/netlist/solver/nld_solver.cpp317
-rw-r--r--src/lib/netlist/solver/nld_solver.h60
-rw-r--r--src/lib/netlist/tests/test_penum.cpp59
-rw-r--r--src/lib/netlist/tests/test_precommit.cpp4
79 files changed, 3633 insertions, 2876 deletions
diff --git a/src/lib/netlist/analog/nld_bjt.cpp b/src/lib/netlist/analog/nld_bjt.cpp
index 18832d0e4d7..eadb725c5c1 100644
--- a/src/lib/netlist/analog/nld_bjt.cpp
+++ b/src/lib/netlist/analog/nld_bjt.cpp
@@ -130,32 +130,6 @@ namespace analog
};
- // Have a common start for transistors
-
- NETLIB_BASE_OBJECT(QBJT)
- {
- public:
-
- NETLIB_CONSTRUCTOR_EX(QBJT, const pstring &model = "NPN")
- , m_model(*this, "MODEL", model)
- , m_qtype(bjt_type::BJT_NPN)
- {
- }
-
- NETLIB_IS_DYNAMIC(true)
-
- //NETLIB_RESETI();
-
- bjt_type qtype() const noexcept { return m_qtype; }
- bool is_qtype(bjt_type atype) const noexcept { return m_qtype == atype; }
- void set_qtype(bjt_type atype) noexcept { m_qtype = atype; }
- protected:
-
- param_model_t m_model;
- private:
- bjt_type m_qtype;
- };
-
// -----------------------------------------------------------------------------
// nld_QBJT_switch
// -----------------------------------------------------------------------------
@@ -174,9 +148,12 @@ namespace analog
// E
//
- NETLIB_OBJECT_DERIVED(QBJT_switch, QBJT)
+ class nld_QBJT_switch : public base_device_t
{
- NETLIB_CONSTRUCTOR(QBJT_switch)
+ public: \
+ nld_QBJT_switch(constructor_param_t data)
+ : base_device_t(data)
+ , m_model(*this, "MODEL", "NPN")
, m_bjt_model(m_model)
, m_RB(*this, "m_RB", NETLIB_DELEGATE(terminal_handler))
, m_RC(*this, "m_RC", NETLIB_DELEGATE(terminal_handler))
@@ -205,14 +182,17 @@ namespace analog
m_RC.solver()->solve_now();
}
+ NETLIB_IS_DYNAMIC(true)
+
NETLIB_UPDATE_PARAMI();
NETLIB_UPDATE_TERMINALSI();
private:
+ param_model_t m_model;
bjt_model_t m_bjt_model;
- nld_two_terminal m_RB;
- nld_two_terminal m_RC;
- nld_two_terminal m_BC;
+ NETLIB_NAME(two_terminal) m_RB;
+ NETLIB_NAME(two_terminal) m_RC;
+ NETLIB_NAME(two_terminal) m_BC;
nl_fptype m_gB; // base conductance / switch on
nl_fptype m_gC; // collector conductance / switch on
@@ -226,10 +206,12 @@ namespace analog
// -----------------------------------------------------------------------------
- NETLIB_OBJECT_DERIVED(QBJT_EB, QBJT)
+ class nld_QBJT_EB : public base_device_t
{
- public:
- NETLIB_CONSTRUCTOR(QBJT_EB)
+ public: \
+ nld_QBJT_EB(constructor_param_t data)
+ : base_device_t(data)
+ , m_model(*this, "MODEL", "NPN")
, m_bjt_model(m_model)
, m_gD_BC(*this, "m_D_BC")
, m_gD_BE(*this, "m_D_BE")
@@ -275,17 +257,20 @@ namespace analog
m_D_CB.solver()->solve_now();
}
+ NETLIB_IS_DYNAMIC(true)
+
NETLIB_UPDATE_PARAMI();
NETLIB_UPDATE_TERMINALSI();
private:
+ param_model_t m_model;
bjt_model_t m_bjt_model;
generic_diode<diode_e::BIPOLAR> m_gD_BC;
generic_diode<diode_e::BIPOLAR> m_gD_BE;
- nld_two_terminal m_D_CB; // gcc, gce - gcc, gec - gcc, gcc - gce | Ic
- nld_two_terminal m_D_EB; // gee, gec - gee, gce - gee, gee - gec | Ie
- nld_two_terminal m_D_EC; // 0, -gec, -gcc, 0 | 0
+ NETLIB_NAME(two_terminal) m_D_CB; // gcc, gce - gcc, gec - gcc, gcc - gce | Ic
+ NETLIB_NAME(two_terminal) m_D_EB; // gee, gec - gee, gce - gee, gee - gec | Ie
+ NETLIB_NAME(two_terminal) m_D_EC; // 0, -gec, -gcc, 0 | 0
nl_fptype m_alpha_f;
nl_fptype m_alpha_r;
@@ -304,8 +289,8 @@ namespace analog
{
if (m_RB.solver() == nullptr && m_RC.solver() == nullptr)
throw nl_exception(MF_DEVICE_FRY_1(this->name()));
- NETLIB_NAME(QBJT)::reset();
- const auto zero(nlconst::zero());
+
+ static constexpr const auto zero(nlconst::zero());
m_state_on = 0;
@@ -323,9 +308,6 @@ namespace analog
nl_fptype NF = m_bjt_model.m_NF;
//nl_fptype VJE = m_bjt_model.dValue("VJE", 0.75);
- // FIXME: check for PNP as well and bail out
- set_qtype(m_bjt_model.m_type);
-
nl_fptype alpha = BF / (nlconst::one() + BF);
diode d(IS, NF);
@@ -349,7 +331,7 @@ namespace analog
NETLIB_UPDATE_TERMINALS(QBJT_switch)
{
- const nl_fptype m = (is_qtype( bjt_type::BJT_NPN) ? 1 : -1);
+ const nl_fptype m = (m_bjt_model.m_type == bjt_type::BJT_NPN) ? nlconst::one() : -nlconst::one();
const unsigned new_state = (m_RB.deltaV() * m > m_V ) ? 1 : 0;
if (m_state_on ^ new_state)
@@ -374,7 +356,7 @@ namespace analog
{
if (m_D_EB.solver() == nullptr && m_D_CB.solver() == nullptr)
throw nl_exception(MF_DEVICE_FRY_1(this->name()));
- NETLIB_NAME(QBJT)::reset();
+
if (m_CJE)
{
m_CJE->reset();
@@ -389,7 +371,7 @@ namespace analog
NETLIB_UPDATE_TERMINALS(QBJT_EB)
{
- const nl_fptype polarity(qtype() == bjt_type::BJT_NPN ? nlconst::one() : -nlconst::one());
+ const nl_fptype polarity(m_bjt_model.m_type == bjt_type::BJT_NPN ? nlconst::one() : -nlconst::one());
m_gD_BE.update_diode(-m_D_EB.deltaV() * polarity);
m_gD_BC.update_diode(-m_D_CB.deltaV() * polarity);
@@ -422,9 +404,6 @@ namespace analog
nl_fptype NR = m_bjt_model.m_NR;
//nl_fptype VJE = m_m_bjt_model.dValue("VJE", 0.75);
- // FIXME: check for PNP as well and bail out
- set_qtype(m_bjt_model.m_type);
-
m_alpha_f = BF / (nlconst::one() + BF);
m_alpha_r = BR / (nlconst::one() + BR);
diff --git a/src/lib/netlist/analog/nld_mosfet.cpp b/src/lib/netlist/analog/nld_mosfet.cpp
index 46dead610ca..805c2dd1e4b 100644
--- a/src/lib/netlist/analog/nld_mosfet.cpp
+++ b/src/lib/netlist/analog/nld_mosfet.cpp
@@ -149,44 +149,17 @@ namespace analog
param_model_t::value_base_t<int> m_CAPMOD; //!< Capacitance model (0=no model 2=Meyer)
};
- // Have a common start for mosfets
-
- NETLIB_BASE_OBJECT(FET)
- {
- public:
- enum q_type {
- FET_NMOS,
- FET_PMOS
- };
-
- NETLIB_CONSTRUCTOR(FET)
- , m_model(*this, "MODEL", "NMOS")
- , m_qtype(FET_NMOS)
- {
- }
-
- NETLIB_IS_DYNAMIC(true)
-
- //NETLIB_RESETI();
-
- q_type qtype() const noexcept { return m_qtype; }
- bool is_qtype(q_type atype) const noexcept { return m_qtype == atype; }
- void set_qtype(q_type atype) noexcept { m_qtype = atype; }
- protected:
-
- param_model_t m_model;
- private:
- q_type m_qtype;
- };
-
// -----------------------------------------------------------------------------
- // nld_QBJT_EB
+ // nld_MOSFET
// -----------------------------------------------------------------------------
- NETLIB_OBJECT_DERIVED(MOSFET, FET)
+ class nld_MOSFET : public base_device_t
{
public:
- NETLIB_CONSTRUCTOR(MOSFET)
+ public: \
+ nld_MOSFET(constructor_param_t data)
+ : base_device_t(data)
+ , m_model(*this, "MODEL", "NMOS")
, m_DG(*this, "m_DG", NETLIB_DELEGATE(terminal_handler))
, m_SG(*this, "m_SG", NETLIB_DELEGATE(terminal_handler))
, m_SD(*this, "m_SD", NETLIB_DELEGATE(terminal_handler))
@@ -204,7 +177,7 @@ namespace analog
, m_lambda(nlconst::zero())
, m_Leff(nlconst::zero())
, m_CoxWL(nlconst::zero())
- , m_polarity(qtype() == FET_NMOS ? nlconst::one() : -nlconst::one())
+ //S, m_polarity(qtype() == FET_NMOS ? nlconst::one() : -nlconst::one())
, m_Cgb(nlconst::zero())
, m_Cgs(nlconst::zero())
, m_Cgd(nlconst::zero())
@@ -222,8 +195,7 @@ namespace analog
connect(m_SG.N(), m_DG.N());
connect(m_DG.P(), m_SD.N());
- set_qtype((m_model.type() == "NMOS_DEFAULT") ? FET_NMOS : FET_PMOS);
- m_polarity = (qtype() == FET_NMOS ? nlconst::one() : -nlconst::one());
+ m_polarity = (m_model.type() == "NMOS_DEFAULT" ? nlconst::one() : -nlconst::one());
m_capacitor_model = m_model_acc.m_CAPMOD;
//# printf("capmod %d %g %g\n", m_capacitor_model, (nl_fptype)m_model_acc.m_VTO, m_polarity);
@@ -296,6 +268,7 @@ namespace analog
//#printf("Cox: %g\n", m_Cox);
}
+ NETLIB_IS_DYNAMIC(true)
NETLIB_IS_TIMESTEP(true || m_capacitor_model != 0)
NETLIB_TIMESTEPI()
@@ -328,7 +301,6 @@ namespace analog
NETLIB_RESETI()
{
- NETLIB_NAME(FET)::reset();
// Bulk diodes
m_D_BD.set_param(m_model_acc.m_ISD, m_model_acc.m_N, exec().gmin(), constants::T0());
@@ -351,9 +323,11 @@ namespace analog
private:
- nld_two_terminal m_DG;
- nld_two_terminal m_SG;
- nld_two_terminal m_SD;
+ param_model_t m_model;
+
+ NETLIB_NAME(two_terminal) m_DG;
+ NETLIB_NAME(two_terminal) m_SG;
+ NETLIB_NAME(two_terminal) m_SD;
generic_diode<diode_e::MOS> m_D_BD;
#if (!BODY_CONNECTED_TO_SOURCE)
@@ -594,14 +568,14 @@ namespace analog
const nl_fptype gSSBB = gSS + gBB + gBS + gSB;
const auto zero(nlconst::zero());
// S G
- m_SG.set_mat( gSSBB, gSG + gBG, +(IS + IB), // S
- gGS + gGB, gGG, IG ); // G
+ m_SG.set_mat( gSSBB, gSG + gBG, +(IS + IB), // S
+ gGS + gGB, gGG, IG ); // G
// D G
- m_DG.set_mat( gDD, gDG, +ID, // D
- gGD, zero, zero ); // G
+ m_DG.set_mat( gDD, gDG, +ID, // D
+ gGD, zero, zero ); // G
// S D
- m_SD.set_mat( zero, gSD + gBD, zero, // S
- gDS + gDB, zero, zero); // D
+ m_SD.set_mat( zero, gSD + gBD, zero, // S
+ gDS + gDB, zero, zero ); // D
}
NETLIB_UPDATE_PARAM(MOSFET)
diff --git a/src/lib/netlist/analog/nld_opamps.cpp b/src/lib/netlist/analog/nld_opamps.cpp
index f68088a6619..b7e4ebfa762 100644
--- a/src/lib/netlist/analog/nld_opamps.cpp
+++ b/src/lib/netlist/analog/nld_opamps.cpp
@@ -101,9 +101,11 @@ namespace netlist
};
- NETLIB_BASE_OBJECT(opamp)
+ class nld_opamp : public base_device_t
{
- NETLIB_CONSTRUCTOR(opamp)
+ public:
+ nld_opamp(constructor_param_t data)
+ : base_device_t(data)
, m_RP(*this, "RP1")
, m_G1(*this, "G1")
, m_VCC(*this, "VCC", NETLIB_DELEGATE(supply))
@@ -113,8 +115,8 @@ namespace netlist
, m_VH(*this, "VH")
, m_VL(*this, "VL")
, m_VREF(*this, "VREF")
+ , m_type(plib::narrow_cast<int>(m_modacc.m_TYPE))
{
- m_type = plib::narrow_cast<int>(m_modacc.m_TYPE);
if (m_type < 1 || m_type > 3)
{
log().fatal(MF_OPAMP_UNKNOWN_TYPE(m_type));
@@ -201,8 +203,8 @@ namespace netlist
private:
- analog::NETLIB_SUB(R_base) m_RP;
- analog::NETLIB_SUB(VCCS) m_G1;
+ NETLIB_SUB_NS(analog, R_base) m_RP;
+ NETLIB_SUB_NS(analog, VCCS) m_G1;
NETLIB_SUB_UPTR(analog, C) m_CP;
#if TEST_ALT_OUTPUT
NETLIB_SUB_UPTR(analog, R_base) m_RO;
@@ -226,14 +228,14 @@ namespace netlist
NETLIB_UPDATE_PARAM(opamp)
{
- m_G1.m_RI.set(m_modacc.m_RI);
+ m_G1().m_RI.set(m_modacc.m_RI);
if (m_type == 1)
{
nl_fptype RO = m_modacc.m_RO;
nl_fptype G = m_modacc.m_UGF / m_modacc.m_FPF / RO;
- m_RP.set_R(RO);
- m_G1.m_G.set(G);
+ m_RP().set_R(RO);
+ m_G1().m_G.set(G);
}
if (m_type == 3 || m_type == 2)
{
@@ -246,8 +248,8 @@ namespace netlist
log().warning(MW_OPAMP_FAIL_CONVERGENCE(this->name()));
m_CP->set_cap_embedded(CP);
- m_RP.set_R(RP);
- m_G1.m_G.set(G);
+ m_RP().set_R(RP);
+ m_G1().m_G.set(G);
}
if (m_type == 2)
diff --git a/src/lib/netlist/analog/nld_switches.cpp b/src/lib/netlist/analog/nld_switches.cpp
index 169d6465969..6b87279e398 100644
--- a/src/lib/netlist/analog/nld_switches.cpp
+++ b/src/lib/netlist/analog/nld_switches.cpp
@@ -19,65 +19,69 @@ namespace netlist
// SWITCH
// ----------------------------------------------------------------------------------------
- NETLIB_BASE_OBJECT(switch1)
+ class nld_switch1 : public base_device_t
{
- NETLIB_CONSTRUCTOR(switch1)
+ public:
+ nld_switch1(constructor_param_t data)
+ : base_device_t(data)
, m_R(*this, "R")
, m_POS(*this, "POS", false)
{
- register_sub_alias("1", m_R.P());
- register_sub_alias("2", m_R.N());
+ register_sub_alias("1", m_R().P());
+ register_sub_alias("2", m_R().N());
}
NETLIB_RESETI()
{
- m_R.set_R(R_OFF);
+ m_R().set_R(R_OFF);
}
NETLIB_UPDATE_PARAMI()
{
- m_R.change_state([this]()
+ m_R().change_state([this]()
{
- m_R.set_R(m_POS() ? R_ON : R_OFF);
+ m_R().set_R(m_POS() ? R_ON : R_OFF);
});
}
private:
- analog::NETLIB_SUB(R_base) m_R;
- param_logic_t m_POS;
+ NETLIB_SUB_NS(analog, R_base) m_R;
+ param_logic_t m_POS;
};
// ----------------------------------------------------------------------------------------
// SWITCH2
// ----------------------------------------------------------------------------------------
- NETLIB_BASE_OBJECT(switch2)
+ class nld_switch2 : public base_device_t
{
- NETLIB_CONSTRUCTOR(switch2)
+ public:
+ nld_switch2(constructor_param_t data)
+ : base_device_t(data)
, m_R1(*this, "R1")
, m_R2(*this, "R2")
, m_POS(*this, "POS", false)
{
- connect(m_R1.N(), m_R2.N());
+ connect(m_R1().N(), m_R2().N());
- register_sub_alias("1", m_R1.P());
- register_sub_alias("2", m_R2.P());
+ register_sub_alias("1", m_R1().P());
+ register_sub_alias("2", m_R2().P());
- register_sub_alias("Q", m_R1.N());
+ register_sub_alias("Q", m_R1().N());
}
NETLIB_RESETI();
NETLIB_UPDATE_PARAMI();
private:
- analog::NETLIB_SUB(R_base) m_R1;
- analog::NETLIB_SUB(R_base) m_R2;
- param_logic_t m_POS;
+ NETLIB_SUB_NS(analog, R_base) m_R1;
+ NETLIB_SUB_NS(analog, R_base) m_R2;
+ param_logic_t m_POS;
};
NETLIB_RESET(switch2)
{
- m_R1.set_R(R_ON);
- m_R2.set_R(R_OFF);
+ m_R1().set_R(R_ON);
+ m_R2().set_R(R_OFF);
}
#ifdef FIXMELATER
@@ -103,12 +107,12 @@ namespace netlist
nl_fptype r1 = m_POS() ? R_OFF : R_ON;
nl_fptype r2 = m_POS() ? R_ON : R_OFF;
- if (m_R1.solver() == m_R2.solver())
- m_R1.change_state([this, &r1, &r2]() { m_R1.set_R(r1); m_R2.set_R(r2); });
+ if (m_R1().solver() == m_R2().solver())
+ m_R1().change_state([this, &r1, &r2]() { m_R1().set_R(r1); m_R2().set_R(r2); });
else
{
- m_R1.change_state([this, &r1]() { m_R1.set_R(r1); });
- m_R2.change_state([this, &r2]() { m_R2.set_R(r2); });
+ m_R1().change_state([this, &r1]() { m_R1().set_R(r1); });
+ m_R2().change_state([this, &r2]() { m_R2().set_R(r2); });
}
}
diff --git a/src/lib/netlist/analog/nlid_fourterm.cpp b/src/lib/netlist/analog/nlid_fourterm.cpp
index 9e1f185e79c..e12a931c142 100644
--- a/src/lib/netlist/analog/nlid_fourterm.cpp
+++ b/src/lib/netlist/analog/nlid_fourterm.cpp
@@ -1,139 +1,129 @@
// license:BSD-3-Clause
// copyright-holders:Couriersud
-#include "solver/nld_solver.h"
-#include "nl_factory.h"
#include "nlid_fourterm.h"
-namespace netlist
-{
- namespace analog
- {
-
+#include "nl_factory.h"
-// ----------------------------------------------------------------------------------------
-// nld_VCCS
-// ----------------------------------------------------------------------------------------
+#include "solver/nld_solver.h"
-NETLIB_RESET(VCCS)
+namespace netlist::analog
{
- const nl_fptype m_mult = m_G() * m_gfac; // 1.0 ==> 1V ==> 1A
- const nl_fptype GI = plib::reciprocal(m_RI());
- m_IP.set_conductivity(GI);
- m_IN.set_conductivity(GI);
+ // -------------------------------------------------------------------------
+ // nld_VCCS
+ // -------------------------------------------------------------------------
- m_OP.set_go_gt(-m_mult, nlconst::zero());
- m_OP1.set_go_gt(m_mult, nlconst::zero());
+ NETLIB_RESET(VCCS)
+ {
+ const nl_fptype m_mult = m_G() * m_gfac; // 1.0 ==> 1V ==> 1A
+ const nl_fptype GI = plib::reciprocal(m_RI());
- m_ON.set_go_gt(m_mult, nlconst::zero());
- m_ON1.set_go_gt(-m_mult, nlconst::zero());
-}
+ m_IP.set_conductivity(GI);
+ m_IN.set_conductivity(GI);
-NETLIB_HANDLER(VCCS, terminal_handler)
-{
- solver::matrix_solver_t *solv = nullptr;
- // only called if connected to a rail net ==> notify the solver to recalculate
- // NOLINTNEXTLINE(bugprone-branch-clone)
- if ((solv = m_IP.solver()) != nullptr)
- solv->solve_now();
- else if ((solv = m_IN.solver()) != nullptr)
- solv->solve_now();
- else if ((solv = m_OP.solver()) != nullptr)
- solv->solve_now();
- else if ((solv = m_ON.solver()) != nullptr)
- solv->solve_now();
-}
-
-// ----------------------------------------------------------------------------------------
-// nld_LVCCS
-// ----------------------------------------------------------------------------------------
-
-NETLIB_RESET(LVCCS)
-{
- NETLIB_NAME(VCCS)::reset();
-}
+ m_OP.set_go_gt(-m_mult, nlconst::zero());
+ m_OP1.set_go_gt(m_mult, nlconst::zero());
-NETLIB_UPDATE_PARAM(LVCCS)
-{
- NETLIB_NAME(VCCS)::update_param();
-}
+ m_ON.set_go_gt(m_mult, nlconst::zero());
+ m_ON1.set_go_gt(-m_mult, nlconst::zero());
+ }
-NETLIB_UPDATE_TERMINALS(LVCCS)
-{
- const nl_fptype m_mult = m_G() * get_gfac(); // 1.0 ==> 1V ==> 1A
- const nl_fptype vi = m_IP.net().Q_Analog() - m_IN.net().Q_Analog();
- const auto c1(nlconst::magic(0.2));
+ NETLIB_HANDLER(VCCS, terminal_handler)
+ {
+ solver::matrix_solver_t *solv = nullptr;
+ // only called if connected to a rail net ==> notify the solver to
+ // recalculate
+ // NOLINTNEXTLINE(bugprone-branch-clone)
+ if ((solv = m_IP.solver()) != nullptr)
+ solv->solve_now();
+ else if ((solv = m_IN.solver()) != nullptr)
+ solv->solve_now();
+ else if ((solv = m_OP.solver()) != nullptr)
+ solv->solve_now();
+ else if ((solv = m_ON.solver()) != nullptr)
+ solv->solve_now();
+ }
+
+ // -------------------------------------------------------------------------
+ // nld_LVCCS
+ // -------------------------------------------------------------------------
+
+ NETLIB_RESET(LVCCS) { NETLIB_NAME(VCCS)::reset(); }
+
+ NETLIB_UPDATE_PARAM(LVCCS) { NETLIB_NAME(VCCS)::update_param(); }
+
+ NETLIB_UPDATE_TERMINALS(LVCCS)
+ {
+ const nl_fptype m_mult = m_G() * get_gfac(); // 1.0 ==> 1V ==> 1A
+ const nl_fptype vi = m_IP.net().Q_Analog() - m_IN.net().Q_Analog();
+ const auto c1(nlconst::magic(0.2));
- if (plib::abs(m_mult / m_cur_limit() * vi) > nlconst::half())
- m_vi = m_vi + c1 * plib::tanh((vi - m_vi) / c1);
- else
- m_vi = vi;
+ if (plib::abs(m_mult / m_cur_limit() * vi) > nlconst::half())
+ m_vi = m_vi + c1 * plib::tanh((vi - m_vi) / c1);
+ else
+ m_vi = vi;
- const nl_fptype x = m_mult / m_cur_limit() * m_vi;
- const nl_fptype tanhx = plib::tanh(x);
+ const nl_fptype x = m_mult / m_cur_limit() * m_vi;
+ const nl_fptype tanhx = plib::tanh(x);
- const nl_fptype beta = m_mult * (nlconst::one() - tanhx*tanhx);
- const nl_fptype I = m_cur_limit() * tanhx - beta * m_vi;
+ const nl_fptype beta = m_mult * (nlconst::one() - tanhx * tanhx);
+ const nl_fptype I = m_cur_limit() * tanhx - beta * m_vi;
- m_OP.set_go_gt_I(-beta, nlconst::zero(), I);
- m_OP1.set_go_gt(beta, nlconst::zero());
+ m_OP.set_go_gt_I(-beta, nlconst::zero(), I);
+ m_OP1.set_go_gt(beta, nlconst::zero());
- m_ON.set_go_gt_I(beta, nlconst::zero(), -I);
- m_ON1.set_go_gt(-beta, nlconst::zero());
-}
+ m_ON.set_go_gt_I(beta, nlconst::zero(), -I);
+ m_ON1.set_go_gt(-beta, nlconst::zero());
+ }
-// ----------------------------------------------------------------------------------------
-// nld_CCCS
-// ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
+ // nld_CCCS
+ // -------------------------------------------------------------------------
-NETLIB_RESET(CCCS)
-{
- NETLIB_NAME(VCCS)::reset();
-}
+ NETLIB_RESET(CCCS) { NETLIB_NAME(VCCS)::reset(); }
-NETLIB_UPDATE_PARAM(CCCS)
-{
- NETLIB_NAME(VCCS)::update_param();
-}
+ NETLIB_UPDATE_PARAM(CCCS) { NETLIB_NAME(VCCS)::update_param(); }
-// ----------------------------------------------------------------------------------------
-// nld_VCVS
-// ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
+ // nld_VCVS
+ // -------------------------------------------------------------------------
-NETLIB_RESET(VCVS)
-{
- const auto gfac(plib::reciprocal(m_RO()));
- set_gfac(gfac);
+ NETLIB_RESET(VCVS)
+ {
+ const auto gfac(plib::reciprocal(m_RO()));
+ set_gfac(gfac);
- NETLIB_NAME(VCCS)::reset();
+ NETLIB_NAME(VCCS)::reset();
- m_OP2.set_conductivity(gfac);
- m_ON2.set_conductivity(gfac);
-}
+ m_OP2.set_conductivity(gfac);
+ m_ON2.set_conductivity(gfac);
+ }
-// ----------------------------------------------------------------------------------------
-// nld_CCVS
-// ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
+ // nld_CCVS
+ // -------------------------------------------------------------------------
-NETLIB_RESET(CCVS)
-{
- const auto gfac(plib::reciprocal(m_RO()));
- set_gfac(gfac);
+ NETLIB_RESET(CCVS)
+ {
+ const auto gfac(plib::reciprocal(m_RO()));
+ set_gfac(gfac);
- NETLIB_NAME(VCCS)::reset();
+ NETLIB_NAME(VCCS)::reset();
- m_OP2.set_conductivity(gfac);
- m_ON2.set_conductivity(gfac);
-}
+ m_OP2.set_conductivity(gfac);
+ m_ON2.set_conductivity(gfac);
+ }
- } //namespace analog
+} // namespace netlist::analog
- namespace devices {
- NETLIB_DEVICE_IMPL_NS(analog, VCVS, "VCVS", "G")
- NETLIB_DEVICE_IMPL_NS(analog, VCCS, "VCCS", "G")
- NETLIB_DEVICE_IMPL_NS(analog, CCCS, "CCCS", "G")
- NETLIB_DEVICE_IMPL_NS(analog, CCVS, "CCVS", "G")
- NETLIB_DEVICE_IMPL_NS(analog, LVCCS, "LVCCS", "")
- } // namespace devices
-} // namespace netlist
+namespace netlist::devices
+{
+ // clang-format off
+ NETLIB_DEVICE_IMPL_NS(analog, VCVS, "VCVS", "G")
+ NETLIB_DEVICE_IMPL_NS(analog, VCCS, "VCCS", "G")
+ NETLIB_DEVICE_IMPL_NS(analog, CCCS, "CCCS", "G")
+ NETLIB_DEVICE_IMPL_NS(analog, CCVS, "CCVS", "G")
+ NETLIB_DEVICE_IMPL_NS(analog, LVCCS, "LVCCS", "")
+ // clang-format on
+} // namespace netlist::devices
diff --git a/src/lib/netlist/analog/nlid_fourterm.h b/src/lib/netlist/analog/nlid_fourterm.h
index 9f71964c6d1..1320f97984b 100644
--- a/src/lib/netlist/analog/nlid_fourterm.h
+++ b/src/lib/netlist/analog/nlid_fourterm.h
@@ -9,9 +9,11 @@
///
#include "nl_base.h"
+
#include "plib/putil.h"
-namespace netlist::analog {
+namespace netlist::analog
+{
// ----------------------------------------------------------------------------------------
// nld_VCCS
@@ -32,26 +34,27 @@ namespace netlist::analog {
//
// RI = 1 / NETLIST_GMIN
//
- NETLIB_BASE_OBJECT(VCCS)
+ class nld_VCCS : public base_device_t
{
public:
- NETLIB_CONSTRUCTOR_EX(VCCS, nl_fptype ri = nlconst::magic(1e9))
+ nld_VCCS(constructor_param_t data, nl_fptype ri = nlconst::magic(1e9))
+ : base_device_t(data)
, m_G(*this, "G", nlconst::one())
, m_RI(*this, "RI", ri)
- , m_OP(*this, "OP", &m_IP, {&m_ON, &m_IN}, NETLIB_DELEGATE(terminal_handler))
- , m_ON(*this, "ON", &m_IP, {&m_OP, &m_IN}, NETLIB_DELEGATE(terminal_handler))
- , m_IP(*this, "IP", &m_IN, {&m_OP, &m_ON}, NETLIB_DELEGATE(terminal_handler))
- , m_IN(*this, "IN", &m_IP, {&m_OP, &m_ON}, NETLIB_DELEGATE(terminal_handler))
+ , m_OP(*this, "OP", &m_IP, {&m_ON, &m_IN},
+ NETLIB_DELEGATE(terminal_handler))
+ , m_ON(*this, "ON", &m_IP, {&m_OP, &m_IN},
+ NETLIB_DELEGATE(terminal_handler))
+ , m_IP(*this, "IP", &m_IN, {&m_OP, &m_ON},
+ NETLIB_DELEGATE(terminal_handler))
+ , m_IN(*this, "IN", &m_IP, {&m_OP, &m_ON},
+ NETLIB_DELEGATE(terminal_handler))
, m_OP1(*this, "_OP1", &m_IN, NETLIB_DELEGATE(terminal_handler))
, m_ON1(*this, "_ON1", &m_IN, NETLIB_DELEGATE(terminal_handler))
- //, m_IPx(*this, "_IPx", &m_OP, NETLIB_DELEGATE(terminal_handler)) // <= this should be NULL and terminal be filtered out prior to solving...
- //, m_INx(*this, "_INx", &m_ON, NETLIB_DELEGATE(terminal_handler)) // <= this should be NULL and terminal be filtered out prior to solving...
, m_gfac(nlconst::one())
{
connect(m_OP, m_OP1);
connect(m_ON, m_ON1);
- //connect(m_IP, m_IPx);
- //connect(m_IN, m_INx);
}
NETLIB_RESETI();
@@ -61,20 +64,11 @@ namespace netlist::analog {
protected:
NETLIB_HANDLERI(terminal_handler);
- NETLIB_UPDATE_PARAMI()
- {
- NETLIB_NAME(VCCS)::reset();
- }
+ NETLIB_UPDATE_PARAMI() { NETLIB_NAME(VCCS)::reset(); }
- void set_gfac(nl_fptype g) noexcept
- {
- m_gfac = g;
- }
+ void set_gfac(nl_fptype g) noexcept { m_gfac = g; }
- nl_fptype get_gfac() const noexcept
- {
- return m_gfac;
- }
+ nl_fptype get_gfac() const noexcept { return m_gfac; }
terminal_t m_OP;
terminal_t m_ON;
@@ -85,19 +79,17 @@ namespace netlist::analog {
terminal_t m_OP1;
terminal_t m_ON1;
- //terminal_t m_IPx;
- //terminal_t m_INx;
-
private:
nl_fptype m_gfac;
};
// Limited Current source
- NETLIB_OBJECT_DERIVED(LVCCS, VCCS)
+ class nld_LVCCS : public nld_VCCS
{
public:
- NETLIB_CONSTRUCTOR(LVCCS)
+ nld_LVCCS(constructor_param_t data)
+ : nld_VCCS(data)
, m_cur_limit(*this, "CURLIM", nlconst::magic(1000.0))
, m_vi(nlconst::zero())
{
@@ -106,14 +98,13 @@ namespace netlist::analog {
NETLIB_IS_DYNAMIC(true)
protected:
- //NETLIB_UPDATEI();
NETLIB_RESETI();
NETLIB_UPDATE_PARAMI();
NETLIB_UPDATE_TERMINALSI();
private:
param_fp_t m_cur_limit; // current limit
- nl_fptype m_vi;
+ nl_fptype m_vi;
};
// ----------------------------------------------------------------------------------------
@@ -140,10 +131,11 @@ namespace netlist::analog {
// This needs high levels of accuracy to work with 1 Ohm RI.
//
- NETLIB_OBJECT_DERIVED(CCCS, VCCS)
+ class nld_CCCS : public nld_VCCS
{
public:
- NETLIB_CONSTRUCTOR_PASS(CCCS, nlconst::one())
+ nld_CCCS(constructor_param_t data)
+ : nld_VCCS(data, nlconst::one())
{
set_gfac(-plib::reciprocal(m_RI()));
}
@@ -151,11 +143,9 @@ namespace netlist::analog {
NETLIB_RESETI();
protected:
- //NETLIB_UPDATEI();
NETLIB_UPDATE_PARAMI();
};
-
// ----------------------------------------------------------------------------------------
// nld_VCVS
// ----------------------------------------------------------------------------------------
@@ -182,10 +172,11 @@ namespace netlist::analog {
// Internal GI = G / RO
//
- NETLIB_OBJECT_DERIVED(VCVS, VCCS)
+ class nld_VCVS : public nld_VCCS
{
public:
- NETLIB_CONSTRUCTOR(VCVS)
+ nld_VCVS(constructor_param_t data)
+ : nld_VCCS(data)
, m_RO(*this, "RO", nlconst::one())
, m_OP2(*this, "_OP2", &m_ON2, NETLIB_DELEGATE(terminal_handler))
, m_ON2(*this, "_ON2", &m_OP2, NETLIB_DELEGATE(terminal_handler))
@@ -199,16 +190,14 @@ namespace netlist::analog {
param_fp_t m_RO;
private:
- //NETLIB_UPDATE_PARAMI();
+ // NETLIB_UPDATE_PARAMI();
NETLIB_HANDLERI(terminal_handler)
{
- NETLIB_NAME(VCCS) :: terminal_handler();
+ NETLIB_NAME(VCCS)::terminal_handler();
}
terminal_t m_OP2;
terminal_t m_ON2;
-
-
};
// ----------------------------------------------------------------------------------------
@@ -225,7 +214,7 @@ namespace netlist::analog {
// IP ---+ +--+---- OP
// | | |
// RI I RO
- // RI => G => I RO V(OP) - V(ON) = (V(IP)-V(IN)) / RI * G
+ // RI => G => I RO V(OP) - V(ON) = (V(IP)-V(IN)) / RI * G
// RI I RO
// | | |
// IN ---+ +--+---- ON
@@ -237,10 +226,11 @@ namespace netlist::analog {
// Internal GI = G / RO
//
- NETLIB_OBJECT_DERIVED(CCVS, VCCS)
+ class nld_CCVS : public nld_VCCS
{
public:
- NETLIB_CONSTRUCTOR_PASS(CCVS, nlconst::one())
+ nld_CCVS(constructor_param_t data)
+ : nld_VCCS(data, nlconst::one())
, m_RO(*this, "RO", nlconst::one())
, m_OP2(*this, "_OP2", &m_ON2, NETLIB_DELEGATE(terminal_handler))
, m_ON2(*this, "_ON2", &m_OP2, NETLIB_DELEGATE(terminal_handler))
@@ -254,18 +244,17 @@ namespace netlist::analog {
param_fp_t m_RO;
private:
- //NETLIB_UPDATE_PARAMI();
+ // NETLIB_UPDATE_PARAMI();
NETLIB_HANDLERI(terminal_handler)
{
- NETLIB_NAME(VCCS) :: terminal_handler();
+ NETLIB_NAME(VCCS)::terminal_handler();
}
terminal_t m_OP2;
terminal_t m_ON2;
};
-
} // namespace netlist::analog
#endif // NLD_FOURTERM_H_
diff --git a/src/lib/netlist/analog/nlid_twoterm.cpp b/src/lib/netlist/analog/nlid_twoterm.cpp
index 4bb7ab64059..3d5d0721dfb 100644
--- a/src/lib/netlist/analog/nlid_twoterm.cpp
+++ b/src/lib/netlist/analog/nlid_twoterm.cpp
@@ -1,21 +1,20 @@
// license:BSD-3-Clause
// copyright-holders:Couriersud
-#include "solver/nld_solver.h"
+#include "nlid_twoterm.h"
#include "nl_factory.h"
-#include "nlid_twoterm.h"
-namespace netlist
-{
-namespace analog
+#include "solver/nld_solver.h"
+
+namespace netlist::analog
{
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// nld_twoterm
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
- solver::matrix_solver_t * NETLIB_NAME(two_terminal)::solver() const noexcept
+ solver::matrix_solver_t *nld_two_terminal::solver() const noexcept
{
auto *solv(m_P.solver());
if (solv != nullptr)
@@ -23,8 +22,7 @@ namespace analog
return m_N.solver();
}
-
- void NETLIB_NAME(two_terminal)::solve_now() const
+ void nld_two_terminal::solve_now() const
{
auto *solv(solver());
if (solv != nullptr)
@@ -33,92 +31,97 @@ namespace analog
NETLIB_HANDLER(two_terminal, terminal_handler)
{
- // only called if connected to a rail net ==> notify the solver to recalculate
- //printf("%s update\n", this->name().c_str());
+ // only called if connected to a rail net ==> notify the solver to
+ // recalculate
+ // printf("%s update\n", this->name().c_str());
solve_now();
}
- // ----------------------------------------------------------------------------------------
+
+ // -------------------------------------------------------------------------
// nld_POT
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
NETLIB_RESET(POT)
{
nl_fptype v = m_Dial();
if (m_DialIsLog())
- v = (plib::exp(v) - nlconst::one()) / (plib::exp(nlconst::one()) - nlconst::one());
+ v = (plib::exp(v) - nlconst::one())
+ / (plib::exp(nlconst::one()) - nlconst::one());
- m_R1.set_R(std::max(m_R() * v, exec().gmin()));
- m_R2.set_R(std::max(m_R() * (nlconst::one() - v), exec().gmin()));
+ m_R1().set_R(std::max(m_R() * v, exec().gmin()));
+ m_R2().set_R(std::max(m_R() * (nlconst::one() - v), exec().gmin()));
}
NETLIB_UPDATE_PARAM(POT)
{
nl_fptype v = m_Dial();
if (m_DialIsLog())
- v = (plib::exp(v) - nlconst::one()) / (plib::exp(nlconst::one()) - nlconst::one());
+ v = (plib::exp(v) - nlconst::one())
+ / (plib::exp(nlconst::one()) - nlconst::one());
if (m_Reverse())
v = nlconst::one() - v;
nl_fptype r1(std::max(m_R() * v, exec().gmin()));
nl_fptype r2(std::max(m_R() * (nlconst::one() - v), exec().gmin()));
- if (m_R1.solver() == m_R2.solver())
- m_R1.change_state([this, &r1, &r2]() { m_R1.set_R(r1); m_R2.set_R(r2); });
+ if (m_R1().solver() == m_R2().solver())
+ m_R1().change_state(
+ [this, &r1, &r2]()
+ {
+ m_R1().set_R(r1);
+ m_R2().set_R(r2);
+ });
else
{
- m_R1.change_state([this, &r1]() { m_R1.set_R(r1); });
- m_R2.change_state([this, &r2]() { m_R2.set_R(r2); });
+ m_R1().change_state([this, &r1]() { m_R1().set_R(r1); });
+ m_R2().change_state([this, &r2]() { m_R2().set_R(r2); });
}
-
}
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// nld_POT2
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
NETLIB_RESET(POT2)
{
nl_fptype v = m_Dial();
if (m_DialIsLog())
- v = (plib::exp(v) - nlconst::one()) / (plib::exp(nlconst::one()) - nlconst::one());
+ v = (plib::exp(v) - nlconst::one())
+ / (plib::exp(nlconst::one()) - nlconst::one());
if (m_Reverse())
v = nlconst::one() - v;
- m_R1.set_R(std::max(m_R() * v, exec().gmin()));
+ m_R1().set_R(std::max(m_R() * v, exec().gmin()));
}
-
NETLIB_UPDATE_PARAM(POT2)
{
nl_fptype v = m_Dial();
if (m_DialIsLog())
- v = (plib::exp(v) - nlconst::one()) / (plib::exp(nlconst::one()) - nlconst::one());
+ v = (plib::exp(v) - nlconst::one())
+ / (plib::exp(nlconst::one()) - nlconst::one());
if (m_Reverse())
v = nlconst::one() - v;
- m_R1.change_state([this, &v]()
- {
- m_R1.set_R(std::max(m_R() * v, exec().gmin()));
- });
+ m_R1().change_state(
+ [this, &v]() { m_R1().set_R(std::max(m_R() * v, exec().gmin())); });
}
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// nld_L
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
NETLIB_RESET(L)
{
m_gmin = exec().gmin();
m_I = nlconst::zero();
m_G = m_gmin;
- set_mat( m_G, -m_G, -m_I,
- -m_G, m_G, m_I);
+ set_mat(m_G, -m_G, -m_I, //
+ -m_G, m_G, m_I);
}
- NETLIB_UPDATE_PARAM(L)
- {
- }
+ NETLIB_UPDATE_PARAM(L) {}
NETLIB_TIMESTEP(L)
{
@@ -129,8 +132,8 @@ namespace analog
// Gpar should support convergence
m_I += m_G * deltaV();
m_G = step / m_L() + m_gmin;
- set_mat( m_G, -m_G, -m_I,
- -m_G, m_G, m_I);
+ set_mat(m_G, -m_G, -m_I, //
+ -m_G, m_G, m_I);
}
else
{
@@ -139,9 +142,9 @@ namespace analog
}
}
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// nld_D
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
NETLIB_RESET(D)
{
@@ -165,29 +168,37 @@ namespace analog
m_D.update_diode(deltaV());
const nl_fptype G(m_D.G());
const nl_fptype I(m_D.Ieq());
- set_mat( G, -G, -I,
- -G, G, I);
- //set(m_D.G(), 0.0, m_D.Ieq());
+ set_mat(G, -G, -I, //
+ -G, G, I);
+ // set(m_D.G(), 0.0, m_D.Ieq());
}
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// nld_Z
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
NETLIB_RESET(Z)
{
- nl_fptype IsBV = m_modacc.m_IBV / (plib::exp(m_modacc.m_BV / nlconst::np_VT(m_modacc.m_NBV)) - nlconst::one());
+ nl_fptype IsBV = m_modacc.m_IBV
+ / (plib::exp(m_modacc.m_BV
+ / nlconst::np_VT(m_modacc.m_NBV))
+ - nlconst::one());
- m_D.set_param(m_modacc.m_IS, m_modacc.m_N, exec().gmin(), nlconst::T0());
+ m_D.set_param(m_modacc.m_IS, m_modacc.m_N, exec().gmin(),
+ nlconst::T0());
m_R.set_param(IsBV, m_modacc.m_NBV, exec().gmin(), nlconst::T0());
set_G_V_I(m_D.G(), nlconst::zero(), m_D.Ieq());
}
NETLIB_UPDATE_PARAM(Z)
{
- nl_fptype IsBV = m_modacc.m_IBV / (plib::exp(m_modacc.m_BV / nlconst::np_VT(m_modacc.m_NBV)) - nlconst::one());
+ nl_fptype IsBV = m_modacc.m_IBV
+ / (plib::exp(m_modacc.m_BV
+ / nlconst::np_VT(m_modacc.m_NBV))
+ - nlconst::one());
- m_D.set_param(m_modacc.m_IS, m_modacc.m_N, exec().gmin(), nlconst::T0());
+ m_D.set_param(m_modacc.m_IS, m_modacc.m_N, exec().gmin(),
+ nlconst::T0());
m_R.set_param(IsBV, m_modacc.m_NBV, exec().gmin(), nlconst::T0());
set_G_V_I(m_D.G(), nlconst::zero(), m_D.Ieq());
}
@@ -198,15 +209,15 @@ namespace analog
m_R.update_diode(-deltaV());
const nl_fptype G(m_D.G() + m_R.G());
const nl_fptype I(m_D.Ieq() - m_R.Ieq());
- set_mat( G, -G, -I,
- -G, G, I);
+ set_mat(G, -G, -I, //
+ -G, G, I);
}
+} // namespace netlist::analog
-
-} //namespace analog
-
-namespace devices {
+namespace netlist::devices
+{
+ // clang-format off
NETLIB_DEVICE_IMPL_NS(analog, R, "RES", "R")
NETLIB_DEVICE_IMPL_NS(analog, POT, "POT", "R")
NETLIB_DEVICE_IMPL_NS(analog, POT2, "POT2", "R")
@@ -216,6 +227,5 @@ namespace devices {
NETLIB_DEVICE_IMPL_NS(analog, Z, "ZDIODE", "MODEL")
NETLIB_DEVICE_IMPL_NS(analog, VS, "VS", "V")
NETLIB_DEVICE_IMPL_NS(analog, CS, "CS", "I")
-} // namespace devices
-
-} // namespace netlist
+ // clang-format on
+} // namespace netlist::devices
diff --git a/src/lib/netlist/analog/nlid_twoterm.h b/src/lib/netlist/analog/nlid_twoterm.h
index 52fc8aa08e8..c2d9eee3333 100644
--- a/src/lib/netlist/analog/nlid_twoterm.h
+++ b/src/lib/netlist/analog/nlid_twoterm.h
@@ -37,9 +37,11 @@
#include "../nl_setup.h"
#include "nl_base.h"
#include "nld_generic_models.h"
-#include "plib/pfunction.h"
+
#include "solver/nld_solver.h"
+#include "plib/pfunction.h"
+
// -----------------------------------------------------------------------------
// Implementation
// -----------------------------------------------------------------------------
@@ -47,45 +49,37 @@
namespace netlist::analog
{
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// nld_two_terminal
- // -----------------------------------------------------------------------------
-
- template <class C>
- static inline core_device_t &bselect(bool b, C &d1, core_device_t &d2)
- {
- auto *h = dynamic_cast<core_device_t *>(&d1);
- return b ? *h : d2;
- }
- template <>
- inline core_device_t &bselect(bool b, [[maybe_unused]] netlist_state_t &d1, core_device_t &d2)
- {
- if (b)
- throw nl_exception("bselect with netlist and b==true");
- return d2;
- }
+ // -------------------------------------------------------------------------
- NETLIB_BASE_OBJECT(two_terminal)
+ class nld_two_terminal : public base_device_t
{
- NETLIB_CONSTRUCTOR(two_terminal)
+ public:
+ nld_two_terminal(constructor_param_t data)
+ : base_device_t(data)
, m_P(*this, "1", &m_N, NETLIB_DELEGATE(terminal_handler))
, m_N(*this, "2", &m_P, NETLIB_DELEGATE(terminal_handler))
{
}
- //#NETLIB_CONSTRUCTOR_EX(twoterm, nldelegate owner_delegate)
- template <class C>
- NETLIB_NAME(two_terminal)(C &owner, const pstring &name, nl_delegate owner_delegate) \
- : base_type(owner, name)
+
+ // This constructor covers the case in which the terminals are "owned"
+ // by the device using a two_terminal. In this case it passes
+ // the terminal handler on to the terminals.
+
+ nld_two_terminal(base_device_t &owner, const pstring &name,
+ nl_delegate owner_delegate)
+ : base_device_t(
+ constructor_data_t{owner.state(), owner.name() + "." + name})
, m_P(owner, name + ".1", &m_N, owner_delegate)
, m_N(owner, name + ".2", &m_P, owner_delegate)
{
}
- //NETLIB_UPDATE_TERMINALSI() { }
- //NETLIB_RESETI() {}
+ // NETLIB_UPDATE_TERMINALSI() { }
+ // NETLIB_RESETI() {}
public:
-
NETLIB_HANDLERI(terminal_handler);
solver::matrix_solver_t *solver() const noexcept;
@@ -112,18 +106,13 @@ namespace netlist::analog
return m_P.net().Q_Analog() - m_N.net().Q_Analog();
}
- nl_fptype V1P() const noexcept
- {
- return m_P.net().Q_Analog();
- }
+ nl_fptype V1P() const noexcept { return m_P.net().Q_Analog(); }
- nl_fptype V2N() const noexcept
- {
- return m_N.net().Q_Analog();
- }
+ nl_fptype V2N() const noexcept { return m_N.net().Q_Analog(); }
- void set_mat(nl_fptype a11, nl_fptype a12, nl_fptype rhs1,
- nl_fptype a21, nl_fptype a22, nl_fptype rhs2) const noexcept
+ void set_mat(nl_fptype a11, nl_fptype a12, nl_fptype rhs1, //
+ nl_fptype a21, nl_fptype a22, nl_fptype rhs2 //
+ ) const noexcept
{
// GO, GT, I
m_P.set_go_gt_I(a12, a11, rhs1);
@@ -173,78 +162,75 @@ namespace netlist::analog
private:
terminal_t m_P;
terminal_t m_N;
-
};
-
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// nld_R
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
- NETLIB_OBJECT_DERIVED(R_base, two_terminal)
+ class nld_R_base : public nld_two_terminal
{
- NETLIB_CONSTRUCTOR(R_base)
+ public:
+ nld_R_base(constructor_param_t data)
+ : nld_two_terminal(data)
{
}
void set_R(nl_fptype R) const noexcept
{
const nl_fptype G = plib::reciprocal(R);
- set_mat( G, -G, nlconst::zero(),
- -G, G, nlconst::zero());
+ set_mat(G, -G, nlconst::zero(), //
+ -G, G, nlconst::zero());
}
void set_G(nl_fptype G) const noexcept
{
- set_mat( G, -G, nlconst::zero(),
- -G, G, nlconst::zero());
+ set_mat(G, -G, nlconst::zero(), //
+ -G, G, nlconst::zero());
}
- //NETLIB_RESETI();
+ // NETLIB_RESETI();
protected:
- //NETLIB_UPDATEI();
-
+ // NETLIB_UPDATEI();
};
- NETLIB_OBJECT_DERIVED(R, R_base)
+ class nld_R : public nld_R_base
{
- NETLIB_CONSTRUCTOR(R)
+ public:
+ nld_R(constructor_param_t data)
+ : nld_R_base(data)
, m_R(*this, "R", nlconst::magic(1e9))
{
}
-
protected:
-
- NETLIB_RESETI()
- {
- set_R(std::max(m_R(), exec().gmin()));
- }
+ NETLIB_RESETI() { set_R(std::max(m_R(), exec().gmin())); }
NETLIB_UPDATE_PARAMI()
{
- // FIXME: We only need to update the net first if this is a time stepping net
- change_state([this]()
- {
- set_R(std::max(m_R(), exec().gmin()));
- });
+ // FIXME: We only need to update the net first if this is a time
+ // stepping net
+ change_state([this]() { set_R(std::max(m_R(), exec().gmin())); });
}
private:
param_fp_t m_R;
- // protect set_R ... it's a recipe to disaster when used to bypass the parameter
- using NETLIB_NAME(R_base)::set_R;
- using NETLIB_NAME(R_base)::set_G;
+ // protect set_R ... it's a recipe to disaster when used to bypass the
+ // parameter
+ using nld_R_base::set_G;
+ using nld_R_base::set_R;
};
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// nld_POT
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
- NETLIB_BASE_OBJECT(POT)
+ class nld_POT : public base_device_t
{
- NETLIB_CONSTRUCTOR(POT)
+ public:
+ nld_POT(constructor_param_t data)
+ : base_device_t(data)
, m_R1(*this, "_R1")
, m_R2(*this, "_R2")
, m_R(*this, "R", 10000)
@@ -252,63 +238,65 @@ namespace netlist::analog
, m_DialIsLog(*this, "DIALLOG", false)
, m_Reverse(*this, "REVERSE", false)
{
- register_sub_alias("1", m_R1.P());
- register_sub_alias("2", m_R1.N());
- register_sub_alias("3", m_R2.N());
-
- connect(m_R2.P(), m_R1.N());
+ register_sub_alias("1", m_R1().P());
+ register_sub_alias("2", m_R1().N());
+ register_sub_alias("3", m_R2().N());
+ connect(m_R2().P(), m_R1().N());
}
- //NETLIB_UPDATEI();
+ // NETLIB_UPDATEI();
NETLIB_RESETI();
NETLIB_UPDATE_PARAMI();
private:
- NETLIB_SUB(R_base) m_R1;
- NETLIB_SUB(R_base) m_R2;
+ NETLIB_SUB_NS(analog, R_base) m_R1;
+ NETLIB_SUB_NS(analog, R_base) m_R2;
- param_fp_t m_R;
- param_fp_t m_Dial;
+ param_fp_t m_R;
+ param_fp_t m_Dial;
param_logic_t m_DialIsLog;
param_logic_t m_Reverse;
};
- NETLIB_BASE_OBJECT(POT2)
+ class nld_POT2 : public base_device_t
{
- NETLIB_CONSTRUCTOR(POT2)
+ public:
+ nld_POT2(constructor_param_t data)
+ : base_device_t(data)
, m_R1(*this, "_R1")
, m_R(*this, "R", nlconst::magic(10000.0))
, m_Dial(*this, "DIAL", nlconst::half())
, m_DialIsLog(*this, "DIALLOG", false)
, m_Reverse(*this, "REVERSE", false)
{
- register_sub_alias("1", m_R1.P());
- register_sub_alias("2", m_R1.N());
-
+ register_sub_alias("1", m_R1().P());
+ register_sub_alias("2", m_R1().N());
}
- //NETLIB_UPDATEI();
+ // NETLIB_UPDATEI();
NETLIB_RESETI();
NETLIB_UPDATE_PARAMI();
private:
- NETLIB_SUB(R_base) m_R1;
+ NETLIB_SUB_NS(analog, R_base) m_R1;
- param_fp_t m_R;
- param_fp_t m_Dial;
+ param_fp_t m_R;
+ param_fp_t m_Dial;
param_logic_t m_DialIsLog;
param_logic_t m_Reverse;
};
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// nld_C
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
+
#if 1
- NETLIB_OBJECT_DERIVED(C, two_terminal)
+ class nld_C : public nld_two_terminal
{
public:
- NETLIB_CONSTRUCTOR(C)
+ nld_C(constructor_param_t data)
+ : nld_two_terminal(data)
, m_C(*this, "C", nlconst::magic(1e-6))
, m_cap(*this, "m_cap")
{
@@ -320,20 +308,17 @@ namespace netlist::analog
if (ts_type == time_step_type::FORWARD)
{
// G, Ieq
- const auto res(m_cap.time_step(m_C(), deltaV(), step));
+ const auto res(m_cap.time_step(m_C(), deltaV(), step));
const nl_fptype G = res.first;
const nl_fptype I = res.second;
- set_mat( G, -G, -I,
- -G, G, I);
+ set_mat(G, -G, -I, //
+ -G, G, I);
}
else
m_cap.restore_state();
}
- NETLIB_RESETI()
- {
- m_cap.set_parameters(exec().gmin());
- }
+ NETLIB_RESETI() { m_cap.set_parameters(exec().gmin()); }
/// \brief Set capacitance
///
@@ -343,27 +328,25 @@ namespace netlist::analog
///
/// \param val Capacitance value
///
- void set_cap_embedded(nl_fptype val)
- {
- m_C.set(val);
- }
+ void set_cap_embedded(nl_fptype val) { m_C.set(val); }
protected:
- //NETLIB_UPDATEI();
- //FIXME: should be able to change
- NETLIB_UPDATE_PARAMI() { }
+ // NETLIB_UPDATEI();
+ // FIXME: should be able to change
+ NETLIB_UPDATE_PARAMI() {}
private:
- param_fp_t m_C;
+ param_fp_t m_C;
generic_capacitor_const m_cap;
};
#else
// Code preserved as a basis for a current/voltage controlled capacitor
- NETLIB_OBJECT_DERIVED(C, two_terminal)
+ class nld_C : public nld_two_terminal)
{
public:
- NETLIB_CONSTRUCTOR_DERIVED(C, two_terminal)
+ nld_C(constructor_param_t data)
+ : nld_two_terminal(data)
, m_C(*this, "C", nlconst::magic(1e-6))
, m_cap(*this, "m_cap")
{
@@ -377,8 +360,8 @@ namespace netlist::analog
{
const nl_fptype I = m_cap.Ieq(m_C(), deltaV());
const nl_fptype G = m_cap.G(m_C());
- set_mat( G, -G, -I,
- -G, G, I);
+ set_mat(G, -G, -I, //
+ -G, G, I);
}
}
@@ -387,34 +370,33 @@ namespace netlist::analog
{
const nl_fptype I = m_cap.Ieq(m_C(), deltaV());
const nl_fptype G = m_cap.G(m_C());
- set_mat( G, -G, -I,
- -G, G, I);
+ set_mat(G, -G, -I, //
+ -G, G, I);
}
param_fp_t m_C;
- NETLIB_RESETI()
- {
- m_cap.set_parameters(exec().gmin());
- }
+ NETLIB_RESETI() { m_cap.set_parameters(exec().gmin()); }
protected:
- //NETLIB_UPDATEI();
- //FIXME: should be able to change
- NETLIB_UPDATE_PARAMI() { }
+ // NETLIB_UPDATEI();
+ // FIXME: should be able to change
+ NETLIB_UPDATE_PARAMI() {}
private:
- //generic_capacitor<capacitor_e::VARIABLE_CAPACITY> m_cap;
+ // generic_capacitor<capacitor_e::VARIABLE_CAPACITY> m_cap;
generic_capacitor<capacitor_e::CONSTANT_CAPACITY> m_cap;
};
#endif
- // -----------------------------------------------------------------------------
+
+ // -------------------------------------------------------------------------
// nld_L
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
- NETLIB_OBJECT_DERIVED(L, two_terminal)
+ class nld_L : public nld_two_terminal
{
public:
- NETLIB_CONSTRUCTOR(L)
+ nld_L(constructor_param_t data)
+ : nld_two_terminal(data)
, m_L(*this, "L", nlconst::magic(1e-6))
, m_gmin(nlconst::zero())
, m_G(*this, "m_G", nlconst::zero())
@@ -422,8 +404,8 @@ namespace netlist::analog
, m_last_I(*this, "m_last_I", nlconst::zero())
, m_last_G(*this, "m_last_G", nlconst::zero())
{
- //register_term("1", m_P);
- //register_term("2", m_N);
+ // register_term("1", m_P);
+ // register_term("2", m_N);
}
NETLIB_IS_TIMESTEP(true)
@@ -431,13 +413,13 @@ namespace netlist::analog
NETLIB_RESETI();
protected:
- //NETLIB_UPDATEI();
+ // NETLIB_UPDATEI();
NETLIB_UPDATE_PARAMI();
private:
param_fp_t m_L;
- nl_fptype m_gmin;
+ nl_fptype m_gmin;
state_var<nl_fptype> m_G;
state_var<nl_fptype> m_I;
state_var<nl_fptype> m_last_I;
@@ -446,9 +428,9 @@ namespace netlist::analog
/// \brief Class representing the diode model parameters.
///
- /// This is the model representation of the diode model. Typically, SPICE uses
- /// the following parameters. A "Y" in the first column indicates that the
- /// parameter is actually used in netlist.
+ /// This is the model representation of the diode model. Typically, SPICE
+ /// uses the following parameters. A "Y" in the first column indicates that
+ /// the parameter is actually used in netlist.
///
/// NBV, BV and IBV are only used in the ZDIODE model. It is assumed
/// that DIODEs are not modeled up to their breakdown voltage.
@@ -478,10 +460,11 @@ namespace netlist::analog
diode_model_t(param_model_t &model)
: m_IS(model, "IS")
, m_N(model, "N")
- {}
+ {
+ }
- param_model_t::value_t m_IS; //!< saturation current.
- param_model_t::value_t m_N; //!< emission coefficient.
+ param_model_t::value_t m_IS; //!< saturation current.
+ param_model_t::value_t m_N; //!< emission coefficient.
};
class zdiode_model_t : public diode_model_t
@@ -492,21 +475,23 @@ namespace netlist::analog
, m_NBV(model, "NBV")
, m_BV(model, "BV")
, m_IBV(model, "IBV")
- {}
+ {
+ }
- param_model_t::value_t m_NBV; //!< reverse emission coefficient.
- param_model_t::value_t m_BV; //!< reverse breakdown voltage.
- param_model_t::value_t m_IBV; //!< current at breakdown voltage.
+ param_model_t::value_t m_NBV; //!< reverse emission coefficient.
+ param_model_t::value_t m_BV; //!< reverse breakdown voltage.
+ param_model_t::value_t m_IBV; //!< current at breakdown voltage.
};
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// nld_D
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
- NETLIB_OBJECT_DERIVED(D, two_terminal)
+ class nld_D : public nld_two_terminal
{
public:
- NETLIB_CONSTRUCTOR_EX(D, const pstring &model = "D")
+ nld_D(constructor_param_t data, const pstring &model = "D")
+ : nld_two_terminal(data)
, m_model(*this, "MODEL", model)
, m_modacc(m_model)
, m_D(*this, "m_D")
@@ -520,23 +505,24 @@ namespace netlist::analog
NETLIB_RESETI();
protected:
- //NETLIB_UPDATEI();
+ // NETLIB_UPDATEI();
NETLIB_UPDATE_PARAMI();
private:
- param_model_t m_model;
- diode_model_t m_modacc;
+ param_model_t m_model;
+ diode_model_t m_modacc;
generic_diode<diode_e::BIPOLAR> m_D;
};
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// nld_Z - Zener Diode
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
- NETLIB_OBJECT_DERIVED(Z, two_terminal)
+ class nld_Z : public nld_two_terminal
{
public:
- NETLIB_CONSTRUCTOR_EX(Z, const pstring &model = "D")
+ nld_Z(constructor_param_t data, const pstring &model = "D")
+ : nld_two_terminal(data)
, m_model(*this, "MODEL", model)
, m_modacc(m_model)
, m_D(*this, "m_D")
@@ -551,38 +537,40 @@ namespace netlist::analog
NETLIB_RESETI();
protected:
- //NETLIB_UPDATEI();
+ // NETLIB_UPDATEI();
NETLIB_UPDATE_PARAMI();
private:
- param_model_t m_model;
- zdiode_model_t m_modacc;
+ param_model_t m_model;
+ zdiode_model_t m_modacc;
generic_diode<diode_e::BIPOLAR> m_D;
// REVERSE diode
generic_diode<diode_e::BIPOLAR> m_R;
};
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// nld_VS - Voltage source
//
// netlist voltage source must have inner resistance
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
- NETLIB_OBJECT_DERIVED(VS, two_terminal)
+ class nld_VS : public nld_two_terminal
{
public:
- NETLIB_CONSTRUCTOR(VS)
+ nld_VS(constructor_param_t data)
+ : nld_two_terminal(data)
, m_t(*this, "m_t", nlconst::zero())
, m_R(*this, "RI", nlconst::magic(0.1))
, m_V(*this, "V", nlconst::zero())
- , m_func(*this,"FUNC", "")
+ , m_func(*this, "FUNC", "")
, m_compiled(*this, "m_compiled")
, m_funcparam({nlconst::zero()})
{
register_sub_alias("P", P());
register_sub_alias("N", N());
if (!m_func().empty())
- m_compiled->compile(m_func(), std::vector<pstring>({{pstring("T")}}));
+ m_compiled->compile(m_func(),
+ std::vector<pstring>({{pstring("T")}}));
}
NETLIB_IS_TIMESTEP(!m_func().empty())
@@ -594,48 +582,49 @@ namespace netlist::analog
m_t += step;
m_funcparam[0] = m_t;
this->set_G_V_I(plib::reciprocal(m_R()),
- m_compiled->evaluate(m_funcparam),
- nlconst::zero());
+ m_compiled->evaluate(m_funcparam),
+ nlconst::zero());
}
else
m_t -= step; // only need to restore state, will be called again
}
protected:
-
NETLIB_RESETI()
{
- NETLIB_NAME(two_terminal)::reset();
+ nld_two_terminal::reset();
this->set_G_V_I(plib::reciprocal(m_R()), m_V(), nlconst::zero());
}
private:
- state_var<nl_fptype> m_t;
- param_fp_t m_R;
- param_fp_t m_V;
- param_str_t m_func;
+ state_var<nl_fptype> m_t;
+ param_fp_t m_R;
+ param_fp_t m_V;
+ param_str_t m_func;
state_var<plib::pfunction<nl_fptype>> m_compiled;
- std::vector<nl_fptype> m_funcparam;
+ std::vector<nl_fptype> m_funcparam;
};
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// nld_CS - Current source
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
- NETLIB_OBJECT_DERIVED(CS, two_terminal)
+ class nld_CS : public nld_two_terminal
{
public:
- NETLIB_CONSTRUCTOR(CS)
+ nld_CS(constructor_param_t data)
+ : nld_two_terminal(data)
, m_t(*this, "m_t", nlconst::zero())
, m_I(*this, "I", nlconst::one())
- , m_func(*this,"FUNC", "")
+ , m_func(*this, "FUNC", "")
, m_compiled(*this, "m_compiled")
, m_funcparam({nlconst::zero()})
{
register_sub_alias("P", "1");
register_sub_alias("N", "2");
if (!m_func().empty())
- m_compiled->compile(m_func(), std::vector<pstring>({{pstring("T")}}));
+ m_compiled->compile(m_func(),
+ std::vector<pstring>({{pstring("T")}}));
}
NETLIB_IS_TIMESTEP(!m_func().empty())
@@ -646,42 +635,43 @@ namespace netlist::analog
m_t += step;
m_funcparam[0] = m_t;
const nl_fptype I = m_compiled->evaluate(m_funcparam);
- const auto zero(nlconst::zero());
- set_mat(zero, zero, -I,
- zero, zero, I);
+ const auto zero(nlconst::zero());
+ set_mat(zero, zero, -I, //
+ zero, zero, I);
}
else
m_t -= step;
}
protected:
-
NETLIB_RESETI()
{
- NETLIB_NAME(two_terminal)::reset();
+ nld_two_terminal::reset();
const auto zero(nlconst::zero());
- set_mat(zero, zero, -m_I(),
- zero, zero, m_I());
+ set_mat(zero, zero, -m_I(), //
+ zero, zero, m_I());
}
NETLIB_UPDATE_PARAMI()
{
- // FIXME: We only need to update the net first if this is a time stepping net
- //FIXME: works only for CS without function
- change_state([this]()
- {
- const auto zero(nlconst::zero());
- set_mat(zero, zero, -m_I(),
- zero, zero, m_I());
- });
+ // FIXME: We only need to update the net first if this is a time
+ // stepping net
+ // FIXME: works only for CS without function
+ change_state(
+ [this]()
+ {
+ const auto zero(nlconst::zero());
+ set_mat(zero, zero, -m_I(), //
+ zero, zero, m_I());
+ });
}
private:
- state_var<nl_fptype> m_t;
- param_fp_t m_I;
- param_str_t m_func;
+ state_var<nl_fptype> m_t;
+ param_fp_t m_I;
+ param_str_t m_func;
state_var<plib::pfunction<nl_fptype>> m_compiled;
- std::vector<nl_fptype> m_funcparam;
+ std::vector<nl_fptype> m_funcparam;
};
} // namespace netlist::analog
diff --git a/src/lib/netlist/build/.clang-format b/src/lib/netlist/build/.clang-format
new file mode 100644
index 00000000000..46d1fb6dcec
--- /dev/null
+++ b/src/lib/netlist/build/.clang-format
@@ -0,0 +1,102 @@
+Language: Cpp
+Standard: c++17
+UseTab: ForContinuationAndIndentation
+TabWidth: 4
+IndentWidth: 4
+ColumnLimit: 80
+ContinuationIndentWidth: 4
+ConstructorInitializerIndentWidth: 0
+NamespaceIndentation: All
+CompactNamespaces: true
+FixNamespaceComments: true
+
+IndentAccessModifiers: false
+AccessModifierOffset: -4
+IndentCaseLabels: true
+
+BreakBeforeBraces: Allman
+BreakBeforeBinaryOperators: All
+BreakConstructorInitializers: BeforeComma
+# Currentline doesn't work
+# PackConstructorInitializers: CurrentLine >= 14
+BreakStringLiterals: false
+# Multiline does not work in clang-format 13
+# AlwaysBreakTemplateDeclarations: MultiLine
+AlwaysBreakTemplateDeclarations: Yes
+# AfterComma does not work <= 13
+#BreakInheritanceList: AfterComma
+#BreakInheritanceList: BeforeComma
+#BreakInheritanceList: false
+SpaceBeforeInheritanceColon: true
+
+#AlignAfterOpenBracket: DontAlign
+AlignAfterOpenBracket: Align
+PointerAlignment: Right
+SpacesInAngles: false
+SpaceBeforeAssignmentOperators: true
+AlignConsecutiveDeclarations: true
+
+AllowShortIfStatementsOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: true
+AllowAllArgumentsOnNextLine: false
+AllowAllParametersOfDeclarationOnNextLine: false
+
+PenaltyBreakComment: 1
+PenaltyBreakAssignment: 1000
+AlwaysBreakBeforeMultilineStrings: true
+
+PenaltyReturnTypeOnItsOwnLine: 1
+
+# SortIncludes: CaseSensitive # >= 13!
+SortIncludes: true
+IncludeBlocks: Regroup
+
+IncludeCategories:
+ - Regex: '^(("|"../)core)/'
+ Priority: 20
+ - Regex: '^(("|"../)analog)/'
+ Priority: 21
+ - Regex: '^(("|"../)devices)/'
+ Priority: 22
+ - Regex: '^(("|"../)solver)/'
+ Priority: 23
+ - Regex: '^(("|"../)plib)/'
+ Priority: 30
+ - Regex: '<[([:alnum:]|_).]+>'
+ Priority: 40
+ - Regex: '.*'
+ Priority: 10
+
+StatementMacros:
+ - "NETLIB_DEVICE_IMPL_NS"
+ - "TTL_7400_NAND"
+ - "TTL_7402_NOR"
+ - "NET_C"
+ - "TRUTHTABLE_ENTRY"
+ - "LOCAL_LIB_ENTRY"
+ - "TT_HEAD"
+ - "TT_LINE"
+ - "TT_FAMILY"
+ - "DIPPINS"
+
+#StatementAttributeLikeMacros:
+# - "NETLIST_NAME"
+# - "NETLIB_NAME"
+
+TypenameMacros:
+ - "NETLIST_NAME"
+ - "NETLIB_NAME"
+
+IndentPPDirectives: BeforeHash
+MacroBlockBegin: "^static NETLIST_START\\(.*\\)|static TRUTHTABLE_START\\(.*\\)$"
+MacroBlockEnd: "^NETLIST_END\\(\\)|TRUTHTABLE_END\\(\\)$"
+# ReferenceAlignment: Middle
+# Avoid formatting (breaking) doxygen
+CommentPragmas: '^\\.+'
+# Avoid formatting cspell ignored comments
+CommentPragmas: '^#.+'
+# Avoid breaking tables
+CommentPragmas: '^\|.+'
+# Avoid breaking clang-tidy
+CommentPragmas: '^ NOLINT.+'
+
diff --git a/src/lib/netlist/build/makefile b/src/lib/netlist/build/makefile
index 91ae7140acf..ab89d6adcdd 100644
--- a/src/lib/netlist/build/makefile
+++ b/src/lib/netlist/build/makefile
@@ -55,6 +55,7 @@ TIDY_FLAGSX += -modernize-use-auto,
#TIDY_FLAGSX += -modernize-use-transparent-functors,
TIDY_FLAGSX += -readability-function-cognitive-complexity,
TIDY_FLAGSX += -readability-uppercase-literal-suffix
+TIDY_FLAGSX += -cert-err58-cpp
#TIDY_FLAGSX += -cppcoreguidelines-avoid-non-const-global-variables
@@ -113,7 +114,7 @@ TIDY_DB = $(OBJ)/compile_commands.json
#LTO decreases performance :-(
#LTO = -flto=4 -fuse-linker-plugin -Wodr
-CCOREFLAGS = -g -O3 -std=c++17 -I$(SRC) -I$(SRC)/..
+CCOREFLAGS = -g -O3 -std=c++17 -I$(SRC) -I$(SRC)/.. -I$(SRC)/../..
CFLAGS = $(LTO) $(CCOREFLAGS) $(CEXTRAFLAGS)
LDFLAGS = $(LTO) -g -O3 -std=c++17 $(LDEXTRAFLAGS)
@@ -289,22 +290,20 @@ native:
$(MAKE) CEXTRAFLAGS="-march=native -msse4.2 -Wall -Wpedantic -Wsign-compare -Wextra"
gcc9:
- $(MAKE) CC=g++-9 LD=g++-9 CEXTRAFLAGS="-march=native -Wall -pedantic -Wpedantic -fext-numeric-literals -Wsign-compare -Wextra" EXTRALIBS="-lquadmath" OBJ=obj/gcc9
+ $(MAKE) CC=g++-9 LD=g++-9 CEXTRAFLAGS="-march=native -Wall -Wextra -pedantic -Wpedantic -pedantic-errors -fext-numeric-literals -Wsign-compare" EXTRALIBS="-lquadmath" OBJ=obj/gcc9
clang:
#$(MAKE) CC=clang++-11 LD=clang++-11 OBJ=obj/clang CEXTRAFLAGS="-march=native -msse4.2 -Weverything -Wall -pedantic -Wpedantic -Wunused-private-field -Wno-padded -Wno-unused-template -Wno-missing-variable-declarations -Wno-float-equal -Wconversion -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-format-nonliteral -Wno-exit-time-destructors"
$(MAKE) CC=clang++-13 LD=clang++-13 OBJ=obj/clang CEXTRAFLAGS="-march=native \
- -mllvm -inline-threshold=2000 \
+ -mllvm -inline-threshold=2000 \
-Wunknown-warning-option \
- -Weverything -Wall -pedantic -Wpedantic -Wunused-private-field \
+ -Weverything -Wall -pedantic -Wpedantic \
-Werror -Wno-padded -Wno-weak-vtables -Wno-weak-template-vtables -Wunused-template \
- -Wmissing-variable-declarations -Wno-float-equal -Wconversion \
- -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wformat-nonliteral \
- -Wno-exit-time-destructors -Winconsistent-missing-destructor-override \
- -Wno-embedded-directive \
+ -Wno-float-equal \
+ -Wno-c++98-compat -Wno-c++98-compat-pedantic \
+ -Wno-exit-time-destructors \
-Wno-undefined-reinterpret-cast -Wno-error=unused-macros \
- -Wunreachable-code \
- -Wmissing-prototypes -Wno-error=deprecated"
+ -Wno-error=deprecated"
clang-libc:
#clang-11 currently broken
diff --git a/src/lib/netlist/core/analog.h b/src/lib/netlist/core/analog.h
index a003e1c37a5..da9639a3de1 100644
--- a/src/lib/netlist/core/analog.h
+++ b/src/lib/netlist/core/analog.h
@@ -20,23 +20,22 @@
namespace netlist
{
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// analog_t
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
class analog_t : public detail::core_terminal_t
{
public:
-
analog_t(core_device_t &dev, const pstring &aname, state_e state,
nl_delegate delegate);
- const analog_net_t & net() const noexcept
+ const analog_net_t &net() const noexcept
{
return plib::downcast<const analog_net_t &>(core_terminal_t::net());
}
- analog_net_t & net() noexcept
+ analog_net_t &net() noexcept
{
return plib::downcast<analog_net_t &>(core_terminal_t::net());
}
@@ -53,24 +52,23 @@ namespace netlist
class terminal_t : public analog_t
{
public:
-
/// \brief constructor
///
/// \param dev object owning the terminal
/// \param aname name of this terminal
/// \param other_terminal pointer to the sibling terminal
- terminal_t(core_device_t &dev, const pstring &aname, terminal_t *other_terminal, nl_delegate delegate);
+ terminal_t(core_device_t &dev, const pstring &aname,
+ terminal_t *other_terminal, nl_delegate delegate);
- terminal_t(core_device_t &dev, const pstring &aname, terminal_t *other_terminal,
- const std::array<terminal_t *, 2> &splitter_terms, nl_delegate delegate);
+ terminal_t(core_device_t &dev, const pstring &aname,
+ terminal_t * other_terminal,
+ const std::array<terminal_t *, 2> &splitter_terms,
+ nl_delegate delegate);
/// \brief Returns voltage of connected net
///
/// \return voltage of net this terminal is connected to
- nl_fptype operator ()() const noexcept
- {
- return net().Q_Analog();
- }
+ nl_fptype operator()() const noexcept { return net().Q_Analog(); }
/// \brief sets conductivity value of this terminal
///
@@ -85,42 +83,33 @@ namespace netlist
set_go_gt_I(GO, GT, nlconst::zero());
}
- void set_go_gt_I(nl_fptype GO, nl_fptype GT, nl_fptype I) const noexcept
- {
- // Check for rail nets ...
- if (m_go != nullptr)
- {
- *m_Idr = I;
- *m_go = GO;
- *m_gt = GT;
- }
- }
+ void set_go_gt_I(nl_fptype GO, nl_fptype GT,
+ nl_fptype I) const noexcept;
- void set_ptrs(nl_fptype *gt, nl_fptype *go, nl_fptype *Idr) noexcept(false);
+ void set_ptrs(nl_fptype *gt, nl_fptype *go, nl_fptype *Idr) noexcept(
+ false);
private:
nl_fptype *m_Idr; ///< drive current
nl_fptype *m_go; ///< conductance for Voltage from other term
nl_fptype *m_gt; ///< conductance for total conductance
-
};
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// analog_input_t
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
/// \brief terminal providing analog input voltage.
///
- /// This terminal class provides a voltage measurement. The conductance against
- /// ground is infinite.
-
+ /// This terminal class provides a voltage measurement. The conductance
+ /// against ground is infinite.
class analog_input_t : public analog_t
{
public:
/// \brief Constructor
- analog_input_t(core_device_t &dev, ///< owning device
- const pstring &aname, ///< name of terminal
- nl_delegate delegate ///< delegate
+ analog_input_t(core_device_t &dev, ///< owning device
+ const pstring & aname, ///< name of terminal
+ nl_delegate delegate ///< delegate
);
/// \brief returns voltage at terminal.
@@ -129,29 +118,19 @@ namespace netlist
/// \brief returns voltage at terminal.
/// \returns voltage at terminal.
- nl_fptype Q_Analog() const noexcept
- {
- return net().Q_Analog();
- }
+ nl_fptype Q_Analog() const noexcept { return net().Q_Analog(); }
};
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// analog_output_t
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
class analog_output_t : public analog_t
{
public:
analog_output_t(core_device_t &dev, const pstring &aname);
- void push(nl_fptype val) noexcept
- {
- if (val != m_my_net.Q_Analog())
- {
- m_my_net.set_Q_Analog(val);
- m_my_net.toggle_and_push_to_queue(netlist_time::quantum());
- }
- }
+ void push(nl_fptype val) noexcept;
void initial(nl_fptype val) noexcept;
@@ -159,12 +138,36 @@ namespace netlist
analog_net_t m_my_net;
};
+ // -------------------------------------------------------------------------
+ // out of class
+ // -------------------------------------------------------------------------
+
inline solver::matrix_solver_t *analog_t::solver() const noexcept
{
return (this->has_net() ? net().solver() : nullptr);
}
-} // namespace netlist
+ inline void terminal_t::set_go_gt_I(nl_fptype GO, nl_fptype GT,
+ nl_fptype I) const noexcept
+ {
+ // Check for rail nets ...
+ if (m_go != nullptr)
+ {
+ *m_Idr = I;
+ *m_go = GO;
+ *m_gt = GT;
+ }
+ }
+ inline void analog_output_t::push(nl_fptype val) noexcept
+ {
+ if (val != m_my_net.Q_Analog())
+ {
+ m_my_net.set_Q_Analog(val);
+ m_my_net.toggle_and_push_to_queue(netlist_time::quantum());
+ }
+ }
+
+} // namespace netlist
#endif // NL_CORE_ANALOG_H_
diff --git a/src/lib/netlist/core/base_objects.h b/src/lib/netlist/core/base_objects.h
index 782d94cf572..1f924d988dc 100644
--- a/src/lib/netlist/core/base_objects.h
+++ b/src/lib/netlist/core/base_objects.h
@@ -8,11 +8,10 @@
#ifndef NL_CORE_BASE_OBJECTS_H_
#define NL_CORE_BASE_OBJECTS_H_
+#include "../nltypes.h"
#include "netlist_state.h"
#include "state_var.h"
-#include "../nltypes.h"
-
#include "../plib/palloc.h"
#include "../plib/pchrono.h"
#include "../plib/pexception.h"
@@ -21,7 +20,8 @@
#include <unordered_map>
-namespace netlist::detail {
+namespace netlist::detail
+{
template <typename C, typename T>
struct property_store_t
@@ -30,30 +30,44 @@ namespace netlist::detail {
using key_type = const C *;
using store_type = std::unordered_map<key_type, value_type>;
- static void add(key_type obj, const value_type &aname) noexcept
+ static void add(key_type obj, const value_type &value) noexcept
{
- store().insert({obj, aname});
+ try
+ {
+ store().insert({obj, value});
+ }
+ catch (...)
+ {
+ plib::terminate("exception in property_store_t.add()");
+ }
}
- static value_type *get(key_type obj) noexcept
+ static const value_type &get(key_type obj) noexcept
{
try
{
typename store_type::iterator ret(store().find(obj));
if (ret == store().end())
- return nullptr;
- return &ret->second;
+ plib::terminate(
+ "object not found in property_store_t.get()");
+ return ret->second;
}
catch (...)
{
plib::terminate("exception in property_store_t.get()");
- return static_cast<value_type *>(nullptr);
}
}
static void remove(key_type obj) noexcept
{
- store().erase(store().find(obj));
+ try
+ {
+ store().erase(store().find(obj));
+ }
+ catch (...)
+ {
+ plib::terminate("exception in property_store_t.remove()");
+ }
}
static store_type &store() noexcept
@@ -61,12 +75,11 @@ namespace netlist::detail {
static store_type static_store;
return static_store;
}
-
};
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// object_t
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
/// \brief The base class for netlist devices, terminals and parameters.
///
@@ -76,36 +89,25 @@ namespace netlist::detail {
class object_t
{
public:
-
/// \brief Constructor.
/// Every class derived from the object_t class must have a name.
///
/// \param aname string containing name of the object
- explicit object_t(const pstring &aname)
- {
- props::add(this, aname);
- }
+ explicit object_t(const pstring &aname) { props::add(this, aname); }
PCOPYASSIGNMOVE(object_t, delete)
/// \brief return name of the object
///
/// \returns name of the object.
- const pstring &name() const noexcept
- {
- return *props::get(this);
- }
+ const pstring &name() const noexcept { return props::get(this); }
protected:
-
using props = property_store_t<object_t, pstring>;
// only childs should be destructible
- ~object_t() noexcept
- {
- props::remove(this);
- }
+ ~object_t() noexcept { props::remove(this); }
private:
};
@@ -122,33 +124,34 @@ namespace netlist::detail {
explicit netlist_object_t(netlist_t &nl, const pstring &name)
: object_t(name)
, m_netlist(nl)
- { }
+ {
+ }
~netlist_object_t() = default;
PCOPYASSIGNMOVE(netlist_object_t, delete)
- netlist_state_t & state() noexcept;
- const netlist_state_t & state() const noexcept;
+ netlist_state_t & state() noexcept;
+ const netlist_state_t &state() const noexcept;
- constexpr netlist_t & exec() noexcept { return m_netlist; }
- constexpr const netlist_t & exec() const noexcept { return m_netlist; }
+ constexpr netlist_t & exec() noexcept { return m_netlist; }
+ constexpr const netlist_t &exec() const noexcept { return m_netlist; }
// to ease template design
template <typename T, typename... Args>
- device_arena::unique_ptr<T> make_pool_object(Args&&... args)
+ device_arena::unique_ptr<T> make_pool_object(Args &&...args) noexcept(
+ false)
{
return state().make_pool_object<T>(std::forward<Args>(args)...);
}
private:
- netlist_t & m_netlist;
-
+ netlist_t &m_netlist;
};
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// device_object_t
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
/// \brief Base class for all objects being owned by a device.
///
@@ -171,31 +174,32 @@ namespace netlist::detail {
/// \brief returns reference to owning device.
/// \returns reference to owning device.
- core_device_t &device() noexcept { return *m_device; }
+ core_device_t & device() noexcept { return *m_device; }
const core_device_t &device() const noexcept { return *m_device; }
/// \brief The netlist owning the owner of this object.
/// \returns reference to netlist object.
- netlist_state_t &state() noexcept;
+ netlist_state_t & state() noexcept;
const netlist_state_t &state() const noexcept;
private:
- core_device_t * m_device;
+ core_device_t *m_device;
};
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// core_terminal_t
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
/// \brief Base class for all terminals.
///
/// All terminals are derived from this class.
///
- class core_terminal_t : public device_object_t
- , public plib::linked_list_t<core_terminal_t, 0>::element_t
+ class core_terminal_t
+ : public device_object_t
+ , public plib::linked_list_t<core_terminal_t, 0>::element_t
#if NL_USE_INPLACE_CORE_TERMS
- , public plib::linked_list_t<core_terminal_t, 1>::element_t
+ , public plib::linked_list_t<core_terminal_t, 1>::element_t
#endif
{
public:
@@ -213,19 +217,21 @@ namespace netlist::detail {
static constexpr netlist_sig_t OUT_TRISTATE() { return INP_MASK; }
- static_assert(INP_BITS * 2 <= sizeof(netlist_sig_t) * 8, "netlist_sig_t size not sufficient");
+ static_assert(INP_BITS * 2 <= sizeof(netlist_sig_t) * 8,
+ "netlist_sig_t size not sufficient");
- enum state_e {
+ enum state_e
+ {
STATE_INP_PASSIVE = 0,
- STATE_INP_HL = (INP_MASK << INP_HL_SHIFT),
- STATE_INP_LH = (INP_MASK << INP_LH_SHIFT),
- STATE_INP_ACTIVE = STATE_INP_HL | STATE_INP_LH,
- STATE_OUT = (1 << (2*INP_BITS)),
- STATE_BIDIR = (1 << (2*INP_BITS + 1))
+ STATE_INP_HL = (INP_MASK << INP_HL_SHIFT),
+ STATE_INP_LH = (INP_MASK << INP_LH_SHIFT),
+ STATE_INP_ACTIVE = STATE_INP_HL | STATE_INP_LH,
+ STATE_OUT = (1 << (2 * INP_BITS)),
+ STATE_BIDIR = (1 << (2 * INP_BITS + 1))
};
- core_terminal_t(core_device_t &dev, const pstring &aname,
- state_e state, nl_delegate delegate);
+ core_terminal_t(core_device_t &dev, const pstring &aname, state_e state,
+ nl_delegate delegate);
virtual ~core_terminal_t() noexcept = default;
PCOPYASSIGNMOVE(core_terminal_t, delete)
@@ -237,13 +243,16 @@ namespace netlist::detail {
/// \brief Checks if object is of specified type.
/// \param atype type to check object against.
/// \returns true if object is of specified type else false.
- bool is_type(const terminal_type atype) const noexcept(false) { return (type() == atype); }
+ bool is_type(const terminal_type atype) const noexcept(false)
+ {
+ return (type() == atype);
+ }
- void set_net(net_t *anet) noexcept { m_net = anet; }
- void clear_net() noexcept { m_net = nullptr; }
+ void set_net(net_t *anet) noexcept { m_net = anet; }
+ void clear_net() noexcept { m_net = nullptr; }
constexpr bool has_net() const noexcept { return (m_net != nullptr); }
- constexpr net_t & net() const noexcept { return *m_net;}
+ constexpr net_t &net() const noexcept { return *m_net; }
bool is_logic() const noexcept;
bool is_logic_input() const noexcept;
@@ -253,13 +262,21 @@ namespace netlist::detail {
bool is_analog_input() const noexcept;
bool is_analog_output() const noexcept;
- constexpr bool is_state(state_e state) const noexcept { return (m_state == state); }
+ constexpr bool is_state(state_e state) const noexcept
+ {
+ return (m_state == state);
+ }
constexpr state_e terminal_state() const noexcept { return m_state; }
- constexpr void set_state(state_e state) noexcept { m_state = state; }
+ constexpr void set_state(state_e state) noexcept { m_state = state; }
- void reset() noexcept { set_state(is_type(terminal_type::OUTPUT) ? STATE_OUT : STATE_INP_ACTIVE); }
+ void reset() noexcept
+ {
+ set_state(
+ is_type(terminal_type::OUTPUT) ? STATE_OUT : STATE_INP_ACTIVE);
+ }
- constexpr void set_copied_input([[maybe_unused]] netlist_sig_t val) noexcept
+ constexpr void set_copied_input(
+ [[maybe_unused]] netlist_sig_t val) noexcept
{
if constexpr (config::use_copy_instead_of_reference::value)
{
@@ -267,20 +284,24 @@ namespace netlist::detail {
}
}
- void set_delegate(const nl_delegate &delegate) noexcept { m_delegate = delegate; }
+ void set_delegate(const nl_delegate &delegate) noexcept
+ {
+ m_delegate = delegate;
+ }
const nl_delegate &delegate() const noexcept { return m_delegate; }
void run_delegate() const noexcept { return m_delegate(); }
+
protected:
- //std::conditional_t<config::use_copy_instead_of_reference::value, state_var_sig, void *> m_Q;
+ // std::conditional_t<config::use_copy_instead_of_reference::value,
+ // state_var_sig, void *> m_Q;
state_var_sig m_Q_CIR;
+
private:
- nl_delegate m_delegate;
- net_t * m_net;
+ nl_delegate m_delegate;
+ net_t * m_net;
state_var<state_e> m_state;
};
-
} // namespace netlist::detail
-
#endif // NL_CORE_BASE_OBJECTS_H_
diff --git a/src/lib/netlist/core/core_device.h b/src/lib/netlist/core/core_device.h
index b81835b716e..87391450787 100644
--- a/src/lib/netlist/core/core_device.h
+++ b/src/lib/netlist/core/core_device.h
@@ -9,21 +9,60 @@
#define NL_CORE_DEVICE_H_
#include "../nltypes.h"
-#include "../plib/pstring.h"
#include "base_objects.h"
-#include "logic_family.h"
+
+#include "../plib/pstring.h"
namespace netlist
{
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
+ // core_device_t construction parameters
+ // -------------------------------------------------------------------------
+
+ struct core_device_data_t
+ {
+ friend class core_device_t;
+ friend class base_device_t;
+ friend class analog::NETLIB_NAME(two_terminal);
+ friend class logic_family_std_proxy_t;
+
+ template <unsigned m_NI, unsigned m_NO>
+ friend class devices::factory_truth_table_t;
+
+ template <class C, typename... Args>
+ friend class factory::device_element_t;
+ friend class factory::library_element_t;
+
+ template <typename CX>
+ friend struct sub_device_wrapper;
+
+ friend class solver::matrix_solver_t;
+
+ private:
+ core_device_data_t(netlist_state_t &o, const pstring &n)
+ : owner(o)
+ , name(n)
+ {
+ }
+ netlist_state_t &owner;
+ const pstring & name;
+ };
+
+ // The type use to pass data on
+ using core_device_param_t = const core_device_data_t &;
+
+ // -------------------------------------------------------------------------
// core_device_t
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// FIXME: belongs into detail namespace
+
class core_device_t : public detail::netlist_object_t
{
public:
- core_device_t(netlist_state_t &owner, const pstring &name);
- core_device_t(core_device_t &owner, const pstring &name);
+ using constructor_data_t = core_device_data_t;
+ using constructor_param_t = core_device_param_t;
+
+ core_device_t(core_device_param_t data);
core_device_t(const core_device_t &) = delete;
core_device_t &operator=(const core_device_t &) = delete;
@@ -50,25 +89,25 @@ namespace netlist
plib::pperfcount_t<true> m_stat_inc_active;
};
- stats_t * stats() const noexcept { return m_stats.get(); }
+ stats_t *stats() const noexcept { return m_stats.get(); }
- virtual void reset() { }
+ virtual void reset() {}
- void handler_noop()
- {
- }
+ void handler_noop() {}
protected:
- using activate_delegate = plib::pmfp<void (bool)>;
+ using activate_delegate = plib::pmfp<void(bool)>;
activate_delegate m_activate;
- log_type & log();
+ log_type &log();
public:
virtual void time_step([[maybe_unused]] time_step_type ts_type,
- [[maybe_unused]] nl_fptype st) noexcept { }
- virtual void update_terminals() noexcept { }
+ [[maybe_unused]] nl_fptype st) noexcept
+ {
+ }
+ virtual void update_terminals() noexcept {}
virtual void update_param() noexcept {}
virtual bool is_dynamic() const noexcept { return false; }
@@ -76,8 +115,8 @@ namespace netlist
private:
// FIXME: should this be a state_var?
- bool m_hint_deactivate;
- state_var_s32 m_active_outputs;
+ bool m_hint_deactivate;
+ state_var_s32 m_active_outputs;
device_arena::unique_ptr<stats_t> m_stats;
};
@@ -91,7 +130,7 @@ namespace netlist
{
if (m_stats)
m_stats->m_stat_inc_active.inc();
- m_activate(true);//inc_active();
+ m_activate(true); // inc_active();
}
}
}
@@ -103,44 +142,62 @@ namespace netlist
if (!m_activate.isnull() && m_hint_deactivate)
if (--m_active_outputs == 0)
{
- m_activate(false); //dec_active();
+ m_activate(false); // dec_active();
}
}
+ // -------------------------------------------------------------------------
+ // core_device_t construction parameters
+ // -------------------------------------------------------------------------
+
+ using base_device_data_t = core_device_data_t;
+ // The type use to pass data on
+ using base_device_param_t = const base_device_data_t &;
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// base_device_t
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
- class base_device_t : public core_device_t
+ class base_device_t : public core_device_t
{
public:
- base_device_t(netlist_state_t &owner, const pstring &name);
- base_device_t(base_device_t &owner, const pstring &name);
+ using constructor_data_t = base_device_data_t;
+ using constructor_param_t = base_device_param_t;
+
+ base_device_t(base_device_param_t data);
PCOPYASSIGNMOVE(base_device_t, delete)
~base_device_t() noexcept override = default;
template <class O, class C, typename... Args>
- void create_and_register_sub_device(O& owner, const pstring &name, device_arena::unique_ptr<C> &dev, Args&&... args)
+ void create_and_register_sub_device(O &owner, const pstring &name,
+ device_arena::unique_ptr<C> &dev, Args &&...args)
{
- dev = state().make_pool_object<C>(owner, name, std::forward<Args>(args)...);
+ // dev = state().make_pool_object<C>(owner, name,
+ // std::forward<Args>(args)...);
+ using dev_constructor_data_t = typename C::constructor_data_t;
+ dev = state().make_pool_object<C>(
+ dev_constructor_data_t{state(), owner.name() + "." + name},
+ std::forward<Args>(args)...);
+ state().register_device(dev->name(),
+ device_arena::owned_ptr<core_device_t>(dev.get(), false));
}
- void register_sub_alias(const pstring &name, const detail::core_terminal_t &term);
+ void register_sub_alias(const pstring &name,
+ const detail::core_terminal_t & term);
void register_sub_alias(const pstring &name, const pstring &aliased);
void connect(const pstring &t1, const pstring &t2);
- void connect(const detail::core_terminal_t &t1, const detail::core_terminal_t &t2);
- protected:
+ void connect(const detail::core_terminal_t &t1,
+ const detail::core_terminal_t & t2);
- //NETLIB_UPDATE_TERMINALSI() { }
+ protected:
+ // NETLIB_UPDATE_TERMINALSI() { }
private:
};
} // namespace netlist
-
#endif // NL_CORE_DEVICE_H_
diff --git a/src/lib/netlist/core/device.h b/src/lib/netlist/core/device.h
index 33a1bdaac35..5f4a6937f23 100644
--- a/src/lib/netlist/core/device.h
+++ b/src/lib/netlist/core/device.h
@@ -9,29 +9,35 @@
#define NL_DEVICE_H_
#include "core_device.h"
+#include "logic_family.h"
#include "param.h"
namespace netlist
{
- // -----------------------------------------------------------------------------
+
+ // -------------------------------------------------------------------------
+ // device_t construction parameters
+ // -------------------------------------------------------------------------
+
+ using device_data_t = base_device_data_t;
+ // The type use to pass data on
+ using device_param_t = const device_data_t &;
+
+ // -------------------------------------------------------------------------
// device_t
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
- class device_t : public base_device_t,
- public logic_family_t
+ class device_t : public base_device_t, public logic_family_t
{
public:
- device_t(netlist_state_t &owner, const pstring &name);
- device_t(netlist_state_t &owner, const pstring &name,
- const pstring &model);
- // only needed by proxies
- device_t(netlist_state_t &owner, const pstring &name,
- const logic_family_desc_t *desc);
+ using constructor_data_t = device_data_t;
+ using constructor_param_t = device_param_t;
+
+ device_t(device_param_t data);
- device_t(device_t &owner, const pstring &name);
- // pass in a default model - this may be overwritten by PARAM(DEVICE.MODEL, "XYZ(...)")
- device_t(device_t &owner, const pstring &name,
- const pstring &model);
+ device_t(device_param_t data, const pstring &model);
+ // only needed by proxies
+ device_t(device_param_t data, const logic_family_desc_t *desc);
device_t(const device_t &) = delete;
device_t &operator=(const device_t &) = delete;
@@ -42,8 +48,9 @@ namespace netlist
protected:
template <typename T1, typename T2>
- void push_two(T1 &term1, netlist_sig_t newQ1, const netlist_time &delay1,
- T2 &term2, netlist_sig_t newQ2, const netlist_time &delay2) noexcept
+ void push_two(T1 &term1, netlist_sig_t newQ1,
+ const netlist_time &delay1, T2 &term2, netlist_sig_t newQ2,
+ const netlist_time &delay2) noexcept
{
if (delay2 < delay1)
{
@@ -57,13 +64,51 @@ namespace netlist
}
}
-
- //NETLIB_UPDATE_TERMINALSI() { }
+ // NETLIB_UPDATE_TERMINALSI() { }
private:
param_model_t m_model;
};
-} // namespace netlist
+ // -------------------------------------------------------------------------
+ // FIXME: Rename
+ // -------------------------------------------------------------------------
+
+ template <typename CX>
+ struct sub_device_wrapper
+ {
+ using constructor_data_t = typename CX::constructor_data_t;
+ using constructor_param_t = typename CX::constructor_param_t;
+ template <typename... Args>
+ sub_device_wrapper(base_device_t &owner, const pstring &name,
+ Args &&...args)
+ {
+ // m_dev = owner.state().make_pool_object<CX>(owner, name,
+ // std::forward<Args>(args)...);
+ m_dev = owner.state().make_pool_object<CX>(
+ constructor_data_t{owner.state(), owner.name() + "." + name},
+ std::forward<Args>(args)...);
+ owner.state().register_device(m_dev->name(),
+ device_arena::owned_ptr<core_device_t>(m_dev.get(), false));
+ }
+ template <typename... Args>
+ sub_device_wrapper(device_t &owner, const pstring &name, Args &&...args)
+ {
+ // m_dev = owner.state().make_pool_object<CX>(owner, name,
+ // std::forward<Args>(args)...);
+ m_dev = owner.state().make_pool_object<CX>(
+ constructor_data_t{owner.state(), owner.name() + "." + name},
+ std::forward<Args>(args)...);
+ owner.state().register_device(m_dev->name(),
+ device_arena::owned_ptr<core_device_t>(m_dev.get(), false));
+ }
+ CX & operator()() { return *m_dev; }
+ const CX &operator()() const { return *m_dev; }
+
+ private:
+ device_arena::unique_ptr<CX> m_dev;
+ };
+
+} // namespace netlist
#endif // NL_DEVICE_H_
diff --git a/src/lib/netlist/core/device_macros.h b/src/lib/netlist/core/device_macros.h
index 156722bfc65..af1fb15e78f 100644
--- a/src/lib/netlist/core/device_macros.h
+++ b/src/lib/netlist/core/device_macros.h
@@ -8,9 +8,9 @@
/// \file device_macros.h
///
-//============================================================
+// -----------------------------------------------------------------------------
// MACROS / New Syntax
-//============================================================
+// -----------------------------------------------------------------------------
/// \brief Start a netlist device class.
///
@@ -25,45 +25,20 @@
///
/// Also refer to #NETLIB_CONSTRUCTOR.
#define NETLIB_OBJECT(name) \
-class NETLIB_NAME(name) : public delegator_t<device_t>
-
-/// \brief Start a derived netlist device class.
-///
-/// Used to define a derived device class based on `plcass`.
-/// The simplest device without inputs or outputs would look like this:
-///
-/// NETLIB_OBJECT_DERIVED(some_object, parent_object)
-/// {
-/// public:
-/// NETLIB_CONSTRUCTOR(some_object) { }
-/// };
-///
-/// Also refer to #NETLIB_CONSTRUCTOR.
-#define NETLIB_OBJECT_DERIVED(name, pclass) \
-class NETLIB_NAME(name) : public delegator_t<NETLIB_NAME(pclass)>
-
-
-
-// Only used for analog objects like diodes and resistors
-
-#define NETLIB_BASE_OBJECT(name) \
-class NETLIB_NAME(name) : public delegator_t<base_device_t>
-
-#define NETLIB_CONSTRUCTOR_PASS(cname, ...) \
- using this_type = NETLIB_NAME(cname); \
- public: template <class CLASS> NETLIB_NAME(cname)(CLASS &owner, const pstring &name) \
- : base_type(owner, name, __VA_ARGS__)
+ class NETLIB_NAME(name) \
+ : public device_t
/// \brief Used to define the constructor of a netlist device.
///
/// Use this to define the constructor of a netlist device. Please refer to
/// #NETLIB_OBJECT for an example.
#define NETLIB_CONSTRUCTOR(cname) \
- using this_type = NETLIB_NAME(cname); \
- public: template <class CLASS> NETLIB_NAME(cname)(CLASS &owner, const pstring &name)\
- : base_type(owner, name)
+public: \
+ NETLIB_NAME(cname)(constructor_param_t data) \
+ : device_t(data)
-/// \brief Used to define the constructor of a netlist device and define a default model.
+/// \brief Used to define the constructor of a netlist device and define a
+/// default model.
///
///
/// NETLIB_CONSTRUCTOR_MODEL(some_object, "TTL")
@@ -72,22 +47,16 @@ class NETLIB_NAME(name) : public delegator_t<base_device_t>
/// NETLIB_CONSTRUCTOR(some_object) { }
/// };
///
-#define NETLIB_CONSTRUCTOR_MODEL(cname, cmodel) \
- using this_type = NETLIB_NAME(cname); \
- public: template <class CLASS> NETLIB_NAME(cname)(CLASS &owner, const pstring &name) \
- : base_type(owner, name, cmodel)
-
-/// \brief Define an extended constructor and add further parameters to it.
-/// The macro allows to add further parameters to a device constructor. This is
-/// normally used for sub-devices and system devices only.
-#define NETLIB_CONSTRUCTOR_EX(cname, ...) \
- using this_type = NETLIB_NAME(cname); \
- public: template <class CLASS> NETLIB_NAME(cname)(CLASS &owner, const pstring &name, __VA_ARGS__) \
- : base_type(owner, name)
+#define NETLIB_CONSTRUCTOR_MODEL(cname, cmodel) \
+public: \
+ NETLIB_NAME(cname)(constructor_param_t data) \
+ : device_t(data, cmodel)
/// \brief Used to define the destructor of a netlist device.
/// The use of a destructor for netlist device should normally not be necessary.
-#define NETLIB_DESTRUCTOR(name) public: virtual ~NETLIB_NAME(name)() noexcept override
+#define NETLIB_DESTRUCTOR(name) \
+public: \
+ virtual ~NETLIB_NAME(name)() noexcept override
/// \brief Add this to a device definition to mark the device as dynamic.
///
@@ -102,9 +71,11 @@ class NETLIB_NAME(name) : public delegator_t<base_device_t>
/// \param expr boolean expression
///
#define NETLIB_IS_DYNAMIC(expr) \
- public: virtual bool is_dynamic() const noexcept override { return expr; }
+public: \
+ virtual bool is_dynamic() const noexcept override { return expr; }
-/// \brief Add this to a device definition to mark the device as a time-stepping device.
+/// \brief Add this to a device definition to mark the device as a time-stepping
+/// device.
///
/// You have to implement NETLIB_TIMESTEP in this case as well. Currently, only
/// the capacitor and inductor devices uses this.
@@ -127,14 +98,17 @@ class NETLIB_NAME(name) : public delegator_t<base_device_t>
/// \endcode
#define NETLIB_IS_TIMESTEP(expr) \
- public: virtual bool is_time_step() const noexcept override { return expr; }
+public: \
+ virtual bool is_time_step() const noexcept override { return expr; }
/// \brief Used to implement the time stepping code.
///
/// Please see \ref NETLIB_IS_TIMESTEP for an example.
#define NETLIB_TIMESTEPI() \
- public: virtual void time_step(time_step_type ts_type, nl_fptype step) noexcept override
+public: \
+ virtual void time_step(time_step_type ts_type, \
+ nl_fptype step) noexcept override
/// \brief Used to implement the body of the time stepping code.
///
@@ -145,26 +119,36 @@ class NETLIB_NAME(name) : public delegator_t<base_device_t>
/// \param cname Name of object as given to \ref NETLIB_OBJECT
///
#define NETLIB_TIMESTEP(cname) \
- void NETLIB_NAME(cname) :: time_step(time_step_type ts_type, nl_fptype step) noexcept
+ void NETLIB_NAME(cname)::time_step(time_step_type ts_type, \
+ nl_fptype step) noexcept
-#define NETLIB_DELEGATE(name) nl_delegate(&this_type :: name, this)
+//#define NETLIB_DELEGATE(name) nl_delegate(&this_type :: name, this)
+#define NETLIB_DELEGATE(name) \
+ nl_delegate(&std::remove_pointer_t<decltype(this)>::name, this)
-#define NETLIB_DELEGATE_NOOP() nl_delegate(&core_device_t::handler_noop, static_cast<core_device_t *>(this))
+#define NETLIB_DELEGATE_NOOP() \
+ nl_delegate(&core_device_t::handler_noop, \
+ static_cast<core_device_t *>(this))
-#define NETLIB_UPDATE_TERMINALSI() virtual void update_terminals() noexcept override
+#define NETLIB_UPDATE_TERMINALSI() \
+ virtual void update_terminals() noexcept override
#define NETLIB_HANDLERI(name) void name() noexcept
#define NETLIB_UPDATE_PARAMI() virtual void update_param() noexcept override
#define NETLIB_RESETI() virtual void reset() override
-#define NETLIB_SUB(chip) nld_ ## chip
-#define NETLIB_SUB_UPTR(ns, chip) device_arena::unique_ptr< ns :: nld_ ## chip >
+#define NETLIB_SUB(chip) sub_device_wrapper<nld_##chip>
+#define NETLIB_SUB_NS(ns, chip) sub_device_wrapper<ns ::nld_##chip>
+
+#define NETLIB_SUB_UPTR(ns, chip) device_arena::unique_ptr<ns ::nld_##chip>
-#define NETLIB_HANDLER(chip, name) void NETLIB_NAME(chip) :: name() noexcept
+#define NETLIB_HANDLER(chip, name) void NETLIB_NAME(chip)::name() noexcept
-#define NETLIB_RESET(chip) void NETLIB_NAME(chip) :: reset(void)
+#define NETLIB_RESET(chip) void NETLIB_NAME(chip)::reset(void)
-#define NETLIB_UPDATE_PARAM(chip) void NETLIB_NAME(chip) :: update_param() noexcept
+#define NETLIB_UPDATE_PARAM(chip) \
+ void NETLIB_NAME(chip)::update_param() noexcept
-#define NETLIB_UPDATE_TERMINALS(chip) void NETLIB_NAME(chip) :: update_terminals() noexcept
+#define NETLIB_UPDATE_TERMINALS(chip) \
+ void NETLIB_NAME(chip)::update_terminals() noexcept
#endif // NL_CORE_DEVICE_MACROS_H_
diff --git a/src/lib/netlist/core/devices.h b/src/lib/netlist/core/devices.h
index 07c82be20da..29667723bf5 100644
--- a/src/lib/netlist/core/devices.h
+++ b/src/lib/netlist/core/devices.h
@@ -30,25 +30,23 @@ namespace netlist::devices
NETLIB_OBJECT(mainclock)
{
NETLIB_CONSTRUCTOR(mainclock)
- , m_Q(*this, "Q")
- , m_freq(*this, "FREQ", nlconst::magic(7159000.0 * 5))
+ , m_Q(*this, "Q"), m_freq(*this, "FREQ", nlconst::magic(7159000.0 * 5))
{
- m_inc = netlist_time::from_fp(plib::reciprocal(m_freq()*nlconst::two()));
+ m_inc = netlist_time::from_fp(
+ plib::reciprocal(m_freq() * nlconst::two()));
}
- NETLIB_RESETI()
- {
- m_Q.net().set_next_scheduled_time(exec().time());
- }
+ NETLIB_RESETI() { m_Q.net().set_next_scheduled_time(exec().time()); }
NETLIB_UPDATE_PARAMI()
{
- m_inc = netlist_time::from_fp(plib::reciprocal(m_freq()*nlconst::two()));
+ m_inc = netlist_time::from_fp(
+ plib::reciprocal(m_freq() * nlconst::two()));
}
public:
- logic_output_t m_Q; // NOLINT: needed in core
- netlist_time m_inc; // NOLINT: needed in core
+ logic_output_t m_Q; // NOLINT: needed in core
+ netlist_time m_inc; // NOLINT: needed in core
private:
param_fp_t m_freq;
};
@@ -65,7 +63,7 @@ namespace netlist::devices
class nld_power_pins
{
public:
- using this_type = nld_power_pins;
+ using constructor_type = nld_power_pins;
explicit nld_power_pins(device_t &owner)
: m_VCC(owner, owner.logic_family()->vcc_pin(), NETLIB_DELEGATE(noop))
@@ -80,33 +78,26 @@ namespace netlist::devices
}
// Some devices like the 74LS629 have two pairs of supply pins.
- explicit nld_power_pins(device_t &owner,
- const pstring &vcc, const pstring &gnd)
+ explicit nld_power_pins(device_t &owner, const pstring &vcc,
+ const pstring &gnd)
: m_VCC(owner, vcc, NETLIB_DELEGATE(noop))
, m_GND(owner, gnd, NETLIB_DELEGATE(noop))
{
}
// Some devices like the 74LS629 have two pairs of supply pins.
- explicit nld_power_pins(device_t &owner,
- const pstring &vcc, const pstring &gnd,
- nl_delegate delegate)
+ explicit nld_power_pins(device_t &owner, const pstring &vcc,
+ const pstring &gnd, nl_delegate delegate)
: m_VCC(owner, vcc, delegate)
, m_GND(owner, gnd, delegate)
{
}
- const analog_input_t &VCC() const noexcept
- {
- return m_VCC;
- }
- const analog_input_t &GND() const noexcept
- {
- return m_GND;
- }
+ const analog_input_t &VCC() const noexcept { return m_VCC; }
+ const analog_input_t &GND() const noexcept { return m_GND; }
private:
- void noop() { }
+ void noop() {}
analog_input_t m_VCC;
analog_input_t m_GND;
};
@@ -124,14 +115,14 @@ namespace netlist::devices
, m_max_link_loops(*this, "MAX_LINK_RESOLVE_LOOPS", 100)
{
}
- //NETLIB_RESETI() {}
- //NETLIB_UPDATE_PARAMI() { }
+ // NETLIB_RESETI() {}
+ // NETLIB_UPDATE_PARAMI() { }
public:
- param_logic_t m_use_deactivate;
- param_num_t<unsigned> m_startup_strategy;
- param_num_t<unsigned> m_mos_cap_model;
+ param_logic_t m_use_deactivate;
+ param_num_t<unsigned> m_startup_strategy;
+ param_num_t<unsigned> m_mos_cap_model;
//! How many times do we try to resolve links (connections)
- param_num_t<unsigned> m_max_link_loops;
+ param_num_t<unsigned> m_max_link_loops;
};
// -----------------------------------------------------------------------------
@@ -145,16 +136,13 @@ namespace netlist::devices
{
public:
NETLIB_CONSTRUCTOR(nc_pin)
- , m_I(*this, "I", NETLIB_DELEGATE_NOOP())
- {
- }
+ , m_I(*this, "I", NETLIB_DELEGATE_NOOP()) {}
protected:
- //NETLIB_RESETI() {}
+ // NETLIB_RESETI() {}
private:
analog_input_t m_I;
-
};
// -----------------------------------------------------------------------------
@@ -164,16 +152,11 @@ namespace netlist::devices
NETLIB_OBJECT(gnd)
{
NETLIB_CONSTRUCTOR(gnd)
- , m_Q(*this, "Q")
- {
- }
+ , m_Q(*this, "Q") {}
- NETLIB_UPDATE_PARAMI()
- {
- m_Q.push(nlconst::zero());
- }
+ NETLIB_UPDATE_PARAMI() { m_Q.push(nlconst::zero()); }
- //NETLIB_RESETI() {}
+ // NETLIB_RESETI() {}
protected:
analog_output_t m_Q;
};
diff --git a/src/lib/netlist/core/exec.h b/src/lib/netlist/core/exec.h
index 70786d420e6..091d7181e7d 100644
--- a/src/lib/netlist/core/exec.h
+++ b/src/lib/netlist/core/exec.h
@@ -8,23 +8,22 @@
#ifndef NL_CORE_EXEC_H_
#define NL_CORE_EXEC_H_
+#include "../nltypes.h"
#include "base_objects.h"
#include "state_var.h"
-#include "../nltypes.h"
#include "../plib/plists.h"
#include "../plib/pstring.h"
namespace netlist
{
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// netlist_t
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
class netlist_t // NOLINT(clang-analyzer-optin.performance.Padding)
{
public:
-
explicit netlist_t(netlist_state_t &state, const pstring &aname);
netlist_t(const netlist_t &) = delete;
@@ -36,7 +35,10 @@ namespace netlist
// run functions
- constexpr const netlist_time_ext &time() const noexcept { return m_time; }
+ constexpr const netlist_time_ext &time() const noexcept
+ {
+ return m_time;
+ }
void process_queue(netlist_time_ext delta) noexcept;
void abort_current_queue_slice() noexcept
@@ -45,15 +47,20 @@ namespace netlist
queue_push(m_time, nullptr);
}
- constexpr const detail::queue_t &queue() const noexcept { return m_queue; }
+ constexpr const detail::queue_t &queue() const noexcept
+ {
+ return m_queue;
+ }
template <typename... Args>
- void queue_push(Args&&...args) noexcept
+ void queue_push(Args &&...args) noexcept
{
if (config::use_queue_stats::value && m_use_stats)
- m_queue.emplace<true>(std::forward<Args>(args)...); // NOLINT(performance-move-const-arg)
+ m_queue.emplace<true>(std::forward<Args>(
+ args)...); // NOLINT(performance-move-const-arg)
else
- m_queue.emplace<false>(std::forward<Args>(args)...); // NOLINT(performance-move-const-arg)
+ m_queue.emplace<false>(std::forward<Args>(
+ args)...); // NOLINT(performance-move-const-arg)
}
template <class R>
@@ -80,40 +87,38 @@ namespace netlist
return static_cast<X *>(m_solver)->gmin();
}
- netlist_state_t &nl_state() noexcept { return m_state; }
+ netlist_state_t & nl_state() noexcept { return m_state; }
const netlist_state_t &nl_state() const noexcept { return m_state; }
- log_type & log() noexcept { return m_state.log(); }
+ log_type & log() noexcept { return m_state.log(); }
const log_type &log() const noexcept { return m_state.log(); }
void print_stats() const;
constexpr bool stats_enabled() const noexcept { return m_use_stats; }
- void enable_stats(bool val) noexcept { m_use_stats = val; }
+ void enable_stats(bool val) noexcept { m_use_stats = val; }
private:
-
template <bool KEEP_STATS>
void process_queue_stats(netlist_time_ext delta) noexcept;
- netlist_state_t & m_state;
- devices::nld_solver * m_solver;
+ netlist_state_t & m_state;
+ devices::nld_solver *m_solver;
// mostly rw
- //PALIGNAS(16)
- netlist_time_ext m_time;
- devices::nld_mainclock * m_main_clock;
-
- //PALIGNAS_CACHELINE()
- //PALIGNAS(16)
- bool m_use_stats;
- detail::queue_t m_queue;
+ // PALIGNAS(16)
+ netlist_time_ext m_time;
+ devices::nld_mainclock *m_main_clock;
+
+ // PALIGNAS_CACHELINE()
+ // PALIGNAS(16)
+ bool m_use_stats;
+ detail::queue_t m_queue;
// performance
- plib::pperftime_t<true> m_stat_mainloop;
- plib::pperfcount_t<true> m_perf_out_processed;
+ plib::pperftime_t<true> m_stat_mainloop;
+ plib::pperfcount_t<true> m_perf_out_processed;
};
} // namespace netlist
-
#endif // NL_CORE_EXEC_H_
diff --git a/src/lib/netlist/core/logic.h b/src/lib/netlist/core/logic.h
index 2efa92d8f6d..ef567398c84 100644
--- a/src/lib/netlist/core/logic.h
+++ b/src/lib/netlist/core/logic.h
@@ -2,7 +2,7 @@
// copyright-holders:Couriersud
///
-/// \file param.h
+/// \file logic.h
///
#ifndef NL_CORE_LOGIC_H_
@@ -22,37 +22,39 @@
namespace netlist
{
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// logic_t
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
- class logic_t : public detail::core_terminal_t, public logic_family_t
+ class logic_t
+ : public detail::core_terminal_t
+ , public logic_family_t
{
public:
- logic_t(device_t &dev, const pstring &aname,
- state_e terminal_state, nl_delegate delegate);
+ logic_t(device_t &dev, const pstring &aname, state_e terminal_state,
+ nl_delegate delegate);
- logic_net_t & net() noexcept
+ logic_net_t &net() noexcept
{
return plib::downcast<logic_net_t &>(core_terminal_t::net());
}
- constexpr const logic_net_t & net() const noexcept
+ constexpr const logic_net_t &net() const noexcept
{
return plib::downcast<const logic_net_t &>(core_terminal_t::net());
}
};
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// logic_input_t
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
class logic_input_t : public logic_t
{
public:
logic_input_t(device_t &dev, const pstring &aname,
- nl_delegate delegate);
+ nl_delegate delegate);
- //const netlist_sig_t &operator()() const noexcept
+ // const netlist_sig_t &operator()() const noexcept
constexpr netlist_sig_t operator()() const noexcept
{
gsl_Expects(terminal_state() != STATE_INP_PASSIVE);
@@ -97,17 +99,15 @@ namespace netlist
set_state(STATE_INP_LH);
}
}
-
};
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// logic_output_t
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
class logic_output_t : public logic_t
{
public:
-
/// \brief logic output constructor
///
/// The third parameter does nothing. It is provided only for
@@ -115,7 +115,8 @@ namespace netlist
///
/// \param dev Device owning this output
/// \param aname The name of this output
- /// \param dummy Dummy parameter to allow construction like tristate output
+ /// \param dummy Dummy parameter to allow construction like tristate
+ /// output
///
logic_output_t(device_t &dev, const pstring &aname, bool dummy = false);
@@ -142,17 +143,20 @@ namespace netlist
/// This function terminates if actually called.
///
[[noreturn]] static void set_tristate([[maybe_unused]] netlist_sig_t v,
- [[maybe_unused]] netlist_time ts_off_on, [[maybe_unused]] netlist_time ts_on_off)
+ [[maybe_unused]] netlist_time ts_off_on,
+ [[maybe_unused]] netlist_time ts_on_off)
{
- plib::terminate("set_tristate on logic_output should never be called!");
+ plib::terminate(
+ "set_tristate on logic_output should never be called!");
}
+
private:
logic_net_t m_my_net;
};
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// tristate_output_t
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
/// \brief Tristate output
///
@@ -170,8 +174,8 @@ namespace netlist
class tristate_output_t : public logic_output_t
{
public:
-
- tristate_output_t(device_t &dev, const pstring &aname, bool force_logic);
+ tristate_output_t(device_t &dev, const pstring &aname,
+ bool force_logic);
void push(netlist_sig_t newQ, netlist_time delay) noexcept
{
@@ -180,31 +184,29 @@ namespace netlist
m_last_logic = newQ;
}
- void set_tristate(netlist_sig_t v,
- netlist_time ts_off_on, netlist_time ts_on_off) noexcept
+ void set_tristate(netlist_sig_t v, netlist_time ts_off_on,
+ netlist_time ts_on_off) noexcept
{
if (!m_force_logic)
if (v != m_tristate)
{
- logic_output_t::push((v != 0) ? OUT_TRISTATE() : m_last_logic, v ? ts_off_on : ts_on_off);
+ logic_output_t::push((v != 0) ? OUT_TRISTATE()
+ : m_last_logic,
+ v ? ts_off_on : ts_on_off);
m_tristate = v;
}
}
- bool is_force_logic() const noexcept
- {
- return m_force_logic;
- }
+ bool is_force_logic() const noexcept { return m_force_logic; }
private:
using logic_output_t::initial;
using logic_output_t::set_Q_time;
state_var<netlist_sig_t> m_last_logic;
state_var<netlist_sig_t> m_tristate;
- bool m_force_logic;
+ bool m_force_logic;
};
} // namespace netlist
-
#endif // NL_CORE_LOGIC_H_
diff --git a/src/lib/netlist/core/logic_family.h b/src/lib/netlist/core/logic_family.h
index 7264987b466..97084dd4dc0 100644
--- a/src/lib/netlist/core/logic_family.h
+++ b/src/lib/netlist/core/logic_family.h
@@ -9,6 +9,7 @@
#define NL_CORE_LOGIC_FAMILY_H_
#include "../nltypes.h"
+
#include "../plib/pstring.h"
namespace netlist
@@ -20,52 +21,78 @@ namespace netlist
class logic_family_desc_t
{
public:
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init, modernize-use-equals-default)
- logic_family_desc_t()
- {
- }
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init,
+ // modernize-use-equals-default)
+ logic_family_desc_t() = default;
logic_family_desc_t(const logic_family_desc_t &) = delete;
logic_family_desc_t &operator=(const logic_family_desc_t &) = delete;
// FOXME: Should be move constructible
logic_family_desc_t(logic_family_desc_t &&) noexcept = delete;
- logic_family_desc_t &operator=(logic_family_desc_t &&) noexcept = delete;
+ logic_family_desc_t &operator=(
+ logic_family_desc_t &&) noexcept = delete;
virtual ~logic_family_desc_t() noexcept = default;
- virtual device_arena::unique_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_state_t &anetlist, const pstring &name,
- const logic_output_t *proxied) const = 0;
- virtual device_arena::unique_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_state_t &anetlist, const pstring &name,
- const logic_input_t *proxied) const = 0;
+ virtual device_arena::unique_ptr<devices::nld_base_d_to_a_proxy>
+ create_d_a_proxy(netlist_state_t &anetlist, const pstring &name,
+ const logic_output_t *proxied) const = 0;
+ virtual device_arena::unique_ptr<devices::nld_base_a_to_d_proxy>
+ create_a_d_proxy(netlist_state_t &anetlist, const pstring &name,
+ const logic_input_t *proxied) const = 0;
- nl_fptype low_threshold_V(nl_fptype VN, nl_fptype VP) const noexcept{ return VN + (VP - VN) * m_low_threshold_PCNT; }
- nl_fptype high_threshold_V(nl_fptype VN, nl_fptype VP) const noexcept{ return VN + (VP - VN) * m_high_threshold_PCNT; }
- nl_fptype low_offset_V() const noexcept{ return m_low_VO; }
- nl_fptype high_offset_V() const noexcept{ return m_high_VO; }
- nl_fptype R_low() const noexcept{ return m_R_low; }
- nl_fptype R_high() const noexcept{ return m_R_high; }
+ nl_fptype low_threshold_V(nl_fptype VN, nl_fptype VP) const noexcept
+ {
+ return VN + (VP - VN) * m_low_threshold_PCNT;
+ }
+ nl_fptype high_threshold_V(nl_fptype VN, nl_fptype VP) const noexcept
+ {
+ return VN + (VP - VN) * m_high_threshold_PCNT;
+ }
+ nl_fptype low_offset_V() const noexcept { return m_low_VO; }
+ nl_fptype high_offset_V() const noexcept { return m_high_VO; }
+ nl_fptype R_low() const noexcept { return m_R_low; }
+ nl_fptype R_high() const noexcept { return m_R_high; }
- bool is_above_high_threshold_V(nl_fptype V, nl_fptype VN, nl_fptype VP) const noexcept
- { return V > high_threshold_V(VN, VP); }
+ bool is_above_high_threshold_V(nl_fptype V, nl_fptype VN,
+ nl_fptype VP) const noexcept
+ {
+ return V > high_threshold_V(VN, VP);
+ }
- bool is_below_low_threshold_V(nl_fptype V, nl_fptype VN, nl_fptype VP) const noexcept
- { return V < low_threshold_V(VN, VP); }
+ bool is_below_low_threshold_V(nl_fptype V, nl_fptype VN,
+ nl_fptype VP) const noexcept
+ {
+ return V < low_threshold_V(VN, VP);
+ }
pstring vcc_pin() const { return pstring(m_vcc); }
pstring gnd_pin() const { return pstring(m_gnd); }
- nl_fptype m_low_threshold_PCNT; //!< low input threshold offset. If the input voltage is below this value times supply voltage, a "0" input is signalled
- nl_fptype m_high_threshold_PCNT; //!< high input threshold offset. If the input voltage is above the value times supply voltage, a "0" input is signalled
- nl_fptype m_low_VO; //!< low output voltage offset. This voltage is output if the ouput is "0"
- nl_fptype m_high_VO; //!< high output voltage offset. The supply voltage minus this offset is output if the ouput is "1"
- nl_fptype m_R_low; //!< low output resistance. Value of series resistor used for low output
- nl_fptype m_R_high; //!< high output resistance. Value of series resistor used for high output
- const char *m_vcc; //!< default power pin name for positive supply
- const char *m_gnd; //!< default power pin name for negative supply
+ nl_fptype m_low_threshold_PCNT; //!< low input threshold offset. If the
+ //!< input voltage is below this value
+ //!< times supply voltage, a "0" input
+ //!< is signalled
+ nl_fptype m_high_threshold_PCNT; //!< high input threshold offset. If
+ //!< the input voltage is above the
+ //!< value times supply voltage, a "0"
+ //!< input is signalled
+ nl_fptype m_low_VO; //!< low output voltage offset. This voltage is
+ //!< output if the ouput is "0"
+ nl_fptype m_high_VO; //!< high output voltage offset. The supply voltage
+ //!< minus this offset is output if the ouput is
+ //!< "1"
+ nl_fptype m_R_low; //!< low output resistance. Value of series resistor
+ //!< used for low output
+ nl_fptype m_R_high; //!< high output resistance. Value of series
+ //!< resistor used for high output
+ const char *m_vcc; //!< default power pin name for positive supply
+ const char *m_gnd; //!< default power pin name for negative supply
};
- /// \brief Base class for devices, terminals, outputs and inputs which support
+ /// \brief Base class for devices, terminals, outputs and inputs which
+ /// support
/// logic families.
/// This class is a storage container to store the logic family for a
/// netlist object. You will not directly use it. Please refer to
@@ -79,8 +106,14 @@ namespace netlist
class logic_family_t
{
public:
- logic_family_t() : m_logic_family(nullptr) {}
- logic_family_t(const logic_family_desc_t *d) : m_logic_family(d) {}
+ logic_family_t()
+ : m_logic_family(nullptr)
+ {
+ }
+ logic_family_t(const logic_family_desc_t *d)
+ : m_logic_family(d)
+ {
+ }
logic_family_t(const logic_family_t &) = delete;
logic_family_t &operator=(const logic_family_t &) = delete;
@@ -89,16 +122,22 @@ namespace netlist
logic_family_t(logic_family_t &&) noexcept = delete;
logic_family_t &operator=(logic_family_t &&) noexcept = delete;
- const logic_family_desc_t *logic_family() const noexcept { return m_logic_family; }
- void set_logic_family(const logic_family_desc_t *fam) noexcept { m_logic_family = fam; }
+ const logic_family_desc_t *logic_family() const noexcept
+ {
+ return m_logic_family;
+ }
+ void set_logic_family(const logic_family_desc_t *fam) noexcept
+ {
+ m_logic_family = fam;
+ }
protected:
- ~logic_family_t() noexcept = default; // prohibit polymorphic destruction
+ ~logic_family_t() noexcept = default; // prohibit polymorphic
+ // destruction
private:
const logic_family_desc_t *m_logic_family;
};
} // namespace netlist
-
#endif // NL_CORE_LOGIC_FAMILY_H_
diff --git a/src/lib/netlist/core/netlist_state.h b/src/lib/netlist/core/netlist_state.h
index 0f0b62f8bee..f8a87b9280f 100644
--- a/src/lib/netlist/core/netlist_state.h
+++ b/src/lib/netlist/core/netlist_state.h
@@ -8,9 +8,8 @@
#ifndef NL_CORE_NETLIST_STATE_H_
#define NL_CORE_NETLIST_STATE_H_
-#include "queue.h"
-
#include "../nltypes.h"
+#include "queue.h"
#include "../plib/plists.h"
#include "../plib/pstate.h"
@@ -30,12 +29,14 @@ namespace netlist
class netlist_state_t
{
public:
-
- using nets_collection_type = std::vector<device_arena::owned_ptr<detail::net_t>>;
- using family_collection_type = std::unordered_map<pstring, host_arena::unique_ptr<logic_family_desc_t>>;
+ using nets_collection_type = std::vector<
+ device_arena::owned_ptr<detail::net_t>>;
+ using family_collection_type = std::unordered_map<pstring,
+ host_arena::unique_ptr<logic_family_desc_t>>;
// need to preserve order of device creation ...
- using devices_collection_type = std::vector<std::pair<pstring, device_arena::owned_ptr<core_device_t>>>;
+ using devices_collection_type = std::vector<
+ std::pair<pstring, device_arena::owned_ptr<core_device_t>>>;
netlist_state_t(const pstring &name, plib::plog_delegate logger);
@@ -51,10 +52,11 @@ namespace netlist
template <class C>
static bool check_class(core_device_t *p) noexcept
{
- return dynamic_cast<C *>(p) != nullptr;
+ return bool(plib::dynamic_downcast<C *>(p));
}
- core_device_t *get_single_device(const pstring &classname, bool (*cc)(core_device_t *)) const noexcept(false);
+ core_device_t *get_single_device(const pstring &classname,
+ bool (*cc)(core_device_t *)) const noexcept(false);
/// \brief Get single device filtered by class and name
///
@@ -81,19 +83,21 @@ namespace netlist
std::vector<C *> tmp;
for (const auto &d : m_devices)
{
- auto * const dev = dynamic_cast<C *>(d.second.get());
- if (dev != nullptr)
- tmp.push_back(dev);
+ if (auto dev = plib::dynamic_downcast<C *>(d.second.get()))
+ tmp.push_back(*dev);
}
return tmp;
}
// logging
- log_type & log() noexcept { return m_log; }
+ log_type & log() noexcept { return m_log; }
const log_type &log() const noexcept { return m_log; }
- plib::dynamic_library_base &static_solver_lib() const noexcept { return *m_lib; }
+ plib::dynamic_library_base &static_solver_lib() const noexcept
+ {
+ return *m_lib;
+ }
/// \brief provide library with static solver implementations.
///
@@ -101,32 +105,41 @@ namespace netlist
/// determined by the specific use case. You can pass such a collection
/// of symbols with this method.
///
- void set_static_solver_lib(std::unique_ptr<plib::dynamic_library_base> &&lib);
+ void set_static_solver_lib(
+ std::unique_ptr<plib::dynamic_library_base> &&lib);
- netlist_t &exec() noexcept { return *m_netlist; }
+ netlist_t & exec() noexcept { return *m_netlist; }
const netlist_t &exec() const noexcept { return *m_netlist; }
// state handling
plib::state_manager_t &run_state_manager() noexcept { return m_state; }
template <typename O, typename C>
- void save(O &owner, C &state, const pstring &module, const pstring &stname)
+ void save(O &owner, C &state, const pstring &module,
+ const pstring &stname)
{
- this->run_state_manager().save_item(plib::void_ptr_cast(&owner), state, module + "." + stname);
+ this->run_state_manager().save_item(plib::void_ptr_cast(&owner),
+ state, module + "." + stname);
}
template <typename O, typename C>
- void save(O &owner, C *state, const pstring &module, const pstring &stname, const std::size_t count)
+ void save(O &owner, C *state, const pstring &module,
+ const pstring &stname, const std::size_t count)
{
- this->run_state_manager().save_state_ptr(plib::void_ptr_cast(&owner), module + "." + stname, plib::state_manager_t::dtype<C>(), count, state);
+ this->run_state_manager().save_state_ptr(
+ plib::void_ptr_cast(&owner), module + "." + stname,
+ plib::state_manager_t::dtype<C>(), count, state);
}
// FIXME: only used by queue_t save state
- std::size_t find_net_id(const detail::net_t *net) const;
+ std::size_t find_net_id(const detail::net_t *net) const;
detail::net_t *net_by_id(std::size_t id) const;
template <typename T>
- void register_net(device_arena::owned_ptr<T> &&net) { m_nets.push_back(std::move(net)); }
+ void register_net(device_arena::owned_ptr<T> &&net)
+ {
+ m_nets.push_back(std::move(net));
+ }
/// \brief Get device pointer by name
///
@@ -137,7 +150,7 @@ namespace netlist
core_device_t *find_device(const pstring &name) const
{
- for (const auto & d : m_devices)
+ for (const auto &d : m_devices)
if (d.first == name)
return d.second.get();
return nullptr;
@@ -145,24 +158,25 @@ namespace netlist
/// \brief Register device using owned_ptr
///
- /// Used to register owned devices. These are devices declared as objects
- /// in another devices.
+ /// Used to register owned devices. These are devices declared as
+ /// objects in another devices.
///
/// \param name Name of the device
/// \param dev Device to be registered
template <typename T>
- void register_device(const pstring &name, device_arena::owned_ptr<T> &&dev) noexcept(false)
+ void register_device(const pstring &name,
+ device_arena::owned_ptr<T> && dev) noexcept(false)
{
- for (auto & d : m_devices)
+ for (auto &d : m_devices)
if (d.first == name)
{
dev.release();
log().fatal(MF_DUPLICATE_NAME_DEVICE_LIST(name));
throw nl_exception(MF_DUPLICATE_NAME_DEVICE_LIST(name));
}
- //m_devices.push_back(std::move(dev));
- m_devices.insert(m_devices.end(), { name, std::move(dev) });
+ // m_devices.push_back(std::move(dev));
+ m_devices.insert(m_devices.end(), {name, std::move(dev)});
}
/// \brief Register device using unique_ptr
@@ -173,9 +187,11 @@ namespace netlist
/// \param dev Device to be registered
template <typename T>
- void register_device(const pstring &name, device_arena::unique_ptr<T> &&dev)
+ void register_device(const pstring &name,
+ device_arena::unique_ptr<T> && dev)
{
- register_device(name, device_arena::owned_ptr<T>(dev.release(), true, dev.get_deleter()));
+ register_device(name, device_arena::owned_ptr<T>(dev.release(),
+ true, dev.get_deleter()));
}
/// \brief Remove device
@@ -187,41 +203,45 @@ namespace netlist
void remove_device(core_device_t *dev);
- setup_t &setup() noexcept { return *m_setup; }
+ setup_t & setup() noexcept { return *m_setup; }
const setup_t &setup() const noexcept { return *m_setup; }
- nlparse_t &parser();
- const nlparse_t &parser() const;
+ nlparse_t & parser() noexcept;
+ const nlparse_t &parser() const noexcept;
// FIXME: make a post load member and include code there
void rebuild_lists(); // must be called after post_load !
- static void compile_defines(std::vector<std::pair<pstring, pstring>> &defs);
+ static void compile_defines(
+ std::vector<std::pair<pstring, pstring>> &defs);
static pstring version();
static pstring version_patchlevel();
- nets_collection_type & nets() noexcept { return m_nets; }
- const nets_collection_type & nets() const noexcept { return m_nets; }
+ nets_collection_type & nets() noexcept { return m_nets; }
+ const nets_collection_type &nets() const noexcept { return m_nets; }
- devices_collection_type & devices() noexcept { return m_devices; }
- const devices_collection_type & devices() const noexcept { return m_devices; }
+ devices_collection_type & devices() noexcept { return m_devices; }
+ const devices_collection_type &devices() const noexcept
+ {
+ return m_devices;
+ }
family_collection_type &family_cache() { return m_family_cache; }
template <typename T, typename... Args>
- device_arena::unique_ptr<T> make_pool_object(Args&&... args)
+ device_arena::unique_ptr<T> make_pool_object(Args &&...args)
{
return plib::make_unique<T>(m_pool, std::forward<Args>(args)...);
}
// memory pool - still needed in some places
- device_arena &pool() noexcept { return m_pool; }
+ device_arena & pool() noexcept { return m_pool; }
const device_arena &pool() const noexcept { return m_pool; }
struct stats_info
{
- const detail::queue_t &m_queue;// performance
- const plib::pperftime_t<true> &m_stat_mainloop;
- const plib::pperfcount_t<true> &m_perf_out_processed;
+ const detail::queue_t & m_queue; // performance
+ const plib::pperftime_t<true> & m_stat_mainloop;
+ const plib::pperfcount_t<true> &m_perf_out_processed;
};
/// \brief print statistics gathered during run
@@ -236,37 +256,38 @@ namespace netlist
///
void free_setup_resources();
#if !(NL_USE_INPLACE_CORE_TERMS)
- std::vector<detail::core_terminal_t *> &core_terms(const detail::net_t &net)
+ std::vector<detail::core_terminal_t *> &core_terms(
+ const detail::net_t &net)
{
return m_core_terms[&net];
}
#endif
private:
+ device_arena m_pool; // must be deleted last!
- device_arena m_pool; // must be deleted last!
-
- device_arena::unique_ptr<netlist_t> m_netlist;
- std::unique_ptr<plib::dynamic_library_base> m_lib;
- plib::state_manager_t m_state;
- log_type m_log;
+ device_arena::unique_ptr<netlist_t> m_netlist;
+ std::unique_ptr<plib::dynamic_library_base> m_lib;
+ plib::state_manager_t m_state;
+ log_type m_log;
// FIXME: should only be available during device construction
- host_arena::unique_ptr<setup_t> m_setup;
+ host_arena::unique_ptr<setup_t> m_setup;
- nets_collection_type m_nets;
+ nets_collection_type m_nets;
// sole use is to manage lifetime of net objects
- devices_collection_type m_devices;
+ devices_collection_type m_devices;
// sole use is to manage lifetime of family objects
- family_collection_type m_family_cache;
+ family_collection_type m_family_cache;
#if !(NL_USE_INPLACE_CORE_TERMS)
// all terms for a net
- std::unordered_map<const detail::net_t *, std::vector<detail::core_terminal_t *>> m_core_terms;
+ std::unordered_map<const detail::net_t *,
+ std::vector<detail::core_terminal_t *>>
+ m_core_terms;
#endif
// dummy version
- int m_dummy_version;
+ int m_dummy_version;
};
} // namespace netlist
-
#endif // NL_CORE_NETLIST_STATE_H_
diff --git a/src/lib/netlist/core/nets.h b/src/lib/netlist/core/nets.h
index 280cda2013e..1a81c7ecd1c 100644
--- a/src/lib/netlist/core/nets.h
+++ b/src/lib/netlist/core/nets.h
@@ -8,12 +8,12 @@
#ifndef NL_CORE_NETS_H_
#define NL_CORE_NETS_H_
+#include "../nltypes.h"
#include "base_objects.h"
#include "core_device.h"
#include "exec.h"
#include "state_var.h"
-#include "../nltypes.h"
#include "../plib/plists.h"
#include "../plib/pstring.h"
@@ -21,16 +21,16 @@
namespace netlist
{
- namespace detail {
+ namespace detail
+ {
- // -----------------------------------------------------------------------------
+ // ---------------------------------------------------------------------
// net_t
- // -----------------------------------------------------------------------------
+ // ---------------------------------------------------------------------
class net_t : public netlist_object_t
{
public:
-
enum class queue_status
{
DELAYED_DUE_TO_INACTIVE = 0,
@@ -38,7 +38,8 @@ namespace netlist
DELIVERED
};
- net_t(netlist_state_t &nl, const pstring &aname, core_terminal_t *rail_terminal = nullptr);
+ net_t(netlist_state_t &nl, const pstring &aname,
+ core_terminal_t *rail_terminal = nullptr);
net_t(const net_t &) = delete;
net_t &operator=(const net_t &) = delete;
@@ -49,16 +50,13 @@ namespace netlist
virtual void reset() noexcept;
- // -----------------------------------------------------------------------------
+ // -----------------------------------------------------------------
// Hot section
//
// Any changes below will impact performance.
- // -----------------------------------------------------------------------------
+ // -----------------------------------------------------------------
- constexpr void toggle_new_Q() noexcept
- {
- m_new_Q = (m_cur_Q ^ 1);
- }
+ constexpr void toggle_new_Q() noexcept { m_new_Q = (m_cur_Q ^ 1); }
void toggle_and_push_to_queue(const netlist_time &delay) noexcept
{
@@ -73,30 +71,44 @@ namespace netlist
return m_in_queue == queue_status::QUEUED;
}
- // -----------------------------------------------------------------------------
+ // -----------------------------------------------------------------
// Very hot
- // -----------------------------------------------------------------------------
+ // -----------------------------------------------------------------
template <bool KEEP_STATS>
void update_devs() noexcept;
- constexpr const netlist_time_ext &next_scheduled_time() const noexcept { return m_next_scheduled_time; }
- void set_next_scheduled_time(const netlist_time_ext &next_time) noexcept { m_next_scheduled_time = next_time; }
+ constexpr const netlist_time_ext &
+ next_scheduled_time() const noexcept
+ {
+ return m_next_scheduled_time;
+ }
+ void set_next_scheduled_time(
+ const netlist_time_ext &next_time) noexcept
+ {
+ m_next_scheduled_time = next_time;
+ }
- bool is_rail_net() const noexcept { return !(m_rail_terminal == nullptr); }
- core_terminal_t & rail_terminal() const noexcept { return *m_rail_terminal; }
+ bool is_rail_net() const noexcept
+ {
+ return !(m_rail_terminal == nullptr);
+ }
+ core_terminal_t &rail_terminal() const noexcept
+ {
+ return *m_rail_terminal;
+ }
void add_to_active_list(core_terminal_t &term) noexcept;
void remove_from_active_list(core_terminal_t &term) noexcept;
- // -----------------------------------------------------------------------------
+ // -----------------------------------------------------------------
// setup stuff - cold
- // -----------------------------------------------------------------------------
+ // -----------------------------------------------------------------
bool is_logic() const noexcept;
bool is_analog() const noexcept;
- void rebuild_list(); // rebuild m_list after a load
+ void rebuild_list() noexcept(false); // rebuild m_list after a load
void update_inputs() noexcept
{
@@ -107,26 +119,36 @@ namespace netlist
}
}
- // -----------------------------------------------------------------------------
+ // -----------------------------------------------------------------
// net management
- // -----------------------------------------------------------------------------
+ // -----------------------------------------------------------------
- const std::vector<detail::core_terminal_t *> core_terms_copy()
+ std::vector<detail::core_terminal_t *>
+ core_terms_copy() noexcept(false)
{
- std::vector<detail::core_terminal_t *> ret(core_terms_ref().size());
- std::copy(core_terms_ref().begin(), core_terms_ref().end(), ret.begin());
+ std::vector<detail::core_terminal_t *> ret(
+ core_terms_ref().size());
+ std::copy(core_terms_ref().begin(), core_terms_ref().end(),
+ ret.begin());
return ret;
}
- void remove_terminal(detail::core_terminal_t &term);
- void remove_all_terminals();
- void add_terminal(detail::core_terminal_t &terminal);
+ void remove_terminal(detail::core_terminal_t &term) noexcept(false);
+ void remove_all_terminals() noexcept(false);
+ void add_terminal(detail::core_terminal_t &terminal) noexcept(
+ false);
- bool core_terms_empty() noexcept { return core_terms_ref().empty(); }
- protected:
+ bool core_terms_empty() noexcept(false)
+ {
+ return core_terms_ref().empty();
+ }
+ protected:
// only used for logic nets
- constexpr const netlist_sig_t &Q() const noexcept { return m_cur_Q; }
+ constexpr const netlist_sig_t &Q() const noexcept
+ {
+ return m_cur_Q;
+ }
// only used for logic nets
void initial(netlist_sig_t val) noexcept
@@ -136,15 +158,17 @@ namespace netlist
}
// only used for logic nets
- void set_Q_and_push(netlist_sig_t newQ, const netlist_time &delay) noexcept;
+ void set_Q_and_push(netlist_sig_t newQ,
+ const netlist_time & delay) noexcept;
// only used for logic nets
- void set_Q_time(netlist_sig_t newQ, const netlist_time_ext &at) noexcept;
-
+ void set_Q_time(netlist_sig_t newQ,
+ const netlist_time_ext & at) noexcept;
private:
#if NL_USE_INPLACE_CORE_TERMS
- const plib::linked_list_t<core_terminal_t, 1> &core_terms_ref() const noexcept
+ const plib::linked_list_t<core_terminal_t, 1> &
+ core_terms_ref() const noexcept
{
return m_core_terms;
}
@@ -154,14 +178,14 @@ namespace netlist
return state().core_terms(*this);
}
#endif
- state_var<netlist_sig_t> m_new_Q;
- state_var<netlist_sig_t> m_cur_Q;
- state_var<queue_status> m_in_queue;
+ state_var<netlist_sig_t> m_new_Q;
+ state_var<netlist_sig_t> m_cur_Q;
+ state_var<queue_status> m_in_queue;
// FIXME: this needs to be saved as well
plib::linked_list_t<core_terminal_t, 0> m_list_active;
- state_var<netlist_time_ext> m_next_scheduled_time;
+ state_var<netlist_time_ext> m_next_scheduled_time;
- core_terminal_t * m_rail_terminal;
+ core_terminal_t *m_rail_terminal;
#if NL_USE_INPLACE_CORE_TERMS
plib::linked_list_t<core_terminal_t, 1> m_core_terms;
#endif
@@ -174,10 +198,15 @@ namespace netlist
m_next_scheduled_time = exec().time() + delay;
if constexpr (config::avoid_noop_queue_pushes::value)
- m_in_queue = (m_list_active.empty() ? queue_status::DELAYED_DUE_TO_INACTIVE
- : (m_new_Q != m_cur_Q ? queue_status::QUEUED : queue_status::DELIVERED));
+ m_in_queue = (m_list_active.empty()
+ ? queue_status::DELAYED_DUE_TO_INACTIVE
+ : (m_new_Q != m_cur_Q
+ ? queue_status::QUEUED
+ : queue_status::DELIVERED));
else
- m_in_queue = m_list_active.empty() ? queue_status::DELAYED_DUE_TO_INACTIVE : queue_status::QUEUED;
+ m_in_queue = m_list_active.empty()
+ ? queue_status::DELAYED_DUE_TO_INACTIVE
+ : queue_status::QUEUED;
if (m_in_queue == queue_status::QUEUED)
exec().queue_push(m_next_scheduled_time, this);
@@ -194,15 +223,16 @@ namespace netlist
const netlist_sig_t new_Q(m_new_Q);
const netlist_sig_t cur_Q(m_cur_Q);
- if (config::avoid_noop_queue_pushes::value || ((new_Q ^ cur_Q) != 0))
+ if (config::avoid_noop_queue_pushes::value
+ || ((new_Q ^ cur_Q) != 0))
{
m_cur_Q = new_Q;
const auto mask = (new_Q << core_terminal_t::INP_LH_SHIFT)
- | (cur_Q << core_terminal_t::INP_HL_SHIFT);
+ | (cur_Q << core_terminal_t::INP_HL_SHIFT);
if (!KEEP_STATS)
{
- for (core_terminal_t * p: m_list_active)
+ for (core_terminal_t *p : m_list_active)
{
p->set_copied_input(new_Q);
if ((p->terminal_state() & mask) != 0)
@@ -211,7 +241,7 @@ namespace netlist
}
else
{
- for (core_terminal_t * p : m_list_active)
+ for (core_terminal_t *p : m_list_active)
{
p->set_copied_input(new_Q);
auto *stats(p->device().stats());
@@ -239,11 +269,13 @@ namespace netlist
rail_terminal().device().do_inc_active();
if (m_in_queue == queue_status::DELAYED_DUE_TO_INACTIVE)
{
- // if we avoid queue pushes we must test if m_cur_Q and m_new_Q are equal
- if ((!config::avoid_noop_queue_pushes::value || (m_cur_Q != m_new_Q))
+ // if we avoid queue pushes we must test if m_cur_Q and
+ // m_new_Q are equal
+ if ((!config::avoid_noop_queue_pushes::value
+ || (m_cur_Q != m_new_Q))
&& (m_next_scheduled_time > exec().time()))
{
- m_in_queue = queue_status::QUEUED; // pending
+ m_in_queue = queue_status::QUEUED; // pending
exec().queue_push(m_next_scheduled_time, this);
}
else
@@ -258,7 +290,8 @@ namespace netlist
}
}
- inline void net_t::remove_from_active_list(core_terminal_t &term) noexcept
+ inline void net_t::remove_from_active_list(
+ core_terminal_t &term) noexcept
{
gsl_Expects(!m_list_active.empty());
m_list_active.remove(&term);
@@ -269,7 +302,8 @@ namespace netlist
// All our connected outputs have signalled they no longer
// will act on input. We thus remove any potentially queued
// events and mark them.
- // FIXME: May cause regression test to fail - revisit in this case
+ // FIXME: May cause regression test to fail - revisit in
+ // this case
//
// This code is definitively needed for the
// AVOID_NOOP_QUEUE_PUSHES code path - therefore I left
@@ -285,7 +319,8 @@ namespace netlist
}
// only used for logic nets
- inline void net_t::set_Q_and_push(netlist_sig_t newQ, const netlist_time &delay) noexcept
+ inline void net_t::set_Q_and_push(netlist_sig_t newQ,
+ const netlist_time & delay) noexcept
{
gsl_Expects(delay >= netlist_time::zero());
@@ -297,7 +332,8 @@ namespace netlist
}
// only used for logic nets
- inline void net_t::set_Q_time(netlist_sig_t newQ, const netlist_time_ext &at) noexcept
+ inline void net_t::set_Q_time(netlist_sig_t newQ,
+ const netlist_time_ext & at) noexcept
{
gsl_Expects(at >= netlist_time_ext::zero());
@@ -317,12 +353,11 @@ namespace netlist
} // namespace detail
-
class analog_net_t : public detail::net_t
{
public:
-
- analog_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *rail_terminal = nullptr);
+ analog_net_t(netlist_state_t &nl, const pstring &aname,
+ detail::core_terminal_t *rail_terminal = nullptr);
void reset() noexcept override;
@@ -331,11 +366,15 @@ namespace netlist
// used by solver code ...
nl_fptype *Q_Analog_state_ptr() noexcept { return *m_cur_Analog; }
- //FIXME: needed by current solver code
+ // FIXME: needed by current solver code
solver::matrix_solver_t *solver() const noexcept { return m_solver; }
- void set_solver(solver::matrix_solver_t *solver) noexcept { m_solver = solver; }
+ void set_solver(solver::matrix_solver_t *solver) noexcept
+ {
+ m_solver = solver;
+ }
- friend constexpr bool operator==(const analog_net_t &lhs, const analog_net_t &rhs) noexcept
+ friend constexpr bool operator==(const analog_net_t &lhs,
+ const analog_net_t & rhs) noexcept
{
return &lhs == &rhs;
}
@@ -348,17 +387,15 @@ namespace netlist
class logic_net_t : public detail::net_t
{
public:
+ logic_net_t(netlist_state_t &nl, const pstring &aname,
+ detail::core_terminal_t *rail_terminal = nullptr);
- logic_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *rail_terminal = nullptr);
-
- using detail::net_t::Q;
using detail::net_t::initial;
+ using detail::net_t::Q;
using detail::net_t::set_Q_and_push;
using detail::net_t::set_Q_time;
};
-
} // namespace netlist
-
#endif // NL_CORE_NETS_H_
diff --git a/src/lib/netlist/core/param.h b/src/lib/netlist/core/param.h
index 388ccebc1ba..34e6c3b1b1e 100644
--- a/src/lib/netlist/core/param.h
+++ b/src/lib/netlist/core/param.h
@@ -9,7 +9,6 @@
#define NL_CORE_PARAM_H_
#include "../nltypes.h"
-
#include "base_objects.h"
#include "core_device.h"
#include "setup.h"
@@ -30,16 +29,17 @@ namespace netlist
class param_t : public detail::device_object_t
{
public:
-
- enum param_type_t {
+ enum param_type_t
+ {
STRING,
DOUBLE,
INTEGER,
LOGIC,
- POINTER // Special-case which is always initialized at MAME startup time
+ POINTER // Special-case which is always initialized at MAME startup
+ // time
};
- //device-less, it's the responsibility of the owner to register!
+ // device-less, it's the responsibility of the owner to register!
param_t(const pstring &name);
param_t(core_device_t &device, const pstring &name);
@@ -52,7 +52,6 @@ namespace netlist
virtual pstring value_string() const = 0;
protected:
-
pstring get_initial(const core_device_t *dev, bool *found) const;
template <typename C>
@@ -64,7 +63,6 @@ namespace netlist
device().update_param();
}
}
-
};
// -----------------------------------------------------------------------------
@@ -72,17 +70,21 @@ namespace netlist
// -----------------------------------------------------------------------------
template <typename T>
- class param_num_t final: public param_t
+ class param_num_t final : public param_t
{
public:
using value_type = T;
- param_num_t(core_device_t &device, const pstring &name, T val) noexcept(false);
+ param_num_t(core_device_t &device, const pstring &name, T val) noexcept(
+ false);
constexpr const T &operator()() const noexcept { return m_param; }
- constexpr operator const T& () const noexcept { return m_param; }
+ constexpr operator const T &() const noexcept { return m_param; }
- void set(const T &param) noexcept { set_and_update_param(m_param, param); }
+ void set(const T &param) noexcept
+ {
+ set_and_update_param(m_param, param);
+ }
pstring value_string() const override
{
@@ -94,22 +96,27 @@ namespace netlist
};
template <typename T>
- class param_enum_t final: public param_t
+ class param_enum_t final : public param_t
{
public:
using value_type = T;
- param_enum_t(core_device_t &device, const pstring &name, T val) noexcept(false);
+ param_enum_t(core_device_t &device, const pstring &name,
+ T val) noexcept(false);
constexpr T operator()() const noexcept { return m_param; }
- constexpr operator T() const noexcept { return m_param; }
- void set(const T &param) noexcept { set_and_update_param(m_param, param); }
+ constexpr operator T() const noexcept { return m_param; }
+ void set(const T &param) noexcept
+ {
+ set_and_update_param(m_param, param);
+ }
pstring value_string() const override
{
// returns the numerical value
return plib::pfmt("{}")(static_cast<int>(m_param));
}
+
private:
T m_param;
};
@@ -119,21 +126,25 @@ namespace netlist
// -----------------------------------------------------------------------------
// FIXME: not a core component -> legacy
- class param_ptr_t final: public param_t
+ class param_ptr_t final : public param_t
{
public:
- param_ptr_t(core_device_t &device, const pstring &name, std::uint8_t* val);
- std::uint8_t * operator()() const noexcept { return m_param; }
- void set(std::uint8_t *param) noexcept { set_and_update_param(m_param, param); }
+ param_ptr_t(core_device_t &device, const pstring &name,
+ std::uint8_t *val);
+ std::uint8_t *operator()() const noexcept { return m_param; }
+ void set(std::uint8_t *param) noexcept
+ {
+ set_and_update_param(m_param, param);
+ }
pstring value_string() const override
{
// returns something which errors
- return { "PTRERROR" };
+ return {"PTRERROR"};
}
private:
- std::uint8_t* m_param;
+ std::uint8_t *m_param;
};
// -----------------------------------------------------------------------------
@@ -143,11 +154,16 @@ namespace netlist
class param_str_t : public param_t
{
public:
- param_str_t(core_device_t &device, const pstring &name, const pstring &val);
- param_str_t(netlist_state_t &state, const pstring &name, const pstring &val);
+ param_str_t(core_device_t &device, const pstring &name,
+ const pstring &val);
+ // FIXME: The device less constructor is only used by macro parameters
+ // Every macro device gets a nld_wrapper object as the owner.
+ // Use this as the owner and get rid of this constructor.
+ param_str_t(netlist_state_t &state, const pstring &name,
+ const pstring &val);
pstring operator()() const noexcept { return str(); }
- void set(const pstring &param)
+ void set(const pstring &param)
{
if (*m_param != param)
{
@@ -156,14 +172,12 @@ namespace netlist
device().update_param();
}
}
- pstring value_string() const override
- {
- return *m_param;
- }
+ pstring value_string() const override { return *m_param; }
protected:
virtual void changed() noexcept;
- pstring str() const noexcept { return *m_param; }
+ pstring str() const noexcept { return *m_param; }
+
private:
host_arena::unique_ptr<pstring> m_param;
};
@@ -175,23 +189,26 @@ namespace netlist
class param_model_t : public param_str_t
{
public:
-
template <typename T>
class value_base_t
{
public:
- template <typename P, typename Y=T, typename DUMMY = std::enable_if_t<plib::is_arithmetic<Y>::value>>
+ template <typename P, typename Y = T,
+ typename DUMMY = std::enable_if_t<
+ plib::is_arithmetic<Y>::value>>
value_base_t(P &param, const pstring &name)
: m_value(gsl::narrow<T>(param.value(name)))
{
}
- template <typename P, typename Y=T, std::enable_if_t<!plib::is_arithmetic<Y>::value, int> = 0>
+ template <typename P, typename Y = T,
+ std::enable_if_t<!plib::is_arithmetic<Y>::value, int> = 0>
value_base_t(P &param, const pstring &name)
: m_value(static_cast<T>(param.value_str(name)))
{
}
T operator()() const noexcept { return m_value; }
- operator T() const noexcept { return m_value; }
+ operator T() const noexcept { return m_value; }
+
private:
const T m_value;
};
@@ -199,18 +216,21 @@ namespace netlist
using value_t = value_base_t<nl_fptype>;
using value_str_t = value_base_t<pstring>;
- param_model_t(core_device_t &device, const pstring &name, const pstring &val)
+ param_model_t(core_device_t &device, const pstring &name,
+ const pstring &val)
: param_str_t(device, name, val)
{
}
- pstring value_str(const pstring &entity);
+ pstring value_str(const pstring &entity);
nl_fptype value(const pstring &entity);
- pstring type();
+ pstring type();
// hide this
void set(const pstring &param) = delete;
+
protected:
void changed() noexcept override;
+
private:
};
@@ -227,8 +247,9 @@ namespace netlist
}
plib::istream_uptr stream();
+
protected:
- void changed() noexcept override { }
+ void changed() noexcept override {}
};
// -----------------------------------------------------------------------------
@@ -236,17 +257,17 @@ namespace netlist
// -----------------------------------------------------------------------------
template <typename ST, std::size_t AW, std::size_t DW>
- class param_rom_t final: public param_data_t
+ class param_rom_t final : public param_data_t
{
public:
-
param_rom_t(core_device_t &device, const pstring &name);
- const ST & operator[] (std::size_t n) const noexcept { return m_data[n]; }
+ const ST &operator[](std::size_t n) const noexcept { return m_data[n]; }
+
protected:
void changed() noexcept override
{
- plib::istream_read(*stream(), m_data.data(), 1<<AW);
+ plib::istream_read(*stream(), m_data.data(), 1 << AW);
}
private:
@@ -254,11 +275,12 @@ namespace netlist
};
template <typename T>
- param_num_t<T>::param_num_t(core_device_t &device, const pstring &name, const T val)
+ param_num_t<T>::param_num_t(core_device_t &device, const pstring &name,
+ const T val)
: param_t(device, name)
, m_param(val)
{
- bool found = false;
+ bool found = false;
pstring p = this->get_initial(&device, &found);
if (found)
{
@@ -267,7 +289,8 @@ namespace netlist
auto valx = func.evaluate();
if (plib::is_integral<T>::value)
if (plib::abs(valx - plib::trunc(valx)) > nlconst::magic(1e-6))
- throw nl_exception(MF_INVALID_NUMBER_CONVERSION_1_2(device.name() + "." + name, p));
+ throw nl_exception(MF_INVALID_NUMBER_CONVERSION_1_2(
+ device.name() + "." + name, p));
m_param = plib::narrow_cast<T>(valx);
}
@@ -275,19 +298,21 @@ namespace netlist
}
template <typename T>
- param_enum_t<T>::param_enum_t(core_device_t &device, const pstring &name, const T val)
+ param_enum_t<T>::param_enum_t(core_device_t &device, const pstring &name,
+ const T val)
: param_t(device, name)
, m_param(val)
{
- bool found = false;
+ bool found = false;
pstring p = this->get_initial(&device, &found);
if (found)
{
- T temp(val);
+ T temp(val);
bool ok = temp.set_from_string(p);
if (!ok)
{
- device.state().log().fatal(MF_INVALID_ENUM_CONVERSION_1_2(name, p));
+ device.state().log().fatal(
+ MF_INVALID_ENUM_CONVERSION_1_2(name, p));
throw nl_exception(MF_INVALID_ENUM_CONVERSION_1_2(name, p));
}
m_param = temp;
@@ -297,13 +322,14 @@ namespace netlist
}
template <typename ST, std::size_t AW, std::size_t DW>
- param_rom_t<ST, AW, DW>::param_rom_t(core_device_t &device, const pstring &name)
+ param_rom_t<ST, AW, DW>::param_rom_t(core_device_t &device,
+ const pstring & name)
: param_data_t(device, name)
{
auto f = this->stream();
if (!f.empty())
{
- plib::istream_read(*f, m_data.data(), 1<<AW);
+ plib::istream_read(*f, m_data.data(), 1 << AW);
// FIXME: check for failbit if not in validation.
}
else
@@ -338,5 +364,4 @@ namespace netlist
} // namespace netlist
-
#endif // NL_CORE_PARAM_H_
diff --git a/src/lib/netlist/core/queue.h b/src/lib/netlist/core/queue.h
index 19600f0198c..9fdd6ac1c64 100644
--- a/src/lib/netlist/core/queue.h
+++ b/src/lib/netlist/core/queue.h
@@ -8,10 +8,9 @@
#ifndef NL_CORE_QUEUE_H_
#define NL_CORE_QUEUE_H_
-#include "queue.h"
-
#include "../nl_errstr.h"
#include "../nltypes.h"
+#include "queue.h"
#include "../plib/pstate.h"
#include "../plib/pstring.h"
@@ -33,17 +32,18 @@ namespace netlist::detail
// solvers will update inputs after parallel processing.
template <typename A, typename O>
- class queue_base :
- public config::timed_queue<A, plib::queue_entry_t<netlist_time_ext, O *>>,
- public plib::state_manager_t::callback_t
+ class queue_base
+ : public config::timed_queue<A, plib::queue_entry_t<netlist_time_ext, O *>>
+ , public plib::state_manager_t::callback_t
{
public:
using entry_t = plib::queue_entry_t<netlist_time_ext, O *>;
using base_queue = config::timed_queue<A, entry_t>;
- using id_delegate = plib::pmfp<std::size_t (const O *)>;
- using obj_delegate = plib::pmfp<O * (std::size_t)>;
+ using id_delegate = plib::pmfp<std::size_t(const O *)>;
+ using obj_delegate = plib::pmfp<O *(std::size_t)>;
- explicit queue_base(A &arena, std::size_t size, id_delegate get_id, obj_delegate get_obj)
+ explicit queue_base(A &arena, std::size_t size, id_delegate get_id,
+ obj_delegate get_obj)
: base_queue(arena, size)
, m_size(0)
, m_times(size)
@@ -61,43 +61,47 @@ namespace netlist::detail
queue_base &operator=(queue_base &&) = delete;
protected:
-
- void register_state(plib::state_manager_t &manager, const pstring &module) override
+ void register_state(plib::state_manager_t &manager,
+ const pstring & module) override
{
manager.save_item(this, m_size, module + "." + "size");
- manager.save_item(this, &m_times[0], module + "." + "times", m_times.size());
- manager.save_item(this, &m_net_ids[0], module + "." + "names", m_net_ids.size());
+ manager.save_item(this, &m_times[0], module + "." + "times",
+ m_times.size());
+ manager.save_item(this, &m_net_ids[0], module + "." + "names",
+ m_net_ids.size());
}
- void on_pre_save([[maybe_unused]] plib::state_manager_t &manager) override
+ void on_pre_save(
+ [[maybe_unused]] plib::state_manager_t &manager) override
{
m_size = this->size();
- for (std::size_t i = 0; i < m_size; i++ )
+ for (std::size_t i = 0; i < m_size; i++)
{
- m_times[i] = this->list_pointer()[i].exec_time().as_raw();
+ m_times[i] = this->list_pointer()[i].exec_time().as_raw();
m_net_ids[i] = m_get_id(this->list_pointer()[i].object());
}
}
- void on_post_load([[maybe_unused]] plib::state_manager_t &manager) override
+ void on_post_load(
+ [[maybe_unused]] plib::state_manager_t &manager) override
{
this->clear();
- for (std::size_t i = 0; i < m_size; i++ )
+ for (std::size_t i = 0; i < m_size; i++)
{
O *n = m_obj_by_id(m_net_ids[i]);
- this->template push<false>(entry_t(netlist_time_ext::from_raw(m_times[i]),n));
+ this->template push<false>(
+ entry_t(netlist_time_ext::from_raw(m_times[i]), n));
}
}
private:
- std::size_t m_size;
+ std::size_t m_size;
std::vector<netlist_time_ext::internal_type> m_times;
- std::vector<std::size_t> m_net_ids;
- id_delegate m_get_id;
- obj_delegate m_obj_by_id;
+ std::vector<std::size_t> m_net_ids;
+ id_delegate m_get_id;
+ obj_delegate m_obj_by_id;
};
using queue_t = queue_base<device_arena, net_t>;
} // namespace netlist::detail
-
#endif // NL_CORE_QUEUE_H_
diff --git a/src/lib/netlist/core/setup.h b/src/lib/netlist/core/setup.h
index ddf1aa14889..63210a96a06 100644
--- a/src/lib/netlist/core/setup.h
+++ b/src/lib/netlist/core/setup.h
@@ -179,11 +179,11 @@ namespace netlist
models_t &models() noexcept { return m_models; }
const models_t &models() const noexcept { return m_models; }
- netlist_state_t &nlstate() { return m_nlstate; }
- const netlist_state_t &nlstate() const { return m_nlstate; }
+ netlist_state_t &nlstate() noexcept { return m_nlstate; }
+ const netlist_state_t &nlstate() const noexcept { return m_nlstate; }
- nlparse_t &parser() { return m_parser; }
- const nlparse_t &parser() const { return m_parser; }
+ nlparse_t &parser() noexcept { return m_parser; }
+ const nlparse_t &parser() const noexcept { return m_parser; }
log_type &log() noexcept;
const log_type &log() const noexcept;
@@ -196,10 +196,10 @@ namespace netlist
void merge_nets(detail::net_t &this_net, detail::net_t &other_net);
void connect_terminals(detail::core_terminal_t &t1, detail::core_terminal_t &t2);
- void connect_input_output(detail::core_terminal_t &in, detail::core_terminal_t &out);
- void connect_terminal_output(terminal_t &in, detail::core_terminal_t &out);
- void connect_terminal_input(terminal_t &term, detail::core_terminal_t &inp);
- bool connect_input_input(detail::core_terminal_t &t1, detail::core_terminal_t &t2);
+ void connect_input_output(detail::core_terminal_t &input, detail::core_terminal_t &output);
+ void connect_terminal_output(detail::core_terminal_t &terminal, detail::core_terminal_t &output);
+ void connect_terminal_input(detail::core_terminal_t &terminal, detail::core_terminal_t &input);
+ bool connect_input_input(detail::core_terminal_t &input1, detail::core_terminal_t &input2);
bool connect(detail::core_terminal_t &t1, detail::core_terminal_t &t2);
diff --git a/src/lib/netlist/core/state_var.h b/src/lib/netlist/core/state_var.h
index 88f9a072a1f..7c6e7aec8be 100644
--- a/src/lib/netlist/core/state_var.h
+++ b/src/lib/netlist/core/state_var.h
@@ -9,6 +9,7 @@
#define NL_CORE_STATE_VAR_H_
#include "../nltypes.h"
+
#include "../plib/pstring.h"
namespace netlist
@@ -31,20 +32,19 @@ namespace netlist
struct state_var
{
public:
-
using value_type = T;
template <typename O>
//! Constructor.
- state_var(O &owner, //!< owner must have a netlist() method.
- const pstring &name, //!< identifier/name for this state variable
- const T &value //!< Initial value after construction
- );
+ state_var(O & owner, //!< owner must have a netlist() method.
+ const pstring &name, //!< identifier/name for this state variable
+ const T & value //!< Initial value after construction
+ );
template <typename O>
//! Constructor.
- state_var(O &owner, //!< owner must have a netlist() method.
- const pstring &name //!< identifier/name for this state variable
+ state_var(O & owner, //!< owner must have a netlist() method.
+ const pstring &name //!< identifier/name for this state variable
);
state_var(state_var &&) noexcept = delete;
@@ -63,38 +63,47 @@ namespace netlist
return *this;
} // OSX doesn't like noexcept
//! Assignment operator to assign value of type T.
- constexpr state_var &operator=(const T &rhs) noexcept { m_value = rhs; return *this; }
+ constexpr state_var &operator=(const T &rhs) noexcept
+ {
+ m_value = rhs;
+ return *this;
+ }
//! Assignment move operator to assign value of type T.
- //constexpr state_var &operator=(T &&rhs) noexcept { std::swap(m_value, rhs); return *this; }
- constexpr state_var &operator=(T &&rhs) noexcept { m_value = std::move(rhs); return *this; }
+ // constexpr state_var &operator=(T &&rhs) noexcept { std::swap(m_value,
+ // rhs); return *this; }
+ constexpr state_var &operator=(T &&rhs) noexcept
+ {
+ m_value = std::move(rhs);
+ return *this;
+ }
//! Return non-const value of state variable.
- constexpr operator T & () noexcept { return m_value; }
+ constexpr operator T &() noexcept { return m_value; }
//! Return const value of state variable.
- constexpr operator const T & () const noexcept { return m_value; }
+ constexpr operator const T &() const noexcept { return m_value; }
//! Return non-const value of state variable.
- constexpr T & var() noexcept { return m_value; }
+ constexpr T &var() noexcept { return m_value; }
//! Return const value of state variable.
- constexpr const T & var() const noexcept { return m_value; }
+ constexpr const T &var() const noexcept { return m_value; }
//! Return non-const value of state variable.
- constexpr T & operator ()() noexcept { return m_value; }
+ constexpr T &operator()() noexcept { return m_value; }
//! Return const value of state variable.
- constexpr const T & operator ()() const noexcept { return m_value; }
+ constexpr const T &operator()() const noexcept { return m_value; }
//! Access state variable by ->.
- constexpr T * operator->() noexcept { return &m_value; }
+ constexpr T *operator->() noexcept { return &m_value; }
//! Access state variable by const ->.
- constexpr const T * operator->() const noexcept{ return &m_value; }
+ constexpr const T *operator->() const noexcept { return &m_value; }
//! Access state variable by *.
- constexpr T * operator *() noexcept { return &m_value; }
+ constexpr T *operator*() noexcept { return &m_value; }
//! Access state variable by const *.
- constexpr const T * operator *() const noexcept{ return &m_value; }
+ constexpr const T *operator*() const noexcept { return &m_value; }
private:
T m_value;
};
/// \brief A persistent array template.
- /// Use this state_var template to define an array whose contents are saved.
- /// Please refer to \ref state_var.
+ /// Use this state_var template to define an array whose contents are
+ /// saved. Please refer to \ref state_var.
///
/// \tparam C container class to use.
@@ -105,24 +114,25 @@ namespace netlist
using value_type = typename C::value_type;
//! Constructor.
template <typename O>
- state_container(O &owner, //!< owner must have a netlist() method.
- const pstring &name, //!< identifier/name for this state variable
- const value_type &value //!< Initial value after construction
- );
+ state_container(O & owner, //!< owner must have a netlist() method.
+ const pstring & name, //!< identifier/name for this state variable
+ const value_type &value //!< Initial value after construction
+ );
//! Constructor.
template <typename O>
- state_container(O &owner, //!< owner must have a netlist() method.
- const pstring &name, //!< identifier/name for this state variable
- std::size_t n, //!< number of elements to allocate
- const value_type &value //!< Initial value after construction
- );
+ state_container(O & owner, //!< owner must have a netlist() method.
+ const pstring & name, //!< identifier/name for this state variable
+ std::size_t n, //!< number of elements to allocate
+ const value_type &value //!< Initial value after construction
+ );
//! Copy Constructor.
state_container(const state_container &rhs) noexcept = default;
//! Destructor.
~state_container() noexcept = default;
//! Move Constructor.
state_container(state_container &&rhs) noexcept = default;
- state_container &operator=(const state_container &rhs) noexcept = default;
+ state_container &operator=(
+ const state_container &rhs) noexcept = default;
state_container &operator=(state_container &&rhs) noexcept = default;
};
@@ -160,17 +170,17 @@ namespace netlist
template <typename C>
template <typename O>
state_container<C>::state_container(O &owner, const pstring &name,
- const state_container<C>::value_type & value)
+ const state_container<C>::value_type &value)
{
owner.state().save(owner, static_cast<C &>(*this), owner.name(), name);
- for (std::size_t i=0; i < this->size(); i++)
+ for (std::size_t i = 0; i < this->size(); i++)
(*this)[i] = value;
}
template <typename C>
template <typename O>
state_container<C>::state_container(O &owner, const pstring &name,
- std::size_t n, const state_container<C>::value_type & value)
+ std::size_t n, const state_container<C>::value_type &value)
: C(n, value)
{
owner.state().save(owner, static_cast<C &>(*this), owner.name(), name);
@@ -190,7 +200,6 @@ namespace netlist
extern template struct state_var<std::int64_t>;
extern template struct state_var<bool>;
-
} // namespace netlist
namespace plib
diff --git a/src/lib/netlist/devices/nld_4020.cpp b/src/lib/netlist/devices/nld_4020.cpp
index 9d08b4a8220..626a22f7d05 100644
--- a/src/lib/netlist/devices/nld_4020.cpp
+++ b/src/lib/netlist/devices/nld_4020.cpp
@@ -108,63 +108,11 @@ namespace netlist::devices {
nld_power_pins m_supply;
};
- NETLIB_OBJECT(CD4020)
- {
- NETLIB_CONSTRUCTOR_MODEL(CD4020, "CD4XXX")
- , m_sub(*this, "A")
- {
- register_sub_alias("IP", "A.IP");
- register_sub_alias("RESET", "A.RESET");
- register_sub_alias("Q1", "A.Q1");
- register_sub_alias("Q4", "A.Q4");
- register_sub_alias("Q5", "A.Q5");
- register_sub_alias("Q6", "A.Q6");
- register_sub_alias("Q7", "A.Q7");
- register_sub_alias("Q8", "A.Q8");
- register_sub_alias("Q9", "A.Q9");
- register_sub_alias("Q10", "A.Q10");
- register_sub_alias("Q11", "A.Q11");
- register_sub_alias("Q12", "A.Q12");
- register_sub_alias("Q13", "A.Q13");
- register_sub_alias("Q14", "A.Q14");
- register_sub_alias("VDD", "A.VDD");
- register_sub_alias("VSS", "A.VSS");
- }
-
- //NETLIB_RESETI() {}
-
- private:
- NETLIB_SUB(CD4020_sub)<14, 0x3ff9> m_sub;
- };
-
- NETLIB_OBJECT(CD4024)
- {
- NETLIB_CONSTRUCTOR_MODEL(CD4024, "CD4XXX")
- , m_sub(*this, "A")
- {
- register_sub_alias("IP", "A.IP");
- register_sub_alias("RESET", "A.RESET");
- register_sub_alias("Q1", "A.Q1");
- register_sub_alias("Q2", "A.Q2");
- register_sub_alias("Q3", "A.Q3");
- register_sub_alias("Q4", "A.Q4");
- register_sub_alias("Q5", "A.Q5");
- register_sub_alias("Q6", "A.Q6");
- register_sub_alias("Q7", "A.Q7");
- register_sub_alias("VDD", "A.VDD");
- register_sub_alias("VSS", "A.VSS");
- }
-
- //NETLIB_RESETI() {}
-
- private:
- NETLIB_SUB(CD4020_sub)<7, 0x7f> m_sub;
- };
-
-
-
- NETLIB_DEVICE_IMPL(CD4020, "CD4020", "+IP,+RESET,+VDD,+VSS")
+ // FIXME: Exposes Q2 and Q3 as well
+ using NETLIB_NAME(CD4020_impl) = nld_CD4020_sub<14, 0x3ff9>;
+ NETLIB_DEVICE_IMPL_ALIAS(CD4020, CD4020_impl,"CD4020", "+IP,+RESET,+VDD,+VSS")
- NETLIB_DEVICE_IMPL(CD4024, "CD4024", "")
+ using NETLIB_NAME(CD4024_impl) = nld_CD4020_sub<7, 0x7f>;
+ NETLIB_DEVICE_IMPL_ALIAS(CD4024, CD4024_impl, "CD4024", "")
} // namespace netlist::devices
diff --git a/src/lib/netlist/devices/nld_4053.cpp b/src/lib/netlist/devices/nld_4053.cpp
index c996ed0c2a5..a199fedf7fc 100644
--- a/src/lib/netlist/devices/nld_4053.cpp
+++ b/src/lib/netlist/devices/nld_4053.cpp
@@ -101,40 +101,40 @@ namespace netlist::devices {
const nl_fptype Roff = plib::reciprocal(exec().gmin());
const nl_fptype RX = newx ? Ron : Roff;
const nl_fptype RY = newy ? Ron : Roff;
- if (m_RX.solver() == m_RY.solver())
+ if (m_RX().solver() == m_RY().solver())
{
- m_RX.change_state([this, &RX, &RY]()
+ m_RX().change_state([this, &RX, &RY]()
{
- m_RX.set_R(RX);
- m_RY.set_R(RY);
+ m_RX().set_R(RX);
+ m_RY().set_R(RY);
});
}
else
{
- m_RX.change_state([this, &RX]()
+ m_RX().change_state([this, &RX]()
{
- m_RX.set_R(RX);
+ m_RX().set_R(RX);
});
- m_RY.change_state([this, &RY]()
+ m_RY().change_state([this, &RY]()
{
- m_RY.set_R(RY);
+ m_RY().set_R(RY);
});
}
m_last_x = newx;
m_last_y = newy;
}
- analog::NETLIB_SUB(R_base) m_RX;
- analog::NETLIB_SUB(R_base) m_RY;
- analog_input_t m_select;
- analog_input_t m_inhibit;
- analog_input_t m_VEE;
- param_fp_t m_base_r;
- state_var<bool> m_last_x;
- state_var<bool> m_last_y;
- state_var<bool> m_select_state;
- state_var<bool> m_inhibit_state;
- nld_power_pins m_supply;
+ NETLIB_SUB_NS(analog, R_base) m_RX;
+ NETLIB_SUB_NS(analog, R_base) m_RY;
+ analog_input_t m_select;
+ analog_input_t m_inhibit;
+ analog_input_t m_VEE;
+ param_fp_t m_base_r;
+ state_var<bool> m_last_x;
+ state_var<bool> m_last_y;
+ state_var<bool> m_select_state;
+ state_var<bool> m_inhibit_state;
+ nld_power_pins m_supply;
};
NETLIB_DEVICE_IMPL(CD4053_GATE, "CD4053_GATE", "")
diff --git a/src/lib/netlist/devices/nld_4066.cpp b/src/lib/netlist/devices/nld_4066.cpp
index b003dd13178..bd2a0a13196 100644
--- a/src/lib/netlist/devices/nld_4066.cpp
+++ b/src/lib/netlist/devices/nld_4066.cpp
@@ -42,7 +42,7 @@ namespace netlist::devices {
{
// Start in off condition
// FIXME: is ROFF correct?
- m_R.set_R(plib::reciprocal(exec().gmin()));
+ m_R().set_R(plib::reciprocal(exec().gmin()));
}
private:
@@ -67,11 +67,11 @@ namespace netlist::devices {
if (R > nlconst::zero() && (m_last != new_state))
{
m_last = new_state;
- m_R.change_state([this, &R]() -> void { this->m_R.set_R(R);});
+ m_R().change_state([this, &R]() -> void { this->m_R().set_R(R);});
}
}
- analog::NETLIB_SUB(R_base) m_R;
+ NETLIB_SUB_NS(analog, R_base) m_R;
analog_input_t m_control;
param_fp_t m_base_r;
state_var<bool> m_last;
diff --git a/src/lib/netlist/devices/nld_4316.cpp b/src/lib/netlist/devices/nld_4316.cpp
index 81ac77d4468..c875a4e5840 100644
--- a/src/lib/netlist/devices/nld_4316.cpp
+++ b/src/lib/netlist/devices/nld_4316.cpp
@@ -42,27 +42,27 @@ namespace netlist::devices {
NETLIB_RESETI()
{
- m_R.set_R(plib::reciprocal(exec().gmin()));
+ m_R().set_R(plib::reciprocal(exec().gmin()));
}
NETLIB_HANDLERI(inputs)
{
- m_R.change_state([this]()
+ m_R().change_state([this]()
{
if (m_S() && !m_E())
- m_R.set_R(m_base_r());
+ m_R().set_R(m_base_r());
else
- m_R.set_R(plib::reciprocal(exec().gmin()));
+ m_R().set_R(plib::reciprocal(exec().gmin()));
});
}
private:
- analog::NETLIB_SUB(R_base) m_R;
+ NETLIB_SUB_NS(analog, R_base) m_R;
- logic_input_t m_S;
- logic_input_t m_E;
- param_fp_t m_base_r;
- nld_power_pins m_supply;
+ logic_input_t m_S;
+ logic_input_t m_E;
+ param_fp_t m_base_r;
+ nld_power_pins m_supply;
};
NETLIB_DEVICE_IMPL(CD4316_GATE, "CD4316_GATE", "")
diff --git a/src/lib/netlist/devices/nld_74113.cpp b/src/lib/netlist/devices/nld_74113.cpp
index ea2c6d7794a..32f96d87c12 100644
--- a/src/lib/netlist/devices/nld_74113.cpp
+++ b/src/lib/netlist/devices/nld_74113.cpp
@@ -134,11 +134,7 @@ namespace netlist::devices {
nld_power_pins m_power_pins;
};
- NETLIB_OBJECT_DERIVED(74113A, 74113)
- {
- NETLIB_CONSTRUCTOR(74113A) { }
-
- };
+ using NETLIB_NAME(74113A) = NETLIB_NAME(74113);
NETLIB_DEVICE_IMPL(74113, "TTL_74113", "+CLK,+J,+K,+CLRQ,@VCC,@GND")
NETLIB_DEVICE_IMPL(74113A, "TTL_74113A", "+CLK,+J,+K,+CLRQ,@VCC,@GND")
diff --git a/src/lib/netlist/devices/nld_74123.cpp b/src/lib/netlist/devices/nld_74123.cpp
index 81a5d3f9e0d..fc0beef9972 100644
--- a/src/lib/netlist/devices/nld_74123.cpp
+++ b/src/lib/netlist/devices/nld_74123.cpp
@@ -128,8 +128,8 @@ namespace netlist::devices {
connect("RN.1", "RP.2");
connect("_CV", "RN.1");
- m_RP.m_RON.set(D::RI());
- m_RN.m_RON.set(D::RI());
+ m_RP().m_RON.set(D::RI());
+ m_RN().m_RON.set(D::RI());
}
NETLIB_HANDLERI(ab_clear)
@@ -169,7 +169,7 @@ namespace netlist::devices {
{
if (m_state == 1)
{
- const nl_fptype vLow = m_KP * m_RP.P()();
+ const nl_fptype vLow = m_KP * m_RP().P()();
if (m_CV() < vLow)
{
m_RN_Q.push(0, NLTIME_FROM_NS(10)); // R_OFF
@@ -178,7 +178,7 @@ namespace netlist::devices {
}
if (m_state == 2)
{
- const nl_fptype vHigh = (nlconst::one() - m_KP) * m_RP.P()();
+ const nl_fptype vHigh = (nlconst::one() - m_KP) * m_RP().P()();
if (m_CV() > vHigh)
{
m_RP_Q.push(0, NLTIME_FROM_NS(10)); // R_OFF
@@ -192,8 +192,8 @@ namespace netlist::devices {
NETLIB_RESETI()
{
- m_RP.reset();
- m_RN.reset();
+ m_RP().reset();
+ m_RN().reset();
//m_RP.set_R(R_OFF);
//m_RN.set_R(R_OFF);
diff --git a/src/lib/netlist/devices/nld_74174.cpp b/src/lib/netlist/devices/nld_74174.cpp
index ed45783f31e..2789eef0bb5 100644
--- a/src/lib/netlist/devices/nld_74174.cpp
+++ b/src/lib/netlist/devices/nld_74174.cpp
@@ -37,15 +37,15 @@
namespace netlist::devices {
- NETLIB_OBJECT(74174_GATE)
+ NETLIB_OBJECT(74174)
{
- NETLIB_CONSTRUCTOR(74174_GATE)
+ NETLIB_CONSTRUCTOR(74174)
, m_CLK(*this, "CLK", NETLIB_DELEGATE(clk))
- , m_Q(*this, "Q")
+ , m_Q(*this, 1, "Q{}")
, m_clrq(*this, "m_clr", 0)
, m_data(*this, "m_data", 0)
- , m_D(*this, "D", NETLIB_DELEGATE(other))
- , m_CLRQ(*this, "CLRQ", NETLIB_DELEGATE(other))
+ , m_D(*this, 1, "D{}", NETLIB_DELEGATE(other))
+ , m_CLRQ(*this, "CLRQ", NETLIB_DELEGATE(clrq))
, m_power_pins(*this)
{
}
@@ -57,22 +57,27 @@ namespace netlist::devices {
m_data = 0xFF;
}
- NETLIB_HANDLERI(other)
+ private:
+ NETLIB_HANDLERI(clrq)
{
- netlist_sig_t d = m_D();
m_clrq = m_CLRQ();
if (!m_clrq)
{
- m_Q.push(0, NLTIME_FROM_NS(40));
m_data = 0;
- } else if (d != m_data)
- {
- m_data = d;
- m_CLK.activate_lh();
+ m_Q.push(m_data, NLTIME_FROM_NS(40));
+ m_CLK.inactivate();
}
+ else
+ m_CLK.activate_lh();
+ }
+
+ NETLIB_HANDLERI(other)
+ {
+ m_data = m_D();
+ if (m_clrq)
+ m_CLK.activate_lh();
}
- private:
NETLIB_HANDLERI(clk)
{
if (m_clrq)
@@ -83,82 +88,16 @@ namespace netlist::devices {
}
logic_input_t m_CLK;
- logic_output_t m_Q;
+ object_array_t<logic_output_t, 6> m_Q;
state_var<netlist_sig_t> m_clrq;
state_var<netlist_sig_t> m_data;
- logic_input_t m_D;
+ object_array_t<logic_input_t, 6> m_D;
logic_input_t m_CLRQ;
nld_power_pins m_power_pins;
};
- NETLIB_OBJECT(74174)
- {
- NETLIB_CONSTRUCTOR(74174)
- , A(*this, "A")
- , B(*this, "B")
- , C(*this, "C")
- , D(*this, "D")
- , E(*this, "E")
- , F(*this, "F")
- {
- register_sub_alias("CLRQ", "A.CLRQ");
- connect("A.CLRQ", "B.CLRQ");
- connect("A.CLRQ", "C.CLRQ");
- connect("A.CLRQ", "D.CLRQ");
- connect("A.CLRQ", "E.CLRQ");
- connect("A.CLRQ", "F.CLRQ");
-
- register_sub_alias("CLK", "A.CLK");
- connect("A.CLK", "B.CLK");
- connect("A.CLK", "C.CLK");
- connect("A.CLK", "D.CLK");
- connect("A.CLK", "E.CLK");
- connect("A.CLK", "F.CLK");
-
- register_sub_alias("D1", "A.D");
- register_sub_alias("Q1", "A.Q");
-
- register_sub_alias("D2", "B.D");
- register_sub_alias("Q2", "B.Q");
-
- register_sub_alias("D3", "C.D");
- register_sub_alias("Q3", "C.Q");
-
- register_sub_alias("D4", "D.D");
- register_sub_alias("Q4", "D.Q");
-
- register_sub_alias("D5", "E.D");
- register_sub_alias("Q5", "E.Q");
-
- register_sub_alias("D6", "F.D");
- register_sub_alias("Q6", "F.Q");
-
- register_sub_alias("GND", "A.GND");
- connect("A.GND", "B.GND");
- connect("A.GND", "C.GND");
- connect("A.GND", "D.GND");
- connect("A.GND", "E.GND");
- connect("A.GND", "F.GND");
-
- register_sub_alias("VCC", "A.VCC");
- connect("A.VCC", "B.VCC");
- connect("A.VCC", "C.VCC");
- connect("A.VCC", "D.VCC");
- connect("A.VCC", "E.VCC");
- connect("A.VCC", "F.VCC");
- }
- //NETLIB_RESETI() {}
- private:
- NETLIB_SUB(74174_GATE) A;
- NETLIB_SUB(74174_GATE) B;
- NETLIB_SUB(74174_GATE) C;
- NETLIB_SUB(74174_GATE) D;
- NETLIB_SUB(74174_GATE) E;
- NETLIB_SUB(74174_GATE) F;
- };
-
NETLIB_DEVICE_IMPL(74174, "TTL_74174", "+CLK,+D1,+D2,+D3,+D4,+D5,+D6,+CLRQ,@VCC,@GND")
} // namespace netlist::devices
diff --git a/src/lib/netlist/devices/nld_7473.cpp b/src/lib/netlist/devices/nld_7473.cpp
index 5336bfa85dd..d5b859859a4 100644
--- a/src/lib/netlist/devices/nld_7473.cpp
+++ b/src/lib/netlist/devices/nld_7473.cpp
@@ -127,10 +127,7 @@ namespace netlist::devices {
nld_power_pins m_power_pins;
};
- NETLIB_OBJECT_DERIVED(7473A, 7473)
- {
- NETLIB_CONSTRUCTOR(7473A) { }
- };
+ using NETLIB_NAME(7473A) = NETLIB_NAME(7473);
NETLIB_DEVICE_IMPL(7473, "TTL_7473", "+CLK,+J,+K,+CLRQ,@VCC,@GND")
NETLIB_DEVICE_IMPL(7473A, "TTL_7473A", "+CLK,+J,+K,+CLRQ,@VCC,@GND")
diff --git a/src/lib/netlist/devices/nld_74ls629.cpp b/src/lib/netlist/devices/nld_74ls629.cpp
index a09d99995a7..11cbc8aeb0d 100644
--- a/src/lib/netlist/devices/nld_74ls629.cpp
+++ b/src/lib/netlist/devices/nld_74ls629.cpp
@@ -121,8 +121,8 @@ namespace netlist::devices {
private:
NETLIB_RESETI()
{
- m_R_FC.set_R( nlconst::magic(90000.0));
- m_R_RNG.set_R(nlconst::magic(90000.0));
+ m_R_FC().set_R( nlconst::magic(90000.0));
+ m_R_RNG().set_R(nlconst::magic(90000.0));
}
NETLIB_UPDATE_PARAMI()
@@ -131,8 +131,8 @@ namespace netlist::devices {
}
SN74LS629clk m_clock;
- analog::NETLIB_SUB(R_base) m_R_FC;
- analog::NETLIB_SUB(R_base) m_R_RNG;
+ NETLIB_SUB_NS(analog, R_base) m_R_FC;
+ NETLIB_SUB_NS(analog, R_base) m_R_RNG;
logic_input_t m_ENQ;
analog_input_t m_RNG;
diff --git a/src/lib/netlist/devices/nld_8277.cpp b/src/lib/netlist/devices/nld_8277.cpp
index 424155656f1..c1c59e360fd 100644
--- a/src/lib/netlist/devices/nld_8277.cpp
+++ b/src/lib/netlist/devices/nld_8277.cpp
@@ -114,8 +114,8 @@ namespace netlist::devices {
{
if (!m_RESET())
{
- m_A.reset_shifter();
- m_B.reset_shifter();
+ m_A().reset_shifter();
+ m_B().reset_shifter();
}
}
@@ -123,8 +123,8 @@ namespace netlist::devices {
{
if (!m_last_CLK && m_CLK())
{
- m_A.shift();
- m_B.shift();
+ m_A().shift();
+ m_B().shift();
}
m_last_CLK = m_CLK();
m_last_CLKA = m_CLKA();
@@ -135,7 +135,7 @@ namespace netlist::devices {
{
if (!m_last_CLKA && m_CLKA())
{
- m_A.shift();
+ m_A().shift();
}
m_last_CLKA = m_CLKA();
}
@@ -144,7 +144,7 @@ namespace netlist::devices {
{
if (!m_last_CLKB && m_CLKB())
{
- m_B.shift();
+ m_B().shift();
}
m_last_CLKB = m_CLKB();
}
diff --git a/src/lib/netlist/devices/nld_am2847.cpp b/src/lib/netlist/devices/nld_am2847.cpp
index ac2edb4f3ff..07b811ab0a9 100644
--- a/src/lib/netlist/devices/nld_am2847.cpp
+++ b/src/lib/netlist/devices/nld_am2847.cpp
@@ -107,10 +107,10 @@ namespace netlist::devices {
{
if (m_last_CP && !m_CP())
{
- m_A.shift();
- m_B.shift();
- m_C.shift();
- m_D.shift();
+ m_A().shift();
+ m_B().shift();
+ m_C().shift();
+ m_D().shift();
}
m_last_CP = m_CP();
}
diff --git a/src/lib/netlist/devices/nld_log.cpp b/src/lib/netlist/devices/nld_log.cpp
index 289eb28e67b..a3dae6a4b39 100644
--- a/src/lib/netlist/devices/nld_log.cpp
+++ b/src/lib/netlist/devices/nld_log.cpp
@@ -117,6 +117,7 @@ namespace netlist::devices {
static constexpr std::size_t BUF_SIZE=16384;
static constexpr std::size_t BUFFERS=4;
analog_input_t m_I;
+ private:
plib::ofstream m_strm;
plib::putf8_writer m_writer;
bool m_reset;
@@ -129,14 +130,17 @@ namespace netlist::devices {
std::thread m_write_thread;
};
- NETLIB_OBJECT_DERIVED(logD, log)
+ class NETLIB_NAME(logD) : public NETLIB_NAME(log)
{
- NETLIB_CONSTRUCTOR(logD)
+ public:
+ NETLIB_NAME(logD)(constructor_param_t data)
+ : NETLIB_NAME(log)(data)
, m_I2(*this, "I2", nl_delegate(&NETLIB_NAME(logD)::input, this))
{
m_I.set_delegate(nl_delegate(&NETLIB_NAME(logD)::input, this));
}
+ private:
NETLIB_HANDLERI(input)
{
log_value(static_cast<nl_fptype>(m_I() - m_I2()));
diff --git a/src/lib/netlist/devices/nld_mm5837.cpp b/src/lib/netlist/devices/nld_mm5837.cpp
index b1b78208b64..cd92ce1e5df 100644
--- a/src/lib/netlist/devices/nld_mm5837.cpp
+++ b/src/lib/netlist/devices/nld_mm5837.cpp
@@ -48,7 +48,7 @@ namespace netlist::devices {
{
//m_V0.initial(0.0);
//m_RV.do_reset();
- m_RV.set_G_V_I(plib::reciprocal(m_R_LOW()),
+ m_RV().set_G_V_I(plib::reciprocal(m_R_LOW()),
nlconst::zero(),
nlconst::zero());
m_inc = netlist_time::from_fp(plib::reciprocal(m_FREQ()));
@@ -86,15 +86,15 @@ namespace netlist::devices {
const nl_fptype R = state ? m_R_HIGH : m_R_LOW;
const nl_fptype V = state ? m_VDD() : m_VSS();
- m_RV.change_state([this, &R, &V]()
+ m_RV().change_state([this, &R, &V]()
{
- m_RV.set_G_V_I(plib::reciprocal(R), V, nlconst::zero());
+ m_RV().set_G_V_I(plib::reciprocal(R), V, nlconst::zero());
});
}
}
- analog::NETLIB_SUB(two_terminal) m_RV;
+ NETLIB_SUB_NS(analog, two_terminal) m_RV;
analog_input_t m_VDD;
analog_input_t m_VGG;
analog_input_t m_VSS;
diff --git a/src/lib/netlist/devices/nld_ne555.cpp b/src/lib/netlist/devices/nld_ne555.cpp
index b6b444fe04d..a94d868373d 100644
--- a/src/lib/netlist/devices/nld_ne555.cpp
+++ b/src/lib/netlist/devices/nld_ne555.cpp
@@ -46,11 +46,11 @@ namespace netlist::devices {
NETLIB_RESETI()
{
/* FIXME make resistances a parameter, properly model other variants */
- m_R1.set_R(nlconst::magic(5000));
- m_R2.set_R(nlconst::magic(5000));
- m_R3.set_R(nlconst::magic(5000));
- m_ROUT.set_R(nlconst::magic(20));
- m_RDIS.set_R(nlconst::magic(R_OFF));
+ m_R1().set_R(nlconst::magic(5000));
+ m_R2().set_R(nlconst::magic(5000));
+ m_R3().set_R(nlconst::magic(5000));
+ m_ROUT().set_R(nlconst::magic(20));
+ m_RDIS().set_R(nlconst::magic(R_OFF));
m_last_out = true;
// Check for astable setup, usually TRIG AND THRES connected. Enable
@@ -66,8 +66,8 @@ namespace netlist::devices {
const auto reset = m_RESET();
- const nl_fptype v_threshold = clamp_hl(m_R2.P()(), nlconst::magic(0.7), nlconst::magic(1.4));
- const nl_fptype v_trigger = clamp_hl(m_R2.N()(), nlconst::magic(0.7), nlconst::magic(1.4));
+ const nl_fptype v_threshold = clamp_hl(m_R2().P()(), nlconst::magic(0.7), nlconst::magic(1.4));
+ const nl_fptype v_trigger = clamp_hl(m_R2().N()(), nlconst::magic(0.7), nlconst::magic(1.4));
// avoid artificial oscillation due to overshoot compensation when
// the control input is used.
@@ -106,11 +106,11 @@ namespace netlist::devices {
m_overshoot = plib::clamp(m_overshoot(), nlconst::zero(), overshoot_limit);
//if (this->name() == "IC6_2")
// printf("%f %s %f %f %f\n", exec().time().as_double(), this->name().c_str(), m_overshoot(), m_R2.P()(), m_THRES());
- m_RDIS.change_state([this]()
+ m_RDIS().change_state([this]()
{
- m_RDIS.set_R(nlconst::magic(R_ON));
+ m_RDIS().set_R(nlconst::magic(R_ON));
});
- m_OUT.push(m_R3.N()());
+ m_OUT.push(m_R3().N()());
}
else if (!m_last_out && out)
{
@@ -121,21 +121,21 @@ namespace netlist::devices {
m_undershoot += (v_trigger - m_TRIG());
m_undershoot = plib::clamp(m_undershoot(), nlconst::zero(), overshoot_limit);
#endif
- m_RDIS.change_state([this]()
+ m_RDIS().change_state([this]()
{
- m_RDIS.set_R(nlconst::magic(R_OFF));
+ m_RDIS().set_R(nlconst::magic(R_OFF));
});
// FIXME: Should be delayed by 100ns
- m_OUT.push(m_R1.P()());
+ m_OUT.push(m_R1().P()());
}
m_last_reset = reset;
m_last_out = out;
}
- analog::NETLIB_SUB(R_base) m_R1;
- analog::NETLIB_SUB(R_base) m_R2;
- analog::NETLIB_SUB(R_base) m_R3;
- analog::NETLIB_SUB(R_base) m_ROUT;
- analog::NETLIB_SUB(R_base) m_RDIS;
+ NETLIB_SUB_NS(analog, R_base) m_R1;
+ NETLIB_SUB_NS(analog, R_base) m_R2;
+ NETLIB_SUB_NS(analog, R_base) m_R3;
+ NETLIB_SUB_NS(analog, R_base) m_ROUT;
+ NETLIB_SUB_NS(analog, R_base) m_RDIS;
logic_input_t m_RESET;
analog_input_t m_THRES;
@@ -151,7 +151,7 @@ namespace netlist::devices {
nl_fptype clamp_hl(const nl_fptype v, const nl_fptype a, const nl_fptype b) noexcept
{
- const nl_fptype vcc = m_R1.P()();
+ const nl_fptype vcc = m_R1().P()();
return plib::clamp(v, b, vcc - a);
}
};
diff --git a/src/lib/netlist/devices/nld_r2r_dac.cpp b/src/lib/netlist/devices/nld_r2r_dac.cpp
index e1607536db6..efff78d9ca8 100644
--- a/src/lib/netlist/devices/nld_r2r_dac.cpp
+++ b/src/lib/netlist/devices/nld_r2r_dac.cpp
@@ -44,14 +44,18 @@
*/
#include "nl_base.h"
-#include "analog/nlid_twoterm.h"
#include "nl_factory.h"
-namespace netlist::analog {
+#include "analog/nlid_twoterm.h"
+
+namespace netlist::analog
+{
- NETLIB_OBJECT_DERIVED(r2r_dac, two_terminal)
+ class nld_r2r_dac : public nld_two_terminal
{
- NETLIB_CONSTRUCTOR(r2r_dac)
+ public:
+ nld_r2r_dac(constructor_param_t data)
+ : nld_two_terminal(data)
, m_VIN(*this, "VIN", nlconst::one())
, m_R(*this, "R", nlconst::one())
, m_num(*this, "N", 1)
@@ -62,31 +66,28 @@ namespace netlist::analog {
}
NETLIB_UPDATE_PARAMI();
- //NETLIB_RESETI();
- //NETLIB_UPDATEI();
+ // NETLIB_RESETI();
protected:
- param_fp_t m_VIN;
- param_fp_t m_R;
+ param_fp_t m_VIN;
+ param_fp_t m_R;
param_int_t m_num;
param_int_t m_val;
};
-
NETLIB_UPDATE_PARAM(r2r_dac)
{
nl_fptype V = m_VIN() / static_cast<nl_fptype>(1 << m_num())
- * static_cast<nl_fptype>(m_val());
- change_state([this, &V]()
- {
- this->set_G_V_I(plib::reciprocal(m_R()), V, nlconst::zero());
- }
- );
+ * static_cast<nl_fptype>(m_val());
+ change_state(
+ [this, &V]()
+ { this->set_G_V_I(plib::reciprocal(m_R()), V, nlconst::zero()); });
}
} // namespace netlist::analog
-namespace netlist::devices {
+namespace netlist::devices
+{
NETLIB_DEVICE_IMPL_NS(analog, r2r_dac, "R2R_DAC", "VIN,R,N")
diff --git a/src/lib/netlist/devices/nld_roms.cpp b/src/lib/netlist/devices/nld_roms.cpp
index 739039c6c22..024d508497a 100644
--- a/src/lib/netlist/devices/nld_roms.cpp
+++ b/src/lib/netlist/devices/nld_roms.cpp
@@ -169,9 +169,13 @@ namespace netlist::devices {
, m_A(*this, 0, "A{}", NETLIB_DELEGATE(addr))
, m_CEQ(*this, 1,
D::chip_enable_mask::value ^ static_cast<size_t>(0xffff), pstring("CE{}"),
- std::array<nl_delegate, 3>{ NETLIB_DELEGATE(ce<0>),
- NETLIB_DELEGATE(ce<1>),
- NETLIB_DELEGATE(ce<2>)})
+ // Causes a expected primary expression before { with gcc9
+ //std::array<nl_delegate, 3>{NETLIB_DELEGATE(ce<0>),
+ // NETLIB_DELEGATE(ce<1>),
+ // NETLIB_DELEGATE(ce<2>)})
+ std::array<nl_delegate, 3>{nl_delegate(& NETLIB_NAME(generic_prom) :: ce<0>, this),
+ nl_delegate(& NETLIB_NAME(generic_prom) :: ce<1>, this),
+ nl_delegate(& NETLIB_NAME(generic_prom) :: ce<2>, this)})
, m_O(*this, D::data_name_offset::value, "O{}", m_TE())
, m_ROM(*this, "ROM")
, m_power_pins(*this)
diff --git a/src/lib/netlist/devices/nld_schmitt.cpp b/src/lib/netlist/devices/nld_schmitt.cpp
index f3d3a1e7a57..a6134f3a953 100644
--- a/src/lib/netlist/devices/nld_schmitt.cpp
+++ b/src/lib/netlist/devices/nld_schmitt.cpp
@@ -66,18 +66,18 @@ namespace netlist::devices {
connect("A", "RVI.1");
// FIXME: need a symbolic reference from connect as well
- connect(m_supply.GND(), m_RVI.N());
- connect(m_supply.GND(), m_RVO.N());
+ connect(m_supply.GND(), m_RVI().N());
+ connect(m_supply.GND(), m_RVO().N());
}
protected:
NETLIB_RESETI()
{
m_last_state = 1;
- m_RVI.reset();
- m_RVO.reset();
- m_RVI.set_G_V_I(plib::reciprocal(m_modacc.m_RI()), m_modacc.m_VI, nlconst::zero());
- m_RVO.set_G_V_I(plib::reciprocal(m_modacc.m_ROL()), m_modacc.m_VOL, nlconst::zero());
+ m_RVI().reset();
+ m_RVO().reset();
+ m_RVI().set_G_V_I(plib::reciprocal(m_modacc.m_RI()), m_modacc.m_VI, nlconst::zero());
+ m_RVO().set_G_V_I(plib::reciprocal(m_modacc.m_ROL()), m_modacc.m_VOL, nlconst::zero());
}
private:
@@ -89,9 +89,9 @@ namespace netlist::devices {
if (va < m_modacc.m_VTM)
{
m_last_state = 0;
- m_RVO.change_state([this]()
+ m_RVO().change_state([this]()
{
- m_RVO.set_G_V_I(plib::reciprocal(m_modacc.m_ROH()), m_modacc.m_VOH, nlconst::zero());
+ m_RVO().set_G_V_I(plib::reciprocal(m_modacc.m_ROH()), m_modacc.m_VOH, nlconst::zero());
});
}
}
@@ -100,9 +100,9 @@ namespace netlist::devices {
if (va > m_modacc.m_VTP)
{
m_last_state = 1;
- m_RVO.change_state([this]()
+ m_RVO().change_state([this]()
{
- m_RVO.set_G_V_I(plib::reciprocal(m_modacc.m_ROL()), m_modacc.m_VOL, nlconst::zero());
+ m_RVO().set_G_V_I(plib::reciprocal(m_modacc.m_ROL()), m_modacc.m_VOL, nlconst::zero());
});
}
}
@@ -110,8 +110,8 @@ namespace netlist::devices {
analog_input_t m_A;
NETLIB_NAME(power_pins) m_supply;
- analog::NETLIB_SUB(two_terminal) m_RVI;
- analog::NETLIB_SUB(two_terminal) m_RVO;
+ NETLIB_SUB_NS(analog, two_terminal) m_RVI;
+ NETLIB_SUB_NS(analog, two_terminal) m_RVO;
param_model_t m_stmodel;
schmitt_trigger_model_t m_modacc;
state_var<int> m_last_state;
diff --git a/src/lib/netlist/devices/nlid_proxy.cpp b/src/lib/netlist/devices/nlid_proxy.cpp
index 96ec987df8e..0ab77e84e7d 100644
--- a/src/lib/netlist/devices/nlid_proxy.cpp
+++ b/src/lib/netlist/devices/nlid_proxy.cpp
@@ -21,9 +21,9 @@ namespace netlist::devices {
static constexpr std::array<std::pair<const char *, const char *>, 3> power_syms = {{ {"VCC", "VEE"}, {"VCC", "GND"}, {"VDD", "VSS"}}};
- nld_base_proxy::nld_base_proxy(netlist_state_t &anetlist, const pstring &name,
+ nld_base_proxy::nld_base_proxy(device_param_t data,
const logic_t *inout_proxied)
- : device_t(anetlist, name, inout_proxied->logic_family())
+ : device_t(data, inout_proxied->logic_family())
, m_tp(nullptr)
, m_tn(nullptr)
{
@@ -32,15 +32,14 @@ namespace netlist::devices {
throw nl_exception(MF_NULLPTR_FAMILY_NP("nld_base_proxy"));
}
-
bool f = false;
for (const auto & pwr_sym : power_syms)
{
pstring devname = inout_proxied->device().name();
- auto *tp_ct(anetlist.setup().find_terminal(devname + "." + pstring(pwr_sym.first),
+ auto *tp_ct(state().setup().find_terminal(devname + "." + pstring(pwr_sym.first),
/*detail::terminal_type::INPUT,*/ false));
- auto *tp_cn(anetlist.setup().find_terminal(devname + "." + pstring(pwr_sym.second),
+ auto *tp_cn(state().setup().find_terminal(devname + "." + pstring(pwr_sym.second),
/*detail::terminal_type::INPUT,*/ false));
if ((tp_ct != nullptr) && (tp_cn != nullptr))
{
@@ -49,23 +48,23 @@ namespace netlist::devices {
if (!tp_cn->is_analog())
throw nl_exception(plib::pfmt("Not an analog terminal: {1}")(tp_cn->name()));
- auto *tp_t = dynamic_cast<analog_t* >(tp_ct);
- auto *tn_t = dynamic_cast<analog_t *>(tp_cn);
- if (f && (tp_t != nullptr && tn_t != nullptr))
+ auto tp_t = plib::dynamic_downcast<analog_t* >(tp_ct);
+ auto tn_t = plib::dynamic_downcast<analog_t *>(tp_cn);
+ if (f && (tp_t && tn_t))
log().warning(MI_MULTIPLE_POWER_TERMINALS_ON_DEVICE(inout_proxied->device().name(),
m_tp->name(), m_tn->name(),
- tp_t != nullptr ? tp_t->name() : "",
- tn_t != nullptr ? tn_t->name() : ""));
- else if (tp_t != nullptr && tn_t != nullptr)
+ tp_t ? (*tp_t)->name() : "",
+ tn_t ? (*tn_t)->name() : ""));
+ else if (tp_t && tn_t)
{
- m_tp = tp_t;
- m_tn = tn_t;
+ m_tp = *tp_t;
+ m_tn = *tn_t;
f = true;
}
}
}
if (!f)
- throw nl_exception(MF_NO_POWER_TERMINALS_ON_DEVICE_2(name, anetlist.setup().de_alias(inout_proxied->device().name())));
+ throw nl_exception(MF_NO_POWER_TERMINALS_ON_DEVICE_2(name(), state().setup().de_alias(inout_proxied->device().name())));
log().verbose("D/A Proxy: Found power terminals on device {1}", inout_proxied->device().name());
}
@@ -74,14 +73,14 @@ namespace netlist::devices {
// nld_a_to_d_proxy
// ----------------------------------------------------------------------------------------
- nld_base_a_to_d_proxy::nld_base_a_to_d_proxy(netlist_state_t &anetlist, const pstring &name,
+ nld_base_a_to_d_proxy::nld_base_a_to_d_proxy(device_param_t data,
const logic_input_t *in_proxied)
- : nld_base_proxy(anetlist, name, in_proxied)
+ : nld_base_proxy(data, in_proxied)
{
}
- nld_a_to_d_proxy::nld_a_to_d_proxy(netlist_state_t &anetlist, const pstring &name, const logic_input_t *in_proxied)
- : nld_base_a_to_d_proxy(anetlist, name, in_proxied)
+ nld_a_to_d_proxy::nld_a_to_d_proxy(device_param_t data, const logic_input_t *in_proxied)
+ : nld_base_a_to_d_proxy(data, in_proxied)
, m_Q(*this, "Q")
, m_I(*this, "I", nl_delegate(&nld_a_to_d_proxy::input, this))
{
@@ -107,14 +106,14 @@ namespace netlist::devices {
// nld_d_to_a_proxy
// ----------------------------------------------------------------------------------------
- nld_base_d_to_a_proxy::nld_base_d_to_a_proxy(netlist_state_t &anetlist, const pstring &name,
+ nld_base_d_to_a_proxy::nld_base_d_to_a_proxy(device_param_t data,
const logic_output_t *out_proxied)
- : nld_base_proxy(anetlist, name, out_proxied)
+ : nld_base_proxy(data, out_proxied)
{
}
- nld_d_to_a_proxy::nld_d_to_a_proxy(netlist_state_t &anetlist, const pstring &name, const logic_output_t *out_proxied)
- : nld_base_d_to_a_proxy(anetlist, name, out_proxied)
+ nld_d_to_a_proxy::nld_d_to_a_proxy(device_param_t data, const logic_output_t *out_proxied)
+ : nld_base_d_to_a_proxy(data, out_proxied)
, m_I(*this, "I", nl_delegate(&nld_d_to_a_proxy :: input, this))
, m_RP(*this, "RP")
, m_RN(*this, "RN")
@@ -122,10 +121,10 @@ namespace netlist::devices {
{
register_sub_alias("Q", "RN.1");
- connect(m_RN.N(), *m_tn);
- connect(m_RP.P(), *m_tp);
+ connect(m_RN().N(), *m_tn);
+ connect(m_RP().P(), *m_tp);
- connect(m_RN.P(), m_RP.N());
+ connect(m_RN().P(), m_RP().N());
}
@@ -133,11 +132,11 @@ namespace netlist::devices {
{
//m_Q.initial(0.0);
m_last_state = terminal_t::OUT_TRISTATE();
- m_RN.reset();
- m_RP.reset();
- m_RN.set_G_V_I(plib::reciprocal(logic_family()->R_low()),
+ m_RN().reset();
+ m_RP().reset();
+ m_RN().set_G_V_I(plib::reciprocal(logic_family()->R_low()),
logic_family()->low_offset_V(), nlconst::zero());
- m_RP.set_G_V_I(G_OFF,
+ m_RP().set_G_V_I(G_OFF,
nlconst::zero(),
nlconst::zero());
}
@@ -148,29 +147,29 @@ namespace netlist::devices {
if (state != m_last_state)
{
// RN, RP are connected ...
- m_RN.change_state([this, &state]()
+ m_RN().change_state([this, &state]()
{
switch (state)
{
case 0:
- m_RN.set_G_V_I(plib::reciprocal(logic_family()->R_low()),
+ m_RN().set_G_V_I(plib::reciprocal(logic_family()->R_low()),
logic_family()->low_offset_V(), nlconst::zero());
- m_RP.set_G_V_I(G_OFF,
+ m_RP().set_G_V_I(G_OFF,
nlconst::zero(),
nlconst::zero());
break;
case 1:
- m_RN.set_G_V_I(G_OFF,
+ m_RN().set_G_V_I(G_OFF,
nlconst::zero(),
nlconst::zero());
- m_RP.set_G_V_I(plib::reciprocal(logic_family()->R_high()),
+ m_RP().set_G_V_I(plib::reciprocal(logic_family()->R_high()),
logic_family()->high_offset_V(), nlconst::zero());
break;
case terminal_t::OUT_TRISTATE():
- m_RN.set_G_V_I(G_OFF,
+ m_RN().set_G_V_I(G_OFF,
nlconst::zero(),
nlconst::zero());
- m_RP.set_G_V_I(G_OFF,
+ m_RP().set_G_V_I(G_OFF,
nlconst::zero(),
nlconst::zero());
break;
diff --git a/src/lib/netlist/devices/nlid_proxy.h b/src/lib/netlist/devices/nlid_proxy.h
index aea5b6f11d8..0f1b2ffeacd 100644
--- a/src/lib/netlist/devices/nlid_proxy.h
+++ b/src/lib/netlist/devices/nlid_proxy.h
@@ -25,8 +25,7 @@ namespace netlist::devices {
class nld_base_proxy : public device_t
{
public:
- nld_base_proxy(netlist_state_t &anetlist, const pstring &name,
- const logic_t *inout_proxied);
+ nld_base_proxy(device_param_t data, const logic_t *inout_proxied);
// only used during setup
virtual detail::core_terminal_t &proxy_term() noexcept = 0;
@@ -49,16 +48,14 @@ namespace netlist::devices {
virtual logic_output_t &out() noexcept = 0;
protected:
- nld_base_a_to_d_proxy(netlist_state_t &anetlist, const pstring &name,
- const logic_input_t *in_proxied);
+ nld_base_a_to_d_proxy(device_param_t data, const logic_input_t *in_proxied);
};
class nld_a_to_d_proxy : public nld_base_a_to_d_proxy
{
public:
- nld_a_to_d_proxy(netlist_state_t &anetlist, const pstring &name,
- const logic_input_t *in_proxied);
+ nld_a_to_d_proxy(device_param_t data, const logic_input_t *in_proxied);
logic_output_t &out() noexcept override { return m_Q; }
@@ -87,22 +84,20 @@ namespace netlist::devices {
virtual logic_input_t &in() noexcept = 0;
protected:
- nld_base_d_to_a_proxy(netlist_state_t &anetlist, const pstring &name,
- const logic_output_t *out_proxied);
+ nld_base_d_to_a_proxy(device_param_t data, const logic_output_t *out_proxied);
};
class nld_d_to_a_proxy : public nld_base_d_to_a_proxy
{
public:
- nld_d_to_a_proxy(netlist_state_t &anetlist, const pstring &name,
- const logic_output_t *out_proxied);
+ nld_d_to_a_proxy(device_param_t data, const logic_output_t *out_proxied);
logic_input_t &in() noexcept override { return m_I; }
detail::core_terminal_t &proxy_term() noexcept override
{
- return m_RN.setup_P();
+ return m_RN().setup_P();
}
protected:
@@ -115,8 +110,8 @@ namespace netlist::devices {
static constexpr const nl_fptype G_OFF = nlconst::cgmin();
logic_input_t m_I;
- analog::NETLIB_NAME(two_terminal) m_RP;
- analog::NETLIB_NAME(two_terminal) m_RN;
+ NETLIB_SUB_NS(analog, two_terminal) m_RP;
+ NETLIB_SUB_NS(analog, two_terminal) m_RN;
state_var<netlist_sig_t> m_last_state;
};
diff --git a/src/lib/netlist/devices/nlid_system.h b/src/lib/netlist/devices/nlid_system.h
index c87bbcfbd9b..fee4fad0333 100644
--- a/src/lib/netlist/devices/nlid_system.h
+++ b/src/lib/netlist/devices/nlid_system.h
@@ -84,7 +84,7 @@ namespace netlist::devices {
for (std::uint64_t i=0; i < m_N(); i++)
{
pstring input_name = plib::pfmt("A{1}")(i);
- m_I.push_back(owner.template make_pool_object<analog_input_t>(*this, input_name, NETLIB_DELEGATE(fb)));
+ m_I.push_back(state().make_pool_object<analog_input_t>(*this, input_name, NETLIB_DELEGATE(fb)));
inputs.push_back(input_name);
m_vals.push_back(nlconst::zero());
}
@@ -303,7 +303,7 @@ namespace netlist::devices {
for (uint64_t i=0; i < m_N(); i++)
{
pstring input_name = plib::pfmt("A{1}")(i);
- m_I.push_back(owner.template make_pool_object<analog_input_t>(*this, input_name, NETLIB_DELEGATE(inputs)));
+ m_I.push_back(state().make_pool_object<analog_input_t>(*this, input_name, NETLIB_DELEGATE(inputs)));
inputs.push_back(input_name);
m_values.push_back(nlconst::zero());
}
@@ -364,15 +364,15 @@ namespace netlist::devices {
NETLIB_RESETI()
{
m_last_state = 0;
- m_R.set_R(m_ROFF());
+ m_R().set_R(m_ROFF());
}
//NETLIB_UPDATE_PARAMI();
//FIXME: used by 74123
- const terminal_t &P() const noexcept { return m_R.P(); }
- const terminal_t &N() const noexcept { return m_R.N(); }
+ const terminal_t &P() const noexcept { return m_R().P(); }
+ const terminal_t &N() const noexcept { return m_R().N(); }
const logic_input_t &I() const noexcept { return m_I; }
param_fp_t m_RON;
@@ -387,14 +387,14 @@ namespace netlist::devices {
m_last_state = state;
const nl_fptype R = (state != 0) ? m_RON() : m_ROFF();
- m_R.change_state([this, &R]()
+ m_R().change_state([this, &R]()
{
- m_R.set_R(R);
+ m_R().set_R(R);
});
}
}
- analog::NETLIB_SUB(R_base) m_R;
+ NETLIB_SUB_NS(analog, R_base) m_R;
logic_input_t m_I;
state_var<netlist_sig_t> m_last_state;
@@ -424,8 +424,8 @@ namespace netlist::devices {
private:
NETLIB_RESETI()
{
- m_R1.set_G(m_GOFF());
- m_R2.set_G(m_GON());
+ m_R1().set_G(m_GOFF());
+ m_R2().set_G(m_GON());
}
//NETLIB_UPDATE_PARAMI();
@@ -437,29 +437,29 @@ namespace netlist::devices {
//printf("Here %d\n", state);
const nl_fptype G1 = (state != 0) ? m_GON() : m_GOFF();
const nl_fptype G2 = (state != 0) ? m_GOFF() : m_GON();
- if (m_R1.solver() == m_R2.solver())
+ if (m_R1().solver() == m_R2().solver())
{
- m_R1.change_state([this, &G1, &G2]()
+ m_R1().change_state([this, &G1, &G2]()
{
- m_R1.set_G(G1);
- m_R2.set_G(G2);
+ m_R1().set_G(G1);
+ m_R2().set_G(G2);
});
}
else
{
- m_R1.change_state([this, &G1]()
+ m_R1().change_state([this, &G1]()
{
- m_R1.set_G(G1);
+ m_R1().set_G(G1);
});
- m_R2.change_state([this, &G2]()
+ m_R2().change_state([this, &G2]()
{
- m_R2.set_G(G2);
+ m_R2().set_G(G2);
});
}
}
- analog::NETLIB_SUB(R_base) m_R1;
- analog::NETLIB_SUB(R_base) m_R2;
+ NETLIB_SUB_NS(analog, R_base) m_R1;
+ NETLIB_SUB_NS(analog, R_base) m_R2;
logic_input_t m_I;
param_fp_t m_GON;
param_fp_t m_GOFF;
@@ -570,18 +570,18 @@ namespace netlist::devices {
NETLIB_HANDLERI(input)
{
nl_fptype val = m_dis()(m_mt());
- m_T.change_state([this, val]()
+ m_T().change_state([this, val]()
{
- m_T.set_G_V_I(plib::reciprocal(m_RI()), val, nlconst::zero());
+ m_T().set_G_V_I(plib::reciprocal(m_RI()), val, nlconst::zero());
});
}
NETLIB_RESETI()
{
- m_T.set_G_V_I(plib::reciprocal(m_RI()), nlconst::zero(), nlconst::zero());
+ m_T().set_G_V_I(plib::reciprocal(m_RI()), nlconst::zero(), nlconst::zero());
}
- analog::NETLIB_SUB(two_terminal) m_T;
+ NETLIB_SUB_NS(analog, two_terminal) m_T;
logic_input_t m_I;
param_fp_t m_RI;
param_fp_t m_sigma;
diff --git a/src/lib/netlist/devices/nlid_truthtable.cpp b/src/lib/netlist/devices/nlid_truthtable.cpp
index 0f68517cb1f..072fa148d75 100644
--- a/src/lib/netlist/devices/nlid_truthtable.cpp
+++ b/src/lib/netlist/devices/nlid_truthtable.cpp
@@ -36,11 +36,9 @@ namespace netlist::devices {
std::array<netlist_time, 16> m_timing_nt;
};
- template <class C>
- nld_truth_table_t(C &owner, const pstring &name,
- const pstring &model,
+ nld_truth_table_t(device_param_t data, const pstring &model,
truth_table_t &ttp, const std::vector<pstring> &desc)
- : device_t(owner, name, model)
+ : device_t(data, model)
#if NL_USE_TT_ALTERNATIVE
, m_state(*this, "m_state", 0)
#endif
@@ -272,8 +270,8 @@ namespace netlist::devices {
return ret;
}
- static constexpr const pbitset all_bits() noexcept { return pbitset(~static_cast<T>(0)); }
- static constexpr const pbitset no_bits() noexcept{ return pbitset(static_cast<T>(0)); }
+ static constexpr pbitset all_bits() noexcept { return pbitset(~static_cast<T>(0)); }
+ static constexpr pbitset no_bits() noexcept{ return pbitset(static_cast<T>(0)); }
private:
T m_bs;
};
@@ -414,7 +412,7 @@ namespace netlist::devices {
// Connect output "Q" to input "_Q" if this exists
// This enables timed state without having explicit state ....
pstring tmp = "_" + outputs[i];
- const std::size_t idx = plib::container::indexof(inout, tmp);
+ const std::size_t idx = plib::container::index_of(inout, tmp);
if (idx != plib::container::npos)
connect(m_Q[i], m_I[idx]);
}
@@ -426,10 +424,10 @@ namespace netlist::devices {
// ----------------------------------------------------------------------------------------
template<unsigned m_NI, unsigned m_NO>
- class netlist_factory_truth_table_t : public factory::truth_table_base_element_t
+ class factory_truth_table_t : public factory::truth_table_base_element_t
{
public:
- netlist_factory_truth_table_t(const pstring &name,
+ factory_truth_table_t(const pstring &name,
factory::properties &&props)
: truth_table_base_element_t(name, std::move(props))
{ }
@@ -448,7 +446,7 @@ namespace netlist::devices {
desc_s.parse(m_desc);
}
- return plib::make_unique<tt_type>(pool, anetlist, name, m_family_name, *m_table, m_desc);
+ return plib::make_unique<tt_type>(pool, device_data_t{anetlist, name}, m_family_name, *m_table, m_desc);
}
private:
device_arena::unique_ptr<typename nld_truth_table_t<m_NI, m_NO>::truth_table_t> m_table;
@@ -667,7 +665,7 @@ namespace netlist::factory {
}
#define ENTRYY(n, m, s) case (n * 100 + m): \
- { using dev_type = devices::netlist_factory_truth_table_t<n, m>; \
+ { using dev_type = devices::factory_truth_table_t<n, m>; \
auto cs=s; \
ret = plib::make_unique<dev_type, host_arena>(desc.name, std::move(cs)); } \
break
diff --git a/src/lib/netlist/macro/nlm_ttl74xx_lib.cpp b/src/lib/netlist/macro/nlm_ttl74xx_lib.cpp
index 707d57cfd9f..c918d5015e6 100644
--- a/src/lib/netlist/macro/nlm_ttl74xx_lib.cpp
+++ b/src/lib/netlist/macro/nlm_ttl74xx_lib.cpp
@@ -21,6 +21,7 @@
//- +---+---++---+
//-
static NETLIST_START(TTL_7400_DIP)
+{
TTL_7400_NAND(A)
TTL_7400_NAND(B)
TTL_7400_NAND(C)
@@ -39,6 +40,7 @@ static NETLIST_START(TTL_7400_DIP)
A.GND, /* GND |7 8| Y3 */ C.Q
/* +--------------+ */
)
+}
NETLIST_END()
//- Identifier: TTL_7402_DIP
@@ -2091,20 +2093,15 @@ NETLIST_END()
//-
static NETLIST_START(TTL_74174_DIP)
TTL_74174(A)
- TTL_74174(B)
- TTL_74174(C)
- TTL_74174(D)
- TTL_74174(E)
- TTL_74174(F)
DIPPINS( /* +--------------+ */
- A.CLRQ, /* CLRQ |1 ++ 16| VCC */ A.VCC,
- A.Q, /* Q1 |2 15| Q6 */ F.Q,
- A.D, /* D1 |3 14| D6 */ F.D,
- B.D, /* D2 |4 74174 13| D5 */ E.D,
- B.Q, /* Q2 |5 12| Q5 */ E.Q,
- C.D, /* D3 |6 11| D4 */ D.D,
- C.Q, /* Q3 |7 10| Q4 */ D.Q,
+ A.CLRQ, /* CLRQ |1 ++ 16| VCC */ A.VCC
+ A.Q1, /* Q1 |2 15| Q6 */ A.Q6,
+ A.D1, /* D1 |3 14| D6 */ A.D6,
+ A.D2, /* D2 |4 74174 13| D5 */ A.D5,
+ A.Q2, /* Q2 |5 12| Q5 */ A.Q5,
+ A.D3, /* D3 |6 11| D4 */ A.D4,
+ A.Q3, /* Q3 |7 10| Q4 */ A.Q4,
A.GND, /* GND |8 9| CLK */ A.CLK
/* +--------------+ */
)
@@ -3147,6 +3144,7 @@ static TRUTHTABLE_START(TTL_74279B, 4, 1, "")
TRUTHTABLE_END()
static TRUTHTABLE_START(TTL_9312, 12, 2, "+A,+B,+C,+G,+D0,+D1,+D2,+D3,+D4,+D5,+D6,+D7,@VCC,@GND")
+{
TT_HEAD(" C, B, A, G,D0,D1,D2,D3,D4,D5,D6,D7| Y,YQ")
TT_LINE(" X, X, X, 1, X, X, X, X, X, X, X, X| 0, 1|33,19")
TT_LINE(" 0, 0, 0, 0, 0, X, X, X, X, X, X, X| 0, 1|33,28")
@@ -3166,6 +3164,7 @@ static TRUTHTABLE_START(TTL_9312, 12, 2, "+A,+B,+C,+G,+D0,+D1,+D2,+D3,+D4,+D5,+D
TT_LINE(" 1, 1, 1, 0, X, X, X, X, X, X, X, 0| 0, 1|33,28")
TT_LINE(" 1, 1, 1, 0, X, X, X, X, X, X, X, 1| 1, 0|33,28")
TT_FAMILY("74XX")
+}
TRUTHTABLE_END()
NETLIST_START(ttl74xx_lib)
diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp
index c60162efb0c..96790951b33 100644
--- a/src/lib/netlist/nl_base.cpp
+++ b/src/lib/netlist/nl_base.cpp
@@ -1,6 +1,14 @@
// license:BSD-3-Clause
// copyright-holders:Couriersud
+#include "nl_errstr.h"
+
+#include "core/devices.h"
+#include "core/logic.h"
+#include "core/setup.h"
+
+#include "devices/nlid_proxy.h"
+
#include "solver/nld_matrix_solver.h"
#include "solver/nld_solver.h"
@@ -10,13 +18,6 @@
#include "plib/pmempool.h"
#include "plib/putil.h"
-#include "core/devices.h"
-#include "core/logic.h"
-#include "core/setup.h"
-#include "devices/nlid_proxy.h"
-
-#include "nl_errstr.h"
-
#include <limits>
NETLIST_EXTERNAL(base_lib)
@@ -24,31 +25,32 @@ NETLIST_EXTERNAL(base_lib)
namespace netlist
{
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// detail::core_terminal_t
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
detail::terminal_type detail::core_terminal_t::type() const noexcept(false)
{
- if (dynamic_cast<const terminal_t *>(this) != nullptr)
+ if (plib::dynamic_downcast<const terminal_t *>(this))
return terminal_type::TERMINAL;
- if (dynamic_cast<const logic_input_t *>(this) != nullptr
- || dynamic_cast<const analog_input_t *>(this) != nullptr)
+ if (plib::dynamic_downcast<const logic_input_t *>(this)
+ || plib::dynamic_downcast<const analog_input_t *>(this))
return terminal_type::INPUT;
- if (dynamic_cast<const logic_output_t *>(this) != nullptr
- || dynamic_cast<const analog_output_t *>(this) != nullptr)
+ if (plib::dynamic_downcast<const logic_output_t *>(this)
+ || plib::dynamic_downcast<const analog_output_t *>(this))
return terminal_type::OUTPUT;
state().log().fatal(MF_UNKNOWN_TYPE_FOR_OBJECT(name()));
throw nl_exception(MF_UNKNOWN_TYPE_FOR_OBJECT(name()));
- //return terminal_type::TERMINAL; // please compiler
+ // return terminal_type::TERMINAL; // please compiler
}
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// detail::device_object_t
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
- detail::device_object_t::device_object_t(core_device_t *dev, const pstring &aname)
+ detail::device_object_t::device_object_t(core_device_t *dev,
+ const pstring & aname)
: object_t(aname)
, m_device(dev)
{
@@ -64,23 +66,23 @@ namespace netlist
return m_device->state();
}
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// detail::netlist_object_t
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
- netlist_state_t & detail::netlist_object_t::state() noexcept
+ netlist_state_t &detail::netlist_object_t::state() noexcept
{
return m_netlist.nl_state();
}
- const netlist_state_t & detail::netlist_object_t::state() const noexcept
+ const netlist_state_t &detail::netlist_object_t::state() const noexcept
{
return m_netlist.nl_state();
}
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// netlist_t
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
netlist_t::netlist_t(netlist_state_t &state, const pstring &aname)
: m_state(state)
@@ -89,28 +91,33 @@ namespace netlist
, m_main_clock(nullptr)
, m_use_stats(false)
, m_queue(state.pool(), config::max_queue_size::value,
- detail::queue_t::id_delegate(&netlist_state_t :: find_net_id, &state),
- detail::queue_t::obj_delegate(&netlist_state_t :: net_by_id, &state))
+ detail::queue_t::id_delegate(&netlist_state_t ::find_net_id, &state),
+ detail::queue_t::obj_delegate(&netlist_state_t ::net_by_id, &state))
{
- state.save(*this, static_cast<plib::state_manager_t::callback_t &>(m_queue), aname, "m_queue");
+ state.save(*this,
+ static_cast<plib::state_manager_t::callback_t &>(m_queue), aname,
+ "m_queue");
state.save(*this, m_time, aname, "m_time");
}
void netlist_t::reset()
{
log().debug("Searching for main clock\n");
- m_main_clock = m_state.get_single_device<devices::NETLIB_NAME(mainclock)>("mainclock");
+ m_main_clock = m_state
+ .get_single_device<devices::NETLIB_NAME(mainclock)>(
+ "mainclock");
log().debug("Searching for solver\n");
- m_solver = m_state.get_single_device<devices::NETLIB_NAME(solver)>("solver");
+ m_solver = m_state.get_single_device<devices::NETLIB_NAME(solver)>(
+ "solver");
// Don't reset time
- //m_time = netlist_time_ext::zero();
+ // m_time = netlist_time_ext::zero();
m_queue.clear();
if (m_main_clock != nullptr)
m_main_clock->m_Q.net().set_next_scheduled_time(m_time);
- //if (m_solver != nullptr)
- // m_solver->reset();
+ // if (m_solver != nullptr)
+ // m_solver->reset();
m_state.reset();
}
@@ -128,19 +135,22 @@ namespace netlist
{
if (m_use_stats)
{
- netlist_state_t::stats_info si{m_queue, m_stat_mainloop, m_perf_out_processed};
+ netlist_state_t::stats_info si{m_queue, m_stat_mainloop,
+ m_perf_out_processed};
m_state.print_stats(si);
}
- log().verbose("Current pool memory allocated: {1:12} kB", nl_state().pool().cur_alloc() >> 10);
- log().verbose("Maximum pool memory allocated: {1:12} kB", nl_state().pool().max_alloc() >> 10);
+ log().verbose("Current pool memory allocated: {1:12} kB",
+ nl_state().pool().cur_alloc() >> 10);
+ log().verbose("Maximum pool memory allocated: {1:12} kB",
+ nl_state().pool().max_alloc() >> 10);
}
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// netlist_state_t
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
netlist_state_t::netlist_state_t(const pstring &name,
- plib::plog_delegate logger)
+ plib::plog_delegate logger)
: m_log(logger)
, m_dummy_version(1)
{
@@ -156,47 +166,59 @@ namespace netlist
devices::initialize_factory(m_setup->parser().factory());
// Add default include file
- const pstring content =
- "#define RES_R(res) (res) \n"
- "#define RES_K(res) ((res) * 1e3) \n"
- "#define RES_M(res) ((res) * 1e6) \n"
- "#define CAP_U(cap) ((cap) * 1e-6) \n"
- "#define CAP_N(cap) ((cap) * 1e-9) \n"
- "#define CAP_P(cap) ((cap) * 1e-12) \n"
- "#define IND_U(ind) ((ind) * 1e-6) \n"
- "#define IND_N(ind) ((ind) * 1e-9) \n"
- "#define IND_P(ind) ((ind) * 1e-12) \n";
- m_setup->parser().add_include<plib::psource_str_t>("netlist/devices/net_lib.h", content);
+ const pstring content
+ = "#define RES_R(res) (res) \n"
+ "#define RES_K(res) ((res) * 1e3) \n"
+ "#define RES_M(res) ((res) * 1e6) \n"
+ "#define CAP_U(cap) ((cap) * 1e-6) \n"
+ "#define CAP_N(cap) ((cap) * 1e-9) \n"
+ "#define CAP_P(cap) ((cap) * 1e-12) \n"
+ "#define IND_U(ind) ((ind) * 1e-6) \n"
+ "#define IND_N(ind) ((ind) * 1e-9) \n"
+ "#define IND_P(ind) ((ind) * 1e-12) \n";
+ m_setup->parser().add_include<plib::psource_str_t>(
+ "netlist/devices/net_lib.h", content);
// This is for core macro libraries
- m_setup->parser().add_include<plib::psource_str_t>("devices/net_lib.h", content);
+ m_setup->parser().add_include<plib::psource_str_t>("devices/net_lib.h",
+ content);
#if 1
NETLIST_NAME(base_lib)(m_setup->parser());
//#m_setup->parser().register_source<source_pattern_t>("../macro/modules/nlmod_{1}.cpp");
//#m_setup->parser().register_source<source_pattern_t>("../macro/nlm_{1}.cpp");
#else
-#if 1
+ #if 1
pstring dir = "src/lib/netlist/";
- m_setup->parser().register_source<source_pattern_t>(dir + "/macro/nlm_{1}.cpp", true);
- m_setup->parser().register_source<source_pattern_t>(dir + "/generated/nlm_{1}.cpp", true);
- m_setup->parser().register_source<source_pattern_t>(dir + "/macro/modules/nlmod_{1}.cpp", true);
+ m_setup->parser().register_source<source_pattern_t>(
+ dir + "/macro/nlm_{1}.cpp", true);
+ m_setup->parser().register_source<source_pattern_t>(
+ dir + "/generated/nlm_{1}.cpp", true);
+ m_setup->parser().register_source<source_pattern_t>(
+ dir + "/macro/modules/nlmod_{1}.cpp", true);
m_setup->parser().include("base_lib");
-#else
+ #else
// FIXME: This is very slow - need optimized parsing scanning
pstring dir = "src/lib/netlist/macro/";
- //m_setup->parser().register_source<source_pattern_t>("src/lib/netlist/macro/nlm_{}.cpp");
- m_setup->parser().register_source<source_file_t>(dir + "nlm_base_lib.cpp");
- m_setup->parser().register_source<source_file_t>(dir + "nlm_opamp_lib.cpp");
- m_setup->parser().register_source<source_file_t>(dir + "nlm_roms_lib.cpp");
- m_setup->parser().register_source<source_file_t>(dir + "nlm_cd4xxx_lib.cpp");
- m_setup->parser().register_source<source_file_t>(dir + "nlm_otheric_lib.cpp");
- m_setup->parser().register_source<source_file_t>(dir + "nlm_ttl74xx_lib.cpp");
+ // m_setup->parser().register_source<source_pattern_t>("src/lib/netlist/macro/nlm_{}.cpp");
+ m_setup->parser().register_source<source_file_t>(
+ dir + "nlm_base_lib.cpp");
+ m_setup->parser().register_source<source_file_t>(
+ dir + "nlm_opamp_lib.cpp");
+ m_setup->parser().register_source<source_file_t>(
+ dir + "nlm_roms_lib.cpp");
+ m_setup->parser().register_source<source_file_t>(
+ dir + "nlm_cd4xxx_lib.cpp");
+ m_setup->parser().register_source<source_file_t>(
+ dir + "nlm_otheric_lib.cpp");
+ m_setup->parser().register_source<source_file_t>(
+ dir + "nlm_ttl74xx_lib.cpp");
m_setup->parser().include("base_lib");
-#endif
+ #endif
#endif
}
- void netlist_state_t::set_static_solver_lib(std::unique_ptr<plib::dynamic_library_base> &&lib)
+ void netlist_state_t::set_static_solver_lib(
+ std::unique_ptr<plib::dynamic_library_base> &&lib)
{
m_lib = std::move(lib);
}
@@ -225,16 +247,20 @@ namespace netlist
void netlist_state_t::rebuild_lists()
{
- for (auto & net : m_nets)
+ for (auto &net : m_nets)
net->rebuild_list();
}
- void netlist_state_t::compile_defines(std::vector<std::pair<pstring, pstring>> &defs)
+ void netlist_state_t::compile_defines(
+ std::vector<std::pair<pstring, pstring>> &defs)
{
- #define ENTRY(x) if (pstring(#x) != PSTRINGIFY(x)) \
- defs.emplace_back(std::pair<pstring, pstring>(#x, PSTRINGIFY(x))); \
- else defs.emplace_back(std::pair<pstring, pstring>(#x, "<NOT DEFINED>"));
- #define ENTRY_EX(x) defs.emplace_back(std::pair<pstring, pstring>(#x, plib::pfmt("{}")(x)));
+#define ENTRY(x) \
+ if (pstring(#x) != PSTRINGIFY(x)) \
+ defs.emplace_back(std::pair<pstring, pstring>(#x, PSTRINGIFY(x))); \
+ else \
+ defs.emplace_back(std::pair<pstring, pstring>(#x, "<NOT DEFINED>"));
+#define ENTRY_EX(x) \
+ defs.emplace_back(std::pair<pstring, pstring>(#x, plib::pfmt("{}")(x)));
ENTRY(NL_VERSION_MAJOR)
ENTRY(NL_VERSION_MINOR)
ENTRY(NL_VERSION_PATCHLEVEL)
@@ -267,10 +293,10 @@ namespace netlist
ENTRY(__clang_patchlevel__)
ENTRY(__clang_version__)
- ENTRY(OPENMP )
- ENTRY(_OPENMP )
+ ENTRY(OPENMP)
+ ENTRY(_OPENMP)
- ENTRY(__x86_64__ )
+ ENTRY(__x86_64__)
ENTRY(__i386__)
ENTRY(_WIN32)
ENTRY(_MSC_VER)
@@ -295,8 +321,8 @@ namespace netlist
ENTRY(PPMF_FORCE_TYPE)
ENTRY(PHAS_PMF_INTERNAL)
- #undef ENTRY
- #undef ENTRY_EX
+#undef ENTRY
+#undef ENTRY_EX
}
pstring netlist_state_t::version()
@@ -306,24 +332,22 @@ namespace netlist
pstring netlist_state_t::version_patchlevel()
{
- return plib::pfmt("{1}.{2}.{3}")(NL_VERSION_MAJOR, NL_VERSION_MINOR, NL_VERSION_PATCHLEVEL);
+ return plib::pfmt("{1}.{2}.{3}")(NL_VERSION_MAJOR, NL_VERSION_MINOR,
+ NL_VERSION_PATCHLEVEL);
}
- void netlist_state_t::free_setup_resources()
- {
- m_setup = nullptr;
- }
+ void netlist_state_t::free_setup_resources() { m_setup = nullptr; }
void netlist_state_t::reset()
{
// Reset all nets once !
log().verbose("Call reset on all nets:");
- for (auto & n : nets())
+ for (auto &n : nets())
n->reset();
// Reset all devices once !
log().verbose("Call reset on all devices:");
- for (auto & dev : m_devices)
+ for (auto &dev : m_devices)
dev.second->reset();
// Make sure everything depending on parameters is set
@@ -332,7 +356,7 @@ namespace netlist
std::vector<core_device_t *> devices_called;
log().verbose("Call update_param on all devices:");
- for (auto & dev : m_devices)
+ for (auto &dev : m_devices)
{
dev.second->update_param();
if (!plib::container::contains(devices_called, dev.second.get()))
@@ -344,7 +368,8 @@ namespace netlist
// INFO: The order here affects power up of e.g. breakout. However, such
// variations are explicitly stated in the breakout manual.
- auto *netlist_params = get_single_device<devices::NETLIB_NAME(netlistparams)>("parameter");
+ auto *netlist_params = get_single_device<
+ devices::NETLIB_NAME(netlistparams)>("parameter");
switch (netlist_params->m_startup_strategy())
{
@@ -354,8 +379,9 @@ namespace netlist
log().verbose("Using default startup strategy");
for (auto &n : m_nets)
{
- n->update_inputs(); // only used if USE_COPY_INSTEAD_OF_REFERENCE == 1
- for (detail::core_terminal_t * term : n->core_terms_copy())
+ n->update_inputs(); // only used if
+ // USE_COPY_INSTEAD_OF_REFERENCE == 1
+ for (detail::core_terminal_t *term : n->core_terms_copy())
{
if (!plib::container::contains(t, &term->delegate()))
{
@@ -363,19 +389,22 @@ namespace netlist
term->run_delegate();
}
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- auto *dev = reinterpret_cast<core_device_t *>(term->delegate().object());
+ auto *dev = reinterpret_cast<core_device_t *>(
+ term->delegate().object());
if (!plib::container::contains(devices_called, dev))
devices_called.push_back(dev);
}
}
log().verbose("Devices not yet updated:");
for (auto &dev : m_devices)
- if (!plib::container::contains(devices_called, dev.second.get()))
+ if (!plib::container::contains(devices_called,
+ dev.second.get()))
{
// FIXME: doesn't seem to be needed, use cases include
// analog output devices. Check and remove
- log().error("\t Device {1} not yet updated", dev.second->name());
- //dev.second->update();
+ log().error("\t Device {1} not yet updated",
+ dev.second->name());
+ // dev.second->update();
}
}
break;
@@ -383,40 +412,52 @@ namespace netlist
// the above may screw up m_active and the list
rebuild_lists();
-
}
void netlist_state_t::print_stats(stats_info &si) const
{
std::vector<size_t> index;
- for (size_t i=0; i < this->m_devices.size(); i++)
+ for (size_t i = 0; i < this->m_devices.size(); i++)
index.push_back(i);
std::sort(index.begin(), index.end(),
- [&](size_t i1, size_t i2) { return this->m_devices[i1].second->stats()->m_stat_total_time.total() < this->m_devices[i2].second->stats()->m_stat_total_time.total(); });
-
- plib::pperftime_t<true>::type total_time(0);
+ [&](size_t i1, size_t i2)
+ {
+ return this->m_devices[i1]
+ .second->stats()
+ ->m_stat_total_time.total()
+ < this->m_devices[i2]
+ .second->stats()
+ ->m_stat_total_time.total();
+ });
+
+ plib::pperftime_t<true>::type total_time(0);
plib::pperftime_t<true>::ctype total_count(0);
- for (auto & j : index)
+ for (auto &j : index)
{
auto *entry = this->m_devices[j].second.get();
auto *stats = entry->stats();
- log().verbose("Device {1:20} : {2:12} {3:12} {4:15} {5:12}", entry->name(),
- stats->m_stat_call_count(), stats->m_stat_total_time.count(),
- stats->m_stat_total_time.total(), stats->m_stat_inc_active());
+ log().verbose("Device {1:20} : {2:12} {3:12} {4:15} {5:12}",
+ entry->name(), stats->m_stat_call_count(),
+ stats->m_stat_total_time.count(),
+ stats->m_stat_total_time.total(), stats->m_stat_inc_active());
total_time += stats->m_stat_total_time.total();
total_count += stats->m_stat_total_time.count();
}
log().verbose("Total calls : {1:12} {2:12} {3:12}", total_count,
- total_time, total_time / gsl::narrow<decltype(total_time)>((total_count > 0) ? total_count : 1));
+ total_time,
+ total_time
+ / gsl::narrow<decltype(total_time)>(
+ (total_count > 0) ? total_count : 1));
log().verbose("Total loop {1:15}", si.m_stat_mainloop());
log().verbose("Total time {1:15}", total_time);
// FIXME: clang complains about unreachable code without
- const bool clang_workaround_unreachable_code(config::use_queue_stats::value);
+ const bool clang_workaround_unreachable_code(
+ config::use_queue_stats::value);
if (clang_workaround_unreachable_code)
{
// Only one serialization should be counted in total time
@@ -425,26 +466,32 @@ namespace netlist
plib::pperftime_t<true> test;
{
auto overhead_guard(overhead.guard());
- for (int j=0; j<100000;j++)
+ for (int j = 0; j < 100000; j++)
{
auto test_guard(test.guard());
}
}
- plib::pperftime_t<true>::type total_overhead = overhead()
- * gsl::narrow<plib::pperftime_t<true>::type>(total_count)
- / gsl::narrow<plib::pperftime_t<true>::type>(200000);
+ plib::pperftime_t<true>::type total_overhead
+ = overhead()
+ * gsl::narrow<plib::pperftime_t<true>::type>(total_count)
+ / gsl::narrow<plib::pperftime_t<true>::type>(200000);
log().verbose("Queue Pushes {1:15}", si.m_queue.m_prof_call());
- log().verbose("Queue Moves {1:15}", si.m_queue.m_prof_sort_move());
+ log().verbose("Queue Moves {1:15}",
+ si.m_queue.m_prof_sort_move());
log().verbose("Queue Removes {1:15}", si.m_queue.m_prof_remove());
log().verbose("");
- log().verbose("Take the next lines with a grain of salt. They depend on the measurement implementation.");
+ log().verbose(
+ "Take the next lines with a grain of salt. They depend on the measurement implementation.");
log().verbose("Total overhead {1:15}", total_overhead);
- plib::pperftime_t<true>::type overhead_per_pop = (si.m_stat_mainloop()-2*total_overhead - (total_time - total_overhead))
- / gsl::narrow<plib::pperftime_t<true>::type>(si.m_queue.m_prof_call());
- log().verbose("Overhead per pop {1:11}", overhead_per_pop );
+ plib::pperftime_t<true>::type overhead_per_pop
+ = (si.m_stat_mainloop() - 2 * total_overhead
+ - (total_time - total_overhead))
+ / gsl::narrow<plib::pperftime_t<true>::type>(
+ si.m_queue.m_prof_call());
+ log().verbose("Overhead per pop {1:11}", overhead_per_pop);
log().verbose("");
}
@@ -454,16 +501,21 @@ namespace netlist
auto *ep = entry.second.get();
auto *stats = ep->stats();
// Factor of 3 offers best performance increase
- if (stats->m_stat_inc_active() > 3 * stats->m_stat_total_time.count()
+ if (stats->m_stat_inc_active()
+ > 3 * stats->m_stat_total_time.count()
&& stats->m_stat_inc_active() > trigger)
log().verbose("HINT({}, NO_DEACTIVATE) // {} {} {}", ep->name(),
- gsl::narrow<nl_fptype>(stats->m_stat_inc_active()) / gsl::narrow<nl_fptype>(stats->m_stat_total_time.count()),
- stats->m_stat_inc_active(), stats->m_stat_total_time.count());
+ gsl::narrow<nl_fptype>(stats->m_stat_inc_active())
+ / gsl::narrow<nl_fptype>(
+ stats->m_stat_total_time.count()),
+ stats->m_stat_inc_active(),
+ stats->m_stat_total_time.count());
}
log().verbose("");
}
- core_device_t *netlist_state_t::get_single_device(const pstring &classname, bool (*cc)(core_device_t *)) const
+ core_device_t *netlist_state_t::get_single_device(const pstring &classname,
+ bool (*cc)(core_device_t *)) const
{
core_device_t *ret = nullptr;
for (const auto &d : m_devices)
@@ -473,7 +525,8 @@ namespace netlist
if (ret != nullptr)
{
m_log.fatal(MF_MORE_THAN_ONE_1_DEVICE_FOUND(classname));
- throw nl_exception(MF_MORE_THAN_ONE_1_DEVICE_FOUND(classname));
+ throw nl_exception(
+ MF_MORE_THAN_ONE_1_DEVICE_FOUND(classname));
}
ret = d.second.get();
}
@@ -481,8 +534,11 @@ namespace netlist
return ret;
}
- nlparse_t &netlist_state_t::parser() { return m_setup->parser(); }
- const nlparse_t &netlist_state_t::parser() const { return m_setup->parser(); }
+ nlparse_t &netlist_state_t::parser() noexcept { return m_setup->parser(); }
+ const nlparse_t &netlist_state_t::parser() const noexcept
+ {
+ return m_setup->parser();
+ }
void netlist_state_t::remove_device(core_device_t *dev)
{
@@ -495,50 +551,32 @@ namespace netlist
}
}
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// core_device_t
- // ----------------------------------------------------------------------------------------
-
- core_device_t::core_device_t(netlist_state_t &owner, const pstring &name)
- : netlist_object_t(owner.exec(), name)
- , m_hint_deactivate(false)
- , m_active_outputs(*this, "m_active_outputs", 1)
- {
- if (exec().stats_enabled())
- m_stats = owner.make_pool_object<stats_t>();
- }
+ // -------------------------------------------------------------------------
- core_device_t::core_device_t(core_device_t &owner, const pstring &name)
- : netlist_object_t(owner.state().exec(), owner.name() + "." + name)
- , m_hint_deactivate(false)
- , m_active_outputs(*this, "m_active_outputs", 1)
+ core_device_t::core_device_t(core_device_param_t data)
+ : netlist_object_t(data.owner.exec(), data.name)
+ , m_hint_deactivate(false)
+ , m_active_outputs(*this, "m_active_outputs", 1)
{
- //printf("owned device: %s\n", this->name().c_str());
- owner.state().register_device(this->name(), device_arena::owned_ptr<core_device_t>(this, false));
if (exec().stats_enabled())
- m_stats = owner.state().make_pool_object<stats_t>();
+ m_stats = state().make_pool_object<stats_t>();
}
- log_type & core_device_t::log()
- {
- return state().log();
- }
+ log_type &core_device_t::log() { return state().log(); }
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// base_device_t
- // ----------------------------------------------------------------------------------------
-
- base_device_t::base_device_t(netlist_state_t &owner, const pstring &name)
- : core_device_t(owner, name)
- {
- }
+ // -------------------------------------------------------------------------
- base_device_t::base_device_t(base_device_t &owner, const pstring &name)
- : core_device_t(owner, name)
+ base_device_t::base_device_t(base_device_param_t data)
+ : core_device_t(data)
{
}
- void base_device_t::register_sub_alias(const pstring &name, const detail::core_terminal_t &term)
+ void base_device_t::register_sub_alias(const pstring &name,
+ const detail::core_terminal_t & term)
{
pstring alias = this->name() + "." + name;
@@ -546,7 +584,8 @@ namespace netlist
state().parser().register_alias_no_fqn(alias, term.name());
}
- void base_device_t::register_sub_alias(const pstring &name, const pstring &aliased)
+ void base_device_t::register_sub_alias(const pstring &name,
+ const pstring & aliased)
{
pstring alias = this->name() + "." + name;
pstring aliased_fqn = this->name() + "." + aliased;
@@ -555,23 +594,24 @@ namespace netlist
state().parser().register_alias_no_fqn(alias, aliased_fqn);
}
- void base_device_t::connect(const detail::core_terminal_t &t1, const detail::core_terminal_t &t2)
+ void base_device_t::connect(const detail::core_terminal_t &t1,
+ const detail::core_terminal_t & t2)
{
state().parser().register_link_fqn(t1.name(), t2.name());
}
void base_device_t::connect(const pstring &t1, const pstring &t2)
{
- state().parser().register_link_fqn(name() + "." + t1, name() + "." + t2);
+ state().parser().register_link_fqn(name() + "." + t1,
+ name() + "." + t2);
}
-
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// device_t
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
- device_t::device_t(netlist_state_t &owner, const pstring &name)
- : base_device_t(owner, name)
+ device_t::device_t(device_param_t data)
+ : base_device_t(data)
, m_model(*this, "MODEL", pstring(config::DEFAULT_LOGIC_FAMILY()))
{
set_logic_family(state().setup().family_from_model(m_model()));
@@ -579,9 +619,8 @@ namespace netlist
throw nl_exception(MF_NULLPTR_FAMILY(this->name(), m_model()));
}
- device_t::device_t(netlist_state_t &owner, const pstring &name,
- const pstring &model)
- : base_device_t(owner, name)
+ device_t::device_t(device_param_t data, const pstring &model)
+ : base_device_t(data)
, m_model(*this, "MODEL", model)
{
set_logic_family(state().setup().family_from_model(m_model()));
@@ -589,67 +628,50 @@ namespace netlist
throw nl_exception(MF_NULLPTR_FAMILY(this->name(), m_model()));
}
- device_t::device_t(netlist_state_t &owner, const pstring &name,
- const logic_family_desc_t *desc)
- : base_device_t(owner, name)
+ device_t::device_t(device_param_t data, const logic_family_desc_t *desc)
+ : base_device_t(data)
, m_model(*this, "MODEL", pstring(""))
{
set_logic_family(desc);
if (logic_family() == nullptr)
- throw nl_exception(MF_NULLPTR_FAMILY(this->name(), "<pointer provided by constructor>"));
- }
-
- device_t::device_t(device_t &owner, const pstring &name)
- : base_device_t(owner, name)
- , m_model(*this, "MODEL", pstring(""))
- {
- set_logic_family(owner.logic_family());
- if (logic_family() == nullptr)
- throw nl_exception(MF_NULLPTR_FAMILY(this->name(), "<owner logic family>"));
+ throw nl_exception(MF_NULLPTR_FAMILY(this->name(),
+ "<pointer provided by constructor>"));
}
- device_t::device_t(device_t &owner, const pstring &name, const pstring &model)
- : base_device_t(owner, name)
- , m_model(*this, "MODEL", model)
- {
- set_logic_family(state().setup().family_from_model(m_model()));
- if (logic_family() == nullptr)
- throw nl_exception(MF_NULLPTR_FAMILY(this->name(), m_model()));
- }
-
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// analog_t
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
- analog_t::analog_t(core_device_t &dev, const pstring &aname, const state_e state,
- nl_delegate delegate)
+ analog_t::analog_t(core_device_t &dev, const pstring &aname,
+ const state_e state, nl_delegate delegate)
: core_terminal_t(dev, aname, state, delegate)
{
}
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// net_t
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
- detail::net_t::net_t(netlist_state_t &nl, const pstring &aname, core_terminal_t *rail_terminal)
- : netlist_object_t(nl.exec(), aname)
- , m_new_Q(*this, "m_new_Q", netlist_sig_t(0))
- , m_cur_Q (*this, "m_cur_Q", netlist_sig_t(0))
- , m_in_queue(*this, "m_in_queue", queue_status::DELIVERED)
- , m_next_scheduled_time(*this, "m_time", netlist_time_ext::zero())
- , m_rail_terminal(rail_terminal)
+ detail::net_t::net_t(netlist_state_t &nl, const pstring &aname,
+ core_terminal_t *rail_terminal)
+ : netlist_object_t(nl.exec(), aname)
+ , m_new_Q(*this, "m_new_Q", netlist_sig_t(0))
+ , m_cur_Q(*this, "m_cur_Q", netlist_sig_t(0))
+ , m_in_queue(*this, "m_in_queue", queue_status::DELIVERED)
+ , m_next_scheduled_time(*this, "m_time", netlist_time_ext::zero())
+ , m_rail_terminal(rail_terminal)
{
props::add(this, props::value_type());
}
bool detail::net_t::is_logic() const noexcept
{
- return dynamic_cast<const logic_net_t *>(this) != nullptr;
+ return bool(plib::dynamic_downcast<const logic_net_t *>(this));
}
bool detail::net_t::is_analog() const noexcept
{
- return dynamic_cast<const analog_net_t *>(this) != nullptr;
+ return bool(plib::dynamic_downcast<const analog_net_t *>(this));
}
void detail::net_t::rebuild_list()
@@ -657,7 +679,7 @@ namespace netlist
// rebuild m_list
m_list_active.clear();
- for (core_terminal_t * term : core_terms_ref())
+ for (core_terminal_t *term : core_terms_ref())
if (term->terminal_state() != logic_t::STATE_INP_PASSIVE)
{
m_list_active.push_back(term);
@@ -673,15 +695,13 @@ namespace netlist
m_new_Q = 0;
m_cur_Q = 0;
- auto *p = dynamic_cast<analog_net_t *>(this);
-
- if (p != nullptr)
- p->set_Q_Analog(nlconst::zero());
+ if (auto p = plib::dynamic_downcast<analog_net_t *>(this))
+ (*p)->set_Q_Analog(nlconst::zero());
// rebuild m_list and reset terminals to active or analog out state
m_list_active.clear();
- for (core_terminal_t * ct : core_terms_copy())
+ for (core_terminal_t *ct : core_terms_copy())
{
ct->reset();
if (ct->terminal_state() != logic_t::STATE_INP_PASSIVE)
@@ -696,18 +716,17 @@ namespace netlist
m_core_terms.remove(&term);
}
- void detail::net_t::remove_all_terminals()
- {
- m_core_terms.clear();
- }
+ void detail::net_t::remove_all_terminals() { m_core_terms.clear(); }
void detail::net_t::add_terminal(detail::core_terminal_t &terminal)
{
- for (detail::core_terminal_t * t : m_core_terms)
+ for (detail::core_terminal_t *t : m_core_terms)
if (t == &terminal)
{
- state().log().fatal(MF_NET_1_DUPLICATE_TERMINAL_2(this->name(), t->name()));
- throw nl_exception(MF_NET_1_DUPLICATE_TERMINAL_2(this->name(), t->name()));
+ state().log().fatal(
+ MF_NET_1_DUPLICATE_TERMINAL_2(this->name(), t->name()));
+ throw nl_exception(
+ MF_NET_1_DUPLICATE_TERMINAL_2(this->name(), t->name()));
}
terminal.set_net(this);
@@ -718,8 +737,9 @@ namespace netlist
#else
void detail::net_t::remove_terminal(detail::core_terminal_t &term)
{
- //net.core_terms().remove(p);
- for (auto pp = state().core_terms(*this).begin(); pp != state().core_terms(*this).end(); pp++)
+ // net.core_terms().remove(p);
+ for (auto pp = state().core_terms(*this).begin();
+ pp != state().core_terms(*this).end(); pp++)
if (*pp == &term)
{
state().core_terms(*this).erase(pp);
@@ -734,11 +754,13 @@ namespace netlist
void detail::net_t::add_terminal(detail::core_terminal_t &terminal)
{
- for (detail::core_terminal_t * t : state().core_terms(*this))
+ for (detail::core_terminal_t *t : core_terms_ref())
if (t == &terminal)
{
- state().log().fatal(MF_NET_1_DUPLICATE_TERMINAL_2(this->name(), t->name()));
- throw nl_exception(MF_NET_1_DUPLICATE_TERMINAL_2(this->name(), t->name()));
+ state().log().fatal(
+ MF_NET_1_DUPLICATE_TERMINAL_2(this->name(), t->name()));
+ throw nl_exception(
+ MF_NET_1_DUPLICATE_TERMINAL_2(this->name(), t->name()));
}
terminal.set_net(this);
@@ -747,23 +769,25 @@ namespace netlist
}
#endif
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// logic_net_t
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
- logic_net_t::logic_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *rail_terminal)
- : net_t(nl, aname, rail_terminal)
+ logic_net_t::logic_net_t(netlist_state_t &nl, const pstring &aname,
+ detail::core_terminal_t *rail_terminal)
+ : net_t(nl, aname, rail_terminal)
{
}
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// analog_net_t
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
- analog_net_t::analog_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *rail_terminal)
- : net_t(nl, aname, rail_terminal)
- , m_cur_Analog(*this, "m_cur_Analog", nlconst::zero())
- , m_solver(nullptr)
+ analog_net_t::analog_net_t(netlist_state_t &nl, const pstring &aname,
+ detail::core_terminal_t *rail_terminal)
+ : net_t(nl, aname, rail_terminal)
+ , m_cur_Analog(*this, "m_cur_Analog", nlconst::zero())
+ , m_solver(nullptr)
{
}
@@ -773,12 +797,12 @@ namespace netlist
m_cur_Analog = nlconst::zero();
}
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// core_terminal_t
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
- detail::core_terminal_t::core_terminal_t(core_device_t &dev, const pstring &aname,
- const state_e state, nl_delegate delegate)
+ detail::core_terminal_t::core_terminal_t(core_device_t &dev,
+ const pstring &aname, const state_e state, nl_delegate delegate)
: device_object_t(&dev, dev.name() + "." + aname)
, m_Q_CIR(*this, "m_Q", 0)
, m_delegate(delegate)
@@ -789,52 +813,52 @@ namespace netlist
bool detail::core_terminal_t::is_logic() const noexcept
{
- return dynamic_cast<const logic_t *>(this) != nullptr;
+ return bool(plib::dynamic_downcast<const logic_t *>(this));
}
bool detail::core_terminal_t::is_logic_input() const noexcept
{
- return dynamic_cast<const logic_input_t *>(this) != nullptr;
+ return bool(plib::dynamic_downcast<const logic_input_t *>(this));
}
bool detail::core_terminal_t::is_logic_output() const noexcept
{
- return dynamic_cast<const logic_output_t *>(this) != nullptr;
+ return bool(plib::dynamic_downcast<const logic_output_t *>(this));
}
bool detail::core_terminal_t::is_tristate_output() const noexcept
{
- return dynamic_cast<const tristate_output_t *>(this) != nullptr;
+ return bool(plib::dynamic_downcast<const tristate_output_t *>(this));
}
bool detail::core_terminal_t::is_analog() const noexcept
{
- return dynamic_cast<const analog_t *>(this) != nullptr;
+ return bool(plib::dynamic_downcast<const analog_t *>(this));
}
bool detail::core_terminal_t::is_analog_input() const noexcept
{
- return dynamic_cast<const analog_input_t *>(this) != nullptr;
+ return bool(plib::dynamic_downcast<const analog_input_t *>(this));
}
bool detail::core_terminal_t::is_analog_output() const noexcept
{
- return dynamic_cast<const analog_output_t *>(this) != nullptr;
+ return bool(plib::dynamic_downcast<const analog_output_t *>(this));
}
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// terminal_t
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
terminal_t::terminal_t(core_device_t &dev, const pstring &aname,
terminal_t *other_terminal, nl_delegate delegate)
- : terminal_t(dev, aname, other_terminal, { nullptr, nullptr }, delegate)
+ : terminal_t(dev, aname, other_terminal, {nullptr, nullptr}, delegate)
{
}
terminal_t::terminal_t(core_device_t &dev, const pstring &aname,
- terminal_t *other_terminal, const std::array<terminal_t *, 2> &splitter_terms,
- nl_delegate delegate)
+ terminal_t * other_terminal,
+ const std::array<terminal_t *, 2> &splitter_terms, nl_delegate delegate)
: analog_t(dev, aname, STATE_BIDIR, delegate)
, m_Idr(nullptr)
, m_go(nullptr)
@@ -843,12 +867,15 @@ namespace netlist
state().setup().register_term(*this, other_terminal, splitter_terms);
}
- void terminal_t::set_ptrs(nl_fptype *gt, nl_fptype *go, nl_fptype *Idr) noexcept(false)
+ void terminal_t::set_ptrs(nl_fptype *gt, nl_fptype *go,
+ nl_fptype *Idr) noexcept(false)
{
// NOLINTNEXTLINE(readability-implicit-bool-conversion)
if (!(gt && go && Idr) && (gt || go || Idr))
{
- throw nl_exception("Either all pointers must be set or none for terminal {}", name());
+ throw nl_exception(
+ "Either all pointers must be set or none for terminal {}",
+ name());
}
m_gt = gt;
@@ -856,46 +883,40 @@ namespace netlist
m_Idr = Idr;
}
- // ----------------------------------------------------------------------------------------
- // net_input_t
- // ----------------------------------------------------------------------------------------
-
- // ----------------------------------------------------------------------------------------
- // net_output_t
- // ----------------------------------------------------------------------------------------
-
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// logic_t
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
- logic_t::logic_t(device_t &dev, const pstring &aname, const state_e terminal_state,
- nl_delegate delegate)
- : core_terminal_t(dev, aname, terminal_state, delegate)
- , logic_family_t(dev.logic_family())
+ logic_t::logic_t(device_t &dev, const pstring &aname,
+ const state_e terminal_state, nl_delegate delegate)
+ : core_terminal_t(dev, aname, terminal_state, delegate)
+ , logic_family_t(dev.logic_family())
{
}
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// logic_input_t
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
logic_input_t::logic_input_t(device_t &dev, const pstring &aname,
- nl_delegate delegate)
- : logic_t(dev, aname, STATE_INP_ACTIVE, delegate)
+ nl_delegate delegate)
+ : logic_t(dev, aname, STATE_INP_ACTIVE, delegate)
{
state().setup().register_term(*this);
}
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// logic_output_t
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
- logic_output_t::logic_output_t(device_t &dev, const pstring &aname, [[maybe_unused]] bool dummy)
- : logic_t(dev, aname, STATE_OUT, nl_delegate())
- , m_my_net(dev.state(), name() + ".net", this)
+ logic_output_t::logic_output_t(device_t &dev, const pstring &aname,
+ [[maybe_unused]] bool dummy)
+ : logic_t(dev, aname, STATE_OUT, nl_delegate())
+ , m_my_net(dev.state(), name() + ".net", this)
{
this->set_net(&m_my_net);
- state().register_net(device_arena::owned_ptr<logic_net_t>(&m_my_net, false));
+ state().register_net(
+ device_arena::owned_ptr<logic_net_t>(&m_my_net, false));
state().setup().register_term(*this);
}
@@ -905,20 +926,23 @@ namespace netlist
net().initial(val);
}
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// tristate_output_t
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
- tristate_output_t::tristate_output_t(device_t &dev, const pstring &aname, bool force_logic)
+ tristate_output_t::tristate_output_t(device_t &dev, const pstring &aname,
+ bool force_logic)
: logic_output_t(dev, aname)
, m_last_logic(dev, name() + "." + "m_last_logic", 1) // force change
- , m_tristate(dev, name() + "." + "m_tristate", force_logic ? 0 : 2) // force change
+ , m_tristate(dev, name() + "." + "m_tristate",
+ force_logic ? 0 : 2) // force change
, m_force_logic(force_logic)
- {}
+ {
+ }
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// analog_input_t
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
analog_input_t::analog_input_t(core_device_t &dev, const pstring &aname,
nl_delegate delegate)
@@ -927,18 +951,19 @@ namespace netlist
state().setup().register_term(*this);
}
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// analog_output_t
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
analog_output_t::analog_output_t(core_device_t &dev, const pstring &aname)
- : analog_t(dev, aname, STATE_OUT, nl_delegate())
- , m_my_net(dev.state(), name() + ".net", this)
+ : analog_t(dev, aname, STATE_OUT, nl_delegate())
+ , m_my_net(dev.state(), name() + ".net", this)
{
- state().register_net(device_arena::owned_ptr<analog_net_t>(&m_my_net, false));
+ state().register_net(
+ device_arena::owned_ptr<analog_net_t>(&m_my_net, false));
this->set_net(&m_my_net);
- //net().m_cur_Analog = NL_FCONST(0.0);
+ // net().m_cur_Analog = NL_FCONST(0.0);
state().setup().register_term(*this);
}
@@ -947,18 +972,18 @@ namespace netlist
net().set_Q_Analog(val);
}
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// Parameters ...
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// device-less, it's the responsibility of the owner to register!
param_t::param_t(const pstring &name)
- : device_object_t(nullptr, name)
+ : device_object_t(nullptr, name)
{
}
param_t::param_t(core_device_t &device, const pstring &name)
- : device_object_t(&device, device.name() + "." + name)
+ : device_object_t(&device, device.name() + "." + name)
{
device.state().setup().register_param_t(*this);
}
@@ -968,57 +993,57 @@ namespace netlist
param_t::param_type_t param_t::param_type() const noexcept(false)
{
- if (dynamic_cast<const param_str_t *>(this) != nullptr)
+ if (plib::dynamic_downcast<const param_str_t *>(this))
return STRING;
- if (dynamic_cast<const param_fp_t *>(this) != nullptr)
+ if (plib::dynamic_downcast<const param_fp_t *>(this))
return DOUBLE;
- if (dynamic_cast<const param_int_t *>(this) != nullptr)
+ if (plib::dynamic_downcast<const param_int_t *>(this))
return INTEGER;
- if (dynamic_cast<const param_logic_t *>(this) != nullptr)
+ if (plib::dynamic_downcast<const param_logic_t *>(this))
return LOGIC;
- if (dynamic_cast<const param_ptr_t *>(this) != nullptr)
+ if (plib::dynamic_downcast<const param_ptr_t *>(this))
return POINTER;
state().log().fatal(MF_UNKNOWN_PARAM_TYPE(name()));
throw nl_exception(MF_UNKNOWN_PARAM_TYPE(name()));
}
-
pstring param_t::get_initial(const core_device_t *dev, bool *found) const
{
- pstring res = dev->state().setup().get_initial_param_val(this->name(), "");
+ pstring res = dev->state().setup().get_initial_param_val(this->name(),
+ "");
*found = (!res.empty());
return res;
}
- param_str_t::param_str_t(core_device_t &device, const pstring &name, const pstring &val)
+ param_str_t::param_str_t(core_device_t &device, const pstring &name,
+ const pstring &val)
: param_t(device, name)
{
m_param = plib::make_unique<pstring, host_arena>(val);
- *m_param = device.state().setup().get_initial_param_val(this->name(),val);
+ *m_param = device.state().setup().get_initial_param_val(this->name(),
+ val);
}
- param_str_t::param_str_t(netlist_state_t &state, const pstring &name, const pstring &val)
+ param_str_t::param_str_t(netlist_state_t &state, const pstring &name,
+ const pstring &val)
: param_t(name)
{
// device-less parameter, no registration, owner is responsible
m_param = plib::make_unique<pstring, host_arena>(val);
- *m_param = state.setup().get_initial_param_val(this->name(),val);
+ *m_param = state.setup().get_initial_param_val(this->name(), val);
}
- void param_str_t::changed() noexcept
- {
- }
+ void param_str_t::changed() noexcept {}
- param_ptr_t::param_ptr_t(core_device_t &device, const pstring &name, uint8_t * val)
+ param_ptr_t::param_ptr_t(core_device_t &device, const pstring &name,
+ uint8_t *val)
: param_t(device, name)
, m_param(val)
{
}
- void param_model_t::changed() noexcept
- {
- }
+ void param_model_t::changed() noexcept {}
pstring param_model_t::type()
{
@@ -1041,13 +1066,13 @@ namespace netlist
return device().state().parser().get_data_stream(str());
}
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// netlist_t
//
// Hot section
//
// Any changes below will impact performance.
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
template <bool KEEP_STATS>
void netlist_t::process_queue_stats(const netlist_time_ext delta) noexcept
@@ -1075,9 +1100,9 @@ namespace netlist
}
else
{
- logic_net_t &mc_net(m_main_clock->m_Q.net());
+ logic_net_t & mc_net(m_main_clock->m_Q.net());
const netlist_time inc(m_main_clock->m_inc);
- netlist_time_ext mc_time(mc_net.next_scheduled_time());
+ netlist_time_ext mc_time(mc_net.next_scheduled_time());
do
{
diff --git a/src/lib/netlist/nl_config.h b/src/lib/netlist/nl_config.h
index c19fe296aa7..01bc99dc706 100644
--- a/src/lib/netlist/nl_config.h
+++ b/src/lib/netlist/nl_config.h
@@ -18,22 +18,22 @@
///
/// \brief Version - Major.
///
-#define NL_VERSION_MAJOR 0
+#define NL_VERSION_MAJOR 0
///
/// \brief Version - Minor.
///
-#define NL_VERSION_MINOR 14
+#define NL_VERSION_MINOR 14
/// \brief Version - Patch level.
///
-#define NL_VERSION_PATCHLEVEL 0
+#define NL_VERSION_PATCHLEVEL 0
///
/// \addtogroup compiledefine
/// \{
-//============================================================
-// GENERAL
-//============================================================
+// -----------------------------------------------------------------------------
+// General
+// -----------------------------------------------------------------------------
/// \brief Compile in academic solvers
///
@@ -48,20 +48,19 @@
/// time significantly.
///
#ifndef NL_USE_ACADEMIC_SOLVERS
-#define NL_USE_ACADEMIC_SOLVERS (1)
+ #define NL_USE_ACADEMIC_SOLVERS (1)
#endif
/// \brief Use backward Euler integration
///
/// This will use backward Euler instead of trapezoidal integration.
///
-/// FIXME: Long term this will become a runtime setting. Only the capacitor model
-/// currently has a trapezoidal version and there is no support currently for
-/// variable capacitors.
-/// The change will have impact on timings since trapezoidal improves timing
-/// accuracy.
+/// FIXME: Long term this will become a runtime setting. Only the capacitor
+/// model currently has a trapezoidal version and there is no support currently
+/// for variable capacitors. The change will have impact on timings since
+/// trapezoidal improves timing accuracy.
#ifndef NL_USE_BACKWARD_EULER
-#define NL_USE_BACKWARD_EULER (1) // FIXME: Move to config struct later
+ #define NL_USE_BACKWARD_EULER (1) // FIXME: Move to config struct later
#endif
/// \brief Compile with core terminals owned by net_t
@@ -78,7 +77,7 @@
/// By default the setting is currently disabled.
///
#ifndef NL_USE_INPLACE_CORE_TERMS
-#define NL_USE_INPLACE_CORE_TERMS (0)
+ #define NL_USE_INPLACE_CORE_TERMS (0)
#endif
/// \brief Use alternative truth table execution approach
@@ -90,26 +89,25 @@
/// Unfortunately this has to be macro since it needs another member variable.
///
#ifndef NL_USE_TT_ALTERNATIVE
-#define NL_USE_TT_ALTERNATIVE (0)
+ #define NL_USE_TT_ALTERNATIVE (0)
#endif
/// \brief Compile matrix solvers using the __float128 type.
///
/// Defaults to \ref PUSE_FLOAT128
#ifndef NL_USE_FLOAT128
-#define NL_USE_FLOAT128 PUSE_FLOAT128
+ #define NL_USE_FLOAT128 PUSE_FLOAT128
#endif
-
-//============================================================
+// -----------------------------------------------------------------------------
// DEBUGGING
-//============================================================
+// -----------------------------------------------------------------------------
/// \brief Enable compile time debugging code
///
#ifndef NL_DEBUG
-#define NL_DEBUG (false)
+ #define NL_DEBUG (false)
#endif
///
@@ -118,9 +116,9 @@
namespace netlist
{
- //============================================================
- // GENERAL
- //============================================================
+ // -------------------------------------------------------------------------
+ // GENERAL
+ // -------------------------------------------------------------------------
struct config_default
{
@@ -136,10 +134,11 @@ namespace netlist
/// brief default minimum alignment of mempool_arena
///
/// 256 is the best compromise between logic applications like MAME
- /// TTL games (e.g. pong) and analog applications like e.g. kidnikik sound.
+ /// TTL games (e.g. pong) and analog applications like e.g. kidnikik
+ /// sound.
///
- /// Best performance for pong is achieved with a value of 16, but this degrades
- /// kidniki performance by ~10%.
+ /// Best performance for pong is achieved with a value of 16, but this
+ /// degrades kidniki performance by ~10%.
///
/// More work is needed here.
using mempool_align = std::integral_constant<std::size_t, 16>;
@@ -159,9 +158,9 @@ namespace netlist
///
using use_queue_stats = std::integral_constant<bool, false>;
- //============================================================
+ // ---------------------------------------------------------------------
// Time resolution
- //============================================================
+ // ---------------------------------------------------------------------
/// \brief Resolution as clocks per second for timing
///
@@ -178,15 +177,17 @@ namespace netlist
/// | 63 | 100,000,000,000 | 92,233,720 | 1,068| 2.9 |
/// | 63 | 1,000,000,000,000 | 9,223,372 | 107| 0.3 |
///
- using INTERNAL_RES = std::integral_constant<long long int, 10'000'000'000LL>; // NOLINT
+ using INTERNAL_RES = std::integral_constant<long long int,
+ 10'000'000'000LL>; // NOLINT
/// \brief Recommended clock to be used
///
- /// This is the recommended clock to be used in fixed clock applications limited
- /// to 32 bit clock resolution. The MAME code (netlist.cpp) contains code
- /// illustrating how to deal with remainders if \ref INTERNAL_RES is bigger than
- /// NETLIST_CLOCK.
- using DEFAULT_CLOCK = std::integral_constant<int, 1'000'000'000>; // NOLINT
+ /// This is the recommended clock to be used in fixed clock applications
+ /// limited to 32 bit clock resolution. The MAME code (netlist.cpp)
+ /// contains code illustrating how to deal with remainders if \ref
+ /// INTERNAL_RES is bigger than NETLIST_CLOCK.
+ using DEFAULT_CLOCK = std::integral_constant<int,
+ 1'000'000'000>; // NOLINT
/// \brief Default logic family
///
@@ -194,23 +195,28 @@ namespace netlist
/// \brief Maximum queue size
///
- using max_queue_size = std::integral_constant<std::size_t, 1024>; // NOLINT
+ using max_queue_size = std::integral_constant<std::size_t,
+ 1024>; // NOLINT
/// \brief Maximum queue size for solvers
///
- using max_solver_queue_size = std::integral_constant<std::size_t, 512>; // NOLINT
+ using max_solver_queue_size = std::integral_constant<std::size_t,
+ 512>; // NOLINT
/// \brief Support float type for matrix calculations.
///
/// Defaults to NL_USE_ACADEMIC_SOLVERS to provide faster build times
- using use_float_matrix = std::integral_constant<bool, NL_USE_ACADEMIC_SOLVERS>;
+ using use_float_matrix = std::integral_constant<bool,
+ NL_USE_ACADEMIC_SOLVERS>;
/// \brief Support long double type for matrix calculations.
///
/// Defaults to NL_USE_ACADEMIC_SOLVERS to provide faster build times
- using use_long_double_matrix = std::integral_constant<bool, NL_USE_ACADEMIC_SOLVERS>;
+ using use_long_double_matrix = std::integral_constant<bool,
+ NL_USE_ACADEMIC_SOLVERS>;
- using use_float128_matrix = std::integral_constant<bool, NL_USE_FLOAT128>;
+ using use_float128_matrix = std::integral_constant<bool,
+ NL_USE_FLOAT128>;
/// \brief Floating point types used
///
@@ -235,7 +241,8 @@ namespace netlist
/// By default it is disabled since it is not as fast as
/// the default approach. It is ~20% slower.
///
- using use_copy_instead_of_reference = std::integral_constant<bool, false>;
+ using use_copy_instead_of_reference = std::integral_constant<bool,
+ false>;
/// \brief Avoid unnecessary queue pushes
///
@@ -268,9 +275,10 @@ namespace netlist
///
struct config : public config_default
{
- //using mempool_align = std::integral_constant<std::size_t, 32>;
- //using avoid_noop_queue_pushes = std::integral_constant<bool, true>;
- //using use_copy_instead_of_reference = std::integral_constant<bool, true>;
+ // using mempool_align = std::integral_constant<std::size_t, 32>;
+ // using avoid_noop_queue_pushes = std::integral_constant<bool, true>;
+ // using use_copy_instead_of_reference = std::integral_constant<bool,
+ // true>;
};
using nl_fptype = config::fptype;
@@ -281,21 +289,34 @@ namespace netlist
///
template <typename FT>
struct fp_constants
- { };
+ {
+ };
/// \brief Specific constants for long double floating point type
///
template <>
struct fp_constants<long double>
{
- static constexpr long double DIODE_MAXDIFF() noexcept { return 1e100L; } // NOLINT
- static constexpr long double DIODE_MAXVOLT() noexcept { return 300.0L; } // NOLINT
-
- static constexpr long double TIMESTEP_MAXDIFF() noexcept { return 1e100L; } // NOLINT
- static constexpr long double TIMESTEP_MINDIV() noexcept { return 1e-60L; } // NOLINT
-
- static constexpr const char * name() noexcept { return "long double"; }
- static constexpr const char * suffix() noexcept { return "L"; }
+ static constexpr long double DIODE_MAXDIFF() noexcept
+ {
+ return 1e100L;
+ } // NOLINT
+ static constexpr long double DIODE_MAXVOLT() noexcept
+ {
+ return 300.0L;
+ } // NOLINT
+
+ static constexpr long double TIMESTEP_MAXDIFF() noexcept
+ {
+ return 1e100L;
+ } // NOLINT
+ static constexpr long double TIMESTEP_MINDIV() noexcept
+ {
+ return 1e-60L;
+ } // NOLINT
+
+ static constexpr const char *name() noexcept { return "long double"; }
+ static constexpr const char *suffix() noexcept { return "L"; }
};
/// \brief Specific constants for double floating point type
@@ -303,14 +324,26 @@ namespace netlist
template <>
struct fp_constants<double>
{
- static constexpr double DIODE_MAXDIFF() noexcept { return 1e100; } // NOLINT
- static constexpr double DIODE_MAXVOLT() noexcept { return 300.0; } // NOLINT
-
- static constexpr double TIMESTEP_MAXDIFF() noexcept { return 1e100; } // NOLINT
- static constexpr double TIMESTEP_MINDIV() noexcept { return 1e-60; } // NOLINT
-
- static constexpr const char * name() noexcept { return "double"; }
- static constexpr const char * suffix() noexcept { return ""; }
+ static constexpr double DIODE_MAXDIFF() noexcept
+ {
+ return 1e100;
+ } // NOLINT
+ static constexpr double DIODE_MAXVOLT() noexcept
+ {
+ return 300.0;
+ } // NOLINT
+
+ static constexpr double TIMESTEP_MAXDIFF() noexcept
+ {
+ return 1e100;
+ } // NOLINT
+ static constexpr double TIMESTEP_MINDIV() noexcept
+ {
+ return 1e-60;
+ } // NOLINT
+
+ static constexpr const char *name() noexcept { return "double"; }
+ static constexpr const char *suffix() noexcept { return ""; }
};
/// \brief Specific constants for float floating point type
@@ -318,14 +351,26 @@ namespace netlist
template <>
struct fp_constants<float>
{
- static constexpr float DIODE_MAXDIFF() noexcept { return 1e20F; } // NOLINT
- static constexpr float DIODE_MAXVOLT() noexcept { return 90.0F; } // NOLINT
-
- static constexpr float TIMESTEP_MAXDIFF() noexcept { return 1e30F; } // NOLINT
- static constexpr float TIMESTEP_MINDIV() noexcept { return 1e-8F; } // NOLINT
-
- static constexpr const char * name() noexcept { return "float"; }
- static constexpr const char * suffix() noexcept { return "f"; }
+ static constexpr float DIODE_MAXDIFF() noexcept
+ {
+ return 1e20F;
+ } // NOLINT
+ static constexpr float DIODE_MAXVOLT() noexcept
+ {
+ return 90.0F;
+ } // NOLINT
+
+ static constexpr float TIMESTEP_MAXDIFF() noexcept
+ {
+ return 1e30F;
+ } // NOLINT
+ static constexpr float TIMESTEP_MINDIV() noexcept
+ {
+ return 1e-8F;
+ } // NOLINT
+
+ static constexpr const char *name() noexcept { return "float"; }
+ static constexpr const char *suffix() noexcept { return "f"; }
};
#if (NL_USE_FLOAT128)
@@ -334,7 +379,7 @@ namespace netlist
template <>
struct fp_constants<FLOAT128>
{
-#if 0
+ #if 0
// MAME compile doesn't support Q
static constexpr FLOAT128 DIODE_MAXDIFF() noexcept { return 1e100Q; }
static constexpr FLOAT128 DIODE_MAXVOLT() noexcept { return 300.0Q; }
@@ -344,17 +389,29 @@ namespace netlist
static constexpr const char * name() noexcept { return "FLOAT128"; }
static constexpr const char * suffix() noexcept { return "Q"; }
-#else
- static constexpr FLOAT128 DIODE_MAXDIFF() noexcept { return static_cast<FLOAT128>(1e100L); }
- static constexpr FLOAT128 DIODE_MAXVOLT() noexcept { return static_cast<FLOAT128>(300.0L); }
-
- static constexpr FLOAT128 TIMESTEP_MAXDIFF() noexcept { return static_cast<FLOAT128>(1e100L); }
- static constexpr FLOAT128 TIMESTEP_MINDIV() noexcept { return static_cast<FLOAT128>(1e-60L); }
-
- static constexpr const char * name() noexcept { return "__float128"; }
- static constexpr const char * suffix() noexcept { return "Q"; }
-
-#endif
+ #else
+ static constexpr FLOAT128 DIODE_MAXDIFF() noexcept
+ {
+ return static_cast<FLOAT128>(1e100L);
+ }
+ static constexpr FLOAT128 DIODE_MAXVOLT() noexcept
+ {
+ return static_cast<FLOAT128>(300.0L);
+ }
+
+ static constexpr FLOAT128 TIMESTEP_MAXDIFF() noexcept
+ {
+ return static_cast<FLOAT128>(1e100L);
+ }
+ static constexpr FLOAT128 TIMESTEP_MINDIV() noexcept
+ {
+ return static_cast<FLOAT128>(1e-60L);
+ }
+
+ static constexpr const char *name() noexcept { return "__float128"; }
+ static constexpr const char *suffix() noexcept { return "Q"; }
+
+ #endif
};
#endif
} // namespace netlist
@@ -363,7 +420,12 @@ namespace netlist
// Asserts
//============================================================
-#define nl_assert(x) do { if (NL_DEBUG) passert_always(x); } while (0)
+#define nl_assert(x) \
+ do \
+ { \
+ if (NL_DEBUG) \
+ passert_always(x); \
+ } while (0)
#define nl_assert_always(x, msg) passert_always_msg(x, msg)
#endif // NLCONFIG_H_
diff --git a/src/lib/netlist/nl_errstr.h b/src/lib/netlist/nl_errstr.h
index bca9d5c93ce..46f2ac3e5e1 100644
--- a/src/lib/netlist/nl_errstr.h
+++ b/src/lib/netlist/nl_errstr.h
@@ -108,6 +108,7 @@ namespace netlist
PERRMSGV(MW_TERMINAL_1_WITHOUT_CONNECTIONS, 1, "Found terminal {1} without connections")
PERRMSGV(ME_TERMINAL_1_WITHOUT_NET, 1, "Found terminal {1} without a net")
+ PERRMSGV(ME_TERMINALS_1_2_WITHOUT_NET, 2, "Found terminals {1} and {2} without a net")
PERRMSGV(MF_TERMINALS_WITHOUT_NET, 0, "Found terminals without a net")
PERRMSGV(ME_TRISTATE_NO_PROXY_FOUND_2, 2,
"Tristate output {1} on device {2} is not connected to a proxy. You "
diff --git a/src/lib/netlist/nl_factory.cpp b/src/lib/netlist/nl_factory.cpp
index 2a1cde5bb42..6ab9e84cafd 100644
--- a/src/lib/netlist/nl_factory.cpp
+++ b/src/lib/netlist/nl_factory.cpp
@@ -5,26 +5,30 @@
/// \file nl_factory.cpp
///
-#include "nl_errstr.h"
#include "nl_factory.h"
+
+#include "nl_errstr.h"
#include "nl_setup.h"
#include "core/core_device.h"
#include "plib/putil.h"
-namespace netlist::factory {
+namespace netlist::factory
+{
// FIXME: this doesn't do anything, check how to remove
- class NETLIB_NAME(wrapper) : public base_device_t
+ class NETLIB_NAME(wrapper)
+ : public base_device_t
{
public:
- NETLIB_NAME(wrapper)(netlist_state_t &anetlist, const pstring &name)
- : base_device_t(anetlist, name)
+ NETLIB_NAME(wrapper)(base_device_param_t data)
+ : base_device_t(data)
{
}
+
protected:
- //NETLIB_RESETI() {}
+ // NETLIB_RESETI() {}
};
element_t::element_t(const pstring &name, properties &&props)
@@ -33,9 +37,9 @@ namespace netlist::factory {
{
}
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// net_device_t_base_factory
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
list_t::list_t(log_type &alog)
: m_log(alog)
@@ -46,7 +50,7 @@ namespace netlist::factory {
bool list_t::exists(const pstring &name) const noexcept
{
- for (const auto & e : *this)
+ for (const auto &e : *this)
if (e->name() == name)
return true;
return false;
@@ -62,9 +66,9 @@ namespace netlist::factory {
push_back(std::move(factory));
}
- factory::element_t * list_t::factory_by_name(const pstring &devname)
+ factory::element_t *list_t::factory_by_name(const pstring &devname)
{
- for (auto & e : *this)
+ for (auto &e : *this)
{
if (e->name() == devname)
return e.get();
@@ -74,19 +78,22 @@ namespace netlist::factory {
throw nl_exception(MF_CLASS_1_NOT_FOUND(devname));
}
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// library_element_t: factory class to wrap macro based chips/elements
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
- library_element_t::library_element_t(const pstring &name, properties &&props)
- : element_t(name, std::move(properties(props).set_type(element_type::MACRO)))
+ library_element_t::library_element_t(const pstring &name,
+ properties && props)
+ : element_t(name,
+ std::move(properties(props).set_type(element_type::MACRO)))
{
}
- device_arena::unique_ptr<core_device_t> library_element_t::make_device(device_arena &pool, netlist_state_t &anetlist, const pstring &name)
+ device_arena::unique_ptr<core_device_t> library_element_t::make_device(
+ device_arena &pool, netlist_state_t &anetlist, const pstring &name)
{
- return plib::make_unique<NETLIB_NAME(wrapper)>(pool, anetlist, name);
+ return plib::make_unique<NETLIB_NAME(wrapper)>(pool,
+ base_device_data_t{anetlist, name});
}
-
} // namespace netlist::factory
diff --git a/src/lib/netlist/nl_factory.h b/src/lib/netlist/nl_factory.h
index 1a3cd74ae1f..0141a168c2c 100644
--- a/src/lib/netlist/nl_factory.h
+++ b/src/lib/netlist/nl_factory.h
@@ -9,6 +9,7 @@
#define NLFACTORY_H_
#include "nltypes.h"
+
#include "plib/palloc.h"
#include "plib/pmempool.h"
#include "plib/psource.h"
@@ -18,30 +19,28 @@
#include <utility>
#include <vector>
-#define NETLIB_DEVICE_IMPL_ALIAS(p_alias, chip, p_name, p_def_param) \
- NETLIB_DEVICE_IMPL_BASE(devices, p_alias, chip, p_name, p_def_param) \
+#define NETLIB_DEVICE_IMPL_ALIAS(p_alias, chip, p_name, p_def_param) \
+ NETLIB_DEVICE_IMPL_BASE(devices, p_alias, chip, p_name, p_def_param)
-#define NETLIB_DEVICE_IMPL(chip, p_name, p_def_param) \
+#define NETLIB_DEVICE_IMPL(chip, p_name, p_def_param) \
NETLIB_DEVICE_IMPL_NS(devices, chip, p_name, p_def_param)
-#define NETLIB_DEVICE_IMPL_NS(ns, chip, p_name, p_def_param) \
- NETLIB_DEVICE_IMPL_BASE(ns, chip, chip, p_name, p_def_param) \
-
-#define NETLIB_DEVICE_IMPL_BASE(ns, p_alias, chip, p_name, p_def_param) \
- static factory::element_t::uptr NETLIB_NAME(p_alias ## _c) () \
- { \
- using devtype = factory::device_element_t<ns :: NETLIB_NAME(chip)>; \
- factory::properties sl(p_def_param, PSOURCELOC()); \
- return devtype::create(p_name, std::move(sl)); \
- } \
- \
- extern factory::constructor_ptr_t decl_ ## p_alias; \
- factory::constructor_ptr_t decl_ ## p_alias = NETLIB_NAME(p_alias ## _c);
-
-namespace netlist {
-
-namespace factory {
-
+#define NETLIB_DEVICE_IMPL_NS(ns, chip, p_name, p_def_param) \
+ NETLIB_DEVICE_IMPL_BASE(ns, chip, chip, p_name, p_def_param)
+
+#define NETLIB_DEVICE_IMPL_BASE(ns, p_alias, chip, p_name, p_def_param) \
+ static factory::element_t::uptr NETLIB_NAME(p_alias##_c)() \
+ { \
+ using devtype = factory::device_element_t<ns ::NETLIB_NAME(chip)>; \
+ factory::properties sl(p_def_param, PSOURCELOC()); \
+ return devtype::create(p_name, std::move(sl)); \
+ } \
+ \
+ extern factory::constructor_ptr_t decl_##p_alias; \
+ factory::constructor_ptr_t decl_##p_alias = NETLIB_NAME(p_alias##_c);
+
+namespace netlist::factory
+{
enum class element_type
{
BUILTIN,
@@ -50,11 +49,13 @@ namespace factory {
struct properties
{
- properties(const pstring &default_parameter, plib::source_location &&location)
+ properties(const pstring & default_parameter,
+ plib::source_location &&location)
: m_default_parameter(default_parameter)
, m_location(std::move(location))
, m_type(element_type::BUILTIN)
- { }
+ {
+ }
~properties() = default;
PCOPYASSIGNMOVE(properties, default)
@@ -64,10 +65,7 @@ namespace factory {
return m_default_parameter;
}
- plib::source_location source() const noexcept
- {
- return m_location;
- }
+ plib::source_location source() const noexcept { return m_location; }
element_type type() const noexcept { return m_type; }
@@ -76,20 +74,20 @@ namespace factory {
m_type = t;
return *this;
}
+
private:
- pstring m_default_parameter;
+ pstring m_default_parameter;
plib::source_location m_location;
- element_type m_type;
+ element_type m_type;
};
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// net_dev class factory
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
class element_t
{
public:
-
using dev_uptr = device_arena::unique_ptr<core_device_t>;
using uptr = host_arena::unique_ptr<element_t>;
using pointer = element_t *;
@@ -99,57 +97,71 @@ namespace factory {
PCOPYASSIGNMOVE(element_t, default)
- virtual dev_uptr make_device(device_arena &pool,
- netlist_state_t &anetlist,
- const pstring &name) = 0;
+ virtual dev_uptr
+ make_device(device_arena &pool, netlist_state_t &anetlist,
+ const pstring &name)
+ = 0;
pstring name() const noexcept { return m_name; }
- pstring param_desc() const noexcept { return m_properties.default_parameter(); }
- plib::source_location source() const noexcept { return m_properties.source(); }
+ pstring param_desc() const noexcept
+ {
+ return m_properties.default_parameter();
+ }
+ plib::source_location source() const noexcept
+ {
+ return m_properties.source();
+ }
element_type type() const noexcept { return m_properties.type(); }
+
private:
- pstring m_name; ///< device name
- properties m_properties; ///< source file and other information and settings
+ pstring m_name; ///< device name
+ properties m_properties; ///< source file and other information and
+ ///< settings
};
template <class C, typename... Args>
class device_element_t : public element_t
{
public:
+ using constructor_data_t = typename C::constructor_data_t;
- device_element_t(const pstring &name, properties &&props, Args&&... args)
+ device_element_t(const pstring &name, properties &&props,
+ Args &&...args)
: element_t(name, std::move(props))
, m_args(std::forward<Args>(args)...)
- { }
-
+ {
+ }
template <std::size_t... Is>
- dev_uptr make_device(device_arena &pool,
- netlist_state_t &anetlist,
- const pstring &name, std::tuple<Args...>& args, std::index_sequence<Is...>)
+ dev_uptr make_device(device_arena &pool, netlist_state_t &anetlist,
+ const pstring &name, std::tuple<Args...> &args,
+ std::index_sequence<Is...>)
{
- return plib::make_unique<C>(pool, anetlist, name, std::forward<Args>(std::get<Is>(args))...);
+ return plib::make_unique<C>(
+ pool, constructor_data_t{anetlist, name},
+ std::forward<Args>(std::get<Is>(args))...);
}
- dev_uptr make_device(device_arena &pool,
- netlist_state_t &anetlist,
- const pstring &name, std::tuple<Args...>& args)
+ dev_uptr make_device(device_arena &pool, netlist_state_t &anetlist,
+ const pstring &name, std::tuple<Args...> &args)
{
- return make_device(pool, anetlist, name, args, std::index_sequence_for<Args...>{});
+ return make_device(pool, anetlist, name, args,
+ std::index_sequence_for<Args...>{});
}
- dev_uptr make_device(device_arena &pool,
- netlist_state_t &anetlist,
- const pstring &name) override
+ dev_uptr make_device(device_arena &pool, netlist_state_t &anetlist,
+ const pstring &name) override
{
return make_device(pool, anetlist, name, m_args);
}
- static uptr create(const pstring &name, properties &&props, Args&&... args)
+ static uptr
+ create(const pstring &name, properties &&props, Args &&...args)
{
- return plib::make_unique<device_element_t<C, Args...>, host_arena>(name,
- std::move(props), std::forward<Args>(args)...);
+ return plib::make_unique<device_element_t<C, Args...>, host_arena>(
+ name, std::move(props), std::forward<Args>(args)...);
}
+
private:
std::tuple<Args...> m_args;
};
@@ -162,60 +174,61 @@ namespace factory {
PCOPYASSIGNMOVE(list_t, delete)
- template<class device_class, typename... Args>
- void add(const pstring &name, properties &&props, Args&&... args)
+ template <class device_class, typename... Args>
+ void add(const pstring &name, properties &&props, Args &&...args)
{
- add(device_element_t<device_class, Args...>::create(name, std::move(props),
- std::forward<Args>(args)...));
+ add(device_element_t<device_class, Args...>::create(
+ name, std::move(props), std::forward<Args>(args)...));
}
void add(element_t::uptr &&factory) noexcept(false);
- element_t::pointer factory_by_name(const pstring &devname) noexcept(false);
+ element_t::pointer
+ factory_by_name(const pstring &devname) noexcept(false);
template <class C>
bool is_class(element_t::pointer f) noexcept
{
- return dynamic_cast<device_element_t<C> *>(f) != nullptr;
+ return bool(plib::dynamic_downcast<device_element_t<C> *>(f));
}
bool exists(const pstring &name) const noexcept;
+
private:
log_type &m_log;
};
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// factory_creator_ptr_t
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
using constructor_ptr_t = element_t::uptr (*const)();
template <typename T>
element_t::uptr constructor_t(const pstring &name, properties &&props)
{
- return plib::make_unique<device_element_t<T>, host_arena>(name, std::move(props));
+ return plib::make_unique<device_element_t<T>, host_arena>(
+ name, std::move(props));
}
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// library_element_t: factory class to wrap macro based chips/elements
- // -----------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
class library_element_t : public element_t
{
public:
-
library_element_t(const pstring &name, properties &&props);
- dev_uptr make_device(device_arena &pool,
- netlist_state_t &anetlist,
- const pstring &name) override;
+ dev_uptr make_device(device_arena &pool, netlist_state_t &anetlist,
+ const pstring &name) override;
};
- } // namespace factory
+} // namespace netlist::factory
- namespace devices {
- void initialize_factory(factory::list_t &factory);
- } // namespace devices
-} // namespace netlist
+namespace netlist::devices
+{
+ void initialize_factory(factory::list_t &factory);
+} // namespace netlist::devices
#endif // NLFACTORY_H_
diff --git a/src/lib/netlist/nl_interface.h b/src/lib/netlist/nl_interface.h
index a9acb0bd564..eb187bad241 100644
--- a/src/lib/netlist/nl_interface.h
+++ b/src/lib/netlist/nl_interface.h
@@ -11,232 +11,238 @@
#define NLINTERFACE_H_
#include "nl_setup.h"
+
#include "core/analog.h"
#include "core/device.h"
#include "core/device_macros.h"
#include "core/logic.h"
#include "core/setup.h"
-#include <memory>
#include <array>
+#include <memory>
-namespace netlist
+namespace netlist::interface
{
-
- namespace interface
+ /// \brief analog_callback device
+ ///
+ /// This device is used to call back into the application which
+ /// is controlling the execution of the netlist.
+ ///
+ /// The device will call the provided lambda with a reference to
+ /// itself and the current value of the net it is connected to.
+ ///
+ /// The following code is an example on how to add the device to
+ /// the netlist factory.
+ ///
+ /// ```
+ /// const pstring pin(m_in);
+ /// pstring dname = pstring("OUT_") + pin;
+ ///
+ /// const auto lambda = [this](auto &in, netlist::nl_fptype val)
+ /// {
+ /// this->cpu()->update_icount(in.exec().time());
+ /// this->m_delegate(val, this->cpu()->local_time());
+ /// this->cpu()->check_mame_abort_slice();
+ /// };
+ ///
+ /// using lb_t = decltype(lambda);
+ /// using cb_t =
+ /// netlist::interface::NETLIB_NAME(analog_callback)<lb_t>;
+ ///
+ /// parser.factory().add<cb_t, netlist::nl_fptype, lb_t>(dname,
+ /// netlist::factory::properties("-", PSOURCELOC()), 1e-6,
+ /// std::forward<lb_t>(lambda));
+ /// ```
+
+ template <typename FUNC>
+ class nld_analog_callback : public device_t
{
- /// \brief analog_callback device
- ///
- /// This device is used to call back into the application which
- /// is controlling the execution of the netlist.
- ///
- /// The device will call the provided lambda with a reference to
- /// itself and the current value of the net it is connected to.
- ///
- /// The following code is an example on how to add the device to
- /// the netlist factory.
- ///
- /// ```
- /// const pstring pin(m_in);
- /// pstring dname = pstring("OUT_") + pin;
- ///
- /// const auto lambda = [this](auto &in, netlist::nl_fptype val)
- /// {
- /// this->cpu()->update_icount(in.exec().time());
- /// this->m_delegate(val, this->cpu()->local_time());
- /// this->cpu()->check_mame_abort_slice();
- /// };
- ///
- /// using lb_t = decltype(lambda);
- /// using cb_t = netlist::interface::NETLIB_NAME(analog_callback)<lb_t>;
- ///
- /// parser.factory().add<cb_t, netlist::nl_fptype, lb_t>(dname,
- /// netlist::factory::properties("-", PSOURCELOC()), 1e-6, std::forward<lb_t>(lambda));
- /// ```
-
- template <typename FUNC>
- NETLIB_OBJECT(analog_callback)
+ public:
+ nld_analog_callback(constructor_param_t data, nl_fptype threshold,
+ FUNC &&func)
+ : device_t(data)
+ , m_in(*this, "IN", NETLIB_DELEGATE(in))
+ , m_threshold(threshold)
+ , m_last(*this, "m_last", 0)
+ , m_func(func)
{
- public:
- NETLIB_CONSTRUCTOR_EX(analog_callback, nl_fptype threshold, FUNC &&func)
- , m_in(*this, "IN", NETLIB_DELEGATE(in))
- , m_threshold(threshold)
- , m_last(*this, "m_last", 0)
- , m_func(func)
- {
- }
+ }
- NETLIB_RESETI()
- {
- m_last = 0.0;
- }
-
- NETLIB_HANDLERI(in)
- {
- const nl_fptype cur = m_in();
- if (plib::abs(cur - m_last) > m_threshold)
- {
- m_last = cur;
- m_func(*this, cur);
- }
- }
+ NETLIB_RESETI() { m_last = 0.0; }
- private:
- analog_input_t m_in;
- nl_fptype m_threshold;
- state_var<nl_fptype> m_last;
- FUNC m_func;
- };
-
-
- /// \brief logic_callback device
- ///
- /// This device must be connected to a logic net. It has no power terminals
- /// and conversion with proxies will not work.
- ///
- /// Background: This device may be inserted later into the driver and should
- /// not modify the resulting analog representation of the netlist.
- ///
- /// If you get error messages on missing power terminals you have to use the
- /// analog callback device instead.
-
- template <typename FUNC>
- NETLIB_OBJECT(logic_callback)
+ NETLIB_HANDLERI(in)
{
- public:
- NETLIB_CONSTRUCTOR_EX(logic_callback, FUNC &&func)
- , m_in(*this, "IN", NETLIB_DELEGATE(in))
- , m_func(func)
- {
- }
-
- NETLIB_HANDLERI(in)
+ const nl_fptype cur = m_in();
+ if (plib::abs(cur - m_last) > m_threshold)
{
- const netlist_sig_t cur = m_in();
+ m_last = cur;
m_func(*this, cur);
}
+ }
+
+ private:
+ analog_input_t m_in;
+ nl_fptype m_threshold;
+ state_var<nl_fptype> m_last;
+ FUNC m_func;
+ };
+
+ /// \brief logic_callback device
+ ///
+ /// This device must be connected to a logic net. It has no power
+ /// terminals and conversion with proxies will not work.
+ ///
+ /// Background: This device may be inserted later into the driver and
+ /// should not modify the resulting analog representation of the
+ /// netlist.
+ ///
+ /// If you get error messages on missing power terminals you have to use
+ /// the analog callback device instead.
+
+ template <typename FUNC>
+ class nld_logic_callback : public device_t
+ {
+ public:
+ nld_logic_callback(constructor_param_t data, FUNC &&func)
+ : device_t(data)
+ , m_in(*this, "IN", NETLIB_DELEGATE(in))
+ , m_func(func)
+ {
+ }
- private:
- logic_input_t m_in;
- FUNC m_func;
- };
-
- /// \brief Set parameters to buffers contents at regular intervals
- ///
- /// This device will update a parameter from a buffers passed to the device.
- /// It is the responsibility of the controlling application to ensure that
- /// the buffer is filled at regular intervals.
- ///
- /// \tparam T The buffer type
- /// \tparam N Maximum number of supported buffers
- ///
- template <typename T>
- NETLIB_OBJECT(buffered_param_setter)
+ NETLIB_HANDLERI(in)
{
- public:
-
- NETLIB_CONSTRUCTOR(buffered_param_setter)
- , m_sample_time(netlist_time::zero())
- , m_feedback(*this, "FB", NETLIB_DELEGATE(feedback)) // clock part
- , m_Q(*this, "Q")
- , m_pos(0)
- , m_samples(0)
- , m_param_name(*this, "CHAN", "")
- , m_param_mult(*this, "MULT", 1.0)
- , m_param_offset(*this, "OFFSET", 0.0)
- , m_param(nullptr)
- , m_id(*this, "ID", 0)
- {
- connect("FB", "Q");
- m_buffer = nullptr;
- }
+ const netlist_sig_t cur = m_in();
+ m_func(*this, cur);
+ }
+
+ private:
+ logic_input_t m_in;
+ FUNC m_func;
+ };
+
+ /// \brief Set parameters to buffers contents at regular intervals
+ ///
+ /// This device will update a parameter from a buffer passed to the
+ /// device. It is the responsibility of the controlling application to
+ /// ensure that the buffer is filled at regular intervals.
+ ///
+ /// \tparam T The buffer type
+ /// \tparam N Maximum number of supported buffers
+ ///
+ template <typename T>
+ class nld_buffered_param_setter : public device_t
+ {
+ public:
+ nld_buffered_param_setter(constructor_param_t data)
+ : device_t(data)
+ , m_sample_time(netlist_time::zero())
+ , m_feedback(*this, "FB", NETLIB_DELEGATE(feedback)) // clock part
+ , m_Q(*this, "Q")
+ , m_pos(0)
+ , m_samples(0)
+ , m_param_name(*this, "CHAN", "")
+ , m_param_mult(*this, "MULT", 1.0)
+ , m_param_offset(*this, "OFFSET", 0.0)
+ , m_param(nullptr)
+ , m_id(*this, "ID", 0)
+ {
+ connect("FB", "Q");
+ m_buffer = nullptr;
+ }
- protected:
- NETLIB_RESETI()
- {
- }
+ protected:
+ NETLIB_RESETI() {}
- NETLIB_HANDLERI(feedback)
+ NETLIB_HANDLERI(feedback)
+ {
+ if (m_pos < m_samples)
{
- if (m_pos < m_samples)
- {
- // check if called outside of stream_update
- if (m_buffer != nullptr)
- {
- const nl_fptype v = (*m_buffer)[m_pos];
- m_param_setter(v * m_param_mult() + m_param_offset());
- }
- }
- else
+ // check if called outside of stream_update
+ if (m_buffer != nullptr)
{
- // FIXME: The logic has a rounding issue because time resolution divided
- // by 48,000 is not a natural number. The fractional part
- // adds up to one samples every 13 seconds for 100 ps resolution.
- // Fixing this is possible but complicated and expensive.
+ const nl_fptype v = (*m_buffer)[m_pos];
+ m_param_setter(v * m_param_mult() + m_param_offset());
}
- m_pos++;
-
- m_Q.net().toggle_and_push_to_queue(m_sample_time);
}
-
- public:
- /// \brief resolve parameter names to pointers
- ///
- /// This function must be called after all device were constructed but
- /// before reset is called.
- void resolve_params(netlist_time sample_time)
+ else
{
- m_pos = 0;
- m_sample_time = sample_time;
- if (m_param_name() != pstring(""))
- {
- param_t *p = &state().setup().find_param(m_param_name()).param();
- m_param = p;
- if (dynamic_cast<param_fp_t *>(p) != nullptr)
- m_param_setter = setter_t(&NETLIB_NAME(buffered_param_setter)::setter<param_fp_t>, this);
- else if (dynamic_cast<param_logic_t *>(p) != nullptr)
- m_param_setter = setter_t(&NETLIB_NAME(buffered_param_setter)::setter<param_logic_t>, this);
- }
+ // FIXME: The logic has a rounding issue because time
+ // resolution divided by 48,000 is not a natural
+ // number. The fractional part adds up to one samples
+ // every 13 seconds for 100 ps resolution. Fixing
+ // this is possible but complicated and expensive.
}
+ m_pos++;
- void buffer_reset(netlist_time sample_time, std::size_t num_samples, T *inputs)
+ m_Q.net().toggle_and_push_to_queue(m_sample_time);
+ }
+
+ public:
+ /// \brief resolve parameter names to pointers
+ ///
+ /// This function must be called after all device were constructed
+ /// but before reset is called.
+ void resolve_params(netlist_time sample_time)
+ {
+ m_pos = 0;
+ m_sample_time = sample_time;
+ if (m_param_name() != pstring(""))
{
- m_samples = num_samples;
- m_sample_time = sample_time;
- m_pos = 0;
- m_buffer = inputs;
+ param_t *p = &state()
+ .setup()
+ .find_param(m_param_name())
+ .param();
+ m_param = p;
+ if (plib::dynamic_downcast<param_fp_t *>(p))
+ m_param_setter = setter_t(
+ &NETLIB_NAME(buffered_param_setter)::setter<param_fp_t>,
+ this);
+ else if (plib::dynamic_downcast<param_logic_t *>(p))
+ m_param_setter = setter_t(
+ &NETLIB_NAME(buffered_param_setter)::setter<
+ param_logic_t>,
+ this);
}
+ }
- std::size_t id() const { return m_id; }
- private:
- using setter_t = plib::pmfp<void (nl_fptype)>;
+ void buffer_reset(netlist_time sample_time, std::size_t num_samples,
+ T *inputs)
+ {
+ m_samples = num_samples;
+ m_sample_time = sample_time;
+ m_pos = 0;
+ m_buffer = inputs;
+ }
- template <typename S>
- void setter(nl_fptype v)
- {
- static_cast<S *>(m_param)->set(v);
- }
+ std::size_t id() const { return m_id; }
- netlist_time m_sample_time;
+ private:
+ using setter_t = plib::pmfp<void(nl_fptype)>;
- logic_input_t m_feedback;
- logic_output_t m_Q;
+ template <typename S>
+ void setter(nl_fptype v)
+ {
+ static_cast<S *>(m_param)->set(v);
+ }
- std::size_t m_pos;
- std::size_t m_samples;
+ netlist_time m_sample_time;
- param_str_t m_param_name;
- param_fp_t m_param_mult;
- param_fp_t m_param_offset;
- param_t * m_param;
- setter_t m_param_setter;
- T * m_buffer;
- param_num_t<std::size_t> m_id;
- };
+ logic_input_t m_feedback;
+ logic_output_t m_Q;
- } // namespace interface
+ std::size_t m_pos;
+ std::size_t m_samples;
-} // namespace netlist
+ param_str_t m_param_name;
+ param_fp_t m_param_mult;
+ param_fp_t m_param_offset;
+ param_t * m_param;
+ setter_t m_param_setter;
+ T * m_buffer;
+ param_num_t<std::size_t> m_id;
+ };
+} // namespace netlist::interface
#endif // NLINTERFACE_H_
diff --git a/src/lib/netlist/nl_parser.cpp b/src/lib/netlist/nl_parser.cpp
index 02c7d11f2b2..3e4ecd0937c 100644
--- a/src/lib/netlist/nl_parser.cpp
+++ b/src/lib/netlist/nl_parser.cpp
@@ -1,16 +1,17 @@
// license:BSD-3-Clause
// copyright-holders:Couriersud
+#include "nl_parser.h"
+
#include "nl_errstr.h"
#include "nl_factory.h"
-#include "nl_parser.h"
#include "nl_setup.h"
namespace netlist
{
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// A netlist parser
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
void parser_t::verror(const pstring &msg)
{
@@ -19,12 +20,16 @@ namespace netlist
}
parser_t::parser_t(nlparse_t &setup)
- : m_setup(setup)
- , m_cur_local(nullptr)
+ : m_setup(setup)
+ , m_cur_local(nullptr)
{
- m_tokenizer.identifier_chars("abcdefghijklmnopqrstuvwvxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890_.-$@")
- .number_chars(".0123456789", "0123456789eE-.") //FIXME: processing of numbers
- .whitespace(pstring("") + ' ' + static_cast<char>(9) + static_cast<char>(10) + static_cast<char>(13))
+ m_tokenizer
+ .identifier_chars(
+ "abcdefghijklmnopqrstuvwvxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890_.-$@")
+ .number_chars(".0123456789", "0123456789eE-.") // FIXME: processing
+ // of numbers
+ .whitespace(pstring("") + ' ' + static_cast<char>(9)
+ + static_cast<char>(10) + static_cast<char>(13))
.comment("/*", "*/", "//");
m_tok_paren_left = m_tokenizer.register_token("(");
m_tok_paren_right = m_tokenizer.register_token(")");
@@ -43,7 +48,8 @@ namespace netlist
m_tok_INCLUDE = m_tokenizer.register_token("INCLUDE");
m_tok_LOCAL_SOURCE = m_tokenizer.register_token("LOCAL_SOURCE");
m_tok_LOCAL_LIB_ENTRY = m_tokenizer.register_token("LOCAL_LIB_ENTRY");
- m_tok_EXTERNAL_LIB_ENTRY = m_tokenizer.register_token("EXTERNAL_LIB_ENTRY");
+ m_tok_EXTERNAL_LIB_ENTRY = m_tokenizer.register_token(
+ "EXTERNAL_LIB_ENTRY");
m_tok_SUBMODEL = m_tokenizer.register_token("SUBMODEL");
m_tok_NETLIST_START = m_tokenizer.register_token("NETLIST_START");
m_tok_NETLIST_END = m_tokenizer.register_token("NETLIST_END");
@@ -62,7 +68,6 @@ namespace netlist
m_tokenizer.register_token("CAP_U");
m_tokenizer.register_token("CAP_N");
m_tokenizer.register_token("CAP_P");
-
}
bool parser_t::parse(plib::istream_uptr &&strm, const pstring &nlname)
@@ -72,15 +77,16 @@ namespace netlist
return parse(tokstor, nlname);
}
- void parser_t::parse_tokens(plib::istream_uptr &&strm, token_store_t &tokstor)
+ void parser_t::parse_tokens(plib::istream_uptr &&strm,
+ token_store_t & tokstor)
{
plib::putf8_reader u8reader(strm.release_stream());
m_tokenizer.append_to_store(&u8reader, tokstor);
}
- bool parser_t::parse(const token_store_t &tokstor, const pstring &nlname)
+ bool parser_t::parse(const token_store_t &store, const pstring &nlname)
{
- set_token_source(&tokstor);
+ set_token_source(&store);
bool in_nl = false;
@@ -97,7 +103,7 @@ namespace netlist
if (token.is(m_tok_NETLIST_END) || token.is(m_tok_TRUTHTABLE_END))
{
if (!in_nl)
- error (MF_PARSER_UNEXPECTED_1(token.str()));
+ error(MF_PARSER_UNEXPECTED_1(token.str()));
else
{
in_nl = false;
@@ -108,15 +114,16 @@ namespace netlist
m_cur_local->push_back(token);
m_cur_local->push_back(token_t(m_tok_paren_left));
m_cur_local->push_back(token_t(m_tok_paren_right));
-
}
- else if (token.is(m_tok_NETLIST_START) || token.is(m_tok_TRUTHTABLE_START))
+ else if (token.is(m_tok_NETLIST_START)
+ || token.is(m_tok_TRUTHTABLE_START))
{
if (in_nl)
- error (MF_PARSER_UNEXPECTED_1(token.str()));
+ error(MF_PARSER_UNEXPECTED_1(token.str()));
require_token(m_tok_paren_left);
token_t name = get_token();
- if (token.is(m_tok_NETLIST_START) && (name.str() == nlname || nlname.empty()))
+ if (token.is(m_tok_NETLIST_START)
+ && (name.str() == nlname || nlname.empty()))
{
require_token(m_tok_paren_right);
parse_netlist();
@@ -132,29 +139,32 @@ namespace netlist
m_local.emplace(name.str(), token_store_t());
m_cur_local = &m_local[name.str()];
auto sl = location();
- auto li = plib::pfmt("# {1} \"{2}\"")(sl.line(), sl.file_name());
+ auto li = plib::pfmt(
+ "# {1} \"{2}\"")(sl.line(), sl.file_name());
m_cur_local->push_back(token_t(token_type::LINEMARKER, li));
m_cur_local->push_back(token);
m_cur_local->push_back(token_t(m_tok_paren_left));
m_cur_local->push_back(name);
- //m_cur_local->push_back(token_t(m_tok_paren_right));
+ // m_cur_local->push_back(token_t(m_tok_paren_right));
in_nl = true;
}
- // FIXME: do we really need this going forward ? there should be no need
+ // FIXME: do we really need this going forward ? there should be no
+ // need
// for NETLIST_EXTERNAL in netlist files
else if (token.is(m_tok_NETLIST_EXTERNAL))
{
if (in_nl)
- error (MF_UNEXPECTED_NETLIST_EXTERNAL());
+ error(MF_UNEXPECTED_NETLIST_EXTERNAL());
require_token(m_tok_paren_left);
token_t name = get_token();
require_token(m_tok_paren_right);
}
else if (!in_nl)
{
- if (!token.is(m_tok_static) && !token.is_type(token_type::SOURCELINE)
- && !token.is_type(token_type::LINEMARKER))
+ if (!token.is(m_tok_static)
+ && !token.is_type(token_type::SOURCELINE)
+ && !token.is_type(token_type::LINEMARKER))
error(MF_EXPECTED_NETLIST_START_1(token.str()));
}
else
@@ -171,7 +181,7 @@ namespace netlist
token_t token = get_token();
if (token.is_type(token_type::ENDOFFILE))
- error (MF_UNEXPECTED_END_OF_FILE());
+ error(MF_UNEXPECTED_END_OF_FILE());
m_setup.log().debug("Parser: Device: {1}\n", token.str());
@@ -237,7 +247,8 @@ namespace netlist
else if (m_local.find(name) != m_local.end())
error(MF_EXTERNAL_SOURCE_IS_LOCAL_1(name));
- // FIXME: Need to pass in parameter definition FIXME: get line number right
+ // FIXME: Need to pass in parameter definition FIXME: get line number
+ // right
m_setup.register_lib_entry(name, "", location());
require_token(m_tok_paren_right);
}
@@ -376,7 +387,6 @@ namespace netlist
require_token(m_tok_paren_left);
pstring name(get_identifier());
require_token(m_tok_paren_right);
-
}
void parser_t::net_alias()
@@ -403,7 +413,7 @@ namespace netlist
while (true)
{
pstring t1 = get_identifier();
- m_setup.register_link(first , t1);
+ m_setup.register_link(first, t1);
m_setup.log().debug("Parser: Connect: {1} {2}\n", first, t1);
token_t n = get_token();
if (n.is(m_tok_paren_right))
@@ -411,7 +421,6 @@ namespace netlist
if (!n.is(m_tok_comma))
error(MF_EXPECTED_COMMA_OR_RP_1(n.str()));
}
-
}
void parser_t::dip_pins()
@@ -437,8 +446,8 @@ namespace netlist
std::size_t n = pins.size();
for (std::size_t i = 0; i < n / 2; i++)
{
- m_setup.register_alias(plib::pfmt("{1}")(i+1), pins[i*2]);
- m_setup.register_alias(plib::pfmt("{1}")(n-i), pins[i*2 + 1]);
+ m_setup.register_alias(plib::pfmt("{1}")(i + 1), pins[i * 2]);
+ m_setup.register_alias(plib::pfmt("{1}")(n - i), pins[i * 2 + 1]);
}
}
@@ -471,7 +480,8 @@ namespace netlist
token_t tok = get_token();
if (tok.is_type(token_type::STRING))
{
- m_setup.log().debug("Parser: DefParam: {1} {2}\n", param, tok.str());
+ m_setup.log().debug("Parser: DefParam: {1} {2}\n", param,
+ tok.str());
m_setup.register_default_param(param, tok.str());
require_token(m_tok_paren_right);
}
@@ -535,13 +545,13 @@ namespace netlist
m_setup.register_dev(dev_type, devname, params);
}
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// private
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
pstring parser_t::stringify_expression(token_t &tok)
{
- int pc(0);
+ int pc(0);
pstring ret;
while (!tok.is(m_tok_comma))
{
@@ -549,7 +559,7 @@ namespace netlist
pc++;
else if (tok.is(m_tok_paren_right))
{
- if (pc<=0)
+ if (pc <= 0)
break;
pc--;
}
@@ -559,9 +569,9 @@ namespace netlist
return ret;
}
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// source_token_t
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
bool source_token_t::parse(nlparse_t &setup, const pstring &name)
{
@@ -574,7 +584,8 @@ namespace netlist
return false;
}
- plib::istream_uptr source_token_t::stream([[maybe_unused]] const pstring &name)
+ plib::istream_uptr source_token_t::stream(
+ [[maybe_unused]] const pstring &name)
{
return plib::istream_uptr();
}
diff --git a/src/lib/netlist/nl_parser.h b/src/lib/netlist/nl_parser.h
index 0f5e135e9a6..87997866e32 100644
--- a/src/lib/netlist/nl_parser.h
+++ b/src/lib/netlist/nl_parser.h
@@ -8,8 +8,10 @@
#ifndef NL_PARSER_H_
#define NL_PARSER_H_
-#include "core/setup.h"
#include "nltypes.h" // for setup_t
+
+#include "core/setup.h"
+
#include "plib/ptokenizer.h"
#include <unordered_map>
@@ -51,6 +53,7 @@ namespace netlist
void net_truth_table_start(const pstring &nlname);
void verror(const pstring &msg) override;
+
private:
void register_local_as_source(const pstring &name);
@@ -86,16 +89,17 @@ namespace netlist
token_id_t m_tok_TT_FAMILY;
plib::tokenizer_t m_tokenizer;
- nlparse_t &m_setup;
+ nlparse_t & m_setup;
std::unordered_map<pstring, token_store_t> m_local;
- token_store_t *m_cur_local;
+ token_store_t * m_cur_local;
};
class source_token_t : public source_netlist_t
{
public:
- source_token_t(const pstring &name, const parser_t::token_store_t &store)
+ source_token_t(const pstring & name,
+ const parser_t::token_store_t &store)
: m_store(store)
, m_name(name)
{
@@ -108,10 +112,9 @@ namespace netlist
private:
parser_t::token_store_t m_store;
- pstring m_name;
+ pstring m_name;
};
-
} // namespace netlist
#endif // NL_PARSER_H_
diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp
index d8040258568..19ed531b853 100644
--- a/src/lib/netlist/nl_setup.cpp
+++ b/src/lib/netlist/nl_setup.cpp
@@ -1,35 +1,40 @@
// license:BSD-3-Clause
// copyright-holders:Couriersud
-#include "plib/palloc.h"
+#include "nl_setup.h"
+
+#include "nl_errstr.h"
+#include "nl_factory.h"
+#include "nl_parser.h"
+
#include "core/devices.h"
#include "core/setup.h"
+
#include "devices/nlid_proxy.h"
#include "devices/nlid_truthtable.h"
-#include "nl_errstr.h"
-#include "nl_factory.h"
-#include "nl_parser.h"
-#include "nl_setup.h"
+
+#include "solver/nld_solver.h"
+
+#include "plib/palloc.h"
#include "plib/penum.h"
#include "plib/pstonum.h"
#include "plib/pstrutil.h"
#include "plib/putil.h"
-#include "solver/nld_solver.h"
-
#include <sstream>
namespace netlist
{
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// nl_parse_t
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
nlparse_t::nlparse_t(log_type &log, detail::abstract_t &abstract)
: m_abstract(abstract)
, m_log(log)
, m_frontier_cnt(0)
- { }
+ {
+ }
void nlparse_t::register_alias(const pstring &alias, const pstring &out)
{
@@ -40,26 +45,29 @@ namespace netlist
void nlparse_t::register_dip_alias_arr(const pstring &terms)
{
- const auto list(plib::psplit(terms,pstring(", ")));
+ const auto list(plib::psplit(terms, pstring(", ")));
if (list.empty() || (list.size() % 2) == 1)
{
- log().fatal(MF_DIP_PINS_MUST_BE_AN_EQUAL_NUMBER_OF_PINS_1(build_fqn("")));
- throw nl_exception(MF_DIP_PINS_MUST_BE_AN_EQUAL_NUMBER_OF_PINS_1(build_fqn("")));
+ log().fatal(
+ MF_DIP_PINS_MUST_BE_AN_EQUAL_NUMBER_OF_PINS_1(build_fqn("")));
+ throw nl_exception(
+ MF_DIP_PINS_MUST_BE_AN_EQUAL_NUMBER_OF_PINS_1(build_fqn("")));
}
std::size_t n = list.size();
for (std::size_t i = 0; i < n / 2; i++)
{
- register_alias(plib::pfmt("{1}")(i+1), list[i * 2]);
- register_alias(plib::pfmt("{1}")(n-i), list[i * 2 + 1]);
+ register_alias(plib::pfmt("{1}")(i + 1), list[i * 2]);
+ register_alias(plib::pfmt("{1}")(n - i), list[i * 2 + 1]);
}
}
- void nlparse_t::register_dev(const pstring &classname,
- std::initializer_list<const char *> more_parameters)
+ void
+ nlparse_t::register_dev(const pstring & classname,
+ std::initializer_list<const char *> more_parameters)
{
std::vector<pstring> params;
- const auto *i(more_parameters.begin());
- pstring name(*i);
+ const auto * i(more_parameters.begin());
+ pstring name(*i);
++i;
for (; i != more_parameters.end(); ++i)
{
@@ -68,9 +76,10 @@ namespace netlist
register_dev(classname, name, params);
}
- void nlparse_t::register_dev(const pstring &classname, const pstring &name,
- const std::vector<pstring> &params_and_connections,
- factory::element_t **factory_element)
+ void
+ nlparse_t::register_dev(const pstring &classname, const pstring &name,
+ const std::vector<pstring> &params_and_connections,
+ factory::element_t ** factory_element)
{
auto *f = factory().factory_by_name(classname);
@@ -92,7 +101,8 @@ namespace netlist
throw nl_exception(MF_DEVICE_ALREADY_EXISTS_1(key));
}
- m_abstract.m_device_factory.insert(m_abstract.m_device_factory.end(), {key, f});
+ m_abstract.m_device_factory.insert(m_abstract.m_device_factory.end(),
+ {key, f});
auto parameter_list = plib::psplit(f->param_desc(), ',');
@@ -107,10 +117,11 @@ namespace netlist
{
if (token_ptr == token_end)
{
- auto err = MF_PARAM_COUNT_MISMATCH_2(name, params_and_connections.size());
+ auto err = MF_PARAM_COUNT_MISMATCH_2(
+ name, params_and_connections.size());
log().fatal(err);
throw nl_exception(err);
- //break;
+ // break;
}
pstring output_name = *token_ptr;
log().debug("Link: {1} {2}", tp, output_name);
@@ -129,13 +140,15 @@ namespace netlist
{
if (token_ptr == token_end)
{
- auto err = MF_PARAM_COUNT_MISMATCH_2(name, params_and_connections.size());
+ auto err = MF_PARAM_COUNT_MISMATCH_2(
+ name, params_and_connections.size());
log().fatal(err);
throw nl_exception(err);
}
pstring fully_qualified_name = name + "." + tp;
- log().debug("Default parameter: {1}\n", fully_qualified_name);
+ log().debug("Default parameter: {1}\n",
+ fully_qualified_name);
register_param(fully_qualified_name, *token_ptr);
@@ -144,7 +157,8 @@ namespace netlist
}
if (token_ptr != params_and_connections.end())
{
- MF_PARAM_COUNT_EXCEEDED_2 err(name, params_and_connections.size());
+ MF_PARAM_COUNT_EXCEEDED_2 err(name,
+ params_and_connections.size());
log().fatal(err);
throw nl_exception(err);
}
@@ -153,7 +167,8 @@ namespace netlist
*factory_element = f;
}
- void nlparse_t::register_hint(const pstring &object_name, const pstring &hint_name)
+ void nlparse_t::register_hint(const pstring &object_name,
+ const pstring &hint_name)
{
const auto name = build_fqn(object_name) + hint_name;
if (!m_abstract.m_hints.insert({name, false}).second)
@@ -165,12 +180,13 @@ namespace netlist
void nlparse_t::register_link(const pstring &sin, const pstring &sout)
{
- register_link_fqn(build_fqn(plib::trim(sin)), build_fqn(plib::trim(sout)));
+ register_link_fqn(build_fqn(plib::trim(sin)),
+ build_fqn(plib::trim(sout)));
}
void nlparse_t::register_link_arr(const pstring &terms)
{
- const auto list(plib::psplit(terms,pstring(", ")));
+ const auto list(plib::psplit(terms, pstring(", ")));
if (list.size() < 2)
{
log().fatal(MF_NET_C_NEEDS_AT_LEAST_2_TERMINAL());
@@ -184,10 +200,9 @@ namespace netlist
void nlparse_t::include(const pstring &netlist_name)
{
- if (m_sources.for_all<source_netlist_t>([this, &netlist_name] (source_netlist_t *src)
- {
- return src->parse(*this, netlist_name);
- }))
+ if (m_sources.for_all<source_netlist_t>(
+ [this, &netlist_name](source_netlist_t *src)
+ { return src->parse(*this, netlist_name); }))
return;
log().fatal(MF_NOT_FOUND_IN_SOURCE_COLLECTION(netlist_name));
throw nl_exception(MF_NOT_FOUND_IN_SOURCE_COLLECTION(netlist_name));
@@ -196,18 +211,16 @@ namespace netlist
void nlparse_t::namespace_push(const pstring &aname)
{
if (m_namespace_stack.empty())
- //m_namespace_stack.push(netlist().name() + "." + aname);
+ // m_namespace_stack.push(netlist().name() + "." + aname);
m_namespace_stack.push(aname);
else
m_namespace_stack.push(m_namespace_stack.top() + "." + aname);
}
- void nlparse_t::namespace_pop()
- {
- m_namespace_stack.pop();
- }
+ void nlparse_t::namespace_pop() { m_namespace_stack.pop(); }
- void nlparse_t::register_param_fp(const pstring &param, const nl_fptype value)
+ void
+ nlparse_t::register_param_fp(const pstring &param, const nl_fptype value)
{
if (plib::abs(value - plib::floor(value)) > nlconst::magic(1e-30)
|| plib::abs(value) > nlconst::magic(1e9))
@@ -233,7 +246,8 @@ namespace netlist
if (!m_abstract.m_param_values.insert({fqn, val}).second)
{
log().fatal(MF_ADDING_PARAMETER_1_TO_PARAMETER_LIST(param));
- throw nl_exception(MF_ADDING_PARAMETER_1_TO_PARAMETER_LIST(param));
+ throw nl_exception(
+ MF_ADDING_PARAMETER_1_TO_PARAMETER_LIST(param));
}
}
else
@@ -241,14 +255,15 @@ namespace netlist
if (idx->second.find("$(") == pstring::npos)
{
// There may be reason ... so make it an INFO
- log().info(MI_OVERWRITING_PARAM_1_OLD_2_NEW_3(fqn,
- idx->second, val));
+ log().info(
+ MI_OVERWRITING_PARAM_1_OLD_2_NEW_3(fqn, idx->second, val));
}
m_abstract.m_param_values[fqn] = val;
}
}
- void nlparse_t::register_default_param(const pstring &name, const pstring &def)
+ void
+ nlparse_t::register_default_param(const pstring &name, const pstring &def)
{
// strip " from stringified strings
pstring val(def);
@@ -256,7 +271,8 @@ namespace netlist
val = def.substr(1, def.length() - 2);
// Replace "@." with the current namespace
val = plib::replace_all(val, "@.", namespace_prefix());
- m_abstract.m_default_params.emplace_back(namespace_prefix() + name, val);
+ m_abstract.m_default_params.emplace_back(namespace_prefix() + name,
+ val);
}
factory::list_t &nlparse_t::factory() noexcept
@@ -269,14 +285,16 @@ namespace netlist
return m_abstract.m_factory;
}
-
- void nlparse_t::register_lib_entry(const pstring &name, const pstring &def_params, plib::source_location &&loc)
+ void nlparse_t::register_lib_entry(const pstring & name,
+ const pstring & def_params,
+ plib::source_location &&loc)
{
- factory().add(plib::make_unique<factory::library_element_t, host_arena>(name, factory::properties(def_params, std::move(loc))));
+ factory().add(plib::make_unique<factory::library_element_t, host_arena>(
+ name, factory::properties(def_params, std::move(loc))));
}
- void nlparse_t::register_frontier(const pstring &attach, const pstring &r_IN,
- const pstring &r_OUT)
+ void nlparse_t::register_frontier(const pstring &attach,
+ const pstring &r_IN, const pstring &r_OUT)
{
pstring frontier_name = plib::pfmt("frontier_{1}")(m_frontier_cnt);
m_frontier_cnt++;
@@ -286,8 +304,8 @@ namespace netlist
register_link(frontier_name + ".G", "GND");
pstring attach_fully_qualified_name = build_fqn(attach);
pstring front_fqn = build_fqn(frontier_name);
- bool found = false;
- for (auto & link : m_abstract.m_links)
+ bool found = false;
+ for (auto &link : m_abstract.m_links)
{
if (link.first == attach_fully_qualified_name)
{
@@ -313,9 +331,11 @@ namespace netlist
register_source<netlist::source_proc_t>(name, func);
}
- void nlparse_t::truth_table_create(tt_desc &desc, const pstring &def_params, plib::source_location &&loc)
+ void nlparse_t::truth_table_create(tt_desc &desc, const pstring &def_params,
+ plib::source_location &&loc)
{
- auto fac = factory::truth_table_create(desc, netlist::factory::properties(def_params, std::move(loc)));
+ auto fac = factory::truth_table_create(
+ desc, netlist::factory::properties(def_params, std::move(loc)));
factory().add(std::move(fac));
}
@@ -329,7 +349,8 @@ namespace netlist
return namespace_prefix() + obj_name;
}
- void nlparse_t::register_alias_no_fqn(const pstring &alias, const pstring &out)
+ void
+ nlparse_t::register_alias_no_fqn(const pstring &alias, const pstring &out)
{
if (!m_abstract.m_alias.insert({alias, out}).second)
{
@@ -353,13 +374,15 @@ namespace netlist
return false;
}
- bool nlparse_t::parse_tokens(const plib::detail::token_store_t &tokens, const pstring &name)
+ bool nlparse_t::parse_tokens(const plib::detail::token_store_t &tokens,
+ const pstring & name)
{
parser_t parser(*this);
return parser.parse(tokens, name);
}
- bool nlparse_t::parse_stream(plib::istream_uptr &&in_stream, const pstring &name)
+ bool
+ nlparse_t::parse_stream(plib::istream_uptr &&in_stream, const pstring &name)
{
#if 0
auto key = in_stream.filename();
@@ -380,12 +403,14 @@ namespace netlist
}
#else
const auto filename = in_stream.filename();
- auto preprocessed = std::make_unique<std::stringstream>(putf8string(
- plib::ppreprocessor(m_includes, &m_defines).process(std::move(in_stream), filename)));
+ auto preprocessed = std::make_unique<std::stringstream>(
+ putf8string(plib::ppreprocessor(m_includes, &m_defines)
+ .process(std::move(in_stream), filename)));
parser_t::token_store_t st;
- parser_t parser(*this);
- parser.parse_tokens(plib::istream_uptr(std::move(preprocessed), filename), st);
+ parser_t parser(*this);
+ parser.parse_tokens(
+ plib::istream_uptr(std::move(preprocessed), filename), st);
return parser.parse(st, name);
#endif
}
@@ -394,12 +419,13 @@ namespace netlist
{
auto p = define.find('=');
if (p != pstring::npos)
- add_define(plib::left(define, p), define.substr(p+1));
+ add_define(plib::left(define, p), define.substr(p + 1));
else
add_define(define, "1");
}
- void nlparse_t::register_dynamic_log_devices(const std::vector<pstring> &log_list)
+ void nlparse_t::register_dynamic_log_devices(
+ const std::vector<pstring> &log_list)
{
log().debug("Creating dynamic logs ...");
for (const pstring &ll : log_list)
@@ -415,13 +441,16 @@ namespace netlist
{
// FIXME: check use_cases - remove_connections may be dead
pstring pin_fully_qualified_name = build_fqn(pin);
- bool found = false;
+ bool found = false;
- for (auto link = m_abstract.m_links.begin(); link != m_abstract.m_links.end(); )
+ for (auto link = m_abstract.m_links.begin();
+ link != m_abstract.m_links.end();)
{
- if ((link->first == pin_fully_qualified_name) || (link->second == pin_fully_qualified_name))
+ if ((link->first == pin_fully_qualified_name)
+ || (link->second == pin_fully_qualified_name))
{
- log().verbose("removing connection: {1} <==> {2}\n", link->first, link->second);
+ log().verbose("removing connection: {1} <==> {2}\n",
+ link->first, link->second);
link = m_abstract.m_links.erase(link);
found = true;
}
@@ -445,15 +474,15 @@ namespace netlist
if (!m_abstract.m_models.insert({model, def}).second)
{
// FIXME: Add an directive MODEL_OVERWRITE to netlist language
- //throw nl_exception(MF_MODEL_ALREADY_EXISTS_1(model_in));
+ // throw nl_exception(MF_MODEL_ALREADY_EXISTS_1(model_in));
log().info(MI_MODEL_OVERWRITE_1(model, model_in));
m_abstract.m_models[model] = def;
}
}
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// Sources
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
plib::istream_uptr nlparse_t::get_data_stream(const pstring &name)
{
@@ -464,17 +493,17 @@ namespace netlist
return plib::istream_uptr();
}
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// setup_t
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
setup_t::setup_t(netlist_state_t &nlstate)
- : m_abstract(nlstate.log())
- , m_parser(nlstate.log(), m_abstract)
- , m_nlstate(nlstate)
- , m_models(m_abstract.m_models) // FIXME : parse abstract_t only
- , m_netlist_params(nullptr)
- , m_proxy_cnt(0)
+ : m_abstract(nlstate.log())
+ , m_parser(nlstate.log(), m_abstract)
+ , m_nlstate(nlstate)
+ , m_models(m_abstract.m_models) // FIXME : parse abstract_t only
+ , m_netlist_params(nullptr)
+ , m_proxy_cnt(0)
{
}
@@ -482,33 +511,32 @@ namespace netlist
{
switch (in.type())
{
- case detail::terminal_type::TERMINAL:
- return "TERMINAL";
- case detail::terminal_type::INPUT:
- return "INPUT";
- case detail::terminal_type::OUTPUT:
- return "OUTPUT";
+ case detail::terminal_type::TERMINAL: return "TERMINAL";
+ case detail::terminal_type::INPUT: return "INPUT";
+ case detail::terminal_type::OUTPUT: return "OUTPUT";
}
return "Error"; // Tease gcc
}
- pstring setup_t::get_initial_param_val(const pstring &name, const pstring &def) const
+ pstring setup_t::get_initial_param_val(const pstring &name,
+ const pstring &def) const
{
- // When `get_intial_param_val` is called the parameter `<name>` is already registered
- // and the value `(value_string())` is set to the default value, e.g. "74XX"
- // If thus `$(IC5E.A.MODEL)` is given for `name=="IC5E.A.MODEL"` `value_string()` below
- // will return the default.
- // FIXME: It may be more explicit and stable to test if pattern==name and return
- // `def` in this case.
+ // When `get_intial_param_val` is called the parameter `<name>` is
+ // already registered and the value `(value_string())` is set to the
+ // default value, e.g. "74XX" If thus `$(IC5E.A.MODEL)` is given for
+ // `name=="IC5E.A.MODEL"` `value_string()` below will return the
+ // default.
+ // FIXME: It may be more explicit and stable to test if pattern==name
+ // and return `def` in this case.
- auto i = m_abstract.m_param_values.find(name);
- auto found_pat(false);
+ auto i = m_abstract.m_param_values.find(name);
+ auto found_pat(false);
pstring v = (i == m_abstract.m_param_values.end()) ? def : i->second;
do
{
found_pat = false;
- auto sp(plib::psplit(v, std::vector<pstring>({"$(", ")"})));
+ auto sp(plib::psplit(v, std::vector<pstring>({"$(", ")"})));
std::size_t p(0);
v = "";
while (p < sp.size())
@@ -545,23 +573,31 @@ namespace netlist
log().debug("{1} {2}\n", termtype_as_str(term), term.name());
if (!m_terminals.insert({term.name(), &term}).second)
{
- log().fatal(MF_ADDING_1_2_TO_TERMINAL_LIST(termtype_as_str(term), term.name()));
- throw nl_exception(MF_ADDING_1_2_TO_TERMINAL_LIST(termtype_as_str(term), term.name()));
+ log().fatal(MF_ADDING_1_2_TO_TERMINAL_LIST(termtype_as_str(term),
+ term.name()));
+ throw nl_exception(MF_ADDING_1_2_TO_TERMINAL_LIST(
+ termtype_as_str(term), term.name()));
}
}
- void setup_t::register_term(terminal_t &term, terminal_t *other_term, const std::array<terminal_t *, 2> &splitter_terms)
+ void
+ setup_t::register_term(terminal_t &term, terminal_t *other_term,
+ const std::array<terminal_t *, 2> &splitter_terms)
{
this->register_term(term);
- m_connected_terminals.insert({&term, {other_term, splitter_terms[0], splitter_terms[1], nullptr}});
+ m_connected_terminals.insert(
+ {&term,
+ {other_term, splitter_terms[0], splitter_terms[1], nullptr}});
}
void setup_t::register_param_t(param_t &param)
{
- if (!m_params.insert({param.name(), param_ref_t(param.device(), param)}).second)
+ if (!m_params.insert({param.name(), param_ref_t(param.device(), param)})
+ .second)
{
log().fatal(MF_ADDING_PARAMETER_1_TO_PARAMETER_LIST(param.name()));
- throw nl_exception(MF_ADDING_PARAMETER_1_TO_PARAMETER_LIST(param.name()));
+ throw nl_exception(
+ MF_ADDING_PARAMETER_1_TO_PARAMETER_LIST(param.name()));
}
}
@@ -571,7 +607,8 @@ namespace netlist
pstring ret;
// FIXME: Detect endless loop
- do {
+ do
+ {
ret = temp;
auto p = m_abstract.m_alias.find(ret);
temp = (p != m_abstract.m_alias.end() ? p->second : "");
@@ -587,7 +624,8 @@ namespace netlist
pstring ret;
// FIXME: Detect endless loop
- do {
+ do
+ {
ret = temp;
temp = "";
for (const auto &e : m_abstract.m_alias)
@@ -605,32 +643,35 @@ namespace netlist
return ret;
}
- std::vector<pstring> setup_t::get_terminals_for_device_name(const pstring &devname) const
+ std::vector<pstring>
+ setup_t::get_terminals_for_device_name(const pstring &devname) const
{
std::vector<pstring> terms;
- for (const auto & t : m_terminals)
+ for (const auto &t : m_terminals)
{
if (plib::startsWith(t.second->name(), devname))
{
- pstring tn(t.second->name().substr(devname.length()+1));
+ pstring tn(t.second->name().substr(devname.length() + 1));
if (tn.find('.') == pstring::npos)
terms.push_back(tn);
}
}
- for (const auto & t : m_abstract.m_alias)
+ for (const auto &t : m_abstract.m_alias)
{
if (plib::startsWith(t.first, devname))
{
- pstring tn(t.first.substr(devname.length()+1));
+ pstring tn(t.first.substr(devname.length() + 1));
if (tn.find('.') == pstring::npos)
{
terms.push_back(tn);
pstring resolved = resolve_alias(t.first);
if (resolved != t.first)
{
- auto found = std::find(terms.begin(), terms.end(), resolved.substr(devname.length()+1));
- if (found!=terms.end())
+ auto found = std::find(
+ terms.begin(), terms.end(),
+ resolved.substr(devname.length() + 1));
+ if (found != terms.end())
terms.erase(found);
}
}
@@ -639,10 +680,11 @@ namespace netlist
return terms;
}
- detail::core_terminal_t *setup_t::find_terminal(const pstring &terminal_in, bool required) const
+ detail::core_terminal_t *
+ setup_t::find_terminal(const pstring &terminal_in, bool required) const
{
const pstring &tname = resolve_alias(terminal_in);
- auto ret = m_terminals.find(tname);
+ auto ret = m_terminals.find(tname);
// look for default
if (ret == m_terminals.end())
{
@@ -650,7 +692,9 @@ namespace netlist
ret = m_terminals.find(tname + ".Q");
}
- detail::core_terminal_t *term = (ret == m_terminals.end() ? nullptr : ret->second);
+ detail::core_terminal_t *term = (ret == m_terminals.end()
+ ? nullptr
+ : ret->second);
if (term == nullptr && required)
{
@@ -665,11 +709,12 @@ namespace netlist
return term;
}
- detail::core_terminal_t *setup_t::find_terminal(const pstring &terminal_in,
- detail::terminal_type atype, bool required) const
+ detail::core_terminal_t *
+ setup_t::find_terminal(const pstring & terminal_in,
+ detail::terminal_type atype, bool required) const
{
const pstring &tname = resolve_alias(terminal_in);
- auto ret = m_terminals.find(tname);
+ auto ret = m_terminals.find(tname);
// look for default
if (ret == m_terminals.end() && atype == detail::terminal_type::OUTPUT)
{
@@ -681,14 +726,17 @@ namespace netlist
log().fatal(MF_TERMINAL_1_2_NOT_FOUND(terminal_in, tname));
throw nl_exception(MF_TERMINAL_1_2_NOT_FOUND(terminal_in, tname));
}
- detail::core_terminal_t *term = (ret == m_terminals.end() ? nullptr : ret->second);
+ detail::core_terminal_t *term = (ret == m_terminals.end()
+ ? nullptr
+ : ret->second);
if (term != nullptr && term->type() != atype)
{
if (required)
{
log().fatal(MF_OBJECT_1_2_WRONG_TYPE(terminal_in, tname));
- throw nl_exception(MF_OBJECT_1_2_WRONG_TYPE(terminal_in, tname));
+ throw nl_exception(
+ MF_OBJECT_1_2_WRONG_TYPE(terminal_in, tname));
}
term = nullptr;
@@ -702,30 +750,34 @@ namespace netlist
param_ref_t setup_t::find_param(const pstring &param_in) const
{
const pstring resolved_param_name(resolve_alias(param_in));
- auto ret(m_params.find(resolved_param_name));
+ auto ret(m_params.find(resolved_param_name));
if (ret == m_params.end())
{
- log().fatal(MF_PARAMETER_1_2_NOT_FOUND(param_in, resolved_param_name));
- throw nl_exception(MF_PARAMETER_1_2_NOT_FOUND(param_in, resolved_param_name));
+ log().fatal(
+ MF_PARAMETER_1_2_NOT_FOUND(param_in, resolved_param_name));
+ throw nl_exception(
+ MF_PARAMETER_1_2_NOT_FOUND(param_in, resolved_param_name));
}
return ret->second;
}
- //NOLINTNEXTLINE(misc-no-recursion)
- devices::nld_base_proxy *setup_t::get_d_a_proxy(const detail::core_terminal_t &out)
+ // NOLINTNEXTLINE(misc-no-recursion)
+ devices::nld_base_proxy *
+ setup_t::get_d_a_proxy(const detail::core_terminal_t &out)
{
- gsl_Expects(out.is_logic());
-
- const auto &out_cast = dynamic_cast<const logic_output_t &>(out);
auto iter_proxy(m_proxies.find(&out));
if (iter_proxy != m_proxies.end())
return iter_proxy->second;
// create a new one ...
+
+ auto out_cast = plib::dynamic_downcast<const logic_output_t *>(out);
+ nl_assert_always(bool(out_cast), "Not able to cast to logic_output_t&");
+
pstring x = plib::pfmt("proxy_da_{1}_{2}")(out.name())(m_proxy_cnt);
- auto new_proxy =
- out_cast.logic_family()->create_d_a_proxy(m_nlstate, x, &out_cast);
+ auto new_proxy = (*out_cast)->logic_family()->create_d_a_proxy(
+ m_nlstate, x, *out_cast);
m_proxy_cnt++;
// connect all existing terminals to new net
@@ -734,15 +786,15 @@ namespace netlist
// remove all terminals from out.net()
out.net().remove_all_terminals();
- for (detail::core_terminal_t * p : temp_terminals)
+ for (detail::core_terminal_t *p : temp_terminals)
{
p->clear_net(); // de-link from all nets ...
if (!connect(new_proxy->proxy_term(), *p))
{
- log().fatal(MF_CONNECTING_1_TO_2(
- new_proxy->proxy_term().name(), (*p).name()));
+ log().fatal(MF_CONNECTING_1_TO_2(new_proxy->proxy_term().name(),
+ (*p).name()));
throw nl_exception(MF_CONNECTING_1_TO_2(
- new_proxy->proxy_term().name(), (*p).name()));
+ new_proxy->proxy_term().name(), (*p).name()));
}
}
@@ -754,15 +806,16 @@ namespace netlist
m_nlstate.register_device(new_proxy->name(), std::move(new_proxy));
return proxy;
-
}
- //NOLINTNEXTLINE(misc-no-recursion)
- devices::nld_base_proxy *setup_t::get_a_d_proxy(detail::core_terminal_t &inp)
+ // NOLINTNEXTLINE(misc-no-recursion)
+ devices::nld_base_proxy *
+ setup_t::get_a_d_proxy(detail::core_terminal_t &inp)
{
gsl_Expects(inp.is_logic());
- const auto &logic_input_terminal = dynamic_cast<const logic_input_t &>(inp);
+ const auto &logic_input_terminal = dynamic_cast<const logic_input_t &>(
+ inp);
auto iter_proxy(m_proxies.find(&inp));
@@ -770,10 +823,9 @@ namespace netlist
return iter_proxy->second;
log().debug("connect_terminal_input: connecting proxy\n");
- auto new_proxy =
- logic_input_terminal.logic_family()->create_a_d_proxy(m_nlstate,
- plib::pfmt("proxy_ad_{1}_{2}")(inp.name())(m_proxy_cnt),
- &logic_input_terminal);
+ auto new_proxy = logic_input_terminal.logic_family()->create_a_d_proxy(
+ m_nlstate, plib::pfmt("proxy_ad_{1}_{2}")(inp.name())(m_proxy_cnt),
+ &logic_input_terminal);
auto *ret(new_proxy.get());
@@ -790,7 +842,7 @@ namespace netlist
inp.net().remove_all_terminals();
- for (detail::core_terminal_t * p : temp_terminals)
+ for (detail::core_terminal_t *p : temp_terminals)
{
// inp may already belongs to the logic net. Thus skip it here.
// It will be removed by the clear further down.
@@ -800,9 +852,9 @@ namespace netlist
if (!connect(ret->proxy_term(), *p))
{
log().fatal(MF_CONNECTING_1_TO_2(
- ret->proxy_term().name(), (*p).name()));
+ ret->proxy_term().name(), (*p).name()));
throw nl_exception(MF_CONNECTING_1_TO_2(
- ret->proxy_term().name(), (*p).name()));
+ ret->proxy_term().name(), (*p).name()));
}
}
}
@@ -813,19 +865,20 @@ namespace netlist
return ret;
}
- detail::core_terminal_t &setup_t::resolve_proxy(detail::core_terminal_t &term)
+ detail::core_terminal_t &
+ setup_t::resolve_proxy(detail::core_terminal_t &term)
{
if (term.is_logic())
{
const auto &out = dynamic_cast<const logic_t &>(term);
- auto iter_proxy(m_proxies.find(&out));
+ auto iter_proxy(m_proxies.find(&out));
if (iter_proxy != m_proxies.end())
return iter_proxy->second->proxy_term();
}
return term;
}
- //NOLINTNEXTLINE(misc-no-recursion)
+ // NOLINTNEXTLINE(misc-no-recursion)
void setup_t::merge_nets(detail::net_t &this_net, detail::net_t &other_net)
{
log().debug("merging nets ...\n");
@@ -837,8 +890,10 @@ namespace netlist
if (this_net.is_rail_net() && other_net.is_rail_net())
{
- log().fatal(MF_MERGE_RAIL_NETS_1_AND_2(this_net.name(), other_net.name()));
- throw nl_exception(MF_MERGE_RAIL_NETS_1_AND_2(this_net.name(), other_net.name()));
+ log().fatal(
+ MF_MERGE_RAIL_NETS_1_AND_2(this_net.name(), other_net.name()));
+ throw nl_exception(
+ MF_MERGE_RAIL_NETS_1_AND_2(this_net.name(), other_net.name()));
}
if (other_net.is_rail_net())
@@ -852,90 +907,111 @@ namespace netlist
}
}
- //NOLINTNEXTLINE(misc-no-recursion)
- void setup_t::connect_input_output(detail::core_terminal_t &in, detail::core_terminal_t &out)
+ // NOLINTNEXTLINE(misc-no-recursion)
+ void setup_t::connect_input_output(detail::core_terminal_t &input,
+ detail::core_terminal_t &output)
{
- if (out.is_analog() && in.is_logic())
+ if (input.has_net() && input.net().is_rail_net())
+ {
+ log().fatal(MF_INPUT_1_ALREADY_CONNECTED(input.name()));
+ throw nl_exception(MF_INPUT_1_ALREADY_CONNECTED(input.name()));
+ }
+ if (output.is_analog() && input.is_logic())
{
- auto *proxy = get_a_d_proxy(in);
+ auto *proxy = get_a_d_proxy(input);
- out.net().add_terminal(proxy->proxy_term());
+ output.net().add_terminal(proxy->proxy_term());
}
- else if (out.is_logic() && in.is_analog())
+ else if (output.is_logic() && input.is_analog())
{
- devices::nld_base_proxy *proxy = get_d_a_proxy(out);
+ devices::nld_base_proxy *proxy = get_d_a_proxy(output);
- connect_terminals(proxy->proxy_term(), in);
- //proxy->out().net().register_con(in);
+ connect_terminals(proxy->proxy_term(), input);
}
else
{
- if (in.has_net())
- merge_nets(out.net(), in.net());
+ if (input.has_net())
+ merge_nets(output.net(), input.net());
+ else if (output.has_net())
+ output.net().add_terminal(input);
else
- out.net().add_terminal(in);
+ {
+ log().fatal(
+ ME_TERMINALS_1_2_WITHOUT_NET(input.name(), output.name()));
+ throw nl_exception(
+ ME_TERMINALS_1_2_WITHOUT_NET(input.name(), output.name()));
+ }
}
}
- //NOLINTNEXTLINE(misc-no-recursion)
- void setup_t::connect_terminal_input(terminal_t &term, detail::core_terminal_t &inp)
+ // NOLINTNEXTLINE(misc-no-recursion)
+ void setup_t::connect_terminal_input(detail::core_terminal_t &terminal,
+ detail::core_terminal_t &input)
{
- if (inp.is_analog())
+ if (input.is_analog())
{
- connect_terminals(inp, term);
+ connect_terminals(input, terminal);
}
- else if (inp.is_logic())
+ else if (input.is_logic())
{
- log().verbose("connect terminal {1} (in, {2}) to {3}\n", inp.name(),
- inp.is_analog() ? "analog" : inp.is_logic() ? "logic" : "?", term.name());
- auto *proxy = get_a_d_proxy(inp);
-
- //out.net().register_con(proxy->proxy_term());
- connect_terminals(term, proxy->proxy_term());
+ log().verbose("connect terminal {1} (in, {2}) to {3}\n",
+ input.name(),
+ input.is_analog() ? "analog"
+ : input.is_logic() ? "logic"
+ : "?",
+ terminal.name());
+ auto *proxy = get_a_d_proxy(input);
+ // out.net().register_con(proxy->proxy_term());
+ connect_terminals(terminal, proxy->proxy_term());
}
else
{
- log().fatal(MF_OBJECT_INPUT_TYPE_1(inp.name()));
- throw nl_exception(MF_OBJECT_INPUT_TYPE_1(inp.name()));
+ log().fatal(MF_OBJECT_INPUT_TYPE_1(input.name()));
+ throw nl_exception(MF_OBJECT_INPUT_TYPE_1(input.name()));
}
}
- //NOLINTNEXTLINE(misc-no-recursion)
- void setup_t::connect_terminal_output(terminal_t &in, detail::core_terminal_t &out)
+ // NOLINTNEXTLINE(misc-no-recursion)
+ void setup_t::connect_terminal_output(detail::core_terminal_t &terminal,
+ detail::core_terminal_t &output)
{
- if (out.is_analog())
+ if (output.is_analog())
{
- log().debug("connect_terminal_output: {1} {2}\n", in.name(), out.name());
+ log().debug("connect_terminal_output: {1} {2}\n", terminal.name(),
+ output.name());
// no proxy needed, just merge existing terminal net
- if (in.has_net())
+ if (terminal.has_net())
{
- if (&out.net() != &in.net())
- merge_nets(out.net(), in.net());
+ if (&output.net() != &terminal.net())
+ merge_nets(output.net(), terminal.net());
else
- // Only an info - some ICs (CD4538) connect pins internally to GND
- // and the schematics again externally. This will cause this warning.
+ // Only an info - some ICs (CD4538) connect pins internally
+ // to GND and the schematics again externally. This will
+ // cause this warning.
// FIXME: Add a hint to suppress the warning.
- log().info(MI_CONNECTING_1_TO_2_SAME_NET(in.name(), out.name(), in.net().name()));
+ log().info(MI_CONNECTING_1_TO_2_SAME_NET(
+ terminal.name(), output.name(), terminal.net().name()));
}
else
- out.net().add_terminal(in);
+ output.net().add_terminal(terminal);
}
- else if (out.is_logic())
+ else if (output.is_logic())
{
log().debug("connect_terminal_output: connecting proxy\n");
- devices::nld_base_proxy *proxy = get_d_a_proxy(out);
+ devices::nld_base_proxy *proxy = get_d_a_proxy(output);
- connect_terminals(proxy->proxy_term(), in);
+ connect_terminals(proxy->proxy_term(), terminal);
}
else
{
- log().fatal(MF_OBJECT_OUTPUT_TYPE_1(out.name()));
- throw nl_exception(MF_OBJECT_OUTPUT_TYPE_1(out.name()));
+ log().fatal(MF_OBJECT_OUTPUT_TYPE_1(output.name()));
+ throw nl_exception(MF_OBJECT_OUTPUT_TYPE_1(output.name()));
}
}
- void setup_t::connect_terminals(detail::core_terminal_t &t1,detail::core_terminal_t &t2)
+ void setup_t::connect_terminals(detail::core_terminal_t &t1,
+ detail::core_terminal_t &t2)
{
if (t1.has_net() && t2.has_net())
{
@@ -956,7 +1032,8 @@ namespace netlist
{
log().debug("adding analog net ...\n");
// FIXME: Nets should have a unique name
- auto new_net_uptr = plib::make_owned<analog_net_t>(nlstate().pool(), m_nlstate,"net." + t1.name());
+ auto new_net_uptr = plib::make_owned<analog_net_t>(
+ nlstate().pool(), m_nlstate, "net." + t1.name());
auto *new_net_ptr = new_net_uptr.get();
m_nlstate.register_net(std::move(new_net_uptr));
t1.set_net(new_net_ptr);
@@ -965,35 +1042,48 @@ namespace netlist
}
}
- //NOLINTNEXTLINE(misc-no-recursion)
- bool setup_t::connect_input_input(detail::core_terminal_t &t1, detail::core_terminal_t &t2)
+ // NOLINTNEXTLINE(misc-no-recursion)
+ bool setup_t::connect_input_input(detail::core_terminal_t &input1,
+ detail::core_terminal_t &input2)
{
bool ret = false;
- if (t1.has_net())
- {
- if (t1.net().is_rail_net())
- ret = connect(t2, t1.net().rail_terminal());
+ if (input1.has_net()) // if input 1 already has a net
+ {
+ if (input1.net().is_rail_net()) // and the net is a rail net
+ ret = connect(input2, input1.net().rail_terminal()); // try to
+ // connect
+ // input 2
+ // to rail
+ // terminal
+ // of input
+ // 1 net
if (!ret)
{
- for (detail::core_terminal_t * t : t1.net().core_terms_copy())
+ // the above was not successfull - try to connect input2 to
+ // TERMINAL type terminals of input 1 net's terminals
+ for (detail::core_terminal_t *t :
+ input1.net().core_terms_copy())
{
if (t->is_type(detail::terminal_type::TERMINAL))
- ret = connect(t2, *t);
+ ret = connect(input2, *t);
if (ret)
break;
}
}
}
- if (!ret && t2.has_net())
+ // FIXME: We could use a helper connect_input_input_helper(input2,
+ // input1) here.
+ if (!ret && input2.has_net())
{
- if (t2.net().is_rail_net())
- ret = connect(t1, t2.net().rail_terminal());
+ if (input2.net().is_rail_net())
+ ret = connect(input1, input2.net().rail_terminal());
if (!ret)
{
- for (detail::core_terminal_t * t : t2.net().core_terms_copy())
+ for (detail::core_terminal_t *t :
+ input2.net().core_terms_copy())
{
if (t->is_type(detail::terminal_type::TERMINAL))
- ret = connect(t1, *t);
+ ret = connect(input1, *t);
if (ret)
break;
}
@@ -1002,59 +1092,67 @@ namespace netlist
return ret;
}
- //NOLINTNEXTLINE(misc-no-recursion)
- bool setup_t::connect(detail::core_terminal_t &t1_in, detail::core_terminal_t &t2_in)
+ // NOLINTNEXTLINE(misc-no-recursion)
+ bool setup_t::connect(detail::core_terminal_t &t1_in,
+ detail::core_terminal_t &t2_in)
{
+ using namespace detail;
+
log().debug("Connecting {1} to {2}\n", t1_in.name(), t2_in.name());
detail::core_terminal_t &t1 = resolve_proxy(t1_in);
detail::core_terminal_t &t2 = resolve_proxy(t2_in);
- bool ret = true;
+ detail::terminal_type t1_type = t1.type();
+ detail::terminal_type t2_type = t2.type();
+ bool ret = true;
- if (t1.is_type(detail::terminal_type::OUTPUT) && t2.is_type(detail::terminal_type::INPUT))
+ switch (t1_type)
{
- if (t2.has_net() && t2.net().is_rail_net())
+ case terminal_type::TERMINAL:
{
- log().fatal(MF_INPUT_1_ALREADY_CONNECTED(t2.name()));
- throw nl_exception(MF_INPUT_1_ALREADY_CONNECTED(t2.name()));
+ switch (t2_type)
+ {
+ case terminal_type::TERMINAL:
+ connect_terminals(t1, t2);
+ break;
+ case terminal_type::INPUT:
+ connect_terminal_input(t1, t2);
+ break;
+ case terminal_type::OUTPUT:
+ connect_terminal_output(t1, t2);
+ break;
+ }
+ break;
}
- connect_input_output(t2, t1);
- }
- else if (t1.is_type(detail::terminal_type::INPUT) && t2.is_type(detail::terminal_type::OUTPUT))
- {
- if (t1.has_net() && t1.net().is_rail_net())
+ case terminal_type::INPUT:
{
- log().fatal(MF_INPUT_1_ALREADY_CONNECTED(t1.name()));
- throw nl_exception(MF_INPUT_1_ALREADY_CONNECTED(t1.name()));
+ switch (t2_type)
+ {
+ case terminal_type::TERMINAL:
+ connect_terminal_input(t2, t1);
+ break;
+ case terminal_type::INPUT:
+ ret = connect_input_input(t1, t2);
+ break;
+ case terminal_type::OUTPUT:
+ connect_input_output(t1, t2);
+ break;
+ }
+ break;
+ }
+ case terminal_type::OUTPUT:
+ {
+ switch (t2_type)
+ {
+ case terminal_type::TERMINAL:
+ connect_terminal_output(t2, t1);
+ break;
+ case terminal_type::INPUT:
+ connect_input_output(t2, t1);
+ break;
+ case terminal_type::OUTPUT: ret = false; break;
+ }
+ break;
}
- connect_input_output(t1, t2);
- }
- else if (t1.is_type(detail::terminal_type::OUTPUT) && t2.is_type(detail::terminal_type::TERMINAL))
- {
- connect_terminal_output(dynamic_cast<terminal_t &>(t2), t1);
- }
- else if (t1.is_type(detail::terminal_type::TERMINAL) && t2.is_type(detail::terminal_type::OUTPUT))
- {
- connect_terminal_output(dynamic_cast<terminal_t &>(t1), t2);
- }
- else if (t1.is_type(detail::terminal_type::INPUT) && t2.is_type(detail::terminal_type::TERMINAL))
- {
- connect_terminal_input(dynamic_cast<terminal_t &>(t2), t1);
- }
- else if (t1.is_type(detail::terminal_type::TERMINAL) && t2.is_type(detail::terminal_type::INPUT))
- {
- connect_terminal_input(dynamic_cast<terminal_t &>(t1), t2);
- }
- else if (t1.is_type(detail::terminal_type::TERMINAL) && t2.is_type(detail::terminal_type::TERMINAL))
- {
- connect_terminals(dynamic_cast<terminal_t &>(t1), dynamic_cast<terminal_t &>(t2));
- }
- else if (t1.is_type(detail::terminal_type::INPUT) && t2.is_type(detail::terminal_type::INPUT))
- {
- ret = connect_input_input(t1, t2);
- }
- else
- {
- ret = false;
}
return ret;
}
@@ -1068,7 +1166,7 @@ namespace netlist
// after all other terminals were connected.
unsigned tries = m_netlist_params->m_max_link_loops();
- #if 0
+#if 0
// This code fails for some netlists when the element at position 0
// is deleted. It will fail somewhere deep in std::pair releasing
// std::string called from erase.
@@ -1112,30 +1210,35 @@ namespace netlist
}
tries--;
}
- #else
+#else
while (!m_abstract.m_links.empty() && tries > 0)
{
- for (std::size_t i = 0; i < m_abstract.m_links.size(); )
+ for (std::size_t i = 0; i < m_abstract.m_links.size();)
{
- const pstring t1s(m_abstract.m_links[i].first);
- const pstring t2s(m_abstract.m_links[i].second);
+ const pstring t1s(m_abstract.m_links[i].first);
+ const pstring t2s(m_abstract.m_links[i].second);
detail::core_terminal_t *t1 = find_terminal(t1s);
detail::core_terminal_t *t2 = find_terminal(t2s);
if (connect(*t1, *t2))
- m_abstract.m_links.erase(m_abstract.m_links.begin() + plib::narrow_cast<std::ptrdiff_t>(i));
+ m_abstract.m_links.erase(
+ m_abstract.m_links.begin()
+ + plib::narrow_cast<std::ptrdiff_t>(i));
else
i++;
}
tries--;
}
- #endif
+#endif
if (tries == 0)
{
- for (auto & link : m_abstract.m_links)
- log().warning(MF_CONNECTING_1_TO_2(de_alias(link.first), de_alias(link.second)));
+ for (auto &link : m_abstract.m_links)
+ log().warning(MF_CONNECTING_1_TO_2(de_alias(link.first),
+ de_alias(link.second)));
- log().fatal(MF_LINK_TRIES_EXCEEDED(m_netlist_params->m_max_link_loops()));
- throw nl_exception(MF_LINK_TRIES_EXCEEDED(m_netlist_params->m_max_link_loops()));
+ log().fatal(
+ MF_LINK_TRIES_EXCEEDED(m_netlist_params->m_max_link_loops()));
+ throw nl_exception(
+ MF_LINK_TRIES_EXCEEDED(m_netlist_params->m_max_link_loops()));
}
log().verbose("deleting empty nets ...");
@@ -1147,11 +1250,13 @@ namespace netlist
bool err(false);
log().verbose("looking for terminals not connected ...");
- for (auto & i : m_terminals)
+ for (auto &i : m_terminals)
{
detail::core_terminal_t *term = i.second;
- const pstring name_da = de_alias(term->name());
- bool is_nc_pin(dynamic_cast< devices::NETLIB_NAME(nc_pin) *>(&term->device()) != nullptr);
+ const pstring name_da = de_alias(term->name());
+ bool is_nc_pin(
+ dynamic_cast<devices::NETLIB_NAME(nc_pin) *>(&term->device())
+ != nullptr);
bool is_nc_flagged(false);
auto hnc = m_abstract.m_hints.find(name_da + sHINT_NC);
@@ -1178,16 +1283,19 @@ namespace netlist
else if (term->net().core_terms_empty())
{
if (term->is_logic_input())
- log().warning(MW_LOGIC_INPUT_1_WITHOUT_CONNECTIONS(name_da));
+ log().warning(
+ MW_LOGIC_INPUT_1_WITHOUT_CONNECTIONS(name_da));
else if (term->is_logic_output())
{
if (!is_nc_flagged)
- log().info(MI_LOGIC_OUTPUT_1_WITHOUT_CONNECTIONS(name_da));
+ log().info(
+ MI_LOGIC_OUTPUT_1_WITHOUT_CONNECTIONS(name_da));
}
else if (term->is_analog_output())
{
if (!is_nc_flagged)
- log().info(MI_ANALOG_OUTPUT_1_WITHOUT_CONNECTIONS(name_da));
+ log().info(
+ MI_ANALOG_OUTPUT_1_WITHOUT_CONNECTIONS(name_da));
}
else
log().warning(MW_TERMINAL_1_WITHOUT_CONNECTIONS(name_da));
@@ -1195,7 +1303,7 @@ namespace netlist
}
log().verbose("checking tristate consistency ...");
- for (auto & i : m_terminals)
+ for (auto &i : m_terminals)
{
detail::core_terminal_t *term = i.second;
if (term->is_tristate_output())
@@ -1206,12 +1314,14 @@ namespace netlist
if (iter_proxy == m_proxies.end() && !tri.is_force_logic())
{
- log().error(ME_TRISTATE_NO_PROXY_FOUND_2(term->name(), term->device().name()));
+ log().error(ME_TRISTATE_NO_PROXY_FOUND_2(
+ term->name(), term->device().name()));
err = true;
}
else if (iter_proxy != m_proxies.end() && tri.is_force_logic())
{
- log().error(ME_TRISTATE_PROXY_FOUND_2(term->name(), term->device().name()));
+ log().error(ME_TRISTATE_PROXY_FOUND_2(
+ term->name(), term->device().name()));
err = true;
}
}
@@ -1221,7 +1331,6 @@ namespace netlist
log().fatal(MF_TERMINALS_WITHOUT_NET());
throw nl_exception(MF_TERMINALS_WITHOUT_NET());
}
-
}
void setup_t::move_connections(detail::net_t &net, detail::net_t &dest_net)
@@ -1230,30 +1339,31 @@ namespace netlist
net.remove_all_terminals();
- for (detail::core_terminal_t * ct : temp)
+ for (detail::core_terminal_t *ct : temp)
{
dest_net.add_terminal(*ct);
}
}
- log_type &setup_t::log() noexcept { return m_nlstate.log(); }
+ log_type & setup_t::log() noexcept { return m_nlstate.log(); }
const log_type &setup_t::log() const noexcept { return m_nlstate.log(); }
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// Models
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
- //NOLINTNEXTLINE(misc-no-recursion)
+ // NOLINTNEXTLINE(misc-no-recursion)
void models_t::model_parse(const pstring &model_in, map_t &map)
{
- pstring model = model_in;
+ pstring model = model_in;
std::size_t pos = 0;
- pstring key;
+ pstring key;
while (true)
{
pos = model.find('(');
- if (pos != pstring::npos) break;
+ if (pos != pstring::npos)
+ break;
key = plib::ucase(model);
auto i = m_models.find(key);
@@ -1283,7 +1393,7 @@ namespace netlist
// FIMXE: Not optimal
remainder = plib::left(remainder, remainder.length() - 1);
- const auto pairs(plib::psplit(remainder,' ', true));
+ const auto pairs(plib::psplit(remainder, ' ', true));
for (const pstring &pe : pairs)
{
auto pose = pe.find('=');
@@ -1297,7 +1407,7 @@ namespace netlist
{
// operator [] has no const implementation
pstring ret = map.at("COREMODEL") + "(";
- for (const auto & i : map)
+ for (const auto &i : map)
ret += (i.first + '=' + i.second + ' ');
return ret + ")";
@@ -1308,18 +1418,20 @@ namespace netlist
map_t &map = m_cache[model];
if (map.empty())
- model_parse(model , map);
+ model_parse(model, map);
- return { model, map };
+ return {model, map};
}
pstring models_t::model_t::value_str(const pstring &entity) const
{
if (entity != plib::ucase(entity))
- throw nl_exception(MF_MODEL_PARAMETERS_NOT_UPPERCASE_1_2(entity, model_string(m_map)));
+ throw nl_exception(MF_MODEL_PARAMETERS_NOT_UPPERCASE_1_2(
+ entity, model_string(m_map)));
const auto it(m_map.find(entity));
- if ( it == m_map.end())
- throw nl_exception(MF_ENTITY_1_NOT_FOUND_IN_MODEL_2(entity, model_string(m_map)));
+ if (it == m_map.end())
+ throw nl_exception(
+ MF_ENTITY_1_NOT_FOUND_IN_MODEL_2(entity, model_string(m_map)));
return it->second;
}
@@ -1329,21 +1441,24 @@ namespace netlist
pstring tmp = value_str(entity);
nl_fptype factor = nlconst::one();
- auto p = std::next(tmp.begin(), plib::narrow_cast<pstring::difference_type>(tmp.length() - 1));
+ auto p = std::next(
+ tmp.begin(),
+ plib::narrow_cast<pstring::difference_type>(tmp.length() - 1));
switch (*p)
{
case 'M': factor = nlconst::magic(1e6); break; // NOLINT
case 'k':
- case 'K': factor = nlconst::magic(1e3); break; // NOLINT
- case 'm': factor = nlconst::magic(1e-3); break; // NOLINT
- case 'u': factor = nlconst::magic(1e-6); break; // NOLINT
- case 'n': factor = nlconst::magic(1e-9); break; // NOLINT
+ case 'K': factor = nlconst::magic(1e3); break; // NOLINT
+ case 'm': factor = nlconst::magic(1e-3); break; // NOLINT
+ case 'u': factor = nlconst::magic(1e-6); break; // NOLINT
+ case 'n': factor = nlconst::magic(1e-9); break; // NOLINT
case 'p': factor = nlconst::magic(1e-12); break; // NOLINT
case 'f': factor = nlconst::magic(1e-15); break; // NOLINT
case 'a': factor = nlconst::magic(1e-18); break; // NOLINT
default:
if (*p < '0' || *p > '9')
- throw nl_exception(MF_UNKNOWN_NUMBER_FACTOR_IN_2(m_model, entity));
+ throw nl_exception(
+ MF_UNKNOWN_NUMBER_FACTOR_IN_2(m_model, entity));
}
if (factor != nlconst::one())
tmp = plib::left(tmp, tmp.length() - 1);
@@ -1351,22 +1466,17 @@ namespace netlist
bool err(false);
auto val = plib::pstonum_ne<nl_fptype>(tmp, err);
if (err)
- throw nl_exception(MF_MODEL_NUMBER_CONVERSION_ERROR(entity, tmp, "double", m_model));
+ throw nl_exception(MF_MODEL_NUMBER_CONVERSION_ERROR(
+ entity, tmp, "double", m_model));
return val * factor;
}
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// logic_family_std_proxy_t
//
// FIXME: all this belongs elsewhere
- // ----------------------------------------------------------------------------------------
- PENUM(family_type,
- CUSTOM,
- TTL,
- MOS,
- CMOS,
- NMOS,
- PMOS)
+ // -------------------------------------------------------------------------
+ PENUM(family_type, CUSTOM, TTL, MOS, CMOS, NMOS, PMOS)
class logic_family_std_proxy_t : public logic_family_desc_t
{
@@ -1377,10 +1487,11 @@ namespace netlist
}
// FIXME: create proxies based on family type (far future)
- device_arena::unique_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_state_t &anetlist,
- const pstring &name, const logic_output_t *proxied) const override
+ device_arena::unique_ptr<devices::nld_base_d_to_a_proxy>
+ create_d_a_proxy(netlist_state_t &anetlist, const pstring &name,
+ const logic_output_t *proxied) const override
{
- switch(m_family_type)
+ switch (m_family_type)
{
case family_type::CUSTOM:
case family_type::TTL:
@@ -1388,14 +1499,18 @@ namespace netlist
case family_type::CMOS:
case family_type::NMOS:
case family_type::PMOS:
- return anetlist.make_pool_object<devices::nld_d_to_a_proxy>(anetlist, name, proxied);
+ return anetlist.make_pool_object<devices::nld_d_to_a_proxy>(
+ device_data_t{anetlist, name}, proxied);
}
- return anetlist.make_pool_object<devices::nld_d_to_a_proxy>(anetlist, name, proxied);
+ return anetlist.make_pool_object<devices::nld_d_to_a_proxy>(
+ device_data_t{anetlist, name}, proxied);
}
- device_arena::unique_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, const logic_input_t *proxied) const override
+ device_arena::unique_ptr<devices::nld_base_a_to_d_proxy>
+ create_a_d_proxy(netlist_state_t &anetlist, const pstring &name,
+ const logic_input_t *proxied) const override
{
- switch(m_family_type)
+ switch (m_family_type)
{
case family_type::CUSTOM:
case family_type::TTL:
@@ -1403,14 +1518,18 @@ namespace netlist
case family_type::CMOS:
case family_type::NMOS:
case family_type::PMOS:
- return anetlist.make_pool_object<devices::nld_a_to_d_proxy>(anetlist, name, proxied);
+ return anetlist.make_pool_object<devices::nld_a_to_d_proxy>(
+ device_data_t{anetlist, name}, proxied);
}
- return anetlist.make_pool_object<devices::nld_a_to_d_proxy>(anetlist, name, proxied);
+ return anetlist.make_pool_object<devices::nld_a_to_d_proxy>(
+ device_data_t{anetlist, name}, proxied);
}
+
private:
family_type m_family_type;
};
+ // clang-format off
/// \brief Class representing the logic families.
///
/// This is the model representation of the logic families. This is a
@@ -1426,6 +1545,7 @@ namespace netlist
/// | Y |ORL |Output output resistance for logic 0 | | 0|
/// | Y |ORH |Output output resistance for logic 1 | | 0|
///
+ // clang-format on
class family_model_t
{
public:
@@ -1438,22 +1558,27 @@ namespace netlist
, m_OVH(model, "OVH")
, m_ORL(model, "ORL")
, m_ORH(model, "ORH")
- {}
+ {
+ }
param_model_t::value_str_t m_TYPE; //!< Family type (TTL, CMOS, ...)
- param_model_t::value_t m_IVL; //!< Input voltage low threshold relative to supply voltage
- param_model_t::value_t m_IVH; //!< Input voltage high threshold relative to supply voltage
- param_model_t::value_t m_OVL; //!< Output voltage minimum voltage relative to supply voltage
- param_model_t::value_t m_OVH; //!< Output voltage maximum voltage relative to supply voltage
- param_model_t::value_t m_ORL; //!< Output output resistance for logic 0
- param_model_t::value_t m_ORH; //!< Output output resistance for logic 1
+ param_model_t::value_t m_IVL; //!< Input voltage low threshold relative
+ //!< to supply voltage
+ param_model_t::value_t m_IVH; //!< Input voltage high threshold relative
+ //!< to supply voltage
+ param_model_t::value_t m_OVL; //!< Output voltage minimum voltage
+ //!< relative to supply voltage
+ param_model_t::value_t m_OVH; //!< Output voltage maximum voltage
+ //!< relative to supply voltage
+ param_model_t::value_t m_ORL; //!< Output output resistance for logic 0
+ param_model_t::value_t m_ORH; //!< Output output resistance for logic 1
};
const logic_family_desc_t *setup_t::family_from_model(const pstring &model)
{
family_type ft(family_type::CUSTOM);
- auto mod(m_models.get_model(model));
+ auto mod(m_models.get_model(model));
family_model_t modv(mod);
if (!ft.set_from_string(modv.m_TYPE()))
@@ -1495,30 +1620,35 @@ namespace netlist
return retp;
}
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// Device handling
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
void setup_t::delete_empty_nets()
{
m_nlstate.nets().erase(
- std::remove_if(m_nlstate.nets().begin(), m_nlstate.nets().end(),
+ std::remove_if(
+ m_nlstate.nets().begin(), m_nlstate.nets().end(),
[](device_arena::owned_ptr<detail::net_t> &net)
{
if (net->core_terms_empty())
{
- // FIXME: need to remove from state->m_core_terms as well.
- net->state().log().verbose("Deleting net {1} ...", net->name());
- net->state().run_state_manager().remove_save_items(net.get());
+ // FIXME: need to remove from state->m_core_terms as
+ // well.
+ net->state().log().verbose("Deleting net {1} ...",
+ net->name());
+ net->state().run_state_manager().remove_save_items(
+ net.get());
return true;
}
return false;
- }), m_nlstate.nets().end());
+ }),
+ m_nlstate.nets().end());
}
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// Run preparation
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
void setup_t::prepare_to_run()
{
@@ -1532,55 +1662,68 @@ namespace netlist
// create default parameters first!
- for (auto & e : m_abstract.m_default_params)
+ for (auto &e : m_abstract.m_default_params)
{
- auto param(plib::make_unique<param_str_t, host_arena>(nlstate(), e.first, e.second));
+ auto param(plib::make_unique<param_str_t, host_arena>(
+ nlstate(), e.first, e.second));
register_param_t(*param);
m_defparam_lifetime.push_back(std::move(param));
}
// make sure the solver and parameters are started first!
- for (auto & e : m_abstract.m_device_factory)
+ for (auto &e : m_abstract.m_device_factory)
{
- if ( m_parser.factory().is_class<devices::NETLIB_NAME(solver)>(e.second)
- || m_parser.factory().is_class<devices::NETLIB_NAME(netlistparams)>(e.second))
+ if (m_parser.factory().is_class<devices::NETLIB_NAME(solver)>(
+ e.second)
+ || m_parser.factory()
+ .is_class<devices::NETLIB_NAME(netlistparams)>(e.second))
{
- m_nlstate.register_device(e.first, e.second->make_device(nlstate().pool(), m_nlstate, e.first));
+ m_nlstate.register_device(
+ e.first, e.second->make_device(nlstate().pool(), m_nlstate,
+ e.first));
}
}
log().debug("Searching for solver and parameters ...\n");
- auto *solver = m_nlstate.get_single_device<devices::NETLIB_NAME(solver)>("solver");
- m_netlist_params = m_nlstate.get_single_device<devices::NETLIB_NAME(netlistparams)>("parameter");
+ auto *solver = m_nlstate
+ .get_single_device<devices::NETLIB_NAME(solver)>(
+ "solver");
+ m_netlist_params = m_nlstate.get_single_device<
+ devices::NETLIB_NAME(netlistparams)>("parameter");
// set default model parameters
// FIXME: this is not optimal
- m_parser.register_model(plib::pfmt("NMOS_DEFAULT _(CAPMOD={1})")(m_netlist_params->m_mos_cap_model()));
- m_parser.register_model(plib::pfmt("PMOS_DEFAULT _(CAPMOD={1})")(m_netlist_params->m_mos_cap_model()));
+ m_parser.register_model(plib::pfmt("NMOS_DEFAULT _(CAPMOD={1})")(
+ m_netlist_params->m_mos_cap_model()));
+ m_parser.register_model(plib::pfmt("PMOS_DEFAULT _(CAPMOD={1})")(
+ m_netlist_params->m_mos_cap_model()));
// create devices
log().debug("Creating devices ...\n");
- for (auto & e : m_abstract.m_device_factory)
+ for (auto &e : m_abstract.m_device_factory)
{
- if ( !m_parser.factory().is_class<devices::NETLIB_NAME(solver)>(e.second)
- && !m_parser.factory().is_class<devices::NETLIB_NAME(netlistparams)>(e.second))
+ if (!m_parser.factory().is_class<devices::NETLIB_NAME(solver)>(
+ e.second)
+ && !m_parser.factory()
+ .is_class<devices::NETLIB_NAME(netlistparams)>(
+ e.second))
{
- auto dev = e.second->make_device(m_nlstate.pool(), m_nlstate, e.first);
+ auto dev = e.second->make_device(m_nlstate.pool(), m_nlstate,
+ e.first);
m_nlstate.register_device(dev->name(), std::move(dev));
}
}
- int error_count(0);
-
const bool use_deactivate = m_netlist_params->m_use_deactivate();
for (auto &d : m_nlstate.devices())
{
- auto p = m_abstract.m_hints.find(d.second->name() + sHINT_NO_DEACTIVATE);
+ auto p = m_abstract.m_hints.find(d.second->name()
+ + sHINT_NO_DEACTIVATE);
if (p != m_abstract.m_hints.end())
{
p->second = true; // mark as used
@@ -1590,38 +1733,36 @@ namespace netlist
d.second->set_hint_deactivate(use_deactivate);
}
- if (error_count > 0)
- {
- log().fatal(MF_ERRORS_FOUND(error_count));
- throw nl_exception(MF_ERRORS_FOUND(error_count));
- }
-
// resolve inputs
resolve_inputs();
log().verbose("looking for two terms connected to rail nets ...");
- for (auto & t : m_nlstate.get_device_list<analog::NETLIB_NAME(two_terminal)>())
+ for (auto &t :
+ m_nlstate.get_device_list<analog::NETLIB_NAME(two_terminal)>())
{
if (t->N().net().is_rail_net() && t->P().net().is_rail_net())
{
log().info(MI_REMOVE_DEVICE_1_CONNECTED_ONLY_TO_RAILS_2_3(
t->name(), t->N().net().name(), t->P().net().name()));
- // The following would remove internal devices in e.g. MOSFETs as well.
- #if 0
+ // The following would remove internal devices in e.g. MOSFETs
+ // as well.
+#if 0
remove_terminal(t->setup_N().net(), t->setup_N());
remove_terminal(t->setup_P().net(), t->setup_P());
m_nlstate.remove_device(t);
- #endif
+#endif
}
}
+ int error_count = 0;
+
log().verbose("looking for unused hints ...");
for (auto &h : m_abstract.m_hints)
{
if (!h.second)
{
- log().fatal(MF_UNUSED_HINT_1(h.first));
- throw nl_exception(MF_UNUSED_HINT_1(h.first));
+ log().error(MF_UNUSED_HINT_1(h.first));
+ error_count++;
}
}
@@ -1632,14 +1773,13 @@ namespace netlist
for (auto &p : m_nlstate.nets())
if (p->is_analog())
{
- log().fatal(MF_NO_SOLVER());
- throw nl_exception(MF_NO_SOLVER());
+ log().error(MF_NO_SOLVER());
+ error_count++;
}
}
else
solver->post_start();
- error_count = 0;
log().debug("Looking for unknown parameters ...\n");
for (auto &p : m_abstract.m_param_values)
{
@@ -1650,66 +1790,78 @@ namespace netlist
error_count++;
}
}
- if (error_count > 0)
- {
- log().fatal(MF_ERRORS_FOUND(error_count));
- throw nl_exception(MF_ERRORS_FOUND(error_count));
- }
for (auto &n : m_nlstate.nets())
{
- for (detail::core_terminal_t * term : n->core_terms_copy())
+ for (detail::core_terminal_t *term : n->core_terms_copy())
if (term->delegate().isnull())
{
- log().fatal(MF_DELEGATE_NOT_SET_1(term->name()));
- throw nl_exception(MF_DELEGATE_NOT_SET_1(term->name()));
+ log().error(MF_DELEGATE_NOT_SET_1(term->name()));
+ error_count++;
}
n->rebuild_list();
}
+
+ if (error_count > 0)
+ {
+ log().fatal(MF_ERRORS_FOUND(error_count));
+ throw nl_exception(MF_ERRORS_FOUND(error_count));
+ }
}
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// base sources
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
bool source_netlist_t::parse(nlparse_t &setup, const pstring &name)
{
auto strm(stream(name));
- return (!strm.empty()) ? setup.parse_stream(std::move(strm), name) : false;
+ return (!strm.empty()) ? setup.parse_stream(std::move(strm), name)
+ : false;
}
- plib::istream_uptr source_string_t::stream([[maybe_unused]] const pstring &name)
+ plib::istream_uptr
+ source_string_t::stream([[maybe_unused]] const pstring &name)
{
- plib::istream_uptr ret(std::make_unique<std::istringstream>(putf8string(m_str)), name);
+ plib::istream_uptr ret(
+ std::make_unique<std::istringstream>(putf8string(m_str)), name);
ret->imbue(std::locale::classic());
return ret;
}
- plib::istream_uptr source_mem_t::stream([[maybe_unused]] const pstring &name)
+ plib::istream_uptr
+ source_mem_t::stream([[maybe_unused]] const pstring &name)
{
- plib::istream_uptr ret(std::make_unique<std::istringstream>(m_str, std::ios_base::binary), name);
+ plib::istream_uptr ret(
+ std::make_unique<std::istringstream>(m_str, std::ios_base::binary),
+ name);
ret->imbue(std::locale::classic());
return ret;
}
- plib::istream_uptr source_file_t::stream([[maybe_unused]] const pstring &name)
+ plib::istream_uptr
+ source_file_t::stream([[maybe_unused]] const pstring &name)
{
- auto f = std::make_unique<plib::ifstream>(plib::filesystem::u8path(m_filename));
+ auto f = std::make_unique<plib::ifstream>(
+ plib::filesystem::u8path(m_filename));
if (f->is_open())
{
- return { std::move(f), m_filename };
+ return {std::move(f), m_filename};
}
return plib::istream_uptr();
}
- plib::istream_uptr source_pattern_t::stream([[maybe_unused]] const pstring &name)
+ plib::istream_uptr
+ source_pattern_t::stream([[maybe_unused]] const pstring &name)
{
- pstring filename = plib::pfmt(m_pattern)(m_force_lowercase ? plib::lcase(name) : name);
- auto f = std::make_unique<plib::ifstream>(plib::filesystem::u8path(filename));
+ pstring filename = plib::pfmt(m_pattern)(
+ m_force_lowercase ? plib::lcase(name) : name);
+ auto f = std::make_unique<plib::ifstream>(
+ plib::filesystem::u8path(filename));
if (f->is_open())
{
- return { std::move(f), filename };
+ return {std::move(f), filename};
}
return plib::istream_uptr();
@@ -1726,10 +1878,10 @@ namespace netlist
return false;
}
- plib::istream_uptr source_proc_t::stream([[maybe_unused]] const pstring &name)
+ plib::istream_uptr
+ source_proc_t::stream([[maybe_unused]] const pstring &name)
{
return plib::istream_uptr();
}
} // namespace netlist
-
diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h
index d22b78c3703..dad4f894375 100644
--- a/src/lib/netlist/nl_setup.h
+++ b/src/lib/netlist/nl_setup.h
@@ -107,15 +107,26 @@ void NETLIST_NAME(name)([[maybe_unused]] netlist::nlparse_t &setup) \
// truth table defines
// -----------------------------------------------------------------------------
+#if 0
#define TRUTHTABLE_START(cname, in, out, pdef_params) \
- NETLIST_START(cname) \
- netlist::tt_desc desc; \
- desc.name = #cname ; \
- desc.ni = in; \
- desc.no = out; \
- desc.family = ""; \
+ void NETLIST_NAME(cname ## _impl)(netlist::tt_desc &desc); \
+ static NETLIST_START(cname) \
+ netlist::tt_desc xdesc{ #cname, in, out, "" }; \
auto sloc = PSOURCELOC(); \
- const pstring def_params = pdef_params;
+ const pstring def_params = pdef_params; \
+ NETLIST_NAME(cname ## _impl)(xdesc); \
+ setup.truth_table_create(xdesc, def_params, std::move(sloc)); \
+ NETLIST_END() \
+ static void NETLIST_NAME(cname ## _impl)(netlist::tt_desc &desc) \
+ {
+#else
+#define TRUTHTABLE_START(cname, in, out, pdef_params) \
+ NETLIST_START(cname) \
+ netlist::tt_desc desc{ #cname, in, out, "", {} }; \
+ auto sloc = PSOURCELOC(); \
+ const pstring def_params = pdef_params; \
+ plib::functor_guard lg([&](){ setup.truth_table_create(desc, def_params, std::move(sloc)); });
+#endif
#define TT_HEAD(x) \
desc.desc.emplace_back(x);
@@ -127,7 +138,6 @@ void NETLIST_NAME(name)([[maybe_unused]] netlist::nlparse_t &setup) \
desc.family = x;
#define TRUTHTABLE_END() \
- setup.truth_table_create(desc, def_params, std::move(sloc)); \
NETLIST_END()
#define TRUTHTABLE_ENTRY(name) \
@@ -143,12 +153,11 @@ namespace netlist
struct tt_desc
{
- tt_desc() : ni(0), no(0) { }
pstring name;
unsigned long ni;
unsigned long no;
- std::vector<pstring> desc;
pstring family;
+ std::vector<pstring> desc;
};
// ----------------------------------------------------------------------------------------
@@ -174,7 +183,7 @@ namespace netlist
// last argument only needed by nltool
void register_dev(const pstring &classname, const pstring &name,
const std::vector<pstring> &params_and_connections,
- factory::element_t **felem = nullptr);
+ factory::element_t **factory_element = nullptr);
void register_dev(const pstring &classname, std::initializer_list<const char *> more_parameters);
void register_dev(const pstring &classname, const pstring &name)
{
diff --git a/src/lib/netlist/nltypes.h b/src/lib/netlist/nltypes.h
index 6dcef5ad1df..3e36fd912d9 100644
--- a/src/lib/netlist/nltypes.h
+++ b/src/lib/netlist/nltypes.h
@@ -24,8 +24,7 @@
/// \brief Construct a netlist device name
///
-#define NETLIB_NAME(chip) nld_ ## chip
-
+#define NETLIB_NAME(chip) nld_##chip
namespace netlist
{
@@ -43,14 +42,24 @@ namespace netlist
class netlist_t;
class netlist_state_t;
class core_device_t;
+ class base_device_t;
class device_t;
class netlist_state_t;
class param_t;
class logic_family_desc_t;
+ class logic_family_std_proxy_t;
class terminal_t;
+ template <typename CX>
+ struct sub_device_wrapper;
+
class models_t;
+ namespace analog
+ {
+ class NETLIB_NAME(two_terminal);
+ } // namespace analog
+
namespace devices
{
class nld_solver;
@@ -59,6 +68,9 @@ namespace netlist
class nld_base_d_to_a_proxy;
class nld_base_a_to_d_proxy;
class nld_netlistparams;
+
+ template <unsigned m_NI, unsigned m_NO>
+ class factory_truth_table_t;
} // namespace devices
namespace solver
@@ -76,20 +88,15 @@ namespace netlist
namespace factory
{
+ template <class C, typename... Args>
+ class device_element_t;
+ class library_element_t;
+
class list_t;
class element_t;
struct properties;
} // namespace factory
- template <class CX>
- class delegator_t : public CX
- {
- protected:
- using base_type = delegator_t<CX>;
- using delegated_type = CX;
- using delegated_type::delegated_type;
- };
-
} // namespace netlist
@@ -98,15 +105,20 @@ namespace netlist
/// \brief Constants and const calculations for the library
///
- template<typename T>
+ template <typename T>
struct nlconst_base : public plib::constants<T>
{
using BC = plib::constants<T>;
- static constexpr T np_VT(T n=BC::one(), T temp=BC::T0()) noexcept
- { return n * temp * BC::k_b() / BC::Q_e(); }
+ static constexpr T np_VT(T n = BC::one(), T temp = BC::T0()) noexcept
+ {
+ return n * temp * BC::k_b() / BC::Q_e();
+ }
- static constexpr T np_Is() noexcept { return static_cast<T>(1e-15); } // NOLINT
+ static constexpr T np_Is() noexcept
+ {
+ return static_cast<T>(1e-15);
+ } // NOLINT
/// \brief constant startup gmin
///
@@ -114,20 +126,32 @@ namespace netlist
/// conductivities with a reasonable value.
/// During reset, the object should than make use of exec().gmin()
/// to use the actual gmin() value.
- static constexpr T cgmin() noexcept { return BC::magic(1e-9); } // NOLINT
+ static constexpr T cgmin() noexcept
+ {
+ return BC::magic(1e-9);
+ } // NOLINT
// FIXME: Some objects used 1e-15 for initial gmin. Needs to be
// aligned with cgmin
- static constexpr T cgminalt() noexcept { return BC::magic(1e-15); } // NOLINT
+ static constexpr T cgminalt() noexcept
+ {
+ return BC::magic(1e-15);
+ } // NOLINT
- /// \brief Multiplier applied to VT in np diode models to determine range for constant model
+ /// \brief Multiplier applied to VT in np diode models to determine
+ /// range for constant model
///
- static constexpr T diode_min_cutoff_mult() noexcept { return BC::magic(-5.0); } // NOLINT
+ static constexpr T diode_min_cutoff_mult() noexcept
+ {
+ return BC::magic(-5.0);
+ } // NOLINT
/// \brief Startup voltage used by np diode models
///
- static constexpr T diode_start_voltage() noexcept { return BC::magic(0.7); } // NOLINT
-
+ static constexpr T diode_start_voltage() noexcept
+ {
+ return BC::magic(0.7);
+ } // NOLINT
};
/// \brief nlconst_base struct specialized for nl_fptype.
@@ -149,11 +173,12 @@ namespace netlist
///
using device_arena = std::conditional_t<config::use_mempool::value,
- plib::mempool_arena<plib::aligned_arena<>, config::mempool_align::value>,
+ plib::mempool_arena<plib::aligned_arena<>,
+ config::mempool_align::value>,
plib::aligned_arena<>>;
- using host_arena = plib::aligned_arena<>;
+ using host_arena = plib::aligned_arena<>;
- using log_type = plib::plog_base<NL_DEBUG>;
+ using log_type = plib::plog_base<NL_DEBUG>;
//============================================================
// Types needed by various includes
@@ -165,49 +190,69 @@ namespace netlist
///
enum class time_step_type
{
- FORWARD, ///< forward time
- RESTORE ///< restore state before last forward
+ FORWARD, ///< forward time
+ RESTORE ///< restore state before last forward
};
/// \brief Delegate type for device notification.
///
- using nl_delegate = plib::pmfp<void ()>;
- using nl_delegate_ts = plib::pmfp<void (time_step_type, nl_fptype)>;
- using nl_delegate_dyn = plib::pmfp<void ()>;
+ using nl_delegate = plib::pmfp<void()>;
+ using nl_delegate_ts = plib::pmfp<void(time_step_type, nl_fptype)>;
+ using nl_delegate_dyn = plib::pmfp<void()>;
- namespace detail {
+ namespace detail
+ {
/// \brief Enum specifying the type of object
///
- enum class terminal_type {
+ enum class terminal_type
+ {
TERMINAL = 0, ///< object is an analog terminal
- INPUT = 1, ///< object is an input
- OUTPUT = 2, ///< object is an output
+ INPUT = 1, ///< object is an input
+ OUTPUT = 2, ///< object is an output
};
} // namespace detail
using netlist_time = plib::ptime<std::int64_t, config::INTERNAL_RES::value>;
- using netlist_time_ext = plib::ptime<std::conditional<config::prefer_int128::value && plib::compile_info::has_int128::value, INT128, std::int64_t>::type, config::INTERNAL_RES::value>;
+ using netlist_time_ext = plib::ptime<
+ std::conditional<config::prefer_int128::value
+ && plib::compile_info::has_int128::value,
+ INT128, std::int64_t>::type,
+ config::INTERNAL_RES::value>;
- static_assert(noexcept(netlist_time::from_nsec(1)), "Not evaluated as constexpr");
+ static_assert(noexcept(netlist_time::from_nsec(1)),
+ "Not evaluated as constexpr");
//============================================================
// MACROS
//============================================================
- template <typename T> constexpr netlist_time NLTIME_FROM_NS(T &&t) noexcept { return netlist_time::from_nsec(t); }
- template <typename T> constexpr netlist_time NLTIME_FROM_US(T &&t) noexcept { return netlist_time::from_usec(t); }
- template <typename T> constexpr netlist_time NLTIME_FROM_MS(T &&t) noexcept { return netlist_time::from_msec(t); }
+ template <typename T>
+ constexpr netlist_time NLTIME_FROM_NS(T &&t) noexcept
+ {
+ return netlist_time::from_nsec(t);
+ }
+ template <typename T>
+ constexpr netlist_time NLTIME_FROM_US(T &&t) noexcept
+ {
+ return netlist_time::from_usec(t);
+ }
+ template <typename T>
+ constexpr netlist_time NLTIME_FROM_MS(T &&t) noexcept
+ {
+ return netlist_time::from_msec(t);
+ }
struct desc_base
{
/// \brief: used to hold one static netlist_time value
///
- template<netlist_time::internal_type value0>
+ template <netlist_time::internal_type value0>
struct times_ns1
{
- static constexpr netlist_time value([[maybe_unused]] std::size_t N = 0)
+ static constexpr netlist_time value(
+ [[maybe_unused]] std::size_t N = 0)
{
return NLTIME_FROM_NS(value0);
}
@@ -218,8 +263,8 @@ namespace netlist
/// \brief: used to hold two static netlist_time values
///
- template<netlist_time::internal_type value0,
- netlist_time::internal_type value1>
+ template <netlist_time::internal_type value0,
+ netlist_time::internal_type value1>
struct times_ns2
{
static constexpr netlist_time value(std::size_t N)
@@ -230,16 +275,16 @@ namespace netlist
/// \brief: used to hold three static netlist_time values
///
- template<netlist_time::internal_type value0,
- netlist_time::internal_type value1,
- netlist_time::internal_type value2>
+ template <netlist_time::internal_type value0,
+ netlist_time::internal_type value1,
+ netlist_time::internal_type value2>
struct times_ns3
{
static constexpr netlist_time value(std::size_t N)
{
- return N == 0 ? NLTIME_FROM_NS(value0) :
- N == 1 ? NLTIME_FROM_NS(value1) :
- NLTIME_FROM_NS(value2);
+ return N == 0 ? NLTIME_FROM_NS(value0)
+ : N == 1 ? NLTIME_FROM_NS(value1)
+ : NLTIME_FROM_NS(value2);
}
};
@@ -248,10 +293,10 @@ namespace netlist
/// See the 74125 implementation
///
template <std::size_t V>
- using desc_const = std::integral_constant<const std::size_t, V>;
+ using desc_const = std::integral_constant<const std::size_t, V>;
template <typename T, T V>
- using desc_const_t = std::integral_constant<const T, V>;
+ using desc_const_t = std::integral_constant<const T, V>;
};
//============================================================
@@ -268,20 +313,24 @@ namespace netlist
/// Allows a descriptive text to be passed to the exception
explicit nl_exception(const pstring &text //!< text to be passed
- )
- : plib::pexception(text) { }
+ )
+ : plib::pexception(text)
+ {
+ }
/// \brief Constructor.
/// Allows to use \ref plib::pfmt logic to be used in exception
- template<typename... Args>
+ template <typename... Args>
explicit nl_exception(const pstring &fmt //!< format to be used
- , Args&&... args //!< arguments to be passed
+ ,
+ Args &&...args //!< arguments to be passed
)
- : plib::pexception(plib::pfmt(fmt)(std::forward<Args>(args)...)) { }
+ : plib::pexception(plib::pfmt(fmt)(std::forward<Args>(args)...))
+ {
+ }
};
} // namespace netlist
-
#endif // NLTYPES_H_
diff --git a/src/lib/netlist/plib/pexception.cpp b/src/lib/netlist/plib/pexception.cpp
index 260fa908bf0..168cb172473 100644
--- a/src/lib/netlist/plib/pexception.cpp
+++ b/src/lib/netlist/plib/pexception.cpp
@@ -20,7 +20,7 @@ namespace plib {
// terminate
//============================================================
- void terminate(const char *msg) noexcept
+ [[noreturn]] void terminate(const char *msg) noexcept
{
try
{
diff --git a/src/lib/netlist/plib/pexception.h b/src/lib/netlist/plib/pexception.h
index 641d7a70e6d..bf2a286e81e 100644
--- a/src/lib/netlist/plib/pexception.h
+++ b/src/lib/netlist/plib/pexception.h
@@ -104,7 +104,7 @@ namespace plib {
class fp_signal_enabler
{
public:
- explicit fp_signal_enabler(unsigned fpexceptions);
+ explicit fp_signal_enabler(unsigned fp_exceptions);
PCOPYASSIGNMOVE(fp_signal_enabler, delete)
diff --git a/src/lib/netlist/plib/pfmtlog.cpp b/src/lib/netlist/plib/pfmtlog.cpp
index 64a9d8791ae..188c04f4cf7 100644
--- a/src/lib/netlist/plib/pfmtlog.cpp
+++ b/src/lib/netlist/plib/pfmtlog.cpp
@@ -39,7 +39,7 @@ private:
};
#endif
-pfmt::rtype pfmt::set_format(std::stringstream &strm, char32_t cfmt_spec)
+pfmt::rtype pfmt::set_format(std::stringstream &strm, char32_t char_format)
{
pstring fmt;
pstring search("{");
@@ -92,18 +92,18 @@ pfmt::rtype pfmt::set_format(std::stringstream &strm, char32_t cfmt_spec)
// a.b format here ...
char32_t pend(0);
int width(0);
- if (!fmt.empty() && pstring("duxofge").find(static_cast<pstring::value_type>(cfmt_spec)) != pstring::npos)
+ if (!fmt.empty() && pstring("duxofge").find(static_cast<pstring::value_type>(char_format)) != pstring::npos)
{
//pend = static_cast<char32_t>(fmt.at(fmt.size() - 1));
pend = plib::right(fmt, 1).at(0);
if (pstring("duxofge").find(static_cast<pstring::value_type>(pend)) == pstring::npos)
- pend = cfmt_spec;
+ pend = char_format;
else
fmt = plib::left(fmt, fmt.length() - 1);
}
else
// FIXME: Error
- pend = cfmt_spec;
+ pend = char_format;
auto pdot(fmt.find('.'));
diff --git a/src/lib/netlist/plib/pfmtlog.h b/src/lib/netlist/plib/pfmtlog.h
index 1586deacf3c..2e45498c637 100644
--- a/src/lib/netlist/plib/pfmtlog.h
+++ b/src/lib/netlist/plib/pfmtlog.h
@@ -375,7 +375,7 @@ namespace plib {
if (build_enabled && enabled && m_enabled)
{
pfmt pf(fmt);
- dynamic_cast<T &>(*this).upstream_write(log_translate(pf, std::forward<Args>(args)...));
+ plib::dynamic_downcast<T &>(*this).upstream_write(log_translate(pf, std::forward<Args>(args)...));
}
}
diff --git a/src/lib/netlist/plib/pgsl.h b/src/lib/netlist/plib/pgsl.h
index 3125df5cc00..b585e3ed9e3 100644
--- a/src/lib/netlist/plib/pgsl.h
+++ b/src/lib/netlist/plib/pgsl.h
@@ -19,6 +19,7 @@
#include "ptypes.h"
#include <exception>
+#include <optional>
#include <type_traits>
#include <utility>
@@ -101,6 +102,54 @@ namespace plib {
} // namespace pgsl
+ /// \brief dynamic downcast from base type pointer to derived type pointer
+ ///
+ /// This is a `noexcept` dynamic_cast implementation. It will return the cast
+ /// wrapped into a std::optional type forcing the caller to
+ /// examine if the conversion was successful.
+ ///
+ /// \tparam D Derived type
+ /// \tparam B Base type
+ /// \param base pointer to type B
+ /// \returns return_success_t
+ ///
+ template <typename D, typename B>
+ std::enable_if_t<std::is_pointer_v<D> && std::is_pointer_v<std::remove_reference_t<B>>,
+ std::optional<D>>
+ dynamic_downcast(B base) noexcept
+ {
+ D ret = dynamic_cast<D>(base);
+ if (ret != nullptr)
+ return ret;
+ return std::nullopt;
+ }
+
+ /// \brief dynamic downcast from base type reference to derived type pointer
+ ///
+ /// This is a `noexcept` dynamic_cast implementation. It will return the
+ /// pointer cast wrapped into a std::optional type forcing the caller to
+ /// examine if the conversion was successful.
+ ///
+ /// The return value is a pointer cast since there is no std::optional for
+ /// references. Such a construct is considered ill-formed according to
+ /// the std::optional specification (Section 5.2, p1).
+ ///
+ /// \tparam D Derived type
+ /// \tparam B Base type
+ /// \param base reference of type B
+ /// \returns return_success_t
+ ///
+ template <typename D, typename B>
+ std::enable_if_t<std::is_pointer_v<D> &&!std::is_pointer_v<std::remove_reference_t<B>> ,
+ std::optional<D>>
+ dynamic_downcast(B &base) noexcept
+ {
+ D ret = dynamic_cast<D>(&base);
+ if (ret != nullptr)
+ return ret;
+ return std::nullopt;
+ }
+
/// \brief downcast from base type to derived type
///
/// The cpp core guidelines require a very careful use of static cast
@@ -110,8 +159,8 @@ namespace plib {
template <typename D, typename B>
constexpr D downcast(B && b) noexcept
{
- static_assert(std::is_pointer<D>::value || std::is_reference<D>::value, "downcast only supports pointers or reference for derived");
- static_assert(std::is_pointer<B>::value || std::is_reference<B>::value, "downcast only supports pointers or reference for base");
+ static_assert((std::is_pointer<D>::value && std::is_pointer<B>::value)
+ || (std::is_reference<D>::value && std::is_reference<B>::value), "downcast only supports pointers or reference for derived");
return static_cast<D>(std::forward<B>(b));
}
diff --git a/src/lib/netlist/plib/pmatrix_cr.h b/src/lib/netlist/plib/pmatrix_cr.h
index ec1729dae72..74175e07101 100644
--- a/src/lib/netlist/plib/pmatrix_cr.h
+++ b/src/lib/netlist/plib/pmatrix_cr.h
@@ -505,7 +505,7 @@ namespace plib
~pLUmatrix_cr() = default;
template <typename M>
- void build(M &fill, std::size_t ilup) noexcept
+ void build(M &fill, std::size_t ilup) noexcept(false)
{
std::size_t p(0);
// build ilu_rows
diff --git a/src/lib/netlist/plib/poptions.h b/src/lib/netlist/plib/poptions.h
index 4d9544dd890..a758c446ff9 100644
--- a/src/lib/netlist/plib/poptions.h
+++ b/src/lib/netlist/plib/poptions.h
@@ -132,7 +132,7 @@ namespace plib {
protected:
int parse(const pstring &argument) override
{
- auto raw = plib::container::indexof(limit(), argument);
+ auto raw = plib::container::index_of(limit(), argument);
if (raw != plib::container::npos)
{
diff --git a/src/lib/netlist/plib/ppmf.cpp b/src/lib/netlist/plib/ppmf.cpp
index 05493f98d2f..85088b25638 100644
--- a/src/lib/netlist/plib/ppmf.cpp
+++ b/src/lib/netlist/plib/ppmf.cpp
@@ -83,8 +83,8 @@ namespace plib {
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
std::uint8_t const *const vptr = *reinterpret_cast<std::uint8_t const *const *>(byteptr);
// and add offset to virtual base from vtable
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
if (sizeof(unknown_base_equiv) == m_size)
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
byteptr += *reinterpret_cast<int const *>(vptr + m_vt_index);
}
diff --git a/src/lib/netlist/plib/ppmf.h b/src/lib/netlist/plib/ppmf.h
index b0612c6aea9..56f40bde922 100644
--- a/src/lib/netlist/plib/ppmf.h
+++ b/src/lib/netlist/plib/ppmf.h
@@ -577,7 +577,7 @@ namespace plib {
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto p = reinterpret_cast<const typename late_pmfp<T>::traits::template specific_member_function<O> *>(raw);
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- auto o = reinterpret_cast<O *>(obj);
+ auto *o = reinterpret_cast<O *>(obj);
return return_type(*p, o);
}
diff --git a/src/lib/netlist/plib/psource.h b/src/lib/netlist/plib/psource.h
index a26480aaad9..80a313ec415 100644
--- a/src/lib/netlist/plib/psource.h
+++ b/src/lib/netlist/plib/psource.h
@@ -140,10 +140,9 @@ namespace plib
{
for (auto &s : m_collection)
{
- auto *source(dynamic_cast<S *>(s.get()));
- if (source)
+ if (auto source = plib::dynamic_downcast<S *>(s.get()))
{
- auto strm = source->stream(name);
+ auto strm = (*source)->stream(name);
if (!strm.empty())
return strm;
}
@@ -156,10 +155,9 @@ namespace plib
{
for (auto &s : m_collection)
{
- auto *source(dynamic_cast<S *>(s.get()));
- if (source)
+ if (auto source = plib::dynamic_downcast<S *>(s.get()))
{
- if (lambda(source))
+ if (lambda(*source))
return true;
}
}
diff --git a/src/lib/netlist/plib/ptests.h b/src/lib/netlist/plib/ptests.h
index 5b385c0b9db..cc05b120b96 100644
--- a/src/lib/netlist/plib/ptests.h
+++ b/src/lib/netlist/plib/ptests.h
@@ -175,7 +175,14 @@ namespace plib::testing
reg_entry_base(const char *n, const char *d, test_location l)
: name(n), desc(d), location(l)
{
- registry().push_back(this);
+ try
+ {
+ registry().push_back(this);
+ }
+ catch (...)
+ {
+ std::terminate();
+ }
}
reg_entry_base(const reg_entry_base &) = delete;
@@ -253,22 +260,22 @@ namespace plib::testing
t->set_parameters(&params);
})).first)
{
- stream_error(std::cout, e->location) << "unexpected exception thrown during instantiation" << (r.second != "" ? ": " + r.second : "") << std::endl;
+ stream_error(std::cout, e->location) << "unexpected exception thrown during instantiation" << (!r.second.empty() ? ": " + r.second : "") << std::endl;
total_errors++;
}
else if ((r = catch_exception([&]{ t->SetUp(); })).first)
{
- stream_error(std::cout, e->location) << "unexpected exception thrown during Setup" << (r.second != "" ? ": " + r.second : "") << std::endl;
+ stream_error(std::cout, e->location) << "unexpected exception thrown during Setup" << (!r.second.empty() ? ": " + r.second : "") << std::endl;
total_errors++;
}
else if ((r = catch_exception([&]{ t->run(); })).first)
{
- stream_error(std::cout, params.m_last_source) << "unexpected exception thrown during run after this line" << (r.second != "" ? ": " + r.second : "") << std::endl;
+ stream_error(std::cout, params.m_last_source) << "unexpected exception thrown during run after this line" << (!r.second.empty() ? ": " + r.second : "") << std::endl;
total_errors++;
}
else if ((r = catch_exception([&]{ t->TearDown(); })).first)
{
- stream_error(std::cout, e->location) << "unexpected exception thrown during Teardown" << (r.second != "" ? ": " + r.second : "") << std::endl;
+ stream_error(std::cout, e->location) << "unexpected exception thrown during Teardown" << (!r.second.empty() ? ": " + r.second : "") << std::endl;
total_errors++;
}
diff --git a/src/lib/netlist/plib/ptokenizer.cpp b/src/lib/netlist/plib/ptokenizer.cpp
index 98be18b6419..59468bf84cd 100644
--- a/src/lib/netlist/plib/ptokenizer.cpp
+++ b/src/lib/netlist/plib/ptokenizer.cpp
@@ -69,16 +69,16 @@ namespace plib {
m_unget = c;
}
- void tokenizer_t::append_to_store(putf8_reader *reader, token_store_t &tokstor)
+ void tokenizer_t::append_to_store(putf8_reader *reader, token_store_t &store)
{
clear();
m_strm = reader;
// Process tokens into queue
token_t ret(token_type::UNKNOWN);
- m_token_queue = &tokstor;
+ m_token_queue = &store;
do {
ret = get_token_comment();
- tokstor.push_back(ret);
+ store.push_back(ret);
} while (!ret.is_type(token_type::token_type::ENDOFFILE));
m_token_queue = nullptr;
}
@@ -300,28 +300,26 @@ namespace plib {
}
return { token_type::STRING, tokstr };
}
- else
+
+ // read identifier till first identifier char or ws
+ pstring tokstr = "";
+ while ((m_identifier_chars.find(c) == pstring::npos) && (m_whitespace.find(c) == pstring::npos))
{
- // read identifier till first identifier char or ws
- pstring tokstr = "";
- while ((m_identifier_chars.find(c) == pstring::npos) && (m_whitespace.find(c) == pstring::npos))
+ tokstr += c;
+ // expensive, check for single char tokens
+ if (tokstr.length() == 1)
{
- tokstr += c;
- // expensive, check for single char tokens
- if (tokstr.length() == 1)
- {
- auto id = m_tokens.find(tokstr);
- if (id != m_tokens.end())
- return { id->second, tokstr };
- }
- c = getc();
+ auto id = m_tokens.find(tokstr);
+ if (id != m_tokens.end())
+ return { id->second, tokstr };
}
- ungetc(c);
- auto id = m_tokens.find(tokstr);
- return (id != m_tokens.end()) ?
- token_t(id->second, tokstr)
- : token_t(token_type::UNKNOWN, tokstr);
+ c = getc();
}
+ ungetc(c);
+ auto id = m_tokens.find(tokstr);
+ return (id != m_tokens.end()) ?
+ token_t(id->second, tokstr)
+ : token_t(token_type::UNKNOWN, tokstr);
}
token_reader_t::token_t tokenizer_t::get_token_comment()
diff --git a/src/lib/netlist/plib/putil.h b/src/lib/netlist/plib/putil.h
index 734442ff96a..ae383aaf807 100644
--- a/src/lib/netlist/plib/putil.h
+++ b/src/lib/netlist/plib/putil.h
@@ -17,15 +17,18 @@
#include <sstream>
#include <vector>
-#define PSTRINGIFY_HELP(y) # y
+#define PSTRINGIFY_HELP(y) #y
#define PSTRINGIFY(x) PSTRINGIFY_HELP(x)
-// Discussion and background of this MSVC bug: https://github.com/mamedev/mame/issues/6106
+// Discussion and background of this MSVC bug:
+// https://github.com/mamedev/mame/issues/6106
///
/// \brief Macro to work around a bug in MSVC treatment of __VA_ARGS__
///
#define PMSVC_VARARG_BUG(MACRO, ARGS) MACRO ARGS
+// clang-format off
+
/// \brief Determine number of arguments in __VA_ARGS__
///
/// This macro works up to 16 arguments in __VA_ARGS__
@@ -70,13 +73,16 @@
#define PSTRINGIFY_16(x, x2, x3, x4, x5, x6, x7, x8, x9, xa, xb, xc, xd, xe, xf, x10) \
#x, #x2, #x3, #x4, #x5, #x6, #x7, #x8, #x9, #xa, #xb, #xc, #xd, #xe, #xf, #x10
+// clang-format on
+
/// \brief Individually stringify up to 16 arguments
///
/// PSTRINGIFY_VA(a, b, c) will be expanded to "a", "b", "c"
///
/// \returns List of stringified individual arguments
///
-#define PSTRINGIFY_VA(...) PMSVC_VARARG_BUG(PCONCAT, (PSTRINGIFY_, PNARGS(__VA_ARGS__)))(__VA_ARGS__)
+#define PSTRINGIFY_VA(...) \
+ PMSVC_VARARG_BUG(PCONCAT, (PSTRINGIFY_, PNARGS(__VA_ARGS__)))(__VA_ARGS__)
/// \brief Dispatch VARARG macro to specialized macros
///
@@ -93,7 +99,8 @@
///
/// \returns result of specialized macro
///
-#define PCALLVARARG(MAC, ...) PMSVC_VARARG_BUG(PCONCAT, (MAC, PNARGS(__VA_ARGS__)))(__VA_ARGS__)
+#define PCALLVARARG(MAC, ...) \
+ PMSVC_VARARG_BUG(PCONCAT, (MAC, PNARGS(__VA_ARGS__)))(__VA_ARGS__)
// FIXME:: __FUNCTION__ may be not be supported by all compilers.
@@ -107,7 +114,7 @@ namespace plib
pstring basename(const pstring &filename, const pstring &suffix = "");
pstring path(const pstring &filename);
bool exists(const pstring &filename);
- pstring build_path(std::initializer_list<pstring> list );
+ pstring build_path(std::initializer_list<pstring> list);
pstring environment(const pstring &var, const pstring &default_val);
} // namespace util
@@ -121,7 +128,7 @@ namespace plib
static constexpr const std::size_t npos = static_cast<std::size_t>(-1);
template <class C>
- std::size_t indexof(C &con, const typename C::value_type &elem)
+ std::size_t index_of(C &con, const typename C::value_type &elem)
{
auto it = std::find(con.begin(), con.end(), elem);
if (it != con.end())
@@ -130,7 +137,8 @@ namespace plib
}
template <class C>
- void insert_at(C &con, const std::size_t index, const typename C::value_type &elem)
+ void insert_at(C &con, const std::size_t index,
+ const typename C::value_type &elem)
{
con.insert(con.begin() + narrow_cast<std::ptrdiff_t>(index), elem);
}
@@ -142,19 +150,72 @@ namespace plib
}
} // namespace container
- // ----------------------------------------------------------------------------------------
- // simple hash
- // ----------------------------------------------------------------------------------------
-
+ /// \brief Consistent hash implementation
+ ///
+ /// Hash implementations in c++ standard libraries may differ and deliver
+ /// different results. This hash can be used as a replacement hash in e.g.
+ /// std::map to deliver consistent results.
+ ///
+ /// \tparam V result type
+ /// \tparam T buffer element type
+ /// \param buf pointer to buffer for which hash should be calculated
+ /// \param size number of buffer elements
+ /// \return the hash of the buffer
+ ///
template <typename V, typename T>
constexpr V hash(const T *buf, std::size_t size) noexcept
{
V result = 5381; // NOLINT
- for (const T* p = buf; p != buf + size; p++)
- result = ((result << 5) + result ) ^ (result >> (32 - 5)) ^ narrow_cast<std::size_t>(*p); // NOLINT
+ for (const T *p = buf; p != buf + size; p++)
+ result = ((result << 5) + result) ^ (result >> (32 - 5))
+ ^ narrow_cast<std::size_t>(*p); // NOLINT
return result;
}
+ /// \brief Execute code at end of block
+ ///
+ /// The class can be used to execute code at the end of a block. It follows
+ /// the same design as std::lock_guard.
+ ///
+ /// Since the functor is executed in the destructor of the class the
+ /// execution is protected by a try catch block. If an exception is raised,
+ /// \ref plib::terminate is called.
+ ///
+ /// \tparam F type of functor - will be derived by template deduction guide
+ ///
+ template <typename F>
+ struct functor_guard
+ {
+ /// \brief constructor
+ ///
+ /// \param f functor to execute
+ functor_guard(F &&f)
+ : m_f(std::move(f))
+ {
+ }
+ /// \brief destructor
+ ///
+ ~functor_guard()
+ {
+ try
+ {
+ m_f();
+ }
+ catch (...)
+ {
+ plib::terminate("exception raised in lambda_guard");
+ }
+ }
+
+ private:
+ F m_f;
+ };
+
+ /// \brief template deduction guide
+ ///
+ template <class F>
+ functor_guard(F f) -> functor_guard<F>;
+
} // namespace plib
#endif // PUTIL_H_
diff --git a/src/lib/netlist/solver/nld_matrix_solver.cpp b/src/lib/netlist/solver/nld_matrix_solver.cpp
index b741259c49e..a918aac1c58 100644
--- a/src/lib/netlist/solver/nld_matrix_solver.cpp
+++ b/src/lib/netlist/solver/nld_matrix_solver.cpp
@@ -50,7 +50,8 @@ namespace netlist::solver
matrix_solver_t::matrix_solver_t(devices::nld_solver &main_solver, const pstring &name,
const net_list_t &nets,
const solver::solver_parameters_t *params)
- : device_t(static_cast<device_t &>(main_solver), name)
+ //: device_t(static_cast<device_t &>(main_solver), name)
+ : device_t(device_data_t{main_solver.state(), main_solver.name() + "." + name})
, m_params(*params)
, m_gonn(m_arena)
, m_gtn(m_arena)
@@ -126,9 +127,9 @@ namespace netlist::solver
if (!plib::container::contains(dynamic_devices, &p->device()))
dynamic_devices.push_back(&p->device());
{
- auto *pterm = dynamic_cast<terminal_t *>(p);
- nl_assert(pterm != nullptr);
- add_term(k, pterm);
+ auto pterm = plib::dynamic_downcast<terminal_t *>(p);
+ nl_assert_always(bool(pterm), "cast to terminal_t * failed");
+ add_term(k, *pterm);
}
log().debug("Added terminal {1}\n", p->name());
break;
@@ -145,8 +146,9 @@ namespace netlist::solver
if (net_proxy_output == nullptr)
{
pstring new_name(this->name() + "." + pstring(plib::pfmt("m{1}")(m_inputs.size())));
- nl_assert_always(net.is_analog(), "Net is not an analog net");
- auto net_proxy_output_u = state().make_pool_object<proxied_analog_output_t>(*this, new_name, &dynamic_cast<analog_net_t &>(p->net()));
+ auto proxied_net = plib::dynamic_downcast<analog_net_t *>(p->net());
+ nl_assert_always(proxied_net, "Net is not an analog net");
+ auto net_proxy_output_u = state().make_pool_object<proxied_analog_output_t>(*this, new_name, *proxied_net);
net_proxy_output = net_proxy_output_u.get();
m_inputs.emplace_back(std::move(net_proxy_output_u));
}
@@ -366,6 +368,8 @@ namespace netlist::solver
}
log().verbose("Number of multiplications/additions for {1}: {2}", name(), m_ops);
+ // Dumps non zero elements right of diagonal -> to much output, disabled
+ // NOLINTNEXTLINE(readability-simplify-boolean-expr)
if ((false))
for (std::size_t k = 0; k < iN; k++)
{
diff --git a/src/lib/netlist/solver/nld_matrix_solver.h b/src/lib/netlist/solver/nld_matrix_solver.h
index 6b53fe81ed2..cdee6dbb5ff 100644
--- a/src/lib/netlist/solver/nld_matrix_solver.h
+++ b/src/lib/netlist/solver/nld_matrix_solver.h
@@ -320,8 +320,8 @@ namespace netlist::solver
std::size_t max_rail_start() const noexcept
{
std::size_t max_rail = 0;
- for (std::size_t k = 0; k < m_terms.size(); k++)
- max_rail = std::max(max_rail, m_terms[k].rail_start());
+ for (const auto &term : m_terms)
+ max_rail = std::max(max_rail, term.rail_start());
return max_rail;
}
diff --git a/src/lib/netlist/solver/nld_matrix_solver_ext.h b/src/lib/netlist/solver/nld_matrix_solver_ext.h
index e4cfef0701f..3627c0b8e91 100644
--- a/src/lib/netlist/solver/nld_matrix_solver_ext.h
+++ b/src/lib/netlist/solver/nld_matrix_solver_ext.h
@@ -61,7 +61,7 @@ namespace netlist::solver
// FIXME: Not yet working, mat_cr.h needs some more work
#if 0
- auto mat_GE = dynamic_cast<plib::pGEmatrix_cr_t<typename M::base> *>(&mat);
+ auto mat_GE = plib::dynamic_downcast<plib::pGEmatrix_cr_t<typename M::base> *>(&mat);
#endif
std::vector<unsigned> levL(iN, 0);
std::vector<unsigned> levU(iN, 0);
diff --git a/src/lib/netlist/solver/nld_ms_gcr.h b/src/lib/netlist/solver/nld_ms_gcr.h
index 61bedfa8d06..a2c5d284c43 100644
--- a/src/lib/netlist/solver/nld_ms_gcr.h
+++ b/src/lib/netlist/solver/nld_ms_gcr.h
@@ -327,7 +327,7 @@ namespace netlist::solver
t.imbue(std::locale::classic());
plib::putf8_fmt_writer w(&t);
generate_code(w);
- //std::hash<typename std::remove_const<std::remove_reference<decltype(t.str())>::type>::type> h;
+ //#std::hash<typename std::remove_const<std::remove_reference<decltype(t.str())>::type>::type> h;
return plib::pfmt("nl_gcr_{1}_{2}_{3}_{4:x}")(mat.nz_num)(str_fptype)(str_floattype)(plib::hash<uint64_t>( t.str().c_str(), t.str().size() ));
}
diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp
index 445608a2c27..d7381cc813a 100644
--- a/src/lib/netlist/solver/nld_solver.cpp
+++ b/src/lib/netlist/solver/nld_solver.cpp
@@ -4,9 +4,10 @@
// Names
// spell-checker: words Woodbury,
-#include "nl_factory.h"
-#include "core/setup.h"
+#include "nld_solver.h"
+
#include "nl_errstr.h"
+#include "nl_factory.h"
#include "nl_setup.h" // FIXME: only needed for splitter code
#include "nld_matrix_solver.h"
#include "nld_ms_direct.h"
@@ -18,7 +19,9 @@
#include "nld_ms_sor.h"
#include "nld_ms_sor_mat.h"
#include "nld_ms_w.h"
-#include "nld_solver.h"
+
+#include "core/setup.h"
+
#include "plib/pomp.h"
#include "plib/ptimed_queue.h"
@@ -28,9 +31,27 @@
namespace netlist::devices
{
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
// solver
- // ----------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
+
+ nld_solver::nld_solver(constructor_param_t data)
+ : device_t(data)
+ , m_fb_step(*this, "FB_step", NETLIB_DELEGATE(fb_step<false>))
+ , m_Q_step(*this, "Q_step")
+ , m_params(*this, "", solver::solver_parameter_defaults::get_instance())
+ , m_queue(
+ this->state().pool(), config::max_solver_queue_size(),
+ queue_type::id_delegate(&NETLIB_NAME(solver)::get_solver_id, this),
+ queue_type::obj_delegate(&NETLIB_NAME(solver)::solver_by_id, this))
+ {
+ // internal stuff
+ state().save(*this,
+ static_cast<plib::state_manager_t::callback_t &>(m_queue),
+ this->name(), "m_queue");
+
+ connect("FB_step", "Q_step");
+ }
NETLIB_RESET(solver)
{
@@ -54,16 +75,28 @@ namespace netlist::devices
NETLIB_HANDLER(solver, fb_step)
{
const netlist_time_ext now(exec().time());
- const std::size_t nthreads = m_params.m_parallel() < 2 ? 1 : std::min(static_cast<std::size_t>(m_params.m_parallel()), plib::omp::get_max_threads());
- const netlist_time_ext sched(now + (nthreads <= 1 ? netlist_time_ext::zero() : netlist_time_ext::from_nsec(100)));
- plib::uninitialised_array<solver::matrix_solver_t *, config::max_solver_queue_size::value> tmp; //NOLINT
- plib::uninitialised_array<netlist_time, config::max_solver_queue_size::value> nt; //NOLINT
- std::size_t p=0;
+ const std::size_t nthreads = m_params.m_parallel() < 2
+ ? 1
+ : std::min(
+ static_cast<std::size_t>(
+ m_params.m_parallel()),
+ plib::omp::get_max_threads());
+ const netlist_time_ext sched(
+ now
+ + (nthreads <= 1 ? netlist_time_ext::zero()
+ : netlist_time_ext::from_nsec(100)));
+ plib::uninitialised_array<solver::matrix_solver_t *,
+ config::max_solver_queue_size::value>
+ tmp; // NOLINT
+ plib::uninitialised_array<netlist_time,
+ config::max_solver_queue_size::value>
+ nt; // NOLINT
+ std::size_t p = 0;
while (!m_queue.empty())
{
const auto t = m_queue.top().exec_time();
- auto *o = m_queue.top().object();
+ auto * o = m_queue.top().object();
if (t != now)
if (t > sched)
break;
@@ -71,14 +104,15 @@ namespace netlist::devices
m_queue.pop();
}
- // FIXME: Disabled for now since parallel processing will decrease performance
+ // FIXME: Disabled for now since parallel processing will decrease
+ // performance
// for tested applications. More testing required here
if (true || nthreads < 2)
{
if (!KEEP_STATS)
{
for (std::size_t i = 0; i < p; i++)
- nt[i] = tmp[i]->solve(now, "no-parallel");
+ nt[i] = tmp[i]->solve(now, "no-parallel");
}
else
{
@@ -102,10 +136,9 @@ namespace netlist::devices
else
{
plib::omp::set_num_threads(nthreads);
- plib::omp::for_static(static_cast<std::size_t>(0), p, [&tmp, &nt,now](std::size_t i)
- {
- nt[i] = tmp[i]->solve(now, "parallel");
- });
+ plib::omp::for_static(static_cast<std::size_t>(0), p,
+ [&tmp, &nt, now](std::size_t i)
+ { nt[i] = tmp[i]->solve(now, "parallel"); });
for (std::size_t i = 0; i < p; i++)
{
if (nt[i] != netlist_time::zero())
@@ -114,10 +147,12 @@ namespace netlist::devices
}
}
if (!m_queue.empty())
- m_Q_step.net().toggle_and_push_to_queue(static_cast<netlist_time>(m_queue.top().exec_time() - now));
+ m_Q_step.net().toggle_and_push_to_queue(
+ static_cast<netlist_time>(m_queue.top().exec_time() - now));
}
- void NETLIB_NAME(solver) :: reschedule(solver::matrix_solver_t *solv, netlist_time ts)
+ void NETLIB_NAME(solver)::reschedule(solver::matrix_solver_t *solv,
+ netlist_time ts)
{
const netlist_time_ext now(exec().time());
const netlist_time_ext sched(now + ts);
@@ -141,78 +176,101 @@ namespace netlist::devices
netlist_time_ext now(exec().time());
// force solving during start up if there are no time-step devices
// FIXME: Needs a more elegant solution
- bool force_solve = (now < netlist_time_ext::from_fp<decltype(m_params.m_max_time_step)>(2 * m_params.m_max_time_step));
+ bool force_solve = (now < netlist_time_ext::from_fp<
+ decltype(m_params.m_max_time_step)>(
+ 2 * m_params.m_max_time_step));
- std::size_t nthreads = std::min(static_cast<std::size_t>(m_params.m_parallel()), plib::omp::get_max_threads());
+ std::size_t nthreads = std::min(
+ static_cast<std::size_t>(m_params.m_parallel()),
+ plib::omp::get_max_threads());
- std::vector<solver_entry *> &solvers = (force_solve ? m_mat_solvers_all : m_mat_solvers_time_stepping);
+ std::vector<solver_entry *>
+ &solvers = (force_solve ? m_mat_solvers_all
+ : m_mat_solvers_time_stepping);
if (nthreads > 1 && solvers.size() > 1)
{
plib::omp::set_num_threads(nthreads);
- plib::omp::for_static(static_cast<std::size_t>(0), solvers.size(), [&solvers, now](std::size_t i)
- {
- [[maybe_unused]] const netlist_time ts = solvers[i]->ptr->solve(now);
+ plib::omp::for_static(
+ static_cast<std::size_t>(0), solvers.size(),
+ [&solvers, now](std::size_t i) {
+ [[maybe_unused]] const netlist_time ts = solvers[i]
+ ->ptr->solve(
+ now);
});
}
else
- for (auto & solver : solvers)
+ for (auto &solver : solvers)
{
- [[maybe_unused]] const netlist_time ts = solver->ptr->solve(now);
+ [[maybe_unused]] const netlist_time ts = solver->ptr->solve(
+ now);
}
- for (auto & solver : solvers)
+ for (auto &solver : solvers)
solver->ptr->update_inputs();
// step circuit
if (!m_Q_step.net().is_queued())
{
- m_Q_step.net().toggle_and_push_to_queue(netlist_time::from_fp(m_params.m_max_time_step));
+ m_Q_step.net().toggle_and_push_to_queue(
+ netlist_time::from_fp(m_params.m_max_time_step));
}
}
#endif
// FIXME: should be created in device space
template <class C, class A>
- NETLIB_NAME(solver)::solver_ptr create_it(A &arena, NETLIB_NAME(solver) &main_solver, pstring name,
- NETLIB_NAME(solver)::net_list_t &nets,
- const solver::solver_parameters_t *params, std::size_t size)
+ NETLIB_NAME(solver)::solver_ptr
+ create_it(A &arena, NETLIB_NAME(solver) &main_solver, pstring name,
+ NETLIB_NAME(solver)::net_list_t & nets,
+ const solver::solver_parameters_t *params, std::size_t size)
{
- return plib::make_unique<C>(arena, main_solver, name, nets, params, size);
+ return plib::make_unique<C>(arena, main_solver, name, nets, params,
+ size);
}
template <typename FT, int SIZE>
- NETLIB_NAME(solver)::solver_ptr NETLIB_NAME(solver)::create_solver(std::size_t size,
- const pstring &solver_name, const solver::solver_parameters_t *params,
- NETLIB_NAME(solver)::net_list_t &nets)
+ NETLIB_NAME(solver)::solver_ptr NETLIB_NAME(solver)::create_solver(
+ std::size_t size, const pstring &solver_name,
+ const solver::solver_parameters_t *params,
+ NETLIB_NAME(solver)::net_list_t & nets)
{
switch (params->m_method())
{
case solver::matrix_type_e::MAT_CR:
- return create_it<solver::matrix_solver_GCR_t<FT, SIZE>>(state().pool(), *this, solver_name, nets, params, size);
+ return create_it<solver::matrix_solver_GCR_t<FT, SIZE>>(
+ state().pool(), *this, solver_name, nets, params, size);
case solver::matrix_type_e::MAT:
- return create_it<solver::matrix_solver_direct_t<FT, SIZE>>(state().pool(), *this, solver_name, nets, params, size);
+ return create_it<solver::matrix_solver_direct_t<FT, SIZE>>(
+ state().pool(), *this, solver_name, nets, params, size);
case solver::matrix_type_e::GMRES:
- return create_it<solver::matrix_solver_GMRES_t<FT, SIZE>>(state().pool(), *this, solver_name, nets, params, size);
+ return create_it<solver::matrix_solver_GMRES_t<FT, SIZE>>(
+ state().pool(), *this, solver_name, nets, params, size);
#if (NL_USE_ACADEMIC_SOLVERS)
case solver::matrix_type_e::SOR:
- return create_it<solver::matrix_solver_SOR_t<FT, SIZE>>(state().pool(), *this, solver_name, nets, params, size);
+ return create_it<solver::matrix_solver_SOR_t<FT, SIZE>>(
+ state().pool(), *this, solver_name, nets, params, size);
case solver::matrix_type_e::SOR_MAT:
- return create_it<solver::matrix_solver_SOR_mat_t<FT, SIZE>>(state().pool(), *this, solver_name, nets, params, size);
+ return create_it<solver::matrix_solver_SOR_mat_t<FT, SIZE>>(
+ state().pool(), *this, solver_name, nets, params, size);
case solver::matrix_type_e::SM:
// Sherman-Morrison Formula
- return create_it<solver::matrix_solver_sm_t<FT, SIZE>>(state().pool(), *this, solver_name, nets, params, size);
+ return create_it<solver::matrix_solver_sm_t<FT, SIZE>>(
+ state().pool(), *this, solver_name, nets, params, size);
case solver::matrix_type_e::W:
// Woodbury Formula
- return create_it<solver::matrix_solver_w_t<FT, SIZE>>(state().pool(), *this, solver_name, nets, params, size);
+ return create_it<solver::matrix_solver_w_t<FT, SIZE>>(
+ state().pool(), *this, solver_name, nets, params, size);
#else
- //case solver::matrix_type_e::GMRES:
+ // case solver::matrix_type_e::GMRES:
case solver::matrix_type_e::SOR:
case solver::matrix_type_e::SOR_MAT:
case solver::matrix_type_e::SM:
case solver::matrix_type_e::W:
- state().log().warning(MW_SOLVER_METHOD_NOT_SUPPORTED(params->m_method().name(), "MAT_CR"));
- return create_it<solver::matrix_solver_GCR_t<FT, SIZE>>(state().pool(), *this, solver_name, nets, params, size);
+ state().log().warning(MW_SOLVER_METHOD_NOT_SUPPORTED(
+ params->m_method().name(), "MAT_CR"));
+ return create_it<solver::matrix_solver_GCR_t<FT, SIZE>>(
+ state().pool(), *this, solver_name, nets, params, size);
#endif
}
return solver_ptr();
@@ -228,47 +286,49 @@ namespace netlist::devices
{
#if !defined(__EMSCRIPTEN__)
case 1:
- return plib::make_unique<solver::matrix_solver_direct1_t<FT>>(state().pool(), *this, sname, nets, params);
+ return plib::make_unique<solver::matrix_solver_direct1_t<FT>>(
+ state().pool(), *this, sname, nets, params);
case 2:
- return plib::make_unique<solver::matrix_solver_direct2_t<FT>>(state().pool(), *this, sname, nets, params);
- case 3:
- return create_solver<FT, 3>(3, sname, params, nets);
- case 4:
- return create_solver<FT, 4>(4, sname, params, nets);
- case 5:
- return create_solver<FT, 5>(5, sname, params, nets);
- case 6:
- return create_solver<FT, 6>(6, sname, params, nets);
- case 7:
- return create_solver<FT, 7>(7, sname, params, nets);
- case 8:
- return create_solver<FT, 8>(8, sname, params, nets);
+ return plib::make_unique<solver::matrix_solver_direct2_t<FT>>(
+ state().pool(), *this, sname, nets, params);
+ case 3: return create_solver<FT, 3>(3, sname, params, nets);
+ case 4: return create_solver<FT, 4>(4, sname, params, nets);
+ case 5: return create_solver<FT, 5>(5, sname, params, nets);
+ case 6: return create_solver<FT, 6>(6, sname, params, nets);
+ case 7: return create_solver<FT, 7>(7, sname, params, nets);
+ case 8: return create_solver<FT, 8>(8, sname, params, nets);
#endif
default:
log().info(MI_NO_SPECIFIC_SOLVER(net_count));
if (net_count <= 16)
{
- return create_solver<FT, -16>(net_count, sname, params, nets);
+ return create_solver<FT, -16>(net_count, sname, params,
+ nets);
}
if (net_count <= 32)
{
- return create_solver<FT, -32>(net_count, sname, params, nets);
+ return create_solver<FT, -32>(net_count, sname, params,
+ nets);
}
if (net_count <= 64)
{
- return create_solver<FT, -64>(net_count, sname, params, nets);
+ return create_solver<FT, -64>(net_count, sname, params,
+ nets);
}
if (net_count <= 128)
{
- return create_solver<FT, -128>(net_count, sname, params, nets);
+ return create_solver<FT, -128>(net_count, sname, params,
+ nets);
}
if (net_count <= 256)
{
- return create_solver<FT, -256>(net_count, sname, params, nets);
+ return create_solver<FT, -256>(net_count, sname, params,
+ nets);
}
if (net_count <= 512)
{
- return create_solver<FT, -512>(net_count, sname, params, nets);
+ return create_solver<FT, -512>(net_count, sname, params,
+ nets);
}
return create_solver<FT, 0>(net_count, sname, params, nets);
}
@@ -278,18 +338,21 @@ namespace netlist::devices
{
void run(netlist_state_t &nl_state)
{
- for (auto & net : nl_state.nets())
+ for (auto &net : nl_state.nets())
{
nl_state.log().verbose("processing {1}", net->name());
if (!net->is_rail_net() && !net->core_terms_empty())
{
nl_state.log().verbose(" ==> not a rail net");
// Must be an analog net
- auto &n = dynamic_cast<analog_net_t &>(*net);
- if (!already_processed(n))
+ auto n = plib::dynamic_downcast<analog_net_t *>(net.get());
+ nl_assert_always(bool(n),
+ "Unable to cast to analog_net_t &");
+ if (!already_processed(*(*n)))
{
- groupspre.emplace_back(NETLIB_NAME(solver)::net_list_t());
- process_net(nl_state, n);
+ groupspre.emplace_back(
+ NETLIB_NAME(solver)::net_list_t());
+ process_net(nl_state, *(*n));
}
}
}
@@ -301,14 +364,13 @@ namespace netlist::devices
std::vector<NETLIB_NAME(solver)::net_list_t> groups;
private:
-
bool already_processed(const analog_net_t &n) const
{
// no need to process rail nets - these are known variables
if (n.is_rail_net())
return true;
// if it's already processed - no need to continue
- for (const auto & grp : groups)
+ for (const auto &grp : groups)
if (plib::container::contains(grp, &n))
return true;
return false;
@@ -323,12 +385,13 @@ namespace netlist::devices
// In this case we need to merge this group into the current group
if (groupspre.size() > 1)
{
- for (std::size_t i = 0; i<groupspre.size() - 1; i++)
+ for (std::size_t i = 0; i < groupspre.size() - 1; i++)
if (plib::container::contains(groupspre[i], &n))
{
// copy all nets
- for (auto & cn : groupspre[i])
- if (!plib::container::contains(groupspre.back(), cn))
+ for (auto &cn : groupspre[i])
+ if (!plib::container::contains(groupspre.back(),
+ cn))
groupspre.back().push_back(cn);
// clear
groupspre[i].clear();
@@ -336,7 +399,8 @@ namespace netlist::devices
}
}
// if it's already processed - no need to continue
- if (!groupspre.empty() && plib::container::contains(groupspre.back(), &n))
+ if (!groupspre.empty()
+ && plib::container::contains(groupspre.back(), &n))
return true;
return false;
}
@@ -353,20 +417,26 @@ namespace netlist::devices
// add the net
groupspre.back().push_back(&n);
// process all terminals connected to this net
- for (detail::core_terminal_t * term : terminals)
+ for (detail::core_terminal_t *term : terminals)
{
- nl_state.log().verbose("Term {} {}", term->name(), static_cast<int>(term->type()));
+ nl_state.log().verbose("Term {} {}", term->name(),
+ static_cast<int>(term->type()));
// only process analog terminals
if (term->is_type(detail::terminal_type::TERMINAL))
{
- auto &pt = dynamic_cast<terminal_t &>(*term);
+ auto pt = plib::dynamic_downcast<terminal_t *>(term);
+ nl_assert_always(bool(pt),
+ "Error casting *term to terminal_t &");
// check the connected terminal
- const auto *const connected_terminals = nl_state.setup().get_connected_terminals(pt);
+ const auto *const connected_terminals
+ = nl_state.setup().get_connected_terminals(*(*pt));
// NOLINTNEXTLINE proposal does not work for VS
- for (auto ct = connected_terminals->begin(); *ct != nullptr; ct++)
+ for (auto ct = connected_terminals->begin();
+ *ct != nullptr; ct++)
{
analog_net_t &connected_net = (*ct)->net();
- nl_state.log().verbose(" Connected net {}", connected_net.name());
+ nl_state.log().verbose(" Connected net {}",
+ connected_net.name());
if (!check_if_processed_and_join(connected_net))
process_net(nl_state, connected_net);
}
@@ -386,40 +456,48 @@ namespace netlist::devices
net_splitter splitter;
splitter.run(state());
- log().verbose("Found {1} net groups in {2} nets\n", splitter.groups.size(), state().nets().size());
+ log().verbose("Found {1} net groups in {2} nets\n",
+ splitter.groups.size(), state().nets().size());
int num_errors = 0;
log().verbose("checking net consistency ...");
for (const auto &grp : splitter.groups)
{
- int rail_terminals = 0;
+ int rail_terminals = 0;
pstring nets_in_grp;
for (const auto &n : grp)
{
nets_in_grp += (n->name() + " ");
if (!n->is_analog())
{
- state().log().error(ME_SOLVER_CONSISTENCY_NOT_ANALOG_NET(n->name()));
+ state().log().error(
+ ME_SOLVER_CONSISTENCY_NOT_ANALOG_NET(n->name()));
num_errors++;
}
if (n->is_rail_net())
{
- state().log().error(ME_SOLVER_CONSISTENCY_RAIL_NET(n->name()));
+ state().log().error(
+ ME_SOLVER_CONSISTENCY_RAIL_NET(n->name()));
num_errors++;
}
- for (detail::core_terminal_t * t : n->core_terms_copy())
+ for (detail::core_terminal_t *t : n->core_terms_copy())
{
if (!t->has_net())
{
- state().log().error(ME_SOLVER_TERMINAL_NO_NET(t->name()));
+ state().log().error(
+ ME_SOLVER_TERMINAL_NO_NET(t->name()));
num_errors++;
}
else
{
- auto *other_terminal = dynamic_cast<terminal_t *>(t);
- if (other_terminal != nullptr)
- if (state().setup().get_connected_terminal(*other_terminal)->net().is_rail_net())
+ if (auto other_terminal = plib::dynamic_downcast<
+ terminal_t *>(t))
+ if (state()
+ .setup()
+ .get_connected_terminal(*(*other_terminal))
+ ->net()
+ .is_rail_net())
rail_terminals++;
}
}
@@ -433,43 +511,56 @@ namespace netlist::devices
if (num_errors > 0)
throw nl_exception(MF_SOLVER_CONSISTENCY_ERRORS(num_errors));
-
// setup the solvers
- for (auto & grp : splitter.groups)
+ for (auto &grp : splitter.groups)
{
- solver_ptr ms;
- pstring sname = plib::pfmt("Solver_{1}")(m_mat_solvers.size());
- params_uptr params = plib::make_unique<solver::solver_parameters_t>(state().pool(), *this, sname + ".", m_params);
+ solver_ptr ms;
+ pstring sname = plib::pfmt("Solver_{1}")(m_mat_solvers.size());
+ params_uptr params = plib::make_unique<solver::solver_parameters_t>(
+ state().pool(), *this, sname + ".", m_params);
switch (params->m_fp_type())
{
case solver::matrix_fp_type_e::FLOAT:
if (!config::use_float_matrix::value)
- log().info("FPTYPE {1} not supported. Using DOUBLE", params->m_fp_type().name());
- ms = create_solvers<std::conditional_t<config::use_float_matrix::value, float, double>>(sname, params.get(), grp);
+ log().info("FPTYPE {1} not supported. Using DOUBLE",
+ params->m_fp_type().name());
+ ms = create_solvers<std::conditional_t<
+ config::use_float_matrix::value, float, double>>(
+ sname, params.get(), grp);
break;
case solver::matrix_fp_type_e::DOUBLE:
ms = create_solvers<double>(sname, params.get(), grp);
break;
case solver::matrix_fp_type_e::LONGDOUBLE:
if (!config::use_long_double_matrix::value)
- log().info("FPTYPE {1} not supported. Using DOUBLE", params->m_fp_type().name());
- ms = create_solvers<std::conditional_t<config::use_long_double_matrix::value, long double, double>>(sname, params.get(), grp);
+ log().info("FPTYPE {1} not supported. Using DOUBLE",
+ params->m_fp_type().name());
+ ms = create_solvers<std::conditional_t<
+ config::use_long_double_matrix::value, long double,
+ double>>(sname, params.get(), grp);
break;
case solver::matrix_fp_type_e::FLOATQ128:
#if (NL_USE_FLOAT128)
ms = create_solvers<FLOAT128>(sname, params.get(), grp);
#else
- log().info("FPTYPE {1} not supported. Using DOUBLE", params->m_fp_type().name());
+ log().info("FPTYPE {1} not supported. Using DOUBLE",
+ params->m_fp_type().name());
ms = create_solvers<double>(sname, params.get(), grp);
#endif
break;
}
+ state().register_device(
+ ms->name(),
+ device_arena::owned_ptr<core_device_t>(ms.get(), false));
+
log().verbose("Solver {1}", ms->name());
log().verbose(" ==> {1} nets", grp.size());
- log().verbose(" has {1} dynamic elements", ms->dynamic_device_count());
- log().verbose(" has {1} time step elements", ms->time_step_device_count());
+ log().verbose(" has {1} dynamic elements",
+ ms->dynamic_device_count());
+ log().verbose(" has {1} time step elements",
+ ms->time_step_device_count());
for (auto &n : grp)
{
log().verbose("Net {1}", n->name());
@@ -482,35 +573,37 @@ namespace netlist::devices
m_mat_params.push_back(std::move(params));
m_mat_solvers.push_back(std::move(ms));
}
-
}
- solver::static_compile_container NETLIB_NAME(solver)::create_solver_code(solver::static_compile_target target)
+ solver::static_compile_container NETLIB_NAME(solver)::create_solver_code(
+ solver::static_compile_target target)
{
solver::static_compile_container mp;
- for (auto & s : m_mat_solvers)
+ for (auto &s : m_mat_solvers)
{
auto r = s->create_solver_code(target);
- if (!r.first.empty()) // ignore solvers not supporting static compile
+ if (!r.first.empty()) // ignore solvers not supporting static
+ // compile
mp.push_back(r);
}
return mp;
}
- std::size_t NETLIB_NAME(solver)::get_solver_id(const solver::matrix_solver_t *net) const
+ std::size_t NETLIB_NAME(solver)::get_solver_id(
+ const solver::matrix_solver_t *net) const
{
- for (std::size_t i=0; i < m_mat_solvers.size(); i++)
+ for (std::size_t i = 0; i < m_mat_solvers.size(); i++)
if (m_mat_solvers[i].get() == net)
return i;
return std::numeric_limits<std::size_t>::max();
}
- solver::matrix_solver_t * NETLIB_NAME(solver)::solver_by_id(std::size_t id) const
+ solver::matrix_solver_t *NETLIB_NAME(solver)::solver_by_id(
+ std::size_t id) const
{
return m_mat_solvers[id].get();
}
-
NETLIB_DEVICE_IMPL(solver, "SOLVER", "FREQ")
} // namespace netlist::devices
diff --git a/src/lib/netlist/solver/nld_solver.h b/src/lib/netlist/solver/nld_solver.h
index 898dac7403f..c4f6c2e5bf1 100644
--- a/src/lib/netlist/solver/nld_solver.h
+++ b/src/lib/netlist/solver/nld_solver.h
@@ -8,49 +8,43 @@
/// \file nld_solver.h
///
-#include "../plib/pstream.h"
+#include "nld_matrix_solver.h"
#include "core/core_device.h"
#include "core/logic.h"
#include "core/state_var.h"
-#include "nld_matrix_solver.h"
+
+#include "../plib/pstream.h"
#include <map>
#include <memory>
#include <vector>
-// ----------------------------------------------------------------------------------------
-// solver
-// ----------------------------------------------------------------------------------------
-
namespace netlist::devices
{
- NETLIB_OBJECT(solver)
+ // -------------------------------------------------------------------------
+ // solver
+ // -------------------------------------------------------------------------
+
+ class nld_solver : public device_t
{
public:
using solver_arena = device_arena;
- using queue_type = detail::queue_base<solver_arena, solver::matrix_solver_t>;
-
- NETLIB_CONSTRUCTOR(solver)
- , m_fb_step(*this, "FB_step", NETLIB_DELEGATE(fb_step<false>))
- , m_Q_step(*this, "Q_step")
- , m_params(*this, "", solver::solver_parameter_defaults::get_instance())
- , m_queue(this->state().pool(), config::max_solver_queue_size(),
- queue_type::id_delegate(&NETLIB_NAME(solver) :: get_solver_id, this),
- queue_type::obj_delegate(&NETLIB_NAME(solver) :: solver_by_id, this))
- {
- // internal stuff
- state().save(*this, static_cast<plib::state_manager_t::callback_t &>(m_queue), this->name(), "m_queue");
+ using queue_type = detail::queue_base<solver_arena,
+ solver::matrix_solver_t>;
- connect("FB_step", "Q_step");
- }
+ nld_solver(constructor_param_t data);
void post_start();
void stop();
- auto gmin() const -> decltype(solver::solver_parameters_t::m_gmin()) { return m_params.m_gmin(); }
+ auto gmin() const -> decltype(solver::solver_parameters_t::m_gmin())
+ {
+ return m_params.m_gmin();
+ }
- solver::static_compile_container create_solver_code(solver::static_compile_target target);
+ solver::static_compile_container
+ create_solver_code(solver::static_compile_target target);
NETLIB_RESETI();
// NETLIB_UPDATE_PARAMI();
@@ -62,32 +56,34 @@ namespace netlist::devices
void reschedule(solver::matrix_solver_t *solv, netlist_time ts);
private:
- using params_uptr = solver_arena::unique_ptr<solver::solver_parameters_t>;
+ using params_uptr = solver_arena::unique_ptr<
+ solver::solver_parameters_t>;
- template<bool KEEP_STATS>
+ template <bool KEEP_STATS>
NETLIB_HANDLERI(fb_step);
- logic_input_t m_fb_step;
+ logic_input_t m_fb_step;
logic_output_t m_Q_step;
// FIXME: these should be created in device space
std::vector<params_uptr> m_mat_params;
- std::vector<solver_ptr> m_mat_solvers;
+ std::vector<solver_ptr> m_mat_solvers;
solver::solver_parameters_t m_params;
- queue_type m_queue;
+ queue_type m_queue;
template <typename FT, int SIZE>
solver_ptr create_solver(std::size_t size, const pstring &solver_name,
- const solver::solver_parameters_t *params,net_list_t &nets);
+ const solver::solver_parameters_t *params,
+ net_list_t & nets);
template <typename FT>
- solver_ptr create_solvers(const pstring &sname,
- const solver::solver_parameters_t *params, net_list_t &nets);
+ solver_ptr create_solvers(const pstring & sname,
+ const solver::solver_parameters_t *params,
+ net_list_t & nets);
std::size_t get_solver_id(const solver::matrix_solver_t *net) const;
solver::matrix_solver_t *solver_by_id(std::size_t id) const;
-
};
} // namespace netlist::devices
diff --git a/src/lib/netlist/tests/test_penum.cpp b/src/lib/netlist/tests/test_penum.cpp
index 0fafafa97b4..8e90c8537e1 100644
--- a/src/lib/netlist/tests/test_penum.cpp
+++ b/src/lib/netlist/tests/test_penum.cpp
@@ -14,6 +14,7 @@
#include <string>
#include <type_traits>
+#include <string_view>
#if 0
namespace plib
@@ -166,6 +167,58 @@ operator == (const E &lhs, const char * rhs)
}
#endif
+// ---------------------------------------
+
+template <typename T>
+struct ret_t
+{
+ bool success;
+ T value;
+};
+
+template <typename T, T BASE>
+constexpr ret_t<T> stl_h(std::string_view sv)
+{
+ T r(0);
+ for (const auto &c : sv)
+ {
+ if (c >= '0' && c < '0' + std::min(10,BASE))
+ {
+ r = r * BASE + (c - '0');
+ }
+ else if (c >= 'A' && c < ('A' + BASE - 10))
+ {
+ r = r * BASE + (10 + c - 'A');
+ }
+ else if (c >= 'a' && c < ('a' + BASE - 10))
+ {
+ r = r * BASE + (10 + c - 'a');
+ }
+ else
+ return { false, T(0) };
+ }
+ return { true, r };
+}
+
+template <typename T, T BASE = 0>
+constexpr ret_t<T> stl(std::string_view sv)
+{
+ if constexpr (BASE == 0)
+ {
+ if (sv.size() > 2)
+ {
+ if (sv.substr(0,2) == "0x" || sv.substr(0,2) == "0X")
+ return stl_h<T,16>(sv.substr(2));
+ if (sv.substr(0,2) == "0b")
+ return stl_h<T,2>(sv.substr(2));
+ }
+ if (sv.size() > 1 && sv.substr(0,1) == "0" )
+ return stl_h<T,8>(sv.substr(1));
+ return stl_h<T, 10>(sv);
+ }
+ return stl_h<T, BASE>(sv);
+}
+
#include "plib/ptests.h"
//PENUM_NS(plibx, teste, A, B, C)
@@ -179,6 +232,12 @@ PENUM(testf, A, B, C)
PTEST(penum, conversion)
{
+ static_assert(stl<int,0>("0xa0bc").success,"no");
+ static_assert(stl<int,0>("0xa0bc").value==0xa0bc,"no");
+ static_assert(stl<int,0>("0b1010").value==0b1010,"no");
+ static_assert(stl<int,0>("0123").value==0123,"no");
+ //const auto x(stl<int,0>("123"));
+ //static_assert(x.value==123,"no");
plibx::teste x = plib::functor<plibx::teste>("A");
PEXPECT_NE(x, plibx::teste::B);
diff --git a/src/lib/netlist/tests/test_precommit.cpp b/src/lib/netlist/tests/test_precommit.cpp
index 55f9b596a8c..15575fbbe7f 100644
--- a/src/lib/netlist/tests/test_precommit.cpp
+++ b/src/lib/netlist/tests/test_precommit.cpp
@@ -7,10 +7,10 @@
/// tests for `plib::pmfp`
///
-#include "plib/pconfig.h"
-#include "plib/ppmf.h"
#include "netlist/nl_config.h"
+#include "plib/pconfig.h"
+#include "plib/ppmf.h"
#include "plib/ptests.h"
PTEST(test_precommit, precommit)