changeset 87f4fd9a2760 in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=87f4fd9a2760
description:
        inorder: pipe. stage inst. buffering
        use skidbuffer as only location for instructions between stages. before,
        we had the insts queue from the prior stage and the skidbuffer for the
        current stage, but that gets confusing and this consolidation helps
        when handling squash cases

diffstat:

 src/cpu/inorder/first_stage.cc    |  39 ++++++++--------
 src/cpu/inorder/first_stage.hh    |   5 --
 src/cpu/inorder/pipeline_stage.cc |  92 ++++++++++++++++----------------------
 src/cpu/inorder/pipeline_stage.hh |   5 --
 4 files changed, 57 insertions(+), 84 deletions(-)

diffs (truncated from 315 to 300 lines):

diff -r c9286580867a -r 87f4fd9a2760 src/cpu/inorder/first_stage.cc
--- a/src/cpu/inorder/first_stage.cc    Fri Feb 04 00:08:15 2011 -0500
+++ b/src/cpu/inorder/first_stage.cc    Fri Feb 04 00:08:16 2011 -0500
@@ -69,24 +69,24 @@
     // insts in them.
     DPRINTF(InOrderStage, "Removing instructions from stage instruction "
             "list.\n");
-    while (!insts[tid].empty()) {
-        if (insts[tid].front()->seqNum <= squash_seq_num) {
+    while (!skidBuffer[tid].empty()) {
+        if (skidBuffer[tid].front()->seqNum <= squash_seq_num) {
             DPRINTF(InOrderStage,"[tid:%i]: Cannot remove [sn:%i] because "
                     "it's <= squashing seqNum %i.\n",
                     tid,
-                    insts[tid].front()->seqNum,
+                    skidBuffer[tid].front()->seqNum,
                     squash_seq_num);
 
             DPRINTF(InOrderStage, "[tid:%i]: Cannot remove incoming "
                     "instructions before delay slot [sn:%i]. %i insts"
                     "left.\n", tid, squash_seq_num,
-                    insts[tid].size());
+                    skidBuffer[tid].size());
             break;
         }
         DPRINTF(InOrderStage, "[tid:%i]: Removing instruction, [sn:%i] "
-                "PC %s.\n", tid, insts[tid].front()->seqNum,
-                insts[tid].front()->pc);
-        insts[tid].pop();
+                "PC %s.\n", tid, skidBuffer[tid].front()->seqNum,
+                skidBuffer[tid].front()->pc);
+        skidBuffer[tid].pop_front();
     }
 
     // Now that squash has propagated to the first stage,
@@ -118,9 +118,7 @@
         status_change =  checkSignalsAndUpdate(tid) || status_change;
     }
 
