commit
e8ce32a156
@ -59,6 +59,7 @@ endif
|
||||
ifeq ($(SUITE),GroundtestSuiteA)
|
||||
PROJECT=groundtest
|
||||
CONFIGS=MemtestConfig MemtestBufferlessConfig MemtestStatelessConfig
|
||||
# FancyMemtestConfig takes too long to compile
|
||||
endif
|
||||
|
||||
ifeq ($(SUITE),GroundtestSuiteB)
|
||||
|
@ -143,12 +143,11 @@ class WithBufferlessBroadcastHub extends Config((site, here, up) => {
|
||||
* DO NOT use this configuration.
|
||||
*/
|
||||
class WithStatelessBridge extends Config((site, here, up) => {
|
||||
/* !!! FIXME
|
||||
case BankedL2Config => up(BankedL2Config, site).copy(coherenceManager = { case (_, _) =>
|
||||
val pass = LazyModule(new TLBuffer(0)(site))
|
||||
(pass.node, pass.node)
|
||||
})
|
||||
*/
|
||||
case BankedL2Config => up(BankedL2Config, site).copy(coherenceManager = { case q =>
|
||||
implicit val p = q
|
||||
val cork = LazyModule(new TLCacheCork(unsafe = true))
|
||||
(cork.node, TLWidthWidget(p(L1toL2Config).beatBytes)(cork.node))
|
||||
})
|
||||
case DCacheKey => up(DCacheKey, site).copy(nMSHRs = 0)
|
||||
})
|
||||
|
||||
|
@ -55,7 +55,7 @@ trait CoreplexNetworkModule extends HasCoreplexParameters {
|
||||
val prot = (if (manager.supportsGet) "R" else "") +
|
||||
(if (manager.supportsPutFull) "W" else "") +
|
||||
(if (manager.executable) "X" else "") +
|
||||
(if (manager.supportsAcquire) " [C]" else "")
|
||||
(if (manager.supportsAcquireB) " [C]" else "")
|
||||
manager.address.foreach { a =>
|
||||
println(f"\t${manager.name}%s ${a.base}%x - ${a.base+a.mask+1}%x, $prot")
|
||||
}
|
||||
@ -70,27 +70,23 @@ trait BankedL2CoherenceManagers extends CoreplexNetwork {
|
||||
require (isPow2(l2Config.nBanksPerChannel))
|
||||
require (isPow2(l1tol2_lineBytes))
|
||||
|
||||
val mem = Seq.fill(l2Config.nMemoryChannels) {
|
||||
val mem = TLOutputNode()
|
||||
for (i <- 0 until l2Config.nMemoryChannels) {
|
||||
val bankBar = LazyModule(new TLXbar)
|
||||
val output = TLOutputNode()
|
||||
|
||||
output := bankBar.node
|
||||
mem := bankBar.node
|
||||
val mask = ~BigInt((l2Config.nBanksPerChannel-1) * l1tol2_lineBytes)
|
||||
for (i <- 0 until l2Config.nBanksPerChannel) {
|
||||
val (in, out) = l2Config.coherenceManager(p)
|
||||
in := TLFilter(AddressSet(i * l1tol2_lineBytes, mask))(l1tol2.node)
|
||||
bankBar.node := out
|
||||
}
|
||||
|
||||
output
|
||||
}
|
||||
}
|
||||
|
||||
trait BankedL2CoherenceManagersBundle extends CoreplexNetworkBundle {
|
||||
val outer: BankedL2CoherenceManagers
|
||||
|
||||
require (l2Config.nMemoryChannels <= 1, "Seq in Chisel Bundle needed to support > 1") // !!!
|
||||
val mem = outer.mem.map(_.bundleOut).toList.headOption // .headOption should be removed !!!
|
||||
val mem = outer.mem.bundleOut
|
||||
}
|
||||
|
||||
trait BankedL2CoherenceManagersModule extends CoreplexNetworkModule {
|
||||
|
@ -224,29 +224,29 @@ class SinkNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B])(pi: P
|
||||
override lazy val bundleOut = { require(false, s"${name} has no bundleOut; try bundleIn?"); bundleIn }
|
||||
}
|
||||
|
||||
class BlindOutputNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B])(pi: PI)
|
||||
extends SimpleNode(imp)({case (0, _) => Seq()}, {case (n, Seq()) => Seq.fill(n)(pi)}, 0 to 0, 1 to 1)
|
||||
class BlindOutputNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B])(pi: Seq[PI])
|
||||
extends SimpleNode(imp)({case (0, _) => Seq()}, {case (_, Seq()) => pi}, 0 to 0, pi.size to pi.size)
|
||||
{
|
||||
override val flip = true
|
||||
override lazy val bundleOut = bundleIn
|
||||
}
|
||||
|
||||
class BlindInputNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B])(po: PO)
|
||||
extends SimpleNode(imp)({case (n, Seq()) => Seq.fill(n)(po)}, {case (0, _) => Seq()}, 1 to 1, 0 to 0)
|
||||
class BlindInputNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B])(po: Seq[PO])
|
||||
extends SimpleNode(imp)({case (_, Seq()) => po}, {case (0, _) => Seq()}, po.size to po.size, 0 to 0)
|
||||
{
|
||||
override val flip = true
|
||||
override lazy val bundleIn = bundleOut
|
||||
}
|
||||
|
||||
class InternalOutputNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B])(pi: PI)
|
||||
extends SimpleNode(imp)({case (0, _) => Seq()}, {case (n, Seq()) => Seq.fill(n)(pi)}, 0 to 0, 1 to 1)
|
||||
class InternalOutputNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B])(pi: Seq[PI])
|
||||
extends SimpleNode(imp)({case (0, _) => Seq()}, {case (_, Seq()) => pi}, 0 to 0, pi.size to pi.size)
|
||||
{
|
||||
override val wire = true
|
||||
override lazy val bundleOut = bundleIn
|
||||
}
|
||||
|
||||
class InternalInputNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B])(po: PO)
|
||||
extends SimpleNode(imp)({case (n, Seq()) => Seq.fill(n)(po)}, {case (0, _) => Seq()}, 1 to 1, 0 to 0)
|
||||
class InternalInputNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B])(po: Seq[PO])
|
||||
extends SimpleNode(imp)({case (_, Seq()) => po}, {case (0, _) => Seq()}, po.size to po.size, 0 to 0)
|
||||
{
|
||||
override val wire = true
|
||||
override lazy val bundleIn = bundleOut
|
||||
|
@ -40,7 +40,7 @@ class MemtestStatelessConfig extends Config(
|
||||
// Test ALL the things
|
||||
class FancyMemtestConfig extends Config(
|
||||
new WithNGenerators(1, 2) ++ new WithNCores(2) ++ new WithMemtest ++
|
||||
new WithNMemoryChannels(1) ++ new WithNBanksPerMemChannel(4) ++ // !!! waiting on Chisel3 support for 2 channels
|
||||
new WithNMemoryChannels(2) ++ new WithNBanksPerMemChannel(4) ++
|
||||
new WithL2Cache ++ new GroundTestConfig)
|
||||
|
||||
class CacheFillTestConfig extends Config(
|
||||
|
@ -16,11 +16,6 @@ class TestHarness(implicit p: Parameters) extends Module {
|
||||
val dut = Module(LazyModule(new GroundTestTop).module)
|
||||
io.success := dut.io.success
|
||||
|
||||
if (dut.io.mem_axi4.nonEmpty) {
|
||||
val memSize = p(ExtMem).size
|
||||
require(memSize % dut.io.mem_axi4.size == 0)
|
||||
for (axi4 <- dut.io.mem_axi4) {
|
||||
Module(LazyModule(new SimAXIMem(memSize / dut.io.mem_axi4.size)).module).io.axi4 <> axi4
|
||||
}
|
||||
}
|
||||
val channels = p(coreplex.BankedL2Config).nMemoryChannels
|
||||
if (channels > 0) Module(LazyModule(new SimAXIMem(channels)).module).io.axi4 <> dut.io.mem_axi4
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ class GroundTestTop(implicit p: Parameters) extends BaseTop
|
||||
|
||||
socBus.node := coreplex.mmio
|
||||
coreplex.mmioInt := intBus.intnode
|
||||
(mem zip coreplex.mem) foreach { case (m, c) => m := c }
|
||||
mem.foreach { _ := coreplex.mem }
|
||||
}
|
||||
|
||||
class GroundTestTopBundle[+L <: GroundTestTop](_outer: L) extends BaseTopBundle(_outer)
|
||||
|
@ -253,7 +253,7 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) {
|
||||
val access_address = s2_req.addr
|
||||
val a_size = s2_req.typ(MT_SZ-2, 0)
|
||||
val a_data = Fill(beatWords, pstore1_storegen.data)
|
||||
val acquire = if (edge.manager.anySupportAcquire) {
|
||||
val acquire = if (edge.manager.anySupportAcquireB) {
|
||||
edge.Acquire(a_source, acquire_address, lgCacheBlockBytes, s2_grow_param)._2 // Cacheability checked by tlb
|
||||
} else {
|
||||
Wire(new TLBundleA(edge.bundle))
|
||||
@ -373,7 +373,7 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) {
|
||||
b = probe_bits,
|
||||
reportPermissions = TLPermissions.NtoN)
|
||||
|
||||
val voluntaryReleaseMessage = if (edge.manager.anySupportAcquire) {
|
||||
val voluntaryReleaseMessage = if (edge.manager.anySupportAcquireB) {
|
||||
edge.Release(
|
||||
fromSource = UInt(maxUncachedInFlight - 1),
|
||||
toAddress = probe_bits.address,
|
||||
|
@ -332,7 +332,7 @@ class MSHRFile(implicit edge: TLEdgeOut, cfg: DCacheConfig, p: Parameters) exten
|
||||
}
|
||||
|
||||
// determine if the request is cacheable or not
|
||||
val cacheable = edge.manager.supportsAcquireFast(io.req.bits.addr, lgCacheBlockBytes)
|
||||
val cacheable = edge.manager.supportsAcquireBFast(io.req.bits.addr, lgCacheBlockBytes)
|
||||
|
||||
val sdq_val = Reg(init=Bits(0, cfg.nSDQ))
|
||||
val sdq_alloc_id = PriorityEncoder(~sdq_val(cfg.nSDQ-1,0))
|
||||
|
@ -73,16 +73,19 @@ class TLB(implicit edge: TLEdgeOut, val p: Parameters) extends Module with HasTL
|
||||
val prot_r = fastCheck(_.supportsGet)
|
||||
val prot_w = fastCheck(_.supportsPutFull)
|
||||
val prot_x = fastCheck(_.executable)
|
||||
val cacheable = fastCheck(_.supportsAcquire)
|
||||
val cacheable = fastCheck(_.supportsAcquireB)
|
||||
val xferSizes = TransferSizes(cacheBlockBytes, cacheBlockBytes)
|
||||
val allSizes = TransferSizes(1, cacheBlockBytes)
|
||||
val amoSizes = TransferSizes(1, xLen/8)
|
||||
edge.manager.managers.foreach { m =>
|
||||
require (m.minAlignment >= 4096, s"MemoryMap region ${m.name} must be page-aligned (is ${m.minAlignment})")
|
||||
require (!m.supportsGet || m.supportsGet .contains(allSizes), s"MemoryMap region ${m.name} only supports ${m.supportsGet} Get, but must support ${allSizes}")
|
||||
require (!m.supportsPutFull || m.supportsPutFull.contains(allSizes), s"MemoryMap region ${m.name} only supports ${m.supportsPutFull} PutFull, but must support ${allSizes}")
|
||||
require (!m.supportsAcquire || m.supportsAcquire.contains(allSizes), s"MemoryMap region ${m.name} only supports ${m.supportsAcquire} Acquire, but must support ${allSizes}")
|
||||
require (!m.supportsLogical || m.supportsLogical.contains(amoSizes), s"MemoryMap region ${m.name} only supports ${m.supportsLogical} Logical, but must support ${amoSizes}")
|
||||
require (!m.supportsArithmetic || m.supportsArithmetic.contains(amoSizes), s"MemoryMap region ${m.name} only supports ${m.supportsArithmetic} Arithmetic, but must support ${amoSizes}")
|
||||
require (!m.supportsGet || m.supportsGet .contains(allSizes), s"MemoryMap region ${m.name} only supports ${m.supportsGet} Get, but must support ${allSizes}")
|
||||
require (!m.supportsPutFull || m.supportsPutFull .contains(allSizes), s"MemoryMap region ${m.name} only supports ${m.supportsPutFull} PutFull, but must support ${allSizes}")
|
||||
require (!m.supportsAcquireB || m.supportsAcquireB .contains(xferSizes), s"MemoryMap region ${m.name} only supports ${m.supportsAcquireB} AcquireB, but must support ${xferSizes}")
|
||||
require (!m.supportsAcquireT || m.supportsAcquireT .contains(xferSizes), s"MemoryMap region ${m.name} only supports ${m.supportsAcquireT} AcquireT, but must support ${xferSizes}")
|
||||
require (!m.supportsLogical || m.supportsLogical .contains(amoSizes), s"MemoryMap region ${m.name} only supports ${m.supportsLogical} Logical, but must support ${amoSizes}")
|
||||
require (!m.supportsArithmetic || m.supportsArithmetic.contains(amoSizes), s"MemoryMap region ${m.name} only supports ${m.supportsArithmetic} Arithmetic, but must support ${amoSizes}")
|
||||
require (m.supportsAcquireT || !m.supportsPutFull || !m.supportsAcquireB, s"MemoryMap region ${m.name} supports PutFull and AcquireB but not AcquireT")
|
||||
}
|
||||
|
||||
val lookup_tag = Cat(io.ptw.ptbr.asid, io.req.bits.vpn(vpnBits-1,0))
|
||||
|
@ -87,11 +87,11 @@ trait PeripheryMasterAXI4Mem {
|
||||
private val config = p(ExtMem)
|
||||
private val channels = p(BankedL2Config).nMemoryChannels
|
||||
|
||||
val mem_axi4 = Seq.tabulate(channels) { i =>
|
||||
val mem_axi4 = AXI4BlindOutputNode(Seq.tabulate(channels) { i =>
|
||||
val c_size = config.size/channels
|
||||
val c_base = config.base + c_size*i
|
||||
|
||||
AXI4BlindOutputNode(AXI4SlavePortParameters(
|
||||
AXI4SlavePortParameters(
|
||||
slaves = Seq(AXI4SlaveParameters(
|
||||
address = List(AddressSet(c_base, c_size-1)),
|
||||
regionType = RegionType.UNCACHED, // cacheable
|
||||
@ -99,12 +99,12 @@ trait PeripheryMasterAXI4Mem {
|
||||
supportsWrite = TransferSizes(1, 256), // The slave supports 1-256 byte transfers
|
||||
supportsRead = TransferSizes(1, 256),
|
||||
interleavedId = Some(0))), // slave does not interleave read responses
|
||||
beatBytes = config.beatBytes))
|
||||
}
|
||||
beatBytes = config.beatBytes)
|
||||
})
|
||||
|
||||
val mem = mem_axi4.map { node =>
|
||||
val mem = Seq.fill(channels) {
|
||||
val converter = LazyModule(new TLToAXI4(config.idBits))
|
||||
node := AXI4Buffer()(converter.node)
|
||||
mem_axi4 := AXI4Buffer()(converter.node)
|
||||
converter.node
|
||||
}
|
||||
}
|
||||
@ -113,7 +113,7 @@ trait PeripheryMasterAXI4MemBundle {
|
||||
this: TopNetworkBundle {
|
||||
val outer: PeripheryMasterAXI4Mem
|
||||
} =>
|
||||
val mem_axi4 = outer.mem_axi4.map(_.bundleOut).toList.headOption // !!! remove headOption when Seq supported
|
||||
val mem_axi4 = outer.mem_axi4.bundleOut
|
||||
}
|
||||
|
||||
trait PeripheryMasterAXI4MemModule {
|
||||
@ -130,14 +130,14 @@ trait PeripheryMasterAXI4MMIO {
|
||||
this: TopNetwork =>
|
||||
|
||||
private val config = p(ExtBus)
|
||||
val mmio_axi4 = AXI4BlindOutputNode(AXI4SlavePortParameters(
|
||||
val mmio_axi4 = AXI4BlindOutputNode(Seq(AXI4SlavePortParameters(
|
||||
slaves = Seq(AXI4SlaveParameters(
|
||||
address = List(AddressSet(BigInt(config.base), config.size-1)),
|
||||
executable = true, // Can we run programs on this memory?
|
||||
supportsWrite = TransferSizes(1, 256), // The slave supports 1-256 byte transfers
|
||||
supportsRead = TransferSizes(1, 256),
|
||||
interleavedId = Some(0))), // slave does not interleave read responses
|
||||
beatBytes = config.beatBytes))
|
||||
beatBytes = config.beatBytes)))
|
||||
|
||||
mmio_axi4 :=
|
||||
AXI4Buffer()(
|
||||
@ -167,9 +167,9 @@ trait PeripheryMasterAXI4MMIOModule {
|
||||
// PeripherySlaveAXI4 is an example, make your own cake pattern like this one.
|
||||
trait PeripherySlaveAXI4 extends L2Crossbar {
|
||||
private val config = p(ExtIn)
|
||||
val l2_axi4 = AXI4BlindInputNode(AXI4MasterPortParameters(
|
||||
val l2_axi4 = AXI4BlindInputNode(Seq(AXI4MasterPortParameters(
|
||||
masters = Seq(AXI4MasterParameters(
|
||||
id = IdRange(0, 1 << config.idBits)))))
|
||||
id = IdRange(0, 1 << config.idBits))))))
|
||||
|
||||
l2.node :=
|
||||
TLSourceShrinker(1 << config.sourceBits)(
|
||||
@ -197,14 +197,14 @@ trait PeripheryMasterTLMMIO {
|
||||
this: TopNetwork =>
|
||||
|
||||
private val config = p(ExtBus)
|
||||
val mmio_tl = TLBlindOutputNode(TLManagerPortParameters(
|
||||
val mmio_tl = TLBlindOutputNode(Seq(TLManagerPortParameters(
|
||||
managers = Seq(TLManagerParameters(
|
||||
address = List(AddressSet(BigInt(config.base), config.size-1)),
|
||||
executable = true,
|
||||
supportsGet = TransferSizes(1, cacheBlockBytes),
|
||||
supportsPutFull = TransferSizes(1, cacheBlockBytes),
|
||||
supportsPutPartial = TransferSizes(1, cacheBlockBytes))),
|
||||
beatBytes = config.beatBytes))
|
||||
beatBytes = config.beatBytes)))
|
||||
|
||||
mmio_tl :=
|
||||
TLBuffer()(
|
||||
@ -233,9 +233,9 @@ trait PeripheryMasterTLMMIOModule {
|
||||
// NOTE: this port is NOT allowed to issue Acquires
|
||||
trait PeripherySlaveTL extends L2Crossbar {
|
||||
private val config = p(ExtIn)
|
||||
val l2_tl = TLBlindInputNode(TLClientPortParameters(
|
||||
val l2_tl = TLBlindInputNode(Seq(TLClientPortParameters(
|
||||
clients = Seq(TLClientParameters(
|
||||
sourceId = IdRange(0, 1 << config.idBits)))))
|
||||
sourceId = IdRange(0, 1 << config.idBits))))))
|
||||
|
||||
l2.node :=
|
||||
TLSourceShrinker(1 << config.sourceBits)(
|
||||
|
@ -19,7 +19,7 @@ trait RocketPlexMaster extends L2Crossbar {
|
||||
coreplex.l2in := l2.node
|
||||
socBus.node := coreplex.mmio
|
||||
coreplex.mmioInt := intBus.intnode
|
||||
(mem zip coreplex.mem) foreach { case (m, c) => m := c }
|
||||
mem.foreach { _ := coreplex.mem }
|
||||
}
|
||||
|
||||
trait RocketPlexMasterBundle extends L2CrossbarBundle {
|
||||
|
@ -18,13 +18,8 @@ class TestHarness()(implicit p: Parameters) extends Module {
|
||||
for (int <- dut.io.interrupts(0))
|
||||
int := Bool(false)
|
||||
|
||||
if (dut.io.mem_axi4.nonEmpty) {
|
||||
val memSize = p(ExtMem).size
|
||||
require(memSize % dut.io.mem_axi4.size == 0)
|
||||
for (axi4 <- dut.io.mem_axi4) {
|
||||
Module(LazyModule(new SimAXIMem(memSize / dut.io.mem_axi4.size)).module).io.axi4 <> axi4
|
||||
}
|
||||
}
|
||||
val channels = p(coreplex.BankedL2Config).nMemoryChannels
|
||||
if (channels > 0) Module(LazyModule(new SimAXIMem(channels)).module).io.axi4 <> dut.io.mem_axi4
|
||||
|
||||
if (!p(IncludeJtagDTM)) {
|
||||
val dtm = Module(new SimDTM).connect(clock, reset, dut.io.debug.get, io.success)
|
||||
@ -32,7 +27,7 @@ class TestHarness()(implicit p: Parameters) extends Module {
|
||||
val jtag = Module(new JTAGVPI).connect(dut.io.jtag.get, reset, io.success)
|
||||
}
|
||||
|
||||
val mmio_sim = Module(LazyModule(new SimAXIMem(4096)).module)
|
||||
val mmio_sim = Module(LazyModule(new SimAXIMem(1, 4096)).module)
|
||||
mmio_sim.io.axi4 <> dut.io.mmio_axi4
|
||||
|
||||
val l2_axi4 = dut.io.l2_axi4(0)
|
||||
@ -43,12 +38,19 @@ class TestHarness()(implicit p: Parameters) extends Module {
|
||||
l2_axi4.b .ready := Bool(true)
|
||||
}
|
||||
|
||||
class SimAXIMem(size: BigInt)(implicit p: Parameters) extends LazyModule {
|
||||
class SimAXIMem(channels: Int, forceSize: BigInt = 0)(implicit p: Parameters) extends LazyModule {
|
||||
val config = p(ExtMem)
|
||||
val totalSize = if (forceSize > 0) forceSize else BigInt(config.size)
|
||||
val size = totalSize / channels
|
||||
require(totalSize % channels == 0)
|
||||
|
||||
val node = AXI4BlindInputNode(AXI4MasterPortParameters(Seq(AXI4MasterParameters(IdRange(0, 1 << config.idBits)))))
|
||||
val sram = LazyModule(new AXI4RAM(AddressSet(0, size-1), beatBytes = config.beatBytes))
|
||||
sram.node := AXI4Buffer()(AXI4Fragmenter(maxInFlight = 4)(node))
|
||||
val node = AXI4BlindInputNode(Seq.fill(channels) {
|
||||
AXI4MasterPortParameters(Seq(AXI4MasterParameters(IdRange(0, 1 << config.idBits))))})
|
||||
|
||||
for (i <- 0 until channels) {
|
||||
val sram = LazyModule(new AXI4RAM(AddressSet(0, size-1), beatBytes = config.beatBytes))
|
||||
sram.node := AXI4Buffer()(AXI4Fragmenter(maxInFlight = 4)(node))
|
||||
}
|
||||
|
||||
lazy val module = new LazyModuleImp(this) {
|
||||
val io = new Bundle {
|
||||
|
@ -11,14 +11,9 @@ object AHBImp extends NodeImp[AHBMasterPortParameters, AHBSlavePortParameters, A
|
||||
{
|
||||
def edgeO(pd: AHBMasterPortParameters, pu: AHBSlavePortParameters): AHBEdgeParameters = AHBEdgeParameters(pd, pu)
|
||||
def edgeI(pd: AHBMasterPortParameters, pu: AHBSlavePortParameters): AHBEdgeParameters = AHBEdgeParameters(pd, pu)
|
||||
def bundleO(eo: Seq[AHBEdgeParameters]): Vec[AHBBundle] = {
|
||||
require (!eo.isEmpty)
|
||||
Vec(eo.size, AHBBundle(eo.map(_.bundle).reduce(_.union(_))))
|
||||
}
|
||||
def bundleI(ei: Seq[AHBEdgeParameters]): Vec[AHBBundle] = {
|
||||
require (!ei.isEmpty)
|
||||
Vec(ei.size, AHBBundle(ei.map(_.bundle).reduce(_.union(_))))
|
||||
}
|
||||
|
||||
def bundleO(eo: Seq[AHBEdgeParameters]): Vec[AHBBundle] = Vec(eo.size, AHBBundle(AHBBundleParameters.union(eo.map(_.bundle))))
|
||||
def bundleI(ei: Seq[AHBEdgeParameters]): Vec[AHBBundle] = Vec(ei.size, AHBBundle(AHBBundleParameters.union(ei.map(_.bundle))))
|
||||
|
||||
def colour = "#00ccff" // bluish
|
||||
override def labelI(ei: AHBEdgeParameters) = (ei.slave.beatBytes * 8).toString
|
||||
@ -52,8 +47,8 @@ case class AHBOutputNode() extends OutputNode(AHBImp)
|
||||
case class AHBInputNode() extends InputNode(AHBImp)
|
||||
|
||||
// Nodes used for external ports
|
||||
case class AHBBlindOutputNode(portParams: AHBSlavePortParameters) extends BlindOutputNode(AHBImp)(portParams)
|
||||
case class AHBBlindInputNode(portParams: AHBMasterPortParameters) extends BlindInputNode(AHBImp)(portParams)
|
||||
case class AHBBlindOutputNode(portParams: Seq[AHBSlavePortParameters]) extends BlindOutputNode(AHBImp)(portParams)
|
||||
case class AHBBlindInputNode(portParams: Seq[AHBMasterPortParameters]) extends BlindInputNode(AHBImp)(portParams)
|
||||
|
||||
case class AHBInternalOutputNode(portParams: AHBSlavePortParameters) extends InternalOutputNode(AHBImp)(portParams)
|
||||
case class AHBInternalInputNode(portParams: AHBMasterPortParameters) extends InternalInputNode(AHBImp)(portParams)
|
||||
case class AHBInternalOutputNode(portParams: Seq[AHBSlavePortParameters]) extends InternalOutputNode(AHBImp)(portParams)
|
||||
case class AHBInternalInputNode(portParams: Seq[AHBMasterPortParameters]) extends InternalInputNode(AHBImp)(portParams)
|
||||
|
@ -85,6 +85,9 @@ case class AHBBundleParameters(
|
||||
|
||||
object AHBBundleParameters
|
||||
{
|
||||
val emptyBundleParams = AHBBundleParameters(addrBits = 1, dataBits = 8)
|
||||
def union(x: Seq[AHBBundleParameters]) = x.foldLeft(emptyBundleParams)((x,y) => x.union(y))
|
||||
|
||||
def apply(master: AHBMasterPortParameters, slave: AHBSlavePortParameters) =
|
||||
new AHBBundleParameters(
|
||||
addrBits = log2Up(slave.maxAddress+1),
|
||||
|
@ -11,14 +11,9 @@ object APBImp extends NodeImp[APBMasterPortParameters, APBSlavePortParameters, A
|
||||
{
|
||||
def edgeO(pd: APBMasterPortParameters, pu: APBSlavePortParameters): APBEdgeParameters = APBEdgeParameters(pd, pu)
|
||||
def edgeI(pd: APBMasterPortParameters, pu: APBSlavePortParameters): APBEdgeParameters = APBEdgeParameters(pd, pu)
|
||||
def bundleO(eo: Seq[APBEdgeParameters]): Vec[APBBundle] = {
|
||||
require (!eo.isEmpty)
|
||||
Vec(eo.size, APBBundle(eo.map(_.bundle).reduce(_.union(_))))
|
||||
}
|
||||
def bundleI(ei: Seq[APBEdgeParameters]): Vec[APBBundle] = {
|
||||
require (!ei.isEmpty)
|
||||
Vec(ei.size, APBBundle(ei.map(_.bundle).reduce(_.union(_))))
|
||||
}
|
||||
|
||||
def bundleO(eo: Seq[APBEdgeParameters]): Vec[APBBundle] = Vec(eo.size, APBBundle(APBBundleParameters.union(eo.map(_.bundle))))
|
||||
def bundleI(ei: Seq[APBEdgeParameters]): Vec[APBBundle] = Vec(ei.size, APBBundle(APBBundleParameters.union(ei.map(_.bundle))))
|
||||
|
||||
def colour = "#00ccff" // bluish
|
||||
override def labelI(ei: APBEdgeParameters) = (ei.slave.beatBytes * 8).toString
|
||||
@ -52,8 +47,8 @@ case class APBOutputNode() extends OutputNode(APBImp)
|
||||
case class APBInputNode() extends InputNode(APBImp)
|
||||
|
||||
// Nodes used for external ports
|
||||
case class APBBlindOutputNode(portParams: APBSlavePortParameters) extends BlindOutputNode(APBImp)(portParams)
|
||||
case class APBBlindInputNode(portParams: APBMasterPortParameters) extends BlindInputNode(APBImp)(portParams)
|
||||
case class APBBlindOutputNode(portParams: Seq[APBSlavePortParameters]) extends BlindOutputNode(APBImp)(portParams)
|
||||
case class APBBlindInputNode(portParams: Seq[APBMasterPortParameters]) extends BlindInputNode(APBImp)(portParams)
|
||||
|
||||
case class APBInternalOutputNode(portParams: APBSlavePortParameters) extends InternalOutputNode(APBImp)(portParams)
|
||||
case class APBInternalInputNode(portParams: APBMasterPortParameters) extends InternalInputNode(APBImp)(portParams)
|
||||
case class APBInternalOutputNode(portParams: Seq[APBSlavePortParameters]) extends InternalOutputNode(APBImp)(portParams)
|
||||
case class APBInternalInputNode(portParams: Seq[APBMasterPortParameters]) extends InternalInputNode(APBImp)(portParams)
|
||||
|
@ -72,6 +72,9 @@ case class APBBundleParameters(
|
||||
|
||||
object APBBundleParameters
|
||||
{
|
||||
val emptyBundleParams = APBBundleParameters(addrBits = 1, dataBits = 8)
|
||||
def union(x: Seq[APBBundleParameters]) = x.foldLeft(emptyBundleParams)((x,y) => x.union(y))
|
||||
|
||||
def apply(master: APBMasterPortParameters, slave: APBSlavePortParameters) =
|
||||
new APBBundleParameters(
|
||||
addrBits = log2Up(slave.maxAddress+1),
|
||||
|
@ -11,14 +11,9 @@ object AXI4Imp extends NodeImp[AXI4MasterPortParameters, AXI4SlavePortParameters
|
||||
{
|
||||
def edgeO(pd: AXI4MasterPortParameters, pu: AXI4SlavePortParameters): AXI4EdgeParameters = AXI4EdgeParameters(pd, pu)
|
||||
def edgeI(pd: AXI4MasterPortParameters, pu: AXI4SlavePortParameters): AXI4EdgeParameters = AXI4EdgeParameters(pd, pu)
|
||||
def bundleO(eo: Seq[AXI4EdgeParameters]): Vec[AXI4Bundle] = {
|
||||
require (!eo.isEmpty)
|
||||
Vec(eo.size, AXI4Bundle(eo.map(_.bundle).reduce(_.union(_))))
|
||||
}
|
||||
def bundleI(ei: Seq[AXI4EdgeParameters]): Vec[AXI4Bundle] = {
|
||||
require (!ei.isEmpty)
|
||||
Vec(ei.size, AXI4Bundle(ei.map(_.bundle).reduce(_.union(_))))
|
||||
}
|
||||
|
||||
def bundleO(eo: Seq[AXI4EdgeParameters]): Vec[AXI4Bundle] = Vec(eo.size, AXI4Bundle(AXI4BundleParameters.union(eo.map(_.bundle))))
|
||||
def bundleI(ei: Seq[AXI4EdgeParameters]): Vec[AXI4Bundle] = Vec(ei.size, AXI4Bundle(AXI4BundleParameters.union(ei.map(_.bundle))))
|
||||
|
||||
def colour = "#00ccff" // bluish
|
||||
override def labelI(ei: AXI4EdgeParameters) = (ei.slave.beatBytes * 8).toString
|
||||
@ -52,8 +47,8 @@ case class AXI4OutputNode() extends OutputNode(AXI4Imp)
|
||||
case class AXI4InputNode() extends InputNode(AXI4Imp)
|
||||
|
||||
// Nodes used for external ports
|
||||
case class AXI4BlindOutputNode(portParams: AXI4SlavePortParameters) extends BlindOutputNode(AXI4Imp)(portParams)
|
||||
case class AXI4BlindInputNode(portParams: AXI4MasterPortParameters) extends BlindInputNode(AXI4Imp)(portParams)
|
||||
case class AXI4BlindOutputNode(portParams: Seq[AXI4SlavePortParameters]) extends BlindOutputNode(AXI4Imp)(portParams)
|
||||
case class AXI4BlindInputNode(portParams: Seq[AXI4MasterPortParameters]) extends BlindInputNode(AXI4Imp)(portParams)
|
||||
|
||||
case class AXI4InternalOutputNode(portParams: AXI4SlavePortParameters) extends InternalOutputNode(AXI4Imp)(portParams)
|
||||
case class AXI4InternalInputNode(portParams: AXI4MasterPortParameters) extends InternalInputNode(AXI4Imp)(portParams)
|
||||
case class AXI4InternalOutputNode(portParams: Seq[AXI4SlavePortParameters]) extends InternalOutputNode(AXI4Imp)(portParams)
|
||||
case class AXI4InternalInputNode(portParams: Seq[AXI4MasterPortParameters]) extends InternalInputNode(AXI4Imp)(portParams)
|
||||
|
@ -101,6 +101,9 @@ case class AXI4BundleParameters(
|
||||
|
||||
object AXI4BundleParameters
|
||||
{
|
||||
val emptyBundleParams = AXI4BundleParameters(addrBits=1, dataBits=8, idBits=1)
|
||||
def union(x: Seq[AXI4BundleParameters]) = x.foldLeft(emptyBundleParams)((x,y) => x.union(y))
|
||||
|
||||
def apply(master: AXI4MasterPortParameters, slave: AXI4SlavePortParameters) =
|
||||
new AXI4BundleParameters(
|
||||
addrBits = log2Up(slave.maxAddress+1),
|
||||
|
@ -253,7 +253,7 @@ class TLAtomicAutomata(logical: Boolean = true, arithmetic: Boolean = true, conc
|
||||
in.d.bits := out.d.bits
|
||||
}
|
||||
|
||||
if (edgeOut.manager.anySupportAcquire && edgeIn.client.anySupportProbe) {
|
||||
if (edgeOut.manager.anySupportAcquireB && edgeIn.client.anySupportProbe) {
|
||||
in.b.valid := out.b.valid
|
||||
out.b.ready := in.b.ready
|
||||
in.b.bits := out.b.bits
|
||||
|
@ -22,22 +22,24 @@ class TLBroadcast(lineBytes: Int, numTrackers: Int = 4, bufferless: Boolean = fa
|
||||
endSinkId = numTrackers,
|
||||
managers = mp.managers.map { m =>
|
||||
// We are the last level manager
|
||||
require (m.regionType != RegionType.CACHED)
|
||||
require (m.regionType != RegionType.TRACKED)
|
||||
require (!m.supportsAcquire)
|
||||
require (!m.supportsAcquireB)
|
||||
// We only manage addresses which are uncached
|
||||
if (m.regionType == RegionType.UNCACHED && m.supportsGet) {
|
||||
if (m.regionType == RegionType.UNCACHED) {
|
||||
// The device had better support line transfers
|
||||
val lowerBound = max(m.supportsPutFull.min, m.supportsGet.min)
|
||||
require (!m.supportsPutFull || m.supportsPutFull.contains(lineBytes))
|
||||
require (!m.supportsGet || m.supportsGet .contains(lineBytes))
|
||||
m.copy(
|
||||
regionType = RegionType.TRACKED,
|
||||
supportsAcquire = TransferSizes(lowerBound, lineBytes),
|
||||
supportsAcquireB = TransferSizes(lowerBound, lineBytes),
|
||||
supportsAcquireT = if (m.supportsPutFull) TransferSizes(lowerBound, lineBytes) else TransferSizes.none,
|
||||
// truncate supported accesses to lineBytes (we only ever probe for one line)
|
||||
supportsPutFull = TransferSizes(m.supportsPutFull .min, min(m.supportsPutFull .max, lineBytes)),
|
||||
supportsPutPartial = TransferSizes(m.supportsPutPartial.min, min(m.supportsPutPartial.max, lineBytes)),
|
||||
supportsGet = TransferSizes(m.supportsGet .min, min(m.supportsGet .max, lineBytes)),
|
||||
supportsHint = TransferSizes(m.supportsHint .min, min(m.supportsHint .max, lineBytes)),
|
||||
supportsArithmetic = TransferSizes(m.supportsArithmetic.min, min(m.supportsArithmetic.max, lineBytes)),
|
||||
supportsLogical = TransferSizes(m.supportsLogical .min, min(m.supportsLogical .max, lineBytes)),
|
||||
fifoId = None // trackers do not respond in FIFO order!
|
||||
)
|
||||
} else {
|
||||
|
@ -31,7 +31,7 @@ class TLBuffer(a: Int = 2, b: Int = 2, c: Int = 2, d: Int = 2, e: Int = 2, pipe:
|
||||
if (a>0) { out.a <> Queue(in .a, a, pipe && a<2) } else { out.a <> in.a }
|
||||
if (d>0) { in .d <> Queue(out.d, d, pipe && d<2) } else { in.d <> out.d }
|
||||
|
||||
if (edgeOut.manager.anySupportAcquire && edgeOut.client.anySupportProbe) {
|
||||
if (edgeOut.manager.anySupportAcquireB && edgeOut.client.anySupportProbe) {
|
||||
if (b>0) { in .b <> Queue(out.b, b, pipe && b<2) } else { in.b <> out.b }
|
||||
if (c>0) { out.c <> Queue(in .c, c, pipe && c<2) } else { out.c <> in.c }
|
||||
if (e>0) { out.e <> Queue(in .e, e, pipe && e<2) } else { out.e <> in.e }
|
||||
|
128
src/main/scala/uncore/tilelink2/CacheCork.scala
Normal file
128
src/main/scala/uncore/tilelink2/CacheCork.scala
Normal file
@ -0,0 +1,128 @@
|
||||
// See LICENSE.SiFive for license details.
|
||||
|
||||
package uncore.tilelink2
|
||||
|
||||
import Chisel._
|
||||
import chisel3.internal.sourceinfo.SourceInfo
|
||||
import config._
|
||||
import diplomacy._
|
||||
import scala.math.{min,max}
|
||||
import TLMessages._
|
||||
|
||||
class TLCacheCork(unsafe: Boolean = false)(implicit p: Parameters) extends LazyModule
|
||||
{
|
||||
val node = TLAdapterNode(
|
||||
clientFn = { case Seq(cp) =>
|
||||
cp.copy(clients = cp.clients.map { c => c.copy(
|
||||
sourceId = IdRange(c.sourceId.start*2, c.sourceId.end*2))})},
|
||||
managerFn = { case Seq(mp) =>
|
||||
mp.copy(managers = mp.managers.map { m => m.copy(
|
||||
regionType = if (m.regionType == RegionType.UNCACHED) RegionType.TRACKED else m.regionType,
|
||||
supportsAcquireB = m.supportsGet,
|
||||
supportsAcquireT = m.supportsPutFull)})})
|
||||
|
||||
lazy val module = new LazyModuleImp(this) {
|
||||
val io = new Bundle {
|
||||
val in = node.bundleIn
|
||||
val out = node.bundleOut
|
||||
}
|
||||
|
||||
val edgeIn = node.edgesIn(0)
|
||||
val edgeOut = node.edgesOut(0)
|
||||
|
||||
require (edgeIn.client.clients.size == 1 || unsafe, "Only one client can safely use a TLCacheCork")
|
||||
require (edgeIn.client.clients.filter(_.supportsProbe).size == 1, "Only one caching client allowed")
|
||||
edgeOut.manager.managers.foreach { case m =>
|
||||
require (!m.supportsAcquireB, "Cannot support caches beyond the Cork")
|
||||
}
|
||||
|
||||
val out = io.out(0)
|
||||
val in = io.in(0)
|
||||
|
||||
// The Cork turns [Acquire=>Get] => [AccessAckData=>GrantData]
|
||||
// and [ReleaseData=>PutFullData] => [AccessAck=>ReleaseAck]
|
||||
// We need to encode information sufficient to reverse the transformation in output.
|
||||
// A caveat is that we get Acquire+Release with the same source and must keep the
|
||||
// source unique after transformation onto the A channel.
|
||||
// The coding scheme is:
|
||||
// Put: 1, Release: 0 => AccessAck
|
||||
// *: 0, Acquire: 1 => AccessAckData
|
||||
|
||||
// Take requests from A to A
|
||||
val isPut = in.a.bits.opcode === PutFullData || in.a.bits.opcode === PutPartialData
|
||||
val a_a = Wire(out.a)
|
||||
a_a <> in.a
|
||||
a_a.bits.source := in.a.bits.source << 1 | Mux(isPut, UInt(1), UInt(0))
|
||||
|
||||
// Transform Acquire into Get
|
||||
when (in.a.bits.opcode === Acquire) {
|
||||
a_a.bits.opcode := Get
|
||||
a_a.bits.param := UInt(0)
|
||||
a_a.bits.source := in.a.bits.source << 1 | UInt(1)
|
||||
}
|
||||
|
||||
// Take ReleaseData from C to A; Release from C to D
|
||||
val c_a = Wire(out.a)
|
||||
c_a.valid := in.c.valid && in.c.bits.opcode === ReleaseData
|
||||
c_a.bits.opcode := PutFullData
|
||||
c_a.bits.param := UInt(0)
|
||||
c_a.bits.size := in.c.bits.size
|
||||
c_a.bits.source := in.c.bits.source << 1
|
||||
c_a.bits.address := in.c.bits.address
|
||||
c_a.bits.mask := edgeOut.mask(in.c.bits.address, in.c.bits.size)
|
||||
c_a.bits.data := in.c.bits.data
|
||||
|
||||
val c_d = Wire(in.d)
|
||||
c_d.valid := in.c.valid && in.c.bits.opcode === Release
|
||||
c_d.bits.opcode := ReleaseAck
|
||||
c_d.bits.param := UInt(0)
|
||||
c_d.bits.size := in.c.bits.size
|
||||
c_d.bits.source := in.c.bits.source
|
||||
c_d.bits.sink := UInt(0)
|
||||
c_d.bits.addr_lo := in.c.bits.address
|
||||
c_d.bits.data := UInt(0)
|
||||
c_d.bits.error := Bool(false)
|
||||
|
||||
assert (!in.c.valid || in.c.bits.opcode === Release || in.c.bits.opcode === ReleaseData)
|
||||
in.c.ready := Mux(in.c.bits.opcode === Release, c_d.ready, c_a.ready)
|
||||
|
||||
// Discard E
|
||||
in.e.ready := Bool(true)
|
||||
|
||||
// Block B; should never happen
|
||||
out.b.ready := Bool(false)
|
||||
assert (!out.b.valid)
|
||||
|
||||
// Take responses from D and transform them
|
||||
val d_d = Wire(in.d)
|
||||
d_d <> out.d
|
||||
d_d.bits.source := out.d.bits.source >> 1
|
||||
|
||||
when (out.d.bits.opcode === AccessAckData && out.d.bits.source(0)) {
|
||||
d_d.bits.opcode := GrantData
|
||||
d_d.bits.param := TLPermissions.toT
|
||||
}
|
||||
when (out.d.bits.opcode === AccessAck && !out.d.bits.source(0)) {
|
||||
d_d.bits.opcode := ReleaseAck
|
||||
}
|
||||
|
||||
// Combine the sources of messages into the channels
|
||||
TLArbiter(TLArbiter.lowestIndexFirst)(out.a, (edgeOut.numBeats1(c_a.bits), c_a), (edgeOut.numBeats1(a_a.bits), a_a))
|
||||
TLArbiter(TLArbiter.lowestIndexFirst)(in.d, (edgeIn .numBeats1(d_d.bits), d_d), (UInt(0), Queue(c_d, 2)))
|
||||
|
||||
// Tie off unused ports
|
||||
in.b.valid := Bool(false)
|
||||
out.c.valid := Bool(false)
|
||||
out.e.valid := Bool(false)
|
||||
}
|
||||
}
|
||||
|
||||
object TLCacheCork
|
||||
{
|
||||
// applied to the TL source node; y.node := TLCacheCork()(x.node)
|
||||
def apply(unsafe: Boolean = false)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
||||
val cork = LazyModule(new TLCacheCork(unsafe))
|
||||
cork.node := x
|
||||
cork.node
|
||||
}
|
||||
}
|
@ -20,7 +20,7 @@ class TLAsyncCrossingSource(sync: Int = 3)(implicit p: Parameters) extends LazyM
|
||||
|
||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
||||
val sink_reset_n = out.a.sink_reset_n
|
||||
val bce = edgeIn.manager.anySupportAcquire && edgeIn.client.anySupportProbe
|
||||
val bce = edgeIn.manager.anySupportAcquireB && edgeIn.client.anySupportProbe
|
||||
val depth = edgeOut.manager.depth
|
||||
|
||||
out.a <> ToAsyncBundle(in.a, depth, sync)
|
||||
@ -54,7 +54,7 @@ class TLAsyncCrossingSink(depth: Int = 8, sync: Int = 3)(implicit p: Parameters)
|
||||
|
||||
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
|
||||
val source_reset_n = in.a.source_reset_n
|
||||
val bce = edgeOut.manager.anySupportAcquire && edgeOut.client.anySupportProbe
|
||||
val bce = edgeOut.manager.anySupportAcquireB && edgeOut.client.anySupportProbe
|
||||
|
||||
out.a <> FromAsyncBundle(in.a, sync)
|
||||
in.d <> ToAsyncBundle(out.d, depth, sync)
|
||||
|
@ -27,7 +27,7 @@ class TLEdge(
|
||||
// Do there exist A messages with Data?
|
||||
val aDataYes = manager.anySupportArithmetic || manager.anySupportLogical || manager.anySupportPutFull || manager.anySupportPutPartial
|
||||
// Do there exist A messages without Data?
|
||||
val aDataNo = manager.anySupportAcquire || manager.anySupportGet || manager.anySupportHint
|
||||
val aDataNo = manager.anySupportAcquireB || manager.anySupportGet || manager.anySupportHint
|
||||
// Statically optimize the case where hasData is a constant
|
||||
if (!aDataYes) Some(false) else if (!aDataNo) Some(true) else None
|
||||
}
|
||||
@ -48,9 +48,9 @@ class TLEdge(
|
||||
}
|
||||
case _:TLBundleD => {
|
||||
// Do there eixst D messages with Data?
|
||||
val dDataYes = manager.anySupportGet || manager.anySupportArithmetic || manager.anySupportLogical || manager.anySupportAcquire
|
||||
val dDataYes = manager.anySupportGet || manager.anySupportArithmetic || manager.anySupportLogical || manager.anySupportAcquireB
|
||||
// Do there exist D messages without Data?
|
||||
val dDataNo = manager.anySupportPutFull || manager.anySupportPutPartial || manager.anySupportHint || manager.anySupportAcquire
|
||||
val dDataNo = manager.anySupportPutFull || manager.anySupportPutPartial || manager.anySupportHint || manager.anySupportAcquireT
|
||||
if (!dDataYes) Some(false) else if (!dDataNo) Some(true) else None
|
||||
}
|
||||
case _:TLBundleE => Some(false)
|
||||
@ -244,8 +244,8 @@ class TLEdgeOut(
|
||||
{
|
||||
// Transfers
|
||||
def Acquire(fromSource: UInt, toAddress: UInt, lgSize: UInt, growPermissions: UInt) = {
|
||||
require (manager.anySupportAcquire)
|
||||
val legal = manager.supportsAcquireFast(toAddress, lgSize)
|
||||
require (manager.anySupportAcquireB)
|
||||
val legal = manager.supportsAcquireBFast(toAddress, lgSize)
|
||||
val a = Wire(new TLBundleA(bundle))
|
||||
a.opcode := TLMessages.Acquire
|
||||
a.param := growPermissions
|
||||
@ -258,8 +258,8 @@ class TLEdgeOut(
|
||||
}
|
||||
|
||||
def Release(fromSource: UInt, toAddress: UInt, lgSize: UInt, shrinkPermissions: UInt) = {
|
||||
require (manager.anySupportAcquire)
|
||||
val legal = manager.supportsAcquireFast(toAddress, lgSize)
|
||||
require (manager.anySupportAcquireB)
|
||||
val legal = manager.supportsAcquireBFast(toAddress, lgSize)
|
||||
val c = Wire(new TLBundleC(bundle))
|
||||
c.opcode := TLMessages.Release
|
||||
c.param := shrinkPermissions
|
||||
@ -272,8 +272,8 @@ class TLEdgeOut(
|
||||
}
|
||||
|
||||
def Release(fromSource: UInt, toAddress: UInt, lgSize: UInt, shrinkPermissions: UInt, data: UInt) = {
|
||||
require (manager.anySupportAcquire)
|
||||
val legal = manager.supportsAcquireFast(toAddress, lgSize)
|
||||
require (manager.anySupportAcquireB)
|
||||
val legal = manager.supportsAcquireBFast(toAddress, lgSize)
|
||||
val c = Wire(new TLBundleC(bundle))
|
||||
c.opcode := TLMessages.ReleaseData
|
||||
c.param := shrinkPermissions
|
||||
|
@ -22,7 +22,8 @@ class TLFilter(select: AddressSet)(implicit p: Parameters) extends LazyModule
|
||||
if (filtered.isEmpty) { None } else {
|
||||
Some(m.copy(
|
||||
address = filtered,
|
||||
supportsAcquire = m.supportsAcquire .intersect(cap),
|
||||
supportsAcquireT = m.supportsAcquireT .intersect(cap),
|
||||
supportsAcquireB = m.supportsAcquireB .intersect(cap),
|
||||
supportsArithmetic = m.supportsArithmetic.intersect(cap),
|
||||
supportsLogical = m.supportsLogical .intersect(cap),
|
||||
supportsGet = m.supportsGet .intersect(cap),
|
||||
|
@ -62,7 +62,7 @@ class TLFragmenter(val minSize: Int, val maxSize: Int, val alwaysMin: Boolean =
|
||||
// We don't support fragmenting to sub-beat accesses
|
||||
require (minSize >= beatBytes)
|
||||
// We can't support devices which are cached on both sides of us
|
||||
require (!edgeOut.manager.anySupportAcquire || !edgeIn.client.anySupportProbe)
|
||||
require (!edgeOut.manager.anySupportAcquireB || !edgeIn.client.anySupportProbe)
|
||||
|
||||
/* The Fragmenter is a bit tricky, because there are 5 sizes in play:
|
||||
* max size -- the maximum transfer size possible
|
||||
|
@ -27,7 +27,7 @@ class TLHintHandler(supportManagers: Boolean = true, supportClients: Boolean = f
|
||||
val edgeOut = node.edgesOut(0)
|
||||
|
||||
// Don't add support for clients if there is no BCE channel
|
||||
val bce = edgeOut.manager.anySupportAcquire && edgeIn.client.anySupportProbe
|
||||
val bce = edgeOut.manager.anySupportAcquireB && edgeIn.client.anySupportProbe
|
||||
require (!supportClients || bce)
|
||||
|
||||
// Does it even make sense to add the HintHandler?
|
||||
|
@ -95,11 +95,11 @@ case class IntAdapterNode(
|
||||
case class IntOutputNode() extends OutputNode(IntImp)
|
||||
case class IntInputNode() extends InputNode(IntImp)
|
||||
|
||||
case class IntBlindOutputNode() extends BlindOutputNode(IntImp)(IntSinkPortParameters(Seq(IntSinkParameters())))
|
||||
case class IntBlindInputNode(num: Int) extends BlindInputNode(IntImp)(IntSourcePortParameters(Seq(IntSourceParameters(num))))
|
||||
case class IntBlindOutputNode() extends BlindOutputNode(IntImp)(Seq(IntSinkPortParameters(Seq(IntSinkParameters()))))
|
||||
case class IntBlindInputNode(num: Int) extends BlindInputNode(IntImp)(Seq(IntSourcePortParameters(Seq(IntSourceParameters(num)))))
|
||||
|
||||
case class IntInternalOutputNode() extends InternalOutputNode(IntImp)(IntSinkPortParameters(Seq(IntSinkParameters())))
|
||||
case class IntInternalInputNode(num: Int) extends InternalInputNode(IntImp)(IntSourcePortParameters(Seq(IntSourceParameters(num))))
|
||||
case class IntInternalOutputNode() extends InternalOutputNode(IntImp)(Seq(IntSinkPortParameters(Seq(IntSinkParameters()))))
|
||||
case class IntInternalInputNode(num: Int) extends InternalInputNode(IntImp)(Seq(IntSourcePortParameters(Seq(IntSourceParameters(num)))))
|
||||
|
||||
class IntXbar()(implicit p: Parameters) extends LazyModule
|
||||
{
|
||||
|
@ -57,7 +57,7 @@ class TLIsolation(fOut: (Bool, UInt) => UInt, fIn: (Bool, UInt) => UInt)(implici
|
||||
ABo(out.a, in .a)
|
||||
ABi(in .d, out.d)
|
||||
|
||||
if (edgeOut.manager.base.anySupportAcquire && edgeOut.client.base.anySupportProbe) {
|
||||
if (edgeOut.manager.base.anySupportAcquireB && edgeOut.client.base.anySupportProbe) {
|
||||
ABi(in .b, out.b)
|
||||
ABo(out.c, in .c)
|
||||
ABo(out.e, in .e)
|
||||
|
@ -42,7 +42,7 @@ class TLMonitor(args: TLMonitorArgs) extends TLMonitorBase(args)
|
||||
val mask = edge.full_mask(bundle)
|
||||
|
||||
when (bundle.opcode === TLMessages.Acquire) {
|
||||
assert (edge.manager.supportsAcquireSafe(edge.address(bundle), bundle.size), "'A' channel carries Acquire type unsupported by manager" + extra)
|
||||
assert (edge.manager.supportsAcquireBSafe(edge.address(bundle), bundle.size), "'A' channel carries Acquire type unsupported by manager" + extra)
|
||||
assert (source_ok, "'A' channel Acquire carries invalid source ID" + extra)
|
||||
assert (bundle.size >= UInt(log2Ceil(edge.manager.beatBytes)), "'A' channel Acquire smaller than a beat" + extra)
|
||||
assert (is_aligned, "'A' channel Acquire address not aligned to size" + extra)
|
||||
@ -189,7 +189,7 @@ class TLMonitor(args: TLMonitorArgs) extends TLMonitorBase(args)
|
||||
}
|
||||
|
||||
when (bundle.opcode === TLMessages.Release) {
|
||||
assert (edge.manager.supportsAcquireSafe(edge.address(bundle), bundle.size), "'C' channel carries Release type unsupported by manager" + extra)
|
||||
assert (edge.manager.supportsAcquireBSafe(edge.address(bundle), bundle.size), "'C' channel carries Release type unsupported by manager" + extra)
|
||||
assert (source_ok, "'C' channel Release carries invalid source ID" + extra)
|
||||
assert (bundle.size >= UInt(log2Ceil(edge.manager.beatBytes)), "'C' channel Release smaller than a beat" + extra)
|
||||
assert (is_aligned, "'C' channel Release address not aligned to size" + extra)
|
||||
@ -198,7 +198,7 @@ class TLMonitor(args: TLMonitorArgs) extends TLMonitorBase(args)
|
||||
}
|
||||
|
||||
when (bundle.opcode === TLMessages.ReleaseData) {
|
||||
assert (edge.manager.supportsAcquireSafe(edge.address(bundle), bundle.size), "'C' channel carries ReleaseData type unsupported by manager" + extra)
|
||||
assert (edge.manager.supportsAcquireBSafe(edge.address(bundle), bundle.size), "'C' channel carries ReleaseData type unsupported by manager" + extra)
|
||||
assert (source_ok, "'C' channel ReleaseData carries invalid source ID" + extra)
|
||||
assert (bundle.size >= UInt(log2Ceil(edge.manager.beatBytes)), "'C' channel ReleaseData smaller than a beat" + extra)
|
||||
assert (is_aligned, "'C' channel ReleaseData address not aligned to size" + extra)
|
||||
@ -409,7 +409,7 @@ class TLMonitor(args: TLMonitorArgs) extends TLMonitorBase(args)
|
||||
val d_last = edge.last(bundle.d.bits, bundle.d.fire())
|
||||
|
||||
if (edge.manager.minLatency > 0) {
|
||||
assert(bundle.a.bits.source =/= bundle.d.bits.source || !bundle.a.valid || !bundle.d.valid, s"'A' and 'D' concurrent, despite minlatency ${edge.manager.minLatency}" + extra)
|
||||
assert(bundle.d.bits.opcode === TLMessages.ReleaseAck || bundle.a.bits.source =/= bundle.d.bits.source || !bundle.a.valid || !bundle.d.valid, s"'A' and 'D' concurrent, despite minlatency ${edge.manager.minLatency}" + extra)
|
||||
}
|
||||
|
||||
val a_set = Wire(init = UInt(0, width = edge.client.endSourceId))
|
||||
|
@ -16,14 +16,9 @@ object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TL
|
||||
{
|
||||
def edgeO(pd: TLClientPortParameters, pu: TLManagerPortParameters): TLEdgeOut = new TLEdgeOut(pd, pu)
|
||||
def edgeI(pd: TLClientPortParameters, pu: TLManagerPortParameters): TLEdgeIn = new TLEdgeIn(pd, pu)
|
||||
def bundleO(eo: Seq[TLEdgeOut]): Vec[TLBundle] = {
|
||||
require (!eo.isEmpty)
|
||||
Vec(eo.size, TLBundle(eo.map(_.bundle).reduce(_.union(_))))
|
||||
}
|
||||
def bundleI(ei: Seq[TLEdgeIn]): Vec[TLBundle] = {
|
||||
require (!ei.isEmpty)
|
||||
Vec(ei.size, TLBundle(ei.map(_.bundle).reduce(_.union(_))))
|
||||
}
|
||||
|
||||
def bundleO(eo: Seq[TLEdgeOut]): Vec[TLBundle] = Vec(eo.size, TLBundle(TLBundleParameters.union(eo.map(_.bundle))))
|
||||
def bundleI(ei: Seq[TLEdgeIn]): Vec[TLBundle] = Vec(ei.size, TLBundle(TLBundleParameters.union(ei.map(_.bundle))))
|
||||
|
||||
def colour = "#000000" // black
|
||||
override def labelI(ei: TLEdgeIn) = (ei.manager.beatBytes * 8).toString
|
||||
@ -120,11 +115,11 @@ case class TLOutputNode() extends OutputNode(TLImp)
|
||||
case class TLInputNode() extends InputNode(TLImp)
|
||||
|
||||
// Nodes used for external ports
|
||||
case class TLBlindOutputNode(portParams: TLManagerPortParameters) extends BlindOutputNode(TLImp)(portParams)
|
||||
case class TLBlindInputNode(portParams: TLClientPortParameters) extends BlindInputNode(TLImp)(portParams)
|
||||
case class TLBlindOutputNode(portParams: Seq[TLManagerPortParameters]) extends BlindOutputNode(TLImp)(portParams)
|
||||
case class TLBlindInputNode(portParams: Seq[TLClientPortParameters]) extends BlindInputNode(TLImp)(portParams)
|
||||
|
||||
case class TLInternalOutputNode(portParams: TLManagerPortParameters) extends InternalOutputNode(TLImp)(portParams)
|
||||
case class TLInternalInputNode(portParams: TLClientPortParameters) extends InternalInputNode(TLImp)(portParams)
|
||||
case class TLInternalOutputNode(portParams: Seq[TLManagerPortParameters]) extends InternalOutputNode(TLImp)(portParams)
|
||||
case class TLInternalInputNode(portParams: Seq[TLClientPortParameters]) extends InternalInputNode(TLImp)(portParams)
|
||||
|
||||
/** Synthesizeable unit tests */
|
||||
import unittest._
|
||||
@ -152,14 +147,9 @@ object TLAsyncImp extends NodeImp[TLAsyncClientPortParameters, TLAsyncManagerPor
|
||||
{
|
||||
def edgeO(pd: TLAsyncClientPortParameters, pu: TLAsyncManagerPortParameters): TLAsyncEdgeParameters = TLAsyncEdgeParameters(pd, pu)
|
||||
def edgeI(pd: TLAsyncClientPortParameters, pu: TLAsyncManagerPortParameters): TLAsyncEdgeParameters = TLAsyncEdgeParameters(pd, pu)
|
||||
def bundleO(eo: Seq[TLAsyncEdgeParameters]): Vec[TLAsyncBundle] = {
|
||||
require (eo.size == 1)
|
||||
Vec(eo.size, new TLAsyncBundle(eo(0).bundle))
|
||||
}
|
||||
def bundleI(ei: Seq[TLAsyncEdgeParameters]): Vec[TLAsyncBundle] = {
|
||||
require (ei.size == 1)
|
||||
Vec(ei.size, new TLAsyncBundle(ei(0).bundle))
|
||||
}
|
||||
|
||||
def bundleO(eo: Seq[TLAsyncEdgeParameters]): Vec[TLAsyncBundle] = Vec(eo.size, new TLAsyncBundle(TLAsyncBundleParameters.union(eo.map(_.bundle))))
|
||||
def bundleI(ei: Seq[TLAsyncEdgeParameters]): Vec[TLAsyncBundle] = Vec(ei.size, new TLAsyncBundle(TLAsyncBundleParameters.union(ei.map(_.bundle))))
|
||||
|
||||
def colour = "#ff0000" // red
|
||||
override def labelI(ei: TLAsyncEdgeParameters) = ei.manager.depth.toString
|
||||
|
@ -12,7 +12,8 @@ case class TLManagerParameters(
|
||||
executable: Boolean = false, // processor can execute from this memory
|
||||
nodePath: Seq[BaseNode] = Seq(),
|
||||
// Supports both Acquire+Release+Finish of these sizes
|
||||
supportsAcquire: TransferSizes = TransferSizes.none,
|
||||
supportsAcquireT: TransferSizes = TransferSizes.none,
|
||||
supportsAcquireB: TransferSizes = TransferSizes.none,
|
||||
supportsArithmetic: TransferSizes = TransferSizes.none,
|
||||
supportsLogical: TransferSizes = TransferSizes.none,
|
||||
supportsGet: TransferSizes = TransferSizes.none,
|
||||
@ -28,10 +29,20 @@ case class TLManagerParameters(
|
||||
|
||||
address.combinations(2).foreach { case Seq(x,y) => require (!x.overlaps(y)) }
|
||||
require (supportsPutFull.contains(supportsPutPartial))
|
||||
require (supportsPutFull.contains(supportsArithmetic))
|
||||
require (supportsPutFull.contains(supportsLogical))
|
||||
require (supportsGet.contains(supportsArithmetic))
|
||||
require (supportsGet.contains(supportsLogical))
|
||||
require (supportsAcquireB.contains(supportsAcquireT))
|
||||
|
||||
// Make sure that the regionType agrees with the capabilities
|
||||
require ((regionType == RegionType.CACHED || regionType == RegionType.TRACKED) != supportsAcquireB.none)
|
||||
require (regionType != RegionType.UNCACHED || supportsGet)
|
||||
|
||||
// Largest support transfer of all types
|
||||
val maxTransfer = List(
|
||||
supportsAcquire.max,
|
||||
supportsAcquireT.max,
|
||||
supportsAcquireB.max,
|
||||
supportsArithmetic.max,
|
||||
supportsLogical.max,
|
||||
supportsGet.max,
|
||||
@ -73,7 +84,8 @@ case class TLManagerPortParameters(
|
||||
def maxTransfer = managers.map(_.maxTransfer).max
|
||||
|
||||
// Operation sizes supported by all outward Managers
|
||||
val allSupportAcquire = managers.map(_.supportsAcquire) .reduce(_ intersect _)
|
||||
val allSupportAcquireT = managers.map(_.supportsAcquireT) .reduce(_ intersect _)
|
||||
val allSupportAcquireB = managers.map(_.supportsAcquireB) .reduce(_ intersect _)
|
||||
val allSupportArithmetic = managers.map(_.supportsArithmetic).reduce(_ intersect _)
|
||||
val allSupportLogical = managers.map(_.supportsLogical) .reduce(_ intersect _)
|
||||
val allSupportGet = managers.map(_.supportsGet) .reduce(_ intersect _)
|
||||
@ -82,7 +94,8 @@ case class TLManagerPortParameters(
|
||||
val allSupportHint = managers.map(_.supportsHint) .reduce(_ intersect _)
|
||||
|
||||
// Operation supported by at least one outward Managers
|
||||
val anySupportAcquire = managers.map(!_.supportsAcquire.none) .reduce(_ || _)
|
||||
val anySupportAcquireT = managers.map(!_.supportsAcquireT.none) .reduce(_ || _)
|
||||
val anySupportAcquireB = managers.map(!_.supportsAcquireB.none) .reduce(_ || _)
|
||||
val anySupportArithmetic = managers.map(!_.supportsArithmetic.none).reduce(_ || _)
|
||||
val anySupportLogical = managers.map(!_.supportsLogical.none) .reduce(_ || _)
|
||||
val anySupportGet = managers.map(!_.supportsGet.none) .reduce(_ || _)
|
||||
@ -122,7 +135,8 @@ case class TLManagerPortParameters(
|
||||
}
|
||||
|
||||
// Check for support of a given operation at a specific address
|
||||
val supportsAcquireSafe = safe_helper(_.supportsAcquire) _
|
||||
val supportsAcquireTSafe = safe_helper(_.supportsAcquireT) _
|
||||
val supportsAcquireBSafe = safe_helper(_.supportsAcquireB) _
|
||||
val supportsArithmeticSafe = safe_helper(_.supportsArithmetic) _
|
||||
val supportsLogicalSafe = safe_helper(_.supportsLogical) _
|
||||
val supportsGetSafe = safe_helper(_.supportsGet) _
|
||||
@ -130,7 +144,8 @@ case class TLManagerPortParameters(
|
||||
val supportsPutPartialSafe = safe_helper(_.supportsPutPartial) _
|
||||
val supportsHintSafe = safe_helper(_.supportsHint) _
|
||||
|
||||
val supportsAcquireFast = fast_helper(_.supportsAcquire) _
|
||||
val supportsAcquireTFast = fast_helper(_.supportsAcquireT) _
|
||||
val supportsAcquireBFast = fast_helper(_.supportsAcquireB) _
|
||||
val supportsArithmeticFast = fast_helper(_.supportsArithmetic) _
|
||||
val supportsLogicalFast = fast_helper(_.supportsLogical) _
|
||||
val supportsGetFast = fast_helper(_.supportsGet) _
|
||||
@ -258,6 +273,15 @@ case class TLBundleParameters(
|
||||
|
||||
object TLBundleParameters
|
||||
{
|
||||
val emptyBundleParams = TLBundleParameters(
|
||||
addressBits = 1,
|
||||
dataBits = 8,
|
||||
sourceBits = 1,
|
||||
sinkBits = 1,
|
||||
sizeBits = 1)
|
||||
|
||||
def union(x: Seq[TLBundleParameters]) = x.foldLeft(emptyBundleParams)((x,y) => x.union(y))
|
||||
|
||||
def apply(client: TLClientPortParameters, manager: TLManagerPortParameters) =
|
||||
new TLBundleParameters(
|
||||
addressBits = log2Up(manager.maxAddress + 1),
|
||||
@ -282,7 +306,21 @@ case class TLEdgeParameters(
|
||||
|
||||
case class TLAsyncManagerPortParameters(depth: Int, base: TLManagerPortParameters) { require (isPow2(depth)) }
|
||||
case class TLAsyncClientPortParameters(base: TLClientPortParameters)
|
||||
case class TLAsyncBundleParameters(depth: Int, base: TLBundleParameters) { require (isPow2(depth)) }
|
||||
|
||||
case class TLAsyncBundleParameters(depth: Int, base: TLBundleParameters)
|
||||
{
|
||||
require (isPow2(depth))
|
||||
def union(x: TLAsyncBundleParameters) = TLAsyncBundleParameters(
|
||||
depth = max(depth, x.depth),
|
||||
base = base.union(x.base))
|
||||
}
|
||||
|
||||
object TLAsyncBundleParameters
|
||||
{
|
||||
val emptyBundleParams = TLAsyncBundleParameters(depth = 1, base = TLBundleParameters.emptyBundleParams)
|
||||
def union(x: Seq[TLAsyncBundleParameters]) = x.foldLeft(emptyBundleParams)((x,y) => x.union(y))
|
||||
}
|
||||
|
||||
case class TLAsyncEdgeParameters(client: TLAsyncClientPortParameters, manager: TLAsyncManagerPortParameters)
|
||||
{
|
||||
val bundle = TLAsyncBundleParameters(manager.depth, TLBundleParameters(client.base, manager.base))
|
||||
@ -296,7 +334,8 @@ object ManagerUnification
|
||||
regionType: RegionType.T,
|
||||
executable: Boolean,
|
||||
lastNode: BaseNode,
|
||||
supportsAcquire: TransferSizes,
|
||||
supportsAcquireT: TransferSizes,
|
||||
supportsAcquireB: TransferSizes,
|
||||
supportsArithmetic: TransferSizes,
|
||||
supportsLogical: TransferSizes,
|
||||
supportsGet: TransferSizes,
|
||||
@ -307,7 +346,8 @@ object ManagerUnification
|
||||
regionType = x.regionType,
|
||||
executable = x.executable,
|
||||
lastNode = x.nodePath.last,
|
||||
supportsAcquire = x.supportsAcquire,
|
||||
supportsAcquireT = x.supportsAcquireT,
|
||||
supportsAcquireB = x.supportsAcquireB,
|
||||
supportsArithmetic = x.supportsArithmetic,
|
||||
supportsLogical = x.supportsLogical,
|
||||
supportsGet = x.supportsGet,
|
||||
|
@ -31,7 +31,7 @@ class TLSourceShrinker(maxInFlight: Int)(implicit p: Parameters) extends LazyMod
|
||||
|
||||
// Acquires cannot pass this adapter; it makes Probes impossible
|
||||
require (!edgeIn.client.anySupportProbe ||
|
||||
!edgeOut.manager.anySupportAcquire)
|
||||
!edgeOut.manager.anySupportAcquireB)
|
||||
|
||||
out.b.ready := Bool(true)
|
||||
out.c.valid := Bool(false)
|
||||
|
@ -84,9 +84,9 @@ class TLToAXI4(idBits: Int, combinational: Boolean = true)(implicit p: Parameter
|
||||
val a_last = edgeIn.last(in.a)
|
||||
|
||||
// Make sure the fields are within the bounds we assumed
|
||||
assert (a_source < UInt(1 << sourceBits))
|
||||
assert (a_size < UInt(1 << sizeBits))
|
||||
assert (a_addr_lo < UInt(1 << addrBits))
|
||||
assert (a_source < UInt(BigInt(1) << sourceBits))
|
||||
assert (a_size < UInt(BigInt(1) << sizeBits))
|
||||
assert (a_addr_lo < UInt(BigInt(1) << addrBits))
|
||||
|
||||
// Carefully pack/unpack fields into the state we send
|
||||
val baseEnd = 0
|
||||
|
@ -147,7 +147,7 @@ class TLWidthWidget(innerBeatBytes: Int)(implicit p: Parameters) extends LazyMod
|
||||
splice(edgeIn, in.a, edgeOut, out.a)
|
||||
splice(edgeOut, out.d, edgeIn, in.d)
|
||||
|
||||
if (edgeOut.manager.anySupportAcquire && edgeIn.client.anySupportProbe) {
|
||||
if (edgeOut.manager.anySupportAcquireB && edgeIn.client.anySupportProbe) {
|
||||
splice(edgeOut, out.b, edgeIn, in.b)
|
||||
splice(edgeIn, in.c, edgeOut, out.c)
|
||||
in.e.ready := out.e.ready
|
||||
|
@ -164,7 +164,7 @@ class TLXbar(policy: TLArbiter.Policy = TLArbiter.lowestIndexFirst)(implicit p:
|
||||
for (o <- 0 until out.size) {
|
||||
val allowI = Seq.tabulate(in.size) { i =>
|
||||
node.edgesIn(i).client.anySupportProbe &&
|
||||
node.edgesOut(o).manager.anySupportAcquire
|
||||
node.edgesOut(o).manager.anySupportAcquireB
|
||||
}
|
||||
TLArbiter(policy)(out(o).a, (beatsAI zip portsAOI(o) ):_*)
|
||||
TLArbiter(policy)(out(o).c, filter(beatsCI zip portsCOI(o), allowI):_*)
|
||||
@ -174,7 +174,7 @@ class TLXbar(policy: TLArbiter.Policy = TLArbiter.lowestIndexFirst)(implicit p:
|
||||
for (i <- 0 until in.size) {
|
||||
val allowO = Seq.tabulate(out.size) { o =>
|
||||
node.edgesIn(i).client.anySupportProbe &&
|
||||
node.edgesOut(o).manager.anySupportAcquire
|
||||
node.edgesOut(o).manager.anySupportAcquireB
|
||||
}
|
||||
TLArbiter(policy)(in(i).b, filter(beatsBO zip portsBIO(i), allowO):_*)
|
||||
TLArbiter(policy)(in(i).d, (beatsDO zip portsDIO(i) ):_*)
|
||||
|
Loading…
Reference in New Issue
Block a user