1/*************************************************************************************** 2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3* Copyright (c) 2020-2021 Peng Cheng Laboratory 4* 5* XiangShan is licensed under Mulan PSL v2. 6* You can use this software according to the terms and conditions of the Mulan PSL v2. 7* You may obtain a copy of Mulan PSL v2 at: 8* http://license.coscl.org.cn/MulanPSL2 9* 10* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13* 14* See the Mulan PSL v2 for more details. 15***************************************************************************************/ 16 17package xiangshan.cache 18 19import org.chipsalliance.cde.config.Parameters 20import chisel3._ 21import chisel3.util._ 22import utility.XSDebug 23 24class AtomicsReplayEntry(implicit p: Parameters) extends DCacheModule 25{ 26 val io = IO(new Bundle { 27 val lsu = Flipped(new AtomicWordIO) 28 val pipe_req = Decoupled(new MainPipeReq) 29 val pipe_resp = Flipped(ValidIO(new MainPipeResp)) 30 val block_lr = Input(Bool()) 31 32 val block_addr = Output(Valid(UInt())) 33 }) 34 35 val s_invalid :: s_pipe_req :: s_pipe_resp :: s_resp :: Nil = Enum(4) 36 val state = RegInit(s_invalid) 37 38 val req = Reg(new DCacheWordReqWithVaddr) 39 40 // assign default values to output signals 41 io.lsu.req.ready := state === s_invalid 42 io.lsu.resp.valid := false.B 43 io.lsu.resp.bits := DontCare 44 45 io.pipe_req.valid := false.B 46 io.pipe_req.bits := DontCare 47 48 io.block_addr.valid := state =/= s_invalid 49 io.block_addr.bits := req.addr 50 51 52 XSDebug(state =/= s_invalid, "AtomicsReplayEntry: state: %d block_addr: %x\n", state, io.block_addr.bits) 53 54 // -------------------------------------------- 55 // s_invalid: receive requests 56 when (state === s_invalid) { 57 when (io.lsu.req.fire) { 58 req := io.lsu.req.bits 59 state := s_pipe_req 60 } 61 } 62 63 // -------------------------------------------- 64 // replay 65 when (state === s_pipe_req) { 66 io.pipe_req.valid := Mux( 67 io.pipe_req.bits.cmd === M_XLR, 68 !io.block_lr, // block lr to survive in lr storm 69 true.B 70 ) 71 72 val pipe_req = io.pipe_req.bits 73 pipe_req := DontCare 74 pipe_req.miss := false.B 75 pipe_req.probe := false.B 76 pipe_req.probe_need_data := false.B 77 pipe_req.source := AMO_SOURCE.U 78 pipe_req.cmd := req.cmd 79 pipe_req.addr := get_block_addr(req.addr) 80 pipe_req.vaddr := get_block_addr(req.vaddr) 81 pipe_req.word_idx := get_word(req.addr) 82 pipe_req.amo_data := req.data 83 pipe_req.amo_mask := req.mask 84 85 when (io.pipe_req.fire) { 86 state := s_pipe_resp 87 assert(!io.pipe_req.bits.vaddr === 0.U) 88 } 89 } 90 91 val resp_data = Reg(UInt()) 92 val resp_id = Reg(UInt()) 93 val resp_error = Reg(Bool()) 94 when (state === s_pipe_resp) { 95 // when not miss 96 // everything is OK, simply send response back to sbuffer 97 // when miss and not replay 98 // wait for missQueue to handling miss and replaying our request 99 // when miss and replay 100 // req missed and fail to enter missQueue, manually replay it later 101 // TODO: add assertions: 102 // 1. add a replay delay counter? 103 // 2. when req gets into MissQueue, it should not miss any more 104 when (io.pipe_resp.fire) { 105 when (io.pipe_resp.bits.miss) { 106 when (io.pipe_resp.bits.replay) { 107 state := s_pipe_req 108 } 109 } .otherwise { 110 resp_data := io.pipe_resp.bits.data 111 resp_id := io.pipe_resp.bits.id 112 resp_error := io.pipe_resp.bits.error 113 state := s_resp 114 } 115 } 116 } 117 118 // -------------------------------------------- 119 when (state === s_resp) { 120 io.lsu.resp.valid := true.B 121 io.lsu.resp.bits := DontCare 122 io.lsu.resp.bits.data := resp_data 123 io.lsu.resp.bits.id := resp_id 124 io.lsu.resp.bits.error := resp_error 125 126 when (io.lsu.resp.fire) { 127 state := s_invalid 128 } 129 } 130 131 // debug output 132 // when (io.lsu.req.fire) { 133 // io.lsu.req.bits.dump() 134 // } 135 136 // when (io.lsu.resp.fire) { 137 // io.lsu.resp.bits.dump() 138 // } 139 140// when (io.pipe_req.fire) { 141// io.pipe_req.bits.dump() 142// } 143// 144// when (io.pipe_resp.fire) { 145// io.pipe_resp.bits.dump() 146// } 147}