From 9f0ccbeac58c32ae2416e030d53dc656969fb7a1 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Thu, 28 Feb 2013 18:13:41 -0800 Subject: [PATCH] writebacks on release network pass asm tests and bmarks --- uncore/src/coherence.scala | 213 +++++++++++++++++-------------------- 1 file changed, 100 insertions(+), 113 deletions(-) diff --git a/uncore/src/coherence.scala b/uncore/src/coherence.scala index e1cc453e..effba2e9 100644 --- a/uncore/src/coherence.scala +++ b/uncore/src/coherence.scala @@ -28,20 +28,21 @@ abstract class CoherencePolicy { def getAcquireTypeOnPrimaryMiss(cmd: Bits, state: UFix): UFix def getAcquireTypeOnSecondaryMiss(cmd: Bits, state: UFix, outstanding: Acquire): UFix - def getAcquireTypeOnCacheControl(cmd: Bits): Bits - def getAcquireTypeOnWriteback(): Bits + def getReleaseTypeOnCacheControl(cmd: Bits): Bits + def getReleaseTypeOnVoluntaryWriteback(): Bits def getVoluntaryWriteback(addr: UFix, client_id: UFix, master_id: UFix): Release - def newRelease (incoming: Probe, state: UFix): Release + def newRelease (incoming: Probe, state: UFix, id: UFix): Release - def messageHasData (reply: Release): Bool + def messageHasData (rel: Release): Bool def messageHasData (acq: Acquire): Bool - def messageHasData (reply: Grant): Bool + def messageHasData (grant: Grant): Bool def messageUpdatesDataArray (reply: Grant): Bool def messageIsUncached(acq: Acquire): Bool def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool def isVoluntary(rel: Release): Bool + def isVoluntary(gnt: Grant): Bool def getGrantType(a_type: UFix, count: UFix): Bits def getGrantType(rel: Release, count: UFix): Bits def getProbeType(a_type: UFix, global_state: UFix): UFix @@ -50,6 +51,9 @@ abstract class CoherencePolicy { def needsAckReply(a_type: UFix, global_state: UFix): Bool def requiresAck(grant: Grant): Bool def requiresAck(release: Release): Bool + def pendingVoluntaryReleaseIsSufficient(r_type: UFix, p_type: UFix): Bool + + def uFixListContains(list: List[UFix], elem: UFix): Bool = list.map(elem === _).reduceLeft(_||_) } trait UncachedTransactions { @@ -66,13 +70,8 @@ abstract class CoherencePolicyWithUncached extends CoherencePolicy with Uncached abstract class IncoherentPolicy extends CoherencePolicy { // UNIMPLEMENTED def newStateOnProbe(incoming: Probe, state: UFix): Bits = state - def newRelease (incoming: Probe, state: UFix): Release = { - val reply = new Release - reply.r_type := UFix(0) - reply.master_xact_id := UFix(0) - reply - } - def messageHasData (reply: Release) = Bool(false) + def newRelease (incoming: Probe, state: UFix, id: UFix): Release = Release( UFix(0), UFix(0), UFix(0), UFix(0)) + def messageHasData (rel: Release) = Bool(false) def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = Bool(false) def getGrantType(a_type: UFix, count: UFix): Bits = Bits(0) def getGrantType(rel: Release, count: UFix): Bits = Bits(0) @@ -82,15 +81,19 @@ abstract class IncoherentPolicy extends CoherencePolicy { def needsAckReply(a_type: UFix, global_state: UFix): Bool = Bool(false) def requiresAck(grant: Grant) = Bool(true) def requiresAck(release: Release) = Bool(false) + def pendingVoluntaryReleaseIsSufficient(r_type: UFix, p_type: UFix): Bool = Bool(false) + } class ThreeStateIncoherence extends IncoherentPolicy { val tileInvalid :: tileClean :: tileDirty :: Nil = Enum(3){ UFix() } val acquireReadClean :: acquireReadDirty :: acquireWriteback :: Nil = Enum(3){ UFix() } - val grantData :: grantAck :: Nil = Enum(2){ UFix() } + val grantVoluntaryAck :: grantData :: grantAck :: Nil = Enum(3){ UFix() } val releaseVoluntaryInvalidateData :: releaseInvalidateAck :: Nil = Enum(2){ UFix() } - val uncachedTypeList = List() - val hasDataTypeList = List(acquireWriteback) + val uncachedAcquireTypeList = List() + val hasDataAcquireTypeList = List(acquireWriteback) + val hasDataReleaseTypeList = List(acquireWriteback) + val hasDataGrantTypeList = List(grantData) def isHit ( cmd: Bits, state: UFix): Bool = (state === tileClean || state === tileDirty) def isValid (state: UFix): Bool = state != tileInvalid @@ -116,6 +119,7 @@ class ThreeStateIncoherence extends IncoherentPolicy { def getVoluntaryWriteback(addr: UFix, client_id: UFix, master_id: UFix) = Release(releaseVoluntaryInvalidateData, addr, client_id, master_id) def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData + def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck def getAcquireTypeOnPrimaryMiss(cmd: Bits, state: UFix): UFix = { val (read, write) = cpuCmdToRW(cmd) @@ -125,13 +129,13 @@ class ThreeStateIncoherence extends IncoherentPolicy { val (read, write) = cpuCmdToRW(cmd) Mux(write, acquireReadDirty, outstanding.a_type) } - def getAcquireTypeOnCacheControl(cmd: Bits): Bits = acquireWriteback //TODO - def getAcquireTypeOnWriteback(): Bits = acquireWriteback + def getReleaseTypeOnCacheControl(cmd: Bits): Bits = releaseVoluntaryInvalidateData // TODO + def getReleaseTypeOnVoluntaryWriteback(): Bits = releaseVoluntaryInvalidateData - def messageHasData (init: Acquire): Bool = hasDataTypeList.map(t => init.a_type === t).reduceLeft(_||_) - def messageHasData (reply: Grant) = (reply.g_type === grantData) + def messageHasData (acq: Acquire): Bool = uFixListContains(hasDataAcquireTypeList, acq.a_type) + def messageHasData (grant: Grant): Bool = uFixListContains(hasDataGrantTypeList, grant.g_type) def messageUpdatesDataArray (reply: Grant) = (reply.g_type === grantData) - def messageIsUncached(init: Acquire): Bool = uncachedTypeList.map(t => init.a_type === t).reduceLeft(_||_) + def messageIsUncached(acq: Acquire): Bool = uFixListContains(uncachedAcquireTypeList, acq.a_type) } class MICoherence extends CoherencePolicyWithUncached { @@ -143,8 +147,10 @@ class MICoherence extends CoherencePolicyWithUncached { val grantVoluntaryAck :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: Nil = Enum(7){ UFix() } val probeInvalidate :: probeCopy :: Nil = Enum(2){ UFix() } val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseCopyData :: releaseInvalidateAck :: releaseCopyAck :: Nil = Enum(5){ UFix() } - val uncachedTypeList = List(acquireReadUncached, acquireWriteUncached, grantReadWordUncached, acquireWriteWordUncached, acquireAtomicUncached) - val hasDataTypeList = List(acquireWriteUncached, acquireWriteWordUncached, acquireAtomicUncached) + val uncachedAcquireTypeList = List(acquireReadUncached, acquireWriteUncached, acquireReadWordUncached, acquireWriteWordUncached, acquireAtomicUncached) + val hasDataAcquireTypeList = List(acquireWriteUncached, acquireWriteWordUncached, acquireAtomicUncached) + val hasDataReleaseTypeList = List(releaseVoluntaryInvalidateData, releaseInvalidateData, releaseCopyData) + val hasDataGrantTypeList = List(grantReadExclusive, grantReadUncached, grantReadWordUncached, grantAtomicUncached) def isHit (cmd: Bits, state: UFix): Bool = state != tileInvalid def isValid (state: UFix): Bool = state != tileInvalid @@ -194,14 +200,14 @@ class MICoherence extends CoherencePolicyWithUncached { def getVoluntaryWriteback(addr: UFix, client_id: UFix, master_id: UFix) = Release(releaseVoluntaryInvalidateData, addr, client_id, master_id) def isUncachedReadTransaction(acq: Acquire) = acq.a_type === acquireReadUncached def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData + def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck def getAcquireTypeOnPrimaryMiss(cmd: Bits, state: UFix): UFix = acquireReadExclusive def getAcquireTypeOnSecondaryMiss(cmd: Bits, state: UFix, outstanding: Acquire): UFix = acquireReadExclusive - def getAcquireTypeOnCacheControl(cmd: Bits): Bits = acquireWriteUncached - def getAcquireTypeOnWriteback(): Bits = getAcquireTypeOnCacheControl(M_INV) + def getReleaseTypeOnCacheControl(cmd: Bits): Bits = releaseVoluntaryInvalidateData // TODO + def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV) - def newRelease (incoming: Probe, state: UFix): Release = { - val reply = new Release + def newRelease (incoming: Probe, state: UFix, id: UFix): Release = { val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array( probeInvalidate -> releaseInvalidateData, probeCopy -> releaseCopyData @@ -210,23 +216,16 @@ class MICoherence extends CoherencePolicyWithUncached { probeInvalidate -> releaseInvalidateAck, probeCopy -> releaseCopyAck )) - reply.r_type := Mux(needsWriteback(state), with_data, without_data) - reply.master_xact_id := incoming.master_xact_id - reply + Release( Mux(needsWriteback(state), with_data, without_data), incoming.addr, id, incoming.master_xact_id) } - def messageHasData (reply: Release): Bool = { - (reply.r_type === releaseInvalidateData || - reply.r_type === releaseCopyData) - } - def messageHasData (acq: Acquire): Bool = hasDataTypeList.map(t => acq.a_type === t).reduceLeft(_||_) - def messageHasData (reply: Grant): Bool = { - (reply.g_type != grantWriteUncached && reply.g_type != grantWriteWordUncached) - } + def messageHasData (rel: Release): Bool = uFixListContains(hasDataReleaseTypeList, rel.r_type) + def messageHasData (acq: Acquire): Bool = uFixListContains(hasDataAcquireTypeList, acq.a_type) + def messageHasData (grant: Grant): Bool = uFixListContains(hasDataGrantTypeList, grant.g_type) def messageUpdatesDataArray (reply: Grant): Bool = { (reply.g_type === grantReadExclusive) } - def messageIsUncached(acq: Acquire): Bool = uncachedTypeList.map(t => acq.a_type === t).reduceLeft(_||_) + def messageIsUncached(acq: Acquire): Bool = uFixListContains(uncachedAcquireTypeList, acq.a_type) def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2) @@ -269,6 +268,7 @@ class MICoherence extends CoherencePolicyWithUncached { } def requiresAck(grant: Grant) = Bool(true) def requiresAck(release: Release) = Bool(false) + def pendingVoluntaryReleaseIsSufficient(r_type: UFix, p_type: UFix): Bool = (r_type === releaseVoluntaryInvalidateData) } class MEICoherence extends CoherencePolicyWithUncached { @@ -280,8 +280,11 @@ class MEICoherence extends CoherencePolicyWithUncached { val grantVoluntaryAck :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadExclusiveAck :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: Nil = Enum(8){ UFix() } val probeInvalidate :: probeDowngrade :: probeCopy :: Nil = Enum(3){ UFix() } val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(7){ UFix() } - val uncachedTypeList = List(acquireReadUncached, acquireWriteUncached, grantReadWordUncached, acquireWriteWordUncached, acquireAtomicUncached) - val hasDataTypeList = List(acquireWriteUncached, acquireWriteWordUncached, acquireAtomicUncached) + + val uncachedAcquireTypeList = List(acquireReadUncached, acquireWriteUncached, acquireReadWordUncached, acquireWriteWordUncached, acquireAtomicUncached) + val hasDataAcquireTypeList = List(acquireWriteUncached, acquireWriteWordUncached, acquireAtomicUncached) + val hasDataReleaseTypeList = List(releaseVoluntaryInvalidateData, releaseInvalidateData, releaseDowngradeData, releaseCopyData) + val hasDataGrantTypeList = List(grantReadExclusive, grantReadUncached, grantReadWordUncached, grantAtomicUncached) def isHit (cmd: Bits, state: UFix): Bool = state != tileInvalid def isValid (state: UFix): Bool = state != tileInvalid @@ -340,6 +343,7 @@ class MEICoherence extends CoherencePolicyWithUncached { def getVoluntaryWriteback(addr: UFix, client_id: UFix, master_id: UFix) = Release(releaseVoluntaryInvalidateData, addr, client_id, master_id) def isUncachedReadTransaction(acq: Acquire) = acq.a_type === acquireReadUncached def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData + def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck def getAcquireTypeOnPrimaryMiss(cmd: Bits, state: UFix): UFix = { val (read, write) = cpuCmdToRW(cmd) @@ -349,11 +353,10 @@ class MEICoherence extends CoherencePolicyWithUncached { val (read, write) = cpuCmdToRW(cmd) Mux(write, acquireReadExclusiveDirty, outstanding.a_type) } - def getAcquireTypeOnCacheControl(cmd: Bits): Bits = acquireWriteUncached - def getAcquireTypeOnWriteback(): Bits = getAcquireTypeOnCacheControl(M_INV) + def getReleaseTypeOnCacheControl(cmd: Bits): Bits = releaseVoluntaryInvalidateData // TODO + def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV) - def newRelease (incoming: Probe, state: UFix): Release = { - val reply = new Release + def newRelease (incoming: Probe, state: UFix, id: UFix): Release = { val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array( probeInvalidate -> releaseInvalidateData, probeDowngrade -> releaseDowngradeData, @@ -364,24 +367,16 @@ class MEICoherence extends CoherencePolicyWithUncached { probeDowngrade -> releaseDowngradeAck, probeCopy -> releaseCopyAck )) - reply.r_type := Mux(needsWriteback(state), with_data, without_data) - reply.master_xact_id := incoming.master_xact_id - reply + Release( Mux(needsWriteback(state), with_data, without_data), incoming.addr, id, incoming.master_xact_id) } - def messageHasData (reply: Release): Bool = { - (reply.r_type === releaseInvalidateData || - reply.r_type === releaseDowngradeData || - reply.r_type === releaseCopyData) - } - def messageHasData (acq: Acquire): Bool = hasDataTypeList.map(t => acq.a_type === t).reduceLeft(_||_) - def messageHasData (reply: Grant): Bool = { - (reply.g_type != grantWriteUncached && reply.g_type != grantReadExclusiveAck && reply.g_type != grantWriteWordUncached) - } + def messageHasData (rel: Release): Bool = uFixListContains(hasDataReleaseTypeList, rel.r_type) + def messageHasData (acq: Acquire): Bool = uFixListContains(hasDataAcquireTypeList, acq.a_type) + def messageHasData (grant: Grant): Bool = uFixListContains(hasDataGrantTypeList, grant.g_type) def messageUpdatesDataArray (reply: Grant): Bool = { (reply.g_type === grantReadExclusive) } - def messageIsUncached(init: Acquire): Bool = uncachedTypeList.map(t => init.a_type === t).reduceLeft(_||_) + def messageIsUncached(acq: Acquire): Bool = uFixListContains(uncachedAcquireTypeList, acq.a_type) def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2) @@ -426,6 +421,8 @@ class MEICoherence extends CoherencePolicyWithUncached { } def requiresAck(grant: Grant) = Bool(true) def requiresAck(release: Release) = Bool(false) + + def pendingVoluntaryReleaseIsSufficient(r_type: UFix, p_type: UFix): Bool = (r_type === releaseVoluntaryInvalidateData) } class MSICoherence extends CoherencePolicyWithUncached { @@ -437,8 +434,10 @@ class MSICoherence extends CoherencePolicyWithUncached { val grantVoluntaryAck :: grantReadShared :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadExclusiveAck :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: Nil = Enum(9){ UFix() } val probeInvalidate :: probeDowngrade :: probeCopy :: Nil = Enum(3){ UFix() } val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(7){ UFix() } - val uncachedTypeList = List(acquireReadUncached, acquireWriteUncached, grantReadWordUncached, acquireWriteWordUncached, acquireAtomicUncached) - val hasDataTypeList = List(acquireWriteUncached, acquireWriteWordUncached, acquireAtomicUncached) + val uncachedAcquireTypeList = List(acquireReadUncached, acquireWriteUncached, acquireReadWordUncached, acquireWriteWordUncached, acquireAtomicUncached) + val hasDataAcquireTypeList = List(acquireWriteUncached, acquireWriteWordUncached, acquireAtomicUncached) + val hasDataReleaseTypeList = List(releaseVoluntaryInvalidateData, releaseInvalidateData, releaseDowngradeData, releaseCopyData) + val hasDataGrantTypeList = List(grantReadShared, grantReadExclusive, grantReadUncached, grantReadWordUncached, grantAtomicUncached) def isHit (cmd: Bits, state: UFix): Bool = { val (read, write) = cpuCmdToRW(cmd) @@ -504,6 +503,7 @@ class MSICoherence extends CoherencePolicyWithUncached { def getVoluntaryWriteback(addr: UFix, client_id: UFix, master_id: UFix) = Release(releaseVoluntaryInvalidateData, addr, client_id, master_id) def isUncachedReadTransaction(acq: Acquire) = acq.a_type === acquireReadUncached def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData + def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck def getAcquireTypeOnPrimaryMiss(cmd: Bits, state: UFix): UFix = { val (read, write) = cpuCmdToRW(cmd) @@ -513,11 +513,10 @@ class MSICoherence extends CoherencePolicyWithUncached { val (read, write) = cpuCmdToRW(cmd) Mux(write, acquireReadExclusive, outstanding.a_type) } - def getAcquireTypeOnCacheControl(cmd: Bits): Bits = acquireWriteUncached - def getAcquireTypeOnWriteback(): Bits = getAcquireTypeOnCacheControl(M_INV) + def getReleaseTypeOnCacheControl(cmd: Bits): Bits = releaseVoluntaryInvalidateData // TODO + def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV) - def newRelease (incoming: Probe, state: UFix): Release = { - val reply = new Release + def newRelease (incoming: Probe, state: UFix, id: UFix): Release = { val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array( probeInvalidate -> releaseInvalidateData, probeDowngrade -> releaseDowngradeData, @@ -528,24 +527,16 @@ class MSICoherence extends CoherencePolicyWithUncached { probeDowngrade -> releaseDowngradeAck, probeCopy -> releaseCopyAck )) - reply.r_type := Mux(needsWriteback(state), with_data, without_data) - reply.master_xact_id := incoming.master_xact_id - reply + Release( Mux(needsWriteback(state), with_data, without_data), incoming.addr, id, incoming.master_xact_id) } - def messageHasData (reply: Release): Bool = { - (reply.r_type === releaseInvalidateData || - reply.r_type === releaseDowngradeData || - reply.r_type === releaseCopyData) - } - def messageHasData (acq: Acquire): Bool = hasDataTypeList.map(t => acq.a_type === t).reduceLeft(_||_) - def messageHasData (reply: Grant): Bool = { - (reply.g_type != grantWriteUncached && reply.g_type != grantReadExclusiveAck && reply.g_type != grantWriteWordUncached) - } + def messageHasData (rel: Release): Bool = uFixListContains(hasDataReleaseTypeList, rel.r_type) + def messageHasData (acq: Acquire): Bool = uFixListContains(hasDataAcquireTypeList, acq.a_type) + def messageHasData (grant: Grant): Bool = uFixListContains(hasDataGrantTypeList, grant.g_type) def messageUpdatesDataArray (reply: Grant): Bool = { (reply.g_type === grantReadShared || reply.g_type === grantReadExclusive) } - def messageIsUncached(acq: Acquire): Bool = uncachedTypeList.map(t => acq.a_type === t).reduceLeft(_||_) + def messageIsUncached(acq: Acquire): Bool = uFixListContains(uncachedAcquireTypeList, acq.a_type) def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2) @@ -587,6 +578,8 @@ class MSICoherence extends CoherencePolicyWithUncached { } def requiresAck(grant: Grant) = Bool(true) def requiresAck(release: Release) = Bool(false) + + def pendingVoluntaryReleaseIsSufficient(r_type: UFix, p_type: UFix): Bool = (r_type === releaseVoluntaryInvalidateData) } class MESICoherence extends CoherencePolicyWithUncached { @@ -598,8 +591,11 @@ class MESICoherence extends CoherencePolicyWithUncached { val grantVoluntaryAck :: grantReadShared :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadExclusiveAck :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: Nil = Enum(9){ UFix() } val probeInvalidate :: probeDowngrade :: probeCopy :: Nil = Enum(3){ UFix() } val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(7){ UFix() } - val uncachedTypeList = List(acquireReadUncached, acquireWriteUncached, acquireReadWordUncached, acquireWriteWordUncached, acquireAtomicUncached) - val hasDataTypeList = List(acquireWriteUncached, acquireWriteWordUncached, acquireAtomicUncached) + + val uncachedAcquireTypeList = List(acquireReadUncached, acquireWriteUncached, acquireReadWordUncached, acquireWriteWordUncached, acquireAtomicUncached) + val hasDataAcquireTypeList = List(acquireWriteUncached, acquireWriteWordUncached, acquireAtomicUncached) + val hasDataReleaseTypeList = List(releaseVoluntaryInvalidateData, releaseInvalidateData, releaseDowngradeData, releaseCopyData) + val hasDataGrantTypeList = List(grantReadShared, grantReadExclusive, grantReadUncached, grantReadWordUncached, grantAtomicUncached) def isHit (cmd: Bits, state: UFix): Bool = { val (read, write) = cpuCmdToRW(cmd) @@ -665,6 +661,7 @@ class MESICoherence extends CoherencePolicyWithUncached { def getVoluntaryWriteback(addr: UFix, client_id: UFix, master_id: UFix) = Release(releaseVoluntaryInvalidateData, addr, client_id, master_id) def isUncachedReadTransaction(acq: Acquire) = acq.a_type === acquireReadUncached def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData + def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck def getAcquireTypeOnPrimaryMiss(cmd: Bits, state: UFix): UFix = { val (read, write) = cpuCmdToRW(cmd) @@ -674,11 +671,10 @@ class MESICoherence extends CoherencePolicyWithUncached { val (read, write) = cpuCmdToRW(cmd) Mux(write, acquireReadExclusive, outstanding.a_type) } - def getAcquireTypeOnCacheControl(cmd: Bits): Bits = acquireWriteUncached - def getAcquireTypeOnWriteback(): Bits = getAcquireTypeOnCacheControl(M_INV) + def getReleaseTypeOnCacheControl(cmd: Bits): Bits = releaseVoluntaryInvalidateData // TODO + def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV) - def newRelease (incoming: Probe, state: UFix): Release = { - val reply = new Release + def newRelease (incoming: Probe, state: UFix, id: UFix): Release = { val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array( probeInvalidate -> releaseInvalidateData, probeDowngrade -> releaseDowngradeData, @@ -689,24 +685,16 @@ class MESICoherence extends CoherencePolicyWithUncached { probeDowngrade -> releaseDowngradeAck, probeCopy -> releaseCopyAck )) - reply.r_type := Mux(needsWriteback(state), with_data, without_data) - reply.master_xact_id := incoming.master_xact_id - reply + Release( Mux(needsWriteback(state), with_data, without_data), incoming.addr, id, incoming.master_xact_id) } - def messageHasData (reply: Release): Bool = { - (reply.r_type === releaseInvalidateData || - reply.r_type === releaseDowngradeData || - reply.r_type === releaseCopyData) - } - def messageHasData (acq: Acquire): Bool = hasDataTypeList.map(t => acq.a_type === t).reduceLeft(_||_) - def messageHasData (reply: Grant): Bool = { - (reply.g_type != grantWriteUncached && reply.g_type != grantReadExclusiveAck && reply.g_type != grantWriteWordUncached) - } + def messageHasData (rel: Release): Bool = uFixListContains(hasDataReleaseTypeList, rel.r_type) + def messageHasData (acq: Acquire): Bool = uFixListContains(hasDataAcquireTypeList, acq.a_type) + def messageHasData (grant: Grant): Bool = uFixListContains(hasDataGrantTypeList, grant.g_type) def messageUpdatesDataArray (reply: Grant): Bool = { (reply.g_type === grantReadShared || reply.g_type === grantReadExclusive) } - def messageIsUncached(acq: Acquire): Bool = uncachedTypeList.map(t => acq.a_type === t).reduceLeft(_||_) + def messageIsUncached(acq: Acquire): Bool = uFixListContains(uncachedAcquireTypeList, acq.a_type) def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2) @@ -752,6 +740,8 @@ class MESICoherence extends CoherencePolicyWithUncached { def requiresAck(grant: Grant) = Bool(true) def requiresAck(release: Release) = Bool(false) + + def pendingVoluntaryReleaseIsSufficient(r_type: UFix, p_type: UFix): Bool = (r_type === releaseVoluntaryInvalidateData) } class MigratoryCoherence extends CoherencePolicyWithUncached { @@ -762,10 +752,11 @@ class MigratoryCoherence extends CoherencePolicyWithUncached { val grantVoluntaryAck :: grantReadShared :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadExclusiveAck :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: grantReadMigratory :: Nil = Enum(10){ UFix() } val probeInvalidate :: probeDowngrade :: probeCopy :: probeInvalidateOthers :: Nil = Enum(4){ UFix() } val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: releaseDowngradeDataMigratory :: releaseDowngradeAckHasCopy :: releaseInvalidateDataMigratory :: releaseInvalidateAckMigratory :: Nil = Enum(11){ UFix() } - val uncachedTypeList = List(acquireReadUncached, acquireWriteUncached, acquireReadWordUncached, acquireWriteWordUncached, acquireAtomicUncached) - val hasDataTypeList = List(acquireWriteUncached, acquireWriteWordUncached, acquireAtomicUncached) - def uFixListContains(list: List[UFix], elem: UFix): Bool = list.map(elem === _).reduceLeft(_||_) + val uncachedAcquireTypeList = List(acquireReadUncached, acquireWriteUncached, acquireReadWordUncached, acquireWriteWordUncached, acquireAtomicUncached) + val hasDataAcquireTypeList = List(acquireWriteUncached, acquireWriteWordUncached, acquireAtomicUncached) + val hasDataGrantTypeList = List(grantReadShared, grantReadExclusive, grantReadUncached, grantReadMigratory, grantReadWordUncached, grantAtomicUncached) + val hasDataReleaseTypeList = List(releaseVoluntaryInvalidateData, releaseInvalidateData, releaseDowngradeData, releaseCopyData, releaseInvalidateDataMigratory, releaseDowngradeDataMigratory) def isHit (cmd: Bits, state: UFix): Bool = { val (read, write) = cpuCmdToRW(cmd) @@ -844,6 +835,7 @@ class MigratoryCoherence extends CoherencePolicyWithUncached { def getVoluntaryWriteback(addr: UFix, client_id: UFix, master_id: UFix) = Release(releaseVoluntaryInvalidateData, addr, client_id, master_id) def isUncachedReadTransaction(acq: Acquire) = acq.a_type === acquireReadUncached def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData + def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck def getAcquireTypeOnPrimaryMiss(cmd: Bits, state: UFix): UFix = { val (read, write) = cpuCmdToRW(cmd) @@ -853,12 +845,11 @@ class MigratoryCoherence extends CoherencePolicyWithUncached { val (read, write) = cpuCmdToRW(cmd) Mux(write, Mux(state === tileInvalid, acquireReadExclusive, acquireInvalidateOthers), outstanding.a_type) } - def getAcquireTypeOnCacheControl(cmd: Bits): Bits = acquireWriteUncached - def getAcquireTypeOnWriteback(): Bits = getAcquireTypeOnCacheControl(M_INV) + def getReleaseTypeOnCacheControl(cmd: Bits): Bits = releaseVoluntaryInvalidateData // TODO + def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV) - def newRelease (incoming: Probe, state: UFix): Release = { + def newRelease (incoming: Probe, state: UFix, id: UFix): Release = { Assert( incoming.p_type === probeInvalidateOthers && needsWriteback(state), "Bad probe request type, should be impossible.") - val reply = new Release() val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array( probeInvalidate -> Mux(uFixListContains(List(tileExclusiveDirty, tileMigratoryDirty), state), releaseInvalidateDataMigratory, releaseInvalidateData), @@ -871,22 +862,16 @@ class MigratoryCoherence extends CoherencePolicyWithUncached { probeDowngrade -> Mux(state != tileInvalid, releaseDowngradeAckHasCopy, releaseDowngradeAck), probeCopy -> releaseCopyAck )) - reply.r_type := Mux(needsWriteback(state), with_data, without_data) - reply.master_xact_id := incoming.master_xact_id - reply + Release( Mux(needsWriteback(state), with_data, without_data), incoming.addr, id, incoming.master_xact_id) } - def messageHasData (reply: Release): Bool = { - uFixListContains(List(releaseInvalidateData, releaseDowngradeData, releaseCopyData, releaseInvalidateDataMigratory, releaseDowngradeDataMigratory), reply.r_type) - } - def messageHasData (acq: Acquire): Bool = uFixListContains(hasDataTypeList, acq.a_type) - def messageHasData (reply: Grant): Bool = { - uFixListContains(List(grantReadShared, grantReadExclusive, grantReadUncached, grantReadMigratory, grantReadWordUncached, grantAtomicUncached), reply.g_type) - } + def messageHasData (acq: Acquire): Bool = uFixListContains(hasDataAcquireTypeList, acq.a_type) + def messageHasData (rel: Release): Bool = uFixListContains(hasDataReleaseTypeList, rel.r_type) + def messageHasData (grant: Grant): Bool = uFixListContains(hasDataGrantTypeList, grant.g_type) def messageUpdatesDataArray (reply: Grant): Bool = { uFixListContains(List(grantReadShared, grantReadExclusive, grantReadMigratory), reply.g_type) } - def messageIsUncached(acq: Acquire): Bool = uFixListContains(uncachedTypeList, acq.a_type) + def messageIsUncached(acq: Acquire): Bool = uFixListContains(uncachedAcquireTypeList, acq.a_type) def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2) @@ -933,4 +918,6 @@ class MigratoryCoherence extends CoherencePolicyWithUncached { } def requiresAck(grant: Grant) = Bool(true) def requiresAck(release: Release) = Bool(false) + + def pendingVoluntaryReleaseIsSufficient(r_type: UFix, p_type: UFix): Bool = (r_type === releaseVoluntaryInvalidateData) }