summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/netlist/analog/nld_twoterm.h25
-rw-r--r--src/lib/netlist/analog/nlid_twoterm.h4
-rw-r--r--src/lib/netlist/devices/net_lib.h32
-rw-r--r--src/lib/netlist/devices/nld_74ls629.h7
-rw-r--r--src/lib/netlist/devices/nld_system.cpp2
-rw-r--r--src/lib/netlist/devices/nld_system.h5
-rw-r--r--src/lib/netlist/devices/nlid_system.h4
-rw-r--r--src/lib/netlist/macro/nlm_base.cpp2
-rw-r--r--src/lib/netlist/macro/nlm_opamp.cpp2
-rw-r--r--src/lib/netlist/macro/nlm_opamp.h4
-rw-r--r--src/lib/netlist/macro/nlm_ttl74xx.h5
-rw-r--r--src/lib/netlist/nl_base.h11
-rw-r--r--src/lib/netlist/nl_dice_compat.h10
-rw-r--r--src/lib/netlist/nl_errstr.h2
-rw-r--r--src/lib/netlist/nl_parser.cpp134
-rw-r--r--src/lib/netlist/nl_setup.cpp86
-rw-r--r--src/lib/netlist/nl_setup.h17
-rw-r--r--src/lib/netlist/plib/pfunction.cpp87
-rw-r--r--src/lib/netlist/plib/pfunction.h23
-rw-r--r--src/lib/netlist/plib/ptokenizer.h10
-rw-r--r--src/lib/netlist/plib/putil.h1
-rw-r--r--src/lib/netlist/prg/nltool.cpp15
22 files changed, 382 insertions, 106 deletions
diff --git a/src/lib/netlist/analog/nld_twoterm.h b/src/lib/netlist/analog/nld_twoterm.h
index a1ebf8f4892..1ad39247660 100644
--- a/src/lib/netlist/analog/nld_twoterm.h
+++ b/src/lib/netlist/analog/nld_twoterm.h
@@ -15,39 +15,30 @@
// -----------------------------------------------------------------------------
#define RES(name, p_R) \
- NET_REGISTER_DEV(RES, name) \
- NETDEV_PARAMI(name, R, p_R)
+ NET_REGISTER_DEVEXT(RES, name, p_R)
#define POT(name, p_R) \
- NET_REGISTER_DEV(POT, name) \
- NETDEV_PARAMI(name, R, p_R)
+ NET_REGISTER_DEVEXT(POT, name, p_R)
// Does not have pin 3 connected
#define POT2(name, p_R) \
- NET_REGISTER_DEV(POT2, name) \
- NETDEV_PARAMI(name, R, p_R)
-
+ NET_REGISTER_DEVEXT(POT2, name, p_R)
#define CAP(name, p_C) \
- NET_REGISTER_DEV(CAP, name) \
- NETDEV_PARAMI(name, C, p_C)
+ NET_REGISTER_DEVEXT(CAP, name, p_C)
#define IND(name, p_L) \
- NET_REGISTER_DEV(IND, name) \
- NETDEV_PARAMI(name, L, p_L)
+ NET_REGISTER_DEVEXT(IND, name, p_L)
// Generic Diode
#define DIODE(name, model) \
- NET_REGISTER_DEV(DIODE, name) \
- NETDEV_PARAMI(name, MODEL, model)
+ NET_REGISTER_DEVEXT(DIODE, name, model)
#define VS(name, pV) \
- NET_REGISTER_DEV(VS, name) \
- NETDEV_PARAMI(name, V, pV)
+ NET_REGISTER_DEVEXT(VS, name, pV)
#define CS(name, pI) \
- NET_REGISTER_DEV(CS, name) \
- NETDEV_PARAMI(name, I, pI)
+ NET_REGISTER_DEVEXT(CS, name, pI)
// -----------------------------------------------------------------------------
// Generic macros
diff --git a/src/lib/netlist/analog/nlid_twoterm.h b/src/lib/netlist/analog/nlid_twoterm.h
index 0687dde55c9..99c962a5c8c 100644
--- a/src/lib/netlist/analog/nlid_twoterm.h
+++ b/src/lib/netlist/analog/nlid_twoterm.h
@@ -398,7 +398,7 @@ namespace analog
register_subalias("P", m_P);
register_subalias("N", m_N);
if (m_func() != "")
- m_compiled.compile(std::vector<pstring>({{pstring("T")}}), m_func());
+ m_compiled.compile(m_func(), std::vector<pstring>({{pstring("T")}}));
}
NETLIB_IS_TIMESTEP(m_func() != "")
@@ -447,7 +447,7 @@ namespace analog
register_subalias("P", m_P);
register_subalias("N", m_N);
if (m_func() != "")
- m_compiled.compile(std::vector<pstring>({{pstring("T")}}), m_func());
+ m_compiled.compile(m_func(), std::vector<pstring>({{pstring("T")}}));
}
NETLIB_IS_TIMESTEP(m_func() != "")
diff --git a/src/lib/netlist/devices/net_lib.h b/src/lib/netlist/devices/net_lib.h
index 342733f6c82..4cd621cd019 100644
--- a/src/lib/netlist/devices/net_lib.h
+++ b/src/lib/netlist/devices/net_lib.h
@@ -14,22 +14,38 @@
//#define NL_AUTO_DEVICES 1
-#define SOLVER(name, freq) \
- NET_REGISTER_DEV(SOLVER, name) \
- PARAM(name.FREQ, freq)
-
#ifdef NL_AUTO_DEVICES
#include "nld_devinc.h"
-#include "macro/nlm_cd4xxx.h"
-#include "macro/nlm_ttl74xx.h"
-#include "macro/nlm_opamp.h"
-#include "macro/nlm_other.h"
+// FIXME: copied from nld_twoterm.h
+#ifdef RES_R
+#warning "Do not include rescap.h in a netlist environment"
+#endif
+#ifndef RES_R
+#define RES_R(res) (res)
+#define RES_K(res) ((res) * 1e3)
+#define RES_M(res) ((res) * 1e6)
+#define CAP_U(cap) ((cap) * 1e-6)
+#define CAP_N(cap) ((cap) * 1e-9)
+#define CAP_P(cap) ((cap) * 1e-12)
+#define IND_U(ind) ((ind) * 1e-6)
+#define IND_N(ind) ((ind) * 1e-9)
+#define IND_P(ind) ((ind) * 1e-12)
+#endif
+
+#include "netlist/macro/nlm_cd4xxx.h"
+#include "netlist/macro/nlm_ttl74xx.h"
+#include "netlist/macro/nlm_opamp.h"
+#include "netlist/macro/nlm_other.h"
#include "nld_7448.h"
#else
+#define SOLVER(name, freq) \
+ NET_REGISTER_DEV(SOLVER, name) \
+ PARAM(name.FREQ, freq)
+
#include "nld_system.h"
#include "nld_2102A.h"
diff --git a/src/lib/netlist/devices/nld_74ls629.h b/src/lib/netlist/devices/nld_74ls629.h
index 30d15d70865..dd2b657bc9b 100644
--- a/src/lib/netlist/devices/nld_74ls629.h
+++ b/src/lib/netlist/devices/nld_74ls629.h
@@ -30,6 +30,7 @@
#include "netlist/nl_setup.h"
+#if 0
#define SN74LS629(name, p_cap) \
NET_REGISTER_DEV(SN74LS629, name) \
NETDEV_PARAMI(name, CAP, p_cap)
@@ -38,5 +39,11 @@
NET_REGISTER_DEV(SN74LS629_DIP, name) \
NETDEV_PARAMI(name, 1.CAP, p_cap1) \
NETDEV_PARAMI(name, 2.CAP, p_cap2)
+#else
+#define SN74LS629(name, p_cap) \
+ NET_REGISTER_DEVEXT(SN74LS629, name, p_cap)
+#define SN74LS629_DIP(name, p_cap1, p_cap2) \
+ NET_REGISTER_DEVEXT(SN74LS629_DIP, name, p_cap1, p_cap2)
+#endif
#endif /* NLD_74LS629_H_ */
diff --git a/src/lib/netlist/devices/nld_system.cpp b/src/lib/netlist/devices/nld_system.cpp
index 79da1811491..004b8c1b900 100644
--- a/src/lib/netlist/devices/nld_system.cpp
+++ b/src/lib/netlist/devices/nld_system.cpp
@@ -70,7 +70,7 @@ namespace devices
NETLIB_DEVICE_IMPL(extclock, "EXTCLOCK", "FREQ,PATTERN")
NETLIB_DEVICE_IMPL(res_sw, "RES_SWITCH", "+I,+1,+2")
NETLIB_DEVICE_IMPL(mainclock, "MAINCLOCK", "FREQ")
- NETLIB_DEVICE_IMPL(gnd, "GND", "")
+ NETLIB_DEVICE_IMPL(gnd, "GNDA", "")
NETLIB_DEVICE_IMPL(netlistparams, "PARAMETER", "")
NETLIB_DEVICE_IMPL(logic_input, "LOGIC_INPUT", "IN,FAMILY")
diff --git a/src/lib/netlist/devices/nld_system.h b/src/lib/netlist/devices/nld_system.h
index e2b70455411..d5e69bd10ec 100644
--- a/src/lib/netlist/devices/nld_system.h
+++ b/src/lib/netlist/devices/nld_system.h
@@ -28,9 +28,14 @@
NET_REGISTER_DEV(ANALOG_INPUT, name) \
PARAM(name.IN, v)
+#if 0
#define MAINCLOCK(name, freq) \
NET_REGISTER_DEV(MAINCLOCK, name) \
PARAM(name.FREQ, freq)
+#else
+#define MAINCLOCK(name, freq) \
+ NET_REGISTER_DEVEXT(MAINCLOCK, name, freq)
+#endif
#define CLOCK(name, freq) \
NET_REGISTER_DEV(CLOCK, name) \
diff --git a/src/lib/netlist/devices/nlid_system.h b/src/lib/netlist/devices/nlid_system.h
index 12a8288b99e..fb5403ed909 100644
--- a/src/lib/netlist/devices/nlid_system.h
+++ b/src/lib/netlist/devices/nlid_system.h
@@ -128,7 +128,7 @@ namespace devices
, m_funcparam({nlconst::zero()})
{
if (m_func() != "")
- m_compiled.compile(std::vector<pstring>({{pstring("T")}}), m_func());
+ m_compiled.compile(m_func(), std::vector<pstring>({{pstring("T")}}));
connect(m_feedback, m_Q);
}
//NETLIB_RESETI();
@@ -370,7 +370,7 @@ namespace devices
inps.push_back(n);
m_vals.push_back(nlconst::zero());
}
- m_compiled.compile(inps, m_func());
+ m_compiled.compile(m_func(), inps);
}
protected:
diff --git a/src/lib/netlist/macro/nlm_base.cpp b/src/lib/netlist/macro/nlm_base.cpp
index 3a8e2b5eb0d..cbc6a5ac772 100644
--- a/src/lib/netlist/macro/nlm_base.cpp
+++ b/src/lib/netlist/macro/nlm_base.cpp
@@ -91,7 +91,7 @@ NETLIST_END()
NETLIST_START(base)
TTL_INPUT(ttlhigh, 1)
TTL_INPUT(ttllow, 0)
- NET_REGISTER_DEV(GND, GND)
+ NET_REGISTER_DEV(GNDA, GND)
NET_REGISTER_DEV(PARAMETER, NETLIST)
LOCAL_SOURCE(diode_models)
diff --git a/src/lib/netlist/macro/nlm_opamp.cpp b/src/lib/netlist/macro/nlm_opamp.cpp
index 34c0791e312..31a52f74a96 100644
--- a/src/lib/netlist/macro/nlm_opamp.cpp
+++ b/src/lib/netlist/macro/nlm_opamp.cpp
@@ -1,6 +1,6 @@
// license:GPL-2.0+
// copyright-holders:Couriersud
-#include "nlm_opamp.h"
+
#include "netlist/devices/net_lib.h"
/*
diff --git a/src/lib/netlist/macro/nlm_opamp.h b/src/lib/netlist/macro/nlm_opamp.h
index 90f527dec6a..a7a001a710d 100644
--- a/src/lib/netlist/macro/nlm_opamp.h
+++ b/src/lib/netlist/macro/nlm_opamp.h
@@ -33,7 +33,7 @@
#define LM3900(name) \
NET_REGISTER_DEV(LM3900, name)
-#endif
+#endif // NL_AUTO_DEVICES
/* ----------------------------------------------------------------------------
* External declarations
@@ -41,6 +41,6 @@
NETLIST_EXTERNAL(OPAMP_lib)
-#endif
+#endif // __PLIB_PREPROCESSOR__
#endif
diff --git a/src/lib/netlist/macro/nlm_ttl74xx.h b/src/lib/netlist/macro/nlm_ttl74xx.h
index bc6314f567c..544445c83e6 100644
--- a/src/lib/netlist/macro/nlm_ttl74xx.h
+++ b/src/lib/netlist/macro/nlm_ttl74xx.h
@@ -305,7 +305,7 @@
#define DM9312_DIP(name) \
NET_REGISTER_DEV(DM9312_DIP, name)
-#endif
+#endif // NL_AUTO_DEVICES
/* ----------------------------------------------------------------------------
* External declarations
@@ -313,6 +313,7 @@
NETLIST_EXTERNAL(TTL74XX_lib)
-#endif // NL_AUTO_DEVICES
+#endif // __PLIB_PREPROCESSOR__
+
#endif // NLM_TTL74XX
diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h
index f0a84dd0bb3..4553d19ea2a 100644
--- a/src/lib/netlist/nl_base.h
+++ b/src/lib/netlist/nl_base.h
@@ -22,6 +22,7 @@
#include "plib/pstonum.h"
#include "plib/pstream.h"
#include "plib/ptime.h"
+#include "plib/pfunction.h"
#include "nl_errstr.h"
#include "nltypes.h"
@@ -1733,6 +1734,7 @@ namespace netlist
pstring p = this->get_initial(device, &found);
if (found)
{
+#if 0
bool err = false;
auto vald = plib::pstonum_ne<T>(p, err);
if (err)
@@ -1741,6 +1743,15 @@ namespace netlist
plib::pthrow<nl_exception>(MF_INVALID_NUMBER_CONVERSION_1_2(name, p));
}
m_param = vald;
+#else
+ plib::pfunction<nl_fptype> func;
+ func.compile_infix(p, {});
+ auto valx = func.evaluate();
+ if (std::is_integral<T>::value)
+ if (plib::abs(valx - plib::trunc(valx)) > nlconst::magic(1e-6))
+ plib::pthrow<nl_exception>(MF_INVALID_NUMBER_CONVERSION_1_2(device.name() + "." + name, p));
+ m_param = static_cast<T>(valx);
+#endif
}
else
m_param = val;
diff --git a/src/lib/netlist/nl_dice_compat.h b/src/lib/netlist/nl_dice_compat.h
index 89d7b392b3f..fbd60629e2c 100644
--- a/src/lib/netlist/nl_dice_compat.h
+++ b/src/lib/netlist/nl_dice_compat.h
@@ -26,8 +26,6 @@ sed -e 's/#define \(.*\)"\(.*\)"[ \t]*,[ \t]*\(.*\)/NET_ALIAS(\1,\2.\3)/' src/ma
#ifndef NL_CONVERT_CPP
#include "devices/net_lib.h"
-#include "analog/nld_twoterm.h"
-
#endif
@@ -125,8 +123,8 @@ public:
#define CHIP_555_Mono(name, pdesc) \
NE555_DIP(name) \
NET_C(name.6, name.7) \
- RES(name ## _R, (pdesc)->r) \
- CAP(name ## _C, (pdesc)->c) \
+ RES(name ## _R, pdesc ## _R) \
+ CAP(name ## _C, pdesc ## _C) \
NET_C(name.6, name ## _R.1) \
NET_C(name.6, name ## _C.1) \
NET_C(name ## _R.2, V5) \
@@ -167,8 +165,8 @@ public:
NET_C(name.14, name ## _R2.2) \
NET_C(VCC, name ## _R2.1)
#define CHIP_SERIES_RC(name, pdesc) \
- RES(name ## _R, (pdesc)->r) \
- CAP(name ## _C, (pdesc)->c) \
+ RES(name ## _R, pdesc ## _R) \
+ CAP(name ## _C, pdesc ## _C) \
NET_C(name ## _R.1, name ## _C.2) \
ALIAS(name.3, name ## _R.1) \
ALIAS(name.2, name ## _R.2) \
diff --git a/src/lib/netlist/nl_errstr.h b/src/lib/netlist/nl_errstr.h
index bec1070b3d0..e3dde969338 100644
--- a/src/lib/netlist/nl_errstr.h
+++ b/src/lib/netlist/nl_errstr.h
@@ -68,6 +68,8 @@ namespace netlist
PERRMSGV(MF_DEVICE_ALREADY_EXISTS_1, 1, "Device already exists: {1}")
PERRMSGV(MF_ADDING_ALI1_TO_ALIAS_LIST, 1, "Error adding alias {1} to alias list")
PERRMSGV(MF_DIP_PINS_MUST_BE_AN_EQUAL_NUMBER_OF_PINS_1, 1,"You must pass an equal number of pins to DIPPINS {1}")
+ PERRMSGV(MF_PARAM_COUNT_MISMATCH_2, 2, "Parameter count mismatch for {1} - only found {2}")
+ PERRMSGV(MF_PARAM_COUNT_EXCEEDED_2, 2, "Parameter count exceed for {1} - found {2}")
PERRMSGV(MF_UNKNOWN_OBJECT_TYPE_1, 1, "Unknown object type {1}")
PERRMSGV(MF_INVALID_NUMBER_CONVERSION_1_2, 2, "Invalid number conversion {1} : {2}")
PERRMSGV(MF_INVALID_ENUM_CONVERSION_1_2, 2, "Invalid element found {1} : {2}")
diff --git a/src/lib/netlist/nl_parser.cpp b/src/lib/netlist/nl_parser.cpp
index 92473fcdb74..bf12c97f141 100644
--- a/src/lib/netlist/nl_parser.cpp
+++ b/src/lib/netlist/nl_parser.cpp
@@ -47,6 +47,13 @@ bool parser_t::parse(const pstring &nlname)
m_tok_TT_LINE = register_token("TT_LINE");
m_tok_TT_FAMILY = register_token("TT_FAMILY");
+ register_token("RES_R");
+ register_token("RES_K");
+ register_token("RES_M");
+ register_token("CAP_U");
+ register_token("CAP_N");
+ register_token("CAP_P");
+
bool in_nl = false;
while (true)
@@ -347,56 +354,127 @@ void parser_t::netdev_hint()
void parser_t::device(const pstring &dev_type)
{
+#if 1
+ std::vector<pstring> params;
+
+ pstring devname = get_identifier();
+
+ m_setup.log().debug("Parser: IC: {1}\n", devname);
+
+ auto tok(get_token());
+
+ //printf("enter\n");
+ while (tok.is(m_tok_comma))
+ {
+ tok = get_token();
+ //printf("%d %s\n", tok.type(), tok.str().c_str());
+ if (tok.is_type(IDENTIFIER))
+ params.push_back(tok.str());
+ else if (tok.is_type(STRING))
+ {
+ params.push_back(tok.str());
+ }
+ else
+ {
+ // FIXME: Do we really need this?
+ nl_fptype value = eval_param(tok);
+ if (plib::abs(value - plib::floor(value)) > nlconst::magic(1e-30)
+ || plib::abs(value) > nlconst::magic(1e9))
+ params.push_back(plib::pfmt("{1:.9}").e(value));
+ else
+ params.push_back(plib::pfmt("{1}")(static_cast<long>(value)));
+ }
+ tok = get_token();
+ }
+
+ require_token(tok, m_tok_param_right);
+ m_setup.register_dev(dev_type, devname, params);
+
+#else
factory::element_t *f = m_setup.factory().factory_by_name(dev_type);
auto paramlist = plib::psplit(f->param_desc(), ",");
+ std::vector<pstring> params;
pstring devname = get_identifier();
m_setup.register_dev(dev_type, devname);
m_setup.log().debug("Parser: IC: {1}\n", devname);
- for (const pstring &tp : paramlist)
+ auto tok(get_token());
+
+ //printf("enter\n");
+ while (tok.is(m_tok_comma))
{
- if (plib::startsWith(tp, "+"))
+ tok = get_token();
+ //printf("%d %s\n", tok.type(), tok.str().c_str());
+ if (tok.is_type(IDENTIFIER))
+ params.push_back(tok.str());
+ else if (tok.is_type(STRING))
{
- require_token(m_tok_comma);
- pstring output_name = get_identifier();
- m_setup.log().debug("Link: {1} {2}\n", tp, output_name);
-
- m_setup.register_link(devname + "." + tp.substr(1), output_name);
+ params.push_back(tok.str());
}
- else if (plib::startsWith(tp, "@"))
+ else
{
- pstring term = tp.substr(1);
- m_setup.log().debug("Link: {1} {2}\n", tp, term);
-
- //FIXME
- if (term == "VCC")
- m_setup.register_link(devname + "." + term, "V5");
+ // FIXME: Do we really need this?
+ nl_fptype value = eval_param(tok);
+ if (plib::abs(value - plib::floor(value)) > nlconst::magic(1e-30)
+ || plib::abs(value) > nlconst::magic(1e9))
+ params.push_back(plib::pfmt("{1:.9}").e(value));
else
- m_setup.register_link(devname + "." + term, term);
+ params.push_back(plib::pfmt("{1}")(static_cast<long>(value)));
}
- else
- {
- require_token(m_tok_comma);
- pstring paramfq = devname + "." + tp;
+ tok = get_token();
+ }
+
+ require_token(tok, m_tok_param_right);
+
+ if (params.size() > 0)
+ {
+ auto ptok(params.begin());
- m_setup.log().debug("Defparam: {1}\n", paramfq);
- token_t tok = get_token();
- if (tok.is_type(STRING))
+ for (const pstring &tp : paramlist)
+ {
+ //printf("x %s %s\n", tp.c_str(), ptok->c_str());
+ if (plib::startsWith(tp, "+"))
+ {
+ if (ptok == params.end())
+ {
+ error(plib::pfmt("Input count mismatch for {1} - only found {2}")(devname)(params.size()));
+ break;
+ }
+ pstring output_name = *ptok;
+ m_setup.log().debug("Link: {1} {2}\n", tp, output_name);
+
+ m_setup.register_link(devname + "." + tp.substr(1), output_name);
+ ++ptok;
+ }
+ else if (plib::startsWith(tp, "@"))
{
- m_setup.register_param(paramfq, tok.str());
+ pstring term = tp.substr(1);
+ m_setup.log().debug("Link: {1} {2}\n", tp, term);
+
+ m_setup.register_link(devname + "." + term, term);
}
else
{
- nl_fptype val = eval_param(tok);
- m_setup.register_param(paramfq, val);
+ if (ptok == params.end())
+ {
+ error(plib::pfmt("Input count mismatch for {1} - only found {2}")(devname)(params.size()));
+ break;
+ }
+ pstring paramfq = devname + "." + tp;
+
+ m_setup.log().debug("Defparam: {1}\n", paramfq);
+ m_setup.register_param(paramfq, *ptok);
+ ++ptok;
}
}
+ if (ptok != params.end())
+ {
+ error(plib::pfmt("Input count exceed for {1} - found {2}")(devname)(params.size()));
+ }
}
-
- // error(plib::pfmt("Input count mismatch for {1} - expected {2} found {3}")(devname)(termlist.size())(cnt));
- require_token(m_tok_param_right);
+#endif
}
diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp
index dff5606dc40..bcf3b2109d9 100644
--- a/src/lib/netlist/nl_setup.cpp
+++ b/src/lib/netlist/nl_setup.cpp
@@ -33,7 +33,7 @@ namespace netlist
register_alias_nofqn(alias_fqn, out_fqn);
}
- void nlparse_t::register_dippins_arr(const pstring &terms)
+ void nlparse_t::register_dip_alias_arr(const pstring &terms)
{
std::vector<pstring> list(plib::psplit(terms,", "));
if (list.size() == 0 || (list.size() % 2) == 1)
@@ -49,6 +49,90 @@ namespace netlist
}
}
+ void nlparse_t::register_dev(const pstring &classname, const pstring &name,
+ const char * params_and_connections)
+ {
+ auto params(plib::psplit(pstring(params_and_connections), ",", false));
+ for (auto &i : params)
+ i = plib::trim(i);
+ register_dev(classname, name, params);
+ }
+
+ void nlparse_t::register_dev(const pstring &classname, const pstring &name,
+ std::initializer_list<const char *> params_and_connections)
+ {
+ std::vector<pstring> params;
+ for (auto &i : params_and_connections)
+ params.push_back(pstring(i));
+ register_dev(classname, name, params);
+ }
+
+ void nlparse_t::register_dev(const pstring &classname, const pstring &name,
+ const std::vector<pstring> &params_and_connections)
+ {
+ factory::element_t *f = m_setup.factory().factory_by_name(classname);
+ auto paramlist = plib::psplit(f->param_desc(), ",");
+
+ register_dev(classname, name);
+
+ if (params_and_connections.size() > 0)
+ {
+ auto ptok(params_and_connections.begin());
+ auto ptok_end(params_and_connections.end());
+
+ for (const pstring &tp : paramlist)
+ {
+ //printf("x %s %s\n", tp.c_str(), ptok->c_str());
+ if (plib::startsWith(tp, "+"))
+ {
+ if (ptok == ptok_end)
+ {
+ auto err(MF_PARAM_COUNT_MISMATCH_2(name, params_and_connections.size()));
+ log().fatal(err);
+ plib::pthrow<nl_exception>(err);
+ //break;
+ }
+ pstring output_name = *ptok;
+ log().debug("Link: {1} {2}\n", tp, output_name);
+
+ register_link(name + "." + tp.substr(1), output_name);
+ ++ptok;
+ }
+ else if (plib::startsWith(tp, "@"))
+ {
+ pstring term = tp.substr(1);
+ m_setup.log().debug("Link: {1} {2}\n", tp, term);
+
+ register_link(name + "." + term, term);
+ }
+ else
+ {
+ if (ptok == params_and_connections.end())
+ {
+ auto err(MF_PARAM_COUNT_MISMATCH_2(name, params_and_connections.size()));
+ log().fatal(err);
+ plib::pthrow<nl_exception>(err);
+ }
+ pstring paramfq = name + "." + tp;
+
+ log().debug("Defparam: {1}\n", paramfq);
+ // remove quotes
+ if (plib::startsWith(*ptok, "\"") && plib::endsWith(*ptok, "\""))
+ register_param(paramfq, ptok->substr(1, ptok->length() - 2));
+ else
+ register_param(paramfq, *ptok);
+ ++ptok;
+ }
+ }
+ if (ptok != params_and_connections.end())
+ {
+ auto err(MF_PARAM_COUNT_EXCEEDED_2(name, params_and_connections.size()));
+ log().fatal(err);
+ plib::pthrow<nl_exception>(err);
+ }
+ }
+ }
+
void nlparse_t::register_dev(const pstring &classname, const pstring &name)
{
auto f = m_factory.factory_by_name(classname);
diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h
index 98a25be69c2..f8fb642768a 100644
--- a/src/lib/netlist/nl_setup.h
+++ b/src/lib/netlist/nl_setup.h
@@ -21,7 +21,7 @@
#include <stack>
#include <unordered_map>
#include <vector>
-
+#include <initializer_list>
//============================================================
// MACROS / inline netlist definitions
@@ -36,12 +36,15 @@
setup.register_alias(# alias, # name);
#define DIPPINS(pin1, ...) \
- setup.register_dippins_arr( # pin1 ", " # __VA_ARGS__);
+ setup.register_dip_alias_arr( # pin1 ", " # __VA_ARGS__);
// to be used to reference new library truthtable devices
#define NET_REGISTER_DEV(type, name) \
setup.register_dev(# type, # name);
+#define NET_REGISTER_DEVEXT(type, name, ...) \
+ setup.register_dev(# type, # name, # __VA_ARGS__);
+
#define NET_CONNECT(name, input, output) \
setup.register_link(# name "." # input, # output);
@@ -239,8 +242,16 @@ namespace netlist
void register_model(const pstring &model_in) { m_models.register_model(model_in); }
void register_alias(const pstring &alias, const pstring &out);
- void register_dippins_arr(const pstring &terms);
+ void register_dip_alias_arr(const pstring &terms);
void register_dev(const pstring &classname, const pstring &name);
+ void register_dev(const pstring &classname, const pstring &name,
+ const std::vector<pstring> &params_and_connections);
+
+ void register_dev(const pstring &classname, const pstring &name,
+ std::initializer_list<const char *> params_and_connections);
+ void register_dev(const pstring &classname, const pstring &name,
+ const char *params_and_connections);
+
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);
diff --git a/src/lib/netlist/plib/pfunction.cpp b/src/lib/netlist/plib/pfunction.cpp
index a1530a5590e..6f563ee9bbf 100644
--- a/src/lib/netlist/plib/pfunction.cpp
+++ b/src/lib/netlist/plib/pfunction.cpp
@@ -10,20 +10,21 @@
#include "putil.h"
#include <stack>
+#include <type_traits>
namespace plib {
template <typename NT>
- void pfunction<NT>::compile(const std::vector<pstring> &inputs, const pstring &expr)
+ void pfunction<NT>::compile(const pstring &expr, const std::vector<pstring> &inputs)
{
if (plib::startsWith(expr, "rpn:"))
- compile_postfix(inputs, expr.substr(4));
+ compile_postfix(expr.substr(4), inputs);
else
- compile_infix(inputs, expr);
+ compile_infix(expr, inputs);
}
template <typename NT>
- void pfunction<NT>::compile_postfix(const std::vector<pstring> &inputs, const pstring &expr)
+ void pfunction<NT>::compile_postfix(const pstring &expr, const std::vector<pstring> &inputs)
{
std::vector<pstring> cmds(plib::psplit(expr, " "));
compile_postfix(inputs, cmds, expr);
@@ -113,13 +114,61 @@ namespace plib {
}
template <typename NT>
- void pfunction<NT>::compile_infix(const std::vector<pstring> &inputs, const pstring &expr)
+ void pfunction<NT>::compile_infix(const pstring &expr, const std::vector<pstring> &inputs)
{
// Shunting-yard infix parsing
std::vector<pstring> sep = {"(", ")", ",", "*", "/", "+", "-", "^"};
- std::vector<pstring> sexpr(plib::psplit(plib::replace_all(expr, " ", ""), sep));
+ std::vector<pstring> sexpr1(plib::psplit(plib::replace_all(expr, " ", ""), sep));
std::stack<pstring> opstk;
std::vector<pstring> postfix;
+ std::vector<pstring> sexpr;
+
+ // FIXME: We really need to switch to ptokenizer and fix negative number
+ // handling in ptokenizer.
+
+ // Fix numbers
+ for (std::size_t i = 0; i < sexpr1.size(); )
+ {
+ if ((i == 0) && (sexpr1.size() > 1) && (sexpr1[0] == "-")
+ && (plib::left(sexpr1[1],1) >= "0") && (plib::left(sexpr1[1],1) <= "9"))
+ {
+ if (sexpr1.size() < 4)
+ {
+ sexpr.push_back(sexpr1[0] + sexpr1[1]);
+ i+=2;
+ }
+ else
+ {
+ auto r(plib::right(sexpr1[1], 1));
+ auto ne(sexpr1[2]);
+ if ((r == "e" || r == "E") && (ne == "-" || ne == "+"))
+ {
+ sexpr.push_back(sexpr1[0] + sexpr1[1] + ne + sexpr1[3]);
+ i+=4;
+ }
+ else
+ {
+ sexpr.push_back(sexpr1[0] + sexpr1[1]);
+ i+=2;
+ }
+ }
+ }
+ else if (i + 2 < sexpr1.size() && sexpr1[i].length() > 1)
+ {
+ auto l(plib::left(sexpr1[i], 1));
+ auto r(plib::right(sexpr1[i], 1));
+ auto ne(sexpr1[i+1]);
+ if ((l >= "0") && (l <= "9") && (r == "e" || r == "E") && (ne == "-" || ne == "+"))
+ {
+ sexpr.push_back(sexpr1[i] + ne + sexpr1[i+2]);
+ i+=3;
+ }
+ else
+ sexpr.push_back(sexpr1[i++]);
+ }
+ else
+ sexpr.push_back(sexpr1[i++]);
+ }
for (std::size_t i = 0; i < sexpr.size(); i++)
{
@@ -176,9 +225,33 @@ namespace plib {
postfix.push_back(opstk.top());
opstk.pop();
}
+ //printf("e : %s\n", expr.c_str());
+ //for (auto &s : postfix)
+ // printf("x : %s\n", s.c_str());
compile_postfix(inputs, postfix, expr);
}
+ template <typename NT>
+ static inline typename std::enable_if<std::is_floating_point<NT>::value, NT>::type
+ lfsr_random(std::uint16_t &lfsr) noexcept
+ {
+ std::uint16_t lsb = lfsr & 1;
+ lfsr >>= 1;
+ if (lsb)
+ lfsr ^= 0xB400u; // taps 15, 13, 12, 10
+ return static_cast<NT>(lfsr) / static_cast<NT>(0xffffu);
+ }
+
+ template <typename NT>
+ static inline typename std::enable_if<std::is_integral<NT>::value, NT>::type
+ lfsr_random(std::uint16_t &lfsr) noexcept
+ {
+ std::uint16_t lsb = lfsr & 1;
+ lfsr >>= 1;
+ if (lsb)
+ lfsr ^= 0xB400u; // taps 15, 13, 12, 10
+ return static_cast<NT>(lfsr);
+ }
#define ST1 stack[ptr]
#define ST2 stack[ptr-1]
@@ -208,7 +281,7 @@ namespace plib {
OP(COS, 0, plib::cos(ST2))
OP(TRUNC, 0, plib::trunc(ST2))
case RAND:
- stack[ptr++] = lfsr_random();
+ stack[ptr++] = lfsr_random<NT>(m_lfsr);
break;
case PUSH_INPUT:
stack[ptr++] = values[static_cast<unsigned>(rc.m_param)];
diff --git a/src/lib/netlist/plib/pfunction.h b/src/lib/netlist/plib/pfunction.h
index 643a8b1ae26..c6e94614856 100644
--- a/src/lib/netlist/plib/pfunction.h
+++ b/src/lib/netlist/plib/pfunction.h
@@ -72,47 +72,38 @@ namespace plib {
/// \brief Compile an expression
///
- /// \param inputs Vector of input variables, e.g. {"A","B"}
/// \param expr infix or postfix expression. default is infix, postrix
/// to be prefixed with rpn, e.g. "rpn:A B + 1.3 /"
+ /// \param inputs Vector of input variables, e.g. {"A","B"}
///
- void compile(const std::vector<pstring> &inputs, const pstring &expr);
+ void compile(const pstring &expr, const std::vector<pstring> &inputs);
/// \brief Compile a rpn expression
///
- /// \param inputs Vector of input variables, e.g. {"A","B"}
/// \param expr Reverse polish notation expression, e.g. "A B + 1.3 /"
+ /// \param inputs Vector of input variables, e.g. {"A","B"}
///
- void compile_postfix(const std::vector<pstring> &inputs, const pstring &expr);
+ void compile_postfix(const pstring &expr, const std::vector<pstring> &inputs);
/// \brief Compile an infix expression
///
- /// \param inputs Vector of input variables, e.g. {"A","B"}
/// \param expr Infix expression, e.g. "(A+B)/1.3"
+ /// \param inputs Vector of input variables, e.g. {"A","B"}
///
- void compile_infix(const std::vector<pstring> &inputs, const pstring &expr);
+ void compile_infix(const pstring &expr, const std::vector<pstring> &inputs);
/// \brief Evaluate the expression
///
/// \param values for input variables, e.g. {1.1, 2.2}
/// \return value of expression
///
- NT evaluate(const std::vector<NT> &values) noexcept;
+ NT evaluate(const std::vector<NT> &values = std::vector<NT>()) noexcept;
private:
void compile_postfix(const std::vector<pstring> &inputs,
const std::vector<pstring> &cmds, const pstring &expr);
- NT lfsr_random() noexcept
- {
- std::uint16_t lsb = m_lfsr & 1;
- m_lfsr >>= 1;
- if (lsb)
- m_lfsr ^= 0xB400u; // taps 15, 13, 12, 10
- return static_cast<NT>(m_lfsr) / static_cast<NT>(0xffffu);
- }
-
std::vector<rpn_inst> m_precompiled; //!< precompiled expression
std::uint16_t m_lfsr; //!< lfsr used for generating random numbers
diff --git a/src/lib/netlist/plib/ptokenizer.h b/src/lib/netlist/plib/ptokenizer.h
index 66365bcc017..b6e94c0546f 100644
--- a/src/lib/netlist/plib/ptokenizer.h
+++ b/src/lib/netlist/plib/ptokenizer.h
@@ -79,12 +79,14 @@ namespace plib {
{
}
- bool is(const token_id_t &tok_id) const { return m_id.id() == tok_id.id(); }
- bool is_not(const token_id_t &tok_id) const { return !is(tok_id); }
+ bool is(const token_id_t &tok_id) const noexcept { return m_id.id() == tok_id.id(); }
+ bool is_not(const token_id_t &tok_id) const noexcept { return !is(tok_id); }
- bool is_type(const token_type type) const { return m_type == type; }
+ bool is_type(const token_type type) const noexcept { return m_type == type; }
- pstring str() const { return m_token; }
+ token_type type() const noexcept { return m_type; }
+
+ pstring str() const noexcept { return m_token; }
private:
token_type m_type;
diff --git a/src/lib/netlist/plib/putil.h b/src/lib/netlist/plib/putil.h
index 128e804a1ae..437c78052b1 100644
--- a/src/lib/netlist/plib/putil.h
+++ b/src/lib/netlist/plib/putil.h
@@ -14,6 +14,7 @@
#include <algorithm>
#include <vector>
+#include <initializer_list>
#define PSTRINGIFY_HELP(y) # y
#define PSTRINGIFY(x) PSTRINGIFY_HELP(x)
diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp
index 2591d49bc49..a9c1244f191 100644
--- a/src/lib/netlist/prg/nltool.cpp
+++ b/src/lib/netlist/prg/nltool.cpp
@@ -674,18 +674,24 @@ void tool_app_t::header_entry(const netlist::factory::element_t *e)
if (!plib::startsWith(s, "@"))
vs += ", p" + plib::replace_all(plib::replace_all(s, "+", ""), ".", "_");
mac_out("#define " + e->name() + "(name" + vs + ")");
- mac_out("\tNET_REGISTER_DEV(" + e->name() +", name)");
+
+ vs = "";
for (const auto &s : v)
{
pstring r(plib::replace_all(plib::replace_all(plib::replace_all(s, "+", ""), ".", "_"), "@",""));
if (plib::startsWith(s, "+"))
- mac_out("\tNET_CONNECT(name, " + r + ", p" + r + ")");
+ vs += ", p" + r;
else if (plib::startsWith(s, "@"))
- mac_out("\tNET_CONNECT(name, " + r + ", " + r + ")");
+ {
+ // automatically connected
+ //mac_out("\tNET_CONNECT(name, " + r + ", " + r + ")");
+ }
else
- mac_out("\tNETDEV_PARAMI(name, " + r + ", p" + r + ")");
+ vs += ", p" + r;
}
+
+ mac_out("\tNET_REGISTER_DEVEXT(" + e->name() +", name" + vs + ")", false);
mac_out("", false);
}
@@ -730,7 +736,6 @@ void tool_app_t::create_header()
pout("#ifndef NLD_DEVINC_H\n");
pout("#define NLD_DEVINC_H\n");
pout("\n");
- pout("#include \"nl_setup.h\"\n");
pout("#ifndef __PLIB_PREPROCESSOR__\n");
pout("\n");
pout("// ----------------------------------------------------------------------------\n");