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 } 78dfde261eSljw def selectOldestRedirect(xs: Seq[Valid[Redirect]]): (Valid[Redirect], UInt) = { 79dfde261eSljw val wrappers = for((r, i) <- xs.zipWithIndex) yield { 80dfde261eSljw val wrap = Wire(new Wrapper(xs.size)) 81dfde261eSljw wrap.redirect := r.bits 82dfde261eSljw wrap.valid := r.valid 83dfde261eSljw wrap.idx := i.U 84dfde261eSljw wrap 85dfde261eSljw } 86dfde261eSljw val oldest = ParallelOperation[Wrapper](wrappers, (x, y) => { 876060732cSLinJiawei Mux(x.valid, 88dfde261eSljw Mux(y.valid, Mux(isAfter(x.redirect.roqIdx, y.redirect.roqIdx), y, x), x), y 896060732cSLinJiawei ) 90faf3cfa9SLinJiawei }) 91dfde261eSljw val result = Wire(Valid(new Redirect)) 92dfde261eSljw result.valid := oldest.valid 93dfde261eSljw result.bits := oldest.redirect 94dfde261eSljw (result, oldest.idx) 95dfde261eSljw } 96faf3cfa9SLinJiawei 97dfde261eSljw for((ptr, redirect) <- io.stage1FtqRead.map(_.ptr).zip( 98dfde261eSljw io.exuMispredict.map(_.bits.redirect) :+ io.loadReplay.bits 99dfde261eSljw )){ ptr := redirect.ftqIdx } 100f7f707b0SLinJiawei 101dfde261eSljw def getRedirect(exuOut: Valid[ExuOutput]): ValidIO[Redirect] = { 102dfde261eSljw val redirect = Wire(Valid(new Redirect)) 103dfde261eSljw redirect.valid := exuOut.valid && exuOut.bits.redirect.cfiUpdate.isMisPred 104dfde261eSljw redirect.bits := exuOut.bits.redirect 105dfde261eSljw redirect 106dfde261eSljw } 107dfde261eSljw 108dfde261eSljw val jumpOut = io.exuMispredict.head 109dfde261eSljw val aluOut = VecInit(io.exuMispredict.tail) 110dfde261eSljw val (oldestAluRedirect, oldestAluIdx) = selectOldestRedirect(aluOut.map(getRedirect)) 111dfde261eSljw val (oldestExuRedirect, jumpIsOlder) = selectOldestRedirect(Seq( 112dfde261eSljw oldestAluRedirect, getRedirect(jumpOut) 113dfde261eSljw )) 114dfde261eSljw val oldestExuOutput = Mux(jumpIsOlder.asBool(), jumpOut, aluOut(oldestAluIdx)) 115dfde261eSljw val (oldestRedirect, _) = selectOldestRedirect(Seq(io.loadReplay, oldestExuRedirect)) 116dfde261eSljw 117dfde261eSljw val s1_isJump = RegNext(jumpIsOlder.asBool(), init = false.B) 1186060732cSLinJiawei val s1_jumpTarget = RegEnable(jumpOut.bits.redirect.cfiUpdate.target, jumpOut.valid) 119dfde261eSljw val s1_imm12_reg = RegEnable(oldestExuOutput.bits.uop.ctrl.imm(11, 0), oldestExuOutput.valid) 120dfde261eSljw val s1_pd = RegEnable(oldestExuOutput.bits.uop.cf.pd, oldestExuOutput.valid) 121faf3cfa9SLinJiawei val s1_redirect_bits_reg = Reg(new Redirect) 122faf3cfa9SLinJiawei val s1_redirect_valid_reg = RegInit(false.B) 123dfde261eSljw val s1_aluIdx = RegEnable(oldestAluIdx, oldestAluRedirect.valid) 124faf3cfa9SLinJiawei 125faf3cfa9SLinJiawei // stage1 -> stage2 126dfde261eSljw when(oldestRedirect.valid && !oldestRedirect.bits.roqIdx.needFlush(io.stage2Redirect, io.flush)){ 127dfde261eSljw s1_redirect_bits_reg := oldestRedirect.bits 128faf3cfa9SLinJiawei s1_redirect_valid_reg := true.B 129faf3cfa9SLinJiawei }.otherwise({ 130faf3cfa9SLinJiawei s1_redirect_valid_reg := false.B 131faf3cfa9SLinJiawei }) 13227c1214eSLinJiawei io.stage2Redirect.valid := s1_redirect_valid_reg && !io.flush 133faf3cfa9SLinJiawei io.stage2Redirect.bits := s1_redirect_bits_reg 134faf3cfa9SLinJiawei io.stage2Redirect.bits.cfiUpdate := DontCare 135faf3cfa9SLinJiawei // at stage2, we read ftq to get pc 136faf3cfa9SLinJiawei io.stage2FtqRead.ptr := s1_redirect_bits_reg.ftqIdx 137faf3cfa9SLinJiawei 138dfde261eSljw val isReplay = RedirectLevel.flushItself(s1_redirect_bits_reg.level) 139dfde261eSljw val ftqRead = Mux(isReplay, 140dfde261eSljw io.stage1FtqRead.last.entry, 141dfde261eSljw Mux( 142dfde261eSljw s1_isJump, 143dfde261eSljw io.stage1FtqRead.head.entry, 144dfde261eSljw VecInit(io.stage1FtqRead.tail.take(exuParameters.AluCnt).map(_.entry))(s1_aluIdx) 145dfde261eSljw ) 146dfde261eSljw ) 147dfde261eSljw val cfiUpdate_pc = Cat( 148dfde261eSljw ftqRead.ftqPC.head(VAddrBits - s1_redirect_bits_reg.ftqOffset.getWidth - instOffsetBits), 149dfde261eSljw s1_redirect_bits_reg.ftqOffset, 150dfde261eSljw 0.U(instOffsetBits.W) 151dfde261eSljw ) 152dfde261eSljw val real_pc = GetPcByFtq(ftqRead.ftqPC, s1_redirect_bits_reg.ftqOffset, 15301f25297SLingrui98 ftqRead.lastPacketPC.valid, 154dfde261eSljw ftqRead.lastPacketPC.bits 155dfde261eSljw ) 156dfde261eSljw val brTarget = real_pc + SignExt(ImmUnion.B.toImm32(s1_imm12_reg), XLEN) 157dfde261eSljw val snpc = real_pc + Mux(s1_pd.isRVC, 2.U, 4.U) 158faf3cfa9SLinJiawei val target = Mux(isReplay, 15901f25297SLingrui98 real_pc, // repaly from itself 160dfde261eSljw Mux(s1_redirect_bits_reg.cfiUpdate.taken, 161dfde261eSljw Mux(s1_isJump, s1_jumpTarget, brTarget), 1626060732cSLinJiawei snpc 163faf3cfa9SLinJiawei ) 164faf3cfa9SLinJiawei ) 1652b8b2e7aSWilliam Wang 1662b8b2e7aSWilliam Wang // update waittable if load violation redirect triggered 167dfde261eSljw io.waitTableUpdate.valid := RegNext(isReplay && s1_redirect_valid_reg, init = false.B) 168dfde261eSljw io.waitTableUpdate.waddr := RegNext(XORFold(real_pc(VAddrBits-1, 1), WaitTableAddrWidth)) 1692b8b2e7aSWilliam Wang io.waitTableUpdate.wdata := true.B 1702b8b2e7aSWilliam Wang 171dfde261eSljw io.stage2FtqRead.ptr := s1_redirect_bits_reg.ftqIdx 172dfde261eSljw 173*09348ee5Sljw val s2_br_mask = RegEnable(ftqRead.br_mask, enable = s1_redirect_valid_reg) 174*09348ee5Sljw val s2_sawNotTakenBranch = RegEnable(VecInit((0 until PredictWidth).map{ i => 175*09348ee5Sljw if(i == 0) false.B else Cat(ftqRead.br_mask.take(i)).orR() 176*09348ee5Sljw })(s1_redirect_bits_reg.ftqOffset), enable = s1_redirect_valid_reg) 177*09348ee5Sljw val s2_hist = RegEnable(ftqRead.hist, enable = s1_redirect_valid_reg) 178dfde261eSljw val s2_target = RegEnable(target, enable = s1_redirect_valid_reg) 179dfde261eSljw val s2_pd = RegEnable(s1_pd, enable = s1_redirect_valid_reg) 180dfde261eSljw val s2_cfiUpdata_pc = RegEnable(cfiUpdate_pc, enable = s1_redirect_valid_reg) 181dfde261eSljw val s2_redirect_bits_reg = RegEnable(s1_redirect_bits_reg, enable = s1_redirect_valid_reg) 182dfde261eSljw val s2_redirect_valid_reg = RegNext(s1_redirect_valid_reg && !io.flush, init = false.B) 183dfde261eSljw val s2_ftqRead = io.stage2FtqRead.entry 184dfde261eSljw 185faf3cfa9SLinJiawei io.stage3Redirect.valid := s2_redirect_valid_reg 186faf3cfa9SLinJiawei io.stage3Redirect.bits := s2_redirect_bits_reg 187faf3cfa9SLinJiawei val stage3CfiUpdate = io.stage3Redirect.bits.cfiUpdate 188dfde261eSljw stage3CfiUpdate.pc := s2_cfiUpdata_pc 189faf3cfa9SLinJiawei stage3CfiUpdate.pd := s2_pd 190dfde261eSljw stage3CfiUpdate.rasSp := s2_ftqRead.rasSp 191dfde261eSljw stage3CfiUpdate.rasEntry := s2_ftqRead.rasTop 192dfde261eSljw stage3CfiUpdate.predHist := s2_ftqRead.predHist 193dfde261eSljw stage3CfiUpdate.specCnt := s2_ftqRead.specCnt 194*09348ee5Sljw stage3CfiUpdate.hist := s2_hist 195cde9280dSLinJiawei stage3CfiUpdate.predTaken := s2_redirect_bits_reg.cfiUpdate.predTaken 196*09348ee5Sljw stage3CfiUpdate.sawNotTakenBranch := s2_sawNotTakenBranch 197dfde261eSljw stage3CfiUpdate.target := s2_target 198faf3cfa9SLinJiawei stage3CfiUpdate.taken := s2_redirect_bits_reg.cfiUpdate.taken 199faf3cfa9SLinJiawei stage3CfiUpdate.isMisPred := s2_redirect_bits_reg.cfiUpdate.isMisPred 200884dbb3bSLinJiawei} 201884dbb3bSLinJiawei 20221732575SYinan Xuclass CtrlBlock extends XSModule with HasCircularQueuePtrHelper { 2038921b337SYinan Xu val io = IO(new Bundle { 2048921b337SYinan Xu val frontend = Flipped(new FrontendToBackendIO) 2058921b337SYinan Xu val fromIntBlock = Flipped(new IntBlockToCtrlIO) 2068921b337SYinan Xu val fromFpBlock = Flipped(new FpBlockToCtrlIO) 2078921b337SYinan Xu val fromLsBlock = Flipped(new LsBlockToCtrlIO) 2088921b337SYinan Xu val toIntBlock = new CtrlToIntBlockIO 2098921b337SYinan Xu val toFpBlock = new CtrlToFpBlockIO 2108921b337SYinan Xu val toLsBlock = new CtrlToLsBlockIO 2111c2588aaSYinan Xu val roqio = new Bundle { 2121c2588aaSYinan Xu // to int block 2131c2588aaSYinan Xu val toCSR = new RoqCSRIO 2143a474d38SYinan Xu val exception = ValidIO(new ExceptionInfo) 2151c2588aaSYinan Xu // to mem block 21610aac6e7SWilliam Wang val lsq = new RoqLsqIO 2171c2588aaSYinan Xu } 2182b8b2e7aSWilliam Wang val csrCtrl = Input(new CustomCSRCtrlIO) 2198921b337SYinan Xu }) 2208921b337SYinan Xu 221a165bd69Swangkaifan val difftestIO = IO(new Bundle() { 222a165bd69Swangkaifan val fromRoq = new Bundle() { 223a165bd69Swangkaifan val commit = Output(UInt(32.W)) 224a165bd69Swangkaifan val thisPC = Output(UInt(XLEN.W)) 225a165bd69Swangkaifan val thisINST = Output(UInt(32.W)) 226a165bd69Swangkaifan val skip = Output(UInt(32.W)) 227a165bd69Swangkaifan val wen = Output(UInt(32.W)) 228a165bd69Swangkaifan val wdata = Output(Vec(CommitWidth, UInt(XLEN.W))) // set difftest width to 6 229a165bd69Swangkaifan val wdst = Output(Vec(CommitWidth, UInt(32.W))) // set difftest width to 6 230a165bd69Swangkaifan val wpc = Output(Vec(CommitWidth, UInt(XLEN.W))) // set difftest width to 6 231a165bd69Swangkaifan val isRVC = Output(UInt(32.W)) 232a165bd69Swangkaifan val scFailed = Output(Bool()) 23307635e87Swangkaifan val lpaddr = Output(Vec(CommitWidth, UInt(64.W))) 23407635e87Swangkaifan val ltype = Output(Vec(CommitWidth, UInt(32.W))) 23507635e87Swangkaifan val lfu = Output(Vec(CommitWidth, UInt(4.W))) 236a165bd69Swangkaifan } 237a165bd69Swangkaifan }) 238a165bd69Swangkaifan difftestIO <> DontCare 239a165bd69Swangkaifan 240884dbb3bSLinJiawei val ftq = Module(new Ftq) 24154bc08adSwangkaifan val trapIO = IO(new TrapIO()) 24254bc08adSwangkaifan trapIO <> DontCare 24354bc08adSwangkaifan 2448921b337SYinan Xu val decode = Module(new DecodeStage) 2458921b337SYinan Xu val rename = Module(new Rename) 246694b0180SLinJiawei val dispatch = Module(new Dispatch) 2473fae98acSYinan Xu val intBusyTable = Module(new BusyTable(NRIntReadPorts, NRIntWritePorts)) 2483fae98acSYinan Xu val fpBusyTable = Module(new BusyTable(NRFpReadPorts, NRFpWritePorts)) 249884dbb3bSLinJiawei val redirectGen = Module(new RedirectGenerator) 2508921b337SYinan Xu 251884dbb3bSLinJiawei val roqWbSize = NRIntWritePorts + NRFpWritePorts + exuParameters.StuCnt 252694b0180SLinJiawei val roq = Module(new Roq(roqWbSize)) 2538921b337SYinan Xu 254884dbb3bSLinJiawei val backendRedirect = redirectGen.io.stage2Redirect 255faf3cfa9SLinJiawei val frontendRedirect = redirectGen.io.stage3Redirect 2562d7c7105SYinan Xu val flush = roq.io.flushOut.valid 257bbd262adSLinJiawei val flushReg = RegNext(flush) 258faf3cfa9SLinJiawei 259dfde261eSljw val exuRedirect = io.fromIntBlock.exuRedirect.map(x => { 260dfde261eSljw val valid = x.valid && x.bits.redirectValid 261dfde261eSljw val killedByOlder = x.bits.uop.roqIdx.needFlush(backendRedirect, flushReg) 262dfde261eSljw val delayed = Wire(Valid(new ExuOutput)) 263dfde261eSljw delayed.valid := RegNext(valid && !killedByOlder, init = false.B) 264dfde261eSljw delayed.bits := RegEnable(x.bits, x.valid) 265dfde261eSljw delayed 266faf3cfa9SLinJiawei }) 267c1b37c81Sljw val loadReplay = Wire(Valid(new Redirect)) 268c1b37c81Sljw loadReplay.valid := RegNext(io.fromLsBlock.replay.valid && 269c1b37c81Sljw !io.fromLsBlock.replay.bits.roqIdx.needFlush(backendRedirect, flushReg), 270c1b37c81Sljw init = false.B 271c1b37c81Sljw ) 272c1b37c81Sljw loadReplay.bits := RegEnable(io.fromLsBlock.replay.bits, io.fromLsBlock.replay.valid) 273dfde261eSljw VecInit(ftq.io.ftqRead.tail.dropRight(1)) <> redirectGen.io.stage1FtqRead 274dfde261eSljw ftq.io.cfiRead <> redirectGen.io.stage2FtqRead 275dfde261eSljw redirectGen.io.exuMispredict <> exuRedirect 276c1b37c81Sljw redirectGen.io.loadReplay <> loadReplay 277bbd262adSLinJiawei redirectGen.io.flush := flushReg 2788921b337SYinan Xu 279884dbb3bSLinJiawei ftq.io.enq <> io.frontend.fetchInfo 280884dbb3bSLinJiawei for(i <- 0 until CommitWidth){ 2816060732cSLinJiawei ftq.io.roq_commits(i).valid := roq.io.commits.valid(i) && !roq.io.commits.isWalk 282884dbb3bSLinJiawei ftq.io.roq_commits(i).bits := roq.io.commits.info(i) 283884dbb3bSLinJiawei } 284884dbb3bSLinJiawei ftq.io.redirect <> backendRedirect 285bbd262adSLinJiawei ftq.io.flush := flushReg 286bbd262adSLinJiawei ftq.io.flushIdx := RegNext(roq.io.flushOut.bits.ftqIdx) 287bbd262adSLinJiawei ftq.io.flushOffset := RegNext(roq.io.flushOut.bits.ftqOffset) 288faf3cfa9SLinJiawei ftq.io.frontendRedirect <> frontendRedirect 289dfde261eSljw ftq.io.exuWriteback <> exuRedirect 290884dbb3bSLinJiawei 291dfde261eSljw ftq.io.ftqRead.last.ptr := roq.io.flushOut.bits.ftqIdx 2929ed972adSLinJiawei val flushPC = GetPcByFtq( 293dfde261eSljw ftq.io.ftqRead.last.entry.ftqPC, 2949ed972adSLinJiawei RegEnable(roq.io.flushOut.bits.ftqOffset, roq.io.flushOut.valid), 295dfde261eSljw ftq.io.ftqRead.last.entry.lastPacketPC.valid, 296dfde261eSljw ftq.io.ftqRead.last.entry.lastPacketPC.bits 2979ed972adSLinJiawei ) 298884dbb3bSLinJiawei 2999ed972adSLinJiawei val flushRedirect = Wire(Valid(new Redirect)) 300bbd262adSLinJiawei flushRedirect.valid := flushReg 3019ed972adSLinJiawei flushRedirect.bits := DontCare 3029ed972adSLinJiawei flushRedirect.bits.ftqIdx := RegEnable(roq.io.flushOut.bits.ftqIdx, flush) 3039ed972adSLinJiawei flushRedirect.bits.interrupt := true.B 304ac5a5d53SLinJiawei flushRedirect.bits.cfiUpdate.target := Mux(io.roqio.toCSR.isXRet || roq.io.exception.valid, 305ac5a5d53SLinJiawei io.roqio.toCSR.trapTarget, 306ac5a5d53SLinJiawei flushPC + 4.U // flush pipe 3079ed972adSLinJiawei ) 308c1b37c81Sljw val flushRedirectReg = Wire(Valid(new Redirect)) 309c1b37c81Sljw flushRedirectReg.valid := RegNext(flushRedirect.valid, init = false.B) 310c1b37c81Sljw flushRedirectReg.bits := RegEnable(flushRedirect.bits, enable = flushRedirect.valid) 3119ed972adSLinJiawei 312c1b37c81Sljw io.frontend.redirect_cfiUpdate := Mux(flushRedirectReg.valid, flushRedirectReg, frontendRedirect) 31303380706SLinJiawei io.frontend.commit_cfiUpdate := ftq.io.commit_ftqEntry 314fc4776e4SLinJiawei io.frontend.ftqEnqPtr := ftq.io.enqPtr 315fc4776e4SLinJiawei io.frontend.ftqLeftOne := ftq.io.leftOne 31666bcc42fSYinan Xu 3178921b337SYinan Xu decode.io.in <> io.frontend.cfVec 3182b8b2e7aSWilliam Wang // currently, we only update wait table when isReplay 3192b8b2e7aSWilliam Wang decode.io.waitTableUpdate(0) <> RegNext(redirectGen.io.waitTableUpdate) 3202b8b2e7aSWilliam Wang decode.io.waitTableUpdate(1) := DontCare 3212b8b2e7aSWilliam Wang decode.io.waitTableUpdate(1).valid := false.B 3222b8b2e7aSWilliam Wang // decode.io.waitTableUpdate <> io.toLsBlock.waitTableUpdate 3232b8b2e7aSWilliam Wang decode.io.csrCtrl := RegNext(io.csrCtrl) 3242b8b2e7aSWilliam Wang 3258921b337SYinan Xu 326884dbb3bSLinJiawei val jumpInst = dispatch.io.enqIQCtrl(0).bits 3276060732cSLinJiawei val ftqOffsetReg = Reg(UInt(log2Up(PredictWidth).W)) 3286060732cSLinJiawei ftqOffsetReg := jumpInst.cf.ftqOffset 329884dbb3bSLinJiawei ftq.io.ftqRead(0).ptr := jumpInst.cf.ftqPtr // jump 3307aa94463SLinJiawei io.toIntBlock.jumpPc := GetPcByFtq( 3311670d147SLingrui98 ftq.io.ftqRead(0).entry.ftqPC, ftqOffsetReg, 3321670d147SLingrui98 ftq.io.ftqRead(0).entry.lastPacketPC.valid, 3331670d147SLingrui98 ftq.io.ftqRead(0).entry.lastPacketPC.bits 3347aa94463SLinJiawei ) 335148ba860SLinJiawei io.toIntBlock.jalr_target := ftq.io.ftqRead(0).entry.target 3360412e00dSLinJiawei 337b424051cSYinan Xu // pipeline between decode and dispatch 338b424051cSYinan Xu for (i <- 0 until RenameWidth) { 339884dbb3bSLinJiawei PipelineConnect(decode.io.out(i), rename.io.in(i), rename.io.in(i).ready, 340c1b37c81Sljw flushReg || io.frontend.redirect_cfiUpdate.valid) 341b424051cSYinan Xu } 3428921b337SYinan Xu 343884dbb3bSLinJiawei rename.io.redirect <> backendRedirect 344bbd262adSLinJiawei rename.io.flush := flushReg 3458921b337SYinan Xu rename.io.roqCommits <> roq.io.commits 3468921b337SYinan Xu rename.io.out <> dispatch.io.fromRename 34799b8dc2cSYinan Xu rename.io.renameBypass <> dispatch.io.renameBypass 348049559e7SYinan Xu rename.io.dispatchInfo <> dispatch.io.preDpInfo 3498921b337SYinan Xu 350884dbb3bSLinJiawei dispatch.io.redirect <> backendRedirect 351bbd262adSLinJiawei dispatch.io.flush := flushReg 35221b47d38SYinan Xu dispatch.io.enqRoq <> roq.io.enq 35308fafef0SYinan Xu dispatch.io.enqLsq <> io.toLsBlock.enqLsq 3542bb6eba1SYinan Xu dispatch.io.readIntRf <> io.toIntBlock.readRf 3552bb6eba1SYinan Xu dispatch.io.readFpRf <> io.toFpBlock.readRf 3563fae98acSYinan Xu dispatch.io.allocPregs.zipWithIndex.foreach { case (preg, i) => 3573fae98acSYinan Xu intBusyTable.io.allocPregs(i).valid := preg.isInt 3581c931a03SYinan Xu fpBusyTable.io.allocPregs(i).valid := preg.isFp 3593fae98acSYinan Xu intBusyTable.io.allocPregs(i).bits := preg.preg 3603fae98acSYinan Xu fpBusyTable.io.allocPregs(i).bits := preg.preg 3613fae98acSYinan Xu } 3628921b337SYinan Xu dispatch.io.numExist <> io.fromIntBlock.numExist ++ io.fromFpBlock.numExist ++ io.fromLsBlock.numExist 3632bb6eba1SYinan Xu dispatch.io.enqIQCtrl <> io.toIntBlock.enqIqCtrl ++ io.toFpBlock.enqIqCtrl ++ io.toLsBlock.enqIqCtrl 36476e1d2a4SYikeZhou// dispatch.io.enqIQData <> io.toIntBlock.enqIqData ++ io.toFpBlock.enqIqData ++ io.toLsBlock.enqIqData 3658921b337SYinan Xu 3660412e00dSLinJiawei 367bbd262adSLinJiawei fpBusyTable.io.flush := flushReg 368bbd262adSLinJiawei intBusyTable.io.flush := flushReg 3693fae98acSYinan Xu for((wb, setPhyRegRdy) <- io.fromIntBlock.wbRegs.zip(intBusyTable.io.wbPregs)){ 3701e2ad30cSYinan Xu setPhyRegRdy.valid := wb.valid && wb.bits.uop.ctrl.rfWen 3713fae98acSYinan Xu setPhyRegRdy.bits := wb.bits.uop.pdest 3723fae98acSYinan Xu } 3733fae98acSYinan Xu for((wb, setPhyRegRdy) <- io.fromFpBlock.wbRegs.zip(fpBusyTable.io.wbPregs)){ 3743fae98acSYinan Xu setPhyRegRdy.valid := wb.valid && wb.bits.uop.ctrl.fpWen 3753fae98acSYinan Xu setPhyRegRdy.bits := wb.bits.uop.pdest 3763fae98acSYinan Xu } 3778af95560SYinan Xu intBusyTable.io.read <> dispatch.io.readIntState 3788af95560SYinan Xu fpBusyTable.io.read <> dispatch.io.readFpState 3793fae98acSYinan Xu 380884dbb3bSLinJiawei roq.io.redirect <> backendRedirect 381c1b37c81Sljw val exeWbResults = VecInit(io.fromIntBlock.wbRegs ++ io.fromFpBlock.wbRegs ++ io.fromLsBlock.stOut) 382c1b37c81Sljw for((roq_wb, wb) <- roq.io.exeWbResults.zip(exeWbResults)) { 383c1b37c81Sljw roq_wb.valid := RegNext(wb.valid && !wb.bits.uop.roqIdx.needFlush(backendRedirect, flushReg)) 384c1b37c81Sljw roq_wb.bits := RegNext(wb.bits) 385c1b37c81Sljw } 3860412e00dSLinJiawei 387884dbb3bSLinJiawei // TODO: is 'backendRedirect' necesscary? 388884dbb3bSLinJiawei io.toIntBlock.redirect <> backendRedirect 389bbd262adSLinJiawei io.toIntBlock.flush <> flushReg 390884dbb3bSLinJiawei io.toFpBlock.redirect <> backendRedirect 391bbd262adSLinJiawei io.toFpBlock.flush <> flushReg 392884dbb3bSLinJiawei io.toLsBlock.redirect <> backendRedirect 393bbd262adSLinJiawei io.toLsBlock.flush <> flushReg 3940412e00dSLinJiawei 3953d499721Swangkaifan if (!env.FPGAPlatform) { 396a165bd69Swangkaifan difftestIO.fromRoq <> roq.difftestIO 39754bc08adSwangkaifan trapIO <> roq.trapIO 398a165bd69Swangkaifan } 399a165bd69Swangkaifan 4009916fbd7SYikeZhou dispatch.io.readPortIndex.intIndex <> io.toIntBlock.readPortIndex 4019916fbd7SYikeZhou dispatch.io.readPortIndex.fpIndex <> io.toFpBlock.readPortIndex 4029916fbd7SYikeZhou 4031c2588aaSYinan Xu // roq to int block 4041c2588aaSYinan Xu io.roqio.toCSR <> roq.io.csr 4052d7c7105SYinan Xu io.roqio.exception := roq.io.exception 4069ed972adSLinJiawei io.roqio.exception.bits.uop.cf.pc := flushPC 4071c2588aaSYinan Xu // roq to mem block 40810aac6e7SWilliam Wang io.roqio.lsq <> roq.io.lsq 4098921b337SYinan Xu} 410