1*024ee227SWilliam Wangpackage xiangshan.mem 2*024ee227SWilliam Wang 3*024ee227SWilliam Wangimport chisel3._ 4*024ee227SWilliam Wangimport chisel3.util._ 5*024ee227SWilliam Wangimport utils._ 6*024ee227SWilliam Wangimport xiangshan._ 7*024ee227SWilliam Wangimport xiangshan.cache.{DCacheWordIO, TlbRequestIO, TlbCmd, MemoryOpConstants} 8*024ee227SWilliam Wangimport xiangshan.backend.LSUOpType 9*024ee227SWilliam Wang 10*024ee227SWilliam Wangclass LoadToLsroqIO extends XSBundle { 11*024ee227SWilliam Wang val loadIn = ValidIO(new LsPipelineBundle) 12*024ee227SWilliam Wang val ldout = Flipped(DecoupledIO(new ExuOutput)) 13*024ee227SWilliam Wang val forward = new LoadForwardQueryIO 14*024ee227SWilliam Wang} 15*024ee227SWilliam Wang 16*024ee227SWilliam Wangclass LoadUnit extends XSModule { 17*024ee227SWilliam Wang val io = IO(new Bundle() { 18*024ee227SWilliam Wang val ldin = Flipped(Decoupled(new ExuInput)) 19*024ee227SWilliam Wang val ldout = Decoupled(new ExuOutput) 20*024ee227SWilliam Wang val redirect = Flipped(ValidIO(new Redirect)) 21*024ee227SWilliam Wang val tlbFeedback = ValidIO(new TlbFeedback) 22*024ee227SWilliam Wang val dcache = new DCacheWordIO 23*024ee227SWilliam Wang val dtlb = new TlbRequestIO() 24*024ee227SWilliam Wang val sbuffer = new LoadForwardQueryIO 25*024ee227SWilliam Wang val lsroq = new LoadToLsroqIO 26*024ee227SWilliam Wang }) 27*024ee227SWilliam Wang 28*024ee227SWilliam Wang when(io.ldin.valid){ 29*024ee227SWilliam Wang XSDebug("load enpipe %x iw %x fw %x\n", io.ldin.bits.uop.cf.pc, io.ldin.bits.uop.ctrl.rfWen, io.ldin.bits.uop.ctrl.fpWen) 30*024ee227SWilliam Wang } 31*024ee227SWilliam Wang 32*024ee227SWilliam Wang //------------------------------------------------------- 33*024ee227SWilliam Wang // Load Pipeline 34*024ee227SWilliam Wang //------------------------------------------------------- 35*024ee227SWilliam Wang 36*024ee227SWilliam Wang val l2_out = Wire(Decoupled(new LsPipelineBundle)) 37*024ee227SWilliam Wang val l4_out = Wire(Decoupled(new LsPipelineBundle)) 38*024ee227SWilliam Wang val l5_in = Wire(Flipped(Decoupled(new LsPipelineBundle))) 39*024ee227SWilliam Wang 40*024ee227SWilliam Wang //------------------------------------------------------- 41*024ee227SWilliam Wang // LD Pipeline Stage 2 42*024ee227SWilliam Wang // Generate addr, use addr to query DCache Tag and DTLB 43*024ee227SWilliam Wang //------------------------------------------------------- 44*024ee227SWilliam Wang 45*024ee227SWilliam Wang val l2_dtlb_hit = Wire(new Bool()) 46*024ee227SWilliam Wang val l2_dtlb_miss = Wire(new Bool()) 47*024ee227SWilliam Wang val l2_dcache = Wire(new Bool()) 48*024ee227SWilliam Wang val l2_mmio = Wire(new Bool()) 49*024ee227SWilliam Wang val isMMIOReq = Wire(new Bool()) 50*024ee227SWilliam Wang 51*024ee227SWilliam Wang // send req to dtlb 52*024ee227SWilliam Wang io.dtlb.req.valid := l2_out.valid 53*024ee227SWilliam Wang io.dtlb.req.bits.vaddr := l2_out.bits.vaddr 54*024ee227SWilliam Wang io.dtlb.req.bits.cmd := TlbCmd.read 55*024ee227SWilliam Wang io.dtlb.req.bits.roqIdx := l2_out.bits.uop.roqIdx 56*024ee227SWilliam Wang io.dtlb.req.bits.debug.pc := l2_out.bits.uop.cf.pc 57*024ee227SWilliam Wang io.dtlb.req.bits.debug.lsroqIdx := l2_out.bits.uop.lsroqIdx 58*024ee227SWilliam Wang 59*024ee227SWilliam Wang l2_dtlb_hit := io.dtlb.resp.valid && !io.dtlb.resp.bits.miss 60*024ee227SWilliam Wang l2_dtlb_miss := io.dtlb.resp.valid && io.dtlb.resp.bits.miss 61*024ee227SWilliam Wang isMMIOReq := AddressSpace.isMMIO(io.dtlb.resp.bits.paddr) 62*024ee227SWilliam Wang l2_dcache := l2_dtlb_hit && !isMMIOReq 63*024ee227SWilliam Wang l2_mmio := l2_dtlb_hit && isMMIOReq 64*024ee227SWilliam Wang 65*024ee227SWilliam Wang // l2_out is used to generate dcache req 66*024ee227SWilliam Wang l2_out.bits := DontCare 67*024ee227SWilliam Wang l2_out.bits.vaddr := io.ldin.bits.src1 + io.ldin.bits.uop.ctrl.imm 68*024ee227SWilliam Wang l2_out.bits.paddr := io.dtlb.resp.bits.paddr 69*024ee227SWilliam Wang l2_out.bits.mask := genWmask(l2_out.bits.vaddr, io.ldin.bits.uop.ctrl.fuOpType(1,0)) 70*024ee227SWilliam Wang l2_out.bits.uop := io.ldin.bits.uop 71*024ee227SWilliam Wang l2_out.bits.miss := false.B 72*024ee227SWilliam Wang l2_out.bits.mmio := l2_mmio 73*024ee227SWilliam Wang l2_out.valid := io.ldin.valid && !io.ldin.bits.uop.needFlush(io.redirect) 74*024ee227SWilliam Wang // when we are sure it's a MMIO req, we do not need to wait for cache ready 75*024ee227SWilliam Wang l2_out.ready := (l2_dcache && io.dcache.req.ready) || l2_mmio || l2_dtlb_miss 76*024ee227SWilliam Wang io.ldin.ready := l2_out.ready 77*024ee227SWilliam Wang 78*024ee227SWilliam Wang // exception check 79*024ee227SWilliam Wang val addrAligned = LookupTree(io.ldin.bits.uop.ctrl.fuOpType(1,0), List( 80*024ee227SWilliam Wang "b00".U -> true.B, //b 81*024ee227SWilliam Wang "b01".U -> (l2_out.bits.vaddr(0) === 0.U), //h 82*024ee227SWilliam Wang "b10".U -> (l2_out.bits.vaddr(1,0) === 0.U), //w 83*024ee227SWilliam Wang "b11".U -> (l2_out.bits.vaddr(2,0) === 0.U) //d 84*024ee227SWilliam Wang )) 85*024ee227SWilliam Wang l2_out.bits.uop.cf.exceptionVec(loadAddrMisaligned) := !addrAligned 86*024ee227SWilliam Wang l2_out.bits.uop.cf.exceptionVec(loadPageFault) := io.dtlb.resp.bits.excp.pf.ld 87*024ee227SWilliam Wang 88*024ee227SWilliam Wang // send result to dcache 89*024ee227SWilliam Wang // never send tlb missed or MMIO reqs to dcache 90*024ee227SWilliam Wang io.dcache.req.valid := l2_dcache 91*024ee227SWilliam Wang 92*024ee227SWilliam Wang io.dcache.req.bits.cmd := MemoryOpConstants.M_XRD 93*024ee227SWilliam Wang // TODO: vaddr 94*024ee227SWilliam Wang io.dcache.req.bits.addr := io.dtlb.resp.bits.paddr 95*024ee227SWilliam Wang io.dcache.req.bits.data := DontCare 96*024ee227SWilliam Wang io.dcache.req.bits.mask := l2_out.bits.mask 97*024ee227SWilliam Wang 98*024ee227SWilliam Wang io.dcache.req.bits.meta.id := DontCare 99*024ee227SWilliam Wang io.dcache.req.bits.meta.vaddr := l2_out.bits.vaddr 100*024ee227SWilliam Wang io.dcache.req.bits.meta.paddr := io.dtlb.resp.bits.paddr 101*024ee227SWilliam Wang io.dcache.req.bits.meta.uop := l2_out.bits.uop 102*024ee227SWilliam Wang io.dcache.req.bits.meta.mmio := isMMIOReq 103*024ee227SWilliam Wang io.dcache.req.bits.meta.tlb_miss := io.dtlb.resp.bits.miss 104*024ee227SWilliam Wang io.dcache.req.bits.meta.mask := l2_out.bits.mask 105*024ee227SWilliam Wang io.dcache.req.bits.meta.replay := false.B 106*024ee227SWilliam Wang 107*024ee227SWilliam Wang 108*024ee227SWilliam Wang val l2_tlbFeedback = Wire(new TlbFeedback) 109*024ee227SWilliam Wang l2_tlbFeedback.hit := !io.dtlb.resp.bits.miss 110*024ee227SWilliam Wang l2_tlbFeedback.roqIdx := l2_out.bits.uop.roqIdx 111*024ee227SWilliam Wang 112*024ee227SWilliam Wang // dump l2 113*024ee227SWilliam Wang XSDebug(l2_out.valid, "L2: pc 0x%x addr 0x%x -> 0x%x op %b data 0x%x mask %x dltb_miss %b dcache %b mmio %b\n", 114*024ee227SWilliam Wang l2_out.bits.uop.cf.pc, l2_out.bits.vaddr, l2_out.bits.paddr, 115*024ee227SWilliam Wang l2_out.bits.uop.ctrl.fuOpType, l2_out.bits.data, l2_out.bits.mask, 116*024ee227SWilliam Wang l2_dtlb_miss, l2_dcache, l2_mmio) 117*024ee227SWilliam Wang 118*024ee227SWilliam Wang XSDebug(l2_out.fire(), "load req: pc 0x%x addr 0x%x -> 0x%x op %b\n", 119*024ee227SWilliam Wang l2_out.bits.uop.cf.pc, l2_out.bits.vaddr, l2_out.bits.paddr, l2_out.bits.uop.ctrl.fuOpType) 120*024ee227SWilliam Wang 121*024ee227SWilliam Wang XSDebug(io.dcache.req.valid, p"dcache req(${io.dcache.req.valid} ${io.dcache.req.ready}): pc:0x${Hexadecimal(io.dcache.req.bits.meta.uop.cf.pc)} roqIdx:${io.dcache.req.bits.meta.uop.roqIdx} lsroqIdx:${io.dcache.req.bits.meta.uop.lsroqIdx} addr:0x${Hexadecimal(io.dcache.req.bits.addr)} vaddr:0x${Hexadecimal(io.dcache.req.bits.meta.vaddr)} paddr:0x${Hexadecimal(io.dcache.req.bits.meta.paddr)} mmio:${io.dcache.req.bits.meta.mmio} tlb_miss:${io.dcache.req.bits.meta.tlb_miss} mask:${io.dcache.req.bits.meta.mask}\n") 122*024ee227SWilliam Wang 123*024ee227SWilliam Wang //------------------------------------------------------- 124*024ee227SWilliam Wang // LD Pipeline Stage 3 125*024ee227SWilliam Wang // Compare tag, use addr to query DCache Data 126*024ee227SWilliam Wang //------------------------------------------------------- 127*024ee227SWilliam Wang 128*024ee227SWilliam Wang val l3_valid = RegNext(l2_out.fire(), false.B) 129*024ee227SWilliam Wang val l3_dtlb_miss = RegEnable(next = l2_dtlb_miss, enable = l2_out.fire(), init = false.B) 130*024ee227SWilliam Wang val l3_dcache = RegEnable(next = l2_dcache, enable = l2_out.fire(), init = false.B) 131*024ee227SWilliam Wang val l3_tlbFeedback = RegEnable(next = l2_tlbFeedback, enable = l2_out.fire()) 132*024ee227SWilliam Wang val l3_bundle = RegEnable(next = l2_out.bits, enable = l2_out.fire()) 133*024ee227SWilliam Wang val l3_uop = l3_bundle.uop 134*024ee227SWilliam Wang // dltb miss reqs ends here 135*024ee227SWilliam Wang val l3_passdown = l3_valid && !l3_dtlb_miss && !l3_uop.needFlush(io.redirect) 136*024ee227SWilliam Wang 137*024ee227SWilliam Wang io.tlbFeedback.valid := l3_valid 138*024ee227SWilliam Wang io.tlbFeedback.bits := l3_tlbFeedback 139*024ee227SWilliam Wang io.dcache.s1_kill := l3_valid && l3_dcache && l3_uop.needFlush(io.redirect) 140*024ee227SWilliam Wang 141*024ee227SWilliam Wang // dump l3 142*024ee227SWilliam Wang XSDebug(l3_valid, "l3: pc 0x%x addr 0x%x -> 0x%x op %b data 0x%x mask %x dltb_miss %b dcache %b mmio %b\n", 143*024ee227SWilliam Wang l3_bundle.uop.cf.pc, l3_bundle.vaddr, l3_bundle.paddr, 144*024ee227SWilliam Wang l3_bundle.uop.ctrl.fuOpType, l3_bundle.data, l3_bundle.mask, 145*024ee227SWilliam Wang l3_dtlb_miss, l3_dcache, l3_bundle.mmio) 146*024ee227SWilliam Wang 147*024ee227SWilliam Wang XSDebug(io.tlbFeedback.valid, "tlbFeedback: hit %b roqIdx %d\n", 148*024ee227SWilliam Wang io.tlbFeedback.bits.hit, io.tlbFeedback.bits.roqIdx) 149*024ee227SWilliam Wang 150*024ee227SWilliam Wang XSDebug(io.dcache.s1_kill, "l3: dcache s1_kill\n") 151*024ee227SWilliam Wang 152*024ee227SWilliam Wang // Done in Dcache 153*024ee227SWilliam Wang 154*024ee227SWilliam Wang //------------------------------------------------------- 155*024ee227SWilliam Wang // LD Pipeline Stage 4 156*024ee227SWilliam Wang // Dcache return result, do tag ecc check and forward check 157*024ee227SWilliam Wang //------------------------------------------------------- 158*024ee227SWilliam Wang 159*024ee227SWilliam Wang val l4_valid = RegNext(l3_passdown, false.B) 160*024ee227SWilliam Wang val l4_dcache = RegNext(l3_dcache, false.B) 161*024ee227SWilliam Wang val l4_bundle = RegNext(l3_bundle) 162*024ee227SWilliam Wang 163*024ee227SWilliam Wang val fullForward = Wire(Bool()) 164*024ee227SWilliam Wang 165*024ee227SWilliam Wang assert(!(io.dcache.resp.ready && !io.dcache.resp.valid), "DCache response got lost") 166*024ee227SWilliam Wang io.dcache.resp.ready := l4_valid && l4_dcache 167*024ee227SWilliam Wang when (io.dcache.resp.fire()) { 168*024ee227SWilliam Wang l4_out.bits := DontCare 169*024ee227SWilliam Wang l4_out.bits.data := io.dcache.resp.bits.data 170*024ee227SWilliam Wang l4_out.bits.paddr := io.dcache.resp.bits.meta.paddr 171*024ee227SWilliam Wang l4_out.bits.uop := io.dcache.resp.bits.meta.uop 172*024ee227SWilliam Wang l4_out.bits.mmio := io.dcache.resp.bits.meta.mmio 173*024ee227SWilliam Wang l4_out.bits.mask := io.dcache.resp.bits.meta.mask 174*024ee227SWilliam Wang // when we can get the data completely from forward 175*024ee227SWilliam Wang // we no longer need to access dcache 176*024ee227SWilliam Wang // treat nack as miss 177*024ee227SWilliam Wang l4_out.bits.miss := Mux(fullForward, false.B, 178*024ee227SWilliam Wang io.dcache.resp.bits.miss || io.dcache.resp.bits.nack) 179*024ee227SWilliam Wang XSDebug(io.dcache.resp.fire(), p"DcacheResp(l4): data:0x${Hexadecimal(io.dcache.resp.bits.data)} paddr:0x${Hexadecimal(io.dcache.resp.bits.meta.paddr)} pc:0x${Hexadecimal(io.dcache.resp.bits.meta.uop.cf.pc)} roqIdx:${io.dcache.resp.bits.meta.uop.roqIdx} lsroqIdx:${io.dcache.resp.bits.meta.uop.lsroqIdx} miss:${io.dcache.resp.bits.miss}\n") 180*024ee227SWilliam Wang } .otherwise { 181*024ee227SWilliam Wang l4_out.bits := l4_bundle 182*024ee227SWilliam Wang } 183*024ee227SWilliam Wang l4_out.valid := l4_valid && !l4_out.bits.uop.needFlush(io.redirect) 184*024ee227SWilliam Wang 185*024ee227SWilliam Wang // Store addr forward match 186*024ee227SWilliam Wang // If match, get data / fmask from store queue / store buffer 187*024ee227SWilliam Wang 188*024ee227SWilliam Wang io.lsroq.forward.paddr := l4_out.bits.paddr 189*024ee227SWilliam Wang io.lsroq.forward.mask := io.dcache.resp.bits.meta.mask 190*024ee227SWilliam Wang io.lsroq.forward.lsroqIdx := l4_out.bits.uop.lsroqIdx 191*024ee227SWilliam Wang io.lsroq.forward.uop := l4_out.bits.uop 192*024ee227SWilliam Wang io.lsroq.forward.pc := l4_out.bits.uop.cf.pc 193*024ee227SWilliam Wang io.lsroq.forward.valid := io.dcache.resp.valid //TODO: opt timing 194*024ee227SWilliam Wang 195*024ee227SWilliam Wang io.sbuffer.paddr := l4_out.bits.paddr 196*024ee227SWilliam Wang io.sbuffer.mask := io.dcache.resp.bits.meta.mask 197*024ee227SWilliam Wang io.sbuffer.lsroqIdx := l4_out.bits.uop.lsroqIdx 198*024ee227SWilliam Wang io.sbuffer.uop := DontCare 199*024ee227SWilliam Wang io.sbuffer.pc := l4_out.bits.uop.cf.pc 200*024ee227SWilliam Wang io.sbuffer.valid := l4_out.valid 201*024ee227SWilliam Wang 202*024ee227SWilliam Wang val forwardVec = WireInit(io.sbuffer.forwardData) 203*024ee227SWilliam Wang val forwardMask = WireInit(io.sbuffer.forwardMask) 204*024ee227SWilliam Wang // generate XLEN/8 Muxs 205*024ee227SWilliam Wang (0 until XLEN/8).map(j => { 206*024ee227SWilliam Wang when(io.lsroq.forward.forwardMask(j)) { 207*024ee227SWilliam Wang forwardMask(j) := true.B 208*024ee227SWilliam Wang forwardVec(j) := io.lsroq.forward.forwardData(j) 209*024ee227SWilliam Wang } 210*024ee227SWilliam Wang }) 211*024ee227SWilliam Wang l4_out.bits.forwardMask := forwardMask 212*024ee227SWilliam Wang l4_out.bits.forwardData := forwardVec 213*024ee227SWilliam Wang fullForward := (~l4_out.bits.forwardMask.asUInt & l4_out.bits.mask) === 0.U 214*024ee227SWilliam Wang 215*024ee227SWilliam Wang PipelineConnect(l4_out, l5_in, io.ldout.fire() || (l5_in.bits.miss || l5_in.bits.mmio) && l5_in.valid, false.B) 216*024ee227SWilliam Wang 217*024ee227SWilliam Wang XSDebug(l4_valid, "l4: out.valid:%d pc 0x%x addr 0x%x -> 0x%x op %b data 0x%x mask %x forwardData: 0x%x forwardMask: %x dcache %b mmio %b miss:%d\n", 218*024ee227SWilliam Wang l4_out.valid, l4_out.bits.uop.cf.pc, l4_out.bits.vaddr, l4_out.bits.paddr, 219*024ee227SWilliam Wang l4_out.bits.uop.ctrl.fuOpType, l4_out.bits.data, l4_out.bits.mask, 220*024ee227SWilliam Wang l4_out.bits.forwardData.asUInt, l4_out.bits.forwardMask.asUInt, l4_dcache, l4_out.bits.mmio, l4_out.bits.miss) 221*024ee227SWilliam Wang 222*024ee227SWilliam Wang XSDebug(l5_in.valid, "L5(%d %d): pc 0x%x addr 0x%x -> 0x%x op %b data 0x%x mask %x forwardData: 0x%x forwardMask: %x\n", 223*024ee227SWilliam Wang l5_in.valid, l5_in.ready, l5_in.bits.uop.cf.pc, l5_in.bits.vaddr, l5_in.bits.paddr, 224*024ee227SWilliam Wang l5_in.bits.uop.ctrl.fuOpType , l5_in.bits.data, l5_in.bits.mask, 225*024ee227SWilliam Wang l5_in.bits.forwardData.asUInt, l5_in.bits.forwardMask.asUInt) 226*024ee227SWilliam Wang 227*024ee227SWilliam Wang XSDebug(l4_valid, "l4: sbuffer forwardData: 0x%x forwardMask: %x\n", 228*024ee227SWilliam Wang io.sbuffer.forwardData.asUInt, io.sbuffer.forwardMask.asUInt) 229*024ee227SWilliam Wang 230*024ee227SWilliam Wang XSDebug(l4_valid, "l4: lsroq forwardData: 0x%x forwardMask: %x\n", 231*024ee227SWilliam Wang io.lsroq.forward.forwardData.asUInt, io.lsroq.forward.forwardMask.asUInt) 232*024ee227SWilliam Wang 233*024ee227SWilliam Wang XSDebug(io.redirect.valid, p"Redirect: excp:${io.redirect.bits.isException} flushPipe:${io.redirect.bits.isFlushPipe} misp:${io.redirect.bits.isMisPred} replay:${io.redirect.bits.isReplay} pc:0x${Hexadecimal(io.redirect.bits.pc)} target:0x${Hexadecimal(io.redirect.bits.target)} brTag:${io.redirect.bits.brTag} l2:${io.ldin.bits.uop.needFlush(io.redirect)} l3:${l3_uop.needFlush(io.redirect)} l4:${l4_out.bits.uop.needFlush(io.redirect)}\n") 234*024ee227SWilliam Wang //------------------------------------------------------- 235*024ee227SWilliam Wang // LD Pipeline Stage 5 236*024ee227SWilliam Wang // Do data ecc check, merge result and write back to LS ROQ 237*024ee227SWilliam Wang // If cache hit, return writeback result to CDB 238*024ee227SWilliam Wang //------------------------------------------------------- 239*024ee227SWilliam Wang 240*024ee227SWilliam Wang val loadWriteBack = l5_in.fire() 241*024ee227SWilliam Wang 242*024ee227SWilliam Wang // data merge 243*024ee227SWilliam Wang val rdata = VecInit((0 until 8).map(j => { 244*024ee227SWilliam Wang Mux(l5_in.bits.forwardMask(j), 245*024ee227SWilliam Wang l5_in.bits.forwardData(j), 246*024ee227SWilliam Wang l5_in.bits.data(8*(j+1)-1, 8*j) 247*024ee227SWilliam Wang ) 248*024ee227SWilliam Wang })).asUInt 249*024ee227SWilliam Wang val func = l5_in.bits.uop.ctrl.fuOpType 250*024ee227SWilliam Wang val raddr = l5_in.bits.paddr 251*024ee227SWilliam Wang val rdataSel = LookupTree(raddr(2, 0), List( 252*024ee227SWilliam Wang "b000".U -> rdata(63, 0), 253*024ee227SWilliam Wang "b001".U -> rdata(63, 8), 254*024ee227SWilliam Wang "b010".U -> rdata(63, 16), 255*024ee227SWilliam Wang "b011".U -> rdata(63, 24), 256*024ee227SWilliam Wang "b100".U -> rdata(63, 32), 257*024ee227SWilliam Wang "b101".U -> rdata(63, 40), 258*024ee227SWilliam Wang "b110".U -> rdata(63, 48), 259*024ee227SWilliam Wang "b111".U -> rdata(63, 56) 260*024ee227SWilliam Wang )) 261*024ee227SWilliam Wang val rdataPartialLoad = LookupTree(func, List( 262*024ee227SWilliam Wang LSUOpType.lb -> SignExt(rdataSel(7, 0) , XLEN), 263*024ee227SWilliam Wang LSUOpType.lh -> SignExt(rdataSel(15, 0), XLEN), 264*024ee227SWilliam Wang LSUOpType.lw -> SignExt(rdataSel(31, 0), XLEN), 265*024ee227SWilliam Wang LSUOpType.ld -> SignExt(rdataSel(63, 0), XLEN), 266*024ee227SWilliam Wang LSUOpType.lbu -> ZeroExt(rdataSel(7, 0) , XLEN), 267*024ee227SWilliam Wang LSUOpType.lhu -> ZeroExt(rdataSel(15, 0), XLEN), 268*024ee227SWilliam Wang LSUOpType.lwu -> ZeroExt(rdataSel(31, 0), XLEN) 269*024ee227SWilliam Wang )) 270*024ee227SWilliam Wang 271*024ee227SWilliam Wang // ecc check 272*024ee227SWilliam Wang // TODO 273*024ee227SWilliam Wang 274*024ee227SWilliam Wang // if hit, writeback result to CDB 275*024ee227SWilliam Wang // val ldout = Vec(2, Decoupled(new ExuOutput)) 276*024ee227SWilliam Wang // when io.loadIn(i).fire() && !io.io.loadIn(i).miss, commit load to cdb 277*024ee227SWilliam Wang val hitLoadOut = Wire(Decoupled(new ExuOutput)) 278*024ee227SWilliam Wang hitLoadOut.bits.uop := l5_in.bits.uop 279*024ee227SWilliam Wang hitLoadOut.bits.data := rdataPartialLoad 280*024ee227SWilliam Wang hitLoadOut.bits.redirectValid := false.B 281*024ee227SWilliam Wang hitLoadOut.bits.redirect := DontCare 282*024ee227SWilliam Wang hitLoadOut.bits.brUpdate := DontCare 283*024ee227SWilliam Wang hitLoadOut.bits.debug.isMMIO := l5_in.bits.mmio 284*024ee227SWilliam Wang hitLoadOut.valid := l5_in.valid && !l5_in.bits.mmio && !l5_in.bits.miss // MMIO will be done in lsroq 285*024ee227SWilliam Wang XSDebug(hitLoadOut.fire(), "load writeback: pc %x data %x (%x + %x(%b))\n", 286*024ee227SWilliam Wang hitLoadOut.bits.uop.cf.pc, rdataPartialLoad, l5_in.bits.data, 287*024ee227SWilliam Wang l5_in.bits.forwardData.asUInt, l5_in.bits.forwardMask.asUInt 288*024ee227SWilliam Wang ) 289*024ee227SWilliam Wang 290*024ee227SWilliam Wang // writeback to LSROQ 291*024ee227SWilliam Wang // Current dcache use MSHR 292*024ee227SWilliam Wang 293*024ee227SWilliam Wang io.lsroq.loadIn.bits := l5_in.bits 294*024ee227SWilliam Wang io.lsroq.loadIn.bits.data := rdataPartialLoad // for debug 295*024ee227SWilliam Wang io.lsroq.loadIn.valid := loadWriteBack 296*024ee227SWilliam Wang 297*024ee227SWilliam Wang // pipeline control 298*024ee227SWilliam Wang l5_in.ready := io.ldout.ready 299*024ee227SWilliam Wang 300*024ee227SWilliam Wang val cdbArb = Module(new Arbiter(new ExuOutput, 2)) 301*024ee227SWilliam Wang io.ldout <> cdbArb.io.out 302*024ee227SWilliam Wang hitLoadOut <> cdbArb.io.in(0) 303*024ee227SWilliam Wang io.lsroq.ldout <> cdbArb.io.in(1) // missLoadOut 304*024ee227SWilliam Wang 305*024ee227SWilliam Wang when(io.ldout.fire()){ 306*024ee227SWilliam Wang XSDebug("ldout %x iw %x fw %x\n", io.ldout.bits.uop.cf.pc, io.ldout.bits.uop.ctrl.rfWen, io.ldout.bits.uop.ctrl.fpWen) 307*024ee227SWilliam Wang } 308*024ee227SWilliam Wang} 309