From 176110b6d3828d1852427fb89c674c231f48111f Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Sat, 12 Aug 2017 15:23:57 -0700 Subject: [PATCH 1/4] Don't trigger ECC writebacks when a release is in flight --- src/main/scala/rocket/DCache.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/rocket/DCache.scala b/src/main/scala/rocket/DCache.scala index e36096b0..c75d1e6f 100644 --- a/src/main/scala/rocket/DCache.scala +++ b/src/main/scala/rocket/DCache.scala @@ -236,7 +236,7 @@ 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_pre_data_ecc = s2_valid_masked && s2_readwrite && !s2_meta_error && s2_hit - val s2_valid_data_error = s2_valid_hit_pre_data_ecc && s2_data_error + val s2_valid_data_error = s2_valid_hit_pre_data_ecc && s2_data_error && !release_ack_wait val s2_valid_hit = s2_valid_hit_pre_data_ecc && !s2_data_error && (!s2_waw_hazard || s2_store_merge) val s2_valid_miss = s2_valid_masked && s2_readwrite && !s2_meta_error && !s2_hit && !release_ack_wait val s2_valid_cached_miss = s2_valid_miss && !s2_uncached && !uncachedInFlight.asUInt.orR From 18fb052fc95204c672f1e2c253334a9539001a05 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Sat, 12 Aug 2017 15:27:30 -0700 Subject: [PATCH 2/4] DRY --- src/main/scala/rocket/DCache.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/scala/rocket/DCache.scala b/src/main/scala/rocket/DCache.scala index c75d1e6f..26ca8eed 100644 --- a/src/main/scala/rocket/DCache.scala +++ b/src/main/scala/rocket/DCache.scala @@ -100,7 +100,8 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) { val s1_valid_masked = s1_valid && !io.cpu.s1_kill val s1_valid_not_nacked = s1_valid && !s1_nack val s1_req = Reg(io.cpu.req.bits) - when (metaArb.io.out.valid && !metaArb.io.out.bits.write) { + val s0_clk_en = metaArb.io.out.valid && !metaArb.io.out.bits.write + when (s0_clk_en) { s1_req := io.cpu.req.bits s1_req.addr := Cat(metaArb.io.out.bits.addr >> blockOffBits, io.cpu.req.bits.addr(blockOffBits-1,0)) when (!metaArb.io.in(7).ready) { s1_req.phys := true } @@ -135,7 +136,7 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) { dataArb.io.in(3).bits.wordMask := UIntToOH(io.cpu.req.bits.addr.extract(rowOffBits-1,offsetlsb)) dataArb.io.in(3).bits.way_en := ~UInt(0, nWays) when (!dataArb.io.in(3).ready && s0_read) { io.cpu.req.ready := false } - val s1_didntRead = RegEnable(s0_needsRead && !dataArb.io.in(3).ready, metaArb.io.out.valid && !metaArb.io.out.bits.write) + val s1_didntRead = RegEnable(s0_needsRead && !dataArb.io.in(3).ready, s0_clk_en) metaArb.io.in(7).valid := io.cpu.req.valid metaArb.io.in(7).bits.write := false metaArb.io.in(7).bits.addr := io.cpu.req.bits.addr From 604abd5b074608fb80552381b61b1e3d83ef6179 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Sat, 12 Aug 2017 15:28:03 -0700 Subject: [PATCH 3/4] Only report ECC errors when the RAM was actually read --- src/main/scala/rocket/DCache.scala | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/scala/rocket/DCache.scala b/src/main/scala/rocket/DCache.scala index 26ca8eed..39795d3a 100644 --- a/src/main/scala/rocket/DCache.scala +++ b/src/main/scala/rocket/DCache.scala @@ -136,7 +136,7 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) { dataArb.io.in(3).bits.wordMask := UIntToOH(io.cpu.req.bits.addr.extract(rowOffBits-1,offsetlsb)) dataArb.io.in(3).bits.way_en := ~UInt(0, nWays) when (!dataArb.io.in(3).ready && s0_read) { io.cpu.req.ready := false } - val s1_didntRead = RegEnable(s0_needsRead && !dataArb.io.in(3).ready, s0_clk_en) + val s1_did_read = RegEnable(dataArb.io.in(3).fire(), s0_clk_en) metaArb.io.in(7).valid := io.cpu.req.valid metaArb.io.in(7).bits.write := false metaArb.io.in(7).bits.addr := io.cpu.req.bits.addr @@ -233,7 +233,8 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) { val (s2_hit, s2_grow_param, s2_new_hit_state) = s2_hit_state.onAccess(s2_req.cmd) val s2_data_decoded = decodeData(s2_data) val s2_word_idx = s2_req.addr.extract(log2Up(rowBits/8)-1, log2Up(wordBytes)) - val s2_data_error = needsRead(s2_req) && (s2_data_decoded.map(_.error).grouped(wordBits/eccBits).map(_.reduce(_||_)).toSeq)(s2_word_idx) + val s2_did_read = RegEnable(s1_did_read, s1_valid_not_nacked) + val s2_data_error = s2_did_read && (s2_data_decoded.map(_.error).grouped(wordBits/eccBits).map(_.reduce(_||_)).toSeq)(s2_word_idx) 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_pre_data_ecc = s2_valid_masked && s2_readwrite && !s2_meta_error && s2_hit @@ -349,7 +350,7 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) { (pstore1_valid && s1Depends(pstore1_addr, pstore1_mask)) || (pstore2_valid && s1Depends(pstore2_addr, pstore2_storegen_mask)) val s1_raw_hazard = s1_read && s1_hazard - s1_waw_hazard := Bool(eccBytes > 1) && s1_write && (s1_hazard || s1_didntRead) + s1_waw_hazard := Bool(eccBytes > 1) && s1_write && (s1_hazard || needsRead(s1_req) && !s1_did_read) when (s1_valid && s1_raw_hazard) { s1_nack := true } // Prepare a TileLink request message that initiates a transaction From 7387f2a93afc49801a4c1294e1a166af6507b186 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Sat, 12 Aug 2017 16:13:24 -0700 Subject: [PATCH 4/4] Don't block D-channel when handling a probe This is an acquire-before-release regression. --- src/main/scala/rocket/DCache.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/rocket/DCache.scala b/src/main/scala/rocket/DCache.scala index 39795d3a..c9e1675e 100644 --- a/src/main/scala/rocket/DCache.scala +++ b/src/main/scala/rocket/DCache.scala @@ -411,7 +411,7 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) { val grantInProgress = Reg(init=Bool(false)) val blockProbeAfterGrantCount = Reg(init=UInt(0)) when (blockProbeAfterGrantCount > 0) { blockProbeAfterGrantCount := blockProbeAfterGrantCount - 1 } - val canAcceptCachedGrant = if (cacheParams.acquireBeforeRelease) release_state === s_ready else true.B + val canAcceptCachedGrant = if (cacheParams.acquireBeforeRelease) !release_state.isOneOf(s_voluntary_writeback, s_voluntary_write_meta) else true.B tl_out.d.ready := Mux(grantIsCached, (!d_first || tl_out.e.ready) && canAcceptCachedGrant, true.B) when (tl_out.d.fire()) { when (grantIsCached) {