1*44c9c1deSEaston Man/*************************************************************************************** 2*44c9c1deSEaston Man* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3*44c9c1deSEaston Man* Copyright (c) 2020-2021 Peng Cheng Laboratory 4*44c9c1deSEaston Man* 5*44c9c1deSEaston Man* XiangShan is licensed under Mulan PSL v2. 6*44c9c1deSEaston Man* You can use this software according to the terms and conditions of the Mulan PSL v2. 7*44c9c1deSEaston Man* You may obtain a copy of Mulan PSL v2 at: 8*44c9c1deSEaston Man* http://license.coscl.org.cn/MulanPSL2 9*44c9c1deSEaston Man* 10*44c9c1deSEaston Man* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11*44c9c1deSEaston Man* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12*44c9c1deSEaston Man* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13*44c9c1deSEaston Man* 14*44c9c1deSEaston Man* See the Mulan PSL v2 for more details. 15*44c9c1deSEaston Man***************************************************************************************/ 16*44c9c1deSEaston Man 17*44c9c1deSEaston Manpackage xiangshan.frontend 18*44c9c1deSEaston Man 19*44c9c1deSEaston Manimport org.chipsalliance.cde.config.Parameters 20*44c9c1deSEaston Manimport chisel3._ 21*44c9c1deSEaston Manimport chisel3.util._ 22*44c9c1deSEaston Manimport xiangshan._ 23*44c9c1deSEaston Manimport utils._ 24*44c9c1deSEaston Manimport utility._ 25*44c9c1deSEaston Manimport xiangshan.ExceptionNO._ 26*44c9c1deSEaston Man 27*44c9c1deSEaston Manclass IBufPtr(implicit p: Parameters) extends CircularQueuePtr[IBufPtr]( 28*44c9c1deSEaston Man p => p(XSCoreParamsKey).IBufSize 29*44c9c1deSEaston Man) { 30*44c9c1deSEaston Man} 31*44c9c1deSEaston Man 32*44c9c1deSEaston Manclass IBufInBankPtr(implicit p: Parameters) extends CircularQueuePtr[IBufInBankPtr]( 33*44c9c1deSEaston Man p => p(XSCoreParamsKey).IBufSize / p(XSCoreParamsKey).IBufNBank 34*44c9c1deSEaston Man) { 35*44c9c1deSEaston Man} 36*44c9c1deSEaston Man 37*44c9c1deSEaston Manclass IBufBankPtr(implicit p: Parameters) extends CircularQueuePtr[IBufBankPtr]( 38*44c9c1deSEaston Man p => p(XSCoreParamsKey).IBufNBank 39*44c9c1deSEaston Man) { 40*44c9c1deSEaston Man} 41*44c9c1deSEaston Man 42*44c9c1deSEaston Manclass IBufferIO(implicit p: Parameters) extends XSBundle { 43*44c9c1deSEaston Man val flush = Input(Bool()) 44*44c9c1deSEaston Man val ControlRedirect = Input(Bool()) 45*44c9c1deSEaston Man val ControlBTBMissBubble = Input(Bool()) 46*44c9c1deSEaston Man val TAGEMissBubble = Input(Bool()) 47*44c9c1deSEaston Man val SCMissBubble = Input(Bool()) 48*44c9c1deSEaston Man val ITTAGEMissBubble = Input(Bool()) 49*44c9c1deSEaston Man val RASMissBubble = Input(Bool()) 50*44c9c1deSEaston Man val MemVioRedirect = Input(Bool()) 51*44c9c1deSEaston Man val in = Flipped(DecoupledIO(new FetchToIBuffer)) 52*44c9c1deSEaston Man val out = Vec(DecodeWidth, DecoupledIO(new CtrlFlow)) 53*44c9c1deSEaston Man val full = Output(Bool()) 54*44c9c1deSEaston Man val stallReason = new StallReasonIO(DecodeWidth) 55*44c9c1deSEaston Man} 56*44c9c1deSEaston Man 57*44c9c1deSEaston Manclass IBufEntry(implicit p: Parameters) extends XSBundle { 58*44c9c1deSEaston Man val inst = UInt(32.W) 59*44c9c1deSEaston Man val pc = UInt(VAddrBits.W) 60*44c9c1deSEaston Man val foldpc = UInt(MemPredPCWidth.W) 61*44c9c1deSEaston Man val pd = new PreDecodeInfo 62*44c9c1deSEaston Man val pred_taken = Bool() 63*44c9c1deSEaston Man val ftqPtr = new FtqPtr 64*44c9c1deSEaston Man val ftqOffset = UInt(log2Ceil(PredictWidth).W) 65*44c9c1deSEaston Man val ipf = Bool() 66*44c9c1deSEaston Man val acf = Bool() 67*44c9c1deSEaston Man val crossPageIPFFix = Bool() 68*44c9c1deSEaston Man val triggered = new TriggerCf 69*44c9c1deSEaston Man 70*44c9c1deSEaston Man def fromFetch(fetch: FetchToIBuffer, i: Int): IBufEntry = { 71*44c9c1deSEaston Man inst := fetch.instrs(i) 72*44c9c1deSEaston Man pc := fetch.pc(i) 73*44c9c1deSEaston Man foldpc := fetch.foldpc(i) 74*44c9c1deSEaston Man pd := fetch.pd(i) 75*44c9c1deSEaston Man pred_taken := fetch.ftqOffset(i).valid 76*44c9c1deSEaston Man ftqPtr := fetch.ftqPtr 77*44c9c1deSEaston Man ftqOffset := fetch.ftqOffset(i).bits 78*44c9c1deSEaston Man ipf := fetch.ipf(i) 79*44c9c1deSEaston Man acf := fetch.acf(i) 80*44c9c1deSEaston Man crossPageIPFFix := fetch.crossPageIPFFix(i) 81*44c9c1deSEaston Man triggered := fetch.triggered(i) 82*44c9c1deSEaston Man this 83*44c9c1deSEaston Man } 84*44c9c1deSEaston Man 85*44c9c1deSEaston Man def toCtrlFlow: CtrlFlow = { 86*44c9c1deSEaston Man val cf = Wire(new CtrlFlow) 87*44c9c1deSEaston Man cf.instr := inst 88*44c9c1deSEaston Man cf.pc := pc 89*44c9c1deSEaston Man cf.foldpc := foldpc 90*44c9c1deSEaston Man cf.exceptionVec := 0.U.asTypeOf(ExceptionVec()) 91*44c9c1deSEaston Man cf.exceptionVec(instrPageFault) := ipf 92*44c9c1deSEaston Man cf.exceptionVec(instrAccessFault) := acf 93*44c9c1deSEaston Man cf.trigger := triggered 94*44c9c1deSEaston Man cf.pd := pd 95*44c9c1deSEaston Man cf.pred_taken := pred_taken 96*44c9c1deSEaston Man cf.crossPageIPFFix := crossPageIPFFix 97*44c9c1deSEaston Man cf.storeSetHit := DontCare 98*44c9c1deSEaston Man cf.waitForRobIdx := DontCare 99*44c9c1deSEaston Man cf.loadWaitBit := DontCare 100*44c9c1deSEaston Man cf.loadWaitStrict := DontCare 101*44c9c1deSEaston Man cf.ssid := DontCare 102*44c9c1deSEaston Man cf.ftqPtr := ftqPtr 103*44c9c1deSEaston Man cf.ftqOffset := ftqOffset 104*44c9c1deSEaston Man cf 105*44c9c1deSEaston Man } 106*44c9c1deSEaston Man} 107*44c9c1deSEaston Man 108*44c9c1deSEaston Manclass IBuffer(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHelper with HasPerfEvents { 109*44c9c1deSEaston Man val io = IO(new IBufferIO) 110*44c9c1deSEaston Man 111*44c9c1deSEaston Man // Parameter Check 112*44c9c1deSEaston Man private val bankSize = IBufSize / IBufNBank 113*44c9c1deSEaston Man require(IBufSize % IBufNBank == 0, s"IBufNBank should divide IBufSize, IBufNBank: $IBufNBank, IBufSize: $IBufSize") 114*44c9c1deSEaston Man require(IBufNBank >= DecodeWidth, 115*44c9c1deSEaston Man s"IBufNBank should be equal or larger than DecodeWidth, IBufNBank: $IBufNBank, DecodeWidth: $DecodeWidth") 116*44c9c1deSEaston Man 117*44c9c1deSEaston Man // IBuffer is organized as raw registers 118*44c9c1deSEaston Man // This is due to IBuffer is a huge queue, read & write port logic should be precisely controlled 119*44c9c1deSEaston Man // . + + E E E - . 120*44c9c1deSEaston Man // . + + E E E - . 121*44c9c1deSEaston Man // . . + E E E - . 122*44c9c1deSEaston Man // . . + E E E E - 123*44c9c1deSEaston Man // As shown above, + means enqueue, - means dequeue, E is current content 124*44c9c1deSEaston Man // When dequeue, read port is organized like a banked FIFO 125*44c9c1deSEaston Man // Dequeue reads no more than 1 entry from each bank sequentially, this can be exploit to reduce area 126*44c9c1deSEaston Man // Enqueue writes cannot benefit from this characteristic unless use a SRAM 127*44c9c1deSEaston Man // For detail see Enqueue and Dequeue below 128*44c9c1deSEaston Man private val ibuf: Vec[IBufEntry] = RegInit(VecInit.fill(IBufSize)(0.U.asTypeOf(new IBufEntry))) 129*44c9c1deSEaston Man private val bankedIBufView: Vec[Vec[IBufEntry]] = VecInit.tabulate(IBufNBank)( 130*44c9c1deSEaston Man bankID => VecInit.tabulate(bankSize)( 131*44c9c1deSEaston Man inBankOffset => ibuf(bankID + inBankOffset * IBufNBank) 132*44c9c1deSEaston Man ) 133*44c9c1deSEaston Man ) 134*44c9c1deSEaston Man 135*44c9c1deSEaston Man // Between Bank 136*44c9c1deSEaston Man private val deqBankPtrVec: Vec[IBufBankPtr] = RegInit(VecInit.tabulate(DecodeWidth)(_.U.asTypeOf(new IBufBankPtr))) 137*44c9c1deSEaston Man private val deqBankPtr: IBufBankPtr = deqBankPtrVec(0) 138*44c9c1deSEaston Man // Inside Bank 139*44c9c1deSEaston Man private val deqInBankPtr: Vec[IBufInBankPtr] = RegInit(VecInit.fill(IBufNBank)(0.U.asTypeOf(new IBufInBankPtr))) 140*44c9c1deSEaston Man 141*44c9c1deSEaston Man val deqPtr = RegInit(0.U.asTypeOf(new IBufPtr)) 142*44c9c1deSEaston Man 143*44c9c1deSEaston Man val enqPtrVec = RegInit(VecInit.tabulate(PredictWidth)(_.U.asTypeOf(new IBufPtr))) 144*44c9c1deSEaston Man val enqPtr = enqPtrVec(0) 145*44c9c1deSEaston Man 146*44c9c1deSEaston Man val validEntries = distanceBetween(enqPtr, deqPtr) 147*44c9c1deSEaston Man val allowEnq = RegInit(true.B) 148*44c9c1deSEaston Man 149*44c9c1deSEaston Man val numEnq = Mux(io.in.fire, PopCount(io.in.bits.valid), 0.U) 150*44c9c1deSEaston Man val numTryDeq = Mux(validEntries >= DecodeWidth.U, DecodeWidth.U, validEntries) 151*44c9c1deSEaston Man val numDeq = Mux(io.out.head.ready, numTryDeq, 0.U) 152*44c9c1deSEaston Man 153*44c9c1deSEaston Man val numAfterEnq = validEntries +& numEnq 154*44c9c1deSEaston Man val nextValidEntries = Mux(io.out(0).ready, numAfterEnq - numTryDeq, numAfterEnq) 155*44c9c1deSEaston Man allowEnq := (IBufSize - PredictWidth).U >= nextValidEntries // Disable when almost full 156*44c9c1deSEaston Man 157*44c9c1deSEaston Man ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 158*44c9c1deSEaston Man // Enqueue 159*44c9c1deSEaston Man ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 160*44c9c1deSEaston Man io.in.ready := allowEnq 161*44c9c1deSEaston Man // Data 162*44c9c1deSEaston Man val enqOffset = VecInit.tabulate(PredictWidth)(i => PopCount(io.in.bits.valid.asBools.take(i))) 163*44c9c1deSEaston Man val enqData = VecInit.tabulate(PredictWidth)(i => Wire(new IBufEntry).fromFetch(io.in.bits, i)) 164*44c9c1deSEaston Man ibuf.zipWithIndex.foreach { 165*44c9c1deSEaston Man case (entry, idx) => { 166*44c9c1deSEaston Man // Select 167*44c9c1deSEaston Man val validOH = Range(0, PredictWidth).map { 168*44c9c1deSEaston Man i => io.in.bits.valid(i) && 169*44c9c1deSEaston Man io.in.bits.enqEnable(i) && 170*44c9c1deSEaston Man enqPtrVec(enqOffset(i)).value === idx.asUInt 171*44c9c1deSEaston Man } // Should be OneHot 172*44c9c1deSEaston Man val wen = validOH.reduce(_ || _) && io.in.fire && !io.flush 173*44c9c1deSEaston Man 174*44c9c1deSEaston Man // Write port 175*44c9c1deSEaston Man // Each IBuffer entry has a PredictWidth -> 1 Mux 176*44c9c1deSEaston Man val writeEntry = Mux1H(validOH, enqData) 177*44c9c1deSEaston Man entry := Mux(wen, writeEntry, entry) 178*44c9c1deSEaston Man 179*44c9c1deSEaston Man // Debug Assertion 180*44c9c1deSEaston Man XSError(PopCount(validOH) > 1.asUInt, "validOH is not OneHot") 181*44c9c1deSEaston Man } 182*44c9c1deSEaston Man } 183*44c9c1deSEaston Man // Pointer maintenance 184*44c9c1deSEaston Man when (io.in.fire && !io.flush) { 185*44c9c1deSEaston Man enqPtrVec := VecInit(enqPtrVec.map(_ + PopCount(io.in.bits.enqEnable))) 186*44c9c1deSEaston Man } 187*44c9c1deSEaston Man 188*44c9c1deSEaston Man ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 189*44c9c1deSEaston Man // Dequeue 190*44c9c1deSEaston Man ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 191*44c9c1deSEaston Man val validVec = Mux(validEntries >= DecodeWidth.U, 192*44c9c1deSEaston Man ((1 << DecodeWidth) - 1).U, 193*44c9c1deSEaston Man UIntToMask(validEntries(log2Ceil(DecodeWidth) - 1, 0), DecodeWidth) 194*44c9c1deSEaston Man ) 195*44c9c1deSEaston Man // Data 196*44c9c1deSEaston Man // Read port 197*44c9c1deSEaston Man // 2-stage, IBufNBank * (bankSize -> 1) + IBufNBank -> 1 198*44c9c1deSEaston Man // Should be better than IBufSize -> 1 in area, with no significant latency increase 199*44c9c1deSEaston Man private val readStage1: Vec[IBufEntry] = VecInit.tabulate(IBufNBank)( 200*44c9c1deSEaston Man bankID => Mux1H(UIntToOH(deqInBankPtr(bankID).value), bankedIBufView(bankID)) 201*44c9c1deSEaston Man ) 202*44c9c1deSEaston Man for (i <- 0 until DecodeWidth) { 203*44c9c1deSEaston Man io.out(i).valid := validVec(i) 204*44c9c1deSEaston Man io.out(i).bits := Mux1H(UIntToOH(deqBankPtrVec(i).value), readStage1).toCtrlFlow 205*44c9c1deSEaston Man } 206*44c9c1deSEaston Man // Pointer maintenance 207*44c9c1deSEaston Man deqBankPtrVec := Mux(io.out.head.ready, VecInit(deqBankPtrVec.map(_ + numTryDeq)), deqBankPtrVec) 208*44c9c1deSEaston Man deqPtr := Mux(io.out.head.ready, deqPtr + numTryDeq, deqPtr) 209*44c9c1deSEaston Man deqInBankPtr.zipWithIndex.foreach { 210*44c9c1deSEaston Man case (ptr, idx) => { 211*44c9c1deSEaston Man // validVec[k] == bankValid[deqBankPtr + k] 212*44c9c1deSEaston Man // So bankValid[n] == validVec[n - deqBankPtr] 213*44c9c1deSEaston Man val validIdx = Mux(idx.asUInt >= deqBankPtr.value, 214*44c9c1deSEaston Man idx.asUInt - deqBankPtr.value, 215*44c9c1deSEaston Man ((idx + IBufNBank).asUInt - deqBankPtr.value)(log2Ceil(IBufNBank) - 1, 0) 216*44c9c1deSEaston Man ) 217*44c9c1deSEaston Man val bankAdvance = Mux(validIdx >= DecodeWidth.U, 218*44c9c1deSEaston Man false.B, 219*44c9c1deSEaston Man validVec(validIdx(log2Ceil(DecodeWidth) - 1, 0)) 220*44c9c1deSEaston Man ) && io.out.head.ready 221*44c9c1deSEaston Man ptr := Mux(bankAdvance , ptr + 1.U, ptr) 222*44c9c1deSEaston Man } 223*44c9c1deSEaston Man } 224*44c9c1deSEaston Man 225*44c9c1deSEaston Man // Flush 226*44c9c1deSEaston Man when (io.flush) { 227*44c9c1deSEaston Man allowEnq := true.B 228*44c9c1deSEaston Man enqPtrVec := enqPtrVec.indices.map(_.U.asTypeOf(new IBufPtr)) 229*44c9c1deSEaston Man deqBankPtrVec := deqBankPtrVec.indices.map(_.U.asTypeOf(new IBufBankPtr)) 230*44c9c1deSEaston Man deqInBankPtr := VecInit.fill(IBufNBank)(0.U.asTypeOf(new IBufInBankPtr)) 231*44c9c1deSEaston Man deqPtr := 0.U.asTypeOf(new IBufPtr()) 232*44c9c1deSEaston Man } 233*44c9c1deSEaston Man io.full := !allowEnq 234*44c9c1deSEaston Man 235*44c9c1deSEaston Man ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 236*44c9c1deSEaston Man // TopDown 237*44c9c1deSEaston Man ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 238*44c9c1deSEaston Man val topdown_stage = RegInit(0.U.asTypeOf(new FrontendTopDownBundle)) 239*44c9c1deSEaston Man topdown_stage := io.in.bits.topdown_info 240*44c9c1deSEaston Man when(io.flush) { 241*44c9c1deSEaston Man when(io.ControlRedirect) { 242*44c9c1deSEaston Man when(io.ControlBTBMissBubble) { 243*44c9c1deSEaston Man topdown_stage.reasons(TopDownCounters.BTBMissBubble.id) := true.B 244*44c9c1deSEaston Man }.elsewhen(io.TAGEMissBubble) { 245*44c9c1deSEaston Man topdown_stage.reasons(TopDownCounters.TAGEMissBubble.id) := true.B 246*44c9c1deSEaston Man }.elsewhen(io.SCMissBubble) { 247*44c9c1deSEaston Man topdown_stage.reasons(TopDownCounters.SCMissBubble.id) := true.B 248*44c9c1deSEaston Man }.elsewhen(io.ITTAGEMissBubble) { 249*44c9c1deSEaston Man topdown_stage.reasons(TopDownCounters.ITTAGEMissBubble.id) := true.B 250*44c9c1deSEaston Man }.elsewhen(io.RASMissBubble) { 251*44c9c1deSEaston Man topdown_stage.reasons(TopDownCounters.RASMissBubble.id) := true.B 252*44c9c1deSEaston Man } 253*44c9c1deSEaston Man }.elsewhen(io.MemVioRedirect) { 254*44c9c1deSEaston Man topdown_stage.reasons(TopDownCounters.MemVioRedirectBubble.id) := true.B 255*44c9c1deSEaston Man }.otherwise { 256*44c9c1deSEaston Man topdown_stage.reasons(TopDownCounters.OtherRedirectBubble.id) := true.B 257*44c9c1deSEaston Man } 258*44c9c1deSEaston Man } 259*44c9c1deSEaston Man 260*44c9c1deSEaston Man 261*44c9c1deSEaston Man val dequeueInsufficient = Wire(Bool()) 262*44c9c1deSEaston Man val matchBubble = Wire(UInt(log2Up(TopDownCounters.NumStallReasons.id).W)) 263*44c9c1deSEaston Man val deqValidCount = PopCount(validVec.asBools) 264*44c9c1deSEaston Man val deqWasteCount = DecodeWidth.U - deqValidCount 265*44c9c1deSEaston Man dequeueInsufficient := deqValidCount < DecodeWidth.U 266*44c9c1deSEaston Man matchBubble := (TopDownCounters.NumStallReasons.id - 1).U - PriorityEncoder(topdown_stage.reasons.reverse) 267*44c9c1deSEaston Man 268*44c9c1deSEaston Man io.stallReason.reason.map(_ := 0.U) 269*44c9c1deSEaston Man for (i <- 0 until DecodeWidth) { 270*44c9c1deSEaston Man when(i.U < deqWasteCount) { 271*44c9c1deSEaston Man io.stallReason.reason(DecodeWidth - i - 1) := matchBubble 272*44c9c1deSEaston Man } 273*44c9c1deSEaston Man } 274*44c9c1deSEaston Man 275*44c9c1deSEaston Man when(!(deqWasteCount === DecodeWidth.U || topdown_stage.reasons.asUInt.orR)) { 276*44c9c1deSEaston Man // should set reason for FetchFragmentationStall 277*44c9c1deSEaston Man // topdown_stage.reasons(TopDownCounters.FetchFragmentationStall.id) := true.B 278*44c9c1deSEaston Man for (i <- 0 until DecodeWidth) { 279*44c9c1deSEaston Man when(i.U < deqWasteCount) { 280*44c9c1deSEaston Man io.stallReason.reason(DecodeWidth - i - 1) := TopDownCounters.FetchFragBubble.id.U 281*44c9c1deSEaston Man } 282*44c9c1deSEaston Man } 283*44c9c1deSEaston Man } 284*44c9c1deSEaston Man 285*44c9c1deSEaston Man when(io.stallReason.backReason.valid) { 286*44c9c1deSEaston Man io.stallReason.reason.map(_ := io.stallReason.backReason.bits) 287*44c9c1deSEaston Man } 288*44c9c1deSEaston Man 289*44c9c1deSEaston Man // Debug info 290*44c9c1deSEaston Man XSError( 291*44c9c1deSEaston Man deqPtr.value =/= deqBankPtr.value + deqInBankPtr(deqBankPtr.value).value * IBufNBank.asUInt, 292*44c9c1deSEaston Man "Dequeue PTR mismatch" 293*44c9c1deSEaston Man ) 294*44c9c1deSEaston Man XSDebug(io.flush, "IBuffer Flushed\n") 295*44c9c1deSEaston Man 296*44c9c1deSEaston Man when(io.in.fire) { 297*44c9c1deSEaston Man XSDebug("Enque:\n") 298*44c9c1deSEaston Man XSDebug(p"MASK=${Binary(io.in.bits.valid)}\n") 299*44c9c1deSEaston Man for(i <- 0 until PredictWidth){ 300*44c9c1deSEaston Man XSDebug(p"PC=${Hexadecimal(io.in.bits.pc(i))} ${Hexadecimal(io.in.bits.instrs(i))}\n") 301*44c9c1deSEaston Man } 302*44c9c1deSEaston Man } 303*44c9c1deSEaston Man 304*44c9c1deSEaston Man for (i <- 0 until DecodeWidth) { 305*44c9c1deSEaston Man XSDebug(io.out(i).fire, 306*44c9c1deSEaston Man p"deq: ${Hexadecimal(io.out(i).bits.instr)} PC=${Hexadecimal(io.out(i).bits.pc)}" + 307*44c9c1deSEaston Man p"v=${io.out(i).valid} r=${io.out(i).ready} " + 308*44c9c1deSEaston Man p"excpVec=${Binary(io.out(i).bits.exceptionVec.asUInt)} crossPageIPF=${io.out(i).bits.crossPageIPFFix}\n") 309*44c9c1deSEaston Man } 310*44c9c1deSEaston Man 311*44c9c1deSEaston Man XSDebug(p"ValidEntries: ${validEntries}\n") 312*44c9c1deSEaston Man XSDebug(p"EnqNum: ${numEnq}\n") 313*44c9c1deSEaston Man XSDebug(p"DeqNum: ${numDeq}\n") 314*44c9c1deSEaston Man 315*44c9c1deSEaston Man val afterInit = RegInit(false.B) 316*44c9c1deSEaston Man val headBubble = RegInit(false.B) 317*44c9c1deSEaston Man when (io.in.fire) { afterInit := true.B } 318*44c9c1deSEaston Man when (io.flush) { 319*44c9c1deSEaston Man headBubble := true.B 320*44c9c1deSEaston Man } .elsewhen(validEntries =/= 0.U) { 321*44c9c1deSEaston Man headBubble := false.B 322*44c9c1deSEaston Man } 323*44c9c1deSEaston Man val instrHungry = afterInit && (validEntries === 0.U) && !headBubble 324*44c9c1deSEaston Man 325*44c9c1deSEaston Man QueuePerf(IBufSize, validEntries, !allowEnq) 326*44c9c1deSEaston Man XSPerfAccumulate("flush", io.flush) 327*44c9c1deSEaston Man XSPerfAccumulate("hungry", instrHungry) 328*44c9c1deSEaston Man 329*44c9c1deSEaston Man val ibuffer_IDWidth_hvButNotFull = afterInit && (validEntries =/= 0.U) && (validEntries < DecodeWidth.U) && !headBubble 330*44c9c1deSEaston Man XSPerfAccumulate("ibuffer_IDWidth_hvButNotFull", ibuffer_IDWidth_hvButNotFull) 331*44c9c1deSEaston Man /* 332*44c9c1deSEaston Man XSPerfAccumulate("ICacheMissBubble", Mux(matchBubbleVec(TopDownCounters.ICacheMissBubble.id), deqWasteCount, 0.U)) 333*44c9c1deSEaston Man XSPerfAccumulate("ITLBMissBubble", Mux(matchBubbleVec(TopDownCounters.ITLBMissBubble.id), deqWasteCount, 0.U)) 334*44c9c1deSEaston Man XSPerfAccumulate("ControlRedirectBubble", Mux(matchBubbleVec(TopDownCounters.ControlRedirectBubble.id), deqWasteCount, 0.U)) 335*44c9c1deSEaston Man XSPerfAccumulate("MemVioRedirectBubble", Mux(matchBubbleVec(TopDownCounters.MemVioRedirectBubble.id), deqWasteCount, 0.U)) 336*44c9c1deSEaston Man XSPerfAccumulate("OtherRedirectBubble", Mux(matchBubbleVec(TopDownCounters.OtherRedirectBubble.id), deqWasteCount, 0.U)) 337*44c9c1deSEaston Man XSPerfAccumulate("BTBMissBubble", Mux(matchBubbleVec(TopDownCounters.BTBMissBubble.id), deqWasteCount, 0.U)) 338*44c9c1deSEaston Man XSPerfAccumulate("OverrideBubble", Mux(matchBubbleVec(TopDownCounters.OverrideBubble.id), deqWasteCount, 0.U)) 339*44c9c1deSEaston Man XSPerfAccumulate("FtqUpdateBubble", Mux(matchBubbleVec(TopDownCounters.FtqUpdateBubble.id), deqWasteCount, 0.U)) 340*44c9c1deSEaston Man XSPerfAccumulate("FtqFullStall", Mux(matchBubbleVec(TopDownCounters.FtqFullStall.id), deqWasteCount, 0.U)) 341*44c9c1deSEaston Man XSPerfAccumulate("FetchFragmentBubble", 342*44c9c1deSEaston Man Mux(deqWasteCount === DecodeWidth.U || topdown_stage.reasons.asUInt.orR, 0.U, deqWasteCount)) 343*44c9c1deSEaston Man XSPerfAccumulate("TAGEMissBubble", Mux(matchBubbleVec(TopDownCounters.TAGEMissBubble.id), deqWasteCount, 0.U)) 344*44c9c1deSEaston Man XSPerfAccumulate("SCMissBubble", Mux(matchBubbleVec(TopDownCounters.SCMissBubble.id), deqWasteCount, 0.U)) 345*44c9c1deSEaston Man XSPerfAccumulate("ITTAGEMissBubble", Mux(matchBubbleVec(TopDownCounters.ITTAGEMissBubble.id), deqWasteCount, 0.U)) 346*44c9c1deSEaston Man XSPerfAccumulate("RASMissBubble", Mux(matchBubbleVec(TopDownCounters.RASMissBubble.id), deqWasteCount, 0.U)) 347*44c9c1deSEaston Man */ 348*44c9c1deSEaston Man 349*44c9c1deSEaston Man val perfEvents = Seq( 350*44c9c1deSEaston Man ("IBuffer_Flushed ", io.flush ), 351*44c9c1deSEaston Man ("IBuffer_hungry ", instrHungry ), 352*44c9c1deSEaston Man ("IBuffer_1_4_valid", (validEntries > (0*(IBufSize/4)).U) & (validEntries < (1*(IBufSize/4)).U) ), 353*44c9c1deSEaston Man ("IBuffer_2_4_valid", (validEntries >= (1*(IBufSize/4)).U) & (validEntries < (2*(IBufSize/4)).U) ), 354*44c9c1deSEaston Man ("IBuffer_3_4_valid", (validEntries >= (2*(IBufSize/4)).U) & (validEntries < (3*(IBufSize/4)).U) ), 355*44c9c1deSEaston Man ("IBuffer_4_4_valid", (validEntries >= (3*(IBufSize/4)).U) & (validEntries < (4*(IBufSize/4)).U) ), 356*44c9c1deSEaston Man ("IBuffer_full ", validEntries.andR ), 357*44c9c1deSEaston Man ("Front_Bubble ", PopCount((0 until DecodeWidth).map(i => io.out(i).ready && !io.out(i).valid))) 358*44c9c1deSEaston Man ) 359*44c9c1deSEaston Man generatePerfEvent() 360*44c9c1deSEaston Man} 361