xref: /XiangShan/src/main/scala/xiangshan/backend/issue/Entries.scala (revision eea4a3cafcbfc8f96402eef630721ce0829c7251)
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.{LqPtr, MemWaitUpdateReq, SqPtr}
16import xiangshan.backend.issue.EntryBundles._
17
18class Entries(implicit p: Parameters, params: IssueBlockParams) extends XSModule {
19  override def desiredName: String = params.getEntryName
20
21  require(params.numEnq <= 2, "number of enq should be no more than 2")
22
23  private val EnqEntryNum         = params.numEnq
24  private val OthersEntryNum      = params.numEntries - params.numEnq
25  private val SimpEntryNum        = params.numSimp
26  private val CompEntryNum        = params.numComp
27  val io = IO(new EntriesIO)
28
29  // only memAddrIQ use it
30  val memEtyResps: MixedVec[ValidIO[EntryDeqRespBundle]] = {
31    if (params.isLdAddrIQ && !params.isStAddrIQ)
32      MixedVecInit(io.og0Resp ++ io.og1Resp ++ io.finalIssueResp.get)
33    else if (params.isLdAddrIQ && params.isStAddrIQ || params.isHyAddrIQ)
34      MixedVecInit(io.og0Resp ++ io.og1Resp ++ io.finalIssueResp.get ++ io.fromMem.get.fastResp ++ io.fromMem.get.slowResp)
35    else if (params.isMemAddrIQ)
36      MixedVecInit(io.og0Resp ++ io.og1Resp ++ io.fromMem.get.fastResp ++ io.fromMem.get.slowResp)
37    else MixedVecInit(Seq())
38  }
39
40  val resps: Vec[Vec[ValidIO[EntryDeqRespBundle]]] = VecInit(io.og0Resp, io.og1Resp, 0.U.asTypeOf(io.og0Resp), 0.U.asTypeOf(io.og0Resp))
41
42  //Module
43  val enqEntries          = Seq.fill(EnqEntryNum)(Module(EnqEntry(isComp = true)(p, params)))
44  val othersEntriesSimp   = Seq.fill(SimpEntryNum)(Module(OthersEntry(isComp = false)(p, params)))
45  val othersEntriesComp   = Seq.fill(CompEntryNum)(Module(OthersEntry(isComp = true)(p, params)))
46  val othersEntries       = othersEntriesSimp ++ othersEntriesComp
47  val othersTransPolicy   = OptionWrapper(params.isAllComp || params.isAllSimp, Module(new EnqPolicy))
48  val simpTransPolicy     = OptionWrapper(params.hasCompAndSimp, Module(new EnqPolicy))
49  val compTransPolicy     = OptionWrapper(params.hasCompAndSimp, Module(new EnqPolicy))
50
51  //Wire
52  //entries status
53  val entries             = Wire(Vec(params.numEntries, ValidIO(new EntryBundle)))
54  val robIdxVec           = Wire(Vec(params.numEntries, new RobPtr))
55  val validVec            = Wire(Vec(params.numEntries, Bool()))
56  val canIssueVec         = Wire(Vec(params.numEntries, Bool()))
57  val fuTypeVec           = Wire(Vec(params.numEntries, FuType()))
58  val isFirstIssueVec     = Wire(Vec(params.numEntries, Bool()))
59  val issueTimerVec       = Wire(Vec(params.numEntries, UInt(2.W)))
60  //src status
61  val dataSourceVec       = Wire(Vec(params.numEntries, Vec(params.numRegSrc, DataSource())))
62  val loadDependencyVec   = Wire(Vec(params.numEntries, Vec(LoadPipelineWidth, UInt(3.W))))
63  val srcLoadDependencyVec= Wire(Vec(params.numEntries, Vec(params.numRegSrc, Vec(LoadPipelineWidth, UInt(3.W)))))
64  val srcTimerVec         = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numEntries, Vec(params.numRegSrc, UInt(3.W)))))
65  val srcWakeUpL1ExuOHVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numEntries, Vec(params.numRegSrc, ExuVec()))))
66  //deq sel
67  val deqSelVec           = Wire(Vec(params.numEntries, Bool()))
68  val issueRespVec        = Wire(Vec(params.numEntries, ValidIO(new EntryDeqRespBundle)))
69  val deqPortIdxWriteVec  = Wire(Vec(params.numEntries, UInt(1.W)))
70  val deqPortIdxReadVec   = Wire(Vec(params.numEntries, UInt(1.W)))
71  //trans sel
72  val othersEntryEnqReadyVec = Wire(Vec(OthersEntryNum, Bool()))
73  val othersEntryEnqVec      = Wire(Vec(OthersEntryNum, Valid(new EntryBundle)))
74  val enqEntryTransVec       = Wire(Vec(EnqEntryNum, Valid(new EntryBundle)))
75  val simpEntryTransVec      = OptionWrapper(params.hasCompAndSimp, Wire(Vec(SimpEntryNum, Valid(new EntryBundle))))
76  val compEnqVec             = OptionWrapper(params.hasCompAndSimp, Wire(Vec(EnqEntryNum, Valid(new EntryBundle))))
77
78  val enqCanTrans2Simp       = OptionWrapper(params.hasCompAndSimp, Wire(Bool()))
79  val enqCanTrans2Comp       = OptionWrapper(params.hasCompAndSimp, Wire(Bool()))
80  val simpCanTrans2Comp      = OptionWrapper(params.hasCompAndSimp, Wire(Vec(EnqEntryNum, Bool())))
81  val simpTransSelVec        = OptionWrapper(params.hasCompAndSimp, Wire(Vec(EnqEntryNum, Valid(UInt(SimpEntryNum.W)))))
82  val compTransSelVec        = OptionWrapper(params.hasCompAndSimp, Wire(Vec(EnqEntryNum, Valid(UInt(CompEntryNum.W)))))
83  val finalSimpTransSelVec   = OptionWrapper(params.hasCompAndSimp, Wire(Vec(EnqEntryNum, UInt(SimpEntryNum.W))))
84  val finalCompTransSelVec   = OptionWrapper(params.hasCompAndSimp, Wire(Vec(EnqEntryNum, UInt(CompEntryNum.W))))
85
86  val enqCanTrans2Others     = OptionWrapper(params.isAllComp || params.isAllSimp, Wire(Bool()))
87  val othersTransSelVec      = OptionWrapper(params.isAllComp || params.isAllSimp, Wire(Vec(EnqEntryNum, Valid(UInt(OthersEntryNum.W)))))
88  val finalOthersTransSelVec = OptionWrapper(params.isAllComp || params.isAllSimp, Wire(Vec(EnqEntryNum, UInt(OthersEntryNum.W))))
89
90  val simpEntryEnqReadyVec   = othersEntryEnqReadyVec.take(SimpEntryNum)
91  val compEntryEnqReadyVec   = othersEntryEnqReadyVec.takeRight(CompEntryNum)
92  val simpEntryEnqVec        = othersEntryEnqVec.take(SimpEntryNum)
93  val compEntryEnqVec        = othersEntryEnqVec.takeRight(CompEntryNum)
94  //debug
95  val cancelVec              = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numEntries, Bool())))
96  //cancel bypass
97  val cancelBypassVec        = Wire(Vec(params.numEntries, Bool()))
98  val uopIdxVec              = OptionWrapper(params.isVecMemIQ, Wire(Vec(params.numEntries, UopIdx())))
99
100
101  //enqEntries
102  enqEntries.zipWithIndex.foreach { case (enqEntry, entryIdx) =>
103    enqEntry.io.commonIn.enq                  := io.enq(entryIdx)
104    enqEntry.io.commonIn.transSel             := (if (params.isAllComp || params.isAllSimp) enqCanTrans2Others.get && othersTransSelVec.get(entryIdx).valid
105                                                  else enqCanTrans2Simp.get && simpTransSelVec.get(entryIdx).valid || enqCanTrans2Comp.get && compTransSelVec.get(entryIdx).valid)
106    EntriesConnect(enqEntry.io.commonIn, enqEntry.io.commonOut, entryIdx)
107    enqEntry.io.enqDelayWakeUpFromWB          := RegNext(io.wakeUpFromWB)
108    enqEntry.io.enqDelayWakeUpFromIQ          := RegNext(io.wakeUpFromIQ)
109    enqEntry.io.enqDelayOg0Cancel             := RegNext(io.og0Cancel.asUInt)
110    enqEntry.io.enqDelayLdCancel              := RegNext(io.ldCancel)
111    enqEntryTransVec(entryIdx)                := enqEntry.io.commonOut.transEntry
112    // TODO: move it into EntriesConnect
113    if (params.isVecMemIQ) {
114      enqEntry.io.commonIn.fromLsq.get.sqDeqPtr := io.vecMemIn.get.sqDeqPtr
115      enqEntry.io.commonIn.fromLsq.get.lqDeqPtr := io.vecMemIn.get.lqDeqPtr
116    }
117  }
118  //othersEntries
119  othersEntries.zipWithIndex.foreach { case (othersEntry, entryIdx) =>
120    othersEntry.io.commonIn.enq               := othersEntryEnqVec(entryIdx)
121    othersEntry.io.commonIn.transSel          := (if (params.hasCompAndSimp && (entryIdx < SimpEntryNum))
122                                                    io.simpEntryDeqSelVec.get.zip(simpCanTrans2Comp.get).map(x => x._1(entryIdx) && x._2).reduce(_ | _)
123                                                  else false.B)
124    EntriesConnect(othersEntry.io.commonIn, othersEntry.io.commonOut, entryIdx + EnqEntryNum)
125    othersEntryEnqReadyVec(entryIdx)          := othersEntry.io.commonOut.enqReady
126    if (params.hasCompAndSimp && (entryIdx < SimpEntryNum)) {
127      simpEntryTransVec.get(entryIdx)         := othersEntry.io.commonOut.transEntry
128    }
129    if (params.isVecMemIQ) {
130      othersEntry.io.commonIn.fromLsq.get.sqDeqPtr := io.vecMemIn.get.sqDeqPtr
131      othersEntry.io.commonIn.fromLsq.get.lqDeqPtr := io.vecMemIn.get.lqDeqPtr
132    }
133  }
134
135
136  deqSelVec.zip(deqPortIdxWriteVec).zipWithIndex.foreach { case ((deqSel, deqPortIdxWrite), i) =>
137    val deqVec = io.deqSelOH.zip(io.deqReady).map(x => x._1.valid && x._1.bits(i) && x._2)
138    deqPortIdxWrite := OHToUInt(deqVec)
139    deqSel := deqVec.reduce(_ | _)
140  }
141
142
143  if (params.isAllComp || params.isAllSimp) {
144    //transPolicy
145    othersTransPolicy.get.io.canEnq := othersEntryEnqReadyVec.asUInt
146    enqCanTrans2Others.get := PopCount(validVec.take(EnqEntryNum)) <= PopCount(othersEntryEnqReadyVec)
147    othersTransSelVec.get(0).valid := othersTransPolicy.get.io.enqSelOHVec(0).valid && validVec(0)
148    othersTransSelVec.get(0).bits  := othersTransPolicy.get.io.enqSelOHVec(0).bits
149    // Todo: comments why enqTransSelVec(1).valid relies on validVec(0)
150  if (params.numEnq == 2) {
151    othersTransSelVec.get(1).valid := Mux(!validVec(0), othersTransPolicy.get.io.enqSelOHVec(0).valid, othersTransPolicy.get.io.enqSelOHVec(1).valid)
152      othersTransSelVec.get(1).bits  := Mux(!validVec(0), othersTransPolicy.get.io.enqSelOHVec(0).bits,  othersTransPolicy.get.io.enqSelOHVec(1).bits)
153    }
154
155    finalOthersTransSelVec.get.zip(othersTransSelVec.get).zipWithIndex.foreach { case ((finalOH, selOH), enqIdx) =>
156      finalOH := Fill(OthersEntryNum, enqCanTrans2Others.get && selOH.valid) & selOH.bits
157    }
158
159    //othersEntryEnq
160    othersEntryEnqVec.zipWithIndex.foreach { case (othersEntryEnq, othersIdx) =>
161      val othersEnqOH = finalOthersTransSelVec.get.map(_(othersIdx))
162      if (othersEnqOH.size == 1)
163        othersEntryEnq := Mux(othersEnqOH.head, enqEntryTransVec.head, 0.U.asTypeOf(enqEntryTransVec.head))
164      else
165        othersEntryEnq := Mux1H(othersEnqOH, enqEntryTransVec)
166    }
167  }
168  else {
169    //transPolicy
170    simpTransPolicy.get.io.canEnq := VecInit(simpEntryEnqReadyVec).asUInt
171    compTransPolicy.get.io.canEnq := VecInit(validVec.takeRight(CompEntryNum).map(!_)).asUInt
172
173    enqCanTrans2Comp.get := PopCount(validVec.take(EnqEntryNum)) <= PopCount(validVec.takeRight(CompEntryNum).map(!_)) && !validVec.drop(EnqEntryNum).take(SimpEntryNum).reduce(_ || _)
174    enqCanTrans2Simp.get := !enqCanTrans2Comp.get && PopCount(validVec.take(EnqEntryNum)) <= PopCount(simpEntryEnqReadyVec)
175    simpCanTrans2Comp.get.zipWithIndex.foreach { case (canTrans, idx) =>
176      canTrans := !enqCanTrans2Comp.get && PopCount(validVec.takeRight(CompEntryNum).map(!_)) >= (idx + 1).U
177    }
178
179    simpTransSelVec.get(0).valid := simpTransPolicy.get.io.enqSelOHVec(0).valid && validVec(0)
180    simpTransSelVec.get(0).bits  := simpTransPolicy.get.io.enqSelOHVec(0).bits
181    compTransSelVec.get(0).valid := compTransPolicy.get.io.enqSelOHVec(0).valid && validVec(0)
182    compTransSelVec.get(0).bits  := compTransPolicy.get.io.enqSelOHVec(0).bits
183    if (params.numEnq == 2) {
184      simpTransSelVec.get(1).valid := Mux(!validVec(0), simpTransPolicy.get.io.enqSelOHVec(0).valid, simpTransPolicy.get.io.enqSelOHVec(1).valid)
185      simpTransSelVec.get(1).bits  := Mux(!validVec(0), simpTransPolicy.get.io.enqSelOHVec(0).bits,  simpTransPolicy.get.io.enqSelOHVec(1).bits)
186      compTransSelVec.get(1).valid := Mux(!validVec(0), compTransPolicy.get.io.enqSelOHVec(0).valid, compTransPolicy.get.io.enqSelOHVec(1).valid)
187      compTransSelVec.get(1).bits  := Mux(!validVec(0), compTransPolicy.get.io.enqSelOHVec(0).bits,  compTransPolicy.get.io.enqSelOHVec(1).bits)
188    }
189
190    finalSimpTransSelVec.get.zip(simpTransSelVec.get).zipWithIndex.foreach { case ((finalOH, selOH), enqIdx) =>
191      finalOH := Fill(SimpEntryNum, enqCanTrans2Simp.get && selOH.valid) & selOH.bits
192    }
193    finalCompTransSelVec.get.zip(compTransSelVec.get).zip(compTransPolicy.get.io.enqSelOHVec).zipWithIndex.foreach {
194      case (((finalOH, selOH), origSelOH), enqIdx) =>
195        finalOH := Mux(enqCanTrans2Comp.get, Fill(CompEntryNum, selOH.valid) & selOH.bits, Fill(CompEntryNum, origSelOH.valid) & origSelOH.bits)
196    }
197
198    //othersEntryEnq
199    simpEntryEnqVec.zipWithIndex.foreach { case (simpEntryEnq, simpIdx) =>
200      val simpEnqOH = finalSimpTransSelVec.get.map(_(simpIdx))
201      // shit Mux1H directly returns in(0) if the seq has only 1 elements
202      if (simpEnqOH.size == 1)
203        simpEntryEnq := Mux(simpEnqOH.head, enqEntryTransVec.head, 0.U.asTypeOf(enqEntryTransVec.head))
204      else
205        simpEntryEnq := Mux1H(simpEnqOH, enqEntryTransVec)
206    }
207
208    compEnqVec.get.zip(enqEntryTransVec).zip(io.simpEntryDeqSelVec.get).foreach { case ((compEnq, enqEntry), deqSel) =>
209      compEnq := Mux(enqCanTrans2Comp.get, enqEntry, Mux1H(deqSel, simpEntryTransVec.get))
210    }
211    compEntryEnqVec.zipWithIndex.foreach { case (compEntryEnq, compIdx) =>
212      val compEnqOH = finalCompTransSelVec.get.map(_(compIdx))
213      // shit Mux1H directly returns in(0) if the seq has only 1 elements
214      if (compEnqOH.size == 1)
215        compEntryEnq := Mux(compEnqOH.head, compEnqVec.get.head, 0.U.asTypeOf(compEnqVec.get.head))
216      else
217        compEntryEnq := Mux1H(compEnqOH, compEnqVec.get)
218    }
219
220    assert(PopCount(simpEntryEnqVec.map(_.valid)) <= params.numEnq.U, "the number of simpEntryEnq is more than numEnq\n")
221    assert(PopCount(compEntryEnqVec.map(_.valid)) <= params.numEnq.U, "the number of compEntryEnq is more than numEnq\n")
222  }
223
224  if(backendParams.debugEn) {
225    dontTouch(othersEntryEnqVec)
226  }
227
228  //issueRespVec
229  if (params.isVecMemIQ) {
230    // vector memory IQ
231    issueRespVec.zip(robIdxVec).zip(uopIdxVec.get).foreach { case ((issueResp, robIdx), uopIdx) =>
232      val hitRespsVec = VecInit(resps.flatten.map(x =>
233        x.valid && x.bits.robIdx === robIdx && x.bits.uopIdx.get === uopIdx
234      ))
235      issueResp.valid := hitRespsVec.reduce(_ | _)
236      issueResp.bits := Mux1H(hitRespsVec, resps.flatten.map(_.bits))
237    }
238  } else if (params.isMemAddrIQ) {
239    // scalar memory IQ
240    issueRespVec.zip(robIdxVec).foreach { case (issueResp, robIdx) =>
241      val hitRespsVec = VecInit(memEtyResps.map(x => x.valid && (x.bits.robIdx === robIdx)).toSeq)
242      issueResp.valid := hitRespsVec.reduce(_ | _)
243      issueResp.bits := Mux1H(hitRespsVec, memEtyResps.map(_.bits).toSeq)
244    }
245  }
246  else {
247    issueRespVec.zip(issueTimerVec).zip(deqPortIdxReadVec).foreach { case ((issueResp, issueTimer), deqPortIdx) =>
248      val Resp = resps(issueTimer)(deqPortIdx)
249      issueResp := Resp
250    }
251  }
252
253  //deq
254  val enqEntryOldest          = Wire(Vec(params.numDeq, ValidIO(new EntryBundle)))
255  val simpEntryOldest         = OptionWrapper(params.hasCompAndSimp, Wire(Vec(params.numDeq, ValidIO(new EntryBundle))))
256  val compEntryOldest         = OptionWrapper(params.hasCompAndSimp, Wire(Vec(params.numDeq, ValidIO(new EntryBundle))))
257  val othersEntryOldest       = OptionWrapper(params.isAllComp || params.isAllSimp, Wire(Vec(params.numDeq, ValidIO(new EntryBundle))))
258  val enqEntryOldestCancel    = Wire(Vec(params.numDeq, Bool()))
259  val simpEntryOldestCancel   = OptionWrapper(params.hasCompAndSimp, Wire(Vec(params.numDeq, Bool())))
260  val compEntryOldestCancel   = OptionWrapper(params.hasCompAndSimp, Wire(Vec(params.numDeq, Bool())))
261  val othersEntryOldestCancel = OptionWrapper(params.isAllComp || params.isAllSimp, Wire(Vec(params.numDeq, Bool())))
262
263  io.enqEntryOldestSel.zipWithIndex.map { case (sel, deqIdx) =>
264    enqEntryOldest(deqIdx) := Mux1H(sel.bits, entries.take(EnqEntryNum))
265    enqEntryOldestCancel(deqIdx) := Mux1H(sel.bits, cancelBypassVec.take(EnqEntryNum))
266  }
267
268  if (params.isAllComp || params.isAllSimp) {
269    io.othersEntryOldestSel.get.zipWithIndex.map { case (sel, deqIdx) =>
270      othersEntryOldest.get(deqIdx) := Mux1H(sel.bits, entries.drop(EnqEntryNum))
271      othersEntryOldestCancel.get(deqIdx) := Mux1H(sel.bits, cancelBypassVec.drop(EnqEntryNum))
272    }
273  }
274  else {
275    io.simpEntryOldestSel.get.zipWithIndex.map { case (sel, deqIdx) =>
276      simpEntryOldest.get(deqIdx) := Mux1H(sel.bits, entries.drop(EnqEntryNum).take(SimpEntryNum))
277      simpEntryOldestCancel.get(deqIdx) := Mux1H(sel.bits, cancelBypassVec.drop(EnqEntryNum).take(SimpEntryNum))
278    }
279    io.compEntryOldestSel.get.zipWithIndex.map { case (sel, deqIdx) =>
280      compEntryOldest.get(deqIdx) := Mux1H(sel.bits, entries.drop(EnqEntryNum).takeRight(CompEntryNum))
281      compEntryOldestCancel.get(deqIdx) := Mux1H(sel.bits, cancelBypassVec.drop(EnqEntryNum).takeRight(CompEntryNum))
282    }
283  }
284
285  if (params.deqFuSame) {
286    val subDeqPolicyEntryVec = Wire(Vec(params.numDeq, ValidIO(new EntryBundle)))
287    val subDeqPolicyValidVec = Wire(Vec(params.numDeq, Bool()))
288    val subDeqPolicyCancelBypassVec = Wire(Vec(params.numDeq, Bool()))
289
290    subDeqPolicyValidVec(0) := PopCount(io.subDeqRequest.get(0)) >= 1.U
291    subDeqPolicyValidVec(1) := PopCount(io.subDeqRequest.get(0)) >= 2.U
292
293    if (params.isAllComp || params.isAllSimp) {
294      subDeqPolicyEntryVec(0) := PriorityMux(io.subDeqRequest.get(0), entries)
295      subDeqPolicyEntryVec(1) := PriorityMux(Reverse(io.subDeqRequest.get(0)), entries.reverse)
296      subDeqPolicyCancelBypassVec(0) := PriorityMux(io.subDeqRequest.get(0), cancelBypassVec)
297      subDeqPolicyCancelBypassVec(1) := PriorityMux(Reverse(io.subDeqRequest.get(0)), cancelBypassVec.reverse)
298
299      io.deqEntry(0) := Mux(io.othersEntryOldestSel.get(0).valid, othersEntryOldest.get(0), subDeqPolicyEntryVec(1))
300      io.deqEntry(1) := subDeqPolicyEntryVec(0)
301      io.cancelDeqVec(0) := Mux(io.othersEntryOldestSel.get(0).valid, othersEntryOldestCancel.get(0), subDeqPolicyCancelBypassVec(1))
302      io.cancelDeqVec(1) := subDeqPolicyCancelBypassVec(0)
303    }
304    else {
305      subDeqPolicyEntryVec(0) := PriorityMux(Reverse(io.subDeqRequest.get(0)), entries.reverse)
306      subDeqPolicyEntryVec(1) := PriorityMux(io.subDeqRequest.get(0), entries)
307      subDeqPolicyCancelBypassVec(0) := PriorityMux(Reverse(io.subDeqRequest.get(0)), cancelBypassVec.reverse)
308      subDeqPolicyCancelBypassVec(1) := PriorityMux(io.subDeqRequest.get(0), cancelBypassVec)
309
310      io.deqEntry(0) := Mux(io.compEntryOldestSel.get(0).valid,
311                            compEntryOldest.get(0),
312                            Mux(io.simpEntryOldestSel.get(0).valid, simpEntryOldest.get(0), subDeqPolicyEntryVec(1)))
313      io.deqEntry(1) := subDeqPolicyEntryVec(0)
314      io.cancelDeqVec(0) := Mux(io.compEntryOldestSel.get(0).valid,
315                                compEntryOldestCancel.get(0),
316                                Mux(io.simpEntryOldestSel.get(0).valid, simpEntryOldestCancel.get(0), subDeqPolicyCancelBypassVec(1)))
317      io.cancelDeqVec(1) := subDeqPolicyCancelBypassVec(0)
318    }
319
320    when (subDeqPolicyValidVec(0)) {
321      assert(Mux1H(io.subDeqSelOH.get(0), entries).bits.status.robIdx === subDeqPolicyEntryVec(0).bits.status.robIdx, "subDeqSelOH(0) is not the same\n")
322    }
323    when (subDeqPolicyValidVec(1)) {
324      assert(Mux1H(io.subDeqSelOH.get(1), entries).bits.status.robIdx === subDeqPolicyEntryVec(1).bits.status.robIdx, "subDeqSelOH(1) is not the same\n")
325    }
326  }
327  else {
328    if (params.isAllComp || params.isAllSimp) {
329      io.othersEntryOldestSel.get.zipWithIndex.foreach { case (sel, i) =>
330        io.deqEntry(i)     := Mux(sel.valid, othersEntryOldest.get(i), enqEntryOldest(i))
331        io.cancelDeqVec(i) := Mux(sel.valid, othersEntryOldestCancel.get(i), enqEntryOldestCancel(i))
332      }
333    }
334    else {
335      io.compEntryOldestSel.get.zip(io.simpEntryOldestSel.get).zipWithIndex.foreach { case ((compSel, simpSel), i) =>
336        io.deqEntry(i)     := Mux(compSel.valid,
337                                  compEntryOldest.get(i),
338                                  Mux(simpSel.valid, simpEntryOldest.get(i), enqEntryOldest(i)))
339        io.cancelDeqVec(i) := Mux(compSel.valid,
340                                  compEntryOldestCancel.get(i),
341                                  Mux(simpSel.valid, simpEntryOldestCancel.get(i), enqEntryOldestCancel(i)))
342      }
343    }
344  }
345
346  if (params.hasIQWakeUp) {
347    cancelBypassVec.zip(srcWakeUpL1ExuOHVec.get).zip(srcTimerVec.get).zip(srcLoadDependencyVec).foreach{ case (((cancelBypass: Bool, l1ExuOH: Vec[Vec[Bool]]), srcTimer: Vec[UInt]), srcLoadDependency: Vec[Vec[UInt]]) =>
348      val cancelByOg0 = l1ExuOH.zip(srcTimer).map {
349        case(exuOH, srcTimer) =>
350          (exuOH.asUInt & io.og0Cancel.asUInt).orR && srcTimer === 1.U
351      }.reduce(_ | _)
352      val cancelByLd = srcLoadDependency.map(x => LoadShouldCancel(Some(x), io.ldCancel)).reduce(_ | _)
353      cancelBypass := cancelByOg0 || cancelByLd
354    }
355  } else {
356    cancelBypassVec.zip(srcLoadDependencyVec).foreach { case (cancelBypass, srcLoadDependency) =>
357      val cancelByLd = srcLoadDependency.map(x => LoadShouldCancel(Some(x), io.ldCancel)).reduce(_ | _)
358      cancelBypass := cancelByLd
359    }
360  }
361
362  io.valid                          := validVec.asUInt
363  io.canIssue                       := canIssueVec.asUInt
364  io.fuType                         := fuTypeVec
365  io.dataSources                    := dataSourceVec
366  io.srcWakeUpL1ExuOH.foreach(_     := srcWakeUpL1ExuOHVec.get.map(x => VecInit(x.map(_.asUInt))))
367  io.srcTimer.foreach(_             := srcTimerVec.get)
368  io.loadDependency                 := loadDependencyVec
369  io.isFirstIssue.zipWithIndex.foreach{ case (isFirstIssue, deqIdx) =>
370    isFirstIssue                    := io.deqSelOH(deqIdx).valid && Mux1H(io.deqSelOH(deqIdx).bits, isFirstIssueVec)
371  }
372  io.simpEntryEnqSelVec.foreach(_   := finalSimpTransSelVec.get.zip(enqEntryTransVec).map(x => x._1 & Fill(SimpEntryNum, x._2.valid)))
373  io.compEntryEnqSelVec.foreach(_   := finalCompTransSelVec.get.zip(compEnqVec.get).map(x => x._1 & Fill(CompEntryNum, x._2.valid)))
374  io.othersEntryEnqSelVec.foreach(_ := finalOthersTransSelVec.get.zip(enqEntryTransVec).map(x => x._1 & Fill(OthersEntryNum, x._2.valid)))
375  io.robIdx.foreach(_           := robIdxVec)
376  io.uopIdx.foreach(_           := uopIdxVec.get)
377  io.rsFeedback                     := 0.U.asTypeOf(io.rsFeedback)  //should be removed
378  io.cancel.foreach(_               := cancelVec.get)               //for debug
379
380  def EntriesConnect(in: CommonInBundle, out: CommonOutBundle, entryIdx: Int) = {
381    in.flush                    := io.flush
382    in.wakeUpFromWB             := io.wakeUpFromWB
383    in.wakeUpFromIQ             := io.wakeUpFromIQ
384    in.og0Cancel                := io.og0Cancel
385    in.og1Cancel                := io.og1Cancel
386    in.ldCancel                 := io.ldCancel
387    in.deqSel                   := deqSelVec(entryIdx)
388    in.deqPortIdxWrite          := deqPortIdxWriteVec(entryIdx)
389    in.issueResp                := issueRespVec(entryIdx)
390    if (params.isMemAddrIQ) {
391      in.fromMem.get.stIssuePtr := io.fromMem.get.stIssuePtr
392      in.fromMem.get.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
393    }
394    if (params.isVecMemIQ) {
395      in.fromLsq.get.sqDeqPtr := io.vecMemIn.get.sqDeqPtr
396      in.fromLsq.get.lqDeqPtr := io.vecMemIn.get.lqDeqPtr
397    }
398    validVec(entryIdx)          := out.valid
399    canIssueVec(entryIdx)       := out.canIssue
400    fuTypeVec(entryIdx)         := out.fuType
401    robIdxVec(entryIdx)         := out.robIdx
402    dataSourceVec(entryIdx)     := out.dataSource
403    isFirstIssueVec(entryIdx)   := out.isFirstIssue
404    entries(entryIdx)           := out.entry
405    deqPortIdxReadVec(entryIdx) := out.deqPortIdxRead
406    issueTimerVec(entryIdx)     := out.issueTimerRead
407    srcLoadDependencyVec(entryIdx)          := out.srcLoadDependency
408    loadDependencyVec(entryIdx)             := out.entry.bits.status.mergedLoadDependency
409    if (params.hasIQWakeUp) {
410      srcWakeUpL1ExuOHVec.get(entryIdx)       := out.srcWakeUpL1ExuOH.get
411      srcTimerVec.get(entryIdx)               := out.srcTimer.get
412      cancelVec.get(entryIdx)                 := out.cancel.get
413    }
414    if (params.isVecMemIQ) {
415      uopIdxVec.get(entryIdx)   := out.uopIdx.get
416    }
417  }
418}
419
420class EntriesIO(implicit p: Parameters, params: IssueBlockParams) extends XSBundle {
421  val flush               = Flipped(ValidIO(new Redirect))
422  //enq
423  val enq                 = Vec(params.numEnq, Flipped(ValidIO(new EntryBundle)))
424  val og0Resp             = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle)))
425  val og1Resp             = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle)))
426  val finalIssueResp      = OptionWrapper(params.LdExuCnt > 0, Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle))))
427  //deq sel
428  val deqReady            = Vec(params.numDeq, Input(Bool()))
429  val deqSelOH            = Vec(params.numDeq, Flipped(ValidIO(UInt(params.numEntries.W))))
430  val enqEntryOldestSel   = Vec(params.numDeq, Flipped(ValidIO(UInt(params.numEnq.W))))
431  val simpEntryOldestSel  = OptionWrapper(params.hasCompAndSimp, Vec(params.numDeq, Flipped(ValidIO(UInt(params.numSimp.W)))))
432  val compEntryOldestSel  = OptionWrapper(params.hasCompAndSimp, Vec(params.numDeq, Flipped(ValidIO(UInt(params.numComp.W)))))
433  val othersEntryOldestSel= OptionWrapper(params.isAllComp || params.isAllSimp, Vec(params.numDeq, Flipped(ValidIO(UInt((params.numEntries - params.numEnq).W)))))
434  val subDeqRequest       = OptionWrapper(params.deqFuSame, Vec(params.numDeq, Input(UInt(params.numEntries.W))))
435  val subDeqSelOH         = OptionWrapper(params.deqFuSame, Vec(params.numDeq, Input(UInt(params.numEntries.W))))
436  // wakeup
437  val wakeUpFromWB: MixedVec[ValidIO[IssueQueueWBWakeUpBundle]] = Flipped(params.genWBWakeUpSinkValidBundle)
438  val wakeUpFromIQ: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(params.genIQWakeUpSinkValidBundle)
439  val og0Cancel           = Input(ExuOH(backendParams.numExu))
440  val og1Cancel           = Input(ExuOH(backendParams.numExu))
441  val ldCancel            = Vec(backendParams.LdExuCnt, Flipped(new LoadCancelIO))
442  //entries status
443  val valid               = Output(UInt(params.numEntries.W))
444  val canIssue            = Output(UInt(params.numEntries.W))
445  val fuType              = Vec(params.numEntries, Output(FuType()))
446  val dataSources         = Vec(params.numEntries, Vec(params.numRegSrc, Output(DataSource())))
447  val loadDependency      = Vec(params.numEntries, Vec(LoadPipelineWidth, UInt(3.W)))
448  val srcWakeUpL1ExuOH    = OptionWrapper(params.hasIQWakeUp, Vec(params.numEntries, Vec(params.numRegSrc, Output(ExuOH()))))
449  val srcTimer            = OptionWrapper(params.hasIQWakeUp, Vec(params.numEntries, Vec(params.numRegSrc, Output(UInt(3.W)))))
450  //deq status
451  val isFirstIssue        = Vec(params.numDeq, Output(Bool()))
452  val deqEntry            = Vec(params.numDeq, ValidIO(new EntryBundle))
453  val cancelDeqVec        = Vec(params.numDeq, Output(Bool()))
454  // mem only
455  val fromMem = if (params.isMemAddrIQ) Some(new Bundle {
456    val stIssuePtr        = Input(new SqPtr)
457    val memWaitUpdateReq  = Flipped(new MemWaitUpdateReq)
458    val slowResp          = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle)))
459    val fastResp          = Vec(params.numDeq, Flipped(ValidIO(new EntryDeqRespBundle)))
460  }) else None
461  val vecMemIn = OptionWrapper(params.isVecMemIQ, new Bundle {
462    val sqDeqPtr = Input(new SqPtr)
463    val lqDeqPtr = Input(new LqPtr)
464  })
465
466  val robIdx = OptionWrapper(params.isVecMemIQ, Output(Vec(params.numEntries, new RobPtr)))
467  val uopIdx = OptionWrapper(params.isVecMemIQ, Output(Vec(params.numEntries, UopIdx())))
468
469  val rsFeedback          = Output(Vec(5, Bool()))
470  // trans
471  val simpEntryDeqSelVec = OptionWrapper(params.hasCompAndSimp, Vec(params.numEnq, Input(UInt(params.numSimp.W))))
472  val simpEntryEnqSelVec = OptionWrapper(params.hasCompAndSimp, Vec(params.numEnq, Output(UInt(params.numSimp.W))))
473  val compEntryEnqSelVec = OptionWrapper(params.hasCompAndSimp, Vec(params.numEnq, Output(UInt(params.numComp.W))))
474  val othersEntryEnqSelVec = OptionWrapper(params.isAllComp || params.isAllSimp, Vec(params.numEnq, Output(UInt((params.numEntries - params.numEnq).W))))
475
476  // debug
477  val cancel              = OptionWrapper(params.hasIQWakeUp, Output(Vec(params.numEntries, Bool())))
478
479  def wakeup = wakeUpFromWB ++ wakeUpFromIQ
480}
481