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