Fix long standing workaround which would ignore policy of "change-only"

propagation. (nw)
This commit is contained in:
couriersud 2016-06-04 01:02:07 +02:00
parent f8e9851677
commit bc1eb91c91
8 changed files with 44 additions and 40 deletions

View File

@ -93,8 +93,8 @@ namespace netlist
}
};
static const netlist_time delay[2] = { NLTIME_FROM_NS(25), NLTIME_FROM_NS(25) };
static const netlist_time delay_clear[2] = { NLTIME_FROM_NS(40), NLTIME_FROM_NS(25) };
const netlist_time delay[2] = { NLTIME_FROM_NS(25), NLTIME_FROM_NS(25) };
const netlist_time delay_clear[2] = { NLTIME_FROM_NS(40), NLTIME_FROM_NS(25) };
NETLIB_RESET(74175_sub)
{

View File

@ -111,7 +111,7 @@ namespace netlist
}
// FIXME: Timing
/* static */ const netlist_time delay[4] =
static const netlist_time delay[4] =
{
NLTIME_FROM_NS(40),
NLTIME_FROM_NS(40),

View File

@ -143,7 +143,7 @@ namespace netlist
const UINT8 G = INPLOGIC(m_G);
if (G)
{
/* static */ const netlist_time delay[2] = { NLTIME_FROM_NS(33), NLTIME_FROM_NS(19) };
const netlist_time delay[2] = { NLTIME_FROM_NS(33), NLTIME_FROM_NS(19) };
OUTLOGIC(m_Y, 0, delay[0]);
OUTLOGIC(m_YQ, 1, delay[1]);
@ -161,7 +161,7 @@ namespace netlist
m_B.activate();
m_C.activate();
}
/* static */ const netlist_time delay[2] = { NLTIME_FROM_NS(33), NLTIME_FROM_NS(28) };
const netlist_time delay[2] = { NLTIME_FROM_NS(33), NLTIME_FROM_NS(28) };
const UINT8 chan = INPLOGIC(m_A) | (INPLOGIC(m_B)<<1) | (INPLOGIC(m_C)<<2);
if (m_last_chan != chan)
{

View File

@ -662,30 +662,25 @@ void net_t::update_devs()
//assert(m_num_cons != 0);
nl_assert(this->isRailNet());
const int masks[4] = { 1, 5, 3, 1 };
const int mask = masks[ (m_cur_Q << 1) | m_new_Q ];
static const unsigned masks[4] =
{
0,
core_terminal_t::STATE_INP_LH | core_terminal_t::STATE_INP_ACTIVE,
core_terminal_t::STATE_INP_HL | core_terminal_t::STATE_INP_ACTIVE,
0
};
const unsigned mask = masks[ m_cur_Q * 2 + m_new_Q ];
m_in_queue = 2; /* mark as taken ... */
m_cur_Q = m_new_Q;
#if 1
for (core_terminal_t *p = m_list_active.first(); p != nullptr; p = p->next())
for (auto p = m_list_active.first(); p != nullptr; p = p->next())
{
inc_stat(p->device().stat_call_count);
if ((p->state() & mask) != 0)
p->device().update_dev();
}
#else
for (auto p = &m_list_active.m_head; *p != nullptr; )
{
auto pn = &((*p)->m_next);
inc_stat(p->device().stat_call_count);
if (((*p)->state() & mask) != 0)
(*p)->device().update_dev();
p = pn;
}
#endif
}
void net_t::reset()

View File

@ -426,9 +426,9 @@ namespace netlist
void set_net(net_t *anet);
void clear_net();
bool has_net() const { return (m_net != nullptr); }
const net_t & net() const { return *m_net;}
net_t & net() { return *m_net;}
bool has_net() const { return (m_net != nullptr); }
const net_t & net() const { return *m_net;}
net_t & net() { return *m_net;}
bool is_logic() const;
bool is_analog() const;
@ -626,19 +626,21 @@ namespace netlist
bool is_logic() const;
bool is_analog() const;
void push_to_queue(const netlist_time delay) NOEXCEPT;
void reschedule_in_queue(const netlist_time delay) NOEXCEPT;
bool is_queued() const { return m_in_queue == 1; }
void toggle_new_Q() { m_new_Q ^= 1; }
void push_to_queue(const netlist_time delay) NOEXCEPT;
void reschedule_in_queue(const netlist_time delay) NOEXCEPT;
bool is_queued() const { return m_in_queue == 1; }
void update_devs();
const netlist_time time() const { return m_time; }
void set_time(const netlist_time ntime) { m_time = ntime; }
const netlist_time time() const { return m_time; }
void set_time(const netlist_time ntime) { m_time = ntime; }
bool isRailNet() const { return !(m_railterminal == nullptr); }
core_terminal_t & railterminal() const { return *m_railterminal; }
bool isRailNet() const { return !(m_railterminal == nullptr); }
core_terminal_t & railterminal() const { return *m_railterminal; }
int num_cons() const { return m_core_terms.size(); }
int num_cons() const { return m_core_terms.size(); }
void inc_active(core_terminal_t &term);
void dec_active(core_terminal_t &term);
@ -655,15 +657,13 @@ namespace netlist
netlist_time m_time;
INT32 m_active;
UINT8 m_in_queue; /* 0: not in queue, 1: in queue, 2: last was taken */
UINT8 m_in_queue; /* 0: not in queue, 1: in queue, 2: last was taken */
private:
plib::linkedlist_t<core_terminal_t> m_list_active;
core_terminal_t * m_railterminal;
public:
// We have to have those on one object. Dividing those does lead
// to a significant performance hit
// FIXME: Have to fix the public at some time
nl_double m_cur_Analog;
@ -679,9 +679,8 @@ namespace netlist
logic_net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr = nullptr);
virtual ~logic_net_t() { };
netlist_sig_t Q() const { return m_cur_Q; }
netlist_sig_t new_Q() const { return m_new_Q; }
void toggle_new_Q() { m_new_Q ^= 1; }
netlist_sig_t Q() const { return m_cur_Q; }
netlist_sig_t new_Q() const { return m_new_Q; }
void initial(const netlist_sig_t val) { m_cur_Q = m_new_Q = val; }
void set_Q(const netlist_sig_t newQ, const netlist_time &delay) NOEXCEPT
@ -1334,6 +1333,7 @@ protected:
if (newQ != net().Q_Analog())
{
net().m_cur_Analog = newQ;
net().toggle_new_Q();
net().push_to_queue(NLTIME_FROM_NS(1));
}
}

