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