Skip to content

Commit

Permalink
fix(MainPipe): fix s1_way_en generate logic when ecc inject occur (#…
Browse files Browse the repository at this point in the history
…4285)

* When inject tag ecc error `io.pseudo_error.valid == 1` and mainpipe
request valid (for example `io.miss_req.valid == 1`
```
  val s1_need_replacement = s1_req.miss && !s1_tag_match
  val s1_need_eviction = s1_req.miss && !s1_tag_match && s1_repl_coh.state =/= ClientStates.Nothing
  val s1_way_en = Mux(s1_need_replacement, s1_repl_way_en, s1_tag_match_way)
```
when generate `s1_way_en`, `s1_tag_match == 0` cause inject tag ecc
error, so `s1_need_replacement == 1`, but may be target cacheline
already in dcache (for example `prefetch.w` miss), finally there is 2
same paddr cacheline in dcache, obviously this is illegal.

* Determine whether it is a pseudo error. If it's pseudo error, use
no-toggled-tag (which no toggled by cacheCtrl) for generate `s1_way_en`,
otherwise use toggled-tag
  • Loading branch information
cz4e authored Feb 20, 2025
1 parent 48f7f55 commit 302eb94
Showing 1 changed file with 12 additions and 6 deletions.
18 changes: 12 additions & 6 deletions src/main/scala/xiangshan/cache/dcache/mainpipe/MainPipe.scala
Original file line number Diff line number Diff line change
Expand Up @@ -335,14 +335,16 @@ class MainPipe(implicit p: Parameters) extends DCacheModule with HasPerfEvents w
val tag_resp = encTag_resp.map(encTag => encTag(tagBits - 1, 0))
val s1_meta_valids = wayMap((w: Int) => Meta(meta_resp(w)).coh.isValid()).asUInt
val s1_tag_errors = wayMap((w: Int) => s1_meta_valids(w) && dcacheParameters.tagCode.decode(encTag_resp(w)).error).asUInt
val s1_tag_eq_way = wayMap((w: Int) => tag_resp(w) === get_tag(s1_req.addr) && !s1_tag_errors(w)).asUInt
val s1_tag_eq_way = wayMap((w: Int) => tag_resp(w) === get_tag(s1_req.addr)).asUInt
val s1_tag_ecc_eq_way = wayMap((w: Int) => s1_tag_eq_way(w) && !s1_tag_errors(w)).asUInt
val s1_tag_match_way = wayMap((w: Int) => s1_tag_eq_way(w) && s1_meta_valids(w)).asUInt
val s1_tag_match = ParallelORR(s1_tag_match_way)
val s1_tag_ecc_match_way = wayMap((w: Int) => s1_tag_ecc_eq_way(w) && s1_meta_valids(w)).asUInt
val s1_tag_match = ParallelORR(s1_tag_ecc_match_way)

val s1_hit_tag = get_tag(s1_req.addr)
val s1_hit_coh = ClientMetadata(ParallelMux(s1_tag_match_way.asBools, (0 until nWays).map(w => meta_resp(w))))
val s1_flag_error = ParallelMux(s1_tag_match_way.asBools, (0 until nWays).map(w => io.extra_meta_resp(w).error))
val s1_extra_meta = ParallelMux(s1_tag_match_way.asBools, (0 until nWays).map(w => io.extra_meta_resp(w)))
val s1_hit_coh = ClientMetadata(ParallelMux(s1_tag_ecc_match_way.asBools, (0 until nWays).map(w => meta_resp(w))))
val s1_flag_error = ParallelMux(s1_tag_ecc_match_way.asBools, (0 until nWays).map(w => io.extra_meta_resp(w).error))
val s1_extra_meta = ParallelMux(s1_tag_ecc_match_way.asBools, (0 until nWays).map(w => io.extra_meta_resp(w)))
io.pseudo_tag_error_inj_done := s1_fire && s1_meta_valids.orR

XSPerfAccumulate("probe_unused_prefetch", s1_req.probe && isFromL1Prefetch(s1_extra_meta.prefetch) && !s1_extra_meta.access) // may not be accurate
Expand All @@ -368,7 +370,11 @@ class MainPipe(implicit p: Parameters) extends DCacheModule with HasPerfEvents w
val s1_need_replacement = s1_req.miss && !s1_tag_match
val s1_need_eviction = s1_req.miss && !s1_tag_match && s1_repl_coh.state =/= ClientStates.Nothing

val s1_way_en = Mux(s1_need_replacement, s1_repl_way_en, s1_tag_match_way)
val s1_way_en = Mux(
RegEnable(!io.pseudo_error.valid, false.B, s0_fire),
Mux(s1_need_replacement, s1_repl_way_en, s1_tag_match_way),
Mux(ParallelORR(s1_tag_match_way), s1_tag_match_way, s1_repl_way_en)
)
assert(!RegNext(s1_fire && PopCount(s1_way_en) > 1.U))

val s1_tag = s1_hit_tag
Expand Down

0 comments on commit 302eb94

Please sign in to comment.