netlist: Add the NE566 as a macro device. [Couriersud]

The device can be found in nlm_other.cpp.
Removed nld_ne566.*
Added SYS_SW, SYS_SW2 and SYS_COMP. These are single switch,
alternating switch and a analog comparator with digital outputs.
Renamed RES_SWITCH to SYS_SW.
Added example ne566.cpp in netlist/examples.
This commit is contained in:
couriersud 2020-05-01 10:04:22 +02:00
parent cb3210d0ad
commit 13f6e92cec
21 changed files with 360 additions and 186 deletions

View File

@ -203,8 +203,6 @@ project "netlist"
MAME_DIR .. "src/lib/netlist/devices/nld_dm9334.h",
MAME_DIR .. "src/lib/netlist/devices/nld_ne555.cpp",
MAME_DIR .. "src/lib/netlist/devices/nld_ne555.h",
MAME_DIR .. "src/lib/netlist/devices/nld_ne566.cpp",
MAME_DIR .. "src/lib/netlist/devices/nld_ne566.h",
MAME_DIR .. "src/lib/netlist/devices/nld_mm5837.cpp",
MAME_DIR .. "src/lib/netlist/devices/nld_mm5837.h",
MAME_DIR .. "src/lib/netlist/devices/nld_r2r_dac.cpp",

View File

@ -182,6 +182,12 @@ namespace analog
-G, G, nlconst::zero());
}
void set_G(nl_fptype G) const noexcept
{
set_mat( G, -G, nlconst::zero(),
-G, G, nlconst::zero());
}
NETLIB_RESETI();
protected:
@ -218,6 +224,7 @@ namespace analog
param_fp_t m_R;
// protect set_R ... it's a recipe to desaster when used to bypass the parameter
using NETLIB_NAME(R_base)::set_R;
using NETLIB_NAME(R_base)::set_G;
};
// -----------------------------------------------------------------------------

View File

@ -175,7 +175,6 @@ NLOBJS := \
$(NLOBJ)/devices/nld_dm9334.o \
$(NLOBJ)/devices/nld_mm5837.o \
$(NLOBJ)/devices/nld_ne555.o \
$(NLOBJ)/devices/nld_ne566.o \
$(NLOBJ)/devices/nld_r2r_dac.o \
$(NLOBJ)/devices/nld_tristate.o \
$(NLOBJ)/devices/nld_schmitt.o \

View File

@ -60,7 +60,9 @@ namespace devices
LIB_ENTRY(gnd)
LIB_ENTRY(netlistparams)
LIB_ENTRY(solver)
LIB_ENTRY(res_sw)
LIB_ENTRY(sys_dsw1)
LIB_ENTRY(sys_dsw2)
LIB_ENTRY(sys_compd)
LIB_ENTRY(switch1)
LIB_ENTRY(switch2)
LIB_ENTRY(nicRSFF)
@ -149,8 +151,6 @@ namespace devices
//ENTRY(4066, CD_4066, "+A,B")
LIB_ENTRY(NE555)
LIB_ENTRY(NE555_dip)
LIB_ENTRY(NE566)
LIB_ENTRY(NE566_dip)
LIB_ENTRY(MC1455P)
LIB_ENTRY(MC1455P_dip)
LIB_ENTRY(TMS4800)

View File

@ -22,6 +22,7 @@
#define RES_K(res) ((res) * 1e3)
#define RES_M(res) ((res) * 1e6)
#define CAP_U(cap) ((cap) * 1e-6)
//#define CAP_U(cap) ((cap) * 1μ)
#define CAP_N(cap) ((cap) * 1e-9)
#define CAP_P(cap) ((cap) * 1e-12)
#define IND_U(ind) ((ind) * 1e-6)
@ -90,7 +91,6 @@
#include "nld_mm5837.h"
#include "nld_ne555.h"
#include "nld_ne566.h"
#include "nld_r2r_dac.h"

View File