View File

@ -52,14 +52,14 @@ namespace netlist
/* Lock */
while (m_lock.exchange(1)) { }
#endif
entry_t * i = m_end++;
entry_t * i = m_end;
for (; t > (i - 1)->m_exec_time; --i)
{
*(i) = *(i-1);
//i--;
inc_stat(m_prof_sortmove);
}
*i = { t, o };
++m_end;
inc_stat(m_prof_call);
#if HAS_OPENMP && USE_OPENMP
m_lock = 0;
@ -112,7 +112,7 @@ namespace netlist
const entry_t *listptr() const { return &m_list[1]; }
std::size_t size() const { return m_end - &m_list[1]; }
const entry_t & operator[](const std::size_t index) const { return m_list[1+index]; }
const entry_t & operator[](const std::size_t index) const { return m_list[ 1 + index]; }
#if (NL_KEEP_STATISTICS)
// profiling

View File

@ -145,6 +145,7 @@ public:
void update_forced();
void update_after(const netlist_time &after)
{
m_Q_sync.net().toggle_new_Q();
m_Q_sync.net().reschedule_in_queue(after);
}

View File

@ -390,7 +390,10 @@ void matrix_solver_t::update() NOEXCEPT
const netlist_time new_timestep = solve();
if (m_params.m_dynamic && has_timestep_devices() && new_timestep > netlist_time::zero)
{
m_Q_sync.net().toggle_new_Q();
m_Q_sync.net().reschedule_in_queue(new_timestep);
}
}
void matrix_solver_t::update_forced()
@ -398,7 +401,10 @@ void matrix_solver_t::update_forced()
ATTR_UNUSED const netlist_time new_timestep = solve();
if (m_params.m_dynamic && has_timestep_devices())
{
m_Q_sync.net().toggle_new_Q();
m_Q_sync.net().reschedule_in_queue(netlist_time(m_params.m_min_timestep));
}
}
void matrix_solver_t::step(const netlist_time &delta)
@ -428,6 +434,7 @@ const netlist_time matrix_solver_t::solve_base()
if (this_resched > 1 && !m_Q_sync.net().is_queued())
{
log().warning("NEWTON_LOOPS exceeded on net {1}... reschedule", this->name());
m_Q_sync.net().toggle_new_Q();
m_Q_sync.net().reschedule_in_queue(m_params.m_nt_sync_delay);
}
}
@ -620,6 +627,7 @@ NETLIB_UPDATE(solver)
/* step circuit */
if (!m_Q_step.net().is_queued())
{
m_Q_step.net().toggle_new_Q();
m_Q_step.net().push_to_queue(netlist_time(m_params.m_max_timestep));
}
}