Cleaned up uncore and coherence interface. Removed defunct broadcast hub. Trait-ified tilelink bundle components. Added generalized mem arbiter.
This commit is contained in:
		| @@ -34,9 +34,7 @@ abstract class CoherencePolicy { | |||||||
|   def getVoluntaryWriteback(addr: UFix, client_id: UFix, master_id: UFix): Release |   def getVoluntaryWriteback(addr: UFix, client_id: UFix, master_id: UFix): Release | ||||||
|   def newRelease (incoming: Probe, state: UFix, id: UFix): Release |   def newRelease (incoming: Probe, state: UFix, id: UFix): Release | ||||||
|  |  | ||||||
|   def messageHasData (rel: Release): Bool |   def messageHasData (rel: SourcedMessage): Bool | ||||||
|   def messageHasData (acq: Acquire): Bool |  | ||||||
|   def messageHasData (grant: Grant): Bool |  | ||||||
|   def messageUpdatesDataArray (reply: Grant): Bool |   def messageUpdatesDataArray (reply: Grant): Bool | ||||||
|   def messageIsUncached(acq: Acquire): Bool |   def messageIsUncached(acq: Acquire): Bool | ||||||
|  |  | ||||||
| @@ -46,8 +44,8 @@ abstract class CoherencePolicy { | |||||||
|   def getGrantType(a_type: UFix, count: UFix): Bits |   def getGrantType(a_type: UFix, count: UFix): Bits | ||||||
|   def getGrantType(rel: Release, count: UFix): Bits |   def getGrantType(rel: Release, count: UFix): Bits | ||||||
|   def getProbeType(a_type: UFix, global_state: UFix): UFix |   def getProbeType(a_type: UFix, global_state: UFix): UFix | ||||||
|   def needsMemRead(a_type: UFix, global_state: UFix): Bool |   def needsOuterRead(a_type: UFix, global_state: UFix): Bool | ||||||
|   def needsMemWrite(a_type: UFix, global_state: UFix): Bool |   def needsOuterWrite(a_type: UFix, global_state: UFix): Bool | ||||||
|   def needsAckReply(a_type: UFix, global_state: UFix): Bool |   def needsAckReply(a_type: UFix, global_state: UFix): Bool | ||||||
|   def needsSelfProbe(acq: Acquire): Bool |   def needsSelfProbe(acq: Acquire): Bool | ||||||
|   def requiresAck(grant: Grant): Bool |   def requiresAck(grant: Grant): Bool | ||||||
| @@ -72,13 +70,12 @@ abstract class IncoherentPolicy extends CoherencePolicy { | |||||||
|   // UNIMPLEMENTED |   // UNIMPLEMENTED | ||||||
|   def newStateOnProbe(incoming: Probe, state: UFix): Bits = state |   def newStateOnProbe(incoming: Probe, state: UFix): Bits = state | ||||||
|   def newRelease (incoming: Probe, state: UFix, id: UFix): Release = Release( UFix(0), UFix(0), UFix(0), UFix(0)) |   def newRelease (incoming: Probe, state: UFix, id: UFix): Release = Release( UFix(0), UFix(0), UFix(0), UFix(0)) | ||||||
|   def messageHasData (rel: Release) = Bool(false) |  | ||||||
|   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: UFix, count: UFix): Bits = Bits(0) | ||||||
|   def getGrantType(rel: Release, count: UFix): Bits = Bits(0) |   def getGrantType(rel: Release, count: UFix): Bits = Bits(0) | ||||||
|   def getProbeType(a_type: UFix, global_state: UFix): UFix = UFix(0) |   def getProbeType(a_type: UFix, global_state: UFix): UFix = UFix(0) | ||||||
|   def needsMemRead(a_type: UFix, global_state: UFix): Bool = Bool(false) |   def needsOuterRead(a_type: UFix, global_state: UFix): Bool = Bool(false) | ||||||
|   def needsMemWrite(a_type: UFix, global_state: UFix): Bool = Bool(false) |   def needsOuterWrite(a_type: UFix, global_state: UFix): Bool = Bool(false) | ||||||
|   def needsAckReply(a_type: UFix, global_state: UFix): Bool = Bool(false) |   def needsAckReply(a_type: UFix, global_state: UFix): 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) | ||||||
| @@ -134,8 +131,12 @@ class ThreeStateIncoherence extends IncoherentPolicy { | |||||||
|   def getReleaseTypeOnCacheControl(cmd: Bits): Bits = releaseVoluntaryInvalidateData // TODO |   def getReleaseTypeOnCacheControl(cmd: Bits): Bits = releaseVoluntaryInvalidateData // TODO | ||||||
|   def getReleaseTypeOnVoluntaryWriteback(): Bits = releaseVoluntaryInvalidateData |   def getReleaseTypeOnVoluntaryWriteback(): Bits = releaseVoluntaryInvalidateData | ||||||
|  |  | ||||||
|   def messageHasData (acq: Acquire): Bool = uFixListContains(hasDataAcquireTypeList, acq.a_type) |   def messageHasData( msg: SourcedMessage ) = msg match { | ||||||
|   def messageHasData (grant: Grant): Bool = uFixListContains(hasDataGrantTypeList, grant.g_type)  |     case acq: Acquire => uFixListContains(hasDataAcquireTypeList, acq.a_type) | ||||||
|  |     case grant: Grant => uFixListContains(hasDataGrantTypeList, grant.g_type)  | ||||||
|  |     case rel: Release => 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 = uFixListContains(uncachedAcquireTypeList, acq.a_type) | ||||||
| } | } | ||||||
| @@ -221,9 +222,12 @@ class MICoherence extends CoherencePolicyWithUncached { | |||||||
|     Release( Mux(needsWriteback(state), with_data, without_data), incoming.addr, id, incoming.master_xact_id) |     Release( Mux(needsWriteback(state), with_data, without_data), incoming.addr, id, incoming.master_xact_id) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   def messageHasData (rel: Release): Bool = uFixListContains(hasDataReleaseTypeList, rel.r_type)  |   def messageHasData(msg: SourcedMessage) = msg match { | ||||||
|   def messageHasData (acq: Acquire): Bool = uFixListContains(hasDataAcquireTypeList, acq.a_type) |     case acq: Acquire => uFixListContains(hasDataAcquireTypeList, acq.a_type) | ||||||
|   def messageHasData (grant: Grant): Bool = uFixListContains(hasDataGrantTypeList, grant.g_type)  |     case grant: Grant => uFixListContains(hasDataGrantTypeList, grant.g_type)  | ||||||
|  |     case rel: Release => uFixListContains(hasDataReleaseTypeList, rel.r_type)  | ||||||
|  |     case _ => Bool(false) | ||||||
|  |   } | ||||||
|   def messageUpdatesDataArray (reply: Grant): Bool = { |   def messageUpdatesDataArray (reply: Grant): Bool = { | ||||||
|     (reply.g_type === grantReadExclusive) |     (reply.g_type === grantReadExclusive) | ||||||
|   } |   } | ||||||
| @@ -259,10 +263,10 @@ class MICoherence extends CoherencePolicyWithUncached { | |||||||
|     )) |     )) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   def needsMemRead(a_type: UFix, global_state: UFix): Bool = { |   def needsOuterRead(a_type: UFix, global_state: UFix): Bool = { | ||||||
|       (a_type != acquireWriteUncached) |       (a_type != acquireWriteUncached) | ||||||
|   } |   } | ||||||
|   def needsMemWrite(a_type: UFix, global_state: UFix): Bool = { |   def needsOuterWrite(a_type: UFix, global_state: UFix): Bool = { | ||||||
|       (a_type === acquireWriteUncached) |       (a_type === acquireWriteUncached) | ||||||
|   } |   } | ||||||
|   def needsAckReply(a_type: UFix, global_state: UFix): Bool = { |   def needsAckReply(a_type: UFix, global_state: UFix): Bool = { | ||||||
| @@ -373,9 +377,12 @@ class MEICoherence extends CoherencePolicyWithUncached { | |||||||
|     Release( Mux(needsWriteback(state), with_data, without_data), incoming.addr, id, incoming.master_xact_id) |     Release( Mux(needsWriteback(state), with_data, without_data), incoming.addr, id, incoming.master_xact_id) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   def messageHasData (rel: Release): Bool = uFixListContains(hasDataReleaseTypeList, rel.r_type)  |   def messageHasData(msg: SourcedMessage) = msg match { | ||||||
|   def messageHasData (acq: Acquire): Bool = uFixListContains(hasDataAcquireTypeList, acq.a_type) |     case acq: Acquire => uFixListContains(hasDataAcquireTypeList, acq.a_type) | ||||||
|   def messageHasData (grant: Grant): Bool = uFixListContains(hasDataGrantTypeList, grant.g_type)  |     case grant: Grant => uFixListContains(hasDataGrantTypeList, grant.g_type)  | ||||||
|  |     case rel: Release => uFixListContains(hasDataReleaseTypeList, rel.r_type)  | ||||||
|  |     case _ => Bool(false) | ||||||
|  |   } | ||||||
|   def messageUpdatesDataArray (reply: Grant): Bool = { |   def messageUpdatesDataArray (reply: Grant): Bool = { | ||||||
|     (reply.g_type === grantReadExclusive) |     (reply.g_type === grantReadExclusive) | ||||||
|   } |   } | ||||||
| @@ -413,10 +420,10 @@ class MEICoherence extends CoherencePolicyWithUncached { | |||||||
|     )) |     )) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   def needsMemRead(a_type: UFix, global_state: UFix): Bool = { |   def needsOuterRead(a_type: UFix, global_state: UFix): Bool = { | ||||||
|       (a_type != acquireWriteUncached) |       (a_type != acquireWriteUncached) | ||||||
|   } |   } | ||||||
|   def needsMemWrite(a_type: UFix, global_state: UFix): Bool = { |   def needsOuterWrite(a_type: UFix, global_state: UFix): Bool = { | ||||||
|       (a_type === acquireWriteUncached) |       (a_type === acquireWriteUncached) | ||||||
|   } |   } | ||||||
|   def needsAckReply(a_type: UFix, global_state: UFix): Bool = { |   def needsAckReply(a_type: UFix, global_state: UFix): Bool = { | ||||||
| @@ -534,9 +541,12 @@ class MSICoherence extends CoherencePolicyWithUncached { | |||||||
|     Release( Mux(needsWriteback(state), with_data, without_data), incoming.addr, id, incoming.master_xact_id) |     Release( Mux(needsWriteback(state), with_data, without_data), incoming.addr, id, incoming.master_xact_id) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   def messageHasData (rel: Release): Bool = uFixListContains(hasDataReleaseTypeList, rel.r_type)  |   def messageHasData(msg: SourcedMessage) = msg match { | ||||||
|   def messageHasData (acq: Acquire): Bool = uFixListContains(hasDataAcquireTypeList, acq.a_type) |     case acq: Acquire => uFixListContains(hasDataAcquireTypeList, acq.a_type) | ||||||
|   def messageHasData (grant: Grant): Bool = uFixListContains(hasDataGrantTypeList, grant.g_type)  |     case grant: Grant => uFixListContains(hasDataGrantTypeList, grant.g_type)  | ||||||
|  |     case rel: Release => uFixListContains(hasDataReleaseTypeList, rel.r_type)  | ||||||
|  |     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) | ||||||
|   } |   } | ||||||
| @@ -571,10 +581,10 @@ class MSICoherence extends CoherencePolicyWithUncached { | |||||||
|     )) |     )) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   def needsMemRead(a_type: UFix, global_state: UFix): Bool = { |   def needsOuterRead(a_type: UFix, global_state: UFix): Bool = { | ||||||
|       (a_type != acquireWriteUncached) |       (a_type != acquireWriteUncached) | ||||||
|   } |   } | ||||||
|   def needsMemWrite(a_type: UFix, global_state: UFix): Bool = { |   def needsOuterWrite(a_type: UFix, global_state: UFix): Bool = { | ||||||
|       (a_type === acquireWriteUncached) |       (a_type === acquireWriteUncached) | ||||||
|   } |   } | ||||||
|   def needsAckReply(a_type: UFix, global_state: UFix): Bool = { |   def needsAckReply(a_type: UFix, global_state: UFix): Bool = { | ||||||
| @@ -693,9 +703,12 @@ class MESICoherence extends CoherencePolicyWithUncached { | |||||||
|     Release( Mux(needsWriteback(state), with_data, without_data), incoming.addr, id, incoming.master_xact_id) |     Release( Mux(needsWriteback(state), with_data, without_data), incoming.addr, id, incoming.master_xact_id) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   def messageHasData (rel: Release): Bool = uFixListContains(hasDataReleaseTypeList, rel.r_type)  |   def messageHasData(msg: SourcedMessage) = msg match { | ||||||
|   def messageHasData (acq: Acquire): Bool = uFixListContains(hasDataAcquireTypeList, acq.a_type) |     case acq: Acquire => uFixListContains(hasDataAcquireTypeList, acq.a_type) | ||||||
|   def messageHasData (grant: Grant): Bool = uFixListContains(hasDataGrantTypeList, grant.g_type)  |     case grant: Grant => uFixListContains(hasDataGrantTypeList, grant.g_type)  | ||||||
|  |     case rel: Release => uFixListContains(hasDataReleaseTypeList, rel.r_type)  | ||||||
|  |     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) | ||||||
|   } |   } | ||||||
| @@ -733,10 +746,10 @@ class MESICoherence extends CoherencePolicyWithUncached { | |||||||
|     )) |     )) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   def needsMemRead(a_type: UFix, global_state: UFix): Bool = { |   def needsOuterRead(a_type: UFix, global_state: UFix): Bool = { | ||||||
|       (a_type != acquireWriteUncached) |       (a_type != acquireWriteUncached) | ||||||
|   } |   } | ||||||
|   def needsMemWrite(a_type: UFix, global_state: UFix): Bool = { |   def needsOuterWrite(a_type: UFix, global_state: UFix): Bool = { | ||||||
|       (a_type === acquireWriteUncached) |       (a_type === acquireWriteUncached) | ||||||
|   } |   } | ||||||
|   def needsAckReply(a_type: UFix, global_state: UFix): Bool = { |   def needsAckReply(a_type: UFix, global_state: UFix): Bool = { | ||||||
| @@ -871,9 +884,12 @@ class MigratoryCoherence extends CoherencePolicyWithUncached { | |||||||
|     Release( Mux(needsWriteback(state), with_data, without_data), incoming.addr, id, incoming.master_xact_id) |     Release( Mux(needsWriteback(state), with_data, without_data), incoming.addr, id, incoming.master_xact_id) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   def messageHasData (acq: Acquire): Bool = uFixListContains(hasDataAcquireTypeList, acq.a_type) |   def messageHasData(msg: SourcedMessage) = msg match { | ||||||
|   def messageHasData (rel: Release): Bool = uFixListContains(hasDataReleaseTypeList, rel.r_type)  |     case acq: Acquire => uFixListContains(hasDataAcquireTypeList, acq.a_type) | ||||||
|   def messageHasData (grant: Grant): Bool = uFixListContains(hasDataGrantTypeList, grant.g_type)  |     case grant: Grant => uFixListContains(hasDataGrantTypeList, grant.g_type)  | ||||||
|  |     case rel: Release => uFixListContains(hasDataReleaseTypeList, rel.r_type)  | ||||||
|  |     case _ => Bool(false) | ||||||
|  |   } | ||||||
|   def messageUpdatesDataArray (reply: Grant): Bool = { |   def messageUpdatesDataArray (reply: Grant): Bool = { | ||||||
|     uFixListContains(List(grantReadShared, grantReadExclusive, grantReadMigratory), reply.g_type) |     uFixListContains(List(grantReadShared, grantReadExclusive, grantReadMigratory), reply.g_type) | ||||||
|   } |   } | ||||||
| @@ -913,10 +929,10 @@ class MigratoryCoherence extends CoherencePolicyWithUncached { | |||||||
|     )) |     )) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   def needsMemRead(a_type: UFix, global_state: UFix): Bool = { |   def needsOuterRead(a_type: UFix, global_state: UFix): Bool = { | ||||||
|       (a_type != acquireWriteUncached && a_type != acquireInvalidateOthers) |       (a_type != acquireWriteUncached && a_type != acquireInvalidateOthers) | ||||||
|   } |   } | ||||||
|   def needsMemWrite(a_type: UFix, global_state: UFix): Bool = { |   def needsOuterWrite(a_type: UFix, global_state: UFix): 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: UFix, global_state: UFix): Bool = { | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ abstract trait CoherenceConfigConstants { | |||||||
|  |  | ||||||
| trait UncoreConstants { | trait UncoreConstants { | ||||||
|   val NGLOBAL_XACTS = 8 |   val NGLOBAL_XACTS = 8 | ||||||
|   val MASTER_XACT_ID_BITS = log2Up(NGLOBAL_XACTS) |   val MASTER_XACT_ID_MAX_BITS = log2Up(NGLOBAL_XACTS) | ||||||
|   val CACHE_DATA_SIZE_IN_BYTES = 1 << 6  |   val CACHE_DATA_SIZE_IN_BYTES = 1 << 6  | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -29,7 +29,7 @@ trait TileLinkTypeConstants { | |||||||
| trait TileLinkSizeConstants extends  | trait TileLinkSizeConstants extends  | ||||||
|   TileLinkTypeConstants |   TileLinkTypeConstants | ||||||
| { | { | ||||||
|   val CLIENT_XACT_ID_BITS = 5 |   val CLIENT_XACT_ID_MAX_BITS = 10 | ||||||
|   val ACQUIRE_WRITE_MASK_BITS = 6 |   val ACQUIRE_WRITE_MASK_BITS = 6 | ||||||
|   val ACQUIRE_SUBWORD_ADDR_BITS = 3 |   val ACQUIRE_SUBWORD_ADDR_BITS = 3 | ||||||
|   val ACQUIRE_ATOMIC_OP_BITS = 4 |   val ACQUIRE_ATOMIC_OP_BITS = 4 | ||||||
| @@ -72,7 +72,7 @@ trait MemoryInterfaceConstants extends | |||||||
|   UncoreConstants with  |   UncoreConstants with  | ||||||
|   TileLinkSizeConstants  |   TileLinkSizeConstants  | ||||||
| { | { | ||||||
|   val MEM_TAG_BITS = max(CLIENT_XACT_ID_BITS, MASTER_XACT_ID_BITS) |   val MEM_TAG_BITS = max(CLIENT_XACT_ID_MAX_BITS, MASTER_XACT_ID_MAX_BITS) | ||||||
|   val MEM_DATA_BITS = 128 |   val MEM_DATA_BITS = 128 | ||||||
|   val REFILL_CYCLES = CACHE_DATA_SIZE_IN_BYTES*8/MEM_DATA_BITS |   val REFILL_CYCLES = CACHE_DATA_SIZE_IN_BYTES*8/MEM_DATA_BITS | ||||||
| } | } | ||||||
|   | |||||||
| @@ -40,8 +40,6 @@ class BasicCrossbar[T <: Data]()(data: => T)(implicit conf: PhysicalNetworkConfi | |||||||
|       rdy := arb.ready && (in.bits.header.dst === UFix(i)) |       rdy := arb.ready && (in.bits.header.dst === UFix(i)) | ||||||
|     }} |     }} | ||||||
|     out <> rrarb.io.out |     out <> rrarb.io.out | ||||||
|     //out.bits.header.src := rrarb.io.chosen.toUFix |  | ||||||
|     //out.bits.header.dst := UFix(i) |  | ||||||
|   }} |   }} | ||||||
|   for(i <- 0 until conf.nEndpoints) { |   for(i <- 0 until conf.nEndpoints) { | ||||||
|     io.in(i).ready := rdyVecs.map(r => r(i)).reduceLeft(_||_) |     io.in(i).ready := rdyVecs.map(r => r(i)).reduceLeft(_||_) | ||||||
| @@ -62,21 +60,23 @@ class LogicalHeader(implicit conf: LogicalNetworkConfiguration) extends Bundle { | |||||||
| } | } | ||||||
|  |  | ||||||
| object FIFOedLogicalNetworkIOWrapper { | object FIFOedLogicalNetworkIOWrapper { | ||||||
|   def apply[T <: Data](in: FIFOIO[T])(implicit conf: LogicalNetworkConfiguration) = { |   def apply[T <: Data](in: FIFOIO[T], src: UFix = UFix(0), dst: UFix = UFix(0))(implicit conf: LogicalNetworkConfiguration) = { | ||||||
|     val shim = (new FIFOedLogicalNetworkIOWrapper){ in.bits.clone } |     val shim = (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]()(data: => T)(implicit lconf: LogicalNetworkConfiguration) extends Component { | class FIFOedLogicalNetworkIOWrapper[T <: Data](src: UFix, dst: UFix)(data: => T)(implicit lconf: LogicalNetworkConfiguration) extends Component { | ||||||
|   val io = new Bundle { |   val io = new Bundle { | ||||||
|     val in = (new FIFOIO){ data }.flip |     val in = (new FIFOIO){ data }.flip | ||||||
|     val out = (new FIFOIO){(new LogicalNetworkIO){ data }}  |     val out = (new FIFOIO){(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 | ||||||
|  |   io.out.bits.header.dst := dst | ||||||
|  |   io.out.bits.header.src := src | ||||||
|   io.in.ready := io.out.ready |   io.in.ready := io.out.ready | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -3,20 +3,30 @@ package uncore | |||||||
| import Chisel._ | import Chisel._ | ||||||
| import Constants._ | import Constants._ | ||||||
|  |  | ||||||
| class PhysicalAddress extends Bundle { | trait HasPhysicalAddress extends Bundle { | ||||||
|   val addr = UFix(width = PADDR_BITS - OFFSET_BITS) |   val addr = UFix(width = PADDR_BITS - OFFSET_BITS) | ||||||
| } | } | ||||||
|  |  | ||||||
| class MemData extends Bundle { | trait HasClientTransactionId extends Bundle { | ||||||
|  |   val client_xact_id = Bits(width = CLIENT_XACT_ID_MAX_BITS) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | trait HasMasterTransactionId extends Bundle { | ||||||
|  |   val master_xact_id = Bits(width = MASTER_XACT_ID_MAX_BITS) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | trait HasMemData extends Bundle { | ||||||
|   val data = Bits(width = MEM_DATA_BITS) |   val data = Bits(width = MEM_DATA_BITS) | ||||||
| } | } | ||||||
|  |  | ||||||
| class MemReqCmd extends PhysicalAddress { | class MemData extends Bundle with HasMemData | ||||||
|  |  | ||||||
|  | class MemReqCmd extends Bundle with HasPhysicalAddress { | ||||||
|   val rw = Bool() |   val rw = Bool() | ||||||
|   val tag = Bits(width = MEM_TAG_BITS) |   val tag = Bits(width = MEM_TAG_BITS) | ||||||
| } | } | ||||||
|  |  | ||||||
| class MemResp extends MemData { | class MemResp extends Bundle with HasMemData { | ||||||
|   val tag = Bits(width = MEM_TAG_BITS) |   val tag = Bits(width = MEM_TAG_BITS) | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -32,9 +42,12 @@ class ioMemPipe extends Bundle { | |||||||
|   val resp     = (new PipeIO) { new MemResp() }.flip |   val resp     = (new PipeIO) { new MemResp() }.flip | ||||||
| } | } | ||||||
|  |  | ||||||
| class Acquire extends PhysicalAddress { | trait SourcedMessage extends Bundle | ||||||
|  | trait ClientSourcedMessage extends SourcedMessage | ||||||
|  | trait MasterSourcedMessage extends SourcedMessage | ||||||
|  |  | ||||||
|  | class Acquire extends ClientSourcedMessage with HasPhysicalAddress with HasClientTransactionId { | ||||||
|   val a_type = Bits(width = ACQUIRE_TYPE_MAX_BITS) |   val a_type = Bits(width = ACQUIRE_TYPE_MAX_BITS) | ||||||
|   val client_xact_id = Bits(width = CLIENT_XACT_ID_BITS) |  | ||||||
|   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) | ||||||
| @@ -47,6 +60,9 @@ object Acquire | |||||||
|     acq.a_type := a_type |     acq.a_type := a_type | ||||||
|     acq.addr := addr |     acq.addr := addr | ||||||
|     acq.client_xact_id := client_xact_id |     acq.client_xact_id := client_xact_id | ||||||
|  |     acq.write_mask := Bits(0, width = ACQUIRE_WRITE_MASK_BITS) | ||||||
|  |     acq.subword_addr := Bits(0, width = ACQUIRE_SUBWORD_ADDR_BITS) | ||||||
|  |     acq.atomic_opcode := Bits(0, width = ACQUIRE_ATOMIC_OP_BITS) | ||||||
|     acq |     acq | ||||||
|   } |   } | ||||||
|   def apply(a_type: Bits, addr: UFix, client_xact_id: UFix, write_mask: Bits) = { |   def apply(a_type: Bits, addr: UFix, client_xact_id: UFix, write_mask: Bits) = { | ||||||
| @@ -55,6 +71,8 @@ object Acquire | |||||||
|     acq.addr := addr |     acq.addr := addr | ||||||
|     acq.client_xact_id := client_xact_id |     acq.client_xact_id := client_xact_id | ||||||
|     acq.write_mask := write_mask |     acq.write_mask := write_mask | ||||||
|  |     acq.subword_addr := Bits(0, width = ACQUIRE_SUBWORD_ADDR_BITS) | ||||||
|  |     acq.atomic_opcode := Bits(0, width = ACQUIRE_ATOMIC_OP_BITS) | ||||||
|     acq |     acq | ||||||
|   } |   } | ||||||
|   def apply(a_type: Bits, addr: UFix, client_xact_id: UFix, subword_addr: UFix, atomic_opcode: UFix) = { |   def apply(a_type: Bits, addr: UFix, client_xact_id: UFix, subword_addr: UFix, atomic_opcode: UFix) = { | ||||||
| @@ -64,15 +82,15 @@ object Acquire | |||||||
|     acq.client_xact_id := client_xact_id |     acq.client_xact_id := client_xact_id | ||||||
|     acq.subword_addr := subword_addr |     acq.subword_addr := subword_addr | ||||||
|     acq.atomic_opcode := atomic_opcode |     acq.atomic_opcode := atomic_opcode | ||||||
|  |     acq.write_mask := Bits(0, width = ACQUIRE_WRITE_MASK_BITS) | ||||||
|     acq |     acq | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| class AcquireData extends MemData | class AcquireData extends ClientSourcedMessage with HasMemData | ||||||
|  |  | ||||||
| class Probe extends PhysicalAddress { | class Probe extends MasterSourcedMessage with HasPhysicalAddress with HasMasterTransactionId { | ||||||
|   val p_type = Bits(width = PROBE_TYPE_MAX_BITS) |   val p_type = Bits(width = PROBE_TYPE_MAX_BITS) | ||||||
|   val master_xact_id = Bits(width = MASTER_XACT_ID_BITS) |  | ||||||
| } | } | ||||||
|  |  | ||||||
| object Release | object Release | ||||||
| @@ -86,35 +104,105 @@ object Release | |||||||
|     rel |     rel | ||||||
|   } |   } | ||||||
| } | } | ||||||
| class Release extends PhysicalAddress { | class Release extends ClientSourcedMessage with HasPhysicalAddress with HasClientTransactionId with HasMasterTransactionId { | ||||||
|   val r_type = Bits(width = RELEASE_TYPE_MAX_BITS) |   val r_type = Bits(width = RELEASE_TYPE_MAX_BITS) | ||||||
|   val client_xact_id = Bits(width = CLIENT_XACT_ID_BITS) |  | ||||||
|   val master_xact_id = Bits(width = MASTER_XACT_ID_BITS) |  | ||||||
| } | } | ||||||
|  |  | ||||||
| class ReleaseData extends MemData | class ReleaseData extends ClientSourcedMessage with HasMemData | ||||||
|  |  | ||||||
| class Grant extends MemData { | class Grant extends MasterSourcedMessage with HasMemData with HasClientTransactionId with HasMasterTransactionId { | ||||||
|   val g_type = Bits(width = GRANT_TYPE_MAX_BITS) |   val g_type = Bits(width = GRANT_TYPE_MAX_BITS) | ||||||
|   val client_xact_id = Bits(width = CLIENT_XACT_ID_BITS) |  | ||||||
|   val master_xact_id = Bits(width = MASTER_XACT_ID_BITS) |  | ||||||
| } | } | ||||||
|  |  | ||||||
| class GrantAck extends Bundle { | class GrantAck extends ClientSourcedMessage with HasMasterTransactionId  | ||||||
|   val master_xact_id = Bits(width = MASTER_XACT_ID_BITS) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| abstract class DirectionalFIFOIO[T <: Data]()(data: => T) extends FIFOIO()(data) | abstract class DirectionalFIFOIO[T <: Data]()(data: => T) extends FIFOIO()(data) | ||||||
| class ClientSourcedIO[T <: Data]()(data: => T)  extends DirectionalFIFOIO()(data)  | class ClientSourcedIO[T <: Data]()(data: => T)  extends DirectionalFIFOIO()(data)  | ||||||
| class MasterSourcedIO[T <: Data]()(data: => T) extends DirectionalFIFOIO()(data) {flip()} | class MasterSourcedIO[T <: Data]()(data: => T) extends DirectionalFIFOIO()(data) {flip()} | ||||||
|  |  | ||||||
| class TileLinkIO(implicit conf: LogicalNetworkConfiguration) extends Bundle {  | class UncachedTileLinkIO(implicit conf: LogicalNetworkConfiguration) extends Bundle { | ||||||
|   val acquire      = (new ClientSourcedIO){(new LogicalNetworkIO){new Acquire }} |   val acquire      = (new ClientSourcedIO){(new LogicalNetworkIO){new Acquire }} | ||||||
|   val acquire_data = (new ClientSourcedIO){(new LogicalNetworkIO){new AcquireData }} |   val acquire_data = (new ClientSourcedIO){(new LogicalNetworkIO){new AcquireData }} | ||||||
|  |   val grant       = (new MasterSourcedIO) {(new LogicalNetworkIO){new Grant }} | ||||||
|  |   val grant_ack    = (new ClientSourcedIO){(new LogicalNetworkIO){new GrantAck }} | ||||||
|  |   override def clone = { new UncachedTileLinkIO().asInstanceOf[this.type] } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class TileLinkIO(implicit conf: LogicalNetworkConfiguration) extends UncachedTileLinkIO()(conf) {  | ||||||
|   val probe        = (new MasterSourcedIO){(new LogicalNetworkIO){new Probe }} |   val probe        = (new MasterSourcedIO){(new LogicalNetworkIO){new Probe }} | ||||||
|   val release      = (new ClientSourcedIO){(new LogicalNetworkIO){new Release }} |   val release      = (new ClientSourcedIO){(new LogicalNetworkIO){new Release }} | ||||||
|   val release_data = (new ClientSourcedIO){(new LogicalNetworkIO){new ReleaseData }} |   val release_data = (new ClientSourcedIO){(new LogicalNetworkIO){new ReleaseData }} | ||||||
|   val grant        = (new MasterSourcedIO){(new LogicalNetworkIO){new Grant }} |  | ||||||
|   val grant_ack    = (new ClientSourcedIO){(new LogicalNetworkIO){new GrantAck }} |  | ||||||
|   override def clone = { new TileLinkIO().asInstanceOf[this.type] } |   override def clone = { new TileLinkIO().asInstanceOf[this.type] } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | object UncachedTileLinkIOArbiterShim { | ||||||
|  |   def apply[T <: HasClientTransactionId](in: ClientSourcedIO[LogicalNetworkIO[T]], id: Int, max: Int)(implicit lconf: LogicalNetworkConfiguration) = { | ||||||
|  |     val shim = (new UncachedTileLinkIOArbiterShim(id, max)){in.bits.payload.clone} | ||||||
|  |     shim.io.in <> in | ||||||
|  |     shim.io.out | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | class UncachedTileLinkIOArbiterShim[T <: HasClientTransactionId](id: Int, max: Int)(data: => T)(implicit lconf: LogicalNetworkConfiguration) extends Component { | ||||||
|  |   val io = new Bundle { | ||||||
|  |     val in  = (new ClientSourcedIO){(new LogicalNetworkIO){ data }}.flip | ||||||
|  |     val out = (new ClientSourcedIO){(new LogicalNetworkIO){ data }} | ||||||
|  |   } | ||||||
|  |   io.out.bits := io.in.bits  | ||||||
|  |   io.out.bits.payload.client_xact_id := Cat(io.in.bits.payload.client_xact_id, UFix(id, log2Up(max))) | ||||||
|  |   io.out.valid := io.in.valid | ||||||
|  |   io.in.ready := io.out.ready | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class UncachedTileLinkIOArbiter(n: Int)(implicit conf: LogicalNetworkConfiguration) extends Component { | ||||||
|  |   val io = new Bundle { | ||||||
|  |     val in = Vec(n) { new UncachedTileLinkIO }.flip | ||||||
|  |     val out = new UncachedTileLinkIO | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   val mem_cnt = Reg(resetVal = UFix(0, width = log2Up(REFILL_CYCLES))) | ||||||
|  |   val mem_cnt_next = mem_cnt + UFix(1) | ||||||
|  |   val locked = Reg(resetVal = Bool(false)) | ||||||
|  |   val lock_idx = Reg(resetVal = UFix(n)) | ||||||
|  |  | ||||||
|  |   when(io.out.acquire_data.valid && io.out.acquire_data.ready) { | ||||||
|  |     mem_cnt := mem_cnt_next | ||||||
|  |     when(!locked) { | ||||||
|  |       locked := Bool(true) | ||||||
|  |       lock_idx := Vec(io.in.map{ in => in.acquire_data.ready && in.acquire_data.valid}){Bool()}.indexWhere{i: Bool => i}  | ||||||
|  |     } | ||||||
|  |     when(mem_cnt_next === UFix(0)) { | ||||||
|  |       locked := Bool(false) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   val acqd_grant = ArbiterCtrl(io.in.map(_.acquire_data.valid)) | ||||||
|  |   (0 until n).map(i => io.in(i).acquire_data.ready := Mux(locked, UFix(i) === lock_idx, acqd_grant(i)) && io.out.acquire_data.ready) | ||||||
|  |   var acqd_bits = io.in(n-1).acquire_data.bits | ||||||
|  |   for (i <- n-2 to 0 by -1) { | ||||||
|  |     acqd_bits = Mux(io.in(i).acquire_data.valid, io.in(i).acquire_data.bits, acqd_bits) | ||||||
|  |   } | ||||||
|  |   val locked_req = io.in(lock_idx).acquire_data | ||||||
|  |   io.out.acquire_data.bits := Mux(locked, locked_req.bits, acqd_bits) | ||||||
|  |   io.out.acquire_data.valid := Mux(locked, locked_req.valid, io.in.map(_.acquire_data.valid).reduce(_||_)) | ||||||
|  |  | ||||||
|  |   val acq_arb = (new Arbiter(n)){ (new LogicalNetworkIO){new Acquire} } | ||||||
|  |   io.out.acquire <> acq_arb.io.out | ||||||
|  |   io.in.map(_.acquire).zipWithIndex.map{ case(acq, id) => UncachedTileLinkIOArbiterShim(acq, id, n) }.zip(acq_arb.io.in).map{ case (req, arb) => req <> arb} | ||||||
|  |  | ||||||
|  |   val grant_ack_arb = (new Arbiter(n)){ (new LogicalNetworkIO){new GrantAck} } | ||||||
|  |   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 } | ||||||
|  |  | ||||||
|  |   io.out.grant.ready := Bool(false) | ||||||
|  |   for (i <- 0 until n) { | ||||||
|  |     val tag = io.out.grant.bits.payload.client_xact_id | ||||||
|  |     io.in(i).grant.valid := Bool(false) | ||||||
|  |     when (tag(log2Up(n)-1,0) === UFix(i)) { | ||||||
|  |       io.in(i).grant.valid := io.out.grant.valid | ||||||
|  |       io.out.grant.ready := io.in(i).grant.ready | ||||||
|  |     } | ||||||
|  |     io.in(i).grant.bits := io.out.grant.bits | ||||||
|  |     io.in(i).grant.bits.payload.client_xact_id := tag >> UFix(log2Up(n)) | ||||||
|  |   } | ||||||
|  | } | ||||||
|   | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user