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

View File

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

View File

@ -698,7 +698,7 @@ namespace netlist
void reset(); 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 force_queue_execution() NL_NOEXCEPT { m_new_Q = (m_cur_Q ^ 1); }
void push_to_queue(const netlist_time delay) NL_NOEXCEPT; void push_to_queue(const netlist_time delay) NL_NOEXCEPT;
@ -707,7 +707,7 @@ namespace netlist
void update_devs() NL_NOEXCEPT; 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; } void set_time(const netlist_time ntime) NL_NOEXCEPT { m_time = ntime; }
bool isRailNet() const { return !(m_railterminal == nullptr); } 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; } 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 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; m_new_Q = newQ;
push_to_queue(delay); push_to_queue(delay);
@ -826,7 +834,17 @@ namespace netlist
void push(const netlist_sig_t newQ, const netlist_time delay) NL_NOEXCEPT 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: private:
@ -1374,8 +1392,10 @@ namespace netlist
inline void detail::net_t::push_to_queue(const netlist_time delay) NL_NOEXCEPT 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_time = netlist().time() + delay;
m_in_queue = (m_active > 0); /* queued ? */ m_in_queue = (m_active > 0); /* queued ? */
if (m_in_queue) 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 inline void detail::net_t::reschedule_in_queue(const netlist_time delay) NL_NOEXCEPT
{ {
if (is_queued()) if (is_queued())