summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--scripts/src/netlist.lua1
-rw-r--r--src/emu/netlist/devices/nld_truthtable.c189
-rw-r--r--src/emu/netlist/devices/nld_truthtable.h218
3 files changed, 229 insertions, 179 deletions
diff --git a/scripts/src/netlist.lua b/scripts/src/netlist.lua
index 3c0ded1383e..6c79eb1b463 100644
--- a/scripts/src/netlist.lua
+++ b/scripts/src/netlist.lua
@@ -116,5 +116,6 @@ files {
MAME_DIR .. "src/emu/netlist/devices/nld_system.h",
MAME_DIR .. "src/emu/netlist/devices/nld_cmos.h",
MAME_DIR .. "src/emu/netlist/devices/nld_signal.h",
+ MAME_DIR .. "src/emu/netlist/devices/nld_truthtable.c",
MAME_DIR .. "src/emu/netlist/devices/nld_truthtable.h",
}
diff --git a/src/emu/netlist/devices/nld_truthtable.c b/src/emu/netlist/devices/nld_truthtable.c
new file mode 100644
index 00000000000..54733eb160f
--- /dev/null
+++ b/src/emu/netlist/devices/nld_truthtable.c
@@ -0,0 +1,189 @@
+// license:GPL-2.0+
+// copyright-holders:Couriersud
+/*
+ * nld_truthtable.c
+ *
+ */
+
+#include "nld_truthtable.h"
+
+static inline int count_bits(UINT32 v)
+{
+ int ret = 0;
+ for (int i=0; i<32; i++)
+ if (v & (1<<i))
+ ret++;
+ return ret;
+}
+
+static inline UINT32 set_bits(UINT32 v, UINT32 b)
+{
+ UINT32 ret = 0;
+ for (int i=0; i<32; i++)
+ if (v & (1<<i))
+ {
+ ret |= ((b&1)<<i);
+ b = b >> 1;
+ }
+ return ret;
+}
+
+
+// ----------------------------------------------------------------------------------------
+// desc
+// ----------------------------------------------------------------------------------------
+
+ATTR_COLD void truthtable_desc_t::help(int cur, nl_util::pstring_list list,
+ UINT64 state,UINT16 val, UINT8 *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 UINT64 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
+ m_outs[nstate] = val;
+ for (int j=0; j<m_NO; j++)
+ m_timing[nstate * m_NO + j] = timing_index[j];
+ }
+ }
+}
+
+ATTR_COLD void truthtable_desc_t::setup(const char **truthtable)
+{
+ if (*m_initialized)
+ return;
+
+ pstring ttline = pstring(truthtable[0]);
+ truthtable++;
+ ttline = pstring(truthtable[0]);
+ truthtable++;
+
+ for (int j=0; j < m_size; j++)
+ m_outs[j] = -1;
+
+ for (int j=0; j < 16; j++)
+ m_timing_nt[j] = netlist_time::zero;
+
+ while (!ttline.equals(""))
+ {
+ nl_util::pstring_list io = nl_util::split(ttline,"|");
+ // checks
+ nl_assert_always(io.count() == 3, "io.count mismatch");
+ nl_util::pstring_list inout = nl_util::split(io[0], ",");
+ nl_assert_always(inout.count() == m_num_bits, "number of bits not matching");
+ nl_util::pstring_list out = nl_util::split(io[1], ",");
+ nl_assert_always(out.count() == m_NO, "output count not matching");
+ nl_util::pstring_list times = nl_util::split(io[2], ",");
+ nl_assert_always(times.count() == m_NO, "timing count not matching");
+
+ UINT16 val = 0;
+ UINT8 tindex[m_NO];
+ for (int j=0; j<m_NO; j++)
+ {
+ pstring outs = out[j].trim();
+ if (outs.equals("1"))
+ val = val | (1 << j);
+ else
+ nl_assert_always(outs.equals("0"), "Unknown value (not 0 or 1");
+ netlist_time t = netlist_time::from_nsec(times[j].trim().as_long());
+ int k=0;
+ while (m_timing_nt[k] != netlist_time::zero && m_timing_nt[k] != t)
+ k++;
+ m_timing_nt[k] = t;
+ tindex[j] = k;
+ }
+
+ help(0, inout, 0 , val, tindex);
+ ttline = pstring(truthtable[0]);
+ truthtable++;
+ }
+
+ // determine ignore
+ UINT32 ign[m_size];
+
+ for (int i=0; i<m_size; i++)
+ {
+#if 1
+ UINT32 m_enable = 0;
+ for (int j=0; j<m_size; j++)
+ {
+ if (m_outs[j] != m_outs[i])
+ {
+ m_enable |= (i ^ j);
+ }
+ }
+ ign[i] = m_enable ^ (m_size - 1);
+#else
+ // this doesn't work in all cases and is dog slow
+ UINT32 nign = 0;
+ for (int j=0; j<m_NI; j++)
+ {
+ if (m_outs[i] == m_outs[i ^ (1 << j)])
+ nign |= (1<<j);
+ }
+ /* Check all permutations of ign
+ */
+ int t[1<<count_bits(nign)];
+
+ for (UINT32 j=0; j<(1<<count_bits(nign)); j++)
+ {
+ UINT32 tign = set_bits(nign, j);
+ t[j] = 0;
+ for (UINT32 k=0; k<(1<<count_bits(tign)); k++)
+ {
+ UINT32 b=set_bits(tign, k);
+ if (m_outs[i] != m_outs[(i & ~tign) | b])
+ t[j] = 1;
+ }
+ //printf("x %d %d\n", j, tign);
+ }
+ UINT32 jb=0;
+ UINT32 jm=0;
+ for (UINT32 j=0; j<(1<<count_bits(nign)); j++)
+ {
+ int nb = count_bits(j);
+ if ((t[j] == 0)&& (nb>jb))
+ {
+ jb = nb;
+ jm = j;
+ }
+ }
+ ign[i] = set_bits(nign, jm);
+#endif
+ }
+ for (int i=0; i<m_size; i++)
+ {
+ m_outs[i] |= (ign[i] << m_NO);
+ }
+ *m_initialized = true;
+
+}
+
+
diff --git a/src/emu/netlist/devices/nld_truthtable.h b/src/emu/netlist/devices/nld_truthtable.h
index 2ab64bc8b42..ad2683f4f74 100644
--- a/src/emu/netlist/devices/nld_truthtable.h
+++ b/src/emu/netlist/devices/nld_truthtable.h
@@ -32,26 +32,37 @@ static inline UINT32 remove_first_bit(UINT32 v)
return v;
}
-static inline int count_bits(UINT32 v)
+struct truthtable_desc_t
{
- int ret = 0;
- for (int i=0; i<32; i++)
- if (v & (1<<i))
- ret++;
- return ret;
-}
+ truthtable_desc_t(int NO, int NI, int has_state, bool *initialized,
+ UINT32 *outs, UINT8 *timing, netlist_time *timing_nt)
+ : m_NO(NO), m_NI(NI), m_has_state(has_state), m_initialized(initialized),
+ m_outs(outs), m_timing(timing), m_timing_nt(timing_nt),
+ m_num_bits(m_NI + has_state * (m_NI + m_NO)),
+ m_size(1 << (m_num_bits))
+ {
+ }
-static inline UINT32 set_bits(UINT32 v, UINT32 b)
-{
- UINT32 ret = 0;
- for (int i=0; i<32; i++)
- if (v & (1<<i))
- {
- ret |= ((b&1)<<i);
- b = b >> 1;
- }
- return ret;
-}
+ ATTR_COLD void setup(const char **truthtable);
+
+private:
+ ATTR_COLD void help(int cur, nl_util::pstring_list list,
+ UINT64 state,UINT16 val, UINT8 *timing_index);
+
+ int m_NO;
+ int m_NI;
+ int m_has_state;
+ bool *m_initialized;
+ UINT32 *m_outs;
+ UINT8 *m_timing;
+ netlist_time *m_timing_nt;
+
+ /* additional values */
+
+ const int m_num_bits;
+ const int m_size;
+
+};
template<int m_NI, int m_NO, int has_state>
class nld_truthtable_t : public netlist_device_t
@@ -63,11 +74,13 @@ public:
struct truthtable_t
{
- truthtable_t() : m_initialized(false) {}
+ truthtable_t() : m_initialized(false),
+ m_desc(m_NO, m_NI, has_state, &m_initialized, m_outs, m_timing, m_timing_nt) {}
+ bool m_initialized;
UINT32 m_outs[m_size];
UINT8 m_timing[m_size * m_NO];
netlist_time m_timing_nt[16];
- bool m_initialized;
+ truthtable_desc_t m_desc;
};
nld_truthtable_t(truthtable_t *ttbl, const char *desc[])
@@ -112,172 +125,16 @@ public:
}
}
m_ign = 0;
- setup_tt();
- // FIXME: save state
- }
-
- ATTR_COLD void help(int cur, nl_util::pstring_list list,
- UINT64 state,UINT16 val, UINT8 timing_index[m_NO])
- {
- 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 UINT64 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
- m_ttp->m_outs[nstate] = val;
- for (int j=0; j<m_NO; j++)
- m_ttp->m_timing[nstate * m_NO + j] = timing_index[j];
- }
- }
- }
-
- ATTR_COLD void setup_tt()
- {
- if (m_ttp->m_initialized)
- return;
-
- const char **truthtable = m_desc;
- pstring ttline = pstring(truthtable[0]);
- truthtable++;
- ttline = pstring(truthtable[0]);
- truthtable++;
-
- for (int j=0; j < m_size; j++)
- m_ttp->m_outs[j] = -1;
-
- for (int j=0; j < 16; j++)
- m_ttp->m_timing_nt[j] = netlist_time::zero;
-
- while (!ttline.equals(""))
- {
- nl_util::pstring_list io = nl_util::split(ttline,"|");
- // checks
- nl_assert_always(io.count() == 3, "io.count mismatch");
- nl_util::pstring_list inout = nl_util::split(io[0], ",");
- nl_assert_always(inout.count() == m_num_bits, "number of bits not matching");
- nl_util::pstring_list out = nl_util::split(io[1], ",");
- nl_assert_always(out.count() == m_NO, "output count not matching");
- nl_util::pstring_list times = nl_util::split(io[2], ",");
- nl_assert_always(times.count() == m_NO, "timing count not matching");
-
- UINT16 val = 0;
- UINT8 tindex[m_NO];
- for (int j=0; j<m_NO; j++)
- {
- pstring outs = out[j].trim();
- if (outs.equals("1"))
- val = val | (1 << j);
- else
- nl_assert_always(outs.equals("0"), "Unknown value (not 0 or 1");
- netlist_time t = netlist_time::from_nsec(times[j].trim().as_long());
- int k=0;
- while (m_ttp->m_timing_nt[k] != netlist_time::zero && m_ttp->m_timing_nt[k] != t)
- k++;
- m_ttp->m_timing_nt[k] = t;
- tindex[j] = k;
- }
-
- help(0, inout, 0 , val, tindex);
- ttline = pstring(truthtable[0]);
- truthtable++;
- }
-
- // ((nignore & ((1 << m_NI)-1)) << m_NO)
-
- // determine ignore
- UINT32 ign[m_size];
-
- for (int i=0; i<m_size; i++)
- {
-#if 1
- UINT32 m_enable = 0;
- for (int j=0; j<m_size; j++)
- {
- if (m_ttp->m_outs[j] != m_ttp->m_outs[i])
- {
- m_enable |= (i ^ j);
- }
- }
- ign[i] = m_enable ^ (m_size - 1);
-#else
- // this doesn't work in all cases and is dog slow
- UINT32 nign = 0;
- for (int j=0; j<m_NI; j++)
- {
- if (m_ttp->m_outs[i] == m_ttp->m_outs[i ^ (1 << j)])
- nign |= (1<<j);
- }
- /* Check all permutations of ign
- */
- int t[1<<count_bits(nign)];
-
- for (UINT32 j=0; j<(1<<count_bits(nign)); j++)
- {
- UINT32 tign = set_bits(nign, j);
- t[j] = 0;
- for (UINT32 k=0; k<(1<<count_bits(tign)); k++)
- {
- UINT32 b=set_bits(tign, k);
- if (m_ttp->m_outs[i] != m_ttp->m_outs[(i & ~tign) | b])
- t[j] = 1;
- }
- //printf("x %d %d\n", j, tign);
- }
- UINT32 jb=0;
- UINT32 jm=0;
- for (UINT32 j=0; j<(1<<count_bits(nign)); j++)
- {
- int nb = count_bits(j);
- if ((t[j] == 0)&& (nb>jb))
- {
- jb = nb;
- jm = j;
- }
- }
- ign[i] = set_bits(nign, jm);
-#endif
- }
- for (int i=0; i<m_size; i++)
- {
- m_ttp->m_outs[i] |= (ign[i] << m_NO);
- }
+ m_ttp->m_desc.setup(m_desc);
#if 0
printf("%s\n", name().cstr());
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][0]);
+ 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
- m_ttp->m_initialized = true;
-
+ // FIXME: save state
}
ATTR_COLD void reset()
@@ -366,4 +223,7 @@ private:
const char **m_desc;
};
+
+
+
#endif /* NLD_TRUTHTABLE_H_ */