diff options
author | 2020-05-01 10:04:22 +0200 | |
---|---|---|
committer | 2020-05-01 10:04:22 +0200 | |
commit | 13f6e92cec9bba6a96464e382f97d14e28628290 (patch) | |
tree | a5962552284cb030790912e2f34200db25ae1655 /src/lib/netlist | |
parent | cb3210d0ad8e00f2a3f17d2f7346a75f78739a36 (diff) |
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.
Diffstat (limited to 'src/lib/netlist')
-rw-r--r-- | src/lib/netlist/analog/nlid_twoterm.h | 7 | ||||
-rw-r--r-- | src/lib/netlist/build/makefile | 1 | ||||
-rw-r--r-- | src/lib/netlist/devices/net_lib.cpp | 6 | ||||
-rw-r--r-- | src/lib/netlist/devices/net_lib.h | 2 | ||||
-rw-r--r-- | src/lib/netlist/devices/nld_74123.cpp | 4 | ||||
-rw-r--r-- | src/lib/netlist/devices/nld_ne555.cpp | 21 | ||||
-rw-r--r-- | src/lib/netlist/devices/nld_ne555.h | 21 | ||||
-rw-r--r-- | src/lib/netlist/devices/nld_ne566.cpp | 96 | ||||
-rw-r--r-- | src/lib/netlist/devices/nld_ne566.h | 15 | ||||
-rw-r--r-- | src/lib/netlist/devices/nld_system.cpp | 4 | ||||
-rw-r--r-- | src/lib/netlist/devices/nld_system.h | 15 | ||||
-rw-r--r-- | src/lib/netlist/devices/nlid_system.h | 150 | ||||
-rw-r--r-- | src/lib/netlist/examples/ne566.cpp | 21 | ||||
-rw-r--r-- | src/lib/netlist/macro/nlm_base.cpp | 2 | ||||
-rw-r--r-- | src/lib/netlist/macro/nlm_other.cpp | 113 | ||||
-rw-r--r-- | src/lib/netlist/macro/nlm_other.h | 3 | ||||
-rw-r--r-- | src/lib/netlist/nl_base.h | 8 | ||||
-rw-r--r-- | src/lib/netlist/plib/pfunction.cpp | 45 |
18 files changed, 355 insertions, 179 deletions
diff --git a/src/lib/netlist/analog/nlid_twoterm.h b/src/lib/netlist/analog/nlid_twoterm.h index e318a508817..e71ee76b16f 100644 --- a/src/lib/netlist/analog/nlid_twoterm.h +++ b/src/lib/netlist/analog/nlid_twoterm.h @@ -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; }; // ----------------------------------------------------------------------------- diff --git a/src/lib/netlist/build/makefile b/src/lib/netlist/build/makefile index 705b68c815d..99000404552 100644 --- a/src/lib/netlist/build/makefile +++ b/src/lib/netlist/build/makefile @@ -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 \ diff --git a/src/lib/netlist/devices/net_lib.cpp b/src/lib/netlist/devices/net_lib.cpp index d319e5235da..d0d0077256b 100644 --- a/src/lib/netlist/devices/net_lib.cpp +++ b/src/lib/netlist/devices/net_lib.cpp @@ -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) diff --git a/src/lib/netlist/devices/net_lib.h b/src/lib/netlist/devices/net_lib.h index 1cafc1162eb..dbe1e8736fa 100644 --- a/src/lib/netlist/devices/net_lib.h +++ b/src/lib/netlist/devices/net_lib.h @@ -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" diff --git a/src/lib/netlist/devices/nld_74123.cpp b/src/lib/netlist/devices/nld_74123.cpp index e4570d27baf..fac78954243 100644 --- a/src/lib/netlist/devices/nld_74123.cpp +++ b/src/lib/netlist/devices/nld_74123.cpp @@ -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; diff --git a/src/lib/netlist/devices/nld_ne555.cpp b/src/lib/netlist/devices/nld_ne555.cpp index f5b27839960..7c799c70718 100644 --- a/src/lib/netlist/devices/nld_ne555.cpp +++ b/src/lib/netlist/devices/nld_ne555.cpp @@ -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" diff --git a/src/lib/netlist/devices/nld_ne555.h b/src/lib/netlist/devices/nld_ne555.h deleted file mode 100644 index fc575d914b7..00000000000 --- a/src/lib/netlist/devices/nld_ne555.h +++ /dev/null @@ -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_ */ diff --git a/src/lib/netlist/devices/nld_ne566.cpp b/src/lib/netlist/devices/nld_ne566.cpp deleted file mode 100644 index c2975b2b0b5..00000000000 --- a/src/lib/netlist/devices/nld_ne566.cpp +++ /dev/null @@ -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 diff --git a/src/lib/netlist/devices/nld_ne566.h b/src/lib/netlist/devices/nld_ne566.h deleted file mode 100644 index 744afd0a3bf..00000000000 --- a/src/lib/netlist/devices/nld_ne566.h +++ /dev/null @@ -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_ */ diff --git a/src/lib/netlist/devices/nld_system.cpp b/src/lib/netlist/devices/nld_system.cpp index 85c9ae4ae6a..1888c1b9fb0 100644 --- a/src/lib/netlist/devices/nld_system.cpp +++ b/src/lib/netlist/devices/nld_system.cpp @@ -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", "") diff --git a/src/lib/netlist/devices/nld_system.h b/src/lib/netlist/devices/nld_system.h index ee246600a56..879361f3ee1 100644 --- a/src/lib/netlist/devices/nld_system.h +++ b/src/lib/netlist/devices/nld_system.h @@ -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) diff --git a/src/lib/netlist/devices/nlid_system.h b/src/lib/netlist/devices/nlid_system.h index 91ffe7477d6..cd830995156 100644 --- a/src/lib/netlist/devices/nlid_system.h +++ b/src/lib/netlist/devices/nlid_system.h @@ -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 diff --git a/src/lib/netlist/examples/ne566.cpp b/src/lib/netlist/examples/ne566.cpp new file mode 100644 index 00000000000..c6ef3d0d4ca --- /dev/null +++ b/src/lib/netlist/examples/ne566.cpp @@ -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() diff --git a/src/lib/netlist/macro/nlm_base.cpp b/src/lib/netlist/macro/nlm_base.cpp index e04d98e59ad..1c7c81fd839 100644 --- a/src/lib/netlist/macro/nlm_base.cpp +++ b/src/lib/netlist/macro/nlm_base.cpp @@ -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)") diff --git a/src/lib/netlist/macro/nlm_other.cpp b/src/lib/netlist/macro/nlm_other.cpp index 873f3ad84c5..5926d12d454 100644 --- a/src/lib/netlist/macro/nlm_other.cpp +++ b/src/lib/netlist/macro/nlm_other.cpp @@ -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() + diff --git a/src/lib/netlist/macro/nlm_other.h b/src/lib/netlist/macro/nlm_other.h index 3d2c61f98f0..e6f8f82c939 100644 --- a/src/lib/netlist/macro/nlm_other.h +++ b/src/lib/netlist/macro/nlm_other.h @@ -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 /* ---------------------------------------------------------------------------- diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index e1e119961f0..1df1043b4ce 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -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) diff --git a/src/lib/netlist/plib/pfunction.cpp b/src/lib/netlist/plib/pfunction.cpp index 292bd9bb9c6..b5c1a46dda2 100644 --- a/src/lib/netlist/plib/pfunction.cpp +++ b/src/lib/netlist/plib/pfunction.cpp @@ -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; |