netlist: maintenance and simplifcation. (nw)

- solver: align matrix population along the various solvers
- solver: delete dead code
- renamed nl_double to nl_fptype and use nl_fptype where previously
  double has been used.
- renamed param_double_t to param_fp_t
This commit is contained in:
couriersud 2019-10-31 18:39:09 +01:00
parent cae02668fa
commit 6c075e602c
48 changed files with 602 additions and 654 deletions

View File

@ -189,7 +189,7 @@ public:
NETLIB_UPDATEI() NETLIB_UPDATEI()
{ {
nl_double cur = m_in(); nl_fptype cur = m_in();
// FIXME: make this a parameter // FIXME: make this a parameter
// avoid calls due to noise // avoid calls due to noise
@ -206,7 +206,7 @@ private:
netlist::analog_input_t m_in; netlist::analog_input_t m_in;
std::unique_ptr<netlist_mame_analog_output_device::output_delegate> m_callback; // TODO: change to std::optional for C++17 std::unique_ptr<netlist_mame_analog_output_device::output_delegate> m_callback; // TODO: change to std::optional for C++17
netlist_mame_cpu_device *m_cpu_device; netlist_mame_cpu_device *m_cpu_device;
netlist::state_var<nl_double> m_last; netlist::state_var<nl_fptype> m_last;
}; };
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
@ -443,7 +443,7 @@ public:
NETLIB_UPDATEI() NETLIB_UPDATEI()
{ {
nl_double val = m_in() * m_mult() + m_offset(); nl_fptype val = m_in() * m_mult() + m_offset();
sound_update(exec().time()); sound_update(exec().time());
/* ignore spikes */ /* ignore spikes */
if (std::abs(val) < 32767.0) if (std::abs(val) < 32767.0)
@ -463,8 +463,8 @@ public:
} }
netlist::param_int_t m_channel; netlist::param_int_t m_channel;
netlist::param_double_t m_mult; netlist::param_fp_t m_mult;
netlist::param_double_t m_offset; netlist::param_fp_t m_offset;
stream_sample_t *m_buffer; stream_sample_t *m_buffer;
int m_bufsize; int m_bufsize;
@ -500,8 +500,8 @@ public:
for (int i = 0; i < MAX_INPUT_CHANNELS; i++) for (int i = 0; i < MAX_INPUT_CHANNELS; i++)
{ {
m_channels[i].m_param_name = netlist::pool().make_unique<netlist::param_str_t>(*this, plib::pfmt("CHAN{1}")(i), ""); m_channels[i].m_param_name = netlist::pool().make_unique<netlist::param_str_t>(*this, plib::pfmt("CHAN{1}")(i), "");
m_channels[i].m_param_mult = netlist::pool().make_unique<netlist::param_double_t>(*this, plib::pfmt("MULT{1}")(i), 1.0); m_channels[i].m_param_mult = netlist::pool().make_unique<netlist::param_fp_t>(*this, plib::pfmt("MULT{1}")(i), 1.0);
m_channels[i].m_param_offset = netlist::pool().make_unique<netlist::param_double_t>(*this, plib::pfmt("OFFSET{1}")(i), 0.0); m_channels[i].m_param_offset = netlist::pool().make_unique<netlist::param_fp_t>(*this, plib::pfmt("OFFSET{1}")(i), 0.0);
} }
} }
@ -522,7 +522,7 @@ public:
if (i != m_num_channels) if (i != m_num_channels)
state().log().fatal("sound input numbering has to be sequential!"); state().log().fatal("sound input numbering has to be sequential!");
m_num_channels++; m_num_channels++;
m_channels[i].m_param = dynamic_cast<netlist::param_double_t *>(state().setup().find_param((*m_channels[i].m_param_name)(), true)); m_channels[i].m_param = dynamic_cast<netlist::param_fp_t *>(state().setup().find_param((*m_channels[i].m_param_name)(), true));
} }
} }
} }
@ -533,7 +533,7 @@ public:
{ {
if (m_channels[i].m_buffer == nullptr) if (m_channels[i].m_buffer == nullptr)
break; // stop, called outside of stream_update break; // stop, called outside of stream_update
const nl_double v = m_channels[i].m_buffer[m_pos]; const nl_fptype v = m_channels[i].m_buffer[m_pos];
m_channels[i].m_param->setTo(v * (*m_channels[i].m_param_mult)() + (*m_channels[i].m_param_offset)()); m_channels[i].m_param->setTo(v * (*m_channels[i].m_param_mult)() + (*m_channels[i].m_param_offset)());
} }
m_pos++; m_pos++;
@ -549,10 +549,10 @@ public:
struct channel struct channel
{ {
netlist::unique_pool_ptr<netlist::param_str_t> m_param_name; netlist::unique_pool_ptr<netlist::param_str_t> m_param_name;
netlist::param_double_t *m_param; netlist::param_fp_t *m_param;
stream_sample_t *m_buffer; stream_sample_t *m_buffer;
netlist::unique_pool_ptr<netlist::param_double_t> m_param_mult; netlist::unique_pool_ptr<netlist::param_fp_t> m_param_mult;
netlist::unique_pool_ptr<netlist::param_double_t> m_param_offset; netlist::unique_pool_ptr<netlist::param_fp_t> m_param_offset;
}; };
channel m_channels[MAX_INPUT_CHANNELS]; channel m_channels[MAX_INPUT_CHANNELS];
netlist::netlist_time m_inc; netlist::netlist_time m_inc;
@ -688,7 +688,7 @@ void netlist_mame_analog_input_device::device_start()
{ {
LOGDEVCALLS("start\n"); LOGDEVCALLS("start\n");
netlist::param_t *p = this->nl_owner().setup().find_param(pstring(m_param_name)); netlist::param_t *p = this->nl_owner().setup().find_param(pstring(m_param_name));
m_param = dynamic_cast<netlist::param_double_t *>(p); m_param = dynamic_cast<netlist::param_fp_t *>(p);
if (m_param == nullptr) if (m_param == nullptr)
{ {
fatalerror("device %s wrong parameter type for %s\n", basetag(), m_param_name); fatalerror("device %s wrong parameter type for %s\n", basetag(), m_param_name);
@ -704,7 +704,7 @@ void netlist_mame_analog_input_device::validity_helper(validity_checker &valid,
netlist::netlist_state_t &nlstate) const netlist::netlist_state_t &nlstate) const
{ {
netlist::param_t *p = nlstate.setup().find_param(pstring(m_param_name)); netlist::param_t *p = nlstate.setup().find_param(pstring(m_param_name));
auto *param = dynamic_cast<netlist::param_double_t *>(p); auto *param = dynamic_cast<netlist::param_fp_t *>(p);
if (param == nullptr) if (param == nullptr)
{ {
osd_printf_warning("device %s wrong parameter type for %s\n", basetag(), m_param_name); osd_printf_warning("device %s wrong parameter type for %s\n", basetag(), m_param_name);

View File

@ -16,33 +16,33 @@ namespace netlist
{ {
namespace analog namespace analog
{ {
using constants = plib::constants<nl_double>; using constants = plib::constants<nl_fptype>;
class diode class diode
{ {
public: public:
diode() : m_Is(1e-15), m_VT(0.0258), m_VT_inv(1.0 / m_VT) {} diode() : m_Is(1e-15), m_VT(0.0258), m_VT_inv(1.0 / m_VT) {}
diode(const nl_double Is, const nl_double n) diode(const nl_fptype Is, const nl_fptype n)
{ {
m_Is = Is; m_Is = Is;
m_VT = 0.0258 * n; m_VT = 0.0258 * n;
m_VT_inv = 1.0 / m_VT; m_VT_inv = 1.0 / m_VT;
} }
void set(const nl_double Is, const nl_double n) void set(const nl_fptype Is, const nl_fptype n)
{ {
m_Is = Is; m_Is = Is;
m_VT = 0.0258 * n; m_VT = 0.0258 * n;
m_VT_inv = 1.0 / m_VT; m_VT_inv = 1.0 / m_VT;
} }
nl_double I(const nl_double V) const { return m_Is * std::exp(V * m_VT_inv) - m_Is; } nl_fptype I(const nl_fptype V) const { return m_Is * std::exp(V * m_VT_inv) - m_Is; }
nl_double g(const nl_double V) const { return m_Is * m_VT_inv * std::exp(V * m_VT_inv); } nl_fptype g(const nl_fptype V) const { return m_Is * m_VT_inv * std::exp(V * m_VT_inv); }
nl_double V(const nl_double I) const { return std::log1p(I / m_Is) * m_VT; } // log1p(x)=log(1.0 + x) nl_fptype V(const nl_fptype I) const { return std::log1p(I / m_Is) * m_VT; } // log1p(x)=log(1.0 + x)
nl_double gI(const nl_double I) const { return m_VT_inv * (I + m_Is); } nl_fptype gI(const nl_fptype I) const { return m_VT_inv * (I + m_Is); }
private: private:
nl_double m_Is; nl_fptype m_Is;
nl_double m_VT; nl_fptype m_VT;
nl_double m_VT_inv; nl_fptype m_VT_inv;
}; };
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -203,9 +203,9 @@ namespace analog
nld_twoterm m_RC; nld_twoterm m_RC;
nld_twoterm m_BC; nld_twoterm m_BC;
nl_double m_gB; // base conductance / switch on nl_fptype m_gB; // base conductance / switch on
nl_double m_gC; // collector conductance / switch on nl_fptype m_gC; // collector conductance / switch on
nl_double m_V; // internal voltage source nl_fptype m_V; // internal voltage source
state_var<unsigned> m_state_on; state_var<unsigned> m_state_on;
private: private:
@ -267,8 +267,8 @@ namespace analog
nld_twoterm m_D_EB; // gee, gec - gee, gce - gee, gee - gec | Ie nld_twoterm m_D_EB; // gee, gec - gee, gce - gee, gee - gec | Ie
nld_twoterm m_D_EC; // 0, -gec, -gcc, 0 | 0 nld_twoterm m_D_EC; // 0, -gec, -gcc, 0 | 0
nl_double m_alpha_f; nl_fptype m_alpha_f;
nl_double m_alpha_r; nl_fptype m_alpha_r;
NETLIB_SUBXX(analog, C) m_CJE; NETLIB_SUBXX(analog, C) m_CJE;
NETLIB_SUBXX(analog, C) m_CJC; NETLIB_SUBXX(analog, C) m_CJC;
@ -316,14 +316,14 @@ namespace analog
NETLIB_UPDATE_PARAM(QBJT_switch) NETLIB_UPDATE_PARAM(QBJT_switch)
{ {
nl_double IS = m_model.m_IS; nl_fptype IS = m_model.m_IS;
nl_double BF = m_model.m_BF; nl_fptype BF = m_model.m_BF;
nl_double NF = m_model.m_NF; nl_fptype NF = m_model.m_NF;
//nl_double VJE = m_model.dValue("VJE", 0.75); //nl_fptype VJE = m_model.dValue("VJE", 0.75);
set_qtype((m_model.type() == "NPN") ? BJT_NPN : BJT_PNP); set_qtype((m_model.type() == "NPN") ? BJT_NPN : BJT_PNP);
nl_double alpha = BF / (1.0 + BF); nl_fptype alpha = BF / (1.0 + BF);
diode d(IS, NF); diode d(IS, NF);
@ -345,14 +345,14 @@ namespace analog
NETLIB_UPDATE_TERMINALS(QBJT_switch) NETLIB_UPDATE_TERMINALS(QBJT_switch)
{ {
const nl_double m = (is_qtype( BJT_NPN) ? 1 : -1); const nl_fptype m = (is_qtype( BJT_NPN) ? 1 : -1);
const unsigned new_state = (m_RB.deltaV() * m > m_V ) ? 1 : 0; const unsigned new_state = (m_RB.deltaV() * m > m_V ) ? 1 : 0;
if (m_state_on ^ new_state) if (m_state_on ^ new_state)
{ {
const nl_double gb = new_state ? m_gB : exec().gmin(); const nl_fptype gb = new_state ? m_gB : exec().gmin();
const nl_double gc = new_state ? m_gC : exec().gmin(); const nl_fptype gc = new_state ? m_gC : exec().gmin();
const nl_double v = new_state ? m_V * m : 0; const nl_fptype v = new_state ? m_V * m : 0;
m_RB.set_G_V_I(gb, v, 0.0); m_RB.set_G_V_I(gb, v, 0.0);
m_RC.set_G_V_I(gc, 0.0, 0.0); m_RC.set_G_V_I(gc, 0.0, 0.0);
@ -395,19 +395,19 @@ namespace analog
NETLIB_UPDATE_TERMINALS(QBJT_EB) NETLIB_UPDATE_TERMINALS(QBJT_EB)
{ {
const nl_double polarity = (qtype() == BJT_NPN ? 1.0 : -1.0); const nl_fptype polarity = (qtype() == BJT_NPN ? 1.0 : -1.0);
m_gD_BE.update_diode(-m_D_EB.deltaV() * polarity); m_gD_BE.update_diode(-m_D_EB.deltaV() * polarity);
m_gD_BC.update_diode(-m_D_CB.deltaV() * polarity); m_gD_BC.update_diode(-m_D_CB.deltaV() * polarity);
const nl_double gee = m_gD_BE.G(); const nl_fptype gee = m_gD_BE.G();
const nl_double gcc = m_gD_BC.G(); const nl_fptype gcc = m_gD_BC.G();
const nl_double gec = m_alpha_r * gcc; const nl_fptype gec = m_alpha_r * gcc;
const nl_double gce = m_alpha_f * gee; const nl_fptype gce = m_alpha_f * gee;
const nl_double sIe = -m_gD_BE.I() + m_alpha_r * m_gD_BC.I(); const nl_fptype sIe = -m_gD_BE.I() + m_alpha_r * m_gD_BC.I();
const nl_double sIc = m_alpha_f * m_gD_BE.I() - m_gD_BC.I(); const nl_fptype sIc = m_alpha_f * m_gD_BE.I() - m_gD_BC.I();
const nl_double Ie = (sIe + gee * m_gD_BE.Vd() - gec * m_gD_BC.Vd()) * polarity; const nl_fptype Ie = (sIe + gee * m_gD_BE.Vd() - gec * m_gD_BC.Vd()) * polarity;
const nl_double Ic = (sIc - gce * m_gD_BE.Vd() + gcc * m_gD_BC.Vd()) * polarity; const nl_fptype Ic = (sIc - gce * m_gD_BE.Vd() + gcc * m_gD_BC.Vd()) * polarity;
// "Circuit Design", page 174 // "Circuit Design", page 174
@ -422,12 +422,12 @@ namespace analog
NETLIB_UPDATE_PARAM(QBJT_EB) NETLIB_UPDATE_PARAM(QBJT_EB)
{ {
nl_double IS = m_model.m_IS; nl_fptype IS = m_model.m_IS;
nl_double BF = m_model.m_BF; nl_fptype BF = m_model.m_BF;
nl_double NF = m_model.m_NF; nl_fptype NF = m_model.m_NF;
nl_double BR = m_model.m_BR; nl_fptype BR = m_model.m_BR;
nl_double NR = m_model.m_NR; nl_fptype NR = m_model.m_NR;
//nl_double VJE = m_model.dValue("VJE", 0.75); //nl_fptype VJE = m_model.dValue("VJE", 0.75);
set_qtype((m_model.type() == "NPN") ? BJT_NPN : BJT_PNP); set_qtype((m_model.type() == "NPN") ? BJT_NPN : BJT_PNP);

View File

@ -54,14 +54,14 @@ namespace analog
// so that G depends on un+1 only and Ieq on un only. // so that G depends on un+1 only and Ieq on un only.
// In both cases, i = G * un+1 + Ieq // In both cases, i = G * un+1 + Ieq
nl_double G(nl_double cap) const nl_fptype G(nl_fptype cap) const
{ {
//return m_h * cap + m_gmin; //return m_h * cap + m_gmin;
return m_h * 0.5 * (cap + m_c) + m_gmin; return m_h * 0.5 * (cap + m_c) + m_gmin;
//return m_h * cap + m_gmin; //return m_h * cap + m_gmin;
} }
nl_double Ieq(nl_double cap, nl_double v) const nl_fptype Ieq(nl_fptype cap, nl_fptype v) const
{ {
plib::unused_var(v); 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 + (cap - m_c) * v) ;
@ -69,20 +69,20 @@ namespace analog
//return -m_h * cap * m_v; //return -m_h * cap * m_v;
} }
void timestep(nl_double cap, nl_double v, nl_double step) void timestep(nl_fptype cap, nl_fptype v, nl_fptype step)
{ {
m_h = 1.0 / step; m_h = 1.0 / step;
m_c = cap; m_c = cap;
m_v = v; m_v = v;
} }
void setparams(nl_double gmin) { m_gmin = gmin; } void setparams(nl_fptype gmin) { m_gmin = gmin; }
private: private:
state_var<double> m_h; state_var<nl_fptype> m_h;
state_var<double> m_c; state_var<nl_fptype> m_c;
state_var<double> m_v; state_var<nl_fptype> m_v;
nl_double m_gmin; nl_fptype m_gmin;
}; };
// "Circuit simulation", page 274 // "Circuit simulation", page 274
@ -98,24 +98,24 @@ namespace analog
} }
capacitor_e type() const { return capacitor_e::CONSTANT_CAPACITY; } capacitor_e type() const { return capacitor_e::CONSTANT_CAPACITY; }
nl_double G(nl_double cap) const { return cap * m_h + m_gmin; } nl_fptype G(nl_fptype cap) const { return cap * m_h + m_gmin; }
nl_double Ieq(nl_double cap, nl_double v) const nl_fptype Ieq(nl_fptype cap, nl_fptype v) const
{ {
plib::unused_var(v); plib::unused_var(v);
return - G(cap) * m_v; return - G(cap) * m_v;
} }
void timestep(nl_double cap, nl_double v, nl_double step) void timestep(nl_fptype cap, nl_fptype v, nl_fptype step)
{ {
plib::unused_var(cap); plib::unused_var(cap);
m_h = 1.0 / step; m_h = 1.0 / step;
m_v = v; m_v = v;
} }
void setparams(nl_double gmin) { m_gmin = gmin; } void setparams(nl_fptype gmin) { m_gmin = gmin; }
private: private:
state_var<nl_double> m_h; state_var<nl_fptype> m_h;
state_var<double> m_v; state_var<nl_fptype> m_v;
nl_double m_gmin; nl_fptype m_gmin;
}; };
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -149,17 +149,17 @@ namespace analog
set_param(1e-15, 1, 1e-15, 300.0); set_param(1e-15, 1, 1e-15, 300.0);
} }
void update_diode(const nl_double nVd) void update_diode(const nl_fptype nVd)
{ {
nl_double IseVDVt(0.0); nl_fptype IseVDVt(0.0);
if (TYPE == diode_e::BIPOLAR) if (TYPE == diode_e::BIPOLAR)
{ {
//printf("%s: %g %g\n", m_name.c_str(), nVd, (double) m_Vd); //printf("%s: %g %g\n", m_name.c_str(), nVd, (nl_fptype) m_Vd);
if (nVd > m_Vcrit) if (nVd > m_Vcrit)
{ {
const nl_double d = std::min(1e100, nVd - m_Vd); const nl_fptype d = std::min(1e100, nVd - m_Vd);
const nl_double a = std::abs(d) * m_VtInv; 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 + (d < 0 ? -1.0 : 1.0) * std::log1p(a) * m_Vt;
} }
else else
@ -196,7 +196,7 @@ namespace analog
} }
} }
void set_param(const nl_double Is, const nl_double n, nl_double gmin, nl_double temp) void set_param(const nl_fptype Is, const nl_fptype n, nl_fptype gmin, nl_fptype temp)
{ {
m_Is = Is; m_Is = Is;
m_logIs = std::log(Is); m_logIs = std::log(Is);
@ -213,27 +213,27 @@ namespace analog
} }
nl_double I() const { return m_Id; } nl_fptype I() const { return m_Id; }
nl_double G() const { return m_G; } nl_fptype G() const { return m_G; }
nl_double Ieq() const { return (m_Id - m_Vd * m_G); } nl_fptype Ieq() const { return (m_Id - m_Vd * m_G); }
nl_double Vd() const { return m_Vd; } nl_fptype Vd() const { return m_Vd; }
/* owning object must save those ... */ /* owning object must save those ... */
private: private:
state_var<nl_double> m_Vd; state_var<nl_fptype> m_Vd;
state_var<nl_double> m_Id; state_var<nl_fptype> m_Id;
state_var<nl_double> m_G; state_var<nl_fptype> m_G;
nl_double m_Vt; nl_fptype m_Vt;
nl_double m_Vmin; nl_fptype m_Vmin;
nl_double m_Is; nl_fptype m_Is;
nl_double m_logIs; nl_fptype m_logIs;
nl_double m_n; nl_fptype m_n;
nl_double m_gmin; nl_fptype m_gmin;
nl_double m_VtInv; nl_fptype m_VtInv;
nl_double m_Vcrit; nl_fptype m_Vcrit;
pstring m_name; pstring m_name;
}; };

View File

@ -31,7 +31,7 @@ namespace netlist
namespace analog namespace analog
{ {
using constants = plib::constants<nl_double>; using constants = plib::constants<nl_fptype>;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// nld_FET - Base classes // nld_FET - Base classes
@ -223,7 +223,7 @@ namespace analog
m_polarity = qtype() == FET_NMOS ? 1.0 : -1.0; m_polarity = qtype() == FET_NMOS ? 1.0 : -1.0;
m_capmod = m_model.m_CAPMOD; m_capmod = m_model.m_CAPMOD;
// printf("capmod %d %g %g\n", m_capmod, (double)m_model.m_VTO, m_polarity); // printf("capmod %d %g %g\n", m_capmod, (nl_fptype)m_model.m_VTO, m_polarity);
nl_assert_always(m_capmod == 0 || m_capmod == 2, "Error: CAPMODEL invalid value for " + m_model.name()); nl_assert_always(m_capmod == 0 || m_capmod == 2, "Error: CAPMODEL invalid value for " + m_model.name());
/* /*
@ -243,7 +243,7 @@ namespace analog
m_Leff = m_model.m_L - 2 * m_model.m_LD; 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 > 0.0, "Effective Lateral diffusion would be negative for model " + m_model.name());
nl_double 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 > 0.0) ? (constants::eps_SiO2() * constants::eps_0() / m_model.m_TOX) : 0.0;
// calculate DC transconductance coefficient // calculate DC transconductance coefficient
if (m_model.m_KP > 0) if (m_model.m_KP > 0)
@ -254,7 +254,7 @@ namespace analog
m_beta = 2e-5 * m_model.m_W / m_Leff; m_beta = 2e-5 * m_model.m_W / m_Leff;
//FIXME::UT can disappear //FIXME::UT can disappear
const double Vt = constants::T0() * constants::k_b() / constants::Q_e(); const nl_fptype Vt = constants::T0() * constants::k_b() / constants::Q_e();
// calculate surface potential if not given // calculate surface potential if not given
@ -298,12 +298,12 @@ namespace analog
{ {
if (m_capmod != 0) if (m_capmod != 0)
{ {
//const nl_double Ugd = -m_DG.deltaV() * m_polarity; // Gate - Drain //const nl_nl_fptype Ugd = -m_DG.deltaV() * m_polarity; // Gate - Drain
//const nl_double Ugs = -m_SG.deltaV() * m_polarity; // Gate - Source //const nl_nl_fptype Ugs = -m_SG.deltaV() * m_polarity; // Gate - Source
const nl_double Ugd = m_Vgd; // Gate - Drain const nl_fptype Ugd = m_Vgd; // Gate - Drain
const nl_double Ugs = m_Vgs; // Gate - Source const nl_fptype Ugs = m_Vgs; // Gate - Source
const nl_double Ubs = 0.0; // Bulk - Source == 0 if connected const nl_fptype Ubs = 0.0; // Bulk - Source == 0 if connected
const nl_double Ugb = Ugs - Ubs; const nl_fptype Ugb = Ugs - Ubs;
m_cap_gb.timestep(m_Cgb, Ugb, step); m_cap_gb.timestep(m_Cgb, Ugb, step);
m_cap_gs.timestep(m_Cgs, Ugs, step); m_cap_gs.timestep(m_Cgs, Ugs, step);
@ -343,43 +343,43 @@ namespace analog
generic_capacitor<capacitor_e::VARIABLE_CAPACITY> m_cap_gs; generic_capacitor<capacitor_e::VARIABLE_CAPACITY> m_cap_gs;
generic_capacitor<capacitor_e::VARIABLE_CAPACITY> m_cap_gd; generic_capacitor<capacitor_e::VARIABLE_CAPACITY> m_cap_gd;
nl_double m_phi; nl_fptype m_phi;
nl_double m_gamma; nl_fptype m_gamma;
nl_double m_vto; nl_fptype m_vto;
nl_double m_beta; nl_fptype m_beta;
nl_double m_lambda; nl_fptype m_lambda;
/* used in capacitance calculation */ /* used in capacitance calculation */
nl_double m_Leff; nl_fptype m_Leff;
nl_double m_CoxWL; nl_fptype m_CoxWL;
nl_double m_polarity; nl_fptype m_polarity;
/* capacitance values */ /* capacitance values */
nl_double m_Cgb; nl_fptype m_Cgb;
nl_double m_Cgs; nl_fptype m_Cgs;
nl_double m_Cgd; nl_fptype m_Cgd;
int m_capmod; int m_capmod;
state_var<nl_double> m_Vgs; state_var<nl_fptype> m_Vgs;
state_var<nl_double> m_Vgd; state_var<nl_fptype> m_Vgd;
void set_cap(generic_capacitor<capacitor_e::VARIABLE_CAPACITY> cap, void set_cap(generic_capacitor<capacitor_e::VARIABLE_CAPACITY> cap,
nl_double capval, nl_double V, nl_fptype capval, nl_fptype V,
nl_double &g11, nl_double &g12, nl_double &g21, nl_double &g22, nl_fptype &g11, nl_fptype &g12, nl_fptype &g21, nl_fptype &g22,
nl_double &I1, nl_double &I2) nl_fptype &I1, nl_fptype &I2)
{ {
const nl_double I = cap.Ieq(capval, V) * m_polarity; const nl_fptype I = cap.Ieq(capval, V) * m_polarity;
const nl_double G = cap.G(capval); const nl_fptype G = cap.G(capval);
g11 += G; g12 -= G; g21 -= G; g22 += G; g11 += G; g12 -= G; g21 -= G; g22 += G;
I1 -= I; I2 += I; I1 -= I; I2 += I;
//printf("Cap: %g\n", capval); //printf("Cap: %g\n", capval);
} }
void calculate_caps(nl_double Vgs, nl_double Vgd, nl_double Vth, void calculate_caps(nl_fptype Vgs, nl_fptype Vgd, nl_fptype Vth,
nl_double &Cgs, nl_double &Cgd, nl_double &Cgb) nl_fptype &Cgs, nl_fptype &Cgd, nl_fptype &Cgb)
{ {
nl_double Vctrl = Vgs - Vth * m_polarity; nl_fptype Vctrl = Vgs - Vth * m_polarity;
// Cut off - now further differentiated into 3 different formulas // Cut off - now further differentiated into 3 different formulas
// Accumulation // Accumulation
if (Vctrl <= -m_phi) if (Vctrl <= -m_phi)
@ -403,8 +403,8 @@ namespace analog
} }
else else
{ {
const nl_double Vdsat = Vctrl; const nl_fptype Vdsat = Vctrl;
const nl_double Vds = Vgs - Vgd; const nl_fptype Vds = Vgs - Vgd;
// saturation // saturation
if (Vdsat <= Vds) if (Vdsat <= Vds)
{ {
@ -415,8 +415,8 @@ namespace analog
else else
{ {
// linear // linear
const nl_double Sqr1 = std::pow(Vdsat - Vds, 2); const nl_fptype Sqr1 = std::pow(Vdsat - Vds, 2);
const nl_double Sqr2 = std::pow(2.0 * Vdsat - Vds, 2); const nl_fptype Sqr2 = std::pow(2.0 * Vdsat - Vds, 2);
Cgb = 0; Cgb = 0;
Cgs = m_CoxWL * (1.0 - Sqr1 / Sqr2) * (2.0 / 3.0); Cgs = m_CoxWL * (1.0 - Sqr1 / Sqr2) * (2.0 / 3.0);
Cgd = m_CoxWL * (1.0 - Vdsat * Vdsat / Sqr2) * (2.0 / 3.0); Cgd = m_CoxWL * (1.0 - Vdsat * Vdsat / Sqr2) * (2.0 / 3.0);
@ -442,13 +442,13 @@ namespace analog
NETLIB_UPDATE_TERMINALS(MOSFET) NETLIB_UPDATE_TERMINALS(MOSFET)
{ {
nl_double Vgd = -m_DG.deltaV() * m_polarity; // Gate - Drain nl_fptype Vgd = -m_DG.deltaV() * m_polarity; // Gate - Drain
nl_double Vgs = -m_SG.deltaV() * m_polarity; // Gate - Source nl_fptype Vgs = -m_SG.deltaV() * m_polarity; // Gate - Source
// limit step sizes // limit step sizes
const nl_double k = 3.5; // see "Circuit Simulation", page 185 const nl_fptype k = 3.5; // see "Circuit Simulation", page 185
nl_double d = (Vgs - m_Vgs); nl_fptype d = (Vgs - m_Vgs);
Vgs = m_Vgs + 1.0/k * (d < 0 ? -1.0 : 1.0) * std::log1p(k * std::abs(d)); Vgs = m_Vgs + 1.0/k * (d < 0 ? -1.0 : 1.0) * std::log1p(k * std::abs(d));
d = (Vgd - m_Vgd); d = (Vgd - m_Vgd);
Vgd = m_Vgd + 1.0/k * (d < 0 ? -1.0 : 1.0) * std::log1p(k * std::abs(d)); Vgd = m_Vgd + 1.0/k * (d < 0 ? -1.0 : 1.0) * std::log1p(k * std::abs(d));
@ -456,10 +456,10 @@ namespace analog
m_Vgs = Vgs; m_Vgs = Vgs;
m_Vgd = Vgd; m_Vgd = Vgd;
const nl_double Vbs = 0.0; // Bulk - Source == 0 if connected const nl_fptype Vbs = 0.0; // Bulk - Source == 0 if connected
//const nl_double Vbd = m_SD.deltaV() * m_polarity; // Bulk - Drain = Source - Drain //const nl_nl_fptype Vbd = m_SD.deltaV() * m_polarity; // Bulk - Drain = Source - Drain
const nl_double Vds = Vgs - Vgd; const nl_fptype Vds = Vgs - Vgd;
const nl_double Vbd = -Vds; // Bulk - Drain = Source - Drain const nl_fptype Vbd = -Vds; // Bulk - Drain = Source - Drain
#if (!BODY_CONNECTED_TO_SOURCE) #if (!BODY_CONNECTED_TO_SOURCE)
m_D_BS.update_diode(Vbs); m_D_BS.update_diode(Vbs);
@ -471,14 +471,14 @@ namespace analog
const bool is_forward = Vds >= 0; const bool is_forward = Vds >= 0;
// calculate Vth // calculate Vth
const nl_double Vbulk = is_forward ? Vbs : Vbd; const nl_fptype Vbulk = is_forward ? Vbs : Vbd;
const nl_double 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) : 0.0;
const nl_double Vth = m_vto * m_polarity + m_gamma * (phi_m_Vbulk - std::sqrt(m_phi)); const nl_fptype Vth = m_vto * m_polarity + m_gamma * (phi_m_Vbulk - std::sqrt(m_phi));
const nl_double Vctrl = (is_forward ? Vgs : Vgd) - Vth; const nl_fptype Vctrl = (is_forward ? Vgs : Vgd) - Vth;
nl_double Ids(0), gm(0), gds(0), gmb(0); nl_fptype Ids(0), gm(0), gds(0), gmb(0);
const nl_double absVds = std::abs(Vds); const nl_fptype absVds = std::abs(Vds);
if (Vctrl <= 0.0) if (Vctrl <= 0.0)
{ {
@ -490,7 +490,7 @@ namespace analog
} }
else else
{ {
const nl_double beta = m_beta * (1.0 + m_lambda * absVds); const nl_fptype beta = m_beta * (1.0 + m_lambda * absVds);
if (Vctrl <= absVds) if (Vctrl <= absVds)
{ {
// saturation region // saturation region
@ -507,63 +507,63 @@ namespace analog
} }
// backgate transconductance // backgate transconductance
const nl_double bgtc = (phi_m_Vbulk != 0.0) ? (m_gamma / phi_m_Vbulk / 2.0) : 0.0; const nl_fptype bgtc = (phi_m_Vbulk != 0.0) ? (m_gamma / phi_m_Vbulk / 2.0) : 0.0;
gmb = gm * bgtc; gmb = gm * bgtc;
} }
// FIXME: these are needed to compute capacitance // FIXME: these are needed to compute capacitance
// nl_double Udsat = pol * std::max (Utst, 0.0); // nl_fptype Udsat = pol * std::max (Utst, 0.0);
// Uon = pol * Vth; // Uon = pol * Vth;
// compute bulk diode equivalent currents // compute bulk diode equivalent currents
const nl_double IeqBD = m_D_BD.Ieq(); const nl_fptype IeqBD = m_D_BD.Ieq();
const nl_double gbd = m_D_BD.G(); const nl_fptype gbd = m_D_BD.G();
#if (!BODY_CONNECTED_TO_SOURCE) #if (!BODY_CONNECTED_TO_SOURCE)
const nl_double IeqBS = m_D_BS.Ieq(); const nl_fptype IeqBS = m_D_BS.Ieq();
const nl_double gbs = m_D_BS.G(); const nl_fptype gbs = m_D_BS.G();
#else #else
const nl_double IeqBS = 0.0; const nl_fptype IeqBS = 0.0;
const nl_double gbs = 0.0; const nl_fptype gbs = 0.0;
#endif #endif
// exchange controlling nodes if necessary // exchange controlling nodes if necessary
const nl_double gsource = is_forward ? (gm + gmb) : 0; const nl_fptype gsource = is_forward ? (gm + gmb) : 0;
const nl_double gdrain = is_forward ? 0.0 : (gm + gmb); const nl_fptype gdrain = is_forward ? 0.0 : (gm + gmb);
const nl_double IeqDS = (is_forward) ? const nl_fptype IeqDS = (is_forward) ?
Ids - gm * Vgs - gmb * Vbs - gds * Vds Ids - gm * Vgs - gmb * Vbs - gds * Vds
: -Ids - gm * Vgd - gmb * Vbd - gds * Vds; : -Ids - gm * Vgd - gmb * Vbd - gds * Vds;
// IG = 0 // IG = 0
nl_double IG = 0.0; nl_fptype IG = 0.0;
nl_double ID = (+IeqBD - IeqDS) * m_polarity; nl_fptype ID = (+IeqBD - IeqDS) * m_polarity;
nl_double IS = (+IeqBS + IeqDS) * m_polarity; nl_fptype IS = (+IeqBS + IeqDS) * m_polarity;
nl_double IB = (-IeqBD - IeqBS) * m_polarity; nl_fptype IB = (-IeqBD - IeqBS) * m_polarity;
nl_double gGG = 0.0; nl_fptype gGG = 0.0;
nl_double gGD = 0.0; nl_fptype gGD = 0.0;
nl_double gGS = 0.0; nl_fptype gGS = 0.0;
nl_double gGB = 0.0; nl_fptype gGB = 0.0;
nl_double gDG = gm; nl_fptype gDG = gm;
nl_double gDD = gds + gbd - gdrain; nl_fptype gDD = gds + gbd - gdrain;
const nl_double gDS = -gds - gsource; const nl_fptype gDS = -gds - gsource;
const nl_double gDB = gmb - gbd; const nl_fptype gDB = gmb - gbd;
nl_double gSG = -gm; nl_fptype gSG = -gm;
const nl_double gSD = -gds + gdrain; const nl_fptype gSD = -gds + gdrain;
nl_double gSS = gbs + gds + gsource; nl_fptype gSS = gbs + gds + gsource;
const nl_double gSB = -gbs - gmb; const nl_fptype gSB = -gbs - gmb;
nl_double gBG = 0.0; nl_fptype gBG = 0.0;
const nl_double gBD = -gbd; const nl_fptype gBD = -gbd;
const nl_double gBS = -gbs; const nl_fptype gBS = -gbs;
nl_double gBB = gbs + gbd; nl_fptype gBB = gbs + gbd;
if (m_capmod != 0) if (m_capmod != 0)
{ {
const nl_double Vgb = Vgs - Vbs; const nl_fptype Vgb = Vgs - Vbs;
if (is_forward) if (is_forward)
calculate_caps(Vgs, Vgd, Vth, m_Cgs, m_Cgd, m_Cgb); calculate_caps(Vgs, Vgd, Vth, m_Cgs, m_Cgd, m_Cgb);
@ -576,7 +576,7 @@ namespace analog
} }
// Source connected to body, Diode S-B shorted! // Source connected to body, Diode S-B shorted!
const nl_double gSSBB = gSS + gBB + gBS + gSB; const nl_fptype gSSBB = gSS + gBB + gBS + gSB;
// S G // S G
m_SG.set_mat( gSSBB, gSG + gBG, +(IS + IB), // S m_SG.set_mat( gSSBB, gSG + gBG, +(IS + IB), // S

View File

@ -197,9 +197,9 @@ namespace netlist
NETLIB_UPDATE(opamp) NETLIB_UPDATE(opamp)
{ {
const double cVt = 0.0258 * 1.0; // * m_n; const nl_fptype cVt = 0.0258 * 1.0; // * m_n;
const double cId = m_model.m_DAB; // 3 mA const nl_fptype cId = m_model.m_DAB; // 3 mA
const double cVd = cVt * std::log(cId / 1e-15 + 1.0); const nl_fptype cVd = cVt * std::log(cId / 1e-15 + 1.0);
m_VH.push(m_VCC() - m_model.m_VLH - cVd); m_VH.push(m_VCC() - m_model.m_VLH - cVd);
m_VL.push(m_GND() + m_model.m_VLL + cVd); m_VL.push(m_GND() + m_model.m_VLL + cVd);
@ -212,16 +212,16 @@ namespace netlist
if (m_type == 1) if (m_type == 1)
{ {
double RO = m_model.m_RO; nl_fptype RO = m_model.m_RO;
double G = m_model.m_UGF / m_model.m_FPF / RO; nl_fptype G = m_model.m_UGF / m_model.m_FPF / RO;
m_RP.set_R(RO); m_RP.set_R(RO);
m_G1.m_G.setTo(G); m_G1.m_G.setTo(G);
} }
if (m_type == 3 || m_type == 2) if (m_type == 3 || m_type == 2)
{ {
double CP = m_model.m_DAB / m_model.m_SLEW; nl_fptype CP = m_model.m_DAB / m_model.m_SLEW;
double RP = 0.5 / constants::pi() / CP / m_model.m_FPF; nl_fptype RP = 0.5 / constants::pi() / CP / m_model.m_FPF;
double G = m_model.m_UGF / m_model.m_FPF / RP; 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); //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 / (4.0 * constants::pi() * 0.0258) < m_model.m_UGF)

View File

@ -53,15 +53,15 @@
#warning "Do not include rescap.h in a netlist environment" #warning "Do not include rescap.h in a netlist environment"
#endif #endif
#ifndef RES_R #ifndef RES_R
#define RES_R(res) (static_cast<double>(res)) #define RES_R(res) (static_cast<nl_fptype>(res))
#define RES_K(res) (static_cast<double>(res) * 1e3) #define RES_K(res) (static_cast<nl_fptype>(res) * 1e3)
#define RES_M(res) (static_cast<double>(res) * 1e6) #define RES_M(res) (static_cast<nl_fptype>(res) * 1e6)
#define CAP_U(cap) (static_cast<double>(cap) * 1e-6) #define CAP_U(cap) (static_cast<nl_fptype>(cap) * 1e-6)
#define CAP_N(cap) (static_cast<double>(cap) * 1e-9) #define CAP_N(cap) (static_cast<nl_fptype>(cap) * 1e-9)
#define CAP_P(cap) (static_cast<double>(cap) * 1e-12) #define CAP_P(cap) (static_cast<nl_fptype>(cap) * 1e-12)
#define IND_U(ind) (static_cast<double>(ind) * 1e-6) #define IND_U(ind) (static_cast<nl_fptype>(ind) * 1e-6)
#define IND_N(ind) (static_cast<double>(ind) * 1e-9) #define IND_N(ind) (static_cast<nl_fptype>(ind) * 1e-9)
#define IND_P(ind) (static_cast<double>(ind) * 1e-12) #define IND_P(ind) (static_cast<nl_fptype>(ind) * 1e-12)
#endif #endif
#endif /* NLD_TWOTERM_H_ */ #endif /* NLD_TWOTERM_H_ */

View File

@ -23,17 +23,17 @@ namespace netlist
NETLIB_RESET(VCCS) NETLIB_RESET(VCCS)
{ {
const nl_double m_mult = m_G() * m_gfac; // 1.0 ==> 1V ==> 1A const nl_fptype m_mult = m_G() * m_gfac; // 1.0 ==> 1V ==> 1A
const nl_double GI = plib::constants<nl_double>::one() / m_RI(); const nl_fptype GI = plib::constants<nl_fptype>::one() / m_RI();
m_IP.set_conductivity(GI); m_IP.set_conductivity(GI);
m_IN.set_conductivity(GI); m_IN.set_conductivity(GI);
m_OP.set_go_gt(-m_mult, plib::constants<nl_double>::zero()); m_OP.set_go_gt(-m_mult, plib::constants<nl_fptype>::zero());
m_OP1.set_go_gt(m_mult, plib::constants<nl_double>::zero()); m_OP1.set_go_gt(m_mult, plib::constants<nl_fptype>::zero());
m_ON.set_go_gt(m_mult, plib::constants<nl_double>::zero()); m_ON.set_go_gt(m_mult, plib::constants<nl_fptype>::zero());
m_ON1.set_go_gt(-m_mult, plib::constants<nl_double>::zero()); m_ON1.set_go_gt(-m_mult, plib::constants<nl_fptype>::zero());
} }
NETLIB_UPDATE(VCCS) NETLIB_UPDATE(VCCS)
@ -65,25 +65,25 @@ NETLIB_UPDATE_PARAM(LVCCS)
NETLIB_UPDATE_TERMINALS(LVCCS) NETLIB_UPDATE_TERMINALS(LVCCS)
{ {
const nl_double m_mult = m_G() * m_gfac; // 1.0 ==> 1V ==> 1A const nl_fptype m_mult = m_G() * m_gfac; // 1.0 ==> 1V ==> 1A
const nl_double vi = m_IP.net().Q_Analog() - m_IN.net().Q_Analog(); const nl_fptype vi = m_IP.net().Q_Analog() - m_IN.net().Q_Analog();
if (std::abs(m_mult / m_cur_limit() * vi) > 0.5) if (std::abs(m_mult / m_cur_limit() * vi) > 0.5)
m_vi = m_vi + 0.2*std::tanh((vi - m_vi)/0.2); m_vi = m_vi + 0.2*std::tanh((vi - m_vi)/0.2);
else else
m_vi = vi; m_vi = vi;
const nl_double x = m_mult / m_cur_limit() * m_vi; const nl_fptype x = m_mult / m_cur_limit() * m_vi;
const nl_double X = std::tanh(x); const nl_fptype X = std::tanh(x);
const nl_double beta = m_mult * (1.0 - X*X); const nl_fptype beta = m_mult * (1.0 - X*X);
const nl_double I = m_cur_limit() * X - beta * m_vi; const nl_fptype I = m_cur_limit() * X - beta * m_vi;
m_OP.set_go_gt_I(-beta, plib::constants<nl_double>::zero(), I); m_OP.set_go_gt_I(-beta, plib::constants<nl_fptype>::zero(), I);
m_OP1.set_go_gt(beta, plib::constants<nl_double>::zero()); m_OP1.set_go_gt(beta, plib::constants<nl_fptype>::zero());
m_ON.set_go_gt_I(beta, plib::constants<nl_double>::zero(), -I); m_ON.set_go_gt_I(beta, plib::constants<nl_fptype>::zero(), -I);
m_ON1.set_go_gt(-beta, plib::constants<nl_double>::zero()); m_ON1.set_go_gt(-beta, plib::constants<nl_fptype>::zero());
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
@ -106,11 +106,11 @@ NETLIB_UPDATE_PARAM(CCCS)
NETLIB_RESET(VCVS) NETLIB_RESET(VCVS)
{ {
m_gfac = plib::constants<nl_double>::one() / m_RO(); m_gfac = plib::constants<nl_fptype>::one() / m_RO();
NETLIB_NAME(VCCS)::reset(); NETLIB_NAME(VCCS)::reset();
m_OP2.set_conductivity(plib::constants<nl_double>::one() / m_RO()); m_OP2.set_conductivity(plib::constants<nl_fptype>::one() / m_RO());
m_ON2.set_conductivity(plib::constants<nl_double>::one() / m_RO()); m_ON2.set_conductivity(plib::constants<nl_fptype>::one() / m_RO());
} }
} //namespace analog } //namespace analog

View File

@ -51,13 +51,13 @@ namespace netlist {
{ {
connect(m_OP, m_OP1); connect(m_OP, m_OP1);
connect(m_ON, m_ON1); connect(m_ON, m_ON1);
m_gfac = plib::constants<nl_double>::one(); m_gfac = plib::constants<nl_fptype>::one();
} }
NETLIB_RESETI(); NETLIB_RESETI();
param_double_t m_G; param_fp_t m_G;
param_double_t m_RI; param_fp_t m_RI;
protected: protected:
NETLIB_UPDATEI(); NETLIB_UPDATEI();
@ -76,7 +76,7 @@ namespace netlist {
terminal_t m_OP1; terminal_t m_OP1;
terminal_t m_ON1; terminal_t m_ON1;
nl_double m_gfac; nl_fptype m_gfac;
}; };
/* Limited Current source*/ /* Limited Current source*/
@ -99,8 +99,8 @@ namespace netlist {
NETLIB_UPDATE_TERMINALSI(); NETLIB_UPDATE_TERMINALSI();
private: private:
param_double_t m_cur_limit; /* current limit */ param_fp_t m_cur_limit; /* current limit */
nl_double m_vi; nl_fptype m_vi;
}; };
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
@ -131,7 +131,7 @@ namespace netlist {
public: public:
NETLIB_CONSTRUCTOR_DERIVED(CCCS, VCCS) NETLIB_CONSTRUCTOR_DERIVED(CCCS, VCCS)
{ {
m_gfac = plib::constants<nl_double>::one() / m_RI(); m_gfac = plib::constants<nl_fptype>::one() / m_RI();
} }
NETLIB_RESETI(); NETLIB_RESETI();
@ -184,7 +184,7 @@ namespace netlist {
NETLIB_RESETI(); NETLIB_RESETI();
param_double_t m_RO; param_fp_t m_RO;
private: private:
//NETLIB_UPDATEI(); //NETLIB_UPDATEI();

View File

@ -62,12 +62,12 @@ NETLIB_RESET(R_base)
NETLIB_RESET(POT) NETLIB_RESET(POT)
{ {
nl_double v = m_Dial(); nl_fptype v = m_Dial();
if (m_DialIsLog()) if (m_DialIsLog())
v = (std::exp(v) - 1.0) / (std::exp(1.0) - 1.0); v = (std::exp(v) - 1.0) / (std::exp(1.0) - 1.0);
m_R1.set_R(std::max(m_R() * v, exec().gmin())); m_R1.set_R(std::max(m_R() * v, exec().gmin()));
m_R2.set_R(std::max(m_R() * (plib::constants<nl_double>::one() - v), exec().gmin())); m_R2.set_R(std::max(m_R() * (plib::constants<nl_fptype>::one() - v), exec().gmin()));
} }
NETLIB_UPDATE_PARAM(POT) NETLIB_UPDATE_PARAM(POT)
@ -75,13 +75,13 @@ NETLIB_UPDATE_PARAM(POT)
m_R1.solve_now(); m_R1.solve_now();
m_R2.solve_now(); m_R2.solve_now();
nl_double v = m_Dial(); nl_fptype v = m_Dial();
if (m_DialIsLog()) if (m_DialIsLog())
v = (std::exp(v) - 1.0) / (std::exp(1.0) - 1.0); v = (std::exp(v) - 1.0) / (std::exp(1.0) - 1.0);
if (m_Reverse()) if (m_Reverse())
v = 1.0 - v; v = 1.0 - v;
m_R1.set_R(std::max(m_R() * v, exec().gmin())); m_R1.set_R(std::max(m_R() * v, exec().gmin()));
m_R2.set_R(std::max(m_R() * (plib::constants<nl_double>::one() - v), exec().gmin())); m_R2.set_R(std::max(m_R() * (plib::constants<nl_fptype>::one() - v), exec().gmin()));
} }
@ -91,7 +91,7 @@ NETLIB_UPDATE_PARAM(POT)
NETLIB_RESET(POT2) NETLIB_RESET(POT2)
{ {
nl_double v = m_Dial(); nl_fptype v = m_Dial();
if (m_DialIsLog()) if (m_DialIsLog())
v = (std::exp(v) - 1.0) / (std::exp(1.0) - 1.0); v = (std::exp(v) - 1.0) / (std::exp(1.0) - 1.0);
@ -105,7 +105,7 @@ NETLIB_UPDATE_PARAM(POT2)
{ {
m_R1.solve_now(); m_R1.solve_now();
nl_double v = m_Dial(); nl_fptype v = m_Dial();
if (m_DialIsLog()) if (m_DialIsLog())
v = (std::exp(v) - 1.0) / (std::exp(1.0) - 1.0); v = (std::exp(v) - 1.0) / (std::exp(1.0) - 1.0);
@ -148,8 +148,8 @@ NETLIB_TIMESTEP(L)
NETLIB_RESET(D) NETLIB_RESET(D)
{ {
nl_double Is = m_model.m_IS; nl_fptype Is = m_model.m_IS;
nl_double n = m_model.m_N; nl_fptype n = m_model.m_N;
m_D.set_param(Is, n, exec().gmin(), constants::T0()); 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(), 0.0, m_D.Ieq());
@ -157,8 +157,8 @@ NETLIB_RESET(D)
NETLIB_UPDATE_PARAM(D) NETLIB_UPDATE_PARAM(D)
{ {
nl_double Is = m_model.m_IS; nl_fptype Is = m_model.m_IS;
nl_double n = m_model.m_N; nl_fptype n = m_model.m_N;
m_D.set_param(Is, n, exec().gmin(), constants::T0()); m_D.set_param(Is, n, exec().gmin(), constants::T0());
} }
@ -166,8 +166,8 @@ NETLIB_UPDATE_PARAM(D)
NETLIB_UPDATE_TERMINALS(D) NETLIB_UPDATE_TERMINALS(D)
{ {
m_D.update_diode(deltaV()); m_D.update_diode(deltaV());
const nl_double G = m_D.G(); const nl_fptype G = m_D.G();
const nl_double I = m_D.Ieq(); const nl_fptype I = m_D.Ieq();
set_mat( G, -G, -I, set_mat( G, -G, -I,
-G, G, I); -G, G, I);
//set(m_D.G(), 0.0, m_D.Ieq()); //set(m_D.G(), 0.0, m_D.Ieq());

View File

@ -91,20 +91,20 @@ namespace analog
void solve_later(netlist_time delay = netlist_time::quantum()); void solve_later(netlist_time delay = netlist_time::quantum());
void set_G_V_I(const nl_double G, const nl_double V, const nl_double I) void set_G_V_I(const nl_fptype G, const nl_fptype V, const nl_fptype I)
{ {
/* GO, GT, I */ /* GO, GT, I */
m_P.set_go_gt_I( -G, G, ( V) * G - I); m_P.set_go_gt_I( -G, G, ( V) * G - I);
m_N.set_go_gt_I( -G, G, ( -V) * G + I); m_N.set_go_gt_I( -G, G, ( -V) * G + I);
} }
nl_double deltaV() const nl_fptype deltaV() const
{ {
return m_P.net().Q_Analog() - m_N.net().Q_Analog(); return m_P.net().Q_Analog() - m_N.net().Q_Analog();
} }
void set_mat(const nl_double a11, const nl_double a12, const nl_double rhs1, void set_mat(const nl_fptype a11, const nl_fptype a12, const nl_fptype rhs1,
const nl_double a21, const nl_double a22, const nl_double rhs2) const nl_fptype a21, const nl_fptype a22, const nl_fptype rhs2)
{ {
/* GO, GT, I */ /* GO, GT, I */
m_P.set_go_gt_I(a12, a11, rhs1); m_P.set_go_gt_I(a12, a11, rhs1);
@ -125,9 +125,9 @@ namespace analog
{ {
} }
void set_R(const nl_double R) void set_R(const nl_fptype R)
{ {
const nl_double G = plib::constants<nl_double>::one() / R; const nl_fptype G = plib::constants<nl_fptype>::one() / R;
set_mat( G, -G, 0.0, set_mat( G, -G, 0.0,
-G, G, 0.0); -G, G, 0.0);
} }
@ -163,7 +163,7 @@ namespace analog
} }
private: private:
param_double_t m_R; param_fp_t m_R;
/* protect set_R ... it's a recipe to desaster when used to bypass the parameter */ /* protect set_R ... it's a recipe to desaster when used to bypass the parameter */
using NETLIB_NAME(R_base)::set_R; using NETLIB_NAME(R_base)::set_R;
}; };
@ -198,8 +198,8 @@ namespace analog
NETLIB_SUB(R_base) m_R1; NETLIB_SUB(R_base) m_R1;
NETLIB_SUB(R_base) m_R2; NETLIB_SUB(R_base) m_R2;
param_double_t m_R; param_fp_t m_R;
param_double_t m_Dial; param_fp_t m_Dial;
param_logic_t m_DialIsLog; param_logic_t m_DialIsLog;
param_logic_t m_Reverse; param_logic_t m_Reverse;
}; };
@ -225,8 +225,8 @@ namespace analog
private: private:
NETLIB_SUB(R_base) m_R1; NETLIB_SUB(R_base) m_R1;
param_double_t m_R; param_fp_t m_R;
param_double_t m_Dial; param_fp_t m_Dial;
param_logic_t m_DialIsLog; param_logic_t m_DialIsLog;
param_logic_t m_Reverse; param_logic_t m_Reverse;
}; };
@ -250,8 +250,8 @@ namespace analog
m_cap.timestep(m_C(), deltaV(), step); m_cap.timestep(m_C(), deltaV(), step);
if (m_cap.type() == capacitor_e::CONSTANT_CAPACITY) if (m_cap.type() == capacitor_e::CONSTANT_CAPACITY)
{ {
const nl_double I = m_cap.Ieq(m_C(), deltaV()); const nl_fptype I = m_cap.Ieq(m_C(), deltaV());
const nl_double G = m_cap.G(m_C()); const nl_fptype G = m_cap.G(m_C());
set_mat( G, -G, -I, set_mat( G, -G, -I,
-G, G, I); -G, G, I);
} }
@ -260,13 +260,13 @@ namespace analog
NETLIB_IS_DYNAMIC(m_cap.type() == capacitor_e::VARIABLE_CAPACITY) NETLIB_IS_DYNAMIC(m_cap.type() == capacitor_e::VARIABLE_CAPACITY)
NETLIB_UPDATE_TERMINALSI() NETLIB_UPDATE_TERMINALSI()
{ {
const nl_double I = m_cap.Ieq(m_C(), deltaV()); const nl_fptype I = m_cap.Ieq(m_C(), deltaV());
const nl_double G = m_cap.G(m_C()); const nl_fptype G = m_cap.G(m_C());
set_mat( G, -G, -I, set_mat( G, -G, -I,
-G, G, I); -G, G, I);
} }
param_double_t m_C; param_fp_t m_C;
NETLIB_RESETI() NETLIB_RESETI()
{ {
m_cap.setparams(exec().gmin()); m_cap.setparams(exec().gmin());
@ -307,11 +307,11 @@ namespace analog
NETLIB_UPDATE_PARAMI(); NETLIB_UPDATE_PARAMI();
private: private:
param_double_t m_L; param_fp_t m_L;
nl_double m_gmin; nl_fptype m_gmin;
nl_double m_G; nl_fptype m_G;
nl_double m_I; nl_fptype m_I;
}; };
/*! Class representing the diode model paramers. /*! Class representing the diode model paramers.
@ -426,12 +426,12 @@ namespace analog
} }
private: private:
state_var<double> m_t; state_var<nl_fptype> m_t;
param_double_t m_R; param_fp_t m_R;
param_double_t m_V; param_fp_t m_V;
param_str_t m_func; param_str_t m_func;
plib::pfunction m_compiled; plib::pfunction m_compiled;
std::vector<double> m_funcparam; std::vector<nl_fptype> m_funcparam;
}; };
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -459,7 +459,7 @@ namespace analog
{ {
m_t += step; m_t += step;
m_funcparam[0] = m_t; m_funcparam[0] = m_t;
const double I = m_compiled.evaluate(m_funcparam); const nl_fptype I = m_compiled.evaluate(m_funcparam);
set_mat(0.0, 0.0, -I, set_mat(0.0, 0.0, -I,
0.0, 0.0, I); 0.0, 0.0, I);
} }
@ -483,11 +483,11 @@ namespace analog
private: private:
state_var<double> m_t; state_var<nl_fptype> m_t;
param_double_t m_I; param_fp_t m_I;
param_str_t m_func; param_str_t m_func;
plib::pfunction m_compiled; plib::pfunction m_compiled;
std::vector<double> m_funcparam; std::vector<nl_fptype> m_funcparam;
}; };

View File

@ -34,35 +34,35 @@ namespace netlist
analog::NETLIB_SUB(R_base) m_R; analog::NETLIB_SUB(R_base) m_R;
analog_input_t m_control; analog_input_t m_control;
param_double_t m_base_r; param_fp_t m_base_r;
}; };
NETLIB_RESET(CD4066_GATE) NETLIB_RESET(CD4066_GATE)
{ {
// Start in off condition // Start in off condition
// FIXME: is ROFF correct? // FIXME: is ROFF correct?
m_R.set_R(plib::constants<nl_double>::one() / exec().gmin()); m_R.set_R(plib::constants<nl_fptype>::one() / exec().gmin());
} }
NETLIB_UPDATE(CD4066_GATE) NETLIB_UPDATE(CD4066_GATE)
{ {
nl_double sup = (m_supply.VCC() - m_supply.GND()); nl_fptype sup = (m_supply.VCC() - m_supply.GND());
nl_double low = plib::constants<nl_double>::cast(0.45) * sup; nl_fptype low = plib::constants<nl_fptype>::cast(0.45) * sup;
nl_double high = plib::constants<nl_double>::cast(0.55) * sup; nl_fptype high = plib::constants<nl_fptype>::cast(0.55) * sup;
nl_double in = m_control() - m_supply.GND(); nl_fptype in = m_control() - m_supply.GND();
nl_double rON = m_base_r() * plib::constants<nl_double>::cast(5.0) / sup; nl_fptype rON = m_base_r() * plib::constants<nl_fptype>::cast(5.0) / sup;
nl_double R = -1.0; nl_fptype R = -1.0;
if (in < low) if (in < low)
{ {
R = plib::constants<nl_double>::one() / exec().gmin(); R = plib::constants<nl_fptype>::one() / exec().gmin();
} }
else if (in > high) else if (in > high)
{ {
R = rON; R = rON;
} }
if (R > plib::constants<nl_double>::zero()) if (R > plib::constants<nl_fptype>::zero())
{ {
m_R.update(); m_R.update();
m_R.set_R(R); m_R.set_R(R);

View File

@ -33,12 +33,12 @@ namespace netlist { namespace devices {
logic_input_t m_S; logic_input_t m_S;
logic_input_t m_E; logic_input_t m_E;
param_double_t m_base_r; param_fp_t m_base_r;
}; };
NETLIB_RESET(CD4316_GATE) NETLIB_RESET(CD4316_GATE)
{ {
m_R.set_R(plib::constants<nl_double>::one() / exec().gmin()); m_R.set_R(plib::constants<nl_fptype>::one() / exec().gmin());
} }
NETLIB_UPDATE(CD4316_GATE) NETLIB_UPDATE(CD4316_GATE)
@ -47,7 +47,7 @@ namespace netlist { namespace devices {
if (m_S() && !m_E()) if (m_S() && !m_E())
m_R.set_R(m_base_r()); m_R.set_R(m_base_r());
else else
m_R.set_R(plib::constants<nl_double>::one() / exec().gmin()); m_R.set_R(plib::constants<nl_fptype>::one() / exec().gmin());
m_R.solve_later(NLTIME_FROM_NS(1)); m_R.solve_later(NLTIME_FROM_NS(1));
} }

View File

@ -74,10 +74,10 @@ namespace netlist
state_var<netlist_sig_t> m_last_trig; state_var<netlist_sig_t> m_last_trig;
state_var<unsigned> m_state; state_var<unsigned> m_state;
state_var<double> m_KP; state_var<nl_fptype> m_KP;
param_double_t m_K; param_fp_t m_K;
param_double_t m_RI; param_fp_t m_RI;
}; };
NETLIB_OBJECT(74123_dip) NETLIB_OBJECT(74123_dip)
@ -232,7 +232,7 @@ namespace netlist
if (m_state == 1) if (m_state == 1)
{ {
const nl_double vLow = m_KP * m_RP.m_R.m_P(); const nl_fptype vLow = m_KP * m_RP.m_R.m_P();
if (m_CV() < vLow) if (m_CV() < vLow)
{ {
m_RN_Q.push(0, NLTIME_FROM_NS(10)); // R_OFF m_RN_Q.push(0, NLTIME_FROM_NS(10)); // R_OFF
@ -241,7 +241,7 @@ namespace netlist
} }
if (m_state == 2) if (m_state == 2)
{ {
const nl_double vHigh = m_RP.m_R.m_P() * (1.0 - m_KP); const nl_fptype vHigh = m_RP.m_R.m_P() * (1.0 - m_KP);
if (m_CV() > vHigh) if (m_CV() > vHigh)
{ {
m_RP_Q.push(0, NLTIME_FROM_NS(10)); // R_OFF m_RP_Q.push(0, NLTIME_FROM_NS(10)); // R_OFF

View File

@ -118,7 +118,7 @@ namespace netlist
analog_input_t m_RNG; analog_input_t m_RNG;
analog_input_t m_FC; analog_input_t m_FC;
param_double_t m_CAP; param_fp_t m_CAP;
}; };
NETLIB_OBJECT(SN74LS629_dip) NETLIB_OBJECT(SN74LS629_dip)
@ -175,29 +175,29 @@ namespace netlist
{ {
{ {
// recompute // recompute
nl_double v_freq = m_FC(); nl_fptype v_freq = m_FC();
nl_double v_rng = m_RNG(); nl_fptype v_rng = m_RNG();
/* coefficients */ /* coefficients */
const nl_double k1 = 1.9904769024796283E+03; const nl_fptype k1 = 1.9904769024796283E+03;
const nl_double k2 = 1.2070059213983407E+03; const nl_fptype k2 = 1.2070059213983407E+03;
const nl_double k3 = 1.3266985579561108E+03; const nl_fptype k3 = 1.3266985579561108E+03;
const nl_double k4 = -1.5500979825922698E+02; const nl_fptype k4 = -1.5500979825922698E+02;
const nl_double k5 = 2.8184536266938172E+00; const nl_fptype k5 = 2.8184536266938172E+00;
const nl_double k6 = -2.3503421582744556E+02; const nl_fptype k6 = -2.3503421582744556E+02;
const nl_double k7 = -3.3836786704527788E+02; const nl_fptype k7 = -3.3836786704527788E+02;
const nl_double k8 = -1.3569136703258670E+02; const nl_fptype k8 = -1.3569136703258670E+02;
const nl_double k9 = 2.9914575453819188E+00; const nl_fptype k9 = 2.9914575453819188E+00;
const nl_double k10 = 1.6855569086173170E+00; const nl_fptype k10 = 1.6855569086173170E+00;
/* scale due to input resistance */ /* scale due to input resistance */
/* Polyfunctional3D_model created by zunzun.com using sum of squared absolute error */ /* Polyfunctional3D_model created by zunzun.com using sum of squared absolute error */
nl_double v_freq_2 = v_freq * v_freq; nl_fptype v_freq_2 = v_freq * v_freq;
nl_double v_freq_3 = v_freq_2 * v_freq; nl_fptype v_freq_3 = v_freq_2 * v_freq;
nl_double v_freq_4 = v_freq_3 * v_freq; nl_fptype v_freq_4 = v_freq_3 * v_freq;
nl_double freq = k1; nl_fptype freq = k1;
freq += k2 * v_freq; freq += k2 * v_freq;
freq += k3 * v_freq_2; freq += k3 * v_freq_2;
freq += k4 * v_freq_3; freq += k4 * v_freq_3;
@ -208,7 +208,7 @@ namespace netlist
freq += k9 * v_rng * v_freq_3; freq += k9 * v_rng * v_freq_3;
freq += k10 * v_rng * v_freq_4; freq += k10 * v_rng * v_freq_4;
freq *= plib::constants<nl_double>::cast(0.1e-6) / m_CAP(); freq *= plib::constants<nl_fptype>::cast(0.1e-6) / m_CAP();
// FIXME: we need a possibility to remove entries from queue ... // FIXME: we need a possibility to remove entries from queue ...
// or an exact model ... // or an exact model ...

View File

@ -31,7 +31,7 @@ namespace netlist
NETLIB_UPDATEI() NETLIB_UPDATEI()
{ {
/* use pstring::sprintf, it is a LOT faster */ /* use pstring::sprintf, it is a LOT faster */
m_writer.writeline(plib::pfmt("{1:.9} {2}").e(exec().time().as_double()).e(static_cast<double>(m_I()))); m_writer.writeline(plib::pfmt("{1:.9} {2}").e(exec().time().as_double()).e(static_cast<nl_fptype>(m_I())));
} }
NETLIB_RESETI() { } NETLIB_RESETI() { }
@ -50,7 +50,7 @@ namespace netlist
NETLIB_UPDATEI() NETLIB_UPDATEI()
{ {
m_writer.writeline(plib::pfmt("{1:.9} {2}").e(exec().time().as_double()).e(static_cast<double>(m_I() - m_I2()))); m_writer.writeline(plib::pfmt("{1:.9} {2}").e(exec().time().as_double()).e(static_cast<nl_fptype>(m_I() - m_I2())));
} }
NETLIB_RESETI() { } NETLIB_RESETI() { }

View File

@ -51,7 +51,7 @@ namespace netlist
analog_input_t m_VDD; analog_input_t m_VDD;
analog_input_t m_VGG; analog_input_t m_VGG;
analog_input_t m_VSS; analog_input_t m_VSS;
param_double_t m_FREQ; param_fp_t m_FREQ;
/* clock stage */ /* clock stage */
logic_input_t m_feedback; logic_input_t m_feedback;
@ -69,7 +69,7 @@ namespace netlist
{ {
//m_V0.initial(0.0); //m_V0.initial(0.0);
//m_RV.do_reset(); //m_RV.do_reset();
m_RV.set_G_V_I(plib::constants<nl_double>::one() / R_LOW, 0.0, 0.0); m_RV.set_G_V_I(plib::constants<nl_fptype>::one() / R_LOW, 0.0, 0.0);
m_inc = netlist_time::from_double(1.0 / m_FREQ()); m_inc = netlist_time::from_double(1.0 / m_FREQ());
if (m_FREQ() < 24000 || m_FREQ() > 56000) if (m_FREQ() < 24000 || m_FREQ() > 56000)
log().warning(MW_FREQUENCY_OUTSIDE_OF_SPECS_1(m_FREQ())); log().warning(MW_FREQUENCY_OUTSIDE_OF_SPECS_1(m_FREQ()));
@ -102,13 +102,13 @@ namespace netlist
if (state != last_state) if (state != last_state)
{ {
const nl_double R = state ? R_HIGH : R_LOW; const nl_fptype R = state ? R_HIGH : R_LOW;
const nl_double V = state ? m_VDD() : m_VSS(); const nl_fptype V = state ? m_VDD() : m_VSS();
// We only need to update the net first if this is a time stepping net // We only need to update the net first if this is a time stepping net
if (m_is_timestep) if (m_is_timestep)
m_RV.update(); m_RV.update();
m_RV.set_G_V_I(plib::constants<nl_double>::one() / R, V, plib::constants<nl_double>::zero()); m_RV.set_G_V_I(plib::constants<nl_fptype>::one() / R, V, plib::constants<nl_fptype>::zero());
m_RV.solve_later(NLTIME_FROM_NS(1)); m_RV.solve_later(NLTIME_FROM_NS(1));
} }

View File

@ -103,10 +103,10 @@ namespace netlist
state_var<bool> m_ff; state_var<bool> m_ff;
state_var<bool> m_last_reset; state_var<bool> m_last_reset;
nl_double clamp(const nl_double v, const nl_double a, const nl_double b) nl_fptype clamp(const nl_fptype v, const nl_fptype a, const nl_fptype b)
{ {
nl_double ret = v; nl_fptype ret = v;
nl_double vcc = m_R1.m_P(); nl_fptype vcc = m_R1.m_P();
if (ret > vcc - a) if (ret > vcc - a)
ret = vcc - a; ret = vcc - a;
@ -161,7 +161,7 @@ namespace netlist
} }
else else
{ {
const nl_double vt = clamp(m_R2.m_P(), 0.7, 1.4); const nl_fptype vt = clamp(m_R2.m_P(), 0.7, 1.4);
const bool bthresh = (m_THRES() > vt); 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(), 0.7, 1.4));

View File

@ -30,8 +30,8 @@ namespace netlist
//NETLIB_UPDATEI(); //NETLIB_UPDATEI();
protected: protected:
param_double_t m_VIN; param_fp_t m_VIN;
param_double_t m_R; param_fp_t m_R;
param_int_t m_num; param_int_t m_num;
param_int_t m_val; param_int_t m_val;
}; };
@ -41,8 +41,8 @@ namespace netlist
{ {
solve_now(); solve_now();
double V = m_VIN() / static_cast<double>(1 << m_num()) nl_fptype V = m_VIN() / static_cast<nl_fptype>(1 << m_num())
* static_cast<double>(m_val()); * static_cast<nl_fptype>(m_val());
this->set_G_V_I(1.0 / m_R(), V, 0.0); this->set_G_V_I(1.0 / m_R(), V, 0.0);
} }

View File

@ -85,8 +85,8 @@ namespace netlist
m_RVI.reset(); m_RVI.reset();
m_RVO.reset(); m_RVO.reset();
m_is_timestep = m_RVO.m_P.net().solver()->has_timestep_devices(); m_is_timestep = m_RVO.m_P.net().solver()->has_timestep_devices();
m_RVI.set_G_V_I(plib::constants<nl_double>::one() / m_model.m_RI, m_model.m_VI, 0.0); 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_double>::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, 0.0);
} }
NETLIB_UPDATEI() NETLIB_UPDATEI()
@ -98,7 +98,7 @@ namespace netlist
m_last_state = 0; m_last_state = 0;
if (m_is_timestep) if (m_is_timestep)
m_RVO.update(); m_RVO.update();
m_RVO.set_G_V_I(plib::constants<nl_double>::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, 0.0);
m_RVO.solve_later(); m_RVO.solve_later();
} }
} }
@ -109,7 +109,7 @@ namespace netlist
m_last_state = 1; m_last_state = 1;
if (m_is_timestep) if (m_is_timestep)
m_RVO.update(); m_RVO.update();
m_RVO.set_G_V_I(plib::constants<nl_double>::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, 0.0);
m_RVO.solve_later(); m_RVO.solve_later();
} }
} }

View File

@ -76,7 +76,7 @@ namespace netlist
if (state != m_last_state) if (state != m_last_state)
{ {
m_last_state = state; m_last_state = state;
const nl_double R = state ? m_RON() : m_ROFF(); const nl_fptype R = state ? m_RON() : m_ROFF();
// FIXME: We only need to update the net first if this is a time stepping net // FIXME: We only need to update the net first if this is a time stepping net
m_R.update(); m_R.update();

View File

@ -28,8 +28,8 @@ namespace devices
NETLIB_RESETI() {} NETLIB_RESETI() {}
public: public:
nl_double vdd() { return m_vdd(); } nl_fptype vdd() { return m_vdd(); }
nl_double vss() { return m_vss(); } nl_fptype vss() { return m_vss(); }
analog_input_t m_vdd; analog_input_t m_vdd;
analog_input_t m_vss; analog_input_t m_vss;

View File

@ -51,7 +51,7 @@ namespace netlist
{ {
nl_assert(m_logic_family != nullptr); nl_assert(m_logic_family != nullptr);
// FIXME: Variable supply voltage! // FIXME: Variable supply voltage!
double supply_V = logic_family()->fixed_V(); nl_fptype supply_V = logic_family()->fixed_V();
if (supply_V == 0.0) supply_V = 5.0; if (supply_V == 0.0) supply_V = 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(0.0, supply_V))
@ -147,7 +147,7 @@ namespace netlist
void nld_d_to_a_proxy::reset() void nld_d_to_a_proxy::reset()
{ {
// FIXME: Variable voltage // FIXME: Variable voltage
double supply_V = logic_family()->fixed_V(); nl_fptype supply_V = logic_family()->fixed_V();
if (supply_V == 0.0) supply_V = 5.0; if (supply_V == 0.0) supply_V = 5.0;
//m_Q.initial(0.0); //m_Q.initial(0.0);
@ -159,7 +159,7 @@ namespace netlist
if (m_VCCHack) if (m_VCCHack)
m_VCCHack->initial(supply_V); m_VCCHack->initial(supply_V);
m_is_timestep = m_RN.m_P.net().solver()->has_timestep_devices(); m_is_timestep = m_RN.m_P.net().solver()->has_timestep_devices();
m_RN.set_G_V_I(plib::constants<nl_double>::one() / logic_family()->R_low(), 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(), 0.0);
m_RP.set_G_V_I(G_OFF, m_RP.set_G_V_I(G_OFF,
0.0, 0.0); 0.0, 0.0);
@ -179,12 +179,12 @@ namespace netlist
{ {
m_RN.set_G_V_I(G_OFF, m_RN.set_G_V_I(G_OFF,
0.0, 0.0); 0.0, 0.0);
m_RP.set_G_V_I(plib::constants<nl_double>::one() / logic_family()->R_high(), 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(), 0.0);
} }
else else
{ {
m_RN.set_G_V_I(plib::constants<nl_double>::one() / logic_family()->R_low(), 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(), 0.0);
m_RP.set_G_V_I(G_OFF, m_RP.set_G_V_I(G_OFF,
0.0, 0.0); 0.0, 0.0);

View File

@ -104,7 +104,7 @@ namespace netlist
private: private:
static constexpr const nl_double G_OFF = 1e-9; static constexpr const nl_fptype G_OFF = 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_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 plib::unique_ptr<analog_output_t> m_VCCHack; // FIXME: Long term, we need to connect proxy gnd to device gnd

View File

@ -79,7 +79,7 @@ namespace devices
logic_output_t m_Q; logic_output_t m_Q;
netlist_time m_inc; netlist_time m_inc;
private: private:
param_double_t m_freq; param_fp_t m_freq;
}; };
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -113,7 +113,7 @@ namespace devices
logic_input_t m_feedback; logic_input_t m_feedback;
logic_output_t m_Q; logic_output_t m_Q;
param_double_t m_freq; param_fp_t m_freq;
netlist_time m_inc; netlist_time m_inc;
}; };
@ -150,7 +150,7 @@ namespace devices
param_str_t m_func; param_str_t m_func;
plib::pfunction m_compiled; plib::pfunction m_compiled;
std::vector<double> m_funcparam; std::vector<nl_fptype> m_funcparam;
}; };
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -207,9 +207,9 @@ namespace devices
private: private:
param_double_t m_freq; param_fp_t m_freq;
param_str_t m_pattern; param_str_t m_pattern;
param_double_t m_offset; param_fp_t m_offset;
logic_input_t m_feedback; logic_input_t m_feedback;
logic_output_t m_Q; logic_output_t m_Q;
@ -260,7 +260,7 @@ namespace devices
private: private:
analog_output_t m_Q; analog_output_t m_Q;
param_double_t m_IN; param_fp_t m_IN;
}; };
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -347,8 +347,8 @@ namespace devices
analog_input_t m_I; analog_input_t m_I;
analog_output_t m_Q; analog_output_t m_Q;
param_double_t m_p_RIN; param_fp_t m_p_RIN;
param_double_t m_p_ROUT; param_fp_t m_p_ROUT;
}; };
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
@ -388,7 +388,7 @@ namespace devices
analog_output_t m_Q; analog_output_t m_Q;
std::vector<unique_pool_ptr<analog_input_t>> m_I; std::vector<unique_pool_ptr<analog_input_t>> m_I;
std::vector<double> m_vals; std::vector<nl_fptype> m_vals;
plib::pfunction m_compiled; plib::pfunction m_compiled;
}; };
@ -416,8 +416,8 @@ namespace devices
analog::NETLIB_SUB(R_base) m_R; analog::NETLIB_SUB(R_base) m_R;
logic_input_t m_I; logic_input_t m_I;
param_double_t m_RON; param_fp_t m_RON;
param_double_t m_ROFF; param_fp_t m_ROFF;
private: private:
@ -452,8 +452,8 @@ namespace devices
} }
/* FIXME: this will seg-fault if force_analog_input = false */ /* FIXME: this will seg-fault if force_analog_input = false */
nl_double VCC() const NL_NOEXCEPT { return m_VCC->Q_Analog(); } nl_fptype VCC() const NL_NOEXCEPT { return m_VCC->Q_Analog(); }
nl_double GND() const NL_NOEXCEPT { return m_GND->Q_Analog(); } nl_fptype GND() const NL_NOEXCEPT { return m_GND->Q_Analog(); }
NETLIB_SUBXX(analog, R) m_RVG; // dummy resistor between VCC and GND NETLIB_SUBXX(analog, R) m_RVG; // dummy resistor between VCC and GND

View File

@ -482,7 +482,7 @@ namespace netlist
if (stats->m_stat_inc_active() > 3 * stats->m_stat_total_time.count() if (stats->m_stat_inc_active() > 3 * stats->m_stat_total_time.count()
&& stats->m_stat_inc_active() > trigger) && stats->m_stat_inc_active() > trigger)
log().verbose("HINT({}, NO_DEACTIVATE) // {} {} {}", ep->name(), log().verbose("HINT({}, NO_DEACTIVATE) // {} {} {}", ep->name(),
static_cast<double>(stats->m_stat_inc_active()) / static_cast<double>(stats->m_stat_total_time.count()), static_cast<nl_fptype>(stats->m_stat_inc_active()) / static_cast<nl_fptype>(stats->m_stat_total_time.count()),
stats->m_stat_inc_active(), stats->m_stat_total_time.count()); stats->m_stat_inc_active(), stats->m_stat_total_time.count());
} }
} }
@ -847,7 +847,7 @@ namespace netlist
state().setup().register_term(*this); state().setup().register_term(*this);
} }
void analog_output_t::initial(const nl_double val) void analog_output_t::initial(const nl_fptype val)
{ {
net().set_Q_Analog(val); net().set_Q_Analog(val);
} }
@ -878,7 +878,7 @@ namespace netlist
{ {
if (dynamic_cast<const param_str_t *>(this) != nullptr) if (dynamic_cast<const param_str_t *>(this) != nullptr)
return STRING; return STRING;
else if (dynamic_cast<const param_double_t *>(this) != nullptr) else if (dynamic_cast<const param_fp_t *>(this) != nullptr)
return DOUBLE; return DOUBLE;
else if (dynamic_cast<const param_int_t *>(this) != nullptr) else if (dynamic_cast<const param_int_t *>(this) != nullptr)
return INTEGER; return INTEGER;
@ -938,7 +938,7 @@ namespace netlist
return state().setup().models().value_str(str(), entity); return state().setup().models().value_str(str(), entity);
} }
nl_double param_model_t::value(const pstring &entity) nl_fptype param_model_t::value(const pstring &entity)
{ {
return state().setup().models().value(str(), entity); return state().setup().models().value(str(), entity);
} }

