mirror of
https://github.com/holub/mame
synced 2025-10-04 08:28:39 +03:00
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:
parent
cae02668fa
commit
6c075e602c
@ -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);
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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_ */
|
||||||
|
@ -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
|
||||||
|
@ -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();
|
||||||
|
@ -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());
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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 ...
|
||||||
|
@ -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() { }
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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));
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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 ¶m) = delete;
|
void setTo(const pstring ¶m) = 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())
|
||||||
{
|
{
|
||||||
|
@ -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_ */
|
||||||
|
@ -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
|
||||||
|
@ -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];
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -119,7 +119,7 @@ namespace netlist
|
|||||||
m_namespace_stack.pop();
|
m_namespace_stack.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void nlparse_t::register_param(const pstring ¶m, const double value)
|
void nlparse_t::register_param(const pstring ¶m, 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);
|
||||||
|
@ -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 ¶m, const pstring &value);
|
void register_param(const pstring ¶m, const pstring &value);
|
||||||
void register_param(const pstring ¶m, const double value);
|
void register_param(const pstring ¶m, 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)
|
||||||
|
@ -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.
|
||||||
*
|
*
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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++;
|
||||||
|
@ -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 */
|
||||||
|
|
||||||
|
@ -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++)
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user