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