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: 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() NETLIB_RESETI()
{ {
m_cnt = 0; m_cnt = 0;
@ -47,12 +80,6 @@ namespace devices
m_last_B = 0; 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_A;
logic_input_t m_B; logic_input_t m_B;
logic_input_t m_R1; logic_input_t m_R1;
@ -96,40 +123,6 @@ namespace devices
NETLIB_SUB(7490) A; 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, "TTL_7490", "+A,+B,+R1,+R2,+R91,+R92,@VCC,@GND")
NETLIB_DEVICE_IMPL(7490_dip, "TTL_7490_DIP", "") NETLIB_DEVICE_IMPL(7490_dip, "TTL_7490_DIP", "")

View File

@ -37,7 +37,37 @@ namespace devices
} }
private: 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() NETLIB_RESETI()
{ {
m_cnt = 0; m_cnt = 0;
@ -45,12 +75,6 @@ namespace devices
m_last_B = 0; 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_A;
logic_input_t m_B; logic_input_t m_B;
logic_input_t m_R1; logic_input_t m_R1;
@ -92,37 +116,6 @@ namespace devices
NETLIB_SUB(7492) A; 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, "TTL_7492", "+A,+B,+R1,+R2,@VCC,@GND")
NETLIB_DEVICE_IMPL(7492_dip, "TTL_7492_DIP", "") 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_CLKA(*this, "CLKA", NETLIB_DELEGATE(7493, updA))
, m_CLKB(*this, "CLKB", NETLIB_DELEGATE(7493, updB)) , m_CLKB(*this, "CLKB", NETLIB_DELEGATE(7493, updB))
, m_QA(*this, "QA") , m_QA(*this, "QA")
, m_QB(*this, "QB") , m_QB(*this, {"QB", "QC", "QD"})
, m_QC(*this, "QC")
, m_QD(*this, "QD")
, m_power_pins(*this) , m_power_pins(*this)
{ {
} }
@ -116,8 +114,6 @@ namespace netlist
m_CLKB.inactivate(); m_CLKB.inactivate();
m_QA.push(0, NLTIME_FROM_NS(40)); m_QA.push(0, NLTIME_FROM_NS(40));
m_QB.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; m_a = m_bcd = 0;
} }
} }
@ -131,9 +127,9 @@ namespace netlist
NETLIB_HANDLERI(updB) NETLIB_HANDLERI(updB)
{ {
const auto cnt(++m_bcd &= 0x07); const auto cnt(++m_bcd &= 0x07);
m_QD.push((cnt >> 2) & 1, out_delay3); m_QB[2].push((cnt >> 2) & 1, out_delay3);
m_QC.push((cnt >> 1) & 1, out_delay2); m_QB[1].push((cnt >> 1) & 1, out_delay2);
m_QB.push(cnt & 1, out_delay); m_QB[0].push(cnt & 1, out_delay);
} }
logic_input_t m_R1; logic_input_t m_R1;
@ -146,9 +142,7 @@ namespace netlist
logic_input_t m_CLKB; logic_input_t m_CLKB;
logic_output_t m_QA; logic_output_t m_QA;
logic_output_t m_QB; object_array_t<logic_output_t, 3> m_QB;
logic_output_t m_QC;
logic_output_t m_QD;
nld_power_pins m_power_pins; nld_power_pins m_power_pins;
}; };

View File

