xref: /XiangShan/src/main/scala/xiangshan/backend/issue/Scheduler.scala (revision 2e0a7dc5b7b351e89578b74832f6ea55c6a89344)
1730cfbc0SXuan Hupackage xiangshan.backend.issue
2730cfbc0SXuan Hu
3730cfbc0SXuan Huimport chipsalliance.rocketchip.config.Parameters
4730cfbc0SXuan Huimport chisel3._
5730cfbc0SXuan Huimport chisel3.util._
6730cfbc0SXuan Huimport freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp}
7730cfbc0SXuan Huimport xiangshan._
8730cfbc0SXuan Huimport xiangshan.backend.Bundles
9730cfbc0SXuan Huimport xiangshan.backend.datapath.DataConfig.VAddrData
10730cfbc0SXuan Huimport xiangshan.backend.regfile.RfWritePortWithConfig
11730cfbc0SXuan Huimport xiangshan.backend.rename.BusyTable
12730cfbc0SXuan Huimport xiangshan.mem.{LsqEnqCtrl, LsqEnqIO, MemWaitUpdateReq, SqPtr}
13730cfbc0SXuan Huimport xiangshan.backend.Bundles.{DynInst, IssueQueueWakeUpBundle}
14730cfbc0SXuan Hu
15730cfbc0SXuan Husealed trait SchedulerType
16730cfbc0SXuan Hu
17730cfbc0SXuan Hucase class IntScheduler() extends SchedulerType
18730cfbc0SXuan Hucase class MemScheduler() extends SchedulerType
19730cfbc0SXuan Hucase class VfScheduler() extends SchedulerType
20730cfbc0SXuan Hucase class NoScheduler() extends SchedulerType
21730cfbc0SXuan Hu
22730cfbc0SXuan Huclass Scheduler(val params: SchdBlockParams)(implicit p: Parameters) extends LazyModule with HasXSParameter {
23730cfbc0SXuan Hu  val numIntStateWrite = backendParams.numIntWb
24730cfbc0SXuan Hu  val numVfStateWrite = backendParams.numVfWb
25730cfbc0SXuan Hu
26730cfbc0SXuan Hu  val dispatch2Iq = LazyModule(new Dispatch2Iq(params))
27730cfbc0SXuan Hu  val issueQueue = params.issueBlockParams.map(x => LazyModule(new IssueQueue(x).suggestName(x.getIQName)))
28730cfbc0SXuan Hu
29730cfbc0SXuan Hu  lazy val module = params.schdType match {
30730cfbc0SXuan Hu    case IntScheduler() => new SchedulerArithImp(this)(params, p)
31730cfbc0SXuan Hu    case MemScheduler() => new SchedulerMemImp(this)(params, p)
32730cfbc0SXuan Hu    case VfScheduler() => new SchedulerArithImp(this)(params, p)
33730cfbc0SXuan Hu    case _ => null
34730cfbc0SXuan Hu  }
35730cfbc0SXuan Hu}
36730cfbc0SXuan Hu
37730cfbc0SXuan Huclass SchedulerIO()(implicit params: SchdBlockParams, p: Parameters) extends XSBundle {
3868d13085SXuan Hu  // params alias
3968d13085SXuan Hu  private val LoadQueueSize = VirtualLoadQueueSize
4068d13085SXuan Hu
41730cfbc0SXuan Hu  val fromTop = new Bundle {
42730cfbc0SXuan Hu    val hartId = Input(UInt(8.W))
43730cfbc0SXuan Hu  }
44*2e0a7dc5Sfdy  val fromWbFuBusyTable = new Bundle{
45*2e0a7dc5Sfdy    val fuBusyTableRead = MixedVec(params.issueBlockParams.map(x => Input(x.genWbFuBusyTableReadBundle)))
46*2e0a7dc5Sfdy  }
47*2e0a7dc5Sfdy  val toWbFuBusyTable = new Bundle{
48*2e0a7dc5Sfdy    val intFuBusyTableWrite = MixedVec(params.issueBlockParams.map(x => x.genWbFuBusyTableWriteBundle))
49*2e0a7dc5Sfdy    val vfFuBusyTableWrite = MixedVec(params.issueBlockParams.map(x => x.genWbFuBusyTableWriteBundle))
508d29ec32Sczw  }
51730cfbc0SXuan Hu  val fromCtrlBlock = new Bundle {
52730cfbc0SXuan Hu    val pcVec = Input(Vec(params.numPcReadPort, UInt(VAddrData().dataWidth.W)))
53730cfbc0SXuan Hu    val targetVec = 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  }
60730cfbc0SXuan Hu  val intWriteBack = MixedVec(Vec(backendParams.intPregParams.numWrite,
61730cfbc0SXuan Hu    new RfWritePortWithConfig(backendParams.intPregParams.dataCfg, backendParams.intPregParams.addrWidth)))
62730cfbc0SXuan Hu  val vfWriteBack = MixedVec(Vec(backendParams.vfPregParams.numWrite,
63730cfbc0SXuan Hu    new RfWritePortWithConfig(backendParams.vfPregParams.dataCfg, backendParams.vfPregParams.addrWidth)))
64730cfbc0SXuan Hu  val toDataPath: MixedVec[MixedVec[DecoupledIO[Bundles.IssueQueueIssueBundle]]] = MixedVec(params.issueBlockParams.map(_.genIssueDecoupledBundle))
65730cfbc0SXuan Hu  val fromDataPath: MixedVec[MixedVec[Bundles.OGRespBundle]] = MixedVec(params.issueBlockParams.map(x => Flipped(x.genOGRespBundle)))
66730cfbc0SXuan Hu
67730cfbc0SXuan Hu  val memIO = if (params.isMemSchd) Some(new Bundle {
68730cfbc0SXuan Hu    val lsqEnqIO = Flipped(new LsqEnqIO)
69730cfbc0SXuan Hu  }) else None
70730cfbc0SXuan Hu  val fromMem = if (params.isMemSchd) Some(new Bundle {
717b753bebSXuan Hu    val ldaFeedback = Flipped(Vec(params.LduCnt, new MemRSFeedbackIO))
727b753bebSXuan Hu    val staFeedback = Flipped(Vec(params.StaCnt, new MemRSFeedbackIO))
73730cfbc0SXuan Hu    val stIssuePtr = Input(new SqPtr())
74730cfbc0SXuan Hu    val lcommit = Input(UInt(log2Up(CommitWidth + 1).W))
75730cfbc0SXuan Hu    val scommit = Input(UInt(log2Ceil(EnsbufferWidth + 1).W)) // connected to `memBlock.io.sqDeq` instead of ROB
76730cfbc0SXuan Hu    // from lsq
77730cfbc0SXuan Hu    val lqCancelCnt = Input(UInt(log2Up(LoadQueueSize + 1).W))
78730cfbc0SXuan Hu    val sqCancelCnt = Input(UInt(log2Up(StoreQueueSize + 1).W))
79730cfbc0SXuan Hu    val memWaitUpdateReq = Flipped(new MemWaitUpdateReq)
80730cfbc0SXuan Hu  }) else None
81730cfbc0SXuan Hu  val toMem = if (params.isMemSchd) Some(new Bundle {
82730cfbc0SXuan Hu    val loadFastMatch = Output(Vec(params.LduCnt, new IssueQueueLoadBundle))
83730cfbc0SXuan Hu  }) else None
84730cfbc0SXuan Hu}
85730cfbc0SXuan Hu
86730cfbc0SXuan Huabstract class SchedulerImpBase(wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters)
87730cfbc0SXuan Hu  extends LazyModuleImp(wrapper)
88730cfbc0SXuan Hu    with HasXSParameter
89730cfbc0SXuan Hu{
90730cfbc0SXuan Hu  val io = IO(new SchedulerIO())
91730cfbc0SXuan Hu
92730cfbc0SXuan Hu  // alias
93730cfbc0SXuan Hu  private val schdType = params.schdType
94730cfbc0SXuan Hu  private val (numRfRead, numRfWrite) = params.numRfReadWrite.getOrElse((0, 0))
95730cfbc0SXuan Hu  private val numPregs = params.numPregs
96730cfbc0SXuan Hu
97730cfbc0SXuan Hu  // Modules
98730cfbc0SXuan Hu  val dispatch2Iq: Dispatch2IqImp = wrapper.dispatch2Iq.module
99730cfbc0SXuan Hu  val issueQueues: Seq[IssueQueueImp] = wrapper.issueQueue.map(_.module)
100730cfbc0SXuan Hu
101730cfbc0SXuan Hu  // BusyTable Modules
102730cfbc0SXuan Hu  val intBusyTable = schdType match {
103730cfbc0SXuan Hu    case IntScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numIntStateRead, wrapper.numIntStateWrite)))
104730cfbc0SXuan Hu    case _ => None
105730cfbc0SXuan Hu  }
106730cfbc0SXuan Hu
107730cfbc0SXuan Hu  val vfBusyTable = schdType match {
108730cfbc0SXuan Hu    case VfScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numVfStateRead, wrapper.numVfStateWrite)))
109730cfbc0SXuan Hu    case _ => None
110730cfbc0SXuan Hu  }
111730cfbc0SXuan Hu
112730cfbc0SXuan Hu  dispatch2Iq.io match { case dp2iq =>
113730cfbc0SXuan Hu    dp2iq.redirect <> io.fromCtrlBlock.flush
114730cfbc0SXuan Hu    dp2iq.in <> io.fromDispatch.uops
115730cfbc0SXuan Hu    dp2iq.readIntState.foreach(_ <> intBusyTable.get.io.read)
116730cfbc0SXuan Hu    dp2iq.readVfState.foreach(_ <> vfBusyTable.get.io.read)
117730cfbc0SXuan Hu  }
118730cfbc0SXuan Hu
119730cfbc0SXuan Hu  intBusyTable match {
120730cfbc0SXuan Hu    case Some(bt) =>
121730cfbc0SXuan Hu      bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) =>
122730cfbc0SXuan Hu        btAllocPregs.valid := dpAllocPregs.isInt
123730cfbc0SXuan Hu        btAllocPregs.bits := dpAllocPregs.preg
124730cfbc0SXuan Hu      }
125730cfbc0SXuan Hu      bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) =>
126730cfbc0SXuan Hu        wb.valid := io.intWriteBack(i).wen && io.intWriteBack(i).intWen
127730cfbc0SXuan Hu        wb.bits := io.intWriteBack(i).addr
128730cfbc0SXuan Hu      }
129730cfbc0SXuan Hu    case None =>
130730cfbc0SXuan Hu  }
131730cfbc0SXuan Hu
132730cfbc0SXuan Hu  vfBusyTable match {
133730cfbc0SXuan Hu    case Some(bt) =>
134730cfbc0SXuan Hu      bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) =>
135730cfbc0SXuan Hu        btAllocPregs.valid := dpAllocPregs.isFp
136730cfbc0SXuan Hu        btAllocPregs.bits := dpAllocPregs.preg
137730cfbc0SXuan Hu      }
138730cfbc0SXuan Hu      bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) =>
139730cfbc0SXuan Hu        wb.valid := io.vfWriteBack(i).wen && (io.vfWriteBack(i).fpWen || io.vfWriteBack(i).vecWen)
140730cfbc0SXuan Hu        wb.bits := io.vfWriteBack(i).addr
141730cfbc0SXuan Hu      }
142730cfbc0SXuan Hu    case None =>
143730cfbc0SXuan Hu  }
144730cfbc0SXuan Hu
145730cfbc0SXuan Hu  val wakeupFromWBVec = Wire(Vec(params.numWakeupFromWB, ValidIO(new IssueQueueWakeUpBundle(params.pregIdxWidth))))
146730cfbc0SXuan Hu  val writeback = params.schdType match {
147730cfbc0SXuan Hu    case IntScheduler() => io.intWriteBack
148730cfbc0SXuan Hu    case MemScheduler() => io.intWriteBack ++ io.vfWriteBack
149730cfbc0SXuan Hu    case VfScheduler() => io.vfWriteBack
150730cfbc0SXuan Hu    case _ => Seq()
151730cfbc0SXuan Hu  }
152730cfbc0SXuan Hu  wakeupFromWBVec.zip(writeback).foreach { case (sink, source) =>
153730cfbc0SXuan Hu    sink.valid := source.wen
154730cfbc0SXuan Hu    sink.bits.rfWen := source.intWen
155730cfbc0SXuan Hu    sink.bits.fpWen := source.fpWen
156730cfbc0SXuan Hu    sink.bits.vecWen := source.vecWen
157730cfbc0SXuan Hu    sink.bits.pdest := source.addr
158730cfbc0SXuan Hu  }
159730cfbc0SXuan Hu
160730cfbc0SXuan Hu  io.toDataPath.zipWithIndex.foreach { case (toDp, i) =>
161730cfbc0SXuan Hu    toDp <> issueQueues(i).io.deq
162730cfbc0SXuan Hu  }
163730cfbc0SXuan Hu}
164730cfbc0SXuan Hu
165730cfbc0SXuan Huclass SchedulerArithImp(override val wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters)
166730cfbc0SXuan Hu  extends SchedulerImpBase(wrapper)
167730cfbc0SXuan Hu    with HasXSParameter
168730cfbc0SXuan Hu{
169*2e0a7dc5Sfdy//  dontTouch(io.vfWbFuBusyTable)
170730cfbc0SXuan Hu  println(s"[SchedulerArithImp] " +
171730cfbc0SXuan Hu    s"has intBusyTable: ${intBusyTable.nonEmpty}, " +
172730cfbc0SXuan Hu    s"has vfBusyTable: ${vfBusyTable.nonEmpty}")
173730cfbc0SXuan Hu
174730cfbc0SXuan Hu  issueQueues.zipWithIndex.foreach { case (iq, i) =>
175730cfbc0SXuan Hu    iq.io.flush <> io.fromCtrlBlock.flush
176730cfbc0SXuan Hu    iq.io.enq <> dispatch2Iq.io.out(i)
177730cfbc0SXuan Hu    iq.io.wakeup := wakeupFromWBVec
178730cfbc0SXuan Hu    iq.io.deqResp.zipWithIndex.foreach { case (deqResp, j) =>
179ea0f92d8Sczw      deqResp.valid := iq.io.deq(j).valid && io.toDataPath(i)(j).ready
180730cfbc0SXuan Hu      deqResp.bits.success := false.B
181ea0f92d8Sczw      deqResp.bits.respType := RSFeedbackType.issueSuccess
182730cfbc0SXuan Hu      deqResp.bits.addrOH := iq.io.deq(j).bits.addrOH
1838d29ec32Sczw      deqResp.bits.rfWen := iq.io.deq(j).bits.common.rfWen.getOrElse(false.B)
1848d29ec32Sczw      deqResp.bits.fuType := iq.io.deq(j).bits.common.fuType
1858d29ec32Sczw
186*2e0a7dc5Sfdy      io.toWbFuBusyTable.intFuBusyTableWrite(i)(j).deqResp.valid := iq.io.deq(j).valid && io.toDataPath(i)(j).ready
187*2e0a7dc5Sfdy      io.toWbFuBusyTable.intFuBusyTableWrite(i)(j).deqResp.bits.fuType := iq.io.deq(j).bits.common.fuType
188*2e0a7dc5Sfdy      io.toWbFuBusyTable.intFuBusyTableWrite(i)(j).deqResp.bits.respType := RSFeedbackType.issueSuccess
189*2e0a7dc5Sfdy      io.toWbFuBusyTable.intFuBusyTableWrite(i)(j).deqResp.bits.rfWen := iq.io.deq(j).bits.common.rfWen.getOrElse(false.B)
190*2e0a7dc5Sfdy
191*2e0a7dc5Sfdy      io.toWbFuBusyTable.vfFuBusyTableWrite(i)(j).deqResp.valid := iq.io.deq(j).valid && io.toDataPath(i)(j).ready
192*2e0a7dc5Sfdy      io.toWbFuBusyTable.vfFuBusyTableWrite(i)(j).deqResp.bits.fuType := iq.io.deq(j).bits.common.fuType
193*2e0a7dc5Sfdy      io.toWbFuBusyTable.vfFuBusyTableWrite(i)(j).deqResp.bits.respType := RSFeedbackType.issueSuccess
194*2e0a7dc5Sfdy      io.toWbFuBusyTable.vfFuBusyTableWrite(i)(j).deqResp.bits.rfWen := iq.io.deq(j).bits.common.rfWen.getOrElse(false.B)
195730cfbc0SXuan Hu    }
196730cfbc0SXuan Hu    iq.io.og0Resp.zipWithIndex.foreach { case (og0Resp, j) =>
197730cfbc0SXuan Hu      og0Resp.valid := io.fromDataPath(i)(j).og0resp.valid
198730cfbc0SXuan Hu      og0Resp.bits.success := false.B // Todo: remove it
199730cfbc0SXuan Hu      og0Resp.bits.respType := io.fromDataPath(i)(j).og0resp.bits.respType
200730cfbc0SXuan Hu      og0Resp.bits.addrOH := io.fromDataPath(i)(j).og0resp.bits.addrOH
2018d29ec32Sczw      og0Resp.bits.rfWen := io.fromDataPath(i)(j).og0resp.bits.rfWen
2028d29ec32Sczw      og0Resp.bits.fuType := io.fromDataPath(i)(j).og0resp.bits.fuType
2038d29ec32Sczw
204*2e0a7dc5Sfdy      io.toWbFuBusyTable.intFuBusyTableWrite(i)(j).og0Resp.valid := io.fromDataPath(i)(j).og0resp.valid
205*2e0a7dc5Sfdy      io.toWbFuBusyTable.intFuBusyTableWrite(i)(j).og0Resp.bits.fuType := io.fromDataPath(i)(j).og0resp.bits.fuType
206*2e0a7dc5Sfdy      io.toWbFuBusyTable.intFuBusyTableWrite(i)(j).og0Resp.bits.respType := io.fromDataPath(i)(j).og0resp.bits.respType
207*2e0a7dc5Sfdy      io.toWbFuBusyTable.intFuBusyTableWrite(i)(j).og0Resp.bits.rfWen := io.fromDataPath(i)(j).og0resp.bits.rfWen
208*2e0a7dc5Sfdy
209*2e0a7dc5Sfdy      io.toWbFuBusyTable.vfFuBusyTableWrite(i)(j).og0Resp.valid := io.fromDataPath(i)(j).og0resp.valid
210*2e0a7dc5Sfdy      io.toWbFuBusyTable.vfFuBusyTableWrite(i)(j).og0Resp.bits.fuType := io.fromDataPath(i)(j).og0resp.bits.fuType
211*2e0a7dc5Sfdy      io.toWbFuBusyTable.vfFuBusyTableWrite(i)(j).og0Resp.bits.respType := io.fromDataPath(i)(j).og0resp.bits.respType
212*2e0a7dc5Sfdy      io.toWbFuBusyTable.vfFuBusyTableWrite(i)(j).og0Resp.bits.rfWen := io.fromDataPath(i)(j).og0resp.bits.rfWen
213730cfbc0SXuan Hu    }
214730cfbc0SXuan Hu    iq.io.og1Resp.zipWithIndex.foreach { case (og1Resp, j) =>
215730cfbc0SXuan Hu      og1Resp.valid := io.fromDataPath(i)(j).og1resp.valid
216730cfbc0SXuan Hu      og1Resp.bits.success := false.B
217730cfbc0SXuan Hu      og1Resp.bits.respType := io.fromDataPath(i)(j).og1resp.bits.respType
218730cfbc0SXuan Hu      og1Resp.bits.addrOH := io.fromDataPath(i)(j).og1resp.bits.addrOH
2198d29ec32Sczw      og1Resp.bits.rfWen := io.fromDataPath(i)(j).og1resp.bits.rfWen
2208d29ec32Sczw      og1Resp.bits.fuType := io.fromDataPath(i)(j).og1resp.bits.fuType
2218d29ec32Sczw
222*2e0a7dc5Sfdy      io.toWbFuBusyTable.intFuBusyTableWrite(i)(j).og1Resp.valid := io.fromDataPath(i)(j).og1resp.valid
223*2e0a7dc5Sfdy      io.toWbFuBusyTable.intFuBusyTableWrite(i)(j).og1Resp.bits.fuType := io.fromDataPath(i)(j).og1resp.bits.fuType
224*2e0a7dc5Sfdy      io.toWbFuBusyTable.intFuBusyTableWrite(i)(j).og1Resp.bits.respType := io.fromDataPath(i)(j).og1resp.bits.respType
225*2e0a7dc5Sfdy      io.toWbFuBusyTable.intFuBusyTableWrite(i)(j).og1Resp.bits.rfWen := io.fromDataPath(i)(j).og1resp.bits.rfWen
226*2e0a7dc5Sfdy
227*2e0a7dc5Sfdy      io.toWbFuBusyTable.vfFuBusyTableWrite(i)(j).og1Resp.valid := io.fromDataPath(i)(j).og1resp.valid
228*2e0a7dc5Sfdy      io.toWbFuBusyTable.vfFuBusyTableWrite(i)(j).og1Resp.bits.fuType := io.fromDataPath(i)(j).og1resp.bits.fuType
229*2e0a7dc5Sfdy      io.toWbFuBusyTable.vfFuBusyTableWrite(i)(j).og1Resp.bits.respType := io.fromDataPath(i)(j).og1resp.bits.respType
230*2e0a7dc5Sfdy      io.toWbFuBusyTable.vfFuBusyTableWrite(i)(j).og1Resp.bits.rfWen := io.fromDataPath(i)(j).og1resp.bits.rfWen
231730cfbc0SXuan Hu    }
232*2e0a7dc5Sfdy
233*2e0a7dc5Sfdy    iq.io.wbBusyTableRead := io.fromWbFuBusyTable.fuBusyTableRead(i)
234730cfbc0SXuan Hu  }
235730cfbc0SXuan Hu
236730cfbc0SXuan Hu  val iqJumpBundleVec: Seq[IssueQueueJumpBundle] = issueQueues.map {
237730cfbc0SXuan Hu    case imp: IssueQueueIntImp => imp.io.enqJmp
238730cfbc0SXuan Hu    case _ => None
239730cfbc0SXuan Hu  }.filter(_.nonEmpty).flatMap(_.get)
240730cfbc0SXuan Hu  println(s"[Scheduler] iqJumpBundleVec: ${iqJumpBundleVec}")
241730cfbc0SXuan Hu
242730cfbc0SXuan Hu  iqJumpBundleVec.zip(io.fromCtrlBlock.pcVec zip io.fromCtrlBlock.targetVec).foreach { case (iqJmp, (pc, target)) =>
243730cfbc0SXuan Hu    iqJmp.pc := pc
244730cfbc0SXuan Hu    iqJmp.target := target
245730cfbc0SXuan Hu  }
246730cfbc0SXuan Hu}
247730cfbc0SXuan Hu
248730cfbc0SXuan Huclass SchedulerMemImp(override val wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters)
249730cfbc0SXuan Hu  extends SchedulerImpBase(wrapper)
250730cfbc0SXuan Hu    with HasXSParameter
251730cfbc0SXuan Hu{
252730cfbc0SXuan Hu  println(s"[SchedulerMemImp] " +
253730cfbc0SXuan Hu    s"has intBusyTable: ${intBusyTable.nonEmpty}, " +
254730cfbc0SXuan Hu    s"has vfBusyTable: ${vfBusyTable.nonEmpty}")
255730cfbc0SXuan Hu
256730cfbc0SXuan Hu  val memAddrIQs = issueQueues.filter(iq => iq.params.StdCnt == 0)
257730cfbc0SXuan Hu  val stAddrIQs = issueQueues.filter(iq => iq.params.StaCnt > 0) // included in memAddrIQs
2587b753bebSXuan Hu  val ldAddrIQs = issueQueues.filter(iq => iq.params.LduCnt > 0)
259730cfbc0SXuan Hu  val stDataIQs = issueQueues.filter(iq => iq.params.StdCnt > 0)
260730cfbc0SXuan Hu  require(memAddrIQs.nonEmpty && stDataIQs.nonEmpty)
261730cfbc0SXuan Hu
262730cfbc0SXuan Hu  issueQueues.zipWithIndex.foreach { case (iq, i) =>
263730cfbc0SXuan Hu    iq.io.deqResp.zipWithIndex.foreach { case (deqResp, j) =>
264ea0f92d8Sczw      deqResp.valid := iq.io.deq(j).valid && io.toDataPath(i)(j).ready
265730cfbc0SXuan Hu      deqResp.bits.success := false.B
266ea0f92d8Sczw      deqResp.bits.respType := RSFeedbackType.issueSuccess
267730cfbc0SXuan Hu      deqResp.bits.addrOH := iq.io.deq(j).bits.addrOH
2688d29ec32Sczw      deqResp.bits.rfWen := iq.io.deq(j).bits.common.rfWen.getOrElse(false.B)
2698d29ec32Sczw      deqResp.bits.fuType := iq.io.deq(j).bits.common.fuType
2708d29ec32Sczw
271*2e0a7dc5Sfdy      io.toWbFuBusyTable.intFuBusyTableWrite(i)(j).deqResp.valid := iq.io.deq(j).valid && io.toDataPath(i)(j).ready
272*2e0a7dc5Sfdy      io.toWbFuBusyTable.intFuBusyTableWrite(i)(j).deqResp.bits.fuType := iq.io.deq(j).bits.common.fuType
273*2e0a7dc5Sfdy      io.toWbFuBusyTable.intFuBusyTableWrite(i)(j).deqResp.bits.respType := RSFeedbackType.issueSuccess
274*2e0a7dc5Sfdy      io.toWbFuBusyTable.intFuBusyTableWrite(i)(j).deqResp.bits.rfWen := iq.io.deq(j).bits.common.rfWen.getOrElse(false.B)
275730cfbc0SXuan Hu    }
276730cfbc0SXuan Hu    iq.io.og0Resp.zipWithIndex.foreach { case (og0Resp, j) =>
277730cfbc0SXuan Hu      og0Resp.valid := io.fromDataPath(i)(j).og0resp.valid
278730cfbc0SXuan Hu      og0Resp.bits.success := false.B // Todo: remove it
279730cfbc0SXuan Hu      og0Resp.bits.respType := io.fromDataPath(i)(j).og0resp.bits.respType
280730cfbc0SXuan Hu      og0Resp.bits.addrOH := io.fromDataPath(i)(j).og0resp.bits.addrOH
2818d29ec32Sczw      og0Resp.bits.rfWen := io.fromDataPath(i)(j).og0resp.bits.rfWen
2828d29ec32Sczw      og0Resp.bits.fuType := io.fromDataPath(i)(j).og0resp.bits.fuType
2838d29ec32Sczw
284*2e0a7dc5Sfdy      io.toWbFuBusyTable.intFuBusyTableWrite(i)(j).og0Resp.valid := io.fromDataPath(i)(j).og0resp.valid
285*2e0a7dc5Sfdy      io.toWbFuBusyTable.intFuBusyTableWrite(i)(j).og0Resp.bits.fuType := io.fromDataPath(i)(j).og0resp.bits.fuType
286*2e0a7dc5Sfdy      io.toWbFuBusyTable.intFuBusyTableWrite(i)(j).og0Resp.bits.respType := io.fromDataPath(i)(j).og0resp.bits.respType
287*2e0a7dc5Sfdy      io.toWbFuBusyTable.intFuBusyTableWrite(i)(j).og0Resp.bits.rfWen := io.fromDataPath(i)(j).og0resp.bits.rfWen
288730cfbc0SXuan Hu    }
289730cfbc0SXuan Hu    iq.io.og1Resp.zipWithIndex.foreach { case (og1Resp, j) =>
290730cfbc0SXuan Hu      og1Resp.valid := io.fromDataPath(i)(j).og1resp.valid
291730cfbc0SXuan Hu      og1Resp.bits.success := false.B
292730cfbc0SXuan Hu      og1Resp.bits.respType := io.fromDataPath(i)(j).og1resp.bits.respType
293730cfbc0SXuan Hu      og1Resp.bits.addrOH := io.fromDataPath(i)(j).og1resp.bits.addrOH
2948d29ec32Sczw      og1Resp.bits.rfWen := io.fromDataPath(i)(j).og1resp.bits.rfWen
2958d29ec32Sczw      og1Resp.bits.fuType := io.fromDataPath(i)(j).og1resp.bits.fuType
2968d29ec32Sczw
297*2e0a7dc5Sfdy      io.toWbFuBusyTable.intFuBusyTableWrite(i)(j).og1Resp.valid := io.fromDataPath(i)(j).og1resp.valid
298*2e0a7dc5Sfdy      io.toWbFuBusyTable.intFuBusyTableWrite(i)(j).og1Resp.bits.fuType := io.fromDataPath(i)(j).og1resp.bits.fuType
299*2e0a7dc5Sfdy      io.toWbFuBusyTable.intFuBusyTableWrite(i)(j).og1Resp.bits.respType := io.fromDataPath(i)(j).og1resp.bits.respType
300*2e0a7dc5Sfdy      io.toWbFuBusyTable.intFuBusyTableWrite(i)(j).og1Resp.bits.rfWen := io.fromDataPath(i)(j).og1resp.bits.rfWen
301730cfbc0SXuan Hu    }
302*2e0a7dc5Sfdy    iq.io.wbBusyTableRead := io.fromWbFuBusyTable.fuBusyTableRead(i)
303730cfbc0SXuan Hu  }
304730cfbc0SXuan Hu
305730cfbc0SXuan Hu  memAddrIQs.zipWithIndex.foreach { case (iq, i) =>
306730cfbc0SXuan Hu    iq.io.flush <> io.fromCtrlBlock.flush
307730cfbc0SXuan Hu    iq.io.enq <> dispatch2Iq.io.out(i)
308730cfbc0SXuan Hu    iq.io.wakeup := wakeupFromWBVec
309730cfbc0SXuan Hu  }
310730cfbc0SXuan Hu
3117b753bebSXuan Hu  ldAddrIQs.foreach {
3127b753bebSXuan Hu    case imp: IssueQueueMemAddrImp => imp.io.memIO.get.feedbackIO <> io.fromMem.get.ldaFeedback
3137b753bebSXuan Hu    case _ =>
3147b753bebSXuan Hu  }
3157b753bebSXuan Hu
3167b753bebSXuan Hu  stAddrIQs.foreach {
3177b753bebSXuan Hu    case imp: IssueQueueMemAddrImp => imp.io.memIO.get.feedbackIO <> io.fromMem.get.staFeedback
3187b753bebSXuan Hu    case _ =>
3197b753bebSXuan Hu  }
320730cfbc0SXuan Hu
321730cfbc0SXuan Hu  dispatch2Iq.io.out(1).zip(stAddrIQs(0).io.enq).zip(stDataIQs(0).io.enq).foreach{ case((di, staIQ), stdIQ) =>
322730cfbc0SXuan Hu    val isAllReady = staIQ.ready && stdIQ.ready
323730cfbc0SXuan Hu    di.ready := isAllReady
324730cfbc0SXuan Hu    staIQ.valid := di.valid && isAllReady
325730cfbc0SXuan Hu    stdIQ.valid := di.valid && isAllReady
326730cfbc0SXuan Hu  }
327730cfbc0SXuan Hu
328730cfbc0SXuan Hu  require(stAddrIQs.size == stDataIQs.size, s"number of store address IQs(${stAddrIQs.size}) " +
329730cfbc0SXuan Hu    s"should be equal to number of data IQs(${stDataIQs})")
330730cfbc0SXuan Hu  stDataIQs.zip(stAddrIQs).zipWithIndex.foreach { case ((stdIQ, staIQ), i) =>
331730cfbc0SXuan Hu    stdIQ.io.flush <> io.fromCtrlBlock.flush
332730cfbc0SXuan Hu
333730cfbc0SXuan Hu    stdIQ.io.enq.zip(staIQ.io.enq).foreach { case (stdIQEnq, staIQEnq) =>
334730cfbc0SXuan Hu      stdIQEnq.bits  := staIQEnq.bits
335730cfbc0SXuan Hu      // Store data reuses store addr src(1) in dispatch2iq
336730cfbc0SXuan Hu      // [dispatch2iq] --src*------src*(0)--> [staIQ]
337730cfbc0SXuan Hu      //                       \
338730cfbc0SXuan Hu      //                        ---src*(1)--> [stdIQ]
339730cfbc0SXuan Hu      // Since the src(1) of sta is easier to get, stdIQEnq.bits.src*(0) is assigned to staIQEnq.bits.src*(1)
340730cfbc0SXuan Hu      // instead of dispatch2Iq.io.out(x).bits.src*(1)
341730cfbc0SXuan Hu      stdIQEnq.bits.srcState(0) := staIQEnq.bits.srcState(1)
342730cfbc0SXuan Hu      stdIQEnq.bits.srcType(0) := staIQEnq.bits.srcType(1)
343730cfbc0SXuan Hu      stdIQEnq.bits.psrc(0) := staIQEnq.bits.psrc(1)
344730cfbc0SXuan Hu      stdIQEnq.bits.sqIdx := staIQEnq.bits.sqIdx
345730cfbc0SXuan Hu    }
346730cfbc0SXuan Hu    stdIQ.io.wakeup := wakeupFromWBVec
347730cfbc0SXuan Hu  }
348730cfbc0SXuan Hu
349730cfbc0SXuan Hu  val lsqEnqCtrl = Module(new LsqEnqCtrl)
350730cfbc0SXuan Hu
351730cfbc0SXuan Hu  lsqEnqCtrl.io.redirect <> io.fromCtrlBlock.flush
352730cfbc0SXuan Hu  lsqEnqCtrl.io.enq <> dispatch2Iq.io.enqLsqIO.get
353730cfbc0SXuan Hu  lsqEnqCtrl.io.lcommit := io.fromMem.get.lcommit
354730cfbc0SXuan Hu  lsqEnqCtrl.io.scommit := io.fromMem.get.scommit
355730cfbc0SXuan Hu  lsqEnqCtrl.io.lqCancelCnt := io.fromMem.get.lqCancelCnt
356730cfbc0SXuan Hu  lsqEnqCtrl.io.sqCancelCnt := io.fromMem.get.sqCancelCnt
357730cfbc0SXuan Hu  io.memIO.get.lsqEnqIO <> lsqEnqCtrl.io.enqLsq
358730cfbc0SXuan Hu}
359