diff options
Diffstat (limited to 'src/lib')
38 files changed, 659 insertions, 498 deletions
diff --git a/src/lib/netlist/analog/nld_opamps.cpp b/src/lib/netlist/analog/nld_opamps.cpp index d587f691e56..3dc6711c406 100644 --- a/src/lib/netlist/analog/nld_opamps.cpp +++ b/src/lib/netlist/analog/nld_opamps.cpp @@ -8,35 +8,6 @@ #include "nld_opamps.h" #include "devices/net_lib.h" -NETLIST_START(opamp_lm3900) - - /* - * Fast norton opamp model without bandwidth - */ - - /* Terminal definitions for calling netlists */ - - ALIAS(PLUS, R1.1) // Positive input - ALIAS(MINUS, R2.1) // Negative input - ALIAS(OUT, G1.OP) // Opamp output ... - ALIAS(VM, G1.ON) // V- terminal - ALIAS(VP, DUMMY.I) // V+ terminal - - DUMMY_INPUT(DUMMY) - - /* The opamp model */ - - RES(R1, 1) - RES(R2, 1) - NET_C(R1.1, G1.IP) - NET_C(R2.1, G1.IN) - NET_C(R1.2, R2.2, G1.ON) - VCVS(G1) - PARAM(G1.G, 10000000) - //PARAM(G1.RI, 1) - PARAM(G1.RO, RES_K(8)) - -NETLIST_END() namespace netlist { diff --git a/src/lib/netlist/analog/nld_opamps.h b/src/lib/netlist/analog/nld_opamps.h index 5d9825d4b21..95060dfdbd3 100644 --- a/src/lib/netlist/analog/nld_opamps.h +++ b/src/lib/netlist/analog/nld_opamps.h @@ -23,15 +23,10 @@ NET_REGISTER_DEV(OPAMP, name) \ NETDEV_PARAMI(name, MODEL, model) -#define LM3900(name) \ - SUBMODEL(opamp_lm3900, name) - // ---------------------------------------------------------------------------------------- // Devices ... // ---------------------------------------------------------------------------------------- -NETLIST_EXTERNAL(opamp_lm3900) - namespace netlist { namespace devices diff --git a/src/lib/netlist/devices/net_lib.cpp b/src/lib/netlist/devices/net_lib.cpp index 5250135feb8..9f23283ac6b 100644 --- a/src/lib/netlist/devices/net_lib.cpp +++ b/src/lib/netlist/devices/net_lib.cpp @@ -63,7 +63,7 @@ NETLIST_END() #define ENTRY1(nic, name, defparam) factory.register_device<nic>( # name, xstr(nic), defparam ); #define ENTRY(nic, name, defparam) ENTRY1(NETLIB_NAME(nic), name, defparam) -#define NETLIB_DEVICE_DECL(chip) extern factory_creator_ptr_t decl_ ## chip; +#define NETLIB_DEVICE_DECL(chip) extern factory::constructor_ptr_t decl_ ## chip; #define ENTRYX1(nic, name, defparam, decl) factory.register_device( decl (# name, xstr(nic), defparam) ); #define ENTRYX(nic, name, defparam) { NETLIB_DEVICE_DECL(nic) ENTRYX1(NETLIB_NAME(nic), name, defparam, decl_ ## nic) } @@ -72,7 +72,7 @@ namespace netlist { namespace devices { -static void initialize_factory(factory_list_t &factory) +static void initialize_factory(factory::list_t &factory) { ENTRY(R, RES, "R") ENTRY(POT, POT, "R") @@ -80,15 +80,15 @@ static void initialize_factory(factory_list_t &factory) ENTRY(C, CAP, "C") ENTRY(L, IND, "L") ENTRY(D, DIODE, "MODEL") - ENTRY(VCVS, VCVS, "-") - ENTRY(VCCS, VCCS, "-") - ENTRY(CCCS, CCCS, "-") - ENTRY(LVCCS, LVCCS, "-") + ENTRY(VCVS, VCVS, "") + ENTRY(VCCS, VCCS, "") + ENTRY(CCCS, CCCS, "") + ENTRY(LVCCS, LVCCS, "") ENTRY(VS, VS, "V") ENTRY(CS, CS, "I") ENTRY(OPAMP, OPAMP, "MODEL") - ENTRYX(dummy_input, DUMMY_INPUT, "-") - ENTRYX(frontier, FRONTIER_DEV, "+I,G,Q") // not intended to be used directly + ENTRYX(dummy_input, DUMMY_INPUT, "") + ENTRYX(frontier, FRONTIER_DEV, "+I,+G,+Q") // not intended to be used directly ENTRYX(function, AFUNC, "N,FUNC") // only for macro devices - NO FEEDBACK loops ENTRY(QBJT_EB, QBJT_EB, "MODEL") ENTRY(QBJT_switch, QBJT_SW, "MODEL") @@ -96,106 +96,107 @@ static void initialize_factory(factory_list_t &factory) ENTRYX(logic_input, LOGIC_INPUT, "IN,FAMILY") ENTRYX(analog_input, ANALOG_INPUT, "IN") ENTRYX(log, LOG, "+I") - ENTRYX(logD, LOGD, "+I,I2") + ENTRYX(logD, LOGD, "+I,+I2") ENTRYX(clock, CLOCK, "FREQ") ENTRYX(extclock, EXTCLOCK, "FREQ") ENTRYX(mainclock, MAINCLOCK, "FREQ") - ENTRYX(gnd, GND, "-") - ENTRYX(netlistparams, PARAMETER, "-") + ENTRYX(gnd, GND, "") + ENTRYX(netlistparams, PARAMETER, "") ENTRY(solver, SOLVER, "FREQ") - ENTRYX(res_sw, RES_SWITCH, "+IN,P1,P2") - ENTRY(switch1, SWITCH, "-") - ENTRY(switch2, SWITCH2, "-") - ENTRYX(nicRSFF, NETDEV_RSFF, "+S,R") - ENTRYX(nicDelay, NETDEV_DELAY, "-") - ENTRYX(2716, EPROM_2716, "+GQ,EPQ,A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10") - ENTRYX(2102A, RAM_2102A, "+CEQ,A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,RWQ,DI") - ENTRYX(7450, TTL_7450_ANDORINVERT, "+A,B,C,D") - ENTRYX(7448, TTL_7448, "+A,B,C,D,LTQ,BIQ,RBIQ") - ENTRYX(7473, TTL_7473, "+CLK,J,K,CLRQ") - ENTRYX(7473A, TTL_7473A, "+CLK,J,K,CLRQ") - ENTRYX(7474, TTL_7474, "+CLK,D,CLRQ,PREQ") - ENTRYX(7475, TTL_7475, "-") - ENTRYX(7477, TTL_7477, "-") - ENTRYX(7483, TTL_7483, "+A1,A2,A3,A4,B1,B2,B3,B4,C0") - ENTRYX(7485, TTL_7485, "+A0,A1,A2,A3,B0,B1,B2,B3,LTIN,EQIN,GTIN") - ENTRYX(7490, TTL_7490, "+A,B,R1,R2,R91,R92") - ENTRYX(7493, TTL_7493, "+CLKA,CLKB,R1,R2") - ENTRYX(74107, TTL_74107, "+CLK,J,K,CLRQ") - ENTRYX(74107A, TTL_74107A, "+CLK,J,K,CLRQ") - ENTRYX(74123, TTL_74123, "-") - ENTRYX(74153, TTL_74153, "+C0,C1,C2,C3,A,B,G") - ENTRYX(74161, TTL_74161, "+A,B,C,D,CLRQ,LOADQ,CLK,ENABLEP,ENABLET") - ENTRYX(74165, TTL_74165, "+CLK,CLKINH,SH_LDQ,SER,A,B,C,D,E,F,G,H") - ENTRYX(74166, TTL_74166, "+CLK,CLKINH,SH_LDQ,SER,A,B,C,D,E,F,G,H,CLRQ") - ENTRYX(74174, TTL_74174, "+CLK,D1,D2,D3,D4,D5,D6,CLRQ") - ENTRYX(74175, TTL_74175, "+CLK,D1,D2,D3,D4,CLRQ") - ENTRYX(74192, TTL_74192, "+A,B,C,D,CLEAR,LOADQ,CU,CD") - ENTRYX(74193, TTL_74193, "+A,B,C,D,CLEAR,LOADQ,CU,CD") - ENTRYX(74194, TTL_74194, "+CLK,S0,S1,SRIN,A,B,C,D,SLIN,CLRQ") - ENTRYX(74365, TTL_74365, "+G1Q,G2Q,A1,A2,A3,A4,A5,A6") - //ENTRY(74279, TTL_74279, "-") // only dip available + ENTRYX(res_sw, RES_SWITCH, "+IN,+P1,+P2") + ENTRY(switch1, SWITCH, "") + ENTRY(switch2, SWITCH2, "") + ENTRYX(nicRSFF, NETDEV_RSFF, "+S,+R") + ENTRYX(nicDelay, NETDEV_DELAY, "") + ENTRYX(2716, EPROM_2716, "+GQ,+EPQ,+A0,+A1,+A2,+A3,+A4,+A5,+A6,+A7,+A8,+A9,+A10") + ENTRYX(2102A, RAM_2102A, "+CEQ,+A0,+A1,+A2,+A3,+A4,+A5,+A6,+A7,+A8,+A9,+RWQ,+DI") + ENTRYX(7450, TTL_7450_ANDORINVERT, "+A,+B,+C,+D") + ENTRYX(7448, TTL_7448, "+A,+B,+C,+D,+LTQ,+BIQ,+RBIQ") + ENTRYX(7473, TTL_7473, "+CLK,+J,+K,+CLRQ") + ENTRYX(7473A, TTL_7473A, "+CLK,+J,+K,+CLRQ") + ENTRYX(7474, TTL_7474, "+CLK,+D,+CLRQ,+PREQ") + ENTRYX(7475, TTL_7475, "") + ENTRYX(7477, TTL_7477, "") + ENTRYX(7483, TTL_7483, "+A1,+A2,+A3,+A4,+B1,+B2,+B3,+B4,+C0") + ENTRYX(7485, TTL_7485, "+A0,+A1,+A2,+A3,+B0,+B1,+B2,+B3,+LTIN,+EQIN,+GTIN") + ENTRYX(7490, TTL_7490, "+A,+B,+R1,+R2,+R91,+R92") + ENTRYX(7493, TTL_7493, "+CLKA,+CLKB,+R1,+R2") + ENTRYX(74107, TTL_74107, "+CLK,+J,+K,+CLRQ") + ENTRYX(74107A, TTL_74107A, "+CLK,+J,+K,+CLRQ") + ENTRYX(74123, TTL_74123, "") + ENTRYX(74153, TTL_74153, "+C0,+C1,+C2,+C3,+A,+B,+G") + ENTRYX(74161, TTL_74161, "+A,+B,+C,+D,+CLRQ,+LOADQ,+CLK,+ENABLEP,+ENABLET") + ENTRYX(74165, TTL_74165, "+CLK,+CLKINH,+SH_LDQ,+SER,+A,+B,+C,+D,+E,+F,+G,+H") + ENTRYX(74166, TTL_74166, "+CLK,+CLKINH,+SH_LDQ,+SER,+A,+B,+C,+D,+E,+F,+G,+H,+CLRQ") + ENTRYX(74174, TTL_74174, "+CLK,+D1,+D2,+D3,+D4,+D5,+D6,+CLRQ") + ENTRYX(74175, TTL_74175, "+CLK,+D1,+D2,+D3,+D4,+CLRQ") + ENTRYX(74192, TTL_74192, "+A,+B,+C,+D,+CLEAR,+LOADQ,+CU,+CD") + ENTRYX(74193, TTL_74193, "+A,+B,+C,+D,+CLEAR,+LOADQ,+CU,+CD") + ENTRYX(74194, TTL_74194, "+CLK,+S0,+S1,+SRIN,+A,+B,+C,+D,+SLIN,+CLRQ") + ENTRYX(74365, TTL_74365, "+G1Q,+G2Q,+A1,+A2,+A3,+A4,+A5,+A6") + //ENTRY(74279, TTL_74279, "") // only dip available ENTRYX(SN74LS629, SN74LS629, "CAP") - ENTRYX(82S16, TTL_82S16, "-") - ENTRYX(82S115, PROM_82S115, "+CE1Q,CE2,A0,A1,A2,A3,A4,A5,A6,A7,A8,STROBE") - ENTRYX(82S123, PROM_82S123, "+CEQ,A0,A1,A2,A3,A4") - ENTRYX(82S126, PROM_82S126, "+CE1Q,CE2Q,A0,A1,A2,A3,A4,A5,A6,A7") - ENTRYX(9310, TTL_9310, "-") - ENTRYX(9312, TTL_9312, "+A,B,C,D0,D1,D2,D3,D4,D5,D6,D7,G") - ENTRYX(9316, TTL_9316, "+CLK,ENP,ENT,CLRQ,LOADQ,A,B,C,D") - ENTRYX(9322, TTL_9322, "+SELECT,A1,B1,A2,B2,A3,B3,A4,B4,STROBE") - ENTRYX(9334, TTL_9334, "+CQ,EQ,D,A0,A1,A2") - ENTRYX(AM2847, TTL_AM2847, "+CP,INA,INB,INC,IND,RCA,RCB,RCC,RCD") + ENTRYX(82S16, TTL_82S16, "") + ENTRYX(82S115, PROM_82S115, "+CE1Q,+CE2,+A0,+A1,+A2,+A3,+A4,+A5,+A6,+A7,+A8,+STROBE") + ENTRYX(82S123, PROM_82S123, "+CEQ,+A0,+A1,+A2,+A3,+A4") + ENTRYX(82S126, PROM_82S126, "+CE1Q,+CE2Q,+A0,+A1,+A2,+A3,+A4,+A5,+A6,+A7") + ENTRYX(9310, TTL_9310, "") + ENTRYX(9312, TTL_9312, "+A,+B,+C,+D0,+D1,+D2,+D3,+D4,+D5,+D6,+D7,+G") + ENTRYX(9316, TTL_9316, "+CLK,+ENP,+ENT,+CLRQ,+LOADQ,+A,+B,+C,+D") + ENTRYX(9322, TTL_9322, "+SELECT,+A1,+B1,+A2,+B2,+A3,+B3,+A4,+B4,+STROBE") + ENTRYX(9334, TTL_9334, "+CQ,+EQ,+D,+A0,+A1,+A2") + ENTRYX(AM2847, TTL_AM2847, "+CP,+INA,+INB,+INC,+IND,+RCA,+RCB,+RCC,+RCD") ENTRYX(CD4020, CD4020, "") ENTRYX(CD4066_GATE, CD4066_GATE, "") + ENTRYX(CD4316_GATE, CD4316_GATE, "") /* entries with suffix WI are legacy only */ - ENTRYX(CD4020, CD4020_WI, "+IP,RESET,VDD,VSS") + ENTRYX(CD4020, CD4020_WI, "+IP,+RESET,+VDD,+VSS") //ENTRY(4066, CD_4066, "+A,B") - ENTRYX(NE555, NE555, "-") - ENTRYX(r2r_dac, R2R_DAC, "+VIN,R,N") - ENTRYX(tristate, TTL_TRISTATE, "+CEQ1,D1,CEQ2,D2") - ENTRYX(tristate3, TTL_TRISTATE3, "-") - ENTRYX(2102A_dip, RAM_2102A_DIP, "-") - ENTRYX(2716_dip, EPROM_2716_DIP, "-") - ENTRYX(4538_dip, CD4538_DIP, "-") - ENTRYX(7448_dip, TTL_7448_DIP, "-") - ENTRYX(7450_dip, TTL_7450_DIP, "-") - ENTRYX(7473_dip, TTL_7473_DIP, "-") - ENTRYX(7473A_dip, TTL_7473A_DIP, "-") - ENTRYX(7474_dip, TTL_7474_DIP, "-") - ENTRYX(7475_dip, TTL_7475_DIP, "-") - ENTRYX(7477_dip, TTL_7477_DIP, "-") - ENTRYX(7483_dip, TTL_7483_DIP, "-") - ENTRYX(7485_dip, TTL_7485_DIP, "-") - ENTRYX(7490_dip, TTL_7490_DIP, "-") - ENTRYX(7493_dip, TTL_7493_DIP, "-") - ENTRYX(74107_dip, TTL_74107_DIP, "-") - ENTRYX(74123_dip, TTL_74123_DIP, "-") - ENTRYX(74153_dip, TTL_74153_DIP, "-") - ENTRYX(74161_dip, TTL_74161_DIP, "-") - ENTRYX(74165_dip, TTL_74165_DIP, "-") - ENTRYX(74166_dip, TTL_74166_DIP, "-") - ENTRYX(74174_dip, TTL_74174_DIP, "-") - ENTRYX(74175_dip, TTL_74175_DIP, "-") - ENTRYX(74192_dip, TTL_74192_DIP, "-") - ENTRYX(74193_dip, TTL_74193_DIP, "-") - ENTRYX(74194_dip, TTL_74194_DIP, "-") - ENTRYX(74279_dip, TTL_74279_DIP, "-") - ENTRYX(74365_dip, TTL_74365_DIP, "-") - ENTRYX(82S16_dip, TTL_82S16_DIP, "-") - ENTRYX(82S115_dip, PROM_82S115_DIP, "-") - ENTRYX(82S123_dip, PROM_82S123_DIP, "-") - ENTRYX(82S126_dip, PROM_82S126_DIP, "-") - ENTRYX(9602_dip, TTL_9602_DIP, "-") - ENTRYX(9310_dip, TTL_9310_DIP, "-") - ENTRYX(9312_dip, TTL_9312_DIP, "-") - ENTRYX(9316_dip, TTL_9316_DIP, "-") - ENTRYX(9322_dip, TTL_9322_DIP, "-") - ENTRYX(9334_dip, TTL_9334_DIP, "-") - ENTRYX(AM2847_dip, TTL_AM2847_DIP, "-") + ENTRYX(NE555, NE555, "") + ENTRYX(r2r_dac, R2R_DAC, "VIN,R,N") + ENTRYX(tristate, TTL_TRISTATE, "+CEQ1,+D1,+CEQ2,+D2") + ENTRYX(tristate3, TTL_TRISTATE3, "") + ENTRYX(2102A_dip, RAM_2102A_DIP, "") + ENTRYX(2716_dip, EPROM_2716_DIP, "") + ENTRYX(4538_dip, CD4538_DIP, "") + ENTRYX(7448_dip, TTL_7448_DIP, "") + ENTRYX(7450_dip, TTL_7450_DIP, "") + ENTRYX(7473_dip, TTL_7473_DIP, "") + ENTRYX(7473A_dip, TTL_7473A_DIP, "") + ENTRYX(7474_dip, TTL_7474_DIP, "") + ENTRYX(7475_dip, TTL_7475_DIP, "") + ENTRYX(7477_dip, TTL_7477_DIP, "") + ENTRYX(7483_dip, TTL_7483_DIP, "") + ENTRYX(7485_dip, TTL_7485_DIP, "") + ENTRYX(7490_dip, TTL_7490_DIP, "") + ENTRYX(7493_dip, TTL_7493_DIP, "") + ENTRYX(74107_dip, TTL_74107_DIP, "") + ENTRYX(74123_dip, TTL_74123_DIP, "") + ENTRYX(74153_dip, TTL_74153_DIP, "") + ENTRYX(74161_dip, TTL_74161_DIP, "") + ENTRYX(74165_dip, TTL_74165_DIP, "") + ENTRYX(74166_dip, TTL_74166_DIP, "") + ENTRYX(74174_dip, TTL_74174_DIP, "") + ENTRYX(74175_dip, TTL_74175_DIP, "") + ENTRYX(74192_dip, TTL_74192_DIP, "") + ENTRYX(74193_dip, TTL_74193_DIP, "") + ENTRYX(74194_dip, TTL_74194_DIP, "") + ENTRYX(74279_dip, TTL_74279_DIP, "") + ENTRYX(74365_dip, TTL_74365_DIP, "") + ENTRYX(82S16_dip, TTL_82S16_DIP, "") + ENTRYX(82S115_dip, PROM_82S115_DIP, "") + ENTRYX(82S123_dip, PROM_82S123_DIP, "") + ENTRYX(82S126_dip, PROM_82S126_DIP, "") + ENTRYX(9602_dip, TTL_9602_DIP, "") + ENTRYX(9310_dip, TTL_9310_DIP, "") + ENTRYX(9312_dip, TTL_9312_DIP, "") + ENTRYX(9316_dip, TTL_9316_DIP, "") + ENTRYX(9322_dip, TTL_9322_DIP, "") + ENTRYX(9334_dip, TTL_9334_DIP, "") + ENTRYX(AM2847_dip, TTL_AM2847_DIP, "") ENTRYX(SN74LS629_dip, SN74LS629_DIP, "1.CAP1,2.CAP2") - ENTRYX(NE555_dip, NE555_DIP, "-") - ENTRYX(MM5837_dip, MM5837_DIP, "-") + ENTRYX(NE555_dip, NE555_DIP, "") + ENTRYX(MM5837_dip, MM5837_DIP, "") } } //namespace devices @@ -203,7 +204,7 @@ static void initialize_factory(factory_list_t &factory) namespace netlist { - void initialize_factory(factory_list_t &factory) + void initialize_factory(factory::list_t &factory) { devices::initialize_factory(factory); } diff --git a/src/lib/netlist/devices/net_lib.h b/src/lib/netlist/devices/net_lib.h index c9c0b6b3917..585df6aa369 100644 --- a/src/lib/netlist/devices/net_lib.h +++ b/src/lib/netlist/devices/net_lib.h @@ -81,7 +81,7 @@ NETLIST_EXTERNAL(bjt_models) NETLIST_EXTERNAL(family_models) namespace netlist { - void initialize_factory(netlist::factory_list_t &factory); + void initialize_factory(factory::list_t &factory); } #endif diff --git a/src/lib/netlist/devices/nld_7448.cpp b/src/lib/netlist/devices/nld_7448.cpp index 56b322dbc2f..8b4d11c374b 100644 --- a/src/lib/netlist/devices/nld_7448.cpp +++ b/src/lib/netlist/devices/nld_7448.cpp @@ -62,7 +62,7 @@ namespace netlist register_subalias("2", m_C); register_subalias("3", m_LTQ); register_subalias("4", m_BIQ); - register_subalias("5",m_RBIQ); + register_subalias("5", m_RBIQ); register_subalias("6", m_D); register_subalias("7", m_A); diff --git a/src/lib/netlist/devices/nld_7493.cpp b/src/lib/netlist/devices/nld_7493.cpp index 6e96facabae..a87aada2cd6 100644 --- a/src/lib/netlist/devices/nld_7493.cpp +++ b/src/lib/netlist/devices/nld_7493.cpp @@ -71,7 +71,7 @@ namespace netlist { NETLIB_CONSTRUCTOR_DERIVED(7493_dip, 7493) { - register_subalias("1", B.m_I); + register_subalias("1", "CLKB"); register_subalias("2", m_R1); register_subalias("3", m_R2); @@ -80,13 +80,13 @@ namespace netlist // register_subalias("6", ); --> NC // register_subalias("7", ); --> NC - register_subalias("8", C.m_Q); - register_subalias("9", B.m_Q); + register_subalias("8", "QC"); + register_subalias("9", "QB"); // register_subalias("10", ); -. GND - register_subalias("11", D.m_Q); - register_subalias("12", A.m_Q); + register_subalias("11", "QD"); + register_subalias("12", "QA"); // register_subalias("13", ); -. NC - register_subalias("14", A.m_I); + register_subalias("14", "CLKA"); } }; diff --git a/src/lib/netlist/devices/nld_truthtable.h b/src/lib/netlist/devices/nld_truthtable.h index 6fcd746578f..564699cd89b 100644 --- a/src/lib/netlist/devices/nld_truthtable.h +++ b/src/lib/netlist/devices/nld_truthtable.h @@ -235,7 +235,7 @@ namespace netlist desc.setup(m_desc, disabled_ignore * 0); #if 0 - printf("%s\n", name().cstr()); + printf("%s\n", name().c_str()); for (int j=0; j < m_size; j++) printf("%05x %04x %04x %04x\n", j, m_ttp->m_outs[j] & ((1 << m_NO)-1), m_ttp->m_outs[j] >> m_NO, m_ttp->m_timing[j * m_NO + 0]); @@ -261,7 +261,7 @@ namespace netlist } public: - void inc_active() noexcept override + void inc_active() NL_NOEXCEPT override { if (m_NI > 1) if (++m_active == 1) @@ -270,7 +270,7 @@ namespace netlist } } - void dec_active() noexcept override + void dec_active() NL_NOEXCEPT override { /* FIXME: * Based on current measurements there is no point to disable @@ -366,13 +366,13 @@ namespace netlist plib::pstring_vector_t m_desc; }; - class netlist_base_factory_truthtable_t : public base_factory_t + class netlist_base_factory_truthtable_t : public factory::element_t { P_PREVENT_COPYING(netlist_base_factory_truthtable_t) public: netlist_base_factory_truthtable_t(const pstring &name, const pstring &classname, const pstring &def_param) - : base_factory_t(name, classname, def_param), m_family(family_TTL()) + : factory::element_t(name, classname, def_param), m_family(family_TTL()) {} virtual ~netlist_base_factory_truthtable_t() diff --git a/src/lib/netlist/devices/nlid_proxy.cpp b/src/lib/netlist/devices/nlid_proxy.cpp index 6ecad8656a2..080f9a27a4b 100644 --- a/src/lib/netlist/devices/nlid_proxy.cpp +++ b/src/lib/netlist/devices/nlid_proxy.cpp @@ -53,9 +53,9 @@ namespace netlist else netlist().log().warning("D/A Proxy: Found power terminals on device {1}", out_proxied->device().name()); #if (0) - printf("%s %s\n", out_proxied->name().cstr(), out_proxied->device().name().cstr()); + printf("%s %s\n", out_proxied->name().c_str(), out_proxied->device().name().c_str()); auto x = netlist().setup().find_terminal(out_proxied->name(), detail::device_object_t::type_t::OUTPUT, false); - if (x) printf("==> %s\n", x->name().cstr()); + if (x) printf("==> %s\n", x->name().c_str()); #endif } diff --git a/src/lib/netlist/devices/nlid_proxy.h b/src/lib/netlist/devices/nlid_proxy.h index bcda8fa4e2a..50920c5cf80 100644 --- a/src/lib/netlist/devices/nlid_proxy.h +++ b/src/lib/netlist/devices/nlid_proxy.h @@ -61,20 +61,41 @@ namespace netlist // nld_a_to_d_proxy // ----------------------------------------------------------------------------- - NETLIB_OBJECT_DERIVED(a_to_d_proxy, base_proxy) + NETLIB_OBJECT_DERIVED(base_a_to_d_proxy, base_proxy) + { + public: + + virtual ~nld_base_a_to_d_proxy() {} + + virtual logic_output_t &out() { return m_Q; } + + protected: + + nld_base_a_to_d_proxy(netlist_t &anetlist, const pstring &name, + logic_input_t *in_proxied, detail::core_terminal_t *in_proxy) + : nld_base_proxy(anetlist, name, in_proxied, in_proxy) + , m_Q(*this, "Q") + { + } + + private: + + logic_output_t m_Q; + + }; + + NETLIB_OBJECT_DERIVED(a_to_d_proxy, base_a_to_d_proxy) { public: nld_a_to_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *in_proxied) - : nld_base_proxy(anetlist, name, in_proxied, &m_I) + : nld_base_a_to_d_proxy(anetlist, name, in_proxied, &m_I) , m_I(*this, "I") - , m_Q(*this, "Q") { } virtual ~nld_a_to_d_proxy() {} analog_input_t m_I; - logic_output_t m_Q; protected: @@ -88,9 +109,9 @@ namespace netlist if (supply_V == 0.0) supply_V = 5.0; if (m_I.Q_Analog() > logic_family().high_thresh_V(0.0, supply_V)) - m_Q.push(1, NLTIME_FROM_NS(1)); + out().push(1, NLTIME_FROM_NS(1)); else if (m_I.Q_Analog() < logic_family().low_thresh_V(0.0, supply_V)) - m_Q.push(0, NLTIME_FROM_NS(1)); + out().push(0, NLTIME_FROM_NS(1)); else { // do nothing @@ -141,43 +162,6 @@ namespace netlist bool m_is_timestep; }; - - class factory_lib_entry_t : public base_factory_t - { - P_PREVENT_COPYING(factory_lib_entry_t) - public: - - factory_lib_entry_t(setup_t &setup, const pstring &name, const pstring &classname, - const pstring &def_param) - : base_factory_t(name, classname, def_param), m_setup(setup) { } - - class wrapper : public device_t - { - public: - wrapper(const pstring &devname, netlist_t &anetlist, const pstring &name) - : device_t(anetlist, name), m_devname(devname) - { - anetlist.setup().namespace_push(name); - anetlist.setup().include(m_devname); - anetlist.setup().namespace_pop(); - } - protected: - NETLIB_RESETI() { } - NETLIB_UPDATEI() { } - - pstring m_devname; - }; - - plib::owned_ptr<device_t> Create(netlist_t &anetlist, const pstring &name) override - { - return plib::owned_ptr<device_t>::Create<wrapper>(this->name(), anetlist, name); - } - - private: - setup_t &m_setup; - }; - - } //namespace devices } // namespace netlist diff --git a/src/lib/netlist/macro/nlm_opamp.cpp b/src/lib/netlist/macro/nlm_opamp.cpp index 08dc5f60b27..146f95b72b4 100644 --- a/src/lib/netlist/macro/nlm_opamp.cpp +++ b/src/lib/netlist/macro/nlm_opamp.cpp @@ -52,7 +52,7 @@ static NETLIST_START(opamp_layout_2_13_9_4) A.GND, /* |4 11| */ NC, B.N1, /* |5 10| */ B.OUT, B.PLUS, /* |6 9| */ B.VCC, - B.MINUS /* |7 8| */ B.N2 + B.MINUS, /* |7 8| */ B.N2 /* +--------------+ */ ) NET_C(A.GND, B.GND) @@ -186,6 +186,37 @@ static NETLIST_START(LM747A_DIP) NETLIST_END() +static NETLIST_START(LM3900) + + /* + * Fast norton opamp model without bandwidth + */ + + /* Terminal definitions for calling netlists */ + + ALIAS(PLUS, R1.1) // Positive input + ALIAS(MINUS, R2.1) // Negative input + ALIAS(OUT, G1.OP) // Opamp output ... + ALIAS(VM, G1.ON) // V- terminal + ALIAS(VP, DUMMY.I) // V+ terminal + + DUMMY_INPUT(DUMMY) + + /* The opamp model */ + + RES(R1, 1) + RES(R2, 1) + NET_C(R1.1, G1.IP) + NET_C(R2.1, G1.IN) + NET_C(R1.2, R2.2, G1.ON) + VCVS(G1) + PARAM(G1.G, 10000000) + //PARAM(G1.RI, 1) + PARAM(G1.RO, RES_K(8)) + +NETLIST_END() + + NETLIST_START(OPAMP_lib) LOCAL_LIB_ENTRY(opamp_layout_4_4_11) LOCAL_LIB_ENTRY(opamp_layout_2_8_4) @@ -209,5 +240,6 @@ NETLIST_START(OPAMP_lib) LOCAL_LIB_ENTRY(UA741_DIP14) LOCAL_LIB_ENTRY(LM747_DIP) LOCAL_LIB_ENTRY(LM747A_DIP) + LOCAL_LIB_ENTRY(LM3900) NETLIST_END() diff --git a/src/lib/netlist/macro/nlm_opamp.h b/src/lib/netlist/macro/nlm_opamp.h index f349f11911c..6e3c1f615e7 100644 --- a/src/lib/netlist/macro/nlm_opamp.h +++ b/src/lib/netlist/macro/nlm_opamp.h @@ -20,6 +20,9 @@ #define LM358_DIP(name) \ NET_REGISTER_DEV(LM358_DIP, name) +#define LM3900(name) \ + NET_REGISTER_DEV(LM3900, name) + /* ---------------------------------------------------------------------------- * External declarations * ---------------------------------------------------------------------------*/ diff --git a/src/lib/netlist/macro/nlm_ttl74xx.cpp b/src/lib/netlist/macro/nlm_ttl74xx.cpp index 2120d88eb3f..c66314366d2 100644 --- a/src/lib/netlist/macro/nlm_ttl74xx.cpp +++ b/src/lib/netlist/macro/nlm_ttl74xx.cpp @@ -588,7 +588,7 @@ NETLIST_START(TTL74XX_lib) TT_FAMILY("74XX") TRUTHTABLE_END() - TRUTHTABLE_START(TTL_7400_NAND, 2, 1, "A,B") + TRUTHTABLE_START(TTL_7400_NAND, 2, 1, "+A,+B") TT_HEAD("A,B|Q ") TT_LINE("0,X|1|22") TT_LINE("X,0|1|22") @@ -604,7 +604,7 @@ NETLIST_START(TTL74XX_lib) TT_FAMILY("74XX") TRUTHTABLE_END() - TRUTHTABLE_START(TTL_7402_NOR, 2, 1, "A,B") + TRUTHTABLE_START(TTL_7402_NOR, 2, 1, "+A,+B") TT_HEAD("A,B|Q ") TT_LINE("0,0|1|22") TT_LINE("X,1|0|15") @@ -619,7 +619,7 @@ NETLIST_START(TTL74XX_lib) TT_FAMILY("74XX") TRUTHTABLE_END() - TRUTHTABLE_START(TTL_7404_INVERT, 1, 1, "A") + TRUTHTABLE_START(TTL_7404_INVERT, 1, 1, "+A") TT_HEAD(" A | Q ") TT_LINE(" 0 | 1 |22") TT_LINE(" 1 | 0 |15") @@ -634,7 +634,7 @@ NETLIST_START(TTL74XX_lib) TT_FAMILY("74XX") TRUTHTABLE_END() - TRUTHTABLE_START(TTL_7408_AND, 2, 1, "A,B") + TRUTHTABLE_START(TTL_7408_AND, 2, 1, "+A,+B") TT_HEAD("A,B|Q ") TT_LINE("0,X|0|15") TT_LINE("X,0|0|15") @@ -642,7 +642,7 @@ NETLIST_START(TTL74XX_lib) TT_FAMILY("74XX") TRUTHTABLE_END() - TRUTHTABLE_START(TTL_7410_NAND, 3, 1, "A,B,C") + TRUTHTABLE_START(TTL_7410_NAND, 3, 1, "+A,+B,+C") TT_HEAD("A,B,C|Q ") TT_LINE("0,X,X|1|22") TT_LINE("X,0,X|1|22") @@ -660,7 +660,7 @@ NETLIST_START(TTL74XX_lib) TT_FAMILY("74XX") TRUTHTABLE_END() - TRUTHTABLE_START(TTL_7411_AND, 3, 1, "A,B,C") + TRUTHTABLE_START(TTL_7411_AND, 3, 1, "+A,+B,+C") TT_HEAD("A,B,C|Q ") TT_LINE("0,X,X|0|15") TT_LINE("X,0,X|0|15") @@ -696,7 +696,7 @@ NETLIST_START(TTL74XX_lib) TT_FAMILY("74XX") TRUTHTABLE_END() - TRUTHTABLE_START(TTL_7420_NAND, 4, 1, "A,B,C,D") + TRUTHTABLE_START(TTL_7420_NAND, 4, 1, "+A,+B,+C,+D") TT_HEAD("A,B,C,D|Q ") TT_LINE("0,X,X,X|1|22") TT_LINE("X,0,X,X|1|22") @@ -716,7 +716,7 @@ NETLIST_START(TTL74XX_lib) TT_FAMILY("74XX") TRUTHTABLE_END() - TRUTHTABLE_START(TTL_7425_NOR, 4, 1, "A,B,C,D") + TRUTHTABLE_START(TTL_7425_NOR, 4, 1, "+A,+B,+C,+D") TT_HEAD("A,B,C,D|Q ") TT_LINE("1,X,X,X|0|15") TT_LINE("X,1,X,X|0|15") @@ -735,7 +735,7 @@ NETLIST_START(TTL74XX_lib) TT_FAMILY("74XX") TRUTHTABLE_END() - TRUTHTABLE_START(TTL_7427_NOR, 3, 1, "A,B,C") + TRUTHTABLE_START(TTL_7427_NOR, 3, 1, "+A,+B,+C") TT_HEAD("A,B,C|Q ") TT_LINE("1,X,X|0|15") TT_LINE("X,1,X|0|15") @@ -758,7 +758,7 @@ NETLIST_START(TTL74XX_lib) TT_FAMILY("74XX") TRUTHTABLE_END() - TRUTHTABLE_START(TTL_7430_NAND, 8, 1, "A,B,C,D,E,F,G,H") + TRUTHTABLE_START(TTL_7430_NAND, 8, 1, "+A,+B,+C,+D,+E,+F,+G,+H") TT_HEAD("A,B,C,D,E,F,G,H|Q ") TT_LINE("0,X,X,X,X,X,X,X|1|22") TT_LINE("X,0,X,X,X,X,X,X|1|22") @@ -780,7 +780,7 @@ NETLIST_START(TTL74XX_lib) TT_FAMILY("74XX") TRUTHTABLE_END() - TRUTHTABLE_START(TTL_7432_OR, 2, 1, "A,B") + TRUTHTABLE_START(TTL_7432_OR, 2, 1, "+A,+B") TT_HEAD("A,B|Q ") TT_LINE("1,X|1|22") TT_LINE("X,1|1|22") @@ -800,7 +800,7 @@ NETLIST_START(TTL74XX_lib) TT_FAMILY("74XX") TRUTHTABLE_END() - TRUTHTABLE_START(TTL_7437_NAND, 2, 1, "A,B") + TRUTHTABLE_START(TTL_7437_NAND, 2, 1, "+A,+B") TT_HEAD("A,B|Q ") TT_LINE("0,X|1|22") TT_LINE("X,0|1|22") @@ -817,7 +817,7 @@ NETLIST_START(TTL74XX_lib) TT_FAMILY("74XX") TRUTHTABLE_END() - TRUTHTABLE_START(TTL_7486_XOR, 2, 1, "A,B") + TRUTHTABLE_START(TTL_7486_XOR, 2, 1, "+A,+B") TT_HEAD("A,B|Q ") TT_LINE("0,0|0|15") TT_LINE("0,1|1|22") @@ -837,7 +837,7 @@ NETLIST_START(TTL74XX_lib) TT_FAMILY("74XX") TRUTHTABLE_END() - TRUTHTABLE_START(TTL_74260_NOR, 5, 1, "A,B,C,D,E") + TRUTHTABLE_START(TTL_74260_NOR, 5, 1, "+A,+B,+C,+D,+E") TT_HEAD("A,B,C,D,E|Q ") TT_LINE("0,0,0,0,0|1|10") TT_LINE("X,X,X,X,1|0|12") diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp index 76ce59db5ac..aa6cfc5b340 100644 --- a/src/lib/netlist/nl_base.cpp +++ b/src/lib/netlist/nl_base.cpp @@ -71,6 +71,10 @@ public: { return plib::owned_ptr<devices::nld_base_d_to_a_proxy>::Create<devices::nld_d_to_a_proxy>(anetlist, name, proxied); } + virtual plib::owned_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *proxied) const override + { + return plib::owned_ptr<devices::nld_base_a_to_d_proxy>::Create<devices::nld_a_to_d_proxy>(anetlist, name, proxied); + } }; class logic_family_cd4xxx_t : public logic_family_desc_t @@ -91,6 +95,10 @@ public: { return plib::owned_ptr<devices::nld_base_d_to_a_proxy>::Create<devices::nld_d_to_a_proxy>(anetlist, name, proxied); } + virtual plib::owned_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *proxied) const override + { + return plib::owned_ptr<devices::nld_base_a_to_d_proxy>::Create<devices::nld_a_to_d_proxy>(anetlist, name, proxied); + } }; const logic_family_desc_t *family_TTL() @@ -138,7 +146,7 @@ void detail::queue_t::on_pre_save() pstring p = this->listptr()[i].m_object->name(); std::size_t n = p.len(); if (n > 63) n = 63; - std::strncpy(m_names[i].m_buf, p.cstr(), n); + std::strncpy(m_names[i].m_buf, p.c_str(), n); m_names[i].m_buf[n] = 0; } } @@ -722,8 +730,12 @@ void detail::net_t::reset() m_active++; } -void detail::net_t::register_con(detail::core_terminal_t &terminal) +void detail::net_t::add_terminal(detail::core_terminal_t &terminal) { + for (auto t : m_core_terms) + if (t == &terminal) + netlist().log().fatal("net {1}: duplicate terminal {2}", name(), t->name()); + terminal.set_net(this); m_core_terms.push_back(&terminal); @@ -735,7 +747,7 @@ void detail::net_t::register_con(detail::core_terminal_t &terminal) void detail::net_t::move_connections(detail::net_t &dest_net) { for (auto &ct : m_core_terms) - dest_net.register_con(*ct); + dest_net.add_terminal(*ct); m_core_terms.clear(); m_active = 0; } diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index f72665c62bc..045f7c9b1cb 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -169,6 +169,7 @@ namespace netlist class NETLIB_NAME(netlistparams); class NETLIB_NAME(base_proxy); class NETLIB_NAME(base_d_to_a_proxy); + class NETLIB_NAME(base_a_to_d_proxy); } namespace detail { @@ -203,6 +204,7 @@ namespace netlist }; class logic_output_t; + class logic_input_t; class analog_net_t; class logic_net_t; class net_t; @@ -225,8 +227,11 @@ namespace netlist public: logic_family_desc_t() {} virtual ~logic_family_desc_t() {} + virtual plib::owned_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_t &anetlist, const pstring &name, logic_output_t *proxied) const = 0; + virtual plib::owned_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_t &anetlist, const pstring &name, + logic_input_t *proxied) const = 0; double fixed_V() const { return m_fixed_V; } double low_thresh_V(const double VN, const double VP) const { return VN + (VP - VN) * m_low_thresh_PCNT; } @@ -297,9 +302,9 @@ namespace netlist const T &value //!< Initial value after construction ); //! Copy Constructor. - state_var(const state_var &rhs) noexcept = default; + state_var(const state_var &rhs) NL_NOEXCEPT = default; //! Move Constructor. - state_var(state_var &&rhs) noexcept = default; + state_var(state_var &&rhs) NL_NOEXCEPT = default; //! Assignment operator to assign value of a state var. state_var &operator=(state_var rhs) { std::swap(rhs.m_value, this->m_value); return *this; } //! Assignment operator to assign value of type T. @@ -327,8 +332,8 @@ namespace netlist { public: state_var(device_t &dev, const pstring name, const T & value); - state_var(const state_var &rhs) noexcept = default; - state_var(state_var &&rhs) noexcept = default; + state_var(const state_var &rhs) NL_NOEXCEPT = default; + state_var(state_var &&rhs) NL_NOEXCEPT = default; state_var &operator=(const state_var rhs) { m_value = rhs.m_value; return *this; } state_var &operator=(const T rhs) { m_value = rhs; return *this; } T & operator[](const std::size_t i) { return m_value[i]; } @@ -491,8 +496,8 @@ namespace netlist const net_t & net() const { return *m_net;} net_t & net() { return *m_net;} - bool is_logic() const noexcept; - bool is_analog() const noexcept; + bool is_logic() const NL_NOEXCEPT; + bool is_analog() const NL_NOEXCEPT; bool is_state(const state_e astate) const { return (m_state == astate); } state_e state() const { return m_state; } @@ -519,8 +524,8 @@ namespace netlist { } - const analog_net_t & net() const noexcept; - analog_net_t & net() noexcept; + const analog_net_t & net() const NL_NOEXCEPT; + analog_net_t & net() NL_NOEXCEPT; }; // ----------------------------------------------------------------------------- @@ -604,8 +609,8 @@ namespace netlist devices::nld_base_proxy *get_proxy() const { return m_proxy; } void set_proxy(devices::nld_base_proxy *proxy) { m_proxy = proxy; } - logic_net_t & net() noexcept; - const logic_net_t & net() const noexcept; + logic_net_t & net() NL_NOEXCEPT; + const logic_net_t & net() const NL_NOEXCEPT; protected: @@ -622,7 +627,7 @@ namespace netlist public: logic_input_t(core_device_t &dev, const pstring &aname); - netlist_sig_t Q() const noexcept; + netlist_sig_t Q() const NL_NOEXCEPT; netlist_sig_t operator()() const NL_NOEXCEPT { @@ -662,7 +667,7 @@ namespace netlist /*! returns voltage at terminal. * \returns voltage at terminal. */ - nl_double Q_Analog() const noexcept; + nl_double Q_Analog() const NL_NOEXCEPT; }; @@ -682,16 +687,16 @@ namespace netlist void reset(); - void register_con(core_terminal_t &terminal); + void add_terminal(core_terminal_t &terminal); - bool is_logic() const noexcept; - bool is_analog() const noexcept; + bool is_logic() const NL_NOEXCEPT; + bool is_analog() const NL_NOEXCEPT; void toggle_new_Q() { m_new_Q ^= 1; } void force_queue_execution() { m_new_Q = (m_cur_Q ^ 1); } - void push_to_queue(const netlist_time delay) noexcept; - void reschedule_in_queue(const netlist_time delay) noexcept; + void push_to_queue(const netlist_time delay) NL_NOEXCEPT; + void reschedule_in_queue(const netlist_time delay) NL_NOEXCEPT; bool is_queued() const { return m_in_queue == 1; } void update_devs() NL_NOEXCEPT; @@ -702,7 +707,7 @@ namespace netlist bool isRailNet() const { return !(m_railterminal == nullptr); } core_terminal_t & railterminal() const { return *m_railterminal; } - std::size_t num_cons() const noexcept { return m_core_terms.size(); } + std::size_t num_cons() const NL_NOEXCEPT { return m_core_terms.size(); } void inc_active(core_terminal_t &term) NL_NOEXCEPT; void dec_active(core_terminal_t &term) NL_NOEXCEPT; @@ -742,7 +747,7 @@ namespace netlist netlist_sig_t new_Q() const { return m_new_Q; } void initial(const netlist_sig_t val) { m_cur_Q = m_new_Q = val; } - void set_Q(const netlist_sig_t newQ, const netlist_time delay) noexcept + void set_Q(const netlist_sig_t newQ, const netlist_time delay) NL_NOEXCEPT { if (newQ != m_new_Q) { @@ -751,7 +756,7 @@ namespace netlist } } - void set_Q_time(const netlist_sig_t newQ, const netlist_time at) noexcept + void set_Q_time(const netlist_sig_t newQ, const netlist_time at) NL_NOEXCEPT { if (newQ != m_new_Q) { @@ -806,7 +811,7 @@ namespace netlist void initial(const netlist_sig_t val); - void push(const netlist_sig_t newQ, const netlist_time delay) noexcept + void push(const netlist_sig_t newQ, const netlist_time delay) NL_NOEXCEPT { m_my_net.set_Q(newQ, delay); // take the shortcut } @@ -821,11 +826,11 @@ namespace netlist public: analog_output_t(core_device_t &dev, const pstring &aname); - void push(const nl_double val) noexcept { set_Q(val); } + void push(const nl_double val) NL_NOEXCEPT { set_Q(val); } void initial(const nl_double val); private: - void set_Q(const nl_double newQ) noexcept; + void set_Q(const nl_double newQ) NL_NOEXCEPT; analog_net_t m_my_net; }; @@ -955,28 +960,6 @@ namespace netlist virtual void changed() override { } }; - template <typename ST, std::size_t AW, std::size_t DW> - class param_rom_t final: public param_data_t - { - public: - - param_rom_t(device_t &device, const pstring name) - : param_data_t(device, name) - { - stream()->read(&m_data[0],1<<AW); - } - - const ST & operator[] (std::size_t n) { return m_data[n]; } - - protected: - virtual void changed() override - { - stream()->read(&m_data[0],1<<AW); - } - private: - ST m_data[1 << AW]; - }; - // ----------------------------------------------------------------------------- // core_device_t // ----------------------------------------------------------------------------- @@ -1014,7 +997,7 @@ namespace netlist void set_delegate_pointer(); void stop_dev(); - void do_inc_active() noexcept + void do_inc_active() NL_NOEXCEPT { if (m_hint_deactivate) { @@ -1023,7 +1006,7 @@ namespace netlist } } - void do_dec_active() noexcept + void do_dec_active() NL_NOEXCEPT { if (m_hint_deactivate) dec_active(); @@ -1039,8 +1022,8 @@ namespace netlist protected: virtual void update() NL_NOEXCEPT { } - virtual void inc_active() noexcept { } - virtual void dec_active() noexcept { } + virtual void inc_active() NL_NOEXCEPT { } + virtual void dec_active() NL_NOEXCEPT { } virtual void stop() { } virtual void reset() { } @@ -1177,7 +1160,7 @@ namespace netlist devices::NETLIB_NAME(gnd) *gnd() const { return m_gnd; } nl_double gmin() const; - void push_to_queue(detail::net_t &out, const netlist_time attime) noexcept; + void push_to_queue(detail::net_t &out, const netlist_time attime) NL_NOEXCEPT; void remove_from_queue(detail::net_t &out) NL_NOEXCEPT; void process_queue(const netlist_time &delta); @@ -1294,25 +1277,55 @@ namespace netlist }; // ----------------------------------------------------------------------------- + // rom parameter + // ----------------------------------------------------------------------------- + + template <typename ST, std::size_t AW, std::size_t DW> + class param_rom_t final: public param_data_t + { + public: + + param_rom_t(device_t &device, const pstring name) + : param_data_t(device, name) + { + auto f = stream(); + if (f != nullptr) + f->read(&m_data[0],1<<AW); + else + device.netlist().log().warning("Rom {1} not found", Value()); + } + + const ST & operator[] (std::size_t n) { return m_data[n]; } + + protected: + virtual void changed() override + { + stream()->read(&m_data[0],1<<AW); + } + private: + ST m_data[1 << AW]; + }; + + // ----------------------------------------------------------------------------- // inline implementations // ----------------------------------------------------------------------------- - inline bool detail::core_terminal_t::is_logic() const noexcept + inline bool detail::core_terminal_t::is_logic() const NL_NOEXCEPT { return dynamic_cast<const logic_t *>(this) != nullptr; } - inline bool detail::core_terminal_t::is_analog() const noexcept + inline bool detail::core_terminal_t::is_analog() const NL_NOEXCEPT { return dynamic_cast<const analog_t *>(this) != nullptr; } - inline bool detail::net_t::is_logic() const noexcept + inline bool detail::net_t::is_logic() const NL_NOEXCEPT { return dynamic_cast<const logic_net_t *>(this) != nullptr; } - inline bool detail::net_t::is_analog() const noexcept + inline bool detail::net_t::is_analog() const NL_NOEXCEPT { return dynamic_cast<const analog_net_t *>(this) != nullptr; } @@ -1353,7 +1366,7 @@ namespace netlist } } - inline void detail::net_t::push_to_queue(const netlist_time delay) noexcept + inline void detail::net_t::push_to_queue(const netlist_time delay) NL_NOEXCEPT { if (!is_queued() && (num_cons() != 0)) { @@ -1366,7 +1379,7 @@ namespace netlist } } - inline void detail::net_t::reschedule_in_queue(const netlist_time delay) noexcept + inline void detail::net_t::reschedule_in_queue(const netlist_time delay) NL_NOEXCEPT { if (is_queued()) netlist().remove_from_queue(*this); @@ -1379,39 +1392,39 @@ namespace netlist } } - inline const analog_net_t & analog_t::net() const noexcept + inline const analog_net_t & analog_t::net() const NL_NOEXCEPT { return static_cast<const analog_net_t &>(core_terminal_t::net()); } - inline analog_net_t & analog_t::net() noexcept + inline analog_net_t & analog_t::net() NL_NOEXCEPT { return static_cast<analog_net_t &>(core_terminal_t::net()); } inline nl_double terminal_t::operator ()() const { return net().Q_Analog(); } - inline logic_net_t & logic_t::net() noexcept + inline logic_net_t & logic_t::net() NL_NOEXCEPT { return *static_cast<logic_net_t *>(&core_terminal_t::net()); } - inline const logic_net_t & logic_t::net() const noexcept + inline const logic_net_t & logic_t::net() const NL_NOEXCEPT { return static_cast<const logic_net_t &>(core_terminal_t::net()); } - inline netlist_sig_t logic_input_t::Q() const noexcept + inline netlist_sig_t logic_input_t::Q() const NL_NOEXCEPT { return net().Q(); } - inline nl_double analog_input_t::Q_Analog() const noexcept + inline nl_double analog_input_t::Q_Analog() const NL_NOEXCEPT { return net().Q_Analog(); } - inline void analog_output_t::set_Q(const nl_double newQ) noexcept + inline void analog_output_t::set_Q(const nl_double newQ) NL_NOEXCEPT { if (newQ != net().Q_Analog()) { @@ -1421,7 +1434,7 @@ namespace netlist } } - inline void netlist_t::push_to_queue(detail::net_t &out, const netlist_time attime) noexcept + inline void netlist_t::push_to_queue(detail::net_t &out, const netlist_time attime) NL_NOEXCEPT { m_queue.push(attime, &out); } diff --git a/src/lib/netlist/nl_config.h b/src/lib/netlist/nl_config.h index 14598d2dccf..3181e486dde 100644 --- a/src/lib/netlist/nl_config.h +++ b/src/lib/netlist/nl_config.h @@ -51,7 +51,7 @@ */ // This will be autodetected -//#define NL_PMF_TYPE 0 +// #define NL_PMF_TYPE 0 #define NL_PMF_TYPE_VIRTUAL 0 #define NL_PMF_TYPE_GNUC_PMF 1 @@ -82,16 +82,16 @@ * linear memory pool. This is based of the assumption that * due to enhanced locality there will be less cache misses. * Your mileage may vary. + * This will cause crashes on OSX and thus is ignored on OSX. * */ -#define USE_MEMPOOL (1) +#define USE_MEMPOOL (0) #define USE_TRUTHTABLE (1) //============================================================ // Solver defines //============================================================ -#define USE_MATRIX_GS (0) #define USE_GABS (1) // savings are eaten up by effort // FIXME: Convert into solver parameter @@ -165,5 +165,9 @@ using nl_double = double; #endif #endif +#ifdef __APPLE__ +#undef USE_MEMPOOL +#define USE_MEMPOOL (0) +#endif #endif /* NLCONFIG_H_ */ diff --git a/src/lib/netlist/nl_factory.cpp b/src/lib/netlist/nl_factory.cpp index f1d3281aa81..1e5a8e11b44 100644 --- a/src/lib/netlist/nl_factory.cpp +++ b/src/lib/netlist/nl_factory.cpp @@ -12,45 +12,28 @@ #include "nl_setup.h" #include "plib/putil.h" -namespace netlist +namespace netlist { namespace factory { // ---------------------------------------------------------------------------------------- // net_device_t_base_factory // ---------------------------------------------------------------------------------------- -const plib::pstring_vector_t base_factory_t::term_param_list() -{ - if (m_def_param.startsWith("+")) - return plib::pstring_vector_t(m_def_param.substr(1), ","); - else - return plib::pstring_vector_t(); -} - -const plib::pstring_vector_t base_factory_t::def_params() -{ - if (m_def_param.startsWith("+") || m_def_param.equals("-")) - return plib::pstring_vector_t(); - else - return plib::pstring_vector_t(m_def_param, ","); -} - - -factory_list_t::factory_list_t( setup_t &setup) +list_t::list_t( setup_t &setup) : m_setup(setup) { } -factory_list_t::~factory_list_t() +list_t::~list_t() { clear(); } -void factory_list_t::error(const pstring &s) +void list_t::error(const pstring &s) { m_setup.log().fatal("{1}", s); } -base_factory_t * factory_list_t::factory_by_name(const pstring &devname) +factory::element_t * list_t::factory_by_name(const pstring &devname) { for (auto & e : *this) { @@ -62,4 +45,21 @@ base_factory_t * factory_list_t::factory_by_name(const pstring &devname) return nullptr; // appease code analysis } +// ----------------------------------------------------------------------------- +// factory_lib_entry_t: factory class to wrap macro based chips/elements +// ----------------------------------------------------------------------------- + +plib::owned_ptr<device_t> library_element_t::Create(netlist_t &anetlist, const pstring &name) +{ + return plib::owned_ptr<device_t>::Create<wrapper>(anetlist, name); } + +void library_element_t::macro_actions(netlist_t &anetlist, const pstring &name) +{ + anetlist.setup().namespace_push(name); + anetlist.setup().include(this->name()); + anetlist.setup().namespace_pop(); +} + + +} } diff --git a/src/lib/netlist/nl_factory.h b/src/lib/netlist/nl_factory.h index 6a53797d0d8..b7750751e06 100644 --- a/src/lib/netlist/nl_factory.h +++ b/src/lib/netlist/nl_factory.h @@ -17,32 +17,31 @@ #include "plib/putil.h" #include "nl_base.h" -#define NETLIB_DEVICE_IMPL(chip) factory_creator_ptr_t decl_ ## chip = factory_creator_t< NETLIB_NAME(chip) >; +#define NETLIB_DEVICE_IMPL(chip) factory::constructor_ptr_t decl_ ## chip = factory::constructor_t< NETLIB_NAME(chip) >; -namespace netlist +namespace netlist { namespace factory { // ----------------------------------------------------------------------------- // net_dev class factory // ----------------------------------------------------------------------------- - class base_factory_t + class element_t { - P_PREVENT_COPYING(base_factory_t) + P_PREVENT_COPYING(element_t) public: - base_factory_t(const pstring &name, const pstring &classname, + element_t(const pstring &name, const pstring &classname, const pstring &def_param) : m_name(name), m_classname(classname), m_def_param(def_param) {} - virtual ~base_factory_t() {} + virtual ~element_t() {} virtual plib::owned_ptr<device_t> Create(netlist_t &anetlist, const pstring &name) = 0; + virtual void macro_actions(netlist_t &anetlist, const pstring &name) {}; const pstring &name() const { return m_name; } const pstring &classname() const { return m_classname; } const pstring ¶m_desc() const { return m_def_param; } - const plib::pstring_vector_t term_param_list(); - const plib::pstring_vector_t def_params(); protected: pstring m_name; /* device name */ @@ -51,13 +50,13 @@ namespace netlist }; template <class C> - class factory_t : public base_factory_t + class device_element_t : public element_t { - P_PREVENT_COPYING(factory_t) + P_PREVENT_COPYING(device_element_t) public: - factory_t(const pstring &name, const pstring &classname, + device_element_t(const pstring &name, const pstring &classname, const pstring &def_param) - : base_factory_t(name, classname, def_param) { } + : element_t(name, classname, def_param) { } plib::owned_ptr<device_t> Create(netlist_t &anetlist, const pstring &name) override { @@ -65,20 +64,20 @@ namespace netlist } }; - class factory_list_t : public std::vector<std::unique_ptr<base_factory_t>> + class list_t : public std::vector<std::unique_ptr<element_t>> { public: - factory_list_t(setup_t &m_setup); - ~factory_list_t(); + list_t(setup_t &m_setup); + ~list_t(); template<class device_class> void register_device(const pstring &name, const pstring &classname, const pstring &def_param) { - register_device(std::unique_ptr<base_factory_t>(new factory_t<device_class>(name, classname, def_param))); + register_device(std::unique_ptr<element_t>(new device_element_t<device_class>(name, classname, def_param))); } - void register_device(std::unique_ptr<base_factory_t> factory) + void register_device(std::unique_ptr<element_t> factory) { for (auto & e : *this) if (e->name() == factory->name()) @@ -86,12 +85,12 @@ namespace netlist push_back(std::move(factory)); } - base_factory_t * factory_by_name(const pstring &devname); + element_t * factory_by_name(const pstring &devname); template <class C> - bool is_class(base_factory_t *f) + bool is_class(element_t *f) { - return dynamic_cast<factory_t<C> *>(f) != nullptr; + return dynamic_cast<device_element_t<C> *>(f) != nullptr; } private: @@ -104,16 +103,49 @@ namespace netlist // factory_creator_ptr_t // ----------------------------------------------------------------------------- - using factory_creator_ptr_t = std::unique_ptr<base_factory_t> (*)(const pstring &name, const pstring &classname, + using constructor_ptr_t = std::unique_ptr<element_t> (*)(const pstring &name, const pstring &classname, const pstring &def_param); template <typename T> - std::unique_ptr<base_factory_t> factory_creator_t(const pstring &name, const pstring &classname, + std::unique_ptr<element_t> constructor_t(const pstring &name, const pstring &classname, const pstring &def_param) { - return std::unique_ptr<base_factory_t>(new factory_t<T>(name, classname, def_param)); + return std::unique_ptr<element_t>(new device_element_t<T>(name, classname, def_param)); } -} + // ----------------------------------------------------------------------------- + // factory_lib_entry_t: factory class to wrap macro based chips/elements + // ----------------------------------------------------------------------------- + + class library_element_t : public element_t + { + P_PREVENT_COPYING(library_element_t) + public: + + library_element_t(setup_t &setup, const pstring &name, const pstring &classname, + const pstring &def_param) + : element_t(name, classname, def_param), m_setup(setup) { } + + class wrapper : public device_t + { + public: + wrapper(netlist_t &anetlist, const pstring &name) + : device_t(anetlist, name) + { + } + protected: + NETLIB_RESETI() { } + NETLIB_UPDATEI() { } + }; + + plib::owned_ptr<device_t> Create(netlist_t &anetlist, const pstring &name) override; + + void macro_actions(netlist_t &anetlist, const pstring &name) override; + + private: + setup_t &m_setup; + }; + +} } #endif /* NLFACTORY_H_ */ diff --git a/src/lib/netlist/nl_parser.cpp b/src/lib/netlist/nl_parser.cpp index 6760873a4af..b2588faaaa8 100644 --- a/src/lib/netlist/nl_parser.cpp +++ b/src/lib/netlist/nl_parser.cpp @@ -316,7 +316,7 @@ void parser_t::dippins() error(plib::pfmt("expected a comma, found <{1}>")(n.str()) ); } if ((pins.size() % 2) == 1) - error("You must pass an equal number of pins to DIPPINS"); + error(plib::pfmt("You must pass an equal number of pins to DIPPINS, first pin is {}")(pins[0])); std::size_t n = pins.size(); for (std::size_t i = 0; i < n / 2; i++) { @@ -356,35 +356,29 @@ void parser_t::netdev_hint() void parser_t::device(const pstring &dev_type) { - if (m_setup.is_library_item(dev_type)) - { - pstring devname = get_identifier(); - m_setup.namespace_push(devname); - m_setup.include(dev_type); - m_setup.namespace_pop(); - require_token(m_tok_param_right); - } - else - { - base_factory_t *f = m_setup.factory().factory_by_name(dev_type); - plib::pstring_vector_t termlist = f->term_param_list(); - plib::pstring_vector_t def_params = f->def_params(); + factory::element_t *f = m_setup.factory().factory_by_name(dev_type); + auto paramlist = plib::pstring_vector_t(f->param_desc(), ","); - std::size_t cnt; + pstring devname = get_identifier(); - pstring devname = get_identifier(); + m_setup.register_dev(dev_type, m_setup.build_fqn(devname)); + m_setup.log().debug("Parser: IC: {1}\n", devname); - m_setup.register_dev(dev_type, m_setup.build_fqn(devname)); - - m_setup.log().debug("Parser: IC: {1}\n", devname); + for (pstring tp : paramlist) + { + require_token(m_tok_comma); + if (tp.startsWith("+")) + { + pstring output_name = get_identifier(); + m_setup.log().debug("Link: {1} {2}\n", tp, output_name); - cnt = 0; - while (cnt < def_params.size()) + m_setup.register_link(devname + "." + tp.substr(1), output_name); + } + else { - pstring paramfq = devname + "." + def_params[cnt]; + pstring paramfq = devname + "." + tp; m_setup.log().debug("Defparam: {1}\n", paramfq); - require_token(m_tok_comma); token_t tok = get_token(); if (tok.is_type(STRING)) { @@ -395,24 +389,11 @@ void parser_t::device(const pstring &dev_type) nl_double val = eval_param(tok); m_setup.register_param(paramfq, val); } - cnt++; } - - token_t tok = get_token(); - cnt = 0; - while (tok.is(m_tok_comma) && cnt < termlist.size()) - { - pstring output_name = get_identifier(); - - m_setup.register_link(devname + "." + termlist[cnt], output_name); - - cnt++; - tok = get_token(); - } - if (cnt != termlist.size()) - error(plib::pfmt("Input count mismatch for {1} - expected {2} found {3}")(devname)(termlist.size())(cnt)); - require_token(tok, m_tok_param_right); } + + // error(plib::pfmt("Input count mismatch for {1} - expected {2} found {3}")(devname)(termlist.size())(cnt)); + require_token(m_tok_param_right); } diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp index 06cef2a0947..5c68449f6c4 100644 --- a/src/lib/netlist/nl_setup.cpp +++ b/src/lib/netlist/nl_setup.cpp @@ -103,27 +103,17 @@ void setup_t::namespace_pop() void setup_t::register_lib_entry(const pstring &name) { - if (plib::container::contains(m_lib, name)) - log().warning("Lib entry collection already contains {1}. IGNORED", name); - else - m_lib.push_back(name); + factory().register_device(plib::make_unique_base<factory::element_t, factory::library_element_t>(*this, name, name, "")); } void setup_t::register_dev(const pstring &classname, const pstring &name) { - if (plib::container::contains(m_lib, classname)) - { - namespace_push(name); - include(classname); - namespace_pop(); - } - else - { - auto f = factory().factory_by_name(classname); - if (f == nullptr) - log().fatal("Class {1} not found!\n", classname); - m_device_factory.push_back(std::pair<pstring, base_factory_t *>(build_fqn(name), f)); - } + auto f = factory().factory_by_name(classname); + if (f == nullptr) + log().fatal("Class {1} not found!\n", classname); + /* make sure we parse macro library entries */ + f->macro_actions(netlist(), build_fqn(name)); + m_device_factory.push_back(std::pair<pstring, factory::element_t *>(build_fqn(name), f)); } bool setup_t::device_exists(const pstring name) const @@ -165,7 +155,7 @@ void setup_t::register_dippins_arr(const pstring &terms) { plib::pstring_vector_t list(terms,", "); if (list.size() == 0 || (list.size() % 2) == 1) - log().fatal("You must pass an equal number of pins to DIPPINS"); + log().fatal("You must pass an equal number of pins to DIPPINS {1}" , build_fqn("")); std::size_t n = list.size(); for (std::size_t i = 0; i < n / 2; i++) { @@ -207,7 +197,7 @@ double setup_t::get_initial_param_val(const pstring name, const double def) if (i != m_param_values.end()) { double vald = 0; - if (sscanf(i->second.cstr(), "%lf", &vald) != 1) + if (sscanf(i->second.c_str(), "%lf", &vald) != 1) log().fatal("Invalid number conversion {1} : {2}\n", name, i->second); return vald; } @@ -221,7 +211,7 @@ int setup_t::get_initial_param_val(const pstring name, const int def) if (i != m_param_values.end()) { double vald = 0; - if (sscanf(i->second.cstr(), "%lf", &vald) != 1) + if (sscanf(i->second.c_str(), "%lf", &vald) != 1) log().fatal("Invalid number conversion {1} : {2}\n", name, i->second); return static_cast<int>(vald); } @@ -349,7 +339,7 @@ const pstring setup_t::resolve_alias(const pstring &name) const ret = temp; auto p = m_alias.find(ret); temp = (p != m_alias.end() ? p->second : ""); - } while (temp != ""); + } while (temp != "" && temp != ret); log().debug("{1}==>{2}\n", name, ret); return ret; @@ -445,7 +435,7 @@ devices::nld_base_proxy *setup_t::get_d_a_proxy(detail::core_terminal_t &out) } out.net().m_core_terms.clear(); // clear the list - out.net().register_con(new_proxy->in()); + out.net().add_terminal(new_proxy->in()); out_cast.set_proxy(proxy); proxy = new_proxy.get(); @@ -455,6 +445,52 @@ devices::nld_base_proxy *setup_t::get_d_a_proxy(detail::core_terminal_t &out) return proxy; } +devices::nld_base_proxy *setup_t::get_a_d_proxy(detail::core_terminal_t &inp) +{ + nl_assert(inp.is_analog()); + + logic_input_t &incast = dynamic_cast<logic_input_t &>(inp); + devices::nld_base_proxy *proxy = incast.get_proxy(); + + if (proxy != nullptr) + return proxy; + else + { + log().debug("connect_terminal_input: connecting proxy\n"); + pstring x = plib::pfmt("proxy_ad_{1}_{2}")(inp.name())(m_proxy_cnt); + auto new_proxy = incast.logic_family()->create_a_d_proxy(netlist(), x, &incast); + //auto new_proxy = plib::owned_ptr<devices::nld_a_to_d_proxy>::Create(netlist(), x, &incast); + incast.set_proxy(new_proxy.get()); + m_proxy_cnt++; + + auto ret = new_proxy.get(); + +#if 1 + /* connect all existing terminals to new net */ + + if (inp.has_net()) + { + for (auto & p : inp.net().m_core_terms) + { + p->clear_net(); // de-link from all nets ... + if (!connect(ret->proxy_term(), *p)) + log().fatal("Error connecting {1} to {2}\n", ret->proxy_term().name(), (*p).name()); + } + inp.net().m_core_terms.clear(); // clear the list + } + ret->out().net().add_terminal(inp); +#else + if (inp.has_net()) + //fatalerror("logic inputs can only belong to one net!\n"); + merge_nets(ret->out().net(), inp.net()); + else + ret->out().net().add_terminal(inp); +#endif + netlist().register_dev(std::move(new_proxy)); + return ret; + } +} + void setup_t::merge_nets(detail::net_t &thisnet, detail::net_t &othernet) { netlist().log().debug("merging nets ...\n"); @@ -484,17 +520,16 @@ void setup_t::connect_input_output(detail::core_terminal_t &in, detail::core_ter { if (out.is_analog() && in.is_logic()) { +#if 0 logic_input_t &incast = dynamic_cast<logic_input_t &>(in); pstring x = plib::pfmt("proxy_ad_{1}_{2}")(in.name())( m_proxy_cnt); auto proxy = plib::owned_ptr<devices::nld_a_to_d_proxy>::Create(netlist(), x, &incast); incast.set_proxy(proxy.get()); m_proxy_cnt++; +#endif + auto proxy = get_a_d_proxy(in); - proxy->m_Q.net().register_con(in); - out.net().register_con(proxy->m_I); - - netlist().register_dev(std::move(proxy)); - + out.net().add_terminal(proxy->proxy_term()); } else if (out.is_logic() && in.is_analog()) { @@ -508,7 +543,7 @@ void setup_t::connect_input_output(detail::core_terminal_t &in, detail::core_ter if (in.has_net()) merge_nets(out.net(), in.net()); else - out.net().register_con(in); + out.net().add_terminal(in); } } @@ -522,22 +557,19 @@ void setup_t::connect_terminal_input(terminal_t &term, detail::core_terminal_t & else if (inp.is_logic()) { netlist().log().verbose("connect terminal {1} (in, {2}) to {3}\n", inp.name(), pstring(inp.is_analog() ? "analog" : inp.is_logic() ? "logic" : "?"), term.name()); +#if 0 logic_input_t &incast = dynamic_cast<logic_input_t &>(inp); log().debug("connect_terminal_input: connecting proxy\n"); pstring x = plib::pfmt("proxy_ad_{1}_{2}")(inp.name())(m_proxy_cnt); auto proxy = plib::owned_ptr<devices::nld_a_to_d_proxy>::Create(netlist(), x, &incast); incast.set_proxy(proxy.get()); m_proxy_cnt++; +#endif + auto proxy = get_a_d_proxy(inp); - connect_terminals(term, proxy->m_I); + //out.net().register_con(proxy->proxy_term()); + connect_terminals(term, proxy->proxy_term()); - if (inp.has_net()) - //fatalerror("logic inputs can only belong to one net!\n"); - merge_nets(proxy->m_Q.net(), inp.net()); - else - proxy->m_Q.net().register_con(inp); - - netlist().register_dev(std::move(proxy)); } else { @@ -554,7 +586,7 @@ void setup_t::connect_terminal_output(terminal_t &in, detail::core_terminal_t &o if (in.has_net()) merge_nets(out.net(), in.net()); else - out.net().register_con(in); + out.net().add_terminal(in); } else if (out.is_logic()) { @@ -579,12 +611,12 @@ void setup_t::connect_terminals(detail::core_terminal_t &t1, detail::core_termin else if (t2.has_net()) { log().debug("T2 has net\n"); - t2.net().register_con(t1); + t2.net().add_terminal(t1); } else if (t1.has_net()) { log().debug("T1 has net\n"); - t1.net().register_con(t2); + t1.net().add_terminal(t2); } else { @@ -592,8 +624,8 @@ void setup_t::connect_terminals(detail::core_terminal_t &t1, detail::core_termin // FIXME: Nets should have a unique name auto anet = plib::palloc<analog_net_t>(netlist(),"net." + t1.name()); t1.set_net(anet); - anet->register_con(t2); - anet->register_con(t1); + anet->add_terminal(t2); + anet->add_terminal(t1); } } @@ -836,6 +868,10 @@ public: { return plib::owned_ptr<devices::nld_base_d_to_a_proxy>::Create<devices::nld_d_to_a_proxy>(anetlist, name, proxied); } + virtual plib::owned_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *proxied) const override + { + return plib::owned_ptr<devices::nld_base_a_to_d_proxy>::Create<devices::nld_a_to_d_proxy>(anetlist, name, proxied); + } }; const logic_family_desc_t *setup_t::family_from_model(const pstring &model) @@ -994,7 +1030,8 @@ std::unique_ptr<plib::pistream> setup_t::get_data_stream(const pstring name) return strm; } } - log().fatal("unable to find data named {1} in source collection", name); + //log().fatal("unable to find data named {1} in source collection", name); + log().warning("unable to find data named {1} in source collection", name); return std::unique_ptr<plib::pistream>(nullptr); } @@ -1030,12 +1067,12 @@ bool source_t::parse(const pstring &name) std::unique_ptr<plib::pistream> source_string_t::stream(const pstring &name) { - return plib::make_unique_base<plib::pistream, plib::pimemstream>(m_str.cstr(), m_str.len()); + return plib::make_unique_base<plib::pistream, plib::pimemstream>(m_str.c_str(), m_str.len()); } std::unique_ptr<plib::pistream> source_mem_t::stream(const pstring &name) { - return plib::make_unique_base<plib::pistream, plib::pimemstream>(m_str.cstr(), m_str.len()); + return plib::make_unique_base<plib::pistream, plib::pimemstream>(m_str.c_str(), m_str.len()); } std::unique_ptr<plib::pistream> source_file_t::stream(const pstring &name) diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h index e560a3b9f79..1edc3b50781 100644 --- a/src/lib/netlist/nl_setup.h +++ b/src/lib/netlist/nl_setup.h @@ -92,7 +92,7 @@ void NETLIST_NAME(name)(netlist::setup_t &setup) \ desc.classname = #cname ; \ desc.ni = in; \ desc.no = out; \ - desc.def_param = pstring("+") + def_params; \ + desc.def_param = def_params; \ desc.family = ""; #define TT_HEAD(x) \ @@ -252,10 +252,8 @@ namespace netlist void register_define(pstring def, pstring val) { m_defines.push_back(plib::ppreprocessor::define_t(def, val)); } void register_define(pstring defstr); - factory_list_t &factory() { return m_factory; } - const factory_list_t &factory() const { return m_factory; } - - bool is_library_item(const pstring &name) const { return plib::container::contains(m_lib, name); } + factory::list_t &factory() { return m_factory; } + const factory::list_t &factory() const { return m_factory; } /* model / family related */ @@ -275,7 +273,7 @@ namespace netlist plib::plog_base<NL_DEBUG> &log(); const plib::plog_base<NL_DEBUG> &log() const; - std::vector<std::pair<pstring, base_factory_t *>> m_device_factory; + std::vector<std::pair<pstring, factory::element_t *>> m_device_factory; std::unordered_map<pstring, pstring> m_alias; std::unordered_map<pstring, pstring> m_param_values; @@ -300,17 +298,17 @@ namespace netlist pstring objtype_as_str(detail::device_object_t &in) const; devices::nld_base_proxy *get_d_a_proxy(detail::core_terminal_t &out); + devices::nld_base_proxy *get_a_d_proxy(detail::core_terminal_t &inp); netlist_t &m_netlist; std::unordered_map<pstring, param_ref_t> m_params; std::vector<link_t> m_links; - factory_list_t m_factory; + factory::list_t m_factory; std::unordered_map<pstring, pstring> m_models; std::stack<pstring> m_namespace_stack; source_t::list_t m_sources; std::vector<plib::ppreprocessor::define_t> m_defines; - std::vector<pstring> m_lib; unsigned m_proxy_cnt; unsigned m_frontier_cnt; diff --git a/src/lib/netlist/plib/pdynlib.cpp b/src/lib/netlist/plib/pdynlib.cpp index 0ed2ca3a620..92f79f27702 100644 --- a/src/lib/netlist/plib/pdynlib.cpp +++ b/src/lib/netlist/plib/pdynlib.cpp @@ -62,8 +62,8 @@ dynlib::dynlib(const pstring libname) : m_isLoaded(false), m_lib(nullptr) { #ifdef _WIN32 - //fprintf(stderr, "win: loading <%s>\n", libname.cstr()); - TCHAR *buffer = tstring_from_utf8(libname.cstr()); + //fprintf(stderr, "win: loading <%s>\n", libname.c_str()); + TCHAR *buffer = tstring_from_utf8(libname.c_str()); if (libname != "") m_lib = LoadLibrary(buffer); else @@ -71,27 +71,27 @@ dynlib::dynlib(const pstring libname) if (m_lib != nullptr) m_isLoaded = true; //else - // fprintf(stderr, "win: library <%s> not found!\n", libname.cstr()); + // fprintf(stderr, "win: library <%s> not found!\n", libname.c_str()); pfree_array(buffer); #else - //printf("loading <%s>\n", libname.cstr()); + //printf("loading <%s>\n", libname.c_str()); if (libname != "") - m_lib = dlopen(libname.cstr(), RTLD_LAZY); + m_lib = dlopen(libname.c_str(), RTLD_LAZY); else m_lib = dlopen(nullptr, RTLD_LAZY); if (m_lib != nullptr) m_isLoaded = true; //else - // printf("library <%s> not found: %s\n", libname.cstr(), dlerror()); + // printf("library <%s> not found: %s\n", libname.c_str(), dlerror()); #endif } dynlib::dynlib(const pstring path, const pstring libname) : m_isLoaded(false), m_lib(nullptr) { - // printf("win: loading <%s>\n", libname.cstr()); + // printf("win: loading <%s>\n", libname.c_str()); #ifdef _WIN32 - TCHAR *buffer = tstring_from_utf8(libname.cstr()); + TCHAR *buffer = tstring_from_utf8(libname.c_str()); if (libname != "") m_lib = LoadLibrary(buffer); else @@ -100,20 +100,20 @@ dynlib::dynlib(const pstring path, const pstring libname) m_isLoaded = true; else { - //printf("win: library <%s> not found!\n", libname.cstr()); + //printf("win: library <%s> not found!\n", libname.c_str()); } pfree_array(buffer); #else - //printf("loading <%s>\n", libname.cstr()); + //printf("loading <%s>\n", libname.c_str()); if (libname != "") - m_lib = dlopen(libname.cstr(), RTLD_LAZY); + m_lib = dlopen(libname.c_str(), RTLD_LAZY); else m_lib = dlopen(nullptr, RTLD_LAZY); if (m_lib != nullptr) m_isLoaded = true; else { - //printf("library <%s> not found!\n", libname.cstr()); + //printf("library <%s> not found!\n", libname.c_str()); } #endif } @@ -138,9 +138,9 @@ bool dynlib::isLoaded() const void *dynlib::getsym_p(const pstring name) { #ifdef _WIN32 - return (void *) GetProcAddress((HMODULE) m_lib, name.cstr()); + return (void *) GetProcAddress((HMODULE) m_lib, name.c_str()); #else - return dlsym(m_lib, name.cstr()); + return dlsym(m_lib, name.c_str()); #endif } diff --git a/src/lib/netlist/plib/pfmtlog.cpp b/src/lib/netlist/plib/pfmtlog.cpp index 770a53af49d..73da6822d20 100644 --- a/src/lib/netlist/plib/pfmtlog.cpp +++ b/src/lib/netlist/plib/pfmtlog.cpp @@ -26,7 +26,7 @@ pfmt::pfmt(const pstring &fmt) m_allocated = 2 * l; m_str = palloc_array<char>(2 * l); } - memcpy(m_str, fmt.cstr(), l); + memcpy(m_str, fmt.c_str(), l); } pfmt::pfmt(const char *fmt) diff --git a/src/lib/netlist/plib/pfmtlog.h b/src/lib/netlist/plib/pfmtlog.h index 0e8b7f46946..49f8ae62b44 100644 --- a/src/lib/netlist/plib/pfmtlog.h +++ b/src/lib/netlist/plib/pfmtlog.h @@ -122,7 +122,7 @@ public: P &operator ()(const char *x, const char *f = "") { format_element(f, "", "s", x); return static_cast<P &>(*this); } P &operator ()(char *x, const char *f = "") { format_element(f, "", "s", x); return static_cast<P &>(*this); } P &operator ()(const void *x, const char *f = "") { format_element(f, "", "p", x); return static_cast<P &>(*this); } - P &operator ()(const pstring &x, const char *f = "") { format_element(f, "", "s", x.cstr() ); return static_cast<P &>(*this); } + P &operator ()(const pstring &x, const char *f = "") { format_element(f, "", "s", x.c_str() ); return static_cast<P &>(*this); } template<typename T> P &operator ()(const T x, const char *f = "") diff --git a/src/lib/netlist/plib/pstream.cpp b/src/lib/netlist/plib/pstream.cpp index ad2010213f9..b9895036a12 100644 --- a/src/lib/netlist/plib/pstream.cpp +++ b/src/lib/netlist/plib/pstream.cpp @@ -58,7 +58,7 @@ void postream::write(pistream &strm) pifilestream::pifilestream(const pstring &fname) : pistream(0) -, m_file(fopen(fname.cstr(), "rb")) +, m_file(fopen(fname.c_str(), "rb")) , m_pos(0) , m_actually_close(true) , m_filename(fname) @@ -147,7 +147,7 @@ pstdin::pstdin() // ----------------------------------------------------------------------------- pofilestream::pofilestream(const pstring &fname) -: postream(0), m_file(fopen(fname.cstr(), "wb")), m_pos(0), m_actually_close(true), m_filename(fname) +: postream(0), m_file(fopen(fname.c_str(), "wb")), m_pos(0), m_actually_close(true), m_filename(fname) { if (m_file == nullptr) throw file_open_e(m_filename); diff --git a/src/lib/netlist/plib/pstream.h b/src/lib/netlist/plib/pstream.h index 20aaab83a3a..e400837c3ac 100644 --- a/src/lib/netlist/plib/pstream.h +++ b/src/lib/netlist/plib/pstream.h @@ -126,7 +126,7 @@ public: void write(const pstring &text) { - write(text.cstr(), text.blen()); + write(text.c_str(), text.blen()); } void write(const char c) @@ -325,7 +325,7 @@ class pistringstream : public pimemstream P_PREVENT_COPYING(pistringstream) public: - pistringstream(const pstring &str) : pimemstream(str.cstr(), str.len()), m_str(str) { } + pistringstream(const pstring &str) : pimemstream(str.c_str(), str.len()), m_str(str) { } private: /* only needed for a reference till destruction */ diff --git a/src/lib/netlist/plib/pstring.cpp b/src/lib/netlist/plib/pstring.cpp index d42ef6f4400..2506357c9a5 100644 --- a/src/lib/netlist/plib/pstring.cpp +++ b/src/lib/netlist/plib/pstring.cpp @@ -46,7 +46,7 @@ void pstring_t<F>::pcat(const pstring_t &s) if (m_ptr->len() > 0) std::memcpy(n->str(), m_ptr->str(), m_ptr->len()); if (slen > 0) - std::memcpy(n->str() + m_ptr->len(), s.cstr(), slen); + std::memcpy(n->str() + m_ptr->len(), s.c_str(), slen); *(n->str() + n->len()) = 0; sfree(m_ptr); m_ptr = n; @@ -65,7 +65,7 @@ int pstring_t<F>::pcmp(const pstring_t &right) const else return -1; } - int ret = memcmp(m_ptr->str(), right.cstr(), l); + int ret = memcmp(m_ptr->str(), right.c_str(), l); if (ret == 0) { if (this->blen() > right.blen()) @@ -102,7 +102,7 @@ template<typename F> const pstring_t<F> pstring_t<F>::ucase() const { pstring_t ret = *this; - ret.pcopy(cstr(), blen()); + ret.pcopy(c_str(), blen()); for (std::size_t i=0; i<ret.len(); i++) ret.m_ptr->str()[i] = static_cast<char>(toupper(static_cast<int>(ret.m_ptr->str()[i]))); return ret; @@ -230,7 +230,7 @@ double pstring_t<F>::as_double(bool *error) const if (error != nullptr) *error = false; - ret = strtod(cstr(), &e); + ret = strtod(c_str(), &e); if (*e != 0) if (error != nullptr) *error = true; @@ -246,9 +246,9 @@ long pstring_t<F>::as_long(bool *error) const if (error != nullptr) *error = false; if (startsWith("0x")) - ret = strtol(substr(2).cstr(), &e, 16); + ret = strtol(substr(2).c_str(), &e, 16); else - ret = strtol(cstr(), &e, 10); + ret = strtol(c_str(), &e, 10); if (*e != 0) if (error != nullptr) *error = true; @@ -279,7 +279,7 @@ bool pstring_t<F>::startsWith(const pstring_t &arg) const if (arg.blen() > blen()) return false; else - return (memcmp(arg.cstr(), cstr(), arg.blen()) == 0); + return (memcmp(arg.c_str(), c_str(), arg.blen()) == 0); } template<typename F> @@ -288,7 +288,7 @@ bool pstring_t<F>::endsWith(const pstring_t &arg) const if (arg.blen() > blen()) return false; else - return (memcmp(cstr()+this->blen()-arg.blen(), arg.cstr(), arg.blen()) == 0); + return (memcmp(c_str()+this->blen()-arg.blen(), arg.c_str(), arg.blen()) == 0); } @@ -299,7 +299,7 @@ bool pstring_t<F>::startsWith(const mem_t *arg) const if (alen > blen()) return false; else - return (memcmp(arg, cstr(), alen) == 0); + return (memcmp(arg, c_str(), alen) == 0); } template<typename F> @@ -351,7 +351,7 @@ void pstringbuffer::pcopy(const pstring &from) { std::size_t nl = from.blen() + 1; resize(nl); - std::memcpy(m_ptr, from.cstr(), nl); + std::memcpy(m_ptr, from.c_str(), nl); } void pstringbuffer::pcat(const char *s) @@ -377,7 +377,7 @@ void pstringbuffer::pcat(const pstring &s) const std::size_t slen = s.blen(); const std::size_t nl = m_len + slen + 1; resize(nl); - std::memcpy(m_ptr + m_len, s.cstr(), slen); + std::memcpy(m_ptr + m_len, s.c_str(), slen); m_len += slen; m_ptr[m_len] = 0; } diff --git a/src/lib/netlist/plib/pstring.h b/src/lib/netlist/plib/pstring.h index 17132a5bf31..16bf61b08ee 100644 --- a/src/lib/netlist/plib/pstring.h +++ b/src/lib/netlist/plib/pstring.h @@ -90,7 +90,7 @@ public: iterator end() const { return iterator(m_ptr->str() + blen()); } // C string conversion helpers - const mem_t *cstr() const { return m_ptr->str(); } + const mem_t *c_str() const { return m_ptr->str(); } // concatenation operators pstring_t& operator+=(const pstring_t &string) { pcat(string); return *this; } @@ -356,7 +356,7 @@ public: pstringbuffer &operator=(const pstringbuffer &string) { pcopy(string); return *this; } // C string conversion helpers - const char *cstr() const { return m_ptr; } + const char *c_str() const { return m_ptr; } operator pstring() const { return pstring(m_ptr); } @@ -405,7 +405,7 @@ namespace std typedef std::size_t result_type; result_type operator()(argument_type const& s) const { - const pstring::mem_t *string = s.cstr(); + const pstring::mem_t *string = s.c_str(); result_type result = 5381; for (pstring::mem_t c = *string; c != 0; c = *string++) result = ((result << 5) + result ) ^ (result >> (32 - 5)) ^ static_cast<result_type>(c); diff --git a/src/lib/netlist/plib/ptypes.h b/src/lib/netlist/plib/ptypes.h index 2e2d19994e4..9c477f71944 100644 --- a/src/lib/netlist/plib/ptypes.h +++ b/src/lib/netlist/plib/ptypes.h @@ -57,7 +57,7 @@ namespace plib ename (e v) : m_v(v) { } \ bool set_from_string (const pstring &s) { \ static const char *strings = # __VA_ARGS__; \ - int f = from_string_int(strings, s.cstr()); \ + int f = from_string_int(strings, s.c_str()); \ if (f>=0) { m_v = static_cast<e>(f); return true; } else { return false; } \ } \ operator e() const {return m_v;} \ diff --git a/src/lib/netlist/plib/putil.cpp b/src/lib/netlist/plib/putil.cpp index ad340017bc4..39e1b444f33 100644 --- a/src/lib/netlist/plib/putil.cpp +++ b/src/lib/netlist/plib/putil.cpp @@ -33,10 +33,10 @@ namespace plib const pstring environment(const pstring &var, const pstring &default_val) { - if (getenv(var.cstr()) == nullptr) + if (getenv(var.c_str()) == nullptr) return default_val; else - return pstring(getenv(var.cstr())); + return pstring(getenv(var.c_str())); } } @@ -73,7 +73,7 @@ namespace plib std::size_t p = static_cast<std::size_t>(-1); for (std::size_t j=0; j < onstrl.size(); j++) { - if (std::memcmp(onstrl[j].cstr(), &(str.cstr()[i]), onstrl[j].blen())==0) + if (std::memcmp(onstrl[j].c_str(), &(str.c_str()[i]), onstrl[j].blen())==0) { p = j; break; @@ -90,7 +90,7 @@ namespace plib } else { - pstring::traits::code_t c = pstring::traits::code(str.cstr() + i); + pstring::traits::code_t c = pstring::traits::code(str.c_str() + i); col += c; i+=pstring::traits::codelen(c); } diff --git a/src/lib/netlist/plib/putil.h b/src/lib/netlist/plib/putil.h index cc388cd3393..9e79e958927 100644 --- a/src/lib/netlist/plib/putil.h +++ b/src/lib/netlist/plib/putil.h @@ -45,6 +45,11 @@ namespace plib con.insert(con.begin() + static_cast<std::ptrdiff_t>(index), elem); } + template <class C> + void remove(C &con, const typename C::value_type &elem) + { + con.erase(std::remove(con.begin(), con.end(), elem), con.end()); + } } template <class C> diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp index fbfa3a50c5c..086fe517a2f 100644 --- a/src/lib/netlist/prg/nltool.cpp +++ b/src/lib/netlist/prg/nltool.cpp @@ -181,7 +181,7 @@ protected: void vlog(const plib::plog_level &l, const pstring &ls) const override { - pstring err = plib::pfmt("{}: {}\n")(l.name())(ls.cstr()); + pstring err = plib::pfmt("{}: {}\n")(l.name())(ls.c_str()); pout("{}", err); if (l == plib::plog_level::FATAL) throw netlist::nl_exception(err); @@ -199,7 +199,7 @@ void usage(tool_options_t &opts) { pout("{}\n", opts.help( "nltool serves as the Swiss Army knife to run, test and convert netlists.", - "nltool [options]").cstr()); + "nltool [options]").c_str()); } struct input_t @@ -214,7 +214,7 @@ struct input_t { char buf[400]; double t; - int e = sscanf(line.cstr(), "%lf,%[^,],%lf", &t, buf, &m_value); + int e = sscanf(line.c_str(), "%lf,%[^,],%lf", &t, buf, &m_value); if ( e!= 3) throw netlist::nl_exception(plib::pfmt("error {1} scanning line {2}\n")(e)(line)); m_time = netlist::netlist_time::from_double(t); @@ -346,7 +346,7 @@ static void listdevices(tool_options_t &opts) if (opts.opt_quiet()) nt.log().warning.set_enabled(false); - netlist::factory_list_t &list = nt.setup().factory(); + netlist::factory::list_t &list = nt.setup().factory(); nt.setup().register_source(plib::make_unique_base<netlist::source_t, netlist::source_proc_t>(nt.setup(), "dummy", &netlist_dummy)); @@ -363,6 +363,7 @@ static void listdevices(tool_options_t &opts) pstring out = plib::pfmt("{1} {2}(<id>")(f->classname(),"-20")(f->name()); std::vector<pstring> terms; + f->macro_actions(nt.setup().netlist(), f->name() + "_lc"); auto d = f->Create(nt.setup().netlist(), f->name() + "_lc"); // get the list of terminals ... @@ -381,10 +382,12 @@ static void listdevices(tool_options_t &opts) if (t.first.startsWith(d->name())) { pstring tn(t.first.substr(d->name().len()+1)); + //printf("\t%s %s %s\n", t.first.c_str(), t.second.c_str(), tn.c_str()); if (tn.find(".") == tn.end()) { terms.push_back(tn); pstring resolved = nt.setup().resolve_alias(t.first); + //printf("\t%s %s %s\n", t.first.c_str(), t.second.c_str(), resolved.c_str()); if (resolved != t.first) { auto found = std::find(terms.begin(), terms.end(), resolved.substr(d->name().len()+1)); @@ -395,27 +398,22 @@ static void listdevices(tool_options_t &opts) } } - if (f->param_desc().startsWith("+")) + out += "," + f->param_desc(); + for (auto p : plib::pstring_vector_t(f->param_desc(),",") ) { - out += "," + f->param_desc().substr(1); - terms.clear(); - } - else if (f->param_desc() == "-") - { - /* no params at all */ - } - else - { - out += "," + f->param_desc(); + if (p.startsWith("+")) + { + plib::container::remove(terms, p.substr(1)); + } } out += ")"; - printf("%s\n", out.cstr()); + printf("%s\n", out.c_str()); if (terms.size() > 0) { pstring t = ""; for (auto & j : terms) t += "," + j; - printf("Terminals: %s\n", t.substr(1).cstr()); + printf("\tTerminals: %s\n", t.substr(1).c_str()); } devs.push_back(std::move(d)); } @@ -514,11 +512,11 @@ int main(int argc, char *argv[]) result = c.result(); } /* present result */ - pout_strm.write(result.cstr()); + pout_strm.write(result.c_str()); } else { - perr("Unknown command {}\n", cmd.cstr()); + perr("Unknown command {}\n", cmd.c_str()); usage(opts); return 1; } diff --git a/src/lib/netlist/prg/nlwav.cpp b/src/lib/netlist/prg/nlwav.cpp index ea5fc450f2b..32ca8c6e173 100644 --- a/src/lib/netlist/prg/nlwav.cpp +++ b/src/lib/netlist/prg/nlwav.cpp @@ -148,7 +148,7 @@ static void convert(nlwav_options_t &opts) { #if 1 double t = 0.0; double v = 0.0; - sscanf(line.cstr(), "%lf %lf", &t, &v); + sscanf(line.c_str(), "%lf %lf", &t, &v); while (t >= ct) { outsam += (ct - lt) * cursam; @@ -203,7 +203,7 @@ static void convert(nlwav_options_t &opts) static void usage(plib::pstream_fmt_writer_t &fw, nlwav_options_t &opts) { fw("{}\n", opts.help("Convert netlist log files into wav files.\n", - "nltool [options]").cstr()); + "nltool [options]").c_str()); } diff --git a/src/lib/netlist/solver/nld_ms_w.h b/src/lib/netlist/solver/nld_ms_w.h index 55d9d630224..e644ce40085 100644 --- a/src/lib/netlist/solver/nld_ms_w.h +++ b/src/lib/netlist/solver/nld_ms_w.h @@ -300,7 +300,7 @@ unsigned matrix_solver_w_t<m_N, storage_N>::solve_non_dynamic(const bool newton_ for (unsigned i = 0; i < rowcount; i++) { if (H[i][i] == 0.0) - printf("%s H singular\n", this->name().cstr()); + printf("%s H singular\n", this->name().c_str()); const nl_double f = 1.0 / H[i][i]; for (unsigned j = i+1; j < rowcount; j++) { @@ -355,7 +355,7 @@ unsigned matrix_solver_w_t<m_N, storage_N>::solve_non_dynamic(const bool newton_ tmp += A(i,j) * new_V[j]; } if (std::abs(tmp-RHS(i)) > 1e-6) - printf("%s failed on row %d: %f RHS: %f\n", this->name().cstr(), i, std::abs(tmp-RHS(i)), RHS(i)); + printf("%s failed on row %d: %f RHS: %f\n", this->name().c_str(), i, std::abs(tmp-RHS(i)), RHS(i)); } if (newton_raphson) { diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp index b9c69884382..3f4deb0340f 100644 --- a/src/lib/netlist/solver/nld_solver.cpp +++ b/src/lib/netlist/solver/nld_solver.cpp @@ -163,7 +163,7 @@ void matrix_solver_t::setup_base(analog_net_t::list_t &nets) nl_assert(p->net().is_analog()); net_proxy_output->m_proxied_net = static_cast<analog_net_t *>(&p->net()); } - net_proxy_output->net().register_con(*p); + net_proxy_output->net().add_terminal(*p); // FIXME: repeated net_proxy_output->net().rebuild_list(); log().debug("Added input\n"); diff --git a/src/lib/netlist/tools/nl_convert.cpp b/src/lib/netlist/tools/nl_convert.cpp index db1fb5bb3c9..3dc021cce64 100644 --- a/src/lib/netlist/tools/nl_convert.cpp +++ b/src/lib/netlist/tools/nl_convert.cpp @@ -121,7 +121,7 @@ void nl_convert_base_t::dump_nl() { net_t *net = m_nets[m_ext_alias[i]].get(); // use the first terminal ... - out("ALIAS({}, {})\n", m_ext_alias[i].cstr(), net->terminals()[0].cstr()); + out("ALIAS({}, {})\n", m_ext_alias[i].c_str(), net->terminals()[0].c_str()); // if the aliased net only has this one terminal connected ==> don't dump if (net->terminals().size() == 1) net->set_no_export(); @@ -138,14 +138,14 @@ void nl_convert_base_t::dump_nl() std::size_t j = sorted[i]; if (m_devs[j]->has_value()) - out("{}({}, {})\n", m_devs[j]->type().cstr(), - m_devs[j]->name().cstr(), get_nl_val(m_devs[j]->value()).cstr()); + out("{}({}, {})\n", m_devs[j]->type().c_str(), + m_devs[j]->name().c_str(), get_nl_val(m_devs[j]->value()).c_str()); else if (m_devs[j]->has_model()) - out("{}({}, \"{}\")\n", m_devs[j]->type().cstr(), - m_devs[j]->name().cstr(), m_devs[j]->model().cstr()); + out("{}({}, \"{}\")\n", m_devs[j]->type().c_str(), + m_devs[j]->name().c_str(), m_devs[j]->model().c_str()); else - out("{}({})\n", m_devs[j]->type().cstr(), - m_devs[j]->name().cstr()); + out("{}({})\n", m_devs[j]->type().c_str(), + m_devs[j]->name().c_str()); } // print nets for (auto & i : m_nets) @@ -153,11 +153,11 @@ void nl_convert_base_t::dump_nl() net_t * net = i.second.get(); if (!net->is_no_export()) { - //printf("Net {}\n", net->name().cstr()); - out("NET_C({}", net->terminals()[0].cstr() ); + //printf("Net {}\n", net->name().c_str()); + out("NET_C({}", net->terminals()[0].c_str() ); for (std::size_t j=1; j<net->terminals().size(); j++) { - out(", {}", net->terminals()[j].cstr() ); + out(", {}", net->terminals()[j].c_str() ); } out(")\n"); } @@ -178,7 +178,7 @@ const pstring nl_convert_base_t::get_nl_val(const double val) break; i++; } - return plib::pfmt(m_units[i].m_func.cstr())(val / m_units[i].m_mult); + return plib::pfmt(m_units[i].m_func.c_str())(val / m_units[i].m_mult); } } double nl_convert_base_t::get_sp_unit(const pstring &unit) @@ -190,7 +190,7 @@ double nl_convert_base_t::get_sp_unit(const pstring &unit) return m_units[i].m_mult; i++; } - fprintf(stderr, "Unit %s unknown\n", unit.cstr()); + fprintf(stderr, "Unit %s unknown\n", unit.c_str()); return 0.0; } @@ -269,12 +269,12 @@ void nl_convert_spice_t::process_line(const pstring &line) out("// {}\n", line.substr(1)); break; case '*': - out("// {}\n", line.substr(1).cstr()); + out("// {}\n", line.substr(1).c_str()); break; case '.': if (tt[0].equals(".SUBCKT")) { - out("NETLIST_START({})\n", tt[1].cstr()); + out("NETLIST_START({})\n", tt[1].c_str()); for (std::size_t i=2; i<tt.size(); i++) add_ext_alias(tt[i]); } @@ -284,7 +284,7 @@ void nl_convert_spice_t::process_line(const pstring &line) out("NETLIST_END()\n"); } else - out("// {}\n", line.cstr()); + out("// {}\n", line.c_str()); break; case 'Q': { @@ -304,7 +304,7 @@ void nl_convert_spice_t::process_line(const pstring &line) if (m.size() == 2) { if (m[1].len() != 4) - fprintf(stderr, "error with model desc %s\n", model.cstr()); + fprintf(stderr, "error with model desc %s\n", model.c_str()); pins = m[1].left(m[1].begin() + 3); } add_device("QBJT_EB", tt[0], m[0]); @@ -346,7 +346,7 @@ void nl_convert_spice_t::process_line(const pstring &line) //add_term(tt[2], tt[0] + ".2"); } else - fprintf(stderr, "Voltage Source %s not connected to GND\n", tt[0].cstr()); + fprintf(stderr, "Voltage Source %s not connected to GND\n", tt[0].c_str()); break; case 'I': // Input pin special notation { @@ -379,7 +379,7 @@ void nl_convert_spice_t::process_line(const pstring &line) break; } default: - out("// IGNORED {}: {}\n", tt[0].cstr(), line.cstr()); + out("// IGNORED {}: {}\n", tt[0].c_str(), line.c_str()); } } } @@ -485,7 +485,7 @@ void nl_convert_eagle_t::convert(const pstring &contents) } else { - out("Unexpected {}\n", token.str().cstr()); + out("Unexpected {}\n", token.str().c_str()); return; } } diff --git a/src/lib/netlist/tools/nl_convert.h b/src/lib/netlist/tools/nl_convert.h index fa496a092d7..859c5ea1e9c 100644 --- a/src/lib/netlist/tools/nl_convert.h +++ b/src/lib/netlist/tools/nl_convert.h @@ -204,7 +204,7 @@ public: void verror(const pstring &msg, int line_num, const pstring &line) override { - m_convert.out("{} (line {}): {}\n", msg.cstr(), line_num, line.cstr()); + m_convert.out("{} (line {}): {}\n", msg.c_str(), line_num, line.c_str()); } @@ -273,7 +273,7 @@ public: void verror(const pstring &msg, int line_num, const pstring &line) override { - m_convert.out("{} (line {}): {}\n", msg.cstr(), line_num, line.cstr()); + m_convert.out("{} (line {}): {}\n", msg.c_str(), line_num, line.c_str()); } diff --git a/src/lib/util/unicode.cpp b/src/lib/util/unicode.cpp index a6c5515fbf6..b3e92e4094e 100644 --- a/src/lib/util/unicode.cpp +++ b/src/lib/util/unicode.cpp @@ -2,7 +2,7 @@ // copyright-holders:Aaron Giles /********************************************************************* - unicode.c + unicode.cpp Unicode related functions @@ -10,6 +10,12 @@ #include "unicode.h" +#ifdef _WIN32 +#define UTF8PROC_DLLEXPORT +#endif + +#include "utf8proc/utf8proc.h" + //------------------------------------------------- // uchar_isvalid - return true if a given @@ -346,6 +352,87 @@ int utf16f_from_uchar(char16_t *utf16string, size_t count, char32_t uchar) //------------------------------------------------- +// internal_normalize_unicode - uses utf8proc to +// normalize unicode +//------------------------------------------------- + +static std::string internal_normalize_unicode(const char *s, size_t length, unicode_normalization_form normalization_form, bool null_terminated) +{ + // convert the normalization form + int options; + switch (normalization_form) + { + case unicode_normalization_form::C: + options = UTF8PROC_STABLE | UTF8PROC_COMPOSE; + break; + case unicode_normalization_form::D: + options = UTF8PROC_STABLE | UTF8PROC_DECOMPOSE; + break; + case unicode_normalization_form::KC: + options = UTF8PROC_STABLE | UTF8PROC_COMPOSE | UTF8PROC_COMPAT; + break; + case unicode_normalization_form::KD: + options = UTF8PROC_STABLE | UTF8PROC_DECOMPOSE | UTF8PROC_COMPAT; + break; + default: + throw false; + } + + // was this null terminated? + if (null_terminated) + options |= UTF8PROC_NULLTERM; + + // invoke utf8proc + utf8proc_uint8_t *utf8proc_result; + utf8proc_ssize_t utf8proc_result_length = utf8proc_map((utf8proc_uint8_t *) s, length, &utf8proc_result, (utf8proc_option_t)options); + + // conver the result + std::string result; + if (utf8proc_result) + { + if (utf8proc_result_length > 0) + result = std::string((const char *)utf8proc_result, utf8proc_result_length); + free(utf8proc_result); + } + + return result; +} + + +//------------------------------------------------- +// normalize_unicode - uses utf8proc to normalize +// unicode +//------------------------------------------------- + +std::string normalize_unicode(const std::string &s, unicode_normalization_form normalization_form) +{ + return internal_normalize_unicode(s.c_str(), s.length(), normalization_form, false); +} + + +//------------------------------------------------- +// normalize_unicode - uses utf8proc to normalize +// unicode +//------------------------------------------------- + +std::string normalize_unicode(const char *s, unicode_normalization_form normalization_form) +{ + return internal_normalize_unicode(s, 0, normalization_form, true); +} + + +//------------------------------------------------- +// normalize_unicode - uses utf8proc to normalize +// unicode +//------------------------------------------------- + +std::string normalize_unicode(const char *s, size_t length, unicode_normalization_form normalization_form) +{ + return internal_normalize_unicode(s, length, normalization_form, false); +} + + +//------------------------------------------------- // utf8_previous_char - return a pointer to the // previous character in a string //------------------------------------------------- diff --git a/src/lib/util/unicode.h b/src/lib/util/unicode.h index 5cc6db383ee..ef5267794e6 100644 --- a/src/lib/util/unicode.h +++ b/src/lib/util/unicode.h @@ -72,6 +72,9 @@ #define UTF8_UP "\xe2\x86\x91" /* cursor up */ #define UTF8_DOWN "\xe2\x86\x93" /* cursor down */ +enum class unicode_normalization_form { C, D, KC, KD }; + + /*************************************************************************** FUNCTION PROTOTYPES @@ -97,6 +100,11 @@ std::string utf8_from_uchar(char32_t uchar); int utf16_from_uchar(char16_t *utf16string, size_t count, char32_t uchar); int utf16f_from_uchar(char16_t *utf16string, size_t count, char32_t uchar); +// unicode normalization +std::string normalize_unicode(const std::string &s, unicode_normalization_form normalization_form); +std::string normalize_unicode(const char *s, unicode_normalization_form normalization_form); +std::string normalize_unicode(const char *s, size_t length, unicode_normalization_form normalization_form); + // misc UTF-8 helpers const char *utf8_previous_char(const char *utf8string); bool utf8_is_valid_string(const char *utf8string); |