1
0

cleanups supporting uncore hierarchy

This commit is contained in:
Henry Cook 2014-01-21 12:20:55 -08:00
parent 3e634aef1d
commit bbf8010230
6 changed files with 284 additions and 206 deletions

View File

@ -1,10 +1,6 @@
package uncore package uncore
import Chisel._ import Chisel._
abstract trait CoherenceAgentRole
abstract trait ClientCoherenceAgent extends CoherenceAgentRole
abstract trait MasterCoherenceAgent extends CoherenceAgentRole
abstract class CoherencePolicy { abstract class CoherencePolicy {
def nClientStates: Int def nClientStates: Int
def nMasterStates: Int def nMasterStates: Int
@ -31,41 +27,42 @@ abstract class CoherencePolicy {
def newStateOnWriteback(): UInt def newStateOnWriteback(): UInt
def newStateOnFlush(): UInt def newStateOnFlush(): UInt
def newStateOnGrant(incoming: Grant, outstanding: Acquire): 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 getAcquireTypeOnPrimaryMiss(cmd: UInt, state: UInt): UInt
def getAcquireTypeOnSecondaryMiss(cmd: UInt, state: UInt, outstanding: Acquire): UInt def getAcquireTypeOnSecondaryMiss(cmd: UInt, state: UInt, outstanding: Acquire): UInt
def getProbeType(a_type: UInt, global_state: UInt): UInt def getProbeType(a_type: UInt, global_state: UInt): UInt
def getReleaseTypeOnCacheControl(cmd: UInt): Bits def getReleaseTypeOnCacheControl(cmd: UInt): UInt
def getReleaseTypeOnVoluntaryWriteback(): Bits def getReleaseTypeOnVoluntaryWriteback(): UInt
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): Bits def getReleaseTypeOnProbe(incoming: Probe, state: UInt): UInt
def getGrantType(a_type: UInt, count: UInt): Bits def getGrantType(a_type: UInt, count: UInt): UInt
def getGrantType(rel: Release, count: UInt): Bits def getGrantType(rel: Release, count: UInt): UInt
def messageHasData (rel: SourcedMessage): Bool def messageHasData (rel: SourcedMessage): Bool
def messageUpdatesDataArray (reply: Grant): Bool def messageUpdatesDataArray (reply: Grant): Bool
def messageIsUncached(acq: Acquire): 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(rel: Release): Bool
def isVoluntary(gnt: Grant): Bool def isVoluntary(gnt: Grant): Bool
def needsOuterRead(a_type: UInt, global_state: UInt): Bool def needsOuterRead(a_type: UInt, global_state: UInt): Bool
def needsOuterWrite(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 requiresOuterAcquire(a_type: UInt, global_state: UInt): Bool
def needsSelfProbe(acq: Acquire): Bool def requiresDatalessGrant(a_type: UInt, global_state: UInt): Bool
def requiresAck(grant: Grant): Bool def requiresSelfProbe(a_type: UInt): Bool
def requiresAck(release: Release): Bool def requiresAckForGrant(g_type: UInt): Bool
def requiresAckForRelease(r_type: UInt): Bool
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool
def 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 { trait UncachedTransactions {
def getUncachedReadAcquireType: Bits def getUncachedReadAcquireType: UInt
def getUncachedWriteAcquireType: Bits def getUncachedWriteAcquireType: UInt
def getUncachedReadWordAcquireType: Bits def getUncachedReadWordAcquireType: UInt
def getUncachedWriteWordAcquireType: Bits def getUncachedWriteWordAcquireType: UInt
def getUncachedAtomicAcquireType: Bits def getUncachedAtomicAcquireType: UInt
def isUncachedReadTransaction(acq: Acquire): Bool def isUncachedReadTransaction(acq: Acquire): Bool
} }
@ -73,18 +70,19 @@ abstract class CoherencePolicyWithUncached extends CoherencePolicy with Uncached
abstract class IncoherentPolicy extends CoherencePolicy { abstract class IncoherentPolicy extends CoherencePolicy {
// UNIMPLEMENTED // UNIMPLEMENTED
def newStateOnProbe(incoming: Probe, state: UInt): Bits = state def newStateOnProbe(incoming: Probe, state: UInt): UInt = state
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): Bits = Bits(0) def getReleaseTypeOnProbe(incoming: Probe, state: UInt): UInt = UInt(0)
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = Bool(false) def isCoherenceConflict(addr1: UInt, addr2: UInt): Bool = Bool(false)
def getGrantType(a_type: UInt, count: UInt): Bits = Bits(0) def getGrantType(a_type: UInt, count: UInt): UInt = UInt(0)
def getGrantType(rel: Release, count: UInt): Bits = Bits(0) def getGrantType(rel: Release, count: UInt): UInt = UInt(0)
def getProbeType(a_type: UInt, global_state: 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 needsOuterRead(a_type: UInt, global_state: UInt): Bool = Bool(false)
def needsOuterWrite(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 requiresOuterAcquire(a_type: UInt, global_state: UInt): Bool = Bool(false)
def needsSelfProbe(acq: Acquire) = Bool(false) def requiresDatalessGrant(a_type: UInt, global_state: UInt): Bool = Bool(false)
def requiresAck(grant: Grant) = Bool(true) def requiresSelfProbe(a_type: UInt) = Bool(false)
def requiresAck(release: Release) = 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) 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 = { def getAcquireTypeOnSecondaryMiss(cmd: UInt, state: UInt, outstanding: Acquire): UInt = {
Mux(isWriteIntent(cmd), acquireReadDirty, outstanding.a_type) Mux(isWriteIntent(cmd), acquireReadDirty, outstanding.a_type)
} }
def getReleaseTypeOnCacheControl(cmd: UInt): Bits = releaseVoluntaryInvalidateData // TODO def getReleaseTypeOnCacheControl(cmd: UInt): UInt = releaseVoluntaryInvalidateData // TODO
def getReleaseTypeOnVoluntaryWriteback(): Bits = releaseVoluntaryInvalidateData def getReleaseTypeOnVoluntaryWriteback(): UInt = releaseVoluntaryInvalidateData
def messageHasData( msg: SourcedMessage ) = msg match { def messageHasData( msg: SourcedMessage ) = msg match {
case acq: Acquire => uSIntListContains(hasDataAcquireTypeList, acq.a_type) case acq: Acquire => uIntListContains(hasDataAcquireTypeList, acq.a_type)
case grant: Grant => uSIntListContains(hasDataGrantTypeList, grant.g_type) case grant: Grant => uIntListContains(hasDataGrantTypeList, grant.g_type)
case rel: Release => Bool(false) case rel: Release => Bool(false)
case _ => Bool(false) case _ => Bool(false)
} }
def messageUpdatesDataArray (reply: Grant) = (reply.g_type === grantData) 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 { class MICoherence extends CoherencePolicyWithUncached {
@ -202,7 +200,7 @@ class MICoherence extends CoherencePolicyWithUncached {
grantAtomicUncached -> tileInvalid grantAtomicUncached -> tileInvalid
)) ))
} }
def newStateOnProbe(incoming: Probe, state: UInt): Bits = { def newStateOnProbe(incoming: Probe, state: UInt): UInt = {
MuxLookup(incoming.p_type, state, Array( MuxLookup(incoming.p_type, state, Array(
probeInvalidate -> tileInvalid, probeInvalidate -> tileInvalid,
probeCopy -> state probeCopy -> state
@ -220,9 +218,9 @@ class MICoherence extends CoherencePolicyWithUncached {
def getAcquireTypeOnPrimaryMiss(cmd: UInt, state: UInt): UInt = acquireReadExclusive def getAcquireTypeOnPrimaryMiss(cmd: UInt, state: UInt): UInt = acquireReadExclusive
def getAcquireTypeOnSecondaryMiss(cmd: UInt, state: UInt, outstanding: Acquire): UInt = acquireReadExclusive def getAcquireTypeOnSecondaryMiss(cmd: UInt, state: UInt, outstanding: Acquire): UInt = acquireReadExclusive
def getReleaseTypeOnCacheControl(cmd: UInt): Bits = releaseVoluntaryInvalidateData // TODO def getReleaseTypeOnCacheControl(cmd: UInt): UInt = releaseVoluntaryInvalidateData // TODO
def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV) def getReleaseTypeOnVoluntaryWriteback(): UInt = getReleaseTypeOnCacheControl(M_INV)
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): Bits = { def getReleaseTypeOnProbe(incoming: Probe, state: UInt): UInt = {
val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array( val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array(
probeInvalidate -> releaseInvalidateData, probeInvalidate -> releaseInvalidateData,
probeCopy -> releaseCopyData probeCopy -> releaseCopyData
@ -235,19 +233,19 @@ class MICoherence extends CoherencePolicyWithUncached {
} }
def messageHasData(msg: SourcedMessage) = msg match { def messageHasData(msg: SourcedMessage) = msg match {
case acq: Acquire => uSIntListContains(hasDataAcquireTypeList, acq.a_type) case acq: Acquire => uIntListContains(hasDataAcquireTypeList, acq.a_type)
case grant: Grant => uSIntListContains(hasDataGrantTypeList, grant.g_type) case grant: Grant => uIntListContains(hasDataGrantTypeList, grant.g_type)
case rel: Release => uSIntListContains(hasDataReleaseTypeList, rel.r_type) case rel: Release => uIntListContains(hasDataReleaseTypeList, rel.r_type)
case _ => Bool(false) case _ => Bool(false)
} }
def messageUpdatesDataArray (reply: Grant): Bool = { def messageUpdatesDataArray (reply: Grant): Bool = {
(reply.g_type === grantReadExclusive) (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( MuxLookup(a_type, grantReadUncached, Array(
acquireReadExclusive -> grantReadExclusive, acquireReadExclusive -> grantReadExclusive,
acquireReadUncached -> grantReadUncached, 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( MuxLookup(rel.r_type, grantReadUncached, Array(
releaseVoluntaryInvalidateData -> grantVoluntaryAck releaseVoluntaryInvalidateData -> grantVoluntaryAck
)) ))
@ -281,12 +279,15 @@ class MICoherence extends CoherencePolicyWithUncached {
def needsOuterWrite(a_type: UInt, global_state: UInt): Bool = { def needsOuterWrite(a_type: UInt, global_state: UInt): Bool = {
(a_type === acquireWriteUncached) (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) (a_type === acquireWriteUncached)
} }
def requiresAck(grant: Grant) = grant.g_type != grantVoluntaryAck def requiresAckForGrant(g_type: UInt) = g_type != grantVoluntaryAck
def requiresAck(release: Release) = Bool(false) def requiresAckForRelease(r_type: UInt) = Bool(false)
def needsSelfProbe(acq: Acquire) = Bool(false) def requiresSelfProbe(a_type: UInt) = Bool(false)
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData) def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData)
} }
@ -350,7 +351,7 @@ class MEICoherence extends CoherencePolicyWithUncached {
grantAtomicUncached -> tileInvalid grantAtomicUncached -> tileInvalid
)) ))
} }
def newStateOnProbe(incoming: Probe, state: UInt): Bits = { def newStateOnProbe(incoming: Probe, state: UInt): UInt = {
MuxLookup(incoming.p_type, state, Array( MuxLookup(incoming.p_type, state, Array(
probeInvalidate -> tileInvalid, probeInvalidate -> tileInvalid,
probeDowngrade -> tileExclusiveClean, probeDowngrade -> tileExclusiveClean,
@ -373,9 +374,9 @@ class MEICoherence extends CoherencePolicyWithUncached {
def getAcquireTypeOnSecondaryMiss(cmd: UInt, state: UInt, outstanding: Acquire): UInt = { def getAcquireTypeOnSecondaryMiss(cmd: UInt, state: UInt, outstanding: Acquire): UInt = {
Mux(isWriteIntent(cmd), acquireReadExclusiveDirty, outstanding.a_type) Mux(isWriteIntent(cmd), acquireReadExclusiveDirty, outstanding.a_type)
} }
def getReleaseTypeOnCacheControl(cmd: UInt): Bits = releaseVoluntaryInvalidateData // TODO def getReleaseTypeOnCacheControl(cmd: UInt): UInt = releaseVoluntaryInvalidateData // TODO
def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV) def getReleaseTypeOnVoluntaryWriteback(): UInt = getReleaseTypeOnCacheControl(M_INV)
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): Bits = { def getReleaseTypeOnProbe(incoming: Probe, state: UInt): UInt = {
val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array( val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array(
probeInvalidate -> releaseInvalidateData, probeInvalidate -> releaseInvalidateData,
probeDowngrade -> releaseDowngradeData, probeDowngrade -> releaseDowngradeData,
@ -390,19 +391,19 @@ class MEICoherence extends CoherencePolicyWithUncached {
} }
def messageHasData(msg: SourcedMessage) = msg match { def messageHasData(msg: SourcedMessage) = msg match {
case acq: Acquire => uSIntListContains(hasDataAcquireTypeList, acq.a_type) case acq: Acquire => uIntListContains(hasDataAcquireTypeList, acq.a_type)
case grant: Grant => uSIntListContains(hasDataGrantTypeList, grant.g_type) case grant: Grant => uIntListContains(hasDataGrantTypeList, grant.g_type)
case rel: Release => uSIntListContains(hasDataReleaseTypeList, rel.r_type) case rel: Release => uIntListContains(hasDataReleaseTypeList, rel.r_type)
case _ => Bool(false) case _ => Bool(false)
} }
def messageUpdatesDataArray (reply: Grant): Bool = { def messageUpdatesDataArray (reply: Grant): Bool = {
(reply.g_type === grantReadExclusive) (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( MuxLookup(a_type, grantReadUncached, Array(
acquireReadExclusiveClean -> grantReadExclusive, acquireReadExclusiveClean -> grantReadExclusive,
acquireReadExclusiveDirty -> grantReadExclusive, acquireReadExclusiveDirty -> grantReadExclusive,
@ -413,7 +414,7 @@ class MEICoherence extends CoherencePolicyWithUncached {
acquireAtomicUncached -> grantAtomicUncached acquireAtomicUncached -> grantAtomicUncached
)) ))
} }
def getGrantType(rel: Release, count: UInt): Bits = { def getGrantType(rel: Release, count: UInt): UInt = {
MuxLookup(rel.r_type, grantReadUncached, Array( MuxLookup(rel.r_type, grantReadUncached, Array(
releaseVoluntaryInvalidateData -> grantVoluntaryAck releaseVoluntaryInvalidateData -> grantVoluntaryAck
)) ))
@ -438,12 +439,15 @@ class MEICoherence extends CoherencePolicyWithUncached {
def needsOuterWrite(a_type: UInt, global_state: UInt): Bool = { def needsOuterWrite(a_type: UInt, global_state: UInt): Bool = {
(a_type === acquireWriteUncached) (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) (a_type === acquireWriteUncached)
} }
def requiresAck(grant: Grant) = grant.g_type != grantVoluntaryAck def requiresAckForGrant(g_type: UInt) = g_type != grantVoluntaryAck
def requiresAck(release: Release) = Bool(false) def requiresAckForRelease(r_type: UInt) = Bool(false)
def needsSelfProbe(acq: Acquire) = Bool(false) def requiresSelfProbe(a_type: UInt) = Bool(false)
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData) def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData)
} }
@ -514,7 +518,7 @@ class MSICoherence extends CoherencePolicyWithUncached {
grantAtomicUncached -> tileInvalid grantAtomicUncached -> tileInvalid
)) ))
} }
def newStateOnProbe(incoming: Probe, state: UInt): Bits = { def newStateOnProbe(incoming: Probe, state: UInt): UInt = {
MuxLookup(incoming.p_type, state, Array( MuxLookup(incoming.p_type, state, Array(
probeInvalidate -> tileInvalid, probeInvalidate -> tileInvalid,
probeDowngrade -> tileShared, probeDowngrade -> tileShared,
@ -537,9 +541,9 @@ class MSICoherence extends CoherencePolicyWithUncached {
def getAcquireTypeOnSecondaryMiss(cmd: UInt, state: UInt, outstanding: Acquire): UInt = { def getAcquireTypeOnSecondaryMiss(cmd: UInt, state: UInt, outstanding: Acquire): UInt = {
Mux(isWriteIntent(cmd), acquireReadExclusive, outstanding.a_type) Mux(isWriteIntent(cmd), acquireReadExclusive, outstanding.a_type)
} }
def getReleaseTypeOnCacheControl(cmd: UInt): Bits = releaseVoluntaryInvalidateData // TODO def getReleaseTypeOnCacheControl(cmd: UInt): UInt = releaseVoluntaryInvalidateData // TODO
def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV) def getReleaseTypeOnVoluntaryWriteback(): UInt = getReleaseTypeOnCacheControl(M_INV)
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): Bits = { def getReleaseTypeOnProbe(incoming: Probe, state: UInt): UInt = {
val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array( val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array(
probeInvalidate -> releaseInvalidateData, probeInvalidate -> releaseInvalidateData,
probeDowngrade -> releaseDowngradeData, probeDowngrade -> releaseDowngradeData,
@ -554,19 +558,19 @@ class MSICoherence extends CoherencePolicyWithUncached {
} }
def messageHasData(msg: SourcedMessage) = msg match { def messageHasData(msg: SourcedMessage) = msg match {
case acq: Acquire => uSIntListContains(hasDataAcquireTypeList, acq.a_type) case acq: Acquire => uIntListContains(hasDataAcquireTypeList, acq.a_type)
case grant: Grant => uSIntListContains(hasDataGrantTypeList, grant.g_type) case grant: Grant => uIntListContains(hasDataGrantTypeList, grant.g_type)
case rel: Release => uSIntListContains(hasDataReleaseTypeList, rel.r_type) case rel: Release => uIntListContains(hasDataReleaseTypeList, rel.r_type)
case _ => Bool(false) case _ => Bool(false)
} }
def messageUpdatesDataArray (reply: Grant): Bool = { def messageUpdatesDataArray (reply: Grant): Bool = {
(reply.g_type === grantReadShared || reply.g_type === grantReadExclusive) (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( MuxLookup(a_type, grantReadUncached, Array(
acquireReadShared -> Mux(count > UInt(0), grantReadShared, grantReadExclusive), acquireReadShared -> Mux(count > UInt(0), grantReadShared, grantReadExclusive),
acquireReadExclusive -> grantReadExclusive, acquireReadExclusive -> grantReadExclusive,
@ -577,7 +581,7 @@ class MSICoherence extends CoherencePolicyWithUncached {
acquireAtomicUncached -> grantAtomicUncached acquireAtomicUncached -> grantAtomicUncached
)) ))
} }
def getGrantType(rel: Release, count: UInt): Bits = { def getGrantType(rel: Release, count: UInt): UInt = {
MuxLookup(rel.r_type, grantReadUncached, Array( MuxLookup(rel.r_type, grantReadUncached, Array(
releaseVoluntaryInvalidateData -> grantVoluntaryAck releaseVoluntaryInvalidateData -> grantVoluntaryAck
)) ))
@ -599,12 +603,15 @@ class MSICoherence extends CoherencePolicyWithUncached {
def needsOuterWrite(a_type: UInt, global_state: UInt): Bool = { def needsOuterWrite(a_type: UInt, global_state: UInt): Bool = {
(a_type === acquireWriteUncached) (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) (a_type === acquireWriteUncached)
} }
def requiresAck(grant: Grant) = grant.g_type != grantVoluntaryAck def requiresAckForGrant(g_type: UInt) = g_type != grantVoluntaryAck
def requiresAck(release: Release) = Bool(false) def requiresAckForRelease(r_type: UInt) = Bool(false)
def needsSelfProbe(acq: Acquire) = Bool(false) def requiresSelfProbe(a_type: UInt) = Bool(false)
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData) def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData)
} }
@ -675,7 +682,7 @@ class MESICoherence extends CoherencePolicyWithUncached {
grantAtomicUncached -> tileInvalid grantAtomicUncached -> tileInvalid
)) ))
} }
def newStateOnProbe(incoming: Probe, state: UInt): Bits = { def newStateOnProbe(incoming: Probe, state: UInt): UInt = {
MuxLookup(incoming.p_type, state, Array( MuxLookup(incoming.p_type, state, Array(
probeInvalidate -> tileInvalid, probeInvalidate -> tileInvalid,
probeDowngrade -> tileShared, probeDowngrade -> tileShared,
@ -698,9 +705,9 @@ class MESICoherence extends CoherencePolicyWithUncached {
def getAcquireTypeOnSecondaryMiss(cmd: UInt, state: UInt, outstanding: Acquire): UInt = { def getAcquireTypeOnSecondaryMiss(cmd: UInt, state: UInt, outstanding: Acquire): UInt = {
Mux(isWriteIntent(cmd), acquireReadExclusive, outstanding.a_type) Mux(isWriteIntent(cmd), acquireReadExclusive, outstanding.a_type)
} }
def getReleaseTypeOnCacheControl(cmd: UInt): Bits = releaseVoluntaryInvalidateData // TODO def getReleaseTypeOnCacheControl(cmd: UInt): UInt = releaseVoluntaryInvalidateData // TODO
def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV) def getReleaseTypeOnVoluntaryWriteback(): UInt = getReleaseTypeOnCacheControl(M_INV)
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): Bits = { def getReleaseTypeOnProbe(incoming: Probe, state: UInt): UInt = {
val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array( val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array(
probeInvalidate -> releaseInvalidateData, probeInvalidate -> releaseInvalidateData,
probeDowngrade -> releaseDowngradeData, probeDowngrade -> releaseDowngradeData,
@ -715,19 +722,19 @@ class MESICoherence extends CoherencePolicyWithUncached {
} }
def messageHasData(msg: SourcedMessage) = msg match { def messageHasData(msg: SourcedMessage) = msg match {
case acq: Acquire => uSIntListContains(hasDataAcquireTypeList, acq.a_type) case acq: Acquire => uIntListContains(hasDataAcquireTypeList, acq.a_type)
case grant: Grant => uSIntListContains(hasDataGrantTypeList, grant.g_type) case grant: Grant => uIntListContains(hasDataGrantTypeList, grant.g_type)
case rel: Release => uSIntListContains(hasDataReleaseTypeList, rel.r_type) case rel: Release => uIntListContains(hasDataReleaseTypeList, rel.r_type)
case _ => Bool(false) case _ => Bool(false)
} }
def messageUpdatesDataArray (reply: Grant): Bool = { def messageUpdatesDataArray (reply: Grant): Bool = {
(reply.g_type === grantReadShared || reply.g_type === grantReadExclusive) (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( MuxLookup(a_type, grantReadUncached, Array(
acquireReadShared -> Mux(count > UInt(0), grantReadShared, grantReadExclusive), acquireReadShared -> Mux(count > UInt(0), grantReadShared, grantReadExclusive),
acquireReadExclusive -> grantReadExclusive, acquireReadExclusive -> grantReadExclusive,
@ -738,7 +745,7 @@ class MESICoherence extends CoherencePolicyWithUncached {
acquireAtomicUncached -> grantAtomicUncached acquireAtomicUncached -> grantAtomicUncached
)) ))
} }
def getGrantType(rel: Release, count: UInt): Bits = { def getGrantType(rel: Release, count: UInt): UInt = {
MuxLookup(rel.r_type, grantReadUncached, Array( MuxLookup(rel.r_type, grantReadUncached, Array(
releaseVoluntaryInvalidateData -> grantVoluntaryAck releaseVoluntaryInvalidateData -> grantVoluntaryAck
)) ))
@ -763,13 +770,16 @@ class MESICoherence extends CoherencePolicyWithUncached {
def needsOuterWrite(a_type: UInt, global_state: UInt): Bool = { def needsOuterWrite(a_type: UInt, global_state: UInt): Bool = {
(a_type === acquireWriteUncached) (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) (a_type === acquireWriteUncached)
} }
def requiresAck(grant: Grant) = grant.g_type != grantVoluntaryAck def requiresAckForGrant(g_type: UInt) = g_type != grantVoluntaryAck
def requiresAck(release: Release) = Bool(false) def requiresAckForRelease(r_type: UInt) = Bool(false)
def needsSelfProbe(acq: Acquire) = Bool(false) def requiresSelfProbe(a_type: UInt) = Bool(false)
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData) def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData)
} }
@ -795,7 +805,7 @@ class MigratoryCoherence extends CoherencePolicyWithUncached {
val hasDataReleaseTypeList = List(releaseVoluntaryInvalidateData, releaseInvalidateData, releaseDowngradeData, releaseCopyData, releaseInvalidateDataMigratory, releaseDowngradeDataMigratory) val hasDataReleaseTypeList = List(releaseVoluntaryInvalidateData, releaseInvalidateData, releaseDowngradeData, releaseCopyData, releaseInvalidateDataMigratory, releaseDowngradeDataMigratory)
def isHit (cmd: UInt, state: UInt): Bool = { 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 = { def isValid (state: UInt): Bool = {
state != tileInvalid state != tileInvalid
@ -807,8 +817,8 @@ class MigratoryCoherence extends CoherencePolicyWithUncached {
} }
def needsTransactionOnCacheControl(cmd: UInt, state: UInt): Bool = { def needsTransactionOnCacheControl(cmd: UInt, state: UInt): Bool = {
MuxLookup(cmd, (state === tileExclusiveDirty), Array( MuxLookup(cmd, (state === tileExclusiveDirty), Array(
M_INV -> uSIntListContains(List(tileExclusiveDirty,tileMigratoryDirty),state), M_INV -> uIntListContains(List(tileExclusiveDirty,tileMigratoryDirty),state),
M_CLN -> uSIntListContains(List(tileExclusiveDirty,tileMigratoryDirty),state) M_CLN -> uIntListContains(List(tileExclusiveDirty,tileMigratoryDirty),state)
)) ))
} }
def needsWriteback (state: UInt): Bool = { def needsWriteback (state: UInt): Bool = {
@ -846,7 +856,7 @@ class MigratoryCoherence extends CoherencePolicyWithUncached {
acquireReadShared -> tileMigratoryClean)) acquireReadShared -> tileMigratoryClean))
)) ))
} }
def newStateOnProbe(incoming: Probe, state: UInt): Bits = { def newStateOnProbe(incoming: Probe, state: UInt): UInt = {
MuxLookup(incoming.p_type, state, Array( MuxLookup(incoming.p_type, state, Array(
probeInvalidate -> tileInvalid, probeInvalidate -> tileInvalid,
probeInvalidateOthers -> tileInvalid, probeInvalidateOthers -> tileInvalid,
@ -875,11 +885,11 @@ class MigratoryCoherence extends CoherencePolicyWithUncached {
def getAcquireTypeOnSecondaryMiss(cmd: UInt, state: UInt, outstanding: Acquire): UInt = { def getAcquireTypeOnSecondaryMiss(cmd: UInt, state: UInt, outstanding: Acquire): UInt = {
Mux(isWriteIntent(cmd), Mux(state === tileInvalid, acquireReadExclusive, acquireInvalidateOthers), outstanding.a_type) Mux(isWriteIntent(cmd), Mux(state === tileInvalid, acquireReadExclusive, acquireInvalidateOthers), outstanding.a_type)
} }
def getReleaseTypeOnCacheControl(cmd: UInt): Bits = releaseVoluntaryInvalidateData // TODO def getReleaseTypeOnCacheControl(cmd: UInt): UInt = releaseVoluntaryInvalidateData // TODO
def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV) def getReleaseTypeOnVoluntaryWriteback(): UInt = getReleaseTypeOnCacheControl(M_INV)
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): Bits = { def getReleaseTypeOnProbe(incoming: Probe, state: UInt): UInt = {
val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array( 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), releaseInvalidateDataMigratory, releaseInvalidateData),
probeDowngrade -> Mux(state === tileMigratoryDirty, releaseDowngradeDataMigratory, releaseDowngradeData), probeDowngrade -> Mux(state === tileMigratoryDirty, releaseDowngradeDataMigratory, releaseDowngradeData),
probeCopy -> releaseCopyData probeCopy -> releaseCopyData
@ -894,19 +904,19 @@ class MigratoryCoherence extends CoherencePolicyWithUncached {
} }
def messageHasData(msg: SourcedMessage) = msg match { def messageHasData(msg: SourcedMessage) = msg match {
case acq: Acquire => uSIntListContains(hasDataAcquireTypeList, acq.a_type) case acq: Acquire => uIntListContains(hasDataAcquireTypeList, acq.a_type)
case grant: Grant => uSIntListContains(hasDataGrantTypeList, grant.g_type) case grant: Grant => uIntListContains(hasDataGrantTypeList, grant.g_type)
case rel: Release => uSIntListContains(hasDataReleaseTypeList, rel.r_type) case rel: Release => uIntListContains(hasDataReleaseTypeList, rel.r_type)
case _ => Bool(false) case _ => Bool(false)
} }
def messageUpdatesDataArray (reply: Grant): Bool = { 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( MuxLookup(a_type, grantReadUncached, Array(
acquireReadShared -> Mux(count > UInt(0), grantReadShared, grantReadExclusive), //TODO: what is count? Depend on release.p_type??? acquireReadShared -> Mux(count > UInt(0), grantReadShared, grantReadExclusive), //TODO: what is count? Depend on release.p_type???
acquireReadExclusive -> grantReadExclusive, acquireReadExclusive -> grantReadExclusive,
@ -918,7 +928,7 @@ class MigratoryCoherence extends CoherencePolicyWithUncached {
acquireInvalidateOthers -> grantReadExclusiveAck //TODO: add this to MESI? 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( MuxLookup(rel.r_type, grantReadUncached, Array(
releaseVoluntaryInvalidateData -> grantVoluntaryAck releaseVoluntaryInvalidateData -> grantVoluntaryAck
)) ))
@ -944,12 +954,16 @@ class MigratoryCoherence extends CoherencePolicyWithUncached {
def needsOuterWrite(a_type: UInt, global_state: UInt): Bool = { def needsOuterWrite(a_type: UInt, global_state: UInt): Bool = {
(a_type === acquireWriteUncached || a_type === acquireWriteWordUncached || a_type === acquireAtomicUncached) (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) (a_type === acquireWriteUncached || a_type === acquireWriteWordUncached ||a_type === acquireInvalidateOthers)
} }
def requiresAck(grant: Grant) = grant.g_type != grantVoluntaryAck def requiresAckForGrant(g_type: UInt) = g_type != grantVoluntaryAck
def requiresAck(release: Release) = Bool(false) def requiresAckForRelease(r_type: UInt) = Bool(false)
def needsSelfProbe(acq: Acquire) = Bool(false) def requiresSelfProbe(a_type: UInt) = Bool(false)
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData) def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData)
} }

View File

@ -6,14 +6,15 @@ import scala.math.max
object MemoryOpConstants extends MemoryOpConstants object MemoryOpConstants extends MemoryOpConstants
trait MemoryOpConstants { trait MemoryOpConstants {
val MT_X = Bits("b???", 3); val MT_SZ = 3
val MT_B = Bits("b000", 3); val MT_X = Bits("b???")
val MT_H = Bits("b001", 3); val MT_B = Bits("b000")
val MT_W = Bits("b010", 3); val MT_H = Bits("b001")
val MT_D = Bits("b011", 3); val MT_W = Bits("b010")
val MT_BU = Bits("b100", 3); val MT_D = Bits("b011")
val MT_HU = Bits("b101", 3); val MT_BU = Bits("b100")
val MT_WU = Bits("b110", 3); val MT_HU = Bits("b101")
val MT_WU = Bits("b110")
val M_SZ = 5 val M_SZ = 5
val M_X = Bits("b?????"); val M_X = Bits("b?????");

View File

@ -41,7 +41,7 @@ class SCRIO(n: Int) extends Bundle
val wdata = Bits(OUTPUT, 64) 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) implicit val (ln, co) = (conf.ln, conf.co)
val nTiles = ln.nClients-1 // This HTIF is itself a TileLink client 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_acked := Bool(true)
mem_gxid := io.mem.grant.bits.payload.master_xact_id mem_gxid := io.mem.grant.bits.payload.master_xact_id
mem_gsrc := io.mem.grant.bits.header.src mem_gsrc := io.mem.grant.bits.header.src
mem_needs_ack := 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) io.mem.grant.ready := Bool(true)

View File

@ -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 } 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) { class PairedCrossbarIO[M <: Data, D <: Data](mType: M, dType: D)(implicit conf: PhysicalNetworkConfiguration) extends Bundle {
val io = new Bundle {
val in = Vec.fill(conf.nEndpoints){new PairedDataIO(new PhysicalNetworkIO(mType),new PhysicalNetworkIO(dType))}.flip 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))} 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 metaRdyVecs = List.fill(conf.nEndpoints)(Vec.fill(conf.nEndpoints){Bool()})
val dataRdyVecs = 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 abstract class PhysicalNetwork(conf: PhysicalNetworkConfiguration) extends Module
class BasicCrossbar[T <: Data](dType: T, count: Int = 1)(implicit conf: PhysicalNetworkConfiguration) extends PhysicalNetwork(conf) { class BasicCrossbarIO[T <: Data](dType: T)(implicit conf: PhysicalNetworkConfiguration) extends Bundle {
val io = new Bundle {
val in = Vec.fill(conf.nEndpoints){Decoupled(new PhysicalNetworkIO(dType))}.flip val in = Vec.fill(conf.nEndpoints){Decoupled(new PhysicalNetworkIO(dType))}.flip
val out = Vec.fill(conf.nEndpoints){Decoupled(new PhysicalNetworkIO(dType))} 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())) 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) case class LogicalNetworkConfiguration(idBits: Int, nMasters: Int, nClients: Int) {
val nEndpoints = nMasters + nClients
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)
} }
abstract class LogicalNetwork[TileLinkType <: Bundle](implicit conf: LogicalNetworkConfiguration) extends Module
class LogicalHeader(implicit conf: LogicalNetworkConfiguration) extends Bundle { class LogicalHeader(implicit conf: LogicalNetworkConfiguration) extends Bundle {
val src = UInt(width = conf.idBits) val src = UInt(width = conf.idBits)
val dst = UInt(width = conf.idBits) val dst = UInt(width = conf.idBits)

View File

@ -40,20 +40,25 @@ object Acquire
acq.atomic_opcode := Bits(0) acq.atomic_opcode := Bits(0)
acq 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) val acq = apply(a_type, addr, client_xact_id)
acq.write_mask := write_mask acq.write_mask := write_mask
acq 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) val acq = apply(a_type, addr, client_xact_id)
acq.subword_addr := subword_addr acq.subword_addr := subword_addr
acq.atomic_opcode := atomic_opcode acq.atomic_opcode := atomic_opcode
acq 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 { 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 write_mask = Bits(width = ACQUIRE_WRITE_MASK_BITS)
val subword_addr = Bits(width = ACQUIRE_SUBWORD_ADDR_BITS) val subword_addr = Bits(width = ACQUIRE_SUBWORD_ADDR_BITS)
val atomic_opcode = Bits(width = ACQUIRE_ATOMIC_OP_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 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 { 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 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 val rel = new Release
rel.r_type := r_type rel.r_type := r_type
rel.addr := addr rel.addr := addr
@ -77,100 +98,141 @@ object Release
} }
} }
class Release(implicit val conf: TileLinkConfiguration) extends ClientSourcedMessage with HasPhysicalAddress with HasClientTransactionId with HasMasterTransactionId { 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 ReleaseData(implicit val conf: TileLinkConfiguration) extends ClientSourcedMessage with HasTileLinkData
class Grant(implicit val conf: TileLinkConfiguration) extends MasterSourcedMessage with HasTileLinkData with HasClientTransactionId with HasMasterTransactionId { 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 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 { class UncachedTileLinkIO(implicit conf: TileLinkConfiguration) extends Bundle {
implicit val ln = conf.ln implicit val ln = conf.ln
val acquire = new ClientSourcedDataIO(new LogicalNetworkIO(new Acquire), new LogicalNetworkIO(new AcquireData)) val acquire = new PairedDataIO(new LogicalNetworkIO(new Acquire), new LogicalNetworkIO(new AcquireData))
val grant = new MasterSourcedFIFOIO(new LogicalNetworkIO(new Grant)) val grant = new DecoupledIO(new LogicalNetworkIO(new Grant)).flip
val grant_ack = new ClientSourcedFIFOIO(new LogicalNetworkIO(new GrantAck)) val grant_ack = new DecoupledIO(new LogicalNetworkIO(new GrantAck))
override def clone = { new UncachedTileLinkIO().asInstanceOf[this.type] } override def clone = { new UncachedTileLinkIO().asInstanceOf[this.type] }
} }
class TileLinkIO(implicit conf: TileLinkConfiguration) extends UncachedTileLinkIO()(conf) { class TileLinkIO(implicit conf: TileLinkConfiguration) extends UncachedTileLinkIO()(conf) {
val probe = new MasterSourcedFIFOIO(new LogicalNetworkIO(new Probe)) val probe = new DecoupledIO(new LogicalNetworkIO(new Probe)).flip
val release = new ClientSourcedDataIO(new LogicalNetworkIO(new Release), new LogicalNetworkIO(new ReleaseData)) val release = new PairedDataIO(new LogicalNetworkIO(new Release), new LogicalNetworkIO(new ReleaseData))
override def clone = { new TileLinkIO().asInstanceOf[this.type] } override def clone = { new TileLinkIO().asInstanceOf[this.type] }
} }
abstract class UncachedTileLinkIOArbiter(n: Int)(implicit conf: TileLinkConfiguration) extends Module { abstract class TileLinkArbiterLike(val arbN: Int)(implicit conf: TileLinkConfiguration) extends Module {
def acquireClientXactId(in: Acquire, id: Int): Bits
def grantClientXactId(in: Grant): Bits
def arbIdx(in: Grant): UInt
implicit val (ln, co) = (conf.ln, conf.co) 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 io = new Bundle {
val in = Vec.fill(n){new UncachedTileLinkIO}.flip val in = Vec.fill(n){new UncachedTileLinkIO}.flip
val out = new UncachedTileLinkIO 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 _)) hookupClientSource(io.in.map(_.acquire), io.out.acquire)
io.out.acquire <> acq_arb.io.out hookupMasterSource(io.in.map(_.grant), io.out.grant)
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
}}
val grant_ack_arb = Module(new RRArbiter(new LogicalNetworkIO(new GrantAck), n)) val grant_ack_arb = Module(new RRArbiter(new LogicalNetworkIO(new GrantAck), n))
io.out.grant_ack <> grant_ack_arb.io.out 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 } grant_ack_arb.io.in zip io.in map { case (arb, req) => arb <> req.grant_ack }
}
io.out.grant.ready := Bool(false) abstract class TileLinkIOArbiter(n: Int)(implicit conf: TileLinkConfiguration) extends TileLinkArbiterLike(n)(conf) {
for (i <- 0 until n) { val io = new Bundle {
io.in(i).grant.valid := Bool(false) val in = Vec.fill(n){new TileLinkIO}.flip
when (arbIdx(io.out.grant.bits.payload) === UInt(i)) { val out = new TileLinkIO
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)
} }
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) { abstract trait AppendsArbiterId {
def acquireClientXactId(in: Acquire, id: Int) = Cat(in.client_xact_id, UInt(id, log2Up(n))) val arbN: Int
def grantClientXactId(in: Grant) = in.client_xact_id >> UInt(log2Up(n)) def clientSourcedClientXactId(in: ClientSourcedMessage with HasClientTransactionId, id: Int) =
def arbIdx(in: Grant) = in.client_xact_id(log2Up(n)-1,0).toUInt 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) { abstract trait PassesId {
def acquireClientXactId(in: Acquire, id: Int) = in.client_xact_id def clientSourcedClientXactId(in: ClientSourcedMessage with HasClientTransactionId, id: Int) =
def grantClientXactId(in: Grant) = in.client_xact_id in.client_xact_id
def arbIdx(in: Grant): UInt = 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) { abstract trait UsesNewId {
def acquireClientXactId(in: Acquire, id: Int) = UInt(id, log2Up(n)) val arbN: Int
def grantClientXactId(in: Grant) = UInt(0) // DNC def clientSourcedClientXactId(in: ClientSourcedMessage with HasClientTransactionId, id: Int) =
def arbIdx(in: Grant) = in.client_xact_id 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

View File

@ -1,7 +1,7 @@
package uncore package uncore
import Chisel._ 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 io = new Bundle {
val client = (new TileLinkIO).flip val client = (new TileLinkIO).flip
val master = new UncachedTileLinkIO val master = new UncachedTileLinkIO
@ -279,13 +279,13 @@ class AcquireTracker(trackerId: Int, bankId: Int)(implicit conf: L2CoherenceAgen
} . elsewhen (x_needs_read) { } . elsewhen (x_needs_read) {
doOuterReqRead(io.master.acquire, cmd_to_read, x_needs_read) doOuterReqRead(io.master.acquire, cmd_to_read, x_needs_read)
} . otherwise { } . otherwise {
state := Mux(co.needsAckReply(xact.a_type, UInt(0)), s_ack, state := Mux(co.requiresDatalessGrant(xact.a_type, UInt(0)), s_ack,
Mux(co.requiresAck(io.client.grant.bits.payload), s_busy, s_idle)) Mux(co.requiresAckForGrant(io.client.grant.bits.payload.g_type), s_busy, s_idle))
} }
} }
is(s_ack) { is(s_ack) {
io.client.grant.valid := Bool(true) 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 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)) { when (io.client.grant_ack.valid && io.client.grant_ack.bits.payload.master_xact_id === UInt(trackerId)) {