# HG changeset patch
# User Korey Sewell <ksew...@umich.edu>
# Date 1236007009 18000
# Node ID 2c4821af1e8314377232578e7aa72177bad27761
# Parent  9a2e4b6c275a8513f040d4cb7604b2f8f25aeb68
make handling of interstage buffers (i.e. StageQueues) more consistent: 
(1)number from 0-n, not 1-n+1, (2) always check nextStageValid before a 
stageNum+1 and prevStageValid for a stageNum-1 reference (3) add skidSize() to 
get StageQueue size for all threads

diff -r 9a2e4b6c275a -r 2c4821af1e83 src/cpu/inorder/cpu.cc
--- a/src/cpu/inorder/cpu.cc    Mon Mar 02 10:16:47 2009 -0500
+++ b/src/cpu/inorder/cpu.cc    Mon Mar 02 10:16:49 2009 -0500
@@ -250,8 +250,8 @@ InOrderCPU::InOrderCPU(Params *params)
         // Take Care of 1st/Nth stages
         if (stNum > 0)
             pipelineStage[stNum]->setPrevStageQueue(stageQueue[stNum - 1]);
-        if (stNum < NumStages - 2)
-            pipelineStage[stNum]->setNextStageQueue(stageQueue[stNum + 1]);
+        if (stNum < NumStages - 1)
+            pipelineStage[stNum]->setNextStageQueue(stageQueue[stNum]);
     }
 
     // Initialize thread specific variables
