summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author couriersud <couriersud@arcor.de>2016-12-30 15:48:23 +0100
committer couriersud <couriersud@arcor.de>2016-12-30 20:31:14 +0100
commitb1516cc7a3f756750261260bb3fc79f507da9762 (patch)
treed86adf5ad8396fc665f1a5dcd7d0899d94d442e2
parentc6cb9f8bef6665bd1d9d753ae84e34b5a51d2eb6 (diff)
Analog to digital proxy rework. (nw)
Properly handle connected inputs when creating a-d proxy. Aligned a-d proxy to d-a proxy class structure.
-rw-r--r--src/lib/netlist/devices/nlid_proxy.h70
-rw-r--r--src/lib/netlist/devices/nlid_system.h39
-rw-r--r--src/lib/netlist/nl_base.cpp12
-rw-r--r--src/lib/netlist/nl_base.h5
-rw-r--r--src/lib/netlist/nl_setup.cpp70
-rw-r--r--src/lib/netlist/nl_setup.h1
6 files changed, 141 insertions, 56 deletions
diff --git a/src/lib/netlist/devices/nlid_proxy.h b/src/lib/netlist/devices/nlid_proxy.h
index bcda8fa4e2a..50920c5cf80 100644
--- a/src/lib/netlist/devices/nlid_proxy.h
+++ b/src/lib/netlist/devices/nlid_proxy.h
@@ -61,20 +61,41 @@ namespace netlist
// nld_a_to_d_proxy
// -----------------------------------------------------------------------------
- NETLIB_OBJECT_DERIVED(a_to_d_proxy, base_proxy)
+ NETLIB_OBJECT_DERIVED(base_a_to_d_proxy, base_proxy)
+ {
+ public:
+
+ virtual ~nld_base_a_to_d_proxy() {}
+
+ virtual logic_output_t &out() { return m_Q; }
+
+ protected:
+
+ nld_base_a_to_d_proxy(netlist_t &anetlist, const pstring &name,
+ logic_input_t *in_proxied, detail::core_terminal_t *in_proxy)
+ : nld_base_proxy(anetlist, name, in_proxied, in_proxy)
+ , m_Q(*this, "Q")
+ {
+ }
+
+ private:
+
+ logic_output_t m_Q;
+
+ };
+
+ NETLIB_OBJECT_DERIVED(a_to_d_proxy, base_a_to_d_proxy)
{
public:
nld_a_to_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *in_proxied)
- : nld_base_proxy(anetlist, name, in_proxied, &m_I)
+ : nld_base_a_to_d_proxy(anetlist, name, in_proxied, &m_I)
, m_I(*this, "I")
- , m_Q(*this, "Q")
{
}
virtual ~nld_a_to_d_proxy() {}
analog_input_t m_I;
- logic_output_t m_Q;
protected:
@@ -88,9 +109,9 @@ namespace netlist
if (supply_V == 0.0) supply_V = 5.0;
if (m_I.Q_Analog() > logic_family().high_thresh_V(0.0, supply_V))
- m_Q.push(1, NLTIME_FROM_NS(1));
+ out().push(1, NLTIME_FROM_NS(1));
else if (m_I.Q_Analog() < logic_family().low_thresh_V(0.0, supply_V))
- m_Q.push(0, NLTIME_FROM_NS(1));
+ out().push(0, NLTIME_FROM_NS(1));
else
{
// do nothing
@@ -141,43 +162,6 @@ namespace netlist
bool m_is_timestep;
};
-
- class factory_lib_entry_t : public base_factory_t
- {
- P_PREVENT_COPYING(factory_lib_entry_t)
- public:
-
- factory_lib_entry_t(setup_t &setup, const pstring &name, const pstring &classname,
- const pstring &def_param)
- : base_factory_t(name, classname, def_param), m_setup(setup) { }
-
- class wrapper : public device_t
- {
- public:
- wrapper(const pstring &devname, netlist_t &anetlist, const pstring &name)
- : device_t(anetlist, name), m_devname(devname)
- {
- anetlist.setup().namespace_push(name);
- anetlist.setup().include(m_devname);
- anetlist.setup().namespace_pop();
- }
- protected:
- NETLIB_RESETI() { }
- NETLIB_UPDATEI() { }
-
- pstring m_devname;
- };
-
- plib::owned_ptr<device_t> Create(netlist_t &anetlist, const pstring &name) override
- {
- return plib::owned_ptr<device_t>::Create<wrapper>(this->name(), anetlist, name);
- }
-
- private:
- setup_t &m_setup;
- };
-
-
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/devices/nlid_system.h b/src/lib/netlist/devices/nlid_system.h
index 89251264fa7..ff08177cfdb 100644
--- a/src/lib/netlist/devices/nlid_system.h
+++ b/src/lib/netlist/devices/nlid_system.h
@@ -413,6 +413,45 @@ namespace netlist
state_var<netlist_sig_t> m_last_state;
};
+ // -----------------------------------------------------------------------------
+ // factory class to wrap macro based chips/elements
+ // -----------------------------------------------------------------------------
+
+ class factory_lib_entry_t : public base_factory_t
+ {
+ P_PREVENT_COPYING(factory_lib_entry_t)
+ public:
+
+ factory_lib_entry_t(setup_t &setup, const pstring &name, const pstring &classname,
+ const pstring &def_param)
+ : base_factory_t(name, classname, def_param), m_setup(setup) { }
+
+ class wrapper : public device_t
+ {
+ public:
+ wrapper(const pstring &devname, netlist_t &anetlist, const pstring &name)
+ : device_t(anetlist, name), m_devname(devname)
+ {
+ anetlist.setup().namespace_push(name);
+ anetlist.setup().include(m_devname);
+ anetlist.setup().namespace_pop();
+ }
+ protected:
+ NETLIB_RESETI() { }
+ NETLIB_UPDATEI() { }
+
+ pstring m_devname;
+ };
+
+ plib::owned_ptr<device_t> Create(netlist_t &anetlist, const pstring &name) override
+ {
+ return plib::owned_ptr<device_t>::Create<wrapper>(this->name(), anetlist, name);
+ }
+
+ private:
+ setup_t &m_setup;
+ };
+
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp
index 76ce59db5ac..44f63a4a403 100644
--- a/src/lib/netlist/nl_base.cpp
+++ b/src/lib/netlist/nl_base.cpp
@@ -71,6 +71,10 @@ public:
{
return plib::owned_ptr<devices::nld_base_d_to_a_proxy>::Create<devices::nld_d_to_a_proxy>(anetlist, name, proxied);
}
+ virtual plib::owned_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *proxied) const override
+ {
+ return plib::owned_ptr<devices::nld_base_a_to_d_proxy>::Create<devices::nld_a_to_d_proxy>(anetlist, name, proxied);
+ }
};
class logic_family_cd4xxx_t : public logic_family_desc_t
@@ -91,6 +95,10 @@ public:
{
return plib::owned_ptr<devices::nld_base_d_to_a_proxy>::Create<devices::nld_d_to_a_proxy>(anetlist, name, proxied);
}
+ virtual plib::owned_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *proxied) const override
+ {
+ return plib::owned_ptr<devices::nld_base_a_to_d_proxy>::Create<devices::nld_a_to_d_proxy>(anetlist, name, proxied);
+ }
};
const logic_family_desc_t *family_TTL()
@@ -724,6 +732,10 @@ void detail::net_t::reset()
void detail::net_t::register_con(detail::core_terminal_t &terminal)
{
+ for (auto t : m_core_terms)
+ if (t == &terminal)
+ netlist().log().fatal("net {1}: duplicate terminal {2}", name(), t->name());
+
terminal.set_net(this);
m_core_terms.push_back(&terminal);
diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h
index f72665c62bc..def52d3ff69 100644
--- a/src/lib/netlist/nl_base.h
+++ b/src/lib/netlist/nl_base.h
@@ -169,6 +169,7 @@ namespace netlist
class NETLIB_NAME(netlistparams);
class NETLIB_NAME(base_proxy);
class NETLIB_NAME(base_d_to_a_proxy);
+ class NETLIB_NAME(base_a_to_d_proxy);
}
namespace detail {
@@ -203,6 +204,7 @@ namespace netlist
};
class logic_output_t;
+ class logic_input_t;
class analog_net_t;
class logic_net_t;
class net_t;
@@ -225,8 +227,11 @@ namespace netlist
public:
logic_family_desc_t() {}
virtual ~logic_family_desc_t() {}
+
virtual plib::owned_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_t &anetlist, const pstring &name,
logic_output_t *proxied) const = 0;
+ virtual plib::owned_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_t &anetlist, const pstring &name,
+ logic_input_t *proxied) const = 0;
double fixed_V() const { return m_fixed_V; }
double low_thresh_V(const double VN, const double VP) const { return VN + (VP - VN) * m_low_thresh_PCNT; }
diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp
index 06cef2a0947..62c06176a2d 100644
--- a/src/lib/netlist/nl_setup.cpp
+++ b/src/lib/netlist/nl_setup.cpp
@@ -455,6 +455,50 @@ devices::nld_base_proxy *setup_t::get_d_a_proxy(detail::core_terminal_t &out)
return proxy;
}
+devices::nld_base_proxy *setup_t::get_a_d_proxy(detail::core_terminal_t &inp)
+{
+ nl_assert(inp.is_analog());
+
+ logic_input_t &incast = dynamic_cast<logic_input_t &>(inp);
+ devices::nld_base_proxy *proxy = incast.get_proxy();
+
+ if (proxy != nullptr)
+ return proxy;
+ 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(netlist(), 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();
+
+#if 1
+ /* connect all existing terminals to new net */
+
+ if (inp.has_net())
+ for (auto & p : inp.net().m_core_terms)
+ {
+ p->clear_net(); // de-link from all nets ...
+ if (!connect(ret->proxy_term(), *p))
+ log().fatal("Error connecting {1} to {2}\n", ret->proxy_term().name(), (*p).name());
+ }
+ inp.net().m_core_terms.clear(); // clear the list
+ ret->out().net().register_con(inp);
+#else
+ if (inp.has_net())
+ //fatalerror("logic inputs can only belong to one net!\n");
+ merge_nets(ret->out().net(), inp.net());
+ else
+ ret->out().net().register_con(inp);
+#endif
+ netlist().register_dev(std::move(new_proxy));
+ return ret;
+ }
+}
+
void setup_t::merge_nets(detail::net_t &thisnet, detail::net_t &othernet)
{
netlist().log().debug("merging nets ...\n");
@@ -484,17 +528,16 @@ void setup_t::connect_input_output(detail::core_terminal_t &in, detail::core_ter
{
if (out.is_analog() && in.is_logic())
{
+#if 0
logic_input_t &incast = dynamic_cast<logic_input_t &>(in);
pstring x = plib::pfmt("proxy_ad_{1}_{2}")(in.name())( m_proxy_cnt);
auto proxy = plib::owned_ptr<devices::nld_a_to_d_proxy>::Create(netlist(), x, &incast);
incast.set_proxy(proxy.get());
m_proxy_cnt++;
+#endif
+ auto proxy = get_a_d_proxy(in);
- proxy->m_Q.net().register_con(in);
- out.net().register_con(proxy->m_I);
-
- netlist().register_dev(std::move(proxy));
-
+ out.net().register_con(proxy->proxy_term());
}
else if (out.is_logic() && in.is_analog())
{
@@ -522,22 +565,19 @@ void setup_t::connect_terminal_input(terminal_t &term, detail::core_terminal_t &
else if (inp.is_logic())
{
netlist().log().verbose("connect terminal {1} (in, {2}) to {3}\n", inp.name(), pstring(inp.is_analog() ? "analog" : inp.is_logic() ? "logic" : "?"), term.name());
+#if 0
logic_input_t &incast = dynamic_cast<logic_input_t &>(inp);
log().debug("connect_terminal_input: connecting proxy\n");
pstring x = plib::pfmt("proxy_ad_{1}_{2}")(inp.name())(m_proxy_cnt);
auto proxy = plib::owned_ptr<devices::nld_a_to_d_proxy>::Create(netlist(), x, &incast);
incast.set_proxy(proxy.get());
m_proxy_cnt++;
+#endif
+ auto proxy = get_a_d_proxy(inp);
- connect_terminals(term, proxy->m_I);
+ //out.net().register_con(proxy->proxy_term());
+ connect_terminals(term, proxy->proxy_term());
- if (inp.has_net())
- //fatalerror("logic inputs can only belong to one net!\n");
- merge_nets(proxy->m_Q.net(), inp.net());
- else
- proxy->m_Q.net().register_con(inp);
-
- netlist().register_dev(std::move(proxy));
}
else
{
@@ -836,6 +876,10 @@ public:
{
return plib::owned_ptr<devices::nld_base_d_to_a_proxy>::Create<devices::nld_d_to_a_proxy>(anetlist, name, proxied);
}
+ virtual plib::owned_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *proxied) const override
+ {
+ return plib::owned_ptr<devices::nld_base_a_to_d_proxy>::Create<devices::nld_a_to_d_proxy>(anetlist, name, proxied);
+ }
};
const logic_family_desc_t *setup_t::family_from_model(const pstring &model)
diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h
index e560a3b9f79..399c44e3dbe 100644
--- a/src/lib/netlist/nl_setup.h
+++ b/src/lib/netlist/nl_setup.h
@@ -300,6 +300,7 @@ namespace netlist
pstring objtype_as_str(detail::device_object_t &in) const;
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);
netlist_t &m_netlist;
std::unordered_map<pstring, param_ref_t> m_params;