summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist
diff options
context:
space:
mode:
author couriersud <couriersud@gmx.org>2019-11-02 22:25:11 +0100
committer couriersud <couriersud@gmx.org>2019-11-02 22:25:11 +0100
commit77ea61bac778e0eccaf2872e6d67c2eec7eb541b (patch)
tree34559a448c8c142ee5e707b567fa17d7c98cf006 /src/lib/netlist
parent7518cc226b9a6754847f67f6129b44c34be29179 (diff)
netlist: add RELTOL/VNTOL solver parameters. Type safety. [Couriersud]
The newly added RELTOL and VNTOL parameters implement Newton convergence checks comparable following other SPICE implementations. The ACCURACY solver parameter now is only used for convergence checks in iterative solvers. In addition, type safety was significantly improved and a lot of "magic" numbers are identifiable now.
Diffstat (limited to 'src/lib/netlist')
-rw-r--r--src/lib/netlist/analog/nld_bjt.cpp50
-rw-r--r--src/lib/netlist/analog/nld_generic_models.h52
-rw-r--r--src/lib/netlist/analog/nld_mosfet.cpp155
-rw-r--r--src/lib/netlist/analog/nld_opamps.cpp14
-rw-r--r--src/lib/netlist/analog/nld_switches.cpp2
-rw-r--r--src/lib/netlist/analog/nld_twoterm.h18
-rw-r--r--src/lib/netlist/analog/nlid_fourterm.cpp7
-rw-r--r--src/lib/netlist/analog/nlid_fourterm.h12
-rw-r--r--src/lib/netlist/analog/nlid_twoterm.cpp18
-rw-r--r--src/lib/netlist/analog/nlid_twoterm.h55
-rw-r--r--src/lib/netlist/devices/nld_4066.cpp4
-rw-r--r--src/lib/netlist/devices/nld_4316.cpp2
-rw-r--r--src/lib/netlist/devices/nld_74123.cpp8
-rw-r--r--src/lib/netlist/devices/nld_74ls629.cpp28
-rw-r--r--src/lib/netlist/devices/nld_mm5837.cpp10
-rw-r--r--src/lib/netlist/devices/nld_ne555.cpp18
-rw-r--r--src/lib/netlist/devices/nld_r2r_dac.cpp6
-rw-r--r--src/lib/netlist/devices/nld_schmitt.cpp8
-rw-r--r--src/lib/netlist/devices/nlid_proxy.cpp27
-rw-r--r--src/lib/netlist/devices/nlid_proxy.h2
-rw-r--r--src/lib/netlist/devices/nlid_system.h38
-rw-r--r--src/lib/netlist/nl_base.cpp32
-rw-r--r--src/lib/netlist/nl_base.h4
-rw-r--r--src/lib/netlist/nl_config.h3
-rw-r--r--src/lib/netlist/nl_parser.cpp12
-rw-r--r--src/lib/netlist/nl_setup.cpp26
-rw-r--r--src/lib/netlist/nl_setup.h11
-rw-r--r--src/lib/netlist/plib/pchrono.h8
-rw-r--r--src/lib/netlist/plib/pfunction.cpp5
-rw-r--r--src/lib/netlist/plib/pfunction.h4
-rw-r--r--src/lib/netlist/plib/ptime.h2
-rw-r--r--src/lib/netlist/plib/putil.h7
-rw-r--r--src/lib/netlist/prg/nltool.cpp12
-rw-r--r--src/lib/netlist/solver/nld_matrix_solver.cpp4
-rw-r--r--src/lib/netlist/solver/nld_matrix_solver.h107
-rw-r--r--src/lib/netlist/solver/nld_ms_direct.h32
-rw-r--r--src/lib/netlist/solver/nld_ms_direct1.h14
-rw-r--r--src/lib/netlist/solver/nld_ms_direct2.h13
-rw-r--r--src/lib/netlist/solver/nld_ms_gcr.h34
-rw-r--r--src/lib/netlist/solver/nld_ms_gmres.h14
-rw-r--r--src/lib/netlist/solver/nld_ms_sm.h14
-rw-r--r--src/lib/netlist/solver/nld_ms_sor.h22
-rw-r--r--src/lib/netlist/solver/nld_ms_sor_mat.h11
-rw-r--r--src/lib/netlist/solver/nld_ms_w.h22
44 files changed, 510 insertions, 437 deletions
diff --git a/src/lib/netlist/analog/nld_bjt.cpp b/src/lib/netlist/analog/nld_bjt.cpp
index f1d66c2344f..2eed4711322 100644
--- a/src/lib/netlist/analog/nld_bjt.cpp
+++ b/src/lib/netlist/analog/nld_bjt.cpp
@@ -21,17 +21,22 @@ namespace analog
class diode
{
public:
- diode() : m_Is(1e-15), m_VT(0.0258), m_VT_inv(plib::reciprocal(m_VT)) {}
+ diode()
+ : m_Is(plib::constants<nl_fptype>::cast(1e-15))
+ , m_VT(plib::constants<nl_fptype>::cast(0.0258))
+ , m_VT_inv(plib::reciprocal(m_VT))
+ {}
+
diode(const nl_fptype Is, const nl_fptype n)
{
m_Is = Is;
- m_VT = 0.0258 * n;
+ m_VT = plib::constants<nl_fptype>::cast(0.0258) * n;
m_VT_inv = plib::reciprocal(m_VT);
}
void set(const nl_fptype Is, const nl_fptype n)
{
m_Is = Is;
- m_VT = 0.0258 * n;
+ m_VT = plib::constants<nl_fptype>::cast(0.0258) * n;
m_VT_inv = plib::reciprocal(m_VT);
}
nl_fptype I(const nl_fptype V) const { return m_Is * std::exp(V * m_VT_inv) - m_Is; }
@@ -179,9 +184,9 @@ namespace analog
, m_RB(*this, "m_RB", true)
, m_RC(*this, "m_RC", true)
, m_BC(*this, "m_BC", true)
- , m_gB(1e-9)
- , m_gC(1e-9)
- , m_V(0.0)
+ , m_gB(plib::constants<nl_fptype>::cast(1e-9))
+ , m_gC(plib::constants<nl_fptype>::cast(1e-9))
+ , m_V(plib::constants<nl_fptype>::zero())
, m_state_on(*this, "m_state_on", 0)
{
register_subalias("B", m_RB.m_P);
@@ -237,13 +242,13 @@ namespace analog
connect(m_D_EB.m_N, m_D_CB.m_N);
connect(m_D_CB.m_P, m_D_EC.m_N);
- if (m_model.m_CJE > 0.0)
+ if (m_model.m_CJE > plib::constants<nl_fptype>::zero())
{
create_and_register_subdevice("m_CJE", m_CJE);
connect("B", "m_CJE.1");
connect("E", "m_CJE.2");
}
- if (m_model.m_CJC > 0.0)
+ if (m_model.m_CJC > plib::constants<nl_fptype>::zero())
{
create_and_register_subdevice("m_CJC", m_CJC);
connect("B", "m_CJC.1");
@@ -292,13 +297,14 @@ namespace analog
NETLIB_RESET(QBJT_switch)
{
NETLIB_NAME(QBJT)::reset();
+ const auto zero(plib::constants<nl_fptype>::zero());
m_state_on = 0;
- m_RB.set_G_V_I(exec().gmin(), 0.0, 0.0);
- m_RC.set_G_V_I(exec().gmin(), 0.0, 0.0);
+ m_RB.set_G_V_I(exec().gmin(), zero, zero);
+ m_RC.set_G_V_I(exec().gmin(), zero, zero);
- m_BC.set_G_V_I(exec().gmin() / 10.0, 0.0, 0.0);
+ m_BC.set_G_V_I(exec().gmin() / plib::constants<nl_fptype>::cast(10.0), zero, zero);
}
@@ -323,24 +329,25 @@ namespace analog
set_qtype((m_model.type() == "NPN") ? BJT_NPN : BJT_PNP);
- nl_fptype alpha = BF / (1.0 + BF);
+ nl_fptype alpha = BF / (plib::constants<nl_fptype>::one() + BF);
diode d(IS, NF);
// Assume 5mA Collector current for switch operation
- m_V = d.V(0.005 / alpha);
+ const auto cc(plib::constants<nl_fptype>::cast(0.005));
+ m_V = d.V(cc / alpha);
/* Base current is 0.005 / beta
* as a rough estimate, we just scale the conductance down */
- m_gB = plib::reciprocal((m_V/(0.005 / BF)));
+ m_gB = plib::reciprocal((m_V/(cc / BF)));
//m_gB = d.gI(0.005 / alpha);
if (m_gB < exec().gmin())
m_gB = exec().gmin();
- m_gC = d.gI(0.005); // very rough estimate
+ m_gC = d.gI(cc); // very rough estimate
}
NETLIB_UPDATE_TERMINALS(QBJT_switch)
@@ -350,12 +357,13 @@ namespace analog
const unsigned new_state = (m_RB.deltaV() * m > m_V ) ? 1 : 0;
if (m_state_on ^ new_state)
{
+ const auto zero(plib::constants<nl_fptype>::zero());
const nl_fptype gb = new_state ? m_gB : exec().gmin();
const nl_fptype gc = new_state ? m_gC : exec().gmin();
- const nl_fptype v = new_state ? m_V * m : 0;
+ const nl_fptype v = new_state ? m_V * m : zero;
- m_RB.set_G_V_I(gb, v, 0.0);
- m_RC.set_G_V_I(gc, 0.0, 0.0);
+ m_RB.set_G_V_I(gb, v, zero);
+ m_RC.set_G_V_I(gc, zero, zero);
m_state_on = new_state;
}
}
@@ -395,7 +403,7 @@ namespace analog
NETLIB_UPDATE_TERMINALS(QBJT_EB)
{
- const nl_fptype polarity = (qtype() == BJT_NPN ? 1.0 : -1.0);
+ const nl_fptype polarity = plib::constants<nl_fptype>::cast(qtype() == BJT_NPN ? 1.0 : -1.0);
m_gD_BE.update_diode(-m_D_EB.deltaV() * polarity);
m_gD_BC.update_diode(-m_D_CB.deltaV() * polarity);
@@ -431,8 +439,8 @@ namespace analog
set_qtype((m_model.type() == "NPN") ? BJT_NPN : BJT_PNP);
- m_alpha_f = BF / (1.0 + BF);
- m_alpha_r = BR / (1.0 + BR);
+ m_alpha_f = BF / (plib::constants<nl_fptype>::one() + BF);
+ m_alpha_r = BR / (plib::constants<nl_fptype>::one() + BR);
m_gD_BE.set_param(IS / m_alpha_f, NF, exec().gmin(), constants::T0());
m_gD_BC.set_param(IS / m_alpha_r, NR, exec().gmin(), constants::T0());
diff --git a/src/lib/netlist/analog/nld_generic_models.h b/src/lib/netlist/analog/nld_generic_models.h
index fe56e25e674..6a5285b94f6 100644
--- a/src/lib/netlist/analog/nld_generic_models.h
+++ b/src/lib/netlist/analog/nld_generic_models.h
@@ -38,10 +38,10 @@ namespace analog
{
public:
generic_capacitor(device_t &dev, const pstring &name)
- : m_h(dev, name + ".m_h", 0.0)
- , m_c(dev, name + ".m_c", 0.0)
- , m_v(dev, name + ".m_v", 0.0)
- , m_gmin(0.0)
+ : m_h(dev, name + ".m_h", plib::constants<nl_fptype>::zero())
+ , m_c(dev, name + ".m_c", plib::constants<nl_fptype>::zero())
+ , m_v(dev, name + ".m_v", plib::constants<nl_fptype>::zero())
+ , m_gmin(plib::constants<nl_fptype>::zero())
{
}
@@ -57,7 +57,7 @@ namespace analog
nl_fptype G(nl_fptype cap) const
{
//return m_h * cap + m_gmin;
- return m_h * 0.5 * (cap + m_c) + m_gmin;
+ return m_h * plib::constants<nl_fptype>::half() * (cap + m_c) + m_gmin;
//return m_h * cap + m_gmin;
}
@@ -65,7 +65,7 @@ namespace analog
{
plib::unused_var(v);
//return -m_h * 0.5 * ((cap + m_c) * m_v + (cap - m_c) * v) ;
- return -m_h * 0.5 * (cap + m_c) * m_v;
+ return -m_h * plib::constants<nl_fptype>::half() * (cap + m_c) * m_v;
//return -m_h * cap * m_v;
}
@@ -91,9 +91,9 @@ namespace analog
{
public:
generic_capacitor(device_t &dev, const pstring &name)
- : m_h(dev, name + ".m_h", 0.0)
- , m_v(dev, name + ".m_v", 0.0)
- , m_gmin(0.0)
+ : m_h(dev, name + ".m_h", plib::constants<nl_fptype>::zero())
+ , m_v(dev, name + ".m_v", plib::constants<nl_fptype>::zero())
+ , m_gmin(plib::constants<nl_fptype>::zero())
{
}
@@ -133,25 +133,29 @@ namespace analog
{
public:
generic_diode(device_t &dev, const pstring &name)
- : m_Vd(dev, name + ".m_Vd", 0.7)
- , m_Id(dev, name + ".m_Id", 0.0)
- , m_G(dev, name + ".m_G", 1e-15)
- , m_Vt(0.0)
- , m_Vmin(0.0) // not used in MOS model
- , m_Is(0.0)
- , m_logIs(0.0)
- , m_n(0.0)
- , m_gmin(1e-15)
- , m_VtInv(0.0)
- , m_Vcrit(0.0)
+ : m_Vd(dev, name + ".m_Vd", plib::constants<nl_fptype>::cast(0.7))
+ , m_Id(dev, name + ".m_Id", plib::constants<nl_fptype>::zero())
+ , m_G(dev, name + ".m_G", plib::constants<nl_fptype>::cast(1e-15))
+ , m_Vt(plib::constants<nl_fptype>::zero())
+ , m_Vmin(plib::constants<nl_fptype>::zero()) // not used in MOS model
+ , m_Is(plib::constants<nl_fptype>::zero())
+ , m_logIs(plib::constants<nl_fptype>::zero())
+ , m_n(plib::constants<nl_fptype>::zero())
+ , m_gmin(plib::constants<nl_fptype>::cast(1e-15))
+ , m_VtInv(plib::constants<nl_fptype>::zero())
+ , m_Vcrit(plib::constants<nl_fptype>::zero())
, m_name(name)
{
- set_param(1e-15, 1, 1e-15, 300.0);
+ set_param(
+ plib::constants<nl_fptype>::cast(1e-15)
+ , plib::constants<nl_fptype>::cast(1)
+ , plib::constants<nl_fptype>::cast(1e-15)
+ , plib::constants<nl_fptype>::cast(300.0));
}
void update_diode(const nl_fptype nVd)
{
- nl_fptype IseVDVt(0.0);
+ nl_fptype IseVDVt(plib::constants<nl_fptype>::zero());
if (TYPE == diode_e::BIPOLAR)
{
@@ -160,7 +164,7 @@ namespace analog
{
const nl_fptype d = std::min(+fp_constants<nl_fptype>::DIODE_MAXDIFF(), nVd - m_Vd);
const nl_fptype a = std::abs(d) * m_VtInv;
- m_Vd = m_Vd + (d < 0 ? -1.0 : 1.0) * std::log1p(a) * m_Vt;
+ m_Vd = m_Vd + plib::constants<nl_fptype>::cast(d < 0 ? -1.0 : 1.0) * std::log1p(a) * m_Vt;
}
else
m_Vd = std::max(-fp_constants<nl_fptype>::DIODE_MAXDIFF(), nVd);
@@ -205,7 +209,7 @@ namespace analog
m_Vt = m_n * temp * constants::k_b() / constants::Q_e();
- m_Vmin = -5.0 * m_Vt;
+ m_Vmin = plib::constants<nl_fptype>::cast(-5.0) * m_Vt;
m_Vcrit = m_Vt * std::log(m_Vt / m_Is / constants::sqrt2());
m_VtInv = constants::one() / m_Vt;
diff --git a/src/lib/netlist/analog/nld_mosfet.cpp b/src/lib/netlist/analog/nld_mosfet.cpp
index e78de46252f..172f8cd75f0 100644
--- a/src/lib/netlist/analog/nld_mosfet.cpp
+++ b/src/lib/netlist/analog/nld_mosfet.cpp
@@ -195,20 +195,20 @@ namespace analog
, m_cap_gb(*this, "m_cap_gb")
, m_cap_gs(*this, "m_cap_gs")
, m_cap_gd(*this, "m_cap_gd")
- , m_phi(0.0)
- , m_gamma(0.0)
- , m_vto(0.0)
- , m_beta(0.0)
- , m_lambda(0.0)
- , m_Leff(0.0)
- , m_CoxWL(0.0)
- , m_polarity(qtype() == FET_NMOS ? 1.0 : -1.0)
- , m_Cgb(0.0)
- , m_Cgs(0.0)
- , m_Cgd(0.0)
+ , m_phi(plib::constants<nl_fptype>::zero())
+ , m_gamma(plib::constants<nl_fptype>::zero())
+ , m_vto(plib::constants<nl_fptype>::zero())
+ , m_beta(plib::constants<nl_fptype>::zero())
+ , m_lambda(plib::constants<nl_fptype>::zero())
+ , m_Leff(plib::constants<nl_fptype>::zero())
+ , m_CoxWL(plib::constants<nl_fptype>::zero())
+ , m_polarity(plib::constants<nl_fptype>::cast(qtype() == FET_NMOS ? 1.0 : -1.0))
+ , m_Cgb(plib::constants<nl_fptype>::zero())
+ , m_Cgs(plib::constants<nl_fptype>::zero())
+ , m_Cgd(plib::constants<nl_fptype>::zero())
, m_capmod(2)
- , m_Vgs(*this, "m_Vgs", 0.0)
- , m_Vgd(*this, "m_Vgd", 0.0)
+ , m_Vgs(*this, "m_Vgs", plib::constants<nl_fptype>::zero())
+ , m_Vgd(*this, "m_Vgd", plib::constants<nl_fptype>::zero())
{
register_subalias("S", m_SG.m_P); // Source
register_subalias("G", m_SG.m_N); // Gate
@@ -220,7 +220,7 @@ namespace analog
connect(m_DG.m_P, m_SD.m_N);
set_qtype((m_model.type() == "NMOS_DEFAULT") ? FET_NMOS : FET_PMOS);
- m_polarity = qtype() == FET_NMOS ? 1.0 : -1.0;
+ m_polarity = qtype() == plib::constants<nl_fptype>::cast(FET_NMOS ? 1.0 : -1.0);
m_capmod = m_model.m_CAPMOD;
// printf("capmod %d %g %g\n", m_capmod, (nl_fptype)m_model.m_VTO, m_polarity);
@@ -241,46 +241,49 @@ namespace analog
// calculate effective channel length
m_Leff = m_model.m_L - 2 * m_model.m_LD;
- nl_assert_always(m_Leff > 0.0, "Effective Lateral diffusion would be negative for model " + m_model.name());
+ nl_assert_always(m_Leff > plib::constants<nl_fptype>::zero(), "Effective Lateral diffusion would be negative for model " + m_model.name());
- nl_fptype Cox = (m_model.m_TOX > 0.0) ? (constants::eps_SiO2() * constants::eps_0() / m_model.m_TOX) : 0.0;
+ nl_fptype Cox = (m_model.m_TOX > plib::constants<nl_fptype>::zero()) ? (constants::eps_SiO2() * constants::eps_0() / m_model.m_TOX) : plib::constants<nl_fptype>::zero();
// calculate DC transconductance coefficient
- if (m_model.m_KP > 0)
+ if (m_model.m_KP > plib::constants<nl_fptype>::zero())
m_beta = m_model.m_KP * m_model.m_W / m_Leff;
- else if (Cox > 0 && m_model.m_UO > 0)
- m_beta = m_model.m_UO * 1e-4 * Cox * m_model.m_W / m_Leff;
+ else if (Cox > plib::constants<nl_fptype>::zero() && m_model.m_UO > plib::constants<nl_fptype>::zero())
+ m_beta = m_model.m_UO * plib::constants<nl_fptype>::cast(1e-4) * Cox * m_model.m_W / m_Leff;
else
- m_beta = 2e-5 * m_model.m_W / m_Leff;
+ m_beta = plib::constants<nl_fptype>::cast(2e-5) * m_model.m_W / m_Leff;
//FIXME::UT can disappear
const nl_fptype Vt = constants::T0() * constants::k_b() / constants::Q_e();
// calculate surface potential if not given
- if (m_model.m_PHI > 0.0)
+ if (m_model.m_PHI > plib::constants<nl_fptype>::zero())
m_phi = m_model.m_PHI;
- else if (m_model.m_NSUB > 0.0)
+ else if (m_model.m_NSUB > plib::constants<nl_fptype>::zero())
{
- nl_assert_always(m_model.m_NSUB * 1e6 >= constants::NiSi(), "Error calculating phi for model " + m_model.name());
- m_phi = 2 * Vt * std::log (m_model.m_NSUB * 1e6 / constants::NiSi());
+ nl_assert_always(m_model.m_NSUB * plib::constants<nl_fptype>::cast(1e6) >= constants::NiSi(), "Error calculating phi for model " + m_model.name());
+ m_phi = plib::constants<nl_fptype>::two() * Vt * std::log (m_model.m_NSUB * plib::constants<nl_fptype>::cast(1e6) / constants::NiSi());
}
else
- m_phi = 0.6;
+ m_phi = plib::constants<nl_fptype>::cast(0.6);
// calculate bulk threshold if not given
- if (m_model.m_GAMMA > 0.0)
+ if (m_model.m_GAMMA > plib::constants<nl_fptype>::zero())
m_gamma = m_model.m_GAMMA;
else
{
- if (Cox > 0.0 && m_model.m_NSUB > 0)
- m_gamma = std::sqrt (2.0 * constants::Q_e() * constants::eps_Si() * constants::eps_0() * m_model.m_NSUB * 1e6) / Cox;
+ if (Cox > plib::constants<nl_fptype>::zero() && m_model.m_NSUB > plib::constants<nl_fptype>::zero())
+ m_gamma = std::sqrt (plib::constants<nl_fptype>::two()
+ * constants::Q_e() * constants::eps_Si() * constants::eps_0()
+ * m_model.m_NSUB * plib::constants<nl_fptype>::cast(1e6)) / Cox;
else
- m_gamma = 0.0;
+ m_gamma = plib::constants<nl_fptype>::zero();
}
m_vto = m_model.m_VTO;
- if(m_vto != 0.0)
+ // FIXME zero conversion
+ if(m_vto != plib::constants<nl_fptype>::zero())
log().warning(MW_MOSFET_THRESHOLD_VOLTAGE(m_model.name()));
/* FIXME: VTO if missing may be calculated from TPG, NSS and temperature. Usually models
@@ -302,7 +305,7 @@ namespace analog
//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 = 0.0; // Bulk - Source == 0 if connected
+ const nl_fptype Ubs = plib::constants<nl_fptype>::zero(); // Bulk - Source == 0 if connected
const nl_fptype Ugb = Ugs - Ubs;
m_cap_gb.timestep(m_Cgb, Ugb, step);
@@ -385,21 +388,21 @@ namespace analog
if (Vctrl <= -m_phi)
{
Cgb = m_CoxWL;
- Cgs = 0.0;
- Cgd = 0.0;
+ Cgs = plib::constants<nl_fptype>::zero();
+ Cgd = plib::constants<nl_fptype>::zero();
}
- else if (Vctrl <= -m_phi / 2.0)
+ else if (Vctrl <= -m_phi / plib::constants<nl_fptype>::two())
{
Cgb = -Vctrl * m_CoxWL / m_phi;
- Cgs = 0.0;
- Cgd = 0.0;
+ Cgs = plib::constants<nl_fptype>::zero();
+ Cgd = plib::constants<nl_fptype>::zero();
}
// Depletion
else if (Vctrl <= 0)
{
Cgb = -Vctrl * m_CoxWL / m_phi;
- Cgs = Vctrl * m_CoxWL * (4.0 / 3.0) / m_phi + (2.0 / 3.0) * m_CoxWL;
- Cgd = 0.0;
+ Cgs = Vctrl * m_CoxWL * plib::constants<nl_fptype>::cast(4.0 / 3.0) / m_phi + plib::constants<nl_fptype>::cast(2.0 / 3.0) * m_CoxWL;
+ Cgd = plib::constants<nl_fptype>::zero();
}
else
{
@@ -408,18 +411,18 @@ namespace analog
// saturation
if (Vdsat <= Vds)
{
- Cgb = 0;
- Cgs = (2.0 / 3.0) * m_CoxWL;
- Cgd = 0;
+ Cgb = plib::constants<nl_fptype>::zero();
+ Cgs = plib::constants<nl_fptype>::cast(2.0 / 3.0) * m_CoxWL;
+ Cgd = plib::constants<nl_fptype>::zero();
}
else
{
// linear
- const nl_fptype Sqr1 = std::pow(Vdsat - Vds, 2);
- const nl_fptype Sqr2 = std::pow(2.0 * Vdsat - Vds, 2);
+ const nl_fptype Sqr1 = static_cast<nl_fptype>(std::pow(Vdsat - Vds, 2));
+ const nl_fptype Sqr2 = static_cast<nl_fptype>(std::pow(plib::constants<nl_fptype>::two() * Vdsat - Vds, 2));
Cgb = 0;
- Cgs = m_CoxWL * (1.0 - Sqr1 / Sqr2) * (2.0 / 3.0);
- Cgd = m_CoxWL * (1.0 - Vdsat * Vdsat / Sqr2) * (2.0 / 3.0);
+ Cgs = m_CoxWL * (plib::constants<nl_fptype>::one() - Sqr1 / Sqr2) * plib::constants<nl_fptype>::cast(2.0 / 3.0);
+ Cgd = m_CoxWL * (plib::constants<nl_fptype>::one() - Vdsat * Vdsat / Sqr2) * plib::constants<nl_fptype>::cast(2.0 / 3.0);
}
}
}
@@ -447,16 +450,16 @@ namespace analog
// limit step sizes
- const nl_fptype k = 3.5; // see "Circuit Simulation", page 185
+ const nl_fptype k = plib::constants<nl_fptype>::cast(3.5); // see "Circuit Simulation", page 185
nl_fptype d = (Vgs - m_Vgs);
- Vgs = m_Vgs + plib::reciprocal(k) * (d < 0 ? -1.0 : 1.0) * std::log1p(k * std::abs(d));
+ Vgs = m_Vgs + plib::reciprocal(k) * plib::constants<nl_fptype>::cast(d < 0 ? -1.0 : 1.0) * std::log1p(k * std::abs(d));
d = (Vgd - m_Vgd);
- Vgd = m_Vgd + plib::reciprocal(k) * (d < 0 ? -1.0 : 1.0) * std::log1p(k * std::abs(d));
+ Vgd = m_Vgd + plib::reciprocal(k) * plib::constants<nl_fptype>::cast(d < 0 ? -1.0 : 1.0) * std::log1p(k * std::abs(d));
m_Vgs = Vgs;
m_Vgd = Vgd;
- const nl_fptype Vbs = 0.0; // Bulk - Source == 0 if connected
+ const nl_fptype Vbs = plib::constants<nl_fptype>::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
@@ -468,11 +471,11 @@ namespace analog
// Are we in forward mode ?
// in backward mode, just swap source and drain
- const bool is_forward = Vds >= 0;
+ const bool is_forward = Vds >= plib::constants<nl_fptype>::zero();
// calculate Vth
const nl_fptype Vbulk = is_forward ? Vbs : Vbd;
- const nl_fptype phi_m_Vbulk = (m_phi > Vbulk) ? std::sqrt(m_phi - Vbulk) : 0.0;
+ const nl_fptype phi_m_Vbulk = (m_phi > Vbulk) ? std::sqrt(m_phi - Vbulk) : plib::constants<nl_fptype>::zero();
const nl_fptype Vth = m_vto * m_polarity + m_gamma * (phi_m_Vbulk - std::sqrt(m_phi));
const nl_fptype Vctrl = (is_forward ? Vgs : Vgd) - Vth;
@@ -480,34 +483,34 @@ namespace analog
nl_fptype Ids(0), gm(0), gds(0), gmb(0);
const nl_fptype absVds = std::abs(Vds);
- if (Vctrl <= 0.0)
+ if (Vctrl <= plib::constants<nl_fptype>::zero())
{
// cutoff region
- Ids = 0.0;
- gm = 0.0;
- gds = 0.0;
- gmb = 0.0;
+ Ids = plib::constants<nl_fptype>::zero();
+ gm = plib::constants<nl_fptype>::zero();
+ gds = plib::constants<nl_fptype>::zero();
+ gmb = plib::constants<nl_fptype>::zero();
}
else
{
- const nl_fptype beta = m_beta * (1.0 + m_lambda * absVds);
+ const nl_fptype beta = m_beta * (plib::constants<nl_fptype>::one() + m_lambda * absVds);
if (Vctrl <= absVds)
{
// saturation region
- Ids = beta * Vctrl * Vctrl / 2.0;
+ Ids = beta * Vctrl * Vctrl / plib::constants<nl_fptype>::two();
gm = beta * Vctrl;
- gds = m_lambda * m_beta * Vctrl * Vctrl / 2.0;
+ gds = m_lambda * m_beta * Vctrl * Vctrl / plib::constants<nl_fptype>::two();
}
else
{
// linear region
- Ids = beta * absVds * (Vctrl - absVds / 2);
+ Ids = beta * absVds * (Vctrl - absVds / plib::constants<nl_fptype>::two());
gm = beta * absVds;
- gds = beta * (Vctrl - absVds) + m_lambda * m_beta * absVds * (Vctrl - absVds / 2.0);
+ gds = beta * (Vctrl - absVds) + m_lambda * m_beta * absVds * (Vctrl - absVds / plib::constants<nl_fptype>::two());
}
// backgate transconductance
- const nl_fptype bgtc = (phi_m_Vbulk != 0.0) ? (m_gamma / phi_m_Vbulk / 2.0) : 0.0;
+ const nl_fptype bgtc = (phi_m_Vbulk != plib::constants<nl_fptype>::zero()) ? (m_gamma / phi_m_Vbulk / plib::constants<nl_fptype>::two()) : plib::constants<nl_fptype>::zero();
gmb = gm * bgtc;
}
@@ -524,27 +527,27 @@ namespace analog
const nl_fptype IeqBS = m_D_BS.Ieq();
const nl_fptype gbs = m_D_BS.G();
#else
- const nl_fptype IeqBS = 0.0;
- const nl_fptype gbs = 0.0;
+ const nl_fptype IeqBS = plib::constants<nl_fptype>::zero();
+ const nl_fptype gbs = plib::constants<nl_fptype>::zero();
#endif
// exchange controlling nodes if necessary
- const nl_fptype gsource = is_forward ? (gm + gmb) : 0;
- const nl_fptype gdrain = is_forward ? 0.0 : (gm + gmb);
+ const nl_fptype gsource = is_forward ? (gm + gmb) : plib::constants<nl_fptype>::zero();
+ const nl_fptype gdrain = is_forward ? plib::constants<nl_fptype>::zero() : (gm + gmb);
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 = 0.0;
+ nl_fptype IG = plib::constants<nl_fptype>::zero();
nl_fptype ID = (+IeqBD - IeqDS) * m_polarity;
nl_fptype IS = (+IeqBS + IeqDS) * m_polarity;
nl_fptype IB = (-IeqBD - IeqBS) * m_polarity;
- nl_fptype gGG = 0.0;
- nl_fptype gGD = 0.0;
- nl_fptype gGS = 0.0;
- nl_fptype gGB = 0.0;
+ nl_fptype gGG = plib::constants<nl_fptype>::zero();
+ nl_fptype gGD = plib::constants<nl_fptype>::zero();
+ nl_fptype gGS = plib::constants<nl_fptype>::zero();
+ nl_fptype gGB = plib::constants<nl_fptype>::zero();
nl_fptype gDG = gm;
nl_fptype gDD = gds + gbd - gdrain;
@@ -556,7 +559,7 @@ namespace analog
nl_fptype gSS = gbs + gds + gsource;
const nl_fptype gSB = -gbs - gmb;
- nl_fptype gBG = 0.0;
+ nl_fptype gBG = plib::constants<nl_fptype>::zero();
const nl_fptype gBD = -gbd;
const nl_fptype gBS = -gbs;
nl_fptype gBB = gbs + gbd;
@@ -577,16 +580,16 @@ namespace analog
// Source connected to body, Diode S-B shorted!
const nl_fptype gSSBB = gSS + gBB + gBS + gSB;
-
+ const auto zero(plib::constants<nl_fptype>::zero());
// S 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, 0.0, 0.0 ); // G
+ gGD, zero, zero ); // G
// S D
- m_SD.set_mat( 0.0, gSD + gBD, 0.0, // S
- gDS + gDB, 0.0, 0.0); // D
+ m_SD.set_mat( zero, gSD + gBD, zero, // S
+ gDS + gDB, zero, zero); // D
}
NETLIB_UPDATE_PARAM(MOSFET)
diff --git a/src/lib/netlist/analog/nld_opamps.cpp b/src/lib/netlist/analog/nld_opamps.cpp
index 77ca356116c..dfd1e06b139 100644
--- a/src/lib/netlist/analog/nld_opamps.cpp
+++ b/src/lib/netlist/analog/nld_opamps.cpp
@@ -197,13 +197,13 @@ namespace netlist
NETLIB_UPDATE(opamp)
{
- const nl_fptype cVt = 0.0258 * 1.0; // * m_n;
+ const nl_fptype cVt = plib::constants<nl_fptype>::cast(0.0258 * 1.0); // * m_n;
const nl_fptype cId = m_model.m_DAB; // 3 mA
- const nl_fptype cVd = cVt * std::log(cId / 1e-15 + 1.0);
+ const nl_fptype cVd = cVt * std::log(cId / plib::constants<nl_fptype>::cast(1e-15) + plib::constants<nl_fptype>::one());
m_VH.push(m_VCC() - m_model.m_VLH - cVd);
m_VL.push(m_GND() + m_model.m_VLL + cVd);
- m_VREF.push((m_VCC() + m_GND()) / 2.0);
+ m_VREF.push((m_VCC() + m_GND()) / plib::constants<nl_fptype>::two());
}
NETLIB_UPDATE_PARAM(opamp)
@@ -220,11 +220,11 @@ namespace netlist
if (m_type == 3 || m_type == 2)
{
nl_fptype CP = m_model.m_DAB / m_model.m_SLEW;
- nl_fptype RP = 0.5 / constants::pi() / CP / m_model.m_FPF;
+ nl_fptype RP = plib::constants<nl_fptype>::half() / constants::pi() / CP / m_model.m_FPF;
nl_fptype G = m_model.m_UGF / m_model.m_FPF / RP;
//printf("OPAMP %s: %g %g %g\n", name().c_str(), CP, RP, G);
- if (m_model.m_SLEW / (4.0 * constants::pi() * 0.0258) < m_model.m_UGF)
+ if (m_model.m_SLEW / (plib::constants<nl_fptype>::four() * constants::pi() * plib::constants<nl_fptype>::cast(0.0258)) < m_model.m_UGF)
log().warning(MW_OPAMP_FAIL_CONVERGENCE(this->name()));
m_CP->m_C.setTo(CP);
@@ -234,12 +234,12 @@ namespace netlist
}
if (m_type == 2)
{
- m_EBUF->m_G.setTo(1.0);
+ m_EBUF->m_G.setTo(plib::constants<nl_fptype>::one());
m_EBUF->m_RO.setTo(m_model.m_RO);
}
if (m_type == 3)
{
- m_EBUF->m_G.setTo(1.0);
+ m_EBUF->m_G.setTo(plib::constants<nl_fptype>::one());
m_EBUF->m_RO.setTo(m_model.m_RO);
}
}
diff --git a/src/lib/netlist/analog/nld_switches.cpp b/src/lib/netlist/analog/nld_switches.cpp
index 9b73eb9650f..8f0647da04c 100644
--- a/src/lib/netlist/analog/nld_switches.cpp
+++ b/src/lib/netlist/analog/nld_switches.cpp
@@ -13,7 +13,7 @@
/* FIXME : convert to parameters */
#define R_OFF (plib::reciprocal(exec().gmin()))
-#define R_ON 0.01
+#define R_ON plib::constants<nl_fptype>::cast(0.01)
namespace netlist
{
diff --git a/src/lib/netlist/analog/nld_twoterm.h b/src/lib/netlist/analog/nld_twoterm.h
index fbebe8be6cf..39ad2dfc162 100644
--- a/src/lib/netlist/analog/nld_twoterm.h
+++ b/src/lib/netlist/analog/nld_twoterm.h
@@ -53,15 +53,15 @@
#warning "Do not include rescap.h in a netlist environment"
#endif
#ifndef RES_R
-#define RES_R(res) (static_cast<nl_fptype>(res))
-#define RES_K(res) (static_cast<nl_fptype>(res) * 1e3)
-#define RES_M(res) (static_cast<nl_fptype>(res) * 1e6)
-#define CAP_U(cap) (static_cast<nl_fptype>(cap) * 1e-6)
-#define CAP_N(cap) (static_cast<nl_fptype>(cap) * 1e-9)
-#define CAP_P(cap) (static_cast<nl_fptype>(cap) * 1e-12)
-#define IND_U(ind) (static_cast<nl_fptype>(ind) * 1e-6)
-#define IND_N(ind) (static_cast<nl_fptype>(ind) * 1e-9)
-#define IND_P(ind) (static_cast<nl_fptype>(ind) * 1e-12)
+#define RES_R(res) (res)
+#define RES_K(res) ((res) * 1e3)
+#define RES_M(res) ((res) * 1e6)
+#define CAP_U(cap) ((cap) * 1e-6)
+#define CAP_N(cap) ((cap) * 1e-9)
+#define CAP_P(cap) ((cap) * 1e-12)
+#define IND_U(ind) ((ind) * 1e-6)
+#define IND_N(ind) ((ind) * 1e-9)
+#define IND_P(ind) ((ind) * 1e-12)
#endif
#endif /* NLD_TWOTERM_H_ */
diff --git a/src/lib/netlist/analog/nlid_fourterm.cpp b/src/lib/netlist/analog/nlid_fourterm.cpp
index 49955c0c952..ea5687c4f80 100644
--- a/src/lib/netlist/analog/nlid_fourterm.cpp
+++ b/src/lib/netlist/analog/nlid_fourterm.cpp
@@ -67,16 +67,17 @@ NETLIB_UPDATE_TERMINALS(LVCCS)
{
const nl_fptype m_mult = m_G() * m_gfac; // 1.0 ==> 1V ==> 1A
const nl_fptype vi = m_IP.net().Q_Analog() - m_IN.net().Q_Analog();
+ const auto c1(plib::constants<nl_fptype>::cast(0.2));
- if (std::abs(m_mult / m_cur_limit() * vi) > 0.5)
- m_vi = m_vi + 0.2*std::tanh((vi - m_vi)/0.2);
+ if (std::abs(m_mult / m_cur_limit() * vi) > plib::constants<nl_fptype>::half())
+ m_vi = m_vi + c1 * std::tanh((vi - m_vi) / c1);
else
m_vi = vi;
const nl_fptype x = m_mult / m_cur_limit() * m_vi;
const nl_fptype X = std::tanh(x);
- const nl_fptype beta = m_mult * (1.0 - X*X);
+ const nl_fptype beta = m_mult * (plib::constants<nl_fptype>::one() - X*X);
const nl_fptype I = m_cur_limit() * X - beta * m_vi;
m_OP.set_go_gt_I(-beta, plib::constants<nl_fptype>::zero(), I);
diff --git a/src/lib/netlist/analog/nlid_fourterm.h b/src/lib/netlist/analog/nlid_fourterm.h
index 7faaac926c1..4900b55fda6 100644
--- a/src/lib/netlist/analog/nlid_fourterm.h
+++ b/src/lib/netlist/analog/nlid_fourterm.h
@@ -39,15 +39,15 @@ namespace netlist {
{
public:
NETLIB_CONSTRUCTOR(VCCS)
- , m_G(*this, "G", 1.0)
- , m_RI(*this, "RI", 1e9)
+ , m_G(*this, "G", plib::constants<nl_fptype>::one())
+ , m_RI(*this, "RI", plib::constants<nl_fptype>::cast(1e9))
, m_OP(*this, "OP", &m_IP)
, m_ON(*this, "ON", &m_IP)
, m_IP(*this, "IP", &m_IN) // <= this should be NULL and terminal be filtered out prior to solving...
, m_IN(*this, "IN", &m_IP) // <= this should be NULL and terminal be filtered out prior to solving...
, m_OP1(*this, "_OP1", &m_IN)
, m_ON1(*this, "_ON1", &m_IN)
- , m_gfac(1.0)
+ , m_gfac(plib::constants<nl_fptype>::one())
{
connect(m_OP, m_OP1);
connect(m_ON, m_ON1);
@@ -85,8 +85,8 @@ namespace netlist {
{
public:
NETLIB_CONSTRUCTOR_DERIVED(LVCCS, VCCS)
- , m_cur_limit(*this, "CURLIM", 1000.0)
- , m_vi(0.0)
+ , m_cur_limit(*this, "CURLIM", plib::constants<nl_fptype>::cast(1000.0))
+ , m_vi(plib::constants<nl_fptype>::zero())
{
}
@@ -174,7 +174,7 @@ namespace netlist {
{
public:
NETLIB_CONSTRUCTOR_DERIVED(VCVS, VCCS)
- , m_RO(*this, "RO", 1.0)
+ , m_RO(*this, "RO", plib::constants<nl_fptype>::one())
, m_OP2(*this, "_OP2", &m_ON2)
, m_ON2(*this, "_ON2", &m_OP2)
{
diff --git a/src/lib/netlist/analog/nlid_twoterm.cpp b/src/lib/netlist/analog/nlid_twoterm.cpp
index fe928782810..c9d94c98f51 100644
--- a/src/lib/netlist/analog/nlid_twoterm.cpp
+++ b/src/lib/netlist/analog/nlid_twoterm.cpp
@@ -64,7 +64,7 @@ NETLIB_RESET(POT)
{
nl_fptype v = m_Dial();
if (m_DialIsLog())
- v = (std::exp(v) - 1.0) / (std::exp(1.0) - 1.0);
+ v = (std::exp(v) - plib::constants<nl_fptype>::one()) / (std::exp(plib::constants<nl_fptype>::one()) - plib::constants<nl_fptype>::one());
m_R1.set_R(std::max(m_R() * v, exec().gmin()));
m_R2.set_R(std::max(m_R() * (plib::constants<nl_fptype>::one() - v), exec().gmin()));
@@ -77,9 +77,9 @@ NETLIB_UPDATE_PARAM(POT)
nl_fptype v = m_Dial();
if (m_DialIsLog())
- v = (std::exp(v) - 1.0) / (std::exp(1.0) - 1.0);
+ v = (std::exp(v) - plib::constants<nl_fptype>::one()) / (std::exp(plib::constants<nl_fptype>::one()) - plib::constants<nl_fptype>::one());
if (m_Reverse())
- v = 1.0 - v;
+ v = plib::constants<nl_fptype>::one() - v;
m_R1.set_R(std::max(m_R() * v, exec().gmin()));
m_R2.set_R(std::max(m_R() * (plib::constants<nl_fptype>::one() - v), exec().gmin()));
@@ -94,9 +94,9 @@ NETLIB_RESET(POT2)
nl_fptype v = m_Dial();
if (m_DialIsLog())
- v = (std::exp(v) - 1.0) / (std::exp(1.0) - 1.0);
+ v = (std::exp(v) - plib::constants<nl_fptype>::one()) / (std::exp(plib::constants<nl_fptype>::one()) - plib::constants<nl_fptype>::one());
if (m_Reverse())
- v = 1.0 - v;
+ v = plib::constants<nl_fptype>::one() - v;
m_R1.set_R(std::max(m_R() * v, exec().gmin()));
}
@@ -108,9 +108,9 @@ NETLIB_UPDATE_PARAM(POT2)
nl_fptype v = m_Dial();
if (m_DialIsLog())
- v = (std::exp(v) - 1.0) / (std::exp(1.0) - 1.0);
+ v = (std::exp(v) - plib::constants<nl_fptype>::one()) / (std::exp(plib::constants<nl_fptype>::one()) - plib::constants<nl_fptype>::one());
if (m_Reverse())
- v = 1.0 - v;
+ v = plib::constants<nl_fptype>::one() - v;
m_R1.set_R(std::max(m_R() * v, exec().gmin()));
}
@@ -121,7 +121,7 @@ NETLIB_UPDATE_PARAM(POT2)
NETLIB_RESET(L)
{
m_gmin = exec().gmin();
- m_I = 0.0;
+ m_I = plib::constants<nl_fptype>::zero();
m_G = m_gmin;
set_mat( m_G, -m_G, -m_I,
-m_G, m_G, m_I);
@@ -152,7 +152,7 @@ NETLIB_RESET(D)
nl_fptype n = m_model.m_N;
m_D.set_param(Is, n, exec().gmin(), constants::T0());
- set_G_V_I(m_D.G(), 0.0, m_D.Ieq());
+ set_G_V_I(m_D.G(), plib::constants<nl_fptype>::zero(), m_D.Ieq());
}
NETLIB_UPDATE_PARAM(D)
diff --git a/src/lib/netlist/analog/nlid_twoterm.h b/src/lib/netlist/analog/nlid_twoterm.h
index cb80e15a34a..72de24181e0 100644
--- a/src/lib/netlist/analog/nlid_twoterm.h
+++ b/src/lib/netlist/analog/nlid_twoterm.h
@@ -128,8 +128,8 @@ namespace analog
void set_R(const nl_fptype R)
{
const nl_fptype G = plib::constants<nl_fptype>::one() / R;
- set_mat( G, -G, 0.0,
- -G, G, 0.0);
+ set_mat( G, -G, plib::constants<nl_fptype>::zero(),
+ -G, G, plib::constants<nl_fptype>::zero());
}
NETLIB_RESETI();
@@ -142,7 +142,7 @@ namespace analog
NETLIB_OBJECT_DERIVED(R, R_base)
{
NETLIB_CONSTRUCTOR_DERIVED(R, R_base)
- , m_R(*this, "R", 1e9)
+ , m_R(*this, "R", plib::constants<nl_fptype>::cast(1e9))
{
}
@@ -178,7 +178,7 @@ namespace analog
, m_R1(*this, "_R1")
, m_R2(*this, "_R2")
, m_R(*this, "R", 10000)
- , m_Dial(*this, "DIAL", 0.5)
+ , m_Dial(*this, "DIAL", plib::constants<nl_fptype>::half())
, m_DialIsLog(*this, "DIALLOG", false)
, m_Reverse(*this, "REVERSE", false)
{
@@ -208,8 +208,8 @@ namespace analog
{
NETLIB_CONSTRUCTOR(POT2)
, m_R1(*this, "_R1")
- , m_R(*this, "R", 10000)
- , m_Dial(*this, "DIAL", 0.5)
+ , m_R(*this, "R", plib::constants<nl_fptype>::cast(10000.0))
+ , m_Dial(*this, "DIAL", plib::constants<nl_fptype>::half())
, m_DialIsLog(*this, "DIALLOG", false)
, m_Reverse(*this, "REVERSE", false)
{
@@ -239,7 +239,7 @@ namespace analog
{
public:
NETLIB_CONSTRUCTOR_DERIVED(C, twoterm)
- , m_C(*this, "C", 1e-6)
+ , m_C(*this, "C", plib::constants<nl_fptype>::cast(1e-6))
, m_cap(*this, "m_cap")
{
}
@@ -289,10 +289,10 @@ namespace analog
{
public:
NETLIB_CONSTRUCTOR_DERIVED(L, twoterm)
- , m_L(*this, "L", 1e-6)
- , m_gmin(0.0)
- , m_G(0.0)
- , m_I(0.0)
+ , m_L(*this, "L", plib::constants<nl_fptype>::cast(1e-6))
+ , m_gmin(plib::constants<nl_fptype>::zero())
+ , m_G(plib::constants<nl_fptype>::zero())
+ , m_I(plib::constants<nl_fptype>::zero())
{
//register_term("1", m_P);
//register_term("2", m_N);
@@ -392,12 +392,12 @@ namespace analog
{
public:
NETLIB_CONSTRUCTOR_DERIVED(VS, twoterm)
- , m_t(*this, "m_t", 0.0)
- , m_R(*this, "R", 0.1)
- , m_V(*this, "V", 0.0)
+ , m_t(*this, "m_t", plib::constants<nl_fptype>::zero())
+ , m_R(*this, "R", plib::constants<nl_fptype>::cast(0.1))
+ , m_V(*this, "V", plib::constants<nl_fptype>::zero())
, m_func(*this,"FUNC", "")
, m_compiled(this->name() + ".FUNCC", this, this->state().run_state_manager())
- , m_funcparam({0.0})
+ , m_funcparam({plib::constants<nl_fptype>::zero()})
{
register_subalias("P", m_P);
register_subalias("N", m_N);
@@ -413,7 +413,7 @@ namespace analog
m_funcparam[0] = m_t;
this->set_G_V_I(plib::reciprocal(m_R()),
m_compiled.evaluate(m_funcparam),
- 0.0);
+ plib::constants<nl_fptype>::zero());
}
protected:
@@ -422,7 +422,7 @@ namespace analog
NETLIB_RESETI()
{
NETLIB_NAME(twoterm)::reset();
- this->set_G_V_I(plib::reciprocal(m_R()), m_V(), 0.0);
+ this->set_G_V_I(plib::reciprocal(m_R()), m_V(), plib::constants<nl_fptype>::zero());
}
private:
@@ -442,11 +442,11 @@ namespace analog
{
public:
NETLIB_CONSTRUCTOR_DERIVED(CS, twoterm)
- , m_t(*this, "m_t", 0.0)
- , m_I(*this, "I", 1.0)
+ , m_t(*this, "m_t", plib::constants<nl_fptype>::zero())
+ , m_I(*this, "I", plib::constants<nl_fptype>::one())
, m_func(*this,"FUNC", "")
, m_compiled(this->name() + ".FUNCC", this, this->state().run_state_manager())
- , m_funcparam({0.0})
+ , m_funcparam({plib::constants<nl_fptype>::zero()})
{
register_subalias("P", m_P);
register_subalias("N", m_N);
@@ -460,8 +460,9 @@ namespace analog
m_t += step;
m_funcparam[0] = m_t;
const nl_fptype I = m_compiled.evaluate(m_funcparam);
- set_mat(0.0, 0.0, -I,
- 0.0, 0.0, I);
+ const auto zero(plib::constants<nl_fptype>::zero());
+ set_mat(zero, zero, -I,
+ zero, zero, I);
}
protected:
@@ -470,15 +471,17 @@ namespace analog
NETLIB_RESETI()
{
NETLIB_NAME(twoterm)::reset();
- set_mat(0.0, 0.0, -m_I(),
- 0.0, 0.0, m_I());
+ const auto zero(plib::constants<nl_fptype>::zero());
+ set_mat(zero, zero, -m_I(),
+ zero, zero, m_I());
}
NETLIB_UPDATE_PARAMI()
{
solve_now();
- set_mat(0.0, 0.0, -m_I(),
- 0.0, 0.0, m_I());
+ const auto zero(plib::constants<nl_fptype>::zero());
+ set_mat(zero, zero, -m_I(),
+ zero, zero, m_I());
}
diff --git a/src/lib/netlist/devices/nld_4066.cpp b/src/lib/netlist/devices/nld_4066.cpp
index 798beffa975..ed14748975a 100644
--- a/src/lib/netlist/devices/nld_4066.cpp
+++ b/src/lib/netlist/devices/nld_4066.cpp
@@ -22,7 +22,7 @@ namespace netlist
, m_supply(*this, "VDD", "VSS", true)
, m_R(*this, "R")
, m_control(*this, "CTL")
- , m_base_r(*this, "BASER", 270.0)
+ , m_base_r(*this, "BASER", plib::constants<nl_fptype>::cast(270.0))
{
}
@@ -52,7 +52,7 @@ namespace netlist
nl_fptype high = plib::constants<nl_fptype>::cast(0.55) * sup;
nl_fptype in = m_control() - m_supply.GND();
nl_fptype rON = m_base_r() * plib::constants<nl_fptype>::cast(5.0) / sup;
- nl_fptype R = -1.0;
+ nl_fptype R = -plib::constants<nl_fptype>::one();
if (in < low)
{
diff --git a/src/lib/netlist/devices/nld_4316.cpp b/src/lib/netlist/devices/nld_4316.cpp
index 26a188502a8..206dffc821d 100644
--- a/src/lib/netlist/devices/nld_4316.cpp
+++ b/src/lib/netlist/devices/nld_4316.cpp
@@ -20,7 +20,7 @@ namespace netlist { namespace devices {
, m_R(*this, "_R")
, m_S(*this, "S")
, m_E(*this, "E")
- , m_base_r(*this, "BASER", 45.0)
+ , m_base_r(*this, "BASER", plib::constants<nl_fptype>::cast(45.0))
{
}
diff --git a/src/lib/netlist/devices/nld_74123.cpp b/src/lib/netlist/devices/nld_74123.cpp
index 067e6ca1918..a7d654a83d2 100644
--- a/src/lib/netlist/devices/nld_74123.cpp
+++ b/src/lib/netlist/devices/nld_74123.cpp
@@ -31,8 +31,8 @@ namespace netlist
, m_last_trig(*this, "m_last_trig", 0)
, m_state(*this, "m_state", 0)
, m_KP(*this, "m_KP", 0)
- , m_K(*this, "K", (m_dev_type == 4538) ? 1.0 : 0.4) // CD4538 datasheet states PW=RC
- , m_RI(*this, "RI", 400.0) // around 250 for HC series, 400 on LS/TTL, estimated from datasheets
+ , m_K(*this, "K", plib::constants<nl_fptype>::cast((m_dev_type == 4538) ? 1.0 : 0.4)) // CD4538 datasheet states PW=RC
+ , m_RI(*this, "RI", plib::constants<nl_fptype>::cast(400.0)) // around 250 for HC series, 400 on LS/TTL, estimated from datasheets
{
if ((m_dev_type != 9602) && (m_dev_type != 4538) )
m_dev_type = 74123;
@@ -241,7 +241,7 @@ namespace netlist
}
if (m_state == 2)
{
- const nl_fptype vHigh = m_RP.m_R.m_P() * (1.0 - m_KP);
+ const nl_fptype vHigh = m_RP.m_R.m_P() * (plib::constants<nl_fptype>::one() - m_KP);
if (m_CV() > vHigh)
{
m_RP_Q.push(0, NLTIME_FROM_NS(10)); // R_OFF
@@ -255,7 +255,7 @@ namespace netlist
NETLIB_RESET(74123)
{
- m_KP = plib::reciprocal(1.0 + exp(m_K()));
+ m_KP = plib::reciprocal(plib::constants<nl_fptype>::one() + std::exp(m_K()));
m_RP.reset();
m_RN.reset();
diff --git a/src/lib/netlist/devices/nld_74ls629.cpp b/src/lib/netlist/devices/nld_74ls629.cpp
index 42c9292315c..f95da603e7e 100644
--- a/src/lib/netlist/devices/nld_74ls629.cpp
+++ b/src/lib/netlist/devices/nld_74ls629.cpp
@@ -85,7 +85,7 @@ namespace netlist
, m_ENQ(*this, "ENQ")
, m_RNG(*this, "RNG")
, m_FC(*this, "FC")
- , m_CAP(*this, "CAP", 1e-6)
+ , m_CAP(*this, "CAP", plib::constants<nl_fptype>::cast(1e-6))
{
register_subalias("GND", m_R_FC.m_N);
@@ -98,8 +98,8 @@ namespace netlist
NETLIB_RESETI()
{
- m_R_FC.set_R(90000.0);
- m_R_RNG.set_R(90000.0);
+ m_R_FC.set_R( plib::constants<nl_fptype>::cast(90000.0));
+ m_R_RNG.set_R(plib::constants<nl_fptype>::cast(90000.0));
m_clock.reset();
}
NETLIB_UPDATEI();
@@ -179,16 +179,16 @@ namespace netlist
nl_fptype v_rng = m_RNG();
/* coefficients */
- const nl_fptype k1 = 1.9904769024796283E+03;
- const nl_fptype k2 = 1.2070059213983407E+03;
- const nl_fptype k3 = 1.3266985579561108E+03;
- const nl_fptype k4 = -1.5500979825922698E+02;
- const nl_fptype k5 = 2.8184536266938172E+00;
- const nl_fptype k6 = -2.3503421582744556E+02;
- const nl_fptype k7 = -3.3836786704527788E+02;
- const nl_fptype k8 = -1.3569136703258670E+02;
- const nl_fptype k9 = 2.9914575453819188E+00;
- const nl_fptype k10 = 1.6855569086173170E+00;
+ const nl_fptype k1 = plib::constants<nl_fptype>::cast( 1.9904769024796283E+03);
+ const nl_fptype k2 = plib::constants<nl_fptype>::cast( 1.2070059213983407E+03);
+ const nl_fptype k3 = plib::constants<nl_fptype>::cast( 1.3266985579561108E+03);
+ const nl_fptype k4 = plib::constants<nl_fptype>::cast(-1.5500979825922698E+02);
+ const nl_fptype k5 = plib::constants<nl_fptype>::cast( 2.8184536266938172E+00);
+ const nl_fptype k6 = plib::constants<nl_fptype>::cast(-2.3503421582744556E+02);
+ const nl_fptype k7 = plib::constants<nl_fptype>::cast(-3.3836786704527788E+02);
+ const nl_fptype k8 = plib::constants<nl_fptype>::cast(-1.3569136703258670E+02);
+ const nl_fptype k9 = plib::constants<nl_fptype>::cast( 2.9914575453819188E+00);
+ const nl_fptype k10 = plib::constants<nl_fptype>::cast( 1.6855569086173170E+00);
/* scale due to input resistance */
@@ -212,7 +212,7 @@ namespace netlist
// FIXME: we need a possibility to remove entries from queue ...
// or an exact model ...
- m_clock.m_inc = netlist_time::from_fp<nl_fptype>(0.5 / freq);
+ m_clock.m_inc = netlist_time::from_fp(plib::constants<nl_fptype>::half() / freq);
//m_clock.update();
//NL_VERBOSE_OUT(("{1} {2} {3} {4}\n", name(), v_freq, v_rng, freq));
diff --git a/src/lib/netlist/devices/nld_mm5837.cpp b/src/lib/netlist/devices/nld_mm5837.cpp
index 5d32c8ff8cd..21b7e7d17ab 100644
--- a/src/lib/netlist/devices/nld_mm5837.cpp
+++ b/src/lib/netlist/devices/nld_mm5837.cpp
@@ -69,9 +69,11 @@ namespace netlist
{
//m_V0.initial(0.0);
//m_RV.do_reset();
- m_RV.set_G_V_I(plib::constants<nl_fptype>::one() / R_LOW, 0.0, 0.0);
+ m_RV.set_G_V_I(plib::constants<nl_fptype>::one() / plib::constants<nl_fptype>::cast(R_LOW),
+ plib::constants<nl_fptype>::zero(),
+ plib::constants<nl_fptype>::zero());
m_inc = netlist_time::from_fp(plib::reciprocal(m_FREQ()));
- if (m_FREQ() < 24000 || m_FREQ() > 56000)
+ if (m_FREQ() < plib::constants<nl_fptype>::cast(24000) || m_FREQ() > plib::constants<nl_fptype>::cast(56000))
log().warning(MW_FREQUENCY_OUTSIDE_OF_SPECS_1(m_FREQ()));
m_shift = 0x1ffff;
@@ -81,7 +83,7 @@ namespace netlist
NETLIB_UPDATE_PARAM(MM5837_dip)
{
m_inc = netlist_time::from_fp(plib::reciprocal(m_FREQ()));
- if (m_FREQ() < 24000 || m_FREQ() > 56000)
+ if (m_FREQ() < plib::constants<nl_fptype>::cast(24000) || m_FREQ() > plib::constants<nl_fptype>::cast(56000))
log().warning(MW_FREQUENCY_OUTSIDE_OF_SPECS_1(m_FREQ()));
}
@@ -102,7 +104,7 @@ namespace netlist
if (state != last_state)
{
- const nl_fptype R = state ? R_HIGH : R_LOW;
+ const nl_fptype R = plib::constants<nl_fptype>::cast(state ? R_HIGH : R_LOW);
const nl_fptype V = state ? m_VDD() : m_VSS();
// We only need to update the net first if this is a time stepping net
diff --git a/src/lib/netlist/devices/nld_ne555.cpp b/src/lib/netlist/devices/nld_ne555.cpp
index 05a334c2fe4..5c28f8313c0 100644
--- a/src/lib/netlist/devices/nld_ne555.cpp
+++ b/src/lib/netlist/devices/nld_ne555.cpp
@@ -140,11 +140,11 @@ namespace netlist
m_RDIS.reset();
/* FIXME make resistances a parameter, properly model other variants */
- m_R1.set_R(5000);
- m_R2.set_R(5000);
- m_R3.set_R(5000);
- m_ROUT.set_R(20);
- m_RDIS.set_R(R_OFF);
+ m_R1.set_R(plib::constants<nl_fptype>::cast(5000));
+ m_R2.set_R(plib::constants<nl_fptype>::cast(5000));
+ m_R3.set_R(plib::constants<nl_fptype>::cast(5000));
+ m_ROUT.set_R(plib::constants<nl_fptype>::cast(20));
+ m_RDIS.set_R(plib::constants<nl_fptype>::cast(R_OFF));
m_last_out = true;
}
@@ -161,9 +161,9 @@ namespace netlist
}
else
{
- const nl_fptype vt = clamp(m_R2.m_P(), 0.7, 1.4);
+ const nl_fptype vt = clamp(m_R2.m_P(), plib::constants<nl_fptype>::cast(0.7), plib::constants<nl_fptype>::cast(1.4));
const bool bthresh = (m_THRES() > vt);
- const bool btrig = (m_TRIG() > clamp(m_R2.m_N(), 0.7, 1.4));
+ const bool btrig = (m_TRIG() > clamp(m_R2.m_N(), plib::constants<nl_fptype>::cast(0.7), plib::constants<nl_fptype>::cast(1.4)));
if (!btrig)
m_ff = true;
@@ -177,14 +177,14 @@ namespace netlist
{
m_RDIS.update();
m_OUT.push(m_R3.m_N());
- m_RDIS.set_R(R_ON);
+ m_RDIS.set_R(plib::constants<nl_fptype>::cast(R_ON));
}
else if (!m_last_out && out)
{
m_RDIS.update();
// FIXME: Should be delayed by 100ns
m_OUT.push(m_R1.m_P());
- m_RDIS.set_R(R_OFF);
+ m_RDIS.set_R(plib::constants<nl_fptype>::cast(R_OFF));
}
m_last_reset = reset;
m_last_out = out;
diff --git a/src/lib/netlist/devices/nld_r2r_dac.cpp b/src/lib/netlist/devices/nld_r2r_dac.cpp
index c1cc4462b7b..6d83d755791 100644
--- a/src/lib/netlist/devices/nld_r2r_dac.cpp
+++ b/src/lib/netlist/devices/nld_r2r_dac.cpp
@@ -16,8 +16,8 @@ namespace netlist
NETLIB_OBJECT_DERIVED(r2r_dac, twoterm)
{
NETLIB_CONSTRUCTOR_DERIVED(r2r_dac, twoterm)
- , m_VIN(*this, "VIN", 1.0)
- , m_R(*this, "R", 1.0)
+ , m_VIN(*this, "VIN", plib::constants<nl_fptype>::one())
+ , m_R(*this, "R", plib::constants<nl_fptype>::one())
, m_num(*this, "N", 1)
, m_val(*this, "VAL", 1)
{
@@ -44,7 +44,7 @@ namespace netlist
nl_fptype V = m_VIN() / static_cast<nl_fptype>(1 << m_num())
* static_cast<nl_fptype>(m_val());
- this->set_G_V_I(plib::reciprocal(m_R()), V, 0.0);
+ this->set_G_V_I(plib::reciprocal(m_R()), V, plib::constants<nl_fptype>::zero());
}
} //namespace analog
diff --git a/src/lib/netlist/devices/nld_schmitt.cpp b/src/lib/netlist/devices/nld_schmitt.cpp
index 95739cfd662..fafeaa9f2a8 100644
--- a/src/lib/netlist/devices/nld_schmitt.cpp
+++ b/src/lib/netlist/devices/nld_schmitt.cpp
@@ -85,8 +85,8 @@ namespace netlist
m_RVI.reset();
m_RVO.reset();
m_is_timestep = m_RVO.m_P.net().solver()->has_timestep_devices();
- m_RVI.set_G_V_I(plib::constants<nl_fptype>::one() / m_model.m_RI, m_model.m_VI, 0.0);
- m_RVO.set_G_V_I(plib::constants<nl_fptype>::one() / m_model.m_ROL, m_model.m_VOL, 0.0);
+ m_RVI.set_G_V_I(plib::constants<nl_fptype>::one() / m_model.m_RI, m_model.m_VI, plib::constants<nl_fptype>::zero());
+ m_RVO.set_G_V_I(plib::constants<nl_fptype>::one() / m_model.m_ROL, m_model.m_VOL, plib::constants<nl_fptype>::zero());
}
NETLIB_UPDATEI()
@@ -98,7 +98,7 @@ namespace netlist
m_last_state = 0;
if (m_is_timestep)
m_RVO.update();
- m_RVO.set_G_V_I(plib::constants<nl_fptype>::one() / m_model.m_ROH, m_model.m_VOH, 0.0);
+ m_RVO.set_G_V_I(plib::constants<nl_fptype>::one() / m_model.m_ROH, m_model.m_VOH, plib::constants<nl_fptype>::zero());
m_RVO.solve_later();
}
}
@@ -109,7 +109,7 @@ namespace netlist
m_last_state = 1;
if (m_is_timestep)
m_RVO.update();
- m_RVO.set_G_V_I(plib::constants<nl_fptype>::one() / m_model.m_ROL, m_model.m_VOL, 0.0);
+ m_RVO.set_G_V_I(plib::constants<nl_fptype>::one() / m_model.m_ROL, m_model.m_VOL, plib::constants<nl_fptype>::zero());
m_RVO.solve_later();
}
}
diff --git a/src/lib/netlist/devices/nlid_proxy.cpp b/src/lib/netlist/devices/nlid_proxy.cpp
index 2b608185ff6..9f5be46a6cd 100644
--- a/src/lib/netlist/devices/nlid_proxy.cpp
+++ b/src/lib/netlist/devices/nlid_proxy.cpp
@@ -52,11 +52,11 @@ namespace netlist
nl_assert(m_logic_family != nullptr);
// FIXME: Variable supply voltage!
nl_fptype supply_V = logic_family()->fixed_V();
- if (supply_V == 0.0) supply_V = 5.0;
+ if (supply_V == plib::constants<nl_fptype>::zero()) supply_V = plib::constants<nl_fptype>::cast(5.0);
- if (m_I.Q_Analog() > logic_family()->high_thresh_V(0.0, supply_V))
+ if (m_I.Q_Analog() > logic_family()->high_thresh_V(plib::constants<nl_fptype>::zero(), supply_V))
out().push(1, netlist_time::quantum());
- else if (m_I.Q_Analog() < logic_family()->low_thresh_V(0.0, supply_V))
+ else if (m_I.Q_Analog() < logic_family()->low_thresh_V(plib::constants<nl_fptype>::zero(), supply_V))
out().push(0, netlist_time::quantum());
else
{
@@ -112,7 +112,7 @@ namespace netlist
//FIXME: Use power terminals and change info to warning or error
if (!f)
{
- if (logic_family()->fixed_V() == 0.0)
+ if (logic_family()->fixed_V() == plib::constants<nl_fptype>::zero())
log().error(MI_NO_POWER_TERMINALS_ON_DEVICE_1(state().setup().de_alias(out_proxied->device().name())));
else
log().info(MI_NO_POWER_TERMINALS_ON_DEVICE_1(state().setup().de_alias(out_proxied->device().name())));
@@ -148,7 +148,9 @@ namespace netlist
{
// FIXME: Variable voltage
nl_fptype supply_V = logic_family()->fixed_V();
- if (supply_V == 0.0) supply_V = 5.0;
+ // FIXME: comparison to zero
+ if (supply_V == plib::constants<nl_fptype>::zero())
+ supply_V = plib::constants<nl_fptype>::cast(5.0);
//m_Q.initial(0.0);
m_last_state = -1;
@@ -160,9 +162,10 @@ namespace netlist
m_VCCHack->initial(supply_V);
m_is_timestep = m_RN.m_P.net().solver()->has_timestep_devices();
m_RN.set_G_V_I(plib::constants<nl_fptype>::one() / logic_family()->R_low(),
- logic_family()->low_offset_V(), 0.0);
+ logic_family()->low_offset_V(), plib::constants<nl_fptype>::zero());
m_RP.set_G_V_I(G_OFF,
- 0.0, 0.0);
+ plib::constants<nl_fptype>::zero(),
+ plib::constants<nl_fptype>::zero());
}
NETLIB_UPDATE(d_to_a_proxy)
@@ -178,16 +181,18 @@ namespace netlist
if (state)
{
m_RN.set_G_V_I(G_OFF,
- 0.0, 0.0);
+ plib::constants<nl_fptype>::zero(),
+ plib::constants<nl_fptype>::zero());
m_RP.set_G_V_I(plib::constants<nl_fptype>::one() / logic_family()->R_high(),
- logic_family()->high_offset_V(), 0.0);
+ logic_family()->high_offset_V(), plib::constants<nl_fptype>::zero());
}
else
{
m_RN.set_G_V_I(plib::constants<nl_fptype>::one() / logic_family()->R_low(),
- logic_family()->low_offset_V(), 0.0);
+ logic_family()->low_offset_V(), plib::constants<nl_fptype>::zero());
m_RP.set_G_V_I(G_OFF,
- 0.0, 0.0);
+ plib::constants<nl_fptype>::zero(),
+ plib::constants<nl_fptype>::zero());
}
m_RN.solve_later(); // RN, RP are connected ...
m_last_state = state;
diff --git a/src/lib/netlist/devices/nlid_proxy.h b/src/lib/netlist/devices/nlid_proxy.h
index bdf871d9f9b..30043580306 100644
--- a/src/lib/netlist/devices/nlid_proxy.h
+++ b/src/lib/netlist/devices/nlid_proxy.h
@@ -104,7 +104,7 @@ namespace netlist
private:
- static constexpr const nl_fptype G_OFF = 1e-9;
+ static constexpr const nl_fptype G_OFF = plib::constants<nl_fptype>::cast(1e-9);
plib::unique_ptr<analog_output_t> m_GNDHack; // FIXME: Long term, we need to connect proxy gnd to device gnd
plib::unique_ptr<analog_output_t> m_VCCHack; // FIXME: Long term, we need to connect proxy gnd to device gnd
diff --git a/src/lib/netlist/devices/nlid_system.h b/src/lib/netlist/devices/nlid_system.h
index d57de8f4750..c92c18b56e3 100644
--- a/src/lib/netlist/devices/nlid_system.h
+++ b/src/lib/netlist/devices/nlid_system.h
@@ -52,9 +52,9 @@ namespace devices
{
NETLIB_CONSTRUCTOR(mainclock)
, m_Q(*this, "Q")
- , m_freq(*this, "FREQ", 7159000.0 * 5)
+ , m_freq(*this, "FREQ", plib::constants<nl_fptype>::cast(7159000.0 * 5))
{
- m_inc = netlist_time::from_fp<decltype(m_freq())>(1.0 / (m_freq()*2.0));
+ m_inc = netlist_time::from_fp(plib::reciprocal(m_freq()*plib::constants<nl_fptype>::two()));
}
NETLIB_RESETI()
@@ -64,7 +64,7 @@ namespace devices
NETLIB_UPDATE_PARAMI()
{
- m_inc = netlist_time::from_fp<decltype(m_freq())>(1.0 / (m_freq()*2.0));
+ m_inc = netlist_time::from_fp(plib::reciprocal(m_freq()*plib::constants<nl_fptype>::two()));
}
NETLIB_UPDATEI()
@@ -91,9 +91,9 @@ namespace devices
NETLIB_CONSTRUCTOR(clock)
, m_feedback(*this, "FB")
, m_Q(*this, "Q")
- , m_freq(*this, "FREQ", 7159000.0 * 5.0)
+ , m_freq(*this, "FREQ", plib::constants<nl_fptype>::cast(7159000.0 * 5.0))
{
- m_inc = netlist_time::from_fp<decltype(m_freq())>(1.0 / (m_freq()*2.0));
+ m_inc = netlist_time::from_fp(plib::reciprocal(m_freq()*plib::constants<nl_fptype>::two()));
connect(m_feedback, m_Q);
}
@@ -101,7 +101,7 @@ namespace devices
NETLIB_UPDATE_PARAMI()
{
- m_inc = netlist_time::from_fp<decltype(m_freq())>(1.0 / (m_freq() * 2.0));
+ m_inc = netlist_time::from_fp(plib::reciprocal(m_freq()*plib::constants<nl_fptype>::two()));
}
NETLIB_UPDATEI()
@@ -128,7 +128,7 @@ namespace devices
, m_Q(*this, "Q")
, m_func(*this,"FUNC", "")
, m_compiled(this->name() + ".FUNCC", this, this->state().run_state_manager())
- , m_funcparam({0.0})
+ , m_funcparam({plib::constants<nl_fptype>::zero()})
{
if (m_func() != "")
m_compiled.compile(std::vector<pstring>({{pstring("T")}}), m_func());
@@ -160,19 +160,19 @@ namespace devices
NETLIB_OBJECT(extclock)
{
NETLIB_CONSTRUCTOR(extclock)
- , m_freq(*this, "FREQ", 7159000.0 * 5.0)
+ , m_freq(*this, "FREQ", plib::constants<nl_fptype>::cast(7159000.0 * 5.0))
, m_pattern(*this, "PATTERN", "1,1")
- , m_offset(*this, "OFFSET", 0.0)
+ , m_offset(*this, "OFFSET", plib::constants<nl_fptype>::zero())
, m_feedback(*this, "FB")
, m_Q(*this, "Q")
, m_cnt(*this, "m_cnt", 0)
, m_off(*this, "m_off", netlist_time::zero())
{
- m_inc[0] = netlist_time::from_fp<decltype(m_freq())>(1.0 / (m_freq() * 2.0));
+ m_inc[0] = netlist_time::from_fp(plib::reciprocal(m_freq()*plib::constants<nl_fptype>::two()));
connect(m_feedback, m_Q);
- netlist_time base = netlist_time::from_fp<decltype(m_freq())>(1.0 / (m_freq()*2.0));
+ netlist_time base = netlist_time::from_fp(plib::reciprocal(m_freq()*plib::constants<nl_fptype>::two()));
std::vector<pstring> pat(plib::psplit(m_pattern(),","));
m_off = netlist_time::from_fp(m_offset());
@@ -250,12 +250,12 @@ namespace devices
{
NETLIB_CONSTRUCTOR(analog_input)
, m_Q(*this, "Q")
- , m_IN(*this, "IN", 0.0)
+ , m_IN(*this, "IN", plib::constants<nl_fptype>::zero())
{
}
NETLIB_UPDATEI() { }
- NETLIB_RESETI() { m_Q.initial(0.0); }
+ NETLIB_RESETI() { m_Q.initial(plib::constants<nl_fptype>::zero()); }
NETLIB_UPDATE_PARAMI() { m_Q.push(m_IN()); }
private:
@@ -275,7 +275,7 @@ namespace devices
}
NETLIB_UPDATEI()
{
- m_Q.push(0.0);
+ m_Q.push(plib::constants<nl_fptype>::zero());
}
NETLIB_RESETI() { }
protected:
@@ -316,8 +316,8 @@ namespace devices
, m_ROUT(*this, "m_ROUT", true)
, m_I(*this, "_I")
, m_Q(*this, "_Q")
- , m_p_RIN(*this, "RIN", 1.0e6)
- , m_p_ROUT(*this, "ROUT", 50.0)
+ , m_p_RIN(*this, "RIN", plib::constants<nl_fptype>::cast(1.0e6))
+ , m_p_ROUT(*this, "ROUT", plib::constants<nl_fptype>::cast(50.0))
{
register_subalias("I", m_RIN.m_P);
@@ -371,7 +371,7 @@ namespace devices
pstring n = plib::pfmt("A{1}")(i);
m_I.push_back(pool().make_unique<analog_input_t>(*this, n));
inps.push_back(n);
- m_vals.push_back(0.0);
+ m_vals.push_back(plib::constants<nl_fptype>::zero());
}
m_compiled.compile(inps, m_func());
}
@@ -402,8 +402,8 @@ namespace devices
NETLIB_CONSTRUCTOR(res_sw)
, m_R(*this, "_R")
, m_I(*this, "I")
- , m_RON(*this, "RON", 1.0)
- , m_ROFF(*this, "ROFF", 1.0E20)
+ , m_RON(*this, "RON", plib::constants<nl_fptype>::one())
+ , m_ROFF(*this, "ROFF", plib::constants<nl_fptype>::cast(1.0E20))
, m_last_state(*this, "m_last_state", 0)
{
register_subalias("1", m_R.m_P);
diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp
index f0b5735ff26..02a341f5b7f 100644
--- a/src/lib/netlist/nl_base.cpp
+++ b/src/lib/netlist/nl_base.cpp
@@ -40,14 +40,14 @@ namespace netlist
public:
logic_family_ttl_t() : logic_family_desc_t()
{
- m_fixed_V = 5.0;
- m_low_thresh_PCNT = 0.8 / 5.0;
- m_high_thresh_PCNT = 2.0 / 5.0;
+ m_fixed_V = plib::constants<nl_fptype>::cast(5.0);
+ m_low_thresh_PCNT = plib::constants<nl_fptype>::cast(0.8 / 5.0);
+ m_high_thresh_PCNT = plib::constants<nl_fptype>::cast(2.0 / 5.0);
// m_low_V - these depend on sinked/sourced current. Values should be suitable for typical applications.
- m_low_VO = 0.1;
- m_high_VO = 1.0; // 4.0
- m_R_low = 1.0;
- m_R_high = 130.0;
+ m_low_VO = plib::constants<nl_fptype>::cast(0.1);
+ m_high_VO = plib::constants<nl_fptype>::cast(1.0); // 4.0
+ m_R_low = plib::constants<nl_fptype>::cast(1.0);
+ m_R_high = plib::constants<nl_fptype>::cast(130.0);
}
unique_pool_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const override;
unique_pool_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const override;
@@ -67,14 +67,14 @@ namespace netlist
public:
logic_family_cd4xxx_t() : logic_family_desc_t()
{
- m_fixed_V = 0.0;
- m_low_thresh_PCNT = 1.5 / 5.0;
- m_high_thresh_PCNT = 3.5 / 5.0;
+ m_fixed_V = plib::constants<nl_fptype>::cast(0.0);
+ m_low_thresh_PCNT = plib::constants<nl_fptype>::cast(1.5 / 5.0);
+ m_high_thresh_PCNT = plib::constants<nl_fptype>::cast(3.5 / 5.0);
// m_low_V - these depend on sinked/sourced current. Values should be suitable for typical applications.
- m_low_VO = 0.05;
- m_high_VO = 0.05; // 4.95
- m_R_low = 10.0;
- m_R_high = 10.0;
+ m_low_VO = plib::constants<nl_fptype>::cast(0.05);
+ m_high_VO = plib::constants<nl_fptype>::cast(0.05); // 4.95
+ m_R_low = plib::constants<nl_fptype>::cast(10.0);
+ m_R_high = plib::constants<nl_fptype>::cast(10.0);
}
unique_pool_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const override;
unique_pool_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const override;
@@ -669,7 +669,7 @@ namespace netlist
auto *p = dynamic_cast<analog_net_t *>(this);
if (p != nullptr)
- p->m_cur_Analog = 0.0;
+ p->m_cur_Analog = plib::constants<nl_fptype>::zero();
/* rebuild m_list and reset terminals to active or analog out state */
@@ -727,7 +727,7 @@ namespace netlist
analog_net_t::analog_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *mr)
: net_t(nl, aname, mr)
- , m_cur_Analog(*this, "m_cur_Analog", 0.0)
+ , m_cur_Analog(*this, "m_cur_Analog", plib::constants<nl_fptype>::zero())
, m_solver(nullptr)
{
}
diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h
index ca1e121536c..c1d42f22cb9 100644
--- a/src/lib/netlist/nl_base.h
+++ b/src/lib/netlist/nl_base.h
@@ -764,12 +764,12 @@ namespace netlist
void set_conductivity(const nl_fptype G) noexcept
{
- set_go_gt_I(-G, G, 0.0);
+ set_go_gt_I(-G, G, plib::constants<nl_fptype>::zero());
}
void set_go_gt(const nl_fptype GO, const nl_fptype GT) noexcept
{
- set_go_gt_I(GO, GT, 0.0);
+ set_go_gt_I(GO, GT, plib::constants<nl_fptype>::zero());
}
void set_go_gt_I(const nl_fptype GO, const nl_fptype GT, const nl_fptype I) noexcept
diff --git a/src/lib/netlist/nl_config.h b/src/lib/netlist/nl_config.h
index 1633efc523b..a0cbb687fec 100644
--- a/src/lib/netlist/nl_config.h
+++ b/src/lib/netlist/nl_config.h
@@ -128,6 +128,7 @@ namespace netlist
static inline constexpr long double TIMESTEP_MINDIV() noexcept { return 1e-60L; }
static inline constexpr const char * name() noexcept { return "long double"; }
+ static inline constexpr const char * suffix() noexcept { return "L"; }
};
/*! Specific constants for double floating point type
@@ -142,6 +143,7 @@ namespace netlist
static inline constexpr double TIMESTEP_MINDIV() noexcept { return 1e-60; }
static inline constexpr const char * name() noexcept { return "double"; }
+ static inline constexpr const char * suffix() noexcept { return ""; }
};
/*! Specific constants for float floating point type
@@ -156,6 +158,7 @@ namespace netlist
static inline constexpr float TIMESTEP_MINDIV() noexcept { return 1e-8f; }
static inline constexpr const char * name() noexcept { return "float"; }
+ static inline constexpr const char * suffix() noexcept { return "f"; }
};
} // namespace netlist
diff --git a/src/lib/netlist/nl_parser.cpp b/src/lib/netlist/nl_parser.cpp
index 27165d9d1f4..44c2a02ca0d 100644
--- a/src/lib/netlist/nl_parser.cpp
+++ b/src/lib/netlist/nl_parser.cpp
@@ -413,7 +413,15 @@ void parser_t::device(const pstring &dev_type)
nl_fptype parser_t::eval_param(const token_t &tok)
{
static std::array<pstring, 7> macs = {"", "RES_R", "RES_K", "RES_M", "CAP_U", "CAP_N", "CAP_P"};
- static std::array<nl_fptype, 7> facs = {1, 1, 1e3, 1e6, 1e-6, 1e-9, 1e-12};
+ static std::array<nl_fptype, 7> facs = {
+ plib::constants<nl_fptype>::cast(1.0),
+ plib::constants<nl_fptype>::cast(1.0),
+ plib::constants<nl_fptype>::cast(1e3),
+ plib::constants<nl_fptype>::cast(1e6),
+ plib::constants<nl_fptype>::cast(1e-6),
+ plib::constants<nl_fptype>::cast(1e-9),
+ plib::constants<nl_fptype>::cast(1e-12)
+ };
std::size_t f=0;
nl_fptype ret(0);
@@ -423,7 +431,7 @@ nl_fptype parser_t::eval_param(const token_t &tok)
if (f>0)
{
require_token(m_tok_param_left);
- ret = get_number_double();
+ ret = static_cast<nl_fptype>(get_number_double());
require_token(m_tok_param_right);
}
else
diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp
index a9ff47959fa..e6008595e3f 100644
--- a/src/lib/netlist/nl_setup.cpp
+++ b/src/lib/netlist/nl_setup.cpp
@@ -119,9 +119,10 @@ namespace netlist
m_namespace_stack.pop();
}
- void nlparse_t::register_param(const pstring &param, const nl_fptype value)
+ void nlparse_t::register_param_x(const pstring &param, const nl_fptype value)
{
- if (std::abs(value - std::floor(value)) > 1e-30 || std::abs(value) > 1e9)
+ if (std::abs(value - std::floor(value)) > plib::constants<nl_fptype>::cast(1e-30)
+ || std::abs(value) > plib::constants<nl_fptype>::cast(1e9))
register_param(param, plib::pfmt("{1:.9}").e(value));
else
register_param(param, plib::pfmt("{1}")(static_cast<long>(value)));
@@ -945,15 +946,15 @@ nl_fptype models_t::value(const pstring &model, const pstring &entity)
auto p = std::next(tmp.begin(), static_cast<pstring::difference_type>(tmp.size() - 1));
switch (*p)
{
- case 'M': factor = 1e6; break;
+ case 'M': factor = plib::constants<nl_fptype>::cast(1e6); break;
case 'k':
- case 'K': factor = 1e3; break;
- case 'm': factor = 1e-3; break;
- case 'u': factor = 1e-6; break;
- case 'n': factor = 1e-9; break;
- case 'p': factor = 1e-12; break;
- case 'f': factor = 1e-15; break;
- case 'a': factor = 1e-18; break;
+ case 'K': factor = plib::constants<nl_fptype>::cast(1e3); break;
+ case 'm': factor = plib::constants<nl_fptype>::cast(1e-3); break;
+ case 'u': factor = plib::constants<nl_fptype>::cast(1e-6); break;
+ case 'n': factor = plib::constants<nl_fptype>::cast(1e-9); break;
+ case 'p': factor = plib::constants<nl_fptype>::cast(1e-12); break;
+ case 'f': factor = plib::constants<nl_fptype>::cast(1e-15); break;
+ case 'a': factor = plib::constants<nl_fptype>::cast(1e-18); break;
default:
if (*p < '0' || *p > '9')
throw nl_exception(MF_UNKNOWN_NUMBER_FACTOR_IN_1(entity));
@@ -1125,9 +1126,10 @@ void setup_t::prepare_to_run()
//FIXME: check for errors ...
bool err(false);
auto v = plib::pstonum_ne<nl_fptype>(p->second, err);
- if (err || std::abs(v - std::floor(v)) > 1e-6 )
+ if (err || std::abs(v - std::floor(v)) > plib::constants<nl_fptype>::cast(1e-6) )
log().fatal(MF_HND_VAL_NOT_SUPPORTED(p->second));
- d.second->set_hint_deactivate(v == 0.0);
+ // FIXME comparison with zero
+ d.second->set_hint_deactivate(v == plib::constants<nl_fptype>::zero());
}
}
else
diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h
index 180b437d293..7d34f66d91a 100644
--- a/src/lib/netlist/nl_setup.h
+++ b/src/lib/netlist/nl_setup.h
@@ -244,7 +244,16 @@ namespace netlist
void register_link(const pstring &sin, const pstring &sout);
void register_link_arr(const pstring &terms);
void register_param(const pstring &param, const pstring &value);
- void register_param(const pstring &param, const nl_fptype value);
+
+ // FIXME: quick hack
+ void register_param_x(const pstring &param, const nl_fptype value);
+ template <typename T>
+ typename std::enable_if<std::is_floating_point<T>::value || std::is_integral<T>::value>::type
+ register_param(const pstring &param, T value)
+ {
+ register_param_x(param, static_cast<nl_fptype>(value));
+ }
+
void register_lib_entry(const pstring &name, const pstring &sourcefile);
void register_frontier(const pstring &attach, const nl_fptype r_IN, const nl_fptype r_OUT);
diff --git a/src/lib/netlist/plib/pchrono.h b/src/lib/netlist/plib/pchrono.h
index 8eb2e64d358..21890099d3f 100644
--- a/src/lib/netlist/plib/pchrono.h
+++ b/src/lib/netlist/plib/pchrono.h
@@ -216,8 +216,9 @@ namespace plib {
type total() const noexcept { return m_time; }
ctype count() const noexcept { return m_count; }
- double as_seconds() const noexcept { return static_cast<double>(total())
- / static_cast<double>(T::per_second()); }
+ template <typename S>
+ S as_seconds() const noexcept { return static_cast<S>(total())
+ / static_cast<S>(T::per_second()); }
guard_t guard() noexcept { return guard_t(*this); }
private:
@@ -247,7 +248,8 @@ namespace plib {
constexpr type average() const noexcept { return 0; }
constexpr type total() const noexcept { return 0; }
constexpr ctype count() const noexcept { return 0; }
- constexpr double as_seconds() const noexcept { return 0.0; }
+ template <typename S>
+ S as_seconds() const noexcept { return static_cast<S>(0.0); }
constexpr static bool enabled = false;
guard_t guard() { return guard_t(); }
};
diff --git a/src/lib/netlist/plib/pfunction.cpp b/src/lib/netlist/plib/pfunction.cpp
index 3a1c2962169..48939c8236a 100644
--- a/src/lib/netlist/plib/pfunction.cpp
+++ b/src/lib/netlist/plib/pfunction.cpp
@@ -195,9 +195,9 @@ namespace plib {
template <typename NT>
NT pfunction<NT>::evaluate(const std::vector<NT> &values) noexcept
{
- std::array<NT, 20> stack = { 0 };
+ std::array<NT, 20> stack = { plib::constants<NT>::zero() };
unsigned ptr = 0;
- stack[0] = 0.0;
+ stack[0] = plib::constants<NT>::zero();
for (auto &rc : m_precompiled)
{
switch (rc.m_cmd)
@@ -226,5 +226,6 @@ namespace plib {
template class pfunction<float>;
template class pfunction<double>;
+ template class pfunction<long double>;
} // namespace plib
diff --git a/src/lib/netlist/plib/pfunction.h b/src/lib/netlist/plib/pfunction.h
index 3f9c7ddc861..d1f4d8c3da4 100644
--- a/src/lib/netlist/plib/pfunction.h
+++ b/src/lib/netlist/plib/pfunction.h
@@ -10,6 +10,7 @@
#include "pstate.h"
#include "pstring.h"
+#include "putil.h"
#include <vector>
@@ -42,7 +43,7 @@ namespace plib {
};
struct rpn_inst
{
- rpn_inst() : m_cmd(ADD), m_param(0.0) { }
+ rpn_inst() : m_cmd(ADD), m_param(plib::constants<NT>::zero()) { }
rpn_cmd m_cmd;
NT m_param;
};
@@ -116,6 +117,7 @@ namespace plib {
extern template class pfunction<float>;
extern template class pfunction<double>;
+ extern template class pfunction<long double>;
} // namespace plib
diff --git a/src/lib/netlist/plib/ptime.h b/src/lib/netlist/plib/ptime.h
index c0a6cd5a34b..f6972d9f41e 100644
--- a/src/lib/netlist/plib/ptime.h
+++ b/src/lib/netlist/plib/ptime.h
@@ -123,7 +123,7 @@ namespace plib
template <typename FT>
static constexpr const typename std::enable_if<std::is_floating_point<FT>::value, ptime>::type
- from_fp(const FT t) noexcept { return ptime(static_cast<internal_type>(std::floor(t * static_cast<FT>(RES) + 0.5)), RES); }
+ from_fp(const FT t) noexcept { return ptime(static_cast<internal_type>(std::floor(t * static_cast<FT>(RES) + static_cast<FT>(0.5))), RES); }
static constexpr const ptime from_double(const double t) noexcept
{ return from_fp<double>(t); }
diff --git a/src/lib/netlist/plib/putil.h b/src/lib/netlist/plib/putil.h
index ae358b960df..1fa3971f8a6 100644
--- a/src/lib/netlist/plib/putil.h
+++ b/src/lib/netlist/plib/putil.h
@@ -221,10 +221,13 @@ namespace plib
struct constants
{
static inline constexpr T zero() noexcept { return static_cast<T>(0); }
+ static inline constexpr T half() noexcept { return static_cast<T>(0.5); }
static inline constexpr T one() noexcept { return static_cast<T>(1); }
static inline constexpr T two() noexcept { return static_cast<T>(2); }
- static inline constexpr T sqrt2() noexcept { return static_cast<T>(1.414213562373095048801688724209); }
- static inline constexpr T pi() noexcept { return static_cast<T>(3.14159265358979323846264338327950); }
+ static inline constexpr T three() noexcept { return static_cast<T>(3); }
+ static inline constexpr T four() noexcept { return static_cast<T>(4); }
+ static inline constexpr T sqrt2() noexcept { return static_cast<T>(1.414213562373095048801688724209L); }
+ static inline constexpr T pi() noexcept { return static_cast<T>(3.14159265358979323846264338327950L); }
/*!
* \brief Electric constant of vacuum
diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp
index 9ca4579ae4d..ffadd002cda 100644
--- a/src/lib/netlist/prg/nltool.cpp
+++ b/src/lib/netlist/prg/nltool.cpp
@@ -47,7 +47,7 @@ public:
opt_dir(*this, "d", "dir", "", "output directory for the generated files"),
opt_grp4(*this, "Options for run command", "These options are only used by the run command."),
- opt_ttr (*this, "t", "time_to_run", 1.0, "time to run the emulation (seconds)\n\n abc def\n\n xyz"),
+ opt_ttr (*this, "t", "time_to_run", 1, "time to run the emulation (seconds)\n\n abc def\n\n xyz"),
opt_stats(*this, "s", "statistics", "gather runtime statistics"),
opt_logs(*this, "l", "log" , "define terminal to log. This option may be specified repeatedly."),
opt_inp(*this, "i", "input", "", "input file to process (default is none)"),
@@ -311,7 +311,7 @@ void netlist_tool_callbacks_t::vlog(const plib::plog_level &l, const pstring &ls
struct input_t
{
input_t(const netlist::setup_t &setup, const pstring &line)
- : m_value(0.0)
+ : m_value(plib::constants<nl_fptype>::zero())
{
std::array<char, 400> buf; // NOLINT(cppcoreguidelines-pro-type-member-init)
double t(0);
@@ -402,7 +402,7 @@ void tool_app_t::run()
}
- pout("startup time ==> {1:5.3f}\n", t.as_seconds() );
+ pout("startup time ==> {1:5.3f}\n", t.as_seconds<nl_fptype>() );
t.reset();
@@ -462,10 +462,10 @@ void tool_app_t::run()
nt.stop();
}
- nl_fptype emutime = t.as_seconds();
+ auto emutime(t.as_seconds<nl_fptype>());
pout("{1:f} seconds emulation took {2:f} real time ==> {3:5.2f}%\n",
- (ttr - nlt).as_double(), emutime,
- (ttr - nlt).as_double() / emutime * 100.0);
+ (ttr - nlt).as_fp<nl_fptype>(), emutime,
+ (ttr - nlt).as_fp<nl_fptype>() / emutime * plib::constants<nl_fptype>::cast(100.0));
}
void tool_app_t::validate()
diff --git a/src/lib/netlist/solver/nld_matrix_solver.cpp b/src/lib/netlist/solver/nld_matrix_solver.cpp
index a1bb4f2f88e..d7b77baf1b9 100644
--- a/src/lib/netlist/solver/nld_matrix_solver.cpp
+++ b/src/lib/netlist/solver/nld_matrix_solver.cpp
@@ -501,7 +501,7 @@ namespace solver
std::vector<bool> touched(1024, false); // FIXME!
- nl_fptype weight = 0.0;
+ nl_fptype weight = plib::constants<nl_fptype>::zero();
auto &term = m_terms[row];
for (std::size_t i = 0; i < term.count(); i++)
{
@@ -560,7 +560,7 @@ namespace solver
this->m_stat_calculations,
static_cast<nl_fptype>(this->m_stat_calculations) / this->exec().time().as_fp<nl_fptype>(),
this->m_iterative_fail,
- 100.0 * static_cast<nl_fptype>(this->m_iterative_fail)
+ plib::constants<nl_fptype>::cast(100.0) * static_cast<nl_fptype>(this->m_iterative_fail)
/ static_cast<nl_fptype>(this->m_stat_calculations),
static_cast<nl_fptype>(this->m_iterative_total) / static_cast<nl_fptype>(this->m_stat_calculations));
}
diff --git a/src/lib/netlist/solver/nld_matrix_solver.h b/src/lib/netlist/solver/nld_matrix_solver.h
index 341374b1df0..3a9c8386f69 100644
--- a/src/lib/netlist/solver/nld_matrix_solver.h
+++ b/src/lib/netlist/solver/nld_matrix_solver.h
@@ -49,26 +49,29 @@ namespace solver
struct solver_parameters_t
{
solver_parameters_t(device_t &parent)
- : m_freq(parent, "FREQ", 48000.0)
+ : m_freq(parent, "FREQ", plib::constants<nl_fptype>::cast(48000.0))
/* iteration parameters */
- , m_gs_sor(parent, "SOR_FACTOR", 1.059)
- , m_method(parent, "METHOD", matrix_type_e::MAT_CR)
- , m_fp_type(parent, "FPTYPE", matrix_fp_type_e::DOUBLE)
- , m_accuracy(parent, "ACCURACY", 1e-7)
- , m_gs_loops(parent, "GS_LOOPS", 9) // Gauss-Seidel loops
+ , m_gs_sor(parent, "SOR_FACTOR", plib::constants<nl_fptype>::cast(1.059))
+ , m_method(parent, "METHOD", matrix_type_e::MAT_CR)
+ , m_fp_type(parent, "FPTYPE", matrix_fp_type_e::DOUBLE)
+ , m_reltol(parent, "RELTOL", plib::constants<nl_fptype>::cast(1e-3)) ///< SPICE RELTOL parameter
+ , m_vntol(parent, "VNTOL", plib::constants<nl_fptype>::cast(1e-6)) ///< SPICE VNTOL parameter
+ , m_accuracy(parent, "ACCURACY", plib::constants<nl_fptype>::cast(1e-7)) ///< Iterative solver accuracy
+ , m_nr_loops(parent, "NR_LOOPS", 250) ///< Maximum number of Newton-Raphson loops
+ , m_gs_loops(parent, "GS_LOOPS", 9) ///< Maximum number of Gauss-Seidel loops
/* general parameters */
- , m_gmin(parent, "GMIN", 1e-9)
- , m_pivot(parent, "PIVOT", false) // use pivoting - on supported solvers
- , m_nr_loops(parent, "NR_LOOPS", 250) // Newton-Raphson loops
- , m_nr_recalc_delay(parent, "NR_RECALC_DELAY", netlist_time::quantum().as_fp<nl_fptype>()) // Delay to next solve attempt if nr loops exceeded
+ , m_gmin(parent, "GMIN", plib::constants<nl_fptype>::cast(1e-9))
+ , m_pivot(parent, "PIVOT", false) ///< use pivoting on supported solvers
+ , m_nr_recalc_delay(parent, "NR_RECALC_DELAY",
+ netlist_time::quantum().as_fp<nl_fptype>()) ///< Delay to next solve attempt if nr loops exceeded
, m_parallel(parent, "PARALLEL", 0)
/* automatic time step */
- , m_dynamic_ts(parent, "DYNAMIC_TS", false)
- , m_dynamic_lte(parent, "DYNAMIC_LTE", 1e-5) // diff/timestep
- , m_dynamic_min_ts(parent, "DYNAMIC_MIN_TIMESTEP", 1e-6) // nl_fptype timestep resolution
+ , m_dynamic_ts(parent, "DYNAMIC_TS", false) ///< Use dynamic time stepping
+ , m_dynamic_lte(parent, "DYNAMIC_LTE", plib::constants<nl_fptype>::cast(1e-5)) ///< dynamic time stepping slope
+ , m_dynamic_min_ts(parent, "DYNAMIC_MIN_TIMESTEP", plib::constants<nl_fptype>::cast(1e-6)) ///< smallest time step allowed
/* matrix sorting */
, m_sort_type(parent, "SORT_TYPE", matrix_sort_type_e::PREFER_IDENTITY_TOP_LEFT)
@@ -95,11 +98,13 @@ namespace solver
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_num_t<std::size_t> m_nr_loops;
param_fp_t m_nr_recalc_delay;
param_int_t m_parallel;
param_logic_t m_dynamic_ts;
@@ -229,31 +234,6 @@ namespace solver
return max_rail;
}
- template <typename T>
- void store(const T & V)
- {
- const std::size_t iN = this->m_terms.size();
- for (std::size_t i = 0; i < iN; i++)
- this->m_terms[i].setV(V[i]);
- }
-
-
- template <typename T>
- auto delta(const T & V) -> typename std::decay<decltype(V[0])>::type
- {
- /* NOTE: Ideally we should also include currents (RHS) here. This would
- * need a reevaluation of the right hand side after voltages have been updated
- * and thus belong into a different calculation. This applies to all solvers.
- */
-
- const std::size_t iN = this->m_terms.size();
- using vtype = typename std::decay<decltype(V[0])>::type;
- vtype cerr = 0;
- for (std::size_t i = 0; i < iN; i++)
- cerr = std::max(cerr, std::abs(V[i] - this->m_terms[i].getV<vtype>()));
- return cerr;
- }
-
void set_pointers()
{
const std::size_t iN = this->m_terms.size();
@@ -392,6 +372,8 @@ namespace solver
const solver_parameters_t *params, const std::size_t size)
: matrix_solver_t(anetlist, name, nets, params)
, m_dim(size)
+ , m_new_V(size)
+ , m_RHS(size)
, m_mat_ptr(size, this->max_railstart() + 1)
, m_last_V(size, plib::constants<nl_fptype>::zero())
, m_DD_n_m_1(size, plib::constants<nl_fptype>::zero())
@@ -414,7 +396,14 @@ namespace solver
static constexpr const std::size_t m_pitch_ABS = (((SIZEABS + 0) + 7) / 8) * 8;
PALIGNAS_VECTOROPT()
+ plib::parray<FT, SIZE> m_new_V;
+ PALIGNAS_VECTOROPT()
+ plib::parray<FT, SIZE> m_RHS;
+
+ PALIGNAS_VECTOROPT()
plib::parray2D<float_type *, SIZE, 0> m_mat_ptr;
+
+ // FIXME: below should be private
/* state - variable time_stepping */
PALIGNAS_VECTOROPT()
plib::parray<nl_fptype, SIZE> m_last_V;
@@ -423,7 +412,38 @@ namespace solver
PALIGNAS_VECTOROPT()
plib::parray<nl_fptype, SIZE> m_h_n_m_1;
- constexpr std::size_t size() const noexcept { return (SIZE > 0) ? static_cast<std::size_t>(SIZE) : m_dim; }
+ constexpr std::size_t size() const noexcept
+ {
+ return (SIZE > 0) ? static_cast<std::size_t>(SIZE) : m_dim;
+ }
+
+ void store()
+ {
+ const std::size_t iN = size();
+ for (std::size_t i = 0; i < iN; i++)
+ this->m_terms[i].setV(m_new_V[i]);
+ }
+
+ bool check_err()
+ {
+ /* NOTE: Ideally we should also include currents (RHS) here. This would
+ * need a reevaluation of the right hand side after voltages have been updated
+ * and thus belong into a different calculation. This applies to all solvers.
+ */
+
+ const std::size_t iN = size();
+ const auto reltol(static_cast<FT>(m_params.m_reltol));
+ const auto vntol(static_cast<FT>(m_params.m_vntol));
+ for (std::size_t i = 0; i < iN; i++)
+ {
+ const auto vold(this->m_terms[i].template getV<FT>());
+ const auto vnew(m_new_V[i]);
+ const auto tol(vntol + reltol * std::max(std::abs(vnew),std::abs(vold)));
+ if (std::abs(vnew - vold) > tol)
+ return true;
+ }
+ return false;
+ }
netlist_time compute_next_timestep(const nl_fptype cur_ts) override
{
@@ -431,7 +451,7 @@ namespace solver
if (m_params.m_dynamic_ts)
{
- for (std::size_t k = 0; k < m_terms.size(); k++)
+ for (std::size_t k = 0; k < size(); k++)
{
auto &t = m_terms[k];
//const nl_fptype DD_n = (n->Q_Analog() - t->m_last_V);
@@ -507,8 +527,7 @@ namespace solver
}
}
- template <typename RT>
- void fill_matrix(RT &RHS)
+ void fill_matrix_and_rhs()
{
const std::size_t N = size();
@@ -549,7 +568,7 @@ namespace solver
RHS_t += (/*m_Idr[i]*/ (- go[i]) * *cnV[i]);
}
- RHS[k] = static_cast<FT>(RHS_t);
+ m_RHS[k] = static_cast<FT>(RHS_t);
// update diagonal element ...
*tcr_r[railstart] += static_cast<FT>(gtot_t); //mat.A[mat.diag[k]] += gtot_t;
}
diff --git a/src/lib/netlist/solver/nld_ms_direct.h b/src/lib/netlist/solver/nld_ms_direct.h
index dc7aea3e743..20f9fa23964 100644
--- a/src/lib/netlist/solver/nld_ms_direct.h
+++ b/src/lib/netlist/solver/nld_ms_direct.h
@@ -52,11 +52,7 @@ namespace solver
void LE_back_subst(T & x);
PALIGNAS_VECTOROPT()
- plib::parray<FT, SIZE> m_new_V;
- PALIGNAS_VECTOROPT()
plib::parray2D<FT, SIZE, m_pitch_ABS> m_A;
- PALIGNAS_VECTOROPT()
- plib::parray<FT, SIZE> m_RHS;
};
// ----------------------------------------------------------------------------------------
@@ -81,7 +77,7 @@ namespace solver
const FT f1 = -f * m_A[j][i];
for (auto &k : nzrd)
m_A[j][k] += m_A[i][k] * f1;
- m_RHS[j] += m_RHS[i] * f1;
+ this->m_RHS[j] += this->m_RHS[i] * f1;
}
}
}
@@ -93,8 +89,8 @@ namespace solver
std::size_t maxrow = i;
for (std::size_t j = i + 1; j < kN; j++)
{
- //if (std::abs(m_A[j][i]) > std::abs(m_A[maxrow][i]))
- if (m_A[j][i] * m_A[j][i] > m_A[maxrow][i] * m_A[maxrow][i])
+ if (std::abs(m_A[j][i]) > std::abs(m_A[maxrow][i]))
+ //if (m_A[j][i] * m_A[j][i] > m_A[maxrow][i] * m_A[maxrow][i])
maxrow = j;
}
@@ -104,7 +100,7 @@ namespace solver
for (std::size_t k = 0; k < kN; k++) {
std::swap(m_A[i][k], m_A[maxrow][k]);
}
- std::swap(m_RHS[i], m_RHS[maxrow]);
+ std::swap(this->m_RHS[i], this->m_RHS[maxrow]);
}
/* FIXME: Singular matrix? */
const FT f = plib::reciprocal(m_A[i][i]);
@@ -123,7 +119,7 @@ namespace solver
// pj[k] = pj[k] + pi[k] * f1;
//for (unsigned k = i+1; k < kN; k++)
//A(j,k) += A(i,k) * f1;
- m_RHS[j] += m_RHS[i] * f1;
+ this->m_RHS[j] += this->m_RHS[i] * f1;
}
}
}
@@ -145,7 +141,7 @@ namespace solver
FT tmp = 0;
for (std::size_t k = j+1; k < kN; k++)
tmp += m_A[j][k] * x[k];
- x[j] = (m_RHS[j] - tmp) / m_A[j][j];
+ x[j] = (this->m_RHS[j] - tmp) / m_A[j][j];
}
}
else
@@ -157,7 +153,7 @@ namespace solver
const auto e = nzrd.size(); // - 1; /* exclude RHS element */
for ( std::size_t k = 0; k < e; k++)
tmp += m_A[j][nzrd[k]] * x[nzrd[k]];
- x[j] = (m_RHS[j] - tmp) / m_A[j][j];
+ x[j] = (this->m_RHS[j] - tmp) / m_A[j][j];
}
}
}
@@ -166,11 +162,13 @@ namespace solver
unsigned matrix_solver_direct_t<FT, SIZE>::solve_non_dynamic(const bool newton_raphson)
{
this->LE_solve();
- this->LE_back_subst(m_new_V);
+ this->LE_back_subst(this->m_new_V);
- const FT err = (newton_raphson ? this->delta(m_new_V) : plib::constants<FT>::zero());
- this->store(m_new_V);
- return (err > static_cast<FT>(this->m_params.m_accuracy)) ? 2 : 1;
+ bool err(false);
+ if (newton_raphson)
+ err = this->check_err();
+ this->store();
+ return (err) ? 2 : 1;
}
template <typename FT, int SIZE>
@@ -178,7 +176,7 @@ namespace solver
{
/* populate matrix */
this->clear_square_mat(m_A);
- this->fill_matrix(m_RHS);
+ this->fill_matrix_and_rhs();
this->m_stat_calculations++;
return this->solve_non_dynamic(newton_raphson);
@@ -191,9 +189,7 @@ namespace solver
const std::size_t size)
: matrix_solver_ext_t<FT, SIZE>(anetlist, name, nets, params, size)
, m_pitch(m_pitch_ABS ? m_pitch_ABS : (((size + 0) + 7) / 8) * 8)
- , m_new_V(size)
, m_A(size, m_pitch)
- , m_RHS(size)
{
this->build_mat_ptr(m_A);
}
diff --git a/src/lib/netlist/solver/nld_ms_direct1.h b/src/lib/netlist/solver/nld_ms_direct1.h
index fa4d50677fb..3a04107103f 100644
--- a/src/lib/netlist/solver/nld_ms_direct1.h
+++ b/src/lib/netlist/solver/nld_ms_direct1.h
@@ -35,19 +35,19 @@ namespace solver
unsigned vsolve_non_dynamic(const bool newton_raphson) override
{
this->clear_square_mat(this->m_A);
- this->fill_matrix(this->m_RHS);
+ this->fill_matrix_and_rhs();
- std::array<FT, 1> new_V = { this->m_RHS[0] / this->m_A[0][0] };
+ this->m_new_V[0] = this->m_RHS[0] / this->m_A[0][0];
- const FT err = (newton_raphson ? this->delta(new_V) : plib::constants<FT>::zero());
- this->store(new_V);
- return (err > static_cast<FT>(this->m_params.m_accuracy)) ? 2 : 1;
+ bool err(false);
+ if (newton_raphson)
+ err = this->check_err();
+ this->store();
+ return (err) ? 2 : 1;
}
-
};
-
} // namespace solver
} // namespace netlist
diff --git a/src/lib/netlist/solver/nld_ms_direct2.h b/src/lib/netlist/solver/nld_ms_direct2.h
index a24ceb9ef71..26123730b59 100644
--- a/src/lib/netlist/solver/nld_ms_direct2.h
+++ b/src/lib/netlist/solver/nld_ms_direct2.h
@@ -35,7 +35,7 @@ namespace solver
unsigned vsolve_non_dynamic(const bool newton_raphson) override
{
this->clear_square_mat(this->m_A);
- this->fill_matrix(this->m_RHS);
+ this->fill_matrix_and_rhs();
const float_type a = this->m_A[0][0];
const float_type b = this->m_A[0][1];
@@ -44,12 +44,15 @@ namespace solver
const float_type v1 = (a * this->m_RHS[1] - c * this->m_RHS[0]) / (a * d - b * c);
const float_type v0 = (this->m_RHS[0] - b * v1) / a;
- std::array<float_type, 2> new_V = {v0, v1};
+ this->m_new_V[0] = v0;
+ this->m_new_V[1] = v1;
this->m_stat_calculations++;
- const float_type err = (newton_raphson ? this->delta(new_V) : plib::constants<FT>::zero());
- this->store(new_V);
- return (err > static_cast<float_type>(this->m_params.m_accuracy)) ? 2 : 1;
+ bool err(false);
+ if (newton_raphson)
+ err = this->check_err();
+ this->store();
+ return (err) ? 2 : 1;
}
};
diff --git a/src/lib/netlist/solver/nld_ms_gcr.h b/src/lib/netlist/solver/nld_ms_gcr.h
index d7f9716a5d7..5d4730ea3b1 100644
--- a/src/lib/netlist/solver/nld_ms_gcr.h
+++ b/src/lib/netlist/solver/nld_ms_gcr.h
@@ -36,8 +36,6 @@ namespace solver
const analog_net_t::list_t &nets,
const solver_parameters_t *params, const std::size_t size)
: matrix_solver_ext_t<FT, SIZE>(anetlist, name, nets, params, size)
- , RHS(size)
- , new_V(size)
, mat(static_cast<typename mat_type::index_type>(size))
, m_proc()
{
@@ -120,9 +118,6 @@ namespace solver
pstring static_compile_name();
- plib::parray<FT, SIZE> RHS;
- plib::parray<FT, SIZE> new_V;
-
mat_type mat;
plib::dynproc<void, FT * , FT * , FT * > m_proc;
@@ -137,9 +132,11 @@ namespace solver
void matrix_solver_GCR_t<FT, SIZE>::generate_code(plib::putf8_fmt_writer &strm)
{
const std::size_t iN = this->size();
+ pstring fptype(fp_constants<FT>::name());
+ pstring fpsuffix(fp_constants<FT>::suffix());
for (std::size_t i = 0; i < mat.nz_num; i++)
- strm("double m_A{1} = m_A[{2}];\n", i, i);
+ strm("{1} m_A{2} = m_A[{3}];\n", fptype, i, i);
for (std::size_t i = 0; i < iN - 1; i++)
{
@@ -150,7 +147,7 @@ namespace solver
std::size_t pi = mat.diag[i];
//const FT f = 1.0 / m_A[pi++];
- strm("const double f{1} = 1.0 / m_A{2};\n", i, pi);
+ strm("const {1} f{2} = 1.0{3} / m_A{4};\n", fptype, i, fpsuffix, pi);
pi++;
const std::size_t piie = mat.row_idx[i+1];
@@ -164,7 +161,7 @@ namespace solver
pj++;
//const FT f1 = - m_A[pj++] * f;
- strm("\tconst double f{1}_{2} = -f{3} * m_A{4};\n", i, j, i, pj);
+ strm("\tconst {1} f{2}_{3} = -f{4} * m_A{5};\n", fptype, i, j, i, pj);
pj++;
// subtract row i from j */
@@ -186,7 +183,7 @@ namespace solver
strm("\tV[{1}] = RHS[{2}] / m_A{3};\n", iN - 1, iN - 1, mat.diag[iN - 1]);
for (std::size_t j = iN - 1; j-- > 0;)
{
- strm("\tdouble tmp{1} = 0.0;\n", j);
+ strm("\t{1} tmp{2} = 0.0{3};\n", fptype, j, fpsuffix);
const std::size_t e = mat.row_idx[j+1];
for (std::size_t pk = mat.diag[j] + 1; pk < e; pk++)
{
@@ -214,8 +211,9 @@ namespace solver
t.imbue(std::locale::classic());
plib::putf8_fmt_writer strm(&t);
pstring name = static_compile_name();
+ pstring fptype(fp_constants<FT>::name());
- strm.writeline(plib::pfmt("extern \"C\" void {1}(double * __restrict m_A, double * __restrict RHS, double * __restrict V)\n")(name));
+ strm.writeline(plib::pfmt("extern \"C\" void {1}({2} * __restrict m_A, {2} * __restrict RHS, {2} * __restrict V)\n")(name, fptype));
strm.writeline("{\n");
generate_code(strm);
strm.writeline("}\n");
@@ -228,28 +226,30 @@ namespace solver
{
/* populate matrix */
mat.set_scalar(plib::constants<FT>::zero());
- this->fill_matrix(RHS);
+ this->fill_matrix_and_rhs();
/* now solve it */
if (m_proc.resolved())
{
- m_proc(&mat.A[0], &RHS[0], &new_V[0]);
+ m_proc(&mat.A[0], &this->m_RHS[0], &this->m_new_V[0]);
}
else
{
// parallel is slow -- very slow
//mat.gaussian_elimination_parallel(RHS);
- mat.gaussian_elimination(RHS);
+ mat.gaussian_elimination(this->m_RHS);
/* backward substitution */
- mat.gaussian_back_substitution(new_V, RHS);
+ mat.gaussian_back_substitution(this->m_new_V, this->m_RHS);
}
this->m_stat_calculations++;
- const FT err = (newton_raphson ? this->delta(new_V) : plib::constants<FT>::zero());
- this->store(new_V);
- return (err > static_cast<FT>(this->m_params.m_accuracy)) ? 2 : 1;
+ bool err(false);
+ if (newton_raphson)
+ err = this->check_err();
+ this->store();
+ return (err) ? 2 : 1;
}
} // namespace solver
diff --git a/src/lib/netlist/solver/nld_ms_gmres.h b/src/lib/netlist/solver/nld_ms_gmres.h
index 6d9e7929fe3..abee33bb18a 100644
--- a/src/lib/netlist/solver/nld_ms_gmres.h
+++ b/src/lib/netlist/solver/nld_ms_gmres.h
@@ -101,12 +101,10 @@ namespace solver
{
const std::size_t iN = this->size();
- plib::parray<FT, SIZE> RHS(iN);
-
m_ops.m_mat.set_scalar(plib::constants<FT>::zero());
/* populate matrix and V for first estimate */
- this->fill_matrix(RHS);
+ this->fill_matrix_and_rhs();
for (std::size_t k = 0; k < iN; k++)
{
@@ -116,7 +114,7 @@ namespace solver
const float_type accuracy = static_cast<float_type>(this->m_params.m_accuracy);
auto iter = std::max(plib::constants<std::size_t>::one(), this->m_params.m_gs_loops());
- auto gsl = m_gmres.solve(m_ops, this->m_new_V, RHS, iter, accuracy);
+ auto gsl = m_gmres.solve(m_ops, this->m_new_V, this->m_RHS, iter, accuracy);
this->m_iterative_total += gsl;
this->m_stat_calculations++;
@@ -127,9 +125,11 @@ namespace solver
return matrix_solver_direct_t<FT, SIZE>::vsolve_non_dynamic(newton_raphson);
}
- const float_type err = (newton_raphson ? this->delta(this->m_new_V) : plib::constants<FT>::zero());
- this->store(this->m_new_V);
- return (err > static_cast<float_type>(this->m_params.m_accuracy)) ? 2 : 1;
+ bool err(false);
+ if (newton_raphson)
+ err = this->check_err();
+ this->store();
+ return (err) ? 2 : 1;
}
diff --git a/src/lib/netlist/solver/nld_ms_sm.h b/src/lib/netlist/solver/nld_ms_sm.h
index 679819a2627..0d62911bc3d 100644
--- a/src/lib/netlist/solver/nld_ms_sm.h
+++ b/src/lib/netlist/solver/nld_ms_sm.h
@@ -205,8 +205,6 @@ namespace solver
const std::size_t iN = this->size();
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
- std::array<float_type, storage_N> new_V;
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
std::array<float_type, m_pitch> v;
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
std::array<std::size_t, m_pitch> cols;
@@ -277,11 +275,13 @@ namespace solver
m_cnt++;
- this->LE_compute_x(new_V);
+ this->LE_compute_x(this->m_new_V);
- const float_type err = (newton_raphson ? this->delta(new_V) : plib::constants<FT>::zero());
- this->store(new_V);
- return (err > static_cast<FT>(this->m_params.m_accuracy)) ? 2 : 1;
+ bool err(false);
+ if (newton_raphson)
+ err = this->check_err();
+ this->store();
+ return (err) ? 2 : 1;
}
template <typename FT, int SIZE>
@@ -289,7 +289,7 @@ namespace solver
{
this->clear_square_mat(this->m_A);
- this->fill_matrix(this->m_RHS);
+ this->fill_matrix_and_rhs();
this->m_stat_calculations++;
return this->solve_non_dynamic(newton_raphson);
diff --git a/src/lib/netlist/solver/nld_ms_sor.h b/src/lib/netlist/solver/nld_ms_sor.h
index 08d8a358a45..f2e8352279e 100644
--- a/src/lib/netlist/solver/nld_ms_sor.h
+++ b/src/lib/netlist/solver/nld_ms_sor.h
@@ -36,8 +36,6 @@ namespace solver
, m_lp_fact(*this, "m_lp_fact", 0)
, w(size, plib::constants<FT>::zero())
, one_m_w(size, plib::constants<FT>::zero())
- , RHS(size, plib::constants<FT>::zero())
- //, new_V(size, 0.0)
{
}
@@ -47,8 +45,6 @@ namespace solver
state_var<float_type> m_lp_fact;
std::vector<float_type> w;
std::vector<float_type> one_m_w;
- std::vector<float_type> RHS;
- //std::vector<float_type> new_V;
};
// ----------------------------------------------------------------------------------------
@@ -74,9 +70,9 @@ namespace solver
for (std::size_t k = 0; k < iN; k++)
{
- nl_fptype gtot_t = 0.0;
- nl_fptype gabs_t = 0.0;
- nl_fptype RHS_t = 0.0;
+ nl_fptype gtot_t = plib::constants<nl_fptype>::zero();
+ nl_fptype gabs_t = plib::constants<nl_fptype>::zero();
+ nl_fptype RHS_t = plib::constants<nl_fptype>::zero();
const std::size_t term_count = this->m_terms[k].count();
const nl_fptype * const gt = this->m_gtn[k];
@@ -95,7 +91,7 @@ namespace solver
for (std::size_t i = this->m_terms[k].railstart(); i < term_count; i++)
RHS_t = RHS_t - go[i] * *other_cur_analog[i];
- RHS[k] = static_cast<float_type>(RHS_t);
+ this->m_RHS[k] = static_cast<float_type>(RHS_t);
if (this->m_params.m_use_gabs)
{
@@ -136,7 +132,7 @@ namespace solver
for (std::size_t i = 0; i < railstart; i++)
Idrive = Idrive - static_cast<float_type>(go[i]) * this->m_new_V[static_cast<std::size_t>(net_other[i])];
- const float_type new_val = this->m_new_V[k] * one_m_w[k] + (Idrive + RHS[k]) * w[k];
+ const float_type new_val = this->m_new_V[k] * one_m_w[k] + (Idrive + this->m_RHS[k]) * w[k];
err = std::max(std::abs(new_val - this->m_new_V[k]), err);
this->m_new_V[k] = new_val;
@@ -158,9 +154,11 @@ namespace solver
return matrix_solver_direct_t<FT, SIZE>::vsolve_non_dynamic(newton_raphson);
}
- const float_type err = (newton_raphson ? this->delta(this->m_new_V) : plib::constants<FT>::zero());
- this->store(this->m_new_V);
- return (err > static_cast<float_type>(this->m_params.m_accuracy)) ? 2 : 1;
+ bool err(false);
+ if (newton_raphson)
+ err = this->check_err();
+ this->store();
+ return (err) ? 2 : 1;
}
} // namespace solver
diff --git a/src/lib/netlist/solver/nld_ms_sor_mat.h b/src/lib/netlist/solver/nld_ms_sor_mat.h
index da862e182ec..e411b1f1e59 100644
--- a/src/lib/netlist/solver/nld_ms_sor_mat.h
+++ b/src/lib/netlist/solver/nld_ms_sor_mat.h
@@ -117,7 +117,7 @@ namespace solver
const std::size_t iN = this->size();
this->clear_square_mat(this->m_A);
- this->fill_matrix(this->m_RHS);
+ this->fill_matrix_and_rhs();
bool resched = false;
@@ -210,10 +210,11 @@ namespace solver
return matrix_solver_direct_t<FT, SIZE>::solve_non_dynamic(newton_raphson);
}
- const float_type err = (newton_raphson ? this->delta(this->m_new_V) : plib::constants<FT>::zero());
- this->store(this->m_new_V);
- return (err > static_cast<float_type>(this->m_params.m_accuracy)) ? 2 : 1;
-
+ bool err(false);
+ if (newton_raphson)
+ err = this->check_err();
+ this->store();
+ return (err) ? 2 : 1;
}
} // namespace solver
diff --git a/src/lib/netlist/solver/nld_ms_w.h b/src/lib/netlist/solver/nld_ms_w.h
index b89edd70b74..b0c148bf252 100644
--- a/src/lib/netlist/solver/nld_ms_w.h
+++ b/src/lib/netlist/solver/nld_ms_w.h
@@ -214,8 +214,6 @@ namespace solver
const auto iN = this->size();
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
- std::array<float_type, storage_N> new_V;
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
std::array<float_type, storage_N> t; // FIXME: convert to member
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
std::array<float_type, storage_N> w;
@@ -224,12 +222,12 @@ namespace solver
{
/* complete calculation */
this->LE_invert();
- this->LE_compute_x(new_V);
+ this->LE_compute_x(this->m_new_V);
}
else
{
/* Solve Ay = b for y */
- this->LE_compute_x(new_V);
+ this->LE_compute_x(this->m_new_V);
/* determine changed rows */
@@ -261,7 +259,7 @@ namespace solver
const unsigned r = rows[i];
FT tmp = plib::constants<FT>::zero();
for (unsigned k = 0; k < iN; k++)
- tmp += VT(r,k) * new_V[k];
+ tmp += VT(r,k) * this->m_new_V[k];
w[i] = tmp;
}
@@ -328,7 +326,7 @@ namespace solver
const unsigned row = rows[j];
tmp += Ainv(i,row) * t[j];
}
- new_V[i] -= tmp;
+ this->m_new_V[i] -= tmp;
}
}
}
@@ -340,22 +338,24 @@ namespace solver
float_type tmp = plib::constants<FT>::zero();
for (unsigned j=0; j<iN; j++)
{
- tmp += A(i,j) * new_V[j];
+ tmp += A(i,j) * this->m_new_V[j];
}
if (std::abs(tmp-RHS(i)) > static_cast<float_type>(1e-6))
plib::perrlogger("{} failed on row {}: {} RHS: {}\n", this->name(), i, std::abs(tmp-RHS(i)), RHS(i));
}
- const float_type err = (newton_raphson ? this->delta(new_V) : plib::constants<FT>::zero());
- this->store(new_V);
- return (err > static_cast<float_type>(this->m_params.m_accuracy)) ? 2 : 1;
+ bool err(false);
+ if (newton_raphson)
+ err = this->check_err();
+ this->store();
+ return (err) ? 2 : 1;
}
template <typename FT, int SIZE>
unsigned matrix_solver_w_t<FT, SIZE>::vsolve_non_dynamic(const bool newton_raphson)
{
this->clear_square_mat(this->m_A);
- this->fill_matrix(this->m_RHS);
+ this->fill_matrix_and_rhs();
this->m_stat_calculations++;
return this->solve_non_dynamic(newton_raphson);