summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-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);