1
0

Major tilelink revision for uncached message types

This commit is contained in:
Henry Cook 2014-11-11 17:36:55 -08:00
parent 35553cc0b7
commit 82155f333e
6 changed files with 351 additions and 435 deletions

View File

@ -120,59 +120,48 @@ abstract class CoherencePolicy(val dir: () => DirectoryRepresentation) {
def getReleaseTypeOnVoluntaryWriteback(): UInt def getReleaseTypeOnVoluntaryWriteback(): UInt
def getReleaseTypeOnProbe(p: Probe, m: ClientMetadata): UInt def getReleaseTypeOnProbe(p: Probe, m: ClientMetadata): UInt
def getGrantType(a: Acquire, m: MasterMetadata): UInt def getGrantType(a: Acquire, m: MasterMetadata): UInt
def getGrantType(r: Release, m: MasterMetadata): UInt def getGrantTypeOnVoluntaryWriteback(m: MasterMetadata): UInt
//def getGrantType(a: Acquire) = getGrantType(a, new NullRepresentation) // TODO
//def getGrantType(r: Release) = getGrantType(r, new NullRepresentation)
def messageHasData (rel: SourcedMessage): Bool def messageHasData(rel: SourcedMessage): Bool
def messageUpdatesDataArray (reply: Grant): Bool def messageUpdatesDataArray(g: Grant): Bool
def messageIsUncached(acq: Acquire): Bool
def isCoherenceConflict(addr1: UInt, addr2: UInt): Bool def isCoherenceConflict(addr1: UInt, addr2: UInt): Bool
def isVoluntary(rel: Release): Bool def isVoluntary(rel: Release): Bool
def isVoluntary(gnt: Grant): Bool def isVoluntary(gnt: Grant): Bool
def requiresOuterRead(a_type: UInt, m: MasterMetadata): Bool def requiresOuterRead(acq: Acquire, m: MasterMetadata): Bool
def requiresOuterWrite(a_type: UInt, m: MasterMetadata): Bool def requiresOuterWrite(acq: Acquire, m: MasterMetadata): Bool
def requiresOuterRead(a_type: UInt): Bool def requiresSelfProbe(a: Acquire): Bool
def requiresOuterWrite(a_type: UInt): Bool def requiresAckForGrant(g: Grant): Bool
def requiresSelfProbe(a_type: UInt): Bool def requiresAckForRelease(r: Release): Bool
def requiresAckForGrant(g_type: UInt): Bool
def requiresAckForRelease(r_type: UInt): Bool
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool
def getGrantTypeForUncached(a: Acquire, m: MasterMetadata): UInt = {
MuxLookup(a.a_type, Grant.uncachedRead, Array(
Acquire.uncachedRead -> Grant.uncachedRead,
Acquire.uncachedWrite -> Grant.uncachedWrite,
Acquire.uncachedAtomic -> Grant.uncachedAtomic
))
}
} }
trait UncachedTransactions { class MICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicy(dir) {
def getUncachedReadAcquireType: UInt
def getUncachedWriteAcquireType: UInt
def getUncachedReadWordAcquireType: UInt
def getUncachedWriteWordAcquireType: UInt
def getUncachedAtomicAcquireType: UInt
def isUncachedReadTransaction(acq: Acquire): Bool
}
abstract class CoherencePolicyWithUncached(dir: () => DirectoryRepresentation) extends CoherencePolicy(dir)
with UncachedTransactions
class MICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyWithUncached(dir) {
def nClientStates = 2 def nClientStates = 2
def nMasterStates = 2 def nMasterStates = 2
def nAcquireTypes = 6 def nAcquireTypes = 1
def nProbeTypes = 2 def nProbeTypes = 2
def nReleaseTypes = 5 def nReleaseTypes = 5
def nGrantTypes = 7 def nGrantTypes = 2
val clientInvalid :: clientValid :: Nil = Enum(UInt(), nClientStates) val clientInvalid :: clientValid :: Nil = Enum(UInt(), nClientStates)
val masterInvalid :: masterValid :: Nil = Enum(UInt(), nMasterStates) val masterInvalid :: masterValid :: Nil = Enum(UInt(), nMasterStates)
val acquireReadExclusive :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: Nil = Enum(UInt(), nAcquireTypes) val acquireReadExclusive :: Nil = Enum(UInt(), nAcquireTypes)
val probeInvalidate :: probeCopy :: Nil = Enum(UInt(), nProbeTypes) val probeInvalidate :: probeCopy :: Nil = Enum(UInt(), nProbeTypes)
val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseCopyData :: releaseInvalidateAck :: releaseCopyAck :: Nil = Enum(UInt(), nReleaseTypes) val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseCopyData :: releaseInvalidateAck :: releaseCopyAck :: Nil = Enum(UInt(), nReleaseTypes)
val grantVoluntaryAck :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: Nil = Enum(UInt(), nGrantTypes) val grantVoluntaryAck :: grantReadExclusive :: Nil = Enum(UInt(), nGrantTypes)
val uncachedAcquireTypeVec = Vec(acquireReadUncached, acquireWriteUncached, acquireReadWordUncached, acquireWriteWordUncached, acquireAtomicUncached)
val hasDataAcquireTypeVec = Vec(acquireWriteUncached, acquireWriteWordUncached, acquireAtomicUncached)
val hasDataReleaseTypeVec = Vec(releaseVoluntaryInvalidateData, releaseInvalidateData, releaseCopyData) val hasDataReleaseTypeVec = Vec(releaseVoluntaryInvalidateData, releaseInvalidateData, releaseCopyData)
val hasDataGrantTypeVec = Vec(grantReadExclusive, grantReadUncached, grantReadWordUncached, grantAtomicUncached) val hasDataGrantTypeVec = Vec(grantReadExclusive)
def isHit (cmd: UInt, m: ClientMetadata): Bool = isValid(m) def isHit (cmd: UInt, m: ClientMetadata): Bool = isValid(m)
def isValid (m: ClientMetadata): Bool = m.state != clientInvalid def isValid (m: ClientMetadata): Bool = m.state != clientInvalid
@ -197,15 +186,8 @@ class MICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyWit
M_CLN -> clientValid M_CLN -> clientValid
)))(this) )))(this)
def clientMetadataOnFlush = clientMetadataOnCacheControl(M_INV) def clientMetadataOnFlush = clientMetadataOnCacheControl(M_INV)
def clientMetadataOnGrant(incoming: Grant, outstanding: Acquire) = ClientMetadata( def clientMetadataOnGrant(incoming: Grant, outstanding: Acquire) =
MuxLookup(incoming.g_type, clientInvalid, Array( ClientMetadata(Mux(incoming.uncached, clientInvalid, clientValid))(this)
grantReadExclusive -> clientValid,
grantReadUncached -> clientInvalid,
grantWriteUncached -> clientInvalid,
grantReadWordUncached -> clientInvalid,
grantWriteWordUncached -> clientInvalid,
grantAtomicUncached -> clientInvalid
)))(this)
def clientMetadataOnProbe(incoming: Probe, m: ClientMetadata) = ClientMetadata( def clientMetadataOnProbe(incoming: Probe, m: ClientMetadata) = ClientMetadata(
MuxLookup(incoming.p_type, m.state, Array( MuxLookup(incoming.p_type, m.state, Array(
probeInvalidate -> clientInvalid, probeInvalidate -> clientInvalid,
@ -225,14 +207,8 @@ class MICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyWit
)) ))
} }
def getUncachedReadAcquireType = acquireReadUncached
def getUncachedWriteAcquireType = acquireWriteUncached
def getUncachedReadWordAcquireType = acquireReadWordUncached
def getUncachedWriteWordAcquireType = acquireWriteWordUncached
def getUncachedAtomicAcquireType = acquireAtomicUncached
def isUncachedReadTransaction(acq: Acquire) = acq.a_type === acquireReadUncached
def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData
def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck def isVoluntary(gnt: Grant) = !gnt.uncached && gnt.g_type === grantVoluntaryAck
def getAcquireTypeOnPrimaryMiss(cmd: UInt, m: ClientMetadata): UInt = acquireReadExclusive def getAcquireTypeOnPrimaryMiss(cmd: UInt, m: ClientMetadata): UInt = acquireReadExclusive
def getAcquireTypeOnSecondaryMiss(cmd: UInt, m: ClientMetadata, outstanding: Acquire): UInt = acquireReadExclusive def getAcquireTypeOnSecondaryMiss(cmd: UInt, m: ClientMetadata, outstanding: Acquire): UInt = acquireReadExclusive
@ -251,80 +227,61 @@ class MICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyWit
} }
def messageHasData(msg: SourcedMessage) = msg match { def messageHasData(msg: SourcedMessage) = msg match {
case acq: Acquire => hasDataAcquireTypeVec.contains(acq.a_type) case acq: Acquire => Mux(acq.uncached, Acquire.hasData(acq.a_type), Bool(false))
case grant: Grant => hasDataGrantTypeVec.contains(grant.g_type) case gnt: Grant => Mux(gnt.uncached, Grant.hasData(gnt.g_type), hasDataGrantTypeVec.contains(gnt.g_type))
case rel: Release => hasDataReleaseTypeVec.contains(rel.r_type) case rel: Release => hasDataReleaseTypeVec.contains(rel.r_type)
case _ => Bool(false) case _ => Bool(false)
} }
def messageUpdatesDataArray (reply: Grant): Bool = { def messageUpdatesDataArray(g: Grant): Bool = {
(reply.g_type === grantReadExclusive) Mux(g.uncached, Bool(false),
(g.g_type === grantReadExclusive))
} }
def messageIsUncached(acq: Acquire): Bool = uncachedAcquireTypeVec.contains(acq.a_type)
def isCoherenceConflict(addr1: UInt, addr2: UInt): Bool = (addr1 === addr2) def isCoherenceConflict(addr1: UInt, addr2: UInt): Bool = (addr1 === addr2)
def getGrantType(a: Acquire, m: MasterMetadata): UInt = { def getGrantType(a: Acquire, m: MasterMetadata): UInt =
MuxLookup(a.a_type, grantReadUncached, Array( Mux(a.uncached, getGrantTypeForUncached(a, m), grantReadExclusive)
acquireReadExclusive -> grantReadExclusive,
acquireReadUncached -> grantReadUncached,
acquireWriteUncached -> grantWriteUncached,
acquireReadWordUncached -> grantReadWordUncached,
acquireWriteWordUncached -> grantWriteWordUncached,
acquireAtomicUncached -> grantAtomicUncached
))
}
def getGrantType(r: Release, m: MasterMetadata): UInt = { def getGrantTypeOnVoluntaryWriteback(m: MasterMetadata): UInt = grantVoluntaryAck
MuxLookup(r.r_type, grantReadUncached, Array(
releaseVoluntaryInvalidateData -> grantVoluntaryAck
))
}
def getProbeType(a: Acquire, m: MasterMetadata): UInt = { def getProbeType(a: Acquire, m: MasterMetadata): UInt = {
MuxLookup(a.a_type, probeCopy, Array( Mux(a.uncached,
acquireReadExclusive -> probeInvalidate, MuxLookup(a.a_type, probeCopy, Array(
acquireReadUncached -> probeCopy, Acquire.uncachedRead -> probeCopy,
acquireWriteUncached -> probeInvalidate, Acquire.uncachedWrite -> probeInvalidate,
acquireReadWordUncached -> probeCopy, Acquire.uncachedAtomic -> probeInvalidate
acquireWriteWordUncached -> probeInvalidate, )), probeInvalidate)
acquireAtomicUncached -> probeInvalidate
))
} }
def requiresOuterRead(a_type: UInt) = { def requiresOuterRead(acq: Acquire, m: MasterMetadata) =
(a_type != acquireWriteUncached) Mux(acq.uncached, Acquire.requiresOuterRead(acq.a_type), Bool(true))
} def requiresOuterWrite(acq: Acquire, m: MasterMetadata) =
def requiresOuterWrite(a_type: UInt) = { Mux(acq.uncached, Acquire.requiresOuterWrite(acq.a_type), Bool(false))
(a_type === acquireWriteUncached)
} def requiresAckForGrant(g: Grant) = g.uncached || g.g_type != grantVoluntaryAck
def requiresOuterRead(a_type: UInt, m: MasterMetadata) = requiresOuterRead(a_type) def requiresAckForRelease(r: Release) = Bool(false)
def requiresOuterWrite(a_type: UInt, m: MasterMetadata) = requiresOuterWrite(a_type) def requiresSelfProbe(a: Acquire) = a.uncached && a.a_type === Acquire.uncachedRead
def requiresAckForGrant(g_type: UInt) = g_type != grantVoluntaryAck
def requiresAckForRelease(r_type: UInt) = Bool(false)
def requiresSelfProbe(a_type: UInt) = Bool(false)
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData) def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData)
} }
class MEICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyWithUncached(dir) { class MEICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicy(dir) {
def nClientStates = 3 def nClientStates = 3
def nMasterStates = 2 def nMasterStates = 2
def nAcquireTypes = 7 def nAcquireTypes = 2
def nProbeTypes = 3 def nProbeTypes = 3
def nReleaseTypes = 7 def nReleaseTypes = 7
def nGrantTypes = 8 def nGrantTypes = 2
val clientInvalid :: clientExclusiveClean :: clientExclusiveDirty :: Nil = Enum(UInt(), nClientStates) val clientInvalid :: clientExclusiveClean :: clientExclusiveDirty :: Nil = Enum(UInt(), nClientStates)
val masterInvalid :: masterValid :: Nil = Enum(UInt(), nMasterStates) val masterInvalid :: masterValid :: Nil = Enum(UInt(), nMasterStates)
val acquireReadExclusiveClean :: acquireReadExclusiveDirty :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: Nil = Enum(UInt(), nAcquireTypes) val acquireReadExclusiveClean :: acquireReadExclusiveDirty :: Nil = Enum(UInt(), nAcquireTypes)
val probeInvalidate :: probeDowngrade :: probeCopy :: Nil = Enum(UInt(), nProbeTypes) val probeInvalidate :: probeDowngrade :: probeCopy :: Nil = Enum(UInt(), nProbeTypes)
val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(UInt(), nReleaseTypes) val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(UInt(), nReleaseTypes)
val grantVoluntaryAck :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadExclusiveAck :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: Nil = Enum(UInt(), nGrantTypes) val grantVoluntaryAck :: grantReadExclusive :: Nil = Enum(UInt(), nGrantTypes)
val uncachedAcquireTypeVec = Vec(acquireReadUncached, acquireWriteUncached, acquireReadWordUncached, acquireWriteWordUncached, acquireAtomicUncached)
val hasDataAcquireTypeVec = Vec(acquireWriteUncached, acquireWriteWordUncached, acquireAtomicUncached)
val hasDataReleaseTypeVec = Vec(releaseVoluntaryInvalidateData, releaseInvalidateData, releaseDowngradeData, releaseCopyData) val hasDataReleaseTypeVec = Vec(releaseVoluntaryInvalidateData, releaseInvalidateData, releaseDowngradeData, releaseCopyData)
val hasDataGrantTypeVec = Vec(grantReadExclusive, grantReadUncached, grantReadWordUncached, grantAtomicUncached) val hasDataGrantTypeVec = Vec(grantReadExclusive)
def isHit (cmd: UInt, m: ClientMetadata) = isValid(m) def isHit (cmd: UInt, m: ClientMetadata) = isValid(m)
def isValid (m: ClientMetadata) = m.state != clientInvalid def isValid (m: ClientMetadata) = m.state != clientInvalid
@ -332,7 +289,7 @@ class MEICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyWi
def isValid (m: MasterMetadata) = m.state != masterInvalid def isValid (m: MasterMetadata) = m.state != masterInvalid
def needsTransactionOnSecondaryMiss(cmd: UInt, outstanding: Acquire): Bool = { def needsTransactionOnSecondaryMiss(cmd: UInt, outstanding: Acquire): Bool = {
(isRead(cmd) && messageIsUncached(outstanding)) || (isRead(cmd) && outstanding.uncached) ||
(isWriteIntent(cmd) && (outstanding.a_type != acquireReadExclusiveDirty)) (isWriteIntent(cmd) && (outstanding.a_type != acquireReadExclusiveDirty))
} }
def needsTransactionOnCacheControl(cmd: UInt, m: ClientMetadata): Bool = { def needsTransactionOnCacheControl(cmd: UInt, m: ClientMetadata): Bool = {
@ -355,16 +312,9 @@ class MEICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyWi
)))(this) )))(this)
def clientMetadataOnFlush() = clientMetadataOnCacheControl(M_INV) def clientMetadataOnFlush() = clientMetadataOnCacheControl(M_INV)
def clientMetadataOnGrant(incoming: Grant, outstanding: Acquire) = ClientMetadata( def clientMetadataOnGrant(incoming: Grant, outstanding: Acquire) = ClientMetadata(
MuxLookup(incoming.g_type, clientInvalid, Array( Mux(incoming.uncached, clientInvalid,
grantReadExclusive -> Mux(outstanding.a_type === acquireReadExclusiveDirty, Mux(outstanding.a_type === acquireReadExclusiveDirty, clientExclusiveDirty,
clientExclusiveDirty, clientExclusiveClean), clientExclusiveClean)))(this)
grantReadExclusiveAck -> clientExclusiveDirty,
grantReadUncached -> clientInvalid,
grantWriteUncached -> clientInvalid,
grantReadWordUncached -> clientInvalid,
grantWriteWordUncached -> clientInvalid,
grantAtomicUncached -> clientInvalid
)))(this)
def clientMetadataOnProbe(incoming: Probe, m: ClientMetadata) = ClientMetadata( def clientMetadataOnProbe(incoming: Probe, m: ClientMetadata) = ClientMetadata(
MuxLookup(incoming.p_type, m.state, Array( MuxLookup(incoming.p_type, m.state, Array(
probeInvalidate -> clientInvalid, probeInvalidate -> clientInvalid,
@ -387,14 +337,8 @@ class MEICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyWi
)) ))
} }
def getUncachedReadAcquireType = acquireReadUncached
def getUncachedWriteAcquireType = acquireWriteUncached
def getUncachedReadWordAcquireType = acquireReadWordUncached
def getUncachedWriteWordAcquireType = acquireWriteWordUncached
def getUncachedAtomicAcquireType = acquireAtomicUncached
def isUncachedReadTransaction(acq: Acquire) = acq.a_type === acquireReadUncached
def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData
def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck def isVoluntary(gnt: Grant) = !gnt.uncached && gnt.g_type === grantVoluntaryAck
def getAcquireTypeOnPrimaryMiss(cmd: UInt, m: ClientMetadata): UInt = { def getAcquireTypeOnPrimaryMiss(cmd: UInt, m: ClientMetadata): UInt = {
Mux(isWriteIntent(cmd), acquireReadExclusiveDirty, acquireReadExclusiveClean) Mux(isWriteIntent(cmd), acquireReadExclusiveDirty, acquireReadExclusiveClean)
@ -419,83 +363,62 @@ class MEICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyWi
} }
def messageHasData(msg: SourcedMessage) = msg match { def messageHasData(msg: SourcedMessage) = msg match {
case acq: Acquire => hasDataAcquireTypeVec.contains(acq.a_type) case acq: Acquire => Mux(acq.uncached, Acquire.hasData(acq.a_type), Bool(false))
case grant: Grant => hasDataGrantTypeVec.contains(grant.g_type) case gnt: Grant => Mux(gnt.uncached, Grant.hasData(gnt.g_type), hasDataGrantTypeVec.contains(gnt.g_type))
case rel: Release => hasDataReleaseTypeVec.contains(rel.r_type) case rel: Release => hasDataReleaseTypeVec.contains(rel.r_type)
case _ => Bool(false) case _ => Bool(false)
} }
def messageUpdatesDataArray (reply: Grant): Bool = { def messageUpdatesDataArray(g: Grant): Bool = {
(reply.g_type === grantReadExclusive) Mux(g.uncached, Bool(false),
(g.g_type === grantReadExclusive))
} }
def messageIsUncached(acq: Acquire): Bool = uncachedAcquireTypeVec.contains(acq.a_type)
def isCoherenceConflict(addr1: UInt, addr2: UInt): Bool = (addr1 === addr2) def isCoherenceConflict(addr1: UInt, addr2: UInt): Bool = (addr1 === addr2)
def getGrantType(a: Acquire, m: MasterMetadata): UInt = { def getGrantType(a: Acquire, m: MasterMetadata): UInt = {
MuxLookup(a.a_type, grantReadUncached, Array( Mux(a.uncached, getGrantTypeForUncached(a, m), grantReadExclusive)
acquireReadExclusiveClean -> grantReadExclusive,
acquireReadExclusiveDirty -> grantReadExclusive,
acquireReadUncached -> grantReadUncached,
acquireWriteUncached -> grantWriteUncached,
acquireReadWordUncached -> grantReadWordUncached,
acquireWriteWordUncached -> grantWriteWordUncached,
acquireAtomicUncached -> grantAtomicUncached
))
} }
def getGrantType(r: Release, m: MasterMetadata): UInt = { def getGrantTypeOnVoluntaryWriteback(m: MasterMetadata): UInt = grantVoluntaryAck
MuxLookup(r.r_type, grantReadUncached, Array(
releaseVoluntaryInvalidateData -> grantVoluntaryAck
))
}
def getProbeType(a: Acquire, m: MasterMetadata): UInt = { def getProbeType(a: Acquire, m: MasterMetadata): UInt = {
MuxLookup(a.a_type, probeCopy, Array( Mux(a.uncached,
acquireReadExclusiveClean -> probeInvalidate, MuxLookup(a.a_type, probeCopy, Array(
acquireReadExclusiveDirty -> probeInvalidate, Acquire.uncachedRead -> probeCopy,
acquireReadUncached -> probeCopy, Acquire.uncachedWrite -> probeInvalidate,
acquireWriteUncached -> probeInvalidate, Acquire.uncachedAtomic -> probeInvalidate
acquireReadWordUncached -> probeCopy, )), probeInvalidate)
acquireWriteWordUncached -> probeInvalidate,
acquireAtomicUncached -> probeInvalidate
))
} }
def requiresOuterRead(a_type: UInt) = { def requiresOuterRead(acq: Acquire, m: MasterMetadata) =
(a_type != acquireWriteUncached) Mux(acq.uncached, Acquire.requiresOuterRead(acq.a_type), Bool(true))
} def requiresOuterWrite(acq: Acquire, m: MasterMetadata) =
def requiresOuterWrite(a_type: UInt) = { Mux(acq.uncached, Acquire.requiresOuterWrite(acq.a_type), Bool(false))
(a_type === acquireWriteUncached)
} def requiresAckForGrant(g: Grant) = g.uncached || g.g_type != grantVoluntaryAck
def requiresOuterRead(a_type: UInt, m: MasterMetadata) = requiresOuterRead(a_type) def requiresAckForRelease(r: Release) = Bool(false)
def requiresOuterWrite(a_type: UInt, m: MasterMetadata) = requiresOuterWrite(a_type) def requiresSelfProbe(a: Acquire) = a.uncached && a.a_type === Acquire.uncachedRead
def requiresAckForGrant(g_type: UInt) = g_type != grantVoluntaryAck
def requiresAckForRelease(r_type: UInt) = Bool(false)
def requiresSelfProbe(a_type: UInt) = Bool(false)
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData) def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData)
} }
class MSICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyWithUncached(dir) { class MSICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicy(dir) {
def nClientStates = 3 def nClientStates = 3
def nMasterStates = 3 def nMasterStates = 3
def nAcquireTypes = 7 def nAcquireTypes = 2
def nProbeTypes = 3 def nProbeTypes = 3
def nReleaseTypes = 7 def nReleaseTypes = 7
def nGrantTypes = 9 def nGrantTypes = 3
val clientInvalid :: clientShared :: clientExclusiveDirty :: Nil = Enum(UInt(), nClientStates) val clientInvalid :: clientShared :: clientExclusiveDirty :: Nil = Enum(UInt(), nClientStates)
val masterInvalid :: masterShared :: masterExclusive :: Nil = Enum(UInt(), nMasterStates) val masterInvalid :: masterShared :: masterExclusive :: Nil = Enum(UInt(), nMasterStates)
val acquireReadShared :: acquireReadExclusive :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: Nil = Enum(UInt(), nAcquireTypes) val acquireReadShared :: acquireReadExclusive :: Nil = Enum(UInt(), nAcquireTypes)
val probeInvalidate :: probeDowngrade :: probeCopy :: Nil = Enum(UInt(), nProbeTypes) val probeInvalidate :: probeDowngrade :: probeCopy :: Nil = Enum(UInt(), nProbeTypes)
val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(UInt(), nReleaseTypes) val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(UInt(), nReleaseTypes)
val grantVoluntaryAck :: grantReadShared :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadExclusiveAck :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: Nil = Enum(UInt(), nGrantTypes) val grantVoluntaryAck :: grantReadShared :: grantReadExclusive :: Nil = Enum(UInt(), nGrantTypes)
val uncachedAcquireTypeVec = Vec(acquireReadUncached, acquireWriteUncached, acquireReadWordUncached, acquireWriteWordUncached, acquireAtomicUncached)
val hasDataAcquireTypeVec = Vec(acquireWriteUncached, acquireWriteWordUncached, acquireAtomicUncached)
val hasDataReleaseTypeVec = Vec(releaseVoluntaryInvalidateData, releaseInvalidateData, releaseDowngradeData, releaseCopyData) val hasDataReleaseTypeVec = Vec(releaseVoluntaryInvalidateData, releaseInvalidateData, releaseDowngradeData, releaseCopyData)
val hasDataGrantTypeVec = Vec(grantReadShared, grantReadExclusive, grantReadUncached, grantReadWordUncached, grantAtomicUncached) val hasDataGrantTypeVec = Vec(grantReadShared, grantReadExclusive)
def isHit (cmd: UInt, m: ClientMetadata): Bool = { def isHit (cmd: UInt, m: ClientMetadata): Bool = {
Mux(isWriteIntent(cmd), (m.state === clientExclusiveDirty), Mux(isWriteIntent(cmd), (m.state === clientExclusiveDirty),
@ -508,7 +431,7 @@ class MSICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyWi
def isValid (m: MasterMetadata) = m.state != masterInvalid def isValid (m: MasterMetadata) = m.state != masterInvalid
def needsTransactionOnSecondaryMiss(cmd: UInt, outstanding: Acquire): Bool = { def needsTransactionOnSecondaryMiss(cmd: UInt, outstanding: Acquire): Bool = {
(isRead(cmd) && messageIsUncached(outstanding)) || (isRead(cmd) && outstanding.uncached) ||
(isWriteIntent(cmd) && (outstanding.a_type != acquireReadExclusive)) (isWriteIntent(cmd) && (outstanding.a_type != acquireReadExclusive))
} }
def needsTransactionOnCacheControl(cmd: UInt, m: ClientMetadata): Bool = { def needsTransactionOnCacheControl(cmd: UInt, m: ClientMetadata): Bool = {
@ -530,16 +453,9 @@ class MSICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyWi
)))(this) )))(this)
def clientMetadataOnFlush() = clientMetadataOnCacheControl(M_INV) def clientMetadataOnFlush() = clientMetadataOnCacheControl(M_INV)
def clientMetadataOnGrant(incoming: Grant, outstanding: Acquire) = ClientMetadata( def clientMetadataOnGrant(incoming: Grant, outstanding: Acquire) = ClientMetadata(
MuxLookup(incoming.g_type, clientInvalid, Array( Mux(incoming.uncached, clientInvalid,
grantReadShared -> clientShared, Mux(incoming.g_type === grantReadShared, clientShared,
grantReadExclusive -> clientExclusiveDirty, clientExclusiveDirty)))(this)
grantReadExclusiveAck -> clientExclusiveDirty,
grantReadUncached -> clientInvalid,
grantWriteUncached -> clientInvalid,
grantReadWordUncached -> clientInvalid,
grantWriteWordUncached -> clientInvalid,
grantAtomicUncached -> clientInvalid
)))(this)
def clientMetadataOnProbe(incoming: Probe, m: ClientMetadata) = ClientMetadata( def clientMetadataOnProbe(incoming: Probe, m: ClientMetadata) = ClientMetadata(
MuxLookup(incoming.p_type, m.state, Array( MuxLookup(incoming.p_type, m.state, Array(
probeInvalidate -> clientInvalid, probeInvalidate -> clientInvalid,
@ -564,14 +480,8 @@ class MSICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyWi
)) ))
} }
def getUncachedReadAcquireType = acquireReadUncached
def getUncachedWriteAcquireType = acquireWriteUncached
def getUncachedReadWordAcquireType = acquireReadWordUncached
def getUncachedWriteWordAcquireType = acquireWriteWordUncached
def getUncachedAtomicAcquireType = acquireAtomicUncached
def isUncachedReadTransaction(acq: Acquire) = acq.a_type === acquireReadUncached
def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData
def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck def isVoluntary(gnt: Grant) = !gnt.uncached && gnt.g_type === grantVoluntaryAck
def getAcquireTypeOnPrimaryMiss(cmd: UInt, m: ClientMetadata): UInt = { def getAcquireTypeOnPrimaryMiss(cmd: UInt, m: ClientMetadata): UInt = {
Mux(isWriteIntent(cmd), acquireReadExclusive, acquireReadShared) Mux(isWriteIntent(cmd), acquireReadExclusive, acquireReadShared)
@ -596,79 +506,69 @@ class MSICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyWi
} }
def messageHasData(msg: SourcedMessage) = msg match { def messageHasData(msg: SourcedMessage) = msg match {
case acq: Acquire => hasDataAcquireTypeVec.contains(acq.a_type) case acq: Acquire => Mux(acq.uncached, Acquire.hasData(acq.a_type), Bool(false))
case grant: Grant => hasDataGrantTypeVec.contains(grant.g_type) case gnt: Grant => Mux(gnt.uncached, Grant.hasData(gnt.g_type), hasDataGrantTypeVec.contains(gnt.g_type))
case rel: Release => hasDataReleaseTypeVec.contains(rel.r_type) case rel: Release => hasDataReleaseTypeVec.contains(rel.r_type)
case _ => Bool(false) case _ => Bool(false)
} }
def messageUpdatesDataArray (reply: Grant): Bool = { def messageUpdatesDataArray(g: Grant): Bool = {
(reply.g_type === grantReadShared || reply.g_type === grantReadExclusive) Mux(g.uncached, Bool(false),
(g.g_type === grantReadShared || g.g_type === grantReadExclusive))
} }
def messageIsUncached(acq: Acquire): Bool = uncachedAcquireTypeVec.contains(acq.a_type)
def isCoherenceConflict(addr1: UInt, addr2: UInt): Bool = (addr1 === addr2) def isCoherenceConflict(addr1: UInt, addr2: UInt): Bool = (addr1 === addr2)
def getGrantType(a: Acquire, m: MasterMetadata): UInt = { def getGrantType(a: Acquire, m: MasterMetadata): UInt = {
MuxLookup(a.a_type, grantReadUncached, Array( Mux(a.uncached, getGrantTypeForUncached(a, m),
acquireReadShared -> Mux(m.sharers.count() > UInt(0), grantReadShared, grantReadExclusive), Mux(a.a_type === acquireReadShared,
acquireReadExclusive -> grantReadExclusive, Mux(m.sharers.count() > UInt(0), grantReadShared, grantReadExclusive),
acquireReadUncached -> grantReadUncached, grantReadExclusive))
acquireWriteUncached -> grantWriteUncached,
acquireReadWordUncached -> grantReadWordUncached,
acquireWriteWordUncached -> grantWriteWordUncached,
acquireAtomicUncached -> grantAtomicUncached
))
}
def getGrantType(r: Release, m: MasterMetadata): UInt = {
MuxLookup(r.r_type, grantReadUncached, Array(
releaseVoluntaryInvalidateData -> grantVoluntaryAck
))
} }
def getGrantTypeOnVoluntaryWriteback(m: MasterMetadata): UInt = grantVoluntaryAck
def getProbeType(a: Acquire, m: MasterMetadata): UInt = { def getProbeType(a: Acquire, m: MasterMetadata): UInt = {
MuxLookup(a.a_type, probeCopy, Array( Mux(a.uncached,
acquireReadShared -> probeDowngrade, MuxLookup(a.a_type, probeCopy, Array(
acquireReadExclusive -> probeInvalidate, Acquire.uncachedRead -> probeCopy,
acquireReadUncached -> probeCopy, Acquire.uncachedWrite -> probeInvalidate,
acquireWriteUncached -> probeInvalidate Acquire.uncachedAtomic -> probeInvalidate
)) )),
MuxLookup(a.a_type, probeInvalidate, Array(
acquireReadShared -> probeDowngrade,
acquireReadExclusive -> probeInvalidate
)))
} }
def requiresOuterRead(a_type: UInt) = { def requiresOuterRead(acq: Acquire, m: MasterMetadata) =
(a_type != acquireWriteUncached) Mux(acq.uncached, Acquire.requiresOuterRead(acq.a_type), Bool(true))
} def requiresOuterWrite(acq: Acquire, m: MasterMetadata) =
def requiresOuterWrite(a_type: UInt) = { Mux(acq.uncached, Acquire.requiresOuterWrite(acq.a_type), Bool(false))
(a_type === acquireWriteUncached)
} def requiresAckForGrant(g: Grant) = g.uncached || g.g_type != grantVoluntaryAck
def requiresOuterRead(a_type: UInt, m: MasterMetadata) = requiresOuterRead(a_type) def requiresAckForRelease(r: Release) = Bool(false)
def requiresOuterWrite(a_type: UInt, m: MasterMetadata) = requiresOuterWrite(a_type) def requiresSelfProbe(a: Acquire) = a.uncached && a.a_type === Acquire.uncachedRead
def requiresAckForGrant(g_type: UInt) = g_type != grantVoluntaryAck
def requiresAckForRelease(r_type: UInt) = Bool(false)
def requiresSelfProbe(a_type: UInt) = Bool(false)
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData) def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData)
} }
class MESICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyWithUncached(dir) { class MESICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicy(dir) {
def nClientStates = 4 def nClientStates = 4
def nMasterStates = 3 def nMasterStates = 3
def nAcquireTypes = 7 def nAcquireTypes = 2
def nProbeTypes = 3 def nProbeTypes = 3
def nReleaseTypes = 7 def nReleaseTypes = 7
def nGrantTypes = 9 def nGrantTypes = 4
val clientInvalid :: clientShared :: clientExclusiveClean :: clientExclusiveDirty :: Nil = Enum(UInt(), nClientStates) val clientInvalid :: clientShared :: clientExclusiveClean :: clientExclusiveDirty :: Nil = Enum(UInt(), nClientStates)
val masterInvalid :: masterShared :: masterExclusive :: Nil = Enum(UInt(), nMasterStates) val masterInvalid :: masterShared :: masterExclusive :: Nil = Enum(UInt(), nMasterStates)
val acquireReadShared :: acquireReadExclusive :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: Nil = Enum(UInt(), nAcquireTypes) val acquireReadShared :: acquireReadExclusive :: Nil = Enum(UInt(), nAcquireTypes)
val probeInvalidate :: probeDowngrade :: probeCopy :: Nil = Enum(UInt(), nProbeTypes) val probeInvalidate :: probeDowngrade :: probeCopy :: Nil = Enum(UInt(), nProbeTypes)
val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(UInt(), nReleaseTypes) val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(UInt(), nReleaseTypes)
val grantVoluntaryAck :: grantReadShared :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadExclusiveAck :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: Nil = Enum(UInt(), nGrantTypes) val grantVoluntaryAck :: grantReadShared :: grantReadExclusive :: grantReadExclusiveAck :: Nil = Enum(UInt(), nGrantTypes)
val uncachedAcquireTypeVec = Vec(acquireReadUncached, acquireWriteUncached, acquireReadWordUncached, acquireWriteWordUncached, acquireAtomicUncached)
val hasDataAcquireTypeVec = Vec(acquireWriteUncached, acquireWriteWordUncached, acquireAtomicUncached)
val hasDataReleaseTypeVec = Vec(releaseVoluntaryInvalidateData, releaseInvalidateData, releaseDowngradeData, releaseCopyData) val hasDataReleaseTypeVec = Vec(releaseVoluntaryInvalidateData, releaseInvalidateData, releaseDowngradeData, releaseCopyData)
val hasDataGrantTypeVec = Vec(grantReadShared, grantReadExclusive, grantReadUncached, grantReadWordUncached, grantAtomicUncached) val hasDataGrantTypeVec = Vec(grantReadShared, grantReadExclusive)
def isHit (cmd: UInt, m: ClientMetadata): Bool = { def isHit (cmd: UInt, m: ClientMetadata): Bool = {
Mux(isWriteIntent(cmd), (m.state === clientExclusiveClean || m.state === clientExclusiveDirty), Mux(isWriteIntent(cmd), (m.state === clientExclusiveClean || m.state === clientExclusiveDirty),
@ -681,7 +581,7 @@ class MESICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyW
def isValid (m: MasterMetadata) = m.state != masterInvalid def isValid (m: MasterMetadata) = m.state != masterInvalid
def needsTransactionOnSecondaryMiss(cmd: UInt, outstanding: Acquire): Bool = { def needsTransactionOnSecondaryMiss(cmd: UInt, outstanding: Acquire): Bool = {
(isRead(cmd) && messageIsUncached(outstanding)) || (isRead(cmd) && outstanding.uncached) ||
(isWriteIntent(cmd) && (outstanding.a_type != acquireReadExclusive)) (isWriteIntent(cmd) && (outstanding.a_type != acquireReadExclusive))
} }
def needsTransactionOnCacheControl(cmd: UInt, m: ClientMetadata): Bool = { def needsTransactionOnCacheControl(cmd: UInt, m: ClientMetadata): Bool = {
@ -704,16 +604,13 @@ class MESICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyW
)))(this) )))(this)
def clientMetadataOnFlush = clientMetadataOnCacheControl(M_INV) def clientMetadataOnFlush = clientMetadataOnCacheControl(M_INV)
def clientMetadataOnGrant(incoming: Grant, outstanding: Acquire) = ClientMetadata( def clientMetadataOnGrant(incoming: Grant, outstanding: Acquire) = ClientMetadata(
MuxLookup(incoming.g_type, clientInvalid, Array( Mux(incoming.uncached, clientInvalid,
grantReadShared -> clientShared, MuxLookup(incoming.g_type, clientInvalid, Array(
grantReadExclusive -> Mux(outstanding.a_type === acquireReadExclusive, clientExclusiveDirty, clientExclusiveClean), grantReadShared -> clientShared,
grantReadExclusiveAck -> clientExclusiveDirty, grantReadExclusive -> Mux(outstanding.a_type === acquireReadExclusive,
grantReadUncached -> clientInvalid, clientExclusiveDirty, clientExclusiveClean),
grantWriteUncached -> clientInvalid, grantReadExclusiveAck -> clientExclusiveDirty
grantReadWordUncached -> clientInvalid, ))))(this)
grantWriteWordUncached -> clientInvalid,
grantAtomicUncached -> clientInvalid
)))(this)
def clientMetadataOnProbe(incoming: Probe, m: ClientMetadata) = ClientMetadata( def clientMetadataOnProbe(incoming: Probe, m: ClientMetadata) = ClientMetadata(
MuxLookup(incoming.p_type, m.state, Array( MuxLookup(incoming.p_type, m.state, Array(
probeInvalidate -> clientInvalid, probeInvalidate -> clientInvalid,
@ -738,14 +635,8 @@ class MESICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyW
)) ))
} }
def getUncachedReadAcquireType = acquireReadUncached
def getUncachedWriteAcquireType = acquireWriteUncached
def getUncachedReadWordAcquireType = acquireReadWordUncached
def getUncachedWriteWordAcquireType = acquireWriteWordUncached
def getUncachedAtomicAcquireType = acquireAtomicUncached
def isUncachedReadTransaction(acq: Acquire) = acq.a_type === acquireReadUncached
def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData
def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck def isVoluntary(gnt: Grant) = !gnt.uncached && gnt.g_type === grantVoluntaryAck
def getAcquireTypeOnPrimaryMiss(cmd: UInt, m: ClientMetadata): UInt = { def getAcquireTypeOnPrimaryMiss(cmd: UInt, m: ClientMetadata): UInt = {
Mux(isWriteIntent(cmd), acquireReadExclusive, acquireReadShared) Mux(isWriteIntent(cmd), acquireReadExclusive, acquireReadShared)
@ -770,83 +661,68 @@ class MESICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyW
} }
def messageHasData(msg: SourcedMessage) = msg match { def messageHasData(msg: SourcedMessage) = msg match {
case acq: Acquire => hasDataAcquireTypeVec.contains(acq.a_type) case acq: Acquire => Mux(acq.uncached, Acquire.hasData(acq.a_type), Bool(false))
case grant: Grant => hasDataGrantTypeVec.contains(grant.g_type) case gnt: Grant => Mux(gnt.uncached, Grant.hasData(gnt.g_type), hasDataGrantTypeVec.contains(gnt.g_type))
case rel: Release => hasDataReleaseTypeVec.contains(rel.r_type) case rel: Release => hasDataReleaseTypeVec.contains(rel.r_type)
case _ => Bool(false) case _ => Bool(false)
} }
def messageUpdatesDataArray (reply: Grant): Bool = { def messageUpdatesDataArray(g: Grant): Bool = {
(reply.g_type === grantReadShared || reply.g_type === grantReadExclusive) Mux(g.uncached, Bool(false),
(g.g_type === grantReadShared || g.g_type === grantReadExclusive))
} }
def messageIsUncached(acq: Acquire): Bool = uncachedAcquireTypeVec.contains(acq.a_type)
def isCoherenceConflict(addr1: UInt, addr2: UInt): Bool = (addr1 === addr2) def isCoherenceConflict(addr1: UInt, addr2: UInt): Bool = (addr1 === addr2)
def getGrantType(a: Acquire, m: MasterMetadata): UInt = { def getGrantType(a: Acquire, m: MasterMetadata): UInt = {
MuxLookup(a.a_type, grantReadUncached, Array( Mux(a.uncached, getGrantTypeForUncached(a, m),
acquireReadShared -> Mux(m.sharers.count() > UInt(0), grantReadShared, grantReadExclusive), Mux(a.a_type === acquireReadShared,
acquireReadExclusive -> grantReadExclusive, Mux(m.sharers.count() > UInt(0), grantReadShared, grantReadExclusive),
acquireReadUncached -> grantReadUncached, grantReadExclusive))
acquireWriteUncached -> grantWriteUncached,
acquireReadWordUncached -> grantReadWordUncached,
acquireWriteWordUncached -> grantWriteWordUncached,
acquireAtomicUncached -> grantAtomicUncached
))
} }
def getGrantType(r: Release, m: MasterMetadata): UInt = { def getGrantTypeOnVoluntaryWriteback(m: MasterMetadata): UInt = grantVoluntaryAck
MuxLookup(r.r_type, grantReadUncached, Array(
releaseVoluntaryInvalidateData -> grantVoluntaryAck
))
}
def getProbeType(a: Acquire, m: MasterMetadata): UInt = { def getProbeType(a: Acquire, m: MasterMetadata): UInt = {
MuxLookup(a.a_type, probeCopy, Array( Mux(a.uncached,
acquireReadShared -> probeDowngrade, MuxLookup(a.a_type, probeCopy, Array(
acquireReadExclusive -> probeInvalidate, Acquire.uncachedRead -> probeCopy,
acquireReadUncached -> probeCopy, Acquire.uncachedWrite -> probeInvalidate,
acquireWriteUncached -> probeInvalidate, Acquire.uncachedAtomic -> probeInvalidate
acquireReadWordUncached -> probeCopy, )),
acquireWriteWordUncached -> probeInvalidate, MuxLookup(a.a_type, probeCopy, Array(
acquireAtomicUncached -> probeInvalidate acquireReadShared -> probeDowngrade,
)) acquireReadExclusive -> probeInvalidate
)))
} }
def requiresOuterRead(a_type: UInt) = { def requiresOuterRead(acq: Acquire, m: MasterMetadata) =
(a_type != acquireWriteUncached) Mux(acq.uncached, Acquire.requiresOuterRead(acq.a_type), Bool(true))
} def requiresOuterWrite(acq: Acquire, m: MasterMetadata) =
def requiresOuterWrite(a_type: UInt) = { Mux(acq.uncached, Acquire.requiresOuterWrite(acq.a_type), Bool(false))
(a_type === acquireWriteUncached)
}
def requiresOuterRead(a_type: UInt, m: MasterMetadata) = requiresOuterRead(a_type)
def requiresOuterWrite(a_type: UInt, m: MasterMetadata) = requiresOuterWrite(a_type)
def requiresAckForGrant(g_type: UInt) = g_type != grantVoluntaryAck def requiresAckForGrant(g: Grant) = g.uncached || g.g_type != grantVoluntaryAck
def requiresAckForRelease(r_type: UInt) = Bool(false) def requiresAckForRelease(r: Release) = Bool(false)
def requiresSelfProbe(a_type: UInt) = Bool(false) def requiresSelfProbe(a: Acquire) = a.uncached && a.a_type === Acquire.uncachedRead
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData) def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData)
} }
class MigratoryCoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyWithUncached(dir) { class MigratoryCoherence(dir: () => DirectoryRepresentation) extends CoherencePolicy(dir) {
def nClientStates = 7 def nClientStates = 7
def nMasterStates = 3 def nMasterStates = 3
def nAcquireTypes = 8 def nAcquireTypes = 3
def nProbeTypes = 4 def nProbeTypes = 4
def nReleaseTypes = 11 def nReleaseTypes = 11
def nGrantTypes = 9 def nGrantTypes = 5
val clientInvalid :: clientShared :: clientExclusiveClean :: clientExclusiveDirty :: clientSharedByTwo :: clientMigratoryClean :: clientMigratoryDirty :: Nil = Enum(UInt(), nClientStates) val clientInvalid :: clientShared :: clientExclusiveClean :: clientExclusiveDirty :: clientSharedByTwo :: clientMigratoryClean :: clientMigratoryDirty :: Nil = Enum(UInt(), nClientStates)
val masterInvalid :: masterShared :: masterExclusive :: Nil = Enum(UInt(), nMasterStates) val masterInvalid :: masterShared :: masterExclusive :: Nil = Enum(UInt(), nMasterStates)
val acquireReadShared :: acquireReadExclusive :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: acquireInvalidateOthers :: Nil = Enum(UInt(), nAcquireTypes) val acquireReadShared :: acquireReadExclusive :: acquireInvalidateOthers :: Nil = Enum(UInt(), nAcquireTypes)
val probeInvalidate :: probeDowngrade :: probeCopy :: probeInvalidateOthers :: Nil = Enum(UInt(), nProbeTypes) val probeInvalidate :: probeDowngrade :: probeCopy :: probeInvalidateOthers :: Nil = Enum(UInt(), nProbeTypes)
val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: releaseDowngradeDataMigratory :: releaseDowngradeAckHasCopy :: releaseInvalidateDataMigratory :: releaseInvalidateAckMigratory :: Nil = Enum(UInt(), nReleaseTypes) val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: releaseDowngradeDataMigratory :: releaseDowngradeAckHasCopy :: releaseInvalidateDataMigratory :: releaseInvalidateAckMigratory :: Nil = Enum(UInt(), nReleaseTypes)
val grantVoluntaryAck :: grantReadShared :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadExclusiveAck :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: grantReadMigratory :: Nil = Enum(UInt(), nGrantTypes) val grantVoluntaryAck :: grantReadShared :: grantReadExclusive :: grantReadExclusiveAck :: grantReadMigratory :: Nil = Enum(UInt(), nGrantTypes)
val uncachedAcquireTypeVec = Vec(acquireReadUncached, acquireWriteUncached, acquireReadWordUncached, acquireWriteWordUncached, acquireAtomicUncached) val hasDataGrantTypeVec = Vec(grantReadShared, grantReadExclusive, grantReadMigratory)
val hasDataAcquireTypeVec = Vec(acquireWriteUncached, acquireWriteWordUncached, acquireAtomicUncached)
val hasDataGrantTypeVec = Vec(grantReadShared, grantReadExclusive, grantReadUncached, grantReadMigratory, grantReadWordUncached, grantAtomicUncached)
val hasDataReleaseTypeVec = Vec(releaseVoluntaryInvalidateData, releaseInvalidateData, releaseDowngradeData, releaseCopyData, releaseInvalidateDataMigratory, releaseDowngradeDataMigratory) val hasDataReleaseTypeVec = Vec(releaseVoluntaryInvalidateData, releaseInvalidateData, releaseDowngradeData, releaseCopyData, releaseInvalidateDataMigratory, releaseDowngradeDataMigratory)
def isHit (cmd: UInt, m: ClientMetadata): Bool = { def isHit (cmd: UInt, m: ClientMetadata): Bool = {
@ -859,7 +735,7 @@ class MigratoryCoherence(dir: () => DirectoryRepresentation) extends CoherencePo
def isValid (m: MasterMetadata) = m.state != masterInvalid def isValid (m: MasterMetadata) = m.state != masterInvalid
def needsTransactionOnSecondaryMiss(cmd: UInt, outstanding: Acquire): Bool = { def needsTransactionOnSecondaryMiss(cmd: UInt, outstanding: Acquire): Bool = {
(isRead(cmd) && messageIsUncached(outstanding)) || (isRead(cmd) && outstanding.uncached) ||
(isWriteIntent(cmd) && (outstanding.a_type != acquireReadExclusive && outstanding.a_type != acquireInvalidateOthers)) (isWriteIntent(cmd) && (outstanding.a_type != acquireReadExclusive && outstanding.a_type != acquireInvalidateOthers))
} }
def needsTransactionOnCacheControl(cmd: UInt, m: ClientMetadata): Bool = { def needsTransactionOnCacheControl(cmd: UInt, m: ClientMetadata): Bool = {
@ -883,22 +759,18 @@ class MigratoryCoherence(dir: () => DirectoryRepresentation) extends CoherencePo
)))(this) )))(this)
def clientMetadataOnFlush = clientMetadataOnCacheControl(M_INV) def clientMetadataOnFlush = clientMetadataOnCacheControl(M_INV)
def clientMetadataOnGrant(incoming: Grant, outstanding: Acquire) = ClientMetadata( def clientMetadataOnGrant(incoming: Grant, outstanding: Acquire) = ClientMetadata(
MuxLookup(incoming.g_type, clientInvalid, Array( Mux(incoming.uncached, clientInvalid,
grantReadShared -> clientShared, MuxLookup(incoming.g_type, clientInvalid, Array(
grantReadExclusive -> MuxLookup(outstanding.a_type, clientExclusiveDirty, Array( grantReadShared -> clientShared,
acquireReadExclusive -> clientExclusiveDirty, grantReadExclusive -> MuxLookup(outstanding.a_type, clientExclusiveDirty, Array(
acquireReadShared -> clientExclusiveClean)), acquireReadExclusive -> clientExclusiveDirty,
grantReadExclusiveAck -> clientExclusiveDirty, acquireReadShared -> clientExclusiveClean)),
grantReadUncached -> clientInvalid, grantReadExclusiveAck -> clientExclusiveDirty,
grantWriteUncached -> clientInvalid, grantReadMigratory -> MuxLookup(outstanding.a_type, clientMigratoryDirty, Array(
grantReadWordUncached -> clientInvalid, acquireInvalidateOthers -> clientMigratoryDirty,
grantWriteWordUncached -> clientInvalid, acquireReadExclusive -> clientMigratoryDirty,
grantAtomicUncached -> clientInvalid, acquireReadShared -> clientMigratoryClean))
grantReadMigratory -> MuxLookup(outstanding.a_type, clientMigratoryDirty, Array( ))))(this)
acquireInvalidateOthers -> clientMigratoryDirty,
acquireReadExclusive -> clientMigratoryDirty,
acquireReadShared -> clientMigratoryClean))
)))(this)
def clientMetadataOnProbe(incoming: Probe, m: ClientMetadata) = ClientMetadata( def clientMetadataOnProbe(incoming: Probe, m: ClientMetadata) = ClientMetadata(
MuxLookup(incoming.p_type, m.state, Array( MuxLookup(incoming.p_type, m.state, Array(
probeInvalidate -> clientInvalid, probeInvalidate -> clientInvalid,
@ -935,14 +807,8 @@ class MigratoryCoherence(dir: () => DirectoryRepresentation) extends CoherencePo
} }
def getUncachedReadAcquireType = acquireReadUncached
def getUncachedWriteAcquireType = acquireWriteUncached
def getUncachedReadWordAcquireType = acquireReadWordUncached
def getUncachedWriteWordAcquireType = acquireWriteWordUncached
def getUncachedAtomicAcquireType = acquireAtomicUncached
def isUncachedReadTransaction(acq: Acquire) = acq.a_type === acquireReadUncached
def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData
def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck def isVoluntary(gnt: Grant) = !gnt.uncached && gnt.g_type === grantVoluntaryAck
def getAcquireTypeOnPrimaryMiss(cmd: UInt, m: ClientMetadata): UInt = { def getAcquireTypeOnPrimaryMiss(cmd: UInt, m: ClientMetadata): UInt = {
Mux(isWriteIntent(cmd), Mux(m.state === clientInvalid, acquireReadExclusive, acquireInvalidateOthers), acquireReadShared) Mux(isWriteIntent(cmd), Mux(m.state === clientInvalid, acquireReadExclusive, acquireInvalidateOthers), acquireReadShared)
@ -969,60 +835,50 @@ class MigratoryCoherence(dir: () => DirectoryRepresentation) extends CoherencePo
} }
def messageHasData(msg: SourcedMessage) = msg match { def messageHasData(msg: SourcedMessage) = msg match {
case acq: Acquire => hasDataAcquireTypeVec.contains(acq.a_type) case acq: Acquire => Mux(acq.uncached, Acquire.hasData(acq.a_type), Bool(false))
case grant: Grant => hasDataGrantTypeVec.contains(grant.g_type) case gnt: Grant => Mux(gnt.uncached, Grant.hasData(gnt.g_type), hasDataGrantTypeVec.contains(gnt.g_type))
case rel: Release => hasDataReleaseTypeVec.contains(rel.r_type) case rel: Release => hasDataReleaseTypeVec.contains(rel.r_type)
case _ => Bool(false) case _ => Bool(false)
} }
def messageUpdatesDataArray (reply: Grant): Bool = Vec(grantReadShared, grantReadExclusive, grantReadMigratory).contains(reply.g_type) def messageUpdatesDataArray(g: Grant): Bool = {
def messageIsUncached(acq: Acquire): Bool = uncachedAcquireTypeVec.contains(acq.a_type) Mux(g.uncached, Bool(false),
Vec(grantReadShared, grantReadExclusive, grantReadMigratory).contains(g.g_type))
}
def isCoherenceConflict(addr1: UInt, addr2: UInt): Bool = (addr1 === addr2) def isCoherenceConflict(addr1: UInt, addr2: UInt): Bool = (addr1 === addr2)
def getGrantType(a: Acquire, m: MasterMetadata): UInt = { def getGrantType(a: Acquire, m: MasterMetadata): UInt = {
MuxLookup(a.a_type, grantReadUncached, Array( Mux(a.uncached, getGrantTypeForUncached(a, m),
acquireReadShared -> Mux(m.sharers.count() > UInt(0), grantReadShared, grantReadExclusive), //TODO: what is count? Depend on release.p_type??? MuxLookup(a.a_type, grantReadShared, Array(
acquireReadExclusive -> grantReadExclusive, acquireReadShared -> Mux(m.sharers.count() > UInt(0), grantReadShared, grantReadExclusive),
acquireReadUncached -> grantReadUncached, acquireReadExclusive -> grantReadExclusive,
acquireWriteUncached -> grantWriteUncached, acquireInvalidateOthers -> grantReadExclusiveAck //TODO: add this to MESI for broadcast?
acquireReadWordUncached -> grantReadWordUncached, )))
acquireWriteWordUncached -> grantWriteWordUncached,
acquireAtomicUncached -> grantAtomicUncached,
acquireInvalidateOthers -> grantReadExclusiveAck //TODO: add this to MESI?
))
} }
def getGrantType(r: Release, m: MasterMetadata): UInt = { def getGrantTypeOnVoluntaryWriteback(m: MasterMetadata): UInt = grantVoluntaryAck
MuxLookup(r.r_type, grantReadUncached, Array(
releaseVoluntaryInvalidateData -> grantVoluntaryAck
))
}
def getProbeType(a: Acquire, m: MasterMetadata): UInt = { def getProbeType(a: Acquire, m: MasterMetadata): UInt = {
MuxLookup(a.a_type, probeCopy, Array( Mux(a.uncached,
acquireReadShared -> probeDowngrade, MuxLookup(a.a_type, probeCopy, Array(
acquireReadExclusive -> probeInvalidate, Acquire.uncachedRead -> probeCopy,
acquireReadUncached -> probeCopy, Acquire.uncachedWrite -> probeInvalidate,
acquireWriteUncached -> probeInvalidate, Acquire.uncachedAtomic -> probeInvalidate
acquireReadWordUncached -> probeCopy, )),
acquireWriteWordUncached -> probeInvalidate, MuxLookup(a.a_type, probeCopy, Array(
acquireAtomicUncached -> probeInvalidate, acquireReadShared -> probeDowngrade,
acquireInvalidateOthers -> probeInvalidateOthers acquireReadExclusive -> probeInvalidate,
)) acquireInvalidateOthers -> probeInvalidateOthers
)))
} }
def requiresOuterRead(a_type: UInt) = { def requiresOuterRead(acq: Acquire, m: MasterMetadata) =
(a_type != acquireWriteUncached && a_type != acquireInvalidateOthers) Mux(acq.uncached, Acquire.requiresOuterRead(acq.a_type), acq.a_type != acquireInvalidateOthers)
} def requiresOuterWrite(acq: Acquire, m: MasterMetadata) =
def requiresOuterWrite(a_type: UInt) = { Mux(acq.uncached, Acquire.requiresOuterWrite(acq.a_type), Bool(false))
(a_type === acquireWriteUncached || a_type === acquireWriteWordUncached || a_type === acquireAtomicUncached)
}
def requiresOuterRead(a_type: UInt, m: MasterMetadata) = requiresOuterRead(a_type)
def requiresOuterWrite(a_type: UInt, m: MasterMetadata) = requiresOuterWrite(a_type)
def requiresAckForGrant(g_type: UInt) = g_type != grantVoluntaryAck def requiresAckForGrant(g: Grant) = g.uncached || g.g_type != grantVoluntaryAck
def requiresAckForRelease(r_type: UInt) = Bool(false) def requiresAckForRelease(r: Release) = Bool(false)
def requiresSelfProbe(a_type: UInt) = Bool(false) def requiresSelfProbe(a: Acquire) = a.uncached && a.a_type === Acquire.uncachedRead
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData) def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData)
} }

