Initial version of migratory protocol
This commit is contained in:
		| @@ -9,7 +9,7 @@ object cpuCmdToRW { | ||||
|     val load    = (cmd === M_XRD) | ||||
|     val amo     = cmd(3).toBool | ||||
|     val read    = load  || amo || (cmd === M_PFR) || (cmd === M_PFW) | ||||
|     val write   = store || amo | ||||
|     val write   = store || amo  | ||||
|     (read, write) | ||||
|   } | ||||
| } | ||||
| @@ -556,7 +556,7 @@ class MESICoherence extends CoherencePolicyWithUncached { | ||||
|   val xactReplyReadShared :: xactReplyReadExclusive :: xactReplyReadUncached :: xactReplyWriteUncached :: xactReplyReadExclusiveAck :: xactReplyReadWordUncached :: xactReplyWriteWordUncached :: xactReplyAtomicUncached :: Nil = Enum(8){ UFix() } | ||||
|   val probeReqInvalidate :: probeReqDowngrade :: probeReqCopy :: Nil = Enum(3){ UFix() } | ||||
|   val probeRepInvalidateData :: probeRepDowngradeData :: probeRepCopyData :: probeRepInvalidateAck :: probeRepDowngradeAck :: probeRepCopyAck :: Nil = Enum(6){ UFix() } | ||||
|   val uncachedTypeList = List(xactInitReadUncached, xactInitWriteUncached, xactReplyReadWordUncached, xactInitWriteWordUncached, xactInitAtomicUncached)  | ||||
|   val uncachedTypeList = List(xactInitReadUncached, xactInitWriteUncached, xactInitReadWordUncached, xactInitWriteWordUncached, xactInitAtomicUncached)  | ||||
|   val hasDataTypeList = List(xactInitWriteUncached, xactInitWriteWordUncached, xactInitAtomicUncached)  | ||||
|  | ||||
|   def isHit (cmd: Bits, state: UFix): Bool = { | ||||
| @@ -699,3 +699,173 @@ class MESICoherence extends CoherencePolicyWithUncached { | ||||
|       (x_type === xactInitWriteUncached) | ||||
|   } | ||||
| } | ||||
|  | ||||
| class MigratoryCoherence extends CoherencePolicyWithUncached { | ||||
|  | ||||
|   val tileInvalid :: tileShared :: tileExclusiveClean :: tileExclusiveDirty :: tileSharedByTwo :: tileMigratoryClean :: tileMigratoryDirty :: Nil = Enum(7){ UFix() } | ||||
|  | ||||
|   val xactInitReadShared :: xactInitReadExclusive :: xactInitReadUncached :: xactInitWriteUncached :: xactInitReadWordUncached :: xactInitWriteWordUncached :: xactInitAtomicUncached :: xactInitInvalidateOthers :: Nil = Enum(8){ UFix() } | ||||
|   val xactReplyReadShared :: xactReplyReadExclusive :: xactReplyReadUncached :: xactReplyWriteUncached :: xactReplyReadExclusiveAck :: xactReplyReadWordUncached :: xactReplyWriteWordUncached :: xactReplyAtomicUncached :: xactReplyReadMigratory :: Nil = Enum(9){ UFix() } | ||||
|   val probeReqInvalidate :: probeReqDowngrade :: probeReqCopy :: probeReqInvalidateOthers :: Nil = Enum(4){ UFix() } | ||||
|   val probeRepInvalidateData :: probeRepDowngradeData :: probeRepCopyData :: probeRepInvalidateAck :: probeRepDowngradeAck :: probeRepCopyAck :: probeRepDowngradeDataMigratory :: probeRepDowngradeAckHasCopy :: probeRepInvalidateDataMigratory :: probeRepInvalidateAckMigratory :: Nil = Enum(10){ UFix() } | ||||
|   val uncachedTypeList = List(xactInitReadUncached, xactInitWriteUncached, xactInitReadWordUncached, xactInitWriteWordUncached, xactInitAtomicUncached)  | ||||
|   val hasDataTypeList = List(xactInitWriteUncached, xactInitWriteWordUncached, xactInitAtomicUncached)  | ||||
|  | ||||
|   def uFixListContains(list: List[UFix], elem: UFix): Bool = list.map(elem === _).reduceLeft(_||_) | ||||
|  | ||||
|   def isHit (cmd: Bits, state: UFix): Bool = { | ||||
|     val (read, write) = cpuCmdToRW(cmd) | ||||
|     Mux(write, uFixListContains(List(tileExclusiveClean, tileExclusiveDirty, tileMigratoryClean, tileMigratoryDirty), state), (state != tileInvalid)) | ||||
|   } | ||||
|   def isValid (state: UFix): Bool = { | ||||
|     state != tileInvalid | ||||
|   } | ||||
|  | ||||
|   def needsTransactionOnSecondaryMiss(cmd: Bits, outstanding: TransactionInit): Bool = { | ||||
|     val (read, write) = cpuCmdToRW(cmd) | ||||
|     (read && messageIsUncached(outstanding)) || | ||||
|       (write && (outstanding.x_type != xactInitReadExclusive && outstanding.x_type != xactInitInvalidateOthers)) | ||||
|   } | ||||
|   def needsTransactionOnCacheControl(cmd: Bits, state: UFix): Bool = { | ||||
|     MuxLookup(cmd, (state === tileExclusiveDirty), Array( | ||||
|       M_INV -> uFixListContains(List(tileExclusiveDirty,tileMigratoryDirty),state), | ||||
|       M_CLN -> uFixListContains(List(tileExclusiveDirty,tileMigratoryDirty),state) | ||||
|     )) | ||||
|   } | ||||
|   def needsWriteback (state: UFix): Bool = { | ||||
|     needsTransactionOnCacheControl(M_INV, state) | ||||
|   } | ||||
|  | ||||
|   def newStateOnHit(cmd: Bits, state: UFix): UFix = {  | ||||
|     val (read, write) = cpuCmdToRW(cmd) | ||||
|     Mux(write, MuxLookup(state, tileExclusiveDirty, Array( | ||||
|                 tileExclusiveClean -> tileExclusiveDirty, | ||||
|                 tileMigratoryClean -> tileMigratoryDirty)), state) | ||||
|   } | ||||
|   def newStateOnCacheControl(cmd: Bits) = { | ||||
|     MuxLookup(cmd, tileInvalid, Array( | ||||
|       M_INV -> tileInvalid, | ||||
|       M_CLN -> tileShared | ||||
|     )) | ||||
|   } | ||||
|   def newStateOnWriteback() = newStateOnCacheControl(M_INV) | ||||
|   def newStateOnFlush() = newStateOnCacheControl(M_INV) | ||||
|   def newStateOnTransactionReply(incoming: TransactionReply, outstanding: TransactionInit): UFix = { | ||||
|     MuxLookup(incoming.x_type, tileInvalid, Array( | ||||
|       xactReplyReadShared -> tileShared, | ||||
|       xactReplyReadExclusive  -> MuxLookup(outstanding.x_type, tileExclusiveDirty,  Array( | ||||
|                                    xactInitReadExclusive -> tileExclusiveDirty, | ||||
|                                    xactInitReadShared -> tileExclusiveClean)), | ||||
|       xactReplyReadExclusiveAck -> tileExclusiveDirty,  | ||||
|       xactReplyReadUncached -> tileInvalid, | ||||
|       xactReplyWriteUncached -> tileInvalid, | ||||
|       xactReplyReadWordUncached -> tileInvalid, | ||||
|       xactReplyWriteWordUncached -> tileInvalid, | ||||
|       xactReplyAtomicUncached -> tileInvalid, | ||||
|       xactReplyReadMigratory -> MuxLookup(outstanding.x_type, tileMigratoryDirty, Array( | ||||
|                                   xactInitInvalidateOthers -> tileMigratoryDirty, | ||||
|                                   xactInitReadExclusive -> tileMigratoryDirty, | ||||
|                                   xactInitReadShared -> tileMigratoryClean)) | ||||
|     )) | ||||
|   }  | ||||
|   def newStateOnProbeRequest(incoming: ProbeRequest, state: UFix): Bits = { | ||||
|     MuxLookup(incoming.p_type, state, Array( | ||||
|       probeReqInvalidate -> tileInvalid, | ||||
|       probeReqInvalidateOthers -> tileInvalid, | ||||
|       probeReqCopy -> state, | ||||
|       probeReqDowngrade -> MuxLookup(state, tileShared, Array( | ||||
|                               tileExclusiveClean -> tileSharedByTwo, | ||||
|                               tileExclusiveDirty -> tileSharedByTwo, | ||||
|                               tileSharedByTwo    -> tileShared, | ||||
|                               tileMigratoryClean -> tileSharedByTwo, | ||||
|                               tileMigratoryDirty -> tileInvalid)) | ||||
|     )) | ||||
|   } | ||||
|  | ||||
|   def getUncachedReadTransactionInit(addr: UFix, id: UFix) = TransactionInit(xactInitReadUncached, addr, id) | ||||
|   def getUncachedWriteTransactionInit(addr: UFix, id: UFix) = TransactionInit(xactInitWriteUncached, addr, id) | ||||
|   def getUncachedReadWordTransactionInit(addr: UFix, id: UFix) = TransactionInit(xactInitReadWordUncached, addr, id) | ||||
|   def getUncachedWriteWordTransactionInit(addr: UFix, id: UFix, write_mask: Bits) = TransactionInit(xactInitWriteWordUncached, addr, id, write_mask) | ||||
|   def getUncachedAtomicTransactionInit(addr: UFix, id: UFix, subword_addr: UFix, atomic_op: UFix) = TransactionInit(xactInitAtomicUncached, addr, id, subword_addr, atomic_op) | ||||
|  | ||||
|   def getTransactionInitTypeOnPrimaryMiss(cmd: Bits, state: UFix): UFix = { | ||||
|     val (read, write) = cpuCmdToRW(cmd) | ||||
|     Mux(write || cmd === M_PFW, Mux(state === tileInvalid, xactInitReadExclusive, xactInitInvalidateOthers), xactInitReadShared) | ||||
|   } | ||||
|   def getTransactionInitTypeOnSecondaryMiss(cmd: Bits, state: UFix, outstanding: TransactionInit): UFix = { | ||||
|     val (read, write) = cpuCmdToRW(cmd) | ||||
|     Mux(write, Mux(state === tileInvalid, xactInitReadExclusive, xactInitInvalidateOthers), outstanding.x_type) | ||||
|   } | ||||
|   def getTransactionInitTypeOnCacheControl(cmd: Bits): Bits = xactInitWriteUncached | ||||
|   def getTransactionInitTypeOnWriteback(): Bits = getTransactionInitTypeOnCacheControl(M_INV) | ||||
|  | ||||
|   def newProbeReply (incoming: ProbeRequest, state: UFix): ProbeReply = { | ||||
|     Assert( incoming.p_type === probeReqInvalidateOthers && needsWriteback(state), "Bad probe request type, should be impossible.") | ||||
|     val reply = new ProbeReply() | ||||
|     val with_data = MuxLookup(incoming.p_type, probeRepInvalidateData, Array( | ||||
|       probeReqInvalidate       -> Mux(uFixListContains(List(tileExclusiveDirty, tileMigratoryDirty), state),  | ||||
|                                     probeRepInvalidateDataMigratory, probeRepInvalidateData), | ||||
|       probeReqDowngrade        -> Mux(state === tileMigratoryDirty, probeRepDowngradeDataMigratory, probeRepDowngradeData), | ||||
|       probeReqCopy       -> probeRepCopyData | ||||
|     )) | ||||
|     val without_data = MuxLookup(incoming.p_type, probeRepInvalidateAck, Array( | ||||
|       probeReqInvalidate       -> Mux(tileExclusiveClean === state, probeRepInvalidateAckMigratory, probeRepInvalidateAck), | ||||
|       probeReqInvalidateOthers -> Mux(state === tileSharedByTwo, probeRepInvalidateAckMigratory, probeRepInvalidateAck), | ||||
|       probeReqDowngrade  -> Mux(state != tileInvalid, probeRepDowngradeAckHasCopy, 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 = { | ||||
|     uFixListContains(List(probeRepInvalidateData, probeRepDowngradeData, probeRepCopyData, probeRepInvalidateDataMigratory, probeRepDowngradeDataMigratory), reply.p_type) | ||||
|   } | ||||
|   def messageHasData (init: TransactionInit): Bool = uFixListContains(hasDataTypeList, init.x_type) | ||||
|   def messageHasData (reply: TransactionReply): Bool = { | ||||
|     uFixListContains(List(xactReplyReadShared, xactReplyReadExclusive, xactReplyReadUncached, xactReplyReadMigratory, xactReplyReadWordUncached, xactReplyAtomicUncached), reply.x_type) | ||||
|   } | ||||
|   def messageUpdatesDataArray (reply: TransactionReply): Bool = { | ||||
|     uFixListContains(List(xactReplyReadShared, xactReplyReadExclusive, xactReplyReadMigratory), reply.x_type) | ||||
|   } | ||||
|   def messageIsUncached(init: TransactionInit): Bool = uFixListContains(uncachedTypeList, init.x_type) | ||||
|  | ||||
|   def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = (addr1 === addr2) | ||||
|  | ||||
|   def getTransactionReplyType(x_type: UFix, count: UFix): Bits = { | ||||
|     MuxLookup(x_type, xactReplyReadUncached, Array( | ||||
|       xactInitReadShared    -> Mux(count > UFix(0), xactReplyReadShared, xactReplyReadExclusive), //TODO: what is count? Depend on probeRep.p_type??? | ||||
|       xactInitReadExclusive -> xactReplyReadExclusive,                                             | ||||
|       xactInitReadUncached  -> xactReplyReadUncached, | ||||
|       xactInitWriteUncached -> xactReplyWriteUncached, | ||||
|       xactInitReadWordUncached  -> xactReplyReadWordUncached, | ||||
|       xactInitWriteWordUncached -> xactReplyWriteWordUncached, | ||||
|       xactInitAtomicUncached -> xactReplyAtomicUncached, | ||||
|       xactInitInvalidateOthers -> xactReplyReadExclusiveAck                                      //TODO: add this to MESI? | ||||
|     )) | ||||
|   } | ||||
|  | ||||
|   def getProbeRequestType(x_type: UFix, global_state: UFix): UFix = { | ||||
|     MuxLookup(x_type, probeReqCopy, Array( | ||||
|       xactInitReadShared -> probeReqDowngrade, | ||||
|       xactInitReadExclusive -> probeReqInvalidate,  | ||||
|       xactInitReadUncached -> probeReqCopy,  | ||||
|       xactInitWriteUncached -> probeReqInvalidate, | ||||
|       xactInitReadWordUncached -> probeReqCopy,  | ||||
|       xactInitWriteWordUncached -> probeReqInvalidate, | ||||
|       xactInitAtomicUncached -> probeReqInvalidate, | ||||
|       xactInitInvalidateOthers -> probeReqInvalidateOthers | ||||
|     )) | ||||
|   } | ||||
|  | ||||
|   def needsMemRead(x_type: UFix, global_state: UFix): Bool = { | ||||
|       (x_type != xactInitWriteUncached && x_type != xactInitInvalidateOthers) | ||||
|   } | ||||
|   def needsMemWrite(x_type: UFix, global_state: UFix): Bool = { | ||||
|       (x_type === xactInitWriteUncached || x_type === xactInitWriteWordUncached || x_type === xactInitAtomicUncached) | ||||
|   } | ||||
|   def needsAckReply(x_type: UFix, global_state: UFix): Bool = { | ||||
|       (x_type === xactInitWriteUncached || x_type === xactInitWriteWordUncached ||x_type === xactInitInvalidateOthers) | ||||
|   } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user