initial attempt at upgrade
This commit is contained in:
parent
bc2b45da12
commit
5c7a1f5cd6
@ -12,35 +12,35 @@ abstract class CoherencePolicy {
|
|||||||
def nProbeTypes: Int
|
def nProbeTypes: Int
|
||||||
def nReleaseTypes: Int
|
def nReleaseTypes: Int
|
||||||
def nGrantTypes: Int
|
def nGrantTypes: Int
|
||||||
def clientStateBits = log2Up(nClientStates)
|
def clientStateWidth = log2Up(nClientStates)
|
||||||
def masterStateBits = log2Up(nMasterStates)
|
def masterStateWidth = log2Up(nMasterStates)
|
||||||
def acquireTypeBits = log2Up(nAcquireTypes)
|
def acquireTypeWidth = log2Up(nAcquireTypes)
|
||||||
def probeTypeBits = log2Up(nProbeTypes)
|
def probeTypeWidth = log2Up(nProbeTypes)
|
||||||
def releaseTypeBits = log2Up(nReleaseTypes)
|
def releaseTypeWidth = log2Up(nReleaseTypes)
|
||||||
def grantTypeBits = log2Up(nGrantTypes)
|
def grantTypeWidth = log2Up(nGrantTypes)
|
||||||
|
|
||||||
def isHit (cmd: Bits, state: UFix): Bool
|
def isHit (cmd: UInt, state: UInt): Bool
|
||||||
def isValid (state: UFix): Bool
|
def isValid (state: UInt): Bool
|
||||||
|
|
||||||
def needsTransactionOnSecondaryMiss(cmd: Bits, outstanding: Acquire): Bool
|
def needsTransactionOnSecondaryMiss(cmd: UInt, outstanding: Acquire): Bool
|
||||||
def needsTransactionOnCacheControl(cmd: Bits, state: UFix): Bool
|
def needsTransactionOnCacheControl(cmd: UInt, state: UInt): Bool
|
||||||
def needsWriteback (state: UFix): Bool
|
def needsWriteback (state: UInt): Bool
|
||||||
|
|
||||||
def newStateOnHit(cmd: Bits, state: UFix): UFix
|
def newStateOnHit(cmd: UInt, state: UInt): UInt
|
||||||
def newStateOnCacheControl(cmd: Bits): UFix
|
def newStateOnCacheControl(cmd: UInt): UInt
|
||||||
def newStateOnWriteback(): UFix
|
def newStateOnWriteback(): UInt
|
||||||
def newStateOnFlush(): UFix
|
def newStateOnFlush(): UInt
|
||||||
def newStateOnGrant(incoming: Grant, outstanding: Acquire): UFix
|
def newStateOnGrant(incoming: Grant, outstanding: Acquire): UInt
|
||||||
def newStateOnProbe(incoming: Probe, state: UFix): Bits
|
def newStateOnProbe(incoming: Probe, state: UInt): Bits
|
||||||
|
|
||||||
def getAcquireTypeOnPrimaryMiss(cmd: Bits, state: UFix): UFix
|
def getAcquireTypeOnPrimaryMiss(cmd: UInt, state: UInt): UInt
|
||||||
def getAcquireTypeOnSecondaryMiss(cmd: Bits, state: UFix, outstanding: Acquire): UFix
|
def getAcquireTypeOnSecondaryMiss(cmd: UInt, state: UInt, outstanding: Acquire): UInt
|
||||||
def getProbeType(a_type: UFix, global_state: UFix): UFix
|
def getProbeType(a_type: UInt, global_state: UInt): UInt
|
||||||
def getReleaseTypeOnCacheControl(cmd: Bits): Bits
|
def getReleaseTypeOnCacheControl(cmd: UInt): Bits
|
||||||
def getReleaseTypeOnVoluntaryWriteback(): Bits
|
def getReleaseTypeOnVoluntaryWriteback(): Bits
|
||||||
def getReleaseTypeOnProbe(incoming: Probe, state: UFix): Bits
|
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): Bits
|
||||||
def getGrantType(a_type: UFix, count: UFix): Bits
|
def getGrantType(a_type: UInt, count: UInt): Bits
|
||||||
def getGrantType(rel: Release, count: UFix): Bits
|
def getGrantType(rel: Release, count: UInt): Bits
|
||||||
|
|
||||||
def messageHasData (rel: SourcedMessage): Bool
|
def messageHasData (rel: SourcedMessage): Bool
|
||||||
def messageUpdatesDataArray (reply: Grant): Bool
|
def messageUpdatesDataArray (reply: Grant): Bool
|
||||||
@ -49,15 +49,15 @@ abstract class CoherencePolicy {
|
|||||||
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool
|
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool
|
||||||
def isVoluntary(rel: Release): Bool
|
def isVoluntary(rel: Release): Bool
|
||||||
def isVoluntary(gnt: Grant): Bool
|
def isVoluntary(gnt: Grant): Bool
|
||||||
def needsOuterRead(a_type: UFix, global_state: UFix): Bool
|
def needsOuterRead(a_type: UInt, global_state: UInt): Bool
|
||||||
def needsOuterWrite(a_type: UFix, global_state: UFix): Bool
|
def needsOuterWrite(a_type: UInt, global_state: UInt): Bool
|
||||||
def needsAckReply(a_type: UFix, global_state: UFix): Bool
|
def needsAckReply(a_type: UInt, global_state: UInt): Bool
|
||||||
def needsSelfProbe(acq: Acquire): Bool
|
def needsSelfProbe(acq: Acquire): Bool
|
||||||
def requiresAck(grant: Grant): Bool
|
def requiresAck(grant: Grant): Bool
|
||||||
def requiresAck(release: Release): Bool
|
def requiresAck(release: Release): Bool
|
||||||
def pendingVoluntaryReleaseIsSufficient(r_type: UFix, p_type: UFix): Bool
|
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool
|
||||||
|
|
||||||
def uFixListContains(list: List[UFix], elem: UFix): Bool = list.map(elem === _).reduceLeft(_||_)
|
def uSIntListContains(list: List[UInt], elem: UInt): Bool = list.map(elem === _).reduceLeft(_||_)
|
||||||
}
|
}
|
||||||
|
|
||||||
trait UncachedTransactions {
|
trait UncachedTransactions {
|
||||||
@ -73,19 +73,19 @@ abstract class CoherencePolicyWithUncached extends CoherencePolicy with Uncached
|
|||||||
|
|
||||||
abstract class IncoherentPolicy extends CoherencePolicy {
|
abstract class IncoherentPolicy extends CoherencePolicy {
|
||||||
// UNIMPLEMENTED
|
// UNIMPLEMENTED
|
||||||
def newStateOnProbe(incoming: Probe, state: UFix): Bits = state
|
def newStateOnProbe(incoming: Probe, state: UInt): Bits = state
|
||||||
def getReleaseTypeOnProbe(incoming: Probe, state: UFix): Bits = Bits(0)
|
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): Bits = Bits(0)
|
||||||
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = Bool(false)
|
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = Bool(false)
|
||||||
def getGrantType(a_type: UFix, count: UFix): Bits = Bits(0)
|
def getGrantType(a_type: UInt, count: UInt): Bits = Bits(0)
|
||||||
def getGrantType(rel: Release, count: UFix): Bits = Bits(0)
|
def getGrantType(rel: Release, count: UInt): Bits = Bits(0)
|
||||||
def getProbeType(a_type: UFix, global_state: UFix): UFix = UFix(0)
|
def getProbeType(a_type: UInt, global_state: UInt): UInt = UInt(0)
|
||||||
def needsOuterRead(a_type: UFix, global_state: UFix): Bool = Bool(false)
|
def needsOuterRead(a_type: UInt, global_state: UInt): Bool = Bool(false)
|
||||||
def needsOuterWrite(a_type: UFix, global_state: UFix): Bool = Bool(false)
|
def needsOuterWrite(a_type: UInt, global_state: UInt): Bool = Bool(false)
|
||||||
def needsAckReply(a_type: UFix, global_state: UFix): Bool = Bool(false)
|
def needsAckReply(a_type: UInt, global_state: UInt): Bool = Bool(false)
|
||||||
def needsSelfProbe(acq: Acquire) = Bool(false)
|
def needsSelfProbe(acq: Acquire) = Bool(false)
|
||||||
def requiresAck(grant: Grant) = Bool(true)
|
def requiresAck(grant: Grant) = Bool(true)
|
||||||
def requiresAck(release: Release) = Bool(false)
|
def requiresAck(release: Release) = Bool(false)
|
||||||
def pendingVoluntaryReleaseIsSufficient(r_type: UFix, p_type: UFix): Bool = Bool(false)
|
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = Bool(false)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,27 +96,27 @@ class ThreeStateIncoherence extends IncoherentPolicy {
|
|||||||
def nProbeTypes = 0
|
def nProbeTypes = 0
|
||||||
def nReleaseTypes = 2
|
def nReleaseTypes = 2
|
||||||
def nGrantTypes = 3
|
def nGrantTypes = 3
|
||||||
val tileInvalid :: tileClean :: tileDirty :: Nil = Enum(nClientStates){ UFix() }
|
val tileInvalid :: tileClean :: tileDirty :: Nil = Enum(nClientStates){ UInt() }
|
||||||
val acquireReadClean :: acquireReadDirty :: acquireWriteback :: Nil = Enum(nAcquireTypes){ UFix() }
|
val acquireReadClean :: acquireReadDirty :: acquireWriteback :: Nil = Enum(nAcquireTypes){ UInt() }
|
||||||
val releaseVoluntaryInvalidateData :: releaseInvalidateAck :: Nil = Enum(nReleaseTypes){ UFix() }
|
val releaseVoluntaryInvalidateData :: releaseInvalidateAck :: Nil = Enum(nReleaseTypes){ UInt() }
|
||||||
val grantVoluntaryAck :: grantData :: grantAck :: Nil = Enum(nGrantTypes){ UFix() }
|
val grantVoluntaryAck :: grantData :: grantAck :: Nil = Enum(nGrantTypes){ UInt() }
|
||||||
val uncachedAcquireTypeList = List()
|
val uncachedAcquireTypeList = List()
|
||||||
val hasDataAcquireTypeList = List(acquireWriteback)
|
val hasDataAcquireTypeList = List(acquireWriteback)
|
||||||
val hasDataReleaseTypeList = List(acquireWriteback)
|
val hasDataReleaseTypeList = List(acquireWriteback)
|
||||||
val hasDataGrantTypeList = List(grantData)
|
val hasDataGrantTypeList = List(grantData)
|
||||||
|
|
||||||
def isHit ( cmd: Bits, state: UFix): Bool = (state === tileClean || state === tileDirty)
|
def isHit ( cmd: UInt, state: UInt): Bool = (state === tileClean || state === tileDirty)
|
||||||
def isValid (state: UFix): Bool = state != tileInvalid
|
def isValid (state: UInt): Bool = state != tileInvalid
|
||||||
|
|
||||||
def needsTransactionOnSecondaryMiss(cmd: Bits, outstanding: Acquire) = Bool(false)
|
def needsTransactionOnSecondaryMiss(cmd: UInt, outstanding: Acquire) = Bool(false)
|
||||||
def needsTransactionOnCacheControl(cmd: Bits, state: UFix): Bool = state === tileDirty
|
def needsTransactionOnCacheControl(cmd: UInt, state: UInt): Bool = state === tileDirty
|
||||||
def needsWriteback (state: UFix): Bool = state === tileDirty
|
def needsWriteback (state: UInt): Bool = state === tileDirty
|
||||||
|
|
||||||
def newState(cmd: Bits, state: UFix): UFix = {
|
def newState(cmd: UInt, state: UInt): UInt = {
|
||||||
Mux(isWrite(cmd), tileDirty, Mux(isRead(cmd), Mux(state === tileDirty, tileDirty, tileClean), state))
|
Mux(isWrite(cmd), tileDirty, Mux(isRead(cmd), Mux(state === tileDirty, tileDirty, tileClean), state))
|
||||||
}
|
}
|
||||||
def newStateOnHit(cmd: Bits, state: UFix): UFix = newState(cmd, state)
|
def newStateOnHit(cmd: UInt, state: UInt): UInt = newState(cmd, state)
|
||||||
def newStateOnCacheControl(cmd: Bits) = tileInvalid //TODO
|
def newStateOnCacheControl(cmd: UInt) = tileInvalid //TODO
|
||||||
def newStateOnWriteback() = tileInvalid
|
def newStateOnWriteback() = tileInvalid
|
||||||
def newStateOnFlush() = tileInvalid
|
def newStateOnFlush() = tileInvalid
|
||||||
def newStateOnGrant(incoming: Grant, outstanding: Acquire) = {
|
def newStateOnGrant(incoming: Grant, outstanding: Acquire) = {
|
||||||
@ -129,23 +129,23 @@ class ThreeStateIncoherence extends IncoherentPolicy {
|
|||||||
def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData
|
def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData
|
||||||
def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck
|
def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck
|
||||||
|
|
||||||
def getAcquireTypeOnPrimaryMiss(cmd: Bits, state: UFix): UFix = {
|
def getAcquireTypeOnPrimaryMiss(cmd: UInt, state: UInt): UInt = {
|
||||||
Mux(isWriteIntent(cmd), acquireReadDirty, acquireReadClean)
|
Mux(isWriteIntent(cmd), acquireReadDirty, acquireReadClean)
|
||||||
}
|
}
|
||||||
def getAcquireTypeOnSecondaryMiss(cmd: Bits, state: UFix, outstanding: Acquire): UFix = {
|
def getAcquireTypeOnSecondaryMiss(cmd: UInt, state: UInt, outstanding: Acquire): UInt = {
|
||||||
Mux(isWriteIntent(cmd), acquireReadDirty, outstanding.a_type)
|
Mux(isWriteIntent(cmd), acquireReadDirty, outstanding.a_type)
|
||||||
}
|
}
|
||||||
def getReleaseTypeOnCacheControl(cmd: Bits): Bits = releaseVoluntaryInvalidateData // TODO
|
def getReleaseTypeOnCacheControl(cmd: UInt): Bits = releaseVoluntaryInvalidateData // TODO
|
||||||
def getReleaseTypeOnVoluntaryWriteback(): Bits = releaseVoluntaryInvalidateData
|
def getReleaseTypeOnVoluntaryWriteback(): Bits = releaseVoluntaryInvalidateData
|
||||||
|
|
||||||
def messageHasData( msg: SourcedMessage ) = msg match {
|
def messageHasData( msg: SourcedMessage ) = msg match {
|
||||||
case acq: Acquire => uFixListContains(hasDataAcquireTypeList, acq.a_type)
|
case acq: Acquire => uSIntListContains(hasDataAcquireTypeList, acq.a_type)
|
||||||
case grant: Grant => uFixListContains(hasDataGrantTypeList, grant.g_type)
|
case grant: Grant => uSIntListContains(hasDataGrantTypeList, grant.g_type)
|
||||||
case rel: Release => Bool(false)
|
case rel: Release => Bool(false)
|
||||||
case _ => Bool(false)
|
case _ => Bool(false)
|
||||||
}
|
}
|
||||||
def messageUpdatesDataArray (reply: Grant) = (reply.g_type === grantData)
|
def messageUpdatesDataArray (reply: Grant) = (reply.g_type === grantData)
|
||||||
def messageIsUncached(acq: Acquire): Bool = uFixListContains(uncachedAcquireTypeList, acq.a_type)
|
def messageIsUncached(acq: Acquire): Bool = uSIntListContains(uncachedAcquireTypeList, acq.a_type)
|
||||||
}
|
}
|
||||||
|
|
||||||
class MICoherence extends CoherencePolicyWithUncached {
|
class MICoherence extends CoherencePolicyWithUncached {
|
||||||
@ -156,35 +156,35 @@ class MICoherence extends CoherencePolicyWithUncached {
|
|||||||
def nReleaseTypes = 5
|
def nReleaseTypes = 5
|
||||||
def nGrantTypes = 7
|
def nGrantTypes = 7
|
||||||
|
|
||||||
val tileInvalid :: tileValid :: Nil = Enum(nClientStates){ UFix() }
|
val tileInvalid :: tileValid :: Nil = Enum(nClientStates){ UInt() }
|
||||||
val globalInvalid :: globalValid :: Nil = Enum(nMasterStates){ UFix() }
|
val globalInvalid :: globalValid :: Nil = Enum(nMasterStates){ UInt() }
|
||||||
|
|
||||||
val acquireReadExclusive :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: Nil = Enum(nAcquireTypes){ UFix() }
|
val acquireReadExclusive :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: Nil = Enum(nAcquireTypes){ UInt() }
|
||||||
val probeInvalidate :: probeCopy :: Nil = Enum(nProbeTypes){ UFix() }
|
val probeInvalidate :: probeCopy :: Nil = Enum(nProbeTypes){ UInt() }
|
||||||
val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseCopyData :: releaseInvalidateAck :: releaseCopyAck :: Nil = Enum(nReleaseTypes){ UFix() }
|
val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseCopyData :: releaseInvalidateAck :: releaseCopyAck :: Nil = Enum(nReleaseTypes){ UInt() }
|
||||||
val grantVoluntaryAck :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: Nil = Enum(nGrantTypes){ UFix() }
|
val grantVoluntaryAck :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: Nil = Enum(nGrantTypes){ UInt() }
|
||||||
|
|
||||||
val uncachedAcquireTypeList = List(acquireReadUncached, acquireWriteUncached, acquireReadWordUncached, acquireWriteWordUncached, acquireAtomicUncached)
|
val uncachedAcquireTypeList = List(acquireReadUncached, acquireWriteUncached, acquireReadWordUncached, acquireWriteWordUncached, acquireAtomicUncached)
|
||||||
val hasDataAcquireTypeList = List(acquireWriteUncached, acquireWriteWordUncached, acquireAtomicUncached)
|
val hasDataAcquireTypeList = List(acquireWriteUncached, acquireWriteWordUncached, acquireAtomicUncached)
|
||||||
val hasDataReleaseTypeList = List(releaseVoluntaryInvalidateData, releaseInvalidateData, releaseCopyData)
|
val hasDataReleaseTypeList = List(releaseVoluntaryInvalidateData, releaseInvalidateData, releaseCopyData)
|
||||||
val hasDataGrantTypeList = List(grantReadExclusive, grantReadUncached, grantReadWordUncached, grantAtomicUncached)
|
val hasDataGrantTypeList = List(grantReadExclusive, grantReadUncached, grantReadWordUncached, grantAtomicUncached)
|
||||||
|
|
||||||
def isHit (cmd: Bits, state: UFix): Bool = state != tileInvalid
|
def isHit (cmd: UInt, state: UInt): Bool = state != tileInvalid
|
||||||
def isValid (state: UFix): Bool = state != tileInvalid
|
def isValid (state: UInt): Bool = state != tileInvalid
|
||||||
|
|
||||||
def needsTransactionOnSecondaryMiss(cmd: Bits, outstanding: Acquire): Bool = (outstanding.a_type != acquireReadExclusive)
|
def needsTransactionOnSecondaryMiss(cmd: UInt, outstanding: Acquire): Bool = (outstanding.a_type != acquireReadExclusive)
|
||||||
def needsTransactionOnCacheControl(cmd: Bits, state: UFix): Bool = {
|
def needsTransactionOnCacheControl(cmd: UInt, state: UInt): Bool = {
|
||||||
MuxLookup(cmd, (state === tileValid), Array(
|
MuxLookup(cmd, (state === tileValid), Array(
|
||||||
M_INV -> (state === tileValid),
|
M_INV -> (state === tileValid),
|
||||||
M_CLN -> (state === tileValid)
|
M_CLN -> (state === tileValid)
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
def needsWriteback (state: UFix): Bool = {
|
def needsWriteback (state: UInt): Bool = {
|
||||||
needsTransactionOnCacheControl(M_INV, state)
|
needsTransactionOnCacheControl(M_INV, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
def newStateOnHit(cmd: Bits, state: UFix): UFix = state
|
def newStateOnHit(cmd: UInt, state: UInt): UInt = state
|
||||||
def newStateOnCacheControl(cmd: Bits) = {
|
def newStateOnCacheControl(cmd: UInt) = {
|
||||||
MuxLookup(cmd, tileInvalid, Array(
|
MuxLookup(cmd, tileInvalid, Array(
|
||||||
M_INV -> tileInvalid,
|
M_INV -> tileInvalid,
|
||||||
M_CLN -> tileValid
|
M_CLN -> tileValid
|
||||||
@ -192,7 +192,7 @@ class MICoherence extends CoherencePolicyWithUncached {
|
|||||||
}
|
}
|
||||||
def newStateOnWriteback() = newStateOnCacheControl(M_INV)
|
def newStateOnWriteback() = newStateOnCacheControl(M_INV)
|
||||||
def newStateOnFlush() = newStateOnCacheControl(M_INV)
|
def newStateOnFlush() = newStateOnCacheControl(M_INV)
|
||||||
def newStateOnGrant(incoming: Grant, outstanding: Acquire): UFix = {
|
def newStateOnGrant(incoming: Grant, outstanding: Acquire): UInt = {
|
||||||
MuxLookup(incoming.g_type, tileInvalid, Array(
|
MuxLookup(incoming.g_type, tileInvalid, Array(
|
||||||
grantReadExclusive -> tileValid,
|
grantReadExclusive -> tileValid,
|
||||||
grantReadUncached -> tileInvalid,
|
grantReadUncached -> tileInvalid,
|
||||||
@ -202,7 +202,7 @@ class MICoherence extends CoherencePolicyWithUncached {
|
|||||||
grantAtomicUncached -> tileInvalid
|
grantAtomicUncached -> tileInvalid
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
def newStateOnProbe(incoming: Probe, state: UFix): Bits = {
|
def newStateOnProbe(incoming: Probe, state: UInt): Bits = {
|
||||||
MuxLookup(incoming.p_type, state, Array(
|
MuxLookup(incoming.p_type, state, Array(
|
||||||
probeInvalidate -> tileInvalid,
|
probeInvalidate -> tileInvalid,
|
||||||
probeCopy -> state
|
probeCopy -> state
|
||||||
@ -218,11 +218,11 @@ class MICoherence extends CoherencePolicyWithUncached {
|
|||||||
def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData
|
def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData
|
||||||
def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck
|
def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck
|
||||||
|
|
||||||
def getAcquireTypeOnPrimaryMiss(cmd: Bits, state: UFix): UFix = acquireReadExclusive
|
def getAcquireTypeOnPrimaryMiss(cmd: UInt, state: UInt): UInt = acquireReadExclusive
|
||||||
def getAcquireTypeOnSecondaryMiss(cmd: Bits, state: UFix, outstanding: Acquire): UFix = acquireReadExclusive
|
def getAcquireTypeOnSecondaryMiss(cmd: UInt, state: UInt, outstanding: Acquire): UInt = acquireReadExclusive
|
||||||
def getReleaseTypeOnCacheControl(cmd: Bits): Bits = releaseVoluntaryInvalidateData // TODO
|
def getReleaseTypeOnCacheControl(cmd: UInt): Bits = releaseVoluntaryInvalidateData // TODO
|
||||||
def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV)
|
def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV)
|
||||||
def getReleaseTypeOnProbe(incoming: Probe, state: UFix): Bits = {
|
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): Bits = {
|
||||||
val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array(
|
val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array(
|
||||||
probeInvalidate -> releaseInvalidateData,
|
probeInvalidate -> releaseInvalidateData,
|
||||||
probeCopy -> releaseCopyData
|
probeCopy -> releaseCopyData
|
||||||
@ -235,19 +235,19 @@ class MICoherence extends CoherencePolicyWithUncached {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def messageHasData(msg: SourcedMessage) = msg match {
|
def messageHasData(msg: SourcedMessage) = msg match {
|
||||||
case acq: Acquire => uFixListContains(hasDataAcquireTypeList, acq.a_type)
|
case acq: Acquire => uSIntListContains(hasDataAcquireTypeList, acq.a_type)
|
||||||
case grant: Grant => uFixListContains(hasDataGrantTypeList, grant.g_type)
|
case grant: Grant => uSIntListContains(hasDataGrantTypeList, grant.g_type)
|
||||||
case rel: Release => uFixListContains(hasDataReleaseTypeList, rel.r_type)
|
case rel: Release => uSIntListContains(hasDataReleaseTypeList, rel.r_type)
|
||||||
case _ => Bool(false)
|
case _ => Bool(false)
|
||||||
}
|
}
|
||||||
def messageUpdatesDataArray (reply: Grant): Bool = {
|
def messageUpdatesDataArray (reply: Grant): Bool = {
|
||||||
(reply.g_type === grantReadExclusive)
|
(reply.g_type === grantReadExclusive)
|
||||||
}
|
}
|
||||||
def messageIsUncached(acq: Acquire): Bool = uFixListContains(uncachedAcquireTypeList, acq.a_type)
|
def messageIsUncached(acq: Acquire): Bool = uSIntListContains(uncachedAcquireTypeList, acq.a_type)
|
||||||
|
|
||||||
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2)
|
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2)
|
||||||
|
|
||||||
def getGrantType(a_type: UFix, count: UFix): Bits = {
|
def getGrantType(a_type: UInt, count: UInt): Bits = {
|
||||||
MuxLookup(a_type, grantReadUncached, Array(
|
MuxLookup(a_type, grantReadUncached, Array(
|
||||||
acquireReadExclusive -> grantReadExclusive,
|
acquireReadExclusive -> grantReadExclusive,
|
||||||
acquireReadUncached -> grantReadUncached,
|
acquireReadUncached -> grantReadUncached,
|
||||||
@ -258,13 +258,13 @@ class MICoherence extends CoherencePolicyWithUncached {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
def getGrantType(rel: Release, count: UFix): Bits = {
|
def getGrantType(rel: Release, count: UInt): Bits = {
|
||||||
MuxLookup(rel.r_type, grantReadUncached, Array(
|
MuxLookup(rel.r_type, grantReadUncached, Array(
|
||||||
releaseVoluntaryInvalidateData -> grantVoluntaryAck
|
releaseVoluntaryInvalidateData -> grantVoluntaryAck
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
def getProbeType(a_type: UFix, global_state: UFix): UFix = {
|
def getProbeType(a_type: UInt, global_state: UInt): UInt = {
|
||||||
MuxLookup(a_type, probeCopy, Array(
|
MuxLookup(a_type, probeCopy, Array(
|
||||||
acquireReadExclusive -> probeInvalidate,
|
acquireReadExclusive -> probeInvalidate,
|
||||||
acquireReadUncached -> probeCopy,
|
acquireReadUncached -> probeCopy,
|
||||||
@ -275,19 +275,19 @@ class MICoherence extends CoherencePolicyWithUncached {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
def needsOuterRead(a_type: UFix, global_state: UFix): Bool = {
|
def needsOuterRead(a_type: UInt, global_state: UInt): Bool = {
|
||||||
(a_type != acquireWriteUncached)
|
(a_type != acquireWriteUncached)
|
||||||
}
|
}
|
||||||
def needsOuterWrite(a_type: UFix, global_state: UFix): Bool = {
|
def needsOuterWrite(a_type: UInt, global_state: UInt): Bool = {
|
||||||
(a_type === acquireWriteUncached)
|
(a_type === acquireWriteUncached)
|
||||||
}
|
}
|
||||||
def needsAckReply(a_type: UFix, global_state: UFix): Bool = {
|
def needsAckReply(a_type: UInt, global_state: UInt): Bool = {
|
||||||
(a_type === acquireWriteUncached)
|
(a_type === acquireWriteUncached)
|
||||||
}
|
}
|
||||||
def requiresAck(grant: Grant) = grant.g_type != grantVoluntaryAck
|
def requiresAck(grant: Grant) = grant.g_type != grantVoluntaryAck
|
||||||
def requiresAck(release: Release) = Bool(false)
|
def requiresAck(release: Release) = Bool(false)
|
||||||
def needsSelfProbe(acq: Acquire) = Bool(false)
|
def needsSelfProbe(acq: Acquire) = Bool(false)
|
||||||
def pendingVoluntaryReleaseIsSufficient(r_type: UFix, p_type: UFix): Bool = (r_type === releaseVoluntaryInvalidateData)
|
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData)
|
||||||
}
|
}
|
||||||
|
|
||||||
class MEICoherence extends CoherencePolicyWithUncached {
|
class MEICoherence extends CoherencePolicyWithUncached {
|
||||||
@ -298,40 +298,40 @@ class MEICoherence extends CoherencePolicyWithUncached {
|
|||||||
def nReleaseTypes = 7
|
def nReleaseTypes = 7
|
||||||
def nGrantTypes = 8
|
def nGrantTypes = 8
|
||||||
|
|
||||||
val tileInvalid :: tileExclusiveClean :: tileExclusiveDirty :: Nil = Enum(nClientStates){ UFix() }
|
val tileInvalid :: tileExclusiveClean :: tileExclusiveDirty :: Nil = Enum(nClientStates){ UInt() }
|
||||||
val globalInvalid :: globalExclusiveClean :: Nil = Enum(nMasterStates){ UFix() }
|
val globalInvalid :: globalExclusiveClean :: Nil = Enum(nMasterStates){ UInt() }
|
||||||
|
|
||||||
val acquireReadExclusiveClean :: acquireReadExclusiveDirty :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: Nil = Enum(nAcquireTypes){ UFix() }
|
val acquireReadExclusiveClean :: acquireReadExclusiveDirty :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: Nil = Enum(nAcquireTypes){ UInt() }
|
||||||
val probeInvalidate :: probeDowngrade :: probeCopy :: Nil = Enum(nProbeTypes){ UFix() }
|
val probeInvalidate :: probeDowngrade :: probeCopy :: Nil = Enum(nProbeTypes){ UInt() }
|
||||||
val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(nReleaseTypes){ UFix() }
|
val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(nReleaseTypes){ UInt() }
|
||||||
val grantVoluntaryAck :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadExclusiveAck :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: Nil = Enum(nGrantTypes){ UFix() }
|
val grantVoluntaryAck :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadExclusiveAck :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: Nil = Enum(nGrantTypes){ UInt() }
|
||||||
|
|
||||||
val uncachedAcquireTypeList = List(acquireReadUncached, acquireWriteUncached, acquireReadWordUncached, acquireWriteWordUncached, acquireAtomicUncached)
|
val uncachedAcquireTypeList = List(acquireReadUncached, acquireWriteUncached, acquireReadWordUncached, acquireWriteWordUncached, acquireAtomicUncached)
|
||||||
val hasDataAcquireTypeList = List(acquireWriteUncached, acquireWriteWordUncached, acquireAtomicUncached)
|
val hasDataAcquireTypeList = List(acquireWriteUncached, acquireWriteWordUncached, acquireAtomicUncached)
|
||||||
val hasDataReleaseTypeList = List(releaseVoluntaryInvalidateData, releaseInvalidateData, releaseDowngradeData, releaseCopyData)
|
val hasDataReleaseTypeList = List(releaseVoluntaryInvalidateData, releaseInvalidateData, releaseDowngradeData, releaseCopyData)
|
||||||
val hasDataGrantTypeList = List(grantReadExclusive, grantReadUncached, grantReadWordUncached, grantAtomicUncached)
|
val hasDataGrantTypeList = List(grantReadExclusive, grantReadUncached, grantReadWordUncached, grantAtomicUncached)
|
||||||
|
|
||||||
def isHit (cmd: Bits, state: UFix): Bool = state != tileInvalid
|
def isHit (cmd: UInt, state: UInt): Bool = state != tileInvalid
|
||||||
def isValid (state: UFix): Bool = state != tileInvalid
|
def isValid (state: UInt): Bool = state != tileInvalid
|
||||||
|
|
||||||
def needsTransactionOnSecondaryMiss(cmd: Bits, outstanding: Acquire): Bool = {
|
def needsTransactionOnSecondaryMiss(cmd: UInt, outstanding: Acquire): Bool = {
|
||||||
(isRead(cmd) && messageIsUncached(outstanding)) ||
|
(isRead(cmd) && messageIsUncached(outstanding)) ||
|
||||||
(isWriteIntent(cmd) && (outstanding.a_type != acquireReadExclusiveDirty))
|
(isWriteIntent(cmd) && (outstanding.a_type != acquireReadExclusiveDirty))
|
||||||
}
|
}
|
||||||
def needsTransactionOnCacheControl(cmd: Bits, state: UFix): Bool = {
|
def needsTransactionOnCacheControl(cmd: UInt, state: UInt): Bool = {
|
||||||
MuxLookup(cmd, (state === tileExclusiveDirty), Array(
|
MuxLookup(cmd, (state === tileExclusiveDirty), Array(
|
||||||
M_INV -> (state === tileExclusiveDirty),
|
M_INV -> (state === tileExclusiveDirty),
|
||||||
M_CLN -> (state === tileExclusiveDirty)
|
M_CLN -> (state === tileExclusiveDirty)
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
def needsWriteback (state: UFix): Bool = {
|
def needsWriteback (state: UInt): Bool = {
|
||||||
needsTransactionOnCacheControl(M_INV, state)
|
needsTransactionOnCacheControl(M_INV, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
def newStateOnHit(cmd: Bits, state: UFix): UFix = {
|
def newStateOnHit(cmd: UInt, state: UInt): UInt = {
|
||||||
Mux(isWrite(cmd), tileExclusiveDirty, state)
|
Mux(isWrite(cmd), tileExclusiveDirty, state)
|
||||||
}
|
}
|
||||||
def newStateOnCacheControl(cmd: Bits) = {
|
def newStateOnCacheControl(cmd: UInt) = {
|
||||||
MuxLookup(cmd, tileInvalid, Array(
|
MuxLookup(cmd, tileInvalid, Array(
|
||||||
M_INV -> tileInvalid,
|
M_INV -> tileInvalid,
|
||||||
M_CLN -> tileExclusiveClean
|
M_CLN -> tileExclusiveClean
|
||||||
@ -339,7 +339,7 @@ class MEICoherence extends CoherencePolicyWithUncached {
|
|||||||
}
|
}
|
||||||
def newStateOnWriteback() = newStateOnCacheControl(M_INV)
|
def newStateOnWriteback() = newStateOnCacheControl(M_INV)
|
||||||
def newStateOnFlush() = newStateOnCacheControl(M_INV)
|
def newStateOnFlush() = newStateOnCacheControl(M_INV)
|
||||||
def newStateOnGrant(incoming: Grant, outstanding: Acquire): UFix = {
|
def newStateOnGrant(incoming: Grant, outstanding: Acquire): UInt = {
|
||||||
MuxLookup(incoming.g_type, tileInvalid, Array(
|
MuxLookup(incoming.g_type, tileInvalid, Array(
|
||||||
grantReadExclusive -> Mux(outstanding.a_type === acquireReadExclusiveDirty, tileExclusiveDirty, tileExclusiveClean),
|
grantReadExclusive -> Mux(outstanding.a_type === acquireReadExclusiveDirty, tileExclusiveDirty, tileExclusiveClean),
|
||||||
grantReadExclusiveAck -> tileExclusiveDirty,
|
grantReadExclusiveAck -> tileExclusiveDirty,
|
||||||
@ -350,7 +350,7 @@ class MEICoherence extends CoherencePolicyWithUncached {
|
|||||||
grantAtomicUncached -> tileInvalid
|
grantAtomicUncached -> tileInvalid
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
def newStateOnProbe(incoming: Probe, state: UFix): Bits = {
|
def newStateOnProbe(incoming: Probe, state: UInt): Bits = {
|
||||||
MuxLookup(incoming.p_type, state, Array(
|
MuxLookup(incoming.p_type, state, Array(
|
||||||
probeInvalidate -> tileInvalid,
|
probeInvalidate -> tileInvalid,
|
||||||
probeDowngrade -> tileExclusiveClean,
|
probeDowngrade -> tileExclusiveClean,
|
||||||
@ -367,15 +367,15 @@ class MEICoherence extends CoherencePolicyWithUncached {
|
|||||||
def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData
|
def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData
|
||||||
def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck
|
def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck
|
||||||
|
|
||||||
def getAcquireTypeOnPrimaryMiss(cmd: Bits, state: UFix): UFix = {
|
def getAcquireTypeOnPrimaryMiss(cmd: UInt, state: UInt): UInt = {
|
||||||
Mux(isWriteIntent(cmd), acquireReadExclusiveDirty, acquireReadExclusiveClean)
|
Mux(isWriteIntent(cmd), acquireReadExclusiveDirty, acquireReadExclusiveClean)
|
||||||
}
|
}
|
||||||
def getAcquireTypeOnSecondaryMiss(cmd: Bits, state: UFix, outstanding: Acquire): UFix = {
|
def getAcquireTypeOnSecondaryMiss(cmd: UInt, state: UInt, outstanding: Acquire): UInt = {
|
||||||
Mux(isWriteIntent(cmd), acquireReadExclusiveDirty, outstanding.a_type)
|
Mux(isWriteIntent(cmd), acquireReadExclusiveDirty, outstanding.a_type)
|
||||||
}
|
}
|
||||||
def getReleaseTypeOnCacheControl(cmd: Bits): Bits = releaseVoluntaryInvalidateData // TODO
|
def getReleaseTypeOnCacheControl(cmd: UInt): Bits = releaseVoluntaryInvalidateData // TODO
|
||||||
def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV)
|
def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV)
|
||||||
def getReleaseTypeOnProbe(incoming: Probe, state: UFix): Bits = {
|
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): Bits = {
|
||||||
val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array(
|
val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array(
|
||||||
probeInvalidate -> releaseInvalidateData,
|
probeInvalidate -> releaseInvalidateData,
|
||||||
probeDowngrade -> releaseDowngradeData,
|
probeDowngrade -> releaseDowngradeData,
|
||||||
@ -390,19 +390,19 @@ class MEICoherence extends CoherencePolicyWithUncached {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def messageHasData(msg: SourcedMessage) = msg match {
|
def messageHasData(msg: SourcedMessage) = msg match {
|
||||||
case acq: Acquire => uFixListContains(hasDataAcquireTypeList, acq.a_type)
|
case acq: Acquire => uSIntListContains(hasDataAcquireTypeList, acq.a_type)
|
||||||
case grant: Grant => uFixListContains(hasDataGrantTypeList, grant.g_type)
|
case grant: Grant => uSIntListContains(hasDataGrantTypeList, grant.g_type)
|
||||||
case rel: Release => uFixListContains(hasDataReleaseTypeList, rel.r_type)
|
case rel: Release => uSIntListContains(hasDataReleaseTypeList, rel.r_type)
|
||||||
case _ => Bool(false)
|
case _ => Bool(false)
|
||||||
}
|
}
|
||||||
def messageUpdatesDataArray (reply: Grant): Bool = {
|
def messageUpdatesDataArray (reply: Grant): Bool = {
|
||||||
(reply.g_type === grantReadExclusive)
|
(reply.g_type === grantReadExclusive)
|
||||||
}
|
}
|
||||||
def messageIsUncached(acq: Acquire): Bool = uFixListContains(uncachedAcquireTypeList, acq.a_type)
|
def messageIsUncached(acq: Acquire): Bool = uSIntListContains(uncachedAcquireTypeList, acq.a_type)
|
||||||
|
|
||||||
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2)
|
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2)
|
||||||
|
|
||||||
def getGrantType(a_type: UFix, count: UFix): Bits = {
|
def getGrantType(a_type: UInt, count: UInt): Bits = {
|
||||||
MuxLookup(a_type, grantReadUncached, Array(
|
MuxLookup(a_type, grantReadUncached, Array(
|
||||||
acquireReadExclusiveClean -> grantReadExclusive,
|
acquireReadExclusiveClean -> grantReadExclusive,
|
||||||
acquireReadExclusiveDirty -> grantReadExclusive,
|
acquireReadExclusiveDirty -> grantReadExclusive,
|
||||||
@ -413,14 +413,14 @@ class MEICoherence extends CoherencePolicyWithUncached {
|
|||||||
acquireAtomicUncached -> grantAtomicUncached
|
acquireAtomicUncached -> grantAtomicUncached
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
def getGrantType(rel: Release, count: UFix): Bits = {
|
def getGrantType(rel: Release, count: UInt): Bits = {
|
||||||
MuxLookup(rel.r_type, grantReadUncached, Array(
|
MuxLookup(rel.r_type, grantReadUncached, Array(
|
||||||
releaseVoluntaryInvalidateData -> grantVoluntaryAck
|
releaseVoluntaryInvalidateData -> grantVoluntaryAck
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def getProbeType(a_type: UFix, global_state: UFix): UFix = {
|
def getProbeType(a_type: UInt, global_state: UInt): UInt = {
|
||||||
MuxLookup(a_type, probeCopy, Array(
|
MuxLookup(a_type, probeCopy, Array(
|
||||||
acquireReadExclusiveClean -> probeInvalidate,
|
acquireReadExclusiveClean -> probeInvalidate,
|
||||||
acquireReadExclusiveDirty -> probeInvalidate,
|
acquireReadExclusiveDirty -> probeInvalidate,
|
||||||
@ -432,20 +432,20 @@ class MEICoherence extends CoherencePolicyWithUncached {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
def needsOuterRead(a_type: UFix, global_state: UFix): Bool = {
|
def needsOuterRead(a_type: UInt, global_state: UInt): Bool = {
|
||||||
(a_type != acquireWriteUncached)
|
(a_type != acquireWriteUncached)
|
||||||
}
|
}
|
||||||
def needsOuterWrite(a_type: UFix, global_state: UFix): Bool = {
|
def needsOuterWrite(a_type: UInt, global_state: UInt): Bool = {
|
||||||
(a_type === acquireWriteUncached)
|
(a_type === acquireWriteUncached)
|
||||||
}
|
}
|
||||||
def needsAckReply(a_type: UFix, global_state: UFix): Bool = {
|
def needsAckReply(a_type: UInt, global_state: UInt): Bool = {
|
||||||
(a_type === acquireWriteUncached)
|
(a_type === acquireWriteUncached)
|
||||||
}
|
}
|
||||||
def requiresAck(grant: Grant) = grant.g_type != grantVoluntaryAck
|
def requiresAck(grant: Grant) = grant.g_type != grantVoluntaryAck
|
||||||
def requiresAck(release: Release) = Bool(false)
|
def requiresAck(release: Release) = Bool(false)
|
||||||
def needsSelfProbe(acq: Acquire) = Bool(false)
|
def needsSelfProbe(acq: Acquire) = Bool(false)
|
||||||
|
|
||||||
def pendingVoluntaryReleaseIsSufficient(r_type: UFix, p_type: UFix): Bool = (r_type === releaseVoluntaryInvalidateData)
|
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData)
|
||||||
}
|
}
|
||||||
|
|
||||||
class MSICoherence extends CoherencePolicyWithUncached {
|
class MSICoherence extends CoherencePolicyWithUncached {
|
||||||
@ -456,45 +456,45 @@ class MSICoherence extends CoherencePolicyWithUncached {
|
|||||||
def nReleaseTypes = 7
|
def nReleaseTypes = 7
|
||||||
def nGrantTypes = 9
|
def nGrantTypes = 9
|
||||||
|
|
||||||
val tileInvalid :: tileShared :: tileExclusiveDirty :: Nil = Enum(nClientStates){ UFix() }
|
val tileInvalid :: tileShared :: tileExclusiveDirty :: Nil = Enum(nClientStates){ UInt() }
|
||||||
val globalInvalid :: globalShared :: globalExclusive :: Nil = Enum(nMasterStates){ UFix() }
|
val globalInvalid :: globalShared :: globalExclusive :: Nil = Enum(nMasterStates){ UInt() }
|
||||||
|
|
||||||
val acquireReadShared :: acquireReadExclusive :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: Nil = Enum(nAcquireTypes){ UFix() }
|
val acquireReadShared :: acquireReadExclusive :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: Nil = Enum(nAcquireTypes){ UInt() }
|
||||||
val probeInvalidate :: probeDowngrade :: probeCopy :: Nil = Enum(nProbeTypes){ UFix() }
|
val probeInvalidate :: probeDowngrade :: probeCopy :: Nil = Enum(nProbeTypes){ UInt() }
|
||||||
val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(nReleaseTypes){ UFix() }
|
val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(nReleaseTypes){ UInt() }
|
||||||
val grantVoluntaryAck :: grantReadShared :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadExclusiveAck :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: Nil = Enum(nGrantTypes){ UFix() }
|
val grantVoluntaryAck :: grantReadShared :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadExclusiveAck :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: Nil = Enum(nGrantTypes){ UInt() }
|
||||||
|
|
||||||
val uncachedAcquireTypeList = List(acquireReadUncached, acquireWriteUncached, acquireReadWordUncached, acquireWriteWordUncached, acquireAtomicUncached)
|
val uncachedAcquireTypeList = List(acquireReadUncached, acquireWriteUncached, acquireReadWordUncached, acquireWriteWordUncached, acquireAtomicUncached)
|
||||||
val hasDataAcquireTypeList = List(acquireWriteUncached, acquireWriteWordUncached, acquireAtomicUncached)
|
val hasDataAcquireTypeList = List(acquireWriteUncached, acquireWriteWordUncached, acquireAtomicUncached)
|
||||||
val hasDataReleaseTypeList = List(releaseVoluntaryInvalidateData, releaseInvalidateData, releaseDowngradeData, releaseCopyData)
|
val hasDataReleaseTypeList = List(releaseVoluntaryInvalidateData, releaseInvalidateData, releaseDowngradeData, releaseCopyData)
|
||||||
val hasDataGrantTypeList = List(grantReadShared, grantReadExclusive, grantReadUncached, grantReadWordUncached, grantAtomicUncached)
|
val hasDataGrantTypeList = List(grantReadShared, grantReadExclusive, grantReadUncached, grantReadWordUncached, grantAtomicUncached)
|
||||||
|
|
||||||
def isHit (cmd: Bits, state: UFix): Bool = {
|
def isHit (cmd: UInt, state: UInt): Bool = {
|
||||||
Mux(isWriteIntent(cmd), (state === tileExclusiveDirty),
|
Mux(isWriteIntent(cmd), (state === tileExclusiveDirty),
|
||||||
(state === tileShared || state === tileExclusiveDirty))
|
(state === tileShared || state === tileExclusiveDirty))
|
||||||
}
|
}
|
||||||
def isValid (state: UFix): Bool = {
|
def isValid (state: UInt): Bool = {
|
||||||
state != tileInvalid
|
state != tileInvalid
|
||||||
}
|
}
|
||||||
|
|
||||||
def needsTransactionOnSecondaryMiss(cmd: Bits, outstanding: Acquire): Bool = {
|
def needsTransactionOnSecondaryMiss(cmd: UInt, outstanding: Acquire): Bool = {
|
||||||
(isRead(cmd) && messageIsUncached(outstanding)) ||
|
(isRead(cmd) && messageIsUncached(outstanding)) ||
|
||||||
(isWriteIntent(cmd) && (outstanding.a_type != acquireReadExclusive))
|
(isWriteIntent(cmd) && (outstanding.a_type != acquireReadExclusive))
|
||||||
}
|
}
|
||||||
def needsTransactionOnCacheControl(cmd: Bits, state: UFix): Bool = {
|
def needsTransactionOnCacheControl(cmd: UInt, state: UInt): Bool = {
|
||||||
MuxLookup(cmd, (state === tileExclusiveDirty), Array(
|
MuxLookup(cmd, (state === tileExclusiveDirty), Array(
|
||||||
M_INV -> (state === tileExclusiveDirty),
|
M_INV -> (state === tileExclusiveDirty),
|
||||||
M_CLN -> (state === tileExclusiveDirty)
|
M_CLN -> (state === tileExclusiveDirty)
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
def needsWriteback (state: UFix): Bool = {
|
def needsWriteback (state: UInt): Bool = {
|
||||||
needsTransactionOnCacheControl(M_INV, state)
|
needsTransactionOnCacheControl(M_INV, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
def newStateOnHit(cmd: Bits, state: UFix): UFix = {
|
def newStateOnHit(cmd: UInt, state: UInt): UInt = {
|
||||||
Mux(isWrite(cmd), tileExclusiveDirty, state)
|
Mux(isWrite(cmd), tileExclusiveDirty, state)
|
||||||
}
|
}
|
||||||
def newStateOnCacheControl(cmd: Bits) = {
|
def newStateOnCacheControl(cmd: UInt) = {
|
||||||
MuxLookup(cmd, tileInvalid, Array(
|
MuxLookup(cmd, tileInvalid, Array(
|
||||||
M_INV -> tileInvalid,
|
M_INV -> tileInvalid,
|
||||||
M_CLN -> tileShared
|
M_CLN -> tileShared
|
||||||
@ -502,7 +502,7 @@ class MSICoherence extends CoherencePolicyWithUncached {
|
|||||||
}
|
}
|
||||||
def newStateOnWriteback() = newStateOnCacheControl(M_INV)
|
def newStateOnWriteback() = newStateOnCacheControl(M_INV)
|
||||||
def newStateOnFlush() = newStateOnCacheControl(M_INV)
|
def newStateOnFlush() = newStateOnCacheControl(M_INV)
|
||||||
def newStateOnGrant(incoming: Grant, outstanding: Acquire): UFix = {
|
def newStateOnGrant(incoming: Grant, outstanding: Acquire): UInt = {
|
||||||
MuxLookup(incoming.g_type, tileInvalid, Array(
|
MuxLookup(incoming.g_type, tileInvalid, Array(
|
||||||
grantReadShared -> tileShared,
|
grantReadShared -> tileShared,
|
||||||
grantReadExclusive -> tileExclusiveDirty,
|
grantReadExclusive -> tileExclusiveDirty,
|
||||||
@ -514,7 +514,7 @@ class MSICoherence extends CoherencePolicyWithUncached {
|
|||||||
grantAtomicUncached -> tileInvalid
|
grantAtomicUncached -> tileInvalid
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
def newStateOnProbe(incoming: Probe, state: UFix): Bits = {
|
def newStateOnProbe(incoming: Probe, state: UInt): Bits = {
|
||||||
MuxLookup(incoming.p_type, state, Array(
|
MuxLookup(incoming.p_type, state, Array(
|
||||||
probeInvalidate -> tileInvalid,
|
probeInvalidate -> tileInvalid,
|
||||||
probeDowngrade -> tileShared,
|
probeDowngrade -> tileShared,
|
||||||
@ -531,15 +531,15 @@ class MSICoherence extends CoherencePolicyWithUncached {
|
|||||||
def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData
|
def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData
|
||||||
def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck
|
def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck
|
||||||
|
|
||||||
def getAcquireTypeOnPrimaryMiss(cmd: Bits, state: UFix): UFix = {
|
def getAcquireTypeOnPrimaryMiss(cmd: UInt, state: UInt): UInt = {
|
||||||
Mux(isWriteIntent(cmd), acquireReadExclusive, acquireReadShared)
|
Mux(isWriteIntent(cmd), acquireReadExclusive, acquireReadShared)
|
||||||
}
|
}
|
||||||
def getAcquireTypeOnSecondaryMiss(cmd: Bits, state: UFix, outstanding: Acquire): UFix = {
|
def getAcquireTypeOnSecondaryMiss(cmd: UInt, state: UInt, outstanding: Acquire): UInt = {
|
||||||
Mux(isWriteIntent(cmd), acquireReadExclusive, outstanding.a_type)
|
Mux(isWriteIntent(cmd), acquireReadExclusive, outstanding.a_type)
|
||||||
}
|
}
|
||||||
def getReleaseTypeOnCacheControl(cmd: Bits): Bits = releaseVoluntaryInvalidateData // TODO
|
def getReleaseTypeOnCacheControl(cmd: UInt): Bits = releaseVoluntaryInvalidateData // TODO
|
||||||
def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV)
|
def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV)
|
||||||
def getReleaseTypeOnProbe(incoming: Probe, state: UFix): Bits = {
|
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): Bits = {
|
||||||
val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array(
|
val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array(
|
||||||
probeInvalidate -> releaseInvalidateData,
|
probeInvalidate -> releaseInvalidateData,
|
||||||
probeDowngrade -> releaseDowngradeData,
|
probeDowngrade -> releaseDowngradeData,
|
||||||
@ -554,21 +554,21 @@ class MSICoherence extends CoherencePolicyWithUncached {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def messageHasData(msg: SourcedMessage) = msg match {
|
def messageHasData(msg: SourcedMessage) = msg match {
|
||||||
case acq: Acquire => uFixListContains(hasDataAcquireTypeList, acq.a_type)
|
case acq: Acquire => uSIntListContains(hasDataAcquireTypeList, acq.a_type)
|
||||||
case grant: Grant => uFixListContains(hasDataGrantTypeList, grant.g_type)
|
case grant: Grant => uSIntListContains(hasDataGrantTypeList, grant.g_type)
|
||||||
case rel: Release => uFixListContains(hasDataReleaseTypeList, rel.r_type)
|
case rel: Release => uSIntListContains(hasDataReleaseTypeList, rel.r_type)
|
||||||
case _ => Bool(false)
|
case _ => Bool(false)
|
||||||
}
|
}
|
||||||
def messageUpdatesDataArray (reply: Grant): Bool = {
|
def messageUpdatesDataArray (reply: Grant): Bool = {
|
||||||
(reply.g_type === grantReadShared || reply.g_type === grantReadExclusive)
|
(reply.g_type === grantReadShared || reply.g_type === grantReadExclusive)
|
||||||
}
|
}
|
||||||
def messageIsUncached(acq: Acquire): Bool = uFixListContains(uncachedAcquireTypeList, acq.a_type)
|
def messageIsUncached(acq: Acquire): Bool = uSIntListContains(uncachedAcquireTypeList, acq.a_type)
|
||||||
|
|
||||||
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2)
|
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2)
|
||||||
|
|
||||||
def getGrantType(a_type: UFix, count: UFix): Bits = {
|
def getGrantType(a_type: UInt, count: UInt): Bits = {
|
||||||
MuxLookup(a_type, grantReadUncached, Array(
|
MuxLookup(a_type, grantReadUncached, Array(
|
||||||
acquireReadShared -> Mux(count > UFix(0), grantReadShared, grantReadExclusive),
|
acquireReadShared -> Mux(count > UInt(0), grantReadShared, grantReadExclusive),
|
||||||
acquireReadExclusive -> grantReadExclusive,
|
acquireReadExclusive -> grantReadExclusive,
|
||||||
acquireReadUncached -> grantReadUncached,
|
acquireReadUncached -> grantReadUncached,
|
||||||
acquireWriteUncached -> grantWriteUncached,
|
acquireWriteUncached -> grantWriteUncached,
|
||||||
@ -577,14 +577,14 @@ class MSICoherence extends CoherencePolicyWithUncached {
|
|||||||
acquireAtomicUncached -> grantAtomicUncached
|
acquireAtomicUncached -> grantAtomicUncached
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
def getGrantType(rel: Release, count: UFix): Bits = {
|
def getGrantType(rel: Release, count: UInt): Bits = {
|
||||||
MuxLookup(rel.r_type, grantReadUncached, Array(
|
MuxLookup(rel.r_type, grantReadUncached, Array(
|
||||||
releaseVoluntaryInvalidateData -> grantVoluntaryAck
|
releaseVoluntaryInvalidateData -> grantVoluntaryAck
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def getProbeType(a_type: UFix, global_state: UFix): UFix = {
|
def getProbeType(a_type: UInt, global_state: UInt): UInt = {
|
||||||
MuxLookup(a_type, probeCopy, Array(
|
MuxLookup(a_type, probeCopy, Array(
|
||||||
acquireReadShared -> probeDowngrade,
|
acquireReadShared -> probeDowngrade,
|
||||||
acquireReadExclusive -> probeInvalidate,
|
acquireReadExclusive -> probeInvalidate,
|
||||||
@ -593,20 +593,20 @@ class MSICoherence extends CoherencePolicyWithUncached {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
def needsOuterRead(a_type: UFix, global_state: UFix): Bool = {
|
def needsOuterRead(a_type: UInt, global_state: UInt): Bool = {
|
||||||
(a_type != acquireWriteUncached)
|
(a_type != acquireWriteUncached)
|
||||||
}
|
}
|
||||||
def needsOuterWrite(a_type: UFix, global_state: UFix): Bool = {
|
def needsOuterWrite(a_type: UInt, global_state: UInt): Bool = {
|
||||||
(a_type === acquireWriteUncached)
|
(a_type === acquireWriteUncached)
|
||||||
}
|
}
|
||||||
def needsAckReply(a_type: UFix, global_state: UFix): Bool = {
|
def needsAckReply(a_type: UInt, global_state: UInt): Bool = {
|
||||||
(a_type === acquireWriteUncached)
|
(a_type === acquireWriteUncached)
|
||||||
}
|
}
|
||||||
def requiresAck(grant: Grant) = grant.g_type != grantVoluntaryAck
|
def requiresAck(grant: Grant) = grant.g_type != grantVoluntaryAck
|
||||||
def requiresAck(release: Release) = Bool(false)
|
def requiresAck(release: Release) = Bool(false)
|
||||||
def needsSelfProbe(acq: Acquire) = Bool(false)
|
def needsSelfProbe(acq: Acquire) = Bool(false)
|
||||||
|
|
||||||
def pendingVoluntaryReleaseIsSufficient(r_type: UFix, p_type: UFix): Bool = (r_type === releaseVoluntaryInvalidateData)
|
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData)
|
||||||
}
|
}
|
||||||
|
|
||||||
class MESICoherence extends CoherencePolicyWithUncached {
|
class MESICoherence extends CoherencePolicyWithUncached {
|
||||||
@ -617,45 +617,45 @@ class MESICoherence extends CoherencePolicyWithUncached {
|
|||||||
def nReleaseTypes = 7
|
def nReleaseTypes = 7
|
||||||
def nGrantTypes = 9
|
def nGrantTypes = 9
|
||||||
|
|
||||||
val tileInvalid :: tileShared :: tileExclusiveClean :: tileExclusiveDirty :: Nil = Enum(nClientStates){ UFix() }
|
val tileInvalid :: tileShared :: tileExclusiveClean :: tileExclusiveDirty :: Nil = Enum(nClientStates){ UInt() }
|
||||||
val globalInvalid :: globalShared :: globalExclusiveClean :: Nil = Enum(nMasterStates){ UFix() }
|
val globalInvalid :: globalShared :: globalExclusiveClean :: Nil = Enum(nMasterStates){ UInt() }
|
||||||
|
|
||||||
val acquireReadShared :: acquireReadExclusive :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: Nil = Enum(nAcquireTypes){ UFix() }
|
val acquireReadShared :: acquireReadExclusive :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: Nil = Enum(nAcquireTypes){ UInt() }
|
||||||
val probeInvalidate :: probeDowngrade :: probeCopy :: Nil = Enum(nProbeTypes){ UFix() }
|
val probeInvalidate :: probeDowngrade :: probeCopy :: Nil = Enum(nProbeTypes){ UInt() }
|
||||||
val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(nReleaseTypes){ UFix() }
|
val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(nReleaseTypes){ UInt() }
|
||||||
val grantVoluntaryAck :: grantReadShared :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadExclusiveAck :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: Nil = Enum(nGrantTypes){ UFix() }
|
val grantVoluntaryAck :: grantReadShared :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadExclusiveAck :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: Nil = Enum(nGrantTypes){ UInt() }
|
||||||
|
|
||||||
val uncachedAcquireTypeList = List(acquireReadUncached, acquireWriteUncached, acquireReadWordUncached, acquireWriteWordUncached, acquireAtomicUncached)
|
val uncachedAcquireTypeList = List(acquireReadUncached, acquireWriteUncached, acquireReadWordUncached, acquireWriteWordUncached, acquireAtomicUncached)
|
||||||
val hasDataAcquireTypeList = List(acquireWriteUncached, acquireWriteWordUncached, acquireAtomicUncached)
|
val hasDataAcquireTypeList = List(acquireWriteUncached, acquireWriteWordUncached, acquireAtomicUncached)
|
||||||
val hasDataReleaseTypeList = List(releaseVoluntaryInvalidateData, releaseInvalidateData, releaseDowngradeData, releaseCopyData)
|
val hasDataReleaseTypeList = List(releaseVoluntaryInvalidateData, releaseInvalidateData, releaseDowngradeData, releaseCopyData)
|
||||||
val hasDataGrantTypeList = List(grantReadShared, grantReadExclusive, grantReadUncached, grantReadWordUncached, grantAtomicUncached)
|
val hasDataGrantTypeList = List(grantReadShared, grantReadExclusive, grantReadUncached, grantReadWordUncached, grantAtomicUncached)
|
||||||
|
|
||||||
def isHit (cmd: Bits, state: UFix): Bool = {
|
def isHit (cmd: UInt, state: UInt): Bool = {
|
||||||
Mux(isWriteIntent(cmd), (state === tileExclusiveClean || state === tileExclusiveDirty),
|
Mux(isWriteIntent(cmd), (state === tileExclusiveClean || state === tileExclusiveDirty),
|
||||||
(state === tileShared || state === tileExclusiveClean || state === tileExclusiveDirty))
|
(state === tileShared || state === tileExclusiveClean || state === tileExclusiveDirty))
|
||||||
}
|
}
|
||||||
def isValid (state: UFix): Bool = {
|
def isValid (state: UInt): Bool = {
|
||||||
state != tileInvalid
|
state != tileInvalid
|
||||||
}
|
}
|
||||||
|
|
||||||
def needsTransactionOnSecondaryMiss(cmd: Bits, outstanding: Acquire): Bool = {
|
def needsTransactionOnSecondaryMiss(cmd: UInt, outstanding: Acquire): Bool = {
|
||||||
(isRead(cmd) && messageIsUncached(outstanding)) ||
|
(isRead(cmd) && messageIsUncached(outstanding)) ||
|
||||||
(isWriteIntent(cmd) && (outstanding.a_type != acquireReadExclusive))
|
(isWriteIntent(cmd) && (outstanding.a_type != acquireReadExclusive))
|
||||||
}
|
}
|
||||||
def needsTransactionOnCacheControl(cmd: Bits, state: UFix): Bool = {
|
def needsTransactionOnCacheControl(cmd: UInt, state: UInt): Bool = {
|
||||||
MuxLookup(cmd, (state === tileExclusiveDirty), Array(
|
MuxLookup(cmd, (state === tileExclusiveDirty), Array(
|
||||||
M_INV -> (state === tileExclusiveDirty),
|
M_INV -> (state === tileExclusiveDirty),
|
||||||
M_CLN -> (state === tileExclusiveDirty)
|
M_CLN -> (state === tileExclusiveDirty)
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
def needsWriteback (state: UFix): Bool = {
|
def needsWriteback (state: UInt): Bool = {
|
||||||
needsTransactionOnCacheControl(M_INV, state)
|
needsTransactionOnCacheControl(M_INV, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
def newStateOnHit(cmd: Bits, state: UFix): UFix = {
|
def newStateOnHit(cmd: UInt, state: UInt): UInt = {
|
||||||
Mux(isWrite(cmd), tileExclusiveDirty, state)
|
Mux(isWrite(cmd), tileExclusiveDirty, state)
|
||||||
}
|
}
|
||||||
def newStateOnCacheControl(cmd: Bits) = {
|
def newStateOnCacheControl(cmd: UInt) = {
|
||||||
MuxLookup(cmd, tileInvalid, Array(
|
MuxLookup(cmd, tileInvalid, Array(
|
||||||
M_INV -> tileInvalid,
|
M_INV -> tileInvalid,
|
||||||
M_CLN -> tileShared
|
M_CLN -> tileShared
|
||||||
@ -663,7 +663,7 @@ class MESICoherence extends CoherencePolicyWithUncached {
|
|||||||
}
|
}
|
||||||
def newStateOnWriteback() = newStateOnCacheControl(M_INV)
|
def newStateOnWriteback() = newStateOnCacheControl(M_INV)
|
||||||
def newStateOnFlush() = newStateOnCacheControl(M_INV)
|
def newStateOnFlush() = newStateOnCacheControl(M_INV)
|
||||||
def newStateOnGrant(incoming: Grant, outstanding: Acquire): UFix = {
|
def newStateOnGrant(incoming: Grant, outstanding: Acquire): UInt = {
|
||||||
MuxLookup(incoming.g_type, tileInvalid, Array(
|
MuxLookup(incoming.g_type, tileInvalid, Array(
|
||||||
grantReadShared -> tileShared,
|
grantReadShared -> tileShared,
|
||||||
grantReadExclusive -> Mux(outstanding.a_type === acquireReadExclusive, tileExclusiveDirty, tileExclusiveClean),
|
grantReadExclusive -> Mux(outstanding.a_type === acquireReadExclusive, tileExclusiveDirty, tileExclusiveClean),
|
||||||
@ -675,7 +675,7 @@ class MESICoherence extends CoherencePolicyWithUncached {
|
|||||||
grantAtomicUncached -> tileInvalid
|
grantAtomicUncached -> tileInvalid
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
def newStateOnProbe(incoming: Probe, state: UFix): Bits = {
|
def newStateOnProbe(incoming: Probe, state: UInt): Bits = {
|
||||||
MuxLookup(incoming.p_type, state, Array(
|
MuxLookup(incoming.p_type, state, Array(
|
||||||
probeInvalidate -> tileInvalid,
|
probeInvalidate -> tileInvalid,
|
||||||
probeDowngrade -> tileShared,
|
probeDowngrade -> tileShared,
|
||||||
@ -692,15 +692,15 @@ class MESICoherence extends CoherencePolicyWithUncached {
|
|||||||
def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData
|
def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData
|
||||||
def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck
|
def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck
|
||||||
|
|
||||||
def getAcquireTypeOnPrimaryMiss(cmd: Bits, state: UFix): UFix = {
|
def getAcquireTypeOnPrimaryMiss(cmd: UInt, state: UInt): UInt = {
|
||||||
Mux(isWriteIntent(cmd), acquireReadExclusive, acquireReadShared)
|
Mux(isWriteIntent(cmd), acquireReadExclusive, acquireReadShared)
|
||||||
}
|
}
|
||||||
def getAcquireTypeOnSecondaryMiss(cmd: Bits, state: UFix, outstanding: Acquire): UFix = {
|
def getAcquireTypeOnSecondaryMiss(cmd: UInt, state: UInt, outstanding: Acquire): UInt = {
|
||||||
Mux(isWriteIntent(cmd), acquireReadExclusive, outstanding.a_type)
|
Mux(isWriteIntent(cmd), acquireReadExclusive, outstanding.a_type)
|
||||||
}
|
}
|
||||||
def getReleaseTypeOnCacheControl(cmd: Bits): Bits = releaseVoluntaryInvalidateData // TODO
|
def getReleaseTypeOnCacheControl(cmd: UInt): Bits = releaseVoluntaryInvalidateData // TODO
|
||||||
def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV)
|
def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV)
|
||||||
def getReleaseTypeOnProbe(incoming: Probe, state: UFix): Bits = {
|
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): Bits = {
|
||||||
val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array(
|
val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array(
|
||||||
probeInvalidate -> releaseInvalidateData,
|
probeInvalidate -> releaseInvalidateData,
|
||||||
probeDowngrade -> releaseDowngradeData,
|
probeDowngrade -> releaseDowngradeData,
|
||||||
@ -715,21 +715,21 @@ class MESICoherence extends CoherencePolicyWithUncached {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def messageHasData(msg: SourcedMessage) = msg match {
|
def messageHasData(msg: SourcedMessage) = msg match {
|
||||||
case acq: Acquire => uFixListContains(hasDataAcquireTypeList, acq.a_type)
|
case acq: Acquire => uSIntListContains(hasDataAcquireTypeList, acq.a_type)
|
||||||
case grant: Grant => uFixListContains(hasDataGrantTypeList, grant.g_type)
|
case grant: Grant => uSIntListContains(hasDataGrantTypeList, grant.g_type)
|
||||||
case rel: Release => uFixListContains(hasDataReleaseTypeList, rel.r_type)
|
case rel: Release => uSIntListContains(hasDataReleaseTypeList, rel.r_type)
|
||||||
case _ => Bool(false)
|
case _ => Bool(false)
|
||||||
}
|
}
|
||||||
def messageUpdatesDataArray (reply: Grant): Bool = {
|
def messageUpdatesDataArray (reply: Grant): Bool = {
|
||||||
(reply.g_type === grantReadShared || reply.g_type === grantReadExclusive)
|
(reply.g_type === grantReadShared || reply.g_type === grantReadExclusive)
|
||||||
}
|
}
|
||||||
def messageIsUncached(acq: Acquire): Bool = uFixListContains(uncachedAcquireTypeList, acq.a_type)
|
def messageIsUncached(acq: Acquire): Bool = uSIntListContains(uncachedAcquireTypeList, acq.a_type)
|
||||||
|
|
||||||
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2)
|
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2)
|
||||||
|
|
||||||
def getGrantType(a_type: UFix, count: UFix): Bits = {
|
def getGrantType(a_type: UInt, count: UInt): Bits = {
|
||||||
MuxLookup(a_type, grantReadUncached, Array(
|
MuxLookup(a_type, grantReadUncached, Array(
|
||||||
acquireReadShared -> Mux(count > UFix(0), grantReadShared, grantReadExclusive),
|
acquireReadShared -> Mux(count > UInt(0), grantReadShared, grantReadExclusive),
|
||||||
acquireReadExclusive -> grantReadExclusive,
|
acquireReadExclusive -> grantReadExclusive,
|
||||||
acquireReadUncached -> grantReadUncached,
|
acquireReadUncached -> grantReadUncached,
|
||||||
acquireWriteUncached -> grantWriteUncached,
|
acquireWriteUncached -> grantWriteUncached,
|
||||||
@ -738,14 +738,14 @@ class MESICoherence extends CoherencePolicyWithUncached {
|
|||||||
acquireAtomicUncached -> grantAtomicUncached
|
acquireAtomicUncached -> grantAtomicUncached
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
def getGrantType(rel: Release, count: UFix): Bits = {
|
def getGrantType(rel: Release, count: UInt): Bits = {
|
||||||
MuxLookup(rel.r_type, grantReadUncached, Array(
|
MuxLookup(rel.r_type, grantReadUncached, Array(
|
||||||
releaseVoluntaryInvalidateData -> grantVoluntaryAck
|
releaseVoluntaryInvalidateData -> grantVoluntaryAck
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def getProbeType(a_type: UFix, global_state: UFix): UFix = {
|
def getProbeType(a_type: UInt, global_state: UInt): UInt = {
|
||||||
MuxLookup(a_type, probeCopy, Array(
|
MuxLookup(a_type, probeCopy, Array(
|
||||||
acquireReadShared -> probeDowngrade,
|
acquireReadShared -> probeDowngrade,
|
||||||
acquireReadExclusive -> probeInvalidate,
|
acquireReadExclusive -> probeInvalidate,
|
||||||
@ -757,13 +757,13 @@ class MESICoherence extends CoherencePolicyWithUncached {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
def needsOuterRead(a_type: UFix, global_state: UFix): Bool = {
|
def needsOuterRead(a_type: UInt, global_state: UInt): Bool = {
|
||||||
(a_type != acquireWriteUncached)
|
(a_type != acquireWriteUncached)
|
||||||
}
|
}
|
||||||
def needsOuterWrite(a_type: UFix, global_state: UFix): Bool = {
|
def needsOuterWrite(a_type: UInt, global_state: UInt): Bool = {
|
||||||
(a_type === acquireWriteUncached)
|
(a_type === acquireWriteUncached)
|
||||||
}
|
}
|
||||||
def needsAckReply(a_type: UFix, global_state: UFix): Bool = {
|
def needsAckReply(a_type: UInt, global_state: UInt): Bool = {
|
||||||
(a_type === acquireWriteUncached)
|
(a_type === acquireWriteUncached)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -771,7 +771,7 @@ class MESICoherence extends CoherencePolicyWithUncached {
|
|||||||
def requiresAck(release: Release) = Bool(false)
|
def requiresAck(release: Release) = Bool(false)
|
||||||
def needsSelfProbe(acq: Acquire) = Bool(false)
|
def needsSelfProbe(acq: Acquire) = Bool(false)
|
||||||
|
|
||||||
def pendingVoluntaryReleaseIsSufficient(r_type: UFix, p_type: UFix): Bool = (r_type === releaseVoluntaryInvalidateData)
|
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData)
|
||||||
}
|
}
|
||||||
|
|
||||||
class MigratoryCoherence extends CoherencePolicyWithUncached {
|
class MigratoryCoherence extends CoherencePolicyWithUncached {
|
||||||
@ -782,45 +782,45 @@ class MigratoryCoherence extends CoherencePolicyWithUncached {
|
|||||||
def nReleaseTypes = 11
|
def nReleaseTypes = 11
|
||||||
def nGrantTypes = 9
|
def nGrantTypes = 9
|
||||||
|
|
||||||
val tileInvalid :: tileShared :: tileExclusiveClean :: tileExclusiveDirty :: tileSharedByTwo :: tileMigratoryClean :: tileMigratoryDirty :: Nil = Enum(nClientStates){ UFix() }
|
val tileInvalid :: tileShared :: tileExclusiveClean :: tileExclusiveDirty :: tileSharedByTwo :: tileMigratoryClean :: tileMigratoryDirty :: Nil = Enum(nClientStates){ UInt() }
|
||||||
|
|
||||||
val acquireReadShared :: acquireReadExclusive :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: acquireInvalidateOthers :: Nil = Enum(nAcquireTypes){ UFix() }
|
val acquireReadShared :: acquireReadExclusive :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: acquireInvalidateOthers :: Nil = Enum(nAcquireTypes){ UInt() }
|
||||||
val probeInvalidate :: probeDowngrade :: probeCopy :: probeInvalidateOthers :: Nil = Enum(nProbeTypes){ UFix() }
|
val probeInvalidate :: probeDowngrade :: probeCopy :: probeInvalidateOthers :: Nil = Enum(nProbeTypes){ UInt() }
|
||||||
val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: releaseDowngradeDataMigratory :: releaseDowngradeAckHasCopy :: releaseInvalidateDataMigratory :: releaseInvalidateAckMigratory :: Nil = Enum(nReleaseTypes){ UFix() }
|
val releaseVoluntaryInvalidateData :: releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: releaseDowngradeDataMigratory :: releaseDowngradeAckHasCopy :: releaseInvalidateDataMigratory :: releaseInvalidateAckMigratory :: Nil = Enum(nReleaseTypes){ UInt() }
|
||||||
val grantVoluntaryAck :: grantReadShared :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadExclusiveAck :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: grantReadMigratory :: Nil = Enum(nGrantTypes){ UFix() }
|
val grantVoluntaryAck :: grantReadShared :: grantReadExclusive :: grantReadUncached :: grantWriteUncached :: grantReadExclusiveAck :: grantReadWordUncached :: grantWriteWordUncached :: grantAtomicUncached :: grantReadMigratory :: Nil = Enum(nGrantTypes){ UInt() }
|
||||||
|
|
||||||
val uncachedAcquireTypeList = List(acquireReadUncached, acquireWriteUncached, acquireReadWordUncached, acquireWriteWordUncached, acquireAtomicUncached)
|
val uncachedAcquireTypeList = List(acquireReadUncached, acquireWriteUncached, acquireReadWordUncached, acquireWriteWordUncached, acquireAtomicUncached)
|
||||||
val hasDataAcquireTypeList = List(acquireWriteUncached, acquireWriteWordUncached, acquireAtomicUncached)
|
val hasDataAcquireTypeList = List(acquireWriteUncached, acquireWriteWordUncached, acquireAtomicUncached)
|
||||||
val hasDataGrantTypeList = List(grantReadShared, grantReadExclusive, grantReadUncached, grantReadMigratory, grantReadWordUncached, grantAtomicUncached)
|
val hasDataGrantTypeList = List(grantReadShared, grantReadExclusive, grantReadUncached, grantReadMigratory, grantReadWordUncached, grantAtomicUncached)
|
||||||
val hasDataReleaseTypeList = List(releaseVoluntaryInvalidateData, releaseInvalidateData, releaseDowngradeData, releaseCopyData, releaseInvalidateDataMigratory, releaseDowngradeDataMigratory)
|
val hasDataReleaseTypeList = List(releaseVoluntaryInvalidateData, releaseInvalidateData, releaseDowngradeData, releaseCopyData, releaseInvalidateDataMigratory, releaseDowngradeDataMigratory)
|
||||||
|
|
||||||
def isHit (cmd: Bits, state: UFix): Bool = {
|
def isHit (cmd: UInt, state: UInt): Bool = {
|
||||||
Mux(isWriteIntent(cmd), uFixListContains(List(tileExclusiveClean, tileExclusiveDirty, tileMigratoryClean, tileMigratoryDirty), state), (state != tileInvalid))
|
Mux(isWriteIntent(cmd), uSIntListContains(List(tileExclusiveClean, tileExclusiveDirty, tileMigratoryClean, tileMigratoryDirty), state), (state != tileInvalid))
|
||||||
}
|
}
|
||||||
def isValid (state: UFix): Bool = {
|
def isValid (state: UInt): Bool = {
|
||||||
state != tileInvalid
|
state != tileInvalid
|
||||||
}
|
}
|
||||||
|
|
||||||
def needsTransactionOnSecondaryMiss(cmd: Bits, outstanding: Acquire): Bool = {
|
def needsTransactionOnSecondaryMiss(cmd: UInt, outstanding: Acquire): Bool = {
|
||||||
(isRead(cmd) && messageIsUncached(outstanding)) ||
|
(isRead(cmd) && messageIsUncached(outstanding)) ||
|
||||||
(isWriteIntent(cmd) && (outstanding.a_type != acquireReadExclusive && outstanding.a_type != acquireInvalidateOthers))
|
(isWriteIntent(cmd) && (outstanding.a_type != acquireReadExclusive && outstanding.a_type != acquireInvalidateOthers))
|
||||||
}
|
}
|
||||||
def needsTransactionOnCacheControl(cmd: Bits, state: UFix): Bool = {
|
def needsTransactionOnCacheControl(cmd: UInt, state: UInt): Bool = {
|
||||||
MuxLookup(cmd, (state === tileExclusiveDirty), Array(
|
MuxLookup(cmd, (state === tileExclusiveDirty), Array(
|
||||||
M_INV -> uFixListContains(List(tileExclusiveDirty,tileMigratoryDirty),state),
|
M_INV -> uSIntListContains(List(tileExclusiveDirty,tileMigratoryDirty),state),
|
||||||
M_CLN -> uFixListContains(List(tileExclusiveDirty,tileMigratoryDirty),state)
|
M_CLN -> uSIntListContains(List(tileExclusiveDirty,tileMigratoryDirty),state)
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
def needsWriteback (state: UFix): Bool = {
|
def needsWriteback (state: UInt): Bool = {
|
||||||
needsTransactionOnCacheControl(M_INV, state)
|
needsTransactionOnCacheControl(M_INV, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
def newStateOnHit(cmd: Bits, state: UFix): UFix = {
|
def newStateOnHit(cmd: UInt, state: UInt): UInt = {
|
||||||
Mux(isWrite(cmd), MuxLookup(state, tileExclusiveDirty, Array(
|
Mux(isWrite(cmd), MuxLookup(state, tileExclusiveDirty, Array(
|
||||||
tileExclusiveClean -> tileExclusiveDirty,
|
tileExclusiveClean -> tileExclusiveDirty,
|
||||||
tileMigratoryClean -> tileMigratoryDirty)), state)
|
tileMigratoryClean -> tileMigratoryDirty)), state)
|
||||||
}
|
}
|
||||||
def newStateOnCacheControl(cmd: Bits) = {
|
def newStateOnCacheControl(cmd: UInt) = {
|
||||||
MuxLookup(cmd, tileInvalid, Array(
|
MuxLookup(cmd, tileInvalid, Array(
|
||||||
M_INV -> tileInvalid,
|
M_INV -> tileInvalid,
|
||||||
M_CLN -> tileShared
|
M_CLN -> tileShared
|
||||||
@ -828,7 +828,7 @@ class MigratoryCoherence extends CoherencePolicyWithUncached {
|
|||||||
}
|
}
|
||||||
def newStateOnWriteback() = newStateOnCacheControl(M_INV)
|
def newStateOnWriteback() = newStateOnCacheControl(M_INV)
|
||||||
def newStateOnFlush() = newStateOnCacheControl(M_INV)
|
def newStateOnFlush() = newStateOnCacheControl(M_INV)
|
||||||
def newStateOnGrant(incoming: Grant, outstanding: Acquire): UFix = {
|
def newStateOnGrant(incoming: Grant, outstanding: Acquire): UInt = {
|
||||||
MuxLookup(incoming.g_type, tileInvalid, Array(
|
MuxLookup(incoming.g_type, tileInvalid, Array(
|
||||||
grantReadShared -> tileShared,
|
grantReadShared -> tileShared,
|
||||||
grantReadExclusive -> MuxLookup(outstanding.a_type, tileExclusiveDirty, Array(
|
grantReadExclusive -> MuxLookup(outstanding.a_type, tileExclusiveDirty, Array(
|
||||||
@ -846,7 +846,7 @@ class MigratoryCoherence extends CoherencePolicyWithUncached {
|
|||||||
acquireReadShared -> tileMigratoryClean))
|
acquireReadShared -> tileMigratoryClean))
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
def newStateOnProbe(incoming: Probe, state: UFix): Bits = {
|
def newStateOnProbe(incoming: Probe, state: UInt): Bits = {
|
||||||
MuxLookup(incoming.p_type, state, Array(
|
MuxLookup(incoming.p_type, state, Array(
|
||||||
probeInvalidate -> tileInvalid,
|
probeInvalidate -> tileInvalid,
|
||||||
probeInvalidateOthers -> tileInvalid,
|
probeInvalidateOthers -> tileInvalid,
|
||||||
@ -869,17 +869,17 @@ class MigratoryCoherence extends CoherencePolicyWithUncached {
|
|||||||
def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData
|
def isVoluntary(rel: Release) = rel.r_type === releaseVoluntaryInvalidateData
|
||||||
def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck
|
def isVoluntary(gnt: Grant) = gnt.g_type === grantVoluntaryAck
|
||||||
|
|
||||||
def getAcquireTypeOnPrimaryMiss(cmd: Bits, state: UFix): UFix = {
|
def getAcquireTypeOnPrimaryMiss(cmd: UInt, state: UInt): UInt = {
|
||||||
Mux(isWriteIntent(cmd), Mux(state === tileInvalid, acquireReadExclusive, acquireInvalidateOthers), acquireReadShared)
|
Mux(isWriteIntent(cmd), Mux(state === tileInvalid, acquireReadExclusive, acquireInvalidateOthers), acquireReadShared)
|
||||||
}
|
}
|
||||||
def getAcquireTypeOnSecondaryMiss(cmd: Bits, state: UFix, outstanding: Acquire): UFix = {
|
def getAcquireTypeOnSecondaryMiss(cmd: UInt, state: UInt, outstanding: Acquire): UInt = {
|
||||||
Mux(isWriteIntent(cmd), Mux(state === tileInvalid, acquireReadExclusive, acquireInvalidateOthers), outstanding.a_type)
|
Mux(isWriteIntent(cmd), Mux(state === tileInvalid, acquireReadExclusive, acquireInvalidateOthers), outstanding.a_type)
|
||||||
}
|
}
|
||||||
def getReleaseTypeOnCacheControl(cmd: Bits): Bits = releaseVoluntaryInvalidateData // TODO
|
def getReleaseTypeOnCacheControl(cmd: UInt): Bits = releaseVoluntaryInvalidateData // TODO
|
||||||
def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV)
|
def getReleaseTypeOnVoluntaryWriteback(): Bits = getReleaseTypeOnCacheControl(M_INV)
|
||||||
def getReleaseTypeOnProbe(incoming: Probe, state: UFix): Bits = {
|
def getReleaseTypeOnProbe(incoming: Probe, state: UInt): Bits = {
|
||||||
val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array(
|
val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array(
|
||||||
probeInvalidate -> Mux(uFixListContains(List(tileExclusiveDirty, tileMigratoryDirty), state),
|
probeInvalidate -> Mux(uSIntListContains(List(tileExclusiveDirty, tileMigratoryDirty), state),
|
||||||
releaseInvalidateDataMigratory, releaseInvalidateData),
|
releaseInvalidateDataMigratory, releaseInvalidateData),
|
||||||
probeDowngrade -> Mux(state === tileMigratoryDirty, releaseDowngradeDataMigratory, releaseDowngradeData),
|
probeDowngrade -> Mux(state === tileMigratoryDirty, releaseDowngradeDataMigratory, releaseDowngradeData),
|
||||||
probeCopy -> releaseCopyData
|
probeCopy -> releaseCopyData
|
||||||
@ -894,21 +894,21 @@ class MigratoryCoherence extends CoherencePolicyWithUncached {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def messageHasData(msg: SourcedMessage) = msg match {
|
def messageHasData(msg: SourcedMessage) = msg match {
|
||||||
case acq: Acquire => uFixListContains(hasDataAcquireTypeList, acq.a_type)
|
case acq: Acquire => uSIntListContains(hasDataAcquireTypeList, acq.a_type)
|
||||||
case grant: Grant => uFixListContains(hasDataGrantTypeList, grant.g_type)
|
case grant: Grant => uSIntListContains(hasDataGrantTypeList, grant.g_type)
|
||||||
case rel: Release => uFixListContains(hasDataReleaseTypeList, rel.r_type)
|
case rel: Release => uSIntListContains(hasDataReleaseTypeList, rel.r_type)
|
||||||
case _ => Bool(false)
|
case _ => Bool(false)
|
||||||
}
|
}
|
||||||
def messageUpdatesDataArray (reply: Grant): Bool = {
|
def messageUpdatesDataArray (reply: Grant): Bool = {
|
||||||
uFixListContains(List(grantReadShared, grantReadExclusive, grantReadMigratory), reply.g_type)
|
uSIntListContains(List(grantReadShared, grantReadExclusive, grantReadMigratory), reply.g_type)
|
||||||
}
|
}
|
||||||
def messageIsUncached(acq: Acquire): Bool = uFixListContains(uncachedAcquireTypeList, acq.a_type)
|
def messageIsUncached(acq: Acquire): Bool = uSIntListContains(uncachedAcquireTypeList, acq.a_type)
|
||||||
|
|
||||||
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2)
|
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2)
|
||||||
|
|
||||||
def getGrantType(a_type: UFix, count: UFix): Bits = {
|
def getGrantType(a_type: UInt, count: UInt): Bits = {
|
||||||
MuxLookup(a_type, grantReadUncached, Array(
|
MuxLookup(a_type, grantReadUncached, Array(
|
||||||
acquireReadShared -> Mux(count > UFix(0), grantReadShared, grantReadExclusive), //TODO: what is count? Depend on release.p_type???
|
acquireReadShared -> Mux(count > UInt(0), grantReadShared, grantReadExclusive), //TODO: what is count? Depend on release.p_type???
|
||||||
acquireReadExclusive -> grantReadExclusive,
|
acquireReadExclusive -> grantReadExclusive,
|
||||||
acquireReadUncached -> grantReadUncached,
|
acquireReadUncached -> grantReadUncached,
|
||||||
acquireWriteUncached -> grantWriteUncached,
|
acquireWriteUncached -> grantWriteUncached,
|
||||||
@ -918,14 +918,14 @@ class MigratoryCoherence extends CoherencePolicyWithUncached {
|
|||||||
acquireInvalidateOthers -> grantReadExclusiveAck //TODO: add this to MESI?
|
acquireInvalidateOthers -> grantReadExclusiveAck //TODO: add this to MESI?
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
def getGrantType(rel: Release, count: UFix): Bits = {
|
def getGrantType(rel: Release, count: UInt): Bits = {
|
||||||
MuxLookup(rel.r_type, grantReadUncached, Array(
|
MuxLookup(rel.r_type, grantReadUncached, Array(
|
||||||
releaseVoluntaryInvalidateData -> grantVoluntaryAck
|
releaseVoluntaryInvalidateData -> grantVoluntaryAck
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def getProbeType(a_type: UFix, global_state: UFix): UFix = {
|
def getProbeType(a_type: UInt, global_state: UInt): UInt = {
|
||||||
MuxLookup(a_type, probeCopy, Array(
|
MuxLookup(a_type, probeCopy, Array(
|
||||||
acquireReadShared -> probeDowngrade,
|
acquireReadShared -> probeDowngrade,
|
||||||
acquireReadExclusive -> probeInvalidate,
|
acquireReadExclusive -> probeInvalidate,
|
||||||
@ -938,18 +938,18 @@ class MigratoryCoherence extends CoherencePolicyWithUncached {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
def needsOuterRead(a_type: UFix, global_state: UFix): Bool = {
|
def needsOuterRead(a_type: UInt, global_state: UInt): Bool = {
|
||||||
(a_type != acquireWriteUncached && a_type != acquireInvalidateOthers)
|
(a_type != acquireWriteUncached && a_type != acquireInvalidateOthers)
|
||||||
}
|
}
|
||||||
def needsOuterWrite(a_type: UFix, global_state: UFix): Bool = {
|
def needsOuterWrite(a_type: UInt, global_state: UInt): Bool = {
|
||||||
(a_type === acquireWriteUncached || a_type === acquireWriteWordUncached || a_type === acquireAtomicUncached)
|
(a_type === acquireWriteUncached || a_type === acquireWriteWordUncached || a_type === acquireAtomicUncached)
|
||||||
}
|
}
|
||||||
def needsAckReply(a_type: UFix, global_state: UFix): Bool = {
|
def needsAckReply(a_type: UInt, global_state: UInt): Bool = {
|
||||||
(a_type === acquireWriteUncached || a_type === acquireWriteWordUncached ||a_type === acquireInvalidateOthers)
|
(a_type === acquireWriteUncached || a_type === acquireWriteWordUncached ||a_type === acquireInvalidateOthers)
|
||||||
}
|
}
|
||||||
def requiresAck(grant: Grant) = grant.g_type != grantVoluntaryAck
|
def requiresAck(grant: Grant) = grant.g_type != grantVoluntaryAck
|
||||||
def requiresAck(release: Release) = Bool(false)
|
def requiresAck(release: Release) = Bool(false)
|
||||||
def needsSelfProbe(acq: Acquire) = Bool(false)
|
def needsSelfProbe(acq: Acquire) = Bool(false)
|
||||||
|
|
||||||
def pendingVoluntaryReleaseIsSufficient(r_type: UFix, p_type: UFix): Bool = (r_type === releaseVoluntaryInvalidateData)
|
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData)
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
package uncore
|
package uncore
|
||||||
import Chisel._
|
import Chisel._
|
||||||
|
|
||||||
class BigMem[T <: Data](n: Int, preLatency: Int, postLatency: Int, leaf: Mem[Bits])(gen: => T) extends Component
|
class BigMem[T <: Data](n: Int, preLatency: Int, postLatency: Int, leaf: Mem[UInt])(gen: => T) extends Module
|
||||||
{
|
{
|
||||||
class Inputs extends Bundle {
|
class Inputs extends Bundle {
|
||||||
val addr = UFix(INPUT, log2Up(n))
|
val addr = UInt(INPUT, log2Up(n))
|
||||||
val rw = Bool(INPUT)
|
val rw = Bool(INPUT)
|
||||||
val wdata = gen.asInput
|
val wdata = gen.asInput
|
||||||
val wmask = gen.asInput
|
val wmask = gen.asInput
|
||||||
override def clone = new Inputs().asInstanceOf[this.type]
|
override def clone = new Inputs().asInstanceOf[this.type]
|
||||||
}
|
}
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val in = new PipeIO()(new Inputs).flip
|
val in = Valid(new Inputs).flip
|
||||||
val rdata = gen.asOutput
|
val rdata = gen.asOutput
|
||||||
}
|
}
|
||||||
val data = gen
|
val data = gen
|
||||||
@ -21,27 +21,27 @@ class BigMem[T <: Data](n: Int, preLatency: Int, postLatency: Int, leaf: Mem[Bit
|
|||||||
if (nDeep > 1 || colMux > 1)
|
if (nDeep > 1 || colMux > 1)
|
||||||
require(isPow2(n) && isPow2(leaf.n))
|
require(isPow2(n) && isPow2(leaf.n))
|
||||||
|
|
||||||
val rdataDeep = Vec(nDeep) { Bits() }
|
val rdataDeep = Vec.fill(nDeep){Bits()}
|
||||||
val rdataSel = Vec(nDeep) { Bool() }
|
val rdataSel = Vec.fill(nDeep){Bool()}
|
||||||
for (i <- 0 until nDeep) {
|
for (i <- 0 until nDeep) {
|
||||||
val in = Pipe(io.in.valid && (if (nDeep == 1) Bool(true) else UFix(i) === io.in.bits.addr(log2Up(n)-1, log2Up(n/nDeep))), io.in.bits, preLatency)
|
val in = Pipe(io.in.valid && (if (nDeep == 1) Bool(true) else UInt(i) === io.in.bits.addr(log2Up(n)-1, log2Up(n/nDeep))), io.in.bits, preLatency)
|
||||||
val idx = in.bits.addr(log2Up(n/nDeep/colMux)-1, 0)
|
val idx = in.bits.addr(log2Up(n/nDeep/colMux)-1, 0)
|
||||||
val wdata = in.bits.wdata.toBits
|
val wdata = in.bits.wdata.toBits
|
||||||
val wmask = in.bits.wmask.toBits
|
val wmask = in.bits.wmask.toBits
|
||||||
val ren = in.valid && !in.bits.rw
|
val ren = in.valid && !in.bits.rw
|
||||||
val reg_ren = Reg(ren)
|
val reg_ren = RegUpdate(ren)
|
||||||
val rdata = Vec(nWide) { Bits() }
|
val rdata = Vec.fill(nWide){Bits()}
|
||||||
|
|
||||||
val r = Pipe(ren, in.bits.addr, postLatency)
|
val r = Pipe(ren, in.bits.addr, postLatency)
|
||||||
|
|
||||||
for (j <- 0 until nWide) {
|
for (j <- 0 until nWide) {
|
||||||
val mem = leaf.clone
|
val mem = leaf.clone
|
||||||
var dout: Bits = null
|
var dout: Bits = null
|
||||||
val ridx = if (postLatency > 0) Reg() { Bits() } else null
|
val ridx = if (postLatency > 0) Reg(Bits()) else null
|
||||||
|
|
||||||
var wmask0 = Fill(colMux, wmask(math.min(wmask.getWidth, leaf.data.width*(j+1))-1, leaf.data.width*j))
|
var wmask0 = Fill(colMux, wmask(math.min(wmask.getWidth, leaf.data.width*(j+1))-1, leaf.data.width*j))
|
||||||
if (colMux > 1)
|
if (colMux > 1)
|
||||||
wmask0 = wmask0 & FillInterleaved(gen.width, UFixToOH(in.bits.addr(log2Up(n/nDeep)-1, log2Up(n/nDeep/colMux)), log2Up(colMux)))
|
wmask0 = wmask0 & FillInterleaved(gen.width, UIntToOH(in.bits.addr(log2Up(n/nDeep)-1, log2Up(n/nDeep/colMux)), log2Up(colMux)))
|
||||||
val wdata0 = Fill(colMux, wdata(math.min(wdata.getWidth, leaf.data.width*(j+1))-1, leaf.data.width*j))
|
val wdata0 = Fill(colMux, wdata(math.min(wdata.getWidth, leaf.data.width*(j+1))-1, leaf.data.width*j))
|
||||||
when (in.valid) {
|
when (in.valid) {
|
||||||
when (in.bits.rw) { mem.write(idx, wdata0, wmask0) }
|
when (in.bits.rw) { mem.write(idx, wdata0, wmask0) }
|
||||||
@ -61,7 +61,7 @@ class BigMem[T <: Data](n: Int, preLatency: Int, postLatency: Int, leaf: Mem[Bit
|
|||||||
|
|
||||||
var colMuxOut = rdataWide
|
var colMuxOut = rdataWide
|
||||||
if (colMux > 1) {
|
if (colMux > 1) {
|
||||||
val colMuxIn = Vec((0 until colMux).map(k => rdataWide(gen.width*(k+1)-1, gen.width*k))) { Bits() }
|
val colMuxIn = Vec((0 until colMux).map(k => rdataWide(gen.width*(k+1)-1, gen.width*k)))
|
||||||
colMuxOut = colMuxIn(r.bits(log2Up(n/nDeep)-1, log2Up(n/nDeep/colMux)))
|
colMuxOut = colMuxIn(r.bits(log2Up(n/nDeep)-1, log2Up(n/nDeep/colMux)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,47 +74,49 @@ class BigMem[T <: Data](n: Int, preLatency: Int, postLatency: Int, leaf: Mem[Bit
|
|||||||
|
|
||||||
class LLCDataReq(ways: Int) extends MemReqCmd
|
class LLCDataReq(ways: Int) extends MemReqCmd
|
||||||
{
|
{
|
||||||
val way = UFix(width = log2Up(ways))
|
val way = UInt(width = log2Up(ways))
|
||||||
val isWriteback = Bool()
|
val isWriteback = Bool()
|
||||||
|
|
||||||
override def clone = new LLCDataReq(ways).asInstanceOf[this.type]
|
override def clone = new LLCDataReq(ways).asInstanceOf[this.type]
|
||||||
}
|
}
|
||||||
|
|
||||||
class LLCMSHRFile(sets: Int, ways: Int, outstanding: Int) extends Component
|
class LLCTagReq(ways: Int) extends HasMemAddr
|
||||||
|
{
|
||||||
|
val way = UInt(width = log2Up(ways))
|
||||||
|
override def clone = new LLCTagReq(ways).asInstanceOf[this.type]
|
||||||
|
}
|
||||||
|
|
||||||
|
class LLCMSHRFile(sets: Int, ways: Int, outstanding: Int) extends Module
|
||||||
{
|
{
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val cpu = (new FIFOIO) { new MemReqCmd }.flip
|
val cpu = Decoupled(new MemReqCmd).flip
|
||||||
val repl_way = UFix(INPUT, log2Up(ways))
|
val repl_way = UInt(INPUT, log2Up(ways))
|
||||||
val repl_dirty = Bool(INPUT)
|
val repl_dirty = Bool(INPUT)
|
||||||
val repl_tag = UFix(INPUT, MEM_ADDR_BITS - log2Up(sets))
|
val repl_tag = UInt(INPUT, MEM_ADDR_BITS - log2Up(sets))
|
||||||
val data = (new FIFOIO) { new LLCDataReq(ways) }
|
val data = Decoupled(new LLCDataReq(ways))
|
||||||
val tag = (new FIFOIO) { new Bundle {
|
val tag = Decoupled(new LLCTagReq(ways))
|
||||||
val addr = UFix(width = MEM_ADDR_BITS)
|
|
||||||
val way = UFix(width = log2Up(ways))
|
|
||||||
} }
|
|
||||||
val mem = new ioMemPipe
|
val mem = new ioMemPipe
|
||||||
val mem_resp_set = UFix(OUTPUT, log2Up(sets))
|
val mem_resp_set = UInt(OUTPUT, log2Up(sets))
|
||||||
val mem_resp_way = UFix(OUTPUT, log2Up(ways))
|
val mem_resp_way = UInt(OUTPUT, log2Up(ways))
|
||||||
}
|
}
|
||||||
|
|
||||||
class MSHR extends Bundle {
|
class MSHR extends Bundle {
|
||||||
val addr = UFix(width = PADDR_BITS - OFFSET_BITS)
|
val addr = UInt(width = PADDR_BITS - OFFSET_BITS)
|
||||||
val way = UFix(width = log2Up(ways))
|
val way = UInt(width = log2Up(ways))
|
||||||
val tag = io.cpu.bits.tag.clone
|
val tag = io.cpu.bits.tag.clone
|
||||||
val refilled = Bool()
|
val refilled = Bool()
|
||||||
val refillCount = UFix(width = log2Up(REFILL_CYCLES))
|
val refillCount = UInt(width = log2Up(REFILL_CYCLES))
|
||||||
val requested = Bool()
|
val requested = Bool()
|
||||||
val old_dirty = Bool()
|
val old_dirty = Bool()
|
||||||
val old_tag = UFix(width = MEM_ADDR_BITS - log2Up(sets))
|
val old_tag = UInt(width = MEM_ADDR_BITS - log2Up(sets))
|
||||||
val wb_busy = Bool()
|
val wb_busy = Bool()
|
||||||
|
|
||||||
override def clone = new MSHR().asInstanceOf[this.type]
|
override def clone = new MSHR().asInstanceOf[this.type]
|
||||||
}
|
}
|
||||||
|
|
||||||
val valid = Vec(outstanding) { Reg(resetVal = Bool(false)) }
|
val valid = Vec.fill(outstanding){RegReset(Bool(false))}
|
||||||
val validBits = valid.toBits
|
val validBits = valid.toBits
|
||||||
val freeId = PriorityEncoder(~validBits)
|
val freeId = PriorityEncoder(~validBits)
|
||||||
val mshr = Vec(outstanding) { Reg() { new MSHR } }
|
val mshr = Vec.fill(outstanding){Reg(new MSHR)}
|
||||||
when (io.cpu.valid && io.cpu.ready) {
|
when (io.cpu.valid && io.cpu.ready) {
|
||||||
valid(freeId) := Bool(true)
|
valid(freeId) := Bool(true)
|
||||||
mshr(freeId).addr := io.cpu.bits.addr
|
mshr(freeId).addr := io.cpu.bits.addr
|
||||||
@ -124,7 +126,7 @@ class LLCMSHRFile(sets: Int, ways: Int, outstanding: Int) extends Component
|
|||||||
mshr(freeId).old_tag := io.repl_tag
|
mshr(freeId).old_tag := io.repl_tag
|
||||||
mshr(freeId).wb_busy := Bool(false)
|
mshr(freeId).wb_busy := Bool(false)
|
||||||
mshr(freeId).requested := Bool(false)
|
mshr(freeId).requested := Bool(false)
|
||||||
mshr(freeId).refillCount := UFix(0)
|
mshr(freeId).refillCount := UInt(0)
|
||||||
mshr(freeId).refilled := Bool(false)
|
mshr(freeId).refilled := Bool(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,8 +138,8 @@ class LLCMSHRFile(sets: Int, ways: Int, outstanding: Int) extends Component
|
|||||||
val refillId = io.mem.resp.bits.tag(log2Up(outstanding)-1, 0)
|
val refillId = io.mem.resp.bits.tag(log2Up(outstanding)-1, 0)
|
||||||
val refillCount = mshr(refillId).refillCount
|
val refillCount = mshr(refillId).refillCount
|
||||||
when (io.mem.resp.valid) {
|
when (io.mem.resp.valid) {
|
||||||
mshr(refillId).refillCount := refillCount + UFix(1)
|
mshr(refillId).refillCount := refillCount + UInt(1)
|
||||||
when (refillCount === UFix(REFILL_CYCLES-1)) { mshr(refillId).refilled := Bool(true) }
|
when (refillCount === UInt(REFILL_CYCLES-1)) { mshr(refillId).refilled := Bool(true) }
|
||||||
}
|
}
|
||||||
|
|
||||||
val replays = Cat(Bits(0), (outstanding-1 to 0 by -1).map(i => valid(i) && mshr(i).refilled):_*)
|
val replays = Cat(Bits(0), (outstanding-1 to 0 by -1).map(i => valid(i) && mshr(i).refilled):_*)
|
||||||
@ -161,7 +163,7 @@ class LLCMSHRFile(sets: Int, ways: Int, outstanding: Int) extends Component
|
|||||||
io.data.bits.rw := Bool(false)
|
io.data.bits.rw := Bool(false)
|
||||||
io.data.bits.tag := mshr(replayId).tag
|
io.data.bits.tag := mshr(replayId).tag
|
||||||
io.data.bits.isWriteback := Bool(true)
|
io.data.bits.isWriteback := Bool(true)
|
||||||
io.data.bits.addr := Cat(mshr(writebackId).old_tag, mshr(writebackId).addr(log2Up(sets)-1, 0)).toUFix
|
io.data.bits.addr := Cat(mshr(writebackId).old_tag, mshr(writebackId).addr(log2Up(sets)-1, 0)).toUInt
|
||||||
io.data.bits.way := mshr(writebackId).way
|
io.data.bits.way := mshr(writebackId).way
|
||||||
when (replay) {
|
when (replay) {
|
||||||
io.data.valid := io.tag.ready
|
io.data.valid := io.tag.ready
|
||||||
@ -181,25 +183,25 @@ class LLCMSHRFile(sets: Int, ways: Int, outstanding: Int) extends Component
|
|||||||
io.mem_resp_way := mshr(refillId).way
|
io.mem_resp_way := mshr(refillId).way
|
||||||
}
|
}
|
||||||
|
|
||||||
class LLCWriteback(requestors: Int) extends Component
|
class LLCWriteback(requestors: Int) extends Module
|
||||||
{
|
{
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val req = Vec(requestors) { (new FIFOIO) { UFix(width = MEM_ADDR_BITS) }.flip }
|
val req = Vec.fill(requestors){Decoupled(UInt(width = MEM_ADDR_BITS)).flip }
|
||||||
val data = Vec(requestors) { (new FIFOIO) { new MemData }.flip }
|
val data = Vec.fill(requestors){Decoupled(new MemData).flip }
|
||||||
val mem = new ioMemPipe
|
val mem = new ioMemPipe
|
||||||
}
|
}
|
||||||
|
|
||||||
val valid = Reg(resetVal = Bool(false))
|
val valid = RegReset(Bool(false))
|
||||||
val who = Reg() { UFix() }
|
val who = Reg(UInt())
|
||||||
val addr = Reg() { UFix() }
|
val addr = Reg(UInt())
|
||||||
val cmd_sent = Reg() { Bool() }
|
val cmd_sent = Reg(Bool())
|
||||||
val data_sent = Reg() { Bool() }
|
val data_sent = Reg(Bool())
|
||||||
val count = Reg(resetVal = UFix(0, log2Up(REFILL_CYCLES)))
|
val count = RegReset(UInt(0, log2Up(REFILL_CYCLES)))
|
||||||
|
|
||||||
var anyReq = Bool(false)
|
var anyReq = Bool(false)
|
||||||
for (i <- 0 until requestors) {
|
for (i <- 0 until requestors) {
|
||||||
io.req(i).ready := !valid && !anyReq
|
io.req(i).ready := !valid && !anyReq
|
||||||
io.data(i).ready := valid && who === UFix(i) && io.mem.req_data.ready
|
io.data(i).ready := valid && who === UInt(i) && io.mem.req_data.ready
|
||||||
anyReq = anyReq || io.req(i).valid
|
anyReq = anyReq || io.req(i).valid
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,8 +215,8 @@ class LLCWriteback(requestors: Int) extends Component
|
|||||||
}
|
}
|
||||||
|
|
||||||
when (io.mem.req_data.valid && io.mem.req_data.ready) {
|
when (io.mem.req_data.valid && io.mem.req_data.ready) {
|
||||||
count := count + UFix(1)
|
count := count + UInt(1)
|
||||||
when (count === UFix(REFILL_CYCLES-1)) {
|
when (count === UInt(REFILL_CYCLES-1)) {
|
||||||
data_sent := Bool(true)
|
data_sent := Bool(true)
|
||||||
when (cmd_sent) { valid := Bool(false) }
|
when (cmd_sent) { valid := Bool(false) }
|
||||||
}
|
}
|
||||||
@ -230,51 +232,51 @@ class LLCWriteback(requestors: Int) extends Component
|
|||||||
io.mem.req_data.bits := io.data(who).bits
|
io.mem.req_data.bits := io.data(who).bits
|
||||||
}
|
}
|
||||||
|
|
||||||
class LLCData(latency: Int, sets: Int, ways: Int, leaf: Mem[Bits]) extends Component
|
class LLCData(latency: Int, sets: Int, ways: Int, leaf: Mem[UInt]) extends Module
|
||||||
{
|
{
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val req = (new FIFOIO) { new LLCDataReq(ways) }.flip
|
val req = Decoupled(new LLCDataReq(ways)).flip
|
||||||
val req_data = (new FIFOIO) { new MemData }.flip
|
val req_data = Decoupled(new MemData).flip
|
||||||
val writeback = (new FIFOIO) { UFix(width = MEM_ADDR_BITS) }
|
val writeback = Decoupled(UInt(width = MEM_ADDR_BITS))
|
||||||
val writeback_data = (new FIFOIO) { new MemData }
|
val writeback_data = Decoupled(new MemData)
|
||||||
val resp = (new FIFOIO) { new MemResp }
|
val resp = Decoupled(new MemResp)
|
||||||
val mem_resp = (new PipeIO) { new MemResp }.flip
|
val mem_resp = Valid(new MemResp).flip
|
||||||
val mem_resp_set = UFix(INPUT, log2Up(sets))
|
val mem_resp_set = UInt(INPUT, log2Up(sets))
|
||||||
val mem_resp_way = UFix(INPUT, log2Up(ways))
|
val mem_resp_way = UInt(INPUT, log2Up(ways))
|
||||||
}
|
}
|
||||||
|
|
||||||
val data = new BigMem(sets*ways*REFILL_CYCLES, 1, latency-1, leaf)(Bits(width = MEM_DATA_BITS))
|
val data = Module(new BigMem(sets*ways*REFILL_CYCLES, 1, latency-1, leaf)(Bits(width = MEM_DATA_BITS)))
|
||||||
class QEntry extends MemResp {
|
class QEntry extends MemResp {
|
||||||
val isWriteback = Bool()
|
val isWriteback = Bool()
|
||||||
override def clone = new QEntry().asInstanceOf[this.type]
|
override def clone = new QEntry().asInstanceOf[this.type]
|
||||||
}
|
}
|
||||||
val q = (new Queue(latency+2)) { new QEntry }
|
val q = Module(new Queue(new QEntry, latency+2))
|
||||||
val qReady = q.io.count <= UFix(q.entries-latency-1)
|
val qReady = q.io.count <= UInt(q.entries-latency-1)
|
||||||
val valid = Reg(resetVal = Bool(false))
|
val valid = RegReset(Bool(false))
|
||||||
val req = Reg() { io.req.bits.clone }
|
val req = Reg(io.req.bits.clone)
|
||||||
val count = Reg(resetVal = UFix(0, log2Up(REFILL_CYCLES)))
|
val count = RegReset(UInt(0, log2Up(REFILL_CYCLES)))
|
||||||
val refillCount = Reg(resetVal = UFix(0, log2Up(REFILL_CYCLES)))
|
val refillCount = RegReset(UInt(0, log2Up(REFILL_CYCLES)))
|
||||||
|
|
||||||
when (data.io.in.valid && !io.mem_resp.valid) {
|
when (data.io.in.valid && !io.mem_resp.valid) {
|
||||||
count := count + UFix(1)
|
count := count + UInt(1)
|
||||||
when (valid && count === UFix(REFILL_CYCLES-1)) { valid := Bool(false) }
|
when (valid && count === UInt(REFILL_CYCLES-1)) { valid := Bool(false) }
|
||||||
}
|
}
|
||||||
when (io.req.valid && io.req.ready) { valid := Bool(true); req := io.req.bits }
|
when (io.req.valid && io.req.ready) { valid := Bool(true); req := io.req.bits }
|
||||||
when (io.mem_resp.valid) { refillCount := refillCount + UFix(1) }
|
when (io.mem_resp.valid) { refillCount := refillCount + UInt(1) }
|
||||||
|
|
||||||
data.io.in.valid := io.req.valid && io.req.ready && Mux(io.req.bits.rw, io.req_data.valid, qReady)
|
data.io.in.valid := io.req.valid && io.req.ready && Mux(io.req.bits.rw, io.req_data.valid, qReady)
|
||||||
data.io.in.bits.addr := Cat(io.req.bits.way, io.req.bits.addr(log2Up(sets)-1, 0), count).toUFix
|
data.io.in.bits.addr := Cat(io.req.bits.way, io.req.bits.addr(log2Up(sets)-1, 0), count).toUInt
|
||||||
data.io.in.bits.rw := io.req.bits.rw
|
data.io.in.bits.rw := io.req.bits.rw
|
||||||
data.io.in.bits.wdata := io.req_data.bits.data
|
data.io.in.bits.wdata := io.req_data.bits.data
|
||||||
data.io.in.bits.wmask := Fix(-1, io.req_data.bits.data.width)
|
data.io.in.bits.wmask := SInt(-1, io.req_data.bits.data.width)
|
||||||
when (valid) {
|
when (valid) {
|
||||||
data.io.in.valid := Mux(req.rw, io.req_data.valid, qReady)
|
data.io.in.valid := Mux(req.rw, io.req_data.valid, qReady)
|
||||||
data.io.in.bits.addr := Cat(req.way, req.addr(log2Up(sets)-1, 0), count).toUFix
|
data.io.in.bits.addr := Cat(req.way, req.addr(log2Up(sets)-1, 0), count).toUInt
|
||||||
data.io.in.bits.rw := req.rw
|
data.io.in.bits.rw := req.rw
|
||||||
}
|
}
|
||||||
when (io.mem_resp.valid) {
|
when (io.mem_resp.valid) {
|
||||||
data.io.in.valid := Bool(true)
|
data.io.in.valid := Bool(true)
|
||||||
data.io.in.bits.addr := Cat(io.mem_resp_way, io.mem_resp_set, refillCount).toUFix
|
data.io.in.bits.addr := Cat(io.mem_resp_way, io.mem_resp_set, refillCount).toUInt
|
||||||
data.io.in.bits.rw := Bool(true)
|
data.io.in.bits.rw := Bool(true)
|
||||||
data.io.in.bits.wdata := io.mem_resp.bits.data
|
data.io.in.bits.wdata := io.mem_resp.bits.data
|
||||||
}
|
}
|
||||||
@ -298,21 +300,21 @@ class LLCData(latency: Int, sets: Int, ways: Int, leaf: Mem[Bits]) extends Compo
|
|||||||
io.writeback_data.bits := q.io.deq.bits
|
io.writeback_data.bits := q.io.deq.bits
|
||||||
}
|
}
|
||||||
|
|
||||||
class MemReqArb(n: Int) extends Component // UNTESTED
|
class MemReqArb(n: Int) extends Module // UNTESTED
|
||||||
{
|
{
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val cpu = Vec(n) { new ioMem().flip }
|
val cpu = Vec.fill(n){new ioMem().flip}
|
||||||
val mem = new ioMem
|
val mem = new ioMem
|
||||||
}
|
}
|
||||||
|
|
||||||
val lock = Reg(resetVal = Bool(false))
|
val lock = RegReset(Bool(false))
|
||||||
val locker = Reg() { UFix() }
|
val locker = Reg(UInt())
|
||||||
|
|
||||||
val arb = new RRArbiter(n)(new MemReqCmd)
|
val arb = Module(new RRArbiter(new MemReqCmd, n))
|
||||||
val respWho = io.mem.resp.bits.tag(log2Up(n)-1,0)
|
val respWho = io.mem.resp.bits.tag(log2Up(n)-1,0)
|
||||||
val respTag = io.mem.resp.bits.tag >> UFix(log2Up(n))
|
val respTag = io.mem.resp.bits.tag >> UInt(log2Up(n))
|
||||||
for (i <- 0 until n) {
|
for (i <- 0 until n) {
|
||||||
val me = UFix(i, log2Up(n))
|
val me = UInt(i, log2Up(n))
|
||||||
arb.io.in(i).valid := io.cpu(i).req_cmd.valid
|
arb.io.in(i).valid := io.cpu(i).req_cmd.valid
|
||||||
arb.io.in(i).bits := io.cpu(i).req_cmd.bits
|
arb.io.in(i).bits := io.cpu(i).req_cmd.bits
|
||||||
arb.io.in(i).bits.tag := Cat(io.cpu(i).req_cmd.bits.tag, me)
|
arb.io.in(i).bits.tag := Cat(io.cpu(i).req_cmd.bits.tag, me)
|
||||||
@ -323,7 +325,7 @@ class MemReqArb(n: Int) extends Component // UNTESTED
|
|||||||
val haveLock = lock && locker === me
|
val haveLock = lock && locker === me
|
||||||
when (getLock) {
|
when (getLock) {
|
||||||
lock := Bool(true)
|
lock := Bool(true)
|
||||||
locker := UFix(i)
|
locker := UInt(i)
|
||||||
}
|
}
|
||||||
when (getLock || haveLock) {
|
when (getLock || haveLock) {
|
||||||
io.cpu(i).req_data.ready := io.mem.req_data.ready
|
io.cpu(i).req_data.ready := io.mem.req_data.ready
|
||||||
@ -341,7 +343,7 @@ class MemReqArb(n: Int) extends Component // UNTESTED
|
|||||||
when (unlock) { lock := Bool(false) }
|
when (unlock) { lock := Bool(false) }
|
||||||
}
|
}
|
||||||
|
|
||||||
class DRAMSideLLC(sets: Int, ways: Int, outstanding: Int, tagLeaf: Mem[Bits], dataLeaf: Mem[Bits]) extends Component
|
class DRAMSideLLC(sets: Int, ways: Int, outstanding: Int, tagLeaf: Mem[UInt], dataLeaf: Mem[UInt]) extends Module
|
||||||
{
|
{
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val cpu = new ioMem().flip
|
val cpu = new ioMem().flip
|
||||||
@ -351,48 +353,48 @@ class DRAMSideLLC(sets: Int, ways: Int, outstanding: Int, tagLeaf: Mem[Bits], da
|
|||||||
val tagWidth = MEM_ADDR_BITS - log2Up(sets)
|
val tagWidth = MEM_ADDR_BITS - log2Up(sets)
|
||||||
val metaWidth = tagWidth + 2 // valid + dirty
|
val metaWidth = tagWidth + 2 // valid + dirty
|
||||||
|
|
||||||
val memCmdArb = (new Arbiter(2)) { new MemReqCmd }
|
val memCmdArb = Module(new Arbiter(new MemReqCmd, 2))
|
||||||
val dataArb = (new Arbiter(2)) { new LLCDataReq(ways) }
|
val dataArb = Module(new Arbiter(new LLCDataReq(ways), 2))
|
||||||
val mshr = new LLCMSHRFile(sets, ways, outstanding)
|
val mshr = Module(new LLCMSHRFile(sets, ways, outstanding))
|
||||||
val tags = new BigMem(sets, 0, 1, tagLeaf)(Bits(width = metaWidth*ways))
|
val tags = Module(new BigMem(sets, 0, 1, tagLeaf)(Bits(width = metaWidth*ways)))
|
||||||
val data = new LLCData(4, sets, ways, dataLeaf)
|
val data = Module(new LLCData(4, sets, ways, dataLeaf))
|
||||||
val writeback = new LLCWriteback(2)
|
val writeback = Module(new LLCWriteback(2))
|
||||||
|
|
||||||
val initCount = Reg(resetVal = UFix(0, log2Up(sets+1)))
|
val initCount = RegReset(UInt(0, log2Up(sets+1)))
|
||||||
val initialize = !initCount(log2Up(sets))
|
val initialize = !initCount(log2Up(sets))
|
||||||
when (initialize) { initCount := initCount + UFix(1) }
|
when (initialize) { initCount := initCount + UInt(1) }
|
||||||
|
|
||||||
val replay_s2 = Reg(resetVal = Bool(false))
|
val replay_s2 = RegReset(Bool(false))
|
||||||
val s2_valid = Reg(resetVal = Bool(false))
|
val s2_valid = RegReset(Bool(false))
|
||||||
val s2 = Reg() { new MemReqCmd }
|
val s2 = Reg(new MemReqCmd)
|
||||||
val s3_rdy = Bool()
|
val s3_rdy = Bool()
|
||||||
val replay_s2_rdy = Bool()
|
val replay_s2_rdy = Bool()
|
||||||
|
|
||||||
val s1_valid = Reg(io.cpu.req_cmd.fire() || replay_s2 && replay_s2_rdy, resetVal = Bool(false))
|
val s1_valid = Reg(update = io.cpu.req_cmd.fire() || replay_s2 && replay_s2_rdy, reset = Bool(false))
|
||||||
val s1 = Reg() { new MemReqCmd }
|
val s1 = Reg(new MemReqCmd)
|
||||||
when (io.cpu.req_cmd.fire()) { s1 := io.cpu.req_cmd.bits }
|
when (io.cpu.req_cmd.fire()) { s1 := io.cpu.req_cmd.bits }
|
||||||
when (replay_s2 && replay_s2_rdy) { s1 := s2 }
|
when (replay_s2 && replay_s2_rdy) { s1 := s2 }
|
||||||
|
|
||||||
s2_valid := s1_valid
|
s2_valid := s1_valid
|
||||||
replay_s2 := s2_valid && !s3_rdy || replay_s2 && !replay_s2_rdy
|
replay_s2 := s2_valid && !s3_rdy || replay_s2 && !replay_s2_rdy
|
||||||
val s2_tags = Vec(ways) { Reg() { Bits(width = metaWidth) } }
|
val s2_tags = Vec.fill(ways){Reg(Bits(width = metaWidth))}
|
||||||
when (s1_valid) {
|
when (s1_valid) {
|
||||||
s2 := s1
|
s2 := s1
|
||||||
for (i <- 0 until ways)
|
for (i <- 0 until ways)
|
||||||
s2_tags(i) := tags.io.rdata(metaWidth*(i+1)-1, metaWidth*i)
|
s2_tags(i) := tags.io.rdata(metaWidth*(i+1)-1, metaWidth*i)
|
||||||
}
|
}
|
||||||
val s2_hits = s2_tags.map(t => t(tagWidth) && s2.addr(s2.addr.width-1, s2.addr.width-tagWidth) === t(tagWidth-1, 0))
|
val s2_hits = s2_tags.map(t => t(tagWidth) && s2.addr(s2.addr.width-1, s2.addr.width-tagWidth) === t(tagWidth-1, 0))
|
||||||
val s2_hit_way = OHToUFix(s2_hits)
|
val s2_hit_way = OHToUInt(s2_hits)
|
||||||
val s2_hit = s2_hits.reduceLeft(_||_)
|
val s2_hit = s2_hits.reduceLeft(_||_)
|
||||||
val s2_hit_dirty = s2_tags(s2_hit_way)(tagWidth+1)
|
val s2_hit_dirty = s2_tags(s2_hit_way)(tagWidth+1)
|
||||||
val repl_way = LFSR16(s2_valid)(log2Up(ways)-1, 0)
|
val repl_way = LFSR16(s2_valid)(log2Up(ways)-1, 0)
|
||||||
val repl_tag = s2_tags(repl_way).toUFix
|
val repl_tag = s2_tags(repl_way).toUInt
|
||||||
val setDirty = s2_valid && s2.rw && s2_hit && !s2_hit_dirty
|
val setDirty = s2_valid && s2.rw && s2_hit && !s2_hit_dirty
|
||||||
|
|
||||||
val tag_we = initialize || setDirty || mshr.io.tag.fire()
|
val tag_we = initialize || setDirty || mshr.io.tag.fire()
|
||||||
val tag_waddr = Mux(initialize, initCount, Mux(setDirty, s2.addr, mshr.io.tag.bits.addr))
|
val tag_waddr = Mux(initialize, initCount, Mux(setDirty, s2.addr, mshr.io.tag.bits.addr))
|
||||||
val tag_wdata = Cat(setDirty, !initialize, Mux(setDirty, s2.addr, mshr.io.tag.bits.addr)(mshr.io.tag.bits.addr.width-1, mshr.io.tag.bits.addr.width-tagWidth))
|
val tag_wdata = Cat(setDirty, !initialize, Mux(setDirty, s2.addr, mshr.io.tag.bits.addr)(mshr.io.tag.bits.addr.width-1, mshr.io.tag.bits.addr.width-tagWidth))
|
||||||
val tag_wmask = Mux(initialize, Fix(-1, ways), UFixToOH(Mux(setDirty, s2_hit_way, mshr.io.tag.bits.way)))
|
val tag_wmask = Mux(initialize, SInt(-1, ways), UIntToOH(Mux(setDirty, s2_hit_way, mshr.io.tag.bits.way)))
|
||||||
tags.io.in.valid := io.cpu.req_cmd.fire() || replay_s2 && replay_s2_rdy || tag_we
|
tags.io.in.valid := io.cpu.req_cmd.fire() || replay_s2 && replay_s2_rdy || tag_we
|
||||||
tags.io.in.bits.addr := Mux(tag_we, tag_waddr, Mux(replay_s2, s2.addr, io.cpu.req_cmd.bits.addr)(log2Up(sets)-1,0))
|
tags.io.in.bits.addr := Mux(tag_we, tag_waddr, Mux(replay_s2, s2.addr, io.cpu.req_cmd.bits.addr)(log2Up(sets)-1,0))
|
||||||
tags.io.in.bits.rw := tag_we
|
tags.io.in.bits.rw := tag_we
|
||||||
@ -440,16 +442,16 @@ class DRAMSideLLC(sets: Int, ways: Int, outstanding: Int, tagLeaf: Mem[Bits], da
|
|||||||
io.mem.req_data <> writeback.io.mem.req_data
|
io.mem.req_data <> writeback.io.mem.req_data
|
||||||
}
|
}
|
||||||
|
|
||||||
class HellaFlowQueue[T <: Data](val entries: Int)(data: => T) extends Component
|
class HellaFlowQueue[T <: Data](val entries: Int)(data: => T) extends Module
|
||||||
{
|
{
|
||||||
val io = new ioQueue(entries)(data)
|
val io = new QueueIO(data, entries)
|
||||||
require(isPow2(entries) && entries > 1)
|
require(isPow2(entries) && entries > 1)
|
||||||
|
|
||||||
val do_flow = Bool()
|
val do_flow = Bool()
|
||||||
val do_enq = io.enq.fire() && !do_flow
|
val do_enq = io.enq.fire() && !do_flow
|
||||||
val do_deq = io.deq.fire() && !do_flow
|
val do_deq = io.deq.fire() && !do_flow
|
||||||
|
|
||||||
val maybe_full = Reg(resetVal = Bool(false))
|
val maybe_full = RegReset(Bool(false))
|
||||||
val enq_ptr = Counter(do_enq, entries)._1
|
val enq_ptr = Counter(do_enq, entries)._1
|
||||||
val deq_ptr = Counter(do_deq, entries)._1
|
val deq_ptr = Counter(do_deq, entries)._1
|
||||||
when (do_enq != do_deq) { maybe_full := do_enq }
|
when (do_enq != do_deq) { maybe_full := do_enq }
|
||||||
@ -457,37 +459,37 @@ class HellaFlowQueue[T <: Data](val entries: Int)(data: => T) extends Component
|
|||||||
val ptr_match = enq_ptr === deq_ptr
|
val ptr_match = enq_ptr === deq_ptr
|
||||||
val empty = ptr_match && !maybe_full
|
val empty = ptr_match && !maybe_full
|
||||||
val full = ptr_match && maybe_full
|
val full = ptr_match && maybe_full
|
||||||
val atLeastTwo = full || enq_ptr - deq_ptr >= UFix(2)
|
val atLeastTwo = full || enq_ptr - deq_ptr >= UInt(2)
|
||||||
do_flow := empty && io.deq.ready
|
do_flow := empty && io.deq.ready
|
||||||
|
|
||||||
val ram = Mem(entries, seqRead = true){Bits(width = data.getWidth)}
|
val ram = Mem(data, entries, seqRead = true)
|
||||||
val ram_addr = Reg{Bits()}
|
val ram_addr = Reg(Bits())
|
||||||
val ram_out_valid = Reg{Bool()}
|
val ram_out_valid = Reg(Bool())
|
||||||
ram_out_valid := Bool(false)
|
ram_out_valid := Bool(false)
|
||||||
when (do_enq) { ram(enq_ptr) := io.enq.bits.toBits }
|
when (do_enq) { ram(enq_ptr) := io.enq.bits.toBits }
|
||||||
when (io.deq.ready && (atLeastTwo || !io.deq.valid && !empty)) {
|
when (io.deq.ready && (atLeastTwo || !io.deq.valid && !empty)) {
|
||||||
ram_out_valid := Bool(true)
|
ram_out_valid := Bool(true)
|
||||||
ram_addr := Mux(io.deq.valid, deq_ptr + UFix(1), deq_ptr)
|
ram_addr := Mux(io.deq.valid, deq_ptr + UInt(1), deq_ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
io.deq.valid := Mux(empty, io.enq.valid, ram_out_valid)
|
io.deq.valid := Mux(empty, io.enq.valid, ram_out_valid)
|
||||||
io.enq.ready := !full
|
io.enq.ready := !full
|
||||||
io.deq.bits := Mux(empty, io.enq.bits, data.fromBits(ram(ram_addr)))
|
io.deq.bits := Mux(empty, io.enq.bits, ram(ram_addr))
|
||||||
}
|
}
|
||||||
|
|
||||||
class HellaQueue[T <: Data](val entries: Int)(data: => T) extends Component
|
class HellaQueue[T <: Data](val entries: Int)(data: => T) extends Module
|
||||||
{
|
{
|
||||||
val io = new ioQueue(entries)(data)
|
val io = new QueueIO(data, entries)
|
||||||
|
|
||||||
val fq = new HellaFlowQueue(entries)(data)
|
val fq = Module(new HellaFlowQueue(entries)(data))
|
||||||
io.enq <> fq.io.enq
|
io.enq <> fq.io.enq
|
||||||
io.deq <> Queue(fq.io.deq, 1, pipe = true)
|
io.deq <> Queue(fq.io.deq, 1, pipe = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
object HellaQueue
|
object HellaQueue
|
||||||
{
|
{
|
||||||
def apply[T <: Data](enq: FIFOIO[T], entries: Int) = {
|
def apply[T <: Data](enq: DecoupledIO[T], entries: Int) = {
|
||||||
val q = (new HellaQueue(entries)) { enq.bits.clone }
|
val q = Module((new HellaQueue(entries)) { enq.bits.clone })
|
||||||
q.io.enq.valid := enq.valid // not using <> so that override is allowed
|
q.io.enq.valid := enq.valid // not using <> so that override is allowed
|
||||||
q.io.enq.bits := enq.bits
|
q.io.enq.bits := enq.bits
|
||||||
enq.ready := q.io.enq.ready
|
enq.ready := q.io.enq.ready
|
||||||
@ -495,7 +497,7 @@ object HellaQueue
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DRAMSideLLCNull(numRequests: Int, refillCycles: Int) extends Component
|
class DRAMSideLLCNull(numRequests: Int, refillCycles: Int) extends Module
|
||||||
{
|
{
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val cpu = new ioMem().flip
|
val cpu = new ioMem().flip
|
||||||
@ -507,17 +509,17 @@ class DRAMSideLLCNull(numRequests: Int, refillCycles: Int) extends Component
|
|||||||
|
|
||||||
val inc = Bool()
|
val inc = Bool()
|
||||||
val dec = Bool()
|
val dec = Bool()
|
||||||
val count = Reg(resetVal = UFix(numEntries, size))
|
val count = RegReset(UInt(numEntries, size))
|
||||||
val watermark = count >= UFix(refillCycles)
|
val watermark = count >= UInt(refillCycles)
|
||||||
|
|
||||||
when (inc && !dec) {
|
when (inc && !dec) {
|
||||||
count := count + UFix(1)
|
count := count + UInt(1)
|
||||||
}
|
}
|
||||||
when (!inc && dec) {
|
when (!inc && dec) {
|
||||||
count := count - UFix(refillCycles)
|
count := count - UInt(refillCycles)
|
||||||
}
|
}
|
||||||
when (inc && dec) {
|
when (inc && dec) {
|
||||||
count := count - UFix(refillCycles-1)
|
count := count - UInt(refillCycles-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
val cmdq_mask = io.cpu.req_cmd.bits.rw || watermark
|
val cmdq_mask = io.cpu.req_cmd.bits.rw || watermark
|
||||||
@ -528,7 +530,7 @@ class DRAMSideLLCNull(numRequests: Int, refillCycles: Int) extends Component
|
|||||||
|
|
||||||
io.mem.req_data <> io.cpu.req_data
|
io.mem.req_data <> io.cpu.req_data
|
||||||
|
|
||||||
val resp_dataq = (new HellaQueue(numEntries)) { new MemResp }
|
val resp_dataq = Module((new HellaQueue(numEntries)) { new MemResp })
|
||||||
resp_dataq.io.enq <> io.mem.resp
|
resp_dataq.io.enq <> io.mem.resp
|
||||||
io.cpu.resp <> resp_dataq.io.deq
|
io.cpu.resp <> resp_dataq.io.deq
|
||||||
|
|
||||||
|
@ -2,40 +2,45 @@ package uncore
|
|||||||
import Chisel._
|
import Chisel._
|
||||||
import scala.math._
|
import scala.math._
|
||||||
|
|
||||||
class MemData extends Bundle {
|
trait HasMemData extends Bundle {
|
||||||
val data = Bits(width = MEM_DATA_BITS)
|
val data = Bits(width = MEM_DATA_BITS)
|
||||||
}
|
}
|
||||||
|
|
||||||
class MemReqCmd extends Bundle {
|
trait HasMemAddr extends Bundle {
|
||||||
val addr = UFix(width = MEM_ADDR_BITS)
|
val addr = UInt(width = MEM_ADDR_BITS)
|
||||||
|
}
|
||||||
|
|
||||||
|
trait HasMemTag extends Bundle {
|
||||||
|
val tag = UInt(width = MEM_TAG_BITS)
|
||||||
|
}
|
||||||
|
|
||||||
|
class MemReqCmd extends HasMemAddr with HasMemTag {
|
||||||
val rw = Bool()
|
val rw = Bool()
|
||||||
val tag = Bits(width = MEM_TAG_BITS)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class MemResp extends Bundle {
|
class MemResp extends HasMemData with HasMemTag
|
||||||
val tag = Bits(width = MEM_TAG_BITS)
|
|
||||||
val data = Bits(width = MEM_DATA_BITS)
|
class MemData extends HasMemData
|
||||||
}
|
|
||||||
|
|
||||||
class ioMem extends Bundle {
|
class ioMem extends Bundle {
|
||||||
val req_cmd = (new FIFOIO) { new MemReqCmd() }
|
val req_cmd = Decoupled(new MemReqCmd)
|
||||||
val req_data = (new FIFOIO) { new MemData() }
|
val req_data = Decoupled(new MemData)
|
||||||
val resp = (new FIFOIO) { new MemResp() }.flip
|
val resp = Decoupled(new MemResp).flip
|
||||||
}
|
}
|
||||||
|
|
||||||
class ioMemPipe extends Bundle {
|
class ioMemPipe extends Bundle {
|
||||||
val req_cmd = (new FIFOIO) { new MemReqCmd() }
|
val req_cmd = Decoupled(new MemReqCmd)
|
||||||
val req_data = (new FIFOIO) { new MemData() }
|
val req_data = Decoupled(new MemData)
|
||||||
val resp = (new PipeIO) { new MemResp() }.flip
|
val resp = Valid(new MemResp).flip
|
||||||
}
|
}
|
||||||
|
|
||||||
class ioMemSerialized(w: Int) extends Bundle
|
class ioMemSerialized(w: Int) extends Bundle
|
||||||
{
|
{
|
||||||
val req = (new FIFOIO) { Bits(width = w) }
|
val req = Decoupled(Bits(width = w))
|
||||||
val resp = (new PipeIO) { Bits(width = w) }.flip
|
val resp = Valid(Bits(width = w)).flip
|
||||||
}
|
}
|
||||||
|
|
||||||
class MemSerdes(w: Int) extends Component
|
class MemSerdes(w: Int) extends Module
|
||||||
{
|
{
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val wide = new ioMem().flip
|
val wide = new ioMem().flip
|
||||||
@ -45,19 +50,19 @@ class MemSerdes(w: Int) extends Component
|
|||||||
val dbits = io.wide.req_data.bits.toBits.getWidth
|
val dbits = io.wide.req_data.bits.toBits.getWidth
|
||||||
val rbits = io.wide.resp.bits.getWidth
|
val rbits = io.wide.resp.bits.getWidth
|
||||||
|
|
||||||
val out_buf = Reg() { Bits() }
|
val out_buf = Reg(Bits())
|
||||||
val in_buf = Reg() { Bits() }
|
val in_buf = Reg(Bits())
|
||||||
|
|
||||||
val s_idle :: s_read_addr :: s_write_addr :: s_write_idle :: s_write_data :: Nil = Enum(5) { UFix() }
|
val s_idle :: s_read_addr :: s_write_addr :: s_write_idle :: s_write_data :: Nil = Enum(5) { UInt() }
|
||||||
val state = Reg(resetVal = s_idle)
|
val state = RegReset(s_idle)
|
||||||
val send_cnt = Reg(resetVal = UFix(0, log2Up((max(abits, dbits)+w-1)/w)))
|
val send_cnt = RegReset(UInt(0, log2Up((max(abits, dbits)+w-1)/w)))
|
||||||
val data_send_cnt = Reg(resetVal = UFix(0, log2Up(REFILL_CYCLES)))
|
val data_send_cnt = RegReset(UInt(0, log2Up(REFILL_CYCLES)))
|
||||||
val adone = io.narrow.req.ready && send_cnt === UFix((abits-1)/w)
|
val adone = io.narrow.req.ready && send_cnt === UInt((abits-1)/w)
|
||||||
val ddone = io.narrow.req.ready && send_cnt === UFix((dbits-1)/w)
|
val ddone = io.narrow.req.ready && send_cnt === UInt((dbits-1)/w)
|
||||||
|
|
||||||
when (io.narrow.req.valid && io.narrow.req.ready) {
|
when (io.narrow.req.valid && io.narrow.req.ready) {
|
||||||
send_cnt := send_cnt + UFix(1)
|
send_cnt := send_cnt + UInt(1)
|
||||||
out_buf := out_buf >> UFix(w)
|
out_buf := out_buf >> UInt(w)
|
||||||
}
|
}
|
||||||
when (io.wide.req_cmd.valid && io.wide.req_cmd.ready) {
|
when (io.wide.req_cmd.valid && io.wide.req_cmd.ready) {
|
||||||
out_buf := io.wide.req_cmd.bits.toBits
|
out_buf := io.wide.req_cmd.bits.toBits
|
||||||
@ -76,31 +81,31 @@ class MemSerdes(w: Int) extends Component
|
|||||||
}
|
}
|
||||||
when (state === s_read_addr && adone) {
|
when (state === s_read_addr && adone) {
|
||||||
state := s_idle
|
state := s_idle
|
||||||
send_cnt := UFix(0)
|
send_cnt := UInt(0)
|
||||||
}
|
}
|
||||||
when (state === s_write_addr && adone) {
|
when (state === s_write_addr && adone) {
|
||||||
state := s_write_idle
|
state := s_write_idle
|
||||||
send_cnt := UFix(0)
|
send_cnt := UInt(0)
|
||||||
}
|
}
|
||||||
when (state === s_write_idle && io.wide.req_data.valid) {
|
when (state === s_write_idle && io.wide.req_data.valid) {
|
||||||
state := s_write_data
|
state := s_write_data
|
||||||
}
|
}
|
||||||
when (state === s_write_data && ddone) {
|
when (state === s_write_data && ddone) {
|
||||||
data_send_cnt := data_send_cnt + UFix(1)
|
data_send_cnt := data_send_cnt + UInt(1)
|
||||||
state := Mux(data_send_cnt === UFix(REFILL_CYCLES-1), s_idle, s_write_idle)
|
state := Mux(data_send_cnt === UInt(REFILL_CYCLES-1), s_idle, s_write_idle)
|
||||||
send_cnt := UFix(0)
|
send_cnt := UInt(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
val recv_cnt = Reg(resetVal = UFix(0, log2Up((rbits+w-1)/w)))
|
val recv_cnt = RegReset(UInt(0, log2Up((rbits+w-1)/w)))
|
||||||
val data_recv_cnt = Reg(resetVal = UFix(0, log2Up(REFILL_CYCLES)))
|
val data_recv_cnt = RegReset(UInt(0, log2Up(REFILL_CYCLES)))
|
||||||
val resp_val = Reg(resetVal = Bool(false))
|
val resp_val = RegReset(Bool(false))
|
||||||
|
|
||||||
resp_val := Bool(false)
|
resp_val := Bool(false)
|
||||||
when (io.narrow.resp.valid) {
|
when (io.narrow.resp.valid) {
|
||||||
recv_cnt := recv_cnt + UFix(1)
|
recv_cnt := recv_cnt + UInt(1)
|
||||||
when (recv_cnt === UFix((rbits-1)/w)) {
|
when (recv_cnt === UInt((rbits-1)/w)) {
|
||||||
recv_cnt := UFix(0)
|
recv_cnt := UInt(0)
|
||||||
data_recv_cnt := data_recv_cnt + UFix(1)
|
data_recv_cnt := data_recv_cnt + UInt(1)
|
||||||
resp_val := Bool(true)
|
resp_val := Bool(true)
|
||||||
}
|
}
|
||||||
in_buf := Cat(io.narrow.resp.bits, in_buf((rbits+w-1)/w*w-1,w))
|
in_buf := Cat(io.narrow.resp.bits, in_buf((rbits+w-1)/w*w-1,w))
|
||||||
@ -108,7 +113,7 @@ class MemSerdes(w: Int) extends Component
|
|||||||
|
|
||||||
io.wide.resp.valid := resp_val
|
io.wide.resp.valid := resp_val
|
||||||
io.wide.resp.bits.tag := in_buf(io.wide.resp.bits.tag.width-1,0)
|
io.wide.resp.bits.tag := in_buf(io.wide.resp.bits.tag.width-1,0)
|
||||||
io.wide.resp.bits.data := in_buf >> UFix(io.wide.resp.bits.tag.width)
|
io.wide.resp.bits.data := in_buf >> UInt(io.wide.resp.bits.tag.width)
|
||||||
}
|
}
|
||||||
|
|
||||||
class MemDesserIO(w: Int) extends Bundle {
|
class MemDesserIO(w: Int) extends Bundle {
|
||||||
@ -116,7 +121,7 @@ class MemDesserIO(w: Int) extends Bundle {
|
|||||||
val wide = new ioMem
|
val wide = new ioMem
|
||||||
}
|
}
|
||||||
|
|
||||||
class MemDesser(w: Int) extends Component // test rig side
|
class MemDesser(w: Int) extends Module // test rig side
|
||||||
{
|
{
|
||||||
val io = new MemDesserIO(w)
|
val io = new MemDesserIO(w)
|
||||||
val abits = io.wide.req_cmd.bits.toBits.getWidth
|
val abits = io.wide.req_cmd.bits.toBits.getWidth
|
||||||
@ -124,59 +129,59 @@ class MemDesser(w: Int) extends Component // test rig side
|
|||||||
val rbits = io.wide.resp.bits.getWidth
|
val rbits = io.wide.resp.bits.getWidth
|
||||||
|
|
||||||
require(dbits >= abits && rbits >= dbits)
|
require(dbits >= abits && rbits >= dbits)
|
||||||
val recv_cnt = Reg(resetVal = UFix(0, log2Up((rbits+w-1)/w)))
|
val recv_cnt = RegReset(UInt(0, log2Up((rbits+w-1)/w)))
|
||||||
val data_recv_cnt = Reg(resetVal = UFix(0, log2Up(REFILL_CYCLES)))
|
val data_recv_cnt = RegReset(UInt(0, log2Up(REFILL_CYCLES)))
|
||||||
val adone = io.narrow.req.valid && recv_cnt === UFix((abits-1)/w)
|
val adone = io.narrow.req.valid && recv_cnt === UInt((abits-1)/w)
|
||||||
val ddone = io.narrow.req.valid && recv_cnt === UFix((dbits-1)/w)
|
val ddone = io.narrow.req.valid && recv_cnt === UInt((dbits-1)/w)
|
||||||
val rdone = io.narrow.resp.valid && recv_cnt === UFix((rbits-1)/w)
|
val rdone = io.narrow.resp.valid && recv_cnt === UInt((rbits-1)/w)
|
||||||
|
|
||||||
val s_cmd_recv :: s_cmd :: s_data_recv :: s_data :: s_reply :: Nil = Enum(5) { UFix() }
|
val s_cmd_recv :: s_cmd :: s_data_recv :: s_data :: s_reply :: Nil = Enum(5) { UInt() }
|
||||||
val state = Reg(resetVal = s_cmd_recv)
|
val state = RegReset(s_cmd_recv)
|
||||||
|
|
||||||
val in_buf = Reg() { Bits() }
|
val in_buf = Reg(Bits())
|
||||||
when (io.narrow.req.valid && io.narrow.req.ready || io.narrow.resp.valid) {
|
when (io.narrow.req.valid && io.narrow.req.ready || io.narrow.resp.valid) {
|
||||||
recv_cnt := recv_cnt + UFix(1)
|
recv_cnt := recv_cnt + UInt(1)
|
||||||
in_buf := Cat(io.narrow.req.bits, in_buf((rbits+w-1)/w*w-1,w))
|
in_buf := Cat(io.narrow.req.bits, in_buf((rbits+w-1)/w*w-1,w))
|
||||||
}
|
}
|
||||||
io.narrow.req.ready := state === s_cmd_recv || state === s_data_recv
|
io.narrow.req.ready := state === s_cmd_recv || state === s_data_recv
|
||||||
|
|
||||||
when (state === s_cmd_recv && adone) {
|
when (state === s_cmd_recv && adone) {
|
||||||
state := s_cmd
|
state := s_cmd
|
||||||
recv_cnt := UFix(0)
|
recv_cnt := UInt(0)
|
||||||
}
|
}
|
||||||
when (state === s_cmd && io.wide.req_cmd.ready) {
|
when (state === s_cmd && io.wide.req_cmd.ready) {
|
||||||
state := Mux(io.wide.req_cmd.bits.rw, s_data_recv, s_reply)
|
state := Mux(io.wide.req_cmd.bits.rw, s_data_recv, s_reply)
|
||||||
}
|
}
|
||||||
when (state === s_data_recv && ddone) {
|
when (state === s_data_recv && ddone) {
|
||||||
state := s_data
|
state := s_data
|
||||||
recv_cnt := UFix(0)
|
recv_cnt := UInt(0)
|
||||||
}
|
}
|
||||||
when (state === s_data && io.wide.req_data.ready) {
|
when (state === s_data && io.wide.req_data.ready) {
|
||||||
state := s_data_recv
|
state := s_data_recv
|
||||||
when (data_recv_cnt === UFix(REFILL_CYCLES-1)) {
|
when (data_recv_cnt === UInt(REFILL_CYCLES-1)) {
|
||||||
state := s_cmd_recv
|
state := s_cmd_recv
|
||||||
}
|
}
|
||||||
data_recv_cnt := data_recv_cnt + UFix(1)
|
data_recv_cnt := data_recv_cnt + UInt(1)
|
||||||
}
|
}
|
||||||
when (rdone) { // state === s_reply
|
when (rdone) { // state === s_reply
|
||||||
when (data_recv_cnt === UFix(REFILL_CYCLES-1)) {
|
when (data_recv_cnt === UInt(REFILL_CYCLES-1)) {
|
||||||
state := s_cmd_recv
|
state := s_cmd_recv
|
||||||
}
|
}
|
||||||
recv_cnt := UFix(0)
|
recv_cnt := UInt(0)
|
||||||
data_recv_cnt := data_recv_cnt + UFix(1)
|
data_recv_cnt := data_recv_cnt + UInt(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
val req_cmd = in_buf >> UFix(((rbits+w-1)/w - (abits+w-1)/w)*w)
|
val req_cmd = in_buf >> UInt(((rbits+w-1)/w - (abits+w-1)/w)*w)
|
||||||
io.wide.req_cmd.valid := state === s_cmd
|
io.wide.req_cmd.valid := state === s_cmd
|
||||||
io.wide.req_cmd.bits := io.wide.req_cmd.bits.fromBits(req_cmd)
|
io.wide.req_cmd.bits := io.wide.req_cmd.bits.fromBits(req_cmd)
|
||||||
|
|
||||||
io.wide.req_data.valid := state === s_data
|
io.wide.req_data.valid := state === s_data
|
||||||
io.wide.req_data.bits.data := in_buf >> UFix(((rbits+w-1)/w - (dbits+w-1)/w)*w)
|
io.wide.req_data.bits.data := in_buf >> UInt(((rbits+w-1)/w - (dbits+w-1)/w)*w)
|
||||||
|
|
||||||
val dataq = (new Queue(REFILL_CYCLES)) { new MemResp }
|
val dataq = Module(new Queue(new MemResp, REFILL_CYCLES))
|
||||||
dataq.io.enq <> io.wide.resp
|
dataq.io.enq <> io.wide.resp
|
||||||
dataq.io.deq.ready := recv_cnt === UFix((rbits-1)/w)
|
dataq.io.deq.ready := recv_cnt === UInt((rbits-1)/w)
|
||||||
|
|
||||||
io.narrow.resp.valid := dataq.io.deq.valid
|
io.narrow.resp.valid := dataq.io.deq.valid
|
||||||
io.narrow.resp.bits := dataq.io.deq.bits.toBits >> (recv_cnt * UFix(w))
|
io.narrow.resp.bits := dataq.io.deq.bits.toBits >> (recv_cnt * UInt(w))
|
||||||
}
|
}
|
||||||
|
@ -3,24 +3,24 @@ import Chisel._
|
|||||||
import scala.collection.mutable.Stack
|
import scala.collection.mutable.Stack
|
||||||
|
|
||||||
class PairedDataIO[M <: Data, D <: Data]()(m: => M, d: => D) extends Bundle {
|
class PairedDataIO[M <: Data, D <: Data]()(m: => M, d: => D) extends Bundle {
|
||||||
val meta = new FIFOIO()(m)
|
val meta = Decoupled(m)
|
||||||
val data = new FIFOIO()(d)
|
val data = Decoupled(d)
|
||||||
override def clone = { new PairedDataIO()(m,d).asInstanceOf[this.type] }
|
override def clone = { new PairedDataIO()(m,d).asInstanceOf[this.type] }
|
||||||
}
|
}
|
||||||
|
|
||||||
class PairedArbiterIO[M <: Data, D <: Data](n: Int)(m: => M, d: => D) extends Bundle {
|
class PairedArbiterIO[M <: Data, D <: Data](n: Int)(m: => M, d: => D) extends Bundle {
|
||||||
val in = Vec(n) { new PairedDataIO()(m,d) }.flip
|
val in = Vec.fill(n){new PairedDataIO()(m,d)}.flip
|
||||||
val out = new PairedDataIO()(m,d)
|
val out = new PairedDataIO()(m,d)
|
||||||
val meta_chosen = Bits(OUTPUT, log2Up(n))
|
val meta_chosen = Bits(OUTPUT, log2Up(n))
|
||||||
val data_chosen = Bits(OUTPUT, log2Up(n))
|
val data_chosen = Bits(OUTPUT, log2Up(n))
|
||||||
override def clone = { new PairedArbiterIO(n)(m,d).asInstanceOf[this.type] }
|
override def clone = { new PairedArbiterIO(n)(m,d).asInstanceOf[this.type] }
|
||||||
}
|
}
|
||||||
|
|
||||||
class PairedLockingRRArbiter[M <: Data, D <: Data](n: Int, count: Int, needsLock: Option[M => Bool] = None)(meta: => M, data: => D) extends Component {
|
class PairedLockingRRArbiter[M <: Data, D <: Data](n: Int, count: Int, needsLock: Option[M => Bool] = None)(meta: => M, data: => D) extends Module {
|
||||||
require(isPow2(count))
|
require(isPow2(count))
|
||||||
val io = new PairedArbiterIO(n)(meta,data)
|
val io = new PairedArbiterIO(n)(meta,data)
|
||||||
val locked = if(count > 1) Reg(resetVal = Bool(false)) else Bool(false)
|
val locked = if(count > 1) RegReset(Bool(false)) else Bool(false)
|
||||||
val lockIdx = if(count > 1) Reg(resetVal = UFix(n-1)) else UFix(n-1)
|
val lockIdx = if(count > 1) RegReset(UInt(n-1)) else UInt(n-1)
|
||||||
val grant = List.fill(n)(Bool())
|
val grant = List.fill(n)(Bool())
|
||||||
val meta_chosen = Bits(width = log2Up(n))
|
val meta_chosen = Bits(width = log2Up(n))
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ class PairedLockingRRArbiter[M <: Data, D <: Data](n: Int, count: Int, needsLock
|
|||||||
val valid_meta_has_data = io.in(meta_chosen).meta.valid && chosen_meta_has_data
|
val valid_meta_has_data = io.in(meta_chosen).meta.valid && chosen_meta_has_data
|
||||||
val grant_chosen_meta = !(locked && chosen_meta_has_data)
|
val grant_chosen_meta = !(locked && chosen_meta_has_data)
|
||||||
(0 until n).map(i => io.in(i).meta.ready := grant(i) && grant_chosen_meta && io.out.meta.ready)
|
(0 until n).map(i => io.in(i).meta.ready := grant(i) && grant_chosen_meta && io.out.meta.ready)
|
||||||
(0 until n).map(i => io.in(i).data.ready := Mux(locked, lockIdx === UFix(i), grant(i) && valid_meta_has_data) && io.out.data.ready)
|
(0 until n).map(i => io.in(i).data.ready := Mux(locked, lockIdx === UInt(i), grant(i) && valid_meta_has_data) && io.out.data.ready)
|
||||||
io.out.meta.valid := io.in(meta_chosen).meta.valid && grant_chosen_meta
|
io.out.meta.valid := io.in(meta_chosen).meta.valid && grant_chosen_meta
|
||||||
io.out.data.valid := Mux(locked, io.in(lockIdx).data.valid, io.in(meta_chosen).data.valid && valid_meta_has_data)
|
io.out.data.valid := Mux(locked, io.in(lockIdx).data.valid, io.in(meta_chosen).data.valid && valid_meta_has_data)
|
||||||
io.out.meta.bits := io.in(meta_chosen).meta.bits
|
io.out.meta.bits := io.in(meta_chosen).meta.bits
|
||||||
@ -37,11 +37,11 @@ class PairedLockingRRArbiter[M <: Data, D <: Data](n: Int, count: Int, needsLock
|
|||||||
io.data_chosen := Mux(locked, lockIdx, meta_chosen)
|
io.data_chosen := Mux(locked, lockIdx, meta_chosen)
|
||||||
|
|
||||||
if(count > 1){
|
if(count > 1){
|
||||||
val cnt = Reg(resetVal = UFix(0, width = log2Up(count)))
|
val cnt = RegReset(UInt(0, width = log2Up(count)))
|
||||||
val cnt_next = cnt + UFix(1)
|
val cnt_next = cnt + UInt(1)
|
||||||
when(io.out.data.fire()){
|
when(io.out.data.fire()){
|
||||||
cnt := cnt_next
|
cnt := cnt_next
|
||||||
when(cnt_next === UFix(0)) {
|
when(cnt_next === UInt(0)) {
|
||||||
locked := Bool(false)
|
locked := Bool(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -49,20 +49,20 @@ class PairedLockingRRArbiter[M <: Data, D <: Data](n: Int, count: Int, needsLock
|
|||||||
when(needsLock.map(_(io.out.meta.bits)).getOrElse(Bool(true))) {
|
when(needsLock.map(_(io.out.meta.bits)).getOrElse(Bool(true))) {
|
||||||
when(!locked) {
|
when(!locked) {
|
||||||
locked := Bool(true)
|
locked := Bool(true)
|
||||||
lockIdx := Vec(io.in.map{in => in.meta.fire()}){Bool()}.indexWhere{i: Bool => i}
|
lockIdx := Vec(io.in.map{in => in.meta.fire()}).indexWhere{i: Bool => i}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val last_grant = Reg(resetVal = Bits(0, log2Up(n)))
|
val last_grant = RegReset(Bits(0, log2Up(n)))
|
||||||
val ctrl = ArbiterCtrl((0 until n).map(i => io.in(i).meta.valid && UFix(i) > last_grant) ++ io.in.map(_.meta.valid))
|
val ctrl = ArbiterCtrl((0 until n).map(i => io.in(i).meta.valid && UInt(i) > last_grant) ++ io.in.map(_.meta.valid))
|
||||||
(0 until n).map(i => grant(i) := ctrl(i) && UFix(i) > last_grant || ctrl(i + n))
|
(0 until n).map(i => grant(i) := ctrl(i) && UInt(i) > last_grant || ctrl(i + n))
|
||||||
|
|
||||||
var choose = Bits(n-1)
|
var choose = Bits(n-1)
|
||||||
for (i <- n-2 to 0 by -1)
|
for (i <- n-2 to 0 by -1)
|
||||||
choose = Mux(io.in(i).meta.valid, Bits(i), choose)
|
choose = Mux(io.in(i).meta.valid, Bits(i), choose)
|
||||||
for (i <- n-1 to 1 by -1)
|
for (i <- n-1 to 1 by -1)
|
||||||
choose = Mux(io.in(i).meta.valid && UFix(i) > last_grant, Bits(i), choose)
|
choose = Mux(io.in(i).meta.valid && UInt(i) > last_grant, Bits(i), choose)
|
||||||
meta_chosen := choose
|
meta_chosen := choose
|
||||||
|
|
||||||
when (io.out.meta.fire()) { last_grant := meta_chosen }
|
when (io.out.meta.fire()) { last_grant := meta_chosen }
|
||||||
@ -70,23 +70,23 @@ class PairedLockingRRArbiter[M <: Data, D <: Data](n: Int, count: Int, needsLock
|
|||||||
|
|
||||||
class PairedCrossbar[M <: Data, D <: Data](count: Int, needsLock: Option[PhysicalNetworkIO[M] => Bool] = None)(meta: => M, data: => D)(implicit conf: PhysicalNetworkConfiguration) extends PhysicalNetwork(conf) {
|
class PairedCrossbar[M <: Data, D <: Data](count: Int, needsLock: Option[PhysicalNetworkIO[M] => Bool] = None)(meta: => M, data: => D)(implicit conf: PhysicalNetworkConfiguration) extends PhysicalNetwork(conf) {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val in = Vec(conf.nEndpoints){new PairedDataIO()(new PhysicalNetworkIO()(meta),new PhysicalNetworkIO()(data))}.flip
|
val in = Vec.fill(conf.nEndpoints){new PairedDataIO()(new PhysicalNetworkIO()(meta),new PhysicalNetworkIO()(data))}.flip
|
||||||
val out = Vec(conf.nEndpoints){new PairedDataIO()(new PhysicalNetworkIO()(meta),new PhysicalNetworkIO()(data))}
|
val out = Vec.fill(conf.nEndpoints){new PairedDataIO()(new PhysicalNetworkIO()(meta),new PhysicalNetworkIO()(data))}
|
||||||
}
|
}
|
||||||
|
|
||||||
val metaRdyVecs = List.fill(conf.nEndpoints)(Vec(conf.nEndpoints){Bool()})
|
val metaRdyVecs = List.fill(conf.nEndpoints)(Vec.fill(conf.nEndpoints){Bool()})
|
||||||
val dataRdyVecs = List.fill(conf.nEndpoints)(Vec(conf.nEndpoints){Bool()})
|
val dataRdyVecs = List.fill(conf.nEndpoints)(Vec.fill(conf.nEndpoints){Bool()})
|
||||||
val rdyVecs = metaRdyVecs zip dataRdyVecs
|
val rdyVecs = metaRdyVecs zip dataRdyVecs
|
||||||
|
|
||||||
io.out.zip(rdyVecs).zipWithIndex.map{ case ((out, rdys), i) => {
|
io.out.zip(rdyVecs).zipWithIndex.map{ case ((out, rdys), i) => {
|
||||||
val rrarb = new PairedLockingRRArbiter(conf.nEndpoints, count, needsLock)(io.in(0).meta.bits.clone, io.in(0).data.bits.clone)
|
val rrarb = Module(new PairedLockingRRArbiter(conf.nEndpoints, count, needsLock)(io.in(0).meta.bits.clone, io.in(0).data.bits.clone))
|
||||||
rrarb.io.in zip io.in zip rdys._1 zip rdys._2 map { case (((arb, in), meta_rdy), data_rdy) => {
|
rrarb.io.in zip io.in zip rdys._1 zip rdys._2 map { case (((arb, in), meta_rdy), data_rdy) => {
|
||||||
arb.meta.valid := in.meta.valid && (in.meta.bits.header.dst === UFix(i))
|
arb.meta.valid := in.meta.valid && (in.meta.bits.header.dst === UInt(i))
|
||||||
arb.meta.bits := in.meta.bits
|
arb.meta.bits := in.meta.bits
|
||||||
meta_rdy := arb.meta.ready && (in.meta.bits.header.dst === UFix(i))
|
meta_rdy := arb.meta.ready && (in.meta.bits.header.dst === UInt(i))
|
||||||
arb.data.valid := in.data.valid && (in.data.bits.header.dst === UFix(i))
|
arb.data.valid := in.data.valid && (in.data.bits.header.dst === UInt(i))
|
||||||
arb.data.bits := in.data.bits
|
arb.data.bits := in.data.bits
|
||||||
data_rdy := arb.data.ready && (in.data.bits.header.dst === UFix(i))
|
data_rdy := arb.data.ready && (in.data.bits.header.dst === UInt(i))
|
||||||
}}
|
}}
|
||||||
out <> rrarb.io.out
|
out <> rrarb.io.out
|
||||||
}}
|
}}
|
||||||
@ -99,8 +99,8 @@ class PairedCrossbar[M <: Data, D <: Data](count: Int, needsLock: Option[Physica
|
|||||||
case class PhysicalNetworkConfiguration(nEndpoints: Int, idBits: Int)
|
case class PhysicalNetworkConfiguration(nEndpoints: Int, idBits: Int)
|
||||||
|
|
||||||
class PhysicalHeader(implicit conf: PhysicalNetworkConfiguration) extends Bundle {
|
class PhysicalHeader(implicit conf: PhysicalNetworkConfiguration) extends Bundle {
|
||||||
val src = UFix(width = conf.idBits)
|
val src = UInt(width = conf.idBits)
|
||||||
val dst = UFix(width = conf.idBits)
|
val dst = UInt(width = conf.idBits)
|
||||||
}
|
}
|
||||||
|
|
||||||
class PhysicalNetworkIO[T <: Data]()(data: => T)(implicit conf: PhysicalNetworkConfiguration) extends Bundle {
|
class PhysicalNetworkIO[T <: Data]()(data: => T)(implicit conf: PhysicalNetworkConfiguration) extends Bundle {
|
||||||
@ -109,22 +109,22 @@ class PhysicalNetworkIO[T <: Data]()(data: => T)(implicit conf: PhysicalNetworkC
|
|||||||
override def clone = { new PhysicalNetworkIO()(data).asInstanceOf[this.type] }
|
override def clone = { new PhysicalNetworkIO()(data).asInstanceOf[this.type] }
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class PhysicalNetwork(conf: PhysicalNetworkConfiguration) extends Component
|
abstract class PhysicalNetwork(conf: PhysicalNetworkConfiguration) extends Module
|
||||||
|
|
||||||
class BasicCrossbar[T <: Data](count: Int = 1)(data: => T)(implicit conf: PhysicalNetworkConfiguration) extends PhysicalNetwork(conf) {
|
class BasicCrossbar[T <: Data](count: Int = 1)(data: => T)(implicit conf: PhysicalNetworkConfiguration) extends PhysicalNetwork(conf) {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val in = Vec(conf.nEndpoints){(new FIFOIO){(new PhysicalNetworkIO){data}}}.flip
|
val in = Vec.fill(conf.nEndpoints){Decoupled((new PhysicalNetworkIO){data})}.flip
|
||||||
val out = Vec(conf.nEndpoints){(new FIFOIO){(new PhysicalNetworkIO){data}}}
|
val out = Vec.fill(conf.nEndpoints){Decoupled((new PhysicalNetworkIO){data})}
|
||||||
}
|
}
|
||||||
|
|
||||||
val rdyVecs = List.fill(conf.nEndpoints)(Vec(conf.nEndpoints){Bool()})
|
val rdyVecs = List.fill(conf.nEndpoints)(Vec.fill(conf.nEndpoints)(Bool()))
|
||||||
|
|
||||||
io.out.zip(rdyVecs).zipWithIndex.map{ case ((out, rdys), i) => {
|
io.out.zip(rdyVecs).zipWithIndex.map{ case ((out, rdys), i) => {
|
||||||
val rrarb = (new LockingRRArbiter(conf.nEndpoints, count)){io.in(0).bits.clone}
|
val rrarb = Module(new LockingRRArbiter(io.in(0).bits, conf.nEndpoints, count))
|
||||||
(rrarb.io.in, io.in, rdys).zipped.map{ case (arb, in, rdy) => {
|
(rrarb.io.in, io.in, rdys).zipped.map{ case (arb, in, rdy) => {
|
||||||
arb.valid := in.valid && (in.bits.header.dst === UFix(i))
|
arb.valid := in.valid && (in.bits.header.dst === UInt(i))
|
||||||
arb.bits := in.bits
|
arb.bits := in.bits
|
||||||
rdy := arb.ready && (in.bits.header.dst === UFix(i))
|
rdy := arb.ready && (in.bits.header.dst === UInt(i))
|
||||||
}}
|
}}
|
||||||
out <> rrarb.io.out
|
out <> rrarb.io.out
|
||||||
}}
|
}}
|
||||||
@ -135,30 +135,30 @@ class BasicCrossbar[T <: Data](count: Int = 1)(data: => T)(implicit conf: Physic
|
|||||||
|
|
||||||
case class LogicalNetworkConfiguration(nEndpoints: Int, idBits: Int, nMasters: Int, nClients: Int)
|
case class LogicalNetworkConfiguration(nEndpoints: Int, idBits: Int, nMasters: Int, nClients: Int)
|
||||||
|
|
||||||
abstract class LogicalNetwork[TileLinkType <: Bundle](endpoints: Seq[CoherenceAgentRole])(implicit conf: LogicalNetworkConfiguration) extends Component {
|
abstract class LogicalNetwork[TileLinkType <: Bundle](endpoints: Seq[CoherenceAgentRole])(implicit conf: LogicalNetworkConfiguration) extends Module {
|
||||||
override val io: Vec[TileLinkType]
|
override val io: Vec[TileLinkType]
|
||||||
val physicalNetworks: Seq[PhysicalNetwork]
|
val physicalNetworks: Seq[PhysicalNetwork]
|
||||||
require(endpoints.length == conf.nEndpoints)
|
require(endpoints.length == conf.nEndpoints)
|
||||||
}
|
}
|
||||||
|
|
||||||
class LogicalHeader(implicit conf: LogicalNetworkConfiguration) extends Bundle {
|
class LogicalHeader(implicit conf: LogicalNetworkConfiguration) extends Bundle {
|
||||||
val src = UFix(width = conf.idBits)
|
val src = UInt(width = conf.idBits)
|
||||||
val dst = UFix(width = conf.idBits)
|
val dst = UInt(width = conf.idBits)
|
||||||
}
|
}
|
||||||
|
|
||||||
object FIFOedLogicalNetworkIOWrapper {
|
object FIFOedLogicalNetworkIOWrapper {
|
||||||
def apply[T <: Data](in: FIFOIO[T], src: UFix = UFix(0), dst: UFix = UFix(0))(implicit conf: LogicalNetworkConfiguration) = {
|
def apply[T <: Data](in: DecoupledIO[T], src: UInt = UInt(0), dst: UInt = UInt(0))(implicit conf: LogicalNetworkConfiguration) = {
|
||||||
val shim = (new FIFOedLogicalNetworkIOWrapper(src, dst)){ in.bits.clone }
|
val shim = Module((new FIFOedLogicalNetworkIOWrapper(src, dst)){ in.bits.clone })
|
||||||
shim.io.in.valid := in.valid
|
shim.io.in.valid := in.valid
|
||||||
shim.io.in.bits := in.bits
|
shim.io.in.bits := in.bits
|
||||||
in.ready := shim.io.in.ready
|
in.ready := shim.io.in.ready
|
||||||
shim.io.out
|
shim.io.out
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class FIFOedLogicalNetworkIOWrapper[T <: Data](src: UFix, dst: UFix)(data: => T)(implicit lconf: LogicalNetworkConfiguration) extends Component {
|
class FIFOedLogicalNetworkIOWrapper[T <: Data](src: UInt, dst: UInt)(data: => T)(implicit lconf: LogicalNetworkConfiguration) extends Module {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val in = (new FIFOIO){ data }.flip
|
val in = Decoupled(data).flip
|
||||||
val out = (new FIFOIO){(new LogicalNetworkIO){ data }}
|
val out = Decoupled((new LogicalNetworkIO){data})
|
||||||
}
|
}
|
||||||
io.out.valid := io.in.valid
|
io.out.valid := io.in.valid
|
||||||
io.out.bits.payload := io.in.bits
|
io.out.bits.payload := io.in.bits
|
||||||
@ -168,18 +168,18 @@ class FIFOedLogicalNetworkIOWrapper[T <: Data](src: UFix, dst: UFix)(data: => T)
|
|||||||
}
|
}
|
||||||
|
|
||||||
object FIFOedLogicalNetworkIOUnwrapper {
|
object FIFOedLogicalNetworkIOUnwrapper {
|
||||||
def apply[T <: Data](in: FIFOIO[LogicalNetworkIO[T]])(implicit conf: LogicalNetworkConfiguration) = {
|
def apply[T <: Data](in: DecoupledIO[LogicalNetworkIO[T]])(implicit conf: LogicalNetworkConfiguration) = {
|
||||||
val shim = (new FIFOedLogicalNetworkIOUnwrapper){ in.bits.payload.clone }
|
val shim = Module((new FIFOedLogicalNetworkIOUnwrapper){ in.bits.payload.clone })
|
||||||
shim.io.in.valid := in.valid
|
shim.io.in.valid := in.valid
|
||||||
shim.io.in.bits := in.bits
|
shim.io.in.bits := in.bits
|
||||||
in.ready := shim.io.in.ready
|
in.ready := shim.io.in.ready
|
||||||
shim.io.out
|
shim.io.out
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class FIFOedLogicalNetworkIOUnwrapper[T <: Data]()(data: => T)(implicit lconf: LogicalNetworkConfiguration) extends Component {
|
class FIFOedLogicalNetworkIOUnwrapper[T <: Data]()(data: => T)(implicit lconf: LogicalNetworkConfiguration) extends Module {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val in = (new FIFOIO){(new LogicalNetworkIO){ data }}.flip
|
val in = Decoupled((new LogicalNetworkIO){data}).flip
|
||||||
val out = (new FIFOIO){ data }
|
val out = Decoupled(data)
|
||||||
}
|
}
|
||||||
io.out.valid := io.in.valid
|
io.out.valid := io.in.valid
|
||||||
io.out.bits := io.in.bits.payload
|
io.out.bits := io.in.bits.payload
|
||||||
|
@ -1,71 +1,68 @@
|
|||||||
package uncore
|
package uncore
|
||||||
import Chisel._
|
import Chisel._
|
||||||
|
|
||||||
class SlowIO[T <: Data](val divisor_max: Int)(data: => T) extends Component
|
class SlowIO[T <: Data](val divisor_max: Int)(data: => T) extends Module
|
||||||
{
|
{
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val out_fast = new FIFOIO()(data).flip
|
val out_fast = Decoupled(data).flip
|
||||||
val out_slow = new FIFOIO()(data)
|
val out_slow = Decoupled(data)
|
||||||
|
val in_fast = Decoupled(data)
|
||||||
val in_fast = new FIFOIO()(data)
|
val in_slow = Decoupled(data).flip
|
||||||
val in_slow = new FIFOIO()(data).flip
|
|
||||||
|
|
||||||
val clk_slow = Bool(OUTPUT)
|
val clk_slow = Bool(OUTPUT)
|
||||||
|
val set_divisor = Valid(Bits(width = 32)).flip
|
||||||
val set_divisor = new PipeIO()(Bits(width = 32)).flip
|
|
||||||
val divisor = Bits(OUTPUT, 32)
|
val divisor = Bits(OUTPUT, 32)
|
||||||
}
|
}
|
||||||
|
|
||||||
require(divisor_max >= 8 && divisor_max <= 65536 && isPow2(divisor_max))
|
require(divisor_max >= 8 && divisor_max <= 65536 && isPow2(divisor_max))
|
||||||
val divisor = Reg(resetVal = UFix(divisor_max-1))
|
val divisor = RegReset(UInt(divisor_max-1))
|
||||||
val d_shadow = Reg(resetVal = UFix(divisor_max-1))
|
val d_shadow = RegReset(UInt(divisor_max-1))
|
||||||
val hold = Reg(resetVal = UFix(divisor_max/4-1))
|
val hold = RegReset(UInt(divisor_max/4-1))
|
||||||
val h_shadow = Reg(resetVal = UFix(divisor_max/4-1))
|
val h_shadow = RegReset(UInt(divisor_max/4-1))
|
||||||
when (io.set_divisor.valid) {
|
when (io.set_divisor.valid) {
|
||||||
d_shadow := io.set_divisor.bits(log2Up(divisor_max)-1, 0).toUFix
|
d_shadow := io.set_divisor.bits(log2Up(divisor_max)-1, 0).toUInt
|
||||||
h_shadow := io.set_divisor.bits(log2Up(divisor_max)-1+16, 16).toUFix
|
h_shadow := io.set_divisor.bits(log2Up(divisor_max)-1+16, 16).toUInt
|
||||||
}
|
}
|
||||||
io.divisor := hold << UFix(16) | divisor
|
io.divisor := hold << UInt(16) | divisor
|
||||||
|
|
||||||
val count = Reg{UFix(width = log2Up(divisor_max))}
|
val count = Reg{UInt(width = log2Up(divisor_max))}
|
||||||
val clock = Reg{Bool()}
|
val myclock = Reg{Bool()}
|
||||||
count := count + UFix(1)
|
count := count + UInt(1)
|
||||||
|
|
||||||
val rising = count === (divisor >> UFix(1))
|
val rising = count === (divisor >> UInt(1))
|
||||||
val falling = count === divisor
|
val falling = count === divisor
|
||||||
val held = count === (divisor >> UFix(1)) + hold
|
val held = count === (divisor >> UInt(1)) + hold
|
||||||
|
|
||||||
when (falling) {
|
when (falling) {
|
||||||
divisor := d_shadow
|
divisor := d_shadow
|
||||||
hold := h_shadow
|
hold := h_shadow
|
||||||
count := UFix(0)
|
count := UInt(0)
|
||||||
clock := Bool(false)
|
myclock := Bool(false)
|
||||||
}
|
}
|
||||||
when (rising) {
|
when (rising) {
|
||||||
clock := Bool(true)
|
myclock := Bool(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
val in_slow_rdy = Reg(resetVal = Bool(false))
|
val in_slow_rdy = RegReset(Bool(false))
|
||||||
val out_slow_val = Reg(resetVal = Bool(false))
|
val out_slow_val = RegReset(Bool(false))
|
||||||
val out_slow_bits = Reg() { data }
|
val out_slow_bits = Reg(data)
|
||||||
|
|
||||||
val fromhost_q = new Queue(1)(data)
|
val fromhost_q = Module(new Queue(data,1))
|
||||||
fromhost_q.io.enq.valid := rising && (io.in_slow.valid && in_slow_rdy || reset)
|
fromhost_q.io.enq.valid := rising && (io.in_slow.valid && in_slow_rdy || this.getReset)
|
||||||
fromhost_q.io.enq.bits := io.in_slow.bits
|
fromhost_q.io.enq.bits := io.in_slow.bits
|
||||||
fromhost_q.io.deq <> io.in_fast
|
fromhost_q.io.deq <> io.in_fast
|
||||||
|
|
||||||
val tohost_q = new Queue(1)(data)
|
val tohost_q = Module(new Queue(data,1))
|
||||||
tohost_q.io.enq <> io.out_fast
|
tohost_q.io.enq <> io.out_fast
|
||||||
tohost_q.io.deq.ready := rising && io.out_slow.ready && out_slow_val
|
tohost_q.io.deq.ready := rising && io.out_slow.ready && out_slow_val
|
||||||
|
|
||||||
when (held) {
|
when (held) {
|
||||||
in_slow_rdy := fromhost_q.io.enq.ready
|
in_slow_rdy := fromhost_q.io.enq.ready
|
||||||
out_slow_val := tohost_q.io.deq.valid
|
out_slow_val := tohost_q.io.deq.valid
|
||||||
out_slow_bits := Mux(reset, fromhost_q.io.deq.bits, tohost_q.io.deq.bits)
|
out_slow_bits := Mux(this.getReset, fromhost_q.io.deq.bits, tohost_q.io.deq.bits)
|
||||||
}
|
}
|
||||||
|
|
||||||
io.in_slow.ready := in_slow_rdy
|
io.in_slow.ready := in_slow_rdy
|
||||||
io.out_slow.valid := out_slow_val
|
io.out_slow.valid := out_slow_val
|
||||||
io.out_slow.bits := out_slow_bits
|
io.out_slow.bits := out_slow_bits
|
||||||
io.clk_slow := clock
|
io.clk_slow := myclock
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,11 @@ case class TileLinkConfiguration(co: CoherencePolicyWithUncached, ln: LogicalNet
|
|||||||
|
|
||||||
abstract trait TileLinkSubBundle extends Bundle {
|
abstract trait TileLinkSubBundle extends Bundle {
|
||||||
implicit val conf: TileLinkConfiguration
|
implicit val conf: TileLinkConfiguration
|
||||||
|
// TODO: override clone here, passing conf
|
||||||
}
|
}
|
||||||
|
|
||||||
trait HasPhysicalAddress extends TileLinkSubBundle {
|
trait HasPhysicalAddress extends TileLinkSubBundle {
|
||||||
val addr = UFix(width = PADDR_BITS - OFFSET_BITS)
|
val addr = UInt(width = PADDR_BITS - OFFSET_BITS)
|
||||||
}
|
}
|
||||||
|
|
||||||
trait HasClientTransactionId extends TileLinkSubBundle {
|
trait HasClientTransactionId extends TileLinkSubBundle {
|
||||||
@ -29,7 +30,7 @@ trait MasterSourcedMessage extends SourcedMessage
|
|||||||
|
|
||||||
object Acquire
|
object Acquire
|
||||||
{
|
{
|
||||||
def apply(a_type: Bits, addr: UFix, client_xact_id: UFix)(implicit conf: TileLinkConfiguration) = {
|
def apply(a_type: Bits, addr: UInt, client_xact_id: UInt)(implicit conf: TileLinkConfiguration) = {
|
||||||
val acq = new Acquire
|
val acq = new Acquire
|
||||||
acq.a_type := a_type
|
acq.a_type := a_type
|
||||||
acq.addr := addr
|
acq.addr := addr
|
||||||
@ -39,7 +40,7 @@ object Acquire
|
|||||||
acq.atomic_opcode := Bits(0)
|
acq.atomic_opcode := Bits(0)
|
||||||
acq
|
acq
|
||||||
}
|
}
|
||||||
def apply(a_type: Bits, addr: UFix, client_xact_id: UFix, write_mask: Bits)(implicit conf: TileLinkConfiguration) = {
|
def apply(a_type: Bits, addr: UInt, client_xact_id: UInt, write_mask: Bits)(implicit conf: TileLinkConfiguration) = {
|
||||||
val acq = new Acquire
|
val acq = new Acquire
|
||||||
acq.a_type := a_type
|
acq.a_type := a_type
|
||||||
acq.addr := addr
|
acq.addr := addr
|
||||||
@ -49,7 +50,7 @@ object Acquire
|
|||||||
acq.atomic_opcode := Bits(0)
|
acq.atomic_opcode := Bits(0)
|
||||||
acq
|
acq
|
||||||
}
|
}
|
||||||
def apply(a_type: Bits, addr: UFix, client_xact_id: UFix, subword_addr: UFix, atomic_opcode: UFix)(implicit conf: TileLinkConfiguration) = {
|
def apply(a_type: Bits, addr: UInt, client_xact_id: UInt, subword_addr: UInt, atomic_opcode: UInt)(implicit conf: TileLinkConfiguration) = {
|
||||||
val acq = new Acquire
|
val acq = new Acquire
|
||||||
acq.a_type := a_type
|
acq.a_type := a_type
|
||||||
acq.addr := addr
|
acq.addr := addr
|
||||||
@ -61,7 +62,7 @@ object Acquire
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
class Acquire(implicit val conf: TileLinkConfiguration) extends ClientSourcedMessage with HasPhysicalAddress with HasClientTransactionId {
|
class Acquire(implicit val conf: TileLinkConfiguration) extends ClientSourcedMessage with HasPhysicalAddress with HasClientTransactionId {
|
||||||
val a_type = Bits(width = conf.co.acquireTypeBits)
|
val a_type = Bits(width = conf.co.acquireTypeWidth)
|
||||||
val write_mask = Bits(width = ACQUIRE_WRITE_MASK_BITS)
|
val write_mask = Bits(width = ACQUIRE_WRITE_MASK_BITS)
|
||||||
val subword_addr = Bits(width = ACQUIRE_SUBWORD_ADDR_BITS)
|
val subword_addr = Bits(width = ACQUIRE_SUBWORD_ADDR_BITS)
|
||||||
val atomic_opcode = Bits(width = ACQUIRE_ATOMIC_OP_BITS)
|
val atomic_opcode = Bits(width = ACQUIRE_ATOMIC_OP_BITS)
|
||||||
@ -74,13 +75,13 @@ class AcquireData(implicit val conf: TileLinkConfiguration) extends ClientSource
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Probe(implicit val conf: TileLinkConfiguration) extends MasterSourcedMessage with HasPhysicalAddress with HasMasterTransactionId {
|
class Probe(implicit val conf: TileLinkConfiguration) extends MasterSourcedMessage with HasPhysicalAddress with HasMasterTransactionId {
|
||||||
val p_type = Bits(width = conf.co.probeTypeBits)
|
val p_type = Bits(width = conf.co.probeTypeWidth)
|
||||||
override def clone = { (new Probe).asInstanceOf[this.type] }
|
override def clone = { (new Probe).asInstanceOf[this.type] }
|
||||||
}
|
}
|
||||||
|
|
||||||
object Release
|
object Release
|
||||||
{
|
{
|
||||||
def apply(r_type: Bits, addr: UFix, client_xact_id: UFix, master_xact_id: UFix)(implicit conf: TileLinkConfiguration) = {
|
def apply(r_type: Bits, addr: UInt, client_xact_id: UInt, master_xact_id: UInt)(implicit conf: TileLinkConfiguration) = {
|
||||||
val rel = new Release
|
val rel = new Release
|
||||||
rel.r_type := r_type
|
rel.r_type := r_type
|
||||||
rel.addr := addr
|
rel.addr := addr
|
||||||
@ -90,7 +91,7 @@ object Release
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
class Release(implicit val conf: TileLinkConfiguration) extends ClientSourcedMessage with HasPhysicalAddress with HasClientTransactionId with HasMasterTransactionId {
|
class Release(implicit val conf: TileLinkConfiguration) extends ClientSourcedMessage with HasPhysicalAddress with HasClientTransactionId with HasMasterTransactionId {
|
||||||
val r_type = Bits(width = conf.co.releaseTypeBits)
|
val r_type = Bits(width = conf.co.releaseTypeWidth)
|
||||||
override def clone = { (new Release).asInstanceOf[this.type] }
|
override def clone = { (new Release).asInstanceOf[this.type] }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +100,7 @@ class ReleaseData(implicit val conf: TileLinkConfiguration) extends ClientSource
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Grant(implicit val conf: TileLinkConfiguration) extends MasterSourcedMessage with HasTileLinkData with HasClientTransactionId with HasMasterTransactionId {
|
class Grant(implicit val conf: TileLinkConfiguration) extends MasterSourcedMessage with HasTileLinkData with HasClientTransactionId with HasMasterTransactionId {
|
||||||
val g_type = Bits(width = conf.co.grantTypeBits)
|
val g_type = Bits(width = conf.co.grantTypeWidth)
|
||||||
override def clone = { (new Grant).asInstanceOf[this.type] }
|
override def clone = { (new Grant).asInstanceOf[this.type] }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,13 +112,13 @@ class GrantAck(implicit val conf: TileLinkConfiguration) extends ClientSourcedMe
|
|||||||
trait DirectionalIO
|
trait DirectionalIO
|
||||||
trait ClientSourcedIO extends DirectionalIO
|
trait ClientSourcedIO extends DirectionalIO
|
||||||
trait MasterSourcedIO extends DirectionalIO
|
trait MasterSourcedIO extends DirectionalIO
|
||||||
class ClientSourcedFIFOIO[T <: Data]()(data: => T) extends FIFOIO()(data) with ClientSourcedIO {
|
class ClientSourcedFIFOIO[T <: Data]()(data: => T) extends DecoupledIO(data) with ClientSourcedIO {
|
||||||
override def clone = { new ClientSourcedFIFOIO()(data).asInstanceOf[this.type] }
|
override def clone = { new ClientSourcedFIFOIO()(data).asInstanceOf[this.type] }
|
||||||
}
|
}
|
||||||
class ClientSourcedDataIO[M <: Data, D <: Data]()(meta: => M, data: => D) extends PairedDataIO()(meta,data) with ClientSourcedIO {
|
class ClientSourcedDataIO[M <: Data, D <: Data]()(meta: => M, data: => D) extends PairedDataIO()(meta,data) with ClientSourcedIO {
|
||||||
override def clone = { new ClientSourcedDataIO()(meta,data).asInstanceOf[this.type] }
|
override def clone = { new ClientSourcedDataIO()(meta,data).asInstanceOf[this.type] }
|
||||||
}
|
}
|
||||||
class MasterSourcedFIFOIO[T <: Data]()(data: => T) extends FIFOIO()(data) with MasterSourcedIO {
|
class MasterSourcedFIFOIO[T <: Data]()(data: => T) extends DecoupledIO(data) with MasterSourcedIO {
|
||||||
flip()
|
flip()
|
||||||
override def clone = { new MasterSourcedFIFOIO()(data).asInstanceOf[this.type] }
|
override def clone = { new MasterSourcedFIFOIO()(data).asInstanceOf[this.type] }
|
||||||
}
|
}
|
||||||
@ -142,25 +143,25 @@ class TileLinkIO(implicit conf: TileLinkConfiguration) extends UncachedTileLinkI
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO: Merge the below classes into children of an abstract class in Chisel 2.0
|
* TODO: Merge the below classes into children of an abstract class in Chisel 2.0
|
||||||
abstract class UncachedTileLinkIOArbiter(n: Int, co: CoherencePolicy)(implicit conf: LogicalNetworkConfiguration) extends Component {
|
abstract class UncachedTileLinkIOArbiter(n: Int, co: CoherencePolicy)(implicit conf: LogicalNetworkConfiguration) extends Module {
|
||||||
def acquireClientXactId(in: Acquire, id: Int): Bits
|
def acquireClientXactId(in: Acquire, id: Int): Bits
|
||||||
def grantClientXactId(in: Grant): Bits
|
def grantClientXactId(in: Grant): Bits
|
||||||
def arbIdx(in: Grant): UFix
|
def arbIdx(in: Grant): UInt
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class UncachedTileLinkIOArbiterThatAppendsArbiterId(n: Int)(implicit conf: TileLinkConfiguration) extends Component {
|
class UncachedTileLinkIOArbiterThatAppendsArbiterId(n: Int)(implicit conf: TileLinkConfiguration) extends Module {
|
||||||
implicit val (ln, co) = (conf.ln, conf.co)
|
implicit val (ln, co) = (conf.ln, conf.co)
|
||||||
def acquireClientXactId(in: Acquire, id: Int) = Cat(in.client_xact_id, UFix(id, log2Up(n)))
|
def acquireClientXactId(in: Acquire, id: Int) = Cat(in.client_xact_id, UInt(id, log2Up(n)))
|
||||||
def grantClientXactId(in: Grant) = in.client_xact_id >> UFix(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).toUFix
|
def arbIdx(in: Grant) = in.client_xact_id(log2Up(n)-1,0).toUInt
|
||||||
|
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val in = Vec(n) { new UncachedTileLinkIO }.flip
|
val in = Vec.fill(n){new UncachedTileLinkIO}.flip
|
||||||
val out = new UncachedTileLinkIO
|
val out = new UncachedTileLinkIO
|
||||||
}
|
}
|
||||||
def acqHasData(acq: LogicalNetworkIO[Acquire]) = co.messageHasData(acq.payload)
|
def acqHasData(acq: LogicalNetworkIO[Acquire]) = co.messageHasData(acq.payload)
|
||||||
val acq_arb = new PairedLockingRRArbiter(n, REFILL_CYCLES, acqHasData _)((new LogicalNetworkIO){new Acquire},(new LogicalNetworkIO){new AcquireData})
|
val acq_arb = Module(new PairedLockingRRArbiter(n, REFILL_CYCLES, acqHasData _)((new LogicalNetworkIO){new Acquire},(new LogicalNetworkIO){new AcquireData}))
|
||||||
io.out.acquire <> acq_arb.io.out
|
io.out.acquire <> acq_arb.io.out
|
||||||
io.in.map(_.acquire).zipWithIndex.zip(acq_arb.io.in).map{ case ((req,id), arb) => {
|
io.in.map(_.acquire).zipWithIndex.zip(acq_arb.io.in).map{ case ((req,id), arb) => {
|
||||||
arb.data <> req.data
|
arb.data <> req.data
|
||||||
@ -170,14 +171,14 @@ class UncachedTileLinkIOArbiterThatAppendsArbiterId(n: Int)(implicit conf: TileL
|
|||||||
req.meta.ready := arb.meta.ready
|
req.meta.ready := arb.meta.ready
|
||||||
}}
|
}}
|
||||||
|
|
||||||
val grant_ack_arb = (new RRArbiter(n)){ (new LogicalNetworkIO){new GrantAck} }
|
val grant_ack_arb = Module(new RRArbiter((new LogicalNetworkIO){new GrantAck},n))
|
||||||
io.out.grant_ack <> grant_ack_arb.io.out
|
io.out.grant_ack <> grant_ack_arb.io.out
|
||||||
grant_ack_arb.io.in zip io.in map { case (arb, req) => arb <> req.grant_ack }
|
grant_ack_arb.io.in zip io.in map { case (arb, req) => arb <> req.grant_ack }
|
||||||
|
|
||||||
io.out.grant.ready := Bool(false)
|
io.out.grant.ready := Bool(false)
|
||||||
for (i <- 0 until n) {
|
for (i <- 0 until n) {
|
||||||
io.in(i).grant.valid := Bool(false)
|
io.in(i).grant.valid := Bool(false)
|
||||||
when (arbIdx(io.out.grant.bits.payload) === UFix(i)) {
|
when (arbIdx(io.out.grant.bits.payload) === UInt(i)) {
|
||||||
io.in(i).grant.valid := io.out.grant.valid
|
io.in(i).grant.valid := io.out.grant.valid
|
||||||
io.out.grant.ready := io.in(i).grant.ready
|
io.out.grant.ready := io.in(i).grant.ready
|
||||||
}
|
}
|
||||||
@ -186,18 +187,18 @@ class UncachedTileLinkIOArbiterThatAppendsArbiterId(n: Int)(implicit conf: TileL
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class UncachedTileLinkIOArbiterThatPassesId(n: Int)(implicit conf: TileLinkConfiguration) extends Component {
|
class UncachedTileLinkIOArbiterThatPassesId(n: Int)(implicit conf: TileLinkConfiguration) extends Module {
|
||||||
implicit val (ln, co) = (conf.ln, conf.co)
|
implicit val (ln, co) = (conf.ln, conf.co)
|
||||||
def acquireClientXactId(in: Acquire, id: Int) = in.client_xact_id
|
def acquireClientXactId(in: Acquire, id: Int) = in.client_xact_id
|
||||||
def grantClientXactId(in: Grant) = in.client_xact_id
|
def grantClientXactId(in: Grant) = in.client_xact_id
|
||||||
def arbIdx(in: Grant): UFix = in.client_xact_id
|
def arbIdx(in: Grant): UInt = in.client_xact_id
|
||||||
|
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val in = Vec(n) { new UncachedTileLinkIO }.flip
|
val in = Vec.fill(n){new UncachedTileLinkIO}.flip
|
||||||
val out = new UncachedTileLinkIO
|
val out = new UncachedTileLinkIO
|
||||||
}
|
}
|
||||||
def acqHasData(acq: LogicalNetworkIO[Acquire]) = co.messageHasData(acq.payload)
|
def acqHasData(acq: LogicalNetworkIO[Acquire]) = co.messageHasData(acq.payload)
|
||||||
val acq_arb = new PairedLockingRRArbiter(n, REFILL_CYCLES, acqHasData _)((new LogicalNetworkIO){new Acquire},(new LogicalNetworkIO){new AcquireData})
|
val acq_arb = Module(new PairedLockingRRArbiter(n, REFILL_CYCLES, acqHasData _)((new LogicalNetworkIO){new Acquire},(new LogicalNetworkIO){new AcquireData}))
|
||||||
io.out.acquire <> acq_arb.io.out
|
io.out.acquire <> acq_arb.io.out
|
||||||
io.in.map(_.acquire).zipWithIndex.zip(acq_arb.io.in).map{ case ((req,id), arb) => {
|
io.in.map(_.acquire).zipWithIndex.zip(acq_arb.io.in).map{ case ((req,id), arb) => {
|
||||||
arb.data <> req.data
|
arb.data <> req.data
|
||||||
@ -207,14 +208,14 @@ class UncachedTileLinkIOArbiterThatPassesId(n: Int)(implicit conf: TileLinkConfi
|
|||||||
req.meta.ready := arb.meta.ready
|
req.meta.ready := arb.meta.ready
|
||||||
}}
|
}}
|
||||||
|
|
||||||
val grant_ack_arb = (new RRArbiter(n)){ (new LogicalNetworkIO){new GrantAck} }
|
val grant_ack_arb = Module(new RRArbiter((new LogicalNetworkIO){new GrantAck},n))
|
||||||
io.out.grant_ack <> grant_ack_arb.io.out
|
io.out.grant_ack <> grant_ack_arb.io.out
|
||||||
grant_ack_arb.io.in zip io.in map { case (arb, req) => arb <> req.grant_ack }
|
grant_ack_arb.io.in zip io.in map { case (arb, req) => arb <> req.grant_ack }
|
||||||
|
|
||||||
io.out.grant.ready := Bool(false)
|
io.out.grant.ready := Bool(false)
|
||||||
for (i <- 0 until n) {
|
for (i <- 0 until n) {
|
||||||
io.in(i).grant.valid := Bool(false)
|
io.in(i).grant.valid := Bool(false)
|
||||||
when (arbIdx(io.out.grant.bits.payload) === UFix(i)) {
|
when (arbIdx(io.out.grant.bits.payload) === UInt(i)) {
|
||||||
io.in(i).grant.valid := io.out.grant.valid
|
io.in(i).grant.valid := io.out.grant.valid
|
||||||
io.out.grant.ready := io.in(i).grant.ready
|
io.out.grant.ready := io.in(i).grant.ready
|
||||||
}
|
}
|
||||||
@ -223,18 +224,18 @@ class UncachedTileLinkIOArbiterThatPassesId(n: Int)(implicit conf: TileLinkConfi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class UncachedTileLinkIOArbiterThatUsesNewId(n: Int)(implicit conf: TileLinkConfiguration) extends Component {
|
class UncachedTileLinkIOArbiterThatUsesNewId(n: Int)(implicit conf: TileLinkConfiguration) extends Module {
|
||||||
implicit val (ln, co) = (conf.ln, conf.co)
|
implicit val (ln, co) = (conf.ln, conf.co)
|
||||||
def acquireClientXactId(in: Acquire, id: Int) = UFix(id, log2Up(n))
|
def acquireClientXactId(in: Acquire, id: Int) = UInt(id, log2Up(n))
|
||||||
def grantClientXactId(in: Grant) = UFix(0) // DNC
|
def grantClientXactId(in: Grant) = UInt(0) // DNC
|
||||||
def arbIdx(in: Grant) = in.client_xact_id
|
def arbIdx(in: Grant) = in.client_xact_id
|
||||||
|
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val in = Vec(n) { new UncachedTileLinkIO }.flip
|
val in = Vec.fill(n){new UncachedTileLinkIO}.flip
|
||||||
val out = new UncachedTileLinkIO
|
val out = new UncachedTileLinkIO
|
||||||
}
|
}
|
||||||
def acqHasData(acq: LogicalNetworkIO[Acquire]) = co.messageHasData(acq.payload)
|
def acqHasData(acq: LogicalNetworkIO[Acquire]) = co.messageHasData(acq.payload)
|
||||||
val acq_arb = new PairedLockingRRArbiter(n, REFILL_CYCLES, acqHasData _)((new LogicalNetworkIO){new Acquire},(new LogicalNetworkIO){new AcquireData})
|
val acq_arb = Module(new PairedLockingRRArbiter(n, REFILL_CYCLES, acqHasData _)((new LogicalNetworkIO){new Acquire},(new LogicalNetworkIO){new AcquireData}))
|
||||||
io.out.acquire <> acq_arb.io.out
|
io.out.acquire <> acq_arb.io.out
|
||||||
io.in.map(_.acquire).zipWithIndex.zip(acq_arb.io.in).map{ case ((req,id), arb) => {
|
io.in.map(_.acquire).zipWithIndex.zip(acq_arb.io.in).map{ case ((req,id), arb) => {
|
||||||
arb.data <> req.data
|
arb.data <> req.data
|
||||||
@ -244,14 +245,14 @@ class UncachedTileLinkIOArbiterThatUsesNewId(n: Int)(implicit conf: TileLinkConf
|
|||||||
req.meta.ready := arb.meta.ready
|
req.meta.ready := arb.meta.ready
|
||||||
}}
|
}}
|
||||||
|
|
||||||
val grant_ack_arb = (new RRArbiter(n)){ (new LogicalNetworkIO){new GrantAck} }
|
val grant_ack_arb = Module(new RRArbiter((new LogicalNetworkIO){new GrantAck},n))
|
||||||
io.out.grant_ack <> grant_ack_arb.io.out
|
io.out.grant_ack <> grant_ack_arb.io.out
|
||||||
grant_ack_arb.io.in zip io.in map { case (arb, req) => arb <> req.grant_ack }
|
grant_ack_arb.io.in zip io.in map { case (arb, req) => arb <> req.grant_ack }
|
||||||
|
|
||||||
io.out.grant.ready := Bool(false)
|
io.out.grant.ready := Bool(false)
|
||||||
for (i <- 0 until n) {
|
for (i <- 0 until n) {
|
||||||
io.in(i).grant.valid := Bool(false)
|
io.in(i).grant.valid := Bool(false)
|
||||||
when (arbIdx(io.out.grant.bits.payload) === UFix(i)) {
|
when (arbIdx(io.out.grant.bits.payload) === UInt(i)) {
|
||||||
io.in(i).grant.valid := io.out.grant.valid
|
io.in(i).grant.valid := io.out.grant.valid
|
||||||
io.out.grant.ready := io.in(i).grant.ready
|
io.out.grant.ready := io.in(i).grant.ready
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package uncore
|
package uncore
|
||||||
import Chisel._
|
import Chisel._
|
||||||
|
|
||||||
abstract class CoherenceAgent(implicit conf: TileLinkConfiguration) extends Component with MasterCoherenceAgent {
|
abstract class CoherenceAgent(implicit conf: TileLinkConfiguration) extends Module with MasterCoherenceAgent {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val client = (new TileLinkIO).flip
|
val client = (new TileLinkIO).flip
|
||||||
val master = new UncachedTileLinkIO
|
val master = new UncachedTileLinkIO
|
||||||
val incoherent = Vec(conf.ln.nClients) { Bool() }.asInput
|
val incoherent = Vec.fill(conf.ln.nClients){Bool()}.asInput
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -17,8 +17,8 @@ class L2CoherenceAgent(bankId: Int)(implicit conf: L2CoherenceAgentConfiguration
|
|||||||
|
|
||||||
// Create SHRs for outstanding transactions
|
// Create SHRs for outstanding transactions
|
||||||
val nTrackers = conf.nReleaseTransactions + conf.nAcquireTransactions
|
val nTrackers = conf.nReleaseTransactions + conf.nAcquireTransactions
|
||||||
val trackerList = (0 until conf.nReleaseTransactions).map(new VoluntaryReleaseTracker(_, bankId)) ++
|
val trackerList = (0 until conf.nReleaseTransactions).map(id => Module(new VoluntaryReleaseTracker(id, bankId))) ++
|
||||||
(conf.nReleaseTransactions until nTrackers).map(new AcquireTracker(_, bankId))
|
(conf.nReleaseTransactions until nTrackers).map(id => Module(new AcquireTracker(id, bankId)))
|
||||||
|
|
||||||
// Propagate incoherence flags
|
// Propagate incoherence flags
|
||||||
trackerList.map(_.io.tile_incoherent := io.incoherent.toBits)
|
trackerList.map(_.io.tile_incoherent := io.incoherent.toBits)
|
||||||
@ -28,7 +28,7 @@ class L2CoherenceAgent(bankId: Int)(implicit conf: L2CoherenceAgentConfiguration
|
|||||||
val any_acquire_conflict = trackerList.map(_.io.has_acquire_conflict).reduce(_||_)
|
val any_acquire_conflict = trackerList.map(_.io.has_acquire_conflict).reduce(_||_)
|
||||||
val block_acquires = any_acquire_conflict
|
val block_acquires = any_acquire_conflict
|
||||||
|
|
||||||
val alloc_arb = (new Arbiter(trackerList.size)) { Bool() }
|
val alloc_arb = Module(new Arbiter(Bool(), trackerList.size))
|
||||||
for( i <- 0 until trackerList.size ) {
|
for( i <- 0 until trackerList.size ) {
|
||||||
val t = trackerList(i).io.client
|
val t = trackerList(i).io.client
|
||||||
alloc_arb.io.in(i).valid := t.acquire.meta.ready
|
alloc_arb.io.in(i).valid := t.acquire.meta.ready
|
||||||
@ -43,7 +43,7 @@ class L2CoherenceAgent(bankId: Int)(implicit conf: L2CoherenceAgentConfiguration
|
|||||||
alloc_arb.io.out.ready := acquire.meta.valid && !block_acquires
|
alloc_arb.io.out.ready := acquire.meta.valid && !block_acquires
|
||||||
|
|
||||||
// Handle probe request generation
|
// Handle probe request generation
|
||||||
val probe_arb = (new Arbiter(trackerList.size)){(new LogicalNetworkIO){ new Probe }}
|
val probe_arb = Module(new Arbiter((new LogicalNetworkIO){ new Probe }, trackerList.size))
|
||||||
io.client.probe <> probe_arb.io.out
|
io.client.probe <> probe_arb.io.out
|
||||||
probe_arb.io.in zip trackerList map { case (arb, t) => arb <> t.io.client.probe }
|
probe_arb.io.in zip trackerList map { case (arb, t) => arb <> t.io.client.probe }
|
||||||
|
|
||||||
@ -52,21 +52,21 @@ class L2CoherenceAgent(bankId: Int)(implicit conf: L2CoherenceAgentConfiguration
|
|||||||
val voluntary = co.isVoluntary(release.meta.bits.payload)
|
val voluntary = co.isVoluntary(release.meta.bits.payload)
|
||||||
val any_release_conflict = trackerList.tail.map(_.io.has_release_conflict).reduce(_||_)
|
val any_release_conflict = trackerList.tail.map(_.io.has_release_conflict).reduce(_||_)
|
||||||
val block_releases = Bool(false)
|
val block_releases = Bool(false)
|
||||||
val conflict_idx = Vec(trackerList.map(_.io.has_release_conflict)){Bool()}.lastIndexWhere{b: Bool => b}
|
val conflict_idx = Vec(trackerList.map(_.io.has_release_conflict)).lastIndexWhere{b: Bool => b}
|
||||||
//val release_idx = Mux(voluntary, Mux(any_release_conflict, conflict_idx, UFix(0)), release.bits.payload.master_xact_id) // TODO: Add merging logic to allow allocated AcquireTracker to handle conflicts, send all necessary grants, use first sufficient response
|
//val release_idx = Mux(voluntary, Mux(any_release_conflict, conflict_idx, UInt(0)), release.bits.payload.master_xact_id) // TODO: Add merging logic to allow allocated AcquireTracker to handle conflicts, send all necessary grants, use first sufficient response
|
||||||
val release_idx = Mux(voluntary, UFix(0), release.meta.bits.payload.master_xact_id)
|
val release_idx = Mux(voluntary, UInt(0), release.meta.bits.payload.master_xact_id)
|
||||||
for( i <- 0 until trackerList.size ) {
|
for( i <- 0 until trackerList.size ) {
|
||||||
val t = trackerList(i).io.client
|
val t = trackerList(i).io.client
|
||||||
t.release.meta.bits := release.meta.bits
|
t.release.meta.bits := release.meta.bits
|
||||||
t.release.meta.valid := release.meta.valid && (release_idx === UFix(i)) && !block_releases
|
t.release.meta.valid := release.meta.valid && (release_idx === UInt(i)) && !block_releases
|
||||||
t.release.data.bits := release.data.bits
|
t.release.data.bits := release.data.bits
|
||||||
t.release.data.valid := release.data.valid
|
t.release.data.valid := release.data.valid
|
||||||
}
|
}
|
||||||
release.meta.ready := Vec(trackerList.map(_.io.client.release.meta.ready)){Bool()}(release_idx) && !block_releases
|
release.meta.ready := Vec(trackerList.map(_.io.client.release.meta.ready)).read(release_idx) && !block_releases
|
||||||
release.data.ready := trackerList.map(_.io.client.release.data.ready).reduce(_||_)
|
release.data.ready := trackerList.map(_.io.client.release.data.ready).reduce(_||_)
|
||||||
|
|
||||||
// Reply to initial requestor
|
// Reply to initial requestor
|
||||||
val grant_arb = (new Arbiter(trackerList.size)){(new LogicalNetworkIO){ new Grant }}
|
val grant_arb = Module(new Arbiter((new LogicalNetworkIO){ new Grant }, trackerList.size))
|
||||||
io.client.grant <> grant_arb.io.out
|
io.client.grant <> grant_arb.io.out
|
||||||
grant_arb.io.in zip trackerList map { case (arb, t) => arb <> t.io.client.grant }
|
grant_arb.io.in zip trackerList map { case (arb, t) => arb <> t.io.client.grant }
|
||||||
|
|
||||||
@ -77,13 +77,13 @@ class L2CoherenceAgent(bankId: Int)(implicit conf: L2CoherenceAgentConfiguration
|
|||||||
ack.ready := Bool(true)
|
ack.ready := Bool(true)
|
||||||
|
|
||||||
// Create an arbiter for the one memory port
|
// Create an arbiter for the one memory port
|
||||||
val outer_arb = new UncachedTileLinkIOArbiterThatPassesId(trackerList.size)
|
val outer_arb = Module(new UncachedTileLinkIOArbiterThatPassesId(trackerList.size))
|
||||||
outer_arb.io.in zip trackerList map { case(arb, t) => arb <> t.io.master }
|
outer_arb.io.in zip trackerList map { case(arb, t) => arb <> t.io.master }
|
||||||
io.master <> outer_arb.io.out
|
io.master <> outer_arb.io.out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
abstract class XactTracker()(implicit conf: L2CoherenceAgentConfiguration) extends Component with OuterRequestGenerator {
|
abstract class XactTracker()(implicit conf: L2CoherenceAgentConfiguration) extends Module with OuterRequestGenerator {
|
||||||
implicit val (tl, ln, co) = (conf.tl, conf.tl.ln, conf.tl.co)
|
implicit val (tl, ln, co) = (conf.tl, conf.tl.ln, conf.tl.co)
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val client = (new TileLinkIO).flip
|
val client = (new TileLinkIO).flip
|
||||||
@ -95,13 +95,13 @@ abstract class XactTracker()(implicit conf: L2CoherenceAgentConfiguration) exten
|
|||||||
}
|
}
|
||||||
|
|
||||||
class VoluntaryReleaseTracker(trackerId: Int, bankId: Int)(implicit conf: L2CoherenceAgentConfiguration) 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 s_idle :: s_mem :: s_ack :: s_busy :: Nil = Enum(4){ UInt() }
|
||||||
val state = Reg(resetVal = s_idle)
|
val state = RegReset(s_idle)
|
||||||
val xact = Reg{ new Release }
|
val xact = Reg{ new Release }
|
||||||
val init_client_id_ = Reg(resetVal = UFix(0, width = log2Up(ln.nClients)))
|
val init_client_id_ = RegReset(UInt(0, width = log2Up(ln.nClients)))
|
||||||
val release_data_needs_write = Reg(resetVal = Bool(false))
|
val release_data_needs_write = RegReset(Bool(false))
|
||||||
val mem_cmd_sent = Reg(resetVal = Bool(false))
|
val mem_cmd_sent = RegReset(Bool(false))
|
||||||
val cmd_to_write = Acquire(co.getUncachedWriteAcquireType, xact.addr, UFix(trackerId))
|
val cmd_to_write = Acquire(co.getUncachedWriteAcquireType, xact.addr, UInt(trackerId))
|
||||||
|
|
||||||
io.has_acquire_conflict := Bool(false)
|
io.has_acquire_conflict := Bool(false)
|
||||||
io.has_release_conflict := co.isCoherenceConflict(xact.addr, io.client.release.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)
|
||||||
@ -110,23 +110,23 @@ class VoluntaryReleaseTracker(trackerId: Int, bankId: Int)(implicit conf: L2Cohe
|
|||||||
io.master.acquire.meta.valid := Bool(false)
|
io.master.acquire.meta.valid := Bool(false)
|
||||||
io.master.acquire.meta.bits.payload := cmd_to_write
|
io.master.acquire.meta.bits.payload := cmd_to_write
|
||||||
//TODO io.master.acquire.bits.header.dst
|
//TODO io.master.acquire.bits.header.dst
|
||||||
io.master.acquire.meta.bits.header.src := UFix(bankId)
|
io.master.acquire.meta.bits.header.src := UInt(bankId)
|
||||||
io.master.acquire.data.valid := Bool(false)
|
io.master.acquire.data.valid := Bool(false)
|
||||||
io.master.acquire.data.bits.payload.data := UFix(0)
|
io.master.acquire.data.bits.payload.data := UInt(0)
|
||||||
//TODO io.master.acquire_data.bits.header.dst
|
//TODO io.master.acquire_data.bits.header.dst
|
||||||
io.master.acquire.data.bits.header.src := UFix(bankId)
|
io.master.acquire.data.bits.header.src := UInt(bankId)
|
||||||
io.client.acquire.meta.ready := Bool(false)
|
io.client.acquire.meta.ready := Bool(false)
|
||||||
io.client.acquire.data.ready := Bool(false)
|
io.client.acquire.data.ready := Bool(false)
|
||||||
io.client.probe.valid := Bool(false)
|
io.client.probe.valid := Bool(false)
|
||||||
io.client.release.meta.ready := Bool(false)
|
io.client.release.meta.ready := Bool(false)
|
||||||
io.client.release.data.ready := Bool(false) // DNC
|
io.client.release.data.ready := Bool(false) // DNC
|
||||||
io.client.grant.valid := Bool(false)
|
io.client.grant.valid := Bool(false)
|
||||||
io.client.grant.bits.payload.g_type := co.getGrantType(xact, UFix(0))
|
io.client.grant.bits.payload.g_type := co.getGrantType(xact, UInt(0))
|
||||||
io.client.grant.bits.payload.client_xact_id := xact.client_xact_id
|
io.client.grant.bits.payload.client_xact_id := xact.client_xact_id
|
||||||
io.client.grant.bits.payload.master_xact_id := UFix(trackerId)
|
io.client.grant.bits.payload.master_xact_id := UInt(trackerId)
|
||||||
io.client.grant.bits.payload.data := UFix(0)
|
io.client.grant.bits.payload.data := UInt(0)
|
||||||
io.client.grant.bits.header.dst := init_client_id_
|
io.client.grant.bits.header.dst := init_client_id_
|
||||||
io.client.grant.bits.header.src := UFix(bankId)
|
io.client.grant.bits.header.src := UInt(bankId)
|
||||||
io.client.grant_ack.valid := Bool(false)
|
io.client.grant_ack.valid := Bool(false)
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
@ -136,7 +136,7 @@ class VoluntaryReleaseTracker(trackerId: Int, bankId: Int)(implicit conf: L2Cohe
|
|||||||
xact := io.client.release.meta.bits.payload
|
xact := io.client.release.meta.bits.payload
|
||||||
init_client_id_ := io.client.release.meta.bits.header.src
|
init_client_id_ := io.client.release.meta.bits.header.src
|
||||||
release_data_needs_write := co.messageHasData(io.client.release.meta.bits.payload)
|
release_data_needs_write := co.messageHasData(io.client.release.meta.bits.payload)
|
||||||
mem_cnt := UFix(0)
|
mem_cnt := UInt(0)
|
||||||
mem_cmd_sent := Bool(false)
|
mem_cmd_sent := Bool(false)
|
||||||
state := s_mem
|
state := s_mem
|
||||||
}
|
}
|
||||||
@ -159,56 +159,54 @@ class VoluntaryReleaseTracker(trackerId: Int, bankId: Int)(implicit conf: L2Cohe
|
|||||||
}
|
}
|
||||||
|
|
||||||
class AcquireTracker(trackerId: Int, bankId: Int)(implicit conf: L2CoherenceAgentConfiguration) 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 s_idle :: s_ack :: s_mem :: s_probe :: s_busy :: Nil = Enum(5){ UInt() }
|
||||||
val state = Reg(resetVal = s_idle)
|
val state = RegReset(s_idle)
|
||||||
val xact = Reg{ new Acquire }
|
val xact = Reg{ new Acquire }
|
||||||
val init_client_id_ = Reg(resetVal = UFix(0, width = log2Up(ln.nClients)))
|
val init_client_id_ = RegReset(UInt(0, width = log2Up(ln.nClients)))
|
||||||
val release_data_client_id = Reg(resetVal = UFix(0, width = log2Up(ln.nClients)))
|
val release_data_client_id = RegReset(UInt(0, width = log2Up(ln.nClients)))
|
||||||
//TODO: Will need id reg for merged release xacts
|
//TODO: Will need id reg for merged release xacts
|
||||||
val init_sharer_cnt_ = Reg(resetVal = UFix(0, width = log2Up(ln.nClients)))
|
val init_sharer_cnt_ = RegReset(UInt(0, width = log2Up(ln.nClients)))
|
||||||
val grant_type = co.getGrantType(xact.a_type, init_sharer_cnt_)
|
val grant_type = co.getGrantType(xact.a_type, init_sharer_cnt_)
|
||||||
val release_count = if (ln.nClients == 1) UFix(0) else Reg(resetVal = UFix(0, width = log2Up(ln.nClients)))
|
val release_count = if (ln.nClients == 1) UInt(0) else RegReset(UInt(0, width = log2Up(ln.nClients)))
|
||||||
val probe_flags = Reg(resetVal = Bits(0, width = ln.nClients))
|
val probe_flags = RegReset(Bits(0, width = ln.nClients))
|
||||||
val curr_p_id = PriorityEncoder(probe_flags)
|
val curr_p_id = PriorityEncoder(probe_flags)
|
||||||
val x_needs_read = Reg(resetVal = Bool(false))
|
val x_needs_read = RegReset(Bool(false))
|
||||||
val acquire_data_needs_write = Reg(resetVal = Bool(false))
|
val acquire_data_needs_write = RegReset(Bool(false))
|
||||||
val release_data_needs_write = Reg(resetVal = Bool(false))
|
val release_data_needs_write = RegReset(Bool(false))
|
||||||
val cmd_to_write = Acquire(co.getUncachedWriteAcquireType, xact.addr, UFix(trackerId))
|
val cmd_to_write = Acquire(co.getUncachedWriteAcquireType, xact.addr, UInt(trackerId))
|
||||||
val cmd_to_read = Acquire(co.getUncachedReadAcquireType, xact.addr, UFix(trackerId))
|
val cmd_to_read = Acquire(co.getUncachedReadAcquireType, xact.addr, UInt(trackerId))
|
||||||
val a_w_mem_cmd_sent = Reg(resetVal = Bool(false))
|
val a_w_mem_cmd_sent = RegReset(Bool(false))
|
||||||
val r_w_mem_cmd_sent = Reg(resetVal = Bool(false))
|
val r_w_mem_cmd_sent = RegReset(Bool(false))
|
||||||
val probe_initial_flags = Bits(width = ln.nClients)
|
val probe_initial_flags = Bits(width = ln.nClients)
|
||||||
probe_initial_flags := Bits(0)
|
probe_initial_flags := Bits(0)
|
||||||
if (ln.nClients > 1) {
|
if (ln.nClients > 1) {
|
||||||
// issue self-probes for uncached read xacts to facilitate I$ coherence
|
// issue self-probes for uncached read xacts to facilitate I$ coherence
|
||||||
val probe_self = Bool(true) //co.needsSelfProbe(io.client.acquire.bits.payload)
|
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(ln.nClients)-1,0)))
|
val myflag = Mux(probe_self, Bits(0), UIntToOH(io.client.acquire.meta.bits.header.src(log2Up(ln.nClients)-1,0)))
|
||||||
probe_initial_flags := ~(io.tile_incoherent | myflag)
|
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_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.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.valid := Bool(false)
|
||||||
io.master.acquire.meta.bits.payload := Acquire(co.getUncachedReadAcquireType, xact.addr, UFix(trackerId))
|
io.master.acquire.meta.bits.payload := Acquire(co.getUncachedReadAcquireType, xact.addr, UInt(trackerId))
|
||||||
//TODO io.master.acquire.bits.header.dst
|
io.master.acquire.meta.bits.header.src := UInt(bankId)
|
||||||
io.master.acquire.meta.bits.header.src := UFix(bankId)
|
|
||||||
io.master.acquire.data.valid := Bool(false)
|
io.master.acquire.data.valid := Bool(false)
|
||||||
io.master.acquire.data.bits.payload.data := UFix(0)
|
io.master.acquire.data.bits.payload.data := UInt(0)
|
||||||
//TODO io.master.acquire_data.bits.header.dst
|
io.master.acquire.data.bits.header.src := UInt(bankId)
|
||||||
io.master.acquire.data.bits.header := UFix(bankId)
|
|
||||||
io.client.probe.valid := Bool(false)
|
io.client.probe.valid := Bool(false)
|
||||||
io.client.probe.bits.payload.p_type := co.getProbeType(xact.a_type, UFix(0))
|
io.client.probe.bits.payload.p_type := co.getProbeType(xact.a_type, UInt(0))
|
||||||
io.client.probe.bits.payload.master_xact_id := UFix(trackerId)
|
io.client.probe.bits.payload.master_xact_id := UInt(trackerId)
|
||||||
io.client.probe.bits.payload.addr := xact.addr
|
io.client.probe.bits.payload.addr := xact.addr
|
||||||
io.client.probe.bits.header.dst := UFix(0)
|
io.client.probe.bits.header.dst := UInt(0)
|
||||||
io.client.probe.bits.header.src := UFix(bankId)
|
io.client.probe.bits.header.src := UInt(bankId)
|
||||||
io.client.grant.bits.payload.data := io.master.grant.bits.payload.data
|
io.client.grant.bits.payload.data := io.master.grant.bits.payload.data
|
||||||
io.client.grant.bits.payload.g_type := grant_type
|
io.client.grant.bits.payload.g_type := grant_type
|
||||||
io.client.grant.bits.payload.client_xact_id := xact.client_xact_id
|
io.client.grant.bits.payload.client_xact_id := xact.client_xact_id
|
||||||
io.client.grant.bits.payload.master_xact_id := UFix(trackerId)
|
io.client.grant.bits.payload.master_xact_id := UInt(trackerId)
|
||||||
io.client.grant.bits.header.dst := init_client_id_
|
io.client.grant.bits.header.dst := init_client_id_
|
||||||
io.client.grant.bits.header.src := UFix(bankId)
|
io.client.grant.bits.header.src := UInt(bankId)
|
||||||
io.client.grant.valid := (io.master.grant.valid && (UFix(trackerId) === io.master.grant.bits.payload.client_xact_id))
|
io.client.grant.valid := (io.master.grant.valid && (UInt(trackerId) === io.master.grant.bits.payload.client_xact_id))
|
||||||
io.client.acquire.meta.ready := Bool(false)
|
io.client.acquire.meta.ready := Bool(false)
|
||||||
io.client.acquire.data.ready := Bool(false)
|
io.client.acquire.data.ready := Bool(false)
|
||||||
io.client.release.meta.ready := Bool(false)
|
io.client.release.meta.ready := Bool(false)
|
||||||
@ -222,11 +220,11 @@ class AcquireTracker(trackerId: Int, bankId: Int)(implicit conf: L2CoherenceAgen
|
|||||||
when( io.client.acquire.meta.valid ) {
|
when( io.client.acquire.meta.valid ) {
|
||||||
xact := io.client.acquire.meta.bits.payload
|
xact := io.client.acquire.meta.bits.payload
|
||||||
init_client_id_ := io.client.acquire.meta.bits.header.src
|
init_client_id_ := io.client.acquire.meta.bits.header.src
|
||||||
init_sharer_cnt_ := UFix(ln.nClients) // TODO: Broadcast only
|
init_sharer_cnt_ := UInt(ln.nClients) // TODO: Broadcast only
|
||||||
acquire_data_needs_write := co.messageHasData(io.client.acquire.meta.bits.payload)
|
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))
|
x_needs_read := co.needsOuterRead(io.client.acquire.meta.bits.payload.a_type, UInt(0))
|
||||||
probe_flags := probe_initial_flags
|
probe_flags := probe_initial_flags
|
||||||
mem_cnt := UFix(0)
|
mem_cnt := UInt(0)
|
||||||
r_w_mem_cmd_sent := Bool(false)
|
r_w_mem_cmd_sent := Bool(false)
|
||||||
a_w_mem_cmd_sent := Bool(false)
|
a_w_mem_cmd_sent := Bool(false)
|
||||||
if(ln.nClients > 1) {
|
if(ln.nClients > 1) {
|
||||||
@ -241,12 +239,12 @@ class AcquireTracker(trackerId: Int, bankId: Int)(implicit conf: L2CoherenceAgen
|
|||||||
io.client.probe.bits.header.dst := curr_p_id
|
io.client.probe.bits.header.dst := curr_p_id
|
||||||
}
|
}
|
||||||
when(io.client.probe.ready) {
|
when(io.client.probe.ready) {
|
||||||
probe_flags := probe_flags & ~(UFixToOH(curr_p_id))
|
probe_flags := probe_flags & ~(UIntToOH(curr_p_id))
|
||||||
}
|
}
|
||||||
io.client.release.meta.ready := Bool(true)
|
io.client.release.meta.ready := Bool(true)
|
||||||
when(io.client.release.meta.valid) {
|
when(io.client.release.meta.valid) {
|
||||||
if(ln.nClients > 1) release_count := release_count - UFix(1)
|
if(ln.nClients > 1) release_count := release_count - UInt(1)
|
||||||
when(release_count === UFix(1)) {
|
when(release_count === UInt(1)) {
|
||||||
state := s_mem
|
state := s_mem
|
||||||
}
|
}
|
||||||
when( co.messageHasData(io.client.release.meta.bits.payload)) {
|
when( co.messageHasData(io.client.release.meta.bits.payload)) {
|
||||||
@ -281,7 +279,7 @@ class AcquireTracker(trackerId: Int, bankId: Int)(implicit conf: L2CoherenceAgen
|
|||||||
} . elsewhen (x_needs_read) {
|
} . elsewhen (x_needs_read) {
|
||||||
doOuterReqRead(io.master.acquire, cmd_to_read, x_needs_read)
|
doOuterReqRead(io.master.acquire, cmd_to_read, x_needs_read)
|
||||||
} . otherwise {
|
} . otherwise {
|
||||||
state := Mux(co.needsAckReply(xact.a_type, UFix(0)), s_ack,
|
state := Mux(co.needsAckReply(xact.a_type, UInt(0)), s_ack,
|
||||||
Mux(co.requiresAck(io.client.grant.bits.payload), s_busy, s_idle))
|
Mux(co.requiresAck(io.client.grant.bits.payload), s_busy, s_idle))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -290,7 +288,7 @@ class AcquireTracker(trackerId: Int, bankId: Int)(implicit conf: L2CoherenceAgen
|
|||||||
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.requiresAck(io.client.grant.bits.payload), s_busy, s_idle) }
|
||||||
}
|
}
|
||||||
is(s_busy) { // Nothing left to do but wait for transaction to complete
|
is(s_busy) { // Nothing left to do but wait for transaction to complete
|
||||||
when (io.client.grant_ack.valid && io.client.grant_ack.bits.payload.master_xact_id === UFix(trackerId)) {
|
when (io.client.grant_ack.valid && io.client.grant_ack.bits.payload.master_xact_id === UInt(trackerId)) {
|
||||||
state := s_idle
|
state := s_idle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -298,10 +296,10 @@ class AcquireTracker(trackerId: Int, bankId: Int)(implicit conf: L2CoherenceAgen
|
|||||||
}
|
}
|
||||||
|
|
||||||
abstract trait OuterRequestGenerator {
|
abstract trait OuterRequestGenerator {
|
||||||
val mem_cnt = Reg(resetVal = UFix(0, width = log2Up(REFILL_CYCLES)))
|
val mem_cnt = RegReset(UInt(0, width = log2Up(REFILL_CYCLES)))
|
||||||
val mem_cnt_next = mem_cnt + UFix(1)
|
val mem_cnt_next = mem_cnt + UInt(1)
|
||||||
|
|
||||||
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) {
|
def doOuterReqWrite[T <: HasTileLinkData](master_acq: PairedDataIO[LogicalNetworkIO[Acquire],LogicalNetworkIO[AcquireData]], client_data: DecoupledIO[LogicalNetworkIO[T]], cmd: Acquire, trigger: Bool, cmd_sent: Bool, desired_client_data_src_id: UInt) {
|
||||||
val do_write = client_data.valid && (client_data.bits.header.src === desired_client_data_src_id)
|
val do_write = client_data.valid && (client_data.bits.header.src === desired_client_data_src_id)
|
||||||
master_acq.meta.bits.payload := cmd
|
master_acq.meta.bits.payload := cmd
|
||||||
master_acq.data.bits.payload := client_data.bits.payload
|
master_acq.data.bits.payload := client_data.bits.payload
|
||||||
@ -315,7 +313,7 @@ abstract trait OuterRequestGenerator {
|
|||||||
when(master_acq.data.ready) {
|
when(master_acq.data.ready) {
|
||||||
client_data.ready:= Bool(true)
|
client_data.ready:= Bool(true)
|
||||||
mem_cnt := mem_cnt_next
|
mem_cnt := mem_cnt_next
|
||||||
when(mem_cnt === UFix(REFILL_CYCLES-1)) {
|
when(mem_cnt === UInt(REFILL_CYCLES-1)) {
|
||||||
trigger := Bool(false)
|
trigger := Bool(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user