@ -56,8 +56,8 @@ namespace netlist
private:
int m_dev_type;
public:
NETLIB_SUB(res_sw) m_RP;
NETLIB_SUB(res_sw) m_RN;
NETLIB_SUB(sys_dsw1) m_RP;
NETLIB_SUB(sys_dsw1) m_RN;
logic_output_t m_RP_Q;
logic_output_t m_RN_Q;

View File

@ -45,27 +45,6 @@
//- |High | >1/3 VDD | <2/3 VDD | As previously established||
//-
/*
* "Description: The Swiss army knife for timing purposes\n"
* " which has a ton of applications.\n"
* "DipAlias: GND,TRIG,OUT,RESET,VCC,DISCH,THRES,CONT\n"
* "Package: DIP\n"
* "NamingConvention: Naming conventions follow Texas Instruments datasheet\n"
* "Limitations: Internal resistor network currently fixed to 5k\n"
* " more limitations\n"
* "Function Table:\n"
*
* Function table created from truthtable if missing.
*
* For package, refer to:
*
* https://en.wikipedia.org/wiki/List_of_integrated_circuit_packaging_types
*
* Special case: GATE -> use symbolic names
*
*/
#include "nld_ne555.h"
#include "netlist/analog/nlid_twoterm.h"
#include "netlist/solver/nld_solver.h"

View File

@ -1,21 +0,0 @@
// license:GPL-2.0+
// copyright-holders:Couriersud
#ifndef NLD_NE555_H_
#define NLD_NE555_H_
#include "netlist/nl_setup.h"
#define NE555(name) \
NET_REGISTER_DEV(NE555, name)
#define NE555_DIP(name) \
NET_REGISTER_DEV(NE555_DIP, name)
#define MC1455P(name) \
NET_REGISTER_DEV(MC1455P, name)
#define MC1455P_DIP(name) \
NET_REGISTER_DEV(MC1455P_DIP, name)
#endif /* NLD_NE555_H_ */

View File

@ -1,96 +0,0 @@
// license:GPL-2.0+
// copyright-holders:Couriersud
//- Identifier: NE566_DIP
//- Title: NE566 VOLTAGE-CONTROLED OSCILLATOR
//- Description:
//-
//- Pinalias: GND,NC,SQUARE,TRIANGLE,MODULATION,R1,C1,VCC
//- Package: DIP
//- NamingConvention: Naming conventions follow Phillips datasheet
//- Limitations:
//- Example:
//- FunctionTable:
//-
//-
/*
* "Description: The Swiss army knife for timing purposes\n"
* " which has a ton of applications.\n"
* "DipAlias: GND,NC,SQUARE,TRIANGLE,MODULATION,R1,C1,VCC\n"
* "Package: DIP\n"
* "NamingConvention: Naming conventions follow Philips datasheet\n"
* "Limitations: \n"
* "Function Table:\n"
*
* Function table created from truthtable if missing.
*
* For package, refer to:
*
* https://en.wikipedia.org/wiki/List_of_integrated_circuit_packaging_types
*
* Special case: GATE -> use symbolic names
*
*/
#include "nld_ne566.h"
#include "netlist/analog/nlid_twoterm.h"
#include "nlid_system.h"
namespace netlist
{
namespace devices
{
NETLIB_OBJECT(NE566)
{
NETLIB_CONSTRUCTOR(NE566)
, m_MODULATION(*this, "MODULATION") // Pin 5
, m_R1(*this, "R1") // Pin 6
, m_C1(*this, "C1") // Pin 7
, m_SQUARE(*this, "SQUARE") // Pin 3
, m_TRIANGLE(*this, "TRIANGLE") // Pin 4
, m_power_pins(*this)
{
}
NETLIB_UPDATEI();
NETLIB_RESETI();
private:
analog_input_t m_MODULATION;
analog_input_t m_R1;
analog_input_t m_C1;
analog_output_t m_SQUARE;
analog_output_t m_TRIANGLE;
nld_power_pins m_power_pins;
};
NETLIB_OBJECT_DERIVED(NE566_dip, NE566)
{
NETLIB_CONSTRUCTOR_DERIVED(NE566_dip, NE566)
{
register_subalias("1", "GND"); // Pin 1
register_subalias("2", "NC"); // Pin 2
register_subalias("3", "SQUARE"); // Pin 3
register_subalias("4", "TRIANGLE"); // Pin 4
register_subalias("5", "MODULATION"); // Pin 5
register_subalias("6", "R1"); // Pin 6
register_subalias("7", "C1"); // Pin 7
register_subalias("8", "VCC"); // Pin 8
}
};
NETLIB_RESET(NE566)
{
}
NETLIB_UPDATE(NE566)
{
// frequency = f0 = (2 * (VCC - MODULATION)) / (R1 * C1 * VCC)
}
NETLIB_DEVICE_IMPL(NE566, "NE566", "")
NETLIB_DEVICE_IMPL(NE566_dip, "NE566_DIP", "")
} //namespace devices
} // namespace netlist

