xref: /XiangShan/src/main/scala/xiangshan/backend/issue/Scheduler.scala (revision e62b6911ae93719e61651d0e98c7aca586ea8bb5)
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}
11*e62b6911SXuan 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
860f55a0d3SHaojin Tang  val loadFinalIssueResp = MixedVec(params.issueBlockParams.map(x => MixedVec(Vec(x.LduCnt, Flipped(ValidIO(new IssueQueueDeqRespBundle()(p, x)))))))
87e8800897SXuan Hu  val memAddrIssueResp = MixedVec(params.issueBlockParams.map(x => MixedVec(Vec(x.LduCnt, 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) =>
234f99b81adSHaojin Tang      finalIssueResp := io.loadFinalIssueResp(i)(j)
235f99b81adSHaojin Tang    })
236e8800897SXuan Hu    iq.io.memAddrIssueResp.foreach(_.zipWithIndex.foreach { case (memAddrIssueResp, j) =>
237e8800897SXuan Hu      memAddrIssueResp := io.memAddrIssueResp(i)(j)
238e8800897SXuan Hu    })
239f99b81adSHaojin Tang    iq.io.wbBusyTableRead := io.fromWbFuBusyTable.fuBusyTableRead(i)
240f99b81adSHaojin Tang    io.wbFuBusyTable(i) := iq.io.wbBusyTableWrite
241f99b81adSHaojin Tang  }
242f99b81adSHaojin Tang
243c0be7f33SXuan Hu  println(s"[Scheduler] io.fromSchedulers.wakeupVec: ${io.fromSchedulers.wakeupVec.map(x => backendParams.getExuName(x.bits.exuIdx))}")
244bf35baadSXuan Hu  println(s"[Scheduler] iqWakeUpInKeys: ${iqWakeUpInMap.keys}")
245bf35baadSXuan Hu
246bf35baadSXuan Hu  println(s"[Scheduler] iqWakeUpOutKeys: ${iqWakeUpOutMap.keys}")
247c0be7f33SXuan Hu  println(s"[Scheduler] io.toSchedulers.wakeupVec: ${io.toSchedulers.wakeupVec.map(x => backendParams.getExuName(x.bits.exuIdx))}")
248730cfbc0SXuan Hu}
249730cfbc0SXuan Hu
250730cfbc0SXuan Huclass SchedulerArithImp(override val wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters)
251730cfbc0SXuan Hu  extends SchedulerImpBase(wrapper)
252730cfbc0SXuan Hu    with HasXSParameter
253730cfbc0SXuan Hu{
2542e0a7dc5Sfdy//  dontTouch(io.vfWbFuBusyTable)
255730cfbc0SXuan Hu  println(s"[SchedulerArithImp] " +
256730cfbc0SXuan Hu    s"has intBusyTable: ${intBusyTable.nonEmpty}, " +
257730cfbc0SXuan Hu    s"has vfBusyTable: ${vfBusyTable.nonEmpty}")
258730cfbc0SXuan Hu
259730cfbc0SXuan Hu  issueQueues.zipWithIndex.foreach { case (iq, i) =>
260730cfbc0SXuan Hu    iq.io.flush <> io.fromCtrlBlock.flush
261730cfbc0SXuan Hu    iq.io.enq <> dispatch2Iq.io.out(i)
262bf35baadSXuan Hu    iq.io.wakeupFromWB := wakeupFromWBVec
263730cfbc0SXuan Hu  }
264730cfbc0SXuan Hu}
265730cfbc0SXuan Hu
266f99b81adSHaojin Tang// FIXME: Vector mem instructions may not be handled properly!
267730cfbc0SXuan Huclass SchedulerMemImp(override val wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters)
268730cfbc0SXuan Hu  extends SchedulerImpBase(wrapper)
269730cfbc0SXuan Hu    with HasXSParameter
270730cfbc0SXuan Hu{
271730cfbc0SXuan Hu  println(s"[SchedulerMemImp] " +
272730cfbc0SXuan Hu    s"has intBusyTable: ${intBusyTable.nonEmpty}, " +
273730cfbc0SXuan Hu    s"has vfBusyTable: ${vfBusyTable.nonEmpty}")
274730cfbc0SXuan Hu
275730cfbc0SXuan Hu  val memAddrIQs = issueQueues.filter(iq => iq.params.StdCnt == 0)
276730cfbc0SXuan Hu  val stAddrIQs = issueQueues.filter(iq => iq.params.StaCnt > 0) // included in memAddrIQs
2777b753bebSXuan Hu  val ldAddrIQs = issueQueues.filter(iq => iq.params.LduCnt > 0)
278730cfbc0SXuan Hu  val stDataIQs = issueQueues.filter(iq => iq.params.StdCnt > 0)
2798f1fa9b1Ssfencevma  val hyuIQs = issueQueues.filter(iq => iq.params.HyuCnt > 0)
280499caf4cSXuan Hu
281499caf4cSXuan Hu  println(s"[SchedulerMemImp] memAddrIQs.size: ${memAddrIQs.size}, enq.size: ${memAddrIQs.map(_.io.enq.size).sum}")
282499caf4cSXuan Hu  println(s"[SchedulerMemImp] stAddrIQs.size:  ${stAddrIQs.size }, enq.size: ${stAddrIQs.map(_.io.enq.size).sum}")
283499caf4cSXuan Hu  println(s"[SchedulerMemImp] ldAddrIQs.size:  ${ldAddrIQs.size }, enq.size: ${ldAddrIQs.map(_.io.enq.size).sum}")
284499caf4cSXuan Hu  println(s"[SchedulerMemImp] stDataIQs.size:  ${stDataIQs.size }, enq.size: ${stDataIQs.map(_.io.enq.size).sum}")
285499caf4cSXuan Hu  println(s"[SchedulerMemImp] hyuIQs.size:     ${hyuIQs.size    }, enq.size: ${hyuIQs.map(_.io.enq.size).sum}")
286730cfbc0SXuan Hu  require(memAddrIQs.nonEmpty && stDataIQs.nonEmpty)
287730cfbc0SXuan Hu
288853cd2d8SHaojin Tang  io.toMem.get.loadFastMatch := 0.U.asTypeOf(io.toMem.get.loadFastMatch) // TODO: is still needed?
289853cd2d8SHaojin Tang
290730cfbc0SXuan Hu  memAddrIQs.zipWithIndex.foreach { case (iq, i) =>
291730cfbc0SXuan Hu    iq.io.flush <> io.fromCtrlBlock.flush
292730cfbc0SXuan Hu    iq.io.enq <> dispatch2Iq.io.out(i)
293bf35baadSXuan Hu    iq.io.wakeupFromWB := wakeupFromWBVec
294730cfbc0SXuan Hu  }
295730cfbc0SXuan Hu
2967b753bebSXuan Hu  ldAddrIQs.foreach {
297de784418SXuan Hu    case imp: IssueQueueMemAddrImp =>
298de784418SXuan Hu      imp.io.memIO.get.feedbackIO <> io.fromMem.get.ldaFeedback
299c14e89f4SHaojin Tang      imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr
300de784418SXuan Hu      imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
3017b753bebSXuan Hu    case _ =>
3027b753bebSXuan Hu  }
3037b753bebSXuan Hu
3047b753bebSXuan Hu  stAddrIQs.foreach {
305c14e89f4SHaojin Tang    case imp: IssueQueueMemAddrImp =>
306c14e89f4SHaojin Tang      imp.io.memIO.get.feedbackIO <> io.fromMem.get.staFeedback
307c14e89f4SHaojin Tang      imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr
308c14e89f4SHaojin Tang      imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
3097b753bebSXuan Hu    case _ =>
3107b753bebSXuan Hu  }
311730cfbc0SXuan Hu
3128f1fa9b1Ssfencevma  hyuIQs.foreach {
3138f1fa9b1Ssfencevma    case imp: IssueQueueMemAddrImp =>
3148f1fa9b1Ssfencevma      imp.io.memIO.get.feedbackIO <> io.fromMem.get.hyuFeedback
3158f1fa9b1Ssfencevma      imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr
3168f1fa9b1Ssfencevma      imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
3178f1fa9b1Ssfencevma    case _ =>
3188f1fa9b1Ssfencevma  }
3198f1fa9b1Ssfencevma
320166eb00dSHaojin Tang  // TODO: Implement vstu
321166eb00dSHaojin Tang  issueQueues.filter(iq => iq.params.VstuCnt > 0).foreach {
322166eb00dSHaojin Tang    case imp: IssueQueueMemAddrImp =>
323166eb00dSHaojin Tang      imp.io.memIO.get.feedbackIO <> DontCare
324166eb00dSHaojin Tang      imp.io.memIO.get.checkWait.stIssuePtr := DontCare
325166eb00dSHaojin Tang      imp.io.memIO.get.checkWait.memWaitUpdateReq := DontCare
326166eb00dSHaojin Tang    case _ =>
327166eb00dSHaojin Tang  }
328166eb00dSHaojin Tang
329166eb00dSHaojin Tang  // TODO: Implement vldu
330166eb00dSHaojin Tang  issueQueues.filter(iq => iq.params.VlduCnt > 0).foreach {
331166eb00dSHaojin Tang    case imp: IssueQueueMemAddrImp =>
332166eb00dSHaojin Tang      imp.io.memIO.get.feedbackIO <> DontCare
333166eb00dSHaojin Tang      imp.io.memIO.get.checkWait.stIssuePtr := DontCare
334166eb00dSHaojin Tang      imp.io.memIO.get.checkWait.memWaitUpdateReq := DontCare
335166eb00dSHaojin Tang    case _ =>
336166eb00dSHaojin Tang  }
337166eb00dSHaojin Tang
338*e62b6911SXuan Hu  private val staIdxSeq = (stAddrIQs).map(iq => iq.params.idxInSchBlk)
339*e62b6911SXuan Hu  private val hyaIdxSeq = (hyuIQs).map(iq => iq.params.idxInSchBlk)
340*e62b6911SXuan Hu
341*e62b6911SXuan Hu  println(s"[SchedulerMemImp] sta iq idx in memSchdBlock: $staIdxSeq")
342*e62b6911SXuan Hu  println(s"[SchedulerMemImp] hya iq idx in memSchdBlock: $hyaIdxSeq")
343*e62b6911SXuan Hu
344*e62b6911SXuan Hu  private val staEnqs = stAddrIQs.map(_.io.enq).flatten
345*e62b6911SXuan Hu  private val stdEnqs = stDataIQs.map(_.io.enq).flatten.take(staEnqs.size)
346*e62b6911SXuan Hu  private val hyaEnqs = hyuIQs.map(_.io.enq).flatten
347*e62b6911SXuan Hu  private val hydEnqs = stDataIQs.map(_.io.enq).flatten.drop(staEnqs.size)
348*e62b6911SXuan Hu
349*e62b6911SXuan Hu  require(staEnqs.size == stdEnqs.size, s"number of enq ports of store address IQs(${staEnqs.size}) " +
350*e62b6911SXuan Hu  s"should be equal to number of enq ports of store data IQs(${stdEnqs.size})")
351*e62b6911SXuan Hu
352*e62b6911SXuan Hu  require(hyaEnqs.size == hydEnqs.size, s"number of enq ports of hybrid address IQs(${hyaEnqs.size}) " +
353*e62b6911SXuan Hu  s"should be equal to number of enq ports of hybrid data IQs(${hydEnqs.size})")
3549b258a00Sxgkiri
3559b258a00Sxgkiri  for ((idxInSchBlk, i) <- staIdxSeq.zipWithIndex) {
356*e62b6911SXuan Hu    dispatch2Iq.io.out(idxInSchBlk).zip(staEnqs).zip(stdEnqs).foreach{ case((dp, staIQ), stdIQ) =>
357730cfbc0SXuan Hu      val isAllReady = staIQ.ready && stdIQ.ready
358*e62b6911SXuan Hu      dp.ready := isAllReady
359*e62b6911SXuan Hu      staIQ.valid := dp.valid && isAllReady
360*e62b6911SXuan Hu      stdIQ.valid := dp.valid && isAllReady
361730cfbc0SXuan Hu    }
3629b258a00Sxgkiri  }
363730cfbc0SXuan Hu
364*e62b6911SXuan Hu  for ((idxInSchBlk, i) <- hyaIdxSeq.zipWithIndex) {
365*e62b6911SXuan Hu    dispatch2Iq.io.out(idxInSchBlk).zip(hyaEnqs).zip(hydEnqs).foreach{ case((dp, hyaIQ), hydIQ) =>
366*e62b6911SXuan Hu      val isAllReady = hyaIQ.ready && hydIQ.ready
367*e62b6911SXuan Hu      dp.ready := isAllReady
368*e62b6911SXuan Hu      hyaIQ.valid := dp.valid && isAllReady
369*e62b6911SXuan Hu      hydIQ.valid := dp.valid && isAllReady && FuType.isStore(dp.bits.fuType)
370*e62b6911SXuan Hu    }
371*e62b6911SXuan Hu  }
372730cfbc0SXuan Hu
373*e62b6911SXuan Hu  stDataIQs.zipWithIndex.foreach { case (iq, i) =>
374*e62b6911SXuan Hu    iq.io.flush <> io.fromCtrlBlock.flush
375*e62b6911SXuan Hu    iq.io.wakeupFromWB := wakeupFromWBVec
376*e62b6911SXuan Hu  }
377*e62b6911SXuan Hu
378*e62b6911SXuan Hu  (stdEnqs ++ hydEnqs).zip(staEnqs ++ hyaEnqs).zipWithIndex.foreach { case ((stdIQEnq, staIQEnq), i) =>
379730cfbc0SXuan Hu    stdIQEnq.bits  := staIQEnq.bits
380730cfbc0SXuan Hu    // Store data reuses store addr src(1) in dispatch2iq
381*e62b6911SXuan Hu    // [dispatch2iq] --src*------src*(0)--> [staIQ|hyaIQ]
382730cfbc0SXuan Hu    //                       \
383730cfbc0SXuan Hu    //                        ---src*(1)--> [stdIQ]
384730cfbc0SXuan Hu    // Since the src(1) of sta is easier to get, stdIQEnq.bits.src*(0) is assigned to staIQEnq.bits.src*(1)
385730cfbc0SXuan Hu    // instead of dispatch2Iq.io.out(x).bits.src*(1)
386730cfbc0SXuan Hu    stdIQEnq.bits.srcState(0) := staIQEnq.bits.srcState(1)
387730cfbc0SXuan Hu    stdIQEnq.bits.srcType(0) := staIQEnq.bits.srcType(1)
388bc7d6943SzhanglyGit    stdIQEnq.bits.dataSource(0) := staIQEnq.bits.dataSource(1)
389bc7d6943SzhanglyGit    stdIQEnq.bits.l1ExuOH(0) := staIQEnq.bits.l1ExuOH(1)
390730cfbc0SXuan Hu    stdIQEnq.bits.psrc(0) := staIQEnq.bits.psrc(1)
391730cfbc0SXuan Hu    stdIQEnq.bits.sqIdx := staIQEnq.bits.sqIdx
392730cfbc0SXuan Hu  }
393730cfbc0SXuan Hu
394730cfbc0SXuan Hu  val lsqEnqCtrl = Module(new LsqEnqCtrl)
395730cfbc0SXuan Hu
396730cfbc0SXuan Hu  lsqEnqCtrl.io.redirect <> io.fromCtrlBlock.flush
397730cfbc0SXuan Hu  lsqEnqCtrl.io.enq <> dispatch2Iq.io.enqLsqIO.get
398730cfbc0SXuan Hu  lsqEnqCtrl.io.lcommit := io.fromMem.get.lcommit
399730cfbc0SXuan Hu  lsqEnqCtrl.io.scommit := io.fromMem.get.scommit
400730cfbc0SXuan Hu  lsqEnqCtrl.io.lqCancelCnt := io.fromMem.get.lqCancelCnt
401730cfbc0SXuan Hu  lsqEnqCtrl.io.sqCancelCnt := io.fromMem.get.sqCancelCnt
402730cfbc0SXuan Hu  io.memIO.get.lsqEnqIO <> lsqEnqCtrl.io.enqLsq
403730cfbc0SXuan Hu}
404