From 91ca668d141570b26879cf111d644515aca173e2 Mon Sep 17 00:00:00 2001 From: couriersud Date: Tue, 29 Sep 2020 22:35:18 +0200 Subject: netlist: Fix a net splitting issue with four term devices. * Under cirtum circumstances the splitter would create "ghost" solvers consisting of terminals already used in another and complete solver. This may impact all netlist which use opamps and thus is committed early in the cycle. * This commit adds functionality to instruct the splitter code to include terminals which will not create matrix elements into the parsing of net groups for solvers. --- src/lib/netlist/analog/nlid_fourterm.h | 15 +++++++++++---- src/lib/netlist/core/analog.h | 3 +++ src/lib/netlist/core/setup.h | 18 ++++++++++++++---- src/lib/netlist/nl_base.cpp | 12 ++++++++++-- src/lib/netlist/nl_setup.cpp | 4 ++-- src/lib/netlist/solver/nld_solver.cpp | 12 ++++++++---- src/mame/audio/nl_astrob.cpp | 1 - 7 files changed, 48 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/lib/netlist/analog/nlid_fourterm.h b/src/lib/netlist/analog/nlid_fourterm.h index 02ca5a9563b..8656cf7e32f 100644 --- a/src/lib/netlist/analog/nlid_fourterm.h +++ b/src/lib/netlist/analog/nlid_fourterm.h @@ -39,16 +39,20 @@ namespace analog { NETLIB_CONSTRUCTOR_EX(VCCS, nl_fptype ri = nlconst::magic(1e9)) , m_G(*this, "G", nlconst::one()) , m_RI(*this, "RI", ri) - , m_OP(*this, "OP", &m_IP, NETLIB_DELEGATE(termhandler)) - , m_ON(*this, "ON", &m_IP, NETLIB_DELEGATE(termhandler)) - , m_IP(*this, "IP", &m_IN, NETLIB_DELEGATE(termhandler)) // <= this should be NULL and terminal be filtered out prior to solving... - , m_IN(*this, "IN", &m_IP, NETLIB_DELEGATE(termhandler)) // <= this should be NULL and terminal be filtered out prior to solving... + , m_OP(*this, "OP", &m_IP, {&m_ON, &m_IN}, NETLIB_DELEGATE(termhandler)) + , m_ON(*this, "ON", &m_IP, {&m_OP, &m_IN}, NETLIB_DELEGATE(termhandler)) + , m_IP(*this, "IP", &m_IN, {&m_OP, &m_ON}, NETLIB_DELEGATE(termhandler)) + , m_IN(*this, "IN", &m_IP, {&m_OP, &m_ON}, NETLIB_DELEGATE(termhandler)) , m_OP1(*this, "_OP1", &m_IN, NETLIB_DELEGATE(termhandler)) , m_ON1(*this, "_ON1", &m_IN, NETLIB_DELEGATE(termhandler)) + //, m_IPx(*this, "_IPx", &m_OP, NETLIB_DELEGATE(termhandler)) // <= this should be NULL and terminal be filtered out prior to solving... + //, m_INx(*this, "_INx", &m_ON, NETLIB_DELEGATE(termhandler)) // <= this should be NULL and terminal be filtered out prior to solving... , m_gfac(nlconst::one()) { connect(m_OP, m_OP1); connect(m_ON, m_ON1); + //connect(m_IP, m_IPx); + //connect(m_IN, m_INx); } NETLIB_RESETI(); @@ -82,6 +86,9 @@ namespace analog { terminal_t m_OP1; terminal_t m_ON1; + //terminal_t m_IPx; + //terminal_t m_INx; + private: nl_fptype m_gfac; }; diff --git a/src/lib/netlist/core/analog.h b/src/lib/netlist/core/analog.h index 4bc986f48fc..d6f217210c4 100644 --- a/src/lib/netlist/core/analog.h +++ b/src/lib/netlist/core/analog.h @@ -61,6 +61,9 @@ namespace netlist /// @param otherterm pointer to the sibling terminal terminal_t(core_device_t &dev, const pstring &aname, terminal_t *otherterm, nldelegate delegate); + terminal_t(core_device_t &dev, const pstring &aname, terminal_t *otherterm, + const std::array &splitterterms, nldelegate delegate); + /// \brief Returns voltage of connected net /// /// @return voltage of net this terminal is connected to diff --git a/src/lib/netlist/core/setup.h b/src/lib/netlist/core/setup.h index 8b8a49dbc34..ba783c52130 100644 --- a/src/lib/netlist/core/setup.h +++ b/src/lib/netlist/core/setup.h @@ -144,13 +144,21 @@ namespace netlist pstring get_initial_param_val(const pstring &name, const pstring &def) const; void register_term(detail::core_terminal_t &term); - void register_term(terminal_t &term, terminal_t &other_term); + void register_term(terminal_t &term, terminal_t *other_term, const std::array &splitter_terms); - // called from net_splitter + // called from matrix_solver_t::get_connected_net + // returns the terminal being part of a two terminal device. terminal_t *get_connected_terminal(const terminal_t &term) const noexcept { auto ret(m_connected_terminals.find(&term)); - return (ret != m_connected_terminals.end()) ? ret->second : nullptr; + return (ret != m_connected_terminals.end()) ? ret->second[0] : nullptr; + } + + // called from net_splitter + const std::array *get_connected_terminals(const terminal_t &term) const noexcept + { + auto ret(m_connected_terminals.find(&term)); + return (ret != m_connected_terminals.end()) ? &ret->second : nullptr; } // get family -> truthtable @@ -223,7 +231,9 @@ namespace netlist // FIXME: can be cleared before run std::unordered_map m_terminals; - std::unordered_map m_connected_terminals; + // FIXME: Limited to 3 additional terminals + std::unordered_map> m_connected_terminals; std::unordered_map m_params; std::unordered_map m_proxies; diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp index 7e0e5f0425f..52cad23e9ba 100644 --- a/src/lib/netlist/nl_base.cpp +++ b/src/lib/netlist/nl_base.cpp @@ -703,13 +703,21 @@ namespace netlist // terminal_t // ---------------------------------------------------------------------------------------- - terminal_t::terminal_t(core_device_t &dev, const pstring &aname, terminal_t *otherterm, nldelegate delegate) + terminal_t::terminal_t(core_device_t &dev, const pstring &aname, + terminal_t *otherterm, nldelegate delegate) + : terminal_t(dev, aname, otherterm, { nullptr, nullptr }, delegate) + { + } + + terminal_t::terminal_t(core_device_t &dev, const pstring &aname, + terminal_t *otherterm, const std::array &splitterterms, + nldelegate delegate) : analog_t(dev, aname, STATE_BIDIR, delegate) , m_Idr(nullptr) , m_go(nullptr) , m_gt(nullptr) { - state().setup().register_term(*this, *otherterm); + state().setup().register_term(*this, otherterm, splitterterms); } void terminal_t::set_ptrs(nl_fptype *gt, nl_fptype *go, nl_fptype *Idr) noexcept(false) diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp index 3a4a952841e..09c84642c75 100644 --- a/src/lib/netlist/nl_setup.cpp +++ b/src/lib/netlist/nl_setup.cpp @@ -552,10 +552,10 @@ void setup_t::register_term(detail::core_terminal_t &term) } } -void setup_t::register_term(terminal_t &term, terminal_t &other_term) +void setup_t::register_term(terminal_t &term, terminal_t *other_term, const std::array &splitter_terms) { this->register_term(term); - m_connected_terminals.insert({&term, &other_term}); + m_connected_terminals.insert({&term, {other_term, splitter_terms[0], splitter_terms[1], nullptr}}); } void setup_t::register_param_t(param_t ¶m) diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp index 9f152369001..09a43178e55 100644 --- a/src/lib/netlist/solver/nld_solver.cpp +++ b/src/lib/netlist/solver/nld_solver.cpp @@ -361,10 +361,14 @@ namespace devices { auto &pt = dynamic_cast(*term); // check the connected terminal - analog_net_t &connected_net = netlist.setup().get_connected_terminal(pt)->net(); - netlist.log().verbose(" Connected net {}", connected_net.name()); - if (!check_if_processed_and_join(connected_net)) - process_net(netlist, connected_net); + auto connected_terminals = netlist.setup().get_connected_terminals(pt); + for (auto ct = connected_terminals->begin(); *ct != nullptr; ct++) + { + analog_net_t &connected_net = (*ct)->net(); + netlist.log().verbose(" Connected net {}", connected_net.name()); + if (!check_if_processed_and_join(connected_net)) + process_net(netlist, connected_net); + } } } } diff --git a/src/mame/audio/nl_astrob.cpp b/src/mame/audio/nl_astrob.cpp index e4718888a4b..9633191499a 100644 --- a/src/mame/audio/nl_astrob.cpp +++ b/src/mame/audio/nl_astrob.cpp @@ -1201,7 +1201,6 @@ NETLIST_START(astrob) // // Unconnected outputs // - NET_C(GND, U7.7, U7.14) // avoid singular matrices #if (ENABLE_FRONTIERS) #define RXX 192 -- cgit v1.2.3-70-g09d2