inorder: remove stalls on trap squash
authorKorey Sewell <ksewell@umich.edu>
Mon, 20 Jun 2011 01:43:37 +0000 (21:43 -0400)
committerKorey Sewell <ksewell@umich.edu>
Mon, 20 Jun 2011 01:43:37 +0000 (21:43 -0400)
src/cpu/inorder/comm.hh
src/cpu/inorder/inorder_dyn_inst.hh
src/cpu/inorder/pipeline_stage.cc
src/cpu/inorder/reg_dep_map.cc
src/cpu/inorder/resources/fetch_seq_unit.cc

index b05ec4eff5e62b84db7723bbdb8fd456f442bd63..02a7e9fa4d02629f6a9eecd82bd65d9dea983782 100644 (file)
@@ -55,18 +55,32 @@ struct InterStageStruct {
 
 /** Struct that defines all backwards communication. */
 struct TimeStruct {
-    struct stageComm {
+    struct StageComm {
         bool squash;
         InstSeqNum doneSeqNum;
 
         bool uncached;
         ThePipeline::DynInstPtr uncachedLoad;
-    };
 
-    stageComm stageInfo[ThePipeline::NumStages][ThePipeline::MaxThreads];
+        StageComm()
+            : squash(false), doneSeqNum(0), uncached(false), uncachedLoad(NULL)
+        { }
+    };
 
+    StageComm stageInfo[ThePipeline::NumStages][ThePipeline::MaxThreads];
     bool stageBlock[ThePipeline::NumStages][ThePipeline::MaxThreads];
     bool stageUnblock[ThePipeline::NumStages][ThePipeline::MaxThreads];
+
+    TimeStruct()
+    {
+        for (int i = 0; i < ThePipeline::NumStages; i++) {
+            for (int j = 0; j < ThePipeline::MaxThreads; j++) {
+                stageBlock[i][j] = false;
+                stageUnblock[i][j] = false;
+            }
+        }
+    }
+
 };
 
 #endif //__CPU_INORDER_COMM_HH__
index c2c4840743b140cc9eff67db2675be2842d0800d..b374e24a6facaa901f6c516bd6d0c6d745bd7a12 100644 (file)
@@ -314,7 +314,8 @@ class InOrderDynInst : public FastAlloc, public RefCounted
     //  BASE INSTRUCTION INFORMATION.
     //
     ////////////////////////////////////////////////////////////
-    std::string instName() { return staticInst->getName(); }
+    std::string instName()
+    { return (staticInst) ? staticInst->getName() : "undecoded-inst"; }
 
     void setMachInst(ExtMachInst inst);
 
index 2e9ca64e3743fc5f3b6a775d1207213087f70bdc..e739fd2e66c39055a23b47b132c18c41780bc59b 100644 (file)
@@ -226,6 +226,7 @@ PipelineStage::checkStall(ThreadID tid) const
     }
 
     if (!stalls[tid].resources.empty()) {
+#if TRACING_ON
         string stall_src;
 
         for (int i=0; i < stalls[tid].resources.size(); i++) {
@@ -234,6 +235,7 @@ PipelineStage::checkStall(ThreadID tid) const
 
         DPRINTF(InOrderStage,"[tid:%i]: Stall fom resources (%s) detected.\n",
                 tid, stall_src);
+#endif
         ret_val = true;
     }
 
@@ -294,8 +296,11 @@ PipelineStage::block(ThreadID tid)
 
         stageStatus[tid] = Blocked;
 
-        if (prevStageValid)
+        if (prevStageValid) {
+            DPRINTF(InOrderStage, "[tid:%d]: Stage %i setting block signal.\n",
+                    tid, stageNum);
             toPrevStages->stageBlock[stageNum][tid] = true;
+        }
 
         return true;
     }
