changeset 79cba855342c in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=79cba855342c
description:
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.
diffstat:
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(-)
diffs (truncated from 582 to 300 lines):
diff -r fe5fcf6271e9 -r 79cba855342c src/cpu/inorder/cpu.cc
--- a/src/cpu/inorder/cpu.cc Sun Jun 19 21:43:40 2011 -0400
+++ b/src/cpu/inorder/cpu.cc Sun Jun 19 21:43:40 2011 -0400
@@ -196,7 +196,6 @@
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 @@
endOfSkedIt = skedCache.end();
frontEndSked = createFrontEndSked();
-
+ faultSked = createFaultSked();
+
lastRunningCycle = curTick();
lockAddr = 0;
@@ -417,12 +417,22 @@
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)
{
RSkedPtr res_sked = lookupSked(inst);
diff -r fe5fcf6271e9 -r 79cba855342c src/cpu/inorder/cpu.hh
--- a/src/cpu/inorder/cpu.hh Sun Jun 19 21:43:40 2011 -0400
+++ b/src/cpu/inorder/cpu.hh Sun Jun 19 21:43:40 2011 -0400
@@ -319,6 +319,7 @@
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 @@
}
ThePipeline::RSkedPtr createFrontEndSked();
+ ThePipeline::RSkedPtr createFaultSked();
ThePipeline::RSkedPtr createBackEndSked(DynInstPtr inst);
class StageScheduler {
@@ -751,7 +753,7 @@
virtual void wakeup();
#endif
- // LL/SC debug functionality
+ /* LL/SC debug functionality
unsigned stCondFails;
unsigned readStCondFailures()
@@ -759,6 +761,7 @@
unsigned setStCondFailures(unsigned st_fails)
{ return stCondFails = st_fails; }
+ */
/** Returns a pointer to a thread context. */
ThreadContext *tcBase(ThreadID tid = 0)
diff -r fe5fcf6271e9 -r 79cba855342c src/cpu/inorder/inorder_dyn_inst.cc
--- a/src/cpu/inorder/inorder_dyn_inst.cc Sun Jun 19 21:43:40 2011 -0400
+++ b/src/cpu/inorder/inorder_dyn_inst.cc Sun Jun 19 21:43:40 2011 -0400
@@ -87,6 +87,12 @@
int InOrderDynInst::instcount = 0;
+int
+InOrderDynInst::cpuId()
+{
+ return cpu->cpuId();
+}
+
void
InOrderDynInst::setMachInst(ExtMachInst machInst)
{
@@ -330,7 +336,7 @@
squashSeqNum = seqNum;
#if ISA_HAS_DELAY_SLOT
- if (isControl()) {
+ if (staticInst && isControl()) {
TheISA::PCState nextPC = pc;
TheISA::advancePC(nextPC, staticInst);
diff -r fe5fcf6271e9 -r 79cba855342c src/cpu/inorder/inorder_dyn_inst.hh
--- a/src/cpu/inorder/inorder_dyn_inst.hh Sun Jun 19 21:43:40 2011 -0400
+++ b/src/cpu/inorder/inorder_dyn_inst.hh Sun Jun 19 21:43:40 2011 -0400
@@ -355,6 +355,12 @@
/** 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 @@
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 @@
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 -r fe5fcf6271e9 -r 79cba855342c src/cpu/inorder/pipeline_stage.cc
--- a/src/cpu/inorder/pipeline_stage.cc Sun Jun 19 21:43:40 2011 -0400
+++ b/src/cpu/inorder/pipeline_stage.cc Sun Jun 19 21:43:40 2011 -0400
@@ -130,6 +130,7 @@
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 -r fe5fcf6271e9 -r 79cba855342c src/cpu/inorder/resources/agen_unit.cc
--- a/src/cpu/inorder/resources/agen_unit.cc Sun Jun 19 21:43:40 2011 -0400
+++ b/src/cpu/inorder/resources/agen_unit.cc Sun Jun 19 21:43:40 2011 -0400
@@ -58,6 +58,15 @@
#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 -r fe5fcf6271e9 -r 79cba855342c
src/cpu/inorder/resources/branch_predictor.cc
--- a/src/cpu/inorder/resources/branch_predictor.cc Sun Jun 19 21:43:40
2011 -0400
+++ b/src/cpu/inorder/resources/branch_predictor.cc Sun Jun 19 21:43:40
2011 -0400
@@ -68,8 +68,14 @@
{
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 @@
return;
}
-
+ ThreadID tid = inst->readTid();
+ InstSeqNum seq_num = inst->seqNum;
switch (bpred_req->cmd)
{
case PredictBranch:
@@ -110,6 +117,8 @@
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 -r fe5fcf6271e9 -r 79cba855342c src/cpu/inorder/resources/cache_unit.cc
--- a/src/cpu/inorder/resources/cache_unit.cc Sun Jun 19 21:43:40 2011 -0400
+++ b/src/cpu/inorder/resources/cache_unit.cc Sun Jun 19 21:43:40 2011 -0400
@@ -395,7 +395,7 @@
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 @@
}
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 @@
"[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 @@
"[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 @@
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 @@
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 @@
CacheUnit::squash(DynInstPtr inst, int stage_num,
InstSeqNum squash_seq_num, ThreadID tid)
{
- if (tlbBlockSeqNum[tid] &&
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev