mirror of
https://github.com/holub/mame
synced 2025-10-04 16:34:53 +03:00
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:
parent
7624f7490f
commit
55000018e7
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
@ -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:
|
||||
};
|
||||
|
@ -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 ¶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
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
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 ¶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)
|
||||
|
||||
void setup_t::register_param_t(const pstring &name, param_t ¶m)
|
||||
{
|
||||
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 ¶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 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)
|
||||
|
@ -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 ¶m, const pstring &value);
|
||||
void register_param(const pstring ¶m, 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 ¶m);
|
||||
void register_param_t(const pstring &name, param_t ¶m);
|
||||
|
||||
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 ¶m, const pstring &value);
|
||||
void register_param(const pstring ¶m, 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 ¶m_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;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
@ -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 ...
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user