xref: /XiangShan/src/main/scala/xiangshan/backend/issue/Scheduler.scala (revision b6279fc62b995344eb1f409e6a3b794762f82d5e)
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)))
52c1e19666Sxiaofeibao-xjtu  val IQValidNumVec = Output(MixedVec(backendParams.genIQValidNumBundle))
53dd970561SzhanglyGit
54730cfbc0SXuan Hu  val fromCtrlBlock = new Bundle {
55730cfbc0SXuan Hu    val flush = Flipped(ValidIO(new Redirect))
56730cfbc0SXuan Hu  }
57730cfbc0SXuan Hu  val fromDispatch = new Bundle {
58730cfbc0SXuan Hu    val allocPregs = Vec(RenameWidth, Input(new ResetPregStateReq))
59730cfbc0SXuan Hu    val uops =  Vec(params.numUopIn, Flipped(DecoupledIO(new DynInst)))
60730cfbc0SXuan Hu  }
6139c59369SXuan Hu  val intWriteBack = MixedVec(Vec(backendParams.numPregWb(IntData()),
62730cfbc0SXuan Hu    new RfWritePortWithConfig(backendParams.intPregParams.dataCfg, backendParams.intPregParams.addrWidth)))
6339c59369SXuan Hu  val vfWriteBack = MixedVec(Vec(backendParams.numPregWb(VecData()),
64730cfbc0SXuan Hu    new RfWritePortWithConfig(backendParams.vfPregParams.dataCfg, backendParams.vfPregParams.addrWidth)))
6559ef6009Sxiaofeibao-xjtu  val toDataPathAfterDelay: MixedVec[MixedVec[DecoupledIO[IssueQueueIssueBundle]]] = MixedVec(params.issueBlockParams.map(_.genIssueDecoupledBundle))
66730cfbc0SXuan Hu
67*b6279fc6SZiyue Zhang  val vlWriteBack = new Bundle {
68*b6279fc6SZiyue Zhang    val vlIsZero = Input(Bool())
69*b6279fc6SZiyue Zhang    val vlIsVlmax = Input(Bool())
70*b6279fc6SZiyue Zhang  }
71*b6279fc6SZiyue Zhang
72bf35baadSXuan Hu  val fromSchedulers = new Bundle {
73c0be7f33SXuan Hu    val wakeupVec: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(params.genIQWakeUpInValidBundle)
74bf35baadSXuan Hu  }
75bf35baadSXuan Hu
76bf35baadSXuan Hu  val toSchedulers = new Bundle {
77c0be7f33SXuan Hu    val wakeupVec: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = params.genIQWakeUpOutValidBundle
78bf35baadSXuan Hu  }
79bf35baadSXuan Hu
80c0be7f33SXuan Hu  val fromDataPath = new Bundle {
8110fe9778SXuan Hu    val resp: MixedVec[MixedVec[OGRespBundle]] = MixedVec(params.issueBlockParams.map(x => Flipped(x.genOGRespBundle)))
827a96cc7fSHaojin Tang    val og0Cancel = Input(ExuOH(backendParams.numExu))
83ea46c302SXuan Hu    // Todo: remove this after no cancel signal from og1
847a96cc7fSHaojin Tang    val og1Cancel = Input(ExuOH(backendParams.numExu))
85bc7d6943SzhanglyGit    val cancelToBusyTable = Vec(backendParams.numExu, Flipped(ValidIO(new CancelSignal)))
86c0be7f33SXuan Hu    // just be compatible to old code
87c0be7f33SXuan Hu    def apply(i: Int)(j: Int) = resp(i)(j)
88c0be7f33SXuan Hu  }
89c0be7f33SXuan Hu
908a66c02cSXuan Hu  val loadFinalIssueResp = MixedVec(params.issueBlockParams.map(x => MixedVec(Vec(x.LdExuCnt, Flipped(ValidIO(new IssueQueueDeqRespBundle()(p, x)))))))
918a66c02cSXuan Hu  val memAddrIssueResp = MixedVec(params.issueBlockParams.map(x => MixedVec(Vec(x.LdExuCnt, Flipped(ValidIO(new IssueQueueDeqRespBundle()(p, x)))))))
927e471bf8SXuan Hu  val vecLoadIssueResp = MixedVec(params.issueBlockParams.map(x => MixedVec(Vec(x.VlduCnt, Flipped(ValidIO(new IssueQueueDeqRespBundle()(p, x)))))))
930f55a0d3SHaojin Tang
946810d1e8Ssfencevma  val ldCancel = Vec(backendParams.LduCnt + backendParams.HyuCnt, Flipped(new LoadCancelIO))
95c0be7f33SXuan Hu
96730cfbc0SXuan Hu  val memIO = if (params.isMemSchd) Some(new Bundle {
97730cfbc0SXuan Hu    val lsqEnqIO = Flipped(new LsqEnqIO)
98730cfbc0SXuan Hu  }) else None
99730cfbc0SXuan Hu  val fromMem = if (params.isMemSchd) Some(new Bundle {
1007b753bebSXuan Hu    val ldaFeedback = Flipped(Vec(params.LduCnt, new MemRSFeedbackIO))
1017b753bebSXuan Hu    val staFeedback = Flipped(Vec(params.StaCnt, new MemRSFeedbackIO))
1028f1fa9b1Ssfencevma    val hyuFeedback = Flipped(Vec(params.HyuCnt, new MemRSFeedbackIO))
103fd490615Sweiding liu    val vstuFeedback = Flipped(Vec(params.VstuCnt, new MemRSFeedbackIO(isVector = true)))
104fd490615Sweiding liu    val vlduFeedback = Flipped(Vec(params.VlduCnt, new MemRSFeedbackIO(isVector = true)))
105730cfbc0SXuan Hu    val stIssuePtr = Input(new SqPtr())
106730cfbc0SXuan Hu    val lcommit = Input(UInt(log2Up(CommitWidth + 1).W))
107730cfbc0SXuan Hu    val scommit = Input(UInt(log2Ceil(EnsbufferWidth + 1).W)) // connected to `memBlock.io.sqDeq` instead of ROB
108fc45ed13SXuan Hu    val wakeup = Vec(params.LdExuCnt, Flipped(Valid(new DynInst)))
1092d270511Ssinsanction    val lqDeqPtr = Input(new LqPtr)
1102d270511Ssinsanction    val sqDeqPtr = Input(new SqPtr)
111730cfbc0SXuan Hu    // from lsq
112730cfbc0SXuan Hu    val lqCancelCnt = Input(UInt(log2Up(LoadQueueSize + 1).W))
113730cfbc0SXuan Hu    val sqCancelCnt = Input(UInt(log2Up(StoreQueueSize + 1).W))
114730cfbc0SXuan Hu    val memWaitUpdateReq = Flipped(new MemWaitUpdateReq)
115730cfbc0SXuan Hu  }) else None
116730cfbc0SXuan Hu  val toMem = if (params.isMemSchd) Some(new Bundle {
117730cfbc0SXuan Hu    val loadFastMatch = Output(Vec(params.LduCnt, new IssueQueueLoadBundle))
118730cfbc0SXuan Hu  }) else None
119730cfbc0SXuan Hu}
120730cfbc0SXuan Hu
121730cfbc0SXuan Huabstract class SchedulerImpBase(wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters)
122730cfbc0SXuan Hu  extends LazyModuleImp(wrapper)
123730cfbc0SXuan Hu    with HasXSParameter
124730cfbc0SXuan Hu{
125730cfbc0SXuan Hu  val io = IO(new SchedulerIO())
126730cfbc0SXuan Hu
127730cfbc0SXuan Hu  // alias
128c0be7f33SXuan Hu  private val iqWakeUpInMap: Map[Int, ValidIO[IssueQueueIQWakeUpBundle]] =
129c0be7f33SXuan Hu    io.fromSchedulers.wakeupVec.map(x => (x.bits.exuIdx, x)).toMap
130730cfbc0SXuan Hu  private val schdType = params.schdType
131730cfbc0SXuan Hu
132730cfbc0SXuan Hu  // Modules
133730cfbc0SXuan Hu  val dispatch2Iq: Dispatch2IqImp = wrapper.dispatch2Iq.module
134730cfbc0SXuan Hu  val issueQueues: Seq[IssueQueueImp] = wrapper.issueQueue.map(_.module)
135ff3fcdf1Sxiaofeibao-xjtu  if (params.isIntSchd) {
136ff3fcdf1Sxiaofeibao-xjtu    dispatch2Iq.io.IQValidNumVec.get := io.IQValidNumVec
137c1e19666Sxiaofeibao-xjtu    io.IQValidNumVec := MixedVecInit(issueQueues.map(_.io.validCntDeqVec))
138ff3fcdf1Sxiaofeibao-xjtu  }
139ff3fcdf1Sxiaofeibao-xjtu  else io.IQValidNumVec := 0.U.asTypeOf(io.IQValidNumVec)
140730cfbc0SXuan Hu
14156bcaed7SHaojin Tang  // valid count
14256bcaed7SHaojin Tang  dispatch2Iq.io.iqValidCnt := issueQueues.filter(_.params.StdCnt == 0).map(_.io.status.validCnt)
14356bcaed7SHaojin Tang
144730cfbc0SXuan Hu  // BusyTable Modules
145730cfbc0SXuan Hu  val intBusyTable = schdType match {
146bc7d6943SzhanglyGit    case IntScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numIntStateRead, wrapper.numIntStateWrite, IntPhyRegs, IntWB())))
147730cfbc0SXuan Hu    case _ => None
148730cfbc0SXuan Hu  }
149730cfbc0SXuan Hu
150730cfbc0SXuan Hu  val vfBusyTable = schdType match {
151bc7d6943SzhanglyGit    case VfScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numVfStateRead, wrapper.numVfStateWrite, VfPhyRegs, VfWB())))
152730cfbc0SXuan Hu    case _ => None
153730cfbc0SXuan Hu  }
154730cfbc0SXuan Hu
155730cfbc0SXuan Hu  dispatch2Iq.io match { case dp2iq =>
156730cfbc0SXuan Hu    dp2iq.redirect <> io.fromCtrlBlock.flush
157730cfbc0SXuan Hu    dp2iq.in <> io.fromDispatch.uops
158730cfbc0SXuan Hu    dp2iq.readIntState.foreach(_ <> intBusyTable.get.io.read)
159730cfbc0SXuan Hu    dp2iq.readVfState.foreach(_ <> vfBusyTable.get.io.read)
160730cfbc0SXuan Hu  }
161730cfbc0SXuan Hu
162730cfbc0SXuan Hu  intBusyTable match {
163730cfbc0SXuan Hu    case Some(bt) =>
164730cfbc0SXuan Hu      bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) =>
165730cfbc0SXuan Hu        btAllocPregs.valid := dpAllocPregs.isInt
166730cfbc0SXuan Hu        btAllocPregs.bits := dpAllocPregs.preg
167730cfbc0SXuan Hu      }
168730cfbc0SXuan Hu      bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) =>
169730cfbc0SXuan Hu        wb.valid := io.intWriteBack(i).wen && io.intWriteBack(i).intWen
170730cfbc0SXuan Hu        wb.bits := io.intWriteBack(i).addr
171730cfbc0SXuan Hu      }
172bc7d6943SzhanglyGit      bt.io.wakeUp := io.fromSchedulers.wakeupVec
173bc7d6943SzhanglyGit      bt.io.cancel := io.fromDataPath.cancelToBusyTable
17413551487SzhanglyGit      bt.io.ldCancel := io.ldCancel
175730cfbc0SXuan Hu    case None =>
176730cfbc0SXuan Hu  }
177730cfbc0SXuan Hu
178730cfbc0SXuan Hu  vfBusyTable match {
179730cfbc0SXuan Hu    case Some(bt) =>
180730cfbc0SXuan Hu      bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) =>
181730cfbc0SXuan Hu        btAllocPregs.valid := dpAllocPregs.isFp
182730cfbc0SXuan Hu        btAllocPregs.bits := dpAllocPregs.preg
183730cfbc0SXuan Hu      }
184730cfbc0SXuan Hu      bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) =>
185730cfbc0SXuan Hu        wb.valid := io.vfWriteBack(i).wen && (io.vfWriteBack(i).fpWen || io.vfWriteBack(i).vecWen)
186730cfbc0SXuan Hu        wb.bits := io.vfWriteBack(i).addr
187730cfbc0SXuan Hu      }
188bc7d6943SzhanglyGit      bt.io.wakeUp := io.fromSchedulers.wakeupVec
189bc7d6943SzhanglyGit      bt.io.cancel := io.fromDataPath.cancelToBusyTable
19013551487SzhanglyGit      bt.io.ldCancel := io.ldCancel
191730cfbc0SXuan Hu    case None =>
192730cfbc0SXuan Hu  }
193730cfbc0SXuan Hu
194f39a61a1SzhanglyGit  val wakeupFromIntWBVec = Wire(params.genIntWBWakeUpSinkValidBundle)
195f39a61a1SzhanglyGit  val wakeupFromVfWBVec = Wire(params.genVfWBWakeUpSinkValidBundle)
196f39a61a1SzhanglyGit
197f39a61a1SzhanglyGit  wakeupFromIntWBVec.zip(io.intWriteBack).foreach { case (sink, source) =>
198f39a61a1SzhanglyGit    sink.valid := source.wen
199f39a61a1SzhanglyGit    sink.bits.rfWen := source.intWen
200f39a61a1SzhanglyGit    sink.bits.fpWen := source.fpWen
201f39a61a1SzhanglyGit    sink.bits.vecWen := source.vecWen
202f39a61a1SzhanglyGit    sink.bits.pdest := source.addr
203730cfbc0SXuan Hu  }
204f39a61a1SzhanglyGit
205f39a61a1SzhanglyGit  wakeupFromVfWBVec.zip(io.vfWriteBack).foreach { case (sink, source) =>
206730cfbc0SXuan Hu    sink.valid := source.wen
207730cfbc0SXuan Hu    sink.bits.rfWen := source.intWen
208730cfbc0SXuan Hu    sink.bits.fpWen := source.fpWen
209730cfbc0SXuan Hu    sink.bits.vecWen := source.vecWen
210730cfbc0SXuan Hu    sink.bits.pdest := source.addr
211730cfbc0SXuan Hu  }
212730cfbc0SXuan Hu
213bf35baadSXuan Hu  // Connect bundles having the same wakeup source
21459ef6009Sxiaofeibao-xjtu  issueQueues.zipWithIndex.foreach { case(iq, i) =>
215bf35baadSXuan Hu    iq.io.wakeupFromIQ.foreach { wakeUp =>
2160c7ebb58Sxiaofeibao-xjtu      val wakeUpIn = iqWakeUpInMap(wakeUp.bits.exuIdx)
2170c7ebb58Sxiaofeibao-xjtu      val exuIdx = wakeUp.bits.exuIdx
2180c7ebb58Sxiaofeibao-xjtu      println(s"[Backend] Connect wakeup exuIdx ${exuIdx}")
2190c7ebb58Sxiaofeibao-xjtu      connectSamePort(wakeUp,wakeUpIn)
2200c7ebb58Sxiaofeibao-xjtu      backendParams.connectWakeup(exuIdx)
2210c7ebb58Sxiaofeibao-xjtu      if (backendParams.isCopyPdest(exuIdx)) {
2220c7ebb58Sxiaofeibao-xjtu        println(s"[Backend] exuIdx ${exuIdx} use pdestCopy ${backendParams.getCopyPdestIndex(exuIdx)}")
2230c7ebb58Sxiaofeibao-xjtu        wakeUp.bits.pdest := wakeUpIn.bits.pdestCopy.get(backendParams.getCopyPdestIndex(exuIdx))
2244c5a0d77Sxiaofeibao-xjtu        if (wakeUpIn.bits.rfWenCopy.nonEmpty) wakeUp.bits.rfWen := wakeUpIn.bits.rfWenCopy.get(backendParams.getCopyPdestIndex(exuIdx))
2254c5a0d77Sxiaofeibao-xjtu        if (wakeUpIn.bits.fpWenCopy.nonEmpty) wakeUp.bits.fpWen := wakeUpIn.bits.fpWenCopy.get(backendParams.getCopyPdestIndex(exuIdx))
2264c5a0d77Sxiaofeibao-xjtu        if (wakeUpIn.bits.vecWenCopy.nonEmpty) wakeUp.bits.vecWen := wakeUpIn.bits.vecWenCopy.get(backendParams.getCopyPdestIndex(exuIdx))
2274c5a0d77Sxiaofeibao-xjtu        if (wakeUpIn.bits.loadDependencyCopy.nonEmpty) wakeUp.bits.loadDependency := wakeUpIn.bits.loadDependencyCopy.get(backendParams.getCopyPdestIndex(exuIdx))
2280c7ebb58Sxiaofeibao-xjtu      }
22960912d84Sxiaofeibao-xjtu      if (iq.params.numIntSrc == 0) wakeUp.bits.rfWen := false.B
230b67f36d0Sxiaofeibao-xjtu      if (iq.params.numVfSrc == 0)  wakeUp.bits.fpWen := false.B
23160912d84Sxiaofeibao-xjtu      if (iq.params.numVfSrc == 0)  wakeUp.bits.vecWen := false.B
232bf35baadSXuan Hu    }
233ea46c302SXuan Hu    iq.io.og0Cancel := io.fromDataPath.og0Cancel
234ea46c302SXuan Hu    iq.io.og1Cancel := io.fromDataPath.og1Cancel
2350f55a0d3SHaojin Tang    iq.io.ldCancel := io.ldCancel
236bf35baadSXuan Hu  }
237bf35baadSXuan Hu
238*b6279fc6SZiyue Zhang  // connect the vl writeback informatino to the issue queues
239*b6279fc6SZiyue Zhang  issueQueues.zipWithIndex.foreach { case(iq, i) =>
240*b6279fc6SZiyue Zhang    iq.io.vlIsVlmax := io.vlWriteBack.vlIsVlmax
241*b6279fc6SZiyue Zhang    iq.io.vlIsZero := io.vlWriteBack.vlIsZero
242*b6279fc6SZiyue Zhang  }
243*b6279fc6SZiyue Zhang
244c0be7f33SXuan Hu  private val iqWakeUpOutMap: Map[Int, ValidIO[IssueQueueIQWakeUpBundle]] =
245bf35baadSXuan Hu    issueQueues.flatMap(_.io.wakeupToIQ)
246c0be7f33SXuan Hu      .map(x => (x.bits.exuIdx, x))
247bf35baadSXuan Hu      .toMap
248bf35baadSXuan Hu
249bf35baadSXuan Hu  // Connect bundles having the same wakeup source
250bf35baadSXuan Hu  io.toSchedulers.wakeupVec.foreach { wakeUp =>
251c0be7f33SXuan Hu    wakeUp := iqWakeUpOutMap(wakeUp.bits.exuIdx)
252bf35baadSXuan Hu  }
253bf35baadSXuan Hu
25459ef6009Sxiaofeibao-xjtu  io.toDataPathAfterDelay.zipWithIndex.foreach { case (toDpDy, i) =>
25559ef6009Sxiaofeibao-xjtu    toDpDy <> issueQueues(i).io.deqDelay
25659ef6009Sxiaofeibao-xjtu  }
257bf35baadSXuan Hu
258f99b81adSHaojin Tang  // Response
259f99b81adSHaojin Tang  issueQueues.zipWithIndex.foreach { case (iq, i) =>
260f99b81adSHaojin Tang    iq.io.og0Resp.zipWithIndex.foreach { case (og0Resp, j) =>
261f99b81adSHaojin Tang      og0Resp := io.fromDataPath(i)(j).og0resp
262f99b81adSHaojin Tang    }
263f99b81adSHaojin Tang    iq.io.og1Resp.zipWithIndex.foreach { case (og1Resp, j) =>
264f99b81adSHaojin Tang      og1Resp := io.fromDataPath(i)(j).og1resp
265f99b81adSHaojin Tang    }
266f99b81adSHaojin Tang    iq.io.finalIssueResp.foreach(_.zipWithIndex.foreach { case (finalIssueResp, j) =>
267670870b3SXuan Hu      if (io.loadFinalIssueResp(i).isDefinedAt(j)) {
268f99b81adSHaojin Tang        finalIssueResp := io.loadFinalIssueResp(i)(j)
269670870b3SXuan Hu      } else {
270670870b3SXuan Hu        finalIssueResp := 0.U.asTypeOf(finalIssueResp)
271670870b3SXuan Hu      }
272f99b81adSHaojin Tang    })
273e8800897SXuan Hu    iq.io.memAddrIssueResp.foreach(_.zipWithIndex.foreach { case (memAddrIssueResp, j) =>
274aa2bcc31SzhanglyGit      if (io.memAddrIssueResp(i).isDefinedAt(j)) {
275e8800897SXuan Hu        memAddrIssueResp := io.memAddrIssueResp(i)(j)
276aa2bcc31SzhanglyGit      } else {
277aa2bcc31SzhanglyGit        memAddrIssueResp := 0.U.asTypeOf(memAddrIssueResp)
278aa2bcc31SzhanglyGit      }
279e8800897SXuan Hu    })
2807e471bf8SXuan Hu    iq.io.vecLoadIssueResp.foreach(_.zipWithIndex.foreach { case (resp, deqIdx) =>
2817e471bf8SXuan Hu      resp := io.vecLoadIssueResp(i)(deqIdx)
2827e471bf8SXuan Hu    })
283f99b81adSHaojin Tang    iq.io.wbBusyTableRead := io.fromWbFuBusyTable.fuBusyTableRead(i)
284f99b81adSHaojin Tang    io.wbFuBusyTable(i) := iq.io.wbBusyTableWrite
285f99b81adSHaojin Tang  }
286f99b81adSHaojin Tang
287c0be7f33SXuan Hu  println(s"[Scheduler] io.fromSchedulers.wakeupVec: ${io.fromSchedulers.wakeupVec.map(x => backendParams.getExuName(x.bits.exuIdx))}")
288bf35baadSXuan Hu  println(s"[Scheduler] iqWakeUpInKeys: ${iqWakeUpInMap.keys}")
289bf35baadSXuan Hu
290bf35baadSXuan Hu  println(s"[Scheduler] iqWakeUpOutKeys: ${iqWakeUpOutMap.keys}")
291c0be7f33SXuan Hu  println(s"[Scheduler] io.toSchedulers.wakeupVec: ${io.toSchedulers.wakeupVec.map(x => backendParams.getExuName(x.bits.exuIdx))}")
292730cfbc0SXuan Hu}
293730cfbc0SXuan Hu
294730cfbc0SXuan Huclass SchedulerArithImp(override val wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters)
295730cfbc0SXuan Hu  extends SchedulerImpBase(wrapper)
296730cfbc0SXuan Hu    with HasXSParameter
297730cfbc0SXuan Hu{
2982e0a7dc5Sfdy//  dontTouch(io.vfWbFuBusyTable)
299730cfbc0SXuan Hu  println(s"[SchedulerArithImp] " +
300730cfbc0SXuan Hu    s"has intBusyTable: ${intBusyTable.nonEmpty}, " +
301730cfbc0SXuan Hu    s"has vfBusyTable: ${vfBusyTable.nonEmpty}")
302730cfbc0SXuan Hu
303730cfbc0SXuan Hu  issueQueues.zipWithIndex.foreach { case (iq, i) =>
304730cfbc0SXuan Hu    iq.io.flush <> io.fromCtrlBlock.flush
305730cfbc0SXuan Hu    iq.io.enq <> dispatch2Iq.io.out(i)
306f39a61a1SzhanglyGit    val intWBIQ = params.schdType match {
307f39a61a1SzhanglyGit      case IntScheduler() => wakeupFromIntWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromIntWBPort.keys.toSeq.contains(x._2)).map(_._1)
308f39a61a1SzhanglyGit      case VfScheduler() => wakeupFromVfWBVec
309596af5d2SHaojin Tang      case _ => null
310f39a61a1SzhanglyGit    }
311f39a61a1SzhanglyGit    iq.io.wakeupFromWB.zip(intWBIQ).foreach{ case (sink, source) => sink := source}
312730cfbc0SXuan Hu  }
313730cfbc0SXuan Hu}
314730cfbc0SXuan Hu
315f99b81adSHaojin Tang// FIXME: Vector mem instructions may not be handled properly!
316730cfbc0SXuan Huclass SchedulerMemImp(override val wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters)
317730cfbc0SXuan Hu  extends SchedulerImpBase(wrapper)
318730cfbc0SXuan Hu    with HasXSParameter
319730cfbc0SXuan Hu{
320730cfbc0SXuan Hu  println(s"[SchedulerMemImp] " +
321730cfbc0SXuan Hu    s"has intBusyTable: ${intBusyTable.nonEmpty}, " +
322730cfbc0SXuan Hu    s"has vfBusyTable: ${vfBusyTable.nonEmpty}")
323730cfbc0SXuan Hu
324559c1710SHaojin Tang  val memAddrIQs = issueQueues.filter(_.params.isMemAddrIQ)
325e07131b2Ssinsanction  val stAddrIQs = issueQueues.filter(iq => iq.params.StaCnt > 0) // included in memAddrIQs
326e07131b2Ssinsanction  val ldAddrIQs = issueQueues.filter(iq => iq.params.LduCnt > 0)
327e07131b2Ssinsanction  val stDataIQs = issueQueues.filter(iq => iq.params.StdCnt > 0)
328559c1710SHaojin Tang  val vecMemIQs = issueQueues.filter(_.params.isVecMemIQ)
329559c1710SHaojin Tang  val (hyuIQs, hyuIQIdxs) = issueQueues.zipWithIndex.filter(_._1.params.HyuCnt > 0).unzip
330499caf4cSXuan Hu
331499caf4cSXuan Hu  println(s"[SchedulerMemImp] memAddrIQs.size: ${memAddrIQs.size}, enq.size: ${memAddrIQs.map(_.io.enq.size).sum}")
332499caf4cSXuan Hu  println(s"[SchedulerMemImp] stAddrIQs.size:  ${stAddrIQs.size }, enq.size: ${stAddrIQs.map(_.io.enq.size).sum}")
333499caf4cSXuan Hu  println(s"[SchedulerMemImp] ldAddrIQs.size:  ${ldAddrIQs.size }, enq.size: ${ldAddrIQs.map(_.io.enq.size).sum}")
334499caf4cSXuan Hu  println(s"[SchedulerMemImp] stDataIQs.size:  ${stDataIQs.size }, enq.size: ${stDataIQs.map(_.io.enq.size).sum}")
335499caf4cSXuan Hu  println(s"[SchedulerMemImp] hyuIQs.size:     ${hyuIQs.size    }, enq.size: ${hyuIQs.map(_.io.enq.size).sum}")
336730cfbc0SXuan Hu  require(memAddrIQs.nonEmpty && stDataIQs.nonEmpty)
337730cfbc0SXuan Hu
338853cd2d8SHaojin Tang  io.toMem.get.loadFastMatch := 0.U.asTypeOf(io.toMem.get.loadFastMatch) // TODO: is still needed?
339853cd2d8SHaojin Tang
340fc45ed13SXuan Hu  private val loadWakeUp = issueQueues.filter(_.params.LdExuCnt > 0).map(_.asInstanceOf[IssueQueueMemAddrImp].io.memIO.get.loadWakeUp).flatten
341596af5d2SHaojin Tang  require(loadWakeUp.length == io.fromMem.get.wakeup.length)
342596af5d2SHaojin Tang  loadWakeUp.zip(io.fromMem.get.wakeup).foreach(x => x._1 := x._2)
343596af5d2SHaojin Tang
344730cfbc0SXuan Hu  memAddrIQs.zipWithIndex.foreach { case (iq, i) =>
345730cfbc0SXuan Hu    iq.io.flush <> io.fromCtrlBlock.flush
346730cfbc0SXuan Hu    iq.io.enq <> dispatch2Iq.io.out(i)
347f39a61a1SzhanglyGit    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}
348730cfbc0SXuan Hu  }
349730cfbc0SXuan Hu
350ecfc6f16SXuan Hu  ldAddrIQs.zipWithIndex.foreach {
351ecfc6f16SXuan Hu    case (imp: IssueQueueMemAddrImp, i) =>
352ecfc6f16SXuan Hu      imp.io.memIO.get.feedbackIO.head := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO.head)
353c14e89f4SHaojin Tang      imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr
354de784418SXuan Hu      imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
3557b753bebSXuan Hu    case _ =>
3567b753bebSXuan Hu  }
3577b753bebSXuan Hu
358ecfc6f16SXuan Hu  stAddrIQs.zipWithIndex.foreach {
359ecfc6f16SXuan Hu    case (imp: IssueQueueMemAddrImp, i) =>
360ecfc6f16SXuan Hu      imp.io.memIO.get.feedbackIO.head := io.fromMem.get.staFeedback(i)
361c14e89f4SHaojin Tang      imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr
362c14e89f4SHaojin Tang      imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
3637b753bebSXuan Hu    case _ =>
3647b753bebSXuan Hu  }
365730cfbc0SXuan Hu
366559c1710SHaojin Tang  hyuIQs.zip(hyuIQIdxs).foreach {
367559c1710SHaojin Tang    case (imp: IssueQueueMemAddrImp, idx) =>
368670870b3SXuan Hu      imp.io.memIO.get.feedbackIO.head := io.fromMem.get.hyuFeedback.head
369670870b3SXuan Hu      imp.io.memIO.get.feedbackIO(1) := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO(1))
3708f1fa9b1Ssfencevma      imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr
3718f1fa9b1Ssfencevma      imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
372559c1710SHaojin Tang      // TODO: refactor ditry code
373559c1710SHaojin Tang      imp.io.deqDelay(1).ready := false.B
374559c1710SHaojin Tang      io.toDataPathAfterDelay(idx)(1).valid := false.B
375559c1710SHaojin Tang      io.toDataPathAfterDelay(idx)(1).bits := 0.U.asTypeOf(io.toDataPathAfterDelay(idx)(1).bits)
3768f1fa9b1Ssfencevma    case _ =>
3778f1fa9b1Ssfencevma  }
3788f1fa9b1Ssfencevma
379e62b6911SXuan Hu  private val staIdxSeq = (stAddrIQs).map(iq => iq.params.idxInSchBlk)
380e62b6911SXuan Hu  private val hyaIdxSeq = (hyuIQs).map(iq => iq.params.idxInSchBlk)
381e62b6911SXuan Hu
382e62b6911SXuan Hu  println(s"[SchedulerMemImp] sta iq idx in memSchdBlock: $staIdxSeq")
383e62b6911SXuan Hu  println(s"[SchedulerMemImp] hya iq idx in memSchdBlock: $hyaIdxSeq")
384e62b6911SXuan Hu
385e62b6911SXuan Hu  private val staEnqs = stAddrIQs.map(_.io.enq).flatten
386e62b6911SXuan Hu  private val stdEnqs = stDataIQs.map(_.io.enq).flatten.take(staEnqs.size)
387e62b6911SXuan Hu  private val hyaEnqs = hyuIQs.map(_.io.enq).flatten
388e62b6911SXuan Hu  private val hydEnqs = stDataIQs.map(_.io.enq).flatten.drop(staEnqs.size)
389e62b6911SXuan Hu
390e62b6911SXuan Hu  require(staEnqs.size == stdEnqs.size, s"number of enq ports of store address IQs(${staEnqs.size}) " +
391e62b6911SXuan Hu  s"should be equal to number of enq ports of store data IQs(${stdEnqs.size})")
392e62b6911SXuan Hu
393e62b6911SXuan Hu  require(hyaEnqs.size == hydEnqs.size, s"number of enq ports of hybrid address IQs(${hyaEnqs.size}) " +
394e62b6911SXuan Hu  s"should be equal to number of enq ports of hybrid data IQs(${hydEnqs.size})")
3959b258a00Sxgkiri
3960438e8f4SHaojin Tang  val d2IqStaOut = dispatch2Iq.io.out.zipWithIndex.filter(staIdxSeq contains _._2).unzip._1.flatten
3970438e8f4SHaojin Tang  d2IqStaOut.zip(staEnqs).zip(stdEnqs).foreach{ case((dp, staIQ), stdIQ) =>
398730cfbc0SXuan Hu    val isAllReady = staIQ.ready && stdIQ.ready
399e62b6911SXuan Hu    dp.ready := isAllReady
400e62b6911SXuan Hu    staIQ.valid := dp.valid && isAllReady
4010438e8f4SHaojin Tang    stdIQ.valid := dp.valid && isAllReady && FuType.FuTypeOrR(dp.bits.fuType, FuType.stu, FuType.mou)
4029b258a00Sxgkiri  }
403730cfbc0SXuan Hu
4040438e8f4SHaojin Tang  val d2IqHyaOut = dispatch2Iq.io.out.zipWithIndex.filter(hyaIdxSeq contains _._2).unzip._1.flatten
4050438e8f4SHaojin Tang  d2IqHyaOut.zip(hyaEnqs).zip(hydEnqs).foreach{ case((dp, hyaIQ), hydIQ) =>
406e62b6911SXuan Hu    val isAllReady = hyaIQ.ready && hydIQ.ready
407e62b6911SXuan Hu    dp.ready := isAllReady
408e62b6911SXuan Hu    hyaIQ.valid := dp.valid && isAllReady
40956bceacbSHaojin Tang    hydIQ.valid := dp.valid && isAllReady && FuType.FuTypeOrR(dp.bits.fuType, FuType.stu, FuType.mou)
410e62b6911SXuan Hu  }
411730cfbc0SXuan Hu
412e62b6911SXuan Hu  stDataIQs.zipWithIndex.foreach { case (iq, i) =>
413e62b6911SXuan Hu    iq.io.flush <> io.fromCtrlBlock.flush
414f39a61a1SzhanglyGit    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}
415e62b6911SXuan Hu  }
416e62b6911SXuan Hu
417e62b6911SXuan Hu  (stdEnqs ++ hydEnqs).zip(staEnqs ++ hyaEnqs).zipWithIndex.foreach { case ((stdIQEnq, staIQEnq), i) =>
418730cfbc0SXuan Hu    stdIQEnq.bits  := staIQEnq.bits
419730cfbc0SXuan Hu    // Store data reuses store addr src(1) in dispatch2iq
420e62b6911SXuan Hu    // [dispatch2iq] --src*------src*(0)--> [staIQ|hyaIQ]
421730cfbc0SXuan Hu    //                       \
422730cfbc0SXuan Hu    //                        ---src*(1)--> [stdIQ]
423730cfbc0SXuan Hu    // Since the src(1) of sta is easier to get, stdIQEnq.bits.src*(0) is assigned to staIQEnq.bits.src*(1)
424730cfbc0SXuan Hu    // instead of dispatch2Iq.io.out(x).bits.src*(1)
42597b279b9SXuan Hu    val stdIdx = 1
4262d270511Ssinsanction    stdIQEnq.bits.srcState(0) := staIQEnq.bits.srcState(stdIdx)
42713551487SzhanglyGit    stdIQEnq.bits.srcLoadDependency(0) := staIQEnq.bits.srcLoadDependency(1)
4282d270511Ssinsanction      stdIQEnq.bits.srcType(0) := staIQEnq.bits.srcType(stdIdx)
4292d270511Ssinsanction    stdIQEnq.bits.psrc(0) := staIQEnq.bits.psrc(stdIdx)
430730cfbc0SXuan Hu    stdIQEnq.bits.sqIdx := staIQEnq.bits.sqIdx
431730cfbc0SXuan Hu  }
432730cfbc0SXuan Hu
4332d270511Ssinsanction  vecMemIQs.foreach {
4342d270511Ssinsanction    case imp: IssueQueueVecMemImp =>
4352d270511Ssinsanction      imp.io.memIO.get.sqDeqPtr.foreach(_ := io.fromMem.get.sqDeqPtr)
4362d270511Ssinsanction      imp.io.memIO.get.lqDeqPtr.foreach(_ := io.fromMem.get.lqDeqPtr)
4371f3d1b4dSXuan Hu      // not used
438b7c799beSzhanglyGit      //imp.io.memIO.get.feedbackIO.head := io.fromMem.get.vstuFeedback.head // only vector store replay
4391f3d1b4dSXuan Hu      // maybe not used
4401f3d1b4dSXuan Hu      imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr
4411f3d1b4dSXuan Hu      imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
442f39a61a1SzhanglyGit      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}
443f39a61a1SzhanglyGit
4442d270511Ssinsanction    case _ =>
4452d270511Ssinsanction  }
446b7c799beSzhanglyGit  val vecMemFeedbackIO: Seq[MemRSFeedbackIO] = vecMemIQs.map {
447b7c799beSzhanglyGit    case imp: IssueQueueVecMemImp =>
448b7c799beSzhanglyGit      imp.io.memIO.get.feedbackIO
449b7c799beSzhanglyGit  }.flatten
450b7c799beSzhanglyGit  assert(vecMemFeedbackIO.size == io.fromMem.get.vstuFeedback.size, "vecMemFeedback size dont match!")
451b7c799beSzhanglyGit  vecMemFeedbackIO.zip(io.fromMem.get.vstuFeedback).foreach{
452b7c799beSzhanglyGit    case (sink, source) =>
453b7c799beSzhanglyGit      sink := source
454b7c799beSzhanglyGit  }
4552d270511Ssinsanction
456730cfbc0SXuan Hu  val lsqEnqCtrl = Module(new LsqEnqCtrl)
457730cfbc0SXuan Hu
458730cfbc0SXuan Hu  lsqEnqCtrl.io.redirect <> io.fromCtrlBlock.flush
459730cfbc0SXuan Hu  lsqEnqCtrl.io.enq <> dispatch2Iq.io.enqLsqIO.get
460730cfbc0SXuan Hu  lsqEnqCtrl.io.lcommit := io.fromMem.get.lcommit
461730cfbc0SXuan Hu  lsqEnqCtrl.io.scommit := io.fromMem.get.scommit
462730cfbc0SXuan Hu  lsqEnqCtrl.io.lqCancelCnt := io.fromMem.get.lqCancelCnt
463730cfbc0SXuan Hu  lsqEnqCtrl.io.sqCancelCnt := io.fromMem.get.sqCancelCnt
464f3a9fb05SAnzo  dispatch2Iq.io.lqFreeCount.get := lsqEnqCtrl.io.lqFreeCount
465f3a9fb05SAnzo  dispatch2Iq.io.sqFreeCount.get := lsqEnqCtrl.io.sqFreeCount
466730cfbc0SXuan Hu  io.memIO.get.lsqEnqIO <> lsqEnqCtrl.io.enqLsq
4677e471bf8SXuan Hu
4687e471bf8SXuan Hu  dontTouch(io.vecLoadIssueResp)
469730cfbc0SXuan Hu}
470