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