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