diff --git a/uncore/src/coherence.scala b/uncore/src/coherence.scala index b869436a..b8c3e4ad 100644 --- a/uncore/src/coherence.scala +++ b/uncore/src/coherence.scala @@ -6,6 +6,19 @@ abstract trait ClientCoherenceAgent extends CoherenceAgentRole abstract trait MasterCoherenceAgent extends CoherenceAgentRole abstract class CoherencePolicy { + def nClientStates: Int + def nMasterStates: Int + def nAcquireTypes: Int + def nProbeTypes: Int + def nReleaseTypes: Int + def nGrantTypes: Int + def clientStateBits = log2Up(nClientStates) + def masterStateBits = log2Up(nMasterStates) + def acquireTypeBits = log2Up(nAcquireTypes) + def probeTypeBits = log2Up(nProbeTypes) + def releaseTypeBits = log2Up(nReleaseTypes) + def grantTypeBits = log2Up(nGrantTypes) + def isHit (cmd: Bits, state: UFix): Bool def isValid (state: UFix): Bool @@ -22,11 +35,12 @@ abstract class CoherencePolicy { def getAcquireTypeOnPrimaryMiss(cmd: Bits, state: UFix): UFix def getAcquireTypeOnSecondaryMiss(cmd: Bits, state: UFix, outstanding: Acquire): UFix + def getProbeType(a_type: UFix, global_state: UFix): UFix def getReleaseTypeOnCacheControl(cmd: Bits): Bits def getReleaseTypeOnVoluntaryWriteback(): Bits - - def getVoluntaryWriteback(addr: UFix, client_id: UFix, master_id: UFix): Release - def newRelease (incoming: Probe, state: UFix, id: UFix): Release + def getReleaseTypeOnProbe(incoming: Probe, state: UFix): Bits + def getGrantType(a_type: UFix, count: UFix): Bits + def getGrantType(rel: Release, count: UFix): Bits def messageHasData (rel: SourcedMessage): Bool def messageUpdatesDataArray (reply: Grant): Bool @@ -35,9 +49,6 @@ abstract class CoherencePolicy { def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool def isVoluntary(rel: Release): Bool def isVoluntary(gnt: Grant): Bool - def getGrantType(a_type: UFix, count: UFix): Bits - def getGrantType(rel: Release, count: UFix): Bits - def getProbeType(a_type: UFix, global_state: UFix): UFix def needsOuterRead(a_type: UFix, global_state: UFix): Bool def needsOuterWrite(a_type: UFix, global_state: UFix): Bool def needsAckReply(a_type: UFix, global_state: UFix): Bool @@ -50,11 +61,11 @@ abstract class CoherencePolicy { } trait UncachedTransactions { - def getUncachedReadAcquire(addr: UFix, id: UFix): Acquire - def getUncachedWriteAcquire(addr: UFix, id: UFix): Acquire - def getUncachedReadWordAcquire(addr: UFix, id: UFix): Acquire - def getUncachedWriteWordAcquire(addr: UFix, id: UFix, write_mask: Bits): Acquire - def getUncachedAtomicAcquire(addr: UFix, id: UFix, subword_addr: UFix, atomic_op: UFix): Acquire + def getUncachedReadAcquireType: Bits + def getUncachedWriteAcquireType: Bits + def getUncachedReadWordAcquireType: Bits + def getUncachedWriteWordAcquireType: Bits + def getUncachedAtomicAcquireType: Bits def isUncachedReadTransaction(acq: Acquire): Bool } @@ -63,7 +74,7 @@ abstract class CoherencePolicyWithUncached extends CoherencePolicy with Uncached abstract class IncoherentPolicy extends CoherencePolicy { // UNIMPLEMENTED def newStateOnProbe(incoming: Probe, state: UFix): Bits = state - def newRelease (incoming: Probe, state: UFix, id: UFix): Release = Release( UFix(0), UFix(0), UFix(0), UFix(0)) + def getReleaseTypeOnProbe(incoming: Probe, state: UFix): Bits = Bits(0) def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = Bool(false) def getGrantType(a_type: UFix, count: UFix): Bits = Bits(0) def getGrantType(rel: Release, count: UFix): Bits = Bits(0) @@ -79,10 +90,16 @@ abstract class IncoherentPolicy extends CoherencePolicy { } class ThreeStateIncoherence extends IncoherentPolicy { - val tileInvalid :: tileClean :: tileDirty :: Nil = Enum(3){ UFix() } - val acquireReadClean :: acquireReadDirty :: acquireWriteback :: Nil = Enum(3){ UFix() } - val grantVoluntaryAck :: grantData :: grantAck :: Nil = Enum(3){ UFix() } - val releaseVoluntaryInvalidateData :: releaseInvalidateAck :: Nil = Enum(2){ UFix() } + def nClientStates = 3 + def nMasterStates = 0 + def nAcquireTypes = 3 + def nProbeTypes = 0 + def nReleaseTypes = 2 + def nGrantTypes = 3 + val tileInvalid :: tileClean :: tileDirty :: Nil = Enum(nClientStates){ UFix() } + val acquireReadClean :: acquireReadDirty :: acquireWriteback :: Nil = Enum(nAcquireTypes){ UFix() } + val releaseVoluntaryInvalidateData :: releaseInvalidateAck :: Nil = Enum(nReleaseTypes){ UFix() } + val grantVoluntaryAck :: grantData :: grantAck :: Nil = Enum(nGrantTypes){ UFix() } val uncachedAcquireTypeList = List() val hasDataAcquireTypeList = List(acquireWriteback) val hasDataReleaseTypeList = List(acquireWriteback) @@ -109,7 +126,6 @@ class ThreeStateIncoherence extends IncoherentPolicy { )) } - def getVoluntaryWriteback(addr: UFix, client_id: UFix, master_id: UFix) = Release(releaseVoluntaryInvalidateData, addr, client_id, master_id) def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck @@ -133,14 +149,21 @@ class ThreeStateIncoherence extends IncoherentPolicy { } class MICoherence extends CoherencePolicyWithUncached { + def nClientStates = 2 + def nMasterStates = 2 + def nAcquireTypes = 6 + def nProbeTypes = 2 + def nReleaseTypes = 5 + def nGrantTypes = 7 - val tileInvalid :: tileValid :: Nil = Enum(2){ UFix() } - val globalInvalid :: globalValid :: Nil = Enum(2){ UFix() } + val tileInvalid :: tileValid :: Nil = Enum(nClientStates){ UFix() } + val globalInvalid :: globalValid :: Nil = Enum(nMasterStates){ UFix() } + + val acquireReadExclusive :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: Nil = Enum(nAcquireTypes){ UFix() } + val probeInvalidate :: probeCopy :: Nil = Enum(nProbeTypes){ UFix() } + val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseCopyData :: releaseInvalidateAck :: releaseCopyAck :: Nil = Enum(nReleaseTypes){ UFix() } + val grantVoluntaryAck :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: Nil = Enum(nGrantTypes){ UFix() } - val acquireReadExclusive :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: Nil = Enum(6){ UFix() } - val grantVoluntaryAck :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: Nil = Enum(7){ UFix() } - val probeInvalidate :: probeCopy :: Nil = Enum(2){ UFix() } - val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseCopyData :: releaseInvalidateAck :: releaseCopyAck :: Nil = Enum(5){ UFix() } val uncachedAcquireTypeList = List(acquireReadUncached, acquireWriteUncached, acquireReadWordUncached, acquireWriteWordUncached, acquireAtomicUncached) val hasDataAcquireTypeList = List(acquireWriteUncached, acquireWriteWordUncached, acquireAtomicUncached) val hasDataReleaseTypeList = List(releaseVoluntaryInvalidateData, releaseInvalidateData, releaseCopyData) @@ -186,12 +209,11 @@ class MICoherence extends CoherencePolicyWithUncached { )) } - def getUncachedReadAcquire(addr: UFix, id: UFix) = Acquire(acquireReadUncached, addr, id) - def getUncachedWriteAcquire(addr: UFix, id: UFix) = Acquire(acquireWriteUncached, addr, id) - def getUncachedReadWordAcquire(addr: UFix, id: UFix) = Acquire(acquireReadWordUncached, addr, id) - def getUncachedWriteWordAcquire(addr: UFix, id: UFix, write_mask: Bits) = Acquire(acquireWriteWordUncached, addr, id, write_mask) - def getUncachedAtomicAcquire(addr: UFix, id: UFix, subword_addr: UFix, atomic_op: UFix) = Acquire(acquireAtomicUncached, addr, id, subword_addr, atomic_op) - def getVoluntaryWriteback(addr: UFix, client_id: UFix, master_id: UFix) = Release(releaseVoluntaryInvalidateData, addr, client_id, master_id) + def getUncachedReadAcquireType = acquireReadUncached + def getUncachedWriteAcquireType = acquireWriteUncached + def getUncachedReadWordAcquireType = acquireReadWordUncached + def getUncachedWriteWordAcquireType = acquireWriteWordUncached + def getUncachedAtomicAcquireType = acquireAtomicUncached def isUncachedReadTransaction(acq: Acquire) = acq.a_type === acquireReadUncached def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck @@ -200,8 +222,7 @@ class MICoherence extends CoherencePolicyWithUncached { def getAcquireTypeOnSecondaryMiss(cmd: Bits, state: UFix, outstanding: Acquire): UFix = acquireReadExclusive def getReleaseTypeOnCacheControl(cmd: Bits): Bits = releaseVoluntaryInvalidateData // TODO def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV) - - def newRelease (incoming: Probe, state: UFix, id: UFix): Release = { + def getReleaseTypeOnProbe(incoming: Probe, state: UFix): Bits = { val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array( probeInvalidate -> releaseInvalidateData, probeCopy -> releaseCopyData @@ -210,7 +231,7 @@ class MICoherence extends CoherencePolicyWithUncached { probeInvalidate -> releaseInvalidateAck, probeCopy -> releaseCopyAck )) - Release( Mux(needsWriteback(state), with_data, without_data), incoming.addr, id, incoming.master_xact_id) + Mux(needsWriteback(state), with_data, without_data) } def messageHasData(msg: SourcedMessage) = msg match { @@ -270,14 +291,20 @@ class MICoherence extends CoherencePolicyWithUncached { } class MEICoherence extends CoherencePolicyWithUncached { + def nClientStates = 3 + def nMasterStates = 2 + def nAcquireTypes = 7 + def nProbeTypes = 3 + def nReleaseTypes = 7 + def nGrantTypes = 8 - val tileInvalid :: tileExclusiveClean :: tileExclusiveDirty :: Nil = Enum(3){ UFix() } - val globalInvalid :: globalExclusiveClean :: Nil = Enum(2){ UFix() } + val tileInvalid :: tileExclusiveClean :: tileExclusiveDirty :: Nil = Enum(nClientStates){ UFix() } + val globalInvalid :: globalExclusiveClean :: Nil = Enum(nMasterStates){ UFix() } - val acquireReadExclusiveClean :: acquireReadExclusiveDirty :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: Nil = Enum(7){ UFix() } - val grantVoluntaryAck :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadExclusiveAck :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: Nil = Enum(8){ UFix() } - val probeInvalidate :: probeDowngrade :: probeCopy :: Nil = Enum(3){ UFix() } - val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(7){ UFix() } + val acquireReadExclusiveClean :: acquireReadExclusiveDirty :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: Nil = Enum(nAcquireTypes){ UFix() } + val probeInvalidate :: probeDowngrade :: probeCopy :: Nil = Enum(nProbeTypes){ UFix() } + val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(nReleaseTypes){ UFix() } + val grantVoluntaryAck :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadExclusiveAck :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: Nil = Enum(nGrantTypes){ UFix() } val uncachedAcquireTypeList = List(acquireReadUncached, acquireWriteUncached, acquireReadWordUncached, acquireWriteWordUncached, acquireAtomicUncached) val hasDataAcquireTypeList = List(acquireWriteUncached, acquireWriteWordUncached, acquireAtomicUncached) @@ -331,12 +358,11 @@ class MEICoherence extends CoherencePolicyWithUncached { )) } - def getUncachedReadAcquire(addr: UFix, id: UFix) = Acquire(acquireReadUncached, addr, id) - def getUncachedWriteAcquire(addr: UFix, id: UFix) = Acquire(acquireWriteUncached, addr, id) - def getUncachedReadWordAcquire(addr: UFix, id: UFix) = Acquire(acquireReadWordUncached, addr, id) - def getUncachedWriteWordAcquire(addr: UFix, id: UFix, write_mask: Bits) = Acquire(acquireWriteWordUncached, addr, id, write_mask) - def getUncachedAtomicAcquire(addr: UFix, id: UFix, subword_addr: UFix, atomic_op: UFix) = Acquire(acquireAtomicUncached, addr, id, subword_addr, atomic_op) - def getVoluntaryWriteback(addr: UFix, client_id: UFix, master_id: UFix) = Release(releaseVoluntaryInvalidateData, addr, client_id, master_id) + def getUncachedReadAcquireType = acquireReadUncached + def getUncachedWriteAcquireType = acquireWriteUncached + def getUncachedReadWordAcquireType = acquireReadWordUncached + def getUncachedWriteWordAcquireType = acquireWriteWordUncached + def getUncachedAtomicAcquireType = acquireAtomicUncached def isUncachedReadTransaction(acq: Acquire) = acq.a_type === acquireReadUncached def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck @@ -349,8 +375,7 @@ class MEICoherence extends CoherencePolicyWithUncached { } def getReleaseTypeOnCacheControl(cmd: Bits): Bits = releaseVoluntaryInvalidateData // TODO def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV) - - def newRelease (incoming: Probe, state: UFix, id: UFix): Release = { + def getReleaseTypeOnProbe(incoming: Probe, state: UFix): Bits = { val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array( probeInvalidate -> releaseInvalidateData, probeDowngrade -> releaseDowngradeData, @@ -361,7 +386,7 @@ class MEICoherence extends CoherencePolicyWithUncached { probeDowngrade -> releaseDowngradeAck, probeCopy -> releaseCopyAck )) - Release( Mux(needsWriteback(state), with_data, without_data), incoming.addr, id, incoming.master_xact_id) + Mux(needsWriteback(state), with_data, without_data) } def messageHasData(msg: SourcedMessage) = msg match { @@ -424,14 +449,21 @@ class MEICoherence extends CoherencePolicyWithUncached { } class MSICoherence extends CoherencePolicyWithUncached { + def nClientStates = 3 + def nMasterStates = 3 + def nAcquireTypes = 7 + def nProbeTypes = 3 + def nReleaseTypes = 7 + def nGrantTypes = 9 - val tileInvalid :: tileShared :: tileExclusiveDirty :: Nil = Enum(3){ UFix() } - val globalInvalid :: globalShared :: globalExclusive :: Nil = Enum(3){ UFix() } + val tileInvalid :: tileShared :: tileExclusiveDirty :: Nil = Enum(nClientStates){ UFix() } + val globalInvalid :: globalShared :: globalExclusive :: Nil = Enum(nMasterStates){ UFix() } + + val acquireReadShared :: acquireReadExclusive :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: Nil = Enum(nAcquireTypes){ UFix() } + val probeInvalidate :: probeDowngrade :: probeCopy :: Nil = Enum(nProbeTypes){ UFix() } + val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(nReleaseTypes){ UFix() } + val grantVoluntaryAck :: grantReadShared :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadExclusiveAck :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: Nil = Enum(nGrantTypes){ UFix() } - val acquireReadShared :: acquireReadExclusive :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: Nil = Enum(7){ UFix() } - val grantVoluntaryAck :: grantReadShared :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadExclusiveAck :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: Nil = Enum(9){ UFix() } - val probeInvalidate :: probeDowngrade :: probeCopy :: Nil = Enum(3){ UFix() } - val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(7){ UFix() } val uncachedAcquireTypeList = List(acquireReadUncached, acquireWriteUncached, acquireReadWordUncached, acquireWriteWordUncached, acquireAtomicUncached) val hasDataAcquireTypeList = List(acquireWriteUncached, acquireWriteWordUncached, acquireAtomicUncached) val hasDataReleaseTypeList = List(releaseVoluntaryInvalidateData, releaseInvalidateData, releaseDowngradeData, releaseCopyData) @@ -490,12 +522,11 @@ class MSICoherence extends CoherencePolicyWithUncached { )) } - def getUncachedReadAcquire(addr: UFix, id: UFix) = Acquire(acquireReadUncached, addr, id) - def getUncachedWriteAcquire(addr: UFix, id: UFix) = Acquire(acquireWriteUncached, addr, id) - def getUncachedReadWordAcquire(addr: UFix, id: UFix) = Acquire(acquireReadWordUncached, addr, id) - def getUncachedWriteWordAcquire(addr: UFix, id: UFix, write_mask: Bits) = Acquire(acquireWriteWordUncached, addr, id, write_mask) - def getUncachedAtomicAcquire(addr: UFix, id: UFix, subword_addr: UFix, atomic_op: UFix) = Acquire(acquireAtomicUncached, addr, id, subword_addr, atomic_op) - def getVoluntaryWriteback(addr: UFix, client_id: UFix, master_id: UFix) = Release(releaseVoluntaryInvalidateData, addr, client_id, master_id) + def getUncachedReadAcquireType = acquireReadUncached + def getUncachedWriteAcquireType = acquireWriteUncached + def getUncachedReadWordAcquireType = acquireReadWordUncached + def getUncachedWriteWordAcquireType = acquireWriteWordUncached + def getUncachedAtomicAcquireType = acquireAtomicUncached def isUncachedReadTransaction(acq: Acquire) = acq.a_type === acquireReadUncached def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck @@ -508,8 +539,7 @@ class MSICoherence extends CoherencePolicyWithUncached { } def getReleaseTypeOnCacheControl(cmd: Bits): Bits = releaseVoluntaryInvalidateData // TODO def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV) - - def newRelease (incoming: Probe, state: UFix, id: UFix): Release = { + def getReleaseTypeOnProbe(incoming: Probe, state: UFix): Bits = { val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array( probeInvalidate -> releaseInvalidateData, probeDowngrade -> releaseDowngradeData, @@ -520,7 +550,7 @@ class MSICoherence extends CoherencePolicyWithUncached { probeDowngrade -> releaseDowngradeAck, probeCopy -> releaseCopyAck )) - Release( Mux(needsWriteback(state), with_data, without_data), incoming.addr, id, incoming.master_xact_id) + Mux(needsWriteback(state), with_data, without_data) } def messageHasData(msg: SourcedMessage) = msg match { @@ -580,14 +610,20 @@ class MSICoherence extends CoherencePolicyWithUncached { } class MESICoherence extends CoherencePolicyWithUncached { + def nClientStates = 4 + def nMasterStates = 3 + def nAcquireTypes = 7 + def nProbeTypes = 3 + def nReleaseTypes = 7 + def nGrantTypes = 9 - val tileInvalid :: tileShared :: tileExclusiveClean :: tileExclusiveDirty :: Nil = Enum(4){ UFix() } - val globalInvalid :: globalShared :: globalExclusiveClean :: Nil = Enum(3){ UFix() } + val tileInvalid :: tileShared :: tileExclusiveClean :: tileExclusiveDirty :: Nil = Enum(nClientStates){ UFix() } + val globalInvalid :: globalShared :: globalExclusiveClean :: Nil = Enum(nMasterStates){ UFix() } - val acquireReadShared :: acquireReadExclusive :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: Nil = Enum(7){ UFix() } - val grantVoluntaryAck :: grantReadShared :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadExclusiveAck :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: Nil = Enum(9){ UFix() } - val probeInvalidate :: probeDowngrade :: probeCopy :: Nil = Enum(3){ UFix() } - val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(7){ UFix() } + val acquireReadShared :: acquireReadExclusive :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: Nil = Enum(nAcquireTypes){ UFix() } + val probeInvalidate :: probeDowngrade :: probeCopy :: Nil = Enum(nProbeTypes){ UFix() } + val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(nReleaseTypes){ UFix() } + val grantVoluntaryAck :: grantReadShared :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadExclusiveAck :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: Nil = Enum(nGrantTypes){ UFix() } val uncachedAcquireTypeList = List(acquireReadUncached, acquireWriteUncached, acquireReadWordUncached, acquireWriteWordUncached, acquireAtomicUncached) val hasDataAcquireTypeList = List(acquireWriteUncached, acquireWriteWordUncached, acquireAtomicUncached) @@ -647,12 +683,11 @@ class MESICoherence extends CoherencePolicyWithUncached { )) } - def getUncachedReadAcquire(addr: UFix, id: UFix) = Acquire(acquireReadUncached, addr, id) - def getUncachedWriteAcquire(addr: UFix, id: UFix) = Acquire(acquireWriteUncached, addr, id) - def getUncachedReadWordAcquire(addr: UFix, id: UFix) = Acquire(acquireReadWordUncached, addr, id) - def getUncachedWriteWordAcquire(addr: UFix, id: UFix, write_mask: Bits) = Acquire(acquireWriteWordUncached, addr, id, write_mask) - def getUncachedAtomicAcquire(addr: UFix, id: UFix, subword_addr: UFix, atomic_op: UFix) = Acquire(acquireAtomicUncached, addr, id, subword_addr, atomic_op) - def getVoluntaryWriteback(addr: UFix, client_id: UFix, master_id: UFix) = Release(releaseVoluntaryInvalidateData, addr, client_id, master_id) + def getUncachedReadAcquireType = acquireReadUncached + def getUncachedWriteAcquireType = acquireWriteUncached + def getUncachedReadWordAcquireType = acquireReadWordUncached + def getUncachedWriteWordAcquireType = acquireWriteWordUncached + def getUncachedAtomicAcquireType = acquireAtomicUncached def isUncachedReadTransaction(acq: Acquire) = acq.a_type === acquireReadUncached def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck @@ -665,8 +700,7 @@ class MESICoherence extends CoherencePolicyWithUncached { } def getReleaseTypeOnCacheControl(cmd: Bits): Bits = releaseVoluntaryInvalidateData // TODO def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV) - - def newRelease (incoming: Probe, state: UFix, id: UFix): Release = { + def getReleaseTypeOnProbe(incoming: Probe, state: UFix): Bits = { val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array( probeInvalidate -> releaseInvalidateData, probeDowngrade -> releaseDowngradeData, @@ -677,7 +711,7 @@ class MESICoherence extends CoherencePolicyWithUncached { probeDowngrade -> releaseDowngradeAck, probeCopy -> releaseCopyAck )) - Release( Mux(needsWriteback(state), with_data, without_data), incoming.addr, id, incoming.master_xact_id) + Mux(needsWriteback(state), with_data, without_data) } def messageHasData(msg: SourcedMessage) = msg match { @@ -741,13 +775,19 @@ class MESICoherence extends CoherencePolicyWithUncached { } class MigratoryCoherence extends CoherencePolicyWithUncached { + def nClientStates = 7 + def nMasterStates = 0 + def nAcquireTypes = 8 + def nProbeTypes = 4 + def nReleaseTypes = 11 + def nGrantTypes = 9 - val tileInvalid :: tileShared :: tileExclusiveClean :: tileExclusiveDirty :: tileSharedByTwo :: tileMigratoryClean :: tileMigratoryDirty :: Nil = Enum(7){ UFix() } + val tileInvalid :: tileShared :: tileExclusiveClean :: tileExclusiveDirty :: tileSharedByTwo :: tileMigratoryClean :: tileMigratoryDirty :: Nil = Enum(nClientStates){ UFix() } - val acquireReadShared :: acquireReadExclusive :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: acquireInvalidateOthers :: Nil = Enum(8){ UFix() } - val grantVoluntaryAck :: grantReadShared :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadExclusiveAck :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: grantReadMigratory :: Nil = Enum(10){ UFix() } - val probeInvalidate :: probeDowngrade :: probeCopy :: probeInvalidateOthers :: Nil = Enum(4){ UFix() } - val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: releaseDowngradeDataMigratory :: releaseDowngradeAckHasCopy :: releaseInvalidateDataMigratory :: releaseInvalidateAckMigratory :: Nil = Enum(11){ UFix() } + val acquireReadShared :: acquireReadExclusive :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: acquireInvalidateOthers :: Nil = Enum(nAcquireTypes){ UFix() } + val probeInvalidate :: probeDowngrade :: probeCopy :: probeInvalidateOthers :: Nil = Enum(nProbeTypes){ UFix() } + val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: releaseDowngradeDataMigratory :: releaseDowngradeAckHasCopy :: releaseInvalidateDataMigratory :: releaseInvalidateAckMigratory :: Nil = Enum(nReleaseTypes){ UFix() } + val grantVoluntaryAck :: grantReadShared :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadExclusiveAck :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: grantReadMigratory :: Nil = Enum(nGrantTypes){ UFix() } val uncachedAcquireTypeList = List(acquireReadUncached, acquireWriteUncached, acquireReadWordUncached, acquireWriteWordUncached, acquireAtomicUncached) val hasDataAcquireTypeList = List(acquireWriteUncached, acquireWriteWordUncached, acquireAtomicUncached) @@ -820,12 +860,11 @@ class MigratoryCoherence extends CoherencePolicyWithUncached { )) } - def getUncachedReadAcquire(addr: UFix, id: UFix) = Acquire(acquireReadUncached, addr, id) - def getUncachedWriteAcquire(addr: UFix, id: UFix) = Acquire(acquireWriteUncached, addr, id) - def getUncachedReadWordAcquire(addr: UFix, id: UFix) = Acquire(acquireReadWordUncached, addr, id) - def getUncachedWriteWordAcquire(addr: UFix, id: UFix, write_mask: Bits) = Acquire(acquireWriteWordUncached, addr, id, write_mask) - def getUncachedAtomicAcquire(addr: UFix, id: UFix, subword_addr: UFix, atomic_op: UFix) = Acquire(acquireAtomicUncached, addr, id, subword_addr, atomic_op) - def getVoluntaryWriteback(addr: UFix, client_id: UFix, master_id: UFix) = Release(releaseVoluntaryInvalidateData, addr, client_id, master_id) + def getUncachedReadAcquireType = acquireReadUncached + def getUncachedWriteAcquireType = acquireWriteUncached + def getUncachedReadWordAcquireType = acquireReadWordUncached + def getUncachedWriteWordAcquireType = acquireWriteWordUncached + def getUncachedAtomicAcquireType = acquireAtomicUncached def isUncachedReadTransaction(acq: Acquire) = acq.a_type === acquireReadUncached def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck @@ -838,22 +877,20 @@ class MigratoryCoherence extends CoherencePolicyWithUncached { } def getReleaseTypeOnCacheControl(cmd: Bits): Bits = releaseVoluntaryInvalidateData // TODO def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV) - - def newRelease (incoming: Probe, state: UFix, id: UFix): Release = { - //Assert( incoming.p_type === probeInvalidateOthers && needsWriteback(state), "Bad probe request type, should be impossible.") + def getReleaseTypeOnProbe(incoming: Probe, state: UFix): Bits = { val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array( - probeInvalidate -> Mux(uFixListContains(List(tileExclusiveDirty, tileMigratoryDirty), state), + probeInvalidate -> Mux(uFixListContains(List(tileExclusiveDirty, tileMigratoryDirty), state), releaseInvalidateDataMigratory, releaseInvalidateData), - probeDowngrade -> Mux(state === tileMigratoryDirty, releaseDowngradeDataMigratory, releaseDowngradeData), - probeCopy -> releaseCopyData + probeDowngrade -> Mux(state === tileMigratoryDirty, releaseDowngradeDataMigratory, releaseDowngradeData), + probeCopy -> releaseCopyData )) val without_data = MuxLookup(incoming.p_type, releaseInvalidateAck, Array( - probeInvalidate -> Mux(tileExclusiveClean === state, releaseInvalidateAckMigratory, releaseInvalidateAck), + probeInvalidate -> Mux(tileExclusiveClean === state, releaseInvalidateAckMigratory, releaseInvalidateAck), probeInvalidateOthers -> Mux(state === tileSharedByTwo, releaseInvalidateAckMigratory, releaseInvalidateAck), probeDowngrade -> Mux(state != tileInvalid, releaseDowngradeAckHasCopy, releaseDowngradeAck), probeCopy -> releaseCopyAck )) - Release( Mux(needsWriteback(state), with_data, without_data), incoming.addr, id, incoming.master_xact_id) + Mux(needsWriteback(state), with_data, without_data) } def messageHasData(msg: SourcedMessage) = msg match { diff --git a/uncore/src/consts.scala b/uncore/src/consts.scala index 4e3c814e..15bfee4d 100644 --- a/uncore/src/consts.scala +++ b/uncore/src/consts.scala @@ -4,38 +4,6 @@ package constants import Chisel._ import scala.math.max -abstract trait CoherenceConfigConstants { - val ENABLE_SHARING: Boolean - val ENABLE_CLEAN_EXCLUSIVE: Boolean -} - -trait UncoreConstants { - val NGLOBAL_ACQ_XACTS = 8 - val NGLOBAL_REL_XACTS = 1 - val MASTER_XACT_ID_MAX_BITS = log2Up(NGLOBAL_ACQ_XACTS+NGLOBAL_REL_XACTS) - val CACHE_DATA_SIZE_IN_BYTES = 1 << 6 -} - -trait CacheConstants extends UncoreConstants { - val OFFSET_BITS = log2Up(CACHE_DATA_SIZE_IN_BYTES) -} - -trait TileLinkTypeConstants { - val ACQUIRE_TYPE_MAX_BITS = 2 - val GRANT_TYPE_MAX_BITS = 3 - val PROBE_TYPE_MAX_BITS = 2 - val RELEASE_TYPE_MAX_BITS = 3 -} - -trait TileLinkSizeConstants extends - TileLinkTypeConstants -{ - val CLIENT_XACT_ID_MAX_BITS = 10 - val ACQUIRE_WRITE_MASK_BITS = 6 - val ACQUIRE_SUBWORD_ADDR_BITS = 3 - val ACQUIRE_ATOMIC_OP_BITS = 4 -} - object MemoryOpConstants extends MemoryOpConstants trait MemoryOpConstants { val MT_X = Bits("b???", 3); @@ -74,15 +42,6 @@ trait MemoryOpConstants { def isWriteIntent(cmd: Bits) = isWrite(cmd) || cmd === M_PFW || cmd === M_XLR } -trait MemoryInterfaceConstants extends - UncoreConstants with - TileLinkSizeConstants -{ - val MEM_TAG_BITS = max(CLIENT_XACT_ID_MAX_BITS, MASTER_XACT_ID_MAX_BITS) - val MEM_DATA_BITS = 128 - val REFILL_CYCLES = CACHE_DATA_SIZE_IN_BYTES*8/MEM_DATA_BITS -} - object AddressConstants extends AddressConstants trait AddressConstants { val PADDR_BITS = 32 @@ -94,3 +53,23 @@ trait AddressConstants { val PERM_BITS = 6; } +trait CacheConstants { + val CACHE_DATA_SIZE_IN_BYTES = 1 << 6 + val OFFSET_BITS = log2Up(CACHE_DATA_SIZE_IN_BYTES) +} + +trait TileLinkSizeConstants { + val ACQUIRE_WRITE_MASK_BITS = 6 + val ACQUIRE_SUBWORD_ADDR_BITS = 3 + val ACQUIRE_ATOMIC_OP_BITS = 4 +} + +trait MemoryInterfaceConstants extends + CacheConstants with + AddressConstants +{ + val MEM_TAG_BITS = 5 + val MEM_DATA_BITS = 128 + val REFILL_CYCLES = CACHE_DATA_SIZE_IN_BYTES*8/MEM_DATA_BITS + val MEM_ADDR_BITS = PADDR_BITS - OFFSET_BITS +} diff --git a/uncore/src/llc.scala b/uncore/src/llc.scala index 6b0c77f2..cb6465c5 100644 --- a/uncore/src/llc.scala +++ b/uncore/src/llc.scala @@ -86,10 +86,10 @@ class LLCMSHRFile(sets: Int, ways: Int, outstanding: Int) extends Component val cpu = (new FIFOIO) { new MemReqCmd }.flip val repl_way = UFix(INPUT, log2Up(ways)) val repl_dirty = Bool(INPUT) - val repl_tag = UFix(INPUT, PADDR_BITS - OFFSET_BITS - log2Up(sets)) + val repl_tag = UFix(INPUT, MEM_ADDR_BITS - log2Up(sets)) val data = (new FIFOIO) { new LLCDataReq(ways) } val tag = (new FIFOIO) { new Bundle { - val addr = UFix(width = PADDR_BITS - OFFSET_BITS) + val addr = UFix(width = MEM_ADDR_BITS) val way = UFix(width = log2Up(ways)) } } val mem = new ioMemPipe @@ -105,7 +105,7 @@ class LLCMSHRFile(sets: Int, ways: Int, outstanding: Int) extends Component val refillCount = UFix(width = log2Up(REFILL_CYCLES)) val requested = Bool() val old_dirty = Bool() - val old_tag = UFix(width = PADDR_BITS - OFFSET_BITS - log2Up(sets)) + val old_tag = UFix(width = MEM_ADDR_BITS - log2Up(sets)) val wb_busy = Bool() override def clone = new MSHR().asInstanceOf[this.type] @@ -184,7 +184,7 @@ class LLCMSHRFile(sets: Int, ways: Int, outstanding: Int) extends Component class LLCWriteback(requestors: Int) extends Component { val io = new Bundle { - val req = Vec(requestors) { (new FIFOIO) { UFix(width = PADDR_BITS - OFFSET_BITS) }.flip } + val req = Vec(requestors) { (new FIFOIO) { UFix(width = MEM_ADDR_BITS) }.flip } val data = Vec(requestors) { (new FIFOIO) { new MemData }.flip } val mem = new ioMemPipe } @@ -235,7 +235,7 @@ class LLCData(latency: Int, sets: Int, ways: Int, leaf: Mem[Bits]) extends Compo val io = new Bundle { val req = (new FIFOIO) { new LLCDataReq(ways) }.flip val req_data = (new FIFOIO) { new MemData }.flip - val writeback = (new FIFOIO) { UFix(width = PADDR_BITS - OFFSET_BITS) } + val writeback = (new FIFOIO) { UFix(width = MEM_ADDR_BITS) } val writeback_data = (new FIFOIO) { new MemData } val resp = (new FIFOIO) { new MemResp } val mem_resp = (new PipeIO) { new MemResp }.flip @@ -348,7 +348,7 @@ class DRAMSideLLC(sets: Int, ways: Int, outstanding: Int, tagLeaf: Mem[Bits], da val mem = new ioMemPipe } - val tagWidth = PADDR_BITS - OFFSET_BITS - log2Up(sets) + val tagWidth = MEM_ADDR_BITS - log2Up(sets) val metaWidth = tagWidth + 2 // valid + dirty val memCmdArb = (new Arbiter(2)) { new MemReqCmd } diff --git a/uncore/src/memserdes.scala b/uncore/src/memserdes.scala index c7c8e773..b1272b28 100644 --- a/uncore/src/memserdes.scala +++ b/uncore/src/memserdes.scala @@ -2,6 +2,33 @@ package uncore import Chisel._ import scala.math._ +class MemData extends Bundle { + val data = Bits(width = MEM_DATA_BITS) +} + +class MemReqCmd extends Bundle { + val addr = UFix(width = MEM_ADDR_BITS) + val rw = Bool() + val tag = Bits(width = MEM_TAG_BITS) +} + +class MemResp extends Bundle { + val tag = Bits(width = MEM_TAG_BITS) + val data = Bits(width = MEM_DATA_BITS) +} + +class ioMem extends Bundle { + val req_cmd = (new FIFOIO) { new MemReqCmd() } + val req_data = (new FIFOIO) { new MemData() } + val resp = (new FIFOIO) { new MemResp() }.flip +} + +class ioMemPipe extends Bundle { + val req_cmd = (new FIFOIO) { new MemReqCmd() } + val req_data = (new FIFOIO) { new MemData() } + val resp = (new PipeIO) { new MemResp() }.flip +} + class ioMemSerialized(w: Int) extends Bundle { val req = (new FIFOIO) { Bits(width = w) } diff --git a/uncore/src/package.scala b/uncore/src/package.scala index a92f739c..4ac83d0b 100644 --- a/uncore/src/package.scala +++ b/uncore/src/package.scala @@ -1,8 +1,7 @@ package object uncore extends uncore.constants.MemoryOpConstants with - uncore.constants.MemoryInterfaceConstants with - uncore.constants.CacheConstants with - uncore.constants.AddressConstants + uncore.constants.TileLinkSizeConstants with + uncore.constants.MemoryInterfaceConstants { implicit def toOption[A](a: A) = Option(a) } diff --git a/uncore/src/tilelink.scala b/uncore/src/tilelink.scala index 3621e73b..6f7e6175 100644 --- a/uncore/src/tilelink.scala +++ b/uncore/src/tilelink.scala @@ -1,99 +1,86 @@ package uncore import Chisel._ -trait HasPhysicalAddress extends Bundle { +case class TileLinkConfiguration(co: CoherencePolicyWithUncached, ln: LogicalNetworkConfiguration, masterXactIdBits: Int, clientXactIdBits: Int, dataBits: Int) + +abstract trait TileLinkSubBundle extends Bundle { + implicit val conf: TileLinkConfiguration +} + +trait HasPhysicalAddress extends TileLinkSubBundle { val addr = UFix(width = PADDR_BITS - OFFSET_BITS) } -trait HasClientTransactionId extends Bundle { - val client_xact_id = Bits(width = CLIENT_XACT_ID_MAX_BITS) +trait HasClientTransactionId extends TileLinkSubBundle { + val client_xact_id = Bits(width = conf.clientXactIdBits) } -trait HasMasterTransactionId extends Bundle { - val master_xact_id = Bits(width = MASTER_XACT_ID_MAX_BITS) +trait HasMasterTransactionId extends TileLinkSubBundle { + val master_xact_id = Bits(width = conf.masterXactIdBits) } -trait HasMemData extends Bundle { - val data = Bits(width = MEM_DATA_BITS) -} - -class MemData extends Bundle with HasMemData - -class MemReqCmd extends Bundle with HasPhysicalAddress { - val rw = Bool() - val tag = Bits(width = MEM_TAG_BITS) -} - -class MemResp extends Bundle with HasMemData { - val tag = Bits(width = MEM_TAG_BITS) -} - -class ioMem extends Bundle { - val req_cmd = (new FIFOIO) { new MemReqCmd() } - val req_data = (new FIFOIO) { new MemData() } - val resp = (new FIFOIO) { new MemResp() }.flip -} - -class ioMemPipe extends Bundle { - val req_cmd = (new FIFOIO) { new MemReqCmd() } - val req_data = (new FIFOIO) { new MemData() } - val resp = (new PipeIO) { new MemResp() }.flip +trait HasTileLinkData extends TileLinkSubBundle { + val data = Bits(width = conf.dataBits) } trait SourcedMessage extends Bundle trait ClientSourcedMessage extends SourcedMessage trait MasterSourcedMessage extends SourcedMessage -class Acquire extends ClientSourcedMessage with HasPhysicalAddress with HasClientTransactionId { - val a_type = Bits(width = ACQUIRE_TYPE_MAX_BITS) - 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) -} - object Acquire { - def apply(a_type: Bits, addr: UFix, client_xact_id: UFix) = { + def apply(a_type: Bits, addr: UFix, client_xact_id: UFix)(implicit conf: TileLinkConfiguration) = { val acq = new Acquire acq.a_type := a_type acq.addr := addr acq.client_xact_id := client_xact_id - acq.write_mask := Bits(0, width = ACQUIRE_WRITE_MASK_BITS) - acq.subword_addr := Bits(0, width = ACQUIRE_SUBWORD_ADDR_BITS) - acq.atomic_opcode := Bits(0, width = ACQUIRE_ATOMIC_OP_BITS) + acq.write_mask := Bits(0) + acq.subword_addr := Bits(0) + acq.atomic_opcode := Bits(0) acq } - def apply(a_type: Bits, addr: UFix, client_xact_id: UFix, write_mask: Bits) = { + def apply(a_type: Bits, addr: UFix, client_xact_id: UFix, write_mask: Bits)(implicit conf: TileLinkConfiguration) = { val acq = new Acquire acq.a_type := a_type acq.addr := addr acq.client_xact_id := client_xact_id acq.write_mask := write_mask - acq.subword_addr := Bits(0, width = ACQUIRE_SUBWORD_ADDR_BITS) - acq.atomic_opcode := Bits(0, width = ACQUIRE_ATOMIC_OP_BITS) + acq.subword_addr := Bits(0) + acq.atomic_opcode := Bits(0) acq } - def apply(a_type: Bits, addr: UFix, client_xact_id: UFix, subword_addr: UFix, atomic_opcode: UFix) = { + def apply(a_type: Bits, addr: UFix, client_xact_id: UFix, subword_addr: UFix, atomic_opcode: UFix)(implicit conf: TileLinkConfiguration) = { val acq = new Acquire acq.a_type := a_type acq.addr := addr acq.client_xact_id := client_xact_id acq.subword_addr := subword_addr acq.atomic_opcode := atomic_opcode - acq.write_mask := Bits(0, width = ACQUIRE_WRITE_MASK_BITS) + acq.write_mask := Bits(0) acq } } +class Acquire(implicit val conf: TileLinkConfiguration) extends ClientSourcedMessage with HasPhysicalAddress with HasClientTransactionId { + val a_type = Bits(width = conf.co.acquireTypeBits) + 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) + override def clone = { (new Acquire).asInstanceOf[this.type] } +} -class AcquireData extends ClientSourcedMessage with HasMemData -class Probe extends MasterSourcedMessage with HasPhysicalAddress with HasMasterTransactionId { - val p_type = Bits(width = PROBE_TYPE_MAX_BITS) +class AcquireData(implicit val conf: TileLinkConfiguration) extends ClientSourcedMessage with HasTileLinkData { + override def clone = { (new AcquireData).asInstanceOf[this.type] } +} + +class Probe(implicit val conf: TileLinkConfiguration) extends MasterSourcedMessage with HasPhysicalAddress with HasMasterTransactionId { + val p_type = Bits(width = conf.co.probeTypeBits) + override def clone = { (new Probe).asInstanceOf[this.type] } } object Release { - def apply(r_type: Bits, addr: UFix, client_xact_id: UFix, master_xact_id: UFix) = { + def apply(r_type: Bits, addr: UFix, client_xact_id: UFix, master_xact_id: UFix)(implicit conf: TileLinkConfiguration) = { val rel = new Release rel.r_type := r_type rel.addr := addr @@ -102,17 +89,24 @@ object Release rel } } -class Release extends ClientSourcedMessage with HasPhysicalAddress with HasClientTransactionId with HasMasterTransactionId { - val r_type = Bits(width = RELEASE_TYPE_MAX_BITS) +class Release(implicit val conf: TileLinkConfiguration) extends ClientSourcedMessage with HasPhysicalAddress with HasClientTransactionId with HasMasterTransactionId { + val r_type = Bits(width = conf.co.releaseTypeBits) + override def clone = { (new Release).asInstanceOf[this.type] } } -class ReleaseData extends ClientSourcedMessage with HasMemData - -class Grant extends MasterSourcedMessage with HasMemData with HasClientTransactionId with HasMasterTransactionId { - val g_type = Bits(width = GRANT_TYPE_MAX_BITS) +class ReleaseData(implicit val conf: TileLinkConfiguration) extends ClientSourcedMessage with HasTileLinkData { + override def clone = { (new ReleaseData).asInstanceOf[this.type] } +} + +class Grant(implicit val conf: TileLinkConfiguration) extends MasterSourcedMessage with HasTileLinkData with HasClientTransactionId with HasMasterTransactionId { + val g_type = Bits(width = conf.co.grantTypeBits) + override def clone = { (new Grant).asInstanceOf[this.type] } +} + +class GrantAck(implicit val conf: TileLinkConfiguration) extends ClientSourcedMessage with HasMasterTransactionId { + override def clone = { (new GrantAck).asInstanceOf[this.type] } } -class GrantAck extends ClientSourcedMessage with HasMasterTransactionId trait DirectionalIO trait ClientSourcedIO extends DirectionalIO @@ -132,14 +126,15 @@ class MasterSourcedDataIO[M <: Data, D <: Data]()(meta: => M, data: => D) exten override def clone = { new MasterSourcedDataIO()(meta,data).asInstanceOf[this.type] } } -class UncachedTileLinkIO(implicit conf: LogicalNetworkConfiguration) extends Bundle { +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)) override def clone = { new UncachedTileLinkIO().asInstanceOf[this.type] } } -class TileLinkIO(implicit conf: LogicalNetworkConfiguration) extends UncachedTileLinkIO()(conf) { +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)) override def clone = { new TileLinkIO().asInstanceOf[this.type] } @@ -154,7 +149,8 @@ abstract class UncachedTileLinkIOArbiter(n: Int, co: CoherencePolicy)(implicit c } */ -class UncachedTileLinkIOArbiterThatAppendsArbiterId(n: Int, co: CoherencePolicy)(implicit conf: LogicalNetworkConfiguration) extends Component { +class UncachedTileLinkIOArbiterThatAppendsArbiterId(n: Int)(implicit conf: TileLinkConfiguration) extends Component { + implicit val (ln, co) = (conf.ln, conf.co) def acquireClientXactId(in: Acquire, id: Int) = Cat(in.client_xact_id, UFix(id, log2Up(n))) def grantClientXactId(in: Grant) = in.client_xact_id >> UFix(log2Up(n)) def arbIdx(in: Grant) = in.client_xact_id(log2Up(n)-1,0).toUFix @@ -190,7 +186,8 @@ class UncachedTileLinkIOArbiterThatAppendsArbiterId(n: Int, co: CoherencePolicy) } } -class UncachedTileLinkIOArbiterThatPassesId(n: Int, co: CoherencePolicy)(implicit conf: LogicalNetworkConfiguration) extends Component { +class UncachedTileLinkIOArbiterThatPassesId(n: Int)(implicit conf: TileLinkConfiguration) extends Component { + implicit val (ln, co) = (conf.ln, conf.co) def acquireClientXactId(in: Acquire, id: Int) = in.client_xact_id def grantClientXactId(in: Grant) = in.client_xact_id def arbIdx(in: Grant): UFix = in.client_xact_id @@ -226,7 +223,8 @@ class UncachedTileLinkIOArbiterThatPassesId(n: Int, co: CoherencePolicy)(implici } } -class UncachedTileLinkIOArbiterThatUsesNewId(n: Int, co: CoherencePolicy)(implicit conf: LogicalNetworkConfiguration) extends Component { +class UncachedTileLinkIOArbiterThatUsesNewId(n: Int)(implicit conf: TileLinkConfiguration) extends Component { + implicit val (ln, co) = (conf.ln, conf.co) def acquireClientXactId(in: Acquire, id: Int) = UFix(id, log2Up(n)) def grantClientXactId(in: Grant) = UFix(0) // DNC def arbIdx(in: Grant) = in.client_xact_id diff --git a/uncore/src/uncore.scala b/uncore/src/uncore.scala index 5f87f724..60e100e0 100644 --- a/uncore/src/uncore.scala +++ b/uncore/src/uncore.scala @@ -1,30 +1,26 @@ package uncore import Chisel._ -class TrackerDependency(implicit conf: UncoreConfiguration) extends Bundle { - val tracker_id = Bits(width = MASTER_XACT_ID_MAX_BITS) - val data_src_id = Bits(width = conf.ln.idBits) - override def clone = { new TrackerDependency().asInstanceOf[this.type] } -} - -case class UncoreConfiguration(co: CoherencePolicyWithUncached, ln: LogicalNetworkConfiguration) - -abstract class CoherenceAgent(implicit conf: LogicalNetworkConfiguration) extends Component with MasterCoherenceAgent { +abstract class CoherenceAgent(implicit conf: TileLinkConfiguration) extends Component with MasterCoherenceAgent { val io = new Bundle { val client = (new TileLinkIO).flip val master = new UncachedTileLinkIO - val incoherent = Vec(conf.nClients) { Bool() }.asInput + val incoherent = Vec(conf.ln.nClients) { Bool() }.asInput } } -class L2CoherenceAgent(bankId: Int)(implicit conf: UncoreConfiguration) extends CoherenceAgent()(conf.ln) +case class L2CoherenceAgentConfiguration(tl: TileLinkConfiguration, nReleaseTransactions: Int, nAcquireTransactions: Int) + +class L2CoherenceAgent(bankId: Int)(implicit conf: L2CoherenceAgentConfiguration) extends CoherenceAgent()(conf.tl) { - implicit val lnConf = conf.ln - val co = conf.co - //require(conf.ln.nClients < NGLOBAL_REL_XACTS) //TODO: handle in config - val trackerList = (0 until NGLOBAL_REL_XACTS).map(new VoluntaryReleaseTracker(_, bankId)) ++ - (NGLOBAL_REL_XACTS until NGLOBAL_REL_XACTS + NGLOBAL_ACQ_XACTS).map(new AcquireTracker(_, bankId)) + implicit val (tl, ln, co) = (conf.tl, conf.tl.ln, conf.tl.co) + + // Create SHRs for outstanding transactions + val nTrackers = conf.nReleaseTransactions + conf.nAcquireTransactions + val trackerList = (0 until conf.nReleaseTransactions).map(new VoluntaryReleaseTracker(_, bankId)) ++ + (conf.nReleaseTransactions until nTrackers).map(new AcquireTracker(_, bankId)) + // Propagate incoherence flags trackerList.map(_.io.tile_incoherent := io.incoherent.toBits) // Handle acquire transaction initiation @@ -81,32 +77,31 @@ class L2CoherenceAgent(bankId: Int)(implicit conf: UncoreConfiguration) extends ack.ready := Bool(true) // Create an arbiter for the one memory port - val outer_arb = new UncachedTileLinkIOArbiterThatPassesId(trackerList.size, conf.co) + val outer_arb = new UncachedTileLinkIOArbiterThatPassesId(trackerList.size) outer_arb.io.in zip trackerList map { case(arb, t) => arb <> t.io.master } io.master <> outer_arb.io.out } -abstract class XactTracker()(implicit conf: UncoreConfiguration) extends Component with OuterRequestGenerator { - val co = conf.co - implicit val ln = conf.ln +abstract class XactTracker()(implicit conf: L2CoherenceAgentConfiguration) extends Component with OuterRequestGenerator { + implicit val (tl, ln, co) = (conf.tl, conf.tl.ln, conf.tl.co) val io = new Bundle { val client = (new TileLinkIO).flip val master = new UncachedTileLinkIO - val tile_incoherent = Bits(INPUT, conf.ln.nClients) + val tile_incoherent = Bits(INPUT, ln.nClients) val has_acquire_conflict = Bool(OUTPUT) val has_release_conflict = Bool(OUTPUT) } } -class VoluntaryReleaseTracker(trackerId: Int, bankId: Int)(implicit conf: UncoreConfiguration) extends XactTracker()(conf) { +class VoluntaryReleaseTracker(trackerId: Int, bankId: Int)(implicit conf: L2CoherenceAgentConfiguration) extends XactTracker()(conf) { val s_idle :: s_mem :: s_ack :: s_busy :: Nil = Enum(4){ UFix() } val state = Reg(resetVal = s_idle) val xact = Reg{ new Release } - val init_client_id_ = Reg(resetVal = UFix(0, width = log2Up(conf.ln.nClients))) + val init_client_id_ = Reg(resetVal = UFix(0, width = log2Up(ln.nClients))) val release_data_needs_write = Reg(resetVal = Bool(false)) val mem_cmd_sent = Reg(resetVal = Bool(false)) - val cmd_to_write = co.getUncachedWriteAcquire(xact.addr, UFix(trackerId)) + val cmd_to_write = Acquire(co.getUncachedWriteAcquireType, xact.addr, UFix(trackerId)) io.has_acquire_conflict := Bool(false) io.has_release_conflict := co.isCoherenceConflict(xact.addr, io.client.release.meta.bits.payload.addr) && (state != s_idle) @@ -163,38 +158,38 @@ class VoluntaryReleaseTracker(trackerId: Int, bankId: Int)(implicit conf: Uncore } } -class AcquireTracker(trackerId: Int, bankId: Int)(implicit conf: UncoreConfiguration) extends XactTracker()(conf) { +class AcquireTracker(trackerId: Int, bankId: Int)(implicit conf: L2CoherenceAgentConfiguration) extends XactTracker()(conf) { val s_idle :: s_ack :: s_mem :: s_probe :: s_busy :: Nil = Enum(5){ UFix() } val state = Reg(resetVal = s_idle) val xact = Reg{ new Acquire } - val init_client_id_ = Reg(resetVal = UFix(0, width = log2Up(conf.ln.nClients))) - val release_data_client_id = Reg(resetVal = UFix(0, width = log2Up(conf.ln.nClients))) + val init_client_id_ = Reg(resetVal = UFix(0, width = log2Up(ln.nClients))) + val release_data_client_id = Reg(resetVal = UFix(0, width = log2Up(ln.nClients))) //TODO: Will need id reg for merged release xacts - val init_sharer_cnt_ = Reg(resetVal = UFix(0, width = log2Up(conf.ln.nClients))) + val init_sharer_cnt_ = Reg(resetVal = UFix(0, width = log2Up(ln.nClients))) val grant_type = co.getGrantType(xact.a_type, init_sharer_cnt_) - val release_count = if (conf.ln.nClients == 1) UFix(0) else Reg(resetVal = UFix(0, width = log2Up(conf.ln.nClients))) - val probe_flags = Reg(resetVal = Bits(0, width = conf.ln.nClients)) + val release_count = if (ln.nClients == 1) UFix(0) else Reg(resetVal = UFix(0, width = log2Up(ln.nClients))) + val probe_flags = Reg(resetVal = Bits(0, width = ln.nClients)) val curr_p_id = PriorityEncoder(probe_flags) val x_needs_read = Reg(resetVal = Bool(false)) val acquire_data_needs_write = Reg(resetVal = Bool(false)) val release_data_needs_write = Reg(resetVal = Bool(false)) - val cmd_to_write = co.getUncachedWriteAcquire(xact.addr, UFix(trackerId)) - val cmd_to_read = co.getUncachedReadAcquire(xact.addr, UFix(trackerId)) + val cmd_to_write = Acquire(co.getUncachedWriteAcquireType, xact.addr, UFix(trackerId)) + val cmd_to_read = Acquire(co.getUncachedReadAcquireType, xact.addr, UFix(trackerId)) val a_w_mem_cmd_sent = Reg(resetVal = Bool(false)) val r_w_mem_cmd_sent = Reg(resetVal = Bool(false)) - val probe_initial_flags = Bits(width = conf.ln.nClients) + val probe_initial_flags = Bits(width = ln.nClients) probe_initial_flags := Bits(0) - if (conf.ln.nClients > 1) { + if (ln.nClients > 1) { // issue self-probes for uncached read xacts to facilitate I$ coherence val probe_self = Bool(true) //co.needsSelfProbe(io.client.acquire.bits.payload) - val myflag = Mux(probe_self, Bits(0), UFixToOH(io.client.acquire.meta.bits.header.src(log2Up(conf.ln.nClients)-1,0))) + val myflag = Mux(probe_self, Bits(0), UFixToOH(io.client.acquire.meta.bits.header.src(log2Up(ln.nClients)-1,0))) probe_initial_flags := ~(io.tile_incoherent | myflag) } io.has_acquire_conflict := co.isCoherenceConflict(xact.addr, io.client.acquire.meta.bits.payload.addr) && (state != s_idle) io.has_release_conflict := co.isCoherenceConflict(xact.addr, io.client.release.meta.bits.payload.addr) && (state != s_idle) io.master.acquire.meta.valid := Bool(false) - io.master.acquire.meta.bits.payload := co.getUncachedReadAcquire(xact.addr, UFix(trackerId)) + io.master.acquire.meta.bits.payload := Acquire(co.getUncachedReadAcquireType, xact.addr, UFix(trackerId)) //TODO io.master.acquire.bits.header.dst io.master.acquire.meta.bits.header.src := UFix(bankId) io.master.acquire.data.valid := Bool(false) @@ -227,14 +222,14 @@ class AcquireTracker(trackerId: Int, bankId: Int)(implicit conf: UncoreConfigura when( io.client.acquire.meta.valid ) { xact := io.client.acquire.meta.bits.payload init_client_id_ := io.client.acquire.meta.bits.header.src - init_sharer_cnt_ := UFix(conf.ln.nClients) // TODO: Broadcast only + init_sharer_cnt_ := UFix(ln.nClients) // TODO: Broadcast only acquire_data_needs_write := co.messageHasData(io.client.acquire.meta.bits.payload) x_needs_read := co.needsOuterRead(io.client.acquire.meta.bits.payload.a_type, UFix(0)) probe_flags := probe_initial_flags mem_cnt := UFix(0) r_w_mem_cmd_sent := Bool(false) a_w_mem_cmd_sent := Bool(false) - if(conf.ln.nClients > 1) { + if(ln.nClients > 1) { release_count := PopCount(probe_initial_flags) state := Mux(probe_initial_flags.orR, s_probe, s_mem) } else state := s_mem @@ -250,7 +245,7 @@ class AcquireTracker(trackerId: Int, bankId: Int)(implicit conf: UncoreConfigura } io.client.release.meta.ready := Bool(true) when(io.client.release.meta.valid) { - if(conf.ln.nClients > 1) release_count := release_count - UFix(1) + if(ln.nClients > 1) release_count := release_count - UFix(1) when(release_count === UFix(1)) { state := s_mem } @@ -306,7 +301,7 @@ abstract trait OuterRequestGenerator { val mem_cnt = Reg(resetVal = UFix(0, width = log2Up(REFILL_CYCLES))) val mem_cnt_next = mem_cnt + UFix(1) - def doOuterReqWrite[T <: HasMemData](master_acq: PairedDataIO[LogicalNetworkIO[Acquire],LogicalNetworkIO[AcquireData]], client_data: FIFOIO[LogicalNetworkIO[T]], cmd: Acquire, trigger: Bool, cmd_sent: Bool, desired_client_data_src_id: UFix) { + def doOuterReqWrite[T <: HasTileLinkData](master_acq: PairedDataIO[LogicalNetworkIO[Acquire],LogicalNetworkIO[AcquireData]], client_data: FIFOIO[LogicalNetworkIO[T]], cmd: Acquire, trigger: Bool, cmd_sent: Bool, desired_client_data_src_id: UFix) { val do_write = client_data.valid && (client_data.bits.header.src === desired_client_data_src_id) master_acq.meta.bits.payload := cmd master_acq.data.bits.payload := client_data.bits.payload