Refactored coherence as member rather than trait. MI and MEI protocols.
This commit is contained in:
		| @@ -50,7 +50,7 @@ object cpuCmdToRW { | ||||
|   } | ||||
| } | ||||
|  | ||||
| trait CoherencePolicy { | ||||
| abstract class CoherencePolicy { | ||||
|   def isHit (cmd: Bits, state: UFix): Bool | ||||
|   def isValid (state: UFix): Bool | ||||
|  | ||||
| @@ -72,9 +72,10 @@ trait CoherencePolicy { | ||||
|  | ||||
|   def newProbeReply (incoming: ProbeRequest, state: UFix): ProbeReply | ||||
|  | ||||
|   def hasData (reply: ProbeReply): Bool | ||||
|   def hasData (init: TransactionInit): Bool | ||||
|   def hasData (reply: TransactionReply): Bool | ||||
|   def messageHasData (reply: ProbeReply): Bool | ||||
|   def messageHasData (init: TransactionInit): Bool | ||||
|   def messageHasData (reply: TransactionReply): Bool | ||||
|   def messageUpdatesDataArray (reply: TransactionReply): Bool | ||||
|  | ||||
|   def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool | ||||
|   def getTransactionReplyType(x_type: UFix, count: UFix): Bits | ||||
| @@ -84,7 +85,14 @@ trait CoherencePolicy { | ||||
|   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 | ||||
|   def newStateOnProbeRequest(incoming: ProbeRequest, state: UFix): Bits = state | ||||
|   def newProbeReply (incoming: ProbeRequest, state: UFix): ProbeReply = {  | ||||
| @@ -93,7 +101,7 @@ trait IncoherentPolicy extends CoherencePolicy { | ||||
|     reply.global_xact_id := UFix(0) | ||||
|     reply | ||||
|   } | ||||
|   def hasData (reply: ProbeReply) = Bool(false) | ||||
|   def messageHasData (reply: ProbeReply) = Bool(false) | ||||
|   def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = Bool(false) | ||||
|   def getTransactionReplyType(x_type: UFix, count: UFix): Bits = Bits(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) | ||||
| } | ||||
|  | ||||
| trait ThreeStateIncoherence extends IncoherentPolicy { | ||||
| class ThreeStateIncoherence extends IncoherentPolicy { | ||||
|   val tileInvalid :: tileClean :: tileDirty :: Nil = Enum(3){ UFix() } | ||||
|   val xactInitReadClean :: xactInitReadDirty :: xactInitWriteback :: Nil = Enum(3){ UFix() } | ||||
|   val xactReplyData :: xactReplyAck :: Nil = Enum(2){ UFix() } | ||||
| @@ -141,11 +149,256 @@ trait ThreeStateIncoherence extends IncoherentPolicy { | ||||
|   def getTransactionInitTypeOnCacheControl(cmd: Bits): Bits = xactInitWriteback //TODO | ||||
|   def getTransactionInitTypeOnWriteback(): Bits = xactInitWriteback | ||||
|  | ||||
|   def hasData (init: TransactionInit): Bool = (init.x_type === xactInitWriteback) | ||||
|   def hasData (reply: TransactionReply) = (reply.x_type === xactReplyData) | ||||
|   def messageHasData (init: TransactionInit): Bool = (init.x_type === xactInitWriteback) | ||||
|   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 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 = { | ||||
|     val (read, write) = cpuCmdToRW(cmd) | ||||
|     Mux(write || cmd === M_PFW, xactInitReadExclusive, xactInitReadShared) | ||||
| @@ -236,17 +491,20 @@ trait FourStateCoherence extends CoherencePolicy { | ||||
|     reply | ||||
|   } | ||||
|  | ||||
|   def hasData (reply: ProbeReply): Bool = { | ||||
|   def messageHasData (reply: ProbeReply): Bool = { | ||||
|     (reply.p_type === probeRepInvalidateData || | ||||
|      reply.p_type === probeRepDowngradeData || | ||||
|      reply.p_type === probeRepCopyData) | ||||
|   } | ||||
|   def hasData (init: TransactionInit): Bool = { | ||||
|   def messageHasData (init: TransactionInit): Bool = { | ||||
|     (init.x_type === xactInitWriteUncached) | ||||
|   } | ||||
|   def hasData (reply: TransactionReply): Bool = { | ||||
|   def messageHasData (reply: TransactionReply): Bool = { | ||||
|     (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) | ||||
|  | ||||
|   | ||||
| @@ -50,7 +50,7 @@ class ioTileLink extends Bundle { | ||||
|   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 alloc_req       = (new ioDecoupled) { new TrackerAllocReq }.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.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.addr := addr_ | ||||
|   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_lock := 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.address := addr_ | ||||
|   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 | ||||
|         init_tile_id_ := io.alloc_req.bits.tile_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_needs_read := needsMemRead(io.alloc_req.bits.xact_init.x_type, UFix(0)) | ||||
|         x_init_data_needs_write := co.messageHasData(io.alloc_req.bits.xact_init) | ||||
|         x_needs_read := co.needsMemRead(io.alloc_req.bits.xact_init.x_type, UFix(0)) | ||||
|         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 | ||||
|         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) {     | ||||
|         doMemReqRead(io.mem_req_cmd, x_needs_read) | ||||
|       } . 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) { | ||||
| @@ -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 tiles = Vec(ntiles) { new ioTileLink() }.flip | ||||
|     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 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 | ||||
|   io.mem.req_cmd.valid   := x_init.valid && !(is_write && io.mem.resp.valid) | ||||
|   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 | ||||
|  | ||||
|   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.global_xact_id := UFix(0) // don't care | ||||
|   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 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.valid := Bool(false) | ||||
|     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.global_xact_id := mem_idx | ||||
|       rep.valid := Bool(true) | ||||
|     } . 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.global_xact_id := 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() } } | ||||
|     for( i <- 0 until NGLOBAL_XACTS) { | ||||
|       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 | ||||
|     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) | ||||
|     switch(abort_state_arr(j)) { | ||||
|       is(s_idle) { | ||||
|         when(want_to_abort_arr(j)) { | ||||
|           when(hasData(x_init.bits)) { | ||||
|           when(co.messageHasData(x_init.bits)) { | ||||
|             abort_state_arr(j) := s_abort_drain | ||||
|           } . otherwise { | ||||
|             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) | ||||
|     val pop_x_inits = trackerList.map(_.io.pop_x_init(j).toBool) | ||||
|     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.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))(_||_) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user