ReservationStation.scala 20.5 KB
Newer Older
1 2 3 4 5
package xiangshan.backend.issue

import chisel3._
import chisel3.util._
import xiangshan._
L
LinJiawei 已提交
6
import xiangshan.backend.exu.{Exu, ExuConfig}
7
import xiangshan.backend.rename.FreeListPtr
L
LinJiawei 已提交
8
import utils._
L
LinJiawei 已提交
9
import xiangshan.backend.fu.FunctionUnit._
10
import xiangshan.backend.regfile.RfReadPort
L
LinJiawei 已提交
11

12

13
trait HasIQConst extends HasXSParameter{
14
  val iqSize = IssQueSize
15
  val iqIdxWidth = log2Up(iqSize)
J
jinyue 已提交
16 17
}

18 19 20 21 22 23 24 25 26
object OneCycleFire {
  def apply(fire: Bool) = {
    val valid = RegInit(false.B)
    when (valid) { valid := false.B }
    when (fire) { valid := true.B }
    valid
  }
}

27
class ReservationStation
28 29 30 31 32 33 34
(
  val exuCfg: ExuConfig,
  val wakeupCnt: Int,
  val bypassCnt: Int = 0,
  val enableBypass: Boolean = false,
  val fifo: Boolean = false
) extends XSModule with HasIQConst {
35

36
  val src2Use = true
L
LinJiawei 已提交
37
  val src3Use = (exuCfg.intSrcCnt > 2) || (exuCfg.fpSrcCnt > 2)
38
  val src2Listen = true
L
LinJiawei 已提交
39
  val src3Listen = (exuCfg.intSrcCnt > 2) || (exuCfg.fpSrcCnt > 2)
40 41 42 43 44 45 46 47

  val io = IO(new Bundle() {
    // flush Issue Queue
    val redirect = Flipped(ValidIO(new Redirect))

    // enq Ctrl sigs at dispatch-2
    val enqCtrl = Flipped(DecoupledIO(new MicroOp))
    // enq Data at next cycle (regfile has 1 cycle latency)
Y
Yinan Xu 已提交
48
    val enqData = Input(new ExuInput)
49 50

    //  broadcast selected uop to other issue queues which has bypasses
51
    val selectedUop = if(enableBypass) ValidIO(new MicroOp) else null
52 53 54 55 56 57 58 59

    // send to exu
    val deq = DecoupledIO(new ExuInput)

    // listen to write back bus
    val wakeUpPorts = Vec(wakeupCnt, Flipped(ValidIO(new ExuOutput)))

    // use bypass uops to speculative wake-up
60 61
    val bypassUops = Vec(bypassCnt, Flipped(ValidIO(new MicroOp)))
    val bypassData = Vec(bypassCnt, Flipped(ValidIO(new ExuOutput)))
62 63

    // to Dispatch
64
    val numExist = Output(UInt(iqIdxWidth.W))
65 66
  })

67 68 69
  val srcAllNum = 3
  val srcUseNum = 1 + (if(src2Use) 1 else 0) + (if(src3Use) 1 else 0)// when src2Use is false, then src3Use must be false
  val srcListenNum = 1 + (if(src2Listen) 1 else 0) + (if(src3Listen) 1 else 0) // when src2Listen is false, then src3Listen must be false
70 71 72 73 74 75 76
  // when use is false, Listen must be false
  require(!(!src2Use && src2Listen))
  require(!(!src3Use && src3Listen))
  require(!(!src2Use && src3Use))
  require(!(!src2Listen && src3Listen))

  // Issue Queue
Z
ZhangZifei 已提交
77 78 79
  // val issQue = IndexableMem(iqSize, new ExuInput, mem = false, init = None)
  val issQue = Mem(iqSize, new ExuInput)
  // val issQue = Reg(Vec(iqSize, new ExuInput))
80 81
  val validQue = RegInit(VecInit(Seq.fill(iqSize)(false.B)))
  val idQue = RegInit(VecInit((0 until iqSize).map(_.U(iqIdxWidth.W))))
82
  val idValidQue = VecInit((0 until iqSize).map(i => validQue(idQue(i)))).asUInt
83 84 85
  val tailAll = RegInit(0.U((iqIdxWidth+1).W))
  val tail = tailAll(iqIdxWidth-1, 0)
  val full = tailAll(iqIdxWidth)
86

87
  // alias failed, turn to independent storage(Reg)
88
  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
89 90
  val srcRdyVec = Reg(Vec(iqSize, Vec(srcAllNum, Bool()))) // NOTE: indexed by IssQue's idx
  val srcData = Reg(Vec(iqSize, Vec(srcAllNum, UInt(XLEN.W)))) // NOTE: indexed by IssQue's idx
91
  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
92
  val srcIdRdy = VecInit((0 until iqSize).map(i => srcRdy(idQue(i)))).asUInt // NOTE: indexed by IdQue's idx
93
  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
94

Z
ZhangZifei 已提交
95 96 97
  // val srcDataWire = Wire(srcData)
  val srcDataWire = Wire(Vec(iqSize, Vec(srcAllNum, UInt(XLEN.W)))) // NOTE: indexed by IssQue's idx
  srcDataWire := srcData
Z
ZhangZifei 已提交
98 99
  srcData := srcDataWire

100
  // there are three stages
101 102 103
  // |-------------|--------------------|--------------|
  // |Enq:get state|Deq: select/get data| fire stage   |
  // |-------------|--------------------|--------------|
104

105
  //-----------------------------------------
106
  // Enqueue
107
  //-----------------------------------------
108 109
  val enqRedHit = Wire(Bool())
  val enqFire = io.enqCtrl.fire() && !enqRedHit
110 111
  val deqFire = io.deq.fire()
  val popOne = Wire(Bool())
112
  io.enqCtrl.ready := !full || popOne
Y
Yinan Xu 已提交
113
  val enqSelIq = Wire(UInt(iqIdxWidth.W))
114 115 116
  val enqSrcRdy = List(Mux(SrcType.isPcImm(io.enqCtrl.bits.ctrl.src1Type), true.B, io.enqCtrl.bits.src1State === SrcState.rdy),
                       Mux(SrcType.isPcImm(io.enqCtrl.bits.ctrl.src2Type), true.B, io.enqCtrl.bits.src2State === SrcState.rdy),
                       Mux(SrcType.isPcImm(io.enqCtrl.bits.ctrl.src3Type), true.B, io.enqCtrl.bits.src3State === SrcState.rdy))
117

118
  // state enq
119
  when (enqFire) {
120 121 122
    issQue(enqSelIq).uop := io.enqCtrl.bits
    validQue(enqSelIq) := true.B
    assert(!validQue(enqSelIq) || popOne/* && idQue(deqSel)===enqSelIq*/)
123

124 125 126
    srcRdyVec(enqSelIq)(0) := enqSrcRdy(0)
    if(src2Listen) { srcRdyVec(enqSelIq)(1) := enqSrcRdy(1) }
    if(src3Listen) { srcRdyVec(enqSelIq)(2) := enqSrcRdy(2) }
127 128
  }

129
  // data enq
130 131
  val enqSelIqNext = RegEnable(enqSelIq, enqFire)
  // val enqSelIqNext = RegNext(enqSelIq)
132 133 134 135
  val enqFireNext = RegInit(false.B)
  when (enqFireNext) { enqFireNext := false.B }
  when (enqFire) { enqFireNext := true.B }

Y
Yinan Xu 已提交
136
  val enqDataVec = List(io.enqData.src1, io.enqData.src2, io.enqData.src3)
137
  when (enqFireNext) {
138
    for(i <- 0 until srcUseNum) {
139
      srcDataWire(enqSelIqNext)(i) := enqDataVec(i)
140 141 142
    }
  }

143
  //-----------------------------------------
144
  // tail
145
  //-----------------------------------------
146 147
  val tailInc = enqFire
  val tailDec = popOne
148
  val tailKeep = tailInc === tailDec
149 150
  val tailAdd = tailAll + 1.U
  val tailSub = tailAll - 1.U
151
  tailAll := Mux(tailKeep, tailAll, Mux(tailInc, tailAdd, tailSub))
152
  // Select to Dequeue
153
  val deqSel = if (fifo) 0.U else PriorityEncoder(idValidQue & srcIdRdy) //may not need idx, just need oneHot, idx by IdQue's idx
154
  val deqSelIq = idQue(deqSel)
Z
ZhangZifei 已提交
155
  val deqSelOH = PriorityEncoderOH(idValidQue & srcIdRdy)
156
  val has1Rdy = if (fifo) idValidQue(deqSel) && srcIdRdy(deqSel) else ParallelOR((validQue.asUInt & srcRdy.asUInt).asBools).asBool()
157

158
  //-----------------------------------------
159
  // idQue Move
160
  //-----------------------------------------
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
  def UIntToMHP(in: UInt) = {
    // UInt to Multi-Hot plus 1: 1.U -> "11".U; 2.U(2.W) -> "0111".U; 3.U(3.W) -> "00001111".W
    val a = Seq.fill(in.getWidth)(2).product
    val s = (1 << (a-1)).S
    Reverse((s(a-1,0).asSInt >> in)(a-1,0).asUInt)
  }
  def UIntToMH(in: UInt) = {
    val a = Seq.fill(in.getWidth)(2).product
    val s = (1 << (a-1)).S
    Reverse((s(a-1,0).asSInt >> in)(a-1,0).asUInt) ^ UIntToOH(in)
  }
  def PriorityDot(in: UInt) = {
    // "1100".U -> "0111".U; "1010".U -> "0011".U; "0000".U -> "0000".U
    val a = Array.fill(iqSize)(1)
    for(i <- 1 until in.getWidth) {
      a(i) = a(i-1)*2 + 1
    }
    Mux(in===0.U, 0.U(in.getWidth.W), PriorityMux(in, a.map(_.U(in.getWidth.W))))
  }
  val tailDot = Mux(full, VecInit(Seq.fill(iqSize)(true.B)).asUInt, UIntToMHP(tail))
  val tailDot2 = Mux(full, VecInit(Seq.fill(iqSize)(true.B)).asUInt, UIntToMH(tail))
  val selDot = UIntToMHP(deqSel) // FIXIT: PriorityEncoder -> UIntToMHP means long latency
  val nonValid = ~(idValidQue | ~tailDot2)
184
  val popSel = PriorityEncoder(nonValid) // Note: idxed by IDque's index
185 186 187 188
  val popDot = PriorityDot(nonValid)
  val isPop = ParallelOR(nonValid.asBools).asBool()
  val moveDot = Mux(isPop, tailDot ^ popDot, tailDot ^ selDot)

189
  assert(!(popOne&&moveDot(0)))
190 191 192 193
  when (popOne) {
    for(i <- 1 until iqSize) {
      when (moveDot(i)) { idQue(i-1) := idQue(i) }
    }
194
    val ptr_tmp = Mux(full, VecInit(Seq.fill(iqIdxWidth)(true.B)).asUInt, tail)
195
    idQue(ptr_tmp) := idQue(Mux(isPop, popSel, deqSel))
196
  }
197
  assert(ParallelAND(List.tabulate(iqSize)(i => ParallelOR(List.tabulate(iqSize)(j => i.U === idQue(j))))).asBool)
198

Z
ZhangZifei 已提交
199 200 201 202
  //-----------------------------------------
  // Redirect
  //-----------------------------------------
  // redirect enq
Y
Yinan Xu 已提交
203
  enqRedHit := io.redirect.valid && io.enqCtrl.bits.roqIdx.needFlush(io.redirect)
Z
ZhangZifei 已提交
204 205

  // redirect issQue
Y
Yinan Xu 已提交
206
  val redHitVec = List.tabulate(iqSize)(i => issQue(i).uop.roqIdx.needFlush(io.redirect))
207
  for (i <- validQue.indices) {
208
    when (redHitVec(i) && validQue(i)) {
Z
ZhangZifei 已提交
209 210 211 212
      validQue(i) := false.B
    }
  }
  // reditect deq(issToExu)
Y
Yinan Xu 已提交
213
  val redIdHitVec = List.tabulate(iqSize)(i => issQue(idQue(i)).uop.roqIdx.needFlush(io.redirect))
Z
ZhangZifei 已提交
214 215
  val selIsRed = ParallelOR((deqSelOH & VecInit(redIdHitVec).asUInt).asBools).asBool

216
  //-----------------------------------------
217
  // Dequeue (or to Issue Stage)
218
  //-----------------------------------------
219 220
  val issueToExu = Reg(new ExuInput)
  val issueToExuValid = RegInit(false.B)
Y
Yinan Xu 已提交
221
  val deqFlushHit = issueToExu.uop.roqIdx.needFlush(io.redirect)
222
  val deqCanIn = !issueToExuValid || io.deq.ready || deqFlushHit
223
  
224
  val toIssFire = deqCanIn && has1Rdy && !isPop && !selIsRed
225 226 227
  popOne := deqCanIn && (has1Rdy || isPop) // send a empty or valid term to issueStage

  when (toIssFire) {
228
    issueToExu := issQue(deqSelIq)
229
    issueToExuValid := true.B
230
    validQue(deqSelIq) := enqFire && enqSelIq===deqSelIq
231
    assert(validQue(deqSelIq))
232 233 234
    issueToExu.src1 := srcDataWire(deqSelIq)(0)
    if (src2Use) { issueToExu.src2 := srcDataWire(deqSelIq)(1) } else { issueToExu.src2 := DontCare }
    if (src3Use) { issueToExu.src3 := srcDataWire(deqSelIq)(2) } else { issueToExu.src3 := DontCare }
235
  }
236
  when ((deqFire || deqFlushHit) && !toIssFire) {
237 238 239 240 241 242
    issueToExuValid := false.B
  }

  io.deq.valid := issueToExuValid && !deqFlushHit
  io.deq.bits := issueToExu

Y
Yinan Xu 已提交
243 244 245 246 247 248 249 250
  enqSelIq := Mux(full,
    Mux(isPop,
      idQue(popSel),
      deqSelIq
    ),
    idQue(tail)
  ) // Note: direct by IQue's idx, different from deqSel

251
  io.numExist := Mux(tailAll === iqSize.U, (iqSize-1).U, tailAll)
252

253 254 255 256 257 258 259
  //-----------------------------------------
  // Issue with No Delay
  //-----------------------------------------
  // when enq is ready && no other rdy && no pop &&  fireStage is ready && no flush
  // send out directly without store the data
  val enqAlreadyRdy = if(src3Listen) { if(src2Listen) enqSrcRdy(0)&&enqSrcRdy(1)&&enqSrcRdy(2) else enqSrcRdy(0)&&enqSrcRdy(2) } else  { if(src2Listen) enqSrcRdy(0)&&enqSrcRdy(1) else enqSrcRdy(0) }
  val enqALRdyNext = OneCycleFire(enqAlreadyRdy && enqFire)
Y
Yinan Xu 已提交
260
  val enqSendFlushHit = issQue(enqSelIqNext).uop.roqIdx.needFlush(io.redirect)
261
  val enqSendEnable = if(fifo) { RegNext(tailAll===0.U) && enqALRdyNext && (!issueToExuValid || deqFlushHit) && (enqSelIqNext === deqSelIq) && !isPop && !enqSendFlushHit/* && has1Rdy*//* && io.deq.ready*/ } else { enqALRdyNext && (!issueToExuValid || deqFlushHit) && (enqSelIqNext === deqSelIq) && !isPop && !enqSendFlushHit/* && has1Rdy*//* && io.deq.ready*/ } // FIXME: has1Rdy has combination loop
262 263 264 265 266 267 268 269 270 271 272 273
  when (enqSendEnable) {
    io.deq.valid := true.B
    io.deq.bits := issQue(enqSelIqNext)
    io.deq.bits.src1 := enqDataVec(0)
    if (src2Use) { io.deq.bits.src2 := enqDataVec(1) }
    if (src3Use) { io.deq.bits.src3 := enqDataVec(2) }
    issueToExuValid := false.B
    when (!io.deq.ready) { // if Func Unit is not ready, store it to FireStage
      issueToExuValid := true.B
    }
  }

274
  //-----------------------------------------
275
  // Wakeup and Bypass
276
  //-----------------------------------------
277 278 279 280 281
    val cdbValid = io.wakeUpPorts.map(_.valid)
    val cdbData  = io.wakeUpPorts.map(_.bits.data)
    val cdbPdest = io.wakeUpPorts.map(_.bits.uop.pdest)
    val cdbrfWen = io.wakeUpPorts.map(_.bits.uop.ctrl.rfWen)
    val cdbfpWen = io.wakeUpPorts.map(_.bits.uop.ctrl.fpWen)
282

283
    for(i <- idQue.indices) { // Should be IssQue.indices but Mem() does not support
284
      for(j <- 0 until srcListenNum) {
285
        val hitVec = cdbValid.indices.map(k => psrc(i)(j) === cdbPdest(k) && cdbValid(k) && (srcType(i)(j)===SrcType.reg && cdbrfWen(k) && cdbPdest(k) =/= 0.U || srcType(i)(j)===SrcType.fp && cdbfpWen(k)))
286 287 288
        val hit = ParallelOR(hitVec).asBool
        val data = ParallelMux(hitVec zip cdbData)
        when (validQue(i) && !srcRdyVec(i)(j) && hit) { 
Z
ZhangZifei 已提交
289
          srcDataWire(i)(j) := data
290 291
          srcRdyVec(i)(j) := true.B
        }
Z
ZhangZifei 已提交
292
        // 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)
293
        for (k <- cdbValid.indices) {
Y
Yinan Xu 已提交
294 295 296
          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.asUInt)
Z
ZhangZifei 已提交
297
        }
298 299
      }
    }