diff -r 9a2e4b6c275a -r 2c4821af1e83 src/cpu/inorder/first_stage.cc
--- a/src/cpu/inorder/first_stage.cc    Mon Mar 02 10:16:47 2009 -0500
+++ b/src/cpu/inorder/first_stage.cc    Mon Mar 02 10:16:49 2009 -0500
@@ -127,7 +127,7 @@ FirstStage::processInsts(unsigned tid)
 {
     bool all_reqs_completed = true;
 
-    for (int insts_fetched = 0; insts_fetched < stageWidth && 
canSendInstToNextStage(); insts_fetched++) {
+    for (int insts_fetched = 0; insts_fetched < stageWidth && 
canSendInstToStage(1); insts_fetched++) {
         DynInstPtr inst;
         bool new_inst = false;
 
diff -r 9a2e4b6c275a -r 2c4821af1e83 src/cpu/inorder/pipeline_stage.cc
--- a/src/cpu/inorder/pipeline_stage.cc Mon Mar 02 10:16:47 2009 -0500
+++ b/src/cpu/inorder/pipeline_stage.cc Mon Mar 02 10:16:49 2009 -0500
@@ -229,7 +229,7 @@ PipelineStage::checkStall(unsigned tid) 
     bool ret_val = false;
 
     // Only check pipeline stall from stage directly following this stage
-    if (stalls[tid].stage[stageNum + 1]) {
+    if (nextStageValid && stalls[tid].stage[stageNum + 1]) {
         DPRINTF(InOrderStage,"[tid:%i]: Stall fom Stage %i detected.\n",
                 tid, stageNum + 1);
         ret_val = true;
@@ -422,26 +422,28 @@ PipelineStage::stageBufferAvail()
     }
 
     int incoming_insts = (prevStageValid) ?
-        cpu->pipelineStage[stageNum-1]->nextStage->size :
+        cpu->pipelineStage[stageNum]->prevStage->size :
         0;
 
-    int avail = stageBufferMax - total - incoming_insts;
-
-    assert(avail >= 0);
+    int avail = stageBufferMax - total -0;// incoming_insts;
+
+    if (avail < 0)
+        fatal("stageNum %i:stageBufferAvail() < 
0...stBMax=%i,total=%i,incoming=%i=>%i",
+              stageNum, stageBufferMax, total, incoming_insts, avail);
 
     return avail;
 }
 
 bool
-PipelineStage::canSendInstToNextStage()
+PipelineStage::canSendInstToStage(unsigned stage_num)
 {
     bool buffer_avail = false;
 
-    if (nextStageValid) {
-        buffer_avail = (cpu->pipelineStage[stageNum+1]->stageBufferAvail() >= 
1);
-    }
-
-    if (!buffer_avail && nextStageValid) {
+    if (cpu->pipelineStage[stage_num]->prevStageValid) {
+        buffer_avail = cpu->pipelineStage[stage_num]->stageBufferAvail() >= 1;
+    }
+
+    if (!buffer_avail && nextStageQueueValid(stage_num)) {
         DPRINTF(InOrderStall, "STALL: No room in stage %i buffer.\n", stageNum 
+ 1);
     }
 
@@ -468,6 +470,17 @@ PipelineStage::skidInsert(unsigned tid)
 }
 
 
+int
+PipelineStage::skidSize()
+{
+    int total = 0;
+
+    for (int i=0; i < ThePipeline::MaxThreads; i++) {
+        total += skidBuffer[i].size();
+    }
+
+    return total;
+}
 
 bool
 PipelineStage::skidsEmpty()
@@ -743,8 +756,11 @@ PipelineStage::processStage(bool &status
                 nextStage->size, stageNum + 1);
     }
 
-    DPRINTF(InOrderStage, "%i insts left in stage buffer.\n", stageBufferMax - 
stageBufferAvail());
-
+    DPRINTF(InOrderStage, "%i left in stage %i incoming buffer.\n", skidSize(),
+            stageNum);
+
+    DPRINTF(InOrderStage, "%i available in stage %i incoming buffer.\n", 
stageBufferAvail(),
+            stageNum);
 }
 
 void
@@ -814,14 +830,10 @@ PipelineStage::processInsts(unsigned tid
 
     int insts_processed = 0;
 
-    DPRINTF(InOrderStage, "[tid:%u]: Sending instructions to stage %u.\n", tid,
-            stageNum+1);
-
-    //Keep processing instructions while ... these ?s are true:
-    while (insts_available > 0 &&                            //1. are there 
instructions to process
-           insts_processed < stageWidth &&                   //2. can the 
stage still process this
-           (canSendInstToNextStage() || !nextStageValid) &&  //3. is there 
room in next stage
-           last_req_completed) {                             //4. was the last 
instruction completed
+    while (insts_available > 0 &&
+           insts_processed < stageWidth &&
+           (!nextStageValid || canSendInstToStage(stageNum+1)) &&
+           last_req_completed) {
         assert(!insts_to_stage.empty());
 
         inst = insts_to_stage.front();
@@ -847,23 +859,21 @@ PipelineStage::processInsts(unsigned tid
 
         last_req_completed = processInstSchedule(inst);
 
-
-        insts_processed++;
-
         // Don't let instruction pass to next stage if it hasnt completed
         // all of it's requests for this stage.
         if (!last_req_completed && !outOfOrderValid())
             continue;
 
+        // Send to Next Stage or Break Loop
+        if (nextStageValid && !sendInstToNextStage(inst)) {
+            DPRINTF(InOrderStage, "[tid:%i] [sn:%i] unable to proceed to stage 
%i.\n",
+                    tid, inst->seqNum,inst->nextStage);
+            break;
+        }
+
+        insts_processed++;
+
         insts_to_stage.pop();
-
-        DPRINTF(InOrderStage, "Marking [tid:%i] [sn:%i] for insertion into 
next stage buffer.\n",
-                tid, inst->seqNum);
-
-        // Send to Next Stage or Break Loop
-        if (!sendInstToNextStage(inst))
-            break;;
-
 
         //++stageProcessedInsts;
         --insts_available;
@@ -871,8 +881,6 @@ PipelineStage::processInsts(unsigned tid
 
     // If we didn't process all instructions, then we will need to block
     // and put all those instructions into the skid buffer.
-    // @TODO:-IN-PROGRESS-:Evaluating when stages should block/unblock
-    // for stage stalls...
     if (!insts_to_stage.empty()) {
         blockDueToBuffer(tid);
     }
@@ -945,6 +953,8 @@ PipelineStage::sendInstToNextStage(DynIn
 PipelineStage::sendInstToNextStage(DynInstPtr inst)
 {
     // Update Next Stage Variable in Instruction
+    // NOTE: Some Resources will update this nextStage var. to
+    // for bypassing, so can't always assume nextStage=stageNum+1
     if (inst->nextStage == stageNum)
         inst->nextStage++;
 
@@ -952,6 +962,19 @@ PipelineStage::sendInstToNextStage(DynIn
     int tid = inst->readTid();
     int next_stage = inst->nextStage;
     int prev_stage = next_stage - 1;
+
+    assert(next_stage >= 1);
+    assert(prev_stage >= 0);
+
+    DPRINTF(InOrderStage, "[tid:%u]: Attempting to send instructions to stage 
%u.\n", tid,
+            stageNum+1);
+
+    if (!canSendInstToStage(inst->nextStage)) {
+        DPRINTF(InOrderStage, "[tid:%u]: Could not send instruction to stage 
%u.\n", tid,
+            stageNum+1);
+        return false;
+    }
+
 
     if (nextStageQueueValid(inst->nextStage - 1)) {
         if (inst->seqNum > cpu->squashSeqNum[tid] &&
@@ -959,8 +982,10 @@ PipelineStage::sendInstToNextStage(DynIn
             DPRINTF(InOrderStage, "[tid:%u]: [sn:%i]: squashed, skipping 
insertion "
                     "into stage %i queue.\n", tid, inst->seqNum, 
inst->nextStage);
         } else {
-            DPRINTF(InOrderStage, "[tid:%u] %i slots available in next stage 
buffer.\n",
+            if (nextStageValid) {
+                DPRINTF(InOrderStage, "[tid:%u] %i slots available in next 
stage buffer.\n",
                     tid, cpu->pipelineStage[next_stage]->stageBufferAvail());
+            }
 
             DPRINTF(InOrderStage, "[tid:%u]: [sn:%i]: being placed into  "
                     "index %i of stage buffer %i queue.\n",
diff -r 9a2e4b6c275a -r 2c4821af1e83 src/cpu/inorder/pipeline_stage.hh
--- a/src/cpu/inorder/pipeline_stage.hh Mon Mar 02 10:16:47 2009 -0500
+++ b/src/cpu/inorder/pipeline_stage.hh Mon Mar 02 10:16:49 2009 -0500
@@ -184,7 +184,7 @@ class PipelineStage
     virtual bool processInstSchedule(DynInstPtr inst);
 
     /** Is there room in the next stage buffer for this instruction? */
-    virtual bool canSendInstToNextStage();
+    virtual bool canSendInstToStage(unsigned stage_num);
 
     /** Send an instruction to the next stage buffer */
     virtual bool sendInstToNextStage(DynInstPtr inst);
@@ -193,6 +193,9 @@ class PipelineStage
      * once stage unblocks.
      */
     virtual void skidInsert(unsigned tid);
+
+    /** Total size of all skid buffers */
+    int skidSize();
 
     /** Returns if all of the skid buffers are empty. */
     bool skidsEmpty();
_______________________________________________
m5-dev mailing list
m5-dev@m5sim.org
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to