diff --git a/src/lib/netlist/analog/nld_opamps.cpp b/src/lib/netlist/analog/nld_opamps.cpp index 7b5db6b2fb6..0fc1b27a553 100644 --- a/src/lib/netlist/analog/nld_opamps.cpp +++ b/src/lib/netlist/analog/nld_opamps.cpp @@ -107,8 +107,8 @@ namespace netlist NETLIB_CONSTRUCTOR(opamp) , m_RP(*this, "RP1") , m_G1(*this, "G1") - , m_VCC(*this, "VCC") - , m_GND(*this, "GND") + , m_VCC(*this, "VCC", NETLIB_DELEGATE(supply)) + , m_GND(*this, "GND", NETLIB_DELEGATE(supply)) , m_model(*this, "MODEL", "LM324") , m_modacc(m_model) , m_VH(*this, "VH") @@ -183,10 +183,26 @@ namespace netlist } - NETLIB_UPDATEI(); + NETLIB_UPDATEI() + { + supply(); + } + + NETLIB_HANDLERI(supply) + { + const nl_fptype cVt = nlconst::np_VT(nlconst::one()); // * m_n; + const nl_fptype cId = m_modacc.m_DAB; // 3 mA + const nl_fptype cVd = cVt * plib::log(cId / nlconst::np_Is() + nlconst::one()); + + m_VH.push(m_VCC() - m_modacc.m_VLH - cVd); + m_VL.push(m_GND() + m_modacc.m_VLL + cVd); + m_VREF.push((m_VCC() + m_GND()) / nlconst::two()); + } + NETLIB_RESETI() { } + NETLIB_UPDATE_PARAMI(); private: @@ -214,17 +230,6 @@ namespace netlist int m_type; }; - NETLIB_UPDATE(opamp) - { - const nl_fptype cVt = nlconst::np_VT(nlconst::one()); // * m_n; - const nl_fptype cId = m_modacc.m_DAB; // 3 mA - const nl_fptype cVd = cVt * plib::log(cId / nlconst::np_Is() + nlconst::one()); - - m_VH.push(m_VCC() - m_modacc.m_VLH - cVd); - m_VL.push(m_GND() + m_modacc.m_VLL + cVd); - m_VREF.push((m_VCC() + m_GND()) / nlconst::two()); - } - NETLIB_UPDATE_PARAM(opamp) { m_G1.m_RI.set(m_modacc.m_RI); diff --git a/src/lib/netlist/devices/nld_4066.cpp b/src/lib/netlist/devices/nld_4066.cpp index ba6b5ac5e36..8fe67600b14 100644 --- a/src/lib/netlist/devices/nld_4066.cpp +++ b/src/lib/netlist/devices/nld_4066.cpp @@ -33,7 +33,7 @@ namespace netlist NETLIB_CONSTRUCTOR_MODEL(CD4066_GATE, "CD4XXX") , m_supply(*this, "VDD", "VSS") , m_R(*this, "R") - , m_control(*this, "CTL") + , m_control(*this, "CTL", NETLIB_DELEGATE(control)) , m_base_r(*this, "BASER", nlconst::magic(270.0)) , m_last(*this, "m_last", false) { @@ -47,6 +47,12 @@ namespace netlist } NETLIB_UPDATEI() + { + control(); + } + + private: + NETLIB_HANDLERI(control) { nl_fptype sup = (m_supply.VCC().Q_Analog() - m_supply.GND().Q_Analog()); nl_fptype in = m_control() - m_supply.GND().Q_Analog(); @@ -71,7 +77,6 @@ namespace netlist } } - private: nld_power_pins m_supply; analog::NETLIB_SUB(R_base) m_R; analog_input_t m_control; diff --git a/src/lib/netlist/devices/nld_74123.cpp b/src/lib/netlist/devices/nld_74123.cpp index 5033e5d5528..ae8663b78d9 100644 --- a/src/lib/netlist/devices/nld_74123.cpp +++ b/src/lib/netlist/devices/nld_74123.cpp @@ -72,7 +72,7 @@ namespace netlist , m_I(*this, D::names(), NETLIB_DELEGATE(ab_clear)) , m_Q(*this, "Q") , m_QQ(*this, "QQ") - , m_CV(*this, "_CV") // internal + , m_CV(*this, "_CV", NETLIB_DELEGATE(cv)) // internal , m_last_trig(*this, "m_last_trig", 0) , m_state(*this, "m_state", 0) , m_KP(plib::reciprocal(nlconst::one() + plib::exp(D::K()))) @@ -128,6 +128,11 @@ namespace netlist } NETLIB_UPDATEI() + { + cv(); + } + + NETLIB_HANDLERI(cv) { if (m_state == 1) { diff --git a/src/lib/netlist/devices/nld_7475.cpp b/src/lib/netlist/devices/nld_7475.cpp index 81ea424321a..2633e7c76f4 100644 --- a/src/lib/netlist/devices/nld_7475.cpp +++ b/src/lib/netlist/devices/nld_7475.cpp @@ -16,10 +16,10 @@ namespace netlist NETLIB_OBJECT(7477) { NETLIB_CONSTRUCTOR(7477) - , m_C1C2(*this, "C1C2") - , m_C3C4(*this, "C3C4") + , m_C1C2(*this, "C1C2", NETLIB_DELEGATE(inputs)) + , m_C3C4(*this, "C3C4", NETLIB_DELEGATE(inputs)) , m_last_Q(*this, "m_last_Q", 0) - , m_D(*this, {"D1", "D2", "D3", "D4"}) + , m_D(*this, {"D1", "D2", "D3", "D4"}, NETLIB_DELEGATE(inputs)) , m_Q(*this, {"Q1", "Q2", "Q3", "Q4"}) , m_power_pins(*this) { @@ -30,9 +30,41 @@ namespace netlist { m_last_Q = 0; } - NETLIB_UPDATEI(); + NETLIB_UPDATEI() + { + inputs(); + } - void update_outputs(std::size_t start, std::size_t end); + NETLIB_HANDLERI(inputs) + { + netlist_sig_t c1c2 = m_C1C2(); + netlist_sig_t c3c4 = m_C3C4(); + if (c1c2 && c3c4) + { + update_outputs(0, 4); + } + else if (c1c2) + { + update_outputs(0, 2); + } + else if (c3c4) + { + update_outputs(2, 4); + } + + } + + void update_outputs(std::size_t start, std::size_t end) + { + for (std::size_t i=start; i> i) & 1)) + m_Q[i].push(d, d != 0 ? NLTIME_FROM_NS(30) : NLTIME_FROM_NS(25)); + m_last_Q &= ~(1 << i); + m_last_Q |= d << i; + } + } friend class NETLIB_NAME(7477_dip); friend class NETLIB_NAME(7475_dip); @@ -47,19 +79,80 @@ namespace netlist nld_power_pins m_power_pins; }; - NETLIB_OBJECT_DERIVED(7475, 7477) + NETLIB_OBJECT(7475) { NETLIB_CONSTRUCTOR(7475) + , m_C1C2(*this, "C1C2", NETLIB_DELEGATE(inputs)) + , m_C3C4(*this, "C3C4", NETLIB_DELEGATE(inputs)) + , m_last_Q(*this, "m_last_Q", 0) + , m_D(*this, {"D1", "D2", "D3", "D4"}, NETLIB_DELEGATE(inputs)) + , m_Q(*this, {"Q1", "Q2", "Q3", "Q4"}) , m_QQ(*this, {"QQ1", "QQ2", "QQ3", "QQ4"}) + , m_power_pins(*this) { + register_subalias("Q1", m_Q[0]); } - NETLIB_UPDATEI(); + NETLIB_RESETI() + { + m_last_Q = 0; + } + + NETLIB_UPDATEI() + { + inputs(); + } + + NETLIB_HANDLERI(inputs) + { + unsigned start_q = m_last_Q; + + netlist_sig_t c1c2 = m_C1C2(); + netlist_sig_t c3c4 = m_C3C4(); + if (c1c2 && c3c4) + { + update_outputs(0, 4); + } + else if (c1c2) + { + update_outputs(0, 2); + } + else if (c3c4) + { + update_outputs(2, 4); + } + + for (std::size_t i=0; i<4; i++) + { + unsigned last_bit = (m_last_Q >> i) & 1; + unsigned start_bit = (start_q >> i) & 1; + if (last_bit != start_bit) + m_QQ[i].push(last_bit ^ 1, last_bit != 0 ? NLTIME_FROM_NS(15) : NLTIME_FROM_NS(40)); + } + } + + void update_outputs(std::size_t start, std::size_t end) + { + for (std::size_t i=start; i> i) & 1)) + m_Q[i].push(d, d != 0 ? NLTIME_FROM_NS(30) : NLTIME_FROM_NS(25)); + m_last_Q &= ~(1 << i); + m_last_Q |= d << i; + } + } friend class NETLIB_NAME(7477_dip); friend class NETLIB_NAME(7475_dip); private: + logic_input_t m_C1C2; + logic_input_t m_C3C4; + state_var m_last_Q; + object_array_t m_D; + object_array_t m_Q; object_array_t m_QQ; + nld_power_pins m_power_pins; }; NETLIB_OBJECT(7475_dip) @@ -118,52 +211,6 @@ namespace netlist NETLIB_SUB(7477) A; }; - NETLIB_UPDATE(7475) - { - unsigned start_q = m_last_Q; - - NETLIB_NAME(7477)::update(); - - for (std::size_t i=0; i<4; i++) - { - unsigned last_bit = (m_last_Q >> i) & 1; - unsigned start_bit = (start_q >> i) & 1; - if (last_bit != start_bit) - m_QQ[i].push(last_bit ^ 1, last_bit != 0 ? NLTIME_FROM_NS(15) : NLTIME_FROM_NS(40)); - } - } - - void NETLIB_NAME(7477)::update_outputs(std::size_t start, std::size_t end) - { - for (std::size_t i=start; i> i) & 1)) - m_Q[i].push(d, d != 0 ? NLTIME_FROM_NS(30) : NLTIME_FROM_NS(25)); - m_last_Q &= ~(1 << i); - m_last_Q |= d << i; - } - } - - NETLIB_UPDATE(7477) - { - netlist_sig_t c1c2 = m_C1C2(); - netlist_sig_t c3c4 = m_C3C4(); - if (c1c2 && c3c4) - { - update_outputs(0, 4); - } - else if (c1c2) - { - update_outputs(0, 2); - } - else if (c3c4) - { - update_outputs(2, 4); - } - - } - NETLIB_DEVICE_IMPL(7475, "TTL_7475", "") NETLIB_DEVICE_IMPL(7475_dip, "TTL_7475_DIP", "") NETLIB_DEVICE_IMPL(7477, "TTL_7477", "") diff --git a/src/lib/netlist/devices/nld_7483.cpp b/src/lib/netlist/devices/nld_7483.cpp index ccfc2df9e8b..eaa35f87ef1 100644 --- a/src/lib/netlist/devices/nld_7483.cpp +++ b/src/lib/netlist/devices/nld_7483.cpp @@ -65,13 +65,13 @@ namespace netlist NETLIB_HANDLERI(upd_a) { m_a = static_cast((m_A1() << 0) | (m_A2() << 1) | (m_A3() << 2) | (m_A4() << 3)); - NETLIB_NAME(7483)::update(); + c0(); } NETLIB_HANDLERI(upd_b) { m_b = static_cast((m_B1() << 0) | (m_B2() << 1) | (m_B3() << 2) | (m_B4() << 3)); - NETLIB_NAME(7483)::update(); + c0(); } diff --git a/src/lib/netlist/devices/nld_7497.cpp b/src/lib/netlist/devices/nld_7497.cpp index 671a98eeabd..5fa1d17d35b 100644 --- a/src/lib/netlist/devices/nld_7497.cpp +++ b/src/lib/netlist/devices/nld_7497.cpp @@ -23,10 +23,10 @@ namespace netlist NETLIB_OBJECT(7497) { NETLIB_CONSTRUCTOR(7497) - , m_B(*this, {"B5", "B4", "B3", "B2", "B1", "B0"}) + , m_B(*this, {"B5", "B4", "B3", "B2", "B1", "B0"}, NETLIB_DELEGATE(inputs)) , m_CLK(*this, "CLK", NETLIB_DELEGATE(clk_strb)) , m_STRBQ(*this, "STRBQ", NETLIB_DELEGATE(clk_strb)) - , m_ENQ(*this, "ENQ", NETLIB_DELEGATE(enq)) + , m_ENQ(*this, "ENQ", NETLIB_DELEGATE(inputs)) , m_UNITYQ(*this, "UNITYQ", NETLIB_DELEGATE(unity)) , m_CLR(*this, "CLR", NETLIB_DELEGATE(clr)) , m_Y(*this, "Y") @@ -50,7 +50,7 @@ namespace netlist NETLIB_UPDATEI() { - enq(); + inputs(); } NETLIB_HANDLERI(noop) { } @@ -101,7 +101,7 @@ namespace netlist } - NETLIB_HANDLERI(enq) + NETLIB_HANDLERI(inputs) { m_rate = rate(); clk_strb(); @@ -146,9 +146,6 @@ namespace netlist } }; - - - NETLIB_OBJECT(7497_dip) { NETLIB_CONSTRUCTOR(7497_dip) diff --git a/src/lib/netlist/devices/nld_74ls629.cpp b/src/lib/netlist/devices/nld_74ls629.cpp index 7e629f2cc7f..e733312fa2e 100644 --- a/src/lib/netlist/devices/nld_74ls629.cpp +++ b/src/lib/netlist/devices/nld_74ls629.cpp @@ -184,7 +184,6 @@ namespace netlist // FIXME: we need a possibility to remove entries from queue ... // or an exact model ... m_clock.m_inc = netlist_time::from_fp(nlconst::half() / freq); - //m_clock.update(); //NL_VERBOSE_OUT(("{1} {2} {3} {4}\n", name(), v_freq, v_rng, freq)); } diff --git a/src/lib/netlist/devices/nld_82S16.cpp b/src/lib/netlist/devices/nld_82S16.cpp index 157b9f78d94..1981f7a9832 100644 --- a/src/lib/netlist/devices/nld_82S16.cpp +++ b/src/lib/netlist/devices/nld_82S16.cpp @@ -71,7 +71,7 @@ namespace netlist adr |= (m_A[i]() << i); } m_addr = adr; - NETLIB_NAME(82S16)::update(); + inputs(); } NETLIB_HANDLERI(enq) { @@ -92,7 +92,7 @@ namespace netlist m_A[i].activate(); m_WEQ.activate(); m_DIN.activate(); - NETLIB_NAME(82S16)::update(); + inputs(); } } diff --git a/src/lib/netlist/devices/nld_log.cpp b/src/lib/netlist/devices/nld_log.cpp index bff10317434..87599f31600 100644 --- a/src/lib/netlist/devices/nld_log.cpp +++ b/src/lib/netlist/devices/nld_log.cpp @@ -26,7 +26,7 @@ namespace netlist NETLIB_OBJECT(log) { NETLIB_CONSTRUCTOR(log) - , m_I(*this, "I") + , m_I(*this, "I", NETLIB_DELEGATE(input)) , m_strm(plib::filesystem::u8path(plib::pfmt("{1}.log")(this->name()))) , m_writer(&m_strm) , m_reset(false) @@ -54,6 +54,16 @@ namespace netlist } NETLIB_UPDATEI() + { + input(); + } + + NETLIB_HANDLERI(input) + { + log_value(static_cast(m_I())); + } + + void log_value(nl_fptype val) { if (m_buffers[m_w].size() == BUF_SIZE) { @@ -64,7 +74,7 @@ namespace netlist m_w = 0; } /* use pstring::sprintf, it is a LOT faster */ - m_buffers[m_w].push_back({exec().time(), static_cast(m_I())}); + m_buffers[m_w].push_back({exec().time(), val}); //m_writer.writeline(plib::pfmt("{1:.9} {2}").e(exec().time().as_fp()).e(static_cast(m_I()))); } @@ -117,13 +127,19 @@ namespace netlist NETLIB_OBJECT_DERIVED(logD, log) { NETLIB_CONSTRUCTOR(logD) - , m_I2(*this, "I2") + , m_I2(*this, "I2", nldelegate(&NETLIB_NAME(logD)::input, this)) { + m_I.set_delegate(nldelegate(&NETLIB_NAME(logD)::input, this)); } NETLIB_UPDATEI() { - m_writer.writeline(plib::pfmt("{1:.9} {2}").e(exec().time().as_fp()).e(static_cast(m_I() - m_I2()))); + input(); + } + + NETLIB_HANDLERI(input) + { + log_value(static_cast(m_I() - m_I2())); } NETLIB_RESETI() { } diff --git a/src/lib/netlist/devices/nld_schmitt.cpp b/src/lib/netlist/devices/nld_schmitt.cpp index 7e69f247a10..98075ee549c 100644 --- a/src/lib/netlist/devices/nld_schmitt.cpp +++ b/src/lib/netlist/devices/nld_schmitt.cpp @@ -60,7 +60,7 @@ namespace netlist NETLIB_OBJECT(schmitt_trigger) { NETLIB_CONSTRUCTOR(schmitt_trigger) - , m_A(*this, "A") + , m_A(*this, "A", NETLIB_DELEGATE(input)) , m_supply(*this) , m_RVI(*this, "RVI") , m_RVO(*this, "RVO") @@ -86,6 +86,12 @@ namespace netlist } NETLIB_UPDATEI() + { + input(); + } + + private: + NETLIB_HANDLERI(input) { const auto va(m_A.Q_Analog() - m_supply.GND().Q_Analog()); if (m_last_state) @@ -112,7 +118,6 @@ namespace netlist } } - private: analog_input_t m_A; NETLIB_NAME(power_pins) m_supply; analog::NETLIB_SUB(twoterm) m_RVI; diff --git a/src/lib/netlist/devices/nld_system.cpp b/src/lib/netlist/devices/nld_system.cpp index c987ef7065a..78b5a3af923 100644 --- a/src/lib/netlist/devices/nld_system.cpp +++ b/src/lib/netlist/devices/nld_system.cpp @@ -18,46 +18,6 @@ namespace devices // ---------------------------------------------------------------------------------------- - // ---------------------------------------------------------------------------------------- - // extclock - // ---------------------------------------------------------------------------------------- - - NETLIB_RESET(extclock) - { - m_cnt = 0; - m_off = netlist_time::from_fp(m_offset()); - m_feedback.set_delegate(NETLIB_DELEGATE(update)); - } - - NETLIB_HANDLER(extclock, clk2) - { - m_Q.push((m_cnt & 1) ^ 1, m_inc[m_cnt]); - if (++m_cnt >= m_size) - m_cnt = 0; - } - - NETLIB_HANDLER(extclock, clk2_pow2) - { - m_Q.push((m_cnt & 1) ^ 1, m_inc[m_cnt]); - m_cnt = (++m_cnt) & (m_size-1); - } - - NETLIB_UPDATE(extclock) - { - m_Q.push((m_cnt & 1) ^ 1, m_inc[m_cnt] + m_off()); - m_off = netlist_time::zero(); - if (++m_cnt >= m_size) - m_cnt = 0; - - // continue with optimized clock handlers .... - - if ((m_size & (m_size-1)) == 0) // power of 2? - m_feedback.set_delegate(nldelegate(&NETLIB_NAME(extclock)::clk2_pow2, this)); - else - m_feedback.set_delegate(nldelegate(&NETLIB_NAME(extclock)::clk2, this)); - } - - NETLIB_DEVICE_IMPL(nc_pin, "NC_PIN", "") NETLIB_DEVICE_IMPL(frontier, "FRONTIER_DEV", "+I,+G,+Q") NETLIB_DEVICE_IMPL(function, "AFUNC", "N,FUNC") diff --git a/src/lib/netlist/devices/nld_tristate.cpp b/src/lib/netlist/devices/nld_tristate.cpp index f95d35ffe64..e5b7f4863ca 100644 --- a/src/lib/netlist/devices/nld_tristate.cpp +++ b/src/lib/netlist/devices/nld_tristate.cpp @@ -8,6 +8,9 @@ #include "nld_tristate.h" #include "netlist/nl_base.h" +// FIXME: netlist now supports proper tristate outputs. All of this is legacy +// now and needs to be removed at some time. + namespace netlist { namespace devices @@ -15,61 +18,67 @@ namespace netlist NETLIB_OBJECT(tristate) { NETLIB_CONSTRUCTOR(tristate) - , m_CEQ(*this, { "CEQ1", "CEQ2" }) - , m_D(*this, { "D1", "D2" }) + , m_CEQ(*this, { "CEQ1", "CEQ2" }, NETLIB_DELEGATE(inputs)) + , m_D(*this, { "D1", "D2" }, NETLIB_DELEGATE(inputs)) , m_Q(*this, "Q") { } - NETLIB_UPDATEI(); + NETLIB_UPDATEI() + { + inputs(); + } protected: object_array_t m_CEQ; object_array_t m_D; logic_output_t m_Q; + private: + NETLIB_HANDLERI(inputs) + { + unsigned q = 0; + if (!m_CEQ[0]()) + q |= m_D[0](); + if (!m_CEQ[1]()) + q |= m_D[1](); + + m_Q.push(q, NLTIME_FROM_NS(1)); + } }; NETLIB_OBJECT(tristate3) { NETLIB_CONSTRUCTOR(tristate3) - , m_CEQ(*this, { "CEQ1", "CEQ2", "CEQ3" } ) - , m_D(*this, { "D1", "D2", "D3" } ) + , m_CEQ(*this, { "CEQ1", "CEQ2", "CEQ3" }, NETLIB_DELEGATE(inputs) ) + , m_D(*this, { "D1", "D2", "D3" }, NETLIB_DELEGATE(inputs) ) , m_Q(*this, "Q") { } - NETLIB_UPDATEI(); + NETLIB_UPDATEI() + { + inputs(); + } protected: object_array_t m_CEQ; object_array_t m_D; logic_output_t m_Q; + private: + NETLIB_HANDLERI(inputs) + { + unsigned q = 0; + if (!m_CEQ[0]()) + q |= m_D[0](); + if (!m_CEQ[1]()) + q |= m_D[1](); + if (!m_CEQ[2]()) + q |= m_D[2](); + + m_Q.push(q, NLTIME_FROM_NS(1)); + } }; - NETLIB_UPDATE(tristate) - { - unsigned q = 0; - if (!m_CEQ[0]()) - q |= m_D[0](); - if (!m_CEQ[1]()) - q |= m_D[1](); - - m_Q.push(q, NLTIME_FROM_NS(1)); - } - - NETLIB_UPDATE(tristate3) - { - unsigned q = 0; - if (!m_CEQ[0]()) - q |= m_D[0](); - if (!m_CEQ[1]()) - q |= m_D[1](); - if (!m_CEQ[2]()) - q |= m_D[2](); - - m_Q.push(q, NLTIME_FROM_NS(1)); - } - NETLIB_DEVICE_IMPL(tristate, "TTL_TRISTATE", "+CEQ1,+D1,+CEQ2,+D2") NETLIB_DEVICE_IMPL(tristate3, "TTL_TRISTATE3", "") diff --git a/src/lib/netlist/devices/nlid_proxy.cpp b/src/lib/netlist/devices/nlid_proxy.cpp index 55bf27eb6fd..3ef03a16544 100644 --- a/src/lib/netlist/devices/nlid_proxy.cpp +++ b/src/lib/netlist/devices/nlid_proxy.cpp @@ -85,7 +85,7 @@ namespace netlist nld_a_to_d_proxy::nld_a_to_d_proxy(netlist_state_t &anetlist, const pstring &name, const logic_input_t *in_proxied) : nld_base_a_to_d_proxy(anetlist, name, in_proxied) , m_Q(*this, "Q") - , m_I(*this, "I") + , m_I(*this, "I", nldelegate(&nld_a_to_d_proxy::input, this)) { } @@ -93,7 +93,7 @@ namespace netlist { } - NETLIB_UPDATE(a_to_d_proxy) + NETLIB_HANDLER(a_to_d_proxy, input) { const auto v(m_I.Q_Analog()); const auto vn(m_tn->net().Q_Analog()); @@ -121,7 +121,7 @@ namespace netlist nld_d_to_a_proxy::nld_d_to_a_proxy(netlist_state_t &anetlist, const pstring &name, const logic_output_t *out_proxied) : nld_base_d_to_a_proxy(anetlist, name, out_proxied) - , m_I(*this, "I") + , m_I(*this, "I", nldelegate(&nld_d_to_a_proxy :: input, this)) , m_RP(*this, "RP") , m_RN(*this, "RN") , m_last_state(*this, "m_last_var", terminal_t::OUT_TRISTATE()) @@ -158,7 +158,7 @@ namespace netlist nlconst::zero()); } - NETLIB_UPDATE(d_to_a_proxy) + NETLIB_HANDLER(d_to_a_proxy ,input) { const auto state = m_I(); if (state != m_last_state) diff --git a/src/lib/netlist/devices/nlid_proxy.h b/src/lib/netlist/devices/nlid_proxy.h index 46c14116c58..5081b80e7fd 100644 --- a/src/lib/netlist/devices/nlid_proxy.h +++ b/src/lib/netlist/devices/nlid_proxy.h @@ -70,9 +70,14 @@ namespace devices protected: NETLIB_RESETI(); - NETLIB_UPDATEI(); + NETLIB_UPDATEI() + { + input(); + } private: + NETLIB_HANDLERI(input); + logic_output_t m_Q; analog_input_t m_I; }; @@ -109,9 +114,13 @@ namespace devices protected: NETLIB_RESETI(); - NETLIB_UPDATEI(); + NETLIB_UPDATEI() + { + input(); + } private: + NETLIB_HANDLERI(input); static constexpr const nl_fptype G_OFF = nlconst::cgmin(); diff --git a/src/lib/netlist/devices/nlid_system.h b/src/lib/netlist/devices/nlid_system.h index 958c40087e0..e16e5ee33ac 100644 --- a/src/lib/netlist/devices/nlid_system.h +++ b/src/lib/netlist/devices/nlid_system.h @@ -51,7 +51,7 @@ namespace devices NETLIB_OBJECT(clock) { NETLIB_CONSTRUCTOR(clock) - , m_feedback(*this, "FB") + , m_feedback(*this, "FB", NETLIB_DELEGATE(fb)) , m_Q(*this, "Q") , m_freq(*this, "FREQ", nlconst::magic(7159000.0 * 5.0)) , m_supply(*this) @@ -67,6 +67,11 @@ namespace devices } NETLIB_UPDATEI() + { + fb(); + } + + NETLIB_HANDLERI(fb) { m_Q.push(m_feedback() ^ 1, m_inc); } @@ -90,7 +95,7 @@ namespace devices NETLIB_CONSTRUCTOR(varclock) , m_N(*this, "N", 1) , m_func(*this,"FUNC", "T") - , m_feedback(*this, "FB") + , m_feedback(*this, "FB", NETLIB_DELEGATE(fb)) , m_Q(*this, "Q") , m_compiled(*this, "m_compiled") , m_supply(*this) @@ -103,7 +108,7 @@ namespace devices for (int i=0; i < m_N(); i++) { pstring inpname = plib::pfmt("A{1}")(i); - m_I.push_back(state().make_pool_object(*this, inpname)); + m_I.push_back(state().make_pool_object(*this, inpname, NETLIB_DELEGATE(fb))); inps.push_back(inpname); m_vals.push_back(nlconst::zero()); } @@ -115,6 +120,12 @@ namespace devices //NETLIB_UPDATE_PARAMI() NETLIB_UPDATEI() + { + fb(); + } + + private: + NETLIB_HANDLERI(fb) { m_vals[0] = exec().time().as_fp(); for (std::size_t i = 0; i < static_cast(m_N()); i++) @@ -125,7 +136,6 @@ namespace devices m_Q.push(m_feedback() ^ 1, m_inc); } - private: using pf_type = plib::pfunction; param_int_t m_N; param_str_t m_func; @@ -149,7 +159,7 @@ namespace devices , m_freq(*this, "FREQ", nlconst::magic(7159000.0 * 5.0)) , m_pattern(*this, "PATTERN", "1,1") , m_offset(*this, "OFFSET", nlconst::zero()) - , m_feedback(*this, "FB") + , m_feedback(*this, "FB", NETLIB_DELEGATE(first)) , m_Q(*this, "Q") , m_cnt(*this, "m_cnt", 0) , m_off(*this, "m_off", netlist_time::zero()) @@ -182,15 +192,50 @@ namespace devices } - NETLIB_UPDATEI(); - NETLIB_RESETI(); + NETLIB_UPDATEI() + { + first(); + } + + NETLIB_RESETI() + { + m_cnt = 0; + m_off = netlist_time::from_fp(m_offset()); + m_feedback.set_delegate(NETLIB_DELEGATE(first)); + } //NETLIB_UPDATE_PARAMI(); - NETLIB_HANDLERI(clk2); - NETLIB_HANDLERI(clk2_pow2); - private: + NETLIB_HANDLERI(clk2) + { + m_Q.push((m_cnt & 1) ^ 1, m_inc[m_cnt]); + if (++m_cnt >= m_size) + m_cnt = 0; + } + + NETLIB_HANDLERI(clk2_pow2) + { + m_Q.push((m_cnt & 1) ^ 1, m_inc[m_cnt]); + m_cnt = (++m_cnt) & (m_size-1); + } + + NETLIB_HANDLERI(first) + { + m_Q.push((m_cnt & 1) ^ 1, m_inc[m_cnt] + m_off()); + m_off = netlist_time::zero(); + if (++m_cnt >= m_size) + m_cnt = 0; + + // continue with optimized clock handlers .... + + if ((m_size & (m_size-1)) == 0) // power of 2? + m_feedback.set_delegate(nldelegate(&NETLIB_NAME(extclock)::clk2_pow2, this)); + else + m_feedback.set_delegate(nldelegate(&NETLIB_NAME(extclock)::clk2, this)); + } + + param_fp_t m_freq; param_str_t m_pattern; param_fp_t m_offset; @@ -301,7 +346,7 @@ namespace devices { public: NETLIB_CONSTRUCTOR(nc_pin) - , m_I(*this, "I") + , m_I(*this, "I", NETLIB_DELEGATE(noop)) { } @@ -310,6 +355,10 @@ namespace devices NETLIB_UPDATEI() { } private: + NETLIB_HANDLERI(noop) + { + } + analog_input_t m_I; }; @@ -324,7 +373,7 @@ namespace devices NETLIB_CONSTRUCTOR(frontier) , m_RIN(*this, "m_RIN", true) , m_ROUT(*this, "m_ROUT", true) - , m_I(*this, "_I") + , m_I(*this, "_I", NETLIB_DELEGATE(input)) , m_Q(*this, "_Q") , m_p_RIN(*this, "RIN", nlconst::magic(1.0e6)) , m_p_ROUT(*this, "ROUT", nlconst::magic(50.0)) @@ -347,10 +396,15 @@ namespace devices NETLIB_UPDATEI() { - m_Q.push(m_I()); + input(); } private: + NETLIB_HANDLERI(input) + { + m_Q.push(m_I()); + } + analog::NETLIB_NAME(twoterm) m_RIN; analog::NETLIB_NAME(twoterm) m_ROUT; analog_input_t m_I; @@ -376,7 +430,7 @@ namespace devices for (int i=0; i < m_N(); i++) { pstring inpname = plib::pfmt("A{1}")(i); - m_I.push_back(state().make_pool_object(*this, inpname)); + m_I.push_back(state().make_pool_object(*this, inpname, NETLIB_DELEGATE(inputs))); inps.push_back(inpname); m_vals.push_back(nlconst::zero()); } @@ -390,6 +444,11 @@ namespace devices } NETLIB_UPDATEI() + { + inputs(); + } + + NETLIB_HANDLERI(inputs) { for (std::size_t i = 0; i < static_cast(m_N()); i++) { @@ -421,7 +480,7 @@ namespace devices , m_RON(*this, "RON", nlconst::one()) , m_ROFF(*this, "ROFF", nlconst::magic(1.0E20)) , m_R(*this, "_R") - , m_I(*this, "I") + , m_I(*this, "I", NETLIB_DELEGATE(input)) , m_last_state(*this, "m_last_state", 0) { register_subalias("1", m_R.P()); @@ -434,21 +493,6 @@ namespace devices m_R.set_R(m_ROFF()); } - NETLIB_UPDATEI() - { - const netlist_sig_t state = m_I(); - if (state != m_last_state) - { - m_last_state = state; - const nl_fptype R = (state != 0) ? m_RON() : m_ROFF(); - - m_R.change_state([this, &R]() - { - m_R.set_R(R); - }); - } - } - //NETLIB_UPDATE_PARAMI(); //FIXME: used by 74123 @@ -461,6 +505,26 @@ namespace devices param_fp_t m_ROFF; private: + NETLIB_UPDATEI() + { + input(); + } + + NETLIB_HANDLERI(input) + { + const netlist_sig_t state = m_I(); + if (state != m_last_state) + { + m_last_state = state; + const nl_fptype R = (state != 0) ? m_RON() : m_ROFF(); + + m_R.change_state([this, &R]() + { + m_R.set_R(R); + }); + } + } + analog::NETLIB_SUB(R_base) m_R; logic_input_t m_I; @@ -477,7 +541,7 @@ namespace devices NETLIB_CONSTRUCTOR(sys_dsw2) , m_R1(*this, "_R1") , m_R2(*this, "_R2") - , m_I(*this, "I") + , m_I(*this, "I", NETLIB_DELEGATE(input)) , m_GON(*this, "GON", nlconst::magic(1e9)) // FIXME: all switches should have some on value , m_GOFF(*this, "GOFF", nlconst::cgmin()) , m_power_pins(*this) @@ -495,7 +559,15 @@ namespace devices m_R2.set_G(m_GON()); } + //NETLIB_UPDATE_PARAMI(); + + private: NETLIB_UPDATEI() + { + input(); + } + + NETLIB_HANDLERI(input) { const netlist_sig_t state = m_I(); @@ -523,9 +595,6 @@ namespace devices } } - //NETLIB_UPDATE_PARAMI(); - - private: analog::NETLIB_SUB(R_base) m_R1; analog::NETLIB_SUB(R_base) m_R2; logic_input_t m_I; @@ -544,8 +613,8 @@ namespace devices { public: NETLIB_CONSTRUCTOR(sys_compd) - , m_IP(*this, "IP") - , m_IN(*this, "IN") + , m_IP(*this, "IP", NETLIB_DELEGATE(inputs)) + , m_IN(*this, "IN", NETLIB_DELEGATE(inputs)) , m_Q(*this, "Q") , m_QQ(*this, "QQ") , m_power_pins(*this) @@ -559,6 +628,14 @@ namespace devices } NETLIB_UPDATEI() + { + inputs(); + } + + //NETLIB_UPDATE_PARAMI(); + + private: + NETLIB_HANDLERI(inputs) { const netlist_sig_t state = (m_IP() > m_IN()); if (state != m_last_state) @@ -570,9 +647,6 @@ namespace devices } } - //NETLIB_UPDATE_PARAMI(); - - private: analog_input_t m_IP; analog_input_t m_IN; logic_output_t m_Q; @@ -588,6 +662,9 @@ namespace devices /// An externally clocked noise source. The noise acts as a voltage source /// with internal resistance RI. /// + /// Since a new random value is used on each state change on I the effective + /// frequency is clock source frequency times two! + /// /// Typical application: /// /// VCC @@ -621,7 +698,7 @@ namespace devices NETLIB_CONSTRUCTOR(sys_noise) , m_T(*this, "m_T") - , m_I(*this, "I") + , m_I(*this, "I", NETLIB_DELEGATE(input)) , m_RI(*this, "RI", nlconst::magic(0.1)) , m_sigma(*this, "SIGMA", nlconst::zero()) , m_mt(*this, "m_mt") @@ -632,9 +709,13 @@ namespace devices register_subalias("2", m_T.N()); } - protected: - + private: NETLIB_UPDATEI() + { + input(); + } + + NETLIB_HANDLERI(input) { nl_fptype val = m_dis.var()(m_mt.var()); m_T.change_state([this, val]() @@ -648,7 +729,6 @@ namespace devices m_T.set_G_V_I(plib::reciprocal(m_RI()), nlconst::zero(), nlconst::zero()); } - private: analog::NETLIB_SUB(twoterm) m_T; logic_input_t m_I; param_fp_t m_RI; diff --git a/src/lib/netlist/devices/nlid_truthtable.cpp b/src/lib/netlist/devices/nlid_truthtable.cpp index 9255e4c8c0a..91f50c898dc 100644 --- a/src/lib/netlist/devices/nlid_truthtable.cpp +++ b/src/lib/netlist/devices/nlid_truthtable.cpp @@ -81,6 +81,11 @@ namespace devices // update is only called during startup here ... NETLIB_UPDATEI() { + inputs(); + } + + NETLIB_HANDLERI(inputs) + { #if USE_TT_ALTERNATIVE m_state = 0; for (std::size_t i = 0; i < m_NI; ++i) @@ -390,7 +395,7 @@ namespace devices for (std::size_t i=0; i < m_NI; i++) { inout[i] = plib::trim(inout[i]); - m_I.emplace(i, *this, inout[i]); + m_I.emplace(i, *this, inout[i], nldelegate(&NETLIB_NAME(truthtable_t) :: inputs, this)); } #else for (std::size_t i=0; i < m_NI; i++) diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp index f546056ec30..f4c9fe2512e 100644 --- a/src/lib/netlist/nl_base.cpp +++ b/src/lib/netlist/nl_base.cpp @@ -717,7 +717,7 @@ namespace netlist // ---------------------------------------------------------------------------------------- terminal_t::terminal_t(core_device_t &dev, const pstring &aname, terminal_t *otherterm) - : analog_t(dev, aname, STATE_BIDIR) + : analog_t(dev, aname, STATE_BIDIR, nldelegate()) , m_Idr(nullptr) , m_go(nullptr) , m_gt(nullptr) @@ -782,7 +782,7 @@ namespace netlist // ---------------------------------------------------------------------------------------- logic_output_t::logic_output_t(device_t &dev, const pstring &aname, bool dummy) - : logic_t(dev, aname, STATE_OUT) + : logic_t(dev, aname, STATE_OUT, nldelegate()) , m_my_net(dev.state(), name() + ".net", this) { plib::unused_var(dummy); @@ -813,7 +813,7 @@ namespace netlist // ---------------------------------------------------------------------------------------- analog_output_t::analog_output_t(core_device_t &dev, const pstring &aname) - : analog_t(dev, aname, STATE_OUT) + : analog_t(dev, aname, STATE_OUT, nldelegate()) , m_my_net(dev.state(), name() + ".net", this) { state().register_net(device_arena::owned_ptr(&m_my_net, false)); diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index 912d733c882..3d1a739b429 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -627,7 +627,7 @@ namespace netlist }; core_terminal_t(core_device_t &dev, const pstring &aname, - state_e state, nldelegate delegate = nldelegate()); + state_e state, nldelegate delegate); virtual ~core_terminal_t() noexcept = default; PCOPYASSIGNMOVE(core_terminal_t, delete) @@ -813,7 +813,7 @@ namespace netlist public: analog_t(core_device_t &dev, const pstring &aname, state_e state, - nldelegate delegate = nldelegate()); + nldelegate delegate); const analog_net_t & net() const noexcept; analog_net_t & net() noexcept; @@ -890,7 +890,7 @@ namespace netlist { public: logic_t(device_t &dev, const pstring &aname, - state_e terminal_state, nldelegate delegate = nldelegate()); + state_e terminal_state, nldelegate delegate); logic_net_t & net() noexcept; const logic_net_t & net() const noexcept; @@ -904,7 +904,7 @@ namespace netlist { public: logic_input_t(device_t &dev, const pstring &aname, - nldelegate delegate = nldelegate()); + nldelegate delegate); #if 0 template @@ -933,7 +933,7 @@ namespace netlist /// \brief Constructor analog_input_t(core_device_t &dev, ///< owning device const pstring &aname, ///< name of terminal - nldelegate delegate = nldelegate() ///< delegate + nldelegate delegate ///< delegate ); /// \brief returns voltage at terminal. diff --git a/src/lib/netlist/nl_interface.h b/src/lib/netlist/nl_interface.h index 8b57c652f00..d833a7bf0c8 100644 --- a/src/lib/netlist/nl_interface.h +++ b/src/lib/netlist/nl_interface.h @@ -51,13 +51,11 @@ namespace netlist /// template - class NETLIB_NAME(analog_callback) : public device_t + NETLIB_OBJECT(analog_callback) { public: - NETLIB_NAME(analog_callback)(netlist_state_t &anetlist, - const pstring &name, nl_fptype threshold, FUNC &&func) - : device_t(anetlist, name) - , m_in(*this, "IN") + NETLIB_CONSTRUCTOR_EX(analog_callback, nl_fptype threshold, FUNC &&func) + , m_in(*this, "IN", NETLIB_DELEGATE(in)) , m_threshold(threshold) , m_last(*this, "m_last", 0) , m_func(func) @@ -70,6 +68,11 @@ namespace netlist } NETLIB_UPDATEI() + { + in(); + } + + NETLIB_HANDLERI(in) { const nl_fptype cur = m_in(); if (plib::abs(cur - m_last) > m_threshold) diff --git a/src/lib/netlist/solver/nld_matrix_solver.cpp b/src/lib/netlist/solver/nld_matrix_solver.cpp index 6de0bb83458..2e0b50dcf64 100644 --- a/src/lib/netlist/solver/nld_matrix_solver.cpp +++ b/src/lib/netlist/solver/nld_matrix_solver.cpp @@ -49,7 +49,7 @@ namespace solver , m_stat_newton_raphson_fail(*this, "m_stat_newton_raphson_fail", 0) , m_stat_vsolver_calls(*this, "m_stat_vsolver_calls", 0) , m_last_step(*this, "m_last_step", netlist_time_ext::zero()) - , m_fb_sync(*this, "FB_sync") + , m_fb_sync(*this, "FB_sync", nldelegate(&matrix_solver_t::fb_sync, this)) , m_Q_sync(*this, "Q_sync") , m_ops(0) { diff --git a/src/lib/netlist/solver/nld_matrix_solver.h b/src/lib/netlist/solver/nld_matrix_solver.h index 03c4b6f9663..233f12b650c 100644 --- a/src/lib/netlist/solver/nld_matrix_solver.h +++ b/src/lib/netlist/solver/nld_matrix_solver.h @@ -254,6 +254,11 @@ namespace solver // netdevice functions NETLIB_UPDATEI() + { + fb_sync(); + } + + NETLIB_HANDLERI(fb_sync) { PFDEBUG(printf("update\n");) const netlist_time new_timestep = solve(exec().time()); diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp index 63b3592f83a..1c5898d866d 100644 --- a/src/lib/netlist/solver/nld_solver.cpp +++ b/src/lib/netlist/solver/nld_solver.cpp @@ -42,7 +42,7 @@ namespace devices s->log_stats(); } - NETLIB_UPDATE(solver) + NETLIB_HANDLER(solver, fb_step) { if (m_params.m_dynamic_ts) return; diff --git a/src/lib/netlist/solver/nld_solver.h b/src/lib/netlist/solver/nld_solver.h index 4ff70d04606..640393dd776 100644 --- a/src/lib/netlist/solver/nld_solver.h +++ b/src/lib/netlist/solver/nld_solver.h @@ -27,7 +27,7 @@ namespace devices NETLIB_OBJECT(solver) { NETLIB_CONSTRUCTOR(solver) - , m_fb_step(*this, "FB_step") + , m_fb_step(*this, "FB_step", NETLIB_DELEGATE(fb_step)) , m_Q_step(*this, "Q_step") , m_params(*this) { @@ -43,7 +43,11 @@ namespace devices solver::static_compile_container create_solver_code(solver::static_compile_target target); - NETLIB_UPDATEI(); + NETLIB_UPDATEI() + { + fb_step(); + } + NETLIB_RESETI(); // NETLIB_UPDATE_PARAMI(); @@ -52,6 +56,8 @@ namespace devices using net_list_t = solver::matrix_solver_t::net_list_t; private: + NETLIB_HANDLERI(fb_step); + logic_input_t m_fb_step; logic_output_t m_Q_step;