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

D$: guarantee that no-alloc accesses are ordered even if aliased #2358

Merged
merged 2 commits into from
Mar 24, 2020
Merged
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: 24 additions & 1 deletion src/main/scala/rocket/DCache.scala
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,28 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) {
val s2_data_corrected = (s2_data_decoded.map(_.corrected): Seq[UInt]).asUInt
val s2_data_uncorrected = (s2_data_decoded.map(_.uncorrected): Seq[UInt]).asUInt
val s2_valid_hit_maybe_flush_pre_data_ecc_and_waw = s2_valid_masked && !s2_meta_error && s2_hit
val s2_valid_hit_pre_data_ecc_and_waw = s2_valid_hit_maybe_flush_pre_data_ecc_and_waw && s2_readwrite
val s2_no_alloc_hazard = {
// make sure that any in-flight non-allocating accesses are ordered before
// any allocating accesses. this can only happen if aliasing is possible.
val any_no_alloc_in_flight = Reg(Bool())
when (!uncachedInFlight.asUInt.orR) { any_no_alloc_in_flight := false }
when (s2_valid && s2_req.no_alloc) { any_no_alloc_in_flight := true }
val s1_need_check = any_no_alloc_in_flight || s2_valid && s2_req.no_alloc

val concerns = (uncachedInFlight zip uncachedReqs) :+ (s2_valid && s2_req.no_alloc, s2_req)
val s1_uncached_hits = concerns.map { c =>
val concern_wmask = new StoreGen(c._2.size, c._2.addr, UInt(0), wordBytes).mask
val addr_match = (c._2.addr ^ s1_paddr)(pgIdxBits+pgLevelBits-1, wordBytes.log2) === 0
val mask_match = (concern_wmask & s1_mask_xwr).orR || c._2.cmd === M_PWR || s1_req.cmd === M_PWR
val cmd_match = isWrite(c._2.cmd) || isWrite(s1_req.cmd)
c._1 && s1_need_check && cmd_match && addr_match && mask_match
}

val s2_uncached_hits = RegEnable(s1_uncached_hits.asUInt, s1_valid_not_nacked)

usingVM && pgIdxBits < untagBits && s2_uncached_hits.orR
}
val s2_valid_hit_pre_data_ecc_and_waw = s2_valid_hit_maybe_flush_pre_data_ecc_and_waw && s2_readwrite && !s2_no_alloc_hazard
val s2_valid_flush_line = s2_valid_hit_maybe_flush_pre_data_ecc_and_waw && s2_cmd_flush_line
val s2_valid_hit_pre_data_ecc = s2_valid_hit_pre_data_ecc_and_waw && (!s2_waw_hazard || s2_store_merge)
val s2_valid_data_error = s2_valid_hit_pre_data_ecc_and_waw && s2_data_error
Expand Down Expand Up @@ -539,6 +560,7 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) {
when (s) {
f := Bool(true)
r := s2_req
r.cmd := Mux(s2_write, Mux(s2_req.cmd === M_PWR, M_PWR, M_XWR), M_XRD)
}
}
}.otherwise {
Expand Down Expand Up @@ -819,6 +841,7 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) {
resp.bits.size := uncachedResp.size
resp.bits.signed := uncachedResp.signed
resp.bits.data := new LoadGen(uncachedResp.size, uncachedResp.signed, uncachedResp.addr, s1_uncached_data_word, false.B, wordBytes).data
resp.bits.data_raw := s1_uncached_data_word
when (grantIsUncachedData && !resp.ready) {
tl_out.d.ready := false
}
Expand Down