xref: /XiangShan/src/main/scala/xiangshan/backend/issue/IssueQueue.scala (revision bc41f0166965820b4f1008dcc746ded55d25667a)
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 = idQue(tail) // Note: direct by IQue's idx, different from deqSel
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  // Wakeup and Bypass
225  //-----------------------------------------
226  if (wakeupCnt > 0) {
227    val cdbValid = List.tabulate(wakeupCnt)(i => io.wakeUpPorts(i).valid)
228    val cdbData = List.tabulate(wakeupCnt)(i => io.wakeUpPorts(i).bits.data)
229    val cdbPdest = List.tabulate(wakeupCnt)(i => io.wakeUpPorts(i).bits.uop.pdest)
230    val cdbrfWen = List.tabulate(wakeupCnt)(i => io.wakeUpPorts(i).bits.uop.ctrl.rfWen)
231    val cdbfpWen = List.tabulate(wakeupCnt)(i => io.wakeUpPorts(i).bits.uop.ctrl.fpWen)
232
233    for(i <- 0 until iqSize) {
234      for(j <- 0 until srcListenNum) {
235        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)))
236        val hit = ParallelOR(hitVec).asBool
237        val data = ParallelMux(hitVec zip cdbData)
238        when (validQue(i) && !srcRdyVec(i)(j) && hit) {
239          srcDataWire(i)(j) := data
240          srcRdyVec(i)(j) := true.B
241        }
242        // 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)
243        for (k <- 0 until wakeupCnt) {
244          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)
245        }
246      }
247    }
248  }
249  if (useBypass) {
250    val bpPdest = List.tabulate(bypassCnt)(i => io.bypassUops(i).bits.pdest)
251    val bpValid = List.tabulate(bypassCnt)(i => io.bypassUops(i).valid)
252    val bpData = List.tabulate(bypassCnt)(i => io.bypassData(i).bits.data)
253    val bprfWen = List.tabulate(bypassCnt)(i => io.bypassUops(i).bits.ctrl.rfWen)
254    val bpfpWen = List.tabulate(bypassCnt)(i => io.bypassUops(i).bits.ctrl.fpWen)
255
256    for (i <- 0 until iqSize) {
257      for (j <- 0 until srcListenNum) {
258        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)))
259        val hitVecNext = hitVec.map(RegNext(_))
260        val hit = ParallelOR(hitVec).asBool
261        when (validQue(i) && !srcRdyVec(i)(j) && hit) {
262          srcRdyVec(i)(j) := true.B // FIXME: if uncomment the up comment, will cause combiantional loop, but it is Mem type??
263        }
264        when (RegNext(validQue(i) && !srcRdyVec(i)(j) && hit)) {
265          srcDataWire(i)(j) := PriorityMux(hitVecNext zip bpData)
266        }
267        // 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)
268        for (k <- 0 until bypassCnt) {
269          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)
270        }
271        // 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))
272        for (k <- 0 until bypassCnt) {
273          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)
274        }
275      }
276    }
277
278    // Enqueue Bypass
279    val enqCtrl = io.enqCtrl
280    val enqPsrc = List(enqCtrl.bits.psrc1, enqCtrl.bits.psrc2, enqCtrl.bits.psrc3)
281    val enqSrcType = List(enqCtrl.bits.ctrl.src1Type, enqCtrl.bits.ctrl.src2Type, enqCtrl.bits.ctrl.src3Type)
282    for (i <- 0 until srcListenNum) {
283      val hitVec = List.tabulate(bypassCnt)(j => enqPsrc(i)===bpPdest(j) && bpValid(j) && (enqSrcType(i)===SrcType.reg && bprfWen(j) || enqSrcType(i)===SrcType.fp && bpfpWen(j)))
284      val hitVecNext = hitVec.map(RegNext(_))
285      val hit = ParallelOR(hitVec).asBool
286      when (enqFire && hit && !enqSrcRdy(i)) {
287        srcRdyVec(enqSelIq)(i) := true.B
288      }
289      when (RegNext(enqFire && hit && !enqSrcRdy(i))) {
290        srcDataWire(enqSelIqNext)(i) := ParallelMux(hitVecNext zip bpData)
291      }
292      // XSDebug(enqFire && hit, "EnqBypassCtrl: enqSelIq:%d Src:(%d|%d) Hit:%d HitVec:%b \n", enqSelIq, i.U, enqPsrc(i), hit, VecInit(hitVec).asUInt)
293      for (k <- 0 until bypassCnt) {
294        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)
295      }
296      // 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))
297      for (k <- 0 until bypassCnt) {
298        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)
299      }
300    }
301
302    // send out bypass
303    assert(fixedDelay==1) // only support fixedDelay is 1 now
304    val sel = io.selectedUop
305    sel.valid := toIssFire
306    sel.bits := DontCare
307    sel.bits.pdest := issQue(deqSelIq).uop.pdest
308    sel.bits.cf.pc := issQue(deqSelIq).uop.cf.pc
309    sel.bits.roqIdx := issQue(deqSelIq).uop.roqIdx
310    sel.bits.ctrl.rfWen := issQue(deqSelIq).uop.ctrl.rfWen
311    sel.bits.ctrl.fpWen := issQue(deqSelIq).uop.ctrl.fpWen
312  }
313  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)
314  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
315    , 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)
316  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)
317  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)
318  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)
319  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)
320  if(useBypass) {
321    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)
322  } else {
323    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)
324  }
325  XSDebug("id|v|r|psrc|r|   src1         |psrc|r|   src2         |psrc|r|   src3         |brTag|    pc    |roqIdx FuType:%x\n", fuTypeInt.U)
326  for (i <- 0 until iqSize) {
327    when (i.U===tail && tailAll=/=8.U) {
328      XSDebug("%d |%d|%d| %d|%b|%x| %d|%b|%x| %d|%b|%x| %x |%x|%x <-\n",
329        idQue(i),
330        idValidQue(i),
331        srcRdy(idQue(i)),
332        psrc(idQue(i))(0),
333        srcRdyVec(idQue(i))(0),
334        srcData(idQue(i))(0),
335        psrc(idQue(i))(1),
336        srcRdyVec(idQue(i))(1),
337        srcData(idQue(i))(1),
338        psrc(idQue(i))(2),
339        srcRdyVec(idQue(i))(2),
340        srcData(idQue(i))(2),
341        issQue(idQue(i)).uop.brTag.value,
342        issQue(idQue(i)).uop.cf.pc,
343        issQue(idQue(i)).uop.roqIdx
344      )
345    }.otherwise {
346      XSDebug("%d |%d|%d| %d|%b|%x| %d|%b|%x| %d|%b|%x| %x |%x|%x\n",
347        idQue(i),
348        idValidQue(i),
349        srcRdy(idQue(i)),
350        psrc(idQue(i))(0),
351        srcRdyVec(idQue(i))(0),
352        srcData(idQue(i))(0),
353        psrc(idQue(i))(1),
354        srcRdyVec(idQue(i))(1),
355        srcData(idQue(i))(1),
356        psrc(idQue(i))(2),
357        srcRdyVec(idQue(i))(2),
358        srcData(idQue(i))(2),
359        issQue(idQue(i)).uop.brTag.value,
360        issQue(idQue(i)).uop.cf.pc,
361        issQue(idQue(i)).uop.roqIdx
362      )
363    }
364  }
365}