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