From 809c7e8551f3f322aa0ef8b6409488ae424115fb Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Tue, 8 Aug 2017 15:12:40 -0700 Subject: [PATCH] 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. --- src/main/scala/rocket/DCache.scala | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/scala/rocket/DCache.scala b/src/main/scala/rocket/DCache.scala index c57967b1..e36096b0 100644 --- a/src/main/scala/rocket/DCache.scala +++ b/src/main/scala/rocket/DCache.scala @@ -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)