300
  
301 302 303 304 305
    val bpPdest = io.bypassUops.map(_.bits.pdest)
    val bpValid = io.bypassUops.map(_.valid)
    val bpData  = io.bypassData.map(_.bits.data)
    val bprfWen = io.bypassUops.map(_.bits.ctrl.rfWen)
    val bpfpWen = io.bypassUops.map(_.bits.ctrl.fpWen)
306

307
    for (i <- idQue.indices) { // Should be IssQue.indices but Mem() does not support
308
      for (j <- 0 until srcListenNum) {
309
        val hitVec = bpValid.indices.map(k => psrc(i)(j) === bpPdest(k) && bpValid(k) && (srcType(i)(j)===SrcType.reg && bprfWen(k) && bpPdest(k) =/= 0.U || srcType(i)(j)===SrcType.fp && bpfpWen(k)))
310 311 312
        val hitVecNext = hitVec.map(RegNext(_))
        val hit = ParallelOR(hitVec).asBool
        when (validQue(i) && !srcRdyVec(i)(j) && hit) {
313
          srcRdyVec(i)(j) := true.B
314 315
        }
        when (RegNext(validQue(i) && !srcRdyVec(i)(j) && hit)) {
Z
ZhangZifei 已提交
316
          srcDataWire(i)(j) := PriorityMux(hitVecNext zip bpData)
317
        }
Z
ZhangZifei 已提交
318
        // 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)
319
        for (k <- bpValid.indices) {
Y
Yinan Xu 已提交
320 321 322
          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.asUInt)
Z
ZhangZifei 已提交
323 324
        }
        // 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))
325
        for (k <- bpValid.indices) {
326 327
          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",
Y
Yinan Xu 已提交
328
            i.U, j.U, psrc(i)(j), k.U, bpData(k), io.bypassUops(k).bits.cf.pc, io.bypassUops(k).bits.roqIdx.asUInt)
Z
ZhangZifei 已提交
329
        }
