mirror of
https://github.com/holub/mame
synced 2025-04-23 08:49:55 +03:00
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:
parent
c6cb9f8bef
commit
b1516cc7a3
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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; }
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user