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