xref: /XiangShan/src/main/scala/xiangshan/backend/issue/Scheduler.scala (revision 4c5a0d77fca2d8c3969de02de43c1b36afcee253)
1730cfbc0SXuan Hupackage xiangshan.backend.issue
2730cfbc0SXuan Hu
383ba63b3SXuan Huimport org.chipsalliance.cde.config.Parameters
4730cfbc0SXuan Huimport chisel3._
5730cfbc0SXuan Huimport chisel3.util._
6730cfbc0SXuan Huimport freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp}
74fa00a44SzhanglyGitimport utils.OptionWrapper
8730cfbc0SXuan Huimport xiangshan._
910fe9778SXuan Huimport xiangshan.backend.Bundles._
1039c59369SXuan Huimport xiangshan.backend.datapath.DataConfig.{IntData, VAddrData, VecData}
1139c59369SXuan Huimport xiangshan.backend.datapath.WbConfig.{IntWB, VfWB}
12e62b6911SXuan Huimport xiangshan.backend.fu.FuType
13730cfbc0SXuan Huimport xiangshan.backend.regfile.RfWritePortWithConfig
14730cfbc0SXuan Huimport xiangshan.backend.rename.BusyTable
152d270511Ssinsanctionimport xiangshan.mem.{LsqEnqCtrl, LsqEnqIO, MemWaitUpdateReq, SqPtr, LqPtr}
16730cfbc0SXuan Hu
17730cfbc0SXuan Husealed trait SchedulerType
18730cfbc0SXuan Hu
19730cfbc0SXuan Hucase class IntScheduler() extends SchedulerType
20730cfbc0SXuan Hucase class MemScheduler() extends SchedulerType
21730cfbc0SXuan Hucase class VfScheduler() extends SchedulerType
22730cfbc0SXuan Hucase class NoScheduler() extends SchedulerType
23730cfbc0SXuan Hu
24730cfbc0SXuan Huclass Scheduler(val params: SchdBlockParams)(implicit p: Parameters) extends LazyModule with HasXSParameter {
251ca4a39dSXuan Hu  override def shouldBeInlined: Boolean = false
261ca4a39dSXuan Hu
2739c59369SXuan Hu  val numIntStateWrite = backendParams.numPregWb(IntData())
2839c59369SXuan Hu  val numVfStateWrite = backendParams.numPregWb(VecData())
29730cfbc0SXuan Hu
30730cfbc0SXuan Hu  val dispatch2Iq = LazyModule(new Dispatch2Iq(params))
31730cfbc0SXuan Hu  val issueQueue = params.issueBlockParams.map(x => LazyModule(new IssueQueue(x).suggestName(x.getIQName)))
32730cfbc0SXuan Hu
3383ba63b3SXuan Hu  lazy val module: SchedulerImpBase = params.schdType match {
34730cfbc0SXuan Hu    case IntScheduler() => new SchedulerArithImp(this)(params, p)
35730cfbc0SXuan Hu    case MemScheduler() => new SchedulerMemImp(this)(params, p)
36730cfbc0SXuan Hu    case VfScheduler() => new SchedulerArithImp(this)(params, p)
37730cfbc0SXuan Hu    case _ => null
38730cfbc0SXuan Hu  }
39730cfbc0SXuan Hu}
40730cfbc0SXuan Hu
417f8233d5SHaojin Tangclass SchedulerIO()(implicit params: SchdBlockParams, p: Parameters) extends XSBundle {
4268d13085SXuan Hu  // params alias
437f8233d5SHaojin Tang  private val LoadQueueSize = VirtualLoadQueueSize
4468d13085SXuan Hu
45730cfbc0SXuan Hu  val fromTop = new Bundle {
46730cfbc0SXuan Hu    val hartId = Input(UInt(8.W))
47730cfbc0SXuan Hu  }
482e0a7dc5Sfdy  val fromWbFuBusyTable = new Bundle{
492e0a7dc5Sfdy    val fuBusyTableRead = MixedVec(params.issueBlockParams.map(x => Input(x.genWbFuBusyTableReadBundle)))
502e0a7dc5Sfdy  }
51dd970561SzhanglyGit  val wbFuBusyTable = MixedVec(params.issueBlockParams.map(x => Output(x.genWbFuBusyTableWriteBundle)))
52dd970561SzhanglyGit
53730cfbc0SXuan Hu  val fromCtrlBlock = new Bundle {
54730cfbc0SXuan Hu    val pcVec = Input(Vec(params.numPcReadPort, UInt(VAddrData().dataWidth.W)))
55730cfbc0SXuan Hu    val flush = Flipped(ValidIO(new Redirect))
56730cfbc0SXuan Hu  }
57730cfbc0SXuan Hu  val fromDispatch = new Bundle {
58730cfbc0SXuan Hu    val allocPregs = Vec(RenameWidth, Input(new ResetPregStateReq))
59730cfbc0SXuan Hu    val uops =  Vec(params.numUopIn, Flipped(DecoupledIO(new DynInst)))
60730cfbc0SXuan Hu  }
6139c59369SXuan Hu  val intWriteBack = MixedVec(Vec(backendParams.numPregWb(IntData()),
62730cfbc0SXuan Hu    new RfWritePortWithConfig(backendParams.intPregParams.dataCfg, backendParams.intPregParams.addrWidth)))
6339c59369SXuan Hu  val vfWriteBack = MixedVec(Vec(backendParams.numPregWb(VecData()),
64730cfbc0SXuan Hu    new RfWritePortWithConfig(backendParams.vfPregParams.dataCfg, backendParams.vfPregParams.addrWidth)))
6559ef6009Sxiaofeibao-xjtu  val toDataPathAfterDelay: MixedVec[MixedVec[DecoupledIO[IssueQueueIssueBundle]]] = MixedVec(params.issueBlockParams.map(_.genIssueDecoupledBundle))
66730cfbc0SXuan Hu
67bf35baadSXuan Hu  val fromSchedulers = new Bundle {
68c0be7f33SXuan Hu    val wakeupVec: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(params.genIQWakeUpInValidBundle)
69bf35baadSXuan Hu  }
70bf35baadSXuan Hu
71bf35baadSXuan Hu  val toSchedulers = new Bundle {
72c0be7f33SXuan Hu    val wakeupVec: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = params.genIQWakeUpOutValidBundle
73bf35baadSXuan Hu  }
74bf35baadSXuan Hu
75c0be7f33SXuan Hu  val fromDataPath = new Bundle {
7610fe9778SXuan Hu    val resp: MixedVec[MixedVec[OGRespBundle]] = MixedVec(params.issueBlockParams.map(x => Flipped(x.genOGRespBundle)))
777a96cc7fSHaojin Tang    val og0Cancel = Input(ExuOH(backendParams.numExu))
78ea46c302SXuan Hu    // Todo: remove this after no cancel signal from og1
797a96cc7fSHaojin Tang    val og1Cancel = Input(ExuOH(backendParams.numExu))
80bc7d6943SzhanglyGit    val cancelToBusyTable = Vec(backendParams.numExu, Flipped(ValidIO(new CancelSignal)))
81c0be7f33SXuan Hu    // just be compatible to old code
82c0be7f33SXuan Hu    def apply(i: Int)(j: Int) = resp(i)(j)
83c0be7f33SXuan Hu  }
84c0be7f33SXuan Hu
858a66c02cSXuan Hu  val loadFinalIssueResp = MixedVec(params.issueBlockParams.map(x => MixedVec(Vec(x.LdExuCnt, Flipped(ValidIO(new IssueQueueDeqRespBundle()(p, x)))))))
868a66c02cSXuan Hu  val memAddrIssueResp = MixedVec(params.issueBlockParams.map(x => MixedVec(Vec(x.LdExuCnt, Flipped(ValidIO(new IssueQueueDeqRespBundle()(p, x)))))))
870f55a0d3SHaojin Tang
886810d1e8Ssfencevma  val ldCancel = Vec(backendParams.LduCnt + backendParams.HyuCnt, Flipped(new LoadCancelIO))
89c0be7f33SXuan Hu
904fa00a44SzhanglyGit  val finalBlockMem = OptionWrapper(params.isMemSchd, MixedVec(params.issueBlockParams.map(x => MixedVec(Vec(x.numExu, Input(Bool()))))))
914fa00a44SzhanglyGit
92730cfbc0SXuan Hu  val memIO = if (params.isMemSchd) Some(new Bundle {
93730cfbc0SXuan Hu    val lsqEnqIO = Flipped(new LsqEnqIO)
94730cfbc0SXuan Hu  }) else None
95730cfbc0SXuan Hu  val fromMem = if (params.isMemSchd) Some(new Bundle {
967b753bebSXuan Hu    val ldaFeedback = Flipped(Vec(params.LduCnt, new MemRSFeedbackIO))
977b753bebSXuan Hu    val staFeedback = Flipped(Vec(params.StaCnt, new MemRSFeedbackIO))
988f1fa9b1Ssfencevma    val hyuFeedback = Flipped(Vec(params.HyuCnt, new MemRSFeedbackIO))
99730cfbc0SXuan Hu    val stIssuePtr = Input(new SqPtr())
100730cfbc0SXuan Hu    val lcommit = Input(UInt(log2Up(CommitWidth + 1).W))
101730cfbc0SXuan Hu    val scommit = Input(UInt(log2Ceil(EnsbufferWidth + 1).W)) // connected to `memBlock.io.sqDeq` instead of ROB
1022d270511Ssinsanction    val lqDeqPtr = Input(new LqPtr)
1032d270511Ssinsanction    val sqDeqPtr = Input(new SqPtr)
104730cfbc0SXuan Hu    // from lsq
105730cfbc0SXuan Hu    val lqCancelCnt = Input(UInt(log2Up(LoadQueueSize + 1).W))
106730cfbc0SXuan Hu    val sqCancelCnt = Input(UInt(log2Up(StoreQueueSize + 1).W))
107730cfbc0SXuan Hu    val memWaitUpdateReq = Flipped(new MemWaitUpdateReq)
108730cfbc0SXuan Hu  }) else None
109730cfbc0SXuan Hu  val toMem = if (params.isMemSchd) Some(new Bundle {
110730cfbc0SXuan Hu    val loadFastMatch = Output(Vec(params.LduCnt, new IssueQueueLoadBundle))
111730cfbc0SXuan Hu  }) else None
112730cfbc0SXuan Hu}
113730cfbc0SXuan Hu
114730cfbc0SXuan Huabstract class SchedulerImpBase(wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters)
115730cfbc0SXuan Hu  extends LazyModuleImp(wrapper)
116730cfbc0SXuan Hu    with HasXSParameter
117730cfbc0SXuan Hu{
118730cfbc0SXuan Hu  val io = IO(new SchedulerIO())
119730cfbc0SXuan Hu
120730cfbc0SXuan Hu  // alias
121c0be7f33SXuan Hu  private val iqWakeUpInMap: Map[Int, ValidIO[IssueQueueIQWakeUpBundle]] =
122c0be7f33SXuan Hu    io.fromSchedulers.wakeupVec.map(x => (x.bits.exuIdx, x)).toMap
123730cfbc0SXuan Hu  private val schdType = params.schdType
124730cfbc0SXuan Hu
125730cfbc0SXuan Hu  // Modules
126730cfbc0SXuan Hu  val dispatch2Iq: Dispatch2IqImp = wrapper.dispatch2Iq.module
127730cfbc0SXuan Hu  val issueQueues: Seq[IssueQueueImp] = wrapper.issueQueue.map(_.module)
128730cfbc0SXuan Hu
12956bcaed7SHaojin Tang  // valid count
13056bcaed7SHaojin Tang  dispatch2Iq.io.iqValidCnt := issueQueues.filter(_.params.StdCnt == 0).map(_.io.status.validCnt)
13156bcaed7SHaojin Tang
132730cfbc0SXuan Hu  // BusyTable Modules
133730cfbc0SXuan Hu  val intBusyTable = schdType match {
134bc7d6943SzhanglyGit    case IntScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numIntStateRead, wrapper.numIntStateWrite, IntPhyRegs, IntWB())))
135730cfbc0SXuan Hu    case _ => None
136730cfbc0SXuan Hu  }
137730cfbc0SXuan Hu
138730cfbc0SXuan Hu  val vfBusyTable = schdType match {
139bc7d6943SzhanglyGit    case VfScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numVfStateRead, wrapper.numVfStateWrite, VfPhyRegs, VfWB())))
140730cfbc0SXuan Hu    case _ => None
141730cfbc0SXuan Hu  }
142730cfbc0SXuan Hu
143730cfbc0SXuan Hu  dispatch2Iq.io match { case dp2iq =>
144730cfbc0SXuan Hu    dp2iq.redirect <> io.fromCtrlBlock.flush
145730cfbc0SXuan Hu    dp2iq.in <> io.fromDispatch.uops
146730cfbc0SXuan Hu    dp2iq.readIntState.foreach(_ <> intBusyTable.get.io.read)
147730cfbc0SXuan Hu    dp2iq.readVfState.foreach(_ <> vfBusyTable.get.io.read)
148730cfbc0SXuan Hu  }
149730cfbc0SXuan Hu
150730cfbc0SXuan Hu  intBusyTable match {
151730cfbc0SXuan Hu    case Some(bt) =>
152730cfbc0SXuan Hu      bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) =>
153730cfbc0SXuan Hu        btAllocPregs.valid := dpAllocPregs.isInt
154730cfbc0SXuan Hu        btAllocPregs.bits := dpAllocPregs.preg
155730cfbc0SXuan Hu      }
156730cfbc0SXuan Hu      bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) =>
157730cfbc0SXuan Hu        wb.valid := io.intWriteBack(i).wen && io.intWriteBack(i).intWen
158730cfbc0SXuan Hu        wb.bits := io.intWriteBack(i).addr
159730cfbc0SXuan Hu      }
160bc7d6943SzhanglyGit      bt.io.wakeUp := io.fromSchedulers.wakeupVec
161bc7d6943SzhanglyGit      bt.io.cancel := io.fromDataPath.cancelToBusyTable
16213551487SzhanglyGit      bt.io.ldCancel := io.ldCancel
163730cfbc0SXuan Hu    case None =>
164730cfbc0SXuan Hu  }
165730cfbc0SXuan Hu
166730cfbc0SXuan Hu  vfBusyTable match {
167730cfbc0SXuan Hu    case Some(bt) =>
168730cfbc0SXuan Hu      bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) =>
169730cfbc0SXuan Hu        btAllocPregs.valid := dpAllocPregs.isFp
170730cfbc0SXuan Hu        btAllocPregs.bits := dpAllocPregs.preg
171730cfbc0SXuan Hu      }
172730cfbc0SXuan Hu      bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) =>
173730cfbc0SXuan Hu        wb.valid := io.vfWriteBack(i).wen && (io.vfWriteBack(i).fpWen || io.vfWriteBack(i).vecWen)
174730cfbc0SXuan Hu        wb.bits := io.vfWriteBack(i).addr
175730cfbc0SXuan Hu      }
176bc7d6943SzhanglyGit      bt.io.wakeUp := io.fromSchedulers.wakeupVec
177bc7d6943SzhanglyGit      bt.io.cancel := io.fromDataPath.cancelToBusyTable
17813551487SzhanglyGit      bt.io.ldCancel := io.ldCancel
179730cfbc0SXuan Hu    case None =>
180730cfbc0SXuan Hu  }
181730cfbc0SXuan Hu
182f39a61a1SzhanglyGit  val wakeupFromIntWBVec = Wire(params.genIntWBWakeUpSinkValidBundle)
183f39a61a1SzhanglyGit  val wakeupFromVfWBVec = Wire(params.genVfWBWakeUpSinkValidBundle)
184f39a61a1SzhanglyGit
185f39a61a1SzhanglyGit  wakeupFromIntWBVec.zip(io.intWriteBack).foreach { case (sink, source) =>
186f39a61a1SzhanglyGit    sink.valid := source.wen
187f39a61a1SzhanglyGit    sink.bits.rfWen := source.intWen
188f39a61a1SzhanglyGit    sink.bits.fpWen := source.fpWen
189f39a61a1SzhanglyGit    sink.bits.vecWen := source.vecWen
190f39a61a1SzhanglyGit    sink.bits.pdest := source.addr
191730cfbc0SXuan Hu  }
192f39a61a1SzhanglyGit
193f39a61a1SzhanglyGit  wakeupFromVfWBVec.zip(io.vfWriteBack).foreach { case (sink, source) =>
194730cfbc0SXuan Hu    sink.valid := source.wen
195730cfbc0SXuan Hu    sink.bits.rfWen := source.intWen
196730cfbc0SXuan Hu    sink.bits.fpWen := source.fpWen
197730cfbc0SXuan Hu    sink.bits.vecWen := source.vecWen
198730cfbc0SXuan Hu    sink.bits.pdest := source.addr
199730cfbc0SXuan Hu  }
200730cfbc0SXuan Hu
201bf35baadSXuan Hu  // Connect bundles having the same wakeup source
20259ef6009Sxiaofeibao-xjtu  issueQueues.zipWithIndex.foreach { case(iq, i) =>
203bf35baadSXuan Hu    iq.io.wakeupFromIQ.foreach { wakeUp =>
2040c7ebb58Sxiaofeibao-xjtu      val wakeUpIn = iqWakeUpInMap(wakeUp.bits.exuIdx)
2050c7ebb58Sxiaofeibao-xjtu      val exuIdx = wakeUp.bits.exuIdx
2060c7ebb58Sxiaofeibao-xjtu      println(s"[Backend] Connect wakeup exuIdx ${exuIdx}")
2070c7ebb58Sxiaofeibao-xjtu      connectSamePort(wakeUp,wakeUpIn)
2080c7ebb58Sxiaofeibao-xjtu      backendParams.connectWakeup(exuIdx)
2090c7ebb58Sxiaofeibao-xjtu      if (backendParams.isCopyPdest(exuIdx)) {
2100c7ebb58Sxiaofeibao-xjtu        println(s"[Backend] exuIdx ${exuIdx} use pdestCopy ${backendParams.getCopyPdestIndex(exuIdx)}")
2110c7ebb58Sxiaofeibao-xjtu        wakeUp.bits.pdest := wakeUpIn.bits.pdestCopy.get(backendParams.getCopyPdestIndex(exuIdx))
212*4c5a0d77Sxiaofeibao-xjtu        if (wakeUpIn.bits.rfWenCopy.nonEmpty) wakeUp.bits.rfWen := wakeUpIn.bits.rfWenCopy.get(backendParams.getCopyPdestIndex(exuIdx))
213*4c5a0d77Sxiaofeibao-xjtu        if (wakeUpIn.bits.fpWenCopy.nonEmpty) wakeUp.bits.fpWen := wakeUpIn.bits.fpWenCopy.get(backendParams.getCopyPdestIndex(exuIdx))
214*4c5a0d77Sxiaofeibao-xjtu        if (wakeUpIn.bits.vecWenCopy.nonEmpty) wakeUp.bits.vecWen := wakeUpIn.bits.vecWenCopy.get(backendParams.getCopyPdestIndex(exuIdx))
215*4c5a0d77Sxiaofeibao-xjtu        if (wakeUpIn.bits.loadDependencyCopy.nonEmpty) wakeUp.bits.loadDependency := wakeUpIn.bits.loadDependencyCopy.get(backendParams.getCopyPdestIndex(exuIdx))
2160c7ebb58Sxiaofeibao-xjtu      }
21760912d84Sxiaofeibao-xjtu      if (iq.params.numIntSrc == 0) wakeUp.bits.rfWen := false.B
21860912d84Sxiaofeibao-xjtu      if (iq.params.numFpSrc == 0)  wakeUp.bits.fpWen := false.B
21960912d84Sxiaofeibao-xjtu      if (iq.params.numVfSrc == 0)  wakeUp.bits.vecWen := false.B
220bf35baadSXuan Hu    }
221ea46c302SXuan Hu    iq.io.og0Cancel := io.fromDataPath.og0Cancel
222ea46c302SXuan Hu    iq.io.og1Cancel := io.fromDataPath.og1Cancel
2230f55a0d3SHaojin Tang    iq.io.ldCancel := io.ldCancel
2244fa00a44SzhanglyGit    if(params.isMemSchd) {
2254fa00a44SzhanglyGit      iq.io.finalBlock.zip(io.finalBlockMem.get(i)).foreach(x => x._1 := x._2)
2264fa00a44SzhanglyGit    } else {
2274fa00a44SzhanglyGit      iq.io.finalBlock.foreach(_ := false.B)
2284fa00a44SzhanglyGit    }
229bf35baadSXuan Hu  }
230bf35baadSXuan Hu
231c0be7f33SXuan Hu  private val iqWakeUpOutMap: Map[Int, ValidIO[IssueQueueIQWakeUpBundle]] =
232bf35baadSXuan Hu    issueQueues.flatMap(_.io.wakeupToIQ)
233c0be7f33SXuan Hu      .map(x => (x.bits.exuIdx, x))
234bf35baadSXuan Hu      .toMap
235bf35baadSXuan Hu
236bf35baadSXuan Hu  // Connect bundles having the same wakeup source
237bf35baadSXuan Hu  io.toSchedulers.wakeupVec.foreach { wakeUp =>
238c0be7f33SXuan Hu    wakeUp := iqWakeUpOutMap(wakeUp.bits.exuIdx)
239bf35baadSXuan Hu  }
240bf35baadSXuan Hu
24159ef6009Sxiaofeibao-xjtu  io.toDataPathAfterDelay.zipWithIndex.foreach { case (toDpDy, i) =>
24259ef6009Sxiaofeibao-xjtu    toDpDy <> issueQueues(i).io.deqDelay
24359ef6009Sxiaofeibao-xjtu  }
244bf35baadSXuan Hu
245f99b81adSHaojin Tang  // Response
246f99b81adSHaojin Tang  issueQueues.zipWithIndex.foreach { case (iq, i) =>
247f99b81adSHaojin Tang    iq.io.og0Resp.zipWithIndex.foreach { case (og0Resp, j) =>
248f99b81adSHaojin Tang      og0Resp := io.fromDataPath(i)(j).og0resp
249f99b81adSHaojin Tang    }
250f99b81adSHaojin Tang    iq.io.og1Resp.zipWithIndex.foreach { case (og1Resp, j) =>
251f99b81adSHaojin Tang      og1Resp := io.fromDataPath(i)(j).og1resp
252f99b81adSHaojin Tang    }
253f99b81adSHaojin Tang    iq.io.finalIssueResp.foreach(_.zipWithIndex.foreach { case (finalIssueResp, j) =>
254670870b3SXuan Hu      if (io.loadFinalIssueResp(i).isDefinedAt(j)) {
255f99b81adSHaojin Tang        finalIssueResp := io.loadFinalIssueResp(i)(j)
256670870b3SXuan Hu      } else {
257670870b3SXuan Hu        finalIssueResp := 0.U.asTypeOf(finalIssueResp)
258670870b3SXuan Hu      }
259f99b81adSHaojin Tang    })
260e8800897SXuan Hu    iq.io.memAddrIssueResp.foreach(_.zipWithIndex.foreach { case (memAddrIssueResp, j) =>
261e8800897SXuan Hu      memAddrIssueResp := io.memAddrIssueResp(i)(j)
262e8800897SXuan Hu    })
263f99b81adSHaojin Tang    iq.io.wbBusyTableRead := io.fromWbFuBusyTable.fuBusyTableRead(i)
264f99b81adSHaojin Tang    io.wbFuBusyTable(i) := iq.io.wbBusyTableWrite
265f99b81adSHaojin Tang  }
266f99b81adSHaojin Tang
267c0be7f33SXuan Hu  println(s"[Scheduler] io.fromSchedulers.wakeupVec: ${io.fromSchedulers.wakeupVec.map(x => backendParams.getExuName(x.bits.exuIdx))}")
268bf35baadSXuan Hu  println(s"[Scheduler] iqWakeUpInKeys: ${iqWakeUpInMap.keys}")
269bf35baadSXuan Hu
270bf35baadSXuan Hu  println(s"[Scheduler] iqWakeUpOutKeys: ${iqWakeUpOutMap.keys}")
271c0be7f33SXuan Hu  println(s"[Scheduler] io.toSchedulers.wakeupVec: ${io.toSchedulers.wakeupVec.map(x => backendParams.getExuName(x.bits.exuIdx))}")
272730cfbc0SXuan Hu}
273730cfbc0SXuan Hu
274730cfbc0SXuan Huclass SchedulerArithImp(override val wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters)
275730cfbc0SXuan Hu  extends SchedulerImpBase(wrapper)
276730cfbc0SXuan Hu    with HasXSParameter
277730cfbc0SXuan Hu{
2782e0a7dc5Sfdy//  dontTouch(io.vfWbFuBusyTable)
279730cfbc0SXuan Hu  println(s"[SchedulerArithImp] " +
280730cfbc0SXuan Hu    s"has intBusyTable: ${intBusyTable.nonEmpty}, " +
281730cfbc0SXuan Hu    s"has vfBusyTable: ${vfBusyTable.nonEmpty}")
282730cfbc0SXuan Hu
283730cfbc0SXuan Hu  issueQueues.zipWithIndex.foreach { case (iq, i) =>
284730cfbc0SXuan Hu    iq.io.flush <> io.fromCtrlBlock.flush
285730cfbc0SXuan Hu    iq.io.enq <> dispatch2Iq.io.out(i)
286f39a61a1SzhanglyGit    val intWBIQ = params.schdType match {
287f39a61a1SzhanglyGit      case IntScheduler() => wakeupFromIntWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromIntWBPort.keys.toSeq.contains(x._2)).map(_._1)
288f39a61a1SzhanglyGit      case VfScheduler() => wakeupFromVfWBVec
289f39a61a1SzhanglyGit    }
290f39a61a1SzhanglyGit    iq.io.wakeupFromWB.zip(intWBIQ).foreach{ case (sink, source) => sink := source}
291730cfbc0SXuan Hu  }
292730cfbc0SXuan Hu}
293730cfbc0SXuan Hu
294f99b81adSHaojin Tang// FIXME: Vector mem instructions may not be handled properly!
295730cfbc0SXuan Huclass SchedulerMemImp(override val wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters)
296730cfbc0SXuan Hu  extends SchedulerImpBase(wrapper)
297730cfbc0SXuan Hu    with HasXSParameter
298730cfbc0SXuan Hu{
299730cfbc0SXuan Hu  println(s"[SchedulerMemImp] " +
300730cfbc0SXuan Hu    s"has intBusyTable: ${intBusyTable.nonEmpty}, " +
301730cfbc0SXuan Hu    s"has vfBusyTable: ${vfBusyTable.nonEmpty}")
302730cfbc0SXuan Hu
303559c1710SHaojin Tang  val memAddrIQs = issueQueues.filter(_.params.isMemAddrIQ)
3042d270511Ssinsanction  val stAddrIQs = issueQueues.filter(iq => iq.params.StaCnt > 0 || iq.params.VstaCnt > 0) // included in memAddrIQs
3052d270511Ssinsanction  val ldAddrIQs = issueQueues.filter(iq => iq.params.LduCnt > 0 || iq.params.VlduCnt > 0)
3062d270511Ssinsanction  val stDataIQs = issueQueues.filter(iq => iq.params.StdCnt > 0 || iq.params.VstdCnt > 0)
307559c1710SHaojin Tang  val vecMemIQs = issueQueues.filter(_.params.isVecMemIQ)
308559c1710SHaojin Tang  val (hyuIQs, hyuIQIdxs) = issueQueues.zipWithIndex.filter(_._1.params.HyuCnt > 0).unzip
309499caf4cSXuan Hu
310499caf4cSXuan Hu  println(s"[SchedulerMemImp] memAddrIQs.size: ${memAddrIQs.size}, enq.size: ${memAddrIQs.map(_.io.enq.size).sum}")
311499caf4cSXuan Hu  println(s"[SchedulerMemImp] stAddrIQs.size:  ${stAddrIQs.size }, enq.size: ${stAddrIQs.map(_.io.enq.size).sum}")
312499caf4cSXuan Hu  println(s"[SchedulerMemImp] ldAddrIQs.size:  ${ldAddrIQs.size }, enq.size: ${ldAddrIQs.map(_.io.enq.size).sum}")
313499caf4cSXuan Hu  println(s"[SchedulerMemImp] stDataIQs.size:  ${stDataIQs.size }, enq.size: ${stDataIQs.map(_.io.enq.size).sum}")
314499caf4cSXuan Hu  println(s"[SchedulerMemImp] hyuIQs.size:     ${hyuIQs.size    }, enq.size: ${hyuIQs.map(_.io.enq.size).sum}")
315730cfbc0SXuan Hu  require(memAddrIQs.nonEmpty && stDataIQs.nonEmpty)
316730cfbc0SXuan Hu
317853cd2d8SHaojin Tang  io.toMem.get.loadFastMatch := 0.U.asTypeOf(io.toMem.get.loadFastMatch) // TODO: is still needed?
318853cd2d8SHaojin Tang
319730cfbc0SXuan Hu  memAddrIQs.zipWithIndex.foreach { case (iq, i) =>
320730cfbc0SXuan Hu    iq.io.flush <> io.fromCtrlBlock.flush
321730cfbc0SXuan Hu    iq.io.enq <> dispatch2Iq.io.out(i)
322f39a61a1SzhanglyGit    iq.io.wakeupFromWB.zip(wakeupFromIntWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromIntWBPort.keys.toSeq.contains(x._2)).map(_._1) ++ wakeupFromVfWBVec).foreach{ case (sink, source) => sink := source}
323730cfbc0SXuan Hu  }
324730cfbc0SXuan Hu
325ecfc6f16SXuan Hu  ldAddrIQs.zipWithIndex.foreach {
326ecfc6f16SXuan Hu    case (imp: IssueQueueMemAddrImp, i) =>
327ecfc6f16SXuan Hu      imp.io.memIO.get.feedbackIO.head := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO.head)
328c14e89f4SHaojin Tang      imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr
329de784418SXuan Hu      imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
3307b753bebSXuan Hu    case _ =>
3317b753bebSXuan Hu  }
3327b753bebSXuan Hu
333ecfc6f16SXuan Hu  stAddrIQs.zipWithIndex.foreach {
334ecfc6f16SXuan Hu    case (imp: IssueQueueMemAddrImp, i) =>
335ecfc6f16SXuan Hu      imp.io.memIO.get.feedbackIO.head := io.fromMem.get.staFeedback(i)
336c14e89f4SHaojin Tang      imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr
337c14e89f4SHaojin Tang      imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
3387b753bebSXuan Hu    case _ =>
3397b753bebSXuan Hu  }
340730cfbc0SXuan Hu
341559c1710SHaojin Tang  hyuIQs.zip(hyuIQIdxs).foreach {
342559c1710SHaojin Tang    case (imp: IssueQueueMemAddrImp, idx) =>
343670870b3SXuan Hu      imp.io.memIO.get.feedbackIO.head := io.fromMem.get.hyuFeedback.head
344670870b3SXuan Hu      imp.io.memIO.get.feedbackIO(1) := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO(1))
3458f1fa9b1Ssfencevma      imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr
3468f1fa9b1Ssfencevma      imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
347559c1710SHaojin Tang      // TODO: refactor ditry code
348559c1710SHaojin Tang      imp.io.deqDelay(1).ready := false.B
349559c1710SHaojin Tang      io.toDataPathAfterDelay(idx)(1).valid := false.B
350559c1710SHaojin Tang      io.toDataPathAfterDelay(idx)(1).bits := 0.U.asTypeOf(io.toDataPathAfterDelay(idx)(1).bits)
3518f1fa9b1Ssfencevma    case _ =>
3528f1fa9b1Ssfencevma  }
3538f1fa9b1Ssfencevma
354e62b6911SXuan Hu  private val staIdxSeq = (stAddrIQs).map(iq => iq.params.idxInSchBlk)
355e62b6911SXuan Hu  private val hyaIdxSeq = (hyuIQs).map(iq => iq.params.idxInSchBlk)
356e62b6911SXuan Hu
357e62b6911SXuan Hu  println(s"[SchedulerMemImp] sta iq idx in memSchdBlock: $staIdxSeq")
358e62b6911SXuan Hu  println(s"[SchedulerMemImp] hya iq idx in memSchdBlock: $hyaIdxSeq")
359e62b6911SXuan Hu
360e62b6911SXuan Hu  private val staEnqs = stAddrIQs.map(_.io.enq).flatten
361e62b6911SXuan Hu  private val stdEnqs = stDataIQs.map(_.io.enq).flatten.take(staEnqs.size)
362e62b6911SXuan Hu  private val hyaEnqs = hyuIQs.map(_.io.enq).flatten
363e62b6911SXuan Hu  private val hydEnqs = stDataIQs.map(_.io.enq).flatten.drop(staEnqs.size)
364e62b6911SXuan Hu
365e62b6911SXuan Hu  require(staEnqs.size == stdEnqs.size, s"number of enq ports of store address IQs(${staEnqs.size}) " +
366e62b6911SXuan Hu  s"should be equal to number of enq ports of store data IQs(${stdEnqs.size})")
367e62b6911SXuan Hu
368e62b6911SXuan Hu  require(hyaEnqs.size == hydEnqs.size, s"number of enq ports of hybrid address IQs(${hyaEnqs.size}) " +
369e62b6911SXuan Hu  s"should be equal to number of enq ports of hybrid data IQs(${hydEnqs.size})")
3709b258a00Sxgkiri
3719b258a00Sxgkiri  for ((idxInSchBlk, i) <- staIdxSeq.zipWithIndex) {
372e62b6911SXuan Hu    dispatch2Iq.io.out(idxInSchBlk).zip(staEnqs).zip(stdEnqs).foreach{ case((dp, staIQ), stdIQ) =>
373730cfbc0SXuan Hu      val isAllReady = staIQ.ready && stdIQ.ready
374e62b6911SXuan Hu      dp.ready := isAllReady
375e62b6911SXuan Hu      staIQ.valid := dp.valid && isAllReady
3764ec52c44SXuan Hu      stdIQ.valid := dp.valid && isAllReady && FuType.isStore(dp.bits.fuType)
377730cfbc0SXuan Hu    }
3789b258a00Sxgkiri  }
379730cfbc0SXuan Hu
380e62b6911SXuan Hu  for ((idxInSchBlk, i) <- hyaIdxSeq.zipWithIndex) {
381e62b6911SXuan Hu    dispatch2Iq.io.out(idxInSchBlk).zip(hyaEnqs).zip(hydEnqs).foreach{ case((dp, hyaIQ), hydIQ) =>
382e62b6911SXuan Hu      val isAllReady = hyaIQ.ready && hydIQ.ready
383e62b6911SXuan Hu      dp.ready := isAllReady
384e62b6911SXuan Hu      hyaIQ.valid := dp.valid && isAllReady
38556bceacbSHaojin Tang      hydIQ.valid := dp.valid && isAllReady && FuType.FuTypeOrR(dp.bits.fuType, FuType.stu, FuType.mou)
386e62b6911SXuan Hu    }
387e62b6911SXuan Hu  }
388730cfbc0SXuan Hu
389e62b6911SXuan Hu  stDataIQs.zipWithIndex.foreach { case (iq, i) =>
390e62b6911SXuan Hu    iq.io.flush <> io.fromCtrlBlock.flush
391f39a61a1SzhanglyGit    iq.io.wakeupFromWB.zip(wakeupFromIntWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromIntWBPort.keys.toSeq.contains(x._2)).map(_._1).toSeq ++ wakeupFromVfWBVec).foreach{ case (sink, source) => sink := source}
392e62b6911SXuan Hu  }
393e62b6911SXuan Hu
394e62b6911SXuan Hu  (stdEnqs ++ hydEnqs).zip(staEnqs ++ hyaEnqs).zipWithIndex.foreach { case ((stdIQEnq, staIQEnq), i) =>
395730cfbc0SXuan Hu    stdIQEnq.bits  := staIQEnq.bits
396730cfbc0SXuan Hu    // Store data reuses store addr src(1) in dispatch2iq
397e62b6911SXuan Hu    // [dispatch2iq] --src*------src*(0)--> [staIQ|hyaIQ]
398730cfbc0SXuan Hu    //                       \
399730cfbc0SXuan Hu    //                        ---src*(1)--> [stdIQ]
400730cfbc0SXuan Hu    // Since the src(1) of sta is easier to get, stdIQEnq.bits.src*(0) is assigned to staIQEnq.bits.src*(1)
401730cfbc0SXuan Hu    // instead of dispatch2Iq.io.out(x).bits.src*(1)
40297b279b9SXuan Hu    val stdIdx = 1
4032d270511Ssinsanction    stdIQEnq.bits.srcState(0) := staIQEnq.bits.srcState(stdIdx)
40413551487SzhanglyGit    stdIQEnq.bits.srcLoadDependency(0) := staIQEnq.bits.srcLoadDependency(1)
4052d270511Ssinsanction      stdIQEnq.bits.srcType(0) := staIQEnq.bits.srcType(stdIdx)
4062d270511Ssinsanction    stdIQEnq.bits.psrc(0) := staIQEnq.bits.psrc(stdIdx)
407730cfbc0SXuan Hu    stdIQEnq.bits.sqIdx := staIQEnq.bits.sqIdx
408730cfbc0SXuan Hu  }
409730cfbc0SXuan Hu
4102d270511Ssinsanction  vecMemIQs.foreach {
4112d270511Ssinsanction    case imp: IssueQueueVecMemImp =>
4122d270511Ssinsanction      imp.io.memIO.get.sqDeqPtr.foreach(_ := io.fromMem.get.sqDeqPtr)
4132d270511Ssinsanction      imp.io.memIO.get.lqDeqPtr.foreach(_ := io.fromMem.get.lqDeqPtr)
4141f3d1b4dSXuan Hu      // not used
4151f3d1b4dSXuan Hu      imp.io.memIO.get.feedbackIO := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO)
4161f3d1b4dSXuan Hu      // maybe not used
4171f3d1b4dSXuan Hu      imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr
4181f3d1b4dSXuan Hu      imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
419f39a61a1SzhanglyGit      imp.io.wakeupFromWB.zip(wakeupFromIntWBVec.zipWithIndex.filter(x => imp.params.needWakeupFromIntWBPort.keys.toSeq.contains(x._2)).map(_._1).toSeq ++ wakeupFromVfWBVec).foreach{ case (sink, source) => sink := source}
420f39a61a1SzhanglyGit
4212d270511Ssinsanction    case _ =>
4222d270511Ssinsanction  }
4232d270511Ssinsanction
424730cfbc0SXuan Hu  val lsqEnqCtrl = Module(new LsqEnqCtrl)
425730cfbc0SXuan Hu
426730cfbc0SXuan Hu  lsqEnqCtrl.io.redirect <> io.fromCtrlBlock.flush
427730cfbc0SXuan Hu  lsqEnqCtrl.io.enq <> dispatch2Iq.io.enqLsqIO.get
428730cfbc0SXuan Hu  lsqEnqCtrl.io.lcommit := io.fromMem.get.lcommit
429730cfbc0SXuan Hu  lsqEnqCtrl.io.scommit := io.fromMem.get.scommit
430730cfbc0SXuan Hu  lsqEnqCtrl.io.lqCancelCnt := io.fromMem.get.lqCancelCnt
431730cfbc0SXuan Hu  lsqEnqCtrl.io.sqCancelCnt := io.fromMem.get.sqCancelCnt
432730cfbc0SXuan Hu  io.memIO.get.lsqEnqIO <> lsqEnqCtrl.io.enqLsq
433730cfbc0SXuan Hu}
434