diff --git a/src/lib/netlist/devices/nld_schmitt.cpp b/src/lib/netlist/devices/nld_schmitt.cpp index 987691e371b..7e69f247a10 100644 --- a/src/lib/netlist/devices/nld_schmitt.cpp +++ b/src/lib/netlist/devices/nld_schmitt.cpp @@ -64,8 +64,8 @@ namespace netlist , m_supply(*this) , m_RVI(*this, "RVI") , m_RVO(*this, "RVO") - , m_model(*this, "MODEL", "TTL_7414_GATE") - , m_modacc(m_model) + , m_stmodel(*this, "STMODEL", "TTL_7414_GATE") + , m_modacc(m_stmodel) , m_last_state(*this, "m_last_var", 1) { register_subalias("Q", m_RVO.P()); @@ -117,12 +117,12 @@ namespace netlist NETLIB_NAME(power_pins) m_supply; analog::NETLIB_SUB(twoterm) m_RVI; analog::NETLIB_SUB(twoterm) m_RVO; - param_model_t m_model; + param_model_t m_stmodel; schmitt_trigger_model_t m_modacc; state_var m_last_state; }; - NETLIB_DEVICE_IMPL(schmitt_trigger, "SCHMITT_TRIGGER", "MODEL") + NETLIB_DEVICE_IMPL(schmitt_trigger, "SCHMITT_TRIGGER", "STMODEL") } // namespace devices } // namespace netlist diff --git a/src/lib/netlist/devices/nld_schmitt.h b/src/lib/netlist/devices/nld_schmitt.h index 11a17555d52..fbc10706b23 100644 --- a/src/lib/netlist/devices/nld_schmitt.h +++ b/src/lib/netlist/devices/nld_schmitt.h @@ -16,6 +16,6 @@ #define SCHMITT_TRIGGER(name, model) \ NET_REGISTER_DEV(SCHMITT_TRIGGER, name) \ - NETDEV_PARAMI(name, MODEL, model) + NETDEV_PARAMI(name, STMODEL, model) #endif /* NLD_SCHMITT_H_ */ diff --git a/src/lib/netlist/devices/nlid_system.h b/src/lib/netlist/devices/nlid_system.h index 3dd9c34a137..d399da27506 100644 --- a/src/lib/netlist/devices/nlid_system.h +++ b/src/lib/netlist/devices/nlid_system.h @@ -53,14 +53,12 @@ namespace devices , m_feedback(*this, "FB") , m_Q(*this, "Q") , m_freq(*this, "FREQ", nlconst::magic(7159000.0 * 5.0)) - , m_model(*this, "MODEL", "FAMILY(TYPE=TTL)") , m_supply(*this) { m_inc = netlist_time::from_fp(plib::reciprocal(m_freq()*nlconst::two())); connect(m_feedback, m_Q); } - //NETLIB_RESETI(); NETLIB_UPDATE_PARAMI() { @@ -79,7 +77,6 @@ namespace devices param_fp_t m_freq; netlist_time m_inc; - param_model_t m_model; NETLIB_NAME(power_pins) m_supply; }; @@ -192,12 +189,8 @@ namespace devices NETLIB_CONSTRUCTOR(logic_input) , m_Q(*this, "Q") , m_IN(*this, "IN", false) - // make sure we get the family first - , m_model(*this, "MODEL", "FAMILY(TYPE=TTL)") , m_supply(*this) { - set_logic_family(state().setup().family_from_model(m_model())); - m_Q.set_logic_family(this->logic_family()); } NETLIB_UPDATEI() { } @@ -212,7 +205,6 @@ namespace devices logic_output_t m_Q; param_logic_t m_IN; - param_model_t m_model; NETLIB_NAME(power_pins) m_supply; }; @@ -222,13 +214,8 @@ namespace devices NETLIB_CONSTRUCTOR(logic_inputN) , m_Q(*this, "Q{}") , m_IN(*this, "IN", 0) - // make sure we get the family first - , m_model(*this, "model", "MODEL(TYPE=TTL)") , m_supply(*this) { - set_logic_family(state().setup().family_from_model(m_model())); - for (auto &q : m_Q) - q.set_logic_family(this->logic_family()); } NETLIB_UPDATEI() { } @@ -244,7 +231,6 @@ namespace devices object_array_t m_Q; param_int_t m_IN; - param_model_t m_model; NETLIB_NAME(power_pins) m_supply; }; @@ -465,13 +451,8 @@ namespace devices , m_GON(*this, "GON", nlconst::magic(1e9)) // FIXME: all switches should have some on value , m_GOFF(*this, "GOFF", nlconst::cgmin()) , m_last_state(*this, "m_last_state", 0) - , m_model(*this, "MODEL", "FAMILY(TYPE=TTL)") , m_power_pins(*this) { - // Pass on logic family - set_logic_family(state().setup().family_from_model(m_model())); - m_I.set_logic_family(this->logic_family()); - // connect and register pins register_subalias("1", m_R1.P()); register_subalias("2", m_R1.N()); @@ -528,7 +509,6 @@ namespace devices private: state_var m_last_state; - param_model_t m_model; nld_power_pins m_power_pins; }; @@ -545,14 +525,9 @@ namespace devices , m_IN(*this, "IN") , m_Q(*this, "Q") , m_QQ(*this, "QQ") - , m_model(*this, "MODEL", "FAMILY(TYPE=TTL)") , m_power_pins(*this) , m_last_state(*this, "m_last_state", 2) // ensure first execution { - // Pass on logic family - set_logic_family(state().setup().family_from_model(m_model())); - m_Q.set_logic_family(this->logic_family()); - m_QQ.set_logic_family(this->logic_family()); } NETLIB_RESETI() @@ -562,7 +537,6 @@ namespace devices NETLIB_UPDATEI() { - //printf("P %f N %f\n", m_IP(), m_IN()); const netlist_sig_t state = (m_IP() > m_IN()); if (state != m_last_state) { @@ -579,7 +553,6 @@ namespace devices analog_input_t m_IN; logic_output_t m_Q; logic_output_t m_QQ; - param_model_t m_model; nld_power_pins m_power_pins; private: diff --git a/src/lib/netlist/devices/nlid_truthtable.cpp b/src/lib/netlist/devices/nlid_truthtable.cpp index 5de1bd7e039..04a0293894e 100644 --- a/src/lib/netlist/devices/nlid_truthtable.cpp +++ b/src/lib/netlist/devices/nlid_truthtable.cpp @@ -474,7 +474,7 @@ namespace factory truthtable_base_element_t::truthtable_base_element_t(const pstring &name, const pstring &classname, const pstring &def_param, const pstring &sourcefile) : factory::element_t(name, classname, def_param, sourcefile) - , m_family_name(NETLIST_DEFAULT_TRUTHTABLE_FAMILY) + , m_family_name(NETLIST_DEFAULT_LOGIC_FAMILY) { } @@ -510,7 +510,7 @@ namespace factory nl_assert_always(false, msg.c_str()); } ret->m_desc = desc.desc; - ret->m_family_name = (desc.family != "" ? desc.family : pstring(NETLIST_DEFAULT_TRUTHTABLE_FAMILY)); + ret->m_family_name = (desc.family != "" ? desc.family : pstring(NETLIST_DEFAULT_LOGIC_FAMILY)); return ret; } diff --git a/src/lib/netlist/macro/nlm_base.cpp b/src/lib/netlist/macro/nlm_base.cpp index 88fe75a9bc2..be32c225ddb 100644 --- a/src/lib/netlist/macro/nlm_base.cpp +++ b/src/lib/netlist/macro/nlm_base.cpp @@ -79,11 +79,16 @@ static NETLIST_START(family_models) NET_MODEL("OPAMP _()") NET_MODEL("SCHMITT_TRIGGER _()") - // TTL: FAMILY(IVL=0.16 IVH=0.4 OVL=0.1 OVH=1.0 ORL=1.0 ORH=130) + NET_MODEL("74XX FAMILY(TYPE=TTL IVL=0.16 IVH=0.4 OVL=0.1 OVH=1.0 ORL=1.0 ORH=130)") - NET_MODEL("74XXOC FAMILY(IVL=0.16 IVH=0.4 OVL=0.1 OVH=0.05 ORL=10.0 ORH=1.0e8)") - NET_MODEL("74XX FAMILY(TYPE=TTL)") - NET_MODEL("CD4XXX FAMILY(TYPE=CD4XXX)") + // CMOS + // low input 1.5 , high input trigger 3.5 at 5V supply + // output offsets, low for CMOS, thus 0.05 + // output currents: see https://www.classe.cornell.edu/~ib38/teaching/p360/lectures/wk09/l26/EE2301Exp3F10.pdf + // typical CMOS may sink 0.4mA while output stays <= 0.4V + NET_MODEL("CD4XXX FAMILY(TYPE=CMOS IVL=0.3 IVH=0.7 OVL=0.05 OVH=0.05 ORL=500 ORH=500)") + + NET_MODEL("74XXOC FAMILY(TYPE=TTL IVL=0.16 IVH=0.4 OVL=0.1 OVH=0.05 ORL=10.0 ORH=1.0e8)") NETLIST_END() /* ---------------------------------------------------------------------------- diff --git a/src/lib/netlist/macro/nlm_other.cpp b/src/lib/netlist/macro/nlm_other.cpp index a5d665aa17b..58fda2e1db7 100644 --- a/src/lib/netlist/macro/nlm_other.cpp +++ b/src/lib/netlist/macro/nlm_other.cpp @@ -159,7 +159,7 @@ NETLIST_START(otheric_lib) TT_LINE(" 0 | 1 |100") TT_LINE(" 1 | 0 |100") // 2.1V negative going and 2.7V positive going at 5V - TT_FAMILY("FAMILY(IVL=0.42 IVH=0.54 OVL=0.05 OVH=0.05 ORL=10.0 ORH=10.0)") + TT_FAMILY("FAMILY(TYPE=CMOS IVL=0.42 IVH=0.54 OVL=0.05 OVH=0.05 ORL=10.0 ORH=10.0)") TRUTHTABLE_END() LOCAL_LIB_ENTRY(MC14584B_DIP) diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp index 527257a570f..265b2f93922 100644 --- a/src/lib/netlist/nl_base.cpp +++ b/src/lib/netlist/nl_base.cpp @@ -25,87 +25,15 @@ namespace netlist { + // ---------------------------------------------------------------------------------------- + // callbacks_t + // ---------------------------------------------------------------------------------------- + plib::unique_ptr callbacks_t:: static_solver_lib() const { return plib::make_unique(nullptr); } - // ---------------------------------------------------------------------------------------- - // logic_family_ttl_t - // ---------------------------------------------------------------------------------------- - - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init, modernize-use-equals-default) - logic_family_desc_t::logic_family_desc_t() - { - } - - class logic_family_ttl_t : public logic_family_desc_t - { - public: - logic_family_ttl_t() : logic_family_desc_t() - { - m_low_thresh_PCNT = nlconst::magic(0.8 / 5.0); - m_high_thresh_PCNT = nlconst::magic(2.0 / 5.0); - // m_low_V - these depend on sinked/sourced current. Values should be suitable for typical applications. - m_low_VO = nlconst::magic(0.1); - m_high_VO = nlconst::magic(1.0); // 4.0 - m_R_low = nlconst::magic(1.0); - m_R_high = nlconst::magic(130.0); - } - unique_pool_ptr create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, const logic_output_t *proxied) const override; - unique_pool_ptr create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, const logic_input_t *proxied) const override; - }; - - unique_pool_ptr logic_family_ttl_t::create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, const logic_output_t *proxied) const - { - return anetlist.make_object(anetlist, name, proxied); - } - unique_pool_ptr logic_family_ttl_t::create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, const logic_input_t *proxied) const - { - return anetlist.make_object(anetlist, name, proxied); - } - - class logic_family_cd4xxx_t : public logic_family_desc_t - { - public: - logic_family_cd4xxx_t() : logic_family_desc_t() - { - m_low_thresh_PCNT = nlconst::magic(1.5 / 5.0); - m_high_thresh_PCNT = nlconst::magic(3.5 / 5.0); - // m_low_V - these depend on sinked/sourced current. Values should be suitable for typical applications. - m_low_VO = nlconst::magic(0.05); - m_high_VO = nlconst::magic(0.05); // 4.95 - // https://www.classe.cornell.edu/~ib38/teaching/p360/lectures/wk09/l26/EE2301Exp3F10.pdf - // typical CMOS may sink 0.4mA while output stays <= 0.4V - m_R_low = nlconst::magic(500.0); - m_R_high = nlconst::magic(500.0); - } - unique_pool_ptr create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, const logic_output_t *proxied) const override; - unique_pool_ptr create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, const logic_input_t *proxied) const override; - }; - - unique_pool_ptr logic_family_cd4xxx_t::create_d_a_proxy(netlist_state_t &anetlist, const pstring &name, const logic_output_t *proxied) const - { - return anetlist.make_object(anetlist, name, proxied); - } - - unique_pool_ptr logic_family_cd4xxx_t::create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, const logic_input_t *proxied) const - { - return anetlist.make_object(anetlist, name, proxied); - } - - const logic_family_desc_t *family_TTL() - { - static logic_family_ttl_t obj; - return &obj; - } - const logic_family_desc_t *family_CD4XXX() - { - static logic_family_cd4xxx_t obj; - return &obj; - } - - // ---------------------------------------------------------------------------------------- // queue_t // ---------------------------------------------------------------------------------------- @@ -445,90 +373,95 @@ namespace netlist #endif } - void netlist_t::print_stats() const { if (m_use_stats) { - std::vector index; - for (size_t i=0; i < m_state.m_devices.size(); i++) - index.push_back(i); - - std::sort(index.begin(), index.end(), - [&](size_t i1, size_t i2) { return m_state.m_devices[i1].second->stats()->m_stat_total_time.total() < m_state.m_devices[i2].second->stats()->m_stat_total_time.total(); }); - - plib::pperftime_t::type total_time(0); - plib::pperftime_t::ctype total_count(0); - - for (auto & j : index) - { - auto *entry = m_state.m_devices[j].second.get(); - auto *stats = entry->stats(); - log().verbose("Device {1:20} : {2:12} {3:12} {4:15} {5:12}", entry->name(), - stats->m_stat_call_count(), stats->m_stat_total_time.count(), - stats->m_stat_total_time.total(), stats->m_stat_inc_active()); - total_time += stats->m_stat_total_time.total(); - total_count += stats->m_stat_total_time.count(); - } - - log().verbose("Total calls : {1:12} {2:12} {3:12}", total_count, - total_time, total_time / static_cast(total_count ? total_count : 1)); - - log().verbose("Total loop {1:15}", m_stat_mainloop()); - log().verbose("Total time {1:15}", total_time); - - // FIXME: clang complains about unreachable code without - const auto clang_workaround_unreachable_code = NL_USE_QUEUE_STATS; - if (clang_workaround_unreachable_code) - { - // Only one serialization should be counted in total time - // But two are contained in m_stat_mainloop - plib::pperftime_t overhead; - plib::pperftime_t test; - { - auto overhead_guard(overhead.guard()); - for (int j=0; j<100000;j++) - { - auto test_guard(test.guard()); - } - } - - plib::pperftime_t::type total_overhead = overhead() - * static_cast::type>(total_count) - / static_cast::type>(200000); - - log().verbose("Queue Pushes {1:15}", m_queue.m_prof_call()); - log().verbose("Queue Moves {1:15}", m_queue.m_prof_sortmove()); - log().verbose("Queue Removes {1:15}", m_queue.m_prof_remove()); - log().verbose("Queue Retimes {1:15}", m_queue.m_prof_retime()); - log().verbose(""); - - log().verbose("Take the next lines with a grain of salt. They depend on the measurement implementation."); - log().verbose("Total overhead {1:15}", total_overhead); - plib::pperftime_t::type overhead_per_pop = (m_stat_mainloop()-2*total_overhead - (total_time - total_overhead)) - / static_cast::type>(m_queue.m_prof_call()); - log().verbose("Overhead per pop {1:11}", overhead_per_pop ); - log().verbose(""); - } - - auto trigger = total_count * 200 / 1000000; // 200 ppm - for (auto &entry : m_state.m_devices) - { - auto *ep = entry.second.get(); - auto *stats = ep->stats(); - // Factor of 3 offers best performace increase - if (stats->m_stat_inc_active() > 3 * stats->m_stat_total_time.count() - && stats->m_stat_inc_active() > trigger) - log().verbose("HINT({}, NO_DEACTIVATE) // {} {} {}", ep->name(), - static_cast(stats->m_stat_inc_active()) / static_cast(stats->m_stat_total_time.count()), - stats->m_stat_inc_active(), stats->m_stat_total_time.count()); - } - log().verbose(""); + netlist_state_t::stats_info si{m_queue, m_stat_mainloop, m_perf_out_processed}; + m_state.print_stats(si); } log().verbose("Current pool memory allocated: {1:12} kB", nlstate().pool().cur_alloc() >> 10); log().verbose("Maximum pool memory allocated: {1:12} kB", nlstate().pool().max_alloc() >> 10); } + void netlist_state_t::print_stats(stats_info &si) const + { + std::vector index; + for (size_t i=0; i < this->m_devices.size(); i++) + index.push_back(i); + + std::sort(index.begin(), index.end(), + [&](size_t i1, size_t i2) { return this->m_devices[i1].second->stats()->m_stat_total_time.total() < this->m_devices[i2].second->stats()->m_stat_total_time.total(); }); + + plib::pperftime_t::type total_time(0); + plib::pperftime_t::ctype total_count(0); + + for (auto & j : index) + { + auto *entry = this->m_devices[j].second.get(); + auto *stats = entry->stats(); + log().verbose("Device {1:20} : {2:12} {3:12} {4:15} {5:12}", entry->name(), + stats->m_stat_call_count(), stats->m_stat_total_time.count(), + stats->m_stat_total_time.total(), stats->m_stat_inc_active()); + total_time += stats->m_stat_total_time.total(); + total_count += stats->m_stat_total_time.count(); + } + + log().verbose("Total calls : {1:12} {2:12} {3:12}", total_count, + total_time, total_time / static_cast(total_count ? total_count : 1)); + + log().verbose("Total loop {1:15}", si.m_stat_mainloop()); + log().verbose("Total time {1:15}", total_time); + + // FIXME: clang complains about unreachable code without + const auto clang_workaround_unreachable_code = NL_USE_QUEUE_STATS; + if (clang_workaround_unreachable_code) + { + // Only one serialization should be counted in total time + // But two are contained in m_stat_mainloop + plib::pperftime_t overhead; + plib::pperftime_t test; + { + auto overhead_guard(overhead.guard()); + for (int j=0; j<100000;j++) + { + auto test_guard(test.guard()); + } + } + + plib::pperftime_t::type total_overhead = overhead() + * static_cast::type>(total_count) + / static_cast::type>(200000); + + log().verbose("Queue Pushes {1:15}", si.m_queue.m_prof_call()); + log().verbose("Queue Moves {1:15}", si.m_queue.m_prof_sortmove()); + log().verbose("Queue Removes {1:15}", si.m_queue.m_prof_remove()); + log().verbose("Queue Retimes {1:15}", si.m_queue.m_prof_retime()); + log().verbose(""); + + log().verbose("Take the next lines with a grain of salt. They depend on the measurement implementation."); + log().verbose("Total overhead {1:15}", total_overhead); + plib::pperftime_t::type overhead_per_pop = (si.m_stat_mainloop()-2*total_overhead - (total_time - total_overhead)) + / static_cast::type>(si.m_queue.m_prof_call()); + log().verbose("Overhead per pop {1:11}", overhead_per_pop ); + log().verbose(""); + } + + auto trigger = total_count * 200 / 1000000; // 200 ppm + for (auto &entry : this->m_devices) + { + auto *ep = entry.second.get(); + auto *stats = ep->stats(); + // Factor of 3 offers best performace increase + if (stats->m_stat_inc_active() > 3 * stats->m_stat_total_time.count() + && stats->m_stat_inc_active() > trigger) + log().verbose("HINT({}, NO_DEACTIVATE) // {} {} {}", ep->name(), + static_cast(stats->m_stat_inc_active()) / static_cast(stats->m_stat_total_time.count()), + stats->m_stat_inc_active(), stats->m_stat_total_time.count()); + } + log().verbose(""); + } + core_device_t *netlist_state_t::get_single_device(const pstring &classname, bool (*cc)(core_device_t *)) const { core_device_t *ret = nullptr; @@ -630,76 +563,49 @@ namespace netlist device_t::device_t(netlist_state_t &owner, const pstring &name) : base_device_t(owner, name) + , m_model(*this, "MODEL", pstring(NETLIST_DEFAULT_LOGIC_FAMILY)) { - // FIXME: this needs debugging! + set_logic_family(state().setup().family_from_model(m_model())); if (logic_family() == nullptr) - { - //printf("Issue with 1 %s\n", this->name().c_str()); - set_logic_family(family_TTL()); - } + throw nl_exception(MF_NULLPTR_FAMILY(this->name(), m_model())); } device_t::device_t(netlist_state_t &owner, const pstring &name, const pstring &model) : base_device_t(owner, name) + , m_model(*this, "MODEL", model) { - //printf("In 1a %s: %s\n", this->name().c_str(), model.c_str()); - set_logic_family(state().setup().family_from_model(model)); //printf("%s %f %f\n", this->name().c_str(), logic_family()->R_low(), logic_family()->R_high()); - // FIXME: this needs debugging! + set_logic_family(state().setup().family_from_model(m_model())); if (logic_family() == nullptr) - { - printf("Issue with 1a %s\n", this->name().c_str()); - set_logic_family(family_TTL()); - } + throw nl_exception(MF_NULLPTR_FAMILY(this->name(), m_model())); } device_t::device_t(netlist_state_t &owner, const pstring &name, const logic_family_desc_t *desc) : base_device_t(owner, name) + , m_model(*this, "MODEL", pstring("")) { set_logic_family(desc); - // FIXME: this needs debugging! if (logic_family() == nullptr) - { - printf("Issue with 1b %s\n", this->name().c_str()); - set_logic_family(family_TTL()); - } + throw nl_exception(MF_NULLPTR_FAMILY(this->name(), "")); } device_t::device_t(device_t &owner, const pstring &name) : base_device_t(owner, name) + , m_model(*this, "MODEL", pstring("")) { set_logic_family(owner.logic_family()); - //printf("%s %f %f\n", this->name().c_str(), logic_family()->R_low(), logic_family()->R_high()); if (logic_family() == nullptr) - { - printf("Issue with 2 %s\n", this->name().c_str()); - set_logic_family(family_TTL()); - } + throw nl_exception(MF_NULLPTR_FAMILY(this->name(), "")); } device_t::device_t(device_t &owner, const pstring &name, const pstring &model) : base_device_t(owner, name) + , m_model(*this, "MODEL", model) { - set_logic_family(state().setup().family_from_model(model)); - //printf("%s %f %f\n", this->name().c_str(), logic_family()->R_low(), logic_family()->R_high()); + set_logic_family(state().setup().family_from_model(m_model())); if (logic_family() == nullptr) - { - printf("Issue with 3 %s\n", this->name().c_str()); - set_logic_family(family_TTL()); - } - } - - device_t::device_t(device_t &owner, const pstring &name, const logic_family_desc_t *desc) - : base_device_t(owner, name) - { - set_logic_family(desc); - //printf("%s %f %f\n", this->name().c_str(), logic_family()->R_low(), logic_family()->R_high()); - if (logic_family() == nullptr) - { - printf("Issue with 3 %s\n", this->name().c_str()); - set_logic_family(family_TTL()); - } + throw nl_exception(MF_NULLPTR_FAMILY(this->name(), m_model())); } // ---------------------------------------------------------------------------------------- @@ -742,7 +648,7 @@ namespace netlist auto *p = dynamic_cast(this); if (p != nullptr) - p->m_cur_Analog = nlconst::zero(); + p->set_Q_Analog(nlconst::zero()); // rebuild m_list and reset terminals to active or analog out state @@ -833,12 +739,6 @@ namespace netlist { } - logic_t::logic_t(device_t &dev, const pstring &aname, const state_e state, - nldelegate delegate) - : core_terminal_t(dev, aname, state, delegate) - { - } - // ---------------------------------------------------------------------------------------- // terminal_t // ---------------------------------------------------------------------------------------- @@ -868,6 +768,29 @@ namespace netlist // net_output_t // ---------------------------------------------------------------------------------------- + // ----------------------------------------------------------------------------- + // logic_t + // ----------------------------------------------------------------------------- + + logic_t::logic_t(device_t &dev, const pstring &aname, const state_e terminal_state, + nldelegate delegate) + : core_terminal_t(dev, aname, terminal_state, delegate) + , logic_family_t(dev.logic_family()) + { + } + + // ----------------------------------------------------------------------------- + // logic_input_t + // ----------------------------------------------------------------------------- + + logic_input_t::logic_input_t(device_t &dev, const pstring &aname, + nldelegate delegate) + : logic_t(dev, aname, STATE_INP_ACTIVE, delegate) + { + state().setup().register_term(*this); + } + + // ---------------------------------------------------------------------------------------- // logic_output_t // ---------------------------------------------------------------------------------------- @@ -878,7 +801,6 @@ namespace netlist { this->set_net(&m_my_net); state().register_net(owned_pool_ptr(&m_my_net, false)); - set_logic_family(dev.logic_family()); state().setup().register_term(*this); } @@ -919,18 +841,6 @@ namespace netlist net().set_Q_Analog(val); } - // ----------------------------------------------------------------------------- - // logic_input_t - // ----------------------------------------------------------------------------- - - logic_input_t::logic_input_t(device_t &dev, const pstring &aname, - nldelegate delegate) - : logic_t(dev, aname, STATE_INP_ACTIVE, delegate) - { - set_logic_family(dev.logic_family()); - state().setup().register_term(*this); - } - // ---------------------------------------------------------------------------------------- // Parameters ... // ---------------------------------------------------------------------------------------- diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index 169def605b3..86bccb432ac 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -279,7 +279,11 @@ namespace netlist class logic_family_desc_t { public: - logic_family_desc_t(); + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init, modernize-use-equals-default) + logic_family_desc_t() + { + } + PCOPYASSIGNMOVE(logic_family_desc_t, delete) @@ -326,6 +330,7 @@ namespace netlist { public: logic_family_t() : m_logic_family(nullptr) {} + logic_family_t(const logic_family_desc_t *d) : m_logic_family(d) {} PCOPYASSIGNMOVE(logic_family_t, delete) const logic_family_desc_t *logic_family() const noexcept { return m_logic_family; } @@ -337,9 +342,6 @@ namespace netlist const logic_family_desc_t *m_logic_family; }; - const logic_family_desc_t *family_TTL(); ///< logic family for TTL devices. - const logic_family_desc_t *family_CD4XXX(); ///< logic family for CD4XXX CMOS devices. - /// \brief A persistent variable template. /// Use the state_var template to define a variable whose value is saved. /// Within a device definition use @@ -891,14 +893,10 @@ namespace netlist { public: logic_t(device_t &dev, const pstring &aname, - state_e state, nldelegate delegate = nldelegate()); + state_e terminal_state, nldelegate delegate = nldelegate()); logic_net_t & net() noexcept; const logic_net_t & net() const noexcept; - - protected: - - private: }; // ----------------------------------------------------------------------------- @@ -970,8 +968,6 @@ namespace netlist using list_t = std::vector; - friend class detail::net_t; - analog_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *railterminal = nullptr); nl_fptype Q_Analog() const noexcept { return m_cur_Analog; } @@ -1348,14 +1344,14 @@ namespace netlist device_t(netlist_state_t &owner, const pstring &name); device_t(netlist_state_t &owner, const pstring &name, const pstring &model); + // only needed by proxies device_t(netlist_state_t &owner, const pstring &name, const logic_family_desc_t *desc); device_t(device_t &owner, const pstring &name); + // pass in a default model - this may be overwritten by PARAM(DEVICE.MODEL, "XYZ(...)") device_t(device_t &owner, const pstring &name, const pstring &model); - device_t(device_t &owner, const pstring &name, - const logic_family_desc_t *desc); PCOPYASSIGNMOVE(device_t, delete) @@ -1366,6 +1362,8 @@ namespace netlist NETLIB_UPDATEI() { } NETLIB_UPDATE_TERMINALSI() { } + private: + param_model_t m_model; }; namespace detail { @@ -1440,8 +1438,6 @@ namespace netlist /// virtual ~netlist_state_t() noexcept = default; - friend class netlist_t; // allow access to private members - template static bool check_class(core_device_t *p) noexcept { @@ -1628,9 +1624,21 @@ namespace netlist /// turned on. bool is_extended_validation() const { return m_extended_validation; } - private: + struct stats_info + { + const detail::queue_t &m_queue;// performance + const plib::pperftime_t &m_stat_mainloop; + const plib::pperfcount_t &m_perf_out_processed; + }; + + /// \brief print statistics gathered during run + /// + void print_stats(stats_info &si) const; void reset(); + + private: + detail::net_t *find_net(const pstring &name) const; // FIXME: stale nlmempool m_pool; // must be deleted last! @@ -2045,9 +2053,7 @@ namespace netlist inline solver::matrix_solver_t *analog_t::solver() const noexcept { - if (this->has_net()) - return net().solver(); - return nullptr; + return (this->has_net() ? net().solver() : nullptr); } inline nl_fptype terminal_t::operator ()() const noexcept { return net().Q_Analog(); } @@ -2056,7 +2062,6 @@ namespace netlist { if (!(gt && go && Idr) && (gt || go || Idr)) { - state().log().fatal("Inconsistent nullptrs for terminal {}", name()); throw nl_exception("Inconsistent nullptrs for terminal {}", name()); } diff --git a/src/lib/netlist/nl_config.h b/src/lib/netlist/nl_config.h index 71217627aeb..076ec9b6ba5 100644 --- a/src/lib/netlist/nl_config.h +++ b/src/lib/netlist/nl_config.h @@ -180,7 +180,7 @@ static constexpr const int NETLIST_CLOCK = 1'000'000'000; // FIXME: need a better solution for global constants. -static constexpr const char *NETLIST_DEFAULT_TRUTHTABLE_FAMILY = "74XX"; +static constexpr const char *NETLIST_DEFAULT_LOGIC_FAMILY = "74XX"; /// \brief Floating point types used /// diff --git a/src/lib/netlist/nl_errstr.h b/src/lib/netlist/nl_errstr.h index 149de8566b8..a3b01da321f 100644 --- a/src/lib/netlist/nl_errstr.h +++ b/src/lib/netlist/nl_errstr.h @@ -22,6 +22,7 @@ namespace netlist PERRMSGV(MF_DUPLICATE_NAME_DEVICE_LIST, 1, "Error adding {1} to device list. Duplicate name.") PERRMSGV(MF_UNKNOWN_TYPE_FOR_OBJECT, 1, "Unknown type for object {1},") PERRMSGV(MF_NET_1_DUPLICATE_TERMINAL_2, 2, "net {1}: duplicate terminal {2}") + PERRMSGV(MF_NULLPTR_FAMILY, 2, "Unable to determine family for device {1} from model {2}") PERRMSGV(MF_REMOVE_TERMINAL_1_FROM_NET_2, 2, "Can not remove terminal {1} from net {2}.") PERRMSGV(MF_UNKNOWN_PARAM_TYPE, 1, "Can not determine param_type for {1}") PERRMSGV(MF_ERROR_CONNECTING_1_TO_2, 2, "Error connecting {1} to {2}") @@ -60,6 +61,7 @@ namespace netlist PERRMSGV(MF_PARAM_COUNT_MISMATCH_2, 2, "Parameter count mismatch for {1} - only found {2}") PERRMSGV(MF_PARAM_COUNT_EXCEEDED_2, 2, "Parameter count exceed for {1} - found {2}") PERRMSGV(MF_UNKNOWN_OBJECT_TYPE_1, 1, "Unknown object type {1}") + PERRMSGV(MF_UNKNOWN_FAMILY_TYPE_1, 2, "Unknown family type {1} in model {2}") PERRMSGV(MF_INVALID_NUMBER_CONVERSION_1_2, 2, "Invalid number conversion {1} : {2}") PERRMSGV(MF_INVALID_ENUM_CONVERSION_1_2, 2, "Invalid element found {1} : {2}") PERRMSGV(MF_ADDING_PARAMETER_1_TO_PARAMETER_LIST,1, "Error adding parameter {1} to parameter list") diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp index f98440a7b3f..c9629cd7fc1 100755 --- a/src/lib/netlist/nl_setup.cpp +++ b/src/lib/netlist/nl_setup.cpp @@ -1177,24 +1177,38 @@ nl_fptype models_t::value(const pstring &model, const pstring &entity) return val * factor; } +// FIXME: all this belongs elsewhere + +P_ENUM(family_type, + CUSTOM, + TTL, + MOS, + CMOS, + NMOS, + PMOS); + class logic_family_std_proxy_t : public logic_family_desc_t { public: - logic_family_std_proxy_t() = default; - unique_pool_ptr create_d_a_proxy(netlist_state_t &anetlist, - const pstring &name, const logic_output_t *proxied) const override; - unique_pool_ptr create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, const logic_input_t *proxied) const override; -}; + logic_family_std_proxy_t(family_type ft) + : m_family_type(ft) + { + } -unique_pool_ptr logic_family_std_proxy_t::create_d_a_proxy(netlist_state_t &anetlist, - const pstring &name, const logic_output_t *proxied) const -{ - return anetlist.make_object(anetlist, name, proxied); -} -unique_pool_ptr logic_family_std_proxy_t::create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, const logic_input_t *proxied) const -{ - return anetlist.make_object(anetlist, name, proxied); -} + // FIXME: create proxies based on family type (far future) + unique_pool_ptr create_d_a_proxy(netlist_state_t &anetlist, + const pstring &name, const logic_output_t *proxied) const override + { + return anetlist.make_object(anetlist, name, proxied); + } + + unique_pool_ptr create_a_d_proxy(netlist_state_t &anetlist, const pstring &name, const logic_input_t *proxied) const override + { + return anetlist.make_object(anetlist, name, proxied); + } +private: + family_type m_family_type; +}; /// \brief Class representing the logic families. @@ -1232,19 +1246,19 @@ public: param_model_t::value_t m_ORH; //!< Output output resistance for logic 1 }; + const logic_family_desc_t *setup_t::family_from_model(const pstring &model) { + family_type ft(family_type::CUSTOM); - if (models().value_str(model, "TYPE") == "TTL") - return family_TTL(); - if (models().value_str(model, "TYPE") == "CD4XXX") - return family_CD4XXX(); + if (!ft.set_from_string(models().value_str(model, "TYPE")) || ft == family_type::CUSTOM) + throw nl_exception(MF_UNKNOWN_FAMILY_TYPE_1(models().value_str(model, "TYPE"), model)); auto it = m_nlstate.family_cache().find(model); if (it != m_nlstate.family_cache().end()) return it->second.get(); - auto ret = plib::make_unique(); + auto ret = plib::make_unique(ft); ret->m_low_thresh_PCNT = models().value(model, "IVL"); ret->m_high_thresh_PCNT = models().value(model, "IVH"); diff --git a/src/mame/audio/nl_gamemachine.cpp b/src/mame/audio/nl_gamemachine.cpp index ec039e6ab47..422881a2e1a 100644 --- a/src/mame/audio/nl_gamemachine.cpp +++ b/src/mame/audio/nl_gamemachine.cpp @@ -27,9 +27,9 @@ NETLIST_START(gamemachine) * */ - NET_MODEL("OPENDRAIN FAMILY(OVL=0.0 OVH=0.0 ORL=1.0 ORH=1e12)") - NET_MODEL("TYPE6K FAMILY(OVL=0.05 OVH=0.05 ORL=1.0 ORH=6000)") - NET_MODEL("DIRECTDRIVE FAMILY(OVL=0.05 OVH=0.05 ORL=1.0 ORH=1000)") + NET_MODEL("OPENDRAIN FAMILY(TYPE=MOS OVL=0.0 OVH=0.0 ORL=1.0 ORH=1e12)") + NET_MODEL("TYPE6K FAMILY(TYPE=MOS OVL=0.05 OVH=0.05 ORL=1.0 ORH=6000)") + NET_MODEL("DIRECTDRIVE FAMILY(TYPE=MOS OVL=0.05 OVH=0.05 ORL=1.0 ORH=1000)") LOGIC_INPUT(P08, 1, "OPENDRAIN") LOGIC_INPUT(P09, 1, "OPENDRAIN") diff --git a/src/mame/audio/nl_kidniki.cpp b/src/mame/audio/nl_kidniki.cpp index bc7f206a2c1..f30657a2086 100644 --- a/src/mame/audio/nl_kidniki.cpp +++ b/src/mame/audio/nl_kidniki.cpp @@ -430,7 +430,7 @@ NETLIST_START(kidniki) ALIAS(I_SINH0, SINH_DUMMY.2) #endif - NET_MODEL("AY8910PORT FAMILY(OVL=0.05 OVH=0.05 ORL=100.0 ORH=0.5k)") + NET_MODEL("AY8910PORT FAMILY(TYPE=NMOS OVL=0.05 OVH=0.05 ORL=100.0 ORH=0.5k)") LOGIC_INPUT(I_SD0, 1, "AY8910PORT") LOGIC_INPUT(I_BD0, 1, "AY8910PORT") diff --git a/src/mame/audio/nl_zac1b11142.cpp b/src/mame/audio/nl_zac1b11142.cpp index 30992944873..c9912468632 100644 --- a/src/mame/audio/nl_zac1b11142.cpp +++ b/src/mame/audio/nl_zac1b11142.cpp @@ -357,7 +357,7 @@ NETLIST_START(zac1b11142) ALIAS(VCC, I_P5.Q) ALIAS(I_V0.Q, GND) - NET_MODEL("AY8910PORT FAMILY(OVL=0.05 OVH=0.05 ORL=100.0 ORH=0.5k)") + NET_MODEL("AY8910PORT FAMILY(TYPE=NMOS OVL=0.05 OVH=0.05 ORL=100.0 ORH=0.5k)") // AY-3-8910 4G/4H digital outputs LOGIC_INPUT(I_IOA0, 1, "AY8910PORT")