xref: /XiangShan/src/main/scala/xiangshan/backend/issue/Scheduler.scala (revision fc45ed1367d8867aa0b56c7c216e2ca7fc563f76)
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
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))
97730cfbc0SXuan Hu    val stIssuePtr = Input(new SqPtr())
98730cfbc0SXuan Hu    val lcommit = Input(UInt(log2Up(CommitWidth + 1).W))
99730cfbc0SXuan Hu    val scommit = Input(UInt(log2Ceil(EnsbufferWidth + 1).W)) // connected to `memBlock.io.sqDeq` instead of ROB
100*fc45ed13SXuan Hu    val wakeup = Vec(params.LdExuCnt, Flipped(Valid(new DynInst)))
1012d270511Ssinsanction    val lqDeqPtr = Input(new LqPtr)
1022d270511Ssinsanction    val sqDeqPtr = Input(new SqPtr)
103730cfbc0SXuan Hu    // from lsq
104730cfbc0SXuan Hu    val lqCancelCnt = Input(UInt(log2Up(LoadQueueSize + 1).W))
105730cfbc0SXuan Hu    val sqCancelCnt = Input(UInt(log2Up(StoreQueueSize + 1).W))
106730cfbc0SXuan Hu    val memWaitUpdateReq = Flipped(new MemWaitUpdateReq)
107730cfbc0SXuan Hu  }) else None
108730cfbc0SXuan Hu  val toMem = if (params.isMemSchd) Some(new Bundle {
109730cfbc0SXuan Hu    val loadFastMatch = Output(Vec(params.LduCnt, new IssueQueueLoadBundle))
110730cfbc0SXuan Hu  }) else None
111730cfbc0SXuan Hu}
112730cfbc0SXuan Hu
113730cfbc0SXuan Huabstract class SchedulerImpBase(wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters)
114730cfbc0SXuan Hu  extends LazyModuleImp(wrapper)
115730cfbc0SXuan Hu    with HasXSParameter
116730cfbc0SXuan Hu{
117730cfbc0SXuan Hu  val io = IO(new SchedulerIO())
118730cfbc0SXuan Hu
119730cfbc0SXuan Hu  // alias
120c0be7f33SXuan Hu  private val iqWakeUpInMap: Map[Int, ValidIO[IssueQueueIQWakeUpBundle]] =
121c0be7f33SXuan Hu    io.fromSchedulers.wakeupVec.map(x => (x.bits.exuIdx, x)).toMap
122730cfbc0SXuan Hu  private val schdType = params.schdType
123730cfbc0SXuan Hu
124730cfbc0SXuan Hu  // Modules
125730cfbc0SXuan Hu  val dispatch2Iq: Dispatch2IqImp = wrapper.dispatch2Iq.module
126730cfbc0SXuan Hu  val issueQueues: Seq[IssueQueueImp] = wrapper.issueQueue.map(_.module)
127730cfbc0SXuan Hu
12856bcaed7SHaojin Tang  // valid count
12956bcaed7SHaojin Tang  dispatch2Iq.io.iqValidCnt := issueQueues.filter(_.params.StdCnt == 0).map(_.io.status.validCnt)
13056bcaed7SHaojin Tang
131730cfbc0SXuan Hu  // BusyTable Modules
132730cfbc0SXuan Hu  val intBusyTable = schdType match {
133bc7d6943SzhanglyGit    case IntScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numIntStateRead, wrapper.numIntStateWrite, IntPhyRegs, IntWB())))
134730cfbc0SXuan Hu    case _ => None
135730cfbc0SXuan Hu  }
136730cfbc0SXuan Hu
137730cfbc0SXuan Hu  val vfBusyTable = schdType match {
138bc7d6943SzhanglyGit    case VfScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numVfStateRead, wrapper.numVfStateWrite, VfPhyRegs, VfWB())))
139730cfbc0SXuan Hu    case _ => None
140730cfbc0SXuan Hu  }
141730cfbc0SXuan Hu
142730cfbc0SXuan Hu  dispatch2Iq.io match { case dp2iq =>
143730cfbc0SXuan Hu    dp2iq.redirect <> io.fromCtrlBlock.flush
144730cfbc0SXuan Hu    dp2iq.in <> io.fromDispatch.uops
145730cfbc0SXuan Hu    dp2iq.readIntState.foreach(_ <> intBusyTable.get.io.read)
146730cfbc0SXuan Hu    dp2iq.readVfState.foreach(_ <> vfBusyTable.get.io.read)
147730cfbc0SXuan Hu  }
148730cfbc0SXuan Hu
149730cfbc0SXuan Hu  intBusyTable match {
150730cfbc0SXuan Hu    case Some(bt) =>
151730cfbc0SXuan Hu      bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) =>
152730cfbc0SXuan Hu        btAllocPregs.valid := dpAllocPregs.isInt
153730cfbc0SXuan Hu        btAllocPregs.bits := dpAllocPregs.preg
154730cfbc0SXuan Hu      }
155730cfbc0SXuan Hu      bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) =>
156730cfbc0SXuan Hu        wb.valid := io.intWriteBack(i).wen && io.intWriteBack(i).intWen
157730cfbc0SXuan Hu        wb.bits := io.intWriteBack(i).addr
158730cfbc0SXuan Hu      }
159bc7d6943SzhanglyGit      bt.io.wakeUp := io.fromSchedulers.wakeupVec
160bc7d6943SzhanglyGit      bt.io.cancel := io.fromDataPath.cancelToBusyTable
16113551487SzhanglyGit      bt.io.ldCancel := io.ldCancel
162730cfbc0SXuan Hu    case None =>
163730cfbc0SXuan Hu  }
164730cfbc0SXuan Hu
165730cfbc0SXuan Hu  vfBusyTable match {
166730cfbc0SXuan Hu    case Some(bt) =>
167730cfbc0SXuan Hu      bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) =>
168730cfbc0SXuan Hu        btAllocPregs.valid := dpAllocPregs.isFp
169730cfbc0SXuan Hu        btAllocPregs.bits := dpAllocPregs.preg
170730cfbc0SXuan Hu      }
171730cfbc0SXuan Hu      bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) =>
172730cfbc0SXuan Hu        wb.valid := io.vfWriteBack(i).wen && (io.vfWriteBack(i).fpWen || io.vfWriteBack(i).vecWen)
173730cfbc0SXuan Hu        wb.bits := io.vfWriteBack(i).addr
174730cfbc0SXuan Hu      }
175bc7d6943SzhanglyGit      bt.io.wakeUp := io.fromSchedulers.wakeupVec
176bc7d6943SzhanglyGit      bt.io.cancel := io.fromDataPath.cancelToBusyTable
17713551487SzhanglyGit      bt.io.ldCancel := io.ldCancel
178730cfbc0SXuan Hu    case None =>
179730cfbc0SXuan Hu  }
180730cfbc0SXuan Hu
181f39a61a1SzhanglyGit  val wakeupFromIntWBVec = Wire(params.genIntWBWakeUpSinkValidBundle)
182f39a61a1SzhanglyGit  val wakeupFromVfWBVec = Wire(params.genVfWBWakeUpSinkValidBundle)
183f39a61a1SzhanglyGit
184f39a61a1SzhanglyGit  wakeupFromIntWBVec.zip(io.intWriteBack).foreach { case (sink, source) =>
185f39a61a1SzhanglyGit    sink.valid := source.wen
186f39a61a1SzhanglyGit    sink.bits.rfWen := source.intWen
187f39a61a1SzhanglyGit    sink.bits.fpWen := source.fpWen
188f39a61a1SzhanglyGit    sink.bits.vecWen := source.vecWen
189f39a61a1SzhanglyGit    sink.bits.pdest := source.addr
190730cfbc0SXuan Hu  }
191f39a61a1SzhanglyGit
192f39a61a1SzhanglyGit  wakeupFromVfWBVec.zip(io.vfWriteBack).foreach { case (sink, source) =>
193730cfbc0SXuan Hu    sink.valid := source.wen
194730cfbc0SXuan Hu    sink.bits.rfWen := source.intWen
195730cfbc0SXuan Hu    sink.bits.fpWen := source.fpWen
196730cfbc0SXuan Hu    sink.bits.vecWen := source.vecWen
197730cfbc0SXuan Hu    sink.bits.pdest := source.addr
198730cfbc0SXuan Hu  }
199730cfbc0SXuan Hu
200bf35baadSXuan Hu  // Connect bundles having the same wakeup source
20159ef6009Sxiaofeibao-xjtu  issueQueues.zipWithIndex.foreach { case(iq, i) =>
202bf35baadSXuan Hu    iq.io.wakeupFromIQ.foreach { wakeUp =>
2030c7ebb58Sxiaofeibao-xjtu      val wakeUpIn = iqWakeUpInMap(wakeUp.bits.exuIdx)
2040c7ebb58Sxiaofeibao-xjtu      val exuIdx = wakeUp.bits.exuIdx
2050c7ebb58Sxiaofeibao-xjtu      println(s"[Backend] Connect wakeup exuIdx ${exuIdx}")
2060c7ebb58Sxiaofeibao-xjtu      connectSamePort(wakeUp,wakeUpIn)
2070c7ebb58Sxiaofeibao-xjtu      backendParams.connectWakeup(exuIdx)
2080c7ebb58Sxiaofeibao-xjtu      if (backendParams.isCopyPdest(exuIdx)) {
2090c7ebb58Sxiaofeibao-xjtu        println(s"[Backend] exuIdx ${exuIdx} use pdestCopy ${backendParams.getCopyPdestIndex(exuIdx)}")
2100c7ebb58Sxiaofeibao-xjtu        wakeUp.bits.pdest := wakeUpIn.bits.pdestCopy.get(backendParams.getCopyPdestIndex(exuIdx))
2114c5a0d77Sxiaofeibao-xjtu        if (wakeUpIn.bits.rfWenCopy.nonEmpty) wakeUp.bits.rfWen := wakeUpIn.bits.rfWenCopy.get(backendParams.getCopyPdestIndex(exuIdx))
2124c5a0d77Sxiaofeibao-xjtu        if (wakeUpIn.bits.fpWenCopy.nonEmpty) wakeUp.bits.fpWen := wakeUpIn.bits.fpWenCopy.get(backendParams.getCopyPdestIndex(exuIdx))
2134c5a0d77Sxiaofeibao-xjtu        if (wakeUpIn.bits.vecWenCopy.nonEmpty) wakeUp.bits.vecWen := wakeUpIn.bits.vecWenCopy.get(backendParams.getCopyPdestIndex(exuIdx))
2144c5a0d77Sxiaofeibao-xjtu        if (wakeUpIn.bits.loadDependencyCopy.nonEmpty) wakeUp.bits.loadDependency := wakeUpIn.bits.loadDependencyCopy.get(backendParams.getCopyPdestIndex(exuIdx))
2150c7ebb58Sxiaofeibao-xjtu      }
21660912d84Sxiaofeibao-xjtu      if (iq.params.numIntSrc == 0) wakeUp.bits.rfWen := false.B
21760912d84Sxiaofeibao-xjtu      if (iq.params.numFpSrc == 0)  wakeUp.bits.fpWen := false.B
21860912d84Sxiaofeibao-xjtu      if (iq.params.numVfSrc == 0)  wakeUp.bits.vecWen := false.B
219bf35baadSXuan Hu    }
220ea46c302SXuan Hu    iq.io.og0Cancel := io.fromDataPath.og0Cancel
221ea46c302SXuan Hu    iq.io.og1Cancel := io.fromDataPath.og1Cancel
2220f55a0d3SHaojin Tang    iq.io.ldCancel := io.ldCancel
223bf35baadSXuan Hu  }
224bf35baadSXuan Hu
225c0be7f33SXuan Hu  private val iqWakeUpOutMap: Map[Int, ValidIO[IssueQueueIQWakeUpBundle]] =
226bf35baadSXuan Hu    issueQueues.flatMap(_.io.wakeupToIQ)
227c0be7f33SXuan Hu      .map(x => (x.bits.exuIdx, x))
228bf35baadSXuan Hu      .toMap
229bf35baadSXuan Hu
230bf35baadSXuan Hu  // Connect bundles having the same wakeup source
231bf35baadSXuan Hu  io.toSchedulers.wakeupVec.foreach { wakeUp =>
232c0be7f33SXuan Hu    wakeUp := iqWakeUpOutMap(wakeUp.bits.exuIdx)
233bf35baadSXuan Hu  }
234bf35baadSXuan Hu
23559ef6009Sxiaofeibao-xjtu  io.toDataPathAfterDelay.zipWithIndex.foreach { case (toDpDy, i) =>
23659ef6009Sxiaofeibao-xjtu    toDpDy <> issueQueues(i).io.deqDelay
23759ef6009Sxiaofeibao-xjtu  }
238bf35baadSXuan Hu
239f99b81adSHaojin Tang  // Response
240f99b81adSHaojin Tang  issueQueues.zipWithIndex.foreach { case (iq, i) =>
241f99b81adSHaojin Tang    iq.io.og0Resp.zipWithIndex.foreach { case (og0Resp, j) =>
242f99b81adSHaojin Tang      og0Resp := io.fromDataPath(i)(j).og0resp
243f99b81adSHaojin Tang    }
244f99b81adSHaojin Tang    iq.io.og1Resp.zipWithIndex.foreach { case (og1Resp, j) =>
245f99b81adSHaojin Tang      og1Resp := io.fromDataPath(i)(j).og1resp
246f99b81adSHaojin Tang    }
247f99b81adSHaojin Tang    iq.io.finalIssueResp.foreach(_.zipWithIndex.foreach { case (finalIssueResp, j) =>
248670870b3SXuan Hu      if (io.loadFinalIssueResp(i).isDefinedAt(j)) {
249f99b81adSHaojin Tang        finalIssueResp := io.loadFinalIssueResp(i)(j)
250670870b3SXuan Hu      } else {
251670870b3SXuan Hu        finalIssueResp := 0.U.asTypeOf(finalIssueResp)
252670870b3SXuan Hu      }
253f99b81adSHaojin Tang    })
254e8800897SXuan Hu    iq.io.memAddrIssueResp.foreach(_.zipWithIndex.foreach { case (memAddrIssueResp, j) =>
255aa2bcc31SzhanglyGit      if (io.memAddrIssueResp(i).isDefinedAt(j)) {
256e8800897SXuan Hu        memAddrIssueResp := io.memAddrIssueResp(i)(j)
257aa2bcc31SzhanglyGit      } else {
258aa2bcc31SzhanglyGit        memAddrIssueResp := 0.U.asTypeOf(memAddrIssueResp)
259aa2bcc31SzhanglyGit      }
260e8800897SXuan Hu    })
261f99b81adSHaojin Tang    iq.io.wbBusyTableRead := io.fromWbFuBusyTable.fuBusyTableRead(i)
262f99b81adSHaojin Tang    io.wbFuBusyTable(i) := iq.io.wbBusyTableWrite
263f99b81adSHaojin Tang  }
264f99b81adSHaojin Tang
265c0be7f33SXuan Hu  println(s"[Scheduler] io.fromSchedulers.wakeupVec: ${io.fromSchedulers.wakeupVec.map(x => backendParams.getExuName(x.bits.exuIdx))}")
266bf35baadSXuan Hu  println(s"[Scheduler] iqWakeUpInKeys: ${iqWakeUpInMap.keys}")
267bf35baadSXuan Hu
268bf35baadSXuan Hu  println(s"[Scheduler] iqWakeUpOutKeys: ${iqWakeUpOutMap.keys}")
269c0be7f33SXuan Hu  println(s"[Scheduler] io.toSchedulers.wakeupVec: ${io.toSchedulers.wakeupVec.map(x => backendParams.getExuName(x.bits.exuIdx))}")
270730cfbc0SXuan Hu}
271730cfbc0SXuan Hu
272730cfbc0SXuan Huclass SchedulerArithImp(override val wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters)
273730cfbc0SXuan Hu  extends SchedulerImpBase(wrapper)
274730cfbc0SXuan Hu    with HasXSParameter
275730cfbc0SXuan Hu{
2762e0a7dc5Sfdy//  dontTouch(io.vfWbFuBusyTable)
277730cfbc0SXuan Hu  println(s"[SchedulerArithImp] " +
278730cfbc0SXuan Hu    s"has intBusyTable: ${intBusyTable.nonEmpty}, " +
279730cfbc0SXuan Hu    s"has vfBusyTable: ${vfBusyTable.nonEmpty}")
280730cfbc0SXuan Hu
281730cfbc0SXuan Hu  issueQueues.zipWithIndex.foreach { case (iq, i) =>
282730cfbc0SXuan Hu    iq.io.flush <> io.fromCtrlBlock.flush
283730cfbc0SXuan Hu    iq.io.enq <> dispatch2Iq.io.out(i)
284f39a61a1SzhanglyGit    val intWBIQ = params.schdType match {
285f39a61a1SzhanglyGit      case IntScheduler() => wakeupFromIntWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromIntWBPort.keys.toSeq.contains(x._2)).map(_._1)
286f39a61a1SzhanglyGit      case VfScheduler() => wakeupFromVfWBVec
287596af5d2SHaojin Tang      case _ => null
288f39a61a1SzhanglyGit    }
289f39a61a1SzhanglyGit    iq.io.wakeupFromWB.zip(intWBIQ).foreach{ case (sink, source) => sink := source}
290730cfbc0SXuan Hu  }
291730cfbc0SXuan Hu}
292730cfbc0SXuan Hu
293f99b81adSHaojin Tang// FIXME: Vector mem instructions may not be handled properly!
294730cfbc0SXuan Huclass SchedulerMemImp(override val wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters)
295730cfbc0SXuan Hu  extends SchedulerImpBase(wrapper)
296730cfbc0SXuan Hu    with HasXSParameter
297730cfbc0SXuan Hu{
298730cfbc0SXuan Hu  println(s"[SchedulerMemImp] " +
299730cfbc0SXuan Hu    s"has intBusyTable: ${intBusyTable.nonEmpty}, " +
300730cfbc0SXuan Hu    s"has vfBusyTable: ${vfBusyTable.nonEmpty}")
301730cfbc0SXuan Hu
302559c1710SHaojin Tang  val memAddrIQs = issueQueues.filter(_.params.isMemAddrIQ)
3032d270511Ssinsanction  val stAddrIQs = issueQueues.filter(iq => iq.params.StaCnt > 0 || iq.params.VstaCnt > 0) // included in memAddrIQs
3042d270511Ssinsanction  val ldAddrIQs = issueQueues.filter(iq => iq.params.LduCnt > 0 || iq.params.VlduCnt > 0)
3052d270511Ssinsanction  val stDataIQs = issueQueues.filter(iq => iq.params.StdCnt > 0 || iq.params.VstdCnt > 0)
306559c1710SHaojin Tang  val vecMemIQs = issueQueues.filter(_.params.isVecMemIQ)
307559c1710SHaojin Tang  val (hyuIQs, hyuIQIdxs) = issueQueues.zipWithIndex.filter(_._1.params.HyuCnt > 0).unzip
308499caf4cSXuan Hu
309499caf4cSXuan Hu  println(s"[SchedulerMemImp] memAddrIQs.size: ${memAddrIQs.size}, enq.size: ${memAddrIQs.map(_.io.enq.size).sum}")
310499caf4cSXuan Hu  println(s"[SchedulerMemImp] stAddrIQs.size:  ${stAddrIQs.size }, enq.size: ${stAddrIQs.map(_.io.enq.size).sum}")
311499caf4cSXuan Hu  println(s"[SchedulerMemImp] ldAddrIQs.size:  ${ldAddrIQs.size }, enq.size: ${ldAddrIQs.map(_.io.enq.size).sum}")
312499caf4cSXuan Hu  println(s"[SchedulerMemImp] stDataIQs.size:  ${stDataIQs.size }, enq.size: ${stDataIQs.map(_.io.enq.size).sum}")
313499caf4cSXuan Hu  println(s"[SchedulerMemImp] hyuIQs.size:     ${hyuIQs.size    }, enq.size: ${hyuIQs.map(_.io.enq.size).sum}")
314730cfbc0SXuan Hu  require(memAddrIQs.nonEmpty && stDataIQs.nonEmpty)
315730cfbc0SXuan Hu
316853cd2d8SHaojin Tang  io.toMem.get.loadFastMatch := 0.U.asTypeOf(io.toMem.get.loadFastMatch) // TODO: is still needed?
317853cd2d8SHaojin Tang
318*fc45ed13SXuan Hu  private val loadWakeUp = issueQueues.filter(_.params.LdExuCnt > 0).map(_.asInstanceOf[IssueQueueMemAddrImp].io.memIO.get.loadWakeUp).flatten
319596af5d2SHaojin Tang  require(loadWakeUp.length == io.fromMem.get.wakeup.length)
320596af5d2SHaojin Tang  loadWakeUp.zip(io.fromMem.get.wakeup).foreach(x => x._1 := x._2)
321596af5d2SHaojin Tang
322730cfbc0SXuan Hu  memAddrIQs.zipWithIndex.foreach { case (iq, i) =>
323730cfbc0SXuan Hu    iq.io.flush <> io.fromCtrlBlock.flush
324730cfbc0SXuan Hu    iq.io.enq <> dispatch2Iq.io.out(i)
325f39a61a1SzhanglyGit    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}
326730cfbc0SXuan Hu  }
327730cfbc0SXuan Hu
328ecfc6f16SXuan Hu  ldAddrIQs.zipWithIndex.foreach {
329ecfc6f16SXuan Hu    case (imp: IssueQueueMemAddrImp, i) =>
330ecfc6f16SXuan Hu      imp.io.memIO.get.feedbackIO.head := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO.head)
331c14e89f4SHaojin Tang      imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr
332de784418SXuan Hu      imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
3337b753bebSXuan Hu    case _ =>
3347b753bebSXuan Hu  }
3357b753bebSXuan Hu
336ecfc6f16SXuan Hu  stAddrIQs.zipWithIndex.foreach {
337ecfc6f16SXuan Hu    case (imp: IssueQueueMemAddrImp, i) =>
338ecfc6f16SXuan Hu      imp.io.memIO.get.feedbackIO.head := io.fromMem.get.staFeedback(i)
339c14e89f4SHaojin Tang      imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr
340c14e89f4SHaojin Tang      imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
3417b753bebSXuan Hu    case _ =>
3427b753bebSXuan Hu  }
343730cfbc0SXuan Hu
344559c1710SHaojin Tang  hyuIQs.zip(hyuIQIdxs).foreach {
345559c1710SHaojin Tang    case (imp: IssueQueueMemAddrImp, idx) =>
346670870b3SXuan Hu      imp.io.memIO.get.feedbackIO.head := io.fromMem.get.hyuFeedback.head
347670870b3SXuan Hu      imp.io.memIO.get.feedbackIO(1) := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO(1))
3488f1fa9b1Ssfencevma      imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr
3498f1fa9b1Ssfencevma      imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
350559c1710SHaojin Tang      // TODO: refactor ditry code
351559c1710SHaojin Tang      imp.io.deqDelay(1).ready := false.B
352559c1710SHaojin Tang      io.toDataPathAfterDelay(idx)(1).valid := false.B
353559c1710SHaojin Tang      io.toDataPathAfterDelay(idx)(1).bits := 0.U.asTypeOf(io.toDataPathAfterDelay(idx)(1).bits)
3548f1fa9b1Ssfencevma    case _ =>
3558f1fa9b1Ssfencevma  }
3568f1fa9b1Ssfencevma
357e62b6911SXuan Hu  private val staIdxSeq = (stAddrIQs).map(iq => iq.params.idxInSchBlk)
358e62b6911SXuan Hu  private val hyaIdxSeq = (hyuIQs).map(iq => iq.params.idxInSchBlk)
359e62b6911SXuan Hu
360e62b6911SXuan Hu  println(s"[SchedulerMemImp] sta iq idx in memSchdBlock: $staIdxSeq")
361e62b6911SXuan Hu  println(s"[SchedulerMemImp] hya iq idx in memSchdBlock: $hyaIdxSeq")
362e62b6911SXuan Hu
363e62b6911SXuan Hu  private val staEnqs = stAddrIQs.map(_.io.enq).flatten
364e62b6911SXuan Hu  private val stdEnqs = stDataIQs.map(_.io.enq).flatten.take(staEnqs.size)
365e62b6911SXuan Hu  private val hyaEnqs = hyuIQs.map(_.io.enq).flatten
366e62b6911SXuan Hu  private val hydEnqs = stDataIQs.map(_.io.enq).flatten.drop(staEnqs.size)
367e62b6911SXuan Hu
368e62b6911SXuan Hu  require(staEnqs.size == stdEnqs.size, s"number of enq ports of store address IQs(${staEnqs.size}) " +
369e62b6911SXuan Hu  s"should be equal to number of enq ports of store data IQs(${stdEnqs.size})")
370e62b6911SXuan Hu
371e62b6911SXuan Hu  require(hyaEnqs.size == hydEnqs.size, s"number of enq ports of hybrid address IQs(${hyaEnqs.size}) " +
372e62b6911SXuan Hu  s"should be equal to number of enq ports of hybrid data IQs(${hydEnqs.size})")
3739b258a00Sxgkiri
3749b258a00Sxgkiri  for ((idxInSchBlk, i) <- staIdxSeq.zipWithIndex) {
375e62b6911SXuan Hu    dispatch2Iq.io.out(idxInSchBlk).zip(staEnqs).zip(stdEnqs).foreach{ case((dp, staIQ), stdIQ) =>
376730cfbc0SXuan Hu      val isAllReady = staIQ.ready && stdIQ.ready
377e62b6911SXuan Hu      dp.ready := isAllReady
378e62b6911SXuan Hu      staIQ.valid := dp.valid && isAllReady
3794ec52c44SXuan Hu      stdIQ.valid := dp.valid && isAllReady && FuType.isStore(dp.bits.fuType)
380730cfbc0SXuan Hu    }
3819b258a00Sxgkiri  }
382730cfbc0SXuan Hu
383e62b6911SXuan Hu  for ((idxInSchBlk, i) <- hyaIdxSeq.zipWithIndex) {
384e62b6911SXuan Hu    dispatch2Iq.io.out(idxInSchBlk).zip(hyaEnqs).zip(hydEnqs).foreach{ case((dp, hyaIQ), hydIQ) =>
385e62b6911SXuan Hu      val isAllReady = hyaIQ.ready && hydIQ.ready
386e62b6911SXuan Hu      dp.ready := isAllReady
387e62b6911SXuan Hu      hyaIQ.valid := dp.valid && isAllReady
38856bceacbSHaojin Tang      hydIQ.valid := dp.valid && isAllReady && FuType.FuTypeOrR(dp.bits.fuType, FuType.stu, FuType.mou)
389e62b6911SXuan Hu    }
390e62b6911SXuan Hu  }
391730cfbc0SXuan Hu
392e62b6911SXuan Hu  stDataIQs.zipWithIndex.foreach { case (iq, i) =>
393e62b6911SXuan Hu    iq.io.flush <> io.fromCtrlBlock.flush
394f39a61a1SzhanglyGit    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}
395e62b6911SXuan Hu  }
396e62b6911SXuan Hu
397e62b6911SXuan Hu  (stdEnqs ++ hydEnqs).zip(staEnqs ++ hyaEnqs).zipWithIndex.foreach { case ((stdIQEnq, staIQEnq), i) =>
398730cfbc0SXuan Hu    stdIQEnq.bits  := staIQEnq.bits
399730cfbc0SXuan Hu    // Store data reuses store addr src(1) in dispatch2iq
400e62b6911SXuan Hu    // [dispatch2iq] --src*------src*(0)--> [staIQ|hyaIQ]
401730cfbc0SXuan Hu    //                       \
402730cfbc0SXuan Hu    //                        ---src*(1)--> [stdIQ]
403730cfbc0SXuan Hu    // Since the src(1) of sta is easier to get, stdIQEnq.bits.src*(0) is assigned to staIQEnq.bits.src*(1)
404730cfbc0SXuan Hu    // instead of dispatch2Iq.io.out(x).bits.src*(1)
40597b279b9SXuan Hu    val stdIdx = 1
4062d270511Ssinsanction    stdIQEnq.bits.srcState(0) := staIQEnq.bits.srcState(stdIdx)
40713551487SzhanglyGit    stdIQEnq.bits.srcLoadDependency(0) := staIQEnq.bits.srcLoadDependency(1)
4082d270511Ssinsanction      stdIQEnq.bits.srcType(0) := staIQEnq.bits.srcType(stdIdx)
4092d270511Ssinsanction    stdIQEnq.bits.psrc(0) := staIQEnq.bits.psrc(stdIdx)
410730cfbc0SXuan Hu    stdIQEnq.bits.sqIdx := staIQEnq.bits.sqIdx
411730cfbc0SXuan Hu  }
412730cfbc0SXuan Hu
4132d270511Ssinsanction  vecMemIQs.foreach {
4142d270511Ssinsanction    case imp: IssueQueueVecMemImp =>
4152d270511Ssinsanction      imp.io.memIO.get.sqDeqPtr.foreach(_ := io.fromMem.get.sqDeqPtr)
4162d270511Ssinsanction      imp.io.memIO.get.lqDeqPtr.foreach(_ := io.fromMem.get.lqDeqPtr)
4171f3d1b4dSXuan Hu      // not used
4181f3d1b4dSXuan Hu      imp.io.memIO.get.feedbackIO := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO)
4191f3d1b4dSXuan Hu      // maybe not used
4201f3d1b4dSXuan Hu      imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr
4211f3d1b4dSXuan Hu      imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
422f39a61a1SzhanglyGit      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}
423f39a61a1SzhanglyGit
4242d270511Ssinsanction    case _ =>
4252d270511Ssinsanction  }
4262d270511Ssinsanction
427730cfbc0SXuan Hu  val lsqEnqCtrl = Module(new LsqEnqCtrl)
428730cfbc0SXuan Hu
429730cfbc0SXuan Hu  lsqEnqCtrl.io.redirect <> io.fromCtrlBlock.flush
430730cfbc0SXuan Hu  lsqEnqCtrl.io.enq <> dispatch2Iq.io.enqLsqIO.get
431730cfbc0SXuan Hu  lsqEnqCtrl.io.lcommit := io.fromMem.get.lcommit
432730cfbc0SXuan Hu  lsqEnqCtrl.io.scommit := io.fromMem.get.scommit
433730cfbc0SXuan Hu  lsqEnqCtrl.io.lqCancelCnt := io.fromMem.get.lqCancelCnt
434730cfbc0SXuan Hu  lsqEnqCtrl.io.sqCancelCnt := io.fromMem.get.sqCancelCnt
435730cfbc0SXuan Hu  io.memIO.get.lsqEnqIO <> lsqEnqCtrl.io.enqLsq
436730cfbc0SXuan Hu}
437