diff options
Diffstat (limited to 'src/lib/netlist/nl_base.cpp')
-rw-r--r-- | src/lib/netlist/nl_base.cpp | 765 |
1 files changed, 254 insertions, 511 deletions
diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp index 9a513c00804..ad048e899bf 100644 --- a/src/lib/netlist/nl_base.cpp +++ b/src/lib/netlist/nl_base.cpp @@ -8,18 +8,19 @@ #include "solver/nld_matrix_solver.h" #include "solver/nld_solver.h" -#include "plib/putil.h" #include "plib/palloc.h" +#include "plib/pmempool.h" +#include "plib/putil.h" -#include "nl_base.h" -#include "devices/nlid_system.h" #include "devices/nlid_proxy.h" +#include "devices/nlid_system.h" #include "macro/nlm_base.h" +#include "nl_base.h" #include "nl_errstr.h" -#include <cstring> #include <cmath> +#include <cstring> #include <limits> namespace netlist @@ -27,14 +28,13 @@ namespace netlist namespace detail { - static plib::mempool *pool() - { - static plib::mempool *s_pool = nullptr; - if (s_pool == nullptr) - s_pool = new plib::mempool(65536, 16); - return s_pool; - } + //static plib::mempool *pool() + //{ + // static plib::mempool s_pool(655360, 32); + // return &s_pool; + //} +#if 0 void * object_t::operator new (size_t size) { void *ret = nullptr; @@ -44,38 +44,30 @@ namespace detail ret = ::operator new(size); return ret; } - void object_t::operator delete (void * mem) { if (mem) { - if ((USE_MEMPOOL)) - pool()->free(mem); - else + //if ((USE_MEMPOOL)) + // pool()->free(mem); + //else ::operator delete(mem); } } +#endif -} - -nl_exception::~nl_exception() -{ -} +} // namespace detail // ---------------------------------------------------------------------------------------- // logic_family_ttl_t // ---------------------------------------------------------------------------------------- +// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init, modernize-use-equals-default) logic_family_desc_t::logic_family_desc_t() { } -logic_family_desc_t::~logic_family_desc_t() -{ -} - - class logic_family_ttl_t : public logic_family_desc_t { public: @@ -90,17 +82,17 @@ public: m_R_low = 1.0; m_R_high = 130.0; } - virtual plib::owned_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_t &anetlist, const pstring &name, logic_output_t *proxied) const override; - virtual plib::owned_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *proxied) const override; + pool_owned_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const override; + pool_owned_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const override; }; -plib::owned_ptr<devices::nld_base_d_to_a_proxy> logic_family_ttl_t::create_d_a_proxy(netlist_t &anetlist, const pstring &name, logic_output_t *proxied) const +pool_owned_ptr<devices::nld_base_d_to_a_proxy> logic_family_ttl_t::create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const { - return plib::owned_ptr<devices::nld_base_d_to_a_proxy>::Create<devices::nld_d_to_a_proxy>(anetlist, name, proxied); + return pool().make_poolptr<devices::nld_d_to_a_proxy>(anetlist, name, proxied); } -plib::owned_ptr<devices::nld_base_a_to_d_proxy> logic_family_ttl_t::create_a_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *proxied) const +pool_owned_ptr<devices::nld_base_a_to_d_proxy> logic_family_ttl_t::create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const { - return plib::owned_ptr<devices::nld_base_a_to_d_proxy>::Create<devices::nld_a_to_d_proxy>(anetlist, name, proxied); + return pool().make_poolptr<devices::nld_a_to_d_proxy>(anetlist, name, proxied); } class logic_family_cd4xxx_t : public logic_family_desc_t @@ -117,17 +109,18 @@ public: m_R_low = 10.0; m_R_high = 10.0; } - virtual plib::owned_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_t &anetlist, const pstring &name, logic_output_t *proxied) const override; - virtual plib::owned_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *proxied) const override; + pool_owned_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const override; + pool_owned_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const override; }; -plib::owned_ptr<devices::nld_base_d_to_a_proxy> logic_family_cd4xxx_t::create_d_a_proxy(netlist_t &anetlist, const pstring &name, logic_output_t *proxied) const +pool_owned_ptr<devices::nld_base_d_to_a_proxy> logic_family_cd4xxx_t::create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, logic_output_t *proxied) const { - return plib::owned_ptr<devices::nld_base_d_to_a_proxy>::Create<devices::nld_d_to_a_proxy>(anetlist, name, proxied); + return pool().make_poolptr<devices::nld_d_to_a_proxy>(anetlist, name, proxied); } -plib::owned_ptr<devices::nld_base_a_to_d_proxy> logic_family_cd4xxx_t::create_a_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *proxied) const + +pool_owned_ptr<devices::nld_base_a_to_d_proxy> logic_family_cd4xxx_t::create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, logic_input_t *proxied) const { - return plib::owned_ptr<devices::nld_base_a_to_d_proxy>::Create<devices::nld_a_to_d_proxy>(anetlist, name, proxied); + return pool().make_poolptr<devices::nld_a_to_d_proxy>(anetlist, name, proxied); } const logic_family_desc_t *family_TTL() @@ -146,10 +139,10 @@ const logic_family_desc_t *family_CD4XXX() // queue_t // ---------------------------------------------------------------------------------------- -detail::queue_t::queue_t(netlist_t &nl) - : timed_queue<pqentry_t<net_t *, netlist_time>, false>(512) +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() +// , plib::state_manager_t::callback_t() , m_qsize(0) , m_times(512) , m_net_ids(512) @@ -158,52 +151,56 @@ 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()); } -void detail::queue_t::on_pre_save() +void detail::queue_t::on_pre_save(plib::state_manager_t &manager) { - netlist().log().debug("on_pre_save\n"); + plib::unused_var(manager); m_qsize = this->size(); - netlist().log().debug("current time {1} qsize {2}\n", netlist().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); } } -void detail::queue_t::on_post_load() +void detail::queue_t::on_post_load(plib::state_manager_t &manager) { + plib::unused_var(manager); this->clear(); - netlist().log().debug("current time {1} qsize {2}\n", netlist().time().as_double(), m_qsize); for (std::size_t i = 0; i < m_qsize; i++ ) { - detail::net_t *n = netlist().m_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.exec()) { } + +// ---------------------------------------------------------------------------------------- // object_t // ---------------------------------------------------------------------------------------- detail::object_t::object_t(const pstring &aname) - : m_name(plib::make_unique<pstring>(aname)) +// : m_name(aname) { + name_hash().insert({this, aname}); } -detail::object_t::~object_t() +pstring detail::object_t::name() const { -} - -const pstring &detail::object_t::name() const -{ - return *m_name; + return name_hash().find(this)->second; + //return m_name; } // ---------------------------------------------------------------------------------------- @@ -230,7 +227,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 } } @@ -239,159 +236,38 @@ detail::terminal_type detail::core_terminal_t::type() const // netlist_t // ---------------------------------------------------------------------------------------- -netlist_t::netlist_t(const pstring &aname) - : m_time(netlist_time::zero()) - , m_queue(*this) - , m_mainclock(nullptr) +netlist_t::netlist_t(const pstring &aname, plib::unique_ptr<callbacks_t> callbacks) + : m_state(plib::make_unique<netlist_state_t>(aname, *this, std::move(callbacks))) , m_solver(nullptr) - , m_params(nullptr) - , m_name(aname) - , m_log(*this) - , m_lib(nullptr) - , m_state() -{ - state().save_item(this, static_cast<plib::state_manager_t::callback_t &>(m_queue), "m_queue"); - state().save_item(this, m_time, "m_time"); - m_setup = plib::make_unique<setup_t>(*this); - /* FIXME: doesn't really belong here */ - NETLIST_NAME(base)(*m_setup); -} - -netlist_t::~netlist_t() -{ - m_nets.clear(); - m_devices.clear(); -} - -nl_double netlist_t::gmin() const NL_NOEXCEPT -{ - return solver()->gmin(); -} - -void netlist_t::register_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 netlist_t::remove_dev(core_device_t *dev) + , m_time(netlist_time::zero()) + , m_mainclock(nullptr) + , m_queue(*m_state) { - 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() - ); + 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 +// ---------------------------------------------------------------------------------------- - -void netlist_t::start() +netlist_state_t::netlist_state_t(const pstring &aname, + netlist_t & anetlist, + plib::unique_ptr<callbacks_t> &&callbacks) +: m_name(aname) +, m_netlist(anetlist) +, m_state() +, m_callbacks(std::move(callbacks)) // Order is important here +, m_log(*m_callbacks) +, m_setup(plib::make_unique<setup_t>(*this)) { - setup().start_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 mainclock and solver ...\n"); - - m_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)); - } - } - - log().debug("Searching for mainclock\n"); - m_mainclock = get_single_device<devices::NETLIB_NAME(mainclock)>("mainclock"); - - 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: turn this into a proper function - bool error; - auto v = p->second.as_double(&error); - if (error || 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 (m_solver == nullptr) - { - for (auto &p : m_nets) - if (p->is_analog()) - log().fatal(MF_0_NO_SOLVER); - } - else - m_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() { log().debug("Printing statistics ...\n"); @@ -401,7 +277,7 @@ void netlist_t::stop() m_solver->stop(); } -detail::net_t *netlist_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) @@ -410,7 +286,7 @@ detail::net_t *netlist_t::find_net(const pstring &name) const return nullptr; } -std::size_t netlist_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) @@ -420,7 +296,7 @@ std::size_t netlist_t::find_net_id(const detail::net_t *net) const -void netlist_t::rebuild_lists() +void netlist_state_t::rebuild_lists() { for (auto & net : m_nets) net->rebuild_list(); @@ -429,32 +305,44 @@ void netlist_t::rebuild_lists() void netlist_t::reset() { + log().debug("Searching for mainclock\n"); + m_mainclock = m_state->get_single_device<devices::NETLIB_NAME(mainclock)>("mainclock"); + + log().debug("Searching for solver\n"); + m_solver = m_state->get_single_device<devices::NETLIB_NAME(solver)>("solver"); + m_time = netlist_time::zero(); m_queue.clear(); if (m_mainclock != nullptr) - m_mainclock->m_Q.net().set_time(netlist_time::zero()); + m_mainclock->m_Q.net().set_next_scheduled_time(netlist_time::zero()); //if (m_solver != nullptr) - // m_solver->do_reset(); - - std::unordered_map<core_device_t *, bool> m; + // m_solver->reset(); - 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) + log().verbose("Call reset on all nets:"); + for (auto & n : nets()) n->reset(); // Reset all devices once ! + log().verbose("Call reset on all devices:"); for (auto & dev : m_devices) - dev->do_reset(); + dev.second->reset(); // Make sure everything depending on parameters is set + // Currently analog input and logic input also + // push their outputs to queue. + + log().verbose("Call update_param on all devices:"); for (auto & dev : m_devices) - dev->update_param(); + dev.second->update_param(); // Step all devices once ! /* @@ -462,9 +350,9 @@ void netlist_t::reset() * variations are explicitly stated in the breakout manual. */ - const unsigned startup_strategy = 1; //! \note make this a parameter + auto *netlist_params = get_single_device<devices::NETLIB_NAME(netlistparams)>("parameter"); - switch (startup_strategy) + switch (netlist_params->m_startup_strategy()) { case 0: { @@ -472,7 +360,7 @@ void netlist_t::reset() std::vector<nldelegate *> t; log().verbose("Using default startup strategy"); for (auto &n : m_nets) - for (auto & term : n->m_core_terms) + for (auto & term : n->core_terms()) if (term->m_delegate.has_object()) { if (!plib::container::contains(t, &term->m_delegate)) @@ -480,70 +368,68 @@ void netlist_t::reset() t.push_back(&term->m_delegate); term->m_delegate(); } - core_device_t *dev = reinterpret_cast<core_device_t *>(term->m_delegate.object()); + auto *dev = reinterpret_cast<core_device_t *>(term->m_delegate.object()); if (!plib::container::contains(d, dev)) d.push_back(dev); } - log().verbose("Call update on devices which need parameter update:"); - for (auto & dev : m_devices) - if (dev->needs_update_after_param_change()) - { - if (!plib::container::contains(d, dev.get())) - { - d.push_back(dev.get()); - log().verbose("\t ...{1}", dev->name()); - dev->update_dev(); - } - } log().verbose("Devices not yet updated:"); for (auto &dev : m_devices) - if (!plib::container::contains(d, dev.get())) - log().verbose("\t ...{1}", dev->name()); - //x->update_dev(); + if (!plib::container::contains(d, dev.second.get())) + { + log().verbose("\t ...{1}", dev.second->name()); + dev.second->update(); + } } break; case 1: // brute force backward { + log().verbose("Using brute force backward startup strategy"); + + for (auto &n : m_nets) // only used if USE_COPY_INSTEAD_OF_REFERENCE == 1 + n->update_inputs(); + std::size_t i = m_devices.size(); while (i>0) - m_devices[--i]->update_dev(); + m_devices[--i].second->update(); + + for (auto &n : m_nets) // only used if USE_COPY_INSTEAD_OF_REFERENCE == 1 + n->update_inputs(); + } break; case 2: // brute force forward { + log().verbose("Using brute force forward startup strategy"); for (auto &d : m_devices) - d->update_dev(); + d.second->update(); } break; } #if 1 /* the above may screw up m_active and the list */ - for (auto &n : m_nets) - n->rebuild_list(); + rebuild_lists(); #endif } -void netlist_t::process_queue(const netlist_time &delta) NL_NOEXCEPT +void netlist_t::process_queue(const netlist_time delta) NL_NOEXCEPT { + auto sm_guard(m_stat_mainloop.guard()); netlist_time stop(m_time + delta); m_queue.push(detail::queue_t::entry_t(stop, nullptr)); - m_stat_mainloop.start(); if (m_mainclock == nullptr) { - detail::queue_t::entry_t e(m_queue.top()); - m_queue.pop(); + detail::queue_t::entry_t e(m_queue.pop()); m_time = e.m_exec_time; while (e.m_object != nullptr) { e.m_object->update_devs(); m_perf_out_processed.inc(); - e = m_queue.top(); - m_queue.pop(); + e = m_queue.pop(); m_time = e.m_exec_time; } } @@ -551,9 +437,7 @@ void netlist_t::process_queue(const netlist_time &delta) NL_NOEXCEPT { logic_net_t &mc_net(m_mainclock->m_Q.net()); const netlist_time inc(m_mainclock->m_inc); - netlist_time mc_time(mc_net.time()); - - detail::queue_t::entry_t e; + netlist_time mc_time(mc_net.next_scheduled_time()); do { @@ -565,37 +449,37 @@ void netlist_t::process_queue(const netlist_time &delta) NL_NOEXCEPT mc_time += inc; } - e = m_queue.top(); - m_queue.pop(); + detail::queue_t::entry_t e(m_queue.pop()); m_time = e.m_exec_time; if (e.m_object != nullptr) { e.m_object->update_devs(); m_perf_out_processed.inc(); } - } while (e.m_object != nullptr); - mc_net.set_time(mc_time); + else + break; + } while (true); //while (e.m_object != nullptr); + mc_net.set_next_scheduled_time(mc_time); } - m_stat_mainloop.stop(); } void netlist_t::print_stats() const { - if (nperftime_t::enabled) + 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].second->m_stat_total_time.total() < m_state->m_devices[i2].second->m_stat_total_time.total(); }); - nperftime_t::type total_time(0); - uint_least64_t total_count(0); + nperftime_t<NL_KEEP_STATISTICS>::type total_time(0); + nperftime_t<NL_KEEP_STATISTICS>::ctype total_count(0); for (auto & j : index) { - auto entry = m_devices[j].get(); + auto entry = m_state->m_devices[j].second.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()); @@ -603,22 +487,27 @@ void netlist_t::print_stats() const total_count += entry->m_stat_total_time.count(); } - nperftime_t overhead; - nperftime_t test; - overhead.start(); - for (int j=0; j<100000;j++) + log().verbose("Total calls : {1:12} {2:12} {3:12}", total_count, + total_time, total_time / static_cast<decltype(total_time)>(total_count)); + + nperftime_t<NL_KEEP_STATISTICS> overhead; + nperftime_t<NL_KEEP_STATISTICS> test; { - test.start(); - test.stop(); + auto overhead_guard(overhead.guard()); + for (int j=0; j<100000;j++) + { + auto test_guard(test.guard()); + } } - overhead.stop(); - nperftime_t::type total_overhead = overhead() - * static_cast<nperftime_t::type>(total_count) - / static_cast<nperftime_t::type>(200000); + nperftime_t<NL_KEEP_STATISTICS>::type total_overhead = overhead() + * static_cast<nperftime_t<NL_KEEP_STATISTICS>::type>(total_count) + / static_cast<nperftime_t<NL_KEEP_STATISTICS>::type>(200000); - log().verbose("Queue Pushes {1:15}", queue().m_prof_call()); - log().verbose("Queue Moves {1:15}", queue().m_prof_sortmove()); + log().verbose("Queue Pushes {1:15}", m_queue.m_prof_call()); + log().verbose("Queue Moves {1:15}", m_queue.m_prof_sortmove()); + log().verbose("Queue Removes {1:15}", m_queue.m_prof_remove()); + log().verbose("Queue Retimes {1:15}", m_queue.m_prof_retime()); log().verbose("Total loop {1:15}", m_stat_mainloop()); /* Only one serialization should be counted in total time */ @@ -627,29 +516,36 @@ void netlist_t::print_stats() const log().verbose(""); log().verbose("Take the next lines with a grain of salt. They depend on the measurement implementation."); log().verbose("Total overhead {1:15}", total_overhead); - nperftime_t::type overhead_per_pop = (m_stat_mainloop()-2*total_overhead - (total_time - total_overhead)) - / static_cast<nperftime_t::type>(queue().m_prof_call()); + nperftime_t<NL_KEEP_STATISTICS>::type overhead_per_pop = (m_stat_mainloop()-2*total_overhead - (total_time - total_overhead)) + / 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) + + auto trigger = total_count * 200 / 1000000; // 200 ppm + 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()); + auto ep = entry.second.get(); + // Factor of 3 offers best performace increase + if (ep->m_stat_inc_active() > 3 * ep->m_stat_total_time.count() + && ep->m_stat_inc_active() > trigger) + log().verbose("HINT({}, NO_DEACTIVATE) // {} {} {}", ep->name(), + static_cast<double>(ep->m_stat_inc_active()) / static_cast<double>(ep->m_stat_total_time.count()), + ep->m_stat_inc_active(), ep->m_stat_total_time.count()); } } } -core_device_t *netlist_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) { - if (cc(d.get())) + if (cc(d.second.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(); + ret = d.second.get(); } } return ret; @@ -660,11 +556,12 @@ core_device_t *netlist_t::get_single_device(const pstring &classname, bool (*cc) // core_device_t // ---------------------------------------------------------------------------------------- -core_device_t::core_device_t(netlist_t &owner, const pstring &name) +core_device_t::core_device_t(netlist_state_t &owner, const pstring &name) : object_t(name) , logic_family_t() , netlist_ref(owner) , m_hint_deactivate(false) + , m_active_outputs(*this, "m_active_outputs", 1) { if (logic_family() == nullptr) set_logic_family(family_TTL()); @@ -673,17 +570,14 @@ core_device_t::core_device_t(netlist_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) + , m_active_outputs(*this, "m_active_outputs", 1) { 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)); -} - -core_device_t::~core_device_t() -{ + state().add_dev(this->name(), pool_owned_ptr<core_device_t>(this, false)); } void core_device_t::set_default_delegate(detail::core_terminal_t &term) @@ -692,16 +586,16 @@ void core_device_t::set_default_delegate(detail::core_terminal_t &term) term.m_delegate.set(&core_device_t::update, this); } -plib::plog_base<netlist_t, NL_DEBUG> &core_device_t::log() +log_type & core_device_t::log() { - return netlist().log(); + return state().log(); } // ---------------------------------------------------------------------------------------- // device_t // ---------------------------------------------------------------------------------------- -device_t::device_t(netlist_t &owner, const pstring &name) +device_t::device_t(netlist_state_t &owner, const pstring &name) : core_device_t(owner, name) { } @@ -711,14 +605,14 @@ device_t::device_t(core_device_t &owner, const pstring &name) { } -device_t::~device_t() +setup_t &device_t::setup() { - //log().debug("~net_device_t\n"); + return state().setup(); } -setup_t &device_t::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) @@ -762,9 +656,14 @@ void device_t::connect_post_start(detail::core_terminal_t &t1, detail::core_term // family_setter_t // ----------------------------------------------------------------------------- +// NOLINTNEXTLINE(modernize-use-equals-default) +detail::family_setter_t::family_setter_t() +{ +} + 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) @@ -776,81 +675,45 @@ detail::family_setter_t::family_setter_t(core_device_t &dev, const logic_family_ // net_t // ---------------------------------------------------------------------------------------- -detail::net_t::net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr) +detail::net_t::net_t(netlist_state_t &nl, const pstring &aname, core_terminal_t *mr) : object_t(aname) , netlist_ref(nl) , m_new_Q(*this, "m_new_Q", 0) , m_cur_Q (*this, "m_cur_Q", 0) - , m_in_queue(*this, "m_in_queue", QS_DELIVERED) - , m_active(*this, "m_active", 0) - , m_time(*this, "m_time", netlist_time::zero()) + , m_in_queue(*this, "m_in_queue", queue_status::DELIVERED) + , m_next_scheduled_time(*this, "m_time", netlist_time::zero()) , m_railterminal(mr) { } -detail::net_t::~net_t() -{ - netlist().state().remove_save_items(this); -} - -void detail::net_t::inc_active(core_terminal_t &term) NL_NOEXCEPT -{ - m_list_active.push_front(&term); - ++m_active; - nl_assert(m_active <= static_cast<int>(num_cons())); - if (m_active == 1) - { - railterminal().device().do_inc_active(); - if (m_in_queue == QS_DELAYED_DUE_TO_INACTIVE) - { - if (m_time > netlist().time()) - { - m_in_queue = QS_QUEUED; /* pending */ - netlist().queue().push({m_time, this}); - } - else - { - m_in_queue = QS_DELIVERED; - m_cur_Q = m_new_Q; - } - } - } -} - -void detail::net_t::dec_active(core_terminal_t &term) NL_NOEXCEPT -{ - --m_active; - nl_assert(m_active >= 0); - m_list_active.remove(&term); - if (m_active == 0) - railterminal().device().do_dec_active(); -} - void detail::net_t::rebuild_list() { /* rebuild m_list */ - int cnt = 0; 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); - cnt++; + term->set_copied_input(m_cur_Q); } - m_active = cnt; } - -void detail::net_t::process(unsigned Mask) +template <typename T> +void detail::net_t::process(const T mask, netlist_sig_t sig) { + m_cur_Q = sig; + for (auto & p : m_list_active) { + p.set_copied_input(sig); + p.device().m_stat_call_count.inc(); - if ((p.state() & Mask) != 0) + if ((p.terminal_state() & mask)) { - p.device().m_stat_total_time.start(); + auto g(p.device().m_stat_total_time.guard()); + //p.device().m_stat_total_time.start(); p.m_delegate(); - p.device().m_stat_total_time.stop(); + //p.device().m_stat_total_time.stop(); } } } @@ -859,67 +722,59 @@ void detail::net_t::update_devs() NL_NOEXCEPT { nl_assert(this->isRailNet()); - const unsigned mask((m_new_Q << core_terminal_t::INP_LH_SHIFT) - | (m_cur_Q<<core_terminal_t::INP_HL_SHIFT)); + const auto new_Q(m_new_Q); - m_in_queue = QS_DELIVERED; /* mark as taken ... */ + const auto mask((new_Q << core_terminal_t::INP_LH_SHIFT) + | (m_cur_Q << core_terminal_t::INP_HL_SHIFT)); + m_in_queue = queue_status::DELIVERED; /* mark as taken ... */ switch (mask) { case core_terminal_t::STATE_INP_HL: - m_cur_Q = m_new_Q; - process(core_terminal_t::STATE_INP_HL | core_terminal_t::STATE_INP_ACTIVE); - break; case core_terminal_t::STATE_INP_LH: - m_cur_Q = m_new_Q; - process(core_terminal_t::STATE_INP_LH | core_terminal_t::STATE_INP_ACTIVE); + process(mask | core_terminal_t::STATE_INP_ACTIVE, new_Q); break; default: + /* do nothing */ break; } } void detail::net_t::reset() { - m_time = netlist_time::zero(); - m_active = 0; - m_in_queue = QS_DELIVERED; + m_next_scheduled_time = netlist_time::zero(); + m_in_queue = queue_status::DELIVERED; m_new_Q = 0; m_cur_Q = 0; - analog_net_t *p = dynamic_cast<analog_net_t *>(this); + auto *p = dynamic_cast<analog_net_t *>(this); if (p != nullptr) p->m_cur_Analog = 0.0; - /* rebuild m_list */ + /* rebuild m_list and reset terminals to active or analog out state */ m_list_active.clear(); for (core_terminal_t *ct : m_core_terms) - m_list_active.push_back(ct); - - for (core_terminal_t *ct : m_core_terms) + { ct->reset(); - - for (core_terminal_t *ct : m_core_terms) - if (ct->state() != logic_t::STATE_INP_PASSIVE) - m_active++; + if (ct->terminal_state() != logic_t::STATE_INP_PASSIVE) + m_list_active.push_back(ct); + ct->set_copied_input(m_cur_Q); + } } 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); m_core_terms.push_back(&terminal); - - if (terminal.state() != logic_t::STATE_INP_PASSIVE) - m_active++; } void detail::net_t::remove_terminal(detail::core_terminal_t &terminal) @@ -930,10 +785,8 @@ 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()); - if (terminal.state() != logic_t::STATE_INP_PASSIVE) - m_active--; } void detail::net_t::move_connections(detail::net_t &dest_net) @@ -941,37 +794,28 @@ void detail::net_t::move_connections(detail::net_t &dest_net) for (auto &ct : m_core_terms) dest_net.add_terminal(*ct); m_core_terms.clear(); - m_active = 0; } // ---------------------------------------------------------------------------------------- // logic_net_t // ---------------------------------------------------------------------------------------- -logic_net_t::logic_net_t(netlist_t &nl, const pstring &aname, detail::core_terminal_t *mr) +logic_net_t::logic_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *mr) : net_t(nl, aname, mr) { } -logic_net_t::~logic_net_t() -{ -} - // ---------------------------------------------------------------------------------------- // analog_net_t // ---------------------------------------------------------------------------------------- -analog_net_t::analog_net_t(netlist_t &nl, const pstring &aname, detail::core_terminal_t *mr) +analog_net_t::analog_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *mr) : net_t(nl, aname, mr) , m_cur_Analog(*this, "m_cur_Analog", 0.0) , m_solver(nullptr) { } -analog_net_t::~analog_net_t() -{ -} - // ---------------------------------------------------------------------------------------- // core_terminal_t // ---------------------------------------------------------------------------------------- @@ -981,42 +825,19 @@ detail::core_terminal_t::core_terminal_t(core_device_t &dev, const pstring &anam : device_object_t(dev, dev.name() + "." + aname) , plib::linkedlist_t<core_terminal_t>::element_t() , m_delegate(delegate) +#if USE_COPY_INSTEAD_OF_REFERENCE +, m_Q(*this, "m_Q", 0) +#endif , m_net(nullptr) , m_state(*this, "m_state", state) { } -detail::core_terminal_t::~core_terminal_t() -{ -} - -void detail::core_terminal_t::reset() -{ - if (is_type(OUTPUT)) - set_state(STATE_OUT); - else - set_state(STATE_INP_ACTIVE); -} - -void detail::core_terminal_t::set_net(net_t *anet) -{ - m_net = anet; -} - -void detail::core_terminal_t::clear_net() -{ - m_net = nullptr; -} - analog_t::analog_t(core_device_t &dev, const pstring &aname, const state_e state) : core_terminal_t(dev, aname, state) { } -analog_t::~analog_t() -{ -} - logic_t::logic_t(core_device_t &dev, const pstring &aname, const state_e state, nldelegate delegate) : core_terminal_t(dev, aname, state, delegate) @@ -1025,26 +846,18 @@ logic_t::logic_t(core_device_t &dev, const pstring &aname, const state_e state, { } -logic_t::~logic_t() -{ -} - // ---------------------------------------------------------------------------------------- // terminal_t // ---------------------------------------------------------------------------------------- -terminal_t::terminal_t(core_device_t &dev, const pstring &aname) +terminal_t::terminal_t(core_device_t &dev, const pstring &aname, terminal_t *otherterm) : analog_t(dev, aname, STATE_BIDIR) -, m_otherterm(nullptr) , m_Idr1(nullptr) , m_go1(nullptr) , m_gt1(nullptr) +, m_connected_terminal(otherterm) { - netlist().setup().register_term(*this); -} - -terminal_t::~terminal_t() -{ + state().setup().register_term(*this); } void terminal_t::solve_now() @@ -1055,7 +868,7 @@ void terminal_t::solve_now() net().solver()->update_forced(); } -void terminal_t::schedule_solve_after(const netlist_time &after) +void terminal_t::schedule_solve_after(const netlist_time after) { // Nets may belong to railnets which do not have a solver attached if (this->has_net()) @@ -1077,16 +890,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().m_nets.push_back(plib::owned_ptr<logic_net_t>(&m_my_net, false)); + state().register_net(pool_owned_ptr<logic_net_t>(&m_my_net, false)); set_logic_family(dev.logic_family()); - netlist().setup().register_term(*this); -} - -logic_output_t::~logic_output_t() -{ + state().setup().register_term(*this); } void logic_output_t::initial(const netlist_sig_t val) @@ -1102,11 +911,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); -} - -analog_input_t::~analog_input_t() -{ + state().setup().register_term(*this); } // ---------------------------------------------------------------------------------------- @@ -1115,17 +920,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().m_nets.push_back(plib::owned_ptr<analog_net_t>(&m_my_net, false)); + state().register_net(pool_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); -} - -analog_output_t::~analog_output_t() -{ + state().setup().register_term(*this); } void analog_output_t::initial(const nl_double val) @@ -1142,11 +943,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); -} - -logic_input_t::~logic_input_t() -{ + state().setup().register_term(*this); } // ---------------------------------------------------------------------------------------- @@ -1156,11 +953,7 @@ logic_input_t::~logic_input_t() param_t::param_t(device_t &device, const pstring &name) : device_object_t(device, device.name() + "." + name) { - device.setup().register_param(this->name(), *this); -} - -param_t::~param_t() -{ + device.setup().register_param_t(this->name(), *this); } param_t::param_type_t param_t::param_type() const @@ -1177,7 +970,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 */ } } @@ -1186,50 +979,28 @@ param_t::param_type_t param_t::param_type() const void param_t::update_param() { device().update_param(); - if (device().needs_update_after_param_change()) - device().update_dev(); } -const pstring param_model_t::model_type() +pstring param_t::get_initial(const device_t &dev, bool *found) { - if (m_map.size() == 0) - netlist().setup().model_parse(this->Value(), m_map); - return m_map["COREMODEL"]; + pstring res = dev.setup().get_initial_param_val(this->name(), ""); + *found = (res != ""); + return res; } -param_str_t::param_str_t(device_t &device, const pstring &name, const pstring &val) -: param_t(device, name) -{ - m_param = device.setup().get_initial_param_val(this->name(),val); -} - -param_str_t::~param_str_t() -{ -} - -void param_str_t::changed() -{ -} - -param_double_t::param_double_t(device_t &device, const pstring &name, const double val) -: param_t(device, name) +const pstring param_model_t::model_type() { - m_param = device.setup().get_initial_param_val(this->name(),val); - netlist().save(*this, m_param, "m_param"); + return state().setup().models().model_type(value()); } -param_int_t::param_int_t(device_t &device, const pstring &name, const int val) +param_str_t::param_str_t(device_t &device, const pstring &name, const pstring &val) : param_t(device, name) { m_param = device.setup().get_initial_param_val(this->name(),val); - netlist().save(*this, m_param, "m_param"); } -param_logic_t::param_logic_t(device_t &device, const pstring &name, const bool val) -: param_t(device, name) +void param_str_t::changed() { - m_param = device.setup().get_initial_param_val(this->name(),val); - netlist().save(*this, m_param, "m_param"); } param_ptr_t::param_ptr_t(device_t &device, const pstring &name, uint8_t * val) @@ -1241,53 +1012,25 @@ 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()); - m_map.clear(); + state().log().fatal(MF_1_MODEL_1_CAN_NOT_BE_CHANGED_AT_RUNTIME, name()); } 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); + return state().setup().models().model_value_str(value(), 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); + return state().setup().models().model_value(value(), entity); } -param_data_t::param_data_t(device_t &device, const pstring &name) -: param_str_t(device, name, "") -{ -} - -void param_data_t::changed() -{ -} -std::unique_ptr<plib::pistream> param_data_t::stream() +plib::unique_ptr<plib::pistream> param_data_t::stream() { - return device().netlist().setup().get_data_stream(Value()); + return device().setup().get_data_stream(value()); } - namespace devices - { - // ---------------------------------------------------------------------------------------- - // mainclock - // ---------------------------------------------------------------------------------------- - - void NETLIB_NAME(mainclock)::mc_update(logic_net_t &net) - { - net.toggle_new_Q(); - net.update_devs(); - } - - - } //namespace devices - bool detail::core_terminal_t::is_logic() const NL_NOEXCEPT { return dynamic_cast<const logic_t *>(this) != nullptr; |