summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/nl_setup.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/netlist/nl_setup.cpp')
-rw-r--r--src/lib/netlist/nl_setup.cpp272
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 &param)
{
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 &param, 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 &param_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)