View File

@ -115,8 +115,8 @@ class NETLIB_NAME(name) : public device_t
* NETLIB_TIMESTEPI() * NETLIB_TIMESTEPI()
* { * {
* // Gpar should support convergence * // Gpar should support convergence
* const nl_double G = m_C.Value() / step + m_GParallel; * const nl_fptype G = m_C.Value() / step + m_GParallel;
* const nl_double I = -G * deltaV(); * const nl_fptype I = -G * deltaV();
* set(G, 0.0, I); * set(G, 0.0, I);
* } * }
* *
@ -129,7 +129,7 @@ class NETLIB_NAME(name) : public device_t
* Please see NETLIB_IS_TIMESTEP for an example. * Please see NETLIB_IS_TIMESTEP for an example.
*/ */
#define NETLIB_TIMESTEPI() \ #define NETLIB_TIMESTEPI() \
public: virtual void timestep(const nl_double step) NL_NOEXCEPT override public: virtual void timestep(const nl_fptype step) NL_NOEXCEPT override
#define NETLIB_FAMILY(family) , m_famsetter(*this, family) #define NETLIB_FAMILY(family) , m_famsetter(*this, family)
@ -141,7 +141,7 @@ class NETLIB_NAME(name) : public device_t
#define NETLIB_UPDATE_PARAMI() virtual void update_param() NL_NOEXCEPT override #define NETLIB_UPDATE_PARAMI() virtual void update_param() NL_NOEXCEPT override
#define NETLIB_RESETI() virtual void reset() override #define NETLIB_RESETI() virtual void reset() override
#define NETLIB_TIMESTEP(chip) void NETLIB_NAME(chip) :: timestep(nl_double step) NL_NOEXCEPT #define NETLIB_TIMESTEP(chip) void NETLIB_NAME(chip) :: timestep(nl_fptype step) NL_NOEXCEPT
#define NETLIB_SUB(chip) nld_ ## chip #define NETLIB_SUB(chip) nld_ ## chip
#define NETLIB_SUBXX(ns, chip) unique_pool_ptr< ns :: nld_ ## chip > #define NETLIB_SUBXX(ns, chip) unique_pool_ptr< ns :: nld_ ## chip >
@ -250,21 +250,21 @@ namespace netlist
virtual unique_pool_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, virtual 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 = 0; logic_input_t *proxied) const = 0;
double fixed_V() const noexcept{ return m_fixed_V; } nl_fptype fixed_V() const noexcept{ return m_fixed_V; }
double low_thresh_V(const double VN, const double VP) const noexcept{ return VN + (VP - VN) * m_low_thresh_PCNT; } nl_fptype low_thresh_V(const nl_fptype VN, const nl_fptype VP) const noexcept{ return VN + (VP - VN) * m_low_thresh_PCNT; }
double high_thresh_V(const double VN, const double VP) const noexcept{ return VN + (VP - VN) * m_high_thresh_PCNT; } nl_fptype high_thresh_V(const nl_fptype VN, const nl_fptype VP) const noexcept{ return VN + (VP - VN) * m_high_thresh_PCNT; }
double low_offset_V() const noexcept{ return m_low_VO; } nl_fptype low_offset_V() const noexcept{ return m_low_VO; }
double high_offset_V() const noexcept{ return m_high_VO; } nl_fptype high_offset_V() const noexcept{ return m_high_VO; }
double R_low() const noexcept{ return m_R_low; } nl_fptype R_low() const noexcept{ return m_R_low; }
double R_high() const noexcept{ return m_R_high; } nl_fptype R_high() const noexcept{ return m_R_high; }
double m_fixed_V; //!< For variable voltage families, specify 0. For TTL this would be 5. */ nl_fptype m_fixed_V; //!< For variable voltage families, specify 0. For TTL this would be 5. */
double m_low_thresh_PCNT; //!< low input threshhold offset. If the input voltage is below this value times supply voltage, a "0" input is signalled nl_fptype m_low_thresh_PCNT; //!< low input threshhold offset. If the input voltage is below this value times supply voltage, a "0" input is signalled
double m_high_thresh_PCNT; //!< high input threshhold offset. If the input voltage is above the value times supply voltage, a "0" input is signalled nl_fptype m_high_thresh_PCNT; //!< high input threshhold offset. If the input voltage is above the value times supply voltage, a "0" input is signalled
double m_low_VO; //!< low output voltage offset. This voltage is output if the ouput is "0" nl_fptype m_low_VO; //!< low output voltage offset. This voltage is output if the ouput is "0"
double m_high_VO; //!< high output voltage offset. The supply voltage minus this offset is output if the ouput is "1" nl_fptype m_high_VO; //!< high output voltage offset. The supply voltage minus this offset is output if the ouput is "1"
double m_R_low; //!< low output resistance. Value of series resistor used for low output nl_fptype m_R_low; //!< low output resistance. Value of series resistor used for low output
double m_R_high; //!< high output resistance. Value of series resistor used for high output nl_fptype m_R_high; //!< high output resistance. Value of series resistor used for high output
}; };
/*! Base class for devices, terminals, outputs and inputs which support /*! Base class for devices, terminals, outputs and inputs which support
@ -761,19 +761,19 @@ namespace netlist
terminal_t(core_device_t &dev, const pstring &aname, terminal_t *otherterm); terminal_t(core_device_t &dev, const pstring &aname, terminal_t *otherterm);
nl_double operator ()() const NL_NOEXCEPT; nl_fptype operator ()() const NL_NOEXCEPT;
void set_conductivity(const nl_double G) noexcept void set_conductivity(const nl_fptype G) noexcept
{ {
set_go_gt_I(-G, G, 0.0); set_go_gt_I(-G, G, 0.0);
} }
void set_go_gt(const nl_double GO, const nl_double GT) noexcept 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, 0.0);
} }
void set_go_gt_I(const nl_double GO, const nl_double GT, const nl_double I) noexcept void set_go_gt_I(const nl_fptype GO, const nl_fptype GT, const nl_fptype I) noexcept
{ {
if (m_go1 != nullptr) if (m_go1 != nullptr)
{ {
@ -786,14 +786,14 @@ namespace netlist
void solve_now(); void solve_now();
void schedule_solve_after(const netlist_time after); void schedule_solve_after(const netlist_time after);
void set_ptrs(nl_double *gt, nl_double *go, nl_double *Idr) noexcept; void set_ptrs(nl_fptype *gt, nl_fptype *go, nl_fptype *Idr) noexcept;
terminal_t *connected_terminal() const noexcept { return m_connected_terminal; } terminal_t *connected_terminal() const noexcept { return m_connected_terminal; }
private: private:
nl_double *m_Idr1; // drive current nl_fptype *m_Idr1; // drive current
nl_double *m_go1; // conductance for Voltage from other term nl_fptype *m_go1; // conductance for Voltage from other term
nl_double *m_gt1; // conductance for total conductance nl_fptype *m_gt1; // conductance for total conductance
terminal_t *m_connected_terminal; terminal_t *m_connected_terminal;
@ -867,12 +867,12 @@ namespace netlist
/*! returns voltage at terminal. /*! returns voltage at terminal.
* \returns voltage at terminal. * \returns voltage at terminal.
*/ */
nl_double operator()() const NL_NOEXCEPT { return Q_Analog(); } nl_fptype operator()() const NL_NOEXCEPT { return Q_Analog(); }
/*! returns voltage at terminal. /*! returns voltage at terminal.
* \returns voltage at terminal. * \returns voltage at terminal.
*/ */
nl_double Q_Analog() const NL_NOEXCEPT; nl_fptype Q_Analog() const NL_NOEXCEPT;
}; };
@ -901,16 +901,16 @@ namespace netlist
analog_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *mr = nullptr); analog_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *mr = nullptr);
nl_double Q_Analog() const noexcept { return m_cur_Analog; } nl_fptype Q_Analog() const noexcept { return m_cur_Analog; }
void set_Q_Analog(const nl_double v) noexcept { m_cur_Analog = v; } void set_Q_Analog(const nl_fptype v) noexcept { m_cur_Analog = v; }
nl_double *Q_Analog_state_ptr() NL_NOEXCEPT { return m_cur_Analog.ptr(); } nl_fptype *Q_Analog_state_ptr() NL_NOEXCEPT { return m_cur_Analog.ptr(); }
//FIXME: needed by current solver code //FIXME: needed by current solver code
solver::matrix_solver_t *solver() const noexcept { return m_solver; } solver::matrix_solver_t *solver() const noexcept { return m_solver; }
void set_solver(solver::matrix_solver_t *solver) noexcept { m_solver = solver; } void set_solver(solver::matrix_solver_t *solver) noexcept { m_solver = solver; }
private: private:
state_var<nl_double> m_cur_Analog; state_var<nl_fptype> m_cur_Analog;
solver::matrix_solver_t *m_solver; solver::matrix_solver_t *m_solver;
}; };
@ -945,11 +945,11 @@ namespace netlist
public: public:
analog_output_t(core_device_t &dev, const pstring &aname); analog_output_t(core_device_t &dev, const pstring &aname);
void push(const nl_double val) NL_NOEXCEPT { set_Q(val); } void push(const nl_fptype val) NL_NOEXCEPT { set_Q(val); }
void initial(const nl_double val); void initial(const nl_fptype val);
private: private:
void set_Q(const nl_double newQ) NL_NOEXCEPT; void set_Q(const nl_fptype newQ) NL_NOEXCEPT;
analog_net_t m_my_net; analog_net_t m_my_net;
}; };
@ -1028,7 +1028,7 @@ namespace netlist
/* FIXME: these should go as well */ /* FIXME: these should go as well */
using param_logic_t = param_num_t<bool>; using param_logic_t = param_num_t<bool>;
using param_int_t = param_num_t<int>; using param_int_t = param_num_t<int>;
using param_double_t = param_num_t<double>; using param_fp_t = param_num_t<nl_fptype>;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// pointer parameter // pointer parameter
@ -1093,7 +1093,7 @@ namespace netlist
const T m_value; const T m_value;
}; };
using value_t = value_base_t<nl_double>; using value_t = value_base_t<nl_fptype>;
template <typename T> template <typename T>
friend class value_base_t; friend class value_base_t;
@ -1102,7 +1102,7 @@ namespace netlist
: param_str_t(device, name, val) { } : param_str_t(device, name, val) { }
const pstring value_str(const pstring &entity) /*const*/; const pstring value_str(const pstring &entity) /*const*/;
nl_double value(const pstring &entity) /*const*/; nl_fptype value(const pstring &entity) /*const*/;
const pstring type() /*const*/; const pstring type() /*const*/;
/* hide this */ /* hide this */
void setTo(const pstring &param) = delete; void setTo(const pstring &param) = delete;
@ -1218,7 +1218,7 @@ namespace netlist
log_type & log(); log_type & log();
public: public:
virtual void timestep(const nl_double st) NL_NOEXCEPT { plib::unused_var(st); } virtual void timestep(const nl_fptype st) NL_NOEXCEPT { plib::unused_var(st); }
virtual void update_terminals() NL_NOEXCEPT { } virtual void update_terminals() NL_NOEXCEPT { }
virtual void update_param() NL_NOEXCEPT {} virtual void update_param() NL_NOEXCEPT {}
@ -1595,7 +1595,7 @@ namespace netlist
/* force late type resolution */ /* force late type resolution */
template <typename X = devices::NETLIB_NAME(solver)> template <typename X = devices::NETLIB_NAME(solver)>
nl_double gmin(X *solv = nullptr) const NL_NOEXCEPT nl_fptype gmin(X *solv = nullptr) const NL_NOEXCEPT
{ {
plib::unused_var(solv); plib::unused_var(solv);
return static_cast<X *>(m_solver)->gmin(); return static_cast<X *>(m_solver)->gmin();
@ -1823,9 +1823,9 @@ namespace netlist
return static_cast<analog_net_t &>(core_terminal_t::net()); return static_cast<analog_net_t &>(core_terminal_t::net());
} }
inline nl_double terminal_t::operator ()() const NL_NOEXCEPT { return net().Q_Analog(); } inline nl_fptype terminal_t::operator ()() const NL_NOEXCEPT { return net().Q_Analog(); }
inline void terminal_t::set_ptrs(nl_double *gt, nl_double *go, nl_double *Idr) noexcept inline void terminal_t::set_ptrs(nl_fptype *gt, nl_fptype *go, nl_fptype *Idr) noexcept
{ {
if (!(gt && go && Idr) && (gt || go || Idr)) if (!(gt && go && Idr) && (gt || go || Idr))
state().log().fatal("Inconsistent nullptrs for terminal {}", name()); state().log().fatal("Inconsistent nullptrs for terminal {}", name());
@ -1859,12 +1859,12 @@ namespace netlist
#endif #endif
} }
inline nl_double analog_input_t::Q_Analog() const NL_NOEXCEPT inline nl_fptype analog_input_t::Q_Analog() const NL_NOEXCEPT
{ {
return net().Q_Analog(); return net().Q_Analog();
} }
inline void analog_output_t::set_Q(const nl_double newQ) NL_NOEXCEPT inline void analog_output_t::set_Q(const nl_fptype newQ) NL_NOEXCEPT
{ {
if (newQ != m_my_net.Q_Analog()) if (newQ != m_my_net.Q_Analog())
{ {

View File

@ -96,7 +96,7 @@
static constexpr const auto NETLIST_INTERNAL_RES = 1000000000; static constexpr const auto NETLIST_INTERNAL_RES = 1000000000;
static constexpr const auto NETLIST_CLOCK = NETLIST_INTERNAL_RES; static constexpr const auto NETLIST_CLOCK = NETLIST_INTERNAL_RES;
//#define nl_double float //#define nl_fptype float
using nl_double = double; using nl_fptype = double;
#endif /* NLCONFIG_H_ */ #endif /* NLCONFIG_H_ */

View File

@ -72,40 +72,40 @@ sed -e 's/#define \(.*\)"\(.*\)"[ \t]*,[ \t]*\(.*\)/NET_ALIAS(\1,\2.\3)/' src/ma
struct Mono555Desc struct Mono555Desc
{ {
public: public:
nl_double r, c; nl_fptype r, c;
Mono555Desc(nl_double res, nl_double cap) : r(res), c(cap) { } Mono555Desc(nl_fptype res, nl_fptype cap) : r(res), c(cap) { }
}; };
struct Astable555Desc struct Astable555Desc
{ {
public: public:
nl_double r1, r2, c; nl_fptype r1, r2, c;
Astable555Desc(nl_double res1, nl_double res2, nl_double cap) : r1(res1), r2(res2), c(cap) { } Astable555Desc(nl_fptype res1, nl_fptype res2, nl_fptype cap) : r1(res1), r2(res2), c(cap) { }
}; };
struct Mono9602Desc struct Mono9602Desc
{ {
public: public:
nl_double r1, c1, r2, c2; nl_fptype r1, c1, r2, c2;
Mono9602Desc(nl_double res1, nl_double cap1, nl_double res2, nl_double cap2) Mono9602Desc(nl_fptype res1, nl_fptype cap1, nl_fptype res2, nl_fptype cap2)
: r1(res1), c1(cap1), r2(res2), c2(cap2) { } : r1(res1), c1(cap1), r2(res2), c2(cap2) { }
}; };
struct SeriesRCDesc struct SeriesRCDesc
{ {
public: public:
nl_double r, c; nl_fptype r, c;
SeriesRCDesc(nl_double res, nl_double cap) : r(res), c(cap) { } SeriesRCDesc(nl_fptype res, nl_fptype cap) : r(res), c(cap) { }
}; };
struct CapacitorDesc : public SeriesRCDesc struct CapacitorDesc : public SeriesRCDesc
{ {
public: public:
CapacitorDesc(nl_double cap) : SeriesRCDesc(0.0, cap) { } CapacitorDesc(nl_fptype cap) : SeriesRCDesc(0.0, cap) { }
}; };
#else #else

View File

@ -236,9 +236,9 @@ void parser_t::frontier()
// don't do much // don't do much
pstring attachat = get_identifier(); pstring attachat = get_identifier();
require_token(m_tok_comma); require_token(m_tok_comma);
double r_IN = eval_param(get_token()); nl_fptype r_IN = eval_param(get_token());
require_token(m_tok_comma); require_token(m_tok_comma);
double r_OUT = eval_param(get_token()); nl_fptype r_OUT = eval_param(get_token());
require_token(m_tok_param_right); require_token(m_tok_param_right);
m_setup.register_frontier(attachat, r_IN, r_OUT); m_setup.register_frontier(attachat, r_IN, r_OUT);
@ -334,7 +334,7 @@ void parser_t::netdev_param()
} }
else else
{ {
nl_double val = eval_param(tok); nl_fptype val = eval_param(tok);
m_setup.log().debug("Parser: Param: {1} {2}\n", param, val); m_setup.log().debug("Parser: Param: {1} {2}\n", param, val);
m_setup.register_param(param, val); m_setup.register_param(param, val);
} }
@ -394,7 +394,7 @@ void parser_t::device(const pstring &dev_type)
} }
else else
{ {
nl_double val = eval_param(tok); nl_fptype val = eval_param(tok);
m_setup.register_param(paramfq, val); m_setup.register_param(paramfq, val);
} }
} }
@ -410,12 +410,12 @@ void parser_t::device(const pstring &dev_type)
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
nl_double parser_t::eval_param(const token_t &tok) 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<pstring, 7> macs = {"", "RES_R", "RES_K", "RES_M", "CAP_U", "CAP_N", "CAP_P"};
static std::array<nl_double, 7> facs = {1, 1, 1e3, 1e6, 1e-6, 1e-9, 1e-12}; static std::array<nl_fptype, 7> facs = {1, 1, 1e3, 1e6, 1e-6, 1e-9, 1e-12};
std::size_t f=0; std::size_t f=0;
nl_double ret(0); nl_fptype ret(0);
for (std::size_t i=1; i<macs.size();i++) for (std::size_t i=1; i<macs.size();i++)
if (tok.str() == macs[i]) if (tok.str() == macs[i])
@ -429,9 +429,9 @@ nl_double parser_t::eval_param(const token_t &tok)
else else
{ {
bool err(false); bool err(false);
ret = plib::pstonum_ne<nl_double>(tok.str(), err); ret = plib::pstonum_ne<nl_fptype>(tok.str(), err);
if (err) if (err)
error(plib::pfmt("Parameter value <{1}> not double \n")(tok.str())); error(plib::pfmt("Parameter value <{1}> not floating point \n")(tok.str()));
} }
return ret * facs[f]; return ret * facs[f];

