未验证 提交 fd7be884 编写于 作者: S Steve Gou 提交者: GitHub

Merge pull request #334 from RISCVERS/replay-br-update

recover speculatively updated stuff at replay redirect
......@@ -24,7 +24,7 @@ class FetchPacket extends XSBundle {
// val pc = UInt(VAddrBits.W)
val pc = Vec(PredictWidth, UInt(VAddrBits.W))
val pnpc = Vec(PredictWidth, UInt(VAddrBits.W))
val brInfo = Vec(PredictWidth, new BranchInfo)
val bpuMeta = Vec(PredictWidth, new BpuMeta)
val pd = Vec(PredictWidth, new PreDecodeInfo)
val ipf = Bool()
val acf = Bool()
......@@ -116,7 +116,7 @@ class BranchPrediction extends XSBundle with HasIFUConst {
def hasNotTakenBrs = Mux(taken, ParallelPriorityMux(realTakens, sawNotTakenBr), ParallelORR(brNotTakens))
}
class BranchInfo extends XSBundle with HasBPUParameter {
class BpuMeta extends XSBundle with HasBPUParameter {
val ubtbWriteWay = UInt(log2Up(UBtbWays).W)
val ubtbHits = Bool()
val btbWriteWay = UInt(log2Up(BtbWays).W)
......@@ -155,20 +155,22 @@ class Predecode extends XSBundle with HasIFUConst {
val pd = Vec(FetchWidth*2, (new PreDecodeInfo))
}
class BranchUpdateInfo extends XSBundle {
class CfiUpdateInfo extends XSBundle {
// from backend
val pc = UInt(VAddrBits.W)
val pnpc = UInt(VAddrBits.W)
val fetchIdx = UInt(log2Up(FetchWidth*2).W)
// frontend -> backend -> frontend
val pd = new PreDecodeInfo
val bpuMeta = new BpuMeta
// need pipeline update
val target = UInt(VAddrBits.W)
val brTarget = UInt(VAddrBits.W)
val taken = Bool()
val fetchIdx = UInt(log2Up(FetchWidth*2).W)
val isMisPred = Bool()
val brTag = new BrqPtr
// frontend -> backend -> frontend
val pd = new PreDecodeInfo
val brInfo = new BranchInfo
val isReplay = Bool()
}
// Dequeue DecodeWidth insts from Ibuffer
......@@ -177,7 +179,7 @@ class CtrlFlow extends XSBundle {
val pc = UInt(VAddrBits.W)
val exceptionVec = Vec(16, Bool())
val intrVec = Vec(12, Bool())
val brUpdate = new BranchUpdateInfo
val brUpdate = new CfiUpdateInfo
val crossPageIPFFix = Bool()
}
......@@ -274,7 +276,7 @@ class ExuOutput extends XSBundle {
val fflags = new Fflags
val redirectValid = Bool()
val redirect = new Redirect
val brUpdate = new BranchUpdateInfo
val brUpdate = new CfiUpdateInfo
val debug = new DebugBundle
}
......@@ -321,8 +323,8 @@ class FrontendToBackendIO extends XSBundle {
val cfVec = Vec(DecodeWidth, DecoupledIO(new CtrlFlow))
// from backend
val redirect = Flipped(ValidIO(UInt(VAddrBits.W)))
val outOfOrderBrInfo = Flipped(ValidIO(new BranchUpdateInfo))
val inOrderBrInfo = Flipped(ValidIO(new BranchUpdateInfo))
// val cfiUpdateInfo = Flipped(ValidIO(new CfiUpdateInfo))
val cfiUpdateInfo = Flipped(ValidIO(new CfiUpdateInfo))
}
class TlbCsrBundle extends XSBundle {
......
......@@ -78,10 +78,10 @@ class CtrlBlock extends XSModule with HasCircularQueuePtrHelper {
val redirectValid = roq.io.redirect.valid || brq.io.redirect.valid || io.fromLsBlock.replay.valid
val redirect = Mux(roq.io.redirect.valid, roq.io.redirect.bits, redirectArb)
io.frontend.redirect.valid := redirectValid
io.frontend.redirect.bits := Mux(roq.io.redirect.valid, roq.io.redirect.bits.target, redirectArb.target)
io.frontend.outOfOrderBrInfo <> brq.io.outOfOrderBrInfo
io.frontend.inOrderBrInfo <> brq.io.inOrderBrInfo
io.frontend.redirect.valid := RegNext(redirectValid)
io.frontend.redirect.bits := RegNext(Mux(roq.io.redirect.valid, roq.io.redirect.bits.target, redirectArb.target))
// io.frontend.cfiUpdateInfo <> brq.io.cfiInfo
io.frontend.cfiUpdateInfo <> brq.io.cfiInfo
decode.io.in <> io.frontend.cfVec
decode.io.toBrq <> brq.io.enqReqs
......@@ -95,8 +95,9 @@ class CtrlBlock extends XSModule with HasCircularQueuePtrHelper {
brq.io.exuRedirect <> io.fromIntBlock.exuRedirect
// pipeline between decode and dispatch
val lastCycleRedirect = RegNext(redirectValid)
for (i <- 0 until RenameWidth) {
PipelineConnect(decode.io.out(i), rename.io.in(i), rename.io.in(i).ready, redirectValid)
PipelineConnect(decode.io.out(i), rename.io.in(i), rename.io.in(i).ready, redirectValid || lastCycleRedirect)
}
rename.io.redirect.valid <> redirectValid
......
......@@ -51,11 +51,9 @@ class BrqIO extends XSBundle{
val out = ValidIO(new ExuOutput)
// misprediction, flush pipeline
val redirect = Output(Valid(new Redirect))
val outOfOrderBrInfo = ValidIO(new BranchUpdateInfo)
val cfiInfo = ValidIO(new CfiUpdateInfo)
// commit cnt of branch instr
val bcommit = Input(UInt(BrTagWidth.W))
// in order dequeue to train bpd
val inOrderBrInfo = ValidIO(new BranchUpdateInfo)
}
class Brq extends XSModule with HasCircularQueuePtrHelper {
......@@ -63,7 +61,6 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
class BrqEntry extends Bundle {
val ptrFlag = Bool()
val npc = UInt(VAddrBits.W)
val exuOut = new ExuOutput
}
......@@ -117,15 +114,13 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
val deqValid = stateQueue(headIdx).isCommit && brCommitCnt=/=0.U
val commitValid = stateQueue(commitIdx).isWb
val commitEntry = brQueue(commitIdx)
val commitIsMisPred = commitEntry.exuOut.redirect.isMisPred
val commitIsMisPred = commitEntry.exuOut.brUpdate.isMisPred
brCommitCnt := brCommitCnt + io.bcommit - deqValid
XSDebug(p"brCommitCnt:$brCommitCnt\n")
assert(brCommitCnt+io.bcommit >= deqValid)
io.inOrderBrInfo.valid := commitValid
io.inOrderBrInfo.bits := commitEntry.exuOut.brUpdate
XSDebug(io.inOrderBrInfo.valid, "inOrderValid: pc=%x\n", io.inOrderBrInfo.bits.pc)
XSDebug(io.cfiInfo.valid, "inOrderValid: pc=%x\n", io.cfiInfo.bits.pc)
XSDebug(p"headIdx:$headIdx commitIdx:$commitIdx\n")
XSDebug(p"headPtr:$headPtr tailPtr:$tailPtr\n")
......@@ -149,20 +144,19 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
assert(!(commitIdx===headIdx && commitValid && deqValid), "Error: deq and commit a same entry!")
headPtr := headPtrNext
io.redirect.valid := commitValid &&
commitIsMisPred //&&
// !io.roqRedirect.valid &&
// !io.redirect.bits.roqIdx.needFlush(io.memRedirect)
io.redirect.valid := commitValid && commitIsMisPred
io.redirect.bits := commitEntry.exuOut.redirect
io.redirect.bits.brTag := BrqPtr(commitEntry.ptrFlag, commitIdx)
io.out.valid := commitValid
io.out.bits := commitEntry.exuOut
io.outOfOrderBrInfo.valid := commitValid
io.outOfOrderBrInfo.bits := commitEntry.exuOut.brUpdate
when (io.redirect.valid) {
commitEntry.npc := io.redirect.bits.target
}
val brTagRead = RegNext(Mux(io.memRedirect.bits.isReplay, io.memRedirect.bits.brTag - 1.U, io.memRedirect.bits.brTag))
io.cfiInfo.valid := RegNext(io.memRedirect.valid || commitValid)
io.cfiInfo.bits := brQueue(brTagRead.value).exuOut.brUpdate
io.cfiInfo.bits.brTag := brTagRead
io.cfiInfo.bits.isReplay := RegNext(io.memRedirect.bits.isReplay)
XSInfo(io.out.valid,
p"commit branch to roq, mispred:${io.redirect.valid} pc=${Hexadecimal(io.out.bits.uop.cf.pc)}\n"
......@@ -176,9 +170,13 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
val idx = brTag.value
io.enqReqs(i).ready := validEntries <= (BrqSize - (i + 1)).U
io.brTags(i) := brTag
when(io.enqReqs(i).fire()){
brQueue(idx).npc := io.enqReqs(i).bits.cf.brUpdate.pnpc
when (io.enqReqs(i).fire()) {
brQueue(idx).ptrFlag := brTag.flag
brQueue(idx).exuOut.brUpdate.pc := io.enqReqs(i).bits.cf.brUpdate.pc
brQueue(idx).exuOut.brUpdate.pnpc := io.enqReqs(i).bits.cf.brUpdate.pnpc
brQueue(idx).exuOut.brUpdate.fetchIdx := io.enqReqs(i).bits.cf.brUpdate.fetchIdx
brQueue(idx).exuOut.brUpdate.pd := io.enqReqs(i).bits.cf.brUpdate.pd
brQueue(idx).exuOut.brUpdate.bpuMeta := io.enqReqs(i).bits.cf.brUpdate.bpuMeta
stateQueue(idx) := s_idle
}
}
......@@ -187,20 +185,29 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
// exu write back
for(exuWb <- io.exuRedirect){
when(exuWb.valid){
when (exuWb.valid) {
val wbIdx = exuWb.bits.redirect.brTag.value
XSInfo(
p"exu write back: brTag:${exuWb.bits.redirect.brTag}" +
p" pc=${Hexadecimal(exuWb.bits.uop.cf.pc)} pnpc=${Hexadecimal(brQueue(wbIdx).npc)} target=${Hexadecimal(exuWb.bits.redirect.target)}\n"
p" pc=${Hexadecimal(exuWb.bits.uop.cf.pc)} " +
p"pnpc=${Hexadecimal(brQueue(wbIdx).exuOut.brUpdate.pnpc)} " +
p"target=${Hexadecimal(exuWb.bits.redirect.target)}\n"
)
when(stateQueue(wbIdx).isIdle){
when (stateQueue(wbIdx).isIdle) {
stateQueue(wbIdx) := s_wb
}
val exuOut = WireInit(exuWb.bits)
val isMisPred = brQueue(wbIdx).npc =/= exuWb.bits.redirect.target
exuOut.redirect.isMisPred := isMisPred
exuOut.brUpdate.isMisPred := isMisPred
brQueue(wbIdx).exuOut := exuOut
val isMisPred = brQueue(wbIdx).exuOut.brUpdate.pnpc =/= exuWb.bits.redirect.target
// only writeback necessary information
brQueue(wbIdx).exuOut.uop := exuWb.bits.uop
brQueue(wbIdx).exuOut.data := exuWb.bits.data
brQueue(wbIdx).exuOut.fflags := exuWb.bits.fflags
brQueue(wbIdx).exuOut.redirectValid := exuWb.bits.redirectValid
brQueue(wbIdx).exuOut.redirect := exuWb.bits.redirect
brQueue(wbIdx).exuOut.debug := exuWb.bits.debug
brQueue(wbIdx).exuOut.brUpdate.target := exuWb.bits.brUpdate.target
brQueue(wbIdx).exuOut.brUpdate.brTarget := exuWb.bits.brUpdate.brTarget
brQueue(wbIdx).exuOut.brUpdate.taken := exuWb.bits.brUpdate.taken
brQueue(wbIdx).exuOut.brUpdate.isMisPred := isMisPred
}
}
......
......@@ -11,7 +11,7 @@ import xiangshan.backend.decode.isa._
trait HasRedirectOut { this: RawModule =>
val redirectOutValid = IO(Output(Bool()))
val redirectOut = IO(Output(new Redirect))
val brUpdate = IO(Output(new BranchUpdateInfo))
val brUpdate = IO(Output(new CfiUpdateInfo))
}
class Jump extends FunctionUnit with HasRedirectOut {
......@@ -44,7 +44,7 @@ class Jump extends FunctionUnit with HasRedirectOut {
brUpdate := uop.cf.brUpdate
brUpdate.pc := uop.cf.pc
brUpdate.target := target
brUpdate.brTarget := target // DontCare
brUpdate.brTarget := target
brUpdate.taken := true.B
// Output
......
......@@ -115,7 +115,7 @@ abstract class BasePredictor extends XSModule
val pc = Flipped(ValidIO(UInt(VAddrBits.W)))
val hist = Input(UInt(HistoryLength.W))
val inMask = Input(UInt(PredictWidth.W))
val update = Flipped(ValidIO(new BranchUpdateInfoWithHist))
val update = Flipped(ValidIO(new CfiUpdateInfo))
val outFire = Input(Bool())
}
......@@ -129,7 +129,7 @@ class BPUStageIO extends XSBundle {
val mask = UInt(PredictWidth.W)
val resp = new PredictorResponse
// val target = UInt(VAddrBits.W)
val brInfo = Vec(PredictWidth, new BranchInfo)
val brInfo = Vec(PredictWidth, new BpuMeta)
// val saveHalfRVI = Bool()
}
......@@ -251,7 +251,7 @@ class BPUStage3 extends BPUStage {
val predecode = Input(new Predecode)
val realMask = Input(UInt(PredictWidth.W))
val prevHalf = Input(new PrevHalfInstr)
val recover = Flipped(ValidIO(new BranchUpdateInfo))
val recover = Flipped(ValidIO(new CfiUpdateInfo))
}
val s3IO = IO(new S3IO)
// TAGE has its own pipelines and the
......@@ -315,9 +315,9 @@ class BPUStage3 extends BPUStage {
ras.io.recover := s3IO.recover
for(i <- 0 until PredictWidth){
io.out.brInfo(i).rasSp := ras.io.branchInfo.rasSp
io.out.brInfo(i).rasTopCtr := ras.io.branchInfo.rasTopCtr
io.out.brInfo(i).rasToqAddr := ras.io.branchInfo.rasToqAddr
io.out.brInfo(i).rasSp := ras.io.meta.rasSp
io.out.brInfo(i).rasTopCtr := ras.io.meta.rasTopCtr
io.out.brInfo(i).rasToqAddr := ras.io.meta.rasToqAddr
}
takens := VecInit((0 until PredictWidth).map(i => {
((brTakens(i) || jalrs(i)) && btbHits(i)) ||
......@@ -401,25 +401,25 @@ class BPUReq extends XSBundle {
// val histPtr = UInt(log2Up(ExtHistoryLength).W) // only for debug
}
class BranchUpdateInfoWithHist extends XSBundle {
val ui = new BranchUpdateInfo
val hist = UInt(HistoryLength.W)
}
// class CfiUpdateInfoWithHist extends XSBundle {
// val ui = new CfiUpdateInfo
// val hist = UInt(HistoryLength.W)
// }
object BranchUpdateInfoWithHist {
def apply (brInfo: BranchUpdateInfo, hist: UInt) = {
val b = Wire(new BranchUpdateInfoWithHist)
b.ui <> brInfo
b.hist := hist
b
}
}
// object CfiUpdateInfoWithHist {
// def apply (brInfo: CfiUpdateInfo, hist: UInt) = {
// val b = Wire(new CfiUpdateInfoWithHist)
// b.ui <> brInfo
// b.hist := hist
// b
// }
// }
abstract class BaseBPU extends XSModule with BranchPredictorComponents with HasBPUParameter{
val io = IO(new Bundle() {
// from backend
val inOrderBrInfo = Flipped(ValidIO(new BranchUpdateInfoWithHist))
val outOfOrderBrInfo = Flipped(ValidIO(new BranchUpdateInfoWithHist))
val cfiUpdateInfo = Flipped(ValidIO(new CfiUpdateInfo))
// val cfiUpdateInfo = Flipped(ValidIO(new CfiUpdateInfoWithHist))
// from ifu, frontend redirect
val flush = Input(Vec(3, Bool()))
// from if1
......@@ -432,13 +432,13 @@ abstract class BaseBPU extends XSModule with BranchPredictorComponents with HasB
val realMask = Input(UInt(PredictWidth.W))
val prevHalf = Input(new PrevHalfInstr)
// to if4, some bpu info used for updating
val branchInfo = Output(Vec(PredictWidth, new BranchInfo))
val bpuMeta = Output(Vec(PredictWidth, new BpuMeta))
})
def npc(pc: UInt, instCount: UInt) = pc + (instCount << 1.U)
preds.map(_.io.update <> io.outOfOrderBrInfo)
tage.io.update <> io.inOrderBrInfo
preds.map(_.io.update <> io.cfiUpdateInfo)
// tage.io.update <> io.cfiUpdateInfo
val s1 = Module(new BPUStage1)
val s2 = Module(new BPUStage2)
......@@ -469,12 +469,12 @@ abstract class BaseBPU extends XSModule with BranchPredictorComponents with HasB
io.out(1) <> s2.io.pred
io.out(2) <> s3.io.pred
io.branchInfo := s3.io.out.brInfo
io.bpuMeta := s3.io.out.brInfo
if (BPUDebug) {
XSDebug(io.inFire(3), "branchInfo sent!\n")
XSDebug(io.inFire(3), "bpuMeta sent!\n")
for (i <- 0 until PredictWidth) {
val b = io.branchInfo(i)
val b = io.bpuMeta(i)
XSDebug(io.inFire(3), "brInfo(%d): ubtbWrWay:%d, ubtbHit:%d, btbWrWay:%d, btbHitJal:%d, bimCtr:%d, fetchIdx:%d\n",
i.U, b.ubtbWriteWay, b.ubtbHits, b.btbWriteWay, b.btbHitJal, b.bimCtr, b.fetchIdx)
val t = b.tageMeta
......@@ -492,7 +492,7 @@ class FakeBPU extends BaseBPU {
i <> DontCare
i.takens := 0.U
})
io.branchInfo <> DontCare
io.bpuMeta <> DontCare
}
@chiselName
class BPU extends BaseBPU {
......@@ -500,7 +500,7 @@ class BPU extends BaseBPU {
//**********************Stage 1****************************//
val s1_resp_in = Wire(new PredictorResponse)
val s1_brInfo_in = Wire(Vec(PredictWidth, new BranchInfo))
val s1_brInfo_in = Wire(Vec(PredictWidth, new BpuMeta))
s1_resp_in.tage := DontCare
s1_resp_in.loop := DontCare
......@@ -518,8 +518,8 @@ class BPU extends BaseBPU {
// Wrap ubtb response into resp_in and brInfo_in
s1_resp_in.ubtb <> ubtb.io.out
for (i <- 0 until PredictWidth) {
s1_brInfo_in(i).ubtbWriteWay := ubtb.io.uBTBBranchInfo.writeWay(i)
s1_brInfo_in(i).ubtbHits := ubtb.io.uBTBBranchInfo.hits(i)
s1_brInfo_in(i).ubtbWriteWay := ubtb.io.uBTBMeta.writeWay(i)
s1_brInfo_in(i).ubtbHits := ubtb.io.uBTBMeta.hits(i)
}
btb.io.flush := io.flush(0) // TODO: fix this
......@@ -598,8 +598,8 @@ class BPU extends BaseBPU {
s3.s3IO.prevHalf := io.prevHalf
s3.s3IO.recover.valid <> io.inOrderBrInfo.valid
s3.s3IO.recover.bits <> io.inOrderBrInfo.bits.ui
s3.s3IO.recover.valid <> io.cfiUpdateInfo.valid
s3.s3IO.recover.bits <> io.cfiUpdateInfo.bits
if (BPUDebug) {
if (debug_verbose) {
......@@ -615,11 +615,11 @@ class BPU extends BaseBPU {
if (EnableCFICommitLog) {
val buValid = io.inOrderBrInfo.valid
val buinfo = io.inOrderBrInfo.bits.ui
val buValid = io.cfiUpdateInfo.valid
val buinfo = io.cfiUpdateInfo.bits
val pd = buinfo.pd
val tage_cycle = buinfo.brInfo.debug_tage_cycle
XSDebug(buValid, p"cfi_update: isBr(${pd.isBr}) pc(${Hexadecimal(buinfo.pc)}) taken(${buinfo.taken}) mispred(${buinfo.isMisPred}) cycle($tage_cycle) hist(${Hexadecimal(io.inOrderBrInfo.bits.hist)})\n")
val tage_cycle = buinfo.bpuMeta.debug_tage_cycle
XSDebug(buValid, p"cfi_update: isBr(${pd.isBr}) pc(${Hexadecimal(buinfo.pc)}) taken(${buinfo.taken}) mispred(${buinfo.isMisPred}) cycle($tage_cycle) hist(${Hexadecimal(buinfo.bpuMeta.predHist.asUInt)})\n")
}
}
......
......@@ -80,7 +80,7 @@ class BIM extends BasePredictor with BimParams {
io.meta.ctrs(b) := ctr
}
val u = io.update.bits.ui
val u = io.update.bits
val updateBank = bimAddr.getBank(u.pc)
val updateRow = bimAddr.getBankIdx(u.pc)
......@@ -96,12 +96,12 @@ class BIM extends BasePredictor with BimParams {
val wrbypass_hit = wrbypass_hits.reduce(_||_)
val wrbypass_hit_idx = PriorityEncoder(wrbypass_hits)
val oldCtr = Mux(wrbypass_hit && wrbypass_ctr_valids(wrbypass_hit_idx)(updateBank), wrbypass_ctrs(wrbypass_hit_idx)(updateBank), u.brInfo.bimCtr)
val oldCtr = Mux(wrbypass_hit && wrbypass_ctr_valids(wrbypass_hit_idx)(updateBank), wrbypass_ctrs(wrbypass_hit_idx)(updateBank), u.bpuMeta.bimCtr)
val newTaken = u.taken
val newCtr = satUpdate(oldCtr, 2, newTaken)
// val oldSaturated = newCtr === oldCtr
val needToUpdate = io.update.valid && u.pd.isBr
val needToUpdate = io.update.valid && u.pd.isBr && !u.isReplay
when (reset.asBool) { wrbypass_ctr_valids.foreach(_.foreach(_ := false.B))}
......@@ -126,9 +126,9 @@ class BIM extends BasePredictor with BimParams {
if (BPUDebug && debug) {
XSDebug(doing_reset, "Reseting...\n")
XSDebug("[update] v=%d pc=%x pnpc=%x tgt=%x brTgt=%x\n", io.update.valid, u.pc, u.pnpc, u.target, u.brTarget)
XSDebug("[update] v=%d pc=%x pnpc=%x tgt=%x", io.update.valid, u.pc, u.pnpc, u.target)
XSDebug("[update] taken=%d isMisPred=%d", u.taken, u.isMisPred)
XSDebug(false, true.B, p"brTag=${u.brTag} pd.isBr=${u.pd.isBr} brInfo.bimCtr=${Binary(u.brInfo.bimCtr)}\n")
XSDebug(false, true.B, p"brTag=${u.brTag} pd.isBr=${u.pd.isBr} brInfo.bimCtr=${Binary(u.bpuMeta.bimCtr)}\n")
XSDebug("needToUpdate=%d updateBank=%x updateRow=%x newCtr=%b oldCtr=%b\n", needToUpdate, updateBank, updateRow, newCtr, oldCtr)
XSDebug("[wrbypass] hit=%d hits=%b\n", wrbypass_hit, wrbypass_hits.asUInt)
}
......
......@@ -27,8 +27,8 @@ class Frontend extends XSModule {
//backend
ifu.io.redirect <> io.backend.redirect
ifu.io.inOrderBrInfo <> io.backend.inOrderBrInfo
ifu.io.outOfOrderBrInfo <> io.backend.outOfOrderBrInfo
ifu.io.cfiUpdateInfo <> io.backend.cfiUpdateInfo
// ifu.io.cfiUpdateInfo <> io.backend.cfiUpdateInfo
//icache
ifu.io.icacheResp <> icache.io.resp
icache.io.req <> ifu.io.icacheReq
......
......@@ -70,8 +70,8 @@ class IFUIO extends XSBundle
{
val fetchPacket = DecoupledIO(new FetchPacket)
val redirect = Flipped(ValidIO(UInt(VAddrBits.W)))
val outOfOrderBrInfo = Flipped(ValidIO(new BranchUpdateInfo))
val inOrderBrInfo = Flipped(ValidIO(new BranchUpdateInfo))
// val cfiUpdateInfo = Flipped(ValidIO(new CfiUpdateInfo))
val cfiUpdateInfo = Flipped(ValidIO(new CfiUpdateInfo))
val icacheReq = DecoupledIO(new ICacheReq)
val icacheResp = Flipped(DecoupledIO(new ICacheResp))
val icacheFlush = Output(UInt(2.W))
......@@ -355,11 +355,11 @@ class IFU extends XSModule with HasIFUConst
when (io.outOfOrderBrInfo.valid && io.outOfOrderBrInfo.bits.isMisPred) {
val b = io.outOfOrderBrInfo.bits
val oldGh = b.brInfo.hist
val sawNTBr = b.brInfo.sawNotTakenBranch
val cfiUpdate = io.cfiUpdateInfo
when (cfiUpdate.valid && (cfiUpdate.bits.isMisPred || cfiUpdate.bits.isReplay)) {
val b = cfiUpdate.bits
val oldGh = b.bpuMeta.hist
val sawNTBr = b.bpuMeta.sawNotTakenBranch
val isBr = b.pd.isBr
val taken = b.taken
val updatedGh = oldGh.update(sawNTBr, isBr && taken)
......@@ -398,11 +398,7 @@ class IFU extends XSModule with HasIFUConst
io.icacheFlush := Cat(if3_flush, if2_flush)
val inOrderBrHist = io.inOrderBrInfo.bits.brInfo.predHist
bpu.io.inOrderBrInfo.valid := io.inOrderBrInfo.valid
bpu.io.inOrderBrInfo.bits := BranchUpdateInfoWithHist(io.inOrderBrInfo.bits, inOrderBrHist.asUInt)
bpu.io.outOfOrderBrInfo.valid := io.outOfOrderBrInfo.valid
bpu.io.outOfOrderBrInfo.bits := BranchUpdateInfoWithHist(io.outOfOrderBrInfo.bits, inOrderBrHist.asUInt) // Dont care about hist
bpu.io.cfiUpdateInfo <> io.cfiUpdateInfo
// bpu.io.flush := Cat(if4_flush, if3_flush, if2_flush)
bpu.io.flush := VecInit(if2_flush, if3_flush, if4_flush)
......@@ -465,9 +461,9 @@ class IFU extends XSModule with HasIFUConst
when (if4_bp.taken) {
fetchPacketWire.pnpc(if4_bp.jmpIdx) := if4_bp.target
}
fetchPacketWire.brInfo := bpu.io.branchInfo
(0 until PredictWidth).foreach(i => fetchPacketWire.brInfo(i).hist := final_gh)
(0 until PredictWidth).foreach(i => fetchPacketWire.brInfo(i).predHist := if4_predHist.asTypeOf(new GlobalHistory))
fetchPacketWire.bpuMeta := bpu.io.bpuMeta
(0 until PredictWidth).foreach(i => fetchPacketWire.bpuMeta(i).hist := final_gh)
(0 until PredictWidth).foreach(i => fetchPacketWire.bpuMeta(i).predHist := if4_predHist.asTypeOf(new GlobalHistory))
fetchPacketWire.pd := if4_pd.pd
fetchPacketWire.ipf := if4_ipf
fetchPacketWire.acf := if4_acf
......
......@@ -20,7 +20,7 @@ class Ibuffer extends XSModule {
val inst = UInt(32.W)
val pc = UInt(VAddrBits.W)
val pnpc = UInt(VAddrBits.W)
val brInfo = new BranchInfo
val brInfo = new BpuMeta
val pd = new PreDecodeInfo
val ipf = Bool()
val acf = Bool()
......@@ -63,7 +63,7 @@ class Ibuffer extends XSModule {
inWire.inst := io.in.bits.instrs(i)
inWire.pc := io.in.bits.pc(i)
inWire.pnpc := io.in.bits.pnpc(i)
inWire.brInfo := io.in.bits.brInfo(i)
inWire.brInfo := io.in.bits.bpuMeta(i)
inWire.pd := io.in.bits.pd(i)
inWire.ipf := io.in.bits.ipf
inWire.acf := io.in.bits.acf
......@@ -98,7 +98,7 @@ class Ibuffer extends XSModule {
io.out(i).bits.brUpdate.pc := outWire.pc
io.out(i).bits.brUpdate.pnpc := outWire.pnpc
io.out(i).bits.brUpdate.pd := outWire.pd
io.out(i).bits.brUpdate.brInfo := outWire.brInfo
io.out(i).bits.brUpdate.bpuMeta := outWire.brInfo
io.out(i).bits.crossPageIPFFix := outWire.crossPageIPFFix
}
head_ptr := head_ptr + io.out.map(_.fire).fold(0.U(log2Up(DecodeWidth).W))(_+_)
......
......@@ -309,13 +309,13 @@ class LoopPredictor extends BasePredictor with LTBParams {
ltbs(i).io.req.idx := Mux(isInNextRow(i), baseRow + 1.U, baseRow)
ltbs(i).io.req.tag := realTags(i)
// ltbs(i).io.outMask := outMask(i)
ltbs(i).io.update.valid := i.U === ltbAddr.getBank(io.update.bits.ui.pc) && io.update.valid && io.update.bits.ui.pd.isBr
ltbs(i).io.update.bits.misPred := io.update.bits.ui.isMisPred
ltbs(i).io.update.bits.pc := io.update.bits.ui.pc
ltbs(i).io.update.bits.meta := io.update.bits.ui.brInfo.specCnt
ltbs(i).io.update.bits.taken := io.update.bits.ui.taken
ltbs(i).io.update.bits.brTag := io.update.bits.ui.brTag
ltbs(i).io.repair := i.U =/= ltbAddr.getBank(io.update.bits.ui.pc) && io.update.valid && io.update.bits.ui.isMisPred
ltbs(i).io.update.valid := i.U === ltbAddr.getBank(io.update.bits.pc) && io.update.valid && io.update.bits.pd.isBr
ltbs(i).io.update.bits.misPred := io.update.bits.isMisPred
ltbs(i).io.update.bits.pc := io.update.bits.pc
ltbs(i).io.update.bits.meta := io.update.bits.bpuMeta.specCnt
ltbs(i).io.update.bits.taken := io.update.bits.taken
ltbs(i).io.update.bits.brTag := io.update.bits.brTag
ltbs(i).io.repair := i.U =/= ltbAddr.getBank(io.update.bits.pc) && io.update.valid && io.update.bits.isMisPred
}
val ltbResps = VecInit((0 until PredictWidth).map(i => ltbs(i).io.resp))
......
......@@ -28,9 +28,9 @@ class RAS extends BasePredictor
val callIdx = Flipped(ValidIO(UInt(log2Ceil(PredictWidth).W)))
val isRVC = Input(Bool())
val isLastHalfRVI = Input(Bool())
val recover = Flipped(ValidIO(new BranchUpdateInfo))
val recover = Flipped(ValidIO(new CfiUpdateInfo))
val out = ValidIO(new RASResp)
val branchInfo = Output(new RASBranchInfo)
val meta = Output(new RASBranchInfo)
}
class RASEntry() extends XSBundle {
......@@ -187,7 +187,7 @@ class RAS extends BasePredictor
// TODO: back-up stack for ras
// use checkpoint to recover RAS
val copy_valid = io.recover.valid && io.recover.bits.isMisPred
val copy_valid = io.recover.valid && (io.recover.bits.isMisPred || io.recover.bits.isReplay)
val copy_next = RegNext(copy_valid)
spec_ras.copy_valid := copy_next
spec_ras.copy_in_mem := commit_ras.copy_out_mem
......@@ -197,9 +197,9 @@ class RAS extends BasePredictor
commit_ras.copy_in_sp := DontCare
//no need to pass the ras branchInfo
io.branchInfo.rasSp := DontCare
io.branchInfo.rasTopCtr := DontCare
io.branchInfo.rasToqAddr := DontCare
io.meta.rasSp := DontCare
io.meta.rasTopCtr := DontCare
io.meta.rasToqAddr := DontCare
if (BPUDebug && debug) {
val spec_debug = spec.debugIO
......
......@@ -448,12 +448,12 @@ class Tage extends BaseTage {
val debug_hist_s2 = RegEnable(io.hist, enable=io.pc.valid)
val debug_hist_s3 = RegEnable(debug_hist_s2, enable=io.s3Fire)
val u = io.update.bits.ui
val updateValid = io.update.valid
val updateHist = io.update.bits.hist
val u = io.update.bits
val updateValid = io.update.valid && !io.update.bits.isReplay
val updateHist = u.bpuMeta.predHist.asUInt
val updateIsBr = u.pd.isBr
val updateMeta = u.brInfo.tageMeta
val updateMeta = u.bpuMeta.tageMeta
val updateMisPred = u.isMisPred && updateIsBr
val updateMask = WireInit(0.U.asTypeOf(Vec(TageNTables, Vec(TageBanks, Bool()))))
......@@ -475,7 +475,7 @@ class Tage extends BaseTage {
scUpdateTaken := DontCare
scUpdateOldCtrs := DontCare
val updateSCMeta = u.brInfo.tageMeta.scMeta
val updateSCMeta = u.bpuMeta.tageMeta.scMeta
val updateTageMisPred = updateMeta.taken =/= u.taken && updateIsBr
val updateBank = u.pc(log2Ceil(TageBanks), 1)
......@@ -641,7 +641,7 @@ class Tage extends BaseTage {
// use fetch pc instead of instruction pc
tables(i).io.update.pc := u.pc
tables(i).io.update.hist := updateHist
tables(i).io.update.fetchIdx := u.brInfo.fetchIdx
tables(i).io.update.fetchIdx := u.bpuMeta.fetchIdx
}
for (i <- 0 until SCNTables) {
......@@ -651,14 +651,14 @@ class Tage extends BaseTage {
scTables(i).io.update.oldCtr := scUpdateOldCtrs(i)
scTables(i).io.update.pc := u.pc
scTables(i).io.update.hist := updateHist
scTables(i).io.update.fetchIdx := u.brInfo.fetchIdx
scTables(i).io.update.fetchIdx := u.bpuMeta.fetchIdx
}
if (BPUDebug && debug) {
val m = updateMeta
val bri = u.brInfo
val bri = u.bpuMeta
XSDebug(io.pc.valid, "req: pc=0x%x, hist=%x\n", io.pc.bits, io.hist)
XSDebug(io.s3Fire, "s3Fire:%d, resp: pc=%x, hist=%x\n", io.s3Fire, debug_pc_s2, debug_hist_s2)
XSDebug(RegNext(io.s3Fire), "s3FireOnLastCycle: resp: pc=%x, hist=%x, hits=%b, takens=%b\n",
......
......@@ -43,12 +43,12 @@ class MicroBTB extends BasePredictor
class MicroBTBIO extends DefaultBasePredictorIO
{
val out = Output(new MicroBTBResp) //
val uBTBBranchInfo = Output(new MicroBTBBranchInfo)
val uBTBMeta = Output(new MicroBTBBranchInfo)
}
override val debug = true
override val io = IO(new MicroBTBIO)
io.uBTBBranchInfo <> out_ubtb_br_info
io.uBTBMeta <> out_ubtb_br_info
def getTag(pc: UInt) = (pc >> untaggedBits)(tagSize-1, 0)
def getBank(pc: UInt) = pc(log2Ceil(PredictWidth) ,1)
......@@ -251,13 +251,13 @@ class MicroBTB extends BasePredictor
//uBTB update
//backend should send fetch pc to update
val u = io.update.bits.ui
val u = io.update.bits
val update_br_pc = u.pc
val update_br_idx = u.fetchIdx
val update_br_offset = (update_br_idx << 1).asUInt()
val update_fetch_pc = update_br_pc - update_br_offset
val update_write_way = u.brInfo.ubtbWriteWay
val update_hits = u.brInfo.ubtbHits
val update_write_way = u.bpuMeta.ubtbWriteWay
val update_hits = u.bpuMeta.ubtbHits
val update_taken = u.taken
val update_bank = getBank(update_br_pc)
......@@ -268,9 +268,9 @@ class MicroBTB extends BasePredictor
val update_is_BR_or_JAL = (u.pd.brType === BrType.branch) || (u.pd.brType === BrType.jal)
val jalFirstEncountered = !u.isMisPred && !u.brInfo.btbHitJal && (u.pd.brType === BrType.jal)
val entry_write_valid = io.update.valid && (u.isMisPred || jalFirstEncountered)//io.update.valid //&& update_is_BR_or_JAL
val meta_write_valid = io.update.valid && (u.isMisPred || jalFirstEncountered)//io.update.valid //&& update_is_BR_or_JAL
val jalFirstEncountered = !u.isMisPred && !u.bpuMeta.btbHitJal && (u.pd.brType === BrType.jal)
val entry_write_valid = io.update.valid && (u.isMisPred || jalFirstEncountered) && !u.isReplay //io.update.valid //&& update_is_BR_or_JAL
val meta_write_valid = io.update.valid && (u.isMisPred || jalFirstEncountered) && !u.isReplay//io.update.valid //&& update_is_BR_or_JAL
//write btb target when miss prediction
// when(entry_write_valid)
// {
......
......@@ -17,14 +17,14 @@ with HasPartialDecoupledDriver {
test(new MicroBTB) { c =>
def genUpdateReq(pc: Long,target: Long,taken: Boolean,fetchIdx: Int,isMiss: Boolean,write_way: Int,hit: Boolean) = {
c.io.update.valid.poke(true.B)
c.io.update.bits.ui.pc.poke(pc.U)
c.io.update.bits.ui.target.poke(target.U)
c.io.update.bits.ui.taken.poke(taken.B)
c.io.update.bits.ui.fetchIdx.poke(fetchIdx.U)
c.io.update.bits.ui.isMisPred.poke(isMiss.B)
c.io.update.bits.ui.brInfo.ubtbWriteWay.poke(write_way.U)
c.io.update.bits.ui.brInfo.ubtbHits.poke(hit.B)
c.io.update.bits.ui.pd.brType.poke(BrType.branch)
c.io.update.bits.pc.poke(pc.U)
c.io.update.bits.target.poke(target.U)
c.io.update.bits.taken.poke(taken.B)
c.io.update.bits.fetchIdx.poke(fetchIdx.U)
c.io.update.bits.isMisPred.poke(isMiss.B)
c.io.update.bits.bpuMeta.ubtbWriteWay.poke(write_way.U)
c.io.update.bits.bpuMeta.ubtbHits.poke(hit.B)
c.io.update.bits.pd.brType.poke(BrType.branch)
}
def genReadReq(fetchpc: Long){
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册