Refactored coherence as member rather than trait. MI and MEI protocols.
This commit is contained in:
parent
e71e3ce38f
commit
b22d7f8192
@ -50,7 +50,7 @@ object cpuCmdToRW {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trait CoherencePolicy {
|
abstract class CoherencePolicy {
|
||||||
def isHit (cmd: Bits, state: UFix): Bool
|
def isHit (cmd: Bits, state: UFix): Bool
|
||||||
def isValid (state: UFix): Bool
|
def isValid (state: UFix): Bool
|
||||||
|
|
||||||
@ -72,9 +72,10 @@ trait CoherencePolicy {
|
|||||||
|
|
||||||
def newProbeReply (incoming: ProbeRequest, state: UFix): ProbeReply
|
def newProbeReply (incoming: ProbeRequest, state: UFix): ProbeReply
|
||||||
|
|
||||||
def hasData (reply: ProbeReply): Bool
|
def messageHasData (reply: ProbeReply): Bool
|
||||||
def hasData (init: TransactionInit): Bool
|
def messageHasData (init: TransactionInit): Bool
|
||||||
def hasData (reply: TransactionReply): Bool
|
def messageHasData (reply: TransactionReply): Bool
|
||||||
|
def messageUpdatesDataArray (reply: TransactionReply): Bool
|
||||||
|
|
||||||
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool
|
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool
|
||||||
def getTransactionReplyType(x_type: UFix, count: UFix): Bits
|
def getTransactionReplyType(x_type: UFix, count: UFix): Bits
|
||||||
@ -84,7 +85,14 @@ trait CoherencePolicy {
|
|||||||
def needsAckReply(x_type: UFix, global_state: UFix): Bool
|
def needsAckReply(x_type: UFix, global_state: UFix): Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
trait IncoherentPolicy extends CoherencePolicy {
|
trait UncachedTransactions {
|
||||||
|
def getTransactionInitTypeOnUncachedRead(): UFix
|
||||||
|
def getTransactionInitTypeOnUncachedWrite(): UFix
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class CoherencePolicyWithUncached extends CoherencePolicy with UncachedTransactions
|
||||||
|
|
||||||
|
abstract class IncoherentPolicy extends CoherencePolicy {
|
||||||
// UNIMPLEMENTED
|
// UNIMPLEMENTED
|
||||||
def newStateOnProbeRequest(incoming: ProbeRequest, state: UFix): Bits = state
|
def newStateOnProbeRequest(incoming: ProbeRequest, state: UFix): Bits = state
|
||||||
def newProbeReply (incoming: ProbeRequest, state: UFix): ProbeReply = {
|
def newProbeReply (incoming: ProbeRequest, state: UFix): ProbeReply = {
|
||||||
@ -93,7 +101,7 @@ trait IncoherentPolicy extends CoherencePolicy {
|
|||||||
reply.global_xact_id := UFix(0)
|
reply.global_xact_id := UFix(0)
|
||||||
reply
|
reply
|
||||||
}
|
}
|
||||||
def hasData (reply: ProbeReply) = Bool(false)
|
def messageHasData (reply: ProbeReply) = Bool(false)
|
||||||
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = Bool(false)
|
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = Bool(false)
|
||||||
def getTransactionReplyType(x_type: UFix, count: UFix): Bits = Bits(0)
|
def getTransactionReplyType(x_type: UFix, count: UFix): Bits = Bits(0)
|
||||||
def getProbeRequestType(x_type: UFix, global_state: UFix): UFix = UFix(0)
|
def getProbeRequestType(x_type: UFix, global_state: UFix): UFix = UFix(0)
|
||||||
@ -102,7 +110,7 @@ trait IncoherentPolicy extends CoherencePolicy {
|
|||||||
def needsAckReply(x_type: UFix, global_state: UFix): Bool = Bool(false)
|
def needsAckReply(x_type: UFix, global_state: UFix): Bool = Bool(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
trait ThreeStateIncoherence extends IncoherentPolicy {
|
class ThreeStateIncoherence extends IncoherentPolicy {
|
||||||
val tileInvalid :: tileClean :: tileDirty :: Nil = Enum(3){ UFix() }
|
val tileInvalid :: tileClean :: tileDirty :: Nil = Enum(3){ UFix() }
|
||||||
val xactInitReadClean :: xactInitReadDirty :: xactInitWriteback :: Nil = Enum(3){ UFix() }
|
val xactInitReadClean :: xactInitReadDirty :: xactInitWriteback :: Nil = Enum(3){ UFix() }
|
||||||
val xactReplyData :: xactReplyAck :: Nil = Enum(2){ UFix() }
|
val xactReplyData :: xactReplyAck :: Nil = Enum(2){ UFix() }
|
||||||
@ -141,11 +149,256 @@ trait ThreeStateIncoherence extends IncoherentPolicy {
|
|||||||
def getTransactionInitTypeOnCacheControl(cmd: Bits): Bits = xactInitWriteback //TODO
|
def getTransactionInitTypeOnCacheControl(cmd: Bits): Bits = xactInitWriteback //TODO
|
||||||
def getTransactionInitTypeOnWriteback(): Bits = xactInitWriteback
|
def getTransactionInitTypeOnWriteback(): Bits = xactInitWriteback
|
||||||
|
|
||||||
def hasData (init: TransactionInit): Bool = (init.x_type === xactInitWriteback)
|
def messageHasData (init: TransactionInit): Bool = (init.x_type === xactInitWriteback)
|
||||||
def hasData (reply: TransactionReply) = (reply.x_type === xactReplyData)
|
def messageHasData (reply: TransactionReply) = (reply.x_type === xactReplyData)
|
||||||
|
def messageUpdatesDataArray (reply: TransactionReply) = (reply.x_type === xactReplyData)
|
||||||
}
|
}
|
||||||
|
|
||||||
trait FourStateCoherence extends CoherencePolicy {
|
class TwoStateCoherence extends CoherencePolicyWithUncached {
|
||||||
|
|
||||||
|
val tileInvalid :: tileValid :: Nil = Enum(2){ UFix() }
|
||||||
|
val globalInvalid :: globalValid :: Nil = Enum(2){ UFix() }
|
||||||
|
|
||||||
|
val xactInitReadExclusive :: xactInitReadUncached :: xactInitWriteUncached :: Nil = Enum(3){ UFix() }
|
||||||
|
val xactReplyReadExclusive :: xactReplyReadUncached :: xactReplyWriteUncached :: Nil = Enum(3){ UFix() }
|
||||||
|
val probeReqInvalidate :: probeReqCopy :: Nil = Enum(2){ UFix() }
|
||||||
|
val probeRepInvalidateData :: probeRepCopyData :: probeRepInvalidateAck :: probeRepCopyAck :: Nil = Enum(4){ UFix() }
|
||||||
|
|
||||||
|
def isHit (cmd: Bits, state: UFix): Bool = state != tileInvalid
|
||||||
|
def isValid (state: UFix): Bool = state != tileInvalid
|
||||||
|
|
||||||
|
def needsTransactionOnSecondaryMiss(cmd: Bits, outstanding: TransactionInit): Bool = (outstanding.x_type != xactInitReadExclusive)
|
||||||
|
def needsTransactionOnCacheControl(cmd: Bits, state: UFix): Bool = {
|
||||||
|
MuxLookup(cmd, (state === tileValid), Array(
|
||||||
|
M_INV -> (state === tileValid),
|
||||||
|
M_CLN -> (state === tileValid)
|
||||||
|
))
|
||||||
|
}
|
||||||
|
def needsWriteback (state: UFix): Bool = {
|
||||||
|
needsTransactionOnCacheControl(M_INV, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
def newStateOnHit(cmd: Bits, state: UFix): UFix = state
|
||||||
|
def newStateOnCacheControl(cmd: Bits) = {
|
||||||
|
MuxLookup(cmd, tileInvalid, Array(
|
||||||
|
M_INV -> tileInvalid,
|
||||||
|
M_CLN -> tileValid
|
||||||
|
))
|
||||||
|
}
|
||||||
|
def newStateOnWriteback() = newStateOnCacheControl(M_INV)
|
||||||
|
def newStateOnFlush() = newStateOnCacheControl(M_INV)
|
||||||
|
def newStateOnTransactionReply(incoming: TransactionReply, outstanding: TransactionInit): UFix = {
|
||||||
|
MuxLookup(incoming.x_type, tileInvalid, Array(
|
||||||
|
xactReplyReadExclusive -> tileValid,
|
||||||
|
xactReplyReadUncached -> tileInvalid,
|
||||||
|
xactReplyWriteUncached -> tileInvalid
|
||||||
|
))
|
||||||
|
}
|
||||||
|
def newStateOnProbeRequest(incoming: ProbeRequest, state: UFix): Bits = {
|
||||||
|
MuxLookup(incoming.p_type, state, Array(
|
||||||
|
probeReqInvalidate -> tileInvalid,
|
||||||
|
probeReqCopy -> state
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
def getTransactionInitTypeOnUncachedRead() = xactInitReadUncached
|
||||||
|
def getTransactionInitTypeOnUncachedWrite() = xactInitWriteUncached
|
||||||
|
def getTransactionInitTypeOnPrimaryMiss(cmd: Bits, state: UFix): UFix = xactInitReadExclusive
|
||||||
|
def getTransactionInitTypeOnSecondaryMiss(cmd: Bits, state: UFix, outstanding: TransactionInit): UFix = xactInitReadExclusive
|
||||||
|
def getTransactionInitTypeOnCacheControl(cmd: Bits): Bits = xactInitWriteUncached
|
||||||
|
def getTransactionInitTypeOnWriteback(): Bits = getTransactionInitTypeOnCacheControl(M_INV)
|
||||||
|
|
||||||
|
def newProbeReply (incoming: ProbeRequest, state: UFix): ProbeReply = {
|
||||||
|
val reply = Wire() { new ProbeReply() }
|
||||||
|
val with_data = MuxLookup(incoming.p_type, probeRepInvalidateData, Array(
|
||||||
|
probeReqInvalidate -> probeRepInvalidateData,
|
||||||
|
probeReqCopy -> probeRepCopyData
|
||||||
|
))
|
||||||
|
val without_data = MuxLookup(incoming.p_type, probeRepInvalidateAck, Array(
|
||||||
|
probeReqInvalidate -> probeRepInvalidateAck,
|
||||||
|
probeReqCopy -> probeRepCopyAck
|
||||||
|
))
|
||||||
|
reply.p_type := Mux(needsWriteback(state), with_data, without_data)
|
||||||
|
reply.global_xact_id := incoming.global_xact_id
|
||||||
|
reply
|
||||||
|
}
|
||||||
|
|
||||||
|
def messageHasData (reply: ProbeReply): Bool = {
|
||||||
|
(reply.p_type === probeRepInvalidateData ||
|
||||||
|
reply.p_type === probeRepCopyData)
|
||||||
|
}
|
||||||
|
def messageHasData (init: TransactionInit): Bool = {
|
||||||
|
(init.x_type === xactInitWriteUncached)
|
||||||
|
}
|
||||||
|
def messageHasData (reply: TransactionReply): Bool = {
|
||||||
|
(reply.x_type != xactReplyWriteUncached)
|
||||||
|
}
|
||||||
|
def messageUpdatesDataArray (reply: TransactionReply): Bool = {
|
||||||
|
(reply.x_type === xactReplyReadExclusive)
|
||||||
|
}
|
||||||
|
|
||||||
|
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2)
|
||||||
|
|
||||||
|
def getTransactionReplyType(x_type: UFix, count: UFix): Bits = {
|
||||||
|
MuxLookup(x_type, xactReplyReadUncached, Array(
|
||||||
|
xactInitReadExclusive -> xactReplyReadExclusive,
|
||||||
|
xactInitReadUncached -> xactReplyReadUncached,
|
||||||
|
xactInitWriteUncached -> xactReplyWriteUncached
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
def getProbeRequestType(x_type: UFix, global_state: UFix): UFix = {
|
||||||
|
MuxLookup(x_type, probeReqCopy, Array(
|
||||||
|
xactInitReadExclusive -> probeReqInvalidate,
|
||||||
|
xactInitReadUncached -> probeReqCopy,
|
||||||
|
xactInitWriteUncached -> probeReqInvalidate
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
def needsMemRead(x_type: UFix, global_state: UFix): Bool = {
|
||||||
|
(x_type != xactInitWriteUncached)
|
||||||
|
}
|
||||||
|
def needsMemWrite(x_type: UFix, global_state: UFix): Bool = {
|
||||||
|
(x_type === xactInitWriteUncached)
|
||||||
|
}
|
||||||
|
def needsAckReply(x_type: UFix, global_state: UFix): Bool = {
|
||||||
|
(x_type === xactInitWriteUncached)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ThreeStateCoherence extends CoherencePolicyWithUncached { //MEI
|
||||||
|
|
||||||
|
val tileInvalid :: tileExclusiveClean :: tileExclusiveDirty :: Nil = Enum(3){ UFix() }
|
||||||
|
val globalInvalid :: globalExclusiveClean :: Nil = Enum(2){ UFix() }
|
||||||
|
|
||||||
|
val xactInitReadExclusiveClean :: xactInitReadExclusiveDirty :: xactInitReadUncached :: xactInitWriteUncached :: Nil = Enum(4){ UFix() }
|
||||||
|
val xactReplyReadExclusive :: xactReplyReadUncached :: xactReplyWriteUncached :: xactReplyReadExclusiveAck :: Nil = Enum(4){ UFix() }
|
||||||
|
val probeReqInvalidate :: probeReqDowngrade :: probeReqCopy :: Nil = Enum(3){ UFix() }
|
||||||
|
val probeRepInvalidateData :: probeRepDowngradeData :: probeRepCopyData :: probeRepInvalidateAck :: probeRepDowngradeAck :: probeRepCopyAck :: Nil = Enum(6){ UFix() }
|
||||||
|
|
||||||
|
def isHit (cmd: Bits, state: UFix): Bool = state != tileInvalid
|
||||||
|
def isValid (state: UFix): Bool = state != tileInvalid
|
||||||
|
|
||||||
|
def needsTransactionOnSecondaryMiss(cmd: Bits, outstanding: TransactionInit): Bool = {
|
||||||
|
val (read, write) = cpuCmdToRW(cmd)
|
||||||
|
(read && (outstanding.x_type === xactInitReadUncached || outstanding.x_type === xactInitWriteUncached)) ||
|
||||||
|
(write && (outstanding.x_type != xactInitReadExclusiveDirty))
|
||||||
|
}
|
||||||
|
def needsTransactionOnCacheControl(cmd: Bits, state: UFix): Bool = {
|
||||||
|
MuxLookup(cmd, (state === tileExclusiveDirty), Array(
|
||||||
|
M_INV -> (state === tileExclusiveDirty),
|
||||||
|
M_CLN -> (state === tileExclusiveDirty)
|
||||||
|
))
|
||||||
|
}
|
||||||
|
def needsWriteback (state: UFix): Bool = {
|
||||||
|
needsTransactionOnCacheControl(M_INV, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
def newStateOnHit(cmd: Bits, state: UFix): UFix = {
|
||||||
|
val (read, write) = cpuCmdToRW(cmd)
|
||||||
|
Mux(write, tileExclusiveDirty, state)
|
||||||
|
}
|
||||||
|
def newStateOnCacheControl(cmd: Bits) = {
|
||||||
|
MuxLookup(cmd, tileInvalid, Array(
|
||||||
|
M_INV -> tileInvalid,
|
||||||
|
M_CLN -> tileExclusiveClean
|
||||||
|
))
|
||||||
|
}
|
||||||
|
def newStateOnWriteback() = newStateOnCacheControl(M_INV)
|
||||||
|
def newStateOnFlush() = newStateOnCacheControl(M_INV)
|
||||||
|
def newStateOnTransactionReply(incoming: TransactionReply, outstanding: TransactionInit): UFix = {
|
||||||
|
MuxLookup(incoming.x_type, tileInvalid, Array(
|
||||||
|
xactReplyReadExclusive -> Mux(outstanding.x_type === xactInitReadExclusiveDirty, tileExclusiveDirty, tileExclusiveClean),
|
||||||
|
xactReplyReadExclusiveAck -> tileExclusiveDirty,
|
||||||
|
xactReplyReadUncached -> tileInvalid,
|
||||||
|
xactReplyWriteUncached -> tileInvalid
|
||||||
|
))
|
||||||
|
}
|
||||||
|
def newStateOnProbeRequest(incoming: ProbeRequest, state: UFix): Bits = {
|
||||||
|
MuxLookup(incoming.p_type, state, Array(
|
||||||
|
probeReqInvalidate -> tileInvalid,
|
||||||
|
probeReqDowngrade -> tileExclusiveClean,
|
||||||
|
probeReqCopy -> state
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
def getTransactionInitTypeOnUncachedRead() = xactInitReadUncached
|
||||||
|
def getTransactionInitTypeOnUncachedWrite() = xactInitWriteUncached
|
||||||
|
def getTransactionInitTypeOnPrimaryMiss(cmd: Bits, state: UFix): UFix = {
|
||||||
|
val (read, write) = cpuCmdToRW(cmd)
|
||||||
|
Mux(write, xactInitReadExclusiveDirty, xactInitReadExclusiveClean)
|
||||||
|
}
|
||||||
|
def getTransactionInitTypeOnSecondaryMiss(cmd: Bits, state: UFix, outstanding: TransactionInit): UFix = {
|
||||||
|
val (read, write) = cpuCmdToRW(cmd)
|
||||||
|
Mux(write, xactInitReadExclusiveDirty, outstanding.x_type)
|
||||||
|
}
|
||||||
|
def getTransactionInitTypeOnCacheControl(cmd: Bits): Bits = xactInitWriteUncached
|
||||||
|
def getTransactionInitTypeOnWriteback(): Bits = getTransactionInitTypeOnCacheControl(M_INV)
|
||||||
|
|
||||||
|
def newProbeReply (incoming: ProbeRequest, state: UFix): ProbeReply = {
|
||||||
|
val reply = Wire() { new ProbeReply() }
|
||||||
|
val with_data = MuxLookup(incoming.p_type, probeRepInvalidateData, Array(
|
||||||
|
probeReqInvalidate -> probeRepInvalidateData,
|
||||||
|
probeReqDowngrade -> probeRepDowngradeData,
|
||||||
|
probeReqCopy -> probeRepCopyData
|
||||||
|
))
|
||||||
|
val without_data = MuxLookup(incoming.p_type, probeRepInvalidateAck, Array(
|
||||||
|
probeReqInvalidate -> probeRepInvalidateAck,
|
||||||
|
probeReqDowngrade -> probeRepDowngradeAck,
|
||||||
|
probeReqCopy -> probeRepCopyAck
|
||||||
|
))
|
||||||
|
reply.p_type := Mux(needsWriteback(state), with_data, without_data)
|
||||||
|
reply.global_xact_id := incoming.global_xact_id
|
||||||
|
reply
|
||||||
|
}
|
||||||
|
|
||||||
|
def messageHasData (reply: ProbeReply): Bool = {
|
||||||
|
(reply.p_type === probeRepInvalidateData ||
|
||||||
|
reply.p_type === probeRepDowngradeData ||
|
||||||
|
reply.p_type === probeRepCopyData)
|
||||||
|
}
|
||||||
|
def messageHasData (init: TransactionInit): Bool = {
|
||||||
|
(init.x_type === xactInitWriteUncached)
|
||||||
|
}
|
||||||
|
def messageHasData (reply: TransactionReply): Bool = {
|
||||||
|
(reply.x_type != xactReplyWriteUncached && reply.x_type != xactReplyReadExclusiveAck)
|
||||||
|
}
|
||||||
|
def messageUpdatesDataArray (reply: TransactionReply): Bool = {
|
||||||
|
(reply.x_type === xactReplyReadExclusive)
|
||||||
|
}
|
||||||
|
|
||||||
|
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2)
|
||||||
|
|
||||||
|
def getTransactionReplyType(x_type: UFix, count: UFix): Bits = {
|
||||||
|
MuxLookup(x_type, xactReplyReadUncached, Array(
|
||||||
|
xactInitReadExclusiveClean -> xactReplyReadExclusive,
|
||||||
|
xactInitReadExclusiveDirty -> xactReplyReadExclusive,
|
||||||
|
xactInitReadUncached -> xactReplyReadUncached,
|
||||||
|
xactInitWriteUncached -> xactReplyWriteUncached
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
def getProbeRequestType(x_type: UFix, global_state: UFix): UFix = {
|
||||||
|
MuxLookup(x_type, probeReqCopy, Array(
|
||||||
|
xactInitReadExclusiveClean -> probeReqInvalidate,
|
||||||
|
xactInitReadExclusiveDirty -> probeReqInvalidate,
|
||||||
|
xactInitReadUncached -> probeReqCopy,
|
||||||
|
xactInitWriteUncached -> probeReqInvalidate
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
def needsMemRead(x_type: UFix, global_state: UFix): Bool = {
|
||||||
|
(x_type != xactInitWriteUncached)
|
||||||
|
}
|
||||||
|
def needsMemWrite(x_type: UFix, global_state: UFix): Bool = {
|
||||||
|
(x_type === xactInitWriteUncached)
|
||||||
|
}
|
||||||
|
def needsAckReply(x_type: UFix, global_state: UFix): Bool = {
|
||||||
|
(x_type === xactInitWriteUncached)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FourStateCoherence extends CoherencePolicyWithUncached {
|
||||||
|
|
||||||
val tileInvalid :: tileShared :: tileExclusiveClean :: tileExclusiveDirty :: Nil = Enum(4){ UFix() }
|
val tileInvalid :: tileShared :: tileExclusiveClean :: tileExclusiveDirty :: Nil = Enum(4){ UFix() }
|
||||||
val globalInvalid :: globalShared :: globalExclusiveClean :: Nil = Enum(3){ UFix() }
|
val globalInvalid :: globalShared :: globalExclusiveClean :: Nil = Enum(3){ UFix() }
|
||||||
@ -208,6 +461,8 @@ trait FourStateCoherence extends CoherencePolicy {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def getTransactionInitTypeOnUncachedRead() = xactInitReadUncached
|
||||||
|
def getTransactionInitTypeOnUncachedWrite() = xactInitWriteUncached
|
||||||
def getTransactionInitTypeOnPrimaryMiss(cmd: Bits, state: UFix): UFix = {
|
def getTransactionInitTypeOnPrimaryMiss(cmd: Bits, state: UFix): UFix = {
|
||||||
val (read, write) = cpuCmdToRW(cmd)
|
val (read, write) = cpuCmdToRW(cmd)
|
||||||
Mux(write || cmd === M_PFW, xactInitReadExclusive, xactInitReadShared)
|
Mux(write || cmd === M_PFW, xactInitReadExclusive, xactInitReadShared)
|
||||||
@ -236,17 +491,20 @@ trait FourStateCoherence extends CoherencePolicy {
|
|||||||
reply
|
reply
|
||||||
}
|
}
|
||||||
|
|
||||||
def hasData (reply: ProbeReply): Bool = {
|
def messageHasData (reply: ProbeReply): Bool = {
|
||||||
(reply.p_type === probeRepInvalidateData ||
|
(reply.p_type === probeRepInvalidateData ||
|
||||||
reply.p_type === probeRepDowngradeData ||
|
reply.p_type === probeRepDowngradeData ||
|
||||||
reply.p_type === probeRepCopyData)
|
reply.p_type === probeRepCopyData)
|
||||||
}
|
}
|
||||||
def hasData (init: TransactionInit): Bool = {
|
def messageHasData (init: TransactionInit): Bool = {
|
||||||
(init.x_type === xactInitWriteUncached)
|
(init.x_type === xactInitWriteUncached)
|
||||||
}
|
}
|
||||||
def hasData (reply: TransactionReply): Bool = {
|
def messageHasData (reply: TransactionReply): Bool = {
|
||||||
(reply.x_type != xactReplyWriteUncached && reply.x_type != xactReplyReadExclusiveAck)
|
(reply.x_type != xactReplyWriteUncached && reply.x_type != xactReplyReadExclusiveAck)
|
||||||
}
|
}
|
||||||
|
def messageUpdatesDataArray (reply: TransactionReply): Bool = {
|
||||||
|
(reply.x_type === xactReplyReadShared || reply.x_type === xactReplyReadExclusive)
|
||||||
|
}
|
||||||
|
|
||||||
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2)
|
def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2)
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ class ioTileLink extends Bundle {
|
|||||||
val xact_finish = (new ioDecoupled) { new TransactionFinish }
|
val xact_finish = (new ioDecoupled) { new TransactionFinish }
|
||||||
}
|
}
|
||||||
|
|
||||||
class XactTracker(ntiles: Int, id: Int) extends Component with FourStateCoherence {
|
class XactTracker(ntiles: Int, id: Int, co: CoherencePolicy) extends Component {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val alloc_req = (new ioDecoupled) { new TrackerAllocReq }.flip
|
val alloc_req = (new ioDecoupled) { new TrackerAllocReq }.flip
|
||||||
val p_data = (new ioPipe) { new TrackerProbeData }.flip
|
val p_data = (new ioPipe) { new TrackerProbeData }.flip
|
||||||
@ -140,7 +140,7 @@ class XactTracker(ntiles: Int, id: Int) extends Component with FourStateCoherenc
|
|||||||
io.sharer_count := UFix(ntiles) // TODO: Broadcast only
|
io.sharer_count := UFix(ntiles) // TODO: Broadcast only
|
||||||
io.x_type := x_type_
|
io.x_type := x_type_
|
||||||
|
|
||||||
io.mem_req_cmd.valid := Bool(false)
|
io.mem_req_cmd.valid := Bool(false)
|
||||||
io.mem_req_cmd.bits.rw := Bool(false)
|
io.mem_req_cmd.bits.rw := Bool(false)
|
||||||
io.mem_req_cmd.bits.addr := addr_
|
io.mem_req_cmd.bits.addr := addr_
|
||||||
io.mem_req_cmd.bits.tag := UFix(id)
|
io.mem_req_cmd.bits.tag := UFix(id)
|
||||||
@ -148,7 +148,7 @@ class XactTracker(ntiles: Int, id: Int) extends Component with FourStateCoherenc
|
|||||||
io.mem_req_data.bits.data := UFix(0)
|
io.mem_req_data.bits.data := UFix(0)
|
||||||
io.mem_req_lock := Bool(false)
|
io.mem_req_lock := Bool(false)
|
||||||
io.probe_req.valid := Bool(false)
|
io.probe_req.valid := Bool(false)
|
||||||
io.probe_req.bits.p_type := getProbeRequestType(x_type_, UFix(0))
|
io.probe_req.bits.p_type := co.getProbeRequestType(x_type_, UFix(0))
|
||||||
io.probe_req.bits.global_xact_id := UFix(id)
|
io.probe_req.bits.global_xact_id := UFix(id)
|
||||||
io.probe_req.bits.address := addr_
|
io.probe_req.bits.address := addr_
|
||||||
io.push_p_req := Bits(0, width = ntiles)
|
io.push_p_req := Bits(0, width = ntiles)
|
||||||
@ -167,8 +167,8 @@ class XactTracker(ntiles: Int, id: Int) extends Component with FourStateCoherenc
|
|||||||
x_type_ := io.alloc_req.bits.xact_init.x_type
|
x_type_ := io.alloc_req.bits.xact_init.x_type
|
||||||
init_tile_id_ := io.alloc_req.bits.tile_id
|
init_tile_id_ := io.alloc_req.bits.tile_id
|
||||||
tile_xact_id_ := io.alloc_req.bits.xact_init.tile_xact_id
|
tile_xact_id_ := io.alloc_req.bits.xact_init.tile_xact_id
|
||||||
x_init_data_needs_write := hasData(io.alloc_req.bits.xact_init)
|
x_init_data_needs_write := co.messageHasData(io.alloc_req.bits.xact_init)
|
||||||
x_needs_read := needsMemRead(io.alloc_req.bits.xact_init.x_type, UFix(0))
|
x_needs_read := co.needsMemRead(io.alloc_req.bits.xact_init.x_type, UFix(0))
|
||||||
if(ntiles > 1) p_rep_count := UFix(ntiles-1)
|
if(ntiles > 1) p_rep_count := UFix(ntiles-1)
|
||||||
val p_req_initial_flags = ~( UFix(1) << io.alloc_req.bits.tile_id ) //TODO: Broadcast only
|
val p_req_initial_flags = ~( UFix(1) << io.alloc_req.bits.tile_id ) //TODO: Broadcast only
|
||||||
p_req_flags := p_req_initial_flags
|
p_req_flags := p_req_initial_flags
|
||||||
@ -226,7 +226,7 @@ class XactTracker(ntiles: Int, id: Int) extends Component with FourStateCoherenc
|
|||||||
} . elsewhen (x_needs_read) {
|
} . elsewhen (x_needs_read) {
|
||||||
doMemReqRead(io.mem_req_cmd, x_needs_read)
|
doMemReqRead(io.mem_req_cmd, x_needs_read)
|
||||||
} . otherwise {
|
} . otherwise {
|
||||||
state := Mux(needsAckReply(x_type_, UFix(0)), s_ack, s_busy)
|
state := Mux(co.needsAckReply(x_type_, UFix(0)), s_ack, s_busy)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is(s_ack) {
|
is(s_ack) {
|
||||||
@ -241,17 +241,17 @@ class XactTracker(ntiles: Int, id: Int) extends Component with FourStateCoherenc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class CoherenceHub(ntiles: Int) extends Component with CoherencePolicy {
|
abstract class CoherenceHub(ntiles: Int, co: CoherencePolicy) extends Component {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val tiles = Vec(ntiles) { new ioTileLink() }.flip
|
val tiles = Vec(ntiles) { new ioTileLink() }.flip
|
||||||
val mem = new ioMem
|
val mem = new ioMem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CoherenceHubNull extends CoherenceHub(1) with ThreeStateIncoherence
|
class CoherenceHubNull(co: ThreeStateIncoherence) extends CoherenceHub(1, co)
|
||||||
{
|
{
|
||||||
val x_init = io.tiles(0).xact_init
|
val x_init = io.tiles(0).xact_init
|
||||||
val is_write = x_init.bits.x_type === xactInitWriteback
|
val is_write = x_init.bits.x_type === co.xactInitWriteback
|
||||||
x_init.ready := io.mem.req_cmd.ready && !(is_write && io.mem.resp.valid) //stall write req/resp to handle previous read resp
|
x_init.ready := io.mem.req_cmd.ready && !(is_write && io.mem.resp.valid) //stall write req/resp to handle previous read resp
|
||||||
io.mem.req_cmd.valid := x_init.valid && !(is_write && io.mem.resp.valid)
|
io.mem.req_cmd.valid := x_init.valid && !(is_write && io.mem.resp.valid)
|
||||||
io.mem.req_cmd.bits.rw := is_write
|
io.mem.req_cmd.bits.rw := is_write
|
||||||
@ -260,7 +260,7 @@ class CoherenceHubNull extends CoherenceHub(1) with ThreeStateIncoherence
|
|||||||
io.mem.req_data <> io.tiles(0).xact_init_data
|
io.mem.req_data <> io.tiles(0).xact_init_data
|
||||||
|
|
||||||
val x_rep = io.tiles(0).xact_rep
|
val x_rep = io.tiles(0).xact_rep
|
||||||
x_rep.bits.x_type := Mux(io.mem.resp.valid, xactReplyData, xactReplyAck)
|
x_rep.bits.x_type := Mux(io.mem.resp.valid, co.xactReplyData, co.xactReplyAck)
|
||||||
x_rep.bits.tile_xact_id := Mux(io.mem.resp.valid, io.mem.resp.bits.tag, x_init.bits.tile_xact_id)
|
x_rep.bits.tile_xact_id := Mux(io.mem.resp.valid, io.mem.resp.bits.tag, x_init.bits.tile_xact_id)
|
||||||
x_rep.bits.global_xact_id := UFix(0) // don't care
|
x_rep.bits.global_xact_id := UFix(0) // don't care
|
||||||
x_rep.bits.data := io.mem.resp.bits.data
|
x_rep.bits.data := io.mem.resp.bits.data
|
||||||
@ -275,9 +275,9 @@ class CoherenceHubNull extends CoherenceHub(1) with ThreeStateIncoherence
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class CoherenceHubBroadcast(ntiles: Int) extends CoherenceHub(ntiles) with FourStateCoherence
|
class CoherenceHubBroadcast(ntiles: Int, co: CoherencePolicy) extends CoherenceHub(ntiles, co)
|
||||||
{
|
{
|
||||||
val trackerList = (0 until NGLOBAL_XACTS).map(new XactTracker(ntiles, _))
|
val trackerList = (0 until NGLOBAL_XACTS).map(new XactTracker(ntiles, _, co))
|
||||||
|
|
||||||
val busy_arr = Vec(NGLOBAL_XACTS){ Wire(){Bool()} }
|
val busy_arr = Vec(NGLOBAL_XACTS){ Wire(){Bool()} }
|
||||||
val addr_arr = Vec(NGLOBAL_XACTS){ Wire(){Bits(width=PADDR_BITS-OFFSET_BITS)} }
|
val addr_arr = Vec(NGLOBAL_XACTS){ Wire(){Bits(width=PADDR_BITS-OFFSET_BITS)} }
|
||||||
@ -344,12 +344,12 @@ class CoherenceHubBroadcast(ntiles: Int) extends CoherenceHub(ntiles) with FourS
|
|||||||
rep.bits.require_ack := Bool(true)
|
rep.bits.require_ack := Bool(true)
|
||||||
rep.valid := Bool(false)
|
rep.valid := Bool(false)
|
||||||
when(io.mem.resp.valid && (UFix(j) === init_tile_id_arr(mem_idx))) {
|
when(io.mem.resp.valid && (UFix(j) === init_tile_id_arr(mem_idx))) {
|
||||||
rep.bits.x_type := getTransactionReplyType(x_type_arr(mem_idx), sh_count_arr(mem_idx))
|
rep.bits.x_type := co.getTransactionReplyType(x_type_arr(mem_idx), sh_count_arr(mem_idx))
|
||||||
rep.bits.tile_xact_id := tile_xact_id_arr(mem_idx)
|
rep.bits.tile_xact_id := tile_xact_id_arr(mem_idx)
|
||||||
rep.bits.global_xact_id := mem_idx
|
rep.bits.global_xact_id := mem_idx
|
||||||
rep.valid := Bool(true)
|
rep.valid := Bool(true)
|
||||||
} . otherwise {
|
} . otherwise {
|
||||||
rep.bits.x_type := getTransactionReplyType(x_type_arr(ack_idx), sh_count_arr(ack_idx))
|
rep.bits.x_type := co.getTransactionReplyType(x_type_arr(ack_idx), sh_count_arr(ack_idx))
|
||||||
rep.bits.tile_xact_id := tile_xact_id_arr(ack_idx)
|
rep.bits.tile_xact_id := tile_xact_id_arr(ack_idx)
|
||||||
rep.bits.global_xact_id := ack_idx
|
rep.bits.global_xact_id := ack_idx
|
||||||
when (UFix(j) === init_tile_id_arr(ack_idx)) {
|
when (UFix(j) === init_tile_id_arr(ack_idx)) {
|
||||||
@ -417,16 +417,16 @@ class CoherenceHubBroadcast(ntiles: Int) extends CoherenceHub(ntiles) with FourS
|
|||||||
val conflicts = Vec(NGLOBAL_XACTS) { Wire() { Bool() } }
|
val conflicts = Vec(NGLOBAL_XACTS) { Wire() { Bool() } }
|
||||||
for( i <- 0 until NGLOBAL_XACTS) {
|
for( i <- 0 until NGLOBAL_XACTS) {
|
||||||
val t = trackerList(i).io
|
val t = trackerList(i).io
|
||||||
conflicts(i) := t.busy && x_init.valid && isCoherenceConflict(t.addr, x_init.bits.address)
|
conflicts(i) := t.busy && x_init.valid && co.isCoherenceConflict(t.addr, x_init.bits.address)
|
||||||
}
|
}
|
||||||
x_abort.bits.tile_xact_id := x_init.bits.tile_xact_id
|
x_abort.bits.tile_xact_id := x_init.bits.tile_xact_id
|
||||||
want_to_abort_arr(j) := x_init.valid && (conflicts.toBits.orR || busy_arr.toBits.andR || (!x_init_data_dep_list(j).io.enq.ready && hasData(x_init.bits)))
|
want_to_abort_arr(j) := x_init.valid && (conflicts.toBits.orR || busy_arr.toBits.andR || (!x_init_data_dep_list(j).io.enq.ready && co.messageHasData(x_init.bits)))
|
||||||
|
|
||||||
x_abort.valid := Bool(false)
|
x_abort.valid := Bool(false)
|
||||||
switch(abort_state_arr(j)) {
|
switch(abort_state_arr(j)) {
|
||||||
is(s_idle) {
|
is(s_idle) {
|
||||||
when(want_to_abort_arr(j)) {
|
when(want_to_abort_arr(j)) {
|
||||||
when(hasData(x_init.bits)) {
|
when(co.messageHasData(x_init.bits)) {
|
||||||
abort_state_arr(j) := s_abort_drain
|
abort_state_arr(j) := s_abort_drain
|
||||||
} . otherwise {
|
} . otherwise {
|
||||||
abort_state_arr(j) := s_abort_send
|
abort_state_arr(j) := s_abort_send
|
||||||
@ -478,7 +478,7 @@ class CoherenceHubBroadcast(ntiles: Int) extends CoherenceHub(ntiles) with FourS
|
|||||||
init_arb.io.in(j).bits.tile_id := UFix(j)
|
init_arb.io.in(j).bits.tile_id := UFix(j)
|
||||||
val pop_x_inits = trackerList.map(_.io.pop_x_init(j).toBool)
|
val pop_x_inits = trackerList.map(_.io.pop_x_init(j).toBool)
|
||||||
val do_pop = foldR(pop_x_inits)(_||_)
|
val do_pop = foldR(pop_x_inits)(_||_)
|
||||||
x_init_data_dep_list(j).io.enq.valid := do_pop && hasData(x_init.bits) && (abort_state_arr(j) === s_idle)
|
x_init_data_dep_list(j).io.enq.valid := do_pop && co.messageHasData(x_init.bits) && (abort_state_arr(j) === s_idle)
|
||||||
x_init_data_dep_list(j).io.enq.bits.global_xact_id := OHToUFix(pop_x_inits)
|
x_init_data_dep_list(j).io.enq.bits.global_xact_id := OHToUFix(pop_x_inits)
|
||||||
x_init.ready := (abort_state_arr(j) === s_abort_complete) || do_pop
|
x_init.ready := (abort_state_arr(j) === s_abort_complete) || do_pop
|
||||||
x_init_data.ready := (abort_state_arr(j) === s_abort_drain) || foldR(trackerList.map(_.io.pop_x_init_data(j).toBool))(_||_)
|
x_init_data.ready := (abort_state_arr(j) === s_abort_drain) || foldR(trackerList.map(_.io.pop_x_init_data(j).toBool))(_||_)
|
||||||
|
Loading…
Reference in New Issue
Block a user