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 freechips.rocketchip.tilelink.ClientStates._ 23import freechips.rocketchip.tilelink.MemoryOpCategories._ 24import freechips.rocketchip.tilelink.TLPermissions._ 25import freechips.rocketchip.tilelink.{ClientMetadata, ClientStates, TLPermissions} 26import utils._ 27import utility._ 28import xiangshan.L1CacheErrorInfo 29 30class MainPipeReq(implicit p: Parameters) extends DCacheBundle { 31 val miss = Bool() // only amo miss will refill in main pipe 32 val miss_id = UInt(log2Up(cfg.nMissEntries).W) 33 val miss_param = UInt(TLPermissions.bdWidth.W) 34 val miss_dirty = Bool() 35 val miss_way_en = UInt(DCacheWays.W) 36 37 val probe = Bool() 38 val probe_param = UInt(TLPermissions.bdWidth.W) 39 val probe_need_data = Bool() 40 41 // request info 42 // reqs from Store, AMO use this 43 // probe does not use this 44 val source = UInt(sourceTypeWidth.W) 45 val cmd = UInt(M_SZ.W) 46 // if dcache size > 32KB, vaddr is also needed for store 47 // vaddr is used to get extra index bits 48 val vaddr = UInt(VAddrBits.W) 49 // must be aligned to block 50 val addr = UInt(PAddrBits.W) 51 52 // store 53 val store_data = UInt((cfg.blockBytes * 8).W) 54 val store_mask = UInt(cfg.blockBytes.W) 55 56 // which word does amo work on? 57 val word_idx = UInt(log2Up(cfg.blockBytes * 8 / DataBits).W) 58 val amo_data = UInt(DataBits.W) 59 val amo_mask = UInt((DataBits / 8).W) 60 61 // error 62 val error = Bool() 63 64 // replace 65 val replace = Bool() 66 val replace_way_en = UInt(DCacheWays.W) 67 68 val id = UInt(reqIdWidth.W) 69 70 def isLoad: Bool = source === LOAD_SOURCE.U 71 def isStore: Bool = source === STORE_SOURCE.U 72 def isAMO: Bool = source === AMO_SOURCE.U 73 74 def convertStoreReq(store: DCacheLineReq): MainPipeReq = { 75 val req = Wire(new MainPipeReq) 76 req := DontCare 77 req.miss := false.B 78 req.miss_dirty := false.B 79 req.probe := false.B 80 req.probe_need_data := false.B 81 req.source := STORE_SOURCE.U 82 req.cmd := store.cmd 83 req.addr := store.addr 84 req.vaddr := store.vaddr 85 req.store_data := store.data 86 req.store_mask := store.mask 87 req.replace := false.B 88 req.error := false.B 89 req.id := store.id 90 req 91 } 92} 93 94class MainPipeStatus(implicit p: Parameters) extends DCacheBundle { 95 val set = UInt(idxBits.W) 96 val way_en = UInt(nWays.W) 97} 98 99class MainPipe(implicit p: Parameters) extends DCacheModule with HasPerfEvents { 100 val io = IO(new Bundle() { 101 // probe queue 102 val probe_req = Flipped(DecoupledIO(new MainPipeReq)) 103 // store miss go to miss queue 104 val miss_req = DecoupledIO(new MissReq) 105 // store buffer 106 val store_req = Flipped(DecoupledIO(new DCacheLineReq)) 107 val store_replay_resp = ValidIO(new DCacheLineResp) 108 val store_hit_resp = ValidIO(new DCacheLineResp) 109 val release_update = ValidIO(new ReleaseUpdate) 110 // atmoics 111 val atomic_req = Flipped(DecoupledIO(new MainPipeReq)) 112 val atomic_resp = ValidIO(new AtomicsResp) 113 // replace 114 val replace_req = Flipped(DecoupledIO(new MainPipeReq)) 115 val replace_resp = ValidIO(UInt(log2Up(cfg.nMissEntries).W)) 116 // write-back queue 117 val wb = DecoupledIO(new WritebackReq) 118 val wb_ready_dup = Vec(nDupWbReady, Input(Bool())) 119 val probe_ttob_check_req = ValidIO(new ProbeToBCheckReq) 120 val probe_ttob_check_resp = Flipped(ValidIO(new ProbeToBCheckResp)) 121 122 // data sram 123 val data_read_intend = Output(Bool()) 124 val data_read = DecoupledIO(new L1BankedDataReadLineReq) 125 val data_resp = Input(Vec(DCacheBanks, new L1BankedDataReadResult())) 126 val readline_error_delayed = Input(Bool()) 127 val data_write = DecoupledIO(new L1BankedDataWriteReq) 128 val data_write_dup = Vec(DCacheBanks, Valid(new L1BankedDataWriteReqCtrl)) 129 val data_write_ready_dup = Vec(nDupDataWriteReady, Input(Bool())) 130 131 // meta array 132 val meta_read = DecoupledIO(new MetaReadReq) 133 val meta_resp = Input(Vec(nWays, new Meta)) 134 val meta_write = DecoupledIO(new MetaWriteReq) 135 val error_flag_resp = Input(Vec(nWays, Bool())) 136 val error_flag_write = DecoupledIO(new ErrorWriteReq) 137 138 // tag sram 139 val tag_read = DecoupledIO(new TagReadReq) 140 val tag_resp = Input(Vec(nWays, UInt(encTagBits.W))) 141 val tag_write = DecoupledIO(new TagWriteReq) 142 val tag_write_ready_dup = Vec(nDupTagWriteReady, Input(Bool())) 143 val tag_write_intend = Output(new Bool()) 144 145 // update state vec in replacement algo 146 val replace_access = ValidIO(new ReplacementAccessBundle) 147 // find the way to be replaced 148 val replace_way = new ReplacementWayReqIO 149 150 val status = new Bundle() { 151 val s0_set = ValidIO(UInt(idxBits.W)) 152 val s1, s2, s3 = ValidIO(new MainPipeStatus) 153 } 154 val status_dup = Vec(nDupStatus, new Bundle() { 155 val s1, s2, s3 = ValidIO(new MainPipeStatus) 156 }) 157 158 // lrsc locked block should block probe 159 val lrsc_locked_block = Output(Valid(UInt(PAddrBits.W))) 160 val invalid_resv_set = Input(Bool()) 161 val update_resv_set = Output(Bool()) 162 val block_lr = Output(Bool()) 163 164 // ecc error 165 val error = Output(new L1CacheErrorInfo()) 166 }) 167 168 // meta array is made of regs, so meta write or read should always be ready 169 assert(RegNext(io.meta_read.ready)) 170 assert(RegNext(io.meta_write.ready)) 171 172 val s1_s0_set_conflict, s2_s0_set_conlict, s3_s0_set_conflict = Wire(Bool()) 173 val set_conflict = s1_s0_set_conflict || s2_s0_set_conlict || s3_s0_set_conflict 174 // check sbuffer store req set_conflict in parallel with req arbiter 175 // it will speed up the generation of store_req.ready, which is in crit. path 176 val s1_s0_set_conflict_store, s2_s0_set_conlict_store, s3_s0_set_conflict_store = Wire(Bool()) 177 val store_set_conflict = s1_s0_set_conflict_store || s2_s0_set_conlict_store || s3_s0_set_conflict_store 178 val s1_ready, s2_ready, s3_ready = Wire(Bool()) 179 180 // convert store req to main pipe req, and select a req from store and probe 181 val store_req = Wire(DecoupledIO(new MainPipeReq)) 182 store_req.bits := (new MainPipeReq).convertStoreReq(io.store_req.bits) 183 store_req.valid := io.store_req.valid 184 io.store_req.ready := store_req.ready 185 186 // s0: read meta and tag 187 val req = Wire(DecoupledIO(new MainPipeReq)) 188 arbiter( 189 in = Seq( 190 io.probe_req, 191 io.replace_req, 192 store_req, // Note: store_req.ready is now manually assigned for better timing 193 io.atomic_req 194 ), 195 out = req, 196 name = Some("main_pipe_req") 197 ) 198 199 val store_idx = get_idx(io.store_req.bits.vaddr) 200 // manually assign store_req.ready for better timing 201 // now store_req set conflict check is done in parallel with req arbiter 202 store_req.ready := io.meta_read.ready && io.tag_read.ready && s1_ready && !store_set_conflict && 203 !io.probe_req.valid && !io.replace_req.valid 204 val s0_req = req.bits 205 val s0_idx = get_idx(s0_req.vaddr) 206 val s0_need_tag = io.tag_read.valid 207 val s0_can_go = io.meta_read.ready && io.tag_read.ready && s1_ready && !set_conflict 208 val s0_fire = req.valid && s0_can_go 209 210 val bank_write = VecInit((0 until DCacheBanks).map(i => get_mask_of_bank(i, s0_req.store_mask).orR)).asUInt 211 val bank_full_write = VecInit((0 until DCacheBanks).map(i => get_mask_of_bank(i, s0_req.store_mask).andR)).asUInt 212 val banks_full_overwrite = bank_full_write.andR 213 214 val banked_store_rmask = bank_write & ~bank_full_write 215 val banked_full_rmask = ~0.U(DCacheBanks.W) 216 val banked_none_rmask = 0.U(DCacheBanks.W) 217 218 val store_need_data = !s0_req.probe && s0_req.isStore && banked_store_rmask.orR 219 val probe_need_data = s0_req.probe 220 val amo_need_data = !s0_req.probe && s0_req.isAMO 221 val miss_need_data = s0_req.miss 222 val replace_need_data = s0_req.replace 223 224 val banked_need_data = store_need_data || probe_need_data || amo_need_data || miss_need_data || replace_need_data 225 226 val s0_banked_rmask = Mux(store_need_data, banked_store_rmask, 227 Mux(probe_need_data || amo_need_data || miss_need_data || replace_need_data, 228 banked_full_rmask, 229 banked_none_rmask 230 )) 231 232 // generate wmask here and use it in stage 2 233 val banked_store_wmask = bank_write 234 val banked_full_wmask = ~0.U(DCacheBanks.W) 235 val banked_none_wmask = 0.U(DCacheBanks.W) 236 237 // s1: read data 238 val s1_valid = RegInit(false.B) 239 val s1_need_data = RegEnable(banked_need_data, s0_fire) 240 val s1_req = RegEnable(s0_req, s0_fire) 241 val s1_banked_rmask = RegEnable(s0_banked_rmask, s0_fire) 242 val s1_banked_store_wmask = RegEnable(banked_store_wmask, s0_fire) 243 val s1_need_tag = RegEnable(s0_need_tag, s0_fire) 244 val s1_can_go = s2_ready && (io.data_read.ready || !s1_need_data) 245 val s1_fire = s1_valid && s1_can_go 246 val s1_idx = get_idx(s1_req.vaddr) 247 248 // duplicate regs to reduce fanout 249 val s1_valid_dup = RegInit(VecInit(Seq.fill(6)(false.B))) 250 val s1_req_vaddr_dup_for_data_read = RegEnable(s0_req.vaddr, s0_fire) 251 val s1_idx_dup_for_replace_way = RegEnable(get_idx(s0_req.vaddr), s0_fire) 252 253 val s1_valid_dup_for_status = RegInit(VecInit(Seq.fill(nDupStatus)(false.B))) 254 255 when (s0_fire) { 256 s1_valid := true.B 257 s1_valid_dup.foreach(_ := true.B) 258 s1_valid_dup_for_status.foreach(_ := true.B) 259 }.elsewhen (s1_fire) { 260 s1_valid := false.B 261 s1_valid_dup.foreach(_ := false.B) 262 s1_valid_dup_for_status.foreach(_ := false.B) 263 } 264 s1_ready := !s1_valid_dup(0) || s1_can_go 265 s1_s0_set_conflict := s1_valid_dup(1) && s0_idx === s1_idx 266 s1_s0_set_conflict_store := s1_valid_dup(2) && store_idx === s1_idx 267 268 val meta_resp = Wire(Vec(nWays, (new Meta).asUInt())) 269 val tag_resp = Wire(Vec(nWays, UInt(tagBits.W))) 270 val ecc_resp = Wire(Vec(nWays, UInt(eccTagBits.W))) 271 meta_resp := Mux(RegNext(s0_fire), VecInit(io.meta_resp.map(_.asUInt)), RegNext(meta_resp)) 272 tag_resp := Mux(RegNext(s0_fire), VecInit(io.tag_resp.map(r => r(tagBits - 1, 0))), RegNext(tag_resp)) 273 ecc_resp := Mux(RegNext(s0_fire), VecInit(io.tag_resp.map(r => r(encTagBits - 1, tagBits))), RegNext(ecc_resp)) 274 val enc_tag_resp = Wire(io.tag_resp.cloneType) 275 enc_tag_resp := Mux(RegNext(s0_fire), io.tag_resp, RegNext(enc_tag_resp)) 276 277 def wayMap[T <: Data](f: Int => T) = VecInit((0 until nWays).map(f)) 278 val s1_tag_eq_way = wayMap((w: Int) => tag_resp(w) === get_tag(s1_req.addr)).asUInt 279 val s1_tag_match_way = wayMap((w: Int) => s1_tag_eq_way(w) && Meta(meta_resp(w)).coh.isValid()).asUInt 280 val s1_tag_match = s1_tag_match_way.orR 281 282 val s1_hit_tag = Mux(s1_tag_match, Mux1H(s1_tag_match_way, wayMap(w => tag_resp(w))), get_tag(s1_req.addr)) 283 val s1_hit_coh = ClientMetadata(Mux(s1_tag_match, Mux1H(s1_tag_match_way, wayMap(w => meta_resp(w))), 0.U)) 284 val s1_encTag = Mux1H(s1_tag_match_way, wayMap((w: Int) => enc_tag_resp(w))) 285 val s1_flag_error = Mux(s1_tag_match, Mux1H(s1_tag_match_way, wayMap(w => io.error_flag_resp(w))), false.B) 286 val s1_l2_error = s1_req.error 287 288 // replacement policy 289 val s1_repl_way_en = WireInit(0.U(nWays.W)) 290 s1_repl_way_en := Mux(RegNext(s0_fire), UIntToOH(io.replace_way.way), RegNext(s1_repl_way_en)) 291 val s1_repl_tag = Mux1H(s1_repl_way_en, wayMap(w => tag_resp(w))) 292 val s1_repl_coh = Mux1H(s1_repl_way_en, wayMap(w => meta_resp(w))).asTypeOf(new ClientMetadata) 293 val s1_miss_tag = Mux1H(s1_req.miss_way_en, wayMap(w => tag_resp(w))) 294 val s1_miss_coh = Mux1H(s1_req.miss_way_en, wayMap(w => meta_resp(w))).asTypeOf(new ClientMetadata) 295 296 val s1_repl_way_raw = WireInit(0.U(log2Up(nWays).W)) 297 s1_repl_way_raw := Mux(RegNext(s0_fire), io.replace_way.way, RegNext(s1_repl_way_raw)) 298 299 val s1_need_replacement = (s1_req.miss || s1_req.isStore && !s1_req.probe) && !s1_tag_match 300 val s1_way_en = Mux( 301 s1_req.replace, 302 s1_req.replace_way_en, 303 Mux( 304 s1_req.miss, 305 s1_req.miss_way_en, 306 Mux( 307 s1_need_replacement, 308 s1_repl_way_en, 309 s1_tag_match_way 310 ) 311 ) 312 ) 313 assert(!RegNext(s1_fire && PopCount(s1_way_en) > 1.U)) 314 val s1_tag = Mux( 315 s1_req.replace, 316 get_tag(s1_req.addr), 317 Mux( 318 s1_req.miss, 319 s1_miss_tag, 320 Mux(s1_need_replacement, s1_repl_tag, s1_hit_tag) 321 ) 322 ) 323 val s1_coh = Mux( 324 s1_req.replace, 325 Mux1H(s1_req.replace_way_en, meta_resp.map(ClientMetadata(_))), 326 Mux( 327 s1_req.miss, 328 s1_miss_coh, 329 Mux(s1_need_replacement, s1_repl_coh, s1_hit_coh) 330 ) 331 ) 332 333 val s1_has_permission = s1_hit_coh.onAccess(s1_req.cmd)._1 334 val s1_hit = s1_tag_match && s1_has_permission 335 val s1_pregen_can_go_to_mq = !s1_req.replace && !s1_req.probe && !s1_req.miss && (s1_req.isStore || s1_req.isAMO) && !s1_hit 336 337 val s1_ttob_probe = s1_valid && s1_req.probe && s1_req.probe_param === TLPermissions.toB 338 io.probe_ttob_check_req.valid := s1_ttob_probe 339 io.probe_ttob_check_req.bits.addr := get_block_addr(Cat(s1_tag, get_untag(s1_req.vaddr))) 340 341 // s2: select data, return resp if this is a store miss 342 val s2_valid = RegInit(false.B) 343 val s2_req = RegEnable(s1_req, s1_fire) 344 val s2_tag_match = RegEnable(s1_tag_match, s1_fire) 345 val s2_tag_match_way = RegEnable(s1_tag_match_way, s1_fire) 346 val s2_hit_coh = RegEnable(s1_hit_coh, s1_fire) 347 val (s2_has_permission, _, s2_new_hit_coh) = s2_hit_coh.onAccess(s2_req.cmd) 348 349 val s2_repl_tag = RegEnable(s1_repl_tag, s1_fire) 350 val s2_repl_coh = RegEnable(s1_repl_coh, s1_fire) 351 val s2_repl_way_en = RegEnable(s1_repl_way_en, s1_fire) 352 val s2_need_replacement = RegEnable(s1_need_replacement, s1_fire) 353 val s2_need_data = RegEnable(s1_need_data, s1_fire) 354 val s2_need_tag = RegEnable(s1_need_tag, s1_fire) 355 val s2_encTag = RegEnable(s1_encTag, s1_fire) 356 val s2_idx = get_idx(s2_req.vaddr) 357 358 // duplicate regs to reduce fanout 359 val s2_valid_dup = RegInit(VecInit(Seq.fill(8)(false.B))) 360 val s2_valid_dup_for_status = RegInit(VecInit(Seq.fill(nDupStatus)(false.B))) 361 val s2_req_vaddr_dup_for_miss_req = RegEnable(s1_req.vaddr, s1_fire) 362 val s2_idx_dup_for_status = RegEnable(get_idx(s1_req.vaddr), s1_fire) 363 val s2_idx_dup_for_replace_access = RegEnable(get_idx(s1_req.vaddr), s1_fire) 364 365 val s2_req_replace_dup_1, 366 s2_req_replace_dup_2 = RegEnable(s1_req.replace, s1_fire) 367 368 val s2_can_go_to_mq_dup = (0 until 3).map(_ => RegEnable(s1_pregen_can_go_to_mq, s1_fire)) 369 370 val s2_way_en = RegEnable(s1_way_en, s1_fire) 371 val s2_tag = RegEnable(s1_tag, s1_fire) 372 val s2_coh = RegEnable(s1_coh, s1_fire) 373 val s2_banked_store_wmask = RegEnable(s1_banked_store_wmask, s1_fire) 374 val s2_flag_error = RegEnable(s1_flag_error, s1_fire) 375 val s2_tag_error = dcacheParameters.tagCode.decode(s2_encTag).error && s2_need_tag 376 val s2_l2_error = s2_req.error 377 val s2_error = s2_flag_error || s2_tag_error || s2_l2_error // data_error not included 378 379 val s2_may_report_data_error = s2_need_data && s2_coh.state =/= ClientStates.Nothing 380 381 val s2_hit = s2_tag_match && s2_has_permission 382 val s2_amo_hit = s2_hit && !s2_req.probe && !s2_req.miss && s2_req.isAMO 383 val s2_store_hit = s2_hit && !s2_req.probe && !s2_req.miss && s2_req.isStore 384 385 s2_s0_set_conlict := s2_valid_dup(0) && s0_idx === s2_idx 386 s2_s0_set_conlict_store := s2_valid_dup(1) && store_idx === s2_idx 387 388 // For a store req, it either hits and goes to s3, or miss and enter miss queue immediately 389 val s2_can_go_to_s3 = (s2_req_replace_dup_1 || s2_req.probe || s2_req.miss || (s2_req.isStore || s2_req.isAMO) && s2_hit) && s3_ready 390 val s2_can_go_to_mq = RegEnable(s1_pregen_can_go_to_mq, s1_fire) 391 assert(RegNext(!(s2_valid && s2_can_go_to_s3 && s2_can_go_to_mq))) 392 val s2_can_go = s2_can_go_to_s3 || s2_can_go_to_mq 393 val s2_fire = s2_valid && s2_can_go 394 val s2_fire_to_s3 = s2_valid_dup(2) && s2_can_go_to_s3 395 when (s1_fire) { 396 s2_valid := true.B 397 s2_valid_dup.foreach(_ := true.B) 398 s2_valid_dup_for_status.foreach(_ := true.B) 399 }.elsewhen (s2_fire) { 400 s2_valid := false.B 401 s2_valid_dup.foreach(_ := false.B) 402 s2_valid_dup_for_status.foreach(_ := false.B) 403 } 404 s2_ready := !s2_valid_dup(3) || s2_can_go 405 val replay = !io.miss_req.ready 406 407 val data_resp = Wire(io.data_resp.cloneType) 408 data_resp := Mux(RegNext(s1_fire), io.data_resp, RegNext(data_resp)) 409 val s2_store_data_merged = Wire(Vec(DCacheBanks, UInt(DCacheSRAMRowBits.W))) 410 411 def mergePutData(old_data: UInt, new_data: UInt, wmask: UInt): UInt = { 412 val full_wmask = FillInterleaved(8, wmask) 413 ((~full_wmask & old_data) | (full_wmask & new_data)) 414 } 415 416 val s2_data = WireInit(VecInit((0 until DCacheBanks).map(i => { 417 data_resp(i).raw_data 418 }))) 419 420 for (i <- 0 until DCacheBanks) { 421 val old_data = s2_data(i) 422 val new_data = get_data_of_bank(i, s2_req.store_data) 423 // for amo hit, we should use read out SRAM data 424 // do not merge with store data 425 val wmask = Mux(s2_amo_hit, 0.U(wordBytes.W), get_mask_of_bank(i, s2_req.store_mask)) 426 s2_store_data_merged(i) := mergePutData(old_data, new_data, wmask) 427 } 428 429 val s2_data_word = s2_store_data_merged(s2_req.word_idx) 430 431 val s2_probe_ttob_check_resp = Wire(io.probe_ttob_check_resp.cloneType) 432 s2_probe_ttob_check_resp := Mux(RegNext(s1_fire), io.probe_ttob_check_resp, RegNext(s2_probe_ttob_check_resp)) 433 434 // s3: write data, meta and tag 435 val s3_valid = RegInit(false.B) 436 val s3_req = RegEnable(s2_req, s2_fire_to_s3) 437 // val s3_idx = get_idx(s3_req.vaddr) 438 val s3_tag = RegEnable(s2_tag, s2_fire_to_s3) 439 val s3_tag_match = RegEnable(s2_tag_match, s2_fire_to_s3) 440 val s3_coh = RegEnable(s2_coh, s2_fire_to_s3) 441 val s3_hit = RegEnable(s2_hit, s2_fire_to_s3) 442 val s3_amo_hit = RegEnable(s2_amo_hit, s2_fire_to_s3) 443 val s3_store_hit = RegEnable(s2_store_hit, s2_fire_to_s3) 444 val s3_hit_coh = RegEnable(s2_hit_coh, s2_fire_to_s3) 445 val s3_new_hit_coh = RegEnable(s2_new_hit_coh, s2_fire_to_s3) 446 val s3_way_en = RegEnable(s2_way_en, s2_fire_to_s3) 447 val s3_banked_store_wmask = RegEnable(s2_banked_store_wmask, s2_fire_to_s3) 448 val s3_store_data_merged = RegEnable(s2_store_data_merged, s2_fire_to_s3) 449 val s3_data_word = RegEnable(s2_data_word, s2_fire_to_s3) 450 val s3_data = RegEnable(s2_data, s2_fire_to_s3) 451 val s3_l2_error = s3_req.error 452 // data_error will be reported by data array 1 cycle after data read resp 453 val s3_data_error = Wire(Bool()) 454 s3_data_error := Mux(RegNext(RegNext(s1_fire)), // ecc check result is generated 2 cycle after read req 455 io.readline_error_delayed && RegNext(s2_may_report_data_error), 456 RegNext(s3_data_error) // do not update s3_data_error if !s1_fire 457 ) 458 // error signal for amo inst 459 // s3_error = s3_flag_error || s3_tag_error || s3_l2_error || s3_data_error 460 val s3_error = RegEnable(s2_error, s2_fire_to_s3) || s3_data_error 461 val (_, _, probe_new_coh) = s3_coh.onProbe(s3_req.probe_param) 462 val s3_need_replacement = RegEnable(s2_need_replacement, s2_fire_to_s3) 463 val s3_probe_ttob_check_resp = RegEnable(s2_probe_ttob_check_resp, s2_fire_to_s3) 464 465 // duplicate regs to reduce fanout 466 val s3_valid_dup = RegInit(VecInit(Seq.fill(14)(false.B))) 467 val s3_valid_dup_for_status = RegInit(VecInit(Seq.fill(nDupStatus)(false.B))) 468 val s3_way_en_dup = (0 until 4).map(_ => RegEnable(s2_way_en, s2_fire_to_s3)) 469 val s3_coh_dup = (0 until 6).map(_ => RegEnable(s2_coh, s2_fire_to_s3)) 470 val s3_tag_match_dup = RegEnable(s2_tag_match, s2_fire_to_s3) 471 472 val s3_req_vaddr_dup_for_wb, 473 s3_req_vaddr_dup_for_data_write = RegEnable(s2_req.vaddr, s2_fire_to_s3) 474 475 val s3_idx_dup = (0 until 6).map(_ => RegEnable(get_idx(s2_req.vaddr), s2_fire_to_s3)) 476 477 val s3_req_replace_dup = (0 until 8).map(_ => RegEnable(s2_req.replace, s2_fire_to_s3)) 478 val s3_req_cmd_dup = (0 until 6).map(_ => RegEnable(s2_req.cmd, s2_fire_to_s3)) 479 val s3_req_source_dup_1, s3_req_source_dup_2 = RegEnable(s2_req.source, s2_fire_to_s3) 480 val s3_req_addr_dup = (0 until 5).map(_ => RegEnable(s2_req.addr, s2_fire_to_s3)) 481 val s3_req_probe_dup = (0 until 10).map(_ => RegEnable(s2_req.probe, s2_fire_to_s3)) 482 val s3_req_miss_dup = (0 until 10).map(_ => RegEnable(s2_req.miss, s2_fire_to_s3)) 483 val s3_req_word_idx_dup = (0 until DCacheBanks).map(_ => RegEnable(s2_req.word_idx, s2_fire_to_s3)) 484 485 val s3_need_replacement_dup = RegEnable(s2_need_replacement, s2_fire_to_s3) 486 487 val s3_s_amoalu_dup = RegInit(VecInit(Seq.fill(3)(false.B))) 488 489 val s3_hit_coh_dup = RegEnable(s2_hit_coh, s2_fire_to_s3) 490 val s3_new_hit_coh_dup = (0 until 2).map(_ => RegEnable(s2_new_hit_coh, s2_fire_to_s3)) 491 val s3_amo_hit_dup = RegEnable(s2_amo_hit, s2_fire_to_s3) 492 val s3_store_hit_dup = (0 until 2).map(_ => RegEnable(s2_store_hit, s2_fire_to_s3)) 493 494 val lrsc_count_dup = RegInit(VecInit(Seq.fill(3)(0.U(log2Ceil(LRSCCycles).W)))) 495 val lrsc_valid_dup = lrsc_count_dup.map { case cnt => cnt > LRSCBackOff.U } 496 val lrsc_addr_dup = Reg(UInt()) 497 498 val s3_req_probe_param_dup = RegEnable(s2_req.probe_param, s2_fire_to_s3) 499 val (_, probe_shrink_param, _) = s3_coh.onProbe(s3_req_probe_param_dup) 500 501 502 val miss_update_meta = s3_req.miss 503 val probe_update_meta = s3_req_probe_dup(0) && s3_tag_match_dup && s3_coh_dup(0) =/= probe_new_coh 504 val store_update_meta = s3_req.isStore && !s3_req_probe_dup(1) && s3_hit_coh =/= s3_new_hit_coh_dup(0) 505 val amo_update_meta = s3_req.isAMO && !s3_req_probe_dup(2) && s3_hit_coh_dup =/= s3_new_hit_coh_dup(1) 506 val amo_wait_amoalu = s3_req.isAMO && s3_req_cmd_dup(0) =/= M_XLR && s3_req_cmd_dup(1) =/= M_XSC 507 val update_meta = (miss_update_meta || probe_update_meta || store_update_meta || amo_update_meta) && !s3_req_replace_dup(0) 508 509 def missCohGen(cmd: UInt, param: UInt, dirty: Bool) = { 510 val c = categorize(cmd) 511 MuxLookup(Cat(c, param, dirty), Nothing, Seq( 512 //(effect param) -> (next) 513 Cat(rd, toB, false.B) -> Branch, 514 Cat(rd, toB, true.B) -> Branch, 515 Cat(rd, toT, false.B) -> Trunk, 516 Cat(rd, toT, true.B) -> Dirty, 517 Cat(wi, toT, false.B) -> Trunk, 518 Cat(wi, toT, true.B) -> Dirty, 519 Cat(wr, toT, false.B) -> Dirty, 520 Cat(wr, toT, true.B) -> Dirty)) 521 } 522 val miss_new_coh = ClientMetadata(missCohGen(s3_req_cmd_dup(2), s3_req.miss_param, s3_req.miss_dirty)) 523 524 // LR, SC and AMO 525 val debug_sc_fail_addr = RegInit(0.U) 526 val debug_sc_fail_cnt = RegInit(0.U(8.W)) 527 val debug_sc_addr_match_fail_cnt = RegInit(0.U(8.W)) 528 529 val lrsc_count = RegInit(0.U(log2Ceil(LRSCCycles).W)) 530 // val lrsc_valid = lrsc_count > LRSCBackOff.U 531 val lrsc_addr = Reg(UInt()) 532 val s3_lr = !s3_req_probe_dup(3) && s3_req.isAMO && s3_req_cmd_dup(3) === M_XLR 533 val s3_sc = !s3_req_probe_dup(4) && s3_req.isAMO && s3_req_cmd_dup(4) === M_XSC 534 val s3_lrsc_addr_match = lrsc_valid_dup(0) && lrsc_addr === get_block_addr(s3_req.addr) 535 val s3_sc_fail = s3_sc && !s3_lrsc_addr_match 536 val debug_s3_sc_fail_addr_match = s3_sc && lrsc_addr === get_block_addr(s3_req.addr) && !lrsc_valid_dup(0) 537 val s3_sc_resp = Mux(s3_sc_fail, 1.U, 0.U) 538 539 val s3_can_do_amo = (s3_req_miss_dup(0) && !s3_req_probe_dup(5) && s3_req.isAMO) || s3_amo_hit 540 val s3_can_do_amo_write = s3_can_do_amo && isWrite(s3_req_cmd_dup(5)) && !s3_sc_fail 541 542 when (s3_valid_dup(0) && (s3_lr || s3_sc)) { 543 when (s3_can_do_amo && s3_lr) { 544 lrsc_count := (LRSCCycles - 1).U 545 lrsc_count_dup.foreach(_ := (LRSCCycles - 1).U) 546 lrsc_addr := get_block_addr(s3_req_addr_dup(0)) 547 lrsc_addr_dup := get_block_addr(s3_req_addr_dup(0)) 548 } .otherwise { 549 lrsc_count := 0.U 550 lrsc_count_dup.foreach(_ := 0.U) 551 } 552 }.elsewhen (io.invalid_resv_set) { 553 // when we release this block, 554 // we invalidate this reservation set 555 lrsc_count := 0.U 556 lrsc_count_dup.foreach(_ := 0.U) 557 }.elsewhen (lrsc_count > 0.U) { 558 lrsc_count := lrsc_count - 1.U 559 lrsc_count_dup.foreach({case cnt => 560 cnt := cnt - 1.U 561 }) 562 } 563 564 io.lrsc_locked_block.valid := lrsc_valid_dup(1) 565 io.lrsc_locked_block.bits := lrsc_addr_dup 566 io.block_lr := RegNext(lrsc_count > 0.U) 567 568 // When we update update_resv_set, block all probe req in the next cycle 569 // It should give Probe reservation set addr compare an independent cycle, 570 // which will lead to better timing 571 io.update_resv_set := s3_valid_dup(1) && s3_lr && s3_can_do_amo 572 573 when (s3_valid_dup(2)) { 574 when (s3_req_addr_dup(1) === debug_sc_fail_addr) { 575 when (s3_sc_fail) { 576 debug_sc_fail_cnt := debug_sc_fail_cnt + 1.U 577 } .elsewhen (s3_sc) { 578 debug_sc_fail_cnt := 0.U 579 } 580 } .otherwise { 581 when (s3_sc_fail) { 582 debug_sc_fail_addr := s3_req_addr_dup(2) 583 debug_sc_fail_cnt := 1.U 584 XSWarn(s3_sc_fail === 100.U, p"L1DCache failed too many SCs in a row 0x${Hexadecimal(debug_sc_fail_addr)}, check if sth went wrong\n") 585 } 586 } 587 } 588 XSWarn(debug_sc_fail_cnt > 100.U, "L1DCache failed too many SCs in a row") 589 590 when (s3_valid_dup(2)) { 591 when (s3_req_addr_dup(1) === debug_sc_fail_addr) { 592 when (debug_s3_sc_fail_addr_match) { 593 debug_sc_addr_match_fail_cnt := debug_sc_addr_match_fail_cnt + 1.U 594 } .elsewhen (s3_sc) { 595 debug_sc_addr_match_fail_cnt := 0.U 596 } 597 } .otherwise { 598 when (s3_sc_fail) { 599 debug_sc_addr_match_fail_cnt := 1.U 600 } 601 } 602 } 603 XSError(debug_sc_addr_match_fail_cnt > 100.U, "L1DCache failed too many SCs in a row, resv set addr always match") 604 605 606 val banked_amo_wmask = UIntToOH(s3_req.word_idx) 607 val update_data = s3_req_miss_dup(2) || s3_store_hit_dup(0) || s3_can_do_amo_write 608 609 // generate write data 610 // AMO hits 611 val s3_s_amoalu = RegInit(false.B) 612 val do_amoalu = amo_wait_amoalu && s3_valid_dup(3) && !s3_s_amoalu 613 val amoalu = Module(new AMOALU(wordBits)) 614 amoalu.io.mask := s3_req.amo_mask 615 amoalu.io.cmd := s3_req.cmd 616 amoalu.io.lhs := s3_data_word 617 amoalu.io.rhs := s3_req.amo_data 618 619 // merge amo write data 620// val amo_bitmask = FillInterleaved(8, s3_req.amo_mask) 621 val s3_amo_data_merged = Wire(Vec(DCacheBanks, UInt(DCacheSRAMRowBits.W))) 622 val s3_sc_data_merged = Wire(Vec(DCacheBanks, UInt(DCacheSRAMRowBits.W))) 623 for (i <- 0 until DCacheBanks) { 624 val old_data = s3_store_data_merged(i) 625 val new_data = amoalu.io.out 626 val wmask = Mux( 627 s3_req_word_idx_dup(i) === i.U, 628 ~0.U(wordBytes.W), 629 0.U(wordBytes.W) 630 ) 631 s3_amo_data_merged(i) := mergePutData(old_data, new_data, wmask) 632 s3_sc_data_merged(i) := mergePutData(old_data, s3_req.amo_data, 633 Mux(s3_req_word_idx_dup(i) === i.U && !s3_sc_fail, s3_req.amo_mask, 0.U(wordBytes.W)) 634 ) 635 } 636 val s3_amo_data_merged_reg = RegEnable(s3_amo_data_merged, do_amoalu) 637 when(do_amoalu){ 638 s3_s_amoalu := true.B 639 s3_s_amoalu_dup.foreach(_ := true.B) 640 } 641 642 val miss_wb = s3_req_miss_dup(3) && s3_need_replacement && s3_coh_dup(1).state =/= ClientStates.Nothing 643 val miss_wb_dup = s3_req_miss_dup(3) && s3_need_replacement_dup && s3_coh_dup(1).state =/= ClientStates.Nothing 644 val probe_wb = s3_req.probe 645 val replace_wb = s3_req.replace 646 val need_wb = miss_wb_dup || probe_wb || replace_wb 647 648 val (_, miss_shrink_param, _) = s3_coh_dup(2).onCacheControl(M_FLUSH) 649 val writeback_param = Mux(probe_wb, probe_shrink_param, miss_shrink_param) 650 val writeback_data = if (dcacheParameters.alwaysReleaseData) { 651 s3_tag_match && s3_req_probe_dup(6) && s3_req.probe_need_data || 652 s3_coh_dup(3) === ClientStates.Dirty || (miss_wb || replace_wb) && s3_coh_dup(3).state =/= ClientStates.Nothing 653 } else { 654 s3_tag_match && s3_req_probe_dup(6) && s3_req.probe_need_data || s3_coh_dup(3) === ClientStates.Dirty 655 } 656 657 val s3_probe_can_go = s3_req_probe_dup(7) && io.wb.ready && (io.meta_write.ready || !probe_update_meta) 658 val s3_store_can_go = s3_req_source_dup_1 === STORE_SOURCE.U && !s3_req_probe_dup(8) && (io.meta_write.ready || !store_update_meta) && (io.data_write.ready || !update_data) 659 val s3_amo_can_go = s3_amo_hit_dup && (io.meta_write.ready || !amo_update_meta) && (io.data_write.ready || !update_data) && (s3_s_amoalu_dup(0) || !amo_wait_amoalu) 660 val s3_miss_can_go = s3_req_miss_dup(4) && 661 (io.meta_write.ready || !amo_update_meta) && 662 (io.data_write.ready || !update_data) && 663 (s3_s_amoalu_dup(1) || !amo_wait_amoalu) && 664 io.tag_write.ready && 665 io.wb.ready 666 val s3_replace_nothing = s3_req_replace_dup(1) && s3_coh_dup(4).state === ClientStates.Nothing 667 val s3_replace_can_go = s3_req_replace_dup(2) && (s3_replace_nothing || io.wb.ready) 668 val s3_can_go = s3_probe_can_go || s3_store_can_go || s3_amo_can_go || s3_miss_can_go || s3_replace_can_go 669 val s3_update_data_cango = s3_store_can_go || s3_amo_can_go || s3_miss_can_go // used to speed up data_write gen 670 671 // ---------------- duplicate regs for meta_write.valid to solve fanout ---------------- 672 val s3_req_miss_dup_for_meta_w_valid = RegEnable(s2_req.miss, s2_fire_to_s3) 673 val s3_req_probe_dup_for_meta_w_valid = RegEnable(s2_req.probe, s2_fire_to_s3) 674 val s3_tag_match_dup_for_meta_w_valid = RegEnable(s2_tag_match, s2_fire_to_s3) 675 val s3_coh_dup_for_meta_w_valid = RegEnable(s2_coh, s2_fire_to_s3) 676 val s3_req_probe_param_dup_for_meta_w_valid = RegEnable(s2_req.probe_param, s2_fire_to_s3) 677 val (_, _, probe_new_coh_dup_for_meta_w_valid) = s3_coh_dup_for_meta_w_valid.onProbe(s3_req_probe_param_dup_for_meta_w_valid) 678 val s3_req_source_dup_for_meta_w_valid = RegEnable(s2_req.source, s2_fire_to_s3) 679 val s3_req_cmd_dup_for_meta_w_valid = RegEnable(s2_req.cmd, s2_fire_to_s3) 680 val s3_req_replace_dup_for_meta_w_valid = RegEnable(s2_req.replace, s2_fire_to_s3) 681 val s3_hit_coh_dup_for_meta_w_valid = RegEnable(s2_hit_coh, s2_fire_to_s3) 682 val s3_new_hit_coh_dup_for_meta_w_valid = RegEnable(s2_new_hit_coh, s2_fire_to_s3) 683 684 val miss_update_meta_dup_for_meta_w_valid = s3_req_miss_dup_for_meta_w_valid 685 val probe_update_meta_dup_for_meta_w_valid = WireInit(s3_req_probe_dup_for_meta_w_valid && s3_tag_match_dup_for_meta_w_valid && s3_coh_dup_for_meta_w_valid =/= probe_new_coh_dup_for_meta_w_valid) 686 val store_update_meta_dup_for_meta_w_valid = s3_req_source_dup_for_meta_w_valid === STORE_SOURCE.U && 687 !s3_req_probe_dup_for_meta_w_valid && 688 s3_hit_coh_dup_for_meta_w_valid =/= s3_new_hit_coh_dup_for_meta_w_valid 689 val amo_update_meta_dup_for_meta_w_valid = s3_req_source_dup_for_meta_w_valid === AMO_SOURCE.U && 690 !s3_req_probe_dup_for_meta_w_valid && 691 s3_hit_coh_dup_for_meta_w_valid =/= s3_new_hit_coh_dup_for_meta_w_valid 692 val update_meta_dup_for_meta_w_valid = ( 693 miss_update_meta_dup_for_meta_w_valid || 694 probe_update_meta_dup_for_meta_w_valid || 695 store_update_meta_dup_for_meta_w_valid || 696 amo_update_meta_dup_for_meta_w_valid 697 ) && !s3_req_replace_dup_for_meta_w_valid 698 699 val s3_valid_dup_for_meta_w_valid = RegInit(false.B) 700 val s3_amo_hit_dup_for_meta_w_valid = RegEnable(s2_amo_hit, s2_fire_to_s3) 701 val s3_s_amoalu_dup_for_meta_w_valid = RegInit(false.B) 702 val amo_wait_amoalu_dup_for_meta_w_valid = s3_req_source_dup_for_meta_w_valid === AMO_SOURCE.U && 703 s3_req_cmd_dup_for_meta_w_valid =/= M_XLR && 704 s3_req_cmd_dup_for_meta_w_valid =/= M_XSC 705 val do_amoalu_dup_for_meta_w_valid = amo_wait_amoalu_dup_for_meta_w_valid && s3_valid_dup_for_meta_w_valid && !s3_s_amoalu_dup_for_meta_w_valid 706 707 val s3_store_hit_dup_for_meta_w_valid = RegEnable(s2_store_hit, s2_fire_to_s3) 708 val s3_req_addr_dup_for_meta_w_valid = RegEnable(s2_req.addr, s2_fire_to_s3) 709 val s3_can_do_amo_dup_for_meta_w_valid = (s3_req_miss_dup_for_meta_w_valid && !s3_req_probe_dup_for_meta_w_valid && s3_req_source_dup_for_meta_w_valid === AMO_SOURCE.U) || 710 s3_amo_hit_dup_for_meta_w_valid 711 712 val s3_lr_dup_for_meta_w_valid = !s3_req_probe_dup_for_meta_w_valid && s3_req_source_dup_for_meta_w_valid === AMO_SOURCE.U && s3_req_cmd_dup_for_meta_w_valid === M_XLR 713 val s3_sc_dup_for_meta_w_valid = !s3_req_probe_dup_for_meta_w_valid && s3_req_source_dup_for_meta_w_valid === AMO_SOURCE.U && s3_req_cmd_dup_for_meta_w_valid === M_XSC 714 val lrsc_addr_dup_for_meta_w_valid = Reg(UInt()) 715 val lrsc_count_dup_for_meta_w_valid = RegInit(0.U(log2Ceil(LRSCCycles).W)) 716 717 when (s3_valid_dup_for_meta_w_valid && (s3_lr_dup_for_meta_w_valid || s3_sc_dup_for_meta_w_valid)) { 718 when (s3_can_do_amo_dup_for_meta_w_valid && s3_lr_dup_for_meta_w_valid) { 719 lrsc_count_dup_for_meta_w_valid := (LRSCCycles - 1).U 720 lrsc_addr_dup_for_meta_w_valid := get_block_addr(s3_req_addr_dup_for_meta_w_valid) 721 }.otherwise { 722 lrsc_count_dup_for_meta_w_valid := 0.U 723 } 724 }.elsewhen (io.invalid_resv_set) { 725 lrsc_count_dup_for_meta_w_valid := 0.U 726 }.elsewhen (lrsc_count_dup_for_meta_w_valid > 0.U) { 727 lrsc_count_dup_for_meta_w_valid := lrsc_count_dup_for_meta_w_valid - 1.U 728 } 729 730 val lrsc_valid_dup_for_meta_w_valid = lrsc_count_dup_for_meta_w_valid > LRSCBackOff.U 731 val s3_lrsc_addr_match_dup_for_meta_w_valid = lrsc_valid_dup_for_meta_w_valid && lrsc_addr_dup_for_meta_w_valid === get_block_addr(s3_req_addr_dup_for_meta_w_valid) 732 val s3_sc_fail_dup_for_meta_w_valid = s3_sc_dup_for_meta_w_valid && !s3_lrsc_addr_match_dup_for_meta_w_valid 733 val s3_can_do_amo_write_dup_for_meta_w_valid = s3_can_do_amo_dup_for_meta_w_valid && isWrite(s3_req_cmd_dup_for_meta_w_valid) && !s3_sc_fail_dup_for_meta_w_valid 734 val update_data_dup_for_meta_w_valid = s3_req_miss_dup_for_meta_w_valid || s3_store_hit_dup_for_meta_w_valid || s3_can_do_amo_write_dup_for_meta_w_valid 735 736 val s3_probe_can_go_dup_for_meta_w_valid = s3_req_probe_dup_for_meta_w_valid && 737 io.wb_ready_dup(metaWritePort) && 738 (io.meta_write.ready || !probe_update_meta_dup_for_meta_w_valid) 739 val s3_store_can_go_dup_for_meta_w_valid = s3_req_source_dup_for_meta_w_valid === STORE_SOURCE.U && !s3_req_probe_dup_for_meta_w_valid && 740 (io.meta_write.ready || !store_update_meta_dup_for_meta_w_valid) && 741 (io.data_write_ready_dup(metaWritePort) || !update_data_dup_for_meta_w_valid) 742 val s3_amo_can_go_dup_for_meta_w_valid = s3_amo_hit_dup_for_meta_w_valid && 743 (io.meta_write.ready || !amo_update_meta_dup_for_meta_w_valid) && 744 (io.data_write_ready_dup(metaWritePort) || !update_data_dup_for_meta_w_valid) && 745 (s3_s_amoalu_dup_for_meta_w_valid || !amo_wait_amoalu_dup_for_meta_w_valid) 746 val s3_miss_can_go_dup_for_meta_w_valid = s3_req_miss_dup_for_meta_w_valid && 747 (io.meta_write.ready || !amo_update_meta_dup_for_meta_w_valid) && 748 (io.data_write_ready_dup(metaWritePort) || !update_data_dup_for_meta_w_valid) && 749 (s3_s_amoalu_dup_for_meta_w_valid || !amo_wait_amoalu_dup_for_meta_w_valid) && 750 io.tag_write_ready_dup(metaWritePort) && 751 io.wb_ready_dup(metaWritePort) 752 val s3_replace_can_go_dup_for_meta_w_valid = s3_req_replace_dup_for_meta_w_valid && 753 (s3_coh_dup_for_meta_w_valid.state === ClientStates.Nothing || io.wb_ready_dup(metaWritePort)) 754 val s3_can_go_dup_for_meta_w_valid = s3_probe_can_go_dup_for_meta_w_valid || 755 s3_store_can_go_dup_for_meta_w_valid || 756 s3_amo_can_go_dup_for_meta_w_valid || 757 s3_miss_can_go_dup_for_meta_w_valid || 758 s3_replace_can_go_dup_for_meta_w_valid 759 760 val s3_fire_dup_for_meta_w_valid = s3_valid_dup_for_meta_w_valid && s3_can_go_dup_for_meta_w_valid 761 when (do_amoalu_dup_for_meta_w_valid) { s3_s_amoalu_dup_for_meta_w_valid := true.B } 762 when (s3_fire_dup_for_meta_w_valid) { s3_s_amoalu_dup_for_meta_w_valid := false.B } 763 764 // fix probe meta change 765 val s3_probe_ttob_override = s3_valid && 766 // s3_probe_ttob_check_resp.valid && 767 s3_probe_ttob_check_resp.bits.toN && 768 s3_coh_dup_for_meta_w_valid === Trunk 769 val s3_probe_new_coh = Mux( 770 s3_probe_ttob_override, 771 ClientMetadata(Nothing), 772 probe_new_coh_dup_for_meta_w_valid 773 ) 774 when(s3_probe_ttob_override) { 775 probe_update_meta_dup_for_meta_w_valid := true.B 776 } 777 778 val new_coh = Mux( 779 miss_update_meta_dup_for_meta_w_valid, 780 miss_new_coh, 781 Mux( 782 probe_update_meta, 783 s3_probe_new_coh, 784 Mux( 785 store_update_meta_dup_for_meta_w_valid || amo_update_meta_dup_for_meta_w_valid, 786 s3_new_hit_coh_dup_for_meta_w_valid, 787 ClientMetadata.onReset 788 ) 789 ) 790 ) 791 792 when (s2_fire_to_s3) { s3_valid_dup_for_meta_w_valid := true.B } 793 .elsewhen (s3_fire_dup_for_meta_w_valid) { s3_valid_dup_for_meta_w_valid := false.B } 794 // ------------------------------------------------------------------------------------- 795 796 // ---------------- duplicate regs for err_write.valid to solve fanout ----------------- 797 val s3_req_miss_dup_for_err_w_valid = RegEnable(s2_req.miss, s2_fire_to_s3) 798 val s3_req_probe_dup_for_err_w_valid = RegEnable(s2_req.probe, s2_fire_to_s3) 799 val s3_tag_match_dup_for_err_w_valid = RegEnable(s2_tag_match, s2_fire_to_s3) 800 val s3_coh_dup_for_err_w_valid = RegEnable(s2_coh, s2_fire_to_s3) 801 val s3_req_probe_param_dup_for_err_w_valid = RegEnable(s2_req.probe_param, s2_fire_to_s3) 802 val (_, _, probe_new_coh_dup_for_err_w_valid) = s3_coh_dup_for_err_w_valid.onProbe(s3_req_probe_param_dup_for_err_w_valid) 803 val s3_req_source_dup_for_err_w_valid = RegEnable(s2_req.source, s2_fire_to_s3) 804 val s3_req_cmd_dup_for_err_w_valid = RegEnable(s2_req.cmd, s2_fire_to_s3) 805 val s3_req_replace_dup_for_err_w_valid = RegEnable(s2_req.replace, s2_fire_to_s3) 806 val s3_hit_coh_dup_for_err_w_valid = RegEnable(s2_hit_coh, s2_fire_to_s3) 807 val s3_new_hit_coh_dup_for_err_w_valid = RegEnable(s2_new_hit_coh, s2_fire_to_s3) 808 809 val miss_update_meta_dup_for_err_w_valid = s3_req_miss_dup_for_err_w_valid 810 val probe_update_meta_dup_for_err_w_valid = s3_req_probe_dup_for_err_w_valid && s3_tag_match_dup_for_err_w_valid && s3_coh_dup_for_err_w_valid =/= probe_new_coh_dup_for_err_w_valid 811 val store_update_meta_dup_for_err_w_valid = s3_req_source_dup_for_err_w_valid === STORE_SOURCE.U && 812 !s3_req_probe_dup_for_err_w_valid && 813 s3_hit_coh_dup_for_err_w_valid =/= s3_new_hit_coh_dup_for_err_w_valid 814 val amo_update_meta_dup_for_err_w_valid = s3_req_source_dup_for_err_w_valid === AMO_SOURCE.U && 815 !s3_req_probe_dup_for_err_w_valid && 816 s3_hit_coh_dup_for_err_w_valid =/= s3_new_hit_coh_dup_for_err_w_valid 817 val update_meta_dup_for_err_w_valid = ( 818 miss_update_meta_dup_for_err_w_valid || 819 probe_update_meta_dup_for_err_w_valid || 820 store_update_meta_dup_for_err_w_valid || 821 amo_update_meta_dup_for_err_w_valid 822 ) && !s3_req_replace_dup_for_err_w_valid 823 824 val s3_valid_dup_for_err_w_valid = RegInit(false.B) 825 val s3_amo_hit_dup_for_err_w_valid = RegEnable(s2_amo_hit, s2_fire_to_s3) 826 val s3_s_amoalu_dup_for_err_w_valid = RegInit(false.B) 827 val amo_wait_amoalu_dup_for_err_w_valid = s3_req_source_dup_for_err_w_valid === AMO_SOURCE.U && 828 s3_req_cmd_dup_for_err_w_valid =/= M_XLR && 829 s3_req_cmd_dup_for_err_w_valid =/= M_XSC 830 val do_amoalu_dup_for_err_w_valid = amo_wait_amoalu_dup_for_err_w_valid && s3_valid_dup_for_err_w_valid && !s3_s_amoalu_dup_for_err_w_valid 831 832 val s3_store_hit_dup_for_err_w_valid = RegEnable(s2_store_hit, s2_fire_to_s3) 833 val s3_req_addr_dup_for_err_w_valid = RegEnable(s2_req.addr, s2_fire_to_s3) 834 val s3_can_do_amo_dup_for_err_w_valid = (s3_req_miss_dup_for_err_w_valid && !s3_req_probe_dup_for_err_w_valid && s3_req_source_dup_for_err_w_valid === AMO_SOURCE.U) || 835 s3_amo_hit_dup_for_err_w_valid 836 837 val s3_lr_dup_for_err_w_valid = !s3_req_probe_dup_for_err_w_valid && s3_req_source_dup_for_err_w_valid === AMO_SOURCE.U && s3_req_cmd_dup_for_err_w_valid === M_XLR 838 val s3_sc_dup_for_err_w_valid = !s3_req_probe_dup_for_err_w_valid && s3_req_source_dup_for_err_w_valid === AMO_SOURCE.U && s3_req_cmd_dup_for_err_w_valid === M_XSC 839 val lrsc_addr_dup_for_err_w_valid = Reg(UInt()) 840 val lrsc_count_dup_for_err_w_valid = RegInit(0.U(log2Ceil(LRSCCycles).W)) 841 842 when (s3_valid_dup_for_err_w_valid && (s3_lr_dup_for_err_w_valid || s3_sc_dup_for_err_w_valid)) { 843 when (s3_can_do_amo_dup_for_err_w_valid && s3_lr_dup_for_err_w_valid) { 844 lrsc_count_dup_for_err_w_valid := (LRSCCycles - 1).U 845 lrsc_addr_dup_for_err_w_valid := get_block_addr(s3_req_addr_dup_for_err_w_valid) 846 }.otherwise { 847 lrsc_count_dup_for_err_w_valid := 0.U 848 } 849 }.elsewhen (io.invalid_resv_set) { 850 lrsc_count_dup_for_err_w_valid := 0.U 851 }.elsewhen (lrsc_count_dup_for_err_w_valid > 0.U) { 852 lrsc_count_dup_for_err_w_valid := lrsc_count_dup_for_err_w_valid - 1.U 853 } 854 855 val lrsc_valid_dup_for_err_w_valid = lrsc_count_dup_for_err_w_valid > LRSCBackOff.U 856 val s3_lrsc_addr_match_dup_for_err_w_valid = lrsc_valid_dup_for_err_w_valid && lrsc_addr_dup_for_err_w_valid === get_block_addr(s3_req_addr_dup_for_err_w_valid) 857 val s3_sc_fail_dup_for_err_w_valid = s3_sc_dup_for_err_w_valid && !s3_lrsc_addr_match_dup_for_err_w_valid 858 val s3_can_do_amo_write_dup_for_err_w_valid = s3_can_do_amo_dup_for_err_w_valid && isWrite(s3_req_cmd_dup_for_err_w_valid) && !s3_sc_fail_dup_for_err_w_valid 859 val update_data_dup_for_err_w_valid = s3_req_miss_dup_for_err_w_valid || s3_store_hit_dup_for_err_w_valid || s3_can_do_amo_write_dup_for_err_w_valid 860 861 val s3_probe_can_go_dup_for_err_w_valid = s3_req_probe_dup_for_err_w_valid && 862 io.wb_ready_dup(errWritePort) && 863 (io.meta_write.ready || !probe_update_meta_dup_for_err_w_valid) 864 val s3_store_can_go_dup_for_err_w_valid = s3_req_source_dup_for_err_w_valid === STORE_SOURCE.U && !s3_req_probe_dup_for_err_w_valid && 865 (io.meta_write.ready || !store_update_meta_dup_for_err_w_valid) && 866 (io.data_write_ready_dup(errWritePort) || !update_data_dup_for_err_w_valid) 867 val s3_amo_can_go_dup_for_err_w_valid = s3_amo_hit_dup_for_err_w_valid && 868 (io.meta_write.ready || !amo_update_meta_dup_for_err_w_valid) && 869 (io.data_write_ready_dup(errWritePort) || !update_data_dup_for_err_w_valid) && 870 (s3_s_amoalu_dup_for_err_w_valid || !amo_wait_amoalu_dup_for_err_w_valid) 871 val s3_miss_can_go_dup_for_err_w_valid = s3_req_miss_dup_for_err_w_valid && 872 (io.meta_write.ready || !amo_update_meta_dup_for_err_w_valid) && 873 (io.data_write_ready_dup(errWritePort) || !update_data_dup_for_err_w_valid) && 874 (s3_s_amoalu_dup_for_err_w_valid || !amo_wait_amoalu_dup_for_err_w_valid) && 875 io.tag_write_ready_dup(errWritePort) && 876 io.wb_ready_dup(errWritePort) 877 val s3_replace_can_go_dup_for_err_w_valid = s3_req_replace_dup_for_err_w_valid && 878 (s3_coh_dup_for_err_w_valid.state === ClientStates.Nothing || io.wb_ready_dup(errWritePort)) 879 val s3_can_go_dup_for_err_w_valid = s3_probe_can_go_dup_for_err_w_valid || 880 s3_store_can_go_dup_for_err_w_valid || 881 s3_amo_can_go_dup_for_err_w_valid || 882 s3_miss_can_go_dup_for_err_w_valid || 883 s3_replace_can_go_dup_for_err_w_valid 884 885 val s3_fire_dup_for_err_w_valid = s3_valid_dup_for_err_w_valid && s3_can_go_dup_for_err_w_valid 886 when (do_amoalu_dup_for_err_w_valid) { s3_s_amoalu_dup_for_err_w_valid := true.B } 887 when (s3_fire_dup_for_err_w_valid) { s3_s_amoalu_dup_for_err_w_valid := false.B } 888 889 when (s2_fire_to_s3) { s3_valid_dup_for_err_w_valid := true.B } 890 .elsewhen (s3_fire_dup_for_err_w_valid) { s3_valid_dup_for_err_w_valid := false.B } 891 // ------------------------------------------------------------------------------------- 892 // ---------------- duplicate regs for tag_write.valid to solve fanout ----------------- 893 val s3_req_miss_dup_for_tag_w_valid = RegEnable(s2_req.miss, s2_fire_to_s3) 894 val s3_req_probe_dup_for_tag_w_valid = RegEnable(s2_req.probe, s2_fire_to_s3) 895 val s3_tag_match_dup_for_tag_w_valid = RegEnable(s2_tag_match, s2_fire_to_s3) 896 val s3_coh_dup_for_tag_w_valid = RegEnable(s2_coh, s2_fire_to_s3) 897 val s3_req_probe_param_dup_for_tag_w_valid = RegEnable(s2_req.probe_param, s2_fire_to_s3) 898 val (_, _, probe_new_coh_dup_for_tag_w_valid) = s3_coh_dup_for_tag_w_valid.onProbe(s3_req_probe_param_dup_for_tag_w_valid) 899 val s3_req_source_dup_for_tag_w_valid = RegEnable(s2_req.source, s2_fire_to_s3) 900 val s3_req_cmd_dup_for_tag_w_valid = RegEnable(s2_req.cmd, s2_fire_to_s3) 901 val s3_req_replace_dup_for_tag_w_valid = RegEnable(s2_req.replace, s2_fire_to_s3) 902 val s3_hit_coh_dup_for_tag_w_valid = RegEnable(s2_hit_coh, s2_fire_to_s3) 903 val s3_new_hit_coh_dup_for_tag_w_valid = RegEnable(s2_new_hit_coh, s2_fire_to_s3) 904 905 val miss_update_meta_dup_for_tag_w_valid = s3_req_miss_dup_for_tag_w_valid 906 val probe_update_meta_dup_for_tag_w_valid = s3_req_probe_dup_for_tag_w_valid && s3_tag_match_dup_for_tag_w_valid && s3_coh_dup_for_tag_w_valid =/= probe_new_coh_dup_for_tag_w_valid 907 val store_update_meta_dup_for_tag_w_valid = s3_req_source_dup_for_tag_w_valid === STORE_SOURCE.U && 908 !s3_req_probe_dup_for_tag_w_valid && 909 s3_hit_coh_dup_for_tag_w_valid =/= s3_new_hit_coh_dup_for_tag_w_valid 910 val amo_update_meta_dup_for_tag_w_valid = s3_req_source_dup_for_tag_w_valid === AMO_SOURCE.U && 911 !s3_req_probe_dup_for_tag_w_valid && 912 s3_hit_coh_dup_for_tag_w_valid =/= s3_new_hit_coh_dup_for_tag_w_valid 913 val update_meta_dup_for_tag_w_valid = ( 914 miss_update_meta_dup_for_tag_w_valid || 915 probe_update_meta_dup_for_tag_w_valid || 916 store_update_meta_dup_for_tag_w_valid || 917 amo_update_meta_dup_for_tag_w_valid 918 ) && !s3_req_replace_dup_for_tag_w_valid 919 920 val s3_valid_dup_for_tag_w_valid = RegInit(false.B) 921 val s3_amo_hit_dup_for_tag_w_valid = RegEnable(s2_amo_hit, s2_fire_to_s3) 922 val s3_s_amoalu_dup_for_tag_w_valid = RegInit(false.B) 923 val amo_wait_amoalu_dup_for_tag_w_valid = s3_req_source_dup_for_tag_w_valid === AMO_SOURCE.U && 924 s3_req_cmd_dup_for_tag_w_valid =/= M_XLR && 925 s3_req_cmd_dup_for_tag_w_valid =/= M_XSC 926 val do_amoalu_dup_for_tag_w_valid = amo_wait_amoalu_dup_for_tag_w_valid && s3_valid_dup_for_tag_w_valid && !s3_s_amoalu_dup_for_tag_w_valid 927 928 val s3_store_hit_dup_for_tag_w_valid = RegEnable(s2_store_hit, s2_fire_to_s3) 929 val s3_req_addr_dup_for_tag_w_valid = RegEnable(s2_req.addr, s2_fire_to_s3) 930 val s3_can_do_amo_dup_for_tag_w_valid = (s3_req_miss_dup_for_tag_w_valid && !s3_req_probe_dup_for_tag_w_valid && s3_req_source_dup_for_tag_w_valid === AMO_SOURCE.U) || 931 s3_amo_hit_dup_for_tag_w_valid 932 933 val s3_lr_dup_for_tag_w_valid = !s3_req_probe_dup_for_tag_w_valid && s3_req_source_dup_for_tag_w_valid === AMO_SOURCE.U && s3_req_cmd_dup_for_tag_w_valid === M_XLR 934 val s3_sc_dup_for_tag_w_valid = !s3_req_probe_dup_for_tag_w_valid && s3_req_source_dup_for_tag_w_valid === AMO_SOURCE.U && s3_req_cmd_dup_for_tag_w_valid === M_XSC 935 val lrsc_addr_dup_for_tag_w_valid = Reg(UInt()) 936 val lrsc_count_dup_for_tag_w_valid = RegInit(0.U(log2Ceil(LRSCCycles).W)) 937 938 when (s3_valid_dup_for_tag_w_valid && (s3_lr_dup_for_tag_w_valid || s3_sc_dup_for_tag_w_valid)) { 939 when (s3_can_do_amo_dup_for_tag_w_valid && s3_lr_dup_for_tag_w_valid) { 940 lrsc_count_dup_for_tag_w_valid := (LRSCCycles - 1).U 941 lrsc_addr_dup_for_tag_w_valid := get_block_addr(s3_req_addr_dup_for_tag_w_valid) 942 }.otherwise { 943 lrsc_count_dup_for_tag_w_valid := 0.U 944 } 945 }.elsewhen (io.invalid_resv_set) { 946 lrsc_count_dup_for_tag_w_valid := 0.U 947 }.elsewhen (lrsc_count_dup_for_tag_w_valid > 0.U) { 948 lrsc_count_dup_for_tag_w_valid := lrsc_count_dup_for_tag_w_valid - 1.U 949 } 950 951 val lrsc_valid_dup_for_tag_w_valid = lrsc_count_dup_for_tag_w_valid > LRSCBackOff.U 952 val s3_lrsc_addr_match_dup_for_tag_w_valid = lrsc_valid_dup_for_tag_w_valid && lrsc_addr_dup_for_tag_w_valid === get_block_addr(s3_req_addr_dup_for_tag_w_valid) 953 val s3_sc_fail_dup_for_tag_w_valid = s3_sc_dup_for_tag_w_valid && !s3_lrsc_addr_match_dup_for_tag_w_valid 954 val s3_can_do_amo_write_dup_for_tag_w_valid = s3_can_do_amo_dup_for_tag_w_valid && isWrite(s3_req_cmd_dup_for_tag_w_valid) && !s3_sc_fail_dup_for_tag_w_valid 955 val update_data_dup_for_tag_w_valid = s3_req_miss_dup_for_tag_w_valid || s3_store_hit_dup_for_tag_w_valid || s3_can_do_amo_write_dup_for_tag_w_valid 956 957 val s3_probe_can_go_dup_for_tag_w_valid = s3_req_probe_dup_for_tag_w_valid && 958 io.wb_ready_dup(tagWritePort) && 959 (io.meta_write.ready || !probe_update_meta_dup_for_tag_w_valid) 960 val s3_store_can_go_dup_for_tag_w_valid = s3_req_source_dup_for_tag_w_valid === STORE_SOURCE.U && !s3_req_probe_dup_for_tag_w_valid && 961 (io.meta_write.ready || !store_update_meta_dup_for_tag_w_valid) && 962 (io.data_write_ready_dup(tagWritePort) || !update_data_dup_for_tag_w_valid) 963 val s3_amo_can_go_dup_for_tag_w_valid = s3_amo_hit_dup_for_tag_w_valid && 964 (io.meta_write.ready || !amo_update_meta_dup_for_tag_w_valid) && 965 (io.data_write_ready_dup(tagWritePort) || !update_data_dup_for_tag_w_valid) && 966 (s3_s_amoalu_dup_for_tag_w_valid || !amo_wait_amoalu_dup_for_tag_w_valid) 967 val s3_miss_can_go_dup_for_tag_w_valid = s3_req_miss_dup_for_tag_w_valid && 968 (io.meta_write.ready || !amo_update_meta_dup_for_tag_w_valid) && 969 (io.data_write_ready_dup(tagWritePort) || !update_data_dup_for_tag_w_valid) && 970 (s3_s_amoalu_dup_for_tag_w_valid || !amo_wait_amoalu_dup_for_tag_w_valid) && 971 io.tag_write_ready_dup(tagWritePort) && 972 io.wb_ready_dup(tagWritePort) 973 val s3_replace_can_go_dup_for_tag_w_valid = s3_req_replace_dup_for_tag_w_valid && 974 (s3_coh_dup_for_tag_w_valid.state === ClientStates.Nothing || io.wb_ready_dup(tagWritePort)) 975 val s3_can_go_dup_for_tag_w_valid = s3_probe_can_go_dup_for_tag_w_valid || 976 s3_store_can_go_dup_for_tag_w_valid || 977 s3_amo_can_go_dup_for_tag_w_valid || 978 s3_miss_can_go_dup_for_tag_w_valid || 979 s3_replace_can_go_dup_for_tag_w_valid 980 981 val s3_fire_dup_for_tag_w_valid = s3_valid_dup_for_tag_w_valid && s3_can_go_dup_for_tag_w_valid 982 when (do_amoalu_dup_for_tag_w_valid) { s3_s_amoalu_dup_for_tag_w_valid := true.B } 983 when (s3_fire_dup_for_tag_w_valid) { s3_s_amoalu_dup_for_tag_w_valid := false.B } 984 985 when (s2_fire_to_s3) { s3_valid_dup_for_tag_w_valid := true.B } 986 .elsewhen (s3_fire_dup_for_tag_w_valid) { s3_valid_dup_for_tag_w_valid := false.B } 987 // ------------------------------------------------------------------------------------- 988 // ---------------- duplicate regs for data_write.valid to solve fanout ---------------- 989 val s3_req_miss_dup_for_data_w_valid = RegEnable(s2_req.miss, s2_fire_to_s3) 990 val s3_req_probe_dup_for_data_w_valid = RegEnable(s2_req.probe, s2_fire_to_s3) 991 val s3_tag_match_dup_for_data_w_valid = RegEnable(s2_tag_match, s2_fire_to_s3) 992 val s3_coh_dup_for_data_w_valid = RegEnable(s2_coh, s2_fire_to_s3) 993 val s3_req_probe_param_dup_for_data_w_valid = RegEnable(s2_req.probe_param, s2_fire_to_s3) 994 val (_, _, probe_new_coh_dup_for_data_w_valid) = s3_coh_dup_for_data_w_valid.onProbe(s3_req_probe_param_dup_for_data_w_valid) 995 val s3_req_source_dup_for_data_w_valid = RegEnable(s2_req.source, s2_fire_to_s3) 996 val s3_req_cmd_dup_for_data_w_valid = RegEnable(s2_req.cmd, s2_fire_to_s3) 997 val s3_req_replace_dup_for_data_w_valid = RegEnable(s2_req.replace, s2_fire_to_s3) 998 val s3_hit_coh_dup_for_data_w_valid = RegEnable(s2_hit_coh, s2_fire_to_s3) 999 val s3_new_hit_coh_dup_for_data_w_valid = RegEnable(s2_new_hit_coh, s2_fire_to_s3) 1000 1001 val miss_update_meta_dup_for_data_w_valid = s3_req_miss_dup_for_data_w_valid 1002 val probe_update_meta_dup_for_data_w_valid = s3_req_probe_dup_for_data_w_valid && s3_tag_match_dup_for_data_w_valid && s3_coh_dup_for_data_w_valid =/= probe_new_coh_dup_for_data_w_valid 1003 val store_update_meta_dup_for_data_w_valid = s3_req_source_dup_for_data_w_valid === STORE_SOURCE.U && 1004 !s3_req_probe_dup_for_data_w_valid && 1005 s3_hit_coh_dup_for_data_w_valid =/= s3_new_hit_coh_dup_for_data_w_valid 1006 val amo_update_meta_dup_for_data_w_valid = s3_req_source_dup_for_data_w_valid === AMO_SOURCE.U && 1007 !s3_req_probe_dup_for_data_w_valid && 1008 s3_hit_coh_dup_for_data_w_valid =/= s3_new_hit_coh_dup_for_data_w_valid 1009 val update_meta_dup_for_data_w_valid = ( 1010 miss_update_meta_dup_for_data_w_valid || 1011 probe_update_meta_dup_for_data_w_valid || 1012 store_update_meta_dup_for_data_w_valid || 1013 amo_update_meta_dup_for_data_w_valid 1014 ) && !s3_req_replace_dup_for_data_w_valid 1015 1016 val s3_valid_dup_for_data_w_valid = RegInit(false.B) 1017 val s3_amo_hit_dup_for_data_w_valid = RegEnable(s2_amo_hit, s2_fire_to_s3) 1018 val s3_s_amoalu_dup_for_data_w_valid = RegInit(false.B) 1019 val amo_wait_amoalu_dup_for_data_w_valid = s3_req_source_dup_for_data_w_valid === AMO_SOURCE.U && 1020 s3_req_cmd_dup_for_data_w_valid =/= M_XLR && 1021 s3_req_cmd_dup_for_data_w_valid =/= M_XSC 1022 val do_amoalu_dup_for_data_w_valid = amo_wait_amoalu_dup_for_data_w_valid && s3_valid_dup_for_data_w_valid && !s3_s_amoalu_dup_for_data_w_valid 1023 1024 val s3_store_hit_dup_for_data_w_valid = RegEnable(s2_store_hit, s2_fire_to_s3) 1025 val s3_req_addr_dup_for_data_w_valid = RegEnable(s2_req.addr, s2_fire_to_s3) 1026 val s3_can_do_amo_dup_for_data_w_valid = (s3_req_miss_dup_for_data_w_valid && !s3_req_probe_dup_for_data_w_valid && s3_req_source_dup_for_data_w_valid === AMO_SOURCE.U) || 1027 s3_amo_hit_dup_for_data_w_valid 1028 1029 val s3_lr_dup_for_data_w_valid = !s3_req_probe_dup_for_data_w_valid && s3_req_source_dup_for_data_w_valid === AMO_SOURCE.U && s3_req_cmd_dup_for_data_w_valid === M_XLR 1030 val s3_sc_dup_for_data_w_valid = !s3_req_probe_dup_for_data_w_valid && s3_req_source_dup_for_data_w_valid === AMO_SOURCE.U && s3_req_cmd_dup_for_data_w_valid === M_XSC 1031 val lrsc_addr_dup_for_data_w_valid = Reg(UInt()) 1032 val lrsc_count_dup_for_data_w_valid = RegInit(0.U(log2Ceil(LRSCCycles).W)) 1033 1034 when (s3_valid_dup_for_data_w_valid && (s3_lr_dup_for_data_w_valid || s3_sc_dup_for_data_w_valid)) { 1035 when (s3_can_do_amo_dup_for_data_w_valid && s3_lr_dup_for_data_w_valid) { 1036 lrsc_count_dup_for_data_w_valid := (LRSCCycles - 1).U 1037 lrsc_addr_dup_for_data_w_valid := get_block_addr(s3_req_addr_dup_for_data_w_valid) 1038 }.otherwise { 1039 lrsc_count_dup_for_data_w_valid := 0.U 1040 } 1041 }.elsewhen (io.invalid_resv_set) { 1042 lrsc_count_dup_for_data_w_valid := 0.U 1043 }.elsewhen (lrsc_count_dup_for_data_w_valid > 0.U) { 1044 lrsc_count_dup_for_data_w_valid := lrsc_count_dup_for_data_w_valid - 1.U 1045 } 1046 1047 val lrsc_valid_dup_for_data_w_valid = lrsc_count_dup_for_data_w_valid > LRSCBackOff.U 1048 val s3_lrsc_addr_match_dup_for_data_w_valid = lrsc_valid_dup_for_data_w_valid && lrsc_addr_dup_for_data_w_valid === get_block_addr(s3_req_addr_dup_for_data_w_valid) 1049 val s3_sc_fail_dup_for_data_w_valid = s3_sc_dup_for_data_w_valid && !s3_lrsc_addr_match_dup_for_data_w_valid 1050 val s3_can_do_amo_write_dup_for_data_w_valid = s3_can_do_amo_dup_for_data_w_valid && isWrite(s3_req_cmd_dup_for_data_w_valid) && !s3_sc_fail_dup_for_data_w_valid 1051 val update_data_dup_for_data_w_valid = s3_req_miss_dup_for_data_w_valid || s3_store_hit_dup_for_data_w_valid || s3_can_do_amo_write_dup_for_data_w_valid 1052 1053 val s3_probe_can_go_dup_for_data_w_valid = s3_req_probe_dup_for_data_w_valid && 1054 io.wb_ready_dup(dataWritePort) && 1055 (io.meta_write.ready || !probe_update_meta_dup_for_data_w_valid) 1056 val s3_store_can_go_dup_for_data_w_valid = s3_req_source_dup_for_data_w_valid === STORE_SOURCE.U && !s3_req_probe_dup_for_data_w_valid && 1057 (io.meta_write.ready || !store_update_meta_dup_for_data_w_valid) && 1058 (io.data_write_ready_dup(dataWritePort) || !update_data_dup_for_data_w_valid) 1059 val s3_amo_can_go_dup_for_data_w_valid = s3_amo_hit_dup_for_data_w_valid && 1060 (io.meta_write.ready || !amo_update_meta_dup_for_data_w_valid) && 1061 (io.data_write_ready_dup(dataWritePort) || !update_data_dup_for_data_w_valid) && 1062 (s3_s_amoalu_dup_for_data_w_valid || !amo_wait_amoalu_dup_for_data_w_valid) 1063 val s3_miss_can_go_dup_for_data_w_valid = s3_req_miss_dup_for_data_w_valid && 1064 (io.meta_write.ready || !amo_update_meta_dup_for_data_w_valid) && 1065 (io.data_write_ready_dup(dataWritePort) || !update_data_dup_for_data_w_valid) && 1066 (s3_s_amoalu_dup_for_data_w_valid || !amo_wait_amoalu_dup_for_data_w_valid) && 1067 io.tag_write_ready_dup(dataWritePort) && 1068 io.wb_ready_dup(dataWritePort) 1069 val s3_replace_can_go_dup_for_data_w_valid = s3_req_replace_dup_for_data_w_valid && 1070 (s3_coh_dup_for_data_w_valid.state === ClientStates.Nothing || io.wb_ready_dup(dataWritePort)) 1071 val s3_can_go_dup_for_data_w_valid = s3_probe_can_go_dup_for_data_w_valid || 1072 s3_store_can_go_dup_for_data_w_valid || 1073 s3_amo_can_go_dup_for_data_w_valid || 1074 s3_miss_can_go_dup_for_data_w_valid || 1075 s3_replace_can_go_dup_for_data_w_valid 1076 val s3_update_data_cango_dup_for_data_w_valid = s3_store_can_go_dup_for_data_w_valid || s3_amo_can_go_dup_for_data_w_valid || s3_miss_can_go_dup_for_data_w_valid 1077 1078 val s3_fire_dup_for_data_w_valid = s3_valid_dup_for_data_w_valid && s3_can_go_dup_for_data_w_valid 1079 when (do_amoalu_dup_for_data_w_valid) { s3_s_amoalu_dup_for_data_w_valid := true.B } 1080 when (s3_fire_dup_for_data_w_valid) { s3_s_amoalu_dup_for_data_w_valid := false.B } 1081 1082 val s3_banked_store_wmask_dup_for_data_w_valid = RegEnable(s2_banked_store_wmask, s2_fire_to_s3) 1083 val s3_req_word_idx_dup_for_data_w_valid = RegEnable(s2_req.word_idx, s2_fire_to_s3) 1084 val banked_wmask = Mux( 1085 s3_req_miss_dup_for_data_w_valid, 1086 banked_full_wmask, 1087 Mux( 1088 s3_store_hit_dup_for_data_w_valid, 1089 s3_banked_store_wmask_dup_for_data_w_valid, 1090 Mux( 1091 s3_can_do_amo_write_dup_for_data_w_valid, 1092 UIntToOH(s3_req_word_idx_dup_for_data_w_valid), 1093 banked_none_wmask 1094 ) 1095 ) 1096 ) 1097 assert(!(s3_valid && banked_wmask.orR && !update_data)) 1098 1099 val s3_sc_data_merged_dup_for_data_w_valid = Wire(Vec(DCacheBanks, UInt(DCacheSRAMRowBits.W))) 1100 val s3_req_amo_data_dup_for_data_w_valid = RegEnable(s2_req.amo_data, s2_fire_to_s3) 1101 val s3_req_amo_mask_dup_for_data_w_valid = RegEnable(s2_req.amo_mask, s2_fire_to_s3) 1102 for (i <- 0 until DCacheBanks) { 1103 val old_data = s3_store_data_merged(i) 1104 s3_sc_data_merged_dup_for_data_w_valid(i) := mergePutData(old_data, s3_req_amo_data_dup_for_data_w_valid, 1105 Mux( 1106 s3_req_word_idx_dup_for_data_w_valid === i.U && !s3_sc_fail_dup_for_data_w_valid, 1107 s3_req_amo_mask_dup_for_data_w_valid, 1108 0.U(wordBytes.W) 1109 ) 1110 ) 1111 } 1112 1113 when (s2_fire_to_s3) { s3_valid_dup_for_data_w_valid := true.B } 1114 .elsewhen (s3_fire_dup_for_data_w_valid) { s3_valid_dup_for_data_w_valid := false.B } 1115 1116 val s3_valid_dup_for_data_w_bank = RegInit(VecInit(Seq.fill(DCacheBanks)(false.B))) // TODO 1117 val data_write_ready_dup_for_data_w_bank = io.data_write_ready_dup.drop(dataWritePort).take(DCacheBanks) 1118 val tag_write_ready_dup_for_data_w_bank = io.tag_write_ready_dup.drop(dataWritePort).take(DCacheBanks) 1119 val wb_ready_dup_for_data_w_bank = io.wb_ready_dup.drop(dataWritePort).take(DCacheBanks) 1120 for (i <- 0 until DCacheBanks) { 1121 val s3_req_miss_dup_for_data_w_bank = RegEnable(s2_req.miss, s2_fire_to_s3) 1122 val s3_req_probe_dup_for_data_w_bank = RegEnable(s2_req.probe, s2_fire_to_s3) 1123 val s3_tag_match_dup_for_data_w_bank = RegEnable(s2_tag_match, s2_fire_to_s3) 1124 val s3_coh_dup_for_data_w_bank = RegEnable(s2_coh, s2_fire_to_s3) 1125 val s3_req_probe_param_dup_for_data_w_bank = RegEnable(s2_req.probe_param, s2_fire_to_s3) 1126 val (_, _, probe_new_coh_dup_for_data_w_bank) = s3_coh_dup_for_data_w_bank.onProbe(s3_req_probe_param_dup_for_data_w_bank) 1127 val s3_req_source_dup_for_data_w_bank = RegEnable(s2_req.source, s2_fire_to_s3) 1128 val s3_req_cmd_dup_for_data_w_bank = RegEnable(s2_req.cmd, s2_fire_to_s3) 1129 val s3_req_replace_dup_for_data_w_bank = RegEnable(s2_req.replace, s2_fire_to_s3) 1130 val s3_hit_coh_dup_for_data_w_bank = RegEnable(s2_hit_coh, s2_fire_to_s3) 1131 val s3_new_hit_coh_dup_for_data_w_bank = RegEnable(s2_new_hit_coh, s2_fire_to_s3) 1132 1133 val miss_update_meta_dup_for_data_w_bank = s3_req_miss_dup_for_data_w_bank 1134 val probe_update_meta_dup_for_data_w_bank = s3_req_probe_dup_for_data_w_bank && s3_tag_match_dup_for_data_w_bank && s3_coh_dup_for_data_w_bank =/= probe_new_coh_dup_for_data_w_bank 1135 val store_update_meta_dup_for_data_w_bank = s3_req_source_dup_for_data_w_bank === STORE_SOURCE.U && 1136 !s3_req_probe_dup_for_data_w_bank && 1137 s3_hit_coh_dup_for_data_w_bank =/= s3_new_hit_coh_dup_for_data_w_bank 1138 val amo_update_meta_dup_for_data_w_bank = s3_req_source_dup_for_data_w_bank === AMO_SOURCE.U && 1139 !s3_req_probe_dup_for_data_w_bank && 1140 s3_hit_coh_dup_for_data_w_bank =/= s3_new_hit_coh_dup_for_data_w_bank 1141 val update_meta_dup_for_data_w_bank = ( 1142 miss_update_meta_dup_for_data_w_bank || 1143 probe_update_meta_dup_for_data_w_bank || 1144 store_update_meta_dup_for_data_w_bank || 1145 amo_update_meta_dup_for_data_w_bank 1146 ) && !s3_req_replace_dup_for_data_w_bank 1147 1148 val s3_amo_hit_dup_for_data_w_bank = RegEnable(s2_amo_hit, s2_fire_to_s3) 1149 val s3_s_amoalu_dup_for_data_w_bank = RegInit(false.B) 1150 val amo_wait_amoalu_dup_for_data_w_bank = s3_req_source_dup_for_data_w_bank === AMO_SOURCE.U && 1151 s3_req_cmd_dup_for_data_w_bank =/= M_XLR && 1152 s3_req_cmd_dup_for_data_w_bank =/= M_XSC 1153 val do_amoalu_dup_for_data_w_bank = amo_wait_amoalu_dup_for_data_w_bank && s3_valid_dup_for_data_w_bank(i) && !s3_s_amoalu_dup_for_data_w_bank 1154 1155 val s3_store_hit_dup_for_data_w_bank = RegEnable(s2_store_hit, s2_fire_to_s3) 1156 val s3_req_addr_dup_for_data_w_bank = RegEnable(s2_req.addr, s2_fire_to_s3) 1157 val s3_can_do_amo_dup_for_data_w_bank = (s3_req_miss_dup_for_data_w_bank && !s3_req_probe_dup_for_data_w_bank && s3_req_source_dup_for_data_w_bank === AMO_SOURCE.U) || 1158 s3_amo_hit_dup_for_data_w_bank 1159 1160 val s3_lr_dup_for_data_w_bank = !s3_req_probe_dup_for_data_w_bank && s3_req_source_dup_for_data_w_bank === AMO_SOURCE.U && s3_req_cmd_dup_for_data_w_bank === M_XLR 1161 val s3_sc_dup_for_data_w_bank = !s3_req_probe_dup_for_data_w_bank && s3_req_source_dup_for_data_w_bank === AMO_SOURCE.U && s3_req_cmd_dup_for_data_w_bank === M_XSC 1162 val lrsc_addr_dup_for_data_w_bank = Reg(UInt()) 1163 val lrsc_count_dup_for_data_w_bank = RegInit(0.U(log2Ceil(LRSCCycles).W)) 1164 1165 when (s3_valid_dup_for_data_w_bank(i) && (s3_lr_dup_for_data_w_bank || s3_sc_dup_for_data_w_bank)) { 1166 when (s3_can_do_amo_dup_for_data_w_bank && s3_lr_dup_for_data_w_bank) { 1167 lrsc_count_dup_for_data_w_bank := (LRSCCycles - 1).U 1168 lrsc_addr_dup_for_data_w_bank := get_block_addr(s3_req_addr_dup_for_data_w_bank) 1169 }.otherwise { 1170 lrsc_count_dup_for_data_w_bank := 0.U 1171 } 1172 }.elsewhen (io.invalid_resv_set) { 1173 lrsc_count_dup_for_data_w_bank := 0.U 1174 }.elsewhen (lrsc_count_dup_for_data_w_bank > 0.U) { 1175 lrsc_count_dup_for_data_w_bank := lrsc_count_dup_for_data_w_bank - 1.U 1176 } 1177 1178 val lrsc_valid_dup_for_data_w_bank = lrsc_count_dup_for_data_w_bank > LRSCBackOff.U 1179 val s3_lrsc_addr_match_dup_for_data_w_bank = lrsc_valid_dup_for_data_w_bank && lrsc_addr_dup_for_data_w_bank === get_block_addr(s3_req_addr_dup_for_data_w_bank) 1180 val s3_sc_fail_dup_for_data_w_bank = s3_sc_dup_for_data_w_bank && !s3_lrsc_addr_match_dup_for_data_w_bank 1181 val s3_can_do_amo_write_dup_for_data_w_bank = s3_can_do_amo_dup_for_data_w_bank && isWrite(s3_req_cmd_dup_for_data_w_bank) && !s3_sc_fail_dup_for_data_w_bank 1182 val update_data_dup_for_data_w_bank = s3_req_miss_dup_for_data_w_bank || s3_store_hit_dup_for_data_w_bank || s3_can_do_amo_write_dup_for_data_w_bank 1183 1184 val s3_probe_can_go_dup_for_data_w_bank = s3_req_probe_dup_for_data_w_bank && 1185 wb_ready_dup_for_data_w_bank(i) && 1186 (io.meta_write.ready || !probe_update_meta_dup_for_data_w_bank) 1187 val s3_store_can_go_dup_for_data_w_bank = s3_req_source_dup_for_data_w_bank === STORE_SOURCE.U && !s3_req_probe_dup_for_data_w_bank && 1188 (io.meta_write.ready || !store_update_meta_dup_for_data_w_bank) && 1189 (data_write_ready_dup_for_data_w_bank(i) || !update_data_dup_for_data_w_bank) 1190 val s3_amo_can_go_dup_for_data_w_bank = s3_amo_hit_dup_for_data_w_bank && 1191 (io.meta_write.ready || !amo_update_meta_dup_for_data_w_bank) && 1192 (data_write_ready_dup_for_data_w_bank(i) || !update_data_dup_for_data_w_bank) && 1193 (s3_s_amoalu_dup_for_data_w_bank || !amo_wait_amoalu_dup_for_data_w_bank) 1194 val s3_miss_can_go_dup_for_data_w_bank = s3_req_miss_dup_for_data_w_bank && 1195 (io.meta_write.ready || !amo_update_meta_dup_for_data_w_bank) && 1196 (data_write_ready_dup_for_data_w_bank(i) || !update_data_dup_for_data_w_bank) && 1197 (s3_s_amoalu_dup_for_data_w_bank || !amo_wait_amoalu_dup_for_data_w_bank) && 1198 tag_write_ready_dup_for_data_w_bank(i) && 1199 wb_ready_dup_for_data_w_bank(i) 1200 val s3_replace_can_go_dup_for_data_w_bank = s3_req_replace_dup_for_data_w_bank && 1201 (s3_coh_dup_for_data_w_bank.state === ClientStates.Nothing || wb_ready_dup_for_data_w_bank(i)) 1202 val s3_can_go_dup_for_data_w_bank = s3_probe_can_go_dup_for_data_w_bank || 1203 s3_store_can_go_dup_for_data_w_bank || 1204 s3_amo_can_go_dup_for_data_w_bank || 1205 s3_miss_can_go_dup_for_data_w_bank || 1206 s3_replace_can_go_dup_for_data_w_bank 1207 val s3_update_data_cango_dup_for_data_w_bank = s3_store_can_go_dup_for_data_w_bank || s3_amo_can_go_dup_for_data_w_bank || s3_miss_can_go_dup_for_data_w_bank 1208 1209 val s3_fire_dup_for_data_w_bank = s3_valid_dup_for_data_w_bank(i) && s3_can_go_dup_for_data_w_bank 1210 1211 when (do_amoalu_dup_for_data_w_bank) { s3_s_amoalu_dup_for_data_w_bank := true.B } 1212 when (s3_fire_dup_for_data_w_bank) { s3_s_amoalu_dup_for_data_w_bank := false.B } 1213 1214 when (s2_fire_to_s3) { s3_valid_dup_for_data_w_bank(i) := true.B } 1215 .elsewhen (s3_fire_dup_for_data_w_bank) { s3_valid_dup_for_data_w_bank(i) := false.B } 1216 1217 io.data_write_dup(i).valid := s3_valid_dup_for_data_w_bank(i) && s3_update_data_cango_dup_for_data_w_bank && update_data_dup_for_data_w_bank 1218 io.data_write_dup(i).bits.way_en := RegEnable(s2_way_en, s2_fire_to_s3) 1219 io.data_write_dup(i).bits.addr := RegEnable(s2_req.vaddr, s2_fire_to_s3) 1220 } 1221 // ------------------------------------------------------------------------------------- 1222 1223 // ---------------- duplicate regs for wb.valid to solve fanout ---------------- 1224 val s3_req_miss_dup_for_wb_valid = RegEnable(s2_req.miss, s2_fire_to_s3) 1225 val s3_req_probe_dup_for_wb_valid = RegEnable(s2_req.probe, s2_fire_to_s3) 1226 val s3_tag_match_dup_for_wb_valid = RegEnable(s2_tag_match, s2_fire_to_s3) 1227 val s3_coh_dup_for_wb_valid = RegEnable(s2_coh, s2_fire_to_s3) 1228 val s3_req_probe_param_dup_for_wb_valid = RegEnable(s2_req.probe_param, s2_fire_to_s3) 1229 val (_, _, probe_new_coh_dup_for_wb_valid) = s3_coh_dup_for_wb_valid.onProbe(s3_req_probe_param_dup_for_wb_valid) 1230 val s3_req_source_dup_for_wb_valid = RegEnable(s2_req.source, s2_fire_to_s3) 1231 val s3_req_cmd_dup_for_wb_valid = RegEnable(s2_req.cmd, s2_fire_to_s3) 1232 val s3_req_replace_dup_for_wb_valid = RegEnable(s2_req.replace, s2_fire_to_s3) 1233 val s3_hit_coh_dup_for_wb_valid = RegEnable(s2_hit_coh, s2_fire_to_s3) 1234 val s3_new_hit_coh_dup_for_wb_valid = RegEnable(s2_new_hit_coh, s2_fire_to_s3) 1235 1236 val miss_update_meta_dup_for_wb_valid = s3_req_miss_dup_for_wb_valid 1237 val probe_update_meta_dup_for_wb_valid = s3_req_probe_dup_for_wb_valid && s3_tag_match_dup_for_wb_valid && s3_coh_dup_for_wb_valid =/= probe_new_coh_dup_for_wb_valid 1238 val store_update_meta_dup_for_wb_valid = s3_req_source_dup_for_wb_valid === STORE_SOURCE.U && 1239 !s3_req_probe_dup_for_wb_valid && 1240 s3_hit_coh_dup_for_wb_valid =/= s3_new_hit_coh_dup_for_wb_valid 1241 val amo_update_meta_dup_for_wb_valid = s3_req_source_dup_for_wb_valid === AMO_SOURCE.U && 1242 !s3_req_probe_dup_for_wb_valid && 1243 s3_hit_coh_dup_for_wb_valid =/= s3_new_hit_coh_dup_for_wb_valid 1244 val update_meta_dup_for_wb_valid = ( 1245 miss_update_meta_dup_for_wb_valid || 1246 probe_update_meta_dup_for_wb_valid || 1247 store_update_meta_dup_for_wb_valid || 1248 amo_update_meta_dup_for_wb_valid 1249 ) && !s3_req_replace_dup_for_wb_valid 1250 1251 val s3_valid_dup_for_wb_valid = RegInit(false.B) 1252 val s3_amo_hit_dup_for_wb_valid = RegEnable(s2_amo_hit, s2_fire_to_s3) 1253 val s3_s_amoalu_dup_for_wb_valid = RegInit(false.B) 1254 val amo_wait_amoalu_dup_for_wb_valid = s3_req_source_dup_for_wb_valid === AMO_SOURCE.U && 1255 s3_req_cmd_dup_for_wb_valid =/= M_XLR && 1256 s3_req_cmd_dup_for_wb_valid =/= M_XSC 1257 val do_amoalu_dup_for_wb_valid = amo_wait_amoalu_dup_for_wb_valid && s3_valid_dup_for_wb_valid && !s3_s_amoalu_dup_for_wb_valid 1258 1259 val s3_store_hit_dup_for_wb_valid = RegEnable(s2_store_hit, s2_fire_to_s3) 1260 val s3_req_addr_dup_for_wb_valid = RegEnable(s2_req.addr, s2_fire_to_s3) 1261 val s3_can_do_amo_dup_for_wb_valid = (s3_req_miss_dup_for_wb_valid && !s3_req_probe_dup_for_wb_valid && s3_req_source_dup_for_wb_valid === AMO_SOURCE.U) || 1262 s3_amo_hit_dup_for_wb_valid 1263 1264 val s3_lr_dup_for_wb_valid = !s3_req_probe_dup_for_wb_valid && s3_req_source_dup_for_wb_valid === AMO_SOURCE.U && s3_req_cmd_dup_for_wb_valid === M_XLR 1265 val s3_sc_dup_for_wb_valid = !s3_req_probe_dup_for_wb_valid && s3_req_source_dup_for_wb_valid === AMO_SOURCE.U && s3_req_cmd_dup_for_wb_valid === M_XSC 1266 val lrsc_addr_dup_for_wb_valid = Reg(UInt()) 1267 val lrsc_count_dup_for_wb_valid = RegInit(0.U(log2Ceil(LRSCCycles).W)) 1268 1269 when (s3_valid_dup_for_wb_valid && (s3_lr_dup_for_wb_valid || s3_sc_dup_for_wb_valid)) { 1270 when (s3_can_do_amo_dup_for_wb_valid && s3_lr_dup_for_wb_valid) { 1271 lrsc_count_dup_for_wb_valid := (LRSCCycles - 1).U 1272 lrsc_addr_dup_for_wb_valid := get_block_addr(s3_req_addr_dup_for_wb_valid) 1273 }.otherwise { 1274 lrsc_count_dup_for_wb_valid := 0.U 1275 } 1276 }.elsewhen (io.invalid_resv_set) { 1277 lrsc_count_dup_for_wb_valid := 0.U 1278 }.elsewhen (lrsc_count_dup_for_wb_valid > 0.U) { 1279 lrsc_count_dup_for_wb_valid := lrsc_count_dup_for_wb_valid - 1.U 1280 } 1281 1282 val lrsc_valid_dup_for_wb_valid = lrsc_count_dup_for_wb_valid > LRSCBackOff.U 1283 val s3_lrsc_addr_match_dup_for_wb_valid = lrsc_valid_dup_for_wb_valid && lrsc_addr_dup_for_wb_valid === get_block_addr(s3_req_addr_dup_for_wb_valid) 1284 val s3_sc_fail_dup_for_wb_valid = s3_sc_dup_for_wb_valid && !s3_lrsc_addr_match_dup_for_wb_valid 1285 val s3_can_do_amo_write_dup_for_wb_valid = s3_can_do_amo_dup_for_wb_valid && isWrite(s3_req_cmd_dup_for_wb_valid) && !s3_sc_fail_dup_for_wb_valid 1286 val update_data_dup_for_wb_valid = s3_req_miss_dup_for_wb_valid || s3_store_hit_dup_for_wb_valid || s3_can_do_amo_write_dup_for_wb_valid 1287 1288 val s3_probe_can_go_dup_for_wb_valid = s3_req_probe_dup_for_wb_valid && 1289 io.wb_ready_dup(wbPort) && 1290 (io.meta_write.ready || !probe_update_meta_dup_for_wb_valid) 1291 val s3_store_can_go_dup_for_wb_valid = s3_req_source_dup_for_wb_valid === STORE_SOURCE.U && !s3_req_probe_dup_for_wb_valid && 1292 (io.meta_write.ready || !store_update_meta_dup_for_wb_valid) && 1293 (io.data_write_ready_dup(wbPort) || !update_data_dup_for_wb_valid) 1294 val s3_amo_can_go_dup_for_wb_valid = s3_amo_hit_dup_for_wb_valid && 1295 (io.meta_write.ready || !amo_update_meta_dup_for_wb_valid) && 1296 (io.data_write_ready_dup(wbPort) || !update_data_dup_for_wb_valid) && 1297 (s3_s_amoalu_dup_for_wb_valid || !amo_wait_amoalu_dup_for_wb_valid) 1298 val s3_miss_can_go_dup_for_wb_valid = s3_req_miss_dup_for_wb_valid && 1299 (io.meta_write.ready || !amo_update_meta_dup_for_wb_valid) && 1300 (io.data_write_ready_dup(wbPort) || !update_data_dup_for_wb_valid) && 1301 (s3_s_amoalu_dup_for_wb_valid || !amo_wait_amoalu_dup_for_wb_valid) && 1302 io.tag_write_ready_dup(wbPort) && 1303 io.wb_ready_dup(wbPort) 1304 val s3_replace_can_go_dup_for_wb_valid = s3_req_replace_dup_for_wb_valid && 1305 (s3_coh_dup_for_wb_valid.state === ClientStates.Nothing || io.wb_ready_dup(wbPort)) 1306 val s3_can_go_dup_for_wb_valid = s3_probe_can_go_dup_for_wb_valid || 1307 s3_store_can_go_dup_for_wb_valid || 1308 s3_amo_can_go_dup_for_wb_valid || 1309 s3_miss_can_go_dup_for_wb_valid || 1310 s3_replace_can_go_dup_for_wb_valid 1311 val s3_update_data_cango_dup_for_wb_valid = s3_store_can_go_dup_for_wb_valid || s3_amo_can_go_dup_for_wb_valid || s3_miss_can_go_dup_for_wb_valid 1312 1313 val s3_fire_dup_for_wb_valid = s3_valid_dup_for_wb_valid && s3_can_go_dup_for_wb_valid 1314 when (do_amoalu_dup_for_wb_valid) { s3_s_amoalu_dup_for_wb_valid := true.B } 1315 when (s3_fire_dup_for_wb_valid) { s3_s_amoalu_dup_for_wb_valid := false.B } 1316 1317 val s3_banked_store_wmask_dup_for_wb_valid = RegEnable(s2_banked_store_wmask, s2_fire_to_s3) 1318 val s3_req_word_idx_dup_for_wb_valid = RegEnable(s2_req.word_idx, s2_fire_to_s3) 1319 val s3_replace_nothing_dup_for_wb_valid = s3_req_replace_dup_for_wb_valid && s3_coh_dup_for_wb_valid.state === ClientStates.Nothing 1320 1321 val s3_sc_data_merged_dup_for_wb_valid = Wire(Vec(DCacheBanks, UInt(DCacheSRAMRowBits.W))) 1322 val s3_req_amo_data_dup_for_wb_valid = RegEnable(s2_req.amo_data, s2_fire_to_s3) 1323 val s3_req_amo_mask_dup_for_wb_valid = RegEnable(s2_req.amo_mask, s2_fire_to_s3) 1324 for (i <- 0 until DCacheBanks) { 1325 val old_data = s3_store_data_merged(i) 1326 s3_sc_data_merged_dup_for_wb_valid(i) := mergePutData(old_data, s3_req_amo_data_dup_for_wb_valid, 1327 Mux( 1328 s3_req_word_idx_dup_for_wb_valid === i.U && !s3_sc_fail_dup_for_wb_valid, 1329 s3_req_amo_mask_dup_for_wb_valid, 1330 0.U(wordBytes.W) 1331 ) 1332 ) 1333 } 1334 1335 val s3_need_replacement_dup_for_wb_valid = RegEnable(s2_need_replacement, s2_fire_to_s3) 1336 val miss_wb_dup_for_wb_valid = s3_req_miss_dup_for_wb_valid && s3_need_replacement_dup_for_wb_valid && 1337 s3_coh_dup_for_wb_valid.state =/= ClientStates.Nothing 1338 val need_wb_dup_for_wb_valid = miss_wb_dup_for_wb_valid || s3_req_probe_dup_for_wb_valid || s3_req_replace_dup_for_wb_valid 1339 1340 val s3_tag_dup_for_wb_valid = RegEnable(s2_tag, s2_fire_to_s3) 1341 1342 val (_, probe_shrink_param_dup_for_wb_valid, _) = s3_coh_dup_for_wb_valid.onProbe(s3_req_probe_param_dup_for_wb_valid) 1343 val (_, miss_shrink_param_dup_for_wb_valid, _) = s3_coh_dup_for_wb_valid.onCacheControl(M_FLUSH) 1344 val writeback_param_dup_for_wb_valid = Mux( 1345 s3_req_probe_dup_for_wb_valid, 1346 probe_shrink_param_dup_for_wb_valid, 1347 miss_shrink_param_dup_for_wb_valid 1348 ) 1349 val writeback_data_dup_for_wb_valid = if (dcacheParameters.alwaysReleaseData) { 1350 s3_tag_match_dup_for_wb_valid && s3_req_probe_dup_for_wb_valid && RegEnable(s2_req.probe_need_data, s2_fire_to_s3) || 1351 s3_coh_dup_for_wb_valid === ClientStates.Dirty || (miss_wb_dup_for_wb_valid || s3_req_replace_dup_for_wb_valid) && s3_coh_dup_for_wb_valid.state =/= ClientStates.Nothing 1352 } else { 1353 s3_tag_match_dup_for_wb_valid && s3_req_probe_dup_for_wb_valid && RegEnable(s2_req.probe_need_data, s2_fire_to_s3) || s3_coh_dup_for_wb_valid === ClientStates.Dirty 1354 } 1355 1356 when (s2_fire_to_s3) { s3_valid_dup_for_wb_valid := true.B } 1357 .elsewhen (s3_fire_dup_for_wb_valid) { s3_valid_dup_for_wb_valid := false.B } 1358 1359 // ------------------------------------------------------------------------------------- 1360 1361 val s3_fire = s3_valid_dup(4) && s3_can_go 1362 when (s2_fire_to_s3) { 1363 s3_valid := true.B 1364 s3_valid_dup.foreach(_ := true.B) 1365 s3_valid_dup_for_status.foreach(_ := true.B) 1366 }.elsewhen (s3_fire) { 1367 s3_valid := false.B 1368 s3_valid_dup.foreach(_ := false.B) 1369 s3_valid_dup_for_status.foreach(_ := false.B) 1370 } 1371 s3_ready := !s3_valid_dup(5) || s3_can_go 1372 s3_s0_set_conflict := s3_valid_dup(6) && s3_idx_dup(0) === s0_idx 1373 s3_s0_set_conflict_store := s3_valid_dup(7) && s3_idx_dup(1) === store_idx 1374 assert(RegNext(!s3_valid || !(s3_req_source_dup_2 === STORE_SOURCE.U && !s3_req.probe) || s3_hit)) // miss store should never come to s3 1375 1376 when(s3_fire) { 1377 s3_s_amoalu := false.B 1378 s3_s_amoalu_dup.foreach(_ := false.B) 1379 } 1380 1381 req.ready := s0_can_go 1382 1383 io.meta_read.valid := req.valid && s1_ready && !set_conflict 1384 io.meta_read.bits.idx := get_idx(s0_req.vaddr) 1385 io.meta_read.bits.way_en := Mux(s0_req.replace, s0_req.replace_way_en, ~0.U(nWays.W)) 1386 1387 io.tag_read.valid := req.valid && s1_ready && !set_conflict && !s0_req.replace 1388 io.tag_read.bits.idx := get_idx(s0_req.vaddr) 1389 io.tag_read.bits.way_en := ~0.U(nWays.W) 1390 1391 io.data_read_intend := s1_valid_dup(3) && s1_need_data 1392 io.data_read.valid := s1_valid_dup(4) && s1_need_data 1393 io.data_read.bits.rmask := s1_banked_rmask 1394 io.data_read.bits.way_en := s1_way_en 1395 io.data_read.bits.addr := s1_req_vaddr_dup_for_data_read 1396 1397 io.miss_req.valid := s2_valid_dup(4) && s2_can_go_to_mq_dup(0) 1398 val miss_req = io.miss_req.bits 1399 miss_req := DontCare 1400 miss_req.source := s2_req.source 1401 miss_req.cmd := s2_req.cmd 1402 miss_req.addr := s2_req.addr 1403 miss_req.vaddr := s2_req_vaddr_dup_for_miss_req 1404 miss_req.way_en := Mux(s2_tag_match, s2_tag_match_way, s2_repl_way_en) 1405 miss_req.store_data := s2_req.store_data 1406 miss_req.store_mask := s2_req.store_mask 1407 miss_req.word_idx := s2_req.word_idx 1408 miss_req.amo_data := s2_req.amo_data 1409 miss_req.amo_mask := s2_req.amo_mask 1410 miss_req.req_coh := s2_hit_coh 1411 miss_req.replace_coh := s2_repl_coh 1412 miss_req.replace_tag := s2_repl_tag 1413 miss_req.id := s2_req.id 1414 miss_req.cancel := false.B 1415 1416 io.store_replay_resp.valid := s2_valid_dup(5) && s2_can_go_to_mq_dup(1) && replay && s2_req.isStore 1417 io.store_replay_resp.bits.data := DontCare 1418 io.store_replay_resp.bits.miss := true.B 1419 io.store_replay_resp.bits.replay := true.B 1420 io.store_replay_resp.bits.id := s2_req.id 1421 1422 io.store_hit_resp.valid := s3_valid_dup(8) && s3_store_can_go 1423 io.store_hit_resp.bits.data := DontCare 1424 io.store_hit_resp.bits.miss := false.B 1425 io.store_hit_resp.bits.replay := false.B 1426 io.store_hit_resp.bits.id := s3_req.id 1427 1428 io.release_update.valid := s3_valid_dup(9) && (s3_store_can_go || s3_amo_can_go) && s3_hit && update_data 1429 io.release_update.bits.addr := s3_req_addr_dup(3) 1430 io.release_update.bits.mask := Mux(s3_store_hit_dup(1), s3_banked_store_wmask, banked_amo_wmask) 1431 io.release_update.bits.data := Mux( 1432 amo_wait_amoalu, 1433 s3_amo_data_merged_reg, 1434 Mux( 1435 s3_sc, 1436 s3_sc_data_merged, 1437 s3_store_data_merged 1438 ) 1439 ).asUInt 1440 1441 val atomic_hit_resp = Wire(new AtomicsResp) 1442 atomic_hit_resp.data := Mux(s3_sc, s3_sc_resp, s3_data_word) 1443 atomic_hit_resp.miss := false.B 1444 atomic_hit_resp.miss_id := s3_req.miss_id 1445 atomic_hit_resp.error := s3_error 1446 atomic_hit_resp.replay := false.B 1447 atomic_hit_resp.ack_miss_queue := s3_req_miss_dup(5) 1448 atomic_hit_resp.id := lrsc_valid_dup(2) 1449 val atomic_replay_resp = Wire(new AtomicsResp) 1450 atomic_replay_resp.data := DontCare 1451 atomic_replay_resp.miss := true.B 1452 atomic_replay_resp.miss_id := DontCare 1453 atomic_replay_resp.error := false.B 1454 atomic_replay_resp.replay := true.B 1455 atomic_replay_resp.ack_miss_queue := false.B 1456 atomic_replay_resp.id := DontCare 1457 val atomic_replay_resp_valid = s2_valid_dup(6) && s2_can_go_to_mq_dup(2) && replay && s2_req.isAMO 1458 val atomic_hit_resp_valid = s3_valid_dup(10) && (s3_amo_can_go || s3_miss_can_go && s3_req.isAMO) 1459 io.atomic_resp.valid := atomic_replay_resp_valid || atomic_hit_resp_valid 1460 io.atomic_resp.bits := Mux(atomic_replay_resp_valid, atomic_replay_resp, atomic_hit_resp) 1461 1462 io.replace_resp.valid := s3_fire && s3_req_replace_dup(3) 1463 io.replace_resp.bits := s3_req.miss_id 1464 1465 io.meta_write.valid := s3_fire_dup_for_meta_w_valid && update_meta_dup_for_meta_w_valid 1466 io.meta_write.bits.idx := s3_idx_dup(2) 1467 io.meta_write.bits.way_en := s3_way_en_dup(0) 1468 io.meta_write.bits.meta.coh := new_coh 1469 1470 io.error_flag_write.valid := s3_fire_dup_for_err_w_valid && update_meta_dup_for_err_w_valid && s3_l2_error 1471 io.error_flag_write.bits.idx := s3_idx_dup(3) 1472 io.error_flag_write.bits.way_en := s3_way_en_dup(1) 1473 io.error_flag_write.bits.error := s3_l2_error 1474 1475 io.tag_write.valid := s3_fire_dup_for_tag_w_valid && s3_req_miss_dup_for_tag_w_valid 1476 io.tag_write.bits.idx := s3_idx_dup(4) 1477 io.tag_write.bits.way_en := s3_way_en_dup(2) 1478 io.tag_write.bits.tag := get_tag(s3_req_addr_dup(4)) 1479 1480 io.tag_write_intend := s3_req_miss_dup(7) && s3_valid_dup(11) 1481 XSPerfAccumulate("fake_tag_write_intend", io.tag_write_intend && !io.tag_write.valid) 1482 XSPerfAccumulate("mainpipe_tag_write", io.tag_write.valid) 1483 1484 assert(!RegNext(io.tag_write.valid && !io.tag_write_intend)) 1485 1486 io.data_write.valid := s3_valid_dup_for_data_w_valid && s3_update_data_cango_dup_for_data_w_valid && update_data_dup_for_data_w_valid 1487 io.data_write.bits.way_en := s3_way_en_dup(3) 1488 io.data_write.bits.addr := s3_req_vaddr_dup_for_data_write 1489 io.data_write.bits.wmask := banked_wmask 1490 io.data_write.bits.data := Mux( 1491 amo_wait_amoalu_dup_for_data_w_valid, 1492 s3_amo_data_merged_reg, 1493 Mux( 1494 s3_sc_dup_for_data_w_valid, 1495 s3_sc_data_merged_dup_for_data_w_valid, 1496 s3_store_data_merged 1497 ) 1498 ) 1499 assert(RegNext(!io.meta_write.valid || !s3_req.replace)) 1500 assert(RegNext(!io.tag_write.valid || !s3_req.replace)) 1501 assert(RegNext(!io.data_write.valid || !s3_req.replace)) 1502 1503 io.wb.valid := s3_valid_dup_for_wb_valid && ( 1504 // replace 1505 s3_req_replace_dup_for_wb_valid && !s3_replace_nothing_dup_for_wb_valid || 1506 // probe can go to wbq 1507 s3_req_probe_dup_for_wb_valid && (io.meta_write.ready || !probe_update_meta_dup_for_wb_valid) || 1508 // amo miss can go to wbq 1509 s3_req_miss_dup_for_wb_valid && 1510 (io.meta_write.ready || !amo_update_meta_dup_for_wb_valid) && 1511 (io.data_write_ready_dup(wbPort) || !update_data_dup_for_wb_valid) && 1512 (s3_s_amoalu_dup_for_wb_valid || !amo_wait_amoalu_dup_for_wb_valid) && 1513 io.tag_write_ready_dup(wbPort) 1514 ) && need_wb_dup_for_wb_valid 1515 1516 io.wb.bits.addr := get_block_addr(Cat(s3_tag_dup_for_wb_valid, get_untag(s3_req.vaddr))) 1517 io.wb.bits.param := writeback_param_dup_for_wb_valid 1518 io.wb.bits.voluntary := s3_req_miss_dup_for_wb_valid || s3_req_replace_dup_for_wb_valid 1519 io.wb.bits.hasData := writeback_data_dup_for_wb_valid 1520 io.wb.bits.dirty := s3_coh_dup_for_wb_valid === ClientStates.Dirty 1521 io.wb.bits.data := s3_data.asUInt() 1522 io.wb.bits.delay_release := s3_req_replace_dup_for_wb_valid 1523 io.wb.bits.miss_id := s3_req.miss_id 1524 1525 io.replace_access.valid := RegNext(s1_fire && (s1_req.isAMO || s1_req.isStore) && !s1_req.probe) 1526 io.replace_access.bits.set := s2_idx_dup_for_replace_access 1527 io.replace_access.bits.way := RegNext(OHToUInt(s1_way_en)) 1528 1529 io.replace_way.set.valid := RegNext(s0_fire) 1530 io.replace_way.set.bits := s1_idx_dup_for_replace_way 1531 1532 // TODO: consider block policy of a finer granularity 1533 io.status.s0_set.valid := req.valid 1534 io.status.s0_set.bits := get_idx(s0_req.vaddr) 1535 io.status.s1.valid := s1_valid_dup(5) 1536 io.status.s1.bits.set := s1_idx 1537 io.status.s1.bits.way_en := s1_way_en 1538 io.status.s2.valid := s2_valid_dup(7) && !s2_req_replace_dup_2 1539 io.status.s2.bits.set := s2_idx_dup_for_status 1540 io.status.s2.bits.way_en := s2_way_en 1541 io.status.s3.valid := s3_valid && !s3_req_replace_dup(7) 1542 io.status.s3.bits.set := s3_idx_dup(5) 1543 io.status.s3.bits.way_en := s3_way_en 1544 1545 for ((s, i) <- io.status_dup.zipWithIndex) { 1546 s.s1.valid := s1_valid_dup_for_status(i) 1547 s.s1.bits.set := RegEnable(get_idx(s0_req.vaddr), s0_fire) 1548 s.s1.bits.way_en := s1_way_en 1549 s.s2.valid := s2_valid_dup_for_status(i) && !RegEnable(s1_req.replace, s1_fire) 1550 s.s2.bits.set := RegEnable(get_idx(s1_req.vaddr), s1_fire) 1551 s.s2.bits.way_en := RegEnable(s1_way_en, s1_fire) 1552 s.s3.valid := s3_valid_dup_for_status(i) && !RegEnable(s2_req.replace, s2_fire_to_s3) 1553 s.s3.bits.set := RegEnable(get_idx(s2_req.vaddr), s2_fire_to_s3) 1554 s.s3.bits.way_en := RegEnable(s2_way_en, s2_fire_to_s3) 1555 } 1556 dontTouch(io.status_dup) 1557 1558 // report error to beu and csr, 1 cycle after read data resp 1559 io.error := 0.U.asTypeOf(new L1CacheErrorInfo()) 1560 // report error, update error csr 1561 io.error.valid := s3_error && RegNext(s2_fire) 1562 // only tag_error and data_error will be reported to beu 1563 // l2_error should not be reported (l2 will report that) 1564 io.error.report_to_beu := (RegEnable(s2_tag_error, s2_fire) || s3_data_error) && RegNext(s2_fire) 1565 io.error.paddr := RegEnable(s2_req.addr, s2_fire) 1566 io.error.source.tag := RegEnable(s2_tag_error, s2_fire) 1567 io.error.source.data := s3_data_error 1568 io.error.source.l2 := RegEnable(s2_flag_error || s2_l2_error, s2_fire) 1569 io.error.opType.store := RegEnable(s2_req.isStore && !s2_req.probe, s2_fire) 1570 io.error.opType.probe := RegEnable(s2_req.probe, s2_fire) 1571 io.error.opType.release := RegEnable(s2_req.replace, s2_fire) 1572 io.error.opType.atom := RegEnable(s2_req.isAMO && !s2_req.probe, s2_fire) 1573 1574 val perfEvents = Seq( 1575 ("dcache_mp_req ", s0_fire ), 1576 ("dcache_mp_total_penalty", PopCount(VecInit(Seq(s0_fire, s1_valid, s2_valid, s3_valid)))) 1577 ) 1578 generatePerfEvent() 1579} 1580