330 331 332 333 334
      }
    }

    // Enqueue Bypass
    val enqCtrl = io.enqCtrl
335
    val enqPsrc = List(enqCtrl.bits.psrc1, enqCtrl.bits.psrc2, enqCtrl.bits.psrc3)
336
    val enqSrcType = List(enqCtrl.bits.ctrl.src1Type, enqCtrl.bits.ctrl.src2Type, enqCtrl.bits.ctrl.src3Type)
337
    for (i <- 0 until srcListenNum) {
338
      val hitVec = bpValid.indices.map(j => enqPsrc(i)===bpPdest(j) && bpValid(j) && (enqSrcType(i)===SrcType.reg && bprfWen(j) && bpPdest(j) =/= 0.U || enqSrcType(i)===SrcType.fp && bpfpWen(j)))
339 340
      val hitVecNext = hitVec.map(RegNext(_))
      val hit = ParallelOR(hitVec).asBool
341
      when (enqFire && hit && !enqSrcRdy(i)) {
342
        srcRdyVec(enqSelIq)(i) := true.B
343
      }
344
      when (RegNext(enqFire && hit && !enqSrcRdy(i))) {
345
        srcDataWire(enqSelIqNext)(i) := ParallelMux(hitVecNext zip bpData)
346
      }
347
      // XSDebug(enqFire && hit, "EnqBypassCtrl: enqSelIq:%d Src:(%d|%d) Hit:%d HitVec:%b \n", enqSelIq, i.U, enqPsrc(i), hit, VecInit(hitVec).asUInt)
348
      for (k <- bpValid.indices) {
Y
Yinan Xu 已提交
349 350 351
        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.asUInt)
Z
ZhangZifei 已提交
352
      }
