1
0

uncore: switch to new diplomacy Node API

Most adapters should work on multiple ports.
This patch changes them all.
This commit is contained in:
Wesley W. Terpstra 2017-01-29 15:17:52 -08:00
parent 4d646939b0
commit 972953868c
34 changed files with 1681 additions and 1722 deletions

View File

@ -13,7 +13,7 @@ import uncore.util._
class ScratchpadSlavePort(implicit p: Parameters) extends LazyModule { class ScratchpadSlavePort(implicit p: Parameters) extends LazyModule {
val coreDataBytes = p(XLen)/8 val coreDataBytes = p(XLen)/8
val node = TLManagerNode(TLManagerPortParameters( val node = TLManagerNode(Seq(TLManagerPortParameters(
Seq(TLManagerParameters( Seq(TLManagerParameters(
address = List(AddressSet(0x80000000L, BigInt(p(DataScratchpadSize)-1))), address = List(AddressSet(0x80000000L, BigInt(p(DataScratchpadSize)-1))),
regionType = RegionType.UNCACHED, regionType = RegionType.UNCACHED,
@ -25,7 +25,7 @@ class ScratchpadSlavePort(implicit p: Parameters) extends LazyModule {
supportsGet = TransferSizes(1, coreDataBytes), supportsGet = TransferSizes(1, coreDataBytes),
fifoId = Some(0))), // requests handled in FIFO order fifoId = Some(0))), // requests handled in FIFO order
beatBytes = coreDataBytes, beatBytes = coreDataBytes,
minLatency = 1)) minLatency = 1)))
lazy val module = new LazyModuleImp(this) { lazy val module = new LazyModuleImp(this) {
val io = new Bundle { val io = new Bundle {

View File

@ -31,16 +31,14 @@ object AHBImp extends NodeImp[AHBMasterPortParameters, AHBSlavePortParameters, A
// Nodes implemented inside modules // Nodes implemented inside modules
case class AHBIdentityNode() extends IdentityNode(AHBImp) case class AHBIdentityNode() extends IdentityNode(AHBImp)
case class AHBMasterNode(portParams: AHBMasterPortParameters, numPorts: Range.Inclusive = 1 to 1) case class AHBMasterNode(portParams: Seq[AHBMasterPortParameters]) extends SourceNode(AHBImp)(portParams)
extends SourceNode(AHBImp)(portParams, numPorts) case class AHBSlaveNode(portParams: Seq[AHBSlavePortParameters]) extends SinkNode(AHBImp)(portParams)
case class AHBSlaveNode(portParams: AHBSlavePortParameters, numPorts: Range.Inclusive = 1 to 1) case class AHBNexusNode(
extends SinkNode(AHBImp)(portParams, numPorts)
case class AHBAdapterNode(
masterFn: Seq[AHBMasterPortParameters] => AHBMasterPortParameters, masterFn: Seq[AHBMasterPortParameters] => AHBMasterPortParameters,
slaveFn: Seq[AHBSlavePortParameters] => AHBSlavePortParameters, slaveFn: Seq[AHBSlavePortParameters] => AHBSlavePortParameters,
numMasterPorts: Range.Inclusive = 1 to 1, numMasterPorts: Range.Inclusive = 1 to 999,
numSlavePorts: Range.Inclusive = 1 to 1) numSlavePorts: Range.Inclusive = 1 to 999)
extends InteriorNode(AHBImp)(masterFn, slaveFn, numMasterPorts, numSlavePorts) extends NexusNode(AHBImp)(masterFn, slaveFn, numMasterPorts, numSlavePorts)
// Nodes passed from an inner module // Nodes passed from an inner module
case class AHBOutputNode() extends OutputNode(AHBImp) case class AHBOutputNode() extends OutputNode(AHBImp)

View File

@ -9,13 +9,13 @@ import regmapper._
import scala.math.{min,max} import scala.math.{min,max}
class AHBRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false) class AHBRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false)
extends AHBSlaveNode(AHBSlavePortParameters( extends AHBSlaveNode(Seq(AHBSlavePortParameters(
Seq(AHBSlaveParameters( Seq(AHBSlaveParameters(
address = Seq(address), address = Seq(address),
executable = executable, executable = executable,
supportsWrite = TransferSizes(1, min(address.alignment.toInt, beatBytes * AHBParameters.maxTransfer)), supportsWrite = TransferSizes(1, min(address.alignment.toInt, beatBytes * AHBParameters.maxTransfer)),
supportsRead = TransferSizes(1, min(address.alignment.toInt, beatBytes * AHBParameters.maxTransfer)))), supportsRead = TransferSizes(1, min(address.alignment.toInt, beatBytes * AHBParameters.maxTransfer)))),
beatBytes = beatBytes)) beatBytes = beatBytes)))
{ {
require (address.contiguous) require (address.contiguous)

View File

@ -8,14 +8,14 @@ import diplomacy._
class AHBRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule class AHBRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule
{ {
val node = AHBSlaveNode(AHBSlavePortParameters( val node = AHBSlaveNode(Seq(AHBSlavePortParameters(
Seq(AHBSlaveParameters( Seq(AHBSlaveParameters(
address = List(address), address = List(address),
regionType = RegionType.UNCACHED, regionType = RegionType.UNCACHED,
executable = executable, executable = executable,
supportsRead = TransferSizes(1, beatBytes * AHBParameters.maxTransfer), supportsRead = TransferSizes(1, beatBytes * AHBParameters.maxTransfer),
supportsWrite = TransferSizes(1, beatBytes * AHBParameters.maxTransfer))), supportsWrite = TransferSizes(1, beatBytes * AHBParameters.maxTransfer))),
beatBytes = beatBytes)) beatBytes = beatBytes)))
// We require the address range to include an entire beat (for the write mask) // We require the address range to include an entire beat (for the write mask)
require ((address.mask & (beatBytes-1)) == beatBytes-1) require ((address.mask & (beatBytes-1)) == beatBytes-1)

View File

@ -9,7 +9,7 @@ import regmapper._
import scala.math.{min,max} import scala.math.{min,max}
class AHBFanout()(implicit p: Parameters) extends LazyModule { class AHBFanout()(implicit p: Parameters) extends LazyModule {
val node = AHBAdapterNode( val node = AHBNexusNode(
numSlavePorts = 1 to 1, numSlavePorts = 1 to 1,
numMasterPorts = 1 to 32, numMasterPorts = 1 to 32,
masterFn = { case Seq(m) => m }, masterFn = { case Seq(m) => m },

View File

@ -31,16 +31,14 @@ object APBImp extends NodeImp[APBMasterPortParameters, APBSlavePortParameters, A
// Nodes implemented inside modules // Nodes implemented inside modules
case class APBIdentityNode() extends IdentityNode(APBImp) case class APBIdentityNode() extends IdentityNode(APBImp)
case class APBMasterNode(portParams: APBMasterPortParameters, numPorts: Range.Inclusive = 1 to 1) case class APBMasterNode(portParams: Seq[APBMasterPortParameters]) extends SourceNode(APBImp)(portParams)
extends SourceNode(APBImp)(portParams, numPorts) case class APBSlaveNode(portParams: Seq[APBSlavePortParameters]) extends SinkNode(APBImp)(portParams)
case class APBSlaveNode(portParams: APBSlavePortParameters, numPorts: Range.Inclusive = 1 to 1) case class APBNexusNode(
extends SinkNode(APBImp)(portParams, numPorts)
case class APBAdapterNode(
masterFn: Seq[APBMasterPortParameters] => APBMasterPortParameters, masterFn: Seq[APBMasterPortParameters] => APBMasterPortParameters,
slaveFn: Seq[APBSlavePortParameters] => APBSlavePortParameters, slaveFn: Seq[APBSlavePortParameters] => APBSlavePortParameters,
numMasterPorts: Range.Inclusive = 1 to 1, numMasterPorts: Range.Inclusive = 1 to 1,
numSlavePorts: Range.Inclusive = 1 to 1) numSlavePorts: Range.Inclusive = 1 to 1)
extends InteriorNode(APBImp)(masterFn, slaveFn, numMasterPorts, numSlavePorts) extends NexusNode(APBImp)(masterFn, slaveFn, numMasterPorts, numSlavePorts)
// Nodes passed from an inner module // Nodes passed from an inner module
case class APBOutputNode() extends OutputNode(APBImp) case class APBOutputNode() extends OutputNode(APBImp)

View File

@ -9,13 +9,13 @@ import regmapper._
import scala.math.{min,max} import scala.math.{min,max}
class APBRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false) class APBRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false)
extends APBSlaveNode(APBSlavePortParameters( extends APBSlaveNode(Seq(APBSlavePortParameters(
Seq(APBSlaveParameters( Seq(APBSlaveParameters(
address = Seq(address), address = Seq(address),
executable = executable, executable = executable,
supportsWrite = true, supportsWrite = true,
supportsRead = true)), supportsRead = true)),
beatBytes = beatBytes)) beatBytes = beatBytes)))
{ {
require (address.contiguous) require (address.contiguous)

View File

@ -8,14 +8,14 @@ import diplomacy._
class APBRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule class APBRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule
{ {
val node = APBSlaveNode(APBSlavePortParameters( val node = APBSlaveNode(Seq(APBSlavePortParameters(
Seq(APBSlaveParameters( Seq(APBSlaveParameters(
address = List(address), address = List(address),
regionType = RegionType.UNCACHED, regionType = RegionType.UNCACHED,
executable = executable, executable = executable,
supportsRead = true, supportsRead = true,
supportsWrite = true)), supportsWrite = true)),
beatBytes = beatBytes)) beatBytes = beatBytes)))
// We require the address range to include an entire beat (for the write mask) // We require the address range to include an entire beat (for the write mask)
require ((address.mask & (beatBytes-1)) == beatBytes-1) require ((address.mask & (beatBytes-1)) == beatBytes-1)

View File

@ -9,7 +9,7 @@ import regmapper._
import scala.math.{min,max} import scala.math.{min,max}
class APBFanout()(implicit p: Parameters) extends LazyModule { class APBFanout()(implicit p: Parameters) extends LazyModule {
val node = APBAdapterNode( val node = APBNexusNode(
numSlavePorts = 1 to 1, numSlavePorts = 1 to 1,
numMasterPorts = 1 to 32, numMasterPorts = 1 to 32,
masterFn = { case Seq(m) => m }, masterFn = { case Seq(m) => m },

View File

@ -18,8 +18,8 @@ class AXI4Buffer(aw: Int = 2, w: Int = 2, b: Int = 2, ar: Int = 2, r: Int = 2, p
require (r >= 0) require (r >= 0)
val node = AXI4AdapterNode( val node = AXI4AdapterNode(
masterFn = { case Seq(p) => p }, masterFn = { p => p },
slaveFn = { case Seq(p) => p.copy(minLatency = p.minLatency + min(1,min(aw,ar)) + min(1,min(r,b))) }) slaveFn = { p => p.copy(minLatency = p.minLatency + min(1,min(aw,ar)) + min(1,min(r,b))) })
lazy val module = new LazyModuleImp(this) { lazy val module = new LazyModuleImp(this) {
val io = new Bundle { val io = new Bundle {

View File

@ -23,8 +23,8 @@ class AXI4Fragmenter(lite: Boolean = false, maxInFlight: => Int = 32, combinatio
def mapMaster(m: AXI4MasterParameters) = m.copy(aligned = true) def mapMaster(m: AXI4MasterParameters) = m.copy(aligned = true)
val node = AXI4AdapterNode( val node = AXI4AdapterNode(
masterFn = { case Seq(mp) => mp.copy(masters = mp.masters.map(m => mapMaster(m))) }, masterFn = { mp => mp.copy(masters = mp.masters.map(m => mapMaster(m))) },
slaveFn = { case Seq(sp) => sp.copy(slaves = sp.slaves .map(s => mapSlave(s, sp.beatBytes))) }) slaveFn = { sp => sp.copy(slaves = sp.slaves .map(s => mapSlave(s, sp.beatBytes))) })
lazy val module = new LazyModuleImp(this) { lazy val module = new LazyModuleImp(this) {
val io = new Bundle { val io = new Bundle {
@ -32,8 +32,7 @@ class AXI4Fragmenter(lite: Boolean = false, maxInFlight: => Int = 32, combinatio
val out = node.bundleOut val out = node.bundleOut
} }
val edgeOut = node.edgesOut(0) ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
val edgeIn = node.edgesIn(0)
val slave = edgeOut.slave val slave = edgeOut.slave
val slaves = slave.slaves val slaves = slave.slaves
val beatBytes = slave.beatBytes val beatBytes = slave.beatBytes
@ -136,9 +135,6 @@ class AXI4Fragmenter(lite: Boolean = false, maxInFlight: => Int = 32, combinatio
(out, last, beats) (out, last, beats)
} }
val in = io.in(0)
val out = io.out(0)
// The size to which we will fragment the access // The size to which we will fragment the access
val readSizes1 = slaves.map(s => s.supportsRead .max/beatBytes-1) val readSizes1 = slaves.map(s => s.supportsRead .max/beatBytes-1)
val writeSizes1 = slaves.map(s => s.supportsWrite.max/beatBytes-1) val writeSizes1 = slaves.map(s => s.supportsWrite.max/beatBytes-1)
@ -237,9 +233,9 @@ class AXI4Fragmenter(lite: Boolean = false, maxInFlight: => Int = 32, combinatio
when (out_b.fire()) { r_resp := Mux(b_last, UInt(0), resp) } when (out_b.fire()) { r_resp := Mux(b_last, UInt(0), resp) }
in_b.bits.resp := resp in_b.bits.resp := resp
} }
} }
/* We want to put barriers between the fragments of a fragmented transfer and all other transfers. /* We want to put barriers between the fragments of a fragmented transfer and all other transfers.
* This lets us use very little state to reassemble the fragments (else we need one FIFO per ID). * This lets us use very little state to reassemble the fragments (else we need one FIFO per ID).
* Furthermore, because all the fragments share the same AXI ID, they come back contiguously. * Furthermore, because all the fragments share the same AXI ID, they come back contiguously.
* This guarantees that no other R responses might get mixed between fragments, ensuring that the * This guarantees that no other R responses might get mixed between fragments, ensuring that the
@ -247,8 +243,8 @@ class AXI4Fragmenter(lite: Boolean = false, maxInFlight: => Int = 32, combinatio
* Of course, if you need to fragment, this means there is a potentially hefty serialization cost. * Of course, if you need to fragment, this means there is a potentially hefty serialization cost.
* However, this design allows full concurrency in the common no-fragmentation-needed scenario. * However, this design allows full concurrency in the common no-fragmentation-needed scenario.
*/ */
class AXI4FragmenterSideband(maxInFlight: Int, flow: Boolean = false) extends Module class AXI4FragmenterSideband(maxInFlight: Int, flow: Boolean = false) extends Module
{ {
val io = new QueueIO(Bool(), maxInFlight) val io = new QueueIO(Bool(), maxInFlight)
io.count := UInt(0) io.count := UInt(0)
@ -283,6 +279,7 @@ class AXI4FragmenterSideband(maxInFlight: Int, flow: Boolean = false) extends Mo
is(FIND) { when (io.enq.valid && io.enq.bits && !full) { state := Mux(empty, PASS, WAIT) } } is(FIND) { when (io.enq.valid && io.enq.bits && !full) { state := Mux(empty, PASS, WAIT) } }
is(WAIT) { when (last && io.deq.ready) { state := PASS } } is(WAIT) { when (last && io.deq.ready) { state := PASS } }
} }
}
} }
object AXI4Fragmenter object AXI4Fragmenter

View File

@ -31,16 +31,13 @@ object AXI4Imp extends NodeImp[AXI4MasterPortParameters, AXI4SlavePortParameters
// Nodes implemented inside modules // Nodes implemented inside modules
case class AXI4IdentityNode() extends IdentityNode(AXI4Imp) case class AXI4IdentityNode() extends IdentityNode(AXI4Imp)
case class AXI4MasterNode(portParams: AXI4MasterPortParameters, numPorts: Range.Inclusive = 1 to 1) case class AXI4MasterNode(portParams: Seq[AXI4MasterPortParameters]) extends SourceNode(AXI4Imp)(portParams)
extends SourceNode(AXI4Imp)(portParams, numPorts) case class AXI4SlaveNode(portParams: Seq[AXI4SlavePortParameters]) extends SinkNode(AXI4Imp)(portParams)
case class AXI4SlaveNode(portParams: AXI4SlavePortParameters, numPorts: Range.Inclusive = 1 to 1)
extends SinkNode(AXI4Imp)(portParams, numPorts)
case class AXI4AdapterNode( case class AXI4AdapterNode(
masterFn: Seq[AXI4MasterPortParameters] => AXI4MasterPortParameters, masterFn: AXI4MasterPortParameters => AXI4MasterPortParameters,
slaveFn: Seq[AXI4SlavePortParameters] => AXI4SlavePortParameters, slaveFn: AXI4SlavePortParameters => AXI4SlavePortParameters,
numMasterPorts: Range.Inclusive = 1 to 1, numPorts: Range.Inclusive = 0 to 999)
numSlavePorts: Range.Inclusive = 1 to 1) extends AdapterNode(AXI4Imp)(masterFn, slaveFn, numPorts)
extends InteriorNode(AXI4Imp)(masterFn, slaveFn, numMasterPorts, numSlavePorts)
// Nodes passed from an inner module // Nodes passed from an inner module
case class AXI4OutputNode() extends OutputNode(AXI4Imp) case class AXI4OutputNode() extends OutputNode(AXI4Imp)

View File

@ -9,7 +9,7 @@ import regmapper._
import scala.math.{min,max} import scala.math.{min,max}
class AXI4RegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false) class AXI4RegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false)
extends AXI4SlaveNode(AXI4SlavePortParameters( extends AXI4SlaveNode(Seq(AXI4SlavePortParameters(
Seq(AXI4SlaveParameters( Seq(AXI4SlaveParameters(
address = Seq(address), address = Seq(address),
executable = executable, executable = executable,
@ -17,7 +17,7 @@ class AXI4RegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int
supportsRead = TransferSizes(1, beatBytes), supportsRead = TransferSizes(1, beatBytes),
interleavedId = Some(0))), interleavedId = Some(0))),
beatBytes = beatBytes, beatBytes = beatBytes,
minLatency = min(concurrency, 1))) // the Queue adds at most one cycle minLatency = min(concurrency, 1)))) // the Queue adds at most one cycle
{ {
require (address.contiguous) require (address.contiguous)

View File

@ -8,7 +8,7 @@ import diplomacy._
class AXI4RAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule class AXI4RAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule
{ {
val node = AXI4SlaveNode(AXI4SlavePortParameters( val node = AXI4SlaveNode(Seq(AXI4SlavePortParameters(
Seq(AXI4SlaveParameters( Seq(AXI4SlaveParameters(
address = List(address), address = List(address),
regionType = RegionType.UNCACHED, regionType = RegionType.UNCACHED,
@ -17,7 +17,7 @@ class AXI4RAM(address: AddressSet, executable: Boolean = true, beatBytes: Int =
supportsWrite = TransferSizes(1, beatBytes), supportsWrite = TransferSizes(1, beatBytes),
interleavedId = Some(0))), interleavedId = Some(0))),
beatBytes = beatBytes, beatBytes = beatBytes,
minLatency = 0)) // B responds on same cycle minLatency = 0))) // B responds on same cycle
// We require the address range to include an entire beat (for the write mask) // We require the address range to include an entire beat (for the write mask)
require ((address.mask & (beatBytes-1)) == beatBytes-1) require ((address.mask & (beatBytes-1)) == beatBytes-1)

View File

@ -8,15 +8,15 @@ import config._
import diplomacy._ import diplomacy._
import uncore.tilelink2._ import uncore.tilelink2._
case class AXI4ToTLNode() extends MixedNode(AXI4Imp, TLImp)( case class AXI4ToTLNode() extends MixedAdapterNode(AXI4Imp, TLImp)(
dFn = { case (1, Seq(AXI4MasterPortParameters(masters))) => dFn = { case AXI4MasterPortParameters(masters) =>
Seq(TLClientPortParameters(clients = masters.map { m => TLClientPortParameters(clients = masters.map { m =>
TLClientParameters( TLClientParameters(
sourceId = IdRange(m.id.start << 1, m.id.end << 1), // R+W ids are distinct sourceId = IdRange(m.id.start << 1, m.id.end << 1), // R+W ids are distinct
nodePath = m.nodePath) nodePath = m.nodePath)
})) })
}, },
uFn = { case (1, Seq(mp)) => Seq(AXI4SlavePortParameters( uFn = { mp => AXI4SlavePortParameters(
slaves = mp.managers.map { m => slaves = mp.managers.map { m =>
AXI4SlaveParameters( AXI4SlaveParameters(
address = m.address, address = m.address,
@ -27,10 +27,8 @@ case class AXI4ToTLNode() extends MixedNode(AXI4Imp, TLImp)(
supportsRead = m.supportsGet, supportsRead = m.supportsGet,
interleavedId = Some(0))}, // TL2 never interleaves D beats interleavedId = Some(0))}, // TL2 never interleaves D beats
beatBytes = mp.beatBytes, beatBytes = mp.beatBytes,
minLatency = mp.minLatency)) minLatency = mp.minLatency)
}, })
numPO = 1 to 1,
numPI = 1 to 1)
class AXI4ToTL()(implicit p: Parameters) extends LazyModule class AXI4ToTL()(implicit p: Parameters) extends LazyModule
{ {
@ -42,10 +40,7 @@ class AXI4ToTL()(implicit p: Parameters) extends LazyModule
val out = node.bundleOut val out = node.bundleOut
} }
val in = io.in(0) ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
val out = io.out(0)
val edgeIn = node.edgesIn(0)
val edgeOut = node.edgesOut(0)
val numIds = edgeIn.master.endId val numIds = edgeIn.master.endId
val beatBytes = edgeOut.manager.beatBytes val beatBytes = edgeOut.manager.beatBytes
val countBits = AXI4Parameters.lenBits + (1 << AXI4Parameters.sizeBits) - 1 val countBits = AXI4Parameters.lenBits + (1 << AXI4Parameters.sizeBits) - 1
@ -168,6 +163,7 @@ class AXI4ToTL()(implicit p: Parameters) extends LazyModule
out.c.valid := Bool(false) out.c.valid := Bool(false)
out.e.valid := Bool(false) out.e.valid := Bool(false)
} }
}
} }
class AXI4BundleRError(params: AXI4BundleParameters) extends AXI4BundleBase(params) class AXI4BundleRError(params: AXI4BundleParameters) extends AXI4BundleBase(params)

View File

@ -62,7 +62,7 @@ class TLPLIC(supervisor: Boolean, maxPriorities: Int, address: BigInt = 0xC00000
beatBytes = p(rocket.XLen)/8, beatBytes = p(rocket.XLen)/8,
undefZero = false) undefZero = false)
val intnode = IntAdapterNode( val intnode = IntNexusNode(
numSourcePorts = 0 to 1024, numSourcePorts = 0 to 1024,
numSinkPorts = 0 to 1024, numSinkPorts = 0 to 1024,
sourceFn = { _ => IntSourcePortParameters(Seq(IntSourceParameters(contextsPerHart))) }, sourceFn = { _ => IntSourcePortParameters(Seq(IntSourceParameters(contextsPerHart))) },

View File

@ -6,6 +6,7 @@ import Chisel._
import chisel3.internal.sourceinfo.SourceInfo import chisel3.internal.sourceinfo.SourceInfo
import config._ import config._
import diplomacy._ import diplomacy._
import util.GenericParameterizedBundle
import scala.math.{min,max} import scala.math.{min,max}
// Ensures that all downstream RW managers support Atomic operationss. // Ensures that all downstream RW managers support Atomic operationss.
@ -15,8 +16,8 @@ class TLAtomicAutomata(logical: Boolean = true, arithmetic: Boolean = true, conc
require (concurrency >= 1) require (concurrency >= 1)
val node = TLAdapterNode( val node = TLAdapterNode(
clientFn = { case Seq(cp) => require (!cp.unsafeAtomics); cp.copy(unsafeAtomics = true) }, clientFn = { case cp => require (!cp.unsafeAtomics); cp.copy(unsafeAtomics = true) },
managerFn = { case Seq(mp) => mp.copy(managers = mp.managers.map { m => managerFn = { case mp => mp.copy(managers = mp.managers.map { m =>
val ourSupport = TransferSizes(1, mp.beatBytes) val ourSupport = TransferSizes(1, mp.beatBytes)
def widen(x: TransferSizes) = if (passthrough && x.min <= 2*mp.beatBytes) TransferSizes(1, max(mp.beatBytes, x.max)) else ourSupport def widen(x: TransferSizes) = if (passthrough && x.min <= 2*mp.beatBytes) TransferSizes(1, max(mp.beatBytes, x.max)) else ourSupport
val canDoit = m.supportsPutFull.contains(ourSupport) && m.supportsGet.contains(ourSupport) val canDoit = m.supportsPutFull.contains(ourSupport) && m.supportsGet.contains(ourSupport)
@ -33,10 +34,7 @@ class TLAtomicAutomata(logical: Boolean = true, arithmetic: Boolean = true, conc
val out = node.bundleOut val out = node.bundleOut
} }
val in = io.in(0) ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
val out = io.out(0)
val edgeIn = node.edgesIn(0)
val edgeOut = node.edgesOut(0)
val managers = edgeOut.manager.managers val managers = edgeOut.manager.managers
val beatBytes = edgeOut.manager.beatBytes val beatBytes = edgeOut.manager.beatBytes
@ -72,25 +70,14 @@ class TLAtomicAutomata(logical: Boolean = true, arithmetic: Boolean = true, conc
if (x.map(_ == x(0)).reduce(_ && _)) x(0).containsLg(lgSize) else if (x.map(_ == x(0)).reduce(_ && _)) x(0).containsLg(lgSize) else
Mux1H(select, x.map(_.containsLg(lgSize))) Mux1H(select, x.map(_.containsLg(lgSize)))
val params = TLAtomicAutomata.CAMParams(out.a.bits.params, domainsNeedingHelp.size)
// Do we need to do anything at all? // Do we need to do anything at all?
if (camSize > 0) { if (camSize > 0) {
class CAM_S extends Bundle { val initval = Wire(new TLAtomicAutomata.CAM_S(params))
val state = UInt(width = 2)
}
class CAM_A extends Bundle {
val bits = new TLBundleA(out.a.bits.params)
val fifoId = UInt(width = log2Up(domainsNeedingHelp.size))
val lut = UInt(width = 4)
}
class CAM_D extends Bundle {
val data = UInt(width = out.a.bits.params.dataBits)
}
val initval = Wire(new CAM_S)
initval.state := FREE initval.state := FREE
val cam_s = RegInit(Vec.fill(camSize)(initval)) val cam_s = RegInit(Vec.fill(camSize)(initval))
val cam_a = Reg(Vec(camSize, new CAM_A)) val cam_a = Reg(Vec(camSize, new TLAtomicAutomata.CAM_A(params)))
val cam_d = Reg(Vec(camSize, new CAM_D)) val cam_d = Reg(Vec(camSize, new TLAtomicAutomata.CAM_D(params)))
val cam_free = cam_s.map(_.state === FREE) val cam_free = cam_s.map(_.state === FREE)
val cam_amo = cam_s.map(_.state === AMO) val cam_amo = cam_s.map(_.state === AMO)
@ -274,6 +261,7 @@ class TLAtomicAutomata(logical: Boolean = true, arithmetic: Boolean = true, conc
out.e.valid := Bool(false) out.e.valid := Bool(false)
} }
} }
}
} }
object TLAtomicAutomata object TLAtomicAutomata
@ -284,6 +272,20 @@ object TLAtomicAutomata
atomics.node := x atomics.node := x
atomics.node atomics.node
} }
case class CAMParams(a: TLBundleParameters, domainsNeedingHelp: Int)
class CAM_S(params: CAMParams) extends GenericParameterizedBundle(params) {
val state = UInt(width = 2)
}
class CAM_A(params: CAMParams) extends GenericParameterizedBundle(params) {
val bits = new TLBundleA(params.a)
val fifoId = UInt(width = log2Up(params.domainsNeedingHelp))
val lut = UInt(width = 4)
}
class CAM_D(params: CAMParams) extends GenericParameterizedBundle(params) {
val data = UInt(width = params.a.dataBits)
}
} }
/** Synthesizeable unit tests */ /** Synthesizeable unit tests */

View File

@ -13,11 +13,11 @@ class TLBroadcast(lineBytes: Int, numTrackers: Int = 4, bufferless: Boolean = fa
require (numTrackers > 0) require (numTrackers > 0)
val node = TLAdapterNode( val node = TLAdapterNode(
clientFn = { case Seq(cp) => clientFn = { cp =>
cp.copy(clients = Seq(TLClientParameters( cp.copy(clients = Seq(TLClientParameters(
sourceId = IdRange(0, 1 << log2Ceil(cp.endSourceId*4))))) sourceId = IdRange(0, 1 << log2Ceil(cp.endSourceId*4)))))
}, },
managerFn = { case Seq(mp) => managerFn = { mp =>
mp.copy( mp.copy(
endSinkId = numTrackers, endSinkId = numTrackers,
managers = mp.managers.map { m => managers = mp.managers.map { m =>
@ -56,10 +56,7 @@ class TLBroadcast(lineBytes: Int, numTrackers: Int = 4, bufferless: Boolean = fa
val out = node.bundleOut val out = node.bundleOut
} }
val in = io.in(0) ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
val out = io.out(0)
val edgeIn = node.edgesIn(0)
val edgeOut = node.edgesOut(0)
val clients = edgeIn.client.clients val clients = edgeIn.client.clients
val managers = edgeOut.manager.managers val managers = edgeOut.manager.managers
val lineShift = log2Ceil(lineBytes) val lineShift = log2Ceil(lineBytes)
@ -205,6 +202,7 @@ class TLBroadcast(lineBytes: Int, numTrackers: Int = 4, bufferless: Boolean = fa
out.c.valid := Bool(false) out.c.valid := Bool(false)
out.e.valid := Bool(false) out.e.valid := Bool(false)
} }
}
} }
class TLBroadcastTracker(id: Int, lineBytes: Int, probeCountBits: Int, bufferless: Boolean, edgeIn: TLEdgeIn, edgeOut: TLEdgeOut) extends Module class TLBroadcastTracker(id: Int, lineBytes: Int, probeCountBits: Int, bufferless: Boolean, edgeIn: TLEdgeIn, edgeOut: TLEdgeOut) extends Module

View File

@ -18,8 +18,8 @@ class TLBuffer(a: Int = 2, b: Int = 2, c: Int = 2, d: Int = 2, e: Int = 2, pipe:
require (e >= 0) require (e >= 0)
val node = TLAdapterNode( val node = TLAdapterNode(
clientFn = { case Seq(p) => p.copy(minLatency = p.minLatency + min(1,b) + min(1,c)) }, clientFn = { p => p.copy(minLatency = p.minLatency + min(1,b) + min(1,c)) },
managerFn = { case Seq(p) => p.copy(minLatency = p.minLatency + min(1,a) + min(1,d)) }) managerFn = { p => p.copy(minLatency = p.minLatency + min(1,a) + min(1,d)) })
lazy val module = new LazyModuleImp(this) { lazy val module = new LazyModuleImp(this) {
val io = new Bundle { val io = new Bundle {

View File

@ -12,10 +12,10 @@ import TLMessages._
class TLCacheCork(unsafe: Boolean = false)(implicit p: Parameters) extends LazyModule class TLCacheCork(unsafe: Boolean = false)(implicit p: Parameters) extends LazyModule
{ {
val node = TLAdapterNode( val node = TLAdapterNode(
clientFn = { case Seq(cp) => clientFn = { case cp =>
cp.copy(clients = cp.clients.map { c => c.copy( cp.copy(clients = cp.clients.map { c => c.copy(
sourceId = IdRange(c.sourceId.start*2, c.sourceId.end*2))})}, sourceId = IdRange(c.sourceId.start*2, c.sourceId.end*2))})},
managerFn = { case Seq(mp) => managerFn = { case mp =>
mp.copy(managers = mp.managers.map { m => m.copy( mp.copy(managers = mp.managers.map { m => m.copy(
regionType = if (m.regionType == RegionType.UNCACHED) RegionType.TRACKED else m.regionType, regionType = if (m.regionType == RegionType.UNCACHED) RegionType.TRACKED else m.regionType,
supportsAcquireB = m.supportsGet, supportsAcquireB = m.supportsGet,
@ -27,18 +27,13 @@ class TLCacheCork(unsafe: Boolean = false)(implicit p: Parameters) extends LazyM
val out = node.bundleOut val out = node.bundleOut
} }
val edgeIn = node.edgesIn(0) ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
val edgeOut = node.edgesOut(0)
require (edgeIn.client.clients.size == 1 || unsafe, "Only one client can safely use a TLCacheCork") 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") require (edgeIn.client.clients.filter(_.supportsProbe).size == 1, "Only one caching client allowed")
edgeOut.manager.managers.foreach { case m => edgeOut.manager.managers.foreach { case m =>
require (!m.supportsAcquireB, "Cannot support caches beyond the Cork") 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] // The Cork turns [Acquire=>Get] => [AccessAckData=>GrantData]
// and [ReleaseData=>PutFullData] => [AccessAck=>ReleaseAck] // and [ReleaseData=>PutFullData] => [AccessAck=>ReleaseAck]
// We need to encode information sufficient to reverse the transformation in output. // We need to encode information sufficient to reverse the transformation in output.
@ -115,6 +110,7 @@ class TLCacheCork(unsafe: Boolean = false)(implicit p: Parameters) extends LazyM
out.c.valid := Bool(false) out.c.valid := Bool(false)
out.e.valid := Bool(false) out.e.valid := Bool(false)
} }
}
} }
object TLCacheCork object TLCacheCork

View File

@ -11,8 +11,8 @@ import scala.math.{min,max}
class TLFilter(select: AddressSet)(implicit p: Parameters) extends LazyModule class TLFilter(select: AddressSet)(implicit p: Parameters) extends LazyModule
{ {
val node = TLAdapterNode( val node = TLAdapterNode(
clientFn = { case Seq(cp) => cp }, clientFn = { cp => cp },
managerFn = { case Seq(mp) => managerFn = { mp =>
mp.copy(managers = mp.managers.map { m => mp.copy(managers = mp.managers.map { m =>
val filtered = m.address.map(_.intersect(select)).flatten val filtered = m.address.map(_.intersect(select)).flatten
val alignment = select.alignment /* alignment 0 means 'select' selected everything */ val alignment = select.alignment /* alignment 0 means 'select' selected everything */

View File

@ -41,8 +41,8 @@ class TLFragmenter(val minSize: Int, val maxSize: Int, val alwaysMin: Boolean =
sourceId = IdRange(c.sourceId.start << fragmentBits, c.sourceId.end << fragmentBits)) sourceId = IdRange(c.sourceId.start << fragmentBits, c.sourceId.end << fragmentBits))
val node = TLAdapterNode( val node = TLAdapterNode(
clientFn = { case Seq(c) => c.copy(clients = c.clients.map(mapClient)) }, clientFn = { c => c.copy(clients = c.clients.map(mapClient)) },
managerFn = { case Seq(m) => m.copy(managers = m.managers.map(mapManager)) }) managerFn = { m => m.copy(managers = m.managers.map(mapManager)) })
lazy val module = new LazyModuleImp(this) { lazy val module = new LazyModuleImp(this) {
val io = new Bundle { val io = new Bundle {
@ -50,9 +50,8 @@ class TLFragmenter(val minSize: Int, val maxSize: Int, val alwaysMin: Boolean =
val out = node.bundleOut val out = node.bundleOut
} }
((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
// All managers must share a common FIFO domain (responses might end up interleaved) // All managers must share a common FIFO domain (responses might end up interleaved)
val edgeOut = node.edgesOut(0)
val edgeIn = node.edgesIn(0)
val manager = edgeOut.manager val manager = edgeOut.manager
val managers = manager.managers val managers = manager.managers
val beatBytes = manager.beatBytes val beatBytes = manager.beatBytes
@ -129,9 +128,6 @@ class TLFragmenter(val minSize: Int, val maxSize: Int, val alwaysMin: Boolean =
* put1 put1 0 ack1 0 ack1 0 0 * put1 put1 0 ack1 0 ack1 0 0
*/ */
val in = io.in(0)
val out = io.out(0)
val counterBits = log2Up(maxSize/beatBytes) val counterBits = log2Up(maxSize/beatBytes)
val maxDownSize = if (alwaysMin) minSize else manager.maxTransfer val maxDownSize = if (alwaysMin) minSize else manager.maxTransfer
@ -249,6 +245,7 @@ class TLFragmenter(val minSize: Int, val maxSize: Int, val alwaysMin: Boolean =
out.c.valid := Bool(false) out.c.valid := Bool(false)
out.e.valid := Bool(false) out.e.valid := Bool(false)
} }
}
} }
object TLFragmenter object TLFragmenter

View File

@ -12,8 +12,8 @@ import diplomacy._
class TLHintHandler(supportManagers: Boolean = true, supportClients: Boolean = false, passthrough: Boolean = true)(implicit p: Parameters) extends LazyModule class TLHintHandler(supportManagers: Boolean = true, supportClients: Boolean = false, passthrough: Boolean = true)(implicit p: Parameters) extends LazyModule
{ {
val node = TLAdapterNode( val node = TLAdapterNode(
clientFn = { case Seq(c) => if (!supportClients) c else c.copy(minLatency = min(1, c.minLatency), clients = c.clients .map(_.copy(supportsHint = TransferSizes(1, c.maxTransfer)))) }, clientFn = { c => if (!supportClients) c else c.copy(minLatency = min(1, c.minLatency), clients = c.clients .map(_.copy(supportsHint = TransferSizes(1, c.maxTransfer)))) },
managerFn = { case Seq(m) => if (!supportManagers) m else m.copy(minLatency = min(1, m.minLatency), managers = m.managers.map(_.copy(supportsHint = TransferSizes(1, m.maxTransfer)))) }) managerFn = { m => if (!supportManagers) m else m.copy(minLatency = min(1, m.minLatency), managers = m.managers.map(_.copy(supportsHint = TransferSizes(1, m.maxTransfer)))) })
lazy val module = new LazyModuleImp(this) { lazy val module = new LazyModuleImp(this) {
val io = new Bundle { val io = new Bundle {
@ -21,11 +21,7 @@ class TLHintHandler(supportManagers: Boolean = true, supportClients: Boolean = f
val out = node.bundleOut val out = node.bundleOut
} }
val in = io.in(0) ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
val out = io.out(0)
val edgeIn = node.edgesIn(0)
val edgeOut = node.edgesOut(0)
// Don't add support for clients if there is no BCE channel // Don't add support for clients if there is no BCE channel
val bce = edgeOut.manager.anySupportAcquireB && edgeIn.client.anySupportProbe val bce = edgeOut.manager.anySupportAcquireB && edgeIn.client.anySupportProbe
require (!supportClients || bce) require (!supportClients || bce)
@ -96,6 +92,7 @@ class TLHintHandler(supportManagers: Boolean = true, supportClients: Boolean = f
out.e.valid := Bool(false) out.e.valid := Bool(false)
} }
} }
}
} }
object TLHintHandler object TLHintHandler

View File

@ -81,16 +81,16 @@ object IntImp extends NodeImp[IntSourcePortParameters, IntSinkPortParameters, In
case class IntIdentityNode() extends IdentityNode(IntImp) case class IntIdentityNode() extends IdentityNode(IntImp)
case class IntSourceNode(num: Int) extends SourceNode(IntImp)( case class IntSourceNode(num: Int) extends SourceNode(IntImp)(
IntSourcePortParameters(Seq(IntSourceParameters(num))), (if (num == 0) 0 else 1) to 1) if (num == 0) Seq() else Seq(IntSourcePortParameters(Seq(IntSourceParameters(num)))))
case class IntSinkNode() extends SinkNode(IntImp)( case class IntSinkNode() extends SinkNode(IntImp)(
IntSinkPortParameters(Seq(IntSinkParameters()))) Seq(IntSinkPortParameters(Seq(IntSinkParameters()))))
case class IntAdapterNode( case class IntNexusNode(
sourceFn: Seq[IntSourcePortParameters] => IntSourcePortParameters, sourceFn: Seq[IntSourcePortParameters] => IntSourcePortParameters,
sinkFn: Seq[IntSinkPortParameters] => IntSinkPortParameters, sinkFn: Seq[IntSinkPortParameters] => IntSinkPortParameters,
numSourcePorts: Range.Inclusive = 1 to 1, numSourcePorts: Range.Inclusive = 0 to 128,
numSinkPorts: Range.Inclusive = 1 to 1) numSinkPorts: Range.Inclusive = 0 to 128)
extends InteriorNode(IntImp)(sourceFn, sinkFn, numSourcePorts, numSinkPorts) extends NexusNode(IntImp)(sourceFn, sinkFn, numSourcePorts, numSinkPorts)
case class IntOutputNode() extends OutputNode(IntImp) case class IntOutputNode() extends OutputNode(IntImp)
case class IntInputNode() extends InputNode(IntImp) case class IntInputNode() extends InputNode(IntImp)
@ -103,9 +103,7 @@ case class IntInternalInputNode(num: Int) extends InternalInputNode(IntImp)(Seq(
class IntXbar()(implicit p: Parameters) extends LazyModule class IntXbar()(implicit p: Parameters) extends LazyModule
{ {
val intnode = IntAdapterNode( val intnode = IntNexusNode(
numSourcePorts = 0 to 128,
numSinkPorts = 0 to 128,
sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) }, sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) },
sourceFn = { seq => sourceFn = { seq =>
IntSourcePortParameters((seq zip seq.map(_.num).scanLeft(0)(_+_).init).map { IntSourcePortParameters((seq zip seq.map(_.num).scanLeft(0)(_+_).init).map {

View File

@ -86,29 +86,33 @@ object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TL
// Nodes implemented inside modules // Nodes implemented inside modules
case class TLIdentityNode() extends IdentityNode(TLImp) case class TLIdentityNode() extends IdentityNode(TLImp)
case class TLClientNode(portParams: TLClientPortParameters, numPorts: Range.Inclusive = 1 to 1) case class TLClientNode(portParams: Seq[TLClientPortParameters]) extends SourceNode(TLImp)(portParams)
extends SourceNode(TLImp)(portParams, numPorts) case class TLManagerNode(portParams: Seq[TLManagerPortParameters]) extends SinkNode(TLImp)(portParams)
case class TLManagerNode(portParams: TLManagerPortParameters, numPorts: Range.Inclusive = 1 to 1)
extends SinkNode(TLImp)(portParams, numPorts)
object TLClientNode object TLClientNode
{ {
def apply(params: TLClientParameters) = def apply(params: TLClientParameters) =
new TLClientNode(TLClientPortParameters(Seq(params)), 1 to 1) new TLClientNode(Seq(TLClientPortParameters(Seq(params))))
} }
object TLManagerNode object TLManagerNode
{ {
def apply(beatBytes: Int, params: TLManagerParameters) = def apply(beatBytes: Int, params: TLManagerParameters) =
new TLManagerNode(TLManagerPortParameters(Seq(params), beatBytes, minLatency = 0), 1 to 1) new TLManagerNode(Seq(TLManagerPortParameters(Seq(params), beatBytes, minLatency = 0)))
} }
case class TLAdapterNode( case class TLAdapterNode(
clientFn: TLClientPortParameters => TLClientPortParameters,
managerFn: TLManagerPortParameters => TLManagerPortParameters,
num: Range.Inclusive = 0 to 999)
extends AdapterNode(TLImp)(clientFn, managerFn, num)
case class TLNexusNode(
clientFn: Seq[TLClientPortParameters] => TLClientPortParameters, clientFn: Seq[TLClientPortParameters] => TLClientPortParameters,
managerFn: Seq[TLManagerPortParameters] => TLManagerPortParameters, managerFn: Seq[TLManagerPortParameters] => TLManagerPortParameters,
numClientPorts: Range.Inclusive = 1 to 1, numClientPorts: Range.Inclusive = 1 to 999,
numManagerPorts: Range.Inclusive = 1 to 1) numManagerPorts: Range.Inclusive = 1 to 999)
extends InteriorNode(TLImp)(clientFn, managerFn, numClientPorts, numManagerPorts) extends NexusNode(TLImp)(clientFn, managerFn, numClientPorts, numManagerPorts)
// Nodes passed from an inner module // Nodes passed from an inner module
case class TLOutputNode() extends OutputNode(TLImp) case class TLOutputNode() extends OutputNode(TLImp)
@ -169,17 +173,15 @@ case class TLAsyncIdentityNode() extends IdentityNode(TLAsyncImp)
case class TLAsyncOutputNode() extends OutputNode(TLAsyncImp) case class TLAsyncOutputNode() extends OutputNode(TLAsyncImp)
case class TLAsyncInputNode() extends InputNode(TLAsyncImp) case class TLAsyncInputNode() extends InputNode(TLAsyncImp)
case class TLAsyncSourceNode(sync: Int) extends MixedNode(TLImp, TLAsyncImp)( case class TLAsyncSourceNode(sync: Int)
dFn = { case (1, Seq(p)) => Seq(TLAsyncClientPortParameters(p)) }, extends MixedAdapterNode(TLImp, TLAsyncImp)(
uFn = { case (1, Seq(p)) => Seq(p.base.copy(minLatency = sync+1)) }, // discard cycles in other clock domain dFn = { p => TLAsyncClientPortParameters(p) },
numPO = 1 to 1, uFn = { p => p.base.copy(minLatency = sync+1) }) // discard cycles in other clock domain
numPI = 1 to 1)
case class TLAsyncSinkNode(depth: Int, sync: Int) extends MixedNode(TLAsyncImp, TLImp)( case class TLAsyncSinkNode(depth: Int, sync: Int)
dFn = { case (1, Seq(p)) => Seq(p.base.copy(minLatency = sync+1)) }, extends MixedAdapterNode(TLAsyncImp, TLImp)(
uFn = { case (1, Seq(p)) => Seq(TLAsyncManagerPortParameters(depth, p)) }, dFn = { p => p.base.copy(minLatency = sync+1) },
numPO = 1 to 1, uFn = { p => TLAsyncManagerPortParameters(depth, p) })
numPI = 1 to 1)
object TLRationalImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TLEdgeParameters, TLEdgeParameters, TLRationalBundle] object TLRationalImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TLEdgeParameters, TLEdgeParameters, TLRationalBundle]
{ {
@ -205,14 +207,12 @@ case class TLRationalIdentityNode() extends IdentityNode(TLRationalImp)
case class TLRationalOutputNode() extends OutputNode(TLRationalImp) case class TLRationalOutputNode() extends OutputNode(TLRationalImp)
case class TLRationalInputNode() extends InputNode(TLRationalImp) case class TLRationalInputNode() extends InputNode(TLRationalImp)
case class TLRationalSourceNode() extends MixedNode(TLImp, TLRationalImp)( case class TLRationalSourceNode()
dFn = { case (_, s) => s }, extends MixedAdapterNode(TLImp, TLRationalImp)(
uFn = { case (_, s) => s.map(p => p.copy(minLatency = 1)) }, // discard cycles from other clock domain dFn = { p => p },
numPO = 0 to 999, uFn = { p => p.copy(minLatency = 1) }) // discard cycles from other clock domain
numPI = 0 to 999)
case class TLRationalSinkNode() extends MixedNode(TLRationalImp, TLImp)( case class TLRationalSinkNode()
dFn = { case (_, s) => s.map(p => p.copy(minLatency = 1)) }, extends MixedAdapterNode(TLRationalImp, TLImp)(
uFn = { case (_, s) => s }, dFn = { p => p.copy(minLatency = 1) },
numPO = 0 to 999, uFn = { p => p })
numPI = 0 to 999)

View File

@ -5,6 +5,7 @@ package uncore.tilelink2
import Chisel._ import Chisel._
import config._ import config._
import diplomacy._ import diplomacy._
import util.GenericParameterizedBundle
// We detect concurrent puts that put memory into an undefined state. // We detect concurrent puts that put memory into an undefined state.
// put0, put0Ack, put1, put1Ack => ok: defined // put0, put0Ack, put1, put1Ack => ok: defined
@ -31,13 +32,8 @@ class TLRAMModel(log: String = "")(implicit p: Parameters) extends LazyModule
val out = node.bundleOut val out = node.bundleOut
} }
// !!! support multiple clients via clock division ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
require (io.out.size == 1) val edge = edgeIn
val in = io.in(0)
val out = io.out(0)
val edge = node.edgesIn(0)
val endAddress = edge.manager.maxAddress + 1 val endAddress = edge.manager.maxAddress + 1
val endSourceId = edge.client.endSourceId val endSourceId = edge.client.endSourceId
val maxTransfer = edge.manager.maxTransfer val maxTransfer = edge.manager.maxTransfer
@ -71,18 +67,10 @@ class TLRAMModel(log: String = "")(implicit p: Parameters) extends LazyModule
in.c.ready := Bool(true) in.c.ready := Bool(true)
in.e.ready := Bool(true) in.e.ready := Bool(true)
class ByteMonitor extends Bundle { val params = TLRAMModel.MonitorParameters(addressBits, sizeBits)
val valid = Bool()
val value = UInt(width = 8)
}
class FlightMonitor extends Bundle {
val base = UInt(width = addressBits)
val size = UInt(width = sizeBits)
val opcode = UInt(width = 3)
}
// Infer as simple dual port BRAM/M10k with write-first/new-data semantics (bypass needed) // Infer as simple dual port BRAM/M10k with write-first/new-data semantics (bypass needed)
val shadow = Seq.fill(beatBytes) { Mem(endAddressHi, new ByteMonitor) } val shadow = Seq.fill(beatBytes) { Mem(endAddressHi, new TLRAMModel.ByteMonitor(params)) }
val inc_bytes = Seq.fill(beatBytes) { Mem(endAddressHi, UInt(width = countBits)) } val inc_bytes = Seq.fill(beatBytes) { Mem(endAddressHi, UInt(width = countBits)) }
val dec_bytes = Seq.fill(beatBytes) { Mem(endAddressHi, UInt(width = countBits)) } val dec_bytes = Seq.fill(beatBytes) { Mem(endAddressHi, UInt(width = countBits)) }
val inc_trees = Seq.tabulate(decTrees) { i => Mem(endAddressHi >> (i+1), UInt(width = countBits)) } val inc_trees = Seq.tabulate(decTrees) { i => Mem(endAddressHi >> (i+1), UInt(width = countBits)) }
@ -95,11 +83,11 @@ class TLRAMModel(log: String = "")(implicit p: Parameters) extends LazyModule
val dec_trees_wen = Wire(init = Fill(decTrees, wipe)) val dec_trees_wen = Wire(init = Fill(decTrees, wipe))
// This must be registers b/c we build a CAM from it // This must be registers b/c we build a CAM from it
val flight = Reg(Vec(endSourceId, new FlightMonitor)) val flight = Reg(Vec(endSourceId, new TLRAMModel.FlightMonitor(params)))
val valid = Reg(Vec(endSourceId, Bool())) val valid = Reg(Vec(endSourceId, Bool()))
// We want to cross flight data from A to D in the same cycle (for combinational TL2 devices) // We want to cross flight data from A to D in the same cycle (for combinational TL2 devices)
val a_flight = Wire(new FlightMonitor) val a_flight = Wire(new TLRAMModel.FlightMonitor(params))
a_flight.base := edge.address(in.a.bits) a_flight.base := edge.address(in.a.bits)
a_flight.size := edge.size(in.a.bits) a_flight.size := edge.size(in.a.bits)
a_flight.opcode := in.a.bits.opcode a_flight.opcode := in.a.bits.opcode
@ -169,7 +157,7 @@ class TLRAMModel(log: String = "")(implicit p: Parameters) extends LazyModule
val a_waddr = Mux(wipe, wipeIndex, a_addr_hi) val a_waddr = Mux(wipe, wipeIndex, a_addr_hi)
for (i <- 0 until beatBytes) { for (i <- 0 until beatBytes) {
val data = Wire(new ByteMonitor) val data = Wire(new TLRAMModel.ByteMonitor(params))
val busy = a_inc(i) =/= a_dec(i) + (!a_first).asUInt val busy = a_inc(i) =/= a_dec(i) + (!a_first).asUInt
val amo = a.opcode === TLMessages.ArithmeticData || a.opcode === TLMessages.LogicalData val amo = a.opcode === TLMessages.ArithmeticData || a.opcode === TLMessages.LogicalData
data.valid := Mux(wipe, Bool(false), (!busy || a_fifo) && !amo) data.valid := Mux(wipe, Bool(false), (!busy || a_fifo) && !amo)
@ -295,4 +283,20 @@ class TLRAMModel(log: String = "")(implicit p: Parameters) extends LazyModule
} }
} }
} }
}
}
object TLRAMModel
{
case class MonitorParameters(addressBits: Int, sizeBits: Int)
class ByteMonitor(params: MonitorParameters) extends GenericParameterizedBundle(params) {
val valid = Bool()
val value = UInt(width = 8)
}
class FlightMonitor(params: MonitorParameters) extends GenericParameterizedBundle(params) {
val base = UInt(width = params.addressBits)
val size = UInt(width = params.sizeBits)
val opcode = UInt(width = 3)
}
} }

View File

@ -9,7 +9,7 @@ import regmapper._
import scala.math.{min,max} import scala.math.{min,max}
class TLRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false) class TLRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false)
extends TLManagerNode(TLManagerPortParameters( extends TLManagerNode(Seq(TLManagerPortParameters(
Seq(TLManagerParameters( Seq(TLManagerParameters(
address = Seq(address), address = Seq(address),
executable = executable, executable = executable,
@ -18,7 +18,7 @@ class TLRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int =
supportsPutFull = TransferSizes(1, beatBytes), supportsPutFull = TransferSizes(1, beatBytes),
fifoId = Some(0))), // requests are handled in order fifoId = Some(0))), // requests are handled in order
beatBytes = beatBytes, beatBytes = beatBytes,
minLatency = min(concurrency, 1))) // the Queue adds at most one cycle minLatency = min(concurrency, 1)))) // the Queue adds at most one cycle
{ {
require (address.contiguous) require (address.contiguous)

View File

@ -8,7 +8,7 @@ import diplomacy._
class TLRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule class TLRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule
{ {
val node = TLManagerNode(TLManagerPortParameters( val node = TLManagerNode(Seq(TLManagerPortParameters(
Seq(TLManagerParameters( Seq(TLManagerParameters(
address = List(address), address = List(address),
regionType = RegionType.UNCACHED, regionType = RegionType.UNCACHED,
@ -18,7 +18,7 @@ class TLRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)
supportsPutFull = TransferSizes(1, beatBytes), supportsPutFull = TransferSizes(1, beatBytes),
fifoId = Some(0))), // requests are handled in order fifoId = Some(0))), // requests are handled in order
beatBytes = beatBytes, beatBytes = beatBytes,
minLatency = 1)) // no bypass needed for this device minLatency = 1))) // no bypass needed for this device
// We require the address range to include an entire beat (for the write mask) // We require the address range to include an entire beat (for the write mask)
require ((address.mask & (beatBytes-1)) == beatBytes-1) require ((address.mask & (beatBytes-1)) == beatBytes-1)

View File

@ -15,8 +15,8 @@ class TLSourceShrinker(maxInFlight: Int)(implicit p: Parameters) extends LazyMod
private val client = TLClientParameters(sourceId = IdRange(0, maxInFlight)) private val client = TLClientParameters(sourceId = IdRange(0, maxInFlight))
val node = TLAdapterNode( val node = TLAdapterNode(
// We erase all client information since we crush the source Ids // We erase all client information since we crush the source Ids
clientFn = { case _ => TLClientPortParameters(clients = Seq(client)) }, clientFn = { _ => TLClientPortParameters(clients = Seq(client)) },
managerFn = { case Seq(mp) => mp }) managerFn = { mp => mp })
lazy val module = new LazyModuleImp(this) { lazy val module = new LazyModuleImp(this) {
val io = new Bundle { val io = new Bundle {
@ -24,11 +24,7 @@ class TLSourceShrinker(maxInFlight: Int)(implicit p: Parameters) extends LazyMod
val out = node.bundleOut val out = node.bundleOut
} }
val edgeIn = node.edgesIn(0) ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
val edgeOut = node.edgesOut(0)
val in = io.in(0)
val out = io.out(0)
// Acquires cannot pass this adapter; it makes Probes impossible // Acquires cannot pass this adapter; it makes Probes impossible
require (!edgeIn.client.anySupportProbe || require (!edgeIn.client.anySupportProbe ||
!edgeOut.manager.anySupportAcquireB) !edgeOut.manager.anySupportAcquireB)
@ -74,6 +70,7 @@ class TLSourceShrinker(maxInFlight: Int)(implicit p: Parameters) extends LazyMod
allocated := (allocated | alloc_id) & ~free_id allocated := (allocated | alloc_id) & ~free_id
} }
} }
}
} }
object TLSourceShrinker object TLSourceShrinker

View File

@ -10,12 +10,12 @@ import uncore.ahb._
import scala.math.{min, max} import scala.math.{min, max}
import AHBParameters._ import AHBParameters._
case class TLToAHBNode() extends MixedNode(TLImp, AHBImp)( case class TLToAHBNode() extends MixedAdapterNode(TLImp, AHBImp)(
dFn = { case (1, Seq(TLClientPortParameters(clients, unsafeAtomics, minLatency))) => dFn = { case TLClientPortParameters(clients, unsafeAtomics, minLatency) =>
val masters = clients.map { case c => AHBMasterParameters(nodePath = c.nodePath) } val masters = clients.map { case c => AHBMasterParameters(nodePath = c.nodePath) }
Seq(AHBMasterPortParameters(masters)) AHBMasterPortParameters(masters)
}, },
uFn = { case (1, Seq(AHBSlavePortParameters(slaves, beatBytes))) => uFn = { case AHBSlavePortParameters(slaves, beatBytes) =>
val managers = slaves.map { case s => val managers = slaves.map { case s =>
TLManagerParameters( TLManagerParameters(
address = s.address, address = s.address,
@ -26,10 +26,8 @@ case class TLToAHBNode() extends MixedNode(TLImp, AHBImp)(
supportsPutFull = s.supportsWrite, // but not PutPartial supportsPutFull = s.supportsWrite, // but not PutPartial
fifoId = Some(0)) // a common FIFO domain fifoId = Some(0)) // a common FIFO domain
} }
Seq(TLManagerPortParameters(managers, beatBytes, 1, 1)) TLManagerPortParameters(managers, beatBytes, 1, 1)
}, })
numPO = 1 to 1,
numPI = 1 to 1)
class TLToAHB(combinational: Boolean = true)(implicit p: Parameters) extends LazyModule class TLToAHB(combinational: Boolean = true)(implicit p: Parameters) extends LazyModule
{ {
@ -41,10 +39,7 @@ class TLToAHB(combinational: Boolean = true)(implicit p: Parameters) extends Laz
val out = node.bundleOut val out = node.bundleOut
} }
val in = io.in(0) ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
val out = io.out(0)
val edgeIn = node.edgesIn(0)
val edgeOut = node.edgesOut(0)
val beatBytes = edgeOut.slave.beatBytes val beatBytes = edgeOut.slave.beatBytes
val maxTransfer = edgeOut.slave.maxTransfer val maxTransfer = edgeOut.slave.maxTransfer
val lgMax = log2Ceil(maxTransfer) val lgMax = log2Ceil(maxTransfer)
@ -127,6 +122,7 @@ class TLToAHB(combinational: Boolean = true)(implicit p: Parameters) extends Laz
out.hprot := PROT_DEFAULT out.hprot := PROT_DEFAULT
out.hwdata := RegEnable(a.bits.data, a.fire()) out.hwdata := RegEnable(a.bits.data, a.fire())
} }
}
} }
object TLToAHB object TLToAHB

View File

@ -10,12 +10,12 @@ import uncore.apb._
import scala.math.{min, max} import scala.math.{min, max}
import APBParameters._ import APBParameters._
case class TLToAPBNode() extends MixedNode(TLImp, APBImp)( case class TLToAPBNode() extends MixedAdapterNode(TLImp, APBImp)(
dFn = { case (1, Seq(TLClientPortParameters(clients, unsafeAtomics, minLatency))) => dFn = { case TLClientPortParameters(clients, unsafeAtomics, minLatency) =>
val masters = clients.map { case c => APBMasterParameters(nodePath = c.nodePath) } val masters = clients.map { case c => APBMasterParameters(nodePath = c.nodePath) }
Seq(APBMasterPortParameters(masters)) APBMasterPortParameters(masters)
}, },
uFn = { case (1, Seq(APBSlavePortParameters(slaves, beatBytes))) => uFn = { case APBSlavePortParameters(slaves, beatBytes) =>
val managers = slaves.map { case s => val managers = slaves.map { case s =>
TLManagerParameters( TLManagerParameters(
address = s.address, address = s.address,
@ -27,10 +27,8 @@ case class TLToAPBNode() extends MixedNode(TLImp, APBImp)(
supportsPutFull = if (s.supportsWrite) TransferSizes(1, beatBytes) else TransferSizes.none, supportsPutFull = if (s.supportsWrite) TransferSizes(1, beatBytes) else TransferSizes.none,
fifoId = Some(0)) // a common FIFO domain fifoId = Some(0)) // a common FIFO domain
} }
Seq(TLManagerPortParameters(managers, beatBytes, 1, 0)) TLManagerPortParameters(managers, beatBytes, 1, 0)
}, })
numPO = 1 to 1,
numPI = 1 to 1)
class TLToAPB(combinational: Boolean = true)(implicit p: Parameters) extends LazyModule class TLToAPB(combinational: Boolean = true)(implicit p: Parameters) extends LazyModule
{ {
@ -42,10 +40,7 @@ class TLToAPB(combinational: Boolean = true)(implicit p: Parameters) extends Laz
val out = node.bundleOut val out = node.bundleOut
} }
val in = io.in(0) ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
val out = io.out(0)
val edgeIn = node.edgesIn(0)
val edgeOut = node.edgesOut(0)
val beatBytes = edgeOut.slave.beatBytes val beatBytes = edgeOut.slave.beatBytes
val lgBytes = log2Ceil(beatBytes) val lgBytes = log2Ceil(beatBytes)
@ -88,6 +83,7 @@ class TLToAPB(combinational: Boolean = true)(implicit p: Parameters) extends Laz
d.bits := edgeIn.AccessAck(a.bits, UInt(0), out.prdata, out.pslverr) d.bits := edgeIn.AccessAck(a.bits, UInt(0), out.prdata, out.pslverr)
d.bits.opcode := Mux(a_write, TLMessages.AccessAck, TLMessages.AccessAckData) d.bits.opcode := Mux(a_write, TLMessages.AccessAck, TLMessages.AccessAckData)
} }
}
} }
object TLToAPB object TLToAPB

View File

@ -10,16 +10,16 @@ import util.PositionalMultiQueue
import uncore.axi4._ import uncore.axi4._
import scala.math.{min, max} import scala.math.{min, max}
case class TLToAXI4Node(idBits: Int) extends MixedNode(TLImp, AXI4Imp)( case class TLToAXI4Node(idBits: Int) extends MixedAdapterNode(TLImp, AXI4Imp)(
dFn = { case (1, _) => dFn = { _ =>
// We must erase all client information, because we crush their source Ids // We must erase all client information, because we crush their source Ids
val masters = Seq( val masters = Seq(
AXI4MasterParameters( AXI4MasterParameters(
id = IdRange(0, 1 << idBits), id = IdRange(0, 1 << idBits),
aligned = true)) aligned = true))
Seq(AXI4MasterPortParameters(masters)) AXI4MasterPortParameters(masters)
}, },
uFn = { case (1, Seq(p)) => Seq(TLManagerPortParameters( uFn = { p => TLManagerPortParameters(
managers = p.slaves.map { case s => managers = p.slaves.map { case s =>
TLManagerParameters( TLManagerParameters(
address = s.address, address = s.address,
@ -31,10 +31,8 @@ case class TLToAXI4Node(idBits: Int) extends MixedNode(TLImp, AXI4Imp)(
supportsPutPartial = s.supportsWrite)}, supportsPutPartial = s.supportsWrite)},
// AXI4 is NEVER fifo in TL sense (R+W are independent) // AXI4 is NEVER fifo in TL sense (R+W are independent)
beatBytes = p.beatBytes, beatBytes = p.beatBytes,
minLatency = p.minLatency)) minLatency = p.minLatency)
}, })
numPO = 1 to 1,
numPI = 1 to 1)
class TLToAXI4(idBits: Int, combinational: Boolean = true)(implicit p: Parameters) extends LazyModule class TLToAXI4(idBits: Int, combinational: Boolean = true)(implicit p: Parameters) extends LazyModule
{ {
@ -46,11 +44,7 @@ class TLToAXI4(idBits: Int, combinational: Boolean = true)(implicit p: Parameter
val out = node.bundleOut val out = node.bundleOut
} }
val in = io.in(0) ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
val out = io.out(0)
val edgeIn = node.edgesIn(0)
val edgeOut = node.edgesOut(0)
val slaves = edgeOut.slave.slaves val slaves = edgeOut.slave.slaves
// All pairs of slaves must promise that they will never interleave data // All pairs of slaves must promise that they will never interleave data
@ -226,6 +220,7 @@ class TLToAXI4(idBits: Int, combinational: Boolean = true)(implicit p: Parameter
in.c.ready := Bool(true) in.c.ready := Bool(true)
in.e.ready := Bool(true) in.e.ready := Bool(true)
} }
}
} }
object TLToAXI4 object TLToAXI4

View File

@ -12,8 +12,8 @@ import scala.math.{min,max}
class TLWidthWidget(innerBeatBytes: Int)(implicit p: Parameters) extends LazyModule class TLWidthWidget(innerBeatBytes: Int)(implicit p: Parameters) extends LazyModule
{ {
val node = TLAdapterNode( val node = TLAdapterNode(
clientFn = { case Seq(c) => c }, clientFn = { case c => c },
managerFn = { case Seq(m) => m.copy(beatBytes = innerBeatBytes) }) managerFn = { case m => m.copy(beatBytes = innerBeatBytes) })
lazy val module = new LazyModuleImp(this) { lazy val module = new LazyModuleImp(this) {
val io = new Bundle { val io = new Bundle {
@ -139,11 +139,7 @@ class TLWidthWidget(innerBeatBytes: Int)(implicit p: Parameters) extends LazyMod
} }
} }
val edgeOut = node.edgesOut(0) ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) =>
val edgeIn = node.edgesIn(0)
val in = io.in(0)
val out = io.out(0)
splice(edgeIn, in.a, edgeOut, out.a) splice(edgeIn, in.a, edgeOut, out.a)
splice(edgeOut, out.d, edgeIn, in.d) splice(edgeOut, out.d, edgeIn, in.d)
@ -162,6 +158,7 @@ class TLWidthWidget(innerBeatBytes: Int)(implicit p: Parameters) extends LazyMod
out.e.valid := Bool(false) out.e.valid := Bool(false)
} }
} }
}
} }
object TLWidthWidget object TLWidthWidget

View File

@ -34,7 +34,7 @@ class TLXbar(policy: TLArbiter.Policy = TLArbiter.lowestIndexFirst)(implicit p:
} }
} }
val node = TLAdapterNode( val node = TLNexusNode(
numClientPorts = 1 to 32, numClientPorts = 1 to 32,
numManagerPorts = 1 to 32, numManagerPorts = 1 to 32,
clientFn = { seq => clientFn = { seq =>