xref: /XiangShan/src/main/scala/xiangshan/backend/issue/EnqEntry.scala (revision 4fa640e46b60470adc3cf9552409056fb74278cc)
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._
142d270511Ssinsanctionimport xiangshan.mem.{MemWaitUpdateReq, SqPtr, LqPtr}
155db4956bSzhanglyGit
165db4956bSzhanglyGit
175db4956bSzhanglyGitclass EnqEntryIO(implicit p: Parameters, params: IssueBlockParams) extends XSBundle {
185db4956bSzhanglyGit  //input
19aa2bcc31SzhanglyGit  val commonIn            = new CommonInBundle
20*4fa640e4Ssinsanction  val enqDelayIn1         = new EnqDelayInBundle
21*4fa640e4Ssinsanction  val enqDelayIn2         = new EnqDelayInBundle
225db4956bSzhanglyGit
23aa2bcc31SzhanglyGit  //output
24aa2bcc31SzhanglyGit  val commonOut           = new CommonOutBundle
25aa2bcc31SzhanglyGit
26aa2bcc31SzhanglyGit  def wakeup              = commonIn.wakeUpFromWB ++ commonIn.wakeUpFromIQ
275db4956bSzhanglyGit}
285db4956bSzhanglyGit
29df26db8aSsinsanctionclass EnqEntry(isComp: Boolean)(implicit p: Parameters, params: IssueBlockParams) extends XSModule {
305db4956bSzhanglyGit  val io = IO(new EnqEntryIO)
315db4956bSzhanglyGit
32aa2bcc31SzhanglyGit  val common              = Wire(new CommonWireBundle)
335db4956bSzhanglyGit  val entryUpdate         = Wire(new EntryBundle)
34aa2bcc31SzhanglyGit  val entryRegNext        = Wire(new EntryBundle)
35aa2b5219Ssinsanction  val enqDelayValidRegNext= Wire(Bool())
36aa2bcc31SzhanglyGit  val hasWakeupIQ         = OptionWrapper(params.hasIQWakeUp, Wire(new CommonIQWakeupBundle))
375db4956bSzhanglyGit
38aa2b5219Ssinsanction  val currentStatus               = Wire(new Status())
39aa2b5219Ssinsanction  val enqDelaySrcState            = Wire(Vec(params.numRegSrc, SrcState()))
40aa2b5219Ssinsanction  val enqDelayDataSources         = Wire(Vec(params.numRegSrc, DataSource()))
41aa2b5219Ssinsanction  val enqDelaySrcWakeUpL1ExuOH    = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, ExuOH())))
42eea4a3caSzhanglyGit  val enqDelaySrcLoadDependency   = Wire(Vec(params.numRegSrc, Vec(LoadPipelineWidth, UInt(3.W))))
43aa2b5219Ssinsanction
445db4956bSzhanglyGit  //Reg
454243aa09SsinceforYy  val validReg = GatedValidRegNext(common.validRegNext, false.B)
4641dbbdfdSsinceforYy  val entryReg = RegEnable(entryRegNext, validReg || common.validRegNext)
474243aa09SsinceforYy  val enqDelayValidReg = GatedValidRegNext(enqDelayValidRegNext, false.B)
485db4956bSzhanglyGit
495db4956bSzhanglyGit  //Wire
500dfdb52aSzhanglyGit  CommonWireConnect(common, hasWakeupIQ, validReg, currentStatus, io.commonIn, true)
515db4956bSzhanglyGit
5228607074Ssinsanction  when(io.commonIn.enq.valid) {
5328607074Ssinsanction    assert(common.enqReady, "Entry is not ready when enq is valid\n")
5428607074Ssinsanction  }
5528607074Ssinsanction
56aa2bcc31SzhanglyGit  when(io.commonIn.enq.valid && common.enqReady) {
57aa2bcc31SzhanglyGit    entryRegNext := io.commonIn.enq.bits
585db4956bSzhanglyGit  }.otherwise {
595db4956bSzhanglyGit    entryRegNext := entryUpdate
605db4956bSzhanglyGit  }
615db4956bSzhanglyGit
62aa2bcc31SzhanglyGit  when(io.commonIn.enq.valid && common.enqReady) {
63aa2b5219Ssinsanction    enqDelayValidRegNext := true.B
64aa2b5219Ssinsanction  }.otherwise {
65aa2b5219Ssinsanction    enqDelayValidRegNext := false.B
66aa2b5219Ssinsanction  }
67aa2b5219Ssinsanction
685db4956bSzhanglyGit  if (params.hasIQWakeUp) {
69aa2bcc31SzhanglyGit    ShiftLoadDependency(hasWakeupIQ.get)
700dfdb52aSzhanglyGit    CommonIQWakeupConnect(common, hasWakeupIQ.get, validReg, currentStatus, io.commonIn, true)
715db4956bSzhanglyGit  }
725db4956bSzhanglyGit
73aa2b5219Ssinsanction  // enq delay wakeup
74*4fa640e4Ssinsanction  val enqDelayOut1         = Wire(new EnqDelayOutBundle)
75*4fa640e4Ssinsanction  val enqDelayOut2         = Wire(new EnqDelayOutBundle)
76*4fa640e4Ssinsanction  EnqDelayWakeupConnect(io.enqDelayIn1, enqDelayOut1, entryReg.status, delay = 1)
77*4fa640e4Ssinsanction  EnqDelayWakeupConnect(io.enqDelayIn2, enqDelayOut2, entryReg.status, delay = 2)
78aa2b5219Ssinsanction
79aa2b5219Ssinsanction  for (i <- 0 until params.numRegSrc) {
80*4fa640e4Ssinsanction    if (params.inVfSchd && params.readVfRf && params.hasIQWakeUp) {
81*4fa640e4Ssinsanction      enqDelayDataSources(i).value            := Mux(enqDelayOut1.srcWakeUpByIQ(i).asBool,
82*4fa640e4Ssinsanction                                                      DataSource.bypass,
83*4fa640e4Ssinsanction                                                      Mux(enqDelayOut2.srcWakeUpByIQ(i).asBool, DataSource.bypass2, entryReg.status.srcStatus(i).dataSources.value))
84*4fa640e4Ssinsanction      val enqDelay1WakeUpValid = enqDelayOut1.srcWakeUpByIQVec(i).asUInt.orR
85*4fa640e4Ssinsanction      val enqDelay1WakeUpOH    = enqDelayOut1.srcWakeUpByIQVec(i)
86*4fa640e4Ssinsanction      val enqDelay2WakeUpOH    = enqDelayOut2.srcWakeUpByIQVec(i)
87*4fa640e4Ssinsanction      enqDelaySrcWakeUpL1ExuOH.get(i)         := Mux(enqDelay1WakeUpValid,
88*4fa640e4Ssinsanction                                                      Mux1H(enqDelay1WakeUpOH, params.wakeUpSourceExuIdx.map(x => MathUtils.IntToOH(x).U(backendParams.numExu.W))),
89*4fa640e4Ssinsanction                                                      Mux1H(enqDelay2WakeUpOH, params.wakeUpSourceExuIdx.map(x => MathUtils.IntToOH(x).U(backendParams.numExu.W))))
90*4fa640e4Ssinsanction    } else {
91*4fa640e4Ssinsanction      enqDelayDataSources(i).value            := Mux(enqDelayOut1.srcWakeUpByIQ(i).asBool, DataSource.bypass, entryReg.status.srcStatus(i).dataSources.value)
92aa2b5219Ssinsanction      if (params.hasIQWakeUp) {
93*4fa640e4Ssinsanction        val wakeUpOH = enqDelayOut1.srcWakeUpByIQVec(i)
94acf41503Ssinsanction        enqDelaySrcWakeUpL1ExuOH.get(i)       := Mux1H(wakeUpOH, params.wakeUpSourceExuIdx.map(x => MathUtils.IntToOH(x).U(backendParams.numExu.W)).toSeq)
95*4fa640e4Ssinsanction      }
96*4fa640e4Ssinsanction    }
97*4fa640e4Ssinsanction
98*4fa640e4Ssinsanction    enqDelaySrcState(i)                     := entryReg.status.srcStatus(i).srcState | enqDelayOut1.srcWakeUpByWB(i) | enqDelayOut1.srcWakeUpByIQ(i)
99*4fa640e4Ssinsanction    if (params.hasIQWakeUp) {
100*4fa640e4Ssinsanction      val wakeUpValid = enqDelayOut1.srcWakeUpByIQVec(i).asUInt.orR
101*4fa640e4Ssinsanction      val wakeUpOH = enqDelayOut1.srcWakeUpByIQVec(i)
102*4fa640e4Ssinsanction      enqDelaySrcLoadDependency(i)          := Mux(wakeUpValid, Mux1H(wakeUpOH, enqDelayOut1.shiftedWakeupLoadDependencyByIQVec), entryReg.status.srcStatus(i).srcLoadDependency)
103eea4a3caSzhanglyGit    } else {
104eea4a3caSzhanglyGit      enqDelaySrcLoadDependency(i)          := entryReg.status.srcStatus(i).srcLoadDependency
105aa2b5219Ssinsanction    }
106aa2b5219Ssinsanction  }
107*4fa640e4Ssinsanction
108*4fa640e4Ssinsanction  // current status
109aa2b5219Ssinsanction  currentStatus                             := entryReg.status
110aa2b5219Ssinsanction  when (enqDelayValidReg) {
111aa2bcc31SzhanglyGit    currentStatus.srcStatus.zipWithIndex.foreach { case (srcStatus, srcIdx) =>
112aa2bcc31SzhanglyGit      srcStatus.srcState                    := enqDelaySrcState(srcIdx)
113aa2bcc31SzhanglyGit      srcStatus.dataSources                 := enqDelayDataSources(srcIdx)
114eea4a3caSzhanglyGit      srcStatus.srcLoadDependency           := enqDelaySrcLoadDependency(srcIdx)
115aa2bcc31SzhanglyGit    }
116aa2b5219Ssinsanction  }
117aa2b5219Ssinsanction
118acf41503Ssinsanction  if (params.hasIQWakeUp) {
119aa2bcc31SzhanglyGit    currentStatus.srcStatus.map(_.srcWakeUpL1ExuOH.get).zip(entryReg.status.srcStatus.map(_.srcWakeUpL1ExuOH.get)).zip(enqDelaySrcWakeUpL1ExuOH.get).foreach {
120acf41503Ssinsanction      case ((currExuOH, regExuOH), enqDelayExuOH) =>
121acf41503Ssinsanction        currExuOH := 0.U.asTypeOf(currExuOH)
122acf41503Ssinsanction        params.wakeUpSourceExuIdx.foreach(x => currExuOH(x) := Mux(enqDelayValidReg, enqDelayExuOH(x), regExuOH(x)))
123acf41503Ssinsanction    }
124acf41503Ssinsanction  }
125acf41503Ssinsanction
126aa2bcc31SzhanglyGit  EntryRegCommonConnect(common, hasWakeupIQ, validReg, entryUpdate, entryReg, currentStatus, io.commonIn, true)
127e08589a5Ssinsanction
128397c0f33Ssinsanction  //output
129df26db8aSsinsanction  CommonOutConnect(io.commonOut, common, hasWakeupIQ, validReg, entryUpdate, entryReg, currentStatus, io.commonIn, true, isComp)
1305db4956bSzhanglyGit}
1315db4956bSzhanglyGit
132e07131b2Ssinsanctionclass EnqEntryVecMem(isComp: Boolean)(implicit p: Parameters, params: IssueBlockParams) extends EnqEntry(isComp)
1332d270511Ssinsanction  with HasCircularQueuePtrHelper {
1342d270511Ssinsanction
135e07131b2Ssinsanction  require(params.isVecMemIQ, "EnqEntryVecMem can only be instance of VecMem IQ")
1362d270511Ssinsanction
137e07131b2Ssinsanction  EntryVecMemConnect(io.commonIn, common, validReg, entryReg, entryRegNext, entryUpdate)
1382d270511Ssinsanction}
1392d270511Ssinsanction
1405db4956bSzhanglyGitobject EnqEntry {
141df26db8aSsinsanction  def apply(isComp: Boolean)(implicit p: Parameters, iqParams: IssueBlockParams): EnqEntry = {
1425db4956bSzhanglyGit    iqParams.schdType match {
143df26db8aSsinsanction      case IntScheduler() => new EnqEntry(isComp)
1445db4956bSzhanglyGit      case MemScheduler() =>
145e07131b2Ssinsanction        if (iqParams.isVecMemIQ) new EnqEntryVecMem(isComp)
146df26db8aSsinsanction        else new EnqEntry(isComp)
147df26db8aSsinsanction      case VfScheduler() => new EnqEntry(isComp)
1485db4956bSzhanglyGit      case _ => null
1495db4956bSzhanglyGit    }
1505db4956bSzhanglyGit  }
1515db4956bSzhanglyGit}