1/*************************************************************************************** 2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3* Copyright (c) 2020-2021 Peng Cheng Laboratory 4* 5* XiangShan is licensed under Mulan PSL v2. 6* You can use this software according to the terms and conditions of the Mulan PSL v2. 7* You may obtain a copy of Mulan PSL v2 at: 8* http://license.coscl.org.cn/MulanPSL2 9* 10* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13* 14* See the Mulan PSL v2 for more details. 15***************************************************************************************/ 16 17package xiangshan.mem 18 19import org.chipsalliance.cde.config.Parameters 20import chisel3._ 21import chisel3.util._ 22import utility.{XSDebug, XSInfo} 23import xiangshan._ 24import xiangshan.mem.Bundles._ 25import xiangshan.cache.{DCacheLineIO, DCacheWordReq, MemoryOpConstants, DCacheWordReqWithVaddr} 26 27// Fake Store buffer for XiangShan Out of Order LSU 28// 29// Note: fake store buffer is out of date, as store buffer is now 30// used as extended dcache miss queue for store 31class FakeSbuffer(implicit p: Parameters) extends XSModule { 32 val io = IO(new Bundle() { 33 val in = Vec(StorePipelineWidth, Flipped(Decoupled(new DCacheWordReqWithVaddr))) 34 val dcache = new DCacheLineIO 35 val forward = Vec(LoadPipelineWidth, Flipped(new LoadForwardQueryIO)) 36 }) 37 38 assert(!(io.in(1).valid && !io.in(0).valid)) 39 40 // assign default values to signals 41 io.in(1).ready := false.B 42 43 io.dcache.req.valid := false.B 44 io.dcache.req.bits := DontCare 45 io.dcache.resp.ready := false.B 46 47 val s_invalid :: s_req :: s_resp :: Nil = Enum(3) 48 49 val state = RegInit(s_invalid) 50 51 val req = Reg(new DCacheWordReqWithVaddr) 52 53 XSDebug("state: %d\n", state) 54 55 io.in(0).ready := state === s_invalid 56 57 def word_addr(addr: UInt) = (addr >> 3) << 3 58 def block_addr(addr: UInt) = (addr >> 6) << 6 59 60 // -------------------------------------------- 61 // s_invalid: receive requests 62 when (state === s_invalid) { 63 when (io.in(0).fire) { 64 req := io.in(0).bits 65 state := s_req 66 } 67 } 68 69 val wdataVec = WireInit(VecInit(Seq.fill(8)(0.U(64.W)))) 70 val wmaskVec = WireInit(VecInit(Seq.fill(8)(0.U(8.W)))) 71 wdataVec(req.addr(5,3)) := req.data 72 wmaskVec(req.addr(5,3)) := req.mask 73 74 when (state === s_req) { 75 val dcache_req = io.dcache.req 76 dcache_req.valid := true.B 77 dcache_req.bits.cmd := MemoryOpConstants.M_XWR 78 dcache_req.bits.addr := block_addr(req.addr) 79 dcache_req.bits.data := wdataVec.asUInt 80 dcache_req.bits.mask := wmaskVec.asUInt 81 dcache_req.bits.id := DontCare 82 83 when (dcache_req.fire) { 84 state := s_resp 85 } 86 } 87 88 when (state === s_resp) { 89 io.dcache.resp.ready := true.B 90 when (io.dcache.resp.fire) { 91 state := s_invalid 92 } 93 } 94 95 // do forwarding here 96 for (i <- 0 until LoadPipelineWidth) { 97 val addr_match = word_addr(io.forward(i).paddr) === word_addr(req.addr) 98 val mask = io.forward(i).mask & req.mask(7, 0) 99 val mask_match = mask =/= 0.U 100 val need_forward = state =/= s_invalid && addr_match && mask_match 101 102 io.forward(i).forwardMask := Mux(need_forward, VecInit(mask.asBools), 103 VecInit(0.U(8.W).asBools)) 104 io.forward(i).forwardData := VecInit((0 until 8) map {i => req.data((i + 1) * 8 - 1, i * 8)}) 105 } 106 107 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) 108 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) 109 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) 110} 111