xref: /XiangShan/src/main/scala/xiangshan/backend/issue/Scheduler.scala (revision c1e19666c3197f387cecdaec1f822b40f972b205)
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)))
52*c1e19666Sxiaofeibao-xjtu  val IQValidNumVec = Output(MixedVec(backendParams.genIQValidNumBundle))
53dd970561SzhanglyGit
54730cfbc0SXuan Hu  val fromCtrlBlock = new Bundle {
55730cfbc0SXuan Hu    val pcVec = Input(Vec(params.numPcReadPort, UInt(VAddrData().dataWidth.W)))
56730cfbc0SXuan Hu    val flush = Flipped(ValidIO(new Redirect))
57730cfbc0SXuan Hu  }
58730cfbc0SXuan Hu  val fromDispatch = new Bundle {
59730cfbc0SXuan Hu    val allocPregs = Vec(RenameWidth, Input(new ResetPregStateReq))
60730cfbc0SXuan Hu    val uops =  Vec(params.numUopIn, Flipped(DecoupledIO(new DynInst)))
61730cfbc0SXuan Hu  }
6239c59369SXuan Hu  val intWriteBack = MixedVec(Vec(backendParams.numPregWb(IntData()),
63730cfbc0SXuan Hu    new RfWritePortWithConfig(backendParams.intPregParams.dataCfg, backendParams.intPregParams.addrWidth)))
6439c59369SXuan Hu  val vfWriteBack = MixedVec(Vec(backendParams.numPregWb(VecData()),
65730cfbc0SXuan Hu    new RfWritePortWithConfig(backendParams.vfPregParams.dataCfg, backendParams.vfPregParams.addrWidth)))
6659ef6009Sxiaofeibao-xjtu  val toDataPathAfterDelay: MixedVec[MixedVec[DecoupledIO[IssueQueueIssueBundle]]] = MixedVec(params.issueBlockParams.map(_.genIssueDecoupledBundle))
67730cfbc0SXuan Hu
68bf35baadSXuan Hu  val fromSchedulers = new Bundle {
69c0be7f33SXuan Hu    val wakeupVec: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(params.genIQWakeUpInValidBundle)
70bf35baadSXuan Hu  }
71bf35baadSXuan Hu
72bf35baadSXuan Hu  val toSchedulers = new Bundle {
73c0be7f33SXuan Hu    val wakeupVec: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = params.genIQWakeUpOutValidBundle
74bf35baadSXuan Hu  }
75bf35baadSXuan Hu
76c0be7f33SXuan Hu  val fromDataPath = new Bundle {
7710fe9778SXuan Hu    val resp: MixedVec[MixedVec[OGRespBundle]] = MixedVec(params.issueBlockParams.map(x => Flipped(x.genOGRespBundle)))
787a96cc7fSHaojin Tang    val og0Cancel = Input(ExuOH(backendParams.numExu))
79ea46c302SXuan Hu    // Todo: remove this after no cancel signal from og1
807a96cc7fSHaojin Tang    val og1Cancel = Input(ExuOH(backendParams.numExu))
81bc7d6943SzhanglyGit    val cancelToBusyTable = Vec(backendParams.numExu, Flipped(ValidIO(new CancelSignal)))
82c0be7f33SXuan Hu    // just be compatible to old code
83c0be7f33SXuan Hu    def apply(i: Int)(j: Int) = resp(i)(j)
84c0be7f33SXuan Hu  }
85c0be7f33SXuan Hu
868a66c02cSXuan Hu  val loadFinalIssueResp = MixedVec(params.issueBlockParams.map(x => MixedVec(Vec(x.LdExuCnt, Flipped(ValidIO(new IssueQueueDeqRespBundle()(p, x)))))))
878a66c02cSXuan Hu  val memAddrIssueResp = MixedVec(params.issueBlockParams.map(x => MixedVec(Vec(x.LdExuCnt, Flipped(ValidIO(new IssueQueueDeqRespBundle()(p, x)))))))
880f55a0d3SHaojin Tang
896810d1e8Ssfencevma  val ldCancel = Vec(backendParams.LduCnt + backendParams.HyuCnt, Flipped(new LoadCancelIO))
90c0be7f33SXuan Hu
91730cfbc0SXuan Hu  val memIO = if (params.isMemSchd) Some(new Bundle {
92730cfbc0SXuan Hu    val lsqEnqIO = Flipped(new LsqEnqIO)
93730cfbc0SXuan Hu  }) else None
94730cfbc0SXuan Hu  val fromMem = if (params.isMemSchd) Some(new Bundle {
957b753bebSXuan Hu    val ldaFeedback = Flipped(Vec(params.LduCnt, new MemRSFeedbackIO))
967b753bebSXuan Hu    val staFeedback = Flipped(Vec(params.StaCnt, new MemRSFeedbackIO))
978f1fa9b1Ssfencevma    val hyuFeedback = Flipped(Vec(params.HyuCnt, new MemRSFeedbackIO))
98730cfbc0SXuan Hu    val stIssuePtr = Input(new SqPtr())
99730cfbc0SXuan Hu    val lcommit = Input(UInt(log2Up(CommitWidth + 1).W))
100730cfbc0SXuan Hu    val scommit = Input(UInt(log2Ceil(EnsbufferWidth + 1).W)) // connected to `memBlock.io.sqDeq` instead of ROB
101fc45ed13SXuan Hu    val wakeup = Vec(params.LdExuCnt, Flipped(Valid(new DynInst)))
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)
128ff3fcdf1Sxiaofeibao-xjtu  if (params.isIntSchd) {
129ff3fcdf1Sxiaofeibao-xjtu    dispatch2Iq.io.IQValidNumVec.get := io.IQValidNumVec
130*c1e19666Sxiaofeibao-xjtu    io.IQValidNumVec := MixedVecInit(issueQueues.map(_.io.validCntDeqVec))
131ff3fcdf1Sxiaofeibao-xjtu  }
132ff3fcdf1Sxiaofeibao-xjtu  else io.IQValidNumVec := 0.U.asTypeOf(io.IQValidNumVec)
133730cfbc0SXuan Hu
13456bcaed7SHaojin Tang  // valid count
13556bcaed7SHaojin Tang  dispatch2Iq.io.iqValidCnt := issueQueues.filter(_.params.StdCnt == 0).map(_.io.status.validCnt)
13656bcaed7SHaojin Tang
137730cfbc0SXuan Hu  // BusyTable Modules
138730cfbc0SXuan Hu  val intBusyTable = schdType match {
139bc7d6943SzhanglyGit    case IntScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numIntStateRead, wrapper.numIntStateWrite, IntPhyRegs, IntWB())))
140730cfbc0SXuan Hu    case _ => None
141730cfbc0SXuan Hu  }
142730cfbc0SXuan Hu
143730cfbc0SXuan Hu  val vfBusyTable = schdType match {
144bc7d6943SzhanglyGit    case VfScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numVfStateRead, wrapper.numVfStateWrite, VfPhyRegs, VfWB())))
145730cfbc0SXuan Hu    case _ => None
146730cfbc0SXuan Hu  }
147730cfbc0SXuan Hu
148730cfbc0SXuan Hu  dispatch2Iq.io match { case dp2iq =>
149730cfbc0SXuan Hu    dp2iq.redirect <> io.fromCtrlBlock.flush
150730cfbc0SXuan Hu    dp2iq.in <> io.fromDispatch.uops
151730cfbc0SXuan Hu    dp2iq.readIntState.foreach(_ <> intBusyTable.get.io.read)
152730cfbc0SXuan Hu    dp2iq.readVfState.foreach(_ <> vfBusyTable.get.io.read)
153730cfbc0SXuan Hu  }
154730cfbc0SXuan Hu
155730cfbc0SXuan Hu  intBusyTable match {
156730cfbc0SXuan Hu    case Some(bt) =>
157730cfbc0SXuan Hu      bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) =>
158730cfbc0SXuan Hu        btAllocPregs.valid := dpAllocPregs.isInt
159730cfbc0SXuan Hu        btAllocPregs.bits := dpAllocPregs.preg
160730cfbc0SXuan Hu      }
161730cfbc0SXuan Hu      bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) =>
162730cfbc0SXuan Hu        wb.valid := io.intWriteBack(i).wen && io.intWriteBack(i).intWen
163730cfbc0SXuan Hu        wb.bits := io.intWriteBack(i).addr
164730cfbc0SXuan Hu      }
165bc7d6943SzhanglyGit      bt.io.wakeUp := io.fromSchedulers.wakeupVec
166bc7d6943SzhanglyGit      bt.io.cancel := io.fromDataPath.cancelToBusyTable
16713551487SzhanglyGit      bt.io.ldCancel := io.ldCancel
168730cfbc0SXuan Hu    case None =>
169730cfbc0SXuan Hu  }
170730cfbc0SXuan Hu
171730cfbc0SXuan Hu  vfBusyTable match {
172730cfbc0SXuan Hu    case Some(bt) =>
173730cfbc0SXuan Hu      bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) =>
174730cfbc0SXuan Hu        btAllocPregs.valid := dpAllocPregs.isFp
175730cfbc0SXuan Hu        btAllocPregs.bits := dpAllocPregs.preg
176730cfbc0SXuan Hu      }
177730cfbc0SXuan Hu      bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) =>
178730cfbc0SXuan Hu        wb.valid := io.vfWriteBack(i).wen && (io.vfWriteBack(i).fpWen || io.vfWriteBack(i).vecWen)
179730cfbc0SXuan Hu        wb.bits := io.vfWriteBack(i).addr
180730cfbc0SXuan Hu      }
181bc7d6943SzhanglyGit      bt.io.wakeUp := io.fromSchedulers.wakeupVec
182bc7d6943SzhanglyGit      bt.io.cancel := io.fromDataPath.cancelToBusyTable
18313551487SzhanglyGit      bt.io.ldCancel := io.ldCancel
184730cfbc0SXuan Hu    case None =>
185730cfbc0SXuan Hu  }
186730cfbc0SXuan Hu
187f39a61a1SzhanglyGit  val wakeupFromIntWBVec = Wire(params.genIntWBWakeUpSinkValidBundle)
188f39a61a1SzhanglyGit  val wakeupFromVfWBVec = Wire(params.genVfWBWakeUpSinkValidBundle)
189f39a61a1SzhanglyGit
190f39a61a1SzhanglyGit  wakeupFromIntWBVec.zip(io.intWriteBack).foreach { case (sink, source) =>
191f39a61a1SzhanglyGit    sink.valid := source.wen
192f39a61a1SzhanglyGit    sink.bits.rfWen := source.intWen
193f39a61a1SzhanglyGit    sink.bits.fpWen := source.fpWen
194f39a61a1SzhanglyGit    sink.bits.vecWen := source.vecWen
195f39a61a1SzhanglyGit    sink.bits.pdest := source.addr
196730cfbc0SXuan Hu  }
197f39a61a1SzhanglyGit
198f39a61a1SzhanglyGit  wakeupFromVfWBVec.zip(io.vfWriteBack).foreach { case (sink, source) =>
199730cfbc0SXuan Hu    sink.valid := source.wen
200730cfbc0SXuan Hu    sink.bits.rfWen := source.intWen
201730cfbc0SXuan Hu    sink.bits.fpWen := source.fpWen
202730cfbc0SXuan Hu    sink.bits.vecWen := source.vecWen
203730cfbc0SXuan Hu    sink.bits.pdest := source.addr
204730cfbc0SXuan Hu  }
205730cfbc0SXuan Hu
206bf35baadSXuan Hu  // Connect bundles having the same wakeup source
20759ef6009Sxiaofeibao-xjtu  issueQueues.zipWithIndex.foreach { case(iq, i) =>
208bf35baadSXuan Hu    iq.io.wakeupFromIQ.foreach { wakeUp =>
2090c7ebb58Sxiaofeibao-xjtu      val wakeUpIn = iqWakeUpInMap(wakeUp.bits.exuIdx)
2100c7ebb58Sxiaofeibao-xjtu      val exuIdx = wakeUp.bits.exuIdx
2110c7ebb58Sxiaofeibao-xjtu      println(s"[Backend] Connect wakeup exuIdx ${exuIdx}")
2120c7ebb58Sxiaofeibao-xjtu      connectSamePort(wakeUp,wakeUpIn)
2130c7ebb58Sxiaofeibao-xjtu      backendParams.connectWakeup(exuIdx)
2140c7ebb58Sxiaofeibao-xjtu      if (backendParams.isCopyPdest(exuIdx)) {
2150c7ebb58Sxiaofeibao-xjtu        println(s"[Backend] exuIdx ${exuIdx} use pdestCopy ${backendParams.getCopyPdestIndex(exuIdx)}")
2160c7ebb58Sxiaofeibao-xjtu        wakeUp.bits.pdest := wakeUpIn.bits.pdestCopy.get(backendParams.getCopyPdestIndex(exuIdx))
2174c5a0d77Sxiaofeibao-xjtu        if (wakeUpIn.bits.rfWenCopy.nonEmpty) wakeUp.bits.rfWen := wakeUpIn.bits.rfWenCopy.get(backendParams.getCopyPdestIndex(exuIdx))
2184c5a0d77Sxiaofeibao-xjtu        if (wakeUpIn.bits.fpWenCopy.nonEmpty) wakeUp.bits.fpWen := wakeUpIn.bits.fpWenCopy.get(backendParams.getCopyPdestIndex(exuIdx))
2194c5a0d77Sxiaofeibao-xjtu        if (wakeUpIn.bits.vecWenCopy.nonEmpty) wakeUp.bits.vecWen := wakeUpIn.bits.vecWenCopy.get(backendParams.getCopyPdestIndex(exuIdx))
2204c5a0d77Sxiaofeibao-xjtu        if (wakeUpIn.bits.loadDependencyCopy.nonEmpty) wakeUp.bits.loadDependency := wakeUpIn.bits.loadDependencyCopy.get(backendParams.getCopyPdestIndex(exuIdx))
2210c7ebb58Sxiaofeibao-xjtu      }
22260912d84Sxiaofeibao-xjtu      if (iq.params.numIntSrc == 0) wakeUp.bits.rfWen := false.B
22360912d84Sxiaofeibao-xjtu      if (iq.params.numFpSrc == 0)  wakeUp.bits.fpWen := false.B
22460912d84Sxiaofeibao-xjtu      if (iq.params.numVfSrc == 0)  wakeUp.bits.vecWen := false.B
225bf35baadSXuan Hu    }
226ea46c302SXuan Hu    iq.io.og0Cancel := io.fromDataPath.og0Cancel
227ea46c302SXuan Hu    iq.io.og1Cancel := io.fromDataPath.og1Cancel
2280f55a0d3SHaojin Tang    iq.io.ldCancel := io.ldCancel
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) =>
261aa2bcc31SzhanglyGit      if (io.memAddrIssueResp(i).isDefinedAt(j)) {
262e8800897SXuan Hu        memAddrIssueResp := io.memAddrIssueResp(i)(j)
263aa2bcc31SzhanglyGit      } else {
264aa2bcc31SzhanglyGit        memAddrIssueResp := 0.U.asTypeOf(memAddrIssueResp)
265aa2bcc31SzhanglyGit      }
266e8800897SXuan Hu    })
267f99b81adSHaojin Tang    iq.io.wbBusyTableRead := io.fromWbFuBusyTable.fuBusyTableRead(i)
268f99b81adSHaojin Tang    io.wbFuBusyTable(i) := iq.io.wbBusyTableWrite
269f99b81adSHaojin Tang  }
270f99b81adSHaojin Tang
271c0be7f33SXuan Hu  println(s"[Scheduler] io.fromSchedulers.wakeupVec: ${io.fromSchedulers.wakeupVec.map(x => backendParams.getExuName(x.bits.exuIdx))}")
272bf35baadSXuan Hu  println(s"[Scheduler] iqWakeUpInKeys: ${iqWakeUpInMap.keys}")
273bf35baadSXuan Hu
274bf35baadSXuan Hu  println(s"[Scheduler] iqWakeUpOutKeys: ${iqWakeUpOutMap.keys}")
275c0be7f33SXuan Hu  println(s"[Scheduler] io.toSchedulers.wakeupVec: ${io.toSchedulers.wakeupVec.map(x => backendParams.getExuName(x.bits.exuIdx))}")
276730cfbc0SXuan Hu}
277730cfbc0SXuan Hu
278730cfbc0SXuan Huclass SchedulerArithImp(override val wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters)
279730cfbc0SXuan Hu  extends SchedulerImpBase(wrapper)
280730cfbc0SXuan Hu    with HasXSParameter
281730cfbc0SXuan Hu{
2822e0a7dc5Sfdy//  dontTouch(io.vfWbFuBusyTable)
283730cfbc0SXuan Hu  println(s"[SchedulerArithImp] " +
284730cfbc0SXuan Hu    s"has intBusyTable: ${intBusyTable.nonEmpty}, " +
285730cfbc0SXuan Hu    s"has vfBusyTable: ${vfBusyTable.nonEmpty}")
286730cfbc0SXuan Hu
287730cfbc0SXuan Hu  issueQueues.zipWithIndex.foreach { case (iq, i) =>
288730cfbc0SXuan Hu    iq.io.flush <> io.fromCtrlBlock.flush
289730cfbc0SXuan Hu    iq.io.enq <> dispatch2Iq.io.out(i)
290f39a61a1SzhanglyGit    val intWBIQ = params.schdType match {
291f39a61a1SzhanglyGit      case IntScheduler() => wakeupFromIntWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromIntWBPort.keys.toSeq.contains(x._2)).map(_._1)
292f39a61a1SzhanglyGit      case VfScheduler() => wakeupFromVfWBVec
293596af5d2SHaojin Tang      case _ => null
294f39a61a1SzhanglyGit    }
295f39a61a1SzhanglyGit    iq.io.wakeupFromWB.zip(intWBIQ).foreach{ case (sink, source) => sink := source}
296730cfbc0SXuan Hu  }
297730cfbc0SXuan Hu}
298730cfbc0SXuan Hu
299f99b81adSHaojin Tang// FIXME: Vector mem instructions may not be handled properly!
300730cfbc0SXuan Huclass SchedulerMemImp(override val wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters)
301730cfbc0SXuan Hu  extends SchedulerImpBase(wrapper)
302730cfbc0SXuan Hu    with HasXSParameter
303730cfbc0SXuan Hu{
304730cfbc0SXuan Hu  println(s"[SchedulerMemImp] " +
305730cfbc0SXuan Hu    s"has intBusyTable: ${intBusyTable.nonEmpty}, " +
306730cfbc0SXuan Hu    s"has vfBusyTable: ${vfBusyTable.nonEmpty}")
307730cfbc0SXuan Hu
308559c1710SHaojin Tang  val memAddrIQs = issueQueues.filter(_.params.isMemAddrIQ)
3092d270511Ssinsanction  val stAddrIQs = issueQueues.filter(iq => iq.params.StaCnt > 0 || iq.params.VstaCnt > 0) // included in memAddrIQs
3102d270511Ssinsanction  val ldAddrIQs = issueQueues.filter(iq => iq.params.LduCnt > 0 || iq.params.VlduCnt > 0)
3112d270511Ssinsanction  val stDataIQs = issueQueues.filter(iq => iq.params.StdCnt > 0 || iq.params.VstdCnt > 0)
312559c1710SHaojin Tang  val vecMemIQs = issueQueues.filter(_.params.isVecMemIQ)
313559c1710SHaojin Tang  val (hyuIQs, hyuIQIdxs) = issueQueues.zipWithIndex.filter(_._1.params.HyuCnt > 0).unzip
314499caf4cSXuan Hu
315499caf4cSXuan Hu  println(s"[SchedulerMemImp] memAddrIQs.size: ${memAddrIQs.size}, enq.size: ${memAddrIQs.map(_.io.enq.size).sum}")
316499caf4cSXuan Hu  println(s"[SchedulerMemImp] stAddrIQs.size:  ${stAddrIQs.size }, enq.size: ${stAddrIQs.map(_.io.enq.size).sum}")
317499caf4cSXuan Hu  println(s"[SchedulerMemImp] ldAddrIQs.size:  ${ldAddrIQs.size }, enq.size: ${ldAddrIQs.map(_.io.enq.size).sum}")
318499caf4cSXuan Hu  println(s"[SchedulerMemImp] stDataIQs.size:  ${stDataIQs.size }, enq.size: ${stDataIQs.map(_.io.enq.size).sum}")
319499caf4cSXuan Hu  println(s"[SchedulerMemImp] hyuIQs.size:     ${hyuIQs.size    }, enq.size: ${hyuIQs.map(_.io.enq.size).sum}")
320730cfbc0SXuan Hu  require(memAddrIQs.nonEmpty && stDataIQs.nonEmpty)
321730cfbc0SXuan Hu
322853cd2d8SHaojin Tang  io.toMem.get.loadFastMatch := 0.U.asTypeOf(io.toMem.get.loadFastMatch) // TODO: is still needed?
323853cd2d8SHaojin Tang
324fc45ed13SXuan Hu  private val loadWakeUp = issueQueues.filter(_.params.LdExuCnt > 0).map(_.asInstanceOf[IssueQueueMemAddrImp].io.memIO.get.loadWakeUp).flatten
325596af5d2SHaojin Tang  require(loadWakeUp.length == io.fromMem.get.wakeup.length)
326596af5d2SHaojin Tang  loadWakeUp.zip(io.fromMem.get.wakeup).foreach(x => x._1 := x._2)
327596af5d2SHaojin Tang
328730cfbc0SXuan Hu  memAddrIQs.zipWithIndex.foreach { case (iq, i) =>
329730cfbc0SXuan Hu    iq.io.flush <> io.fromCtrlBlock.flush
330730cfbc0SXuan Hu    iq.io.enq <> dispatch2Iq.io.out(i)
331f39a61a1SzhanglyGit    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}
332730cfbc0SXuan Hu  }
333730cfbc0SXuan Hu
334ecfc6f16SXuan Hu  ldAddrIQs.zipWithIndex.foreach {
335ecfc6f16SXuan Hu    case (imp: IssueQueueMemAddrImp, i) =>
336ecfc6f16SXuan Hu      imp.io.memIO.get.feedbackIO.head := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO.head)
337c14e89f4SHaojin Tang      imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr
338de784418SXuan Hu      imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
3397b753bebSXuan Hu    case _ =>
3407b753bebSXuan Hu  }
3417b753bebSXuan Hu
342ecfc6f16SXuan Hu  stAddrIQs.zipWithIndex.foreach {
343ecfc6f16SXuan Hu    case (imp: IssueQueueMemAddrImp, i) =>
344ecfc6f16SXuan Hu      imp.io.memIO.get.feedbackIO.head := io.fromMem.get.staFeedback(i)
345c14e89f4SHaojin Tang      imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr
346c14e89f4SHaojin Tang      imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
3477b753bebSXuan Hu    case _ =>
3487b753bebSXuan Hu  }
349730cfbc0SXuan Hu
350559c1710SHaojin Tang  hyuIQs.zip(hyuIQIdxs).foreach {
351559c1710SHaojin Tang    case (imp: IssueQueueMemAddrImp, idx) =>
352670870b3SXuan Hu      imp.io.memIO.get.feedbackIO.head := io.fromMem.get.hyuFeedback.head
353670870b3SXuan Hu      imp.io.memIO.get.feedbackIO(1) := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO(1))
3548f1fa9b1Ssfencevma      imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr
3558f1fa9b1Ssfencevma      imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
356559c1710SHaojin Tang      // TODO: refactor ditry code
357559c1710SHaojin Tang      imp.io.deqDelay(1).ready := false.B
358559c1710SHaojin Tang      io.toDataPathAfterDelay(idx)(1).valid := false.B
359559c1710SHaojin Tang      io.toDataPathAfterDelay(idx)(1).bits := 0.U.asTypeOf(io.toDataPathAfterDelay(idx)(1).bits)
3608f1fa9b1Ssfencevma    case _ =>
3618f1fa9b1Ssfencevma  }
3628f1fa9b1Ssfencevma
363e62b6911SXuan Hu  private val staIdxSeq = (stAddrIQs).map(iq => iq.params.idxInSchBlk)
364e62b6911SXuan Hu  private val hyaIdxSeq = (hyuIQs).map(iq => iq.params.idxInSchBlk)
365e62b6911SXuan Hu
366e62b6911SXuan Hu  println(s"[SchedulerMemImp] sta iq idx in memSchdBlock: $staIdxSeq")
367e62b6911SXuan Hu  println(s"[SchedulerMemImp] hya iq idx in memSchdBlock: $hyaIdxSeq")
368e62b6911SXuan Hu
369e62b6911SXuan Hu  private val staEnqs = stAddrIQs.map(_.io.enq).flatten
370e62b6911SXuan Hu  private val stdEnqs = stDataIQs.map(_.io.enq).flatten.take(staEnqs.size)
371e62b6911SXuan Hu  private val hyaEnqs = hyuIQs.map(_.io.enq).flatten
372e62b6911SXuan Hu  private val hydEnqs = stDataIQs.map(_.io.enq).flatten.drop(staEnqs.size)
373e62b6911SXuan Hu
374e62b6911SXuan Hu  require(staEnqs.size == stdEnqs.size, s"number of enq ports of store address IQs(${staEnqs.size}) " +
375e62b6911SXuan Hu  s"should be equal to number of enq ports of store data IQs(${stdEnqs.size})")
376e62b6911SXuan Hu
377e62b6911SXuan Hu  require(hyaEnqs.size == hydEnqs.size, s"number of enq ports of hybrid address IQs(${hyaEnqs.size}) " +
378e62b6911SXuan Hu  s"should be equal to number of enq ports of hybrid data IQs(${hydEnqs.size})")
3799b258a00Sxgkiri
3809b258a00Sxgkiri  for ((idxInSchBlk, i) <- staIdxSeq.zipWithIndex) {
381e62b6911SXuan Hu    dispatch2Iq.io.out(idxInSchBlk).zip(staEnqs).zip(stdEnqs).foreach{ case((dp, staIQ), stdIQ) =>
382730cfbc0SXuan Hu      val isAllReady = staIQ.ready && stdIQ.ready
383e62b6911SXuan Hu      dp.ready := isAllReady
384e62b6911SXuan Hu      staIQ.valid := dp.valid && isAllReady
3854ec52c44SXuan Hu      stdIQ.valid := dp.valid && isAllReady && FuType.isStore(dp.bits.fuType)
386730cfbc0SXuan Hu    }
3879b258a00Sxgkiri  }
388730cfbc0SXuan Hu
389e62b6911SXuan Hu  for ((idxInSchBlk, i) <- hyaIdxSeq.zipWithIndex) {
390e62b6911SXuan Hu    dispatch2Iq.io.out(idxInSchBlk).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    }
396e62b6911SXuan Hu  }
397730cfbc0SXuan Hu
398e62b6911SXuan Hu  stDataIQs.zipWithIndex.foreach { case (iq, i) =>
399e62b6911SXuan Hu    iq.io.flush <> io.fromCtrlBlock.flush
400f39a61a1SzhanglyGit    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}
401e62b6911SXuan Hu  }
402e62b6911SXuan Hu
403e62b6911SXuan Hu  (stdEnqs ++ hydEnqs).zip(staEnqs ++ hyaEnqs).zipWithIndex.foreach { case ((stdIQEnq, staIQEnq), i) =>
404730cfbc0SXuan Hu    stdIQEnq.bits  := staIQEnq.bits
405730cfbc0SXuan Hu    // Store data reuses store addr src(1) in dispatch2iq
406e62b6911SXuan Hu    // [dispatch2iq] --src*------src*(0)--> [staIQ|hyaIQ]
407730cfbc0SXuan Hu    //                       \
408730cfbc0SXuan Hu    //                        ---src*(1)--> [stdIQ]
409730cfbc0SXuan Hu    // Since the src(1) of sta is easier to get, stdIQEnq.bits.src*(0) is assigned to staIQEnq.bits.src*(1)
410730cfbc0SXuan Hu    // instead of dispatch2Iq.io.out(x).bits.src*(1)
41197b279b9SXuan Hu    val stdIdx = 1
4122d270511Ssinsanction    stdIQEnq.bits.srcState(0) := staIQEnq.bits.srcState(stdIdx)
41313551487SzhanglyGit    stdIQEnq.bits.srcLoadDependency(0) := staIQEnq.bits.srcLoadDependency(1)
4142d270511Ssinsanction      stdIQEnq.bits.srcType(0) := staIQEnq.bits.srcType(stdIdx)
4152d270511Ssinsanction    stdIQEnq.bits.psrc(0) := staIQEnq.bits.psrc(stdIdx)
416730cfbc0SXuan Hu    stdIQEnq.bits.sqIdx := staIQEnq.bits.sqIdx
417730cfbc0SXuan Hu  }
418730cfbc0SXuan Hu
4192d270511Ssinsanction  vecMemIQs.foreach {
4202d270511Ssinsanction    case imp: IssueQueueVecMemImp =>
4212d270511Ssinsanction      imp.io.memIO.get.sqDeqPtr.foreach(_ := io.fromMem.get.sqDeqPtr)
4222d270511Ssinsanction      imp.io.memIO.get.lqDeqPtr.foreach(_ := io.fromMem.get.lqDeqPtr)
4231f3d1b4dSXuan Hu      // not used
4241f3d1b4dSXuan Hu      imp.io.memIO.get.feedbackIO := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO)
4251f3d1b4dSXuan Hu      // maybe not used
4261f3d1b4dSXuan Hu      imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr
4271f3d1b4dSXuan Hu      imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
428f39a61a1SzhanglyGit      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}
429f39a61a1SzhanglyGit
4302d270511Ssinsanction    case _ =>
4312d270511Ssinsanction  }
4322d270511Ssinsanction
433730cfbc0SXuan Hu  val lsqEnqCtrl = Module(new LsqEnqCtrl)
434730cfbc0SXuan Hu
435730cfbc0SXuan Hu  lsqEnqCtrl.io.redirect <> io.fromCtrlBlock.flush
436730cfbc0SXuan Hu  lsqEnqCtrl.io.enq <> dispatch2Iq.io.enqLsqIO.get
437730cfbc0SXuan Hu  lsqEnqCtrl.io.lcommit := io.fromMem.get.lcommit
438730cfbc0SXuan Hu  lsqEnqCtrl.io.scommit := io.fromMem.get.scommit
439730cfbc0SXuan Hu  lsqEnqCtrl.io.lqCancelCnt := io.fromMem.get.lqCancelCnt
440730cfbc0SXuan Hu  lsqEnqCtrl.io.sqCancelCnt := io.fromMem.get.sqCancelCnt
441730cfbc0SXuan Hu  io.memIO.get.lsqEnqIO <> lsqEnqCtrl.io.enqLsq
442730cfbc0SXuan Hu}
443