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