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***************************************************************************************/ 1609c6f1ddSLingrui98package xiangshan.frontend 1709c6f1ddSLingrui98 1809c6f1ddSLingrui98import chipsalliance.rocketchip.config.Parameters 1909c6f1ddSLingrui98import chisel3._ 2009c6f1ddSLingrui98import chisel3.util._ 21bf358e08SLingrui98import chisel3.experimental.chiselName 2209c6f1ddSLingrui98import xiangshan._ 2309c6f1ddSLingrui98import utils._ 2409c6f1ddSLingrui98 25bf358e08SLingrui98@chiselName 2609c6f1ddSLingrui98class FetchRequestBundle(implicit p: Parameters) extends XSBundle { 2709c6f1ddSLingrui98 val startAddr = UInt(VAddrBits.W) 2809c6f1ddSLingrui98 val fallThruAddr = UInt(VAddrBits.W) 2909c6f1ddSLingrui98 val fallThruError = Bool() 3009c6f1ddSLingrui98 val ftqIdx = new FtqPtr 3109c6f1ddSLingrui98 val ftqOffset = ValidUndirectioned(UInt(log2Ceil(PredictWidth).W)) 3209c6f1ddSLingrui98 val target = UInt(VAddrBits.W) 3309c6f1ddSLingrui98 val oversize = Bool() 3409c6f1ddSLingrui98 3509c6f1ddSLingrui98 def fallThroughError() = { 3609c6f1ddSLingrui98 def carryPos = instOffsetBits+log2Ceil(PredictWidth)+1 3709c6f1ddSLingrui98 def getLower(pc: UInt) = pc(instOffsetBits+log2Ceil(PredictWidth), instOffsetBits) 3809c6f1ddSLingrui98 val carry = (startAddr(carryPos) =/= fallThruAddr(carryPos)).asUInt 3909c6f1ddSLingrui98 val startLower = Cat(0.U(1.W), getLower(startAddr)) 4009c6f1ddSLingrui98 val endLowerwithCarry = Cat(carry, getLower(fallThruAddr)) 4109c6f1ddSLingrui98 require(startLower.getWidth == log2Ceil(PredictWidth)+2) 4209c6f1ddSLingrui98 require(endLowerwithCarry.getWidth == log2Ceil(PredictWidth)+2) 4309c6f1ddSLingrui98 startLower >= endLowerwithCarry || (endLowerwithCarry - startLower) > (PredictWidth+1).U 4409c6f1ddSLingrui98 } 4509c6f1ddSLingrui98 def fromFtqPcBundle(b: Ftq_RF_Components) = { 4609c6f1ddSLingrui98 this.startAddr := b.startAddr 4709c6f1ddSLingrui98 this.fallThruAddr := b.getFallThrough() 4809c6f1ddSLingrui98 this.oversize := b.oversize 4909c6f1ddSLingrui98 this 5009c6f1ddSLingrui98 } 5109c6f1ddSLingrui98 def fromBpuResp(resp: BranchPredictionBundle) = { 5209c6f1ddSLingrui98 // only used to bypass, so some fields remains unchanged 5309c6f1ddSLingrui98 this.startAddr := resp.pc 5409c6f1ddSLingrui98 this.target := resp.target 5509c6f1ddSLingrui98 this.ftqOffset := resp.genCfiIndex 5609c6f1ddSLingrui98 this.fallThruAddr := resp.fallThroughAddr 5709c6f1ddSLingrui98 this.oversize := resp.ftb_entry.oversize 5809c6f1ddSLingrui98 this 5909c6f1ddSLingrui98 } 6009c6f1ddSLingrui98 override def toPrintable: Printable = { 6109c6f1ddSLingrui98 p"[start] ${Hexadecimal(startAddr)} [pft] ${Hexadecimal(fallThruAddr)}" + 6209c6f1ddSLingrui98 p"[tgt] ${Hexadecimal(target)} [ftqIdx] $ftqIdx [jmp] v:${ftqOffset.valid}" + 6309c6f1ddSLingrui98 p" offset: ${ftqOffset.bits}\n" 6409c6f1ddSLingrui98 } 6509c6f1ddSLingrui98} 6609c6f1ddSLingrui98 6709c6f1ddSLingrui98class PredecodeWritebackBundle(implicit p:Parameters) extends XSBundle { 6809c6f1ddSLingrui98 val pc = Vec(PredictWidth, UInt(VAddrBits.W)) 6909c6f1ddSLingrui98 val pd = Vec(PredictWidth, new PreDecodeInfo) // TODO: redefine Predecode 7009c6f1ddSLingrui98 val ftqIdx = new FtqPtr 7109c6f1ddSLingrui98 val ftqOffset = UInt(log2Ceil(PredictWidth).W) 7209c6f1ddSLingrui98 val misOffset = ValidUndirectioned(UInt(log2Ceil(PredictWidth).W)) 7309c6f1ddSLingrui98 val cfiOffset = ValidUndirectioned(UInt(log2Ceil(PredictWidth).W)) 7409c6f1ddSLingrui98 val target = UInt(VAddrBits.W) 7509c6f1ddSLingrui98 val jalTarget = UInt(VAddrBits.W) 7609c6f1ddSLingrui98 val instrRange = Vec(PredictWidth, Bool()) 7709c6f1ddSLingrui98} 7809c6f1ddSLingrui98 7909c6f1ddSLingrui98class Exception(implicit p: Parameters) extends XSBundle { 8009c6f1ddSLingrui98 8109c6f1ddSLingrui98} 8209c6f1ddSLingrui98 8309c6f1ddSLingrui98class FetchToIBuffer(implicit p: Parameters) extends XSBundle { 8409c6f1ddSLingrui98 val instrs = Vec(PredictWidth, UInt(32.W)) 8509c6f1ddSLingrui98 val valid = UInt(PredictWidth.W) 8609c6f1ddSLingrui98 val pd = Vec(PredictWidth, new PreDecodeInfo) 8709c6f1ddSLingrui98 val pc = Vec(PredictWidth, UInt(VAddrBits.W)) 8809c6f1ddSLingrui98 val foldpc = Vec(PredictWidth, UInt(MemPredPCWidth.W)) 8909c6f1ddSLingrui98 //val exception = new Exception 9009c6f1ddSLingrui98 val ftqPtr = new FtqPtr 9109c6f1ddSLingrui98 val ftqOffset = Vec(PredictWidth, ValidUndirectioned(UInt(log2Ceil(PredictWidth).W))) 9209c6f1ddSLingrui98 val ipf = Vec(PredictWidth, Bool()) 9309c6f1ddSLingrui98 val acf = Vec(PredictWidth, Bool()) 9409c6f1ddSLingrui98 val crossPageIPFFix = Vec(PredictWidth, Bool()) 9509c6f1ddSLingrui98} 9609c6f1ddSLingrui98 9709c6f1ddSLingrui98// Move from BPU 9809c6f1ddSLingrui98class GlobalHistory(implicit p: Parameters) extends XSBundle with HasBPUConst { 9909c6f1ddSLingrui98 val predHist = UInt(HistoryLength.W) 10009c6f1ddSLingrui98 // def update(sawNTBr: Bool, takenOnBr: Bool, hist: UInt = predHist): GlobalHistory = { 10109c6f1ddSLingrui98 // val g = Wire(new GlobalHistory) 10209c6f1ddSLingrui98 // val shifted = takenOnBr || sawNTBr 10309c6f1ddSLingrui98 // g.predHist := Mux(shifted, (hist << 1) | takenOnBr.asUInt, hist) 10409c6f1ddSLingrui98 // g 10509c6f1ddSLingrui98 // } 10609c6f1ddSLingrui98 10709c6f1ddSLingrui98 // def update(brValids: UInt, taken_mask: UInt, hist: UInt = predHist): GlobalHistory = { 10809c6f1ddSLingrui98 // val shift = PopCount(brValids & Mux(taken_mask =/= 0.U, LowerMask(taken_mask), ((1.U<<numBr) - 1.U))) 10909c6f1ddSLingrui98 // val g = Wire(new GlobalHistory) 11009c6f1ddSLingrui98 // g.predHist := (hist << shift) | (taken_mask =/= 0.U) 11109c6f1ddSLingrui98 // g 11209c6f1ddSLingrui98 // } 11309c6f1ddSLingrui98 114*eeb5ff92SLingrui98 def update(shift: UInt, taken: Bool, hist: UInt = this.predHist): GlobalHistory = { 11509c6f1ddSLingrui98 val g = Wire(new GlobalHistory) 11609c6f1ddSLingrui98 g.predHist := (hist << shift) | taken 11709c6f1ddSLingrui98 g 11809c6f1ddSLingrui98 } 11909c6f1ddSLingrui98 120*eeb5ff92SLingrui98 def update(br_valids: Vec[Bool], real_taken_mask: Vec[Bool]): GlobalHistory = { 121*eeb5ff92SLingrui98 require(br_valids.length == numBr) 122*eeb5ff92SLingrui98 require(real_taken_mask.length == numBr) 123*eeb5ff92SLingrui98 val last_valid_idx = PriorityMux( 124*eeb5ff92SLingrui98 br_valids.reverse :+ true.B, 125*eeb5ff92SLingrui98 (numBr to 0 by -1).map(_.U(log2Ceil(numBr+1).W)) 126*eeb5ff92SLingrui98 ) 127*eeb5ff92SLingrui98 val first_taken_idx = PriorityEncoder(false.B +: real_taken_mask) 128*eeb5ff92SLingrui98 val smaller = Mux(last_valid_idx < first_taken_idx, 129*eeb5ff92SLingrui98 last_valid_idx, 130*eeb5ff92SLingrui98 first_taken_idx 131*eeb5ff92SLingrui98 ) 132*eeb5ff92SLingrui98 val shift = smaller 133*eeb5ff92SLingrui98 val taken = real_taken_mask.reduce(_||_) 134*eeb5ff92SLingrui98 update(shift, taken, this.predHist) 135*eeb5ff92SLingrui98 } 136*eeb5ff92SLingrui98 13709c6f1ddSLingrui98 final def === (that: GlobalHistory): Bool = { 13809c6f1ddSLingrui98 predHist === that.predHist 13909c6f1ddSLingrui98 } 14009c6f1ddSLingrui98 14109c6f1ddSLingrui98 final def =/= (that: GlobalHistory): Bool = !(this === that) 14209c6f1ddSLingrui98 14309c6f1ddSLingrui98 implicit val name = "IFU" 14409c6f1ddSLingrui98 def debug(where: String) = XSDebug(p"[${where}_GlobalHistory] hist=${Binary(predHist)}\n") 14509c6f1ddSLingrui98 // override def toString(): String = "histPtr=%d, sawNTBr=%d, takenOnBr=%d, saveHalfRVI=%d".format(histPtr, sawNTBr, takenOnBr, saveHalfRVI) 14609c6f1ddSLingrui98} 14709c6f1ddSLingrui98 14809c6f1ddSLingrui98class TableAddr(val idxBits: Int, val banks: Int)(implicit p: Parameters) extends XSBundle{ 14909c6f1ddSLingrui98 def tagBits = VAddrBits - idxBits - instOffsetBits 15009c6f1ddSLingrui98 15109c6f1ddSLingrui98 val tag = UInt(tagBits.W) 15209c6f1ddSLingrui98 val idx = UInt(idxBits.W) 15309c6f1ddSLingrui98 val offset = UInt(instOffsetBits.W) 15409c6f1ddSLingrui98 15509c6f1ddSLingrui98 def fromUInt(x: UInt) = x.asTypeOf(UInt(VAddrBits.W)).asTypeOf(this) 15609c6f1ddSLingrui98 def getTag(x: UInt) = fromUInt(x).tag 15709c6f1ddSLingrui98 def getIdx(x: UInt) = fromUInt(x).idx 15809c6f1ddSLingrui98 def getBank(x: UInt) = if (banks > 1) getIdx(x)(log2Up(banks) - 1, 0) else 0.U 15909c6f1ddSLingrui98 def getBankIdx(x: UInt) = if (banks > 1) getIdx(x)(idxBits - 1, log2Up(banks)) else getIdx(x) 16009c6f1ddSLingrui98} 161*eeb5ff92SLingrui98 162*eeb5ff92SLingrui98@chiselName 16309c6f1ddSLingrui98class BranchPrediction(implicit p: Parameters) extends XSBundle with HasBPUConst { 164*eeb5ff92SLingrui98 val br_taken_mask = Vec(numBr, Bool()) 16509c6f1ddSLingrui98 166*eeb5ff92SLingrui98 val slot_valids = Vec(totalSlot, Bool()) 16709c6f1ddSLingrui98 168*eeb5ff92SLingrui98 val targets = Vec(totalSlot, UInt(VAddrBits.W)) 16909c6f1ddSLingrui98 17009c6f1ddSLingrui98 val is_jal = Bool() 17109c6f1ddSLingrui98 val is_jalr = Bool() 17209c6f1ddSLingrui98 val is_call = Bool() 17309c6f1ddSLingrui98 val is_ret = Bool() 174*eeb5ff92SLingrui98 val is_br_sharing = Bool() 17509c6f1ddSLingrui98 17609c6f1ddSLingrui98 // val call_is_rvc = Bool() 17709c6f1ddSLingrui98 val hit = Bool() 17809c6f1ddSLingrui98 179*eeb5ff92SLingrui98 def br_slot_valids = slot_valids.init 180*eeb5ff92SLingrui98 def tail_slot_valid = slot_valids.last 181*eeb5ff92SLingrui98 182*eeb5ff92SLingrui98 def br_valids = { 183*eeb5ff92SLingrui98 VecInit( 184*eeb5ff92SLingrui98 if (shareTailSlot) 185*eeb5ff92SLingrui98 br_slot_valids :+ (tail_slot_valid && is_br_sharing) 186*eeb5ff92SLingrui98 else 187*eeb5ff92SLingrui98 br_slot_valids 188*eeb5ff92SLingrui98 ) 189*eeb5ff92SLingrui98 } 190*eeb5ff92SLingrui98 191*eeb5ff92SLingrui98 def taken_mask_on_slot = { 192*eeb5ff92SLingrui98 VecInit( 193*eeb5ff92SLingrui98 if (shareTailSlot) 194*eeb5ff92SLingrui98 (br_slot_valids zip br_taken_mask.init).map{ case (t, v) => t && v } :+ ( 195*eeb5ff92SLingrui98 (br_taken_mask.last && tail_slot_valid && is_br_sharing) || 196*eeb5ff92SLingrui98 tail_slot_valid && !is_br_sharing 197*eeb5ff92SLingrui98 ) 198*eeb5ff92SLingrui98 else 199*eeb5ff92SLingrui98 (br_slot_valids zip br_taken_mask).map{ case (v, t) => v && t } :+ 200*eeb5ff92SLingrui98 tail_slot_valid 201*eeb5ff92SLingrui98 ) 202*eeb5ff92SLingrui98 } 203*eeb5ff92SLingrui98 204*eeb5ff92SLingrui98 def taken = br_taken_mask.reduce(_||_) || slot_valids.last // || (is_jal || is_jalr) 20509c6f1ddSLingrui98 20609c6f1ddSLingrui98 def fromFtbEntry(entry: FTBEntry, pc: UInt) = { 207*eeb5ff92SLingrui98 slot_valids := entry.brSlots.map(_.valid) :+ entry.tailSlot.valid 208*eeb5ff92SLingrui98 targets := entry.getTargetVec(pc) 209*eeb5ff92SLingrui98 is_jal := entry.tailSlot.valid && entry.isJal 210*eeb5ff92SLingrui98 is_jalr := entry.tailSlot.valid && entry.isJalr 211*eeb5ff92SLingrui98 is_call := entry.tailSlot.valid && entry.isCall 212*eeb5ff92SLingrui98 is_ret := entry.tailSlot.valid && entry.isRet 213*eeb5ff92SLingrui98 is_br_sharing := entry.tailSlot.valid && entry.tailSlot.sharing 21409c6f1ddSLingrui98 } 21509c6f1ddSLingrui98 // override def toPrintable: Printable = { 21609c6f1ddSLingrui98 // p"-----------BranchPrediction----------- " + 21709c6f1ddSLingrui98 // p"[taken_mask] ${Binary(taken_mask.asUInt)} " + 21809c6f1ddSLingrui98 // p"[is_br] ${Binary(is_br.asUInt)}, [is_jal] ${Binary(is_jal.asUInt)} " + 21909c6f1ddSLingrui98 // p"[is_jalr] ${Binary(is_jalr.asUInt)}, [is_call] ${Binary(is_call.asUInt)}, [is_ret] ${Binary(is_ret.asUInt)} " + 22009c6f1ddSLingrui98 // p"[target] ${Hexadecimal(target)}}, [hit] $hit " 22109c6f1ddSLingrui98 // } 22209c6f1ddSLingrui98 22309c6f1ddSLingrui98 def display(cond: Bool): Unit = { 224*eeb5ff92SLingrui98 XSDebug(cond, p"[taken_mask] ${Binary(br_taken_mask.asUInt)} [hit] $hit\n") 22509c6f1ddSLingrui98 } 22609c6f1ddSLingrui98} 22709c6f1ddSLingrui98 228bf358e08SLingrui98@chiselName 22909c6f1ddSLingrui98class BranchPredictionBundle(implicit p: Parameters) extends XSBundle with HasBPUConst with BPUUtils{ 23009c6f1ddSLingrui98 val pc = UInt(VAddrBits.W) 23109c6f1ddSLingrui98 23209c6f1ddSLingrui98 val valid = Bool() 23309c6f1ddSLingrui98 23409c6f1ddSLingrui98 val hasRedirect = Bool() 23509c6f1ddSLingrui98 val ftq_idx = new FtqPtr 23609c6f1ddSLingrui98 // val hit = Bool() 23709c6f1ddSLingrui98 val preds = new BranchPrediction 23809c6f1ddSLingrui98 23909c6f1ddSLingrui98 val ghist = new GlobalHistory() 24009c6f1ddSLingrui98 val phist = UInt(PathHistoryLength.W) 24109c6f1ddSLingrui98 val rasSp = UInt(log2Ceil(RasSize).W) 24209c6f1ddSLingrui98 val rasTop = new RASEntry 24309c6f1ddSLingrui98 val specCnt = Vec(numBr, UInt(10.W)) 24409c6f1ddSLingrui98 // val meta = UInt(MaxMetaLength.W) 24509c6f1ddSLingrui98 24609c6f1ddSLingrui98 val ftb_entry = new FTBEntry() // TODO: Send this entry to ftq 24709c6f1ddSLingrui98 248*eeb5ff92SLingrui98 def real_slot_taken_mask(): Vec[Bool] = { 249*eeb5ff92SLingrui98 VecInit(preds.taken_mask_on_slot.map(_ && preds.hit)) 250*eeb5ff92SLingrui98 } 251*eeb5ff92SLingrui98 252*eeb5ff92SLingrui98 // len numBr 253bf358e08SLingrui98 def real_br_taken_mask(): Vec[Bool] = { 254*eeb5ff92SLingrui98 if (shareTailSlot) 255*eeb5ff92SLingrui98 VecInit( 256*eeb5ff92SLingrui98 preds.taken_mask_on_slot.map(_ && preds.hit).init :+ 257*eeb5ff92SLingrui98 (preds.br_taken_mask.last && preds.tail_slot_valid && preds.is_br_sharing && preds.hit) 258*eeb5ff92SLingrui98 ) 259*eeb5ff92SLingrui98 else 260*eeb5ff92SLingrui98 VecInit(real_slot_taken_mask().init) 26109c6f1ddSLingrui98 } 26209c6f1ddSLingrui98 263*eeb5ff92SLingrui98 def hit_taken_on_jmp = 264*eeb5ff92SLingrui98 !real_slot_taken_mask().init.reduce(_||_) && 265*eeb5ff92SLingrui98 real_slot_taken_mask().last && !preds.is_br_sharing 266bf358e08SLingrui98 def hit_taken_on_call = hit_taken_on_jmp && preds.is_call 267bf358e08SLingrui98 def hit_taken_on_ret = hit_taken_on_jmp && preds.is_ret 268bf358e08SLingrui98 def hit_taken_on_jalr = hit_taken_on_jmp && preds.is_jalr 26909c6f1ddSLingrui98 27009c6f1ddSLingrui98 def fallThroughAddr = getFallThroughAddr(pc, ftb_entry.carry, ftb_entry.pftAddr) 271bf358e08SLingrui98 27209c6f1ddSLingrui98 def target(): UInt = { 273*eeb5ff92SLingrui98 val targetVec = preds.targets :+ fallThroughAddr :+ (pc + (FetchWidth*4).U) 274*eeb5ff92SLingrui98 val selVec = real_slot_taken_mask() :+ (preds.hit && !real_slot_taken_mask().asUInt.orR) :+ true.B 275bf358e08SLingrui98 PriorityMux(selVec zip targetVec) 27609c6f1ddSLingrui98 } 27709c6f1ddSLingrui98 def genCfiIndex = { 27809c6f1ddSLingrui98 val cfiIndex = Wire(ValidUndirectioned(UInt(log2Ceil(PredictWidth).W))) 279*eeb5ff92SLingrui98 cfiIndex.valid := real_slot_taken_mask().asUInt.orR 28009c6f1ddSLingrui98 // when no takens, set cfiIndex to PredictWidth-1 28109c6f1ddSLingrui98 cfiIndex.bits := 282*eeb5ff92SLingrui98 ParallelPriorityMux(real_slot_taken_mask(), ftb_entry.getOffsetVec) | 283*eeb5ff92SLingrui98 Fill(log2Ceil(PredictWidth), (!real_slot_taken_mask().asUInt.orR).asUInt) 28409c6f1ddSLingrui98 cfiIndex 28509c6f1ddSLingrui98 } 28609c6f1ddSLingrui98 28709c6f1ddSLingrui98 28809c6f1ddSLingrui98 // override def toPrintable: Printable = { 28909c6f1ddSLingrui98 // p"-----------BranchPredictionBundle----------- " + 29009c6f1ddSLingrui98 // p"[pc] ${Hexadecimal(pc)} " + 29109c6f1ddSLingrui98 // p"[ghist] ${Binary(ghist.predHist)} " + 29209c6f1ddSLingrui98 // preds.toPrintable + 29309c6f1ddSLingrui98 // ftb_entry.toPrintable 29409c6f1ddSLingrui98 // } 29509c6f1ddSLingrui98 29609c6f1ddSLingrui98 def display(cond: Bool): Unit = { 29709c6f1ddSLingrui98 XSDebug(cond, p"[pc] ${Hexadecimal(pc)}\n") 29809c6f1ddSLingrui98 XSDebug(cond, p"[ghist] ${Binary(ghist.predHist)}\n") 29909c6f1ddSLingrui98 preds.display(cond) 30009c6f1ddSLingrui98 ftb_entry.display(cond) 30109c6f1ddSLingrui98 } 30209c6f1ddSLingrui98} 30309c6f1ddSLingrui98 304bf358e08SLingrui98@chiselName 30509c6f1ddSLingrui98class BranchPredictionResp(implicit p: Parameters) extends XSBundle with HasBPUConst { 30609c6f1ddSLingrui98 // val valids = Vec(3, Bool()) 30709c6f1ddSLingrui98 val s1 = new BranchPredictionBundle() 30809c6f1ddSLingrui98 val s2 = new BranchPredictionBundle() 30909c6f1ddSLingrui98 val s3 = new BranchPredictionBundle() 31009c6f1ddSLingrui98 31109c6f1ddSLingrui98 def selectedResp = 31209c6f1ddSLingrui98 PriorityMux(Seq( 31309c6f1ddSLingrui98 ((s3.valid && s3.hasRedirect) -> s3), 31409c6f1ddSLingrui98 ((s2.valid && s2.hasRedirect) -> s2), 31509c6f1ddSLingrui98 (s1.valid -> s1) 31609c6f1ddSLingrui98 )) 31709c6f1ddSLingrui98 def selectedRespIdx = 31809c6f1ddSLingrui98 PriorityMux(Seq( 31909c6f1ddSLingrui98 ((s3.valid && s3.hasRedirect) -> BP_S3), 32009c6f1ddSLingrui98 ((s2.valid && s2.hasRedirect) -> BP_S2), 32109c6f1ddSLingrui98 (s1.valid -> BP_S1) 32209c6f1ddSLingrui98 )) 32309c6f1ddSLingrui98 def lastStage = s3 32409c6f1ddSLingrui98} 32509c6f1ddSLingrui98 32609c6f1ddSLingrui98class BpuToFtqBundle(implicit p: Parameters) extends BranchPredictionResp with HasBPUConst { 32709c6f1ddSLingrui98 val meta = UInt(MaxMetaLength.W) 32809c6f1ddSLingrui98} 32909c6f1ddSLingrui98 33009c6f1ddSLingrui98object BpuToFtqBundle { 33109c6f1ddSLingrui98 def apply(resp: BranchPredictionResp)(implicit p: Parameters): BpuToFtqBundle = { 33209c6f1ddSLingrui98 val e = Wire(new BpuToFtqBundle()) 33309c6f1ddSLingrui98 e.s1 := resp.s1 33409c6f1ddSLingrui98 e.s2 := resp.s2 33509c6f1ddSLingrui98 e.s3 := resp.s3 33609c6f1ddSLingrui98 33709c6f1ddSLingrui98 e.meta := DontCare 33809c6f1ddSLingrui98 e 33909c6f1ddSLingrui98 } 34009c6f1ddSLingrui98} 34109c6f1ddSLingrui98 34209c6f1ddSLingrui98class BranchPredictionUpdate(implicit p: Parameters) extends BranchPredictionBundle with HasBPUConst { 34309c6f1ddSLingrui98 val mispred_mask = Vec(numBr+1, Bool()) 34409c6f1ddSLingrui98 val false_hit = Bool() 34509c6f1ddSLingrui98 val new_br_insert_pos = Vec(numBr, Bool()) 34609c6f1ddSLingrui98 val old_entry = Bool() 34709c6f1ddSLingrui98 val meta = UInt(MaxMetaLength.W) 348abdbe4b7SLingrui98 val full_target = UInt(VAddrBits.W) 34909c6f1ddSLingrui98 // val ghist = new GlobalHistory() This in spec_meta 35009c6f1ddSLingrui98 35109c6f1ddSLingrui98 def fromFtqRedirectSram(entry: Ftq_Redirect_SRAMEntry) = { 35209c6f1ddSLingrui98 ghist := entry.ghist 35309c6f1ddSLingrui98 phist := entry.phist 35409c6f1ddSLingrui98 rasSp := entry.rasSp 35509c6f1ddSLingrui98 rasTop := entry.rasEntry 35609c6f1ddSLingrui98 specCnt := entry.specCnt 35709c6f1ddSLingrui98 this 35809c6f1ddSLingrui98 } 35909c6f1ddSLingrui98 // override def toPrintable: Printable = { 36009c6f1ddSLingrui98 // p"-----------BranchPredictionUpdate----------- " + 36109c6f1ddSLingrui98 // p"[mispred_mask] ${Binary(mispred_mask.asUInt)} [false_hit] ${Binary(false_hit)} " + 36209c6f1ddSLingrui98 // p"[new_br_insert_pos] ${Binary(new_br_insert_pos.asUInt)} " + 36309c6f1ddSLingrui98 // super.toPrintable + 36409c6f1ddSLingrui98 // p"\n" 36509c6f1ddSLingrui98 // } 36609c6f1ddSLingrui98 36709c6f1ddSLingrui98 override def display(cond: Bool) { 36809c6f1ddSLingrui98 XSDebug(cond, p"-----------BranchPredictionUpdate-----------\n") 36909c6f1ddSLingrui98 XSDebug(cond, p"[mispred_mask] ${Binary(mispred_mask.asUInt)} [false_hit] $false_hit\n") 37009c6f1ddSLingrui98 XSDebug(cond, p"[new_br_insert_pos] ${Binary(new_br_insert_pos.asUInt)}\n") 37109c6f1ddSLingrui98 super.display(cond) 37209c6f1ddSLingrui98 XSDebug(cond, p"--------------------------------------------\n") 37309c6f1ddSLingrui98 } 37409c6f1ddSLingrui98} 37509c6f1ddSLingrui98 37609c6f1ddSLingrui98class BranchPredictionRedirect(implicit p: Parameters) extends Redirect with HasBPUConst { 37709c6f1ddSLingrui98 // override def toPrintable: Printable = { 37809c6f1ddSLingrui98 // p"-----------BranchPredictionRedirect----------- " + 37909c6f1ddSLingrui98 // p"-----------cfiUpdate----------- " + 38009c6f1ddSLingrui98 // p"[pc] ${Hexadecimal(cfiUpdate.pc)} " + 38109c6f1ddSLingrui98 // p"[predTaken] ${cfiUpdate.predTaken}, [taken] ${cfiUpdate.taken}, [isMisPred] ${cfiUpdate.isMisPred} " + 38209c6f1ddSLingrui98 // p"[target] ${Hexadecimal(cfiUpdate.target)} " + 38309c6f1ddSLingrui98 // p"------------------------------- " + 38409c6f1ddSLingrui98 // p"[roqPtr] f=${roqIdx.flag} v=${roqIdx.value} " + 38509c6f1ddSLingrui98 // p"[ftqPtr] f=${ftqIdx.flag} v=${ftqIdx.value} " + 38609c6f1ddSLingrui98 // p"[ftqOffset] ${ftqOffset} " + 38709c6f1ddSLingrui98 // p"[level] ${level}, [interrupt] ${interrupt} " + 38809c6f1ddSLingrui98 // p"[stFtqIdx] f=${stFtqIdx.flag} v=${stFtqIdx.value} " + 38909c6f1ddSLingrui98 // p"[stFtqOffset] ${stFtqOffset} " + 39009c6f1ddSLingrui98 // p"\n" 39109c6f1ddSLingrui98 39209c6f1ddSLingrui98 // } 39309c6f1ddSLingrui98 39409c6f1ddSLingrui98 def display(cond: Bool): Unit = { 39509c6f1ddSLingrui98 XSDebug(cond, p"-----------BranchPredictionRedirect----------- \n") 39609c6f1ddSLingrui98 XSDebug(cond, p"-----------cfiUpdate----------- \n") 39709c6f1ddSLingrui98 XSDebug(cond, p"[pc] ${Hexadecimal(cfiUpdate.pc)}\n") 39809c6f1ddSLingrui98 XSDebug(cond, p"[hist] ${Binary(cfiUpdate.hist.predHist)}\n") 39909c6f1ddSLingrui98 XSDebug(cond, p"[br_hit] ${cfiUpdate.br_hit} [isMisPred] ${cfiUpdate.isMisPred}\n") 40009c6f1ddSLingrui98 XSDebug(cond, p"[pred_taken] ${cfiUpdate.predTaken} [taken] ${cfiUpdate.taken} [isMisPred] ${cfiUpdate.isMisPred}\n") 40109c6f1ddSLingrui98 XSDebug(cond, p"[target] ${Hexadecimal(cfiUpdate.target)} \n") 40209c6f1ddSLingrui98 XSDebug(cond, p"[shift] ${cfiUpdate.shift}\n") 40309c6f1ddSLingrui98 XSDebug(cond, p"------------------------------- \n") 40409c6f1ddSLingrui98 XSDebug(cond, p"[roqPtr] f=${roqIdx.flag} v=${roqIdx.value}\n") 40509c6f1ddSLingrui98 XSDebug(cond, p"[ftqPtr] f=${ftqIdx.flag} v=${ftqIdx.value} \n") 40609c6f1ddSLingrui98 XSDebug(cond, p"[ftqOffset] ${ftqOffset} \n") 40709c6f1ddSLingrui98 XSDebug(cond, p"[stFtqIdx] f=${stFtqIdx.flag} v=${stFtqIdx.value}\n") 40809c6f1ddSLingrui98 XSDebug(cond, p"[stFtqOffset] ${stFtqOffset}\n") 40909c6f1ddSLingrui98 XSDebug(cond, p"---------------------------------------------- \n") 41009c6f1ddSLingrui98 } 41109c6f1ddSLingrui98} 412