diff options
author | 2020-05-21 09:46:57 +0200 | |
---|---|---|
committer | 2020-05-22 01:15:17 +0200 | |
commit | dae6a396c9c79e1ccc6587dc3be1764df62dc61c (patch) | |
tree | 1c0e128525661603a3a95087637768f6e50f6b5a | |
parent | ba232b1c4a6eacddd8ee0e50603f46cdeaf12062 (diff) |
netlist: fix performance decrease. (nw)
-rw-r--r-- | src/lib/netlist/devices/nld_7490.cpp | 75 | ||||
-rw-r--r-- | src/lib/netlist/devices/nld_7492.cpp | 69 | ||||
-rw-r--r-- | src/lib/netlist/devices/nld_7493.cpp | 16 | ||||
-rw-r--r-- | src/lib/netlist/devices/nld_9316.cpp | 23 | ||||
-rw-r--r-- | src/lib/netlist/nl_base.h | 61 | ||||
-rw-r--r-- | src/lib/netlist/plib/ptypes.h | 16 |
6 files changed, 145 insertions, 115 deletions
diff --git a/src/lib/netlist/devices/nld_7490.cpp b/src/lib/netlist/devices/nld_7490.cpp index f38650daeb2..e923232f278 100644 --- a/src/lib/netlist/devices/nld_7490.cpp +++ b/src/lib/netlist/devices/nld_7490.cpp @@ -39,7 +39,40 @@ namespace devices } private: - NETLIB_UPDATEI(); + NETLIB_UPDATEI() + { + const netlist_sig_t new_A = m_A(); + const netlist_sig_t new_B = m_B(); + + if (m_R91() & m_R92()) + { + m_cnt = 9; + m_Q.push(9, delay); + } + else if (m_R1() & m_R2()) + { + m_cnt = 0; + m_Q.push(0, delay); + } + else + { + if (m_last_A && !new_A) // High - Low + { + m_cnt ^= 1; + m_Q[0].push(m_cnt & 1, delay[0]); + } + if (m_last_B && !new_B) // High - Low + { + m_cnt += 2; + if (m_cnt >= 10) + m_cnt &= 1; /* Output A is not reset! */ + m_Q.push(m_cnt, delay); + } + } + m_last_A = new_A; + m_last_B = new_B; + } + NETLIB_RESETI() { m_cnt = 0; @@ -47,12 +80,6 @@ namespace devices m_last_B = 0; } - void update_outputs() noexcept - { - for (std::size_t i=0; i<4; i++) - m_Q[i].push((m_cnt >> i) & 1, delay[i]); - } - logic_input_t m_A; logic_input_t m_B; logic_input_t m_R1; @@ -96,40 +123,6 @@ namespace devices NETLIB_SUB(7490) A; }; - NETLIB_UPDATE(7490) - { - const netlist_sig_t new_A = m_A(); - const netlist_sig_t new_B = m_B(); - - if (m_R91() & m_R92()) - { - m_cnt = 9; - update_outputs(); - } - else if (m_R1() & m_R2()) - { - m_cnt = 0; - update_outputs(); - } - else - { - if (m_last_A && !new_A) // High - Low - { - m_cnt ^= 1; - m_Q[0].push(m_cnt & 1, delay[0]); - } - if (m_last_B && !new_B) // High - Low - { - m_cnt += 2; - if (m_cnt >= 10) - m_cnt &= 1; /* Output A is not reset! */ - update_outputs(); - } - } - m_last_A = new_A; - m_last_B = new_B; - } - NETLIB_DEVICE_IMPL(7490, "TTL_7490", "+A,+B,+R1,+R2,+R91,+R92,@VCC,@GND") NETLIB_DEVICE_IMPL(7490_dip, "TTL_7490_DIP", "") diff --git a/src/lib/netlist/devices/nld_7492.cpp b/src/lib/netlist/devices/nld_7492.cpp index 603daf21588..39dce8217eb 100644 --- a/src/lib/netlist/devices/nld_7492.cpp +++ b/src/lib/netlist/devices/nld_7492.cpp @@ -37,7 +37,37 @@ namespace devices } private: - NETLIB_UPDATEI(); + NETLIB_UPDATEI() + { + const netlist_sig_t new_A = m_A(); + const netlist_sig_t new_B = m_B(); + + if (m_R1() & m_R2()) + { + m_cnt = 0; + m_Q.push(0, delay); + } + else + { + if (m_last_A && !new_A) // High - Low + { + m_cnt ^= 1; + m_Q[0].push(m_cnt & 1, delay[0]); + } + if (m_last_B && !new_B) // High - Low + { + m_cnt += 2; + if (m_cnt == 6) + m_cnt = 8; + if (m_cnt == 14) + m_cnt = 0; + m_Q.push(m_cnt, delay); + } + } + m_last_A = new_A; + m_last_B = new_B; + } + NETLIB_RESETI() { m_cnt = 0; @@ -45,12 +75,6 @@ namespace devices m_last_B = 0; } - void update_outputs() noexcept - { - for (std::size_t i=0; i<4; i++) - m_Q[i].push((m_cnt >> i) & 1, delay[i]); - } - logic_input_t m_A; logic_input_t m_B; logic_input_t m_R1; @@ -92,37 +116,6 @@ namespace devices NETLIB_SUB(7492) A; }; - NETLIB_UPDATE(7492) - { - const netlist_sig_t new_A = m_A(); - const netlist_sig_t new_B = m_B(); - - if (m_R1() & m_R2()) - { - m_cnt = 0; - update_outputs(); - } - else - { - if (m_last_A && !new_A) // High - Low - { - m_cnt ^= 1; - m_Q[0].push(m_cnt & 1, delay[0]); - } - if (m_last_B && !new_B) // High - Low - { - m_cnt += 2; - if (m_cnt == 6) - m_cnt = 8; - if (m_cnt == 14) - m_cnt = 0; - update_outputs(); - } - } - m_last_A = new_A; - m_last_B = new_B; - } - NETLIB_DEVICE_IMPL(7492, "TTL_7492", "+A,+B,+R1,+R2,@VCC,@GND") NETLIB_DEVICE_IMPL(7492_dip, "TTL_7492_DIP", "") diff --git a/src/lib/netlist/devices/nld_7493.cpp b/src/lib/netlist/devices/nld_7493.cpp index ec2fd9f89fc..2d6e16bb56e 100644 --- a/src/lib/netlist/devices/nld_7493.cpp +++ b/src/lib/netlist/devices/nld_7493.cpp @@ -88,9 +88,7 @@ namespace netlist , m_CLKA(*this, "CLKA", NETLIB_DELEGATE(7493, updA)) , m_CLKB(*this, "CLKB", NETLIB_DELEGATE(7493, updB)) , m_QA(*this, "QA") - , m_QB(*this, "QB") - , m_QC(*this, "QC") - , m_QD(*this, "QD") + , m_QB(*this, {"QB", "QC", "QD"}) , m_power_pins(*this) { } @@ -116,8 +114,6 @@ namespace netlist m_CLKB.inactivate(); m_QA.push(0, NLTIME_FROM_NS(40)); m_QB.push(0, NLTIME_FROM_NS(40)); - m_QC.push(0, NLTIME_FROM_NS(40)); - m_QD.push(0, NLTIME_FROM_NS(40)); m_a = m_bcd = 0; } } @@ -131,9 +127,9 @@ namespace netlist NETLIB_HANDLERI(updB) { const auto cnt(++m_bcd &= 0x07); - m_QD.push((cnt >> 2) & 1, out_delay3); - m_QC.push((cnt >> 1) & 1, out_delay2); - m_QB.push(cnt & 1, out_delay); + m_QB[2].push((cnt >> 2) & 1, out_delay3); + m_QB[1].push((cnt >> 1) & 1, out_delay2); + m_QB[0].push(cnt & 1, out_delay); } logic_input_t m_R1; @@ -146,9 +142,7 @@ namespace netlist logic_input_t m_CLKB; logic_output_t m_QA; - logic_output_t m_QB; - logic_output_t m_QC; - logic_output_t m_QD; + object_array_t<logic_output_t, 3> m_QB; nld_power_pins m_power_pins; }; diff --git a/src/lib/netlist/devices/nld_9316.cpp b/src/lib/netlist/devices/nld_9316.cpp index 7404370205c..f4f7dbee412 100644 --- a/src/lib/netlist/devices/nld_9316.cpp +++ b/src/lib/netlist/devices/nld_9316.cpp @@ -4,7 +4,6 @@ * nld_9316.c * */ - #include "nld_9316.h" #include "netlist/nl_base.h" @@ -31,7 +30,9 @@ namespace netlist , m_ABCD(*this, {"A", "B", "C", "D"}, NETLIB_DELEGATE(9316_base, abcd)) , m_Q(*this, { "QA", "QB", "QC", "QD" }) , m_cnt(*this, "m_cnt", 0) - //, m_abcd(*this, "m_abcd", 0) + , m_abcd(*this, "m_abcd", 0) + , m_loadq(*this, "m_loadq", 0) + , m_ent(*this, "m_ent", 0) , m_power_pins(*this) { } @@ -41,14 +42,16 @@ namespace netlist { m_CLK.set_state(logic_t::STATE_INP_LH); m_cnt = 0; - //m_abcd = 0; + m_abcd = 0; } NETLIB_UPDATEI() { const auto CLRQ(m_CLRQ()); + m_ent = m_ENT(); + m_loadq = m_LOADQ(); - if (((m_LOADQ() ^ 1) || (m_ENT() && m_ENP())) && (!ASYNC || CLRQ)) + if (((m_loadq ^ 1) || (m_ent && m_ENP())) && (!ASYNC || CLRQ)) { m_CLK.activate_lh(); } @@ -61,7 +64,7 @@ namespace netlist m_Q.push(m_cnt, NLTIME_FROM_NS(36)); } } - m_RC.push(m_ENT() && (m_cnt == MAXCNT), NLTIME_FROM_NS(27)); + m_RC.push(m_ent && (m_cnt == MAXCNT), NLTIME_FROM_NS(27)); } @@ -75,8 +78,8 @@ namespace netlist else { //const auto cnt = (m_LOADQ() ? (m_cnt + 1) & MAXCNT: m_abcd); - const auto cnt = (m_LOADQ() ? (m_cnt + 1) & MAXCNT: m_ABCD()); - m_RC.push(m_ENT() && (cnt == MAXCNT), NLTIME_FROM_NS(27)); + const auto cnt = (m_loadq ? (m_cnt + 1) & MAXCNT: m_abcd); + m_RC.push(m_ent && (cnt == MAXCNT), NLTIME_FROM_NS(27)); m_Q.push(cnt, NLTIME_FROM_NS(20)); m_cnt = static_cast<unsigned>(cnt); } @@ -84,7 +87,7 @@ namespace netlist NETLIB_HANDLERI(abcd) { - //m_abcd = static_cast<unsigned>(m_ABCD()); + m_abcd = static_cast<unsigned>(m_ABCD()); } logic_input_t m_CLK; @@ -103,7 +106,9 @@ namespace netlist /* counter state */ state_var<unsigned> m_cnt; /* cached pins */ - //state_var<unsigned> m_abcd; + state_var<unsigned> m_abcd; + state_var_sig m_loadq; + state_var_sig m_ent; nld_power_pins m_power_pins; }; diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index db688fac1e6..8f3a7683f0d 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -2027,7 +2027,6 @@ namespace netlist template<class D, std::size_t ND> object_array_t(D &dev, std::size_t offset, std::size_t qmask, -// const pstring &fmt, std::initializer_list<nldelegate> &delegates) const pstring &fmt, std::array<nldelegate, ND> &&delegates) { passert_always_msg(delegates.size() >= N, "initializer_list size mismatch"); @@ -2045,10 +2044,33 @@ namespace netlist } } + //using value_type = typename plib::fast_type_for_bits<N>::type; + using value_type = std::uint32_t; +#if 0 - //using value_type = typename plib::least_type_for_bits<N>::type; - using value_type = std::uint_fast32_t; + value_type operator ()() + { +#if 0 + if (N <= 8) + return tobits(N, *this); + else +#endif + { + value_type r(0); + for (std::size_t i = 0; i < N; i++) + r = r | static_cast<value_type>((*this)[i]() << i); + return r; + } + } + private: + template <typename T> + static constexpr value_type tobits(std::size_t n, T &a) + { + return (n == 0 ? 0 : (tobits(n-1, a) | static_cast<value_type>(a[n-1]() << (n-1)))); + } + +#else value_type operator ()() { if (N == 1) return e<0>(); @@ -2073,6 +2095,7 @@ namespace netlist private: template <std::size_t P> inline constexpr value_type e() const { return (*this)[P](); } +#endif }; template<std::size_t N> @@ -2082,10 +2105,8 @@ namespace netlist using base_type = object_array_base_t<logic_output_t, N>; using base_type::base_type; - using value_type = std::uint_fast32_t; - //using value_type = typename plib::least_type_for_bits<N>::type; - - void push(value_type v, netlist_time t) + template <typename T> + inline void push(const T &v, const netlist_time &t) { if (N >= 1) (*this)[0].push((v >> 0) & 1, t); if (N >= 2) (*this)[1].push((v >> 1) & 1, t); @@ -2095,18 +2116,33 @@ namespace netlist if (N >= 6) (*this)[5].push((v >> 5) & 1, t); if (N >= 7) (*this)[6].push((v >> 6) & 1, t); if (N >= 8) (*this)[7].push((v >> 7) & 1, t); - for (std::size_t i = 8; i < N; i++) (*this)[i].push((v >> i) & 1, t); } + template<typename T, std::size_t NT> + void push(const T &v, const std::array<netlist_time, NT> &t) + { + static_assert(NT >= N, "Not enough timing entries provided"); + + if (N >= 1) (*this)[0].push((v >> 0) & 1, t[0]); + if (N >= 2) (*this)[1].push((v >> 1) & 1, t[1]); + if (N >= 3) (*this)[2].push((v >> 2) & 1, t[2]); + if (N >= 4) (*this)[3].push((v >> 3) & 1, t[3]); + if (N >= 5) (*this)[4].push((v >> 4) & 1, t[4]); + if (N >= 6) (*this)[5].push((v >> 5) & 1, t[5]); + if (N >= 7) (*this)[6].push((v >> 6) & 1, t[6]); + if (N >= 8) (*this)[7].push((v >> 7) & 1, t[7]); + for (std::size_t i = 8; i < N; i++) + (*this)[i].push((v >> i) & 1, t[i]); + } + void set_tristate(bool v, netlist_time ts_off_on, netlist_time ts_on_off) noexcept { for (std::size_t i = 0; i < N; i++) (*this)[i].set_tristate(v, ts_off_on, ts_on_off); } - }; template<std::size_t N> @@ -2116,10 +2152,8 @@ namespace netlist using base_type = object_array_base_t<tristate_output_t, N>; using base_type::base_type; - using value_type = std::uint_fast32_t; - //using value_type = typename plib::least_type_for_bits<N>::type; - - void push(value_type v, netlist_time t) + template <typename T> + inline void push(const T &v, const netlist_time &t) { if (N >= 1) (*this)[0].push((v >> 0) & 1, t); if (N >= 2) (*this)[1].push((v >> 1) & 1, t); @@ -2129,7 +2163,6 @@ namespace netlist if (N >= 6) (*this)[5].push((v >> 5) & 1, t); if (N >= 7) (*this)[6].push((v >> 6) & 1, t); if (N >= 8) (*this)[7].push((v >> 7) & 1, t); - for (std::size_t i = 8; i < N; i++) (*this)[i].push((v >> i) & 1, t); } diff --git a/src/lib/netlist/plib/ptypes.h b/src/lib/netlist/plib/ptypes.h index dc762a51107..16c0a5575a3 100644 --- a/src/lib/netlist/plib/ptypes.h +++ b/src/lib/netlist/plib/ptypes.h @@ -89,7 +89,7 @@ namespace plib #endif template<unsigned bits> - struct least_size_for_bits + struct size_for_bits { enum { value = bits <= 8 ? 1 : @@ -105,10 +105,22 @@ namespace plib template<> struct least_type_for_size<4> { using type = uint_least32_t; }; template<> struct least_type_for_size<8> { using type = uint_least64_t; }; + template<unsigned N> struct fast_type_for_size; + template<> struct fast_type_for_size<1> { using type = uint_fast8_t; }; + template<> struct fast_type_for_size<2> { using type = uint_fast16_t; }; + template<> struct fast_type_for_size<4> { using type = uint_fast32_t; }; + template<> struct fast_type_for_size<8> { using type = uint_fast64_t; }; + template<unsigned bits> struct least_type_for_bits { - using type = typename least_type_for_size<least_size_for_bits<bits>::value>::type; + using type = typename least_type_for_size<size_for_bits<bits>::value>::type; + }; + + template<unsigned bits> + struct fast_type_for_bits + { + using type = typename fast_type_for_size<size_for_bits<bits>::value>::type; }; //============================================================ |