diff options
-rw-r--r-- | nl_examples/cmos_inverter_clk.cpp | 2 | ||||
-rw-r--r-- | nl_examples/congo_bongo.c | 6 | ||||
-rw-r--r-- | nl_examples/opamp_amplification_curve.cpp | 72 | ||||
-rw-r--r-- | src/lib/netlist/analog/nld_opamps.cpp | 12 | ||||
-rw-r--r-- | src/lib/netlist/analog/nlid_twoterm.h | 14 | ||||
-rw-r--r-- | src/lib/netlist/devices/net_lib.cpp | 1 | ||||
-rw-r--r-- | src/lib/netlist/devices/nld_system.cpp | 15 | ||||
-rw-r--r-- | src/lib/netlist/devices/nld_system.h | 4 | ||||
-rw-r--r-- | src/lib/netlist/devices/nlid_system.h | 48 | ||||
-rw-r--r-- | src/lib/netlist/macro/nlm_opamp.cpp | 2 | ||||
-rw-r--r-- | src/lib/netlist/plib/pfunction.cpp | 11 | ||||
-rw-r--r-- | src/lib/netlist/plib/pfunction.h | 1 | ||||
-rw-r--r-- | src/lib/netlist/plib/pparser.cpp | 16 | ||||
-rw-r--r-- | src/mame/audio/nl_cheekyms.cpp | 2 |
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) |