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