1package xiangshan.mem 2 3import chipsalliance.rocketchip.config.Parameters 4import chisel3._ 5import chisel3.util._ 6import utils.{XSDebug, XSInfo} 7import xiangshan._ 8import xiangshan.cache.{DCacheLineIO, DCacheWordReq, MemoryOpConstants} 9 10// Fake Store buffer for XiangShan Out of Order LSU 11class FakeSbuffer(implicit p: Parameters) extends XSModule { 12 val io = IO(new Bundle() { 13 val in = Vec(StorePipelineWidth, Flipped(Decoupled(new DCacheWordReq))) 14 val dcache = new DCacheLineIO 15 val forward = Vec(LoadPipelineWidth, Flipped(new LoadForwardQueryIO)) 16 }) 17 18 assert(!(io.in(1).valid && !io.in(0).valid)) 19 20 // assign default values to signals 21 io.in(1).ready := false.B 22 23 io.dcache.req.valid := false.B 24 io.dcache.req.bits := DontCare 25 io.dcache.resp.ready := false.B 26 27 val s_invalid :: s_req :: s_resp :: Nil = Enum(3) 28 29 val state = RegInit(s_invalid) 30 31 val req = Reg(new DCacheWordReq) 32 33 XSDebug("state: %d\n", state) 34 35 io.in(0).ready := state === s_invalid 36 37 def word_addr(addr: UInt) = (addr >> 3) << 3 38 def block_addr(addr: UInt) = (addr >> 6) << 6 39 40 // -------------------------------------------- 41 // s_invalid: receive requests 42 when (state === s_invalid) { 43 when (io.in(0).fire()) { 44 req := io.in(0).bits 45 state := s_req 46 } 47 } 48 49 val wdataVec = WireInit(VecInit(Seq.fill(8)(0.U(64.W)))) 50 val wmaskVec = WireInit(VecInit(Seq.fill(8)(0.U(8.W)))) 51 wdataVec(req.addr(5,3)) := req.data 52 wmaskVec(req.addr(5,3)) := req.mask 53 54 when (state === s_req) { 55 val dcache_req = io.dcache.req 56 dcache_req.valid := true.B 57 dcache_req.bits.cmd := MemoryOpConstants.M_XWR 58 dcache_req.bits.addr := block_addr(req.addr) 59 dcache_req.bits.data := wdataVec.asUInt 60 dcache_req.bits.mask := wmaskVec.asUInt 61 dcache_req.bits.id := DontCare 62 63 when (dcache_req.fire()) { 64 state := s_resp 65 } 66 } 67 68 when (state === s_resp) { 69 io.dcache.resp.ready := true.B 70 when (io.dcache.resp.fire()) { 71 state := s_invalid 72 } 73 } 74 75 // do forwarding here 76 for (i <- 0 until LoadPipelineWidth) { 77 val addr_match = word_addr(io.forward(i).paddr) === word_addr(req.addr) 78 val mask = io.forward(i).mask & req.mask(7, 0) 79 val mask_match = mask =/= 0.U 80 val need_forward = state =/= s_invalid && addr_match && mask_match 81 82 io.forward(i).forwardMask := Mux(need_forward, VecInit(mask.asBools), 83 VecInit(0.U(8.W).asBools)) 84 io.forward(i).forwardData := VecInit((0 until 8) map {i => req.data((i + 1) * 8 - 1, i * 8)}) 85 } 86 87 XSInfo(io.in(0).fire(), "ensbuffer addr 0x%x wdata 0x%x mask %b\n", io.in(0).bits.addr, io.in(0).bits.data, io.in(0).bits.mask) 88 XSInfo(io.in(1).fire(), "ensbuffer addr 0x%x wdata 0x%x mask %b\n", io.in(1).bits.addr, io.in(1).bits.data, io.in(0).bits.mask) 89 XSInfo(io.dcache.req.fire(), "desbuffer addr 0x%x wdata 0x%x mask %b\n", io.dcache.req.bits.addr, io.dcache.req.bits.data, io.dcache.req.bits.mask) 90} 91