xref: /XiangShan/src/main/scala/xiangshan/backend/issue/Scheduler.scala (revision 8a66c02c76da83c8d366386feef6b0c409b1e7de)
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}
7730cfbc0SXuan Huimport xiangshan._
810fe9778SXuan Huimport xiangshan.backend.Bundles._
939c59369SXuan Huimport xiangshan.backend.datapath.DataConfig.{IntData, VAddrData, VecData}
1039c59369SXuan Huimport xiangshan.backend.datapath.WbConfig.{IntWB, VfWB}
11e62b6911SXuan Huimport xiangshan.backend.fu.FuType
12730cfbc0SXuan Huimport xiangshan.backend.regfile.RfWritePortWithConfig
13730cfbc0SXuan Huimport xiangshan.backend.rename.BusyTable
14730cfbc0SXuan Huimport xiangshan.mem.{LsqEnqCtrl, LsqEnqIO, MemWaitUpdateReq, SqPtr}
15730cfbc0SXuan Hu
16730cfbc0SXuan Husealed trait SchedulerType
17730cfbc0SXuan Hu
18730cfbc0SXuan Hucase class IntScheduler() extends SchedulerType
19730cfbc0SXuan Hucase class MemScheduler() extends SchedulerType
20730cfbc0SXuan Hucase class VfScheduler() extends SchedulerType
21730cfbc0SXuan Hucase class NoScheduler() extends SchedulerType
22730cfbc0SXuan Hu
23730cfbc0SXuan Huclass Scheduler(val params: SchdBlockParams)(implicit p: Parameters) extends LazyModule with HasXSParameter {
241ca4a39dSXuan Hu  override def shouldBeInlined: Boolean = false
251ca4a39dSXuan Hu
2639c59369SXuan Hu  val numIntStateWrite = backendParams.numPregWb(IntData())
2739c59369SXuan Hu  val numVfStateWrite = backendParams.numPregWb(VecData())
28730cfbc0SXuan Hu
29730cfbc0SXuan Hu  val dispatch2Iq = LazyModule(new Dispatch2Iq(params))
30730cfbc0SXuan Hu  val issueQueue = params.issueBlockParams.map(x => LazyModule(new IssueQueue(x).suggestName(x.getIQName)))
31730cfbc0SXuan Hu
3283ba63b3SXuan Hu  lazy val module: SchedulerImpBase = params.schdType match {
33730cfbc0SXuan Hu    case IntScheduler() => new SchedulerArithImp(this)(params, p)
34730cfbc0SXuan Hu    case MemScheduler() => new SchedulerMemImp(this)(params, p)
35730cfbc0SXuan Hu    case VfScheduler() => new SchedulerArithImp(this)(params, p)
36730cfbc0SXuan Hu    case _ => null
37730cfbc0SXuan Hu  }
38730cfbc0SXuan Hu}
39730cfbc0SXuan Hu
407f8233d5SHaojin Tangclass SchedulerIO()(implicit params: SchdBlockParams, p: Parameters) extends XSBundle {
4168d13085SXuan Hu  // params alias
427f8233d5SHaojin Tang  private val LoadQueueSize = VirtualLoadQueueSize
4368d13085SXuan Hu
44730cfbc0SXuan Hu  val fromTop = new Bundle {
45730cfbc0SXuan Hu    val hartId = Input(UInt(8.W))
46730cfbc0SXuan Hu  }
472e0a7dc5Sfdy  val fromWbFuBusyTable = new Bundle{
482e0a7dc5Sfdy    val fuBusyTableRead = MixedVec(params.issueBlockParams.map(x => Input(x.genWbFuBusyTableReadBundle)))
492e0a7dc5Sfdy  }
50dd970561SzhanglyGit  val wbFuBusyTable = MixedVec(params.issueBlockParams.map(x => Output(x.genWbFuBusyTableWriteBundle)))
51dd970561SzhanglyGit
52730cfbc0SXuan Hu  val fromCtrlBlock = new Bundle {
53730cfbc0SXuan Hu    val pcVec = Input(Vec(params.numPcReadPort, UInt(VAddrData().dataWidth.W)))
54730cfbc0SXuan Hu    val flush = Flipped(ValidIO(new Redirect))
55730cfbc0SXuan Hu  }
56730cfbc0SXuan Hu  val fromDispatch = new Bundle {
57730cfbc0SXuan Hu    val allocPregs = Vec(RenameWidth, Input(new ResetPregStateReq))
58730cfbc0SXuan Hu    val uops =  Vec(params.numUopIn, Flipped(DecoupledIO(new DynInst)))
59730cfbc0SXuan Hu  }
6039c59369SXuan Hu  val intWriteBack = MixedVec(Vec(backendParams.numPregWb(IntData()),
61730cfbc0SXuan Hu    new RfWritePortWithConfig(backendParams.intPregParams.dataCfg, backendParams.intPregParams.addrWidth)))
6239c59369SXuan Hu  val vfWriteBack = MixedVec(Vec(backendParams.numPregWb(VecData()),
63730cfbc0SXuan Hu    new RfWritePortWithConfig(backendParams.vfPregParams.dataCfg, backendParams.vfPregParams.addrWidth)))
6410fe9778SXuan Hu  val toDataPath: MixedVec[MixedVec[DecoupledIO[IssueQueueIssueBundle]]] = MixedVec(params.issueBlockParams.map(_.genIssueDecoupledBundle))
6559ef6009Sxiaofeibao-xjtu  val toDataPathAfterDelay: MixedVec[MixedVec[DecoupledIO[IssueQueueIssueBundle]]] = MixedVec(params.issueBlockParams.map(_.genIssueDecoupledBundle))
6659ef6009Sxiaofeibao-xjtu  val fromCancelNetwork = Flipped(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
86*8a66c02cSXuan Hu  val loadFinalIssueResp = MixedVec(params.issueBlockParams.map(x => MixedVec(Vec(x.LdExuCnt, Flipped(ValidIO(new IssueQueueDeqRespBundle()(p, x)))))))
87*8a66c02cSXuan 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
101730cfbc0SXuan Hu    // from lsq
102730cfbc0SXuan Hu    val lqCancelCnt = Input(UInt(log2Up(LoadQueueSize + 1).W))
103730cfbc0SXuan Hu    val sqCancelCnt = Input(UInt(log2Up(StoreQueueSize + 1).W))
104730cfbc0SXuan Hu    val memWaitUpdateReq = Flipped(new MemWaitUpdateReq)
105730cfbc0SXuan Hu  }) else None
106730cfbc0SXuan Hu  val toMem = if (params.isMemSchd) Some(new Bundle {
107730cfbc0SXuan Hu    val loadFastMatch = Output(Vec(params.LduCnt, new IssueQueueLoadBundle))
108730cfbc0SXuan Hu  }) else None
109730cfbc0SXuan Hu}
110730cfbc0SXuan Hu
111730cfbc0SXuan Huabstract class SchedulerImpBase(wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters)
112730cfbc0SXuan Hu  extends LazyModuleImp(wrapper)
113730cfbc0SXuan Hu    with HasXSParameter
114730cfbc0SXuan Hu{
115730cfbc0SXuan Hu  val io = IO(new SchedulerIO())
116730cfbc0SXuan Hu
117730cfbc0SXuan Hu  // alias
118c0be7f33SXuan Hu  private val iqWakeUpInMap: Map[Int, ValidIO[IssueQueueIQWakeUpBundle]] =
119c0be7f33SXuan Hu    io.fromSchedulers.wakeupVec.map(x => (x.bits.exuIdx, x)).toMap
120730cfbc0SXuan Hu  private val schdType = params.schdType
121730cfbc0SXuan Hu
122730cfbc0SXuan Hu  // Modules
123730cfbc0SXuan Hu  val dispatch2Iq: Dispatch2IqImp = wrapper.dispatch2Iq.module
124730cfbc0SXuan Hu  val issueQueues: Seq[IssueQueueImp] = wrapper.issueQueue.map(_.module)
125730cfbc0SXuan Hu
126730cfbc0SXuan Hu  // BusyTable Modules
127730cfbc0SXuan Hu  val intBusyTable = schdType match {
128bc7d6943SzhanglyGit    case IntScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numIntStateRead, wrapper.numIntStateWrite, IntPhyRegs, IntWB())))
129730cfbc0SXuan Hu    case _ => None
130730cfbc0SXuan Hu  }
131730cfbc0SXuan Hu
132730cfbc0SXuan Hu  val vfBusyTable = schdType match {
133bc7d6943SzhanglyGit    case VfScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numVfStateRead, wrapper.numVfStateWrite, VfPhyRegs, VfWB())))
134730cfbc0SXuan Hu    case _ => None
135730cfbc0SXuan Hu  }
136730cfbc0SXuan Hu
137730cfbc0SXuan Hu  dispatch2Iq.io match { case dp2iq =>
138730cfbc0SXuan Hu    dp2iq.redirect <> io.fromCtrlBlock.flush
139730cfbc0SXuan Hu    dp2iq.in <> io.fromDispatch.uops
140730cfbc0SXuan Hu    dp2iq.readIntState.foreach(_ <> intBusyTable.get.io.read)
141730cfbc0SXuan Hu    dp2iq.readVfState.foreach(_ <> vfBusyTable.get.io.read)
142730cfbc0SXuan Hu  }
143730cfbc0SXuan Hu
144730cfbc0SXuan Hu  intBusyTable match {
145730cfbc0SXuan Hu    case Some(bt) =>
146730cfbc0SXuan Hu      bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) =>
147730cfbc0SXuan Hu        btAllocPregs.valid := dpAllocPregs.isInt
148730cfbc0SXuan Hu        btAllocPregs.bits := dpAllocPregs.preg
149730cfbc0SXuan Hu      }
150730cfbc0SXuan Hu      bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) =>
151730cfbc0SXuan Hu        wb.valid := io.intWriteBack(i).wen && io.intWriteBack(i).intWen
152730cfbc0SXuan Hu        wb.bits := io.intWriteBack(i).addr
153730cfbc0SXuan Hu      }
154bc7d6943SzhanglyGit      bt.io.wakeUp := io.fromSchedulers.wakeupVec
155bc7d6943SzhanglyGit      bt.io.cancel := io.fromDataPath.cancelToBusyTable
156730cfbc0SXuan Hu    case None =>
157730cfbc0SXuan Hu  }
158730cfbc0SXuan Hu
159730cfbc0SXuan Hu  vfBusyTable match {
160730cfbc0SXuan Hu    case Some(bt) =>
161730cfbc0SXuan Hu      bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) =>
162730cfbc0SXuan Hu        btAllocPregs.valid := dpAllocPregs.isFp
163730cfbc0SXuan Hu        btAllocPregs.bits := dpAllocPregs.preg
164730cfbc0SXuan Hu      }
165730cfbc0SXuan Hu      bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) =>
166730cfbc0SXuan Hu        wb.valid := io.vfWriteBack(i).wen && (io.vfWriteBack(i).fpWen || io.vfWriteBack(i).vecWen)
167730cfbc0SXuan Hu        wb.bits := io.vfWriteBack(i).addr
168730cfbc0SXuan Hu      }
169bc7d6943SzhanglyGit      bt.io.wakeUp := io.fromSchedulers.wakeupVec
170bc7d6943SzhanglyGit      bt.io.cancel := io.fromDataPath.cancelToBusyTable
171730cfbc0SXuan Hu    case None =>
172730cfbc0SXuan Hu  }
173730cfbc0SXuan Hu
174c0be7f33SXuan Hu  val wakeupFromWBVec = Wire(params.genWBWakeUpSinkValidBundle)
175730cfbc0SXuan Hu  val writeback = params.schdType match {
176730cfbc0SXuan Hu    case IntScheduler() => io.intWriteBack
177730cfbc0SXuan Hu    case MemScheduler() => io.intWriteBack ++ io.vfWriteBack
178730cfbc0SXuan Hu    case VfScheduler() => io.vfWriteBack
179730cfbc0SXuan Hu    case _ => Seq()
180730cfbc0SXuan Hu  }
181730cfbc0SXuan Hu  wakeupFromWBVec.zip(writeback).foreach { case (sink, source) =>
182730cfbc0SXuan Hu    sink.valid := source.wen
183730cfbc0SXuan Hu    sink.bits.rfWen := source.intWen
184730cfbc0SXuan Hu    sink.bits.fpWen := source.fpWen
185730cfbc0SXuan Hu    sink.bits.vecWen := source.vecWen
186730cfbc0SXuan Hu    sink.bits.pdest := source.addr
187730cfbc0SXuan Hu  }
188730cfbc0SXuan Hu
189bf35baadSXuan Hu  // Connect bundles having the same wakeup source
19059ef6009Sxiaofeibao-xjtu  issueQueues.zipWithIndex.foreach { case(iq, i) =>
191bf35baadSXuan Hu    iq.io.wakeupFromIQ.foreach { wakeUp =>
192c0be7f33SXuan Hu      wakeUp := iqWakeUpInMap(wakeUp.bits.exuIdx)
193bf35baadSXuan Hu    }
194ea46c302SXuan Hu    iq.io.og0Cancel := io.fromDataPath.og0Cancel
195ea46c302SXuan Hu    iq.io.og1Cancel := io.fromDataPath.og1Cancel
1960f55a0d3SHaojin Tang    iq.io.ldCancel := io.ldCancel
19759ef6009Sxiaofeibao-xjtu    iq.io.fromCancelNetwork <> io.fromCancelNetwork(i)
198bf35baadSXuan Hu  }
199bf35baadSXuan Hu
200c0be7f33SXuan Hu  private val iqWakeUpOutMap: Map[Int, ValidIO[IssueQueueIQWakeUpBundle]] =
201bf35baadSXuan Hu    issueQueues.flatMap(_.io.wakeupToIQ)
202c0be7f33SXuan Hu      .map(x => (x.bits.exuIdx, x))
203bf35baadSXuan Hu      .toMap
204bf35baadSXuan Hu
205bf35baadSXuan Hu  // Connect bundles having the same wakeup source
206bf35baadSXuan Hu  io.toSchedulers.wakeupVec.foreach { wakeUp =>
207c0be7f33SXuan Hu    wakeUp := iqWakeUpOutMap(wakeUp.bits.exuIdx)
208bf35baadSXuan Hu  }
209bf35baadSXuan Hu
210730cfbc0SXuan Hu  io.toDataPath.zipWithIndex.foreach { case (toDp, i) =>
211730cfbc0SXuan Hu    toDp <> issueQueues(i).io.deq
212730cfbc0SXuan Hu  }
21359ef6009Sxiaofeibao-xjtu  io.toDataPathAfterDelay.zipWithIndex.foreach { case (toDpDy, i) =>
21459ef6009Sxiaofeibao-xjtu    toDpDy <> issueQueues(i).io.deqDelay
21559ef6009Sxiaofeibao-xjtu  }
216bf35baadSXuan Hu
217f99b81adSHaojin Tang  // Response
218f99b81adSHaojin Tang  issueQueues.zipWithIndex.foreach { case (iq, i) =>
219f99b81adSHaojin Tang    iq.io.deqResp.zipWithIndex.foreach { case (deqResp, j) =>
220f99b81adSHaojin Tang      deqResp.valid := iq.io.deq(j).valid && io.toDataPath(i)(j).ready
221f99b81adSHaojin Tang      deqResp.bits.respType := RSFeedbackType.issueSuccess
222f99b81adSHaojin Tang      deqResp.bits.robIdx := iq.io.deq(j).bits.common.robIdx
223f99b81adSHaojin Tang      deqResp.bits.dataInvalidSqIdx := DontCare
224f99b81adSHaojin Tang      deqResp.bits.rfWen := iq.io.deq(j).bits.common.rfWen.getOrElse(false.B)
225f99b81adSHaojin Tang      deqResp.bits.fuType := iq.io.deq(j).bits.common.fuType
226f99b81adSHaojin Tang    }
227f99b81adSHaojin Tang    iq.io.og0Resp.zipWithIndex.foreach { case (og0Resp, j) =>
228f99b81adSHaojin Tang      og0Resp := io.fromDataPath(i)(j).og0resp
229f99b81adSHaojin Tang    }
230f99b81adSHaojin Tang    iq.io.og1Resp.zipWithIndex.foreach { case (og1Resp, j) =>
231f99b81adSHaojin Tang      og1Resp := io.fromDataPath(i)(j).og1resp
232f99b81adSHaojin Tang    }
233f99b81adSHaojin Tang    iq.io.finalIssueResp.foreach(_.zipWithIndex.foreach { case (finalIssueResp, j) =>
234670870b3SXuan Hu      if (io.loadFinalIssueResp(i).isDefinedAt(j)) {
235f99b81adSHaojin Tang        finalIssueResp := io.loadFinalIssueResp(i)(j)
236670870b3SXuan Hu      } else {
237670870b3SXuan Hu        finalIssueResp := 0.U.asTypeOf(finalIssueResp)
238670870b3SXuan Hu      }
239f99b81adSHaojin Tang    })
240e8800897SXuan Hu    iq.io.memAddrIssueResp.foreach(_.zipWithIndex.foreach { case (memAddrIssueResp, j) =>
241e8800897SXuan Hu      memAddrIssueResp := io.memAddrIssueResp(i)(j)
242e8800897SXuan Hu    })
243f99b81adSHaojin Tang    iq.io.wbBusyTableRead := io.fromWbFuBusyTable.fuBusyTableRead(i)
244f99b81adSHaojin Tang    io.wbFuBusyTable(i) := iq.io.wbBusyTableWrite
245f99b81adSHaojin Tang  }
246f99b81adSHaojin Tang
247c0be7f33SXuan Hu  println(s"[Scheduler] io.fromSchedulers.wakeupVec: ${io.fromSchedulers.wakeupVec.map(x => backendParams.getExuName(x.bits.exuIdx))}")
248bf35baadSXuan Hu  println(s"[Scheduler] iqWakeUpInKeys: ${iqWakeUpInMap.keys}")
249bf35baadSXuan Hu
250bf35baadSXuan Hu  println(s"[Scheduler] iqWakeUpOutKeys: ${iqWakeUpOutMap.keys}")
251c0be7f33SXuan Hu  println(s"[Scheduler] io.toSchedulers.wakeupVec: ${io.toSchedulers.wakeupVec.map(x => backendParams.getExuName(x.bits.exuIdx))}")
252730cfbc0SXuan Hu}
253730cfbc0SXuan Hu
254730cfbc0SXuan Huclass SchedulerArithImp(override val wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters)
255730cfbc0SXuan Hu  extends SchedulerImpBase(wrapper)
256730cfbc0SXuan Hu    with HasXSParameter
257730cfbc0SXuan Hu{
2582e0a7dc5Sfdy//  dontTouch(io.vfWbFuBusyTable)
259730cfbc0SXuan Hu  println(s"[SchedulerArithImp] " +
260730cfbc0SXuan Hu    s"has intBusyTable: ${intBusyTable.nonEmpty}, " +
261730cfbc0SXuan Hu    s"has vfBusyTable: ${vfBusyTable.nonEmpty}")
262730cfbc0SXuan Hu
263730cfbc0SXuan Hu  issueQueues.zipWithIndex.foreach { case (iq, i) =>
264730cfbc0SXuan Hu    iq.io.flush <> io.fromCtrlBlock.flush
265730cfbc0SXuan Hu    iq.io.enq <> dispatch2Iq.io.out(i)
266bf35baadSXuan Hu    iq.io.wakeupFromWB := wakeupFromWBVec
267730cfbc0SXuan Hu  }
268730cfbc0SXuan Hu}
269730cfbc0SXuan Hu
270f99b81adSHaojin Tang// FIXME: Vector mem instructions may not be handled properly!
271730cfbc0SXuan Huclass SchedulerMemImp(override val wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters)
272730cfbc0SXuan Hu  extends SchedulerImpBase(wrapper)
273730cfbc0SXuan Hu    with HasXSParameter
274730cfbc0SXuan Hu{
275730cfbc0SXuan Hu  println(s"[SchedulerMemImp] " +
276730cfbc0SXuan Hu    s"has intBusyTable: ${intBusyTable.nonEmpty}, " +
277730cfbc0SXuan Hu    s"has vfBusyTable: ${vfBusyTable.nonEmpty}")
278730cfbc0SXuan Hu
279730cfbc0SXuan Hu  val memAddrIQs = issueQueues.filter(iq => iq.params.StdCnt == 0)
280730cfbc0SXuan Hu  val stAddrIQs = issueQueues.filter(iq => iq.params.StaCnt > 0) // included in memAddrIQs
2817b753bebSXuan Hu  val ldAddrIQs = issueQueues.filter(iq => iq.params.LduCnt > 0)
282730cfbc0SXuan Hu  val stDataIQs = issueQueues.filter(iq => iq.params.StdCnt > 0)
2838f1fa9b1Ssfencevma  val hyuIQs = issueQueues.filter(iq => iq.params.HyuCnt > 0)
284499caf4cSXuan Hu
285499caf4cSXuan Hu  println(s"[SchedulerMemImp] memAddrIQs.size: ${memAddrIQs.size}, enq.size: ${memAddrIQs.map(_.io.enq.size).sum}")
286499caf4cSXuan Hu  println(s"[SchedulerMemImp] stAddrIQs.size:  ${stAddrIQs.size }, enq.size: ${stAddrIQs.map(_.io.enq.size).sum}")
287499caf4cSXuan Hu  println(s"[SchedulerMemImp] ldAddrIQs.size:  ${ldAddrIQs.size }, enq.size: ${ldAddrIQs.map(_.io.enq.size).sum}")
288499caf4cSXuan Hu  println(s"[SchedulerMemImp] stDataIQs.size:  ${stDataIQs.size }, enq.size: ${stDataIQs.map(_.io.enq.size).sum}")
289499caf4cSXuan Hu  println(s"[SchedulerMemImp] hyuIQs.size:     ${hyuIQs.size    }, enq.size: ${hyuIQs.map(_.io.enq.size).sum}")
290730cfbc0SXuan Hu  require(memAddrIQs.nonEmpty && stDataIQs.nonEmpty)
291730cfbc0SXuan Hu
292853cd2d8SHaojin Tang  io.toMem.get.loadFastMatch := 0.U.asTypeOf(io.toMem.get.loadFastMatch) // TODO: is still needed?
293853cd2d8SHaojin Tang
294730cfbc0SXuan Hu  memAddrIQs.zipWithIndex.foreach { case (iq, i) =>
295730cfbc0SXuan Hu    iq.io.flush <> io.fromCtrlBlock.flush
296730cfbc0SXuan Hu    iq.io.enq <> dispatch2Iq.io.out(i)
297bf35baadSXuan Hu    iq.io.wakeupFromWB := wakeupFromWBVec
298730cfbc0SXuan Hu  }
299730cfbc0SXuan Hu
300ecfc6f16SXuan Hu  ldAddrIQs.zipWithIndex.foreach {
301ecfc6f16SXuan Hu    case (imp: IssueQueueMemAddrImp, i) =>
302ecfc6f16SXuan Hu      imp.io.memIO.get.feedbackIO.head := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO.head)
303c14e89f4SHaojin Tang      imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr
304de784418SXuan Hu      imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
3057b753bebSXuan Hu    case _ =>
3067b753bebSXuan Hu  }
3077b753bebSXuan Hu
308ecfc6f16SXuan Hu  stAddrIQs.zipWithIndex.foreach {
309ecfc6f16SXuan Hu    case (imp: IssueQueueMemAddrImp, i) =>
310ecfc6f16SXuan Hu      imp.io.memIO.get.feedbackIO.head := io.fromMem.get.staFeedback(i)
311ecfc6f16SXuan Hu      imp.io.memIO.get.feedbackIO(1) := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO(1))
312c14e89f4SHaojin Tang      imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr
313c14e89f4SHaojin Tang      imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
3147b753bebSXuan Hu    case _ =>
3157b753bebSXuan Hu  }
316730cfbc0SXuan Hu
3178f1fa9b1Ssfencevma  hyuIQs.foreach {
3188f1fa9b1Ssfencevma    case imp: IssueQueueMemAddrImp =>
319670870b3SXuan Hu      imp.io.memIO.get.feedbackIO.head := io.fromMem.get.hyuFeedback.head
320670870b3SXuan Hu      imp.io.memIO.get.feedbackIO(1) := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO(1))
3218f1fa9b1Ssfencevma      imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr
3228f1fa9b1Ssfencevma      imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
3238f1fa9b1Ssfencevma    case _ =>
3248f1fa9b1Ssfencevma  }
3258f1fa9b1Ssfencevma
326166eb00dSHaojin Tang  // TODO: Implement vstu
327166eb00dSHaojin Tang  issueQueues.filter(iq => iq.params.VstuCnt > 0).foreach {
328166eb00dSHaojin Tang    case imp: IssueQueueMemAddrImp =>
329166eb00dSHaojin Tang      imp.io.memIO.get.feedbackIO <> DontCare
330166eb00dSHaojin Tang      imp.io.memIO.get.checkWait.stIssuePtr := DontCare
331166eb00dSHaojin Tang      imp.io.memIO.get.checkWait.memWaitUpdateReq := DontCare
332166eb00dSHaojin Tang    case _ =>
333166eb00dSHaojin Tang  }
334166eb00dSHaojin Tang
335166eb00dSHaojin Tang  // TODO: Implement vldu
336166eb00dSHaojin Tang  issueQueues.filter(iq => iq.params.VlduCnt > 0).foreach {
337166eb00dSHaojin Tang    case imp: IssueQueueMemAddrImp =>
338166eb00dSHaojin Tang      imp.io.memIO.get.feedbackIO <> DontCare
339166eb00dSHaojin Tang      imp.io.memIO.get.checkWait.stIssuePtr := DontCare
340166eb00dSHaojin Tang      imp.io.memIO.get.checkWait.memWaitUpdateReq := DontCare
341166eb00dSHaojin Tang    case _ =>
342166eb00dSHaojin Tang  }
343166eb00dSHaojin Tang
344e62b6911SXuan Hu  private val staIdxSeq = (stAddrIQs).map(iq => iq.params.idxInSchBlk)
345e62b6911SXuan Hu  private val hyaIdxSeq = (hyuIQs).map(iq => iq.params.idxInSchBlk)
346e62b6911SXuan Hu
347e62b6911SXuan Hu  println(s"[SchedulerMemImp] sta iq idx in memSchdBlock: $staIdxSeq")
348e62b6911SXuan Hu  println(s"[SchedulerMemImp] hya iq idx in memSchdBlock: $hyaIdxSeq")
349e62b6911SXuan Hu
350e62b6911SXuan Hu  private val staEnqs = stAddrIQs.map(_.io.enq).flatten
351e62b6911SXuan Hu  private val stdEnqs = stDataIQs.map(_.io.enq).flatten.take(staEnqs.size)
352e62b6911SXuan Hu  private val hyaEnqs = hyuIQs.map(_.io.enq).flatten
353e62b6911SXuan Hu  private val hydEnqs = stDataIQs.map(_.io.enq).flatten.drop(staEnqs.size)
354e62b6911SXuan Hu
355e62b6911SXuan Hu  require(staEnqs.size == stdEnqs.size, s"number of enq ports of store address IQs(${staEnqs.size}) " +
356e62b6911SXuan Hu  s"should be equal to number of enq ports of store data IQs(${stdEnqs.size})")
357e62b6911SXuan Hu
358e62b6911SXuan Hu  require(hyaEnqs.size == hydEnqs.size, s"number of enq ports of hybrid address IQs(${hyaEnqs.size}) " +
359e62b6911SXuan Hu  s"should be equal to number of enq ports of hybrid data IQs(${hydEnqs.size})")
3609b258a00Sxgkiri
3619b258a00Sxgkiri  for ((idxInSchBlk, i) <- staIdxSeq.zipWithIndex) {
362e62b6911SXuan Hu    dispatch2Iq.io.out(idxInSchBlk).zip(staEnqs).zip(stdEnqs).foreach{ case((dp, staIQ), stdIQ) =>
363730cfbc0SXuan Hu      val isAllReady = staIQ.ready && stdIQ.ready
364e62b6911SXuan Hu      dp.ready := isAllReady
365e62b6911SXuan Hu      staIQ.valid := dp.valid && isAllReady
3664ec52c44SXuan Hu      stdIQ.valid := dp.valid && isAllReady && FuType.isStore(dp.bits.fuType)
367730cfbc0SXuan Hu    }
3689b258a00Sxgkiri  }
369730cfbc0SXuan Hu
370e62b6911SXuan Hu  for ((idxInSchBlk, i) <- hyaIdxSeq.zipWithIndex) {
371e62b6911SXuan Hu    dispatch2Iq.io.out(idxInSchBlk).zip(hyaEnqs).zip(hydEnqs).foreach{ case((dp, hyaIQ), hydIQ) =>
372e62b6911SXuan Hu      val isAllReady = hyaIQ.ready && hydIQ.ready
373e62b6911SXuan Hu      dp.ready := isAllReady
374e62b6911SXuan Hu      hyaIQ.valid := dp.valid && isAllReady
375e62b6911SXuan Hu      hydIQ.valid := dp.valid && isAllReady && FuType.isStore(dp.bits.fuType)
376e62b6911SXuan Hu    }
377e62b6911SXuan Hu  }
378730cfbc0SXuan Hu
379e62b6911SXuan Hu  stDataIQs.zipWithIndex.foreach { case (iq, i) =>
380e62b6911SXuan Hu    iq.io.flush <> io.fromCtrlBlock.flush
381e62b6911SXuan Hu    iq.io.wakeupFromWB := wakeupFromWBVec
382e62b6911SXuan Hu  }
383e62b6911SXuan Hu
384e62b6911SXuan Hu  (stdEnqs ++ hydEnqs).zip(staEnqs ++ hyaEnqs).zipWithIndex.foreach { case ((stdIQEnq, staIQEnq), i) =>
385730cfbc0SXuan Hu    stdIQEnq.bits  := staIQEnq.bits
386730cfbc0SXuan Hu    // Store data reuses store addr src(1) in dispatch2iq
387e62b6911SXuan Hu    // [dispatch2iq] --src*------src*(0)--> [staIQ|hyaIQ]
388730cfbc0SXuan Hu    //                       \
389730cfbc0SXuan Hu    //                        ---src*(1)--> [stdIQ]
390730cfbc0SXuan Hu    // Since the src(1) of sta is easier to get, stdIQEnq.bits.src*(0) is assigned to staIQEnq.bits.src*(1)
391730cfbc0SXuan Hu    // instead of dispatch2Iq.io.out(x).bits.src*(1)
392730cfbc0SXuan Hu    stdIQEnq.bits.srcState(0) := staIQEnq.bits.srcState(1)
393730cfbc0SXuan Hu    stdIQEnq.bits.srcType(0) := staIQEnq.bits.srcType(1)
394bc7d6943SzhanglyGit    stdIQEnq.bits.dataSource(0) := staIQEnq.bits.dataSource(1)
395bc7d6943SzhanglyGit    stdIQEnq.bits.l1ExuOH(0) := staIQEnq.bits.l1ExuOH(1)
396730cfbc0SXuan Hu    stdIQEnq.bits.psrc(0) := staIQEnq.bits.psrc(1)
397730cfbc0SXuan Hu    stdIQEnq.bits.sqIdx := staIQEnq.bits.sqIdx
398730cfbc0SXuan Hu  }
399730cfbc0SXuan Hu
400730cfbc0SXuan Hu  val lsqEnqCtrl = Module(new LsqEnqCtrl)
401730cfbc0SXuan Hu
402730cfbc0SXuan Hu  lsqEnqCtrl.io.redirect <> io.fromCtrlBlock.flush
403730cfbc0SXuan Hu  lsqEnqCtrl.io.enq <> dispatch2Iq.io.enqLsqIO.get
404730cfbc0SXuan Hu  lsqEnqCtrl.io.lcommit := io.fromMem.get.lcommit
405730cfbc0SXuan Hu  lsqEnqCtrl.io.scommit := io.fromMem.get.scommit
406730cfbc0SXuan Hu  lsqEnqCtrl.io.lqCancelCnt := io.fromMem.get.lqCancelCnt
407730cfbc0SXuan Hu  lsqEnqCtrl.io.sqCancelCnt := io.fromMem.get.sqCancelCnt
408730cfbc0SXuan Hu  io.memIO.get.lsqEnqIO <> lsqEnqCtrl.io.enqLsq
409730cfbc0SXuan Hu}
410