1
0

Only flush D$ on FENCE.I if it won't always be probed on I$ miss

This commit is contained in:
Andrew Waterman 2017-08-05 13:47:21 -07:00
parent 991e16de92
commit 83875e3a0c

View File

@ -6,7 +6,7 @@ import Chisel._
import Chisel.ImplicitConversions._ import Chisel.ImplicitConversions._
import freechips.rocketchip.config.Parameters import freechips.rocketchip.config.Parameters
import freechips.rocketchip.coreplex.{RationalCrossing, RocketCrossing, RocketTilesKey} import freechips.rocketchip.coreplex.{RationalCrossing, RocketCrossing, RocketTilesKey}
import freechips.rocketchip.diplomacy.AddressSet import freechips.rocketchip.diplomacy.{AddressSet, RegionType}
import freechips.rocketchip.tilelink._ import freechips.rocketchip.tilelink._
import freechips.rocketchip.util._ import freechips.rocketchip.util._
import TLMessages._ import TLMessages._
@ -640,7 +640,6 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) {
val flushCounterNext = flushCounter +& 1 val flushCounterNext = flushCounter +& 1
val flushDone = (flushCounterNext >> log2Ceil(nSets)) === nWays val flushDone = (flushCounterNext >> log2Ceil(nSets)) === nWays
val flushCounterWrap = flushCounterNext(log2Ceil(nSets)-1, 0) val flushCounterWrap = flushCounterNext(log2Ceil(nSets)-1, 0)
when (tl_out_a.fire() && !s2_uncached) { flushed := false }
when (s2_valid_masked && s2_req.cmd === M_FLUSH_ALL) { when (s2_valid_masked && s2_req.cmd === M_FLUSH_ALL) {
io.cpu.s2_nack := !flushed io.cpu.s2_nack := !flushed
when (!flushed) { when (!flushed) {
@ -653,17 +652,21 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) {
metaArb.io.in(5).bits.addr := Cat(io.cpu.req.bits.addr >> untagBits, flushCounter(idxBits-1, 0) << blockOffBits) metaArb.io.in(5).bits.addr := Cat(io.cpu.req.bits.addr >> untagBits, flushCounter(idxBits-1, 0) << blockOffBits)
metaArb.io.in(5).bits.way_en := ~UInt(0, nWays) metaArb.io.in(5).bits.way_en := ~UInt(0, nWays)
metaArb.io.in(5).bits.data := metaArb.io.in(4).bits.data metaArb.io.in(5).bits.data := metaArb.io.in(4).bits.data
when (flushing) { // Only flush D$ on FENCE.I if some cached executable regions are untracked.
s1_victim_way := flushCounter >> log2Up(nSets) if (!edge.manager.managers.forall(m => !m.supportsAcquireB || !m.executable || m.regionType >= RegionType.TRACKED)) {
when (s2_flush_valid) { when (tl_out_a.fire() && !s2_uncached) { flushed := false }
flushCounter := flushCounterNext when (flushing) {
when (flushDone) { s1_victim_way := flushCounter >> log2Up(nSets)
flushed := true when (s2_flush_valid) {
if (!isPow2(nWays)) flushCounter := flushCounterWrap flushCounter := flushCounterNext
when (flushDone) {
flushed := true
if (!isPow2(nWays)) flushCounter := flushCounterWrap
}
}
when (flushed && release_state === s_ready && !release_ack_wait) {
flushing := false
} }
}
when (flushed && release_state === s_ready && !release_ack_wait) {
flushing := false
} }
} }
metaArb.io.in(0).valid := resetting metaArb.io.in(0).valid := resetting