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