summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib
diff options
context:
space:
mode:
authorGravatarGravatar couriersud <couriersud@gmx.org>2019-11-14 22:59:07 +0100
committerGravatarGravatar couriersud <couriersud@gmx.org>2019-11-14 22:59:07 +0100
commitdc4fa0420182bffb9be8d5e9f654d94b9aafe6b1 (patch)
treeeeda982478b0204dc16ed77eb2e0dd8b79ceb0e5 /src/lib
parentce3c38914d4b710e2e40c212af0d61aa4b328de0 (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')
-rw-r--r--src/lib/netlist/analog/nlid_twoterm.h12
-rw-r--r--src/lib/netlist/devices/nld_tms4800.cpp5
-rw-r--r--src/lib/netlist/devices/nld_tms4800.h4
-rw-r--r--src/lib/netlist/devices/nlid_proxy.cpp87
-rw-r--r--src/lib/netlist/devices/nlid_proxy.h6
-rw-r--r--src/lib/netlist/devices/nlid_system.h87
-rw-r--r--src/lib/netlist/macro/nlm_base.cpp2
-rw-r--r--src/lib/netlist/nl_base.cpp1
-rw-r--r--src/lib/netlist/nl_base.h12
-rw-r--r--src/lib/netlist/nl_errstr.h1
-rw-r--r--src/lib/netlist/nl_setup.cpp61
-rw-r--r--src/lib/netlist/nl_setup.h3
-rw-r--r--src/lib/netlist/solver/nld_matrix_solver.h10
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
{