View File

@ -48,7 +48,7 @@ namespace netlist
void verror(const pstring &msg) override; void verror(const pstring &msg) override;
private: private:
nl_double eval_param(const token_t &tok); nl_fptype eval_param(const token_t &tok);
token_id_t m_tok_param_left; token_id_t m_tok_param_left;
token_id_t m_tok_param_right; token_id_t m_tok_param_right;

View File

@ -119,7 +119,7 @@ namespace netlist
m_namespace_stack.pop(); m_namespace_stack.pop();
} }
void nlparse_t::register_param(const pstring &param, const double value) void nlparse_t::register_param(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)) > 1e-30 || std::abs(value) > 1e9)
register_param(param, plib::pfmt("{1:.9}").e(value)); register_param(param, plib::pfmt("{1:.9}").e(value));
@ -150,7 +150,7 @@ namespace netlist
m_factory.register_device(plib::make_unique<factory::library_element_t>(name, name, "", sourcefile)); m_factory.register_device(plib::make_unique<factory::library_element_t>(name, name, "", sourcefile));
} }
void nlparse_t::register_frontier(const pstring &attach, const double r_IN, const double r_OUT) void nlparse_t::register_frontier(const pstring &attach, const nl_fptype r_IN, const nl_fptype r_OUT)
{ {
pstring frontier_name = plib::pfmt("frontier_{1}")(m_frontier_cnt); pstring frontier_name = plib::pfmt("frontier_{1}")(m_frontier_cnt);
m_frontier_cnt++; m_frontier_cnt++;
@ -932,7 +932,7 @@ pstring models_t::value_str(const pstring &model, const pstring &entity)
return ret; return ret;
} }
nl_double models_t::value(const pstring &model, const pstring &entity) nl_fptype models_t::value(const pstring &model, const pstring &entity)
{ {
model_map_t &map = m_cache[model]; model_map_t &map = m_cache[model];
@ -941,7 +941,7 @@ nl_double models_t::value(const pstring &model, const pstring &entity)
pstring tmp = value_str(model, entity); pstring tmp = value_str(model, entity);
nl_double factor = plib::constants<nl_double>::one(); nl_fptype factor = plib::constants<nl_fptype>::one();
auto p = std::next(tmp.begin(), static_cast<pstring::difference_type>(tmp.size() - 1)); auto p = std::next(tmp.begin(), static_cast<pstring::difference_type>(tmp.size() - 1));
switch (*p) switch (*p)
{ {
@ -958,12 +958,12 @@ nl_double models_t::value(const pstring &model, const pstring &entity)
if (*p < '0' || *p > '9') if (*p < '0' || *p > '9')
throw nl_exception(MF_UNKNOWN_NUMBER_FACTOR_IN_1(entity)); throw nl_exception(MF_UNKNOWN_NUMBER_FACTOR_IN_1(entity));
} }
if (factor != plib::constants<nl_double>::one()) if (factor != plib::constants<nl_fptype>::one())
tmp = plib::left(tmp, tmp.size() - 1); tmp = plib::left(tmp, tmp.size() - 1);
// FIXME: check for errors // FIXME: check for errors
//printf("%s %s %e %e\n", entity.c_str(), tmp.c_str(), plib::pstonum<nl_double>(tmp), factor); //printf("%s %s %e %e\n", entity.c_str(), tmp.c_str(), plib::pstonum<nl_fptype>(tmp), factor);
bool err(false); bool err(false);
auto val = plib::pstonum_ne<nl_double>(tmp, err); auto val = plib::pstonum_ne<nl_fptype>(tmp, err);
if (err) if (err)
throw nl_exception(MF_MODEL_NUMBER_CONVERSION_ERROR(entity, tmp, "double", model)); throw nl_exception(MF_MODEL_NUMBER_CONVERSION_ERROR(entity, tmp, "double", model));
return val * factor; return val * factor;
@ -1124,7 +1124,7 @@ void setup_t::prepare_to_run()
{ {
//FIXME: check for errors ... //FIXME: check for errors ...
bool err(false); bool err(false);
auto v = plib::pstonum_ne<double>(p->second, err); 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)) > 1e-6 )
log().fatal(MF_HND_VAL_NOT_SUPPORTED(p->second)); log().fatal(MF_HND_VAL_NOT_SUPPORTED(p->second));
d.second->set_hint_deactivate(v == 0.0); d.second->set_hint_deactivate(v == 0.0);

View File

@ -212,7 +212,7 @@ namespace netlist
pstring value_str(const pstring &model, const pstring &entity); pstring value_str(const pstring &model, const pstring &entity);
nl_double value(const pstring &model, const pstring &entity); nl_fptype value(const pstring &model, const pstring &entity);
pstring type(const pstring &model) { return value_str(model, "COREMODEL"); } pstring type(const pstring &model) { return value_str(model, "COREMODEL"); }
@ -244,9 +244,9 @@ namespace netlist
void register_link(const pstring &sin, const pstring &sout); void register_link(const pstring &sin, const pstring &sout);
void register_link_arr(const pstring &terms); void register_link_arr(const pstring &terms);
void register_param(const pstring &param, const pstring &value); void register_param(const pstring &param, const pstring &value);
void register_param(const pstring &param, const double value); void register_param(const pstring &param, const nl_fptype value);
void register_lib_entry(const pstring &name, const pstring &sourcefile); void register_lib_entry(const pstring &name, const pstring &sourcefile);
void register_frontier(const pstring &attach, const double r_IN, const double r_OUT); void register_frontier(const pstring &attach, const nl_fptype r_IN, const nl_fptype r_OUT);
/* register a source */ /* register a source */
void register_source(plib::unique_ptr<plib::psource_t> &&src) void register_source(plib::unique_ptr<plib::psource_t> &&src)

View File

@ -27,12 +27,12 @@
namespace netlist namespace netlist
{ {
/*! @brief plib::constants struct specialized for nl_double /*! @brief plib::constants struct specialized for nl_fptype
* *
* This may be any of bool, uint8_t, uint16_t, uin32_t and uint64_t. * This may be any of bool, uint8_t, uint16_t, uin32_t and uint64_t.
* The choice has little to no impact on performance. * The choice has little to no impact on performance.
*/ */
using constants = plib::constants<nl_double>; using constants = plib::constants<nl_fptype>;
/*! @brief netlist_sig_t is the type used for logic signals. /*! @brief netlist_sig_t is the type used for logic signals.
* *

View File

@ -100,6 +100,7 @@ namespace plib {
pstring get_string(); pstring get_string();
pstring get_identifier(); pstring get_identifier();
pstring get_identifier_or_number(); pstring get_identifier_or_number();
double get_number_double(); double get_number_double();
long get_number_long(); long get_number_long();

View File

@ -91,7 +91,7 @@ public:
plib::option_group opt_grp3; plib::option_group opt_grp3;
plib::option_str opt_dir; plib::option_str opt_dir;
plib::option_group opt_grp4; plib::option_group opt_grp4;
plib::option_num<double> opt_ttr; plib::option_num<nl_fptype> opt_ttr;
plib::option_bool opt_stats; plib::option_bool opt_stats;
plib::option_vec opt_logs; plib::option_vec opt_logs;
plib::option_str opt_inp; plib::option_str opt_inp;
@ -311,7 +311,7 @@ struct input_t
: m_value(0.0) : m_value(0.0)
{ {
std::array<char, 400> buf; // NOLINT(cppcoreguidelines-pro-type-member-init) std::array<char, 400> buf; // NOLINT(cppcoreguidelines-pro-type-member-init)
double t(0); nl_fptype t(0);
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
int e = std::sscanf(line.c_str(), "%lf,%[^,],%lf", &t, buf.data(), &m_value); int e = std::sscanf(line.c_str(), "%lf,%[^,],%lf", &t, buf.data(), &m_value);
if (e != 3) if (e != 3)
@ -328,7 +328,7 @@ struct input_t
case netlist::param_t::POINTER: case netlist::param_t::POINTER:
throw netlist::nl_exception(plib::pfmt("param {1} is not numeric\n")(m_param->name())); throw netlist::nl_exception(plib::pfmt("param {1} is not numeric\n")(m_param->name()));
case netlist::param_t::DOUBLE: case netlist::param_t::DOUBLE:
static_cast<netlist::param_double_t*>(m_param)->setTo(m_value); static_cast<netlist::param_fp_t*>(m_param)->setTo(m_value);
break; break;
case netlist::param_t::INTEGER: case netlist::param_t::INTEGER:
static_cast<netlist::param_int_t*>(m_param)->setTo(static_cast<int>(m_value)); static_cast<netlist::param_int_t*>(m_param)->setTo(static_cast<int>(m_value));
@ -341,7 +341,7 @@ struct input_t
netlist::netlist_time m_time; netlist::netlist_time m_time;
netlist::param_t *m_param; netlist::param_t *m_param;
double m_value; nl_fptype m_value;
}; };
static std::vector<input_t> read_input(const netlist::setup_t &setup, const pstring &fname) static std::vector<input_t> read_input(const netlist::setup_t &setup, const pstring &fname)
@ -456,7 +456,7 @@ void tool_app_t::run()
nt.stop(); nt.stop();
} }
double emutime = t.as_seconds(); nl_fptype emutime = t.as_seconds();
pout("{1:f} seconds emulation took {2:f} real time ==> {3:5.2f}%\n", pout("{1:f} seconds emulation took {2:f} real time ==> {3:5.2f}%\n",
(ttr - nlt).as_double(), emutime, (ttr - nlt).as_double(), emutime,
(ttr - nlt).as_double() / emutime * 100.0); (ttr - nlt).as_double() / emutime * 100.0);

View File

@ -341,9 +341,9 @@ namespace solver
* save states * save states
*/ */
m_last_V.resize(iN, plib::constants<nl_double>::zero()); m_last_V.resize(iN, plib::constants<nl_fptype>::zero());
m_DD_n_m_1.resize(iN, plib::constants<nl_double>::zero()); m_DD_n_m_1.resize(iN, plib::constants<nl_fptype>::zero());
m_h_n_m_1.resize(iN, plib::constants<nl_double>::zero()); m_h_n_m_1.resize(iN, plib::constants<nl_fptype>::zero());
state().save(*this, m_last_V.as_base(), this->name(), "m_last_V"); state().save(*this, m_last_V.as_base(), this->name(), "m_last_V");
state().save(*this, m_DD_n_m_1.as_base(), this->name(), "m_DD_n_m_1"); state().save(*this, m_DD_n_m_1.as_base(), this->name(), "m_DD_n_m_1");
@ -411,7 +411,7 @@ namespace solver
void matrix_solver_t::step(const netlist_time &delta) void matrix_solver_t::step(const netlist_time &delta)
{ {
const nl_double dd = delta.as_double(); const nl_fptype dd = delta.as_double();
for (auto &d : m_step_devices) for (auto &d : m_step_devices)
d->timestep(dd); d->timestep(dd);
} }
@ -500,7 +500,7 @@ namespace solver
return {colmax, colmin}; return {colmax, colmin};
} }
double matrix_solver_t::get_weight_around_diag(std::size_t row, std::size_t diag) nl_fptype matrix_solver_t::get_weight_around_diag(std::size_t row, std::size_t diag)
{ {
{ {
/* /*
@ -509,7 +509,7 @@ namespace solver
std::vector<bool> touched(1024, false); // FIXME! std::vector<bool> touched(1024, false); // FIXME!
double weight = 0.0; nl_fptype weight = 0.0;
auto &term = m_terms[row]; auto &term = m_terms[row];
for (std::size_t i = 0; i < term.count(); i++) for (std::size_t i = 0; i < term.count(); i++)
{ {
@ -522,12 +522,12 @@ namespace solver
if (colu==row) colu = static_cast<unsigned>(diag); if (colu==row) colu = static_cast<unsigned>(diag);
else if (colu==diag) colu = static_cast<unsigned>(row); else if (colu==diag) colu = static_cast<unsigned>(row);
weight = weight + std::abs(static_cast<double>(colu) - static_cast<double>(diag)); weight = weight + std::abs(static_cast<nl_fptype>(colu) - static_cast<nl_fptype>(diag));
touched[colu] = true; touched[colu] = true;
} }
} }
} }
return weight; // / static_cast<double>(term.railstart()); return weight; // / static_cast<nl_fptype>(term.railstart());
} }
} }
@ -553,29 +553,29 @@ namespace solver
} }
} }
netlist_time matrix_solver_t::compute_next_timestep(const double cur_ts) netlist_time matrix_solver_t::compute_next_timestep(const nl_fptype cur_ts)
{ {
nl_double new_solver_timestep = m_params.m_max_timestep; nl_fptype new_solver_timestep = m_params.m_max_timestep;
if (m_params.m_dynamic_ts) if (m_params.m_dynamic_ts)
{ {
for (std::size_t k = 0; k < m_terms.size(); k++) for (std::size_t k = 0; k < m_terms.size(); k++)
{ {
auto &t = m_terms[k]; auto &t = m_terms[k];
//const nl_double DD_n = (n->Q_Analog() - t->m_last_V); //const nl_fptype DD_n = (n->Q_Analog() - t->m_last_V);
// avoid floating point exceptions // avoid floating point exceptions
const nl_double DD_n = std::max(-1e100, std::min(1e100,(t.getV() - m_last_V[k]))); const nl_fptype DD_n = std::max(-1e100, std::min(1e100,(t.getV() - m_last_V[k])));
const nl_double hn = cur_ts; const nl_fptype hn = cur_ts;
//printf("%g %g %g %g\n", DD_n, hn, t.m_DD_n_m_1, t.m_h_n_m_1); //printf("%g %g %g %g\n", DD_n, hn, t.m_DD_n_m_1, t.m_h_n_m_1);
nl_double DD2 = (DD_n / hn - m_DD_n_m_1[k] / m_h_n_m_1[k]) / (hn + m_h_n_m_1[k]); nl_fptype DD2 = (DD_n / hn - m_DD_n_m_1[k] / m_h_n_m_1[k]) / (hn + m_h_n_m_1[k]);
nl_double new_net_timestep(0); nl_fptype new_net_timestep(0);
m_h_n_m_1[k] = hn; m_h_n_m_1[k] = hn;
m_DD_n_m_1[k] = DD_n; m_DD_n_m_1[k] = DD_n;
if (std::fabs(DD2) > plib::constants<nl_double>::cast(1e-60)) // avoid div-by-zero if (std::fabs(DD2) > plib::constants<nl_fptype>::cast(1e-60)) // avoid div-by-zero
new_net_timestep = std::sqrt(m_params.m_dynamic_lte / std::fabs(plib::constants<nl_double>::cast(0.5)*DD2)); new_net_timestep = std::sqrt(m_params.m_dynamic_lte / std::fabs(plib::constants<nl_fptype>::cast(0.5)*DD2));
else else
new_net_timestep = m_params.m_max_timestep; new_net_timestep = m_params.m_max_timestep;
@ -607,14 +607,14 @@ namespace solver
log().verbose(" has {1} elements", this->has_dynamic_devices() ? "dynamic" : "no dynamic"); log().verbose(" has {1} elements", this->has_dynamic_devices() ? "dynamic" : "no dynamic");
log().verbose(" has {1} elements", this->has_timestep_devices() ? "timestep" : "no timestep"); log().verbose(" has {1} elements", this->has_timestep_devices() ? "timestep" : "no timestep");
log().verbose(" {1:6.3} average newton raphson loops", log().verbose(" {1:6.3} average newton raphson loops",
static_cast<double>(this->m_stat_newton_raphson) / static_cast<double>(this->m_stat_vsolver_calls)); static_cast<nl_fptype>(this->m_stat_newton_raphson) / static_cast<nl_fptype>(this->m_stat_vsolver_calls));
log().verbose(" {1:10} invocations ({2:6.0} Hz) {3:10} gs fails ({4:6.2} %) {5:6.3} average", log().verbose(" {1:10} invocations ({2:6.0} Hz) {3:10} gs fails ({4:6.2} %) {5:6.3} average",
this->m_stat_calculations, this->m_stat_calculations,
static_cast<double>(this->m_stat_calculations) / this->exec().time().as_double(), static_cast<nl_fptype>(this->m_stat_calculations) / this->exec().time().as_double(),
this->m_iterative_fail, this->m_iterative_fail,
100.0 * static_cast<double>(this->m_iterative_fail) 100.0 * static_cast<nl_fptype>(this->m_iterative_fail)
/ static_cast<double>(this->m_stat_calculations), / static_cast<nl_fptype>(this->m_stat_calculations),
static_cast<double>(this->m_iterative_total) / static_cast<double>(this->m_stat_calculations)); static_cast<nl_fptype>(this->m_iterative_total) / static_cast<nl_fptype>(this->m_stat_calculations));
} }
} }

View File

@ -61,7 +61,7 @@ namespace solver
/* automatic time step */ /* automatic time step */
, m_dynamic_ts(parent, "DYNAMIC_TS", false) , m_dynamic_ts(parent, "DYNAMIC_TS", false)
, m_dynamic_lte(parent, "DYNAMIC_LTE", 1e-5) // diff/timestep , m_dynamic_lte(parent, "DYNAMIC_LTE", 1e-5) // diff/timestep
, m_dynamic_min_ts(parent, "DYNAMIC_MIN_TIMESTEP", 1e-6) // nl_double timestep resolution , m_dynamic_min_ts(parent, "DYNAMIC_MIN_TIMESTEP", 1e-6) // nl_fptype timestep resolution
/* matrix sorting */ /* matrix sorting */
, m_sort_type(parent, "SORT_TYPE", matrix_sort_type_e::PREFER_IDENTITY_TOP_LEFT) , m_sort_type(parent, "SORT_TYPE", matrix_sort_type_e::PREFER_IDENTITY_TOP_LEFT)
@ -84,26 +84,26 @@ namespace solver
} }
} }
param_double_t m_freq; param_fp_t m_freq;
param_double_t m_gs_sor; param_fp_t m_gs_sor;
param_enum_t<matrix_type_e> m_method; param_enum_t<matrix_type_e> m_method;
param_double_t m_accuracy; param_fp_t m_accuracy;
param_num_t<std::size_t> m_gs_loops; param_num_t<std::size_t> m_gs_loops;
param_double_t m_gmin; param_fp_t m_gmin;
param_logic_t m_pivot; param_logic_t m_pivot;
param_num_t<std::size_t> m_nr_loops; param_num_t<std::size_t> m_nr_loops;
param_double_t m_nr_recalc_delay; param_fp_t m_nr_recalc_delay;
param_int_t m_parallel; param_int_t m_parallel;
param_logic_t m_dynamic_ts; param_logic_t m_dynamic_ts;
param_double_t m_dynamic_lte; param_fp_t m_dynamic_lte;
param_double_t m_dynamic_min_ts; param_fp_t m_dynamic_min_ts;
param_enum_t<matrix_sort_type_e> m_sort_type; param_enum_t<matrix_sort_type_e> m_sort_type;
param_logic_t m_use_gabs; param_logic_t m_use_gabs;
param_logic_t m_use_linear_prediction; param_logic_t m_use_linear_prediction;
nl_double m_min_timestep; nl_fptype m_min_timestep;
nl_double m_max_timestep; nl_fptype m_max_timestep;
}; };
@ -122,9 +122,9 @@ namespace solver
terminal_t **terms() noexcept { return m_terms.data(); } terminal_t **terms() noexcept { return m_terms.data(); }
nl_double getV() const noexcept { return m_net->Q_Analog(); } nl_fptype getV() const noexcept { return m_net->Q_Analog(); }
void setV(nl_double v) noexcept { m_net->set_Q_Analog(v); } void setV(nl_fptype v) noexcept { m_net->set_Q_Analog(v); }
bool isNet(const analog_net_t * net) const noexcept { return net == m_net; } bool isNet(const analog_net_t * net) const noexcept { return net == m_net; }
@ -184,7 +184,7 @@ namespace solver
public: public:
int get_net_idx(const analog_net_t *net) const noexcept; int get_net_idx(const analog_net_t *net) const noexcept;
std::pair<int, int> get_left_right_of_diag(std::size_t row, std::size_t diag); std::pair<int, int> get_left_right_of_diag(std::size_t row, std::size_t diag);
double get_weight_around_diag(std::size_t row, std::size_t diag); nl_fptype get_weight_around_diag(std::size_t row, std::size_t diag);
virtual void log_stats(); virtual void log_stats();
@ -208,7 +208,7 @@ namespace solver
virtual unsigned vsolve_non_dynamic(const bool newton_raphson) = 0; virtual unsigned vsolve_non_dynamic(const bool newton_raphson) = 0;
netlist_time compute_next_timestep(const double cur_ts); netlist_time compute_next_timestep(const nl_fptype cur_ts);
/* virtual */ void add_term(std::size_t net_idx, terminal_t *term); /* virtual */ void add_term(std::size_t net_idx, terminal_t *term);
template <typename T> template <typename T>
@ -217,11 +217,6 @@ namespace solver
template <typename T> template <typename T>
auto delta(const T & V) -> typename std::decay<decltype(V[0])>::type; auto delta(const T & V) -> typename std::decay<decltype(V[0])>::type;
template <typename T>
void build_LE_A(T &child);
template <typename T>
void build_LE_RHS(T &child);
void set_pointers() void set_pointers()
{ {
const std::size_t iN = this->m_terms.size(); const std::size_t iN = this->m_terms.size();
@ -252,13 +247,13 @@ namespace solver
} }
} }
template <typename AP, typename FT> template <typename FT>
void fill_matrix(std::size_t N, AP &tcr, FT &RHS) void fill_matrix(std::size_t N, FT &RHS)
{ {
for (std::size_t k = 0; k < N; k++) for (std::size_t k = 0; k < N; k++)
{ {
auto &net = m_terms[k]; auto &net = m_terms[k];
auto **tcr_r = &(tcr[k][0]); auto **tcr_r = &(m_mat_ptr[k][0]);
const std::size_t term_count = net.count(); const std::size_t term_count = net.count();
const std::size_t railstart = net.railstart(); const std::size_t railstart = net.railstart();
@ -350,28 +345,60 @@ namespace solver
} }
} }
template <typename M>
void clear_square_mat(std::size_t n, M &m)
{
for (std::size_t k=0; k < n; k++)
{
auto *p = &(m[k][0]);
for (std::size_t i=0; i < n; i++)
p[i] = 0.0;
}
}
template <typename M>
void build_mat_ptr(std::size_t iN, M &mat)
{
for (std::size_t k=0; k<iN; k++)
{
std::size_t cnt(0);
/* build pointers into the compressed row format matrix for each terminal */
for (std::size_t j=0; j< this->m_terms[k].railstart();j++)
{
int other = this->m_terms[k].m_connected_net_idx[j];
if (other >= 0)
{
m_mat_ptr[k][j] = &(mat[k][static_cast<std::size_t>(other)]);
cnt++;
}
}
nl_assert_always(cnt == this->m_terms[k].railstart(), "Count and railstart mismatch");
m_mat_ptr[k][this->m_terms[k].railstart()] = &(mat[k][k]);
}
}
template <typename T> template <typename T>
using aligned_alloc = plib::aligned_allocator<T, PALIGN_VECTOROPT>; using aligned_alloc = plib::aligned_allocator<T, PALIGN_VECTOROPT>;
plib::pmatrix2d<nl_double, aligned_alloc<nl_double>> m_gonn; plib::pmatrix2d<nl_fptype, aligned_alloc<nl_fptype>> m_gonn;
plib::pmatrix2d<nl_double, aligned_alloc<nl_double>> m_gtn; plib::pmatrix2d<nl_fptype, aligned_alloc<nl_fptype>> m_gtn;
plib::pmatrix2d<nl_double, aligned_alloc<nl_double>> m_Idrn; plib::pmatrix2d<nl_fptype, aligned_alloc<nl_fptype>> m_Idrn;
plib::pmatrix2d<nl_double *, aligned_alloc<nl_double *>> m_mat_ptr; plib::pmatrix2d<nl_fptype *, aligned_alloc<nl_fptype *>> m_mat_ptr;
plib::pmatrix2d<nl_double *, aligned_alloc<nl_double *>> m_connected_net_Vn; plib::pmatrix2d<nl_fptype *, aligned_alloc<nl_fptype *>> m_connected_net_Vn;
plib::aligned_vector<terms_for_net_t> m_terms; plib::aligned_vector<terms_for_net_t> m_terms;
plib::aligned_vector<terms_for_net_t> m_rails_temp; plib::aligned_vector<terms_for_net_t> m_rails_temp;
/* state - variable time_stepping */ /* state - variable time_stepping */
plib::aligned_vector<nl_double> m_last_V; plib::aligned_vector<nl_fptype> m_last_V;
plib::aligned_vector<nl_double> m_DD_n_m_1; plib::aligned_vector<nl_fptype> m_DD_n_m_1;
plib::aligned_vector<nl_double> m_h_n_m_1; plib::aligned_vector<nl_fptype> m_h_n_m_1;
// FIXME: it should be like this, however dimensions are determined // FIXME: it should be like this, however dimensions are determined
// in vsetup. // in vsetup.
//state_container<std::vector<nl_double>> m_last_V; //state_container<std::vector<nl_fptype>> m_last_V;
//state_container<std::vector<nl_double>> m_DD_n_m_1; //state_container<std::vector<nl_fptype>> m_DD_n_m_1;
//state_container<std::vector<nl_double>> m_h_n_m_1; //state_container<std::vector<nl_fptype>> m_h_n_m_1;
std::vector<unique_pool_ptr<proxied_analog_output_t>> m_inps; std::vector<unique_pool_ptr<proxied_analog_output_t>> m_inps;
@ -426,69 +453,6 @@ namespace solver
this->m_terms[i].setV(V[i]); this->m_terms[i].setV(V[i]);
} }
template <typename T>
void matrix_solver_t::build_LE_A(T &child)
{
using float_type = typename T::float_type;
static_assert(std::is_base_of<matrix_solver_t, T>::value, "T must derive from matrix_solver_t");
const std::size_t iN = child.size();
for (std::size_t k = 0; k < iN; k++)
{
terms_for_net_t &terms = m_terms[k];
float_type * Ak = &child.A(k, 0ul);
for (std::size_t i=0; i < iN; i++)
Ak[i] = 0.0;
const std::size_t terms_count = terms.count();
const std::size_t railstart = terms.railstart();
const float_type * const gt = m_gtn[k];
{
float_type akk = 0.0;
for (std::size_t i = 0; i < terms_count; i++)
akk += gt[i];
Ak[k] = akk;
}
const float_type * const go = m_gonn[k];
int * net_other = terms.m_connected_net_idx.data();
for (std::size_t i = 0; i < railstart; i++)
Ak[net_other[i]] += go[i];
}
}
template <typename T>
void matrix_solver_t::build_LE_RHS(T &child)
{
static_assert(std::is_base_of<matrix_solver_t, T>::value, "T must derive from matrix_solver_t");
using float_type = typename T::float_type;
const std::size_t iN = child.size();
for (std::size_t k = 0; k < iN; k++)
{
float_type rhsk_a = 0.0;
float_type rhsk_b = 0.0;
const std::size_t terms_count = m_terms[k].count();
const float_type * const go = m_gonn[k];
const float_type * const Idr = m_Idrn[k];
const float_type * const * other_cur_analog = m_connected_net_Vn[k];
for (std::size_t i = 0; i < terms_count; i++)
rhsk_a += Idr[i];
for (std::size_t i = m_terms[k].railstart(); i < terms_count; i++)
//rhsk = rhsk + go[i] * terms[i]->m_otherterm->net().as_analog().Q_Analog();
rhsk_b += - go[i] * *other_cur_analog[i];
child.RHS(k) = rhsk_a + rhsk_b;
}
}
} // namespace solver } // namespace solver
} // namespace netlist } // namespace netlist

