From 561c33f0824a705cb360ecb4ae3bf8cfd490f007 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sun, 19 Jun 2011 21:43:40 -0400 Subject: inorder: dont handle multiple faults on same cycle if a faulting instruction reaches an execution unit, then ignore it and pass it through the pipeline. Once we recognize the fault in the graduation unit, dont allow a second fault to creep in on the same cycle. --- src/cpu/inorder/cpu.cc | 16 ++++++++--- src/cpu/inorder/cpu.hh | 5 +++- src/cpu/inorder/inorder_dyn_inst.cc | 8 +++++- src/cpu/inorder/inorder_dyn_inst.hh | 18 ++++++++++--- src/cpu/inorder/pipeline_stage.cc | 1 + src/cpu/inorder/resources/agen_unit.cc | 9 +++++++ src/cpu/inorder/resources/branch_predictor.cc | 15 ++++++++--- src/cpu/inorder/resources/cache_unit.cc | 33 +++++++++-------------- src/cpu/inorder/resources/decode_unit.cc | 17 +++++++----- src/cpu/inorder/resources/execution_unit.cc | 9 +++++++ src/cpu/inorder/resources/fetch_seq_unit.cc | 11 ++++++-- src/cpu/inorder/resources/fetch_unit.cc | 20 ++++++++++++-- src/cpu/inorder/resources/graduation_unit.cc | 39 +++++++++++++++++++-------- src/cpu/inorder/resources/graduation_unit.hh | 4 +-- src/cpu/inorder/resources/mult_div_unit.cc | 10 ++++++- src/cpu/inorder/resources/use_def.cc | 14 ++++++++-- 16 files changed, 171 insertions(+), 58 deletions(-) (limited to 'src/cpu/inorder') diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index 2623c6c1d..365b2f18a 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -196,7 +196,6 @@ InOrderCPU::InOrderCPU(Params *params) timeBuffer(2 , 2), removeInstsThisCycle(false), activityRec(params->name, NumStages, 10, params->activity), - stCondFails(0), #if FULL_SYSTEM system(params->system), #endif // FULL_SYSTEM @@ -372,7 +371,8 @@ InOrderCPU::InOrderCPU(Params *params) endOfSkedIt = skedCache.end(); frontEndSked = createFrontEndSked(); - + faultSked = createFaultSked(); + lastRunningCycle = curTick(); lockAddr = 0; @@ -417,8 +417,18 @@ InOrderCPU::createFrontEndSked() D.needs(FetchSeq, FetchSeqUnit::UpdateTargetPC); - DPRINTF(SkedCache, "Resource Sked created for instruction \"front_end\"\n"); + DPRINTF(SkedCache, "Resource Sked created for instruction Front End\n"); + + return res_sked; +} +RSkedPtr +InOrderCPU::createFaultSked() +{ + RSkedPtr res_sked = new ResourceSked(); + StageScheduler W(res_sked, NumStages - 1); + W.needs(Grad, GraduationUnit::CheckFault); + DPRINTF(SkedCache, "Resource Sked created for instruction Faults\n"); return res_sked; } diff --git a/src/cpu/inorder/cpu.hh b/src/cpu/inorder/cpu.hh index 8a0f2167b..a1e92f302 100644 --- a/src/cpu/inorder/cpu.hh +++ b/src/cpu/inorder/cpu.hh @@ -319,6 +319,7 @@ class InOrderCPU : public BaseCPU SkedCacheIt endOfSkedIt; ThePipeline::RSkedPtr frontEndSked; + ThePipeline::RSkedPtr faultSked; /** Add a new instruction schedule to the schedule cache */ void addToSkedCache(DynInstPtr inst, ThePipeline::RSkedPtr inst_sked) @@ -366,6 +367,7 @@ class InOrderCPU : public BaseCPU } ThePipeline::RSkedPtr createFrontEndSked(); + ThePipeline::RSkedPtr createFaultSked(); ThePipeline::RSkedPtr createBackEndSked(DynInstPtr inst); class StageScheduler { @@ -751,7 +753,7 @@ class InOrderCPU : public BaseCPU virtual void wakeup(); #endif - // LL/SC debug functionality + /* LL/SC debug functionality unsigned stCondFails; unsigned readStCondFailures() @@ -759,6 +761,7 @@ class InOrderCPU : public BaseCPU unsigned setStCondFailures(unsigned st_fails) { return stCondFails = st_fails; } + */ /** Returns a pointer to a thread context. */ ThreadContext *tcBase(ThreadID tid = 0) diff --git a/src/cpu/inorder/inorder_dyn_inst.cc b/src/cpu/inorder/inorder_dyn_inst.cc index 58280bf62..7fbab4c7d 100644 --- a/src/cpu/inorder/inorder_dyn_inst.cc +++ b/src/cpu/inorder/inorder_dyn_inst.cc @@ -87,6 +87,12 @@ InOrderDynInst::InOrderDynInst(InOrderCPU *cpu, int InOrderDynInst::instcount = 0; +int +InOrderDynInst::cpuId() +{ + return cpu->cpuId(); +} + void InOrderDynInst::setMachInst(ExtMachInst machInst) { @@ -330,7 +336,7 @@ InOrderDynInst::setSquashInfo(unsigned stage_num) squashSeqNum = seqNum; #if ISA_HAS_DELAY_SLOT - if (isControl()) { + if (staticInst && isControl()) { TheISA::PCState nextPC = pc; TheISA::advancePC(nextPC, staticInst); diff --git a/src/cpu/inorder/inorder_dyn_inst.hh b/src/cpu/inorder/inorder_dyn_inst.hh index c896812d7..54c2e16c5 100644 --- a/src/cpu/inorder/inorder_dyn_inst.hh +++ b/src/cpu/inorder/inorder_dyn_inst.hh @@ -355,6 +355,12 @@ class InOrderDynInst : public FastAlloc, public RefCounted /** Returns the fault type. */ Fault getFault() { return fault; } + /** Read this CPU's ID. */ + int cpuId(); + + /** Read this context's system-wide ID **/ + int contextId() { return thread->contextId(); } + //////////////////////////////////////////////////////////// // // INSTRUCTION TYPES - Forward checks to StaticInst object. @@ -473,12 +479,12 @@ class InOrderDynInst : public FastAlloc, public RefCounted curSkedEntry++; if (inFrontEnd && curSkedEntry == frontSked_end) { - DPRINTF(InOrderDynInst, "[sn:%i] Switching to " + DPRINTF(InOrderDynInst, "[sn:%i] Switching to " "back end schedule.\n", seqNum); assert(backSked != NULL); - curSkedEntry.init(backSked); - curSkedEntry = backSked->begin(); - inFrontEnd = false; + curSkedEntry.init(backSked); + curSkedEntry = backSked->begin(); + inFrontEnd = false; } else if (!inFrontEnd && curSkedEntry == backSked_end) { return true; } @@ -915,6 +921,10 @@ class InOrderDynInst : public FastAlloc, public RefCounted virtual void setRegOtherThread(unsigned idx, const uint64_t &val, ThreadID tid = InvalidThreadID); + /** Returns the number of consecutive store conditional failures. */ + unsigned readStCondFailures() + { return thread->storeCondFailures; } + /** Sets the number of consecutive store conditional failures. */ void setStCondFailures(unsigned sc_failures) { thread->storeCondFailures = sc_failures; } diff --git a/src/cpu/inorder/pipeline_stage.cc b/src/cpu/inorder/pipeline_stage.cc index 3c945d31c..ac180d3c0 100644 --- a/src/cpu/inorder/pipeline_stage.cc +++ b/src/cpu/inorder/pipeline_stage.cc @@ -130,6 +130,7 @@ PipelineStage::setTimeBuffer(TimeBuffer *tb_ptr) timeBuffer = tb_ptr; // Setup wire to write information back to fetch. + // @todo: should this be writing to the next stage => -1 and reading from is (0)??? toPrevStages = timeBuffer->getWire(0); // Create wires to get information from proper places in time buffer. diff --git a/src/cpu/inorder/resources/agen_unit.cc b/src/cpu/inorder/resources/agen_unit.cc index 64f6d7544..7be8a23f2 100644 --- a/src/cpu/inorder/resources/agen_unit.cc +++ b/src/cpu/inorder/resources/agen_unit.cc @@ -58,6 +58,15 @@ AGENUnit::execute(int slot_num) #endif InstSeqNum seq_num = inst->seqNum; + if (inst->fault != NoFault) { + DPRINTF(InOrderAGEN, + "[tid:%i]: [sn:%i]: Detected %s fault @ %x. Forwarding to " + "next stage.\n", tid, inst->seqNum, inst->fault->name(), + inst->pcState()); + agen_req->done(); + return; + } + switch (agen_req->cmd) { case GenerateAddr: diff --git a/src/cpu/inorder/resources/branch_predictor.cc b/src/cpu/inorder/resources/branch_predictor.cc index 3dea92cfb..0dab5a70f 100644 --- a/src/cpu/inorder/resources/branch_predictor.cc +++ b/src/cpu/inorder/resources/branch_predictor.cc @@ -68,8 +68,14 @@ BranchPredictor::execute(int slot_num) { ResourceRequest* bpred_req = reqs[slot_num]; DynInstPtr inst = bpred_req->inst; - ThreadID tid = inst->readTid(); - InstSeqNum seq_num = inst->seqNum; + if (inst->fault != NoFault) { + DPRINTF(InOrderBPred, + "[tid:%i]: [sn:%i]: Detected %s fault @ %x. Forwarding to " + "next stage.\n", inst->readTid(), inst->seqNum, inst->fault->name(), + inst->pcState()); + bpred_req->done(); + return; + } if (!inst->isControl()) { DPRINTF(Resource, "Ignoring %s, not a control inst.\n", @@ -78,7 +84,8 @@ BranchPredictor::execute(int slot_num) return; } - + ThreadID tid = inst->readTid(); + InstSeqNum seq_num = inst->seqNum; switch (bpred_req->cmd) { case PredictBranch: @@ -110,6 +117,8 @@ BranchPredictor::execute(int slot_num) inst->setBranchPred(predict_taken); } + //@todo: Check to see how hw_rei is handled here...how does PC,NPC get + // updated to compare mispredict against??? inst->setPredTarg(pred_PC); DPRINTF(InOrderBPred, "[tid:%i]: [sn:%i]: %s Predicted PC is " "%s.\n", tid, seq_num, inst->instName(), pred_PC); diff --git a/src/cpu/inorder/resources/cache_unit.cc b/src/cpu/inorder/resources/cache_unit.cc index 41429510d..7c8ad6905 100644 --- a/src/cpu/inorder/resources/cache_unit.cc +++ b/src/cpu/inorder/resources/cache_unit.cc @@ -395,7 +395,7 @@ CacheUnit::setupMemRequest(DynInstPtr inst, CacheReqPtr cache_req, if (cache_req->memReq == NULL) { cache_req->memReq = new Request(cpu->asid[tid], aligned_addr, acc_size, flags, - inst->instAddr(), cpu->readCpuId(), + inst->instAddr(), cpu->readCpuId(), //@todo: use context id tid); DPRINTF(InOrderCachePort, "[sn:%i] Created memReq @%x, ->%x\n", inst->seqNum, &cache_req->memReq, cache_req->memReq); @@ -685,6 +685,15 @@ CacheUnit::execute(int slot_num) } DynInstPtr inst = cache_req->inst; + if (inst->fault != NoFault) { + DPRINTF(InOrderCachePort, + "[tid:%i]: [sn:%i]: Detected %s fault @ %x. Forwarding to " + "next stage.\n", inst->readTid(), inst->seqNum, inst->fault->name(), + inst->getMemAddr()); + finishCacheUnitReq(inst, cache_req); + return; + } + #if TRACING_ON ThreadID tid = inst->readTid(); std::string acc_type = "write"; @@ -747,14 +756,6 @@ CacheUnit::execute(int slot_num) "[tid:%i]: [sn:%i]: Trying to Complete Data Read Access\n", tid, inst->seqNum); - if (inst->fault != NoFault) { - DPRINTF(InOrderCachePort, - "[tid:%i]: [sn:%i]: Detected %s fault @ %x. Forwarding to " - "next stage.\n", tid, inst->seqNum, inst->fault->name(), - inst->getMemAddr()); - finishCacheUnitReq(inst, cache_req); - return; - } //@todo: timing translations need to check here... assert(!inst->isInstPrefetch() && "Can't Handle Inst. Prefecthes"); @@ -774,14 +775,6 @@ CacheUnit::execute(int slot_num) "[tid:%i]: [sn:%i]: Trying to Complete Data Write Access\n", tid, inst->seqNum); - if (inst->fault != NoFault) { - DPRINTF(InOrderCachePort, - "[tid:%i]: [sn:%i]: Detected %s fault @ %x. Forwarding to ", - "next stage.\n", tid, inst->seqNum, inst->fault->name(), - inst->getMemAddr()); - finishCacheUnitReq(inst, cache_req); - return; - } //@todo: check that timing translation is finished here RequestPtr mem_req = cache_req->memReq; @@ -937,7 +930,7 @@ CacheUnit::doCacheAccess(DynInstPtr inst, uint64_t *write_res, if (mem_req->isLLSC()) { assert(cache_req->inst->isStoreConditional()); DPRINTF(InOrderCachePort, "Evaluating Store Conditional access\n"); - do_access = TheISA::handleLockedWrite(cpu, mem_req); + do_access = TheISA::handleLockedWrite(inst.get(), mem_req); } } @@ -1129,7 +1122,7 @@ CacheUnit::processCacheCompletion(PacketPtr pkt) DPRINTF(InOrderCachePort, "[tid:%u]: Handling Load-Linked for [sn:%u]\n", tid, inst->seqNum); - TheISA::handleLockedRead(cpu, cache_pkt->req); + TheISA::handleLockedRead(inst.get(), cache_pkt->req); } DPRINTF(InOrderCachePort, @@ -1280,7 +1273,7 @@ void CacheUnit::squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num, ThreadID tid) { - if (tlbBlockSeqNum[tid] && + if (tlbBlocked[tid] && tlbBlockSeqNum[tid] > squash_seq_num) { DPRINTF(InOrderCachePort, "Releasing TLB Block due to " " squash after [sn:%i].\n", squash_seq_num); diff --git a/src/cpu/inorder/resources/decode_unit.cc b/src/cpu/inorder/resources/decode_unit.cc index d15428436..a3548edfc 100644 --- a/src/cpu/inorder/resources/decode_unit.cc +++ b/src/cpu/inorder/resources/decode_unit.cc @@ -59,13 +59,18 @@ DecodeUnit::execute(int slot_num) { case DecodeInst: { - assert(!inst->staticInst->isMacroop()); - DPRINTF(Decode,"Decoded instruction [sn:%i]: %s : 0x%x\n", - inst->seqNum, inst->instName(), - inst->staticInst->machInst); - - inst->setBackSked(cpu->createBackEndSked(inst)); + if (inst->fault != NoFault) { + inst->setBackSked(cpu->faultSked); + DPRINTF(Decode,"[tid:%i]: Fault found for instruction [sn:%i]\n", + inst->readTid(), inst->seqNum); + } else { + assert(!inst->staticInst->isMacroop()); + inst->setBackSked(cpu->createBackEndSked(inst)); + DPRINTF(Decode,"Decoded instruction [sn:%i]: %s : 0x%x\n", + inst->seqNum, inst->instName(), + inst->staticInst->machInst); + } if (inst->backSked != NULL) { DPRINTF(InOrderDecode, diff --git a/src/cpu/inorder/resources/execution_unit.cc b/src/cpu/inorder/resources/execution_unit.cc index 460ec32fe..c1945488c 100644 --- a/src/cpu/inorder/resources/execution_unit.cc +++ b/src/cpu/inorder/resources/execution_unit.cc @@ -87,6 +87,15 @@ ExecutionUnit::execute(int slot_num) { ResourceRequest* exec_req = reqs[slot_num]; DynInstPtr inst = reqs[slot_num]->inst; + if (inst->fault != NoFault) { + DPRINTF(InOrderExecute, + "[tid:%i]: [sn:%i]: Detected %s fault @ %x. Forwarding to " + "next stage.\n", inst->readTid(), inst->seqNum, inst->fault->name(), + inst->pcState()); + exec_req->done(); + return; + } + Fault fault = NoFault; Tick cur_tick = curTick(); unsigned stage_num = exec_req->getStageNum(); diff --git a/src/cpu/inorder/resources/fetch_seq_unit.cc b/src/cpu/inorder/resources/fetch_seq_unit.cc index 58e466e13..71507e2d8 100644 --- a/src/cpu/inorder/resources/fetch_seq_unit.cc +++ b/src/cpu/inorder/resources/fetch_seq_unit.cc @@ -81,6 +81,15 @@ FetchSeqUnit::execute(int slot_num) ThreadID tid = inst->readTid(); int stage_num = fs_req->getStageNum(); + if (inst->fault != NoFault) { + DPRINTF(InOrderFetchSeq, + "[tid:%i]: [sn:%i]: Detected %s fault @ %x. Forwarding to " + "next stage.\n", tid, inst->seqNum, inst->fault->name(), + inst->pcState()); + fs_req->done(); + return; + } + switch (fs_req->cmd) { case AssignNextPC: @@ -302,8 +311,6 @@ FetchSeqUnit::trap(Fault fault, ThreadID tid, DynInstPtr inst) { pcValid[tid] = true; pc[tid] = cpu->pcState(tid); - DPRINTF(Fault, "[tid:%i]: Trap updating to PC: " - "%s.\n", tid, pc[tid]); DPRINTF(InOrderFetchSeq, "[tid:%i]: Trap updating to PC: " "%s.\n", tid, pc[tid]); } diff --git a/src/cpu/inorder/resources/fetch_unit.cc b/src/cpu/inorder/resources/fetch_unit.cc index 958d69b34..85411ae28 100644 --- a/src/cpu/inorder/resources/fetch_unit.cc +++ b/src/cpu/inorder/resources/fetch_unit.cc @@ -247,7 +247,14 @@ FetchUnit::execute(int slot_num) Addr block_addr = cacheBlockAlign(inst->getMemAddr()); int asid = cpu->asid[tid]; - inst->fault = NoFault; + if (inst->fault != NoFault) { + DPRINTF(InOrderCachePort, + "[tid:%i]: [sn:%i]: Detected %s fault @ %x. Forwarding to " + "next stage.\n", tid, inst->seqNum, inst->fault->name(), + cacheBlockAlign(inst->getMemAddr())); + finishCacheUnitReq(inst, cache_req); + return; + } switch (cache_req->cmd) { @@ -295,7 +302,7 @@ FetchUnit::execute(int slot_num) return; } - doTLBAccess(inst, cache_req, cacheBlkSize, 0, TheISA::TLB::Execute); + doTLBAccess(inst, cache_req, cacheBlkSize, Request::INST_FETCH, TheISA::TLB::Execute); if (inst->fault == NoFault) { DPRINTF(InOrderCachePort, @@ -320,6 +327,15 @@ FetchUnit::execute(int slot_num) } case CompleteFetch: + if (inst->fault != NoFault) { + DPRINTF(InOrderCachePort, + "[tid:%i]: [sn:%i]: Detected %s fault @ %x. Forwarding to " + "next stage.\n", tid, inst->seqNum, inst->fault->name(), + inst->getMemAddr()); + finishCacheUnitReq(inst, cache_req); + return; + } + if (cache_req->fetchBufferFill) { // Block request if it's depending on a previous fetch, but it hasnt made it yet std::list::iterator fetch_it = findBlock(fetchBuffer, asid, block_addr); diff --git a/src/cpu/inorder/resources/graduation_unit.cc b/src/cpu/inorder/resources/graduation_unit.cc index 617ef14f6..ebcf40c6a 100644 --- a/src/cpu/inorder/resources/graduation_unit.cc +++ b/src/cpu/inorder/resources/graduation_unit.cc @@ -37,12 +37,13 @@ using namespace ThePipeline; GraduationUnit::GraduationUnit(std::string res_name, int res_id, int res_width, int res_latency, InOrderCPU *_cpu, ThePipeline::Params *params) - : Resource(res_name, res_id, res_width, res_latency, _cpu), - lastNonSpecTick(0) + : Resource(res_name, res_id, res_width, res_latency, _cpu) { for (ThreadID tid = 0; tid < ThePipeline::MaxThreads; tid++) { nonSpecInstActive[tid] = &cpu->nonSpecInstActive[tid]; nonSpecSeqNum[tid] = &cpu->nonSpecSeqNum[tid]; + lastNonSpecTick[tid] = 0; + lastFaultTick[tid] = 0; } } @@ -53,6 +54,25 @@ GraduationUnit::execute(int slot_num) DynInstPtr inst = reqs[slot_num]->inst; ThreadID tid = inst->readTid(); int stage_num = inst->curSkedEntry->stageNum; + Tick cur_tick = curTick(); + + //@todo: not the common case, anyway we can move this + // check to the stage and just ignore instructions + // after? + if (lastNonSpecTick[tid] == cur_tick) { + DPRINTF(InOrderGraduation, "Unable to graduate [sn:%i]. " + "Only 1 nonspec inst. per cycle can graduate.\n"); + grad_req->done(false); + return; + } + + if (lastFaultTick[tid] == cur_tick) { + DPRINTF(InOrderGraduation, "Unable to graduate [sn:%i]. " + "Only 1 fault can be handled per tick.\n"); + grad_req->done(false); + return; + } + switch (grad_req->cmd) { @@ -64,6 +84,7 @@ GraduationUnit::execute(int slot_num) tid, inst->seqNum, inst->fault->name(), inst->instName()); squashThenTrap(stage_num, inst); + lastFaultTick[tid] = cur_tick; grad_req->done(false); return; } @@ -76,13 +97,6 @@ GraduationUnit::execute(int slot_num) case GraduateInst: { - if (lastNonSpecTick == curTick()) { - DPRINTF(InOrderGraduation, "Unable to graduate [sn:%i]. " - "Only 1 nonspec inst. per cycle can graduate.\n"); - grad_req->done(false); - return; - } - DPRINTF(InOrderGraduation, "[tid:%i]:[sn:%i]: Graduating instruction %s.\n", tid, inst->seqNum, inst->staticInst->disassemble(inst->instAddr())); @@ -90,16 +104,19 @@ GraduationUnit::execute(int slot_num) // Release Non-Speculative "Block" on instructions that could not // execute because there was a non-speculative inst. active. // @TODO: Fix this functionality. Probably too conservative. + // Maybe it should be, non-spec. insts should block other + // non-spec insts because they can potentially be reading + // system state that will be changed by the 1st non-spec inst. if (inst->isNonSpeculative()) { *nonSpecInstActive[tid] = false; DPRINTF(InOrderGraduation, "[tid:%i] Non-speculative inst [sn:%i] graduated\n", tid, inst->seqNum); - lastNonSpecTick = curTick(); + lastNonSpecTick[tid] = cur_tick; } if (inst->traceData) { - inst->traceData->setStageCycle(stage_num, curTick()); + inst->traceData->setStageCycle(stage_num, cur_tick); } // Tell CPU that instruction is finished processing diff --git a/src/cpu/inorder/resources/graduation_unit.hh b/src/cpu/inorder/resources/graduation_unit.hh index 01abae85b..836b568a6 100644 --- a/src/cpu/inorder/resources/graduation_unit.hh +++ b/src/cpu/inorder/resources/graduation_unit.hh @@ -58,9 +58,9 @@ class GraduationUnit : public Resource { void execute(int slot_num); protected: - Tick lastNonSpecTick; + Tick lastNonSpecTick[ThePipeline::MaxThreads]; + Tick lastFaultTick[ThePipeline::MaxThreads]; bool *nonSpecInstActive[ThePipeline::MaxThreads]; - InstSeqNum *nonSpecSeqNum[ThePipeline::MaxThreads]; }; diff --git a/src/cpu/inorder/resources/mult_div_unit.cc b/src/cpu/inorder/resources/mult_div_unit.cc index fc27276d5..0ff05252c 100644 --- a/src/cpu/inorder/resources/mult_div_unit.cc +++ b/src/cpu/inorder/resources/mult_div_unit.cc @@ -192,7 +192,15 @@ MultDivUnit::execute(int slot_num) { ResourceRequest* mult_div_req = reqs[slot_num]; DynInstPtr inst = reqs[slot_num]->inst; - + if (inst->fault != NoFault) { + DPRINTF(InOrderMDU, + "[tid:%i]: [sn:%i]: Detected %s fault @ %x. Forwarding to " + "next stage.\n", inst->readTid(), inst->seqNum, inst->fault->name(), + inst->pcState()); + mult_div_req->done(); + return; + } + DPRINTF(InOrderMDU, "Executing [sn:%i] ...\n", slot_num); switch (mult_div_req->cmd) diff --git a/src/cpu/inorder/resources/use_def.cc b/src/cpu/inorder/resources/use_def.cc index 78497f6e5..06591121e 100644 --- a/src/cpu/inorder/resources/use_def.cc +++ b/src/cpu/inorder/resources/use_def.cc @@ -92,6 +92,9 @@ UseDefUnit::regStats() .desc("Total Accesses (Read+Write) to the FP Register File"); floatRegFileAccs = floatRegFileReads + floatRegFileWrites; + //@todo: add miscreg reads/writes + // add forwarding by type??? + regForwards .name(name() + ".regForwards") .desc("Number of Registers Read Through Forwarding Logic"); @@ -153,12 +156,19 @@ UseDefUnit::execute(int slot_idx) // for performance considerations UseDefRequest* ud_req = dynamic_cast(reqs[slot_idx]); assert(ud_req); - DynInstPtr inst = ud_req->inst; + if (inst->fault != NoFault) { + DPRINTF(InOrderUseDef, + "[tid:%i]: [sn:%i]: Detected %s fault @ %x. Forwarding to " + "next stage.\n", inst->readTid(), inst->seqNum, inst->fault->name(), + inst->pcState()); + ud_req->done(); + return; + } + ThreadID tid = inst->readTid(); InstSeqNum seq_num = inst->seqNum; int ud_idx = ud_req->useDefIdx; - // If there is a non-speculative instruction // in the pipeline then stall instructions here if (*nonSpecInstActive[tid] == true && seq_num > *nonSpecSeqNum[tid]) { -- cgit v1.2.3