diff options
Diffstat (limited to 'src/lib/netlist/devices/nlid_truthtable.h')
-rw-r--r-- | src/lib/netlist/devices/nlid_truthtable.h | 175 |
1 files changed, 86 insertions, 89 deletions
diff --git a/src/lib/netlist/devices/nlid_truthtable.h b/src/lib/netlist/devices/nlid_truthtable.h index 311f5ebd8ca..1217d7ee873 100644 --- a/src/lib/netlist/devices/nlid_truthtable.h +++ b/src/lib/netlist/devices/nlid_truthtable.h @@ -10,9 +10,9 @@ #ifndef NLID_TRUTHTABLE_H_ #define NLID_TRUTHTABLE_H_ -#include "../nl_setup.h" -#include "../nl_base.h" -#include "../plib/putil.h" +#include "netlist/nl_base.h" +#include "netlist/nl_setup.h" +#include "plib/putil.h" #define NETLIB_TRUTHTABLE(cname, nIN, nOUT) \ class NETLIB_NAME(cname) : public nld_truthtable_t<nIN, nOUT> \ @@ -29,17 +29,9 @@ namespace netlist { - namespace devices - { +namespace devices +{ -#if 0 - template<unsigned bits> struct uint_for_size { typedef uint_least32_t type; }; - template<unsigned bits> - struct need_bytes_for_bits - { - enum { value = 4 }; - }; -#else template<unsigned bits> struct need_bytes_for_bits { @@ -52,11 +44,35 @@ namespace netlist }; template<unsigned bits> struct uint_for_size; - template<> struct uint_for_size<1> { typedef uint_least8_t type; }; - template<> struct uint_for_size<2> { typedef uint_least16_t type; }; - template<> struct uint_for_size<4> { typedef uint_least32_t type; }; - template<> struct uint_for_size<8> { typedef uint_least64_t type; }; -#endif + template<> struct uint_for_size<1> { using type = uint_least8_t; }; + template<> struct uint_for_size<2> { using type = uint_least16_t; }; + template<> struct uint_for_size<4> { using type = uint_least32_t; }; + template<> struct uint_for_size<8> { using type = uint_least64_t; }; + + template<std::size_t NUM, typename R> + struct aa + { + template<typename T> + R f(T &arr, const R ign) + { + R r = aa<NUM-1, R>().f(arr, ign); + if (ign & (1 << (NUM-1))) + arr[NUM-1].activate(); + return r | (arr[NUM-1]() << (NUM-1)); + } + }; + + template<typename R> + struct aa<1, R> + { + template<typename T> + R f(T &arr, const R ign) + { + if ((ign & 1)) + arr[0].activate(); + return arr[0](); + } + }; template<std::size_t m_NI, std::size_t m_NO> NETLIB_OBJECT(truthtable_t) @@ -65,22 +81,23 @@ namespace netlist detail::family_setter_t m_fam; public: - typedef typename uint_for_size<need_bytes_for_bits<m_NO + m_NI>::value>::type type_t; + using type_t = typename uint_for_size<need_bytes_for_bits<m_NO + m_NI>::value>::type; static constexpr const std::size_t m_num_bits = m_NI; static constexpr const std::size_t m_size = (1 << (m_num_bits)); static constexpr const type_t m_outmask = ((1 << m_NO) - 1); - static constexpr const std::size_t m_min_devices_for_deactivate = 2; struct truthtable_t { truthtable_t() - : m_initialized(false) + : m_timing_index{0} + , m_initialized(false) {} + + std::array<type_t, m_size> m_out_state; + std::array<uint_least8_t, m_size * m_NO> m_timing_index; + std::array<netlist_time, 16> m_timing_nt; bool m_initialized; - type_t m_outs[m_size]; - uint_least8_t m_timing[m_size * m_NO]; - netlist_time m_timing_nt[16]; }; template <class C> @@ -90,7 +107,6 @@ namespace netlist : device_t(owner, name) , m_fam(*this, fam) , m_ign(*this, "m_ign", 0) - , m_active(*this, "m_active", 1) , m_ttp(ttp) { init(desc); @@ -100,13 +116,14 @@ namespace netlist NETLIB_RESETI() { - m_active = 0; + int active_outputs = 0; m_ign = 0; for (auto &i : m_I) i.activate(); for (auto &q : m_Q) if (q.has_net() && q.net().num_cons() > 0) - m_active++; + active_outputs++; + set_active_outputs(active_outputs); } NETLIB_UPDATEI() @@ -116,28 +133,14 @@ namespace netlist void inc_active() NL_NOEXCEPT override { - if (m_NI >= m_min_devices_for_deactivate) - if (++m_active == 1) - { - process<false>(); - } + process<false>(); } void dec_active() NL_NOEXCEPT override { - /* FIXME: - * Based on current measurements there is no point to disable - * 1 input devices. This should actually be a parameter so that we - * can decide for each individual gate whether it is beneficial to - * ignore deactivation. - */ - if (m_NI >= m_min_devices_for_deactivate) - if (--m_active == 0) - { - for (std::size_t i = 0; i< m_NI; i++) - m_I[i].inactivate(); - m_ign = (1<<m_NI)-1; - } + for (std::size_t i = 0; i< m_NI; i++) + m_I[i].inactivate(); + m_ign = (1<<m_NI)-1; } plib::uninitialised_array_t<logic_input_t, m_NI> m_I; @@ -153,46 +156,44 @@ namespace netlist netlist_time mt(netlist_time::zero()); type_t nstate(0); - if (m_NI >= m_min_devices_for_deactivate) - { - type_t ign(m_ign); - if (!doOUT) - for (std::size_t i = 0; i < m_NI; i++) - { - m_I[i].activate(); - nstate |= (m_I[i]() ? (1 << i) : 0); - mt = std::max(this->m_I[i].net().time(), mt); - } - else - for (std::size_t i = 0; i < m_NI; i++) - { - if ((ign & 1)) - m_I[i].activate(); - nstate |= (m_I[i]() ? (1 << i) : 0); - ign >>= 1; - } - } + type_t ign(m_ign); +#if 1 + if (!doOUT) + for (std::size_t i = 0; i < m_NI; i++) + { + m_I[i].activate(); + //nstate |= (m_I[i]() ? (1 << i) : 0); + nstate |= (m_I[i]() << i); + mt = std::max(this->m_I[i].net().next_scheduled_time(), mt); + } else + for (std::size_t i = 0; i < m_NI; i++) + { + if ((ign & 1)) + m_I[i].activate(); + //nstate |= (m_I[i]() ? (1 << i) : 0); + nstate |= (m_I[i]() << i); + ign >>= 1; + } +#else + if (!doOUT) { - if (!doOUT) - for (std::size_t i = 0; i < m_NI; i++) - { - nstate |= (m_I[i]() ? (1 << i) : 0); - mt = std::max(this->m_I[i].net().time(), mt); - } - else - for (std::size_t i = 0; i < m_NI; i++) - nstate |= (m_I[i]() ? (1 << i) : 0); + nstate = aa<m_NI, type_t>().f(m_I, ~0); + for (std::size_t i = 0; i < m_NI; i++) + mt = std::max(this->m_I[i].net().time(), mt); } + else + nstate = aa<m_NI, type_t>().f(m_I, ign); +#endif - const type_t outstate(m_ttp.m_outs[nstate]); + const type_t outstate(m_ttp.m_out_state[nstate]); type_t out(outstate & m_outmask); m_ign = outstate >> m_NO; const std::size_t timebase(nstate * m_NO); - const auto *t(&m_ttp.m_timing[timebase]); - const auto *tim = m_ttp.m_timing_nt; + const auto *t(&m_ttp.m_timing_index[timebase]); + const auto *tim = m_ttp.m_timing_nt.data(); if (doOUT) for (std::size_t i = 0; i < m_NO; out >>= 1, ++i) @@ -201,18 +202,14 @@ namespace netlist for (std::size_t i = 0; i < m_NO; out >>= 1, ++i) m_Q[i].set_Q_time(out & 1, mt + tim[t[i]]); - if (m_NI >= m_min_devices_for_deactivate) - { - type_t ign(m_ign); - for (auto I = m_I.begin(); ign != 0; ign >>= 1, ++I) - if (ign & 1) - I->inactivate(); - } + ign = m_ign; + for (auto I = m_I.begin(); ign != 0; ign >>= 1, ++I) + if (ign & 1) + I->inactivate(); } /* FIXME: check width */ state_var<type_t> m_ign; - state_var_s32 m_active; const truthtable_t &m_ttp; }; @@ -222,15 +219,15 @@ namespace netlist netlist_base_factory_truthtable_t(const pstring &name, const pstring &classname, const pstring &def_param, const pstring &sourcefile); - virtual ~netlist_base_factory_truthtable_t(); - std::vector<pstring> m_desc; - const logic_family_desc_t *m_family; + pstring m_family_name; + const logic_family_desc_t *m_family_desc; }; - void tt_factory_create(setup_t &setup, tt_desc &desc, const pstring &sourcefile); + /* the returned element is still missing a pointer to the family ... */ + plib::unique_ptr<netlist_base_factory_truthtable_t> tt_factory_create(tt_desc &desc, const pstring &sourcefile); - } //namespace devices +} //namespace devices } // namespace netlist |