View File

@ -1,15 +0,0 @@
// license:GPL-2.0+
// copyright-holders:Couriersud
#ifndef NLD_NE566_H_
#define NLD_NE566_H_
#include "netlist/nl_setup.h"
#define NE566(name) \
NET_REGISTER_DEV(NE566, name)
#define NE566_DIP(name) \
NET_REGISTER_DEV(NE566_DIP, name)
#endif /* NLD_NE566_H_ */

View File

@ -68,7 +68,9 @@ namespace devices
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", "+I,+1,+2")
NETLIB_DEVICE_IMPL(sys_dsw1, "SYS_DSW", "+I,+1,+2")
NETLIB_DEVICE_IMPL(sys_dsw2, "SYS_DSW2", "")
NETLIB_DEVICE_IMPL(sys_compd, "SYS_COMPD", "")
NETLIB_DEVICE_IMPL(mainclock, "MAINCLOCK", "FREQ")
NETLIB_DEVICE_IMPL(gnd, "GNDA", "")
NETLIB_DEVICE_IMPL(netlistparams, "PARAMETER", "")

View File

@ -62,12 +62,19 @@
NET_C(cG, name.G) \
NET_C(cOUT, name.Q)
#define RES_SWITCH(name, cIN, cP1, cP2) \
NET_REGISTER_DEV(RES_SWITCH, name) \
NET_C(cIN, name.I) \
NET_C(cP1, name.1) \
// FIXME ... remove parameters
#define SYS_DSW(name, cIN, cP1, cP2) \
NET_REGISTER_DEV(SYS_DSW, name) \
NET_C(cIN, name.I) \
NET_C(cP1, name.1) \
NET_C(cP2, name.2)
#define SYS_DSW2(name) \
NET_REGISTER_DEV(SYS_DSW2, name)
#define SYS_COMPD(name) \
NET_REGISTER_DEV(SYS_COMPD, name)
/* Default device to hold netlist parameters */
#define PARAMETERS(name) \
NET_REGISTER_DEV(PARAMETERS, name)

View File

