// license:GPL-2.0+ // copyright-holders:Couriersud /* * nld_truthtable.c * */ #include "nld_truthtable.h" #include "plib/plists.h" #include "nl_setup.h" namespace netlist { namespace devices { template class netlist_factory_truthtable_t : public netlist_base_factory_truthtable_t { P_PREVENT_COPYING(netlist_factory_truthtable_t) public: netlist_factory_truthtable_t(const pstring &name, const pstring &classname, const pstring &def_param) : netlist_base_factory_truthtable_t(name, classname, def_param) { } plib::owned_ptr Create(netlist_t &anetlist, const pstring &name) override { typedef nld_truthtable_t tt_type; return plib::owned_ptr::Create(anetlist, name, m_family, &m_ttbl, m_desc); } private: typename nld_truthtable_t::truthtable_t m_ttbl; }; static const uint_least64_t all_set = ~((uint_least64_t) 0); unsigned truthtable_desc_t::count_bits(uint_least64_t v) { uint_least64_t ret = 0; for (; v != 0; v = v >> 1) { ret += (v & 1); } return ret; } uint_least64_t truthtable_desc_t::set_bits(uint_least64_t v, uint_least64_t b) { uint_least64_t ret = 0; for (size_t i = 0; v != 0; v = v >> 1, ++i) { if (v & 1) { ret |= ((b&1)<> 1; } } return ret; } uint_least64_t truthtable_desc_t::get_ignored_simple(uint_least64_t i) { uint_least64_t m_enable = 0; for (size_t j=0; j t(bits); for (size_t j=1; jjb)) { jb = nb; jm = j; } } return set_bits(ignore, jm); } // ---------------------------------------------------------------------------------------- // desc // ---------------------------------------------------------------------------------------- void truthtable_desc_t::help(unsigned cur, plib::pstring_vector_t list, uint_least64_t state, uint_least64_t val, std::vector &timing_index) { pstring elem = list[cur].trim(); int start = 0; int end = 0; if (elem.equals("0")) { start = 0; end = 0; } else if (elem.equals("1")) { start = 1; end = 1; } else if (elem.equals("X")) { start = 0; end = 1; } else nl_assert_always(false, "unknown input value (not 0, 1, or X)"); for (int i = start; i <= end; i++) { const uint_least64_t nstate = state | (i << cur); if (cur < m_num_bits - 1) { help(cur + 1, list, nstate, val, timing_index); } else { // cutoff previous inputs and outputs for ignore if (m_outs[nstate] != m_outs.adjust(all_set) && m_outs[nstate] != val) fatalerror_e(plib::pfmt("Error in truthtable: State {1} already set, {2} != {3}\n") .x(nstate,"04")(m_outs[nstate])(val) ); m_outs.set(nstate, val); for (unsigned j=0; j tindex; for (unsigned j=0; j ign(m_size, all_set); for (size_t i=0; i; \ ret = new xtype(desc.name, desc.classname, desc.def_param); } break #define ENTRY(n) ENTRYY(n, 1); ENTRYY(n, 2); ENTRYY(n, 3); ENTRYY(n, 4); ENTRYY(n, 5); ENTRYY(n, 6) void tt_factory_create(setup_t &setup, tt_desc &desc) { netlist_base_factory_truthtable_t *ret; switch (desc.ni * 100 + desc.no) { ENTRY(1); ENTRY(2); ENTRY(3); ENTRY(4); ENTRY(5); ENTRY(6); ENTRY(7); ENTRY(8); ENTRY(9); ENTRY(10); default: pstring msg = plib::pfmt("unable to create truthtable<{1},{2}>")(desc.ni)(desc.no); 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(ret)); } } //namespace devices } // namespace netlist