*
*/
-#include <vector>
#include <list>
+#include <vector>
+
#include "arch/isa_traits.hh"
-#include "cpu/inorder/pipeline_traits.hh"
-#include "cpu/inorder/first_stage.hh"
+#include "config/the_isa.hh"
#include "cpu/inorder/resources/tlb_unit.hh"
#include "cpu/inorder/cpu.hh"
+#include "cpu/inorder/first_stage.hh"
+#include "cpu/inorder/pipeline_traits.hh"
using namespace std;
using namespace TheISA;
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)
+ Cycles res_latency, InOrderCPU *_cpu,
+ ThePipeline::Params *params)
+: Resource(res_name, res_id, res_width, res_latency, _cpu)
{
// Hard-Code Selection For Now
if (res_name == "I-TLB")
{
resourceEvent = new TLBUnitEvent[width];
+ for (int i = 0; i < width; i++) {
+ reqs[i] = new TLBUnitRequest(this);
+ }
+
initSlots();
}
int res_idx, int slot_num,
unsigned cmd)
{
- return new TLBUnitRequest(this, _inst, stage_num, res_idx, slot_num,
- cmd);
+ TLBUnitRequest *tlb_req = dynamic_cast<TLBUnitRequest*>(reqs[slot_num]);
+ tlb_req->setRequest(inst, stage_num, id, slot_num, cmd);
+ return ud_req;
}
void
{
// After this is working, change this to a reinterpret cast
// for performance considerations
- TLBUnitRequest* tlb_req = dynamic_cast<TLBUnitRequest*>(reqMap[slot_idx]);
+ TLBUnitRequest* tlb_req = dynamic_cast<TLBUnitRequest*>(reqs[slot_idx]);
assert(tlb_req != 0x0);
DynInstPtr inst = tlb_req->inst;
- int tid, seq_num, stage_num;
-
- tid = inst->readTid();
- seq_num = inst->seqNum;
- stage_num = tlb_req->getStageNum();
+ ThreadID tid = inst->readTid();
+ InstSeqNum seq_num = inst->seqNum;
+ int stage_num = tlb_req->getStageNum();
tlb_req->fault = NoFault;
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);
if (tlb_req->fault != NoFault) {
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);
- cpu->pipelineStage[stage_num]->setResStall(tlb_req, tid);
- tlbBlocked[tid] = true;
- scheduleEvent(slot_idx, 1);
+ "addr:%08p for [sn:%i] %s.\n", tid, tlb_req->fault->name(),
+ tlb_req->memReq->getVaddr(), seq_num, inst->instName());
- // Let CPU handle the fault
- cpu->trap(tlb_req->fault, tid);
+ if (inst->isDataPrefetch()) {
+ DPRINTF(InOrderTLB, "Ignoring %s fault for data prefetch\n",
+ tlb_req->fault->name());
+
+ tlb_req->fault = NoFault;
+
+ tlb_req->done();
+ } else {
+ cpu->pipelineStage[stage_num]->setResStall(tlb_req, tid);
+ tlbBlocked[tid] = true;
+ scheduleEvent(slot_idx, 1);
+
+ // Let CPU handle the fault
+ cpu->trap(tlb_req->fault, tid, inst);
+ }
} else {
DPRINTF(InOrderTLB, "[tid:%i]: [sn:%i] virt. addr %08p translated "
"to phys. addr:%08p.\n", tid, seq_num,
void
TLBUnitEvent::process()
{
- DynInstPtr inst = resource->reqMap[slotIdx]->inst;
- int stage_num = resource->reqMap[slotIdx]->getStageNum();
- int tid = inst->threadNumber;
+ DynInstPtr inst = resource->reqs[slotIdx]->inst;
+ int stage_num = resource->reqs[slotIdx]->getStageNum();
+ ThreadID tid = inst->threadNumber;
DPRINTF(InOrderTLB, "Waking up from TLB Miss caused by [sn:%i].\n",
inst->seqNum);
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->reqs[slotIdx], tid);
+}
+
+void
+TLBUnit::squash(DynInstPtr inst, int stage_num,
+ InstSeqNum squash_seq_num, ThreadID tid)
+{
+ for (int i = 0; i < width; i++) {
+ ResReqPtr req_ptr = reqs[i];
+
+ if (req_ptr->valid &&
+ req_ptr->getInst()->readTid() == tid &&
+ req_ptr->getInst()->seqNum > squash_seq_num) {
- // Effectively NOP the instruction but still allow it
- // to commit
- //while (!inst->resSched.empty() &&
- // inst->resSched.top()->stageNum != ThePipeline::NumStages - 1) {
- //inst->resSched.pop();
- //}
+ 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 = reqs[req_slot_num]->getStageNum();
+
+ cpu->pipelineStage[stall_stage]->
+ unsetResStall(reqs[req_slot_num], tid);
+
+ if (resourceEvent[req_slot_num].scheduled())
+ unscheduleEvent(req_slot_num);
+
+ freeSlot(req_slot_num);
+ }
+ }
}
+
+