diff options
author | 2019-01-16 23:51:28 +0100 | |
---|---|---|
committer | 2019-01-18 00:58:45 +0100 | |
commit | a527525e52d086c7550f87c82cba5f8204e4d61a (patch) | |
tree | d274f4047f456429863024ea5e02832f4c6097e2 | |
parent | f2da8af21ab5127421b55636e780c6d6039d748d (diff) |
netlist: More run/setup separation. (nw)
Still some distance ahead in properly separating execution and setup.
-rw-r--r-- | src/devices/machine/netlist.cpp | 40 | ||||
-rw-r--r-- | src/lib/netlist/analog/nlid_twoterm.h | 7 | ||||
-rw-r--r-- | src/lib/netlist/devices/nlid_proxy.cpp | 4 | ||||
-rw-r--r-- | src/lib/netlist/devices/nlid_system.h | 2 | ||||
-rw-r--r-- | src/lib/netlist/nl_base.cpp | 288 | ||||
-rw-r--r-- | src/lib/netlist/nl_base.h | 216 | ||||
-rw-r--r-- | src/lib/netlist/nl_factory.h | 12 | ||||
-rw-r--r-- | src/lib/netlist/nl_lists.h | 6 | ||||
-rw-r--r-- | src/lib/netlist/nl_parser.h | 2 | ||||
-rw-r--r-- | src/lib/netlist/nl_setup.cpp | 138 | ||||
-rw-r--r-- | src/lib/netlist/nl_setup.h | 24 | ||||
-rw-r--r-- | src/lib/netlist/prg/nltool.cpp | 24 | ||||
-rw-r--r-- | src/lib/netlist/solver/nld_matrix_solver.cpp | 12 | ||||
-rw-r--r-- | src/lib/netlist/solver/nld_ms_direct.h | 4 | ||||
-rw-r--r-- | src/lib/netlist/solver/nld_ms_gcr.h | 4 | ||||
-rw-r--r-- | src/lib/netlist/solver/nld_ms_sm.h | 4 | ||||
-rw-r--r-- | src/lib/netlist/solver/nld_ms_w.h | 4 | ||||
-rw-r--r-- | src/lib/netlist/solver/nld_solver.cpp | 26 |
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; |