1package xiangshan.backend.issue 2 3import chisel3._ 4import chisel3.util._ 5import xiangshan._ 6import xiangshan.backend.exu.{Exu, ExuConfig} 7import xiangshan.backend.rename.FreeListPtr 8import utils._ 9import xiangshan.backend.fu.FunctionUnit._ 10 11 12trait IQConst extends HasXSParameter{ 13 val iqSize = IssQueSize 14 val iqIdxWidth = log2Up(iqSize) 15} 16 17sealed abstract class IQBundle extends XSBundle with IQConst 18sealed abstract class IQModule extends XSModule with IQConst 19 20object OneCycleFire { 21 def apply(fire: Bool) = { 22 val valid = RegInit(false.B) 23 when (valid) { valid := false.B } 24 when (fire) { valid := true.B } 25 valid 26 } 27} 28 29class IssueQueue 30( 31 exuCfg: ExuConfig, val wakeupCnt: Int, val bypassCnt: Int = 0, val enableBypass: Boolean = false, val fifo: Boolean = false 32) extends IQModule { 33 34 val src2Use = true 35 val src3Use = (exuCfg.intSrcCnt > 2) || (exuCfg.fpSrcCnt > 2) 36 val src2Listen = true 37 val src3Listen = (exuCfg.intSrcCnt > 2) || (exuCfg.fpSrcCnt > 2) 38 39 val io = IO(new Bundle() { 40 // flush Issue Queue 41 val redirect = Flipped(ValidIO(new Redirect)) 42 43 // enq Ctrl sigs at dispatch-2 44 val enqCtrl = Flipped(DecoupledIO(new MicroOp)) 45 // enq Data at next cycle (regfile has 1 cycle latency) 46 val enqData = Flipped(ValidIO(new ExuInput)) 47 48 // broadcast selected uop to other issue queues which has bypasses 49 val selectedUop = if(enableBypass) ValidIO(new MicroOp) else null 50 51 // send to exu 52 val deq = DecoupledIO(new ExuInput) 53 54 // listen to write back bus 55 val wakeUpPorts = Vec(wakeupCnt, Flipped(ValidIO(new ExuOutput))) 56 57 // use bypass uops to speculative wake-up 58 val bypassUops = Vec(bypassCnt, Flipped(ValidIO(new MicroOp))) 59 val bypassData = Vec(bypassCnt, Flipped(ValidIO(new ExuOutput))) 60 61 // to Dispatch 62 val numExist = Output(UInt(iqIdxWidth.W)) 63 }) 64 65 val srcAllNum = 3 66 val srcUseNum = 1 + (if(src2Use) 1 else 0) + (if(src3Use) 1 else 0)// when src2Use is false, then src3Use must be false 67 val srcListenNum = 1 + (if(src2Listen) 1 else 0) + (if(src3Listen) 1 else 0) // when src2Listen is false, then src3Listen must be false 68 // when use is false, Listen must be false 69 require(!(!src2Use && src2Listen)) 70 require(!(!src3Use && src3Listen)) 71 require(!(!src2Use && src3Use)) 72 require(!(!src2Listen && src3Listen)) 73 74 // Issue Queue 75 // val issQue = IndexableMem(iqSize, new ExuInput, mem = false, init = None) 76 val issQue = Mem(iqSize, new ExuInput) 77 // val issQue = Reg(Vec(iqSize, new ExuInput)) 78 val validQue = RegInit(VecInit(Seq.fill(iqSize)(false.B))) 79 val idQue = RegInit(VecInit((0 until iqSize).map(_.U(iqIdxWidth.W)))) 80 val idValidQue = VecInit((0 until iqSize).map(i => validQue(idQue(i)))).asUInt 81 val tailAll = RegInit(0.U((iqIdxWidth+1).W)) 82 val tail = tailAll(iqIdxWidth-1, 0) 83 val full = tailAll(iqIdxWidth) 84 85 // alias failed, turn to independent storage(Reg) 86 val psrc = VecInit(List.tabulate(iqSize)(i => VecInit(List(issQue(i.U).uop.psrc1, issQue(i.U).uop.psrc2, issQue(i.U).uop.psrc3)))) // NOTE: indexed by IssQue's idx 87 val srcRdyVec = Reg(Vec(iqSize, Vec(srcAllNum, Bool()))) // NOTE: indexed by IssQue's idx 88 val srcData = Reg(Vec(iqSize, Vec(srcAllNum, UInt(XLEN.W)))) // NOTE: indexed by IssQue's idx 89 val srcRdy = VecInit(srcRdyVec.map(a => if(src3Listen) { if(src2Listen) a(0)&&a(1)&&a(2) else a(0)&&a(2) } else { if(src2Listen) a(0)&&a(1) else a(0) }))// NOTE: indexed by IssQue's idx 90 val srcIdRdy = VecInit((0 until iqSize).map(i => srcRdy(idQue(i)))).asUInt // NOTE: indexed by IdQue's idx 91 val srcType = List.tabulate(iqSize)(i => List(issQue(i).uop.ctrl.src1Type, issQue(i).uop.ctrl.src2Type, issQue(i).uop.ctrl.src3Type)) // NOTE: indexed by IssQue's idx 92 93 // val srcDataWire = Wire(srcData) 94 val srcDataWire = Wire(Vec(iqSize, Vec(srcAllNum, UInt(XLEN.W)))) // NOTE: indexed by IssQue's idx 95 srcDataWire := srcData 96 srcData := srcDataWire 97 98 // there are three stages 99 // |-------------|--------------------|--------------| 100 // |Enq:get state|Deq: select/get data| fire stage | 101 // |-------------|--------------------|--------------| 102 103 //----------------------------------------- 104 // Enqueue 105 //----------------------------------------- 106 val enqRedHit = Wire(Bool()) 107 val enqFire = io.enqCtrl.fire() && !enqRedHit 108 val deqFire = io.deq.fire() 109 val popOne = Wire(Bool()) 110 io.enqCtrl.ready := !full || popOne 111 val enqSelIq = Wire(UInt(iqIdxWidth.W)) 112 val enqSrcRdy = List(Mux(SrcType.isPcImm(io.enqCtrl.bits.ctrl.src1Type), true.B, io.enqCtrl.bits.src1State === SrcState.rdy), 113 Mux(SrcType.isPcImm(io.enqCtrl.bits.ctrl.src2Type), true.B, io.enqCtrl.bits.src2State === SrcState.rdy), 114 Mux(SrcType.isPcImm(io.enqCtrl.bits.ctrl.src3Type), true.B, io.enqCtrl.bits.src3State === SrcState.rdy)) 115 116 // state enq 117 when (enqFire) { 118 issQue(enqSelIq).uop := io.enqCtrl.bits 119 validQue(enqSelIq) := true.B 120 assert(!validQue(enqSelIq) || popOne/* && idQue(deqSel)===enqSelIq*/) 121 122 srcRdyVec(enqSelIq)(0) := enqSrcRdy(0) 123 if(src2Listen) { srcRdyVec(enqSelIq)(1) := enqSrcRdy(1) } 124 if(src3Listen) { srcRdyVec(enqSelIq)(2) := enqSrcRdy(2) } 125 } 126 127 // data enq 128 val enqSelIqNext = RegEnable(enqSelIq, enqFire) 129 // val enqSelIqNext = RegNext(enqSelIq) 130 val enqFireNext = RegInit(false.B) 131 when (enqFireNext) { enqFireNext := false.B } 132 when (enqFire) { enqFireNext := true.B } 133 134 val enqDataVec = List(io.enqData.bits.src1, io.enqData.bits.src2, io.enqData.bits.src3) 135 when (enqFireNext) { 136 for(i <- 0 until srcUseNum) { 137 srcDataWire(enqSelIqNext)(i) := enqDataVec(i) 138 } 139 } 140 141 //----------------------------------------- 142 // tail 143 //----------------------------------------- 144 val tailInc = enqFire 145 val tailDec = popOne 146 val tailKeep = tailInc === tailDec 147 val tailAdd = tailAll + 1.U 148 val tailSub = tailAll - 1.U 149 tailAll := Mux(tailKeep, tailAll, Mux(tailInc, tailAdd, tailSub)) 150 assert(tailAll < 9.U) 151 // Select to Dequeue 152 val deqSel = if (fifo) 0.U else PriorityEncoder(idValidQue & srcIdRdy) //may not need idx, just need oneHot, idx by IdQue's idx 153 val deqSelIq = idQue(deqSel) 154 val deqSelOH = PriorityEncoderOH(idValidQue & srcIdRdy) 155 val has1Rdy = if (fifo) idValidQue(deqSel) && srcIdRdy(deqSel) else ParallelOR((validQue.asUInt & srcRdy.asUInt).asBools) 156 157 //----------------------------------------- 158 // idQue Move 159 //----------------------------------------- 160 def UIntToMHP(in: UInt) = { 161 // UInt to Multi-Hot plus 1: 1.U -> "11".U; 2.U(2.W) -> "0111".U; 3.U(3.W) -> "00001111".W 162 val a = Seq.fill(in.getWidth)(2).product 163 val s = (1 << (a-1)).S 164 Reverse((s(a-1,0).asSInt >> in)(a-1,0).asUInt) 165 } 166 def UIntToMH(in: UInt) = { 167 val a = Seq.fill(in.getWidth)(2).product 168 val s = (1 << (a-1)).S 169 Reverse((s(a-1,0).asSInt >> in)(a-1,0).asUInt) ^ UIntToOH(in) 170 } 171 def PriorityDot(in: UInt) = { 172 // "1100".U -> "0111".U; "1010".U -> "0011".U; "0000".U -> "0000".U 173 val a = Array.fill(iqSize)(1) 174 for(i <- 1 until in.getWidth) { 175 a(i) = a(i-1)*2 + 1 176 } 177 Mux(in===0.U, 0.U(in.getWidth.W), PriorityMux(in, a.map(_.U(in.getWidth.W)))) 178 } 179 val tailDot = Mux(full, VecInit(Seq.fill(iqSize)(true.B)).asUInt, UIntToMHP(tail)) 180 val tailDot2 = Mux(full, VecInit(Seq.fill(iqSize)(true.B)).asUInt, UIntToMH(tail)) 181 val selDot = UIntToMHP(deqSel) // FIXIT: PriorityEncoder -> UIntToMHP means long latency 182 val nonValid = ~(idValidQue | ~tailDot2) 183 val popSel = PriorityEncoder(nonValid) // Note: idxed by IDque's index 184 val popDot = PriorityDot(nonValid) 185 val isPop = ParallelOR(nonValid.asBools) 186 val moveDot = Mux(isPop, tailDot ^ popDot, tailDot ^ selDot) 187 188 assert(!(popOne&&moveDot(0))) 189 when (popOne) { 190 for(i <- 1 until iqSize) { 191 when (moveDot(i)) { idQue(i-1) := idQue(i) } 192 } 193 val ptr_tmp = Mux(full, VecInit(Seq.fill(iqIdxWidth)(true.B)).asUInt, tail) 194 idQue(ptr_tmp) := idQue(Mux(isPop, popSel, deqSel)) 195 } 196 assert(ParallelAND(List.tabulate(iqSize)(i => ParallelOR(List.tabulate(iqSize)(j => i.U === idQue(j)))))) 197 198 //----------------------------------------- 199 // Redirect 200 //----------------------------------------- 201 // redirect enq 202 enqRedHit := io.redirect.valid && io.enqCtrl.bits.needFlush(io.redirect) 203 204 // redirect issQue 205 val redHitVec = List.tabulate(iqSize)(i => issQue(i).uop.needFlush(io.redirect)) 206 for (i <- validQue.indices) { 207 when (redHitVec(i) && validQue(i)) { 208 validQue(i) := false.B 209 } 210 } 211 // reditect deq(issToExu) 212 val redIdHitVec = List.tabulate(iqSize)(i => issQue(idQue(i)).uop.brTag.needFlush(io.redirect)) 213 val selIsRed = ParallelOR((deqSelOH & VecInit(redIdHitVec).asUInt).asBools) 214 215 //----------------------------------------- 216 // Dequeue (or to Issue Stage) 217 //----------------------------------------- 218 val issueToExu = Reg(new ExuInput) 219 val issueToExuValid = RegInit(false.B) 220 val deqFlushHit = issueToExu.uop.needFlush(io.redirect) 221 val deqCanIn = !issueToExuValid || io.deq.ready || deqFlushHit 222 223 val toIssFire = deqCanIn && has1Rdy && !isPop && !selIsRed 224 popOne := deqCanIn && (has1Rdy || isPop) // send a empty or valid term to issueStage 225 226 when (toIssFire) { 227 issueToExu := issQue(deqSelIq) 228 issueToExuValid := true.B 229 validQue(deqSelIq) := enqFire && enqSelIq===deqSelIq 230 assert(validQue(deqSelIq)) 231 issueToExu.src1 := srcDataWire(deqSelIq)(0) 232 if (src2Use) { issueToExu.src2 := srcDataWire(deqSelIq)(1) } else { issueToExu.src2 := DontCare } 233 if (src3Use) { issueToExu.src3 := srcDataWire(deqSelIq)(2) } else { issueToExu.src3 := DontCare } 234 } 235 when ((deqFire || deqFlushHit) && !toIssFire) { 236 issueToExuValid := false.B 237 } 238 239 io.deq.valid := issueToExuValid && !deqFlushHit 240 io.deq.bits := issueToExu 241 242 enqSelIq := Mux(full, 243 Mux(isPop, 244 idQue(popSel), 245 deqSelIq 246 ), 247 idQue(tail) 248 ) // Note: direct by IQue's idx, different from deqSel 249 250 io.numExist := Mux(tailAll === iqSize.U, (iqSize-1).U, tailAll) 251 assert(tailAll < 9.U) 252 253 //----------------------------------------- 254 // Issue with No Delay 255 //----------------------------------------- 256 // when enq is ready && no other rdy && no pop && fireStage is ready && no flush 257 // send out directly without store the data 258 val enqAlreadyRdy = if(src3Listen) { if(src2Listen) enqSrcRdy(0)&&enqSrcRdy(1)&&enqSrcRdy(2) else enqSrcRdy(0)&&enqSrcRdy(2) } else { if(src2Listen) enqSrcRdy(0)&&enqSrcRdy(1) else enqSrcRdy(0) } 259 val enqALRdyNext = OneCycleFire(enqAlreadyRdy && enqFire) 260 val enqSendFlushHit = issQue(enqSelIqNext).uop.needFlush(io.redirect) 261 val enqSendEnable = if(fifo) { RegNext(tailAll===0.U) && enqALRdyNext && (!issueToExuValid || deqFlushHit) && (enqSelIqNext === deqSelIq) && !isPop && !enqSendFlushHit/* && has1Rdy*//* && io.deq.ready*/ } else { enqALRdyNext && (!issueToExuValid || deqFlushHit) && (enqSelIqNext === deqSelIq) && !isPop && !enqSendFlushHit/* && has1Rdy*//* && io.deq.ready*/ } // FIXME: has1Rdy has combination loop 262 when (enqSendEnable) { 263 io.deq.valid := true.B 264 io.deq.bits := issQue(enqSelIqNext) 265 io.deq.bits.src1 := enqDataVec(0) 266 if (src2Use) { io.deq.bits.src2 := enqDataVec(1) } 267 if (src3Use) { io.deq.bits.src3 := enqDataVec(2) } 268 issueToExuValid := false.B 269 when (!io.deq.ready) { // if Func Unit is not ready, store it to FireStage 270 issueToExuValid := true.B 271 } 272 } 273 274 //----------------------------------------- 275 // Wakeup and Bypass 276 //----------------------------------------- 277 val cdbValid = io.wakeUpPorts.map(_.valid) 278 val cdbData = io.wakeUpPorts.map(_.bits.data) 279 val cdbPdest = io.wakeUpPorts.map(_.bits.uop.pdest) 280 val cdbrfWen = io.wakeUpPorts.map(_.bits.uop.ctrl.rfWen) 281 val cdbfpWen = io.wakeUpPorts.map(_.bits.uop.ctrl.fpWen) 282 283 for(i <- idQue.indices) { // Should be IssQue.indices but Mem() does not support 284 for(j <- 0 until srcListenNum) { 285 val hitVec = cdbValid.indices.map(k => psrc(i)(j) === cdbPdest(k) && cdbValid(k) && (srcType(i)(j)===SrcType.reg && cdbrfWen(k) || srcType(i)(j)===SrcType.fp && cdbfpWen(k))) 286 val hit = ParallelOR(hitVec) 287 val data = ParallelMux(hitVec zip cdbData) 288 when (validQue(i) && !srcRdyVec(i)(j) && hit) { 289 srcDataWire(i)(j) := data 290 srcRdyVec(i)(j) := true.B 291 } 292 // XSDebug(validQue(i) && !srcRdyVec(i)(j) && hit, "WakeUp: Sel:%d Src:(%d|%d) Rdy:%d Hit:%d HitVec:%b Data:%x\n", i.U, j.U, psrc(i)(j), srcRdyVec(i)(j), hit, VecInit(hitVec).asUInt, data) 293 for (k <- cdbValid.indices) { 294 XSDebug(validQue(i) && !srcRdyVec(i)(j) && hit && hitVec(k), "WakeUpHit: IQIdx:%d Src%d:%d Ports:%d Data:%x Pc:%x RoqIdx:%x\n", i.U, j.U, psrc(i)(j), k.U, cdbData(k), io.wakeUpPorts(k).bits.uop.cf.pc, io.wakeUpPorts(k).bits.uop.roqIdx) 295 } 296 } 297 } 298 299 val bpPdest = io.bypassUops.map(_.bits.pdest) 300 val bpValid = io.bypassUops.map(_.valid) 301 val bpData = io.bypassData.map(_.bits.data) 302 val bprfWen = io.bypassUops.map(_.bits.ctrl.rfWen) 303 val bpfpWen = io.bypassUops.map(_.bits.ctrl.fpWen) 304 305 for (i <- idQue.indices) { // Should be IssQue.indices but Mem() does not support 306 for (j <- 0 until srcListenNum) { 307 val hitVec = bpValid.indices.map(k => psrc(i)(j) === bpPdest(k) && bpValid(k) && (srcType(i)(j)===SrcType.reg && bprfWen(k) || srcType(i)(j)===SrcType.fp && bpfpWen(k))) 308 val hitVecNext = hitVec.map(RegNext(_)) 309 val hit = ParallelOR(hitVec) 310 when (validQue(i) && !srcRdyVec(i)(j) && hit) { 311 srcRdyVec(i)(j) := true.B 312 } 313 when (RegNext(validQue(i) && !srcRdyVec(i)(j) && hit)) { 314 srcDataWire(i)(j) := PriorityMux(hitVecNext zip bpData) 315 } 316 // XSDebug(validQue(i) && !srcRdyVec(i)(j) && hit, "BypassCtrl: Sel:%d Src:(%d|%d) Rdy:%d Hit:%d HitVec:%b\n", i.U, j.U, psrc(i)(j), srcRdyVec(i)(j), hit, VecInit(hitVec).asUInt) 317 for (k <- bpValid.indices) { 318 XSDebug(validQue(i) && !srcRdyVec(i)(j) && hit && hitVec(k), "BypassCtrlHit: IQIdx:%d Src%d:%d Ports:%d Pc:%x RoqIdx:%x\n", i.U, j.U, psrc(i)(j), k.U, io.bypassUops(k).bits.cf.pc, io.bypassUops(k).bits.roqIdx) 319 } 320 // XSDebug(RegNext(validQue(i) && !srcRdyVec(i)(j) && hit), "BypassData: Sel:%d Src:(%d|%d) HitVecNext:%b Data:%x (for last cycle's Ctrl)\n", i.U, j.U, psrc(i)(j), VecInit(hitVecNext).asUInt, ParallelMux(hitVecNext zip bpData)) 321 for (k <- bpValid.indices) { 322 XSDebug(RegNext(validQue(i) && !srcRdyVec(i)(j) && hit && hitVec(k)), "BypassDataHit: IQIdx:%d Src%d:%d Ports:%d Data:%x Pc:%x RoqIdx:%x\n", i.U, j.U, psrc(i)(j), k.U, bpData(k), io.bypassUops(k).bits.cf.pc, io.bypassUops(k).bits.roqIdx) 323 } 324 } 325 } 326 327 // Enqueue Bypass 328 val enqCtrl = io.enqCtrl 329 val enqPsrc = List(enqCtrl.bits.psrc1, enqCtrl.bits.psrc2, enqCtrl.bits.psrc3) 330 val enqSrcType = List(enqCtrl.bits.ctrl.src1Type, enqCtrl.bits.ctrl.src2Type, enqCtrl.bits.ctrl.src3Type) 331 for (i <- 0 until srcListenNum) { 332 val hitVec = bpValid.indices.map(j => enqPsrc(i)===bpPdest(j) && bpValid(j) && (enqSrcType(i)===SrcType.reg && bprfWen(j) || enqSrcType(i)===SrcType.fp && bpfpWen(j))) 333 val hitVecNext = hitVec.map(RegNext(_)) 334 val hit = ParallelOR(hitVec) 335 when (enqFire && hit && !enqSrcRdy(i)) { 336 srcRdyVec(enqSelIq)(i) := true.B 337 } 338 when (RegNext(enqFire && hit && !enqSrcRdy(i))) { 339 srcDataWire(enqSelIqNext)(i) := ParallelMux(hitVecNext zip bpData) 340 } 341 // XSDebug(enqFire && hit, "EnqBypassCtrl: enqSelIq:%d Src:(%d|%d) Hit:%d HitVec:%b \n", enqSelIq, i.U, enqPsrc(i), hit, VecInit(hitVec).asUInt) 342 for (k <- bpValid.indices) { 343 XSDebug(enqFire && hit && !enqSrcRdy(i) && hitVec(k), "EnqBypassCtrlHit: enqSelIq:%d Src%d:%d Ports:%d Pc:%x RoqIdx:%x\n", enqSelIq, i.U, enqPsrc(i), k.U, io.bypassUops(k).bits.cf.pc, io.bypassUops(k).bits.roqIdx) 344 } 345 // XSDebug(RegNext(enqFire && hit), "EnqBypassData: enqSelIqNext:%d Src:(%d|%d) HitVecNext:%b Data:%x (for last cycle's Ctrl)\n", enqSelIqNext, i.U, enqPsrc(i), VecInit(hitVecNext).asUInt, ParallelMux(hitVecNext zip bpData)) 346 for (k <- bpValid.indices) { 347 XSDebug(RegNext(enqFire && hit && !enqSrcRdy(i) && hitVec(k)), "EnqBypassDataHit: enqSelIq:%d Src%d:%d Ports:%d Data:%x Pc:%x RoqIdx:%x\n", enqSelIq, i.U, enqPsrc(i), k.U, bpData(k), io.bypassUops(k).bits.cf.pc, io.bypassUops(k).bits.roqIdx) 348 } 349 } 350 351 if (enableBypass) { 352 // send out bypass 353 val sel = io.selectedUop 354 sel.valid := toIssFire && !enqSendEnable 355 sel.bits := DontCare 356 sel.bits.pdest := issQue(deqSelIq).uop.pdest 357 sel.bits.cf.pc := issQue(deqSelIq).uop.cf.pc 358 sel.bits.roqIdx := issQue(deqSelIq).uop.roqIdx 359 sel.bits.ctrl.rfWen := issQue(deqSelIq).uop.ctrl.rfWen 360 sel.bits.ctrl.fpWen := issQue(deqSelIq).uop.ctrl.fpWen 361 } 362 XSInfo(io.redirect.valid, "Redirect: valid:%d isExp:%d brTag:%d redHitVec:%b redIdHitVec:%b enqHit:%d selIsRed:%d\n", io.redirect.valid, io.redirect.bits.isException, io.redirect.bits.brTag.value, VecInit(redHitVec).asUInt, VecInit(redIdHitVec).asUInt, enqRedHit, selIsRed) 363 XSInfo(enqFire, s"EnqCtrl(%d %d) enqSelIq:%d Psrc/Rdy(%d:%d %d:%d %d:%d) Dest:%d oldDest:%d pc:%x roqIdx:%x\n", io.enqCtrl.valid, io.enqCtrl.ready, enqSelIq 364 , io.enqCtrl.bits.psrc1, io.enqCtrl.bits.src1State, io.enqCtrl.bits.psrc2, io.enqCtrl.bits.src2State, io.enqCtrl.bits.psrc3, io.enqCtrl.bits.src3State, io.enqCtrl.bits.pdest, io.enqCtrl.bits.old_pdest, io.enqCtrl.bits.cf.pc, io.enqCtrl.bits.roqIdx) 365 XSInfo(enqFireNext, "EnqData: src1:%x src2:%x src3:%x pc:%x roqIdx:%x(for last cycle's Ctrl)\n", io.enqData.bits.src1, io.enqData.bits.src2, io.enqData.bits.src3, issQue(enqSelIqNext).uop.cf.pc, issQue(enqSelIqNext).uop.roqIdx) 366 XSInfo(deqFire, "Deq:(%d %d) [%d|%x][%d|%x][%d|%x] pdest:%d pc:%x roqIdx:%x\n", io.deq.valid, io.deq.ready, io.deq.bits.uop.psrc1, io.deq.bits.src1, io.deq.bits.uop.psrc2, io.deq.bits.src2, io.deq.bits.uop.psrc3, io.deq.bits.src3, io.deq.bits.uop.pdest, io.deq.bits.uop.cf.pc, io.deq.bits.uop.roqIdx) 367 XSDebug("tailAll:%d KID(%d%d%d) tailDot:%b tailDot2:%b selDot:%b popDot:%b moveDot:%b In(%d %d) Out(%d %d)\n", tailAll, tailKeep, tailInc, tailDec, tailDot, tailDot2, selDot, popDot, moveDot, io.enqCtrl.valid, io.enqCtrl.ready, io.deq.valid, io.deq.ready) 368 XSInfo(issueToExuValid, "FireStage:Out(%d %d) src1(%d|%x) src2(%d|%x) src3(%d|%x) deqFlush:%d pc:%x roqIdx:%d\n", io.deq.valid, io.deq.ready, issueToExu.uop.psrc1, issueToExu.src1, issueToExu.uop.psrc2, issueToExu.src2, issueToExu.uop.psrc3, issueToExu.src3, deqFlushHit, issueToExu.uop.cf.pc, issueToExu.uop.roqIdx) 369 if(enableBypass) { 370 XSDebug("popOne:%d isPop:%d popSel:%d deqSel:%d deqCanIn:%d toIssFire:%d has1Rdy:%d selIsRed:%d nonValid:%b SelUop:(%d, %d)\n", popOne, isPop, popSel, deqSel, deqCanIn, toIssFire, has1Rdy, selIsRed, nonValid, io.selectedUop.valid, io.selectedUop.bits.pdest) 371 } else { 372 XSDebug("popOne:%d isPop:%d popSel:%d deqSel:%d deqCanIn:%d toIssFire:%d has1Rdy:%d selIsRed:%d nonValid:%b\n", popOne, isPop, popSel, deqSel, deqCanIn, toIssFire, has1Rdy, selIsRed, nonValid) 373 } 374 375 XSDebug(enqSendEnable, p"NoDelayIss: enqALRdy:${enqAlreadyRdy} *Next:${enqALRdyNext} En:${enqSendEnable} flush:${enqSendFlushHit} enqSelIqNext:${enqSelIqNext} deqSelIq:${deqSelIq} deqReady:${io.deq.ready}\n") 376 XSDebug(s"id|v|r|psrc|r| src1 |psrc|r| src2 |psrc|r| src3 |brTag| pc |roqIdx Exu:${exuCfg.name}\n") 377 378 for (i <- 0 until iqSize) { 379 when (i.U===tail && tailAll=/=8.U) { 380 XSDebug("%d |%d|%d| %d|%b|%x| %d|%b|%x| %d|%b|%x| %x |%x|%x <-\n", 381 idQue(i), 382 idValidQue(i), 383 srcRdy(idQue(i)), 384 psrc(idQue(i))(0), 385 srcRdyVec(idQue(i))(0), 386 srcData(idQue(i))(0), 387 psrc(idQue(i))(1), 388 srcRdyVec(idQue(i))(1), 389 srcData(idQue(i))(1), 390 psrc(idQue(i))(2), 391 srcRdyVec(idQue(i))(2), 392 srcData(idQue(i))(2), 393 issQue(idQue(i)).uop.brTag.value, 394 issQue(idQue(i)).uop.cf.pc, 395 issQue(idQue(i)).uop.roqIdx 396 ) 397 }.otherwise { 398 XSDebug("%d |%d|%d| %d|%b|%x| %d|%b|%x| %d|%b|%x| %x |%x|%x\n", 399 idQue(i), 400 idValidQue(i), 401 srcRdy(idQue(i)), 402 psrc(idQue(i))(0), 403 srcRdyVec(idQue(i))(0), 404 srcData(idQue(i))(0), 405 psrc(idQue(i))(1), 406 srcRdyVec(idQue(i))(1), 407 srcData(idQue(i))(1), 408 psrc(idQue(i))(2), 409 srcRdyVec(idQue(i))(2), 410 srcData(idQue(i))(2), 411 issQue(idQue(i)).uop.brTag.value, 412 issQue(idQue(i)).uop.cf.pc, 413 issQue(idQue(i)).uop.roqIdx 414 ) 415 } 416 } 417}