mirror of
https://github.com/holub/mame
synced 2025-10-05 08:41:31 +03:00
netlist: MB3614 again, function controlled VARCLOCK and other
improvements. - fix MB3614 parameter - Added VARCLOCK which derives step size from function - optimized function handling in CS and VS - fixed a bug in ppreprocessor - add trunc to pfunction - added opamp_amplification_curve to derive characteristic amplification curve
This commit is contained in:
parent
140dc2237e
commit
58e6383ada
@ -32,7 +32,7 @@ NETLIST_START(cmos_inverter_clk)
|
|||||||
//CLOCK(V, 500000)
|
//CLOCK(V, 500000)
|
||||||
#else
|
#else
|
||||||
VS(V, 5)
|
VS(V, 5)
|
||||||
PARAM(V.FUNC, "T 5e6 *")
|
PARAM(V.FUNC, "T * 5e6")
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
MOSFET(P, "PMOS(VTO=-0.5 GAMMA=0.5 TOX=20n)")
|
MOSFET(P, "PMOS(VTO=-0.5 GAMMA=0.5 TOX=20n)")
|
||||||
|
@ -111,11 +111,11 @@ NETLIST_START(dummy)
|
|||||||
NET_C(RX1.2, XU16.7)
|
NET_C(RX1.2, XU16.7)
|
||||||
#endif
|
#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.
|
* FPF here therefore about half the Solver clock.
|
||||||
*/
|
*/
|
||||||
PARAM(XU16.B.MODEL, "MB3614(TYPE=3 UGF=22k)")
|
PARAM(XU16.B.MODEL, "MB3614(TYPE=3)")
|
||||||
PARAM(XU17.C.MODEL, "MB3614(TYPE=3 UGF=22k)")
|
PARAM(XU17.C.MODEL, "MB3614(TYPE=3 UGF=44k)")
|
||||||
#if 0
|
#if 0
|
||||||
PARAM(XU17.A.MODEL, "MB3614(TYPE=1)")
|
PARAM(XU17.A.MODEL, "MB3614(TYPE=1)")
|
||||||
PARAM(XU17.B.MODEL, "MB3614(TYPE=1)")
|
PARAM(XU17.B.MODEL, "MB3614(TYPE=1)")
|
||||||
|
72
nl_examples/opamp_amplification_curve.cpp
Normal file
72
nl_examples/opamp_amplification_curve.cpp
Normal file
@ -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()
|
@ -223,18 +223,14 @@ namespace netlist
|
|||||||
m_EBUF->reset();
|
m_EBUF->reset();
|
||||||
m_CP->reset();
|
m_CP->reset();
|
||||||
m_RP.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 CP = m_model.m_DAB / m_model.m_SLEW;
|
||||||
double RP = 0.5 / constants::pi() / CP / m_model.m_FPF;
|
double RP = 0.5 / constants::pi() / CP / m_model.m_FPF;
|
||||||
double G = m_model.m_UGF / m_model.m_FPF / RP;
|
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)
|
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_CP->m_C.setTo(CP);
|
||||||
m_RP.set_R(RP);
|
m_RP.set_R(RP);
|
||||||
|
@ -399,11 +399,12 @@ namespace analog
|
|||||||
, m_V(*this, "V", 0.0)
|
, m_V(*this, "V", 0.0)
|
||||||
, m_func(*this,"FUNC", "")
|
, m_func(*this,"FUNC", "")
|
||||||
, m_compiled(this->name() + ".FUNCC", this, this->state().run_state_manager())
|
, m_compiled(this->name() + ".FUNCC", this, this->state().run_state_manager())
|
||||||
|
, m_funcparam({0.0})
|
||||||
{
|
{
|
||||||
register_subalias("P", m_P);
|
register_subalias("P", m_P);
|
||||||
register_subalias("N", m_N);
|
register_subalias("N", m_N);
|
||||||
if (m_func() != "")
|
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_IS_TIMESTEP(m_func() != "")
|
||||||
@ -411,8 +412,9 @@ namespace analog
|
|||||||
NETLIB_TIMESTEPI()
|
NETLIB_TIMESTEPI()
|
||||||
{
|
{
|
||||||
m_t += step;
|
m_t += step;
|
||||||
|
m_funcparam[0] = m_t;
|
||||||
this->set_G_V_I(1.0 / m_R(),
|
this->set_G_V_I(1.0 / m_R(),
|
||||||
m_compiled.evaluate(std::vector<double>({m_t})),
|
m_compiled.evaluate(m_funcparam),
|
||||||
0.0);
|
0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -431,6 +433,7 @@ namespace analog
|
|||||||
param_double_t m_V;
|
param_double_t m_V;
|
||||||
param_str_t m_func;
|
param_str_t m_func;
|
||||||
plib::pfunction m_compiled;
|
plib::pfunction m_compiled;
|
||||||
|
std::vector<double> m_funcparam;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
@ -445,18 +448,20 @@ namespace analog
|
|||||||
, m_I(*this, "I", 1.0)
|
, m_I(*this, "I", 1.0)
|
||||||
, m_func(*this,"FUNC", "")
|
, m_func(*this,"FUNC", "")
|
||||||
, m_compiled(this->name() + ".FUNCC", this, this->state().run_state_manager())
|
, m_compiled(this->name() + ".FUNCC", this, this->state().run_state_manager())
|
||||||
|
, m_funcparam({0.0})
|
||||||
{
|
{
|
||||||
register_subalias("P", m_P);
|
register_subalias("P", m_P);
|
||||||
register_subalias("N", m_N);
|
register_subalias("N", m_N);
|
||||||
if (m_func() != "")
|
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_IS_TIMESTEP(m_func() != "")
|
||||||
NETLIB_TIMESTEPI()
|
NETLIB_TIMESTEPI()
|
||||||
{
|
{
|
||||||
m_t += step;
|
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,
|
set_mat(0.0, 0.0, -I,
|
||||||
0.0, 0.0, I);
|
0.0, 0.0, I);
|
||||||
}
|
}
|
||||||
@ -476,6 +481,7 @@ namespace analog
|
|||||||
param_double_t m_I;
|
param_double_t m_I;
|
||||||
param_str_t m_func;
|
param_str_t m_func;
|
||||||
plib::pfunction m_compiled;
|
plib::pfunction m_compiled;
|
||||||
|
std::vector<double> m_funcparam;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -52,6 +52,7 @@ namespace devices
|
|||||||
LIB_ENTRY(log)
|
LIB_ENTRY(log)
|
||||||
LIB_ENTRY(logD)
|
LIB_ENTRY(logD)
|
||||||
LIB_ENTRY(clock)
|
LIB_ENTRY(clock)
|
||||||
|
LIB_ENTRY(varclock)
|
||||||
LIB_ENTRY(extclock)
|
LIB_ENTRY(extclock)
|
||||||
LIB_ENTRY(mainclock)
|
LIB_ENTRY(mainclock)
|
||||||
LIB_ENTRY(gnd)
|
LIB_ENTRY(gnd)
|
||||||
|
@ -18,20 +18,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
|
// extclock
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
@ -123,6 +109,7 @@ namespace netlist
|
|||||||
NETLIB_DEVICE_IMPL(function, "AFUNC", "N,FUNC")
|
NETLIB_DEVICE_IMPL(function, "AFUNC", "N,FUNC")
|
||||||
NETLIB_DEVICE_IMPL(analog_input, "ANALOG_INPUT", "IN")
|
NETLIB_DEVICE_IMPL(analog_input, "ANALOG_INPUT", "IN")
|
||||||
NETLIB_DEVICE_IMPL(clock, "CLOCK", "FREQ")
|
NETLIB_DEVICE_IMPL(clock, "CLOCK", "FREQ")
|
||||||
|
NETLIB_DEVICE_IMPL(varclock, "VARCLOCK", "FUNC")
|
||||||
NETLIB_DEVICE_IMPL(extclock, "EXTCLOCK", "FREQ,PATTERN")
|
NETLIB_DEVICE_IMPL(extclock, "EXTCLOCK", "FREQ,PATTERN")
|
||||||
NETLIB_DEVICE_IMPL(res_sw, "RES_SWITCH", "+IN,+P1,+P2")
|
NETLIB_DEVICE_IMPL(res_sw, "RES_SWITCH", "+IN,+P1,+P2")
|
||||||
NETLIB_DEVICE_IMPL(mainclock, "MAINCLOCK", "FREQ")
|
NETLIB_DEVICE_IMPL(mainclock, "MAINCLOCK", "FREQ")
|
||||||
|
@ -36,6 +36,10 @@
|
|||||||
NET_REGISTER_DEV(CLOCK, name) \
|
NET_REGISTER_DEV(CLOCK, name) \
|
||||||
PARAM(name.FREQ, freq)
|
PARAM(name.FREQ, freq)
|
||||||
|
|
||||||
|
#define VARCLOCK(name, func) \
|
||||||
|
NET_REGISTER_DEV(VARCLOCK, name) \
|
||||||
|
PARAM(name.FUNC, func)
|
||||||
|
|
||||||
#define EXTCLOCK(name, freq, pattern) \
|
#define EXTCLOCK(name, freq, pattern) \
|
||||||
NET_REGISTER_DEV(EXTCLOCK, name) \
|
NET_REGISTER_DEV(EXTCLOCK, name) \
|
||||||
PARAM(name.FREQ, freq) \
|
PARAM(name.FREQ, freq) \
|
||||||
|
@ -94,9 +94,17 @@ namespace netlist
|
|||||||
|
|
||||||
connect(m_feedback, m_Q);
|
connect(m_feedback, m_Q);
|
||||||
}
|
}
|
||||||
NETLIB_UPDATEI();
|
|
||||||
//NETLIB_RESETI();
|
//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:
|
private:
|
||||||
logic_input_t m_feedback;
|
logic_input_t m_feedback;
|
||||||
@ -106,6 +114,42 @@ namespace netlist
|
|||||||
netlist_time m_inc;
|
netlist_time m_inc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// 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
|
// extclock
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -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("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("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("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("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)")
|
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)")
|
||||||
|
@ -52,6 +52,8 @@ void pfunction::compile_postfix(const std::vector<pstring> &inputs,
|
|||||||
{ rc.m_cmd = SIN; stk -= 0; }
|
{ rc.m_cmd = SIN; stk -= 0; }
|
||||||
else if (cmd == "cos")
|
else if (cmd == "cos")
|
||||||
{ rc.m_cmd = COS; stk -= 0; }
|
{ rc.m_cmd = COS; stk -= 0; }
|
||||||
|
else if (cmd == "trunc")
|
||||||
|
{ rc.m_cmd = TRUNC; stk -= 0; }
|
||||||
else if (cmd == "rand")
|
else if (cmd == "rand")
|
||||||
{ rc.m_cmd = RAND; stk += 1; }
|
{ rc.m_cmd = RAND; stk += 1; }
|
||||||
else
|
else
|
||||||
@ -72,16 +74,16 @@ void pfunction::compile_postfix(const std::vector<pstring> &inputs,
|
|||||||
bool err;
|
bool err;
|
||||||
rc.m_param = plib::pstonum_ne<decltype(rc.m_param)>(cmd, err);
|
rc.m_param = plib::pstonum_ne<decltype(rc.m_param)>(cmd, err);
|
||||||
if (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;
|
stk += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (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);
|
m_precompiled.push_back(rc);
|
||||||
}
|
}
|
||||||
if (stk != 1)
|
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)
|
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)
|
static pstring pop_check(std::stack<pstring> &stk, const pstring &expr)
|
||||||
{
|
{
|
||||||
if (stk.size() == 0)
|
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();
|
pstring res = stk.top();
|
||||||
stk.pop();
|
stk.pop();
|
||||||
return res;
|
return res;
|
||||||
@ -201,6 +203,7 @@ double pfunction::evaluate(const std::vector<double> &values)
|
|||||||
OP(POW, 1, std::pow(ST2, ST1))
|
OP(POW, 1, std::pow(ST2, ST1))
|
||||||
OP(SIN, 0, std::sin(ST2))
|
OP(SIN, 0, std::sin(ST2))
|
||||||
OP(COS, 0, std::cos(ST2))
|
OP(COS, 0, std::cos(ST2))
|
||||||
|
OP(TRUNC, 0, std::trunc(ST2))
|
||||||
case RAND:
|
case RAND:
|
||||||
stack[ptr++] = lfsr_random();
|
stack[ptr++] = lfsr_random();
|
||||||
break;
|
break;
|
||||||
|
@ -34,6 +34,7 @@ namespace plib {
|
|||||||
SIN,
|
SIN,
|
||||||
COS,
|
COS,
|
||||||
RAND, /* random number between 0 and 1 */
|
RAND, /* random number between 0 and 1 */
|
||||||
|
TRUNC,
|
||||||
PUSH_CONST,
|
PUSH_CONST,
|
||||||
PUSH_INPUT
|
PUSH_INPUT
|
||||||
};
|
};
|
||||||
|
@ -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("==");
|
||||||
|
m_expr_sep.emplace_back(",");
|
||||||
m_expr_sep.emplace_back(" ");
|
m_expr_sep.emplace_back(" ");
|
||||||
m_expr_sep.emplace_back("\t");
|
m_expr_sep.emplace_back("\t");
|
||||||
|
|
||||||
@ -508,9 +509,18 @@ pstring ppreprocessor::process_line(pstring line)
|
|||||||
{
|
{
|
||||||
if (m_ifflag == 0)
|
if (m_ifflag == 0)
|
||||||
{
|
{
|
||||||
if (lti.size() != 3)
|
if (lti.size() < 2)
|
||||||
error("PREPRO: only simple defines allowed: " + line);
|
error("PREPRO: define needs at least one argument: " + line);
|
||||||
m_defines.insert({lti[1], define_t(lti[1], lti[2])});
|
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
|
else
|
||||||
|
@ -241,7 +241,7 @@ NETLIST_END()
|
|||||||
|
|
||||||
static NETLIST_START(NOISE)
|
static NETLIST_START(NOISE)
|
||||||
CS(FC, 0)
|
CS(FC, 0)
|
||||||
PARAM(FC.FUNC, "0.0000001 rand *")
|
PARAM(FC.FUNC, "0.0000001 * rand()")
|
||||||
|
|
||||||
ALIAS(E, FC.P)
|
ALIAS(E, FC.P)
|
||||||
ALIAS(B, FC.N)
|
ALIAS(B, FC.N)
|
||||||
|
Loading…
Reference in New Issue
Block a user