summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author couriersud <couriersud@gmx.org>2020-05-21 09:46:57 +0200
committer couriersud <couriersud@gmx.org>2020-05-22 01:15:17 +0200
commitdae6a396c9c79e1ccc6587dc3be1764df62dc61c (patch)
tree1c0e128525661603a3a95087637768f6e50f6b5a
parentba232b1c4a6eacddd8ee0e50603f46cdeaf12062 (diff)
netlist: fix performance decrease. (nw)
-rw-r--r--src/lib/netlist/devices/nld_7490.cpp75
-rw-r--r--src/lib/netlist/devices/nld_7492.cpp69
-rw-r--r--src/lib/netlist/devices/nld_7493.cpp16
-rw-r--r--src/lib/netlist/devices/nld_9316.cpp23
-rw-r--r--src/lib/netlist/nl_base.h61
-rw-r--r--src/lib/netlist/plib/ptypes.h16
6 files changed, 145 insertions, 115 deletions
diff --git a/src/lib/netlist/devices/nld_7490.cpp b/src/lib/netlist/devices/nld_7490.cpp
index f38650daeb2..e923232f278 100644
--- a/src/lib/netlist/devices/nld_7490.cpp
+++ b/src/lib/netlist/devices/nld_7490.cpp
@@ -39,7 +39,40 @@ namespace devices
}
private:
- NETLIB_UPDATEI();
+ NETLIB_UPDATEI()
+ {
+ const netlist_sig_t new_A = m_A();
+ const netlist_sig_t new_B = m_B();
+
+ if (m_R91() & m_R92())
+ {
+ m_cnt = 9;
+ m_Q.push(9, delay);
+ }
+ else if (m_R1() & m_R2())
+ {
+ m_cnt = 0;
+ m_Q.push(0, delay);
+ }
+ else
+ {
+ if (m_last_A && !new_A) // High - Low
+ {
+ m_cnt ^= 1;
+ m_Q[0].push(m_cnt & 1, delay[0]);
+ }
+ if (m_last_B && !new_B) // High - Low
+ {
+ m_cnt += 2;
+ if (m_cnt >= 10)
+ m_cnt &= 1; /* Output A is not reset! */
+ m_Q.push(m_cnt, delay);
+ }
+ }
+ m_last_A = new_A;
+ m_last_B = new_B;
+ }
+
NETLIB_RESETI()
{
m_cnt = 0;
@@ -47,12 +80,6 @@ namespace devices
m_last_B = 0;
}
- void update_outputs() noexcept
- {
- for (std::size_t i=0; i<4; i++)
- m_Q[i].push((m_cnt >> i) & 1, delay[i]);
- }
-
logic_input_t m_A;
logic_input_t m_B;
logic_input_t m_R1;
@@ -96,40 +123,6 @@ namespace devices
NETLIB_SUB(7490) A;
};
- NETLIB_UPDATE(7490)
- {
- const netlist_sig_t new_A = m_A();
- const netlist_sig_t new_B = m_B();
-
- if (m_R91() & m_R92())
- {
- m_cnt = 9;
- update_outputs();
- }
- else if (m_R1() & m_R2())
- {
- m_cnt = 0;
- update_outputs();
- }
- else
- {
- if (m_last_A && !new_A) // High - Low
- {
- m_cnt ^= 1;
- m_Q[0].push(m_cnt & 1, delay[0]);
- }
- if (m_last_B && !new_B) // High - Low
- {
- m_cnt += 2;
- if (m_cnt >= 10)
- m_cnt &= 1; /* Output A is not reset! */
- update_outputs();
- }
- }
- m_last_A = new_A;
- m_last_B = new_B;
- }
-
NETLIB_DEVICE_IMPL(7490, "TTL_7490", "+A,+B,+R1,+R2,+R91,+R92,@VCC,@GND")
NETLIB_DEVICE_IMPL(7490_dip, "TTL_7490_DIP", "")
diff --git a/src/lib/netlist/devices/nld_7492.cpp b/src/lib/netlist/devices/nld_7492.cpp
index 603daf21588..39dce8217eb 100644
--- a/src/lib/netlist/devices/nld_7492.cpp
+++ b/src/lib/netlist/devices/nld_7492.cpp
@@ -37,7 +37,37 @@ namespace devices
}
private:
- NETLIB_UPDATEI();
+ NETLIB_UPDATEI()
+ {
+ const netlist_sig_t new_A = m_A();
+ const netlist_sig_t new_B = m_B();
+
+ if (m_R1() & m_R2())
+ {
+ m_cnt = 0;
+ m_Q.push(0, delay);
+ }
+ else
+ {
+ if (m_last_A && !new_A) // High - Low
+ {
+ m_cnt ^= 1;
+ m_Q[0].push(m_cnt & 1, delay[0]);
+ }
+ if (m_last_B && !new_B) // High - Low
+ {
+ m_cnt += 2;
+ if (m_cnt == 6)
+ m_cnt = 8;
+ if (m_cnt == 14)
+ m_cnt = 0;
+ m_Q.push(m_cnt, delay);
+ }
+ }
+ m_last_A = new_A;
+ m_last_B = new_B;
+ }
+
NETLIB_RESETI()
{
m_cnt = 0;
@@ -45,12 +75,6 @@ namespace devices
m_last_B = 0;
}
- void update_outputs() noexcept
- {
- for (std::size_t i=0; i<4; i++)
- m_Q[i].push((m_cnt >> i) & 1, delay[i]);
- }
-
logic_input_t m_A;
logic_input_t m_B;
logic_input_t m_R1;
@@ -92,37 +116,6 @@ namespace devices
NETLIB_SUB(7492) A;
};
- NETLIB_UPDATE(7492)
- {
- const netlist_sig_t new_A = m_A();
- const netlist_sig_t new_B = m_B();
-
- if (m_R1() & m_R2())
- {
- m_cnt = 0;
- update_outputs();
- }
- else
- {
- if (m_last_A && !new_A) // High - Low
- {
- m_cnt ^= 1;
- m_Q[0].push(m_cnt & 1, delay[0]);
- }
- if (m_last_B && !new_B) // High - Low
- {
- m_cnt += 2;
- if (m_cnt == 6)
- m_cnt = 8;
- if (m_cnt == 14)
- m_cnt = 0;
- update_outputs();
- }
- }
- m_last_A = new_A;
- m_last_B = new_B;
- }
-
NETLIB_DEVICE_IMPL(7492, "TTL_7492", "+A,+B,+R1,+R2,@VCC,@GND")
NETLIB_DEVICE_IMPL(7492_dip, "TTL_7492_DIP", "")
diff --git a/src/lib/netlist/devices/nld_7493.cpp b/src/lib/netlist/devices/nld_7493.cpp
index ec2fd9f89fc..2d6e16bb56e 100644
--- a/src/lib/netlist/devices/nld_7493.cpp
+++ b/src/lib/netlist/devices/nld_7493.cpp
@@ -88,9 +88,7 @@ namespace netlist
, m_CLKA(*this, "CLKA", NETLIB_DELEGATE(7493, updA))
, m_CLKB(*this, "CLKB", NETLIB_DELEGATE(7493, updB))
, m_QA(*this, "QA")
- , m_QB(*this, "QB")
- , m_QC(*this, "QC")
- , m_QD(*this, "QD")
+ , m_QB(*this, {"QB", "QC", "QD"})
, m_power_pins(*this)
{
}
@@ -116,8 +114,6 @@ namespace netlist
m_CLKB.inactivate();
m_QA.push(0, NLTIME_FROM_NS(40));
m_QB.push(0, NLTIME_FROM_NS(40));
- m_QC.push(0, NLTIME_FROM_NS(40));
- m_QD.push(0, NLTIME_FROM_NS(40));
m_a = m_bcd = 0;
}
}
@@ -131,9 +127,9 @@ namespace netlist
NETLIB_HANDLERI(updB)
{
const auto cnt(++m_bcd &= 0x07);
- m_QD.push((cnt >> 2) & 1, out_delay3);
- m_QC.push((cnt >> 1) & 1, out_delay2);
- m_QB.push(cnt & 1, out_delay);
+ m_QB[2].push((cnt >> 2) & 1, out_delay3);
+ m_QB[1].push((cnt >> 1) & 1, out_delay2);
+ m_QB[0].push(cnt & 1, out_delay);
}
logic_input_t m_R1;
@@ -146,9 +142,7 @@ namespace netlist
logic_input_t m_CLKB;
logic_output_t m_QA;
- logic_output_t m_QB;
- logic_output_t m_QC;
- logic_output_t m_QD;
+ object_array_t<logic_output_t, 3> m_QB;
nld_power_pins m_power_pins;
};
diff --git a/src/lib/netlist/devices/nld_9316.cpp b/src/lib/netlist/devices/nld_9316.cpp
index 7404370205c..f4f7dbee412 100644
--- a/src/lib/netlist/devices/nld_9316.cpp
+++ b/src/lib/netlist/devices/nld_9316.cpp
@@ -4,7 +4,6 @@
* nld_9316.c
*
*/
-
#include "nld_9316.h"
#include "netlist/nl_base.h"
@@ -31,7 +30,9 @@ namespace netlist
, m_ABCD(*this, {"A", "B", "C", "D"}, NETLIB_DELEGATE(9316_base, abcd))
, m_Q(*this, { "QA", "QB", "QC", "QD" })
, m_cnt(*this, "m_cnt", 0)
- //, m_abcd(*this, "m_abcd", 0)
+ , m_abcd(*this, "m_abcd", 0)
+ , m_loadq(*this, "m_loadq", 0)
+ , m_ent(*this, "m_ent", 0)
, m_power_pins(*this)
{
}
@@ -41,14 +42,16 @@ namespace netlist
{
m_CLK.set_state(logic_t::STATE_INP_LH);
m_cnt = 0;
- //m_abcd = 0;
+ m_abcd = 0;
}
NETLIB_UPDATEI()
{
const auto CLRQ(m_CLRQ());
+ m_ent = m_ENT();
+ m_loadq = m_LOADQ();
- if (((m_LOADQ() ^ 1) || (m_ENT() && m_ENP())) && (!ASYNC || CLRQ))
+ if (((m_loadq ^ 1) || (m_ent && m_ENP())) && (!ASYNC || CLRQ))
{
m_CLK.activate_lh();
}
@@ -61,7 +64,7 @@ namespace netlist
m_Q.push(m_cnt, NLTIME_FROM_NS(36));
}
}
- m_RC.push(m_ENT() && (m_cnt == MAXCNT), NLTIME_FROM_NS(27));
+ m_RC.push(m_ent && (m_cnt == MAXCNT), NLTIME_FROM_NS(27));
}
@@ -75,8 +78,8 @@ namespace netlist
else
{
//const auto cnt = (m_LOADQ() ? (m_cnt + 1) & MAXCNT: m_abcd);
- const auto cnt = (m_LOADQ() ? (m_cnt + 1) & MAXCNT: m_ABCD());
- m_RC.push(m_ENT() && (cnt == MAXCNT), NLTIME_FROM_NS(27));
+ const auto cnt = (m_loadq ? (m_cnt + 1) & MAXCNT: m_abcd);
+ m_RC.push(m_ent && (cnt == MAXCNT), NLTIME_FROM_NS(27));
m_Q.push(cnt, NLTIME_FROM_NS(20));
m_cnt = static_cast<unsigned>(cnt);
}
@@ -84,7 +87,7 @@ namespace netlist
NETLIB_HANDLERI(abcd)
{
- //m_abcd = static_cast<unsigned>(m_ABCD());
+ m_abcd = static_cast<unsigned>(m_ABCD());
}
logic_input_t m_CLK;
@@ -103,7 +106,9 @@ namespace netlist
/* counter state */
state_var<unsigned> m_cnt;
/* cached pins */
- //state_var<unsigned> m_abcd;
+ state_var<unsigned> m_abcd;
+ state_var_sig m_loadq;
+ state_var_sig m_ent;
nld_power_pins m_power_pins;
};
diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h
index db688fac1e6..8f3a7683f0d 100644
--- a/src/lib/netlist/nl_base.h
+++ b/src/lib/netlist/nl_base.h
@@ -2027,7 +2027,6 @@ namespace netlist
template<class D, std::size_t ND>
object_array_t(D &dev, std::size_t offset, std::size_t qmask,
-// const pstring &fmt, std::initializer_list<nldelegate> &delegates)
const pstring &fmt, std::array<nldelegate, ND> &&delegates)
{
passert_always_msg(delegates.size() >= N, "initializer_list size mismatch");
@@ -2045,10 +2044,33 @@ namespace netlist
}
}
+ //using value_type = typename plib::fast_type_for_bits<N>::type;
+ using value_type = std::uint32_t;
+#if 0
- //using value_type = typename plib::least_type_for_bits<N>::type;
- using value_type = std::uint_fast32_t;
+ value_type operator ()()
+ {
+#if 0
+ if (N <= 8)
+ return tobits(N, *this);
+ else
+#endif
+ {
+ value_type r(0);
+ for (std::size_t i = 0; i < N; i++)
+ r = r | static_cast<value_type>((*this)[i]() << i);
+ return r;
+ }
+ }
+ private:
+ template <typename T>
+ static constexpr value_type tobits(std::size_t n, T &a)
+ {
+ return (n == 0 ? 0 : (tobits(n-1, a) | static_cast<value_type>(a[n-1]() << (n-1))));
+ }
+
+#else
value_type operator ()()
{
if (N == 1) return e<0>();
@@ -2073,6 +2095,7 @@ namespace netlist
private:
template <std::size_t P>
inline constexpr value_type e() const { return (*this)[P](); }
+#endif
};
template<std::size_t N>
@@ -2082,10 +2105,8 @@ namespace netlist
using base_type = object_array_base_t<logic_output_t, N>;
using base_type::base_type;
- using value_type = std::uint_fast32_t;
- //using value_type = typename plib::least_type_for_bits<N>::type;
-
- void push(value_type v, netlist_time t)
+ template <typename T>
+ inline void push(const T &v, const netlist_time &t)
{
if (N >= 1) (*this)[0].push((v >> 0) & 1, t);
if (N >= 2) (*this)[1].push((v >> 1) & 1, t);
@@ -2095,18 +2116,33 @@ namespace netlist
if (N >= 6) (*this)[5].push((v >> 5) & 1, t);
if (N >= 7) (*this)[6].push((v >> 6) & 1, t);
if (N >= 8) (*this)[7].push((v >> 7) & 1, t);
-
for (std::size_t i = 8; i < N; i++)
(*this)[i].push((v >> i) & 1, t);
}
+ template<typename T, std::size_t NT>
+ void push(const T &v, const std::array<netlist_time, NT> &t)
+ {
+ static_assert(NT >= N, "Not enough timing entries provided");
+
+ if (N >= 1) (*this)[0].push((v >> 0) & 1, t[0]);
+ if (N >= 2) (*this)[1].push((v >> 1) & 1, t[1]);
+ if (N >= 3) (*this)[2].push((v >> 2) & 1, t[2]);
+ if (N >= 4) (*this)[3].push((v >> 3) & 1, t[3]);
+ if (N >= 5) (*this)[4].push((v >> 4) & 1, t[4]);
+ if (N >= 6) (*this)[5].push((v >> 5) & 1, t[5]);
+ if (N >= 7) (*this)[6].push((v >> 6) & 1, t[6]);
+ if (N >= 8) (*this)[7].push((v >> 7) & 1, t[7]);
+ for (std::size_t i = 8; i < N; i++)
+ (*this)[i].push((v >> i) & 1, t[i]);
+ }
+
void set_tristate(bool v,
netlist_time ts_off_on, netlist_time ts_on_off) noexcept
{
for (std::size_t i = 0; i < N; i++)
(*this)[i].set_tristate(v, ts_off_on, ts_on_off);
}
-
};
template<std::size_t N>
@@ -2116,10 +2152,8 @@ namespace netlist
using base_type = object_array_base_t<tristate_output_t, N>;
using base_type::base_type;
- using value_type = std::uint_fast32_t;
- //using value_type = typename plib::least_type_for_bits<N>::type;
-
- void push(value_type v, netlist_time t)
+ template <typename T>
+ inline void push(const T &v, const netlist_time &t)
{
if (N >= 1) (*this)[0].push((v >> 0) & 1, t);
if (N >= 2) (*this)[1].push((v >> 1) & 1, t);
@@ -2129,7 +2163,6 @@ namespace netlist
if (N >= 6) (*this)[5].push((v >> 5) & 1, t);
if (N >= 7) (*this)[6].push((v >> 6) & 1, t);
if (N >= 8) (*this)[7].push((v >> 7) & 1, t);
-
for (std::size_t i = 8; i < N; i++)
(*this)[i].push((v >> i) & 1, t);
}
diff --git a/src/lib/netlist/plib/ptypes.h b/src/lib/netlist/plib/ptypes.h
index dc762a51107..16c0a5575a3 100644
--- a/src/lib/netlist/plib/ptypes.h
+++ b/src/lib/netlist/plib/ptypes.h
@@ -89,7 +89,7 @@ namespace plib
#endif
template<unsigned bits>
- struct least_size_for_bits
+ struct size_for_bits
{
enum { value =
bits <= 8 ? 1 :
@@ -105,10 +105,22 @@ namespace plib
template<> struct least_type_for_size<4> { using type = uint_least32_t; };
template<> struct least_type_for_size<8> { using type = uint_least64_t; };
+ template<unsigned N> struct fast_type_for_size;
+ template<> struct fast_type_for_size<1> { using type = uint_fast8_t; };
+ template<> struct fast_type_for_size<2> { using type = uint_fast16_t; };
+ template<> struct fast_type_for_size<4> { using type = uint_fast32_t; };
+ template<> struct fast_type_for_size<8> { using type = uint_fast64_t; };
+
template<unsigned bits>
struct least_type_for_bits
{
- using type = typename least_type_for_size<least_size_for_bits<bits>::value>::type;
+ using type = typename least_type_for_size<size_for_bits<bits>::value>::type;
+ };
+
+ template<unsigned bits>
+ struct fast_type_for_bits
+ {
+ using type = typename fast_type_for_size<size_for_bits<bits>::value>::type;
};
//============================================================