From f3501106acc5da5db0f9ad13e38d2f599df11b56 Mon Sep 17 00:00:00 2001 From: GouLingrui Date: Wed, 16 Sep 2020 13:01:10 +0800 Subject: [PATCH] IFU: fix GHR bugs --- src/main/scala/xiangshan/Bundle.scala | 4 ++-- src/main/scala/xiangshan/frontend/BPU.scala | 16 +++++++++------- src/main/scala/xiangshan/frontend/IFU.scala | 21 ++++++++++++++++----- 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/main/scala/xiangshan/Bundle.scala b/src/main/scala/xiangshan/Bundle.scala index 9f9e8650e..1a07ac8b5 100644 --- a/src/main/scala/xiangshan/Bundle.scala +++ b/src/main/scala/xiangshan/Bundle.scala @@ -7,6 +7,7 @@ import xiangshan.backend.brq.BrqPtr import xiangshan.backend.rename.FreeListPtr import xiangshan.frontend.PreDecodeInfo import xiangshan.frontend.HasBPUParameter +import xiangshan.frontend.HasTageParameter // Fetch FetchWidth x 32-bit insts from Icache class FetchPacket extends XSBundle { @@ -31,8 +32,7 @@ object ValidUndirectioned { } } -class TageMeta extends XSBundle { - def TageNTables = 6 +class TageMeta extends XSBundle with HasTageParameter { val provider = ValidUndirectioned(UInt(log2Ceil(TageNTables).W)) val altDiffers = Bool() val providerU = UInt(2.W) diff --git a/src/main/scala/xiangshan/frontend/BPU.scala b/src/main/scala/xiangshan/frontend/BPU.scala index 1195488d1..5ee13698e 100644 --- a/src/main/scala/xiangshan/frontend/BPU.scala +++ b/src/main/scala/xiangshan/frontend/BPU.scala @@ -8,7 +8,7 @@ import xiangshan.backend.ALUOpType import xiangshan.backend.JumpOpType trait HasBPUParameter extends HasXSParameter { - val BPUDebug = false + val BPUDebug = true val EnableCFICommitLog = true val EnbaleCFIPredLog = true val EnableBPUTimeRecord = true @@ -162,7 +162,7 @@ abstract class BPUStage extends XSModule with HasBPUParameter{ io.pred.bits.jmpIdx := jmpIdx io.pred.bits.hasNotTakenBrs := hasNTBr io.pred.bits.target := target - io.pred.bits.saveHalfRVI := ((lastValidPos === jmpIdx && taken) || !taken ) && !lastIsRVC && lastHit + io.pred.bits.saveHalfRVI := ((lastValidPos === jmpIdx && taken && !(jmpIdx === 0.U && !io.predecode.bits.isFetchpcEqualFirstpc)) || !taken ) && !lastIsRVC && lastHit io.pred.bits.takenOnBr := taken && brMask(jmpIdx) io.out.bits <> DontCare @@ -276,6 +276,8 @@ class BPUStage3 extends BPUStage { // so we do not use those from inLatch val tageResp = io.in.bits.resp.tage val tageTakens = tageResp.takens + val tageHits = tageResp.hits + val tageValidTakens = VecInit((tageTakens zip tageHits).map{case (t, h) => t && h}) val loopResp = io.in.bits.resp.loop.exit @@ -295,8 +297,9 @@ class BPUStage3 extends BPUStage { val callIdx = PriorityEncoder(calls) val retIdx = PriorityEncoder(rets) + // Use bim results for those who tage does not have an entry for val brTakens = brs & - (if (EnableBPD) Reverse(Cat((0 until PredictWidth).map(i => tageTakens(i)))) else Reverse(Cat((0 until PredictWidth).map(i => bimTakens(i))))) & + (if (EnableBPD) Reverse(Cat((0 until PredictWidth).map(i => tageValidTakens(i) || !tageHits(i) && bimTakens(i)))) else Reverse(Cat((0 until PredictWidth).map(i => bimTakens(i))))) & (if (EnableLoop) ~loopResp.asUInt else Fill(PredictWidth, 1.U(1.W))) // if (EnableBPD) { // brs & Reverse(Cat((0 until PredictWidth).map(i => tageValidTakens(i)))) @@ -309,8 +312,7 @@ class BPUStage3 extends BPUStage { // Whether should we count in branches that are not recorded in btb? // PS: Currently counted in. Whenever tage does not provide a valid // taken prediction, the branch is counted as a not taken branch - notTakens := ((if (EnableBPD) { VecInit((0 until PredictWidth).map(i => brs(i) && !tageTakens(i)))} - else { VecInit((0 until PredictWidth).map(i => brs(i) && !bimTakens(i)))}).asUInt | + notTakens := ((VecInit((0 until PredictWidth).map(i => brs(i) && !takens(i)))).asUInt | (if (EnableLoop) { VecInit((0 until PredictWidth).map(i => brs(i) && loopResp(i)))} else { WireInit(0.U.asTypeOf(UInt(PredictWidth.W))) }).asUInt).asTypeOf(Vec(PredictWidth, Bool())) targetSrc := inLatch.resp.btb.targets @@ -547,7 +549,7 @@ class BPU extends BaseBPU { s1.io.in.bits.resp <> s1_resp_in s1.io.in.bits.brInfo <> s1_brInfo_in - val s1_hist = RegEnable(io.in.bits.hist, enable=io.in.valid) + val s1_hist = RegEnable(io.in.bits.hist, enable=s1_fire) //**********************Stage 2****************************// tage.io.flush := io.flush(1) // TODO: fix this @@ -592,7 +594,7 @@ class BPU extends BaseBPU { val buinfo = io.inOrderBrInfo.bits.ui 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)\n") + 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") } } diff --git a/src/main/scala/xiangshan/frontend/IFU.scala b/src/main/scala/xiangshan/frontend/IFU.scala index 546167c52..31f30b94b 100644 --- a/src/main/scala/xiangshan/frontend/IFU.scala +++ b/src/main/scala/xiangshan/frontend/IFU.scala @@ -14,7 +14,7 @@ trait HasIFUConst { this: XSModule => def mask(pc: UInt): UInt = (Fill(PredictWidth * 2, 1.U(1.W)) >> pc(groupAlign - 1, 1))(PredictWidth - 1, 0) def snpc(pc: UInt): UInt = pc + (PopCount(mask(pc)) << 1) - val IFUDebug = false + val IFUDebug = true } class IFUIO extends XSBundle @@ -97,12 +97,16 @@ class IFU extends XSModule with HasIFUConst extHist(newPtr) := if2_bp.takenOnBr.asUInt } + // repair histptr when if4 finds a not taken branch which is + // not recorded in uBTB or BTB + val if4_shiftWithoutRedirect = WireInit(false.B) + //********************** IF3 ****************************// val if3_valid = RegEnable(next = if2_valid, init = false.B, enable = if2_fire) val if4_ready = WireInit(false.B) val if3_fire = if3_valid && if4_ready && io.icacheResp.valid && !if3_flush val if3_pc = RegEnable(if2_pc, if2_fire) - val if3_histPtr = RegEnable(if2_histPtr, if2_fire) + val if3_histPtr = RegEnable(if2_histPtr - if4_shiftWithoutRedirect.asUInt, if2_fire) if3_ready := if3_fire || !if3_valid || if3_flush when (if3_flush) { if3_valid := false.B } .elsewhen (if2_fire) { if3_valid := if2_valid } @@ -206,7 +210,7 @@ class IFU extends XSModule with HasIFUConst val if4_valid = RegInit(false.B) val if4_fire = if4_valid && io.fetchPacket.ready val if4_pc = RegEnable(if3_pc, if3_fire) - val if4_histPtr = RegEnable(if3_histPtr, if3_fire) + val if4_histPtr = RegEnable(if3_histPtr - if4_shiftWithoutRedirect.asUInt, if3_fire) if4_ready := (if4_fire || !if4_valid || if4_flush) && GTimer() > 500.U when (if4_flush) { if4_valid := false.B } .elsewhen (if3_fire) { if4_valid := if3_valid } @@ -262,6 +266,13 @@ class IFU extends XSModule with HasIFUConst extHist(newPtr) := extHist(if4_histPtr) }.otherwise { if4_redirect := false.B + when (if4_bp.takenOnBr || if4_bp.hasNotTakenBrs) { + shiftPtr := true.B + if4_shiftWithoutRedirect := true.B + newPtr := if4_histPtr - 1.U + hist(0) := if4_bp.takenOnBr.asUInt + extHist(newPtr) := if4_bp.takenOnBr.asUInt + } } }.otherwise { if4_redirect := false.B @@ -313,8 +324,8 @@ class IFU extends XSModule with HasIFUConst newPtr := oldPtr }.otherwise { newPtr := oldPtr - 1.U - hist(0) := b.taken - extHist(newPtr) := b.taken + hist(0) := Mux(b.pd.isBr, b.taken, 0.U) + extHist(newPtr) := Mux(b.pd.isBr, b.taken, 0.U) } } -- GitLab