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