summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--nl_examples/cmos_inverter_clk.cpp2
-rw-r--r--nl_examples/congo_bongo.c6
-rw-r--r--nl_examples/opamp_amplification_curve.cpp72
-rw-r--r--src/lib/netlist/analog/nld_opamps.cpp12
-rw-r--r--src/lib/netlist/analog/nlid_twoterm.h14
-rw-r--r--src/lib/netlist/devices/net_lib.cpp1
-rw-r--r--src/lib/netlist/devices/nld_system.cpp15
-rw-r--r--src/lib/netlist/devices/nld_system.h4
-rw-r--r--src/lib/netlist/devices/nlid_system.h48
-rw-r--r--src/lib/netlist/macro/nlm_opamp.cpp2
-rw-r--r--src/lib/netlist/plib/pfunction.cpp11
-rw-r--r--src/lib/netlist/plib/pfunction.h1
-rw-r--r--src/lib/netlist/plib/pparser.cpp16
-rw-r--r--src/mame/audio/nl_cheekyms.cpp2
14 files changed, 165 insertions, 41 deletions
diff --git a/nl_examples/cmos_inverter_clk.cpp b/nl_examples/cmos_inverter_clk.cpp
index 95dba92bb79..8b70c46e715 100644
--- a/nl_examples/cmos_inverter_clk.cpp
+++ b/nl_examples/cmos_inverter_clk.cpp
@@ -32,7 +32,7 @@ NETLIST_START(cmos_inverter_clk)
//CLOCK(V, 500000)
#else
VS(V, 5)
- PARAM(V.FUNC, "T 5e6 *")
+ PARAM(V.FUNC, "T * 5e6")
#endif
MOSFET(P, "PMOS(VTO=-0.5 GAMMA=0.5 TOX=20n)")
diff --git a/nl_examples/congo_bongo.c b/nl_examples/congo_bongo.c
index c31258b0bb2..3ad52e7dced 100644
--- a/nl_examples/congo_bongo.c
+++ b/nl_examples/congo_bongo.c
@@ -111,11 +111,11 @@ NETLIST_START(dummy)
NET_C(RX1.2, XU16.7)
#endif
- /* The opamp actually has an FPF of about 200k. This doesn't work here and causes oscillations.
+ /* The opamp actually has an FPF of about 1000k. This doesn't work here and causes oscillations.
* FPF here therefore about half the Solver clock.
*/
- PARAM(XU16.B.MODEL, "MB3614(TYPE=3 UGF=22k)")
- PARAM(XU17.C.MODEL, "MB3614(TYPE=3 UGF=22k)")
+ PARAM(XU16.B.MODEL, "MB3614(TYPE=3)")
+ PARAM(XU17.C.MODEL, "MB3614(TYPE=3 UGF=44k)")
#if 0
PARAM(XU17.A.MODEL, "MB3614(TYPE=1)")
PARAM(XU17.B.MODEL, "MB3614(TYPE=1)")
diff --git a/nl_examples/opamp_amplification_curve.cpp b/nl_examples/opamp_amplification_curve.cpp
new file mode 100644
index 00000000000..73cb7273d9b
--- /dev/null
+++ b/nl_examples/opamp_amplification_curve.cpp
@@ -0,0 +1,72 @@
+// license:GPL-2.0+
+// copyright-holders:Couriersud
+/*
+ * Script to analyze opamp amplification as a function of frequency.
+ *
+ * ./nltool -t 0.5 -f nl_examples/opamp_amplification_curve.cpp
+ *
+ * t=0.0: 10 Hz
+ * t=0.1: 100 Hz
+ * t=0.2: 1000 Hz
+ * t=0.3: 10000 Hz
+ * t=0.4: 100000 Hz
+ * ....
+ *
+ * ./plot_nl.sh --log Y Z
+ */
+
+
+#include "netlist/devices/net_lib.h"
+
+#define OPAMP_TEST "MB3614(FPF=10 UGF=1000k)"
+
+NETLIST_START(main)
+
+ /* Standard stuff */
+
+ //VARCLOCK(clk, "0.5 / pow(10, 1 + T * 4)")
+ //CLOCK(clk, 1000)
+ SOLVER(Solver, 48000)
+ PARAM(Solver.ACCURACY, 1e-7)
+ PARAM(Solver.NR_LOOPS, 300)
+ PARAM(Solver.DYNAMIC_TS, 1)
+ PARAM(Solver.DYNAMIC_MIN_TIMESTEP, 1e-7)
+
+ VS(vs, 0)
+ PARAM(vs.FUNC, "0.001 * sin(6.28 * pow(10, 1 + 10*T) * T)")
+ //PARAM(vs.FUNC, "0.001 * sin(6.28 * pow(10, trunc((1 + T * 4)*2)/2) * T)")
+ //PARAM(vs.FUNC, "1.001 * sin(6.28 * 100 * T)")
+ PARAM(vs.R, 0.001)
+ ALIAS(clk, vs.1)
+ NET_C(vs.2, GND)
+ ANALOG_INPUT(V12, 12)
+ ANALOG_INPUT(VM12, -12)
+
+ OPAMP(op,OPAMP_TEST)
+
+ NET_C(op.GND, VM12)
+ NET_C(op.VCC, V12)
+
+ /* Opamp B wired as inverting amplifier connected to output of first opamp */
+
+ RES(R1, 0.1)
+ RES(R2, 10000)
+
+ NET_C(op.PLUS, GND)
+ NET_C(op.MINUS, R2.2)
+ NET_C(op.MINUS, R1.2)
+
+ NET_C(clk, R1.1)
+ NET_C(op.OUT, R2.1)
+
+ RES(RL, 2000)
+ NET_C(RL.2, GND)
+ NET_C(RL.1, op.OUT)
+
+ AFUNC(f, 1, "A0 * 1000")
+ NET_C(f.A0, op.OUT)
+#if 1
+ LOG(log_Y, R1.1)
+ LOG(log_Z, f)
+#endif
+NETLIST_END()
diff --git a/src/lib/netlist/analog/nld_opamps.cpp b/src/lib/netlist/analog/nld_opamps.cpp
index 0539a5dea51..009795e9a00 100644
--- a/src/lib/netlist/analog/nld_opamps.cpp
+++ b/src/lib/netlist/analog/nld_opamps.cpp
@@ -223,18 +223,14 @@ namespace netlist
m_EBUF->reset();
m_CP->reset();
m_RP.reset();
-#if 0
- double CP = 0.0;
- double RP = 1000;
- double G = m_model.m_UGF / m_model.m_FPF / RP;
-#else
+
double CP = m_model.m_DAB / m_model.m_SLEW;
double RP = 0.5 / constants::pi() / CP / m_model.m_FPF;
double G = m_model.m_UGF / m_model.m_FPF / RP;
-#endif
- printf("OPAMP %s: %g %g %g\n", name().c_str(), CP, RP, G);
+
+ //printf("OPAMP %s: %g %g %g\n", name().c_str(), CP, RP, G);
if (m_model.m_SLEW / (4.0 * constants::pi() * 0.0258) < m_model.m_UGF)
- printf("failed!\n");
+ log().warning("Opamp <{1}> parameters fail convergence criteria", this->name());
m_CP->m_C.setTo(CP);
m_RP.set_R(RP);
diff --git a/src/lib/netlist/analog/nlid_twoterm.h b/src/lib/netlist/analog/nlid_twoterm.h
index 63ab43db591..00812911550 100644
--- a/src/lib/netlist/analog/nlid_twoterm.h
+++ b/src/lib/netlist/analog/nlid_twoterm.h
@@ -399,11 +399,12 @@ namespace analog
, m_V(*this, "V", 0.0)
, m_func(*this,"FUNC", "")
, m_compiled(this->name() + ".FUNCC", this, this->state().run_state_manager())
+ , m_funcparam({0.0})
{
register_subalias("P", m_P);
register_subalias("N", m_N);
if (m_func() != "")
- m_compiled.compile_postfix(std::vector<pstring>({{"T"}}), m_func());
+ m_compiled.compile(std::vector<pstring>({{"T"}}), m_func());
}
NETLIB_IS_TIMESTEP(m_func() != "")
@@ -411,8 +412,9 @@ namespace analog
NETLIB_TIMESTEPI()
{
m_t += step;
+ m_funcparam[0] = m_t;
this->set_G_V_I(1.0 / m_R(),
- m_compiled.evaluate(std::vector<double>({m_t})),
+ m_compiled.evaluate(m_funcparam),
0.0);
}
@@ -431,6 +433,7 @@ namespace analog
param_double_t m_V;
param_str_t m_func;
plib::pfunction m_compiled;
+ std::vector<double> m_funcparam;
};
// -----------------------------------------------------------------------------
@@ -445,18 +448,20 @@ namespace analog
, m_I(*this, "I", 1.0)
, m_func(*this,"FUNC", "")
, m_compiled(this->name() + ".FUNCC", this, this->state().run_state_manager())
+ , m_funcparam({0.0})
{
register_subalias("P", m_P);
register_subalias("N", m_N);
if (m_func() != "")
- m_compiled.compile_postfix(std::vector<pstring>({{"T"}}), m_func());
+ m_compiled.compile(std::vector<pstring>({{"T"}}), m_func());
}
NETLIB_IS_TIMESTEP(m_func() != "")
NETLIB_TIMESTEPI()
{
m_t += step;
- const double I = m_compiled.evaluate(std::vector<double>({m_t}));
+ m_funcparam[0] = m_t;
+ const double I = m_compiled.evaluate(m_funcparam);
set_mat(0.0, 0.0, -I,
0.0, 0.0, I);
}
@@ -476,6 +481,7 @@ namespace analog
param_double_t m_I;
param_str_t m_func;
plib::pfunction m_compiled;
+ std::vector<double> m_funcparam;
};
diff --git a/src/lib/netlist/devices/net_lib.cpp b/src/lib/netlist/devices/net_lib.cpp
index c0353f2489a..43a74fd43f1 100644
--- a/src/lib/netlist/devices/net_lib.cpp
+++ b/src/lib/netlist/devices/net_lib.cpp
@@ -52,6 +52,7 @@ namespace devices
LIB_ENTRY(log)
LIB_ENTRY(logD)
LIB_ENTRY(clock)
+ LIB_ENTRY(varclock)
LIB_ENTRY(extclock)
LIB_ENTRY(mainclock)
LIB_ENTRY(gnd)
diff --git a/src/lib/netlist/devices/nld_system.cpp b/src/lib/netlist/devices/nld_system.cpp
index 03aa5c678f1..5a1868bb775 100644
--- a/src/lib/netlist/devices/nld_system.cpp
+++ b/src/lib/netlist/devices/nld_system.cpp
@@ -19,20 +19,6 @@ namespace netlist
// ----------------------------------------------------------------------------------------
- // clock
- // ----------------------------------------------------------------------------------------
-
- NETLIB_UPDATE_PARAM(clock)
- {
- m_inc = netlist_time::from_double(1.0 / (m_freq() * 2.0));
- }
-
- NETLIB_UPDATE(clock)
- {
- m_Q.push(!m_feedback(), m_inc);
- }
-
- // ----------------------------------------------------------------------------------------
// extclock
// ----------------------------------------------------------------------------------------
@@ -123,6 +109,7 @@ namespace netlist
NETLIB_DEVICE_IMPL(function, "AFUNC", "N,FUNC")
NETLIB_DEVICE_IMPL(analog_input, "ANALOG_INPUT", "IN")
NETLIB_DEVICE_IMPL(clock, "CLOCK", "FREQ")
+ NETLIB_DEVICE_IMPL(varclock, "VARCLOCK", "FUNC")
NETLIB_DEVICE_IMPL(extclock, "EXTCLOCK", "FREQ,PATTERN")
NETLIB_DEVICE_IMPL(res_sw, "RES_SWITCH", "+IN,+P1,+P2")
NETLIB_DEVICE_IMPL(mainclock, "MAINCLOCK", "FREQ")
diff --git a/src/lib/netlist/devices/nld_system.h b/src/lib/netlist/devices/nld_system.h
index 5158e098cfa..e2b70455411 100644
--- a/src/lib/netlist/devices/nld_system.h
+++ b/src/lib/netlist/devices/nld_system.h
@@ -36,6 +36,10 @@
NET_REGISTER_DEV(CLOCK, name) \
PARAM(name.FREQ, freq)
+#define VARCLOCK(name, func) \
+ NET_REGISTER_DEV(VARCLOCK, name) \
+ PARAM(name.FUNC, func)
+
#define EXTCLOCK(name, freq, pattern) \
NET_REGISTER_DEV(EXTCLOCK, name) \
PARAM(name.FREQ, freq) \
diff --git a/src/lib/netlist/devices/nlid_system.h b/src/lib/netlist/devices/nlid_system.h
index 11b207a1103..a88be547abc 100644
--- a/src/lib/netlist/devices/nlid_system.h
+++ b/src/lib/netlist/devices/nlid_system.h
@@ -94,9 +94,17 @@ namespace netlist
connect(m_feedback, m_Q);
}
- NETLIB_UPDATEI();
//NETLIB_RESETI();
- NETLIB_UPDATE_PARAMI();
+
+ NETLIB_UPDATE_PARAMI()
+ {
+ m_inc = netlist_time::from_double(1.0 / (m_freq() * 2.0));
+ }
+
+ NETLIB_UPDATEI()
+ {
+ m_Q.push(!m_feedback(), m_inc);
+ }
private:
logic_input_t m_feedback;
@@ -107,6 +115,42 @@ namespace netlist
};
// -----------------------------------------------------------------------------
+ // varclock
+ // -----------------------------------------------------------------------------
+
+ NETLIB_OBJECT(varclock)
+ {
+ NETLIB_CONSTRUCTOR(varclock)
+ , m_feedback(*this, "FB")
+ , m_Q(*this, "Q")
+ , m_func(*this,"FUNC", "")
+ , m_compiled(this->name() + ".FUNCC", this, this->state().run_state_manager())
+ , m_funcparam({0.0})
+ {
+ if (m_func() != "")
+ m_compiled.compile(std::vector<pstring>({{"T"}}), m_func());
+ connect(m_feedback, m_Q);
+ }
+ //NETLIB_RESETI();
+ //NETLIB_UPDATE_PARAMI()
+
+ NETLIB_UPDATEI()
+ {
+ m_funcparam[0] = exec().time().as_double();
+ const netlist_time m_inc = netlist_time::from_double(m_compiled.evaluate(m_funcparam));
+ m_Q.push(!m_feedback(), m_inc);
+ }
+
+ private:
+ logic_input_t m_feedback;
+ logic_output_t m_Q;
+
+ param_str_t m_func;
+ plib::pfunction m_compiled;
+ std::vector<double> m_funcparam;
+ };
+
+ // -----------------------------------------------------------------------------
// extclock
// -----------------------------------------------------------------------------
diff --git a/src/lib/netlist/macro/nlm_opamp.cpp b/src/lib/netlist/macro/nlm_opamp.cpp
index 2c61430c935..cfa25cd88b4 100644
--- a/src/lib/netlist/macro/nlm_opamp.cpp
+++ b/src/lib/netlist/macro/nlm_opamp.cpp
@@ -225,7 +225,7 @@ NETLIST_START(OPAMP_lib)
NET_MODEL("LM324 OPAMP(TYPE=3 VLH=2.0 VLL=0.2 FPF=5 UGF=500k SLEW=0.3M RI=1000k RO=50 DAB=0.00075)")
NET_MODEL("LM358 OPAMP(TYPE=3 VLH=2.0 VLL=0.2 FPF=5 UGF=500k SLEW=0.3M RI=1000k RO=50 DAB=0.001)")
- NET_MODEL("MB3614 OPAMP(TYPE=3 VLH=1.4 VLL=0.02 FPF=2 UGF=200k SLEW=0.6M RI=1000k RO=50 DAB=0.002)")
+ NET_MODEL("MB3614 OPAMP(TYPE=3 VLH=1.4 VLL=0.02 FPF=10 UGF=1000k SLEW=0.6M RI=1000k RO=50 DAB=0.002)")
NET_MODEL("UA741 OPAMP(TYPE=3 VLH=1.0 VLL=1.0 FPF=5 UGF=1000k SLEW=0.5M RI=2000k RO=75 DAB=0.0017)")
NET_MODEL("LM747 OPAMP(TYPE=3 VLH=1.0 VLL=1.0 FPF=5 UGF=1000k SLEW=0.5M RI=2000k RO=50 DAB=0.0017)")
NET_MODEL("LM747A OPAMP(TYPE=3 VLH=2.0 VLL=2.0 FPF=5 UGF=1000k SLEW=0.7M RI=6000k RO=50 DAB=0.0015)")
diff --git a/src/lib/netlist/plib/pfunction.cpp b/src/lib/netlist/plib/pfunction.cpp
index 6a2179e0e6f..6b15d7f8229 100644
--- a/src/lib/netlist/plib/pfunction.cpp
+++ b/src/lib/netlist/plib/pfunction.cpp
@@ -52,6 +52,8 @@ void pfunction::compile_postfix(const std::vector<pstring> &inputs,
{ rc.m_cmd = SIN; stk -= 0; }
else if (cmd == "cos")
{ rc.m_cmd = COS; stk -= 0; }
+ else if (cmd == "trunc")
+ { rc.m_cmd = TRUNC; stk -= 0; }
else if (cmd == "rand")
{ rc.m_cmd = RAND; stk += 1; }
else
@@ -72,16 +74,16 @@ void pfunction::compile_postfix(const std::vector<pstring> &inputs,
bool err;
rc.m_param = plib::pstonum_ne<decltype(rc.m_param)>(cmd, err);
if (err)
- throw plib::pexception(plib::pfmt("nld_function: unknown/misformatted token <{1}> in <{2}>")(cmd)(expr));
+ throw plib::pexception(plib::pfmt("pfunction: unknown/misformatted token <{1}> in <{2}>")(cmd)(expr));
stk += 1;
}
}
if (stk < 1)
- throw plib::pexception(plib::pfmt("nld_function: stack underflow on token <{1}> in <{2}>")(cmd)(expr));
+ throw plib::pexception(plib::pfmt("pfunction: stack underflow on token <{1}> in <{2}>")(cmd)(expr));
m_precompiled.push_back(rc);
}
if (stk != 1)
- throw plib::pexception(plib::pfmt("nld_function: stack count different to one on <{2}>")(expr));
+ throw plib::pexception(plib::pfmt("pfunction: stack count different to one on <{2}>")(expr));
}
static int get_prio(const pstring &v)
@@ -103,7 +105,7 @@ static int get_prio(const pstring &v)
static pstring pop_check(std::stack<pstring> &stk, const pstring &expr)
{
if (stk.size() == 0)
- throw plib::pexception(plib::pfmt("nld_function: stack underflow during infix parsing of: <{1}>")(expr));
+ throw plib::pexception(plib::pfmt("pfunction: stack underflow during infix parsing of: <{1}>")(expr));
pstring res = stk.top();
stk.pop();
return res;
@@ -201,6 +203,7 @@ double pfunction::evaluate(const std::vector<double> &values)
OP(POW, 1, std::pow(ST2, ST1))
OP(SIN, 0, std::sin(ST2))
OP(COS, 0, std::cos(ST2))
+ OP(TRUNC, 0, std::trunc(ST2))
case RAND:
stack[ptr++] = lfsr_random();
break;
diff --git a/src/lib/netlist/plib/pfunction.h b/src/lib/netlist/plib/pfunction.h
index fbb6c508333..bc81ef0c5a6 100644
--- a/src/lib/netlist/plib/pfunction.h
+++ b/src/lib/netlist/plib/pfunction.h
@@ -34,6 +34,7 @@ namespace plib {
SIN,
COS,
RAND, /* random number between 0 and 1 */
+ TRUNC,
PUSH_CONST,
PUSH_INPUT
};
diff --git a/src/lib/netlist/plib/pparser.cpp b/src/lib/netlist/plib/pparser.cpp
index 5e1a231da81..55e4c74c778 100644
--- a/src/lib/netlist/plib/pparser.cpp
+++ b/src/lib/netlist/plib/pparser.cpp
@@ -282,6 +282,7 @@ ppreprocessor::ppreprocessor(defines_map_type *defines)
m_expr_sep.emplace_back("&&");
m_expr_sep.emplace_back("||");
m_expr_sep.emplace_back("==");
+ m_expr_sep.emplace_back(",");
m_expr_sep.emplace_back(" ");
m_expr_sep.emplace_back("\t");
@@ -508,9 +509,18 @@ pstring ppreprocessor::process_line(pstring line)
{
if (m_ifflag == 0)
{
- if (lti.size() != 3)
- error("PREPRO: only simple defines allowed: " + line);
- m_defines.insert({lti[1], define_t(lti[1], lti[2])});
+ if (lti.size() < 2)
+ error("PREPRO: define needs at least one argument: " + line);
+ else if (lti.size() == 2)
+ m_defines.insert({lti[1], define_t(lti[1], "")});
+ else
+ {
+ pstring arg("");
+ for (int i=2; i<lti.size() - 1; i++)
+ arg += lti[i] + " ";
+ arg += lti[lti.size()-1];
+ m_defines.insert({lti[1], define_t(lti[1], arg)});
+ }
}
}
else
diff --git a/src/mame/audio/nl_cheekyms.cpp b/src/mame/audio/nl_cheekyms.cpp
index 6caaf71d610..5abc5104778 100644
--- a/src/mame/audio/nl_cheekyms.cpp
+++ b/src/mame/audio/nl_cheekyms.cpp
@@ -241,7 +241,7 @@ NETLIST_END()
static NETLIST_START(NOISE)
CS(FC, 0)
- PARAM(FC.FUNC, "0.0000001 rand *")
+ PARAM(FC.FUNC, "0.0000001 * rand()")
ALIAS(E, FC.P)
ALIAS(B, FC.N)