diff --git a/src/lib/netlist/devices/nld_4066.cpp b/src/lib/netlist/devices/nld_4066.cpp index bd9b7bfe004..a45b2ab9e22 100644 --- a/src/lib/netlist/devices/nld_4066.cpp +++ b/src/lib/netlist/devices/nld_4066.cpp @@ -23,6 +23,7 @@ namespace netlist , m_R(*this, "R") , m_control(*this, "CTL") , m_base_r(*this, "BASER", nlconst::magic(270.0)) + , m_last(*this, "m_last", false) { } @@ -34,7 +35,8 @@ namespace netlist analog::NETLIB_SUB(R_base) m_R; analog_input_t m_control; - param_fp_t m_base_r; + param_fp_t m_base_r; + state_var m_last; }; NETLIB_RESET(CD4066_GATE) @@ -53,6 +55,7 @@ namespace netlist nl_fptype in = m_control() - m_supply.GND().Q_Analog(); nl_fptype rON = m_base_r() * nlconst::magic(5.0) / sup; nl_fptype R = -nlconst::one(); + bool new_state(false); if (in < low) { @@ -61,10 +64,12 @@ namespace netlist else if (in > high) { R = rON; + new_state = true; } //printf("%s %f %f %g\n", name().c_str(), sup, in, R); - if (R > nlconst::zero()) + if (R > nlconst::zero() && (m_last != new_state)) { + m_last = new_state; m_R.update(); m_R.set_R(R); m_R.solve_later(); diff --git a/src/lib/netlist/nl_config.h b/src/lib/netlist/nl_config.h index 3d50da284c4..f6b594af977 100644 --- a/src/lib/netlist/nl_config.h +++ b/src/lib/netlist/nl_config.h @@ -17,7 +17,7 @@ /// /// \brief Version - Minor. /// -#define NL_VERSION_MINOR 9 +#define NL_VERSION_MINOR 10 /// \brief Version - Patch level. /// #define NL_VERSION_PATCHLEVEL 0 diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp index 09920dfd73c..a4eedc38ed7 100644 --- a/src/lib/netlist/solver/nld_solver.cpp +++ b/src/lib/netlist/solver/nld_solver.cpp @@ -253,28 +253,45 @@ namespace devices struct net_splitter { - bool already_processed(const analog_net_t &n) const + bool already_processed(const analog_net_t &n) { // no need to process rail nets - these are known variables if (n.isRailNet()) return true; + // First check if it is in a previous group. + // In this case we need to merge this group into the current group + if (groupspre.size() > 1) + { + for (std::size_t i = 0; iname(), (int) term->type()); // only process analog terminals if (term->is_type(detail::terminal_type::TERMINAL)) { @@ -282,6 +299,7 @@ namespace devices // check the connected terminal // analog_net_t &connected_net = pt->connected_terminal()->net(); analog_net_t &connected_net = netlist.setup().get_connected_terminal(*pt)->net(); + netlist.log().verbose(" Connected net {}", connected_net.name()); if (!already_processed(connected_net)) process_net(netlist, connected_net); } @@ -292,22 +310,29 @@ namespace devices { for (auto & net : netlist.nets()) { - netlist.log().debug("processing {1}\n", net->name()); + netlist.log().debug("processing {1}", net->name()); + netlist.log().verbose("processing {1}", net->name()); if (!net->isRailNet() && net->num_cons() > 0) { - netlist.log().debug(" ==> not a rail net\n"); + netlist.log().debug(" ==> not a rail net"); + netlist.log().verbose(" ==> not a rail net"); // Must be an analog net auto &n = *static_cast(net.get()); if (!already_processed(n)) { - groups.emplace_back(analog_net_t::list_t()); + groupspre.emplace_back(analog_net_t::list_t()); process_net(netlist, n); } } } + for (auto &g : groupspre) + if (!g.empty()) + groups.push_back(g); } std::vector groups; + private: + std::vector groupspre; }; void NETLIB_NAME(solver)::post_start()