summaryrefslogtreecommitdiff
path: root/src/cpu
diff options
context:
space:
mode:
authorMitch Hayenga <mitch.hayenga@arm.com>2014-10-29 23:18:27 -0500
committerMitch Hayenga <mitch.hayenga@arm.com>2014-10-29 23:18:27 -0500
commit5bfa521c46e489c06ac3ae44b97421f5ccb30bb7 (patch)
treec481d242810201e5c9bfb138b4e096ad4174dda4 /src/cpu
parent6847bbf7cefcebfeed6ec29fa139efcb3ce20be4 (diff)
downloadgem5-5bfa521c46e489c06ac3ae44b97421f5ccb30bb7.tar.xz
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.
Diffstat (limited to 'src/cpu')
-rw-r--r--src/cpu/o3/inst_queue.hh3
-rw-r--r--src/cpu/o3/inst_queue_impl.hh7
2 files changed, 9 insertions, 1 deletions
diff --git a/src/cpu/o3/inst_queue.hh b/src/cpu/o3/inst_queue.hh
index c6c55d08a..23d8d416c 100644
--- a/src/cpu/o3/inst_queue.hh
+++ b/src/cpu/o3/inst_queue.hh
@@ -437,6 +437,9 @@ class InstructionQueue
/** The number of physical registers in the CPU. */
unsigned numPhysRegs;
+ /** Number of instructions currently in flight to FUs */
+ int wbOutstanding;
+
/** Delay between commit stage and the IQ.
* @todo: Make there be a distinction between the delays within IEW.
*/
diff --git a/src/cpu/o3/inst_queue_impl.hh b/src/cpu/o3/inst_queue_impl.hh
index 6a76b49d0..33e523f4d 100644
--- a/src/cpu/o3/inst_queue_impl.hh
+++ b/src/cpu/o3/inst_queue_impl.hh
@@ -415,6 +415,7 @@ InstructionQueue<Impl>::resetState()
deferredMemInsts.clear();
blockedMemInsts.clear();
retryMemInsts.clear();
+ wbOutstanding = 0;
}
template <class Impl>
@@ -444,7 +445,9 @@ template <class Impl>
bool
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)
drained = drained && memDepUnit[tid].isDrained();
@@ -723,6 +726,7 @@ InstructionQueue<Impl>::processFUCompletion(DynInstPtr &inst, int fu_idx)
assert(!cpu->switchedOut());
// The CPU could have been sleeping until this op completed (*extremely*
// long latency op). Wake it if it was. This may be overkill.
+ --wbOutstanding;
iewStage->wakeCPU();
if (fu_idx > -1)
@@ -823,6 +827,7 @@ InstructionQueue<Impl>::scheduleReadyInsts()
} else {
Cycles issue_latency = fuPool->getIssueLatency(op_class);
// Generate completion event for the FU
+ ++wbOutstanding;
FUCompletion *execution = new FUCompletion(issuing_inst,
idx, this);