diff options
Diffstat (limited to 'src/lib/netlist/analog/nlid_twoterm.cpp')
-rw-r--r-- | src/lib/netlist/analog/nlid_twoterm.cpp | 233 |
1 files changed, 47 insertions, 186 deletions
diff --git a/src/lib/netlist/analog/nlid_twoterm.cpp b/src/lib/netlist/analog/nlid_twoterm.cpp index f54c2b3e68f..5019c98c0e4 100644 --- a/src/lib/netlist/analog/nlid_twoterm.cpp +++ b/src/lib/netlist/analog/nlid_twoterm.cpp @@ -5,10 +5,10 @@ * */ -#include "../solver/nld_solver.h" +#include "netlist/solver/nld_solver.h" +#include "netlist/nl_factory.h" #include "nlid_twoterm.h" -#include "../nl_factory.h" #include <cmath> @@ -16,81 +16,34 @@ namespace netlist { namespace analog { + // ---------------------------------------------------------------------------------------- -// generic_diode +// nld_twoterm // ---------------------------------------------------------------------------------------- -generic_diode::generic_diode(device_t &dev, pstring name) - : m_Vd(dev, name + ".m_Vd", 0.7) - , m_Id(dev, name + ".m_Id", 0.0) - , m_G(dev, name + ".m_G", 1e-15) - , m_Vt(0.0) - , m_Vmin(0.0) - , m_Is(0.0) - , m_logIs(0.0) - , m_n(0.0) - , m_gmin(1e-15) - , m_VtInv(0.0) - , m_Vcrit(0.0) -{ - set_param(1e-15, 1, 1e-15); -} - -void generic_diode::set_param(const nl_double Is, const nl_double n, nl_double gmin) +void NETLIB_NAME(twoterm)::solve_now() { - static constexpr double csqrt2 = 1.414213562373095048801688724209; //std::sqrt(2.0); - m_Is = Is; - m_logIs = std::log(Is); - m_n = n; - m_gmin = gmin; - - m_Vt = 0.0258 * m_n; - m_Vmin = -5.0 * m_Vt; - - m_Vcrit = m_Vt * std::log(m_Vt / m_Is / csqrt2); - m_VtInv = 1.0 / m_Vt; + /* we only need to call the non-rail terminal */ + if (m_P.has_net() && !m_P.net().isRailNet()) + m_P.solve_now(); + else if (m_N.has_net() && !m_N.net().isRailNet()) + m_N.solve_now(); } -void generic_diode::update_diode(const nl_double nVd) +void NETLIB_NAME(twoterm)::solve_later(netlist_time delay) { - if (nVd < m_Vmin) - { - m_Vd = nVd; - m_G = m_gmin; - m_Id = - m_Is; - } - else if (nVd < m_Vcrit) - { - m_Vd = nVd; - //m_Vd = m_Vd + 10.0 * m_Vt * std::tanh((nVd - m_Vd) / 10.0 / m_Vt); - //const double IseVDVt = m_Is * std::exp(m_Vd * m_VtInv); - const double IseVDVt = std::exp(m_logIs + m_Vd * m_VtInv); - m_Id = IseVDVt - m_Is; - m_G = IseVDVt * m_VtInv + m_gmin; - } - else - { - const double a = std::max((nVd - m_Vd) * m_VtInv, NL_FCONST(-0.99)); - m_Vd = m_Vd + std::log1p(a) * m_Vt; - //const double IseVDVt = m_Is * std::exp(m_Vd * m_VtInv); - const double IseVDVt = std::exp(m_logIs + m_Vd * m_VtInv); - m_Id = IseVDVt - m_Is; - m_G = IseVDVt * m_VtInv + m_gmin; - } + /* we only need to call the non-rail terminal */ + if (m_P.has_net() && !m_P.net().isRailNet()) + m_P.schedule_solve_after(delay); + else if (m_N.has_net() && !m_N.net().isRailNet()) + m_N.schedule_solve_after(delay); } -// ---------------------------------------------------------------------------------------- -// nld_twoterm -// ---------------------------------------------------------------------------------------- NETLIB_UPDATE(twoterm) { /* only called if connected to a rail net ==> notify the solver to recalculate */ - /* we only need to call the non-rail terminal */ - if (m_P.has_net() && !m_P.net().isRailNet()) - m_P.solve_now(); - else if (m_N.has_net() && !m_N.net().isRailNet()) - m_N.solve_now(); + solve_now(); } // ---------------------------------------------------------------------------------------- @@ -100,12 +53,7 @@ NETLIB_UPDATE(twoterm) NETLIB_RESET(R_base) { NETLIB_NAME(twoterm)::reset(); - set_R(1.0 / netlist().gmin()); -} - -NETLIB_UPDATE(R_base) -{ - NETLIB_NAME(twoterm)::update(); + set_R(1.0 / exec().gmin()); } // ---------------------------------------------------------------------------------------- @@ -114,14 +62,14 @@ NETLIB_UPDATE(R_base) NETLIB_UPDATE_PARAM(R) { - update_dev(); - set_R(std::max(m_R(), netlist().gmin())); + solve_now(); + set_R(std::max(m_R(), exec().gmin())); } NETLIB_RESET(R) { NETLIB_NAME(twoterm)::reset(); - set_R(std::max(m_R(), netlist().gmin())); + set_R(std::max(m_R(), exec().gmin())); } // ---------------------------------------------------------------------------------------- @@ -134,21 +82,22 @@ NETLIB_RESET(POT) if (m_DialIsLog()) v = (std::exp(v) - 1.0) / (std::exp(1.0) - 1.0); - m_R1.set_R(std::max(m_R() * v, netlist().gmin())); - m_R2.set_R(std::max(m_R() * (NL_FCONST(1.0) - v), netlist().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())); } NETLIB_UPDATE_PARAM(POT) { - m_R1.update_dev(); - m_R2.update_dev(); + m_R1.solve_now(); + m_R2.solve_now(); nl_double v = m_Dial(); if (m_DialIsLog()) v = (std::exp(v) - 1.0) / (std::exp(1.0) - 1.0); - - m_R1.set_R(std::max(m_R() * v, netlist().gmin())); - m_R2.set_R(std::max(m_R() * (NL_FCONST(1.0) - v), netlist().gmin())); + if (m_Reverse()) + v = 1.0 - v; + 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())); } @@ -164,13 +113,13 @@ NETLIB_RESET(POT2) v = (std::exp(v) - 1.0) / (std::exp(1.0) - 1.0); if (m_Reverse()) v = 1.0 - v; - m_R1.set_R(std::max(m_R() * v, netlist().gmin())); + m_R1.set_R(std::max(m_R() * v, exec().gmin())); } NETLIB_UPDATE_PARAM(POT2) { - m_R1.update_dev(); + m_R1.solve_now(); nl_double v = m_Dial(); @@ -178,38 +127,7 @@ NETLIB_UPDATE_PARAM(POT2) v = (std::exp(v) - 1.0) / (std::exp(1.0) - 1.0); if (m_Reverse()) v = 1.0 - v; - m_R1.set_R(std::max(m_R() * v, netlist().gmin())); -} - -// ---------------------------------------------------------------------------------------- -// nld_C -// ---------------------------------------------------------------------------------------- - -NETLIB_RESET(C) -{ - // FIXME: Startup conditions - set(netlist().gmin(), 0.0, -5.0 / netlist().gmin()); - //set(netlist().gmin(), 0.0, 0.0); -} - -NETLIB_UPDATE_PARAM(C) -{ - m_GParallel = netlist().gmin(); -} - -NETLIB_UPDATE(C) -{ - NETLIB_NAME(twoterm)::update(); -} - -NETLIB_TIMESTEP(C) -{ - /* Gpar should support convergence */ - const nl_double G = m_C() / step + m_GParallel; - const nl_double I = -G * deltaV(); - set_mat( G, -G, -I, - -G, G, I); - //set(G, 0.0, I); + m_R1.set_R(std::max(m_R() * v, exec().gmin())); } // ---------------------------------------------------------------------------------------- @@ -218,9 +136,9 @@ NETLIB_TIMESTEP(C) NETLIB_RESET(L) { - m_GParallel = netlist().gmin(); + m_gmin = exec().gmin(); m_I = 0.0; - m_G = m_GParallel; + m_G = m_gmin; set_mat( m_G, -m_G, -m_I, -m_G, m_G, m_I); //set(1.0/NETLIST_GMIN, 0.0, -5.0 * NETLIST_GMIN); @@ -230,16 +148,11 @@ NETLIB_UPDATE_PARAM(L) { } -NETLIB_UPDATE(L) -{ - NETLIB_NAME(twoterm)::update(); -} - NETLIB_TIMESTEP(L) { /* Gpar should support convergence */ m_I += m_I + m_G * deltaV(); - m_G = step / m_L() + m_GParallel; + m_G = step / m_L() + m_gmin; set_mat( m_G, -m_G, -m_I, -m_G, m_G, m_I); //set(m_G, 0.0, m_I); @@ -254,8 +167,8 @@ NETLIB_RESET(D) nl_double Is = m_model.m_IS; nl_double n = m_model.m_N; - m_D.set_param(Is, n, netlist().gmin()); - set(m_D.G(), 0.0, m_D.Ieq()); + m_D.set_param(Is, n, exec().gmin(), constants::T0()); + set_G_V_I(m_D.G(), 0.0, m_D.Ieq()); } NETLIB_UPDATE_PARAM(D) @@ -263,12 +176,7 @@ NETLIB_UPDATE_PARAM(D) nl_double Is = m_model.m_IS; nl_double n = m_model.m_N; - m_D.set_param(Is, n, netlist().gmin()); -} - -NETLIB_UPDATE(D) -{ - NETLIB_NAME(twoterm)::update(); + m_D.set_param(Is, n, exec().gmin(), constants::T0()); } NETLIB_UPDATE_TERMINALS(D) @@ -281,65 +189,18 @@ NETLIB_UPDATE_TERMINALS(D) //set(m_D.G(), 0.0, m_D.Ieq()); } -// ---------------------------------------------------------------------------------------- -// nld_VS -// ---------------------------------------------------------------------------------------- - -NETLIB_RESET(VS) -{ - NETLIB_NAME(twoterm)::reset(); - this->set(1.0 / m_R(), m_V(), 0.0); -} - -NETLIB_UPDATE(VS) -{ - NETLIB_NAME(twoterm)::update(); -} - -NETLIB_TIMESTEP(VS) -{ - this->set(1.0 / m_R(), - m_compiled.evaluate(std::vector<double>({netlist().time().as_double()})), - 0.0); -} - -// ---------------------------------------------------------------------------------------- -// nld_CS -// ---------------------------------------------------------------------------------------- - -NETLIB_RESET(CS) -{ - NETLIB_NAME(twoterm)::reset(); - const nl_double I = m_I(); - - set_mat(0.0, 0.0, -I, - 0.0, 0.0, I); - //this->set(0.0, 0.0, m_I()); -} - -NETLIB_UPDATE(CS) -{ - NETLIB_NAME(twoterm)::update(); -} - -NETLIB_TIMESTEP(CS) -{ - const double I = m_compiled.evaluate(std::vector<double>({netlist().time().as_double()})); - set_mat(0.0, 0.0, -I, - 0.0, 0.0, I); -} } //namespace analog namespace devices { - NETLIB_DEVICE_IMPL_NS(analog, R) - NETLIB_DEVICE_IMPL_NS(analog, POT) - NETLIB_DEVICE_IMPL_NS(analog, POT2) - NETLIB_DEVICE_IMPL_NS(analog, C) - NETLIB_DEVICE_IMPL_NS(analog, L) - NETLIB_DEVICE_IMPL_NS(analog, D) - NETLIB_DEVICE_IMPL_NS(analog, VS) - NETLIB_DEVICE_IMPL_NS(analog, CS) - } + NETLIB_DEVICE_IMPL_NS(analog, R, "RES", "R") + NETLIB_DEVICE_IMPL_NS(analog, POT, "POT", "R") + NETLIB_DEVICE_IMPL_NS(analog, POT2, "POT2", "R") + NETLIB_DEVICE_IMPL_NS(analog, C, "CAP", "C") + NETLIB_DEVICE_IMPL_NS(analog, L, "IND", "L") + NETLIB_DEVICE_IMPL_NS(analog, D, "DIODE", "MODEL") + NETLIB_DEVICE_IMPL_NS(analog, VS, "VS", "V") + NETLIB_DEVICE_IMPL_NS(analog, CS, "CS", "I") + } // namespace devices } // namespace netlist |