diff options
author | 2020-05-22 21:07:24 +0200 | |
---|---|---|
committer | 2020-05-24 10:48:05 +0200 | |
commit | fff7f6ef55f93ba53ceea798d1c65a9910c41f27 (patch) | |
tree | 25860bda071abfc975d4f241691f54b3617df118 /src/lib | |
parent | 80aeecc227454ee5e4205b1a700cbaa64db3d0bc (diff) |
netlist: Better integretation of INT128. (nw)
Also some minor optimisations bringing pong and breakout to previous
performance.
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/netlist/devices/nlid_truthtable.h | 30 | ||||
-rw-r--r-- | src/lib/netlist/nl_base.h | 14 | ||||
-rw-r--r-- | src/lib/netlist/plib/ptime.h | 22 | ||||
-rw-r--r-- | src/lib/netlist/plib/ptypes.h | 19 |
4 files changed, 65 insertions, 20 deletions
diff --git a/src/lib/netlist/devices/nlid_truthtable.h b/src/lib/netlist/devices/nlid_truthtable.h index fbb93d5b3ff..2e8ae3fe348 100644 --- a/src/lib/netlist/devices/nlid_truthtable.h +++ b/src/lib/netlist/devices/nlid_truthtable.h @@ -26,7 +26,7 @@ namespace devices { public: - using type_t = typename plib::least_type_for_bits<m_NO + m_NI>::type; + using type_t = typename plib::fast_type_for_bits<m_NO + m_NI>::type; static constexpr const std::size_t m_num_bits = m_NI; static constexpr const std::size_t m_size = (1 << (m_num_bits)); @@ -161,16 +161,18 @@ namespace devices m_ign = outstate >> m_NO; - const std::size_t timebase(nstate * m_NO); - const auto *t(&m_ttp.m_timing_index[timebase]); - const auto *tim = m_ttp.m_timing_nt.data(); + const auto *t(&m_ttp.m_timing_index[nstate * m_NO]); if (doOUT) - for (std::size_t i = 0; i < m_NO; ++i) - m_Q[i].push((out >> i) & 1, tim[t[i]]); + //for (std::size_t i = 0; i < m_NO; ++i) + // m_Q[i].push((out >> i) & 1, tim[t[i]]); + this->push(out, t); else + { + const auto *tim = m_ttp.m_timing_nt.data(); for (std::size_t i = 0; i < m_NO; ++i) m_Q[i].set_Q_time((out >> i) & 1, mt + tim[t[i]]); + } ign = m_ign; for (auto I = m_I.begin(); ign != 0; ign >>= 1, ++I) @@ -181,6 +183,22 @@ namespace devices #endif } + template<typename T> + void push(const T &v, const std::uint_least8_t * t) + { + if (m_NO >= 1) m_Q[0].push((v >> 0) & 1, m_ttp.m_timing_nt[t[0]]); + if (m_NO >= 2) m_Q[1].push((v >> 1) & 1, m_ttp.m_timing_nt[t[1]]); + if (m_NO >= 3) m_Q[2].push((v >> 2) & 1, m_ttp.m_timing_nt[t[2]]); + if (m_NO >= 4) m_Q[3].push((v >> 3) & 1, m_ttp.m_timing_nt[t[3]]); + if (m_NO >= 5) m_Q[4].push((v >> 4) & 1, m_ttp.m_timing_nt[t[4]]); + if (m_NO >= 6) m_Q[5].push((v >> 5) & 1, m_ttp.m_timing_nt[t[5]]); + if (m_NO >= 7) m_Q[6].push((v >> 6) & 1, m_ttp.m_timing_nt[t[6]]); + if (m_NO >= 8) m_Q[7].push((v >> 7) & 1, m_ttp.m_timing_nt[t[7]]); + for (std::size_t i = 8; i < m_NO; i++) + m_Q[i].push((v >> i) & 1, m_ttp.m_timing_nt[t[i]]); + } + + plib::uninitialised_array_t<logic_input_t, m_NI> m_I; plib::uninitialised_array_t<logic_output_t, m_NO> m_Q; diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h index ad5a85725af..b6d215510dc 100644 --- a/src/lib/netlist/nl_base.h +++ b/src/lib/netlist/nl_base.h @@ -2092,11 +2092,9 @@ namespace netlist (*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) + template<typename T> + void push(const T &v, const netlist_time * 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]); @@ -2109,6 +2107,14 @@ namespace netlist (*this)[i].push((v >> i) & 1, t[i]); } + 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"); + + push(v, t.data()); + } + void set_tristate(netlist_sig_t v, netlist_time ts_off_on, netlist_time ts_on_off) noexcept { diff --git a/src/lib/netlist/plib/ptime.h b/src/lib/netlist/plib/ptime.h index 839b8e95dbd..655fb84caeb 100644 --- a/src/lib/netlist/plib/ptime.h +++ b/src/lib/netlist/plib/ptime.h @@ -117,32 +117,40 @@ namespace plib return ptime(m_time / rhs); } - friend constexpr bool operator<(const ptime &lhs, const ptime &rhs) noexcept + template <typename O> + friend constexpr bool operator<(const ptime &lhs, const ptime<O, RES> &rhs) noexcept { - return (lhs.m_time < rhs.m_time); + static_assert(ptime_le<ptime<O, RES>, ptime>::value, "Invalid ptime type"); + return (lhs.m_time < rhs.as_raw()); + //return (lhs.m_time < rhs.m_time); } - friend constexpr bool operator>(const ptime &lhs, const ptime &rhs) noexcept + template <typename O> + friend constexpr bool operator>(const ptime &lhs, const ptime<O, RES> &rhs) noexcept { return (rhs < lhs); } - friend constexpr bool operator<=(const ptime &lhs, const ptime &rhs) noexcept + template <typename O> + friend constexpr bool operator<=(const ptime &lhs, const ptime<O, RES> &rhs) noexcept { return !(lhs > rhs); } - friend constexpr bool operator>=(const ptime &lhs, const ptime &rhs) noexcept + template <typename O> + friend constexpr bool operator>=(const ptime &lhs, const ptime<O, RES> &rhs) noexcept { return !(lhs < rhs); } - friend constexpr bool operator==(const ptime &lhs, const ptime &rhs) noexcept + template <typename O> + friend constexpr bool operator==(const ptime &lhs, const ptime<O, RES> &rhs) noexcept { return lhs.m_time == rhs.m_time; } - friend constexpr bool operator!=(const ptime &lhs, const ptime &rhs) noexcept + template <typename O> + friend constexpr bool operator!=(const ptime &lhs, const ptime<O, RES> &rhs) noexcept { return !(lhs == rhs); } diff --git a/src/lib/netlist/plib/ptypes.h b/src/lib/netlist/plib/ptypes.h index 16c0a5575a3..537eda2cc6b 100644 --- a/src/lib/netlist/plib/ptypes.h +++ b/src/lib/netlist/plib/ptypes.h @@ -95,7 +95,12 @@ namespace plib bits <= 8 ? 1 : bits <= 16 ? 2 : bits <= 32 ? 4 : +#if (PHAS_INT128) + bits <= 64 ? 8 : + 16 +#else 8 +#endif }; }; @@ -104,12 +109,20 @@ namespace plib template<> struct least_type_for_size<2> { using type = uint_least16_t; }; template<> struct least_type_for_size<4> { using type = uint_least32_t; }; template<> struct least_type_for_size<8> { using type = uint_least64_t; }; +#if (PHAS_INT128) + template<> struct least_type_for_size<16> { using type = UINT128; }; +#endif + // This is different to the standard library. Mappings provided in stdint + // are not always fastest. 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<1> { using type = uint32_t; }; + template<> struct fast_type_for_size<2> { using type = uint32_t; }; + template<> struct fast_type_for_size<4> { using type = uint32_t; }; template<> struct fast_type_for_size<8> { using type = uint_fast64_t; }; +#if (PHAS_INT128) + template<> struct fast_type_for_size<16> { using type = UINT128; }; +#endif template<unsigned bits> struct least_type_for_bits |