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