inorder: remove stalls on trap squash
This commit is contained in:
parent
34b2500f09
commit
71018f5e8b
5 changed files with 66 additions and 9 deletions
|
@ -55,18 +55,32 @@ struct InterStageStruct {
|
||||||
|
|
||||||
/** Struct that defines all backwards communication. */
|
/** Struct that defines all backwards communication. */
|
||||||
struct TimeStruct {
|
struct TimeStruct {
|
||||||
struct stageComm {
|
struct StageComm {
|
||||||
bool squash;
|
bool squash;
|
||||||
InstSeqNum doneSeqNum;
|
InstSeqNum doneSeqNum;
|
||||||
|
|
||||||
bool uncached;
|
bool uncached;
|
||||||
ThePipeline::DynInstPtr uncachedLoad;
|
ThePipeline::DynInstPtr uncachedLoad;
|
||||||
|
|
||||||
|
StageComm()
|
||||||
|
: squash(false), doneSeqNum(0), uncached(false), uncachedLoad(NULL)
|
||||||
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
stageComm stageInfo[ThePipeline::NumStages][ThePipeline::MaxThreads];
|
StageComm stageInfo[ThePipeline::NumStages][ThePipeline::MaxThreads];
|
||||||
|
|
||||||
bool stageBlock[ThePipeline::NumStages][ThePipeline::MaxThreads];
|
bool stageBlock[ThePipeline::NumStages][ThePipeline::MaxThreads];
|
||||||
bool stageUnblock[ThePipeline::NumStages][ThePipeline::MaxThreads];
|
bool stageUnblock[ThePipeline::NumStages][ThePipeline::MaxThreads];
|
||||||
|
|
||||||
|
TimeStruct()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < ThePipeline::NumStages; i++) {
|
||||||
|
for (int j = 0; j < ThePipeline::MaxThreads; j++) {
|
||||||
|
stageBlock[i][j] = false;
|
||||||
|
stageUnblock[i][j] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //__CPU_INORDER_COMM_HH__
|
#endif //__CPU_INORDER_COMM_HH__
|
||||||
|
|
|
@ -314,7 +314,8 @@ class InOrderDynInst : public FastAlloc, public RefCounted
|
||||||
// BASE INSTRUCTION INFORMATION.
|
// BASE INSTRUCTION INFORMATION.
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
std::string instName() { return staticInst->getName(); }
|
std::string instName()
|
||||||
|
{ return (staticInst) ? staticInst->getName() : "undecoded-inst"; }
|
||||||
|
|
||||||
void setMachInst(ExtMachInst inst);
|
void setMachInst(ExtMachInst inst);
|
||||||
|
|
||||||
|
|
|
@ -226,6 +226,7 @@ PipelineStage::checkStall(ThreadID tid) const
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!stalls[tid].resources.empty()) {
|
if (!stalls[tid].resources.empty()) {
|
||||||
|
#if TRACING_ON
|
||||||
string stall_src;
|
string stall_src;
|
||||||
|
|
||||||
for (int i=0; i < stalls[tid].resources.size(); i++) {
|
for (int i=0; i < stalls[tid].resources.size(); i++) {
|
||||||
|
@ -234,6 +235,7 @@ PipelineStage::checkStall(ThreadID tid) const
|
||||||
|
|
||||||
DPRINTF(InOrderStage,"[tid:%i]: Stall fom resources (%s) detected.\n",
|
DPRINTF(InOrderStage,"[tid:%i]: Stall fom resources (%s) detected.\n",
|
||||||
tid, stall_src);
|
tid, stall_src);
|
||||||
|
#endif
|
||||||
ret_val = true;
|
ret_val = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,8 +296,11 @@ PipelineStage::block(ThreadID tid)
|
||||||
|
|
||||||
stageStatus[tid] = Blocked;
|
stageStatus[tid] = Blocked;
|
||||||
|
|
||||||
if (prevStageValid)
|
if (prevStageValid) {
|
||||||
|
DPRINTF(InOrderStage, "[tid:%d]: Stage %i setting block signal.\n",
|
||||||
|
tid, stageNum);
|
||||||
toPrevStages->stageBlock[stageNum][tid] = true;
|
toPrevStages->stageBlock[stageNum][tid] = true;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -323,6 +328,7 @@ PipelineStage::blockDueToBuffer(ThreadID tid)
|
||||||
bool
|
bool
|
||||||
PipelineStage::unblock(ThreadID tid)
|
PipelineStage::unblock(ThreadID tid)
|
||||||
{
|
{
|
||||||
|
// @todo: Shouldnt this be if any available slots are open???
|
||||||
// Stage is done unblocking only if the skid buffer is empty.
|
// Stage is done unblocking only if the skid buffer is empty.
|
||||||
if (skidBuffer[tid].empty()) {
|
if (skidBuffer[tid].empty()) {
|
||||||
DPRINTF(InOrderStage, "[tid:%u]: Done unblocking.\n", tid);
|
DPRINTF(InOrderStage, "[tid:%u]: Done unblocking.\n", tid);
|
||||||
|
@ -623,6 +629,13 @@ PipelineStage::readStallSignals(ThreadID tid)
|
||||||
for (int stage_idx = stageNum+1; stage_idx <= lastStallingStage[tid];
|
for (int stage_idx = stageNum+1; stage_idx <= lastStallingStage[tid];
|
||||||
stage_idx++) {
|
stage_idx++) {
|
||||||
|
|
||||||
|
DPRINTF(InOrderStage, "[tid:%i] Reading stall signals from Stage "
|
||||||
|
"%i. Block:%i Unblock:%i.\n",
|
||||||
|
tid,
|
||||||
|
stage_idx,
|
||||||
|
fromNextStages->stageBlock[stage_idx][tid],
|
||||||
|
fromNextStages->stageUnblock[stage_idx][tid]);
|
||||||
|
|
||||||
// Check for Stage Blocking Signal
|
// Check for Stage Blocking Signal
|
||||||
if (fromNextStages->stageBlock[stage_idx][tid]) {
|
if (fromNextStages->stageBlock[stage_idx][tid]) {
|
||||||
DPRINTF(InOrderStage, "[tid:%i] Stall from stage %i set.\n", tid,
|
DPRINTF(InOrderStage, "[tid:%i] Stall from stage %i set.\n", tid,
|
||||||
|
@ -637,6 +650,20 @@ PipelineStage::readStallSignals(ThreadID tid)
|
||||||
stalls[tid].stage[stage_idx] = false;
|
stalls[tid].stage[stage_idx] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int stage_idx = 0; stage_idx < NumStages;
|
||||||
|
stage_idx++) {
|
||||||
|
|
||||||
|
DPRINTF(InOrderStage, "[tid:%i] Stall signals from Stage "
|
||||||
|
"%i. Block:%i Unblock:%i...NBlock:%i NUnblock:%i\n",
|
||||||
|
tid,
|
||||||
|
stage_idx,
|
||||||
|
fromNextStages->stageBlock[stage_idx][tid],
|
||||||
|
fromNextStages->stageUnblock[stage_idx][tid],
|
||||||
|
toPrevStages->stageBlock[stage_idx][tid],
|
||||||
|
toPrevStages->stageUnblock[stage_idx][tid]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -866,7 +893,9 @@ PipelineStage::processInsts(ThreadID tid)
|
||||||
inst = insts_to_stage.front();
|
inst = insts_to_stage.front();
|
||||||
|
|
||||||
DPRINTF(InOrderStage, "[tid:%u]: Processing instruction [sn:%lli] "
|
DPRINTF(InOrderStage, "[tid:%u]: Processing instruction [sn:%lli] "
|
||||||
"with PC %s\n", tid, inst->seqNum, inst->pcState());
|
"%s with PC %s\n", tid, inst->seqNum,
|
||||||
|
inst->instName(),
|
||||||
|
inst->pcState());
|
||||||
|
|
||||||
if (inst->isSquashed()) {
|
if (inst->isSquashed()) {
|
||||||
DPRINTF(InOrderStage, "[tid:%u]: Instruction %i with PC %s is "
|
DPRINTF(InOrderStage, "[tid:%u]: Instruction %i with PC %s is "
|
||||||
|
|
|
@ -105,7 +105,7 @@ RegDepMap::insert(DynInstPtr inst)
|
||||||
inst->flattenDestReg(i, flat_idx);
|
inst->flattenDestReg(i, flat_idx);
|
||||||
|
|
||||||
if (flat_idx == TheISA::ZeroReg) {
|
if (flat_idx == TheISA::ZeroReg) {
|
||||||
DPRINTF(IntRegs, "[sn:%i]: Ignoring Insert-Dependency tracking for "
|
DPRINTF(RegDepMap, "[sn:%i]: Ignoring Insert-Dependency tracking for "
|
||||||
"ISA-ZeroReg (Int. Reg %i).\n", inst->seqNum,
|
"ISA-ZeroReg (Int. Reg %i).\n", inst->seqNum,
|
||||||
flat_idx);
|
flat_idx);
|
||||||
continue;
|
continue;
|
||||||
|
@ -145,7 +145,7 @@ RegDepMap::remove(DynInstPtr inst)
|
||||||
RegIndex flat_idx = inst->flattenedDestRegIdx(i);
|
RegIndex flat_idx = inst->flattenedDestRegIdx(i);
|
||||||
|
|
||||||
if (flat_idx == TheISA::ZeroReg) {
|
if (flat_idx == TheISA::ZeroReg) {
|
||||||
DPRINTF(IntRegs, "[sn:%i]: Ignoring Remove-Dependency tracking for "
|
DPRINTF(RegDepMap, "[sn:%i]: Ignoring Remove-Dependency tracking for "
|
||||||
"ISA-ZeroReg (Int. Reg %i).\n", inst->seqNum,
|
"ISA-ZeroReg (Int. Reg %i).\n", inst->seqNum,
|
||||||
flat_idx);
|
flat_idx);
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -116,6 +116,9 @@ FetchSeqUnit::execute(int slot_num)
|
||||||
// If it's a return, then we must wait for resolved address.
|
// If it's a return, then we must wait for resolved address.
|
||||||
// The Predictor will mark a return a false as "not taken"
|
// The Predictor will mark a return a false as "not taken"
|
||||||
// if there is no RAS entry
|
// if there is no RAS entry
|
||||||
|
DPRINTF(InOrderFetchSeq, "[tid:%d]: Setting block signal "
|
||||||
|
"for stage %i.\n",
|
||||||
|
tid, stage_num);
|
||||||
cpu->pipelineStage[stage_num]->
|
cpu->pipelineStage[stage_num]->
|
||||||
toPrevStages->stageBlock[stage_num][tid] = true;
|
toPrevStages->stageBlock[stage_num][tid] = true;
|
||||||
pcValid[tid] = false;
|
pcValid[tid] = false;
|
||||||
|
@ -215,8 +218,16 @@ FetchSeqUnit::squash(DynInstPtr inst, int squash_stage,
|
||||||
|
|
||||||
// Unblock Any Stages Waiting for this information to be updated ...
|
// Unblock Any Stages Waiting for this information to be updated ...
|
||||||
if (!pcValid[tid]) {
|
if (!pcValid[tid]) {
|
||||||
|
DPRINTF(InOrderFetchSeq, "[tid:%d]: Setting unblock signal "
|
||||||
|
"for stage %i.\n",
|
||||||
|
tid, pcBlockStage[tid]);
|
||||||
|
|
||||||
|
// Need to use "fromNextStages" instead of "toPrevStages"
|
||||||
|
// because the timebuffer will have already have advanced
|
||||||
|
// in the tick function and this squash function will happen after
|
||||||
|
// the tick
|
||||||
cpu->pipelineStage[pcBlockStage[tid]]->
|
cpu->pipelineStage[pcBlockStage[tid]]->
|
||||||
toPrevStages->stageUnblock[pcBlockStage[tid]][tid] = true;
|
fromNextStages->stageUnblock[pcBlockStage[tid]][tid] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pcValid[tid] = true;
|
pcValid[tid] = true;
|
||||||
|
@ -291,6 +302,8 @@ FetchSeqUnit::trap(Fault fault, ThreadID tid, DynInstPtr inst)
|
||||||
"%s.\n", tid, pc[tid]);
|
"%s.\n", tid, pc[tid]);
|
||||||
DPRINTF(InOrderFetchSeq, "[tid:%i]: Trap updating to PC: "
|
DPRINTF(InOrderFetchSeq, "[tid:%i]: Trap updating to PC: "
|
||||||
"%s.\n", tid, pc[tid]);
|
"%s.\n", tid, pc[tid]);
|
||||||
|
|
||||||
|
cpu->removePipelineStalls(tid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Loading…
Reference in a new issue