summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author couriersud <couriersud@gmx.org>2019-01-16 23:51:28 +0100
committer couriersud <couriersud@gmx.org>2019-01-18 00:58:45 +0100
commita527525e52d086c7550f87c82cba5f8204e4d61a (patch)
treed274f4047f456429863024ea5e02832f4c6097e2
parentf2da8af21ab5127421b55636e780c6d6039d748d (diff)
netlist: More run/setup separation. (nw)
Still some distance ahead in properly separating execution and setup.
-rw-r--r--src/devices/machine/netlist.cpp40
-rw-r--r--src/lib/netlist/analog/nlid_twoterm.h7
-rw-r--r--src/lib/netlist/devices/nlid_proxy.cpp4
-rw-r--r--src/lib/netlist/devices/nlid_system.h2
-rw-r--r--src/lib/netlist/nl_base.cpp288
-rw-r--r--src/lib/netlist/nl_base.h216
-rw-r--r--src/lib/netlist/nl_factory.h12
-rw-r--r--src/lib/netlist/nl_lists.h6
-rw-r--r--src/lib/netlist/nl_parser.h2
-rw-r--r--src/lib/netlist/nl_setup.cpp138
-rw-r--r--src/lib/netlist/nl_setup.h24
-rw-r--r--src/lib/netlist/prg/nltool.cpp24
-rw-r--r--src/lib/netlist/solver/nld_matrix_solver.cpp12
-rw-r--r--src/lib/netlist/solver/nld_ms_direct.h4
-rw-r--r--src/lib/netlist/solver/nld_ms_gcr.h4
-rw-r--r--src/lib/netlist/solver/nld_ms_sm.h4
-rw-r--r--src/lib/netlist/solver/nld_ms_w.h4
-rw-r--r--src/lib/netlist/solver/nld_solver.cpp26
18 files changed, 439 insertions, 378 deletions
diff --git a/src/devices/machine/netlist.cpp b/src/devices/machine/netlist.cpp
index 75aa472e7e5..9f588368f8e 100644
--- a/src/devices/machine/netlist.cpp
+++ b/src/devices/machine/netlist.cpp
@@ -123,7 +123,7 @@ public:
, m_cpu_device(nullptr)
, m_last(*this, "m_last", 0)
{
- m_cpu_device = downcast<netlist_mame_cpu_device *>(&static_cast<netlist_mame_device::netlist_mame_t &>(netlist()).parent());
+ m_cpu_device = downcast<netlist_mame_cpu_device *>(&static_cast<netlist_mame_device::netlist_mame_t &>(exec()).parent());
}
ATTR_COLD void reset() override
@@ -171,7 +171,7 @@ public:
, m_cpu_device(nullptr)
, m_last(*this, "m_last", 0)
{
- m_cpu_device = downcast<netlist_mame_cpu_device *>(&static_cast<netlist_mame_device::netlist_mame_t &>(netlist()).parent());
+ m_cpu_device = downcast<netlist_mame_cpu_device *>(&static_cast<netlist_mame_device::netlist_mame_t &>(exec()).parent());
}
ATTR_COLD void reset() override
@@ -238,7 +238,7 @@ public:
std::unique_ptr<plib::pistream> netlist_source_memregion_t::stream(const pstring &name)
{
- memory_region *mem = static_cast<netlist_mame_device::netlist_mame_t &>(setup().netlist()).machine().root_device().memregion(m_name.c_str());
+ memory_region *mem = static_cast<netlist_mame_device::netlist_mame_t &>(setup().exec()).machine().root_device().memregion(m_name.c_str());
return plib::make_unique_base<plib::pistream, plib::pimemstream>(mem->base(), mem->bytes());
}
@@ -249,7 +249,7 @@ netlist_data_memregions_t::netlist_data_memregions_t(netlist::setup_t &setup)
std::unique_ptr<plib::pistream> netlist_data_memregions_t::stream(const pstring &name)
{
- memory_region *mem = static_cast<netlist_mame_device::netlist_mame_t &>(setup().netlist()).parent().memregion(name.c_str());
+ memory_region *mem = static_cast<netlist_mame_device::netlist_mame_t &>(setup().exec()).parent().memregion(name.c_str());
if (mem != nullptr)
{
return plib::make_unique_base<plib::pistream, plib::pimemstream>(mem->base(), mem->bytes());
@@ -301,7 +301,7 @@ public:
{
int pos = (upto - m_last_buffer_time) / m_sample_time;
if (pos > m_bufsize)
- netlist().log().fatal("sound {1}: pos {2} exceeded bufsize {3}\n", name().c_str(), pos, m_bufsize);
+ state().log().fatal("sound {1}: pos {2} exceeded bufsize {3}\n", name().c_str(), pos, m_bufsize);
while (m_last_pos < pos )
{
m_buffer[m_last_pos++] = (stream_sample_t) m_cur;
@@ -388,7 +388,7 @@ public:
if ((*m_channels[i].m_param_name)() != pstring(""))
{
if (i != m_num_channels)
- netlist().log().fatal("sound input numbering has to be sequential!");
+ state().log().fatal("sound input numbering has to be sequential!");
m_num_channels++;
m_channels[i].m_param = dynamic_cast<netlist::param_double_t *>(setup().find_param((*m_channels[i].m_param_name)(), true));
}
@@ -451,7 +451,7 @@ private:
netlist::setup_t &netlist_mame_device::setup()
{
- return m_netlist->setup();
+ return m_netlist->nlstate().setup();
}
void netlist_mame_device::register_memregion_source(netlist::setup_t &setup, const char *name)
@@ -585,7 +585,7 @@ void netlist_mame_analog_output_device::custom_netlist_additions(netlist::setup_
plib::owned_ptr<netlist::device_t> dev = plib::owned_ptr<netlist::device_t>::Create<NETLIB_NAME(analog_callback)>(setup.netlist(), setup.build_fqn(dname));
static_cast<NETLIB_NAME(analog_callback) *>(dev.get())->register_callback(std::move(m_delegate));
- setup.netlist().register_dev(std::move(dev));
+ setup.netlist().add_dev(std::move(dev));
setup.register_link(dname + ".IN", pin);
}
@@ -620,7 +620,7 @@ void netlist_mame_logic_output_device::custom_netlist_additions(netlist::setup_t
plib::owned_ptr<netlist::device_t> dev = plib::owned_ptr<netlist::device_t>::Create<NETLIB_NAME(logic_callback)>(setup.netlist(), setup.build_fqn(dname));
static_cast<NETLIB_NAME(logic_callback) *>(dev.get())->register_callback(std::move(m_delegate));
- setup.netlist().register_dev(std::move(dev));
+ setup.netlist().add_dev(std::move(dev));
setup.register_link(dname + ".IN", pin);
}
@@ -880,11 +880,11 @@ void netlist_mame_device::device_start()
}
}
- netlist().prepare_to_run();
+ setup().prepare_to_run();
- netlist().save(*this, m_rem, "m_rem");
- netlist().save(*this, m_div, "m_div");
- netlist().save(*this, m_old, "m_old");
+ netlist().nlstate().save(*this, m_rem, "m_rem");
+ netlist().nlstate().save(*this, m_div, "m_div");
+ netlist().nlstate().save(*this, m_old, "m_old");
save_state();
@@ -922,15 +922,15 @@ ATTR_COLD void netlist_mame_device::device_post_load()
{
LOGDEVCALLS("device_post_load\n");
- netlist().state().post_load();
- netlist().rebuild_lists();
+ netlist().run_state_manager().post_load();
+ netlist().nlstate().rebuild_lists();
}
ATTR_COLD void netlist_mame_device::device_pre_save()
{
LOGDEVCALLS("device_pre_save\n");
- netlist().state().pre_save();
+ netlist().run_state_manager().pre_save();
}
void netlist_mame_device::update_icount()
@@ -951,7 +951,7 @@ void netlist_mame_device::check_mame_abort_slice()
ATTR_COLD void netlist_mame_device::save_state()
{
- for (auto const & s : netlist().state().save_list())
+ for (auto const & s : netlist().run_state_manager().save_list())
{
netlist().log().debug("saving state for {1}\n", s->m_name.c_str());
if (s->m_dt.is_float)
@@ -1015,7 +1015,7 @@ void netlist_mame_cpu_device::device_start()
state_add(STATE_GENPCBASE, "CURPC", m_genPC).noshow();
int index = 0;
- for (auto &n : netlist().nets())
+ for (auto &n : netlist().nlstate().nets())
{
if (n->is_logic())
{
@@ -1120,7 +1120,7 @@ void netlist_mame_sound_device::device_start()
// Configure outputs
- std::vector<nld_sound_out *> outdevs = netlist().get_device_list<nld_sound_out>();
+ std::vector<nld_sound_out *> outdevs = netlist().nlstate().get_device_list<nld_sound_out>();
if (outdevs.size() == 0)
fatalerror("No output devices");
@@ -1147,7 +1147,7 @@ void netlist_mame_sound_device::device_start()
m_in = nullptr;
- std::vector<nld_sound_in *> indevs = netlist().get_device_list<nld_sound_in>();
+ std::vector<nld_sound_in *> indevs = netlist().nlstate().get_device_list<nld_sound_in>();
if (indevs.size() > 1)
fatalerror("A maximum of one input device is allowed!");
if (indevs.size() == 1)
diff --git a/src/lib/netlist/analog/nlid_twoterm.h b/src/lib/netlist/analog/nlid_twoterm.h
index efb9a8dd929..cb856763176 100644
--- a/src/lib/netlist/analog/nlid_twoterm.h
+++ b/src/lib/netlist/analog/nlid_twoterm.h
@@ -33,7 +33,8 @@
#ifndef NLID_TWOTERM_H_
#define NLID_TWOTERM_H_
-#include "../nl_base.h"
+#include "netlist/nl_base.h"
+#include "netlist/nl_setup.h"
#include "../plib/pfunction.h"
// -----------------------------------------------------------------------------
@@ -400,7 +401,7 @@ public:
, m_R(*this, "R", 0.1)
, m_V(*this, "V", 0.0)
, m_func(*this,"FUNC", "")
- , m_compiled(this->name() + ".FUNCC", this, this->netlist().state())
+ , m_compiled(this->name() + ".FUNCC", this, this->state().run_state_manager())
{
register_subalias("P", m_P);
register_subalias("N", m_N);
@@ -431,7 +432,7 @@ public:
NETLIB_CONSTRUCTOR_DERIVED(CS, twoterm)
, m_I(*this, "I", 1.0)
, m_func(*this,"FUNC", "")
- , m_compiled(this->name() + ".FUNCC", this, this->netlist().state())
+ , m_compiled(this->name() + ".FUNCC", this, this->state().run_state_manager())
{
register_subalias("P", m_P);
register_subalias("N", m_N);
diff --git a/src/lib/netlist/devices/nlid_proxy.cpp b/src/lib/netlist/devices/nlid_proxy.cpp
index c5ad63f3910..d4163a74c42 100644
--- a/src/lib/netlist/devices/nlid_proxy.cpp
+++ b/src/lib/netlist/devices/nlid_proxy.cpp
@@ -111,9 +111,9 @@ namespace netlist
for (int i = 0; i < 3; i++)
{
pstring devname = out_proxied->device().name();
- auto tp = netlist().setup().find_terminal(devname + "." + power_syms[i][0],
+ auto tp = setup().find_terminal(devname + "." + power_syms[i][0],
detail::terminal_type::INPUT, false);
- auto tn = netlist().setup().find_terminal(devname + "." + power_syms[i][1],
+ auto tn = setup().find_terminal(devname + "." + power_syms[i][1],
detail::terminal_type::INPUT, false);
if (tp != nullptr && tn != nullptr)
{
diff --git a/src/lib/netlist/devices/nlid_system.h b/src/lib/netlist/devices/nlid_system.h
index 6acda365c8f..498ce657818 100644
--- a/src/lib/netlist/devices/nlid_system.h
+++ b/src/lib/netlist/devices/nlid_system.h
@@ -317,7 +317,7 @@ namespace netlist
, m_N(*this, "N", 1)
, m_func(*this, "FUNC", "A0")
, m_Q(*this, "Q")
- , m_compiled(this->name() + ".FUNCC", this, this->netlist().state())
+ , m_compiled(this->name() + ".FUNCC", this, this->state().run_state_manager())
{
std::vector<pstring> inps;
for (int i=0; i < m_N(); i++)
diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp
index 9c19d10f0c9..831818b8c39 100644
--- a/src/lib/netlist/nl_base.cpp
+++ b/src/lib/netlist/nl_base.cpp
@@ -146,7 +146,7 @@ const logic_family_desc_t *family_CD4XXX()
// queue_t
// ----------------------------------------------------------------------------------------
-detail::queue_t::queue_t(netlist_t &nl)
+detail::queue_t::queue_t(netlist_state_t &nl)
: timed_queue<pqentry_t<net_t *, netlist_time>, false, NL_KEEP_STATISTICS>(512)
, netlist_ref(nl)
, plib::state_manager_t::callback_t()
@@ -158,7 +158,7 @@ detail::queue_t::queue_t(netlist_t &nl)
void detail::queue_t::register_state(plib::state_manager_t &manager, const pstring &module)
{
- //netlist().log().debug("register_state\n");
+ //state().log().debug("register_state\n");
manager.save_item(this, m_qsize, module + "." + "qsize");
manager.save_item(this, &m_times[0], module + "." + "times", m_times.size());
manager.save_item(this, &m_net_ids[0], module + "." + "names", m_net_ids.size());
@@ -166,13 +166,13 @@ void detail::queue_t::register_state(plib::state_manager_t &manager, const pstri
void detail::queue_t::on_pre_save()
{
- netlist().log().debug("on_pre_save\n");
+ state().log().debug("on_pre_save\n");
m_qsize = this->size();
- netlist().log().debug("current time {1} qsize {2}\n", exec().time().as_double(), m_qsize);
+ state().log().debug("current time {1} qsize {2}\n", exec().time().as_double(), m_qsize);
for (std::size_t i = 0; i < m_qsize; i++ )
{
m_times[i] = this->listptr()[i].m_exec_time.as_raw();
- m_net_ids[i] = netlist().find_net_id(this->listptr()[i].m_object);
+ m_net_ids[i] = state().find_net_id(this->listptr()[i].m_object);
}
}
@@ -180,15 +180,22 @@ void detail::queue_t::on_pre_save()
void detail::queue_t::on_post_load()
{
this->clear();
- netlist().log().debug("current time {1} qsize {2}\n", exec().time().as_double(), m_qsize);
+ state().log().debug("current time {1} qsize {2}\n", exec().time().as_double(), m_qsize);
for (std::size_t i = 0; i < m_qsize; i++ )
{
- detail::net_t *n = netlist().nets()[m_net_ids[i]].get();
+ detail::net_t *n = state().nets()[m_net_ids[i]].get();
this->push(queue_t::entry_t(netlist_time::from_raw(m_times[i]),n));
}
}
// ----------------------------------------------------------------------------------------
+// netlist_ref_t
+// ----------------------------------------------------------------------------------------
+
+detail::netlist_ref::netlist_ref(netlist_state_t &nl)
+: m_netlist(nl.setup().exec()) { }
+
+// ----------------------------------------------------------------------------------------
// object_t
// ----------------------------------------------------------------------------------------
@@ -230,7 +237,7 @@ detail::terminal_type detail::core_terminal_t::type() const
return terminal_type::OUTPUT;
else
{
- netlist().log().fatal(MF_1_UNKNOWN_TYPE_FOR_OBJECT, name());
+ state().log().fatal(MF_1_UNKNOWN_TYPE_FOR_OBJECT, name());
return terminal_type::TERMINAL; // please compiler
}
}
@@ -240,14 +247,18 @@ detail::terminal_type detail::core_terminal_t::type() const
// ----------------------------------------------------------------------------------------
netlist_t::netlist_t(const pstring &aname, std::unique_ptr<callbacks_t> callbacks)
- : netlist_base_t(aname, std::move(callbacks))
+ : m_state(plib::make_unique<netlist_state_t>(aname,
+ std::move(callbacks),
+ plib::make_unique<setup_t>(*this))) // FIXME, ugly but needed to have netlist_state_t constructed first
, m_time(netlist_time::zero())
, m_mainclock(nullptr)
- , m_queue(*this)
+ , m_queue(*m_state)
, m_solver(nullptr)
{
- state().save_item(this, static_cast<plib::state_manager_t::callback_t &>(m_queue), "m_queue");
- state().save_item(this, m_time, "m_time");
+ devices::initialize_factory(nlstate().setup().factory());
+ NETLIST_NAME(base)(nlstate().setup());
+ run_state_manager().save_item(this, static_cast<plib::state_manager_t::callback_t &>(m_queue), "m_queue");
+ run_state_manager().save_item(this, m_time, "m_time");
}
netlist_t::~netlist_t()
@@ -258,157 +269,29 @@ netlist_t::~netlist_t()
// netlist_t
// ----------------------------------------------------------------------------------------
-netlist_base_t::netlist_base_t(const pstring &aname, std::unique_ptr<callbacks_t> callbacks)
- :m_params(nullptr)
- , m_name(aname)
- , m_lib(nullptr)
- , m_state()
- , m_callbacks(std::move(callbacks)) // Order is important here
- , m_log(*m_callbacks)
-{
- m_setup = plib::make_unique<setup_t>(*this);
- NETLIST_NAME(base)(*m_setup);
-}
-
-netlist_base_t::~netlist_base_t()
-{
- m_nets.clear();
- m_devices.clear();
-}
-
-void netlist_base_t::register_dev(plib::owned_ptr<core_device_t> dev)
+netlist_state_t::netlist_state_t(const pstring &aname,
+ std::unique_ptr<callbacks_t> &&callbacks,
+ std::unique_ptr<setup_t> &&setup)
+: m_params(nullptr)
+, m_name(aname)
+, m_state()
+, m_callbacks(std::move(callbacks)) // Order is important here
+, m_log(*m_callbacks)
+, m_setup(std::move(setup))
{
- for (auto & d : m_devices)
- if (d->name() == dev->name())
- log().fatal(MF_1_DUPLICATE_NAME_DEVICE_LIST, d->name());
- m_devices.push_back(std::move(dev));
+ pstring libpath = plib::util::environment("NL_BOOSTLIB", plib::util::buildpath({".", "nlboost.so"}));
+ m_lib = plib::make_unique<plib::dynlib>(libpath);
}
-void netlist_base_t::remove_dev(core_device_t *dev)
-{
- m_devices.erase(
- std::remove_if(
- m_devices.begin(),
- m_devices.end(),
- [&] (plib::owned_ptr<core_device_t> const& p)
- {
- return p.get() == dev;
- }),
- m_devices.end()
- );
-}
-void netlist_base_t::delete_empty_nets()
+netlist_state_t::~netlist_state_t()
{
- m_nets.erase(
- std::remove_if(m_nets.begin(), m_nets.end(),
- [](plib::owned_ptr<detail::net_t> &x)
- {
- if (x->num_cons() == 0)
- {
- x->netlist().log().verbose("Deleting net {1} ...", x->name());
- return true;
- }
- else
- return false;
- }), m_nets.end());
+ nets().clear();
+ m_devices.clear();
}
-void netlist_base_t::prepare_to_run()
-{
- setup().register_dynamic_log_devices();
-
- /* load the library ... */
-
- /* make sure the solver and parameters are started first! */
-
- for (auto & e : setup().m_device_factory)
- {
- if ( setup().factory().is_class<devices::NETLIB_NAME(solver)>(e.second)
- || setup().factory().is_class<devices::NETLIB_NAME(netlistparams)>(e.second))
- {
- auto dev = plib::owned_ptr<device_t>(e.second->Create(*this, e.first));
- register_dev(std::move(dev));
- }
- }
-
- log().debug("Searching for solver and parameters ...\n");
- auto solver = get_single_device<devices::NETLIB_NAME(solver)>("solver");
- m_params = get_single_device<devices::NETLIB_NAME(netlistparams)>("parameter");
- /* create devices */
-
- log().debug("Creating devices ...\n");
- for (auto & e : setup().m_device_factory)
- {
- if ( !setup().factory().is_class<devices::NETLIB_NAME(solver)>(e.second)
- && !setup().factory().is_class<devices::NETLIB_NAME(netlistparams)>(e.second))
- {
- auto dev = plib::owned_ptr<device_t>(e.second->Create(*this, e.first));
- register_dev(std::move(dev));
- }
- }
-
- bool use_deactivate = (m_params->m_use_deactivate() ? true : false);
-
- for (auto &d : m_devices)
- {
- if (use_deactivate)
- {
- auto p = setup().m_param_values.find(d->name() + ".HINT_NO_DEACTIVATE");
- if (p != setup().m_param_values.end())
- {
- //FIXME: check for errors ...
- double v = plib::pstonum<double>(p->second);
- if (std::abs(v - std::floor(v)) > 1e-6 )
- log().fatal(MF_1_HND_VAL_NOT_SUPPORTED, p->second);
- d->set_hint_deactivate(v == 0.0);
- }
- }
- else
- d->set_hint_deactivate(false);
- }
-
- pstring libpath = plib::util::environment("NL_BOOSTLIB", plib::util::buildpath({".", "nlboost.so"}));
- m_lib = plib::make_unique<plib::dynlib>(libpath);
-
- /* resolve inputs */
- setup().resolve_inputs();
-
- log().verbose("looking for two terms connected to rail nets ...");
- for (auto & t : get_device_list<analog::NETLIB_NAME(twoterm)>())
- {
- if (t->m_N.net().isRailNet() && t->m_P.net().isRailNet())
- {
- log().warning(MW_3_REMOVE_DEVICE_1_CONNECTED_ONLY_TO_RAILS_2_3,
- t->name(), t->m_N.net().name(), t->m_P.net().name());
- t->m_N.net().remove_terminal(t->m_N);
- t->m_P.net().remove_terminal(t->m_P);
- remove_dev(t);
- }
- }
-
- log().verbose("initialize solver ...\n");
-
- if (solver == nullptr)
- {
- for (auto &p : m_nets)
- if (p->is_analog())
- log().fatal(MF_0_NO_SOLVER);
- }
- else
- solver->post_start();
-
- for (auto &n : m_nets)
- for (auto & term : n->m_core_terms)
- {
- //core_device_t *dev = reinterpret_cast<core_device_t *>(term->m_delegate.object());
- core_device_t *dev = &term->device();
- dev->set_default_delegate(*term);
- }
-
-}
void netlist_t::stop()
{
@@ -419,7 +302,7 @@ void netlist_t::stop()
m_solver->stop();
}
-detail::net_t *netlist_base_t::find_net(const pstring &name) const
+detail::net_t *netlist_state_t::find_net(const pstring &name) const
{
for (auto & net : m_nets)
if (net->name() == name)
@@ -428,7 +311,7 @@ detail::net_t *netlist_base_t::find_net(const pstring &name) const
return nullptr;
}
-std::size_t netlist_base_t::find_net_id(const detail::net_t *net) const
+std::size_t netlist_state_t::find_net_id(const detail::net_t *net) const
{
for (std::size_t i = 0; i < m_nets.size(); i++)
if (m_nets[i].get() == net)
@@ -438,7 +321,7 @@ std::size_t netlist_base_t::find_net_id(const detail::net_t *net) const
-void netlist_base_t::rebuild_lists()
+void netlist_state_t::rebuild_lists()
{
for (auto & net : m_nets)
net->rebuild_list();
@@ -448,10 +331,10 @@ void netlist_base_t::rebuild_lists()
void netlist_t::reset()
{
log().debug("Searching for mainclock\n");
- m_mainclock = get_single_device<devices::NETLIB_NAME(mainclock)>("mainclock");
+ m_mainclock = m_state->get_single_device<devices::NETLIB_NAME(mainclock)>("mainclock");
log().debug("Searching for solver\n");
- m_solver = get_single_device<devices::NETLIB_NAME(solver)>("solver");
+ m_solver = m_state->get_single_device<devices::NETLIB_NAME(solver)>("solver");
m_time = netlist_time::zero();
m_queue.clear();
@@ -460,16 +343,16 @@ void netlist_t::reset()
//if (m_solver != nullptr)
// m_solver->do_reset();
- std::unordered_map<core_device_t *, bool> m;
-
- for (auto &d : m_devices)
- {
- m[d.get()] = d->get_hint_deactivate();
- }
+ m_state->reset();
+}
+void netlist_state_t::reset()
+{
+ //FIXME: never used ???
+ std::unordered_map<core_device_t *, bool> m;
// Reset all nets once !
- for (auto & n : m_nets)
+ for (auto & n : nets())
n->reset();
// Reset all devices once !
@@ -545,8 +428,7 @@ void netlist_t::reset()
#if 1
/* the above may screw up m_active and the list */
- for (auto &n : m_nets)
- n->rebuild_list();
+ rebuild_lists();
#endif
}
@@ -610,18 +492,18 @@ void netlist_t::print_stats() const
if (nperftime_t<NL_KEEP_STATISTICS>::enabled)
{
std::vector<size_t> index;
- for (size_t i=0; i<m_devices.size(); i++)
+ for (size_t i=0; i < m_state->m_devices.size(); i++)
index.push_back(i);
std::sort(index.begin(), index.end(),
- [&](size_t i1, size_t i2) { return m_devices[i1]->m_stat_total_time.total() < m_devices[i2]->m_stat_total_time.total(); });
+ [&](size_t i1, size_t i2) { return m_state->m_devices[i1]->m_stat_total_time.total() < m_state->m_devices[i2]->m_stat_total_time.total(); });
nperftime_t<NL_KEEP_STATISTICS>::type total_time(0);
uint_least64_t total_count(0);
for (auto & j : index)
{
- auto entry = m_devices[j].get();
+ auto entry = m_state->m_devices[j].get();
log().verbose("Device {1:20} : {2:12} {3:12} {4:15} {5:12}", entry->name(),
entry->m_stat_call_count(), entry->m_stat_total_time.count(),
entry->m_stat_total_time.total(), entry->m_stat_inc_active());
@@ -657,7 +539,7 @@ void netlist_t::print_stats() const
/ static_cast<nperftime_t<NL_KEEP_STATISTICS>::type>(m_queue.m_prof_call());
log().verbose("Overhead per pop {1:11}", overhead_per_pop );
log().verbose("");
- for (auto &entry : m_devices)
+ for (auto &entry : m_state->m_devices)
{
if (entry->m_stat_inc_active() > 3 * entry->m_stat_total_time.count())
log().verbose("HINT({}, NO_DEACTIVATE)", entry->name());
@@ -665,7 +547,7 @@ void netlist_t::print_stats() const
}
}
-core_device_t *netlist_base_t::get_single_device(const pstring &classname, bool (*cc)(core_device_t *)) const
+core_device_t *netlist_state_t::get_single_device(const pstring &classname, bool (*cc)(core_device_t *)) const
{
core_device_t *ret = nullptr;
for (auto &d : m_devices)
@@ -673,7 +555,7 @@ core_device_t *netlist_base_t::get_single_device(const pstring &classname, bool
if (cc(d.get()))
{
if (ret != nullptr)
- this->log().fatal(MF_1_MORE_THAN_ONE_1_DEVICE_FOUND, classname);
+ m_log.fatal(MF_1_MORE_THAN_ONE_1_DEVICE_FOUND, classname);
else
ret = d.get();
}
@@ -699,13 +581,13 @@ core_device_t::core_device_t(netlist_base_t &owner, const pstring &name)
core_device_t::core_device_t(core_device_t &owner, const pstring &name)
: object_t(owner.name() + "." + name)
, logic_family_t()
- , netlist_ref(owner.netlist())
+ , netlist_ref(owner.state())
, m_hint_deactivate(false)
{
set_logic_family(owner.logic_family());
if (logic_family() == nullptr)
set_logic_family(family_TTL());
- owner.netlist().register_dev(plib::owned_ptr<core_device_t>(this, false));
+ state().add_dev(plib::owned_ptr<core_device_t>(this, false));
}
core_device_t::~core_device_t()
@@ -720,7 +602,7 @@ void core_device_t::set_default_delegate(detail::core_terminal_t &term)
log_type & core_device_t::log()
{
- return netlist().log();
+ return state().log();
}
// ----------------------------------------------------------------------------------------
@@ -744,12 +626,12 @@ device_t::~device_t()
setup_t &device_t::setup()
{
- return netlist().setup();
+ return state().setup();
}
const setup_t &device_t::setup() const
{
- return netlist().setup();
+ return state().setup();
}
void device_t::register_subalias(const pstring &name, detail::core_terminal_t &term)
@@ -795,7 +677,7 @@ void device_t::connect_post_start(detail::core_terminal_t &t1, detail::core_term
detail::family_setter_t::family_setter_t(core_device_t &dev, const pstring &desc)
{
- dev.set_logic_family(dev.netlist().setup().family_from_model(desc));
+ dev.set_logic_family(dev.setup().family_from_model(desc));
}
detail::family_setter_t::family_setter_t(core_device_t &dev, const logic_family_desc_t *desc)
@@ -820,7 +702,7 @@ detail::net_t::net_t(netlist_base_t &nl, const pstring &aname, core_terminal_t *
detail::net_t::~net_t()
{
- netlist().state().remove_save_items(this);
+ state().run_state_manager().remove_save_items(this);
}
void detail::net_t::add_to_active_list(core_terminal_t &term) NL_NOEXCEPT
@@ -859,7 +741,7 @@ void detail::net_t::rebuild_list()
m_list_active.clear();
for (auto & term : m_core_terms)
- if (term->state() != logic_t::STATE_INP_PASSIVE)
+ if (term->terminal_state() != logic_t::STATE_INP_PASSIVE)
{
m_list_active.push_back(term);
}
@@ -870,7 +752,7 @@ void detail::net_t::process(const std::uint_fast8_t mask)
for (auto & p : m_list_active)
{
p.device().m_stat_call_count.inc();
- if ((p.state() & mask))
+ if ((p.terminal_state() & mask))
{
p.device().m_stat_total_time.start();
p.m_delegate();
@@ -921,7 +803,7 @@ void detail::net_t::reset()
for (core_terminal_t *ct : m_core_terms)
{
ct->reset();
- if (ct->state() != logic_t::STATE_INP_PASSIVE)
+ if (ct->terminal_state() != logic_t::STATE_INP_PASSIVE)
m_list_active.push_back(ct);
}
}
@@ -930,7 +812,7 @@ void detail::net_t::add_terminal(detail::core_terminal_t &terminal)
{
for (auto &t : m_core_terms)
if (t == &terminal)
- netlist().log().fatal(MF_2_NET_1_DUPLICATE_TERMINAL_2, name(),
+ state().log().fatal(MF_2_NET_1_DUPLICATE_TERMINAL_2, name(),
t->name());
terminal.set_net(this);
@@ -946,7 +828,7 @@ void detail::net_t::remove_terminal(detail::core_terminal_t &terminal)
plib::container::remove(m_core_terms, &terminal);
}
else
- netlist().log().fatal(MF_2_REMOVE_TERMINAL_1_FROM_NET_2, terminal.name(),
+ state().log().fatal(MF_2_REMOVE_TERMINAL_1_FROM_NET_2, terminal.name(),
this->name());
}
@@ -1035,7 +917,7 @@ terminal_t::terminal_t(core_device_t &dev, const pstring &aname)
, m_go1(nullptr)
, m_gt1(nullptr)
{
- netlist().setup().register_term(*this);
+ state().setup().register_term(*this);
}
terminal_t::~terminal_t()
@@ -1072,12 +954,12 @@ void terminal_t::schedule_solve_after(const netlist_time &after)
logic_output_t::logic_output_t(core_device_t &dev, const pstring &aname)
: logic_t(dev, aname, STATE_OUT)
- , m_my_net(dev.netlist(), name() + ".net", this)
+ , m_my_net(dev.state(), name() + ".net", this)
{
this->set_net(&m_my_net);
- netlist().register_net(plib::owned_ptr<logic_net_t>(&m_my_net, false));
+ state().register_net(plib::owned_ptr<logic_net_t>(&m_my_net, false));
set_logic_family(dev.logic_family());
- netlist().setup().register_term(*this);
+ state().setup().register_term(*this);
}
logic_output_t::~logic_output_t()
@@ -1097,7 +979,7 @@ void logic_output_t::initial(const netlist_sig_t val)
analog_input_t::analog_input_t(core_device_t &dev, const pstring &aname)
: analog_t(dev, aname, STATE_INP_ACTIVE)
{
- netlist().setup().register_term(*this);
+ state().setup().register_term(*this);
}
analog_input_t::~analog_input_t()
@@ -1110,13 +992,13 @@ analog_input_t::~analog_input_t()
analog_output_t::analog_output_t(core_device_t &dev, const pstring &aname)
: analog_t(dev, aname, STATE_OUT)
- , m_my_net(dev.netlist(), name() + ".net", this)
+ , m_my_net(dev.state(), name() + ".net", this)
{
- netlist().register_net(plib::owned_ptr<analog_net_t>(&m_my_net, false));
+ state().register_net(plib::owned_ptr<analog_net_t>(&m_my_net, false));
this->set_net(&m_my_net);
//net().m_cur_Analog = NL_FCONST(0.0);
- netlist().setup().register_term(*this);
+ state().setup().register_term(*this);
}
analog_output_t::~analog_output_t()
@@ -1137,7 +1019,7 @@ logic_input_t::logic_input_t(core_device_t &dev, const pstring &aname,
: logic_t(dev, aname, STATE_INP_ACTIVE, delegate)
{
set_logic_family(dev.logic_family());
- netlist().setup().register_term(*this);
+ state().setup().register_term(*this);
}
logic_input_t::~logic_input_t()
@@ -1172,7 +1054,7 @@ param_t::param_type_t param_t::param_type() const
return POINTER;
else
{
- netlist().log().fatal(MF_1_UNKNOWN_PARAM_TYPE, name());
+ state().log().fatal(MF_1_UNKNOWN_PARAM_TYPE, name());
return POINTER; /* Please compiler */
}
}
@@ -1196,7 +1078,7 @@ pstring param_t::get_initial(const device_t &dev, bool *found)
const pstring param_model_t::model_type()
{
if (m_map.size() == 0)
- netlist().setup().model_parse(this->Value(), m_map);
+ state().setup().model_parse(this->Value(), m_map);
return m_map["COREMODEL"];
}
@@ -1223,28 +1105,28 @@ param_ptr_t::param_ptr_t(device_t &device, const pstring &name, uint8_t * val)
void param_model_t::changed()
{
- netlist().log().fatal(MF_1_MODEL_1_CAN_NOT_BE_CHANGED_AT_RUNTIME, name());
+ state().log().fatal(MF_1_MODEL_1_CAN_NOT_BE_CHANGED_AT_RUNTIME, name());
m_map.clear();
}
const pstring param_model_t::model_value_str(const pstring &entity)
{
if (m_map.size() == 0)
- netlist().setup().model_parse(this->Value(), m_map);
- return netlist().setup().model_value_str(m_map, entity);
+ state().setup().model_parse(this->Value(), m_map);
+ return state().setup().model_value_str(m_map, entity);
}
nl_double param_model_t::model_value(const pstring &entity)
{
if (m_map.size() == 0)
- netlist().setup().model_parse(this->Value(), m_map);
- return netlist().setup().model_value(m_map, entity);
+ state().setup().model_parse(this->Value(), m_map);
+ return state().setup().model_value(m_map, entity);
}
std::unique_ptr<plib::pistream> param_data_t::stream()
{
- return device().netlist().setup().get_data_stream(Value());
+ return device().setup().get_data_stream(Value());
}
bool detail::core_terminal_t::is_logic() const NL_NOEXCEPT
diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h
index 3d8ef2401d5..72e87fd4964 100644
--- a/src/lib/netlist/nl_base.h
+++ b/src/lib/netlist/nl_base.h
@@ -211,7 +211,8 @@ namespace netlist
class net_t;
class setup_t;
class netlist_t;
- class netlist_base_t;
+ class netlist_state_t;
+ typedef netlist_state_t netlist_base_t;
class core_device_t;
class device_t;
class callbacks_t;
@@ -425,19 +426,22 @@ namespace netlist
struct detail::netlist_ref
{
- explicit constexpr netlist_ref(netlist_base_t &nl) : m_netlist(nl) { }
+ explicit netlist_ref(netlist_state_t &nl);
- C14CONSTEXPR netlist_base_t & netlist() NL_NOEXCEPT { return m_netlist; }
- constexpr const netlist_base_t & netlist() const NL_NOEXCEPT { return m_netlist; }
+ netlist_state_t & state();
+ const netlist_state_t & state() const;
- netlist_t & exec() NL_NOEXCEPT { return *reinterpret_cast<netlist_t *>(&m_netlist); }
- const netlist_t & exec() const NL_NOEXCEPT { return *reinterpret_cast<const netlist_t *>(&m_netlist); }
+ setup_t & setup();
+ const setup_t & setup() const;
+
+ C14CONSTEXPR netlist_t & exec() NL_NOEXCEPT { return m_netlist; }
+ constexpr const netlist_t & exec() const NL_NOEXCEPT { return m_netlist; }
protected:
~netlist_ref() = default; // prohibit polymorphic destruction
private:
- netlist_base_t & m_netlist;
+ netlist_t & m_netlist;
};
@@ -469,8 +473,8 @@ namespace netlist
/*! The netlist owning the owner of this object.
* \returns reference to netlist object.
*/
- netlist_base_t &netlist() NL_NOEXCEPT;
- const netlist_base_t &netlist() const NL_NOEXCEPT;
+ netlist_base_t &state() NL_NOEXCEPT;
+ const netlist_base_t &state() const NL_NOEXCEPT;
netlist_t &exec() NL_NOEXCEPT;
const netlist_t &exec() const NL_NOEXCEPT;
@@ -534,7 +538,7 @@ namespace netlist
bool is_analog() const NL_NOEXCEPT;
bool is_state(const state_e astate) const NL_NOEXCEPT { return (m_state == astate); }
- const state_e &state() const NL_NOEXCEPT { return m_state; }
+ const state_e &terminal_state() const NL_NOEXCEPT { return m_state; }
void set_state(const state_e astate) NL_NOEXCEPT { m_state = astate; }
void reset() { set_state(is_type(OUTPUT) ? STATE_OUT : STATE_INP_ACTIVE); }
@@ -1156,7 +1160,6 @@ namespace netlist
setup_t &setup();
const setup_t &setup() const;
-
template<class C, typename... Args>
void register_sub(const pstring &name, std::unique_ptr<C> &dev, const Args&... args)
{
@@ -1213,7 +1216,7 @@ namespace netlist
{
public:
typedef pqentry_t<net_t *, netlist_time> entry_t;
- explicit queue_t(netlist_t &nl);
+ explicit queue_t(netlist_state_t &nl);
protected:
@@ -1228,55 +1231,21 @@ namespace netlist
};
// -----------------------------------------------------------------------------
- // netlist_t
+ // netlist_state__t
// -----------------------------------------------------------------------------
- class netlist_base_t : private plib::nocopyassignmove
+ class netlist_state_t : private plib::nocopyassignmove
{
public:
-
using nets_collection_type = std::vector<plib::owned_ptr<detail::net_t>>;
+ using devices_collection_type = std::vector<plib::owned_ptr<core_device_t>>;
+ netlist_state_t(const pstring &aname,
+ std::unique_ptr<callbacks_t> &&callbacks,
+ std::unique_ptr<setup_t> &&setup);
- explicit netlist_base_t(const pstring &aname, std::unique_ptr<callbacks_t> callbacks);
- ~netlist_base_t();
-
- /* Control functions */
-
- void stop();
- void reset();
-
- // ========================================================
- // configuration section
- // ========================================================
-
- void prepare_to_run();
-
- // FIXME: sort rebuild_lists out
- void rebuild_lists(); /* must be called after post_load ! */
-
- /* netlist build functions */
-
- setup_t &setup() NL_NOEXCEPT { return *m_setup; }
- const setup_t &setup() const NL_NOEXCEPT { return *m_setup; }
-
- void register_dev(plib::owned_ptr<core_device_t> dev);
- void remove_dev(core_device_t *dev);
+ ~netlist_state_t();
- detail::net_t *find_net(const pstring &name) const;
- std::size_t find_net_id(const detail::net_t *net) const;
-
- template<class device_class>
- std::vector<device_class *> get_device_list() const
- {
- std::vector<device_class *> tmp;
- for (auto &d : m_devices)
- {
- device_class *dev = dynamic_cast<device_class *>(d.get());
- if (dev != nullptr)
- tmp.push_back(dev);
- }
- return tmp;
- }
+ friend class netlist_t; // allow access to private members
template<class C>
static bool check_class(core_device_t *p)
@@ -1297,66 +1266,103 @@ namespace netlist
log_type & log() { return m_log; }
const log_type &log() const { return m_log; }
- /* state related */
+ plib::dynlib &lib() { return *m_lib; }
+
+ /* state handling */
- plib::state_manager_t &state() { return m_state; }
+ plib::state_manager_t &run_state_manager() { return m_state; }
template<typename O, typename C> void save(O &owner, C &state, const pstring &stname)
{
- this->state().save_item(static_cast<void *>(&owner), state, owner.name() + pstring(".") + stname);
+ this->run_state_manager().save_item(static_cast<void *>(&owner), state, owner.name() + pstring(".") + stname);
}
template<typename O, typename C> void save(O &owner, C *state, const pstring &stname, const std::size_t count)
{
- this->state().save_state_ptr(static_cast<void *>(&owner), owner.name() + pstring(".") + stname, plib::state_manager_t::datatype_f<C>::f(), count, state);
+ this->run_state_manager().save_state_ptr(static_cast<void *>(&owner), owner.name() + pstring(".") + stname, plib::state_manager_t::datatype_f<C>::f(), count, state);
}
- plib::dynlib &lib() { return *m_lib; }
+ core_device_t *get_single_device(const pstring &classname, bool (*cc)(core_device_t *)) const;
- const nets_collection_type &nets() { return m_nets; }
+ detail::net_t *find_net(const pstring &name) const;
+ std::size_t find_net_id(const detail::net_t *net) const;
template <typename T>
- void register_net(plib::owned_ptr<T> &&net)
+ void register_net(plib::owned_ptr<T> &&net) { m_nets.push_back(std::move(net)); }
+
+ devices::NETLIB_NAME(netlistparams) *m_params;
+
+ template<class device_class>
+ inline std::vector<device_class *> get_device_list()
{
- m_nets.push_back(std::move(net));
+ std::vector<device_class *> tmp;
+ for (auto &d : m_devices)
+ {
+ device_class *dev = dynamic_cast<device_class *>(d.get());
+ if (dev != nullptr)
+ tmp.push_back(dev);
+ }
+ return tmp;
+ }
+
+ void add_dev(plib::owned_ptr<core_device_t> dev)
+ {
+ for (auto & d : m_devices)
+ if (d->name() == dev->name())
+ log().fatal(MF_1_DUPLICATE_NAME_DEVICE_LIST, d->name());
+ m_devices.push_back(std::move(dev));
}
- void delete_empty_nets();
+ void remove_dev(core_device_t *dev)
+ {
+ m_devices.erase(
+ std::remove_if(
+ m_devices.begin(),
+ m_devices.end(),
+ [&] (plib::owned_ptr<core_device_t> const& p)
+ {
+ return p.get() == dev;
+ }),
+ m_devices.end()
+ );
+ }
/* sole use is to manage lifetime of family objects */
std::vector<std::pair<pstring, std::unique_ptr<logic_family_desc_t>>> m_family_cache;
- protected:
-
- /* sole use is to manage lifetime of net objects */
- std::vector<plib::owned_ptr<core_device_t>> m_devices;
- nets_collection_type m_nets;
+ setup_t &setup() NL_NOEXCEPT { return *m_setup; }
+ const setup_t &setup() const NL_NOEXCEPT { return *m_setup; }
- private:
+ nets_collection_type & nets() { return m_nets; }
+ devices_collection_type & devices() { return m_devices; }
- core_device_t *get_single_device(const pstring &classname, bool (*cc)(core_device_t *)) const;
+ // FIXME: make a postload member and include code there
+ void rebuild_lists(); /* must be called after post_load ! */
- /* mostly ro */
+ private:
- devices::NETLIB_NAME(netlistparams) *m_params;
+ void reset();
pstring m_name;
std::unique_ptr<plib::dynlib> m_lib; // external lib needs to be loaded as long as netlist exists
-
plib::state_manager_t m_state;
+ std::unique_ptr<callbacks_t> m_callbacks;
+ log_type m_log;
+ std::unique_ptr<setup_t> m_setup;
+ nets_collection_type m_nets;
+ /* sole use is to manage lifetime of net objects */
+ devices_collection_type m_devices;
- std::unique_ptr<callbacks_t> m_callbacks;
- log_type m_log;
- std::unique_ptr<setup_t> m_setup;
};
+ // -----------------------------------------------------------------------------
+ // netlist_t
+ // -----------------------------------------------------------------------------
- class netlist_t : public netlist_base_t
+ class netlist_t
{
public:
- using nets_collection_type = std::vector<plib::owned_ptr<detail::net_t>>;
-
explicit netlist_t(const pstring &aname, std::unique_ptr<callbacks_t> callbacks);
~netlist_t();
@@ -1375,6 +1381,10 @@ namespace netlist
void stop();
void reset();
+ /* state handling */
+
+ plib::state_manager_t &run_state_manager() { return m_state->run_state_manager(); }
+
/* only used by nltool to create static c-code */
devices::NETLIB_NAME(solver) *solver() const NL_NOEXCEPT { return m_solver; }
@@ -1385,11 +1395,17 @@ namespace netlist
return static_cast<X *>(m_solver)->gmin();
}
- protected:
+ netlist_state_t &nlstate() NL_NOEXCEPT { return *m_state; }
+ const netlist_state_t &nlstate() const { return *m_state; }
+
+ log_type & log() { return m_state->log(); }
+ const log_type &log() const { return m_state->log(); }
void print_stats() const;
private:
+ std::unique_ptr<netlist_state_t> m_state;
+
/* mostly rw */
netlist_time m_time;
devices::NETLIB_NAME(mainclock) * m_mainclock;
@@ -1426,6 +1442,26 @@ namespace netlist
// inline implementations
// -----------------------------------------------------------------------------
+ inline netlist_state_t & detail::netlist_ref::state()
+ {
+ return m_netlist.nlstate();
+ }
+
+ inline const netlist_state_t & detail::netlist_ref::state() const
+ {
+ return m_netlist.nlstate();
+ }
+
+ inline setup_t & detail::netlist_ref::setup()
+ {
+ return m_netlist.nlstate().setup();
+ }
+
+ inline const setup_t & detail::netlist_ref::setup() const
+ {
+ return m_netlist.nlstate().setup();
+ }
+
template <typename T>
param_num_t<T>::param_num_t(device_t &device, const pstring &name, const T val)
: param_t(device, name)
@@ -1438,13 +1474,13 @@ namespace netlist
bool err = false;
T vald = plib::pstonum_ne<T>(p, err);
if (err)
- netlist().log().fatal(MF_2_INVALID_NUMBER_CONVERSION_1_2, name, p);
+ device.state().log().fatal(MF_2_INVALID_NUMBER_CONVERSION_1_2, name, p);
m_param = vald;
}
else
m_param = val;
- netlist().save(*this, m_param, "m_param");
+ device.state().save(*this, m_param, "m_param");
}
template <typename ST, std::size_t AW, std::size_t DW>
@@ -1455,7 +1491,7 @@ namespace netlist
if (f != nullptr)
f->read(&m_data[0],1<<AW);
else
- device.netlist().log().warning("Rom {1} not found", Value());
+ device.state().log().warning("Rom {1} not found", Value());
}
inline void logic_input_t::inactivate() NL_NOEXCEPT
@@ -1531,7 +1567,7 @@ namespace netlist
inline const netlist_sig_t & logic_input_t::Q() const NL_NOEXCEPT
{
- nl_assert(state() != STATE_INP_PASSIVE);
+ nl_assert(terminal_state() != STATE_INP_PASSIVE);
return net().Q();
}
@@ -1549,14 +1585,14 @@ namespace netlist
}
}
- inline netlist_base_t &detail::device_object_t::netlist() NL_NOEXCEPT
+ inline netlist_base_t &detail::device_object_t::state() NL_NOEXCEPT
{
- return m_device.netlist();
+ return m_device.state();
}
- inline const netlist_base_t &detail::device_object_t::netlist() const NL_NOEXCEPT
+ inline const netlist_base_t &detail::device_object_t::state() const NL_NOEXCEPT
{
- return m_device.netlist();
+ return m_device.state();
}
inline netlist_t &detail::device_object_t::exec() NL_NOEXCEPT
@@ -1574,14 +1610,14 @@ namespace netlist
state_var<T>::state_var(O &owner, const pstring &name, const T &value)
: m_value(value)
{
- owner.netlist().save(owner, m_value, name);
+ owner.state().save(owner, m_value, name);
}
template <typename T, std::size_t N>
template <typename O>
state_var<T[N]>::state_var(O &owner, const pstring &name, const T & value)
{
- owner.netlist().save(owner, m_value, name);
+ owner.state().save(owner, m_value, name);
for (std::size_t i=0; i<N; i++)
m_value[i] = value;
}
diff --git a/src/lib/netlist/nl_factory.h b/src/lib/netlist/nl_factory.h
index 77da4193951..4dc0409da00 100644
--- a/src/lib/netlist/nl_factory.h
+++ b/src/lib/netlist/nl_factory.h
@@ -40,9 +40,9 @@
factory::constructor_ptr_t decl_ ## chip = NETLIB_NAME(chip ## _c);
namespace netlist {
- class netlist_base_t;
class device_t;
class setup_t;
+ class netlist_state_t;
namespace factory {
// -----------------------------------------------------------------------------
@@ -58,8 +58,8 @@ namespace factory {
const pstring &def_param, const pstring &sourcefile);
virtual ~element_t();
- virtual plib::owned_ptr<device_t> Create(netlist_base_t &anetlist, const pstring &name) = 0;
- virtual void macro_actions(netlist_base_t &anetlist, const pstring &name) {}
+ virtual plib::owned_ptr<device_t> Create(netlist_state_t &anetlist, const pstring &name) = 0;
+ virtual void macro_actions(netlist_state_t &anetlist, const pstring &name) {}
const pstring &name() const { return m_name; }
const pstring &classname() const { return m_classname; }
@@ -84,7 +84,7 @@ namespace factory {
const pstring &def_param, const pstring &sourcefile)
: element_t(name, classname, def_param, sourcefile) { }
- plib::owned_ptr<device_t> Create(netlist_base_t &anetlist, const pstring &name) override
+ plib::owned_ptr<device_t> Create(netlist_state_t &anetlist, const pstring &name) override
{
return plib::owned_ptr<device_t>::Create<C>(anetlist, name);
}
@@ -143,9 +143,9 @@ namespace factory {
const pstring &def_param, const pstring &source)
: element_t(name, classname, def_param, source) { }
- plib::owned_ptr<device_t> Create(netlist_base_t &anetlist, const pstring &name) override;
+ plib::owned_ptr<device_t> Create(netlist_state_t &anetlist, const pstring &name) override;
- void macro_actions(netlist_base_t &anetlist, const pstring &name) override;
+ void macro_actions(netlist_state_t &anetlist, const pstring &name) override;
private:
};
diff --git a/src/lib/netlist/nl_lists.h b/src/lib/netlist/nl_lists.h
index 9e8007e24cd..76e7afc4e48 100644
--- a/src/lib/netlist/nl_lists.h
+++ b/src/lib/netlist/nl_lists.h
@@ -62,10 +62,10 @@ namespace netlist
struct pqentry_t final
{
constexpr pqentry_t() noexcept : m_exec_time(), m_object(nullptr) { }
- constexpr pqentry_t(const Time &t, const Element &o) noexcept : m_exec_time(t), m_object(o) { }
+ constexpr pqentry_t(const Time t, const Element o) noexcept : m_exec_time(t), m_object(o) { }
~pqentry_t() = default;
constexpr pqentry_t(const pqentry_t &e) noexcept = default;
- constexpr pqentry_t(pqentry_t &&e) = default;
+ constexpr pqentry_t(pqentry_t &&e) noexcept = default;
pqentry_t& operator=(pqentry_t && other) noexcept = default;
pqentry_t& operator=(const pqentry_t &other) noexcept = default;
@@ -131,7 +131,7 @@ namespace netlist
}
void pop() noexcept { --m_end; }
- const T &top() const noexcept { return *(m_end-1); }
+ const T top() const noexcept { return *(m_end-1); }
template <class R>
void remove(const R &elem) noexcept
diff --git a/src/lib/netlist/nl_parser.h b/src/lib/netlist/nl_parser.h
index 26f9179c040..a36ca39e29e 100644
--- a/src/lib/netlist/nl_parser.h
+++ b/src/lib/netlist/nl_parser.h
@@ -39,7 +39,7 @@ namespace netlist
void net_truthtable_start(const pstring &nlname);
/* for debugging messages */
- netlist_base_t &netlist() { return m_setup.netlist(); }
+ netlist_state_t &netlist() { return m_setup.netlist(); }
virtual void verror(const pstring &msg, int line_num, const pstring &line) override;
private:
diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp
index 9d004c76c28..5e7a0e8933c 100644
--- a/src/lib/netlist/nl_setup.cpp
+++ b/src/lib/netlist/nl_setup.cpp
@@ -25,13 +25,12 @@
namespace netlist
{
-setup_t::setup_t(netlist_base_t &netlist)
+setup_t::setup_t(netlist_t &netlist)
: m_netlist(netlist)
, m_factory(*this)
, m_proxy_cnt(0)
, m_frontier_cnt(0)
{
- devices::initialize_factory(m_factory);
}
setup_t::~setup_t()
@@ -45,6 +44,16 @@ setup_t::~setup_t()
m_sources.clear();
}
+netlist_state_t &setup_t::netlist()
+{
+ return m_netlist.nlstate();
+}
+const netlist_state_t &setup_t::netlist() const
+{
+ return m_netlist.nlstate();
+}
+
+
pstring setup_t::build_fqn(const pstring &obj_name) const
{
if (m_namespace_stack.empty())
@@ -381,7 +390,7 @@ devices::nld_base_proxy *setup_t::get_d_a_proxy(detail::core_terminal_t &out)
proxy = new_proxy.get();
- netlist().register_dev(std::move(new_proxy));
+ m_netlist.nlstate().add_dev(std::move(new_proxy));
}
return proxy;
}
@@ -420,7 +429,7 @@ devices::nld_base_proxy *setup_t::get_a_d_proxy(detail::core_terminal_t &inp)
inp.net().m_core_terms.clear(); // clear the list
}
ret->out().net().add_terminal(inp);
- netlist().register_dev(std::move(new_proxy));
+ m_netlist.nlstate().add_dev(std::move(new_proxy));
return ret;
}
}
@@ -687,7 +696,7 @@ void setup_t::resolve_inputs()
// delete empty nets
- netlist().delete_empty_nets();
+ delete_empty_nets();
pstring errstr("");
@@ -722,7 +731,7 @@ void setup_t::register_dynamic_log_devices()
auto nc = factory().factory_by_name("LOG")->Create(netlist(), name);
register_link(name + ".I", ll);
log().debug(" dynamic link {1}: <{2}>\n",ll, name);
- netlist().register_dev(std::move(nc));
+ m_netlist.nlstate().add_dev(std::move(nc));
}
}
}
@@ -945,6 +954,123 @@ void setup_t::register_define(const pstring &defstr)
}
// ----------------------------------------------------------------------------------------
+// Device handling
+// ----------------------------------------------------------------------------------------
+
+void setup_t::delete_empty_nets()
+{
+ netlist().nets().erase(
+ std::remove_if(netlist().nets().begin(), netlist().nets().end(),
+ [](plib::owned_ptr<detail::net_t> &x)
+ {
+ if (x->num_cons() == 0)
+ {
+ x->state().log().verbose("Deleting net {1} ...", x->name());
+ return true;
+ }
+ else
+ return false;
+ }), netlist().nets().end());
+}
+
+// ----------------------------------------------------------------------------------------
+// Run preparation
+// ----------------------------------------------------------------------------------------
+
+void setup_t::prepare_to_run()
+{
+ register_dynamic_log_devices();
+
+ /* load the library ... */
+
+ /* make sure the solver and parameters are started first! */
+
+ for (auto & e : m_device_factory)
+ {
+ if ( factory().is_class<devices::NETLIB_NAME(solver)>(e.second)
+ || factory().is_class<devices::NETLIB_NAME(netlistparams)>(e.second))
+ {
+ auto dev = plib::owned_ptr<device_t>(e.second->Create(netlist(), e.first));
+ m_netlist.nlstate().add_dev(std::move(dev));
+ }
+ }
+
+ log().debug("Searching for solver and parameters ...\n");
+
+ auto solver = netlist().get_single_device<devices::NETLIB_NAME(solver)>("solver");
+ netlist().m_params = netlist().get_single_device<devices::NETLIB_NAME(netlistparams)>("parameter");
+
+ /* create devices */
+
+ log().debug("Creating devices ...\n");
+ for (auto & e : m_device_factory)
+ {
+ if ( !factory().is_class<devices::NETLIB_NAME(solver)>(e.second)
+ && !factory().is_class<devices::NETLIB_NAME(netlistparams)>(e.second))
+ {
+ auto dev = plib::owned_ptr<device_t>(e.second->Create(netlist(), e.first));
+ m_netlist.nlstate().add_dev(std::move(dev));
+ }
+ }
+
+ bool use_deactivate = (netlist().m_params->m_use_deactivate() ? true : false);
+
+ for (auto &d : netlist().devices())
+ {
+ if (use_deactivate)
+ {
+ auto p = m_param_values.find(d->name() + ".HINT_NO_DEACTIVATE");
+ if (p != m_param_values.end())
+ {
+ //FIXME: check for errors ...
+ double v = plib::pstonum<double>(p->second);
+ if (std::abs(v - std::floor(v)) > 1e-6 )
+ log().fatal(MF_1_HND_VAL_NOT_SUPPORTED, p->second);
+ d->set_hint_deactivate(v == 0.0);
+ }
+ }
+ else
+ d->set_hint_deactivate(false);
+ }
+
+ /* resolve inputs */
+ resolve_inputs();
+
+ log().verbose("looking for two terms connected to rail nets ...");
+ for (auto & t : m_netlist.nlstate().get_device_list<analog::NETLIB_NAME(twoterm)>())
+ {
+ if (t->m_N.net().isRailNet() && t->m_P.net().isRailNet())
+ {
+ log().warning(MW_3_REMOVE_DEVICE_1_CONNECTED_ONLY_TO_RAILS_2_3,
+ t->name(), t->m_N.net().name(), t->m_P.net().name());
+ t->m_N.net().remove_terminal(t->m_N);
+ t->m_P.net().remove_terminal(t->m_P);
+ m_netlist.nlstate().remove_dev(t);
+ }
+ }
+
+ log().verbose("initialize solver ...\n");
+
+ if (solver == nullptr)
+ {
+ for (auto &p : netlist().nets())
+ if (p->is_analog())
+ log().fatal(MF_0_NO_SOLVER);
+ }
+ else
+ solver->post_start();
+
+ for (auto &n : netlist().nets())
+ for (auto & term : n->m_core_terms)
+ {
+ //core_device_t *dev = reinterpret_cast<core_device_t *>(term->m_delegate.object());
+ core_device_t *dev = &term->device();
+ dev->set_default_delegate(*term);
+ }
+
+}
+
+// ----------------------------------------------------------------------------------------
// base sources
// ----------------------------------------------------------------------------------------
diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h
index 3b2f5c874a6..193905ed62b 100644
--- a/src/lib/netlist/nl_setup.h
+++ b/src/lib/netlist/nl_setup.h
@@ -12,6 +12,7 @@
#include "plib/putil.h"
#include "plib/pstream.h"
#include "plib/pparser.h"
+#include "plib/pstate.h"
#include "nl_factory.h"
#include "nl_config.h"
@@ -127,7 +128,8 @@ namespace netlist
class core_device_t;
class param_t;
class setup_t;
- class netlist_base_t;
+ class netlist_state_t;
+ class netlist_t;
class logic_family_desc_t;
class terminal_t;
@@ -204,11 +206,15 @@ namespace netlist
using link_t = std::pair<pstring, pstring>;
- explicit setup_t(netlist_base_t &netlist);
+ explicit setup_t(netlist_t &netlist);
~setup_t();
- netlist_base_t &netlist() { return m_netlist; }
- const netlist_base_t &netlist() const { return m_netlist; }
+
+ netlist_state_t &netlist();
+ const netlist_state_t &netlist() const;
+
+ netlist_t &exec() { return m_netlist; }
+ const netlist_t &exec() const { return m_netlist; }
pstring build_fqn(const pstring &obj_name) const;
@@ -301,6 +307,14 @@ namespace netlist
/* needed by proxy */
detail::core_terminal_t *find_terminal(const pstring &outname_in, const detail::terminal_type atype, bool required = true);
+ /* core net handling */
+
+ void delete_empty_nets();
+
+ /* run preparation */
+
+ void prepare_to_run();
+
private:
detail::core_terminal_t *find_terminal(const pstring &outname_in, bool required = true);
@@ -319,7 +333,7 @@ namespace netlist
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_base_t &m_netlist;
+ netlist_t &m_netlist;
std::unordered_map<pstring, param_ref_t> m_params;
std::vector<link_t> m_links;
factory::list_t m_factory;
diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp
index 42de2fbd901..6f68ea18135 100644
--- a/src/lib/netlist/prg/nltool.cpp
+++ b/src/lib/netlist/prg/nltool.cpp
@@ -163,6 +163,8 @@ public:
{
}
+ netlist::setup_t &setup() { return nlstate().setup(); }
+
void read_netlist(const pstring &filename, const pstring &name,
const std::vector<pstring> &logs,
const std::vector<pstring> &defines,
@@ -179,15 +181,15 @@ public:
setup().register_source(plib::make_unique_base<netlist::source_t,
netlist::source_file_t>(setup(), filename));
setup().include(name);
- log_setup(logs);
+ create_dynamic_logs(logs);
// start devices
- this->prepare_to_run();
+ setup().prepare_to_run();
// reset
this->reset();
}
- void log_setup(const std::vector<pstring> &logs)
+ void create_dynamic_logs(const std::vector<pstring> &logs)
{
log().debug("Creating dynamic logs ...\n");
for (auto & log : logs)
@@ -200,15 +202,15 @@ public:
std::vector<char> save_state()
{
- state().pre_save();
+ run_state_manager().pre_save();
std::size_t size = 0;
- for (auto const & s : state().save_list())
+ for (auto const & s : run_state_manager().save_list())
size += s->m_dt.size * s->m_count;
std::vector<char> buf(size);
char *p = buf.data();
- for (auto const & s : state().save_list())
+ for (auto const & s : run_state_manager().save_list())
{
std::size_t sz = s->m_dt.size * s->m_count;
if (s->m_dt.is_float || s->m_dt.is_integral)
@@ -224,7 +226,7 @@ public:
void load_state(std::vector<char> &buf)
{
std::size_t size = 0;
- for (auto const & s : state().save_list())
+ for (auto const & s : run_state_manager().save_list())
size += s->m_dt.size * s->m_count;
if (buf.size() != size)
@@ -232,7 +234,7 @@ public:
char *p = buf.data();
- for (auto const & s : state().save_list())
+ for (auto const & s : run_state_manager().save_list())
{
std::size_t sz = s->m_dt.size * s->m_count;
if (s->m_dt.is_float || s->m_dt.is_integral)
@@ -241,8 +243,8 @@ public:
log().fatal("found unsupported save element {1}\n", s->m_name);
p += sz;
}
- state().post_load();
- rebuild_lists();
+ run_state_manager().post_load();
+ nlstate().rebuild_lists();
}
protected:
@@ -595,7 +597,7 @@ void tool_app_t::listdevices()
nt.setup().include("dummy");
- nt.prepare_to_run();
+ nt.setup().prepare_to_run();
std::vector<plib::owned_ptr<netlist::core_device_t>> devs;
diff --git a/src/lib/netlist/solver/nld_matrix_solver.cpp b/src/lib/netlist/solver/nld_matrix_solver.cpp
index fd76b88dee8..d43d37eaf18 100644
--- a/src/lib/netlist/solver/nld_matrix_solver.cpp
+++ b/src/lib/netlist/solver/nld_matrix_solver.cpp
@@ -344,13 +344,13 @@ void matrix_solver_t::setup_matrix()
{
pstring num = plib::pfmt("{1}")(k);
- netlist().save(*this, m_terms[k]->m_last_V, "lastV." + num);
- netlist().save(*this, m_terms[k]->m_DD_n_m_1, "m_DD_n_m_1." + num);
- netlist().save(*this, m_terms[k]->m_h_n_m_1, "m_h_n_m_1." + num);
+ state().save(*this, m_terms[k]->m_last_V, "lastV." + num);
+ state().save(*this, m_terms[k]->m_DD_n_m_1, "m_DD_n_m_1." + num);
+ state().save(*this, m_terms[k]->m_h_n_m_1, "m_h_n_m_1." + num);
- netlist().save(*this, m_terms[k]->go(),"GO" + num, m_terms[k]->count());
- netlist().save(*this, m_terms[k]->gt(),"GT" + num, m_terms[k]->count());
- netlist().save(*this, m_terms[k]->Idr(),"IDR" + num , m_terms[k]->count());
+ state().save(*this, m_terms[k]->go(),"GO" + num, m_terms[k]->count());
+ state().save(*this, m_terms[k]->gt(),"GT" + num, m_terms[k]->count());
+ state().save(*this, m_terms[k]->Idr(),"IDR" + num , m_terms[k]->count());
}
for (unsigned k=0; k<iN; k++)
diff --git a/src/lib/netlist/solver/nld_ms_direct.h b/src/lib/netlist/solver/nld_ms_direct.h
index 7414f16db4c..398e20995f8 100644
--- a/src/lib/netlist/solver/nld_ms_direct.h
+++ b/src/lib/netlist/solver/nld_ms_direct.h
@@ -107,10 +107,10 @@ void matrix_solver_direct_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets)
t->m_nzrd.push_back(static_cast<unsigned>(N()));
}
- netlist().save(*this, m_last_RHS, "m_last_RHS");
+ state().save(*this, m_last_RHS, "m_last_RHS");
for (std::size_t k = 0; k < N(); k++)
- netlist().save(*this, RHS(k), plib::pfmt("RHS.{1}")(k));
+ state().save(*this, RHS(k), plib::pfmt("RHS.{1}")(k));
}
diff --git a/src/lib/netlist/solver/nld_ms_gcr.h b/src/lib/netlist/solver/nld_ms_gcr.h
index b49d9e64602..0f5c041061f 100644
--- a/src/lib/netlist/solver/nld_ms_gcr.h
+++ b/src/lib/netlist/solver/nld_ms_gcr.h
@@ -151,7 +151,7 @@ void matrix_solver_GCR_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets)
// FIXME: Move me
- if (netlist().lib().isLoaded())
+ if (state().lib().isLoaded())
{
pstring symname = static_compile_name();
#if 0
@@ -161,7 +161,7 @@ void matrix_solver_GCR_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets)
else
this->log().warning("External static solver {1} not found ...", symname);
#else
- m_proc.load(this->netlist().lib(), symname);
+ m_proc.load(this->state().lib(), symname);
if (m_proc.resolved())
this->log().warning("External static solver {1} found ...", symname);
else
diff --git a/src/lib/netlist/solver/nld_ms_sm.h b/src/lib/netlist/solver/nld_ms_sm.h
index 4b0f6940798..81517fcdc1e 100644
--- a/src/lib/netlist/solver/nld_ms_sm.h
+++ b/src/lib/netlist/solver/nld_ms_sm.h
@@ -122,10 +122,10 @@ void matrix_solver_sm_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets)
{
matrix_solver_t::setup_base(nets);
- netlist().save(*this, m_last_RHS, "m_last_RHS");
+ state().save(*this, m_last_RHS, "m_last_RHS");
for (unsigned k = 0; k < N(); k++)
- netlist().save(*this, RHS(k), plib::pfmt("RHS.{1}")(k));
+ state().save(*this, RHS(k), plib::pfmt("RHS.{1}")(k));
}
diff --git a/src/lib/netlist/solver/nld_ms_w.h b/src/lib/netlist/solver/nld_ms_w.h
index ac7ea36a6a7..faaeb50b3d3 100644
--- a/src/lib/netlist/solver/nld_ms_w.h
+++ b/src/lib/netlist/solver/nld_ms_w.h
@@ -133,10 +133,10 @@ void matrix_solver_w_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets)
{
matrix_solver_t::setup_base(nets);
- netlist().save(*this, m_last_RHS, "m_last_RHS");
+ state().save(*this, m_last_RHS, "m_last_RHS");
for (unsigned k = 0; k < N(); k++)
- netlist().save(*this, RHS(k), plib::pfmt("RHS.{1}")(k));
+ state().save(*this, RHS(k), plib::pfmt("RHS.{1}")(k));
}
diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp
index f7a25fa7fcc..c578dedefbf 100644
--- a/src/lib/netlist/solver/nld_solver.cpp
+++ b/src/lib/netlist/solver/nld_solver.cpp
@@ -138,42 +138,42 @@ matrix_solver_t * NETLIB_NAME(solver)::create_solver(std::size_t size, const pst
{
if (m_method() == "SOR_MAT")
{
- return create_it<matrix_solver_SOR_mat_t<m_N, storage_N>>(netlist(), solvername, m_params, size);
+ return create_it<matrix_solver_SOR_mat_t<m_N, storage_N>>(state(), solvername, m_params, size);
//typedef matrix_solver_SOR_mat_t<m_N,storage_N> solver_sor_mat;
- //return plib::make_unique<solver_sor_mat>(netlist(), solvername, &m_params, size);
+ //return plib::make_unique<solver_sor_mat>(state(), solvername, &m_params, size);
}
else if (m_method() == "MAT_CR")
{
if (size > 0) // GCR always outperforms MAT solver
{
- return create_it<matrix_solver_GCR_t<m_N, storage_N>>(netlist(), solvername, m_params, size);
+ return create_it<matrix_solver_GCR_t<m_N, storage_N>>(state(), solvername, m_params, size);
}
else
{
- return create_it<matrix_solver_direct_t<m_N, storage_N>>(netlist(), solvername, m_params, size);
+ return create_it<matrix_solver_direct_t<m_N, storage_N>>(state(), solvername, m_params, size);
}
}
else if (m_method() == "MAT")
{
- return create_it<matrix_solver_direct_t<m_N, storage_N>>(netlist(), solvername, m_params, size);
+ return create_it<matrix_solver_direct_t<m_N, storage_N>>(state(), solvername, m_params, size);
}
else if (m_method() == "SM")
{
/* Sherman-Morrison Formula */
- return create_it<matrix_solver_sm_t<m_N, storage_N>>(netlist(), solvername, m_params, size);
+ return create_it<matrix_solver_sm_t<m_N, storage_N>>(state(), solvername, m_params, size);
}
else if (m_method() == "W")
{
/* Woodbury Formula */
- return create_it<matrix_solver_w_t<m_N, storage_N>>(netlist(), solvername, m_params, size);
+ return create_it<matrix_solver_w_t<m_N, storage_N>>(state(), solvername, m_params, size);
}
else if (m_method() == "SOR")
{
- return create_it<matrix_solver_SOR_t<m_N, storage_N>>(netlist(), solvername, m_params, size);
+ return create_it<matrix_solver_SOR_t<m_N, storage_N>>(state(), solvername, m_params, size);
}
else if (m_method() == "GMRES")
{
- return create_it<matrix_solver_GMRES_t<m_N, storage_N>>(netlist(), solvername, m_params, size);
+ return create_it<matrix_solver_GMRES_t<m_N, storage_N>>(state(), solvername, m_params, size);
}
else
{
@@ -276,10 +276,10 @@ void NETLIB_NAME(solver)::post_start()
net_splitter splitter;
- splitter.run(netlist());
+ splitter.run(state());
// setup the solvers
- log().verbose("Found {1} net groups in {2} nets\n", splitter.groups.size(), netlist().nets().size());
+ log().verbose("Found {1} net groups in {2} nets\n", splitter.groups.size(), state().nets().size());
for (auto & grp : splitter.groups)
{
matrix_solver_t *ms;
@@ -291,13 +291,13 @@ void NETLIB_NAME(solver)::post_start()
#if 1
case 1:
if (use_specific)
- ms = plib::palloc<matrix_solver_direct1_t>(netlist(), sname, &m_params);
+ ms = plib::palloc<matrix_solver_direct1_t>(state(), sname, &m_params);
else
ms = create_solver<1,1>(1, sname);
break;
case 2:
if (use_specific)
- ms = plib::palloc<matrix_solver_direct2_t>(netlist(), sname, &m_params);
+ ms = plib::palloc<matrix_solver_direct2_t>(state(), sname, &m_params);
else
ms = create_solver<2,2>(2, sname);
break;