Don't merge stores that manifest WAW hazards
The following sequence would drop the first store when eccBytes=4: sb x0, 0(t0) nop sb x0, 4(t0) nop sb x0, 1(t0) Because the first and second store are to different ECC granules, the hazard check correctly allowed the second one to proceed, but the third was merged with the second, even though it conflicted with the first. So, don't allow the third to be merged with the second, since the second stored to a different ECC granule.
This commit is contained in:
parent
3ef6e4c9f2
commit
809c7e8551
@ -312,11 +312,6 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) {
|
||||
pstore2_valid := pstore2_valid && !pstore_drain || advance_pstore1
|
||||
val pstore2_addr = RegEnable(Mux(s2_correct, s2_req.addr, pstore1_addr), advance_pstore1)
|
||||
val pstore2_way = RegEnable(Mux(s2_correct, s2_hit_way, pstore1_way), advance_pstore1)
|
||||
s2_store_merge := {
|
||||
val idxMatch = s2_req.addr(untagBits-1, log2Ceil(wordBytes)) === pstore2_addr(untagBits-1, log2Ceil(wordBytes))
|
||||
val tagMatch = (s2_hit_way & pstore2_way).orR
|
||||
Bool(eccBytes > 1) && pstore2_valid && idxMatch && tagMatch
|
||||
}
|
||||
val pstore2_storegen_data = {
|
||||
for (i <- 0 until wordBytes)
|
||||
yield RegEnable(pstore1_storegen_data(8*(i+1)-1, 8*i), advance_pstore1 || pstore1_merge && pstore1_mask(i))
|
||||
@ -329,6 +324,14 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) {
|
||||
}
|
||||
mask
|
||||
}
|
||||
s2_store_merge := {
|
||||
// only merge stores to ECC granules that are already stored-to, to avoid
|
||||
// WAW hazards
|
||||
val wordMatch = (eccMask(pstore2_storegen_mask) | ~eccMask(pstore1_mask)).andR
|
||||
val idxMatch = s2_req.addr(untagBits-1, log2Ceil(wordBytes)) === pstore2_addr(untagBits-1, log2Ceil(wordBytes))
|
||||
val tagMatch = (s2_hit_way & pstore2_way).orR
|
||||
Bool(eccBytes > 1) && pstore2_valid && wordMatch && idxMatch && tagMatch
|
||||
}
|
||||
dataArb.io.in(0).valid := pstore_drain
|
||||
dataArb.io.in(0).bits.write := true
|
||||
dataArb.io.in(0).bits.addr := Mux(pstore2_valid, pstore2_addr, pstore1_addr)
|
||||
|
Loading…
Reference in New Issue
Block a user