353
      // 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))
354
      for (k <- bpValid.indices) {
Y
Yinan Xu 已提交
355 356 357
        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.asUInt)
Z
ZhangZifei 已提交
358
      }
359
    }
360 361
  
  if (enableBypass) {
362 363
    // send out bypass
    val sel = io.selectedUop
364
    sel.valid := toIssFire && !enqSendEnable
365
    sel.bits := DontCare
366 367 368 369 370
    sel.bits.pdest := issQue(deqSelIq).uop.pdest
    sel.bits.cf.pc := issQue(deqSelIq).uop.cf.pc
    sel.bits.roqIdx := issQue(deqSelIq).uop.roqIdx
    sel.bits.ctrl.rfWen := issQue(deqSelIq).uop.ctrl.rfWen
    sel.bits.ctrl.fpWen := issQue(deqSelIq).uop.ctrl.fpWen
371
  }
372
  XSInfo(io.redirect.valid, "Redirect: valid:%d isExp:%d isFpp:%d brTag:%d redHitVec:%b redIdHitVec:%b enqHit:%d selIsRed:%d\n", io.redirect.valid, io.redirect.bits.isException, io.redirect.bits.isFlushPipe, io.redirect.bits.brTag.value, VecInit(redHitVec).asUInt, VecInit(redIdHitVec).asUInt, enqRedHit, selIsRed)
