xref: /XiangShan/src/main/scala/xiangshan/backend/issue/Scheduler.scala (revision ebb914e7007fa76b83a869685cc5c3efe1f867e9)
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)))
52c1e19666Sxiaofeibao-xjtu  val IQValidNumVec = Output(MixedVec(backendParams.genIQValidNumBundle))
53dd970561SzhanglyGit
54730cfbc0SXuan Hu  val fromCtrlBlock = new Bundle {
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
90730cfbc0SXuan Hu  val memIO = if (params.isMemSchd) Some(new Bundle {
91730cfbc0SXuan Hu    val lsqEnqIO = Flipped(new LsqEnqIO)
92730cfbc0SXuan Hu  }) else None
93730cfbc0SXuan Hu  val fromMem = if (params.isMemSchd) Some(new Bundle {
947b753bebSXuan Hu    val ldaFeedback = Flipped(Vec(params.LduCnt, new MemRSFeedbackIO))
957b753bebSXuan Hu    val staFeedback = Flipped(Vec(params.StaCnt, new MemRSFeedbackIO))
968f1fa9b1Ssfencevma    val hyuFeedback = Flipped(Vec(params.HyuCnt, new MemRSFeedbackIO))
97*ebb914e7Sweiding liu    val vstuFeedback = Flipped(Vec(params.VstuCnt, new MemRSFeedbackIO))
98*ebb914e7Sweiding liu    val vlduFeedback = Flipped(Vec(params.VlduCnt, 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
102fc45ed13SXuan Hu    val wakeup = Vec(params.LdExuCnt, Flipped(Valid(new DynInst)))
1032d270511Ssinsanction    val lqDeqPtr = Input(new LqPtr)
1042d270511Ssinsanction    val sqDeqPtr = Input(new SqPtr)
105730cfbc0SXuan Hu    // from lsq
106730cfbc0SXuan Hu    val lqCancelCnt = Input(UInt(log2Up(LoadQueueSize + 1).W))
107730cfbc0SXuan Hu    val sqCancelCnt = Input(UInt(log2Up(StoreQueueSize + 1).W))
108730cfbc0SXuan Hu    val memWaitUpdateReq = Flipped(new MemWaitUpdateReq)
109730cfbc0SXuan Hu  }) else None
110730cfbc0SXuan Hu  val toMem = if (params.isMemSchd) Some(new Bundle {
111730cfbc0SXuan Hu    val loadFastMatch = Output(Vec(params.LduCnt, new IssueQueueLoadBundle))
112730cfbc0SXuan Hu  }) else None
113730cfbc0SXuan Hu}
114730cfbc0SXuan Hu
115730cfbc0SXuan Huabstract class SchedulerImpBase(wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters)
116730cfbc0SXuan Hu  extends LazyModuleImp(wrapper)
117730cfbc0SXuan Hu    with HasXSParameter
118730cfbc0SXuan Hu{
119730cfbc0SXuan Hu  val io = IO(new SchedulerIO())
120730cfbc0SXuan Hu
121730cfbc0SXuan Hu  // alias
122c0be7f33SXuan Hu  private val iqWakeUpInMap: Map[Int, ValidIO[IssueQueueIQWakeUpBundle]] =
123c0be7f33SXuan Hu    io.fromSchedulers.wakeupVec.map(x => (x.bits.exuIdx, x)).toMap
124730cfbc0SXuan Hu  private val schdType = params.schdType
125730cfbc0SXuan Hu
126730cfbc0SXuan Hu  // Modules
127730cfbc0SXuan Hu  val dispatch2Iq: Dispatch2IqImp = wrapper.dispatch2Iq.module
128730cfbc0SXuan Hu  val issueQueues: Seq[IssueQueueImp] = wrapper.issueQueue.map(_.module)
129ff3fcdf1Sxiaofeibao-xjtu  if (params.isIntSchd) {
130ff3fcdf1Sxiaofeibao-xjtu    dispatch2Iq.io.IQValidNumVec.get := io.IQValidNumVec
131c1e19666Sxiaofeibao-xjtu    io.IQValidNumVec := MixedVecInit(issueQueues.map(_.io.validCntDeqVec))
132ff3fcdf1Sxiaofeibao-xjtu  }
133ff3fcdf1Sxiaofeibao-xjtu  else io.IQValidNumVec := 0.U.asTypeOf(io.IQValidNumVec)
134730cfbc0SXuan Hu
13556bcaed7SHaojin Tang  // valid count
13656bcaed7SHaojin Tang  dispatch2Iq.io.iqValidCnt := issueQueues.filter(_.params.StdCnt == 0).map(_.io.status.validCnt)
13756bcaed7SHaojin Tang
138730cfbc0SXuan Hu  // BusyTable Modules
139730cfbc0SXuan Hu  val intBusyTable = schdType match {
140bc7d6943SzhanglyGit    case IntScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numIntStateRead, wrapper.numIntStateWrite, IntPhyRegs, IntWB())))
141730cfbc0SXuan Hu    case _ => None
142730cfbc0SXuan Hu  }
143730cfbc0SXuan Hu
144730cfbc0SXuan Hu  val vfBusyTable = schdType match {
145bc7d6943SzhanglyGit    case VfScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numVfStateRead, wrapper.numVfStateWrite, VfPhyRegs, VfWB())))
146730cfbc0SXuan Hu    case _ => None
147730cfbc0SXuan Hu  }
148730cfbc0SXuan Hu
149730cfbc0SXuan Hu  dispatch2Iq.io match { case dp2iq =>
150730cfbc0SXuan Hu    dp2iq.redirect <> io.fromCtrlBlock.flush
151730cfbc0SXuan Hu    dp2iq.in <> io.fromDispatch.uops
152730cfbc0SXuan Hu    dp2iq.readIntState.foreach(_ <> intBusyTable.get.io.read)
153730cfbc0SXuan Hu    dp2iq.readVfState.foreach(_ <> vfBusyTable.get.io.read)
154730cfbc0SXuan Hu  }
155730cfbc0SXuan Hu
156730cfbc0SXuan Hu  intBusyTable match {
157730cfbc0SXuan Hu    case Some(bt) =>
158730cfbc0SXuan Hu      bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) =>
159730cfbc0SXuan Hu        btAllocPregs.valid := dpAllocPregs.isInt
160730cfbc0SXuan Hu        btAllocPregs.bits := dpAllocPregs.preg
161730cfbc0SXuan Hu      }
162730cfbc0SXuan Hu      bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) =>
163730cfbc0SXuan Hu        wb.valid := io.intWriteBack(i).wen && io.intWriteBack(i).intWen
164730cfbc0SXuan Hu        wb.bits := io.intWriteBack(i).addr
165730cfbc0SXuan Hu      }
166bc7d6943SzhanglyGit      bt.io.wakeUp := io.fromSchedulers.wakeupVec
167bc7d6943SzhanglyGit      bt.io.cancel := io.fromDataPath.cancelToBusyTable
16813551487SzhanglyGit      bt.io.ldCancel := io.ldCancel
169730cfbc0SXuan Hu    case None =>
170730cfbc0SXuan Hu  }
171730cfbc0SXuan Hu
172730cfbc0SXuan Hu  vfBusyTable match {
173730cfbc0SXuan Hu    case Some(bt) =>
174730cfbc0SXuan Hu      bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) =>
175730cfbc0SXuan Hu        btAllocPregs.valid := dpAllocPregs.isFp
176730cfbc0SXuan Hu        btAllocPregs.bits := dpAllocPregs.preg
177730cfbc0SXuan Hu      }
178730cfbc0SXuan Hu      bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) =>
179730cfbc0SXuan Hu        wb.valid := io.vfWriteBack(i).wen && (io.vfWriteBack(i).fpWen || io.vfWriteBack(i).vecWen)
180730cfbc0SXuan Hu        wb.bits := io.vfWriteBack(i).addr
181730cfbc0SXuan Hu      }
182bc7d6943SzhanglyGit      bt.io.wakeUp := io.fromSchedulers.wakeupVec
183bc7d6943SzhanglyGit      bt.io.cancel := io.fromDataPath.cancelToBusyTable
18413551487SzhanglyGit      bt.io.ldCancel := io.ldCancel
185730cfbc0SXuan Hu    case None =>
186730cfbc0SXuan Hu  }
187730cfbc0SXuan Hu
188f39a61a1SzhanglyGit  val wakeupFromIntWBVec = Wire(params.genIntWBWakeUpSinkValidBundle)
189f39a61a1SzhanglyGit  val wakeupFromVfWBVec = Wire(params.genVfWBWakeUpSinkValidBundle)
190f39a61a1SzhanglyGit
191f39a61a1SzhanglyGit  wakeupFromIntWBVec.zip(io.intWriteBack).foreach { case (sink, source) =>
192f39a61a1SzhanglyGit    sink.valid := source.wen
193f39a61a1SzhanglyGit    sink.bits.rfWen := source.intWen
194f39a61a1SzhanglyGit    sink.bits.fpWen := source.fpWen
195f39a61a1SzhanglyGit    sink.bits.vecWen := source.vecWen
196f39a61a1SzhanglyGit    sink.bits.pdest := source.addr
197730cfbc0SXuan Hu  }
198f39a61a1SzhanglyGit
199f39a61a1SzhanglyGit  wakeupFromVfWBVec.zip(io.vfWriteBack).foreach { case (sink, source) =>
200730cfbc0SXuan Hu    sink.valid := source.wen
201730cfbc0SXuan Hu    sink.bits.rfWen := source.intWen
202730cfbc0SXuan Hu    sink.bits.fpWen := source.fpWen
203730cfbc0SXuan Hu    sink.bits.vecWen := source.vecWen
204730cfbc0SXuan Hu    sink.bits.pdest := source.addr
205730cfbc0SXuan Hu  }
206730cfbc0SXuan Hu
207bf35baadSXuan Hu  // Connect bundles having the same wakeup source
20859ef6009Sxiaofeibao-xjtu  issueQueues.zipWithIndex.foreach { case(iq, i) =>
209bf35baadSXuan Hu    iq.io.wakeupFromIQ.foreach { wakeUp =>
2100c7ebb58Sxiaofeibao-xjtu      val wakeUpIn = iqWakeUpInMap(wakeUp.bits.exuIdx)
2110c7ebb58Sxiaofeibao-xjtu      val exuIdx = wakeUp.bits.exuIdx
2120c7ebb58Sxiaofeibao-xjtu      println(s"[Backend] Connect wakeup exuIdx ${exuIdx}")
2130c7ebb58Sxiaofeibao-xjtu      connectSamePort(wakeUp,wakeUpIn)
2140c7ebb58Sxiaofeibao-xjtu      backendParams.connectWakeup(exuIdx)
2150c7ebb58Sxiaofeibao-xjtu      if (backendParams.isCopyPdest(exuIdx)) {
2160c7ebb58Sxiaofeibao-xjtu        println(s"[Backend] exuIdx ${exuIdx} use pdestCopy ${backendParams.getCopyPdestIndex(exuIdx)}")
2170c7ebb58Sxiaofeibao-xjtu        wakeUp.bits.pdest := wakeUpIn.bits.pdestCopy.get(backendParams.getCopyPdestIndex(exuIdx))
2184c5a0d77Sxiaofeibao-xjtu        if (wakeUpIn.bits.rfWenCopy.nonEmpty) wakeUp.bits.rfWen := wakeUpIn.bits.rfWenCopy.get(backendParams.getCopyPdestIndex(exuIdx))
2194c5a0d77Sxiaofeibao-xjtu        if (wakeUpIn.bits.fpWenCopy.nonEmpty) wakeUp.bits.fpWen := wakeUpIn.bits.fpWenCopy.get(backendParams.getCopyPdestIndex(exuIdx))
2204c5a0d77Sxiaofeibao-xjtu        if (wakeUpIn.bits.vecWenCopy.nonEmpty) wakeUp.bits.vecWen := wakeUpIn.bits.vecWenCopy.get(backendParams.getCopyPdestIndex(exuIdx))
2214c5a0d77Sxiaofeibao-xjtu        if (wakeUpIn.bits.loadDependencyCopy.nonEmpty) wakeUp.bits.loadDependency := wakeUpIn.bits.loadDependencyCopy.get(backendParams.getCopyPdestIndex(exuIdx))
2220c7ebb58Sxiaofeibao-xjtu      }
22360912d84Sxiaofeibao-xjtu      if (iq.params.numIntSrc == 0) wakeUp.bits.rfWen := false.B
22460912d84Sxiaofeibao-xjtu      if (iq.params.numFpSrc == 0)  wakeUp.bits.fpWen := false.B
22560912d84Sxiaofeibao-xjtu      if (iq.params.numVfSrc == 0)  wakeUp.bits.vecWen := false.B
226bf35baadSXuan Hu    }
227ea46c302SXuan Hu    iq.io.og0Cancel := io.fromDataPath.og0Cancel
228ea46c302SXuan Hu    iq.io.og1Cancel := io.fromDataPath.og1Cancel
2290f55a0d3SHaojin Tang    iq.io.ldCancel := io.ldCancel
230bf35baadSXuan Hu  }
231bf35baadSXuan Hu
232c0be7f33SXuan Hu  private val iqWakeUpOutMap: Map[Int, ValidIO[IssueQueueIQWakeUpBundle]] =
233bf35baadSXuan Hu    issueQueues.flatMap(_.io.wakeupToIQ)
234c0be7f33SXuan Hu      .map(x => (x.bits.exuIdx, x))
235bf35baadSXuan Hu      .toMap
236bf35baadSXuan Hu
237bf35baadSXuan Hu  // Connect bundles having the same wakeup source
238bf35baadSXuan Hu  io.toSchedulers.wakeupVec.foreach { wakeUp =>
239c0be7f33SXuan Hu    wakeUp := iqWakeUpOutMap(wakeUp.bits.exuIdx)
240bf35baadSXuan Hu  }
241bf35baadSXuan Hu
24259ef6009Sxiaofeibao-xjtu  io.toDataPathAfterDelay.zipWithIndex.foreach { case (toDpDy, i) =>
24359ef6009Sxiaofeibao-xjtu    toDpDy <> issueQueues(i).io.deqDelay
24459ef6009Sxiaofeibao-xjtu  }
245bf35baadSXuan Hu
246f99b81adSHaojin Tang  // Response
247f99b81adSHaojin Tang  issueQueues.zipWithIndex.foreach { case (iq, i) =>
248f99b81adSHaojin Tang    iq.io.og0Resp.zipWithIndex.foreach { case (og0Resp, j) =>
249f99b81adSHaojin Tang      og0Resp := io.fromDataPath(i)(j).og0resp
250f99b81adSHaojin Tang    }
251f99b81adSHaojin Tang    iq.io.og1Resp.zipWithIndex.foreach { case (og1Resp, j) =>
252f99b81adSHaojin Tang      og1Resp := io.fromDataPath(i)(j).og1resp
253f99b81adSHaojin Tang    }
254f99b81adSHaojin Tang    iq.io.finalIssueResp.foreach(_.zipWithIndex.foreach { case (finalIssueResp, j) =>
255670870b3SXuan Hu      if (io.loadFinalIssueResp(i).isDefinedAt(j)) {
256f99b81adSHaojin Tang        finalIssueResp := io.loadFinalIssueResp(i)(j)
257670870b3SXuan Hu      } else {
258670870b3SXuan Hu        finalIssueResp := 0.U.asTypeOf(finalIssueResp)
259670870b3SXuan Hu      }
260f99b81adSHaojin Tang    })
261e8800897SXuan Hu    iq.io.memAddrIssueResp.foreach(_.zipWithIndex.foreach { case (memAddrIssueResp, j) =>
262aa2bcc31SzhanglyGit      if (io.memAddrIssueResp(i).isDefinedAt(j)) {
263e8800897SXuan Hu        memAddrIssueResp := io.memAddrIssueResp(i)(j)
264aa2bcc31SzhanglyGit      } else {
265aa2bcc31SzhanglyGit        memAddrIssueResp := 0.U.asTypeOf(memAddrIssueResp)
266aa2bcc31SzhanglyGit      }
267e8800897SXuan Hu    })
268f99b81adSHaojin Tang    iq.io.wbBusyTableRead := io.fromWbFuBusyTable.fuBusyTableRead(i)
269f99b81adSHaojin Tang    io.wbFuBusyTable(i) := iq.io.wbBusyTableWrite
270f99b81adSHaojin Tang  }
271f99b81adSHaojin Tang
272c0be7f33SXuan Hu  println(s"[Scheduler] io.fromSchedulers.wakeupVec: ${io.fromSchedulers.wakeupVec.map(x => backendParams.getExuName(x.bits.exuIdx))}")
273bf35baadSXuan Hu  println(s"[Scheduler] iqWakeUpInKeys: ${iqWakeUpInMap.keys}")
274bf35baadSXuan Hu
275bf35baadSXuan Hu  println(s"[Scheduler] iqWakeUpOutKeys: ${iqWakeUpOutMap.keys}")
276c0be7f33SXuan Hu  println(s"[Scheduler] io.toSchedulers.wakeupVec: ${io.toSchedulers.wakeupVec.map(x => backendParams.getExuName(x.bits.exuIdx))}")
277730cfbc0SXuan Hu}
278730cfbc0SXuan Hu
279730cfbc0SXuan Huclass SchedulerArithImp(override val wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters)
280730cfbc0SXuan Hu  extends SchedulerImpBase(wrapper)
281730cfbc0SXuan Hu    with HasXSParameter
282730cfbc0SXuan Hu{
2832e0a7dc5Sfdy//  dontTouch(io.vfWbFuBusyTable)
284730cfbc0SXuan Hu  println(s"[SchedulerArithImp] " +
285730cfbc0SXuan Hu    s"has intBusyTable: ${intBusyTable.nonEmpty}, " +
286730cfbc0SXuan Hu    s"has vfBusyTable: ${vfBusyTable.nonEmpty}")
287730cfbc0SXuan Hu
288730cfbc0SXuan Hu  issueQueues.zipWithIndex.foreach { case (iq, i) =>
289730cfbc0SXuan Hu    iq.io.flush <> io.fromCtrlBlock.flush
290730cfbc0SXuan Hu    iq.io.enq <> dispatch2Iq.io.out(i)
291f39a61a1SzhanglyGit    val intWBIQ = params.schdType match {
292f39a61a1SzhanglyGit      case IntScheduler() => wakeupFromIntWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromIntWBPort.keys.toSeq.contains(x._2)).map(_._1)
293f39a61a1SzhanglyGit      case VfScheduler() => wakeupFromVfWBVec
294596af5d2SHaojin Tang      case _ => null
295f39a61a1SzhanglyGit    }
296f39a61a1SzhanglyGit    iq.io.wakeupFromWB.zip(intWBIQ).foreach{ case (sink, source) => sink := source}
297730cfbc0SXuan Hu  }
298730cfbc0SXuan Hu}
299730cfbc0SXuan Hu
300f99b81adSHaojin Tang// FIXME: Vector mem instructions may not be handled properly!
301730cfbc0SXuan Huclass SchedulerMemImp(override val wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters)
302730cfbc0SXuan Hu  extends SchedulerImpBase(wrapper)
303730cfbc0SXuan Hu    with HasXSParameter
304730cfbc0SXuan Hu{
305730cfbc0SXuan Hu  println(s"[SchedulerMemImp] " +
306730cfbc0SXuan Hu    s"has intBusyTable: ${intBusyTable.nonEmpty}, " +
307730cfbc0SXuan Hu    s"has vfBusyTable: ${vfBusyTable.nonEmpty}")
308730cfbc0SXuan Hu
309559c1710SHaojin Tang  val memAddrIQs = issueQueues.filter(_.params.isMemAddrIQ)
310e07131b2Ssinsanction  val stAddrIQs = issueQueues.filter(iq => iq.params.StaCnt > 0) // included in memAddrIQs
311e07131b2Ssinsanction  val ldAddrIQs = issueQueues.filter(iq => iq.params.LduCnt > 0)
312e07131b2Ssinsanction  val stDataIQs = issueQueues.filter(iq => iq.params.StdCnt > 0)
313559c1710SHaojin Tang  val vecMemIQs = issueQueues.filter(_.params.isVecMemIQ)
314559c1710SHaojin Tang  val (hyuIQs, hyuIQIdxs) = issueQueues.zipWithIndex.filter(_._1.params.HyuCnt > 0).unzip
315499caf4cSXuan Hu
316499caf4cSXuan Hu  println(s"[SchedulerMemImp] memAddrIQs.size: ${memAddrIQs.size}, enq.size: ${memAddrIQs.map(_.io.enq.size).sum}")
317499caf4cSXuan Hu  println(s"[SchedulerMemImp] stAddrIQs.size:  ${stAddrIQs.size }, enq.size: ${stAddrIQs.map(_.io.enq.size).sum}")
318499caf4cSXuan Hu  println(s"[SchedulerMemImp] ldAddrIQs.size:  ${ldAddrIQs.size }, enq.size: ${ldAddrIQs.map(_.io.enq.size).sum}")
319499caf4cSXuan Hu  println(s"[SchedulerMemImp] stDataIQs.size:  ${stDataIQs.size }, enq.size: ${stDataIQs.map(_.io.enq.size).sum}")
320499caf4cSXuan Hu  println(s"[SchedulerMemImp] hyuIQs.size:     ${hyuIQs.size    }, enq.size: ${hyuIQs.map(_.io.enq.size).sum}")
321730cfbc0SXuan Hu  require(memAddrIQs.nonEmpty && stDataIQs.nonEmpty)
322730cfbc0SXuan Hu
323853cd2d8SHaojin Tang  io.toMem.get.loadFastMatch := 0.U.asTypeOf(io.toMem.get.loadFastMatch) // TODO: is still needed?
324853cd2d8SHaojin Tang
325fc45ed13SXuan Hu  private val loadWakeUp = issueQueues.filter(_.params.LdExuCnt > 0).map(_.asInstanceOf[IssueQueueMemAddrImp].io.memIO.get.loadWakeUp).flatten
326596af5d2SHaojin Tang  require(loadWakeUp.length == io.fromMem.get.wakeup.length)
327596af5d2SHaojin Tang  loadWakeUp.zip(io.fromMem.get.wakeup).foreach(x => x._1 := x._2)
328596af5d2SHaojin Tang
329730cfbc0SXuan Hu  memAddrIQs.zipWithIndex.foreach { case (iq, i) =>
330730cfbc0SXuan Hu    iq.io.flush <> io.fromCtrlBlock.flush
331730cfbc0SXuan Hu    iq.io.enq <> dispatch2Iq.io.out(i)
332f39a61a1SzhanglyGit    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}
333730cfbc0SXuan Hu  }
334730cfbc0SXuan Hu
335ecfc6f16SXuan Hu  ldAddrIQs.zipWithIndex.foreach {
336ecfc6f16SXuan Hu    case (imp: IssueQueueMemAddrImp, i) =>
337ecfc6f16SXuan Hu      imp.io.memIO.get.feedbackIO.head := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO.head)
338c14e89f4SHaojin Tang      imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr
339de784418SXuan Hu      imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
3407b753bebSXuan Hu    case _ =>
3417b753bebSXuan Hu  }
3427b753bebSXuan Hu
343ecfc6f16SXuan Hu  stAddrIQs.zipWithIndex.foreach {
344ecfc6f16SXuan Hu    case (imp: IssueQueueMemAddrImp, i) =>
345ecfc6f16SXuan Hu      imp.io.memIO.get.feedbackIO.head := io.fromMem.get.staFeedback(i)
346c14e89f4SHaojin Tang      imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr
347c14e89f4SHaojin Tang      imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
3487b753bebSXuan Hu    case _ =>
3497b753bebSXuan Hu  }
350730cfbc0SXuan Hu
351559c1710SHaojin Tang  hyuIQs.zip(hyuIQIdxs).foreach {
352559c1710SHaojin Tang    case (imp: IssueQueueMemAddrImp, idx) =>
353670870b3SXuan Hu      imp.io.memIO.get.feedbackIO.head := io.fromMem.get.hyuFeedback.head
354670870b3SXuan Hu      imp.io.memIO.get.feedbackIO(1) := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO(1))
3558f1fa9b1Ssfencevma      imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr
3568f1fa9b1Ssfencevma      imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
357559c1710SHaojin Tang      // TODO: refactor ditry code
358559c1710SHaojin Tang      imp.io.deqDelay(1).ready := false.B
359559c1710SHaojin Tang      io.toDataPathAfterDelay(idx)(1).valid := false.B
360559c1710SHaojin Tang      io.toDataPathAfterDelay(idx)(1).bits := 0.U.asTypeOf(io.toDataPathAfterDelay(idx)(1).bits)
3618f1fa9b1Ssfencevma    case _ =>
3628f1fa9b1Ssfencevma  }
3638f1fa9b1Ssfencevma
364e62b6911SXuan Hu  private val staIdxSeq = (stAddrIQs).map(iq => iq.params.idxInSchBlk)
365e62b6911SXuan Hu  private val hyaIdxSeq = (hyuIQs).map(iq => iq.params.idxInSchBlk)
366e62b6911SXuan Hu
367e62b6911SXuan Hu  println(s"[SchedulerMemImp] sta iq idx in memSchdBlock: $staIdxSeq")
368e62b6911SXuan Hu  println(s"[SchedulerMemImp] hya iq idx in memSchdBlock: $hyaIdxSeq")
369e62b6911SXuan Hu
370e62b6911SXuan Hu  private val staEnqs = stAddrIQs.map(_.io.enq).flatten
371e62b6911SXuan Hu  private val stdEnqs = stDataIQs.map(_.io.enq).flatten.take(staEnqs.size)
372e62b6911SXuan Hu  private val hyaEnqs = hyuIQs.map(_.io.enq).flatten
373e62b6911SXuan Hu  private val hydEnqs = stDataIQs.map(_.io.enq).flatten.drop(staEnqs.size)
374e62b6911SXuan Hu
375e62b6911SXuan Hu  require(staEnqs.size == stdEnqs.size, s"number of enq ports of store address IQs(${staEnqs.size}) " +
376e62b6911SXuan Hu  s"should be equal to number of enq ports of store data IQs(${stdEnqs.size})")
377e62b6911SXuan Hu
378e62b6911SXuan Hu  require(hyaEnqs.size == hydEnqs.size, s"number of enq ports of hybrid address IQs(${hyaEnqs.size}) " +
379e62b6911SXuan Hu  s"should be equal to number of enq ports of hybrid data IQs(${hydEnqs.size})")
3809b258a00Sxgkiri
3810438e8f4SHaojin Tang  val d2IqStaOut = dispatch2Iq.io.out.zipWithIndex.filter(staIdxSeq contains _._2).unzip._1.flatten
3820438e8f4SHaojin Tang  d2IqStaOut.zip(staEnqs).zip(stdEnqs).foreach{ case((dp, staIQ), stdIQ) =>
383730cfbc0SXuan Hu    val isAllReady = staIQ.ready && stdIQ.ready
384e62b6911SXuan Hu    dp.ready := isAllReady
385e62b6911SXuan Hu    staIQ.valid := dp.valid && isAllReady
3860438e8f4SHaojin Tang    stdIQ.valid := dp.valid && isAllReady && FuType.FuTypeOrR(dp.bits.fuType, FuType.stu, FuType.mou)
3879b258a00Sxgkiri  }
388730cfbc0SXuan Hu
3890438e8f4SHaojin Tang  val d2IqHyaOut = dispatch2Iq.io.out.zipWithIndex.filter(hyaIdxSeq contains _._2).unzip._1.flatten
3900438e8f4SHaojin Tang  d2IqHyaOut.zip(hyaEnqs).zip(hydEnqs).foreach{ case((dp, hyaIQ), hydIQ) =>
391e62b6911SXuan Hu    val isAllReady = hyaIQ.ready && hydIQ.ready
392e62b6911SXuan Hu    dp.ready := isAllReady
393e62b6911SXuan Hu    hyaIQ.valid := dp.valid && isAllReady
39456bceacbSHaojin Tang    hydIQ.valid := dp.valid && isAllReady && FuType.FuTypeOrR(dp.bits.fuType, FuType.stu, FuType.mou)
395e62b6911SXuan Hu  }
396730cfbc0SXuan Hu
397e62b6911SXuan Hu  stDataIQs.zipWithIndex.foreach { case (iq, i) =>
398e62b6911SXuan Hu    iq.io.flush <> io.fromCtrlBlock.flush
399f39a61a1SzhanglyGit    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}
400e62b6911SXuan Hu  }
401e62b6911SXuan Hu
402e62b6911SXuan Hu  (stdEnqs ++ hydEnqs).zip(staEnqs ++ hyaEnqs).zipWithIndex.foreach { case ((stdIQEnq, staIQEnq), i) =>
403730cfbc0SXuan Hu    stdIQEnq.bits  := staIQEnq.bits
404730cfbc0SXuan Hu    // Store data reuses store addr src(1) in dispatch2iq
405e62b6911SXuan Hu    // [dispatch2iq] --src*------src*(0)--> [staIQ|hyaIQ]
406730cfbc0SXuan Hu    //                       \
407730cfbc0SXuan Hu    //                        ---src*(1)--> [stdIQ]
408730cfbc0SXuan Hu    // Since the src(1) of sta is easier to get, stdIQEnq.bits.src*(0) is assigned to staIQEnq.bits.src*(1)
409730cfbc0SXuan Hu    // instead of dispatch2Iq.io.out(x).bits.src*(1)
41097b279b9SXuan Hu    val stdIdx = 1
4112d270511Ssinsanction    stdIQEnq.bits.srcState(0) := staIQEnq.bits.srcState(stdIdx)
41213551487SzhanglyGit    stdIQEnq.bits.srcLoadDependency(0) := staIQEnq.bits.srcLoadDependency(1)
4132d270511Ssinsanction      stdIQEnq.bits.srcType(0) := staIQEnq.bits.srcType(stdIdx)
4142d270511Ssinsanction    stdIQEnq.bits.psrc(0) := staIQEnq.bits.psrc(stdIdx)
415730cfbc0SXuan Hu    stdIQEnq.bits.sqIdx := staIQEnq.bits.sqIdx
416730cfbc0SXuan Hu  }
417730cfbc0SXuan Hu
4182d270511Ssinsanction  vecMemIQs.foreach {
4192d270511Ssinsanction    case imp: IssueQueueVecMemImp =>
4202d270511Ssinsanction      imp.io.memIO.get.sqDeqPtr.foreach(_ := io.fromMem.get.sqDeqPtr)
4212d270511Ssinsanction      imp.io.memIO.get.lqDeqPtr.foreach(_ := io.fromMem.get.lqDeqPtr)
4221f3d1b4dSXuan Hu      // not used
423*ebb914e7Sweiding liu      imp.io.memIO.get.feedbackIO.head := io.fromMem.get.vstuFeedback.head // only vector store replay
4241f3d1b4dSXuan Hu      // maybe not used
4251f3d1b4dSXuan Hu      imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr
4261f3d1b4dSXuan Hu      imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
427f39a61a1SzhanglyGit      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}
428f39a61a1SzhanglyGit
4292d270511Ssinsanction    case _ =>
4302d270511Ssinsanction  }
4312d270511Ssinsanction
432730cfbc0SXuan Hu  val lsqEnqCtrl = Module(new LsqEnqCtrl)
433730cfbc0SXuan Hu
434730cfbc0SXuan Hu  lsqEnqCtrl.io.redirect <> io.fromCtrlBlock.flush
435730cfbc0SXuan Hu  lsqEnqCtrl.io.enq <> dispatch2Iq.io.enqLsqIO.get
436730cfbc0SXuan Hu  lsqEnqCtrl.io.lcommit := io.fromMem.get.lcommit
437730cfbc0SXuan Hu  lsqEnqCtrl.io.scommit := io.fromMem.get.scommit
438730cfbc0SXuan Hu  lsqEnqCtrl.io.lqCancelCnt := io.fromMem.get.lqCancelCnt
439730cfbc0SXuan Hu  lsqEnqCtrl.io.sqCancelCnt := io.fromMem.get.sqCancelCnt
440f3a9fb05SAnzo  dispatch2Iq.io.lqFreeCount.get := lsqEnqCtrl.io.lqFreeCount
441f3a9fb05SAnzo  dispatch2Iq.io.sqFreeCount.get := lsqEnqCtrl.io.sqFreeCount
442730cfbc0SXuan Hu  io.memIO.get.lsqEnqIO <> lsqEnqCtrl.io.enqLsq
443730cfbc0SXuan Hu}
444