xref: /XiangShan/src/main/scala/xiangshan/backend/issue/Entries.scala (revision 520f7dac5b854b415f337b9ef9e172a2eca7a9ab)
1package xiangshan.backend.issue
2
3import org.chipsalliance.cde.config.Parameters
4import chisel3._
5import chisel3.util._
6import utility.HasCircularQueuePtrHelper
7import utils.{MathUtils, OptionWrapper, XSError}
8import xiangshan._
9import xiangshan.backend.Bundles._
10import xiangshan.backend.datapath.DataConfig.VAddrData
11import xiangshan.backend.datapath.DataSource
12import xiangshan.backend.fu.FuType
13import xiangshan.backend.fu.vector.Utils.NOnes
14import xiangshan.backend.rob.RobPtr
15import xiangshan.mem.{MemWaitUpdateReq, SqPtr, LqPtr}
16
17class StatusMemPart(implicit p:Parameters, params: IssueBlockParams) extends Bundle {
18  val waitForSqIdx = new SqPtr   // generated by store data valid check
19  val waitForRobIdx = new RobPtr // generated by store set
20  val waitForStd = Bool()
21  val strictWait = Bool()
22  val sqIdx = new SqPtr
23}
24
25class StatusVecMemPart(implicit p:Parameters, params: IssueBlockParams) extends Bundle {
26  val sqIdx = new SqPtr
27  val lqIdx = new LqPtr
28}
29
30class Status(implicit p:Parameters, params: IssueBlockParams) extends XSBundle {
31  val srcState = Vec(params.numRegSrc, SrcState())
32
33  val psrc = Vec(params.numRegSrc, UInt(params.rdPregIdxWidth.W))
34  val srcType = Vec(params.numRegSrc, SrcType())
35  val fuType = FuType()
36  val robIdx = new RobPtr
37  val uopIdx = OptionWrapper(params.isVecMemIQ, UopIdx())
38  val issued = Bool()           // for predict issue
39  val firstIssue = Bool()
40  val blocked = Bool()          // for some block reason
41  // read reg or get data from bypass network
42  val dataSources = Vec(params.numRegSrc, DataSource())
43  // if waked up by iq, set when waked up by iq
44  val srcWakeUpL1ExuOH = OptionWrapper(params.hasIQWakeUp, Vec(params.numRegSrc, ExuOH()))
45  // src timer, used by cancel signal. It increases every cycle after wakeup src inst issued.
46  val srcTimer = OptionWrapper(params.hasIQWakeUp, Vec(params.numRegSrc, UInt(3.W)))
47  val issueTimer = UInt(2.W)
48  val deqPortIdx = UInt(1.W)
49  val srcLoadDependency = OptionWrapper(params.hasIQWakeUp, Vec(params.numRegSrc, Vec(LoadPipelineWidth, UInt(3.W))))
50
51
52  // mem only
53  val mem = if (params.isMemAddrIQ) Some(new StatusMemPart) else None
54
55  // vector mem only
56  val vecMem = if (params.isVecMemIQ) Some(new StatusVecMemPart) else None
57
58  // need pc
59  val pc = if (params.needPc) Some(UInt(VAddrData().dataWidth.W)) else None
60
61  def srcReady: Bool = {
62    VecInit(srcState.map(SrcState.isReady)).asUInt.andR
63  }
64
65  def canIssue: Bool = {
66    srcReady && !issued && !blocked
67  }
68
69  def mergedLoadDependency = {
70    srcLoadDependency.map(_.map(_.toSeq).reduce({
71      case (l: Vec[UInt], r: Vec[UInt]) => VecInit(l.zip(r).map(x => x._1 | x._2))
72    }: (Vec[UInt], Vec[UInt]) => Vec[UInt]))
73  }
74}
75
76class EntryDeqRespBundle(implicit p:Parameters, params: IssueBlockParams) extends Bundle {
77  val robIdx = new RobPtr
78  val uopIdx = UopIdx()
79  val respType = RSFeedbackType()   // update credit if needs replay
80  val dataInvalidSqIdx = new SqPtr
81  val rfWen = Bool()
82  val fuType = FuType()
83}
84
85class EntryBundle(implicit p: Parameters, params: IssueBlockParams) extends XSBundle {
86  val status = new Status()
87  val imm = OptionWrapper(params.needImm, UInt((params.deqImmTypesMaxLen).W))
88  val payload = new DynInst()
89}
90
91class DeqBundle(implicit p:Parameters, params: IssueBlockParams) extends XSBundle {
92  //input
93  val enqEntryOldestSel = Flipped(ValidIO(UInt(params.numEnq.W)))
94  val othersEntryOldestSel = Flipped(ValidIO(UInt((params.numEntries - params.numEnq).W)))
95  val subDeqRequest = OptionWrapper(params.deqFuSame, Input(UInt(params.numEntries.W)))
96  val subDeqSelOH = OptionWrapper(params.deqFuSame, Input(UInt(params.numEntries.W)))
97  val deqReady = Input(Bool())
98  val deqSelOH = Flipped(ValidIO(UInt(params.numEntries.W)))
99  //output
100  val isFirstIssue = Output(Bool())
101  val deqEntry = ValidIO(new EntryBundle)
102}
103
104class EntriesIO(implicit p: Parameters, params: IssueBlockParams) extends XSBundle {
105  val flush = Flipped(ValidIO(new Redirect))
106  // status
107  val valid = Output(UInt(params.numEntries.W))
108  val canIssue = Output(UInt(params.numEntries.W))
109  val clear = Output(UInt(params.numEntries.W))
110  val fuType = Output(Vec(params.numEntries, FuType()))
111  val dataSources = Output(Vec(params.numEntries, Vec(params.numRegSrc, DataSource())))
112  val srcWakeUpL1ExuOH = OptionWrapper(params.hasIQWakeUp, Output(Vec(params.numEntries, Vec(params.numRegSrc, ExuOH()))))
113  val srcTimer = OptionWrapper(params.hasIQWakeUp, Output(Vec(params.numEntries, Vec(params.numRegSrc, UInt(3.W)))))
114  val robIdx = OptionWrapper(params.isVecMemIQ, Output(Vec(params.numEntries, new RobPtr)))
115  val uopIdx = OptionWrapper(params.isVecMemIQ, Output(Vec(params.numEntries, UopIdx())))
116  //enq
117  val enq = Vec(params.numEnq, Flipped(ValidIO(new EntryBundle)))
118  // wakeup
119  val wakeUpFromWB: MixedVec[ValidIO[IssueQueueWBWakeUpBundle]] = Flipped(params.genWBWakeUpSinkValidBundle)
120  val wakeUpFromIQ: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(params.genIQWakeUpSinkValidBundle)
121  val og0Cancel = Input(ExuOH(backendParams.numExu))
122  val og1Cancel = Input(ExuOH(backendParams.numExu))
123  val ldCancel = Vec(backendParams.LduCnt + backendParams.HyuCnt, Flipped(new LoadCancelIO))
124  //deq
125  val deq = Vec(params.numDeq, new DeqBundle)
126  val og0Resp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle)))
127  val og1Resp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle)))
128  val finalIssueResp = OptionWrapper(params.LdExuCnt > 0, Vec(params.LdExuCnt, Flipped(ValidIO(new EntryDeqRespBundle))))
129  val memAddrIssueResp = OptionWrapper(params.LdExuCnt > 0, Vec(params.LdExuCnt, Flipped(ValidIO(new EntryDeqRespBundle))))
130  val transEntryDeqVec = Vec(params.numEnq, ValidIO(new EntryBundle))
131  val transSelVec = Output(Vec(params.numEnq, UInt((params.numEntries-params.numEnq).W)))
132  val cancelDeqVec = Output(Vec(params.numDeq, Bool()))
133
134
135  val rsFeedback = Output(Vec(5, Bool()))
136  // mem only
137  val fromMem = if (params.isMemAddrIQ) Some(new Bundle {
138    val stIssuePtr = Input(new SqPtr)
139    val memWaitUpdateReq = Flipped(new MemWaitUpdateReq)
140    val slowResp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle)))
141    val fastResp = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle)))
142  }) else None
143
144  // vector mem only
145  val fromLsq = OptionWrapper(params.isVecMemIQ, new Bundle {
146    val sqDeqPtr = Input(new SqPtr)
147    val lqDeqPtr = Input(new LqPtr)
148  })
149
150  // debug
151  val cancel = OptionWrapper(params.hasIQWakeUp, Output(Vec(params.numEntries, Bool())))
152
153  def wakeup = wakeUpFromWB ++ wakeUpFromIQ
154}
155
156class Entries(implicit p: Parameters, params: IssueBlockParams) extends XSModule {
157  private val EnqEntryNum = params.numEnq
158  private val OthersEntryNum = params.numEntries - params.numEnq
159  val io = IO(new EntriesIO)
160
161  // only memAddrIQ use it
162  val memEtyResps: MixedVec[ValidIO[EntryDeqRespBundle]] = {
163    if (params.isLdAddrIQ && !params.isStAddrIQ)
164      MixedVecInit(io.og0Resp ++ io.og1Resp ++ io.memAddrIssueResp.get ++ io.finalIssueResp.get)
165    else if (params.isLdAddrIQ && params.isStAddrIQ || params.isHyAddrIQ)
166      MixedVecInit(io.og0Resp ++ io.og1Resp ++ io.memAddrIssueResp.get ++ io.finalIssueResp.get ++ io.fromMem.get.fastResp ++ io.fromMem.get.slowResp)
167    else if (params.isMemAddrIQ)
168      MixedVecInit(io.og0Resp ++ io.og1Resp ++ io.fromMem.get.fastResp ++ io.fromMem.get.slowResp)
169    else MixedVecInit(Seq())
170  }
171
172  val resps: Vec[Vec[ValidIO[EntryDeqRespBundle]]] = VecInit(io.og0Resp, io.og1Resp, 0.U.asTypeOf(io.og0Resp), 0.U.asTypeOf(io.og0Resp))
173
174  //Module
175  val enqEntries = Seq.fill(EnqEntryNum)(Module(EnqEntry(p, params)))
176  val othersEntries = Seq.fill(OthersEntryNum)(Module(OthersEntry(p, params)))
177  val transPolicy = Module(new EnqPolicy)
178
179  //Wire
180  val deqSelVec = Wire(Vec(params.numEntries, Bool()))
181  val transSelVec = Wire(Vec(EnqEntryNum, Vec(OthersEntryNum, Bool())))
182  val issueRespVec = Wire(Vec(params.numEntries, ValidIO(new EntryDeqRespBundle)))
183  val transEntryDeqVec = Wire(Vec(EnqEntryNum, ValidIO(new EntryBundle)))
184  val transEntryEnqVec = Wire(Vec(OthersEntryNum, ValidIO(new EntryBundle)))
185  val entries = Wire(Vec(params.numEntries, ValidIO(new EntryBundle)))
186
187  val validVec = Wire(Vec(params.numEntries, Bool()))
188  val canIssueVec = Wire(Vec(params.numEntries, Bool()))
189  val clearVec = Wire(Vec(params.numEntries, Bool()))
190  val fuTypeVec = Wire(Vec(params.numEntries, FuType()))
191  val dataSourceVec = Wire(Vec(params.numEntries, Vec(params.numRegSrc, DataSource())))
192  val srcWakeUpL1ExuOHVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numEntries, Vec(params.numRegSrc, ExuOH()))))
193  val srcTimerVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numEntries, Vec(params.numRegSrc, UInt(3.W)))))
194  val cancelByOg0Vec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numEntries, Bool())))
195  val isFirstIssueVec = Wire(Vec(params.numEntries, Bool()))
196  val robIdxVec = Wire(Vec(params.numEntries, new RobPtr))
197  val issueTimerVec = Wire(Vec(params.numEntries, UInt(2.W)))
198  val deqPortIdxWriteVec = Wire(Vec(params.numEntries, UInt(1.W)))
199  val deqPortIdxReadVec = Wire(Vec(params.numEntries, UInt(1.W)))
200  val cancelVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numEntries, Bool())))
201  val uopIdxVec = OptionWrapper(params.isVecMemIQ, Wire(Vec(params.numEntries, UopIdx())))
202
203  io.transEntryDeqVec := transEntryDeqVec
204
205  //enqEntries
206  enqEntries.zipWithIndex.foreach { case (enqEntry, entryIdx) =>
207    enqEntry.io.enq := io.enq(entryIdx)
208    enqEntry.io.flush := io.flush
209    enqEntry.io.wakeUpFromWB := io.wakeUpFromWB
210    enqEntry.io.wakeUpFromIQ := io.wakeUpFromIQ
211    enqEntry.io.og0Cancel := io.og0Cancel
212    enqEntry.io.og1Cancel := io.og1Cancel
213    enqEntry.io.ldCancel := io.ldCancel
214    enqEntry.io.enqDelayWakeUpFromWB := RegNext(io.wakeUpFromWB)
215    enqEntry.io.enqDelayWakeUpFromIQ := RegNext(io.wakeUpFromIQ)
216    enqEntry.io.enqDelayOg0Cancel := RegNext(io.og0Cancel)
217    enqEntry.io.enqDelayLdCancel := RegNext(io.ldCancel)
218    enqEntry.io.deqSel := deqSelVec(entryIdx)
219    enqEntry.io.deqPortIdxWrite := deqPortIdxWriteVec(entryIdx)
220    enqEntry.io.transSel := transSelVec(entryIdx).asUInt.orR
221    enqEntry.io.issueResp := issueRespVec(entryIdx)
222    validVec(entryIdx) := enqEntry.io.valid
223    canIssueVec(entryIdx) := enqEntry.io.canIssue
224    clearVec(entryIdx) := enqEntry.io.clear
225    fuTypeVec(entryIdx) := enqEntry.io.fuType
226    dataSourceVec(entryIdx) := enqEntry.io.dataSource
227    robIdxVec(entryIdx) := enqEntry.io.robIdx
228    issueTimerVec(entryIdx) := enqEntry.io.issueTimerRead
229    deqPortIdxReadVec(entryIdx) := enqEntry.io.deqPortIdxRead
230    if (params.hasIQWakeUp) {
231      srcWakeUpL1ExuOHVec.get(entryIdx) := enqEntry.io.srcWakeUpL1ExuOH.get
232      srcTimerVec.get(entryIdx) := enqEntry.io.srcTimer.get
233      cancelVec.get(entryIdx) := enqEntry.io.cancel.get
234    }
235    transEntryDeqVec(entryIdx) := enqEntry.io.transEntry
236    isFirstIssueVec(entryIdx) := enqEntry.io.isFirstIssue
237    entries(entryIdx) := enqEntry.io.entry
238    //for mem
239    if (params.isMemAddrIQ) {
240      enqEntry.io.fromMem.get.stIssuePtr := io.fromMem.get.stIssuePtr
241      enqEntry.io.fromMem.get.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
242    }
243    if (params.isVecMemIQ) {
244      uopIdxVec.get(entryIdx) := enqEntry.io.uopIdx.get
245      enqEntry.io.fromLsq.get.sqDeqPtr := io.fromLsq.get.sqDeqPtr
246      enqEntry.io.fromLsq.get.lqDeqPtr := io.fromLsq.get.lqDeqPtr
247    }
248  }
249  //othersEntries
250  othersEntries.zipWithIndex.foreach { case (othersEntry, entryIdx) =>
251    othersEntry.io.enq := transEntryEnqVec(entryIdx)
252    othersEntry.io.flush := io.flush
253    othersEntry.io.wakeUpFromWB := io.wakeUpFromWB
254    othersEntry.io.wakeUpFromIQ := io.wakeUpFromIQ
255    othersEntry.io.og0Cancel := io.og0Cancel
256    othersEntry.io.og1Cancel := io.og1Cancel
257    othersEntry.io.ldCancel := io.ldCancel
258    othersEntry.io.deqSel := deqSelVec(entryIdx + EnqEntryNum)
259    othersEntry.io.deqPortIdxWrite := deqPortIdxWriteVec(entryIdx + EnqEntryNum)
260    othersEntry.io.transSel := transSelVec.map(x => x(entryIdx)).reduce(_ | _)
261    othersEntry.io.issueResp := issueRespVec(entryIdx + EnqEntryNum)
262    validVec(entryIdx + EnqEntryNum) := othersEntry.io.valid
263    canIssueVec(entryIdx + EnqEntryNum) := othersEntry.io.canIssue
264    clearVec(entryIdx + EnqEntryNum) := othersEntry.io.clear
265    fuTypeVec(entryIdx + EnqEntryNum) := othersEntry.io.fuType
266    dataSourceVec(entryIdx + EnqEntryNum) := othersEntry.io.dataSource
267    robIdxVec(entryIdx + EnqEntryNum) := othersEntry.io.robIdx
268    issueTimerVec(entryIdx + EnqEntryNum) := othersEntry.io.issueTimerRead
269    deqPortIdxReadVec(entryIdx + EnqEntryNum) := othersEntry.io.deqPortIdxRead
270    if (params.hasIQWakeUp) {
271      srcWakeUpL1ExuOHVec.get(entryIdx + EnqEntryNum) := othersEntry.io.srcWakeUpL1ExuOH.get
272      srcTimerVec.get(entryIdx + EnqEntryNum) := othersEntry.io.srcTimer.get
273      cancelVec.get(entryIdx + EnqEntryNum) := othersEntry.io.cancel.get
274    }
275    isFirstIssueVec(entryIdx + EnqEntryNum) := othersEntry.io.isFirstIssue
276    entries(entryIdx + EnqEntryNum) := othersEntry.io.entry
277    //for mem
278    if (params.isMemAddrIQ) {
279      othersEntry.io.fromMem.get.stIssuePtr := io.fromMem.get.stIssuePtr
280      othersEntry.io.fromMem.get.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
281    }
282    if (params.isVecMemIQ) {
283      uopIdxVec.get(entryIdx + EnqEntryNum) := othersEntry.io.uopIdx.get
284      othersEntry.io.fromLsq.get.sqDeqPtr := io.fromLsq.get.sqDeqPtr
285      othersEntry.io.fromLsq.get.lqDeqPtr := io.fromLsq.get.lqDeqPtr
286    }
287  }
288
289
290  deqSelVec.zip(deqPortIdxWriteVec).zipWithIndex.foreach { case ((deqSel, deqPortIdxWrite), i) =>
291    val deqVec = io.deq.map(x => x.deqSelOH.valid && x.deqSelOH.bits(i) && x.deqReady)
292    deqPortIdxWrite := OHToUInt(deqVec)
293    deqSel := deqVec.reduce(_ | _)
294  }
295
296
297  //transPolicy
298  transPolicy.io.valid := VecInit(validVec.slice(EnqEntryNum, params.numEntries)).asUInt
299  transSelVec.zip(transPolicy.io.enqSelOHVec).foreach { case (selBools, selOH) =>
300    selBools.zipWithIndex.foreach { case (selBool, i) =>
301      selBool := transPolicy.io.enqSelOHVec.map(_.valid).reduce(_ & _) && selOH.bits(i)
302    }
303  }
304
305  //transEntryEnq
306  transEntryEnqVec.zipWithIndex.foreach { case (transEntryEnq, othersIdx) =>
307    val transEnqHit = transSelVec.map(x => x(othersIdx))
308    transEntryEnq := Mux1H(transEnqHit, transEntryDeqVec)
309  }
310  if(backendParams.debugEn) {
311    dontTouch(transEntryEnqVec)
312  }
313
314  //issueRespVec
315  if (params.isVecMemIQ) {
316    // vector memory IQ
317    issueRespVec.zip(robIdxVec).zip(uopIdxVec.get).foreach { case ((issueResp, robIdx), uopIdx) =>
318      val hitRespsVec = VecInit(resps.flatten.map(x =>
319        x.valid && x.bits.robIdx === robIdx && x.bits.uopIdx === uopIdx
320      ))
321      issueResp.valid := hitRespsVec.reduce(_ | _)
322      issueResp.bits := Mux1H(hitRespsVec, resps.flatten.map(_.bits))
323    }
324  } else if (params.isMemAddrIQ) {
325    // scalar memory IQ
326    issueRespVec.zip(robIdxVec).foreach { case (issueResp, robIdx) =>
327      val hitRespsVec = VecInit(memEtyResps.map(x => x.valid && (x.bits.robIdx === robIdx)).toSeq)
328      issueResp.valid := hitRespsVec.reduce(_ | _)
329      issueResp.bits := Mux1H(hitRespsVec, memEtyResps.map(_.bits).toSeq)
330    }
331  }
332  else {
333    issueRespVec.zip(issueTimerVec).zip(deqPortIdxReadVec).foreach { case ((issueResp, issueTimer), deqPortIdx) =>
334      val Resp = resps(issueTimer)(deqPortIdx)
335      issueResp := Resp
336    }
337  }
338
339  //deq
340  val enqEntryOldest = io.deq.map { deq =>
341    Mux1H(deq.enqEntryOldestSel.bits, entries.take(EnqEntryNum))
342  }
343  val enqEntryOldestCancel = io.deq.map { deq =>
344    Mux1H(deq.enqEntryOldestSel.bits, cancelByOg0Vec.getOrElse(VecInit(Seq.fill(params.numEntries)(false.B))).take(EnqEntryNum))
345  }
346  val othersEntryOldest = io.deq.map { deq =>
347    Mux1H(deq.othersEntryOldestSel.bits, entries.drop(EnqEntryNum))
348  }
349  val othersEntryOldestCancel = io.deq.map { deq =>
350    Mux1H(deq.othersEntryOldestSel.bits, cancelByOg0Vec.getOrElse(VecInit(Seq.fill(params.numEntries)(false.B))).drop(EnqEntryNum))
351  }
352
353  if (params.deqFuSame) {
354    val subDeqPolicyEntryVec = Wire(Vec(params.numDeq, ValidIO(new EntryBundle)))
355    val subDeqPolicyValidVec = Wire(Vec(params.numDeq, Bool()))
356    val subDeqPolicyCancelByOg0Vec = Wire(Vec(params.numDeq, Bool()))
357
358    subDeqPolicyEntryVec(0) := PriorityMux(io.deq(0).subDeqRequest.get, entries)
359    subDeqPolicyEntryVec(1) := PriorityMux(Reverse(io.deq(0).subDeqRequest.get), entries.reverse)
360    subDeqPolicyValidVec(0) := PopCount(io.deq(0).subDeqRequest.get) >= 1.U
361    subDeqPolicyValidVec(1) := PopCount(io.deq(0).subDeqRequest.get) >= 2.U
362    subDeqPolicyCancelByOg0Vec(0) := PriorityMux(io.deq(0).subDeqRequest.get, cancelByOg0Vec.getOrElse(VecInit(Seq.fill(params.numEntries)(false.B))))
363    subDeqPolicyCancelByOg0Vec(1) := PriorityMux(Reverse(io.deq(0).subDeqRequest.get), cancelByOg0Vec.getOrElse(VecInit(Seq.fill(params.numEntries)(false.B))).reverse)
364
365    io.deq(0).deqEntry := Mux(io.deq(0).othersEntryOldestSel.valid, othersEntryOldest(0), subDeqPolicyEntryVec(1))
366    io.deq(1).deqEntry := subDeqPolicyEntryVec(0)
367    io.cancelDeqVec(0) := Mux(io.deq(0).othersEntryOldestSel.valid, othersEntryOldestCancel(0), subDeqPolicyCancelByOg0Vec(1))
368    io.cancelDeqVec(1) := subDeqPolicyCancelByOg0Vec(0)
369
370    when (subDeqPolicyValidVec(0)) {
371      assert(Mux1H(io.deq(0).subDeqSelOH.get, entries).bits.status.robIdx === subDeqPolicyEntryVec(0).bits.status.robIdx, "subDeqSelOH(0) is not the same\n")
372    }
373    when (subDeqPolicyValidVec(1)) {
374      assert(Mux1H(io.deq(1).subDeqSelOH.get, entries).bits.status.robIdx === subDeqPolicyEntryVec(1).bits.status.robIdx, "subDeqSelOH(1) is not the same\n")
375    }
376  }
377  else {
378    io.deq.zipWithIndex.foreach { case (x, i) =>
379      x.deqEntry := Mux(io.deq(i).othersEntryOldestSel.valid, othersEntryOldest(i), enqEntryOldest(i))
380      io.cancelDeqVec(i) := Mux(io.deq(i).othersEntryOldestSel.valid, othersEntryOldestCancel(i), enqEntryOldestCancel(i))
381    }
382  }
383
384  if (params.hasIQWakeUp) {
385    cancelByOg0Vec.get.zip(srcWakeUpL1ExuOHVec.get).zip(srcTimerVec.get).foreach{ case ((cancelByOg0: Bool, l1ExuOH: Vec[UInt]), srcTimer: Vec[UInt]) =>
386      cancelByOg0 := l1ExuOH.zip(srcTimer).map {
387        case(exuOH, srcTimer) =>
388          (exuOH.asUInt & io.og0Cancel.asUInt).orR && srcTimer === 1.U
389      }.reduce(_ | _)
390    }
391  }
392
393  io.valid := validVec.asUInt
394  io.canIssue := canIssueVec.asUInt
395  io.clear := clearVec.asUInt
396  io.fuType := fuTypeVec
397  io.dataSources := dataSourceVec
398  io.srcWakeUpL1ExuOH.foreach(_ := srcWakeUpL1ExuOHVec.get)
399  io.srcTimer.foreach(_ := srcTimerVec.get)
400  io.cancel.foreach(_ := cancelVec.get)
401  io.robIdx.foreach(_ := robIdxVec)
402  io.uopIdx.foreach(_ := uopIdxVec.get)
403  io.rsFeedback := 0.U.asTypeOf(io.rsFeedback) //todo
404  io.deq.foreach{ x =>
405    x.isFirstIssue := x.deqSelOH.valid && Mux1H(x.deqSelOH.bits, isFirstIssueVec)
406  }
407  if(backendParams.debugEn) {
408    dontTouch(io.deq)
409  }
410  io.transSelVec.zip(transSelVec).foreach { case (sink, source) =>
411    sink := source.asUInt
412  }
413}
414