View File

@ -35,7 +35,15 @@ namespace solver
void reset() override { matrix_solver_t::reset(); } void reset() override { matrix_solver_t::reset(); }
private:
const std::size_t m_dim;
const std::size_t m_pitch;
protected: protected:
static constexpr const std::size_t SIZEABS = plib::parray<FT, SIZE>::SIZEABS();
static constexpr const std::size_t m_pitch_ABS = (((SIZEABS + 0) + 7) / 8) * 8;
unsigned vsolve_non_dynamic(const bool newton_raphson) override; unsigned vsolve_non_dynamic(const bool newton_raphson) override;
unsigned solve_non_dynamic(const bool newton_raphson); unsigned solve_non_dynamic(const bool newton_raphson);
@ -46,24 +54,12 @@ namespace solver
template <typename T> template <typename T>
void LE_back_subst(T & x); void LE_back_subst(T & x);
const FT &A(std::size_t r, std::size_t c) const noexcept { return m_A[r][c]; }
FT &A(std::size_t r, std::size_t c) noexcept { return m_A[r][c]; }
const FT &RHS(std::size_t r) const noexcept { return m_A[r][size()]; }
FT &RHS(std::size_t r) noexcept { return m_A[r][size()]; }
PALIGNAS_VECTOROPT() PALIGNAS_VECTOROPT()
plib::parray<FT, SIZE> m_new_V; plib::parray<FT, SIZE> m_new_V;
private:
static constexpr const std::size_t SIZEABS = plib::parray<FT, SIZE>::SIZEABS();
static constexpr const std::size_t m_pitch_ABS = (((SIZEABS + 1) + 7) / 8) * 8;
const std::size_t m_dim;
const std::size_t m_pitch;
PALIGNAS_VECTOROPT() PALIGNAS_VECTOROPT()
plib::parray2D<FT, SIZE, m_pitch_ABS> m_A; plib::parray2D<FT, SIZE, m_pitch_ABS> m_A;
PALIGNAS_VECTOROPT()
plib::parray<FT, SIZE> m_RHS;
}; };
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
@ -79,16 +75,16 @@ namespace solver
for (std::size_t i = 0; i < kN; i++) for (std::size_t i = 0; i < kN; i++)
{ {
/* FIXME: Singular matrix? */ /* FIXME: Singular matrix? */
const FT f = 1.0 / A(i,i); const FT f = 1.0 / m_A[i][i];
const auto &nzrd = m_terms[i].m_nzrd; const auto &nzrd = m_terms[i].m_nzrd;
const auto &nzbd = m_terms[i].m_nzbd; const auto &nzbd = m_terms[i].m_nzbd;
for (auto &j : nzbd) for (auto &j : nzbd)
{ {
const FT f1 = -f * A(j, i); const FT f1 = -f * m_A[j][i];
for (auto &k : nzrd) for (auto &k : nzrd)
A(j, k) += A(i, k) * f1; m_A[j][k] += m_A[i][k] * f1;
//RHS(j) += RHS(i) * f1; m_RHS[j] += m_RHS[i] * f1;
} }
} }
} }
@ -101,7 +97,7 @@ namespace solver
for (std::size_t j = i + 1; j < kN; j++) for (std::size_t j = i + 1; j < kN; j++)
{ {
//if (std::abs(m_A[j][i]) > std::abs(m_A[maxrow][i])) //if (std::abs(m_A[j][i]) > std::abs(m_A[maxrow][i]))
if (A(j,i) * A(j,i) > A(maxrow,i) * A(maxrow,i)) if (m_A[j][i] * m_A[j][i] > m_A[maxrow][i] * m_A[maxrow][i])
maxrow = j; maxrow = j;
} }
@ -109,32 +105,28 @@ namespace solver
{ {
/* Swap the maxrow and ith row */ /* Swap the maxrow and ith row */
for (std::size_t k = 0; k < kN + 1; k++) { for (std::size_t k = 0; k < kN + 1; k++) {
std::swap(A(i,k), A(maxrow,k)); std::swap(m_A[i][k], m_A[maxrow][k]);
} }
//std::swap(RHS(i), RHS(maxrow)); //std::swap(RHS(i), RHS(maxrow));
} }
/* FIXME: Singular matrix? */ /* FIXME: Singular matrix? */
const FT f = 1.0 / A(i,i); const FT f = 1.0 / m_A[i][i];
/* Eliminate column i from row j */ /* Eliminate column i from row j */
for (std::size_t j = i + 1; j < kN; j++) for (std::size_t j = i + 1; j < kN; j++)
{ {
const FT f1 = - A(j,i) * f; const FT f1 = - m_A[j][i] * f;
if (f1 != plib::constants<FT>::zero()) if (f1 != plib::constants<FT>::zero())
{ {
const FT * pi = &A(i,i+1); const FT * pi = &(m_A[i][i+1]);
FT * pj = &A(j,i+1); FT * pj = &(m_A[j][i+1]);
#if 1 plib::vec_add_mult_scalar_p(kN-i-1,pj,pi,f1);
plib::vec_add_mult_scalar_p(kN-i,pj, pi,f1);
#else
vec_add_mult_scalar_p1(kN-i-1,pj,pi,f1);
//for (unsigned k = i+1; k < kN; k++) //for (unsigned k = i+1; k < kN; k++)
// pj[k] = pj[k] + pi[k] * f1; // pj[k] = pj[k] + pi[k] * f1;
//for (unsigned k = i+1; k < kN; k++) //for (unsigned k = i+1; k < kN; k++)
//A(j,k) += A(i,k) * f1; //A(j,k) += A(i,k) * f1;
RHS(j) += RHS(i) * f1; m_RHS[j] += m_RHS[i] * f1;
#endif
} }
} }
} }
@ -155,8 +147,8 @@ namespace solver
{ {
FT tmp = 0; FT tmp = 0;
for (std::size_t k = j+1; k < kN; k++) for (std::size_t k = j+1; k < kN; k++)
tmp += A(j,k) * x[k]; tmp += m_A[j][k] * x[k];
x[j] = (RHS(j) - tmp) / A(j,j); x[j] = (m_RHS[j] - tmp) / m_A[j][j];
} }
} }
else else
@ -165,10 +157,10 @@ namespace solver
{ {
FT tmp = 0; FT tmp = 0;
const auto &nzrd = m_terms[j].m_nzrd; const auto &nzrd = m_terms[j].m_nzrd;
const auto e = nzrd.size() - 1; /* exclude RHS element */ const auto e = nzrd.size(); // - 1; /* exclude RHS element */
for ( std::size_t k = 0; k < e; k++) for ( std::size_t k = 0; k < e; k++)
tmp += A(j, nzrd[k]) * x[nzrd[k]]; tmp += m_A[j][nzrd[k]] * x[nzrd[k]];
x[j] = (RHS(j) - tmp) / A(j,j); x[j] = (m_RHS[j] - tmp) / m_A[j][j];
} }
} }
} }
@ -187,8 +179,12 @@ namespace solver
template <typename FT, int SIZE> template <typename FT, int SIZE>
unsigned matrix_solver_direct_t<FT, SIZE>::vsolve_non_dynamic(const bool newton_raphson) unsigned matrix_solver_direct_t<FT, SIZE>::vsolve_non_dynamic(const bool newton_raphson)
{ {
this->build_LE_A(*this); const std::size_t iN = this->size();
this->build_LE_RHS(*this);
/* populate matrix */
this->clear_square_mat(iN, m_A);
this->fill_matrix(iN, m_RHS);
this->m_stat_calculations++; this->m_stat_calculations++;
return this->solve_non_dynamic(newton_raphson); return this->solve_non_dynamic(newton_raphson);
@ -200,23 +196,13 @@ namespace solver
const solver_parameters_t *params, const solver_parameters_t *params,
const std::size_t size) const std::size_t size)
: matrix_solver_t(anetlist, name, nets, params) : matrix_solver_t(anetlist, name, nets, params)
, m_new_V(size)
, m_dim(size) , m_dim(size)
, m_pitch(m_pitch_ABS ? m_pitch_ABS : (((m_dim + 1) + 7) / 8) * 8) , m_pitch(m_pitch_ABS ? m_pitch_ABS : (((m_dim + 0) + 7) / 8) * 8)
, m_new_V(size)
, m_A(size, m_pitch) , m_A(size, m_pitch)
, m_RHS(size)
{ {
/* add RHS element */ this->build_mat_ptr(size, m_A);
for (std::size_t k = 0; k < this->size(); k++)
{
terms_for_net_t & t = m_terms[k];
if (!plib::container::contains(t.m_nzrd, static_cast<unsigned>(this->size())))
t.m_nzrd.push_back(static_cast<unsigned>(this->size()));
}
// FIXME: This shouldn't be necessary ...
for (std::size_t k = 0; k < this->size(); k++)
state().save(*this, RHS(k), this->name(), plib::pfmt("RHS.{1}")(k));
} }
} // namespace solver } // namespace solver

