The drain did not wait until stages were ready again. Therefore, as a
result of messages in the TimeBuffer being drain, the state after the
drain was not consistent and asserts fired in some places when the
draining happened after a stage got blocked, but before the notification
arrived to the previous stages.
Change-Id: Ib50b3b40b7f745b62c1eba2931dec76860824c71
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
DefaultDecode<Impl>::isDrained() const
{
for (ThreadID tid = 0; tid < numThreads; ++tid) {
- if (!insts[tid].empty() || !skidBuffer[tid].empty())
+ if (!insts[tid].empty() || !skidBuffer[tid].empty() ||
+ (decodeStatus[tid] != Running && decodeStatus[tid] != Idle))
return false;
}
return true;
void
DefaultFetch<Impl>::drainResume()
{
- for (ThreadID i = 0; i < numThreads; ++i)
+ for (ThreadID i = 0; i < numThreads; ++i) {
+ stalls[i].decode = false;
stalls[i].drain = false;
+ }
}
template <class Impl>
DPRINTF(Drain, "%i: Skid buffer not empty.\n", tid);
drained = false;
}
+ drained = drained && dispatchStatus[tid] == Running;
}
// Also check the FU pool as instructions are "stored" in FU
if (instsInProgress[tid] != 0 ||
!historyBuffer[tid].empty() ||
!skidBuffer[tid].empty() ||
- !insts[tid].empty())
+ !insts[tid].empty() ||
+ (renameStatus[tid] != Idle && renameStatus[tid] != Running))
return false;
}
return true;