View File

@ -16,7 +16,9 @@ trait MemoryOpConstants {
val MT_BU = Bits("b100") val MT_BU = Bits("b100")
val MT_HU = Bits("b101") val MT_HU = Bits("b101")
val MT_WU = Bits("b110") val MT_WU = Bits("b110")
val MT_CB = Bits("b111") // cache block
val NUM_XA_OPS = 9
val M_SZ = 5 val M_SZ = 5
val M_X = Bits("b?????"); val M_X = Bits("b?????");
val M_XRD = Bits("b00000"); // int load val M_XRD = Bits("b00000"); // int load

View File

@ -135,7 +135,7 @@ class HTIF(pcr_RESET: Int) extends Module with HTIFParameters {
mem_acked := Bool(true) mem_acked := Bool(true)
mem_gxid := io.mem.grant.bits.payload.master_xact_id mem_gxid := io.mem.grant.bits.payload.master_xact_id
mem_gsrc := io.mem.grant.bits.header.src mem_gsrc := io.mem.grant.bits.header.src
mem_needs_ack := co.requiresAckForGrant(io.mem.grant.bits.payload.g_type) mem_needs_ack := co.requiresAckForGrant(io.mem.grant.bits.payload)
} }
io.mem.grant.ready := Bool(true) io.mem.grant.ready := Bool(true)
@ -193,8 +193,8 @@ class HTIF(pcr_RESET: Int) extends Module with HTIFParameters {
acq_q.io.enq.valid := state === state_mem_rreq || state === state_mem_wreq acq_q.io.enq.valid := state === state_mem_rreq || state === state_mem_wreq
val init_addr = addr.toUInt >> UInt(offsetBits-3) val init_addr = addr.toUInt >> UInt(offsetBits-3)
acq_q.io.enq.bits := Mux(cmd === cmd_writemem, acq_q.io.enq.bits := Mux(cmd === cmd_writemem,
Acquire(co.getUncachedWriteAcquireType, init_addr, UInt(0)), UncachedWrite(init_addr, UInt(0)),
Acquire(co.getUncachedReadAcquireType, init_addr, UInt(0))) UncachedRead(init_addr))
io.mem.acquire.valid := acq_q.io.deq.valid io.mem.acquire.valid := acq_q.io.deq.valid
acq_q.io.deq.ready := io.mem.acquire.ready acq_q.io.deq.ready := io.mem.acquire.ready
io.mem.acquire.bits.payload := acq_q.io.deq.bits io.mem.acquire.bits.payload := acq_q.io.deq.bits

View File

@ -268,7 +268,7 @@ class MemIOUncachedTileLinkIOConverter(qDepth: Int) extends Module {
// Aggregate incoming MemIO responses into TL Grants // Aggregate incoming MemIO responses into TL Grants
io.mem.resp.ready := !active_in || cnt_in < UInt(cnt_max) io.mem.resp.ready := !active_in || cnt_in < UInt(cnt_max)
io.uncached.grant.valid := active_in && (cnt_in === UInt(cnt_max)) io.uncached.grant.valid := active_in && (cnt_in === UInt(cnt_max))
io.uncached.grant.bits.payload := Grant(UInt(0), tag_in, UInt(0), buf_in) io.uncached.grant.bits.payload := Grant(Bool(true), UInt(0), tag_in, UInt(0), buf_in)
when(!active_in && io.mem.resp.valid) { when(!active_in && io.mem.resp.valid) {
active_in := Bool(true) active_in := Bool(true)
cnt_in := UInt(1) cnt_in := UInt(1)

View File

@ -2,65 +2,89 @@
package uncore package uncore
import Chisel._ import Chisel._
import scala.math.max
case object TLId extends Field[String] case object TLId extends Field[String]
case object TLCoherence extends Field[CoherencePolicyWithUncached] case object TLCoherence extends Field[CoherencePolicy]
case object TLAddrBits extends Field[Int] case object TLAddrBits extends Field[Int]
case object TLMasterXactIdBits extends Field[Int] case object TLMasterXactIdBits extends Field[Int]
case object TLClientXactIdBits extends Field[Int] case object TLClientXactIdBits extends Field[Int]
case object TLDataBits extends Field[Int] case object TLDataBits extends Field[Int]
case object TLWriteMaskBits extends Field[Int]
case object TLWordAddrBits extends Field[Int]
case object TLAtomicOpBits extends Field[Int]
trait HasPhysicalAddress extends Bundle { abstract trait TileLinkParameters extends UsesParameters {
val addr = UInt(width = params(TLAddrBits)) val tlAddrBits = params(TLAddrBits)
val tlClientXactIdBits = params(TLClientXactIdBits)
val tlMasterXactIdBits = params(TLMasterXactIdBits)
val tlDataBits = params(TLDataBits)
val tlWriteMaskBits = tlDataBits/8
val tlSubblockAddrBits = log2Up(tlWriteMaskBits)
val tlAtomicOpcodeBits = log2Up(NUM_XA_OPS)
val tlUncachedOperandSizeBits = MT_SZ
val tlSubblockUnionBits = max(tlWriteMaskBits,
(tlSubblockAddrBits +
tlUncachedOperandSizeBits +
tlAtomicOpcodeBits))
} }
trait HasClientTransactionId extends Bundle { class TLBundle extends Bundle with TileLinkParameters
val client_xact_id = Bits(width = params(TLClientXactIdBits))
trait HasPhysicalAddress extends TLBundle {
val addr = UInt(width = tlAddrBits)
} }
trait HasMasterTransactionId extends Bundle { trait HasClientTransactionId extends TLBundle {
val master_xact_id = Bits(width = params(TLMasterXactIdBits)) val client_xact_id = Bits(width = tlClientXactIdBits)
} }
trait HasTileLinkData extends Bundle { trait HasMasterTransactionId extends TLBundle {
val data = Bits(width = params(TLDataBits)) val master_xact_id = Bits(width = tlMasterXactIdBits)
} }
trait SourcedMessage extends Bundle trait HasTileLinkData extends TLBundle {
val data = UInt(width = tlDataBits)
}
trait SourcedMessage extends TLBundle
trait ClientSourcedMessage extends SourcedMessage trait ClientSourcedMessage extends SourcedMessage
trait MasterSourcedMessage extends SourcedMessage trait MasterSourcedMessage extends SourcedMessage
object Acquire class Acquire extends ClientSourcedMessage
{ with HasPhysicalAddress
def apply(a_type: Bits, addr: UInt, client_xact_id: UInt): Acquire = { with HasClientTransactionId
with HasTileLinkData {
val uncached = Bool()
val a_type = UInt(width = max(log2Up(Acquire.nUncachedAcquireTypes), params(TLCoherence).acquireTypeWidth))
val subblock = Bits(width = tlSubblockUnionBits)
val sbAddrOff = tlSubblockAddrBits + tlUncachedOperandSizeBits
val opSzOff = tlUncachedOperandSizeBits + sbAddrOff
def operand_sz(dummy: Int = 0) = subblock(tlUncachedOperandSizeBits-1, 0)
def subblock_addr(dummy: Int = 0) = subblock(sbAddrOff-1, tlUncachedOperandSizeBits)
def atomic_op(dummy: Int = 0) = subblock(opSzOff-1, sbAddrOff)
def write_mask(dummy: Int = 0) = subblock(tlWriteMaskBits-1, 0)
}
object Acquire {
val nUncachedAcquireTypes = 3
//val uncachedRead :: uncachedWrite :: uncachedAtomic :: Nil = Enum(UInt(), nUncachedAcquireTypes)
def uncachedRead = UInt(0)
def uncachedWrite = UInt(1)
def uncachedAtomic = UInt(2)
def hasData(a_type: UInt) = Vec(uncachedWrite, uncachedAtomic).contains(a_type)
def requiresOuterRead(a_type: UInt) = a_type != uncachedWrite
def requiresOuterWrite(a_type: UInt) = a_type === uncachedWrite
def apply(a_type: Bits, addr: UInt, client_xact_id: UInt, data: UInt): Acquire = {
val acq = new Acquire val acq = new Acquire
acq.uncached := Bool(false)
acq.a_type := a_type acq.a_type := a_type
acq.addr := addr acq.addr := addr
acq.client_xact_id := client_xact_id acq.client_xact_id := client_xact_id
acq.data := Bits(0)
acq.write_mask := Bits(0)
acq.subword_addr := Bits(0)
acq.atomic_opcode := Bits(0)
acq
}
def apply(a_type: Bits, addr: UInt, client_xact_id: UInt, data: UInt): Acquire = {
val acq = apply(a_type, addr, client_xact_id)
acq.data := data acq.data := data
acq.subblock := UInt(0)
acq acq
} }
def apply(a_type: UInt, addr: UInt, client_xact_id: UInt, write_mask: Bits, data: UInt): Acquire = { def apply(a_type: Bits, addr: UInt, client_xact_id: UInt): Acquire = {
val acq = apply(a_type, addr, client_xact_id, data) apply(a_type, addr, client_xact_id, UInt(0))
acq.write_mask := write_mask
acq
}
def apply(a_type: UInt, addr: UInt, client_xact_id: UInt, subword_addr: UInt, atomic_opcode: UInt, data: UInt): Acquire = {
val acq = apply(a_type, addr, client_xact_id, data)
acq.subword_addr := subword_addr
acq.atomic_opcode := atomic_opcode
acq
} }
def apply(a: Acquire): Acquire = { def apply(a: Acquire): Acquire = {
val acq = new Acquire val acq = new Acquire
@ -69,16 +93,45 @@ object Acquire
} }
} }
class Acquire extends ClientSourcedMessage object UncachedRead {
with HasPhysicalAddress def apply(addr: UInt, client_xact_id: UInt, subblock_addr: UInt, operand_sz: UInt): Acquire = {
with HasClientTransactionId val acq = Acquire(Acquire.uncachedRead, addr, client_xact_id)
with HasTileLinkData { acq.uncached := Bool(true)
val a_type = UInt(width = params(TLCoherence).acquireTypeWidth) acq.subblock := Cat(subblock_addr, operand_sz)
val write_mask = Bits(width = params(TLWriteMaskBits)) acq
val subword_addr = Bits(width = params(TLWordAddrBits)) }
val atomic_opcode = Bits(width = params(TLAtomicOpBits)) def apply(addr: UInt, client_xact_id: UInt): Acquire = {
apply(addr, client_xact_id, UInt(0), MT_CB)
}
def apply(addr: UInt): Acquire = {
apply(addr, UInt(0), UInt(0), MT_CB)
}
} }
object UncachedWrite {
def apply(addr: UInt, client_xact_id: UInt, write_mask: Bits, data: UInt): Acquire = {
val acq = Acquire(Acquire.uncachedWrite, addr, client_xact_id, data)
acq.uncached := Bool(true)
acq.subblock := write_mask
acq
}
def apply(addr: UInt, client_xact_id: UInt, data: UInt): Acquire = {
apply(addr, client_xact_id, SInt(-1), data)
}
def apply(addr: UInt, data: UInt): Acquire = {
apply(addr, UInt(0), data)
}
}
object UncachedAtomic {
def apply(addr: UInt, client_xact_id: UInt, atomic_opcode: UInt,
subblock_addr: UInt, operand_sz: UInt, data: UInt): Acquire = {
val acq = Acquire(Acquire.uncachedAtomic, addr, client_xact_id, data)
acq.uncached := Bool(true)
acq.subblock := Cat(atomic_opcode, subblock_addr, operand_sz)
acq
}
}
object Probe { object Probe {
def apply(p_type: UInt, addr: UInt) = { def apply(p_type: UInt, addr: UInt) = {
@ -118,28 +171,34 @@ class Release extends ClientSourcedMessage
val r_type = UInt(width = params(TLCoherence).releaseTypeWidth) val r_type = UInt(width = params(TLCoherence).releaseTypeWidth)
} }
object Grant
{
def apply(g_type: UInt, client_xact_id: UInt, master_xact_id: UInt): Grant = {
val gnt = new Grant
gnt.g_type := g_type
gnt.client_xact_id := client_xact_id
gnt.master_xact_id := master_xact_id
gnt.data := UInt(0)
gnt
}
def apply(g_type: UInt, client_xact_id: UInt, master_xact_id: UInt, data: UInt): Grant = {
val gnt = apply(g_type, client_xact_id, master_xact_id)
gnt.data := data
gnt
}
}
class Grant extends MasterSourcedMessage class Grant extends MasterSourcedMessage
with HasTileLinkData with HasTileLinkData
with HasClientTransactionId with HasClientTransactionId
with HasMasterTransactionId { with HasMasterTransactionId {
val g_type = UInt(width = params(TLCoherence).grantTypeWidth) val uncached = Bool()
val g_type = UInt(width = max(log2Up(Grant.nUncachedGrantTypes), params(TLCoherence).grantTypeWidth))
}
object Grant {
val nUncachedGrantTypes = 3
//val uncachedRead :: uncachedWrite :: uncachedAtomic :: Nil = Enum(UInt(), nUncachedGrantTypes)
def uncachedRead = UInt(0)
def uncachedWrite = UInt(1)
def uncachedAtomic = UInt(2)
def hasData(g_type: UInt) = Vec(uncachedRead, uncachedAtomic).contains(g_type)
def apply(uncached: Bool, g_type: UInt, client_xact_id: UInt, master_xact_id: UInt, data: UInt): Grant = {
val gnt = new Grant
gnt.uncached := uncached
gnt.g_type := g_type
gnt.client_xact_id := client_xact_id
gnt.master_xact_id := master_xact_id
gnt.data := data
gnt
}
def apply(uncached: Bool, g_type: UInt, client_xact_id: UInt, master_xact_id: UInt): Grant = {
apply(uncached, g_type, client_xact_id, master_xact_id, UInt(0))
}
} }
class Finish extends ClientSourcedMessage with HasMasterTransactionId class Finish extends ClientSourcedMessage with HasMasterTransactionId

View File

@ -122,7 +122,7 @@ class VoluntaryReleaseTracker(trackerId: Int, bankId: Int, innerId: String, oute
io.outer.acquire.valid := Bool(false) io.outer.acquire.valid := Bool(false)
io.outer.acquire.bits.header.src := UInt(bankId) io.outer.acquire.bits.header.src := UInt(bankId)
//io.outer.acquire.bits.header.dst TODO //io.outer.acquire.bits.header.dst TODO
io.outer.acquire.bits.payload := Bundle(Acquire(co.getUncachedWriteAcquireType, io.outer.acquire.bits.payload := Bundle(UncachedWrite(
xact.addr, xact.addr,
UInt(trackerId), UInt(trackerId),
xact.data), xact.data),
@ -133,7 +133,8 @@ class VoluntaryReleaseTracker(trackerId: Int, bankId: Int, innerId: String, oute
io.inner.grant.valid := Bool(false) io.inner.grant.valid := Bool(false)
io.inner.grant.bits.header.src := UInt(bankId) io.inner.grant.bits.header.src := UInt(bankId)
io.inner.grant.bits.header.dst := init_client_id io.inner.grant.bits.header.dst := init_client_id
io.inner.grant.bits.payload := Grant(co.getGrantType(xact, co.masterMetadataOnFlush), io.inner.grant.bits.payload := Grant(Bool(false),
co.getGrantTypeOnVoluntaryWriteback(co.masterMetadataOnFlush),
xact.client_xact_id, xact.client_xact_id,
UInt(trackerId)) UInt(trackerId))
@ -169,15 +170,13 @@ class AcquireTracker(trackerId: Int, bankId: Int, innerId: String, outerId: Stri
val curr_p_id = PriorityEncoder(probe_flags) val curr_p_id = PriorityEncoder(probe_flags)
val pending_outer_write = co.messageHasData(xact) val pending_outer_write = co.messageHasData(xact)
val pending_outer_read = co.requiresOuterRead(xact.a_type) val pending_outer_read = co.requiresOuterRead(xact, co.masterMetadataOnFlush)
val outer_write_acq = Bundle(Acquire(co.getUncachedWriteAcquireType, val outer_write_acq = Bundle(UncachedWrite(xact.addr, UInt(trackerId), xact.data),
xact.addr, UInt(trackerId), xact.data), { case TLId => outerId })
{ case TLId => outerId }) val outer_write_rel = Bundle(UncachedWrite(xact.addr, UInt(trackerId), c_rel.payload.data),
val outer_write_rel = Bundle(Acquire(co.getUncachedWriteAcquireType, { case TLId => outerId })
xact.addr, UInt(trackerId), c_rel.payload.data), val outer_read = Bundle(UncachedRead(xact.addr, UInt(trackerId)),
{ case TLId => outerId }) { case TLId => outerId })
val outer_read = Bundle(Acquire(co.getUncachedReadAcquireType, xact.addr, UInt(trackerId)),
{ case TLId => outerId })
val probe_initial_flags = Bits(width = nClients) val probe_initial_flags = Bits(width = nClients)
probe_initial_flags := Bits(0) probe_initial_flags := Bits(0)
@ -202,11 +201,11 @@ class AcquireTracker(trackerId: Int, bankId: Int, innerId: String, outerId: Stri
io.inner.probe.bits.header.dst := curr_p_id io.inner.probe.bits.header.dst := curr_p_id
io.inner.probe.bits.payload := Probe(co.getProbeType(xact, co.masterMetadataOnFlush), xact.addr) io.inner.probe.bits.payload := Probe(co.getProbeType(xact, co.masterMetadataOnFlush), xact.addr)
val grant_type = co.getGrantType(xact, co.masterMetadataOnFlush)
io.inner.grant.valid := Bool(false) io.inner.grant.valid := Bool(false)
io.inner.grant.bits.header.src := UInt(bankId) io.inner.grant.bits.header.src := UInt(bankId)
io.inner.grant.bits.header.dst := init_client_id io.inner.grant.bits.header.dst := init_client_id
io.inner.grant.bits.payload := Grant(grant_type, io.inner.grant.bits.payload := Grant(xact.uncached,
co.getGrantType(xact, co.masterMetadataOnFlush),
xact.client_xact_id, xact.client_xact_id,
UInt(trackerId), UInt(trackerId),
m_gnt.payload.data) m_gnt.payload.data)
@ -218,7 +217,7 @@ class AcquireTracker(trackerId: Int, bankId: Int, innerId: String, outerId: Stri
is(s_idle) { is(s_idle) {
io.inner.acquire.ready := Bool(true) io.inner.acquire.ready := Bool(true)
val needs_outer_write = co.messageHasData(c_acq.payload) val needs_outer_write = co.messageHasData(c_acq.payload)
val needs_outer_read = co.requiresOuterRead(c_acq.payload.a_type) val needs_outer_read = co.requiresOuterRead(c_acq.payload, co.masterMetadataOnFlush)
when( io.inner.acquire.valid ) { when( io.inner.acquire.valid ) {
xact := c_acq.payload xact := c_acq.payload
init_client_id := c_acq.header.src init_client_id := c_acq.header.src
@ -266,7 +265,7 @@ class AcquireTracker(trackerId: Int, bankId: Int, innerId: String, outerId: Stri
io.outer.acquire.valid := Bool(true) io.outer.acquire.valid := Bool(true)
io.outer.acquire.bits.payload := outer_read io.outer.acquire.bits.payload := outer_read
when(io.outer.acquire.ready) { when(io.outer.acquire.ready) {
state := Mux(co.requiresAckForGrant(grant_type), s_busy, s_idle) state := Mux(co.requiresAckForGrant(io.inner.grant.bits.payload), s_busy, s_idle)
} }
} }
is(s_mem_write) { is(s_mem_write) {
@ -279,7 +278,7 @@ class AcquireTracker(trackerId: Int, bankId: Int, innerId: String, outerId: Stri
is(s_make_grant) { is(s_make_grant) {
io.inner.grant.valid := Bool(true) io.inner.grant.valid := Bool(true)
when(io.inner.grant.ready) { when(io.inner.grant.ready) {
state := Mux(co.requiresAckForGrant(grant_type), s_busy, s_idle) state := Mux(co.requiresAckForGrant(io.inner.grant.bits.payload), s_busy, s_idle)
} }
} }
is(s_busy) { // Nothing left to do but wait for transaction to complete is(s_busy) { // Nothing left to do but wait for transaction to complete