summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKorey Sewell <ksewell@umich.edu>2011-06-19 21:43:40 -0400
committerKorey Sewell <ksewell@umich.edu>2011-06-19 21:43:40 -0400
commit561c33f0824a705cb360ecb4ae3bf8cfd490f007 (patch)
tree7fb92ebc9a8f09ceacb8ad8e60e60990a9939621
parentc4deabfb97928f81acb0d66338426cb5f2687c37 (diff)
downloadgem5-561c33f0824a705cb360ecb4ae3bf8cfd490f007.tar.xz
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.
-rw-r--r--src/cpu/inorder/cpu.cc16
-rw-r--r--src/cpu/inorder/cpu.hh5
-rw-r--r--src/cpu/inorder/inorder_dyn_inst.cc8
-rw-r--r--src/cpu/inorder/inorder_dyn_inst.hh18
-rw-r--r--src/cpu/inorder/pipeline_stage.cc1
-rw-r--r--src/cpu/inorder/resources/agen_unit.cc9
-rw-r--r--src/cpu/inorder/resources/branch_predictor.cc15
-rw-r--r--src/cpu/inorder/resources/cache_unit.cc33
-rw-r--r--src/cpu/inorder/resources/decode_unit.cc17
-rw-r--r--src/cpu/inorder/resources/execution_unit.cc9
-rw-r--r--src/cpu/inorder/resources/fetch_seq_unit.cc11
-rw-r--r--src/cpu/inorder/resources/fetch_unit.cc20
-rw-r--r--src/cpu/inorder/resources/graduation_unit.cc39
-rw-r--r--src/cpu/inorder/resources/graduation_unit.hh4
-rw-r--r--src/cpu/inorder/resources/mult_div_unit.cc10
-rw-r--r--src/cpu/inorder/resources/use_def.cc14
16 files changed, 171 insertions, 58 deletions
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<TimeStruct> *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<FetchBlock*>::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<UseDefRequest*>(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]) {