提交 b06fe9d0 编写于 作者: Z zoujr

perf: Add perf counters for predictors

上级 15b95b38
......@@ -315,7 +315,7 @@ case class EnviromentParameters
(
FPGAPlatform: Boolean = true,
EnableDebug: Boolean = false,
EnablePerfDebug: Boolean = true,
EnablePerfDebug: Boolean = false,
DualCore: Boolean = false
)
......
......@@ -291,27 +291,104 @@ class Ftq extends XSModule with HasCircularQueuePtrHelper {
}
// Branch Predictor Perf counters
val fires = io.roq_commits.map{case c => c.valid && !c.bits.pd.notCFI}
val predRights = (0 until PredictWidth).map{i => !commitEntry.mispred(i) && !commitEntry.pd(i).notCFI && commitEntry.valids(i)}
val predWrongs = (0 until PredictWidth).map{i => commitEntry.mispred(i) && !commitEntry.pd(i).notCFI && commitEntry.valids(i)}
val isBTypes = (0 until PredictWidth).map{i => commitEntry.pd(i).isBr}
val isJTypes = (0 until PredictWidth).map{i => commitEntry.pd(i).isJal}
val isITypes = (0 until PredictWidth).map{i => commitEntry.pd(i).isJalr}
val isCTypes = (0 until PredictWidth).map{i => commitEntry.pd(i).isCall}
val isRTypes = (0 until PredictWidth).map{i => commitEntry.pd(i).isRet}
val mbpInstrs = fires
val mbpRights = predRights
val mbpWrongs = predWrongs
val mbpBRights = Cat(predRights) & Cat(isBTypes)
val mbpBWrongs = Cat(predWrongs) & Cat(isBTypes)
val mbpJRights = Cat(predRights) & Cat(isJTypes)
val mbpJWrongs = Cat(predWrongs) & Cat(isJTypes)
val mbpIRights = Cat(predRights) & Cat(isITypes)
val mbpIWrongs = Cat(predWrongs) & Cat(isITypes)
val mbpCRights = Cat(predRights) & Cat(isCTypes)
val mbpCWrongs = Cat(predWrongs) & Cat(isCTypes)
val mbpRRights = Cat(predRights) & Cat(isRTypes)
val mbpRWrongs = Cat(predWrongs) & Cat(isRTypes)
def predCheck(commit: FtqEntry, predAns: Seq[PredictorAnswer], lastRights: Seq[Bool], isWrong: Bool, checkTarget: Boolean) = {
commit.valids.zip(commit.pd).zip(predAns).zip(commit.takens).zip(lastRights).map {
case ((((valid, pd), ans), taken), lastRight) =>
Mux(valid && pd.isBr,
isWrong ^ Mux(ans.hit.asBool,
Mux(ans.taken.asBool, if(checkTarget) {ans.target === commitEntry.target} else {taken},
!taken),
lastRight),
false.B)
}
}
def loopCheck(commit: FtqEntry, predAns: Seq[PredictorAnswer], isWrong: Bool) = {
commit.valids.zip(commit.pd).zip(predAns).zip(commit.takens).map {
case (((valid, pd), ans), taken) =>
Mux(valid && (pd.isBr) && ans.hit.asBool,
isWrong ^ (!taken),
false.B)
}
}
def rasCheck(commit: FtqEntry, predAns: Seq[PredictorAnswer], isWrong: Bool) = {
commit.valids.zip(commit.pd).zip(predAns).zip(commit.takens).map {
case (((valid, pd), ans), taken) =>
Mux(valid && pd.isRet && taken && ans.hit.asBool,
isWrong ^ (ans.target === commitEntry.target),
false.B)
}
}
val ubtbRights = predCheck(commitEntry, commitEntry.metas.map(_.ubtbAns), commitEntry.takens.map(!_), false.B, true)
val ubtbWrongs = predCheck(commitEntry, commitEntry.metas.map(_.ubtbAns), commitEntry.takens.map(!_), true.B, true)
// btb and ubtb pred jal and jalr as well
val btbRights = predCheck(commitEntry, commitEntry.metas.map(_.btbAns), ubtbRights, false.B, true)
val btbWrongs = predCheck(commitEntry, commitEntry.metas.map(_.btbAns), ubtbRights, true.B, true)
val tageRights = predCheck(commitEntry, commitEntry.metas.map(_.tageAns), btbRights, false.B, false)
val tageWrongs = predCheck(commitEntry, commitEntry.metas.map(_.tageAns), btbRights, true.B, false)
val loopRights = loopCheck(commitEntry, commitEntry.metas.map(_.loopAns), false.B)
val loopWrongs = loopCheck(commitEntry, commitEntry.metas.map(_.loopAns), true.B)
val rasRights = rasCheck(commitEntry, commitEntry.metas.map(_.rasAns), false.B)
val rasWrongs = rasCheck(commitEntry, commitEntry.metas.map(_.rasAns), true.B)
val perfCountsMap = Map(
"BpInstr" -> PopCount(io.roq_commits.map{case c => c.valid && !c.bits.pd.notCFI}),
"BpInstr" -> PopCount(mbpInstrs),
"BpBInstr" -> PopCount(io.roq_commits.map{case c => c.valid && c.bits.pd.isBr}),
// "BpRight" -> PopCount((0 until PredictWidth).map{i => !mispredict_vec(headPtr.value)(i) && commit_valids(i)}),
"BpRight" -> PopCount((0 until PredictWidth).map{i => !commitEntry.mispred(i) && !commitEntry.pd(i).notCFI && commitEntry.valids(i)}),
// "BpWrong" -> PopCount((0 until PredictWidth).map{i => mispredict_vec(headPtr.value)(i) && commit_valids(i)}),
"BpWrong" -> PopCount((0 until PredictWidth).map{i => commitEntry.mispred(i) && !commitEntry.pd(i).notCFI && commitEntry.valids(i)}),
"BpBRight" -> PopCount((0 until PredictWidth).map{i => !commitEntry.mispred(i) && commitEntry.pd(i).isBr && commitEntry.valids(i)}),
"BpBWrong" -> PopCount((0 until PredictWidth).map{i => commitEntry.mispred(i) && commitEntry.pd(i).isBr && commitEntry.valids(i)}),
"BpJRight" -> PopCount((0 until PredictWidth).map{i => !commitEntry.mispred(i) && commitEntry.pd(i).isJal && commitEntry.valids(i)}),
"BpJWrong" -> PopCount((0 until PredictWidth).map{i => commitEntry.mispred(i) && commitEntry.pd(i).isJal && commitEntry.valids(i)}),
"BpIRight" -> PopCount((0 until PredictWidth).map{i => !commitEntry.mispred(i) && commitEntry.pd(i).isJalr && commitEntry.valids(i)}),
"BpIWrong" -> PopCount((0 until PredictWidth).map{i => commitEntry.mispred(i) && commitEntry.pd(i).isJalr && commitEntry.valids(i)}),
"BpCRight" -> PopCount((0 until PredictWidth).map{i => !commitEntry.mispred(i) && commitEntry.pd(i).isCall && commitEntry.valids(i)}),
"BpCWrong" -> PopCount((0 until PredictWidth).map{i => commitEntry.mispred(i) && commitEntry.pd(i).isCall && commitEntry.valids(i)}),
"BpRRight" -> PopCount((0 until PredictWidth).map{i => !commitEntry.mispred(i) && commitEntry.pd(i).isRet && commitEntry.valids(i)}),
"BpRWrong" -> PopCount((0 until PredictWidth).map{i => commitEntry.mispred(i) && commitEntry.pd(i).isRet && commitEntry.valids(i)}),
"BpRight" -> PopCount(mbpRights),
"BpWrong" -> PopCount(mbpWrongs),
"BpBRight" -> PopCount(mbpBRights),
"BpBWrong" -> PopCount(mbpBWrongs),
"BpJRight" -> PopCount(mbpJRights),
"BpJWrong" -> PopCount(mbpJWrongs),
"BpIRight" -> PopCount(mbpIRights),
"BpIWrong" -> PopCount(mbpIWrongs),
"BpCRight" -> PopCount(mbpCRights),
"BpCWrong" -> PopCount(mbpCWrongs),
"BpRRight" -> PopCount(mbpRRights),
"BpRWrong" -> PopCount(mbpRWrongs),
"ubtbRight" -> PopCount(ubtbRights),
"ubtbWrong" -> PopCount(ubtbWrongs),
"btbRight" -> PopCount(btbRights),
"btbWrong" -> PopCount(btbWrongs),
"tageRight" -> PopCount(tageRights),
"tageWrong" -> PopCount(tageWrongs),
"rasRight" -> PopCount(rasRights),
"rasWrong" -> PopCount(rasWrongs),
"loopRight" -> PopCount(loopRights),
"loopWrong" -> PopCount(loopWrongs),
)
for((key, value) <- perfCountsMap) {
XSPerf(key, value, acc = true, intervalBits = 0)
XSPerf(key, value)
}
XSPerf("ftq_entries", validEntries)
......
......@@ -66,7 +66,6 @@ class Jump extends FunctionUnit with HasRedirectOut {
redirectOutValid := valid && !jumpDataModule.io.isAuipc
redirectOut := DontCare
redirectOut.cfiUpdate.target := jumpDataModule.io.target
redirectOut.level := RedirectLevel.flushAfter
redirectOut.roqIdx := uop.roqIdx
redirectOut.ftqIdx := uop.cf.ftqPtr
......
......@@ -213,6 +213,16 @@ class BPUStage1 extends BPUStage {
io.out.resp <> io.in.resp
io.out.brInfo := io.in.brInfo
// For perf counters
if (!env.FPGAPlatform && env.EnablePerfDebug) {
io.out.brInfo.metas.zipWithIndex.foreach{case (meta, i) =>
// record ubtb pred result
meta.ubtbAns.hit := ubtbResp.hits(i)
meta.ubtbAns.taken := ubtbResp.takens(i)
meta.ubtbAns.target := ubtbResp.targets(i)
}
}
if (BPUDebug) {
XSDebug(io.outFire, "outPred using ubtb resp: hits:%b, takens:%b, notTakens:%b, isRVC:%b\n",
ubtbResp.hits.asUInt, ubtbResp.takens.asUInt, ~ubtbResp.takens.asUInt & brMask.asUInt, ubtbResp.is_RVC.asUInt)
......@@ -233,6 +243,16 @@ class BPUStage2 extends BPUStage {
hasHalfRVI := btbResp.hits(PredictWidth-1) && !btbResp.isRVC(PredictWidth-1) && HasCExtension.B
// For perf counters
if (!env.FPGAPlatform && env.EnablePerfDebug) {
io.out.brInfo.metas.zipWithIndex.foreach{case (meta, i) =>
// record btb pred result
meta.btbAns.hit := btbResp.hits(i)
meta.btbAns.taken := bimResp.ctrs(i)(1)
meta.btbAns.target := btbResp.targets(i)
}
}
if (BPUDebug) {
XSDebug(io.outFire, "outPred using btb&bim resp: hits:%b, ctrTakens:%b\n",
btbResp.hits.asUInt, VecInit(bimResp.ctrs.map(_(1))).asUInt)
......@@ -323,6 +343,26 @@ class BPUStage3 extends BPUStage {
targets(i) := ras.io.out.bits.target
}
}
// For perf counters
if (!env.FPGAPlatform && env.EnablePerfDebug) {
io.out.brInfo.metas.zipWithIndex.foreach{case (meta, i) =>
// record tage pred result
meta.tageAns.hit := tageResp.hits(i)
meta.tageAns.taken := tageResp.takens(i)
meta.tageAns.target := DontCare
// record ras pred result
meta.rasAns.hit := ras.io.out.valid
meta.rasAns.taken := true.B
meta.rasAns.target := ras.io.out.bits.target
// record loop pred result
meta.loopAns.hit := loopRes(i)
meta.loopAns.taken := false.B
meta.loopAns.target := DontCare
}
}
}
......
......@@ -533,12 +533,12 @@ class IFU extends XSModule with HasIFUConst with HasCircularQueuePtrHelper
io.fetchPacket.valid := fetchPacketValid
// if(IFUDebug) {
if (!env.FPGAPlatform) {
val predictor_s3 = RegEnable(Mux(if3_redirect, 1.U(log2Up(4).W), 0.U(log2Up(4).W)), if3_fire)
val predictor_s4 = Mux(if4_redirect, 2.U, predictor_s3)
val predictor = predictor_s4
toFtqBuf.metas.map(_.predictor := predictor)
}
// if (!env.FPGAPlatform) {
// val predictor_s3 = RegEnable(Mux(if3_redirect, 1.U(log2Up(4).W), 0.U(log2Up(4).W)), if3_fire)
// val predictor_s4 = Mux(if4_redirect, 2.U, predictor_s3)
// val predictor = predictor_s4
// toFtqBuf.metas.map(_.predictor := predictor)
// }
// }
// val predRight = cfiUpdate.valid && !cfiUpdate.bits.isMisPred && !cfiUpdate.bits.isReplay
......@@ -562,6 +562,52 @@ class IFU extends XSModule with HasIFUConst with HasCircularQueuePtrHelper
// ExcitingUtils.addSource(loopRight, "perfCntloopRight", Perf)
// ExcitingUtils.addSource(loopWrong, "perfCntloopWrong", Perf)
if (!env.FPGAPlatform && env.EnablePerfDebug) {
val predictor_s3 = RegEnable(Mux(if3_redirect, 1.U(log2Up(4).W), 0.U(log2Up(4).W)), if3_fire)
val predictor_s4 = Mux(if4_redirect, 2.U, predictor_s3)
val predictor = predictor_s4
toFtqBuf.metas.map(_.predictor := predictor)
// val ubtbAns = WireInit(VecInit(Seq.fill(PredictWidth) {0.U.asTypeOf(new PredictorAnswer)} ))
// val btbAns = WireInit(VecInit(Seq.fill(PredictWidth) {0.U.asTypeOf(new PredictorAnswer)} ))
// val bimResp = WireInit(VecInit(Seq.fill(PredictWidth) {false.B} ))
// val tageAns = WireInit(VecInit(Seq.fill(PredictWidth) {0.U.asTypeOf(new PredictorAnswer)} ))
// val rasAns = WireInit(0.U.asTypeOf(new PredictorAnswer))
// val loopAns = WireInit(VecInit(Seq.fill(PredictWidth) {0.U.asTypeOf(new PredictorAnswer)} ))
// ExcitingUtils.addSink(ubtbAns, "ubtbAns")
// ExcitingUtils.addSink(btbAns, "btbAns")
// ExcitingUtils.addSink(bimResp, "bimResp")
// ExcitingUtils.addSink(tageAns, "tageAns")
// ExcitingUtils.addSink(rasAns, "rasAns")
// // ExcitingUtils.addSink(loopAns, "loopAns")
// val ubtbAns_s3 = RegEnable(ubtbAns, if2_fire)
// val ubtbAns_s4 = RegEnable(ubtbAns_s3, if3_fire)
// val btbAns_s3 = RegEnable(btbAns, if2_fire)
// val btbAns_s4 = RegEnable(btbAns_s3, if3_fire)
// val bimResp_s3 = RegEnable(bimResp, if2_fire)
// val bimResp_s4 = RegEnable(bimResp_s3, if3_fire)
toFtqBuf.metas.zipWithIndex.foreach{ case(x,i) =>
x.predictor := predictor
// x.ubtbAns := ubtbAns_s4(i)
// x.btbAns := btbAns_s4(i)
// x.btbAns.taken := bimResp_s4(i)
// x.tageAns := tageAns(i)
// x.rasAns := rasAns // Is this right?
// x.loopAns := loopAns(i)
x.ubtbAns := bpu.io.brInfo.metas(i).ubtbAns
x.btbAns := bpu.io.brInfo.metas(i).btbAns
x.tageAns := bpu.io.brInfo.metas(i).tageAns
x.rasAns := bpu.io.brInfo.metas(i).rasAns // Is this right?
x.loopAns := bpu.io.brInfo.metas(i).loopAns
}
}
// debug info
if (IFUDebug) {
XSDebug(RegNext(reset.asBool) && !reset.asBool, "Reseting...\n")
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册