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 newRelease (incoming: Probe, state: UFix, id: UFix): Release | ||||
|  | ||||
|   def messageHasData (rel: Release): Bool | ||||
|   def messageHasData (acq: Acquire): Bool | ||||
|   def messageHasData (grant: Grant): Bool | ||||
|   def messageHasData (rel: SourcedMessage): Bool | ||||
|   def messageUpdatesDataArray (reply: Grant): Bool | ||||
|   def messageIsUncached(acq: Acquire): Bool | ||||
|  | ||||
| @@ -46,8 +44,8 @@ abstract class CoherencePolicy { | ||||
|   def getGrantType(a_type: UFix, count: UFix): Bits | ||||
|   def getGrantType(rel: Release, count: UFix): Bits | ||||
|   def getProbeType(a_type: UFix, global_state: UFix): UFix | ||||
|   def needsMemRead(a_type: UFix, global_state: UFix): Bool | ||||
|   def needsMemWrite(a_type: UFix, global_state: UFix): Bool | ||||
|   def needsOuterRead(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 needsSelfProbe(acq: Acquire): Bool | ||||
|   def requiresAck(grant: Grant): Bool | ||||
| @@ -72,13 +70,12 @@ abstract class IncoherentPolicy extends CoherencePolicy { | ||||
|   // UNIMPLEMENTED | ||||
|   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 messageHasData (rel: Release) = Bool(false) | ||||
|   def isCoherenceConflict(addr1: Bits, addr2: Bits): Bool = Bool(false) | ||||
|   def getGrantType(a_type: UFix, 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 needsMemRead(a_type: UFix, global_state: UFix): Bool = Bool(false) | ||||
|   def needsMemWrite(a_type: UFix, global_state: UFix): Bool = Bool(false) | ||||
|   def needsOuterRead(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 needsSelfProbe(acq: Acquire) = Bool(false) | ||||
|   def requiresAck(grant: Grant) = Bool(true) | ||||
| @@ -134,8 +131,12 @@ class ThreeStateIncoherence extends IncoherentPolicy { | ||||
|   def getReleaseTypeOnCacheControl(cmd: Bits): Bits = releaseVoluntaryInvalidateData // TODO | ||||
|   def getReleaseTypeOnVoluntaryWriteback(): Bits = releaseVoluntaryInvalidateData | ||||
|  | ||||
|   def messageHasData (acq: Acquire): Bool = uFixListContains(hasDataAcquireTypeList, acq.a_type) | ||||
|   def messageHasData (grant: Grant): Bool = uFixListContains(hasDataGrantTypeList, grant.g_type)  | ||||
|   def messageHasData( msg: SourcedMessage ) = msg match { | ||||
|     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 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) | ||||
|   } | ||||
|  | ||||
|   def messageHasData (rel: Release): Bool = uFixListContains(hasDataReleaseTypeList, rel.r_type)  | ||||
|   def messageHasData (acq: Acquire): Bool = uFixListContains(hasDataAcquireTypeList, acq.a_type) | ||||
|   def messageHasData (grant: Grant): Bool = uFixListContains(hasDataGrantTypeList, grant.g_type)  | ||||
|   def messageHasData(msg: SourcedMessage) = msg match { | ||||
|     case acq: Acquire => uFixListContains(hasDataAcquireTypeList, acq.a_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 = { | ||||
|     (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) | ||||
|   } | ||||
|   def needsMemWrite(a_type: UFix, global_state: UFix): Bool = { | ||||
|   def needsOuterWrite(a_type: UFix, global_state: UFix): Bool = { | ||||
|       (a_type === acquireWriteUncached) | ||||
|   } | ||||
|   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) | ||||
|   } | ||||
|  | ||||
|   def messageHasData (rel: Release): Bool = uFixListContains(hasDataReleaseTypeList, rel.r_type)  | ||||
|   def messageHasData (acq: Acquire): Bool = uFixListContains(hasDataAcquireTypeList, acq.a_type) | ||||
|   def messageHasData (grant: Grant): Bool = uFixListContains(hasDataGrantTypeList, grant.g_type)  | ||||
|   def messageHasData(msg: SourcedMessage) = msg match { | ||||
|     case acq: Acquire => uFixListContains(hasDataAcquireTypeList, acq.a_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 = { | ||||
|     (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) | ||||
|   } | ||||
|   def needsMemWrite(a_type: UFix, global_state: UFix): Bool = { | ||||
|   def needsOuterWrite(a_type: UFix, global_state: UFix): Bool = { | ||||
|       (a_type === acquireWriteUncached) | ||||
|   } | ||||
|   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) | ||||
|   } | ||||
|  | ||||
|   def messageHasData (rel: Release): Bool = uFixListContains(hasDataReleaseTypeList, rel.r_type)  | ||||
|   def messageHasData (acq: Acquire): Bool = uFixListContains(hasDataAcquireTypeList, acq.a_type) | ||||
|   def messageHasData (grant: Grant): Bool = uFixListContains(hasDataGrantTypeList, grant.g_type)  | ||||
|   def messageHasData(msg: SourcedMessage) = msg match { | ||||
|     case acq: Acquire => uFixListContains(hasDataAcquireTypeList, acq.a_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 = { | ||||
|     (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) | ||||
|   } | ||||
|   def needsMemWrite(a_type: UFix, global_state: UFix): Bool = { | ||||
|   def needsOuterWrite(a_type: UFix, global_state: UFix): Bool = { | ||||
|       (a_type === acquireWriteUncached) | ||||
|   } | ||||
|   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) | ||||
|   } | ||||
|  | ||||
|   def messageHasData (rel: Release): Bool = uFixListContains(hasDataReleaseTypeList, rel.r_type)  | ||||
|   def messageHasData (acq: Acquire): Bool = uFixListContains(hasDataAcquireTypeList, acq.a_type) | ||||
|   def messageHasData (grant: Grant): Bool = uFixListContains(hasDataGrantTypeList, grant.g_type)  | ||||
|   def messageHasData(msg: SourcedMessage) = msg match { | ||||
|     case acq: Acquire => uFixListContains(hasDataAcquireTypeList, acq.a_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 = { | ||||
|     (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) | ||||
|   } | ||||
|   def needsMemWrite(a_type: UFix, global_state: UFix): Bool = { | ||||
|   def needsOuterWrite(a_type: UFix, global_state: UFix): Bool = { | ||||
|       (a_type === acquireWriteUncached) | ||||
|   } | ||||
|   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) | ||||
|   } | ||||
|  | ||||
|   def messageHasData (acq: Acquire): Bool = uFixListContains(hasDataAcquireTypeList, acq.a_type) | ||||
|   def messageHasData (rel: Release): Bool = uFixListContains(hasDataReleaseTypeList, rel.r_type)  | ||||
|   def messageHasData (grant: Grant): Bool = uFixListContains(hasDataGrantTypeList, grant.g_type)  | ||||
|   def messageHasData(msg: SourcedMessage) = msg match { | ||||
|     case acq: Acquire => uFixListContains(hasDataAcquireTypeList, acq.a_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 = { | ||||
|     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) | ||||
|   } | ||||
|   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) | ||||
|   } | ||||
|   def needsAckReply(a_type: UFix, global_state: UFix): Bool = { | ||||
|   | ||||
| @@ -11,7 +11,7 @@ abstract trait CoherenceConfigConstants { | ||||
|  | ||||
| trait UncoreConstants { | ||||
|   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  | ||||
| } | ||||
|  | ||||
| @@ -29,7 +29,7 @@ trait TileLinkTypeConstants { | ||||
| trait TileLinkSizeConstants extends  | ||||
|   TileLinkTypeConstants | ||||
| { | ||||
|   val CLIENT_XACT_ID_BITS = 5 | ||||
|   val CLIENT_XACT_ID_MAX_BITS = 10 | ||||
|   val ACQUIRE_WRITE_MASK_BITS = 6 | ||||
|   val ACQUIRE_SUBWORD_ADDR_BITS = 3 | ||||
|   val ACQUIRE_ATOMIC_OP_BITS = 4 | ||||
| @@ -72,7 +72,7 @@ trait MemoryInterfaceConstants extends | ||||
|   UncoreConstants with  | ||||
|   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 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)) | ||||
|     }} | ||||
|     out <> rrarb.io.out | ||||
|     //out.bits.header.src := rrarb.io.chosen.toUFix | ||||
|     //out.bits.header.dst := UFix(i) | ||||
|   }} | ||||
|   for(i <- 0 until conf.nEndpoints) { | ||||
|     io.in(i).ready := rdyVecs.map(r => r(i)).reduceLeft(_||_) | ||||
| @@ -62,21 +60,23 @@ class LogicalHeader(implicit conf: LogicalNetworkConfiguration) extends Bundle { | ||||
| } | ||||
|  | ||||
| object FIFOedLogicalNetworkIOWrapper { | ||||
|   def apply[T <: Data](in: FIFOIO[T])(implicit conf: LogicalNetworkConfiguration) = { | ||||
|     val shim = (new FIFOedLogicalNetworkIOWrapper){ in.bits.clone } | ||||
|   def apply[T <: Data](in: FIFOIO[T], src: UFix = UFix(0), dst: UFix = UFix(0))(implicit conf: LogicalNetworkConfiguration) = { | ||||
|     val shim = (new FIFOedLogicalNetworkIOWrapper(src, dst)){ in.bits.clone } | ||||
|     shim.io.in.valid := in.valid | ||||
|     shim.io.in.bits := in.bits | ||||
|     in.ready := shim.io.in.ready | ||||
|     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 in = (new FIFOIO){ data }.flip | ||||
|     val out = (new FIFOIO){(new LogicalNetworkIO){ data }}  | ||||
|   } | ||||
|   io.out.valid := io.in.valid | ||||
|   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 | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -3,20 +3,30 @@ package uncore | ||||
| import Chisel._ | ||||
| import Constants._ | ||||
|  | ||||
| class PhysicalAddress extends Bundle { | ||||
| trait HasPhysicalAddress extends Bundle { | ||||
|   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) | ||||
| } | ||||
|  | ||||
| class MemReqCmd extends PhysicalAddress { | ||||
| class MemData extends Bundle with HasMemData | ||||
|  | ||||
| class MemReqCmd extends Bundle with HasPhysicalAddress { | ||||
|   val rw = Bool() | ||||
|   val tag = Bits(width = MEM_TAG_BITS) | ||||
| } | ||||
|  | ||||
| class MemResp extends MemData { | ||||
| class MemResp extends Bundle with HasMemData { | ||||
|   val tag = Bits(width = MEM_TAG_BITS) | ||||
| } | ||||
|  | ||||
| @@ -32,9 +42,12 @@ class ioMemPipe extends Bundle { | ||||
|   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 client_xact_id = Bits(width = CLIENT_XACT_ID_BITS) | ||||
|   val write_mask = Bits(width = ACQUIRE_WRITE_MASK_BITS) | ||||
|   val subword_addr = Bits(width = ACQUIRE_SUBWORD_ADDR_BITS) | ||||
|   val atomic_opcode = Bits(width = ACQUIRE_ATOMIC_OP_BITS) | ||||
| @@ -47,6 +60,9 @@ object Acquire | ||||
|     acq.a_type := a_type | ||||
|     acq.addr := addr | ||||
|     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 | ||||
|   } | ||||
|   def apply(a_type: Bits, addr: UFix, client_xact_id: UFix, write_mask: Bits) = { | ||||
| @@ -55,6 +71,8 @@ object Acquire | ||||
|     acq.addr := addr | ||||
|     acq.client_xact_id := client_xact_id | ||||
|     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 | ||||
|   } | ||||
|   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.subword_addr := subword_addr | ||||
|     acq.atomic_opcode := atomic_opcode | ||||
|     acq.write_mask := Bits(0, width = ACQUIRE_WRITE_MASK_BITS) | ||||
|     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 master_xact_id = Bits(width = MASTER_XACT_ID_BITS) | ||||
| } | ||||
|  | ||||
| object Release | ||||
| @@ -86,35 +104,105 @@ object Release | ||||
|     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 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 client_xact_id = Bits(width = CLIENT_XACT_ID_BITS) | ||||
|   val master_xact_id = Bits(width = MASTER_XACT_ID_BITS) | ||||
| } | ||||
|  | ||||
| class GrantAck extends Bundle { | ||||
|   val master_xact_id = Bits(width = MASTER_XACT_ID_BITS) | ||||
| } | ||||
| class GrantAck extends ClientSourcedMessage with HasMasterTransactionId  | ||||
|  | ||||
| abstract class DirectionalFIFOIO[T <: Data]()(data: => T) extends FIFOIO()(data) | ||||
| class ClientSourcedIO[T <: Data]()(data: => T)  extends DirectionalFIFOIO()(data)  | ||||
| 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_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 release      = (new ClientSourcedIO){(new LogicalNetworkIO){new Release }} | ||||
|   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] } | ||||
| } | ||||
|  | ||||
| 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