1
0
rocket-chip/uncore/src/main/scala/coherence.scala

956 lines
45 KiB
Scala
Raw Normal View History

package uncore
import Chisel._
abstract trait CoherenceAgentRole
abstract trait ClientCoherenceAgent extends CoherenceAgentRole
abstract trait MasterCoherenceAgent extends CoherenceAgentRole
2012-12-13 20:39:14 +01:00
abstract class CoherencePolicy {
def nClientStates: Int
def nMasterStates: Int
def nAcquireTypes: Int
def nProbeTypes: Int
def nReleaseTypes: Int
def nGrantTypes: Int
2013-08-12 19:36:44 +02:00
def clientStateWidth = log2Up(nClientStates)
def masterStateWidth = log2Up(nMasterStates)
def acquireTypeWidth = log2Up(nAcquireTypes)
def probeTypeWidth = log2Up(nProbeTypes)
def releaseTypeWidth = log2Up(nReleaseTypes)
def grantTypeWidth = log2Up(nGrantTypes)
def isHit (cmd: UInt, state: UInt): Bool
def isValid (state: UInt): Bool
def needsTransactionOnSecondaryMiss(cmd: UInt, outstanding: Acquire): Bool
def needsTransactionOnCacheControl(cmd: UInt, state: UInt): Bool
def needsWriteback (state: UInt): Bool
def newStateOnHit(cmd: UInt, state: UInt): UInt
def newStateOnCacheControl(cmd: UInt): UInt
def newStateOnWriteback(): UInt
def newStateOnFlush(): UInt
def newStateOnGrant(incoming: Grant, outstanding: Acquire): UInt
def newStateOnProbe(incoming: Probe, state: UInt): Bits
def getAcquireTypeOnPrimaryMiss(cmd: UInt, state: UInt): UInt
def getAcquireTypeOnSecondaryMiss(cmd: UInt, state: UInt, outstanding: Acquire): UInt
def getProbeType(a_type: UInt, global_state: UInt): UInt
def getReleaseTypeOnCacheControl(cmd: UInt): Bits
def getReleaseTypeOnVoluntaryWriteback(): Bits
2013-08-12 19:36:44 +02:00
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): Bits
def getGrantType(a_type: UInt, count: UInt): Bits
def getGrantType(rel: Release, count: UInt): Bits
def messageHasData (rel: SourcedMessage): Bool
2013-01-22 02:17:26 +01:00
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
2013-08-12 19:36:44 +02:00
def needsOuterRead(a_type: UInt, global_state: UInt): Bool
def needsOuterWrite(a_type: UInt, global_state: UInt): Bool
def needsAckReply(a_type: UInt, global_state: UInt): Bool
2013-03-01 04:49:05 +01:00
def needsSelfProbe(acq: Acquire): Bool
def requiresAck(grant: Grant): Bool
def requiresAck(release: Release): Bool
2013-08-12 19:36:44 +02:00
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool
2013-08-12 19:36:44 +02:00
def uSIntListContains(list: List[UInt], elem: UInt): Bool = list.map(elem === _).reduceLeft(_||_)
}
2012-03-02 03:49:00 +01:00
trait UncachedTransactions {
def getUncachedReadAcquireType: Bits
def getUncachedWriteAcquireType: Bits
def getUncachedReadWordAcquireType: Bits
def getUncachedWriteWordAcquireType: Bits
def getUncachedAtomicAcquireType: Bits
2013-01-22 02:17:26 +01:00
def isUncachedReadTransaction(acq: Acquire): Bool
}
abstract class CoherencePolicyWithUncached extends CoherencePolicy with UncachedTransactions
abstract class IncoherentPolicy extends CoherencePolicy {
// UNIMPLEMENTED
2013-08-12 19:36:44 +02:00
def newStateOnProbe(incoming: Probe, state: UInt): Bits = state
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): Bits = Bits(0)
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = Bool(false)
2013-08-12 19:36:44 +02:00
def getGrantType(a_type: UInt, count: UInt): Bits = Bits(0)
def getGrantType(rel: Release, count: UInt): Bits = Bits(0)
def getProbeType(a_type: UInt, global_state: UInt): UInt = UInt(0)
def needsOuterRead(a_type: UInt, global_state: UInt): Bool = Bool(false)
def needsOuterWrite(a_type: UInt, global_state: UInt): Bool = Bool(false)
def needsAckReply(a_type: UInt, global_state: UInt): Bool = Bool(false)
2013-03-01 04:49:05 +01:00
def needsSelfProbe(acq: Acquire) = Bool(false)
def requiresAck(grant: Grant) = Bool(true)
def requiresAck(release: Release) = Bool(false)
2013-08-12 19:36:44 +02:00
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = Bool(false)
}
class ThreeStateIncoherence extends IncoherentPolicy {
def nClientStates = 3
def nMasterStates = 0
def nAcquireTypes = 3
def nProbeTypes = 0
def nReleaseTypes = 2
def nGrantTypes = 3
2013-08-12 19:36:44 +02:00
val tileInvalid :: tileClean :: tileDirty :: Nil = Enum(nClientStates){ UInt() }
val acquireReadClean :: acquireReadDirty :: acquireWriteback :: Nil = Enum(nAcquireTypes){ UInt() }
val releaseVoluntaryInvalidateData :: releaseInvalidateAck :: Nil = Enum(nReleaseTypes){ UInt() }
val grantVoluntaryAck :: grantData :: grantAck :: Nil = Enum(nGrantTypes){ UInt() }
val uncachedAcquireTypeList = List()
val hasDataAcquireTypeList = List(acquireWriteback)
val hasDataReleaseTypeList = List(acquireWriteback)
val hasDataGrantTypeList = List(grantData)
2013-08-12 19:36:44 +02:00
def isHit ( cmd: UInt, state: UInt): Bool = (state === tileClean || state === tileDirty)
def isValid (state: UInt): Bool = state != tileInvalid
2013-08-12 19:36:44 +02:00
def needsTransactionOnSecondaryMiss(cmd: UInt, outstanding: Acquire) = Bool(false)
def needsTransactionOnCacheControl(cmd: UInt, state: UInt): Bool = state === tileDirty
def needsWriteback (state: UInt): Bool = state === tileDirty
2013-08-12 19:36:44 +02:00
def newState(cmd: UInt, state: UInt): UInt = {
Mux(isWrite(cmd), tileDirty, Mux(isRead(cmd), Mux(state === tileDirty, tileDirty, tileClean), state))
}
2013-08-12 19:36:44 +02:00
def newStateOnHit(cmd: UInt, state: UInt): UInt = newState(cmd, state)
def newStateOnCacheControl(cmd: UInt) = tileInvalid //TODO
def newStateOnWriteback() = tileInvalid
def newStateOnFlush() = tileInvalid
2013-01-22 02:17:26 +01:00
def newStateOnGrant(incoming: Grant, outstanding: Acquire) = {
MuxLookup(incoming.g_type, tileInvalid, Array(
grantData -> Mux(outstanding.a_type === acquireReadDirty, tileDirty, tileClean),
grantAck -> tileInvalid
))
}
def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData
def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck
2013-08-12 19:36:44 +02:00
def getAcquireTypeOnPrimaryMiss(cmd: UInt, state: UInt): UInt = {
2013-04-04 07:13:51 +02:00
Mux(isWriteIntent(cmd), acquireReadDirty, acquireReadClean)
}
2013-08-12 19:36:44 +02:00
def getAcquireTypeOnSecondaryMiss(cmd: UInt, state: UInt, outstanding: Acquire): UInt = {
Mux(isWriteIntent(cmd), acquireReadDirty, outstanding.a_type)
}
2013-08-12 19:36:44 +02:00
def getReleaseTypeOnCacheControl(cmd: UInt): Bits = releaseVoluntaryInvalidateData // TODO
def getReleaseTypeOnVoluntaryWriteback(): Bits = releaseVoluntaryInvalidateData
def messageHasData( msg: SourcedMessage ) = msg match {
2013-08-12 19:36:44 +02:00
case acq: Acquire => uSIntListContains(hasDataAcquireTypeList, acq.a_type)
case grant: Grant => uSIntListContains(hasDataGrantTypeList, grant.g_type)
case rel: Release => Bool(false)
case _ => Bool(false)
}
2013-01-22 02:17:26 +01:00
def messageUpdatesDataArray (reply: Grant) = (reply.g_type === grantData)
2013-08-12 19:36:44 +02:00
def messageIsUncached(acq: Acquire): Bool = uSIntListContains(uncachedAcquireTypeList, acq.a_type)
}
class MICoherence extends CoherencePolicyWithUncached {
def nClientStates = 2
def nMasterStates = 2
def nAcquireTypes = 6
def nProbeTypes = 2
def nReleaseTypes = 5
def nGrantTypes = 7
2013-08-12 19:36:44 +02:00
val tileInvalid :: tileValid :: Nil = Enum(nClientStates){ UInt() }
val globalInvalid :: globalValid :: Nil = Enum(nMasterStates){ UInt() }
2013-08-12 19:36:44 +02:00
val acquireReadExclusive :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: Nil = Enum(nAcquireTypes){ UInt() }
val probeInvalidate :: probeCopy :: Nil = Enum(nProbeTypes){ UInt() }
val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseCopyData :: releaseInvalidateAck :: releaseCopyAck :: Nil = Enum(nReleaseTypes){ UInt() }
val grantVoluntaryAck :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: Nil = Enum(nGrantTypes){ UInt() }
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)
2013-08-12 19:36:44 +02:00
def isHit (cmd: UInt, state: UInt): Bool = state != tileInvalid
def isValid (state: UInt): Bool = state != tileInvalid
2013-08-12 19:36:44 +02:00
def needsTransactionOnSecondaryMiss(cmd: UInt, outstanding: Acquire): Bool = (outstanding.a_type != acquireReadExclusive)
def needsTransactionOnCacheControl(cmd: UInt, state: UInt): Bool = {
MuxLookup(cmd, (state === tileValid), Array(
M_INV -> (state === tileValid),
M_CLN -> (state === tileValid)
))
}
2013-08-12 19:36:44 +02:00
def needsWriteback (state: UInt): Bool = {
needsTransactionOnCacheControl(M_INV, state)
}
2013-08-12 19:36:44 +02:00
def newStateOnHit(cmd: UInt, state: UInt): UInt = state
def newStateOnCacheControl(cmd: UInt) = {
MuxLookup(cmd, tileInvalid, Array(
M_INV -> tileInvalid,
M_CLN -> tileValid
))
}
def newStateOnWriteback() = newStateOnCacheControl(M_INV)
def newStateOnFlush() = newStateOnCacheControl(M_INV)
2013-08-12 19:36:44 +02:00
def newStateOnGrant(incoming: Grant, outstanding: Acquire): UInt = {
2013-01-22 02:17:26 +01:00
MuxLookup(incoming.g_type, tileInvalid, Array(
grantReadExclusive -> tileValid,
grantReadUncached -> tileInvalid,
grantWriteUncached -> tileInvalid,
grantReadWordUncached -> tileInvalid,
grantWriteWordUncached -> tileInvalid,
grantAtomicUncached -> tileInvalid
))
}
2013-08-12 19:36:44 +02:00
def newStateOnProbe(incoming: Probe, state: UInt): Bits = {
MuxLookup(incoming.p_type, state, Array(
2013-01-22 02:17:26 +01:00
probeInvalidate -> tileInvalid,
probeCopy -> state
))
}
def getUncachedReadAcquireType = acquireReadUncached
def getUncachedWriteAcquireType = acquireWriteUncached
def getUncachedReadWordAcquireType = acquireReadWordUncached
def getUncachedWriteWordAcquireType = acquireWriteWordUncached
def getUncachedAtomicAcquireType = acquireAtomicUncached
2013-01-22 02:17:26 +01:00
def isUncachedReadTransaction(acq: Acquire) = acq.a_type === acquireReadUncached
def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData
def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck
2013-08-12 19:36:44 +02:00
def getAcquireTypeOnPrimaryMiss(cmd: UInt, state: UInt): UInt = acquireReadExclusive
def getAcquireTypeOnSecondaryMiss(cmd: UInt, state: UInt, outstanding: Acquire): UInt = acquireReadExclusive
def getReleaseTypeOnCacheControl(cmd: UInt): Bits = releaseVoluntaryInvalidateData // TODO
def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV)
2013-08-12 19:36:44 +02:00
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): Bits = {
2013-01-22 02:17:26 +01:00
val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array(
probeInvalidate -> releaseInvalidateData,
probeCopy -> releaseCopyData
))
2013-01-22 02:17:26 +01:00
val without_data = MuxLookup(incoming.p_type, releaseInvalidateAck, Array(
probeInvalidate -> releaseInvalidateAck,
probeCopy -> releaseCopyAck
))
Mux(needsWriteback(state), with_data, without_data)
}
def messageHasData(msg: SourcedMessage) = msg match {
2013-08-12 19:36:44 +02:00
case acq: Acquire => uSIntListContains(hasDataAcquireTypeList, acq.a_type)
case grant: Grant => uSIntListContains(hasDataGrantTypeList, grant.g_type)
case rel: Release => uSIntListContains(hasDataReleaseTypeList, rel.r_type)
case _ => Bool(false)
}
2013-01-22 02:17:26 +01:00
def messageUpdatesDataArray (reply: Grant): Bool = {
(reply.g_type === grantReadExclusive)
}
2013-08-12 19:36:44 +02:00
def messageIsUncached(acq: Acquire): Bool = uSIntListContains(uncachedAcquireTypeList, acq.a_type)
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2)
2013-08-12 19:36:44 +02:00
def getGrantType(a_type: UInt, count: UInt): Bits = {
2013-01-22 02:17:26 +01:00
MuxLookup(a_type, grantReadUncached, Array(
acquireReadExclusive -> grantReadExclusive,
acquireReadUncached -> grantReadUncached,
acquireWriteUncached -> grantWriteUncached,
acquireReadWordUncached -> grantReadWordUncached,
acquireWriteWordUncached -> grantWriteWordUncached,
acquireAtomicUncached -> grantAtomicUncached
))
}
2013-08-12 19:36:44 +02:00
def getGrantType(rel: Release, count: UInt): Bits = {
MuxLookup(rel.r_type, grantReadUncached, Array(
releaseVoluntaryInvalidateData -> grantVoluntaryAck
))
}
2013-08-12 19:36:44 +02:00
def getProbeType(a_type: UInt, global_state: UInt): UInt = {
2013-01-22 02:17:26 +01:00
MuxLookup(a_type, probeCopy, Array(
acquireReadExclusive -> probeInvalidate,
acquireReadUncached -> probeCopy,
acquireWriteUncached -> probeInvalidate,
acquireReadWordUncached -> probeCopy,
acquireWriteWordUncached -> probeInvalidate,
acquireAtomicUncached -> probeInvalidate
))
}
2013-08-12 19:36:44 +02:00
def needsOuterRead(a_type: UInt, global_state: UInt): Bool = {
2013-01-22 02:17:26 +01:00
(a_type != acquireWriteUncached)
}
2013-08-12 19:36:44 +02:00
def needsOuterWrite(a_type: UInt, global_state: UInt): Bool = {
2013-01-22 02:17:26 +01:00
(a_type === acquireWriteUncached)
}
2013-08-12 19:36:44 +02:00
def needsAckReply(a_type: UInt, global_state: UInt): Bool = {
2013-01-22 02:17:26 +01:00
(a_type === acquireWriteUncached)
}
def requiresAck(grant: Grant) = grant.g_type != grantVoluntaryAck
def requiresAck(release: Release) = Bool(false)
def needsSelfProbe(acq: Acquire) = Bool(false)
2013-08-12 19:36:44 +02:00
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData)
}
class MEICoherence extends CoherencePolicyWithUncached {
def nClientStates = 3
def nMasterStates = 2
def nAcquireTypes = 7
def nProbeTypes = 3
def nReleaseTypes = 7
def nGrantTypes = 8
2013-08-12 19:36:44 +02:00
val tileInvalid :: tileExclusiveClean :: tileExclusiveDirty :: Nil = Enum(nClientStates){ UInt() }
val globalInvalid :: globalExclusiveClean :: Nil = Enum(nMasterStates){ UInt() }
2013-08-12 19:36:44 +02:00
val acquireReadExclusiveClean :: acquireReadExclusiveDirty :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: Nil = Enum(nAcquireTypes){ UInt() }
val probeInvalidate :: probeDowngrade :: probeCopy :: Nil = Enum(nProbeTypes){ UInt() }
val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(nReleaseTypes){ UInt() }
val grantVoluntaryAck :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadExclusiveAck :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: Nil = Enum(nGrantTypes){ UInt() }
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)
2013-08-12 19:36:44 +02:00
def isHit (cmd: UInt, state: UInt): Bool = state != tileInvalid
def isValid (state: UInt): Bool = state != tileInvalid
2013-08-12 19:36:44 +02:00
def needsTransactionOnSecondaryMiss(cmd: UInt, outstanding: Acquire): Bool = {
(isRead(cmd) && messageIsUncached(outstanding)) ||
(isWriteIntent(cmd) && (outstanding.a_type != acquireReadExclusiveDirty))
}
2013-08-12 19:36:44 +02:00
def needsTransactionOnCacheControl(cmd: UInt, state: UInt): Bool = {
MuxLookup(cmd, (state === tileExclusiveDirty), Array(
M_INV -> (state === tileExclusiveDirty),
M_CLN -> (state === tileExclusiveDirty)
))
}
2013-08-12 19:36:44 +02:00
def needsWriteback (state: UInt): Bool = {
needsTransactionOnCacheControl(M_INV, state)
}
2013-08-12 19:36:44 +02:00
def newStateOnHit(cmd: UInt, state: UInt): UInt = {
Mux(isWrite(cmd), tileExclusiveDirty, state)
}
2013-08-12 19:36:44 +02:00
def newStateOnCacheControl(cmd: UInt) = {
MuxLookup(cmd, tileInvalid, Array(
M_INV -> tileInvalid,
M_CLN -> tileExclusiveClean
))
}
def newStateOnWriteback() = newStateOnCacheControl(M_INV)
def newStateOnFlush() = newStateOnCacheControl(M_INV)
2013-08-12 19:36:44 +02:00
def newStateOnGrant(incoming: Grant, outstanding: Acquire): UInt = {
2013-01-22 02:17:26 +01:00
MuxLookup(incoming.g_type, tileInvalid, Array(
grantReadExclusive -> Mux(outstanding.a_type === acquireReadExclusiveDirty, tileExclusiveDirty, tileExclusiveClean),
grantReadExclusiveAck -> tileExclusiveDirty,
grantReadUncached -> tileInvalid,
grantWriteUncached -> tileInvalid,
grantReadWordUncached -> tileInvalid,
grantWriteWordUncached -> tileInvalid,
grantAtomicUncached -> tileInvalid
))
}
2013-08-12 19:36:44 +02:00
def newStateOnProbe(incoming: Probe, state: UInt): Bits = {
MuxLookup(incoming.p_type, state, Array(
2013-01-22 02:17:26 +01:00
probeInvalidate -> tileInvalid,
probeDowngrade -> tileExclusiveClean,
probeCopy -> state
))
}
def getUncachedReadAcquireType = acquireReadUncached
def getUncachedWriteAcquireType = acquireWriteUncached
def getUncachedReadWordAcquireType = acquireReadWordUncached
def getUncachedWriteWordAcquireType = acquireWriteWordUncached
def getUncachedAtomicAcquireType = acquireAtomicUncached
2013-01-22 02:17:26 +01:00
def isUncachedReadTransaction(acq: Acquire) = acq.a_type === acquireReadUncached
def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData
def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck
2013-08-12 19:36:44 +02:00
def getAcquireTypeOnPrimaryMiss(cmd: UInt, state: UInt): UInt = {
Mux(isWriteIntent(cmd), acquireReadExclusiveDirty, acquireReadExclusiveClean)
}
2013-08-12 19:36:44 +02:00
def getAcquireTypeOnSecondaryMiss(cmd: UInt, state: UInt, outstanding: Acquire): UInt = {
Mux(isWriteIntent(cmd), acquireReadExclusiveDirty, outstanding.a_type)
}
2013-08-12 19:36:44 +02:00
def getReleaseTypeOnCacheControl(cmd: UInt): Bits = releaseVoluntaryInvalidateData // TODO
def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV)
2013-08-12 19:36:44 +02:00
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): Bits = {
2013-01-22 02:17:26 +01:00
val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array(
probeInvalidate -> releaseInvalidateData,
probeDowngrade -> releaseDowngradeData,
probeCopy -> releaseCopyData
))
2013-01-22 02:17:26 +01:00
val without_data = MuxLookup(incoming.p_type, releaseInvalidateAck, Array(
probeInvalidate -> releaseInvalidateAck,
probeDowngrade -> releaseDowngradeAck,
probeCopy -> releaseCopyAck
))
Mux(needsWriteback(state), with_data, without_data)
}
def messageHasData(msg: SourcedMessage) = msg match {
2013-08-12 19:36:44 +02:00
case acq: Acquire => uSIntListContains(hasDataAcquireTypeList, acq.a_type)
case grant: Grant => uSIntListContains(hasDataGrantTypeList, grant.g_type)
case rel: Release => uSIntListContains(hasDataReleaseTypeList, rel.r_type)
case _ => Bool(false)
}
2013-01-22 02:17:26 +01:00
def messageUpdatesDataArray (reply: Grant): Bool = {
(reply.g_type === grantReadExclusive)
}
2013-08-12 19:36:44 +02:00
def messageIsUncached(acq: Acquire): Bool = uSIntListContains(uncachedAcquireTypeList, acq.a_type)
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2)
2013-08-12 19:36:44 +02:00
def getGrantType(a_type: UInt, count: UInt): Bits = {
2013-01-22 02:17:26 +01:00
MuxLookup(a_type, grantReadUncached, Array(
acquireReadExclusiveClean -> grantReadExclusive,
acquireReadExclusiveDirty -> grantReadExclusive,
acquireReadUncached -> grantReadUncached,
acquireWriteUncached -> grantWriteUncached,
acquireReadWordUncached -> grantReadWordUncached,
acquireWriteWordUncached -> grantWriteWordUncached,
acquireAtomicUncached -> grantAtomicUncached
))
}
2013-08-12 19:36:44 +02:00
def getGrantType(rel: Release, count: UInt): Bits = {
MuxLookup(rel.r_type, grantReadUncached, Array(
releaseVoluntaryInvalidateData -> grantVoluntaryAck
))
}
2013-08-12 19:36:44 +02:00
def getProbeType(a_type: UInt, global_state: UInt): UInt = {
2013-01-22 02:17:26 +01:00
MuxLookup(a_type, probeCopy, Array(
acquireReadExclusiveClean -> probeInvalidate,
acquireReadExclusiveDirty -> probeInvalidate,
acquireReadUncached -> probeCopy,
acquireWriteUncached -> probeInvalidate,
acquireReadWordUncached -> probeCopy,
acquireWriteWordUncached -> probeInvalidate,
acquireAtomicUncached -> probeInvalidate
))
}
2013-08-12 19:36:44 +02:00
def needsOuterRead(a_type: UInt, global_state: UInt): Bool = {
2013-01-22 02:17:26 +01:00
(a_type != acquireWriteUncached)
}
2013-08-12 19:36:44 +02:00
def needsOuterWrite(a_type: UInt, global_state: UInt): Bool = {
2013-01-22 02:17:26 +01:00
(a_type === acquireWriteUncached)
}
2013-08-12 19:36:44 +02:00
def needsAckReply(a_type: UInt, global_state: UInt): Bool = {
2013-01-22 02:17:26 +01:00
(a_type === acquireWriteUncached)
}
def requiresAck(grant: Grant) = grant.g_type != grantVoluntaryAck
def requiresAck(release: Release) = Bool(false)
def needsSelfProbe(acq: Acquire) = Bool(false)
2013-08-12 19:36:44 +02:00
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData)
}
class MSICoherence extends CoherencePolicyWithUncached {
def nClientStates = 3
def nMasterStates = 3
def nAcquireTypes = 7
def nProbeTypes = 3
def nReleaseTypes = 7
def nGrantTypes = 9
2013-08-12 19:36:44 +02:00
val tileInvalid :: tileShared :: tileExclusiveDirty :: Nil = Enum(nClientStates){ UInt() }
val globalInvalid :: globalShared :: globalExclusive :: Nil = Enum(nMasterStates){ UInt() }
2013-08-12 19:36:44 +02:00
val acquireReadShared :: acquireReadExclusive :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: Nil = Enum(nAcquireTypes){ UInt() }
val probeInvalidate :: probeDowngrade :: probeCopy :: Nil = Enum(nProbeTypes){ UInt() }
val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(nReleaseTypes){ UInt() }
val grantVoluntaryAck :: grantReadShared :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadExclusiveAck :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: Nil = Enum(nGrantTypes){ UInt() }
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)
2013-08-12 19:36:44 +02:00
def isHit (cmd: UInt, state: UInt): Bool = {
Mux(isWriteIntent(cmd), (state === tileExclusiveDirty),
(state === tileShared || state === tileExclusiveDirty))
}
2013-08-12 19:36:44 +02:00
def isValid (state: UInt): Bool = {
state != tileInvalid
}
2013-08-12 19:36:44 +02:00
def needsTransactionOnSecondaryMiss(cmd: UInt, outstanding: Acquire): Bool = {
(isRead(cmd) && messageIsUncached(outstanding)) ||
(isWriteIntent(cmd) && (outstanding.a_type != acquireReadExclusive))
}
2013-08-12 19:36:44 +02:00
def needsTransactionOnCacheControl(cmd: UInt, state: UInt): Bool = {
MuxLookup(cmd, (state === tileExclusiveDirty), Array(
M_INV -> (state === tileExclusiveDirty),
M_CLN -> (state === tileExclusiveDirty)
))
}
2013-08-12 19:36:44 +02:00
def needsWriteback (state: UInt): Bool = {
needsTransactionOnCacheControl(M_INV, state)
}
2013-08-12 19:36:44 +02:00
def newStateOnHit(cmd: UInt, state: UInt): UInt = {
Mux(isWrite(cmd), tileExclusiveDirty, state)
}
2013-08-12 19:36:44 +02:00
def newStateOnCacheControl(cmd: UInt) = {
MuxLookup(cmd, tileInvalid, Array(
M_INV -> tileInvalid,
M_CLN -> tileShared
))
}
def newStateOnWriteback() = newStateOnCacheControl(M_INV)
def newStateOnFlush() = newStateOnCacheControl(M_INV)
2013-08-12 19:36:44 +02:00
def newStateOnGrant(incoming: Grant, outstanding: Acquire): UInt = {
2013-01-22 02:17:26 +01:00
MuxLookup(incoming.g_type, tileInvalid, Array(
grantReadShared -> tileShared,
grantReadExclusive -> tileExclusiveDirty,
grantReadExclusiveAck -> tileExclusiveDirty,
grantReadUncached -> tileInvalid,
grantWriteUncached -> tileInvalid,
grantReadWordUncached -> tileInvalid,
grantWriteWordUncached -> tileInvalid,
grantAtomicUncached -> tileInvalid
))
}
2013-08-12 19:36:44 +02:00
def newStateOnProbe(incoming: Probe, state: UInt): Bits = {
MuxLookup(incoming.p_type, state, Array(
2013-01-22 02:17:26 +01:00
probeInvalidate -> tileInvalid,
probeDowngrade -> tileShared,
probeCopy -> state
))
}
def getUncachedReadAcquireType = acquireReadUncached
def getUncachedWriteAcquireType = acquireWriteUncached
def getUncachedReadWordAcquireType = acquireReadWordUncached
def getUncachedWriteWordAcquireType = acquireWriteWordUncached
def getUncachedAtomicAcquireType = acquireAtomicUncached
2013-01-22 02:17:26 +01:00
def isUncachedReadTransaction(acq: Acquire) = acq.a_type === acquireReadUncached
def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData
def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck
2013-08-12 19:36:44 +02:00
def getAcquireTypeOnPrimaryMiss(cmd: UInt, state: UInt): UInt = {
2013-04-04 07:13:51 +02:00
Mux(isWriteIntent(cmd), acquireReadExclusive, acquireReadShared)
}
2013-08-12 19:36:44 +02:00
def getAcquireTypeOnSecondaryMiss(cmd: UInt, state: UInt, outstanding: Acquire): UInt = {
Mux(isWriteIntent(cmd), acquireReadExclusive, outstanding.a_type)
}
2013-08-12 19:36:44 +02:00
def getReleaseTypeOnCacheControl(cmd: UInt): Bits = releaseVoluntaryInvalidateData // TODO
def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV)
2013-08-12 19:36:44 +02:00
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): Bits = {
2013-01-22 02:17:26 +01:00
val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array(
probeInvalidate -> releaseInvalidateData,
probeDowngrade -> releaseDowngradeData,
probeCopy -> releaseCopyData
))
2013-01-22 02:17:26 +01:00
val without_data = MuxLookup(incoming.p_type, releaseInvalidateAck, Array(
probeInvalidate -> releaseInvalidateAck,
probeDowngrade -> releaseDowngradeAck,
probeCopy -> releaseCopyAck
))
Mux(needsWriteback(state), with_data, without_data)
}
def messageHasData(msg: SourcedMessage) = msg match {
2013-08-12 19:36:44 +02:00
case acq: Acquire => uSIntListContains(hasDataAcquireTypeList, acq.a_type)
case grant: Grant => uSIntListContains(hasDataGrantTypeList, grant.g_type)
case rel: Release => uSIntListContains(hasDataReleaseTypeList, rel.r_type)
case _ => Bool(false)
}
2013-01-22 02:17:26 +01:00
def messageUpdatesDataArray (reply: Grant): Bool = {
(reply.g_type === grantReadShared || reply.g_type === grantReadExclusive)
}
2013-08-12 19:36:44 +02:00
def messageIsUncached(acq: Acquire): Bool = uSIntListContains(uncachedAcquireTypeList, acq.a_type)
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2)
2013-08-12 19:36:44 +02:00
def getGrantType(a_type: UInt, count: UInt): Bits = {
2013-01-22 02:17:26 +01:00
MuxLookup(a_type, grantReadUncached, Array(
2013-08-12 19:36:44 +02:00
acquireReadShared -> Mux(count > UInt(0), grantReadShared, grantReadExclusive),
2013-01-22 02:17:26 +01:00
acquireReadExclusive -> grantReadExclusive,
acquireReadUncached -> grantReadUncached,
acquireWriteUncached -> grantWriteUncached,
acquireReadWordUncached -> grantReadWordUncached,
acquireWriteWordUncached -> grantWriteWordUncached,
acquireAtomicUncached -> grantAtomicUncached
))
}
2013-08-12 19:36:44 +02:00
def getGrantType(rel: Release, count: UInt): Bits = {
MuxLookup(rel.r_type, grantReadUncached, Array(
releaseVoluntaryInvalidateData -> grantVoluntaryAck
))
}
2013-08-12 19:36:44 +02:00
def getProbeType(a_type: UInt, global_state: UInt): UInt = {
2013-01-22 02:17:26 +01:00
MuxLookup(a_type, probeCopy, Array(
acquireReadShared -> probeDowngrade,
acquireReadExclusive -> probeInvalidate,
acquireReadUncached -> probeCopy,
acquireWriteUncached -> probeInvalidate
))
}
2013-08-12 19:36:44 +02:00
def needsOuterRead(a_type: UInt, global_state: UInt): Bool = {
2013-01-22 02:17:26 +01:00
(a_type != acquireWriteUncached)
}
2013-08-12 19:36:44 +02:00
def needsOuterWrite(a_type: UInt, global_state: UInt): Bool = {
2013-01-22 02:17:26 +01:00
(a_type === acquireWriteUncached)
}
2013-08-12 19:36:44 +02:00
def needsAckReply(a_type: UInt, global_state: UInt): Bool = {
2013-01-22 02:17:26 +01:00
(a_type === acquireWriteUncached)
}
def requiresAck(grant: Grant) = grant.g_type != grantVoluntaryAck
def requiresAck(release: Release) = Bool(false)
def needsSelfProbe(acq: Acquire) = Bool(false)
2013-08-12 19:36:44 +02:00
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData)
}
class MESICoherence extends CoherencePolicyWithUncached {
def nClientStates = 4
def nMasterStates = 3
def nAcquireTypes = 7
def nProbeTypes = 3
def nReleaseTypes = 7
def nGrantTypes = 9
2013-08-12 19:36:44 +02:00
val tileInvalid :: tileShared :: tileExclusiveClean :: tileExclusiveDirty :: Nil = Enum(nClientStates){ UInt() }
val globalInvalid :: globalShared :: globalExclusiveClean :: Nil = Enum(nMasterStates){ UInt() }
2013-08-12 19:36:44 +02:00
val acquireReadShared :: acquireReadExclusive :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: Nil = Enum(nAcquireTypes){ UInt() }
val probeInvalidate :: probeDowngrade :: probeCopy :: Nil = Enum(nProbeTypes){ UInt() }
val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(nReleaseTypes){ UInt() }
val grantVoluntaryAck :: grantReadShared :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadExclusiveAck :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: Nil = Enum(nGrantTypes){ UInt() }
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)
2013-08-12 19:36:44 +02:00
def isHit (cmd: UInt, state: UInt): Bool = {
Mux(isWriteIntent(cmd), (state === tileExclusiveClean || state === tileExclusiveDirty),
2012-03-12 18:38:37 +01:00
(state === tileShared || state === tileExclusiveClean || state === tileExclusiveDirty))
2012-02-16 21:59:38 +01:00
}
2013-08-12 19:36:44 +02:00
def isValid (state: UInt): Bool = {
2012-02-16 21:59:38 +01:00
state != tileInvalid
}
2013-08-12 19:36:44 +02:00
def needsTransactionOnSecondaryMiss(cmd: UInt, outstanding: Acquire): Bool = {
(isRead(cmd) && messageIsUncached(outstanding)) ||
(isWriteIntent(cmd) && (outstanding.a_type != acquireReadExclusive))
}
2013-08-12 19:36:44 +02:00
def needsTransactionOnCacheControl(cmd: UInt, state: UInt): Bool = {
MuxLookup(cmd, (state === tileExclusiveDirty), Array(
M_INV -> (state === tileExclusiveDirty),
M_CLN -> (state === tileExclusiveDirty)
))
}
2013-08-12 19:36:44 +02:00
def needsWriteback (state: UInt): Bool = {
needsTransactionOnCacheControl(M_INV, state)
}
2013-08-12 19:36:44 +02:00
def newStateOnHit(cmd: UInt, state: UInt): UInt = {
Mux(isWrite(cmd), tileExclusiveDirty, state)
}
2013-08-12 19:36:44 +02:00
def newStateOnCacheControl(cmd: UInt) = {
MuxLookup(cmd, tileInvalid, Array(
M_INV -> tileInvalid,
M_CLN -> tileShared
))
}
def newStateOnWriteback() = newStateOnCacheControl(M_INV)
def newStateOnFlush() = newStateOnCacheControl(M_INV)
2013-08-12 19:36:44 +02:00
def newStateOnGrant(incoming: Grant, outstanding: Acquire): UInt = {
2013-01-22 02:17:26 +01:00
MuxLookup(incoming.g_type, tileInvalid, Array(
grantReadShared -> tileShared,
grantReadExclusive -> Mux(outstanding.a_type === acquireReadExclusive, tileExclusiveDirty, tileExclusiveClean),
grantReadExclusiveAck -> tileExclusiveDirty,
grantReadUncached -> tileInvalid,
grantWriteUncached -> tileInvalid,
grantReadWordUncached -> tileInvalid,
grantWriteWordUncached -> tileInvalid,
grantAtomicUncached -> tileInvalid
))
}
2013-08-12 19:36:44 +02:00
def newStateOnProbe(incoming: Probe, state: UInt): Bits = {
MuxLookup(incoming.p_type, state, Array(
2013-01-22 02:17:26 +01:00
probeInvalidate -> tileInvalid,
probeDowngrade -> tileShared,
probeCopy -> state
))
}
def getUncachedReadAcquireType = acquireReadUncached
def getUncachedWriteAcquireType = acquireWriteUncached
def getUncachedReadWordAcquireType = acquireReadWordUncached
def getUncachedWriteWordAcquireType = acquireWriteWordUncached
def getUncachedAtomicAcquireType = acquireAtomicUncached
2013-01-22 02:17:26 +01:00
def isUncachedReadTransaction(acq: Acquire) = acq.a_type === acquireReadUncached
def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData
def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck
2013-08-12 19:36:44 +02:00
def getAcquireTypeOnPrimaryMiss(cmd: UInt, state: UInt): UInt = {
2013-04-04 07:13:51 +02:00
Mux(isWriteIntent(cmd), acquireReadExclusive, acquireReadShared)
}
2013-08-12 19:36:44 +02:00
def getAcquireTypeOnSecondaryMiss(cmd: UInt, state: UInt, outstanding: Acquire): UInt = {
Mux(isWriteIntent(cmd), acquireReadExclusive, outstanding.a_type)
}
2013-08-12 19:36:44 +02:00
def getReleaseTypeOnCacheControl(cmd: UInt): Bits = releaseVoluntaryInvalidateData // TODO
def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV)
2013-08-12 19:36:44 +02:00
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): Bits = {
2013-01-22 02:17:26 +01:00
val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array(
probeInvalidate -> releaseInvalidateData,
probeDowngrade -> releaseDowngradeData,
probeCopy -> releaseCopyData
2012-03-14 00:43:35 +01:00
))
2013-01-22 02:17:26 +01:00
val without_data = MuxLookup(incoming.p_type, releaseInvalidateAck, Array(
probeInvalidate -> releaseInvalidateAck,
probeDowngrade -> releaseDowngradeAck,
probeCopy -> releaseCopyAck
2012-03-14 00:43:35 +01:00
))
Mux(needsWriteback(state), with_data, without_data)
2012-03-14 00:43:35 +01:00
}
def messageHasData(msg: SourcedMessage) = msg match {
2013-08-12 19:36:44 +02:00
case acq: Acquire => uSIntListContains(hasDataAcquireTypeList, acq.a_type)
case grant: Grant => uSIntListContains(hasDataGrantTypeList, grant.g_type)
case rel: Release => uSIntListContains(hasDataReleaseTypeList, rel.r_type)
case _ => Bool(false)
}
2013-01-22 02:17:26 +01:00
def messageUpdatesDataArray (reply: Grant): Bool = {
(reply.g_type === grantReadShared || reply.g_type === grantReadExclusive)
}
2013-08-12 19:36:44 +02:00
def messageIsUncached(acq: Acquire): Bool = uSIntListContains(uncachedAcquireTypeList, acq.a_type)
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2)
2013-08-12 19:36:44 +02:00
def getGrantType(a_type: UInt, count: UInt): Bits = {
2013-01-22 02:17:26 +01:00
MuxLookup(a_type, grantReadUncached, Array(
2013-08-12 19:36:44 +02:00
acquireReadShared -> Mux(count > UInt(0), grantReadShared, grantReadExclusive),
2013-01-22 02:17:26 +01:00
acquireReadExclusive -> grantReadExclusive,
acquireReadUncached -> grantReadUncached,
acquireWriteUncached -> grantWriteUncached,
acquireReadWordUncached -> grantReadWordUncached,
acquireWriteWordUncached -> grantWriteWordUncached,
acquireAtomicUncached -> grantAtomicUncached
))
}
2013-08-12 19:36:44 +02:00
def getGrantType(rel: Release, count: UInt): Bits = {
MuxLookup(rel.r_type, grantReadUncached, Array(
releaseVoluntaryInvalidateData -> grantVoluntaryAck
))
}
2012-02-22 21:14:57 +01:00
2013-08-12 19:36:44 +02:00
def getProbeType(a_type: UInt, global_state: UInt): UInt = {
2013-01-22 02:17:26 +01:00
MuxLookup(a_type, probeCopy, Array(
acquireReadShared -> probeDowngrade,
acquireReadExclusive -> probeInvalidate,
acquireReadUncached -> probeCopy,
acquireWriteUncached -> probeInvalidate,
acquireReadWordUncached -> probeCopy,
acquireWriteWordUncached -> probeInvalidate,
acquireAtomicUncached -> probeInvalidate
))
}
2013-08-12 19:36:44 +02:00
def needsOuterRead(a_type: UInt, global_state: UInt): Bool = {
2013-01-22 02:17:26 +01:00
(a_type != acquireWriteUncached)
}
2013-08-12 19:36:44 +02:00
def needsOuterWrite(a_type: UInt, global_state: UInt): Bool = {
2013-01-22 02:17:26 +01:00
(a_type === acquireWriteUncached)
}
2013-08-12 19:36:44 +02:00
def needsAckReply(a_type: UInt, global_state: UInt): Bool = {
2013-01-22 02:17:26 +01:00
(a_type === acquireWriteUncached)
}
def requiresAck(grant: Grant) = grant.g_type != grantVoluntaryAck
def requiresAck(release: Release) = Bool(false)
def needsSelfProbe(acq: Acquire) = Bool(false)
2013-08-12 19:36:44 +02:00
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData)
}
2012-10-24 03:01:53 +02:00
class MigratoryCoherence extends CoherencePolicyWithUncached {
def nClientStates = 7
def nMasterStates = 0
def nAcquireTypes = 8
def nProbeTypes = 4
def nReleaseTypes = 11
def nGrantTypes = 9
2012-10-24 03:01:53 +02:00
2013-08-12 19:36:44 +02:00
val tileInvalid :: tileShared :: tileExclusiveClean :: tileExclusiveDirty :: tileSharedByTwo :: tileMigratoryClean :: tileMigratoryDirty :: Nil = Enum(nClientStates){ UInt() }
2012-10-24 03:01:53 +02:00
2013-08-12 19:36:44 +02:00
val acquireReadShared :: acquireReadExclusive :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: acquireInvalidateOthers :: Nil = Enum(nAcquireTypes){ UInt() }
val probeInvalidate :: probeDowngrade :: probeCopy :: probeInvalidateOthers :: Nil = Enum(nProbeTypes){ UInt() }
val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: releaseDowngradeDataMigratory :: releaseDowngradeAckHasCopy :: releaseInvalidateDataMigratory :: releaseInvalidateAckMigratory :: Nil = Enum(nReleaseTypes){ UInt() }
val grantVoluntaryAck :: grantReadShared :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadExclusiveAck :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: grantReadMigratory :: Nil = Enum(nGrantTypes){ UInt() }
2012-10-24 03:01:53 +02:00
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)
2012-10-24 03:01:53 +02:00
2013-08-12 19:36:44 +02:00
def isHit (cmd: UInt, state: UInt): Bool = {
Mux(isWriteIntent(cmd), uSIntListContains(List(tileExclusiveClean, tileExclusiveDirty, tileMigratoryClean, tileMigratoryDirty), state), (state != tileInvalid))
2012-10-24 03:01:53 +02:00
}
2013-08-12 19:36:44 +02:00
def isValid (state: UInt): Bool = {
2012-10-24 03:01:53 +02:00
state != tileInvalid
}
2013-08-12 19:36:44 +02:00
def needsTransactionOnSecondaryMiss(cmd: UInt, outstanding: Acquire): Bool = {
(isRead(cmd) && messageIsUncached(outstanding)) ||
(isWriteIntent(cmd) && (outstanding.a_type != acquireReadExclusive && outstanding.a_type != acquireInvalidateOthers))
2012-10-24 03:01:53 +02:00
}
2013-08-12 19:36:44 +02:00
def needsTransactionOnCacheControl(cmd: UInt, state: UInt): Bool = {
2012-10-24 03:01:53 +02:00
MuxLookup(cmd, (state === tileExclusiveDirty), Array(
2013-08-12 19:36:44 +02:00
M_INV -> uSIntListContains(List(tileExclusiveDirty,tileMigratoryDirty),state),
M_CLN -> uSIntListContains(List(tileExclusiveDirty,tileMigratoryDirty),state)
2012-10-24 03:01:53 +02:00
))
}
2013-08-12 19:36:44 +02:00
def needsWriteback (state: UInt): Bool = {
2012-10-24 03:01:53 +02:00
needsTransactionOnCacheControl(M_INV, state)
}
2013-08-12 19:36:44 +02:00
def newStateOnHit(cmd: UInt, state: UInt): UInt = {
Mux(isWrite(cmd), MuxLookup(state, tileExclusiveDirty, Array(
2012-10-24 03:01:53 +02:00
tileExclusiveClean -> tileExclusiveDirty,
tileMigratoryClean -> tileMigratoryDirty)), state)
}
2013-08-12 19:36:44 +02:00
def newStateOnCacheControl(cmd: UInt) = {
2012-10-24 03:01:53 +02:00
MuxLookup(cmd, tileInvalid, Array(
M_INV -> tileInvalid,
M_CLN -> tileShared
))
}
def newStateOnWriteback() = newStateOnCacheControl(M_INV)
def newStateOnFlush() = newStateOnCacheControl(M_INV)
2013-08-12 19:36:44 +02:00
def newStateOnGrant(incoming: Grant, outstanding: Acquire): UInt = {
2013-01-22 02:17:26 +01:00
MuxLookup(incoming.g_type, tileInvalid, Array(
grantReadShared -> tileShared,
grantReadExclusive -> MuxLookup(outstanding.a_type, tileExclusiveDirty, Array(
acquireReadExclusive -> tileExclusiveDirty,
acquireReadShared -> tileExclusiveClean)),
grantReadExclusiveAck -> tileExclusiveDirty,
grantReadUncached -> tileInvalid,
grantWriteUncached -> tileInvalid,
grantReadWordUncached -> tileInvalid,
grantWriteWordUncached -> tileInvalid,
grantAtomicUncached -> tileInvalid,
grantReadMigratory -> MuxLookup(outstanding.a_type, tileMigratoryDirty, Array(
acquireInvalidateOthers -> tileMigratoryDirty,
acquireReadExclusive -> tileMigratoryDirty,
acquireReadShared -> tileMigratoryClean))
2012-10-24 03:01:53 +02:00
))
}
2013-08-12 19:36:44 +02:00
def newStateOnProbe(incoming: Probe, state: UInt): Bits = {
2012-10-24 03:01:53 +02:00
MuxLookup(incoming.p_type, state, Array(
2013-01-22 02:17:26 +01:00
probeInvalidate -> tileInvalid,
probeInvalidateOthers -> tileInvalid,
probeCopy -> state,
probeDowngrade -> MuxLookup(state, tileShared, Array(
2012-10-24 03:01:53 +02:00
tileExclusiveClean -> tileSharedByTwo,
tileExclusiveDirty -> tileSharedByTwo,
tileSharedByTwo -> tileShared,
tileMigratoryClean -> tileSharedByTwo,
tileMigratoryDirty -> tileInvalid))
))
}
def getUncachedReadAcquireType = acquireReadUncached
def getUncachedWriteAcquireType = acquireWriteUncached
def getUncachedReadWordAcquireType = acquireReadWordUncached
def getUncachedWriteWordAcquireType = acquireWriteWordUncached
def getUncachedAtomicAcquireType = acquireAtomicUncached
2013-01-22 02:17:26 +01:00
def isUncachedReadTransaction(acq: Acquire) = acq.a_type === acquireReadUncached
def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData
def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck
2012-10-24 03:01:53 +02:00
2013-08-12 19:36:44 +02:00
def getAcquireTypeOnPrimaryMiss(cmd: UInt, state: UInt): UInt = {
2013-04-04 07:13:51 +02:00
Mux(isWriteIntent(cmd), Mux(state === tileInvalid, acquireReadExclusive, acquireInvalidateOthers), acquireReadShared)
2012-10-24 03:01:53 +02:00
}
2013-08-12 19:36:44 +02:00
def getAcquireTypeOnSecondaryMiss(cmd: UInt, state: UInt, outstanding: Acquire): UInt = {
Mux(isWriteIntent(cmd), Mux(state === tileInvalid, acquireReadExclusive, acquireInvalidateOthers), outstanding.a_type)
2013-01-22 02:17:26 +01:00
}
2013-08-12 19:36:44 +02:00
def getReleaseTypeOnCacheControl(cmd: UInt): Bits = releaseVoluntaryInvalidateData // TODO
def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV)
2013-08-12 19:36:44 +02:00
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): Bits = {
2013-01-22 02:17:26 +01:00
val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array(
2013-08-12 19:36:44 +02:00
probeInvalidate -> Mux(uSIntListContains(List(tileExclusiveDirty, tileMigratoryDirty), state),
2013-01-22 02:17:26 +01:00
releaseInvalidateDataMigratory, releaseInvalidateData),
probeDowngrade -> Mux(state === tileMigratoryDirty, releaseDowngradeDataMigratory, releaseDowngradeData),
probeCopy -> releaseCopyData
2013-01-22 02:17:26 +01:00
))
val without_data = MuxLookup(incoming.p_type, releaseInvalidateAck, Array(
probeInvalidate -> Mux(tileExclusiveClean === state, releaseInvalidateAckMigratory, releaseInvalidateAck),
2013-01-22 02:17:26 +01:00
probeInvalidateOthers -> Mux(state === tileSharedByTwo, releaseInvalidateAckMigratory, releaseInvalidateAck),
probeDowngrade -> Mux(state != tileInvalid, releaseDowngradeAckHasCopy, releaseDowngradeAck),
probeCopy -> releaseCopyAck
))
Mux(needsWriteback(state), with_data, without_data)
2012-10-24 03:01:53 +02:00
}
def messageHasData(msg: SourcedMessage) = msg match {
2013-08-12 19:36:44 +02:00
case acq: Acquire => uSIntListContains(hasDataAcquireTypeList, acq.a_type)
case grant: Grant => uSIntListContains(hasDataGrantTypeList, grant.g_type)
case rel: Release => uSIntListContains(hasDataReleaseTypeList, rel.r_type)
case _ => Bool(false)
}
2013-01-22 02:17:26 +01:00
def messageUpdatesDataArray (reply: Grant): Bool = {
2013-08-12 19:36:44 +02:00
uSIntListContains(List(grantReadShared, grantReadExclusive, grantReadMigratory), reply.g_type)
2012-10-24 03:01:53 +02:00
}
2013-08-12 19:36:44 +02:00
def messageIsUncached(acq: Acquire): Bool = uSIntListContains(uncachedAcquireTypeList, acq.a_type)
2012-10-24 03:01:53 +02:00
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2)
2013-08-12 19:36:44 +02:00
def getGrantType(a_type: UInt, count: UInt): Bits = {
2013-01-22 02:17:26 +01:00
MuxLookup(a_type, grantReadUncached, Array(
2013-08-12 19:36:44 +02:00
acquireReadShared -> Mux(count > UInt(0), grantReadShared, grantReadExclusive), //TODO: what is count? Depend on release.p_type???
2013-01-22 02:17:26 +01:00
acquireReadExclusive -> grantReadExclusive,
acquireReadUncached -> grantReadUncached,
acquireWriteUncached -> grantWriteUncached,
acquireReadWordUncached -> grantReadWordUncached,
acquireWriteWordUncached -> grantWriteWordUncached,
acquireAtomicUncached -> grantAtomicUncached,
acquireInvalidateOthers -> grantReadExclusiveAck //TODO: add this to MESI?
2012-10-24 03:01:53 +02:00
))
}
2013-08-12 19:36:44 +02:00
def getGrantType(rel: Release, count: UInt): Bits = {
MuxLookup(rel.r_type, grantReadUncached, Array(
releaseVoluntaryInvalidateData -> grantVoluntaryAck
))
}
2012-10-24 03:01:53 +02:00
2013-08-12 19:36:44 +02:00
def getProbeType(a_type: UInt, global_state: UInt): UInt = {
2013-01-22 02:17:26 +01:00
MuxLookup(a_type, probeCopy, Array(
acquireReadShared -> probeDowngrade,
acquireReadExclusive -> probeInvalidate,
acquireReadUncached -> probeCopy,
acquireWriteUncached -> probeInvalidate,
acquireReadWordUncached -> probeCopy,
acquireWriteWordUncached -> probeInvalidate,
acquireAtomicUncached -> probeInvalidate,
acquireInvalidateOthers -> probeInvalidateOthers
2012-10-24 03:01:53 +02:00
))
}
2013-08-12 19:36:44 +02:00
def needsOuterRead(a_type: UInt, global_state: UInt): Bool = {
2013-01-22 02:17:26 +01:00
(a_type != acquireWriteUncached && a_type != acquireInvalidateOthers)
2012-10-24 03:01:53 +02:00
}
2013-08-12 19:36:44 +02:00
def needsOuterWrite(a_type: UInt, global_state: UInt): Bool = {
2013-01-22 02:17:26 +01:00
(a_type === acquireWriteUncached || a_type === acquireWriteWordUncached || a_type === acquireAtomicUncached)
2012-10-24 03:01:53 +02:00
}
2013-08-12 19:36:44 +02:00
def needsAckReply(a_type: UInt, global_state: UInt): Bool = {
2013-01-22 02:17:26 +01:00
(a_type === acquireWriteUncached || a_type === acquireWriteWordUncached ||a_type === acquireInvalidateOthers)
2012-10-24 03:01:53 +02:00
}
def requiresAck(grant: Grant) = grant.g_type != grantVoluntaryAck
def requiresAck(release: Release) = Bool(false)
def needsSelfProbe(acq: Acquire) = Bool(false)
2013-08-12 19:36:44 +02:00
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData)
2012-10-24 03:01:53 +02:00
}