@@ -323,6 +328,7 @@ PipelineStage::blockDueToBuffer(ThreadID tid)
 bool
 PipelineStage::unblock(ThreadID tid)
 {
+    // @todo: Shouldnt this be if any available slots are open???
     // Stage is done unblocking only if the skid buffer is empty.
     if (skidBuffer[tid].empty()) {
         DPRINTF(InOrderStage, "[tid:%u]: Done unblocking.\n", tid);
@@ -623,6 +629,13 @@ PipelineStage::readStallSignals(ThreadID tid)
     for (int stage_idx = stageNum+1; stage_idx <= lastStallingStage[tid];
          stage_idx++) {
 
+        DPRINTF(InOrderStage, "[tid:%i] Reading stall signals from Stage "
+                "%i. Block:%i Unblock:%i.\n",
+                tid,
+                stage_idx,
+                fromNextStages->stageBlock[stage_idx][tid],
+                fromNextStages->stageUnblock[stage_idx][tid]);
+
         // Check for Stage Blocking Signal
         if (fromNextStages->stageBlock[stage_idx][tid]) {
             DPRINTF(InOrderStage, "[tid:%i] Stall from stage %i set.\n", tid,
@@ -637,6 +650,20 @@ PipelineStage::readStallSignals(ThreadID tid)
             stalls[tid].stage[stage_idx] = false;
         }
     }
+
+    for (int stage_idx = 0; stage_idx < NumStages;
+         stage_idx++) {
+
+        DPRINTF(InOrderStage, "[tid:%i] Stall signals from Stage "
+                "%i. Block:%i Unblock:%i...NBlock:%i NUnblock:%i\n",
+                tid,
+                stage_idx,
+                fromNextStages->stageBlock[stage_idx][tid],
+                fromNextStages->stageUnblock[stage_idx][tid],
+                toPrevStages->stageBlock[stage_idx][tid],
+                toPrevStages->stageUnblock[stage_idx][tid]);
+    }
+
 }
 
 
@@ -866,7 +893,9 @@ PipelineStage::processInsts(ThreadID tid)
         inst = insts_to_stage.front();
 
         DPRINTF(InOrderStage, "[tid:%u]: Processing instruction [sn:%lli] "
-                "with PC %s\n", tid, inst->seqNum, inst->pcState());
+                "%s with PC %s\n", tid, inst->seqNum,
+                inst->instName(),
+                inst->pcState());
 
         if (inst->isSquashed()) {
             DPRINTF(InOrderStage, "[tid:%u]: Instruction %i with PC %s is "
index 075c31208bf9616c98db7b34bc12c47bf197277c..2cb6b7adb211a8d5ed24130617014d72937116f4 100644 (file)
@@ -105,7 +105,7 @@ RegDepMap::insert(DynInstPtr inst)
         inst->flattenDestReg(i, flat_idx);
 
         if (flat_idx == TheISA::ZeroReg) {
-            DPRINTF(IntRegs, "[sn:%i]: Ignoring Insert-Dependency tracking for "
+            DPRINTF(RegDepMap, "[sn:%i]: Ignoring Insert-Dependency tracking for "
                     "ISA-ZeroReg (Int. Reg %i).\n", inst->seqNum,
                     flat_idx);
             continue;
@@ -145,7 +145,7 @@ RegDepMap::remove(DynInstPtr inst)
             RegIndex flat_idx = inst->flattenedDestRegIdx(i);
 
             if (flat_idx == TheISA::ZeroReg) {
-                DPRINTF(IntRegs, "[sn:%i]: Ignoring Remove-Dependency tracking for "
+                DPRINTF(RegDepMap, "[sn:%i]: Ignoring Remove-Dependency tracking for "
                         "ISA-ZeroReg (Int. Reg %i).\n", inst->seqNum,
                         flat_idx);
                 continue;
index 5d90f71d3b84c57739db034116aee60f5a7fee03..072ecb76f6c12d8604ca76d4a1231c97846f218e 100644 (file)
@@ -116,6 +116,9 @@ FetchSeqUnit::execute(int slot_num)
                     // If it's a return, then we must wait for resolved address.
                     // The Predictor will mark a return a false as "not taken"
                     // if there is no RAS entry
+                    DPRINTF(InOrderFetchSeq, "[tid:%d]: Setting block signal "
+                            "for stage %i.\n",
+                            tid, stage_num);
                     cpu->pipelineStage[stage_num]->
                         toPrevStages->stageBlock[stage_num][tid] = true;
                     pcValid[tid] = false;
@@ -215,8 +218,16 @@ FetchSeqUnit::squash(DynInstPtr inst, int squash_stage,
 
             // Unblock Any Stages Waiting for this information to be updated ...
             if (!pcValid[tid]) {
+                DPRINTF(InOrderFetchSeq, "[tid:%d]: Setting unblock signal "
+                        "for stage %i.\n",
+                        tid, pcBlockStage[tid]);
+
+                // Need to use "fromNextStages" instead of "toPrevStages"
+                // because the timebuffer will have already have advanced
+                // in the tick function and this squash function will happen after
+                // the tick
                 cpu->pipelineStage[pcBlockStage[tid]]->
-                    toPrevStages->stageUnblock[pcBlockStage[tid]][tid] = true;
+                    fromNextStages->stageUnblock[pcBlockStage[tid]][tid] = true;
             }
 
             pcValid[tid] = true;
@@ -291,6 +302,8 @@ FetchSeqUnit::trap(Fault fault, ThreadID tid, DynInstPtr inst)
             "%s.\n", tid, pc[tid]);
     DPRINTF(InOrderFetchSeq, "[tid:%i]: Trap updating to PC: "
             "%s.\n", tid, pc[tid]);
+
+    cpu->removePipelineStalls(tid);
 }
 
 void