diff options
Diffstat (limited to 'src/lib/netlist/devices/nlid_truthtable.cpp')
-rw-r--r-- | src/lib/netlist/devices/nlid_truthtable.cpp | 141 |
1 files changed, 64 insertions, 77 deletions
diff --git a/src/lib/netlist/devices/nlid_truthtable.cpp b/src/lib/netlist/devices/nlid_truthtable.cpp index bf7d03fe3d7..2221d855880 100644 --- a/src/lib/netlist/devices/nlid_truthtable.cpp +++ b/src/lib/netlist/devices/nlid_truthtable.cpp @@ -6,9 +6,9 @@ */ #include "nlid_truthtable.h" -#include "../plib/plists.h" -#include "../nl_setup.h" -#include "../plib/palloc.h" +#include "netlist/nl_setup.h" +#include "plib/palloc.h" +#include "plib/plists.h" #include <bitset> @@ -24,7 +24,7 @@ namespace netlist template <typename T> struct sbitset { - typedef T type; + using type = T; sbitset() : m_bs(0) { } /* explicit */ sbitset(T v) : m_bs(v) { } @@ -77,8 +77,8 @@ namespace netlist return ret; } - static constexpr sbitset all_bits() { return sbitset(~static_cast<T>(0)); } - static constexpr sbitset no_bits() { return sbitset(static_cast<T>(0)); } + static constexpr const sbitset all_bits() noexcept { return sbitset(~static_cast<T>(0)); } + static constexpr const sbitset no_bits() noexcept{ return sbitset(static_cast<T>(0)); } private: T m_bs; }; @@ -122,8 +122,18 @@ namespace netlist } } - uint_least64_t mask() const { return static_cast<uint_least64_t>(-1); } - + uint_least64_t mask() const + { + switch (m_size) + { + case 8: return static_cast<uint_least8_t>(-1); + case 16: return static_cast<uint_least16_t>(-1); + case 32: return static_cast<uint_least32_t>(-1); + case 64: return static_cast<uint_least64_t>(-1); + default: + return 0; //should never happen + } + } private: void *m_data; size_t m_size; @@ -134,7 +144,7 @@ namespace netlist truthtable_parser(unsigned NO, unsigned NI, bool *initialized, packed_int outs, uint_least8_t *timing, netlist_time *timing_nt) : m_NO(NO), m_NI(NI), m_initialized(initialized), - m_outs(outs), m_timing(timing), m_timing_nt(timing_nt), + m_out_state(outs), m_timing(timing), m_timing_nt(timing_nt), m_num_bits(m_NI), m_size(1 << (m_num_bits)) { @@ -151,7 +161,7 @@ namespace netlist unsigned m_NO; unsigned m_NI; bool *m_initialized; - packed_int m_outs; + packed_int m_out_state; uint_least8_t *m_timing; netlist_time *m_timing_nt; @@ -178,51 +188,27 @@ namespace netlist nl_assert_always(io.size() == 2, "too many '|'"); std::vector<pstring> inout(plib::psplit(io[0], ",")); nl_assert_always(inout.size() == m_num_bits, "bitcount wrong"); - std::vector<pstring> out(plib::psplit(io[1], ",")); - nl_assert_always(out.size() == m_NO, "output count wrong"); + std::vector<pstring> outputs(plib::psplit(io[1], ",")); + nl_assert_always(outputs.size() == m_NO, "output count wrong"); for (std::size_t i=0; i < m_NI; i++) { - inout[i] = inout[i].trim(); + inout[i] = plib::trim(inout[i]); m_I.emplace(i, *this, inout[i]); } for (std::size_t i=0; i < m_NO; i++) { - out[i] = out[i].trim(); - m_Q.emplace(i, *this, out[i]); - } - // Connect output "Q" to input "_Q" if this exists - // This enables timed state without having explicit state .... - tt_bitset disabled_ignore = 0; - for (std::size_t i=0; i < m_NO; i++) - { - pstring tmp = "_" + out[i]; + outputs[i] = plib::trim(outputs[i]); + m_Q.emplace(i, *this, outputs[i]); + // Connect output "Q" to input "_Q" if this exists + // This enables timed state without having explicit state .... + pstring tmp = "_" + outputs[i]; const std::size_t idx = plib::container::indexof(inout, tmp); if (idx != plib::container::npos) - { connect(m_Q[i], m_I[idx]); - // disable ignore for theses inputs altogether. - // FIXME: This shouldn't be necessary - disabled_ignore.set(idx); - } } m_ign = 0; - -#if 0 - for (size_t i=0; i<m_size; i++) - { - m_ttp.m_outs[i] &= ~(disabled_ignore << m_NO); - } -#endif -#if 0 - printf("%s\n", name().c_str()); - for (int j=0; j < m_size; j++) - printf("%05x %04x %04x %04x\n", j, m_ttp->m_outs[j] & ((1 << m_NO)-1), - m_ttp->m_outs[j] >> m_NO, m_ttp->m_timing[j * m_NO + 0]); - for (int k=0; m_ttp->m_timing_nt[k] != netlist_time::zero(); k++) - printf("%d %f\n", k, m_ttp->m_timing_nt[k].as_double() * 1000000.0); -#endif } // ---------------------------------------------------------------------------------------- @@ -238,15 +224,20 @@ namespace netlist : netlist_base_factory_truthtable_t(name, classname, def_param, sourcefile) { } - plib::owned_ptr<device_t> Create(netlist_t &anetlist, const pstring &name) override + pool_owned_ptr<device_t> Create(netlist_state_t &anetlist, const pstring &name) override { - typedef nld_truthtable_t<m_NI, m_NO> tt_type; + using tt_type = nld_truthtable_t<m_NI, m_NO>; truthtable_parser desc_s(m_NO, m_NI, &m_ttbl.m_initialized, - packed_int(m_ttbl.m_outs, sizeof(m_ttbl.m_outs[0]) * 8), - m_ttbl.m_timing, m_ttbl.m_timing_nt); + packed_int(m_ttbl.m_out_state.data(), sizeof(m_ttbl.m_out_state[0]) * 8), + m_ttbl.m_timing_index.data(), m_ttbl.m_timing_nt.data()); desc_s.parse(m_desc); - return plib::owned_ptr<device_t>::Create<tt_type>(anetlist, name, m_family, m_ttbl, m_desc); + + /* update truthtable family definitions */ + if (m_family_name != "") + m_family_desc = anetlist.setup().family_from_model(m_family_name); + + return pool().make_poolptr<tt_type>(anetlist, name, m_family_desc, m_ttbl, m_desc); } private: typename nld_truthtable_t<m_NI, m_NO>::truthtable_t m_ttbl; @@ -259,7 +250,7 @@ namespace netlist for (std::size_t j=0; j<m_NI; j++) { // if changing the input directly doesn't change outputs we can ignore - if (m_outs[state] == m_outs[tt_bitset(state).set(j)]) + if (m_out_state[state] == m_out_state[tt_bitset(state).set(j)]) ignore.set(j); } @@ -285,7 +276,7 @@ namespace netlist { tt_bitset b = tign.expand_and(k); // will any of the inputs ignored change the output if changed? - if (m_outs[state] != m_outs[(state & tign.invert()) | b]) + if (m_out_state[state] != m_out_state[(state & tign.invert()) | b]) { t[j] = true; break; @@ -318,21 +309,21 @@ namespace netlist void truthtable_parser::parseline(unsigned cur, std::vector<pstring> list, tt_bitset state, uint_least64_t val, std::vector<uint_least8_t> &timing_index) { - pstring elem = list[cur].trim(); + pstring elem = plib::trim(list[cur]); uint_least64_t start = 0; uint_least64_t end = 0; - if (elem.equals("0")) + if (elem == "0") { start = 0; end = 0; } - else if (elem.equals("1")) + else if (elem == "1") { start = 1; end = 1; } - else if (elem.equals("X")) + else if (elem == "X") { start = 0; end = 1; @@ -352,10 +343,10 @@ void truthtable_parser::parseline(unsigned cur, std::vector<pstring> list, else { // cutoff previous inputs and outputs for ignore - if (m_outs[nstate] != m_outs.mask() && m_outs[nstate] != val) - nl_exception(plib::pfmt("Error in truthtable: State {1:04} already set, {2} != {3}\n") - .x(nstate.as_uint())(m_outs[nstate])(val) ); - m_outs.set(nstate, val); + if (m_out_state[nstate] != m_out_state.mask() && m_out_state[nstate] != val) + throw nl_exception(plib::pfmt("Error in truthtable: State {1:04} already set, {2} != {3}\n") + .x(nstate.as_uint())(m_out_state[nstate])(val) ); + m_out_state.set(nstate, val); for (std::size_t j=0; j<m_NO; j++) m_timing[nstate * m_NO + j] = timing_index[j]; } @@ -375,12 +366,12 @@ void truthtable_parser::parse(const std::vector<pstring> &truthtable) line++; for (unsigned j=0; j < m_size; j++) - m_outs.set(j, tt_bitset::all_bits()); + m_out_state.set(j, tt_bitset::all_bits()); for (int j=0; j < 16; j++) m_timing_nt[j] = netlist_time::zero(); - while (!ttline.equals("")) + while (!(ttline == "")) { std::vector<pstring> io(plib::psplit(ttline,"|")); // checks @@ -402,12 +393,13 @@ void truthtable_parser::parse(const std::vector<pstring> &truthtable) */ for (unsigned j=0; j<m_NO; j++) { - pstring outs = out[j].trim(); - if (outs.equals("1")) + pstring outs = plib::trim(out[j]); + if (outs == "1") val.set(j); else - nl_assert_always(outs.equals("0"), "Unknown value (not 0 or 1"); - netlist_time t = netlist_time::from_nsec(static_cast<unsigned long>(times[j].trim().as_long())); + nl_assert_always(outs == "0", "Unknown value (not 0 or 1"); + // FIXME: error handling + netlist_time t = netlist_time::from_nsec(plib::pstonum<std::int64_t>(plib::trim(times[j]))); uint_least8_t k=0; while (m_timing_nt[k] != netlist_time::zero() && m_timing_nt[k] != t) k++; @@ -450,9 +442,9 @@ void truthtable_parser::parse(const std::vector<pstring> &truthtable) } for (size_t i=0; i<m_size; i++) { - if (m_outs[i] == m_outs.mask()) + if (m_out_state[i] == m_out_state.mask()) throw nl_exception(plib::pfmt("truthtable: found element not set {1}\n").x(i) ); - m_outs.set(i, m_outs[i] | (ign[i] << m_NO));; + m_out_state.set(i, m_out_state[i] | (ign[i] << m_NO)); } *m_initialized = true; @@ -460,26 +452,21 @@ void truthtable_parser::parse(const std::vector<pstring> &truthtable) netlist_base_factory_truthtable_t::netlist_base_factory_truthtable_t(const pstring &name, const pstring &classname, const pstring &def_param, const pstring &sourcefile) -: factory::element_t(name, classname, def_param, sourcefile), m_family(family_TTL()) -{ -} - -netlist_base_factory_truthtable_t::~netlist_base_factory_truthtable_t() +: factory::element_t(name, classname, def_param, sourcefile), m_family_desc(family_TTL()) { } - #define ENTRYY(n, m, s) case (n * 100 + m): \ { using xtype = netlist_factory_truthtable_t<n, m>; \ - ret = plib::palloc<xtype>(desc.name, desc.classname, desc.def_param, s); } break + ret = plib::make_unique<xtype>(desc.name, desc.classname, desc.def_param, s); } break #define ENTRY(n, s) ENTRYY(n, 1, s); ENTRYY(n, 2, s); ENTRYY(n, 3, s); \ ENTRYY(n, 4, s); ENTRYY(n, 5, s); ENTRYY(n, 6, s); \ ENTRYY(n, 7, s); ENTRYY(n, 8, s) -void tt_factory_create(setup_t &setup, tt_desc &desc, const pstring &sourcefile) +plib::unique_ptr<netlist_base_factory_truthtable_t> tt_factory_create(tt_desc &desc, const pstring &sourcefile) { - netlist_base_factory_truthtable_t *ret; + plib::unique_ptr<netlist_base_factory_truthtable_t> ret; switch (desc.ni * 100 + desc.no) { @@ -500,9 +487,9 @@ void tt_factory_create(setup_t &setup, tt_desc &desc, const pstring &sourcefile) nl_assert_always(false, msg); } ret->m_desc = desc.desc; - if (desc.family != "") - ret->m_family = setup.family_from_model(desc.family); - setup.factory().register_device(std::unique_ptr<netlist_base_factory_truthtable_t>(ret)); + ret->m_family_name = desc.family; + + return ret; } } //namespace devices |