Skip to content

Commit

Permalink
Fix a rare D$ ECC bug (#2458)
Browse files Browse the repository at this point in the history
This bug can manifest with a store, load, store to same word as the first
one, then load, as follows. The first store succeeds, but is still in the
pending store buffer.  Some unrelated load occurs.  Then a store to the
same word as the first store occurs, this time detecting an ECC error.
Finally, some unrelated load occurs.  (The loads are mostly irrelevant,
but the pipeline needs to stay busy for the bug to manifest.)

Since the bug can only manifest with two nearby stores to the same word,
one detecting an error and one not detecting an error, this bug is not
especially likely to occur in practice.  In particular, if the error grew
before the sequence began, the bug would not manifest.
  • Loading branch information
aswaterman authored May 10, 2020
1 parent 8988992 commit 108fce7
Showing 1 changed file with 4 additions and 2 deletions.
6 changes: 4 additions & 2 deletions src/main/scala/rocket/DCache.scala
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,9 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) {
val s2_valid_no_xcpt = s2_valid && !io.cpu.s2_xcpt.asUInt.orR
val s2_probe = Reg(next=s1_probe, init=Bool(false))
val releaseInFlight = s1_probe || s2_probe || release_state =/= s_ready
val s2_valid_masked = s2_valid_no_xcpt && Reg(next = !s1_nack)
val s2_not_nacked_in_s1 = RegNext(!s1_nack)
val s2_valid_not_nacked_in_s1 = s2_valid && s2_not_nacked_in_s1
val s2_valid_masked = s2_valid_no_xcpt && s2_not_nacked_in_s1
val s2_valid_not_killed = s2_valid_masked && !io.cpu.s2_kill
val s2_req = Reg(io.cpu.req.bits)
val s2_cmd_flush_all = s2_req.cmd === M_FLUSH_ALL && !s2_req.size(0)
Expand Down Expand Up @@ -445,7 +447,7 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) {
val pstore1_mask = RegEnable(s1_mask, s1_valid_not_nacked && s1_write)
val pstore1_storegen_data = Wire(init = pstore1_data)
val pstore1_rmw = Bool(usingRMW) && RegEnable(needsRead(s1_req), s1_valid_not_nacked && s1_write)
val pstore1_merge_likely = s2_valid && s2_write && s2_store_merge
val pstore1_merge_likely = s2_valid_not_nacked_in_s1 && s2_write && s2_store_merge
val pstore1_merge = s2_store_valid && s2_store_merge
val pstore2_valid = Reg(Bool())
val pstore_drain_opportunistic = !(io.cpu.req.valid && likelyNeedsRead(io.cpu.req.bits)) && !(s1_valid && s1_waw_hazard)
Expand Down

0 comments on commit 108fce7

Please sign in to comment.