From b1516cc7a3f756750261260bb3fc79f507da9762 Mon Sep 17 00:00:00 2001 From: couriersud Date: Fri, 30 Dec 2016 15:48:23 +0100 Subject: [PATCH] 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. --- src/lib/netlist/devices/nlid_proxy.h | 70 +++++++++++---------------- src/lib/netlist/devices/nlid_system.h | 39 +++++++++++++++ src/lib/netlist/nl_base.cpp | 12 +++++ src/lib/netlist/nl_base.h | 5 ++ src/lib/netlist/nl_setup.cpp | 70 ++++++++++++++++++++++----- src/lib/netlist/nl_setup.h | 1 + 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 Create(netlist_t &anetlist, const pstring &name) override - { - return plib::owned_ptr::Create(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 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 Create(netlist_t &anetlist, const pstring &name) override + { + return plib::owned_ptr::Create(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::Create(anetlist, name, proxied); } + virtual plib::owned_ptr create_a_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *proxied) const override + { + return plib::owned_ptr::Create(anetlist, name, proxied); + } }; class logic_family_cd4xxx_t : public logic_family_desc_t @@ -91,6 +95,10 @@ public: { return plib::owned_ptr::Create(anetlist, name, proxied); } + virtual plib::owned_ptr create_a_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *proxied) const override + { + return plib::owned_ptr::Create(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 create_d_a_proxy(netlist_t &anetlist, const pstring &name, logic_output_t *proxied) const = 0; + virtual plib::owned_ptr 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(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::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(in); pstring x = plib::pfmt("proxy_ad_{1}_{2}")(in.name())( m_proxy_cnt); auto proxy = plib::owned_ptr::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(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::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::Create(anetlist, name, proxied); } + virtual plib::owned_ptr create_a_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *proxied) const override + { + return plib::owned_ptr::Create(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 m_params;