diff options
author | 2022-06-20 20:01:03 +0200 | |
---|---|---|
committer | 2022-06-20 20:01:03 +0200 | |
commit | 0dad442511fc3e96bae721c38fe8040a222cc21a (patch) | |
tree | b0eb0732f9e7f438a41a889621d36193d16d6e1b /src/lib/netlist/nl_setup.cpp | |
parent | 3fbfe0b1d76573ee8971eaaee6b37b4024575624 (diff) |
netlist: fix bug, prepare for future changes and improve readability (#9947)
* netlist: fix bug, prepare for future changes and improve readability
- fix a bug where a net processing error may trigger a nullptr access
- applied some clang-tidy recommendations
- add no_return to plib::terminate
- properly encapsulate dynamic_cast usage
- more review of noexcept
- added a clang-format file. Over time, all source files will be
processed with clang-format
- Used clang format on a number of files
- Rewrote 74174
- all device constructors now use a struct to pass data on
to base classes. Neither netlist state nor the name are intended
to be used in a constructor. After the base class was
constructed, they can be accessed by state() and name().
- The device construction macros can now be removed. Changes to
the core will not need to be reflected in constructors.
- Change truth table macros so that going forward NETLIST_END and
TRUTH_TABLE_END can be replaced by a closing curly brace. netlists can
than use curly braces enclosed blocks.
- more clang-format
- removed some macros completely
- all derived classes from base_device_t now don't use macros
any longer.
- as a result, delegator_t was removed. This class was only used
to support macros :-(
Diffstat (limited to 'src/lib/netlist/nl_setup.cpp')
-rw-r--r-- | src/lib/netlist/nl_setup.cpp | 914 |
1 files changed, 533 insertions, 381 deletions
diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp index d8040258568..19ed531b853 100644 --- a/src/lib/netlist/nl_setup.cpp +++ b/src/lib/netlist/nl_setup.cpp @@ -1,35 +1,40 @@ // license:BSD-3-Clause // copyright-holders:Couriersud -#include "plib/palloc.h" +#include "nl_setup.h" + +#include "nl_errstr.h" +#include "nl_factory.h" +#include "nl_parser.h" + #include "core/devices.h" #include "core/setup.h" + #include "devices/nlid_proxy.h" #include "devices/nlid_truthtable.h" -#include "nl_errstr.h" -#include "nl_factory.h" -#include "nl_parser.h" -#include "nl_setup.h" + +#include "solver/nld_solver.h" + +#include "plib/palloc.h" #include "plib/penum.h" #include "plib/pstonum.h" #include "plib/pstrutil.h" #include "plib/putil.h" -#include "solver/nld_solver.h" - #include <sstream> namespace netlist { - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- // nl_parse_t - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- nlparse_t::nlparse_t(log_type &log, detail::abstract_t &abstract) : m_abstract(abstract) , m_log(log) , m_frontier_cnt(0) - { } + { + } void nlparse_t::register_alias(const pstring &alias, const pstring &out) { @@ -40,26 +45,29 @@ namespace netlist void nlparse_t::register_dip_alias_arr(const pstring &terms) { - const auto list(plib::psplit(terms,pstring(", "))); + const auto list(plib::psplit(terms, pstring(", "))); if (list.empty() || (list.size() % 2) == 1) { - log().fatal(MF_DIP_PINS_MUST_BE_AN_EQUAL_NUMBER_OF_PINS_1(build_fqn(""))); - throw nl_exception(MF_DIP_PINS_MUST_BE_AN_EQUAL_NUMBER_OF_PINS_1(build_fqn(""))); + log().fatal( + MF_DIP_PINS_MUST_BE_AN_EQUAL_NUMBER_OF_PINS_1(build_fqn(""))); + throw nl_exception( + MF_DIP_PINS_MUST_BE_AN_EQUAL_NUMBER_OF_PINS_1(build_fqn(""))); } std::size_t n = list.size(); for (std::size_t i = 0; i < n / 2; i++) { - register_alias(plib::pfmt("{1}")(i+1), list[i * 2]); - register_alias(plib::pfmt("{1}")(n-i), list[i * 2 + 1]); + register_alias(plib::pfmt("{1}")(i + 1), list[i * 2]); + register_alias(plib::pfmt("{1}")(n - i), list[i * 2 + 1]); } } - void nlparse_t::register_dev(const pstring &classname, - std::initializer_list<const char *> more_parameters) + void + nlparse_t::register_dev(const pstring & classname, + std::initializer_list<const char *> more_parameters) { std::vector<pstring> params; - const auto *i(more_parameters.begin()); - pstring name(*i); + const auto * i(more_parameters.begin()); + pstring name(*i); ++i; for (; i != more_parameters.end(); ++i) { @@ -68,9 +76,10 @@ namespace netlist register_dev(classname, name, params); } - void nlparse_t::register_dev(const pstring &classname, const pstring &name, - const std::vector<pstring> ¶ms_and_connections, - factory::element_t **factory_element) + void + nlparse_t::register_dev(const pstring &classname, const pstring &name, + const std::vector<pstring> ¶ms_and_connections, + factory::element_t ** factory_element) { auto *f = factory().factory_by_name(classname); @@ -92,7 +101,8 @@ namespace netlist throw nl_exception(MF_DEVICE_ALREADY_EXISTS_1(key)); } - m_abstract.m_device_factory.insert(m_abstract.m_device_factory.end(), {key, f}); + m_abstract.m_device_factory.insert(m_abstract.m_device_factory.end(), + {key, f}); auto parameter_list = plib::psplit(f->param_desc(), ','); @@ -107,10 +117,11 @@ namespace netlist { if (token_ptr == token_end) { - auto err = MF_PARAM_COUNT_MISMATCH_2(name, params_and_connections.size()); + auto err = MF_PARAM_COUNT_MISMATCH_2( + name, params_and_connections.size()); log().fatal(err); throw nl_exception(err); - //break; + // break; } pstring output_name = *token_ptr; log().debug("Link: {1} {2}", tp, output_name); @@ -129,13 +140,15 @@ namespace netlist { if (token_ptr == token_end) { - auto err = MF_PARAM_COUNT_MISMATCH_2(name, params_and_connections.size()); + auto err = MF_PARAM_COUNT_MISMATCH_2( + name, params_and_connections.size()); log().fatal(err); throw nl_exception(err); } pstring fully_qualified_name = name + "." + tp; - log().debug("Default parameter: {1}\n", fully_qualified_name); + log().debug("Default parameter: {1}\n", + fully_qualified_name); register_param(fully_qualified_name, *token_ptr); @@ -144,7 +157,8 @@ namespace netlist } if (token_ptr != params_and_connections.end()) { - MF_PARAM_COUNT_EXCEEDED_2 err(name, params_and_connections.size()); + MF_PARAM_COUNT_EXCEEDED_2 err(name, + params_and_connections.size()); log().fatal(err); throw nl_exception(err); } @@ -153,7 +167,8 @@ namespace netlist *factory_element = f; } - void nlparse_t::register_hint(const pstring &object_name, const pstring &hint_name) + void nlparse_t::register_hint(const pstring &object_name, + const pstring &hint_name) { const auto name = build_fqn(object_name) + hint_name; if (!m_abstract.m_hints.insert({name, false}).second) @@ -165,12 +180,13 @@ namespace netlist void nlparse_t::register_link(const pstring &sin, const pstring &sout) { - register_link_fqn(build_fqn(plib::trim(sin)), build_fqn(plib::trim(sout))); + register_link_fqn(build_fqn(plib::trim(sin)), + build_fqn(plib::trim(sout))); } void nlparse_t::register_link_arr(const pstring &terms) { - const auto list(plib::psplit(terms,pstring(", "))); + const auto list(plib::psplit(terms, pstring(", "))); if (list.size() < 2) { log().fatal(MF_NET_C_NEEDS_AT_LEAST_2_TERMINAL()); @@ -184,10 +200,9 @@ namespace netlist void nlparse_t::include(const pstring &netlist_name) { - if (m_sources.for_all<source_netlist_t>([this, &netlist_name] (source_netlist_t *src) - { - return src->parse(*this, netlist_name); - })) + if (m_sources.for_all<source_netlist_t>( + [this, &netlist_name](source_netlist_t *src) + { return src->parse(*this, netlist_name); })) return; log().fatal(MF_NOT_FOUND_IN_SOURCE_COLLECTION(netlist_name)); throw nl_exception(MF_NOT_FOUND_IN_SOURCE_COLLECTION(netlist_name)); @@ -196,18 +211,16 @@ namespace netlist void nlparse_t::namespace_push(const pstring &aname) { if (m_namespace_stack.empty()) - //m_namespace_stack.push(netlist().name() + "." + aname); + // m_namespace_stack.push(netlist().name() + "." + aname); m_namespace_stack.push(aname); else m_namespace_stack.push(m_namespace_stack.top() + "." + aname); } - void nlparse_t::namespace_pop() - { - m_namespace_stack.pop(); - } + void nlparse_t::namespace_pop() { m_namespace_stack.pop(); } - void nlparse_t::register_param_fp(const pstring ¶m, const nl_fptype value) + void + nlparse_t::register_param_fp(const pstring ¶m, const nl_fptype value) { if (plib::abs(value - plib::floor(value)) > nlconst::magic(1e-30) || plib::abs(value) > nlconst::magic(1e9)) @@ -233,7 +246,8 @@ namespace netlist if (!m_abstract.m_param_values.insert({fqn, val}).second) { log().fatal(MF_ADDING_PARAMETER_1_TO_PARAMETER_LIST(param)); - throw nl_exception(MF_ADDING_PARAMETER_1_TO_PARAMETER_LIST(param)); + throw nl_exception( + MF_ADDING_PARAMETER_1_TO_PARAMETER_LIST(param)); } } else @@ -241,14 +255,15 @@ namespace netlist if (idx->second.find("$(") == pstring::npos) { // There may be reason ... so make it an INFO - log().info(MI_OVERWRITING_PARAM_1_OLD_2_NEW_3(fqn, - idx->second, val)); + log().info( + MI_OVERWRITING_PARAM_1_OLD_2_NEW_3(fqn, idx->second, val)); } m_abstract.m_param_values[fqn] = val; } } - void nlparse_t::register_default_param(const pstring &name, const pstring &def) + void + nlparse_t::register_default_param(const pstring &name, const pstring &def) { // strip " from stringified strings pstring val(def); @@ -256,7 +271,8 @@ namespace netlist val = def.substr(1, def.length() - 2); // Replace "@." with the current namespace val = plib::replace_all(val, "@.", namespace_prefix()); - m_abstract.m_default_params.emplace_back(namespace_prefix() + name, val); + m_abstract.m_default_params.emplace_back(namespace_prefix() + name, + val); } factory::list_t &nlparse_t::factory() noexcept @@ -269,14 +285,16 @@ namespace netlist return m_abstract.m_factory; } - - void nlparse_t::register_lib_entry(const pstring &name, const pstring &def_params, plib::source_location &&loc) + void nlparse_t::register_lib_entry(const pstring & name, + const pstring & def_params, + plib::source_location &&loc) { - factory().add(plib::make_unique<factory::library_element_t, host_arena>(name, factory::properties(def_params, std::move(loc)))); + factory().add(plib::make_unique<factory::library_element_t, host_arena>( + name, factory::properties(def_params, std::move(loc)))); } - void nlparse_t::register_frontier(const pstring &attach, const pstring &r_IN, - const pstring &r_OUT) + void nlparse_t::register_frontier(const pstring &attach, + const pstring &r_IN, const pstring &r_OUT) { pstring frontier_name = plib::pfmt("frontier_{1}")(m_frontier_cnt); m_frontier_cnt++; @@ -286,8 +304,8 @@ namespace netlist register_link(frontier_name + ".G", "GND"); pstring attach_fully_qualified_name = build_fqn(attach); pstring front_fqn = build_fqn(frontier_name); - bool found = false; - for (auto & link : m_abstract.m_links) + bool found = false; + for (auto &link : m_abstract.m_links) { if (link.first == attach_fully_qualified_name) { @@ -313,9 +331,11 @@ namespace netlist register_source<netlist::source_proc_t>(name, func); } - void nlparse_t::truth_table_create(tt_desc &desc, const pstring &def_params, plib::source_location &&loc) + void nlparse_t::truth_table_create(tt_desc &desc, const pstring &def_params, + plib::source_location &&loc) { - auto fac = factory::truth_table_create(desc, netlist::factory::properties(def_params, std::move(loc))); + auto fac = factory::truth_table_create( + desc, netlist::factory::properties(def_params, std::move(loc))); factory().add(std::move(fac)); } @@ -329,7 +349,8 @@ namespace netlist return namespace_prefix() + obj_name; } - void nlparse_t::register_alias_no_fqn(const pstring &alias, const pstring &out) + void + nlparse_t::register_alias_no_fqn(const pstring &alias, const pstring &out) { if (!m_abstract.m_alias.insert({alias, out}).second) { @@ -353,13 +374,15 @@ namespace netlist return false; } - bool nlparse_t::parse_tokens(const plib::detail::token_store_t &tokens, const pstring &name) + bool nlparse_t::parse_tokens(const plib::detail::token_store_t &tokens, + const pstring & name) { parser_t parser(*this); return parser.parse(tokens, name); } - bool nlparse_t::parse_stream(plib::istream_uptr &&in_stream, const pstring &name) + bool + nlparse_t::parse_stream(plib::istream_uptr &&in_stream, const pstring &name) { #if 0 auto key = in_stream.filename(); @@ -380,12 +403,14 @@ namespace netlist } #else const auto filename = in_stream.filename(); - auto preprocessed = std::make_unique<std::stringstream>(putf8string( - plib::ppreprocessor(m_includes, &m_defines).process(std::move(in_stream), filename))); + auto preprocessed = std::make_unique<std::stringstream>( + putf8string(plib::ppreprocessor(m_includes, &m_defines) + .process(std::move(in_stream), filename))); parser_t::token_store_t st; - parser_t parser(*this); - parser.parse_tokens(plib::istream_uptr(std::move(preprocessed), filename), st); + parser_t parser(*this); + parser.parse_tokens( + plib::istream_uptr(std::move(preprocessed), filename), st); return parser.parse(st, name); #endif } @@ -394,12 +419,13 @@ namespace netlist { auto p = define.find('='); if (p != pstring::npos) - add_define(plib::left(define, p), define.substr(p+1)); + add_define(plib::left(define, p), define.substr(p + 1)); else add_define(define, "1"); } - void nlparse_t::register_dynamic_log_devices(const std::vector<pstring> &log_list) + void nlparse_t::register_dynamic_log_devices( + const std::vector<pstring> &log_list) { log().debug("Creating dynamic logs ..."); for (const pstring &ll : log_list) @@ -415,13 +441,16 @@ namespace netlist { // FIXME: check use_cases - remove_connections may be dead pstring pin_fully_qualified_name = build_fqn(pin); - bool found = false; + bool found = false; - for (auto link = m_abstract.m_links.begin(); link != m_abstract.m_links.end(); ) + for (auto link = m_abstract.m_links.begin(); + link != m_abstract.m_links.end();) { - if ((link->first == pin_fully_qualified_name) || (link->second == pin_fully_qualified_name)) + if ((link->first == pin_fully_qualified_name) + || (link->second == pin_fully_qualified_name)) { - log().verbose("removing connection: {1} <==> {2}\n", link->first, link->second); + log().verbose("removing connection: {1} <==> {2}\n", + link->first, link->second); link = m_abstract.m_links.erase(link); found = true; } @@ -445,15 +474,15 @@ namespace netlist if (!m_abstract.m_models.insert({model, def}).second) { // FIXME: Add an directive MODEL_OVERWRITE to netlist language - //throw nl_exception(MF_MODEL_ALREADY_EXISTS_1(model_in)); + // throw nl_exception(MF_MODEL_ALREADY_EXISTS_1(model_in)); log().info(MI_MODEL_OVERWRITE_1(model, model_in)); m_abstract.m_models[model] = def; } } - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- // Sources - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- plib::istream_uptr nlparse_t::get_data_stream(const pstring &name) { @@ -464,17 +493,17 @@ namespace netlist return plib::istream_uptr(); } - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- // setup_t - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- setup_t::setup_t(netlist_state_t &nlstate) - : m_abstract(nlstate.log()) - , m_parser(nlstate.log(), m_abstract) - , m_nlstate(nlstate) - , m_models(m_abstract.m_models) // FIXME : parse abstract_t only - , m_netlist_params(nullptr) - , m_proxy_cnt(0) + : m_abstract(nlstate.log()) + , m_parser(nlstate.log(), m_abstract) + , m_nlstate(nlstate) + , m_models(m_abstract.m_models) // FIXME : parse abstract_t only + , m_netlist_params(nullptr) + , m_proxy_cnt(0) { } @@ -482,33 +511,32 @@ namespace netlist { switch (in.type()) { - case detail::terminal_type::TERMINAL: - return "TERMINAL"; - case detail::terminal_type::INPUT: - return "INPUT"; - case detail::terminal_type::OUTPUT: - return "OUTPUT"; + case detail::terminal_type::TERMINAL: return "TERMINAL"; + case detail::terminal_type::INPUT: return "INPUT"; + case detail::terminal_type::OUTPUT: return "OUTPUT"; } return "Error"; // Tease gcc } - pstring setup_t::get_initial_param_val(const pstring &name, const pstring &def) const + pstring setup_t::get_initial_param_val(const pstring &name, + const pstring &def) const { - // When `get_intial_param_val` is called the parameter `<name>` is already registered - // and the value `(value_string())` is set to the default value, e.g. "74XX" - // If thus `$(IC5E.A.MODEL)` is given for `name=="IC5E.A.MODEL"` `value_string()` below - // will return the default. - // FIXME: It may be more explicit and stable to test if pattern==name and return - // `def` in this case. + // When `get_intial_param_val` is called the parameter `<name>` is + // already registered and the value `(value_string())` is set to the + // default value, e.g. "74XX" If thus `$(IC5E.A.MODEL)` is given for + // `name=="IC5E.A.MODEL"` `value_string()` below will return the + // default. + // FIXME: It may be more explicit and stable to test if pattern==name + // and return `def` in this case. - auto i = m_abstract.m_param_values.find(name); - auto found_pat(false); + auto i = m_abstract.m_param_values.find(name); + auto found_pat(false); pstring v = (i == m_abstract.m_param_values.end()) ? def : i->second; do { found_pat = false; - auto sp(plib::psplit(v, std::vector<pstring>({"$(", ")"}))); + auto sp(plib::psplit(v, std::vector<pstring>({"$(", ")"}))); std::size_t p(0); v = ""; while (p < sp.size()) @@ -545,23 +573,31 @@ namespace netlist log().debug("{1} {2}\n", termtype_as_str(term), term.name()); if (!m_terminals.insert({term.name(), &term}).second) { - log().fatal(MF_ADDING_1_2_TO_TERMINAL_LIST(termtype_as_str(term), term.name())); - throw nl_exception(MF_ADDING_1_2_TO_TERMINAL_LIST(termtype_as_str(term), term.name())); + log().fatal(MF_ADDING_1_2_TO_TERMINAL_LIST(termtype_as_str(term), + term.name())); + throw nl_exception(MF_ADDING_1_2_TO_TERMINAL_LIST( + termtype_as_str(term), term.name())); } } - void setup_t::register_term(terminal_t &term, terminal_t *other_term, const std::array<terminal_t *, 2> &splitter_terms) + void + setup_t::register_term(terminal_t &term, terminal_t *other_term, + const std::array<terminal_t *, 2> &splitter_terms) { this->register_term(term); - m_connected_terminals.insert({&term, {other_term, splitter_terms[0], splitter_terms[1], nullptr}}); + m_connected_terminals.insert( + {&term, + {other_term, splitter_terms[0], splitter_terms[1], nullptr}}); } void setup_t::register_param_t(param_t ¶m) { - if (!m_params.insert({param.name(), param_ref_t(param.device(), param)}).second) + if (!m_params.insert({param.name(), param_ref_t(param.device(), param)}) + .second) { log().fatal(MF_ADDING_PARAMETER_1_TO_PARAMETER_LIST(param.name())); - throw nl_exception(MF_ADDING_PARAMETER_1_TO_PARAMETER_LIST(param.name())); + throw nl_exception( + MF_ADDING_PARAMETER_1_TO_PARAMETER_LIST(param.name())); } } @@ -571,7 +607,8 @@ namespace netlist pstring ret; // FIXME: Detect endless loop - do { + do + { ret = temp; auto p = m_abstract.m_alias.find(ret); temp = (p != m_abstract.m_alias.end() ? p->second : ""); @@ -587,7 +624,8 @@ namespace netlist pstring ret; // FIXME: Detect endless loop - do { + do + { ret = temp; temp = ""; for (const auto &e : m_abstract.m_alias) @@ -605,32 +643,35 @@ namespace netlist return ret; } - std::vector<pstring> setup_t::get_terminals_for_device_name(const pstring &devname) const + std::vector<pstring> + setup_t::get_terminals_for_device_name(const pstring &devname) const { std::vector<pstring> terms; - for (const auto & t : m_terminals) + for (const auto &t : m_terminals) { if (plib::startsWith(t.second->name(), devname)) { - pstring tn(t.second->name().substr(devname.length()+1)); + pstring tn(t.second->name().substr(devname.length() + 1)); if (tn.find('.') == pstring::npos) terms.push_back(tn); } } - for (const auto & t : m_abstract.m_alias) + for (const auto &t : m_abstract.m_alias) { if (plib::startsWith(t.first, devname)) { - pstring tn(t.first.substr(devname.length()+1)); + pstring tn(t.first.substr(devname.length() + 1)); if (tn.find('.') == pstring::npos) { terms.push_back(tn); pstring resolved = resolve_alias(t.first); if (resolved != t.first) { - auto found = std::find(terms.begin(), terms.end(), resolved.substr(devname.length()+1)); - if (found!=terms.end()) + auto found = std::find( + terms.begin(), terms.end(), + resolved.substr(devname.length() + 1)); + if (found != terms.end()) terms.erase(found); } } @@ -639,10 +680,11 @@ namespace netlist return terms; } - detail::core_terminal_t *setup_t::find_terminal(const pstring &terminal_in, bool required) const + detail::core_terminal_t * + setup_t::find_terminal(const pstring &terminal_in, bool required) const { const pstring &tname = resolve_alias(terminal_in); - auto ret = m_terminals.find(tname); + auto ret = m_terminals.find(tname); // look for default if (ret == m_terminals.end()) { @@ -650,7 +692,9 @@ namespace netlist ret = m_terminals.find(tname + ".Q"); } - detail::core_terminal_t *term = (ret == m_terminals.end() ? nullptr : ret->second); + detail::core_terminal_t *term = (ret == m_terminals.end() + ? nullptr + : ret->second); if (term == nullptr && required) { @@ -665,11 +709,12 @@ namespace netlist return term; } - detail::core_terminal_t *setup_t::find_terminal(const pstring &terminal_in, - detail::terminal_type atype, bool required) const + detail::core_terminal_t * + setup_t::find_terminal(const pstring & terminal_in, + detail::terminal_type atype, bool required) const { const pstring &tname = resolve_alias(terminal_in); - auto ret = m_terminals.find(tname); + auto ret = m_terminals.find(tname); // look for default if (ret == m_terminals.end() && atype == detail::terminal_type::OUTPUT) { @@ -681,14 +726,17 @@ namespace netlist log().fatal(MF_TERMINAL_1_2_NOT_FOUND(terminal_in, tname)); throw nl_exception(MF_TERMINAL_1_2_NOT_FOUND(terminal_in, tname)); } - detail::core_terminal_t *term = (ret == m_terminals.end() ? nullptr : ret->second); + detail::core_terminal_t *term = (ret == m_terminals.end() + ? nullptr + : ret->second); if (term != nullptr && term->type() != atype) { if (required) { log().fatal(MF_OBJECT_1_2_WRONG_TYPE(terminal_in, tname)); - throw nl_exception(MF_OBJECT_1_2_WRONG_TYPE(terminal_in, tname)); + throw nl_exception( + MF_OBJECT_1_2_WRONG_TYPE(terminal_in, tname)); } term = nullptr; @@ -702,30 +750,34 @@ namespace netlist param_ref_t setup_t::find_param(const pstring ¶m_in) const { const pstring resolved_param_name(resolve_alias(param_in)); - auto ret(m_params.find(resolved_param_name)); + auto ret(m_params.find(resolved_param_name)); if (ret == m_params.end()) { - log().fatal(MF_PARAMETER_1_2_NOT_FOUND(param_in, resolved_param_name)); - throw nl_exception(MF_PARAMETER_1_2_NOT_FOUND(param_in, resolved_param_name)); + log().fatal( + MF_PARAMETER_1_2_NOT_FOUND(param_in, resolved_param_name)); + throw nl_exception( + MF_PARAMETER_1_2_NOT_FOUND(param_in, resolved_param_name)); } return ret->second; } - //NOLINTNEXTLINE(misc-no-recursion) - devices::nld_base_proxy *setup_t::get_d_a_proxy(const detail::core_terminal_t &out) + // NOLINTNEXTLINE(misc-no-recursion) + devices::nld_base_proxy * + setup_t::get_d_a_proxy(const detail::core_terminal_t &out) { - gsl_Expects(out.is_logic()); - - const auto &out_cast = dynamic_cast<const logic_output_t &>(out); auto iter_proxy(m_proxies.find(&out)); if (iter_proxy != m_proxies.end()) return iter_proxy->second; // create a new one ... + + auto out_cast = plib::dynamic_downcast<const logic_output_t *>(out); + nl_assert_always(bool(out_cast), "Not able to cast to logic_output_t&"); + pstring x = plib::pfmt("proxy_da_{1}_{2}")(out.name())(m_proxy_cnt); - auto new_proxy = - out_cast.logic_family()->create_d_a_proxy(m_nlstate, x, &out_cast); + auto new_proxy = (*out_cast)->logic_family()->create_d_a_proxy( + m_nlstate, x, *out_cast); m_proxy_cnt++; // connect all existing terminals to new net @@ -734,15 +786,15 @@ namespace netlist // remove all terminals from out.net() out.net().remove_all_terminals(); - for (detail::core_terminal_t * p : temp_terminals) + for (detail::core_terminal_t *p : temp_terminals) { p->clear_net(); // de-link from all nets ... if (!connect(new_proxy->proxy_term(), *p)) { - log().fatal(MF_CONNECTING_1_TO_2( - new_proxy->proxy_term().name(), (*p).name())); + log().fatal(MF_CONNECTING_1_TO_2(new_proxy->proxy_term().name(), + (*p).name())); throw nl_exception(MF_CONNECTING_1_TO_2( - new_proxy->proxy_term().name(), (*p).name())); + new_proxy->proxy_term().name(), (*p).name())); } } @@ -754,15 +806,16 @@ namespace netlist m_nlstate.register_device(new_proxy->name(), std::move(new_proxy)); return proxy; - } - //NOLINTNEXTLINE(misc-no-recursion) - devices::nld_base_proxy *setup_t::get_a_d_proxy(detail::core_terminal_t &inp) + // NOLINTNEXTLINE(misc-no-recursion) + devices::nld_base_proxy * + setup_t::get_a_d_proxy(detail::core_terminal_t &inp) { gsl_Expects(inp.is_logic()); - const auto &logic_input_terminal = dynamic_cast<const logic_input_t &>(inp); + const auto &logic_input_terminal = dynamic_cast<const logic_input_t &>( + inp); auto iter_proxy(m_proxies.find(&inp)); @@ -770,10 +823,9 @@ namespace netlist return iter_proxy->second; log().debug("connect_terminal_input: connecting proxy\n"); - auto new_proxy = - logic_input_terminal.logic_family()->create_a_d_proxy(m_nlstate, - plib::pfmt("proxy_ad_{1}_{2}")(inp.name())(m_proxy_cnt), - &logic_input_terminal); + auto new_proxy = logic_input_terminal.logic_family()->create_a_d_proxy( + m_nlstate, plib::pfmt("proxy_ad_{1}_{2}")(inp.name())(m_proxy_cnt), + &logic_input_terminal); auto *ret(new_proxy.get()); @@ -790,7 +842,7 @@ namespace netlist inp.net().remove_all_terminals(); - for (detail::core_terminal_t * p : temp_terminals) + for (detail::core_terminal_t *p : temp_terminals) { // inp may already belongs to the logic net. Thus skip it here. // It will be removed by the clear further down. @@ -800,9 +852,9 @@ namespace netlist if (!connect(ret->proxy_term(), *p)) { log().fatal(MF_CONNECTING_1_TO_2( - ret->proxy_term().name(), (*p).name())); + ret->proxy_term().name(), (*p).name())); throw nl_exception(MF_CONNECTING_1_TO_2( - ret->proxy_term().name(), (*p).name())); + ret->proxy_term().name(), (*p).name())); } } } @@ -813,19 +865,20 @@ namespace netlist return ret; } - detail::core_terminal_t &setup_t::resolve_proxy(detail::core_terminal_t &term) + detail::core_terminal_t & + setup_t::resolve_proxy(detail::core_terminal_t &term) { if (term.is_logic()) { const auto &out = dynamic_cast<const logic_t &>(term); - auto iter_proxy(m_proxies.find(&out)); + auto iter_proxy(m_proxies.find(&out)); if (iter_proxy != m_proxies.end()) return iter_proxy->second->proxy_term(); } return term; } - //NOLINTNEXTLINE(misc-no-recursion) + // NOLINTNEXTLINE(misc-no-recursion) void setup_t::merge_nets(detail::net_t &this_net, detail::net_t &other_net) { log().debug("merging nets ...\n"); @@ -837,8 +890,10 @@ namespace netlist if (this_net.is_rail_net() && other_net.is_rail_net()) { - log().fatal(MF_MERGE_RAIL_NETS_1_AND_2(this_net.name(), other_net.name())); - throw nl_exception(MF_MERGE_RAIL_NETS_1_AND_2(this_net.name(), other_net.name())); + log().fatal( + MF_MERGE_RAIL_NETS_1_AND_2(this_net.name(), other_net.name())); + throw nl_exception( + MF_MERGE_RAIL_NETS_1_AND_2(this_net.name(), other_net.name())); } if (other_net.is_rail_net()) @@ -852,90 +907,111 @@ namespace netlist } } - //NOLINTNEXTLINE(misc-no-recursion) - void setup_t::connect_input_output(detail::core_terminal_t &in, detail::core_terminal_t &out) + // NOLINTNEXTLINE(misc-no-recursion) + void setup_t::connect_input_output(detail::core_terminal_t &input, + detail::core_terminal_t &output) { - if (out.is_analog() && in.is_logic()) + if (input.has_net() && input.net().is_rail_net()) + { + log().fatal(MF_INPUT_1_ALREADY_CONNECTED(input.name())); + throw nl_exception(MF_INPUT_1_ALREADY_CONNECTED(input.name())); + } + if (output.is_analog() && input.is_logic()) { - auto *proxy = get_a_d_proxy(in); + auto *proxy = get_a_d_proxy(input); - out.net().add_terminal(proxy->proxy_term()); + output.net().add_terminal(proxy->proxy_term()); } - else if (out.is_logic() && in.is_analog()) + else if (output.is_logic() && input.is_analog()) { - devices::nld_base_proxy *proxy = get_d_a_proxy(out); + devices::nld_base_proxy *proxy = get_d_a_proxy(output); - connect_terminals(proxy->proxy_term(), in); - //proxy->out().net().register_con(in); + connect_terminals(proxy->proxy_term(), input); } else { - if (in.has_net()) - merge_nets(out.net(), in.net()); + if (input.has_net()) + merge_nets(output.net(), input.net()); + else if (output.has_net()) + output.net().add_terminal(input); else - out.net().add_terminal(in); + { + log().fatal( + ME_TERMINALS_1_2_WITHOUT_NET(input.name(), output.name())); + throw nl_exception( + ME_TERMINALS_1_2_WITHOUT_NET(input.name(), output.name())); + } } } - //NOLINTNEXTLINE(misc-no-recursion) - void setup_t::connect_terminal_input(terminal_t &term, detail::core_terminal_t &inp) + // NOLINTNEXTLINE(misc-no-recursion) + void setup_t::connect_terminal_input(detail::core_terminal_t &terminal, + detail::core_terminal_t &input) { - if (inp.is_analog()) + if (input.is_analog()) { - connect_terminals(inp, term); + connect_terminals(input, terminal); } - else if (inp.is_logic()) + else if (input.is_logic()) { - log().verbose("connect terminal {1} (in, {2}) to {3}\n", inp.name(), - inp.is_analog() ? "analog" : inp.is_logic() ? "logic" : "?", term.name()); - auto *proxy = get_a_d_proxy(inp); - - //out.net().register_con(proxy->proxy_term()); - connect_terminals(term, proxy->proxy_term()); + log().verbose("connect terminal {1} (in, {2}) to {3}\n", + input.name(), + input.is_analog() ? "analog" + : input.is_logic() ? "logic" + : "?", + terminal.name()); + auto *proxy = get_a_d_proxy(input); + // out.net().register_con(proxy->proxy_term()); + connect_terminals(terminal, proxy->proxy_term()); } else { - log().fatal(MF_OBJECT_INPUT_TYPE_1(inp.name())); - throw nl_exception(MF_OBJECT_INPUT_TYPE_1(inp.name())); + log().fatal(MF_OBJECT_INPUT_TYPE_1(input.name())); + throw nl_exception(MF_OBJECT_INPUT_TYPE_1(input.name())); } } - //NOLINTNEXTLINE(misc-no-recursion) - void setup_t::connect_terminal_output(terminal_t &in, detail::core_terminal_t &out) + // NOLINTNEXTLINE(misc-no-recursion) + void setup_t::connect_terminal_output(detail::core_terminal_t &terminal, + detail::core_terminal_t &output) { - if (out.is_analog()) + if (output.is_analog()) { - log().debug("connect_terminal_output: {1} {2}\n", in.name(), out.name()); + log().debug("connect_terminal_output: {1} {2}\n", terminal.name(), + output.name()); // no proxy needed, just merge existing terminal net - if (in.has_net()) + if (terminal.has_net()) { - if (&out.net() != &in.net()) - merge_nets(out.net(), in.net()); + if (&output.net() != &terminal.net()) + merge_nets(output.net(), terminal.net()); else - // Only an info - some ICs (CD4538) connect pins internally to GND - // and the schematics again externally. This will cause this warning. + // Only an info - some ICs (CD4538) connect pins internally + // to GND and the schematics again externally. This will + // cause this warning. // FIXME: Add a hint to suppress the warning. - log().info(MI_CONNECTING_1_TO_2_SAME_NET(in.name(), out.name(), in.net().name())); + log().info(MI_CONNECTING_1_TO_2_SAME_NET( + terminal.name(), output.name(), terminal.net().name())); } else - out.net().add_terminal(in); + output.net().add_terminal(terminal); } - else if (out.is_logic()) + else if (output.is_logic()) { log().debug("connect_terminal_output: connecting proxy\n"); - devices::nld_base_proxy *proxy = get_d_a_proxy(out); + devices::nld_base_proxy *proxy = get_d_a_proxy(output); - connect_terminals(proxy->proxy_term(), in); + connect_terminals(proxy->proxy_term(), terminal); } else { - log().fatal(MF_OBJECT_OUTPUT_TYPE_1(out.name())); - throw nl_exception(MF_OBJECT_OUTPUT_TYPE_1(out.name())); + log().fatal(MF_OBJECT_OUTPUT_TYPE_1(output.name())); + throw nl_exception(MF_OBJECT_OUTPUT_TYPE_1(output.name())); } } - void setup_t::connect_terminals(detail::core_terminal_t &t1,detail::core_terminal_t &t2) + void setup_t::connect_terminals(detail::core_terminal_t &t1, + detail::core_terminal_t &t2) { if (t1.has_net() && t2.has_net()) { @@ -956,7 +1032,8 @@ namespace netlist { log().debug("adding analog net ...\n"); // FIXME: Nets should have a unique name - auto new_net_uptr = plib::make_owned<analog_net_t>(nlstate().pool(), m_nlstate,"net." + t1.name()); + auto new_net_uptr = plib::make_owned<analog_net_t>( + nlstate().pool(), m_nlstate, "net." + t1.name()); auto *new_net_ptr = new_net_uptr.get(); m_nlstate.register_net(std::move(new_net_uptr)); t1.set_net(new_net_ptr); @@ -965,35 +1042,48 @@ namespace netlist } } - //NOLINTNEXTLINE(misc-no-recursion) - bool setup_t::connect_input_input(detail::core_terminal_t &t1, detail::core_terminal_t &t2) + // NOLINTNEXTLINE(misc-no-recursion) + bool setup_t::connect_input_input(detail::core_terminal_t &input1, + detail::core_terminal_t &input2) { bool ret = false; - if (t1.has_net()) - { - if (t1.net().is_rail_net()) - ret = connect(t2, t1.net().rail_terminal()); + if (input1.has_net()) // if input 1 already has a net + { + if (input1.net().is_rail_net()) // and the net is a rail net + ret = connect(input2, input1.net().rail_terminal()); // try to + // connect + // input 2 + // to rail + // terminal + // of input + // 1 net if (!ret) { - for (detail::core_terminal_t * t : t1.net().core_terms_copy()) + // the above was not successfull - try to connect input2 to + // TERMINAL type terminals of input 1 net's terminals + for (detail::core_terminal_t *t : + input1.net().core_terms_copy()) { if (t->is_type(detail::terminal_type::TERMINAL)) - ret = connect(t2, *t); + ret = connect(input2, *t); if (ret) break; } } } - if (!ret && t2.has_net()) + // FIXME: We could use a helper connect_input_input_helper(input2, + // input1) here. + if (!ret && input2.has_net()) { - if (t2.net().is_rail_net()) - ret = connect(t1, t2.net().rail_terminal()); + if (input2.net().is_rail_net()) + ret = connect(input1, input2.net().rail_terminal()); if (!ret) { - for (detail::core_terminal_t * t : t2.net().core_terms_copy()) + for (detail::core_terminal_t *t : + input2.net().core_terms_copy()) { if (t->is_type(detail::terminal_type::TERMINAL)) - ret = connect(t1, *t); + ret = connect(input1, *t); if (ret) break; } @@ -1002,59 +1092,67 @@ namespace netlist return ret; } - //NOLINTNEXTLINE(misc-no-recursion) - bool setup_t::connect(detail::core_terminal_t &t1_in, detail::core_terminal_t &t2_in) + // NOLINTNEXTLINE(misc-no-recursion) + bool setup_t::connect(detail::core_terminal_t &t1_in, + detail::core_terminal_t &t2_in) { + using namespace detail; + log().debug("Connecting {1} to {2}\n", t1_in.name(), t2_in.name()); detail::core_terminal_t &t1 = resolve_proxy(t1_in); detail::core_terminal_t &t2 = resolve_proxy(t2_in); - bool ret = true; + detail::terminal_type t1_type = t1.type(); + detail::terminal_type t2_type = t2.type(); + bool ret = true; - if (t1.is_type(detail::terminal_type::OUTPUT) && t2.is_type(detail::terminal_type::INPUT)) + switch (t1_type) { - if (t2.has_net() && t2.net().is_rail_net()) + case terminal_type::TERMINAL: { - log().fatal(MF_INPUT_1_ALREADY_CONNECTED(t2.name())); - throw nl_exception(MF_INPUT_1_ALREADY_CONNECTED(t2.name())); + switch (t2_type) + { + case terminal_type::TERMINAL: + connect_terminals(t1, t2); + break; + case terminal_type::INPUT: + connect_terminal_input(t1, t2); + break; + case terminal_type::OUTPUT: + connect_terminal_output(t1, t2); + break; + } + break; } - connect_input_output(t2, t1); - } - else if (t1.is_type(detail::terminal_type::INPUT) && t2.is_type(detail::terminal_type::OUTPUT)) - { - if (t1.has_net() && t1.net().is_rail_net()) + case terminal_type::INPUT: { - log().fatal(MF_INPUT_1_ALREADY_CONNECTED(t1.name())); - throw nl_exception(MF_INPUT_1_ALREADY_CONNECTED(t1.name())); + switch (t2_type) + { + case terminal_type::TERMINAL: + connect_terminal_input(t2, t1); + break; + case terminal_type::INPUT: + ret = connect_input_input(t1, t2); + break; + case terminal_type::OUTPUT: + connect_input_output(t1, t2); + break; + } + break; + } + case terminal_type::OUTPUT: + { + switch (t2_type) + { + case terminal_type::TERMINAL: + connect_terminal_output(t2, t1); + break; + case terminal_type::INPUT: + connect_input_output(t2, t1); + break; + case terminal_type::OUTPUT: ret = false; break; + } + break; } - connect_input_output(t1, t2); - } - else if (t1.is_type(detail::terminal_type::OUTPUT) && t2.is_type(detail::terminal_type::TERMINAL)) - { - connect_terminal_output(dynamic_cast<terminal_t &>(t2), t1); - } - else if (t1.is_type(detail::terminal_type::TERMINAL) && t2.is_type(detail::terminal_type::OUTPUT)) - { - connect_terminal_output(dynamic_cast<terminal_t &>(t1), t2); - } - else if (t1.is_type(detail::terminal_type::INPUT) && t2.is_type(detail::terminal_type::TERMINAL)) - { - connect_terminal_input(dynamic_cast<terminal_t &>(t2), t1); - } - else if (t1.is_type(detail::terminal_type::TERMINAL) && t2.is_type(detail::terminal_type::INPUT)) - { - connect_terminal_input(dynamic_cast<terminal_t &>(t1), t2); - } - else if (t1.is_type(detail::terminal_type::TERMINAL) && t2.is_type(detail::terminal_type::TERMINAL)) - { - connect_terminals(dynamic_cast<terminal_t &>(t1), dynamic_cast<terminal_t &>(t2)); - } - else if (t1.is_type(detail::terminal_type::INPUT) && t2.is_type(detail::terminal_type::INPUT)) - { - ret = connect_input_input(t1, t2); - } - else - { - ret = false; } return ret; } @@ -1068,7 +1166,7 @@ namespace netlist // after all other terminals were connected. unsigned tries = m_netlist_params->m_max_link_loops(); - #if 0 +#if 0 // This code fails for some netlists when the element at position 0 // is deleted. It will fail somewhere deep in std::pair releasing // std::string called from erase. @@ -1112,30 +1210,35 @@ namespace netlist } tries--; } - #else +#else while (!m_abstract.m_links.empty() && tries > 0) { - for (std::size_t i = 0; i < m_abstract.m_links.size(); ) + for (std::size_t i = 0; i < m_abstract.m_links.size();) { - const pstring t1s(m_abstract.m_links[i].first); - const pstring t2s(m_abstract.m_links[i].second); + const pstring t1s(m_abstract.m_links[i].first); + const pstring t2s(m_abstract.m_links[i].second); detail::core_terminal_t *t1 = find_terminal(t1s); detail::core_terminal_t *t2 = find_terminal(t2s); if (connect(*t1, *t2)) - m_abstract.m_links.erase(m_abstract.m_links.begin() + plib::narrow_cast<std::ptrdiff_t>(i)); + m_abstract.m_links.erase( + m_abstract.m_links.begin() + + plib::narrow_cast<std::ptrdiff_t>(i)); else i++; } tries--; } - #endif +#endif if (tries == 0) { - for (auto & link : m_abstract.m_links) - log().warning(MF_CONNECTING_1_TO_2(de_alias(link.first), de_alias(link.second))); + for (auto &link : m_abstract.m_links) + log().warning(MF_CONNECTING_1_TO_2(de_alias(link.first), + de_alias(link.second))); - log().fatal(MF_LINK_TRIES_EXCEEDED(m_netlist_params->m_max_link_loops())); - throw nl_exception(MF_LINK_TRIES_EXCEEDED(m_netlist_params->m_max_link_loops())); + log().fatal( + MF_LINK_TRIES_EXCEEDED(m_netlist_params->m_max_link_loops())); + throw nl_exception( + MF_LINK_TRIES_EXCEEDED(m_netlist_params->m_max_link_loops())); } log().verbose("deleting empty nets ..."); @@ -1147,11 +1250,13 @@ namespace netlist bool err(false); log().verbose("looking for terminals not connected ..."); - for (auto & i : m_terminals) + for (auto &i : m_terminals) { detail::core_terminal_t *term = i.second; - const pstring name_da = de_alias(term->name()); - bool is_nc_pin(dynamic_cast< devices::NETLIB_NAME(nc_pin) *>(&term->device()) != nullptr); + const pstring name_da = de_alias(term->name()); + bool is_nc_pin( + dynamic_cast<devices::NETLIB_NAME(nc_pin) *>(&term->device()) + != nullptr); bool is_nc_flagged(false); auto hnc = m_abstract.m_hints.find(name_da + sHINT_NC); @@ -1178,16 +1283,19 @@ namespace netlist else if (term->net().core_terms_empty()) { if (term->is_logic_input()) - log().warning(MW_LOGIC_INPUT_1_WITHOUT_CONNECTIONS(name_da)); + log().warning( + MW_LOGIC_INPUT_1_WITHOUT_CONNECTIONS(name_da)); else if (term->is_logic_output()) { if (!is_nc_flagged) - log().info(MI_LOGIC_OUTPUT_1_WITHOUT_CONNECTIONS(name_da)); + log().info( + MI_LOGIC_OUTPUT_1_WITHOUT_CONNECTIONS(name_da)); } else if (term->is_analog_output()) { if (!is_nc_flagged) - log().info(MI_ANALOG_OUTPUT_1_WITHOUT_CONNECTIONS(name_da)); + log().info( + MI_ANALOG_OUTPUT_1_WITHOUT_CONNECTIONS(name_da)); } else log().warning(MW_TERMINAL_1_WITHOUT_CONNECTIONS(name_da)); @@ -1195,7 +1303,7 @@ namespace netlist } log().verbose("checking tristate consistency ..."); - for (auto & i : m_terminals) + for (auto &i : m_terminals) { detail::core_terminal_t *term = i.second; if (term->is_tristate_output()) @@ -1206,12 +1314,14 @@ namespace netlist if (iter_proxy == m_proxies.end() && !tri.is_force_logic()) { - log().error(ME_TRISTATE_NO_PROXY_FOUND_2(term->name(), term->device().name())); + log().error(ME_TRISTATE_NO_PROXY_FOUND_2( + term->name(), term->device().name())); err = true; } else if (iter_proxy != m_proxies.end() && tri.is_force_logic()) { - log().error(ME_TRISTATE_PROXY_FOUND_2(term->name(), term->device().name())); + log().error(ME_TRISTATE_PROXY_FOUND_2( + term->name(), term->device().name())); err = true; } } @@ -1221,7 +1331,6 @@ namespace netlist log().fatal(MF_TERMINALS_WITHOUT_NET()); throw nl_exception(MF_TERMINALS_WITHOUT_NET()); } - } void setup_t::move_connections(detail::net_t &net, detail::net_t &dest_net) @@ -1230,30 +1339,31 @@ namespace netlist net.remove_all_terminals(); - for (detail::core_terminal_t * ct : temp) + for (detail::core_terminal_t *ct : temp) { dest_net.add_terminal(*ct); } } - log_type &setup_t::log() noexcept { return m_nlstate.log(); } + log_type & setup_t::log() noexcept { return m_nlstate.log(); } const log_type &setup_t::log() const noexcept { return m_nlstate.log(); } - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- // Models - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- - //NOLINTNEXTLINE(misc-no-recursion) + // NOLINTNEXTLINE(misc-no-recursion) void models_t::model_parse(const pstring &model_in, map_t &map) { - pstring model = model_in; + pstring model = model_in; std::size_t pos = 0; - pstring key; + pstring key; while (true) { pos = model.find('('); - if (pos != pstring::npos) break; + if (pos != pstring::npos) + break; key = plib::ucase(model); auto i = m_models.find(key); @@ -1283,7 +1393,7 @@ namespace netlist // FIMXE: Not optimal remainder = plib::left(remainder, remainder.length() - 1); - const auto pairs(plib::psplit(remainder,' ', true)); + const auto pairs(plib::psplit(remainder, ' ', true)); for (const pstring &pe : pairs) { auto pose = pe.find('='); @@ -1297,7 +1407,7 @@ namespace netlist { // operator [] has no const implementation pstring ret = map.at("COREMODEL") + "("; - for (const auto & i : map) + for (const auto &i : map) ret += (i.first + '=' + i.second + ' '); return ret + ")"; @@ -1308,18 +1418,20 @@ namespace netlist map_t &map = m_cache[model]; if (map.empty()) - model_parse(model , map); + model_parse(model, map); - return { model, map }; + return {model, map}; } pstring models_t::model_t::value_str(const pstring &entity) const { if (entity != plib::ucase(entity)) - throw nl_exception(MF_MODEL_PARAMETERS_NOT_UPPERCASE_1_2(entity, model_string(m_map))); + throw nl_exception(MF_MODEL_PARAMETERS_NOT_UPPERCASE_1_2( + entity, model_string(m_map))); const auto it(m_map.find(entity)); - if ( it == m_map.end()) - throw nl_exception(MF_ENTITY_1_NOT_FOUND_IN_MODEL_2(entity, model_string(m_map))); + if (it == m_map.end()) + throw nl_exception( + MF_ENTITY_1_NOT_FOUND_IN_MODEL_2(entity, model_string(m_map))); return it->second; } @@ -1329,21 +1441,24 @@ namespace netlist pstring tmp = value_str(entity); nl_fptype factor = nlconst::one(); - auto p = std::next(tmp.begin(), plib::narrow_cast<pstring::difference_type>(tmp.length() - 1)); + auto p = std::next( + tmp.begin(), + plib::narrow_cast<pstring::difference_type>(tmp.length() - 1)); switch (*p) { case 'M': factor = nlconst::magic(1e6); break; // NOLINT case 'k': - case 'K': factor = nlconst::magic(1e3); break; // NOLINT - case 'm': factor = nlconst::magic(1e-3); break; // NOLINT - case 'u': factor = nlconst::magic(1e-6); break; // NOLINT - case 'n': factor = nlconst::magic(1e-9); break; // NOLINT + case 'K': factor = nlconst::magic(1e3); break; // NOLINT + case 'm': factor = nlconst::magic(1e-3); break; // NOLINT + case 'u': factor = nlconst::magic(1e-6); break; // NOLINT + case 'n': factor = nlconst::magic(1e-9); break; // NOLINT case 'p': factor = nlconst::magic(1e-12); break; // NOLINT case 'f': factor = nlconst::magic(1e-15); break; // NOLINT case 'a': factor = nlconst::magic(1e-18); break; // NOLINT default: if (*p < '0' || *p > '9') - throw nl_exception(MF_UNKNOWN_NUMBER_FACTOR_IN_2(m_model, entity)); + throw nl_exception( + MF_UNKNOWN_NUMBER_FACTOR_IN_2(m_model, entity)); } if (factor != nlconst::one()) tmp = plib::left(tmp, tmp.length() - 1); @@ -1351,22 +1466,17 @@ namespace netlist bool err(false); auto val = plib::pstonum_ne<nl_fptype>(tmp, err); if (err) - throw nl_exception(MF_MODEL_NUMBER_CONVERSION_ERROR(entity, tmp, "double", m_model)); + throw nl_exception(MF_MODEL_NUMBER_CONVERSION_ERROR( + entity, tmp, "double", m_model)); return val * factor; } - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- // logic_family_std_proxy_t // // FIXME: all this belongs elsewhere - // ---------------------------------------------------------------------------------------- - PENUM(family_type, - CUSTOM, - TTL, - MOS, - CMOS, - NMOS, - PMOS) + // ------------------------------------------------------------------------- + PENUM(family_type, CUSTOM, TTL, MOS, CMOS, NMOS, PMOS) class logic_family_std_proxy_t : public logic_family_desc_t { @@ -1377,10 +1487,11 @@ namespace netlist } // FIXME: create proxies based on family type (far future) - device_arena::unique_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_state_t &anetlist, - const pstring &name, const logic_output_t *proxied) const override + device_arena::unique_ptr<devices::nld_base_d_to_a_proxy> + create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, + const logic_output_t *proxied) const override { - switch(m_family_type) + switch (m_family_type) { case family_type::CUSTOM: case family_type::TTL: @@ -1388,14 +1499,18 @@ namespace netlist case family_type::CMOS: case family_type::NMOS: case family_type::PMOS: - return anetlist.make_pool_object<devices::nld_d_to_a_proxy>(anetlist, name, proxied); + return anetlist.make_pool_object<devices::nld_d_to_a_proxy>( + device_data_t{anetlist, name}, proxied); } - return anetlist.make_pool_object<devices::nld_d_to_a_proxy>(anetlist, name, proxied); + return anetlist.make_pool_object<devices::nld_d_to_a_proxy>( + device_data_t{anetlist, name}, proxied); } - device_arena::unique_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, const logic_input_t *proxied) const override + device_arena::unique_ptr<devices::nld_base_a_to_d_proxy> + create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, + const logic_input_t *proxied) const override { - switch(m_family_type) + switch (m_family_type) { case family_type::CUSTOM: case family_type::TTL: @@ -1403,14 +1518,18 @@ namespace netlist case family_type::CMOS: case family_type::NMOS: case family_type::PMOS: - return anetlist.make_pool_object<devices::nld_a_to_d_proxy>(anetlist, name, proxied); + return anetlist.make_pool_object<devices::nld_a_to_d_proxy>( + device_data_t{anetlist, name}, proxied); } - return anetlist.make_pool_object<devices::nld_a_to_d_proxy>(anetlist, name, proxied); + return anetlist.make_pool_object<devices::nld_a_to_d_proxy>( + device_data_t{anetlist, name}, proxied); } + private: family_type m_family_type; }; + // clang-format off /// \brief Class representing the logic families. /// /// This is the model representation of the logic families. This is a @@ -1426,6 +1545,7 @@ namespace netlist /// | Y |ORL |Output output resistance for logic 0 | | 0| /// | Y |ORH |Output output resistance for logic 1 | | 0| /// + // clang-format on class family_model_t { public: @@ -1438,22 +1558,27 @@ namespace netlist , m_OVH(model, "OVH") , m_ORL(model, "ORL") , m_ORH(model, "ORH") - {} + { + } param_model_t::value_str_t m_TYPE; //!< Family type (TTL, CMOS, ...) - param_model_t::value_t m_IVL; //!< Input voltage low threshold relative to supply voltage - param_model_t::value_t m_IVH; //!< Input voltage high threshold relative to supply voltage - param_model_t::value_t m_OVL; //!< Output voltage minimum voltage relative to supply voltage - param_model_t::value_t m_OVH; //!< Output voltage maximum voltage relative to supply voltage - param_model_t::value_t m_ORL; //!< Output output resistance for logic 0 - param_model_t::value_t m_ORH; //!< Output output resistance for logic 1 + param_model_t::value_t m_IVL; //!< Input voltage low threshold relative + //!< to supply voltage + param_model_t::value_t m_IVH; //!< Input voltage high threshold relative + //!< to supply voltage + param_model_t::value_t m_OVL; //!< Output voltage minimum voltage + //!< relative to supply voltage + param_model_t::value_t m_OVH; //!< Output voltage maximum voltage + //!< relative to supply voltage + param_model_t::value_t m_ORL; //!< Output output resistance for logic 0 + param_model_t::value_t m_ORH; //!< Output output resistance for logic 1 }; const logic_family_desc_t *setup_t::family_from_model(const pstring &model) { family_type ft(family_type::CUSTOM); - auto mod(m_models.get_model(model)); + auto mod(m_models.get_model(model)); family_model_t modv(mod); if (!ft.set_from_string(modv.m_TYPE())) @@ -1495,30 +1620,35 @@ namespace netlist return retp; } - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- // Device handling - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- void setup_t::delete_empty_nets() { m_nlstate.nets().erase( - std::remove_if(m_nlstate.nets().begin(), m_nlstate.nets().end(), + std::remove_if( + m_nlstate.nets().begin(), m_nlstate.nets().end(), [](device_arena::owned_ptr<detail::net_t> &net) { if (net->core_terms_empty()) { - // FIXME: need to remove from state->m_core_terms as well. - net->state().log().verbose("Deleting net {1} ...", net->name()); - net->state().run_state_manager().remove_save_items(net.get()); + // FIXME: need to remove from state->m_core_terms as + // well. + net->state().log().verbose("Deleting net {1} ...", + net->name()); + net->state().run_state_manager().remove_save_items( + net.get()); return true; } return false; - }), m_nlstate.nets().end()); + }), + m_nlstate.nets().end()); } - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- // Run preparation - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- void setup_t::prepare_to_run() { @@ -1532,55 +1662,68 @@ namespace netlist // create default parameters first! - for (auto & e : m_abstract.m_default_params) + for (auto &e : m_abstract.m_default_params) { - auto param(plib::make_unique<param_str_t, host_arena>(nlstate(), e.first, e.second)); + auto param(plib::make_unique<param_str_t, host_arena>( + nlstate(), e.first, e.second)); register_param_t(*param); m_defparam_lifetime.push_back(std::move(param)); } // make sure the solver and parameters are started first! - for (auto & e : m_abstract.m_device_factory) + for (auto &e : m_abstract.m_device_factory) { - if ( m_parser.factory().is_class<devices::NETLIB_NAME(solver)>(e.second) - || m_parser.factory().is_class<devices::NETLIB_NAME(netlistparams)>(e.second)) + if (m_parser.factory().is_class<devices::NETLIB_NAME(solver)>( + e.second) + || m_parser.factory() + .is_class<devices::NETLIB_NAME(netlistparams)>(e.second)) { - m_nlstate.register_device(e.first, e.second->make_device(nlstate().pool(), m_nlstate, e.first)); + m_nlstate.register_device( + e.first, e.second->make_device(nlstate().pool(), m_nlstate, + e.first)); } } log().debug("Searching for solver and parameters ...\n"); - auto *solver = m_nlstate.get_single_device<devices::NETLIB_NAME(solver)>("solver"); - m_netlist_params = m_nlstate.get_single_device<devices::NETLIB_NAME(netlistparams)>("parameter"); + auto *solver = m_nlstate + .get_single_device<devices::NETLIB_NAME(solver)>( + "solver"); + m_netlist_params = m_nlstate.get_single_device< + devices::NETLIB_NAME(netlistparams)>("parameter"); // set default model parameters // FIXME: this is not optimal - m_parser.register_model(plib::pfmt("NMOS_DEFAULT _(CAPMOD={1})")(m_netlist_params->m_mos_cap_model())); - m_parser.register_model(plib::pfmt("PMOS_DEFAULT _(CAPMOD={1})")(m_netlist_params->m_mos_cap_model())); + m_parser.register_model(plib::pfmt("NMOS_DEFAULT _(CAPMOD={1})")( + m_netlist_params->m_mos_cap_model())); + m_parser.register_model(plib::pfmt("PMOS_DEFAULT _(CAPMOD={1})")( + m_netlist_params->m_mos_cap_model())); // create devices log().debug("Creating devices ...\n"); - for (auto & e : m_abstract.m_device_factory) + for (auto &e : m_abstract.m_device_factory) { - if ( !m_parser.factory().is_class<devices::NETLIB_NAME(solver)>(e.second) - && !m_parser.factory().is_class<devices::NETLIB_NAME(netlistparams)>(e.second)) + if (!m_parser.factory().is_class<devices::NETLIB_NAME(solver)>( + e.second) + && !m_parser.factory() + .is_class<devices::NETLIB_NAME(netlistparams)>( + e.second)) { - auto dev = e.second->make_device(m_nlstate.pool(), m_nlstate, e.first); + auto dev = e.second->make_device(m_nlstate.pool(), m_nlstate, + e.first); m_nlstate.register_device(dev->name(), std::move(dev)); } } - int error_count(0); - const bool use_deactivate = m_netlist_params->m_use_deactivate(); for (auto &d : m_nlstate.devices()) { - auto p = m_abstract.m_hints.find(d.second->name() + sHINT_NO_DEACTIVATE); + auto p = m_abstract.m_hints.find(d.second->name() + + sHINT_NO_DEACTIVATE); if (p != m_abstract.m_hints.end()) { p->second = true; // mark as used @@ -1590,38 +1733,36 @@ namespace netlist d.second->set_hint_deactivate(use_deactivate); } - if (error_count > 0) - { - log().fatal(MF_ERRORS_FOUND(error_count)); - throw nl_exception(MF_ERRORS_FOUND(error_count)); - } - // resolve inputs resolve_inputs(); log().verbose("looking for two terms connected to rail nets ..."); - for (auto & t : m_nlstate.get_device_list<analog::NETLIB_NAME(two_terminal)>()) + for (auto &t : + m_nlstate.get_device_list<analog::NETLIB_NAME(two_terminal)>()) { if (t->N().net().is_rail_net() && t->P().net().is_rail_net()) { log().info(MI_REMOVE_DEVICE_1_CONNECTED_ONLY_TO_RAILS_2_3( t->name(), t->N().net().name(), t->P().net().name())); - // The following would remove internal devices in e.g. MOSFETs as well. - #if 0 + // The following would remove internal devices in e.g. MOSFETs + // as well. +#if 0 remove_terminal(t->setup_N().net(), t->setup_N()); remove_terminal(t->setup_P().net(), t->setup_P()); m_nlstate.remove_device(t); - #endif +#endif } } + int error_count = 0; + log().verbose("looking for unused hints ..."); for (auto &h : m_abstract.m_hints) { if (!h.second) { - log().fatal(MF_UNUSED_HINT_1(h.first)); - throw nl_exception(MF_UNUSED_HINT_1(h.first)); + log().error(MF_UNUSED_HINT_1(h.first)); + error_count++; } } @@ -1632,14 +1773,13 @@ namespace netlist for (auto &p : m_nlstate.nets()) if (p->is_analog()) { - log().fatal(MF_NO_SOLVER()); - throw nl_exception(MF_NO_SOLVER()); + log().error(MF_NO_SOLVER()); + error_count++; } } else solver->post_start(); - error_count = 0; log().debug("Looking for unknown parameters ...\n"); for (auto &p : m_abstract.m_param_values) { @@ -1650,66 +1790,78 @@ namespace netlist error_count++; } } - if (error_count > 0) - { - log().fatal(MF_ERRORS_FOUND(error_count)); - throw nl_exception(MF_ERRORS_FOUND(error_count)); - } for (auto &n : m_nlstate.nets()) { - for (detail::core_terminal_t * term : n->core_terms_copy()) + for (detail::core_terminal_t *term : n->core_terms_copy()) if (term->delegate().isnull()) { - log().fatal(MF_DELEGATE_NOT_SET_1(term->name())); - throw nl_exception(MF_DELEGATE_NOT_SET_1(term->name())); + log().error(MF_DELEGATE_NOT_SET_1(term->name())); + error_count++; } n->rebuild_list(); } + + if (error_count > 0) + { + log().fatal(MF_ERRORS_FOUND(error_count)); + throw nl_exception(MF_ERRORS_FOUND(error_count)); + } } - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- // base sources - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- bool source_netlist_t::parse(nlparse_t &setup, const pstring &name) { auto strm(stream(name)); - return (!strm.empty()) ? setup.parse_stream(std::move(strm), name) : false; + return (!strm.empty()) ? setup.parse_stream(std::move(strm), name) + : false; } - plib::istream_uptr source_string_t::stream([[maybe_unused]] const pstring &name) + plib::istream_uptr + source_string_t::stream([[maybe_unused]] const pstring &name) { - plib::istream_uptr ret(std::make_unique<std::istringstream>(putf8string(m_str)), name); + plib::istream_uptr ret( + std::make_unique<std::istringstream>(putf8string(m_str)), name); ret->imbue(std::locale::classic()); return ret; } - plib::istream_uptr source_mem_t::stream([[maybe_unused]] const pstring &name) + plib::istream_uptr + source_mem_t::stream([[maybe_unused]] const pstring &name) { - plib::istream_uptr ret(std::make_unique<std::istringstream>(m_str, std::ios_base::binary), name); + plib::istream_uptr ret( + std::make_unique<std::istringstream>(m_str, std::ios_base::binary), + name); ret->imbue(std::locale::classic()); return ret; } - plib::istream_uptr source_file_t::stream([[maybe_unused]] const pstring &name) + plib::istream_uptr + source_file_t::stream([[maybe_unused]] const pstring &name) { - auto f = std::make_unique<plib::ifstream>(plib::filesystem::u8path(m_filename)); + auto f = std::make_unique<plib::ifstream>( + plib::filesystem::u8path(m_filename)); if (f->is_open()) { - return { std::move(f), m_filename }; + return {std::move(f), m_filename}; } return plib::istream_uptr(); } - plib::istream_uptr source_pattern_t::stream([[maybe_unused]] const pstring &name) + plib::istream_uptr + source_pattern_t::stream([[maybe_unused]] const pstring &name) { - pstring filename = plib::pfmt(m_pattern)(m_force_lowercase ? plib::lcase(name) : name); - auto f = std::make_unique<plib::ifstream>(plib::filesystem::u8path(filename)); + pstring filename = plib::pfmt(m_pattern)( + m_force_lowercase ? plib::lcase(name) : name); + auto f = std::make_unique<plib::ifstream>( + plib::filesystem::u8path(filename)); if (f->is_open()) { - return { std::move(f), filename }; + return {std::move(f), filename}; } return plib::istream_uptr(); @@ -1726,10 +1878,10 @@ namespace netlist return false; } - plib::istream_uptr source_proc_t::stream([[maybe_unused]] const pstring &name) + plib::istream_uptr + source_proc_t::stream([[maybe_unused]] const pstring &name) { return plib::istream_uptr(); } } // namespace netlist - |