cpu: Fix the O3 CPU Drain

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>
This commit is contained in:
Rekai Gonzalez-Alberquilla 2016-09-22 10:49:10 +01:00
parent d0ffd2f9b8
commit ad296b068c
4 changed files with 8 additions and 3 deletions

View file

@ -209,7 +209,8 @@ bool
DefaultDecode<Impl>::isDrained() const DefaultDecode<Impl>::isDrained() const
{ {
for (ThreadID tid = 0; tid < numThreads; ++tid) { 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 false;
} }
return true; return true;

View file

@ -424,8 +424,10 @@ template <class Impl>
void void
DefaultFetch<Impl>::drainResume() 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; stalls[i].drain = false;
}
} }
template <class Impl> template <class Impl>

View file

@ -391,6 +391,7 @@ DefaultIEW<Impl>::isDrained() const
DPRINTF(Drain, "%i: Skid buffer not empty.\n", tid); DPRINTF(Drain, "%i: Skid buffer not empty.\n", tid);
drained = false; drained = false;
} }
drained = drained && dispatchStatus[tid] == Running;
} }
// Also check the FU pool as instructions are "stored" in FU // Also check the FU pool as instructions are "stored" in FU

View file

@ -304,7 +304,8 @@ DefaultRename<Impl>::isDrained() const
if (instsInProgress[tid] != 0 || if (instsInProgress[tid] != 0 ||
!historyBuffer[tid].empty() || !historyBuffer[tid].empty() ||
!skidBuffer[tid].empty() || !skidBuffer[tid].empty() ||
!insts[tid].empty()) !insts[tid].empty() ||
(renameStatus[tid] != Idle && renameStatus[tid] != Running))
return false; return false;
} }
return true; return true;