Slightly improve event timing if state changes.

Also introduce a push_force call to reschedule already pending events if
the state will not change. (nw)
This commit is contained in:
couriersud 2017-02-19 16:55:17 +01:00
parent 0e76e0abb6
commit 0bdffa7e97
3 changed files with 36 additions and 23 deletions

View File

@ -1,7 +1,7 @@
// license:GPL-2.0+
// copyright-holders:Couriersud
/*
* nld_7493.c
* nld_7493.cpp
*
*/
@ -34,6 +34,7 @@ namespace netlist
{
}
private:
NETLIB_RESETI();
NETLIB_UPDATEI();
@ -57,7 +58,6 @@ namespace netlist
}
}
private:
logic_input_t m_R1;
logic_input_t m_R2;
@ -70,7 +70,7 @@ namespace netlist
logic_output_t m_QD;
state_var<netlist_sig_t> m_reset;
state_var_u8 m_a;
state_var<netlist_sig_t> m_a;
state_var_u8 m_bcd;
};
@ -118,10 +118,10 @@ namespace netlist
{
m_CLKA.inactivate();
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_QA.push_force(0, NLTIME_FROM_NS(40));
m_QB.push_force(0, NLTIME_FROM_NS(40));
m_QC.push_force(0, NLTIME_FROM_NS(40));
m_QD.push_force(0, NLTIME_FROM_NS(40));
m_a = m_bcd = 0;
}
}

View File

@ -183,21 +183,13 @@ namespace netlist
{
auto *t = &m_ttp->m_timing[timebase];
for (std::size_t i = 0; i < m_NO; ++i)
{
m_Q[i].push(out & 1, m_ttp->m_timing_nt[*t]);
++t;
out >>= 1;
}
m_Q[i].push((out >> i) & 1, m_ttp->m_timing_nt[t[i]]);
}
else
{
auto *t = &m_ttp->m_timing[timebase];
for (std::size_t i = 0; i < m_NO; ++i)
{
m_Q[i].net().set_Q_time(out & 1, mt + m_ttp->m_timing_nt[*t]);
++t;
out >>= 1;
}
m_Q[i].set_Q_time((out >> i) & 1, mt + m_ttp->m_timing_nt[t[i]]);
}
if (m_NI > 1)

View File

@ -698,7 +698,7 @@ namespace netlist
void reset();
void toggle_new_Q() NL_NOEXCEPT { m_new_Q ^= 1; }
void toggle_new_Q() NL_NOEXCEPT { m_new_Q ^= 1; }
void force_queue_execution() NL_NOEXCEPT { m_new_Q = (m_cur_Q ^ 1); }
void push_to_queue(const netlist_time delay) NL_NOEXCEPT;
@ -707,7 +707,7 @@ namespace netlist
void update_devs() NL_NOEXCEPT;
const netlist_time time() const NL_NOEXCEPT { return m_time; }
netlist_time time() const NL_NOEXCEPT { return m_time; }
void set_time(const netlist_time ntime) NL_NOEXCEPT { m_time = ntime; }
bool isRailNet() const { return !(m_railterminal == nullptr); }
@ -760,9 +760,17 @@ namespace netlist
netlist_sig_t new_Q() const NL_NOEXCEPT { return m_new_Q; }
void initial(const netlist_sig_t val) NL_NOEXCEPT { m_cur_Q = m_new_Q = val; }
void set_Q(const netlist_sig_t newQ, const netlist_time delay) NL_NOEXCEPT
void set_Q_and_push(const netlist_sig_t newQ, const netlist_time delay) NL_NOEXCEPT
{
if (newQ != m_new_Q)
if (newQ != m_new_Q )
{
m_new_Q = newQ;
push_to_queue(delay);
}
}
void set_Q_and_push_force(const netlist_sig_t newQ, const netlist_time delay) NL_NOEXCEPT
{
if (newQ != m_new_Q || is_queued())
{
m_new_Q = newQ;
push_to_queue(delay);
@ -826,7 +834,17 @@ namespace netlist
void push(const netlist_sig_t newQ, const netlist_time delay) NL_NOEXCEPT
{
m_my_net.set_Q(newQ, delay); // take the shortcut
m_my_net.set_Q_and_push(newQ, delay); // take the shortcut
}
void push_force(const netlist_sig_t newQ, const netlist_time delay) NL_NOEXCEPT
{
m_my_net.set_Q_and_push_force(newQ, delay); // take the shortcut
}
void set_Q_time(const netlist_sig_t newQ, const netlist_time at) NL_NOEXCEPT
{
m_my_net.set_Q_time(newQ, at); // take the shortcut
}
private:
@ -1374,8 +1392,10 @@ namespace netlist
inline void detail::net_t::push_to_queue(const netlist_time delay) NL_NOEXCEPT
{
if (!is_queued() && (num_cons() != 0))
if ((num_cons() != 0))
{
if (is_queued())
netlist().queue().remove(this);
m_time = netlist().time() + delay;
m_in_queue = (m_active > 0); /* queued ? */
if (m_in_queue)
@ -1383,6 +1403,7 @@ namespace netlist
}
}
// FIXME: this could be removed after testing
inline void detail::net_t::reschedule_in_queue(const netlist_time delay) NL_NOEXCEPT
{
if (is_queued())