xref: /XiangShan/src/main/scala/xiangshan/backend/issue/IssueQueue.scala (revision d077b11804222346941c6a7dc7188e89b46579a4)
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}