Y
Yinan Xu 已提交
373 374 375 376 377 378 379 380 381 382 383 384
  XSInfo(enqFire,
    s"EnqCtrl(%d %d) enqSelIq:%d Psrc/Rdy(%d:%d %d:%d %d:%d) Dest:%d oldDest:%d pc:%x roqIdx:%x\n",
    io.enqCtrl.valid, io.enqCtrl.ready, enqSelIq, 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.asUInt)
  XSInfo(enqFireNext,
    "EnqData: src1:%x src2:%x src3:%x pc:%x roqIdx:%x(for last cycle's Ctrl)\n",
    io.enqData.src1, io.enqData.src2, io.enqData.src3, issQue(enqSelIqNext).uop.cf.pc, issQue(enqSelIqNext).uop.roqIdx.asUInt)
  XSInfo(deqFire,
    "Deq:(%d %d) [%d|%x][%d|%x][%d|%x] pdest:%d pc:%x roqIdx:%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.asUInt)
385
  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)
Y
Yinan Xu 已提交
386 387 388 389
  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.asUInt)
390
  if(enableBypass) {
391
    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)
392
  } else {
393
    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)
394
  }
L
LinJiawei 已提交
395

396
  XSDebug(enqSendEnable, p"NoDelayIss: enqALRdy:${enqAlreadyRdy} *Next:${enqALRdyNext} En:${enqSendEnable} flush:${enqSendFlushHit} enqSelIqNext:${enqSelIqNext} deqSelIq:${deqSelIq} deqReady:${io.deq.ready}\n")
L
LinJiawei 已提交
397 398
  XSDebug(s"id|v|r|psrc|r|   src1         |psrc|r|   src2         |psrc|r|   src3         |brTag|    pc    |roqIdx Exu:${exuCfg.name}\n")

399 400
  for (i <- 0 until iqSize) {
    when (i.U===tail && tailAll=/=8.U) {
L
LinJiawei 已提交
401 402 403 404 405 406 407 408 409 410 411 412 413 414 415
      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.brTag.value,
        issQue(idQue(i)).uop.cf.pc,
Y
Yinan Xu 已提交
416
        issQue(idQue(i)).uop.roqIdx.asUInt
L
LinJiawei 已提交
417
      )
418
    }.otherwise {
L
LinJiawei 已提交
419 420 421 422 423 424 425 426 427 428 429 430 431 432 433
      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.brTag.value,
        issQue(idQue(i)).uop.cf.pc,
Y
Yinan Xu 已提交
434
        issQue(idQue(i)).uop.roqIdx.asUInt
L
LinJiawei 已提交
435
      )
436 437
    }
  }
Y
Yinan Xu 已提交
438 439

  XSPerf("utilization", tailAll)
440
}