xref: /XiangShan/src/main/scala/xiangshan/backend/issue/EnqEntry.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}
8import xiangshan._
9import xiangshan.backend.Bundles._
10import xiangshan.backend.fu.FuType
11import xiangshan.backend.datapath.DataSource
12import xiangshan.backend.rob.RobPtr
13import xiangshan.mem.{MemWaitUpdateReq, SqPtr, LqPtr}
14
15
16class EnqEntryIO(implicit p: Parameters, params: IssueBlockParams) extends XSBundle {
17  //input
18  val enq = Flipped(ValidIO(new EntryBundle))
19  val flush = Flipped(ValidIO(new Redirect))
20  val wakeUpFromWB: MixedVec[ValidIO[IssueQueueWBWakeUpBundle]] = Flipped(params.genWBWakeUpSinkValidBundle)
21  val wakeUpFromIQ: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(params.genIQWakeUpSinkValidBundle)
22  val og0Cancel = Input(ExuOH(backendParams.numExu))
23  val og1Cancel = Input(ExuOH(backendParams.numExu))
24  val ldCancel = Vec(backendParams.LduCnt + backendParams.HyuCnt, Flipped(new LoadCancelIO))
25  val enqDelayWakeUpFromWB: MixedVec[ValidIO[IssueQueueWBWakeUpBundle]] = Flipped(params.genWBWakeUpSinkValidBundle)
26  val enqDelayWakeUpFromIQ: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(params.genIQWakeUpSinkValidBundle)
27  val enqDelayOg0Cancel = Input(ExuOH(backendParams.numExu))
28  val enqDelayLdCancel = Vec(backendParams.LdExuCnt, Flipped(new LoadCancelIO))
29  val deqSel = Input(Bool())
30  val deqPortIdxWrite = Input(UInt(1.W))
31  val transSel = Input(Bool())
32  val issueResp = Flipped(ValidIO(new EntryDeqRespBundle))
33  //output
34  val valid = Output(Bool())
35  val canIssue = Output(Bool())
36  val clear = Output(Bool())
37  val fuType = Output(FuType())
38  val dataSource = Output(Vec(params.numRegSrc, DataSource()))
39  val srcWakeUpL1ExuOH = OptionWrapper(params.hasIQWakeUp, Output(Vec(params.numRegSrc, ExuOH())))
40  val srcTimer = OptionWrapper(params.hasIQWakeUp, Output(Vec(params.numRegSrc, UInt(3.W))))
41  val transEntry =  ValidIO(new EntryBundle)
42  val isFirstIssue = Output(Bool())
43  val entry = ValidIO(new EntryBundle)
44  val robIdx = Output(new RobPtr)
45  val uopIdx = OptionWrapper(params.isVecMemIQ, Output(UopIdx()))
46  val deqPortIdxRead = Output(UInt(1.W))
47  val issueTimerRead = Output(UInt(2.W))
48  // mem only
49  val fromMem = if(params.isMemAddrIQ) Some(new Bundle {
50    val stIssuePtr = Input(new SqPtr)
51    val memWaitUpdateReq = Flipped(new MemWaitUpdateReq)
52  }) else None
53  // vector mem only
54  val fromLsq = OptionWrapper(params.isVecMemIQ, new Bundle {
55    val sqDeqPtr = Input(new SqPtr)
56    val lqDeqPtr = Input(new LqPtr)
57  })
58  // debug
59  val cancel = OptionWrapper(params.hasIQWakeUp, Output(Bool()))
60
61  def wakeup = wakeUpFromWB ++ wakeUpFromIQ
62}
63
64class EnqEntry(implicit p: Parameters, params: IssueBlockParams) extends XSModule {
65  val io = IO(new EnqEntryIO)
66
67  val validReg = RegInit(false.B)
68  val entryReg = Reg(new EntryBundle)
69  val enqDelayValidReg = RegInit(false.B)
70
71  val validRegNext = Wire(Bool())
72  val entryRegNext = Wire(new EntryBundle)
73  val entryUpdate = Wire(new EntryBundle)
74  val enqDelayValidRegNext = Wire(Bool())
75  val enqReady = Wire(Bool())
76  val clear = Wire(Bool())
77  val flushed = Wire(Bool())
78  val deqSuccess = Wire(Bool())
79  val srcWakeUp = Wire(Vec(params.numRegSrc, Bool()))
80  val srcWakeUpByWB = Wire(Vec(params.numRegSrc, Bool()))
81  val srcCancelVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, Bool())))
82  val srcLoadCancelVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, Bool())))
83  val srcWakeUpByIQVec = Wire(Vec(params.numRegSrc, Vec(params.numWakeupFromIQ, Bool())))
84  val srcWakeUpByIQWithoutCancel = Wire(Vec(params.numRegSrc, Vec(params.numWakeupFromIQ, Bool())))
85  val srcWakeUpButCancel = Wire(Vec(params.numRegSrc, Vec(params.numWakeupFromIQ, Bool())))
86  val srcWakeUpL1ExuOHOut = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, ExuVec())))
87  val srcLoadDependencyOut = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, Vec(LoadPipelineWidth, UInt(3.W)))))
88  val wakeupLoadDependencyByIQVec = Wire(Vec(params.numWakeupFromIQ, Vec(LoadPipelineWidth, UInt(3.W))))
89  val shiftedWakeupLoadDependencyByIQVec = Wire(Vec(params.numWakeupFromIQ, Vec(LoadPipelineWidth, UInt(3.W))))
90  val shiftedWakeupLoadDependencyByIQBypassVec = Wire(Vec(params.numWakeupFromIQ, Vec(LoadPipelineWidth, UInt(3.W))))
91  val cancelVec = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, Bool())))
92
93  val currentStatus = Wire(new Status())
94  val enqDelaySrcState = Wire(Vec(params.numRegSrc, SrcState()))
95  val enqDelayDataSources = Wire(Vec(params.numRegSrc, DataSource()))
96  val enqDelaySrcWakeUpL1ExuOH = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, ExuOH())))
97  val enqDelaySrcTimer = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, UInt(3.W))))
98  val enqDelaySrcLoadDependency = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, Vec(LoadPipelineWidth, UInt(3.W)))))
99
100  val enqDelaySrcWakeUpByWB: Vec[UInt] = Wire(Vec(params.numRegSrc, SrcState()))
101  val enqDelaySrcWakeUpByIQ: Vec[UInt] = Wire(Vec(params.numRegSrc, SrcState()))
102  val enqDelaySrcWakeUpByIQVec: Vec[Vec[Bool]] = Wire(Vec(params.numRegSrc, Vec(params.numWakeupFromIQ, Bool())))
103  val enqDelayShiftedWakeupLoadDependencyByIQVec: Vec[Vec[UInt]] = Wire(Vec(params.numWakeupFromIQ, Vec(LoadPipelineWidth, UInt(3.W))))
104
105  //Reg
106  validReg := validRegNext
107  entryReg := entryRegNext
108  enqDelayValidReg := enqDelayValidRegNext
109
110  //Wire
111  when(io.enq.valid && enqReady) {
112    validRegNext := true.B
113  }.elsewhen(clear) {
114    validRegNext := false.B
115  }.otherwise {
116    validRegNext := validReg
117  }
118
119  when(io.enq.valid && enqReady) {
120    entryRegNext := io.enq.bits
121  }.otherwise {
122    entryRegNext := entryUpdate
123  }
124
125  when(io.enq.valid && enqReady) {
126    enqDelayValidRegNext := true.B
127  }.otherwise {
128    enqDelayValidRegNext := false.B
129  }
130
131  enqReady := !validReg || clear
132  clear := flushed || io.transSel || deqSuccess
133  flushed := entryReg.status.robIdx.needFlush(io.flush)
134  deqSuccess := io.issueResp.valid && io.issueResp.bits.respType === RSFeedbackType.fuIdle && !srcLoadCancelVec.map(_.reduce(_ || _)).getOrElse(false.B)
135
136  // current wakeup
137  srcWakeUpByWB := io.wakeUpFromWB.map(bundle => bundle.bits.wakeUp(entryReg.status.psrc zip entryReg.status.srcType, bundle.valid)).transpose.map(x => VecInit(x.toSeq).asUInt.orR).toSeq
138  srcWakeUp := srcWakeUpByWB.zip(srcWakeUpByIQVec).map { case (x, y) => x || y.asUInt.orR }
139
140  shiftedWakeupLoadDependencyByIQVec
141    .zip(wakeupLoadDependencyByIQVec)
142    .zip(params.wakeUpInExuSources.map(_.name)).foreach {
143    case ((deps, originalDeps), name) => deps.zip(originalDeps).zipWithIndex.foreach {
144      case ((dep, originalDep), deqPortIdx) =>
145        if (params.backendParam.getLdExuIdx(params.backendParam.allExuParams.find(_.name == name).get) == deqPortIdx)
146          dep := (originalDep << 2).asUInt | 2.U
147        else
148          dep := originalDep << 1
149    }
150  }
151  shiftedWakeupLoadDependencyByIQBypassVec
152    .zip(wakeupLoadDependencyByIQVec)
153    .zip(params.wakeUpInExuSources.map(_.name)).foreach {
154    case ((deps, originalDeps), name) => deps.zip(originalDeps).zipWithIndex.foreach {
155      case ((dep, originalDep), deqPortIdx) =>
156        if (params.backendParam.getLdExuIdx(params.backendParam.allExuParams.find(_.name == name).get) == deqPortIdx)
157          dep := (originalDep << 1).asUInt | 1.U
158        else
159          dep := originalDep
160    }
161  }
162
163  if (params.hasIQWakeUp) {
164    srcCancelVec.get.zip(srcLoadCancelVec.get).zip(srcWakeUpByIQWithoutCancel).zipWithIndex.foreach { case (((srcCancel, srcLoadCancel), wakeUpByIQVec), srcIdx) =>
165      val ldTransCancel = Mux1H(wakeUpByIQVec, wakeupLoadDependencyByIQVec.map(dep => LoadShouldCancel(Some(dep), io.ldCancel)))
166      srcLoadCancel := LoadShouldCancel(currentStatus.srcLoadDependency.map(_(srcIdx)), io.ldCancel)
167      srcCancel := srcLoadCancel || ldTransCancel
168    }
169  }
170
171  if (io.wakeUpFromIQ.isEmpty) {
172    srcWakeUpByIQVec := 0.U.asTypeOf(srcWakeUpByIQVec)
173    wakeupLoadDependencyByIQVec := 0.U.asTypeOf(wakeupLoadDependencyByIQVec)
174  } else {
175    val wakeupVec: IndexedSeq[IndexedSeq[Bool]] = io.wakeUpFromIQ.map((bundle: ValidIO[IssueQueueIQWakeUpBundle]) =>
176      bundle.bits.wakeUp(entryReg.status.psrc zip entryReg.status.srcType, bundle.valid)
177    ).toIndexedSeq.transpose
178    val cancelSel = params.wakeUpSourceExuIdx.zip(io.wakeUpFromIQ).map{ case (x, y) => io.og0Cancel(x) && y.bits.is0Lat}
179    srcWakeUpByIQVec := wakeupVec.map(x => VecInit(x.zip(cancelSel).map { case (wakeup, cancel) => wakeup && !cancel }))
180    srcWakeUpButCancel := wakeupVec.map(x => VecInit(x.zip(cancelSel).map { case (wakeup, cancel) => wakeup && cancel }))
181    srcWakeUpByIQWithoutCancel := wakeupVec.map(x => VecInit(x))
182    wakeupLoadDependencyByIQVec := io.wakeUpFromIQ.map(_.bits.loadDependency).toSeq
183  }
184
185  // enq delay wakeup
186  enqDelaySrcWakeUpByWB.zipWithIndex.foreach { case (wakeup, i) =>
187    wakeup := io.enqDelayWakeUpFromWB.map(x => x.bits.wakeUp(Seq((entryReg.status.psrc(i), entryReg.status.srcType(i))), x.valid).head
188    ).reduce(_ || _)
189  }
190
191  if (params.hasIQWakeUp) {
192    val wakeupVec: IndexedSeq[IndexedSeq[Bool]] = io.enqDelayWakeUpFromIQ.map( x =>
193      x.bits.wakeUp(entryReg.status.psrc.zip(entryReg.status.srcType), x.valid)
194    ).toIndexedSeq.transpose
195    val cancelSel = params.wakeUpSourceExuIdx.zip(io.enqDelayWakeUpFromIQ).map{ case (x, y) => io.enqDelayOg0Cancel(x) && y.bits.is0Lat}
196    enqDelaySrcWakeUpByIQVec := wakeupVec.map(x => VecInit(x.zip(cancelSel).map { case (wakeup, cancel) => wakeup && !cancel }))
197  } else {
198    enqDelaySrcWakeUpByIQVec := 0.U.asTypeOf(enqDelaySrcWakeUpByIQVec)
199  }
200
201  if (params.hasIQWakeUp) {
202    enqDelaySrcWakeUpByIQ.zipWithIndex.foreach { case (wakeup, i) =>
203      val ldTransCancel = Mux1H(enqDelaySrcWakeUpByIQVec(i), io.enqDelayWakeUpFromIQ.map(_.bits.loadDependency).map(dp => LoadShouldCancel(Some(dp), io.enqDelayLdCancel)).toSeq)
204      wakeup := enqDelaySrcWakeUpByIQVec(i).asUInt.orR && !ldTransCancel
205    }
206  } else {
207    enqDelaySrcWakeUpByIQ := 0.U.asTypeOf(enqDelaySrcWakeUpByIQ)
208  }
209
210  enqDelayShiftedWakeupLoadDependencyByIQVec.zip(io.enqDelayWakeUpFromIQ.map(_.bits.loadDependency))
211    .zip(params.wakeUpInExuSources.map(_.name)).foreach { case ((dps, ldps), name) =>
212    dps.zip(ldps).zipWithIndex.foreach { case ((dp, ldp), deqPortIdx) =>
213      if (params.backendParam.getLdExuIdx(params.backendParam.allExuParams.find(_.name == name).get) == deqPortIdx)
214        dp := (ldp << 2).asUInt | 2.U
215      else
216        dp := ldp << 1
217    }
218  }
219
220  for (i <- 0 until params.numRegSrc) {
221    enqDelaySrcState(i) := entryReg.status.srcState(i) | enqDelaySrcWakeUpByWB(i) | enqDelaySrcWakeUpByIQ(i)
222    enqDelayDataSources(i).value := Mux(enqDelaySrcWakeUpByIQ(i).asBool, DataSource.bypass, DataSource.reg)
223    if (params.hasIQWakeUp) {
224      val wakeUpValid = enqDelaySrcWakeUpByIQVec(i).asUInt.orR
225      val wakeUpOH = enqDelaySrcWakeUpByIQVec(i)
226      enqDelaySrcWakeUpL1ExuOH.get(i) := Mux1H(wakeUpOH, params.wakeUpSourceExuIdx.map(x => MathUtils.IntToOH(x).U(backendParams.numExu.W)).toSeq)
227      enqDelaySrcTimer.get(i) := Mux(wakeUpValid, 2.U, 3.U)
228      enqDelaySrcLoadDependency.get(i) := Mux(wakeUpValid, Mux1H(wakeUpOH, enqDelayShiftedWakeupLoadDependencyByIQVec), entryReg.status.srcLoadDependency.get(i))
229    }
230  }
231  currentStatus := entryReg.status
232  when (enqDelayValidReg) {
233    currentStatus.srcState := enqDelaySrcState
234    currentStatus.dataSources := enqDelayDataSources
235    currentStatus.srcTimer.foreach(_ := enqDelaySrcTimer.get)
236    currentStatus.srcLoadDependency.foreach(_ := enqDelaySrcLoadDependency.get)
237  }
238
239  if (params.hasIQWakeUp) {
240    currentStatus.srcWakeUpL1ExuOH.get.zip(entryReg.status.srcWakeUpL1ExuOH.get).zip(enqDelaySrcWakeUpL1ExuOH.get).foreach {
241      case ((currExuOH, regExuOH), enqDelayExuOH) =>
242        currExuOH := 0.U.asTypeOf(currExuOH)
243        params.wakeUpSourceExuIdx.foreach(x => currExuOH(x) := Mux(enqDelayValidReg, enqDelayExuOH(x), regExuOH(x)))
244    }
245  }
246
247  //entryUpdate
248  entryUpdate.status.srcState.zip(currentStatus.srcState).zip(srcWakeUp).zipWithIndex.foreach { case (((stateNext, state), wakeup), srcIdx) =>
249    val cancel = srcCancelVec.map(_ (srcIdx)).getOrElse(false.B)
250    stateNext := Mux(cancel, false.B, wakeup | state)
251    if (params.hasIQWakeUp) {
252      cancelVec.get(srcIdx) := cancel
253    }
254  }
255  entryUpdate.status.dataSources.zip(srcWakeUpByIQVec).foreach {
256    case (dataSourceNext: DataSource, wakeUpByIQOH: Vec[Bool]) =>
257      when(wakeUpByIQOH.asUInt.orR) {
258        dataSourceNext.value := DataSource.bypass
259      }.otherwise {
260        dataSourceNext.value := DataSource.reg
261      }
262  }
263  if (params.hasIQWakeUp) {
264    entryUpdate.status.srcWakeUpL1ExuOH.get.zip(srcWakeUpByIQVec).zip(srcWakeUp).zipWithIndex.foreach {
265      case (((exuOH: Vec[Bool], wakeUpByIQOH: Vec[Bool]), wakeUp: Bool), srcIdx) =>
266        val origExuOH = 0.U.asTypeOf(exuOH)
267        when(wakeUpByIQOH.asUInt.orR) {
268          origExuOH := Mux1H(wakeUpByIQOH, params.wakeUpSourceExuIdx.toSeq.map(x => MathUtils.IntToOH(x).U(backendParams.numExu.W))).asBools
269        }.elsewhen(wakeUp) {
270          origExuOH := 0.U.asTypeOf(origExuOH)
271        }.otherwise {
272          origExuOH := currentStatus.srcWakeUpL1ExuOH.get(srcIdx)
273        }
274        exuOH := 0.U.asTypeOf(exuOH)
275        params.wakeUpSourceExuIdx.foreach(x => exuOH(x) := origExuOH(x))
276    }
277    srcWakeUpL1ExuOHOut.get.zip(srcWakeUpByIQWithoutCancel).zip(srcWakeUp).zipWithIndex.foreach {
278      case (((exuOH: Vec[Bool], wakeUpByIQOH: Vec[Bool]), wakeUp: Bool), srcIdx) =>
279        val origExuOH = 0.U.asTypeOf(exuOH)
280        when(wakeUpByIQOH.asUInt.orR) {
281          origExuOH := VecInit(Mux1H(wakeUpByIQOH, params.wakeUpSourceExuIdx.map(x => MathUtils.IntToOH(x).U(backendParams.numExu.W)).toSeq).asBools)
282        }.otherwise {
283          origExuOH := currentStatus.srcWakeUpL1ExuOH.get(srcIdx)
284        }
285        exuOH := 0.U.asTypeOf(exuOH)
286        params.wakeUpSourceExuIdx.foreach(x => exuOH(x) := origExuOH(x))
287    }
288    entryUpdate.status.srcTimer.get.zip(currentStatus.srcTimer.get).zip(srcWakeUpByIQVec).zipWithIndex.foreach {
289      case (((srcIssuedTimerNext, srcIssuedTimer), wakeUpByIQOH: Vec[Bool]), srcIdx) =>
290        srcIssuedTimerNext := MuxCase(3.U, Seq(
291          // T0: waked up by IQ, T1: reset timer as 1
292          wakeUpByIQOH.asUInt.orR -> 2.U,
293          // do not overflow
294          srcIssuedTimer.andR -> srcIssuedTimer,
295          // T2+: increase if the entry is valid, the src is ready, and the src is woken up by iq
296          (validReg && SrcState.isReady(currentStatus.srcState(srcIdx)) && currentStatus.srcWakeUpL1ExuOH.get(srcIdx).asUInt.orR) -> (srcIssuedTimer + 1.U)
297        ))
298    }
299    entryUpdate.status.srcLoadDependency.get.zip(currentStatus.srcLoadDependency.get).zip(srcWakeUpByIQVec).zip(srcWakeUp).foreach {
300      case (((loadDependencyNext, loadDependency), wakeUpByIQVec), wakeup) =>
301        loadDependencyNext :=
302          Mux(wakeup,
303            Mux1H(wakeUpByIQVec, shiftedWakeupLoadDependencyByIQVec),
304            Mux(validReg && loadDependency.asUInt.orR, VecInit(loadDependency.map(i => i(i.getWidth - 2, 0) << 1)), loadDependency)
305          )
306    }
307    srcLoadDependencyOut.get.zip(currentStatus.srcLoadDependency.get).zip(srcWakeUpByIQVec).zip(srcWakeUp).foreach {
308      case (((loadDependencyOut, loadDependency), wakeUpByIQVec), wakeup) =>
309        loadDependencyOut := Mux1H(wakeUpByIQVec, shiftedWakeupLoadDependencyByIQBypassVec)
310    }
311  }
312
313  when(io.deqSel) {
314    entryUpdate.status.issueTimer := 0.U
315    entryUpdate.status.deqPortIdx := io.deqPortIdxWrite
316  }.elsewhen(entryReg.status.issued){
317    entryUpdate.status.issueTimer := entryReg.status.issueTimer + 1.U
318    entryUpdate.status.deqPortIdx := entryReg.status.deqPortIdx
319  }.otherwise {
320    entryUpdate.status.issueTimer := "b10".U
321    entryUpdate.status.deqPortIdx := 0.U
322  }
323  entryUpdate.status.psrc := entryReg.status.psrc
324  entryUpdate.status.srcType := entryReg.status.srcType
325  entryUpdate.status.fuType := entryReg.status.fuType
326  entryUpdate.status.robIdx := entryReg.status.robIdx
327  when(srcLoadCancelVec.map(_.reduce(_ || _)).getOrElse(false.B) || srcWakeUpButCancel.map(_.fold(false.B)(_ || _)).fold(false.B)(_ || _)) {
328    entryUpdate.status.issued := false.B
329  }.elsewhen(io.deqSel) {
330    entryUpdate.status.issued := true.B
331  }.elsewhen(io.issueResp.valid && RSFeedbackType.isBlocked(io.issueResp.bits.respType)) {
332    entryUpdate.status.issued := false.B
333  }.elsewhen(!currentStatus.srcReady) {
334    entryUpdate.status.issued := false.B
335  }.otherwise {
336    entryUpdate.status.issued := entryReg.status.issued
337  }
338  entryUpdate.status.firstIssue := io.deqSel || entryReg.status.firstIssue
339  entryUpdate.status.blocked := false.B //todo
340  //remain imm and payload
341  entryUpdate.imm.foreach(_ := entryReg.imm.get)
342  entryUpdate.payload := entryReg.payload
343
344  //output
345  val canIssue = currentStatus.canIssue && validReg && !srcCancelVec.getOrElse(false.B).asUInt.orR
346  val canIssueBypass = validReg && !entryReg.status.issued && !entryReg.status.blocked &&
347    VecInit(currentStatus.srcState.zip(srcWakeUpByIQWithoutCancel).zipWithIndex.map { case ((state, wakeupVec), srcIdx) =>
348      val cancel = srcCancelVec.map(_ (srcIdx)).getOrElse(false.B)
349      Mux(cancel, false.B, wakeupVec.asUInt.orR | state)
350    }).asUInt.andR
351  io.dataSource.zip(currentStatus.dataSources).zip(srcWakeUpByIQVec).zip(srcWakeUp).foreach {
352    case (((dataSourceOut: DataSource, dataSource: DataSource), wakeUpByIQOH: Vec[Bool]), wakeUpAll) =>
353      when(wakeUpByIQOH.asUInt.orR) {
354        dataSourceOut.value := DataSource.forward
355      }.otherwise {
356        dataSourceOut.value := dataSource.value
357      }
358  }
359  if (params.hasIQWakeUp) {
360    io.srcTimer.get.zip(currentStatus.srcTimer.get).zip(srcWakeUpByIQWithoutCancel).zip(srcWakeUp).foreach {
361      case (((srcTimerOut, srcTimer), wakeUpByIQOH: Vec[Bool]), wakeUpAll) =>
362        when(wakeUpByIQOH.asUInt.orR) {
363          srcTimerOut := Mux1H(wakeUpByIQOH, io.wakeUpFromIQ.map(_.bits.is0Lat).toSeq).asUInt
364        }.otherwise {
365          srcTimerOut := srcTimer
366        }
367    }
368    io.srcWakeUpL1ExuOH.get := Mux(canIssueBypass && !canIssue, srcWakeUpL1ExuOHOut.get, currentStatus.srcWakeUpL1ExuOH.get).map(_.asUInt)
369  }
370  io.transEntry.valid := validReg && !flushed && !deqSuccess
371  io.transEntry.bits := entryUpdate
372  io.canIssue := (canIssue || canIssueBypass) && !flushed
373  io.clear := clear
374  io.fuType := entryReg.status.fuType
375  io.valid := validReg
376  io.isFirstIssue := !entryReg.status.firstIssue
377  io.entry.valid := validReg
378  io.entry.bits := entryReg
379  io.entry.bits.status := currentStatus
380  io.entry.bits.status.srcLoadDependency.foreach(_ := Mux(canIssueBypass && !canIssue, srcLoadDependencyOut.get, currentStatus.srcLoadDependency.get))
381  io.robIdx := entryReg.status.robIdx
382  io.uopIdx.foreach(_ := entryReg.status.uopIdx.get)
383  io.issueTimerRead := entryReg.status.issueTimer
384  io.deqPortIdxRead := entryReg.status.deqPortIdx
385  io.cancel.foreach(_ := cancelVec.get.asUInt.orR)
386}
387
388class EnqEntryMem()(implicit p: Parameters, params: IssueBlockParams) extends EnqEntry
389  with HasCircularQueuePtrHelper {
390  val fromMem = io.fromMem.get
391
392  val memStatus = entryReg.status.mem.get
393  println("memStatus" + memStatus)
394  val memStatusNext = entryRegNext.status.mem.get
395  val memStatusUpdate = entryUpdate.status.mem.get
396
397  // load cannot be issued before older store, unless meet some condition
398  val blockedByOlderStore = isAfter(memStatusNext.sqIdx, fromMem.stIssuePtr)
399
400  val deqFailedForStdInvalid = io.issueResp.valid && io.issueResp.bits.respType === RSFeedbackType.dataInvalid
401
402  val staWaitedReleased = Cat(
403    fromMem.memWaitUpdateReq.robIdx.map(x => x.valid && x.bits.value === memStatusNext.waitForRobIdx.value)
404  ).orR
405  val stdWaitedReleased = Cat(
406    fromMem.memWaitUpdateReq.sqIdx.map(x => x.valid && x.bits.value === memStatusNext.waitForSqIdx.value)
407  ).orR
408  val olderStaNotViolate = staWaitedReleased && !memStatusNext.strictWait
409  val olderStdReady = stdWaitedReleased && memStatusNext.waitForStd
410  val waitStd = !olderStdReady
411  val waitSta = !olderStaNotViolate
412
413  when (io.enq.valid && enqReady) {
414    memStatusNext.waitForSqIdx := io.enq.bits.status.mem.get.waitForSqIdx
415    // update by lfst at dispatch stage
416    memStatusNext.waitForRobIdx := io.enq.bits.status.mem.get.waitForRobIdx
417    // new load inst don't known if it is blocked by store data ahead of it
418    memStatusNext.waitForStd := false.B
419    // update by ssit at rename stage
420    memStatusNext.strictWait := io.enq.bits.status.mem.get.strictWait
421    memStatusNext.sqIdx := io.enq.bits.status.mem.get.sqIdx
422  }.otherwise {
423    memStatusNext := memStatusUpdate
424  }
425
426  when(deqFailedForStdInvalid) {
427    memStatusUpdate.waitForSqIdx := io.issueResp.bits.dataInvalidSqIdx
428    memStatusUpdate.waitForRobIdx := memStatus.waitForRobIdx
429    memStatusUpdate.waitForStd := true.B
430    memStatusUpdate.strictWait := memStatus.strictWait
431    memStatusUpdate.sqIdx := memStatus.sqIdx
432  }.otherwise {
433    memStatusUpdate := memStatus
434  }
435
436  val shouldBlock = Mux(io.enq.valid && enqReady, io.enq.bits.status.blocked, entryReg.status.blocked)
437  val blockNotReleased = waitStd || waitSta
438  val respBlock = deqFailedForStdInvalid
439  entryRegNext.status.blocked := shouldBlock && blockNotReleased && blockedByOlderStore || respBlock
440  entryUpdate.status.blocked := shouldBlock && blockNotReleased && blockedByOlderStore || respBlock
441
442}
443
444class EnqEntryVecMemAddr()(implicit p: Parameters, params: IssueBlockParams) extends EnqEntryMem {
445
446  require(params.isVecMemAddrIQ, "EnqEntryVecMemAddr can only be instance of VecMemAddr IQ")
447
448  val vecMemStatus = entryReg.status.vecMem.get
449  val vecMemStatusNext = entryRegNext.status.vecMem.get
450  val vecMemStatusUpdate = entryUpdate.status.vecMem.get
451  val fromLsq = io.fromLsq.get
452
453  when (io.enq.valid && enqReady) {
454    vecMemStatusNext.sqIdx := io.enq.bits.status.vecMem.get.sqIdx
455    vecMemStatusNext.lqIdx := io.enq.bits.status.vecMem.get.lqIdx
456  }.otherwise {
457    vecMemStatusNext := vecMemStatusUpdate
458  }
459  vecMemStatusUpdate := vecMemStatus
460
461  val isLsqHead = {
462    // if (params.isVecLdAddrIQ)
463      entryRegNext.status.vecMem.get.lqIdx <= fromLsq.lqDeqPtr &&
464    // else
465      entryRegNext.status.vecMem.get.sqIdx <= fromLsq.sqDeqPtr
466  }
467
468  entryRegNext.status.blocked := shouldBlock && blockNotReleased && blockedByOlderStore || respBlock || !isLsqHead
469  entryUpdate.status.blocked := shouldBlock && blockNotReleased && blockedByOlderStore || respBlock || !isLsqHead
470  entryUpdate.status.uopIdx.get := entryReg.status.uopIdx.get
471}
472
473class EnqEntryVecMemData()(implicit p: Parameters, params: IssueBlockParams) extends EnqEntry
474  with HasCircularQueuePtrHelper {
475
476  require(params.isVecStDataIQ, "EnqEntryVecMemData can only be instance of VecMemData IQ")
477
478  val vecMemStatus = entryReg.status.vecMem.get
479  val vecMemStatusNext = entryRegNext.status.vecMem.get
480  val vecMemStatusUpdate = entryUpdate.status.vecMem.get
481  val fromLsq = io.fromLsq.get
482
483  when (io.enq.valid && enqReady) {
484    vecMemStatusNext.sqIdx := io.enq.bits.status.vecMem.get.sqIdx
485    vecMemStatusNext.lqIdx := io.enq.bits.status.vecMem.get.lqIdx
486  }.otherwise {
487    vecMemStatusNext := vecMemStatusUpdate
488  }
489  vecMemStatusUpdate := vecMemStatus
490
491  val isLsqHead = entryRegNext.status.vecMem.get.sqIdx.value === fromLsq.sqDeqPtr.value
492
493  entryRegNext.status.blocked := !isLsqHead
494  entryUpdate.status.blocked := !isLsqHead
495  entryUpdate.status.uopIdx.get := entryReg.status.uopIdx.get
496}
497
498object EnqEntry {
499  def apply(implicit p: Parameters, iqParams: IssueBlockParams): EnqEntry = {
500    iqParams.schdType match {
501      case IntScheduler() => new EnqEntry()
502      case MemScheduler() =>
503        if (iqParams.isLdAddrIQ || iqParams.isStAddrIQ || iqParams.isHyAddrIQ) new EnqEntryMem()
504        else if (iqParams.isVecMemAddrIQ) new EnqEntryVecMemAddr()
505        else if (iqParams.isVecStDataIQ) new EnqEntryVecMemData()
506        else new EnqEntry()
507      case VfScheduler() => new EnqEntry()
508      case _ => null
509    }
510  }
511}