xref: /XiangShan/src/main/scala/xiangshan/backend/issue/Scheduler.scala (revision dd9705615c0460cbe2cb82682b4c4296d66daf2c)
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  }
442e0a7dc5Sfdy  val fromWbFuBusyTable = new Bundle{
452e0a7dc5Sfdy    val fuBusyTableRead = MixedVec(params.issueBlockParams.map(x => Input(x.genWbFuBusyTableReadBundle)))
462e0a7dc5Sfdy  }
47*dd970561SzhanglyGit  val wbFuBusyTable = MixedVec(params.issueBlockParams.map(x => Output(x.genWbFuBusyTableWriteBundle)))
48*dd970561SzhanglyGit
49730cfbc0SXuan Hu  val fromCtrlBlock = new Bundle {
50730cfbc0SXuan Hu    val pcVec = Input(Vec(params.numPcReadPort, UInt(VAddrData().dataWidth.W)))
51730cfbc0SXuan Hu    val targetVec = Input(Vec(params.numPcReadPort, UInt(VAddrData().dataWidth.W)))
52730cfbc0SXuan Hu    val flush = Flipped(ValidIO(new Redirect))
53730cfbc0SXuan Hu  }
54730cfbc0SXuan Hu  val fromDispatch = new Bundle {
55730cfbc0SXuan Hu    val allocPregs = Vec(RenameWidth, Input(new ResetPregStateReq))
56730cfbc0SXuan Hu    val uops =  Vec(params.numUopIn, Flipped(DecoupledIO(new DynInst)))
57730cfbc0SXuan Hu  }
58730cfbc0SXuan Hu  val intWriteBack = MixedVec(Vec(backendParams.intPregParams.numWrite,
59730cfbc0SXuan Hu    new RfWritePortWithConfig(backendParams.intPregParams.dataCfg, backendParams.intPregParams.addrWidth)))
60730cfbc0SXuan Hu  val vfWriteBack = MixedVec(Vec(backendParams.vfPregParams.numWrite,
61730cfbc0SXuan Hu    new RfWritePortWithConfig(backendParams.vfPregParams.dataCfg, backendParams.vfPregParams.addrWidth)))
62730cfbc0SXuan Hu  val toDataPath: MixedVec[MixedVec[DecoupledIO[Bundles.IssueQueueIssueBundle]]] = MixedVec(params.issueBlockParams.map(_.genIssueDecoupledBundle))
63730cfbc0SXuan Hu  val fromDataPath: MixedVec[MixedVec[Bundles.OGRespBundle]] = MixedVec(params.issueBlockParams.map(x => Flipped(x.genOGRespBundle)))
64730cfbc0SXuan Hu
65730cfbc0SXuan Hu  val memIO = if (params.isMemSchd) Some(new Bundle {
66730cfbc0SXuan Hu    val lsqEnqIO = Flipped(new LsqEnqIO)
67730cfbc0SXuan Hu  }) else None
68730cfbc0SXuan Hu  val fromMem = if (params.isMemSchd) Some(new Bundle {
697b753bebSXuan Hu    val ldaFeedback = Flipped(Vec(params.LduCnt, new MemRSFeedbackIO))
707b753bebSXuan Hu    val staFeedback = Flipped(Vec(params.StaCnt, new MemRSFeedbackIO))
71730cfbc0SXuan Hu    val stIssuePtr = Input(new SqPtr())
72730cfbc0SXuan Hu    val lcommit = Input(UInt(log2Up(CommitWidth + 1).W))
73730cfbc0SXuan Hu    val scommit = Input(UInt(log2Ceil(EnsbufferWidth + 1).W)) // connected to `memBlock.io.sqDeq` instead of ROB
74730cfbc0SXuan Hu    // from lsq
75730cfbc0SXuan Hu    val lqCancelCnt = Input(UInt(log2Up(LoadQueueSize + 1).W))
76730cfbc0SXuan Hu    val sqCancelCnt = Input(UInt(log2Up(StoreQueueSize + 1).W))
77730cfbc0SXuan Hu    val memWaitUpdateReq = Flipped(new MemWaitUpdateReq)
78730cfbc0SXuan Hu  }) else None
79730cfbc0SXuan Hu  val toMem = if (params.isMemSchd) Some(new Bundle {
80730cfbc0SXuan Hu    val loadFastMatch = Output(Vec(params.LduCnt, new IssueQueueLoadBundle))
81730cfbc0SXuan Hu  }) else None
82730cfbc0SXuan Hu}
83730cfbc0SXuan Hu
84730cfbc0SXuan Huabstract class SchedulerImpBase(wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters)
85730cfbc0SXuan Hu  extends LazyModuleImp(wrapper)
86730cfbc0SXuan Hu    with HasXSParameter
87730cfbc0SXuan Hu{
88730cfbc0SXuan Hu  val io = IO(new SchedulerIO())
89730cfbc0SXuan Hu
90730cfbc0SXuan Hu  // alias
91730cfbc0SXuan Hu  private val schdType = params.schdType
92730cfbc0SXuan Hu  private val (numRfRead, numRfWrite) = params.numRfReadWrite.getOrElse((0, 0))
93730cfbc0SXuan Hu  private val numPregs = params.numPregs
94730cfbc0SXuan Hu
95730cfbc0SXuan Hu  // Modules
96730cfbc0SXuan Hu  val dispatch2Iq: Dispatch2IqImp = wrapper.dispatch2Iq.module
97730cfbc0SXuan Hu  val issueQueues: Seq[IssueQueueImp] = wrapper.issueQueue.map(_.module)
98730cfbc0SXuan Hu
99730cfbc0SXuan Hu  // BusyTable Modules
100730cfbc0SXuan Hu  val intBusyTable = schdType match {
101730cfbc0SXuan Hu    case IntScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numIntStateRead, wrapper.numIntStateWrite)))
102730cfbc0SXuan Hu    case _ => None
103730cfbc0SXuan Hu  }
104730cfbc0SXuan Hu
105730cfbc0SXuan Hu  val vfBusyTable = schdType match {
106730cfbc0SXuan Hu    case VfScheduler() | MemScheduler() => Some(Module(new BusyTable(dispatch2Iq.numVfStateRead, wrapper.numVfStateWrite)))
107730cfbc0SXuan Hu    case _ => None
108730cfbc0SXuan Hu  }
109730cfbc0SXuan Hu
110730cfbc0SXuan Hu  dispatch2Iq.io match { case dp2iq =>
111730cfbc0SXuan Hu    dp2iq.redirect <> io.fromCtrlBlock.flush
112730cfbc0SXuan Hu    dp2iq.in <> io.fromDispatch.uops
113730cfbc0SXuan Hu    dp2iq.readIntState.foreach(_ <> intBusyTable.get.io.read)
114730cfbc0SXuan Hu    dp2iq.readVfState.foreach(_ <> vfBusyTable.get.io.read)
115730cfbc0SXuan Hu  }
116730cfbc0SXuan Hu
117730cfbc0SXuan Hu  intBusyTable match {
118730cfbc0SXuan Hu    case Some(bt) =>
119730cfbc0SXuan Hu      bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) =>
120730cfbc0SXuan Hu        btAllocPregs.valid := dpAllocPregs.isInt
121730cfbc0SXuan Hu        btAllocPregs.bits := dpAllocPregs.preg
122730cfbc0SXuan Hu      }
123730cfbc0SXuan Hu      bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) =>
124730cfbc0SXuan Hu        wb.valid := io.intWriteBack(i).wen && io.intWriteBack(i).intWen
125730cfbc0SXuan Hu        wb.bits := io.intWriteBack(i).addr
126730cfbc0SXuan Hu      }
127730cfbc0SXuan Hu    case None =>
128730cfbc0SXuan Hu  }
129730cfbc0SXuan Hu
130730cfbc0SXuan Hu  vfBusyTable match {
131730cfbc0SXuan Hu    case Some(bt) =>
132730cfbc0SXuan Hu      bt.io.allocPregs.zip(io.fromDispatch.allocPregs).foreach { case (btAllocPregs, dpAllocPregs) =>
133730cfbc0SXuan Hu        btAllocPregs.valid := dpAllocPregs.isFp
134730cfbc0SXuan Hu        btAllocPregs.bits := dpAllocPregs.preg
135730cfbc0SXuan Hu      }
136730cfbc0SXuan Hu      bt.io.wbPregs.zipWithIndex.foreach { case (wb, i) =>
137730cfbc0SXuan Hu        wb.valid := io.vfWriteBack(i).wen && (io.vfWriteBack(i).fpWen || io.vfWriteBack(i).vecWen)
138730cfbc0SXuan Hu        wb.bits := io.vfWriteBack(i).addr
139730cfbc0SXuan Hu      }
140730cfbc0SXuan Hu    case None =>
141730cfbc0SXuan Hu  }
142730cfbc0SXuan Hu
143730cfbc0SXuan Hu  val wakeupFromWBVec = Wire(Vec(params.numWakeupFromWB, ValidIO(new IssueQueueWakeUpBundle(params.pregIdxWidth))))
144730cfbc0SXuan Hu  val writeback = params.schdType match {
145730cfbc0SXuan Hu    case IntScheduler() => io.intWriteBack
146730cfbc0SXuan Hu    case MemScheduler() => io.intWriteBack ++ io.vfWriteBack
147730cfbc0SXuan Hu    case VfScheduler() => io.vfWriteBack
148730cfbc0SXuan Hu    case _ => Seq()
149730cfbc0SXuan Hu  }
150730cfbc0SXuan Hu  wakeupFromWBVec.zip(writeback).foreach { case (sink, source) =>
151730cfbc0SXuan Hu    sink.valid := source.wen
152730cfbc0SXuan Hu    sink.bits.rfWen := source.intWen
153730cfbc0SXuan Hu    sink.bits.fpWen := source.fpWen
154730cfbc0SXuan Hu    sink.bits.vecWen := source.vecWen
155730cfbc0SXuan Hu    sink.bits.pdest := source.addr
156730cfbc0SXuan Hu  }
157730cfbc0SXuan Hu
158730cfbc0SXuan Hu  io.toDataPath.zipWithIndex.foreach { case (toDp, i) =>
159730cfbc0SXuan Hu    toDp <> issueQueues(i).io.deq
160730cfbc0SXuan Hu  }
161730cfbc0SXuan Hu}
162730cfbc0SXuan Hu
163730cfbc0SXuan Huclass SchedulerArithImp(override val wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters)
164730cfbc0SXuan Hu  extends SchedulerImpBase(wrapper)
165730cfbc0SXuan Hu    with HasXSParameter
166730cfbc0SXuan Hu{
1672e0a7dc5Sfdy//  dontTouch(io.vfWbFuBusyTable)
168730cfbc0SXuan Hu  println(s"[SchedulerArithImp] " +
169730cfbc0SXuan Hu    s"has intBusyTable: ${intBusyTable.nonEmpty}, " +
170730cfbc0SXuan Hu    s"has vfBusyTable: ${vfBusyTable.nonEmpty}")
171730cfbc0SXuan Hu
172730cfbc0SXuan Hu  issueQueues.zipWithIndex.foreach { case (iq, i) =>
173730cfbc0SXuan Hu    iq.io.flush <> io.fromCtrlBlock.flush
174730cfbc0SXuan Hu    iq.io.enq <> dispatch2Iq.io.out(i)
175730cfbc0SXuan Hu    iq.io.wakeup := wakeupFromWBVec
176730cfbc0SXuan Hu    iq.io.deqResp.zipWithIndex.foreach { case (deqResp, j) =>
177ea0f92d8Sczw      deqResp.valid := iq.io.deq(j).valid && io.toDataPath(i)(j).ready
178ea0f92d8Sczw      deqResp.bits.respType := RSFeedbackType.issueSuccess
179730cfbc0SXuan Hu      deqResp.bits.addrOH := iq.io.deq(j).bits.addrOH
1808d29ec32Sczw      deqResp.bits.rfWen := iq.io.deq(j).bits.common.rfWen.getOrElse(false.B)
1818d29ec32Sczw      deqResp.bits.fuType := iq.io.deq(j).bits.common.fuType
1828d29ec32Sczw
183730cfbc0SXuan Hu    }
184730cfbc0SXuan Hu    iq.io.og0Resp.zipWithIndex.foreach { case (og0Resp, j) =>
185730cfbc0SXuan Hu      og0Resp.valid := io.fromDataPath(i)(j).og0resp.valid
186730cfbc0SXuan Hu      og0Resp.bits.respType := io.fromDataPath(i)(j).og0resp.bits.respType
187730cfbc0SXuan Hu      og0Resp.bits.addrOH := io.fromDataPath(i)(j).og0resp.bits.addrOH
1888d29ec32Sczw      og0Resp.bits.rfWen := io.fromDataPath(i)(j).og0resp.bits.rfWen
1898d29ec32Sczw      og0Resp.bits.fuType := io.fromDataPath(i)(j).og0resp.bits.fuType
1908d29ec32Sczw
191730cfbc0SXuan Hu    }
192730cfbc0SXuan Hu    iq.io.og1Resp.zipWithIndex.foreach { case (og1Resp, j) =>
193730cfbc0SXuan Hu      og1Resp.valid := io.fromDataPath(i)(j).og1resp.valid
194730cfbc0SXuan Hu      og1Resp.bits.respType := io.fromDataPath(i)(j).og1resp.bits.respType
195730cfbc0SXuan Hu      og1Resp.bits.addrOH := io.fromDataPath(i)(j).og1resp.bits.addrOH
1968d29ec32Sczw      og1Resp.bits.rfWen := io.fromDataPath(i)(j).og1resp.bits.rfWen
1978d29ec32Sczw      og1Resp.bits.fuType := io.fromDataPath(i)(j).og1resp.bits.fuType
1988d29ec32Sczw
199730cfbc0SXuan Hu    }
2002e0a7dc5Sfdy
2012e0a7dc5Sfdy    iq.io.wbBusyTableRead := io.fromWbFuBusyTable.fuBusyTableRead(i)
202*dd970561SzhanglyGit    io.wbFuBusyTable(i) := iq.io.wbBusyTableWrite
203730cfbc0SXuan Hu  }
204730cfbc0SXuan Hu
205730cfbc0SXuan Hu  val iqJumpBundleVec: Seq[IssueQueueJumpBundle] = issueQueues.map {
206730cfbc0SXuan Hu    case imp: IssueQueueIntImp => imp.io.enqJmp
207730cfbc0SXuan Hu    case _ => None
208730cfbc0SXuan Hu  }.filter(_.nonEmpty).flatMap(_.get)
209730cfbc0SXuan Hu  println(s"[Scheduler] iqJumpBundleVec: ${iqJumpBundleVec}")
210730cfbc0SXuan Hu
211730cfbc0SXuan Hu  iqJumpBundleVec.zip(io.fromCtrlBlock.pcVec zip io.fromCtrlBlock.targetVec).foreach { case (iqJmp, (pc, target)) =>
212730cfbc0SXuan Hu    iqJmp.pc := pc
213730cfbc0SXuan Hu    iqJmp.target := target
214730cfbc0SXuan Hu  }
215730cfbc0SXuan Hu}
216730cfbc0SXuan Hu
217730cfbc0SXuan Huclass SchedulerMemImp(override val wrapper: Scheduler)(implicit params: SchdBlockParams, p: Parameters)
218730cfbc0SXuan Hu  extends SchedulerImpBase(wrapper)
219730cfbc0SXuan Hu    with HasXSParameter
220730cfbc0SXuan Hu{
221730cfbc0SXuan Hu  println(s"[SchedulerMemImp] " +
222730cfbc0SXuan Hu    s"has intBusyTable: ${intBusyTable.nonEmpty}, " +
223730cfbc0SXuan Hu    s"has vfBusyTable: ${vfBusyTable.nonEmpty}")
224730cfbc0SXuan Hu
225730cfbc0SXuan Hu  val memAddrIQs = issueQueues.filter(iq => iq.params.StdCnt == 0)
226730cfbc0SXuan Hu  val stAddrIQs = issueQueues.filter(iq => iq.params.StaCnt > 0) // included in memAddrIQs
2277b753bebSXuan Hu  val ldAddrIQs = issueQueues.filter(iq => iq.params.LduCnt > 0)
228730cfbc0SXuan Hu  val stDataIQs = issueQueues.filter(iq => iq.params.StdCnt > 0)
229730cfbc0SXuan Hu  require(memAddrIQs.nonEmpty && stDataIQs.nonEmpty)
230730cfbc0SXuan Hu
231730cfbc0SXuan Hu  issueQueues.zipWithIndex.foreach { case (iq, i) =>
232730cfbc0SXuan Hu    iq.io.deqResp.zipWithIndex.foreach { case (deqResp, j) =>
233ea0f92d8Sczw      deqResp.valid := iq.io.deq(j).valid && io.toDataPath(i)(j).ready
234ea0f92d8Sczw      deqResp.bits.respType := RSFeedbackType.issueSuccess
235730cfbc0SXuan Hu      deqResp.bits.addrOH := iq.io.deq(j).bits.addrOH
2368d29ec32Sczw      deqResp.bits.rfWen := iq.io.deq(j).bits.common.rfWen.getOrElse(false.B)
2378d29ec32Sczw      deqResp.bits.fuType := iq.io.deq(j).bits.common.fuType
2388d29ec32Sczw
239730cfbc0SXuan Hu    }
240730cfbc0SXuan Hu    iq.io.og0Resp.zipWithIndex.foreach { case (og0Resp, j) =>
241730cfbc0SXuan Hu      og0Resp.valid := io.fromDataPath(i)(j).og0resp.valid
242730cfbc0SXuan Hu      og0Resp.bits.respType := io.fromDataPath(i)(j).og0resp.bits.respType
243730cfbc0SXuan Hu      og0Resp.bits.addrOH := io.fromDataPath(i)(j).og0resp.bits.addrOH
2448d29ec32Sczw      og0Resp.bits.rfWen := io.fromDataPath(i)(j).og0resp.bits.rfWen
2458d29ec32Sczw      og0Resp.bits.fuType := io.fromDataPath(i)(j).og0resp.bits.fuType
2468d29ec32Sczw
247730cfbc0SXuan Hu    }
248730cfbc0SXuan Hu    iq.io.og1Resp.zipWithIndex.foreach { case (og1Resp, j) =>
249730cfbc0SXuan Hu      og1Resp.valid := io.fromDataPath(i)(j).og1resp.valid
250730cfbc0SXuan Hu      og1Resp.bits.respType := io.fromDataPath(i)(j).og1resp.bits.respType
251730cfbc0SXuan Hu      og1Resp.bits.addrOH := io.fromDataPath(i)(j).og1resp.bits.addrOH
2528d29ec32Sczw      og1Resp.bits.rfWen := io.fromDataPath(i)(j).og1resp.bits.rfWen
2538d29ec32Sczw      og1Resp.bits.fuType := io.fromDataPath(i)(j).og1resp.bits.fuType
2548d29ec32Sczw
255730cfbc0SXuan Hu    }
2562e0a7dc5Sfdy    iq.io.wbBusyTableRead := io.fromWbFuBusyTable.fuBusyTableRead(i)
257*dd970561SzhanglyGit    io.wbFuBusyTable(i) := iq.io.wbBusyTableWrite
258730cfbc0SXuan Hu  }
259730cfbc0SXuan Hu
260730cfbc0SXuan Hu  memAddrIQs.zipWithIndex.foreach { case (iq, i) =>
261730cfbc0SXuan Hu    iq.io.flush <> io.fromCtrlBlock.flush
262730cfbc0SXuan Hu    iq.io.enq <> dispatch2Iq.io.out(i)
263730cfbc0SXuan Hu    iq.io.wakeup := wakeupFromWBVec
264730cfbc0SXuan Hu  }
265730cfbc0SXuan Hu
2667b753bebSXuan Hu  ldAddrIQs.foreach {
2677b753bebSXuan Hu    case imp: IssueQueueMemAddrImp => imp.io.memIO.get.feedbackIO <> io.fromMem.get.ldaFeedback
2687b753bebSXuan Hu    case _ =>
2697b753bebSXuan Hu  }
2707b753bebSXuan Hu
2717b753bebSXuan Hu  stAddrIQs.foreach {
2727b753bebSXuan Hu    case imp: IssueQueueMemAddrImp => imp.io.memIO.get.feedbackIO <> io.fromMem.get.staFeedback
2737b753bebSXuan Hu    case _ =>
2747b753bebSXuan Hu  }
275730cfbc0SXuan Hu
276730cfbc0SXuan Hu  dispatch2Iq.io.out(1).zip(stAddrIQs(0).io.enq).zip(stDataIQs(0).io.enq).foreach{ case((di, staIQ), stdIQ) =>
277730cfbc0SXuan Hu    val isAllReady = staIQ.ready && stdIQ.ready
278730cfbc0SXuan Hu    di.ready := isAllReady
279730cfbc0SXuan Hu    staIQ.valid := di.valid && isAllReady
280730cfbc0SXuan Hu    stdIQ.valid := di.valid && isAllReady
281730cfbc0SXuan Hu  }
282730cfbc0SXuan Hu
283730cfbc0SXuan Hu  require(stAddrIQs.size == stDataIQs.size, s"number of store address IQs(${stAddrIQs.size}) " +
284730cfbc0SXuan Hu    s"should be equal to number of data IQs(${stDataIQs})")
285730cfbc0SXuan Hu  stDataIQs.zip(stAddrIQs).zipWithIndex.foreach { case ((stdIQ, staIQ), i) =>
286730cfbc0SXuan Hu    stdIQ.io.flush <> io.fromCtrlBlock.flush
287730cfbc0SXuan Hu
288730cfbc0SXuan Hu    stdIQ.io.enq.zip(staIQ.io.enq).foreach { case (stdIQEnq, staIQEnq) =>
289730cfbc0SXuan Hu      stdIQEnq.bits  := staIQEnq.bits
290730cfbc0SXuan Hu      // Store data reuses store addr src(1) in dispatch2iq
291730cfbc0SXuan Hu      // [dispatch2iq] --src*------src*(0)--> [staIQ]
292730cfbc0SXuan Hu      //                       \
293730cfbc0SXuan Hu      //                        ---src*(1)--> [stdIQ]
294730cfbc0SXuan Hu      // Since the src(1) of sta is easier to get, stdIQEnq.bits.src*(0) is assigned to staIQEnq.bits.src*(1)
295730cfbc0SXuan Hu      // instead of dispatch2Iq.io.out(x).bits.src*(1)
296730cfbc0SXuan Hu      stdIQEnq.bits.srcState(0) := staIQEnq.bits.srcState(1)
297730cfbc0SXuan Hu      stdIQEnq.bits.srcType(0) := staIQEnq.bits.srcType(1)
298730cfbc0SXuan Hu      stdIQEnq.bits.psrc(0) := staIQEnq.bits.psrc(1)
299730cfbc0SXuan Hu      stdIQEnq.bits.sqIdx := staIQEnq.bits.sqIdx
300730cfbc0SXuan Hu    }
301730cfbc0SXuan Hu    stdIQ.io.wakeup := wakeupFromWBVec
302730cfbc0SXuan Hu  }
303730cfbc0SXuan Hu
304730cfbc0SXuan Hu  val lsqEnqCtrl = Module(new LsqEnqCtrl)
305730cfbc0SXuan Hu
306730cfbc0SXuan Hu  lsqEnqCtrl.io.redirect <> io.fromCtrlBlock.flush
307730cfbc0SXuan Hu  lsqEnqCtrl.io.enq <> dispatch2Iq.io.enqLsqIO.get
308730cfbc0SXuan Hu  lsqEnqCtrl.io.lcommit := io.fromMem.get.lcommit
309730cfbc0SXuan Hu  lsqEnqCtrl.io.scommit := io.fromMem.get.scommit
310730cfbc0SXuan Hu  lsqEnqCtrl.io.lqCancelCnt := io.fromMem.get.lqCancelCnt
311730cfbc0SXuan Hu  lsqEnqCtrl.io.sqCancelCnt := io.fromMem.get.sqCancelCnt
312730cfbc0SXuan Hu  io.memIO.get.lsqEnqIO <> lsqEnqCtrl.io.enqLsq
313730cfbc0SXuan Hu}
314