inorder: enforce stage bandwidth
authorKorey Sewell <ksewell@umich.edu>
Sun, 31 Jan 2010 23:28:31 +0000 (18:28 -0500)
committerKorey Sewell <ksewell@umich.edu>
Sun, 31 Jan 2010 23:28:31 +0000 (18:28 -0500)
each stage keeps track of insts_processed on a per_thread basis but we should
be keeping that on a total basis inorder to enforce stage width limits

src/cpu/inorder/first_stage.cc
src/cpu/inorder/pipeline_stage.cc
src/cpu/inorder/pipeline_stage.hh

index 75e13e559e77291c7bbb74c0955e20e32331e850..27831469e0878d841b26912a795e2d5ac2e79e31 100644 (file)
@@ -175,9 +175,14 @@ FirstStage::processInsts(ThreadID tid)
             ThePipeline::createFrontEndSchedule(inst);
         }
 
-        // Don't let instruction pass to next stage if it hasnt completed
-        // all of it's requests for this stage.
-        all_reqs_completed = processInstSchedule(inst);
+        int reqs_processed = 0;            
+        all_reqs_completed = processInstSchedule(inst, reqs_processed);
+
+        // If the instruction isnt squashed & we've completed one request
+        // Then we can officially count this instruction toward the stage's 
+        // bandwidth count
+        if (reqs_processed > 0)
+            instsProcessed++;
 
         if (!all_reqs_completed) {
             if (new_inst) {
index 55ee3ad128a55184477275978c66e537415c860b..79f1ff915c3eac239789d94a13e516ea26372752 100644 (file)
@@ -726,9 +726,11 @@ PipelineStage::tick()
         nextStage->size = 0;
 
     toNextStageIndex = 0;
-
+    
     sortInsts();
 
+    instsProcessed = 0;
+
     processStage(status_change);
 
     if (status_change) {
@@ -873,10 +875,8 @@ PipelineStage::processInsts(ThreadID tid)
     DynInstPtr inst;
     bool last_req_completed = true;
 
-    int insts_processed = 0;
-
     while (insts_available > 0 &&
-           insts_processed < stageWidth &&
+           instsProcessed < stageWidth &&
            (!nextStageValid || canSendInstToStage(stageNum+1)) &&
            last_req_completed) {
         assert(!insts_to_stage.empty());
@@ -901,8 +901,14 @@ PipelineStage::processInsts(ThreadID tid)
             continue;
         }
 
+        int reqs_processed = 0;        
+        last_req_completed = processInstSchedule(inst, reqs_processed);
 
-        last_req_completed = processInstSchedule(inst);
+        // If the instruction isnt squashed & we've completed one request
+        // Then we can officially count this instruction toward the stage's 
+        // bandwidth count
+        if (reqs_processed > 0)
+            instsProcessed++;
 
         // Don't let instruction pass to next stage if it hasnt completed
         // all of it's requests for this stage.
@@ -916,8 +922,6 @@ PipelineStage::processInsts(ThreadID tid)
             break;
         }
 
-        insts_processed++;
-
         insts_to_stage.pop();
 
         //++stageProcessedInsts;
@@ -938,7 +942,7 @@ PipelineStage::processInsts(ThreadID tid)
 }
 
 bool
-PipelineStage::processInstSchedule(DynInstPtr inst)
+PipelineStage::processInstSchedule(DynInstPtr inst,int &reqs_processed)
 {
     bool last_req_completed = true;
     ThreadID tid = inst->readTid();
@@ -966,6 +970,8 @@ PipelineStage::processInstSchedule(DynInstPtr inst)
                     panic("%i: encountered %s fault!\n",
                           curTick, req->fault->name());
                 }
+
+                reqs_processed++;                
             } else {
                 DPRINTF(InOrderStage, "[tid:%i]: [sn:%i] request to %s failed."
                         "\n", tid, inst->seqNum, cpu->resPool->name(res_num));
index dfe1ac7c38673e0f3fe05b407363f71d433d4e23..920734e6a14bd23467592e18e0d9a66a97342d4d 100644 (file)
@@ -178,7 +178,7 @@ class PipelineStage
     virtual void processInsts(ThreadID tid);
 
     /** Process all resources on an instruction's resource schedule */
-    virtual bool processInstSchedule(DynInstPtr inst);
+    virtual bool processInstSchedule(DynInstPtr inst, int &reqs_processed);
 
     /** Is there room in the next stage buffer for this instruction? */
     virtual bool canSendInstToStage(unsigned stage_num);
@@ -270,6 +270,11 @@ class PipelineStage
     std::vector<DynInstPtr> switchedOutBuffer;
     std::vector<bool> switchedOutValid;
 
+    /** Instructions that we've processed this tick
+     *  NOTE: "Processed" means completed at least 1 instruction request 
+     */
+    unsigned instsProcessed;    
+
     /** Queue of all instructions coming from previous stage on this cycle. */
     std::queue<DynInstPtr> insts[ThePipeline::MaxThreads];