xref: /XiangShan/src/main/scala/xiangshan/backend/CtrlBlock.scala (revision 435a337c2b091f055585f06b3531a16f13112198)
18921b337SYinan Xupackage xiangshan.backend
28921b337SYinan Xu
38921b337SYinan Xuimport chisel3._
48921b337SYinan Xuimport chisel3.util._
521732575SYinan Xuimport utils._
68921b337SYinan Xuimport xiangshan._
72b8b2e7aSWilliam Wangimport xiangshan.backend.decode.{DecodeStage, ImmUnion, WaitTableParameters}
88926ac22SLinJiaweiimport xiangshan.backend.rename.{BusyTable, Rename}
98921b337SYinan Xuimport xiangshan.backend.dispatch.Dispatch
108921b337SYinan Xuimport xiangshan.backend.exu._
11694b0180SLinJiaweiimport xiangshan.backend.exu.Exu.exuConfigs
12884dbb3bSLinJiaweiimport xiangshan.backend.ftq.{Ftq, FtqRead, GetPcByFtq}
138921b337SYinan Xuimport xiangshan.backend.regfile.RfReadPort
143a474d38SYinan Xuimport xiangshan.backend.roq.{Roq, RoqCSRIO, RoqLsqIO, RoqPtr}
15780ade3fSYinan Xuimport xiangshan.mem.LsqEnqIO
168921b337SYinan Xu
178921b337SYinan Xuclass CtrlToIntBlockIO extends XSBundle {
188921b337SYinan Xu  val enqIqCtrl = Vec(exuParameters.IntExuCnt, DecoupledIO(new MicroOp))
198af95560SYinan Xu  val readRf = Vec(NRIntReadPorts, Output(UInt(PhyRegIdxWidth.W)))
208926ac22SLinJiawei  val jumpPc = Output(UInt(VAddrBits.W))
21cde9280dSLinJiawei  val jalr_target = Output(UInt(VAddrBits.W))
2282f87dffSYikeZhou  // int block only uses port 0~7
2382f87dffSYikeZhou  val readPortIndex = Vec(exuParameters.IntExuCnt, Output(UInt(log2Ceil(8 / 2).W))) // TODO parameterize 8 here
2466bcc42fSYinan Xu  val redirect = ValidIO(new Redirect)
252d7c7105SYinan Xu  val flush = Output(Bool())
268921b337SYinan Xu}
278921b337SYinan Xu
288921b337SYinan Xuclass CtrlToFpBlockIO extends XSBundle {
298921b337SYinan Xu  val enqIqCtrl = Vec(exuParameters.FpExuCnt, DecoupledIO(new MicroOp))
308af95560SYinan Xu  val readRf = Vec(NRFpReadPorts, Output(UInt(PhyRegIdxWidth.W)))
3182f87dffSYikeZhou  // fp block uses port 0~11
3282f87dffSYikeZhou  val readPortIndex = Vec(exuParameters.FpExuCnt, Output(UInt(log2Ceil((NRFpReadPorts - exuParameters.StuCnt) / 3).W)))
3366bcc42fSYinan Xu  val redirect = ValidIO(new Redirect)
342d7c7105SYinan Xu  val flush = Output(Bool())
358921b337SYinan Xu}
368921b337SYinan Xu
378921b337SYinan Xuclass CtrlToLsBlockIO extends XSBundle {
388921b337SYinan Xu  val enqIqCtrl = Vec(exuParameters.LsExuCnt, DecoupledIO(new MicroOp))
39780ade3fSYinan Xu  val enqLsq = Flipped(new LsqEnqIO)
402b8b2e7aSWilliam Wang  val waitTableUpdate = Vec(StorePipelineWidth, Input(new WaitTableUpdateReq))
4166bcc42fSYinan Xu  val redirect = ValidIO(new Redirect)
422d7c7105SYinan Xu  val flush = Output(Bool())
438921b337SYinan Xu}
448921b337SYinan Xu
452b8b2e7aSWilliam Wangclass RedirectGenerator extends XSModule with HasCircularQueuePtrHelper with WaitTableParameters {
46dfde261eSljw  val numRedirect = exuParameters.JmpCnt + exuParameters.AluCnt
47884dbb3bSLinJiawei  val io = IO(new Bundle() {
48dfde261eSljw    val exuMispredict = Vec(numRedirect, Flipped(ValidIO(new ExuOutput)))
496c0bbf39Sljw    val loadReplay = Flipped(ValidIO(new Redirect))
509ed972adSLinJiawei    val flush = Input(Bool())
51dfde261eSljw    val stage1FtqRead = Vec(numRedirect + 1, new FtqRead)
5236d7aed5SLinJiawei    val stage2FtqRead = new FtqRead
53884dbb3bSLinJiawei    val stage2Redirect = ValidIO(new Redirect)
54faf3cfa9SLinJiawei    val stage3Redirect = ValidIO(new Redirect)
55dfde261eSljw    val waitTableUpdate = Output(new WaitTableUpdateReq)
56884dbb3bSLinJiawei  })
57884dbb3bSLinJiawei  /*
58884dbb3bSLinJiawei        LoadQueue  Jump  ALU0  ALU1  ALU2  ALU3   exception    Stage1
59884dbb3bSLinJiawei          |         |      |    |     |     |         |
60faf3cfa9SLinJiawei          |============= reg & compare =====|         |       ========
6136d7aed5SLinJiawei                            |                         |
6236d7aed5SLinJiawei                            |                         |
6336d7aed5SLinJiawei                            |                         |        Stage2
64884dbb3bSLinJiawei                            |                         |
65884dbb3bSLinJiawei                    redirect (flush backend)          |
66884dbb3bSLinJiawei                    |                                 |
67884dbb3bSLinJiawei               === reg ===                            |       ========
68884dbb3bSLinJiawei                    |                                 |
69884dbb3bSLinJiawei                    |----- mux (exception first) -----|        Stage3
70884dbb3bSLinJiawei                            |
71884dbb3bSLinJiawei                redirect (send to frontend)
72884dbb3bSLinJiawei   */
73dfde261eSljw  private class Wrapper(val n: Int) extends Bundle {
74dfde261eSljw    val redirect = new Redirect
75dfde261eSljw    val valid = Bool()
76dfde261eSljw    val idx = UInt(log2Up(n).W)
77dfde261eSljw  }
78*435a337cSYinan Xu  def selectOldestRedirect(xs: Seq[Valid[Redirect]]): Vec[Bool] = {
79*435a337cSYinan Xu    val compareVec = (0 until xs.length).map(i => (0 until i).map(j => isAfter(xs(j).bits.roqIdx, xs(i).bits.roqIdx)))
80*435a337cSYinan Xu    val resultOnehot = VecInit((0 until xs.length).map(i => Cat((0 until xs.length).map(j =>
81*435a337cSYinan Xu      (if (j < i) !xs(j).valid || compareVec(i)(j)
82*435a337cSYinan Xu      else if (j == i) xs(i).valid
83*435a337cSYinan Xu      else !xs(j).valid || !compareVec(j)(i))
84*435a337cSYinan Xu    )).andR))
85*435a337cSYinan Xu    resultOnehot
86dfde261eSljw  }
87faf3cfa9SLinJiawei
88dfde261eSljw  for((ptr, redirect) <- io.stage1FtqRead.map(_.ptr).zip(
89dfde261eSljw    io.exuMispredict.map(_.bits.redirect) :+ io.loadReplay.bits
90dfde261eSljw  )){ ptr := redirect.ftqIdx }
91f7f707b0SLinJiawei
92dfde261eSljw  def getRedirect(exuOut: Valid[ExuOutput]): ValidIO[Redirect] = {
93dfde261eSljw    val redirect = Wire(Valid(new Redirect))
94dfde261eSljw    redirect.valid := exuOut.valid && exuOut.bits.redirect.cfiUpdate.isMisPred
95dfde261eSljw    redirect.bits := exuOut.bits.redirect
96dfde261eSljw    redirect
97dfde261eSljw  }
98dfde261eSljw
99dfde261eSljw  val jumpOut = io.exuMispredict.head
100*435a337cSYinan Xu  val allRedirect = VecInit(io.exuMispredict.map(x => getRedirect(x)) :+ io.loadReplay)
101*435a337cSYinan Xu  val oldestOneHot = selectOldestRedirect(allRedirect)
102*435a337cSYinan Xu  val needFlushVec = VecInit(allRedirect.map(_.bits.roqIdx.needFlush(io.stage2Redirect, io.flush)))
103*435a337cSYinan Xu  val oldestValid = VecInit(oldestOneHot.zip(needFlushVec).map{ case (v, f) => v && !f }).asUInt.orR
104*435a337cSYinan Xu  val oldestExuOutput = Mux1H((0 until 5).map(oldestOneHot), io.exuMispredict)
105*435a337cSYinan Xu  val oldestRedirect = Mux1H(oldestOneHot, allRedirect)
106dfde261eSljw
1076060732cSLinJiawei  val s1_jumpTarget = RegEnable(jumpOut.bits.redirect.cfiUpdate.target, jumpOut.valid)
108*435a337cSYinan Xu  val s1_imm12_reg = RegNext(oldestExuOutput.bits.uop.ctrl.imm(11, 0))
109*435a337cSYinan Xu  val s1_pd = RegNext(oldestExuOutput.bits.uop.cf.pd)
110*435a337cSYinan Xu  val s1_redirect_bits_reg = RegNext(oldestRedirect.bits)
111*435a337cSYinan Xu  val s1_redirect_valid_reg = RegNext(oldestValid)
112*435a337cSYinan Xu  val s1_redirect_onehot = RegNext(oldestOneHot)
113faf3cfa9SLinJiawei
114faf3cfa9SLinJiawei  // stage1 -> stage2
11527c1214eSLinJiawei  io.stage2Redirect.valid := s1_redirect_valid_reg && !io.flush
116faf3cfa9SLinJiawei  io.stage2Redirect.bits := s1_redirect_bits_reg
117faf3cfa9SLinJiawei  io.stage2Redirect.bits.cfiUpdate := DontCare
118faf3cfa9SLinJiawei  // at stage2, we read ftq to get pc
119faf3cfa9SLinJiawei  io.stage2FtqRead.ptr := s1_redirect_bits_reg.ftqIdx
120faf3cfa9SLinJiawei
121*435a337cSYinan Xu  val s1_isReplay = s1_redirect_onehot(5)
122*435a337cSYinan Xu  val s1_isJump = s1_redirect_onehot(0)
123*435a337cSYinan Xu  val ftqRead = Mux1H(s1_redirect_onehot, io.stage1FtqRead).entry
124dfde261eSljw  val cfiUpdate_pc = Cat(
125dfde261eSljw    ftqRead.ftqPC.head(VAddrBits - s1_redirect_bits_reg.ftqOffset.getWidth - instOffsetBits),
126dfde261eSljw    s1_redirect_bits_reg.ftqOffset,
127dfde261eSljw    0.U(instOffsetBits.W)
128dfde261eSljw  )
129dfde261eSljw  val real_pc = GetPcByFtq(ftqRead.ftqPC, s1_redirect_bits_reg.ftqOffset,
13001f25297SLingrui98    ftqRead.lastPacketPC.valid,
131dfde261eSljw    ftqRead.lastPacketPC.bits
132dfde261eSljw  )
133dfde261eSljw  val brTarget = real_pc + SignExt(ImmUnion.B.toImm32(s1_imm12_reg), XLEN)
134dfde261eSljw  val snpc = real_pc + Mux(s1_pd.isRVC, 2.U, 4.U)
135*435a337cSYinan Xu  val target = Mux(s1_isReplay,
13601f25297SLingrui98    real_pc, // repaly from itself
137dfde261eSljw    Mux(s1_redirect_bits_reg.cfiUpdate.taken,
138dfde261eSljw      Mux(s1_isJump, s1_jumpTarget, brTarget),
1396060732cSLinJiawei      snpc
140faf3cfa9SLinJiawei    )
141faf3cfa9SLinJiawei  )
1422b8b2e7aSWilliam Wang
1432b8b2e7aSWilliam Wang  // update waittable if load violation redirect triggered
144*435a337cSYinan Xu  io.waitTableUpdate.valid := RegNext(s1_isReplay && s1_redirect_valid_reg, init = false.B)
145dfde261eSljw  io.waitTableUpdate.waddr := RegNext(XORFold(real_pc(VAddrBits-1, 1), WaitTableAddrWidth))
1462b8b2e7aSWilliam Wang  io.waitTableUpdate.wdata := true.B
1472b8b2e7aSWilliam Wang
148dfde261eSljw  io.stage2FtqRead.ptr := s1_redirect_bits_reg.ftqIdx
149dfde261eSljw
15009348ee5Sljw  val s2_br_mask = RegEnable(ftqRead.br_mask, enable = s1_redirect_valid_reg)
15109348ee5Sljw  val s2_sawNotTakenBranch = RegEnable(VecInit((0 until PredictWidth).map{ i =>
15209348ee5Sljw      if(i == 0) false.B else Cat(ftqRead.br_mask.take(i)).orR()
15309348ee5Sljw    })(s1_redirect_bits_reg.ftqOffset), enable = s1_redirect_valid_reg)
15409348ee5Sljw  val s2_hist = RegEnable(ftqRead.hist, enable = s1_redirect_valid_reg)
155dfde261eSljw  val s2_target = RegEnable(target, enable = s1_redirect_valid_reg)
156dfde261eSljw  val s2_pd = RegEnable(s1_pd, enable = s1_redirect_valid_reg)
157dfde261eSljw  val s2_cfiUpdata_pc = RegEnable(cfiUpdate_pc, enable = s1_redirect_valid_reg)
158dfde261eSljw  val s2_redirect_bits_reg = RegEnable(s1_redirect_bits_reg, enable = s1_redirect_valid_reg)
159dfde261eSljw  val s2_redirect_valid_reg = RegNext(s1_redirect_valid_reg && !io.flush, init = false.B)
160dfde261eSljw  val s2_ftqRead = io.stage2FtqRead.entry
161dfde261eSljw
162faf3cfa9SLinJiawei  io.stage3Redirect.valid := s2_redirect_valid_reg
163faf3cfa9SLinJiawei  io.stage3Redirect.bits := s2_redirect_bits_reg
164faf3cfa9SLinJiawei  val stage3CfiUpdate = io.stage3Redirect.bits.cfiUpdate
165dfde261eSljw  stage3CfiUpdate.pc := s2_cfiUpdata_pc
166faf3cfa9SLinJiawei  stage3CfiUpdate.pd := s2_pd
167dfde261eSljw  stage3CfiUpdate.rasSp := s2_ftqRead.rasSp
168dfde261eSljw  stage3CfiUpdate.rasEntry := s2_ftqRead.rasTop
169dfde261eSljw  stage3CfiUpdate.predHist := s2_ftqRead.predHist
170dfde261eSljw  stage3CfiUpdate.specCnt := s2_ftqRead.specCnt
17109348ee5Sljw  stage3CfiUpdate.hist := s2_hist
172cde9280dSLinJiawei  stage3CfiUpdate.predTaken := s2_redirect_bits_reg.cfiUpdate.predTaken
17309348ee5Sljw  stage3CfiUpdate.sawNotTakenBranch := s2_sawNotTakenBranch
174dfde261eSljw  stage3CfiUpdate.target := s2_target
175faf3cfa9SLinJiawei  stage3CfiUpdate.taken := s2_redirect_bits_reg.cfiUpdate.taken
176faf3cfa9SLinJiawei  stage3CfiUpdate.isMisPred := s2_redirect_bits_reg.cfiUpdate.isMisPred
177884dbb3bSLinJiawei}
178884dbb3bSLinJiawei
17921732575SYinan Xuclass CtrlBlock extends XSModule with HasCircularQueuePtrHelper {
1808921b337SYinan Xu  val io = IO(new Bundle {
1818921b337SYinan Xu    val frontend = Flipped(new FrontendToBackendIO)
1828921b337SYinan Xu    val fromIntBlock = Flipped(new IntBlockToCtrlIO)
1838921b337SYinan Xu    val fromFpBlock = Flipped(new FpBlockToCtrlIO)
1848921b337SYinan Xu    val fromLsBlock = Flipped(new LsBlockToCtrlIO)
1858921b337SYinan Xu    val toIntBlock = new CtrlToIntBlockIO
1868921b337SYinan Xu    val toFpBlock = new CtrlToFpBlockIO
1878921b337SYinan Xu    val toLsBlock = new CtrlToLsBlockIO
1881c2588aaSYinan Xu    val roqio = new Bundle {
1891c2588aaSYinan Xu      // to int block
1901c2588aaSYinan Xu      val toCSR = new RoqCSRIO
1913a474d38SYinan Xu      val exception = ValidIO(new ExceptionInfo)
1921c2588aaSYinan Xu      // to mem block
19310aac6e7SWilliam Wang      val lsq = new RoqLsqIO
1941c2588aaSYinan Xu    }
1952b8b2e7aSWilliam Wang    val csrCtrl = Input(new CustomCSRCtrlIO)
1968921b337SYinan Xu  })
1978921b337SYinan Xu
198a165bd69Swangkaifan  val difftestIO = IO(new Bundle() {
199a165bd69Swangkaifan    val fromRoq = new Bundle() {
200a165bd69Swangkaifan      val commit = Output(UInt(32.W))
201a165bd69Swangkaifan      val thisPC = Output(UInt(XLEN.W))
202a165bd69Swangkaifan      val thisINST = Output(UInt(32.W))
203a165bd69Swangkaifan      val skip = Output(UInt(32.W))
204a165bd69Swangkaifan      val wen = Output(UInt(32.W))
205a165bd69Swangkaifan      val wdata = Output(Vec(CommitWidth, UInt(XLEN.W))) // set difftest width to 6
206a165bd69Swangkaifan      val wdst = Output(Vec(CommitWidth, UInt(32.W))) // set difftest width to 6
207a165bd69Swangkaifan      val wpc = Output(Vec(CommitWidth, UInt(XLEN.W))) // set difftest width to 6
208a165bd69Swangkaifan      val isRVC = Output(UInt(32.W))
209a165bd69Swangkaifan      val scFailed = Output(Bool())
21007635e87Swangkaifan      val lpaddr = Output(Vec(CommitWidth, UInt(64.W)))
21107635e87Swangkaifan      val ltype = Output(Vec(CommitWidth, UInt(32.W)))
21207635e87Swangkaifan      val lfu = Output(Vec(CommitWidth, UInt(4.W)))
213a165bd69Swangkaifan    }
214a165bd69Swangkaifan  })
215a165bd69Swangkaifan  difftestIO <> DontCare
216a165bd69Swangkaifan
217884dbb3bSLinJiawei  val ftq = Module(new Ftq)
21854bc08adSwangkaifan  val trapIO = IO(new TrapIO())
21954bc08adSwangkaifan  trapIO <> DontCare
22054bc08adSwangkaifan
2218921b337SYinan Xu  val decode = Module(new DecodeStage)
2228921b337SYinan Xu  val rename = Module(new Rename)
223694b0180SLinJiawei  val dispatch = Module(new Dispatch)
2243fae98acSYinan Xu  val intBusyTable = Module(new BusyTable(NRIntReadPorts, NRIntWritePorts))
2253fae98acSYinan Xu  val fpBusyTable = Module(new BusyTable(NRFpReadPorts, NRFpWritePorts))
226884dbb3bSLinJiawei  val redirectGen = Module(new RedirectGenerator)
2278921b337SYinan Xu
228884dbb3bSLinJiawei  val roqWbSize = NRIntWritePorts + NRFpWritePorts + exuParameters.StuCnt
229694b0180SLinJiawei  val roq = Module(new Roq(roqWbSize))
2308921b337SYinan Xu
231884dbb3bSLinJiawei  val backendRedirect = redirectGen.io.stage2Redirect
232faf3cfa9SLinJiawei  val frontendRedirect = redirectGen.io.stage3Redirect
2332d7c7105SYinan Xu  val flush = roq.io.flushOut.valid
234bbd262adSLinJiawei  val flushReg = RegNext(flush)
235faf3cfa9SLinJiawei
236dfde261eSljw  val exuRedirect = io.fromIntBlock.exuRedirect.map(x => {
237dfde261eSljw    val valid = x.valid && x.bits.redirectValid
238dfde261eSljw    val killedByOlder = x.bits.uop.roqIdx.needFlush(backendRedirect, flushReg)
239dfde261eSljw    val delayed = Wire(Valid(new ExuOutput))
240dfde261eSljw    delayed.valid := RegNext(valid && !killedByOlder, init = false.B)
241dfde261eSljw    delayed.bits := RegEnable(x.bits, x.valid)
242dfde261eSljw    delayed
243faf3cfa9SLinJiawei  })
244c1b37c81Sljw  val loadReplay = Wire(Valid(new Redirect))
245c1b37c81Sljw  loadReplay.valid := RegNext(io.fromLsBlock.replay.valid &&
246c1b37c81Sljw    !io.fromLsBlock.replay.bits.roqIdx.needFlush(backendRedirect, flushReg),
247c1b37c81Sljw    init = false.B
248c1b37c81Sljw  )
249c1b37c81Sljw  loadReplay.bits := RegEnable(io.fromLsBlock.replay.bits, io.fromLsBlock.replay.valid)
250dfde261eSljw  VecInit(ftq.io.ftqRead.tail.dropRight(1)) <> redirectGen.io.stage1FtqRead
251dfde261eSljw  ftq.io.cfiRead <> redirectGen.io.stage2FtqRead
252dfde261eSljw  redirectGen.io.exuMispredict <> exuRedirect
253c1b37c81Sljw  redirectGen.io.loadReplay <> loadReplay
254bbd262adSLinJiawei  redirectGen.io.flush := flushReg
2558921b337SYinan Xu
256884dbb3bSLinJiawei  ftq.io.enq <> io.frontend.fetchInfo
257884dbb3bSLinJiawei  for(i <- 0 until CommitWidth){
2586060732cSLinJiawei    ftq.io.roq_commits(i).valid := roq.io.commits.valid(i) && !roq.io.commits.isWalk
259884dbb3bSLinJiawei    ftq.io.roq_commits(i).bits := roq.io.commits.info(i)
260884dbb3bSLinJiawei  }
261884dbb3bSLinJiawei  ftq.io.redirect <> backendRedirect
262bbd262adSLinJiawei  ftq.io.flush := flushReg
263bbd262adSLinJiawei  ftq.io.flushIdx := RegNext(roq.io.flushOut.bits.ftqIdx)
264bbd262adSLinJiawei  ftq.io.flushOffset := RegNext(roq.io.flushOut.bits.ftqOffset)
265faf3cfa9SLinJiawei  ftq.io.frontendRedirect <> frontendRedirect
266dfde261eSljw  ftq.io.exuWriteback <> exuRedirect
267884dbb3bSLinJiawei
268dfde261eSljw  ftq.io.ftqRead.last.ptr := roq.io.flushOut.bits.ftqIdx
2699ed972adSLinJiawei  val flushPC = GetPcByFtq(
270dfde261eSljw    ftq.io.ftqRead.last.entry.ftqPC,
2719ed972adSLinJiawei    RegEnable(roq.io.flushOut.bits.ftqOffset, roq.io.flushOut.valid),
272dfde261eSljw    ftq.io.ftqRead.last.entry.lastPacketPC.valid,
273dfde261eSljw    ftq.io.ftqRead.last.entry.lastPacketPC.bits
2749ed972adSLinJiawei  )
275884dbb3bSLinJiawei
2769ed972adSLinJiawei  val flushRedirect = Wire(Valid(new Redirect))
277bbd262adSLinJiawei  flushRedirect.valid := flushReg
2789ed972adSLinJiawei  flushRedirect.bits := DontCare
2799ed972adSLinJiawei  flushRedirect.bits.ftqIdx := RegEnable(roq.io.flushOut.bits.ftqIdx, flush)
2809ed972adSLinJiawei  flushRedirect.bits.interrupt := true.B
281ac5a5d53SLinJiawei  flushRedirect.bits.cfiUpdate.target := Mux(io.roqio.toCSR.isXRet || roq.io.exception.valid,
282ac5a5d53SLinJiawei    io.roqio.toCSR.trapTarget,
283ac5a5d53SLinJiawei    flushPC + 4.U // flush pipe
2849ed972adSLinJiawei  )
285c1b37c81Sljw  val flushRedirectReg = Wire(Valid(new Redirect))
286c1b37c81Sljw  flushRedirectReg.valid := RegNext(flushRedirect.valid, init = false.B)
287c1b37c81Sljw  flushRedirectReg.bits := RegEnable(flushRedirect.bits, enable = flushRedirect.valid)
2889ed972adSLinJiawei
289c1b37c81Sljw  io.frontend.redirect_cfiUpdate := Mux(flushRedirectReg.valid, flushRedirectReg, frontendRedirect)
29003380706SLinJiawei  io.frontend.commit_cfiUpdate := ftq.io.commit_ftqEntry
291fc4776e4SLinJiawei  io.frontend.ftqEnqPtr := ftq.io.enqPtr
292fc4776e4SLinJiawei  io.frontend.ftqLeftOne := ftq.io.leftOne
29366bcc42fSYinan Xu
2948921b337SYinan Xu  decode.io.in <> io.frontend.cfVec
2952b8b2e7aSWilliam Wang  // currently, we only update wait table when isReplay
2962b8b2e7aSWilliam Wang  decode.io.waitTableUpdate(0) <> RegNext(redirectGen.io.waitTableUpdate)
2972b8b2e7aSWilliam Wang  decode.io.waitTableUpdate(1) := DontCare
2982b8b2e7aSWilliam Wang  decode.io.waitTableUpdate(1).valid := false.B
2992b8b2e7aSWilliam Wang  // decode.io.waitTableUpdate <> io.toLsBlock.waitTableUpdate
3002b8b2e7aSWilliam Wang  decode.io.csrCtrl := RegNext(io.csrCtrl)
3012b8b2e7aSWilliam Wang
3028921b337SYinan Xu
303884dbb3bSLinJiawei  val jumpInst = dispatch.io.enqIQCtrl(0).bits
3046060732cSLinJiawei  val ftqOffsetReg = Reg(UInt(log2Up(PredictWidth).W))
3056060732cSLinJiawei  ftqOffsetReg := jumpInst.cf.ftqOffset
306884dbb3bSLinJiawei  ftq.io.ftqRead(0).ptr := jumpInst.cf.ftqPtr // jump
3077aa94463SLinJiawei  io.toIntBlock.jumpPc := GetPcByFtq(
3081670d147SLingrui98    ftq.io.ftqRead(0).entry.ftqPC, ftqOffsetReg,
3091670d147SLingrui98    ftq.io.ftqRead(0).entry.lastPacketPC.valid,
3101670d147SLingrui98    ftq.io.ftqRead(0).entry.lastPacketPC.bits
3117aa94463SLinJiawei  )
312148ba860SLinJiawei  io.toIntBlock.jalr_target := ftq.io.ftqRead(0).entry.target
3130412e00dSLinJiawei
314b424051cSYinan Xu  // pipeline between decode and dispatch
315b424051cSYinan Xu  for (i <- 0 until RenameWidth) {
316884dbb3bSLinJiawei    PipelineConnect(decode.io.out(i), rename.io.in(i), rename.io.in(i).ready,
317c1b37c81Sljw      flushReg || io.frontend.redirect_cfiUpdate.valid)
318b424051cSYinan Xu  }
3198921b337SYinan Xu
320884dbb3bSLinJiawei  rename.io.redirect <> backendRedirect
321bbd262adSLinJiawei  rename.io.flush := flushReg
3228921b337SYinan Xu  rename.io.roqCommits <> roq.io.commits
3238921b337SYinan Xu  rename.io.out <> dispatch.io.fromRename
32499b8dc2cSYinan Xu  rename.io.renameBypass <> dispatch.io.renameBypass
325049559e7SYinan Xu  rename.io.dispatchInfo <> dispatch.io.preDpInfo
3268921b337SYinan Xu
327884dbb3bSLinJiawei  dispatch.io.redirect <> backendRedirect
328bbd262adSLinJiawei  dispatch.io.flush := flushReg
32921b47d38SYinan Xu  dispatch.io.enqRoq <> roq.io.enq
33008fafef0SYinan Xu  dispatch.io.enqLsq <> io.toLsBlock.enqLsq
3312bb6eba1SYinan Xu  dispatch.io.readIntRf <> io.toIntBlock.readRf
3322bb6eba1SYinan Xu  dispatch.io.readFpRf <> io.toFpBlock.readRf
3333fae98acSYinan Xu  dispatch.io.allocPregs.zipWithIndex.foreach { case (preg, i) =>
3343fae98acSYinan Xu    intBusyTable.io.allocPregs(i).valid := preg.isInt
3351c931a03SYinan Xu    fpBusyTable.io.allocPregs(i).valid := preg.isFp
3363fae98acSYinan Xu    intBusyTable.io.allocPregs(i).bits := preg.preg
3373fae98acSYinan Xu    fpBusyTable.io.allocPregs(i).bits := preg.preg
3383fae98acSYinan Xu  }
3398921b337SYinan Xu  dispatch.io.numExist <> io.fromIntBlock.numExist ++ io.fromFpBlock.numExist ++ io.fromLsBlock.numExist
3402bb6eba1SYinan Xu  dispatch.io.enqIQCtrl <> io.toIntBlock.enqIqCtrl ++ io.toFpBlock.enqIqCtrl ++ io.toLsBlock.enqIqCtrl
34176e1d2a4SYikeZhou//  dispatch.io.enqIQData <> io.toIntBlock.enqIqData ++ io.toFpBlock.enqIqData ++ io.toLsBlock.enqIqData
3428921b337SYinan Xu
3430412e00dSLinJiawei
344bbd262adSLinJiawei  fpBusyTable.io.flush := flushReg
345bbd262adSLinJiawei  intBusyTable.io.flush := flushReg
3463fae98acSYinan Xu  for((wb, setPhyRegRdy) <- io.fromIntBlock.wbRegs.zip(intBusyTable.io.wbPregs)){
3471e2ad30cSYinan Xu    setPhyRegRdy.valid := wb.valid && wb.bits.uop.ctrl.rfWen
3483fae98acSYinan Xu    setPhyRegRdy.bits := wb.bits.uop.pdest
3493fae98acSYinan Xu  }
3503fae98acSYinan Xu  for((wb, setPhyRegRdy) <- io.fromFpBlock.wbRegs.zip(fpBusyTable.io.wbPregs)){
3513fae98acSYinan Xu    setPhyRegRdy.valid := wb.valid && wb.bits.uop.ctrl.fpWen
3523fae98acSYinan Xu    setPhyRegRdy.bits := wb.bits.uop.pdest
3533fae98acSYinan Xu  }
3548af95560SYinan Xu  intBusyTable.io.read <> dispatch.io.readIntState
3558af95560SYinan Xu  fpBusyTable.io.read <> dispatch.io.readFpState
3563fae98acSYinan Xu
357884dbb3bSLinJiawei  roq.io.redirect <> backendRedirect
358c1b37c81Sljw  val exeWbResults = VecInit(io.fromIntBlock.wbRegs ++ io.fromFpBlock.wbRegs ++ io.fromLsBlock.stOut)
359c1b37c81Sljw  for((roq_wb, wb) <- roq.io.exeWbResults.zip(exeWbResults)) {
360c1b37c81Sljw    roq_wb.valid := RegNext(wb.valid && !wb.bits.uop.roqIdx.needFlush(backendRedirect, flushReg))
361c1b37c81Sljw    roq_wb.bits := RegNext(wb.bits)
362c1b37c81Sljw  }
3630412e00dSLinJiawei
364884dbb3bSLinJiawei  // TODO: is 'backendRedirect' necesscary?
365884dbb3bSLinJiawei  io.toIntBlock.redirect <> backendRedirect
366bbd262adSLinJiawei  io.toIntBlock.flush <> flushReg
367884dbb3bSLinJiawei  io.toFpBlock.redirect <> backendRedirect
368bbd262adSLinJiawei  io.toFpBlock.flush <> flushReg
369884dbb3bSLinJiawei  io.toLsBlock.redirect <> backendRedirect
370bbd262adSLinJiawei  io.toLsBlock.flush <> flushReg
3710412e00dSLinJiawei
3723d499721Swangkaifan  if (!env.FPGAPlatform) {
373a165bd69Swangkaifan    difftestIO.fromRoq <> roq.difftestIO
37454bc08adSwangkaifan    trapIO <> roq.trapIO
375a165bd69Swangkaifan  }
376a165bd69Swangkaifan
3779916fbd7SYikeZhou  dispatch.io.readPortIndex.intIndex <> io.toIntBlock.readPortIndex
3789916fbd7SYikeZhou  dispatch.io.readPortIndex.fpIndex <> io.toFpBlock.readPortIndex
3799916fbd7SYikeZhou
3801c2588aaSYinan Xu  // roq to int block
3811c2588aaSYinan Xu  io.roqio.toCSR <> roq.io.csr
3822d7c7105SYinan Xu  io.roqio.exception := roq.io.exception
3839ed972adSLinJiawei  io.roqio.exception.bits.uop.cf.pc := flushPC
3841c2588aaSYinan Xu  // roq to mem block
38510aac6e7SWilliam Wang  io.roqio.lsq <> roq.io.lsq
3868921b337SYinan Xu}
387