cpu: Add writeback modeling for drain functionality
It is possible for the O3 CPU to consider itself drained and later have a squashed instruction perform a writeback. This patch re-adds tracking of in-flight instructions to prevent falsely signaling a drained event.
This commit is contained in:
parent
6847bbf7ce
commit
5bfa521c46
2 changed files with 9 additions and 1 deletions
|
@ -437,6 +437,9 @@ class InstructionQueue
|
||||||
/** The number of physical registers in the CPU. */
|
/** The number of physical registers in the CPU. */
|
||||||
unsigned numPhysRegs;
|
unsigned numPhysRegs;
|
||||||
|
|
||||||
|
/** Number of instructions currently in flight to FUs */
|
||||||
|
int wbOutstanding;
|
||||||
|
|
||||||
/** Delay between commit stage and the IQ.
|
/** Delay between commit stage and the IQ.
|
||||||
* @todo: Make there be a distinction between the delays within IEW.
|
* @todo: Make there be a distinction between the delays within IEW.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -415,6 +415,7 @@ InstructionQueue<Impl>::resetState()
|
||||||
deferredMemInsts.clear();
|
deferredMemInsts.clear();
|
||||||
blockedMemInsts.clear();
|
blockedMemInsts.clear();
|
||||||
retryMemInsts.clear();
|
retryMemInsts.clear();
|
||||||
|
wbOutstanding = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
|
@ -444,7 +445,9 @@ template <class Impl>
|
||||||
bool
|
bool
|
||||||
InstructionQueue<Impl>::isDrained() const
|
InstructionQueue<Impl>::isDrained() const
|
||||||
{
|
{
|
||||||
bool drained = dependGraph.empty() && instsToExecute.empty();
|
bool drained = dependGraph.empty() &&
|
||||||
|
instsToExecute.empty() &&
|
||||||
|
wbOutstanding == 0;
|
||||||
for (ThreadID tid = 0; tid < numThreads; ++tid)
|
for (ThreadID tid = 0; tid < numThreads; ++tid)
|
||||||
drained = drained && memDepUnit[tid].isDrained();
|
drained = drained && memDepUnit[tid].isDrained();
|
||||||
|
|
||||||
|
@ -723,6 +726,7 @@ InstructionQueue<Impl>::processFUCompletion(DynInstPtr &inst, int fu_idx)
|
||||||
assert(!cpu->switchedOut());
|
assert(!cpu->switchedOut());
|
||||||
// The CPU could have been sleeping until this op completed (*extremely*
|
// The CPU could have been sleeping until this op completed (*extremely*
|
||||||
// long latency op). Wake it if it was. This may be overkill.
|
// long latency op). Wake it if it was. This may be overkill.
|
||||||
|
--wbOutstanding;
|
||||||
iewStage->wakeCPU();
|
iewStage->wakeCPU();
|
||||||
|
|
||||||
if (fu_idx > -1)
|
if (fu_idx > -1)
|
||||||
|
@ -823,6 +827,7 @@ InstructionQueue<Impl>::scheduleReadyInsts()
|
||||||
} else {
|
} else {
|
||||||
Cycles issue_latency = fuPool->getIssueLatency(op_class);
|
Cycles issue_latency = fuPool->getIssueLatency(op_class);
|
||||||
// Generate completion event for the FU
|
// Generate completion event for the FU
|
||||||
|
++wbOutstanding;
|
||||||
FUCompletion *execution = new FUCompletion(issuing_inst,
|
FUCompletion *execution = new FUCompletion(issuing_inst,
|
||||||
idx, this);
|
idx, this);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue