diff --git a/uncore/src/main/scala/coherence.scala b/uncore/src/main/scala/coherence.scala index dcb80c8e..e0db85f1 100644 --- a/uncore/src/main/scala/coherence.scala +++ b/uncore/src/main/scala/coherence.scala @@ -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) } diff --git a/uncore/src/main/scala/consts.scala b/uncore/src/main/scala/consts.scala index bbe6cbd5..d4f7130c 100644 --- a/uncore/src/main/scala/consts.scala +++ b/uncore/src/main/scala/consts.scala @@ -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?????"); diff --git a/uncore/src/main/scala/htif.scala b/uncore/src/main/scala/htif.scala index 4e894af8..608ac051 100644 --- a/uncore/src/main/scala/htif.scala +++ b/uncore/src/main/scala/htif.scala @@ -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) diff --git a/uncore/src/main/scala/network.scala b/uncore/src/main/scala/network.scala index 4905ffde..613a3b65 100644 --- a/uncore/src/main/scala/network.scala +++ b/uncore/src/main/scala/network.scala @@ -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) diff --git a/uncore/src/main/scala/tilelink.scala b/uncore/src/main/scala/tilelink.scala index 425cbccd..cd50213f 100644 --- a/uncore/src/main/scala/tilelink.scala +++ b/uncore/src/main/scala/tilelink.scala @@ -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 diff --git a/uncore/src/main/scala/uncore.scala b/uncore/src/main/scala/uncore.scala index a24f309d..8b410639 100644 --- a/uncore/src/main/scala/uncore.scala +++ b/uncore/src/main/scala/uncore.scala @@ -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)) {