xref: /XiangShan/src/main/scala/xiangshan/backend/issue/EnqEntry.scala (revision 4243aa09225ffb7b71ce68fd9a01299dce92729c)
15db4956bSzhanglyGitpackage xiangshan.backend.issue
25db4956bSzhanglyGit
383ba63b3SXuan Huimport org.chipsalliance.cde.config.Parameters
45db4956bSzhanglyGitimport chisel3._
55db4956bSzhanglyGitimport chisel3.util._
6*4243aa09SsinceforYyimport 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
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
28aa2bcc31SzhanglyGit  def wakeup              = commonIn.wakeUpFromWB ++ commonIn.wakeUpFromIQ
295db4956bSzhanglyGit}
305db4956bSzhanglyGit
31df26db8aSsinsanctionclass EnqEntry(isComp: Boolean)(implicit p: Parameters, params: IssueBlockParams) extends XSModule {
325db4956bSzhanglyGit  val io = IO(new EnqEntryIO)
335db4956bSzhanglyGit
34aa2bcc31SzhanglyGit  val common              = Wire(new CommonWireBundle)
355db4956bSzhanglyGit  val entryUpdate         = Wire(new EntryBundle)
36aa2bcc31SzhanglyGit  val entryRegNext        = Wire(new EntryBundle)
37aa2b5219Ssinsanction  val enqDelayValidRegNext= Wire(Bool())
38aa2bcc31SzhanglyGit  val hasWakeupIQ         = OptionWrapper(params.hasIQWakeUp, Wire(new CommonIQWakeupBundle))
395db4956bSzhanglyGit
40aa2b5219Ssinsanction  val currentStatus               = Wire(new Status())
41aa2b5219Ssinsanction  val enqDelaySrcState            = Wire(Vec(params.numRegSrc, SrcState()))
42aa2b5219Ssinsanction  val enqDelayDataSources         = Wire(Vec(params.numRegSrc, DataSource()))
43aa2b5219Ssinsanction  val enqDelaySrcWakeUpL1ExuOH    = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, ExuOH())))
44aa2b5219Ssinsanction  val enqDelaySrcTimer            = OptionWrapper(params.hasIQWakeUp, Wire(Vec(params.numRegSrc, UInt(3.W))))
45eea4a3caSzhanglyGit  val enqDelaySrcLoadDependency   = Wire(Vec(params.numRegSrc, Vec(LoadPipelineWidth, UInt(3.W))))
46aa2b5219Ssinsanction
47aa2b5219Ssinsanction  val enqDelaySrcWakeUpByWB: Vec[UInt]                            = Wire(Vec(params.numRegSrc, SrcState()))
48aa2b5219Ssinsanction  val enqDelaySrcWakeUpByIQ: Vec[UInt]                            = Wire(Vec(params.numRegSrc, SrcState()))
49aa2b5219Ssinsanction  val enqDelaySrcWakeUpByIQVec: Vec[Vec[Bool]]                    = Wire(Vec(params.numRegSrc, Vec(params.numWakeupFromIQ, Bool())))
50aa2b5219Ssinsanction  val enqDelayShiftedWakeupLoadDependencyByIQVec: Vec[Vec[UInt]]  = Wire(Vec(params.numWakeupFromIQ, Vec(LoadPipelineWidth, UInt(3.W))))
51aa2b5219Ssinsanction
525db4956bSzhanglyGit  //Reg
53*4243aa09SsinceforYy  val validReg = GatedValidRegNext(common.validRegNext, false.B)
5441dbbdfdSsinceforYy  val entryReg = RegEnable(entryRegNext, validReg || common.validRegNext)
55*4243aa09SsinceforYy  val enqDelayValidReg = GatedValidRegNext(enqDelayValidRegNext, false.B)
565db4956bSzhanglyGit
575db4956bSzhanglyGit  //Wire
580dfdb52aSzhanglyGit  CommonWireConnect(common, hasWakeupIQ, validReg, currentStatus, io.commonIn, true)
595db4956bSzhanglyGit
6028607074Ssinsanction  when(io.commonIn.enq.valid) {
6128607074Ssinsanction    assert(common.enqReady, "Entry is not ready when enq is valid\n")
6228607074Ssinsanction  }
6328607074Ssinsanction
64aa2bcc31SzhanglyGit  when(io.commonIn.enq.valid && common.enqReady) {
65aa2bcc31SzhanglyGit    entryRegNext := io.commonIn.enq.bits
665db4956bSzhanglyGit  }.otherwise {
675db4956bSzhanglyGit    entryRegNext := entryUpdate
685db4956bSzhanglyGit  }
695db4956bSzhanglyGit
70aa2bcc31SzhanglyGit  when(io.commonIn.enq.valid && common.enqReady) {
71aa2b5219Ssinsanction    enqDelayValidRegNext := true.B
72aa2b5219Ssinsanction  }.otherwise {
73aa2b5219Ssinsanction    enqDelayValidRegNext := false.B
74aa2b5219Ssinsanction  }
75aa2b5219Ssinsanction
765db4956bSzhanglyGit  if (params.hasIQWakeUp) {
77aa2bcc31SzhanglyGit    ShiftLoadDependency(hasWakeupIQ.get)
780dfdb52aSzhanglyGit    CommonIQWakeupConnect(common, hasWakeupIQ.get, validReg, currentStatus, io.commonIn, true)
795db4956bSzhanglyGit  }
805db4956bSzhanglyGit
81aa2b5219Ssinsanction  // enq delay wakeup
82aa2b5219Ssinsanction  enqDelaySrcWakeUpByWB.zipWithIndex.foreach { case (wakeup, i) =>
83aa2bcc31SzhanglyGit    wakeup := io.enqDelayWakeUpFromWB.map(x => x.bits.wakeUp(Seq((entryReg.status.srcStatus(i).psrc, entryReg.status.srcStatus(i).srcType)), x.valid).head
84aa2b5219Ssinsanction    ).reduce(_ || _)
85aa2b5219Ssinsanction  }
86aa2b5219Ssinsanction
87aa2b5219Ssinsanction  if (params.hasIQWakeUp) {
88aa2b5219Ssinsanction    val wakeupVec: IndexedSeq[IndexedSeq[Bool]] = io.enqDelayWakeUpFromIQ.map( x =>
89aa2bcc31SzhanglyGit      x.bits.wakeUpFromIQ(entryReg.status.srcStatus.map(_.psrc) zip entryReg.status.srcStatus.map(_.srcType))
90aa2b5219Ssinsanction    ).toIndexedSeq.transpose
91d20f567fSzhanglyGit    val cancelSel = params.wakeUpSourceExuIdx.zip(io.enqDelayWakeUpFromIQ).map{ case (x, y) => io.enqDelayOg0Cancel(x) && y.bits.is0Lat}
92aa2b5219Ssinsanction    enqDelaySrcWakeUpByIQVec := wakeupVec.map(x => VecInit(x.zip(cancelSel).map { case (wakeup, cancel) => wakeup && !cancel }))
93aa2b5219Ssinsanction  } else {
94aa2b5219Ssinsanction    enqDelaySrcWakeUpByIQVec := 0.U.asTypeOf(enqDelaySrcWakeUpByIQVec)
95aa2b5219Ssinsanction  }
96aa2b5219Ssinsanction
97aa2b5219Ssinsanction  if (params.hasIQWakeUp) {
98aa2b5219Ssinsanction    enqDelaySrcWakeUpByIQ.zipWithIndex.foreach { case (wakeup, i) =>
99aa2b5219Ssinsanction      val ldTransCancel = Mux1H(enqDelaySrcWakeUpByIQVec(i), io.enqDelayWakeUpFromIQ.map(_.bits.loadDependency).map(dp => LoadShouldCancel(Some(dp), io.enqDelayLdCancel)).toSeq)
100aa2b5219Ssinsanction      wakeup := enqDelaySrcWakeUpByIQVec(i).asUInt.orR && !ldTransCancel
101aa2b5219Ssinsanction    }
102aa2b5219Ssinsanction  } else {
103aa2b5219Ssinsanction    enqDelaySrcWakeUpByIQ := 0.U.asTypeOf(enqDelaySrcWakeUpByIQ)
104aa2b5219Ssinsanction  }
105aa2b5219Ssinsanction
106aa2b5219Ssinsanction  enqDelayShiftedWakeupLoadDependencyByIQVec.zip(io.enqDelayWakeUpFromIQ.map(_.bits.loadDependency))
107aa2b5219Ssinsanction    .zip(params.wakeUpInExuSources.map(_.name)).foreach { case ((dps, ldps), name) =>
108aa2b5219Ssinsanction    dps.zip(ldps).zipWithIndex.foreach { case ((dp, ldp), deqPortIdx) =>
109aa2b5219Ssinsanction      if (params.backendParam.getLdExuIdx(params.backendParam.allExuParams.find(_.name == name).get) == deqPortIdx)
110aa2b5219Ssinsanction        dp := (ldp << 2).asUInt | 2.U
111aa2b5219Ssinsanction      else
112aa2b5219Ssinsanction        dp := ldp << 1
113aa2b5219Ssinsanction    }
114aa2b5219Ssinsanction  }
115aa2b5219Ssinsanction
116aa2b5219Ssinsanction  for (i <- 0 until params.numRegSrc) {
117aa2bcc31SzhanglyGit    enqDelaySrcState(i)                     := entryReg.status.srcStatus(i).srcState | enqDelaySrcWakeUpByWB(i) | enqDelaySrcWakeUpByIQ(i)
11853bf098fSxiaofeibao-xjtu    enqDelayDataSources(i).value            := Mux(enqDelaySrcWakeUpByIQ(i).asBool, DataSource.bypass, entryReg.status.srcStatus(i).dataSources.value)
119aa2b5219Ssinsanction    if (params.hasIQWakeUp) {
120aa2b5219Ssinsanction      val wakeUpValid = enqDelaySrcWakeUpByIQVec(i).asUInt.orR
121aa2b5219Ssinsanction      val wakeUpOH = enqDelaySrcWakeUpByIQVec(i)
122acf41503Ssinsanction      enqDelaySrcWakeUpL1ExuOH.get(i)       := Mux1H(wakeUpOH, params.wakeUpSourceExuIdx.map(x => MathUtils.IntToOH(x).U(backendParams.numExu.W)).toSeq)
123aa2b5219Ssinsanction      enqDelaySrcTimer.get(i)               := Mux(wakeUpValid, 2.U, 3.U)
124eea4a3caSzhanglyGit      enqDelaySrcLoadDependency(i)          := Mux(enqDelaySrcWakeUpByIQVec(i).asUInt.orR, Mux1H(enqDelaySrcWakeUpByIQVec(i), enqDelayShiftedWakeupLoadDependencyByIQVec), entryReg.status.srcStatus(i).srcLoadDependency)
125eea4a3caSzhanglyGit    } else {
126eea4a3caSzhanglyGit      enqDelaySrcLoadDependency(i)          := entryReg.status.srcStatus(i).srcLoadDependency
127aa2b5219Ssinsanction    }
128aa2b5219Ssinsanction  }
129aa2b5219Ssinsanction  currentStatus                             := entryReg.status
130aa2b5219Ssinsanction  when (enqDelayValidReg) {
131aa2bcc31SzhanglyGit    currentStatus.srcStatus.zipWithIndex.foreach { case (srcStatus, srcIdx) =>
132aa2bcc31SzhanglyGit      srcStatus.srcState                    := enqDelaySrcState(srcIdx)
133aa2bcc31SzhanglyGit      srcStatus.dataSources                 := enqDelayDataSources(srcIdx)
134aa2bcc31SzhanglyGit      srcStatus.srcTimer.foreach(_          := enqDelaySrcTimer.get(srcIdx))
135eea4a3caSzhanglyGit      srcStatus.srcLoadDependency           := enqDelaySrcLoadDependency(srcIdx)
136aa2bcc31SzhanglyGit    }
137aa2b5219Ssinsanction  }
138aa2b5219Ssinsanction
139acf41503Ssinsanction  if (params.hasIQWakeUp) {
140aa2bcc31SzhanglyGit    currentStatus.srcStatus.map(_.srcWakeUpL1ExuOH.get).zip(entryReg.status.srcStatus.map(_.srcWakeUpL1ExuOH.get)).zip(enqDelaySrcWakeUpL1ExuOH.get).foreach {
141acf41503Ssinsanction      case ((currExuOH, regExuOH), enqDelayExuOH) =>
142acf41503Ssinsanction        currExuOH := 0.U.asTypeOf(currExuOH)
143acf41503Ssinsanction        params.wakeUpSourceExuIdx.foreach(x => currExuOH(x) := Mux(enqDelayValidReg, enqDelayExuOH(x), regExuOH(x)))
144acf41503Ssinsanction    }
145acf41503Ssinsanction  }
146acf41503Ssinsanction
147aa2bcc31SzhanglyGit  EntryRegCommonConnect(common, hasWakeupIQ, validReg, entryUpdate, entryReg, currentStatus, io.commonIn, true)
148e08589a5Ssinsanction
149397c0f33Ssinsanction  //output
150df26db8aSsinsanction  CommonOutConnect(io.commonOut, common, hasWakeupIQ, validReg, entryUpdate, entryReg, currentStatus, io.commonIn, true, isComp)
1515db4956bSzhanglyGit}
1525db4956bSzhanglyGit
153e07131b2Ssinsanctionclass EnqEntryVecMem(isComp: Boolean)(implicit p: Parameters, params: IssueBlockParams) extends EnqEntry(isComp)
1542d270511Ssinsanction  with HasCircularQueuePtrHelper {
1552d270511Ssinsanction
156e07131b2Ssinsanction  require(params.isVecMemIQ, "EnqEntryVecMem can only be instance of VecMem IQ")
1572d270511Ssinsanction
158e07131b2Ssinsanction  EntryVecMemConnect(io.commonIn, common, validReg, entryReg, entryRegNext, entryUpdate)
1592d270511Ssinsanction}
1602d270511Ssinsanction
1615db4956bSzhanglyGitobject EnqEntry {
162df26db8aSsinsanction  def apply(isComp: Boolean)(implicit p: Parameters, iqParams: IssueBlockParams): EnqEntry = {
1635db4956bSzhanglyGit    iqParams.schdType match {
164df26db8aSsinsanction      case IntScheduler() => new EnqEntry(isComp)
1655db4956bSzhanglyGit      case MemScheduler() =>
166e07131b2Ssinsanction        if (iqParams.isVecMemIQ) new EnqEntryVecMem(isComp)
167df26db8aSsinsanction        else new EnqEntry(isComp)
168df26db8aSsinsanction      case VfScheduler() => new EnqEntry(isComp)
1695db4956bSzhanglyGit      case _ => null
1705db4956bSzhanglyGit    }
1715db4956bSzhanglyGit  }
1725db4956bSzhanglyGit}