cleanups supporting uncore hierarchy
This commit is contained in:
parent
3e634aef1d
commit
bbf8010230
@ -1,10 +1,6 @@
|
||||
package uncore
|
||||
import Chisel._
|
||||
|
||||
abstract trait CoherenceAgentRole
|
||||
abstract trait ClientCoherenceAgent extends CoherenceAgentRole
|
||||
abstract trait MasterCoherenceAgent extends CoherenceAgentRole
|
||||
|
||||
abstract class CoherencePolicy {
|
||||
def nClientStates: Int
|
||||
def nMasterStates: Int
|
||||
@ -31,41 +27,42 @@ abstract class CoherencePolicy {
|
||||
def newStateOnWriteback(): UInt
|
||||
def newStateOnFlush(): UInt
|
||||
def newStateOnGrant(incoming: Grant, outstanding: Acquire): UInt
|
||||
def newStateOnProbe(incoming: Probe, state: UInt): Bits
|
||||
def newStateOnProbe(incoming: Probe, state: UInt): UInt
|
||||
|
||||
def getAcquireTypeOnPrimaryMiss(cmd: UInt, state: UInt): UInt
|
||||
def getAcquireTypeOnSecondaryMiss(cmd: UInt, state: UInt, outstanding: Acquire): UInt
|
||||
def getProbeType(a_type: UInt, global_state: UInt): UInt
|
||||
def getReleaseTypeOnCacheControl(cmd: UInt): Bits
|
||||
def getReleaseTypeOnVoluntaryWriteback(): Bits
|
||||
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): Bits
|
||||
def getGrantType(a_type: UInt, count: UInt): Bits
|
||||
def getGrantType(rel: Release, count: UInt): Bits
|
||||
def getReleaseTypeOnCacheControl(cmd: UInt): UInt
|
||||
def getReleaseTypeOnVoluntaryWriteback(): UInt
|
||||
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): UInt
|
||||
def getGrantType(a_type: UInt, count: UInt): UInt
|
||||
def getGrantType(rel: Release, count: UInt): UInt
|
||||
|
||||
def messageHasData (rel: SourcedMessage): Bool
|
||||
def messageUpdatesDataArray (reply: Grant): Bool
|
||||
def messageIsUncached(acq: Acquire): Bool
|
||||
|
||||
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool
|
||||
def isCoherenceConflict(addr1: UInt, addr2: UInt): Bool
|
||||
def isVoluntary(rel: Release): Bool
|
||||
def isVoluntary(gnt: Grant): Bool
|
||||
def needsOuterRead(a_type: UInt, global_state: UInt): Bool
|
||||
def needsOuterWrite(a_type: UInt, global_state: UInt): Bool
|
||||
def needsAckReply(a_type: UInt, global_state: UInt): Bool
|
||||
def needsSelfProbe(acq: Acquire): Bool
|
||||
def requiresAck(grant: Grant): Bool
|
||||
def requiresAck(release: Release): Bool
|
||||
def requiresOuterAcquire(a_type: UInt, global_state: UInt): Bool
|
||||
def requiresDatalessGrant(a_type: UInt, global_state: UInt): Bool
|
||||
def requiresSelfProbe(a_type: UInt): Bool
|
||||
def requiresAckForGrant(g_type: UInt): Bool
|
||||
def requiresAckForRelease(r_type: UInt): Bool
|
||||
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool
|
||||
|
||||
def uSIntListContains(list: List[UInt], elem: UInt): Bool = list.map(elem === _).reduceLeft(_||_)
|
||||
def uIntListContains(list: List[UInt], elem: UInt): Bool = list.map(elem === _).reduceLeft(_||_)
|
||||
}
|
||||
|
||||
trait UncachedTransactions {
|
||||
def getUncachedReadAcquireType: Bits
|
||||
def getUncachedWriteAcquireType: Bits
|
||||
def getUncachedReadWordAcquireType: Bits
|
||||
def getUncachedWriteWordAcquireType: Bits
|
||||
def getUncachedAtomicAcquireType: Bits
|
||||
def getUncachedReadAcquireType: UInt
|
||||
def getUncachedWriteAcquireType: UInt
|
||||
def getUncachedReadWordAcquireType: UInt
|
||||
def getUncachedWriteWordAcquireType: UInt
|
||||
def getUncachedAtomicAcquireType: UInt
|
||||
def isUncachedReadTransaction(acq: Acquire): Bool
|
||||
}
|
||||
|
||||
@ -73,18 +70,19 @@ abstract class CoherencePolicyWithUncached extends CoherencePolicy with Uncached
|
||||
|
||||
abstract class IncoherentPolicy extends CoherencePolicy {
|
||||
// UNIMPLEMENTED
|
||||
def newStateOnProbe(incoming: Probe, state: UInt): Bits = state
|
||||
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): Bits = Bits(0)
|
||||
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = Bool(false)
|
||||
def getGrantType(a_type: UInt, count: UInt): Bits = Bits(0)
|
||||
def getGrantType(rel: Release, count: UInt): Bits = Bits(0)
|
||||
def newStateOnProbe(incoming: Probe, state: UInt): UInt = state
|
||||
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): UInt = UInt(0)
|
||||
def isCoherenceConflict(addr1: UInt, addr2: UInt): Bool = Bool(false)
|
||||
def getGrantType(a_type: UInt, count: UInt): UInt = UInt(0)
|
||||
def getGrantType(rel: Release, count: UInt): UInt = UInt(0)
|
||||
def getProbeType(a_type: UInt, global_state: UInt): UInt = UInt(0)
|
||||
def needsOuterRead(a_type: UInt, global_state: UInt): Bool = Bool(false)
|
||||
def needsOuterWrite(a_type: UInt, global_state: UInt): Bool = Bool(false)
|
||||
def needsAckReply(a_type: UInt, global_state: UInt): Bool = Bool(false)
|
||||
def needsSelfProbe(acq: Acquire) = Bool(false)
|
||||
def requiresAck(grant: Grant) = Bool(true)
|
||||
def requiresAck(release: Release) = Bool(false)
|
||||
def requiresOuterAcquire(a_type: UInt, global_state: UInt): Bool = Bool(false)
|
||||
def requiresDatalessGrant(a_type: UInt, global_state: UInt): Bool = Bool(false)
|
||||
def requiresSelfProbe(a_type: UInt) = Bool(false)
|
||||
def requiresAckForGrant(g_type: UInt) = Bool(true)
|
||||
def requiresAckForRelease(r_type: UInt) = Bool(false)
|
||||
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = Bool(false)
|
||||
|
||||
}
|
||||
@ -135,17 +133,17 @@ class ThreeStateIncoherence extends IncoherentPolicy {
|
||||
def getAcquireTypeOnSecondaryMiss(cmd: UInt, state: UInt, outstanding: Acquire): UInt = {
|
||||
Mux(isWriteIntent(cmd), acquireReadDirty, outstanding.a_type)
|
||||
}
|
||||
def getReleaseTypeOnCacheControl(cmd: UInt): Bits = releaseVoluntaryInvalidateData // TODO
|
||||
def getReleaseTypeOnVoluntaryWriteback(): Bits = releaseVoluntaryInvalidateData
|
||||
def getReleaseTypeOnCacheControl(cmd: UInt): UInt = releaseVoluntaryInvalidateData // TODO
|
||||
def getReleaseTypeOnVoluntaryWriteback(): UInt = releaseVoluntaryInvalidateData
|
||||
|
||||
def messageHasData( msg: SourcedMessage ) = msg match {
|
||||
case acq: Acquire => uSIntListContains(hasDataAcquireTypeList, acq.a_type)
|
||||
case grant: Grant => uSIntListContains(hasDataGrantTypeList, grant.g_type)
|
||||
case acq: Acquire => uIntListContains(hasDataAcquireTypeList, acq.a_type)
|
||||
case grant: Grant => uIntListContains(hasDataGrantTypeList, grant.g_type)
|
||||
case rel: Release => Bool(false)
|
||||
case _ => Bool(false)
|
||||
}
|
||||
def messageUpdatesDataArray (reply: Grant) = (reply.g_type === grantData)
|
||||
def messageIsUncached(acq: Acquire): Bool = uSIntListContains(uncachedAcquireTypeList, acq.a_type)
|
||||
def messageIsUncached(acq: Acquire): Bool = uIntListContains(uncachedAcquireTypeList, acq.a_type)
|
||||
}
|
||||
|
||||
class MICoherence extends CoherencePolicyWithUncached {
|
||||
@ -202,7 +200,7 @@ class MICoherence extends CoherencePolicyWithUncached {
|
||||
grantAtomicUncached -> tileInvalid
|
||||
))
|
||||
}
|
||||
def newStateOnProbe(incoming: Probe, state: UInt): Bits = {
|
||||
def newStateOnProbe(incoming: Probe, state: UInt): UInt = {
|
||||
MuxLookup(incoming.p_type, state, Array(
|
||||
probeInvalidate -> tileInvalid,
|
||||
probeCopy -> state
|
||||
@ -220,9 +218,9 @@ class MICoherence extends CoherencePolicyWithUncached {
|
||||
|
||||
def getAcquireTypeOnPrimaryMiss(cmd: UInt, state: UInt): UInt = acquireReadExclusive
|
||||
def getAcquireTypeOnSecondaryMiss(cmd: UInt, state: UInt, outstanding: Acquire): UInt = acquireReadExclusive
|
||||
def getReleaseTypeOnCacheControl(cmd: UInt): Bits = releaseVoluntaryInvalidateData // TODO
|
||||
def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV)
|
||||
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): Bits = {
|
||||
def getReleaseTypeOnCacheControl(cmd: UInt): UInt = releaseVoluntaryInvalidateData // TODO
|
||||
def getReleaseTypeOnVoluntaryWriteback(): UInt = getReleaseTypeOnCacheControl(M_INV)
|
||||
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): UInt = {
|
||||
val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array(
|
||||
probeInvalidate -> releaseInvalidateData,
|
||||
probeCopy -> releaseCopyData
|
||||
@ -235,19 +233,19 @@ class MICoherence extends CoherencePolicyWithUncached {
|
||||
}
|
||||
|
||||
def messageHasData(msg: SourcedMessage) = msg match {
|
||||
case acq: Acquire => uSIntListContains(hasDataAcquireTypeList, acq.a_type)
|
||||
case grant: Grant => uSIntListContains(hasDataGrantTypeList, grant.g_type)
|
||||
case rel: Release => uSIntListContains(hasDataReleaseTypeList, rel.r_type)
|
||||
case acq: Acquire => uIntListContains(hasDataAcquireTypeList, acq.a_type)
|
||||
case grant: Grant => uIntListContains(hasDataGrantTypeList, grant.g_type)
|
||||
case rel: Release => uIntListContains(hasDataReleaseTypeList, rel.r_type)
|
||||
case _ => Bool(false)
|
||||
}
|
||||
def messageUpdatesDataArray (reply: Grant): Bool = {
|
||||
(reply.g_type === grantReadExclusive)
|
||||
}
|
||||
def messageIsUncached(acq: Acquire): Bool = uSIntListContains(uncachedAcquireTypeList, acq.a_type)
|
||||
def messageIsUncached(acq: Acquire): Bool = uIntListContains(uncachedAcquireTypeList, acq.a_type)
|
||||
|
||||
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2)
|
||||
def isCoherenceConflict(addr1: UInt, addr2: UInt): Bool = (addr1 === addr2)
|
||||
|
||||
def getGrantType(a_type: UInt, count: UInt): Bits = {
|
||||
def getGrantType(a_type: UInt, count: UInt): UInt = {
|
||||
MuxLookup(a_type, grantReadUncached, Array(
|
||||
acquireReadExclusive -> grantReadExclusive,
|
||||
acquireReadUncached -> grantReadUncached,
|
||||
@ -258,7 +256,7 @@ class MICoherence extends CoherencePolicyWithUncached {
|
||||
))
|
||||
}
|
||||
|
||||
def getGrantType(rel: Release, count: UInt): Bits = {
|
||||
def getGrantType(rel: Release, count: UInt): UInt = {
|
||||
MuxLookup(rel.r_type, grantReadUncached, Array(
|
||||
releaseVoluntaryInvalidateData -> grantVoluntaryAck
|
||||
))
|
||||
@ -281,12 +279,15 @@ class MICoherence extends CoherencePolicyWithUncached {
|
||||
def needsOuterWrite(a_type: UInt, global_state: UInt): Bool = {
|
||||
(a_type === acquireWriteUncached)
|
||||
}
|
||||
def needsAckReply(a_type: UInt, global_state: UInt): Bool = {
|
||||
def requiresOuterAcquire(a_type: UInt, global_state: UInt): Bool = {
|
||||
needsOuterRead(a_type, global_state) || needsOuterWrite(a_type, global_state)
|
||||
}
|
||||
def requiresDatalessGrant(a_type: UInt, global_state: UInt): 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 requiresAckForGrant(g_type: UInt) = g_type != grantVoluntaryAck
|
||||
def requiresAckForRelease(r_type: UInt) = Bool(false)
|
||||
def requiresSelfProbe(a_type: UInt) = Bool(false)
|
||||
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData)
|
||||
}
|
||||
|
||||
@ -350,7 +351,7 @@ class MEICoherence extends CoherencePolicyWithUncached {
|
||||
grantAtomicUncached -> tileInvalid
|
||||
))
|
||||
}
|
||||
def newStateOnProbe(incoming: Probe, state: UInt): Bits = {
|
||||
def newStateOnProbe(incoming: Probe, state: UInt): UInt = {
|
||||
MuxLookup(incoming.p_type, state, Array(
|
||||
probeInvalidate -> tileInvalid,
|
||||
probeDowngrade -> tileExclusiveClean,
|
||||
@ -373,9 +374,9 @@ class MEICoherence extends CoherencePolicyWithUncached {
|
||||
def getAcquireTypeOnSecondaryMiss(cmd: UInt, state: UInt, outstanding: Acquire): UInt = {
|
||||
Mux(isWriteIntent(cmd), acquireReadExclusiveDirty, outstanding.a_type)
|
||||
}
|
||||
def getReleaseTypeOnCacheControl(cmd: UInt): Bits = releaseVoluntaryInvalidateData // TODO
|
||||
def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV)
|
||||
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): Bits = {
|
||||
def getReleaseTypeOnCacheControl(cmd: UInt): UInt = releaseVoluntaryInvalidateData // TODO
|
||||
def getReleaseTypeOnVoluntaryWriteback(): UInt = getReleaseTypeOnCacheControl(M_INV)
|
||||
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): UInt = {
|
||||
val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array(
|
||||
probeInvalidate -> releaseInvalidateData,
|
||||
probeDowngrade -> releaseDowngradeData,
|
||||
@ -390,19 +391,19 @@ class MEICoherence extends CoherencePolicyWithUncached {
|
||||
}
|
||||
|
||||
def messageHasData(msg: SourcedMessage) = msg match {
|
||||
case acq: Acquire => uSIntListContains(hasDataAcquireTypeList, acq.a_type)
|
||||
case grant: Grant => uSIntListContains(hasDataGrantTypeList, grant.g_type)
|
||||
case rel: Release => uSIntListContains(hasDataReleaseTypeList, rel.r_type)
|
||||
case acq: Acquire => uIntListContains(hasDataAcquireTypeList, acq.a_type)
|
||||
case grant: Grant => uIntListContains(hasDataGrantTypeList, grant.g_type)
|
||||
case rel: Release => uIntListContains(hasDataReleaseTypeList, rel.r_type)
|
||||
case _ => Bool(false)
|
||||
}
|
||||
def messageUpdatesDataArray (reply: Grant): Bool = {
|
||||
(reply.g_type === grantReadExclusive)
|
||||
}
|
||||
def messageIsUncached(acq: Acquire): Bool = uSIntListContains(uncachedAcquireTypeList, acq.a_type)
|
||||
def messageIsUncached(acq: Acquire): Bool = uIntListContains(uncachedAcquireTypeList, acq.a_type)
|
||||
|
||||
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2)
|
||||
def isCoherenceConflict(addr1: UInt, addr2: UInt): Bool = (addr1 === addr2)
|
||||
|
||||
def getGrantType(a_type: UInt, count: UInt): Bits = {
|
||||
def getGrantType(a_type: UInt, count: UInt): UInt = {
|
||||
MuxLookup(a_type, grantReadUncached, Array(
|
||||
acquireReadExclusiveClean -> grantReadExclusive,
|
||||
acquireReadExclusiveDirty -> grantReadExclusive,
|
||||
@ -413,7 +414,7 @@ class MEICoherence extends CoherencePolicyWithUncached {
|
||||
acquireAtomicUncached -> grantAtomicUncached
|
||||
))
|
||||
}
|
||||
def getGrantType(rel: Release, count: UInt): Bits = {
|
||||
def getGrantType(rel: Release, count: UInt): UInt = {
|
||||
MuxLookup(rel.r_type, grantReadUncached, Array(
|
||||
releaseVoluntaryInvalidateData -> grantVoluntaryAck
|
||||
))
|
||||
@ -438,12 +439,15 @@ class MEICoherence extends CoherencePolicyWithUncached {
|
||||
def needsOuterWrite(a_type: UInt, global_state: UInt): Bool = {
|
||||
(a_type === acquireWriteUncached)
|
||||
}
|
||||
def needsAckReply(a_type: UInt, global_state: UInt): Bool = {
|
||||
def requiresOuterAcquire(a_type: UInt, global_state: UInt): Bool = {
|
||||
needsOuterRead(a_type, global_state) || needsOuterWrite(a_type, global_state)
|
||||
}
|
||||
def requiresDatalessGrant(a_type: UInt, global_state: UInt): 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 requiresAckForGrant(g_type: UInt) = g_type != grantVoluntaryAck
|
||||
def requiresAckForRelease(r_type: UInt) = Bool(false)
|
||||
def requiresSelfProbe(a_type: UInt) = Bool(false)
|
||||
|
||||
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData)
|
||||
}
|
||||
@ -514,7 +518,7 @@ class MSICoherence extends CoherencePolicyWithUncached {
|
||||
grantAtomicUncached -> tileInvalid
|
||||
))
|
||||
}
|
||||
def newStateOnProbe(incoming: Probe, state: UInt): Bits = {
|
||||
def newStateOnProbe(incoming: Probe, state: UInt): UInt = {
|
||||
MuxLookup(incoming.p_type, state, Array(
|
||||
probeInvalidate -> tileInvalid,
|
||||
probeDowngrade -> tileShared,
|
||||
@ -537,9 +541,9 @@ class MSICoherence extends CoherencePolicyWithUncached {
|
||||
def getAcquireTypeOnSecondaryMiss(cmd: UInt, state: UInt, outstanding: Acquire): UInt = {
|
||||
Mux(isWriteIntent(cmd), acquireReadExclusive, outstanding.a_type)
|
||||
}
|
||||
def getReleaseTypeOnCacheControl(cmd: UInt): Bits = releaseVoluntaryInvalidateData // TODO
|
||||
def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV)
|
||||
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): Bits = {
|
||||
def getReleaseTypeOnCacheControl(cmd: UInt): UInt = releaseVoluntaryInvalidateData // TODO
|
||||
def getReleaseTypeOnVoluntaryWriteback(): UInt = getReleaseTypeOnCacheControl(M_INV)
|
||||
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): UInt = {
|
||||
val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array(
|
||||
probeInvalidate -> releaseInvalidateData,
|
||||
probeDowngrade -> releaseDowngradeData,
|
||||
@ -554,19 +558,19 @@ class MSICoherence extends CoherencePolicyWithUncached {
|
||||
}
|
||||
|
||||
def messageHasData(msg: SourcedMessage) = msg match {
|
||||
case acq: Acquire => uSIntListContains(hasDataAcquireTypeList, acq.a_type)
|
||||
case grant: Grant => uSIntListContains(hasDataGrantTypeList, grant.g_type)
|
||||
case rel: Release => uSIntListContains(hasDataReleaseTypeList, rel.r_type)
|
||||
case acq: Acquire => uIntListContains(hasDataAcquireTypeList, acq.a_type)
|
||||
case grant: Grant => uIntListContains(hasDataGrantTypeList, grant.g_type)
|
||||
case rel: Release => uIntListContains(hasDataReleaseTypeList, rel.r_type)
|
||||
case _ => Bool(false)
|
||||
}
|
||||
def messageUpdatesDataArray (reply: Grant): Bool = {
|
||||
(reply.g_type === grantReadShared || reply.g_type === grantReadExclusive)
|
||||
}
|
||||
def messageIsUncached(acq: Acquire): Bool = uSIntListContains(uncachedAcquireTypeList, acq.a_type)
|
||||
def messageIsUncached(acq: Acquire): Bool = uIntListContains(uncachedAcquireTypeList, acq.a_type)
|
||||
|
||||
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2)
|
||||
def isCoherenceConflict(addr1: UInt, addr2: UInt): Bool = (addr1 === addr2)
|
||||
|
||||
def getGrantType(a_type: UInt, count: UInt): Bits = {
|
||||
def getGrantType(a_type: UInt, count: UInt): UInt = {
|
||||
MuxLookup(a_type, grantReadUncached, Array(
|
||||
acquireReadShared -> Mux(count > UInt(0), grantReadShared, grantReadExclusive),
|
||||
acquireReadExclusive -> grantReadExclusive,
|
||||
@ -577,7 +581,7 @@ class MSICoherence extends CoherencePolicyWithUncached {
|
||||
acquireAtomicUncached -> grantAtomicUncached
|
||||
))
|
||||
}
|
||||
def getGrantType(rel: Release, count: UInt): Bits = {
|
||||
def getGrantType(rel: Release, count: UInt): UInt = {
|
||||
MuxLookup(rel.r_type, grantReadUncached, Array(
|
||||
releaseVoluntaryInvalidateData -> grantVoluntaryAck
|
||||
))
|
||||
@ -599,12 +603,15 @@ class MSICoherence extends CoherencePolicyWithUncached {
|
||||
def needsOuterWrite(a_type: UInt, global_state: UInt): Bool = {
|
||||
(a_type === acquireWriteUncached)
|
||||
}
|
||||
def needsAckReply(a_type: UInt, global_state: UInt): Bool = {
|
||||
def requiresOuterAcquire(a_type: UInt, global_state: UInt): Bool = {
|
||||
needsOuterRead(a_type, global_state) || needsOuterWrite(a_type, global_state)
|
||||
}
|
||||
def requiresDatalessGrant(a_type: UInt, global_state: UInt): 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 requiresAckForGrant(g_type: UInt) = g_type != grantVoluntaryAck
|
||||
def requiresAckForRelease(r_type: UInt) = Bool(false)
|
||||
def requiresSelfProbe(a_type: UInt) = Bool(false)
|
||||
|
||||
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData)
|
||||
}
|
||||
@ -675,7 +682,7 @@ class MESICoherence extends CoherencePolicyWithUncached {
|
||||
grantAtomicUncached -> tileInvalid
|
||||
))
|
||||
}
|
||||
def newStateOnProbe(incoming: Probe, state: UInt): Bits = {
|
||||
def newStateOnProbe(incoming: Probe, state: UInt): UInt = {
|
||||
MuxLookup(incoming.p_type, state, Array(
|
||||
probeInvalidate -> tileInvalid,
|
||||
probeDowngrade -> tileShared,
|
||||
@ -698,9 +705,9 @@ class MESICoherence extends CoherencePolicyWithUncached {
|
||||
def getAcquireTypeOnSecondaryMiss(cmd: UInt, state: UInt, outstanding: Acquire): UInt = {
|
||||
Mux(isWriteIntent(cmd), acquireReadExclusive, outstanding.a_type)
|
||||
}
|
||||
def getReleaseTypeOnCacheControl(cmd: UInt): Bits = releaseVoluntaryInvalidateData // TODO
|
||||
def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV)
|
||||
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): Bits = {
|
||||
def getReleaseTypeOnCacheControl(cmd: UInt): UInt = releaseVoluntaryInvalidateData // TODO
|
||||
def getReleaseTypeOnVoluntaryWriteback(): UInt = getReleaseTypeOnCacheControl(M_INV)
|
||||
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): UInt = {
|
||||
val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array(
|
||||
probeInvalidate -> releaseInvalidateData,
|
||||
probeDowngrade -> releaseDowngradeData,
|
||||
@ -715,19 +722,19 @@ class MESICoherence extends CoherencePolicyWithUncached {
|
||||
}
|
||||
|
||||
def messageHasData(msg: SourcedMessage) = msg match {
|
||||
case acq: Acquire => uSIntListContains(hasDataAcquireTypeList, acq.a_type)
|
||||
case grant: Grant => uSIntListContains(hasDataGrantTypeList, grant.g_type)
|
||||
case rel: Release => uSIntListContains(hasDataReleaseTypeList, rel.r_type)
|
||||
case acq: Acquire => uIntListContains(hasDataAcquireTypeList, acq.a_type)
|
||||
case grant: Grant => uIntListContains(hasDataGrantTypeList, grant.g_type)
|
||||
case rel: Release => uIntListContains(hasDataReleaseTypeList, rel.r_type)
|
||||
case _ => Bool(false)
|
||||
}
|
||||
def messageUpdatesDataArray (reply: Grant): Bool = {
|
||||
(reply.g_type === grantReadShared || reply.g_type === grantReadExclusive)
|
||||
}
|
||||
def messageIsUncached(acq: Acquire): Bool = uSIntListContains(uncachedAcquireTypeList, acq.a_type)
|
||||
def messageIsUncached(acq: Acquire): Bool = uIntListContains(uncachedAcquireTypeList, acq.a_type)
|
||||
|
||||
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2)
|
||||
def isCoherenceConflict(addr1: UInt, addr2: UInt): Bool = (addr1 === addr2)
|
||||
|
||||
def getGrantType(a_type: UInt, count: UInt): Bits = {
|
||||
def getGrantType(a_type: UInt, count: UInt): UInt = {
|
||||
MuxLookup(a_type, grantReadUncached, Array(
|
||||
acquireReadShared -> Mux(count > UInt(0), grantReadShared, grantReadExclusive),
|
||||
acquireReadExclusive -> grantReadExclusive,
|
||||
@ -738,7 +745,7 @@ class MESICoherence extends CoherencePolicyWithUncached {
|
||||
acquireAtomicUncached -> grantAtomicUncached
|
||||
))
|
||||
}
|
||||
def getGrantType(rel: Release, count: UInt): Bits = {
|
||||
def getGrantType(rel: Release, count: UInt): UInt = {
|
||||
MuxLookup(rel.r_type, grantReadUncached, Array(
|
||||
releaseVoluntaryInvalidateData -> grantVoluntaryAck
|
||||
))
|
||||
@ -763,13 +770,16 @@ class MESICoherence extends CoherencePolicyWithUncached {
|
||||
def needsOuterWrite(a_type: UInt, global_state: UInt): Bool = {
|
||||
(a_type === acquireWriteUncached)
|
||||
}
|
||||
def needsAckReply(a_type: UInt, global_state: UInt): Bool = {
|
||||
def requiresOuterAcquire(a_type: UInt, global_state: UInt): Bool = {
|
||||
needsOuterRead(a_type, global_state) || needsOuterWrite(a_type, global_state)
|
||||
}
|
||||
def requiresDatalessGrant(a_type: UInt, global_state: UInt): 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 requiresAckForGrant(g_type: UInt) = g_type != grantVoluntaryAck
|
||||
def requiresAckForRelease(r_type: UInt) = Bool(false)
|
||||
def requiresSelfProbe(a_type: UInt) = Bool(false)
|
||||
|
||||
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData)
|
||||
}
|
||||
@ -795,7 +805,7 @@ class MigratoryCoherence extends CoherencePolicyWithUncached {
|
||||
val hasDataReleaseTypeList = List(releaseVoluntaryInvalidateData, releaseInvalidateData, releaseDowngradeData, releaseCopyData, releaseInvalidateDataMigratory, releaseDowngradeDataMigratory)
|
||||
|
||||
def isHit (cmd: UInt, state: UInt): Bool = {
|
||||
Mux(isWriteIntent(cmd), uSIntListContains(List(tileExclusiveClean, tileExclusiveDirty, tileMigratoryClean, tileMigratoryDirty), state), (state != tileInvalid))
|
||||
Mux(isWriteIntent(cmd), uIntListContains(List(tileExclusiveClean, tileExclusiveDirty, tileMigratoryClean, tileMigratoryDirty), state), (state != tileInvalid))
|
||||
}
|
||||
def isValid (state: UInt): Bool = {
|
||||
state != tileInvalid
|
||||
@ -807,8 +817,8 @@ class MigratoryCoherence extends CoherencePolicyWithUncached {
|
||||
}
|
||||
def needsTransactionOnCacheControl(cmd: UInt, state: UInt): Bool = {
|
||||
MuxLookup(cmd, (state === tileExclusiveDirty), Array(
|
||||
M_INV -> uSIntListContains(List(tileExclusiveDirty,tileMigratoryDirty),state),
|
||||
M_CLN -> uSIntListContains(List(tileExclusiveDirty,tileMigratoryDirty),state)
|
||||
M_INV -> uIntListContains(List(tileExclusiveDirty,tileMigratoryDirty),state),
|
||||
M_CLN -> uIntListContains(List(tileExclusiveDirty,tileMigratoryDirty),state)
|
||||
))
|
||||
}
|
||||
def needsWriteback (state: UInt): Bool = {
|
||||
@ -846,7 +856,7 @@ class MigratoryCoherence extends CoherencePolicyWithUncached {
|
||||
acquireReadShared -> tileMigratoryClean))
|
||||
))
|
||||
}
|
||||
def newStateOnProbe(incoming: Probe, state: UInt): Bits = {
|
||||
def newStateOnProbe(incoming: Probe, state: UInt): UInt = {
|
||||
MuxLookup(incoming.p_type, state, Array(
|
||||
probeInvalidate -> tileInvalid,
|
||||
probeInvalidateOthers -> tileInvalid,
|
||||
@ -875,11 +885,11 @@ class MigratoryCoherence extends CoherencePolicyWithUncached {
|
||||
def getAcquireTypeOnSecondaryMiss(cmd: UInt, state: UInt, outstanding: Acquire): UInt = {
|
||||
Mux(isWriteIntent(cmd), Mux(state === tileInvalid, acquireReadExclusive, acquireInvalidateOthers), outstanding.a_type)
|
||||
}
|
||||
def getReleaseTypeOnCacheControl(cmd: UInt): Bits = releaseVoluntaryInvalidateData // TODO
|
||||
def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV)
|
||||
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): Bits = {
|
||||
def getReleaseTypeOnCacheControl(cmd: UInt): UInt = releaseVoluntaryInvalidateData // TODO
|
||||
def getReleaseTypeOnVoluntaryWriteback(): UInt = getReleaseTypeOnCacheControl(M_INV)
|
||||
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): UInt = {
|
||||
val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array(
|
||||
probeInvalidate -> Mux(uSIntListContains(List(tileExclusiveDirty, tileMigratoryDirty), state),
|
||||
probeInvalidate -> Mux(uIntListContains(List(tileExclusiveDirty, tileMigratoryDirty), state),
|
||||
releaseInvalidateDataMigratory, releaseInvalidateData),
|
||||
probeDowngrade -> Mux(state === tileMigratoryDirty, releaseDowngradeDataMigratory, releaseDowngradeData),
|
||||
probeCopy -> releaseCopyData
|
||||
@ -894,19 +904,19 @@ class MigratoryCoherence extends CoherencePolicyWithUncached {
|
||||
}
|
||||
|
||||
def messageHasData(msg: SourcedMessage) = msg match {
|
||||
case acq: Acquire => uSIntListContains(hasDataAcquireTypeList, acq.a_type)
|
||||
case grant: Grant => uSIntListContains(hasDataGrantTypeList, grant.g_type)
|
||||
case rel: Release => uSIntListContains(hasDataReleaseTypeList, rel.r_type)
|
||||
case acq: Acquire => uIntListContains(hasDataAcquireTypeList, acq.a_type)
|
||||
case grant: Grant => uIntListContains(hasDataGrantTypeList, grant.g_type)
|
||||
case rel: Release => uIntListContains(hasDataReleaseTypeList, rel.r_type)
|
||||
case _ => Bool(false)
|
||||
}
|
||||
def messageUpdatesDataArray (reply: Grant): Bool = {
|
||||
uSIntListContains(List(grantReadShared, grantReadExclusive, grantReadMigratory), reply.g_type)
|
||||
uIntListContains(List(grantReadShared, grantReadExclusive, grantReadMigratory), reply.g_type)
|
||||
}
|
||||
def messageIsUncached(acq: Acquire): Bool = uSIntListContains(uncachedAcquireTypeList, acq.a_type)
|
||||
def messageIsUncached(acq: Acquire): Bool = uIntListContains(uncachedAcquireTypeList, acq.a_type)
|
||||
|
||||
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2)
|
||||
def isCoherenceConflict(addr1: UInt, addr2: UInt): Bool = (addr1 === addr2)
|
||||
|
||||
def getGrantType(a_type: UInt, count: UInt): Bits = {
|
||||
def getGrantType(a_type: UInt, count: UInt): UInt = {
|
||||
MuxLookup(a_type, grantReadUncached, Array(
|
||||
acquireReadShared -> Mux(count > UInt(0), grantReadShared, grantReadExclusive), //TODO: what is count? Depend on release.p_type???
|
||||
acquireReadExclusive -> grantReadExclusive,
|
||||
@ -918,7 +928,7 @@ class MigratoryCoherence extends CoherencePolicyWithUncached {
|
||||
acquireInvalidateOthers -> grantReadExclusiveAck //TODO: add this to MESI?
|
||||
))
|
||||
}
|
||||
def getGrantType(rel: Release, count: UInt): Bits = {
|
||||
def getGrantType(rel: Release, count: UInt): UInt = {
|
||||
MuxLookup(rel.r_type, grantReadUncached, Array(
|
||||
releaseVoluntaryInvalidateData -> grantVoluntaryAck
|
||||
))
|
||||
@ -944,12 +954,16 @@ class MigratoryCoherence extends CoherencePolicyWithUncached {
|
||||
def needsOuterWrite(a_type: UInt, global_state: UInt): Bool = {
|
||||
(a_type === acquireWriteUncached || a_type === acquireWriteWordUncached || a_type === acquireAtomicUncached)
|
||||
}
|
||||
def needsAckReply(a_type: UInt, global_state: UInt): Bool = {
|
||||
def requiresOuterAcquire(a_type: UInt, global_state: UInt): Bool = {
|
||||
needsOuterRead(a_type, global_state) || needsOuterWrite(a_type, global_state)
|
||||
}
|
||||
|
||||
def requiresDatalessGrant(a_type: UInt, global_state: UInt): Bool = {
|
||||
(a_type === acquireWriteUncached || a_type === acquireWriteWordUncached ||a_type === acquireInvalidateOthers)
|
||||
}
|
||||
def requiresAck(grant: Grant) = grant.g_type != grantVoluntaryAck
|
||||
def requiresAck(release: Release) = Bool(false)
|
||||
def needsSelfProbe(acq: Acquire) = Bool(false)
|
||||
def requiresAckForGrant(g_type: UInt) = g_type != grantVoluntaryAck
|
||||
def requiresAckForRelease(r_type: UInt) = Bool(false)
|
||||
def requiresSelfProbe(a_type: UInt) = Bool(false)
|
||||
|
||||
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData)
|
||||
}
|
||||
|
@ -6,14 +6,15 @@ import scala.math.max
|
||||
|
||||
object MemoryOpConstants extends MemoryOpConstants
|
||||
trait MemoryOpConstants {
|
||||
val MT_X = Bits("b???", 3);
|
||||
val MT_B = Bits("b000", 3);
|
||||
val MT_H = Bits("b001", 3);
|
||||
val MT_W = Bits("b010", 3);
|
||||
val MT_D = Bits("b011", 3);
|
||||
val MT_BU = Bits("b100", 3);
|
||||
val MT_HU = Bits("b101", 3);
|
||||
val MT_WU = Bits("b110", 3);
|
||||
val MT_SZ = 3
|
||||
val MT_X = Bits("b???")
|
||||
val MT_B = Bits("b000")
|
||||
val MT_H = Bits("b001")
|
||||
val MT_W = Bits("b010")
|
||||
val MT_D = Bits("b011")
|
||||
val MT_BU = Bits("b100")
|
||||
val MT_HU = Bits("b101")
|
||||
val MT_WU = Bits("b110")
|
||||
|
||||
val M_SZ = 5
|
||||
val M_X = Bits("b?????");
|
||||
|
@ -41,7 +41,7 @@ class SCRIO(n: Int) extends Bundle
|
||||
val wdata = Bits(OUTPUT, 64)
|
||||
}
|
||||
|
||||
class HTIF(w: Int, pcr_RESET: Int, nSCR: Int)(implicit conf: TileLinkConfiguration) extends Module with ClientCoherenceAgent
|
||||
class HTIF(w: Int, pcr_RESET: Int, nSCR: Int)(implicit conf: TileLinkConfiguration) extends Module
|
||||
{
|
||||
implicit val (ln, co) = (conf.ln, conf.co)
|
||||
val nTiles = ln.nClients-1 // This HTIF is itself a TileLink client
|
||||
@ -120,7 +120,7 @@ class HTIF(w: Int, pcr_RESET: Int, nSCR: Int)(implicit conf: TileLinkConfigurati
|
||||
mem_acked := Bool(true)
|
||||
mem_gxid := io.mem.grant.bits.payload.master_xact_id
|
||||
mem_gsrc := io.mem.grant.bits.header.src
|
||||
mem_needs_ack := conf.co.requiresAck(io.mem.grant.bits.payload)
|
||||
mem_needs_ack := conf.co.requiresAckForGrant(io.mem.grant.bits.payload.g_type)
|
||||
}
|
||||
io.mem.grant.ready := Bool(true)
|
||||
|
||||
|
@ -68,11 +68,13 @@ class PairedLockingRRArbiter[M <: Data, D <: Data](mType: M, dType: D, n: Int, c
|
||||
when (io.out.meta.fire()) { last_grant := meta_chosen }
|
||||
}
|
||||
|
||||
class PairedCrossbar[M <: Data, D <: Data](mType: M, dType: D, count: Int, needsLock: Option[PhysicalNetworkIO[M] => Bool] = None)(implicit conf: PhysicalNetworkConfiguration) extends PhysicalNetwork(conf) {
|
||||
val io = new Bundle {
|
||||
class PairedCrossbarIO[M <: Data, D <: Data](mType: M, dType: D)(implicit conf: PhysicalNetworkConfiguration) extends Bundle {
|
||||
val in = Vec.fill(conf.nEndpoints){new PairedDataIO(new PhysicalNetworkIO(mType),new PhysicalNetworkIO(dType))}.flip
|
||||
val out = Vec.fill(conf.nEndpoints){new PairedDataIO(new PhysicalNetworkIO(mType),new PhysicalNetworkIO(dType))}
|
||||
}
|
||||
}
|
||||
|
||||
class PairedCrossbar[M <: Data, D <: Data](mType: M, dType: D, count: Int, needsLock: Option[PhysicalNetworkIO[M] => Bool] = None)(implicit conf: PhysicalNetworkConfiguration) extends PhysicalNetwork(conf) {
|
||||
val io = new PairedCrossbarIO(mType, dType)
|
||||
|
||||
val metaRdyVecs = List.fill(conf.nEndpoints)(Vec.fill(conf.nEndpoints){Bool()})
|
||||
val dataRdyVecs = List.fill(conf.nEndpoints)(Vec.fill(conf.nEndpoints){Bool()})
|
||||
@ -111,11 +113,12 @@ class PhysicalNetworkIO[T <: Data](dType: T)(implicit conf: PhysicalNetworkConfi
|
||||
|
||||
abstract class PhysicalNetwork(conf: PhysicalNetworkConfiguration) extends Module
|
||||
|
||||
class BasicCrossbar[T <: Data](dType: T, count: Int = 1)(implicit conf: PhysicalNetworkConfiguration) extends PhysicalNetwork(conf) {
|
||||
val io = new Bundle {
|
||||
class BasicCrossbarIO[T <: Data](dType: T)(implicit conf: PhysicalNetworkConfiguration) extends Bundle {
|
||||
val in = Vec.fill(conf.nEndpoints){Decoupled(new PhysicalNetworkIO(dType))}.flip
|
||||
val out = Vec.fill(conf.nEndpoints){Decoupled(new PhysicalNetworkIO(dType))}
|
||||
}
|
||||
}
|
||||
class BasicCrossbar[T <: Data](dType: T, count: Int = 1)(implicit conf: PhysicalNetworkConfiguration) extends PhysicalNetwork(conf) {
|
||||
val io = new BasicCrossbarIO(dType)
|
||||
|
||||
val rdyVecs = List.fill(conf.nEndpoints)(Vec.fill(conf.nEndpoints)(Bool()))
|
||||
|
||||
@ -133,14 +136,12 @@ class BasicCrossbar[T <: Data](dType: T, count: Int = 1)(implicit conf: Physical
|
||||
}
|
||||
}
|
||||
|
||||
case class LogicalNetworkConfiguration(nEndpoints: Int, idBits: Int, nMasters: Int, nClients: Int)
|
||||
|
||||
abstract class LogicalNetwork[TileLinkType <: Bundle](endpoints: Seq[CoherenceAgentRole])(implicit conf: LogicalNetworkConfiguration) extends Module {
|
||||
override val io: Vec[TileLinkType]
|
||||
val physicalNetworks: Seq[PhysicalNetwork]
|
||||
require(endpoints.length == conf.nEndpoints)
|
||||
case class LogicalNetworkConfiguration(idBits: Int, nMasters: Int, nClients: Int) {
|
||||
val nEndpoints = nMasters + nClients
|
||||
}
|
||||
|
||||
abstract class LogicalNetwork[TileLinkType <: Bundle](implicit conf: LogicalNetworkConfiguration) extends Module
|
||||
|
||||
class LogicalHeader(implicit conf: LogicalNetworkConfiguration) extends Bundle {
|
||||
val src = UInt(width = conf.idBits)
|
||||
val dst = UInt(width = conf.idBits)
|
||||
|
@ -40,20 +40,25 @@ object Acquire
|
||||
acq.atomic_opcode := Bits(0)
|
||||
acq
|
||||
}
|
||||
def apply(a_type: Bits, addr: UInt, client_xact_id: UInt, write_mask: Bits)(implicit conf: TileLinkConfiguration): Acquire = {
|
||||
def apply(a_type: UInt, addr: UInt, client_xact_id: UInt, write_mask: Bits)(implicit conf: TileLinkConfiguration): Acquire = {
|
||||
val acq = apply(a_type, addr, client_xact_id)
|
||||
acq.write_mask := write_mask
|
||||
acq
|
||||
}
|
||||
def apply(a_type: Bits, addr: UInt, client_xact_id: UInt, subword_addr: UInt, atomic_opcode: UInt)(implicit conf: TileLinkConfiguration): Acquire = {
|
||||
def apply(a_type: UInt, addr: UInt, client_xact_id: UInt, subword_addr: UInt, atomic_opcode: UInt)(implicit conf: TileLinkConfiguration): Acquire = {
|
||||
val acq = apply(a_type, addr, client_xact_id)
|
||||
acq.subword_addr := subword_addr
|
||||
acq.atomic_opcode := atomic_opcode
|
||||
acq
|
||||
}
|
||||
def apply(a: Acquire)(implicit conf: TileLinkConfiguration): Acquire = {
|
||||
val acq = new Acquire
|
||||
acq := a
|
||||
acq
|
||||
}
|
||||
}
|
||||
class Acquire(implicit val conf: TileLinkConfiguration) extends ClientSourcedMessage with HasPhysicalAddress with HasClientTransactionId {
|
||||
val a_type = Bits(width = conf.co.acquireTypeWidth)
|
||||
val a_type = UInt(width = conf.co.acquireTypeWidth)
|
||||
val write_mask = Bits(width = ACQUIRE_WRITE_MASK_BITS)
|
||||
val subword_addr = Bits(width = ACQUIRE_SUBWORD_ADDR_BITS)
|
||||
val atomic_opcode = Bits(width = ACQUIRE_ATOMIC_OP_BITS)
|
||||
@ -61,13 +66,29 @@ class Acquire(implicit val conf: TileLinkConfiguration) extends ClientSourcedMes
|
||||
|
||||
class AcquireData(implicit val conf: TileLinkConfiguration) extends ClientSourcedMessage with HasTileLinkData
|
||||
|
||||
object Probe
|
||||
{
|
||||
def apply(p_type: UInt, addr: UInt, master_xact_id: UInt)(implicit conf: TileLinkConfiguration) = {
|
||||
val prb = new Probe
|
||||
prb.p_type := p_type
|
||||
prb.addr := addr
|
||||
prb.master_xact_id := master_xact_id
|
||||
prb
|
||||
}
|
||||
}
|
||||
class Probe(implicit val conf: TileLinkConfiguration) extends MasterSourcedMessage with HasPhysicalAddress with HasMasterTransactionId {
|
||||
val p_type = Bits(width = conf.co.probeTypeWidth)
|
||||
val p_type = UInt(width = conf.co.probeTypeWidth)
|
||||
}
|
||||
|
||||
object Release
|
||||
{
|
||||
def apply(r_type: Bits, addr: UInt, client_xact_id: UInt, master_xact_id: UInt)(implicit conf: TileLinkConfiguration) = {
|
||||
def apply(r_type: UInt, addr: UInt)(implicit conf: TileLinkConfiguration) = {
|
||||
val rel = new Release
|
||||
rel.r_type := r_type
|
||||
rel.addr := addr
|
||||
rel
|
||||
}
|
||||
def apply(r_type: UInt, addr: UInt, client_xact_id: UInt, master_xact_id: UInt)(implicit conf: TileLinkConfiguration) = {
|
||||
val rel = new Release
|
||||
rel.r_type := r_type
|
||||
rel.addr := addr
|
||||
@ -77,100 +98,141 @@ object Release
|
||||
}
|
||||
}
|
||||
class Release(implicit val conf: TileLinkConfiguration) extends ClientSourcedMessage with HasPhysicalAddress with HasClientTransactionId with HasMasterTransactionId {
|
||||
val r_type = Bits(width = conf.co.releaseTypeWidth)
|
||||
val r_type = UInt(width = conf.co.releaseTypeWidth)
|
||||
}
|
||||
|
||||
class ReleaseData(implicit val conf: TileLinkConfiguration) extends ClientSourcedMessage with HasTileLinkData
|
||||
|
||||
class Grant(implicit val conf: TileLinkConfiguration) extends MasterSourcedMessage with HasTileLinkData with HasClientTransactionId with HasMasterTransactionId {
|
||||
val g_type = Bits(width = conf.co.grantTypeWidth)
|
||||
val g_type = UInt(width = conf.co.grantTypeWidth)
|
||||
}
|
||||
|
||||
class GrantAck(implicit val conf: TileLinkConfiguration) extends ClientSourcedMessage with HasMasterTransactionId
|
||||
|
||||
trait DirectionalIO
|
||||
trait ClientSourcedIO extends DirectionalIO
|
||||
trait MasterSourcedIO extends DirectionalIO
|
||||
class ClientSourcedFIFOIO[T <: Data](dType: T) extends DecoupledIO(dType) with ClientSourcedIO {
|
||||
override def clone = { new ClientSourcedFIFOIO(dType).asInstanceOf[this.type] }
|
||||
}
|
||||
class ClientSourcedDataIO[M <: Data, D <: Data](mType: M, dType: D) extends PairedDataIO(mType, dType) with ClientSourcedIO {
|
||||
override def clone = { new ClientSourcedDataIO(mType, dType).asInstanceOf[this.type] }
|
||||
}
|
||||
class MasterSourcedFIFOIO[T <: Data](dType: T) extends DecoupledIO(dType) with MasterSourcedIO {
|
||||
flip()
|
||||
override def clone = { new MasterSourcedFIFOIO(dType).asInstanceOf[this.type] }
|
||||
}
|
||||
class MasterSourcedDataIO[M <: Data, D <: Data](mType: M, dType: D) extends PairedDataIO(mType, dType) with MasterSourcedIO {
|
||||
flip()
|
||||
override def clone = { new MasterSourcedDataIO(mType, dType).asInstanceOf[this.type] }
|
||||
}
|
||||
|
||||
class UncachedTileLinkIO(implicit conf: TileLinkConfiguration) extends Bundle {
|
||||
implicit val ln = conf.ln
|
||||
val acquire = new ClientSourcedDataIO(new LogicalNetworkIO(new Acquire), new LogicalNetworkIO(new AcquireData))
|
||||
val grant = new MasterSourcedFIFOIO(new LogicalNetworkIO(new Grant))
|
||||
val grant_ack = new ClientSourcedFIFOIO(new LogicalNetworkIO(new GrantAck))
|
||||
val acquire = new PairedDataIO(new LogicalNetworkIO(new Acquire), new LogicalNetworkIO(new AcquireData))
|
||||
val grant = new DecoupledIO(new LogicalNetworkIO(new Grant)).flip
|
||||
val grant_ack = new DecoupledIO(new LogicalNetworkIO(new GrantAck))
|
||||
override def clone = { new UncachedTileLinkIO().asInstanceOf[this.type] }
|
||||
}
|
||||
|
||||
class TileLinkIO(implicit conf: TileLinkConfiguration) extends UncachedTileLinkIO()(conf) {
|
||||
val probe = new MasterSourcedFIFOIO(new LogicalNetworkIO(new Probe))
|
||||
val release = new ClientSourcedDataIO(new LogicalNetworkIO(new Release), new LogicalNetworkIO(new ReleaseData))
|
||||
val probe = new DecoupledIO(new LogicalNetworkIO(new Probe)).flip
|
||||
val release = new PairedDataIO(new LogicalNetworkIO(new Release), new LogicalNetworkIO(new ReleaseData))
|
||||
override def clone = { new TileLinkIO().asInstanceOf[this.type] }
|
||||
}
|
||||
|
||||
abstract class UncachedTileLinkIOArbiter(n: Int)(implicit conf: TileLinkConfiguration) extends Module {
|
||||
def acquireClientXactId(in: Acquire, id: Int): Bits
|
||||
def grantClientXactId(in: Grant): Bits
|
||||
def arbIdx(in: Grant): UInt
|
||||
|
||||
abstract class TileLinkArbiterLike(val arbN: Int)(implicit conf: TileLinkConfiguration) extends Module {
|
||||
implicit val (ln, co) = (conf.ln, conf.co)
|
||||
|
||||
type MasterSourcedWithId = MasterSourcedMessage with HasClientTransactionId
|
||||
type ClientSourcedWithId = ClientSourcedMessage with HasClientTransactionId
|
||||
type ClientSourcedWithData = ClientSourcedMessage with HasTileLinkData
|
||||
|
||||
def clientSourcedClientXactId(in: ClientSourcedWithId, id: Int): Bits
|
||||
def masterSourcedClientXactId(in: MasterSourcedWithId): Bits
|
||||
def arbIdx(in: MasterSourcedWithId): UInt
|
||||
|
||||
def hookupClientSource[M <: ClientSourcedWithId, D <: ClientSourcedWithData]
|
||||
(ins: Seq[PairedDataIO[LogicalNetworkIO[M],LogicalNetworkIO[D]]],
|
||||
out: PairedDataIO[LogicalNetworkIO[M],LogicalNetworkIO[D]]) {
|
||||
def hasData(m: LogicalNetworkIO[M]) = co.messageHasData(m.payload)
|
||||
val arb = Module(new PairedLockingRRArbiter(out.meta.bits.clone, out.data.bits.clone,
|
||||
arbN, REFILL_CYCLES, hasData _))
|
||||
out <> arb.io.out
|
||||
ins.zipWithIndex.zip(arb.io.in).map{ case ((req,id), arb) => {
|
||||
arb.data <> req.data
|
||||
arb.meta.valid := req.meta.valid
|
||||
arb.meta.bits := req.meta.bits
|
||||
arb.meta.bits.payload := req.meta.bits.payload
|
||||
arb.meta.bits.payload.client_xact_id := clientSourcedClientXactId(req.meta.bits.payload, id)
|
||||
req.meta.ready := arb.meta.ready
|
||||
}}
|
||||
}
|
||||
|
||||
def hookupMasterSource[M <: MasterSourcedWithId]
|
||||
(ins: Seq[DecoupledIO[LogicalNetworkIO[M]]],
|
||||
out: DecoupledIO[LogicalNetworkIO[M]]) {
|
||||
out.ready := Bool(false)
|
||||
for (i <- 0 until arbN) {
|
||||
ins(i).valid := Bool(false)
|
||||
when (arbIdx(out.bits.payload) === UInt(i)) {
|
||||
ins(i).valid := out.valid
|
||||
out.ready := ins(i).ready
|
||||
}
|
||||
ins(i).bits := out.bits
|
||||
ins(i).bits.payload.client_xact_id := masterSourcedClientXactId(out.bits.payload)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract class UncachedTileLinkIOArbiter(n: Int)(implicit conf: TileLinkConfiguration) extends TileLinkArbiterLike(n)(conf) {
|
||||
val io = new Bundle {
|
||||
val in = Vec.fill(n){new UncachedTileLinkIO}.flip
|
||||
val out = new UncachedTileLinkIO
|
||||
}
|
||||
def acqHasData(acq: LogicalNetworkIO[Acquire]) = co.messageHasData(acq.payload)
|
||||
val acq_arb = Module(new PairedLockingRRArbiter(new LogicalNetworkIO(new Acquire), new LogicalNetworkIO(new AcquireData), n, REFILL_CYCLES, acqHasData _))
|
||||
io.out.acquire <> acq_arb.io.out
|
||||
io.in.map(_.acquire).zipWithIndex.zip(acq_arb.io.in).map{ case ((req,id), arb) => {
|
||||
arb.data <> req.data
|
||||
arb.meta.valid := req.meta.valid
|
||||
arb.meta.bits := req.meta.bits
|
||||
arb.meta.bits.payload.client_xact_id := acquireClientXactId(req.meta.bits.payload, id)
|
||||
req.meta.ready := arb.meta.ready
|
||||
}}
|
||||
|
||||
hookupClientSource(io.in.map(_.acquire), io.out.acquire)
|
||||
hookupMasterSource(io.in.map(_.grant), io.out.grant)
|
||||
|
||||
val grant_ack_arb = Module(new RRArbiter(new LogicalNetworkIO(new GrantAck), n))
|
||||
io.out.grant_ack <> grant_ack_arb.io.out
|
||||
grant_ack_arb.io.in zip io.in map { case (arb, req) => arb <> req.grant_ack }
|
||||
}
|
||||
|
||||
io.out.grant.ready := Bool(false)
|
||||
for (i <- 0 until n) {
|
||||
io.in(i).grant.valid := Bool(false)
|
||||
when (arbIdx(io.out.grant.bits.payload) === UInt(i)) {
|
||||
io.in(i).grant.valid := io.out.grant.valid
|
||||
io.out.grant.ready := io.in(i).grant.ready
|
||||
}
|
||||
io.in(i).grant.bits := io.out.grant.bits
|
||||
io.in(i).grant.bits.payload.client_xact_id := grantClientXactId(io.out.grant.bits.payload)
|
||||
abstract class TileLinkIOArbiter(n: Int)(implicit conf: TileLinkConfiguration) extends TileLinkArbiterLike(n)(conf) {
|
||||
val io = new Bundle {
|
||||
val in = Vec.fill(n){new TileLinkIO}.flip
|
||||
val out = new TileLinkIO
|
||||
}
|
||||
|
||||
hookupClientSource(io.in.map(_.acquire), io.out.acquire)
|
||||
hookupClientSource(io.in.map(_.release), io.out.release)
|
||||
hookupMasterSource(io.in.map(_.grant), io.out.grant)
|
||||
|
||||
io.in.map{ _.probe.valid := io.out.probe.valid }
|
||||
io.in.map{ _.probe.bits := io.out.probe.bits }
|
||||
io.out.probe.ready := io.in.map(_.probe.ready).reduce(_||_)
|
||||
|
||||
val grant_ack_arb = Module(new RRArbiter(new LogicalNetworkIO(new GrantAck), n))
|
||||
io.out.grant_ack <> grant_ack_arb.io.out
|
||||
grant_ack_arb.io.in zip io.in map { case (arb, req) => arb <> req.grant_ack }
|
||||
}
|
||||
|
||||
class UncachedTileLinkIOArbiterThatAppendsArbiterId(n: Int)(implicit conf: TileLinkConfiguration) extends UncachedTileLinkIOArbiter(n)(conf) {
|
||||
def acquireClientXactId(in: Acquire, id: Int) = Cat(in.client_xact_id, UInt(id, log2Up(n)))
|
||||
def grantClientXactId(in: Grant) = in.client_xact_id >> UInt(log2Up(n))
|
||||
def arbIdx(in: Grant) = in.client_xact_id(log2Up(n)-1,0).toUInt
|
||||
abstract trait AppendsArbiterId {
|
||||
val arbN: Int
|
||||
def clientSourcedClientXactId(in: ClientSourcedMessage with HasClientTransactionId, id: Int) =
|
||||
Cat(in.client_xact_id, UInt(id, log2Up(arbN)))
|
||||
def masterSourcedClientXactId(in: MasterSourcedMessage with HasClientTransactionId) =
|
||||
in.client_xact_id >> UInt(log2Up(arbN))
|
||||
def arbIdx(in: MasterSourcedMessage with HasClientTransactionId) =
|
||||
in.client_xact_id(log2Up(arbN)-1,0).toUInt
|
||||
}
|
||||
|
||||
class UncachedTileLinkIOArbiterThatPassesId(n: Int)(implicit conf: TileLinkConfiguration) extends UncachedTileLinkIOArbiter(n)(conf) {
|
||||
def acquireClientXactId(in: Acquire, id: Int) = in.client_xact_id
|
||||
def grantClientXactId(in: Grant) = in.client_xact_id
|
||||
def arbIdx(in: Grant): UInt = in.client_xact_id
|
||||
abstract trait PassesId {
|
||||
def clientSourcedClientXactId(in: ClientSourcedMessage with HasClientTransactionId, id: Int) =
|
||||
in.client_xact_id
|
||||
def masterSourcedClientXactId(in: MasterSourcedMessage with HasClientTransactionId) =
|
||||
in.client_xact_id
|
||||
def arbIdx(in: MasterSourcedMessage with HasClientTransactionId) =
|
||||
in.client_xact_id
|
||||
}
|
||||
|
||||
class UncachedTileLinkIOArbiterThatUsesNewId(n: Int)(implicit conf: TileLinkConfiguration) extends UncachedTileLinkIOArbiter(n)(conf) {
|
||||
def acquireClientXactId(in: Acquire, id: Int) = UInt(id, log2Up(n))
|
||||
def grantClientXactId(in: Grant) = UInt(0) // DNC
|
||||
def arbIdx(in: Grant) = in.client_xact_id
|
||||
abstract trait UsesNewId {
|
||||
val arbN: Int
|
||||
def clientSourcedClientXactId(in: ClientSourcedMessage with HasClientTransactionId, id: Int) =
|
||||
UInt(id, log2Up(arbN))
|
||||
def masterSourcedClientXactId(in: MasterSourcedMessage with HasClientTransactionId) =
|
||||
UInt(0)
|
||||
def arbIdx(in: MasterSourcedMessage with HasClientTransactionId) =
|
||||
in.client_xact_id
|
||||
}
|
||||
|
||||
class UncachedTileLinkIOArbiterThatAppendsArbiterId(val n: Int)(implicit conf: TileLinkConfiguration) extends UncachedTileLinkIOArbiter(n)(conf) with AppendsArbiterId
|
||||
class UncachedTileLinkIOArbiterThatPassesId(val n: Int)(implicit conf: TileLinkConfiguration) extends UncachedTileLinkIOArbiter(n)(conf) with PassesId
|
||||
class UncachedTileLinkIOArbiterThatUsesNewId(val n: Int)(implicit conf: TileLinkConfiguration) extends UncachedTileLinkIOArbiter(n)(conf) with UsesNewId
|
||||
class TileLinkIOArbiterThatAppendsArbiterId(val n: Int)(implicit conf: TileLinkConfiguration) extends TileLinkIOArbiter(n)(conf) with AppendsArbiterId
|
||||
class TileLinkIOArbiterThatPassesId(val n: Int)(implicit conf: TileLinkConfiguration) extends TileLinkIOArbiter(n)(conf) with PassesId
|
||||
class TileLinkIOArbiterThatUsesNewId(val n: Int)(implicit conf: TileLinkConfiguration) extends TileLinkIOArbiter(n)(conf) with UsesNewId
|
||||
|
@ -1,7 +1,7 @@
|
||||
package uncore
|
||||
import Chisel._
|
||||
|
||||
abstract class CoherenceAgent(implicit conf: TileLinkConfiguration) extends Module with MasterCoherenceAgent {
|
||||
abstract class CoherenceAgent(implicit conf: TileLinkConfiguration) extends Module {
|
||||
val io = new Bundle {
|
||||
val client = (new TileLinkIO).flip
|
||||
val master = new UncachedTileLinkIO
|
||||
@ -279,13 +279,13 @@ class AcquireTracker(trackerId: Int, bankId: Int)(implicit conf: L2CoherenceAgen
|
||||
} . elsewhen (x_needs_read) {
|
||||
doOuterReqRead(io.master.acquire, cmd_to_read, x_needs_read)
|
||||
} . otherwise {
|
||||
state := Mux(co.needsAckReply(xact.a_type, UInt(0)), s_ack,
|
||||
Mux(co.requiresAck(io.client.grant.bits.payload), s_busy, s_idle))
|
||||
state := Mux(co.requiresDatalessGrant(xact.a_type, UInt(0)), s_ack,
|
||||
Mux(co.requiresAckForGrant(io.client.grant.bits.payload.g_type), s_busy, s_idle))
|
||||
}
|
||||
}
|
||||
is(s_ack) {
|
||||
io.client.grant.valid := Bool(true)
|
||||
when(io.client.grant.ready) { state := Mux(co.requiresAck(io.client.grant.bits.payload), s_busy, s_idle) }
|
||||
when(io.client.grant.ready) { state := Mux(co.requiresAckForGrant(io.client.grant.bits.payload.g_type), s_busy, s_idle) }
|
||||
}
|
||||
is(s_busy) { // Nothing left to do but wait for transaction to complete
|
||||
when (io.client.grant_ack.valid && io.client.grant_ack.bits.payload.master_xact_id === UInt(trackerId)) {
|
||||
|
Loading…
Reference in New Issue
Block a user