netlist: Separation of duties. (nw)

Make it clearer what is used during parsing a netlist, "compiling" a
netlist and execution of a netlist.
This commit is contained in:
couriersud 2019-02-16 14:31:59 +01:00
parent 7624f7490f
commit 55000018e7
9 changed files with 308 additions and 295 deletions

View File

@ -232,10 +232,10 @@ maketree: $(sort $(OBJDIRS))
.PHONY: clang clang-5 mingw doc native
native:
$(MAKE) CEXTRAFLAGS="-march=native -Wall -Wpedantic -Wsign-compare -Wextra -Wno-unused-parameter"
$(MAKE) CEXTRAFLAGS="-march=native -Wall -Wpedantic -Wsign-compare -Wextra "
clang:
$(MAKE) CC=clang++-9 LD=clang++-9 CEXTRAFLAGS="-march=native -Wno-unused-parameter -Weverything -Werror -Wno-unused-template -Wno-non-virtual-dtor -Wno-unreachable-code -Wno-padded -Wno-weak-vtables -Wno-missing-variable-declarations -Wconversion -Wno-c++98-compat -Wno-float-equal -Wno-global-constructors -Wno-c++98-compat-pedantic -Wno-format-nonliteral -Wweak-template-vtables -Wno-exit-time-destructors"
$(MAKE) CC=clang++-9 LD=clang++-9 CEXTRAFLAGS="-march=native -Weverything -Werror -Wno-unused-template -Wno-non-virtual-dtor -Wno-unreachable-code -Wno-padded -Wno-weak-vtables -Wno-missing-variable-declarations -Wconversion -Wno-c++98-compat -Wno-float-equal -Wno-global-constructors -Wno-c++98-compat-pedantic -Wno-format-nonliteral -Wweak-template-vtables -Wno-exit-time-destructors"
clang-5:
$(MAKE) CC=clang++-5.0 LD=clang++-5.0 CEXTRAFLAGS="-march=native -Weverything -Werror -Wno-inconsistent-missing-destructor-override -Wno-unreachable-code -Wno-padded -Wno-weak-vtables -Wno-missing-variable-declarations -Wconversion -Wno-c++98-compat -Wno-float-equal -Wno-global-constructors -Wno-c++98-compat-pedantic -Wno-format-nonliteral -Wno-weak-template-vtables -Wno-exit-time-destructors"

View File

@ -232,7 +232,12 @@ namespace netlist
m_ttbl.m_timing_index.data(), m_ttbl.m_timing_nt.data());
desc_s.parse(m_desc);
return pool().make_poolptr<tt_type>(anetlist, name, m_family, m_ttbl, m_desc);
/* update truthtable family definitions */
if (m_family_name != "")
m_family_desc = anetlist.setup().family_from_model(m_family_name);
return pool().make_poolptr<tt_type>(anetlist, name, m_family_desc, m_ttbl, m_desc);
}
private:
typename nld_truthtable_t<m_NI, m_NO>::truthtable_t m_ttbl;
@ -447,7 +452,7 @@ void truthtable_parser::parse(const std::vector<pstring> &truthtable)
netlist_base_factory_truthtable_t::netlist_base_factory_truthtable_t(const pstring &name, const pstring &classname,
const pstring &def_param, const pstring &sourcefile)
: factory::element_t(name, classname, def_param, sourcefile), m_family(family_TTL())
: factory::element_t(name, classname, def_param, sourcefile), m_family_desc(family_TTL())
{
}
@ -459,7 +464,7 @@ netlist_base_factory_truthtable_t::netlist_base_factory_truthtable_t(const pstri
ENTRYY(n, 4, s); ENTRYY(n, 5, s); ENTRYY(n, 6, s); \
ENTRYY(n, 7, s); ENTRYY(n, 8, s)
void tt_factory_create(setup_t &setup, tt_desc &desc, const pstring &sourcefile)
std::unique_ptr<netlist_base_factory_truthtable_t> tt_factory_create(tt_desc &desc, const pstring &sourcefile)
{
std::unique_ptr<netlist_base_factory_truthtable_t> ret;
@ -482,9 +487,9 @@ void tt_factory_create(setup_t &setup, tt_desc &desc, const pstring &sourcefile)
nl_assert_always(false, msg);
}
ret->m_desc = desc.desc;
if (desc.family != "")
ret->m_family = setup.family_from_model(desc.family);
setup.factory().register_device(std::move(ret));
ret->m_family_name = desc.family;
return ret;
}
} //namespace devices

