diff options
Diffstat (limited to 'src/lib/netlist/solver/nld_solver.cpp')
-rw-r--r-- | src/lib/netlist/solver/nld_solver.cpp | 55 |
1 files changed, 41 insertions, 14 deletions
diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp index 4b24e003d52..977b6ae7b20 100644 --- a/src/lib/netlist/solver/nld_solver.cpp +++ b/src/lib/netlist/solver/nld_solver.cpp @@ -27,6 +27,7 @@ #endif #include "netlist/nl_factory.h" +#include "netlist/nl_setup.h" // FIXME: only needed for splitter code #include "nld_matrix_solver.h" #include "nld_ms_direct.h" #include "nld_ms_direct1.h" @@ -68,10 +69,10 @@ namespace devices if (m_params.m_dynamic_ts) return; - netlist_time now(exec().time()); + netlist_time_ext now(exec().time()); // force solving during start up if there are no time-step devices // FIXME: Needs a more elegant solution - bool force_solve = (now < netlist_time::from_fp<decltype(m_params.m_max_timestep)>(2 * m_params.m_max_timestep)); + bool force_solve = (now < netlist_time_ext::from_fp<decltype(m_params.m_max_timestep)>(2 * m_params.m_max_timestep)); std::size_t nthreads = std::min(static_cast<std::size_t>(m_params.m_parallel()), plib::omp::get_max_threads()); @@ -252,36 +253,55 @@ 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; i<groupspre.size() - 1; i++) + if (plib::container::contains(groupspre[i], &n)) + { + // copy all nets + for (auto & cn : groupspre[i]) + if (!plib::container::contains(groupspre.back(), cn)) + groupspre.back().push_back(cn); + // clear + groupspre[i].clear(); + return true; + } + } // if it's already processed - no need to continue - for (auto & grp : groups) - if (plib::container::contains(grp, &n)) - return true; + if (!groupspre.empty() && plib::container::contains(groupspre.back(), &n)) + return true; return false; } - void process_net(analog_net_t &n) + void process_net(netlist_state_t &netlist, analog_net_t &n) { // ignore empty nets. FIXME: print a warning message + netlist.log().verbose("Net {}", n.name()); if (n.num_cons() == 0) return; // add the net - groups.back().push_back(&n); + groupspre.back().push_back(&n); // process all terminals connected to this net for (auto &term : n.core_terms()) { + netlist.log().verbose("Term {} {}", term->name(), static_cast<int>(term->type())); // only process analog terminals if (term->is_type(detail::terminal_type::TERMINAL)) { auto *pt = static_cast<terminal_t *>(term); // check the connected terminal - analog_net_t &connected_net = pt->connected_terminal()->net(); + // 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(connected_net); + process_net(netlist, connected_net); } } } @@ -290,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<analog_net_t *>(net.get()); if (!already_processed(n)) { - groups.emplace_back(analog_net_t::list_t()); - process_net(n); + 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<analog_net_t::list_t> groups; + private: + std::vector<analog_net_t::list_t> groupspre; }; void NETLIB_NAME(solver)::post_start() |