Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(MainPipe): Dcache status is not changed by the sc/cas that fails #4217

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 15 additions & 10 deletions src/main/scala/xiangshan/cache/dcache/mainpipe/MainPipe.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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

Expand All @@ -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
Expand Down Expand Up @@ -500,17 +501,19 @@ 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
val (_, probe_shrink_param, probe_new_coh) = s3_coh.onProbe(s3_req.probe_param)
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

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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) &&
Expand Down Expand Up @@ -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,
Expand Down
Loading