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 chipsalliance.rocketchip.config.Parameters 20import chisel3._ 21import chisel3.util._ 22import utils.XSDebug 23 24class AtomicsResp(implicit p: Parameters) extends DCacheBundle { 25 val data = UInt(DataBits.W) 26 val miss = Bool() 27 val miss_id = UInt(log2Up(cfg.nMissEntries).W) 28 val replay = Bool() 29 val error = Bool() 30 31 val ack_miss_queue = Bool() 32 33 val id = UInt(reqIdWidth.W) 34} 35 36class AtomicsReplayEntry(implicit p: Parameters) extends DCacheModule 37{ 38 val io = IO(new Bundle { 39 val lsu = Flipped(new DCacheWordIOWithVaddr) 40 val pipe_req = Decoupled(new MainPipeReq) 41 val pipe_resp = Flipped(ValidIO(new AtomicsResp)) 42 val block_lr = Input(Bool()) 43 44 val block_addr = Output(Valid(UInt())) 45 }) 46 47 val s_invalid :: s_pipe_req :: s_pipe_resp :: s_resp :: Nil = Enum(4) 48 val state = RegInit(s_invalid) 49 50 val req = Reg(new DCacheWordReqWithVaddr) 51 52 // assign default values to output signals 53 io.lsu.req.ready := state === s_invalid 54 io.lsu.resp.valid := false.B 55 io.lsu.resp.bits := DontCare 56 57 io.pipe_req.valid := false.B 58 io.pipe_req.bits := DontCare 59 60 io.block_addr.valid := state =/= s_invalid 61 io.block_addr.bits := req.addr 62 63 64 when (state =/= s_invalid) { 65 XSDebug("AtomicsReplayEntry: state: %d block_addr: %x\n", state, io.block_addr.bits) 66 } 67 68 // -------------------------------------------- 69 // s_invalid: receive requests 70 when (state === s_invalid) { 71 when (io.lsu.req.fire()) { 72 req := io.lsu.req.bits 73 state := s_pipe_req 74 } 75 } 76 77 // -------------------------------------------- 78 // replay 79 when (state === s_pipe_req) { 80 io.pipe_req.valid := Mux( 81 io.pipe_req.bits.cmd === M_XLR, 82 !io.block_lr, // block lr to survive in lr storm 83 true.B 84 ) 85 86 val pipe_req = io.pipe_req.bits 87 pipe_req := DontCare 88 pipe_req.miss := false.B 89 pipe_req.probe := false.B 90 pipe_req.probe_need_data := false.B 91 pipe_req.source := AMO_SOURCE.U 92 pipe_req.cmd := req.cmd 93 pipe_req.addr := get_block_addr(req.addr) 94 pipe_req.vaddr := get_block_addr(req.vaddr) 95 pipe_req.word_idx := get_word(req.addr) 96 pipe_req.amo_data := req.data 97 pipe_req.amo_mask := req.mask 98 99 when (io.pipe_req.fire()) { 100 state := s_pipe_resp 101 assert(!io.pipe_req.bits.vaddr === 0.U) 102 } 103 } 104 105 val resp_data = Reg(UInt()) 106 val resp_id = Reg(UInt()) 107 val resp_error = Reg(Bool()) 108 when (state === s_pipe_resp) { 109 // when not miss 110 // everything is OK, simply send response back to sbuffer 111 // when miss and not replay 112 // wait for missQueue to handling miss and replaying our request 113 // when miss and replay 114 // req missed and fail to enter missQueue, manually replay it later 115 // TODO: add assertions: 116 // 1. add a replay delay counter? 117 // 2. when req gets into MissQueue, it should not miss any more 118 when (io.pipe_resp.fire()) { 119 when (io.pipe_resp.bits.miss) { 120 when (io.pipe_resp.bits.replay) { 121 state := s_pipe_req 122 } 123 } .otherwise { 124 resp_data := io.pipe_resp.bits.data 125 resp_id := io.pipe_resp.bits.id 126 resp_error := io.pipe_resp.bits.error 127 state := s_resp 128 } 129 } 130 } 131 132 // -------------------------------------------- 133 when (state === s_resp) { 134 io.lsu.resp.valid := true.B 135 io.lsu.resp.bits := DontCare 136 io.lsu.resp.bits.data := resp_data 137 io.lsu.resp.bits.id := resp_id 138 io.lsu.resp.bits.error := resp_error 139 140 when (io.lsu.resp.fire()) { 141 state := s_invalid 142 } 143 } 144 145 // debug output 146 when (io.lsu.req.fire()) { 147 io.lsu.req.bits.dump() 148 } 149 150 when (io.lsu.resp.fire()) { 151 io.lsu.resp.bits.dump() 152 } 153 154// when (io.pipe_req.fire()) { 155// io.pipe_req.bits.dump() 156// } 157// 158// when (io.pipe_resp.fire()) { 159// io.pipe_resp.bits.dump() 160// } 161} 162