xref: /XiangShan/src/main/scala/xiangshan/backend/issue/IssueQueue.scala (revision ebfa1e8e74b8219ef0107bf306f6afd274c7f74f)
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.redirect.bits.isException || ParallelOR((UIntToOH(io.redirect.bits.brTag) & io.enqCtrl.bits.brMask).asBools).asBool)
184
185  // redirect issQue
186  val redHitVec = List.tabulate(iqSize)(i => io.redirect.valid && (io.redirect.bits.isException || ParallelOR((UIntToOH(io.redirect.bits.brTag) & issQue(i).uop.brMask).asBools).asBool))
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 => io.redirect.valid && (io.redirect.bits.isException || ParallelOR((UIntToOH(io.redirect.bits.brTag) & issQue(idQue(i)).uop.brMask).asBools).asBool))
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 = io.redirect.valid && (io.redirect.bits.isException ||
202                 ParallelOR((issueToExu.uop.brMask & UIntToOH(io.redirect.bits.brTag)).asBools).asBool)
203  val deqCanIn = !issueToExuValid || deqFire || deqFlushHit
204
205  val toIssFire = deqCanIn && has1Rdy && !isPop && !selIsRed
206  popOne := deqCanIn && (has1Rdy || isPop) // send a empty or valid term to issueStage
207
208  when (toIssFire) {
209    issueToExu := issQue(deqSelIq)
210    issueToExuValid := true.B
211    validQue(deqSelIq) := enqFire && enqSelIq===deqSelIq
212    assert(validQue(deqSelIq))
213    issueToExu.src1 := srcDataWire(deqSelIq)(0)
214    if (src2Use) { issueToExu.src2 := srcDataWire(deqSelIq)(1) } else { issueToExu.src2 := DontCare }
215    if (src3Use) { issueToExu.src3 := srcDataWire(deqSelIq)(2) } else { issueToExu.src3 := DontCare }
216  }
217  when ((deqFire || deqFlushHit) && !toIssFire) {
218    issueToExuValid := false.B
219  }
220
221  io.deq.valid := issueToExuValid && !deqFlushHit
222  io.deq.bits := issueToExu
223
224  //-----------------------------------------
225  // Wakeup and Bypass
226  //-----------------------------------------
227  if (wakeupCnt > 0) {
228    val cdbValid = List.tabulate(wakeupCnt)(i => io.wakeUpPorts(i).valid)
229    val cdbData = List.tabulate(wakeupCnt)(i => io.wakeUpPorts(i).bits.data)
230    val cdbPdest = List.tabulate(wakeupCnt)(i => io.wakeUpPorts(i).bits.uop.pdest)
231    val cdbrfWen = List.tabulate(wakeupCnt)(i => io.wakeUpPorts(i).bits.uop.ctrl.rfWen)
232    val cdbfpWen = List.tabulate(wakeupCnt)(i => io.wakeUpPorts(i).bits.uop.ctrl.fpWen)
233
234    for(i <- 0 until iqSize) {
235      for(j <- 0 until srcListenNum) {
236        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)))
237        val hit = ParallelOR(hitVec).asBool
238        val data = ParallelMux(hitVec zip cdbData)
239        when (validQue(i) && !srcRdyVec(i)(j) && hit) {
240          srcDataWire(i)(j) := data
241          srcRdyVec(i)(j) := true.B
242        }
243        // 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)
244        for (k <- 0 until wakeupCnt) {
245          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)
246        }
247      }
248    }
249  }
250  if (useBypass) {
251    val bpPdest = List.tabulate(bypassCnt)(i => io.bypassUops(i).bits.pdest)
252    val bpValid = List.tabulate(bypassCnt)(i => io.bypassUops(i).valid)
253    val bpData = List.tabulate(bypassCnt)(i => io.bypassData(i).bits.data)
254    val bprfWen = List.tabulate(bypassCnt)(i => io.bypassUops(i).bits.ctrl.rfWen)
255    val bpfpWen = List.tabulate(bypassCnt)(i => io.bypassUops(i).bits.ctrl.fpWen)
256
257    for (i <- 0 until iqSize) {
258      for (j <- 0 until srcListenNum) {
259        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)))
260        val hitVecNext = hitVec.map(RegNext(_))
261        val hit = ParallelOR(hitVec).asBool
262        when (validQue(i) && !srcRdyVec(i)(j) && hit) {
263          srcRdyVec(i)(j) := true.B // FIXME: if uncomment the up comment, will cause combiantional loop, but it is Mem type??
264        }
265        when (RegNext(validQue(i) && !srcRdyVec(i)(j) && hit)) {
266          srcDataWire(i)(j) := PriorityMux(hitVecNext zip bpData)
267        }
268        // 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)
269        for (k <- 0 until bypassCnt) {
270          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)
271        }
272        // 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))
273        for (k <- 0 until bypassCnt) {
274          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)
275        }
276      }
277    }
278
279    // Enqueue Bypass
280    val enqCtrl = io.enqCtrl
281    val enqPsrc = List(enqCtrl.bits.psrc1, enqCtrl.bits.psrc2, enqCtrl.bits.psrc3)
282    val enqSrcType = List(enqCtrl.bits.ctrl.src1Type, enqCtrl.bits.ctrl.src2Type, enqCtrl.bits.ctrl.src3Type)
283    for (i <- 0 until srcListenNum) {
284      val hitVec = List.tabulate(bypassCnt)(j => enqPsrc(i)===bpPdest(j) && bpValid(j) && (enqSrcType(i)===SrcType.reg && bprfWen(j) || enqSrcType(i)===SrcType.fp && bpfpWen(j)))
285      val hitVecNext = hitVec.map(RegNext(_))
286      val hit = ParallelOR(hitVec).asBool
287      when (enqFire && hit && !enqSrcRdy(i)) {
288        srcRdyVec(enqSelIq)(i) := true.B
289      }
290      when (RegNext(enqFire && hit && !enqSrcRdy(i))) {
291        srcDataWire(enqSelIqNext)(i) := ParallelMux(hitVecNext zip bpData)
292      }
293      // XSDebug(enqFire && hit, "EnqBypassCtrl: enqSelIq:%d Src:(%d|%d) Hit:%d HitVec:%b \n", enqSelIq, i.U, enqPsrc(i), hit, VecInit(hitVec).asUInt)
294      for (k <- 0 until bypassCnt) {
295        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)
296      }
297      // 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))
298      for (k <- 0 until bypassCnt) {
299        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)
300      }
301    }
302
303    // send out bypass
304    assert(fixedDelay==1) // only support fixedDelay is 1 now
305    val sel = io.selectedUop
306    sel.valid := toIssFire
307    sel.bits := DontCare
308    sel.bits.pdest := issQue(deqSelIq).uop.pdest
309    sel.bits.cf.pc := issQue(deqSelIq).uop.cf.pc
310    sel.bits.roqIdx := issQue(deqSelIq).uop.roqIdx
311    sel.bits.ctrl.rfWen := issQue(deqSelIq).uop.ctrl.rfWen
312    sel.bits.ctrl.fpWen := issQue(deqSelIq).uop.ctrl.fpWen
313  }
314  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, VecInit(redHitVec).asUInt, VecInit(redIdHitVec).asUInt, enqRedHit, selIsRed)
315  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
316    , 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)
317  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)
318  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)
319  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)
320  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)
321  if(useBypass) {
322    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)
323  } else {
324    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)
325  }
326  XSDebug("id|v|r|psrc|r|   src1         |psrc|r|   src2         |psrc|r|   src3         |brMask|    pc    |roqIdx FuType:%x\n", fuTypeInt.U)
327  for (i <- 0 until iqSize) {
328    when (i.U===tail && tailAll=/=8.U) {
329      XSDebug("%d |%d|%d| %d|%b|%x| %d|%b|%x| %d|%b|%x| %x |%x|%x <-\n", idQue(i), idValidQue(i), srcRdy(idQue(i)), psrc(idQue(i))(0), srcRdyVec(idQue(i))(0), srcData(idQue(i))(0), psrc(idQue(i))(1), srcRdyVec(idQue(i))(1), srcData(idQue(i))(1), psrc(idQue(i))(2), srcRdyVec(idQue(i))(2), srcData(idQue(i))(2), issQue(idQue(i)).uop.brMask, issQue(idQue(i)).uop.cf.pc, issQue(idQue(i)).uop.roqIdx)
330    }.otherwise {
331      XSDebug("%d |%d|%d| %d|%b|%x| %d|%b|%x| %d|%b|%x| %x |%x|%x\n", idQue(i), idValidQue(i), srcRdy(idQue(i)), psrc(idQue(i))(0), srcRdyVec(idQue(i))(0), srcData(idQue(i))(0), psrc(idQue(i))(1), srcRdyVec(idQue(i))(1), srcData(idQue(i))(1), psrc(idQue(i))(2), srcRdyVec(idQue(i))(2), srcData(idQue(i))(2), issQue(idQue(i)).uop.brMask, issQue(idQue(i)).uop.cf.pc, issQue(idQue(i)).uop.roqIdx)
332    }
333  }
334}