xref: /XiangShan/src/main/scala/xiangshan/backend/issue/EnqEntry.scala (revision 4fa640e46b60470adc3cf9552409056fb74278cc)
1package xiangshan.backend.issue
2
3import org.chipsalliance.cde.config.Parameters
4import chisel3._
5import chisel3.util._
6import utility.{HasCircularQueuePtrHelper, GatedValidRegNext}
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.backend.issue.EntryBundles._
14import xiangshan.mem.{MemWaitUpdateReq, SqPtr, LqPtr}
15
16
17class EnqEntryIO(implicit p: Parameters, params: IssueBlockParams) extends XSBundle {
18  //input
19  val commonIn            = new CommonInBundle
20  val enqDelayIn1         = new EnqDelayInBundle
21  val enqDelayIn2         = new EnqDelayInBundle
22
23  //output
24  val commonOut           = new CommonOutBundle
25
26  def wakeup              = commonIn.wakeUpFromWB ++ commonIn.wakeUpFromIQ
27}
28
29class EnqEntry(isComp: Boolean)(implicit p: Parameters, params: IssueBlockParams) extends XSModule {
30  val io = IO(new EnqEntryIO)
31
32  val common              = Wire(new CommonWireBundle)
33  val entryUpdate         = Wire(new EntryBundle)
34  val entryRegNext        = Wire(new EntryBundle)
35  val enqDelayValidRegNext= Wire(Bool())
36  val hasWakeupIQ         = OptionWrapper(params.hasIQWakeUp, Wire(new CommonIQWakeupBundle))
37
38  val currentStatus               = Wire(new Status())
39  val enqDelaySrcState            = Wire(Vec(params.numRegSrc, SrcState()))
40  val enqDelayDataSources         = Wire(Vec(params.numRegSrc, DataSource()))
41  val enqDelaySrcWakeUpL1ExuOH    = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, ExuOH())))
42  val enqDelaySrcLoadDependency   = Wire(Vec(params.numRegSrc, Vec(LoadPipelineWidth, UInt(3.W))))
43
44  //Reg
45  val validReg = GatedValidRegNext(common.validRegNext, false.B)
46  val entryReg = RegEnable(entryRegNext, validReg || common.validRegNext)
47  val enqDelayValidReg = GatedValidRegNext(enqDelayValidRegNext, false.B)
48
49  //Wire
50  CommonWireConnect(common, hasWakeupIQ, validReg, currentStatus, io.commonIn, true)
51
52  when(io.commonIn.enq.valid) {
53    assert(common.enqReady, "Entry is not ready when enq is valid\n")
54  }
55
56  when(io.commonIn.enq.valid && common.enqReady) {
57    entryRegNext := io.commonIn.enq.bits
58  }.otherwise {
59    entryRegNext := entryUpdate
60  }
61
62  when(io.commonIn.enq.valid && common.enqReady) {
63    enqDelayValidRegNext := true.B
64  }.otherwise {
65    enqDelayValidRegNext := false.B
66  }
67
68  if (params.hasIQWakeUp) {
69    ShiftLoadDependency(hasWakeupIQ.get)
70    CommonIQWakeupConnect(common, hasWakeupIQ.get, validReg, currentStatus, io.commonIn, true)
71  }
72
73  // enq delay wakeup
74  val enqDelayOut1         = Wire(new EnqDelayOutBundle)
75  val enqDelayOut2         = Wire(new EnqDelayOutBundle)
76  EnqDelayWakeupConnect(io.enqDelayIn1, enqDelayOut1, entryReg.status, delay = 1)
77  EnqDelayWakeupConnect(io.enqDelayIn2, enqDelayOut2, entryReg.status, delay = 2)
78
79  for (i <- 0 until params.numRegSrc) {
80    if (params.inVfSchd && params.readVfRf && params.hasIQWakeUp) {
81      enqDelayDataSources(i).value            := Mux(enqDelayOut1.srcWakeUpByIQ(i).asBool,
82                                                      DataSource.bypass,
83                                                      Mux(enqDelayOut2.srcWakeUpByIQ(i).asBool, DataSource.bypass2, entryReg.status.srcStatus(i).dataSources.value))
84      val enqDelay1WakeUpValid = enqDelayOut1.srcWakeUpByIQVec(i).asUInt.orR
85      val enqDelay1WakeUpOH    = enqDelayOut1.srcWakeUpByIQVec(i)
86      val enqDelay2WakeUpOH    = enqDelayOut2.srcWakeUpByIQVec(i)
87      enqDelaySrcWakeUpL1ExuOH.get(i)         := Mux(enqDelay1WakeUpValid,
88                                                      Mux1H(enqDelay1WakeUpOH, params.wakeUpSourceExuIdx.map(x => MathUtils.IntToOH(x).U(backendParams.numExu.W))),
89                                                      Mux1H(enqDelay2WakeUpOH, params.wakeUpSourceExuIdx.map(x => MathUtils.IntToOH(x).U(backendParams.numExu.W))))
90    } else {
91      enqDelayDataSources(i).value            := Mux(enqDelayOut1.srcWakeUpByIQ(i).asBool, DataSource.bypass, entryReg.status.srcStatus(i).dataSources.value)
92      if (params.hasIQWakeUp) {
93        val wakeUpOH = enqDelayOut1.srcWakeUpByIQVec(i)
94        enqDelaySrcWakeUpL1ExuOH.get(i)       := Mux1H(wakeUpOH, params.wakeUpSourceExuIdx.map(x => MathUtils.IntToOH(x).U(backendParams.numExu.W)).toSeq)
95      }
96    }
97
98    enqDelaySrcState(i)                     := entryReg.status.srcStatus(i).srcState | enqDelayOut1.srcWakeUpByWB(i) | enqDelayOut1.srcWakeUpByIQ(i)
99    if (params.hasIQWakeUp) {
100      val wakeUpValid = enqDelayOut1.srcWakeUpByIQVec(i).asUInt.orR
101      val wakeUpOH = enqDelayOut1.srcWakeUpByIQVec(i)
102      enqDelaySrcLoadDependency(i)          := Mux(wakeUpValid, Mux1H(wakeUpOH, enqDelayOut1.shiftedWakeupLoadDependencyByIQVec), entryReg.status.srcStatus(i).srcLoadDependency)
103    } else {
104      enqDelaySrcLoadDependency(i)          := entryReg.status.srcStatus(i).srcLoadDependency
105    }
106  }
107
108  // current status
109  currentStatus                             := entryReg.status
110  when (enqDelayValidReg) {
111    currentStatus.srcStatus.zipWithIndex.foreach { case (srcStatus, srcIdx) =>
112      srcStatus.srcState                    := enqDelaySrcState(srcIdx)
113      srcStatus.dataSources                 := enqDelayDataSources(srcIdx)
114      srcStatus.srcLoadDependency           := enqDelaySrcLoadDependency(srcIdx)
115    }
116  }
117
118  if (params.hasIQWakeUp) {
119    currentStatus.srcStatus.map(_.srcWakeUpL1ExuOH.get).zip(entryReg.status.srcStatus.map(_.srcWakeUpL1ExuOH.get)).zip(enqDelaySrcWakeUpL1ExuOH.get).foreach {
120      case ((currExuOH, regExuOH), enqDelayExuOH) =>
121        currExuOH := 0.U.asTypeOf(currExuOH)
122        params.wakeUpSourceExuIdx.foreach(x => currExuOH(x) := Mux(enqDelayValidReg, enqDelayExuOH(x), regExuOH(x)))
123    }
124  }
125
126  EntryRegCommonConnect(common, hasWakeupIQ, validReg, entryUpdate, entryReg, currentStatus, io.commonIn, true)
127
128  //output
129  CommonOutConnect(io.commonOut, common, hasWakeupIQ, validReg, entryUpdate, entryReg, currentStatus, io.commonIn, true, isComp)
130}
131
132class EnqEntryVecMem(isComp: Boolean)(implicit p: Parameters, params: IssueBlockParams) extends EnqEntry(isComp)
133  with HasCircularQueuePtrHelper {
134
135  require(params.isVecMemIQ, "EnqEntryVecMem can only be instance of VecMem IQ")
136
137  EntryVecMemConnect(io.commonIn, common, validReg, entryReg, entryRegNext, entryUpdate)
138}
139
140object EnqEntry {
141  def apply(isComp: Boolean)(implicit p: Parameters, iqParams: IssueBlockParams): EnqEntry = {
142    iqParams.schdType match {
143      case IntScheduler() => new EnqEntry(isComp)
144      case MemScheduler() =>
145        if (iqParams.isVecMemIQ) new EnqEntryVecMem(isComp)
146        else new EnqEntry(isComp)
147      case VfScheduler() => new EnqEntry(isComp)
148      case _ => null
149    }
150  }
151}