109c6f1ddSLingrui98/*************************************************************************************** 209c6f1ddSLingrui98* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 309c6f1ddSLingrui98* Copyright (c) 2020-2021 Peng Cheng Laboratory 409c6f1ddSLingrui98* 509c6f1ddSLingrui98* XiangShan is licensed under Mulan PSL v2. 609c6f1ddSLingrui98* You can use this software according to the terms and conditions of the Mulan PSL v2. 709c6f1ddSLingrui98* You may obtain a copy of Mulan PSL v2 at: 809c6f1ddSLingrui98* http://license.coscl.org.cn/MulanPSL2 909c6f1ddSLingrui98* 1009c6f1ddSLingrui98* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 1109c6f1ddSLingrui98* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 1209c6f1ddSLingrui98* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 1309c6f1ddSLingrui98* 1409c6f1ddSLingrui98* See the Mulan PSL v2 for more details. 1509c6f1ddSLingrui98***************************************************************************************/ 1609c6f1ddSLingrui98 1709c6f1ddSLingrui98package xiangshan.frontend 1809c6f1ddSLingrui98 198891a219SYinan Xuimport org.chipsalliance.cde.config.Parameters 2009c6f1ddSLingrui98import chisel3._ 2109c6f1ddSLingrui98import chisel3.util._ 2209c6f1ddSLingrui98import xiangshan._ 2309c6f1ddSLingrui98import utils._ 243c02ee8fSwakafaimport utility._ 2509c6f1ddSLingrui98 2609c6f1ddSLingrui98import scala.math.min 27d2b20d1aSTang Haojinimport xiangshan.backend.decode.ImmUnion 2809c6f1ddSLingrui98 29dd6c0695SLingrui98trait HasBPUConst extends HasXSParameter { 30dc387c07SGuokai Chen val MaxMetaBaseLength = if (!env.FPGAPlatform) 512 else 219 // TODO: Reduce meta length 31dc387c07SGuokai Chen val MaxMetaLength = if (HasHExtension) MaxMetaBaseLength + 4 else MaxMetaBaseLength 3209c6f1ddSLingrui98 val MaxBasicBlockSize = 32 3309c6f1ddSLingrui98 val LHistoryLength = 32 34dd6c0695SLingrui98 // val numBr = 2 3509c6f1ddSLingrui98 val useBPD = true 3609c6f1ddSLingrui98 val useLHist = true 37b37e4b45SLingrui98 val numBrSlot = numBr-1 38eeb5ff92SLingrui98 val totalSlot = numBrSlot + 1 3909c6f1ddSLingrui98 40adc0b8dfSGuokai Chen val numDup = 4 41adc0b8dfSGuokai Chen 42cb4f77ceSLingrui98 def BP_STAGES = (0 until 3).map(_.U(2.W)) 431d7e5011SLingrui98 def BP_S1 = BP_STAGES(0) 441d7e5011SLingrui98 def BP_S2 = BP_STAGES(1) 45cb4f77ceSLingrui98 def BP_S3 = BP_STAGES(2) 46adc0b8dfSGuokai Chen 47adc0b8dfSGuokai Chen def dup_seq[T](src: T, num: Int = numDup) = Seq.tabulate(num)(n => src) 48adc0b8dfSGuokai Chen def dup[T <: Data](src: T, num: Int = numDup) = VecInit(Seq.tabulate(num)(n => src)) 49adc0b8dfSGuokai Chen def dup_wire[T <: Data](src: T, num: Int = numDup) = Wire(Vec(num, src.cloneType)) 50adc0b8dfSGuokai Chen def dup_idx = Seq.tabulate(numDup)(n => n.toString()) 511d7e5011SLingrui98 val numBpStages = BP_STAGES.length 5209c6f1ddSLingrui98 5309c6f1ddSLingrui98 val debug = true 5409c6f1ddSLingrui98 // TODO: Replace log2Up by log2Ceil 5509c6f1ddSLingrui98} 5609c6f1ddSLingrui98 5709c6f1ddSLingrui98trait HasBPUParameter extends HasXSParameter with HasBPUConst { 5809c6f1ddSLingrui98 val BPUDebug = true && !env.FPGAPlatform && env.EnablePerfDebug 5909c6f1ddSLingrui98 val EnableCFICommitLog = true 6009c6f1ddSLingrui98 val EnbaleCFIPredLog = true 6109c6f1ddSLingrui98 val EnableBPUTimeRecord = (EnableCFICommitLog || EnbaleCFIPredLog) && !env.FPGAPlatform 6209c6f1ddSLingrui98 val EnableCommit = false 6309c6f1ddSLingrui98} 6409c6f1ddSLingrui98 6509c6f1ddSLingrui98class BPUCtrl(implicit p: Parameters) extends XSBundle { 6609c6f1ddSLingrui98 val ubtb_enable = Bool() 6709c6f1ddSLingrui98 val btb_enable = Bool() 6809c6f1ddSLingrui98 val bim_enable = Bool() 6909c6f1ddSLingrui98 val tage_enable = Bool() 7009c6f1ddSLingrui98 val sc_enable = Bool() 7109c6f1ddSLingrui98 val ras_enable = Bool() 7209c6f1ddSLingrui98 val loop_enable = Bool() 7309c6f1ddSLingrui98} 7409c6f1ddSLingrui98 7509c6f1ddSLingrui98trait BPUUtils extends HasXSParameter { 7609c6f1ddSLingrui98 // circular shifting 7709c6f1ddSLingrui98 def circularShiftLeft(source: UInt, len: Int, shamt: UInt): UInt = { 7809c6f1ddSLingrui98 val res = Wire(UInt(len.W)) 7909c6f1ddSLingrui98 val higher = source << shamt 8009c6f1ddSLingrui98 val lower = source >> (len.U - shamt) 8109c6f1ddSLingrui98 res := higher | lower 8209c6f1ddSLingrui98 res 8309c6f1ddSLingrui98 } 8409c6f1ddSLingrui98 8509c6f1ddSLingrui98 def circularShiftRight(source: UInt, len: Int, shamt: UInt): UInt = { 8609c6f1ddSLingrui98 val res = Wire(UInt(len.W)) 8709c6f1ddSLingrui98 val higher = source << (len.U - shamt) 8809c6f1ddSLingrui98 val lower = source >> shamt 8909c6f1ddSLingrui98 res := higher | lower 9009c6f1ddSLingrui98 res 9109c6f1ddSLingrui98 } 9209c6f1ddSLingrui98 9309c6f1ddSLingrui98 // To be verified 9409c6f1ddSLingrui98 def satUpdate(old: UInt, len: Int, taken: Bool): UInt = { 9509c6f1ddSLingrui98 val oldSatTaken = old === ((1 << len)-1).U 9609c6f1ddSLingrui98 val oldSatNotTaken = old === 0.U 9709c6f1ddSLingrui98 Mux(oldSatTaken && taken, ((1 << len)-1).U, 9809c6f1ddSLingrui98 Mux(oldSatNotTaken && !taken, 0.U, 9909c6f1ddSLingrui98 Mux(taken, old + 1.U, old - 1.U))) 10009c6f1ddSLingrui98 } 10109c6f1ddSLingrui98 10209c6f1ddSLingrui98 def signedSatUpdate(old: SInt, len: Int, taken: Bool): SInt = { 10309c6f1ddSLingrui98 val oldSatTaken = old === ((1 << (len-1))-1).S 10409c6f1ddSLingrui98 val oldSatNotTaken = old === (-(1 << (len-1))).S 10509c6f1ddSLingrui98 Mux(oldSatTaken && taken, ((1 << (len-1))-1).S, 10609c6f1ddSLingrui98 Mux(oldSatNotTaken && !taken, (-(1 << (len-1))).S, 10709c6f1ddSLingrui98 Mux(taken, old + 1.S, old - 1.S))) 10809c6f1ddSLingrui98 } 10909c6f1ddSLingrui98 11009c6f1ddSLingrui98 def getFallThroughAddr(start: UInt, carry: Bool, pft: UInt) = { 111a60a2901SLingrui98 val higher = start.head(VAddrBits-log2Ceil(PredictWidth)-instOffsetBits) 11209c6f1ddSLingrui98 Cat(Mux(carry, higher+1.U, higher), pft, 0.U(instOffsetBits.W)) 11309c6f1ddSLingrui98 } 11409c6f1ddSLingrui98 11509c6f1ddSLingrui98 def foldTag(tag: UInt, l: Int): UInt = { 11609c6f1ddSLingrui98 val nChunks = (tag.getWidth + l - 1) / l 11709c6f1ddSLingrui98 val chunks = (0 until nChunks).map { i => 11809c6f1ddSLingrui98 tag(min((i+1)*l, tag.getWidth)-1, i*l) 11909c6f1ddSLingrui98 } 12009c6f1ddSLingrui98 ParallelXOR(chunks) 12109c6f1ddSLingrui98 } 12209c6f1ddSLingrui98} 12309c6f1ddSLingrui98 12409c6f1ddSLingrui98class BasePredictorInput (implicit p: Parameters) extends XSBundle with HasBPUConst { 12509c6f1ddSLingrui98 def nInputs = 1 12609c6f1ddSLingrui98 127adc0b8dfSGuokai Chen val s0_pc = Vec(numDup, UInt(VAddrBits.W)) 12809c6f1ddSLingrui98 129adc0b8dfSGuokai Chen val folded_hist = Vec(numDup, new AllFoldedHistories(foldedGHistInfos)) 13086d9c530SLingrui98 val ghist = UInt(HistoryLength.W) 13109c6f1ddSLingrui98 13209c6f1ddSLingrui98 val resp_in = Vec(nInputs, new BranchPredictionResp) 133dd6c0695SLingrui98 134dd6c0695SLingrui98 // val final_preds = Vec(numBpStages, new) 13509c6f1ddSLingrui98 // val toFtq_fire = Bool() 13609c6f1ddSLingrui98 13709c6f1ddSLingrui98 // val s0_all_ready = Bool() 13809c6f1ddSLingrui98} 13909c6f1ddSLingrui98 140c2d1ec7dSLingrui98class BasePredictorOutput (implicit p: Parameters) extends BranchPredictionResp {} 14109c6f1ddSLingrui98 14209c6f1ddSLingrui98class BasePredictorIO (implicit p: Parameters) extends XSBundle with HasBPUConst { 143c4b44470SGuokai Chen val reset_vector = Input(UInt(PAddrBits.W)) 14409c6f1ddSLingrui98 val in = Flipped(DecoupledIO(new BasePredictorInput)) // TODO: Remove DecoupledIO 14509c6f1ddSLingrui98 // val out = DecoupledIO(new BasePredictorOutput) 14609c6f1ddSLingrui98 val out = Output(new BasePredictorOutput) 14709c6f1ddSLingrui98 // val flush_out = Valid(UInt(VAddrBits.W)) 14809c6f1ddSLingrui98 1496ee06c7aSSteve Gou val ctrl = Input(new BPUCtrl) 15009c6f1ddSLingrui98 151adc0b8dfSGuokai Chen val s0_fire = Input(Vec(numDup, Bool())) 152adc0b8dfSGuokai Chen val s1_fire = Input(Vec(numDup, Bool())) 153adc0b8dfSGuokai Chen val s2_fire = Input(Vec(numDup, Bool())) 154adc0b8dfSGuokai Chen val s3_fire = Input(Vec(numDup, Bool())) 15509c6f1ddSLingrui98 156adc0b8dfSGuokai Chen val s2_redirect = Input(Vec(numDup, Bool())) 157adc0b8dfSGuokai Chen val s3_redirect = Input(Vec(numDup, Bool())) 15885670bacSLingrui98 15909c6f1ddSLingrui98 val s1_ready = Output(Bool()) 16009c6f1ddSLingrui98 val s2_ready = Output(Bool()) 161cb4f77ceSLingrui98 val s3_ready = Output(Bool()) 16209c6f1ddSLingrui98 16309c6f1ddSLingrui98 val update = Flipped(Valid(new BranchPredictionUpdate)) 16409c6f1ddSLingrui98 val redirect = Flipped(Valid(new BranchPredictionRedirect)) 16509c6f1ddSLingrui98} 16609c6f1ddSLingrui98 1674813e060SLingrui98abstract class BasePredictor(implicit p: Parameters) extends XSModule 1684813e060SLingrui98 with HasBPUConst with BPUUtils with HasPerfEvents { 16909c6f1ddSLingrui98 val meta_size = 0 17009c6f1ddSLingrui98 val spec_meta_size = 0 171b60e4b0bSLingrui98 val is_fast_pred = false 17209c6f1ddSLingrui98 val io = IO(new BasePredictorIO()) 17309c6f1ddSLingrui98 174c2d1ec7dSLingrui98 io.out := io.in.bits.resp_in(0) 17509c6f1ddSLingrui98 1763e52bed1SLingrui98 io.out.last_stage_meta := 0.U 17709c6f1ddSLingrui98 17809c6f1ddSLingrui98 io.in.ready := !io.redirect.valid 17909c6f1ddSLingrui98 18009c6f1ddSLingrui98 io.s1_ready := true.B 18109c6f1ddSLingrui98 io.s2_ready := true.B 182cb4f77ceSLingrui98 io.s3_ready := true.B 18309c6f1ddSLingrui98 184c4b44470SGuokai Chen val reset_vector = DelayN(io.reset_vector, 5) 185adc0b8dfSGuokai Chen 186adc0b8dfSGuokai Chen val s0_pc_dup = WireInit(io.in.bits.s0_pc) // fetchIdx(io.f0_pc) 187adc0b8dfSGuokai Chen val s1_pc_dup = s0_pc_dup.zip(io.s0_fire).map {case (s0_pc, s0_fire) => RegEnable(s0_pc, s0_fire)} 188adc0b8dfSGuokai Chen val s2_pc_dup = s1_pc_dup.zip(io.s1_fire).map {case (s1_pc, s1_fire) => RegEnable(s1_pc, s1_fire)} 189adc0b8dfSGuokai Chen val s3_pc_dup = s2_pc_dup.zip(io.s2_fire).map {case (s2_pc, s2_fire) => RegEnable(s2_pc, s2_fire)} 190dd6c0695SLingrui98 191c4b44470SGuokai Chen when (RegNext(RegNext(reset.asBool) && !reset.asBool)) { 192adc0b8dfSGuokai Chen s1_pc_dup.map{case s1_pc => s1_pc := reset_vector} 193c4b44470SGuokai Chen } 194c4b44470SGuokai Chen 195adc0b8dfSGuokai Chen io.out.s1.pc := s1_pc_dup 196adc0b8dfSGuokai Chen io.out.s2.pc := s2_pc_dup 197adc0b8dfSGuokai Chen io.out.s3.pc := s3_pc_dup 198b37e4b45SLingrui98 1994813e060SLingrui98 val perfEvents: Seq[(String, UInt)] = Seq() 2004813e060SLingrui98 201dd6c0695SLingrui98 202dd6c0695SLingrui98 def getFoldedHistoryInfo: Option[Set[FoldedHistoryInfo]] = None 20309c6f1ddSLingrui98} 20409c6f1ddSLingrui98 20509c6f1ddSLingrui98class FakePredictor(implicit p: Parameters) extends BasePredictor { 20609c6f1ddSLingrui98 io.in.ready := true.B 2073e52bed1SLingrui98 io.out.last_stage_meta := 0.U 208c2d1ec7dSLingrui98 io.out := io.in.bits.resp_in(0) 20909c6f1ddSLingrui98} 21009c6f1ddSLingrui98 21109c6f1ddSLingrui98class BpuToFtqIO(implicit p: Parameters) extends XSBundle { 21209c6f1ddSLingrui98 val resp = DecoupledIO(new BpuToFtqBundle()) 21309c6f1ddSLingrui98} 21409c6f1ddSLingrui98 21509c6f1ddSLingrui98class PredictorIO(implicit p: Parameters) extends XSBundle { 21609c6f1ddSLingrui98 val bpu_to_ftq = new BpuToFtqIO() 217935edac4STang Haojin val ftq_to_bpu = Flipped(new FtqToBpuIO) 2186ee06c7aSSteve Gou val ctrl = Input(new BPUCtrl) 219c4b44470SGuokai Chen val reset_vector = Input(UInt(PAddrBits.W)) 22009c6f1ddSLingrui98} 22109c6f1ddSLingrui98 222c7fabd05SSteve Gouclass Predictor(implicit p: Parameters) extends XSModule with HasBPUConst with HasPerfEvents with HasCircularQueuePtrHelper { 22309c6f1ddSLingrui98 val io = IO(new PredictorIO) 22409c6f1ddSLingrui98 2256ee06c7aSSteve Gou val ctrl = DelayN(io.ctrl, 1) 22609c6f1ddSLingrui98 val predictors = Module(if (useBPD) new Composer else new FakePredictor) 22709c6f1ddSLingrui98 228d2b20d1aSTang Haojin def numOfStage = 3 229d2b20d1aSTang Haojin require(numOfStage > 1, "BPU numOfStage must be greater than 1") 230d2b20d1aSTang Haojin val topdown_stages = RegInit(VecInit(Seq.fill(numOfStage)(0.U.asTypeOf(new FrontendTopDownBundle)))) 231d2b20d1aSTang Haojin 232d2b20d1aSTang Haojin // following can only happen on s1 233d2b20d1aSTang Haojin val controlRedirectBubble = Wire(Bool()) 234d2b20d1aSTang Haojin val ControlBTBMissBubble = Wire(Bool()) 235d2b20d1aSTang Haojin val TAGEMissBubble = Wire(Bool()) 236d2b20d1aSTang Haojin val SCMissBubble = Wire(Bool()) 237d2b20d1aSTang Haojin val ITTAGEMissBubble = Wire(Bool()) 238d2b20d1aSTang Haojin val RASMissBubble = Wire(Bool()) 239d2b20d1aSTang Haojin 240d2b20d1aSTang Haojin val memVioRedirectBubble = Wire(Bool()) 241d2b20d1aSTang Haojin val otherRedirectBubble = Wire(Bool()) 242d2b20d1aSTang Haojin val btbMissBubble = Wire(Bool()) 243d2b20d1aSTang Haojin otherRedirectBubble := false.B 244d2b20d1aSTang Haojin memVioRedirectBubble := false.B 245d2b20d1aSTang Haojin 246d2b20d1aSTang Haojin // override can happen between s1-s2 and s2-s3 247d2b20d1aSTang Haojin val overrideBubble = Wire(Vec(numOfStage - 1, Bool())) 248d2b20d1aSTang Haojin def overrideStage = 1 249d2b20d1aSTang Haojin // ftq update block can happen on s1, s2 and s3 250d2b20d1aSTang Haojin val ftqUpdateBubble = Wire(Vec(numOfStage, Bool())) 251d2b20d1aSTang Haojin def ftqUpdateStage = 0 252d2b20d1aSTang Haojin // ftq full stall only happens on s3 (last stage) 253d2b20d1aSTang Haojin val ftqFullStall = Wire(Bool()) 254d2b20d1aSTang Haojin 255d2b20d1aSTang Haojin // by default, no bubble event 256d2b20d1aSTang Haojin topdown_stages(0) := 0.U.asTypeOf(new FrontendTopDownBundle) 257d2b20d1aSTang Haojin // event movement driven by clock only 258d2b20d1aSTang Haojin for (i <- 0 until numOfStage - 1) { 259d2b20d1aSTang Haojin topdown_stages(i + 1) := topdown_stages(i) 260d2b20d1aSTang Haojin } 261d2b20d1aSTang Haojin 262d2b20d1aSTang Haojin 263d2b20d1aSTang Haojin 2646ee06c7aSSteve Gou // ctrl signal 2656ee06c7aSSteve Gou predictors.io.ctrl := ctrl 266c4b44470SGuokai Chen predictors.io.reset_vector := io.reset_vector 2676ee06c7aSSteve Gou 26809c6f1ddSLingrui98 269c4b44470SGuokai Chen val reset_vector = DelayN(io.reset_vector, 5) 270adc0b8dfSGuokai Chen 271adc0b8dfSGuokai Chen val s0_fire_dup, s1_fire_dup, s2_fire_dup, s3_fire_dup = dup_wire(Bool()) 272adc0b8dfSGuokai Chen val s1_valid_dup, s2_valid_dup, s3_valid_dup = dup_seq(RegInit(false.B)) 273adc0b8dfSGuokai Chen val s1_ready_dup, s2_ready_dup, s3_ready_dup = dup_wire(Bool()) 274adc0b8dfSGuokai Chen val s1_components_ready_dup, s2_components_ready_dup, s3_components_ready_dup = dup_wire(Bool()) 275adc0b8dfSGuokai Chen 276adc0b8dfSGuokai Chen val s0_pc_dup = dup(WireInit(0.U.asTypeOf(UInt(VAddrBits.W)))) 277adc0b8dfSGuokai Chen val s0_pc_reg_dup = s0_pc_dup.map(x => RegNext(x)) 278c4b44470SGuokai Chen when (RegNext(RegNext(reset.asBool) && !reset.asBool)) { 279adc0b8dfSGuokai Chen s0_pc_reg_dup.map{case s0_pc => s0_pc := reset_vector} 280c4b44470SGuokai Chen } 281adc0b8dfSGuokai Chen val s1_pc = RegEnable(s0_pc_dup(0), s0_fire_dup(0)) 282adc0b8dfSGuokai Chen val s2_pc = RegEnable(s1_pc, s1_fire_dup(0)) 283adc0b8dfSGuokai Chen val s3_pc = RegEnable(s2_pc, s2_fire_dup(0)) 28409c6f1ddSLingrui98 285adc0b8dfSGuokai Chen val s0_folded_gh_dup = dup_wire(new AllFoldedHistories(foldedGHistInfos)) 286adc0b8dfSGuokai Chen val s0_folded_gh_reg_dup = s0_folded_gh_dup.map(x => RegNext(x, init=0.U.asTypeOf(s0_folded_gh_dup(0)))) 287adc0b8dfSGuokai Chen val s1_folded_gh_dup = RegEnable(s0_folded_gh_dup, 0.U.asTypeOf(s0_folded_gh_dup), s0_fire_dup(1)) 288adc0b8dfSGuokai Chen val s2_folded_gh_dup = RegEnable(s1_folded_gh_dup, 0.U.asTypeOf(s0_folded_gh_dup), s1_fire_dup(1)) 289adc0b8dfSGuokai Chen val s3_folded_gh_dup = RegEnable(s2_folded_gh_dup, 0.U.asTypeOf(s0_folded_gh_dup), s2_fire_dup(1)) 290c2ad24ebSLingrui98 291adc0b8dfSGuokai Chen val s0_last_br_num_oh_dup = dup_wire(UInt((numBr+1).W)) 292adc0b8dfSGuokai Chen val s0_last_br_num_oh_reg_dup = s0_last_br_num_oh_dup.map(x => RegNext(x, init=0.U)) 293adc0b8dfSGuokai Chen val s1_last_br_num_oh_dup = RegEnable(s0_last_br_num_oh_dup, 0.U.asTypeOf(s0_last_br_num_oh_dup), s0_fire_dup(1)) 294adc0b8dfSGuokai Chen val s2_last_br_num_oh_dup = RegEnable(s1_last_br_num_oh_dup, 0.U.asTypeOf(s0_last_br_num_oh_dup), s1_fire_dup(1)) 295adc0b8dfSGuokai Chen val s3_last_br_num_oh_dup = RegEnable(s2_last_br_num_oh_dup, 0.U.asTypeOf(s0_last_br_num_oh_dup), s2_fire_dup(1)) 29667402d75SLingrui98 297adc0b8dfSGuokai Chen val s0_ahead_fh_oldest_bits_dup = dup_wire(new AllAheadFoldedHistoryOldestBits(foldedGHistInfos)) 298adc0b8dfSGuokai Chen val s0_ahead_fh_oldest_bits_reg_dup = s0_ahead_fh_oldest_bits_dup.map(x => RegNext(x, init=0.U.asTypeOf(s0_ahead_fh_oldest_bits_dup(0)))) 299adc0b8dfSGuokai Chen val s1_ahead_fh_oldest_bits_dup = RegEnable(s0_ahead_fh_oldest_bits_dup, 0.U.asTypeOf(s0_ahead_fh_oldest_bits_dup), s0_fire_dup(1)) 300adc0b8dfSGuokai Chen val s2_ahead_fh_oldest_bits_dup = RegEnable(s1_ahead_fh_oldest_bits_dup, 0.U.asTypeOf(s0_ahead_fh_oldest_bits_dup), s1_fire_dup(1)) 301adc0b8dfSGuokai Chen val s3_ahead_fh_oldest_bits_dup = RegEnable(s2_ahead_fh_oldest_bits_dup, 0.U.asTypeOf(s0_ahead_fh_oldest_bits_dup), s2_fire_dup(1)) 30267402d75SLingrui98 303adc0b8dfSGuokai Chen val npcGen_dup = Seq.tabulate(numDup)(n => new PhyPriorityMuxGenerator[UInt]) 304adc0b8dfSGuokai Chen val foldedGhGen_dup = Seq.tabulate(numDup)(n => new PhyPriorityMuxGenerator[AllFoldedHistories]) 305adc0b8dfSGuokai Chen val ghistPtrGen_dup = Seq.tabulate(numDup)(n => new PhyPriorityMuxGenerator[CGHPtr]) 306adc0b8dfSGuokai Chen val lastBrNumOHGen_dup = Seq.tabulate(numDup)(n => new PhyPriorityMuxGenerator[UInt]) 307adc0b8dfSGuokai Chen val aheadFhObGen_dup = Seq.tabulate(numDup)(n => new PhyPriorityMuxGenerator[AllAheadFoldedHistoryOldestBits]) 30867402d75SLingrui98 309b37e4b45SLingrui98 val ghvBitWriteGens = Seq.tabulate(HistoryLength)(n => new PhyPriorityMuxGenerator[Bool]) 31086d9c530SLingrui98 // val ghistGen = new PhyPriorityMuxGenerator[UInt] 311ae8ed1a3Szoujr 312b37e4b45SLingrui98 val ghv = RegInit(0.U.asTypeOf(Vec(HistoryLength, Bool()))) 313b37e4b45SLingrui98 val ghv_wire = WireInit(ghv) 314c2ad24ebSLingrui98 31586d9c530SLingrui98 val s0_ghist = WireInit(0.U.asTypeOf(UInt(HistoryLength.W))) 31686d9c530SLingrui98 31786d9c530SLingrui98 318c7fabd05SSteve Gou println(f"history buffer length ${HistoryLength}") 319b37e4b45SLingrui98 val ghv_write_datas = Wire(Vec(HistoryLength, Bool())) 320b37e4b45SLingrui98 val ghv_wens = Wire(Vec(HistoryLength, Bool())) 321c2ad24ebSLingrui98 322adc0b8dfSGuokai Chen val s0_ghist_ptr_dup = dup_wire(new CGHPtr) 323adc0b8dfSGuokai Chen val s0_ghist_ptr_reg_dup = s0_ghist_ptr_dup.map(x => RegNext(x, init=0.U.asTypeOf(new CGHPtr))) 324adc0b8dfSGuokai Chen val s1_ghist_ptr_dup = RegEnable(s0_ghist_ptr_dup, 0.U.asTypeOf(s0_ghist_ptr_dup), s0_fire_dup(1)) 325adc0b8dfSGuokai Chen val s2_ghist_ptr_dup = RegEnable(s1_ghist_ptr_dup, 0.U.asTypeOf(s0_ghist_ptr_dup), s1_fire_dup(1)) 326adc0b8dfSGuokai Chen val s3_ghist_ptr_dup = RegEnable(s2_ghist_ptr_dup, 0.U.asTypeOf(s0_ghist_ptr_dup), s2_fire_dup(1)) 327c2ad24ebSLingrui98 32886d9c530SLingrui98 def getHist(ptr: CGHPtr): UInt = (Cat(ghv_wire.asUInt, ghv_wire.asUInt) >> (ptr.value+1.U))(HistoryLength-1, 0) 329adc0b8dfSGuokai Chen s0_ghist := getHist(s0_ghist_ptr_dup(0)) 33086d9c530SLingrui98 331c2d1ec7dSLingrui98 val resp = predictors.io.out 33209c6f1ddSLingrui98 33309c6f1ddSLingrui98 33409c6f1ddSLingrui98 val toFtq_fire = io.bpu_to_ftq.resp.valid && io.bpu_to_ftq.resp.ready 33509c6f1ddSLingrui98 336adc0b8dfSGuokai Chen val s1_flush_dup, s2_flush_dup, s3_flush_dup = dup_wire(Bool()) 337adc0b8dfSGuokai Chen val s2_redirect_dup, s3_redirect_dup = dup_wire(Bool()) 33809c6f1ddSLingrui98 33909c6f1ddSLingrui98 // predictors.io := DontCare 340adc0b8dfSGuokai Chen predictors.io.in.valid := s0_fire_dup(0) 341adc0b8dfSGuokai Chen predictors.io.in.bits.s0_pc := s0_pc_dup 34286d9c530SLingrui98 predictors.io.in.bits.ghist := s0_ghist 343adc0b8dfSGuokai Chen predictors.io.in.bits.folded_hist := s0_folded_gh_dup 34409c6f1ddSLingrui98 predictors.io.in.bits.resp_in(0) := (0.U).asTypeOf(new BranchPredictionResp) 34509c6f1ddSLingrui98 // predictors.io.in.bits.resp_in(0).s1.pc := s0_pc 34609c6f1ddSLingrui98 // predictors.io.in.bits.toFtq_fire := toFtq_fire 34709c6f1ddSLingrui98 34809c6f1ddSLingrui98 // predictors.io.out.ready := io.bpu_to_ftq.resp.ready 34909c6f1ddSLingrui98 35053bac374SLingrui98 val redirect_req = io.ftq_to_bpu.redirect 351*7af6acb0SEaston Man val do_redirect_dup = dup_seq(RegNextWithEnable(redirect_req)) 35253bac374SLingrui98 35309c6f1ddSLingrui98 // Pipeline logic 354adc0b8dfSGuokai Chen s2_redirect_dup.map(_ := false.B) 355adc0b8dfSGuokai Chen s3_redirect_dup.map(_ := false.B) 35609c6f1ddSLingrui98 357adc0b8dfSGuokai Chen s3_flush_dup.map(_ := redirect_req.valid) // flush when redirect comes 358adc0b8dfSGuokai Chen for (((s2_flush, s3_flush), s3_redirect) <- s2_flush_dup zip s3_flush_dup zip s3_redirect_dup) 359cb4f77ceSLingrui98 s2_flush := s3_flush || s3_redirect 360adc0b8dfSGuokai Chen for (((s1_flush, s2_flush), s2_redirect) <- s1_flush_dup zip s2_flush_dup zip s2_redirect_dup) 36109c6f1ddSLingrui98 s1_flush := s2_flush || s2_redirect 36209c6f1ddSLingrui98 36309c6f1ddSLingrui98 364adc0b8dfSGuokai Chen s1_components_ready_dup.map(_ := predictors.io.s1_ready) 365adc0b8dfSGuokai Chen for (((s1_ready, s1_fire), s1_valid) <- s1_ready_dup zip s1_fire_dup zip s1_valid_dup) 366adc0b8dfSGuokai Chen s1_ready := s1_fire || !s1_valid 367adc0b8dfSGuokai Chen for (((s0_fire, s1_components_ready), s1_ready) <- s0_fire_dup zip s1_components_ready_dup zip s1_ready_dup) 368adc0b8dfSGuokai Chen s0_fire := s1_components_ready && s1_ready 369adc0b8dfSGuokai Chen predictors.io.s0_fire := s0_fire_dup 370adc0b8dfSGuokai Chen 371adc0b8dfSGuokai Chen s2_components_ready_dup.map(_ := predictors.io.s2_ready) 372adc0b8dfSGuokai Chen for (((s2_ready, s2_fire), s2_valid) <- s2_ready_dup zip s2_fire_dup zip s2_valid_dup) 37309c6f1ddSLingrui98 s2_ready := s2_fire || !s2_valid 374adc0b8dfSGuokai Chen for ((((s1_fire, s2_components_ready), s2_ready), s1_valid) <- s1_fire_dup zip s2_components_ready_dup zip s2_ready_dup zip s1_valid_dup) 37509c6f1ddSLingrui98 s1_fire := s1_valid && s2_components_ready && s2_ready && io.bpu_to_ftq.resp.ready 37609c6f1ddSLingrui98 377adc0b8dfSGuokai Chen s3_components_ready_dup.map(_ := predictors.io.s3_ready) 378adc0b8dfSGuokai Chen for (((s3_ready, s3_fire), s3_valid) <- s3_ready_dup zip s3_fire_dup zip s3_valid_dup) 379cb4f77ceSLingrui98 s3_ready := s3_fire || !s3_valid 380adc0b8dfSGuokai Chen for ((((s2_fire, s3_components_ready), s3_ready), s2_valid) <- s2_fire_dup zip s3_components_ready_dup zip s3_ready_dup zip s2_valid_dup) 381cb4f77ceSLingrui98 s2_fire := s2_valid && s3_components_ready && s3_ready 382cb4f77ceSLingrui98 383adc0b8dfSGuokai Chen for ((((s0_fire, s1_flush), s1_fire), s1_valid) <- s0_fire_dup zip s1_flush_dup zip s1_fire_dup zip s1_valid_dup) { 38453bac374SLingrui98 when (redirect_req.valid) { s1_valid := false.B } 38553bac374SLingrui98 .elsewhen(s0_fire) { s1_valid := true.B } 38609c6f1ddSLingrui98 .elsewhen(s1_flush) { s1_valid := false.B } 38709c6f1ddSLingrui98 .elsewhen(s1_fire) { s1_valid := false.B } 388adc0b8dfSGuokai Chen } 389adc0b8dfSGuokai Chen predictors.io.s1_fire := s1_fire_dup 39009c6f1ddSLingrui98 391adc0b8dfSGuokai Chen s2_fire_dup := s2_valid_dup 39209c6f1ddSLingrui98 393adc0b8dfSGuokai Chen for (((((s1_fire, s2_flush), s2_fire), s2_valid), s1_flush) <- 394adc0b8dfSGuokai Chen s1_fire_dup zip s2_flush_dup zip s2_fire_dup zip s2_valid_dup zip s1_flush_dup) { 39509c6f1ddSLingrui98 39609c6f1ddSLingrui98 when (s2_flush) { s2_valid := false.B } 397b30c10d6SLingrui98 .elsewhen(s1_fire) { s2_valid := !s1_flush } 39809c6f1ddSLingrui98 .elsewhen(s2_fire) { s2_valid := false.B } 399adc0b8dfSGuokai Chen } 40009c6f1ddSLingrui98 401adc0b8dfSGuokai Chen predictors.io.s2_fire := s2_fire_dup 402adc0b8dfSGuokai Chen predictors.io.s2_redirect := s2_redirect_dup 40309c6f1ddSLingrui98 404adc0b8dfSGuokai Chen s3_fire_dup := s3_valid_dup 405adc0b8dfSGuokai Chen 406adc0b8dfSGuokai Chen for (((((s2_fire, s3_flush), s3_fire), s3_valid), s2_flush) <- 407adc0b8dfSGuokai Chen s2_fire_dup zip s3_flush_dup zip s3_fire_dup zip s3_valid_dup zip s2_flush_dup) { 408cb4f77ceSLingrui98 409cb4f77ceSLingrui98 when (s3_flush) { s3_valid := false.B } 410cb4f77ceSLingrui98 .elsewhen(s2_fire) { s3_valid := !s2_flush } 411cb4f77ceSLingrui98 .elsewhen(s3_fire) { s3_valid := false.B } 412adc0b8dfSGuokai Chen } 413cb4f77ceSLingrui98 414adc0b8dfSGuokai Chen predictors.io.s3_fire := s3_fire_dup 415adc0b8dfSGuokai Chen predictors.io.s3_redirect := s3_redirect_dup 416cb4f77ceSLingrui98 41709c6f1ddSLingrui98 41809c6f1ddSLingrui98 io.bpu_to_ftq.resp.valid := 419adc0b8dfSGuokai Chen s1_valid_dup(2) && s2_components_ready_dup(2) && s2_ready_dup(2) || 420adc0b8dfSGuokai Chen s2_fire_dup(2) && s2_redirect_dup(2) || 421adc0b8dfSGuokai Chen s3_fire_dup(2) && s3_redirect_dup(2) 422c2d1ec7dSLingrui98 io.bpu_to_ftq.resp.bits := predictors.io.out 423adc0b8dfSGuokai Chen io.bpu_to_ftq.resp.bits.last_stage_spec_info.folded_hist := s3_folded_gh_dup(2) 424adc0b8dfSGuokai Chen io.bpu_to_ftq.resp.bits.last_stage_spec_info.histPtr := s3_ghist_ptr_dup(2) 425adc0b8dfSGuokai Chen io.bpu_to_ftq.resp.bits.last_stage_spec_info.lastBrNumOH := s3_last_br_num_oh_dup(2) 426adc0b8dfSGuokai Chen io.bpu_to_ftq.resp.bits.last_stage_spec_info.afhob := s3_ahead_fh_oldest_bits_dup(2) 42709c6f1ddSLingrui98 428c89b4642SGuokai Chen val full_pred_diff = WireInit(false.B) 429c89b4642SGuokai Chen val full_pred_diff_stage = WireInit(0.U) 430c89b4642SGuokai Chen val full_pred_diff_offset = WireInit(0.U) 431c89b4642SGuokai Chen for (i <- 0 until numDup - 1) { 432c89b4642SGuokai Chen when (io.bpu_to_ftq.resp.valid && 433c89b4642SGuokai Chen ((io.bpu_to_ftq.resp.bits.s1.full_pred(i).asTypeOf(UInt()) =/= io.bpu_to_ftq.resp.bits.s1.full_pred(i+1).asTypeOf(UInt()) && io.bpu_to_ftq.resp.bits.s1.full_pred(i).hit) || 434c89b4642SGuokai Chen (io.bpu_to_ftq.resp.bits.s2.full_pred(i).asTypeOf(UInt()) =/= io.bpu_to_ftq.resp.bits.s2.full_pred(i+1).asTypeOf(UInt()) && io.bpu_to_ftq.resp.bits.s2.full_pred(i).hit) || 435c89b4642SGuokai Chen (io.bpu_to_ftq.resp.bits.s3.full_pred(i).asTypeOf(UInt()) =/= io.bpu_to_ftq.resp.bits.s3.full_pred(i+1).asTypeOf(UInt()) && io.bpu_to_ftq.resp.bits.s3.full_pred(i).hit))) { 436c89b4642SGuokai Chen full_pred_diff := true.B 437c89b4642SGuokai Chen full_pred_diff_offset := i.U 438c89b4642SGuokai Chen when (io.bpu_to_ftq.resp.bits.s1.full_pred(i).asTypeOf(UInt()) =/= io.bpu_to_ftq.resp.bits.s1.full_pred(i+1).asTypeOf(UInt())) { 439c89b4642SGuokai Chen full_pred_diff_stage := 1.U 440c89b4642SGuokai Chen } .elsewhen (io.bpu_to_ftq.resp.bits.s2.full_pred(i).asTypeOf(UInt()) =/= io.bpu_to_ftq.resp.bits.s2.full_pred(i+1).asTypeOf(UInt())) { 441c89b4642SGuokai Chen full_pred_diff_stage := 2.U 442c89b4642SGuokai Chen } .otherwise { 443c89b4642SGuokai Chen full_pred_diff_stage := 3.U 444c89b4642SGuokai Chen } 445c89b4642SGuokai Chen } 446c89b4642SGuokai Chen } 447c89b4642SGuokai Chen XSError(full_pred_diff, "Full prediction difference detected!") 448c89b4642SGuokai Chen 449adc0b8dfSGuokai Chen npcGen_dup.zip(s0_pc_reg_dup).map{ case (gen, reg) => 450adc0b8dfSGuokai Chen gen.register(true.B, reg, Some("stallPC"), 0)} 451adc0b8dfSGuokai Chen foldedGhGen_dup.zip(s0_folded_gh_reg_dup).map{ case (gen, reg) => 452adc0b8dfSGuokai Chen gen.register(true.B, reg, Some("stallFGH"), 0)} 453adc0b8dfSGuokai Chen ghistPtrGen_dup.zip(s0_ghist_ptr_reg_dup).map{ case (gen, reg) => 454adc0b8dfSGuokai Chen gen.register(true.B, reg, Some("stallGHPtr"), 0)} 455adc0b8dfSGuokai Chen lastBrNumOHGen_dup.zip(s0_last_br_num_oh_reg_dup).map{ case (gen, reg) => 456adc0b8dfSGuokai Chen gen.register(true.B, reg, Some("stallBrNumOH"), 0)} 457adc0b8dfSGuokai Chen aheadFhObGen_dup.zip(s0_ahead_fh_oldest_bits_reg_dup).map{ case (gen, reg) => 458adc0b8dfSGuokai Chen gen.register(true.B, reg, Some("stallAFHOB"), 0)} 45909c6f1ddSLingrui98 460209a4cafSSteve Gou // assign pred cycle for profiling 461209a4cafSSteve Gou io.bpu_to_ftq.resp.bits.s1.full_pred.map(_.predCycle.map(_ := GTimer())) 462209a4cafSSteve Gou io.bpu_to_ftq.resp.bits.s2.full_pred.map(_.predCycle.map(_ := GTimer())) 463209a4cafSSteve Gou io.bpu_to_ftq.resp.bits.s3.full_pred.map(_.predCycle.map(_ := GTimer())) 464209a4cafSSteve Gou 465209a4cafSSteve Gou 466209a4cafSSteve Gou 46709c6f1ddSLingrui98 // History manage 46809c6f1ddSLingrui98 // s1 469adc0b8dfSGuokai Chen val s1_possible_predicted_ghist_ptrs_dup = s1_ghist_ptr_dup.map(ptr => (0 to numBr).map(ptr - _.U)) 470adc0b8dfSGuokai Chen val s1_predicted_ghist_ptr_dup = s1_possible_predicted_ghist_ptrs_dup.zip(resp.s1.lastBrPosOH).map{ case (ptr, oh) => Mux1H(oh, ptr)} 471adc0b8dfSGuokai Chen val s1_possible_predicted_fhs_dup = 472adc0b8dfSGuokai Chen for (((((fgh, afh), br_num_oh), t), br_pos_oh) <- 473adc0b8dfSGuokai Chen s1_folded_gh_dup zip s1_ahead_fh_oldest_bits_dup zip s1_last_br_num_oh_dup zip resp.s1.brTaken zip resp.s1.lastBrPosOH) 474adc0b8dfSGuokai Chen yield (0 to numBr).map(i => 475adc0b8dfSGuokai Chen fgh.update(afh, br_num_oh, i, t & br_pos_oh(i)) 476adc0b8dfSGuokai Chen ) 477adc0b8dfSGuokai Chen val s1_predicted_fh_dup = resp.s1.lastBrPosOH.zip(s1_possible_predicted_fhs_dup).map{ case (oh, fh) => Mux1H(oh, fh)} 478b37e4b45SLingrui98 479adc0b8dfSGuokai Chen val s1_ahead_fh_ob_src_dup = dup_wire(new AllAheadFoldedHistoryOldestBits(foldedGHistInfos)) 480adc0b8dfSGuokai Chen s1_ahead_fh_ob_src_dup.zip(s1_ghist_ptr_dup).map{ case (src, ptr) => src.read(ghv, ptr)} 48167402d75SLingrui98 48286d9c530SLingrui98 if (EnableGHistDiff) { 483adc0b8dfSGuokai Chen val s1_predicted_ghist = WireInit(getHist(s1_predicted_ghist_ptr_dup(0)).asTypeOf(Vec(HistoryLength, Bool()))) 48486d9c530SLingrui98 for (i <- 0 until numBr) { 485adc0b8dfSGuokai Chen when (resp.s1.shouldShiftVec(0)(i)) { 486adc0b8dfSGuokai Chen s1_predicted_ghist(i) := resp.s1.brTaken(0) && (i==0).B 48786d9c530SLingrui98 } 48886d9c530SLingrui98 } 489adc0b8dfSGuokai Chen when (s1_valid_dup(0)) { 49086d9c530SLingrui98 s0_ghist := s1_predicted_ghist.asUInt 49186d9c530SLingrui98 } 49286d9c530SLingrui98 } 49386d9c530SLingrui98 494b37e4b45SLingrui98 val s1_ghv_wens = (0 until HistoryLength).map(n => 495adc0b8dfSGuokai Chen (0 until numBr).map(b => (s1_ghist_ptr_dup(0)).value === (CGHPtr(false.B, n.U) + b.U).value && resp.s1.shouldShiftVec(0)(b) && s1_valid_dup(0))) 496b37e4b45SLingrui98 val s1_ghv_wdatas = (0 until HistoryLength).map(n => 4971ccea249SLingrui98 Mux1H( 498b37e4b45SLingrui98 (0 until numBr).map(b => ( 499adc0b8dfSGuokai Chen (s1_ghist_ptr_dup(0)).value === (CGHPtr(false.B, n.U) + b.U).value && resp.s1.shouldShiftVec(0)(b), 500adc0b8dfSGuokai Chen resp.s1.brTaken(0) && resp.s1.lastBrPosOH(0)(b+1) 501b37e4b45SLingrui98 )) 5021ccea249SLingrui98 ) 5031ccea249SLingrui98 ) 504c2ad24ebSLingrui98 505adc0b8dfSGuokai Chen 506adc0b8dfSGuokai Chen for (((npcGen, s1_valid), s1_target) <- npcGen_dup zip s1_valid_dup zip resp.s1.getTarget) 507adc0b8dfSGuokai Chen npcGen.register(s1_valid, s1_target, Some("s1_target"), 4) 508adc0b8dfSGuokai Chen for (((foldedGhGen, s1_valid), s1_predicted_fh) <- foldedGhGen_dup zip s1_valid_dup zip s1_predicted_fh_dup) 509cb4f77ceSLingrui98 foldedGhGen.register(s1_valid, s1_predicted_fh, Some("s1_FGH"), 4) 510adc0b8dfSGuokai Chen for (((ghistPtrGen, s1_valid), s1_predicted_ghist_ptr) <- ghistPtrGen_dup zip s1_valid_dup zip s1_predicted_ghist_ptr_dup) 511cb4f77ceSLingrui98 ghistPtrGen.register(s1_valid, s1_predicted_ghist_ptr, Some("s1_GHPtr"), 4) 512adc0b8dfSGuokai Chen for (((lastBrNumOHGen, s1_valid), s1_brPosOH) <- lastBrNumOHGen_dup zip s1_valid_dup zip resp.s1.lastBrPosOH.map(_.asUInt)) 513adc0b8dfSGuokai Chen lastBrNumOHGen.register(s1_valid, s1_brPosOH, Some("s1_BrNumOH"), 4) 514adc0b8dfSGuokai Chen for (((aheadFhObGen, s1_valid), s1_ahead_fh_ob_src) <- aheadFhObGen_dup zip s1_valid_dup zip s1_ahead_fh_ob_src_dup) 51567402d75SLingrui98 aheadFhObGen.register(s1_valid, s1_ahead_fh_ob_src, Some("s1_AFHOB"), 4) 516b37e4b45SLingrui98 ghvBitWriteGens.zip(s1_ghv_wens).zipWithIndex.map{case ((b, w), i) => 517cb4f77ceSLingrui98 b.register(w.reduce(_||_), s1_ghv_wdatas(i), Some(s"s1_new_bit_$i"), 4) 5181ccea249SLingrui98 } 51909c6f1ddSLingrui98 52050f995b1SLingrui98 class PreviousPredInfo extends Bundle { 521b166c0eaSEaston Man val hit = Vec(numDup, Bool()) 522adc0b8dfSGuokai Chen val target = Vec(numDup, UInt(VAddrBits.W)) 523adc0b8dfSGuokai Chen val lastBrPosOH = Vec(numDup, Vec(numBr+1, Bool())) 524adc0b8dfSGuokai Chen val taken = Vec(numDup, Bool()) 525b166c0eaSEaston Man val takenMask = Vec(numDup, Vec(numBr, Bool())) 526adc0b8dfSGuokai Chen val cfiIndex = Vec(numDup, UInt(log2Ceil(PredictWidth).W)) 52750f995b1SLingrui98 } 52850f995b1SLingrui98 529adc0b8dfSGuokai Chen def preds_needs_redirect_vec_dup(x: PreviousPredInfo, y: BranchPredictionBundle) = { 530b166c0eaSEaston Man // Timing optimization 531b166c0eaSEaston Man // We first compare all target with previous stage target, 532b166c0eaSEaston Man // then select the difference by taken & hit 533b166c0eaSEaston Man // Usually target is generated quicker than taken, so do target compare before select can help timing 534b166c0eaSEaston Man val targetDiffVec: IndexedSeq[Vec[Bool]] = 535b166c0eaSEaston Man x.target.zip(y.getAllTargets).map { 5362bf6e0ecSEaston Man case (xTarget, yAllTarget) => VecInit(yAllTarget.map(_ =/= xTarget)) 5372bf6e0ecSEaston Man } // [numDup][all Target comparison] 538b166c0eaSEaston Man val targetDiff : IndexedSeq[Bool] = 539b166c0eaSEaston Man targetDiffVec.zip(x.hit).zip(x.takenMask).map { 540b166c0eaSEaston Man case ((diff, hit), takenMask) => selectByTaken(takenMask, hit, diff) 5412bf6e0ecSEaston Man } // [numDup] 542b166c0eaSEaston Man 543b166c0eaSEaston Man val lastBrPosOHDiff: IndexedSeq[Bool] = x.lastBrPosOH.zip(y.lastBrPosOH).map { case (oh1, oh2) => oh1.asUInt =/= oh2.asUInt } 544b166c0eaSEaston Man val takenDiff : IndexedSeq[Bool] = x.taken.zip(y.taken).map { case (t1, t2) => t1 =/= t2 } 545b166c0eaSEaston Man val takenOffsetDiff: IndexedSeq[Bool] = x.cfiIndex.zip(y.cfiIndex).zip(x.taken).zip(y.taken).map { case (((i1, i2), xt), yt) => xt && yt && i1 =/= i2.bits } 546b37e4b45SLingrui98 VecInit( 547adc0b8dfSGuokai Chen for ((((tgtd, lbpohd), tkd), tod) <- 548b166c0eaSEaston Man targetDiff zip lastBrPosOHDiff zip takenDiff zip takenOffsetDiff) 549adc0b8dfSGuokai Chen yield VecInit(tgtd, lbpohd, tkd, tod) 55086d9c530SLingrui98 // x.shouldShiftVec.asUInt =/= y.shouldShiftVec.asUInt, 55186d9c530SLingrui98 // x.brTaken =/= y.brTaken 552b30c10d6SLingrui98 ) 553b30c10d6SLingrui98 } 554b37e4b45SLingrui98 55509c6f1ddSLingrui98 // s2 556adc0b8dfSGuokai Chen val s2_possible_predicted_ghist_ptrs_dup = s2_ghist_ptr_dup.map(ptr => (0 to numBr).map(ptr - _.U)) 557adc0b8dfSGuokai Chen val s2_predicted_ghist_ptr_dup = s2_possible_predicted_ghist_ptrs_dup.zip(resp.s2.lastBrPosOH).map{ case (ptr, oh) => Mux1H(oh, ptr)} 558b37e4b45SLingrui98 559adc0b8dfSGuokai Chen val s2_possible_predicted_fhs_dup = 560adc0b8dfSGuokai Chen for ((((fgh, afh), br_num_oh), full_pred) <- 561adc0b8dfSGuokai Chen s2_folded_gh_dup zip s2_ahead_fh_oldest_bits_dup zip s2_last_br_num_oh_dup zip resp.s2.full_pred) 562adc0b8dfSGuokai Chen yield (0 to numBr).map(i => 563adc0b8dfSGuokai Chen fgh.update(afh, br_num_oh, i, if (i > 0) full_pred.br_taken_mask(i-1) else false.B) 564adc0b8dfSGuokai Chen ) 565adc0b8dfSGuokai Chen val s2_predicted_fh_dup = resp.s2.lastBrPosOH.zip(s2_possible_predicted_fhs_dup).map{ case (oh, fh) => Mux1H(oh, fh)} 566b37e4b45SLingrui98 567adc0b8dfSGuokai Chen val s2_ahead_fh_ob_src_dup = dup_wire(new AllAheadFoldedHistoryOldestBits(foldedGHistInfos)) 568adc0b8dfSGuokai Chen s2_ahead_fh_ob_src_dup.zip(s2_ghist_ptr_dup).map{ case (src, ptr) => src.read(ghv, ptr)} 56967402d75SLingrui98 57086d9c530SLingrui98 if (EnableGHistDiff) { 571adc0b8dfSGuokai Chen val s2_predicted_ghist = WireInit(getHist(s2_predicted_ghist_ptr_dup(0)).asTypeOf(Vec(HistoryLength, Bool()))) 57286d9c530SLingrui98 for (i <- 0 until numBr) { 573adc0b8dfSGuokai Chen when (resp.s2.shouldShiftVec(0)(i)) { 574adc0b8dfSGuokai Chen s2_predicted_ghist(i) := resp.s2.brTaken(0) && (i==0).B 57586d9c530SLingrui98 } 57686d9c530SLingrui98 } 577adc0b8dfSGuokai Chen when(s2_redirect_dup(0)) { 57886d9c530SLingrui98 s0_ghist := s2_predicted_ghist.asUInt 57986d9c530SLingrui98 } 58086d9c530SLingrui98 } 58186d9c530SLingrui98 582b37e4b45SLingrui98 val s2_ghv_wens = (0 until HistoryLength).map(n => 583adc0b8dfSGuokai Chen (0 until numBr).map(b => (s2_ghist_ptr_dup(0)).value === (CGHPtr(false.B, n.U) + b.U).value && resp.s2.shouldShiftVec(0)(b) && s2_redirect_dup(0))) 584b37e4b45SLingrui98 val s2_ghv_wdatas = (0 until HistoryLength).map(n => 5851ccea249SLingrui98 Mux1H( 586b37e4b45SLingrui98 (0 until numBr).map(b => ( 587adc0b8dfSGuokai Chen (s2_ghist_ptr_dup(0)).value === (CGHPtr(false.B, n.U) + b.U).value && resp.s2.shouldShiftVec(0)(b), 588adc0b8dfSGuokai Chen resp.s2.full_pred(0).real_br_taken_mask()(b) 589b37e4b45SLingrui98 )) 5901ccea249SLingrui98 ) 5911ccea249SLingrui98 ) 5921ccea249SLingrui98 59350f995b1SLingrui98 val s1_pred_info = Wire(new PreviousPredInfo) 594b166c0eaSEaston Man s1_pred_info.hit := resp.s1.full_pred.map(_.hit) 59550f995b1SLingrui98 s1_pred_info.target := resp.s1.getTarget 596adc0b8dfSGuokai Chen s1_pred_info.lastBrPosOH := resp.s1.lastBrPosOH 59750f995b1SLingrui98 s1_pred_info.taken := resp.s1.taken 598b166c0eaSEaston Man s1_pred_info.takenMask := resp.s1.full_pred.map(_.taken_mask_on_slot) 599adc0b8dfSGuokai Chen s1_pred_info.cfiIndex := resp.s1.cfiIndex.map { case x => x.bits } 60009c6f1ddSLingrui98 601935edac4STang Haojin val previous_s1_pred_info = RegEnable(s1_pred_info, 0.U.asTypeOf(new PreviousPredInfo), s1_fire_dup(0)) 60250f995b1SLingrui98 603adc0b8dfSGuokai Chen val s2_redirect_s1_last_pred_vec_dup = preds_needs_redirect_vec_dup(previous_s1_pred_info, resp.s2) 60409c6f1ddSLingrui98 605adc0b8dfSGuokai Chen for (((s2_redirect, s2_fire), s2_redirect_s1_last_pred_vec) <- s2_redirect_dup zip s2_fire_dup zip s2_redirect_s1_last_pred_vec_dup) 60662e6338eSLingrui98 s2_redirect := s2_fire && s2_redirect_s1_last_pred_vec.reduce(_||_) 607ae8ed1a3Szoujr 608adc0b8dfSGuokai Chen 609adc0b8dfSGuokai Chen for (((npcGen, s2_redirect), s2_target) <- npcGen_dup zip s2_redirect_dup zip resp.s2.getTarget) 610adc0b8dfSGuokai Chen npcGen.register(s2_redirect, s2_target, Some("s2_target"), 5) 611adc0b8dfSGuokai Chen for (((foldedGhGen, s2_redirect), s2_predicted_fh) <- foldedGhGen_dup zip s2_redirect_dup zip s2_predicted_fh_dup) 612cb4f77ceSLingrui98 foldedGhGen.register(s2_redirect, s2_predicted_fh, Some("s2_FGH"), 5) 613adc0b8dfSGuokai Chen for (((ghistPtrGen, s2_redirect), s2_predicted_ghist_ptr) <- ghistPtrGen_dup zip s2_redirect_dup zip s2_predicted_ghist_ptr_dup) 614cb4f77ceSLingrui98 ghistPtrGen.register(s2_redirect, s2_predicted_ghist_ptr, Some("s2_GHPtr"), 5) 615adc0b8dfSGuokai Chen for (((lastBrNumOHGen, s2_redirect), s2_brPosOH) <- lastBrNumOHGen_dup zip s2_redirect_dup zip resp.s2.lastBrPosOH.map(_.asUInt)) 616adc0b8dfSGuokai Chen lastBrNumOHGen.register(s2_redirect, s2_brPosOH, Some("s2_BrNumOH"), 5) 617adc0b8dfSGuokai Chen for (((aheadFhObGen, s2_redirect), s2_ahead_fh_ob_src) <- aheadFhObGen_dup zip s2_redirect_dup zip s2_ahead_fh_ob_src_dup) 61867402d75SLingrui98 aheadFhObGen.register(s2_redirect, s2_ahead_fh_ob_src, Some("s2_AFHOB"), 5) 619b37e4b45SLingrui98 ghvBitWriteGens.zip(s2_ghv_wens).zipWithIndex.map{case ((b, w), i) => 620cb4f77ceSLingrui98 b.register(w.reduce(_||_), s2_ghv_wdatas(i), Some(s"s2_new_bit_$i"), 5) 6211ccea249SLingrui98 } 62209c6f1ddSLingrui98 623adc0b8dfSGuokai Chen XSPerfAccumulate("s2_redirect_because_target_diff", s2_fire_dup(0) && s2_redirect_s1_last_pred_vec_dup(0)(0)) 624adc0b8dfSGuokai Chen XSPerfAccumulate("s2_redirect_because_branch_num_diff", s2_fire_dup(0) && s2_redirect_s1_last_pred_vec_dup(0)(1)) 625adc0b8dfSGuokai Chen XSPerfAccumulate("s2_redirect_because_direction_diff", s2_fire_dup(0) && s2_redirect_s1_last_pred_vec_dup(0)(2)) 626adc0b8dfSGuokai Chen XSPerfAccumulate("s2_redirect_because_cfi_idx_diff", s2_fire_dup(0) && s2_redirect_s1_last_pred_vec_dup(0)(3)) 62786d9c530SLingrui98 // XSPerfAccumulate("s2_redirect_because_shouldShiftVec_diff", s2_fire && s2_redirect_s1_last_pred_vec(4)) 62886d9c530SLingrui98 // XSPerfAccumulate("s2_redirect_because_brTaken_diff", s2_fire && s2_redirect_s1_last_pred_vec(5)) 629adc0b8dfSGuokai Chen XSPerfAccumulate("s2_redirect_because_fallThroughError", s2_fire_dup(0) && resp.s2.fallThruError(0)) 63009c6f1ddSLingrui98 631adc0b8dfSGuokai Chen XSPerfAccumulate("s2_redirect_when_taken", s2_redirect_dup(0) && resp.s2.taken(0) && resp.s2.full_pred(0).hit) 632adc0b8dfSGuokai Chen XSPerfAccumulate("s2_redirect_when_not_taken", s2_redirect_dup(0) && !resp.s2.taken(0) && resp.s2.full_pred(0).hit) 633adc0b8dfSGuokai Chen XSPerfAccumulate("s2_redirect_when_not_hit", s2_redirect_dup(0) && !resp.s2.full_pred(0).hit) 634edc18578SLingrui98 6351ccea249SLingrui98 636cb4f77ceSLingrui98 // s3 637adc0b8dfSGuokai Chen val s3_possible_predicted_ghist_ptrs_dup = s3_ghist_ptr_dup.map(ptr => (0 to numBr).map(ptr - _.U)) 638adc0b8dfSGuokai Chen val s3_predicted_ghist_ptr_dup = s3_possible_predicted_ghist_ptrs_dup.zip(resp.s3.lastBrPosOH).map{ case (ptr, oh) => Mux1H(oh, ptr)} 639cb4f77ceSLingrui98 640adc0b8dfSGuokai Chen val s3_possible_predicted_fhs_dup = 641adc0b8dfSGuokai Chen for ((((fgh, afh), br_num_oh), full_pred) <- 642adc0b8dfSGuokai Chen s3_folded_gh_dup zip s3_ahead_fh_oldest_bits_dup zip s3_last_br_num_oh_dup zip resp.s3.full_pred) 643adc0b8dfSGuokai Chen yield (0 to numBr).map(i => 644adc0b8dfSGuokai Chen fgh.update(afh, br_num_oh, i, if (i > 0) full_pred.br_taken_mask(i-1) else false.B) 645adc0b8dfSGuokai Chen ) 646adc0b8dfSGuokai Chen val s3_predicted_fh_dup = resp.s3.lastBrPosOH.zip(s3_possible_predicted_fhs_dup).map{ case (oh, fh) => Mux1H(oh, fh)} 647cb4f77ceSLingrui98 648adc0b8dfSGuokai Chen val s3_ahead_fh_ob_src_dup = dup_wire(new AllAheadFoldedHistoryOldestBits(foldedGHistInfos)) 649adc0b8dfSGuokai Chen s3_ahead_fh_ob_src_dup.zip(s3_ghist_ptr_dup).map{ case (src, ptr) => src.read(ghv, ptr)} 65067402d75SLingrui98 651cb4f77ceSLingrui98 if (EnableGHistDiff) { 652adc0b8dfSGuokai Chen val s3_predicted_ghist = WireInit(getHist(s3_predicted_ghist_ptr_dup(0)).asTypeOf(Vec(HistoryLength, Bool()))) 653cb4f77ceSLingrui98 for (i <- 0 until numBr) { 654adc0b8dfSGuokai Chen when (resp.s3.shouldShiftVec(0)(i)) { 655adc0b8dfSGuokai Chen s3_predicted_ghist(i) := resp.s3.brTaken(0) && (i==0).B 656cb4f77ceSLingrui98 } 657cb4f77ceSLingrui98 } 658adc0b8dfSGuokai Chen when(s3_redirect_dup(0)) { 659cb4f77ceSLingrui98 s0_ghist := s3_predicted_ghist.asUInt 660cb4f77ceSLingrui98 } 661cb4f77ceSLingrui98 } 662cb4f77ceSLingrui98 663cb4f77ceSLingrui98 val s3_ghv_wens = (0 until HistoryLength).map(n => 664adc0b8dfSGuokai Chen (0 until numBr).map(b => (s3_ghist_ptr_dup(0)).value === (CGHPtr(false.B, n.U) + b.U).value && resp.s3.shouldShiftVec(0)(b) && s3_redirect_dup(0))) 665cb4f77ceSLingrui98 val s3_ghv_wdatas = (0 until HistoryLength).map(n => 666cb4f77ceSLingrui98 Mux1H( 667cb4f77ceSLingrui98 (0 until numBr).map(b => ( 668adc0b8dfSGuokai Chen (s3_ghist_ptr_dup(0)).value === (CGHPtr(false.B, n.U) + b.U).value && resp.s3.shouldShiftVec(0)(b), 669adc0b8dfSGuokai Chen resp.s3.full_pred(0).real_br_taken_mask()(b) 670cb4f77ceSLingrui98 )) 671cb4f77ceSLingrui98 ) 672cb4f77ceSLingrui98 ) 673cb4f77ceSLingrui98 674935edac4STang Haojin val previous_s2_pred = RegEnable(resp.s2, 0.U.asTypeOf(resp.s2), s2_fire_dup(0)) 675cb4f77ceSLingrui98 676adc0b8dfSGuokai Chen val s3_redirect_on_br_taken_dup = resp.s3.full_pred.zip(previous_s2_pred.full_pred).map {case (fp1, fp2) => fp1.real_br_taken_mask().asUInt =/= fp2.real_br_taken_mask().asUInt} 677209a4cafSSteve Gou val s3_both_first_taken_dup = resp.s3.full_pred.zip(previous_s2_pred.full_pred).map {case (fp1, fp2) => fp1.real_br_taken_mask()(0) && fp2.real_br_taken_mask()(0)} 678adc0b8dfSGuokai Chen val s3_redirect_on_target_dup = resp.s3.getTarget.zip(previous_s2_pred.getTarget).map {case (t1, t2) => t1 =/= t2} 679adc0b8dfSGuokai Chen val s3_redirect_on_jalr_target_dup = resp.s3.full_pred.zip(previous_s2_pred.full_pred).map {case (fp1, fp2) => fp1.hit_taken_on_jalr && fp1.jalr_target =/= fp2.jalr_target} 680adc0b8dfSGuokai Chen val s3_redirect_on_fall_thru_error_dup = resp.s3.fallThruError 681adc0b8dfSGuokai Chen 682209a4cafSSteve Gou for ((((((s3_redirect, s3_fire), s3_redirect_on_br_taken), s3_redirect_on_target), s3_redirect_on_fall_thru_error), s3_both_first_taken) <- 683209a4cafSSteve Gou s3_redirect_dup zip s3_fire_dup zip s3_redirect_on_br_taken_dup zip s3_redirect_on_target_dup zip s3_redirect_on_fall_thru_error_dup zip s3_both_first_taken_dup) { 684cb4f77ceSLingrui98 68562e6338eSLingrui98 s3_redirect := s3_fire && ( 686209a4cafSSteve Gou (s3_redirect_on_br_taken && !s3_both_first_taken) || s3_redirect_on_target || s3_redirect_on_fall_thru_error 687cb4f77ceSLingrui98 ) 688adc0b8dfSGuokai Chen } 689cb4f77ceSLingrui98 690adc0b8dfSGuokai Chen XSPerfAccumulate(f"s3_redirect_on_br_taken", s3_fire_dup(0) && s3_redirect_on_br_taken_dup(0)) 691adc0b8dfSGuokai Chen XSPerfAccumulate(f"s3_redirect_on_jalr_target", s3_fire_dup(0) && s3_redirect_on_jalr_target_dup(0)) 692adc0b8dfSGuokai Chen XSPerfAccumulate(f"s3_redirect_on_others", s3_redirect_dup(0) && !(s3_redirect_on_br_taken_dup(0) || s3_redirect_on_jalr_target_dup(0))) 693ced16aa1SLingrui98 694adc0b8dfSGuokai Chen for (((npcGen, s3_redirect), s3_target) <- npcGen_dup zip s3_redirect_dup zip resp.s3.getTarget) 695adc0b8dfSGuokai Chen npcGen.register(s3_redirect, s3_target, Some("s3_target"), 3) 696adc0b8dfSGuokai Chen for (((foldedGhGen, s3_redirect), s3_predicted_fh) <- foldedGhGen_dup zip s3_redirect_dup zip s3_predicted_fh_dup) 697cb4f77ceSLingrui98 foldedGhGen.register(s3_redirect, s3_predicted_fh, Some("s3_FGH"), 3) 698adc0b8dfSGuokai Chen for (((ghistPtrGen, s3_redirect), s3_predicted_ghist_ptr) <- ghistPtrGen_dup zip s3_redirect_dup zip s3_predicted_ghist_ptr_dup) 699cb4f77ceSLingrui98 ghistPtrGen.register(s3_redirect, s3_predicted_ghist_ptr, Some("s3_GHPtr"), 3) 700adc0b8dfSGuokai Chen for (((lastBrNumOHGen, s3_redirect), s3_brPosOH) <- lastBrNumOHGen_dup zip s3_redirect_dup zip resp.s3.lastBrPosOH.map(_.asUInt)) 701adc0b8dfSGuokai Chen lastBrNumOHGen.register(s3_redirect, s3_brPosOH, Some("s3_BrNumOH"), 3) 702adc0b8dfSGuokai Chen for (((aheadFhObGen, s3_redirect), s3_ahead_fh_ob_src) <- aheadFhObGen_dup zip s3_redirect_dup zip s3_ahead_fh_ob_src_dup) 70367402d75SLingrui98 aheadFhObGen.register(s3_redirect, s3_ahead_fh_ob_src, Some("s3_AFHOB"), 3) 704cb4f77ceSLingrui98 ghvBitWriteGens.zip(s3_ghv_wens).zipWithIndex.map{case ((b, w), i) => 705cb4f77ceSLingrui98 b.register(w.reduce(_||_), s3_ghv_wdatas(i), Some(s"s3_new_bit_$i"), 3) 706cb4f77ceSLingrui98 } 707cb4f77ceSLingrui98 70809c6f1ddSLingrui98 // Send signal tell Ftq override 709adc0b8dfSGuokai Chen val s2_ftq_idx = RegEnable(io.ftq_to_bpu.enq_ptr, s1_fire_dup(0)) 710adc0b8dfSGuokai Chen val s3_ftq_idx = RegEnable(s2_ftq_idx, s2_fire_dup(0)) 71109c6f1ddSLingrui98 712adc0b8dfSGuokai Chen for (((to_ftq_s1_valid, s1_fire), s1_flush) <- io.bpu_to_ftq.resp.bits.s1.valid zip s1_fire_dup zip s1_flush_dup) { 713adc0b8dfSGuokai Chen to_ftq_s1_valid := s1_fire && !s1_flush 714adc0b8dfSGuokai Chen } 715adc0b8dfSGuokai Chen io.bpu_to_ftq.resp.bits.s1.hasRedirect.map(_ := false.B) 71609c6f1ddSLingrui98 io.bpu_to_ftq.resp.bits.s1.ftq_idx := DontCare 717adc0b8dfSGuokai Chen for (((to_ftq_s2_valid, s2_fire), s2_flush) <- io.bpu_to_ftq.resp.bits.s2.valid zip s2_fire_dup zip s2_flush_dup) { 718adc0b8dfSGuokai Chen to_ftq_s2_valid := s2_fire && !s2_flush 719adc0b8dfSGuokai Chen } 720adc0b8dfSGuokai Chen io.bpu_to_ftq.resp.bits.s2.hasRedirect.zip(s2_redirect_dup).map {case (hr, r) => hr := r} 72109c6f1ddSLingrui98 io.bpu_to_ftq.resp.bits.s2.ftq_idx := s2_ftq_idx 722adc0b8dfSGuokai Chen for (((to_ftq_s3_valid, s3_fire), s3_flush) <- io.bpu_to_ftq.resp.bits.s3.valid zip s3_fire_dup zip s3_flush_dup) { 723adc0b8dfSGuokai Chen to_ftq_s3_valid := s3_fire && !s3_flush 724adc0b8dfSGuokai Chen } 725adc0b8dfSGuokai Chen io.bpu_to_ftq.resp.bits.s3.hasRedirect.zip(s3_redirect_dup).map {case (hr, r) => hr := r} 726cb4f77ceSLingrui98 io.bpu_to_ftq.resp.bits.s3.ftq_idx := s3_ftq_idx 72709c6f1ddSLingrui98 728*7af6acb0SEaston Man predictors.io.update.valid := RegNext(io.ftq_to_bpu.update.valid, init = false.B) 729*7af6acb0SEaston Man predictors.io.update.bits := RegEnable(io.ftq_to_bpu.update.bits, io.ftq_to_bpu.update.valid) 730*7af6acb0SEaston Man predictors.io.update.bits.ghist := RegEnable( 731*7af6acb0SEaston Man getHist(io.ftq_to_bpu.update.bits.spec_info.histPtr), io.ftq_to_bpu.update.valid) 732adc0b8dfSGuokai Chen 733adc0b8dfSGuokai Chen val redirect_dup = do_redirect_dup.map(_.bits) 734adc0b8dfSGuokai Chen predictors.io.redirect := do_redirect_dup(0) 73509c6f1ddSLingrui98 736ae8ed1a3Szoujr // Redirect logic 737adc0b8dfSGuokai Chen val shift_dup = redirect_dup.map(_.cfiUpdate.shift) 738adc0b8dfSGuokai Chen val addIntoHist_dup = redirect_dup.map(_.cfiUpdate.addIntoHist) 7391ccea249SLingrui98 // TODO: remove these below 740935edac4STang Haojin val shouldShiftVec_dup = shift_dup.map(shift => Mux(shift === 0.U, VecInit(0.U((1 << (log2Ceil(numBr) + 1)).W).asBools), VecInit((LowerMask(1.U << (shift-1.U))).asBools))) 7411ccea249SLingrui98 // TODO end 742adc0b8dfSGuokai Chen val afhob_dup = redirect_dup.map(_.cfiUpdate.afhob) 743adc0b8dfSGuokai Chen val lastBrNumOH_dup = redirect_dup.map(_.cfiUpdate.lastBrNumOH) 74467402d75SLingrui98 74509c6f1ddSLingrui98 746adc0b8dfSGuokai Chen val isBr_dup = redirect_dup.map(_.cfiUpdate.pd.isBr) 747adc0b8dfSGuokai Chen val taken_dup = redirect_dup.map(_.cfiUpdate.taken) 748adc0b8dfSGuokai Chen val real_br_taken_mask_dup = 749adc0b8dfSGuokai Chen for (((shift, taken), addIntoHist) <- shift_dup zip taken_dup zip addIntoHist_dup) 750adc0b8dfSGuokai Chen yield (0 until numBr).map(i => shift === (i+1).U && taken && addIntoHist ) 75109c6f1ddSLingrui98 752adc0b8dfSGuokai Chen val oldPtr_dup = redirect_dup.map(_.cfiUpdate.histPtr) 753adc0b8dfSGuokai Chen val oldFh_dup = redirect_dup.map(_.cfiUpdate.folded_hist) 754adc0b8dfSGuokai Chen val updated_ptr_dup = oldPtr_dup.zip(shift_dup).map {case (oldPtr, shift) => oldPtr - shift} 755adc0b8dfSGuokai Chen val updated_fh_dup = 756adc0b8dfSGuokai Chen for ((((((oldFh, afhob), lastBrNumOH), taken), addIntoHist), shift) <- 757adc0b8dfSGuokai Chen oldFh_dup zip afhob_dup zip lastBrNumOH_dup zip taken_dup zip addIntoHist_dup zip shift_dup) 758adc0b8dfSGuokai Chen yield VecInit((0 to numBr).map(i => oldFh.update(afhob, lastBrNumOH, i, taken && addIntoHist)))(shift) 759adc0b8dfSGuokai Chen val thisBrNumOH_dup = shift_dup.map(shift => UIntToOH(shift, numBr+1)) 760adc0b8dfSGuokai Chen val thisAheadFhOb_dup = dup_wire(new AllAheadFoldedHistoryOldestBits(foldedGHistInfos)) 761adc0b8dfSGuokai Chen thisAheadFhOb_dup.zip(oldPtr_dup).map {case (afhob, oldPtr) => afhob.read(ghv, oldPtr)} 762b37e4b45SLingrui98 val redirect_ghv_wens = (0 until HistoryLength).map(n => 763adc0b8dfSGuokai Chen (0 until numBr).map(b => oldPtr_dup(0).value === (CGHPtr(false.B, n.U) + b.U).value && shouldShiftVec_dup(0)(b) && do_redirect_dup(0).valid)) 764b37e4b45SLingrui98 val redirect_ghv_wdatas = (0 until HistoryLength).map(n => 7651ccea249SLingrui98 Mux1H( 766adc0b8dfSGuokai Chen (0 until numBr).map(b => oldPtr_dup(0).value === (CGHPtr(false.B, n.U) + b.U).value && shouldShiftVec_dup(0)(b)), 767adc0b8dfSGuokai Chen real_br_taken_mask_dup(0) 7681ccea249SLingrui98 ) 7691ccea249SLingrui98 ) 7701ccea249SLingrui98 77186d9c530SLingrui98 if (EnableGHistDiff) { 772adc0b8dfSGuokai Chen val updated_ghist = WireInit(getHist(updated_ptr_dup(0)).asTypeOf(Vec(HistoryLength, Bool()))) 77386d9c530SLingrui98 for (i <- 0 until numBr) { 774adc0b8dfSGuokai Chen when (shift_dup(0) >= (i+1).U) { 775adc0b8dfSGuokai Chen updated_ghist(i) := taken_dup(0) && addIntoHist_dup(0) && (i==0).B 77686d9c530SLingrui98 } 77786d9c530SLingrui98 } 778adc0b8dfSGuokai Chen when(do_redirect_dup(0).valid) { 77986d9c530SLingrui98 s0_ghist := updated_ghist.asUInt 78086d9c530SLingrui98 } 78186d9c530SLingrui98 } 78286d9c530SLingrui98 78309d0c404SEaston Man // Commit time history checker 784ab0200c8SEaston Man if (EnableCommitGHistDiff) { 78509d0c404SEaston Man val commitGHist = RegInit(0.U.asTypeOf(Vec(HistoryLength, Bool()))) 78609d0c404SEaston Man val commitGHistPtr = RegInit(0.U.asTypeOf(new CGHPtr)) 78794a3f0aaSEaston Man def getCommitHist(ptr: CGHPtr): UInt = 78894a3f0aaSEaston Man (Cat(commitGHist.asUInt, commitGHist.asUInt) >> (ptr.value+1.U))(HistoryLength-1, 0) 78909d0c404SEaston Man 790ab0200c8SEaston Man val updateValid : Bool = io.ftq_to_bpu.update.valid 791cc2d1573SEaston Man val branchValidMask : UInt = io.ftq_to_bpu.update.bits.ftb_entry.brValids.asUInt 792cc2d1573SEaston Man val branchCommittedMask: Vec[Bool] = io.ftq_to_bpu.update.bits.br_committed 793200d06ccSEaston Man val misPredictMask : UInt = io.ftq_to_bpu.update.bits.mispred_mask.asUInt 794200d06ccSEaston Man val takenMask : UInt = 795200d06ccSEaston Man io.ftq_to_bpu.update.bits.br_taken_mask.asUInt | 796200d06ccSEaston Man io.ftq_to_bpu.update.bits.ftb_entry.always_taken.asUInt // Always taken branch is recorded in history 797200d06ccSEaston Man val takenIdx : UInt = (PriorityEncoder(takenMask) + 1.U((log2Ceil(numBr)+1).W)).asUInt 798200d06ccSEaston Man val misPredictIdx : UInt = (PriorityEncoder(misPredictMask) + 1.U((log2Ceil(numBr)+1).W)).asUInt 799200d06ccSEaston Man val shouldShiftMask: UInt = Mux(takenMask.orR, 800200d06ccSEaston Man LowerMask(takenIdx).asUInt, 801200d06ccSEaston Man ((1 << numBr) - 1).asUInt) & 802200d06ccSEaston Man Mux(misPredictMask.orR, 803200d06ccSEaston Man LowerMask(misPredictIdx).asUInt, 804cc2d1573SEaston Man ((1 << numBr) - 1).asUInt) & 805cc2d1573SEaston Man branchCommittedMask.asUInt 806ab0200c8SEaston Man val updateShift : UInt = 807ab0200c8SEaston Man Mux(updateValid && branchValidMask.orR, PopCount(branchValidMask & shouldShiftMask), 0.U) 808ab0200c8SEaston Man 80909d0c404SEaston Man // Maintain the commitGHist 81009d0c404SEaston Man for (i <- 0 until numBr) { 811200d06ccSEaston Man when(updateShift >= (i + 1).U) { 812200d06ccSEaston Man val ptr: CGHPtr = commitGHistPtr - i.asUInt 813200d06ccSEaston Man commitGHist(ptr.value) := takenMask(i) 81409d0c404SEaston Man } 81509d0c404SEaston Man } 816200d06ccSEaston Man when(updateValid) { 817200d06ccSEaston Man commitGHistPtr := commitGHistPtr - updateShift 81809d0c404SEaston Man } 81909d0c404SEaston Man 82009d0c404SEaston Man // Calculate true history using Parallel XOR 82109d0c404SEaston Man def computeFoldedHist(hist: UInt, compLen: Int)(histLen: Int): UInt = { 82209d0c404SEaston Man if (histLen > 0) { 82309d0c404SEaston Man val nChunks = (histLen + compLen - 1) / compLen 82409d0c404SEaston Man val hist_chunks = (0 until nChunks) map { i => 82509d0c404SEaston Man hist(min((i + 1) * compLen, histLen) - 1, i * compLen) 82609d0c404SEaston Man } 82709d0c404SEaston Man ParallelXOR(hist_chunks) 82809d0c404SEaston Man } 82909d0c404SEaston Man else 0.U 83009d0c404SEaston Man } 83109d0c404SEaston Man // Do differential 83209d0c404SEaston Man val predictFHistAll: AllFoldedHistories = io.ftq_to_bpu.update.bits.spec_info.folded_hist 83309d0c404SEaston Man TageTableInfos.map { 83409d0c404SEaston Man case (nRows, histLen, _) => { 83509d0c404SEaston Man val nRowsPerBr = nRows / numBr 83694a3f0aaSEaston Man val commitTrueHist: UInt = computeFoldedHist(getCommitHist(commitGHistPtr), log2Ceil(nRowsPerBr))(histLen) 83709d0c404SEaston Man val predictFHist : UInt = predictFHistAll. 83809d0c404SEaston Man getHistWithInfo((histLen, min(histLen, log2Ceil(nRowsPerBr)))).folded_hist 83965c5c719SEaston Man XSWarn(updateValid && predictFHist =/= commitTrueHist, 84009d0c404SEaston Man p"predict time ghist: ${predictFHist} is different from commit time: ${commitTrueHist}\n") 84109d0c404SEaston Man } 84209d0c404SEaston Man } 84309d0c404SEaston Man } 84409d0c404SEaston Man 8451ccea249SLingrui98 846c2ad24ebSLingrui98 // val updatedGh = oldGh.update(shift, taken && addIntoHist) 847adc0b8dfSGuokai Chen for ((npcGen, do_redirect) <- npcGen_dup zip do_redirect_dup) 84853bac374SLingrui98 npcGen.register(do_redirect.valid, do_redirect.bits.cfiUpdate.target, Some("redirect_target"), 2) 849adc0b8dfSGuokai Chen for (((foldedGhGen, do_redirect), updated_fh) <- foldedGhGen_dup zip do_redirect_dup zip updated_fh_dup) 85053bac374SLingrui98 foldedGhGen.register(do_redirect.valid, updated_fh, Some("redirect_FGHT"), 2) 851adc0b8dfSGuokai Chen for (((ghistPtrGen, do_redirect), updated_ptr) <- ghistPtrGen_dup zip do_redirect_dup zip updated_ptr_dup) 85253bac374SLingrui98 ghistPtrGen.register(do_redirect.valid, updated_ptr, Some("redirect_GHPtr"), 2) 853adc0b8dfSGuokai Chen for (((lastBrNumOHGen, do_redirect), thisBrNumOH) <- lastBrNumOHGen_dup zip do_redirect_dup zip thisBrNumOH_dup) 85467402d75SLingrui98 lastBrNumOHGen.register(do_redirect.valid, thisBrNumOH, Some("redirect_BrNumOH"), 2) 855adc0b8dfSGuokai Chen for (((aheadFhObGen, do_redirect), thisAheadFhOb) <- aheadFhObGen_dup zip do_redirect_dup zip thisAheadFhOb_dup) 85667402d75SLingrui98 aheadFhObGen.register(do_redirect.valid, thisAheadFhOb, Some("redirect_AFHOB"), 2) 857b37e4b45SLingrui98 ghvBitWriteGens.zip(redirect_ghv_wens).zipWithIndex.map{case ((b, w), i) => 858b37e4b45SLingrui98 b.register(w.reduce(_||_), redirect_ghv_wdatas(i), Some(s"redirect_new_bit_$i"), 2) 8591ccea249SLingrui98 } 860c2ad24ebSLingrui98 // no need to assign s0_last_pred 861c2ad24ebSLingrui98 86267402d75SLingrui98 // val need_reset = RegNext(reset.asBool) && !reset.asBool 863ae8ed1a3Szoujr 864ae8ed1a3Szoujr // Reset 86567402d75SLingrui98 // npcGen.register(need_reset, resetVector.U, Some("reset_pc"), 1) 86667402d75SLingrui98 // foldedGhGen.register(need_reset, 0.U.asTypeOf(s0_folded_gh), Some("reset_FGH"), 1) 86767402d75SLingrui98 // ghistPtrGen.register(need_reset, 0.U.asTypeOf(new CGHPtr), Some("reset_GHPtr"), 1) 868ae8ed1a3Szoujr 869adc0b8dfSGuokai Chen s0_pc_dup.zip(npcGen_dup).map {case (s0_pc, npcGen) => s0_pc := npcGen()} 870adc0b8dfSGuokai Chen s0_folded_gh_dup.zip(foldedGhGen_dup).map {case (s0_folded_gh, foldedGhGen) => s0_folded_gh := foldedGhGen()} 871adc0b8dfSGuokai Chen s0_ghist_ptr_dup.zip(ghistPtrGen_dup).map {case (s0_ghist_ptr, ghistPtrGen) => s0_ghist_ptr := ghistPtrGen()} 872adc0b8dfSGuokai Chen s0_ahead_fh_oldest_bits_dup.zip(aheadFhObGen_dup).map {case (s0_ahead_fh_oldest_bits, aheadFhObGen) => 873adc0b8dfSGuokai Chen s0_ahead_fh_oldest_bits := aheadFhObGen()} 874adc0b8dfSGuokai Chen s0_last_br_num_oh_dup.zip(lastBrNumOHGen_dup).map {case (s0_last_br_num_oh, lastBrNumOHGen) => 875adc0b8dfSGuokai Chen s0_last_br_num_oh := lastBrNumOHGen()} 876b37e4b45SLingrui98 (ghv_write_datas zip ghvBitWriteGens).map{case (wd, d) => wd := d()} 8771ccea249SLingrui98 for (i <- 0 until HistoryLength) { 878cb4f77ceSLingrui98 ghv_wens(i) := Seq(s1_ghv_wens, s2_ghv_wens, s3_ghv_wens, redirect_ghv_wens).map(_(i).reduce(_||_)).reduce(_||_) 879b37e4b45SLingrui98 when (ghv_wens(i)) { 880b37e4b45SLingrui98 ghv(i) := ghv_write_datas(i) 8811ccea249SLingrui98 } 8821ccea249SLingrui98 } 88309c6f1ddSLingrui98 884d2b20d1aSTang Haojin // TODO: signals for memVio and other Redirects 885adc0b8dfSGuokai Chen controlRedirectBubble := do_redirect_dup(0).valid && do_redirect_dup(0).bits.ControlRedirectBubble 886adc0b8dfSGuokai Chen ControlBTBMissBubble := do_redirect_dup(0).bits.ControlBTBMissBubble 887adc0b8dfSGuokai Chen TAGEMissBubble := do_redirect_dup(0).bits.TAGEMissBubble 888adc0b8dfSGuokai Chen SCMissBubble := do_redirect_dup(0).bits.SCMissBubble 889adc0b8dfSGuokai Chen ITTAGEMissBubble := do_redirect_dup(0).bits.ITTAGEMissBubble 890adc0b8dfSGuokai Chen RASMissBubble := do_redirect_dup(0).bits.RASMissBubble 891d2b20d1aSTang Haojin 892adc0b8dfSGuokai Chen memVioRedirectBubble := do_redirect_dup(0).valid && do_redirect_dup(0).bits.MemVioRedirectBubble 893adc0b8dfSGuokai Chen otherRedirectBubble := do_redirect_dup(0).valid && do_redirect_dup(0).bits.OtherRedirectBubble 894adc0b8dfSGuokai Chen btbMissBubble := do_redirect_dup(0).valid && do_redirect_dup(0).bits.BTBMissBubble 895adc0b8dfSGuokai Chen overrideBubble(0) := s2_redirect_dup(0) 896adc0b8dfSGuokai Chen overrideBubble(1) := s3_redirect_dup(0) 897adc0b8dfSGuokai Chen ftqUpdateBubble(0) := !s1_components_ready_dup(0) 898adc0b8dfSGuokai Chen ftqUpdateBubble(1) := !s2_components_ready_dup(0) 899adc0b8dfSGuokai Chen ftqUpdateBubble(2) := !s3_components_ready_dup(0) 900d2b20d1aSTang Haojin ftqFullStall := !io.bpu_to_ftq.resp.ready 901d2b20d1aSTang Haojin io.bpu_to_ftq.resp.bits.topdown_info := topdown_stages(numOfStage - 1) 902d2b20d1aSTang Haojin 903d2b20d1aSTang Haojin // topdown handling logic here 904d2b20d1aSTang Haojin when (controlRedirectBubble) { 905d2b20d1aSTang Haojin /* 906d2b20d1aSTang Haojin for (i <- 0 until numOfStage) 907d2b20d1aSTang Haojin topdown_stages(i).reasons(TopDownCounters.ControlRedirectBubble.id) := true.B 908d2b20d1aSTang Haojin io.bpu_to_ftq.resp.bits.topdown_info.reasons(TopDownCounters.ControlRedirectBubble.id) := true.B 909d2b20d1aSTang Haojin */ 910d2b20d1aSTang Haojin when (ControlBTBMissBubble) { 911d2b20d1aSTang Haojin for (i <- 0 until numOfStage) 912d2b20d1aSTang Haojin topdown_stages(i).reasons(TopDownCounters.BTBMissBubble.id) := true.B 913d2b20d1aSTang Haojin io.bpu_to_ftq.resp.bits.topdown_info.reasons(TopDownCounters.BTBMissBubble.id) := true.B 914d2b20d1aSTang Haojin } .elsewhen (TAGEMissBubble) { 915d2b20d1aSTang Haojin for (i <- 0 until numOfStage) 916d2b20d1aSTang Haojin topdown_stages(i).reasons(TopDownCounters.TAGEMissBubble.id) := true.B 917d2b20d1aSTang Haojin io.bpu_to_ftq.resp.bits.topdown_info.reasons(TopDownCounters.TAGEMissBubble.id) := true.B 918d2b20d1aSTang Haojin } .elsewhen (SCMissBubble) { 919d2b20d1aSTang Haojin for (i <- 0 until numOfStage) 920d2b20d1aSTang Haojin topdown_stages(i).reasons(TopDownCounters.SCMissBubble.id) := true.B 921d2b20d1aSTang Haojin io.bpu_to_ftq.resp.bits.topdown_info.reasons(TopDownCounters.SCMissBubble.id) := true.B 922d2b20d1aSTang Haojin } .elsewhen (ITTAGEMissBubble) { 923d2b20d1aSTang Haojin for (i <- 0 until numOfStage) 924d2b20d1aSTang Haojin topdown_stages(i).reasons(TopDownCounters.ITTAGEMissBubble.id) := true.B 925d2b20d1aSTang Haojin io.bpu_to_ftq.resp.bits.topdown_info.reasons(TopDownCounters.ITTAGEMissBubble.id) := true.B 926d2b20d1aSTang Haojin } .elsewhen (RASMissBubble) { 927d2b20d1aSTang Haojin for (i <- 0 until numOfStage) 928d2b20d1aSTang Haojin topdown_stages(i).reasons(TopDownCounters.RASMissBubble.id) := true.B 929d2b20d1aSTang Haojin io.bpu_to_ftq.resp.bits.topdown_info.reasons(TopDownCounters.RASMissBubble.id) := true.B 930d2b20d1aSTang Haojin } 931d2b20d1aSTang Haojin } 932d2b20d1aSTang Haojin when (memVioRedirectBubble) { 933d2b20d1aSTang Haojin for (i <- 0 until numOfStage) 934d2b20d1aSTang Haojin topdown_stages(i).reasons(TopDownCounters.MemVioRedirectBubble.id) := true.B 935d2b20d1aSTang Haojin io.bpu_to_ftq.resp.bits.topdown_info.reasons(TopDownCounters.MemVioRedirectBubble.id) := true.B 936d2b20d1aSTang Haojin } 937d2b20d1aSTang Haojin when (otherRedirectBubble) { 938d2b20d1aSTang Haojin for (i <- 0 until numOfStage) 939d2b20d1aSTang Haojin topdown_stages(i).reasons(TopDownCounters.OtherRedirectBubble.id) := true.B 940d2b20d1aSTang Haojin io.bpu_to_ftq.resp.bits.topdown_info.reasons(TopDownCounters.OtherRedirectBubble.id) := true.B 941d2b20d1aSTang Haojin } 942d2b20d1aSTang Haojin when (btbMissBubble) { 943d2b20d1aSTang Haojin for (i <- 0 until numOfStage) 944d2b20d1aSTang Haojin topdown_stages(i).reasons(TopDownCounters.BTBMissBubble.id) := true.B 945d2b20d1aSTang Haojin io.bpu_to_ftq.resp.bits.topdown_info.reasons(TopDownCounters.BTBMissBubble.id) := true.B 946d2b20d1aSTang Haojin } 947d2b20d1aSTang Haojin 948d2b20d1aSTang Haojin for (i <- 0 until numOfStage) { 949d2b20d1aSTang Haojin if (i < numOfStage - overrideStage) { 950d2b20d1aSTang Haojin when (overrideBubble(i)) { 951d2b20d1aSTang Haojin for (j <- 0 to i) 952d2b20d1aSTang Haojin topdown_stages(j).reasons(TopDownCounters.OverrideBubble.id) := true.B 953d2b20d1aSTang Haojin } 954d2b20d1aSTang Haojin } 955d2b20d1aSTang Haojin if (i < numOfStage - ftqUpdateStage) { 956d2b20d1aSTang Haojin when (ftqUpdateBubble(i)) { 957d2b20d1aSTang Haojin topdown_stages(i).reasons(TopDownCounters.FtqUpdateBubble.id) := true.B 958d2b20d1aSTang Haojin } 959d2b20d1aSTang Haojin } 960d2b20d1aSTang Haojin } 961d2b20d1aSTang Haojin when (ftqFullStall) { 962d2b20d1aSTang Haojin topdown_stages(0).reasons(TopDownCounters.FtqFullStall.id) := true.B 963d2b20d1aSTang Haojin } 964d2b20d1aSTang Haojin 965adc0b8dfSGuokai Chen XSError(isBefore(redirect_dup(0).cfiUpdate.histPtr, s3_ghist_ptr_dup(0)) && do_redirect_dup(0).valid, 966adc0b8dfSGuokai Chen p"s3_ghist_ptr ${s3_ghist_ptr_dup(0)} exceeds redirect histPtr ${redirect_dup(0).cfiUpdate.histPtr}\n") 967adc0b8dfSGuokai Chen XSError(isBefore(redirect_dup(0).cfiUpdate.histPtr, s2_ghist_ptr_dup(0)) && do_redirect_dup(0).valid, 968adc0b8dfSGuokai Chen p"s2_ghist_ptr ${s2_ghist_ptr_dup(0)} exceeds redirect histPtr ${redirect_dup(0).cfiUpdate.histPtr}\n") 969adc0b8dfSGuokai Chen XSError(isBefore(redirect_dup(0).cfiUpdate.histPtr, s1_ghist_ptr_dup(0)) && do_redirect_dup(0).valid, 970adc0b8dfSGuokai Chen p"s1_ghist_ptr ${s1_ghist_ptr_dup(0)} exceeds redirect histPtr ${redirect_dup(0).cfiUpdate.histPtr}\n") 971c7fabd05SSteve Gou 97209c6f1ddSLingrui98 XSDebug(RegNext(reset.asBool) && !reset.asBool, "Reseting...\n") 97309c6f1ddSLingrui98 XSDebug(io.ftq_to_bpu.update.valid, p"Update from ftq\n") 97409c6f1ddSLingrui98 XSDebug(io.ftq_to_bpu.redirect.valid, p"Redirect from ftq\n") 97509c6f1ddSLingrui98 976adc0b8dfSGuokai Chen XSDebug("[BP0] fire=%d pc=%x\n", s0_fire_dup(0), s0_pc_dup(0)) 97709c6f1ddSLingrui98 XSDebug("[BP1] v=%d r=%d cr=%d fire=%d flush=%d pc=%x\n", 978adc0b8dfSGuokai Chen s1_valid_dup(0), s1_ready_dup(0), s1_components_ready_dup(0), s1_fire_dup(0), s1_flush_dup(0), s1_pc) 97909c6f1ddSLingrui98 XSDebug("[BP2] v=%d r=%d cr=%d fire=%d redirect=%d flush=%d pc=%x\n", 980adc0b8dfSGuokai Chen s2_valid_dup(0), s2_ready_dup(0), s2_components_ready_dup(0), s2_fire_dup(0), s2_redirect_dup(0), s2_flush_dup(0), s2_pc) 981cb4f77ceSLingrui98 XSDebug("[BP3] v=%d r=%d cr=%d fire=%d redirect=%d flush=%d pc=%x\n", 982adc0b8dfSGuokai Chen s3_valid_dup(0), s3_ready_dup(0), s3_components_ready_dup(0), s3_fire_dup(0), s3_redirect_dup(0), s3_flush_dup(0), s3_pc) 98309c6f1ddSLingrui98 XSDebug("[FTQ] ready=%d\n", io.bpu_to_ftq.resp.ready) 984adc0b8dfSGuokai Chen XSDebug("resp.s1.target=%x\n", resp.s1.getTarget(0)) 985adc0b8dfSGuokai Chen XSDebug("resp.s2.target=%x\n", resp.s2.getTarget(0)) 986c2ad24ebSLingrui98 // XSDebug("s0_ghist: %b\n", s0_ghist.predHist) 987c2ad24ebSLingrui98 // XSDebug("s1_ghist: %b\n", s1_ghist.predHist) 988c2ad24ebSLingrui98 // XSDebug("s2_ghist: %b\n", s2_ghist.predHist) 989c2ad24ebSLingrui98 // XSDebug("s2_predicted_ghist: %b\n", s2_predicted_ghist.predHist) 990adc0b8dfSGuokai Chen XSDebug(p"s0_ghist_ptr: ${s0_ghist_ptr_dup(0)}\n") 991adc0b8dfSGuokai Chen XSDebug(p"s1_ghist_ptr: ${s1_ghist_ptr_dup(0)}\n") 992adc0b8dfSGuokai Chen XSDebug(p"s2_ghist_ptr: ${s2_ghist_ptr_dup(0)}\n") 993adc0b8dfSGuokai Chen XSDebug(p"s3_ghist_ptr: ${s3_ghist_ptr_dup(0)}\n") 99409c6f1ddSLingrui98 99509c6f1ddSLingrui98 io.ftq_to_bpu.update.bits.display(io.ftq_to_bpu.update.valid) 99609c6f1ddSLingrui98 io.ftq_to_bpu.redirect.bits.display(io.ftq_to_bpu.redirect.valid) 99709c6f1ddSLingrui98 99809c6f1ddSLingrui98 999adc0b8dfSGuokai Chen XSPerfAccumulate("s2_redirect", s2_redirect_dup(0)) 1000adc0b8dfSGuokai Chen XSPerfAccumulate("s3_redirect", s3_redirect_dup(0)) 1001adc0b8dfSGuokai Chen XSPerfAccumulate("s1_not_valid", !s1_valid_dup(0)) 100209c6f1ddSLingrui98 10031ca0e4f3SYinan Xu val perfEvents = predictors.asInstanceOf[Composer].getPerfEvents 10041ca0e4f3SYinan Xu generatePerfEvent() 100509c6f1ddSLingrui98} 1006