summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/devices/nlid_proxy.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/netlist/devices/nlid_proxy.cpp')
-rw-r--r--src/lib/netlist/devices/nlid_proxy.cpp113
1 files changed, 70 insertions, 43 deletions
diff --git a/src/lib/netlist/devices/nlid_proxy.cpp b/src/lib/netlist/devices/nlid_proxy.cpp
index ddf76b27887..6e4dba84c4e 100644
--- a/src/lib/netlist/devices/nlid_proxy.cpp
+++ b/src/lib/netlist/devices/nlid_proxy.cpp
@@ -18,12 +18,60 @@ namespace netlist
// -----------------------------------------------------------------------------
nld_base_proxy::nld_base_proxy(netlist_state_t &anetlist, const pstring &name,
- logic_t *inout_proxied, detail::core_terminal_t *proxy_inout)
- : device_t(anetlist, name)
+ logic_t *inout_proxied, detail::core_terminal_t *proxy_inout)
+ : device_t(anetlist, name)
+ , m_tp(nullptr)
+ , m_tn(nullptr)
+ , m_term_proxied(inout_proxied)
+ , m_proxy_term(proxy_inout)
{
m_logic_family = inout_proxied->logic_family();
- m_term_proxied = inout_proxied;
- m_proxy_term = proxy_inout;
+
+ const std::vector<std::pair<pstring, pstring>> power_syms = { {"VCC", "VEE"}, {"VCC", "GND"}, {"VDD", "VSS"}};
+
+ bool f = false;
+ 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)
+ {
+ m_tp = tp_t;
+ m_tn = tn_t;
+ f = true;
+ }
+ }
+ //FIXME: Use power terminals and change info to warning or error
+ if (!f)
+ {
+#if 1
+ 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())));
+#endif
+ m_GNDHack = plib::make_unique<analog_output_t>(*this, "_QGND");
+ m_VCCHack = plib::make_unique<analog_output_t>(*this, "_QVCC");
+
+ m_tp = m_VCCHack.get();
+ m_tn = m_GNDHack.get();
+ m_need_hack = true;
+ }
+ else
+ {
+ log().verbose("D/A Proxy: Found power terminals on device {1}", inout_proxied->device().name());
+ m_need_hack = false;
+ }
+ //printf("vcc: %f\n", logic_family()->fixed_V());
+
}
// ----------------------------------------------------------------------------------------
@@ -52,6 +100,7 @@ namespace netlist
nl_assert(m_logic_family != nullptr);
// FIXME: Variable supply voltage!
nl_fptype supply_V = logic_family()->fixed_V();
+ // FIXME: bad hack
if (supply_V == nlconst::zero()) supply_V = nlconst::magic(5.0);
if (m_I.Q_Analog() > logic_family()->high_thresh_V(nlconst::zero(), supply_V))
@@ -82,45 +131,20 @@ namespace netlist
, m_last_state(*this, "m_last_var", -1)
, m_is_timestep(false)
{
- const std::vector<std::pair<pstring, pstring>> power_syms = { {"VCC", "VEE"}, {"VCC", "GND"}, {"VDD", "VSS"}};
-
register_subalias("Q", m_RN.m_P);
- bool f = false;
- detail::core_terminal_t *tp(nullptr);
- detail::core_terminal_t *tn(nullptr);
- for (auto & pwr_sym : power_syms)
- {
- pstring devname = out_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(out_proxied->device().name(),
- tp->name(), tn->name(),
- tp_t ? tp_t->name() : "",
- tn_t ? tn_t->name() : ""));
- else if (tp_t != nullptr && tn_t != nullptr)
- {
- /* alternative logic */
- tp = tp_t;
- tn = tn_t;
- f = true;
- }
- }
//FIXME: Use power terminals and change info to warning or error
- if (!f)
+ 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_1(anetlist.setup().de_alias(out_proxied->device().name())));
+ log().error(MI_NO_POWER_TERMINALS_ON_DEVICE_2(name, anetlist.setup().de_alias(out_proxied->device().name())));
else
- log().info(MI_NO_POWER_TERMINALS_ON_DEVICE_1(anetlist.setup().de_alias(out_proxied->device().name())));
- m_GNDHack = plib::make_unique<analog_output_t>(*this, "_QGND");
- m_VCCHack = plib::make_unique<analog_output_t>(*this, "_QVCC");
-
- connect(m_RN.m_N, *m_GNDHack);
- connect(m_RP.m_P, *m_VCCHack);
+ 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_P, m_RP.m_N);
}
else
@@ -135,8 +159,8 @@ namespace netlist
}
else
{
- connect(m_RN.m_N, *tn);
- connect(m_RP.m_P, *tp);
+ connect(m_RN.m_N, *m_tn);
+ connect(m_RP.m_P, *m_tp);
}
connect(m_RN.m_P, m_RP.m_N);
}
@@ -156,10 +180,13 @@ namespace netlist
m_last_state = -1;
m_RN.reset();
m_RP.reset();
- if (m_GNDHack)
- m_GNDHack->initial(0);
- if (m_VCCHack)
- m_VCCHack->initial(supply_V);
+ if (need_hack())
+ {
+ if (m_tn)
+ m_GNDHack->initial(0);
+ if (m_tp)
+ m_VCCHack->initial(supply_V);
+ }
m_is_timestep = m_RN.m_P.net().solver()->has_timestep_devices();
m_RN.set_G_V_I(plib::reciprocal(logic_family()->R_low()),
logic_family()->low_offset_V(), nlconst::zero());