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