From d3ee7e21c6f52a794e67beda0d3bffa32179d03c Mon Sep 17 00:00:00 2001 From: couriersud Date: Sat, 25 Apr 2020 18:08:04 +0200 Subject: netlist: unify solver calls. (nw) Calls to the solver used different paths. These changes unify these calls and provide a common call for discontinuous state changes on analog components (change_state). --- src/lib/netlist/analog/nld_switches.cpp | 35 +++++++------------ src/lib/netlist/analog/nlid_twoterm.cpp | 52 ++++++++++++++-------------- src/lib/netlist/analog/nlid_twoterm.h | 30 ++++++++++------ src/lib/netlist/devices/nld_4066.cpp | 4 +-- src/lib/netlist/devices/nld_4316.cpp | 14 ++++---- src/lib/netlist/devices/nld_mm5837.cpp | 14 +++----- src/lib/netlist/devices/nld_r2r_dac.cpp | 10 +++--- src/lib/netlist/devices/nld_schmitt.cpp | 19 +++++----- src/lib/netlist/devices/nlid_proxy.cpp | 43 +++++++++++------------ src/lib/netlist/devices/nlid_proxy.h | 1 - src/lib/netlist/devices/nlid_system.h | 7 ++-- src/lib/netlist/nl_base.cpp | 14 ++------ src/lib/netlist/nl_base.h | 15 +++++++- src/lib/netlist/solver/nld_matrix_solver.cpp | 32 ++++++++--------- src/lib/netlist/solver/nld_matrix_solver.h | 47 +++++++++++++++++++------ src/lib/netlist/solver/nld_solver.cpp | 15 ++++---- 16 files changed, 183 insertions(+), 169 deletions(-) diff --git a/src/lib/netlist/analog/nld_switches.cpp b/src/lib/netlist/analog/nld_switches.cpp index a5d68228af1..9dbd50c94e9 100644 --- a/src/lib/netlist/analog/nld_switches.cpp +++ b/src/lib/netlist/analog/nld_switches.cpp @@ -49,17 +49,10 @@ namespace netlist NETLIB_UPDATE_PARAM(switch1) { - m_R.solve_now(); - if (!m_POS()) - { - m_R.set_R(R_OFF); - } - else + m_R.change_state([this]() { - m_R.set_R(R_ON); - } - m_R.solve_later(); - + m_R.set_R(m_POS() ? R_ON : R_OFF); + }); } // ---------------------------------------------------------------------------------------- @@ -112,21 +105,19 @@ namespace netlist NETLIB_UPDATE_PARAM(switch2) { - // FIXME: We only need to update the net first if this is a time stepping net - m_R1.solve_now(); - m_R2.solve_now(); - if (!m_POS()) - { - m_R1.set_R(R_ON); - m_R2.set_R(R_OFF); - } + // R1 and R2 are connected. However this net may be a rail net. + // The code here thus is a bit more complex. + + nl_fptype r1 = m_POS() ? R_OFF : R_ON; + nl_fptype r2 = m_POS() ? R_ON : R_OFF; + + if (m_R1.solver() == m_R2.solver()) + m_R1.change_state([this, &r1, &r2]() { m_R1.set_R(r1); m_R2.set_R(r2); }); else { - m_R1.set_R(R_OFF); - m_R2.set_R(R_ON); + m_R1.change_state([this, &r1]() { m_R1.set_R(r1); }); + m_R2.change_state([this, &r2]() { m_R2.set_R(r2); }); } - m_R1.solve_later(); - m_R2.solve_later(); } } //namespace analog diff --git a/src/lib/netlist/analog/nlid_twoterm.cpp b/src/lib/netlist/analog/nlid_twoterm.cpp index 2573103d06b..c57d76c821e 100644 --- a/src/lib/netlist/analog/nlid_twoterm.cpp +++ b/src/lib/netlist/analog/nlid_twoterm.cpp @@ -15,25 +15,22 @@ namespace analog // nld_twoterm // ---------------------------------------------------------------------------------------- - void NETLIB_NAME(twoterm)::solve_now() + solver::matrix_solver_t * NETLIB_NAME(twoterm)::solver() const noexcept { - // we only need to call the non-rail terminal - if (m_P.has_net() && !m_P.net().is_rail_net()) - m_P.solve_now(); - else if (m_N.has_net() && !m_N.net().is_rail_net()) - m_N.solve_now(); + auto *solv(m_P.solver()); + if (solv) + return solv; + return m_N.solver(); } - void NETLIB_NAME(twoterm)::solve_later(netlist_time delay) noexcept + + void NETLIB_NAME(twoterm)::solve_now() const { - // we only need to call the non-rail terminal - if (m_P.has_net() && !m_P.net().is_rail_net()) - m_P.schedule_solve_after(delay); - else if (m_N.has_net() && !m_N.net().is_rail_net()) - m_N.schedule_solve_after(delay); + auto *solv(solver()); + if (solv) + solv->solve_now(); } - NETLIB_UPDATE(twoterm) { // only called if connected to a rail net ==> notify the solver to recalculate @@ -66,19 +63,22 @@ namespace analog NETLIB_UPDATE_PARAM(POT) { - // FIXME: We only need to update the net first if this is a time stepping net - m_R1.solve_now(); - m_R2.solve_now(); - nl_fptype v = m_Dial(); if (m_DialIsLog()) v = (plib::exp(v) - nlconst::one()) / (plib::exp(nlconst::one()) - nlconst::one()); if (m_Reverse()) v = nlconst::one() - v; - m_R1.set_R(std::max(m_R() * v, exec().gmin())); - m_R2.set_R(std::max(m_R() * (nlconst::one() - v), exec().gmin())); - m_R1.solve_later(); - m_R2.solve_later(); + + nl_fptype r1(std::max(m_R() * v, exec().gmin())); + nl_fptype r2(std::max(m_R() * (nlconst::one() - v), exec().gmin())); + + if (m_R1.solver() == m_R2.solver()) + m_R1.change_state([this, &r1, &r2]() { m_R1.set_R(r1); m_R2.set_R(r2); }); + else + { + m_R1.change_state([this, &r1]() { m_R1.set_R(r1); }); + m_R2.change_state([this, &r2]() { m_R2.set_R(r2); }); + } } @@ -100,17 +100,17 @@ namespace analog NETLIB_UPDATE_PARAM(POT2) { - // FIXME: We only need to update the net first if this is a time stepping net - m_R1.solve_now(); - nl_fptype v = m_Dial(); if (m_DialIsLog()) v = (plib::exp(v) - nlconst::one()) / (plib::exp(nlconst::one()) - nlconst::one()); if (m_Reverse()) v = nlconst::one() - v; - m_R1.set_R(std::max(m_R() * v, exec().gmin())); - m_R1.solve_later(); + + m_R1.change_state([this, &v]() + { + m_R1.set_R(std::max(m_R() * v, exec().gmin())); + }); } // ---------------------------------------------------------------------------------------- diff --git a/src/lib/netlist/analog/nlid_twoterm.h b/src/lib/netlist/analog/nlid_twoterm.h index ffeb75e215c..cb816847bf1 100644 --- a/src/lib/netlist/analog/nlid_twoterm.h +++ b/src/lib/netlist/analog/nlid_twoterm.h @@ -86,9 +86,17 @@ namespace analog NETLIB_UPDATEI(); - void solve_now(); + solver::matrix_solver_t *solver() const noexcept; - void solve_later(netlist_time delay = netlist_time::quantum()) noexcept; + void solve_now() const; + + template + void change_state(F f, netlist_time delay = netlist_time::quantum()) + { + auto *solv(solver()); + if (solv) + solv->change_state(f, delay); + } void set_G_V_I(nl_fptype G, nl_fptype V, nl_fptype I) const noexcept { @@ -168,9 +176,10 @@ namespace analog NETLIB_UPDATE_PARAMI() { // FIXME: We only need to update the net first if this is a time stepping net - solve_now(); - set_R(std::max(m_R(), exec().gmin())); - solve_later(); + change_state([this]() + { + set_R(std::max(m_R(), exec().gmin())); + }); } private: @@ -524,11 +533,12 @@ namespace analog { // FIXME: We only need to update the net first if this is a time stepping net //FIXME: works only for CS without function - solve_now(); - const auto zero(nlconst::zero()); - set_mat(zero, zero, -m_I(), - zero, zero, m_I()); - solve_later(); + change_state([this]() + { + const auto zero(nlconst::zero()); + set_mat(zero, zero, -m_I(), + zero, zero, m_I()); + }); } private: diff --git a/src/lib/netlist/devices/nld_4066.cpp b/src/lib/netlist/devices/nld_4066.cpp index 8ccd01156cd..7200e5a3962 100644 --- a/src/lib/netlist/devices/nld_4066.cpp +++ b/src/lib/netlist/devices/nld_4066.cpp @@ -69,9 +69,7 @@ namespace netlist if (R > nlconst::zero() && (m_last != new_state)) { m_last = new_state; - m_R.solve_now(); - m_R.set_R(R); - m_R.solve_later(); + m_R.change_state([this, &R]() -> void { this->m_R.set_R(R);}); } } diff --git a/src/lib/netlist/devices/nld_4316.cpp b/src/lib/netlist/devices/nld_4316.cpp index 7667772bb91..f8085092178 100644 --- a/src/lib/netlist/devices/nld_4316.cpp +++ b/src/lib/netlist/devices/nld_4316.cpp @@ -43,12 +43,14 @@ namespace netlist { namespace devices { NETLIB_UPDATE(CD4316_GATE) { - m_R.solve_now(); - if (m_S() && !m_E()) - m_R.set_R(m_base_r()); - else - m_R.set_R(plib::reciprocal(exec().gmin())); - m_R.solve_later(NLTIME_FROM_NS(1)); + m_R.change_state([this]() + { + if (m_S() && !m_E()) + m_R.set_R(m_base_r()); + else + m_R.set_R(plib::reciprocal(exec().gmin())); + } + , NLTIME_FROM_NS(1)); } NETLIB_DEVICE_IMPL(CD4316_GATE, "CD4316_GATE", "") diff --git a/src/lib/netlist/devices/nld_mm5837.cpp b/src/lib/netlist/devices/nld_mm5837.cpp index 75e0d9635c8..771b64e0ab6 100644 --- a/src/lib/netlist/devices/nld_mm5837.cpp +++ b/src/lib/netlist/devices/nld_mm5837.cpp @@ -28,7 +28,6 @@ namespace netlist , m_Q(*this, "_Q") , m_inc(netlist_time::from_hz(24000 * 2)) , m_shift(*this, "m_shift", 0) - , m_is_timestep(false) { connect(m_feedback, m_Q); @@ -57,9 +56,6 @@ namespace netlist /* state */ state_var_u32 m_shift; - - /* cache */ - bool m_is_timestep; }; NETLIB_RESET(MM5837_dip) @@ -74,7 +70,6 @@ namespace netlist log().warning(MW_FREQUENCY_OUTSIDE_OF_SPECS_1(m_FREQ())); m_shift = 0x1ffff; - m_is_timestep = (m_RV.m_P.net().solver()->timestep_device_count() > 0); } NETLIB_UPDATE_PARAM(MM5837_dip) @@ -104,11 +99,10 @@ namespace netlist const nl_fptype R = state ? m_R_HIGH : m_R_LOW; const nl_fptype V = state ? m_VDD() : m_VSS(); - // We only need to update the net first if this is a time stepping net - if (m_is_timestep) - m_RV.solve_now(); - m_RV.set_G_V_I(plib::reciprocal(R), V, nlconst::zero()); - m_RV.solve_later(NLTIME_FROM_NS(1)); + m_RV.change_state([this, &R, &V]() + { + m_RV.set_G_V_I(plib::reciprocal(R), V, nlconst::zero()); + }); } } diff --git a/src/lib/netlist/devices/nld_r2r_dac.cpp b/src/lib/netlist/devices/nld_r2r_dac.cpp index 361652a373a..946050c1951 100644 --- a/src/lib/netlist/devices/nld_r2r_dac.cpp +++ b/src/lib/netlist/devices/nld_r2r_dac.cpp @@ -39,13 +39,13 @@ namespace netlist NETLIB_UPDATE_PARAM(r2r_dac) { - // FIXME: We only need to update the net first if this is a time stepping net - solve_now(); nl_fptype V = m_VIN() / static_cast(1 << m_num()) * static_cast(m_val()); - - this->set_G_V_I(plib::reciprocal(m_R()), V, nlconst::zero()); - solve_later(); + change_state([this, &V]() + { + this->set_G_V_I(plib::reciprocal(m_R()), V, nlconst::zero()); + } + ); } } //namespace analog diff --git a/src/lib/netlist/devices/nld_schmitt.cpp b/src/lib/netlist/devices/nld_schmitt.cpp index 6c59b2a3192..877c32bf3d7 100644 --- a/src/lib/netlist/devices/nld_schmitt.cpp +++ b/src/lib/netlist/devices/nld_schmitt.cpp @@ -67,7 +67,6 @@ namespace netlist , m_RVO(*this, "RVO") , m_model(*this, "MODEL", "TTL_7414_GATE") , m_last_state(*this, "m_last_var", 1) - , m_is_timestep(false) { register_subalias("Q", m_RVO.m_P); @@ -82,7 +81,6 @@ namespace netlist m_last_state = 1; m_RVI.reset(); m_RVO.reset(); - m_is_timestep = (m_RVO.m_P.net().solver()->timestep_device_count() > 0); m_RVI.set_G_V_I(plib::reciprocal(m_model.m_RI()), m_model.m_VI, nlconst::zero()); m_RVO.set_G_V_I(plib::reciprocal(m_model.m_ROL()), m_model.m_VOL, nlconst::zero()); } @@ -95,10 +93,10 @@ namespace netlist if (va < m_model.m_VTM) { m_last_state = 0; - if (m_is_timestep) - m_RVO.solve_now(); - m_RVO.set_G_V_I(plib::reciprocal(m_model.m_ROH()), m_model.m_VOH, nlconst::zero()); - m_RVO.solve_later(); + m_RVO.change_state([this]() + { + m_RVO.set_G_V_I(plib::reciprocal(m_model.m_ROH()), m_model.m_VOH, nlconst::zero()); + }); } } else @@ -106,10 +104,10 @@ namespace netlist if (va > m_model.m_VTP) { m_last_state = 1; - if (m_is_timestep) - m_RVO.solve_now(); - m_RVO.set_G_V_I(plib::reciprocal(m_model.m_ROL()), m_model.m_VOL, nlconst::zero()); - m_RVO.solve_later(); + m_RVO.change_state([this]() + { + m_RVO.set_G_V_I(plib::reciprocal(m_model.m_ROL()), m_model.m_VOL, nlconst::zero()); + }); } } } @@ -121,7 +119,6 @@ namespace netlist analog::NETLIB_SUB(twoterm) m_RVO; schmitt_trigger_model_t m_model; state_var m_last_state; - bool m_is_timestep; }; NETLIB_DEVICE_IMPL(schmitt_trigger, "SCHMITT_TRIGGER", "MODEL") diff --git a/src/lib/netlist/devices/nlid_proxy.cpp b/src/lib/netlist/devices/nlid_proxy.cpp index 74dbf2d3cc7..f2cf50e7b91 100644 --- a/src/lib/netlist/devices/nlid_proxy.cpp +++ b/src/lib/netlist/devices/nlid_proxy.cpp @@ -117,7 +117,6 @@ namespace netlist , m_RP(*this, "RP") , m_RN(*this, "RN") , m_last_state(*this, "m_last_var", -1) - , m_is_timestep(false) { register_subalias("Q", m_RN.m_P); @@ -145,7 +144,6 @@ namespace netlist m_last_state = -1; m_RN.reset(); m_RP.reset(); - m_is_timestep = (m_RN.m_P.net().solver()->timestep_device_count() > 0); m_RN.set_G_V_I(plib::reciprocal(logic_family()->R_low()), logic_family()->low_offset_V(), nlconst::zero()); m_RP.set_G_V_I(G_OFF, @@ -158,28 +156,27 @@ namespace netlist const auto state = static_cast(m_I()); if (state != m_last_state) { - // We only need to update the net first if this is a time stepping net - if (m_is_timestep) + // RN, RP are connected ... + m_RN.change_state([this, &state]() { - m_RN.solve_now(); // RN, RP are connected ... - } - if (state) - { - m_RN.set_G_V_I(G_OFF, - nlconst::zero(), - nlconst::zero()); - m_RP.set_G_V_I(plib::reciprocal(logic_family()->R_high()), - logic_family()->high_offset_V(), nlconst::zero()); - } - else - { - m_RN.set_G_V_I(plib::reciprocal(logic_family()->R_low()), - logic_family()->low_offset_V(), nlconst::zero()); - m_RP.set_G_V_I(G_OFF, - nlconst::zero(), - nlconst::zero()); - } - m_RN.solve_later(); // RN, RP are connected ... + if (state) + { + + m_RN.set_G_V_I(G_OFF, + nlconst::zero(), + nlconst::zero()); + m_RP.set_G_V_I(plib::reciprocal(logic_family()->R_high()), + logic_family()->high_offset_V(), nlconst::zero()); + } + else + { + m_RN.set_G_V_I(plib::reciprocal(logic_family()->R_low()), + logic_family()->low_offset_V(), nlconst::zero()); + m_RP.set_G_V_I(G_OFF, + nlconst::zero(), + nlconst::zero()); + } + }); m_last_state = state; } } diff --git a/src/lib/netlist/devices/nlid_proxy.h b/src/lib/netlist/devices/nlid_proxy.h index 936d03f8fb6..b1639631a0e 100644 --- a/src/lib/netlist/devices/nlid_proxy.h +++ b/src/lib/netlist/devices/nlid_proxy.h @@ -119,7 +119,6 @@ namespace devices analog::NETLIB_NAME(twoterm) m_RP; analog::NETLIB_NAME(twoterm) m_RN; state_var m_last_state; - bool m_is_timestep; }; } // namespace devices diff --git a/src/lib/netlist/devices/nlid_system.h b/src/lib/netlist/devices/nlid_system.h index 34a8c599b3f..386b4f4b709 100644 --- a/src/lib/netlist/devices/nlid_system.h +++ b/src/lib/netlist/devices/nlid_system.h @@ -463,9 +463,10 @@ namespace devices 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 - m_R.solve_now(); - m_R.set_R(R); - m_R.solve_later(); + m_R.change_state([this, &R]() + { + m_R.set_R(R); + }); } } diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp index facd3f68bd0..e01bd8496a8 100644 --- a/src/lib/netlist/nl_base.cpp +++ b/src/lib/netlist/nl_base.cpp @@ -813,18 +813,10 @@ namespace netlist void terminal_t::solve_now() { + const auto *solv(solver()); // Nets may belong to railnets which do not have a solver attached - if (this->has_net()) - if (net().solver() != nullptr) - net().solver()->solve_now(); - } - - void terminal_t::schedule_solve_after(netlist_time after) noexcept - { - // Nets may belong to railnets which do not have a solver attached - if (this->has_net()) - if (net().solver() != nullptr) - net().solver()->update_after(after); + if (solv) + solver()->solve_now(); } // ---------------------------------------------------------------------------------------- diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index ba18104b2e4..53706060783 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -798,6 +798,8 @@ namespace netlist const analog_net_t & net() const noexcept; analog_net_t & net() noexcept; + + solver::matrix_solver_t *solver() const noexcept; }; // ----------------------------------------------------------------------------- @@ -834,7 +836,6 @@ namespace netlist } void solve_now(); - void schedule_solve_after(netlist_time after) noexcept; void set_ptrs(nl_fptype *gt, nl_fptype *go, nl_fptype *Idr) noexcept(false); @@ -945,6 +946,11 @@ namespace netlist solver::matrix_solver_t *solver() const noexcept { return m_solver; } void set_solver(solver::matrix_solver_t *solver) noexcept { m_solver = solver; } + friend constexpr bool operator==(const analog_net_t &lhs, const analog_net_t &rhs) noexcept + { + return &lhs == &rhs; + } + private: state_var m_cur_Analog; solver::matrix_solver_t *m_solver; @@ -1940,6 +1946,13 @@ namespace netlist return static_cast(core_terminal_t::net()); } + inline solver::matrix_solver_t *analog_t::solver() const noexcept + { + if (this->has_net()) + return net().solver(); + return nullptr; + } + inline nl_fptype terminal_t::operator ()() const noexcept { return net().Q_Analog(); } inline void terminal_t::set_ptrs(nl_fptype *gt, nl_fptype *go, nl_fptype *Idr) noexcept(false) diff --git a/src/lib/netlist/solver/nld_matrix_solver.cpp b/src/lib/netlist/solver/nld_matrix_solver.cpp index 2ea4a85d7cd..a84e958cca5 100644 --- a/src/lib/netlist/solver/nld_matrix_solver.cpp +++ b/src/lib/netlist/solver/nld_matrix_solver.cpp @@ -389,6 +389,20 @@ namespace solver inp->push(inp->proxied_net()->Q_Analog()); } + bool matrix_solver_t::updates_net(const analog_net_t *net) const noexcept + { + if (net != nullptr) + { + for (const auto &t : m_terms ) + if (t.is_net(net)) + return true; + for (const auto &inp : m_inps) + if (&inp->net() == net) + return true; + } + return false; + } + void matrix_solver_t::update_dynamic() noexcept { // update all non-linear devices @@ -412,22 +426,6 @@ namespace solver } } - void matrix_solver_t::solve_now() - { - // this should only occur outside of execution and thus - // using time should be safe. - - const netlist_time new_timestep = solve(exec().time()); - plib::unused_var(new_timestep); - - update_inputs(); - - if (m_params.m_dynamic_ts && (timestep_device_count() != 0)) - { - m_Q_sync.net().toggle_and_push_to_queue(netlist_time::from_fp(m_params.m_min_timestep)); - } - } - void matrix_solver_t::step(netlist_time delta) noexcept { const auto dd(delta.as_fp()); @@ -495,7 +493,7 @@ namespace solver int matrix_solver_t::get_net_idx(const analog_net_t *net) const noexcept { for (std::size_t k = 0; k < m_terms.size(); k++) - if (m_terms[k].isNet(net)) + if (m_terms[k].is_net(net)) return static_cast(k); return -1; } diff --git a/src/lib/netlist/solver/nld_matrix_solver.h b/src/lib/netlist/solver/nld_matrix_solver.h index 7bfcc0944c8..ec7bf9f9727 100644 --- a/src/lib/netlist/solver/nld_matrix_solver.h +++ b/src/lib/netlist/solver/nld_matrix_solver.h @@ -143,13 +143,11 @@ namespace solver terminal_t **terms() noexcept { return m_terms.data(); } - template ::value, void>> - FT getV() const noexcept { return static_cast(m_net->Q_Analog()); } + nl_fptype getV() const noexcept { return m_net->Q_Analog(); } - template ::value, void>> - void setV(FT v) noexcept { m_net->set_Q_Analog(static_cast(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 is_net(const analog_net_t * net) const noexcept { return net == m_net; } void set_railstart(std::size_t val) noexcept { m_railstart = val; } @@ -191,6 +189,14 @@ namespace solver netlist_time solve(netlist_time_ext now); void update_inputs(); + /// \brief Checks if solver may alter a net + /// + /// This checks if a solver will alter a net. Returns true if the + /// net is either part of the voltage vector or if it belongs to + /// the analog input nets connected to the solver. + + bool updates_net(const analog_net_t *net) const noexcept; + std::size_t dynamic_device_count() const noexcept { return m_dynamic_funcs.size(); } std::size_t timestep_device_count() const noexcept { return m_step_funcs.size(); } @@ -199,11 +205,30 @@ namespace solver /// This should only be called from update and update_param events. /// It's purpose is to bring voltage values to the current timestep. /// This will be called BEFORE updating object properties. - void solve_now(); + void solve_now() + { + // this should only occur outside of execution and thus + // using time should be safe. + + const netlist_time new_timestep = solve(exec().time()); + plib::unused_var(new_timestep); + + update_inputs(); + + if (m_params.m_dynamic_ts && (timestep_device_count() != 0)) + { + m_Q_sync.net().toggle_and_push_to_queue(netlist_time::from_fp(m_params.m_min_timestep)); + } + } - void update_after(netlist_time after) noexcept + template + void change_state(F f, netlist_time delay = netlist_time::quantum()) { - m_Q_sync.net().toggle_and_push_to_queue(after); + // We only need to update the net first if this is a time stepping net + if (timestep_device_count() > 0) + solve_now(); + f(); + m_Q_sync.net().toggle_and_push_to_queue(delay); } // netdevice functions @@ -413,7 +438,7 @@ namespace solver { const std::size_t iN = size(); for (std::size_t i = 0; i < iN; i++) - this->m_terms[i].setV(m_new_V[i]); + this->m_terms[i].setV(static_cast(m_new_V[i])); } #else // global tanh damping (4.197) @@ -439,7 +464,7 @@ namespace solver const auto vntol(static_cast(m_params.m_vntol)); for (std::size_t i = 0; i < iN; i++) { - const auto vold(this->m_terms[i].template getV()); + const auto vold(static_cast(this->m_terms[i].getV())); const auto vnew(m_new_V[i]); const auto tol(vntol + reltol * std::max(plib::abs(vnew),plib::abs(vold))); if (plib::abs(vnew - vold) > tol) @@ -455,7 +480,7 @@ namespace solver for (std::size_t k = 0; k < size(); k++) { const auto &t = m_terms[k]; - const auto v(t.template getV()); + const auto v(static_cast(t.getV())); // avoid floating point exceptions const nl_fptype DD_n = std::max(-fp_constants::TIMESTEP_MAXDIFF(), std::min(+fp_constants::TIMESTEP_MAXDIFF(),(v - m_last_V[k]))); diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp index 35a5afd961d..f9870bf68d5 100644 --- a/src/lib/netlist/solver/nld_solver.cpp +++ b/src/lib/netlist/solver/nld_solver.cpp @@ -183,30 +183,27 @@ namespace devices { return create_solver(net_count, sname, nets); } - else if (net_count <= 32) + if (net_count <= 32) { return create_solver(net_count, sname, nets); } - else if (net_count <= 64) + if (net_count <= 64) { return create_solver(net_count, sname, nets); } - else if (net_count <= 128) + if (net_count <= 128) { return create_solver(net_count, sname, nets); } - else if (net_count <= 256) + if (net_count <= 256) { return create_solver(net_count, sname, nets); } - else if (net_count <= 512) + if (net_count <= 512) { return create_solver(net_count, sname, nets); } - else - { - return create_solver(net_count, sname, nets); - } + return create_solver(net_count, sname, nets); break; } } -- cgit v1.2.3