-    for (int insts_fetched = 0; 
-         insts_fetched < stageWidth && canSendInstToStage(1); 
-         insts_fetched++) {
+    while (instsProcessed < stageWidth)  {
         ThreadID tid = getFetchingThread(fetchPolicy);
 
         if (tid >= 0) {
@@ -151,14 +149,14 @@
     bool all_reqs_completed = true;
 
     for (int insts_fetched = instsProcessed;
-         insts_fetched < stageWidth && canSendInstToStage(1); 
+         insts_fetched < stageWidth;
          insts_fetched++) {
 
         DynInstPtr inst;
         bool new_inst = false;
 
-        if (!insts[tid].empty()) {
-            inst = insts[tid].front();
+        if (!skidBuffer[tid].empty()) {
+            inst = skidBuffer[tid].front();
         } else {
             // Get new instruction.
             new_inst = true;
@@ -195,22 +193,21 @@
         if (reqs_processed > 0)
             instsProcessed++;
 
-        if (!all_reqs_completed) {
+        if (!all_reqs_completed || !sendInstToNextStage(inst)) {
             if (new_inst) {
                 DPRINTF(InOrderStage, "[tid:%u]: [sn:%u] Did not finish all "
                         "requests for this stage. Keep in stage inst. "
                         "list.\n", tid, inst->seqNum);
-                insts[tid].push(inst);
+                skidBuffer[tid].push_back(inst);
             }
             block(tid);
             break;
-        } else if (!insts[tid].empty()){
+        } else if (!skidBuffer[tid].empty()){
             DPRINTF(InOrderStage, "[tid:%u]: [sn:%u] Finished all "
                     "requests for this stage.\n", tid, inst->seqNum);
-            insts[tid].pop();
+            skidBuffer[tid].pop_front();
         }
 
-        sendInstToNextStage(inst);
     }
 
     // Record that stage has written to the time buffer for activity
@@ -240,7 +237,8 @@
         ThreadID tid = *activeThreads->begin();
 
         if (stageStatus[tid] == Running ||
-            stageStatus[tid] == Idle) {
+            stageStatus[tid] == Idle ||
+            stageStatus[tid] == Unblocking) {
             return tid;
         } else {
             return InvalidThreadID;
@@ -264,7 +262,8 @@
         assert(high_pri <= numThreads);
 
         if (stageStatus[high_pri] == Running ||
-            stageStatus[high_pri] == Idle) {
+            stageStatus[high_pri] == Idle ||
+            stageStatus[high_pri] == Unblocking){
 
             fetchPriorityList->erase(pri_iter);
             fetchPriorityList->push_back(high_pri);
diff -r c9286580867a -r 87f4fd9a2760 src/cpu/inorder/first_stage.hh
--- a/src/cpu/inorder/first_stage.hh    Fri Feb 04 00:08:15 2011 -0500
+++ b/src/cpu/inorder/first_stage.hh    Fri Feb 04 00:08:16 2011 -0500
@@ -68,11 +68,6 @@
      */
     void sortInsts() {}
 
-    /** There are no skidBuffers for the first stage. So
-     *  just use an empty function.
-     */
-    void skidInsert(ThreadID tid) { }
-
     /** The number of fetching threads in the CPU */
     int numFetchingThreads;
 
diff -r c9286580867a -r 87f4fd9a2760 src/cpu/inorder/pipeline_stage.cc
--- a/src/cpu/inorder/pipeline_stage.cc Fri Feb 04 00:08:15 2011 -0500
+++ b/src/cpu/inorder/pipeline_stage.cc Fri Feb 04 00:08:16 2011 -0500
@@ -272,10 +272,6 @@
     DPRINTF(InOrderStage, "[tid:%d]: Blocking, sending block signal back to "
             "previous stages.\n", tid);
 
-    // Add the current inputs to the skid buffer so they can be
-    // reprocessed when this stage unblocks.
-    // skidInsert(tid);
-
     // If the stage status is blocked or unblocking then stage has not yet
     // signalled fetch to unblock. In that case, there is no need to tell
     // fetch to block.
@@ -412,19 +408,26 @@
 
     DPRINTF(InOrderStage, "[tid:%i]: Removing instructions from incoming stage"
             " skidbuffer.\n", tid);
-    while (!skidBuffer[tid].empty()) {
-        if (skidBuffer[tid].front()->seqNum <= squash_seq_num) {
+    //@TODO: Walk Through List Using iterator and remove
+    //       all instructions over the value
+    std::list<DynInstPtr>::iterator cur_it = skidBuffer[tid].begin();
+    std::list<DynInstPtr>::iterator end_it = skidBuffer[tid].end();
+
+    while (cur_it != end_it) {
+        if ((*cur_it)->seqNum <= squash_seq_num) {
             DPRINTF(InOrderStage, "[tid:%i]: Cannot remove skidBuffer "
                     "instructions (starting w/[sn:%i]) before delay slot "
                     "[sn:%i]. %i insts left.\n", tid, 
-                    skidBuffer[tid].front()->seqNum, squash_seq_num,
+                    (*cur_it)->seqNum, squash_seq_num,
                     skidBuffer[tid].size());
-            break;
+            cur_it++;
+        } else {
+            DPRINTF(InOrderStage, "[tid:%i]: Removing instruction, [sn:%i] "
+                    " PC %s.\n", tid, (*cur_it)->seqNum, (*cur_it)->pc);
+            (*cur_it)->setSquashed();
+            cur_it = skidBuffer[tid].erase(cur_it);
         }
-        DPRINTF(InOrderStage, "[tid:%i]: Removing instruction, [sn:%i] "
-                " PC %s.\n", tid, skidBuffer[tid].front()->seqNum,
-                skidBuffer[tid].front()->pc);
-        skidBuffer[tid].pop_front();
+
     }
 
 }
@@ -442,7 +445,7 @@
         cpu->pipelineStage[stageNum]->prevStage->size :
         0;
 
-    int avail = stageBufferMax - total -0;// incoming_insts;
+    int avail = stageBufferMax - total;
 
     if (avail < 0)
         fatal("stageNum %i:stageBufferAvail() < 0..."
@@ -458,7 +461,8 @@
     bool buffer_avail = false;
 
     if (cpu->pipelineStage[stage_num]->prevStageValid) {
-        buffer_avail = cpu->pipelineStage[stage_num]->stageBufferAvail() >= 1;
+        buffer_avail = cpu->pipelineStage[stage_num]->stageBufferAvail() -
+            cpu->pipelineStage[stage_num-1]->nextStage->size >= 1;
     }
 
     if (!buffer_avail && nextStageQueueValid(stage_num)) {
@@ -469,27 +473,6 @@
     return buffer_avail;
 }
 
-void
-PipelineStage::skidInsert(ThreadID tid)
-{
-    DynInstPtr inst = NULL;
-
-    while (!insts[tid].empty()) {
-        inst = insts[tid].front();
-
-        insts[tid].pop();
-
-        assert(tid == inst->threadNumber);
-
-        DPRINTF(InOrderStage,"[tid:%i]: Inserting [sn:%lli] PC:%s into stage "
-                "skidBuffer %i\n", tid, inst->seqNum, inst->pcState(),
-                inst->threadNumber);
-
-        skidBuffer[tid].push_back(inst);
-    }
-}
-
-
 int
 PipelineStage::skidSize()
 {
@@ -601,13 +584,8 @@
                 insts_from_cur_stage);
 
         int inserted_insts = 0;
-        for (int i = 0; i < insts_from_prev_stage; ++i) {
-            if (inserted_insts + insts_from_cur_stage == stageWidth) {
-               DPRINTF(InOrderStage, "Stage %i has accepted all insts "
-                       "possible for this tick.\n");
-                break;
-            }
 
+        for (int i = 0; i < insts_from_prev_stage; i++) {
             if (prevStage->insts[i]->isSquashed()) {
                 DPRINTF(InOrderStage, "[tid:%i]: Ignoring squashed [sn:%i], "
                         "not inserting into stage buffer.\n",
@@ -617,15 +595,27 @@
                 continue;
             }
 
-            DPRINTF(InOrderStage, "[tid:%i]: Inserting [sn:%i] into stage "
-                    "buffer.\n", prevStage->insts[i]->readTid(),
-                    prevStage->insts[i]->seqNum);
-
             ThreadID tid = prevStage->insts[i]->threadNumber;
 
-            DynInstPtr inst = prevStage->insts[i];
+            if (inserted_insts + insts_from_cur_stage == stageWidth) {
+               DPRINTF(InOrderStage, "Stage %i has accepted all insts "
+                       "possible for this tick. Placing [sn:%i] in stage %i 
skidBuffer\n",
+                       stageNum, prevStage->insts[i]->seqNum, stageNum - 1);
+                cpu->pipelineStage[stageNum - 1]->
+                    skidBuffer[tid].push_front(prevStage->insts[i]);
 
-            skidBuffer[tid].push_back(prevStage->insts[i]);
+                int prev_stage = stageNum - 1;
+                if (cpu->pipelineStage[prev_stage]->stageStatus[tid] == 
Running ||
+                    cpu->pipelineStage[prev_stage]->stageStatus[tid] == Idle) {
+                    cpu->pipelineStage[prev_stage]->stageStatus[tid] = 
Unblocking;
+                }
+            } else {
+                DPRINTF(InOrderStage, "[tid:%i]: Inserting [sn:%i] into stage "
+                        "buffer.\n", prevStage->insts[i]->readTid(),
+                        prevStage->insts[i]->seqNum);
+
+                skidBuffer[tid].push_back(prevStage->insts[i]);
+            }
 
             prevStage->insts[i] = cpu->dummyBufferInst;
 
@@ -633,6 +623,7 @@
 
             inserted_insts++;
         }
+
         assert(prevStage->size == 0);
     }
 }
@@ -862,12 +853,6 @@
         // the rest of unblocking.
         processInsts(tid);
 
-        if (prevStageValid && prevStageInstsValid()) {
-            // Add the current inputs to the skid buffer so they can be
-            // reprocessed when this stage unblocks.
-            skidInsert(tid);
-        }
-
         status_change = unblock(tid) || status_change;
     }
 }
@@ -893,7 +878,6 @@
 
     while (insts_available > 0 &&
            instsProcessed < stageWidth &&
-           (!nextStageValid || canSendInstToStage(stageNum+1)) &&
            last_req_completed) {
         assert(!insts_to_stage.empty());
 
_______________________________________________
m5-dev mailing list
m5-dev@m5sim.org
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to