xref: /XiangShan/src/main/scala/xiangshan/backend/issue/EnqEntry.scala (revision 99ce5576f0ecce1b5045b7bc0dbbb2debd934fbb)
15db4956bSzhanglyGitpackage xiangshan.backend.issue
25db4956bSzhanglyGit
383ba63b3SXuan Huimport org.chipsalliance.cde.config.Parameters
45db4956bSzhanglyGitimport chisel3._
55db4956bSzhanglyGitimport chisel3.util._
64243aa09SsinceforYyimport utility.{HasCircularQueuePtrHelper, GatedValidRegNext}
75db4956bSzhanglyGitimport utils.{MathUtils, OptionWrapper}
85db4956bSzhanglyGitimport xiangshan._
95db4956bSzhanglyGitimport xiangshan.backend.Bundles._
105db4956bSzhanglyGitimport xiangshan.backend.fu.FuType
115db4956bSzhanglyGitimport xiangshan.backend.datapath.DataSource
125db4956bSzhanglyGitimport xiangshan.backend.rob.RobPtr
13aa2bcc31SzhanglyGitimport xiangshan.backend.issue.EntryBundles._
149e12e8edScz4eimport xiangshan.mem.{SqPtr, LqPtr}
15*99ce5576Scz4eimport xiangshan.mem.Bundles.MemWaitUpdateReqBundle
165db4956bSzhanglyGit
175db4956bSzhanglyGit
185db4956bSzhanglyGitclass EnqEntryIO(implicit p: Parameters, params: IssueBlockParams) extends XSBundle {
195db4956bSzhanglyGit  //input
20aa2bcc31SzhanglyGit  val commonIn            = new CommonInBundle
214fa640e4Ssinsanction  val enqDelayIn1         = new EnqDelayInBundle
224fa640e4Ssinsanction  val enqDelayIn2         = new EnqDelayInBundle
235db4956bSzhanglyGit
24aa2bcc31SzhanglyGit  //output
25aa2bcc31SzhanglyGit  val commonOut           = new CommonOutBundle
26aa2bcc31SzhanglyGit
27aa2bcc31SzhanglyGit  def wakeup              = commonIn.wakeUpFromWB ++ commonIn.wakeUpFromIQ
285db4956bSzhanglyGit}
295db4956bSzhanglyGit
30df26db8aSsinsanctionclass EnqEntry(isComp: Boolean)(implicit p: Parameters, params: IssueBlockParams) extends XSModule {
315db4956bSzhanglyGit  val io = IO(new EnqEntryIO)
325db4956bSzhanglyGit
33aa2bcc31SzhanglyGit  val common              = Wire(new CommonWireBundle)
345db4956bSzhanglyGit  val entryUpdate         = Wire(new EntryBundle)
35aa2bcc31SzhanglyGit  val entryRegNext        = Wire(new EntryBundle)
36aa2b5219Ssinsanction  val enqDelayValidRegNext= Wire(Bool())
37aa2bcc31SzhanglyGit  val hasWakeupIQ         = OptionWrapper(params.hasIQWakeUp, Wire(new CommonIQWakeupBundle))
385db4956bSzhanglyGit
39aa2b5219Ssinsanction  val currentStatus               = Wire(new Status())
40aa2b5219Ssinsanction  val enqDelaySrcState            = Wire(Vec(params.numRegSrc, SrcState()))
41aa2b5219Ssinsanction  val enqDelayDataSources         = Wire(Vec(params.numRegSrc, DataSource()))
42f57d73d6Ssinsanction  val enqDelayExuSources          = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, ExuSource())))
43ec49b127Ssinsanction  val enqDelaySrcLoadDependency   = Wire(Vec(params.numRegSrc, Vec(LoadPipelineWidth, UInt(LoadDependencyWidth.W))))
444c2a845dSsinsanction  val enqDelayUseRegCache         = OptionWrapper(params.needReadRegCache, Wire(Vec(params.numRegSrc, Bool())))
454c2a845dSsinsanction  val enqDelayRegCacheIdx         = OptionWrapper(params.needReadRegCache, Wire(Vec(params.numRegSrc, UInt(RegCacheIdxWidth.W))))
46aa2b5219Ssinsanction
475db4956bSzhanglyGit  //Reg
484243aa09SsinceforYy  val validReg = GatedValidRegNext(common.validRegNext, false.B)
4956db494fSxiaofeibao-xjtu  val entryReg = RegNext(entryRegNext)
504243aa09SsinceforYy  val enqDelayValidReg = GatedValidRegNext(enqDelayValidRegNext, false.B)
515db4956bSzhanglyGit
525db4956bSzhanglyGit  //Wire
530dfdb52aSzhanglyGit  CommonWireConnect(common, hasWakeupIQ, validReg, currentStatus, io.commonIn, true)
545db4956bSzhanglyGit
5528607074Ssinsanction  when(io.commonIn.enq.valid) {
56c0beb497Sxiaofeibao    assert(common.enqReady, s"${params.getIQName}'s EnqEntry is not ready when enq is valid\n")
5728607074Ssinsanction  }
5828607074Ssinsanction
59aa2bcc31SzhanglyGit  when(io.commonIn.enq.valid && common.enqReady) {
60aa2bcc31SzhanglyGit    entryRegNext := io.commonIn.enq.bits
615db4956bSzhanglyGit  }.otherwise {
625db4956bSzhanglyGit    entryRegNext := entryUpdate
635db4956bSzhanglyGit  }
645db4956bSzhanglyGit
65aa2bcc31SzhanglyGit  when(io.commonIn.enq.valid && common.enqReady) {
66aa2b5219Ssinsanction    enqDelayValidRegNext := true.B
67aa2b5219Ssinsanction  }.otherwise {
68aa2b5219Ssinsanction    enqDelayValidRegNext := false.B
69aa2b5219Ssinsanction  }
70aa2b5219Ssinsanction
715db4956bSzhanglyGit  if (params.hasIQWakeUp) {
72aa2bcc31SzhanglyGit    ShiftLoadDependency(hasWakeupIQ.get)
730dfdb52aSzhanglyGit    CommonIQWakeupConnect(common, hasWakeupIQ.get, validReg, currentStatus, io.commonIn, true)
745db4956bSzhanglyGit  }
755db4956bSzhanglyGit
76aa2b5219Ssinsanction  // enq delay wakeup
774fa640e4Ssinsanction  val enqDelayOut1         = Wire(new EnqDelayOutBundle)
784fa640e4Ssinsanction  val enqDelayOut2         = Wire(new EnqDelayOutBundle)
794fa640e4Ssinsanction  EnqDelayWakeupConnect(io.enqDelayIn1, enqDelayOut1, entryReg.status, delay = 1)
804fa640e4Ssinsanction  EnqDelayWakeupConnect(io.enqDelayIn2, enqDelayOut2, entryReg.status, delay = 2)
81aa2b5219Ssinsanction
82aa2b5219Ssinsanction  for (i <- 0 until params.numRegSrc) {
834fa640e4Ssinsanction    val enqDelay1WakeUpValid = enqDelayOut1.srcWakeUpByIQVec(i).asUInt.orR
844fa640e4Ssinsanction    val enqDelay1WakeUpOH    = enqDelayOut1.srcWakeUpByIQVec(i)
854fa640e4Ssinsanction    val enqDelay2WakeUpOH    = enqDelayOut2.srcWakeUpByIQVec(i)
86de111a36Ssinsanction    val enqDelay1IsWakeupByMemIQ = enqDelay1WakeUpOH.zip(io.commonIn.wakeUpFromIQ).filter(_._2.bits.params.isMemExeUnit).map(_._1).fold(false.B)(_ || _)
87de111a36Ssinsanction    val enqDelay2IsWakeupByMemIQ = enqDelay2WakeUpOH.zip(io.commonIn.wakeUpFromIQ).filter(_._2.bits.params.isMemExeUnit).map(_._1).fold(false.B)(_ || _)
8809d562eeSsinsanction    val enqDelay2IsWakeupByVfIQ  = enqDelay2WakeUpOH.zip(io.commonIn.wakeUpFromIQ).filter(_._2.bits.params.isVfExeUnit).map(_._1).fold(false.B)(_ || _)
89de111a36Ssinsanction
90c4cabf18Ssinsanction    if (params.inVfSchd && params.readVfRf && params.hasIQWakeUp) {
91c4cabf18Ssinsanction      enqDelayDataSources(i).value            := MuxCase(entryReg.status.srcStatus(i).dataSources.value, Seq(
92c4cabf18Ssinsanction                                                    (enqDelayOut1.srcWakeUpByIQ(i).asBool && !enqDelay1IsWakeupByMemIQ)  -> DataSource.bypass,
93c4cabf18Ssinsanction                                                    (enqDelayOut1.srcWakeUpByIQ(i).asBool && enqDelay1IsWakeupByMemIQ)   -> DataSource.bypass2,
94c4cabf18Ssinsanction                                                    (enqDelayOut2.srcWakeUpByIQ(i).asBool && !enqDelay2IsWakeupByMemIQ)  -> DataSource.bypass2,
95c4cabf18Ssinsanction                                                 ))
96f57d73d6Ssinsanction      enqDelayExuSources.get(i).value         := Mux(enqDelay1WakeUpValid,
97f57d73d6Ssinsanction                                                      ExuSource().fromExuOH(params, Mux1H(enqDelay1WakeUpOH, params.wakeUpSourceExuIdx.map(x => MathUtils.IntToOH(x).U(backendParams.numExu.W)))),
98f57d73d6Ssinsanction                                                      ExuSource().fromExuOH(params, Mux1H(enqDelay2WakeUpOH, params.wakeUpSourceExuIdx.map(x => MathUtils.IntToOH(x).U(backendParams.numExu.W)))))
99c4cabf18Ssinsanction    }
100c4cabf18Ssinsanction    else if (params.inMemSchd && params.readVfRf && params.hasIQWakeUp) {
101c4cabf18Ssinsanction      enqDelayDataSources(i).value            := MuxCase(entryReg.status.srcStatus(i).dataSources.value, Seq(
102c4cabf18Ssinsanction                                                    enqDelayOut1.srcWakeUpByIQ(i).asBool                                 -> DataSource.bypass,
10309d562eeSsinsanction                                                    (enqDelayOut2.srcWakeUpByIQ(i).asBool && enqDelay2IsWakeupByVfIQ)    -> DataSource.bypass2,
104c4cabf18Ssinsanction                                                 ))
105f57d73d6Ssinsanction      enqDelayExuSources.get(i).value         := Mux(enqDelay1WakeUpValid,
106f57d73d6Ssinsanction                                                      ExuSource().fromExuOH(params, Mux1H(enqDelay1WakeUpOH, params.wakeUpSourceExuIdx.map(x => MathUtils.IntToOH(x).U(backendParams.numExu.W)))),
107f57d73d6Ssinsanction                                                      ExuSource().fromExuOH(params, Mux1H(enqDelay2WakeUpOH, params.wakeUpSourceExuIdx.map(x => MathUtils.IntToOH(x).U(backendParams.numExu.W)))))
108c4cabf18Ssinsanction    }
109c4cabf18Ssinsanction    else {
1104fa640e4Ssinsanction      enqDelayDataSources(i).value            := Mux(enqDelayOut1.srcWakeUpByIQ(i).asBool, DataSource.bypass, entryReg.status.srcStatus(i).dataSources.value)
111aa2b5219Ssinsanction      if (params.hasIQWakeUp) {
112f57d73d6Ssinsanction        enqDelayExuSources.get(i).value       := ExuSource().fromExuOH(params, Mux1H(enqDelay1WakeUpOH, params.wakeUpSourceExuIdx.map(x => MathUtils.IntToOH(x).U(backendParams.numExu.W))))
1134fa640e4Ssinsanction      }
1144fa640e4Ssinsanction    }
1154fa640e4Ssinsanction
11691f31488Sxiaofeibao-xjtu    enqDelaySrcState(i)                     := (!enqDelayOut1.srcCancelByLoad(i) & entryReg.status.srcStatus(i).srcState) | enqDelayOut1.srcWakeUpByWB(i) | enqDelayOut1.srcWakeUpByIQ(i)
1174fa640e4Ssinsanction    if (params.hasIQWakeUp) {
118c4cabf18Ssinsanction      enqDelaySrcLoadDependency(i)          := Mux(enqDelay1WakeUpValid, Mux1H(enqDelay1WakeUpOH, enqDelayOut1.shiftedWakeupLoadDependencyByIQVec), entryReg.status.srcStatus(i).srcLoadDependency)
119eea4a3caSzhanglyGit    } else {
120eea4a3caSzhanglyGit      enqDelaySrcLoadDependency(i)          := entryReg.status.srcStatus(i).srcLoadDependency
121aa2b5219Ssinsanction    }
1224c2a845dSsinsanction
1234c2a845dSsinsanction    if (params.needReadRegCache) {
1244c2a845dSsinsanction      val enqDelay1WakeupSrcExuWriteRC = enqDelay1WakeUpOH.zip(io.enqDelayIn1.wakeUpFromIQ).filter(_._2.bits.params.needWriteRegCache)
125de4e991cSsinsanction      val enqDelay1WakeupRC    = enqDelay1WakeupSrcExuWriteRC.map(_._1).fold(false.B)(_ || _) && SrcType.isXp(entryReg.status.srcStatus(i).srcType)
1264c2a845dSsinsanction      val enqDelay1WakeupRCIdx = Mux1H(enqDelay1WakeupSrcExuWriteRC.map(_._1), enqDelay1WakeupSrcExuWriteRC.map(_._2.bits.rcDest.get))
1274c2a845dSsinsanction      val enqDelay1ReplaceRC   = enqDelay1WakeupSrcExuWriteRC.map(x => x._2.bits.rfWen && x._2.bits.rcDest.get === entryReg.status.srcStatus(i).regCacheIdx.get).fold(false.B)(_ || _)
1284c2a845dSsinsanction
129e311c278Ssinsanction      enqDelayUseRegCache.get(i)            := entryReg.status.srcStatus(i).useRegCache.get && !(enqDelayOut1.srcCancelByLoad(i) || enqDelay1ReplaceRC) || enqDelay1WakeupRC
1304c2a845dSsinsanction      enqDelayRegCacheIdx.get(i)            := Mux(enqDelay1WakeupRC, enqDelay1WakeupRCIdx, entryReg.status.srcStatus(i).regCacheIdx.get)
1314c2a845dSsinsanction    }
132aa2b5219Ssinsanction  }
1334fa640e4Ssinsanction
1344fa640e4Ssinsanction  // current status
135aa2b5219Ssinsanction  currentStatus                             := entryReg.status
136aa2b5219Ssinsanction  when (enqDelayValidReg) {
137aa2bcc31SzhanglyGit    currentStatus.srcStatus.zipWithIndex.foreach { case (srcStatus, srcIdx) =>
138aa2bcc31SzhanglyGit      srcStatus.srcState                    := enqDelaySrcState(srcIdx)
139aa2bcc31SzhanglyGit      srcStatus.dataSources                 := enqDelayDataSources(srcIdx)
140eea4a3caSzhanglyGit      srcStatus.srcLoadDependency           := enqDelaySrcLoadDependency(srcIdx)
1414c2a845dSsinsanction      srcStatus.useRegCache.foreach(_       := enqDelayUseRegCache.get(srcIdx))
1424c2a845dSsinsanction      srcStatus.regCacheIdx.foreach(_       := enqDelayRegCacheIdx.get(srcIdx))
143aa2bcc31SzhanglyGit    }
144aa2b5219Ssinsanction  }
145aa2b5219Ssinsanction
146acf41503Ssinsanction  if (params.hasIQWakeUp) {
147f57d73d6Ssinsanction    currentStatus.srcStatus.map(_.exuSources.get).zip(entryReg.status.srcStatus.map(_.exuSources.get)).zip(enqDelayExuSources.get).foreach {
148f57d73d6Ssinsanction      case ((currExu, regExu), enqDelayExu) =>
149f57d73d6Ssinsanction        currExu := Mux(enqDelayValidReg, enqDelayExu, regExu)
150acf41503Ssinsanction    }
151acf41503Ssinsanction  }
152acf41503Ssinsanction
153e311c278Ssinsanction  EntryRegCommonConnect(common, hasWakeupIQ, validReg, entryUpdate, entryReg, currentStatus, io.commonIn, true, isComp)
154e08589a5Ssinsanction
155397c0f33Ssinsanction  //output
156df26db8aSsinsanction  CommonOutConnect(io.commonOut, common, hasWakeupIQ, validReg, entryUpdate, entryReg, currentStatus, io.commonIn, true, isComp)
1575db4956bSzhanglyGit}
1585db4956bSzhanglyGit
159e07131b2Ssinsanctionclass EnqEntryVecMem(isComp: Boolean)(implicit p: Parameters, params: IssueBlockParams) extends EnqEntry(isComp)
1602d270511Ssinsanction  with HasCircularQueuePtrHelper {
1612d270511Ssinsanction
162e07131b2Ssinsanction  require(params.isVecMemIQ, "EnqEntryVecMem can only be instance of VecMem IQ")
1632d270511Ssinsanction
164e07131b2Ssinsanction  EntryVecMemConnect(io.commonIn, common, validReg, entryReg, entryRegNext, entryUpdate)
1652d270511Ssinsanction}
1662d270511Ssinsanction
1675db4956bSzhanglyGitobject EnqEntry {
168df26db8aSsinsanction  def apply(isComp: Boolean)(implicit p: Parameters, iqParams: IssueBlockParams): EnqEntry = {
1695db4956bSzhanglyGit    iqParams.schdType match {
170df26db8aSsinsanction      case IntScheduler() => new EnqEntry(isComp)
17160f0c5aeSxiaofeibao      case FpScheduler()  => new EnqEntry(isComp)
1725db4956bSzhanglyGit      case MemScheduler() =>
173e07131b2Ssinsanction        if (iqParams.isVecMemIQ) new EnqEntryVecMem(isComp)
174df26db8aSsinsanction        else new EnqEntry(isComp)
175df26db8aSsinsanction      case VfScheduler() => new EnqEntry(isComp)
1765db4956bSzhanglyGit      case _ => null
1775db4956bSzhanglyGit    }
1785db4956bSzhanglyGit  }
1795db4956bSzhanglyGit}
180