mirror of
https://github.com/holub/mame
synced 2025-04-22 08:22:15 +03:00
Fix long standing workaround which would ignore policy of "change-only"
propagation. (nw)
This commit is contained in:
parent
f8e9851677
commit
bc1eb91c91
@ -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)
|
||||
{
|
||||
|
@ -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),
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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()
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user