summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/solver/nld_solver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/netlist/solver/nld_solver.cpp')
-rw-r--r--src/lib/netlist/solver/nld_solver.cpp55
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()