diff options
Diffstat (limited to 'src/lib/netlist/nl_base.cpp')
-rw-r--r-- | src/lib/netlist/nl_base.cpp | 938 |
1 files changed, 512 insertions, 426 deletions
diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp index e67ec98a1f8..ddb4f1bca6a 100644 --- a/src/lib/netlist/nl_base.cpp +++ b/src/lib/netlist/nl_base.cpp @@ -1,6 +1,14 @@ // license:BSD-3-Clause // copyright-holders:Couriersud +#include "nl_errstr.h" + +#include "core/devices.h" +#include "core/logic.h" +#include "core/setup.h" + +#include "devices/nlid_proxy.h" + #include "solver/nld_matrix_solver.h" #include "solver/nld_solver.h" @@ -10,12 +18,6 @@ #include "plib/pmempool.h" #include "plib/putil.h" -#include "core/setup.h" -#include "devices/nlid_proxy.h" -#include "nl_base.h" - -#include "nl_errstr.h" - #include <limits> NETLIST_EXTERNAL(base_lib) @@ -23,38 +25,35 @@ NETLIST_EXTERNAL(base_lib) namespace netlist { - // ---------------------------------------------------------------------------------------- - // callbacks_t - // ---------------------------------------------------------------------------------------- - - // ---------------------------------------------------------------------------------------- - // queue_t - // ---------------------------------------------------------------------------------------- - - // ---------------------------------------------------------------------------------------- - // device_object_t - // ---------------------------------------------------------------------------------------- - - detail::device_object_t::device_object_t(core_device_t *dev, const pstring &aname) - : object_t(aname) - , m_device(dev) - { - } + // ------------------------------------------------------------------------- + // detail::core_terminal_t + // ------------------------------------------------------------------------- detail::terminal_type detail::core_terminal_t::type() const noexcept(false) { - if (dynamic_cast<const terminal_t *>(this) != nullptr) + if (plib::dynamic_downcast<const terminal_t *>(this)) return terminal_type::TERMINAL; - if (dynamic_cast<const logic_input_t *>(this) != nullptr - || dynamic_cast<const analog_input_t *>(this) != nullptr) + if (plib::dynamic_downcast<const logic_input_t *>(this) + || plib::dynamic_downcast<const analog_input_t *>(this)) return terminal_type::INPUT; - if (dynamic_cast<const logic_output_t *>(this) != nullptr - || dynamic_cast<const analog_output_t *>(this) != nullptr) + if (plib::dynamic_downcast<const logic_output_t *>(this) + || plib::dynamic_downcast<const analog_output_t *>(this)) return terminal_type::OUTPUT; state().log().fatal(MF_UNKNOWN_TYPE_FOR_OBJECT(name())); throw nl_exception(MF_UNKNOWN_TYPE_FOR_OBJECT(name())); - //return terminal_type::TERMINAL; // please compiler + // return terminal_type::TERMINAL; // please compiler + } + + // ------------------------------------------------------------------------- + // detail::device_object_t + // ------------------------------------------------------------------------- + + detail::device_object_t::device_object_t(core_device_t *dev, + const pstring &aname) + : object_t(aname) + , m_device(dev) + { } netlist_state_t &detail::device_object_t::state() noexcept @@ -67,44 +66,92 @@ namespace netlist return m_device->state(); } - // ---------------------------------------------------------------------------------------- - // netlist_object_t - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- + // detail::netlist_object_t + // ------------------------------------------------------------------------- - netlist_state_t & detail::netlist_object_t::state() noexcept + netlist_state_t &detail::netlist_object_t::state() noexcept { - return m_netlist.nlstate(); + return m_netlist.nl_state(); } - const netlist_state_t & detail::netlist_object_t::state() const noexcept + const netlist_state_t &detail::netlist_object_t::state() const noexcept { - return m_netlist.nlstate(); + return m_netlist.nl_state(); } - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- // netlist_t - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- netlist_t::netlist_t(netlist_state_t &state, const pstring &aname) : m_state(state) , m_solver(nullptr) , m_time(netlist_time_ext::zero()) - , m_mainclock(nullptr) + , m_main_clock(nullptr) , m_use_stats(false) - , m_queue(config::MAX_QUEUE_SIZE::value, - detail::queue_t::id_delegate(&netlist_state_t :: find_net_id, &state), - detail::queue_t::obj_delegate(&netlist_state_t :: net_by_id, &state)) - { - state.save(*this, static_cast<plib::state_manager_t::callback_t &>(m_queue), aname, "m_queue"); + , m_queue( + state.pool(), config::max_queue_size::value, + detail::queue_t::id_delegate(&netlist_state_t ::find_net_id, &state), + detail::queue_t::obj_delegate(&netlist_state_t ::net_by_id, &state)) + { + state.save(*this, + static_cast<plib::state_manager_t::callback_t &>(m_queue), + aname, "m_queue"); state.save(*this, m_time, aname, "m_time"); } - // ---------------------------------------------------------------------------------------- - // netlist_t - // ---------------------------------------------------------------------------------------- + void netlist_t::reset() + { + log().debug("Searching for main clock\n"); + m_main_clock = 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"); + + // Don't reset time + // m_time = netlist_time_ext::zero(); + m_queue.clear(); + if (m_main_clock != nullptr) + m_main_clock->m_Q.net().set_next_scheduled_time(m_time); + // if (m_solver != nullptr) + // m_solver->reset(); - netlist_state_t::netlist_state_t(const pstring &name, - plib::plog_delegate logger) + m_state.reset(); + } + + void netlist_t::stop() + { + log().debug("Printing statistics ...\n"); + print_stats(); + log().debug("Stopping solver device ...\n"); + if (m_solver != nullptr) + m_solver->stop(); + } + + void netlist_t::print_stats() const + { + if (m_use_stats) + { + netlist_state_t::stats_info si{m_queue, m_stat_mainloop, + m_perf_out_processed}; + m_state.print_stats(si); + } + log().verbose("Current pool memory allocated: {1:12} kB", + nl_state().pool().cur_alloc() >> 10); + log().verbose("Maximum pool memory allocated: {1:12} kB", + nl_state().pool().max_alloc() >> 10); + } + + // ------------------------------------------------------------------------- + // netlist_state_t + // ------------------------------------------------------------------------- + + netlist_state_t::netlist_state_t(const pstring & name, + plib::plog_delegate logger) : m_log(logger) , m_dummy_version(1) { @@ -120,84 +167,101 @@ namespace netlist devices::initialize_factory(m_setup->parser().factory()); // Add default include file - const pstring content = - "#define RES_R(res) (res) \n" - "#define RES_K(res) ((res) * 1e3) \n" - "#define RES_M(res) ((res) * 1e6) \n" - "#define CAP_U(cap) ((cap) * 1e-6) \n" - "#define CAP_N(cap) ((cap) * 1e-9) \n" - "#define CAP_P(cap) ((cap) * 1e-12) \n" - "#define IND_U(ind) ((ind) * 1e-6) \n" - "#define IND_N(ind) ((ind) * 1e-9) \n" - "#define IND_P(ind) ((ind) * 1e-12) \n"; - m_setup->parser().add_include<plib::psource_str_t>("netlist/devices/net_lib.h", content); + const pstring content + = "#define RES_R(res) (res) \n" + "#define RES_K(res) ((res) * 1e3) \n" + "#define RES_M(res) ((res) * 1e6) \n" + "#define CAP_U(cap) ((cap) * 1e-6) \n" + "#define CAP_N(cap) ((cap) * 1e-9) \n" + "#define CAP_P(cap) ((cap) * 1e-12) \n" + "#define IND_U(ind) ((ind) * 1e-6) \n" + "#define IND_N(ind) ((ind) * 1e-9) \n" + "#define IND_P(ind) ((ind) * 1e-12) \n"; + m_setup->parser().add_include<plib::psource_str_t>( + "netlist/devices/net_lib.h", content); // This is for core macro libraries - m_setup->parser().add_include<plib::psource_str_t>("devices/net_lib.h", content); + m_setup->parser().add_include<plib::psource_str_t>("devices/net_lib.h", + content); #if 1 NETLIST_NAME(base_lib)(m_setup->parser()); - //m_setup->parser().register_source<source_pattern_t>("../macro/modules/nlmod_{1}.cpp"); - //m_setup->parser().register_source<source_pattern_t>("../macro/nlm_{1}.cpp"); + //#m_setup->parser().register_source<source_pattern_t>("../macro/modules/nlmod_{1}.cpp"); + //#m_setup->parser().register_source<source_pattern_t>("../macro/nlm_{1}.cpp"); #else -#if 1 - m_setup->parser().register_source<source_pattern_t>("src/lib/netlist/macro/nlm_{1}.cpp", true); - m_setup->parser().register_source<source_pattern_t>("src/lib/netlist/generated/nlm_{1}.cpp", true); - m_setup->parser().register_source<source_pattern_t>("src/lib/netlist/macro/modules/nlmod_{1}.cpp", true); + #if 1 + pstring dir = "src/lib/netlist/"; + m_setup->parser().register_source<source_pattern_t>( + dir + "/macro/nlm_{1}.cpp", true); + m_setup->parser().register_source<source_pattern_t>( + dir + "/generated/nlm_{1}.cpp", true); + m_setup->parser().register_source<source_pattern_t>( + dir + "/macro/modules/nlmod_{1}.cpp", true); m_setup->parser().include("base_lib"); -#else + #else // FIXME: This is very slow - need optimized parsing scanning pstring dir = "src/lib/netlist/macro/"; - //m_setup->parser().register_source<source_pattern_t>("src/lib/netlist/macro/nlm_{}.cpp"); - m_setup->parser().register_source<source_file_t>(dir + "nlm_base_lib.cpp"); - m_setup->parser().register_source<source_file_t>(dir + "nlm_opamp_lib.cpp"); - m_setup->parser().register_source<source_file_t>(dir + "nlm_roms_lib.cpp"); - m_setup->parser().register_source<source_file_t>(dir + "nlm_cd4xxx_lib.cpp"); - m_setup->parser().register_source<source_file_t>(dir + "nlm_otheric_lib.cpp"); - m_setup->parser().register_source<source_file_t>(dir + "nlm_ttl74xx_lib.cpp"); + // m_setup->parser().register_source<source_pattern_t>("src/lib/netlist/macro/nlm_{}.cpp"); + m_setup->parser().register_source<source_file_t>(dir + + "nlm_base_lib.cpp"); + m_setup->parser().register_source<source_file_t>(dir + + "nlm_opamp_lib.cpp"); + m_setup->parser().register_source<source_file_t>(dir + + "nlm_roms_lib.cpp"); + m_setup->parser().register_source<source_file_t>( + dir + "nlm_cd4xxx_lib.cpp"); + m_setup->parser().register_source<source_file_t>( + dir + "nlm_otheric_lib.cpp"); + m_setup->parser().register_source<source_file_t>( + dir + "nlm_ttl74xx_lib.cpp"); m_setup->parser().include("base_lib"); -#endif + #endif #endif } - void netlist_state_t::set_static_solver_lib(std::unique_ptr<plib::dynlib_base> &&lib) + void netlist_state_t::set_static_solver_lib( + std::unique_ptr<plib::dynamic_library_base> &&lib) { m_lib = std::move(lib); } - - void netlist_t::stop() - { - log().debug("Printing statistics ...\n"); - print_stats(); - log().debug("Stopping solver device ...\n"); - if (m_solver != nullptr) - m_solver->stop(); - } - std::size_t netlist_state_t::find_net_id(const detail::net_t *net) const { + // special case for queue end processing items + if (net == nullptr) + return std::numeric_limits<std::size_t>::max() - 1; + for (std::size_t i = 0; i < m_nets.size(); i++) if (m_nets[i].get() == net) return i; + return std::numeric_limits<std::size_t>::max(); } + detail::net_t *netlist_state_t::net_by_id(std::size_t id) const { + // special case for queue end processing items + if (id == std::numeric_limits<std::size_t>::max() - 1) + return nullptr; + return m_nets[id].get(); } void netlist_state_t::rebuild_lists() { - for (auto & net : m_nets) + for (auto &net : m_nets) net->rebuild_list(); } - void netlist_state_t::compile_defines(std::vector<std::pair<pstring, pstring>> &defs) + void netlist_state_t::compile_defines( + std::vector<std::pair<pstring, pstring>> &defs) { - #define ENTRY(x) if (pstring(#x) != PSTRINGIFY(x)) \ - defs.emplace_back(std::pair<pstring, pstring>(#x, PSTRINGIFY(x))); \ - else defs.emplace_back(std::pair<pstring, pstring>(#x, "<NOT DEFINED>")); - #define ENTRY_EX(x) defs.emplace_back(std::pair<pstring, pstring>(#x, plib::pfmt("{}")(x))); +#define ENTRY(x) \ + if (pstring(#x) != PSTRINGIFY(x)) \ + defs.emplace_back(std::pair<pstring, pstring>(#x, PSTRINGIFY(x))); \ + else \ + defs.emplace_back(std::pair<pstring, pstring>(#x, "<NOT DEFINED>")); +#define ENTRY_EX(x) \ + defs.emplace_back(std::pair<pstring, pstring>(#x, plib::pfmt("{}")(x))); ENTRY(NL_VERSION_MAJOR) ENTRY(NL_VERSION_MINOR) ENTRY(NL_VERSION_PATCHLEVEL) @@ -208,16 +272,14 @@ namespace netlist ENTRY(PHAS_OPENMP) ENTRY(PUSE_OPENMP) ENTRY(PUSE_FLOAT128) - ENTRY(PPMF_TYPE) - ENTRY(PHAS_PMF_INTERNAL) - ENTRY(NL_USE_MEMPOOL) - ENTRY(NL_USE_QUEUE_STATS) + ENTRY_EX(config::use_mempool::value) + ENTRY_EX(config::use_queue_stats::value) ENTRY(NL_USE_COPY_INSTEAD_OF_REFERENCE) ENTRY(NL_USE_FLOAT128) - ENTRY(NL_USE_FLOAT_MATRIX) - ENTRY(NL_USE_LONG_DOUBLE_MATRIX) + ENTRY_EX(config::use_float_matrix::value) + ENTRY_EX(config::use_long_double_matrix::value) ENTRY(NL_DEBUG) - ENTRY(NVCCBUILD) + ENTRY(__NVCC__) ENTRY(__cplusplus) ENTRY(__VERSION__) @@ -232,10 +294,10 @@ namespace netlist ENTRY(__clang_patchlevel__) ENTRY(__clang_version__) - ENTRY(OPENMP ) - ENTRY(_OPENMP ) + ENTRY(OPENMP) + ENTRY(_OPENMP) - ENTRY(__x86_64__ ) + ENTRY(__x86_64__) ENTRY(__i386__) ENTRY(_WIN32) ENTRY(_MSC_VER) @@ -256,12 +318,12 @@ namespace netlist ENTRY_EX(sizeof(std::vector<detail::core_terminal_t *>)) ENTRY_EX(sizeof(plib::plog_level)) - ENTRY_EX(sizeof(nldelegate)) - ENTRY(PPMF_TYPE) + ENTRY_EX(sizeof(nl_delegate)) + ENTRY(PPMF_FORCE_TYPE) ENTRY(PHAS_PMF_INTERNAL) - #undef ENTRY - #undef ENTRY_EX +#undef ENTRY +#undef ENTRY_EX } pstring netlist_state_t::version() @@ -271,43 +333,22 @@ namespace netlist pstring netlist_state_t::version_patchlevel() { - return plib::pfmt("{1}.{2}.{3}")(NL_VERSION_MAJOR, NL_VERSION_MINOR, NL_VERSION_PATCHLEVEL); + return plib::pfmt("{1}.{2}.{3}")(NL_VERSION_MAJOR, NL_VERSION_MINOR, + NL_VERSION_PATCHLEVEL); } - 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"); - - // Don't reset time - //m_time = netlist_time_ext::zero(); - m_queue.clear(); - if (m_mainclock != nullptr) - m_mainclock->m_Q.net().set_next_scheduled_time(m_time); - //if (m_solver != nullptr) - // m_solver->reset(); - - m_state.reset(); - } - - void netlist_state_t::free_setup_resources() - { - m_setup = nullptr; - } + void netlist_state_t::free_setup_resources() { m_setup = nullptr; } void netlist_state_t::reset() { // Reset all nets once ! log().verbose("Call reset on all nets:"); - for (auto & n : nets()) + for (auto &n : nets()) n->reset(); // Reset all devices once ! log().verbose("Call reset on all devices:"); - for (auto & dev : m_devices) + for (auto &dev : m_devices) dev.second->reset(); // Make sure everything depending on parameters is set @@ -316,7 +357,7 @@ namespace netlist std::vector<core_device_t *> devices_called; log().verbose("Call update_param on all devices:"); - for (auto & dev : m_devices) + for (auto &dev : m_devices) { dev.second->update_param(); if (!plib::container::contains(devices_called, dev.second.get())) @@ -328,18 +369,20 @@ namespace netlist // INFO: The order here affects power up of e.g. breakout. However, such // variations are explicitly stated in the breakout manual. - auto *netlist_params = get_single_device<devices::NETLIB_NAME(netlistparams)>("parameter"); + auto *netlist_params = get_single_device< + devices::NETLIB_NAME(netlistparams)>("parameter"); switch (netlist_params->m_startup_strategy()) { case 0: { - std::vector<const nldelegate *> t; + std::vector<const nl_delegate *> t; log().verbose("Using default startup strategy"); for (auto &n : m_nets) { - n->update_inputs(); // only used if USE_COPY_INSTEAD_OF_REFERENCE == 1 - for (auto & term : core_terms(*n)) + n->update_inputs(); // only used if + // USE_COPY_INSTEAD_OF_REFERENCE == 1 + for (detail::core_terminal_t *term : n->core_terms_copy()) { if (!plib::container::contains(t, &term->delegate())) { @@ -347,19 +390,22 @@ namespace netlist term->run_delegate(); } // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) - auto *dev = reinterpret_cast<core_device_t *>(term->delegate().object()); + auto *dev = reinterpret_cast<core_device_t *>( + term->delegate().object()); if (!plib::container::contains(devices_called, dev)) devices_called.push_back(dev); } } log().verbose("Devices not yet updated:"); for (auto &dev : m_devices) - if (!plib::container::contains(devices_called, dev.second.get())) + if (!plib::container::contains(devices_called, + dev.second.get())) { // FIXME: doesn't seem to be needed, use cases include // analog output devices. Check and remove - log().error("\t Device {1} not yet updated", dev.second->name()); - //dev.second->update(); + log().error("\t Device {1} not yet updated", + dev.second->name()); + // dev.second->update(); } } break; @@ -367,51 +413,52 @@ namespace netlist // the above may screw up m_active and the list rebuild_lists(); - - } - - void netlist_t::print_stats() const - { - if (m_use_stats) - { - netlist_state_t::stats_info si{m_queue, m_stat_mainloop, m_perf_out_processed}; - m_state.print_stats(si); - } - log().verbose("Current pool memory allocated: {1:12} kB", nlstate().pool().cur_alloc() >> 10); - log().verbose("Maximum pool memory allocated: {1:12} kB", nlstate().pool().max_alloc() >> 10); } void netlist_state_t::print_stats(stats_info &si) const { std::vector<size_t> index; - for (size_t i=0; i < this->m_devices.size(); i++) + for (size_t i = 0; i < this->m_devices.size(); i++) index.push_back(i); std::sort(index.begin(), index.end(), - [&](size_t i1, size_t i2) { return this->m_devices[i1].second->stats()->m_stat_total_time.total() < this->m_devices[i2].second->stats()->m_stat_total_time.total(); }); - - plib::pperftime_t<true>::type total_time(0); + [&](size_t i1, size_t i2) + { + return this->m_devices[i1] + .second->stats() + ->m_stat_total_time.total() + < this->m_devices[i2] + .second->stats() + ->m_stat_total_time.total(); + }); + + plib::pperftime_t<true>::type total_time(0); plib::pperftime_t<true>::ctype total_count(0); - for (auto & j : index) + for (auto &j : index) { auto *entry = this->m_devices[j].second.get(); auto *stats = entry->stats(); - log().verbose("Device {1:20} : {2:12} {3:12} {4:15} {5:12}", entry->name(), - stats->m_stat_call_count(), stats->m_stat_total_time.count(), - stats->m_stat_total_time.total(), stats->m_stat_inc_active()); + log().verbose( + "Device {1:20} : {2:12} {3:12} {4:15} {5:12}", entry->name(), + stats->m_stat_call_count(), stats->m_stat_total_time.count(), + stats->m_stat_total_time.total(), stats->m_stat_inc_active()); total_time += stats->m_stat_total_time.total(); total_count += stats->m_stat_total_time.count(); } log().verbose("Total calls : {1:12} {2:12} {3:12}", total_count, - total_time, total_time / gsl::narrow<decltype(total_time)>((total_count > 0) ? total_count : 1)); + total_time, + total_time + / gsl::narrow<decltype(total_time)>( + (total_count > 0) ? total_count : 1)); log().verbose("Total loop {1:15}", si.m_stat_mainloop()); log().verbose("Total time {1:15}", total_time); // FIXME: clang complains about unreachable code without - const bool clang_workaround_unreachable_code(NL_USE_QUEUE_STATS>0); + const bool clang_workaround_unreachable_code( + config::use_queue_stats::value); if (clang_workaround_unreachable_code) { // Only one serialization should be counted in total time @@ -420,26 +467,32 @@ namespace netlist plib::pperftime_t<true> test; { auto overhead_guard(overhead.guard()); - for (int j=0; j<100000;j++) + for (int j = 0; j < 100000; j++) { auto test_guard(test.guard()); } } - plib::pperftime_t<true>::type total_overhead = overhead() - * gsl::narrow<plib::pperftime_t<true>::type>(total_count) - / gsl::narrow<plib::pperftime_t<true>::type>(200000); + plib::pperftime_t<true>::type total_overhead + = overhead() + * gsl::narrow<plib::pperftime_t<true>::type>(total_count) + / gsl::narrow<plib::pperftime_t<true>::type>(200000); log().verbose("Queue Pushes {1:15}", si.m_queue.m_prof_call()); - log().verbose("Queue Moves {1:15}", si.m_queue.m_prof_sortmove()); + log().verbose("Queue Moves {1:15}", + si.m_queue.m_prof_sort_move()); log().verbose("Queue Removes {1:15}", si.m_queue.m_prof_remove()); log().verbose(""); - log().verbose("Take the next lines with a grain of salt. They depend on the measurement implementation."); + 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); - plib::pperftime_t<true>::type overhead_per_pop = (si.m_stat_mainloop()-2*total_overhead - (total_time - total_overhead)) - / gsl::narrow<plib::pperftime_t<true>::type>(si.m_queue.m_prof_call()); - log().verbose("Overhead per pop {1:11}", overhead_per_pop ); + plib::pperftime_t<true>::type overhead_per_pop + = (si.m_stat_mainloop() - 2 * total_overhead + - (total_time - total_overhead)) + / gsl::narrow<plib::pperftime_t<true>::type>( + si.m_queue.m_prof_call()); + log().verbose("Overhead per pop {1:11}", overhead_per_pop); log().verbose(""); } @@ -448,17 +501,23 @@ namespace netlist { auto *ep = entry.second.get(); auto *stats = ep->stats(); - // Factor of 3 offers best performace increase - if (stats->m_stat_inc_active() > 3 * stats->m_stat_total_time.count() + // Factor of 3 offers best performance increase + if (stats->m_stat_inc_active() + > 3 * stats->m_stat_total_time.count() && stats->m_stat_inc_active() > trigger) log().verbose("HINT({}, NO_DEACTIVATE) // {} {} {}", ep->name(), - gsl::narrow<nl_fptype>(stats->m_stat_inc_active()) / gsl::narrow<nl_fptype>(stats->m_stat_total_time.count()), - stats->m_stat_inc_active(), stats->m_stat_total_time.count()); + gsl::narrow<nl_fptype>(stats->m_stat_inc_active()) + / gsl::narrow<nl_fptype>( + stats->m_stat_total_time.count()), + stats->m_stat_inc_active(), + stats->m_stat_total_time.count()); } log().verbose(""); } - core_device_t *netlist_state_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 (const auto &d : m_devices) @@ -468,7 +527,8 @@ namespace netlist if (ret != nullptr) { m_log.fatal(MF_MORE_THAN_ONE_1_DEVICE_FOUND(classname)); - throw nl_exception(MF_MORE_THAN_ONE_1_DEVICE_FOUND(classname)); + throw nl_exception( + MF_MORE_THAN_ONE_1_DEVICE_FOUND(classname)); } ret = d.second.get(); } @@ -476,84 +536,86 @@ namespace netlist return ret; } - - // ---------------------------------------------------------------------------------------- - // core_device_t - // ---------------------------------------------------------------------------------------- - - core_device_t::core_device_t(netlist_state_t &owner, const pstring &name) - : netlist_object_t(owner.exec(), name) - , m_hint_deactivate(false) - , m_active_outputs(*this, "m_active_outputs", 1) + nlparse_t &netlist_state_t::parser() noexcept { return m_setup->parser(); } + const nlparse_t &netlist_state_t::parser() const noexcept { - if (exec().stats_enabled()) - m_stats = owner.make_pool_object<stats_t>(); + return m_setup->parser(); } - core_device_t::core_device_t(core_device_t &owner, const pstring &name) - : netlist_object_t(owner.state().exec(), owner.name() + "." + name) - , m_hint_deactivate(false) - , m_active_outputs(*this, "m_active_outputs", 1) + void netlist_state_t::remove_device(core_device_t *dev) { - //printf("owned device: %s\n", this->name().c_str()); - owner.state().register_device(this->name(), device_arena::owned_ptr<core_device_t>(this, false)); - if (exec().stats_enabled()) - m_stats = owner.state().make_pool_object<stats_t>(); + for (auto it = m_devices.begin(); it != m_devices.end(); it++) + if (it->second.get() == dev) + { + m_state.remove_save_items(dev); + m_devices.erase(it); + return; + } } - log_type & core_device_t::log() + // ------------------------------------------------------------------------- + // core_device_t + // ------------------------------------------------------------------------- + + core_device_t::core_device_t(core_device_param_t data) + : netlist_object_t(data.owner.exec(), data.name) + , m_hint_deactivate(false) + , m_active_outputs(*this, "m_active_outputs", 1) { - return state().log(); + if (exec().stats_enabled()) + m_stats = state().make_pool_object<stats_t>(); } - // ---------------------------------------------------------------------------------------- - // base_device_t - // ---------------------------------------------------------------------------------------- + log_type &core_device_t::log() { return state().log(); } - base_device_t::base_device_t(netlist_state_t &owner, const pstring &name) - : core_device_t(owner, name) - { - } + // ------------------------------------------------------------------------- + // base_device_t + // ------------------------------------------------------------------------- - base_device_t::base_device_t(base_device_t &owner, const pstring &name) - : core_device_t(owner, name) + base_device_t::base_device_t(base_device_param_t data) + : core_device_t(data) { } - void base_device_t::register_subalias(const pstring &name, const detail::core_terminal_t &term) + void base_device_t::register_sub_alias(const pstring & name, + const detail::core_terminal_t &term) { pstring alias = this->name() + "." + name; // everything already fully qualified - state().parser().register_alias_nofqn(alias, term.name()); + state().parser().register_fqn_alias(detail::alias_type::FUNCTIONAL, + alias, term.name()); } - void base_device_t::register_subalias(const pstring &name, const pstring &aliased) + void base_device_t::register_sub_alias(const pstring &name, + const pstring &aliased) { pstring alias = this->name() + "." + name; pstring aliased_fqn = this->name() + "." + aliased; // everything already fully qualified - state().parser().register_alias_nofqn(alias, aliased_fqn); + state().parser().register_fqn_alias(detail::alias_type::FUNCTIONAL, + alias, aliased_fqn); } - void base_device_t::connect(const detail::core_terminal_t &t1, const detail::core_terminal_t &t2) + void base_device_t::connect(const detail::core_terminal_t &t1, + const detail::core_terminal_t &t2) { - state().parser().register_link_fqn(t1.name(), t2.name()); + state().parser().register_connection_fqn(t1.name(), t2.name()); } void base_device_t::connect(const pstring &t1, const pstring &t2) { - state().parser().register_link_fqn(name() + "." + t1, name() + "." + t2); + state().parser().register_connection_fqn(name() + "." + t1, + name() + "." + t2); } - - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- // device_t - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- - device_t::device_t(netlist_state_t &owner, const pstring &name) - : base_device_t(owner, name) + device_t::device_t(device_param_t data) + : base_device_t(data) , m_model(*this, "MODEL", pstring(config::DEFAULT_LOGIC_FAMILY())) { set_logic_family(state().setup().family_from_model(m_model())); @@ -561,9 +623,8 @@ namespace netlist throw nl_exception(MF_NULLPTR_FAMILY(this->name(), m_model())); } - device_t::device_t(netlist_state_t &owner, const pstring &name, - const pstring &model) - : base_device_t(owner, name) + device_t::device_t(device_param_t data, const pstring &model) + : base_device_t(data) , m_model(*this, "MODEL", model) { set_logic_family(state().setup().family_from_model(m_model())); @@ -571,55 +632,58 @@ namespace netlist throw nl_exception(MF_NULLPTR_FAMILY(this->name(), m_model())); } - device_t::device_t(netlist_state_t &owner, const pstring &name, - const logic_family_desc_t *desc) - : base_device_t(owner, name) + device_t::device_t(device_param_t data, const logic_family_desc_t *desc) + : base_device_t(data) , m_model(*this, "MODEL", pstring("")) { set_logic_family(desc); if (logic_family() == nullptr) - throw nl_exception(MF_NULLPTR_FAMILY(this->name(), "<pointer provided by constructor>")); + throw nl_exception(MF_NULLPTR_FAMILY( + this->name(), "<pointer provided by constructor>")); } - device_t::device_t(device_t &owner, const pstring &name) - : base_device_t(owner, name) - , m_model(*this, "MODEL", pstring("")) - { - set_logic_family(owner.logic_family()); - if (logic_family() == nullptr) - throw nl_exception(MF_NULLPTR_FAMILY(this->name(), "<owner logic family>")); - } + // ------------------------------------------------------------------------- + // analog_t + // ------------------------------------------------------------------------- - device_t::device_t(device_t &owner, const pstring &name, const pstring &model) - : base_device_t(owner, name) - , m_model(*this, "MODEL", model) + analog_t::analog_t(core_device_t &dev, const pstring &aname, + const state_e state, nl_delegate delegate) + : core_terminal_t(dev, aname, state, delegate) { - set_logic_family(state().setup().family_from_model(m_model())); - if (logic_family() == nullptr) - throw nl_exception(MF_NULLPTR_FAMILY(this->name(), m_model())); } - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- // net_t - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- - detail::net_t::net_t(netlist_state_t &nl, const pstring &aname, core_terminal_t *railterminal) - : netlist_object_t(nl.exec(), aname) - , m_new_Q(*this, "m_new_Q", netlist_sig_t(0)) - , m_cur_Q (*this, "m_cur_Q", netlist_sig_t(0)) - , m_in_queue(*this, "m_in_queue", queue_status::DELIVERED) - , m_next_scheduled_time(*this, "m_time", netlist_time_ext::zero()) - , m_railterminal(railterminal) + detail::net_t::net_t(netlist_state_t &nl, const pstring &aname, + core_terminal_t *rail_terminal) + : netlist_object_t(nl.exec(), aname) + , m_new_Q(*this, "m_new_Q", netlist_sig_t(0)) + , m_cur_Q(*this, "m_cur_Q", netlist_sig_t(0)) + , m_in_queue(*this, "m_in_queue", queue_status::DELIVERED) + , m_next_scheduled_time(*this, "m_time", netlist_time_ext::zero()) + , m_rail_terminal(rail_terminal) { props::add(this, props::value_type()); } + bool detail::net_t::is_logic() const noexcept + { + return bool(plib::dynamic_downcast<const logic_net_t *>(this)); + } + + bool detail::net_t::is_analog() const noexcept + { + return bool(plib::dynamic_downcast<const analog_net_t *>(this)); + } + void detail::net_t::rebuild_list() { // rebuild m_list m_list_active.clear(); - for (auto & term : exec().nlstate().core_terms(*this)) + for (core_terminal_t *term : core_terms_ref()) if (term->terminal_state() != logic_t::STATE_INP_PASSIVE) { m_list_active.push_back(term); @@ -627,7 +691,6 @@ namespace netlist } } - void detail::net_t::reset() noexcept { m_next_scheduled_time = exec().time(); @@ -636,15 +699,13 @@ namespace netlist m_new_Q = 0; m_cur_Q = 0; - auto *p = dynamic_cast<analog_net_t *>(this); - - if (p != nullptr) - p->set_Q_Analog(nlconst::zero()); + if (auto p = plib::dynamic_downcast<analog_net_t *>(this)) + (*p)->set_Q_Analog(nlconst::zero()); // rebuild m_list and reset terminals to active or analog out state m_list_active.clear(); - for (core_terminal_t *ct : exec().nlstate().core_terms(*this)) + for (core_terminal_t *ct : core_terms_copy()) { ct->reset(); if (ct->terminal_state() != logic_t::STATE_INP_PASSIVE) @@ -653,23 +714,84 @@ namespace netlist } } - // ---------------------------------------------------------------------------------------- +#if NL_USE_INPLACE_CORE_TERMS + void detail::net_t::remove_terminal(detail::core_terminal_t &term) + { + m_core_terms.remove(&term); + } + + void detail::net_t::remove_all_terminals() { m_core_terms.clear(); } + + void detail::net_t::add_terminal(detail::core_terminal_t &terminal) + { + for (detail::core_terminal_t *t : m_core_terms) + if (t == &terminal) + { + state().log().fatal( + MF_NET_1_DUPLICATE_TERMINAL_2(this->name(), t->name())); + throw nl_exception( + MF_NET_1_DUPLICATE_TERMINAL_2(this->name(), t->name())); + } + + terminal.set_net(this); + + m_core_terms.push_back(&terminal); + } + +#else + void detail::net_t::remove_terminal(detail::core_terminal_t &term) + { + // net.core_terms().remove(p); + for (auto pp = state().core_terms(*this).begin(); + pp != state().core_terms(*this).end(); pp++) + if (*pp == &term) + { + state().core_terms(*this).erase(pp); + break; + } + } + + void detail::net_t::remove_all_terminals() + { + state().core_terms(*this).clear(); + } + + void detail::net_t::add_terminal(detail::core_terminal_t &terminal) + { + for (detail::core_terminal_t *t : core_terms_ref()) + if (t == &terminal) + { + state().log().fatal( + MF_NET_1_DUPLICATE_TERMINAL_2(this->name(), t->name())); + throw nl_exception( + MF_NET_1_DUPLICATE_TERMINAL_2(this->name(), t->name())); + } + + terminal.set_net(this); + + state().core_terms(*this).push_back(&terminal); + } +#endif + + // ------------------------------------------------------------------------- // logic_net_t - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- - logic_net_t::logic_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *railterminal) - : net_t(nl, aname, railterminal) + logic_net_t::logic_net_t(netlist_state_t &nl, const pstring &aname, + detail::core_terminal_t *rail_terminal) + : net_t(nl, aname, rail_terminal) { } - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- // analog_net_t - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- - analog_net_t::analog_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *railterminal) - : net_t(nl, aname, railterminal) - , m_cur_Analog(*this, "m_cur_Analog", nlconst::zero()) - , m_solver(nullptr) + analog_net_t::analog_net_t(netlist_state_t &nl, const pstring &aname, + detail::core_terminal_t *rail_terminal) + : net_t(nl, aname, rail_terminal) + , m_cur_Analog(*this, "m_cur_Analog", nlconst::zero()) + , m_solver(nullptr) { } @@ -678,55 +800,89 @@ namespace netlist net_t::reset(); m_cur_Analog = nlconst::zero(); } - // ---------------------------------------------------------------------------------------- + + // ------------------------------------------------------------------------- // core_terminal_t - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- - detail::core_terminal_t::core_terminal_t(core_device_t &dev, const pstring &aname, - const state_e state, nldelegate delegate) + detail::core_terminal_t::core_terminal_t(core_device_t &dev, + const pstring &aname, + const state_e state, + nl_delegate delegate) : device_object_t(&dev, dev.name() + "." + aname) - #if NL_USE_COPY_INSTEAD_OF_REFERENCE - , m_Q(*this, "m_Q", 0) - #endif + , m_Q_CIR(*this, "m_Q", 0) , m_delegate(delegate) , m_net(nullptr) , m_state(*this, "m_state", state) { } - analog_t::analog_t(core_device_t &dev, const pstring &aname, const state_e state, - nldelegate delegate) - : core_terminal_t(dev, aname, state, delegate) + bool detail::core_terminal_t::is_logic() const noexcept + { + return bool(plib::dynamic_downcast<const logic_t *>(this)); + } + + bool detail::core_terminal_t::is_logic_input() const noexcept + { + return bool(plib::dynamic_downcast<const logic_input_t *>(this)); + } + + bool detail::core_terminal_t::is_logic_output() const noexcept + { + return bool(plib::dynamic_downcast<const logic_output_t *>(this)); + } + + bool detail::core_terminal_t::is_tristate_output() const noexcept + { + return bool(plib::dynamic_downcast<const tristate_output_t *>(this)); + } + + bool detail::core_terminal_t::is_analog() const noexcept + { + return bool(plib::dynamic_downcast<const analog_t *>(this)); + } + + bool detail::core_terminal_t::is_analog_input() const noexcept + { + return bool(plib::dynamic_downcast<const analog_input_t *>(this)); + } + + bool detail::core_terminal_t::is_analog_output() const noexcept { + return bool(plib::dynamic_downcast<const analog_output_t *>(this)); } - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- // terminal_t - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- terminal_t::terminal_t(core_device_t &dev, const pstring &aname, - terminal_t *otherterm, nldelegate delegate) - : terminal_t(dev, aname, otherterm, { nullptr, nullptr }, delegate) + terminal_t *other_terminal, nl_delegate delegate) + : terminal_t(dev, aname, other_terminal, {nullptr, nullptr}, delegate) { } terminal_t::terminal_t(core_device_t &dev, const pstring &aname, - terminal_t *otherterm, const std::array<terminal_t *, 2> &splitterterms, - nldelegate delegate) + terminal_t * other_terminal, + const std::array<terminal_t *, 2> &splitter_terms, + nl_delegate delegate) : analog_t(dev, aname, STATE_BIDIR, delegate) , m_Idr(nullptr) , m_go(nullptr) , m_gt(nullptr) { - state().setup().register_term(*this, otherterm, splitterterms); + state().setup().register_term(*this, other_terminal, splitter_terms); } - void terminal_t::set_ptrs(nl_fptype *gt, nl_fptype *go, nl_fptype *Idr) noexcept(false) + void terminal_t::set_ptrs(nl_fptype *gt, nl_fptype *go, + nl_fptype *Idr) noexcept(false) { // NOLINTNEXTLINE(readability-implicit-bool-conversion) if (!(gt && go && Idr) && (gt || go || Idr)) { - throw nl_exception("Inconsistent nullptrs for terminal {}", name()); + throw nl_exception( + "Either all pointers must be set or none for terminal {}", + name()); } m_gt = gt; @@ -734,48 +890,40 @@ namespace netlist m_Idr = Idr; } - // ---------------------------------------------------------------------------------------- - // net_input_t - // ---------------------------------------------------------------------------------------- - - // ---------------------------------------------------------------------------------------- - // net_output_t - // ---------------------------------------------------------------------------------------- - - // ----------------------------------------------------------------------------- + // ------------------------------------------------------------------------- // logic_t - // ----------------------------------------------------------------------------- + // ------------------------------------------------------------------------- - logic_t::logic_t(device_t &dev, const pstring &aname, const state_e terminal_state, - nldelegate delegate) - : core_terminal_t(dev, aname, terminal_state, delegate) - , logic_family_t(dev.logic_family()) + logic_t::logic_t(device_t &dev, const pstring &aname, + const state_e terminal_state, nl_delegate delegate) + : core_terminal_t(dev, aname, terminal_state, delegate) + , logic_family_t(dev.logic_family()) { } - // ----------------------------------------------------------------------------- + // ------------------------------------------------------------------------- // logic_input_t - // ----------------------------------------------------------------------------- + // ------------------------------------------------------------------------- logic_input_t::logic_input_t(device_t &dev, const pstring &aname, - nldelegate delegate) - : logic_t(dev, aname, STATE_INP_ACTIVE, delegate) + nl_delegate delegate) + : logic_t(dev, aname, STATE_INP_ACTIVE, delegate) { state().setup().register_term(*this); } - - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- // logic_output_t - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- - logic_output_t::logic_output_t(device_t &dev, const pstring &aname, bool dummy) - : logic_t(dev, aname, STATE_OUT, nldelegate()) - , m_my_net(dev.state(), name() + ".net", this) + logic_output_t::logic_output_t(device_t &dev, const pstring &aname, + [[maybe_unused]] bool dummy) + : logic_t(dev, aname, STATE_OUT, nl_delegate()) + , m_my_net(dev.state(), name() + ".net", this) { - plib::unused_var(dummy); this->set_net(&m_my_net); - state().register_net(device_arena::owned_ptr<logic_net_t>(&m_my_net, false)); + state().register_net( + device_arena::owned_ptr<logic_net_t>(&m_my_net, false)); state().setup().register_term(*this); } @@ -785,39 +933,44 @@ namespace netlist net().initial(val); } - // ----------------------------------------------------------------------------- + // ------------------------------------------------------------------------- // tristate_output_t - // ----------------------------------------------------------------------------- - tristate_output_t::tristate_output_t(device_t &dev, const pstring &aname, bool force_logic) + // ------------------------------------------------------------------------- + + tristate_output_t::tristate_output_t(device_t &dev, const pstring &aname, + bool force_logic) : logic_output_t(dev, aname) , m_last_logic(dev, name() + "." + "m_last_logic", 1) // force change - , m_tristate(dev, name() + "." + "m_tristate", force_logic ? 0 : 2) // force change + , m_tristate(dev, name() + "." + "m_tristate", + force_logic ? 0 : 2) // force change , m_force_logic(force_logic) - {} + { + } - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- // analog_input_t - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- analog_input_t::analog_input_t(core_device_t &dev, const pstring &aname, - nldelegate delegate) + nl_delegate delegate) : analog_t(dev, aname, STATE_INP_ACTIVE, delegate) { state().setup().register_term(*this); } - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- // analog_output_t - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- analog_output_t::analog_output_t(core_device_t &dev, const pstring &aname) - : analog_t(dev, aname, STATE_OUT, nldelegate()) - , m_my_net(dev.state(), name() + ".net", this) + : analog_t(dev, aname, STATE_OUT, nl_delegate()) + , m_my_net(dev.state(), name() + ".net", this) { - state().register_net(device_arena::owned_ptr<analog_net_t>(&m_my_net, false)); + state().register_net( + device_arena::owned_ptr<analog_net_t>(&m_my_net, false)); this->set_net(&m_my_net); - //net().m_cur_Analog = NL_FCONST(0.0); + // net().m_cur_Analog = NL_FCONST(0.0); state().setup().register_term(*this); } @@ -826,18 +979,18 @@ namespace netlist net().set_Q_Analog(val); } - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- // Parameters ... - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- - // deviceless, it's the responsibility of the owner to register! + // device-less, it's the responsibility of the owner to register! param_t::param_t(const pstring &name) - : device_object_t(nullptr, name) + : device_object_t(nullptr, name) { } param_t::param_t(core_device_t &device, const pstring &name) - : device_object_t(&device, device.name() + "." + name) + : device_object_t(&device, device.name() + "." + name) { device.state().setup().register_param_t(*this); } @@ -847,58 +1000,57 @@ namespace netlist param_t::param_type_t param_t::param_type() const noexcept(false) { - if (dynamic_cast<const param_str_t *>(this) != nullptr) + if (plib::dynamic_downcast<const param_str_t *>(this)) return STRING; - if (dynamic_cast<const param_fp_t *>(this) != nullptr) + if (plib::dynamic_downcast<const param_fp_t *>(this)) return DOUBLE; - if (dynamic_cast<const param_int_t *>(this) != nullptr) + if (plib::dynamic_downcast<const param_int_t *>(this)) return INTEGER; - if (dynamic_cast<const param_logic_t *>(this) != nullptr) + if (plib::dynamic_downcast<const param_logic_t *>(this)) return LOGIC; - if (dynamic_cast<const param_ptr_t *>(this) != nullptr) + if (plib::dynamic_downcast<const param_ptr_t *>(this)) return POINTER; state().log().fatal(MF_UNKNOWN_PARAM_TYPE(name())); throw nl_exception(MF_UNKNOWN_PARAM_TYPE(name())); } - - pstring param_t::get_initial(const core_device_t *dev, bool *found) const { - pstring res = dev->state().setup().get_initial_param_val(this->name(), ""); + pstring res = dev->state().setup().get_initial_param_val(this->name(), + ""); *found = (!res.empty()); return res; } - param_str_t::param_str_t(core_device_t &device, const pstring &name, const pstring &val) + param_str_t::param_str_t(core_device_t &device, const pstring &name, + const pstring &val) : param_t(device, name) { m_param = plib::make_unique<pstring, host_arena>(val); - *m_param = device.state().setup().get_initial_param_val(this->name(),val); + *m_param = device.state().setup().get_initial_param_val(this->name(), + val); } - param_str_t::param_str_t(netlist_state_t &state, const pstring &name, const pstring &val) + param_str_t::param_str_t(netlist_state_t &state, const pstring &name, + const pstring &val) : param_t(name) { - // deviceless parameter, no registration, owner is responsible + // device-less parameter, no registration, owner is responsible m_param = plib::make_unique<pstring, host_arena>(val); - *m_param = state.setup().get_initial_param_val(this->name(),val); + *m_param = state.setup().get_initial_param_val(this->name(), val); } - void param_str_t::changed() noexcept - { - } + void param_str_t::changed() noexcept {} - param_ptr_t::param_ptr_t(core_device_t &device, const pstring &name, uint8_t * val) + param_ptr_t::param_ptr_t(core_device_t &device, const pstring &name, + uint8_t *val) : param_t(device, name) + , m_param(val) { - m_param = val; } - void param_model_t::changed() noexcept - { - } + void param_model_t::changed() noexcept {} pstring param_model_t::type() { @@ -916,92 +1068,27 @@ namespace netlist return state().setup().models().get_model(str()).value(entity); } - plib::istream_uptr param_data_t::stream() { return device().state().parser().get_data_stream(str()); } - bool detail::core_terminal_t::is_logic() const noexcept - { - return dynamic_cast<const logic_t *>(this) != nullptr; - } - - bool detail::core_terminal_t::is_logic_input() const noexcept - { - return dynamic_cast<const logic_input_t *>(this) != nullptr; - } - - bool detail::core_terminal_t::is_logic_output() const noexcept - { - return dynamic_cast<const logic_output_t *>(this) != nullptr; - } - - bool detail::core_terminal_t::is_tristate_output() const noexcept - { - return dynamic_cast<const tristate_output_t *>(this) != nullptr; - } - - bool detail::core_terminal_t::is_analog() const noexcept - { - return dynamic_cast<const analog_t *>(this) != nullptr; - } - - bool detail::core_terminal_t::is_analog_input() const noexcept - { - return dynamic_cast<const analog_input_t *>(this) != nullptr; - } - - bool detail::core_terminal_t::is_analog_output() const noexcept - { - return dynamic_cast<const analog_output_t *>(this) != nullptr; - } - - - bool detail::net_t::is_logic() const noexcept - { - return dynamic_cast<const logic_net_t *>(this) != nullptr; - } - - bool detail::net_t::is_analog() const noexcept - { - return dynamic_cast<const analog_net_t *>(this) != nullptr; - } - - // ---------------------------------------------------------------------------------------- - // netlist_state_t - // ---------------------------------------------------------------------------------------- - - nlparse_t &netlist_state_t::parser() { return m_setup->parser(); } - const nlparse_t &netlist_state_t::parser() const { return m_setup->parser(); } - - void netlist_state_t::remove_device(core_device_t *dev) - { - for (auto it = m_devices.begin(); it != m_devices.end(); it++) - if (it->second.get() == dev) - { - m_state.remove_save_items(dev); - m_devices.erase(it); - return; - } - } - - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- // netlist_t // // Hot section // // Any changes below will impact performance. - // ----------------------------------------------------------------------------- + // ------------------------------------------------------------------------- template <bool KEEP_STATS> void netlist_t::process_queue_stats(const netlist_time_ext delta) noexcept { netlist_time_ext stop(m_time + delta); - qpush(stop, nullptr); + queue_push(stop, nullptr); - if (m_mainclock == nullptr) + if (m_main_clock == nullptr) { m_time = m_queue.top().exec_time(); detail::net_t *obj(m_queue.top().object()); @@ -1020,9 +1107,9 @@ namespace netlist } else { - logic_net_t &mc_net(m_mainclock->m_Q.net()); - const netlist_time inc(m_mainclock->m_inc); - netlist_time_ext mc_time(mc_net.next_scheduled_time()); + logic_net_t & mc_net(m_main_clock->m_Q.net()); + const netlist_time inc(m_main_clock->m_inc); + netlist_time_ext mc_time(mc_net.next_scheduled_time()); do { @@ -1064,7 +1151,6 @@ namespace netlist } } - template struct state_var<std::uint8_t>; template struct state_var<std::uint16_t>; template struct state_var<std::uint32_t>; |