xref: /XiangShan/src/main/scala/xiangshan/backend/issue/Scheduler.scala (revision f8b278aa7f5c894b2f00114935bd4d8edb8a885c)
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}
7e1a85e9fSchengguanghuiimport utils.{HasPerfEvents, OptionWrapper}
8730cfbc0SXuan Huimport xiangshan._
910fe9778SXuan Huimport xiangshan.backend.Bundles._
10c720aa49Ssinsanctionimport xiangshan.backend.datapath.DataConfig._
11c720aa49Ssinsanctionimport xiangshan.backend.datapath.WbConfig._
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}
16c720aa49Ssinsanctionimport xiangshan.backend.datapath.WbConfig.V0WB
17c720aa49Ssinsanctionimport xiangshan.backend.regfile.VlPregParams
18730cfbc0SXuan Hu
19730cfbc0SXuan Husealed trait SchedulerType
20730cfbc0SXuan Hu
21730cfbc0SXuan Hucase class IntScheduler() extends SchedulerType
2260f0c5aeSxiaofeibaocase class FpScheduler() extends SchedulerType
23730cfbc0SXuan Hucase class MemScheduler() extends SchedulerType
24730cfbc0SXuan Hucase class VfScheduler() extends SchedulerType
25730cfbc0SXuan Hucase class NoScheduler() extends SchedulerType
26730cfbc0SXuan Hu
27730cfbc0SXuan Huclass Scheduler(val params: SchdBlockParams)(implicit p: Parameters) extends LazyModule with HasXSParameter {
281ca4a39dSXuan Hu  override def shouldBeInlined: Boolean = false
291ca4a39dSXuan Hu
3039c59369SXuan Hu  val numIntStateWrite = backendParams.numPregWb(IntData())
3160f0c5aeSxiaofeibao  val numFpStateWrite = backendParams.numPregWb(FpData())
3239c59369SXuan Hu  val numVfStateWrite = backendParams.numPregWb(VecData())
3307b5cc60Sxiaofeibao  val numV0StateWrite = backendParams.numPregWb(V0Data())
3407b5cc60Sxiaofeibao  val numVlStateWrite = backendParams.numPregWb(VlData())
35730cfbc0SXuan Hu
36730cfbc0SXuan Hu  val dispatch2Iq = LazyModule(new Dispatch2Iq(params))
37730cfbc0SXuan Hu  val issueQueue = params.issueBlockParams.map(x => LazyModule(new IssueQueue(x).suggestName(x.getIQName)))
38730cfbc0SXuan Hu
3983ba63b3SXuan Hu  lazy val module: SchedulerImpBase = params.schdType match {
40730cfbc0SXuan Hu    case IntScheduler() => new SchedulerArithImp(this)(params, p)
4160f0c5aeSxiaofeibao    case FpScheduler()  => new SchedulerArithImp(this)(params, p)
42730cfbc0SXuan Hu    case MemScheduler() => new SchedulerMemImp(this)(params, p)
43730cfbc0SXuan Hu    case VfScheduler() => new SchedulerArithImp(this)(params, p)
44730cfbc0SXuan Hu    case _ => null
45730cfbc0SXuan Hu  }
46730cfbc0SXuan Hu}
47730cfbc0SXuan Hu
487f8233d5SHaojin Tangclass SchedulerIO()(implicit params: SchdBlockParams, p: Parameters) extends XSBundle {
4968d13085SXuan Hu  // params alias
507f8233d5SHaojin Tang  private val LoadQueueSize = VirtualLoadQueueSize
5168d13085SXuan Hu
52730cfbc0SXuan Hu  val fromTop = new Bundle {
53730cfbc0SXuan Hu    val hartId = Input(UInt(8.W))
54730cfbc0SXuan Hu  }
552e0a7dc5Sfdy  val fromWbFuBusyTable = new Bundle{
562e0a7dc5Sfdy    val fuBusyTableRead = MixedVec(params.issueBlockParams.map(x => Input(x.genWbFuBusyTableReadBundle)))
572e0a7dc5Sfdy  }
58dd970561SzhanglyGit  val wbFuBusyTable = MixedVec(params.issueBlockParams.map(x => Output(x.genWbFuBusyTableWriteBundle)))
5982674533Sxiaofeibao  val intIQValidNumVec = Output(MixedVec(backendParams.genIntIQValidNumBundle))
6082674533Sxiaofeibao  val fpIQValidNumVec = Output(MixedVec(backendParams.genFpIQValidNumBundle))
61dd970561SzhanglyGit
62730cfbc0SXuan Hu  val fromCtrlBlock = new Bundle {
63730cfbc0SXuan Hu    val flush = Flipped(ValidIO(new Redirect))
64730cfbc0SXuan Hu  }
65730cfbc0SXuan Hu  val fromDispatch = new Bundle {
66730cfbc0SXuan Hu    val allocPregs = Vec(RenameWidth, Input(new ResetPregStateReq))
67730cfbc0SXuan Hu    val uops =  Vec(params.numUopIn, Flipped(DecoupledIO(new DynInst)))
68730cfbc0SXuan Hu  }
6939c59369SXuan Hu  val intWriteBack = MixedVec(Vec(backendParams.numPregWb(IntData()),
70730cfbc0SXuan Hu    new RfWritePortWithConfig(backendParams.intPregParams.dataCfg, backendParams.intPregParams.addrWidth)))
7160f0c5aeSxiaofeibao  val fpWriteBack = MixedVec(Vec(backendParams.numPregWb(FpData()),
7260f0c5aeSxiaofeibao    new RfWritePortWithConfig(backendParams.fpPregParams.dataCfg, backendParams.fpPregParams.addrWidth)))
7339c59369SXuan Hu  val vfWriteBack = MixedVec(Vec(backendParams.numPregWb(VecData()),
74730cfbc0SXuan Hu    new RfWritePortWithConfig(backendParams.vfPregParams.dataCfg, backendParams.vfPregParams.addrWidth)))
7507b5cc60Sxiaofeibao  val v0WriteBack = MixedVec(Vec(backendParams.numPregWb(V0Data()),
76c720aa49Ssinsanction    new RfWritePortWithConfig(backendParams.v0PregParams.dataCfg, backendParams.v0PregParams.addrWidth)))
7707b5cc60Sxiaofeibao  val vlWriteBack = MixedVec(Vec(backendParams.numPregWb(VlData()),
78c720aa49Ssinsanction    new RfWritePortWithConfig(backendParams.vlPregParams.dataCfg, backendParams.vlPregParams.addrWidth)))
7959ef6009Sxiaofeibao-xjtu  val toDataPathAfterDelay: MixedVec[MixedVec[DecoupledIO[IssueQueueIssueBundle]]] = MixedVec(params.issueBlockParams.map(_.genIssueDecoupledBundle))
80730cfbc0SXuan Hu
81c720aa49Ssinsanction  val vlWriteBackInfo = new Bundle {
82b6279fc6SZiyue Zhang    val vlIsZero = Input(Bool())
83b6279fc6SZiyue Zhang    val vlIsVlmax = Input(Bool())
84b6279fc6SZiyue Zhang  }
85b6279fc6SZiyue Zhang
86bf35baadSXuan Hu  val fromSchedulers = new Bundle {
87c0be7f33SXuan Hu    val wakeupVec: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = Flipped(params.genIQWakeUpInValidBundle)
88bf35baadSXuan Hu  }
89bf35baadSXuan Hu
90bf35baadSXuan Hu  val toSchedulers = new Bundle {
91c0be7f33SXuan Hu    val wakeupVec: MixedVec[ValidIO[IssueQueueIQWakeUpBundle]] = params.genIQWakeUpOutValidBundle
92bf35baadSXuan Hu  }
93bf35baadSXuan Hu
94c0be7f33SXuan Hu  val fromDataPath = new Bundle {
9510fe9778SXuan Hu    val resp: MixedVec[MixedVec[OGRespBundle]] = MixedVec(params.issueBlockParams.map(x => Flipped(x.genOGRespBundle)))
96be9ff987Ssinsanction    val og0Cancel = Input(ExuVec())
97ea46c302SXuan Hu    // Todo: remove this after no cancel signal from og1
98be9ff987Ssinsanction    val og1Cancel = Input(ExuVec())
99*f8b278aaSsinsanction    // replace RCIdx to Wakeup Queue
100*f8b278aaSsinsanction    val replaceRCIdx = OptionWrapper(params.needWriteRegCache, Vec(params.numWriteRegCache, Input(UInt(RegCacheIdxWidth.W))))
101c0be7f33SXuan Hu    // just be compatible to old code
102c0be7f33SXuan Hu    def apply(i: Int)(j: Int) = resp(i)(j)
103c0be7f33SXuan Hu  }
104c0be7f33SXuan Hu
1058a66c02cSXuan Hu  val loadFinalIssueResp = MixedVec(params.issueBlockParams.map(x => MixedVec(Vec(x.LdExuCnt, Flipped(ValidIO(new IssueQueueDeqRespBundle()(p, x)))))))
1068a66c02cSXuan Hu  val memAddrIssueResp = MixedVec(params.issueBlockParams.map(x => MixedVec(Vec(x.LdExuCnt, Flipped(ValidIO(new IssueQueueDeqRespBundle()(p, x)))))))
1077e471bf8SXuan Hu  val vecLoadIssueResp = MixedVec(params.issueBlockParams.map(x => MixedVec(Vec(x.VlduCnt, Flipped(ValidIO(new IssueQueueDeqRespBundle()(p, x)))))))
1080f55a0d3SHaojin Tang
1096810d1e8Ssfencevma  val ldCancel = Vec(backendParams.LduCnt + backendParams.HyuCnt, Flipped(new LoadCancelIO))
110c0be7f33SXuan Hu
111730cfbc0SXuan Hu  val memIO = if (params.isMemSchd) Some(new Bundle {
112730cfbc0SXuan Hu    val lsqEnqIO = Flipped(new LsqEnqIO)
113730cfbc0SXuan Hu  }) else None
114730cfbc0SXuan Hu  val fromMem = if (params.isMemSchd) Some(new Bundle {
1157b753bebSXuan Hu    val ldaFeedback = Flipped(Vec(params.LduCnt, new MemRSFeedbackIO))
1167b753bebSXuan Hu    val staFeedback = Flipped(Vec(params.StaCnt, new MemRSFeedbackIO))
1178f1fa9b1Ssfencevma    val hyuFeedback = Flipped(Vec(params.HyuCnt, new MemRSFeedbackIO))
118fd490615Sweiding liu    val vstuFeedback = Flipped(Vec(params.VstuCnt, new MemRSFeedbackIO(isVector = true)))
119fd490615Sweiding liu    val vlduFeedback = Flipped(Vec(params.VlduCnt, new MemRSFeedbackIO(isVector = true)))
120730cfbc0SXuan Hu    val stIssuePtr = Input(new SqPtr())
121730cfbc0SXuan Hu    val lcommit = Input(UInt(log2Up(CommitWidth + 1).W))
122730cfbc0SXuan Hu    val scommit = Input(UInt(log2Ceil(EnsbufferWidth + 1).W)) // connected to `memBlock.io.sqDeq` instead of ROB
123fc45ed13SXuan Hu    val wakeup = Vec(params.LdExuCnt, Flipped(Valid(new DynInst)))
1242d270511Ssinsanction    val lqDeqPtr = Input(new LqPtr)
1252d270511Ssinsanction    val sqDeqPtr = Input(new SqPtr)
126730cfbc0SXuan Hu    // from lsq
127730cfbc0SXuan Hu    val lqCancelCnt = Input(UInt(log2Up(LoadQueueSize + 1).W))
128730cfbc0SXuan Hu    val sqCancelCnt = Input(UInt(log2Up(StoreQueueSize + 1).W))
129730cfbc0SXuan Hu    val memWaitUpdateReq = Flipped(new MemWaitUpdateReq)
130730cfbc0SXuan Hu  }) else None
131730cfbc0SXuan Hu  val toMem = if (params.isMemSchd) Some(new Bundle {
132730cfbc0SXuan Hu    val loadFastMatch = Output(Vec(params.LduCnt, new IssueQueueLoadBundle))
133730cfbc0SXuan Hu  }) else None
134c38df446SzhanglyGit  val fromOg2 = if(params.isVfSchd) Some(MixedVec(params.issueBlockParams.map(x => Flipped(x.genOG2RespBundle)))) else None
135730cfbc0SXuan Hu}
136730cfbc0SXuan Hu
137730cfbc0SXuan Huabstract class SchedulerImpBase(wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters)
138730cfbc0SXuan Hu  extends LazyModuleImp(wrapper)
139730cfbc0SXuan Hu    with HasXSParameter
140730cfbc0SXuan Hu{
141730cfbc0SXuan Hu  val io = IO(new SchedulerIO())
142730cfbc0SXuan Hu
143730cfbc0SXuan Hu  // alias
144c0be7f33SXuan Hu  private val iqWakeUpInMap: Map[Int, ValidIO[IssueQueueIQWakeUpBundle]] =
145c0be7f33SXuan Hu    io.fromSchedulers.wakeupVec.map(x => (x.bits.exuIdx, x)).toMap
146730cfbc0SXuan Hu  private val schdType = params.schdType
147730cfbc0SXuan Hu
148730cfbc0SXuan Hu  // Modules
149730cfbc0SXuan Hu  val dispatch2Iq: Dispatch2IqImp = wrapper.dispatch2Iq.module
150730cfbc0SXuan Hu  val issueQueues: Seq[IssueQueueImp] = wrapper.issueQueue.map(_.module)
15182674533Sxiaofeibao  io.intIQValidNumVec := 0.U.asTypeOf(io.intIQValidNumVec)
15282674533Sxiaofeibao  io.fpIQValidNumVec := 0.U.asTypeOf(io.fpIQValidNumVec)
153ff3fcdf1Sxiaofeibao-xjtu  if (params.isIntSchd) {
15482674533Sxiaofeibao    dispatch2Iq.io.intIQValidNumVec.get := io.intIQValidNumVec
15582674533Sxiaofeibao    io.intIQValidNumVec := MixedVecInit(issueQueues.map(_.io.validCntDeqVec))
156ff3fcdf1Sxiaofeibao-xjtu  }
15782674533Sxiaofeibao  else if (params.isFpSchd) {
15882674533Sxiaofeibao    dispatch2Iq.io.fpIQValidNumVec.get := io.fpIQValidNumVec
15982674533Sxiaofeibao    io.fpIQValidNumVec := MixedVecInit(issueQueues.map(_.io.validCntDeqVec))
16082674533Sxiaofeibao  }
161730cfbc0SXuan Hu
16256bcaed7SHaojin Tang  // valid count
16356bcaed7SHaojin Tang  dispatch2Iq.io.iqValidCnt := issueQueues.filter(_.params.StdCnt == 0).map(_.io.status.validCnt)
16456bcaed7SHaojin Tang
165730cfbc0SXuan Hu  // BusyTable Modules
166730cfbc0SXuan Hu  val intBusyTable = schdType match {
167bc7d6943SzhanglyGit    case IntScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numIntStateRead, wrapper.numIntStateWrite, IntPhyRegs, IntWB())))
168730cfbc0SXuan Hu    case _ => None
169730cfbc0SXuan Hu  }
17060f0c5aeSxiaofeibao  val fpBusyTable = schdType match {
17160f0c5aeSxiaofeibao    case FpScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numFpStateRead, wrapper.numFpStateWrite, FpPhyRegs, FpWB())))
17260f0c5aeSxiaofeibao    case _ => None
17360f0c5aeSxiaofeibao  }
174730cfbc0SXuan Hu  val vfBusyTable = schdType match {
175bc7d6943SzhanglyGit    case VfScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numVfStateRead, wrapper.numVfStateWrite, VfPhyRegs, VfWB())))
176730cfbc0SXuan Hu    case _ => None
177730cfbc0SXuan Hu  }
178c720aa49Ssinsanction  val v0BusyTable = schdType match {
179c720aa49Ssinsanction    case VfScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numV0StateRead, wrapper.numV0StateWrite, V0PhyRegs, V0WB())))
180c720aa49Ssinsanction    case _ => None
181c720aa49Ssinsanction  }
182c720aa49Ssinsanction  val vlBusyTable = schdType match {
183c720aa49Ssinsanction    case VfScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numVlStateRead, wrapper.numVlStateWrite, VlPhyRegs, VlWB())))
184c720aa49Ssinsanction    case _ => None
185c720aa49Ssinsanction  }
186730cfbc0SXuan Hu
187730cfbc0SXuan Hu  dispatch2Iq.io match { case dp2iq =>
188730cfbc0SXuan Hu    dp2iq.redirect <> io.fromCtrlBlock.flush
189730cfbc0SXuan Hu    dp2iq.in <> io.fromDispatch.uops
190730cfbc0SXuan Hu    dp2iq.readIntState.foreach(_ <> intBusyTable.get.io.read)
19160f0c5aeSxiaofeibao    dp2iq.readFpState.foreach(_ <> fpBusyTable.get.io.read)
192730cfbc0SXuan Hu    dp2iq.readVfState.foreach(_ <> vfBusyTable.get.io.read)
193c720aa49Ssinsanction    dp2iq.readV0State.foreach(_ <> v0BusyTable.get.io.read)
194c720aa49Ssinsanction    dp2iq.readVlState.foreach(_ <> vlBusyTable.get.io.read)
195730cfbc0SXuan Hu  }
196730cfbc0SXuan Hu
197730cfbc0SXuan Hu  intBusyTable match {
198730cfbc0SXuan Hu    case Some(bt) =>
199730cfbc0SXuan Hu      bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) =>
200730cfbc0SXuan Hu        btAllocPregs.valid := dpAllocPregs.isInt
201730cfbc0SXuan Hu        btAllocPregs.bits := dpAllocPregs.preg
202730cfbc0SXuan Hu      }
203730cfbc0SXuan Hu      bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) =>
204730cfbc0SXuan Hu        wb.valid := io.intWriteBack(i).wen && io.intWriteBack(i).intWen
205730cfbc0SXuan Hu        wb.bits := io.intWriteBack(i).addr
206730cfbc0SXuan Hu      }
207bc7d6943SzhanglyGit      bt.io.wakeUp := io.fromSchedulers.wakeupVec
20837080bd8Ssinsanction      bt.io.og0Cancel := io.fromDataPath.og0Cancel
20913551487SzhanglyGit      bt.io.ldCancel := io.ldCancel
210730cfbc0SXuan Hu    case None =>
211730cfbc0SXuan Hu  }
212730cfbc0SXuan Hu
21360f0c5aeSxiaofeibao  fpBusyTable match {
214730cfbc0SXuan Hu    case Some(bt) =>
215730cfbc0SXuan Hu      bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) =>
216730cfbc0SXuan Hu        btAllocPregs.valid := dpAllocPregs.isFp
217730cfbc0SXuan Hu        btAllocPregs.bits := dpAllocPregs.preg
218730cfbc0SXuan Hu      }
219730cfbc0SXuan Hu      bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) =>
22060f0c5aeSxiaofeibao        wb.valid := io.fpWriteBack(i).wen && io.fpWriteBack(i).fpWen
22160f0c5aeSxiaofeibao        wb.bits := io.fpWriteBack(i).addr
22260f0c5aeSxiaofeibao      }
22360f0c5aeSxiaofeibao      bt.io.wakeUp := io.fromSchedulers.wakeupVec
22437080bd8Ssinsanction      bt.io.og0Cancel := io.fromDataPath.og0Cancel
22560f0c5aeSxiaofeibao      bt.io.ldCancel := io.ldCancel
22660f0c5aeSxiaofeibao    case None =>
22760f0c5aeSxiaofeibao  }
22860f0c5aeSxiaofeibao
22960f0c5aeSxiaofeibao  vfBusyTable match {
23060f0c5aeSxiaofeibao    case Some(bt) =>
23160f0c5aeSxiaofeibao      bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) =>
23260f0c5aeSxiaofeibao        btAllocPregs.valid := dpAllocPregs.isVec
23360f0c5aeSxiaofeibao        btAllocPregs.bits := dpAllocPregs.preg
23460f0c5aeSxiaofeibao      }
23560f0c5aeSxiaofeibao      bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) =>
23660f0c5aeSxiaofeibao        wb.valid := io.vfWriteBack(i).wen && io.vfWriteBack(i).vecWen
237730cfbc0SXuan Hu        wb.bits := io.vfWriteBack(i).addr
238730cfbc0SXuan Hu      }
239bc7d6943SzhanglyGit      bt.io.wakeUp := io.fromSchedulers.wakeupVec
24037080bd8Ssinsanction      bt.io.og0Cancel := io.fromDataPath.og0Cancel
24113551487SzhanglyGit      bt.io.ldCancel := io.ldCancel
242730cfbc0SXuan Hu    case None =>
243730cfbc0SXuan Hu  }
244730cfbc0SXuan Hu
245c720aa49Ssinsanction  v0BusyTable match {
246c720aa49Ssinsanction    case Some(bt) =>
247c720aa49Ssinsanction      bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) =>
24829aa55c1Sxiaofeibao        btAllocPregs.valid := dpAllocPregs.isV0
249c720aa49Ssinsanction        btAllocPregs.bits := dpAllocPregs.preg
250c720aa49Ssinsanction      }
251c720aa49Ssinsanction      bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) =>
252c720aa49Ssinsanction        wb.valid := io.v0WriteBack(i).wen && io.v0WriteBack(i).v0Wen
253c720aa49Ssinsanction        wb.bits := io.v0WriteBack(i).addr
254c720aa49Ssinsanction      }
255c720aa49Ssinsanction      bt.io.wakeUp := io.fromSchedulers.wakeupVec
25637080bd8Ssinsanction      bt.io.og0Cancel := io.fromDataPath.og0Cancel
257c720aa49Ssinsanction      bt.io.ldCancel := io.ldCancel
258c720aa49Ssinsanction    case None =>
259c720aa49Ssinsanction  }
260c720aa49Ssinsanction
261c720aa49Ssinsanction  vlBusyTable match {
262c720aa49Ssinsanction    case Some(bt) =>
263c720aa49Ssinsanction      bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) =>
26429aa55c1Sxiaofeibao        btAllocPregs.valid := dpAllocPregs.isVl
265c720aa49Ssinsanction        btAllocPregs.bits := dpAllocPregs.preg
266c720aa49Ssinsanction      }
267c720aa49Ssinsanction      bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) =>
268c720aa49Ssinsanction        wb.valid := io.vlWriteBack(i).wen && io.vlWriteBack(i).vlWen
269c720aa49Ssinsanction        wb.bits := io.vlWriteBack(i).addr
270c720aa49Ssinsanction      }
271c720aa49Ssinsanction      bt.io.wakeUp := io.fromSchedulers.wakeupVec
27237080bd8Ssinsanction      bt.io.og0Cancel := io.fromDataPath.og0Cancel
273c720aa49Ssinsanction      bt.io.ldCancel := io.ldCancel
274c720aa49Ssinsanction    case None =>
275c720aa49Ssinsanction  }
276c720aa49Ssinsanction
277f39a61a1SzhanglyGit  val wakeupFromIntWBVec = Wire(params.genIntWBWakeUpSinkValidBundle)
27860f0c5aeSxiaofeibao  val wakeupFromFpWBVec = Wire(params.genFpWBWakeUpSinkValidBundle)
279f39a61a1SzhanglyGit  val wakeupFromVfWBVec = Wire(params.genVfWBWakeUpSinkValidBundle)
280c720aa49Ssinsanction  val wakeupFromV0WBVec = Wire(params.genV0WBWakeUpSinkValidBundle)
281c720aa49Ssinsanction  val wakeupFromVlWBVec = Wire(params.genVlWBWakeUpSinkValidBundle)
282f39a61a1SzhanglyGit
283f39a61a1SzhanglyGit  wakeupFromIntWBVec.zip(io.intWriteBack).foreach { case (sink, source) =>
284f39a61a1SzhanglyGit    sink.valid := source.wen
285f39a61a1SzhanglyGit    sink.bits.rfWen := source.intWen
286f39a61a1SzhanglyGit    sink.bits.fpWen := source.fpWen
287f39a61a1SzhanglyGit    sink.bits.vecWen := source.vecWen
288c720aa49Ssinsanction    sink.bits.v0Wen := source.v0Wen
289c720aa49Ssinsanction    sink.bits.vlWen := source.vlWen
290f39a61a1SzhanglyGit    sink.bits.pdest := source.addr
291730cfbc0SXuan Hu  }
292f39a61a1SzhanglyGit
29360f0c5aeSxiaofeibao  wakeupFromFpWBVec.zip(io.fpWriteBack).foreach { case (sink, source) =>
29460f0c5aeSxiaofeibao    sink.valid := source.wen
29560f0c5aeSxiaofeibao    sink.bits.rfWen := source.intWen
29660f0c5aeSxiaofeibao    sink.bits.fpWen := source.fpWen
29760f0c5aeSxiaofeibao    sink.bits.vecWen := source.vecWen
298c720aa49Ssinsanction    sink.bits.v0Wen := source.v0Wen
299c720aa49Ssinsanction    sink.bits.vlWen := source.vlWen
30060f0c5aeSxiaofeibao    sink.bits.pdest := source.addr
30160f0c5aeSxiaofeibao  }
30260f0c5aeSxiaofeibao
303f39a61a1SzhanglyGit  wakeupFromVfWBVec.zip(io.vfWriteBack).foreach { case (sink, source) =>
304730cfbc0SXuan Hu    sink.valid := source.wen
305730cfbc0SXuan Hu    sink.bits.rfWen := source.intWen
306730cfbc0SXuan Hu    sink.bits.fpWen := source.fpWen
307730cfbc0SXuan Hu    sink.bits.vecWen := source.vecWen
308c720aa49Ssinsanction    sink.bits.v0Wen := source.v0Wen
309c720aa49Ssinsanction    sink.bits.vlWen := source.vlWen
310c720aa49Ssinsanction    sink.bits.pdest := source.addr
311c720aa49Ssinsanction  }
312c720aa49Ssinsanction
313c720aa49Ssinsanction  wakeupFromV0WBVec.zip(io.v0WriteBack).foreach { case (sink, source) =>
314c720aa49Ssinsanction    sink.valid := source.wen
315c720aa49Ssinsanction    sink.bits.rfWen := source.intWen
316c720aa49Ssinsanction    sink.bits.fpWen := source.fpWen
317c720aa49Ssinsanction    sink.bits.vecWen := source.vecWen
318c720aa49Ssinsanction    sink.bits.v0Wen := source.v0Wen
319c720aa49Ssinsanction    sink.bits.vlWen := source.vlWen
320c720aa49Ssinsanction    sink.bits.pdest := source.addr
321c720aa49Ssinsanction  }
322c720aa49Ssinsanction
323c720aa49Ssinsanction  wakeupFromVlWBVec.zip(io.vlWriteBack).foreach { case (sink, source) =>
324c720aa49Ssinsanction    sink.valid := source.wen
325c720aa49Ssinsanction    sink.bits.rfWen := source.intWen
326c720aa49Ssinsanction    sink.bits.fpWen := source.fpWen
327c720aa49Ssinsanction    sink.bits.vecWen := source.vecWen
328c720aa49Ssinsanction    sink.bits.v0Wen := source.v0Wen
329c720aa49Ssinsanction    sink.bits.vlWen := source.vlWen
330730cfbc0SXuan Hu    sink.bits.pdest := source.addr
331730cfbc0SXuan Hu  }
332730cfbc0SXuan Hu
333bf35baadSXuan Hu  // Connect bundles having the same wakeup source
33459ef6009Sxiaofeibao-xjtu  issueQueues.zipWithIndex.foreach { case(iq, i) =>
335bf35baadSXuan Hu    iq.io.wakeupFromIQ.foreach { wakeUp =>
3360c7ebb58Sxiaofeibao-xjtu      val wakeUpIn = iqWakeUpInMap(wakeUp.bits.exuIdx)
3370c7ebb58Sxiaofeibao-xjtu      val exuIdx = wakeUp.bits.exuIdx
3380c7ebb58Sxiaofeibao-xjtu      println(s"[Backend] Connect wakeup exuIdx ${exuIdx}")
3390c7ebb58Sxiaofeibao-xjtu      connectSamePort(wakeUp,wakeUpIn)
3400c7ebb58Sxiaofeibao-xjtu      backendParams.connectWakeup(exuIdx)
3410c7ebb58Sxiaofeibao-xjtu      if (backendParams.isCopyPdest(exuIdx)) {
3420c7ebb58Sxiaofeibao-xjtu        println(s"[Backend] exuIdx ${exuIdx} use pdestCopy ${backendParams.getCopyPdestIndex(exuIdx)}")
3430c7ebb58Sxiaofeibao-xjtu        wakeUp.bits.pdest := wakeUpIn.bits.pdestCopy.get(backendParams.getCopyPdestIndex(exuIdx))
3444c5a0d77Sxiaofeibao-xjtu        if (wakeUpIn.bits.rfWenCopy.nonEmpty) wakeUp.bits.rfWen := wakeUpIn.bits.rfWenCopy.get(backendParams.getCopyPdestIndex(exuIdx))
3454c5a0d77Sxiaofeibao-xjtu        if (wakeUpIn.bits.fpWenCopy.nonEmpty) wakeUp.bits.fpWen := wakeUpIn.bits.fpWenCopy.get(backendParams.getCopyPdestIndex(exuIdx))
3464c5a0d77Sxiaofeibao-xjtu        if (wakeUpIn.bits.vecWenCopy.nonEmpty) wakeUp.bits.vecWen := wakeUpIn.bits.vecWenCopy.get(backendParams.getCopyPdestIndex(exuIdx))
347c720aa49Ssinsanction        if (wakeUpIn.bits.v0WenCopy.nonEmpty) wakeUp.bits.v0Wen := wakeUpIn.bits.v0WenCopy.get(backendParams.getCopyPdestIndex(exuIdx))
348c720aa49Ssinsanction        if (wakeUpIn.bits.vlWenCopy.nonEmpty) wakeUp.bits.vlWen := wakeUpIn.bits.vlWenCopy.get(backendParams.getCopyPdestIndex(exuIdx))
3494c5a0d77Sxiaofeibao-xjtu        if (wakeUpIn.bits.loadDependencyCopy.nonEmpty) wakeUp.bits.loadDependency := wakeUpIn.bits.loadDependencyCopy.get(backendParams.getCopyPdestIndex(exuIdx))
3500c7ebb58Sxiaofeibao-xjtu      }
35160912d84Sxiaofeibao-xjtu      if (iq.params.numIntSrc == 0) wakeUp.bits.rfWen := false.B
35260f0c5aeSxiaofeibao      if (iq.params.numFpSrc == 0)  wakeUp.bits.fpWen := false.B
35360912d84Sxiaofeibao-xjtu      if (iq.params.numVfSrc == 0)  wakeUp.bits.vecWen := false.B
354c720aa49Ssinsanction      if (iq.params.numV0Src == 0)  wakeUp.bits.v0Wen := false.B
355c720aa49Ssinsanction      if (iq.params.numVlSrc == 0)  wakeUp.bits.vlWen := false.B
356bf35baadSXuan Hu    }
357ea46c302SXuan Hu    iq.io.og0Cancel := io.fromDataPath.og0Cancel
358ea46c302SXuan Hu    iq.io.og1Cancel := io.fromDataPath.og1Cancel
3590f55a0d3SHaojin Tang    iq.io.ldCancel := io.ldCancel
360bf35baadSXuan Hu  }
361bf35baadSXuan Hu
362b6279fc6SZiyue Zhang  // connect the vl writeback informatino to the issue queues
363b6279fc6SZiyue Zhang  issueQueues.zipWithIndex.foreach { case(iq, i) =>
364c720aa49Ssinsanction    iq.io.vlIsVlmax := io.vlWriteBackInfo.vlIsVlmax
365c720aa49Ssinsanction    iq.io.vlIsZero := io.vlWriteBackInfo.vlIsZero
366b6279fc6SZiyue Zhang  }
367b6279fc6SZiyue Zhang
368c0be7f33SXuan Hu  private val iqWakeUpOutMap: Map[Int, ValidIO[IssueQueueIQWakeUpBundle]] =
369bf35baadSXuan Hu    issueQueues.flatMap(_.io.wakeupToIQ)
370c0be7f33SXuan Hu      .map(x => (x.bits.exuIdx, x))
371bf35baadSXuan Hu      .toMap
372bf35baadSXuan Hu
373bf35baadSXuan Hu  // Connect bundles having the same wakeup source
374bf35baadSXuan Hu  io.toSchedulers.wakeupVec.foreach { wakeUp =>
375c0be7f33SXuan Hu    wakeUp := iqWakeUpOutMap(wakeUp.bits.exuIdx)
376bf35baadSXuan Hu  }
377bf35baadSXuan Hu
37859ef6009Sxiaofeibao-xjtu  io.toDataPathAfterDelay.zipWithIndex.foreach { case (toDpDy, i) =>
37959ef6009Sxiaofeibao-xjtu    toDpDy <> issueQueues(i).io.deqDelay
38059ef6009Sxiaofeibao-xjtu  }
381bf35baadSXuan Hu
382f99b81adSHaojin Tang  // Response
383f99b81adSHaojin Tang  issueQueues.zipWithIndex.foreach { case (iq, i) =>
384f99b81adSHaojin Tang    iq.io.og0Resp.zipWithIndex.foreach { case (og0Resp, j) =>
385f99b81adSHaojin Tang      og0Resp := io.fromDataPath(i)(j).og0resp
386f99b81adSHaojin Tang    }
387f99b81adSHaojin Tang    iq.io.og1Resp.zipWithIndex.foreach { case (og1Resp, j) =>
388f99b81adSHaojin Tang      og1Resp := io.fromDataPath(i)(j).og1resp
389f99b81adSHaojin Tang    }
390f99b81adSHaojin Tang    iq.io.finalIssueResp.foreach(_.zipWithIndex.foreach { case (finalIssueResp, j) =>
391670870b3SXuan Hu      if (io.loadFinalIssueResp(i).isDefinedAt(j)) {
392f99b81adSHaojin Tang        finalIssueResp := io.loadFinalIssueResp(i)(j)
393670870b3SXuan Hu      } else {
394670870b3SXuan Hu        finalIssueResp := 0.U.asTypeOf(finalIssueResp)
395670870b3SXuan Hu      }
396f99b81adSHaojin Tang    })
397e8800897SXuan Hu    iq.io.memAddrIssueResp.foreach(_.zipWithIndex.foreach { case (memAddrIssueResp, j) =>
398aa2bcc31SzhanglyGit      if (io.memAddrIssueResp(i).isDefinedAt(j)) {
399e8800897SXuan Hu        memAddrIssueResp := io.memAddrIssueResp(i)(j)
400aa2bcc31SzhanglyGit      } else {
401aa2bcc31SzhanglyGit        memAddrIssueResp := 0.U.asTypeOf(memAddrIssueResp)
402aa2bcc31SzhanglyGit      }
403e8800897SXuan Hu    })
4047e471bf8SXuan Hu    iq.io.vecLoadIssueResp.foreach(_.zipWithIndex.foreach { case (resp, deqIdx) =>
4057e471bf8SXuan Hu      resp := io.vecLoadIssueResp(i)(deqIdx)
4067e471bf8SXuan Hu    })
407c38df446SzhanglyGit    if(params.isVfSchd) {
408c38df446SzhanglyGit      iq.io.og2Resp.get.zipWithIndex.foreach { case (og2Resp, exuIdx) =>
409c38df446SzhanglyGit        og2Resp := io.fromOg2.get(i)(exuIdx)
410c38df446SzhanglyGit      }
411c38df446SzhanglyGit    }
412f99b81adSHaojin Tang    iq.io.wbBusyTableRead := io.fromWbFuBusyTable.fuBusyTableRead(i)
413f99b81adSHaojin Tang    io.wbFuBusyTable(i) := iq.io.wbBusyTableWrite
414*f8b278aaSsinsanction    iq.io.replaceRCIdx.foreach(x => x := 0.U.asTypeOf(x))
415*f8b278aaSsinsanction  }
416*f8b278aaSsinsanction
417*f8b278aaSsinsanction  // Connect each replace RCIdx to IQ
418*f8b278aaSsinsanction  if (params.needWriteRegCache) {
419*f8b278aaSsinsanction    val iqReplaceRCIdxVec = issueQueues.filter(_.params.needWriteRegCache).flatMap{ iq =>
420*f8b278aaSsinsanction      iq.params.allExuParams.zip(iq.io.replaceRCIdx.get).filter(_._1.needWriteRegCache).map(_._2)
421*f8b278aaSsinsanction    }
422*f8b278aaSsinsanction    iqReplaceRCIdxVec.zip(io.fromDataPath.replaceRCIdx.get).foreach{ case (iq, in) =>
423*f8b278aaSsinsanction      iq := in
424*f8b278aaSsinsanction    }
425*f8b278aaSsinsanction
426*f8b278aaSsinsanction    println(s"[Scheduler] numWriteRegCache: ${params.numWriteRegCache}")
427*f8b278aaSsinsanction    println(s"[Scheduler] iqReplaceRCIdxVec: ${iqReplaceRCIdxVec.size}")
428f99b81adSHaojin Tang  }
429f99b81adSHaojin Tang
430e1a85e9fSchengguanghui  // perfEvent
431e1a85e9fSchengguanghui  val lastCycleDp2IqOutFireVec = RegNext(VecInit(dispatch2Iq.io.out.flatten.map(_.fire)))
432e1a85e9fSchengguanghui  val lastCycleIqEnqFireVec    = RegNext(VecInit(issueQueues.map(_.io.enq.map(_.fire)).flatten))
433e1a85e9fSchengguanghui  val lastCycleIqFullVec       = RegNext(VecInit(issueQueues.map(_.io.enq.head.ready)))
434e1a85e9fSchengguanghui
435e1a85e9fSchengguanghui  val issueQueueFullVecPerf = issueQueues.zip(lastCycleIqFullVec)map{ case (iq, full) => (iq.params.getIQName + s"_full", full) }
436e1a85e9fSchengguanghui  val basePerfEvents = Seq(
437e1a85e9fSchengguanghui    ("dispatch2Iq_out_fire_cnt", PopCount(lastCycleDp2IqOutFireVec)                 ),
438e1a85e9fSchengguanghui    ("issueQueue_enq_fire_cnt",  PopCount(lastCycleIqEnqFireVec)                    )
439e1a85e9fSchengguanghui  )  ++ issueQueueFullVecPerf
440e1a85e9fSchengguanghui
441c0be7f33SXuan Hu  println(s"[Scheduler] io.fromSchedulers.wakeupVec: ${io.fromSchedulers.wakeupVec.map(x => backendParams.getExuName(x.bits.exuIdx))}")
442bf35baadSXuan Hu  println(s"[Scheduler] iqWakeUpInKeys: ${iqWakeUpInMap.keys}")
443bf35baadSXuan Hu
444bf35baadSXuan Hu  println(s"[Scheduler] iqWakeUpOutKeys: ${iqWakeUpOutMap.keys}")
445c0be7f33SXuan Hu  println(s"[Scheduler] io.toSchedulers.wakeupVec: ${io.toSchedulers.wakeupVec.map(x => backendParams.getExuName(x.bits.exuIdx))}")
446730cfbc0SXuan Hu}
447730cfbc0SXuan Hu
448730cfbc0SXuan Huclass SchedulerArithImp(override val wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters)
449730cfbc0SXuan Hu  extends SchedulerImpBase(wrapper)
450730cfbc0SXuan Hu    with HasXSParameter
451e1a85e9fSchengguanghui    with HasPerfEvents
452730cfbc0SXuan Hu{
4532e0a7dc5Sfdy//  dontTouch(io.vfWbFuBusyTable)
454730cfbc0SXuan Hu  println(s"[SchedulerArithImp] " +
455730cfbc0SXuan Hu    s"has intBusyTable: ${intBusyTable.nonEmpty}, " +
456730cfbc0SXuan Hu    s"has vfBusyTable: ${vfBusyTable.nonEmpty}")
457730cfbc0SXuan Hu
458730cfbc0SXuan Hu  issueQueues.zipWithIndex.foreach { case (iq, i) =>
459730cfbc0SXuan Hu    iq.io.flush <> io.fromCtrlBlock.flush
460730cfbc0SXuan Hu    iq.io.enq <> dispatch2Iq.io.out(i)
461f39a61a1SzhanglyGit    val intWBIQ = params.schdType match {
462f39a61a1SzhanglyGit      case IntScheduler() => wakeupFromIntWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromIntWBPort.keys.toSeq.contains(x._2)).map(_._1)
46360f0c5aeSxiaofeibao      case FpScheduler() => wakeupFromFpWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromFpWBPort.keys.toSeq.contains(x._2)).map(_._1)
464c720aa49Ssinsanction      case VfScheduler() => (wakeupFromVfWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromVfWBPort.keys.toSeq.contains(x._2)).map(_._1) ++
465c720aa49Ssinsanction                             wakeupFromV0WBVec.zipWithIndex.filter(x => iq.params.needWakeupFromV0WBPort.keys.toSeq.contains(x._2)).map(_._1) ++
466c720aa49Ssinsanction                             wakeupFromVlWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromVlWBPort.keys.toSeq.contains(x._2)).map(_._1))
467596af5d2SHaojin Tang      case _ => null
468f39a61a1SzhanglyGit    }
469f39a61a1SzhanglyGit    iq.io.wakeupFromWB.zip(intWBIQ).foreach{ case (sink, source) => sink := source}
470730cfbc0SXuan Hu  }
471e1a85e9fSchengguanghui
472e1a85e9fSchengguanghui  val perfEvents = basePerfEvents
473e1a85e9fSchengguanghui  generatePerfEvent()
474730cfbc0SXuan Hu}
475730cfbc0SXuan Hu
476f99b81adSHaojin Tang// FIXME: Vector mem instructions may not be handled properly!
477730cfbc0SXuan Huclass SchedulerMemImp(override val wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters)
478730cfbc0SXuan Hu  extends SchedulerImpBase(wrapper)
479730cfbc0SXuan Hu    with HasXSParameter
480e1a85e9fSchengguanghui    with HasPerfEvents
481730cfbc0SXuan Hu{
482730cfbc0SXuan Hu  println(s"[SchedulerMemImp] " +
483730cfbc0SXuan Hu    s"has intBusyTable: ${intBusyTable.nonEmpty}, " +
484730cfbc0SXuan Hu    s"has vfBusyTable: ${vfBusyTable.nonEmpty}")
485730cfbc0SXuan Hu
486559c1710SHaojin Tang  val memAddrIQs = issueQueues.filter(_.params.isMemAddrIQ)
487e07131b2Ssinsanction  val stAddrIQs = issueQueues.filter(iq => iq.params.StaCnt > 0) // included in memAddrIQs
488e07131b2Ssinsanction  val ldAddrIQs = issueQueues.filter(iq => iq.params.LduCnt > 0)
489e07131b2Ssinsanction  val stDataIQs = issueQueues.filter(iq => iq.params.StdCnt > 0)
490559c1710SHaojin Tang  val vecMemIQs = issueQueues.filter(_.params.isVecMemIQ)
491559c1710SHaojin Tang  val (hyuIQs, hyuIQIdxs) = issueQueues.zipWithIndex.filter(_._1.params.HyuCnt > 0).unzip
492499caf4cSXuan Hu
493499caf4cSXuan Hu  println(s"[SchedulerMemImp] memAddrIQs.size: ${memAddrIQs.size}, enq.size: ${memAddrIQs.map(_.io.enq.size).sum}")
494499caf4cSXuan Hu  println(s"[SchedulerMemImp] stAddrIQs.size:  ${stAddrIQs.size }, enq.size: ${stAddrIQs.map(_.io.enq.size).sum}")
495499caf4cSXuan Hu  println(s"[SchedulerMemImp] ldAddrIQs.size:  ${ldAddrIQs.size }, enq.size: ${ldAddrIQs.map(_.io.enq.size).sum}")
496499caf4cSXuan Hu  println(s"[SchedulerMemImp] stDataIQs.size:  ${stDataIQs.size }, enq.size: ${stDataIQs.map(_.io.enq.size).sum}")
497499caf4cSXuan Hu  println(s"[SchedulerMemImp] hyuIQs.size:     ${hyuIQs.size    }, enq.size: ${hyuIQs.map(_.io.enq.size).sum}")
498730cfbc0SXuan Hu  require(memAddrIQs.nonEmpty && stDataIQs.nonEmpty)
499730cfbc0SXuan Hu
500853cd2d8SHaojin Tang  io.toMem.get.loadFastMatch := 0.U.asTypeOf(io.toMem.get.loadFastMatch) // TODO: is still needed?
501853cd2d8SHaojin Tang
502fc45ed13SXuan Hu  private val loadWakeUp = issueQueues.filter(_.params.LdExuCnt > 0).map(_.asInstanceOf[IssueQueueMemAddrImp].io.memIO.get.loadWakeUp).flatten
503596af5d2SHaojin Tang  require(loadWakeUp.length == io.fromMem.get.wakeup.length)
504596af5d2SHaojin Tang  loadWakeUp.zip(io.fromMem.get.wakeup).foreach(x => x._1 := x._2)
505596af5d2SHaojin Tang
506730cfbc0SXuan Hu  memAddrIQs.zipWithIndex.foreach { case (iq, i) =>
507730cfbc0SXuan Hu    iq.io.flush <> io.fromCtrlBlock.flush
508730cfbc0SXuan Hu    iq.io.enq <> dispatch2Iq.io.out(i)
50960f0c5aeSxiaofeibao    iq.io.wakeupFromWB.zip(
51060f0c5aeSxiaofeibao      wakeupFromIntWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromIntWBPort.keys.toSeq.contains(x._2)).map(_._1) ++
51160f0c5aeSxiaofeibao      wakeupFromFpWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromFpWBPort.keys.toSeq.contains(x._2)).map(_._1) ++
512c720aa49Ssinsanction      wakeupFromVfWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromVfWBPort.keys.toSeq.contains(x._2)).map(_._1) ++
513c720aa49Ssinsanction      wakeupFromV0WBVec.zipWithIndex.filter(x => iq.params.needWakeupFromV0WBPort.keys.toSeq.contains(x._2)).map(_._1) ++
514c720aa49Ssinsanction      wakeupFromVlWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromVlWBPort.keys.toSeq.contains(x._2)).map(_._1)
51560f0c5aeSxiaofeibao    ).foreach{ case (sink, source) => sink := source}
516730cfbc0SXuan Hu  }
517730cfbc0SXuan Hu
518ecfc6f16SXuan Hu  ldAddrIQs.zipWithIndex.foreach {
519ecfc6f16SXuan Hu    case (imp: IssueQueueMemAddrImp, i) =>
520ecfc6f16SXuan Hu      imp.io.memIO.get.feedbackIO.head := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO.head)
521c14e89f4SHaojin Tang      imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr
522de784418SXuan Hu      imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
5237b753bebSXuan Hu    case _ =>
5247b753bebSXuan Hu  }
5257b753bebSXuan Hu
526ecfc6f16SXuan Hu  stAddrIQs.zipWithIndex.foreach {
527ecfc6f16SXuan Hu    case (imp: IssueQueueMemAddrImp, i) =>
528ecfc6f16SXuan Hu      imp.io.memIO.get.feedbackIO.head := io.fromMem.get.staFeedback(i)
529c14e89f4SHaojin Tang      imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr
530c14e89f4SHaojin Tang      imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
5317b753bebSXuan Hu    case _ =>
5327b753bebSXuan Hu  }
533730cfbc0SXuan Hu
534559c1710SHaojin Tang  hyuIQs.zip(hyuIQIdxs).foreach {
535559c1710SHaojin Tang    case (imp: IssueQueueMemAddrImp, idx) =>
536670870b3SXuan Hu      imp.io.memIO.get.feedbackIO.head := io.fromMem.get.hyuFeedback.head
537670870b3SXuan Hu      imp.io.memIO.get.feedbackIO(1) := 0.U.asTypeOf(imp.io.memIO.get.feedbackIO(1))
5388f1fa9b1Ssfencevma      imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr
5398f1fa9b1Ssfencevma      imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
540559c1710SHaojin Tang      // TODO: refactor ditry code
541559c1710SHaojin Tang      imp.io.deqDelay(1).ready := false.B
542559c1710SHaojin Tang      io.toDataPathAfterDelay(idx)(1).valid := false.B
543559c1710SHaojin Tang      io.toDataPathAfterDelay(idx)(1).bits := 0.U.asTypeOf(io.toDataPathAfterDelay(idx)(1).bits)
5448f1fa9b1Ssfencevma    case _ =>
5458f1fa9b1Ssfencevma  }
5468f1fa9b1Ssfencevma
547e62b6911SXuan Hu  private val staIdxSeq = (stAddrIQs).map(iq => iq.params.idxInSchBlk)
548e62b6911SXuan Hu  private val hyaIdxSeq = (hyuIQs).map(iq => iq.params.idxInSchBlk)
549e62b6911SXuan Hu
550e62b6911SXuan Hu  println(s"[SchedulerMemImp] sta iq idx in memSchdBlock: $staIdxSeq")
551e62b6911SXuan Hu  println(s"[SchedulerMemImp] hya iq idx in memSchdBlock: $hyaIdxSeq")
552e62b6911SXuan Hu
553e62b6911SXuan Hu  private val staEnqs = stAddrIQs.map(_.io.enq).flatten
554e62b6911SXuan Hu  private val stdEnqs = stDataIQs.map(_.io.enq).flatten.take(staEnqs.size)
555e62b6911SXuan Hu  private val hyaEnqs = hyuIQs.map(_.io.enq).flatten
556e62b6911SXuan Hu  private val hydEnqs = stDataIQs.map(_.io.enq).flatten.drop(staEnqs.size)
557e62b6911SXuan Hu
558e62b6911SXuan Hu  require(staEnqs.size == stdEnqs.size, s"number of enq ports of store address IQs(${staEnqs.size}) " +
559e62b6911SXuan Hu  s"should be equal to number of enq ports of store data IQs(${stdEnqs.size})")
560e62b6911SXuan Hu
561e62b6911SXuan Hu  require(hyaEnqs.size == hydEnqs.size, s"number of enq ports of hybrid address IQs(${hyaEnqs.size}) " +
562e62b6911SXuan Hu  s"should be equal to number of enq ports of hybrid data IQs(${hydEnqs.size})")
5639b258a00Sxgkiri
5640438e8f4SHaojin Tang  val d2IqStaOut = dispatch2Iq.io.out.zipWithIndex.filter(staIdxSeq contains _._2).unzip._1.flatten
5650438e8f4SHaojin Tang  d2IqStaOut.zip(staEnqs).zip(stdEnqs).foreach{ case((dp, staIQ), stdIQ) =>
566730cfbc0SXuan Hu    val isAllReady = staIQ.ready && stdIQ.ready
567e62b6911SXuan Hu    dp.ready := isAllReady
568e62b6911SXuan Hu    staIQ.valid := dp.valid && isAllReady
5690438e8f4SHaojin Tang    stdIQ.valid := dp.valid && isAllReady && FuType.FuTypeOrR(dp.bits.fuType, FuType.stu, FuType.mou)
5709b258a00Sxgkiri  }
571730cfbc0SXuan Hu
5720438e8f4SHaojin Tang  val d2IqHyaOut = dispatch2Iq.io.out.zipWithIndex.filter(hyaIdxSeq contains _._2).unzip._1.flatten
5730438e8f4SHaojin Tang  d2IqHyaOut.zip(hyaEnqs).zip(hydEnqs).foreach{ case((dp, hyaIQ), hydIQ) =>
574e62b6911SXuan Hu    val isAllReady = hyaIQ.ready && hydIQ.ready
575e62b6911SXuan Hu    dp.ready := isAllReady
576e62b6911SXuan Hu    hyaIQ.valid := dp.valid && isAllReady
57756bceacbSHaojin Tang    hydIQ.valid := dp.valid && isAllReady && FuType.FuTypeOrR(dp.bits.fuType, FuType.stu, FuType.mou)
578e62b6911SXuan Hu  }
579730cfbc0SXuan Hu
580e62b6911SXuan Hu  stDataIQs.zipWithIndex.foreach { case (iq, i) =>
581e62b6911SXuan Hu    iq.io.flush <> io.fromCtrlBlock.flush
58260f0c5aeSxiaofeibao    iq.io.wakeupFromWB.zip(
58360f0c5aeSxiaofeibao      wakeupFromIntWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromIntWBPort.keys.toSeq.contains(x._2)).map(_._1).toSeq ++
58460f0c5aeSxiaofeibao      wakeupFromFpWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromFpWBPort.keys.toSeq.contains(x._2)).map(_._1).toSeq ++
585c720aa49Ssinsanction      wakeupFromVfWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromVfWBPort.keys.toSeq.contains(x._2)).map(_._1).toSeq ++
586c720aa49Ssinsanction      wakeupFromV0WBVec.zipWithIndex.filter(x => iq.params.needWakeupFromV0WBPort.keys.toSeq.contains(x._2)).map(_._1).toSeq ++
587c720aa49Ssinsanction      wakeupFromVlWBVec.zipWithIndex.filter(x => iq.params.needWakeupFromVlWBPort.keys.toSeq.contains(x._2)).map(_._1).toSeq
58860f0c5aeSxiaofeibao    ).foreach{ case (sink, source) => sink := source}
589e62b6911SXuan Hu  }
590e62b6911SXuan Hu
591e62b6911SXuan Hu  (stdEnqs ++ hydEnqs).zip(staEnqs ++ hyaEnqs).zipWithIndex.foreach { case ((stdIQEnq, staIQEnq), i) =>
592730cfbc0SXuan Hu    stdIQEnq.bits  := staIQEnq.bits
593730cfbc0SXuan Hu    // Store data reuses store addr src(1) in dispatch2iq
594e62b6911SXuan Hu    // [dispatch2iq] --src*------src*(0)--> [staIQ|hyaIQ]
595730cfbc0SXuan Hu    //                       \
596730cfbc0SXuan Hu    //                        ---src*(1)--> [stdIQ]
597730cfbc0SXuan Hu    // Since the src(1) of sta is easier to get, stdIQEnq.bits.src*(0) is assigned to staIQEnq.bits.src*(1)
598730cfbc0SXuan Hu    // instead of dispatch2Iq.io.out(x).bits.src*(1)
59997b279b9SXuan Hu    val stdIdx = 1
6002d270511Ssinsanction    stdIQEnq.bits.srcState(0) := staIQEnq.bits.srcState(stdIdx)
60113551487SzhanglyGit    stdIQEnq.bits.srcLoadDependency(0) := staIQEnq.bits.srcLoadDependency(1)
6022d270511Ssinsanction      stdIQEnq.bits.srcType(0) := staIQEnq.bits.srcType(stdIdx)
6032d270511Ssinsanction    stdIQEnq.bits.psrc(0) := staIQEnq.bits.psrc(stdIdx)
604730cfbc0SXuan Hu    stdIQEnq.bits.sqIdx := staIQEnq.bits.sqIdx
605730cfbc0SXuan Hu  }
606730cfbc0SXuan Hu
6072d270511Ssinsanction  vecMemIQs.foreach {
6082d270511Ssinsanction    case imp: IssueQueueVecMemImp =>
6092d270511Ssinsanction      imp.io.memIO.get.sqDeqPtr.foreach(_ := io.fromMem.get.sqDeqPtr)
6102d270511Ssinsanction      imp.io.memIO.get.lqDeqPtr.foreach(_ := io.fromMem.get.lqDeqPtr)
6111f3d1b4dSXuan Hu      // not used
612b7c799beSzhanglyGit      //imp.io.memIO.get.feedbackIO.head := io.fromMem.get.vstuFeedback.head // only vector store replay
6131f3d1b4dSXuan Hu      // maybe not used
6141f3d1b4dSXuan Hu      imp.io.memIO.get.checkWait.stIssuePtr := io.fromMem.get.stIssuePtr
6151f3d1b4dSXuan Hu      imp.io.memIO.get.checkWait.memWaitUpdateReq := io.fromMem.get.memWaitUpdateReq
61660f0c5aeSxiaofeibao      imp.io.wakeupFromWB.zip(
61760f0c5aeSxiaofeibao        wakeupFromIntWBVec.zipWithIndex.filter(x => imp.params.needWakeupFromIntWBPort.keys.toSeq.contains(x._2)).map(_._1).toSeq ++
61860f0c5aeSxiaofeibao        wakeupFromFpWBVec.zipWithIndex.filter(x => imp.params.needWakeupFromFpWBPort.keys.toSeq.contains(x._2)).map(_._1).toSeq ++
619c720aa49Ssinsanction        wakeupFromVfWBVec.zipWithIndex.filter(x => imp.params.needWakeupFromVfWBPort.keys.toSeq.contains(x._2)).map(_._1).toSeq ++
620c720aa49Ssinsanction        wakeupFromV0WBVec.zipWithIndex.filter(x => imp.params.needWakeupFromV0WBPort.keys.toSeq.contains(x._2)).map(_._1).toSeq ++
621c720aa49Ssinsanction        wakeupFromVlWBVec.zipWithIndex.filter(x => imp.params.needWakeupFromVlWBPort.keys.toSeq.contains(x._2)).map(_._1).toSeq
62260f0c5aeSxiaofeibao      ).foreach{ case (sink, source) => sink := source}
623f39a61a1SzhanglyGit
6242d270511Ssinsanction    case _ =>
6252d270511Ssinsanction  }
626b7c799beSzhanglyGit  val vecMemFeedbackIO: Seq[MemRSFeedbackIO] = vecMemIQs.map {
627b7c799beSzhanglyGit    case imp: IssueQueueVecMemImp =>
628b7c799beSzhanglyGit      imp.io.memIO.get.feedbackIO
629b7c799beSzhanglyGit  }.flatten
630b7c799beSzhanglyGit  assert(vecMemFeedbackIO.size == io.fromMem.get.vstuFeedback.size, "vecMemFeedback size dont match!")
631b7c799beSzhanglyGit  vecMemFeedbackIO.zip(io.fromMem.get.vstuFeedback).foreach{
632b7c799beSzhanglyGit    case (sink, source) =>
633b7c799beSzhanglyGit      sink := source
634b7c799beSzhanglyGit  }
6352d270511Ssinsanction
636730cfbc0SXuan Hu  val lsqEnqCtrl = Module(new LsqEnqCtrl)
637730cfbc0SXuan Hu
638730cfbc0SXuan Hu  lsqEnqCtrl.io.redirect <> io.fromCtrlBlock.flush
639730cfbc0SXuan Hu  lsqEnqCtrl.io.enq <> dispatch2Iq.io.enqLsqIO.get
640730cfbc0SXuan Hu  lsqEnqCtrl.io.lcommit := io.fromMem.get.lcommit
641730cfbc0SXuan Hu  lsqEnqCtrl.io.scommit := io.fromMem.get.scommit
642730cfbc0SXuan Hu  lsqEnqCtrl.io.lqCancelCnt := io.fromMem.get.lqCancelCnt
643730cfbc0SXuan Hu  lsqEnqCtrl.io.sqCancelCnt := io.fromMem.get.sqCancelCnt
644f3a9fb05SAnzo  dispatch2Iq.io.lqFreeCount.get := lsqEnqCtrl.io.lqFreeCount
645f3a9fb05SAnzo  dispatch2Iq.io.sqFreeCount.get := lsqEnqCtrl.io.sqFreeCount
646730cfbc0SXuan Hu  io.memIO.get.lsqEnqIO <> lsqEnqCtrl.io.enqLsq
6477e471bf8SXuan Hu
6487e471bf8SXuan Hu  dontTouch(io.vecLoadIssueResp)
649e1a85e9fSchengguanghui
650e1a85e9fSchengguanghui  val intBusyTablePerf = intBusyTable.get
651e1a85e9fSchengguanghui  val fpBusyTablePerf  = fpBusyTable.get
652e1a85e9fSchengguanghui  val vecBusyTablePerf = vfBusyTable.get
653e1a85e9fSchengguanghui  val v0BusyTablePerf  = v0BusyTable.get
654e1a85e9fSchengguanghui  val vlBusyTablePerf  = vlBusyTable.get
655e1a85e9fSchengguanghui
656e1a85e9fSchengguanghui  val perfEvents = basePerfEvents ++ Seq(intBusyTablePerf, fpBusyTablePerf, vecBusyTablePerf, v0BusyTablePerf, vlBusyTablePerf).flatten(_.getPerfEvents)
657e1a85e9fSchengguanghui  generatePerfEvent()
658730cfbc0SXuan Hu}
659