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