summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/devices/nlid_truthtable.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/netlist/devices/nlid_truthtable.cpp')
-rw-r--r--src/lib/netlist/devices/nlid_truthtable.cpp422
1 files changed, 208 insertions, 214 deletions
diff --git a/src/lib/netlist/devices/nlid_truthtable.cpp b/src/lib/netlist/devices/nlid_truthtable.cpp
index db2471a704e..072fa148d75 100644
--- a/src/lib/netlist/devices/nlid_truthtable.cpp
+++ b/src/lib/netlist/devices/nlid_truthtable.cpp
@@ -1,4 +1,4 @@
-// license:GPL-2.0+
+// license:BSD-3-Clause
// copyright-holders:Couriersud
#include "plib/pstonum.h"
@@ -12,13 +12,10 @@
#include <cstdint>
#include <vector>
-namespace netlist
-{
-namespace devices
-{
+namespace netlist::devices {
template<std::size_t m_NI, std::size_t m_NO>
- class NETLIB_NAME(truthtable_t) : public device_t
+ class NETLIB_NAME(truth_table_t) : public device_t
{
public:
@@ -28,9 +25,9 @@ namespace devices
static constexpr const std::size_t m_size = (1 << (m_num_bits));
static constexpr const type_t m_outmask = ((1 << m_NO) - 1);
- struct truthtable_t
+ struct truth_table_t
{
- truthtable_t()
+ truth_table_t()
: m_timing_index{0}
{}
@@ -39,12 +36,10 @@ namespace devices
std::array<netlist_time, 16> m_timing_nt;
};
- template <class C>
- nld_truthtable_t(C &owner, const pstring &name,
- const pstring &model,
- truthtable_t &ttp, const std::vector<pstring> &desc)
- : device_t(owner, name, model)
-#if USE_TT_ALTERNATIVE
+ nld_truth_table_t(device_param_t data, const pstring &model,
+ truth_table_t &ttp, const std::vector<pstring> &desc)
+ : device_t(data, model)
+#if NL_USE_TT_ALTERNATIVE
, m_state(*this, "m_state", 0)
#endif
, m_ign(*this, "m_ign", 0)
@@ -52,7 +47,7 @@ namespace devices
/* FIXME: the family should provide the names of the power-terminals! */
, m_power_pins(*this)
{
- m_activate = activate_delegate(& NETLIB_NAME(truthtable_t) :: incdec_active, this);
+ m_activate = activate_delegate(& NETLIB_NAME(truth_table_t) :: incdec_active, this);
set_hint_deactivate(true);
init(desc);
}
@@ -64,25 +59,26 @@ namespace devices
{
int active_outputs = 0;
m_ign = 0;
-#if USE_TT_ALTERNATIVE
+#if NL_USE_TT_ALTERNATIVE
m_state = 0;
#endif
for (std::size_t i = 0; i < m_NI; ++i)
{
m_I[i].activate();
-#if USE_TT_ALTERNATIVE
+#if NL_USE_TT_ALTERNATIVE
m_state |= (m_I[i]() << i);
#endif
}
for (auto &q : m_Q)
- if (q.has_net() && !exec().nlstate().core_terms(q.net()).empty())
- active_outputs++;
+ if (q.has_net())
+ if (!q.net().core_terms_empty())
+ active_outputs++;
set_active_outputs(active_outputs);
}
NETLIB_HANDLERI(inputs)
{
-#if USE_TT_ALTERNATIVE
+#if NL_USE_TT_ALTERNATIVE
m_state = 0;
for (std::size_t i = 0; i < m_NI; ++i)
{
@@ -92,7 +88,7 @@ namespace devices
process<true>();
}
-#if USE_TT_ALTERNATIVE
+#if NL_USE_TT_ALTERNATIVE
template <std::size_t N>
void update_N() noexcept
{
@@ -120,26 +116,26 @@ namespace devices
void process() noexcept
{
netlist_time_ext mt(netlist_time_ext::zero());
- type_t nstate(0);
+ type_t new_state(0);
type_t ign(m_ign);
if (doOUT)
{
-#if !USE_TT_ALTERNATIVE
+#if !NL_USE_TT_ALTERNATIVE
for (auto I = m_I.begin(); ign != 0; ign >>= 1, ++I)
if (ign & 1)
I->activate();
for (std::size_t i = 0; i < m_NI; i++)
- nstate |= (m_I[i]() << i);
+ new_state |= (m_I[i]() << i);
#else
- nstate = m_state;
+ new_state = m_state;
for (std::size_t i = 0; ign != 0; ign >>= 1, ++i)
{
if (ign & 1)
{
- nstate &= ~(1 << i);
+ new_state &= ~(1 << i);
m_I[i].activate();
- nstate |= (m_I[i]() << i);
+ new_state |= (m_I[i]() << i);
}
}
#endif
@@ -148,16 +144,16 @@ namespace devices
for (std::size_t i = 0; i < m_NI; i++)
{
m_I[i].activate();
- nstate |= (m_I[i]() << i);
+ new_state |= (m_I[i]() << i);
mt = std::max(this->m_I[i].net().next_scheduled_time(), mt);
}
- const type_t outstate(m_ttp.m_out_state[nstate]);
- type_t out(outstate & m_outmask);
+ const type_t output_state(m_ttp.m_out_state[new_state]);
+ const type_t out(output_state & m_outmask);
- m_ign = outstate >> m_NO;
+ m_ign = output_state >> m_NO;
- const auto *t(&m_ttp.m_timing_index[nstate * m_NO]);
+ const auto *t(&m_ttp.m_timing_index[new_state * m_NO]);
if (doOUT)
//for (std::size_t i = 0; i < m_NO; ++i)
@@ -174,8 +170,8 @@ namespace devices
for (auto I = m_I.begin(); ign != 0; ign >>= 1, ++I)
if (ign & 1)
I->inactivate();
-#if USE_TT_ALTERNATIVE
- m_state = nstate;
+#if NL_USE_TT_ALTERNATIVE
+ m_state = new_state;
#endif
}
@@ -198,11 +194,11 @@ namespace devices
plib::static_vector<logic_input_t, m_NI> m_I;
plib::static_vector<logic_output_t, m_NO> m_Q;
-#if USE_TT_ALTERNATIVE
+#if NL_USE_TT_ALTERNATIVE
state_var<type_t> m_state;
#endif
state_var<type_t> m_ign;
- const truthtable_t m_ttp;
+ const truth_table_t m_ttp;
/* FIXME: the family should provide the names of the power-terminals! */
nld_power_pins m_power_pins;
};
@@ -217,18 +213,18 @@ namespace devices
{
using type = T;
- pbitset() noexcept : m_bs(0) { }
- pbitset(T v) noexcept : m_bs(v) { }
+ constexpr pbitset() noexcept : m_bs(0) { }
+ constexpr pbitset(T v) noexcept : m_bs(v) { }
- pbitset &set() noexcept { *this = all_bits(); return *this; }
- pbitset &set(std::size_t bit) noexcept { m_bs |= (static_cast<T>(1) << bit); return *this; }
- pbitset &reset() noexcept { *this = no_bits(); return *this; }
- pbitset &reset(std::size_t bit) noexcept { m_bs &= ~(static_cast<T>(1) << bit); return *this; }
+ constexpr pbitset &set() noexcept { *this = all_bits(); return *this; }
+ constexpr pbitset &set(std::size_t bit) noexcept { m_bs |= (static_cast<T>(1) << bit); return *this; }
+ constexpr pbitset &reset() noexcept { *this = no_bits(); return *this; }
+ constexpr pbitset &reset(std::size_t bit) noexcept { m_bs &= ~(static_cast<T>(1) << bit); return *this; }
- pbitset flip() const noexcept { return pbitset(~m_bs); }
- pbitset flip(std::size_t bit) const noexcept { return pbitset(m_bs ^ (static_cast<T>(1) << bit)); }
+ constexpr pbitset flip() const noexcept { return pbitset(~m_bs); }
+ constexpr pbitset flip(std::size_t bit) const noexcept { return pbitset(m_bs ^ (static_cast<T>(1) << bit)); }
- std::size_t count() const noexcept
+ constexpr std::size_t count() const noexcept
{
std::size_t ret(0);
for (T v = m_bs; v != 0; v = v >> 1)
@@ -239,8 +235,8 @@ namespace devices
}
constexpr bool test(const std::size_t bit) const { return ((m_bs >> bit) & 1) == 1; }
- operator T&() noexcept { return m_bs; }
- operator const T&() const noexcept { return m_bs; }
+ constexpr operator T&() noexcept { return m_bs; }
+ constexpr operator const T&() const noexcept { return m_bs; }
constexpr T as_uint() const noexcept { return m_bs; }
constexpr bool all() const noexcept { return *this == all_bits(); }
@@ -257,7 +253,7 @@ namespace devices
///
/// \returns pbitset
///
- pbitset expand_and(pbitset b) const noexcept
+ constexpr pbitset expand_and(pbitset b) const noexcept
{
pbitset ret;
T v( m_bs);
@@ -281,19 +277,19 @@ namespace devices
};
// ----------------------------------------------------------------------------------------
- // Truthtable parsing ....
+ // Truth table parsing ....
// ----------------------------------------------------------------------------------------
using tt_bitset = pbitset<std::uint_least64_t>;
struct packed_int
{
- packed_int(void *data, std::size_t bits) noexcept
+ constexpr packed_int(void *data, std::size_t bits) noexcept
: m_data(data)
, m_size(bits)
{}
- void set(size_t pos, std::uint_least64_t val) noexcept
+ constexpr void set(size_t pos, std::uint_least64_t val) noexcept
{
switch (m_size)
{
@@ -305,7 +301,7 @@ namespace devices
}
}
- std::uint_least64_t operator[] (size_t pos) const noexcept
+ constexpr std::uint_least64_t operator[] (size_t pos) const noexcept
{
switch (m_size)
{
@@ -318,7 +314,7 @@ namespace devices
}
}
- std::uint_least64_t mask() const noexcept
+ constexpr std::uint_least64_t mask() const noexcept
{
switch (m_size)
{
@@ -335,9 +331,9 @@ namespace devices
size_t m_size;
};
- struct truthtable_parser
+ struct truth_table_parser
{
- truthtable_parser(unsigned NO, unsigned NI,
+ truth_table_parser(unsigned NO, unsigned NI,
packed_int outs, uint_least8_t *timing, netlist_time *timing_nt)
: m_NO(NO)
, m_NI(NI)
@@ -349,10 +345,10 @@ namespace devices
{
}
- void parse(const std::vector<pstring> &truthtable);
+ void parse(const std::vector<pstring> &truth_table);
private:
- void parseline(unsigned cur, std::vector<pstring> list,
+ void parse_line(unsigned cur, std::vector<pstring> list,
tt_bitset state, std::uint_least64_t val, std::vector<uint_least8_t> &timing_index);
tt_bitset calculate_ignored_inputs(tt_bitset state) const;
@@ -369,11 +365,11 @@ namespace devices
};
// ----------------------------------------------------------------------------------------
- // Truthtable class ....
+ // Truth table class ....
// ----------------------------------------------------------------------------------------
template<std::size_t m_NI, std::size_t m_NO>
- void NETLIB_NAME(truthtable_t)<m_NI, m_NO>::init(const std::vector<pstring> &desc)
+ void NETLIB_NAME(truth_table_t)<m_NI, m_NO>::init(const std::vector<pstring> &desc)
{
pstring header = desc[0];
@@ -381,33 +377,33 @@ namespace devices
// checks
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");
+ nl_assert_always(inout.size() == m_num_bits, "bit count wrong");
std::vector<pstring> outputs(plib::psplit(io[1], ','));
nl_assert_always(outputs.size() == m_NO, "output count wrong");
-#if !USE_TT_ALTERNATIVE
+#if !NL_USE_TT_ALTERNATIVE
for (std::size_t i=0; i < m_NI; i++)
{
inout[i] = plib::trim(inout[i]);
- m_I.emplace_back(*this, inout[i], nldelegate(&NETLIB_NAME(truthtable_t)<m_NI, m_NO> :: inputs, this));
+ m_I.emplace_back(*this, inout[i], nl_delegate(&NETLIB_NAME(truth_table_t)<m_NI, m_NO> :: inputs, this));
}
#else
for (std::size_t i=0; i < m_NI; i++)
{
inout[i] = plib::trim(inout[i]);
}
- if (0 < m_NI) m_I.emplace(0, *this, inout[0]); //, nldelegate(&nld_truthtable_t<m_NI, m_NO>::update_N<0>, this));
- if (1 < m_NI) m_I.emplace(1, *this, inout[1]); //, nldelegate(&nld_truthtable_t<m_NI, m_NO>::update_N<1>, this));
- if (2 < m_NI) m_I.emplace(2, *this, inout[2]); //, nldelegate(&nld_truthtable_t<m_NI, m_NO>::update_N<2>, this));
- if (3 < m_NI) m_I.emplace(3, *this, inout[3]); //, nldelegate(&nld_truthtable_t<m_NI, m_NO>::update_N<3>, this));
- if (4 < m_NI) m_I.emplace(4, *this, inout[4]); //, nldelegate(&nld_truthtable_t<m_NI, m_NO>::update_N<4>, this));
- if (5 < m_NI) m_I.emplace(5, *this, inout[5]); //, nldelegate(&nld_truthtable_t<m_NI, m_NO>::update_N<5>, this));
- if (6 < m_NI) m_I.emplace(6, *this, inout[6]); //, nldelegate(&nld_truthtable_t<m_NI, m_NO>::update_N<6>, this));
- if (7 < m_NI) m_I.emplace(7, *this, inout[7]); //, nldelegate(&nld_truthtable_t<m_NI, m_NO>::update_N<7>, this));
- if (8 < m_NI) m_I.emplace(8, *this, inout[8]); //, nldelegate(&nld_truthtable_t<m_NI, m_NO>::update_N<8>, this));
- if (9 < m_NI) m_I.emplace(9, *this, inout[9]); //, nldelegate(&nld_truthtable_t<m_NI, m_NO>::update_N<9>, this));
- if (10 < m_NI) m_I.emplace(10, *this, inout[10]); //, nldelegate(&nld_truthtable_t<m_NI, m_NO>::update_N<10>, this));
- if (11 < m_NI) m_I.emplace(11, *this, inout[11]); //, nldelegate(&nld_truthtable_t<m_NI, m_NO>::update_N<11>, this));
+ if (0 < m_NI) m_I.emplace_back(*this, inout[0], nl_delegate(&nld_truth_table_t<m_NI, m_NO>::update_N<0>, this));
+ if (1 < m_NI) m_I.emplace_back(*this, inout[1], nl_delegate(&nld_truth_table_t<m_NI, m_NO>::update_N<1>, this));
+ if (2 < m_NI) m_I.emplace_back(*this, inout[2], nl_delegate(&nld_truth_table_t<m_NI, m_NO>::update_N<2>, this));
+ if (3 < m_NI) m_I.emplace_back(*this, inout[3], nl_delegate(&nld_truth_table_t<m_NI, m_NO>::update_N<3>, this));
+ if (4 < m_NI) m_I.emplace_back(*this, inout[4], nl_delegate(&nld_truth_table_t<m_NI, m_NO>::update_N<4>, this));
+ if (5 < m_NI) m_I.emplace_back(*this, inout[5], nl_delegate(&nld_truth_table_t<m_NI, m_NO>::update_N<5>, this));
+ if (6 < m_NI) m_I.emplace_back(*this, inout[6], nl_delegate(&nld_truth_table_t<m_NI, m_NO>::update_N<6>, this));
+ if (7 < m_NI) m_I.emplace_back(*this, inout[7], nl_delegate(&nld_truth_table_t<m_NI, m_NO>::update_N<7>, this));
+ if (8 < m_NI) m_I.emplace_back(*this, inout[8], nl_delegate(&nld_truth_table_t<m_NI, m_NO>::update_N<8>, this));
+ if (9 < m_NI) m_I.emplace_back(*this, inout[9], nl_delegate(&nld_truth_table_t<m_NI, m_NO>::update_N<9>, this));
+ if (10 < m_NI) m_I.emplace_back(*this, inout[10], nl_delegate(&nld_truth_table_t<m_NI, m_NO>::update_N<10>, this));
+ if (11 < m_NI) m_I.emplace_back(*this, inout[11], nl_delegate(&nld_truth_table_t<m_NI, m_NO>::update_N<11>, this));
#endif
for (std::size_t i=0; i < m_NO; i++)
{
@@ -416,7 +412,7 @@ namespace devices
// 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);
+ const std::size_t idx = plib::container::index_of(inout, tmp);
if (idx != plib::container::npos)
connect(m_Q[i], m_I[idx]);
}
@@ -424,39 +420,39 @@ namespace devices
}
// ----------------------------------------------------------------------------------------
- // Truthtable factory ....
+ // Truth table factory ....
// ----------------------------------------------------------------------------------------
template<unsigned m_NI, unsigned m_NO>
- class netlist_factory_truthtable_t : public factory::truthtable_base_element_t
+ class factory_truth_table_t : public factory::truth_table_base_element_t
{
public:
- netlist_factory_truthtable_t(const pstring &name,
+ factory_truth_table_t(const pstring &name,
factory::properties &&props)
- : truthtable_base_element_t(name, std::move(props))
+ : truth_table_base_element_t(name, std::move(props))
{ }
device_arena::unique_ptr<core_device_t> make_device(device_arena &pool, netlist_state_t &anetlist, const pstring &name) override
{
- using tt_type = nld_truthtable_t<m_NI, m_NO>;
+ using tt_type = nld_truth_table_t<m_NI, m_NO>;
- if (!m_ttbl)
+ if (!m_table)
{
- m_ttbl = plib::make_unique<typename nld_truthtable_t<m_NI, m_NO>::truthtable_t>(pool);
- truthtable_parser desc_s(m_NO, m_NI,
- 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());
+ m_table = plib::make_unique<typename nld_truth_table_t<m_NI, m_NO>::truth_table_t>(pool);
+ truth_table_parser desc_s(m_NO, m_NI,
+ packed_int(m_table->m_out_state.data(), sizeof(m_table->m_out_state[0]) * 8),
+ m_table->m_timing_index.data(), m_table->m_timing_nt.data());
desc_s.parse(m_desc);
}
- return plib::make_unique<tt_type>(pool, anetlist, name, m_family_name, *m_ttbl, m_desc);
+ return plib::make_unique<tt_type>(pool, device_data_t{anetlist, name}, m_family_name, *m_table, m_desc);
}
private:
- device_arena::unique_ptr<typename nld_truthtable_t<m_NI, m_NO>::truthtable_t> m_ttbl;
+ device_arena::unique_ptr<typename nld_truth_table_t<m_NI, m_NO>::truth_table_t> m_table;
};
- tt_bitset truthtable_parser::calculate_ignored_inputs(tt_bitset state) const
+ tt_bitset truth_table_parser::calculate_ignored_inputs(tt_bitset state) const
{
// Determine all inputs which may be ignored ...
tt_bitset ignore = 0;
@@ -514,155 +510,154 @@ namespace devices
return ignore.expand_and(jm);
}
-// ----------------------------------------------------------------------------------------
-// parseline
-// ----------------------------------------------------------------------------------------
-
-void truthtable_parser::parseline(unsigned cur, std::vector<pstring> list,
- tt_bitset state, std::uint_least64_t val, std::vector<uint_least8_t> &timing_index)
-{
- pstring elem = plib::trim(list[cur]);
- std::uint_least64_t start = 0;
- std::uint_least64_t end = 0;
+ // ----------------------------------------------------------------------------------------
+ // parse line
+ // ----------------------------------------------------------------------------------------
- if (elem == "0")
- {
- start = 0;
- end = 0;
- }
- else if (elem == "1")
- {
- start = 1;
- end = 1;
- }
- else if (elem == "X")
- {
- start = 0;
- end = 1;
- }
- else
- nl_assert_always(false, "unknown input value (not 0, 1, or X)");
- for (std::uint_least64_t i = start; i <= end; i++)
+ void truth_table_parser::parse_line(unsigned cur, std::vector<pstring> list,
+ tt_bitset state, std::uint_least64_t val, std::vector<uint_least8_t> &timing_index)
{
- tt_bitset nstate = state;
- if (i==1)
- nstate.set(cur);
+ pstring elem = plib::trim(list[cur]);
+ std::uint_least64_t start = 0;
+ std::uint_least64_t end = 0;
- if (cur < m_num_bits - 1)
+ if (elem == "0")
+ {
+ start = 0;
+ end = 0;
+ }
+ else if (elem == "1")
+ {
+ start = 1;
+ end = 1;
+ }
+ else if (elem == "X")
{
- parseline(cur + 1, list, nstate, val, timing_index);
+ start = 0;
+ end = 1;
}
else
+ nl_assert_always(false, "unknown input value (not 0, 1, or X)");
+ for (std::uint_least64_t i = start; i <= end; i++)
{
- // cutoff previous inputs and outputs for ignore
- 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];
+ tt_bitset new_state = state;
+ if (i==1)
+ new_state.set(cur);
+
+ if (cur < m_num_bits - 1)
+ {
+ parse_line(cur + 1, list, new_state, val, timing_index);
+ }
+ else
+ {
+ // cutoff previous inputs and outputs for ignore
+ if (m_out_state[new_state] != m_out_state.mask() && m_out_state[new_state] != val)
+ throw nl_exception(plib::pfmt("Error in truth table: State {1:04} already set, {2} != {3}\n")
+ .x(new_state.as_uint())(m_out_state[new_state])(val) );
+ m_out_state.set(new_state, val);
+ for (std::size_t j=0; j<m_NO; j++)
+ m_timing[new_state * m_NO + j] = timing_index[j];
+ }
}
}
-}
-
-void truthtable_parser::parse(const std::vector<pstring> &truthtable)
-{
- unsigned line = 0;
-
- pstring ttline(truthtable[line]);
- line++;
- ttline = truthtable[line];
- line++;
- for (unsigned j=0; j < m_size; j++)
- 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.empty())
+ void truth_table_parser::parse(const std::vector<pstring> &truth_table)
{
- std::vector<pstring> io(plib::psplit(ttline,'|'));
- // checks
- nl_assert_always(io.size() == 3, "io.count mismatch");
- std::vector<pstring> inout(plib::psplit(io[0], ','));
- nl_assert_always(inout.size() == m_num_bits, "number of bits not matching");
- std::vector<pstring> out(plib::psplit(io[1], ','));
- nl_assert_always(out.size() == m_NO, "output count not matching");
- std::vector<pstring> times(plib::psplit(io[2], ','));
- nl_assert_always(times.size() == m_NO, "timing count not matching");
+ unsigned line = 0;
+
+ pstring tt_line(truth_table[line]);
+ line++;
+ tt_line = truth_table[line];
+ line++;
- tt_bitset val = 0;
- std::vector<uint_least8_t> tindex;
+ for (unsigned j=0; j < m_size; j++)
+ m_out_state.set(j, tt_bitset::all_bits());
- //
- // FIXME: evaluation of outputs should be done in parseline to
- // enable the use of inputs for output values, i.e. "I1" or "~I1"
- // in addition to "0" and "1".
+ for (int j=0; j < 16; j++)
+ m_timing_nt[j] = netlist_time::zero();
- for (unsigned j=0; j<m_NO; j++)
+ while (!tt_line.empty())
{
- pstring outs = plib::trim(out[j]);
- if (outs == "1")
- val.set(j);
+ std::vector<pstring> io(plib::psplit(tt_line,'|'));
+ // checks
+ nl_assert_always(io.size() == 3, "io.count mismatch");
+ std::vector<pstring> inout(plib::psplit(io[0], ','));
+ nl_assert_always(inout.size() == m_num_bits, "number of bits not matching");
+ std::vector<pstring> out(plib::psplit(io[1], ','));
+ nl_assert_always(out.size() == m_NO, "output count not matching");
+ std::vector<pstring> times(plib::psplit(io[2], ','));
+ nl_assert_always(times.size() == m_NO, "timing count not matching");
+
+ tt_bitset val = 0;
+ std::vector<uint_least8_t> indexes;
+
+ //
+ // FIXME: evaluation of outputs should be done in parse_line to
+ // enable the use of inputs for output values, i.e. "I1" or "~I1"
+ // in addition to "0" and "1".
+
+ for (unsigned j=0; j<m_NO; j++)
+ {
+ pstring outs = plib::trim(out[j]);
+ if (outs == "1")
+ val.set(j);
+ else
+ 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++;
+ m_timing_nt[k] = t;
+ indexes.push_back(k); //[j] = k;
+ }
+
+ parse_line(0, inout, 0 , val, indexes);
+ if (line < truth_table.size())
+ tt_line = truth_table[line];
else
- 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++;
- m_timing_nt[k] = t;
- tindex.push_back(k); //[j] = k;
+ tt_line = "";
+ line++;
}
- parseline(0, inout, 0 , val, tindex);
- if (line < truthtable.size())
- ttline = truthtable[line];
- else
- ttline = "";
- line++;
- }
-
- // determine ignore mask by looping over all input combinations
- std::vector<tt_bitset> ign(m_size);
- for (tt_bitset &x : ign)
- x.set();
+ // determine ignore mask by looping over all input combinations
+ std::vector<tt_bitset> ign(m_size);
+ for (tt_bitset &x : ign)
+ x.set();
- for (std::uint_least64_t i=0; i < m_size; i++)
- {
- if (ign[i].all()) // not yet visited
+ for (std::uint_least64_t i=0; i < m_size; i++)
{
- tt_bitset tign = calculate_ignored_inputs(i);
+ if (ign[i].all()) // not yet visited
+ {
+ tt_bitset tign = calculate_ignored_inputs(i);
- ign[i] = tign;
+ ign[i] = tign;
- // don't need to recalculate similar ones
- tt_bitset bitsk;
- bitsk.set(tign.count());
+ // don't need to recalculate similar ones
+ tt_bitset bitsk;
+ bitsk.set(tign.count());
- for (std::uint_least64_t k=0; k < bitsk; k++)
- {
- tt_bitset b = tign.expand_and(k);
- ign[(i & tign.flip()) | b] = tign;
+ for (std::uint_least64_t k=0; k < bitsk; k++)
+ {
+ tt_bitset b = tign.expand_and(k);
+ ign[(i & tign.flip()) | b] = tign;
+ }
}
}
- }
- for (size_t i=0; i<m_size; i++)
- {
- if (m_out_state[i] == m_out_state.mask())
- throw nl_exception(plib::pfmt("truthtable: found element not set {1}\n").x(i) );
- m_out_state.set(i, m_out_state[i] | (ign[i] << m_NO));
+ for (size_t i=0; i<m_size; i++)
+ {
+ if (m_out_state[i] == m_out_state.mask())
+ throw nl_exception(plib::pfmt("truth table: found element not set {1}\n").x(i) );
+ m_out_state.set(i, m_out_state[i] | (ign[i] << m_NO));
+ }
}
-}
-} // namespace devices
+} // namespace netlist::devices
-namespace factory
-{
+namespace netlist::factory {
- truthtable_base_element_t::truthtable_base_element_t(const pstring &name,
+ truth_table_base_element_t::truth_table_base_element_t(const pstring &name,
properties &&props)
: factory::element_t(name, std::move(props))
, m_family_name(config::DEFAULT_LOGIC_FAMILY())
@@ -670,9 +665,9 @@ namespace factory
}
#define ENTRYY(n, m, s) case (n * 100 + m): \
- { using xtype = devices::netlist_factory_truthtable_t<n, m>; \
+ { using dev_type = devices::factory_truth_table_t<n, m>; \
auto cs=s; \
- ret = plib::make_unique<xtype, host_arena>(desc.name, std::move(cs)); } \
+ ret = plib::make_unique<dev_type, host_arena>(desc.name, std::move(cs)); } \
break
#define ENTRY(n, s) ENTRYY(n, 1, s); ENTRYY(n, 2, s); ENTRYY(n, 3, s); \
@@ -680,9 +675,9 @@ namespace factory
ENTRYY(n, 7, s); ENTRYY(n, 8, s); ENTRYY(n, 9, s); \
ENTRYY(n, 10, s)
- host_arena::unique_ptr<truthtable_base_element_t> truthtable_create(tt_desc &desc, properties &&props)
+ host_arena::unique_ptr<truth_table_base_element_t> truth_table_create(tt_desc &desc, properties &&props)
{
- host_arena::unique_ptr<truthtable_base_element_t> ret;
+ host_arena::unique_ptr<truth_table_base_element_t> ret;
switch (desc.ni * 100 + desc.no)
{
@@ -699,7 +694,7 @@ namespace factory
ENTRY(11, props);
ENTRY(12, props);
default:
- pstring msg = plib::pfmt("unable to create truthtable<{1},{2}>")(desc.ni)(desc.no);
+ pstring msg = plib::pfmt("unable to create truth table<{1},{2}>")(desc.ni)(desc.no);
nl_assert_always(false, putf8string(msg).c_str());
}
ret->m_desc = desc.desc;
@@ -708,5 +703,4 @@ namespace factory
return ret;
}
-} // namespace factory
-} // namespace netlist
+} // namespace netlist::factory