提交 d42f3562 编写于 作者: L Lingrui98

ibuffer: remove pnpc

ifu: reconsider prediction of prevHalfInstr
     now we do not need to gather meta from the last packet
     because we update with packet, thus updating in the
     correct slot
上级 6ea2c2ab
......@@ -25,7 +25,6 @@ class FetchPacket extends XSBundle {
val pdmask = UInt(PredictWidth.W)
// val pc = UInt(VAddrBits.W)
val pc = Vec(PredictWidth, UInt(VAddrBits.W))
val pnpc = Vec(PredictWidth, UInt(VAddrBits.W))
val pd = Vec(PredictWidth, new PreDecodeInfo)
val ipf = Bool()
val acf = Bool()
......@@ -81,59 +80,32 @@ class BranchPrediction extends XSBundle with HasIFUConst {
val jalMask = UInt(PredictWidth.W)
val targets = Vec(PredictWidth, UInt(VAddrBits.W))
// marks the last 2 bytes of this fetch packet
// val endsAtTheEndOfFirstBank = Bool()
// val endsAtTheEndOfLastBank = Bool()
// half RVI could only start at the end of a packet
val hasHalfRVI = Bool()
// assumes that only one of the two conditions could be true
def lastHalfRVIMask = Cat(hasHalfRVI.asUInt, 0.U((PredictWidth - 1).W))
def lastHalfRVIClearMask = ~lastHalfRVIMask
// is taken from half RVI
def lastHalfRVITaken = takens(PredictWidth - 1) && hasHalfRVI
def lastHalfRVIIdx = (PredictWidth - 1).U
// should not be used if not lastHalfRVITaken
def lastHalfRVITarget = targets(PredictWidth - 1)
def realTakens = takens & lastHalfRVIClearMask
def realBrMask = brMask & lastHalfRVIClearMask
def realJalMask = jalMask & lastHalfRVIClearMask
def brNotTakens = (~takens & realBrMask)
def brNotTakens = (~takens & brMask)
def sawNotTakenBr = VecInit((0 until PredictWidth).map(i =>
(if (i == 0) false.B else ParallelORR(brNotTakens(i - 1, 0)))))
// def hasNotTakenBrs = (brNotTakens & LowerMaskFromLowest(realTakens)).orR
def unmaskedJmpIdx = ParallelPriorityEncoder(takens)
// if not taken before the half RVI inst
def saveHalfRVI = hasHalfRVI && !(ParallelORR(takens(PredictWidth - 2, 0)))
// could get PredictWidth-1 when only the first bank is valid
def jmpIdx = ParallelPriorityEncoder(realTakens)
def jmpIdx = ParallelPriorityEncoder(takens)
// only used when taken
def target = {
val generator = new PriorityMuxGenerator[UInt]
generator.register(realTakens.asBools, targets, List.fill(PredictWidth)(None))
generator.register(takens.asBools, targets, List.fill(PredictWidth)(None))
generator()
}
def taken = ParallelORR(realTakens)
def taken = ParallelORR(takens)
def takenOnBr = taken && ParallelPriorityMux(realTakens, realBrMask.asBools)
def takenOnBr = taken && ParallelPriorityMux(takens, brMask.asBools)
def hasNotTakenBrs = Mux(taken, ParallelPriorityMux(realTakens, sawNotTakenBr), ParallelORR(brNotTakens))
def hasNotTakenBrs = Mux(taken, ParallelPriorityMux(takens, sawNotTakenBr), ParallelORR(brNotTakens))
}
class PredictorAnswer extends XSBundle {
......
......@@ -246,8 +246,6 @@ class BPUStage3 extends BPUStage {
class S3IO extends XSBundle {
val predecode = Input(new Predecode)
val realMask = Input(UInt(PredictWidth.W))
val prevHalf = Flipped(ValidIO(new PrevHalfInstr))
val redirect = Flipped(ValidIO(new Redirect))
}
val s3IO = IO(new S3IO)
......@@ -259,7 +257,6 @@ class BPUStage3 extends BPUStage {
val loopResp = io.in.resp.loop.exit
// realMask is in it
val pdMask = s3IO.predecode.mask
val pdLastHalf = s3IO.predecode.lastHalf
val pds = s3IO.predecode.pd
......@@ -280,11 +277,9 @@ class BPUStage3 extends BPUStage {
val brPred = (if(EnableBPD) tageTakens else bimTakens).asUInt
val loopRes = (if (EnableLoop) loopResp else VecInit(Fill(PredictWidth, 0.U(1.W)))).asUInt
val prevHalfTaken = s3IO.prevHalf.valid && s3IO.prevHalf.bits.taken && HasCExtension.B
val prevHalfTakenMask = prevHalfTaken.asUInt
val brTakens = ((brs & brPred | prevHalfTakenMask) & ~loopRes)
val brTakens = ((brs & brPred) & ~loopRes)
// we should provide btb resp as well
btbHits := btbResp.hits.asUInt | prevHalfTakenMask
btbHits := btbResp.hits.asUInt
// predict taken only if btb has a target, jal and br targets will be provided by IFU
takens := VecInit((0 until PredictWidth).map(i => jalrs(i) && btbHits(i) || (jals(i) || brTakens(i))))
......@@ -331,19 +326,6 @@ class BPUStage3 extends BPUStage {
}
// we should provide the prediction for the first half RVI of the end of a fetch packet
// branch taken information would be lost in the prediction of the next packet,
// so we preserve this information here
when (hasHalfRVI && btbResp.isBrs(PredictWidth-1) && btbHits(PredictWidth-1) && HasCExtension.B) {
takens(PredictWidth-1) := brPred(PredictWidth-1) && !loopRes(PredictWidth-1)
}
// targets would be lost as well, since it is from btb
// unless it is a ret, which target is from ras
when (prevHalfTaken && !rets(0) && HasCExtension.B) {
targets(0) := s3IO.prevHalf.bits.target
}
// Wrap tage resp and tage meta in
// This is ugly
io.out.resp.tage <> io.in.resp.tage
......@@ -362,7 +344,7 @@ class BPUStage3 extends BPUStage {
}
XSDebug(p"brs:${Binary(brs)} jals:${Binary(jals)} jalrs:${Binary(jalrs)} calls:${Binary(calls)} rets:${Binary(rets)} rvcs:${Binary(RVCs)}\n")
XSDebug(p"callIdx:${callIdx} retIdx:${retIdx}\n")
XSDebug(p"brPred:${Binary(brPred)} loopRes:${Binary(loopRes)} prevHalfTaken:${prevHalfTaken} brTakens:${Binary(brTakens)}\n")
XSDebug(p"brPred:${Binary(brPred)} loopRes:${Binary(loopRes)} brTakens:${Binary(brTakens)}\n")
}
if (EnbaleCFIPredLog) {
......@@ -405,8 +387,6 @@ abstract class BaseBPU extends XSModule with BranchPredictorComponents
val out = Vec(3, Output(new BranchPrediction))
// from if4
val predecode = Input(new Predecode)
val realMask = Input(UInt(PredictWidth.W))
val prevHalf = Flipped(ValidIO(new PrevHalfInstr))
// to if4, some bpu info used for updating
val brInfo = Output(new BrInfo)
})
......@@ -560,10 +540,6 @@ class BPU extends BaseBPU {
s3.s3IO.predecode <> io.predecode
s3.s3IO.realMask := io.realMask
s3.s3IO.prevHalf := io.prevHalf
s3.s3IO.redirect <> io.redirect
if (BPUDebug) {
......
......@@ -89,16 +89,10 @@ class IFUIO extends XSBundle
}
class PrevHalfInstr extends XSBundle {
val taken = Bool()
val ghInfo = new GlobalHistory()
val fetchpc = UInt(VAddrBits.W) // only for debug
val idx = UInt(VAddrBits.W) // only for debug
val pc = UInt(VAddrBits.W)
val npc = UInt(VAddrBits.W)
val target = UInt(VAddrBits.W)
val instr = UInt(16.W)
val ipf = Bool()
val meta = new BpuMeta
}
@chiselName
......@@ -235,8 +229,7 @@ class IFU extends XSModule with HasIFUConst with HasCircularQueuePtrHelper
comp.io.res
}
val if3_predTakenRedirectVec = VecInit((0 until PredictWidth).map(i => !if3_pendingPrevHalfInstr && if3_bp.realTakens(i) && if3_nextValidPCNotEquals(if3_bp.targets(i))))
val if3_prevHalfMetRedirect = if3_pendingPrevHalfInstr && if3_prevHalfInstrMet && if3_prevHalfInstr.bits.taken && if3_nextValidPCNotEquals(if3_prevHalfInstr.bits.target)
val if3_predTakenRedirectVec = VecInit((0 until PredictWidth).map(i => !if3_pendingPrevHalfInstr && if3_bp.takens(i) && if3_nextValidPCNotEquals(if3_bp.targets(i))))
val if3_prevHalfNotMetRedirect = if3_pendingPrevHalfInstr && !if3_prevHalfInstrMet && if3_nextValidPCNotEquals(if3_prevHalfInstr.bits.npc)
val if3_predTakenRedirect = ParallelOR(if3_predTakenRedirectVec)
val if3_predNotTakenRedirect = !if3_pendingPrevHalfInstr && !if3_bp.taken && if3_nextValidPCNotEquals(if3_snpc)
......@@ -244,9 +237,6 @@ class IFU extends XSModule with HasIFUConst with HasCircularQueuePtrHelper
// val if3_ghInfoNotIdenticalRedirect = !if3_pendingPrevHalfInstr && if3_GHInfo =/= if3_lastGHInfo && enableGhistRepair.B
if3_redirect := if3_valid && (
// prevHalf is consumed but the next packet is not where it meant to be
// we do not handle this condition because of the burden of building a correct GHInfo
// prevHalfMetRedirect ||
// prevHalf does not match if3_pc and the next fetch packet is not snpc
if3_prevHalfNotMetRedirect && HasCExtension.B ||
// pred taken and next fetch packet is not the predicted target
......@@ -330,7 +320,6 @@ class IFU extends XSModule with HasIFUConst with HasCircularQueuePtrHelper
val if4_prevHalfConsumed = if4_prevHalfInstrMet && if4_fire
val if4_prevHalfFlush = if4_flush
val if4_takenPrevHalf = WireInit(if4_prevHalfInstrMet && if4_prevHalfInstr.bits.taken)
when (if4_prevHalfFlush) {
if4_prevHalfInstr.valid := false.B
}.elsewhen (if3_prevHalfConsumed) {
......@@ -344,19 +333,12 @@ class IFU extends XSModule with HasIFUConst with HasCircularQueuePtrHelper
}
prevHalfInstrReq.valid := if4_fire && if4_bp.saveHalfRVI && HasCExtension.B
val idx = if4_bp.lastHalfRVIIdx
// // this is result of the last half RVI
prevHalfInstrReq.bits.taken := if4_bp.lastHalfRVITaken
prevHalfInstrReq.bits.ghInfo := if4_gh
prevHalfInstrReq.bits.fetchpc := if4_pc
prevHalfInstrReq.bits.idx := idx
prevHalfInstrReq.bits.pc := if4_pd.pc(idx)
prevHalfInstrReq.bits.npc := if4_pd.pc(idx) + 2.U
prevHalfInstrReq.bits.target := if4_bp.lastHalfRVITarget
prevHalfInstrReq.bits.instr := if4_pd.instrs(idx)(15, 0)
prevHalfInstrReq.bits.pc := if4_pd.pc(PredictWidth-1)
prevHalfInstrReq.bits.npc := snpc(if4_pc)
prevHalfInstrReq.bits.instr := if4_pd.instrs(PredictWidth-1)(15, 0)
prevHalfInstrReq.bits.ipf := if4_ipf
prevHalfInstrReq.bits.meta := bpu.io.brInfo.metas(idx)
class IF4_PC_COMP extends XSModule {
val io = IO(new Bundle {
......@@ -381,7 +363,7 @@ class IFU extends XSModule with HasIFUConst with HasCircularQueuePtrHelper
comp.io.res
}
val if4_predTakenRedirectVec = VecInit((0 until PredictWidth).map(i => if4_bp.realTakens(i) && if4_nextValidPCNotEquals(if4_bp.targets(i))))
val if4_predTakenRedirectVec = VecInit((0 until PredictWidth).map(i => if4_bp.takens(i) && if4_nextValidPCNotEquals(if4_bp.targets(i))))
val if4_prevHalfNextNotMet = hasPrevHalfInstrReq && if4_nextValidPCNotEquals(prevHalfInstrReq.bits.pc+2.U)
val if4_predTakenRedirect = ParallelORR(if4_predTakenRedirectVec)
......@@ -437,10 +419,6 @@ class IFU extends XSModule with HasIFUConst with HasCircularQueuePtrHelper
toFtqBuf.metas := bpu.io.brInfo.metas
toFtqBuf.hasLastPrev := if4_pendingPrevHalfInstr
// save it for update
when (if4_pendingPrevHalfInstr) {
toFtqBuf.metas(0) := if4_prevHalfInstr.bits.meta
}
val if4_jmpIdx = WireInit(if4_bp.jmpIdx)
val if4_taken = WireInit(if4_bp.taken)
val if4_real_valids = if4_pd.mask &
......@@ -516,8 +494,6 @@ class IFU extends XSModule with HasIFUConst with HasCircularQueuePtrHelper
bpu.io.predecode.lastHalf := if4_pd.lastHalf
bpu.io.predecode.pd := if4_pd.pd
bpu.io.predecode.hasLastHalfRVI := if4_prevHalfInstrMet
bpu.io.realMask := if4_mask
bpu.io.prevHalf := if4_prevHalfInstr
when (if3_prevHalfInstrMet && icacheResp.ipf && !if3_prevHalfInstr.bits.ipf) {
......@@ -538,10 +514,6 @@ class IFU extends XSModule with HasIFUConst with HasCircularQueuePtrHelper
fetchPacketWire.instrs := expandedInstrs
fetchPacketWire.pc := if4_pd.pc
(0 until PredictWidth).foreach(i => fetchPacketWire.pnpc(i) := if4_pd.pc(i) + Mux(if4_pd.pd(i).isRVC, 2.U, 4.U))
when (if4_bp.taken) {
fetchPacketWire.pnpc(if4_bp.jmpIdx) := if4_bp.target
}
fetchPacketWire.pdmask := if4_pd.mask
fetchPacketWire.pd := if4_pd.pd
......@@ -551,7 +523,7 @@ class IFU extends XSModule with HasIFUConst with HasCircularQueuePtrHelper
fetchPacketWire.ftqPtr := if4_ftqEnqPtr
// predTaken Vec
fetchPacketWire.pred_taken := if4_bp.realTakens
fetchPacketWire.pred_taken := if4_bp.takens
io.fetchPacket.bits := fetchPacketWire
io.fetchPacket.valid := fetchPacketValid
......@@ -604,11 +576,11 @@ class IFU extends XSModule with HasIFUConst with HasCircularQueuePtrHelper
XSDebug("[IF3][icacheResp] v=%d r=%d pc=%x mask=%b\n", icache.io.resp.valid, icache.io.resp.ready, icache.io.resp.bits.pc, icache.io.resp.bits.mask)
XSDebug("[IF3][bp] taken=%d jmpIdx=%d hasNTBrs=%d target=%x saveHalfRVI=%d\n", if3_bp.taken, if3_bp.jmpIdx, if3_bp.hasNotTakenBrs, if3_bp.target, if3_bp.saveHalfRVI)
XSDebug("[IF3][redirect]: v=%d, prevMet=%d, prevNMet=%d, predT=%d, predNT=%d\n", if3_redirect, if3_prevHalfMetRedirect, if3_prevHalfNotMetRedirect, if3_predTakenRedirect, if3_predNotTakenRedirect)
XSDebug("[IF3][redirect]: v=%d, prevNMet=%d, predT=%d, predNT=%d\n", if3_redirect, if3_prevHalfNotMetRedirect, if3_predTakenRedirect, if3_predNotTakenRedirect)
// XSDebug("[IF3][prevHalfInstr] v=%d redirect=%d fetchpc=%x idx=%d tgt=%x taken=%d instr=%x\n\n",
// prev_half_valid, prev_half_redirect, prev_half_fetchpc, prev_half_idx, prev_half_tgt, prev_half_taken, prev_half_instr)
XSDebug("[IF3][if3_prevHalfInstr] v=%d taken=%d fetchpc=%x idx=%d pc=%x npc=%x tgt=%x instr=%x ipf=%d\n\n",
if3_prevHalfInstr.valid, if3_prevHalfInstr.bits.taken, if3_prevHalfInstr.bits.fetchpc, if3_prevHalfInstr.bits.idx, if3_prevHalfInstr.bits.pc, if3_prevHalfInstr.bits.npc, if3_prevHalfInstr.bits.target, if3_prevHalfInstr.bits.instr, if3_prevHalfInstr.bits.ipf)
XSDebug("[IF3][if3_prevHalfInstr] v=%d pc=%x npc=%x instr=%x ipf=%d\n\n",
if3_prevHalfInstr.valid, if3_prevHalfInstr.bits.pc, if3_prevHalfInstr.bits.npc, if3_prevHalfInstr.bits.instr, if3_prevHalfInstr.bits.ipf)
if3_gh.debug("if3")
XSDebug("[IF4][predecode] mask=%b\n", if4_pd.mask)
......@@ -616,19 +588,18 @@ class IFU extends XSModule with HasIFUConst with HasCircularQueuePtrHelper
XSDebug("[IF4][bp] taken=%d jmpIdx=%d hasNTBrs=%d target=%x saveHalfRVI=%d\n", if4_bp.taken, if4_bp.jmpIdx, if4_bp.hasNotTakenBrs, if4_bp.target, if4_bp.saveHalfRVI)
XSDebug("[IF4][redirect]: v=%d, prevNotMet=%d, predT=%d, predNT=%d\n", if4_redirect, if4_prevHalfNextNotMet, if4_predTakenRedirect, if4_predNotTakenRedirect)
XSDebug(if4_pd.pd(if4_bp.jmpIdx).isJal && if4_bp.taken, "[IF4] cfi is jal! instr=%x target=%x\n", if4_instrs(if4_bp.jmpIdx), if4_jal_tgts(if4_bp.jmpIdx))
XSDebug("[IF4][ prevHalfInstrReq] v=%d taken=%d fetchpc=%x idx=%d pc=%x npc=%x tgt=%x instr=%x ipf=%d\n",
prevHalfInstrReq.valid, prevHalfInstrReq.bits.taken, prevHalfInstrReq.bits.fetchpc, prevHalfInstrReq.bits.idx, prevHalfInstrReq.bits.pc, prevHalfInstrReq.bits.npc, prevHalfInstrReq.bits.target, prevHalfInstrReq.bits.instr, prevHalfInstrReq.bits.ipf)
XSDebug("[IF4][if4_prevHalfInstr] v=%d taken=%d fetchpc=%x idx=%d pc=%x npc=%x tgt=%x instr=%x ipf=%d\n",
if4_prevHalfInstr.valid, if4_prevHalfInstr.bits.taken, if4_prevHalfInstr.bits.fetchpc, if4_prevHalfInstr.bits.idx, if4_prevHalfInstr.bits.pc, if4_prevHalfInstr.bits.npc, if4_prevHalfInstr.bits.target, if4_prevHalfInstr.bits.instr, if4_prevHalfInstr.bits.ipf)
XSDebug("[IF4][ prevHalfInstrReq] v=%d pc=%x npc=%x instr=%x ipf=%d\n",
prevHalfInstrReq.valid, prevHalfInstrReq.bits.pc, prevHalfInstrReq.bits.npc, prevHalfInstrReq.bits.instr, prevHalfInstrReq.bits.ipf)
XSDebug("[IF4][if4_prevHalfInstr] v=%d pc=%x npc=%x instr=%x ipf=%d\n",
if4_prevHalfInstr.valid, if4_prevHalfInstr.bits.pc, if4_prevHalfInstr.bits.npc, if4_prevHalfInstr.bits.instr, if4_prevHalfInstr.bits.ipf)
if4_gh.debug("if4")
XSDebug(io.fetchPacket.fire(), "[IF4][fetchPacket] v=%d r=%d mask=%b ipf=%d acf=%d crossPageIPF=%d\n",
io.fetchPacket.valid, io.fetchPacket.ready, io.fetchPacket.bits.mask, io.fetchPacket.bits.ipf, io.fetchPacket.bits.acf, io.fetchPacket.bits.crossPageIPFFix)
for (i <- 0 until PredictWidth) {
XSDebug(io.fetchPacket.fire(), "[IF4][fetchPacket] %b %x pc=%x pnpc=%x pd: rvc=%d brType=%b call=%d ret=%d\n",
XSDebug(io.fetchPacket.fire(), "[IF4][fetchPacket] %b %x pc=%x pd: rvc=%d brType=%b call=%d ret=%d\n",
io.fetchPacket.bits.mask(i),
io.fetchPacket.bits.instrs(i),
io.fetchPacket.bits.pc(i),
io.fetchPacket.bits.pnpc(i),
io.fetchPacket.bits.pd(i).isRVC,
io.fetchPacket.bits.pd(i).brType,
io.fetchPacket.bits.pd(i).isCall,
......
......@@ -31,7 +31,6 @@ class Ibuffer extends XSModule with HasCircularQueuePtrHelper {
class IBufEntry extends XSBundle {
val inst = UInt(32.W)
val pc = UInt(VAddrBits.W)
val pnpc = UInt(VAddrBits.W)
val pd = new PreDecodeInfo
val ipf = Bool()
val acf = Bool()
......@@ -94,7 +93,6 @@ class Ibuffer extends XSModule with HasCircularQueuePtrHelper {
when(io.in.bits.mask(i)) {
inWire.inst := io.in.bits.instrs(i)
inWire.pc := io.in.bits.pc(i)
inWire.pnpc := io.in.bits.pnpc(i)
inWire.pd := io.in.bits.pd(i)
inWire.ipf := io.in.bits.ipf
inWire.acf := io.in.bits.acf
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册