提交 d0527adf 编写于 作者: Z zoujr

BPU: Modify the branch history update logic, update according to each br instruction

上级 879035f6
......@@ -147,6 +147,8 @@ class CfiUpdateInfo(implicit p: Parameters) extends XSBundle with HasBPUParamete
val target = UInt(VAddrBits.W)
val taken = Bool()
val isMisPred = Bool()
val shift = UInt((log2Ceil(numBr)+1).W)
val addIntoHist = Bool()
}
// Dequeue DecodeWidth insts from Ibuffer
......
......@@ -330,19 +330,14 @@ class Predictor(implicit p: Parameters) extends XSModule with HasBPUConst {
// History manage
// s1
val s1_sawNTBr = Mux(resp.s1.preds.hit,
resp.s1.ftb_entry.brValids.zip(resp.s1.preds.taken_mask).map{ case (b, t) => b && !t }.reduce(_||_),
false.B)
val s1_takenOnBr = resp.s1.real_br_taken_mask.asUInt =/= 0.U
val s1_predicted_ghist = s1_ghist.update(s1_sawNTBr, s1_takenOnBr)
XSDebug(p"s1_sawNTBR=${s1_sawNTBr}, resp.s1.hit=${resp.s1.preds.hit}, is_br=${Binary(resp.s1.ftb_entry.brValids.asUInt)}, taken_mask=${Binary(resp.s1.preds.taken_mask.asUInt)}\n")
XSDebug(p"s1_takenOnBr=$s1_takenOnBr, real_taken_mask=${Binary(resp.s1.real_taken_mask.asUInt)}\n")
XSDebug(p"s1_predicted_ghist=${Binary(s1_predicted_ghist.asUInt)}\n")
// when(s1_valid) {
// s0_ghist := s1_predicted_ghist
// }
val s1_shift = Mux(resp.s1.preds.hit,
Mux(resp.s1.real_br_taken_mask.asUInt === 0.U, PopCount(resp.s1.ftb_entry.brValids), PopCount(LowerMaskFromLowest(resp.s1.real_br_taken_mask.asUInt))),
0.U((log2Ceil(numBr)+1).W))
val s1_taken = Mux(resp.s1.preds.hit, resp.s1.real_br_taken_mask.asUInt =/= 0.U, false.B)
val s1_predicted_ghist = s1_ghist.update(s1_shift, s1_taken)
XSDebug(p"[hit] ${resp.s1.preds.hit} [s1_real_br_taken_mask] ${Binary(resp.s1.real_br_taken_mask.asUInt)} [s1_shift] ${s1_shift} [s1_taken] ${s1_taken}\n")
XSDebug(p"s1_predicted_ghist=${Binary(s1_predicted_ghist.predHist)}\n")
when(s1_valid) {
s0_pc := resp.s1.preds.target
......@@ -350,11 +345,12 @@ class Predictor(implicit p: Parameters) extends XSModule with HasBPUConst {
}
// s2
val s2_sawNTBr = Mux(resp.s2.preds.hit,
resp.s2.ftb_entry.brValids.zip(resp.s2.preds.taken_mask).map{ case (b, t) => b && !t }.reduce(_||_),
false.B)
val s2_takenOnBr = resp.s2.real_br_taken_mask.asUInt =/= 0.U
val s2_predicted_ghist = s2_ghist.update(s2_sawNTBr, s2_takenOnBr)
val s2_shift = Mux(resp.s2.preds.hit,
Mux(resp.s2.real_br_taken_mask.asUInt === 0.U, PopCount(resp.s2.ftb_entry.brValids), PopCount(LowerMaskFromLowest(resp.s2.real_br_taken_mask.asUInt))),
0.U((log2Ceil(numBr)+1).W))
val s2_taken = Mux(resp.s2.preds.hit, resp.s2.real_br_taken_mask.asUInt =/= 0.U, false.B)
val s2_predicted_ghist = s2_ghist.update(s2_shift, s2_taken)
val s2_correct_s1_ghist = s1_ghist =/= s2_predicted_ghist
when(s2_fire) {
......@@ -374,11 +370,12 @@ class Predictor(implicit p: Parameters) extends XSModule with HasBPUConst {
XSPerfAccumulate("s2_redirect_because_ghist_diff", s2_fire && s1_valid && s2_correct_s1_ghist)
// s3
val s3_sawNTBr = Mux(resp.s3.preds.hit,
resp.s3.ftb_entry.brValids.zip(resp.s3.preds.taken_mask).map{ case (b, t) => b && !t }.reduce(_||_),
false.B)
val s3_takenOnBr = resp.s3.real_br_taken_mask.asUInt =/= 0.U
val s3_predicted_ghist = s3_ghist.update(s3_sawNTBr, s3_takenOnBr)
val s3_shift = Mux(resp.s3.preds.hit,
Mux(resp.s3.real_br_taken_mask.asUInt === 0.U, PopCount(resp.s3.ftb_entry.brValids), PopCount(LowerMaskFromLowest(resp.s3.real_br_taken_mask.asUInt))),
0.U((log2Ceil(numBr)+1).W))
val s3_taken = Mux(resp.s3.preds.hit, resp.s3.real_br_taken_mask.asUInt =/= 0.U, false.B)
val s3_predicted_ghist = s3_ghist.update(s3_shift, s3_taken)
val s3_correct_s2_ghist = s2_ghist =/= s3_predicted_ghist
val s3_correct_s1_ghist = s1_ghist =/= s3_predicted_ghist
......@@ -400,12 +397,23 @@ class Predictor(implicit p: Parameters) extends XSModule with HasBPUConst {
when(io.ftq_to_bpu.redirect.valid) {
val oldGh = redirect.cfiUpdate.hist
val sawNTBr = redirect.cfiUpdate.br_hit
val shift = redirect.cfiUpdate.shift
val addIntoHist = redirect.cfiUpdate.addIntoHist
val isBr = redirect.cfiUpdate.pd.isBr
val taken = redirect.cfiUpdate.taken
val updatedGh = oldGh.update(sawNTBr || (isBr && taken), isBr && taken)
val updatedGh = oldGh.update(shift, taken && addIntoHist)
s0_ghist := updatedGh // TODO: History fix logic
s0_pc := redirect.cfiUpdate.target
XSDebug(io.ftq_to_bpu.redirect.valid, p"-------------redirect Repair------------\n")
// XSDebug(io.ftq_to_bpu.redirect.valid, p"taken_mask=${Binary(taken_mask.asUInt)}, brValids=${Binary(brValids.asUInt)}\n")
XSDebug(io.ftq_to_bpu.redirect.valid, p"isBr: ${isBr}, taken: ${taken}, addIntoHist: ${addIntoHist}, shift: ${shift}\n")
XSDebug(io.ftq_to_bpu.redirect.valid, p"oldGh =${Binary(oldGh.predHist)}\n")
XSDebug(io.ftq_to_bpu.redirect.valid, p"updateGh=${Binary(updatedGh.predHist)}\n")
}
s0_pc_reg := s0_pc
......
......@@ -64,6 +64,14 @@ class FTBEntry (implicit p: Parameters) extends XSBundle with FTBParams with BPU
case (v, off) => v && off <= offset
}.reduce(_||_)
def getBrMaskByOffset(offset: UInt) = (brValids zip brOffset).map{
case (v, off) => v && off <= offset
}
def brIsSaved(offset: UInt) = (brValids zip brOffset).map{
case (v, off) => v && off === offset
}.reduce(_||_)
def display(cond: Bool): Unit = {
XSDebug(cond, p"-----------FTB entry----------- \n")
XSDebug(cond, p"v=${valid}, tag=${Hexadecimal(tag)}\n")
......
......@@ -50,12 +50,25 @@ class FetchToIBuffer(implicit p: Parameters) extends XSBundle {
}
// Move from BPU
class GlobalHistory(implicit p: Parameters) extends XSBundle {
class GlobalHistory(implicit p: Parameters) extends XSBundle with HasBPUConst {
val predHist = UInt(HistoryLength.W)
def update(sawNTBr: Bool, takenOnBr: Bool, hist: UInt = predHist): GlobalHistory = {
// def update(sawNTBr: Bool, takenOnBr: Bool, hist: UInt = predHist): GlobalHistory = {
// val g = Wire(new GlobalHistory)
// val shifted = takenOnBr || sawNTBr
// g.predHist := Mux(shifted, (hist << 1) | takenOnBr.asUInt, hist)
// g
// }
// def update(brValids: UInt, taken_mask: UInt, hist: UInt = predHist): GlobalHistory = {
// val shift = PopCount(brValids & Mux(taken_mask =/= 0.U, LowerMask(taken_mask), ((1.U<<numBr) - 1.U)))
// val g = Wire(new GlobalHistory)
// g.predHist := (hist << shift) | (taken_mask =/= 0.U)
// g
// }
def update(shift: UInt, taken: Bool, hist: UInt = predHist): GlobalHistory = {
val g = Wire(new GlobalHistory)
val shifted = takenOnBr || sawNTBr
g.predHist := Mux(shifted, (hist << 1) | takenOnBr.asUInt, hist)
g.predHist := (hist << shift) | taken
g
}
......@@ -134,8 +147,8 @@ class BranchPredictionBundle(implicit p: Parameters) extends XSBundle with HasBP
VecInit(preds.taken_mask.zip(ftb_entry.brValids).map{ case(m, b) => m && b }),
VecInit(Seq.fill(numBr)(false.B)))
}
def hit_taken_on_call = !VecInit(real_taken_mask.take(numBr)).asUInt.orR && preds.hit && ftb_entry.isCall
def hit_taken_on_ret = !VecInit(real_taken_mask.take(numBr)).asUInt.orR && preds.hit && ftb_entry.isRet
def hit_taken_on_call = !VecInit(real_taken_mask.take(numBr)).asUInt.orR && preds.hit && ftb_entry.isCall && ftb_entry.jmpValid
def hit_taken_on_ret = !VecInit(real_taken_mask.take(numBr)).asUInt.orR && preds.hit && ftb_entry.isRet && ftb_entry.jmpValid
// override def toPrintable: Printable = {
// p"-----------BranchPredictionBundle----------- " +
......@@ -227,8 +240,12 @@ class BranchPredictionRedirect(implicit p: Parameters) extends Redirect with Has
XSDebug(cond, p"-----------BranchPredictionRedirect----------- \n")
XSDebug(cond, p"-----------cfiUpdate----------- \n")
XSDebug(cond, p"[pc] ${Hexadecimal(cfiUpdate.pc)}\n")
XSDebug(cond, p"[hist] ${Binary(cfiUpdate.hist.predHist)}\n")
XSDebug(cond, p"[predHist] ${Binary(cfiUpdate.predHist.predHist)}\n")
XSDebug(cond, p"[br_hit] ${cfiUpdate.br_hit} [isMisPred] ${cfiUpdate.isMisPred}\n")
XSDebug(cond, p"[pred_taken] ${cfiUpdate.predTaken} [taken] ${cfiUpdate.taken} [isMisPred] ${cfiUpdate.isMisPred}\n")
XSDebug(cond, p"[target] ${Hexadecimal(cfiUpdate.target)} \n")
XSDebug(cond, p"[shift] ${cfiUpdate.shift}\n")
XSDebug(cond, p"------------------------------- \n")
XSDebug(cond, p"[roqPtr] f=${roqIdx.flag} v=${roqIdx.value}\n")
XSDebug(cond, p"[ftqPtr] f=${ftqIdx.flag} v=${ftqIdx.value} \n")
......
......@@ -326,7 +326,7 @@ class FTBEntryGen(implicit p: Parameters) extends XSModule with HasBackendRedire
}
class Ftq(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHelper
with HasBackendRedirectInfo with BPUUtils {
with HasBackendRedirectInfo with BPUUtils with HasBPUConst{
val io = IO(new Bundle {
val fromBpu = Flipped(new BpuToFtqIO)
val fromIfu = Flipped(new IfuToFtqIO)
......@@ -583,6 +583,22 @@ class Ftq(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHelpe
backendRedirectCfi.hist := ftq_hist_mem.io.rdata.init.last
backendRedirectCfi.br_hit := ftb_entry_mem.io.rdata.init.last.hasBr(fromBackendRedirect.bits.ftqOffset) &&
entry_hit_status(fromBackendRedirect.bits.ftqIdx.value) === h_hit
val r_ftb_entry = ftb_entry_mem.io.rdata.init.last
val r_ftqOffset = fromBackendRedirect.bits.ftqOffset
when (entry_hit_status(fromBackendRedirect.bits.ftqIdx.value) === h_hit) {
backendRedirectCfi.shift := PopCount(r_ftb_entry.getBrMaskByOffset(r_ftqOffset)) +&
(backendRedirectCfi.pd.isBr && !r_ftb_entry.brIsSaved(r_ftqOffset) &&
!(r_ftb_entry.brValids(numBr-1) && r_ftqOffset > r_ftb_entry.brOffset(numBr-1)))
backendRedirectCfi.addIntoHist := backendRedirectCfi.pd.isBr && (r_ftb_entry.brIsSaved(r_ftqOffset) ||
!(r_ftb_entry.brValids(numBr-1) && r_ftqOffset > r_ftb_entry.brOffset(numBr-1)))
}.otherwise {
backendRedirectCfi.shift := backendRedirectCfi.pd.isBr.asUInt
backendRedirectCfi.addIntoHist := backendRedirectCfi.pd.isBr.asUInt
}
backendRedirectCfi.rasSp := stage3CfiInfo.rasSp
backendRedirectCfi.rasEntry := stage3CfiInfo.rasEntry
backendRedirectCfi.specCnt := stage3CfiInfo.specCnt
......@@ -812,7 +828,12 @@ class Ftq(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHelpe
val misPred = commit_mispredict(i)
val ghist = commit_ghist.predHist
val predCycle = commit_meta.meta(63, 0)
XSDebug(v && do_commit && isCfi, p"cfi_update: isBr(${!isJmp}) pc(${Hexadecimal(pc)}) taken(${isTaken}) mispred(${misPred}) cycle($predCycle) hist(${Hexadecimal(ghist)}) startAddr(${Hexadecimal(commit_pc_bundle.startAddr)})\n")
val inFtbEntry = update_ftb_entry.brValids.zip(update_ftb_entry.brOffset).map{case(v, offset) => v && offset === i.U}.reduce(_||_)
val addIntoHist = ((commit_hit === h_hit) && inFtbEntry) || ((!(commit_hit === h_hit) && i.U === commit_cfi.bits && isBr && commit_cfi.valid))
XSDebug(v && do_commit && isCfi, p"cfi_update: isBr(${isBr}) pc(${Hexadecimal(pc)}) " +
p"taken(${isTaken}) mispred(${misPred}) cycle($predCycle) hist(${Hexadecimal(ghist)}) " +
p"startAddr(${Hexadecimal(commit_pc_bundle.startAddr)}) AddIntoHist(${addIntoHist})\n")
}
}
......
......@@ -175,6 +175,7 @@ class TageTable
val (s1_idx, s1_tag) = compute_tag_and_hash(s1_unhashed_idx, io.req.bits.hist)
val (s2_idx, s2_tag) = (RegEnable(s1_idx, io.req.valid), RegEnable(s1_tag, io.req.valid))
// TODO: hi_us lo_us use DataModule
val hi_us = Module(new SRAMTemplate(Bool(), set=nRows, way=TageBanks, shouldReset=true, holdRead=true, singlePort=false))
val lo_us = Module(new SRAMTemplate(Bool(), set=nRows, way=TageBanks, shouldReset=true, holdRead=true, singlePort=false))
val table = Module(new SRAMTemplate(new TageEntry, set=nRows, way=TageBanks, shouldReset=true, holdRead=true, singlePort=false))
......
......@@ -237,6 +237,7 @@ class MicroBTB(implicit p: Parameters) extends BasePredictor
// io.out.bits.resp.s1.preds.is_ret := read_resps.jmpValid && read_resps.isRet
// io.out.bits.resp.s1.preds.call_is_rvc := read_resps.last_is_rvc
io.out.resp.s1.ftb_entry := DontCare
io.out.resp.s1.ftb_entry.valid := read_resps.valid
io.out.resp.s1.ftb_entry.brValids := read_resps.brValids
io.out.s3_meta := RegEnable(RegEnable(read_resps.asUInt, io.s1_fire), io.s2_fire)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册