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.
This commit is contained in:
couriersud 2016-12-30 15:48:23 +01:00
parent c6cb9f8bef
commit b1516cc7a3
6 changed files with 141 additions and 56 deletions

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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; }

View File

@ -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)

View File

@ -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;