diff options
author | couriersud <couriersud@gmx.org> | 2019-11-14 22:59:07 +0100 |
---|---|---|
committer | couriersud <couriersud@gmx.org> | 2019-11-14 22:59:07 +0100 |
commit | dc4fa0420182bffb9be8d5e9f654d94b9aafe6b1 (patch) | |
tree | eeda982478b0204dc16ed77eb2e0dd8b79ceb0e5 /src/lib/netlist | |
parent | ce3c38914d4b710e2e40c212af0d61aa4b328de0 (diff) |
netlist: Proxy and power terminal hack removal. [Couriersud]
- Devices ttlhigh and ttlhow are no longer automatically created.
- All logic input devices (e.g. TTL_INPUT, LOGIC_INPUT) now need to have
their power terminals (VCC, GND) connected. This opens the route
for more appropriate proxy devices but comes at a cost. If the
connections are omitted your circuit will not work as expected.
Example:
LOGIC_INPUT(I_SD0, 1, "AY8910PORT")
NET_C(VCC, I_SD0.VCC)
NET_C(GND, I_SD0.GND)
- Updated all netlists.
- Removed proxy information from terminal objects. This was replaced by
a lookup hash whose life-span does not exceed netlest setup.
These changes enable the removal of a number of hacks from the
source going forward.
Diffstat (limited to 'src/lib/netlist')
-rw-r--r-- | src/lib/netlist/analog/nlid_twoterm.h | 12 | ||||
-rw-r--r-- | src/lib/netlist/devices/nld_tms4800.cpp | 5 | ||||
-rw-r--r-- | src/lib/netlist/devices/nld_tms4800.h | 4 | ||||
-rw-r--r-- | src/lib/netlist/devices/nlid_proxy.cpp | 87 | ||||
-rw-r--r-- | src/lib/netlist/devices/nlid_proxy.h | 6 | ||||
-rw-r--r-- | src/lib/netlist/devices/nlid_system.h | 87 | ||||
-rw-r--r-- | src/lib/netlist/macro/nlm_base.cpp | 2 | ||||
-rw-r--r-- | src/lib/netlist/nl_base.cpp | 1 | ||||
-rw-r--r-- | src/lib/netlist/nl_base.h | 12 | ||||
-rw-r--r-- | src/lib/netlist/nl_errstr.h | 1 | ||||
-rw-r--r-- | src/lib/netlist/nl_setup.cpp | 61 | ||||
-rw-r--r-- | src/lib/netlist/nl_setup.h | 3 | ||||
-rw-r--r-- | src/lib/netlist/solver/nld_matrix_solver.h | 10 |
13 files changed, 184 insertions, 107 deletions
diff --git a/src/lib/netlist/analog/nlid_twoterm.h b/src/lib/netlist/analog/nlid_twoterm.h index 99c962a5c8c..a052153e531 100644 --- a/src/lib/netlist/analog/nlid_twoterm.h +++ b/src/lib/netlist/analog/nlid_twoterm.h @@ -38,7 +38,7 @@ #include "netlist/nl_setup.h" #include "netlist/solver/nld_solver.h" #include "nld_generic_models.h" -#include "plib/pfunction.h" +#include "netlist/plib/pfunction.h" // ----------------------------------------------------------------------------- // Implementation @@ -102,6 +102,16 @@ namespace analog return m_P.net().Q_Analog() - m_N.net().Q_Analog(); } + nl_fptype V1P() const noexcept + { + return m_P.net().Q_Analog(); + } + + nl_fptype V2N() const noexcept + { + return m_N.net().Q_Analog(); + } + void set_mat(nl_fptype a11, nl_fptype a12, nl_fptype rhs1, nl_fptype a21, nl_fptype a22, nl_fptype rhs2) const noexcept { diff --git a/src/lib/netlist/devices/nld_tms4800.cpp b/src/lib/netlist/devices/nld_tms4800.cpp index cecdf8c2384..01b9c09f321 100644 --- a/src/lib/netlist/devices/nld_tms4800.cpp +++ b/src/lib/netlist/devices/nld_tms4800.cpp @@ -7,6 +7,7 @@ #include "nld_tms4800.h" #include "netlist/nl_base.h" +#include "netlist/devices/nlid_system.h" namespace netlist { @@ -22,6 +23,7 @@ namespace netlist , m_D(*this, {{ "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7" }}) , m_last_data(*this, "m_last_data", 1) , m_ROM(*this, "ROM") + , m_supply(*this) { } @@ -37,6 +39,7 @@ namespace netlist state_var<unsigned> m_last_data; param_rom_t<uint8_t, 11, 8> m_ROM; // 16 Kbits, used as 2 Kbit x 8 + NETLIB_NAME(power_pins) m_supply; }; NETLIB_OBJECT_DERIVED(TMS4800_dip, TMS4800) @@ -97,7 +100,7 @@ namespace netlist } } - NETLIB_DEVICE_IMPL(TMS4800, "ROM_TMS4800", "+AR,+OE1,+OE2,+A0,+A1,+A2,+A3,+A4,+A5,+A6,+A7,+A8,+A9,+A10") + NETLIB_DEVICE_IMPL(TMS4800, "ROM_TMS4800", "+AR,+OE1,+OE2,+A0,+A1,+A2,+A3,+A4,+A5,+A6,+A7,+A8,+A9,+A10,@VCC,@GND") NETLIB_DEVICE_IMPL(TMS4800_dip, "ROM_TMS4800_DIP", "") } //namespace devices diff --git a/src/lib/netlist/devices/nld_tms4800.h b/src/lib/netlist/devices/nld_tms4800.h index c5bcd1337f0..8a70fdd78aa 100644 --- a/src/lib/netlist/devices/nld_tms4800.h +++ b/src/lib/netlist/devices/nld_tms4800.h @@ -45,7 +45,9 @@ NET_CONNECT(name, A7, cA7) \ NET_CONNECT(name, A8, cA8) \ NET_CONNECT(name, A9, cA9) \ - NET_CONNECT(name, A10, cA10) + NET_CONNECT(name, A10, cA10) \ + NET_CONNECT(name, VCC, VCC) \ + NET_CONNECT(name, GND, GND) #define ROM_TMS4800_DIP(name) \ NET_REGISTER_DEV(ROM_TMS4800_DIP, name) diff --git a/src/lib/netlist/devices/nlid_proxy.cpp b/src/lib/netlist/devices/nlid_proxy.cpp index 6e4dba84c4e..dc613c58f4c 100644 --- a/src/lib/netlist/devices/nlid_proxy.cpp +++ b/src/lib/netlist/devices/nlid_proxy.cpp @@ -33,20 +33,31 @@ namespace netlist for (auto & pwr_sym : power_syms) { pstring devname = inout_proxied->device().name(); - auto tp_t = anetlist.setup().find_terminal(devname + "." + pwr_sym.first, - /*detail::terminal_type::INPUT,*/ false); - auto tn_t = anetlist.setup().find_terminal(devname + "." + pwr_sym.second, - /*detail::terminal_type::INPUT,*/ false); - if (f && (tp_t != nullptr && tn_t != nullptr)) - log().warning(MI_MULTIPLE_POWER_TERMINALS_ON_DEVICE(inout_proxied->device().name(), - m_tp->name(), m_tn->name(), - tp_t ? tp_t->name() : "", - tn_t ? tn_t->name() : "")); - else if (tp_t != nullptr && tn_t != nullptr) + + auto tp_ct(anetlist.setup().find_terminal(devname + "." + pwr_sym.first, + /*detail::terminal_type::INPUT,*/ false)); + auto tp_cn(anetlist.setup().find_terminal(devname + "." + pwr_sym.second, + /*detail::terminal_type::INPUT,*/ false)); + if (tp_ct && tp_cn) { - m_tp = tp_t; - m_tn = tn_t; - f = true; + if (tp_ct && !tp_ct->is_analog()) + plib::pthrow<nl_exception>(plib::pfmt("Not an analog terminal: {1}")(tp_ct->name())); + if (tp_cn && !tp_cn->is_analog()) + plib::pthrow<nl_exception>(plib::pfmt("Not an analog terminal: {1}")(tp_cn->name())); + + auto tp_t = static_cast<analog_t* >(tp_ct); + auto tn_t = static_cast<analog_t *>(tp_cn); + if (f && (tp_t != nullptr && tn_t != nullptr)) + log().warning(MI_MULTIPLE_POWER_TERMINALS_ON_DEVICE(inout_proxied->device().name(), + m_tp->name(), m_tn->name(), + tp_t ? tp_t->name() : "", + tn_t ? tn_t->name() : "")); + else if (tp_t != nullptr && tn_t != nullptr) + { + m_tp = tp_t; + m_tn = tn_t; + f = true; + } } } //FIXME: Use power terminals and change info to warning or error @@ -56,7 +67,7 @@ namespace netlist if (logic_family()->fixed_V() == nlconst::zero()) log().error(MI_NO_POWER_TERMINALS_ON_DEVICE_2(name, anetlist.setup().de_alias(inout_proxied->device().name()))); else - log().info(MI_NO_POWER_TERMINALS_ON_DEVICE_2(name, anetlist.setup().de_alias(inout_proxied->device().name()))); + log().warning(MI_NO_POWER_TERMINALS_ON_DEVICE_2(name, anetlist.setup().de_alias(inout_proxied->device().name()))); #endif m_GNDHack = plib::make_unique<analog_output_t>(*this, "_QGND"); m_VCCHack = plib::make_unique<analog_output_t>(*this, "_QVCC"); @@ -93,10 +104,24 @@ namespace netlist NETLIB_RESET(a_to_d_proxy) { + // FIXME: Variable voltage + nl_fptype supply_V = logic_family()->fixed_V(); + // FIXME: comparison to zero + if (supply_V == nlconst::zero()) + supply_V = nlconst::magic(5.0); + + if (need_hack()) + { + if (m_tn) + m_GNDHack->initial(0); + if (m_tp) + m_VCCHack->initial(supply_V); + } } NETLIB_UPDATE(a_to_d_proxy) { +#if 0 nl_assert(m_logic_family != nullptr); // FIXME: Variable supply voltage! nl_fptype supply_V = logic_family()->fixed_V(); @@ -111,6 +136,20 @@ namespace netlist { // do nothing } +#else + const auto v(m_I.Q_Analog()); + const auto vn(m_tn->net().Q_Analog()); + const auto vp(m_tp->net().Q_Analog()); + + if (logic_family()->is_above_high_thresh_V(v, vn, vp)) + out().push(1, netlist_time::quantum()); + else if (logic_family()->is_below_low_thresh_V(v, vn, vp)) + out().push(0, netlist_time::quantum()); + else + { + // do nothing + } +#endif } // ---------------------------------------------------------------------------------------- @@ -133,18 +172,20 @@ namespace netlist { register_subalias("Q", m_RN.m_P); - //FIXME: Use power terminals and change info to warning or error if (need_hack()) { -#if 1 - // FIXME: move to base proxy class - if (logic_family()->fixed_V() == nlconst::zero()) - log().error(MI_NO_POWER_TERMINALS_ON_DEVICE_2(name, anetlist.setup().de_alias(out_proxied->device().name()))); + if (anetlist.setup().is_extended_validation()) + { + // During validation, don't connect to terminals found + // This will cause terminals not connected to a rail net to + // fail connection stage. + connect(m_RN.m_N, m_RP.m_P); + } else - log().info(MI_NO_POWER_TERMINALS_ON_DEVICE_2(name, anetlist.setup().de_alias(out_proxied->device().name()))); -#endif - connect(m_RN.m_N, *m_tn); - connect(m_RP.m_P, *m_tp); + { + connect(m_RN.m_N, *m_tn); + connect(m_RP.m_P, *m_tp); + } connect(m_RN.m_P, m_RP.m_N); } else diff --git a/src/lib/netlist/devices/nlid_proxy.h b/src/lib/netlist/devices/nlid_proxy.h index 24692508c51..eb2f2dd5ade 100644 --- a/src/lib/netlist/devices/nlid_proxy.h +++ b/src/lib/netlist/devices/nlid_proxy.h @@ -33,8 +33,10 @@ namespace devices detail::core_terminal_t &proxy_term() const { return *m_proxy_term; } protected: - detail::core_terminal_t *m_tp; - detail::core_terminal_t *m_tn; + // FIXME: these should be core_terminal_t and only used for connecting + // inputs. Fix, once the ugly hacks have been removed + analog_t *m_tp; + analog_t *m_tn; plib::unique_ptr<analog_output_t> m_GNDHack; // FIXME: Long term, we need to connect proxy gnd to device gnd plib::unique_ptr<analog_output_t> m_VCCHack; // FIXME: Long term, we need to connect proxy gnd to device gnd diff --git a/src/lib/netlist/devices/nlid_system.h b/src/lib/netlist/devices/nlid_system.h index 44ad1f8efc2..a59a5ca5adf 100644 --- a/src/lib/netlist/devices/nlid_system.h +++ b/src/lib/netlist/devices/nlid_system.h @@ -10,7 +10,7 @@ #include "netlist/analog/nlid_twoterm.h" #include "netlist/nl_base.h" #include "netlist/nl_setup.h" -#include "plib/putil.h" +#include "netlist/plib/putil.h" namespace netlist { @@ -41,6 +41,50 @@ namespace devices }; // ----------------------------------------------------------------------------- + // power pins - not a device, but a helper + // ----------------------------------------------------------------------------- + + /// \brief Power pins class. + /// + /// Power Pins are passive inputs. Delegate noop will silently ignore any + /// updates. + class nld_power_pins + { + public: + explicit nld_power_pins(device_t &owner, const pstring &sVCC = sPowerVCC, + const pstring &sGND = sPowerGND, bool force_analog_input = true) + { + if (owner.state().setup().is_extended_validation() || force_analog_input) + { + m_GND = owner.state().make_object<analog_input_t>(owner, sGND, NETLIB_DELEGATE(power_pins, noop)); + m_VCC = owner.state().make_object<analog_input_t>(owner, sVCC, NETLIB_DELEGATE(power_pins, noop)); + } + else + { + owner.create_and_register_subdevice(sPowerDevRes, m_RVG); + owner.register_subalias(sVCC, pstring(sPowerDevRes) + ".1"); + owner.register_subalias(sGND, pstring(sPowerDevRes) + ".2"); + } + } + + nl_fptype VCC() const noexcept + { + return (m_VCC ? m_VCC->Q_Analog() : m_RVG->V1P()); + } + nl_fptype GND() const noexcept + { + return (m_GND ? m_GND->Q_Analog() : m_RVG->V2N()); + } + + private: + void noop() { } + unique_pool_ptr<analog_input_t> m_VCC; // only used during validation or force_analog_input + unique_pool_ptr<analog_input_t> m_GND; // only used during validation or force_analog_input + + NETLIB_SUB_UPTR(analog, R) m_RVG; // dummy resistor between VCC and GND + }; + + // ----------------------------------------------------------------------------- // clock // ----------------------------------------------------------------------------- @@ -188,6 +232,7 @@ namespace devices , m_IN(*this, "IN", false) // make sure we get the family first , m_FAMILY(*this, "FAMILY", "FAMILY(TYPE=TTL)") + , m_supply(*this) { set_logic_family(state().setup().family_from_model(m_FAMILY())); m_Q.set_logic_family(this->logic_family()); @@ -202,6 +247,7 @@ namespace devices param_logic_t m_IN; param_model_t m_FAMILY; + NETLIB_NAME(power_pins) m_supply; }; NETLIB_OBJECT(analog_input) @@ -410,45 +456,6 @@ namespace devices state_var<netlist_sig_t> m_last_state; }; - // ----------------------------------------------------------------------------- - // power pins - not a device, but a helper - // ----------------------------------------------------------------------------- - - /// \brief Power pins class. - /// - /// Power Pins are passive inputs. Delegate noop will silently ignore any - /// updates. - class nld_power_pins - { - public: - explicit nld_power_pins(device_t &owner, const pstring &sVCC = sPowerVCC, - const pstring &sGND = sPowerGND, bool force_analog_input = false) - { - if (owner.state().setup().is_extended_validation() || force_analog_input) - { - m_GND = owner.state().make_object<analog_input_t>(owner, sGND, NETLIB_DELEGATE(power_pins, noop)); - m_VCC = owner.state().make_object<analog_input_t>(owner, sVCC, NETLIB_DELEGATE(power_pins, noop)); - } - else - { - owner.create_and_register_subdevice(sPowerDevRes, m_RVG); - owner.register_subalias(sVCC, pstring(sPowerDevRes) + ".1"); - owner.register_subalias(sGND, pstring(sPowerDevRes) + ".2"); - } - } - - // FIXME: this will seg-fault if force_analog_input = false - nl_fptype VCC() const noexcept { return m_VCC->Q_Analog(); } - nl_fptype GND() const noexcept { return m_GND->Q_Analog(); } - - private: - void noop() { } - unique_pool_ptr<analog_input_t> m_VCC; // only used during validation or force_analog_input - unique_pool_ptr<analog_input_t> m_GND; // only used during validation or force_analog_input - - NETLIB_SUB_UPTR(analog, R) m_RVG; // dummy resistor between VCC and GND - }; - } // namespace devices } // namespace netlist diff --git a/src/lib/netlist/macro/nlm_base.cpp b/src/lib/netlist/macro/nlm_base.cpp index cbc6a5ac772..79a6a358fa7 100644 --- a/src/lib/netlist/macro/nlm_base.cpp +++ b/src/lib/netlist/macro/nlm_base.cpp @@ -89,8 +89,6 @@ NETLIST_END() * ---------------------------------------------------------------------------*/ NETLIST_START(base) - TTL_INPUT(ttlhigh, 1) - TTL_INPUT(ttllow, 0) NET_REGISTER_DEV(GNDA, GND) NET_REGISTER_DEV(PARAMETER, NETLIST) diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp index 7a9ed54c7d7..1213636d837 100644 --- a/src/lib/netlist/nl_base.cpp +++ b/src/lib/netlist/nl_base.cpp @@ -762,7 +762,6 @@ namespace netlist nldelegate delegate) : core_terminal_t(dev, aname, state, delegate) , logic_family_t() - , m_proxy(nullptr) { } diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index c88b1ce6797..e80267105ae 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -267,6 +267,12 @@ namespace netlist nl_fptype R_low() const noexcept{ return m_R_low; } nl_fptype R_high() const noexcept{ return m_R_high; } + bool is_above_high_thresh_V(nl_fptype V, nl_fptype VN, nl_fptype VP) const noexcept + { return (V - VN) > high_thresh_V(VN, VP); } + + bool is_below_low_thresh_V(nl_fptype V, nl_fptype VN, nl_fptype VP) const noexcept + { return (V - VN) < low_thresh_V(VN, VP); } + nl_fptype m_fixed_V; //!< For variable voltage families, specify 0. For TTL this would be 5. nl_fptype m_low_thresh_PCNT; //!< low input threshhold offset. If the input voltage is below this value times supply voltage, a "0" input is signalled nl_fptype m_high_thresh_PCNT; //!< high input threshhold offset. If the input voltage is above the value times supply voltage, a "0" input is signalled @@ -839,17 +845,12 @@ namespace netlist logic_t(core_device_t &dev, const pstring &aname, const state_e state, nldelegate delegate = nldelegate()); - bool has_proxy() const noexcept { return (m_proxy != nullptr); } - devices::nld_base_proxy *get_proxy() const noexcept { return m_proxy; } - void set_proxy(devices::nld_base_proxy *proxy) noexcept { m_proxy = proxy; } - logic_net_t & net() noexcept; const logic_net_t & net() const noexcept; protected: private: - devices::nld_base_proxy *m_proxy; // FIXME: only used during setup }; // ----------------------------------------------------------------------------- @@ -914,7 +915,6 @@ namespace netlist using detail::net_t::set_Q_and_push; using detail::net_t::set_Q_time; using detail::net_t::Q_state_ptr; - }; class analog_net_t : public detail::net_t diff --git a/src/lib/netlist/nl_errstr.h b/src/lib/netlist/nl_errstr.h index 0ca71a75461..026b3476a16 100644 --- a/src/lib/netlist/nl_errstr.h +++ b/src/lib/netlist/nl_errstr.h @@ -81,6 +81,7 @@ namespace netlist PERRMSGV(MF_OBJECT_1_2_WRONG_TYPE, 2, "object {1}({2}) found but wrong type") PERRMSGV(MF_PARAMETER_1_2_NOT_FOUND, 2, "parameter {1}({2}) not found!") PERRMSGV(MF_CONNECTING_1_TO_2, 2, "Error connecting {1} to {2}") + PERRMSGV(MF_DUPLICATE_PROXY_1, 1, "Terminal {1} already has proxy") PERRMSGV(MF_MERGE_RAIL_NETS_1_AND_2, 2, "Trying to merge two rail nets: {1} and {2}") PERRMSGV(MF_OBJECT_INPUT_TYPE_1, 1, "Unable to determine input type of {1}") PERRMSGV(MF_OBJECT_OUTPUT_TYPE_1, 1, "Unable to determine output type of {1}") diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp index cb02b38ce7b..4722be06be0 100644 --- a/src/lib/netlist/nl_setup.cpp +++ b/src/lib/netlist/nl_setup.cpp @@ -506,7 +506,11 @@ detail::core_terminal_t *setup_t::find_terminal(const pstring &terminal_in, bool plib::pthrow<nl_exception>(MF_TERMINAL_1_2_NOT_FOUND(terminal_in, tname)); } if (term != nullptr) + { log().debug("Found input {1}\n", tname); + } + + // FIXME: this should resolve any proxy return term; } @@ -565,9 +569,9 @@ devices::nld_base_proxy *setup_t::get_d_a_proxy(detail::core_terminal_t &out) nl_assert(out.is_logic()); auto &out_cast = static_cast<logic_output_t &>(out); - devices::nld_base_proxy *proxy = out_cast.get_proxy(); + auto iter_proxy(m_proxies.find(&out)); - if (proxy == nullptr) + if (iter_proxy == m_proxies.end()) { // create a new one ... pstring x = plib::pfmt("proxy_da_{1}_{2}")(out.name())(m_proxy_cnt); @@ -587,17 +591,19 @@ devices::nld_base_proxy *setup_t::get_d_a_proxy(detail::core_terminal_t &out) new_proxy->proxy_term().name(), (*p).name())); } } - out.net().core_terms().clear(); // clear the list + out.net().core_terms().clear(); out.net().add_terminal(new_proxy->in()); - //out_cast.set_proxy(proxy); - Wrong! - proxy = new_proxy.get(); - out_cast.set_proxy(proxy); + auto proxy(new_proxy.get()); + if (!m_proxies.insert({&out, proxy}).second) + plib::pthrow<nl_exception>(MF_DUPLICATE_PROXY_1(out.name())); m_nlstate.register_device(new_proxy->name(), std::move(new_proxy)); + return proxy; } - return proxy; + else + return iter_proxy->second; } devices::nld_base_proxy *setup_t::get_a_d_proxy(detail::core_terminal_t &inp) @@ -605,20 +611,24 @@ devices::nld_base_proxy *setup_t::get_a_d_proxy(detail::core_terminal_t &inp) nl_assert(inp.is_logic()); auto &incast = dynamic_cast<logic_input_t &>(inp); - devices::nld_base_proxy *proxy = incast.get_proxy(); - if (proxy != nullptr) - return proxy; + auto iter_proxy(m_proxies.find(&inp)); + + if (iter_proxy != m_proxies.end()) + return iter_proxy->second; else { log().debug("connect_terminal_input: connecting proxy\n"); pstring x = plib::pfmt("proxy_ad_{1}_{2}")(inp.name())(m_proxy_cnt); auto new_proxy = incast.logic_family()->create_a_d_proxy(m_nlstate, x, &incast); //auto new_proxy = plib::owned_ptr<devices::nld_a_to_d_proxy>::Create(netlist(), x, &incast); - incast.set_proxy(new_proxy.get()); - m_proxy_cnt++; - auto ret = new_proxy.get(); + auto ret(new_proxy.get()); + + if (!m_proxies.insert({&inp, ret}).second) + plib::pthrow<nl_exception>(MF_DUPLICATE_PROXY_1(inp.name())); + + m_proxy_cnt++; // connect all existing terminals to new net @@ -644,6 +654,18 @@ devices::nld_base_proxy *setup_t::get_a_d_proxy(detail::core_terminal_t &inp) } } +detail::core_terminal_t &setup_t::resolve_proxy(detail::core_terminal_t &term) +{ + if (term.is_logic()) + { + auto &out = dynamic_cast<logic_t &>(term); + auto iter_proxy(m_proxies.find(&out)); + if (iter_proxy != m_proxies.end()) + return iter_proxy->second->proxy_term(); + } + return term; +} + void setup_t::merge_nets(detail::net_t &thisnet, detail::net_t &othernet) { log().debug("merging nets ...\n"); @@ -775,17 +797,6 @@ void setup_t::connect_terminals(detail::core_terminal_t &t1, detail::core_termin } } -static detail::core_terminal_t &resolve_proxy(detail::core_terminal_t &term) -{ - if (term.is_logic()) - { - auto &out = dynamic_cast<logic_t &>(term); - if (out.has_proxy()) - return out.get_proxy()->proxy_term(); - } - return term; -} - bool setup_t::connect_input_input(detail::core_terminal_t &t1, detail::core_terminal_t &t2) { bool ret = false; @@ -840,7 +851,7 @@ bool setup_t::connect(detail::core_terminal_t &t1_in, detail::core_terminal_t &t } else if (t1.is_type(detail::terminal_type::INPUT) && t2.is_type(detail::terminal_type::OUTPUT)) { - if (t1.has_net() && t1.net().isRailNet()) + if (t1.has_net() && t1.net().isRailNet()) { log().fatal(MF_INPUT_1_ALREADY_CONNECTED(t1.name())); plib::pthrow<nl_exception>(MF_INPUT_1_ALREADY_CONNECTED(t1.name())); diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h index 68d0e6d41ee..e07a8009157 100644 --- a/src/lib/netlist/nl_setup.h +++ b/src/lib/netlist/nl_setup.h @@ -453,12 +453,15 @@ namespace netlist devices::nld_base_proxy *get_d_a_proxy(detail::core_terminal_t &out); devices::nld_base_proxy *get_a_d_proxy(detail::core_terminal_t &inp); + detail::core_terminal_t &resolve_proxy(detail::core_terminal_t &term); std::unordered_map<pstring, detail::core_terminal_t *> m_terminals; netlist_state_t &m_nlstate; devices::nld_netlistparams *m_netlist_params; std::unordered_map<pstring, param_ref_t> m_params; + std::unordered_map<detail::core_terminal_t *, + devices::nld_base_proxy *> m_proxies; unsigned m_proxy_cnt; bool m_validation; diff --git a/src/lib/netlist/solver/nld_matrix_solver.h b/src/lib/netlist/solver/nld_matrix_solver.h index 218fc819c23..09695f203aa 100644 --- a/src/lib/netlist/solver/nld_matrix_solver.h +++ b/src/lib/netlist/solver/nld_matrix_solver.h @@ -10,11 +10,11 @@ #include "netlist/nl_base.h" #include "netlist/nl_errstr.h" -#include "plib/mat_cr.h" -#include "plib/palloc.h" -#include "plib/pmatrix2d.h" -#include "plib/putil.h" -#include "plib/vector_ops.h" +#include "netlist/plib/mat_cr.h" +#include "netlist/plib/palloc.h" +#include "netlist/plib/pmatrix2d.h" +#include "netlist/plib/putil.h" +#include "netlist/plib/vector_ops.h" namespace netlist { |