@ -246,6 +246,7 @@ namespace devices
param_model_t m_FAMILY;
NETLIB_NAME(power_pins) m_supply;
};
template<std::size_t N>
NETLIB_OBJECT(logic_inputN)
{
@ -396,9 +397,9 @@ namespace devices
std::vector<pstring> inps;
for (int i=0; i < m_N(); i++)
{
pstring n = plib::pfmt("A{1}")(i);
m_I.push_back(state().make_object<analog_input_t>(*this, n));
inps.push_back(n);
pstring inpname = plib::pfmt("A{1}")(i);
m_I.push_back(state().make_object<analog_input_t>(*this, inpname));
inps.push_back(inpname);
m_vals.push_back(nlconst::zero());
}
m_compiled.compile(m_func(), inps);
@ -431,17 +432,17 @@ namespace devices
};
// -----------------------------------------------------------------------------
// nld_res_sw
// nld_sys_dsw1
// -----------------------------------------------------------------------------
NETLIB_OBJECT(res_sw)
NETLIB_OBJECT(sys_dsw1)
{
public:
NETLIB_CONSTRUCTOR(res_sw)
NETLIB_CONSTRUCTOR(sys_dsw1)
, m_R(*this, "_R")
, m_I(*this, "I")
, m_RON(*this, "RON", nlconst::one())
, m_ROFF(*this, "ROFF", nlconst::magic(1.0E20))
, m_ROFF(*this, "ROFF", nlconst::magic(1.0E99))
, m_last_state(*this, "m_last_state", 0)
{
register_subalias("1", m_R.P());
@ -462,7 +463,6 @@ namespace devices
m_last_state = state;
const nl_fptype R = state ? m_RON() : m_ROFF();
// FIXME: We only need to update the net first if this is a time stepping net
m_R.change_state([this, &R]()
{
m_R.set_R(R);
@ -482,6 +482,140 @@ namespace devices
state_var<netlist_sig_t> m_last_state;
};
// -----------------------------------------------------------------------------
// nld_sys_dsw2
// -----------------------------------------------------------------------------
NETLIB_OBJECT(sys_dsw2)
{
public:
NETLIB_CONSTRUCTOR(sys_dsw2)
, m_R1(*this, "_R1")
, m_R2(*this, "_R2")
, m_I(*this, "I")
, m_GON(*this, "GON", nlconst::magic(1e9))
, m_GOFF(*this, "GOFF", nlconst::magic(1e9))
, m_last_state(*this, "m_last_state", 0)
, m_FAMILY(*this, "FAMILY", "FAMILY(TYPE=TTL)")
, m_power_pins(*this)
{
// Pass on logic family
set_logic_family(state().setup().family_from_model(m_FAMILY()));
m_I.set_logic_family(this->logic_family());
// connect and register pins
register_subalias("1", m_R1.P());
register_subalias("2", m_R1.N());
register_subalias("3", m_R2.N());
connect(m_R1.N(), m_R2.P());
}
NETLIB_RESETI()
{
m_last_state = 1;
m_R1.set_G(m_GOFF());
m_R2.set_G(m_GON());
}
NETLIB_UPDATEI()
{
const netlist_sig_t state = m_I();
if (1 || (state != m_last_state))
{
m_last_state = state;
//printf("Here %d\n", state);
const nl_fptype G1 = state ? m_GON() : m_GOFF();
const nl_fptype G2 = state ? m_GOFF() : m_GON();
if (m_R1.solver() == m_R2.solver())
{
m_R1.change_state([this, &G1, &G2]()
{
m_R1.set_G(G1);
m_R2.set_G(G2);
});
}
else
{
m_R1.change_state([this, &G1]()
{
m_R1.set_G(G1);
});
m_R2.change_state([this, &G2]()
{
m_R2.set_G(G2);
});
}
}
}
//NETLIB_UPDATE_PARAMI();
analog::NETLIB_SUB(R_base) m_R1;
analog::NETLIB_SUB(R_base) m_R2;
logic_input_t m_I;
param_fp_t m_GON;
param_fp_t m_GOFF;
private:
state_var<netlist_sig_t> m_last_state;
param_model_t m_FAMILY;
nld_power_pins m_power_pins;
};
// -----------------------------------------------------------------------------
// nld_sys_comp
// -----------------------------------------------------------------------------
NETLIB_OBJECT(sys_compd)
{
public:
NETLIB_CONSTRUCTOR(sys_compd)
, m_IP(*this, "IP")
, m_IN(*this, "IN")
, m_Q(*this, "Q")
, m_QQ(*this, "QQ")
, m_FAMILY(*this, "FAMILY", "FAMILY(TYPE=TTL)")
, m_power_pins(*this)
, m_last_state(*this, "m_last_state", 2) // ensure first execution
{
// Pass on logic family
set_logic_family(state().setup().family_from_model(m_FAMILY()));
m_Q.set_logic_family(this->logic_family());
m_QQ.set_logic_family(this->logic_family());
}
NETLIB_RESETI()
{
m_last_state = 0;
}
NETLIB_UPDATEI()
{
//printf("P %f N %f\n", m_IP(), m_IN());
const netlist_sig_t state = (m_IP() > m_IN());
if (state != m_last_state)
{
m_last_state = state;
// FIXME: make timing a parameter
m_Q.push(state, NLTIME_FROM_NS(10));
m_QQ.push(!state, NLTIME_FROM_NS(10));
}
}
//NETLIB_UPDATE_PARAMI();
analog_input_t m_IP;
analog_input_t m_IN;
logic_output_t m_Q;
logic_output_t m_QQ;
param_model_t m_FAMILY;
nld_power_pins m_power_pins;
private:
state_var<netlist_sig_t> m_last_state;
};
} // namespace devices
} // namespace netlist

View File

@ -0,0 +1,21 @@
#include "netlist/devices/net_lib.h"
NETLIST_START(oscillator)
SOLVER(Solver, 48000)
ANALOG_INPUT(I_V12, 12.0)
ANALOG_INPUT(I_VC, 11.9 - 0.2)
NE566_DIP(X)
RES(R1, 10000) // ~20 Hz.
CAP(C1, 1e-6)
NET_C(I_V12, R1.1, X.8)
NET_C(R1.2, X.6)
NET_C(I_VC, X.5)
NET_C(GND, X.1, C1.2)
NET_C(C1.1, X.7)
NETLIST_END()

View File

@ -79,6 +79,8 @@ static NETLIST_START(family_models)
NET_MODEL("OPAMP _()")
NET_MODEL("SCHMITT_TRIGGER _()")
// TTL: FAMILY(IVL=0.16 IVH=0.4 OVL=0.1 OVH=1.0 ORL=1.0 ORH=130)
NET_MODEL("74XXOC FAMILY(IVL=0.16 IVH=0.4 OVL=0.1 OVH=0.05 ORL=10.0 ORH=1.0e8)")
NET_MODEL("74XX FAMILY(TYPE=TTL)")
NET_MODEL("CD4XXX FAMILY(TYPE=CD4XXX)")

View File

@ -3,6 +3,7 @@
#include "nlm_other.h"
#include "netlist/devices/nld_system.h"
#include "netlist/devices/net_lib.h"
/*
* MC14584B: Hex Schmitt Trigger
@ -42,6 +43,116 @@ static NETLIST_START(MC14584B_DIP)
)
NETLIST_END()
//- Identifier: NE566_DIP
//- Title: NE566 Voltage Controlled Oscillator
//-Description: The LM566CN is a general purpose voltage controlled oscillator
//- which may be used to generate square and triangula waves, the frequency
//- of which is a very linear function of a control voltage. The frequency
//- is also a function of an external resistor and capacitor.
//-
//- The LM566CN is specified for operation over the 0°C to a 70°C
//- temperature range.
//-
//- Applications
//-
//- - FM modulation
//- - Signal generation
//- - Function generation
//- - Frequency shift keying
//- - Tone generation
//-
//- Features
//- - Wide supply voltage range: 10V to 24V
//- - Very linear modulation characteristics
//- - High temperature stability
//- - Excellent supply voltage rejection
//- - 10 to 1 frequency range with fixed capacitor
//- - Frequency programmable by means of current, voltage, resistor or capacitor
//-
//.
//- Pinalias: GND,NC,SQUARE,TRIANGLE,MODULATION,R1,C1,VCC
//- Package: DIP
//- NamingConvention: Naming conventions follow National Semiconductor datasheet
//- Limitations:
//- This implementation is focused on performance. There may be edge cases
//- which lead to issues and ringing.
//.
//- FunctionTable:
//- https://www.egr.msu.edu/eceshop/Parts_Inventory/datasheets/lm566.pdf
//-
//- Example: ne566.cpp,ne566_example
//.
static NETLIST_START(NE566_DIP)
VCVS(VI, 1)
CCCS(CI1, 1)
CCCS(CI2, -1)
SYS_COMPD(COMP)
SYS_DSW2(SW)
VCVS(VO, 1)
DIODE(DC, "D")
DIODE(DM, "D")
RES(ROSQ, 5200)
PARAM(VO.RO, 50)
PARAM(COMP.FAMILY, "FAMILY(IVL=0.16 IVH=0.4 OVL=0.1 OVH=0.1 ORL=50 ORH=50)")
PARAM(SW.GOFF, 0) // This has to be zero to block current sources
NET_C(CI2.IN, VI.OP)
NET_C(CI2.IP, CI1.IN)
NET_C(COMP.Q, SW.I)
NET_C(SW.1, CI1.OP)
NET_C(SW.3, CI2.OP)
NET_C(SW.2, VO.IP)
NET_C(VO.OP, COMP.IN)
// Avoid singular Matrix due to G=0 switch
RES(RX1, 1e10)
RES(RX2, 1e10)
NET_C(RX1.1, SW.1)
NET_C(RX2.1, SW.3)
NET_C(COMP.GND, RX1.2, RX2.2)
// Block if VC < V+ - ~4
VS(VM, 3)
PARAM(VM.RI, 10)
NET_C(VM.1, COMP.VCC)
NET_C(VM.2, DM.A)
NET_C(DM.K, VI.OP)
// Block if VC > V+
NET_C(COMP.GND, DC.A)
NET_C(SW.2, DC.K)
RES(R1, 5000)
RES(R2, 1800)
RES(R3, 6000)
// Square output wave
AFUNC(FO, 2, "min(A1-1,A0 + 5)")
NET_C(COMP.QQ, FO.A0)
NET_C(FO.Q, ROSQ.1)
NET_C(COMP.GND, SW.GND, VI.ON, VI.IN, CI1.ON, CI2.ON, VO.IN, VO.ON, R2.2, ROSQ.2)
NET_C(COMP.VCC, SW.VCC, R1.2)
NET_C(COMP.IP, R1.1, R2.1, R3.1)
NET_C(COMP.Q, R3.2)
ALIAS(1, VI.ON) // GND
ALIAS(3, FO.Q) // Square out
ALIAS(4, VO.OP) // Diag out
ALIAS(5, VI.IP) // VC
ALIAS(6, CI1.IP) // R1
ALIAS(7, SW.2) // C1
ALIAS(8, COMP.VCC) // V+
NET_C(COMP.VCC, FO.A1)
NETLIST_END()
NETLIST_START(otheric_lib)
TRUTHTABLE_START(MC14584B_GATE, 1, 1, "")
TT_HEAD(" A | Q ")
@ -52,4 +163,6 @@ NETLIST_START(otheric_lib)
TRUTHTABLE_END()
LOCAL_LIB_ENTRY(MC14584B_DIP)
LOCAL_LIB_ENTRY(NE566_DIP)
NETLIST_END()

View File

@ -24,6 +24,9 @@
#define MC14584B_DIP(name) \
NET_REGISTER_DEV(MC14584B_DIP, name)
#define NE566_DIP(name) \
NET_REGISTER_DEV(NE566_DIP, name)
#endif
/* ----------------------------------------------------------------------------

View File

@ -1302,12 +1302,12 @@ namespace netlist
std::array<ST, 1 << AW> m_data;
};
// -----------------------------------------------------------------------------
// family_setter_t
// -----------------------------------------------------------------------------
namespace detail {
// -----------------------------------------------------------------------------
// family_setter_t
// -----------------------------------------------------------------------------
struct family_setter_t
{
// NOLINTNEXTLINE(modernize-use-equals-default)

View File

@ -11,11 +11,44 @@
#include <stack>
#include <type_traits>
#include <map>
#include <utility>
namespace plib {
static constexpr const std::size_t MAX_STACK = 32;
// FIXME: Exa parsing conflicts with e,E parsing
template<typename F>
static const std::map<pstring, F> &units_si()
{
static std::map<pstring, F> units_si_stat =
{
//{ "Y", static_cast<F>(1e24) }, // NOLINT: Yotta
//{ "Z", static_cast<F>(1e21) }, // NOLINT: Zetta
//{ "E", static_cast<F>(1e18) }, // NOLINT: Exa
{ "P", static_cast<F>(1e15) }, // NOLINT: Peta
{ "T", static_cast<F>(1e12) }, // NOLINT: Tera
{ "G", static_cast<F>( 1e9) }, // NOLINT: Giga
{ "M", static_cast<F>( 1e6) }, // NOLINT: Mega
{ "k", static_cast<F>( 1e3) }, // NOLINT: Kilo
{ "h", static_cast<F>( 1e2) }, // NOLINT: Hekto
//{ "da", static_cast<F>(1e1) }, // NOLINT: Deka
{ "d", static_cast<F>(1e-1) }, // NOLINT: Dezi
{ "c", static_cast<F>(1e-2) }, // NOLINT: Zenti
{ "m", static_cast<F>(1e-3) }, // NOLINT: Milli
{ "μ", static_cast<F>(1e-6) }, // NOLINT: Mikro
{ "n", static_cast<F>(1e-9) }, // NOLINT: Nano
{ "p", static_cast<F>(1e-12) }, // NOLINT: Piko
{ "f", static_cast<F>(1e-15) }, // NOLINT: Femto
{ "a", static_cast<F>(1e-18) }, // NOLINT: Atto
{ "z", static_cast<F>(1e-21) }, // NOLINT: Zepto
{ "y", static_cast<F>(1e-24) }, // NOLINT: Yokto
};
return units_si_stat;
}
template <typename NT>
void pfunction<NT>::compile(const pstring &expr, const inputs_container &inputs) noexcept(false)
{
@ -78,9 +111,15 @@ namespace plib {
}
if (rc.m_cmd != PUSH_INPUT)
{
using fl_t = decltype(rc.m_param);
rc.m_cmd = PUSH_CONST;
bool err(false);
rc.m_param = plib::pstonum_ne<decltype(rc.m_param)>(cmd, err);
auto rs(plib::right(cmd,1));
auto r=units_si<fl_t>().find(rs);
if (r == units_si<fl_t>().end())
rc.m_param = plib::pstonum_ne<fl_t>(cmd, err);
else
rc.m_param = plib::pstonum_ne<fl_t>(plib::left(cmd, cmd.size()-1), err) * r->second;
if (err)
throw pexception(plib::pfmt("pfunction: unknown/misformatted token <{1}> in <{2}>")(cmd)(expr));
stk += 1;
@ -166,7 +205,9 @@ namespace plib {
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 == "+"))
if ((l >= "0") && (l <= "9")
&& (r == "e" || r == "E")
&& (ne == "-" || ne == "+"))
{
sexpr.push_back(sexpr1[i] + ne + sexpr1[i+2]);
i+=3;

View File

@ -77,10 +77,10 @@ static NETLIST_START(gunfight_schematics)
// accurately, it does not make any audible difference in the
// sound output produced.
RES_SWITCH(SW_LEFT_SHOT, IN_LS, I_V16_5.Q, R130.1)
RES_SWITCH(SW_RIGHT_SHOT, IN_RS, I_V16_5.Q, R230.1)
RES_SWITCH(SW_LEFT_HIT, IN_LH, I_V16_5.Q, R117.1)
RES_SWITCH(SW_RIGHT_HIT, IN_RH, I_V16_5.Q, R217.1)
SYS_DSW(SW_LEFT_SHOT, IN_LS, I_V16_5.Q, R130.1)
SYS_DSW(SW_RIGHT_SHOT, IN_RS, I_V16_5.Q, R230.1)
SYS_DSW(SW_LEFT_HIT, IN_LH, I_V16_5.Q, R117.1)
SYS_DSW(SW_RIGHT_HIT, IN_RH, I_V16_5.Q, R217.1)
// The default on-resistance of 1 ohm is a bit high for my tastes,
// considering the charging resistor which follows is only 15 ohms.

View File

@ -1679,7 +1679,7 @@ NETLIST_START(breakout)
NET_C(CR6.A, R41.1, R42.1, R43.1, R51.1, R52.1)
#else
RES_SWITCH(CR6, E2.11, R41.1, GND)
SYS_DSW(CR6, E2.11, R41.1, GND)
PARAM(CR6.RON, 1e20)
PARAM(CR6.ROFF, 1)
NET_C(R41.1, R42.1, R43.1, R51.1, R52.1)