summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib
diff options
context:
space:
mode:
authorGravatarGravatar couriersud <couriersud@gmx.org>2019-11-10 19:54:26 +0100
committerGravatarGravatar couriersud <couriersud@gmx.org>2019-11-10 19:54:26 +0100
commitb8c43342d531b0bd30f8db30174f7bd1cdaa19fa (patch)
treea7e6fa34b528fb0455e601f1911797b8502ca13a /src/lib
parenta5f06c769538d39c8171154a798ac997a4cb3c6e (diff)
netlist: first steps on the way to calculated parameters. [Couriersud]
This commit is a first step towards using formulas in parameters, i.e. MAINCLOCK(clock, 20 * 30) The intention is to improve readability and scalability. Since device registration already provides all necessary information about parameters, the code to create an include file for all devices has been improved. Long term, this will remove the need for device specific header files. In addition going forward devices will accept either no connections or all specified connections, i.e. TTL_7400_NAND(name, chip1.2, chip2.3) or TTL_7400_NAND(name) NET_C(...) NET_C(...) This will allow to remove all duplicate definitions which are currently necessary, i.e. TTL_7400_NAND/TTL_7400_GATE
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");