This commit is contained in:
Scott Stone 2016-05-11 19:16:38 -04:00
commit eb8e8fe18f
8 changed files with 159 additions and 162 deletions

View File

@ -172,8 +172,7 @@ void netlist_mame_stream_input_t::device_start()
void netlist_mame_stream_input_t::custom_netlist_additions(netlist::setup_t &setup)
{
NETLIB_NAME(sound_in) *snd_in = setup.netlist().get_first_device<NETLIB_NAME(sound_in)>();
if (snd_in == nullptr)
if (!setup.device_exists("STREAM_INPUT"))
setup.register_dev("NETDEV_SOUND_IN", "STREAM_INPUT");
pstring sparam = pfmt("STREAM_INPUT.CHAN{1}")(m_channel);
@ -301,8 +300,7 @@ void netlist_mame_device_t::device_start()
//printf("clock is %d\n", clock());
m_netlist = global_alloc(netlist_mame_t(*this, "netlist"));
m_setup = global_alloc(netlist::setup_t(m_netlist));
m_setup->init();
m_setup = global_alloc(netlist::setup_t(*m_netlist));
// register additional devices
@ -354,9 +352,9 @@ void netlist_mame_device_t::device_reset()
void netlist_mame_device_t::device_stop()
{
LOG_DEV_CALLS(("device_stop\n"));
m_setup->print_stats();
netlist().print_stats();
m_netlist->stop();
netlist().stop();
global_free(m_setup);
m_setup = nullptr;
@ -478,7 +476,7 @@ void netlist_mame_cpu_device_t::device_start()
for (int i=0; i < netlist().m_nets.size(); i++)
{
netlist::net_t *n = netlist().m_nets[i];
netlist::net_t *n = netlist().m_nets[i].get();
if (n->isFamily(netlist::object_t::LOGIC))
{
state_add(i*2, n->name().cstr(), downcast<netlist::logic_net_t *>(n)->Q_state_ptr());

View File

@ -211,13 +211,6 @@ netlist_t::netlist_t(const pstring &aname)
netlist_t::~netlist_t()
{
for (net_t *net : m_nets)
{
if (!net->isRailNet())
{
pfree(net);
}
}
m_nets.clear();
m_devices.clear_and_free();
@ -278,16 +271,16 @@ ATTR_COLD void netlist_t::stop()
ATTR_COLD net_t *netlist_t::find_net(const pstring &name)
{
for (net_t *net : m_nets)
for (auto & net : m_nets)
if (net->name() == name)
return net;
return net.get();
return nullptr;
}
ATTR_COLD void netlist_t::rebuild_lists()
{
for (net_t *net : m_nets)
for (auto & net : m_nets)
net->rebuild_list();
}
@ -379,6 +372,21 @@ ATTR_HOT void netlist_t::process_queue(const netlist_time &delta)
}
}
void netlist_t::print_stats() const
{
#if (NL_KEEP_STATISTICS)
{
for (std::size_t i = 0; i < m_started_devices.size(); i++)
{
core_device_t *entry = m_started_devices[i];
printf("Device %20s : %12d %12d %15ld\n", entry->name().cstr(), entry->stat_call_count, entry->stat_update_count, (long int) entry->stat_total_time / (entry->stat_update_count + 1));
}
printf("Queue Pushes %15d\n", queue().m_prof_call);
printf("Queue Moves %15d\n", queue().m_prof_sortmove);
}
#endif
}
// ----------------------------------------------------------------------------------------
// Default netlist elements ...
// ----------------------------------------------------------------------------------------
@ -409,7 +417,7 @@ ATTR_COLD core_device_t::~core_device_t()
ATTR_COLD void core_device_t::start_dev()
{
#if (NL_KEEP_STATISTICS)
netlist().m_started_devices.add(this, false);
netlist().m_started_devices.push_back(this);
#endif
#if (NL_PMF_TYPE == NL_PMF_TYPE_GNUC_PMF)
void (core_device_t::* pFunc)() = &core_device_t::update;
@ -566,10 +574,20 @@ ATTR_COLD net_t::~net_t()
netlist().remove_save_items(this);
}
ATTR_COLD void net_t::init_object(netlist_t &nl, const pstring &aname)
// FIXME: move somewhere central
struct do_nothing_deleter{
template<typename T> void operator()(T*){}
};
ATTR_COLD void net_t::init_object(netlist_t &nl, const pstring &aname, core_terminal_t *mr)
{
object_t::init_object(nl, aname);
nl.m_nets.push_back(this);
m_railterminal = mr;
if (mr != nullptr)
nl.m_nets.push_back(std::shared_ptr<net_t>(this, do_nothing_deleter()));
else
nl.m_nets.push_back(std::shared_ptr<net_t>(this));
}
ATTR_HOT void net_t::inc_active(core_terminal_t &term)
@ -611,12 +629,6 @@ ATTR_HOT void net_t::dec_active(core_terminal_t &term)
railterminal().device().dec_active();
}
ATTR_COLD void net_t::register_railterminal(core_terminal_t &mr)
{
nl_assert(m_railterminal == nullptr);
m_railterminal = &mr;
}
ATTR_COLD void net_t::rebuild_list()
{
/* rebuild m_list */
@ -656,7 +668,7 @@ ATTR_HOT /* inline */ void net_t::update_devs()
for (core_terminal_t *p = m_list_active.first(); p != nullptr; p = p->next())
{
inc_stat(p->netdev().stat_call_count);
inc_stat(p->device().stat_call_count);
if ((p->state() & mask) != 0)
p->device().update_dev();
}
@ -688,7 +700,7 @@ ATTR_COLD void net_t::reset()
ATTR_COLD void net_t::register_con(core_terminal_t &terminal)
{
terminal.set_net(*this);
terminal.set_net(this);
m_core_terms.push_back(&terminal);
@ -761,6 +773,13 @@ ATTR_COLD analog_net_t::analog_net_t()
{
}
ATTR_COLD analog_net_t::analog_net_t(netlist_t &nl, const pstring &aname)
: net_t(ANALOG)
, m_solver(nullptr)
{
init_object(nl, aname);
}
ATTR_COLD void analog_net_t::reset()
{
net_t::reset();
@ -814,11 +833,17 @@ ATTR_COLD core_terminal_t::core_terminal_t(const type_t atype, const family_t af
{
}
ATTR_COLD void core_terminal_t::set_net(net_t &anet)
ATTR_COLD void core_terminal_t::set_net(net_t::ptr_t anet)
{
m_net = &anet;
m_net = anet;
}
ATTR_COLD void core_terminal_t::clear_net()
{
m_net = nullptr;
}
// ----------------------------------------------------------------------------------------
// terminal_t
// ----------------------------------------------------------------------------------------
@ -880,14 +905,13 @@ ATTR_COLD logic_output_t::logic_output_t()
: logic_t(OUTPUT)
{
set_state(STATE_OUT);
this->set_net(m_my_net);
this->set_net(&m_my_net);
}
ATTR_COLD void logic_output_t::init_object(core_device_t &dev, const pstring &aname)
{
core_terminal_t::init_object(dev, aname);
net().init_object(dev.netlist(), aname + ".net");
net().register_railterminal(*this);
net().init_object(dev.netlist(), aname + ".net", this);
}
ATTR_COLD void logic_output_t::initial(const netlist_sig_t val)
@ -900,33 +924,31 @@ ATTR_COLD void logic_output_t::initial(const netlist_sig_t val)
// analog_output_t
// ----------------------------------------------------------------------------------------
ATTR_COLD analog_output_t::analog_output_t()
: analog_t(OUTPUT), m_proxied_net(nullptr)
{
this->set_net(m_my_net);
set_state(STATE_OUT);
net().m_cur_Analog = NL_FCONST(0.99);
}
ATTR_COLD analog_output_t::analog_output_t(core_device_t &dev, const pstring &aname)
: analog_t(OUTPUT), m_proxied_net(nullptr)
{
this->set_net(m_my_net);
this->set_net(&m_my_net);
set_state(STATE_OUT);
net().m_cur_Analog = NL_FCONST(0.99);
analog_t::init_object(dev, aname);
net().init_object(dev.netlist(), aname + ".net");
net().register_railterminal(*this);
net().init_object(dev.netlist(), aname + ".net", this);
}
ATTR_COLD analog_output_t::analog_output_t()
: analog_t(OUTPUT), m_proxied_net(nullptr)
{
this->set_net(&m_my_net);
set_state(STATE_OUT);
net().m_cur_Analog = NL_FCONST(0.99);
}
ATTR_COLD void analog_output_t::init_object(core_device_t &dev, const pstring &aname)
{
analog_t::init_object(dev, aname);
net().init_object(dev.netlist(), aname + ".net");
net().register_railterminal(*this);
net().init_object(dev.netlist(), aname + ".net", this);
}
ATTR_COLD void analog_output_t::initial(const nl_double val)

View File

@ -482,8 +482,8 @@ namespace netlist
ATTR_COLD core_terminal_t(const type_t atype, const family_t afamily);
ATTR_COLD void set_net(net_t &anet);
ATTR_COLD void clear_net() { m_net = nullptr; }
ATTR_COLD void set_net(net_t *anet);
ATTR_COLD void clear_net();
ATTR_HOT bool has_net() const { return (m_net != nullptr); }
ATTR_HOT const net_t & net() const { return *m_net;}
@ -505,7 +505,7 @@ namespace netlist
}
private:
net_t * m_net;
net_t * m_net;
state_e m_state;
};
@ -692,16 +692,16 @@ namespace netlist
P_PREVENT_COPYING(net_t)
public:
using list_t = pvector_t<net_t *>;
using ptr_t = net_t *;
using list_t = pvector_t<std::shared_ptr<net_t>>;
ATTR_COLD net_t(const family_t afamily);
virtual ~net_t();
ATTR_COLD void init_object(netlist_t &nl, const pstring &aname);
ATTR_COLD void init_object(netlist_t &nl, const pstring &aname, core_terminal_t *mr = nullptr);
ATTR_COLD void register_con(core_terminal_t &terminal);
ATTR_COLD void merge_net(net_t *othernet);
ATTR_COLD void register_railterminal(core_terminal_t &mr);
ATTR_HOT logic_net_t & as_logic();
ATTR_HOT const logic_net_t & as_logic() const;
@ -835,6 +835,8 @@ namespace netlist
using list_t = pvector_t<analog_net_t *>;
ATTR_COLD analog_net_t();
ATTR_COLD analog_net_t(netlist_t &nl, const pstring &aname);
virtual ~analog_net_t() { };
ATTR_HOT const nl_double &Q_Analog() const
@ -1269,7 +1271,7 @@ namespace netlist
pvector_t<device_t *> m_devices;
net_t::list_t m_nets;
#if (NL_KEEP_STATISTICS)
pnamedlist_t<core_device_t *> m_started_devices;
pvector_t<core_device_t *> m_started_devices;
#endif
ATTR_COLD plog_base<NL_DEBUG> &log() { return m_log; }
@ -1279,6 +1281,8 @@ namespace netlist
ATTR_COLD pdynlib &lib() { return *m_lib; }
void print_stats() const;
protected:
#if (NL_KEEP_STATISTICS)

View File

@ -352,7 +352,6 @@ void parser_t::device(const pstring &dev_type)
else
{
base_factory_t *f = m_setup.factory().factory_by_name(dev_type);
device_t *dev;
pstring_vector_t termlist = f->term_param_list();
pstring_vector_t def_params = f->def_params();
@ -360,8 +359,7 @@ void parser_t::device(const pstring &dev_type)
pstring devname = get_identifier();
dev = f->Create(m_setup.netlist(), m_setup.build_fqn(devname));
m_setup.register_dev(dev);
m_setup.register_dev(dev_type, m_setup.build_fqn(devname));
m_setup.log().debug("Parser: IC: {1}\n", devname);

View File

@ -50,32 +50,26 @@ NETLIST_END()
namespace netlist
{
setup_t::setup_t(netlist_t *netlist)
setup_t::setup_t(netlist_t &netlist)
: m_netlist(netlist)
, m_factory(*this)
, m_proxy_cnt(0)
, m_frontier_cnt(0)
{
netlist->set_setup(this);
m_factory = palloc(factory_list_t(*this));
}
void setup_t::init()
{
initialize_factory(factory());
netlist.set_setup(this);
initialize_factory(m_factory);
NETLIST_NAME(base)(*this);
}
setup_t::~setup_t()
{
m_links.clear();
m_alias.clear();
m_params.clear();
m_terminals.clear();
m_params_temp.clear();
m_param_values.clear();
netlist().set_setup(nullptr);
pfree(m_factory);
m_sources.clear_and_free();
pstring::resetmem();
@ -83,23 +77,25 @@ setup_t::~setup_t()
ATTR_COLD pstring setup_t::build_fqn(const pstring &obj_name) const
{
if (m_stack.empty())
return netlist().name() + "." + obj_name;
if (m_namespace_stack.empty())
//return netlist().name() + "." + obj_name;
return obj_name;
else
return m_stack.top() + "." + obj_name;
return m_namespace_stack.top() + "." + obj_name;
}
void setup_t::namespace_push(const pstring &aname)
{
if (m_stack.empty())
m_stack.push(netlist().name() + "." + aname);
if (m_namespace_stack.empty())
//m_namespace_stack.push(netlist().name() + "." + aname);
m_namespace_stack.push(aname);
else
m_stack.push(m_stack.top() + "." + aname);
m_namespace_stack.push(m_namespace_stack.top() + "." + aname);
}
void setup_t::namespace_pop()
{
m_stack.pop();
m_namespace_stack.pop();
}
@ -130,14 +126,31 @@ void setup_t::register_dev(const pstring &classname, const pstring &name)
}
else
{
#if 0
device_t *dev = factory().new_device_by_name(classname, netlist(), build_fqn(name));
//device_t *dev = factory().new_device_by_classname(classname);
if (dev == nullptr)
log().fatal("Class {1} not found!\n", classname);
register_dev(dev);
#else
auto f = factory().factory_by_name(classname);
if (f == nullptr)
log().fatal("Class {1} not found!\n", classname);
m_device_factory.push_back(std::pair<pstring, base_factory_t *>(build_fqn(name), f));
#endif
}
}
bool setup_t::device_exists(const pstring name) const
{
for (auto e : m_device_factory)
{
if (e.first == name)
return true;
}
return false;
}
void setup_t::register_model(const pstring &model_in)
{
int pos = model_in.find(" ");
@ -248,9 +261,9 @@ void setup_t::register_object(device_t &dev, const pstring &name, object_t &obj)
case terminal_t::PARAM:
{
param_t &param = dynamic_cast<param_t &>(obj);
if (m_params_temp.contains(name))
if (m_param_values.contains(name))
{
const pstring val = m_params_temp[name];
const pstring val = m_param_values[name];
switch (param.param_type())
{
case param_t::DOUBLE:
@ -330,9 +343,9 @@ void setup_t::remove_connections(const pstring pin)
for (int i = m_links.size() - 1; i >= 0; i--)
{
auto &link = m_links[i];
if ((link.e1 == pinfn) || (link.e2 == pinfn))
if ((link.first == pinfn) || (link.second == pinfn))
{
log().verbose("removing connection: {1} <==> {2}\n", link.e1, link.e2);
log().verbose("removing connection: {1} <==> {2}\n", link.first, link.second);
m_links.remove_at(i);
found = true;
}
@ -355,14 +368,14 @@ void setup_t::register_frontier(const pstring attach, const double r_IN, const d
bool found = false;
for (auto & link : m_links)
{
if (link.e1 == attfn)
if (link.first == attfn)
{
link.e1 = front_fqn + ".I";
link.first = front_fqn + ".I";
found = true;
}
else if (link.e2 == attfn)
else if (link.second == attfn)
{
link.e2 = front_fqn + ".I";
link.second = front_fqn + ".I";
found = true;
}
}
@ -382,16 +395,16 @@ void setup_t::register_param(const pstring &param, const pstring &value)
{
pstring fqn = build_fqn(param);
int idx = m_params_temp.index_of(fqn);
int idx = m_param_values.index_of(fqn);
if (idx < 0)
{
if (!m_params_temp.add(fqn, value))
if (!m_param_values.add(fqn, value))
log().fatal("Unexpected error adding parameter {1} to parameter list\n", param);
}
else
{
log().warning("Overwriting {1} old <{2}> new <{3}>\n", fqn, m_params_temp.value_at(idx), value);
m_params_temp[fqn] = value;
log().warning("Overwriting {1} old <{2}> new <{3}>\n", fqn, m_param_values.value_at(idx), value);
m_param_values[fqn] = value;
}
}
@ -623,13 +636,12 @@ void setup_t::connect_terminals(core_terminal_t &t1, core_terminal_t &t2)
}
else
{
log().debug("adding net ...\n");
analog_net_t *anet = palloc(analog_net_t);
t1.set_net(*anet);
log().debug("adding analog net ...\n");
// FIXME: Nets should have a unique name
t1.net().init_object(netlist(),"net." + t1.name() );
t1.net().register_con(t2);
t1.net().register_con(t1);
analog_net_t::ptr_t anet = palloc(analog_net_t(netlist(),"net." + t1.name()));
t1.set_net(anet);
anet->register_con(t2);
anet->register_con(t1);
}
}
@ -747,8 +759,8 @@ void setup_t::resolve_inputs()
unsigned li = 0;
while (li < m_links.size())
{
const pstring t1s = m_links[li].e1;
const pstring t2s = m_links[li].e2;
const pstring t1s = m_links[li].first;
const pstring t2s = m_links[li].second;
core_terminal_t *t1 = find_terminal(t1s);
core_terminal_t *t2 = find_terminal(t2s);
@ -762,7 +774,7 @@ void setup_t::resolve_inputs()
if (tries == 0)
{
for (std::size_t i = 0; i < m_links.size(); i++ )
log().warning("Error connecting {1} to {2}\n", m_links[i].e1, m_links[i].e2);
log().warning("Error connecting {1} to {2}\n", m_links[i].first, m_links[i].second);
log().fatal("Error connecting -- bailing out\n");
}
@ -773,7 +785,7 @@ void setup_t::resolve_inputs()
net_t::list_t todelete;
for (net_t *net : netlist().m_nets)
for (auto & net : netlist().m_nets)
{
if (net->num_cons() == 0)
todelete.push_back(net);
@ -781,12 +793,10 @@ void setup_t::resolve_inputs()
net->rebuild_list();
}
for (net_t *net : todelete)
for (auto & net : todelete)
{
log().verbose("Deleting net {1} ...", net->name());
netlist().m_nets.remove(net);
if (!net->isRailNet())
pfree(net);
}
pstring errstr("");
@ -850,22 +860,15 @@ void setup_t::start_devices()
}
}
netlist().start();
}
/* create devices */
void setup_t::print_stats() const
{
#if (NL_KEEP_STATISTICS)
for (auto & e : m_device_factory)
{
for (std::size_t i = 0; i < netlist().m_started_devices.size(); i++)
{
core_device_t *entry = netlist().m_started_devices[i];
printf("Device %20s : %12d %12d %15ld\n", entry->name(), entry->stat_call_count, entry->stat_update_count, (long int) entry->stat_total_time / (entry->stat_update_count + 1));
}
printf("Queue Pushes %15d\n", netlist().queue().m_prof_call);
printf("Queue Moves %15d\n", netlist().queue().m_prof_sortmove);
device_t *dev = e.second->Create(netlist(), e.first);
register_dev(dev);
}
#endif
netlist().start();
}
// ----------------------------------------------------------------------------------------

View File

@ -9,6 +9,7 @@
#define NLSETUP_H_
#include "nl_base.h"
#include "nl_factory.h"
//============================================================
// MACROS / inline netlist definitions
@ -29,9 +30,6 @@
#define NET_REGISTER_DEV(_type, _name) \
setup.register_dev(# _type, # _name);
#define NET_REGISTER_SIGNAL(_type, _name) \
NET_REGISTER_DEV(_type ## _ ## sig, _name)
#define NET_CONNECT(_name, _input, _output) \
setup.register_link(# _name "." # _input, # _output);
@ -102,44 +100,19 @@ namespace netlist
private:
};
struct link_t
{
link_t() { }
link_t(void *) { }
// Copy constructor
link_t(const link_t &from)
{
e1 = from.e1;
e2 = from.e2;
}
using link_t = std::pair<pstring, pstring>;
link_t(const pstring &ae1, const pstring &ae2)
{
e1 = ae1;
e2 = ae2;
}
pstring e1;
pstring e2;
bool operator==(const link_t &rhs) const { return (e1 == rhs.e1) && (e2 == rhs.e2); }
link_t &operator=(const link_t &rhs) { e1 = rhs.e1; e2 = rhs.e2; return *this; }
const pstring &name() const { return e1; }
};
setup_t(netlist_t *netlist);
setup_t(netlist_t &netlist);
~setup_t();
void init();
netlist_t &netlist() { return *m_netlist; }
const netlist_t &netlist() const { return *m_netlist; }
netlist_t &netlist() { return m_netlist; }
const netlist_t &netlist() const { return m_netlist; }
pstring build_fqn(const pstring &obj_name) const;
void register_object(device_t &dev, const pstring &name, object_t &obj);
void register_dev(device_t *dev);
void register_dev(const pstring &classname, const pstring &name);
void remove_dev(const pstring &name);
void register_lib_entry(const pstring &name);
@ -157,13 +130,12 @@ namespace netlist
void register_param(const pstring &param, const double value);
void register_frontier(const pstring attach, const double r_IN, const double r_OUT);
void remove_connections(const pstring attach);
void register_object(device_t &dev, const pstring &name, object_t &obj);
bool connect(core_terminal_t &t1, core_terminal_t &t2);
core_terminal_t *find_terminal(const pstring &outname_in, bool required = true);
core_terminal_t *find_terminal(const pstring &outname_in, object_t::type_t atype, bool required = true);
bool device_exists(const pstring name) const;
param_t *find_param(const pstring &param_in, bool required = true);
@ -183,13 +155,11 @@ namespace netlist
void register_source(source_t *src) { m_sources.push_back(src); }
factory_list_t &factory() { return *m_factory; }
const factory_list_t &factory() const { return *m_factory; }
factory_list_t &factory() { return m_factory; }
const factory_list_t &factory() const { return m_factory; }
bool is_library_item(const pstring &name) const { return m_lib.contains(name); }
void print_stats() const;
/* model / family related */
logic_family_desc_t *family_from_model(const pstring &model);
@ -205,6 +175,9 @@ namespace netlist
private:
core_terminal_t *find_terminal(const pstring &outname_in, bool required = true);
core_terminal_t *find_terminal(const pstring &outname_in, object_t::type_t atype, bool required = true);
void connect_terminals(core_terminal_t &in, core_terminal_t &out);
void connect_input_output(core_terminal_t &in, core_terminal_t &out);
void connect_terminal_output(terminal_t &in, core_terminal_t &out);
@ -217,23 +190,24 @@ namespace netlist
const pstring resolve_alias(const pstring &name) const;
devices::nld_base_proxy *get_d_a_proxy(core_terminal_t &out);
netlist_t *m_netlist;
netlist_t &m_netlist;
phashmap_t<pstring, pstring> m_alias;
phashmap_t<pstring, param_t *> m_params;
phashmap_t<pstring, pstring> m_params_temp;
phashmap_t<pstring, pstring> m_param_values;
phashmap_t<pstring, core_terminal_t *> m_terminals;
pvector_t<link_t> m_links;
pvector_t<std::pair<pstring, base_factory_t *>> m_device_factory;
factory_list_t *m_factory;
factory_list_t m_factory;
phashmap_t<pstring, pstring> m_models;
int m_proxy_cnt;
int m_frontier_cnt;
std::stack<pstring> m_stack;
std::stack<pstring> m_namespace_stack;
source_t::list_t m_sources;
pvector_t<pstring> m_lib;

View File

@ -103,8 +103,7 @@ public:
void init()
{
m_setup = palloc(netlist::setup_t(this));
m_setup->init();
m_setup = palloc(netlist::setup_t(*this));
}
void read_netlist(const pstring &filename, const pstring &name)

View File

@ -184,8 +184,7 @@ ATTR_COLD void matrix_solver_t::setup_base(analog_net_t::list_t &nets)
//net_proxy_output = palloc(analog_output_t(*this,
// this->name() + "." + pfmt("m{1}")(m_inps.size())));
net_proxy_output = palloc(analog_output_t);
net_proxy_output->init_object(*this, this->name() + "." + pfmt("m{1}")(m_inps.size()));
net_proxy_output = palloc(analog_output_t(*this, this->name() + "." + pfmt("m{1}")(m_inps.size())));
m_inps.push_back(net_proxy_output);
net_proxy_output->m_proxied_net = &p->net().as_analog();
}