View File

@ -34,11 +34,10 @@ namespace solver
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
unsigned vsolve_non_dynamic(const bool newton_raphson) override unsigned vsolve_non_dynamic(const bool newton_raphson) override
{ {
this->build_LE_A(*this); this->clear_square_mat(1, this->m_A);
this->build_LE_RHS(*this); this->fill_matrix(1, this->m_RHS);
//NL_VERBOSE_OUT(("{1} {2}\n", new_val, m_RHS[0] / m_A[0][0]);
std::array<FT, 1> new_V = { this->RHS(0) / this->A(0,0) }; std::array<FT, 1> new_V = { this->m_RHS[0] / this->m_A[0][0] };
const FT err = (newton_raphson ? this->delta(new_V) : 0.0); const FT err = (newton_raphson ? this->delta(new_V) : 0.0);
this->store(new_V); this->store(new_V);

View File

@ -34,16 +34,16 @@ namespace solver
{} {}
unsigned vsolve_non_dynamic(const bool newton_raphson) override unsigned vsolve_non_dynamic(const bool newton_raphson) override
{ {
this->build_LE_A(*this); this->clear_square_mat(2, this->m_A);
this->build_LE_RHS(*this); this->fill_matrix(2, this->m_RHS);
const float_type a = this->A(0,0); const float_type a = this->m_A[0][0];
const float_type b = this->A(0,1); const float_type b = this->m_A[0][1];
const float_type c = this->A(1,0); const float_type c = this->m_A[1][0];
const float_type d = this->A(1,1); const float_type d = this->m_A[1][1];
const float_type v1 = (a * this->RHS(1) - c * this->RHS(0)) / (a * d - b * c); const float_type v1 = (a * this->m_RHS[1] - c * this->m_RHS[0]) / (a * d - b * c);
const float_type v0 = (this->RHS(0) - b * v1) / a; const float_type v0 = (this->m_RHS[0] - b * v1) / a;
std::array<float_type, 2> new_V = {v0, v1}; std::array<float_type, 2> new_V = {v0, v1};
this->m_stat_calculations++; this->m_stat_calculations++;

View File

@ -90,9 +90,9 @@ namespace solver
this->log().verbose("maximum fill: {1}", gr.first); this->log().verbose("maximum fill: {1}", gr.first);
this->log().verbose("Post elimination occupancy ratio: {2} Ops: {1}", gr.second, this->log().verbose("Post elimination occupancy ratio: {2} Ops: {1}", gr.second,
static_cast<double>(mat.nz_num) / static_cast<double>(iN * iN)); static_cast<nl_fptype>(mat.nz_num) / static_cast<nl_fptype>(iN * iN));
this->log().verbose(" Pre elimination occupancy ratio: {2}", this->log().verbose(" Pre elimination occupancy ratio: {2}",
static_cast<double>(raw_elements) / static_cast<double>(iN * iN)); static_cast<nl_fptype>(raw_elements) / static_cast<nl_fptype>(iN * iN));
// FIXME: Move me // FIXME: Move me
@ -131,7 +131,7 @@ namespace solver
mat_type mat; mat_type mat;
plib::dynproc<void, double * , double * , double * > m_proc; plib::dynproc<void, nl_fptype * , nl_fptype * , nl_fptype * > m_proc;
}; };
@ -238,7 +238,7 @@ namespace solver
/* populate matrix */ /* populate matrix */
this->fill_matrix(iN, m_mat_ptr, RHS); this->fill_matrix(iN, RHS);
/* now solve it */ /* now solve it */

View File

@ -106,7 +106,7 @@ namespace solver
m_ops.m_mat.set_scalar(0.0); m_ops.m_mat.set_scalar(0.0);
/* populate matrix and V for first estimate */ /* populate matrix and V for first estimate */
this->fill_matrix(iN, this->m_mat_ptr, RHS); this->fill_matrix(iN, RHS);
for (std::size_t k = 0; k < iN; k++) for (std::size_t k = 0; k < iN; k++)
{ {

View File

@ -63,9 +63,7 @@ namespace solver
, m_dim(size) , m_dim(size)
, m_cnt(0) , m_cnt(0)
{ {
/* FIXME: Shouldn't be necessary */ this->build_mat_ptr(this->size(), m_A);
for (std::size_t k = 0; k < this->size(); k++)
state().save(*this, RHS(k), this->name(), plib::pfmt("RHS.{1}")(k));
} }
void reset() override { matrix_solver_t::reset(); } void reset() override { matrix_solver_t::reset(); }
@ -289,8 +287,10 @@ namespace solver
template <typename FT, int SIZE> template <typename FT, int SIZE>
unsigned matrix_solver_sm_t<FT, SIZE>::vsolve_non_dynamic(const bool newton_raphson) unsigned matrix_solver_sm_t<FT, SIZE>::vsolve_non_dynamic(const bool newton_raphson)
{ {
this->build_LE_A(*this);
this->build_LE_RHS(*this); const std::size_t iN = this->size();
this->clear_square_mat(iN, this->m_A);
this->fill_matrix(iN, this->m_RHS);
this->m_stat_calculations++; this->m_stat_calculations++;
return this->solve_non_dynamic(newton_raphson); return this->solve_non_dynamic(newton_raphson);

View File

@ -102,7 +102,7 @@ namespace solver
for (std::size_t i = 0; i < term_count; i++) for (std::size_t i = 0; i < term_count; i++)
gabs_t = gabs_t + std::abs(go[i]); gabs_t = gabs_t + std::abs(go[i]);
gabs_t *= plib::constants<nl_double>::cast(0.5); // derived by try and error gabs_t *= plib::constants<nl_fptype>::cast(0.5); // derived by try and error
if (gabs_t <= gtot_t) if (gabs_t <= gtot_t)
{ {
w[k] = ws / gtot_t; w[k] = ws / gtot_t;

View File

@ -117,14 +117,13 @@ namespace solver
const std::size_t iN = this->size(); const std::size_t iN = this->size();
this->build_LE_A(*this); this->clear_square_mat(iN, this->m_A);
this->build_LE_RHS(*this); this->fill_matrix(iN, this->m_RHS);
bool resched = false; bool resched = false;
unsigned resched_cnt = 0; unsigned resched_cnt = 0;
#if 0 #if 0
static int ws_cnt = 0; static int ws_cnt = 0;
ws_cnt++; ws_cnt++;
@ -174,24 +173,24 @@ namespace solver
const std::size_t e = this->m_terms[k].m_nz.size(); const std::size_t e = this->m_terms[k].m_nz.size();
for (std::size_t i = 0; i < e; i++) for (std::size_t i = 0; i < e; i++)
Idrive = Idrive + this->A(k,p[i]) * this->m_new_V[p[i]]; Idrive = Idrive + this->m_A[k][p[i]] * this->m_new_V[p[i]];
FT w = m_omega / this->A(k,k); FT w = m_omega / this->m_A[k][k];
if (this->m_params.m_use_gabs) if (this->m_params.m_use_gabs)
{ {
FT gabs_t = 0.0; FT gabs_t = 0.0;
for (std::size_t i = 0; i < e; i++) for (std::size_t i = 0; i < e; i++)
if (p[i] != k) if (p[i] != k)
gabs_t = gabs_t + std::abs(this->A(k,p[i])); gabs_t = gabs_t + std::abs(this->m_A[k][p[i]]);
gabs_t *= plib::constants<FT>::one(); // derived by try and error gabs_t *= plib::constants<FT>::one(); // derived by try and error
if (gabs_t > this->A(k,k)) if (gabs_t > this->m_A[k][k])
{ {
w = plib::constants<FT>::one() / (this->A(k,k) + gabs_t); w = plib::constants<FT>::one() / (this->m_A[k][k] + gabs_t);
} }
} }
const float_type delta = w * (this->RHS(k) - Idrive) ; const float_type delta = w * (this->m_RHS[k] - Idrive) ;
cerr = std::max(cerr, std::abs(delta)); cerr = std::max(cerr, std::abs(delta));
this->m_new_V[k] += delta; this->m_new_V[k] += delta;
} }

View File

@ -70,9 +70,7 @@ namespace solver
, m_cnt(0) , m_cnt(0)
, m_dim(size) , m_dim(size)
{ {
// FIXME: This shouldn't be necessary, recalculate on each entry ... this->build_mat_ptr(this->size(), m_A);
for (std::size_t k = 0; k < this->size(); k++)
state().save(*this, RHS(k), this->name(), plib::pfmt("RHS.{1}")(k));
} }
void reset() override { matrix_solver_t::reset(); } void reset() override { matrix_solver_t::reset(); }
@ -267,7 +265,7 @@ namespace solver
for (unsigned i = 0; i < rowcount; i++) for (unsigned i = 0; i < rowcount; i++)
{ {
const unsigned r = rows[i]; const unsigned r = rows[i];
double tmp = 0.0; nl_fptype tmp = 0.0;
for (unsigned k = 0; k < iN; k++) for (unsigned k = 0; k < iN; k++)
tmp += VT(r,k) * new_V[k]; tmp += VT(r,k) * new_V[k];
w[i] = tmp; w[i] = tmp;
@ -359,8 +357,9 @@ namespace solver
template <typename FT, int SIZE> template <typename FT, int SIZE>
unsigned matrix_solver_w_t<FT, SIZE>::vsolve_non_dynamic(const bool newton_raphson) unsigned matrix_solver_w_t<FT, SIZE>::vsolve_non_dynamic(const bool newton_raphson)
{ {
this->build_LE_A(*this); const std::size_t iN = this->size();
this->build_LE_RHS(*this); this->clear_square_mat(iN, this->m_A);
this->fill_matrix(iN, this->m_RHS);
this->m_stat_calculations++; this->m_stat_calculations++;
return this->solve_non_dynamic(newton_raphson); return this->solve_non_dynamic(newton_raphson);

View File

@ -231,62 +231,62 @@ namespace devices
switch (net_count) switch (net_count)
{ {
case 1: case 1:
ms = plib::make_unique<solver::matrix_solver_direct1_t<double>>(state(), sname, grp, &m_params); ms = plib::make_unique<solver::matrix_solver_direct1_t<nl_fptype>>(state(), sname, grp, &m_params);
break; break;
case 2: case 2:
ms = plib::make_unique<solver::matrix_solver_direct2_t<double>>(state(), sname, grp, &m_params); ms = plib::make_unique<solver::matrix_solver_direct2_t<nl_fptype>>(state(), sname, grp, &m_params);
break; break;
#if 0 #if 0
case 3: case 3:
ms = create_solver<double, 3>(3, sname, grp); ms = create_solver<nl_fptype, 3>(3, sname, grp);
break; break;
case 4: case 4:
ms = create_solver<double, 4>(4, sname, grp); ms = create_solver<nl_fptype, 4>(4, sname, grp);
break; break;
case 5: case 5:
ms = create_solver<double, 5>(5, sname, grp); ms = create_solver<nl_fptype, 5>(5, sname, grp);
break; break;
case 6: case 6:
ms = create_solver<double, 6>(6, sname, grp); ms = create_solver<nl_fptype, 6>(6, sname, grp);
break; break;
case 7: case 7:
ms = create_solver<double, 7>(7, sname, grp); ms = create_solver<nl_fptype, 7>(7, sname, grp);
break; break;
case 8: case 8:
ms = create_solver<double, 8>(8, sname, grp); ms = create_solver<nl_fptype, 8>(8, sname, grp);
break; break;
case 9: case 9:
ms = create_solver<double, 9>(9, sname, grp); ms = create_solver<nl_fptype, 9>(9, sname, grp);
break; break;
case 10: case 10:
ms = create_solver<double, 10>(10, sname, grp); ms = create_solver<nl_fptype, 10>(10, sname, grp);
break; break;
#if 0 #if 0
case 11: case 11:
ms = create_solver<double, 11>(11, sname); ms = create_solver<nl_fptype, 11>(11, sname);
break; break;
case 12: case 12:
ms = create_solver<double, 12>(12, sname); ms = create_solver<nl_fptype, 12>(12, sname);
break; break;
case 15: case 15:
ms = create_solver<double, 15>(15, sname); ms = create_solver<nl_fptype, 15>(15, sname);
break; break;
case 31: case 31:
ms = create_solver<double, 31>(31, sname); ms = create_solver<nl_fptype, 31>(31, sname);
break; break;
case 35: case 35:
ms = create_solver<double, 35>(35, sname); ms = create_solver<nl_fptype, 35>(35, sname);
break; break;
case 43: case 43:
ms = create_solver<double, 43>(43, sname); ms = create_solver<nl_fptype, 43>(43, sname);
break; break;
case 49: case 49:
ms = create_solver<double, 49>(49, sname); ms = create_solver<nl_fptype, 49>(49, sname);
break; break;
#endif #endif
#if 1 #if 1
case 87: case 87:
ms = create_solver<double,86>(86, sname, grp); ms = create_solver<nl_fptype,86>(86, sname, grp);
break; break;
#endif #endif
#endif #endif
@ -294,35 +294,35 @@ namespace devices
log().info(MI_NO_SPECIFIC_SOLVER(net_count)); log().info(MI_NO_SPECIFIC_SOLVER(net_count));
if (net_count <= 8) if (net_count <= 8)
{ {
ms = create_solver<double, -8>(net_count, sname, grp); ms = create_solver<nl_fptype, -8>(net_count, sname, grp);
} }
else if (net_count <= 16) else if (net_count <= 16)
{ {
ms = create_solver<double, -16>(net_count, sname, grp); ms = create_solver<nl_fptype, -16>(net_count, sname, grp);
} }
else if (net_count <= 32) else if (net_count <= 32)
{ {
ms = create_solver<double, -32>(net_count, sname, grp); ms = create_solver<nl_fptype, -32>(net_count, sname, grp);
} }
else if (net_count <= 64) else if (net_count <= 64)
{ {
ms = create_solver<double, -64>(net_count, sname, grp); ms = create_solver<nl_fptype, -64>(net_count, sname, grp);
} }
else if (net_count <= 128) else if (net_count <= 128)
{ {
ms = create_solver<double, -128>(net_count, sname, grp); ms = create_solver<nl_fptype, -128>(net_count, sname, grp);
} }
else if (net_count <= 256) else if (net_count <= 256)
{ {
ms = create_solver<double, -256>(net_count, sname, grp); ms = create_solver<nl_fptype, -256>(net_count, sname, grp);
} }
else if (net_count <= 512) else if (net_count <= 512)
{ {
ms = create_solver<double, -512>(net_count, sname, grp); ms = create_solver<nl_fptype, -512>(net_count, sname, grp);
} }
else else
{ {
ms = create_solver<double, 0>(net_count, sname, grp); ms = create_solver<nl_fptype, 0>(net_count, sname, grp);
} }
break; break;
} }

View File

@ -39,7 +39,7 @@ namespace devices
void post_start(); void post_start();
void stop(); void stop();
nl_double gmin() const { return m_params.m_gmin(); } nl_fptype gmin() const { return m_params.m_gmin(); }
void create_solver_code(std::map<pstring, pstring> &mp); void create_solver_code(std::map<pstring, pstring> &mp);