2014-09-13 00:31:38 +02:00
|
|
|
// See LICENSE for license details.
|
|
|
|
|
2012-09-27 21:59:45 +02:00
|
|
|
package uncore
|
2012-02-15 00:51:32 +01:00
|
|
|
import Chisel._
|
|
|
|
|
2014-12-30 07:55:58 +01:00
|
|
|
// Classes to represent coherence information in clients and managers
|
2014-12-16 04:23:13 +01:00
|
|
|
abstract class CoherenceMetadata extends Bundle with CoherenceAgentParameters
|
2014-05-28 22:35:08 +02:00
|
|
|
|
2014-12-16 04:23:13 +01:00
|
|
|
class ClientMetadata extends CoherenceMetadata {
|
|
|
|
val state = UInt(width = co.clientStateWidth)
|
|
|
|
def ===(right: ClientMetadata): Bool = this.state === right.state
|
|
|
|
override def clone = new ClientMetadata().asInstanceOf[this.type]
|
|
|
|
}
|
2014-05-28 22:35:08 +02:00
|
|
|
object ClientMetadata {
|
2014-12-16 04:23:13 +01:00
|
|
|
def apply(state: UInt) = {
|
2015-02-02 04:57:53 +01:00
|
|
|
val meta = new ClientMetadata
|
|
|
|
meta.state := state
|
|
|
|
meta
|
2014-05-28 22:35:08 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-30 07:55:58 +01:00
|
|
|
class ManagerMetadata extends CoherenceMetadata {
|
2014-12-16 04:23:13 +01:00
|
|
|
val state = UInt(width = co.masterStateWidth)
|
|
|
|
val sharers = UInt(width = co.dir.width)
|
2014-12-30 07:55:58 +01:00
|
|
|
override def clone = new ManagerMetadata().asInstanceOf[this.type]
|
2014-12-16 04:23:13 +01:00
|
|
|
}
|
2014-12-30 07:55:58 +01:00
|
|
|
object ManagerMetadata {
|
2014-12-16 04:23:13 +01:00
|
|
|
def apply(state: UInt, sharers: UInt) = {
|
2015-02-02 04:57:53 +01:00
|
|
|
val meta = new ManagerMetadata
|
|
|
|
meta.state := state
|
|
|
|
meta.sharers := sharers
|
|
|
|
meta
|
2014-05-28 22:35:08 +02:00
|
|
|
}
|
2014-12-30 07:55:58 +01:00
|
|
|
def apply(state: UInt): ManagerMetadata = apply(state, new ManagerMetadata().co.dir.flush)
|
2014-05-28 22:35:08 +02:00
|
|
|
}
|
|
|
|
|
2014-12-30 07:55:58 +01:00
|
|
|
// This class encapsulates transformations on different directory information
|
|
|
|
// storage formats
|
2014-10-15 20:46:35 +02:00
|
|
|
abstract class DirectoryRepresentation(val width: Int) {
|
|
|
|
def pop(prev: UInt, id: UInt): UInt
|
|
|
|
def push(prev: UInt, id: UInt): UInt
|
|
|
|
def flush: UInt
|
|
|
|
def none(s: UInt): Bool
|
|
|
|
def one(s: UInt): Bool
|
|
|
|
def count(s: UInt): UInt
|
|
|
|
def next(s: UInt): UInt
|
2014-10-24 06:50:03 +02:00
|
|
|
def full(s: UInt): UInt
|
2014-05-28 22:35:08 +02:00
|
|
|
}
|
|
|
|
|
2014-11-13 01:25:25 +01:00
|
|
|
class NullRepresentation(nClients: Int) extends DirectoryRepresentation(1) {
|
2014-10-15 20:46:35 +02:00
|
|
|
def pop(prev: UInt, id: UInt) = UInt(0)
|
|
|
|
def push(prev: UInt, id: UInt) = UInt(0)
|
|
|
|
def flush = UInt(0)
|
|
|
|
def none(s: UInt) = Bool(false)
|
|
|
|
def one(s: UInt) = Bool(false)
|
2014-11-13 01:25:25 +01:00
|
|
|
def count(s: UInt) = UInt(nClients)
|
2014-10-15 20:46:35 +02:00
|
|
|
def next(s: UInt) = UInt(0)
|
2014-11-13 01:25:25 +01:00
|
|
|
def full(s: UInt) = SInt(-1, width = nClients).toUInt
|
2014-05-28 22:35:08 +02:00
|
|
|
}
|
|
|
|
|
2014-10-15 20:46:35 +02:00
|
|
|
class FullRepresentation(nClients: Int) extends DirectoryRepresentation(nClients) {
|
|
|
|
def pop(prev: UInt, id: UInt) = prev & ~UIntToOH(id)
|
|
|
|
def push(prev: UInt, id: UInt) = prev | UIntToOH(id)
|
|
|
|
def flush = UInt(0, width = width)
|
|
|
|
def none(s: UInt) = s === UInt(0)
|
|
|
|
def one(s: UInt) = PopCount(s) === UInt(1)
|
|
|
|
def count(s: UInt) = PopCount(s)
|
|
|
|
def next(s: UInt) = PriorityEncoder(s)
|
2014-10-24 06:50:03 +02:00
|
|
|
def full(s: UInt) = s
|
2014-05-28 22:35:08 +02:00
|
|
|
}
|
|
|
|
|
2014-12-30 07:55:58 +01:00
|
|
|
// Coherence policy inferface for clients and managers
|
2014-12-16 04:23:13 +01:00
|
|
|
abstract class CoherencePolicy(val dir: DirectoryRepresentation) {
|
2013-08-02 23:55:06 +02:00
|
|
|
def nClientStates: Int
|
2014-12-30 07:55:58 +01:00
|
|
|
def nManagerStates: Int
|
2013-08-02 23:55:06 +02:00
|
|
|
def nAcquireTypes: Int
|
|
|
|
def nProbeTypes: Int
|
|
|
|
def nReleaseTypes: Int
|
|
|
|
def nGrantTypes: Int
|
2013-08-12 19:36:44 +02:00
|
|
|
def clientStateWidth = log2Up(nClientStates)
|
2014-12-30 07:55:58 +01:00
|
|
|
def masterStateWidth = log2Up(nManagerStates)
|
2013-08-12 19:36:44 +02:00
|
|
|
def acquireTypeWidth = log2Up(nAcquireTypes)
|
|
|
|
def probeTypeWidth = log2Up(nProbeTypes)
|
|
|
|
def releaseTypeWidth = log2Up(nReleaseTypes)
|
|
|
|
def grantTypeWidth = log2Up(nGrantTypes)
|
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
val clientStatesWithReadPermission: Vec[UInt]
|
|
|
|
val clientStatesWithWritePermission: Vec[UInt]
|
|
|
|
val clientStatesWithDirtyData: Vec[UInt]
|
|
|
|
val acquireTypesWithData = Nil // Only built-in Acquire types have data for now
|
|
|
|
val releaseTypesWithData: Vec[UInt]
|
|
|
|
val grantTypesWithData: Vec[UInt]
|
|
|
|
|
|
|
|
def isValid(meta: ClientMetadata): Bool
|
|
|
|
def isValid(meta: ManagerMetadata): Bool
|
|
|
|
|
|
|
|
def isHit(cmd: UInt, meta: ClientMetadata): Bool = {
|
|
|
|
Mux(isWriteIntent(cmd),
|
|
|
|
clientStatesWithWritePermission.contains(meta.state),
|
|
|
|
clientStatesWithReadPermission.contains(meta.state))
|
|
|
|
}
|
|
|
|
//TODO: Use outer protocol's clientState instead, remove this function:
|
|
|
|
def isHit(incoming: Acquire, meta: ManagerMetadata) = isValid(meta)
|
2013-08-12 19:36:44 +02:00
|
|
|
|
|
|
|
def needsTransactionOnSecondaryMiss(cmd: UInt, outstanding: Acquire): Bool
|
2015-02-02 04:57:53 +01:00
|
|
|
//TODO: Assumes all cache ctrl ops writeback dirty data, and
|
|
|
|
// doesn't issue transaction when e.g. downgrading Exclusive to Shared:
|
|
|
|
def needsTransactionOnCacheControl(cmd: UInt, meta: ClientMetadata): Bool =
|
|
|
|
clientStatesWithDirtyData.contains(meta.state)
|
|
|
|
def needsWriteback(meta: ClientMetadata): Bool =
|
|
|
|
needsTransactionOnCacheControl(M_FLUSH, meta)
|
2014-05-28 22:35:08 +02:00
|
|
|
|
|
|
|
def clientMetadataOnGrant(incoming: Grant, outstanding: Acquire): ClientMetadata
|
2015-02-02 04:57:53 +01:00
|
|
|
def clientMetadataOnProbe(incoming: Probe, meta: ClientMetadata): ClientMetadata
|
|
|
|
def clientMetadataOnHit(cmd: UInt, meta: ClientMetadata): ClientMetadata
|
|
|
|
def clientMetadataOnCacheControl(cmd: UInt, meta: ClientMetadata): ClientMetadata
|
|
|
|
def clientMetadataOnFlush: ClientMetadata
|
|
|
|
|
|
|
|
def managerMetadataOnRelease(incoming: Release, meta: ManagerMetadata, src: UInt): ManagerMetadata
|
|
|
|
def managerMetadataOnGrant(outgoing: Grant, meta: ManagerMetadata, dst: UInt): ManagerMetadata
|
|
|
|
def managerMetadataOnCacheControl(cmd: UInt, meta: ManagerMetadata): ManagerMetadata
|
|
|
|
def managerMetadataOnFlush: ManagerMetadata
|
|
|
|
|
|
|
|
def getAcquireTypeOnPrimaryMiss(cmd: UInt, meta: ClientMetadata): UInt
|
|
|
|
def getAcquireTypeOnSecondaryMiss(cmd: UInt, meta: ClientMetadata, outstanding: Acquire): UInt
|
|
|
|
def getReleaseType(p: Probe, meta: ClientMetadata): UInt
|
|
|
|
def getReleaseType(cmd: UInt, meta: ClientMetadata): UInt
|
|
|
|
|
|
|
|
def getGrantType(acq: Acquire, meta: ManagerMetadata): UInt
|
|
|
|
def getProbeType(acq: Acquire, meta: ManagerMetadata): UInt
|
|
|
|
def getProbeType(cmd: UInt, meta: ManagerMetadata): UInt
|
|
|
|
|
|
|
|
def requiresOuterRead(acq: Acquire, meta: ManagerMetadata): Bool
|
|
|
|
def requiresOuterWrite(acq: Acquire, meta: ManagerMetadata): Bool
|
|
|
|
def requiresProbes(acq: Acquire, meta: ManagerMetadata): Bool
|
|
|
|
def requiresProbes(cmd: UInt, meta: ManagerMetadata): Bool
|
|
|
|
def requiresProbesOnVoluntaryWriteback(meta: ManagerMetadata): Bool = requiresProbes(M_FLUSH, meta)
|
2012-04-10 09:09:58 +02:00
|
|
|
}
|
|
|
|
|
2014-12-16 04:23:13 +01:00
|
|
|
class MICoherence(dir: DirectoryRepresentation) extends CoherencePolicy(dir) {
|
2013-08-02 23:55:06 +02:00
|
|
|
def nClientStates = 2
|
2014-12-30 07:55:58 +01:00
|
|
|
def nManagerStates = 2
|
2014-11-12 02:36:55 +01:00
|
|
|
def nAcquireTypes = 1
|
2013-08-02 23:55:06 +02:00
|
|
|
def nProbeTypes = 2
|
2015-02-02 04:57:53 +01:00
|
|
|
def nReleaseTypes = 4
|
|
|
|
def nGrantTypes = 1
|
2012-04-10 09:09:58 +02:00
|
|
|
|
2014-05-28 22:35:08 +02:00
|
|
|
val clientInvalid :: clientValid :: Nil = Enum(UInt(), nClientStates)
|
2015-02-02 04:57:53 +01:00
|
|
|
val managerInvalid :: managerValid :: Nil = Enum(UInt(), nManagerStates)
|
2013-08-02 23:55:06 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
val acquireExclusive :: Nil = Enum(UInt(), nAcquireTypes)
|
2013-09-10 19:54:51 +02:00
|
|
|
val probeInvalidate :: probeCopy :: Nil = Enum(UInt(), nProbeTypes)
|
2015-02-02 04:57:53 +01:00
|
|
|
val releaseInvalidateData :: releaseCopyData :: releaseInvalidateAck :: releaseCopyAck :: Nil = Enum(UInt(), nReleaseTypes)
|
|
|
|
val grantExclusive :: Nil = Enum(UInt(), nGrantTypes)
|
|
|
|
|
|
|
|
val clientStatesWithReadPermission = Vec(clientValid)
|
|
|
|
val clientStatesWithWritePermission = Vec(clientValid)
|
|
|
|
val clientStatesWithDirtyData = Vec(clientValid)
|
|
|
|
val releaseTypesWithData = Vec(releaseInvalidateData, releaseCopyData)
|
|
|
|
val grantTypesWithData = Vec(grantExclusive)
|
|
|
|
|
|
|
|
def isValid (meta: ClientMetadata): Bool = meta.state != clientInvalid
|
|
|
|
def isValid (meta: ManagerMetadata): Bool = meta.state != managerInvalid
|
|
|
|
|
|
|
|
def needsTransactionOnSecondaryMiss(cmd: UInt, outstanding: Acquire): Bool =
|
|
|
|
(outstanding.a_type != acquireExclusive)
|
|
|
|
|
|
|
|
def clientMetadataOnHit(cmd: UInt, meta: ClientMetadata) = meta
|
|
|
|
|
|
|
|
def clientMetadataOnFlush = ClientMetadata(clientInvalid)
|
|
|
|
def clientMetadataOnCacheControl(cmd: UInt, meta: ClientMetadata) =
|
|
|
|
ClientMetadata(Mux(cmd === M_FLUSH, clientInvalid, meta.state))
|
|
|
|
|
|
|
|
def clientMetadataOnGrant(incoming: Grant, outstanding: Acquire) =
|
2015-02-02 10:02:06 +01:00
|
|
|
ClientMetadata(Mux(incoming.builtin_type, clientInvalid, clientValid))
|
2015-02-02 04:57:53 +01:00
|
|
|
|
|
|
|
def clientMetadataOnProbe(incoming: Probe, meta: ClientMetadata) =
|
|
|
|
ClientMetadata(Mux(incoming.p_type === probeInvalidate,
|
|
|
|
clientInvalid, meta.state))
|
|
|
|
|
|
|
|
def managerMetadataOnRelease(r: Release, meta: ManagerMetadata, src: UInt) = {
|
|
|
|
val next = ManagerMetadata(managerValid, dir.pop(meta.sharers, src))
|
|
|
|
MuxBundle(meta, Array(
|
2014-10-08 07:33:10 +02:00
|
|
|
r.is(releaseInvalidateData) -> next,
|
|
|
|
r.is(releaseInvalidateAck) -> next
|
|
|
|
))
|
|
|
|
}
|
2012-04-10 09:09:58 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def managerMetadataOnGrant(g: Grant, meta: ManagerMetadata, dst: UInt) =
|
2015-02-02 10:02:06 +01:00
|
|
|
Mux(g.builtin_type,
|
2015-02-02 04:57:53 +01:00
|
|
|
ManagerMetadata(managerValid, meta.sharers),
|
|
|
|
ManagerMetadata(managerValid, dir.push(meta.sharers, dst)))
|
2012-10-02 01:05:37 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def managerMetadataOnFlush = ManagerMetadata(managerInvalid)
|
2012-04-10 09:09:58 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def managerMetadataOnCacheControl(cmd: UInt, meta: ManagerMetadata) =
|
|
|
|
ManagerMetadata(Mux(cmd === M_FLUSH, managerInvalid, meta.state))
|
|
|
|
|
|
|
|
def getAcquireTypeOnPrimaryMiss(cmd: UInt, meta: ClientMetadata): UInt = acquireExclusive
|
|
|
|
|
|
|
|
def getAcquireTypeOnSecondaryMiss(cmd: UInt, meta: ClientMetadata, outstanding: Acquire): UInt = acquireExclusive
|
|
|
|
|
|
|
|
def getReleaseType(cmd: UInt, meta: ClientMetadata): UInt = {
|
|
|
|
val dirty = clientStatesWithDirtyData.contains(meta.state)
|
|
|
|
MuxLookup(cmd, releaseCopyAck, Array(
|
|
|
|
M_FLUSH -> Mux(dirty, releaseInvalidateData, releaseInvalidateAck),
|
|
|
|
M_PRODUCE -> Mux(dirty, releaseCopyData, releaseCopyAck),
|
|
|
|
M_CLEAN -> Mux(dirty, releaseCopyData, releaseCopyAck)))
|
2012-04-10 09:09:58 +02:00
|
|
|
}
|
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def getReleaseType(incoming: Probe, meta: ClientMetadata): UInt =
|
|
|
|
MuxLookup(incoming.p_type, releaseInvalidateAck, Array(
|
|
|
|
probeInvalidate -> getReleaseType(M_FLUSH, meta),
|
|
|
|
probeCopy -> getReleaseType(M_CLEAN, meta)))
|
2012-04-10 09:09:58 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def isCoherenceConflict(addr1: UInt, addr2: UInt): Bool = (addr1 === addr2)
|
2012-04-10 09:09:58 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def getGrantType(a: Acquire, meta: ManagerMetadata): UInt =
|
2015-02-02 10:02:06 +01:00
|
|
|
Mux(a.builtin_type, Grant.getGrantTypeForUncached(a), grantExclusive)
|
2013-01-29 01:39:45 +01:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def getProbeType(a: Acquire, meta: ManagerMetadata): UInt =
|
2015-02-02 10:02:06 +01:00
|
|
|
Mux(a.builtin_type,
|
2014-11-12 02:36:55 +01:00
|
|
|
MuxLookup(a.a_type, probeCopy, Array(
|
2015-02-02 04:57:53 +01:00
|
|
|
Acquire.uncachedReadBlock -> probeCopy,
|
|
|
|
Acquire.uncachedWriteBlock -> probeInvalidate,
|
2014-11-12 02:36:55 +01:00
|
|
|
Acquire.uncachedRead -> probeCopy,
|
|
|
|
Acquire.uncachedWrite -> probeInvalidate,
|
2015-02-02 10:02:06 +01:00
|
|
|
Acquire.uncachedAtomic -> probeInvalidate)),
|
|
|
|
probeInvalidate)
|
2012-04-10 09:09:58 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def getProbeType(cmd: UInt, meta: ManagerMetadata): UInt =
|
|
|
|
MuxLookup(cmd, probeCopy, Array(
|
|
|
|
M_FLUSH -> probeInvalidate))
|
|
|
|
|
|
|
|
def requiresOuterRead(acq: Acquire, meta: ManagerMetadata) =
|
2015-02-02 10:02:06 +01:00
|
|
|
Mux(acq.builtin_type, Acquire.requiresOuterRead(acq.a_type), Bool(true))
|
2015-02-02 04:57:53 +01:00
|
|
|
|
|
|
|
def requiresOuterWrite(acq: Acquire, meta: ManagerMetadata) =
|
2015-02-02 10:02:06 +01:00
|
|
|
Mux(acq.builtin_type, Acquire.requiresOuterWrite(acq.a_type), Bool(false))
|
2014-11-12 02:36:55 +01:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def requiresProbes(a: Acquire, meta: ManagerMetadata) = !dir.none(meta.sharers)
|
|
|
|
|
|
|
|
def requiresProbes(cmd: UInt, meta: ManagerMetadata) = !dir.none(meta.sharers)
|
2012-04-10 09:09:58 +02:00
|
|
|
}
|
|
|
|
|
2014-12-16 04:23:13 +01:00
|
|
|
class MEICoherence(dir: DirectoryRepresentation) extends CoherencePolicy(dir) {
|
2013-08-02 23:55:06 +02:00
|
|
|
def nClientStates = 3
|
2014-12-30 07:55:58 +01:00
|
|
|
def nManagerStates = 2
|
2014-11-12 02:36:55 +01:00
|
|
|
def nAcquireTypes = 2
|
2013-08-02 23:55:06 +02:00
|
|
|
def nProbeTypes = 3
|
2015-02-02 04:57:53 +01:00
|
|
|
def nReleaseTypes = 6
|
|
|
|
def nGrantTypes = 1
|
2012-04-10 09:09:58 +02:00
|
|
|
|
2014-05-28 22:35:08 +02:00
|
|
|
val clientInvalid :: clientExclusiveClean :: clientExclusiveDirty :: Nil = Enum(UInt(), nClientStates)
|
2015-02-02 04:57:53 +01:00
|
|
|
val managerInvalid :: managerValid :: Nil = Enum(UInt(), nManagerStates)
|
2012-04-10 09:09:58 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
val acquireExclusiveClean :: acquireExclusiveDirty :: Nil = Enum(UInt(), nAcquireTypes)
|
2013-09-10 19:54:51 +02:00
|
|
|
val probeInvalidate :: probeDowngrade :: probeCopy :: Nil = Enum(UInt(), nProbeTypes)
|
2015-02-02 04:57:53 +01:00
|
|
|
val releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(UInt(), nReleaseTypes)
|
|
|
|
val grantExclusive :: Nil = Enum(UInt(), nGrantTypes)
|
2013-03-01 03:13:41 +01:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
val clientStatesWithReadPermission = Vec(clientExclusiveClean, clientExclusiveDirty)
|
|
|
|
val clientStatesWithWritePermission = Vec(clientExclusiveClean, clientExclusiveDirty)
|
|
|
|
val clientStatesWithDirtyData = Vec(clientExclusiveDirty)
|
|
|
|
val releaseTypesWithData = Vec(releaseInvalidateData, releaseDowngradeData, releaseCopyData)
|
|
|
|
val grantTypesWithData = Vec(grantExclusive)
|
2012-04-10 09:09:58 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def isValid (meta: ClientMetadata) = meta.state != clientInvalid
|
|
|
|
def isValid (meta: ManagerMetadata) = meta.state != managerInvalid
|
2012-04-10 09:09:58 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def needsTransactionOnSecondaryMiss(cmd: UInt, outstanding: Acquire): Bool =
|
2015-02-02 10:02:06 +01:00
|
|
|
(isRead(cmd) && outstanding.builtin_type) ||
|
2015-02-02 04:57:53 +01:00
|
|
|
(isWriteIntent(cmd) && (outstanding.a_type != acquireExclusiveDirty))
|
|
|
|
|
|
|
|
def clientMetadataOnHit(cmd: UInt, meta: ClientMetadata) =
|
|
|
|
ClientMetadata(Mux(isWrite(cmd), clientExclusiveDirty, meta.state))
|
|
|
|
|
|
|
|
def clientMetadataOnFlush = ClientMetadata(clientInvalid)
|
|
|
|
def clientMetadataOnCacheControl(cmd: UInt, meta: ClientMetadata) =
|
|
|
|
ClientMetadata(
|
|
|
|
MuxLookup(cmd, meta.state, Array(
|
|
|
|
M_FLUSH -> clientInvalid,
|
|
|
|
M_CLEAN -> Mux(meta.state === clientExclusiveDirty, clientExclusiveClean, meta.state))))
|
|
|
|
|
|
|
|
def clientMetadataOnGrant(incoming: Grant, outstanding: Acquire) =
|
|
|
|
ClientMetadata(
|
2015-02-02 10:02:06 +01:00
|
|
|
Mux(incoming.builtin_type, clientInvalid,
|
2015-02-02 04:57:53 +01:00
|
|
|
Mux(outstanding.a_type === acquireExclusiveDirty, clientExclusiveDirty,
|
|
|
|
clientExclusiveClean)))
|
|
|
|
|
|
|
|
def clientMetadataOnProbe(incoming: Probe, meta: ClientMetadata) =
|
|
|
|
ClientMetadata(
|
|
|
|
MuxLookup(incoming.p_type, meta.state, Array(
|
|
|
|
probeInvalidate -> clientInvalid,
|
|
|
|
probeDowngrade -> clientExclusiveClean,
|
|
|
|
probeCopy -> meta.state)))
|
|
|
|
|
|
|
|
def managerMetadataOnRelease(r: Release, meta: ManagerMetadata, src: UInt) = {
|
|
|
|
val next = ManagerMetadata(managerValid, dir.pop(meta.sharers,src))
|
|
|
|
MuxBundle(meta, Array(
|
2014-10-08 07:33:10 +02:00
|
|
|
r.is(releaseInvalidateData) -> next,
|
|
|
|
r.is(releaseInvalidateAck) -> next
|
|
|
|
))
|
|
|
|
}
|
2012-04-10 09:09:58 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def managerMetadataOnGrant(g: Grant, meta: ManagerMetadata, dst: UInt) =
|
2015-02-02 10:02:06 +01:00
|
|
|
Mux(g.builtin_type,
|
2015-02-02 04:57:53 +01:00
|
|
|
ManagerMetadata(managerValid, meta.sharers),
|
|
|
|
ManagerMetadata(managerValid, dir.push(meta.sharers, dst)))
|
2012-10-02 01:05:37 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def managerMetadataOnFlush = ManagerMetadata(managerInvalid)
|
2012-04-10 09:09:58 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def managerMetadataOnCacheControl(cmd: UInt, meta: ManagerMetadata) =
|
|
|
|
ManagerMetadata(Mux(cmd === M_FLUSH, managerInvalid, meta.state))
|
|
|
|
|
|
|
|
def getAcquireTypeOnPrimaryMiss(cmd: UInt, meta: ClientMetadata): UInt =
|
|
|
|
Mux(isWriteIntent(cmd), acquireExclusiveDirty, acquireExclusiveClean)
|
|
|
|
|
|
|
|
def getAcquireTypeOnSecondaryMiss(cmd: UInt, meta: ClientMetadata, outstanding: Acquire): UInt =
|
|
|
|
Mux(isWriteIntent(cmd), acquireExclusiveDirty, outstanding.a_type)
|
|
|
|
|
|
|
|
def getReleaseType(cmd: UInt, meta: ClientMetadata): UInt = {
|
|
|
|
val dirty = clientStatesWithDirtyData.contains(meta.state)
|
|
|
|
MuxLookup(cmd, releaseCopyAck, Array(
|
|
|
|
M_FLUSH -> Mux(dirty, releaseInvalidateData, releaseInvalidateAck),
|
|
|
|
M_PRODUCE -> Mux(dirty, releaseDowngradeData, releaseDowngradeAck),
|
|
|
|
M_CLEAN -> Mux(dirty, releaseCopyData, releaseCopyAck)))
|
2012-04-10 09:09:58 +02:00
|
|
|
}
|
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def getReleaseType(incoming: Probe, meta: ClientMetadata): UInt =
|
|
|
|
MuxLookup(incoming.p_type, releaseInvalidateAck, Array(
|
|
|
|
probeInvalidate -> getReleaseType(M_FLUSH, meta),
|
|
|
|
probeDowngrade -> getReleaseType(M_PRODUCE, meta),
|
|
|
|
probeCopy -> getReleaseType(M_CLEAN, meta)))
|
|
|
|
|
2014-01-21 21:20:55 +01:00
|
|
|
def isCoherenceConflict(addr1: UInt, addr2: UInt): Bool = (addr1 === addr2)
|
2012-04-10 09:09:58 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def getGrantType(a: Acquire, meta: ManagerMetadata): UInt =
|
2015-02-02 10:02:06 +01:00
|
|
|
Mux(a.builtin_type, Grant.getGrantTypeForUncached(a), grantExclusive)
|
2012-04-10 09:09:58 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def getProbeType(a: Acquire, meta: ManagerMetadata): UInt =
|
2015-02-02 10:02:06 +01:00
|
|
|
Mux(a.builtin_type,
|
2014-11-12 02:36:55 +01:00
|
|
|
MuxLookup(a.a_type, probeCopy, Array(
|
2015-02-02 04:57:53 +01:00
|
|
|
Acquire.uncachedReadBlock -> probeCopy,
|
|
|
|
Acquire.uncachedWriteBlock -> probeInvalidate,
|
2014-11-12 02:36:55 +01:00
|
|
|
Acquire.uncachedRead -> probeCopy,
|
|
|
|
Acquire.uncachedWrite -> probeInvalidate,
|
2015-02-02 04:57:53 +01:00
|
|
|
Acquire.uncachedAtomic -> probeInvalidate)),
|
|
|
|
probeInvalidate)
|
|
|
|
|
|
|
|
def getProbeType(cmd: UInt, meta: ManagerMetadata): UInt =
|
|
|
|
MuxLookup(cmd, probeCopy, Array(
|
|
|
|
M_FLUSH -> probeInvalidate,
|
|
|
|
M_PRODUCE -> probeDowngrade))
|
2012-04-10 09:09:58 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def requiresOuterRead(acq: Acquire, meta: ManagerMetadata) =
|
2015-02-02 10:02:06 +01:00
|
|
|
Mux(acq.builtin_type, Acquire.requiresOuterRead(acq.a_type), Bool(true))
|
2015-02-02 04:57:53 +01:00
|
|
|
|
|
|
|
def requiresOuterWrite(acq: Acquire, meta: ManagerMetadata) =
|
2015-02-02 10:02:06 +01:00
|
|
|
Mux(acq.builtin_type, Acquire.requiresOuterWrite(acq.a_type), Bool(false))
|
2014-11-12 02:36:55 +01:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def requiresProbes(a: Acquire, meta: ManagerMetadata) =
|
|
|
|
Mux(dir.none(meta.sharers), Bool(false),
|
|
|
|
Mux(dir.one(meta.sharers), Bool(true), //TODO: for now we assume it's Exclusive
|
2015-02-02 10:02:06 +01:00
|
|
|
Mux(a.builtin_type, a.hasData(), Bool(true))))
|
2015-02-02 04:57:53 +01:00
|
|
|
|
|
|
|
def requiresProbes(cmd: UInt, meta: ManagerMetadata) = !dir.none(meta.sharers)
|
2012-02-15 00:51:32 +01:00
|
|
|
}
|
|
|
|
|
2014-12-16 04:23:13 +01:00
|
|
|
class MSICoherence(dir: DirectoryRepresentation) extends CoherencePolicy(dir) {
|
2013-08-02 23:55:06 +02:00
|
|
|
def nClientStates = 3
|
2014-12-30 07:55:58 +01:00
|
|
|
def nManagerStates = 2
|
2014-11-12 02:36:55 +01:00
|
|
|
def nAcquireTypes = 2
|
2013-08-02 23:55:06 +02:00
|
|
|
def nProbeTypes = 3
|
2015-02-02 04:57:53 +01:00
|
|
|
def nReleaseTypes = 6
|
2014-11-12 02:36:55 +01:00
|
|
|
def nGrantTypes = 3
|
2013-08-02 23:55:06 +02:00
|
|
|
|
2014-05-28 22:35:08 +02:00
|
|
|
val clientInvalid :: clientShared :: clientExclusiveDirty :: Nil = Enum(UInt(), nClientStates)
|
2015-02-02 04:57:53 +01:00
|
|
|
//val managerInvalid :: masterShared :: masterExclusive :: Nil = Enum(UInt(), nManagerStates)
|
|
|
|
val managerInvalid :: managerValid :: Nil = Enum(UInt(), nManagerStates)
|
2012-04-12 02:56:59 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
val acquireShared :: acquireExclusive :: Nil = Enum(UInt(), nAcquireTypes)
|
2013-09-10 19:54:51 +02:00
|
|
|
val probeInvalidate :: probeDowngrade :: probeCopy :: Nil = Enum(UInt(), nProbeTypes)
|
2015-02-02 04:57:53 +01:00
|
|
|
val releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(UInt(), nReleaseTypes)
|
|
|
|
val grantShared :: grantExclusive :: grantExclusiveAck :: Nil = Enum(UInt(), nGrantTypes)
|
2012-04-12 02:56:59 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
val clientStatesWithReadPermission = Vec(clientShared, clientExclusiveDirty)
|
|
|
|
val clientStatesWithWritePermission = Vec(clientExclusiveDirty)
|
|
|
|
val clientStatesWithDirtyData = Vec(clientExclusiveDirty)
|
|
|
|
val releaseTypesWithData = Vec(releaseInvalidateData, releaseDowngradeData, releaseCopyData)
|
|
|
|
val grantTypesWithData = Vec(grantShared, grantExclusive)
|
2012-04-12 02:56:59 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def isValid(meta: ClientMetadata): Bool = meta.state != clientInvalid
|
|
|
|
def isValid(meta: ManagerMetadata) = meta.state != managerInvalid
|
2012-04-12 02:56:59 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def needsTransactionOnSecondaryMiss(cmd: UInt, outstanding: Acquire): Bool =
|
2015-02-02 10:02:06 +01:00
|
|
|
(isRead(cmd) && outstanding.builtin_type) ||
|
2015-02-02 04:57:53 +01:00
|
|
|
(isWriteIntent(cmd) && (outstanding.a_type != acquireExclusive))
|
|
|
|
|
|
|
|
def clientMetadataOnHit(cmd: UInt, meta: ClientMetadata) =
|
|
|
|
ClientMetadata(Mux(isWrite(cmd), clientExclusiveDirty, meta.state))
|
|
|
|
|
|
|
|
def clientMetadataOnFlush = ClientMetadata(clientInvalid)
|
|
|
|
|
|
|
|
def clientMetadataOnCacheControl(cmd: UInt, meta: ClientMetadata) =
|
|
|
|
ClientMetadata(
|
|
|
|
MuxLookup(cmd, meta.state, Array(
|
|
|
|
M_FLUSH -> clientInvalid,
|
|
|
|
M_PRODUCE -> Mux(clientStatesWithWritePermission.contains(meta.state),
|
|
|
|
clientShared, meta.state))))
|
|
|
|
|
|
|
|
def clientMetadataOnGrant(incoming: Grant, outstanding: Acquire) =
|
|
|
|
ClientMetadata(
|
2015-02-02 10:02:06 +01:00
|
|
|
Mux(incoming.builtin_type, clientInvalid,
|
2015-02-02 04:57:53 +01:00
|
|
|
MuxLookup(incoming.g_type, clientInvalid, Array(
|
|
|
|
grantShared -> clientShared,
|
|
|
|
grantExclusive -> clientExclusiveDirty,
|
|
|
|
grantExclusiveAck -> clientExclusiveDirty))))
|
|
|
|
|
|
|
|
def clientMetadataOnProbe(incoming: Probe, meta: ClientMetadata) =
|
|
|
|
ClientMetadata(
|
|
|
|
MuxLookup(incoming.p_type, meta.state, Array(
|
|
|
|
probeInvalidate -> clientInvalid,
|
|
|
|
probeDowngrade -> clientShared,
|
|
|
|
probeCopy -> meta.state)))
|
|
|
|
|
|
|
|
def managerMetadataOnRelease(r: Release, meta: ManagerMetadata, src: UInt) = {
|
|
|
|
val next = ManagerMetadata(managerValid, dir.pop(meta.sharers,src))
|
|
|
|
MuxBundle(meta, Array(
|
2014-10-08 07:33:10 +02:00
|
|
|
r.is(releaseInvalidateData) -> next,
|
|
|
|
r.is(releaseInvalidateAck) -> next
|
|
|
|
))
|
|
|
|
}
|
2012-04-12 02:56:59 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def managerMetadataOnGrant(g: Grant, meta: ManagerMetadata, dst: UInt) =
|
2015-02-02 10:02:06 +01:00
|
|
|
Mux(g.builtin_type,
|
2015-02-02 04:57:53 +01:00
|
|
|
ManagerMetadata(managerValid, meta.sharers),
|
|
|
|
ManagerMetadata(managerValid, dir.push(meta.sharers, dst)))
|
2012-10-02 01:05:37 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def managerMetadataOnFlush = ManagerMetadata(managerInvalid)
|
2012-04-12 02:56:59 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def managerMetadataOnCacheControl(cmd: UInt, meta: ManagerMetadata) =
|
|
|
|
ManagerMetadata(Mux(cmd === M_FLUSH, managerInvalid, meta.state))
|
|
|
|
|
|
|
|
def getAcquireTypeOnPrimaryMiss(cmd: UInt, meta: ClientMetadata): UInt =
|
|
|
|
Mux(isWriteIntent(cmd), acquireExclusive, acquireShared)
|
|
|
|
|
|
|
|
def getAcquireTypeOnSecondaryMiss(cmd: UInt, meta: ClientMetadata, outstanding: Acquire): UInt =
|
|
|
|
Mux(isWriteIntent(cmd), acquireExclusive, outstanding.a_type)
|
|
|
|
|
|
|
|
def getReleaseType(cmd: UInt, meta: ClientMetadata): UInt = {
|
|
|
|
val dirty = clientStatesWithDirtyData.contains(meta.state)
|
|
|
|
MuxLookup(cmd, releaseCopyAck, Array(
|
|
|
|
M_FLUSH -> Mux(dirty, releaseInvalidateData, releaseInvalidateAck),
|
|
|
|
M_PRODUCE -> Mux(dirty, releaseDowngradeData, releaseDowngradeAck),
|
|
|
|
M_CLEAN -> Mux(dirty, releaseCopyData, releaseCopyAck)))
|
2012-04-12 02:56:59 +02:00
|
|
|
}
|
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def getReleaseType(incoming: Probe, meta: ClientMetadata): UInt =
|
|
|
|
MuxLookup(incoming.p_type, releaseInvalidateAck, Array(
|
|
|
|
probeInvalidate -> getReleaseType(M_FLUSH, meta),
|
|
|
|
probeDowngrade -> getReleaseType(M_PRODUCE, meta),
|
|
|
|
probeCopy -> getReleaseType(M_CLEAN, meta)))
|
|
|
|
|
2014-01-21 21:20:55 +01:00
|
|
|
def isCoherenceConflict(addr1: UInt, addr2: UInt): Bool = (addr1 === addr2)
|
2012-04-12 02:56:59 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def getGrantType(a: Acquire, meta: ManagerMetadata): UInt =
|
2015-02-02 10:02:06 +01:00
|
|
|
Mux(a.builtin_type, Grant.getGrantTypeForUncached(a),
|
2015-02-02 04:57:53 +01:00
|
|
|
Mux(a.a_type === acquireShared,
|
|
|
|
Mux(!dir.none(meta.sharers), grantShared, grantExclusive),
|
|
|
|
grantExclusive))
|
2013-01-29 01:39:45 +01:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def getProbeType(a: Acquire, meta: ManagerMetadata): UInt =
|
2015-02-02 10:02:06 +01:00
|
|
|
Mux(a.builtin_type,
|
2014-11-12 02:36:55 +01:00
|
|
|
MuxLookup(a.a_type, probeCopy, Array(
|
2015-02-02 04:57:53 +01:00
|
|
|
Acquire.uncachedReadBlock -> probeCopy,
|
|
|
|
Acquire.uncachedWriteBlock -> probeInvalidate,
|
2014-11-12 02:36:55 +01:00
|
|
|
Acquire.uncachedRead -> probeCopy,
|
|
|
|
Acquire.uncachedWrite -> probeInvalidate,
|
2015-02-02 04:57:53 +01:00
|
|
|
Acquire.uncachedAtomic -> probeInvalidate)),
|
|
|
|
MuxLookup(a.a_type, probeCopy, Array(
|
|
|
|
acquireShared -> probeDowngrade,
|
|
|
|
acquireExclusive -> probeInvalidate)))
|
2012-04-12 02:56:59 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def getProbeType(cmd: UInt, meta: ManagerMetadata): UInt =
|
|
|
|
MuxLookup(cmd, probeCopy, Array(
|
|
|
|
M_FLUSH -> probeInvalidate,
|
|
|
|
M_PRODUCE -> probeDowngrade))
|
|
|
|
|
|
|
|
def requiresOuterRead(acq: Acquire, meta: ManagerMetadata) =
|
2015-02-02 10:02:06 +01:00
|
|
|
Mux(acq.builtin_type, Acquire.requiresOuterRead(acq.a_type), Bool(true))
|
2015-02-02 04:57:53 +01:00
|
|
|
|
|
|
|
def requiresOuterWrite(acq: Acquire, meta: ManagerMetadata) =
|
2015-02-02 10:02:06 +01:00
|
|
|
Mux(acq.builtin_type, Acquire.requiresOuterWrite(acq.a_type), Bool(false))
|
2014-11-12 02:36:55 +01:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def requiresProbes(a: Acquire, meta: ManagerMetadata) =
|
|
|
|
Mux(dir.none(meta.sharers), Bool(false),
|
|
|
|
Mux(dir.one(meta.sharers), Bool(true), //TODO: for now we assume it's Exclusive
|
2015-02-02 10:02:06 +01:00
|
|
|
Mux(a.builtin_type, a.hasData(), a.a_type != acquireShared)))
|
2015-02-02 04:57:53 +01:00
|
|
|
|
|
|
|
def requiresProbes(cmd: UInt, meta: ManagerMetadata) = !dir.none(meta.sharers)
|
2012-04-12 02:56:59 +02:00
|
|
|
}
|
|
|
|
|
2014-12-16 04:23:13 +01:00
|
|
|
class MESICoherence(dir: DirectoryRepresentation) extends CoherencePolicy(dir) {
|
2013-08-02 23:55:06 +02:00
|
|
|
def nClientStates = 4
|
2014-12-30 07:55:58 +01:00
|
|
|
def nManagerStates = 2
|
2014-11-12 02:36:55 +01:00
|
|
|
def nAcquireTypes = 2
|
2013-08-02 23:55:06 +02:00
|
|
|
def nProbeTypes = 3
|
2015-02-02 04:57:53 +01:00
|
|
|
def nReleaseTypes = 6
|
|
|
|
def nGrantTypes = 3
|
2012-02-15 00:51:32 +01:00
|
|
|
|
2014-05-28 22:35:08 +02:00
|
|
|
val clientInvalid :: clientShared :: clientExclusiveClean :: clientExclusiveDirty :: Nil = Enum(UInt(), nClientStates)
|
2015-02-02 04:57:53 +01:00
|
|
|
//val managerInvalid :: masterShared :: masterExclusive :: Nil = Enum(UInt(), nManagerStates)
|
|
|
|
val managerInvalid :: managerValid :: Nil = Enum(UInt(), nManagerStates)
|
2012-02-15 00:51:32 +01:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
val acquireShared :: acquireExclusive :: Nil = Enum(UInt(), nAcquireTypes)
|
2013-09-10 19:54:51 +02:00
|
|
|
val probeInvalidate :: probeDowngrade :: probeCopy :: Nil = Enum(UInt(), nProbeTypes)
|
2015-02-02 04:57:53 +01:00
|
|
|
val releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(UInt(), nReleaseTypes)
|
|
|
|
val grantShared :: grantExclusive :: grantExclusiveAck :: Nil = Enum(UInt(), nGrantTypes)
|
2013-03-01 03:13:41 +01:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
val clientStatesWithReadPermission = Vec(clientShared, clientExclusiveClean, clientExclusiveDirty)
|
|
|
|
val clientStatesWithWritePermission = Vec(clientExclusiveClean, clientExclusiveDirty)
|
|
|
|
val clientStatesWithDirtyData = Vec(clientExclusiveDirty)
|
|
|
|
val releaseTypesWithData = Vec(releaseInvalidateData, releaseDowngradeData, releaseCopyData)
|
|
|
|
val grantTypesWithData = Vec(grantShared, grantExclusive)
|
2012-04-03 21:03:05 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def isValid (meta: ClientMetadata): Bool = meta.state != clientInvalid
|
|
|
|
def isValid (meta: ManagerMetadata) = meta.state != managerInvalid
|
2012-02-15 00:51:32 +01:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def needsTransactionOnSecondaryMiss(cmd: UInt, outstanding: Acquire): Bool =
|
2015-02-02 10:02:06 +01:00
|
|
|
(isRead(cmd) && outstanding.builtin_type) ||
|
2015-02-02 04:57:53 +01:00
|
|
|
(isWriteIntent(cmd) && (outstanding.a_type != acquireExclusive))
|
|
|
|
|
|
|
|
def clientMetadataOnHit(cmd: UInt, meta: ClientMetadata) =
|
|
|
|
ClientMetadata(Mux(isWrite(cmd), clientExclusiveDirty, meta.state))
|
|
|
|
|
|
|
|
def clientMetadataOnFlush = ClientMetadata(clientInvalid)
|
|
|
|
|
|
|
|
def clientMetadataOnCacheControl(cmd: UInt, meta: ClientMetadata) =
|
|
|
|
ClientMetadata(
|
|
|
|
MuxLookup(cmd, meta.state, Array(
|
|
|
|
M_FLUSH -> clientInvalid,
|
|
|
|
M_PRODUCE -> Mux(clientStatesWithWritePermission.contains(meta.state),
|
|
|
|
clientShared, meta.state),
|
|
|
|
M_CLEAN -> Mux(meta.state === clientExclusiveDirty, clientExclusiveClean, meta.state))))
|
|
|
|
|
|
|
|
def clientMetadataOnGrant(incoming: Grant, outstanding: Acquire) =
|
|
|
|
ClientMetadata(
|
2015-02-02 10:02:06 +01:00
|
|
|
Mux(incoming.builtin_type, clientInvalid,
|
2015-02-02 04:57:53 +01:00
|
|
|
MuxLookup(incoming.g_type, clientInvalid, Array(
|
|
|
|
grantShared -> clientShared,
|
|
|
|
grantExclusive -> Mux(outstanding.a_type === acquireExclusive,
|
|
|
|
clientExclusiveDirty, clientExclusiveClean),
|
|
|
|
grantExclusiveAck -> clientExclusiveDirty))))
|
|
|
|
|
|
|
|
def clientMetadataOnProbe(incoming: Probe, meta: ClientMetadata) =
|
|
|
|
ClientMetadata(
|
|
|
|
MuxLookup(incoming.p_type, meta.state, Array(
|
|
|
|
probeInvalidate -> clientInvalid,
|
|
|
|
probeDowngrade -> clientShared,
|
|
|
|
probeCopy -> meta.state)))
|
|
|
|
|
|
|
|
def managerMetadataOnRelease(r: Release, meta: ManagerMetadata, src: UInt) = {
|
|
|
|
val next = ManagerMetadata(managerValid, dir.pop(meta.sharers,src))
|
|
|
|
MuxBundle(meta, Array(
|
2014-10-08 07:33:10 +02:00
|
|
|
r.is(releaseInvalidateData) -> next,
|
|
|
|
r.is(releaseInvalidateAck) -> next
|
|
|
|
))
|
|
|
|
}
|
2012-03-02 02:03:56 +01:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def managerMetadataOnGrant(g: Grant, meta: ManagerMetadata, dst: UInt) =
|
2015-02-02 10:02:06 +01:00
|
|
|
Mux(g.builtin_type,
|
2015-02-02 04:57:53 +01:00
|
|
|
ManagerMetadata(managerValid, meta.sharers),
|
|
|
|
ManagerMetadata(managerValid, dir.push(meta.sharers, dst)))
|
2012-10-02 01:05:37 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def managerMetadataOnFlush = ManagerMetadata(managerInvalid)
|
2012-04-03 21:03:05 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def managerMetadataOnCacheControl(cmd: UInt, meta: ManagerMetadata) =
|
|
|
|
ManagerMetadata(Mux(cmd === M_FLUSH, managerInvalid, meta.state))
|
|
|
|
|
|
|
|
def getAcquireTypeOnPrimaryMiss(cmd: UInt, meta: ClientMetadata): UInt =
|
|
|
|
Mux(isWriteIntent(cmd), acquireExclusive, acquireShared)
|
|
|
|
|
|
|
|
def getAcquireTypeOnSecondaryMiss(cmd: UInt, meta: ClientMetadata, outstanding: Acquire): UInt =
|
|
|
|
Mux(isWriteIntent(cmd), acquireExclusive, outstanding.a_type)
|
|
|
|
|
|
|
|
def getReleaseType(cmd: UInt, meta: ClientMetadata): UInt = {
|
|
|
|
val dirty = clientStatesWithDirtyData.contains(meta.state)
|
|
|
|
MuxLookup(cmd, releaseCopyAck, Array(
|
|
|
|
M_FLUSH -> Mux(dirty, releaseInvalidateData, releaseInvalidateAck),
|
|
|
|
M_PRODUCE -> Mux(dirty, releaseDowngradeData, releaseDowngradeAck),
|
|
|
|
M_CLEAN -> Mux(dirty, releaseCopyData, releaseCopyAck)))
|
2012-04-10 09:09:58 +02:00
|
|
|
}
|
2012-02-15 00:51:32 +01:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def getReleaseType(incoming: Probe, meta: ClientMetadata): UInt =
|
|
|
|
MuxLookup(incoming.p_type, releaseInvalidateAck, Array(
|
|
|
|
probeInvalidate -> getReleaseType(M_FLUSH, meta),
|
|
|
|
probeDowngrade -> getReleaseType(M_PRODUCE, meta),
|
|
|
|
probeCopy -> getReleaseType(M_CLEAN, meta)))
|
|
|
|
|
2014-01-21 21:20:55 +01:00
|
|
|
def isCoherenceConflict(addr1: UInt, addr2: UInt): Bool = (addr1 === addr2)
|
2012-04-03 21:03:05 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def getGrantType(a: Acquire, meta: ManagerMetadata): UInt =
|
2015-02-02 10:02:06 +01:00
|
|
|
Mux(a.builtin_type, Grant.getGrantTypeForUncached(a),
|
2015-02-02 04:57:53 +01:00
|
|
|
Mux(a.a_type === acquireShared,
|
|
|
|
Mux(!dir.none(meta.sharers), grantShared, grantExclusive),
|
|
|
|
grantExclusive))
|
2012-02-22 21:14:57 +01:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def getProbeType(a: Acquire, meta: ManagerMetadata): UInt =
|
2015-02-02 10:02:06 +01:00
|
|
|
Mux(a.builtin_type,
|
2014-11-12 02:36:55 +01:00
|
|
|
MuxLookup(a.a_type, probeCopy, Array(
|
2015-02-02 04:57:53 +01:00
|
|
|
Acquire.uncachedReadBlock -> probeCopy,
|
|
|
|
Acquire.uncachedWriteBlock -> probeInvalidate,
|
2014-11-12 02:36:55 +01:00
|
|
|
Acquire.uncachedRead -> probeCopy,
|
|
|
|
Acquire.uncachedWrite -> probeInvalidate,
|
2015-02-02 04:57:53 +01:00
|
|
|
Acquire.uncachedAtomic -> probeInvalidate)),
|
2014-11-12 02:36:55 +01:00
|
|
|
MuxLookup(a.a_type, probeCopy, Array(
|
2015-02-02 04:57:53 +01:00
|
|
|
acquireShared -> probeDowngrade,
|
|
|
|
acquireExclusive -> probeInvalidate)))
|
|
|
|
|
|
|
|
def getProbeType(cmd: UInt, meta: ManagerMetadata): UInt =
|
|
|
|
MuxLookup(cmd, probeCopy, Array(
|
|
|
|
M_FLUSH -> probeInvalidate,
|
|
|
|
M_PRODUCE -> probeDowngrade))
|
2012-02-29 02:33:06 +01:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def requiresOuterRead(acq: Acquire, meta: ManagerMetadata) =
|
2015-02-02 10:02:06 +01:00
|
|
|
Mux(acq.builtin_type, Acquire.requiresOuterRead(acq.a_type), Bool(true))
|
2015-02-02 04:57:53 +01:00
|
|
|
|
|
|
|
def requiresOuterWrite(acq: Acquire, meta: ManagerMetadata) =
|
2015-02-02 10:02:06 +01:00
|
|
|
Mux(acq.builtin_type, Acquire.requiresOuterWrite(acq.a_type), Bool(false))
|
2013-01-29 01:39:45 +01:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def requiresProbes(a: Acquire, meta: ManagerMetadata) =
|
|
|
|
Mux(dir.none(meta.sharers), Bool(false),
|
|
|
|
Mux(dir.one(meta.sharers), Bool(true), //TODO: for now we assume it's Exclusive
|
2015-02-02 10:02:06 +01:00
|
|
|
Mux(a.builtin_type, a.hasData(), a.a_type != acquireShared)))
|
2015-02-02 04:57:53 +01:00
|
|
|
|
|
|
|
def requiresProbes(cmd: UInt, meta: ManagerMetadata) = !dir.none(meta.sharers)
|
2012-02-23 03:24:52 +01:00
|
|
|
}
|
2012-10-24 03:01:53 +02:00
|
|
|
|
2014-12-16 04:23:13 +01:00
|
|
|
class MigratoryCoherence(dir: DirectoryRepresentation) extends CoherencePolicy(dir) {
|
2013-08-02 23:55:06 +02:00
|
|
|
def nClientStates = 7
|
2014-12-30 07:55:58 +01:00
|
|
|
def nManagerStates = 2
|
2014-11-12 02:36:55 +01:00
|
|
|
def nAcquireTypes = 3
|
2013-08-02 23:55:06 +02:00
|
|
|
def nProbeTypes = 4
|
2015-02-02 04:57:53 +01:00
|
|
|
def nReleaseTypes = 10
|
|
|
|
def nGrantTypes = 4
|
2012-10-24 03:01:53 +02:00
|
|
|
|
2014-05-28 22:35:08 +02:00
|
|
|
val clientInvalid :: clientShared :: clientExclusiveClean :: clientExclusiveDirty :: clientSharedByTwo :: clientMigratoryClean :: clientMigratoryDirty :: Nil = Enum(UInt(), nClientStates)
|
2015-02-02 04:57:53 +01:00
|
|
|
//val managerInvalid :: masterShared :: masterExclusive :: Nil = Enum(UInt(), nManagerStates)
|
|
|
|
val managerInvalid :: managerValid :: Nil = Enum(UInt(), nManagerStates)
|
2012-10-24 03:01:53 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
val acquireShared :: acquireExclusive :: acquireInvalidateOthers :: Nil = Enum(UInt(), nAcquireTypes)
|
2013-09-10 19:54:51 +02:00
|
|
|
val probeInvalidate :: probeDowngrade :: probeCopy :: probeInvalidateOthers :: Nil = Enum(UInt(), nProbeTypes)
|
2015-02-02 04:57:53 +01:00
|
|
|
val releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: releaseDowngradeDataMigratory :: releaseDowngradeAckHasCopy :: releaseInvalidateDataMigratory :: releaseInvalidateAckMigratory :: Nil = Enum(UInt(), nReleaseTypes)
|
|
|
|
val grantShared :: grantExclusive :: grantExclusiveAck :: grantReadMigratory :: Nil = Enum(UInt(), nGrantTypes)
|
2012-10-24 03:01:53 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
val clientStatesWithReadPermission = Vec(clientShared, clientExclusiveClean, clientExclusiveDirty, clientSharedByTwo, clientMigratoryClean, clientMigratoryDirty)
|
|
|
|
val clientStatesWithWritePermission = Vec(clientExclusiveClean, clientExclusiveDirty, clientMigratoryClean, clientMigratoryDirty)
|
|
|
|
val clientStatesWithDirtyData = Vec(clientExclusiveDirty, clientMigratoryDirty)
|
|
|
|
val releaseTypesWithData = Vec(releaseInvalidateData, releaseDowngradeData, releaseCopyData, releaseInvalidateDataMigratory, releaseDowngradeDataMigratory)
|
|
|
|
val grantTypesWithData = Vec(grantShared, grantExclusive, grantReadMigratory)
|
2012-10-24 03:01:53 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def isValid (meta: ClientMetadata): Bool = meta.state != clientInvalid
|
|
|
|
def isValid (meta: ManagerMetadata) = meta.state != managerInvalid
|
2012-10-24 03:01:53 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def needsTransactionOnSecondaryMiss(cmd: UInt, outstanding: Acquire): Bool =
|
2015-02-02 10:02:06 +01:00
|
|
|
(isRead(cmd) && outstanding.builtin_type) ||
|
2015-02-02 04:57:53 +01:00
|
|
|
(isWriteIntent(cmd) && !Vec(acquireExclusive, acquireInvalidateOthers).contains(outstanding.a_type))
|
|
|
|
|
|
|
|
def clientMetadataOnHit(cmd: UInt, meta: ClientMetadata) =
|
|
|
|
ClientMetadata(
|
|
|
|
Mux(isWrite(cmd), MuxLookup(meta.state, clientExclusiveDirty, Array(
|
|
|
|
clientExclusiveClean -> clientExclusiveDirty,
|
|
|
|
clientMigratoryClean -> clientMigratoryDirty)),
|
|
|
|
meta.state))
|
|
|
|
|
|
|
|
def clientMetadataOnFlush = ClientMetadata(clientInvalid)
|
|
|
|
|
|
|
|
def clientMetadataOnCacheControl(cmd: UInt, meta: ClientMetadata) =
|
|
|
|
ClientMetadata(
|
|
|
|
MuxLookup(cmd, meta.state, Array(
|
|
|
|
M_FLUSH -> clientInvalid,
|
|
|
|
M_PRODUCE -> Mux(clientStatesWithWritePermission.contains(meta.state),
|
|
|
|
clientShared, meta.state),
|
|
|
|
M_CLEAN -> MuxLookup(meta.state, meta.state, Array(
|
|
|
|
clientExclusiveDirty -> clientExclusiveClean,
|
|
|
|
clientMigratoryDirty -> clientMigratoryClean)))))
|
|
|
|
|
|
|
|
def clientMetadataOnGrant(incoming: Grant, outstanding: Acquire) =
|
|
|
|
ClientMetadata(
|
2015-02-02 10:02:06 +01:00
|
|
|
Mux(incoming.builtin_type, clientInvalid,
|
2015-02-02 04:57:53 +01:00
|
|
|
MuxLookup(incoming.g_type, clientInvalid, Array(
|
|
|
|
grantShared -> clientShared,
|
|
|
|
grantExclusive -> MuxLookup(outstanding.a_type, clientExclusiveDirty, Array(
|
|
|
|
acquireExclusive -> clientExclusiveDirty,
|
|
|
|
acquireShared -> clientExclusiveClean)),
|
|
|
|
grantExclusiveAck -> clientExclusiveDirty,
|
|
|
|
grantReadMigratory -> MuxLookup(outstanding.a_type, clientMigratoryDirty, Array(
|
|
|
|
acquireInvalidateOthers -> clientMigratoryDirty,
|
|
|
|
acquireExclusive -> clientMigratoryDirty,
|
|
|
|
acquireShared -> clientMigratoryClean))))))
|
|
|
|
|
|
|
|
def clientMetadataOnProbe(incoming: Probe, meta: ClientMetadata) =
|
|
|
|
ClientMetadata(
|
|
|
|
MuxLookup(incoming.p_type, meta.state, Array(
|
|
|
|
probeInvalidate -> clientInvalid,
|
|
|
|
probeInvalidateOthers -> clientInvalid,
|
|
|
|
probeCopy -> meta.state,
|
|
|
|
probeDowngrade -> MuxLookup(meta.state, clientShared, Array(
|
|
|
|
clientExclusiveClean -> clientSharedByTwo,
|
|
|
|
clientExclusiveDirty -> clientSharedByTwo,
|
|
|
|
clientSharedByTwo -> clientShared,
|
|
|
|
clientMigratoryClean -> clientSharedByTwo,
|
|
|
|
clientMigratoryDirty -> clientInvalid)))))
|
|
|
|
|
|
|
|
def managerMetadataOnRelease(r: Release, meta: ManagerMetadata, src: UInt) = {
|
|
|
|
val next = ManagerMetadata(managerValid, dir.pop(meta.sharers,src))
|
|
|
|
MuxBundle(meta, Array(
|
2014-10-08 07:33:10 +02:00
|
|
|
r.is(releaseInvalidateData) -> next,
|
|
|
|
r.is(releaseInvalidateAck) -> next,
|
|
|
|
r.is(releaseInvalidateDataMigratory) -> next,
|
2015-02-02 04:57:53 +01:00
|
|
|
r.is(releaseInvalidateAckMigratory) -> next))
|
2012-10-24 03:01:53 +02:00
|
|
|
}
|
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def managerMetadataOnGrant(g: Grant, meta: ManagerMetadata, dst: UInt) =
|
2015-02-02 10:02:06 +01:00
|
|
|
Mux(g.builtin_type,
|
2015-02-02 04:57:53 +01:00
|
|
|
ManagerMetadata(managerValid, meta.sharers),
|
|
|
|
ManagerMetadata(managerValid, dir.push(meta.sharers, dst)))
|
2014-05-28 22:35:08 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def managerMetadataOnFlush = ManagerMetadata(managerInvalid)
|
2012-10-24 03:01:53 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def managerMetadataOnCacheControl(cmd: UInt, meta: ManagerMetadata) =
|
|
|
|
ManagerMetadata(Mux(cmd === M_FLUSH, managerInvalid, meta.state))
|
|
|
|
|
|
|
|
def getAcquireTypeOnPrimaryMiss(cmd: UInt, meta: ClientMetadata): UInt =
|
|
|
|
Mux(isWriteIntent(cmd),
|
|
|
|
Mux(meta.state === clientInvalid, acquireExclusive, acquireInvalidateOthers),
|
|
|
|
acquireShared)
|
|
|
|
|
|
|
|
def getAcquireTypeOnSecondaryMiss(cmd: UInt, meta: ClientMetadata, outstanding: Acquire): UInt =
|
|
|
|
Mux(isWriteIntent(cmd),
|
|
|
|
Mux(meta.state === clientInvalid, acquireExclusive, acquireInvalidateOthers),
|
|
|
|
outstanding.a_type)
|
|
|
|
|
|
|
|
def getReleaseType(cmd: UInt, meta: ClientMetadata): UInt = {
|
|
|
|
val dirty = clientStatesWithDirtyData.contains(meta.state)
|
|
|
|
MuxLookup(cmd, releaseCopyAck, Array(
|
|
|
|
M_FLUSH -> Mux(dirty, releaseInvalidateData, releaseInvalidateAck),
|
|
|
|
M_PRODUCE -> Mux(dirty, releaseDowngradeData, releaseDowngradeAck),
|
|
|
|
M_CLEAN -> Mux(dirty, releaseCopyData, releaseCopyAck)))
|
2013-01-22 02:17:26 +01:00
|
|
|
}
|
2015-02-02 04:57:53 +01:00
|
|
|
|
|
|
|
def getReleaseType(incoming: Probe, meta: ClientMetadata): UInt = {
|
|
|
|
val dirty = clientStatesWithDirtyData.contains(meta.state)
|
2013-01-22 02:17:26 +01:00
|
|
|
val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array(
|
2015-02-02 04:57:53 +01:00
|
|
|
probeInvalidate -> Mux(Vec(clientExclusiveDirty, clientMigratoryDirty).contains(meta.state),
|
|
|
|
releaseInvalidateDataMigratory, releaseInvalidateData),
|
|
|
|
probeDowngrade -> Mux(meta.state === clientMigratoryDirty,
|
|
|
|
releaseDowngradeDataMigratory, releaseDowngradeData),
|
|
|
|
probeCopy -> releaseCopyData))
|
2013-01-22 02:17:26 +01:00
|
|
|
val without_data = MuxLookup(incoming.p_type, releaseInvalidateAck, Array(
|
2015-02-02 04:57:53 +01:00
|
|
|
probeInvalidate -> Mux(clientExclusiveClean === meta.state,
|
|
|
|
releaseInvalidateAckMigratory, releaseInvalidateAck),
|
|
|
|
probeInvalidateOthers -> Mux(clientSharedByTwo === meta.state,
|
|
|
|
releaseInvalidateAckMigratory, releaseInvalidateAck),
|
|
|
|
probeDowngrade -> Mux(meta.state != clientInvalid,
|
|
|
|
releaseDowngradeAckHasCopy, releaseDowngradeAck),
|
|
|
|
probeCopy -> releaseCopyAck))
|
|
|
|
Mux(dirty, with_data, without_data)
|
2014-11-12 02:36:55 +01:00
|
|
|
}
|
2012-10-24 03:01:53 +02:00
|
|
|
|
2014-01-21 21:20:55 +01:00
|
|
|
def isCoherenceConflict(addr1: UInt, addr2: UInt): Bool = (addr1 === addr2)
|
2012-10-24 03:01:53 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def getGrantType(a: Acquire, meta: ManagerMetadata): UInt =
|
2015-02-02 10:02:06 +01:00
|
|
|
Mux(a.builtin_type, Grant.getGrantTypeForUncached(a),
|
2015-02-02 04:57:53 +01:00
|
|
|
MuxLookup(a.a_type, grantShared, Array(
|
|
|
|
acquireShared -> Mux(!dir.none(meta.sharers), grantShared, grantExclusive),
|
|
|
|
acquireExclusive -> grantExclusive,
|
|
|
|
acquireInvalidateOthers -> grantExclusiveAck))) //TODO: add this to MESI for broadcast?
|
2012-10-24 03:01:53 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def getProbeType(a: Acquire, meta: ManagerMetadata): UInt =
|
2015-02-02 10:02:06 +01:00
|
|
|
Mux(a.builtin_type,
|
2014-11-12 02:36:55 +01:00
|
|
|
MuxLookup(a.a_type, probeCopy, Array(
|
2015-02-02 04:57:53 +01:00
|
|
|
Acquire.uncachedReadBlock -> probeCopy,
|
|
|
|
Acquire.uncachedWriteBlock -> probeInvalidate,
|
2014-11-12 02:36:55 +01:00
|
|
|
Acquire.uncachedRead -> probeCopy,
|
|
|
|
Acquire.uncachedWrite -> probeInvalidate,
|
2015-02-02 04:57:53 +01:00
|
|
|
Acquire.uncachedAtomic -> probeInvalidate)),
|
2014-11-12 02:36:55 +01:00
|
|
|
MuxLookup(a.a_type, probeCopy, Array(
|
2015-02-02 04:57:53 +01:00
|
|
|
acquireShared -> probeDowngrade,
|
|
|
|
acquireExclusive -> probeInvalidate,
|
|
|
|
acquireInvalidateOthers -> probeInvalidateOthers)))
|
|
|
|
|
|
|
|
def getProbeType(cmd: UInt, meta: ManagerMetadata): UInt =
|
|
|
|
MuxLookup(cmd, probeCopy, Array(
|
|
|
|
M_FLUSH -> probeInvalidate,
|
|
|
|
M_PRODUCE -> probeDowngrade))
|
2012-10-24 03:01:53 +02:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def requiresOuterRead(acq: Acquire, meta: ManagerMetadata) =
|
2015-02-02 10:02:06 +01:00
|
|
|
Mux(acq.builtin_type, Acquire.requiresOuterRead(acq.a_type), acq.a_type != acquireInvalidateOthers)
|
2015-02-02 04:57:53 +01:00
|
|
|
|
|
|
|
def requiresOuterWrite(acq: Acquire, meta: ManagerMetadata) =
|
2015-02-02 10:02:06 +01:00
|
|
|
Mux(acq.builtin_type, Acquire.requiresOuterWrite(acq.a_type), Bool(false))
|
2014-01-21 21:20:55 +01:00
|
|
|
|
2015-02-02 04:57:53 +01:00
|
|
|
def requiresProbes(a: Acquire, meta: ManagerMetadata) =
|
|
|
|
Mux(dir.none(meta.sharers), Bool(false),
|
|
|
|
Mux(dir.one(meta.sharers), Bool(true), //TODO: for now we assume it's Exclusive
|
2015-02-02 10:02:06 +01:00
|
|
|
Mux(a.builtin_type, a.hasData(), a.a_type != acquireShared)))
|
2015-02-02 04:57:53 +01:00
|
|
|
|
|
|
|
def requiresProbes(cmd: UInt, meta: ManagerMetadata) = !dir.none(meta.sharers)
|
2012-10-24 03:01:53 +02:00
|
|
|
}
|