xref: /XiangShan/src/main/scala/xiangshan/backend/issue/IssueQueue.scala (revision 9550e6e20b62a6a18a3b6a279e6d600ed6c8b87d)
1package xiangshan.backend.issue
2
3import chisel3._
4import chisel3.util._
5import xiangshan._
6import xiangshan.backend.rename.FreeListPtr
7import xiangshan.utils._
8
9trait IQConst extends HasXSParameter{
10  val iqSize = IssQueSize
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    // to Dispatch
48    val numExist = Output(UInt((iqIdxWidth+1).W))
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.ctrl.src1Type), true.B, io.enqCtrl.bits.src1State === SrcState.rdy),
99                       Mux(SrcType.isPcImm(io.enqCtrl.bits.ctrl.src2Type), true.B, io.enqCtrl.bits.src2State === SrcState.rdy),
100                       Mux(SrcType.isPcImm(io.enqCtrl.bits.ctrl.src3Type), true.B, io.enqCtrl.bits.src3State === SrcState.rdy))
101
102  // state enq
103  when (enqFire) {
104    issQue(enqSelIq).uop := io.enqCtrl.bits
105    validQue(enqSelIq) := true.B
106    assert(!validQue(enqSelIq) || popOne/* && idQue(deqSel)===enqSelIq*/)
107
108    srcRdyVec(enqSelIq)(0) := enqSrcRdy(0)
109    if(src2Listen) { srcRdyVec(enqSelIq)(1) := enqSrcRdy(1) }
110    if(src3Listen) { srcRdyVec(enqSelIq)(2) := enqSrcRdy(2) }
111  }
112
113  // data enq
114  val enqSelIqNext = RegEnable(enqSelIq, enqFire)
115  // val enqSelIqNext = RegNext(enqSelIq)
116  val enqFireNext = RegInit(false.B)
117  when (enqFireNext) { enqFireNext := false.B }
118  when (enqFire) { enqFireNext := true.B }
119
120  val enqDataVec = List(io.enqData.bits.src1, io.enqData.bits.src2, io.enqData.bits.src3)
121  when (enqFireNext) {
122    for(i <- 0 until srcUseNum) {
123      srcDataWire(enqSelIqNext)(i) := enqDataVec(i)
124    }
125  }
126
127  //-----------------------------------------
128  // tail
129  //-----------------------------------------
130  val tailInc = enqFire
131  val tailDec = popOne
132  val tailKeep = tailInc === tailDec
133  val tailAdd = tailAll + 1.U
134  val tailSub = tailAll - 1.U
135  tailAll := Mux(tailKeep, tailAll, Mux(tailInc, tailAdd, tailSub))
136  assert(tailAll < 9.U)
137  // Select to Dequeue
138  val deqSel = if (fifo) 0.U else PriorityEncoder(idValidQue & srcIdRdy) //may not need idx, just need oneHot, idx by IdQue's idx
139  val deqSelIq = idQue(deqSel)
140  val deqSelOH = PriorityEncoderOH(idValidQue & srcIdRdy)
141  val has1Rdy = if (fifo) idValidQue(deqSel) && srcIdRdy(deqSel) else ParallelOR((validQue.asUInt & srcRdy.asUInt).asBools).asBool()
142
143  //-----------------------------------------
144  // idQue Move
145  //-----------------------------------------
146  def UIntToMHP(in: UInt) = {
147    // UInt to Multi-Hot plus 1: 1.U -> "11".U; 2.U(2.W) -> "0111".U; 3.U(3.W) -> "00001111".W
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)
151  }
152  def UIntToMH(in: UInt) = {
153    val a = Seq.fill(in.getWidth)(2).product
154    val s = (1 << (a-1)).S
155    Reverse((s(a-1,0).asSInt >> in)(a-1,0).asUInt) ^ UIntToOH(in)
156  }
157  def PriorityDot(in: UInt) = {
158    // "1100".U -> "0111".U; "1010".U -> "0011".U; "0000".U -> "0000".U
159    val a = Array.fill(iqSize)(1)
160    for(i <- 1 until in.getWidth) {
161      a(i) = a(i-1)*2 + 1
162    }
163    Mux(in===0.U, 0.U(in.getWidth.W), PriorityMux(in, a.map(_.U(in.getWidth.W))))
164  }
165  val tailDot = Mux(full, VecInit(Seq.fill(iqSize)(true.B)).asUInt, UIntToMHP(tail))
166  val tailDot2 = Mux(full, VecInit(Seq.fill(iqSize)(true.B)).asUInt, UIntToMH(tail))
167  val selDot = UIntToMHP(deqSel) // FIXIT: PriorityEncoder -> UIntToMHP means long latency
168  val nonValid = ~(idValidQue | ~tailDot2)
169  val popSel = PriorityEncoder(nonValid) // Note: idxed by IDque's index
170  val popDot = PriorityDot(nonValid)
171  val isPop = ParallelOR(nonValid.asBools).asBool()
172  val moveDot = Mux(isPop, tailDot ^ popDot, tailDot ^ selDot)
173
174  assert(!(popOne&&moveDot(0)))
175  when (popOne) {
176    for(i <- 1 until iqSize) {
177      when (moveDot(i)) { idQue(i-1) := idQue(i) }
178    }
179    val ptr_tmp = Mux(full, VecInit(Seq.fill(iqIdxWidth)(true.B)).asUInt, tail)
180    idQue(ptr_tmp) := idQue(Mux(isPop, popSel, deqSel))
181  }
182  assert(ParallelAND(List.tabulate(iqSize)(i => ParallelOR(List.tabulate(iqSize)(j => i.U === idQue(j))))).asBool)
183
184  //-----------------------------------------
185  // Redirect
186  //-----------------------------------------
187  // redirect enq
188  enqRedHit := io.redirect.valid && io.enqCtrl.bits.brTag.needFlush(io.redirect)
189
190  // redirect issQue
191  val redHitVec = List.tabulate(iqSize)(i => issQue(i).uop.brTag.needFlush(io.redirect))
192  for (i <- validQue.indices) {
193    when (redHitVec(i) && validQue(i)) {
194      validQue(i) := false.B
195    }
196  }
197  // reditect deq(issToExu)
198  val redIdHitVec = List.tabulate(iqSize)(i => issQue(idQue(i)).uop.brTag.needFlush(io.redirect))
199  val selIsRed = ParallelOR((deqSelOH & VecInit(redIdHitVec).asUInt).asBools).asBool
200
201  //-----------------------------------------
202  // Dequeue (or to Issue Stage)
203  //-----------------------------------------
204  val issueToExu = Reg(new ExuInput)
205  val issueToExuValid = RegInit(false.B)
206  val deqFlushHit = issueToExu.uop.brTag.needFlush(io.redirect)
207  val deqCanIn = !issueToExuValid || deqFire || deqFlushHit
208
209  val toIssFire = deqCanIn && has1Rdy && !isPop && !selIsRed
210  popOne := deqCanIn && (has1Rdy || isPop) // send a empty or valid term to issueStage
211
212  when (toIssFire) {
213    issueToExu := issQue(deqSelIq)
214    issueToExuValid := true.B
215    validQue(deqSelIq) := enqFire && enqSelIq===deqSelIq
216    assert(validQue(deqSelIq))
217    issueToExu.src1 := srcDataWire(deqSelIq)(0)
218    if (src2Use) { issueToExu.src2 := srcDataWire(deqSelIq)(1) } else { issueToExu.src2 := DontCare }
219    if (src3Use) { issueToExu.src3 := srcDataWire(deqSelIq)(2) } else { issueToExu.src3 := DontCare }
220  }
221  when ((deqFire || deqFlushHit) && !toIssFire) {
222    issueToExuValid := false.B
223  }
224
225  io.deq.valid := issueToExuValid && !deqFlushHit
226  io.deq.bits := issueToExu
227
228
229  enqSelIq := Mux(full,
230    Mux(isPop,
231      idQue(popSel),
232      deqSelIq
233    ),
234    idQue(tail)
235  ) // Note: direct by IQue's idx, different from deqSel
236
237  io.numExist := tailAll
238  assert(tailAll < 9.U)
239
240  //-----------------------------------------
241  // Wakeup and Bypass
242  //-----------------------------------------
243  if (wakeupCnt > 0) {
244    val cdbValid = io.wakeUpPorts.map(_.valid)
245    val cdbData  = io.wakeUpPorts.map(_.bits.data)
246    val cdbPdest = io.wakeUpPorts.map(_.bits.uop.pdest)
247    val cdbrfWen = io.wakeUpPorts.map(_.bits.uop.ctrl.rfWen)
248    val cdbfpWen = io.wakeUpPorts.map(_.bits.uop.ctrl.fpWen)
249
250    for(i <- idQue.indices) { // Should be IssQue.indices but Mem() does not support
251      for(j <- 0 until srcListenNum) {
252        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)))
253        val hit = ParallelOR(hitVec).asBool
254        val data = ParallelMux(hitVec zip cdbData)
255        when (validQue(i) && !srcRdyVec(i)(j) && hit) {
256          srcDataWire(i)(j) := data
257          srcRdyVec(i)(j) := true.B
258        }
259        // 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)
260        for (k <- cdbValid.indices) {
261          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)
262        }
263      }
264    }
265  }
266  if (useBypass) {
267    val bpPdest = io.bypassUops.map(_.bits.pdest)
268    val bpValid = io.bypassUops.map(_.valid)
269    val bpData  = io.bypassData.map(_.bits.data)
270    val bprfWen = io.bypassUops.map(_.bits.ctrl.rfWen)
271    val bpfpWen = io.bypassUops.map(_.bits.ctrl.fpWen)
272
273    for (i <- idQue.indices) { // Should be IssQue.indices but Mem() does not support
274      for (j <- 0 until srcListenNum) {
275        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)))
276        val hitVecNext = hitVec.map(RegNext(_))
277        val hit = ParallelOR(hitVec).asBool
278        when (validQue(i) && !srcRdyVec(i)(j) && hit) {
279          srcRdyVec(i)(j) := true.B
280        }
281        when (RegNext(validQue(i) && !srcRdyVec(i)(j) && hit)) {
282          srcDataWire(i)(j) := PriorityMux(hitVecNext zip bpData)
283        }
284        // 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)
285        for (k <- bpValid.indices) {
286          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)
287        }
288        // 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))
289        for (k <- bpValid.indices) {
290          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)
291        }
292      }
293    }
294
295    // Enqueue Bypass
296    val enqCtrl = io.enqCtrl
297    val enqPsrc = List(enqCtrl.bits.psrc1, enqCtrl.bits.psrc2, enqCtrl.bits.psrc3)
298    val enqSrcType = List(enqCtrl.bits.ctrl.src1Type, enqCtrl.bits.ctrl.src2Type, enqCtrl.bits.ctrl.src3Type)
299    for (i <- 0 until srcListenNum) {
300      val hitVec = bpValid.indices.map(j => enqPsrc(i)===bpPdest(j) && bpValid(j) && (enqSrcType(i)===SrcType.reg && bprfWen(j) || enqSrcType(i)===SrcType.fp && bpfpWen(j)))
301      val hitVecNext = hitVec.map(RegNext(_))
302      val hit = ParallelOR(hitVec).asBool
303      when (enqFire && hit && !enqSrcRdy(i)) {
304        srcRdyVec(enqSelIq)(i) := true.B
305      }
306      when (RegNext(enqFire && hit && !enqSrcRdy(i))) {
307        srcDataWire(enqSelIqNext)(i) := ParallelMux(hitVecNext zip bpData)
308      }
309      // XSDebug(enqFire && hit, "EnqBypassCtrl: enqSelIq:%d Src:(%d|%d) Hit:%d HitVec:%b \n", enqSelIq, i.U, enqPsrc(i), hit, VecInit(hitVec).asUInt)
310      for (k <- bpValid.indices) {
311        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)
312      }
313      // 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))
314      for (k <- bpValid.indices) {
315        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)
316      }
317    }
318
319    // send out bypass
320    require(fixedDelay==1) // only support fixedDelay is 1 now
321    val sel = io.selectedUop
322    sel.valid := toIssFire
323    sel.bits := DontCare
324    sel.bits.pdest := issQue(deqSelIq).uop.pdest
325    sel.bits.cf.pc := issQue(deqSelIq).uop.cf.pc
326    sel.bits.roqIdx := issQue(deqSelIq).uop.roqIdx
327    sel.bits.ctrl.rfWen := issQue(deqSelIq).uop.ctrl.rfWen
328    sel.bits.ctrl.fpWen := issQue(deqSelIq).uop.ctrl.fpWen
329  }
330  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)
331  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
332    , 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)
333  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)
334  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)
335  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)
336  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)
337  if(useBypass) {
338    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)
339  } else {
340    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)
341  }
342  XSDebug("id|v|r|psrc|r|   src1         |psrc|r|   src2         |psrc|r|   src3         |brTag|    pc    |roqIdx FuType:%x\n", fuTypeInt.U)
343  for (i <- 0 until iqSize) {
344    when (i.U===tail && tailAll=/=8.U) {
345      XSDebug("%d |%d|%d| %d|%b|%x| %d|%b|%x| %d|%b|%x| %x |%x|%x <-\n",
346        idQue(i),
347        idValidQue(i),
348        srcRdy(idQue(i)),
349        psrc(idQue(i))(0),
350        srcRdyVec(idQue(i))(0),
351        srcData(idQue(i))(0),
352        psrc(idQue(i))(1),
353        srcRdyVec(idQue(i))(1),
354        srcData(idQue(i))(1),
355        psrc(idQue(i))(2),
356        srcRdyVec(idQue(i))(2),
357        srcData(idQue(i))(2),
358        issQue(idQue(i)).uop.brTag.value,
359        issQue(idQue(i)).uop.cf.pc,
360        issQue(idQue(i)).uop.roqIdx
361      )
362    }.otherwise {
363      XSDebug("%d |%d|%d| %d|%b|%x| %d|%b|%x| %d|%b|%x| %x |%x|%x\n",
364        idQue(i),
365        idValidQue(i),
366        srcRdy(idQue(i)),
367        psrc(idQue(i))(0),
368        srcRdyVec(idQue(i))(0),
369        srcData(idQue(i))(0),
370        psrc(idQue(i))(1),
371        srcRdyVec(idQue(i))(1),
372        srcData(idQue(i))(1),
373        psrc(idQue(i))(2),
374        srcRdyVec(idQue(i))(2),
375        srcData(idQue(i))(2),
376        issQue(idQue(i)).uop.brTag.value,
377        issQue(idQue(i)).uop.cf.pc,
378        issQue(idQue(i)).uop.roqIdx
379      )
380    }
381  }
382}