Cleaned up uncore and coherence interface. Removed defunct broadcast hub. Trait-ified tilelink bundle components. Added generalized mem arbiter.
This commit is contained in:
parent
319b4544d7
commit
c36b1dfa30
@ -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
Loading…
Reference in New Issue
Block a user