@ -4,7 +4,6 @@
* nld_9316.c * nld_9316.c
* *
*/ */
#include "nld_9316.h" #include "nld_9316.h"
#include "netlist/nl_base.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_ABCD(*this, {"A", "B", "C", "D"}, NETLIB_DELEGATE(9316_base, abcd))
, m_Q(*this, { "QA", "QB", "QC", "QD" }) , m_Q(*this, { "QA", "QB", "QC", "QD" })
, m_cnt(*this, "m_cnt", 0) , 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) , m_power_pins(*this)
{ {
} }
@ -41,14 +42,16 @@ namespace netlist
{ {
m_CLK.set_state(logic_t::STATE_INP_LH); m_CLK.set_state(logic_t::STATE_INP_LH);
m_cnt = 0; m_cnt = 0;
//m_abcd = 0; m_abcd = 0;
} }
NETLIB_UPDATEI() NETLIB_UPDATEI()
{ {
const auto CLRQ(m_CLRQ()); 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(); m_CLK.activate_lh();
} }
@ -61,7 +64,7 @@ namespace netlist
m_Q.push(m_cnt, NLTIME_FROM_NS(36)); 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 else
{ {
//const auto cnt = (m_LOADQ() ? (m_cnt + 1) & MAXCNT: m_abcd); //const auto cnt = (m_LOADQ() ? (m_cnt + 1) & MAXCNT: m_abcd);
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)); m_RC.push(m_ent && (cnt == MAXCNT), NLTIME_FROM_NS(27));
m_Q.push(cnt, NLTIME_FROM_NS(20)); m_Q.push(cnt, NLTIME_FROM_NS(20));
m_cnt = static_cast<unsigned>(cnt); m_cnt = static_cast<unsigned>(cnt);
} }
@ -84,7 +87,7 @@ namespace netlist
NETLIB_HANDLERI(abcd) NETLIB_HANDLERI(abcd)
{ {
//m_abcd = static_cast<unsigned>(m_ABCD()); m_abcd = static_cast<unsigned>(m_ABCD());
} }
logic_input_t m_CLK; logic_input_t m_CLK;
@ -103,7 +106,9 @@ namespace netlist
/* counter state */ /* counter state */
state_var<unsigned> m_cnt; state_var<unsigned> m_cnt;
/* cached pins */ /* 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; nld_power_pins m_power_pins;
}; };

View File

@ -2027,7 +2027,6 @@ namespace netlist
template<class D, std::size_t ND> template<class D, std::size_t ND>
object_array_t(D &dev, std::size_t offset, std::size_t qmask, 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) const pstring &fmt, std::array<nldelegate, ND> &&delegates)
{ {
passert_always_msg(delegates.size() >= N, "initializer_list size mismatch"); 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; value_type operator ()()
using value_type = std::uint_fast32_t; {
#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 ()() value_type operator ()()
{ {
if (N == 1) return e<0>(); if (N == 1) return e<0>();
@ -2073,6 +2095,7 @@ namespace netlist
private: private:
template <std::size_t P> template <std::size_t P>
inline constexpr value_type e() const { return (*this)[P](); } inline constexpr value_type e() const { return (*this)[P](); }
#endif
}; };
template<std::size_t N> 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 = object_array_base_t<logic_output_t, N>;
using base_type::base_type; using base_type::base_type;
using value_type = std::uint_fast32_t; template <typename T>
//using value_type = typename plib::least_type_for_bits<N>::type; inline void push(const T &v, const netlist_time &t)
void push(value_type v, netlist_time t)
{ {
if (N >= 1) (*this)[0].push((v >> 0) & 1, t); if (N >= 1) (*this)[0].push((v >> 0) & 1, t);
if (N >= 2) (*this)[1].push((v >> 1) & 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 >= 6) (*this)[5].push((v >> 5) & 1, t);
if (N >= 7) (*this)[6].push((v >> 6) & 1, t); if (N >= 7) (*this)[6].push((v >> 6) & 1, t);
if (N >= 8) (*this)[7].push((v >> 7) & 1, t); if (N >= 8) (*this)[7].push((v >> 7) & 1, t);
for (std::size_t i = 8; i < N; i++) for (std::size_t i = 8; i < N; i++)
(*this)[i].push((v >> i) & 1, t); (*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, void set_tristate(bool v,
netlist_time ts_off_on, netlist_time ts_on_off) noexcept netlist_time ts_off_on, netlist_time ts_on_off) noexcept
{ {
for (std::size_t i = 0; i < N; i++) for (std::size_t i = 0; i < N; i++)
(*this)[i].set_tristate(v, ts_off_on, ts_on_off); (*this)[i].set_tristate(v, ts_off_on, ts_on_off);
} }
}; };
template<std::size_t N> 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 = object_array_base_t<tristate_output_t, N>;
using base_type::base_type; using base_type::base_type;
using value_type = std::uint_fast32_t; template <typename T>
//using value_type = typename plib::least_type_for_bits<N>::type; inline void push(const T &v, const netlist_time &t)
void push(value_type v, netlist_time t)
{ {
if (N >= 1) (*this)[0].push((v >> 0) & 1, t); if (N >= 1) (*this)[0].push((v >> 0) & 1, t);
if (N >= 2) (*this)[1].push((v >> 1) & 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 >= 6) (*this)[5].push((v >> 5) & 1, t);
if (N >= 7) (*this)[6].push((v >> 6) & 1, t); if (N >= 7) (*this)[6].push((v >> 6) & 1, t);
if (N >= 8) (*this)[7].push((v >> 7) & 1, t); if (N >= 8) (*this)[7].push((v >> 7) & 1, t);
for (std::size_t i = 8; i < N; i++) for (std::size_t i = 8; i < N; i++)
(*this)[i].push((v >> i) & 1, t); (*this)[i].push((v >> i) & 1, t);
} }

View File

@ -89,7 +89,7 @@ namespace plib
#endif #endif
template<unsigned bits> template<unsigned bits>
struct least_size_for_bits struct size_for_bits
{ {
enum { value = enum { value =
bits <= 8 ? 1 : 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<4> { using type = uint_least32_t; };
template<> struct least_type_for_size<8> { using type = uint_least64_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> template<unsigned bits>
struct least_type_for_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;
}; };
//============================================================ //============================================================