diff options
Diffstat (limited to 'src/lib/netlist/nl_setup.cpp')
-rw-r--r-- | src/lib/netlist/nl_setup.cpp | 272 |
1 files changed, 155 insertions, 117 deletions
diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp index 84aa7c8d384..0572ec1e693 100644 --- a/src/lib/netlist/nl_setup.cpp +++ b/src/lib/netlist/nl_setup.cpp @@ -5,22 +5,17 @@ * */ -#include <cstdio> - -#include "solver/nld_solver.h" - #include "plib/palloc.h" #include "plib/putil.h" #include "nl_base.h" #include "nl_setup.h" #include "nl_parser.h" #include "nl_factory.h" -#include "devices/net_lib.h" -#include "devices/nld_truthtable.h" #include "devices/nlid_system.h" #include "devices/nlid_proxy.h" #include "analog/nld_twoterm.h" #include "solver/nld_solver.h" +#include "devices/nlid_truthtable.h" // ---------------------------------------------------------------------------------------- // setup_t @@ -34,7 +29,7 @@ setup_t::setup_t(netlist_t &netlist) , m_proxy_cnt(0) , m_frontier_cnt(0) { - initialize_factory(m_factory); + devices::initialize_factory(m_factory); } setup_t::~setup_t() @@ -73,16 +68,16 @@ void setup_t::namespace_pop() m_namespace_stack.pop(); } -void setup_t::register_lib_entry(const pstring &name) +void setup_t::register_lib_entry(const pstring &name, const pstring &sourcefile) { - factory().register_device(plib::make_unique_base<factory::element_t, factory::library_element_t>(*this, name, name, "")); + factory().register_device(plib::make_unique_base<factory::element_t, factory::library_element_t>(*this, name, name, "", sourcefile)); } void setup_t::register_dev(const pstring &classname, const pstring &name) { auto f = factory().factory_by_name(classname); if (f == nullptr) - log().fatal("Class {1} not found!\n", classname); + log().fatal(MF_1_CLASS_1_NOT_FOUND, classname); /* make sure we parse macro library entries */ f->macro_actions(netlist(), name); m_device_factory.push_back(std::pair<pstring, factory::element_t *>(build_fqn(name), f)); @@ -103,17 +98,17 @@ void setup_t::register_model(const pstring &model_in) { auto pos = model_in.find(" "); if (pos == model_in.end()) - log().fatal("Unable to parse model: {1}", model_in); + log().fatal(MF_1_UNABLE_TO_PARSE_MODEL_1, model_in); pstring model = model_in.left(pos).trim().ucase(); pstring def = model_in.substr(pos + 1).trim(); if (!m_models.insert({model, def}).second) - log().fatal("Model already exists: {1}", model_in); + log().fatal(MF_1_MODEL_ALREADY_EXISTS_1, model_in); } void setup_t::register_alias_nofqn(const pstring &alias, const pstring &out) { if (!m_alias.insert({alias, out}).second) - log().fatal("Error adding alias {1} to alias list\n", alias); + log().fatal(MF_1_ADDING_ALIAS_1_TO_ALIAS_LIST, alias); } void setup_t::register_alias(const pstring &alias, const pstring &out) @@ -125,9 +120,10 @@ void setup_t::register_alias(const pstring &alias, const pstring &out) void setup_t::register_dippins_arr(const pstring &terms) { - plib::pstring_vector_t list(terms,", "); + std::vector<pstring> list(plib::psplit(terms,", ")); if (list.size() == 0 || (list.size() % 2) == 1) - log().fatal("You must pass an equal number of pins to DIPPINS {1}" , build_fqn("")); + 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++) { @@ -136,22 +132,19 @@ void setup_t::register_dippins_arr(const pstring &terms) } } -pstring setup_t::objtype_as_str(detail::device_object_t &in) const +pstring setup_t::termtype_as_str(detail::core_terminal_t &in) const { switch (in.type()) { - case terminal_t::TERMINAL: - return "TERMINAL"; - case terminal_t::INPUT: - return "INPUT"; - case terminal_t::OUTPUT: - return "OUTPUT"; - case terminal_t::PARAM: - return "PARAM"; + case detail::terminal_type::TERMINAL: + return pstring("TERMINAL"); + case detail::terminal_type::INPUT: + return pstring("INPUT"); + case detail::terminal_type::OUTPUT: + return pstring("OUTPUT"); } - // FIXME: noreturn - log().fatal("Unknown object type {1}\n", static_cast<unsigned>(in.type())); - return "Error"; + log().fatal(MF_1_UNKNOWN_OBJECT_TYPE_1, static_cast<unsigned>(in.type())); + return pstring("Error"); } pstring setup_t::get_initial_param_val(const pstring name, const pstring def) @@ -170,7 +163,7 @@ double setup_t::get_initial_param_val(const pstring name, const double def) { double vald = 0; if (sscanf(i->second.c_str(), "%lf", &vald) != 1) - log().fatal("Invalid number conversion {1} : {2}\n", name, i->second); + log().fatal(MF_2_INVALID_NUMBER_CONVERSION_1_2, name, i->second); return vald; } else @@ -184,7 +177,7 @@ int setup_t::get_initial_param_val(const pstring name, const int def) { double vald = 0; if (sscanf(i->second.c_str(), "%lf", &vald) != 1) - log().fatal("Invalid number conversion {1} : {2}\n", name, i->second); + log().fatal(MF_2_INVALID_NUMBER_CONVERSION_1_2, name, i->second); return static_cast<int>(vald); } else @@ -194,21 +187,22 @@ int setup_t::get_initial_param_val(const pstring name, const int def) void setup_t::register_param(pstring name, param_t ¶m) { if (!m_params.insert({param.name(), param_ref_t(param.name(), param.device(), param)}).second) - log().fatal("Error adding parameter {1} to parameter list\n", name); + 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) - log().fatal("Error adding {1} {2} to terminal list\n", objtype_as_str(term), term.name()); - log().debug("{1} {2}\n", objtype_as_str(term), term.name()); + log().fatal(MF_2_ADDING_1_2_TO_TERMINAL_LIST, termtype_as_str(term), + term.name()); + log().debug("{1} {2}\n", termtype_as_str(term), term.name()); } void setup_t::register_link_arr(const pstring &terms) { - plib::pstring_vector_t list(terms,", "); + std::vector<pstring> list(plib::psplit(terms,", ")); if (list.size() < 2) - log().fatal("You must pass at least 2 terminals to NET_C"); + 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]); @@ -245,7 +239,7 @@ void setup_t::remove_connections(const pstring pin) link++; } if (!found) - log().fatal("remove_connections: found no occurrence of {1}\n", pin); + log().fatal(MF_1_FOUND_NO_OCCURRENCE_OF_1, pin); } @@ -274,7 +268,7 @@ void setup_t::register_frontier(const pstring attach, const double r_IN, const d } } if (!found) - log().fatal("Frontier setup: found no occurrence of {1}\n", attach); + log().fatal(MF_1_FOUND_NO_OCCURRENCE_OF_1, attach); register_link(attach, frontier_name + ".Q"); } @@ -292,11 +286,13 @@ void setup_t::register_param(const pstring ¶m, const pstring &value) if (idx == m_param_values.end()) { if (!m_param_values.insert({fqn, value}).second) - log().fatal("Unexpected error adding parameter {1} to parameter list\n", param); + log().fatal(MF_1_ADDING_PARAMETER_1_TO_PARAMETER_LIST, + param); } else { - log().warning("Overwriting {1} old <{2}> new <{3}>\n", fqn, idx->second, value); + log().warning(MW_3_OVERWRITING_PARAM_1_OLD_2_NEW_3, fqn, idx->second, + value); m_param_values[fqn] = value; } } @@ -331,32 +327,32 @@ detail::core_terminal_t *setup_t::find_terminal(const pstring &terminal_in, bool detail::core_terminal_t *term = (ret == m_terminals.end() ? nullptr : ret->second); if (term == nullptr && required) - log().fatal("terminal {1}({2}) not found!\n", terminal_in, tname); + log().fatal(MF_2_TERMINAL_1_2_NOT_FOUND, terminal_in, tname); if (term != nullptr) log().debug("Found input {1}\n", tname); return term; } detail::core_terminal_t *setup_t::find_terminal(const pstring &terminal_in, - detail::device_object_t::type_t atype, bool required) + detail::terminal_type atype, bool required) { const pstring &tname = resolve_alias(terminal_in); auto ret = m_terminals.find(tname); /* look for default */ - if (ret == m_terminals.end() && atype == detail::device_object_t::OUTPUT) + if (ret == m_terminals.end() && atype == detail::terminal_type::OUTPUT) { /* look for ".Q" std output */ ret = m_terminals.find(tname + ".Q"); } if (ret == m_terminals.end() && required) - log().fatal("terminal {1}({2}) not found!\n", terminal_in, tname); + log().fatal(MF_2_TERMINAL_1_2_NOT_FOUND, terminal_in, tname); detail::core_terminal_t *term = (ret == m_terminals.end() ? nullptr : ret->second); if (term != nullptr && term->type() != atype) { if (required) - log().fatal("object {1}({2}) found but wrong type\n", terminal_in, tname); + log().fatal(MF_2_OBJECT_1_2_WRONG_TYPE, terminal_in, tname); else term = nullptr; } @@ -373,18 +369,17 @@ param_t *setup_t::find_param(const pstring ¶m_in, bool required) const const pstring &outname = resolve_alias(param_in_fqn); auto ret = m_params.find(outname); if (ret == m_params.end() && required) - log().fatal("parameter {1}({2}) not found!\n", param_in_fqn, outname); + log().fatal(MF_2_PARAMETER_1_2_NOT_FOUND, param_in_fqn, outname); if (ret != m_params.end()) log().debug("Found parameter {1}\n", outname); return (ret == m_params.end() ? nullptr : &ret->second.m_param); } -// FIXME avoid dynamic cast here devices::nld_base_proxy *setup_t::get_d_a_proxy(detail::core_terminal_t &out) { nl_assert(out.is_logic()); - logic_output_t &out_cast = dynamic_cast<logic_output_t &>(out); + logic_output_t &out_cast = static_cast<logic_output_t &>(out); devices::nld_base_proxy *proxy = out_cast.get_proxy(); if (proxy == nullptr) @@ -403,7 +398,8 @@ devices::nld_base_proxy *setup_t::get_d_a_proxy(detail::core_terminal_t &out) { p->clear_net(); // de-link from all nets ... if (!connect(new_proxy->proxy_term(), *p)) - log().fatal("Error connecting {1} to {2}\n", new_proxy->proxy_term().name(), (*p).name()); + log().fatal(MF_2_CONNECTING_1_TO_2, + new_proxy->proxy_term().name(), (*p).name()); } out.net().m_core_terms.clear(); // clear the list @@ -437,7 +433,6 @@ devices::nld_base_proxy *setup_t::get_a_d_proxy(detail::core_terminal_t &inp) auto ret = new_proxy.get(); -#if 1 /* connect all existing terminals to new net */ if (inp.has_net()) @@ -446,18 +441,12 @@ devices::nld_base_proxy *setup_t::get_a_d_proxy(detail::core_terminal_t &inp) { p->clear_net(); // de-link from all nets ... if (!connect(ret->proxy_term(), *p)) - log().fatal("Error connecting {1} to {2}\n", ret->proxy_term().name(), (*p).name()); + log().fatal(MF_2_CONNECTING_1_TO_2, + ret->proxy_term().name(), (*p).name()); } inp.net().m_core_terms.clear(); // clear the list } ret->out().net().add_terminal(inp); -#else - if (inp.has_net()) - //fatalerror("logic inputs can only belong to one net!\n"); - merge_nets(ret->out().net(), inp.net()); - else - ret->out().net().add_terminal(inp); -#endif netlist().register_dev(std::move(new_proxy)); return ret; } @@ -465,19 +454,20 @@ devices::nld_base_proxy *setup_t::get_a_d_proxy(detail::core_terminal_t &inp) void setup_t::merge_nets(detail::net_t &thisnet, detail::net_t &othernet) { - netlist().log().debug("merging nets ...\n"); + log().debug("merging nets ...\n"); if (&othernet == &thisnet) { - netlist().log().warning("Connecting {1} to itself. This may be right, though\n", thisnet.name()); + log().warning(MW_1_CONNECTING_1_TO_ITSELF, thisnet.name()); return; // Nothing to do } if (thisnet.isRailNet() && othernet.isRailNet()) - netlist().log().fatal("Trying to merge two rail nets: {1} and {2}\n", thisnet.name(), othernet.name()); + log().fatal(MF_2_MERGE_RAIL_NETS_1_AND_2, + thisnet.name(), othernet.name()); if (othernet.isRailNet()) { - netlist().log().debug("othernet is railnet\n"); + log().debug("othernet is railnet\n"); merge_nets(othernet, thisnet); } else @@ -521,7 +511,8 @@ void setup_t::connect_terminal_input(terminal_t &term, detail::core_terminal_t & } else if (inp.is_logic()) { - netlist().log().verbose("connect terminal {1} (in, {2}) to {3}\n", inp.name(), pstring(inp.is_analog() ? "analog" : inp.is_logic() ? "logic" : "?"), term.name()); + log().verbose("connect terminal {1} (in, {2}) to {3}\n", inp.name(), + inp.is_analog() ? pstring("analog") : inp.is_logic() ? pstring("logic") : pstring("?"), term.name()); auto proxy = get_a_d_proxy(inp); //out.net().register_con(proxy->proxy_term()); @@ -530,7 +521,7 @@ void setup_t::connect_terminal_input(terminal_t &term, detail::core_terminal_t & } else { - log().fatal("Netlist: Severe Error"); + log().fatal(MF_1_OBJECT_INPUT_TYPE_1, inp.name()); } } @@ -554,7 +545,7 @@ void setup_t::connect_terminal_output(terminal_t &in, detail::core_terminal_t &o } else { - log().fatal("Netlist: Severe Error"); + log().fatal(MF_1_OBJECT_OUTPUT_TYPE_1, out.name()); } } @@ -609,7 +600,7 @@ bool setup_t::connect_input_input(detail::core_terminal_t &t1, detail::core_term { for (auto & t : t1.net().m_core_terms) { - if (t->is_type(detail::core_terminal_t::TERMINAL)) + if (t->is_type(detail::terminal_type::TERMINAL)) ret = connect(t2, *t); if (ret) break; @@ -624,7 +615,7 @@ bool setup_t::connect_input_input(detail::core_terminal_t &t1, detail::core_term { for (auto & t : t2.net().m_core_terms) { - if (t->is_type(detail::core_terminal_t::TERMINAL)) + if (t->is_type(detail::terminal_type::TERMINAL)) ret = connect(t1, *t); if (ret) break; @@ -643,39 +634,39 @@ bool setup_t::connect(detail::core_terminal_t &t1_in, detail::core_terminal_t &t detail::core_terminal_t &t2 = resolve_proxy(t2_in); bool ret = true; - if (t1.is_type(detail::core_terminal_t::OUTPUT) && t2.is_type(detail::core_terminal_t::INPUT)) + if (t1.is_type(detail::terminal_type::OUTPUT) && t2.is_type(detail::terminal_type::INPUT)) { if (t2.has_net() && t2.net().isRailNet()) - log().fatal("Input {1} already connected\n", t2.name()); + log().fatal(MF_1_INPUT_1_ALREADY_CONNECTED, t2.name()); connect_input_output(t2, t1); } - else if (t1.is_type(detail::core_terminal_t::INPUT) && t2.is_type(detail::core_terminal_t::OUTPUT)) + else if (t1.is_type(detail::terminal_type::INPUT) && t2.is_type(detail::terminal_type::OUTPUT)) { if (t1.has_net() && t1.net().isRailNet()) - log().fatal("Input {1} already connected\n", t1.name()); + log().fatal(MF_1_INPUT_1_ALREADY_CONNECTED, t1.name()); connect_input_output(t1, t2); } - else if (t1.is_type(detail::core_terminal_t::OUTPUT) && t2.is_type(detail::core_terminal_t::TERMINAL)) + 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::core_terminal_t::TERMINAL) && t2.is_type(detail::core_terminal_t::OUTPUT)) + 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::core_terminal_t::INPUT) && t2.is_type(detail::core_terminal_t::TERMINAL)) + 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::core_terminal_t::TERMINAL) && t2.is_type(detail::core_terminal_t::INPUT)) + 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::core_terminal_t::TERMINAL) && t2.is_type(detail::core_terminal_t::TERMINAL)) + 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::core_terminal_t::INPUT) && t2.is_type(detail::core_terminal_t::INPUT)) + else if (t1.is_type(detail::terminal_type::INPUT) && t2.is_type(detail::terminal_type::INPUT)) { ret = connect_input_input(t1, t2); } @@ -693,8 +684,8 @@ void setup_t::resolve_inputs() * We therefore first park connecting inputs and retry * after all other terminals were connected. */ - int tries = 100; - while (m_links.size() > 0 && tries > 0) // FIXME: convert into constant + int tries = NL_MAX_LINK_RESOLVE_LOOPS; + while (m_links.size() > 0 && tries > 0) { for (auto li = m_links.begin(); li != m_links.end(); ) @@ -714,9 +705,9 @@ void setup_t::resolve_inputs() if (tries == 0) { for (auto & link : m_links) - log().warning("Error connecting {1} to {2}\n", link.first, link.second); + log().warning(MF_2_CONNECTING_1_TO_2, link.first, link.second); - log().fatal("Error connecting -- bailing out\n"); + log().fatal(MF_0_LINK_TRIES_EXCEEDED); } log().verbose("deleting empty nets ..."); @@ -743,38 +734,26 @@ void setup_t::resolve_inputs() { detail::core_terminal_t *term = i.second; if (!term->has_net() && dynamic_cast< devices::NETLIB_NAME(dummy_input) *>(&term->device()) != nullptr) - log().warning("Found dummy terminal {1} without connections", term->name()); + log().warning(MW_1_DUMMY_1_WITHOUT_CONNECTIONS, term->name()); else if (!term->has_net()) errstr += plib::pfmt("Found terminal {1} without a net\n")(term->name()); else if (term->net().num_cons() == 0) - log().warning("Found terminal {1} without connections", term->name()); + log().warning(MW_1_TERMINAL_1_WITHOUT_CONNECTIONS, term->name()); } + //FIXME: error string handling if (errstr != "") log().fatal("{1}", errstr); - - log().verbose("looking for two terms connected to rail nets ..."); - for (auto & t : netlist().get_device_list<analog::NETLIB_NAME(twoterm)>()) - { - if (t->m_N.net().isRailNet() && t->m_P.net().isRailNet()) - { - log().warning("Found device {1} connected only to railterminals {2}/{3}. Will be removed", - t->name(), t->m_N.net().name(), t->m_P.net().name()); - t->m_N.net().remove_terminal(t->m_N); - t->m_P.net().remove_terminal(t->m_P); - netlist().remove_dev(t); - } - } } void setup_t::start_devices() { - pstring env = plib::util::environment("NL_LOGS"); + pstring env = plib::util::environment("NL_LOGS", ""); if (env != "") { log().debug("Creating dynamic logs ..."); - plib::pstring_vector_t loglist(env, ":"); + std::vector<pstring> loglist(plib::psplit(env, ":")); for (pstring ll : loglist) { pstring name = "log_" + ll; @@ -800,7 +779,7 @@ const plib::plog_base<NL_DEBUG> &setup_t::log() const // Model // ---------------------------------------------------------------------------------------- -static pstring model_string(model_map_t &map) +static pstring model_string(detail::model_map_t &map) { pstring ret = map["COREMODEL"] + "("; for (auto & i : map) @@ -809,7 +788,7 @@ static pstring model_string(model_map_t &map) return ret + ")"; } -void setup_t::model_parse(const pstring &model_in, model_map_t &map) +void setup_t::model_parse(const pstring &model_in, detail::model_map_t &map) { pstring model = model_in; pstring::iterator pos(nullptr); @@ -823,7 +802,7 @@ void setup_t::model_parse(const pstring &model_in, model_map_t &map) key = model.ucase(); auto i = m_models.find(key); if (i == m_models.end()) - log().fatal("Model {1} not found\n", model); + log().fatal(MF_1_MODEL_NOT_FOUND, model); model = i->second; } pstring xmodel = model.left(pos); @@ -836,40 +815,41 @@ void setup_t::model_parse(const pstring &model_in, model_map_t &map) if (i != m_models.end()) model_parse(xmodel, map); else - log().fatal("Model doesn't exist: <{1}>\n", model_in); + log().fatal(MF_1_MODEL_NOT_FOUND, model_in); } pstring remainder=model.substr(pos+1).trim(); if (!remainder.endsWith(")")) - log().fatal("Model error {1}\n", model); + log().fatal(MF_1_MODEL_ERROR_1, model); // FIMXE: Not optimal remainder = remainder.left(remainder.begin() + (remainder.len() - 1)); - plib::pstring_vector_t pairs(remainder," ", true); + std::vector<pstring> pairs(plib::psplit(remainder," ", true)); for (pstring &pe : pairs) { auto pose = pe.find("="); if (pose == pe.end()) - log().fatal("Model error on pair {1}\n", model); + log().fatal(MF_1_MODEL_ERROR_ON_PAIR_1, model); map[pe.left(pose).ucase()] = pe.substr(pose+1); } } -const pstring setup_t::model_value_str(model_map_t &map, const pstring &entity) +const pstring setup_t::model_value_str(detail::model_map_t &map, const pstring &entity) { pstring ret; if (entity != entity.ucase()) - log().fatal("model parameters should be uppercase:{1} {2}\n", entity, model_string(map)); + log().fatal(MF_2_MODEL_PARAMETERS_NOT_UPPERCASE_1_2, entity, + model_string(map)); if (map.find(entity) == map.end()) - log().fatal("Entity {1} not found in model {2}\n", entity, model_string(map)); + log().fatal(MF_2_ENTITY_1_NOT_FOUND_IN_MODEL_2, entity, model_string(map)); else ret = map[entity]; return ret; } -nl_double setup_t::model_value(model_map_t &map, const pstring &entity) +nl_double setup_t::model_value(detail::model_map_t &map, const pstring &entity) { pstring tmp = model_value_str(map, entity); @@ -887,16 +867,67 @@ nl_double setup_t::model_value(model_map_t &map, const pstring &entity) case 'a': factor = 1e-18; break; default: if (*p < '0' || *p > '9') - nl_exception(plib::pfmt("Unknown number factor in: {1}")(entity)); + log().fatal(MF_1_UNKNOWN_NUMBER_FACTOR_IN_1, entity); } if (factor != NL_FCONST(1.0)) tmp = tmp.left(tmp.begin() + (tmp.len() - 1)); return tmp.as_double() * factor; } -void setup_t::tt_factory_create(tt_desc &desc) +class logic_family_std_proxy_t : public logic_family_desc_t +{ +public: + logic_family_std_proxy_t() { } + virtual plib::owned_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_t &anetlist, + const pstring &name, logic_output_t *proxied) const override; + virtual plib::owned_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *proxied) const override; +}; + +plib::owned_ptr<devices::nld_base_d_to_a_proxy> logic_family_std_proxy_t::create_d_a_proxy(netlist_t &anetlist, + const pstring &name, logic_output_t *proxied) const +{ + return plib::owned_ptr<devices::nld_base_d_to_a_proxy>::Create<devices::nld_d_to_a_proxy>(anetlist, name, proxied); +} +plib::owned_ptr<devices::nld_base_a_to_d_proxy> logic_family_std_proxy_t::create_a_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *proxied) const +{ + return plib::owned_ptr<devices::nld_base_a_to_d_proxy>::Create<devices::nld_a_to_d_proxy>(anetlist, name, proxied); +} + + +const logic_family_desc_t *setup_t::family_from_model(const pstring &model) { - devices::tt_factory_create(*this, desc); + detail::model_map_t map; + model_parse(model, map); + + if (model_value_str(map, "TYPE") == "TTL") + return family_TTL(); + if (model_value_str(map, "TYPE") == "CD4XXX") + return family_CD4XXX(); + + for (auto & e : netlist().m_family_cache) + if (e.first == model) + return e.second.get(); + + auto ret = plib::make_unique_base<logic_family_desc_t, logic_family_std_proxy_t>(); + + ret->m_fixed_V = model_value(map, "FV"); + ret->m_low_thresh_PCNT = model_value(map, "IVL"); + ret->m_high_thresh_PCNT = model_value(map, "IVH"); + ret->m_low_VO = model_value(map, "OVL"); + ret->m_high_VO = model_value(map, "OVH"); + ret->m_R_low = model_value(map, "ORL"); + ret->m_R_high = model_value(map, "ORH"); + + auto retp = ret.get(); + + netlist().m_family_cache.emplace_back(model, std::move(ret)); + + return retp; +} + +void setup_t::tt_factory_create(tt_desc &desc, const pstring &sourcefile) +{ + devices::tt_factory_create(*this, desc, sourcefile); } @@ -911,7 +942,7 @@ void setup_t::include(const pstring &netlist_name) if (source->parse(netlist_name)) return; } - log().fatal("unable to find {1} in source collection", netlist_name); + log().fatal(MF_1_NOT_FOUND_IN_SOURCE_COLLECTION, netlist_name); } std::unique_ptr<plib::pistream> setup_t::get_data_stream(const pstring name) @@ -925,18 +956,21 @@ std::unique_ptr<plib::pistream> setup_t::get_data_stream(const pstring name) return strm; } } - //log().fatal("unable to find data named {1} in source collection", name); - log().warning("unable to find data named {1} in source collection", name); + log().warning(MW_1_DATA_1_NOT_FOUND, name); return std::unique_ptr<plib::pistream>(nullptr); } -bool setup_t::parse_stream(plib::pistream &istrm, const pstring &name) +bool setup_t::parse_stream(plib::putf8_reader &istrm, const pstring &name) { plib::pomemstream ostrm; + plib::putf8_writer owrt(ostrm); - plib::pimemstream istrm2(plib::ppreprocessor(&m_defines).process(istrm, ostrm)); - return parser_t(istrm2, *this).parse(name); + plib::ppreprocessor(&m_defines).process(istrm, owrt); + + plib::pimemstream istrm2(ostrm); + plib::putf8_reader reader2(istrm2); + return parser_t(reader2, *this).parse(name); } void setup_t::register_define(pstring defstr) @@ -957,7 +991,11 @@ bool source_t::parse(const pstring &name) if (m_type != SOURCE) return false; else - return m_setup.parse_stream(*stream(name), name); + { + auto rstream = stream(name); + plib::putf8_reader reader(*rstream); + return m_setup.parse_stream(reader, name); + } } std::unique_ptr<plib::pistream> source_string_t::stream(const pstring &name) |