View File

@ -220,10 +220,12 @@ namespace devices
const pstring &def_param, const pstring &sourcefile);
std::vector<pstring> m_desc;
const logic_family_desc_t *m_family;
pstring m_family_name;
const logic_family_desc_t *m_family_desc;
};
void tt_factory_create(setup_t &setup, tt_desc &desc, const pstring &sourcefile);
/* the returned element is still missing a pointer to the family ... */
std::unique_ptr<netlist_base_factory_truthtable_t> tt_factory_create(tt_desc &desc, const pstring &sourcefile);
} //namespace devices
} // namespace netlist

View File

@ -954,7 +954,7 @@ logic_input_t::logic_input_t(core_device_t &dev, const pstring &aname,
param_t::param_t(device_t &device, const pstring &name)
: device_object_t(device, device.name() + "." + name)
{
device.setup().register_param(this->name(), *this);
device.setup().register_param_t(this->name(), *this);
}
param_t::param_type_t param_t::param_type() const

View File

@ -47,8 +47,8 @@ namespace netlist { namespace factory
// net_device_t_base_factory
// ----------------------------------------------------------------------------------------
list_t::list_t( setup_t &setup)
: m_setup(setup)
list_t::list_t(log_type &alog)
: m_log(alog)
{
}
@ -56,7 +56,7 @@ namespace netlist { namespace factory
{
for (auto & e : *this)
if (e->name() == factory->name())
m_setup.log().fatal(MF_1_FACTORY_ALREADY_CONTAINS_1, factory->name());
m_log.fatal(MF_1_FACTORY_ALREADY_CONTAINS_1, factory->name());
push_back(std::move(factory));
}
@ -68,7 +68,7 @@ namespace netlist { namespace factory
return e.get();
}
m_setup.log().fatal(MF_1_CLASS_1_NOT_FOUND, devname);
m_log.fatal(MF_1_CLASS_1_NOT_FOUND, devname);
return nullptr; // appease code analysis
}
@ -81,11 +81,11 @@ namespace netlist { namespace factory
return pool().make_poolptr<NETLIB_NAME(wrapper)>(anetlist, name);
}
void library_element_t::macro_actions(netlist_state_t &anetlist, const pstring &name)
void library_element_t::macro_actions(nlparse_t &nparser, const pstring &name)
{
anetlist.setup().namespace_push(name);
anetlist.setup().include(this->name());
anetlist.setup().namespace_pop();
nparser.namespace_push(name);
nparser.include(this->name());
nparser.namespace_pop();
}

View File

@ -35,6 +35,7 @@
namespace netlist {
class device_t;
class nlparse_t;
class setup_t;
class netlist_state_t;
@ -55,9 +56,9 @@ namespace factory {
COPYASSIGNMOVE(element_t, default)
virtual poolptr<device_t> Create(netlist_state_t &anetlist, const pstring &name) = 0;
virtual void macro_actions(netlist_state_t &anetlist, const pstring &name)
virtual void macro_actions(nlparse_t &nparser, const pstring &name)
{
plib::unused_var(anetlist);
plib::unused_var(nparser);
plib::unused_var(name);
}
@ -93,7 +94,7 @@ namespace factory {
class list_t : public std::vector<std::unique_ptr<element_t>>
{
public:
explicit list_t(setup_t &m_setup);
explicit list_t(log_type &alog);
~list_t() = default;
COPYASSIGNMOVE(list_t, delete)
@ -116,7 +117,7 @@ namespace factory {
}
private:
setup_t &m_setup;
log_type &m_log;
};
// -----------------------------------------------------------------------------
@ -140,17 +141,15 @@ namespace factory {
{
public:
library_element_t(setup_t &setup, const pstring &name, const pstring &classname,
library_element_t(const pstring &name, const pstring &classname,
const pstring &def_param, const pstring &source)
: element_t(name, classname, def_param, source)
{
// FIXME: if it is not used, remove it
plib::unused_var(setup);
}
poolptr<device_t> Create(netlist_state_t &anetlist, const pstring &name) override;
void macro_actions(netlist_state_t &anetlist, const pstring &name) override;
void macro_actions(nlparse_t &nparser, const pstring &name) override;
private:
};

View File

@ -19,18 +19,215 @@
#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)
{ }
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);
}
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]);
}
}
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 nlparse_t::register_link(const pstring &sin, const pstring &sout)
{
register_link_fqn(build_fqn(sin), build_fqn(sout));
}
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 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 nlparse_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::namespace_pop()
{
m_namespace_stack.pop();
}
void nlparse_t::register_param(const pstring &param, 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 &param, 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
// ----------------------------------------------------------------------------------------
setup_t::setup_t(netlist_t &netlist)
: nlparse_t(netlist)
, m_netlist(netlist)
, m_netlist_params(nullptr)
, m_proxy_cnt(0)
{
}
@ -38,7 +235,6 @@ 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();
@ -54,99 +250,6 @@ const netlist_state_t &setup_t::netlist() const
return m_netlist.nlstate();
}
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 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 setup_t::namespace_pop()
{
m_namespace_stack.pop();
}
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 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
{
/* 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);
else
m_device_factory.insert(m_device_factory.end(), {key, f});
}
}
bool setup_t::device_exists(const pstring &name) const
{
for (auto &d : m_device_factory)
if (d.first == name)
return true;
return false;
}
void setup_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);
}
void setup_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 setup_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 setup_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::termtype_as_str(detail::core_terminal_t &in) const
{
switch (in.type())
@ -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 &param)
{
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)
void setup_t::register_param_t(const pstring &name, param_t &param)
{
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");
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 &param, 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 setup_t::register_param(const pstring &param, 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)

View File

@ -14,14 +14,12 @@
#include <vector>
#include "plib/pparser.h"
//#include "plib/pstate.h"
#include "plib/pstream.h"
#include "plib/pstring.h"
#include "plib/putil.h"
#include "netlist_types.h"
#include "nl_config.h"
//#include "nl_errstr.h"
#include "nl_factory.h"
//============================================================
@ -208,27 +206,71 @@ namespace netlist
// setup_t
// ----------------------------------------------------------------------------------------
// setup.register_alias(# alias, # name);
// setup.register_model(model);
// setup.register_dippins_arr( # pin1 ", " # __VA_ARGS__);
// setup.register_dev(# type, # name);
// setup.register_link(# name "." # input, # output);
// setup.register_link_arr( # term1 ", " # __VA_ARGS__);
// setup.register_param(# name, val);
// setup.register_lib_entry(# name, __FILE__);
// setup.include(# name);
// setup.namespace_push(# name);
// NETLIST_NAME(model)(setup);
// setup.namespace_pop();
// setup.register_frontier(# attach, r_in, r_out);
// setup.tt_factory_create(desc, __FILE__);
class setup_t
class nlparse_t
{
public:
using link_t = std::pair<pstring, pstring>;
nlparse_t(netlist_t &netlist);
void register_model(const pstring &model_in);
void register_alias(const pstring &alias, const pstring &out);
void register_dippins_arr(const pstring &terms);
void register_dev(const pstring &classname, const pstring &name);
void register_link(const pstring &sin, const pstring &sout);
void register_link_arr(const pstring &terms);
void register_param(const pstring &param, const pstring &value);
void register_param(const pstring &param, const double value);
void register_lib_entry(const pstring &name, const pstring &sourcefile);
void register_frontier(const pstring &attach, const double r_IN, const double r_OUT);
void tt_factory_create(tt_desc &desc, const pstring &sourcefile);
/* handle namespace */
void namespace_push(const pstring &aname);
void namespace_pop();
/* include other files */
void include(const pstring &netlist_name);
/* parse a source */
pstring build_fqn(const pstring &obj_name) const;
void register_alias_nofqn(const pstring &alias, const pstring &out);
/* also called from devices for latebinding connected terminals */
void register_link_fqn(const pstring &sin, const pstring &sout);
/* used from netlist.cpp (mame) */
bool device_exists(const pstring &name) const;
protected:
std::unordered_map<pstring, pstring> m_models;
std::stack<pstring> m_namespace_stack;
std::unordered_map<pstring, pstring> m_alias;
std::vector<link_t> m_links;
std::unordered_map<pstring, pstring> m_param_values;
source_t::list_t m_sources;
factory::list_t m_factory;
/* need to preserve order of device creation ... */
std::vector<std::pair<pstring, factory::element_t *>> m_device_factory;
private:
log_type &log() { return m_log; }
const log_type &log() const { return m_log; }
log_type &m_log;
unsigned m_frontier_cnt;
};
class setup_t : public nlparse_t
{
public:
explicit setup_t(netlist_t &netlist);
~setup_t() noexcept;
@ -240,53 +282,21 @@ namespace netlist
netlist_t &exec() { return m_netlist; }
const netlist_t &exec() const { return m_netlist; }
pstring build_fqn(const pstring &obj_name) const;
void register_param(const pstring &name, param_t &param);
void register_param_t(const pstring &name, param_t &param);
pstring get_initial_param_val(const pstring &name, const pstring &def) const;
void register_term(detail::core_terminal_t &obj);
void register_dev(const pstring &classname, const pstring &name);
void register_lib_entry(const pstring &name, const pstring &sourcefile);
void register_model(const pstring &model_in);
void register_alias(const pstring &alias, const pstring &out);
void register_dippins_arr(const pstring &terms);
void register_alias_nofqn(const pstring &alias, const pstring &out);
void register_link_arr(const pstring &terms);
void register_link_fqn(const pstring &sin, const pstring &sout);
void register_link(const pstring &sin, const pstring &sout);
void register_param(const pstring &param, const pstring &value);
void register_param(const pstring &param, const double value);
void register_frontier(const pstring &attach, const double r_IN, const double r_OUT);
void remove_connections(const pstring &attach);
bool connect(detail::core_terminal_t &t1, detail::core_terminal_t &t2);
bool device_exists(const pstring &name) const;
param_t *find_param(const pstring &param_in, bool required = true) const;
void register_dynamic_log_devices();
void resolve_inputs();
/* handle namespace */
void namespace_push(const pstring &aname);
void namespace_pop();
/* parse a source */
void include(const pstring &netlist_name);
std::unique_ptr<plib::pistream> get_data_stream(const pstring &name);
bool parse_stream(std::unique_ptr<plib::pistream> istrm, const pstring &name);
@ -317,8 +327,6 @@ namespace netlist
const logic_family_desc_t *family_from_model(const pstring &model);
void tt_factory_create(tt_desc &desc, const pstring &sourcefile);
/* helper - also used by nltool */
const pstring resolve_alias(const pstring &name) const;
@ -357,28 +365,15 @@ namespace netlist
devices::nld_base_proxy *get_d_a_proxy(detail::core_terminal_t &out);
devices::nld_base_proxy *get_a_d_proxy(detail::core_terminal_t &inp);
/* need to preserve order of device creation ... */
std::vector<std::pair<pstring, factory::element_t *>> m_device_factory;
//std::unordered_map<pstring, factory::element_t *> m_device_factory;
std::unordered_map<pstring, pstring> m_alias;
std::unordered_map<pstring, pstring> m_param_values;
std::unordered_map<pstring, detail::core_terminal_t *> m_terminals;
netlist_t &m_netlist;
devices::nld_netlistparams *m_netlist_params;
std::unordered_map<pstring, param_ref_t> m_params;
std::vector<link_t> m_links;
factory::list_t m_factory;
std::unordered_map<pstring, pstring> m_models;
std::stack<pstring> m_namespace_stack;
source_t::list_t m_sources;
plib::ppreprocessor::defines_map_type m_defines;
unsigned m_proxy_cnt;
unsigned m_frontier_cnt;
};
// ----------------------------------------------------------------------------------------

View File

@ -139,7 +139,7 @@ std::unique_ptr<plib::pistream> netlist_data_folder_t::stream(const pstring &fil
try
{
auto strm = plib::make_unique<plib::pifilestream>(name);
return strm;
return std::move(strm);
}
catch (const plib::pexception &e)
{
@ -632,7 +632,7 @@ void tool_app_t::listdevices()
{
pstring out = plib::pfmt("{1:-20} {2}(<id>")(f->classname())(f->name());
f->macro_actions(nt.setup().netlist(), f->name() + "_lc");
f->macro_actions(nt.setup(), f->name() + "_lc");
auto d = f->Create(nt.setup().netlist(), f->name() + "_lc");
// get the list of terminals ...