diff -r 12a0efdde000 -r ae26c5a9ba33 src/cpu/simple/BaseSimpleCPU.py --- a/src/cpu/simple/BaseSimpleCPU.py Fri Nov 29 14:36:10 2013 +0100 +++ b/src/cpu/simple/BaseSimpleCPU.py Fri Nov 29 17:19:57 2013 +0100 @@ -30,6 +30,7 @@ from m5.params import * from BaseCPU import BaseCPU from DummyChecker import DummyChecker +from BranchPredictor import BranchPredictor class BaseSimpleCPU(BaseCPU): type = 'BaseSimpleCPU' @@ -46,3 +47,5 @@ else: print "ERROR: Checker only supported under ARM ISA!" exit(1) + + branchPred = Param.BranchPredictor(NULL, "Branch Predictor") diff -r 12a0efdde000 -r ae26c5a9ba33 src/cpu/simple/base.hh --- a/src/cpu/simple/base.hh Fri Nov 29 14:36:10 2013 +0100 +++ b/src/cpu/simple/base.hh Fri Nov 29 17:19:57 2013 +0100 @@ -77,7 +77,7 @@ } struct BaseSimpleCPUParams; - +class BPredUnit; class BaseSimpleCPU : public BaseCPU { @@ -87,6 +87,8 @@ typedef TheISA::FloatRegBits FloatRegBits; typedef TheISA::CCReg CCReg; + BPredUnit *branchPred; + protected: Trace::InstRecord *traceData; @@ -272,6 +274,15 @@ Stats::Scalar dcacheRetryCycles; Counter lastDcacheRetry; + /// @{ + /// Total number of branches fetched + Stats::Scalar numBranches; + /// Number of branches predicted as taken + Stats::Scalar numPredictedBranches; + /// Number of misprediced branches + Stats::Scalar numBranchMispred; + /// @} + void serializeThread(std::ostream &os, ThreadID tid); void unserializeThread(Checkpoint *cp, const std::string §ion, ThreadID tid); @@ -446,6 +457,9 @@ bool misspeculating() { return thread->misspeculating(); } ThreadContext *tcBase() { return tc; } + + private: + TheISA::PCState pred_pc; }; #endif // __CPU_SIMPLE_BASE_HH__ diff -r 12a0efdde000 -r ae26c5a9ba33 src/cpu/simple/base.cc --- a/src/cpu/simple/base.cc Fri Nov 29 14:36:10 2013 +0100 +++ b/src/cpu/simple/base.cc Fri Nov 29 17:19:57 2013 +0100 @@ -60,6 +60,7 @@ #include "cpu/checker/cpu.hh" #include "cpu/checker/thread_context.hh" #include "cpu/exetrace.hh" +#include "cpu/pred/bpred_unit.hh" #include "cpu/profile.hh" #include "cpu/simple_thread.hh" #include "cpu/smt.hh" @@ -85,7 +86,9 @@ using namespace TheISA; BaseSimpleCPU::BaseSimpleCPU(BaseSimpleCPUParams *p) - : BaseCPU(p), traceData(NULL), thread(NULL) + : BaseCPU(p), + branchPred(p->branchPred), + traceData(NULL), thread(NULL) { if (FullSystem) thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb, @@ -286,6 +289,21 @@ idleFraction = constant(1.0) - notIdleFraction; numIdleCycles = idleFraction * numCycles; numBusyCycles = (notIdleFraction)*numCycles; + + numBranches + .name(name() + ".Branches") + .desc("Number of branches fetched") + .prereq(numBranches); + + numPredictedBranches + .name(name() + ".predictedBranches") + .desc("Number of branches predicted as taken") + .prereq(numPredictedBranches); + + numBranchMispred + .name(name() + ".BranchMispred") + .desc("Number of branch mispredictions") + .prereq(numBranchMispred); } void @@ -434,6 +452,19 @@ curStaticInst->getName(), curStaticInst->machInst); #endif // TRACING_ON } + + if (branchPred && curStaticInst && curStaticInst->isControl()) { + // Use a fake sequence number since we only have one + // instruction in flight at the same time. + const InstSeqNum cur_sn(0); + const ThreadID tid(0); + pred_pc = thread->pcState(); + const bool predict_taken( + branchPred->predict(curStaticInst, cur_sn, pred_pc, tid)); + + if (predict_taken) + ++numPredictedBranches; + } } void @@ -464,6 +495,10 @@ CPA::cpa()->swAutoBegin(tc, pc.nextInstAddr()); } + if (curStaticInst->isControl()) { + ++numBranches; + } + /* Power model statistics */ //integer alu accesses if (curStaticInst->isInteger()){ @@ -507,10 +542,11 @@ } } - void BaseSimpleCPU::advancePC(Fault fault) { + const bool branching(thread->pcState().branching()); + //Since we're moving to a new pc, zero out the offset fetchOffset = 0; if (fault != NoFault) { @@ -526,6 +562,23 @@ thread->pcState(pcState); } } + + if (branchPred && curStaticInst && curStaticInst->isControl()) { + // Use a fake sequence number since we only have one + // instruction in flight at the same time. + const InstSeqNum cur_sn(0); + const ThreadID tid(0); + + if (pred_pc == thread->pcState()) { + // Correctly predicted branch + branchPred->update(cur_sn, tid); + } else { + // Mis-predicted branch + branchPred->squash(cur_sn, pcState(), + branching, tid); + ++numBranchMispred; + } + } } void