diff options
author | 2022-06-10 16:11:21 +0200 | |
---|---|---|
committer | 2022-06-10 16:11:21 +0200 | |
commit | 1f3f5e0d574e256bc106ee4bc9ee701858585ca3 (patch) | |
tree | e471112c27fccd862215cf2c460d5471d546de86 /src/lib/netlist/nl_base.cpp | |
parent | 63e595ae364a6f9e6b3692af673d1a0c48523f2d (diff) |
netlist: fix bugs and more cpp instead of macros (#9897)
* netlist: fix bugs and more cpp instead of macros
- C-style comments converted to c++
- Fix crash in state saving code when an abort queue processing event
is pending.
- Fix a bug where a net could be twice in the queue.
- Convert more macros to c++
- fixed SUBTARGET=nl build
- fixed potential bugs which would allow a terminal to belong to more
than one net. This is not possible even for a short time.
- moved some member function definitions out-of-class.
- moved code out-of-class
- added constexpr where appropriate
- fixed mamenl build
- Cleanup and indentation
Diffstat (limited to 'src/lib/netlist/nl_base.cpp')
-rw-r--r-- | src/lib/netlist/nl_base.cpp | 336 |
1 files changed, 196 insertions, 140 deletions
diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp index 6441b91c287..c60162efb0c 100644 --- a/src/lib/netlist/nl_base.cpp +++ b/src/lib/netlist/nl_base.cpp @@ -25,23 +25,9 @@ namespace netlist { // ---------------------------------------------------------------------------------------- - // callbacks_t + // detail::core_terminal_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::terminal_type detail::core_terminal_t::type() const noexcept(false) { if (dynamic_cast<const terminal_t *>(this) != nullptr) @@ -58,6 +44,16 @@ namespace netlist //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 { return m_device->state(); @@ -69,7 +65,7 @@ namespace netlist } // ---------------------------------------------------------------------------------------- - // netlist_object_t + // detail::netlist_object_t // ---------------------------------------------------------------------------------------- netlist_state_t & detail::netlist_object_t::state() noexcept @@ -100,8 +96,47 @@ namespace netlist state.save(*this, m_time, aname, "m_time"); } + 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(); + + 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_t + // netlist_state_t // ---------------------------------------------------------------------------------------- netlist_state_t::netlist_state_t(const pstring &name, @@ -137,8 +172,8 @@ namespace netlist 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 pstring dir = "src/lib/netlist/"; @@ -166,25 +201,25 @@ namespace netlist 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(); } @@ -274,25 +309,6 @@ namespace netlist return plib::pfmt("{1}.{2}.{3}")(NL_VERSION_MAJOR, NL_VERSION_MINOR, NL_VERSION_PATCHLEVEL); } - 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(); - - m_state.reset(); - } - void netlist_state_t::free_setup_resources() { m_setup = nullptr; @@ -339,7 +355,7 @@ namespace netlist for (auto &n : m_nets) { n->update_inputs(); // only used if USE_COPY_INSTEAD_OF_REFERENCE == 1 - for (auto & term : core_terms(*n)) + for (detail::core_terminal_t * term : n->core_terms_copy()) { if (!plib::container::contains(t, &term->delegate())) { @@ -370,17 +386,6 @@ namespace netlist } - 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); - } - void netlist_state_t::print_stats(stats_info &si) const { std::vector<size_t> index; @@ -431,7 +436,7 @@ namespace netlist / 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(""); @@ -476,6 +481,19 @@ namespace netlist return ret; } + 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; + } + } // ---------------------------------------------------------------------------------------- // core_device_t @@ -525,7 +543,7 @@ namespace netlist pstring alias = this->name() + "." + name; // everything already fully qualified - state().parser().register_alias_nofqn(alias, term.name()); + state().parser().register_alias_no_fqn(alias, term.name()); } void base_device_t::register_sub_alias(const pstring &name, const pstring &aliased) @@ -534,7 +552,7 @@ namespace netlist pstring aliased_fqn = this->name() + "." + aliased; // everything already fully qualified - state().parser().register_alias_nofqn(alias, aliased_fqn); + state().parser().register_alias_no_fqn(alias, aliased_fqn); } void base_device_t::connect(const detail::core_terminal_t &t1, const detail::core_terminal_t &t2) @@ -600,6 +618,16 @@ namespace netlist } // ---------------------------------------------------------------------------------------- + // analog_t + // ---------------------------------------------------------------------------------------- + + 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) + { + } + + // ---------------------------------------------------------------------------------------- // net_t // ---------------------------------------------------------------------------------------- @@ -614,12 +642,22 @@ namespace netlist props::add(this, props::value_type()); } + 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; + } + void detail::net_t::rebuild_list() { // rebuild m_list m_list_active.clear(); - for (auto & term : exec().nl_state().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 +665,6 @@ namespace netlist } } - void detail::net_t::reset() noexcept { m_next_scheduled_time = exec().time(); @@ -644,7 +681,7 @@ namespace netlist // rebuild m_list and reset terminals to active or analog out state m_list_active.clear(); - for (core_terminal_t *ct : exec().nl_state().core_terms(*this)) + for (core_terminal_t * ct : core_terms_copy()) { ct->reset(); if (ct->terminal_state() != logic_t::STATE_INP_PASSIVE) @@ -653,6 +690,63 @@ 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 : state().core_terms(*this)) + 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 // ---------------------------------------------------------------------------------------- @@ -678,6 +772,7 @@ namespace netlist net_t::reset(); m_cur_Analog = nlconst::zero(); } + // ---------------------------------------------------------------------------------------- // core_terminal_t // ---------------------------------------------------------------------------------------- @@ -685,19 +780,46 @@ namespace netlist 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, - nl_delegate delegate) - : core_terminal_t(dev, aname, state, delegate) + 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; } // ---------------------------------------------------------------------------------------- @@ -764,7 +886,6 @@ namespace netlist state().setup().register_term(*this); } - // ---------------------------------------------------------------------------------------- // logic_output_t // ---------------------------------------------------------------------------------------- @@ -787,6 +908,7 @@ namespace netlist // ----------------------------------------------------------------------------- // tristate_output_t // ----------------------------------------------------------------------------- + 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 @@ -862,7 +984,6 @@ namespace netlist } - pstring param_t::get_initial(const core_device_t *dev, bool *found) const { pstring res = dev->state().setup().get_initial_param_val(this->name(), ""); @@ -915,76 +1036,11 @@ 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 // @@ -998,7 +1054,7 @@ namespace netlist { netlist_time_ext stop(m_time + delta); - qpush(stop, nullptr); + queue_push(stop, nullptr); if (m_main_clock == nullptr) { |