xref: /XiangShan/src/main/scala/xiangshan/mem/sbuffer/FakeSbuffer.scala (revision c6d439803a044ea209139672b25e35fe8d7f4aa0)
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