未验证 提交 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 { ...@@ -24,7 +24,7 @@ class FetchPacket extends XSBundle {
// val pc = UInt(VAddrBits.W) // val pc = UInt(VAddrBits.W)
val pc = Vec(PredictWidth, UInt(VAddrBits.W)) val pc = Vec(PredictWidth, UInt(VAddrBits.W))
val pnpc = 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 pd = Vec(PredictWidth, new PreDecodeInfo)
val ipf = Bool() val ipf = Bool()
val acf = Bool() val acf = Bool()
...@@ -116,7 +116,7 @@ class BranchPrediction extends XSBundle with HasIFUConst { ...@@ -116,7 +116,7 @@ class BranchPrediction extends XSBundle with HasIFUConst {
def hasNotTakenBrs = Mux(taken, ParallelPriorityMux(realTakens, sawNotTakenBr), ParallelORR(brNotTakens)) 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 ubtbWriteWay = UInt(log2Up(UBtbWays).W)
val ubtbHits = Bool() val ubtbHits = Bool()
val btbWriteWay = UInt(log2Up(BtbWays).W) val btbWriteWay = UInt(log2Up(BtbWays).W)
...@@ -155,20 +155,22 @@ class Predecode extends XSBundle with HasIFUConst { ...@@ -155,20 +155,22 @@ class Predecode extends XSBundle with HasIFUConst {
val pd = Vec(FetchWidth*2, (new PreDecodeInfo)) val pd = Vec(FetchWidth*2, (new PreDecodeInfo))
} }
class BranchUpdateInfo extends XSBundle { class CfiUpdateInfo extends XSBundle {
// from backend // from backend
val pc = UInt(VAddrBits.W) val pc = UInt(VAddrBits.W)
val pnpc = 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 target = UInt(VAddrBits.W)
val brTarget = UInt(VAddrBits.W) val brTarget = UInt(VAddrBits.W)
val taken = Bool() val taken = Bool()
val fetchIdx = UInt(log2Up(FetchWidth*2).W)
val isMisPred = Bool() val isMisPred = Bool()
val brTag = new BrqPtr val brTag = new BrqPtr
val isReplay = Bool()
// frontend -> backend -> frontend
val pd = new PreDecodeInfo
val brInfo = new BranchInfo
} }
// Dequeue DecodeWidth insts from Ibuffer // Dequeue DecodeWidth insts from Ibuffer
...@@ -177,7 +179,7 @@ class CtrlFlow extends XSBundle { ...@@ -177,7 +179,7 @@ class CtrlFlow extends XSBundle {
val pc = UInt(VAddrBits.W) val pc = UInt(VAddrBits.W)
val exceptionVec = Vec(16, Bool()) val exceptionVec = Vec(16, Bool())
val intrVec = Vec(12, Bool()) val intrVec = Vec(12, Bool())
val brUpdate = new BranchUpdateInfo val brUpdate = new CfiUpdateInfo
val crossPageIPFFix = Bool() val crossPageIPFFix = Bool()
} }
...@@ -274,7 +276,7 @@ class ExuOutput extends XSBundle { ...@@ -274,7 +276,7 @@ class ExuOutput extends XSBundle {
val fflags = new Fflags val fflags = new Fflags
val redirectValid = Bool() val redirectValid = Bool()
val redirect = new Redirect val redirect = new Redirect
val brUpdate = new BranchUpdateInfo val brUpdate = new CfiUpdateInfo
val debug = new DebugBundle val debug = new DebugBundle
} }
...@@ -321,8 +323,8 @@ class FrontendToBackendIO extends XSBundle { ...@@ -321,8 +323,8 @@ class FrontendToBackendIO extends XSBundle {
val cfVec = Vec(DecodeWidth, DecoupledIO(new CtrlFlow)) val cfVec = Vec(DecodeWidth, DecoupledIO(new CtrlFlow))
// from backend // from backend
val redirect = Flipped(ValidIO(UInt(VAddrBits.W))) val redirect = Flipped(ValidIO(UInt(VAddrBits.W)))
val outOfOrderBrInfo = Flipped(ValidIO(new BranchUpdateInfo)) // val cfiUpdateInfo = Flipped(ValidIO(new CfiUpdateInfo))
val inOrderBrInfo = Flipped(ValidIO(new BranchUpdateInfo)) val cfiUpdateInfo = Flipped(ValidIO(new CfiUpdateInfo))
} }
class TlbCsrBundle extends XSBundle { class TlbCsrBundle extends XSBundle {
......
...@@ -78,10 +78,10 @@ class CtrlBlock extends XSModule with HasCircularQueuePtrHelper { ...@@ -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 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) val redirect = Mux(roq.io.redirect.valid, roq.io.redirect.bits, redirectArb)
io.frontend.redirect.valid := redirectValid io.frontend.redirect.valid := RegNext(redirectValid)
io.frontend.redirect.bits := Mux(roq.io.redirect.valid, roq.io.redirect.bits.target, redirectArb.target) io.frontend.redirect.bits := RegNext(Mux(roq.io.redirect.valid, roq.io.redirect.bits.target, redirectArb.target))
io.frontend.outOfOrderBrInfo <> brq.io.outOfOrderBrInfo // io.frontend.cfiUpdateInfo <> brq.io.cfiInfo
io.frontend.inOrderBrInfo <> brq.io.inOrderBrInfo io.frontend.cfiUpdateInfo <> brq.io.cfiInfo
decode.io.in <> io.frontend.cfVec decode.io.in <> io.frontend.cfVec
decode.io.toBrq <> brq.io.enqReqs decode.io.toBrq <> brq.io.enqReqs
...@@ -95,8 +95,9 @@ class CtrlBlock extends XSModule with HasCircularQueuePtrHelper { ...@@ -95,8 +95,9 @@ class CtrlBlock extends XSModule with HasCircularQueuePtrHelper {
brq.io.exuRedirect <> io.fromIntBlock.exuRedirect brq.io.exuRedirect <> io.fromIntBlock.exuRedirect
// pipeline between decode and dispatch // pipeline between decode and dispatch
val lastCycleRedirect = RegNext(redirectValid)
for (i <- 0 until RenameWidth) { 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 rename.io.redirect.valid <> redirectValid
......
...@@ -51,11 +51,9 @@ class BrqIO extends XSBundle{ ...@@ -51,11 +51,9 @@ class BrqIO extends XSBundle{
val out = ValidIO(new ExuOutput) val out = ValidIO(new ExuOutput)
// misprediction, flush pipeline // misprediction, flush pipeline
val redirect = Output(Valid(new Redirect)) val redirect = Output(Valid(new Redirect))
val outOfOrderBrInfo = ValidIO(new BranchUpdateInfo) val cfiInfo = ValidIO(new CfiUpdateInfo)
// commit cnt of branch instr // commit cnt of branch instr
val bcommit = Input(UInt(BrTagWidth.W)) val bcommit = Input(UInt(BrTagWidth.W))
// in order dequeue to train bpd
val inOrderBrInfo = ValidIO(new BranchUpdateInfo)
} }
class Brq extends XSModule with HasCircularQueuePtrHelper { class Brq extends XSModule with HasCircularQueuePtrHelper {
...@@ -63,7 +61,6 @@ class Brq extends XSModule with HasCircularQueuePtrHelper { ...@@ -63,7 +61,6 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
class BrqEntry extends Bundle { class BrqEntry extends Bundle {
val ptrFlag = Bool() val ptrFlag = Bool()
val npc = UInt(VAddrBits.W)
val exuOut = new ExuOutput val exuOut = new ExuOutput
} }
...@@ -117,15 +114,13 @@ class Brq extends XSModule with HasCircularQueuePtrHelper { ...@@ -117,15 +114,13 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
val deqValid = stateQueue(headIdx).isCommit && brCommitCnt=/=0.U val deqValid = stateQueue(headIdx).isCommit && brCommitCnt=/=0.U
val commitValid = stateQueue(commitIdx).isWb val commitValid = stateQueue(commitIdx).isWb
val commitEntry = brQueue(commitIdx) val commitEntry = brQueue(commitIdx)
val commitIsMisPred = commitEntry.exuOut.redirect.isMisPred val commitIsMisPred = commitEntry.exuOut.brUpdate.isMisPred
brCommitCnt := brCommitCnt + io.bcommit - deqValid brCommitCnt := brCommitCnt + io.bcommit - deqValid
XSDebug(p"brCommitCnt:$brCommitCnt\n") XSDebug(p"brCommitCnt:$brCommitCnt\n")
assert(brCommitCnt+io.bcommit >= deqValid) assert(brCommitCnt+io.bcommit >= deqValid)
io.inOrderBrInfo.valid := commitValid XSDebug(io.cfiInfo.valid, "inOrderValid: pc=%x\n", io.cfiInfo.bits.pc)
io.inOrderBrInfo.bits := commitEntry.exuOut.brUpdate
XSDebug(io.inOrderBrInfo.valid, "inOrderValid: pc=%x\n", io.inOrderBrInfo.bits.pc)
XSDebug(p"headIdx:$headIdx commitIdx:$commitIdx\n") XSDebug(p"headIdx:$headIdx commitIdx:$commitIdx\n")
XSDebug(p"headPtr:$headPtr tailPtr:$tailPtr\n") XSDebug(p"headPtr:$headPtr tailPtr:$tailPtr\n")
...@@ -149,20 +144,19 @@ class Brq extends XSModule with HasCircularQueuePtrHelper { ...@@ -149,20 +144,19 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
assert(!(commitIdx===headIdx && commitValid && deqValid), "Error: deq and commit a same entry!") assert(!(commitIdx===headIdx && commitValid && deqValid), "Error: deq and commit a same entry!")
headPtr := headPtrNext 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 := commitEntry.exuOut.redirect
io.redirect.bits.brTag := BrqPtr(commitEntry.ptrFlag, commitIdx)
io.out.valid := commitValid io.out.valid := commitValid
io.out.bits := commitEntry.exuOut io.out.bits := commitEntry.exuOut
io.outOfOrderBrInfo.valid := commitValid
io.outOfOrderBrInfo.bits := commitEntry.exuOut.brUpdate
when (io.redirect.valid) { val brTagRead = RegNext(Mux(io.memRedirect.bits.isReplay, io.memRedirect.bits.brTag - 1.U, io.memRedirect.bits.brTag))
commitEntry.npc := io.redirect.bits.target 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, XSInfo(io.out.valid,
p"commit branch to roq, mispred:${io.redirect.valid} pc=${Hexadecimal(io.out.bits.uop.cf.pc)}\n" 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 { ...@@ -176,9 +170,13 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
val idx = brTag.value val idx = brTag.value
io.enqReqs(i).ready := validEntries <= (BrqSize - (i + 1)).U io.enqReqs(i).ready := validEntries <= (BrqSize - (i + 1)).U
io.brTags(i) := brTag io.brTags(i) := brTag
when(io.enqReqs(i).fire()){ when (io.enqReqs(i).fire()) {
brQueue(idx).npc := io.enqReqs(i).bits.cf.brUpdate.pnpc
brQueue(idx).ptrFlag := brTag.flag 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 stateQueue(idx) := s_idle
} }
} }
...@@ -187,20 +185,29 @@ class Brq extends XSModule with HasCircularQueuePtrHelper { ...@@ -187,20 +185,29 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
// exu write back // exu write back
for(exuWb <- io.exuRedirect){ for(exuWb <- io.exuRedirect){
when(exuWb.valid){ when (exuWb.valid) {
val wbIdx = exuWb.bits.redirect.brTag.value val wbIdx = exuWb.bits.redirect.brTag.value
XSInfo( XSInfo(
p"exu write back: brTag:${exuWb.bits.redirect.brTag}" + 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 stateQueue(wbIdx) := s_wb
} }
val exuOut = WireInit(exuWb.bits) val isMisPred = brQueue(wbIdx).exuOut.brUpdate.pnpc =/= exuWb.bits.redirect.target
val isMisPred = brQueue(wbIdx).npc =/= exuWb.bits.redirect.target // only writeback necessary information
exuOut.redirect.isMisPred := isMisPred brQueue(wbIdx).exuOut.uop := exuWb.bits.uop
exuOut.brUpdate.isMisPred := isMisPred brQueue(wbIdx).exuOut.data := exuWb.bits.data
brQueue(wbIdx).exuOut := exuOut 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._ ...@@ -11,7 +11,7 @@ import xiangshan.backend.decode.isa._
trait HasRedirectOut { this: RawModule => trait HasRedirectOut { this: RawModule =>
val redirectOutValid = IO(Output(Bool())) val redirectOutValid = IO(Output(Bool()))
val redirectOut = IO(Output(new Redirect)) val redirectOut = IO(Output(new Redirect))
val brUpdate = IO(Output(new BranchUpdateInfo)) val brUpdate = IO(Output(new CfiUpdateInfo))
} }
class Jump extends FunctionUnit with HasRedirectOut { class Jump extends FunctionUnit with HasRedirectOut {
...@@ -44,7 +44,7 @@ class Jump extends FunctionUnit with HasRedirectOut { ...@@ -44,7 +44,7 @@ class Jump extends FunctionUnit with HasRedirectOut {
brUpdate := uop.cf.brUpdate brUpdate := uop.cf.brUpdate
brUpdate.pc := uop.cf.pc brUpdate.pc := uop.cf.pc
brUpdate.target := target brUpdate.target := target
brUpdate.brTarget := target // DontCare brUpdate.brTarget := target
brUpdate.taken := true.B brUpdate.taken := true.B
// Output // Output
......
...@@ -115,7 +115,7 @@ abstract class BasePredictor extends XSModule ...@@ -115,7 +115,7 @@ abstract class BasePredictor extends XSModule
val pc = Flipped(ValidIO(UInt(VAddrBits.W))) val pc = Flipped(ValidIO(UInt(VAddrBits.W)))
val hist = Input(UInt(HistoryLength.W)) val hist = Input(UInt(HistoryLength.W))
val inMask = Input(UInt(PredictWidth.W)) val inMask = Input(UInt(PredictWidth.W))
val update = Flipped(ValidIO(new BranchUpdateInfoWithHist)) val update = Flipped(ValidIO(new CfiUpdateInfo))
val outFire = Input(Bool()) val outFire = Input(Bool())
} }
...@@ -129,7 +129,7 @@ class BPUStageIO extends XSBundle { ...@@ -129,7 +129,7 @@ class BPUStageIO extends XSBundle {
val mask = UInt(PredictWidth.W) val mask = UInt(PredictWidth.W)
val resp = new PredictorResponse val resp = new PredictorResponse
// val target = UInt(VAddrBits.W) // val target = UInt(VAddrBits.W)
val brInfo = Vec(PredictWidth, new BranchInfo) val brInfo = Vec(PredictWidth, new BpuMeta)
// val saveHalfRVI = Bool() // val saveHalfRVI = Bool()
} }
...@@ -251,7 +251,7 @@ class BPUStage3 extends BPUStage { ...@@ -251,7 +251,7 @@ class BPUStage3 extends BPUStage {
val predecode = Input(new Predecode) val predecode = Input(new Predecode)
val realMask = Input(UInt(PredictWidth.W)) val realMask = Input(UInt(PredictWidth.W))
val prevHalf = Input(new PrevHalfInstr) val prevHalf = Input(new PrevHalfInstr)
val recover = Flipped(ValidIO(new BranchUpdateInfo)) val recover = Flipped(ValidIO(new CfiUpdateInfo))
} }
val s3IO = IO(new S3IO) val s3IO = IO(new S3IO)
// TAGE has its own pipelines and the // TAGE has its own pipelines and the
...@@ -315,9 +315,9 @@ class BPUStage3 extends BPUStage { ...@@ -315,9 +315,9 @@ class BPUStage3 extends BPUStage {
ras.io.recover := s3IO.recover ras.io.recover := s3IO.recover
for(i <- 0 until PredictWidth){ for(i <- 0 until PredictWidth){
io.out.brInfo(i).rasSp := ras.io.branchInfo.rasSp io.out.brInfo(i).rasSp := ras.io.meta.rasSp
io.out.brInfo(i).rasTopCtr := ras.io.branchInfo.rasTopCtr io.out.brInfo(i).rasTopCtr := ras.io.meta.rasTopCtr
io.out.brInfo(i).rasToqAddr := ras.io.branchInfo.rasToqAddr io.out.brInfo(i).rasToqAddr := ras.io.meta.rasToqAddr
} }
takens := VecInit((0 until PredictWidth).map(i => { takens := VecInit((0 until PredictWidth).map(i => {
((brTakens(i) || jalrs(i)) && btbHits(i)) || ((brTakens(i) || jalrs(i)) && btbHits(i)) ||
...@@ -401,25 +401,25 @@ class BPUReq extends XSBundle { ...@@ -401,25 +401,25 @@ class BPUReq extends XSBundle {
// val histPtr = UInt(log2Up(ExtHistoryLength).W) // only for debug // val histPtr = UInt(log2Up(ExtHistoryLength).W) // only for debug
} }
class BranchUpdateInfoWithHist extends XSBundle { // class CfiUpdateInfoWithHist extends XSBundle {
val ui = new BranchUpdateInfo // val ui = new CfiUpdateInfo
val hist = UInt(HistoryLength.W) // val hist = UInt(HistoryLength.W)
} // }
object BranchUpdateInfoWithHist { // object CfiUpdateInfoWithHist {
def apply (brInfo: BranchUpdateInfo, hist: UInt) = { // def apply (brInfo: CfiUpdateInfo, hist: UInt) = {
val b = Wire(new BranchUpdateInfoWithHist) // val b = Wire(new CfiUpdateInfoWithHist)
b.ui <> brInfo // b.ui <> brInfo
b.hist := hist // b.hist := hist
b // b
} // }
} // }
abstract class BaseBPU extends XSModule with BranchPredictorComponents with HasBPUParameter{ abstract class BaseBPU extends XSModule with BranchPredictorComponents with HasBPUParameter{
val io = IO(new Bundle() { val io = IO(new Bundle() {
// from backend // from backend
val inOrderBrInfo = Flipped(ValidIO(new BranchUpdateInfoWithHist)) val cfiUpdateInfo = Flipped(ValidIO(new CfiUpdateInfo))
val outOfOrderBrInfo = Flipped(ValidIO(new BranchUpdateInfoWithHist)) // val cfiUpdateInfo = Flipped(ValidIO(new CfiUpdateInfoWithHist))
// from ifu, frontend redirect // from ifu, frontend redirect
val flush = Input(Vec(3, Bool())) val flush = Input(Vec(3, Bool()))
// from if1 // from if1
...@@ -432,13 +432,13 @@ abstract class BaseBPU extends XSModule with BranchPredictorComponents with HasB ...@@ -432,13 +432,13 @@ abstract class BaseBPU extends XSModule with BranchPredictorComponents with HasB
val realMask = Input(UInt(PredictWidth.W)) val realMask = Input(UInt(PredictWidth.W))
val prevHalf = Input(new PrevHalfInstr) val prevHalf = Input(new PrevHalfInstr)
// to if4, some bpu info used for updating // 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) def npc(pc: UInt, instCount: UInt) = pc + (instCount << 1.U)
preds.map(_.io.update <> io.outOfOrderBrInfo) preds.map(_.io.update <> io.cfiUpdateInfo)
tage.io.update <> io.inOrderBrInfo // tage.io.update <> io.cfiUpdateInfo
val s1 = Module(new BPUStage1) val s1 = Module(new BPUStage1)
val s2 = Module(new BPUStage2) val s2 = Module(new BPUStage2)
...@@ -469,12 +469,12 @@ abstract class BaseBPU extends XSModule with BranchPredictorComponents with HasB ...@@ -469,12 +469,12 @@ abstract class BaseBPU extends XSModule with BranchPredictorComponents with HasB
io.out(1) <> s2.io.pred io.out(1) <> s2.io.pred
io.out(2) <> s3.io.pred io.out(2) <> s3.io.pred
io.branchInfo := s3.io.out.brInfo io.bpuMeta := s3.io.out.brInfo
if (BPUDebug) { if (BPUDebug) {
XSDebug(io.inFire(3), "branchInfo sent!\n") XSDebug(io.inFire(3), "bpuMeta sent!\n")
for (i <- 0 until PredictWidth) { 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", 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) i.U, b.ubtbWriteWay, b.ubtbHits, b.btbWriteWay, b.btbHitJal, b.bimCtr, b.fetchIdx)
val t = b.tageMeta val t = b.tageMeta
...@@ -492,7 +492,7 @@ class FakeBPU extends BaseBPU { ...@@ -492,7 +492,7 @@ class FakeBPU extends BaseBPU {
i <> DontCare i <> DontCare
i.takens := 0.U i.takens := 0.U
}) })
io.branchInfo <> DontCare io.bpuMeta <> DontCare
} }
@chiselName @chiselName
class BPU extends BaseBPU { class BPU extends BaseBPU {
...@@ -500,7 +500,7 @@ class BPU extends BaseBPU { ...@@ -500,7 +500,7 @@ class BPU extends BaseBPU {
//**********************Stage 1****************************// //**********************Stage 1****************************//
val s1_resp_in = Wire(new PredictorResponse) 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.tage := DontCare
s1_resp_in.loop := DontCare s1_resp_in.loop := DontCare
...@@ -518,8 +518,8 @@ class BPU extends BaseBPU { ...@@ -518,8 +518,8 @@ class BPU extends BaseBPU {
// Wrap ubtb response into resp_in and brInfo_in // Wrap ubtb response into resp_in and brInfo_in
s1_resp_in.ubtb <> ubtb.io.out s1_resp_in.ubtb <> ubtb.io.out
for (i <- 0 until PredictWidth) { for (i <- 0 until PredictWidth) {
s1_brInfo_in(i).ubtbWriteWay := ubtb.io.uBTBBranchInfo.writeWay(i) s1_brInfo_in(i).ubtbWriteWay := ubtb.io.uBTBMeta.writeWay(i)
s1_brInfo_in(i).ubtbHits := ubtb.io.uBTBBranchInfo.hits(i) s1_brInfo_in(i).ubtbHits := ubtb.io.uBTBMeta.hits(i)
} }
btb.io.flush := io.flush(0) // TODO: fix this btb.io.flush := io.flush(0) // TODO: fix this
...@@ -598,8 +598,8 @@ class BPU extends BaseBPU { ...@@ -598,8 +598,8 @@ class BPU extends BaseBPU {
s3.s3IO.prevHalf := io.prevHalf s3.s3IO.prevHalf := io.prevHalf
s3.s3IO.recover.valid <> io.inOrderBrInfo.valid s3.s3IO.recover.valid <> io.cfiUpdateInfo.valid
s3.s3IO.recover.bits <> io.inOrderBrInfo.bits.ui s3.s3IO.recover.bits <> io.cfiUpdateInfo.bits
if (BPUDebug) { if (BPUDebug) {
if (debug_verbose) { if (debug_verbose) {
...@@ -615,11 +615,11 @@ class BPU extends BaseBPU { ...@@ -615,11 +615,11 @@ class BPU extends BaseBPU {
if (EnableCFICommitLog) { if (EnableCFICommitLog) {
val buValid = io.inOrderBrInfo.valid val buValid = io.cfiUpdateInfo.valid
val buinfo = io.inOrderBrInfo.bits.ui val buinfo = io.cfiUpdateInfo.bits
val pd = buinfo.pd val pd = buinfo.pd
val tage_cycle = buinfo.brInfo.debug_tage_cycle 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(io.inOrderBrInfo.bits.hist)})\n") 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 { ...@@ -80,7 +80,7 @@ class BIM extends BasePredictor with BimParams {
io.meta.ctrs(b) := ctr io.meta.ctrs(b) := ctr
} }
val u = io.update.bits.ui val u = io.update.bits
val updateBank = bimAddr.getBank(u.pc) val updateBank = bimAddr.getBank(u.pc)
val updateRow = bimAddr.getBankIdx(u.pc) val updateRow = bimAddr.getBankIdx(u.pc)
...@@ -96,12 +96,12 @@ class BIM extends BasePredictor with BimParams { ...@@ -96,12 +96,12 @@ class BIM extends BasePredictor with BimParams {
val wrbypass_hit = wrbypass_hits.reduce(_||_) val wrbypass_hit = wrbypass_hits.reduce(_||_)
val wrbypass_hit_idx = PriorityEncoder(wrbypass_hits) 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 newTaken = u.taken
val newCtr = satUpdate(oldCtr, 2, newTaken) val newCtr = satUpdate(oldCtr, 2, newTaken)
// val oldSaturated = newCtr === oldCtr // 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))} when (reset.asBool) { wrbypass_ctr_valids.foreach(_.foreach(_ := false.B))}
...@@ -126,9 +126,9 @@ class BIM extends BasePredictor with BimParams { ...@@ -126,9 +126,9 @@ class BIM extends BasePredictor with BimParams {
if (BPUDebug && debug) { if (BPUDebug && debug) {
XSDebug(doing_reset, "Reseting...\n") 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("[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("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) XSDebug("[wrbypass] hit=%d hits=%b\n", wrbypass_hit, wrbypass_hits.asUInt)
} }
......
package xiangshan.frontend package xiangshan.frontend
import chisel3._ import chisel3._
import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage}
import chisel3.util._ import chisel3.util._
import xiangshan._ import xiangshan._
import xiangshan.backend.ALUOpType import xiangshan.backend.ALUOpType
import utils._ import utils._
import xiangshan.backend.decode.XSTrap import xiangshan.backend.decode.XSTrap
import chisel3.experimental.chiselName import chisel3.experimental.chiselName
import scala.math.min import scala.math.min
trait BTBParams extends HasXSParameter { trait BTBParams extends HasXSParameter {
val nRows = BtbSize / (PredictWidth * BtbWays) val nRows = BtbSize / (PredictWidth * BtbWays)
val offsetLen = 13 val offsetLen = 13
val extendedNRows = nRows val extendedNRows = nRows
} }
class BtbDataEntry extends XSBundle with BTBParams { class BtbDataEntry extends XSBundle with BTBParams {
val offset = SInt(offsetLen.W) val offset = SInt(offsetLen.W)
val extended = Bool() val extended = Bool()
} }
object BtbDataEntry { object BtbDataEntry {
def apply(offset: SInt, extended: Bool) = { def apply(offset: SInt, extended: Bool) = {
val e = Wire(new BtbDataEntry) val e = Wire(new BtbDataEntry)
e.offset := offset e.offset := offset
e.extended := extended e.extended := extended
e e
} }
} }
class BtbMetaEntry() extends XSBundle with BTBParams { class BtbMetaEntry() extends XSBundle with BTBParams {
val valid = Bool() val valid = Bool()
// TODO: don't need full length of tag // TODO: don't need full length of tag
val tag = UInt((VAddrBits - log2Up(BtbSize) - 1).W) val tag = UInt((VAddrBits - log2Up(BtbSize) - 1).W)
val btbType = UInt(2.W) val btbType = UInt(2.W)
val isRVC = Bool() val isRVC = Bool()
} }
object BtbMetaEntry { object BtbMetaEntry {
def apply(tag: UInt, btbType: UInt, isRVC: Bool) = { def apply(tag: UInt, btbType: UInt, isRVC: Bool) = {
val e = Wire(new BtbMetaEntry) val e = Wire(new BtbMetaEntry)
e.valid := true.B e.valid := true.B
e.tag := tag e.tag := tag
e.btbType := btbType e.btbType := btbType
e.isRVC := isRVC e.isRVC := isRVC
e e
} }
} }
class BTB extends BasePredictor with BTBParams{ class BTB extends BasePredictor with BTBParams{
class BTBResp extends Resp { class BTBResp extends Resp {
val targets = Vec(PredictWidth, UInt(VAddrBits.W)) val targets = Vec(PredictWidth, UInt(VAddrBits.W))
val hits = Vec(PredictWidth, Bool()) val hits = Vec(PredictWidth, Bool())
val types = Vec(PredictWidth, UInt(2.W)) val types = Vec(PredictWidth, UInt(2.W))
val isRVC = Vec(PredictWidth, Bool()) val isRVC = Vec(PredictWidth, Bool())
} }
class BTBMeta extends Meta { class BTBMeta extends Meta {
val writeWay = Vec(PredictWidth, UInt(log2Up(BtbWays).W)) val writeWay = Vec(PredictWidth, UInt(log2Up(BtbWays).W))
val hitJal = Vec(PredictWidth, Bool()) val hitJal = Vec(PredictWidth, Bool())
} }
class BTBFromOthers extends FromOthers {} class BTBFromOthers extends FromOthers {}
class BTBIO extends DefaultBasePredictorIO { class BTBIO extends DefaultBasePredictorIO {
val resp = Output(new BTBResp) val resp = Output(new BTBResp)
val meta = Output(new BTBMeta) val meta = Output(new BTBMeta)
} }
override val debug = true override val debug = true
override val io = IO(new BTBIO) override val io = IO(new BTBIO)
val btbAddr = new TableAddr(log2Up(BtbSize/BtbWays), BtbBanks) val btbAddr = new TableAddr(log2Up(BtbSize/BtbWays), BtbBanks)
val if1_bankAlignedPC = bankAligned(io.pc.bits) val if1_bankAlignedPC = bankAligned(io.pc.bits)
val if2_pc = RegEnable(if1_bankAlignedPC, io.pc.valid) val if2_pc = RegEnable(if1_bankAlignedPC, io.pc.valid)
val data = List.fill(BtbWays) { val data = List.fill(BtbWays) {
List.fill(BtbBanks) { List.fill(BtbBanks) {
Module(new SRAMTemplate(new BtbDataEntry, set = nRows, shouldReset = true, holdRead = true)) Module(new SRAMTemplate(new BtbDataEntry, set = nRows, shouldReset = true, holdRead = true))
} }
} }
val meta = List.fill(BtbWays) { val meta = List.fill(BtbWays) {
List.fill(BtbBanks) { List.fill(BtbBanks) {
Module(new SRAMTemplate(new BtbMetaEntry, set = nRows, shouldReset = true, holdRead = true)) Module(new SRAMTemplate(new BtbMetaEntry, set = nRows, shouldReset = true, holdRead = true))
} }
} }
val edata = List.fill(2)(Module(new SRAMTemplate(UInt(VAddrBits.W), set = extendedNRows/2, shouldReset = true, holdRead = true))) val edata = List.fill(2)(Module(new SRAMTemplate(UInt(VAddrBits.W), set = extendedNRows/2, shouldReset = true, holdRead = true)))
// BTB read requests // BTB read requests
// this bank means cache bank // this bank means cache bank
val if1_startsAtOddBank = bankInGroup(if1_bankAlignedPC)(0) val if1_startsAtOddBank = bankInGroup(if1_bankAlignedPC)(0)
val if1_baseBank = btbAddr.getBank(if1_bankAlignedPC) val if1_baseBank = btbAddr.getBank(if1_bankAlignedPC)
val if1_realMask = Mux(if1_startsAtOddBank, val if1_realMask = Mux(if1_startsAtOddBank,
Cat(io.inMask(bankWidth-1,0), io.inMask(PredictWidth-1, bankWidth)), Cat(io.inMask(bankWidth-1,0), io.inMask(PredictWidth-1, bankWidth)),
io.inMask) io.inMask)
val if2_realMask = RegEnable(if1_realMask, io.pc.valid) val if2_realMask = RegEnable(if1_realMask, io.pc.valid)
val if1_isInNextRow = VecInit((0 until BtbBanks).map(i => Mux(if1_startsAtOddBank, (i < bankWidth).B, false.B))) val if1_isInNextRow = VecInit((0 until BtbBanks).map(i => Mux(if1_startsAtOddBank, (i < bankWidth).B, false.B)))
val if1_baseRow = btbAddr.getBankIdx(if1_bankAlignedPC) val if1_baseRow = btbAddr.getBankIdx(if1_bankAlignedPC)
val if1_nextRowStartsUp = if1_baseRow.andR val if1_nextRowStartsUp = if1_baseRow.andR
val if1_realRow = VecInit((0 until BtbBanks).map(b => Mux(if1_isInNextRow(b), (if1_baseRow+1.U)(log2Up(nRows)-1, 0), if1_baseRow))) val if1_realRow = VecInit((0 until BtbBanks).map(b => Mux(if1_isInNextRow(b), (if1_baseRow+1.U)(log2Up(nRows)-1, 0), if1_baseRow)))
val if2_realRow = VecInit(if1_realRow.map(RegEnable(_, enable=io.pc.valid))) val if2_realRow = VecInit(if1_realRow.map(RegEnable(_, enable=io.pc.valid)))
for (w <- 0 until BtbWays) { for (w <- 0 until BtbWays) {
for (b <- 0 until BtbBanks) { for (b <- 0 until BtbBanks) {
meta(w)(b).io.r.req.valid := if1_realMask(b) && io.pc.valid meta(w)(b).io.r.req.valid := if1_realMask(b) && io.pc.valid
meta(w)(b).io.r.req.bits.setIdx := if1_realRow(b) meta(w)(b).io.r.req.bits.setIdx := if1_realRow(b)
data(w)(b).io.r.req.valid := if1_realMask(b) && io.pc.valid data(w)(b).io.r.req.valid := if1_realMask(b) && io.pc.valid
data(w)(b).io.r.req.bits.setIdx := if1_realRow(b) data(w)(b).io.r.req.bits.setIdx := if1_realRow(b)
} }
} }
for (b <- 0 to 1) { for (b <- 0 to 1) {
edata(b).io.r.req.valid := io.pc.valid edata(b).io.r.req.valid := io.pc.valid
val row = if (b == 0) { Mux(if1_startsAtOddBank, if1_realRow(bankWidth), if1_realRow(0)) } val row = if (b == 0) { Mux(if1_startsAtOddBank, if1_realRow(bankWidth), if1_realRow(0)) }
else { Mux(if1_startsAtOddBank, if1_realRow(0), if1_realRow(bankWidth))} else { Mux(if1_startsAtOddBank, if1_realRow(0), if1_realRow(bankWidth))}
edata(b).io.r.req.bits.setIdx := row edata(b).io.r.req.bits.setIdx := row
} }
// Entries read from SRAM // Entries read from SRAM
val if2_metaRead = VecInit((0 until BtbWays).map(w => VecInit((0 until BtbBanks).map( b => meta(w)(b).io.r.resp.data(0))))) val if2_metaRead = VecInit((0 until BtbWays).map(w => VecInit((0 until BtbBanks).map( b => meta(w)(b).io.r.resp.data(0)))))
val if2_dataRead = VecInit((0 until BtbWays).map(w => VecInit((0 until BtbBanks).map( b => data(w)(b).io.r.resp.data(0))))) val if2_dataRead = VecInit((0 until BtbWays).map(w => VecInit((0 until BtbBanks).map( b => data(w)(b).io.r.resp.data(0)))))
val if2_edataRead = VecInit((0 to 1).map(i => edata(i).io.r.resp.data(0))) val if2_edataRead = VecInit((0 to 1).map(i => edata(i).io.r.resp.data(0)))
val if2_baseBank = btbAddr.getBank(if2_pc) val if2_baseBank = btbAddr.getBank(if2_pc)
val if2_startsAtOddBank = bankInGroup(if2_pc)(0) val if2_startsAtOddBank = bankInGroup(if2_pc)(0)
val if2_baseTag = btbAddr.getTag(if2_pc) val if2_baseTag = btbAddr.getTag(if2_pc)
val if2_tagIncremented = VecInit((0 until BtbBanks).map(b => RegEnable(if1_isInNextRow(b.U) && if1_nextRowStartsUp, io.pc.valid))) val if2_tagIncremented = VecInit((0 until BtbBanks).map(b => RegEnable(if1_isInNextRow(b.U) && if1_nextRowStartsUp, io.pc.valid)))
val if2_realTags = VecInit((0 until BtbBanks).map(b => Mux(if2_tagIncremented(b), if2_baseTag + 1.U, if2_baseTag))) val if2_realTags = VecInit((0 until BtbBanks).map(b => Mux(if2_tagIncremented(b), if2_baseTag + 1.U, if2_baseTag)))
val if2_totalHits = VecInit((0 until BtbBanks).map( b => val if2_totalHits = VecInit((0 until BtbBanks).map( b =>
VecInit((0 until BtbWays).map( w => VecInit((0 until BtbWays).map( w =>
// This should correspond to the real mask from last valid cycle! // This should correspond to the real mask from last valid cycle!
if2_metaRead(w)(b).tag === if2_realTags(b) && if2_metaRead(w)(b).valid && if2_realMask(b) if2_metaRead(w)(b).tag === if2_realTags(b) && if2_metaRead(w)(b).valid && if2_realMask(b)
)) ))
)) ))
val if2_bankHits = VecInit(if2_totalHits.map(_.reduce(_||_))) val if2_bankHits = VecInit(if2_totalHits.map(_.reduce(_||_)))
val if2_bankHitWays = VecInit(if2_totalHits.map(PriorityEncoder(_))) val if2_bankHitWays = VecInit(if2_totalHits.map(PriorityEncoder(_)))
def allocWay(valids: UInt, meta_tags: UInt, req_tag: UInt) = { def allocWay(valids: UInt, meta_tags: UInt, req_tag: UInt) = {
val randomAlloc = true val randomAlloc = true
if (BtbWays > 1) { if (BtbWays > 1) {
val w = Wire(UInt(log2Up(BtbWays).W)) val w = Wire(UInt(log2Up(BtbWays).W))
val valid = WireInit(valids.andR) val valid = WireInit(valids.andR)
val tags = Cat(meta_tags, req_tag) val tags = Cat(meta_tags, req_tag)
val l = log2Up(BtbWays) val l = log2Up(BtbWays)
val nChunks = (tags.getWidth + l - 1) / l val nChunks = (tags.getWidth + l - 1) / l
val chunks = (0 until nChunks).map( i => val chunks = (0 until nChunks).map( i =>
tags(min((i+1)*l, tags.getWidth)-1, i*l) tags(min((i+1)*l, tags.getWidth)-1, i*l)
) )
w := Mux(valid, if (randomAlloc) {LFSR64()(log2Up(BtbWays)-1,0)} else {chunks.reduce(_^_)}, PriorityEncoder(~valids)) w := Mux(valid, if (randomAlloc) {LFSR64()(log2Up(BtbWays)-1,0)} else {chunks.reduce(_^_)}, PriorityEncoder(~valids))
w w
} else { } else {
val w = WireInit(0.U) val w = WireInit(0.U)
w w
} }
} }
val allocWays = VecInit((0 until BtbBanks).map(b => val allocWays = VecInit((0 until BtbBanks).map(b =>
allocWay(VecInit(if2_metaRead.map(w => w(b).valid)).asUInt, allocWay(VecInit(if2_metaRead.map(w => w(b).valid)).asUInt,
VecInit(if2_metaRead.map(w => w(b).tag)).asUInt, VecInit(if2_metaRead.map(w => w(b).tag)).asUInt,
if2_realTags(b)))) if2_realTags(b))))
val writeWay = VecInit((0 until BtbBanks).map( val writeWay = VecInit((0 until BtbBanks).map(
b => Mux(if2_bankHits(b), if2_bankHitWays(b), allocWays(b)) b => Mux(if2_bankHits(b), if2_bankHitWays(b), allocWays(b))
)) ))
for (b <- 0 until BtbBanks) { for (b <- 0 until BtbBanks) {
val realBank = (if (b < bankWidth) Mux(if2_startsAtOddBank, (b+bankWidth).U, b.U) val realBank = (if (b < bankWidth) Mux(if2_startsAtOddBank, (b+bankWidth).U, b.U)
else Mux(if2_startsAtOddBank, (b-bankWidth).U, b.U)) else Mux(if2_startsAtOddBank, (b-bankWidth).U, b.U))
val meta_entry = if2_metaRead(if2_bankHitWays(realBank))(realBank) val meta_entry = if2_metaRead(if2_bankHitWays(realBank))(realBank)
val data_entry = if2_dataRead(if2_bankHitWays(realBank))(realBank) val data_entry = if2_dataRead(if2_bankHitWays(realBank))(realBank)
val edataBank = (if (b < bankWidth) Mux(if2_startsAtOddBank, 1.U, 0.U) val edataBank = (if (b < bankWidth) Mux(if2_startsAtOddBank, 1.U, 0.U)
else Mux(if2_startsAtOddBank, 0.U, 1.U)) else Mux(if2_startsAtOddBank, 0.U, 1.U))
// Use real pc to calculate the target // Use real pc to calculate the target
io.resp.targets(b) := Mux(data_entry.extended, if2_edataRead(edataBank), (if2_pc.asSInt + (b << 1).S + data_entry.offset).asUInt) io.resp.targets(b) := Mux(data_entry.extended, if2_edataRead(edataBank), (if2_pc.asSInt + (b << 1).S + data_entry.offset).asUInt)
io.resp.hits(b) := if2_bankHits(realBank) io.resp.hits(b) := if2_bankHits(realBank)
io.resp.types(b) := meta_entry.btbType io.resp.types(b) := meta_entry.btbType
io.resp.isRVC(b) := meta_entry.isRVC io.resp.isRVC(b) := meta_entry.isRVC
io.meta.writeWay(b) := writeWay(realBank) io.meta.writeWay(b) := writeWay(realBank)
io.meta.hitJal(b) := if2_bankHits(realBank) && meta_entry.btbType === BTBtype.J io.meta.hitJal(b) := if2_bankHits(realBank) && meta_entry.btbType === BTBtype.J
} }
def pdInfoToBTBtype(pd: PreDecodeInfo) = { def pdInfoToBTBtype(pd: PreDecodeInfo) = {
val t = WireInit(0.U(2.W)) val t = WireInit(0.U(2.W))
when (pd.isJalr) { t := BTBtype.I} when (pd.isJalr) { t := BTBtype.I}
when (pd.isRet) { t := BTBtype.R} when (pd.isRet) { t := BTBtype.R}
when (pd.isJal) { t := BTBtype.J} when (pd.isJal) { t := BTBtype.J}
when (pd.isBr) { t := BTBtype.B} when (pd.isBr) { t := BTBtype.B}
t t
} }
val u = io.update.bits.ui val u = io.update.bits
val max_offset = Cat(0.B, ~(0.U((offsetLen-1).W))).asSInt val max_offset = Cat(0.B, ~(0.U((offsetLen-1).W))).asSInt
val min_offset = Cat(1.B, (0.U((offsetLen-1).W))).asSInt val min_offset = Cat(1.B, (0.U((offsetLen-1).W))).asSInt
val new_target = Mux(u.pd.isBr, u.brTarget, u.target) val new_target = Mux(u.pd.isBr, u.brTarget, u.target)
val new_offset = (new_target.asSInt - u.pc.asSInt) val new_offset = (new_target.asSInt - u.pc.asSInt)
val new_extended = (new_offset > max_offset || new_offset < min_offset) val new_extended = (new_offset > max_offset || new_offset < min_offset)
val updateWay = u.brInfo.btbWriteWay val updateWay = u.bpuMeta.btbWriteWay
val updateBankIdx = btbAddr.getBank(u.pc) val updateBankIdx = btbAddr.getBank(u.pc)
val updateEBank = updateBankIdx(log2Ceil(BtbBanks)-1) // highest bit of bank idx val updateEBank = updateBankIdx(log2Ceil(BtbBanks)-1) // highest bit of bank idx
val updateRow = btbAddr.getBankIdx(u.pc) val updateRow = btbAddr.getBankIdx(u.pc)
val updateType = pdInfoToBTBtype(u.pd) val updateType = pdInfoToBTBtype(u.pd)
val metaWrite = BtbMetaEntry(btbAddr.getTag(u.pc), updateType, u.pd.isRVC) val metaWrite = BtbMetaEntry(btbAddr.getTag(u.pc), updateType, u.pd.isRVC)
val dataWrite = BtbDataEntry(new_offset, new_extended) val dataWrite = BtbDataEntry(new_offset, new_extended)
val jalFirstEncountered = !u.isMisPred && !u.brInfo.btbHitJal && updateType === BTBtype.J val jalFirstEncountered = !u.isMisPred && !u.bpuMeta.btbHitJal && updateType === BTBtype.J
val updateValid = io.update.valid && (u.isMisPred || jalFirstEncountered) val updateValid = io.update.valid && (u.isMisPred || jalFirstEncountered) && !u.isReplay
// Update btb // Update btb
for (w <- 0 until BtbWays) { for (w <- 0 until BtbWays) {
for (b <- 0 until BtbBanks) { for (b <- 0 until BtbBanks) {
meta(w)(b).io.w.req.valid := updateValid && b.U === updateBankIdx && w.U === updateWay meta(w)(b).io.w.req.valid := updateValid && b.U === updateBankIdx && w.U === updateWay
meta(w)(b).io.w.req.bits.setIdx := updateRow meta(w)(b).io.w.req.bits.setIdx := updateRow
meta(w)(b).io.w.req.bits.data := metaWrite meta(w)(b).io.w.req.bits.data := metaWrite
data(w)(b).io.w.req.valid := updateValid && b.U === updateBankIdx && w.U === updateWay data(w)(b).io.w.req.valid := updateValid && b.U === updateBankIdx && w.U === updateWay
data(w)(b).io.w.req.bits.setIdx := updateRow data(w)(b).io.w.req.bits.setIdx := updateRow
data(w)(b).io.w.req.bits.data := dataWrite data(w)(b).io.w.req.bits.data := dataWrite
} }
} }
for (b <- 0 to 1) { for (b <- 0 to 1) {
edata(b).io.w.req.valid := updateValid && new_extended && b.U === updateEBank edata(b).io.w.req.valid := updateValid && new_extended && b.U === updateEBank
edata(b).io.w.req.bits.setIdx := updateRow edata(b).io.w.req.bits.setIdx := updateRow
edata(b).io.w.req.bits.data := u.target edata(b).io.w.req.bits.data := u.target
} }
if (BPUDebug && debug) { if (BPUDebug && debug) {
val debug_verbose = true val debug_verbose = true
XSDebug("isInNextRow: ") XSDebug("isInNextRow: ")
(0 until BtbBanks).foreach(i => { (0 until BtbBanks).foreach(i => {
XSDebug(false, true.B, "%d ", if1_isInNextRow(i)) XSDebug(false, true.B, "%d ", if1_isInNextRow(i))
if (i == BtbBanks-1) { XSDebug(false, true.B, "\n") } if (i == BtbBanks-1) { XSDebug(false, true.B, "\n") }
}) })
val validLatch = RegNext(io.pc.valid) val validLatch = RegNext(io.pc.valid)
XSDebug(io.pc.valid, "read: pc=0x%x, baseBank=%d, realMask=%b\n", if1_bankAlignedPC, if1_baseBank, if1_realMask) XSDebug(io.pc.valid, "read: pc=0x%x, baseBank=%d, realMask=%b\n", if1_bankAlignedPC, if1_baseBank, if1_realMask)
XSDebug(validLatch, "read_resp: pc=0x%x, readIdx=%d-------------------------------\n", XSDebug(validLatch, "read_resp: pc=0x%x, readIdx=%d-------------------------------\n",
if2_pc, btbAddr.getIdx(if2_pc)) if2_pc, btbAddr.getIdx(if2_pc))
if (debug_verbose) { if (debug_verbose) {
for (i <- 0 until BtbBanks){ for (i <- 0 until BtbBanks){
for (j <- 0 until BtbWays) { for (j <- 0 until BtbWays) {
XSDebug(validLatch, "read_resp[w=%d][b=%d][r=%d] is valid(%d) mask(%d), tag=0x%x, offset=0x%x, type=%d, isExtend=%d, isRVC=%d\n", XSDebug(validLatch, "read_resp[w=%d][b=%d][r=%d] is valid(%d) mask(%d), tag=0x%x, offset=0x%x, type=%d, isExtend=%d, isRVC=%d\n",
j.U, i.U, if2_realRow(i), if2_metaRead(j)(i).valid, if2_realMask(i), if2_metaRead(j)(i).tag, if2_dataRead(j)(i).offset, if2_metaRead(j)(i).btbType, if2_dataRead(j)(i).extended, if2_metaRead(j)(i).isRVC) j.U, i.U, if2_realRow(i), if2_metaRead(j)(i).valid, if2_realMask(i), if2_metaRead(j)(i).tag, if2_dataRead(j)(i).offset, if2_metaRead(j)(i).btbType, if2_dataRead(j)(i).extended, if2_metaRead(j)(i).isRVC)
} }
} }
} }
// e.g: baseBank == 5 => (5, 6,..., 15, 0, 1, 2, 3, 4) // e.g: baseBank == 5 => (5, 6,..., 15, 0, 1, 2, 3, 4)
val bankIdxInOrder = VecInit((0 until BtbBanks).map(b => (if2_baseBank +& b.U)(log2Up(BtbBanks)-1,0))) val bankIdxInOrder = VecInit((0 until BtbBanks).map(b => (if2_baseBank +& b.U)(log2Up(BtbBanks)-1,0)))
for (i <- 0 until BtbBanks) { for (i <- 0 until BtbBanks) {
val idx = bankIdxInOrder(i) val idx = bankIdxInOrder(i)
XSDebug(validLatch && if2_bankHits(bankIdxInOrder(i)), "resp(%d): bank(%d) hits, tgt=%x, isRVC=%d, type=%d\n", XSDebug(validLatch && if2_bankHits(bankIdxInOrder(i)), "resp(%d): bank(%d) hits, tgt=%x, isRVC=%d, type=%d\n",
i.U, idx, io.resp.targets(i), io.resp.isRVC(i), io.resp.types(i)) i.U, idx, io.resp.targets(i), io.resp.isRVC(i), io.resp.types(i))
} }
XSDebug(updateValid, "update_req: cycle=%d, pc=0x%x, target=0x%x, misPred=%d, offset=%x, extended=%d, way=%d, bank=%d, row=0x%x\n", XSDebug(updateValid, "update_req: cycle=%d, pc=0x%x, target=0x%x, misPred=%d, offset=%x, extended=%d, way=%d, bank=%d, row=0x%x\n",
u.brInfo.debug_btb_cycle, u.pc, new_target, u.isMisPred, new_offset, new_extended, updateWay, updateBankIdx, updateRow) u.bpuMeta.debug_btb_cycle, u.pc, new_target, u.isMisPred, new_offset, new_extended, updateWay, updateBankIdx, updateRow)
for (i <- 0 until BtbBanks) { for (i <- 0 until BtbBanks) {
// Conflict when not hit and allocating a valid entry // Conflict when not hit and allocating a valid entry
val conflict = if2_metaRead(allocWays(i))(i).valid && !if2_bankHits(i) val conflict = if2_metaRead(allocWays(i))(i).valid && !if2_bankHits(i)
XSDebug(conflict, "bank(%d) is trying to allocate a valid way(%d)\n", i.U, allocWays(i)) XSDebug(conflict, "bank(%d) is trying to allocate a valid way(%d)\n", i.U, allocWays(i))
// There is another circumstance when a branch is on its way to update while another // There is another circumstance when a branch is on its way to update while another
// branch chose the same way to udpate, then after the first branch is wrote in, // branch chose the same way to udpate, then after the first branch is wrote in,
// the second branch will overwrite the first branch // the second branch will overwrite the first branch
} }
} }
} }
\ No newline at end of file
...@@ -27,8 +27,8 @@ class Frontend extends XSModule { ...@@ -27,8 +27,8 @@ class Frontend extends XSModule {
//backend //backend
ifu.io.redirect <> io.backend.redirect ifu.io.redirect <> io.backend.redirect
ifu.io.inOrderBrInfo <> io.backend.inOrderBrInfo ifu.io.cfiUpdateInfo <> io.backend.cfiUpdateInfo
ifu.io.outOfOrderBrInfo <> io.backend.outOfOrderBrInfo // ifu.io.cfiUpdateInfo <> io.backend.cfiUpdateInfo
//icache //icache
ifu.io.icacheResp <> icache.io.resp ifu.io.icacheResp <> icache.io.resp
icache.io.req <> ifu.io.icacheReq icache.io.req <> ifu.io.icacheReq
......
...@@ -70,8 +70,8 @@ class IFUIO extends XSBundle ...@@ -70,8 +70,8 @@ class IFUIO extends XSBundle
{ {
val fetchPacket = DecoupledIO(new FetchPacket) val fetchPacket = DecoupledIO(new FetchPacket)
val redirect = Flipped(ValidIO(UInt(VAddrBits.W))) val redirect = Flipped(ValidIO(UInt(VAddrBits.W)))
val outOfOrderBrInfo = Flipped(ValidIO(new BranchUpdateInfo)) // val cfiUpdateInfo = Flipped(ValidIO(new CfiUpdateInfo))
val inOrderBrInfo = Flipped(ValidIO(new BranchUpdateInfo)) val cfiUpdateInfo = Flipped(ValidIO(new CfiUpdateInfo))
val icacheReq = DecoupledIO(new ICacheReq) val icacheReq = DecoupledIO(new ICacheReq)
val icacheResp = Flipped(DecoupledIO(new ICacheResp)) val icacheResp = Flipped(DecoupledIO(new ICacheResp))
val icacheFlush = Output(UInt(2.W)) val icacheFlush = Output(UInt(2.W))
...@@ -355,11 +355,11 @@ class IFU extends XSModule with HasIFUConst ...@@ -355,11 +355,11 @@ class IFU extends XSModule with HasIFUConst
val cfiUpdate = io.cfiUpdateInfo
when (io.outOfOrderBrInfo.valid && io.outOfOrderBrInfo.bits.isMisPred) { when (cfiUpdate.valid && (cfiUpdate.bits.isMisPred || cfiUpdate.bits.isReplay)) {
val b = io.outOfOrderBrInfo.bits val b = cfiUpdate.bits
val oldGh = b.brInfo.hist val oldGh = b.bpuMeta.hist
val sawNTBr = b.brInfo.sawNotTakenBranch val sawNTBr = b.bpuMeta.sawNotTakenBranch
val isBr = b.pd.isBr val isBr = b.pd.isBr
val taken = b.taken val taken = b.taken
val updatedGh = oldGh.update(sawNTBr, isBr && taken) val updatedGh = oldGh.update(sawNTBr, isBr && taken)
...@@ -398,11 +398,7 @@ class IFU extends XSModule with HasIFUConst ...@@ -398,11 +398,7 @@ class IFU extends XSModule with HasIFUConst
io.icacheFlush := Cat(if3_flush, if2_flush) io.icacheFlush := Cat(if3_flush, if2_flush)
val inOrderBrHist = io.inOrderBrInfo.bits.brInfo.predHist bpu.io.cfiUpdateInfo <> io.cfiUpdateInfo
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.flush := Cat(if4_flush, if3_flush, if2_flush) // bpu.io.flush := Cat(if4_flush, if3_flush, if2_flush)
bpu.io.flush := VecInit(if2_flush, if3_flush, if4_flush) bpu.io.flush := VecInit(if2_flush, if3_flush, if4_flush)
...@@ -465,9 +461,9 @@ class IFU extends XSModule with HasIFUConst ...@@ -465,9 +461,9 @@ class IFU extends XSModule with HasIFUConst
when (if4_bp.taken) { when (if4_bp.taken) {
fetchPacketWire.pnpc(if4_bp.jmpIdx) := if4_bp.target fetchPacketWire.pnpc(if4_bp.jmpIdx) := if4_bp.target
} }
fetchPacketWire.brInfo := bpu.io.branchInfo fetchPacketWire.bpuMeta := bpu.io.bpuMeta
(0 until PredictWidth).foreach(i => fetchPacketWire.brInfo(i).hist := final_gh) (0 until PredictWidth).foreach(i => fetchPacketWire.bpuMeta(i).hist := final_gh)
(0 until PredictWidth).foreach(i => fetchPacketWire.brInfo(i).predHist := if4_predHist.asTypeOf(new GlobalHistory)) (0 until PredictWidth).foreach(i => fetchPacketWire.bpuMeta(i).predHist := if4_predHist.asTypeOf(new GlobalHistory))
fetchPacketWire.pd := if4_pd.pd fetchPacketWire.pd := if4_pd.pd
fetchPacketWire.ipf := if4_ipf fetchPacketWire.ipf := if4_ipf
fetchPacketWire.acf := if4_acf fetchPacketWire.acf := if4_acf
......
...@@ -20,7 +20,7 @@ class Ibuffer extends XSModule { ...@@ -20,7 +20,7 @@ class Ibuffer extends XSModule {
val inst = UInt(32.W) val inst = UInt(32.W)
val pc = UInt(VAddrBits.W) val pc = UInt(VAddrBits.W)
val pnpc = UInt(VAddrBits.W) val pnpc = UInt(VAddrBits.W)
val brInfo = new BranchInfo val brInfo = new BpuMeta
val pd = new PreDecodeInfo val pd = new PreDecodeInfo
val ipf = Bool() val ipf = Bool()
val acf = Bool() val acf = Bool()
...@@ -63,7 +63,7 @@ class Ibuffer extends XSModule { ...@@ -63,7 +63,7 @@ class Ibuffer extends XSModule {
inWire.inst := io.in.bits.instrs(i) inWire.inst := io.in.bits.instrs(i)
inWire.pc := io.in.bits.pc(i) inWire.pc := io.in.bits.pc(i)
inWire.pnpc := io.in.bits.pnpc(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.pd := io.in.bits.pd(i)
inWire.ipf := io.in.bits.ipf inWire.ipf := io.in.bits.ipf
inWire.acf := io.in.bits.acf inWire.acf := io.in.bits.acf
...@@ -98,7 +98,7 @@ class Ibuffer extends XSModule { ...@@ -98,7 +98,7 @@ class Ibuffer extends XSModule {
io.out(i).bits.brUpdate.pc := outWire.pc io.out(i).bits.brUpdate.pc := outWire.pc
io.out(i).bits.brUpdate.pnpc := outWire.pnpc io.out(i).bits.brUpdate.pnpc := outWire.pnpc
io.out(i).bits.brUpdate.pd := outWire.pd 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 io.out(i).bits.crossPageIPFFix := outWire.crossPageIPFFix
} }
head_ptr := head_ptr + io.out.map(_.fire).fold(0.U(log2Up(DecodeWidth).W))(_+_) head_ptr := head_ptr + io.out.map(_.fire).fold(0.U(log2Up(DecodeWidth).W))(_+_)
......
...@@ -309,13 +309,13 @@ class LoopPredictor extends BasePredictor with LTBParams { ...@@ -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.idx := Mux(isInNextRow(i), baseRow + 1.U, baseRow)
ltbs(i).io.req.tag := realTags(i) ltbs(i).io.req.tag := realTags(i)
// ltbs(i).io.outMask := outMask(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.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.ui.isMisPred ltbs(i).io.update.bits.misPred := io.update.bits.isMisPred
ltbs(i).io.update.bits.pc := io.update.bits.ui.pc ltbs(i).io.update.bits.pc := io.update.bits.pc
ltbs(i).io.update.bits.meta := io.update.bits.ui.brInfo.specCnt ltbs(i).io.update.bits.meta := io.update.bits.bpuMeta.specCnt
ltbs(i).io.update.bits.taken := io.update.bits.ui.taken ltbs(i).io.update.bits.taken := io.update.bits.taken
ltbs(i).io.update.bits.brTag := io.update.bits.ui.brTag ltbs(i).io.update.bits.brTag := io.update.bits.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.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)) val ltbResps = VecInit((0 until PredictWidth).map(i => ltbs(i).io.resp))
......
...@@ -28,9 +28,9 @@ class RAS extends BasePredictor ...@@ -28,9 +28,9 @@ class RAS extends BasePredictor
val callIdx = Flipped(ValidIO(UInt(log2Ceil(PredictWidth).W))) val callIdx = Flipped(ValidIO(UInt(log2Ceil(PredictWidth).W)))
val isRVC = Input(Bool()) val isRVC = Input(Bool())
val isLastHalfRVI = Input(Bool()) val isLastHalfRVI = Input(Bool())
val recover = Flipped(ValidIO(new BranchUpdateInfo)) val recover = Flipped(ValidIO(new CfiUpdateInfo))
val out = ValidIO(new RASResp) val out = ValidIO(new RASResp)
val branchInfo = Output(new RASBranchInfo) val meta = Output(new RASBranchInfo)
} }
class RASEntry() extends XSBundle { class RASEntry() extends XSBundle {
...@@ -187,7 +187,7 @@ class RAS extends BasePredictor ...@@ -187,7 +187,7 @@ class RAS extends BasePredictor
// TODO: back-up stack for ras // TODO: back-up stack for ras
// use checkpoint to recover 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) val copy_next = RegNext(copy_valid)
spec_ras.copy_valid := copy_next spec_ras.copy_valid := copy_next
spec_ras.copy_in_mem := commit_ras.copy_out_mem spec_ras.copy_in_mem := commit_ras.copy_out_mem
...@@ -197,9 +197,9 @@ class RAS extends BasePredictor ...@@ -197,9 +197,9 @@ class RAS extends BasePredictor
commit_ras.copy_in_sp := DontCare commit_ras.copy_in_sp := DontCare
//no need to pass the ras branchInfo //no need to pass the ras branchInfo
io.branchInfo.rasSp := DontCare io.meta.rasSp := DontCare
io.branchInfo.rasTopCtr := DontCare io.meta.rasTopCtr := DontCare
io.branchInfo.rasToqAddr := DontCare io.meta.rasToqAddr := DontCare
if (BPUDebug && debug) { if (BPUDebug && debug) {
val spec_debug = spec.debugIO val spec_debug = spec.debugIO
......
...@@ -448,12 +448,12 @@ class Tage extends BaseTage { ...@@ -448,12 +448,12 @@ class Tage extends BaseTage {
val debug_hist_s2 = RegEnable(io.hist, enable=io.pc.valid) val debug_hist_s2 = RegEnable(io.hist, enable=io.pc.valid)
val debug_hist_s3 = RegEnable(debug_hist_s2, enable=io.s3Fire) val debug_hist_s3 = RegEnable(debug_hist_s2, enable=io.s3Fire)
val u = io.update.bits.ui val u = io.update.bits
val updateValid = io.update.valid val updateValid = io.update.valid && !io.update.bits.isReplay
val updateHist = io.update.bits.hist val updateHist = u.bpuMeta.predHist.asUInt
val updateIsBr = u.pd.isBr val updateIsBr = u.pd.isBr
val updateMeta = u.brInfo.tageMeta val updateMeta = u.bpuMeta.tageMeta
val updateMisPred = u.isMisPred && updateIsBr val updateMisPred = u.isMisPred && updateIsBr
val updateMask = WireInit(0.U.asTypeOf(Vec(TageNTables, Vec(TageBanks, Bool())))) val updateMask = WireInit(0.U.asTypeOf(Vec(TageNTables, Vec(TageBanks, Bool()))))
...@@ -475,7 +475,7 @@ class Tage extends BaseTage { ...@@ -475,7 +475,7 @@ class Tage extends BaseTage {
scUpdateTaken := DontCare scUpdateTaken := DontCare
scUpdateOldCtrs := DontCare scUpdateOldCtrs := DontCare
val updateSCMeta = u.brInfo.tageMeta.scMeta val updateSCMeta = u.bpuMeta.tageMeta.scMeta
val updateTageMisPred = updateMeta.taken =/= u.taken && updateIsBr val updateTageMisPred = updateMeta.taken =/= u.taken && updateIsBr
val updateBank = u.pc(log2Ceil(TageBanks), 1) val updateBank = u.pc(log2Ceil(TageBanks), 1)
...@@ -641,7 +641,7 @@ class Tage extends BaseTage { ...@@ -641,7 +641,7 @@ class Tage extends BaseTage {
// use fetch pc instead of instruction pc // use fetch pc instead of instruction pc
tables(i).io.update.pc := u.pc tables(i).io.update.pc := u.pc
tables(i).io.update.hist := updateHist 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) { for (i <- 0 until SCNTables) {
...@@ -651,14 +651,14 @@ class Tage extends BaseTage { ...@@ -651,14 +651,14 @@ class Tage extends BaseTage {
scTables(i).io.update.oldCtr := scUpdateOldCtrs(i) scTables(i).io.update.oldCtr := scUpdateOldCtrs(i)
scTables(i).io.update.pc := u.pc scTables(i).io.update.pc := u.pc
scTables(i).io.update.hist := updateHist 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) { if (BPUDebug && debug) {
val m = updateMeta 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.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(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", XSDebug(RegNext(io.s3Fire), "s3FireOnLastCycle: resp: pc=%x, hist=%x, hits=%b, takens=%b\n",
......
...@@ -43,12 +43,12 @@ class MicroBTB extends BasePredictor ...@@ -43,12 +43,12 @@ class MicroBTB extends BasePredictor
class MicroBTBIO extends DefaultBasePredictorIO class MicroBTBIO extends DefaultBasePredictorIO
{ {
val out = Output(new MicroBTBResp) // val out = Output(new MicroBTBResp) //
val uBTBBranchInfo = Output(new MicroBTBBranchInfo) val uBTBMeta = Output(new MicroBTBBranchInfo)
} }
override val debug = true override val debug = true
override val io = IO(new MicroBTBIO) 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 getTag(pc: UInt) = (pc >> untaggedBits)(tagSize-1, 0)
def getBank(pc: UInt) = pc(log2Ceil(PredictWidth) ,1) def getBank(pc: UInt) = pc(log2Ceil(PredictWidth) ,1)
...@@ -251,13 +251,13 @@ class MicroBTB extends BasePredictor ...@@ -251,13 +251,13 @@ class MicroBTB extends BasePredictor
//uBTB update //uBTB update
//backend should send fetch pc to 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_pc = u.pc
val update_br_idx = u.fetchIdx val update_br_idx = u.fetchIdx
val update_br_offset = (update_br_idx << 1).asUInt() val update_br_offset = (update_br_idx << 1).asUInt()
val update_fetch_pc = update_br_pc - update_br_offset val update_fetch_pc = update_br_pc - update_br_offset
val update_write_way = u.brInfo.ubtbWriteWay val update_write_way = u.bpuMeta.ubtbWriteWay
val update_hits = u.brInfo.ubtbHits val update_hits = u.bpuMeta.ubtbHits
val update_taken = u.taken val update_taken = u.taken
val update_bank = getBank(update_br_pc) val update_bank = getBank(update_br_pc)
...@@ -268,9 +268,9 @@ class MicroBTB extends BasePredictor ...@@ -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 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 jalFirstEncountered = !u.isMisPred && !u.bpuMeta.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 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)//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 //write btb target when miss prediction
// when(entry_write_valid) // when(entry_write_valid)
// { // {
......
...@@ -17,14 +17,14 @@ with HasPartialDecoupledDriver { ...@@ -17,14 +17,14 @@ with HasPartialDecoupledDriver {
test(new MicroBTB) { c => test(new MicroBTB) { c =>
def genUpdateReq(pc: Long,target: Long,taken: Boolean,fetchIdx: Int,isMiss: Boolean,write_way: Int,hit: Boolean) = { 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.valid.poke(true.B)
c.io.update.bits.ui.pc.poke(pc.U) c.io.update.bits.pc.poke(pc.U)
c.io.update.bits.ui.target.poke(target.U) c.io.update.bits.target.poke(target.U)
c.io.update.bits.ui.taken.poke(taken.B) c.io.update.bits.taken.poke(taken.B)
c.io.update.bits.ui.fetchIdx.poke(fetchIdx.U) c.io.update.bits.fetchIdx.poke(fetchIdx.U)
c.io.update.bits.ui.isMisPred.poke(isMiss.B) c.io.update.bits.isMisPred.poke(isMiss.B)
c.io.update.bits.ui.brInfo.ubtbWriteWay.poke(write_way.U) c.io.update.bits.bpuMeta.ubtbWriteWay.poke(write_way.U)
c.io.update.bits.ui.brInfo.ubtbHits.poke(hit.B) c.io.update.bits.bpuMeta.ubtbHits.poke(hit.B)
c.io.update.bits.ui.pd.brType.poke(BrType.branch) c.io.update.bits.pd.brType.poke(BrType.branch)
} }
def genReadReq(fetchpc: Long){ def genReadReq(fetchpc: Long){
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册