xref: /XiangShan/src/main/scala/xiangshan/cache/dcache/mainpipe/AtomicsReplayUnit.scala (revision 8b33cd30e0034914b58520e0dc3c0c4b1aad6a03)
11f0e2dc7SJiawei Lin/***************************************************************************************
21f0e2dc7SJiawei Lin* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
31f0e2dc7SJiawei Lin* Copyright (c) 2020-2021 Peng Cheng Laboratory
41f0e2dc7SJiawei Lin*
51f0e2dc7SJiawei Lin* XiangShan is licensed under Mulan PSL v2.
61f0e2dc7SJiawei Lin* You can use this software according to the terms and conditions of the Mulan PSL v2.
71f0e2dc7SJiawei Lin* You may obtain a copy of Mulan PSL v2 at:
81f0e2dc7SJiawei Lin*          http://license.coscl.org.cn/MulanPSL2
91f0e2dc7SJiawei Lin*
101f0e2dc7SJiawei Lin* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
111f0e2dc7SJiawei Lin* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
121f0e2dc7SJiawei Lin* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
131f0e2dc7SJiawei Lin*
141f0e2dc7SJiawei Lin* See the Mulan PSL v2 for more details.
151f0e2dc7SJiawei Lin***************************************************************************************/
161f0e2dc7SJiawei Lin
171f0e2dc7SJiawei Linpackage xiangshan.cache
181f0e2dc7SJiawei Lin
198891a219SYinan Xuimport org.chipsalliance.cde.config.Parameters
201f0e2dc7SJiawei Linimport chisel3._
211f0e2dc7SJiawei Linimport chisel3.util._
22bb2f3f51STang Haojinimport utility.XSDebug
231f0e2dc7SJiawei Lin
241f0e2dc7SJiawei Linclass AtomicsReplayEntry(implicit p: Parameters) extends DCacheModule
251f0e2dc7SJiawei Lin{
261f0e2dc7SJiawei Lin  val io = IO(new Bundle {
276786cfb7SWilliam Wang    val lsu  = Flipped(new AtomicWordIO)
281f0e2dc7SJiawei Lin    val pipe_req  = Decoupled(new MainPipeReq)
29ffd3154dSCharlieLiu    val pipe_resp = Flipped(ValidIO(new MainPipeResp))
30b899def8SWilliam Wang    val block_lr = Input(Bool())
311f0e2dc7SJiawei Lin
321f0e2dc7SJiawei Lin    val block_addr  = Output(Valid(UInt()))
331f0e2dc7SJiawei Lin  })
341f0e2dc7SJiawei Lin
351f0e2dc7SJiawei Lin  val s_invalid :: s_pipe_req :: s_pipe_resp :: s_resp :: Nil = Enum(4)
361f0e2dc7SJiawei Lin  val state = RegInit(s_invalid)
371f0e2dc7SJiawei Lin
381f0e2dc7SJiawei Lin  val req = Reg(new DCacheWordReqWithVaddr)
391f0e2dc7SJiawei Lin
401f0e2dc7SJiawei Lin  // assign default values to output signals
411f0e2dc7SJiawei Lin  io.lsu.req.ready     := state === s_invalid
421f0e2dc7SJiawei Lin  io.lsu.resp.valid    := false.B
431f0e2dc7SJiawei Lin  io.lsu.resp.bits     := DontCare
441f0e2dc7SJiawei Lin
451f0e2dc7SJiawei Lin  io.pipe_req.valid    := false.B
461f0e2dc7SJiawei Lin  io.pipe_req.bits     := DontCare
471f0e2dc7SJiawei Lin
481f0e2dc7SJiawei Lin  io.block_addr.valid := state =/= s_invalid
491f0e2dc7SJiawei Lin  io.block_addr.bits  := req.addr
501f0e2dc7SJiawei Lin
511f0e2dc7SJiawei Lin
52*8b33cd30Sklin02  XSDebug(state =/= s_invalid, "AtomicsReplayEntry: state: %d block_addr: %x\n", state, io.block_addr.bits)
531f0e2dc7SJiawei Lin
541f0e2dc7SJiawei Lin  // --------------------------------------------
551f0e2dc7SJiawei Lin  // s_invalid: receive requests
561f0e2dc7SJiawei Lin  when (state === s_invalid) {
57935edac4STang Haojin    when (io.lsu.req.fire) {
581f0e2dc7SJiawei Lin      req   := io.lsu.req.bits
591f0e2dc7SJiawei Lin      state := s_pipe_req
601f0e2dc7SJiawei Lin    }
611f0e2dc7SJiawei Lin  }
621f0e2dc7SJiawei Lin
631f0e2dc7SJiawei Lin  // --------------------------------------------
641f0e2dc7SJiawei Lin  // replay
651f0e2dc7SJiawei Lin  when (state === s_pipe_req) {
66b899def8SWilliam Wang    io.pipe_req.valid := Mux(
67b899def8SWilliam Wang      io.pipe_req.bits.cmd === M_XLR,
68b899def8SWilliam Wang      !io.block_lr, // block lr to survive in lr storm
69b899def8SWilliam Wang      true.B
70b899def8SWilliam Wang    )
711f0e2dc7SJiawei Lin
721f0e2dc7SJiawei Lin    val pipe_req = io.pipe_req.bits
731f0e2dc7SJiawei Lin    pipe_req := DontCare
741f0e2dc7SJiawei Lin    pipe_req.miss := false.B
751f0e2dc7SJiawei Lin    pipe_req.probe := false.B
761f0e2dc7SJiawei Lin    pipe_req.probe_need_data := false.B
771f0e2dc7SJiawei Lin    pipe_req.source := AMO_SOURCE.U
781f0e2dc7SJiawei Lin    pipe_req.cmd    := req.cmd
791f0e2dc7SJiawei Lin    pipe_req.addr   := get_block_addr(req.addr)
801f0e2dc7SJiawei Lin    pipe_req.vaddr  := get_block_addr(req.vaddr)
811f0e2dc7SJiawei Lin    pipe_req.word_idx  := get_word(req.addr)
821f0e2dc7SJiawei Lin    pipe_req.amo_data  := req.data
831f0e2dc7SJiawei Lin    pipe_req.amo_mask  := req.mask
841f0e2dc7SJiawei Lin
85935edac4STang Haojin    when (io.pipe_req.fire) {
861f0e2dc7SJiawei Lin      state := s_pipe_resp
871f0e2dc7SJiawei Lin      assert(!io.pipe_req.bits.vaddr === 0.U)
881f0e2dc7SJiawei Lin    }
891f0e2dc7SJiawei Lin  }
901f0e2dc7SJiawei Lin
911f0e2dc7SJiawei Lin  val resp_data  = Reg(UInt())
921f0e2dc7SJiawei Lin  val resp_id    = Reg(UInt())
93026615fcSWilliam Wang  val resp_error = Reg(Bool())
941f0e2dc7SJiawei Lin  when (state === s_pipe_resp) {
951f0e2dc7SJiawei Lin    // when not miss
961f0e2dc7SJiawei Lin    // everything is OK, simply send response back to sbuffer
971f0e2dc7SJiawei Lin    // when miss and not replay
981f0e2dc7SJiawei Lin    // wait for missQueue to handling miss and replaying our request
991f0e2dc7SJiawei Lin    // when miss and replay
1001f0e2dc7SJiawei Lin    // req missed and fail to enter missQueue, manually replay it later
1011f0e2dc7SJiawei Lin    // TODO: add assertions:
1021f0e2dc7SJiawei Lin    // 1. add a replay delay counter?
1031f0e2dc7SJiawei Lin    // 2. when req gets into MissQueue, it should not miss any more
104935edac4STang Haojin    when (io.pipe_resp.fire) {
1051f0e2dc7SJiawei Lin      when (io.pipe_resp.bits.miss) {
1061f0e2dc7SJiawei Lin        when (io.pipe_resp.bits.replay) {
1071f0e2dc7SJiawei Lin          state := s_pipe_req
1081f0e2dc7SJiawei Lin        }
1091f0e2dc7SJiawei Lin      } .otherwise {
1101f0e2dc7SJiawei Lin        resp_data  := io.pipe_resp.bits.data
1111f0e2dc7SJiawei Lin        resp_id    := io.pipe_resp.bits.id
112026615fcSWilliam Wang        resp_error := io.pipe_resp.bits.error
1131f0e2dc7SJiawei Lin        state := s_resp
1141f0e2dc7SJiawei Lin      }
1151f0e2dc7SJiawei Lin    }
1161f0e2dc7SJiawei Lin  }
1171f0e2dc7SJiawei Lin
1181f0e2dc7SJiawei Lin  // --------------------------------------------
1191f0e2dc7SJiawei Lin  when (state === s_resp) {
1201f0e2dc7SJiawei Lin    io.lsu.resp.valid := true.B
1211f0e2dc7SJiawei Lin    io.lsu.resp.bits  := DontCare
1221f0e2dc7SJiawei Lin    io.lsu.resp.bits.data  := resp_data
1231f0e2dc7SJiawei Lin    io.lsu.resp.bits.id    := resp_id
124026615fcSWilliam Wang    io.lsu.resp.bits.error := resp_error
1251f0e2dc7SJiawei Lin
126935edac4STang Haojin    when (io.lsu.resp.fire) {
1271f0e2dc7SJiawei Lin      state := s_invalid
1281f0e2dc7SJiawei Lin    }
1291f0e2dc7SJiawei Lin  }
1301f0e2dc7SJiawei Lin
1311f0e2dc7SJiawei Lin  // debug output
132935edac4STang Haojin  // when (io.lsu.req.fire) {
13362cb71fbShappy-lx  //   io.lsu.req.bits.dump()
13462cb71fbShappy-lx  // }
1351f0e2dc7SJiawei Lin
136935edac4STang Haojin  // when (io.lsu.resp.fire) {
13762cb71fbShappy-lx  //   io.lsu.resp.bits.dump()
13862cb71fbShappy-lx  // }
1391f0e2dc7SJiawei Lin
140935edac4STang Haojin//  when (io.pipe_req.fire) {
141ad3ba452Szhanglinjuan//    io.pipe_req.bits.dump()
142ad3ba452Szhanglinjuan//  }
143ad3ba452Szhanglinjuan//
144935edac4STang Haojin//  when (io.pipe_resp.fire) {
145ad3ba452Szhanglinjuan//    io.pipe_resp.bits.dump()
146ad3ba452Szhanglinjuan//  }
1471f0e2dc7SJiawei Lin}