xref: /XiangShan/src/main/scala/xiangshan/backend/issue/EnqEntry.scala (revision 0dfdb52aea96edff04a5ddb3fd1531dc005913ef)
15db4956bSzhanglyGitpackage xiangshan.backend.issue
25db4956bSzhanglyGit
383ba63b3SXuan Huimport org.chipsalliance.cde.config.Parameters
45db4956bSzhanglyGitimport chisel3._
55db4956bSzhanglyGitimport chisel3.util._
65db4956bSzhanglyGitimport utility.HasCircularQueuePtrHelper
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
20aa2b5219Ssinsanction  val enqDelayWakeUpFromWB: MixedVec[ValidIO[IssueQueueWBWakeUpBundle]] = Flipped(params.genWBWakeUpSinkValidBundle)
21aa2b5219Ssinsanction  val enqDelayWakeUpFromIQ: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(params.genIQWakeUpSinkValidBundle)
22aa2b5219Ssinsanction  val enqDelayOg0Cancel   = Input(ExuOH(backendParams.numExu))
237cbafe1aSzhanglyGit  val enqDelayLdCancel    = Vec(backendParams.LdExuCnt, Flipped(new LoadCancelIO))
245db4956bSzhanglyGit
25aa2bcc31SzhanglyGit  //output
26aa2bcc31SzhanglyGit  val commonOut           = new CommonOutBundle
27aa2bcc31SzhanglyGit  val transEntry          = ValidIO(new EntryBundle)
28aa2bcc31SzhanglyGit
29aa2bcc31SzhanglyGit  def wakeup              = commonIn.wakeUpFromWB ++ commonIn.wakeUpFromIQ
305db4956bSzhanglyGit}
315db4956bSzhanglyGit
325db4956bSzhanglyGitclass EnqEntry(implicit p: Parameters, params: IssueBlockParams) extends XSModule {
335db4956bSzhanglyGit  val io = IO(new EnqEntryIO)
345db4956bSzhanglyGit
355db4956bSzhanglyGit  val validReg            = RegInit(false.B)
36aa2b5219Ssinsanction  val enqDelayValidReg    = RegInit(false.B)
37aa2bcc31SzhanglyGit  val entryReg            = Reg(new EntryBundle)
385db4956bSzhanglyGit
39aa2bcc31SzhanglyGit  val common              = Wire(new CommonWireBundle)
405db4956bSzhanglyGit  val entryUpdate         = Wire(new EntryBundle)
41aa2bcc31SzhanglyGit  val entryRegNext        = Wire(new EntryBundle)
42aa2b5219Ssinsanction  val enqDelayValidRegNext= Wire(Bool())
43aa2bcc31SzhanglyGit  val hasWakeupIQ         = OptionWrapper(params.hasIQWakeUp, Wire(new CommonIQWakeupBundle))
445db4956bSzhanglyGit
45aa2b5219Ssinsanction  val currentStatus               = Wire(new Status())
46aa2b5219Ssinsanction  val enqDelaySrcState            = Wire(Vec(params.numRegSrc, SrcState()))
47aa2b5219Ssinsanction  val enqDelayDataSources         = Wire(Vec(params.numRegSrc, DataSource()))
48aa2b5219Ssinsanction  val enqDelaySrcWakeUpL1ExuOH    = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, ExuOH())))
49aa2b5219Ssinsanction  val enqDelaySrcTimer            = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, UInt(3.W))))
50aa2b5219Ssinsanction  val enqDelaySrcLoadDependency   = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, Vec(LoadPipelineWidth, UInt(3.W)))))
51aa2b5219Ssinsanction
52aa2b5219Ssinsanction  val enqDelaySrcWakeUpByWB: Vec[UInt]                            = Wire(Vec(params.numRegSrc, SrcState()))
53aa2b5219Ssinsanction  val enqDelaySrcWakeUpByIQ: Vec[UInt]                            = Wire(Vec(params.numRegSrc, SrcState()))
54aa2b5219Ssinsanction  val enqDelaySrcWakeUpByIQVec: Vec[Vec[Bool]]                    = Wire(Vec(params.numRegSrc, Vec(params.numWakeupFromIQ, Bool())))
55aa2b5219Ssinsanction  val enqDelayShiftedWakeupLoadDependencyByIQVec: Vec[Vec[UInt]]  = Wire(Vec(params.numWakeupFromIQ, Vec(LoadPipelineWidth, UInt(3.W))))
56aa2b5219Ssinsanction
575db4956bSzhanglyGit  //Reg
58aa2bcc31SzhanglyGit  validReg                        := common.validRegNext
595db4956bSzhanglyGit  entryReg                        := entryRegNext
60aa2b5219Ssinsanction  enqDelayValidReg                := enqDelayValidRegNext
615db4956bSzhanglyGit
625db4956bSzhanglyGit  //Wire
63*0dfdb52aSzhanglyGit  CommonWireConnect(common, hasWakeupIQ, validReg, currentStatus, io.commonIn, true)
645db4956bSzhanglyGit
65aa2bcc31SzhanglyGit  when(io.commonIn.enq.valid && common.enqReady) {
66aa2bcc31SzhanglyGit    entryRegNext := io.commonIn.enq.bits
675db4956bSzhanglyGit  }.otherwise {
685db4956bSzhanglyGit    entryRegNext := entryUpdate
695db4956bSzhanglyGit  }
705db4956bSzhanglyGit
71aa2bcc31SzhanglyGit  when(io.commonIn.enq.valid && common.enqReady) {
72aa2b5219Ssinsanction    enqDelayValidRegNext := true.B
73aa2b5219Ssinsanction  }.otherwise {
74aa2b5219Ssinsanction    enqDelayValidRegNext := false.B
75aa2b5219Ssinsanction  }
76aa2b5219Ssinsanction
775db4956bSzhanglyGit  if (params.hasIQWakeUp) {
78aa2bcc31SzhanglyGit    ShiftLoadDependency(hasWakeupIQ.get)
79*0dfdb52aSzhanglyGit    CommonIQWakeupConnect(common, hasWakeupIQ.get, validReg, currentStatus, io.commonIn, true)
805db4956bSzhanglyGit  }
815db4956bSzhanglyGit
82aa2b5219Ssinsanction  // enq delay wakeup
83aa2b5219Ssinsanction  enqDelaySrcWakeUpByWB.zipWithIndex.foreach { case (wakeup, i) =>
84aa2bcc31SzhanglyGit    wakeup := io.enqDelayWakeUpFromWB.map(x => x.bits.wakeUp(Seq((entryReg.status.srcStatus(i).psrc, entryReg.status.srcStatus(i).srcType)), x.valid).head
85aa2b5219Ssinsanction    ).reduce(_ || _)
86aa2b5219Ssinsanction  }
87aa2b5219Ssinsanction
88aa2b5219Ssinsanction  if (params.hasIQWakeUp) {
89aa2b5219Ssinsanction    val wakeupVec: IndexedSeq[IndexedSeq[Bool]] = io.enqDelayWakeUpFromIQ.map( x =>
90aa2bcc31SzhanglyGit      x.bits.wakeUpFromIQ(entryReg.status.srcStatus.map(_.psrc) zip entryReg.status.srcStatus.map(_.srcType))
91aa2b5219Ssinsanction    ).toIndexedSeq.transpose
92d20f567fSzhanglyGit    val cancelSel = params.wakeUpSourceExuIdx.zip(io.enqDelayWakeUpFromIQ).map{ case (x, y) => io.enqDelayOg0Cancel(x) && y.bits.is0Lat}
93aa2b5219Ssinsanction    enqDelaySrcWakeUpByIQVec := wakeupVec.map(x => VecInit(x.zip(cancelSel).map { case (wakeup, cancel) => wakeup && !cancel }))
94aa2b5219Ssinsanction  } else {
95aa2b5219Ssinsanction    enqDelaySrcWakeUpByIQVec := 0.U.asTypeOf(enqDelaySrcWakeUpByIQVec)
96aa2b5219Ssinsanction  }
97aa2b5219Ssinsanction
98aa2b5219Ssinsanction  if (params.hasIQWakeUp) {
99aa2b5219Ssinsanction    enqDelaySrcWakeUpByIQ.zipWithIndex.foreach { case (wakeup, i) =>
100aa2b5219Ssinsanction      val ldTransCancel = Mux1H(enqDelaySrcWakeUpByIQVec(i), io.enqDelayWakeUpFromIQ.map(_.bits.loadDependency).map(dp => LoadShouldCancel(Some(dp), io.enqDelayLdCancel)).toSeq)
101aa2b5219Ssinsanction      wakeup := enqDelaySrcWakeUpByIQVec(i).asUInt.orR && !ldTransCancel
102aa2b5219Ssinsanction    }
103aa2b5219Ssinsanction  } else {
104aa2b5219Ssinsanction    enqDelaySrcWakeUpByIQ := 0.U.asTypeOf(enqDelaySrcWakeUpByIQ)
105aa2b5219Ssinsanction  }
106aa2b5219Ssinsanction
107aa2b5219Ssinsanction  enqDelayShiftedWakeupLoadDependencyByIQVec.zip(io.enqDelayWakeUpFromIQ.map(_.bits.loadDependency))
108aa2b5219Ssinsanction    .zip(params.wakeUpInExuSources.map(_.name)).foreach { case ((dps, ldps), name) =>
109aa2b5219Ssinsanction    dps.zip(ldps).zipWithIndex.foreach { case ((dp, ldp), deqPortIdx) =>
110aa2b5219Ssinsanction      if (params.backendParam.getLdExuIdx(params.backendParam.allExuParams.find(_.name == name).get) == deqPortIdx)
111aa2b5219Ssinsanction        dp := (ldp << 2).asUInt | 2.U
112aa2b5219Ssinsanction      else
113aa2b5219Ssinsanction        dp := ldp << 1
114aa2b5219Ssinsanction    }
115aa2b5219Ssinsanction  }
116aa2b5219Ssinsanction
117aa2b5219Ssinsanction  for (i <- 0 until params.numRegSrc) {
118aa2bcc31SzhanglyGit    enqDelaySrcState(i)                     := entryReg.status.srcStatus(i).srcState | enqDelaySrcWakeUpByWB(i) | enqDelaySrcWakeUpByIQ(i)
119aa2b5219Ssinsanction    enqDelayDataSources(i).value            := Mux(enqDelaySrcWakeUpByIQ(i).asBool, DataSource.bypass, DataSource.reg)
120aa2b5219Ssinsanction    if (params.hasIQWakeUp) {
121aa2b5219Ssinsanction      val wakeUpValid = enqDelaySrcWakeUpByIQVec(i).asUInt.orR
122aa2b5219Ssinsanction      val wakeUpOH = enqDelaySrcWakeUpByIQVec(i)
123acf41503Ssinsanction      enqDelaySrcWakeUpL1ExuOH.get(i)       := Mux1H(wakeUpOH, params.wakeUpSourceExuIdx.map(x => MathUtils.IntToOH(x).U(backendParams.numExu.W)).toSeq)
124aa2b5219Ssinsanction      enqDelaySrcTimer.get(i)               := Mux(wakeUpValid, 2.U, 3.U)
125aa2bcc31SzhanglyGit      enqDelaySrcLoadDependency.get(i)      := Mux(wakeUpValid, Mux1H(wakeUpOH, enqDelayShiftedWakeupLoadDependencyByIQVec), entryReg.status.srcStatus(i).srcLoadDependency.get)
126aa2b5219Ssinsanction    }
127aa2b5219Ssinsanction  }
128aa2b5219Ssinsanction  currentStatus                             := entryReg.status
129aa2b5219Ssinsanction  when (enqDelayValidReg) {
130aa2bcc31SzhanglyGit    currentStatus.srcStatus.zipWithIndex.foreach { case (srcStatus, srcIdx) =>
131aa2bcc31SzhanglyGit      srcStatus.srcState                    := enqDelaySrcState(srcIdx)
132aa2bcc31SzhanglyGit      srcStatus.dataSources                 := enqDelayDataSources(srcIdx)
133aa2bcc31SzhanglyGit      srcStatus.srcTimer.foreach(_          := enqDelaySrcTimer.get(srcIdx))
134aa2bcc31SzhanglyGit      srcStatus.srcLoadDependency.foreach(_ := enqDelaySrcLoadDependency.get(srcIdx))
135aa2bcc31SzhanglyGit    }
136aa2b5219Ssinsanction  }
137aa2b5219Ssinsanction
138acf41503Ssinsanction  if (params.hasIQWakeUp) {
139aa2bcc31SzhanglyGit    currentStatus.srcStatus.map(_.srcWakeUpL1ExuOH.get).zip(entryReg.status.srcStatus.map(_.srcWakeUpL1ExuOH.get)).zip(enqDelaySrcWakeUpL1ExuOH.get).foreach {
140acf41503Ssinsanction      case ((currExuOH, regExuOH), enqDelayExuOH) =>
141acf41503Ssinsanction        currExuOH := 0.U.asTypeOf(currExuOH)
142acf41503Ssinsanction        params.wakeUpSourceExuIdx.foreach(x => currExuOH(x) := Mux(enqDelayValidReg, enqDelayExuOH(x), regExuOH(x)))
143acf41503Ssinsanction    }
144acf41503Ssinsanction  }
145acf41503Ssinsanction
146aa2bcc31SzhanglyGit  EntryRegCommonConnect(common, hasWakeupIQ, validReg, entryUpdate, entryReg, currentStatus, io.commonIn, true)
147e08589a5Ssinsanction
148aa2bcc31SzhanglyGit  CommonOutConnect(io.commonOut, common, hasWakeupIQ, validReg, entryReg, currentStatus, io.commonIn, true)
149aa2bcc31SzhanglyGit  io.transEntry.valid := validReg && !common.flushed && !common.deqSuccess
1505db4956bSzhanglyGit  io.transEntry.bits := entryUpdate
1515db4956bSzhanglyGit}
1525db4956bSzhanglyGit
1535db4956bSzhanglyGitclass EnqEntryMem()(implicit p: Parameters, params: IssueBlockParams) extends EnqEntry
1545db4956bSzhanglyGit  with HasCircularQueuePtrHelper {
155aa2bcc31SzhanglyGit  entryUpdate.status.blocked                        := EntryMemConnect(io.commonIn, common, validReg, entryReg, entryRegNext, true)
1565db4956bSzhanglyGit  val memStatusUpdate                                = entryUpdate.status.mem.get
157aa2bcc31SzhanglyGit  val memStatus                                      = entryReg.status.mem.get
158aa2bcc31SzhanglyGit  val deqFailedForStdInvalid                         = io.commonIn.issueResp.valid && io.commonIn.issueResp.bits.respType === RSFeedbackType.dataInvalid
1595db4956bSzhanglyGit
1605db4956bSzhanglyGit  when(deqFailedForStdInvalid) {
161aa2bcc31SzhanglyGit    memStatusUpdate.waitForSqIdx                    := io.commonIn.issueResp.bits.dataInvalidSqIdx
1625db4956bSzhanglyGit    memStatusUpdate.waitForRobIdx                   := memStatus.waitForRobIdx
1635db4956bSzhanglyGit    memStatusUpdate.waitForStd                      := true.B
1645db4956bSzhanglyGit    memStatusUpdate.strictWait                      := memStatus.strictWait
1655db4956bSzhanglyGit    memStatusUpdate.sqIdx                           := memStatus.sqIdx
1665db4956bSzhanglyGit  }.otherwise {
1675db4956bSzhanglyGit    memStatusUpdate                                 := memStatus
1685db4956bSzhanglyGit  }
1695db4956bSzhanglyGit
1705db4956bSzhanglyGit}
1715db4956bSzhanglyGit
1722d270511Ssinsanctionclass EnqEntryVecMemAddr()(implicit p: Parameters, params: IssueBlockParams) extends EnqEntryMem {
1732d270511Ssinsanction
1742d270511Ssinsanction  require(params.isVecMemAddrIQ, "EnqEntryVecMemAddr can only be instance of VecMemAddr IQ")
1752d270511Ssinsanction
1762d270511Ssinsanction  val vecMemStatus = entryReg.status.vecMem.get
1772d270511Ssinsanction  val vecMemStatusNext = entryRegNext.status.vecMem.get
1782d270511Ssinsanction  val vecMemStatusUpdate = entryUpdate.status.vecMem.get
179aa2bcc31SzhanglyGit  val fromLsq = io.commonIn.fromLsq.get
1802d270511Ssinsanction
181aa2bcc31SzhanglyGit  when (io.commonIn.enq.valid && common.enqReady) {
182aa2bcc31SzhanglyGit    vecMemStatusNext.sqIdx := io.commonIn.enq.bits.status.vecMem.get.sqIdx
183aa2bcc31SzhanglyGit    vecMemStatusNext.lqIdx := io.commonIn.enq.bits.status.vecMem.get.lqIdx
1842d270511Ssinsanction  }.otherwise {
1852d270511Ssinsanction    vecMemStatusNext := vecMemStatusUpdate
1862d270511Ssinsanction  }
1872d270511Ssinsanction  vecMemStatusUpdate := vecMemStatus
1882d270511Ssinsanction
1892d270511Ssinsanction  val isLsqHead = {
19029b863e5Szhanglinjuan    // if (params.isVecLdAddrIQ)
19131c1fcd8Szhanglinjuan      entryRegNext.status.vecMem.get.lqIdx <= fromLsq.lqDeqPtr &&
19229b863e5Szhanglinjuan    // else
19331c1fcd8Szhanglinjuan      entryRegNext.status.vecMem.get.sqIdx <= fromLsq.sqDeqPtr
1942d270511Ssinsanction  }
1952d270511Ssinsanction
196aa2bcc31SzhanglyGit  entryUpdate.status.vecMem.get.uopIdx := entryReg.status.vecMem.get.uopIdx
1972d270511Ssinsanction}
1982d270511Ssinsanction
1992d270511Ssinsanctionclass EnqEntryVecMemData()(implicit p: Parameters, params: IssueBlockParams) extends EnqEntry
2002d270511Ssinsanction  with HasCircularQueuePtrHelper {
2012d270511Ssinsanction
2022d270511Ssinsanction  require(params.isVecStDataIQ, "EnqEntryVecMemData can only be instance of VecMemData IQ")
2032d270511Ssinsanction
2042d270511Ssinsanction  val vecMemStatus = entryReg.status.vecMem.get
2052d270511Ssinsanction  val vecMemStatusNext = entryRegNext.status.vecMem.get
2062d270511Ssinsanction  val vecMemStatusUpdate = entryUpdate.status.vecMem.get
207aa2bcc31SzhanglyGit  val fromLsq = io.commonIn.fromLsq.get
2082d270511Ssinsanction
209aa2bcc31SzhanglyGit  when (io.commonIn.enq.valid && common.enqReady) {
210aa2bcc31SzhanglyGit    vecMemStatusNext.sqIdx := io.commonIn.enq.bits.status.vecMem.get.sqIdx
211aa2bcc31SzhanglyGit    vecMemStatusNext.lqIdx := io.commonIn.enq.bits.status.vecMem.get.lqIdx
2122d270511Ssinsanction  }.otherwise {
2132d270511Ssinsanction    vecMemStatusNext := vecMemStatusUpdate
2142d270511Ssinsanction  }
2152d270511Ssinsanction  vecMemStatusUpdate := vecMemStatus
2162d270511Ssinsanction
2172d270511Ssinsanction  val isLsqHead = entryRegNext.status.vecMem.get.sqIdx.value === fromLsq.sqDeqPtr.value
2182d270511Ssinsanction
2192d270511Ssinsanction  entryRegNext.status.blocked := !isLsqHead
2202d270511Ssinsanction  entryUpdate.status.blocked := !isLsqHead
221aa2bcc31SzhanglyGit  entryUpdate.status.vecMem.get.uopIdx := entryReg.status.vecMem.get.uopIdx
2222d270511Ssinsanction}
2232d270511Ssinsanction
2245db4956bSzhanglyGitobject EnqEntry {
2255db4956bSzhanglyGit  def apply(implicit p: Parameters, iqParams: IssueBlockParams): EnqEntry = {
2265db4956bSzhanglyGit    iqParams.schdType match {
2275db4956bSzhanglyGit      case IntScheduler() => new EnqEntry()
2285db4956bSzhanglyGit      case MemScheduler() =>
22997b279b9SXuan Hu        if (iqParams.isLdAddrIQ || iqParams.isStAddrIQ || iqParams.isHyAddrIQ) new EnqEntryMem()
2302d270511Ssinsanction        else if (iqParams.isVecMemAddrIQ) new EnqEntryVecMemAddr()
2312d270511Ssinsanction        else if (iqParams.isVecStDataIQ) new EnqEntryVecMemData()
2325db4956bSzhanglyGit        else new EnqEntry()
2335db4956bSzhanglyGit      case VfScheduler() => new EnqEntry()
2345db4956bSzhanglyGit      case _ => null
2355db4956bSzhanglyGit    }
2365db4956bSzhanglyGit  }
2375db4956bSzhanglyGit}