netlist: fix performance decrease. (nw)

This commit is contained in:
couriersud 2020-05-21 09:46:57 +02:00
parent ba232b1c4a
commit dae6a396c9
6 changed files with 145 additions and 115 deletions

View File

@ -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", "")

View File

@ -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", "")

View File

@ -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;
};

View File

@ -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;
};

View File

@ -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);
}

View File

@ -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;
};
//============================================================