From f93a7c5f446a5a6cc942d961cb5c3e0e31bf5ef8 Mon Sep 17 00:00:00 2001 From: Anzooooo Date: Tue, 21 Jan 2025 12:46:28 +0800 Subject: [PATCH] fix(MainPipe): `Dcache` status is not changed by the `sc/cas` that fails --- .../cache/dcache/mainpipe/MainPipe.scala | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/main/scala/xiangshan/cache/dcache/mainpipe/MainPipe.scala b/src/main/scala/xiangshan/cache/dcache/mainpipe/MainPipe.scala index d42ce2d39bb..336f57a430d 100644 --- a/src/main/scala/xiangshan/cache/dcache/mainpipe/MainPipe.scala +++ b/src/main/scala/xiangshan/cache/dcache/mainpipe/MainPipe.scala @@ -379,7 +379,7 @@ class MainPipe(implicit p: Parameters) extends DCacheModule with HasPerfEvents w val s1_has_permission = s1_hit_coh.onAccess(s1_req.cmd)._1 val s1_hit = s1_tag_match && s1_has_permission - val s1_pregen_can_go_to_mq = !s1_req.replace && !s1_req.probe && !s1_req.miss && (s1_req.isStore || s1_req.isAMO) && !s1_hit + val s1_pregen_can_go_to_mq = !s1_req.replace && !s1_req.probe && !s1_req.miss && (s1_req.isStore || s1_req.isAMO && s1_req.cmd =/= M_XSC) && !s1_hit // s2: select data, return resp if this is a store miss val s2_valid = RegInit(false.B) @@ -412,6 +412,7 @@ class MainPipe(implicit p: Parameters) extends DCacheModule with HasPerfEvents w val s2_may_report_data_error = s2_need_data && s2_coh.state =/= ClientStates.Nothing val s2_hit = s2_tag_match && s2_has_permission + val s2_sc = s2_req.cmd === M_XSC val s2_amo_hit = s2_hit && !s2_req.probe && !s2_req.miss && s2_req.isAMO val s2_store_hit = s2_hit && !s2_req.probe && !s2_req.miss && s2_req.isStore @@ -426,7 +427,7 @@ class MainPipe(implicit p: Parameters) extends DCacheModule with HasPerfEvents w val s2_req_miss_without_data = Mux(s2_valid, s2_req.miss && !io.refill_info.valid, false.B) 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 val s2_can_go_to_mq = RegEnable(s1_pregen_can_go_to_mq, s1_fire) - val s2_can_go_to_s3 = (s2_req.replace || s2_req.probe || (s2_req.miss && io.refill_info.valid && !io.replace_block) || (s2_req.isStore || s2_req.isAMO) && s2_hit) && s3_ready + val s2_can_go_to_s3 = (s2_sc || s2_req.replace || s2_req.probe || (s2_req.miss && io.refill_info.valid && !io.replace_block) || (s2_req.isStore || s2_req.isAMO) && s2_hit) && s3_ready assert(RegNext(!(s2_valid && s2_can_go_to_s3 && s2_can_go_to_mq && s2_can_go_to_mq_replay))) val s2_can_go = s2_can_go_to_s3 || s2_can_go_to_mq || s2_can_go_to_mq_replay val s2_fire = s2_valid && s2_can_go @@ -500,6 +501,8 @@ class MainPipe(implicit p: Parameters) extends DCacheModule with HasPerfEvents w io.readline_error_delayed && RegNext(s2_may_report_data_error), RegNext(s3_data_error) // do not update s3_data_error if !s1_fire ) + val s3_sc_fail = Wire(Bool()) + val s3_cas_fail = Wire(Bool()) // error signal for amo inst // s3_error = s3_flag_error || s3_tag_error || s3_l2_error || s3_data_error val s3_error = RegEnable(s2_error, 0.U.asTypeOf(s2_error), s2_fire_to_s3) || s3_data_error @@ -507,10 +510,10 @@ class MainPipe(implicit p: Parameters) extends DCacheModule with HasPerfEvents w val (_, miss_shrink_param, _) = s3_coh.onCacheControl(M_FLUSH) val s3_need_replacement = RegEnable(s2_need_replacement, s2_fire_to_s3) - val miss_update_meta = s3_req.miss + val miss_update_meta = s3_req.miss && !s3_cas_fail // `missqueue` request does not yield a result when it fails val probe_update_meta = s3_req.probe && s3_tag_match && s3_coh =/= probe_new_coh val store_update_meta = s3_req.isStore && !s3_req.probe && s3_hit_coh =/= s3_new_hit_coh - val amo_update_meta = s3_req.isAMO && !s3_req.probe && s3_hit_coh =/= s3_new_hit_coh + val amo_update_meta = s3_req.isAMO && !s3_req.probe && s3_hit_coh =/= s3_new_hit_coh && !s3_sc_fail && !s3_cas_fail val amo_wait_amoalu = s3_req.isAMO && s3_req.cmd =/= M_XLR && s3_req.cmd =/= M_XSC && !isAMOCAS(s3_req.cmd) val update_meta = (miss_update_meta || probe_update_meta || store_update_meta || amo_update_meta) && !s3_req.replace @@ -544,14 +547,16 @@ class MainPipe(implicit p: Parameters) extends DCacheModule with HasPerfEvents w val s3_sc = !s3_req.probe && s3_req.isAMO && s3_req.cmd === M_XSC val s3_cas = !s3_req.probe && s3_req.isAMO && isAMOCAS(s3_req.cmd) val s3_lrsc_addr_match = lrsc_valid && lrsc_addr === get_block_addr(s3_req.addr) - val s3_sc_fail = s3_sc && !s3_lrsc_addr_match val debug_s3_sc_fail_addr_match = s3_sc && lrsc_addr === get_block_addr(s3_req.addr) && !lrsc_valid - val s3_cas_fail = s3_cas && (FillInterleaved(8, s3_req.amo_mask) & (s3_req.amo_cmp ^ s3_data_quad_word)) =/= 0.U + s3_sc_fail := s3_sc && (!s3_lrsc_addr_match || !s3_hit) + s3_cas_fail := s3_cas && (FillInterleaved(8, s3_req.amo_mask) & (s3_req.amo_cmp ^ s3_data_quad_word)) =/= 0.U val s3_can_do_amo = (s3_req.miss && !s3_req.probe && s3_req.isAMO) || s3_amo_hit val s3_can_do_amo_write = s3_can_do_amo && isWrite(s3_req.cmd) && !s3_sc_fail && !s3_cas_fail + val s3_can_do_miss_write = s3_req.miss && !s3_cas_fail + when (s3_valid && (s3_lr || s3_sc)) { when (s3_can_do_amo && s3_lr) { lrsc_count := (LRSCCycles - 1).U @@ -610,7 +615,7 @@ class MainPipe(implicit p: Parameters) extends DCacheModule with HasPerfEvents w val banked_amo_wmask = UIntToOH(s3_req.word_idx) - val update_data = s3_req.miss || s3_store_hit || s3_can_do_amo_write + val update_data = s3_can_do_miss_write || s3_store_hit || s3_can_do_amo_write// `missqueue` request does not yield a result when it fails // generate write data // AMO hits @@ -670,8 +675,8 @@ class MainPipe(implicit p: Parameters) extends DCacheModule with HasPerfEvents w val s3_probe_can_go = s3_req.probe && io.wb.ready && (io.meta_write.ready || !probe_update_meta) val s3_store_can_go = s3_req.source === STORE_SOURCE.U && !s3_req.probe && (io.meta_write.ready || !store_update_meta) && (io.data_write.ready || !update_data) && !s3_req.miss - val s3_amo_can_go = s3_amo_hit && (io.meta_write.ready || !amo_update_meta) && (io.data_write.ready || !update_data) && (s3_s_amoalu || !amo_wait_amoalu) - val s3_miss_can_go = s3_req.miss && + val s3_amo_can_go = s3_amo_hit && (io.meta_write.ready || !amo_update_meta) && (io.data_write.ready || !update_data) && (s3_s_amoalu || !amo_wait_amoalu) || s3_sc_fail + val s3_miss_can_go = s3_can_do_miss_write && (io.meta_write.ready || !amo_update_meta) && (io.data_write.ready || !update_data) && (s3_s_amoalu || !amo_wait_amoalu) && @@ -705,7 +710,7 @@ class MainPipe(implicit p: Parameters) extends DCacheModule with HasPerfEvents w ) ) val banked_wmask = Mux( - s3_req.miss, + s3_can_do_miss_write, banked_full_wmask, Mux( s3_store_hit,