inorder-tlb: squash insts in TLB correctly
authorKorey Sewell <ksewell@umich.edu>
Tue, 12 May 2009 19:01:16 +0000 (15:01 -0400)
committerKorey Sewell <ksewell@umich.edu>
Tue, 12 May 2009 19:01:16 +0000 (15:01 -0400)
TLB had a bug where if it was stalled and waiting , it would not squash all instructions older than squashed instruction correctly
* * *

src/cpu/inorder/cpu.cc
src/cpu/inorder/cpu.hh
src/cpu/inorder/resource.cc
src/cpu/inorder/resource_pool.cc
src/cpu/inorder/resources/tlb_unit.cc
src/cpu/inorder/resources/tlb_unit.hh

index 51f763112a14b190e31a87176fdae0ff5ef90b40..c522fc23824abeab37650112a823980696c9b73f 100644 (file)
@@ -80,6 +80,22 @@ InOrderCPU::CPUEvent::CPUEvent(InOrderCPU *_cpu, CPUEventType e_type,
     setEvent(e_type, fault, _tid, _vpe);
 }
 
+
+std::string InOrderCPU::eventNames[NumCPUEvents] =
+{
+    "ActivateThread",
+    "DeallocateThread",
+    "SuspendThread",
+    "DisableThreads",
+    "EnableThreads",
+    "DisableVPEs",
+    "EnableVPEs",
+    "Trap",
+    "InstGraduated",
+    "SquashAll",
+    "UpdatePCs"
+};
+
 void
 InOrderCPU::CPUEvent::process()
 {
@@ -486,8 +502,8 @@ InOrderCPU::scheduleCpuEvent(CPUEventType c_event, Fault fault,
     CPUEvent *cpu_event = new CPUEvent(this, c_event, fault, tid, vpe);
 
     if (delay >= 0) {
-        DPRINTF(InOrderCPU, "Scheduling CPU Event Type #%i for cycle %i.\n",
-                c_event, curTick + delay);
+        DPRINTF(InOrderCPU, "Scheduling CPU Event Type #%s for cycle %i.\n",
+                eventNames[c_event], curTick + delay);
         mainEventQueue.schedule(cpu_event,curTick + delay);
     } else {
         cpu_event->process();
index e3bfbb7f0952b5c8b26fdd8c91ea71c90b66e998..ea5404c60c2c726c27734b169810e592789bae29 100644 (file)
@@ -175,6 +175,8 @@ class InOrderCPU : public BaseCPU
         NumCPUEvents
     };
 
+    static std::string eventNames[NumCPUEvents];
+
     /** Define CPU Event */
     class CPUEvent : public Event
     {
index 2846efe7b2e16dcaa970ea1c7d4ac681a683f821..d8fefe0c9abd8a32a46960629beecd95bc63c020 100644 (file)
@@ -304,9 +304,12 @@ Resource::squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num, unsi
                     req_ptr->getInst()->readTid(),
                     req_ptr->getInst()->seqNum);
 
+            req_ptr->setSquashed();
+
             int req_slot_num = req_ptr->getSlot();
 
-            unscheduleEvent(req_slot_num);
+            if (resourceEvent[req_slot_num].scheduled())
+                unscheduleEvent(req_slot_num);
 
             // Mark request for later removal
             cpu->reqRemoveList.push(req_ptr);
index 725f6cbb3ccf56d601e2bee1b12af4ba04fdef25..2187e2818de91d53a3af64a2c699b37dab1cf65b 100644 (file)
@@ -256,7 +256,7 @@ ResourcePool::scheduleEvent(InOrderCPU::CPUEventType e_type, DynInstPtr inst,
         break;
 
       default:
-        DPRINTF(Resource, "Ignoring Unrecognized CPU Event Type #%i.\n", e_type);
+        DPRINTF(Resource, "Ignoring Unrecognized CPU Event Type #%s.\n", InOrderCPU::eventNames[e_type]);
         ; // If Resource Pool doesnt recognize event, we ignore it.
     }
 }
index 93c066bb06e92bb739926be09940293908ca3f2d..1ce8ff8c20cbc38dd189b1b8ca20e75ec7db62fa 100644 (file)
@@ -43,7 +43,7 @@ using namespace ThePipeline;
 
 TLBUnit::TLBUnit(string res_name, int res_id, int res_width,
                  int res_latency, InOrderCPU *_cpu, ThePipeline::Params *params)
-    : InstBuffer(res_name, res_id, res_width, res_latency, _cpu, params)
+: Resource(res_name, res_id, res_width, res_latency, _cpu)
 {
     // Hard-Code Selection For Now
     if (res_name == "I-TLB")
@@ -124,7 +124,9 @@ TLBUnit::execute(int slot_idx)
                 DPRINTF(InOrderTLB, "[tid:%i]: %s encountered while translating "
                         "addr:%08p for [sn:%i].\n", tid, tlb_req->fault->name(),
                         tlb_req->memReq->getVaddr(), seq_num);
-                //insert(inst);
+
+                DPRINTF(InOrderTLB, "slot:%i sn:%i schedule event.\n", slot_idx, seq_num);
+
                 cpu->pipelineStage[stage_num]->setResStall(tlb_req, tid);
                 tlbBlocked[tid] = true;
                 scheduleEvent(slot_idx, 1);
@@ -210,7 +212,7 @@ TLBUnitEvent::process()
 
     tlb_res->tlbBlocked[tid] = false;
 
-    tlb_res->cpu->pipelineStage[stage_num]->unsetResStall(resource->reqMap[slotIdx], tid);
+    tlb_res->cpu->pipelineStage[stage_num]->unsetResStall(tlb_res->reqMap[slotIdx], tid);
 
     // Effectively NOP the instruction but still allow it
     // to commit
@@ -219,3 +221,56 @@ TLBUnitEvent::process()
     //inst->resSched.pop();
     //}
 }
+
+void
+TLBUnit::squash(DynInstPtr inst, int stage_num,
+                   InstSeqNum squash_seq_num, unsigned tid)
+{
+     //@TODO: Figure out a way to consolidate common parts
+     //       of this squash code
+     std::vector<int> slot_remove_list;
+
+     map<int, ResReqPtr>::iterator map_it = reqMap.begin();
+     map<int, ResReqPtr>::iterator map_end = reqMap.end();
+
+     while (map_it != map_end) {
+         ResReqPtr req_ptr = (*map_it).second;
+
+         if (req_ptr &&
+             req_ptr->getInst()->readTid() == tid &&
+             req_ptr->getInst()->seqNum > squash_seq_num) {
+
+             DPRINTF(Resource, "[tid:%i]: Squashing [sn:%i].\n",
+                     req_ptr->getInst()->readTid(),
+                     req_ptr->getInst()->seqNum);
+
+             req_ptr->setSquashed();
+
+             int req_slot_num = req_ptr->getSlot();
+
+             tlbBlocked[tid] = false;
+
+             int stall_stage = reqMap[req_slot_num]->getStageNum();
+
+             cpu->pipelineStage[stall_stage]->unsetResStall(reqMap[req_slot_num], tid);
+
+             if (resourceEvent[req_slot_num].scheduled())
+                 unscheduleEvent(req_slot_num);
+
+             // Mark request for later removal
+             cpu->reqRemoveList.push(req_ptr);
+
+             // Mark slot for removal from resource
+             slot_remove_list.push_back(req_ptr->getSlot());
+         }
+
+         map_it++;
+     }
+
+     // Now Delete Slot Entry from Req. Map
+     for (int i = 0; i < slot_remove_list.size(); i++) {
+         freeSlot(slot_remove_list[i]);
+     }
+}
+
+
index 4ca240ba807b8034e6faa8b4c111688a97c06e31..759fe14f13b4397b9e2b8a5f1c856216b5fb7ca0 100644 (file)
@@ -41,7 +41,8 @@
 #include "cpu/inorder/pipeline_traits.hh"
 #include "cpu/inorder/cpu.hh"
 
-class TLBUnit : public InstBuffer {
+class TLBUnit : public Resource
+{
   public:
     typedef ThePipeline::DynInstPtr DynInstPtr;
 
@@ -66,6 +67,8 @@ class TLBUnit : public InstBuffer {
 
     virtual void execute(int slot_num);
 
+    void squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num, unsigned tid);
+
     bool tlbBlocked[ThePipeline::MaxThreads];
 
     TheISA::TLB* tlb();