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}