diff options
Diffstat (limited to 'src/lib/netlist/nl_setup.cpp')
-rw-r--r-- | src/lib/netlist/nl_setup.cpp | 402 |
1 files changed, 207 insertions, 195 deletions
diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp index 3cdc598afbc..60110d0b110 100644 --- a/src/lib/netlist/nl_setup.cpp +++ b/src/lib/netlist/nl_setup.cpp @@ -19,132 +19,235 @@ #include <cmath> -// ---------------------------------------------------------------------------------------- -// setup_t -// ---------------------------------------------------------------------------------------- - namespace netlist { -setup_t::setup_t(netlist_t &netlist) - : m_netlist(netlist) - , m_netlist_params(nullptr) - , m_factory(*this) - , m_proxy_cnt(0) + // ---------------------------------------------------------------------------------------- + // nl_parse_t + // ---------------------------------------------------------------------------------------- + + nlparse_t::nlparse_t(netlist_t &netlist) + : m_factory(netlist.log()) + , m_log(netlist.log()) , m_frontier_cnt(0) -{ -} + { } -setup_t::~setup_t() noexcept -{ - // FIXME: can't see a need any longer - m_links.clear(); - m_alias.clear(); - m_params.clear(); - m_terminals.clear(); - m_param_values.clear(); - m_sources.clear(); -} + void nlparse_t::register_model(const pstring &model_in) + { + auto pos = model_in.find(" "); + if (pos == pstring::npos) + log().fatal(MF_1_UNABLE_TO_PARSE_MODEL_1, model_in); + pstring model = plib::ucase(plib::trim(plib::left(model_in, pos))); + pstring def = plib::trim(model_in.substr(pos + 1)); + if (!m_models.insert({model, def}).second) + log().fatal(MF_1_MODEL_ALREADY_EXISTS_1, model_in); + } -netlist_state_t &setup_t::netlist() -{ - return m_netlist.nlstate(); -} -const netlist_state_t &setup_t::netlist() const -{ - return m_netlist.nlstate(); -} + void nlparse_t::register_alias(const pstring &alias, const pstring &out) + { + pstring alias_fqn = build_fqn(alias); + pstring out_fqn = build_fqn(out); + register_alias_nofqn(alias_fqn, out_fqn); + } + void nlparse_t::register_dippins_arr(const pstring &terms) + { + std::vector<pstring> list(plib::psplit(terms,", ")); + if (list.size() == 0 || (list.size() % 2) == 1) + log().fatal(MF_1_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]); + } + } -pstring setup_t::build_fqn(const pstring &obj_name) const -{ - if (m_namespace_stack.empty()) - //return netlist().name() + "." + obj_name; - return obj_name; - else - return m_namespace_stack.top() + "." + obj_name; -} + void nlparse_t::register_dev(const pstring &classname, const pstring &name) + { + auto f = m_factory.factory_by_name(classname); + if (f == nullptr) + log().fatal(MF_1_CLASS_1_NOT_FOUND, classname); + else + { + /* make sure we parse macro library entries */ + f->macro_actions(*this, name); + pstring key = build_fqn(name); + if (device_exists(key)) + log().fatal(MF_1_DEVICE_ALREADY_EXISTS_1, name); + else + m_device_factory.insert(m_device_factory.end(), {key, f}); + } + } -void setup_t::namespace_push(const pstring &aname) -{ - if (m_namespace_stack.empty()) - //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::register_link(const pstring &sin, const pstring &sout) + { + register_link_fqn(build_fqn(sin), build_fqn(sout)); + } -void setup_t::namespace_pop() -{ - m_namespace_stack.pop(); -} + void nlparse_t::register_link_arr(const pstring &terms) + { + std::vector<pstring> list(plib::psplit(terms,", ")); + if (list.size() < 2) + log().fatal(MF_2_NET_C_NEEDS_AT_LEAST_2_TERMINAL); + for (std::size_t i = 1; i < list.size(); i++) + { + register_link(list[0], list[i]); + } + } -void setup_t::register_lib_entry(const pstring &name, const pstring &sourcefile) -{ - factory().register_device(plib::make_unique<factory::library_element_t>(*this, name, name, "", sourcefile)); -} + void nlparse_t::include(const pstring &netlist_name) + { + for (auto &source : m_sources) + { + if (source->parse(netlist_name)) + return; + } + log().fatal(MF_1_NOT_FOUND_IN_SOURCE_COLLECTION, netlist_name); + } -void setup_t::register_dev(const pstring &classname, const pstring &name) -{ - auto f = factory().factory_by_name(classname); - if (f == nullptr) - log().fatal(MF_1_CLASS_1_NOT_FOUND, classname); - else + + void nlparse_t::namespace_push(const pstring &aname) { - /* make sure we parse macro library entries */ - f->macro_actions(netlist(), name); - pstring key = build_fqn(name); - if (device_exists(key)) - log().fatal(MF_1_DEVICE_ALREADY_EXISTS_1, name); + if (m_namespace_stack.empty()) + //m_namespace_stack.push(netlist().name() + "." + aname); + m_namespace_stack.push(aname); else - m_device_factory.insert(m_device_factory.end(), {key, f}); + m_namespace_stack.push(m_namespace_stack.top() + "." + aname); } -} -bool setup_t::device_exists(const pstring &name) const -{ - for (auto &d : m_device_factory) - if (d.first == name) - return true; - return false; -} + void nlparse_t::namespace_pop() + { + m_namespace_stack.pop(); + } + + void nlparse_t::register_param(const pstring ¶m, const double value) + { + if (std::abs(value - std::floor(value)) > 1e-30 || std::abs(value) > 1e9) + register_param(param, plib::pfmt("{1:.9}").e(value)); + else + register_param(param, plib::pfmt("{1}")(static_cast<long>(value))); + } + + void nlparse_t::register_param(const pstring ¶m, const pstring &value) + { + pstring fqn = build_fqn(param); + + auto idx = m_param_values.find(fqn); + if (idx == m_param_values.end()) + { + if (!m_param_values.insert({fqn, value}).second) + log().fatal(MF_1_ADDING_PARAMETER_1_TO_PARAMETER_LIST, + param); + } + else + { + log().warning(MW_3_OVERWRITING_PARAM_1_OLD_2_NEW_3, fqn, idx->second, + value); + m_param_values[fqn] = value; + } + } + + void nlparse_t::register_lib_entry(const pstring &name, const pstring &sourcefile) + { + m_factory.register_device(plib::make_unique<factory::library_element_t>(name, name, "", sourcefile)); + } + + void nlparse_t::register_frontier(const pstring &attach, const double r_IN, const double r_OUT) + { + pstring frontier_name = plib::pfmt("frontier_{1}")(m_frontier_cnt); + m_frontier_cnt++; + register_dev("FRONTIER_DEV", frontier_name); + register_param(frontier_name + ".RIN", r_IN); + register_param(frontier_name + ".ROUT", r_OUT); + register_link(frontier_name + ".G", "GND"); + pstring attfn = build_fqn(attach); + pstring front_fqn = build_fqn(frontier_name); + bool found = false; + for (auto & link : m_links) + { + if (link.first == attfn) + { + link.first = front_fqn + ".I"; + found = true; + } + else if (link.second == attfn) + { + link.second = front_fqn + ".I"; + found = true; + } + } + if (!found) + log().fatal(MF_1_FOUND_NO_OCCURRENCE_OF_1, attach); + register_link(attach, frontier_name + ".Q"); + } + + void nlparse_t::tt_factory_create(tt_desc &desc, const pstring &sourcefile) + { + auto fac = devices::tt_factory_create(desc, sourcefile); + m_factory.register_device(std::move(fac)); + } + + pstring nlparse_t::build_fqn(const pstring &obj_name) const + { + if (m_namespace_stack.empty()) + //return netlist().name() + "." + obj_name; + return obj_name; + else + return m_namespace_stack.top() + "." + obj_name; + } + + void nlparse_t::register_alias_nofqn(const pstring &alias, const pstring &out) + { + if (!m_alias.insert({alias, out}).second) + log().fatal(MF_1_ADDING_ALI1_TO_ALIAS_LIST, alias); + } + + void nlparse_t::register_link_fqn(const pstring &sin, const pstring &sout) + { + link_t temp = link_t(sin, sout); + log().debug("link {1} <== {2}\n", sin, sout); + m_links.push_back(temp); + } + + bool nlparse_t::device_exists(const pstring &name) const + { + for (auto &d : m_device_factory) + if (d.first == name) + return true; + return false; + } + // ---------------------------------------------------------------------------------------- + // setup_t + // ---------------------------------------------------------------------------------------- -void setup_t::register_model(const pstring &model_in) + +setup_t::setup_t(netlist_t &netlist) + : nlparse_t(netlist) + , m_netlist(netlist) + , m_netlist_params(nullptr) + , m_proxy_cnt(0) { - auto pos = model_in.find(" "); - if (pos == pstring::npos) - log().fatal(MF_1_UNABLE_TO_PARSE_MODEL_1, model_in); - pstring model = plib::ucase(plib::trim(plib::left(model_in, pos))); - pstring def = plib::trim(model_in.substr(pos + 1)); - if (!m_models.insert({model, def}).second) - log().fatal(MF_1_MODEL_ALREADY_EXISTS_1, model_in); } -void setup_t::register_alias_nofqn(const pstring &alias, const pstring &out) +setup_t::~setup_t() noexcept { - if (!m_alias.insert({alias, out}).second) - log().fatal(MF_1_ADDING_ALI1_TO_ALIAS_LIST, alias); + // FIXME: can't see a need any longer + m_links.clear(); + m_params.clear(); + m_terminals.clear(); + m_param_values.clear(); + m_sources.clear(); } -void setup_t::register_alias(const pstring &alias, const pstring &out) +netlist_state_t &setup_t::netlist() { - pstring alias_fqn = build_fqn(alias); - pstring out_fqn = build_fqn(out); - register_alias_nofqn(alias_fqn, out_fqn); + return m_netlist.nlstate(); } - -void setup_t::register_dippins_arr(const pstring &terms) +const netlist_state_t &setup_t::netlist() const { - std::vector<pstring> list(plib::psplit(terms,", ")); - if (list.size() == 0 || (list.size() % 2) == 1) - log().fatal(MF_1_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]); - } + return m_netlist.nlstate(); } pstring setup_t::termtype_as_str(detail::core_terminal_t &in) const @@ -171,12 +274,6 @@ pstring setup_t::get_initial_param_val(const pstring &name, const pstring &def) return def; } -void setup_t::register_param(const pstring &name, param_t ¶m) -{ - if (!m_params.insert({param.name(), param_ref_t(param.name(), param.device(), param)}).second) - log().fatal(MF_1_ADDING_PARAMETER_1_TO_PARAMETER_LIST, name); -} - void setup_t::register_term(detail::core_terminal_t &term) { if (!m_terminals.insert({term.name(), &term}).second) @@ -185,29 +282,10 @@ void setup_t::register_term(detail::core_terminal_t &term) log().debug("{1} {2}\n", termtype_as_str(term), term.name()); } -void setup_t::register_link_arr(const pstring &terms) -{ - std::vector<pstring> list(plib::psplit(terms,", ")); - if (list.size() < 2) - log().fatal(MF_2_NET_C_NEEDS_AT_LEAST_2_TERMINAL); - for (std::size_t i = 1; i < list.size(); i++) - { - register_link(list[0], list[i]); - } -} -void setup_t::register_link_fqn(const pstring &sin, const pstring &sout) -{ - link_t temp = link_t(sin, sout); - log().debug("link {1} <== {2}\n", sin, sout); - m_links.push_back(temp); -} -void setup_t::register_link(const pstring &sin, const pstring &sout) -{ - register_link_fqn(build_fqn(sin), build_fqn(sout)); -} + void setup_t::remove_connections(const pstring &pin) { @@ -230,62 +308,14 @@ void setup_t::remove_connections(const pstring &pin) } -void setup_t::register_frontier(const pstring &attach, const double r_IN, const double r_OUT) -{ - pstring frontier_name = plib::pfmt("frontier_{1}")(m_frontier_cnt); - m_frontier_cnt++; - register_dev("FRONTIER_DEV", frontier_name); - register_param(frontier_name + ".RIN", r_IN); - register_param(frontier_name + ".ROUT", r_OUT); - register_link(frontier_name + ".G", "GND"); - pstring attfn = build_fqn(attach); - pstring front_fqn = build_fqn(frontier_name); - bool found = false; - for (auto & link : m_links) - { - if (link.first == attfn) - { - link.first = front_fqn + ".I"; - found = true; - } - else if (link.second == attfn) - { - link.second = front_fqn + ".I"; - found = true; - } - } - if (!found) - log().fatal(MF_1_FOUND_NO_OCCURRENCE_OF_1, attach); - register_link(attach, frontier_name + ".Q"); -} - -void setup_t::register_param(const pstring ¶m, const double value) +void setup_t::register_param_t(const pstring &name, param_t ¶m) { - if (std::abs(value - std::floor(value)) > 1e-30 || std::abs(value) > 1e9) - register_param(param, plib::pfmt("{1:.9}").e(value)); - else - register_param(param, plib::pfmt("{1}")(static_cast<long>(value))); + if (!m_params.insert({param.name(), param_ref_t(param.name(), param.device(), param)}).second) + log().fatal(MF_1_ADDING_PARAMETER_1_TO_PARAMETER_LIST, name); } -void setup_t::register_param(const pstring ¶m, const pstring &value) -{ - pstring fqn = build_fqn(param); - auto idx = m_param_values.find(fqn); - if (idx == m_param_values.end()) - { - if (!m_param_values.insert({fqn, value}).second) - log().fatal(MF_1_ADDING_PARAMETER_1_TO_PARAMETER_LIST, - param); - } - else - { - log().warning(MW_3_OVERWRITING_PARAM_1_OLD_2_NEW_3, fqn, idx->second, - value); - m_param_values[fqn] = value; - } -} const pstring setup_t::resolve_alias(const pstring &name) const { @@ -937,12 +967,6 @@ const logic_family_desc_t *setup_t::family_from_model(const pstring &model) return retp; } -void setup_t::tt_factory_create(tt_desc &desc, const pstring &sourcefile) -{ - devices::tt_factory_create(*this, desc, sourcefile); -} - - // ---------------------------------------------------------------------------------------- // Sources // ---------------------------------------------------------------------------------------- @@ -952,16 +976,6 @@ bool setup_t::parse_stream(std::unique_ptr<plib::pistream> istrm, const pstring return parser_t(std::move(plib::ppreprocessor(&m_defines).process(std::move(istrm))), *this).parse(name); } -void setup_t::include(const pstring &netlist_name) -{ - for (auto &source : m_sources) - { - if (source->parse(netlist_name)) - return; - } - log().fatal(MF_1_NOT_FOUND_IN_SOURCE_COLLECTION, netlist_name); -} - std::unique_ptr<plib::pistream> setup_t::get_data_stream(const pstring &name) { for (auto &source : m_sources) @@ -1015,8 +1029,6 @@ void setup_t::prepare_to_run() { register_dynamic_log_devices(); - /* load the library ... */ - /* make sure the solver and parameters are started first! */ for (auto & e : m_device_factory) |