summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/nl_base.cpp
diff options
context:
space:
mode:
author couriersud <couriersud@users.noreply.github.com>2022-06-10 16:11:21 +0200
committer GitHub <noreply@github.com>2022-06-10 16:11:21 +0200
commit1f3f5e0d574e256bc106ee4bc9ee701858585ca3 (patch)
treee471112c27fccd862215cf2c460d5471d546de86 /src/lib/netlist/nl_base.cpp
parent63e595ae364a6f9e6b3692af673d1a0c48523f2d (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.cpp336
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)
{