1024ee227SWilliam Wangpackage xiangshan.mem 2024ee227SWilliam Wang 3024ee227SWilliam Wangimport chisel3._ 4024ee227SWilliam Wangimport chisel3.util._ 5024ee227SWilliam Wangimport utils._ 6024ee227SWilliam Wangimport xiangshan._ 779460b79SLinJiaweiimport xiangshan.backend.decode.ImmUnion 81279060fSWilliam Wangimport xiangshan.cache._ 91279060fSWilliam Wang// import xiangshan.cache.{DCacheWordIO, TlbRequestIO, TlbCmd, MemoryOpConstants, TlbReq, DCacheLoadReq, DCacheWordResp} 10024ee227SWilliam Wangimport xiangshan.backend.LSUOpType 11024ee227SWilliam Wang 120bd67ba5SYinan Xuclass LoadToLsqIO extends XSBundle { 13024ee227SWilliam Wang val loadIn = ValidIO(new LsPipelineBundle) 14024ee227SWilliam Wang val ldout = Flipped(DecoupledIO(new ExuOutput)) 15*5830ba4fSWilliam Wang val loadDataForwarded = Output(Bool()) 16024ee227SWilliam Wang val forward = new LoadForwardQueryIO 17024ee227SWilliam Wang} 18024ee227SWilliam Wang 197962cc88SWilliam Wang// Load Pipeline Stage 0 207962cc88SWilliam Wang// Generate addr, use addr to query DCache and DTLB 217962cc88SWilliam Wangclass LoadUnit_S0 extends XSModule { 22024ee227SWilliam Wang val io = IO(new Bundle() { 237962cc88SWilliam Wang val in = Flipped(Decoupled(new ExuInput)) 247962cc88SWilliam Wang val out = Decoupled(new LsPipelineBundle) 250cab60cbSZhangZifei val dtlbReq = DecoupledIO(new TlbReq) 266e9ed841SAllen val dcacheReq = DecoupledIO(new DCacheWordReq) 27024ee227SWilliam Wang }) 28024ee227SWilliam Wang 297962cc88SWilliam Wang val s0_uop = io.in.bits.uop 3079460b79SLinJiawei val s0_vaddr = io.in.bits.src1 + SignExt(ImmUnion.I.toImm32(s0_uop.ctrl.imm), XLEN) 317962cc88SWilliam Wang val s0_mask = genWmask(s0_vaddr, s0_uop.ctrl.fuOpType(1,0)) 32024ee227SWilliam Wang 337962cc88SWilliam Wang // query DTLB 34d0f66e88SYinan Xu io.dtlbReq.valid := io.in.valid 351279060fSWilliam Wang io.dtlbReq.bits.vaddr := s0_vaddr 361279060fSWilliam Wang io.dtlbReq.bits.cmd := TlbCmd.read 371279060fSWilliam Wang io.dtlbReq.bits.roqIdx := s0_uop.roqIdx 381279060fSWilliam Wang io.dtlbReq.bits.debug.pc := s0_uop.cf.pc 39024ee227SWilliam Wang 407962cc88SWilliam Wang // query DCache 41d0f66e88SYinan Xu io.dcacheReq.valid := io.in.valid 421279060fSWilliam Wang io.dcacheReq.bits.cmd := MemoryOpConstants.M_XRD 431279060fSWilliam Wang io.dcacheReq.bits.addr := s0_vaddr 441279060fSWilliam Wang io.dcacheReq.bits.mask := s0_mask 4559a40467SWilliam Wang io.dcacheReq.bits.data := DontCare 46024ee227SWilliam Wang 4759a40467SWilliam Wang // TODO: update cache meta 4859a40467SWilliam Wang io.dcacheReq.bits.meta.id := DontCare 4959a40467SWilliam Wang io.dcacheReq.bits.meta.vaddr := s0_vaddr 5059a40467SWilliam Wang io.dcacheReq.bits.meta.paddr := DontCare 5159a40467SWilliam Wang io.dcacheReq.bits.meta.uop := s0_uop 5259a40467SWilliam Wang io.dcacheReq.bits.meta.mmio := false.B 5359a40467SWilliam Wang io.dcacheReq.bits.meta.tlb_miss := false.B 5459a40467SWilliam Wang io.dcacheReq.bits.meta.mask := s0_mask 5559a40467SWilliam Wang io.dcacheReq.bits.meta.replay := false.B 56024ee227SWilliam Wang 577962cc88SWilliam Wang val addrAligned = LookupTree(s0_uop.ctrl.fuOpType(1, 0), List( 58024ee227SWilliam Wang "b00".U -> true.B, //b 597962cc88SWilliam Wang "b01".U -> (s0_vaddr(0) === 0.U), //h 607962cc88SWilliam Wang "b10".U -> (s0_vaddr(1, 0) === 0.U), //w 617962cc88SWilliam Wang "b11".U -> (s0_vaddr(2, 0) === 0.U) //d 62024ee227SWilliam Wang )) 63024ee227SWilliam Wang 641a51d1d9SYinan Xu io.out.valid := io.in.valid && io.dcacheReq.ready 65d0f66e88SYinan Xu 667962cc88SWilliam Wang io.out.bits := DontCare 677962cc88SWilliam Wang io.out.bits.vaddr := s0_vaddr 687962cc88SWilliam Wang io.out.bits.mask := s0_mask 697962cc88SWilliam Wang io.out.bits.uop := s0_uop 707962cc88SWilliam Wang io.out.bits.uop.cf.exceptionVec(loadAddrMisaligned) := !addrAligned 71024ee227SWilliam Wang 72d0f66e88SYinan Xu io.in.ready := !io.in.valid || (io.out.ready && io.dcacheReq.ready) 73024ee227SWilliam Wang 74d0f66e88SYinan Xu XSDebug(io.dcacheReq.fire(), 75bcc55f84SYinan Xu p"[DCACHE LOAD REQ] pc ${Hexadecimal(s0_uop.cf.pc)}, vaddr ${Hexadecimal(s0_vaddr)}\n" 763dbae6f8SYinan Xu ) 777962cc88SWilliam Wang} 78024ee227SWilliam Wang 797962cc88SWilliam Wang 807962cc88SWilliam Wang// Load Pipeline Stage 1 817962cc88SWilliam Wang// TLB resp (send paddr to dcache) 827962cc88SWilliam Wangclass LoadUnit_S1 extends XSModule { 837962cc88SWilliam Wang val io = IO(new Bundle() { 847962cc88SWilliam Wang val in = Flipped(Decoupled(new LsPipelineBundle)) 857962cc88SWilliam Wang val out = Decoupled(new LsPipelineBundle) 86bcc55f84SYinan Xu val dtlbResp = Flipped(DecoupledIO(new TlbResp)) 87bcc55f84SYinan Xu val dcachePAddr = Output(UInt(PAddrBits.W)) 88d21b1759SYinan Xu val dcacheKill = Output(Bool()) 892e36e3b7SWilliam Wang val sbuffer = new LoadForwardQueryIO 900bd67ba5SYinan Xu val lsq = new LoadForwardQueryIO 917962cc88SWilliam Wang }) 927962cc88SWilliam Wang 937962cc88SWilliam Wang val s1_uop = io.in.bits.uop 94bcc55f84SYinan Xu val s1_paddr = io.dtlbResp.bits.paddr 95baf8def6SYinan Xu val s1_exception = selectLoad(io.out.bits.uop.cf.exceptionVec, false).asUInt.orR 96bcc55f84SYinan Xu val s1_tlb_miss = io.dtlbResp.bits.miss 97cff68e26SWilliam Wang val s1_mmio = !s1_tlb_miss && io.dtlbResp.bits.mmio 982e36e3b7SWilliam Wang val s1_mask = io.in.bits.mask 997962cc88SWilliam Wang 1002e36e3b7SWilliam Wang io.out.bits := io.in.bits // forwardXX field will be updated in s1 101bcc55f84SYinan Xu 102bcc55f84SYinan Xu io.dtlbResp.ready := true.B 103bcc55f84SYinan Xu 1048005392cSYinan Xu // TOOD: PMA check 105bcc55f84SYinan Xu io.dcachePAddr := s1_paddr 1068005392cSYinan Xu io.dcacheKill := s1_tlb_miss || s1_exception || s1_mmio 1077962cc88SWilliam Wang 1082e36e3b7SWilliam Wang // load forward query datapath 1092e36e3b7SWilliam Wang io.sbuffer.valid := io.in.valid 1102e36e3b7SWilliam Wang io.sbuffer.paddr := s1_paddr 1112e36e3b7SWilliam Wang io.sbuffer.uop := s1_uop 1122e36e3b7SWilliam Wang io.sbuffer.sqIdx := s1_uop.sqIdx 1132e36e3b7SWilliam Wang io.sbuffer.mask := s1_mask 1142e36e3b7SWilliam Wang io.sbuffer.pc := s1_uop.cf.pc // FIXME: remove it 1152e36e3b7SWilliam Wang 1160bd67ba5SYinan Xu io.lsq.valid := io.in.valid 1170bd67ba5SYinan Xu io.lsq.paddr := s1_paddr 1180bd67ba5SYinan Xu io.lsq.uop := s1_uop 1190bd67ba5SYinan Xu io.lsq.sqIdx := s1_uop.sqIdx 1200bd67ba5SYinan Xu io.lsq.mask := s1_mask 1210bd67ba5SYinan Xu io.lsq.pc := s1_uop.cf.pc // FIXME: remove it 1222e36e3b7SWilliam Wang 123d21b1759SYinan Xu io.out.valid := io.in.valid// && !s1_tlb_miss 1247962cc88SWilliam Wang io.out.bits.paddr := s1_paddr 1258005392cSYinan Xu io.out.bits.mmio := s1_mmio && !s1_exception 12659a40467SWilliam Wang io.out.bits.tlbMiss := s1_tlb_miss 127bcc55f84SYinan Xu io.out.bits.uop.cf.exceptionVec(loadPageFault) := io.dtlbResp.bits.excp.pf.ld 128cff68e26SWilliam Wang io.out.bits.uop.cf.exceptionVec(loadAccessFault) := io.dtlbResp.bits.excp.af.ld 1297962cc88SWilliam Wang 130d0f66e88SYinan Xu io.in.ready := !io.in.valid || io.out.ready 1317962cc88SWilliam Wang 1327962cc88SWilliam Wang} 1337962cc88SWilliam Wang 1347962cc88SWilliam Wang 1357962cc88SWilliam Wang// Load Pipeline Stage 2 1367962cc88SWilliam Wang// DCache resp 137579b9f28SLinJiaweiclass LoadUnit_S2 extends XSModule with HasLoadHelper { 1387962cc88SWilliam Wang val io = IO(new Bundle() { 1397962cc88SWilliam Wang val in = Flipped(Decoupled(new LsPipelineBundle)) 1407962cc88SWilliam Wang val out = Decoupled(new LsPipelineBundle) 141d21b1759SYinan Xu val tlbFeedback = ValidIO(new TlbFeedback) 1421279060fSWilliam Wang val dcacheResp = Flipped(DecoupledIO(new DCacheWordResp)) 143b3084e27SWilliam Wang val lsq = new LoadForwardQueryIO 144995f167cSYinan Xu val sbuffer = new LoadForwardQueryIO 145*5830ba4fSWilliam Wang val dataForwarded = Output(Bool()) 1467962cc88SWilliam Wang }) 1477962cc88SWilliam Wang 1487962cc88SWilliam Wang val s2_uop = io.in.bits.uop 1497962cc88SWilliam Wang val s2_mask = io.in.bits.mask 1507962cc88SWilliam Wang val s2_paddr = io.in.bits.paddr 151d21b1759SYinan Xu val s2_tlb_miss = io.in.bits.tlbMiss 1528005392cSYinan Xu val s2_mmio = io.in.bits.mmio 153baf8def6SYinan Xu val s2_exception = selectLoad(io.in.bits.uop.cf.exceptionVec, false).asUInt.orR 1541279060fSWilliam Wang val s2_cache_miss = io.dcacheResp.bits.miss 1556e9ed841SAllen val s2_cache_replay = io.dcacheResp.bits.replay 1567962cc88SWilliam Wang 1571279060fSWilliam Wang io.dcacheResp.ready := true.B 1588005392cSYinan Xu val dcacheShouldResp = !(s2_tlb_miss || s2_exception || s2_mmio) 1598005392cSYinan Xu assert(!(io.in.valid && dcacheShouldResp && !io.dcacheResp.valid), "DCache response got lost") 1607962cc88SWilliam Wang 161d21b1759SYinan Xu // feedback tlb result to RS 162d21b1759SYinan Xu io.tlbFeedback.valid := io.in.valid 163c98c0043SYinan Xu io.tlbFeedback.bits.hit := !s2_tlb_miss && (!s2_cache_replay || s2_mmio) 164d21b1759SYinan Xu io.tlbFeedback.bits.roqIdx := s2_uop.roqIdx 165d21b1759SYinan Xu 166b3084e27SWilliam Wang val forwardMask = io.out.bits.forwardMask 167b3084e27SWilliam Wang val forwardData = io.out.bits.forwardData 1687962cc88SWilliam Wang val fullForward = (~forwardMask.asUInt & s2_mask) === 0.U 169024ee227SWilliam Wang 170b3084e27SWilliam Wang XSDebug(io.out.fire(), "[FWD LOAD RESP] pc %x fwd %x(%b) + %x(%b)\n", 171b3084e27SWilliam Wang s2_uop.cf.pc, 172b3084e27SWilliam Wang io.lsq.forwardData.asUInt, io.lsq.forwardMask.asUInt, 173b3084e27SWilliam Wang io.in.bits.forwardData.asUInt, io.in.bits.forwardMask.asUInt 174b3084e27SWilliam Wang ) 175b3084e27SWilliam Wang 176024ee227SWilliam Wang // data merge 1777962cc88SWilliam Wang val rdata = VecInit((0 until XLEN / 8).map(j => 1781279060fSWilliam Wang Mux(forwardMask(j), forwardData(j), io.dcacheResp.bits.data(8*(j+1)-1, 8*j)))).asUInt 1797962cc88SWilliam Wang val rdataSel = LookupTree(s2_paddr(2, 0), List( 180024ee227SWilliam Wang "b000".U -> rdata(63, 0), 181024ee227SWilliam Wang "b001".U -> rdata(63, 8), 182024ee227SWilliam Wang "b010".U -> rdata(63, 16), 183024ee227SWilliam Wang "b011".U -> rdata(63, 24), 184024ee227SWilliam Wang "b100".U -> rdata(63, 32), 185024ee227SWilliam Wang "b101".U -> rdata(63, 40), 186024ee227SWilliam Wang "b110".U -> rdata(63, 48), 187024ee227SWilliam Wang "b111".U -> rdata(63, 56) 188024ee227SWilliam Wang )) 189579b9f28SLinJiawei val rdataPartialLoad = rdataHelper(s2_uop, rdataSel) 190024ee227SWilliam Wang 1917962cc88SWilliam Wang // TODO: ECC check 192024ee227SWilliam Wang 1938005392cSYinan Xu io.out.valid := io.in.valid && !s2_tlb_miss && (!s2_cache_replay || s2_mmio) 1940bd67ba5SYinan Xu // Inst will be canceled in store queue / lsq, 195dd1ffd4dSWilliam Wang // so we do not need to care about flush in load / store unit's out.valid 1967962cc88SWilliam Wang io.out.bits := io.in.bits 1977962cc88SWilliam Wang io.out.bits.data := rdataPartialLoad 19826a692b9SYinan Xu // when exception occurs, set it to not miss and let it write back to roq (via int port) 199*5830ba4fSWilliam Wang io.out.bits.miss := s2_cache_miss && !s2_exception 20026a692b9SYinan Xu io.out.bits.uop.ctrl.fpWen := io.in.bits.uop.ctrl.fpWen && !s2_exception 2012c671545SYinan Xu io.out.bits.mmio := s2_mmio 2027962cc88SWilliam Wang 203*5830ba4fSWilliam Wang // For timing reasons, we can not let 204*5830ba4fSWilliam Wang // io.out.bits.miss := s2_cache_miss && !s2_exception && !fullForward 205*5830ba4fSWilliam Wang // We use io.dataForwarded instead. It means forward logic have prepared all data needed, 206*5830ba4fSWilliam Wang // and dcache query is no longer needed. 207*5830ba4fSWilliam Wang // Such inst will be writebacked from load queue. 208*5830ba4fSWilliam Wang io.dataForwarded := s2_cache_miss && fullForward && !s2_exception 209*5830ba4fSWilliam Wang 2107962cc88SWilliam Wang io.in.ready := io.out.ready || !io.in.valid 2117962cc88SWilliam Wang 212b3084e27SWilliam Wang // merge forward result 213995f167cSYinan Xu // lsq has higher priority than sbuffer 214b3084e27SWilliam Wang io.lsq := DontCare 215995f167cSYinan Xu io.sbuffer := DontCare 216b3084e27SWilliam Wang // generate XLEN/8 Muxs 217b3084e27SWilliam Wang for (i <- 0 until XLEN / 8) { 218995f167cSYinan Xu when (io.sbuffer.forwardMask(i)) { 219995f167cSYinan Xu io.out.bits.forwardMask(i) := true.B 220995f167cSYinan Xu io.out.bits.forwardData(i) := io.sbuffer.forwardData(i) 221995f167cSYinan Xu } 222b3084e27SWilliam Wang when (io.lsq.forwardMask(i)) { 223b3084e27SWilliam Wang io.out.bits.forwardMask(i) := true.B 224b3084e27SWilliam Wang io.out.bits.forwardData(i) := io.lsq.forwardData(i) 225b3084e27SWilliam Wang } 226b3084e27SWilliam Wang } 227b3084e27SWilliam Wang 2282e36e3b7SWilliam Wang XSDebug(io.out.fire(), "[DCACHE LOAD RESP] pc %x rdata %x <- D$ %x + fwd %x(%b)\n", 229d5ea289eSWilliam Wang s2_uop.cf.pc, rdataPartialLoad, io.dcacheResp.bits.data, 230b3084e27SWilliam Wang io.out.bits.forwardData.asUInt, io.out.bits.forwardMask.asUInt 231024ee227SWilliam Wang ) 2327962cc88SWilliam Wang} 2337962cc88SWilliam Wang 23403a91a79SWilliam Wangclass LoadUnit extends XSModule with HasLoadHelper { 235024ee227SWilliam Wang val io = IO(new Bundle() { 236024ee227SWilliam Wang val ldin = Flipped(Decoupled(new ExuInput)) 237024ee227SWilliam Wang val ldout = Decoupled(new ExuOutput) 238c5c06e78SWilliam Wang val fpout = Decoupled(new ExuOutput) 239024ee227SWilliam Wang val redirect = Flipped(ValidIO(new Redirect)) 240024ee227SWilliam Wang val tlbFeedback = ValidIO(new TlbFeedback) 2411279060fSWilliam Wang val dcache = new DCacheLoadIO 242024ee227SWilliam Wang val dtlb = new TlbRequestIO() 243024ee227SWilliam Wang val sbuffer = new LoadForwardQueryIO 2440bd67ba5SYinan Xu val lsq = new LoadToLsqIO 245024ee227SWilliam Wang }) 246024ee227SWilliam Wang 2477962cc88SWilliam Wang val load_s0 = Module(new LoadUnit_S0) 2487962cc88SWilliam Wang val load_s1 = Module(new LoadUnit_S1) 2497962cc88SWilliam Wang val load_s2 = Module(new LoadUnit_S2) 250024ee227SWilliam Wang 2517962cc88SWilliam Wang load_s0.io.in <> io.ldin 2521279060fSWilliam Wang load_s0.io.dtlbReq <> io.dtlb.req 2531279060fSWilliam Wang load_s0.io.dcacheReq <> io.dcache.req 254024ee227SWilliam Wang 2551a51d1d9SYinan Xu PipelineConnect(load_s0.io.out, load_s1.io.in, true.B, load_s0.io.out.bits.uop.roqIdx.needFlush(io.redirect)) 256024ee227SWilliam Wang 257bcc55f84SYinan Xu load_s1.io.dtlbResp <> io.dtlb.resp 258bcc55f84SYinan Xu io.dcache.s1_paddr <> load_s1.io.dcachePAddr 259d21b1759SYinan Xu io.dcache.s1_kill <> load_s1.io.dcacheKill 260d0f66e88SYinan Xu load_s1.io.sbuffer <> io.sbuffer 261d0f66e88SYinan Xu load_s1.io.lsq <> io.lsq.forward 262024ee227SWilliam Wang 2631a51d1d9SYinan Xu PipelineConnect(load_s1.io.out, load_s2.io.in, true.B, load_s1.io.out.bits.uop.roqIdx.needFlush(io.redirect)) 264024ee227SWilliam Wang 265d21b1759SYinan Xu load_s2.io.tlbFeedback <> io.tlbFeedback 2661279060fSWilliam Wang load_s2.io.dcacheResp <> io.dcache.resp 267b3084e27SWilliam Wang load_s2.io.lsq.forwardData <> io.lsq.forward.forwardData 268b3084e27SWilliam Wang load_s2.io.lsq.forwardMask <> io.lsq.forward.forwardMask 269995f167cSYinan Xu load_s2.io.sbuffer.forwardData <> io.sbuffer.forwardData 270995f167cSYinan Xu load_s2.io.sbuffer.forwardMask <> io.sbuffer.forwardMask 271*5830ba4fSWilliam Wang load_s2.io.dataForwarded <> io.lsq.loadDataForwarded 272024ee227SWilliam Wang 2737962cc88SWilliam Wang XSDebug(load_s0.io.out.valid, 27448ae2f92SWilliam Wang p"S0: pc ${Hexadecimal(load_s0.io.out.bits.uop.cf.pc)}, lId ${Hexadecimal(load_s0.io.out.bits.uop.lqIdx.asUInt)}, " + 2757962cc88SWilliam Wang p"vaddr ${Hexadecimal(load_s0.io.out.bits.vaddr)}, mask ${Hexadecimal(load_s0.io.out.bits.mask)}\n") 2767962cc88SWilliam Wang XSDebug(load_s1.io.out.valid, 27748ae2f92SWilliam Wang p"S1: pc ${Hexadecimal(load_s1.io.out.bits.uop.cf.pc)}, lId ${Hexadecimal(load_s1.io.out.bits.uop.lqIdx.asUInt)}, tlb_miss ${io.dtlb.resp.bits.miss}, " + 27806c91a3dSWilliam Wang p"paddr ${Hexadecimal(load_s1.io.out.bits.paddr)}, mmio ${load_s1.io.out.bits.mmio}\n") 279024ee227SWilliam Wang 2800bd67ba5SYinan Xu // writeback to LSQ 281024ee227SWilliam Wang // Current dcache use MSHR 282c5c06e78SWilliam Wang // Load queue will be updated at s2 for both hit/miss int/fp load 2830bd67ba5SYinan Xu io.lsq.loadIn.valid := load_s2.io.out.valid 2840bd67ba5SYinan Xu io.lsq.loadIn.bits := load_s2.io.out.bits 28526a692b9SYinan Xu 28626a692b9SYinan Xu // write to rob and writeback bus 28726a692b9SYinan Xu val s2_wb_valid = load_s2.io.out.valid && !load_s2.io.out.bits.miss 28803a91a79SWilliam Wang val refillFpLoad = io.lsq.ldout.bits.uop.ctrl.fpWen 289024ee227SWilliam Wang 290c5c06e78SWilliam Wang // Int load, if hit, will be writebacked at s2 29103a91a79SWilliam Wang val intHitLoadOut = Wire(Valid(new ExuOutput)) 29226a692b9SYinan Xu intHitLoadOut.valid := s2_wb_valid && !load_s2.io.out.bits.uop.ctrl.fpWen 29303a91a79SWilliam Wang intHitLoadOut.bits.uop := load_s2.io.out.bits.uop 29403a91a79SWilliam Wang intHitLoadOut.bits.data := load_s2.io.out.bits.data 29503a91a79SWilliam Wang intHitLoadOut.bits.redirectValid := false.B 29603a91a79SWilliam Wang intHitLoadOut.bits.redirect := DontCare 29703a91a79SWilliam Wang intHitLoadOut.bits.brUpdate := DontCare 29803a91a79SWilliam Wang intHitLoadOut.bits.debug.isMMIO := load_s2.io.out.bits.mmio 2998635f18fSwangkaifan intHitLoadOut.bits.debug.isPerfCnt := false.B 30003a91a79SWilliam Wang intHitLoadOut.bits.fflags := DontCare 301024ee227SWilliam Wang 3027962cc88SWilliam Wang load_s2.io.out.ready := true.B 303c5c06e78SWilliam Wang 30403a91a79SWilliam Wang io.ldout.bits := Mux(intHitLoadOut.valid, intHitLoadOut.bits, io.lsq.ldout.bits) 30503a91a79SWilliam Wang io.ldout.valid := intHitLoadOut.valid || io.lsq.ldout.valid && !refillFpLoad 306c5c06e78SWilliam Wang 30703a91a79SWilliam Wang // Fp load, if hit, will be send to recoder at s2, then it will be recoded & writebacked at s3 30803a91a79SWilliam Wang val fpHitLoadOut = Wire(Valid(new ExuOutput)) 30926a692b9SYinan Xu fpHitLoadOut.valid := s2_wb_valid && load_s2.io.out.bits.uop.ctrl.fpWen 31003a91a79SWilliam Wang fpHitLoadOut.bits := intHitLoadOut.bits 31103a91a79SWilliam Wang 31203a91a79SWilliam Wang val fpLoadOut = Wire(Valid(new ExuOutput)) 31303a91a79SWilliam Wang fpLoadOut.bits := Mux(fpHitLoadOut.valid, fpHitLoadOut.bits, io.lsq.ldout.bits) 31403a91a79SWilliam Wang fpLoadOut.valid := fpHitLoadOut.valid || io.lsq.ldout.valid && refillFpLoad 31503a91a79SWilliam Wang 31603a91a79SWilliam Wang val fpLoadOutReg = RegNext(fpLoadOut) 31703a91a79SWilliam Wang io.fpout.bits := fpLoadOutReg.bits 31803a91a79SWilliam Wang io.fpout.bits.data := fpRdataHelper(fpLoadOutReg.bits.uop, fpLoadOutReg.bits.data) // recode 31918a5d947SZhangfw io.fpout.valid := RegNext(fpLoadOut.valid) 32003a91a79SWilliam Wang 321c3d4d93eSZhangfw io.lsq.ldout.ready := Mux(refillFpLoad, !fpHitLoadOut.valid, !intHitLoadOut.valid) 322024ee227SWilliam Wang 323024ee227SWilliam Wang when(io.ldout.fire()){ 324c5c06e78SWilliam Wang XSDebug("ldout %x\n", io.ldout.bits.uop.cf.pc) 325c5c06e78SWilliam Wang } 326c5c06e78SWilliam Wang 327c5c06e78SWilliam Wang when(io.fpout.fire()){ 328c5c06e78SWilliam Wang XSDebug("fpout %x\n", io.fpout.bits.uop.cf.pc) 329024ee227SWilliam Wang } 330024ee227SWilliam Wang} 331