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.
This commit is contained in:
parent
c4deabfb97
commit
561c33f082
|
@ -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,11 +417,21 @@ 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;
|
||||
}
|
||||
|
||||
RSkedPtr
|
||||
InOrderCPU::createBackEndSked(DynInstPtr inst)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
};
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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]) {
|
||||
|
|
Loading…
Reference in a new issue