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 when (state =/= s_invalid) { 53 XSDebug("AtomicsReplayEntry: state: %d block_addr: %x\n", state, io.block_addr.bits) 54 } 55 56 // -------------------------------------------- 57 // s_invalid: receive requests 58 when (state === s_invalid) { 59 when (io.lsu.req.fire) { 60 req := io.lsu.req.bits 61 state := s_pipe_req 62 } 63 } 64 65 // -------------------------------------------- 66 // replay 67 when (state === s_pipe_req) { 68 io.pipe_req.valid := Mux( 69 io.pipe_req.bits.cmd === M_XLR, 70 !io.block_lr, // block lr to survive in lr storm 71 true.B 72 ) 73 74 val pipe_req = io.pipe_req.bits 75 pipe_req := DontCare 76 pipe_req.miss := false.B 77 pipe_req.probe := false.B 78 pipe_req.probe_need_data := false.B 79 pipe_req.source := AMO_SOURCE.U 80 pipe_req.cmd := req.cmd 81 pipe_req.addr := get_block_addr(req.addr) 82 pipe_req.vaddr := get_block_addr(req.vaddr) 83 pipe_req.word_idx := get_word(req.addr) 84 pipe_req.amo_data := req.data 85 pipe_req.amo_mask := req.mask 86 87 when (io.pipe_req.fire) { 88 state := s_pipe_resp 89 assert(!io.pipe_req.bits.vaddr === 0.U) 90 } 91 } 92 93 val resp_data = Reg(UInt()) 94 val resp_id = Reg(UInt()) 95 val resp_error = Reg(Bool()) 96 when (state === s_pipe_resp) { 97 // when not miss 98 // everything is OK, simply send response back to sbuffer 99 // when miss and not replay 100 // wait for missQueue to handling miss and replaying our request 101 // when miss and replay 102 // req missed and fail to enter missQueue, manually replay it later 103 // TODO: add assertions: 104 // 1. add a replay delay counter? 105 // 2. when req gets into MissQueue, it should not miss any more 106 when (io.pipe_resp.fire) { 107 when (io.pipe_resp.bits.miss) { 108 when (io.pipe_resp.bits.replay) { 109 state := s_pipe_req 110 } 111 } .otherwise { 112 resp_data := io.pipe_resp.bits.data 113 resp_id := io.pipe_resp.bits.id 114 resp_error := io.pipe_resp.bits.error 115 state := s_resp 116 } 117 } 118 } 119 120 // -------------------------------------------- 121 when (state === s_resp) { 122 io.lsu.resp.valid := true.B 123 io.lsu.resp.bits := DontCare 124 io.lsu.resp.bits.data := resp_data 125 io.lsu.resp.bits.id := resp_id 126 io.lsu.resp.bits.error := resp_error 127 128 when (io.lsu.resp.fire) { 129 state := s_invalid 130 } 131 } 132 133 // debug output 134 // when (io.lsu.req.fire) { 135 // io.lsu.req.bits.dump() 136 // } 137 138 // when (io.lsu.resp.fire) { 139 // io.lsu.resp.bits.dump() 140 // } 141 142// when (io.pipe_req.fire) { 143// io.pipe_req.bits.dump() 144// } 145// 146// when (io.pipe_resp.fire) { 147// io.pipe_resp.bits.dump() 148// } 149}