summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib
diff options
context:
space:
mode:
author couriersud <couriersud@users.noreply.github.com>2022-07-16 22:48:22 +0200
committer GitHub <noreply@github.com>2022-07-16 22:48:22 +0200
commit4ecc148240db77f49b600933e58e370ec757202f (patch)
tree10cac8edb72cb4dab76b06e060e338c7c95e208b /src/lib
parent20d6ea06f4a19463bbe9b36e3619b012448d76ed (diff)
netlist: include file work (#10096)
- move code to more appropriate locations - apply clang-format to modified files - fixed some cspell errors - Applied emu.h rule.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/netlist/analog/nld_bjt.cpp2
-rw-r--r--src/lib/netlist/analog/nld_mosfet.cpp296
-rw-r--r--src/lib/netlist/analog/nlid_twoterm.cpp2
-rw-r--r--src/lib/netlist/analog/nlid_twoterm.h6
-rw-r--r--src/lib/netlist/build/.clang-format8
-rw-r--r--src/lib/netlist/build/cspell.json4
-rw-r--r--src/lib/netlist/build/makefile2
-rw-r--r--src/lib/netlist/core/base_objects.h36
-rw-r--r--src/lib/netlist/core/core_device.h4
-rw-r--r--src/lib/netlist/core/device.h28
-rw-r--r--src/lib/netlist/core/device_macros.h4
-rw-r--r--src/lib/netlist/core/logic_family.h2
-rw-r--r--src/lib/netlist/core/netlist_state.h58
-rw-r--r--src/lib/netlist/core/object_array.h4
-rw-r--r--src/lib/netlist/core/state_var.h1
-rw-r--r--src/lib/netlist/devices/nld_4013.cpp10
-rw-r--r--src/lib/netlist/nl_base.h1
-rw-r--r--src/lib/netlist/nl_config.h34
-rw-r--r--src/lib/netlist/nl_errstr.h58
-rw-r--r--src/lib/netlist/nl_setup.h176
-rw-r--r--src/lib/netlist/nltypes.h70
-rw-r--r--src/lib/netlist/plib/pmath.h95
-rw-r--r--src/lib/netlist/solver/nld_matrix_solver.cpp417
-rw-r--r--src/lib/netlist/solver/nld_matrix_solver.h258
-rw-r--r--src/lib/netlist/tests/test_precommit.cpp6
25 files changed, 882 insertions, 700 deletions
diff --git a/src/lib/netlist/analog/nld_bjt.cpp b/src/lib/netlist/analog/nld_bjt.cpp
index cae3c9649b0..2152f8f431a 100644
--- a/src/lib/netlist/analog/nld_bjt.cpp
+++ b/src/lib/netlist/analog/nld_bjt.cpp
@@ -353,8 +353,6 @@ namespace netlist::analog
nld_two_terminal m_P0_P1; // 0, -gec, -gcc, 0 | 0
};
-#define USE_THREE (1)
-
// -----------------------------------------------------------------------------
// nld_QBJT_EB
// -----------------------------------------------------------------------------
diff --git a/src/lib/netlist/analog/nld_mosfet.cpp b/src/lib/netlist/analog/nld_mosfet.cpp
index 8cbd368759f..63911ceb02f 100644
--- a/src/lib/netlist/analog/nld_mosfet.cpp
+++ b/src/lib/netlist/analog/nld_mosfet.cpp
@@ -21,14 +21,16 @@
/// http://jaco.ec.t.kanazawa-u.ac.jp/edu/mix/pdf/3.pdf
///
/// Farid N. Naim, Circuit Simulation (Wiley-IEEE Press, 2010).
-/// Stefan Jahn, Michael Margraf, Vincent Habchi and Raimund Jacob, "Qucs Technical Papers" (2007)
+/// Stefan Jahn, Michael Margraf, Vincent Habchi and Raimund Jacob, "Qucs
+/// Technical Papers" (2007)
///
-#include "solver/nld_solver.h"
#include "../nl_setup.h"
#include "nlid_twoterm.h"
-#define BODY_CONNECTED_TO_SOURCE (1)
+#include "solver/nld_solver.h"
+
+#define BODY_CONNECTED_TO_SOURCE (1)
namespace netlist::analog
{
@@ -99,11 +101,11 @@ namespace netlist::analog
{
public:
fet_model_t(param_model_t &model)
- : m_VTO(model, "VTO")
- , m_N(model, "N")
- , m_ISS(model, "IS") // Haven't seen a model using ISS / ISD
- , m_ISD(model, "IS")
- , m_LD(model, "LD")
+ : m_VTO(model, "VTO")
+ , m_N(model, "N")
+ , m_ISS(model, "IS") // Haven't seen a model using ISS / ISD
+ , m_ISD(model, "IS")
+ , m_LD(model, "LD")
, m_L(model, "L")
, m_W(model, "W")
, m_TOX(model, "TOX")
@@ -119,28 +121,33 @@ namespace netlist::analog
, m_CGDO(model, "CGDO")
, m_CGBO(model, "CGBO")
, m_CAPMOD(model, "CAPMOD")
- {}
-
- param_model_t::value_t m_VTO; //!< Threshold voltage [V]
- param_model_t::value_t m_N; //!< Bulk diode emission coefficient
- param_model_t::value_t m_ISS; //!< Body diode saturation current
- param_model_t::value_t m_ISD; //!< Body diode saturation current
- param_model_t::value_t m_LD; //!< Lateral diffusion [m]
- param_model_t::value_t m_L; //!< Length scaling
- param_model_t::value_t m_W; //!< Width scaling
- param_model_t::value_t m_TOX; //!< Oxide thickness
- param_model_t::value_t m_KP; //!< Transconductance parameter [A/V²]
- param_model_t::value_t m_UO; //!< Surface mobility [cm²/V/s]
- param_model_t::value_t m_PHI; //!< Surface inversion potential [V]
- param_model_t::value_t m_NSUB; //!< Substrate doping [1/cm³]
- param_model_t::value_t m_GAMMA; //!< Bulk threshold parameter [V^½]
- param_model_t::value_t m_LAMBDA; //!< Channel-length modulation [1/V]
- param_model_t::value_t m_RD; //!< Drain ohmic resistance
- param_model_t::value_t m_RS; //!< Source ohmic resistance
- param_model_t::value_t m_CGSO; //!< Gate-source overlap capacitance per meter channel width
- param_model_t::value_t m_CGDO; //!< Gate-drain overlap capacitance per meter channel width
- param_model_t::value_t m_CGBO; //!< Gate-bulk overlap capacitance per meter channel width
- param_model_t::value_base_t<int> m_CAPMOD; //!< Capacitance model (0=no model 2=Meyer)
+ {
+ }
+
+ param_model_t::value_t m_VTO; //!< Threshold voltage [V]
+ param_model_t::value_t m_N; //!< Bulk diode emission coefficient
+ param_model_t::value_t m_ISS; //!< Body diode saturation current
+ param_model_t::value_t m_ISD; //!< Body diode saturation current
+ param_model_t::value_t m_LD; //!< Lateral diffusion [m]
+ param_model_t::value_t m_L; //!< Length scaling
+ param_model_t::value_t m_W; //!< Width scaling
+ param_model_t::value_t m_TOX; //!< Oxide thickness
+ param_model_t::value_t m_KP; //!< Transconductance parameter [A/V²]
+ param_model_t::value_t m_UO; //!< Surface mobility [cm²/V/s]
+ param_model_t::value_t m_PHI; //!< Surface inversion potential [V]
+ param_model_t::value_t m_NSUB; //!< Substrate doping [1/cm³]
+ param_model_t::value_t m_GAMMA; //!< Bulk threshold parameter [V^½]
+ param_model_t::value_t m_LAMBDA; //!< Channel-length modulation [1/V]
+ param_model_t::value_t m_RD; //!< Drain ohmic resistance
+ param_model_t::value_t m_RS; //!< Source ohmic resistance
+ param_model_t::value_t m_CGSO; //!< Gate-source overlap capacitance per
+ //!< meter channel width
+ param_model_t::value_t m_CGDO; //!< Gate-drain overlap capacitance per
+ //!< meter channel width
+ param_model_t::value_t m_CGBO; //!< Gate-bulk overlap capacitance per
+ //!< meter channel width
+ param_model_t::value_base_t<int> m_CAPMOD; //!< Capacitance model (0=no
+ //!< model 2=Meyer)
};
// -----------------------------------------------------------------------------
@@ -150,7 +157,6 @@ namespace netlist::analog
class nld_MOSFET : public base_device_t
{
public:
- public: \
nld_MOSFET(constructor_param_t data)
: base_device_t(data)
, m_model(*this, "MODEL", "NMOS")
@@ -171,7 +177,7 @@ namespace netlist::analog
, m_lambda(nlconst::zero())
, m_Leff(nlconst::zero())
, m_CoxWL(nlconst::zero())
- //S, 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())
@@ -179,28 +185,30 @@ namespace netlist::analog
, m_Vgs(*this, "m_Vgs", nlconst::zero())
, m_Vgd(*this, "m_Vgd", nlconst::zero())
, m_model_acc(m_model)
- {
- register_sub_alias("S", m_SG.P()); // Source
- register_sub_alias("G", m_SG.N()); // Gate
+ {
+ register_sub_alias("S", m_SG.P()); // Source
+ register_sub_alias("G", m_SG.N()); // Gate
- register_sub_alias("D", m_DG.P()); // Drain
+ register_sub_alias("D", m_DG.P()); // Drain
connect(m_SG.P(), m_SD.P());
connect(m_SG.N(), m_DG.N());
connect(m_DG.P(), m_SD.N());
- m_polarity = (m_model.type() == "NMOS_DEFAULT" ? 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);
- nl_assert_always(m_capacitor_model == 0 || m_capacitor_model == 2, "Error: CAPMODEL invalid value");
+ nl_assert_always(m_capacitor_model == 0 || m_capacitor_model == 2,
+ "Error: CAPMODEL invalid value");
//
// From http://ltwiki.org/LTspiceHelp/LTspiceHelp/M_MOSFET.htm :
//
- // VTO, KP, LAMBDA, PHI and GAMMA. These parameters are computed
- // if the process parameters(NSUB, TOX,...) are given, but
- // user-specified values always override.
+ // VTO, KP, LAMBDA, PHI and GAMMA. These parameters are
+ // computed if the process parameters(NSUB, TOX,...) are given,
+ // but user-specified values always override.
//
// But couldn't find a formula for lambda anywhere
//
@@ -209,20 +217,28 @@ namespace netlist::analog
// calculate effective channel length
m_Leff = m_model_acc.m_L - 2 * m_model_acc.m_LD;
- nl_assert_always(m_Leff > nlconst::zero(), "Effective Lateral diffusion would be negative for model");
+ nl_assert_always(
+ m_Leff > nlconst::zero(),
+ "Effective Lateral diffusion would be negative for model");
- nl_fptype Cox = (m_model_acc.m_TOX > nlconst::zero()) ? (constants::eps_SiO2() * constants::eps_0() / m_model_acc.m_TOX) : nlconst::zero();
+ nl_fptype Cox = (m_model_acc.m_TOX > nlconst::zero())
+ ? (constants::eps_SiO2() * constants::eps_0()
+ / m_model_acc.m_TOX)
+ : nlconst::zero();
// calculate DC transconductance coefficient
if (m_model_acc.m_KP > nlconst::zero())
m_beta = m_model_acc.m_KP * m_model_acc.m_W / m_Leff;
- else if (Cox > nlconst::zero() && m_model_acc.m_UO > nlconst::zero())
- m_beta = m_model_acc.m_UO * nlconst::magic(1e-4) * Cox * m_model_acc.m_W / m_Leff;
+ else if (Cox > nlconst::zero()
+ && m_model_acc.m_UO > nlconst::zero())
+ m_beta = m_model_acc.m_UO * nlconst::magic(1e-4) * Cox
+ * m_model_acc.m_W / m_Leff;
else
m_beta = nlconst::magic(2e-5) * m_model_acc.m_W / m_Leff;
- //FIXME::UT can disappear
- const nl_fptype Vt = constants::T0() * constants::k_b() / constants::Q_e();
+ // FIXME::UT can disappear
+ const nl_fptype Vt = constants::T0() * constants::k_b()
+ / constants::Q_e();
// calculate surface potential if not given
@@ -230,8 +246,12 @@ namespace netlist::analog
m_phi = m_model_acc.m_PHI;
else if (m_model_acc.m_NSUB > nlconst::zero())
{
- nl_assert_always(m_model_acc.m_NSUB * nlconst::magic(1e6) >= constants::NiSi(), "Error calculating phi for model");
- m_phi = nlconst::two() * Vt * plib::log (m_model_acc.m_NSUB * nlconst::magic(1e6) / constants::NiSi());
+ nl_assert_always(m_model_acc.m_NSUB * nlconst::magic(1e6)
+ >= constants::NiSi(),
+ "Error calculating phi for model");
+ m_phi = nlconst::two() * Vt
+ * plib::log(m_model_acc.m_NSUB * nlconst::magic(1e6)
+ / constants::NiSi());
}
else
m_phi = nlconst::magic(0.6);
@@ -241,21 +261,24 @@ namespace netlist::analog
m_gamma = m_model_acc.m_GAMMA;
else
{
- if (Cox > nlconst::zero() && m_model_acc.m_NSUB > nlconst::zero())
- m_gamma = plib::sqrt (nlconst::two()
- * constants::Q_e() * constants::eps_Si() * constants::eps_0()
- * m_model_acc.m_NSUB * nlconst::magic(1e6)) / Cox;
+ if (Cox > nlconst::zero()
+ && m_model_acc.m_NSUB > nlconst::zero())
+ m_gamma = plib::sqrt(
+ nlconst::two() * constants::Q_e()
+ * constants::eps_Si() * constants::eps_0()
+ * m_model_acc.m_NSUB * nlconst::magic(1e6))
+ / Cox;
else
m_gamma = nlconst::zero();
}
m_vto = m_model_acc.m_VTO;
// FIXME zero conversion
- if(m_vto == nlconst::zero())
+ if (m_vto == nlconst::zero())
log().warning(MW_MOSFET_THRESHOLD_VOLTAGE(m_model.name()));
- // FIXME: VTO if missing may be calculated from TPG, NSS and temperature. Usually models
- // specify VTO so skip this here.
+ // FIXME: VTO if missing may be calculated from TPG, NSS and
+ // temperature. Usually models specify VTO so skip this here.
m_CoxWL = Cox * m_model_acc.m_W * m_Leff;
@@ -269,13 +292,14 @@ namespace netlist::analog
{
if (m_capacitor_model != 0)
{
- if (ts_type == time_step_type::FORWARD)
+ if (ts_type == detail::time_step_type::FORWARD)
{
//#const nl_nl_fptype Ugd = -m_DG.deltaV() * m_polarity; // Gate - Drain
//#const nl_nl_fptype Ugs = -m_SG.deltaV() * m_polarity; // Gate - Source
- const nl_fptype Ugd = m_Vgd; // Gate - Drain
- const nl_fptype Ugs = m_Vgs; // Gate - Source
- const nl_fptype Ubs = nlconst::zero(); // Bulk - Source == 0 if connected
+ const nl_fptype Ugd = m_Vgd; // Gate - Drain
+ const nl_fptype Ugs = m_Vgs; // Gate - Source
+ const nl_fptype Ubs = nlconst::zero(); // Bulk - Source == 0
+ // if connected
const nl_fptype Ugb = Ugs - Ubs;
m_cap_gb.time_step(m_Cgb, Ugb, step);
@@ -292,20 +316,22 @@ namespace netlist::analog
}
protected:
-
NETLIB_RESETI()
{
// Bulk diodes
- m_D_BD.set_param(m_model_acc.m_ISD, m_model_acc.m_N, exec().gmin(), constants::T0());
- #if (!BODY_CONNECTED_TO_SOURCE)
- m_D_BS.set_param(m_model_acc.m_ISS, m_model_acc.m_N, exec().gmin(), constants::T0());
- #endif
+ m_D_BD.set_param(m_model_acc.m_ISD, m_model_acc.m_N, exec().gmin(),
+ constants::T0());
+#if (!BODY_CONNECTED_TO_SOURCE)
+ m_D_BS.set_param(m_model_acc.m_ISS, m_model_acc.m_N, exec().gmin(),
+ constants::T0());
+#endif
}
NETLIB_HANDLERI(terminal_handler)
{
- // only called if connected to a rail net ==> notify the solver to recalculate
+ // only called if connected to a rail net ==> notify the solver to
+ // recalculate
auto *solv(m_SG.solver());
if (solv != nullptr)
solv->solve_now();
@@ -316,7 +342,6 @@ namespace netlist::analog
NETLIB_UPDATE_TERMINALSI();
private:
-
param_model_t m_model;
NETLIB_NAME(two_terminal) m_DG;
@@ -349,25 +374,30 @@ namespace netlist::analog
nl_fptype m_Cgs;
nl_fptype m_Cgd;
- int m_capacitor_model;
+ int m_capacitor_model;
state_var<nl_fptype> m_Vgs;
state_var<nl_fptype> m_Vgd;
- fet_model_t m_model_acc;
+ fet_model_t m_model_acc;
void set_cap(generic_capacitor<capacitor_e::VARIABLE_CAPACITY> &cap,
- nl_fptype capval, nl_fptype V,
- nl_fptype &g11, nl_fptype &g12, nl_fptype &g21, nl_fptype &g22,
- nl_fptype &I1, nl_fptype &I2) const
+ nl_fptype capval, nl_fptype V, nl_fptype &g11,
+ nl_fptype &g12, nl_fptype &g21, nl_fptype &g22,
+ nl_fptype &I1, nl_fptype &I2) const
{
const nl_fptype I = cap.Ieq(capval, V) * m_polarity;
const nl_fptype G = cap.G(capval);
- g11 += G; g12 -= G; g21 -= G; g22 += G;
- I1 -= I; I2 += I;
- //printf("Cap: %g\n", capval);
+ g11 += G;
+ g12 -= G;
+ g21 -= G;
+ g22 += G;
+ I1 -= I;
+ I2 += I;
+ // printf("Cap: %g\n", capval);
}
- void calculate_caps(nl_fptype Vgs, nl_fptype Vgd, nl_fptype Vth,
- nl_fptype &Cgs, nl_fptype &Cgd, nl_fptype &Cgb) const
+ void
+ calculate_caps(nl_fptype Vgs, nl_fptype Vgd, nl_fptype Vth,
+ nl_fptype &Cgs, nl_fptype &Cgd, nl_fptype &Cgb) const
{
nl_fptype Vctrl = Vgs - Vth * m_polarity;
// Cut off - now further differentiated into 3 different formulas
@@ -388,7 +418,8 @@ namespace netlist::analog
else if (Vctrl <= 0)
{
Cgb = -Vctrl * m_CoxWL / m_phi;
- Cgs = Vctrl * m_CoxWL * nlconst::fraction(4.0, 3.0) / m_phi + nlconst::two_thirds() * m_CoxWL;
+ Cgs = Vctrl * m_CoxWL * nlconst::fraction(4.0, 3.0) / m_phi
+ + nlconst::two_thirds() * m_CoxWL;
Cgd = nlconst::zero();
}
else
@@ -405,11 +436,15 @@ namespace netlist::analog
else
{
// linear
- const auto Sqr1(plib::narrow_cast<nl_fptype>(plib::pow(Vdsat - Vds, 2)));
- const auto Sqr2(plib::narrow_cast<nl_fptype>(plib::pow(nlconst::two() * Vdsat - Vds, 2)));
+ const auto Sqr1(plib::narrow_cast<nl_fptype>(
+ plib::pow(Vdsat - Vds, 2)));
+ const auto Sqr2(plib::narrow_cast<nl_fptype>(
+ plib::pow(nlconst::two() * Vdsat - Vds, 2)));
Cgb = 0;
- Cgs = m_CoxWL * (nlconst::one() - Sqr1 / Sqr2) * nlconst::two_thirds();
- Cgd = m_CoxWL * (nlconst::one() - Vdsat * Vdsat / Sqr2) * nlconst::two_thirds();
+ Cgs = m_CoxWL * (nlconst::one() - Sqr1 / Sqr2)
+ * nlconst::two_thirds();
+ Cgd = m_CoxWL * (nlconst::one() - Vdsat * Vdsat / Sqr2)
+ * nlconst::two_thirds();
}
}
}
@@ -426,19 +461,26 @@ namespace netlist::analog
// limit step sizes
- const nl_fptype k = nlconst::magic(3.5); // see "Circuit Simulation", page 185
+ const nl_fptype k = nlconst::magic(3.5); // see "Circuit Simulation",
+ // page 185
nl_fptype d = (Vgs - m_Vgs);
- Vgs = m_Vgs + plib::reciprocal(k) * plib::signum(d) * plib::log1p(k * plib::abs(d));
+ Vgs = m_Vgs
+ + plib::reciprocal(k) * plib::signum(d)
+ * plib::log1p(k * plib::abs(d));
d = (Vgd - m_Vgd);
- Vgd = m_Vgd + plib::reciprocal(k) * plib::signum(d) * plib::log1p(k * plib::abs(d));
+ Vgd = m_Vgd
+ + plib::reciprocal(k) * plib::signum(d)
+ * plib::log1p(k * plib::abs(d));
m_Vgs = Vgs;
m_Vgd = Vgd;
- const nl_fptype Vbs = nlconst::zero(); // Bulk - Source == 0 if connected
- //const nl_nl_fptype Vbd = m_SD.deltaV() * m_polarity; // Bulk - Drain = Source - Drain
+ const nl_fptype Vbs = nlconst::zero(); // Bulk - Source == 0 if
+ // connected
+ // const nl_nl_fptype Vbd = m_SD.deltaV() * m_polarity; // Bulk - Drain
+ // = Source - Drain
const nl_fptype Vds = Vgs - Vgd;
- const nl_fptype Vbd = -Vds; // Bulk - Drain = Source - Drain
+ const nl_fptype Vbd = -Vds; // Bulk - Drain = Source - Drain
#if (!BODY_CONNECTED_TO_SOURCE)
m_D_BS.update_diode(Vbs);
@@ -451,8 +493,11 @@ namespace netlist::analog
// calculate Vth
const nl_fptype Vbulk = is_forward ? Vbs : Vbd;
- const nl_fptype phi_m_Vbulk = (m_phi > Vbulk) ? plib::sqrt(m_phi - Vbulk) : nlconst::zero();
- const nl_fptype Vth = m_vto * m_polarity + m_gamma * (phi_m_Vbulk - plib::sqrt(m_phi));
+ const nl_fptype phi_m_Vbulk = (m_phi > Vbulk)
+ ? plib::sqrt(m_phi - Vbulk)
+ : nlconst::zero();
+ const nl_fptype Vth = m_vto * m_polarity
+ + m_gamma * (phi_m_Vbulk - plib::sqrt(m_phi));
const nl_fptype Vctrl = (is_forward ? Vgs : Vgd) - Vth;
@@ -467,30 +512,36 @@ namespace netlist::analog
{
// cutoff region
Ids = nlconst::zero();
- gm = nlconst::zero();
+ gm = nlconst::zero();
gds = nlconst::zero();
gmb = nlconst::zero();
}
else
{
- const nl_fptype beta = m_beta * (nlconst::one() + m_lambda * absVds);
+ const nl_fptype beta = m_beta
+ * (nlconst::one() + m_lambda * absVds);
if (Vctrl <= absVds)
{
// saturation region
Ids = beta * Vctrl * Vctrl / nlconst::two();
- gm = beta * Vctrl;
+ gm = beta * Vctrl;
gds = m_lambda * m_beta * Vctrl * Vctrl / nlconst::two();
}
else
{
// linear region
Ids = beta * absVds * (Vctrl - absVds / nlconst::two());
- gm = beta * absVds;
- gds = beta * (Vctrl - absVds) + m_lambda * m_beta * absVds * (Vctrl - absVds / nlconst::two());
+ gm = beta * absVds;
+ gds = beta * (Vctrl - absVds)
+ + m_lambda * m_beta * absVds
+ * (Vctrl - absVds / nlconst::two());
}
// back gate transconductance
- const nl_fptype bgtc = (phi_m_Vbulk != nlconst::zero()) ? (m_gamma / phi_m_Vbulk / nlconst::two()) : nlconst::zero();
+ const nl_fptype bgtc = (phi_m_Vbulk != nlconst::zero())
+ ? (m_gamma / phi_m_Vbulk
+ / nlconst::two())
+ : nlconst::zero();
gmb = gm * bgtc;
}
@@ -512,11 +563,11 @@ namespace netlist::analog
#endif
// exchange controlling nodes if necessary
const nl_fptype gate_source = is_forward ? (gm + gmb) : nlconst::zero();
- const nl_fptype gate_drain = is_forward ? nlconst::zero() : (gm + gmb);
+ const nl_fptype gate_drain = is_forward ? nlconst::zero() : (gm + gmb);
- const nl_fptype IeqDS = (is_forward) ?
- Ids - gm * Vgs - gmb * Vbs - gds * Vds
- : -Ids - gm * Vgd - gmb * Vbd - gds * Vds;
+ const nl_fptype IeqDS = (is_forward)
+ ? Ids - gm * Vgs - gmb * Vbs - gds * Vds
+ : -Ids - gm * Vgd - gmb * Vbd - gds * Vds;
// IG = 0
nl_fptype IG = nlconst::zero();
@@ -529,20 +580,20 @@ namespace netlist::analog
nl_fptype gGS = nlconst::zero();
nl_fptype gGB = nlconst::zero();
- nl_fptype gDG = gm;
- nl_fptype gDD = gds + gbd - gate_drain;
+ nl_fptype gDG = gm;
+ nl_fptype gDD = gds + gbd - gate_drain;
const nl_fptype gDS = -gds - gate_source;
- const nl_fptype gDB = gmb - gbd;
+ const nl_fptype gDB = gmb - gbd;
- nl_fptype gSG = -gm;
+ nl_fptype gSG = -gm;
const nl_fptype gSD = -gds + gate_drain;
- nl_fptype gSS = gbs + gds + gate_source;
+ nl_fptype gSS = gbs + gds + gate_source;
const nl_fptype gSB = -gbs - gmb;
- nl_fptype gBG = nlconst::zero();
+ nl_fptype gBG = nlconst::zero();
const nl_fptype gBD = -gbd;
const nl_fptype gBS = -gbs;
- nl_fptype gBB = gbs + gbd;
+ nl_fptype gBB = gbs + gbd;
if (m_capacitor_model != 0)
{
@@ -553,23 +604,26 @@ namespace netlist::analog
else
calculate_caps(Vgd, Vgs, Vth, m_Cgd, m_Cgs, m_Cgb);
- set_cap(m_cap_gb, m_Cgb + m_model_acc.m_CGBO * m_Leff, Vgb, gGG, gGB, gBG, gBB, IG, IB);
- set_cap(m_cap_gs, m_Cgs + m_model_acc.m_CGSO * m_model_acc.m_W, Vgs, gGG, gGS, gSG, gSS, IG, IS);
- set_cap(m_cap_gd, m_Cgd + m_model_acc.m_CGDO * m_model_acc.m_W, Vgd, gGG, gGD, gDG, gDD, IG, ID);
+ set_cap(m_cap_gb, m_Cgb + m_model_acc.m_CGBO * m_Leff, Vgb, gGG,
+ gGB, gBG, gBB, IG, IB);
+ set_cap(m_cap_gs, m_Cgs + m_model_acc.m_CGSO * m_model_acc.m_W, Vgs,
+ gGG, gGS, gSG, gSS, IG, IS);
+ set_cap(m_cap_gd, m_Cgd + m_model_acc.m_CGDO * m_model_acc.m_W, Vgd,
+ gGG, gGD, gDG, gDD, IG, ID);
}
// Source connected to body, Diode S-B shorted!
const nl_fptype gSSBB = gSS + gBB + gBS + gSB;
- const auto zero(nlconst::zero());
+ 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
/// |
/// | D S G I
@@ -600,13 +654,11 @@ namespace netlist::analog
/// |
}
- NETLIB_UPDATE_PARAM(MOSFET)
- {
- }
+ NETLIB_UPDATE_PARAM(MOSFET) {}
} // namespace netlist::analog
-namespace netlist::devices {
+namespace netlist::devices
+{
NETLIB_DEVICE_IMPL_NS(analog, MOSFET, "MOSFET", "MODEL")
} // namespace netlist::devices
-
diff --git a/src/lib/netlist/analog/nlid_twoterm.cpp b/src/lib/netlist/analog/nlid_twoterm.cpp
index 3d5d0721dfb..1a3c79e713f 100644
--- a/src/lib/netlist/analog/nlid_twoterm.cpp
+++ b/src/lib/netlist/analog/nlid_twoterm.cpp
@@ -125,7 +125,7 @@ namespace netlist::analog
NETLIB_TIMESTEP(L)
{
- if (ts_type == time_step_type::FORWARD)
+ if (ts_type == detail::time_step_type::FORWARD)
{
m_last_I = m_I;
m_last_G = m_G;
diff --git a/src/lib/netlist/analog/nlid_twoterm.h b/src/lib/netlist/analog/nlid_twoterm.h
index f940b8fa6dc..d84356fe82d 100644
--- a/src/lib/netlist/analog/nlid_twoterm.h
+++ b/src/lib/netlist/analog/nlid_twoterm.h
@@ -312,7 +312,7 @@ namespace netlist::analog
NETLIB_IS_TIMESTEP(true)
NETLIB_TIMESTEPI()
{
- if (ts_type == time_step_type::FORWARD)
+ if (ts_type == detail::time_step_type::FORWARD)
{
// G, Ieq
const auto res(m_cap.time_step(m_C(), deltaV(), step));
@@ -584,7 +584,7 @@ namespace netlist::analog
NETLIB_TIMESTEPI()
{
- if (ts_type == time_step_type::FORWARD)
+ if (ts_type == detail::time_step_type::FORWARD)
{
m_t += step;
m_funcparam[0] = m_t;
@@ -637,7 +637,7 @@ namespace netlist::analog
NETLIB_IS_TIMESTEP(!m_func().empty())
NETLIB_TIMESTEPI()
{
- if (ts_type == time_step_type::FORWARD)
+ if (ts_type == detail::time_step_type::FORWARD)
{
m_t += step;
m_funcparam[0] = m_t;
diff --git a/src/lib/netlist/build/.clang-format b/src/lib/netlist/build/.clang-format
index 09d57438f7b..d312a0798cc 100644
--- a/src/lib/netlist/build/.clang-format
+++ b/src/lib/netlist/build/.clang-format
@@ -25,13 +25,14 @@ BreakStringLiterals: false
AlwaysBreakTemplateDeclarations: Yes
# AfterComma does not work <= 13
#BreakInheritanceList: AfterComma
-#BreakInheritanceList: BeforeComma
+BreakInheritanceList: BeforeComma
#BreakInheritanceList: false
SpaceBeforeInheritanceColon: true
#AlignAfterOpenBracket: DontAlign
AlignAfterOpenBracket: Align
PointerAlignment: Right
+ReferenceAlignment: Right
SpacesInAngles: false
SpaceBeforeAssignmentOperators: true
AlignConsecutiveDeclarations: true
@@ -90,16 +91,17 @@ StatementMacros:
TypenameMacros:
- "NETLIST_NAME"
- "NETLIB_NAME"
+ - "PENUM"
WhitespaceSensitiveMacros:
- "ALIAS"
- - "NET_C"
- "DIPPINS"
+ - "NET_C"
+ - "PENUM"
IndentPPDirectives: BeforeHash
MacroBlockBegin: "^static NETLIST_START\\(.+\\)|static TRUTHTABLE_START\\(.*\\)$"
MacroBlockEnd: "^NETLIST_END\\(\\)|TRUTHTABLE_END\\(\\)$"
-# ReferenceAlignment: Middle
# Avoid formatting
# -- clang-tidy
diff --git a/src/lib/netlist/build/cspell.json b/src/lib/netlist/build/cspell.json
index f242083ac82..bf46cc2e992 100644
--- a/src/lib/netlist/build/cspell.json
+++ b/src/lib/netlist/build/cspell.json
@@ -19,6 +19,7 @@
"Schmitt",
"Schottky",
"Zener",
+ "Thevenin",
// Company names
"Fairchild",
"Signetics",
@@ -69,6 +70,7 @@
// FIXME: Remove everything below here again
// Excluded for now ... Still over 1000 in the log
"plib", // namespace
+ "isnull",
"pstring",
"passert",
"putf",
@@ -79,6 +81,8 @@
"idrn",
"preprocessor",
"ppreprocessor",
+ "psource",
+ "psemaphore",
"modacc",
"Ainv",
"anetlist",
diff --git a/src/lib/netlist/build/makefile b/src/lib/netlist/build/makefile
index ab89d6adcdd..077b72b028f 100644
--- a/src/lib/netlist/build/makefile
+++ b/src/lib/netlist/build/makefile
@@ -114,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)/.. -I$(SRC)/../..
+CCOREFLAGS = -g -O3 -std=c++17 -I$(SRC)
CFLAGS = $(LTO) $(CCOREFLAGS) $(CEXTRAFLAGS)
LDFLAGS = $(LTO) -g -O3 -std=c++17 $(LDEXTRAFLAGS)
diff --git a/src/lib/netlist/core/base_objects.h b/src/lib/netlist/core/base_objects.h
index 1f924d988dc..b62c82e160c 100644
--- a/src/lib/netlist/core/base_objects.h
+++ b/src/lib/netlist/core/base_objects.h
@@ -17,9 +17,19 @@
#include "../plib/pexception.h"
#include "../plib/plists.h"
#include "../plib/pmempool.h"
+#include "../plib/ppmf.h"
#include <unordered_map>
+namespace netlist
+{
+ /// \brief Delegate type for device notification.
+ ///
+ using nl_delegate = plib::pmfp<void()>;
+ using nl_delegate_ts = plib::pmfp<void(detail::time_step_type, nl_fptype)>;
+ using nl_delegate_dyn = plib::pmfp<void()>;
+} // namespace netlist
+
namespace netlist::detail
{
@@ -131,16 +141,16 @@ namespace netlist::detail
PCOPYASSIGNMOVE(netlist_object_t, delete)
- netlist_state_t & state() noexcept;
+ netlist_state_t &state() noexcept;
const netlist_state_t &state() const noexcept;
- constexpr netlist_t & exec() 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) noexcept(
- false)
+ device_arena::unique_ptr<T>
+ make_pool_object(Args &&...args) noexcept(false)
{
return state().make_pool_object<T>(std::forward<Args>(args)...);
}
@@ -174,13 +184,13 @@ 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:
@@ -218,7 +228,7 @@ 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");
+ "netlist_sig_t size not sufficient");
enum state_e
{
@@ -231,7 +241,7 @@ namespace netlist::detail
};
core_terminal_t(core_device_t &dev, const pstring &aname, state_e state,
- nl_delegate delegate);
+ nl_delegate delegate);
virtual ~core_terminal_t() noexcept = default;
PCOPYASSIGNMOVE(core_terminal_t, delete)
@@ -271,12 +281,12 @@ namespace netlist::detail
void reset() noexcept
{
- set_state(
- is_type(terminal_type::OUTPUT) ? STATE_OUT : STATE_INP_ACTIVE);
+ 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)
{
@@ -298,7 +308,7 @@ namespace netlist::detail
private:
nl_delegate m_delegate;
- net_t * m_net;
+ net_t *m_net;
state_var<state_e> m_state;
};
diff --git a/src/lib/netlist/core/core_device.h b/src/lib/netlist/core/core_device.h
index 87391450787..305a5aed14e 100644
--- a/src/lib/netlist/core/core_device.h
+++ b/src/lib/netlist/core/core_device.h
@@ -33,7 +33,7 @@ namespace netlist
friend class factory::device_element_t;
friend class factory::library_element_t;
- template <typename CX>
+ template <typename DEVICE>
friend struct sub_device_wrapper;
friend class solver::matrix_solver_t;
@@ -103,7 +103,7 @@ namespace netlist
log_type &log();
public:
- virtual void time_step([[maybe_unused]] time_step_type ts_type,
+ virtual void time_step([[maybe_unused]] detail::time_step_type ts_type,
[[maybe_unused]] nl_fptype st) noexcept
{
}
diff --git a/src/lib/netlist/core/device.h b/src/lib/netlist/core/device.h
index 5f4a6937f23..12f3f7d174e 100644
--- a/src/lib/netlist/core/device.h
+++ b/src/lib/netlist/core/device.h
@@ -73,40 +73,42 @@ namespace netlist
// FIXME: Rename
// -------------------------------------------------------------------------
- template <typename CX>
+ template <typename DEVICE>
struct sub_device_wrapper
{
- using constructor_data_t = typename CX::constructor_data_t;
- using constructor_param_t = typename CX::constructor_param_t;
+ using constructor_data_t = typename DEVICE::constructor_data_t;
+ using constructor_param_t = typename DEVICE::constructor_param_t;
template <typename... Args>
sub_device_wrapper(base_device_t &owner, const pstring &name,
- Args &&...args)
+ Args &&...args)
{
- // m_dev = owner.state().make_pool_object<CX>(owner, name,
+ // m_dev = owner.state().make_pool_object<DEVICE>(owner, name,
// std::forward<Args>(args)...);
- m_dev = owner.state().make_pool_object<CX>(
+ m_dev = owner.state().make_pool_object<DEVICE>(
constructor_data_t{owner.state(), owner.name() + "." + name},
std::forward<Args>(args)...);
- owner.state().register_device(m_dev->name(),
+ 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,
+ // m_dev = owner.state().make_pool_object<DEVICE>(owner, name,
// std::forward<Args>(args)...);
- m_dev = owner.state().make_pool_object<CX>(
+ m_dev = owner.state().make_pool_object<DEVICE>(
constructor_data_t{owner.state(), owner.name() + "." + name},
std::forward<Args>(args)...);
- owner.state().register_device(m_dev->name(),
+ 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; }
+ DEVICE & operator()() { return *m_dev; }
+ const DEVICE &operator()() const { return *m_dev; }
private:
- device_arena::unique_ptr<CX> m_dev;
+ device_arena::unique_ptr<DEVICE> m_dev;
};
} // namespace netlist
diff --git a/src/lib/netlist/core/device_macros.h b/src/lib/netlist/core/device_macros.h
index af1fb15e78f..8f46f036412 100644
--- a/src/lib/netlist/core/device_macros.h
+++ b/src/lib/netlist/core/device_macros.h
@@ -107,7 +107,7 @@ public: \
#define NETLIB_TIMESTEPI() \
public: \
- virtual void time_step(time_step_type ts_type, \
+ virtual void time_step(detail::time_step_type ts_type, \
nl_fptype step) noexcept override
/// \brief Used to implement the body of the time stepping code.
@@ -119,7 +119,7 @@ public: \
/// \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, \
+ void NETLIB_NAME(cname)::time_step(detail::time_step_type ts_type, \
nl_fptype step) noexcept
//#define NETLIB_DELEGATE(name) nl_delegate(&this_type :: name, this)
diff --git a/src/lib/netlist/core/logic_family.h b/src/lib/netlist/core/logic_family.h
index 97084dd4dc0..216e74ead2a 100644
--- a/src/lib/netlist/core/logic_family.h
+++ b/src/lib/netlist/core/logic_family.h
@@ -10,6 +10,8 @@
#include "../nltypes.h"
+#include "../plib/palloc.h"
+#include "../plib/pmempool.h"
#include "../plib/pstring.h"
namespace netlist
diff --git a/src/lib/netlist/core/netlist_state.h b/src/lib/netlist/core/netlist_state.h
index f8a87b9280f..505665d9acf 100644
--- a/src/lib/netlist/core/netlist_state.h
+++ b/src/lib/netlist/core/netlist_state.h
@@ -12,6 +12,7 @@
#include "queue.h"
#include "../plib/plists.h"
+#include "../plib/pmempool.h"
#include "../plib/pstate.h"
#include "../plib/pstring.h"
@@ -31,8 +32,8 @@ namespace netlist
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 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<
@@ -55,8 +56,9 @@ namespace netlist
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
///
@@ -91,7 +93,7 @@ namespace netlist
// 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
@@ -108,23 +110,23 @@ namespace netlist
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);
+ 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)
+ const pstring &stname, const std::size_t count)
{
this->run_state_manager().save_state_ptr(
plib::void_ptr_cast(&owner), module + "." + stname,
@@ -165,8 +167,8 @@ namespace netlist
/// \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)
if (d.first == name)
@@ -187,11 +189,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
@@ -203,24 +205,24 @@ 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() noexcept;
+ 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; }
+ 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; }
+ devices_collection_type &devices() noexcept { return m_devices; }
const devices_collection_type &devices() const noexcept
{
return m_devices;
@@ -234,13 +236,13 @@ namespace netlist
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 detail::queue_t &m_queue; // performance
+ const plib::pperftime_t<true> &m_stat_mainloop;
const plib::pperfcount_t<true> &m_perf_out_processed;
};
@@ -256,8 +258,8 @@ 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];
}
@@ -281,7 +283,7 @@ namespace netlist
#if !(NL_USE_INPLACE_CORE_TERMS)
// all terms for a net
std::unordered_map<const detail::net_t *,
- std::vector<detail::core_terminal_t *>>
+ std::vector<detail::core_terminal_t *>>
m_core_terms;
#endif
// dummy version
diff --git a/src/lib/netlist/core/object_array.h b/src/lib/netlist/core/object_array.h
index 08b66a64990..cf1bc5ea4af 100644
--- a/src/lib/netlist/core/object_array.h
+++ b/src/lib/netlist/core/object_array.h
@@ -8,8 +8,12 @@
#ifndef NL_CORE_OBJECT_ARRAY_H_
#define NL_CORE_OBJECT_ARRAY_H_
+#include "base_objects.h"
+#include "logic.h"
+
#include "../nltypes.h"
+#include "../plib/pfmtlog.h"
#include "../plib/plists.h"
#include "../plib/pstring.h"
diff --git a/src/lib/netlist/core/state_var.h b/src/lib/netlist/core/state_var.h
index 7c6e7aec8be..a2b0ae5f477 100644
--- a/src/lib/netlist/core/state_var.h
+++ b/src/lib/netlist/core/state_var.h
@@ -10,6 +10,7 @@
#include "../nltypes.h"
+#include "../plib/pfmtlog.h"
#include "../plib/pstring.h"
namespace netlist
diff --git a/src/lib/netlist/devices/nld_4013.cpp b/src/lib/netlist/devices/nld_4013.cpp
index 30ddb2d63d1..5fa3aa25586 100644
--- a/src/lib/netlist/devices/nld_4013.cpp
+++ b/src/lib/netlist/devices/nld_4013.cpp
@@ -78,7 +78,7 @@ namespace netlist::devices {
}
else
{
- newstate_setreset(set, reset);
+ set_reset(set, reset);
m_CLK.inactivate();
m_D.inactivate();
}
@@ -86,7 +86,7 @@ namespace netlist::devices {
NETLIB_HANDLERI(clk)
{
- newstate_clk(m_nextD);
+ set_output(m_nextD);
m_CLK.inactivate();
}
@@ -101,14 +101,14 @@ namespace netlist::devices {
nld_power_pins m_power_pins;
- void newstate_clk(const netlist_sig_t stateQ)
+ void set_output(const netlist_sig_t stateQ)
{
- static constexpr auto delay = NLTIME_FROM_NS(150);
+ static constexpr const auto delay = NLTIME_FROM_NS(150);
m_Q.push(stateQ, delay);
m_QQ.push(!stateQ, delay);
}
- void newstate_setreset(const netlist_sig_t stateQ, const netlist_sig_t stateQQ)
+ void set_reset(const netlist_sig_t stateQ, const netlist_sig_t stateQQ)
{
// Q: 150 ns, QQ: 200 ns
static constexpr const std::array<netlist_time, 2> delay = { NLTIME_FROM_NS(150), NLTIME_FROM_NS(200) };
diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h
index d06d3767bd9..d191a4537ba 100644
--- a/src/lib/netlist/nl_base.h
+++ b/src/lib/netlist/nl_base.h
@@ -17,6 +17,7 @@
namespace netlist
{
// nothing in here. This should not change.
+
} // namespace netlist
#endif // NLBASE_H_
diff --git a/src/lib/netlist/nl_config.h b/src/lib/netlist/nl_config.h
index 01bc99dc706..7306de88cde 100644
--- a/src/lib/netlist/nl_config.h
+++ b/src/lib/netlist/nl_config.h
@@ -134,7 +134,7 @@ 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
+ /// TTL games (e.g. pong) and analog applications like e.g. kidniki
/// sound.
///
/// Best performance for pong is achieved with a value of 16, but this
@@ -178,7 +178,7 @@ namespace netlist
/// | 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
+ 10'000'000'000LL>; // NOLINT
/// \brief Recommended clock to be used
///
@@ -187,7 +187,7 @@ namespace netlist
/// 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
+ 1'000'000'000>; // NOLINT
/// \brief Default logic family
///
@@ -196,27 +196,27 @@ namespace netlist
/// \brief Maximum queue size
///
using max_queue_size = std::integral_constant<std::size_t,
- 1024>; // NOLINT
+ 1024>; // NOLINT
/// \brief Maximum queue size for solvers
///
using max_solver_queue_size = std::integral_constant<std::size_t,
- 512>; // NOLINT
+ 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>;
+ NL_USE_FLOAT128>;
/// \brief Floating point types used
///
@@ -242,7 +242,7 @@ namespace netlist
/// the default approach. It is ~20% slower.
///
using use_copy_instead_of_reference = std::integral_constant<bool,
- false>;
+ false>;
/// \brief Avoid unnecessary queue pushes
///
@@ -416,16 +416,4 @@ namespace netlist
#endif
} // namespace netlist
-//============================================================
-// Asserts
-//============================================================
-
-#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 46f2ac3e5e1..c65ff257846 100644
--- a/src/lib/netlist/nl_errstr.h
+++ b/src/lib/netlist/nl_errstr.h
@@ -8,13 +8,53 @@
#ifndef NL_ERRSTR_H_
#define NL_ERRSTR_H_
+#include "plib/pexception.h"
#include "plib/pfmtlog.h"
namespace netlist
{
- static constexpr const char sHINT_NO_DEACTIVATE[] = ".HINT_NO_DEACTIVATE"; // NOLINT(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
- static constexpr const char sHINT_NC[] = ".HINT_NC"; // NOLINT(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
+ static constexpr const char sHINT_NO_DEACTIVATE[]
+ = ".HINT_NO_DEACTIVATE"; // NOLINT(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
+ static constexpr const char sHINT_NC[]
+ = ".HINT_NC"; // NOLINT(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
+
+ // -------------------------------------------------------------------------
+ // Exceptions
+ // -------------------------------------------------------------------------
+
+ /// \brief Generic netlist exception.
+ /// The exception is used in all events which are considered fatal.
+
+ class nl_exception : public plib::pexception
+ {
+ public:
+ /// \brief Constructor.
+ /// Allows a descriptive text to be passed to the exception
+
+ explicit nl_exception(const pstring &text //!< text to be passed
+ )
+ : plib::pexception(text)
+ {
+ }
+
+ /// \brief Constructor.
+ /// Allows to use \ref plib::pfmt logic to be used in exception
+
+ template <typename... Args>
+ explicit nl_exception(const pstring &fmt, //!< format to be used
+ Args &&...args //!< arguments to be passed
+ )
+ : plib::pexception(plib::pfmt(fmt)(std::forward<Args>(args)...))
+ {
+ }
+ };
+
+ // -------------------------------------------------------------------------
+ // Error messages
+ // -------------------------------------------------------------------------
+
+ // clang-format off
// nl_base.cpp
@@ -187,9 +227,19 @@ namespace netlist
PERRMSGV(MF_FILE_OPEN_ERROR, 1, "Error opening file: {1}")
-
-
+ // clang-format on
} // namespace netlist
+// -------------------------------------------------------------------------
+// Asserts
+// -------------------------------------------------------------------------
+
+#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 // NL_ERRSTR_H_
diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h
index 7c5cc2e7930..31e971026e9 100644
--- a/src/lib/netlist/nl_setup.h
+++ b/src/lib/netlist/nl_setup.h
@@ -8,14 +8,14 @@
#ifndef NLSETUP_H_
#define NLSETUP_H_
+#include "nl_config.h"
+#include "nltypes.h"
+
#include "plib/ppreprocessor.h"
#include "plib/psource.h"
#include "plib/pstream.h"
#include "plib/pstring.h"
-#include "nl_config.h"
-#include "nltypes.h"
-
#include <initializer_list>
#include <memory>
#include <stack>
@@ -26,118 +26,95 @@
// MACROS - netlist definitions
//============================================================
-#define NET_STR(x) # x
+#define NET_STR(x) #x
-#define NET_MODEL(model) \
- setup.register_model(model);
+#define NET_MODEL(model) setup.register_model(model);
-#define ALIAS(alias, name) \
- setup.register_alias(# alias, # name);
+#define ALIAS(alias, name) setup.register_alias(#alias, #name);
#define DIPPINS(pin1, ...) \
- setup.register_dip_alias_arr( # pin1 ", " # __VA_ARGS__);
+ setup.register_dip_alias_arr(#pin1 ", " #__VA_ARGS__);
// to be used to reference new library truth table devices
-#define NET_REGISTER_DEV(type, name) \
- setup.register_dev(# type, # name);
+#define NET_REGISTER_DEV(type, name) setup.register_dev(#type, #name);
// name is first element so that __VA_ARGS__ always has one element
-#define NET_REGISTER_DEVEXT(type, ...) \
- setup.register_dev(# type, { PSTRINGIFY_VA(__VA_ARGS__) });
+#define NET_REGISTER_DEVEXT(type, ...) \
+ setup.register_dev(#type, {PSTRINGIFY_VA(__VA_ARGS__)});
#define NET_CONNECT(name, input, output) \
- setup.register_link(# name "." # input, # output);
+ setup.register_link(#name "." #input, #output);
#define NET_C(term1, ...) \
- setup.register_connection_arr( # term1 ", " # __VA_ARGS__);
+ setup.register_connection_arr(#term1 ", " #__VA_ARGS__);
-#define PARAM(name, val) \
- setup.register_param(NET_STR(name), NET_STR(val));
+#define PARAM(name, val) setup.register_param(NET_STR(name), NET_STR(val));
#define DEFPARAM(name, val) \
- setup.register_default_param(NET_STR(name), NET_STR(val));
+ setup.register_default_param(NET_STR(name), NET_STR(val));
-#define HINT(name, val) \
- setup.register_hint(# name , ".HINT_" # val);
+#define HINT(name, val) setup.register_hint(#name, ".HINT_" #val);
#define NETDEV_PARAMI(name, param, val) \
- setup.register_param(# name "." # param, val);
+ setup.register_param(#name "." #param, val);
-#define NETLIST_NAME(name) netlist ## _ ## name
+#define NETLIST_NAME(name) netlist##_##name
#define NETLIST_EXTERNAL(name) \
- void NETLIST_NAME(name)(netlist::nlparse_t &setup);
+ void NETLIST_NAME(name)(netlist::nlparse_t & setup);
#define NETLIST_START(name) \
-void NETLIST_NAME(name)([[maybe_unused]] netlist::nlparse_t &setup) \
+ void NETLIST_NAME(name)([[maybe_unused]] netlist::nlparse_t & setup)
#define LOCAL_SOURCE(name) \
- setup.register_source_proc(# name, &NETLIST_NAME(name));
+ setup.register_source_proc(#name, &NETLIST_NAME(name));
#define EXTERNAL_SOURCE(name) \
- setup.register_source_proc(# name, &NETLIST_NAME(name));
+ setup.register_source_proc(#name, &NETLIST_NAME(name));
#define LOCAL_LIB_ENTRY_2(type, name) \
- type ## _SOURCE(name) \
- setup.register_lib_entry(# name, "", PSOURCELOC());
+ type##_SOURCE(name) setup.register_lib_entry(#name, "", PSOURCELOC());
#define LOCAL_LIB_ENTRY_3(type, name, param_spec) \
- type ## _SOURCE(name) \
- setup.register_lib_entry(# name, param_spec, PSOURCELOC());
+ type##_SOURCE(name) \
+ setup.register_lib_entry(#name, param_spec, PSOURCELOC());
#define LOCAL_LIB_ENTRY(...) PCALLVARARG(LOCAL_LIB_ENTRY_, LOCAL, __VA_ARGS__)
-#define EXTERNAL_LIB_ENTRY(...) PCALLVARARG(LOCAL_LIB_ENTRY_, EXTERNAL, __VA_ARGS__)
+#define EXTERNAL_LIB_ENTRY(...) \
+ PCALLVARARG(LOCAL_LIB_ENTRY_, EXTERNAL, __VA_ARGS__)
-#define INCLUDE(name) \
- setup.include(# name);
+#define INCLUDE(name) setup.include(#name);
#define SUBMODEL(model, name) \
- setup.namespace_push(# name); \
- setup.include(# model); \
- setup.namespace_pop();
+ setup.namespace_push(#name); \
+ setup.include(#model); \
+ setup.namespace_pop();
#define OPTIMIZE_FRONTIER(attach, r_in, r_out) \
- setup.register_frontier(# attach, PSTRINGIFY_VA(r_in), PSTRINGIFY_VA(r_out));
+ setup.register_frontier(#attach, PSTRINGIFY_VA(r_in), PSTRINGIFY_VA(r_out));
// -----------------------------------------------------------------------------
// truth table defines
// -----------------------------------------------------------------------------
-#if 0
-#define TRUTHTABLE_START(cname, in, out, pdef_params) \
- 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; \
- NETLIST_NAME(cname ## _impl)(xdesc); \
- setup.truth_table_create(xdesc, def_params, std::move(sloc)); \
- } \
- static void NETLIST_NAME(cname ## _impl)(netlist::tt_desc &desc) \
- {
-#else
-#define TRUTH_TABLE(cname, in, out, pdef_params) \
- void NETLIST_NAME(cname ## _impl)(netlist::nlparse_t &setup, netlist::tt_desc &desc); \
- static void NETLIST_NAME(cname)(netlist::nlparse_t &setup) \
- { \
- netlist::tt_desc desc{ #cname, in, out, "", {} }; \
- NETLIST_NAME(cname ## _impl)(setup, desc); \
- setup.truth_table_create(desc, pdef_params, PSOURCELOC()); \
- } \
- static void NETLIST_NAME(cname ## _impl)([[maybe_unused]] netlist::nlparse_t &setup, netlist::tt_desc &desc) \
-
-#endif
+#define TRUTH_TABLE(cname, in, out, params) \
+ void NETLIST_NAME(cname##_impl)(netlist::nlparse_t & setup, \
+ netlist::tt_desc & desc); \
+ static void NETLIST_NAME(cname)(netlist::nlparse_t & setup) \
+ { \
+ netlist::tt_desc desc{#cname, in, out, "", {}}; \
+ NETLIST_NAME(cname##_impl)(setup, desc); \
+ setup.truth_table_create(desc, params, PSOURCELOC()); \
+ } \
+ static void NETLIST_NAME(cname##_impl)( \
+ [[maybe_unused]] netlist::nlparse_t & setup, netlist::tt_desc & desc)
-#define TT_HEAD(x) \
- desc.desc.emplace_back(x);
+#define TT_HEAD(x) desc.desc.emplace_back(x);
-#define TT_LINE(x) \
- desc.desc.emplace_back(x);
+#define TT_LINE(x) desc.desc.emplace_back(x);
-#define TT_FAMILY(x) \
- desc.family = x;
+#define TT_FAMILY(x) desc.family = x;
#define TRUTHTABLE_ENTRY(name) \
LOCAL_SOURCE(name) \
@@ -152,10 +129,10 @@ namespace netlist
struct tt_desc
{
- pstring name;
- unsigned long ni;
- unsigned long no;
- pstring family;
+ pstring name;
+ unsigned long ni;
+ unsigned long no;
+ pstring family;
std::vector<pstring> desc;
};
@@ -193,25 +170,29 @@ namespace netlist
/// \param type the alias type see \ref alias_type
/// \param alias the alias to be qualified
/// \param points_to the pin aliased
- void register_alias(detail::alias_type type, const pstring &alias, const pstring &points_to);
+ void register_alias(detail::alias_type type, const pstring &alias,
+ const pstring &points_to);
/// \brief Register an aliases where alias and references are fully qualified names
/// \param type the alias type see \ref alias_type
/// \param alias the alias to be qualified
/// \param points_to the pin aliased
- void register_fqn_alias(detail::alias_type type, const pstring &alias, const pstring &points_to);
+ void register_fqn_alias(detail::alias_type type, const pstring &alias,
+ const pstring &points_to);
void register_dip_alias_arr(const pstring &terms);
// 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 **factory_element = nullptr);
- void register_dev(const pstring &classname, std::initializer_list<const char *> more_parameters);
+ const std::vector<pstring> &params_and_connections,
+ 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)
{
register_dev(classname, name, std::vector<pstring>());
}
- void register_hint(const pstring &object_name, const pstring &hint_name);
+ void
+ register_hint(const pstring &object_name, const pstring &hint_name);
void register_connection(const pstring &sin, const pstring &sout);
void register_connection_arr(const pstring &terms);
@@ -230,20 +211,23 @@ namespace netlist
register_param_fp(param, plib::narrow_cast<nl_fptype>(value));
}
- void register_lib_entry(const pstring &name, const pstring &def_params, plib::source_location &&loc);
+ void register_lib_entry(const pstring &name, const pstring &def_params,
+ plib::source_location &&loc);
- void register_frontier(const pstring &attach, const pstring &r_IN, const pstring &r_OUT);
+ void register_frontier(const pstring &attach, const pstring &r_IN,
+ const pstring &r_OUT);
// register a source
template <typename S, typename... Args>
- void register_source(Args&&... args)
+ void register_source(Args &&...args)
{
m_sources.add_source<S>(std::forward<Args>(args)...);
}
void register_source_proc(const pstring &name, nlsetup_func func);
- void truth_table_create(tt_desc &desc, const pstring &def_params, plib::source_location &&loc);
+ void truth_table_create(tt_desc &desc, const pstring &def_params,
+ plib::source_location &&loc);
// include other files
@@ -256,17 +240,18 @@ namespace netlist
// FIXME: used by source_t - need a different approach at some time
bool parse_stream(plib::istream_uptr &&in_stream, const pstring &name);
- bool parse_tokens(const plib::detail::token_store_t &tokens, const pstring &name);
+ bool parse_tokens(const plib::detail::token_store_t &tokens,
+ const pstring &name);
template <typename S, typename... Args>
- void add_include(Args&&... args)
+ void add_include(Args &&...args)
{
m_includes.add_source<S>(std::forward<Args>(args)...);
}
void add_define(const pstring &def, const pstring &val)
{
- m_defines.insert({ def, plib::ppreprocessor::define_t(def, val)});
+ m_defines.insert({def, plib::ppreprocessor::define_t(def, val)});
}
void add_define(const pstring &define);
@@ -274,10 +259,10 @@ namespace netlist
// register a list of logs
void register_dynamic_log_devices(const std::vector<pstring> &log_list);
- factory::list_t &factory() noexcept;
+ factory::list_t &factory() noexcept;
const factory::list_t &factory() const noexcept;
- log_type &log() noexcept { return m_log; }
+ log_type &log() noexcept { return m_log; }
const log_type &log() const noexcept { return m_log; }
plib::istream_uptr get_data_stream(const pstring &name);
@@ -285,23 +270,22 @@ namespace netlist
private:
pstring namespace_prefix() const;
pstring build_fqn(const pstring &obj_name) const;
- void register_param_fp(const pstring &param, nl_fptype value);
- bool device_exists(const pstring &name) const;
+ void register_param_fp(const pstring &param, nl_fptype value);
+ bool device_exists(const pstring &name) const;
// FIXME: stale? - remove later
void remove_connections(const pstring &pin);
- plib::ppreprocessor::defines_map_type m_defines;
- plib::psource_collection_t m_includes;
- std::stack<pstring> m_namespace_stack;
- plib::psource_collection_t m_sources;
- detail::abstract_t & m_abstract;
+ plib::ppreprocessor::defines_map_type m_defines;
+ plib::psource_collection_t m_includes;
+ std::stack<pstring> m_namespace_stack;
+ plib::psource_collection_t m_sources;
+ detail::abstract_t &m_abstract;
log_type &m_log;
- unsigned m_frontier_cnt;
+ unsigned m_frontier_cnt;
};
} // namespace netlist
-
#endif // NLSETUP_H_
diff --git a/src/lib/netlist/nltypes.h b/src/lib/netlist/nltypes.h
index 15cd65a9471..e6a74db1c9d 100644
--- a/src/lib/netlist/nltypes.h
+++ b/src/lib/netlist/nltypes.h
@@ -14,9 +14,6 @@
#include "nl_config.h"
-#include "plib/pmempool.h"
-#include "plib/ppmf.h"
-#include "plib/pstring.h"
#include "plib/ptime.h"
#include "plib/ptypes.h"
@@ -170,12 +167,12 @@ namespace netlist
///
/// \note This is not the right location yet.
///
-
using device_arena = std::conditional_t<
config::use_mempool::value,
plib::mempool_arena<plib::aligned_arena<>,
config::mempool_align::value>,
plib::aligned_arena<>>;
+
using host_arena = plib::aligned_arena<>;
using log_type = plib::plog_base<NL_DEBUG>;
@@ -184,25 +181,19 @@ namespace netlist
// Types needed by various includes
//============================================================
- /// \brief Time step type.
- ///
- /// May be either FORWARD or RESTORE
- ///
- enum class time_step_type
- {
- 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()>;
-
namespace detail
{
+ /// \brief Time step type.
+ ///
+ /// May be either FORWARD or RESTORE
+ ///
+ enum class time_step_type
+ {
+ FORWARD, //!< forward time
+ RESTORE //!< restore state before last forward
+ };
+
/// \brief Enum specifying the type of object
///
enum class terminal_type
@@ -220,10 +211,10 @@ namespace netlist
///
enum class alias_type
{
- UNKNOWN, //!< Used as a placeholder during code changes
- INTERNAL, //!< the alias references a internal pin
- FUNCTIONAL, //!< Used for aliases e.g. in BJTs : ALIAS("B",
- //!< somesub.p())
+ UNKNOWN, //!< Used as a placeholder during code changes
+ INTERNAL, //!< the alias references a internal pin
+ FUNCTIONAL, //!< Used for aliases e.g. in BJTs : ALIAS("B",
+ //!< somesub.p())
PACKAGE_PIN, //!< the alias references a package pin, e.g. ALIAS(13,
//!< B.CLK)
READABILITY, //!< the alias is used to improved readability, e.g.
@@ -317,37 +308,6 @@ namespace netlist
using desc_const_t = std::integral_constant<const T, V>;
};
- //============================================================
- // Exceptions
- //============================================================
-
- /// \brief Generic netlist exception.
- /// The exception is used in all events which are considered fatal.
-
- class nl_exception : public plib::pexception
- {
- public:
- /// \brief Constructor.
- /// Allows a descriptive text to be passed to the exception
-
- explicit nl_exception(const pstring &text //!< text to be passed
- )
- : plib::pexception(text)
- {
- }
-
- /// \brief Constructor.
- /// Allows to use \ref plib::pfmt logic to be used in exception
-
- template <typename... Args>
- explicit nl_exception(const pstring &fmt, //!< format to be used
- Args &&...args //!< arguments to be passed
- )
- : plib::pexception(plib::pfmt(fmt)(std::forward<Args>(args)...))
- {
- }
- };
-
} // namespace netlist
#endif // NLTYPES_H_
diff --git a/src/lib/netlist/plib/pmath.h b/src/lib/netlist/plib/pmath.h
index 311a928a597..96f815bcca7 100644
--- a/src/lib/netlist/plib/pmath.h
+++ b/src/lib/netlist/plib/pmath.h
@@ -9,6 +9,7 @@
///
#include "pconfig.h"
+#include "pgsl.h"
#include "ptypes.h"
#include <algorithm>
@@ -271,8 +272,7 @@ namespace plib
/// FIXME: limited implementation
///
template <typename T1, typename T2>
- static inline
- auto pow(T1 v, T2 p) noexcept -> decltype(std::pow(v, p))
+ static inline auto pow(T1 v, T2 p) noexcept -> decltype(std::pow(v, p))
{
return std::pow(v, p);
}
@@ -283,60 +283,30 @@ namespace plib
return constants<FLOAT128>::one() / v;
}
- static FLOAT128 abs(FLOAT128 v) noexcept
- {
- return fabsq(v);
- }
+ static FLOAT128 abs(FLOAT128 v) noexcept { return fabsq(v); }
- static FLOAT128 sqrt(FLOAT128 v) noexcept
- {
- return sqrtq(v);
- }
+ static FLOAT128 sqrt(FLOAT128 v) noexcept { return sqrtq(v); }
static FLOAT128 hypot(FLOAT128 v1, FLOAT128 v2) noexcept
{
return hypotq(v1, v2);
}
- static FLOAT128 exp(FLOAT128 v) noexcept
- {
- return expq(v);
- }
+ static FLOAT128 exp(FLOAT128 v) noexcept { return expq(v); }
- static FLOAT128 log(FLOAT128 v) noexcept
- {
- return logq(v);
- }
+ static FLOAT128 log(FLOAT128 v) noexcept { return logq(v); }
- static FLOAT128 tanh(FLOAT128 v) noexcept
- {
- return tanhq(v);
- }
+ static FLOAT128 tanh(FLOAT128 v) noexcept { return tanhq(v); }
- static FLOAT128 floor(FLOAT128 v) noexcept
- {
- return floorq(v);
- }
+ static FLOAT128 floor(FLOAT128 v) noexcept { return floorq(v); }
- static FLOAT128 log1p(FLOAT128 v) noexcept
- {
- return log1pq(v);
- }
+ static FLOAT128 log1p(FLOAT128 v) noexcept { return log1pq(v); }
- static FLOAT128 sin(FLOAT128 v) noexcept
- {
- return sinq(v);
- }
+ static FLOAT128 sin(FLOAT128 v) noexcept { return sinq(v); }
- static FLOAT128 cos(FLOAT128 v) noexcept
- {
- return cosq(v);
- }
+ static FLOAT128 cos(FLOAT128 v) noexcept { return cosq(v); }
- static FLOAT128 trunc(FLOAT128 v) noexcept
- {
- return truncq(v);
- }
+ static FLOAT128 trunc(FLOAT128 v) noexcept { return truncq(v); }
template <typename T>
static FLOAT128 pow(FLOAT128 v, T p) noexcept
@@ -346,8 +316,8 @@ namespace plib
static FLOAT128 pow(FLOAT128 v, int p) noexcept
{
- if (p==2)
- return v*v;
+ if (p == 2)
+ return v * v;
else
return powq(v, static_cast<FLOAT128>(p));
}
@@ -364,7 +334,7 @@ namespace plib
constexpr bool is_pow2(T v) noexcept
{
static_assert(is_integral<T>::value, "is_pow2 needs integer arguments");
- return !(v & (v-1));
+ return !(v & (v - 1));
}
/// \brief return absolute value of signed argument
@@ -373,9 +343,9 @@ namespace plib
/// \param v argument
/// \return absolute value of argument
///
- template<typename T>
- constexpr
- std::enable_if_t<plib::is_integral<T>::value && plib::is_signed<T>::value, T>
+ template <typename T>
+ constexpr std::enable_if_t<
+ plib::is_integral<T>::value && plib::is_signed<T>::value, T>
abs(T v) noexcept
{
return v < 0 ? -v : v;
@@ -387,9 +357,9 @@ namespace plib
/// \param v argument
/// \return argument since it has no sign
///
- template<typename T>
- constexpr
- std::enable_if_t<plib::is_integral<T>::value && plib::is_unsigned<T>::value, T>
+ template <typename T>
+ constexpr std::enable_if_t<
+ plib::is_integral<T>::value && plib::is_unsigned<T>::value, T>
abs(T v) noexcept
{
return v;
@@ -406,16 +376,14 @@ namespace plib
/// \param n first argument
/// \return greatest common denominator of m and n
///
- template<typename M, typename N>
+ template <typename M, typename N>
constexpr typename std::common_type<M, N>::type
- gcd(M m, N n) noexcept //NOLINT(misc-no-recursion)
+ gcd(M m, N n) noexcept // NOLINT(misc-no-recursion)
{
static_assert(plib::is_integral<M>::value, "gcd: M must be an integer");
static_assert(plib::is_integral<N>::value, "gcd: N must be an integer");
- return m == 0 ? plib::abs(n)
- : n == 0 ? plib::abs(m)
- : gcd(n, m % n);
+ return m == 0 ? plib::abs(n) : n == 0 ? plib::abs(m) : gcd(n, m % n);
}
/// \brief return least common multiple
@@ -429,24 +397,25 @@ namespace plib
/// \param n first argument
/// \return least common multiple of m and n
///
- template<typename M, typename N>
- constexpr typename std::common_type<M, N>::type
- lcm(M m, N n) noexcept
+ template <typename M, typename N>
+ constexpr typename std::common_type<M, N>::type lcm(M m, N n) noexcept
{
static_assert(plib::is_integral<M>::value, "lcm: M must be an integer");
static_assert(plib::is_integral<N>::value, "lcm: N must be an integer");
- return (m != 0 && n != 0) ? (plib::abs(m) / gcd(m, n)) * plib::abs(n) : 0;
+ return (m != 0 && n != 0) ? (plib::abs(m) / gcd(m, n)) * plib::abs(n)
+ : 0;
}
- template<class T>
- constexpr const T& clamp( const T& v, const T& low, const T& high)
+ template <class T>
+ constexpr const T &clamp(const T &v, const T &low, const T &high)
{
gsl_Expects(high >= low);
return (v < low) ? low : (high < v) ? high : v;
}
- static_assert(noexcept(constants<double>::one()), "Not evaluated as constexpr");
+ static_assert(noexcept(constants<double>::one()),
+ "Not evaluated as constexpr");
} // namespace plib
diff --git a/src/lib/netlist/solver/nld_matrix_solver.cpp b/src/lib/netlist/solver/nld_matrix_solver.cpp
index a918aac1c58..d382da0f7d5 100644
--- a/src/lib/netlist/solver/nld_matrix_solver.cpp
+++ b/src/lib/netlist/solver/nld_matrix_solver.cpp
@@ -7,35 +7,40 @@
// Specific technical terms
// spell-checker: words vsolver
+#include "nld_matrix_solver.h"
+
+#include "nl_setup.h"
#include "nld_solver.h"
+
#include "core/setup.h"
-#include "nl_setup.h"
-#include "nld_matrix_solver.h"
+
#include "plib/putil.h"
namespace netlist::solver
{
- terms_for_net_t::terms_for_net_t(arena_type &arena, analog_net_t * net)
- : m_nz(arena)
- , m_nzrd(arena)
- , m_nzbd(arena)
- , m_connected_net_idx(arena)
- , m_terms(arena)
- , m_net(net)
- , m_rail_start(0)
+ terms_for_net_t::terms_for_net_t(arena_type &arena, analog_net_t *net)
+ : m_nz(arena)
+ , m_nzrd(arena)
+ , m_nzbd(arena)
+ , m_connected_net_idx(arena)
+ , m_terms(arena)
+ , m_net(net)
+ , m_rail_start(0)
{
}
- void terms_for_net_t::add_terminal(terminal_t *term, int net_other, bool sorted)
+ void
+ terms_for_net_t::add_terminal(terminal_t *term, int net_other, bool sorted)
{
if (sorted)
- for (std::size_t i=0; i < m_connected_net_idx.size(); i++)
+ for (std::size_t i = 0; i < m_connected_net_idx.size(); i++)
{
if (m_connected_net_idx[i] > net_other)
{
plib::container::insert_at(m_terms, i, term);
- plib::container::insert_at(m_connected_net_idx, i, net_other);
+ plib::container::insert_at(m_connected_net_idx, i,
+ net_other);
return;
}
}
@@ -47,34 +52,36 @@ namespace netlist::solver
// matrix_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(device_data_t{main_solver.state(), main_solver.name() + "." + name})
- , m_params(*params)
- , m_gonn(m_arena)
- , m_gtn(m_arena)
- , m_Idrn(m_arena)
- , m_connected_net_Vn(m_arena)
- , m_iterative_fail(*this, "m_iterative_fail", 0)
- , m_iterative_total(*this, "m_iterative_total", 0)
- , m_main_solver(main_solver)
- , m_stat_calculations(*this, "m_stat_calculations", 0)
- , m_stat_newton_raphson(*this, "m_stat_newton_raphson", 0)
- , m_stat_newton_raphson_fail(*this, "m_stat_newton_raphson_fail", 0)
- , m_stat_vsolver_calls(*this, "m_stat_vsolver_calls", 0)
- , m_last_step(*this, "m_last_step", netlist_time_ext::zero())
- , m_step_funcs(m_arena)
- , m_dynamic_funcs(m_arena)
- , m_inputs(m_arena)
- , m_ops(0)
+ 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(
+ device_data_t{main_solver.state(), main_solver.name() + "." + name})
+ , m_params(*params)
+ , m_gonn(m_arena)
+ , m_gtn(m_arena)
+ , m_Idrn(m_arena)
+ , m_connected_net_Vn(m_arena)
+ , m_iterative_fail(*this, "m_iterative_fail", 0)
+ , m_iterative_total(*this, "m_iterative_total", 0)
+ , m_main_solver(main_solver)
+ , m_stat_calculations(*this, "m_stat_calculations", 0)
+ , m_stat_newton_raphson(*this, "m_stat_newton_raphson", 0)
+ , m_stat_newton_raphson_fail(*this, "m_stat_newton_raphson_fail", 0)
+ , m_stat_vsolver_calls(*this, "m_stat_vsolver_calls", 0)
+ , m_last_step(*this, "m_last_step", netlist_time_ext::zero())
+ , m_step_funcs(m_arena)
+ , m_dynamic_funcs(m_arena)
+ , m_inputs(m_arena)
+ , m_ops(0)
{
setup_base(this->state().setup(), nets);
// now setup the matrix
setup_matrix();
- //printf("Freq: %f\n", m_params.m_freq());
+ // printf("Freq: %f\n", m_params.m_freq());
}
analog_net_t *matrix_solver_t::get_connected_net(terminal_t *term)
@@ -87,7 +94,8 @@ namespace netlist::solver
m_main_solver.reschedule(this, ts);
}
- void matrix_solver_t::setup_base([[maybe_unused]] setup_t &setup, const net_list_t &nets)
+ void matrix_solver_t::setup_base([[maybe_unused]] setup_t &setup,
+ const net_list_t &nets)
{
log().debug("New solver setup\n");
std::vector<core_device_t *> step_devices;
@@ -95,7 +103,7 @@ namespace netlist::solver
m_terms.clear();
- for (const auto & net : nets)
+ for (const auto &net : nets)
{
m_terms.emplace_back(m_arena, net);
m_rails_temp.emplace_back(m_arena);
@@ -108,68 +116,87 @@ namespace netlist::solver
analog_net_t &net = *nets[k];
// FIXME: add size() to list
- // log().debug("adding net with {1} populated connections\n", net.core_terms().size());
+ // log().debug("adding net with {1} populated connections\n",
+ // net.core_terms().size());
net.set_solver(this);
- for (detail::core_terminal_t * p : net.core_terms_copy())
+ for (detail::core_terminal_t *p : net.core_terms_copy())
{
nl_assert_always(&p->net() == &net, "Net integrity violated");
- log().debug("{1} {2} {3}\n", p->name(), net.name(), net.is_rail_net());
+ log().debug("{1} {2} {3}\n", p->name(), net.name(),
+ net.is_rail_net());
switch (p->type())
{
case detail::terminal_type::TERMINAL:
if (p->device().is_time_step())
- if (!plib::container::contains(step_devices, &p->device()))
+ if (!plib::container::contains(step_devices,
+ &p->device()))
step_devices.push_back(&p->device());
if (p->device().is_dynamic())
- if (!plib::container::contains(dynamic_devices, &p->device()))
+ if (!plib::container::contains(dynamic_devices,
+ &p->device()))
dynamic_devices.push_back(&p->device());
{
- auto pterm = plib::dynamic_downcast<terminal_t *>(p);
- nl_assert_always(bool(pterm), "cast to terminal_t * failed");
+ 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;
case detail::terminal_type::INPUT:
- {
- proxied_analog_output_t *net_proxy_output = nullptr;
- for (auto & input : m_inputs)
- if (input->proxied_net() == &p->net())
- {
- net_proxy_output = input.get();
- break;
- }
-
- if (net_proxy_output == nullptr)
+ {
+ proxied_analog_output_t *net_proxy_output = nullptr;
+ for (auto &input : m_inputs)
+ if (input->proxied_net() == &p->net())
{
- pstring new_name(this->name() + "." + pstring(plib::pfmt("m{1}")(m_inputs.size())));
- 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));
+ net_proxy_output = input.get();
+ break;
}
- net.remove_terminal(*p);
- net_proxy_output->net().add_terminal(*p);
- // FIXME: repeated calling - kind of brute force
- net_proxy_output->net().rebuild_list();
- log().debug("Added input {1}", net_proxy_output->name());
+
+ if (net_proxy_output == nullptr)
+ {
+ pstring new_name(
+ this->name() + "."
+ + pstring(plib::pfmt("m{1}")(m_inputs.size())));
+ 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));
}
- break;
+ net.remove_terminal(*p);
+ net_proxy_output->net().add_terminal(*p);
+ // FIXME: repeated calling - kind of brute force
+ net_proxy_output->net().rebuild_list();
+ log().debug("Added input {1}",
+ net_proxy_output->name());
+ }
+ break;
case detail::terminal_type::OUTPUT:
log().fatal(MF_UNHANDLED_ELEMENT_1_FOUND(p->name()));
- throw nl_exception(MF_UNHANDLED_ELEMENT_1_FOUND(p->name()));
+ throw nl_exception(
+ MF_UNHANDLED_ELEMENT_1_FOUND(p->name()));
}
}
net.rebuild_list();
}
for (auto &d : step_devices)
- m_step_funcs.emplace_back(nl_delegate_ts(&core_device_t::time_step, d));
+ m_step_funcs.emplace_back(
+ nl_delegate_ts(&core_device_t::time_step, d));
for (auto &d : dynamic_devices)
- m_dynamic_funcs.emplace_back(nl_delegate_dyn(&core_device_t::update_terminals, d));
+ m_dynamic_funcs.emplace_back(
+ nl_delegate_dyn(&core_device_t::update_terminals, d));
}
/// \brief Sort terminals
@@ -192,7 +219,8 @@ namespace netlist::solver
/// literature but I have found no articles about Gauss Seidel.
///
/// For Gaussian Elimination however increasing order is better suited.
- /// NOTE: Even better would be to sort on elements right of the matrix diagonal.
+ /// NOTE: Even better would be to sort on elements right of the matrix
+ /// diagonal.
/// FIXME: This entry needs an update.
///
void matrix_solver_t::sort_terms(matrix_sort_type_e sort)
@@ -202,65 +230,69 @@ namespace netlist::solver
switch (sort)
{
case matrix_sort_type_e::PREFER_BAND_MATRIX:
+ {
+ for (std::size_t k = 0; k < iN - 1; k++)
{
- for (std::size_t k = 0; k < iN - 1; k++)
+ auto pk = get_weight_around_diagonal(k, k);
+ for (std::size_t i = k + 1; i < iN; i++)
{
- auto pk = get_weight_around_diagonal(k,k);
- for (std::size_t i = k+1; i < iN; i++)
+ auto pi = get_weight_around_diagonal(i, k);
+ if (pi < pk)
{
- auto pi = get_weight_around_diagonal(i,k);
- if (pi < pk)
- {
- std::swap(m_terms[i], m_terms[k]);
- pk = get_weight_around_diagonal(k,k);
- }
+ std::swap(m_terms[i], m_terms[k]);
+ pk = get_weight_around_diagonal(k, k);
}
}
}
- break;
+ }
+ break;
case matrix_sort_type_e::PREFER_IDENTITY_TOP_LEFT:
+ {
+ for (std::size_t k = 0; k < iN - 1; k++)
{
- for (std::size_t k = 0; k < iN - 1; k++)
+ auto pk = get_left_right_of_diagonal(k, k);
+ for (std::size_t i = k + 1; i < iN; i++)
{
- auto pk = get_left_right_of_diagonal(k,k);
- for (std::size_t i = k+1; i < iN; i++)
+ auto pi = get_left_right_of_diagonal(i, k);
+ if (pi.first <= pk.first && pi.second >= pk.second)
{
- auto pi = get_left_right_of_diagonal(i,k);
- if (pi.first <= pk.first && pi.second >= pk.second)
- {
- std::swap(m_terms[i], m_terms[k]);
- pk = get_left_right_of_diagonal(k,k);
- }
+ std::swap(m_terms[i], m_terms[k]);
+ pk = get_left_right_of_diagonal(k, k);
}
}
}
- break;
+ }
+ break;
case matrix_sort_type_e::ASCENDING:
case matrix_sort_type_e::DESCENDING:
- {
- int sort_order = (sort == matrix_sort_type_e::DESCENDING ? 1 : -1);
+ {
+ int sort_order = (sort == matrix_sort_type_e::DESCENDING ? 1
+ : -1);
- for (std::size_t k = 0; k < iN - 1; k++)
- for (std::size_t i = k+1; i < iN; i++)
+ for (std::size_t k = 0; k < iN - 1; k++)
+ for (std::size_t i = k + 1; i < iN; i++)
+ {
+ if ((static_cast<int>(m_terms[k].rail_start())
+ - static_cast<int>(m_terms[i].rail_start()))
+ * sort_order
+ < 0)
{
- if ((static_cast<int>(m_terms[k].rail_start()) - static_cast<int>(m_terms[i].rail_start())) * sort_order < 0)
- {
- std::swap(m_terms[i], m_terms[k]);
- }
+ std::swap(m_terms[i], m_terms[k]);
}
- }
- break;
- case matrix_sort_type_e::NOSORT:
- break;
+ }
+ }
+ break;
+ case matrix_sort_type_e::NOSORT: break;
}
// rebuild
for (auto &term : m_terms)
{
- //int *other = term.m_connected_net_idx.data();
+ // int *other = term.m_connected_net_idx.data();
for (std::size_t i = 0; i < term.count(); i++)
- //FIXME: this is weird
+ // FIXME: this is weird
if (term.m_connected_net_idx[i] != -1)
- term.m_connected_net_idx[i] = get_net_idx(get_connected_net(term.terms()[i]));
+ term.m_connected_net_idx[i] = get_net_idx(
+ get_connected_net(term.terms()[i]));
}
}
@@ -272,7 +304,9 @@ namespace netlist::solver
{
m_terms[k].set_rail_start(m_terms[k].count());
for (std::size_t i = 0; i < m_rails_temp[k].count(); i++)
- this->m_terms[k].add_terminal(m_rails_temp[k].terms()[i], m_rails_temp[k].m_connected_net_idx.data()[i], false);
+ this->m_terms[k].add_terminal(
+ m_rails_temp[k].terms()[i],
+ m_rails_temp[k].m_connected_net_idx.data()[i], false);
}
// free all - no longer needed
@@ -285,17 +319,18 @@ namespace netlist::solver
// create a list of non zero elements.
for (unsigned k = 0; k < iN; k++)
{
- terms_for_net_t & t = m_terms[k];
+ terms_for_net_t &t = m_terms[k];
// pretty brutal
int *other = t.m_connected_net_idx.data();
t.m_nz.clear();
for (std::size_t i = 0; i < t.rail_start(); i++)
- if (!plib::container::contains(t.m_nz, static_cast<unsigned>(other[i])))
+ if (!plib::container::contains(t.m_nz,
+ static_cast<unsigned>(other[i])))
t.m_nz.push_back(static_cast<unsigned>(other[i]));
- t.m_nz.push_back(k); // add diagonal
+ t.m_nz.push_back(k); // add diagonal
// and sort
std::sort(t.m_nz.begin(), t.m_nz.end());
@@ -307,16 +342,16 @@ namespace netlist::solver
for (std::size_t k = 0; k < iN; k++)
{
- terms_for_net_t & t = m_terms[k];
+ terms_for_net_t &t = m_terms[k];
// pretty brutal
int *other = t.m_connected_net_idx.data();
- if (k==0)
+ if (k == 0)
t.m_nzrd.clear();
else
{
- t.m_nzrd = m_terms[k-1].m_nzrd;
- for (auto j = t.m_nzrd.begin(); j != t.m_nzrd.end(); )
+ t.m_nzrd = m_terms[k - 1].m_nzrd;
+ for (auto j = t.m_nzrd.begin(); j != t.m_nzrd.end();)
{
if (*j < k + 1)
j = t.m_nzrd.erase(j);
@@ -326,7 +361,9 @@ namespace netlist::solver
}
for (std::size_t i = 0; i < t.rail_start(); i++)
- if (!plib::container::contains(t.m_nzrd, static_cast<unsigned>(other[i])) && other[i] >= static_cast<int>(k + 1))
+ if (!plib::container::contains(t.m_nzrd,
+ static_cast<unsigned>(other[i]))
+ && other[i] >= static_cast<int>(k + 1))
t.m_nzrd.push_back(static_cast<unsigned>(other[i]));
// and sort
@@ -366,7 +403,8 @@ namespace netlist::solver
}
}
}
- log().verbose("Number of multiplications/additions for {1}: {2}", name(), m_ops);
+ 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)
@@ -374,7 +412,7 @@ namespace netlist::solver
for (std::size_t k = 0; k < iN; k++)
{
pstring line = plib::pfmt("{1:3}")(k);
- for (const auto & nzrd : m_terms[k].m_nzrd)
+ for (const auto &nzrd : m_terms[k].m_nzrd)
line += plib::pfmt(" {1:3}")(nzrd);
log().verbose("{1}", line);
}
@@ -387,9 +425,12 @@ namespace netlist::solver
{
pstring num = plib::pfmt("{1}")(k);
- state().save(*this, m_gonn[k],"GO" + num, this->name(), m_terms[k].count());
- state().save(*this, m_gtn[k],"GT" + num, this->name(), m_terms[k].count());
- state().save(*this, m_Idrn[k],"IDR" + num, this->name(), m_terms[k].count());
+ state().save(*this, m_gonn[k], "GO" + num, this->name(),
+ m_terms[k].count());
+ state().save(*this, m_gtn[k], "GT" + num, this->name(),
+ m_terms[k].count());
+ state().save(*this, m_Idrn[k], "IDR" + num, this->name(),
+ m_terms[k].count());
}
}
@@ -414,20 +455,22 @@ namespace netlist::solver
for (std::size_t k = 0; k < iN; k++)
for (std::size_t j = 0; j < m_terms[k].count(); j++)
{
- m_gtn.set(k,j, nlconst::zero());
- m_gonn.set(k,j, nlconst::zero());
- m_Idrn.set(k,j, nlconst::zero());
+ m_gtn.set(k, j, nlconst::zero());
+ m_gonn.set(k, j, nlconst::zero());
+ m_Idrn.set(k, j, nlconst::zero());
m_connected_net_Vn.set(k, j, nullptr);
}
-
for (std::size_t k = 0; k < iN; k++)
{
auto count = m_terms[k].count();
for (std::size_t i = 0; i < count; i++)
{
- m_terms[k].terms()[i]->set_ptrs(&m_gtn[k][i], &m_gonn[k][i], &m_Idrn[k][i]);
- m_connected_net_Vn[k][i] = get_connected_net(m_terms[k].terms()[i])->Q_Analog_state_ptr();
+ m_terms[k].terms()[i]->set_ptrs(&m_gtn[k][i], &m_gonn[k][i],
+ &m_Idrn[k][i]);
+ m_connected_net_Vn[k][i] = get_connected_net(
+ m_terms[k].terms()[i])
+ ->Q_Analog_state_ptr();
}
}
}
@@ -448,10 +491,11 @@ namespace netlist::solver
void matrix_solver_t::reset()
{
- //m_last_step = netlist_time_ext::zero();
+ // m_last_step = netlist_time_ext::zero();
}
- void matrix_solver_t::step(time_step_type ts_type, netlist_time delta) noexcept
+ void matrix_solver_t::step(detail::time_step_type ts_type,
+ netlist_time delta) noexcept
{
const auto dd(delta.as_fp<fptype>());
for (auto &d : m_step_funcs)
@@ -460,12 +504,13 @@ namespace netlist::solver
bool matrix_solver_t::solve_nr_base()
{
- bool this_resched(false);
+ bool this_resched(false);
std::size_t newton_loops = 0;
do
{
update_dynamic();
- // Gauss-Seidel will revert to Gaussian elimination if steps exceeded.
+ // Gauss-Seidel will revert to Gaussian elimination if steps
+ // exceeded.
this->m_stat_calculations++;
this->upstream_solve_non_dynamic();
this_resched = this->check_err();
@@ -482,18 +527,21 @@ namespace netlist::solver
netlist_time matrix_solver_t::newton_loops_exceeded(netlist_time delta)
{
netlist_time next_time_step;
- bool resched(false);
+ bool resched(false);
restore();
- step(time_step_type::RESTORE, delta);
+ step(detail::time_step_type::RESTORE, delta);
- for (std::size_t i=0; i< 10; i++)
+ for (std::size_t i = 0; i < 10; i++)
{
backup();
- step(time_step_type::FORWARD, netlist_time::from_fp(m_params.m_min_ts_ts()));
+ step(detail::time_step_type::FORWARD,
+ netlist_time::from_fp(m_params.m_min_ts_ts()));
resched = solve_nr_base();
// update time step calculation
- next_time_step = compute_next_time_step(m_params.m_min_ts_ts(), m_params.m_min_ts_ts(), m_params.m_max_time_step);
+ next_time_step = compute_next_time_step(m_params.m_min_ts_ts(),
+ m_params.m_min_ts_ts(),
+ m_params.m_max_time_step);
delta -= netlist_time::from_fp(m_params.m_min_ts_ts());
}
// try remaining time using compute_next_time step
@@ -502,19 +550,23 @@ namespace netlist::solver
if (next_time_step > delta)
next_time_step = delta;
backup();
- step(time_step_type::FORWARD, next_time_step);
+ step(detail::time_step_type::FORWARD, next_time_step);
delta -= next_time_step;
resched = solve_nr_base();
- next_time_step = compute_next_time_step(next_time_step.as_fp<nl_fptype>(), m_params.m_min_ts_ts(), m_params.m_max_time_step);
+ next_time_step = compute_next_time_step(
+ next_time_step.as_fp<nl_fptype>(), m_params.m_min_ts_ts(),
+ m_params.m_max_time_step);
}
if (m_stat_newton_raphson % 100 == 0)
- log().warning(MW_NEWTON_LOOPS_EXCEEDED_INVOCATION_3(100, this->name(), exec().time().as_double() * 1e6));
+ log().warning(MW_NEWTON_LOOPS_EXCEEDED_INVOCATION_3(
+ 100, this->name(), exec().time().as_double() * 1e6));
if (resched)
{
// reschedule ....
- log().warning(MW_NEWTON_LOOPS_EXCEEDED_ON_NET_2(this->name(), exec().time().as_double() * 1e6));
+ log().warning(MW_NEWTON_LOOPS_EXCEEDED_ON_NET_2(
+ this->name(), exec().time().as_double() * 1e6));
return netlist_time::from_fp(m_params.m_nr_recalc_delay());
}
if (m_params.m_dynamic_ts)
@@ -523,7 +575,8 @@ namespace netlist::solver
return netlist_time::from_fp(m_params.m_max_time_step);
}
- netlist_time matrix_solver_t::solve(netlist_time_ext now, [[maybe_unused]] const char *source)
+ netlist_time matrix_solver_t::solve(netlist_time_ext now,
+ [[maybe_unused]] const char *source)
{
auto delta = static_cast<netlist_time>(now - m_last_step());
PFDEBUG(printf("solve %.10f\n", delta.as_double());)
@@ -532,8 +585,10 @@ namespace netlist::solver
// FIXME: Make this a parameter!
if (delta < netlist_time::quantum())
{
- //printf("solve return %s at %f\n", source, now.as_double());
- return time_step_device_count() > 0 ? netlist_time::from_fp(m_params.m_min_time_step) : netlist_time::zero();
+ // printf("solve return %s at %f\n", source, now.as_double());
+ return time_step_device_count() > 0
+ ? netlist_time::from_fp(m_params.m_min_time_step)
+ : netlist_time::zero();
}
backup(); // save voltages for backup and time step calculation
@@ -543,7 +598,7 @@ namespace netlist::solver
++m_stat_vsolver_calls;
if (dynamic_device_count() != 0)
{
- step(time_step_type::FORWARD, delta);
+ step(detail::time_step_type::FORWARD, delta);
const auto resched = solve_nr_base();
if (resched)
@@ -551,7 +606,7 @@ namespace netlist::solver
}
else
{
- step(time_step_type::FORWARD, delta);
+ step(detail::time_step_type::FORWARD, delta);
this->m_stat_calculations++;
this->upstream_solve_non_dynamic();
this->store();
@@ -560,14 +615,15 @@ namespace netlist::solver
if (m_params.m_dynamic_ts)
{
if (time_step_device_count() > 0)
- return compute_next_time_step(delta.as_fp<nl_fptype>(), m_params.m_min_time_step, m_params.m_max_time_step);
+ return compute_next_time_step(delta.as_fp<nl_fptype>(),
+ m_params.m_min_time_step,
+ m_params.m_max_time_step);
}
if (time_step_device_count() > 0)
return netlist_time::from_fp(m_params.m_max_time_step);
return netlist_time::zero();
-
}
int matrix_solver_t::get_net_idx(const analog_net_t *net) const noexcept
@@ -578,11 +634,14 @@ namespace netlist::solver
return -1;
}
- std::pair<int, int> matrix_solver_t::get_left_right_of_diagonal(std::size_t irow, std::size_t idiag)
+ std::pair<int, int>
+ matrix_solver_t::get_left_right_of_diagonal(std::size_t irow,
+ std::size_t idiag)
{
//
// return the maximum column left of the diagonal (-1 if no cols found)
- // return the minimum column right of the diagonal (999999 if no cols found)
+ // return the minimum column right of the diagonal (999999 if no cols
+ // found)
//
const auto row = static_cast<int>(irow);
@@ -598,8 +657,10 @@ namespace netlist::solver
auto col = get_net_idx(get_connected_net(term.terms()[i]));
if (col != -1)
{
- if (col==row) col = diag;
- else if (col==diag) col = row;
+ if (col == row)
+ col = diag;
+ else if (col == diag)
+ col = row;
if (col > diag && col < colmin)
colmin = col;
@@ -610,7 +671,9 @@ namespace netlist::solver
return {colmax, colmin};
}
- matrix_solver_t::fptype matrix_solver_t::get_weight_around_diagonal(std::size_t row, std::size_t diag)
+ matrix_solver_t::fptype
+ matrix_solver_t::get_weight_around_diagonal(std::size_t row,
+ std::size_t diag)
{
{
//
@@ -620,7 +683,7 @@ namespace netlist::solver
std::vector<bool> touched(1024, false); // FIXME!
fptype weight = nlconst::zero();
- auto &term = m_terms[row];
+ auto &term = m_terms[row];
for (std::size_t i = 0; i < term.count(); i++)
{
auto col = get_net_idx(get_connected_net(term.terms()[i]));
@@ -629,10 +692,14 @@ namespace netlist::solver
auto colu = static_cast<std::size_t>(col);
if (!touched[colu])
{
- if (colu==row) colu = static_cast<unsigned>(diag);
- else if (colu==diag) colu = static_cast<unsigned>(row);
-
- weight = weight + plib::abs(static_cast<fptype>(colu) - static_cast<fptype>(diag));
+ if (colu == row)
+ colu = static_cast<unsigned>(diag);
+ else if (colu == diag)
+ colu = static_cast<unsigned>(row);
+
+ weight = weight
+ + plib::abs(static_cast<fptype>(colu)
+ - static_cast<fptype>(diag));
touched[colu] = true;
}
}
@@ -650,38 +717,46 @@ namespace netlist::solver
else
{
int ot = get_net_idx(get_connected_net(term));
- if (ot>=0)
+ if (ot >= 0)
{
m_terms[net_idx].add_terminal(term, ot, true);
}
else
{
log().fatal(MF_FOUND_TERM_WITH_MISSING_OTHERNET(term->name()));
- throw nl_exception(MF_FOUND_TERM_WITH_MISSING_OTHERNET(term->name()));
+ throw nl_exception(
+ MF_FOUND_TERM_WITH_MISSING_OTHERNET(term->name()));
}
}
}
void matrix_solver_t::log_stats()
{
- if (this->m_stat_calculations != 0 && this->m_stat_vsolver_calls && log().verbose.is_enabled())
+ if (this->m_stat_calculations != 0 && this->m_stat_vsolver_calls
+ && log().verbose.is_enabled())
{
log().verbose("==============================================");
log().verbose("Solver {1}", this->name());
log().verbose(" ==> {1} nets", this->m_terms.size());
- log().verbose(" has {1} dynamic elements", this->dynamic_device_count());
- log().verbose(" has {1} time step elements", this->time_step_device_count());
- log().verbose(" {1:6.3} average newton raphson loops",
- static_cast<fptype>(this->m_stat_newton_raphson) / static_cast<fptype>(this->m_stat_vsolver_calls));
- log().verbose(" {1:10} invocations ({2:6.0} Hz) {3:10} gs fails ({4:6.2} %) {5:6.3} average",
- this->m_stat_calculations,
- static_cast<fptype>(this->m_stat_calculations) / this->exec().time().as_fp<fptype>(),
- this->m_iterative_fail,
- nlconst::hundred() * static_cast<fptype>(this->m_iterative_fail)
- / static_cast<fptype>(this->m_stat_calculations),
- static_cast<fptype>(this->m_iterative_total) / static_cast<fptype>(this->m_stat_calculations));
+ log().verbose(" has {1} dynamic elements",
+ this->dynamic_device_count());
+ log().verbose(" has {1} time step elements",
+ this->time_step_device_count());
+ log().verbose(
+ " {1:6.3} average newton raphson loops",
+ static_cast<fptype>(this->m_stat_newton_raphson)
+ / static_cast<fptype>(this->m_stat_vsolver_calls));
+ log().verbose(
+ " {1:10} invocations ({2:6.0} Hz) {3:10} gs fails ({4:6.2} %) {5:6.3} average",
+ this->m_stat_calculations,
+ static_cast<fptype>(this->m_stat_calculations)
+ / this->exec().time().as_fp<fptype>(),
+ this->m_iterative_fail,
+ nlconst::hundred() * static_cast<fptype>(this->m_iterative_fail)
+ / static_cast<fptype>(this->m_stat_calculations),
+ static_cast<fptype>(this->m_iterative_total)
+ / static_cast<fptype>(this->m_stat_calculations));
}
}
} // namespace netlist::solver
-
diff --git a/src/lib/netlist/solver/nld_matrix_solver.h b/src/lib/netlist/solver/nld_matrix_solver.h
index 21725ab3100..c0b792fd597 100644
--- a/src/lib/netlist/solver/nld_matrix_solver.h
+++ b/src/lib/netlist/solver/nld_matrix_solver.h
@@ -11,14 +11,14 @@
/// \file nld_matrix_solver.h
///
+#include "nl_errstr.h"
+#include "nltypes.h"
#include "../core/analog.h"
#include "../core/device.h"
#include "../core/device_macros.h"
#include "../core/param.h"
-#include "nl_errstr.h"
-#include "nltypes.h"
#include "plib/palloc.h"
#include "plib/penum.h"
#include "plib/pmatrix2d.h"
@@ -29,7 +29,7 @@
#include <numeric>
-//FIXME: remove again
+// FIXME: remove again
#define PFDEBUG(x)
@@ -42,6 +42,8 @@ namespace netlist::solver
CXX_STATIC
};
+ // clang-format off
+
PENUM(matrix_sort_type_e,
NOSORT,
ASCENDING,
@@ -67,40 +69,63 @@ namespace netlist::solver
, FLOATQ128
)
+ // clang-format on
+
using arena_type = plib::mempool_arena<plib::aligned_arena<>, 1024>;
using static_compile_container = std::vector<std::pair<pstring, pstring>>;
struct solver_parameter_defaults
{
- static constexpr nl_fptype m_freq() { return nlconst::magic(48000.0); }
+ static constexpr nl_fptype m_freq() { return nlconst::magic(48000.0); }
// iteration parameters
- static constexpr nl_fptype m_gs_sor() { return nlconst::magic(1.059); }
- static constexpr matrix_type_e m_method() { return matrix_type_e::MAT_CR; }
- static constexpr matrix_fp_type_e m_fp_type() { return matrix_fp_type_e::DOUBLE; }
- static constexpr nl_fptype m_reltol() { return nlconst::magic(1e-3); }
- static constexpr nl_fptype m_vntol() { return nlconst::magic(1e-7); }
- static constexpr nl_fptype m_accuracy() { return nlconst::magic(1e-7); }
- static constexpr std::size_t m_nr_loops() { return 250; }
- static constexpr std::size_t m_gs_loops() { return 50; }
+ static constexpr nl_fptype m_gs_sor() { return nlconst::magic(1.059); }
+ static constexpr matrix_type_e m_method()
+ {
+ return matrix_type_e::MAT_CR;
+ }
+ static constexpr matrix_fp_type_e m_fp_type()
+ {
+ return matrix_fp_type_e::DOUBLE;
+ }
+ static constexpr nl_fptype m_reltol() { return nlconst::magic(1e-3); }
+ static constexpr nl_fptype m_vntol() { return nlconst::magic(1e-7); }
+ static constexpr nl_fptype m_accuracy() { return nlconst::magic(1e-7); }
+ static constexpr std::size_t m_nr_loops() { return 250; }
+ static constexpr std::size_t m_gs_loops() { return 50; }
// general parameters
- static constexpr nl_fptype m_gmin() { return nlconst::magic(1e-9); }
- static constexpr bool m_pivot() { return false; }
- static constexpr nl_fptype m_nr_recalc_delay(){ return netlist_time::quantum().as_fp<nl_fptype>(); }
- static constexpr int m_parallel() { return 0; }
+ static constexpr nl_fptype m_gmin() { return nlconst::magic(1e-9); }
+ static constexpr bool m_pivot() { return false; }
+ static constexpr nl_fptype m_nr_recalc_delay()
+ {
+ return netlist_time::quantum().as_fp<nl_fptype>();
+ }
+ static constexpr int m_parallel() { return 0; }
- static constexpr nl_fptype m_min_ts_ts() { return nlconst::magic(1e-9); }
+ static constexpr nl_fptype m_min_ts_ts()
+ {
+ return nlconst::magic(1e-9);
+ }
// automatic time step
- static constexpr bool m_dynamic_ts() { return false; }
- static constexpr nl_fptype m_dynamic_lte() { return nlconst::magic(1e-5); }
- static constexpr nl_fptype m_dynamic_min_ts() { return nlconst::magic(1e-6); }
+ static constexpr bool m_dynamic_ts() { return false; }
+ static constexpr nl_fptype m_dynamic_lte()
+ {
+ return nlconst::magic(1e-5);
+ }
+ static constexpr nl_fptype m_dynamic_min_ts()
+ {
+ return nlconst::magic(1e-6);
+ }
// matrix sorting
- static constexpr matrix_sort_type_e m_sort_type() { return matrix_sort_type_e::PREFER_IDENTITY_TOP_LEFT; }
+ static constexpr matrix_sort_type_e m_sort_type()
+ {
+ return matrix_sort_type_e::PREFER_IDENTITY_TOP_LEFT;
+ }
// special
- static constexpr bool m_use_gabs() { return true; }
+ static constexpr bool m_use_gabs() { return true; }
static solver_parameter_defaults &get_instance()
{
@@ -112,30 +137,52 @@ namespace netlist::solver
struct solver_parameters_t
{
template <typename D>
- solver_parameters_t(device_t &parent, const pstring &prefix, D &defaults)
+ solver_parameters_t(device_t &parent, const pstring &prefix,
+ D &defaults)
: m_freq(parent, prefix + "FREQ", defaults.m_freq())
// iteration parameters
- , m_gs_sor(parent, prefix + "SOR_FACTOR", defaults.m_gs_sor())
- , m_method(parent, prefix + "METHOD", defaults.m_method())
- , m_fp_type(parent, prefix + "FPTYPE", defaults.m_fp_type())
- , m_reltol(parent, prefix + "RELTOL", defaults.m_reltol()) //!< SPICE RELTOL parameter
- , m_vntol(parent, prefix + "VNTOL", defaults.m_vntol()) //!< SPICE VNTOL parameter
- , m_accuracy(parent, prefix + "ACCURACY", defaults.m_accuracy()) //!< Iterative solver accuracy
- , m_nr_loops(parent, prefix + "NR_LOOPS", defaults.m_nr_loops()) //!< Maximum number of Newton-Raphson loops
- , m_gs_loops(parent, prefix + "GS_LOOPS", defaults.m_gs_loops()) //!< Maximum number of Gauss-Seidel loops
+ , m_gs_sor(parent, prefix + "SOR_FACTOR", defaults.m_gs_sor())
+ , m_method(parent, prefix + "METHOD", defaults.m_method())
+ , m_fp_type(parent, prefix + "FPTYPE", defaults.m_fp_type())
+ , m_reltol(parent, prefix + "RELTOL",
+ defaults.m_reltol()) //!< SPICE RELTOL parameter
+ , m_vntol(parent, prefix + "VNTOL", defaults.m_vntol()) //!< SPICE VNTOL
+ //!< parameter
+ , m_accuracy(parent, prefix + "ACCURACY",
+ defaults.m_accuracy()) //!< Iterative solver accuracy
+ , m_nr_loops(parent, prefix + "NR_LOOPS",
+ defaults.m_nr_loops()) //!< Maximum number of
+ //!< Newton-Raphson loops
+ , m_gs_loops(parent, prefix + "GS_LOOPS",
+ defaults.m_gs_loops()) //!< Maximum number of Gauss-Seidel
+ //!< loops
// general parameters
, m_gmin(parent, prefix + "GMIN", defaults.m_gmin())
- , m_pivot(parent, prefix + "PIVOT", defaults.m_pivot()) //!< use pivoting on supported solvers
- , m_nr_recalc_delay(parent, prefix + "NR_RECALC_DELAY", defaults.m_nr_recalc_delay()) //!< Delay to next solve attempt if nr loops exceeded
+ , m_pivot(parent, prefix + "PIVOT", defaults.m_pivot()) //!< use
+ //!< pivoting on
+ //!< supported
+ //!< solvers
+ , m_nr_recalc_delay(parent, prefix + "NR_RECALC_DELAY",
+ defaults.m_nr_recalc_delay()) //!< Delay to next
+ //!< solve attempt if
+ //!< nr loops exceeded
, m_parallel(parent, prefix + "PARALLEL", defaults.m_parallel())
- , m_min_ts_ts(parent, prefix + "MIN_TS_TS", defaults.m_min_ts_ts()) //!< The minimum time step for solvers with time stepping devices.
+ , m_min_ts_ts(parent, prefix + "MIN_TS_TS",
+ defaults.m_min_ts_ts()) //!< The minimum time step for
+ //!< solvers with time stepping
+ //!< devices.
// automatic time step
- , m_dynamic_ts(parent, prefix + "DYNAMIC_TS", defaults.m_dynamic_ts()) //!< Use dynamic time stepping
- , m_dynamic_lte(parent, prefix + "DYNAMIC_LTE", defaults.m_dynamic_lte()) //!< dynamic time stepping slope
- , m_dynamic_min_ts(parent, prefix + "DYNAMIC_MIN_TIMESTEP", defaults.m_dynamic_min_ts()) //!< smallest time step allowed
+ , m_dynamic_ts(parent, prefix + "DYNAMIC_TS",
+ defaults.m_dynamic_ts()) //!< Use dynamic time stepping
+ , m_dynamic_lte(parent, prefix + "DYNAMIC_LTE",
+ defaults.m_dynamic_lte()) //!< dynamic time stepping
+ //!< slope
+ , m_dynamic_min_ts(parent, prefix + "DYNAMIC_MIN_TIMESTEP",
+ defaults.m_dynamic_min_ts()) //!< smallest time step
+ //!< allowed
// matrix sorting
, m_sort_type(parent, prefix + "SORT_TYPE", defaults.m_sort_type())
@@ -144,11 +191,12 @@ namespace netlist::solver
, m_use_gabs(parent, prefix + "USE_GABS", defaults.m_use_gabs())
, m_min_time_step(m_dynamic_min_ts())
{
- m_max_time_step = netlist_time::from_fp(plib::reciprocal(m_freq())).as_fp<decltype(m_max_time_step)>();
+ m_max_time_step = netlist_time::from_fp(plib::reciprocal(m_freq()))
+ .as_fp<decltype(m_max_time_step)>();
if (m_dynamic_ts)
{
- m_max_time_step *= 1;//NL_FCONST(1000.0);
+ m_max_time_step *= 1; // NL_FCONST(1000.0);
}
else
{
@@ -156,23 +204,23 @@ namespace netlist::solver
}
}
- param_fp_t m_freq;
- param_fp_t m_gs_sor;
- param_enum_t<matrix_type_e> m_method;
- param_enum_t<matrix_fp_type_e> m_fp_type;
- param_fp_t m_reltol;
- param_fp_t m_vntol;
- param_fp_t m_accuracy;
- param_num_t<std::size_t> m_nr_loops;
- param_num_t<std::size_t> m_gs_loops;
- param_fp_t m_gmin;
- param_logic_t m_pivot;
- param_fp_t m_nr_recalc_delay;
- param_int_t m_parallel;
- param_fp_t m_min_ts_ts;
- param_logic_t m_dynamic_ts;
- param_fp_t m_dynamic_lte;
- param_fp_t m_dynamic_min_ts;
+ param_fp_t m_freq;
+ param_fp_t m_gs_sor;
+ param_enum_t<matrix_type_e> m_method;
+ param_enum_t<matrix_fp_type_e> m_fp_type;
+ param_fp_t m_reltol;
+ param_fp_t m_vntol;
+ param_fp_t m_accuracy;
+ param_num_t<std::size_t> m_nr_loops;
+ param_num_t<std::size_t> m_gs_loops;
+ param_fp_t m_gmin;
+ param_logic_t m_pivot;
+ param_fp_t m_nr_recalc_delay;
+ param_int_t m_parallel;
+ param_fp_t m_min_ts_ts;
+ param_logic_t m_dynamic_ts;
+ param_fp_t m_dynamic_lte;
+ param_fp_t m_dynamic_min_ts;
param_enum_t<matrix_sort_type_e> m_sort_type;
param_logic_t m_use_gabs;
@@ -181,11 +229,10 @@ namespace netlist::solver
nl_fptype m_max_time_step;
};
-
class terms_for_net_t
{
public:
- terms_for_net_t(arena_type &arena, analog_net_t * net = nullptr);
+ terms_for_net_t(arena_type &arena, analog_net_t *net = nullptr);
void clear();
@@ -201,35 +248,49 @@ namespace netlist::solver
void setV(nl_fptype v) noexcept { m_net->set_Q_Analog(v); }
- bool is_net(const analog_net_t * net) const noexcept { return net == m_net; }
+ bool is_net(const analog_net_t *net) const noexcept
+ {
+ return net == m_net;
+ }
void set_rail_start(std::size_t val) noexcept { m_rail_start = val; }
PALIGNAS_VECTOROPT()
- plib::arena_vector<arena_type, unsigned> m_nz; //!< all non zero for multiplication
- plib::arena_vector<arena_type, unsigned> m_nzrd; //!< non zero right of the diagonal for elimination, may include RHS element
- plib::arena_vector<arena_type, unsigned> m_nzbd; //!< non zero below of the diagonal for elimination
+ plib::arena_vector<arena_type, unsigned> m_nz; //!< all non zero for
+ //!< multiplication
+ plib::arena_vector<arena_type, unsigned> m_nzrd; //!< non zero right of
+ //!< the diagonal for
+ //!< elimination, may
+ //!< include RHS
+ //!< element
+ plib::arena_vector<arena_type, unsigned> m_nzbd; //!< non zero below of
+ //!< the diagonal for
+ //!< elimination
plib::arena_vector<arena_type, int> m_connected_net_idx;
+
private:
plib::arena_vector<arena_type, terminal_t *> m_terms;
- analog_net_t * m_net;
- std::size_t m_rail_start;
+ analog_net_t *m_net;
+ std::size_t m_rail_start;
};
class proxied_analog_output_t : public analog_output_t
{
public:
-
- proxied_analog_output_t(core_device_t &dev, const pstring &aname, analog_net_t *pnet)
+ proxied_analog_output_t(core_device_t &dev, const pstring &aname,
+ analog_net_t *pnet)
: analog_output_t(dev, aname)
, m_proxied_net(pnet)
- { }
+ {
+ }
+
+ analog_net_t *proxied_net() const { return m_proxied_net; }
- analog_net_t *proxied_net() const { return m_proxied_net;}
private:
- analog_net_t *m_proxied_net; // only for proxy nets in analog input logic
+ analog_net_t *m_proxied_net; // only for proxy nets in analog input
+ // logic
};
class matrix_solver_t : public device_t
@@ -237,16 +298,22 @@ namespace netlist::solver
public:
using list_t = std::vector<matrix_solver_t *>;
using fptype = nl_fptype;
- using net_list_t = std::vector<analog_net_t *>;
+ using net_list_t = std::vector<analog_net_t *>;
// after every call to solve, update inputs must be called.
// this can be done as well as a batch to ease parallel processing.
netlist_time solve(netlist_time_ext now, const char *source);
- void update_inputs();
+ void update_inputs();
- std::size_t dynamic_device_count() const noexcept { return m_dynamic_funcs.size(); }
- std::size_t time_step_device_count() const noexcept { return m_step_funcs.size(); }
+ std::size_t dynamic_device_count() const noexcept
+ {
+ return m_dynamic_funcs.size();
+ }
+ std::size_t time_step_device_count() const noexcept
+ {
+ return m_step_funcs.size();
+ }
/// \brief reschedule solver execution
///
@@ -264,23 +331,28 @@ namespace netlist::solver
// this should only occur outside of execution and thus
// using time should be safe.
- [[maybe_unused]] const netlist_time new_time_step = solve(exec().time(), "solve_now");
+ [[maybe_unused]] const netlist_time new_time_step = solve(
+ exec().time(), "solve_now");
update_inputs();
if (time_step_device_count() > 0)
{
- this->reschedule(netlist_time::from_fp(m_params.m_dynamic_ts ? m_params.m_min_time_step : m_params.m_max_time_step));
+ this->reschedule(netlist_time::from_fp(
+ m_params.m_dynamic_ts ? m_params.m_min_time_step
+ : m_params.m_max_time_step));
}
}
template <typename F>
void change_state(F f)
{
- // We only need to update the net first if this is a time stepping net
+ // We only need to update the net first if this is a time stepping
+ // net
if (time_step_device_count() > 0)
{
- [[maybe_unused]] const netlist_time new_time_step = solve(exec().time(), "change_state");
+ [[maybe_unused]] const netlist_time new_time_step = solve(
+ exec().time(), "change_state");
update_inputs();
}
f();
@@ -297,9 +369,11 @@ namespace netlist::solver
virtual void log_stats();
- virtual std::pair<pstring, pstring> create_solver_code([[maybe_unused]] solver::static_compile_target target)
+ virtual std::pair<pstring, pstring> create_solver_code(
+ [[maybe_unused]] solver::static_compile_target target)
{
- return { "", plib::pfmt("// solver doesn't support static compile\n\n") };
+ return {"",
+ plib::pfmt("// solver doesn't support static compile\n\n")};
}
// return number of floating point operations for solve
@@ -307,11 +381,13 @@ namespace netlist::solver
protected:
matrix_solver_t(devices::nld_solver &main_solver, const pstring &name,
- const net_list_t &nets,
- const solver_parameters_t *params);
+ const net_list_t &nets,
+ const solver_parameters_t *params);
virtual void upstream_solve_non_dynamic() = 0;
- virtual netlist_time compute_next_time_step(fptype cur_ts, fptype min_ts, fptype max_ts) = 0;
+ virtual netlist_time
+ compute_next_time_step(fptype cur_ts, fptype min_ts, fptype max_ts)
+ = 0;
virtual bool check_err() const = 0;
virtual void store() = 0;
virtual void backup() = 0;
@@ -326,7 +402,7 @@ namespace netlist::solver
}
const solver_parameters_t &m_params;
- arena_type m_arena;
+ arena_type m_arena;
plib::pmatrix2d_vrl<arena_type, fptype> m_gonn;
plib::pmatrix2d_vrl<arena_type, fptype> m_gtn;
@@ -339,20 +415,20 @@ namespace netlist::solver
std::vector<terms_for_net_t> m_terms; // setup only
private:
-
// base setup - called from constructor
void setup_base(setup_t &setup, const net_list_t &nets) noexcept(false);
- bool solve_nr_base();
+ bool solve_nr_base();
netlist_time newton_loops_exceeded(netlist_time delta);
void sort_terms(matrix_sort_type_e sort);
void update_dynamic() noexcept;
- void step(time_step_type ts_type, netlist_time delta) noexcept;
+ void step(detail::time_step_type ts_type, netlist_time delta) noexcept;
int get_net_idx(const analog_net_t *net) const noexcept;
- std::pair<int, int> get_left_right_of_diagonal(std::size_t irow, std::size_t idiag);
+ std::pair<int, int>
+ get_left_right_of_diagonal(std::size_t irow, std::size_t idiag);
fptype get_weight_around_diagonal(std::size_t row, std::size_t diag);
void add_term(std::size_t net_idx, terminal_t *term) noexcept(false);
@@ -371,10 +447,12 @@ namespace netlist::solver
state_var<std::size_t> m_stat_newton_raphson_fail;
state_var<std::size_t> m_stat_vsolver_calls;
- state_var<netlist_time_ext> m_last_step;
- plib::arena_vector<arena_type, nl_delegate_ts> m_step_funcs;
+ state_var<netlist_time_ext> m_last_step;
+ plib::arena_vector<arena_type, nl_delegate_ts> m_step_funcs;
plib::arena_vector<arena_type, nl_delegate_dyn> m_dynamic_funcs;
- plib::arena_vector<arena_type, device_arena::unique_ptr<proxied_analog_output_t>> m_inputs;
+ plib::arena_vector<arena_type,
+ device_arena::unique_ptr<proxied_analog_output_t>>
+ m_inputs;
std::size_t m_ops;
diff --git a/src/lib/netlist/tests/test_precommit.cpp b/src/lib/netlist/tests/test_precommit.cpp
index 15575fbbe7f..6faf8029c0b 100644
--- a/src/lib/netlist/tests/test_precommit.cpp
+++ b/src/lib/netlist/tests/test_precommit.cpp
@@ -2,12 +2,12 @@
// copyright-holders:Couriersud
///
-/// \file test_pmfp.cpp
+/// \file test_precommit.cpp
///
-/// tests for `plib::pmfp`
+/// tests to check for experimental code before commit
///
-#include "netlist/nl_config.h"
+#include "nl_config.h"
#include "plib/pconfig.h"
#include "plib/ppmf.h"