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

919 lines
46 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 isHit (cmd: Bits, state: UFix): Bool
def isValid (state: UFix): Bool
2013-01-22 02:17:26 +01:00
def needsTransactionOnSecondaryMiss(cmd: Bits, outstanding: Acquire): Bool
def needsTransactionOnCacheControl(cmd: Bits, state: UFix): Bool
def needsWriteback (state: UFix): Bool
def newStateOnHit(cmd: Bits, state: UFix): UFix
def newStateOnCacheControl(cmd: Bits): UFix
def newStateOnWriteback(): UFix
def newStateOnFlush(): UFix
2013-01-22 02:17:26 +01:00
def newStateOnGrant(incoming: Grant, outstanding: Acquire): UFix
def newStateOnProbe(incoming: Probe, state: UFix): Bits
2013-01-22 02:17:26 +01:00
def getAcquireTypeOnPrimaryMiss(cmd: Bits, state: UFix): UFix
def getAcquireTypeOnSecondaryMiss(cmd: Bits, state: UFix, outstanding: Acquire): UFix
def getReleaseTypeOnCacheControl(cmd: Bits): Bits
def getReleaseTypeOnVoluntaryWriteback(): Bits
def getVoluntaryWriteback(addr: UFix, client_id: UFix, master_id: UFix): Release
def newRelease (incoming: Probe, state: UFix, id: UFix): Release
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-01-22 02:17:26 +01:00
def getGrantType(a_type: UFix, count: UFix): Bits
def getGrantType(rel: Release, count: UFix): Bits
2013-01-22 02:17:26 +01:00
def getProbeType(a_type: UFix, global_state: UFix): UFix
def needsOuterRead(a_type: UFix, global_state: UFix): Bool
def needsOuterWrite(a_type: UFix, global_state: UFix): Bool
2013-01-22 02:17:26 +01:00
def needsAckReply(a_type: UFix, global_state: UFix): Bool
2013-03-01 04:49:05 +01:00
def needsSelfProbe(acq: Acquire): Bool
def requiresAck(grant: Grant): Bool
def requiresAck(release: Release): Bool
def pendingVoluntaryReleaseIsSufficient(r_type: UFix, p_type: UFix): Bool
def uFixListContains(list: List[UFix], elem: UFix): Bool = list.map(elem === _).reduceLeft(_||_)
}
2012-03-02 03:49:00 +01:00
trait UncachedTransactions {
2013-01-22 02:17:26 +01:00
def getUncachedReadAcquire(addr: UFix, id: UFix): Acquire
def getUncachedWriteAcquire(addr: UFix, id: UFix): Acquire
def getUncachedReadWordAcquire(addr: UFix, id: UFix): Acquire
def getUncachedWriteWordAcquire(addr: UFix, id: UFix, write_mask: Bits): Acquire
def getUncachedAtomicAcquire(addr: UFix, id: UFix, subword_addr: UFix, atomic_op: UFix): Acquire
def isUncachedReadTransaction(acq: Acquire): Bool
}
abstract class CoherencePolicyWithUncached extends CoherencePolicy with UncachedTransactions
abstract class IncoherentPolicy extends CoherencePolicy {
// UNIMPLEMENTED
2013-01-22 02:17:26 +01:00
def newStateOnProbe(incoming: Probe, state: UFix): Bits = state
def newRelease (incoming: Probe, state: UFix, id: UFix): Release = Release( UFix(0), UFix(0), UFix(0), UFix(0))
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = Bool(false)
2013-01-22 02:17:26 +01:00
def getGrantType(a_type: UFix, count: UFix): Bits = Bits(0)
def getGrantType(rel: Release, count: UFix): Bits = Bits(0)
2013-01-22 02:17:26 +01:00
def getProbeType(a_type: UFix, global_state: UFix): UFix = UFix(0)
def needsOuterRead(a_type: UFix, global_state: UFix): Bool = Bool(false)
def needsOuterWrite(a_type: UFix, global_state: UFix): Bool = Bool(false)
2013-01-22 02:17:26 +01:00
def needsAckReply(a_type: UFix, global_state: UFix): 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)
def pendingVoluntaryReleaseIsSufficient(r_type: UFix, p_type: UFix): Bool = Bool(false)
}
class ThreeStateIncoherence extends IncoherentPolicy {
val tileInvalid :: tileClean :: tileDirty :: Nil = Enum(3){ UFix() }
2013-01-22 02:17:26 +01:00
val acquireReadClean :: acquireReadDirty :: acquireWriteback :: Nil = Enum(3){ UFix() }
val grantVoluntaryAck :: grantData :: grantAck :: Nil = Enum(3){ UFix() }
val releaseVoluntaryInvalidateData :: releaseInvalidateAck :: Nil = Enum(2){ UFix() }
val uncachedAcquireTypeList = List()
val hasDataAcquireTypeList = List(acquireWriteback)
val hasDataReleaseTypeList = List(acquireWriteback)
val hasDataGrantTypeList = List(grantData)
def isHit ( cmd: Bits, state: UFix): Bool = (state === tileClean || state === tileDirty)
def isValid (state: UFix): Bool = state != tileInvalid
2013-01-22 02:17:26 +01:00
def needsTransactionOnSecondaryMiss(cmd: Bits, outstanding: Acquire) = Bool(false)
def needsTransactionOnCacheControl(cmd: Bits, state: UFix): Bool = state === tileDirty
def needsWriteback (state: UFix): Bool = state === tileDirty
def newState(cmd: Bits, state: UFix): UFix = {
Mux(isWrite(cmd), tileDirty, Mux(isRead(cmd), Mux(state === tileDirty, tileDirty, tileClean), state))
}
def newStateOnHit(cmd: Bits, state: UFix): UFix = newState(cmd, state)
def newStateOnCacheControl(cmd: Bits) = 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 getVoluntaryWriteback(addr: UFix, client_id: UFix, master_id: UFix) = Release(releaseVoluntaryInvalidateData, addr, client_id, master_id)
def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData
def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck
2013-01-22 02:17:26 +01:00
def getAcquireTypeOnPrimaryMiss(cmd: Bits, state: UFix): UFix = {
2013-04-04 07:13:51 +02:00
Mux(isWriteIntent(cmd), acquireReadDirty, acquireReadClean)
}
2013-01-22 02:17:26 +01:00
def getAcquireTypeOnSecondaryMiss(cmd: Bits, state: UFix, outstanding: Acquire): UFix = {
Mux(isWriteIntent(cmd), acquireReadDirty, outstanding.a_type)
}
def getReleaseTypeOnCacheControl(cmd: Bits): Bits = releaseVoluntaryInvalidateData // TODO
def getReleaseTypeOnVoluntaryWriteback(): Bits = releaseVoluntaryInvalidateData
def messageHasData( msg: SourcedMessage ) = msg match {
case acq: Acquire => uFixListContains(hasDataAcquireTypeList, acq.a_type)
case grant: Grant => uFixListContains(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)
def messageIsUncached(acq: Acquire): Bool = uFixListContains(uncachedAcquireTypeList, acq.a_type)
}
class MICoherence extends CoherencePolicyWithUncached {
val tileInvalid :: tileValid :: Nil = Enum(2){ UFix() }
val globalInvalid :: globalValid :: Nil = Enum(2){ UFix() }
2013-01-22 02:17:26 +01:00
val acquireReadExclusive :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: Nil = Enum(6){ UFix() }
val grantVoluntaryAck :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: Nil = Enum(7){ UFix() }
2013-01-22 02:17:26 +01:00
val probeInvalidate :: probeCopy :: Nil = Enum(2){ UFix() }
val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseCopyData :: releaseInvalidateAck :: releaseCopyAck :: Nil = Enum(5){ UFix() }
val uncachedAcquireTypeList = List(acquireReadUncached, acquireWriteUncached, acquireReadWordUncached, acquireWriteWordUncached, acquireAtomicUncached)
val hasDataAcquireTypeList = List(acquireWriteUncached, acquireWriteWordUncached, acquireAtomicUncached)
val hasDataReleaseTypeList = List(releaseVoluntaryInvalidateData, releaseInvalidateData, releaseCopyData)
val hasDataGrantTypeList = List(grantReadExclusive, grantReadUncached, grantReadWordUncached, grantAtomicUncached)
def isHit (cmd: Bits, state: UFix): Bool = state != tileInvalid
def isValid (state: UFix): Bool = state != tileInvalid
2013-01-22 02:17:26 +01:00
def needsTransactionOnSecondaryMiss(cmd: Bits, outstanding: Acquire): Bool = (outstanding.a_type != acquireReadExclusive)
def needsTransactionOnCacheControl(cmd: Bits, state: UFix): Bool = {
MuxLookup(cmd, (state === tileValid), Array(
M_INV -> (state === tileValid),
M_CLN -> (state === tileValid)
))
}
def needsWriteback (state: UFix): Bool = {
needsTransactionOnCacheControl(M_INV, state)
}
def newStateOnHit(cmd: Bits, state: UFix): UFix = state
def newStateOnCacheControl(cmd: Bits) = {
MuxLookup(cmd, tileInvalid, Array(
M_INV -> tileInvalid,
M_CLN -> tileValid
))
}
def newStateOnWriteback() = newStateOnCacheControl(M_INV)
def newStateOnFlush() = newStateOnCacheControl(M_INV)
2013-01-22 02:17:26 +01:00
def newStateOnGrant(incoming: Grant, outstanding: Acquire): UFix = {
MuxLookup(incoming.g_type, tileInvalid, Array(
grantReadExclusive -> tileValid,
grantReadUncached -> tileInvalid,
grantWriteUncached -> tileInvalid,
grantReadWordUncached -> tileInvalid,
grantWriteWordUncached -> tileInvalid,
grantAtomicUncached -> tileInvalid
))
}
2013-01-22 02:17:26 +01:00
def newStateOnProbe(incoming: Probe, state: UFix): Bits = {
MuxLookup(incoming.p_type, state, Array(
2013-01-22 02:17:26 +01:00
probeInvalidate -> tileInvalid,
probeCopy -> state
))
}
2013-01-22 02:17:26 +01:00
def getUncachedReadAcquire(addr: UFix, id: UFix) = Acquire(acquireReadUncached, addr, id)
def getUncachedWriteAcquire(addr: UFix, id: UFix) = Acquire(acquireWriteUncached, addr, id)
def getUncachedReadWordAcquire(addr: UFix, id: UFix) = Acquire(acquireReadWordUncached, addr, id)
def getUncachedWriteWordAcquire(addr: UFix, id: UFix, write_mask: Bits) = Acquire(acquireWriteWordUncached, addr, id, write_mask)
def getUncachedAtomicAcquire(addr: UFix, id: UFix, subword_addr: UFix, atomic_op: UFix) = Acquire(acquireAtomicUncached, addr, id, subword_addr, atomic_op)
def getVoluntaryWriteback(addr: UFix, client_id: UFix, master_id: UFix) = Release(releaseVoluntaryInvalidateData, addr, client_id, master_id)
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-01-22 02:17:26 +01:00
def getAcquireTypeOnPrimaryMiss(cmd: Bits, state: UFix): UFix = acquireReadExclusive
def getAcquireTypeOnSecondaryMiss(cmd: Bits, state: UFix, outstanding: Acquire): UFix = acquireReadExclusive
def getReleaseTypeOnCacheControl(cmd: Bits): Bits = releaseVoluntaryInvalidateData // TODO
def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV)
def newRelease (incoming: Probe, state: UFix, id: UFix): Release = {
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
))
Release( Mux(needsWriteback(state), with_data, without_data), incoming.addr, id, incoming.master_xact_id)
}
def messageHasData(msg: SourcedMessage) = msg match {
case acq: Acquire => uFixListContains(hasDataAcquireTypeList, acq.a_type)
case grant: Grant => uFixListContains(hasDataGrantTypeList, grant.g_type)
case rel: Release => uFixListContains(hasDataReleaseTypeList, rel.r_type)
case _ => Bool(false)
}
2013-01-22 02:17:26 +01:00
def messageUpdatesDataArray (reply: Grant): Bool = {
(reply.g_type === grantReadExclusive)
}
def messageIsUncached(acq: Acquire): Bool = uFixListContains(uncachedAcquireTypeList, acq.a_type)
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2)
2013-01-22 02:17:26 +01:00
def getGrantType(a_type: UFix, count: UFix): Bits = {
MuxLookup(a_type, grantReadUncached, Array(
acquireReadExclusive -> grantReadExclusive,
acquireReadUncached -> grantReadUncached,
acquireWriteUncached -> grantWriteUncached,
acquireReadWordUncached -> grantReadWordUncached,
acquireWriteWordUncached -> grantWriteWordUncached,
acquireAtomicUncached -> grantAtomicUncached
))
}
def getGrantType(rel: Release, count: UFix): Bits = {
MuxLookup(rel.r_type, grantReadUncached, Array(
releaseVoluntaryInvalidateData -> grantVoluntaryAck
))
}
2013-01-22 02:17:26 +01:00
def getProbeType(a_type: UFix, global_state: UFix): UFix = {
MuxLookup(a_type, probeCopy, Array(
acquireReadExclusive -> probeInvalidate,
acquireReadUncached -> probeCopy,
acquireWriteUncached -> probeInvalidate,
acquireReadWordUncached -> probeCopy,
acquireWriteWordUncached -> probeInvalidate,
acquireAtomicUncached -> probeInvalidate
))
}
def needsOuterRead(a_type: UFix, global_state: UFix): Bool = {
2013-01-22 02:17:26 +01:00
(a_type != acquireWriteUncached)
}
def needsOuterWrite(a_type: UFix, global_state: UFix): Bool = {
2013-01-22 02:17:26 +01:00
(a_type === acquireWriteUncached)
}
2013-01-22 02:17:26 +01:00
def needsAckReply(a_type: UFix, global_state: UFix): Bool = {
(a_type === acquireWriteUncached)
}
def requiresAck(grant: Grant) = grant.g_type != grantVoluntaryAck
def requiresAck(release: Release) = Bool(false)
def needsSelfProbe(acq: Acquire) = Bool(false)
def pendingVoluntaryReleaseIsSufficient(r_type: UFix, p_type: UFix): Bool = (r_type === releaseVoluntaryInvalidateData)
}
class MEICoherence extends CoherencePolicyWithUncached {
val tileInvalid :: tileExclusiveClean :: tileExclusiveDirty :: Nil = Enum(3){ UFix() }
val globalInvalid :: globalExclusiveClean :: Nil = Enum(2){ UFix() }
2013-01-22 02:17:26 +01:00
val acquireReadExclusiveClean :: acquireReadExclusiveDirty :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: Nil = Enum(7){ UFix() }
val grantVoluntaryAck :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadExclusiveAck :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: Nil = Enum(8){ UFix() }
2013-01-22 02:17:26 +01:00
val probeInvalidate :: probeDowngrade :: probeCopy :: Nil = Enum(3){ UFix() }
val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(7){ UFix() }
val uncachedAcquireTypeList = List(acquireReadUncached, acquireWriteUncached, acquireReadWordUncached, acquireWriteWordUncached, acquireAtomicUncached)
val hasDataAcquireTypeList = List(acquireWriteUncached, acquireWriteWordUncached, acquireAtomicUncached)
val hasDataReleaseTypeList = List(releaseVoluntaryInvalidateData, releaseInvalidateData, releaseDowngradeData, releaseCopyData)
val hasDataGrantTypeList = List(grantReadExclusive, grantReadUncached, grantReadWordUncached, grantAtomicUncached)
def isHit (cmd: Bits, state: UFix): Bool = state != tileInvalid
def isValid (state: UFix): Bool = state != tileInvalid
2013-01-22 02:17:26 +01:00
def needsTransactionOnSecondaryMiss(cmd: Bits, outstanding: Acquire): Bool = {
(isRead(cmd) && messageIsUncached(outstanding)) ||
(isWriteIntent(cmd) && (outstanding.a_type != acquireReadExclusiveDirty))
}
def needsTransactionOnCacheControl(cmd: Bits, state: UFix): Bool = {
MuxLookup(cmd, (state === tileExclusiveDirty), Array(
M_INV -> (state === tileExclusiveDirty),
M_CLN -> (state === tileExclusiveDirty)
))
}
def needsWriteback (state: UFix): Bool = {
needsTransactionOnCacheControl(M_INV, state)
}
def newStateOnHit(cmd: Bits, state: UFix): UFix = {
Mux(isWrite(cmd), tileExclusiveDirty, state)
}
def newStateOnCacheControl(cmd: Bits) = {
MuxLookup(cmd, tileInvalid, Array(
M_INV -> tileInvalid,
M_CLN -> tileExclusiveClean
))
}
def newStateOnWriteback() = newStateOnCacheControl(M_INV)
def newStateOnFlush() = newStateOnCacheControl(M_INV)
2013-01-22 02:17:26 +01:00
def newStateOnGrant(incoming: Grant, outstanding: Acquire): UFix = {
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-01-22 02:17:26 +01:00
def newStateOnProbe(incoming: Probe, state: UFix): Bits = {
MuxLookup(incoming.p_type, state, Array(
2013-01-22 02:17:26 +01:00
probeInvalidate -> tileInvalid,
probeDowngrade -> tileExclusiveClean,
probeCopy -> state
))
}
2013-01-22 02:17:26 +01:00
def getUncachedReadAcquire(addr: UFix, id: UFix) = Acquire(acquireReadUncached, addr, id)
def getUncachedWriteAcquire(addr: UFix, id: UFix) = Acquire(acquireWriteUncached, addr, id)
def getUncachedReadWordAcquire(addr: UFix, id: UFix) = Acquire(acquireReadWordUncached, addr, id)
def getUncachedWriteWordAcquire(addr: UFix, id: UFix, write_mask: Bits) = Acquire(acquireWriteWordUncached, addr, id, write_mask)
def getUncachedAtomicAcquire(addr: UFix, id: UFix, subword_addr: UFix, atomic_op: UFix) = Acquire(acquireAtomicUncached, addr, id, subword_addr, atomic_op)
def getVoluntaryWriteback(addr: UFix, client_id: UFix, master_id: UFix) = Release(releaseVoluntaryInvalidateData, addr, client_id, master_id)
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-01-22 02:17:26 +01:00
def getAcquireTypeOnPrimaryMiss(cmd: Bits, state: UFix): UFix = {
Mux(isWriteIntent(cmd), acquireReadExclusiveDirty, acquireReadExclusiveClean)
}
2013-01-22 02:17:26 +01:00
def getAcquireTypeOnSecondaryMiss(cmd: Bits, state: UFix, outstanding: Acquire): UFix = {
Mux(isWriteIntent(cmd), acquireReadExclusiveDirty, outstanding.a_type)
}
def getReleaseTypeOnCacheControl(cmd: Bits): Bits = releaseVoluntaryInvalidateData // TODO
def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV)
def newRelease (incoming: Probe, state: UFix, id: UFix): Release = {
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
))
Release( Mux(needsWriteback(state), with_data, without_data), incoming.addr, id, incoming.master_xact_id)
}
def messageHasData(msg: SourcedMessage) = msg match {
case acq: Acquire => uFixListContains(hasDataAcquireTypeList, acq.a_type)
case grant: Grant => uFixListContains(hasDataGrantTypeList, grant.g_type)
case rel: Release => uFixListContains(hasDataReleaseTypeList, rel.r_type)
case _ => Bool(false)
}
2013-01-22 02:17:26 +01:00
def messageUpdatesDataArray (reply: Grant): Bool = {
(reply.g_type === grantReadExclusive)
}
def messageIsUncached(acq: Acquire): Bool = uFixListContains(uncachedAcquireTypeList, acq.a_type)
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2)
2013-01-22 02:17:26 +01:00
def getGrantType(a_type: UFix, count: UFix): Bits = {
MuxLookup(a_type, grantReadUncached, Array(
acquireReadExclusiveClean -> grantReadExclusive,
acquireReadExclusiveDirty -> grantReadExclusive,
acquireReadUncached -> grantReadUncached,
acquireWriteUncached -> grantWriteUncached,
acquireReadWordUncached -> grantReadWordUncached,
acquireWriteWordUncached -> grantWriteWordUncached,
acquireAtomicUncached -> grantAtomicUncached
))
}
def getGrantType(rel: Release, count: UFix): Bits = {
MuxLookup(rel.r_type, grantReadUncached, Array(
releaseVoluntaryInvalidateData -> grantVoluntaryAck
))
}
2013-01-22 02:17:26 +01:00
def getProbeType(a_type: UFix, global_state: UFix): UFix = {
MuxLookup(a_type, probeCopy, Array(
acquireReadExclusiveClean -> probeInvalidate,
acquireReadExclusiveDirty -> probeInvalidate,
acquireReadUncached -> probeCopy,
acquireWriteUncached -> probeInvalidate,
acquireReadWordUncached -> probeCopy,
acquireWriteWordUncached -> probeInvalidate,
acquireAtomicUncached -> probeInvalidate
))
}
def needsOuterRead(a_type: UFix, global_state: UFix): Bool = {
2013-01-22 02:17:26 +01:00
(a_type != acquireWriteUncached)
}
def needsOuterWrite(a_type: UFix, global_state: UFix): Bool = {
2013-01-22 02:17:26 +01:00
(a_type === acquireWriteUncached)
}
2013-01-22 02:17:26 +01:00
def needsAckReply(a_type: UFix, global_state: UFix): Bool = {
(a_type === acquireWriteUncached)
}
def requiresAck(grant: Grant) = grant.g_type != grantVoluntaryAck
def requiresAck(release: Release) = Bool(false)
def needsSelfProbe(acq: Acquire) = Bool(false)
def pendingVoluntaryReleaseIsSufficient(r_type: UFix, p_type: UFix): Bool = (r_type === releaseVoluntaryInvalidateData)
}
class MSICoherence extends CoherencePolicyWithUncached {
val tileInvalid :: tileShared :: tileExclusiveDirty :: Nil = Enum(3){ UFix() }
val globalInvalid :: globalShared :: globalExclusive :: Nil = Enum(3){ UFix() }
2013-01-22 02:17:26 +01:00
val acquireReadShared :: acquireReadExclusive :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: Nil = Enum(7){ UFix() }
val grantVoluntaryAck :: grantReadShared :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadExclusiveAck :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: Nil = Enum(9){ UFix() }
2013-01-22 02:17:26 +01:00
val probeInvalidate :: probeDowngrade :: probeCopy :: Nil = Enum(3){ UFix() }
val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(7){ UFix() }
val uncachedAcquireTypeList = List(acquireReadUncached, acquireWriteUncached, acquireReadWordUncached, acquireWriteWordUncached, acquireAtomicUncached)
val hasDataAcquireTypeList = List(acquireWriteUncached, acquireWriteWordUncached, acquireAtomicUncached)
val hasDataReleaseTypeList = List(releaseVoluntaryInvalidateData, releaseInvalidateData, releaseDowngradeData, releaseCopyData)
val hasDataGrantTypeList = List(grantReadShared, grantReadExclusive, grantReadUncached, grantReadWordUncached, grantAtomicUncached)
def isHit (cmd: Bits, state: UFix): Bool = {
Mux(isWriteIntent(cmd), (state === tileExclusiveDirty),
(state === tileShared || state === tileExclusiveDirty))
}
def isValid (state: UFix): Bool = {
state != tileInvalid
}
2013-01-22 02:17:26 +01:00
def needsTransactionOnSecondaryMiss(cmd: Bits, outstanding: Acquire): Bool = {
(isRead(cmd) && messageIsUncached(outstanding)) ||
(isWriteIntent(cmd) && (outstanding.a_type != acquireReadExclusive))
}
def needsTransactionOnCacheControl(cmd: Bits, state: UFix): Bool = {
MuxLookup(cmd, (state === tileExclusiveDirty), Array(
M_INV -> (state === tileExclusiveDirty),
M_CLN -> (state === tileExclusiveDirty)
))
}
def needsWriteback (state: UFix): Bool = {
needsTransactionOnCacheControl(M_INV, state)
}
def newStateOnHit(cmd: Bits, state: UFix): UFix = {
Mux(isWrite(cmd), tileExclusiveDirty, state)
}
def newStateOnCacheControl(cmd: Bits) = {
MuxLookup(cmd, tileInvalid, Array(
M_INV -> tileInvalid,
M_CLN -> tileShared
))
}
def newStateOnWriteback() = newStateOnCacheControl(M_INV)
def newStateOnFlush() = newStateOnCacheControl(M_INV)
2013-01-22 02:17:26 +01:00
def newStateOnGrant(incoming: Grant, outstanding: Acquire): UFix = {
MuxLookup(incoming.g_type, tileInvalid, Array(
grantReadShared -> tileShared,
grantReadExclusive -> tileExclusiveDirty,
grantReadExclusiveAck -> tileExclusiveDirty,
grantReadUncached -> tileInvalid,
grantWriteUncached -> tileInvalid,
grantReadWordUncached -> tileInvalid,
grantWriteWordUncached -> tileInvalid,
grantAtomicUncached -> tileInvalid
))
}
2013-01-22 02:17:26 +01:00
def newStateOnProbe(incoming: Probe, state: UFix): Bits = {
MuxLookup(incoming.p_type, state, Array(
2013-01-22 02:17:26 +01:00
probeInvalidate -> tileInvalid,
probeDowngrade -> tileShared,
probeCopy -> state
))
}
2013-01-22 02:17:26 +01:00
def getUncachedReadAcquire(addr: UFix, id: UFix) = Acquire(acquireReadUncached, addr, id)
def getUncachedWriteAcquire(addr: UFix, id: UFix) = Acquire(acquireWriteUncached, addr, id)
def getUncachedReadWordAcquire(addr: UFix, id: UFix) = Acquire(acquireReadWordUncached, addr, id)
def getUncachedWriteWordAcquire(addr: UFix, id: UFix, write_mask: Bits) = Acquire(acquireWriteWordUncached, addr, id, write_mask)
def getUncachedAtomicAcquire(addr: UFix, id: UFix, subword_addr: UFix, atomic_op: UFix) = Acquire(acquireAtomicUncached, addr, id, subword_addr, atomic_op)
def getVoluntaryWriteback(addr: UFix, client_id: UFix, master_id: UFix) = Release(releaseVoluntaryInvalidateData, addr, client_id, master_id)
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-01-22 02:17:26 +01:00
def getAcquireTypeOnPrimaryMiss(cmd: Bits, state: UFix): UFix = {
2013-04-04 07:13:51 +02:00
Mux(isWriteIntent(cmd), acquireReadExclusive, acquireReadShared)
}
2013-01-22 02:17:26 +01:00
def getAcquireTypeOnSecondaryMiss(cmd: Bits, state: UFix, outstanding: Acquire): UFix = {
Mux(isWriteIntent(cmd), acquireReadExclusive, outstanding.a_type)
}
def getReleaseTypeOnCacheControl(cmd: Bits): Bits = releaseVoluntaryInvalidateData // TODO
def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV)
def newRelease (incoming: Probe, state: UFix, id: UFix): Release = {
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
))
Release( Mux(needsWriteback(state), with_data, without_data), incoming.addr, id, incoming.master_xact_id)
}
def messageHasData(msg: SourcedMessage) = msg match {
case acq: Acquire => uFixListContains(hasDataAcquireTypeList, acq.a_type)
case grant: Grant => uFixListContains(hasDataGrantTypeList, grant.g_type)
case rel: Release => uFixListContains(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)
}
def messageIsUncached(acq: Acquire): Bool = uFixListContains(uncachedAcquireTypeList, acq.a_type)
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2)
2013-01-22 02:17:26 +01:00
def getGrantType(a_type: UFix, count: UFix): Bits = {
MuxLookup(a_type, grantReadUncached, Array(
acquireReadShared -> Mux(count > UFix(0), grantReadShared, grantReadExclusive),
acquireReadExclusive -> grantReadExclusive,
acquireReadUncached -> grantReadUncached,
acquireWriteUncached -> grantWriteUncached,
acquireReadWordUncached -> grantReadWordUncached,
acquireWriteWordUncached -> grantWriteWordUncached,
acquireAtomicUncached -> grantAtomicUncached
))
}
def getGrantType(rel: Release, count: UFix): Bits = {
MuxLookup(rel.r_type, grantReadUncached, Array(
releaseVoluntaryInvalidateData -> grantVoluntaryAck
))
}
2013-01-22 02:17:26 +01:00
def getProbeType(a_type: UFix, global_state: UFix): UFix = {
MuxLookup(a_type, probeCopy, Array(
acquireReadShared -> probeDowngrade,
acquireReadExclusive -> probeInvalidate,
acquireReadUncached -> probeCopy,
acquireWriteUncached -> probeInvalidate
))
}
def needsOuterRead(a_type: UFix, global_state: UFix): Bool = {
2013-01-22 02:17:26 +01:00
(a_type != acquireWriteUncached)
}
def needsOuterWrite(a_type: UFix, global_state: UFix): Bool = {
2013-01-22 02:17:26 +01:00
(a_type === acquireWriteUncached)
}
2013-01-22 02:17:26 +01:00
def needsAckReply(a_type: UFix, global_state: UFix): Bool = {
(a_type === acquireWriteUncached)
}
def requiresAck(grant: Grant) = grant.g_type != grantVoluntaryAck
def requiresAck(release: Release) = Bool(false)
def needsSelfProbe(acq: Acquire) = Bool(false)
def pendingVoluntaryReleaseIsSufficient(r_type: UFix, p_type: UFix): Bool = (r_type === releaseVoluntaryInvalidateData)
}
class MESICoherence extends CoherencePolicyWithUncached {
val tileInvalid :: tileShared :: tileExclusiveClean :: tileExclusiveDirty :: Nil = Enum(4){ UFix() }
val globalInvalid :: globalShared :: globalExclusiveClean :: Nil = Enum(3){ UFix() }
2013-01-22 02:17:26 +01:00
val acquireReadShared :: acquireReadExclusive :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: Nil = Enum(7){ UFix() }
val grantVoluntaryAck :: grantReadShared :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadExclusiveAck :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: Nil = Enum(9){ UFix() }
2013-01-22 02:17:26 +01:00
val probeInvalidate :: probeDowngrade :: probeCopy :: Nil = Enum(3){ UFix() }
val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(7){ UFix() }
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)
2012-04-04 03:06:02 +02:00
def isHit (cmd: Bits, state: UFix): 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
}
def isValid (state: UFix): Bool = {
state != tileInvalid
}
2013-01-22 02:17:26 +01:00
def needsTransactionOnSecondaryMiss(cmd: Bits, outstanding: Acquire): Bool = {
(isRead(cmd) && messageIsUncached(outstanding)) ||
(isWriteIntent(cmd) && (outstanding.a_type != acquireReadExclusive))
}
def needsTransactionOnCacheControl(cmd: Bits, state: UFix): Bool = {
MuxLookup(cmd, (state === tileExclusiveDirty), Array(
M_INV -> (state === tileExclusiveDirty),
M_CLN -> (state === tileExclusiveDirty)
))
}
def needsWriteback (state: UFix): Bool = {
needsTransactionOnCacheControl(M_INV, state)
}
def newStateOnHit(cmd: Bits, state: UFix): UFix = {
Mux(isWrite(cmd), tileExclusiveDirty, state)
}
def newStateOnCacheControl(cmd: Bits) = {
MuxLookup(cmd, tileInvalid, Array(
M_INV -> tileInvalid,
M_CLN -> tileShared
))
}
def newStateOnWriteback() = newStateOnCacheControl(M_INV)
def newStateOnFlush() = newStateOnCacheControl(M_INV)
2013-01-22 02:17:26 +01:00
def newStateOnGrant(incoming: Grant, outstanding: Acquire): UFix = {
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-01-22 02:17:26 +01:00
def newStateOnProbe(incoming: Probe, state: UFix): Bits = {
MuxLookup(incoming.p_type, state, Array(
2013-01-22 02:17:26 +01:00
probeInvalidate -> tileInvalid,
probeDowngrade -> tileShared,
probeCopy -> state
))
}
2013-01-22 02:17:26 +01:00
def getUncachedReadAcquire(addr: UFix, id: UFix) = Acquire(acquireReadUncached, addr, id)
def getUncachedWriteAcquire(addr: UFix, id: UFix) = Acquire(acquireWriteUncached, addr, id)
def getUncachedReadWordAcquire(addr: UFix, id: UFix) = Acquire(acquireReadWordUncached, addr, id)
def getUncachedWriteWordAcquire(addr: UFix, id: UFix, write_mask: Bits) = Acquire(acquireWriteWordUncached, addr, id, write_mask)
def getUncachedAtomicAcquire(addr: UFix, id: UFix, subword_addr: UFix, atomic_op: UFix) = Acquire(acquireAtomicUncached, addr, id, subword_addr, atomic_op)
def getVoluntaryWriteback(addr: UFix, client_id: UFix, master_id: UFix) = Release(releaseVoluntaryInvalidateData, addr, client_id, master_id)
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-01-22 02:17:26 +01:00
def getAcquireTypeOnPrimaryMiss(cmd: Bits, state: UFix): UFix = {
2013-04-04 07:13:51 +02:00
Mux(isWriteIntent(cmd), acquireReadExclusive, acquireReadShared)
}
2013-01-22 02:17:26 +01:00
def getAcquireTypeOnSecondaryMiss(cmd: Bits, state: UFix, outstanding: Acquire): UFix = {
Mux(isWriteIntent(cmd), acquireReadExclusive, outstanding.a_type)
}
def getReleaseTypeOnCacheControl(cmd: Bits): Bits = releaseVoluntaryInvalidateData // TODO
def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV)
def newRelease (incoming: Probe, state: UFix, id: UFix): Release = {
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
))
Release( Mux(needsWriteback(state), with_data, without_data), incoming.addr, id, incoming.master_xact_id)
2012-03-14 00:43:35 +01:00
}
def messageHasData(msg: SourcedMessage) = msg match {
case acq: Acquire => uFixListContains(hasDataAcquireTypeList, acq.a_type)
case grant: Grant => uFixListContains(hasDataGrantTypeList, grant.g_type)
case rel: Release => uFixListContains(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)
}
def messageIsUncached(acq: Acquire): Bool = uFixListContains(uncachedAcquireTypeList, acq.a_type)
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2)
2013-01-22 02:17:26 +01:00
def getGrantType(a_type: UFix, count: UFix): Bits = {
MuxLookup(a_type, grantReadUncached, Array(
acquireReadShared -> Mux(count > UFix(0), grantReadShared, grantReadExclusive),
acquireReadExclusive -> grantReadExclusive,
acquireReadUncached -> grantReadUncached,
acquireWriteUncached -> grantWriteUncached,
acquireReadWordUncached -> grantReadWordUncached,
acquireWriteWordUncached -> grantWriteWordUncached,
acquireAtomicUncached -> grantAtomicUncached
))
}
def getGrantType(rel: Release, count: UFix): Bits = {
MuxLookup(rel.r_type, grantReadUncached, Array(
releaseVoluntaryInvalidateData -> grantVoluntaryAck
))
}
2012-02-22 21:14:57 +01:00
2013-01-22 02:17:26 +01:00
def getProbeType(a_type: UFix, global_state: UFix): UFix = {
MuxLookup(a_type, probeCopy, Array(
acquireReadShared -> probeDowngrade,
acquireReadExclusive -> probeInvalidate,
acquireReadUncached -> probeCopy,
acquireWriteUncached -> probeInvalidate,
acquireReadWordUncached -> probeCopy,
acquireWriteWordUncached -> probeInvalidate,
acquireAtomicUncached -> probeInvalidate
))
}
def needsOuterRead(a_type: UFix, global_state: UFix): Bool = {
2013-01-22 02:17:26 +01:00
(a_type != acquireWriteUncached)
}
def needsOuterWrite(a_type: UFix, global_state: UFix): Bool = {
2013-01-22 02:17:26 +01:00
(a_type === acquireWriteUncached)
}
2013-01-22 02:17:26 +01:00
def needsAckReply(a_type: UFix, global_state: UFix): Bool = {
(a_type === acquireWriteUncached)
}
def requiresAck(grant: Grant) = grant.g_type != grantVoluntaryAck
def requiresAck(release: Release) = Bool(false)
def needsSelfProbe(acq: Acquire) = Bool(false)
def pendingVoluntaryReleaseIsSufficient(r_type: UFix, p_type: UFix): Bool = (r_type === releaseVoluntaryInvalidateData)
}
2012-10-24 03:01:53 +02:00
class MigratoryCoherence extends CoherencePolicyWithUncached {
val tileInvalid :: tileShared :: tileExclusiveClean :: tileExclusiveDirty :: tileSharedByTwo :: tileMigratoryClean :: tileMigratoryDirty :: Nil = Enum(7){ UFix() }
2013-01-22 02:17:26 +01:00
val acquireReadShared :: acquireReadExclusive :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: acquireInvalidateOthers :: Nil = Enum(8){ UFix() }
val grantVoluntaryAck :: grantReadShared :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadExclusiveAck :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: grantReadMigratory :: Nil = Enum(10){ UFix() }
2013-01-22 02:17:26 +01:00
val probeInvalidate :: probeDowngrade :: probeCopy :: probeInvalidateOthers :: Nil = Enum(4){ UFix() }
val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: releaseDowngradeDataMigratory :: releaseDowngradeAckHasCopy :: releaseInvalidateDataMigratory :: releaseInvalidateAckMigratory :: Nil = Enum(11){ UFix() }
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
def isHit (cmd: Bits, state: UFix): Bool = {
Mux(isWriteIntent(cmd), uFixListContains(List(tileExclusiveClean, tileExclusiveDirty, tileMigratoryClean, tileMigratoryDirty), state), (state != tileInvalid))
2012-10-24 03:01:53 +02:00
}
def isValid (state: UFix): Bool = {
state != tileInvalid
}
2013-01-22 02:17:26 +01:00
def needsTransactionOnSecondaryMiss(cmd: Bits, 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
}
def needsTransactionOnCacheControl(cmd: Bits, state: UFix): Bool = {
MuxLookup(cmd, (state === tileExclusiveDirty), Array(
M_INV -> uFixListContains(List(tileExclusiveDirty,tileMigratoryDirty),state),
M_CLN -> uFixListContains(List(tileExclusiveDirty,tileMigratoryDirty),state)
))
}
def needsWriteback (state: UFix): Bool = {
needsTransactionOnCacheControl(M_INV, state)
}
def newStateOnHit(cmd: Bits, state: UFix): UFix = {
Mux(isWrite(cmd), MuxLookup(state, tileExclusiveDirty, Array(
2012-10-24 03:01:53 +02:00
tileExclusiveClean -> tileExclusiveDirty,
tileMigratoryClean -> tileMigratoryDirty)), state)
}
def newStateOnCacheControl(cmd: Bits) = {
MuxLookup(cmd, tileInvalid, Array(
M_INV -> tileInvalid,
M_CLN -> tileShared
))
}
def newStateOnWriteback() = newStateOnCacheControl(M_INV)
def newStateOnFlush() = newStateOnCacheControl(M_INV)
2013-01-22 02:17:26 +01:00
def newStateOnGrant(incoming: Grant, outstanding: Acquire): UFix = {
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-01-22 02:17:26 +01:00
def newStateOnProbe(incoming: Probe, state: UFix): 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))
))
}
2013-01-22 02:17:26 +01:00
def getUncachedReadAcquire(addr: UFix, id: UFix) = Acquire(acquireReadUncached, addr, id)
def getUncachedWriteAcquire(addr: UFix, id: UFix) = Acquire(acquireWriteUncached, addr, id)
def getUncachedReadWordAcquire(addr: UFix, id: UFix) = Acquire(acquireReadWordUncached, addr, id)
def getUncachedWriteWordAcquire(addr: UFix, id: UFix, write_mask: Bits) = Acquire(acquireWriteWordUncached, addr, id, write_mask)
def getUncachedAtomicAcquire(addr: UFix, id: UFix, subword_addr: UFix, atomic_op: UFix) = Acquire(acquireAtomicUncached, addr, id, subword_addr, atomic_op)
def getVoluntaryWriteback(addr: UFix, client_id: UFix, master_id: UFix) = Release(releaseVoluntaryInvalidateData, addr, client_id, master_id)
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-01-22 02:17:26 +01:00
def getAcquireTypeOnPrimaryMiss(cmd: Bits, state: UFix): UFix = {
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-01-22 02:17:26 +01:00
def getAcquireTypeOnSecondaryMiss(cmd: Bits, state: UFix, outstanding: Acquire): UFix = {
Mux(isWriteIntent(cmd), Mux(state === tileInvalid, acquireReadExclusive, acquireInvalidateOthers), outstanding.a_type)
2013-01-22 02:17:26 +01:00
}
def getReleaseTypeOnCacheControl(cmd: Bits): Bits = releaseVoluntaryInvalidateData // TODO
def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV)
2013-01-22 02:17:26 +01:00
def newRelease (incoming: Probe, state: UFix, id: UFix): Release = {
//Assert( incoming.p_type === probeInvalidateOthers && needsWriteback(state), "Bad probe request type, should be impossible.")
2013-01-22 02:17:26 +01:00
val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array(
probeInvalidate -> Mux(uFixListContains(List(tileExclusiveDirty, tileMigratoryDirty), state),
releaseInvalidateDataMigratory, releaseInvalidateData),
probeDowngrade -> Mux(state === tileMigratoryDirty, releaseDowngradeDataMigratory, releaseDowngradeData),
probeCopy -> releaseCopyData
))
val without_data = MuxLookup(incoming.p_type, releaseInvalidateAck, Array(
probeInvalidate -> Mux(tileExclusiveClean === state, releaseInvalidateAckMigratory, releaseInvalidateAck),
probeInvalidateOthers -> Mux(state === tileSharedByTwo, releaseInvalidateAckMigratory, releaseInvalidateAck),
probeDowngrade -> Mux(state != tileInvalid, releaseDowngradeAckHasCopy, releaseDowngradeAck),
probeCopy -> releaseCopyAck
))
Release( Mux(needsWriteback(state), with_data, without_data), incoming.addr, id, incoming.master_xact_id)
2012-10-24 03:01:53 +02:00
}
def messageHasData(msg: SourcedMessage) = msg match {
case acq: Acquire => uFixListContains(hasDataAcquireTypeList, acq.a_type)
case grant: Grant => uFixListContains(hasDataGrantTypeList, grant.g_type)
case rel: Release => uFixListContains(hasDataReleaseTypeList, rel.r_type)
case _ => Bool(false)
}
2013-01-22 02:17:26 +01:00
def messageUpdatesDataArray (reply: Grant): Bool = {
uFixListContains(List(grantReadShared, grantReadExclusive, grantReadMigratory), reply.g_type)
2012-10-24 03:01:53 +02:00
}
def messageIsUncached(acq: Acquire): Bool = uFixListContains(uncachedAcquireTypeList, acq.a_type)
2012-10-24 03:01:53 +02:00
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2)
2013-01-22 02:17:26 +01:00
def getGrantType(a_type: UFix, count: UFix): Bits = {
MuxLookup(a_type, grantReadUncached, Array(
acquireReadShared -> Mux(count > UFix(0), grantReadShared, grantReadExclusive), //TODO: what is count? Depend on release.p_type???
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
))
}
def getGrantType(rel: Release, count: UFix): Bits = {
MuxLookup(rel.r_type, grantReadUncached, Array(
releaseVoluntaryInvalidateData -> grantVoluntaryAck
))
}
2012-10-24 03:01:53 +02:00
2013-01-22 02:17:26 +01:00
def getProbeType(a_type: UFix, global_state: UFix): UFix = {
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
))
}
def needsOuterRead(a_type: UFix, global_state: UFix): Bool = {
2013-01-22 02:17:26 +01:00
(a_type != acquireWriteUncached && a_type != acquireInvalidateOthers)
2012-10-24 03:01:53 +02:00
}
def needsOuterWrite(a_type: UFix, global_state: UFix): 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-01-22 02:17:26 +01:00
def needsAckReply(a_type: UFix, global_state: UFix): Bool = {
(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)
def pendingVoluntaryReleaseIsSufficient(r_type: UFix, p_type: UFix): Bool = (r_type === releaseVoluntaryInvalidateData)
2012-10-24 03:01:53 +02:00
}