cpu: Add writeback modeling for drain functionality
authorMitch Hayenga <mitch.hayenga@arm.com>
Thu, 30 Oct 2014 04:18:27 +0000 (23:18 -0500)
committerMitch Hayenga <mitch.hayenga@arm.com>
Thu, 30 Oct 2014 04:18:27 +0000 (23:18 -0500)
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.

src/cpu/o3/inst_queue.hh
src/cpu/o3/inst_queue_impl.hh

index c6c55d08aa89f31bdedc7b45355a4c6c94cc27aa..23d8d416c5244c149ada8a3557049d5727873754 100644 (file)
@@ -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.
      */
index 6a76b49d06d28758aef0336355d55eedb9ad93bb..33e523f4d05d44b7d60bbe3d940d1e27c16869e1 100644 (file)
@@ -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);