xref: /XiangShan/src/main/scala/xiangshan/backend/issue/Scheduler.scala (revision 559c1710aac965f8aeae8c783a196fcbdd5c05b1)
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
142d270511Ssinsanctionimport xiangshan.mem.{LsqEnqCtrl, LsqEnqIO, MemWaitUpdateReq, SqPtr, LqPtr}
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
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
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
161730cfbc0SXuan Hu    case None =>
162730cfbc0SXuan Hu  }
163730cfbc0SXuan Hu
164730cfbc0SXuan Hu  vfBusyTable match {
165730cfbc0SXuan Hu    case Some(bt) =>
166730cfbc0SXuan Hu      bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) =>
167730cfbc0SXuan Hu        btAllocPregs.valid := dpAllocPregs.isFp
168730cfbc0SXuan Hu        btAllocPregs.bits := dpAllocPregs.preg
169730cfbc0SXuan Hu      }
170730cfbc0SXuan Hu      bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) =>
171730cfbc0SXuan Hu        wb.valid := io.vfWriteBack(i).wen && (io.vfWriteBack(i).fpWen || io.vfWriteBack(i).vecWen)
172730cfbc0SXuan Hu        wb.bits := io.vfWriteBack(i).addr
173730cfbc0SXuan Hu      }
174bc7d6943SzhanglyGit      bt.io.wakeUp := io.fromSchedulers.wakeupVec
175bc7d6943SzhanglyGit      bt.io.cancel := io.fromDataPath.cancelToBusyTable
176730cfbc0SXuan Hu    case None =>
177730cfbc0SXuan Hu  }
178730cfbc0SXuan Hu
179c0be7f33SXuan Hu  val wakeupFromWBVec = Wire(params.genWBWakeUpSinkValidBundle)
180730cfbc0SXuan Hu  val writeback = params.schdType match {
181730cfbc0SXuan Hu    case IntScheduler() => io.intWriteBack
182730cfbc0SXuan Hu    case MemScheduler() => io.intWriteBack ++ io.vfWriteBack
183730cfbc0SXuan Hu    case VfScheduler() => io.vfWriteBack
184730cfbc0SXuan Hu    case _ => Seq()
185730cfbc0SXuan Hu  }
186730cfbc0SXuan Hu  wakeupFromWBVec.zip(writeback).foreach { case (sink, source) =>
187730cfbc0SXuan Hu    sink.valid := source.wen
188730cfbc0SXuan Hu    sink.bits.rfWen := source.intWen
189730cfbc0SXuan Hu    sink.bits.fpWen := source.fpWen
190730cfbc0SXuan Hu    sink.bits.vecWen := source.vecWen
191730cfbc0SXuan Hu    sink.bits.pdest := source.addr
192730cfbc0SXuan Hu  }
193730cfbc0SXuan Hu
194bf35baadSXuan Hu  // Connect bundles having the same wakeup source
19559ef6009Sxiaofeibao-xjtu  issueQueues.zipWithIndex.foreach { case(iq, i) =>
196bf35baadSXuan Hu    iq.io.wakeupFromIQ.foreach { wakeUp =>
197c0be7f33SXuan Hu      wakeUp := iqWakeUpInMap(wakeUp.bits.exuIdx)
198bf35baadSXuan Hu    }
199ea46c302SXuan Hu    iq.io.og0Cancel := io.fromDataPath.og0Cancel
200ea46c302SXuan Hu    iq.io.og1Cancel := io.fromDataPath.og1Cancel
2010f55a0d3SHaojin Tang    iq.io.ldCancel := io.ldCancel
20259ef6009Sxiaofeibao-xjtu    iq.io.fromCancelNetwork <> io.fromCancelNetwork(i)
203bf35baadSXuan Hu  }
204bf35baadSXuan Hu
205c0be7f33SXuan Hu  private val iqWakeUpOutMap: Map[Int, ValidIO[IssueQueueIQWakeUpBundle]] =
206bf35baadSXuan Hu    issueQueues.flatMap(_.io.wakeupToIQ)
207c0be7f33SXuan Hu      .map(x => (x.bits.exuIdx, x))
208bf35baadSXuan Hu      .toMap
209bf35baadSXuan Hu
210bf35baadSXuan Hu  // Connect bundles having the same wakeup source
211bf35baadSXuan Hu  io.toSchedulers.wakeupVec.foreach { wakeUp =>
212c0be7f33SXuan Hu    wakeUp := iqWakeUpOutMap(wakeUp.bits.exuIdx)
213bf35baadSXuan Hu  }
214bf35baadSXuan Hu
215730cfbc0SXuan Hu  io.toDataPath.zipWithIndex.foreach { case (toDp, i) =>
216730cfbc0SXuan Hu    toDp <> issueQueues(i).io.deq
217730cfbc0SXuan Hu  }
21859ef6009Sxiaofeibao-xjtu  io.toDataPathAfterDelay.zipWithIndex.foreach { case (toDpDy, i) =>
21959ef6009Sxiaofeibao-xjtu    toDpDy <> issueQueues(i).io.deqDelay
22059ef6009Sxiaofeibao-xjtu  }
221bf35baadSXuan Hu
222f99b81adSHaojin Tang  // Response
223f99b81adSHaojin Tang  issueQueues.zipWithIndex.foreach { case (iq, i) =>
224f99b81adSHaojin Tang    iq.io.deqResp.zipWithIndex.foreach { case (deqResp, j) =>
225f99b81adSHaojin Tang      deqResp.valid := iq.io.deq(j).valid && io.toDataPath(i)(j).ready
226f99b81adSHaojin Tang      deqResp.bits.respType := RSFeedbackType.issueSuccess
227f99b81adSHaojin Tang      deqResp.bits.robIdx := iq.io.deq(j).bits.common.robIdx
228887f9c3dSzhanglinjuan      deqResp.bits.uopIdx := iq.io.deq(j).bits.common.vpu.getOrElse(0.U.asTypeOf(new VPUCtrlSignals)).vuopIdx
229f99b81adSHaojin Tang      deqResp.bits.dataInvalidSqIdx := DontCare
230f99b81adSHaojin Tang      deqResp.bits.rfWen := iq.io.deq(j).bits.common.rfWen.getOrElse(false.B)
231f99b81adSHaojin Tang      deqResp.bits.fuType := iq.io.deq(j).bits.common.fuType
232f99b81adSHaojin Tang    }
233f99b81adSHaojin Tang    iq.io.og0Resp.zipWithIndex.foreach { case (og0Resp, j) =>
234f99b81adSHaojin Tang      og0Resp := io.fromDataPath(i)(j).og0resp
235f99b81adSHaojin Tang    }
236f99b81adSHaojin Tang    iq.io.og1Resp.zipWithIndex.foreach { case (og1Resp, j) =>
237f99b81adSHaojin Tang      og1Resp := io.fromDataPath(i)(j).og1resp
238f99b81adSHaojin Tang    }
239f99b81adSHaojin Tang    iq.io.finalIssueResp.foreach(_.zipWithIndex.foreach { case (finalIssueResp, j) =>
240670870b3SXuan Hu      if (io.loadFinalIssueResp(i).isDefinedAt(j)) {
241f99b81adSHaojin Tang        finalIssueResp := io.loadFinalIssueResp(i)(j)
242670870b3SXuan Hu      } else {
243670870b3SXuan Hu        finalIssueResp := 0.U.asTypeOf(finalIssueResp)
244670870b3SXuan Hu      }
245f99b81adSHaojin Tang    })
246e8800897SXuan Hu    iq.io.memAddrIssueResp.foreach(_.zipWithIndex.foreach { case (memAddrIssueResp, j) =>
247e8800897SXuan Hu      memAddrIssueResp := io.memAddrIssueResp(i)(j)
248e8800897SXuan Hu    })
249f99b81adSHaojin Tang    iq.io.wbBusyTableRead := io.fromWbFuBusyTable.fuBusyTableRead(i)
250f99b81adSHaojin Tang    io.wbFuBusyTable(i) := iq.io.wbBusyTableWrite
251f99b81adSHaojin Tang  }
252f99b81adSHaojin Tang
253c0be7f33SXuan Hu  println(s"[Scheduler] io.fromSchedulers.wakeupVec: ${io.fromSchedulers.wakeupVec.map(x => backendParams.getExuName(x.bits.exuIdx))}")
254bf35baadSXuan Hu  println(s"[Scheduler] iqWakeUpInKeys: ${iqWakeUpInMap.keys}")
255bf35baadSXuan Hu
256bf35baadSXuan Hu  println(s"[Scheduler] iqWakeUpOutKeys: ${iqWakeUpOutMap.keys}")
257c0be7f33SXuan Hu  println(s"[Scheduler] io.toSchedulers.wakeupVec: ${io.toSchedulers.wakeupVec.map(x => backendParams.getExuName(x.bits.exuIdx))}")
258730cfbc0SXuan Hu}
259730cfbc0SXuan Hu
260730cfbc0SXuan Huclass SchedulerArithImp(override val wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters)
261730cfbc0SXuan Hu  extends SchedulerImpBase(wrapper)
262730cfbc0SXuan Hu    with HasXSParameter
263730cfbc0SXuan Hu{
2642e0a7dc5Sfdy//  dontTouch(io.vfWbFuBusyTable)
265730cfbc0SXuan Hu  println(s"[SchedulerArithImp] " +
266730cfbc0SXuan Hu    s"has intBusyTable: ${intBusyTable.nonEmpty}, " +
267730cfbc0SXuan Hu    s"has vfBusyTable: ${vfBusyTable.nonEmpty}")
268730cfbc0SXuan Hu
269730cfbc0SXuan Hu  issueQueues.zipWithIndex.foreach { case (iq, i) =>
270730cfbc0SXuan Hu    iq.io.flush <> io.fromCtrlBlock.flush
271730cfbc0SXuan Hu    iq.io.enq <> dispatch2Iq.io.out(i)
272bf35baadSXuan Hu    iq.io.wakeupFromWB := wakeupFromWBVec
273730cfbc0SXuan Hu  }
274730cfbc0SXuan Hu}
275730cfbc0SXuan Hu
276f99b81adSHaojin Tang// FIXME: Vector mem instructions may not be handled properly!
277730cfbc0SXuan Huclass SchedulerMemImp(override val wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters)
278730cfbc0SXuan Hu  extends SchedulerImpBase(wrapper)
279730cfbc0SXuan Hu    with HasXSParameter
280730cfbc0SXuan Hu{
281730cfbc0SXuan Hu  println(s"[SchedulerMemImp] " +
282730cfbc0SXuan Hu    s"has intBusyTable: ${intBusyTable.nonEmpty}, " +
283730cfbc0SXuan Hu    s"has vfBusyTable: ${vfBusyTable.nonEmpty}")
284730cfbc0SXuan Hu
285*559c1710SHaojin Tang  val memAddrIQs = issueQueues.filter(_.params.isMemAddrIQ)
2862d270511Ssinsanction  val stAddrIQs = issueQueues.filter(iq => iq.params.StaCnt > 0 || iq.params.VstaCnt > 0) // included in memAddrIQs
2872d270511Ssinsanction  val ldAddrIQs = issueQueues.filter(iq => iq.params.LduCnt > 0 || iq.params.VlduCnt > 0)
2882d270511Ssinsanction  val stDataIQs = issueQueues.filter(iq => iq.params.StdCnt > 0 || iq.params.VstdCnt > 0)
289*559c1710SHaojin Tang  val vecMemIQs = issueQueues.filter(_.params.isVecMemIQ)
290*559c1710SHaojin Tang  val (hyuIQs, hyuIQIdxs) = issueQueues.zipWithIndex.filter(_._1.params.HyuCnt > 0).unzip
291499caf4cSXuan Hu
292499caf4cSXuan Hu  println(s"[SchedulerMemImp] memAddrIQs.size: ${memAddrIQs.size}, enq.size: ${memAddrIQs.map(_.io.enq.size).sum}")
293499caf4cSXuan Hu  println(s"[SchedulerMemImp] stAddrIQs.size:  ${stAddrIQs.size }, enq.size: ${stAddrIQs.map(_.io.enq.size).sum}")
294499caf4cSXuan Hu  println(s"[SchedulerMemImp] ldAddrIQs.size:  ${ldAddrIQs.size }, enq.size: ${ldAddrIQs.map(_.io.enq.size).sum}")
295499caf4cSXuan Hu  println(s"[SchedulerMemImp] stDataIQs.size:  ${stDataIQs.size }, enq.size: ${stDataIQs.map(_.io.enq.size).sum}")
296499caf4cSXuan Hu  println(s"[SchedulerMemImp] hyuIQs.size:     ${hyuIQs.size    }, enq.size: ${hyuIQs.map(_.io.enq.size).sum}")
297730cfbc0SXuan Hu  require(memAddrIQs.nonEmpty && stDataIQs.nonEmpty)
298730cfbc0SXuan Hu
299853cd2d8SHaojin Tang  io.toMem.get.loadFastMatch := 0.U.asTypeOf(io.toMem.get.loadFastMatch) // TODO: is still needed?
300853cd2d8SHaojin Tang
301730cfbc0SXuan Hu  memAddrIQs.zipWithIndex.foreach { case (iq, i) =>
302730cfbc0SXuan Hu    iq.io.flush <> io.fromCtrlBlock.flush
303730cfbc0SXuan Hu    iq.io.enq <> dispatch2Iq.io.out(i)
304bf35baadSXuan Hu    iq.io.wakeupFromWB := wakeupFromWBVec
305730cfbc0SXuan Hu  }
306730cfbc0SXuan Hu
307ecfc6f16SXuan Hu  ldAddrIQs.zipWithIndex.foreach {
308ecfc6f16SXuan Hu    case (imp: IssueQueueMemAddrImp, i) =>
309ecfc6f16SXuan Hu      imp.io.memIO.get.feedbackIO.head := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO.head)
310c14e89f4SHaojin Tang      imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr
311de784418SXuan Hu      imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
3127b753bebSXuan Hu    case _ =>
3137b753bebSXuan Hu  }
3147b753bebSXuan Hu
315ecfc6f16SXuan Hu  stAddrIQs.zipWithIndex.foreach {
316ecfc6f16SXuan Hu    case (imp: IssueQueueMemAddrImp, i) =>
317ecfc6f16SXuan Hu      imp.io.memIO.get.feedbackIO.head := io.fromMem.get.staFeedback(i)
318c14e89f4SHaojin Tang      imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr
319c14e89f4SHaojin Tang      imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
3207b753bebSXuan Hu    case _ =>
3217b753bebSXuan Hu  }
322730cfbc0SXuan Hu
323*559c1710SHaojin Tang  hyuIQs.zip(hyuIQIdxs).foreach {
324*559c1710SHaojin Tang    case (imp: IssueQueueMemAddrImp, idx) =>
325670870b3SXuan Hu      imp.io.memIO.get.feedbackIO.head := io.fromMem.get.hyuFeedback.head
326670870b3SXuan Hu      imp.io.memIO.get.feedbackIO(1) := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO(1))
3278f1fa9b1Ssfencevma      imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr
3288f1fa9b1Ssfencevma      imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
329*559c1710SHaojin Tang      // TODO: refactor ditry code
330*559c1710SHaojin Tang      imp.io.deq(1).ready := false.B
331*559c1710SHaojin Tang      imp.io.deqDelay(1).ready := false.B
332*559c1710SHaojin Tang      io.toDataPath(idx)(1).valid := false.B
333*559c1710SHaojin Tang      io.toDataPathAfterDelay(idx)(1).valid := false.B
334*559c1710SHaojin Tang      io.toDataPath(idx)(1).bits := 0.U.asTypeOf(io.toDataPath(idx)(1).bits)
335*559c1710SHaojin Tang      io.toDataPathAfterDelay(idx)(1).bits := 0.U.asTypeOf(io.toDataPathAfterDelay(idx)(1).bits)
3368f1fa9b1Ssfencevma    case _ =>
3378f1fa9b1Ssfencevma  }
3388f1fa9b1Ssfencevma
339e62b6911SXuan Hu  private val staIdxSeq = (stAddrIQs).map(iq => iq.params.idxInSchBlk)
340e62b6911SXuan Hu  private val hyaIdxSeq = (hyuIQs).map(iq => iq.params.idxInSchBlk)
341e62b6911SXuan Hu
342e62b6911SXuan Hu  println(s"[SchedulerMemImp] sta iq idx in memSchdBlock: $staIdxSeq")
343e62b6911SXuan Hu  println(s"[SchedulerMemImp] hya iq idx in memSchdBlock: $hyaIdxSeq")
344e62b6911SXuan Hu
345e62b6911SXuan Hu  private val staEnqs = stAddrIQs.map(_.io.enq).flatten
346e62b6911SXuan Hu  private val stdEnqs = stDataIQs.map(_.io.enq).flatten.take(staEnqs.size)
347e62b6911SXuan Hu  private val hyaEnqs = hyuIQs.map(_.io.enq).flatten
348e62b6911SXuan Hu  private val hydEnqs = stDataIQs.map(_.io.enq).flatten.drop(staEnqs.size)
349e62b6911SXuan Hu
350e62b6911SXuan Hu  require(staEnqs.size == stdEnqs.size, s"number of enq ports of store address IQs(${staEnqs.size}) " +
351e62b6911SXuan Hu  s"should be equal to number of enq ports of store data IQs(${stdEnqs.size})")
352e62b6911SXuan Hu
353e62b6911SXuan Hu  require(hyaEnqs.size == hydEnqs.size, s"number of enq ports of hybrid address IQs(${hyaEnqs.size}) " +
354e62b6911SXuan Hu  s"should be equal to number of enq ports of hybrid data IQs(${hydEnqs.size})")
3559b258a00Sxgkiri
3569b258a00Sxgkiri  for ((idxInSchBlk, i) <- staIdxSeq.zipWithIndex) {
357e62b6911SXuan Hu    dispatch2Iq.io.out(idxInSchBlk).zip(staEnqs).zip(stdEnqs).foreach{ case((dp, staIQ), stdIQ) =>
358730cfbc0SXuan Hu      val isAllReady = staIQ.ready && stdIQ.ready
359e62b6911SXuan Hu      dp.ready := isAllReady
360e62b6911SXuan Hu      staIQ.valid := dp.valid && isAllReady
3614ec52c44SXuan Hu      stdIQ.valid := dp.valid && isAllReady && FuType.isStore(dp.bits.fuType)
362730cfbc0SXuan Hu    }
3639b258a00Sxgkiri  }
364730cfbc0SXuan Hu
365e62b6911SXuan Hu  for ((idxInSchBlk, i) <- hyaIdxSeq.zipWithIndex) {
366e62b6911SXuan Hu    dispatch2Iq.io.out(idxInSchBlk).zip(hyaEnqs).zip(hydEnqs).foreach{ case((dp, hyaIQ), hydIQ) =>
367e62b6911SXuan Hu      val isAllReady = hyaIQ.ready && hydIQ.ready
368e62b6911SXuan Hu      dp.ready := isAllReady
369e62b6911SXuan Hu      hyaIQ.valid := dp.valid && isAllReady
37056bceacbSHaojin Tang      hydIQ.valid := dp.valid && isAllReady && FuType.FuTypeOrR(dp.bits.fuType, FuType.stu, FuType.mou)
371e62b6911SXuan Hu    }
372e62b6911SXuan Hu  }
373730cfbc0SXuan Hu
374e62b6911SXuan Hu  stDataIQs.zipWithIndex.foreach { case (iq, i) =>
375e62b6911SXuan Hu    iq.io.flush <> io.fromCtrlBlock.flush
376e62b6911SXuan Hu    iq.io.wakeupFromWB := wakeupFromWBVec
377e62b6911SXuan Hu  }
378e62b6911SXuan Hu
379e62b6911SXuan Hu  (stdEnqs ++ hydEnqs).zip(staEnqs ++ hyaEnqs).zipWithIndex.foreach { case ((stdIQEnq, staIQEnq), i) =>
380730cfbc0SXuan Hu    stdIQEnq.bits  := staIQEnq.bits
381730cfbc0SXuan Hu    // Store data reuses store addr src(1) in dispatch2iq
382e62b6911SXuan Hu    // [dispatch2iq] --src*------src*(0)--> [staIQ|hyaIQ]
383730cfbc0SXuan Hu    //                       \
384730cfbc0SXuan Hu    //                        ---src*(1)--> [stdIQ]
385730cfbc0SXuan Hu    // Since the src(1) of sta is easier to get, stdIQEnq.bits.src*(0) is assigned to staIQEnq.bits.src*(1)
386730cfbc0SXuan Hu    // instead of dispatch2Iq.io.out(x).bits.src*(1)
38797b279b9SXuan Hu    val stdIdx = 1
3882d270511Ssinsanction    stdIQEnq.bits.srcState(0) := staIQEnq.bits.srcState(stdIdx)
3892d270511Ssinsanction    stdIQEnq.bits.srcType(0) := staIQEnq.bits.srcType(stdIdx)
3902d270511Ssinsanction    stdIQEnq.bits.dataSource(0) := staIQEnq.bits.dataSource(stdIdx)
3912d270511Ssinsanction    stdIQEnq.bits.l1ExuOH(0) := staIQEnq.bits.l1ExuOH(stdIdx)
3922d270511Ssinsanction    stdIQEnq.bits.psrc(0) := staIQEnq.bits.psrc(stdIdx)
393730cfbc0SXuan Hu    stdIQEnq.bits.sqIdx := staIQEnq.bits.sqIdx
394730cfbc0SXuan Hu  }
395730cfbc0SXuan Hu
3962d270511Ssinsanction  vecMemIQs.foreach {
3972d270511Ssinsanction    case imp: IssueQueueVecMemImp =>
3982d270511Ssinsanction      imp.io.memIO.get.sqDeqPtr.foreach(_ := io.fromMem.get.sqDeqPtr)
3992d270511Ssinsanction      imp.io.memIO.get.lqDeqPtr.foreach(_ := io.fromMem.get.lqDeqPtr)
4001f3d1b4dSXuan Hu      // not used
4011f3d1b4dSXuan Hu      imp.io.memIO.get.feedbackIO := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO)
4021f3d1b4dSXuan Hu      // maybe not used
4031f3d1b4dSXuan Hu      imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr
4041f3d1b4dSXuan Hu      imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
4052d270511Ssinsanction    case _ =>
4062d270511Ssinsanction  }
4072d270511Ssinsanction
408730cfbc0SXuan Hu  val lsqEnqCtrl = Module(new LsqEnqCtrl)
409730cfbc0SXuan Hu
410730cfbc0SXuan Hu  lsqEnqCtrl.io.redirect <> io.fromCtrlBlock.flush
411730cfbc0SXuan Hu  lsqEnqCtrl.io.enq <> dispatch2Iq.io.enqLsqIO.get
412730cfbc0SXuan Hu  lsqEnqCtrl.io.lcommit := io.fromMem.get.lcommit
413730cfbc0SXuan Hu  lsqEnqCtrl.io.scommit := io.fromMem.get.scommit
414730cfbc0SXuan Hu  lsqEnqCtrl.io.lqCancelCnt := io.fromMem.get.lqCancelCnt
415730cfbc0SXuan Hu  lsqEnqCtrl.io.sqCancelCnt := io.fromMem.get.sqCancelCnt
416730cfbc0SXuan Hu  io.memIO.get.lsqEnqIO <> lsqEnqCtrl.io.enqLsq
417730cfbc0SXuan Hu}
418