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.cpp41
1 files changed, 33 insertions, 8 deletions
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; 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(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(), (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<analog_net_t *>(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<analog_net_t::list_t> groups;
+ private:
+ std::vector<analog_net_t::list_t> groupspre;
};
void NETLIB_NAME(solver)::post_start()