diplomacy: remove node arity and allow empty Nexus nodes (Xbars)
This removes the mostly obsolete 'numIn/Out' range restrictions on nodes. It also makes it possible to connect optional crossbars that disappear. val x = TLXbar() x := master slave := x val y = TLXbar() x :=* y // only connect y if it gets used This will create crossbar x, but crossbar y will disappear.
This commit is contained in:
parent
6a25a3b7ac
commit
e489c4226e
@ -24,10 +24,8 @@ case class AHBMasterNode(portParams: Seq[AHBMasterPortParameters])(implicit valN
|
|||||||
case class AHBSlaveNode(portParams: Seq[AHBSlavePortParameters])(implicit valName: ValName) extends SinkNode(AHBImp)(portParams)
|
case class AHBSlaveNode(portParams: Seq[AHBSlavePortParameters])(implicit valName: ValName) extends SinkNode(AHBImp)(portParams)
|
||||||
case class AHBNexusNode(
|
case class AHBNexusNode(
|
||||||
masterFn: Seq[AHBMasterPortParameters] => AHBMasterPortParameters,
|
masterFn: Seq[AHBMasterPortParameters] => AHBMasterPortParameters,
|
||||||
slaveFn: Seq[AHBSlavePortParameters] => AHBSlavePortParameters,
|
slaveFn: Seq[AHBSlavePortParameters] => AHBSlavePortParameters)(
|
||||||
numMasterPorts: Range.Inclusive = 1 to 999,
|
|
||||||
numSlavePorts: Range.Inclusive = 1 to 999)(
|
|
||||||
implicit valName: ValName)
|
implicit valName: ValName)
|
||||||
extends NexusNode(AHBImp)(masterFn, slaveFn, numMasterPorts, numSlavePorts)
|
extends NexusNode(AHBImp)(masterFn, slaveFn)
|
||||||
|
|
||||||
case class AHBIdentityNode()(implicit valName: ValName) extends IdentityNode(AHBImp)()
|
case class AHBIdentityNode()(implicit valName: ValName) extends IdentityNode(AHBImp)()
|
||||||
|
@ -10,12 +10,14 @@ import scala.math.{min,max}
|
|||||||
|
|
||||||
class AHBFanout()(implicit p: Parameters) extends LazyModule {
|
class AHBFanout()(implicit p: Parameters) extends LazyModule {
|
||||||
val node = AHBNexusNode(
|
val node = AHBNexusNode(
|
||||||
numSlavePorts = 1 to 1,
|
|
||||||
numMasterPorts = 1 to 32,
|
|
||||||
masterFn = { case Seq(m) => m },
|
masterFn = { case Seq(m) => m },
|
||||||
slaveFn = { seq => seq(0).copy(slaves = seq.flatMap(_.slaves)) })
|
slaveFn = { seq => seq(0).copy(slaves = seq.flatMap(_.slaves)) })
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
|
if (node.edges.in.size >= 1) {
|
||||||
|
require (node.edges.in.size == 1, "AHBFanout does not support multiple masters")
|
||||||
|
require (node.edges.out.size > 0, "AHBFanout requires at least one slave")
|
||||||
|
|
||||||
// Require consistent bus widths
|
// Require consistent bus widths
|
||||||
val (io_out, edgesOut) = node.out.unzip
|
val (io_out, edgesOut) = node.out.unzip
|
||||||
val port0 = edgesOut(0).slave
|
val port0 = edgesOut(0).slave
|
||||||
@ -44,3 +46,4 @@ class AHBFanout()(implicit p: Parameters) extends LazyModule {
|
|||||||
in.hrdata := Mux1H(d_sel, io_out.map(_.hrdata))
|
in.hrdata := Mux1H(d_sel, io_out.map(_.hrdata))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -23,10 +23,8 @@ case class APBMasterNode(portParams: Seq[APBMasterPortParameters])(implicit valN
|
|||||||
case class APBSlaveNode(portParams: Seq[APBSlavePortParameters])(implicit valName: ValName) extends SinkNode(APBImp)(portParams)
|
case class APBSlaveNode(portParams: Seq[APBSlavePortParameters])(implicit valName: ValName) extends SinkNode(APBImp)(portParams)
|
||||||
case class APBNexusNode(
|
case class APBNexusNode(
|
||||||
masterFn: Seq[APBMasterPortParameters] => APBMasterPortParameters,
|
masterFn: Seq[APBMasterPortParameters] => APBMasterPortParameters,
|
||||||
slaveFn: Seq[APBSlavePortParameters] => APBSlavePortParameters,
|
slaveFn: Seq[APBSlavePortParameters] => APBSlavePortParameters)(
|
||||||
numMasterPorts: Range.Inclusive = 1 to 1,
|
|
||||||
numSlavePorts: Range.Inclusive = 1 to 1)(
|
|
||||||
implicit valName: ValName)
|
implicit valName: ValName)
|
||||||
extends NexusNode(APBImp)(masterFn, slaveFn, numMasterPorts, numSlavePorts)
|
extends NexusNode(APBImp)(masterFn, slaveFn)
|
||||||
|
|
||||||
case class APBIdentityNode()(implicit valName: ValName) extends IdentityNode(APBImp)()
|
case class APBIdentityNode()(implicit valName: ValName) extends IdentityNode(APBImp)()
|
||||||
|
@ -10,12 +10,14 @@ import scala.math.{min,max}
|
|||||||
|
|
||||||
class APBFanout()(implicit p: Parameters) extends LazyModule {
|
class APBFanout()(implicit p: Parameters) extends LazyModule {
|
||||||
val node = APBNexusNode(
|
val node = APBNexusNode(
|
||||||
numSlavePorts = 1 to 1,
|
|
||||||
numMasterPorts = 1 to 32,
|
|
||||||
masterFn = { case Seq(m) => m },
|
masterFn = { case Seq(m) => m },
|
||||||
slaveFn = { seq => seq(0).copy(slaves = seq.flatMap(_.slaves)) })
|
slaveFn = { seq => seq(0).copy(slaves = seq.flatMap(_.slaves)) })
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
|
if (node.edges.in.size >= 1) {
|
||||||
|
require (node.edges.in.size == 1, "APBFanout does not support multiple masters")
|
||||||
|
require (node.edges.out.size > 0, "APBFanout requires at least one slave")
|
||||||
|
|
||||||
val (in, _) = node.in(0)
|
val (in, _) = node.in(0)
|
||||||
|
|
||||||
// Require consistent bus widths
|
// Require consistent bus widths
|
||||||
@ -43,3 +45,4 @@ class APBFanout()(implicit p: Parameters) extends LazyModule {
|
|||||||
in.prdata := Mux1H(sel, io_out.map(_.prdata))
|
in.prdata := Mux1H(sel, io_out.map(_.prdata))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -23,17 +23,14 @@ case class AXI4MasterNode(portParams: Seq[AXI4MasterPortParameters])(implicit va
|
|||||||
case class AXI4SlaveNode(portParams: Seq[AXI4SlavePortParameters])(implicit valName: ValName) extends SinkNode(AXI4Imp)(portParams)
|
case class AXI4SlaveNode(portParams: Seq[AXI4SlavePortParameters])(implicit valName: ValName) extends SinkNode(AXI4Imp)(portParams)
|
||||||
case class AXI4NexusNode(
|
case class AXI4NexusNode(
|
||||||
masterFn: Seq[AXI4MasterPortParameters] => AXI4MasterPortParameters,
|
masterFn: Seq[AXI4MasterPortParameters] => AXI4MasterPortParameters,
|
||||||
slaveFn: Seq[AXI4SlavePortParameters] => AXI4SlavePortParameters,
|
slaveFn: Seq[AXI4SlavePortParameters] => AXI4SlavePortParameters)(
|
||||||
numMasterPorts: Range.Inclusive = 1 to 999,
|
|
||||||
numSlavePorts: Range.Inclusive = 1 to 999)(
|
|
||||||
implicit valName: ValName)
|
implicit valName: ValName)
|
||||||
extends NexusNode(AXI4Imp)(masterFn, slaveFn, numMasterPorts, numSlavePorts)
|
extends NexusNode(AXI4Imp)(masterFn, slaveFn)
|
||||||
case class AXI4AdapterNode(
|
case class AXI4AdapterNode(
|
||||||
masterFn: AXI4MasterPortParameters => AXI4MasterPortParameters = { m => m },
|
masterFn: AXI4MasterPortParameters => AXI4MasterPortParameters = { m => m },
|
||||||
slaveFn: AXI4SlavePortParameters => AXI4SlavePortParameters = { s => s },
|
slaveFn: AXI4SlavePortParameters => AXI4SlavePortParameters = { s => s })(
|
||||||
numPorts: Range.Inclusive = 0 to 999)(
|
|
||||||
implicit valName: ValName)
|
implicit valName: ValName)
|
||||||
extends AdapterNode(AXI4Imp)(masterFn, slaveFn, numPorts)
|
extends AdapterNode(AXI4Imp)(masterFn, slaveFn)
|
||||||
case class AXI4IdentityNode()(implicit valName: ValName) extends IdentityNode(AXI4Imp)()
|
case class AXI4IdentityNode()(implicit valName: ValName) extends IdentityNode(AXI4Imp)()
|
||||||
|
|
||||||
object AXI4AsyncImp extends SimpleNodeImp[AXI4AsyncMasterPortParameters, AXI4AsyncSlavePortParameters, AXI4AsyncEdgeParameters, AXI4AsyncBundle]
|
object AXI4AsyncImp extends SimpleNodeImp[AXI4AsyncMasterPortParameters, AXI4AsyncSlavePortParameters, AXI4AsyncEdgeParameters, AXI4AsyncBundle]
|
||||||
|
@ -18,8 +18,6 @@ class AXI4Xbar(
|
|||||||
require (awQueueDepth >= 1)
|
require (awQueueDepth >= 1)
|
||||||
|
|
||||||
val node = AXI4NexusNode(
|
val node = AXI4NexusNode(
|
||||||
numMasterPorts = 1 to 999,
|
|
||||||
numSlavePorts = 1 to 999,
|
|
||||||
masterFn = { seq =>
|
masterFn = { seq =>
|
||||||
seq(0).copy(
|
seq(0).copy(
|
||||||
userBits = seq.map(_.userBits).max,
|
userBits = seq.map(_.userBits).max,
|
||||||
@ -56,14 +54,14 @@ class AXI4Xbar(
|
|||||||
val awIn = Seq.fill(io_in .size) { Module(new Queue(UInt(width = io_out.size), awQueueDepth, flow = true)) }
|
val awIn = Seq.fill(io_in .size) { Module(new Queue(UInt(width = io_out.size), awQueueDepth, flow = true)) }
|
||||||
val awOut = Seq.fill(io_out.size) { Module(new Queue(UInt(width = io_in .size), awQueueDepth, flow = true)) }
|
val awOut = Seq.fill(io_out.size) { Module(new Queue(UInt(width = io_in .size), awQueueDepth, flow = true)) }
|
||||||
|
|
||||||
val requestARIO = Vec(io_in.map { i => Vec(outputPorts.map { o => o(i.ar.bits.addr) }) })
|
val requestARIO = io_in.map { i => Vec(outputPorts.map { o => o(i.ar.bits.addr) }) }
|
||||||
val requestAWIO = Vec(io_in.map { i => Vec(outputPorts.map { o => o(i.aw.bits.addr) }) })
|
val requestAWIO = io_in.map { i => Vec(outputPorts.map { o => o(i.aw.bits.addr) }) }
|
||||||
val requestROI = Vec(io_out.map { o => Vec(inputIdRanges.map { i => i.contains(o.r.bits.id) }) })
|
val requestROI = io_out.map { o => inputIdRanges.map { i => i.contains(o.r.bits.id) } }
|
||||||
val requestBOI = Vec(io_out.map { o => Vec(inputIdRanges.map { i => i.contains(o.b.bits.id) }) })
|
val requestBOI = io_out.map { o => inputIdRanges.map { i => i.contains(o.b.bits.id) } }
|
||||||
|
|
||||||
// W follows the path dictated by the AW Q
|
// W follows the path dictated by the AW Q
|
||||||
for (i <- 0 until io_in.size) { awIn(i).io.enq.bits := requestAWIO(i).asUInt }
|
for (i <- 0 until io_in.size) { awIn(i).io.enq.bits := requestAWIO(i).asUInt }
|
||||||
val requestWIO = Vec(awIn.map { q => if (io_out.size > 1) Vec(q.io.deq.bits.toBools) else Vec.fill(1){Bool(true)} })
|
val requestWIO = awIn.map { q => if (io_out.size > 1) q.io.deq.bits.toBools else Seq(Bool(true)) }
|
||||||
|
|
||||||
// We need an intermediate size of bundle with the widest possible identifiers
|
// We need an intermediate size of bundle with the widest possible identifiers
|
||||||
val wide_bundle = AXI4BundleParameters.union(io_in.map(_.params) ++ io_out.map(_.params))
|
val wide_bundle = AXI4BundleParameters.union(io_in.map(_.params) ++ io_out.map(_.params))
|
||||||
|
@ -279,11 +279,9 @@ class TLDebugModuleOuter(device: Device)(implicit p: Parameters) extends LazyMod
|
|||||||
import DMI_RegAddrs._
|
import DMI_RegAddrs._
|
||||||
|
|
||||||
val intnode = IntNexusNode(
|
val intnode = IntNexusNode(
|
||||||
numSourcePorts = 1 to 1024,
|
|
||||||
numSinkPorts = 0 to 0,
|
|
||||||
sourceFn = { _ => IntSourcePortParameters(Seq(IntSourceParameters(1, Seq(Resource(device, "int"))))) },
|
sourceFn = { _ => IntSourcePortParameters(Seq(IntSourceParameters(1, Seq(Resource(device, "int"))))) },
|
||||||
sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) }
|
sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) },
|
||||||
)
|
outputRequiresInput = false)
|
||||||
|
|
||||||
val dmiNode = TLRegisterNode (
|
val dmiNode = TLRegisterNode (
|
||||||
address = AddressSet.misaligned(DMI_DMCONTROL << 2, 4),
|
address = AddressSet.misaligned(DMI_DMCONTROL << 2, 4),
|
||||||
@ -293,6 +291,7 @@ class TLDebugModuleOuter(device: Device)(implicit p: Parameters) extends LazyMod
|
|||||||
)
|
)
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
|
require (intnode.edges.in.size == 0, "Debug Module does not accept interrupts")
|
||||||
|
|
||||||
val nComponents = intnode.out.size
|
val nComponents = intnode.out.size
|
||||||
|
|
||||||
|
@ -37,14 +37,21 @@ class TLBusBypass(beatBytes: Int)(implicit p: Parameters) extends TLBusBypassBas
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TLBypassNode(implicit valName: ValName) extends TLCustomNode
|
||||||
|
{
|
||||||
|
def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
|
||||||
|
require (iStars == 0 && oStars == 0, "TLBypass node does not support :=* or :*=")
|
||||||
|
require (iKnown == 1, "TLBypass node expects exactly one input")
|
||||||
|
require (oKnown == 2, "TLBypass node expects exactly one output")
|
||||||
|
(0, 0)
|
||||||
|
}
|
||||||
|
def mapParamsD(n: Int, p: Seq[TLClientPortParameters]): Seq[TLClientPortParameters] = { p ++ p }
|
||||||
|
def mapParamsU(n: Int, p: Seq[TLManagerPortParameters]): Seq[TLManagerPortParameters] = { p.tail }
|
||||||
|
}
|
||||||
|
|
||||||
class TLBusBypassBar(implicit p: Parameters) extends LazyModule
|
class TLBusBypassBar(implicit p: Parameters) extends LazyModule
|
||||||
{
|
{
|
||||||
// The client only sees the second slave port
|
val node = new TLBypassNode()
|
||||||
val node = TLNexusNode(
|
|
||||||
numClientPorts = 2 to 2 ,
|
|
||||||
numManagerPorts = 1 to 1,
|
|
||||||
clientFn = { seq => seq(0) },
|
|
||||||
managerFn = { seq => seq(1) })
|
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = IO(new Bundle {
|
val io = IO(new Bundle {
|
||||||
|
@ -48,12 +48,13 @@ class CoreplexLocalInterrupter(params: ClintParams)(implicit p: Parameters) exte
|
|||||||
beatBytes = p(XLen)/8)
|
beatBytes = p(XLen)/8)
|
||||||
|
|
||||||
val intnode = IntNexusNode(
|
val intnode = IntNexusNode(
|
||||||
numSourcePorts = 0 to 1024,
|
|
||||||
numSinkPorts = 0 to 0,
|
|
||||||
sourceFn = { _ => IntSourcePortParameters(Seq(IntSourceParameters(ints, Seq(Resource(device, "int"))))) },
|
sourceFn = { _ => IntSourcePortParameters(Seq(IntSourceParameters(ints, Seq(Resource(device, "int"))))) },
|
||||||
sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) })
|
sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) },
|
||||||
|
outputRequiresInput = false)
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
|
require (intnode.edges.in.size == 0, "CLINT only produces interrupts; it does not accept them")
|
||||||
|
|
||||||
val io = IO(new Bundle {
|
val io = IO(new Bundle {
|
||||||
val rtcTick = Bool(INPUT)
|
val rtcTick = Bool(INPUT)
|
||||||
})
|
})
|
||||||
|
@ -86,10 +86,10 @@ class TLPLIC(params: PLICParams)(implicit p: Parameters) extends LazyModule
|
|||||||
concurrency = 1) // limiting concurrency handles RAW hazards on claim registers
|
concurrency = 1) // limiting concurrency handles RAW hazards on claim registers
|
||||||
|
|
||||||
val intnode = IntNexusNode(
|
val intnode = IntNexusNode(
|
||||||
numSourcePorts = 0 to 1024,
|
|
||||||
numSinkPorts = 0 to 1024,
|
|
||||||
sourceFn = { _ => IntSourcePortParameters(Seq(IntSourceParameters(1, Seq(Resource(device, "int"))))) },
|
sourceFn = { _ => IntSourcePortParameters(Seq(IntSourceParameters(1, Seq(Resource(device, "int"))))) },
|
||||||
sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) })
|
sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) },
|
||||||
|
outputRequiresInput = false,
|
||||||
|
inputRequiresOutput = false)
|
||||||
|
|
||||||
/* Negotiated sizes */
|
/* Negotiated sizes */
|
||||||
def nDevices: Int = intnode.edges.in.map(_.source.num).sum
|
def nDevices: Int = intnode.edges.in.map(_.source.num).sum
|
||||||
|
@ -188,18 +188,12 @@ object NodeBinding
|
|||||||
|
|
||||||
trait InwardNode[DI, UI, BI <: Data] extends BaseNode
|
trait InwardNode[DI, UI, BI <: Data] extends BaseNode
|
||||||
{
|
{
|
||||||
protected[diplomacy] val numPI: Range.Inclusive
|
|
||||||
require (!numPI.isEmpty, s"No number of inputs would be acceptable to ${name}${lazyModule.line}")
|
|
||||||
require (numPI.start >= 0, s"${name} accepts a negative number of inputs${lazyModule.line}")
|
|
||||||
|
|
||||||
private val accPI = ListBuffer[(Int, OutwardNode[DI, UI, BI], NodeBinding, Parameters, SourceInfo)]()
|
private val accPI = ListBuffer[(Int, OutwardNode[DI, UI, BI], NodeBinding, Parameters, SourceInfo)]()
|
||||||
private var iRealized = false
|
private var iRealized = false
|
||||||
|
|
||||||
protected[diplomacy] def iPushed = accPI.size
|
protected[diplomacy] def iPushed = accPI.size
|
||||||
protected[diplomacy] def iPush(index: Int, node: OutwardNode[DI, UI, BI], binding: NodeBinding)(implicit p: Parameters, sourceInfo: SourceInfo) {
|
protected[diplomacy] def iPush(index: Int, node: OutwardNode[DI, UI, BI], binding: NodeBinding)(implicit p: Parameters, sourceInfo: SourceInfo) {
|
||||||
val info = sourceLine(sourceInfo, " at ", "")
|
val info = sourceLine(sourceInfo, " at ", "")
|
||||||
val noIs = numPI.size == 1 && numPI.contains(0)
|
|
||||||
require (!noIs, s"${name}${lazyModule.line} was incorrectly connected as a sink" + info)
|
|
||||||
require (!iRealized, s"${name}${lazyModule.line} was incorrectly connected as a sink after its .module was used" + info)
|
require (!iRealized, s"${name}${lazyModule.line} was incorrectly connected as a sink after its .module was used" + info)
|
||||||
accPI += ((index, node, binding, p, sourceInfo))
|
accPI += ((index, node, binding, p, sourceInfo))
|
||||||
}
|
}
|
||||||
@ -222,18 +216,12 @@ trait OutwardNodeHandle[DO, UO, EO, BO <: Data] extends NoHandle
|
|||||||
|
|
||||||
trait OutwardNode[DO, UO, BO <: Data] extends BaseNode
|
trait OutwardNode[DO, UO, BO <: Data] extends BaseNode
|
||||||
{
|
{
|
||||||
protected[diplomacy] val numPO: Range.Inclusive
|
|
||||||
require (!numPO.isEmpty, s"No number of outputs would be acceptable to ${name}${lazyModule.line}")
|
|
||||||
require (numPO.start >= 0, s"${name} accepts a negative number of outputs${lazyModule.line}")
|
|
||||||
|
|
||||||
private val accPO = ListBuffer[(Int, InwardNode [DO, UO, BO], NodeBinding, Parameters, SourceInfo)]()
|
private val accPO = ListBuffer[(Int, InwardNode [DO, UO, BO], NodeBinding, Parameters, SourceInfo)]()
|
||||||
private var oRealized = false
|
private var oRealized = false
|
||||||
|
|
||||||
protected[diplomacy] def oPushed = accPO.size
|
protected[diplomacy] def oPushed = accPO.size
|
||||||
protected[diplomacy] def oPush(index: Int, node: InwardNode [DO, UO, BO], binding: NodeBinding)(implicit p: Parameters, sourceInfo: SourceInfo) {
|
protected[diplomacy] def oPush(index: Int, node: InwardNode [DO, UO, BO], binding: NodeBinding)(implicit p: Parameters, sourceInfo: SourceInfo) {
|
||||||
val info = sourceLine(sourceInfo, " at ", "")
|
val info = sourceLine(sourceInfo, " at ", "")
|
||||||
val noOs = numPO.size == 1 && numPO.contains(0)
|
|
||||||
require (!noOs, s"${name}${lazyModule.line} was incorrectly connected as a source" + info)
|
|
||||||
require (!oRealized, s"${name}${lazyModule.line} was incorrectly connected as a source after its .module was used" + info)
|
require (!oRealized, s"${name}${lazyModule.line} was incorrectly connected as a source after its .module was used" + info)
|
||||||
accPO += ((index, node, binding, p, sourceInfo))
|
accPO += ((index, node, binding, p, sourceInfo))
|
||||||
}
|
}
|
||||||
@ -255,8 +243,6 @@ case class Edges[EI, EO](in: EI, out: EO)
|
|||||||
sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
||||||
val inner: InwardNodeImp [DI, UI, EI, BI],
|
val inner: InwardNodeImp [DI, UI, EI, BI],
|
||||||
val outer: OutwardNodeImp[DO, UO, EO, BO])(
|
val outer: OutwardNodeImp[DO, UO, EO, BO])(
|
||||||
protected[diplomacy] val numPO: Range.Inclusive,
|
|
||||||
protected[diplomacy] val numPI: Range.Inclusive)(
|
|
||||||
implicit valName: ValName)
|
implicit valName: ValName)
|
||||||
extends BaseNode with NodeHandle[DI, UI, EI, BI, DO, UO, EO, BO] with InwardNode[DI, UI, BI] with OutwardNode[DO, UO, BO]
|
extends BaseNode with NodeHandle[DI, UI, EI, BI, DO, UO, EO, BO] with InwardNode[DI, UI, BI] with OutwardNode[DO, UO, BO]
|
||||||
{
|
{
|
||||||
@ -292,8 +278,6 @@ sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
|||||||
case BIND_STAR => iStar }}.scanLeft(0)(_+_)
|
case BIND_STAR => iStar }}.scanLeft(0)(_+_)
|
||||||
val oTotal = oSum.lastOption.getOrElse(0)
|
val oTotal = oSum.lastOption.getOrElse(0)
|
||||||
val iTotal = iSum.lastOption.getOrElse(0)
|
val iTotal = iSum.lastOption.getOrElse(0)
|
||||||
require(numPO.contains(oTotal), s"${name} has ${oTotal} outputs, expected ${numPO}${lazyModule.line}")
|
|
||||||
require(numPI.contains(iTotal), s"${name} has ${iTotal} inputs, expected ${numPI}${lazyModule.line}")
|
|
||||||
(oSum.init zip oSum.tail, iSum.init zip iSum.tail, oStar, iStar)
|
(oSum.init zip oSum.tail, iSum.init zip iSum.tail, oStar, iStar)
|
||||||
} catch {
|
} catch {
|
||||||
case c: StarCycleException => throw c.copy(loop = s"${name}${lazyModule.line}" +: c.loop)
|
case c: StarCycleException => throw c.copy(loop = s"${name}${lazyModule.line}" +: c.loop)
|
||||||
@ -417,10 +401,8 @@ sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
|||||||
abstract class MixedCustomNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
abstract class MixedCustomNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
||||||
inner: InwardNodeImp [DI, UI, EI, BI],
|
inner: InwardNodeImp [DI, UI, EI, BI],
|
||||||
outer: OutwardNodeImp[DO, UO, EO, BO])(
|
outer: OutwardNodeImp[DO, UO, EO, BO])(
|
||||||
numPO: Range.Inclusive,
|
|
||||||
numPI: Range.Inclusive)(
|
|
||||||
implicit valName: ValName)
|
implicit valName: ValName)
|
||||||
extends MixedNode(inner, outer)(numPO, numPI)
|
extends MixedNode(inner, outer)
|
||||||
{
|
{
|
||||||
def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int)
|
def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int)
|
||||||
def mapParamsD(n: Int, p: Seq[DI]): Seq[DO]
|
def mapParamsD(n: Int, p: Seq[DI]): Seq[DO]
|
||||||
@ -428,28 +410,28 @@ abstract class MixedCustomNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
|||||||
}
|
}
|
||||||
|
|
||||||
abstract class CustomNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(
|
abstract class CustomNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(
|
||||||
numPO: Range.Inclusive,
|
|
||||||
numPI: Range.Inclusive)(
|
|
||||||
implicit valName: ValName)
|
implicit valName: ValName)
|
||||||
extends MixedCustomNode(imp, imp)(numPO, numPI)
|
extends MixedCustomNode(imp, imp)
|
||||||
|
|
||||||
class MixedAdapterNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
class MixedAdapterNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
||||||
inner: InwardNodeImp [DI, UI, EI, BI],
|
inner: InwardNodeImp [DI, UI, EI, BI],
|
||||||
outer: OutwardNodeImp[DO, UO, EO, BO])(
|
outer: OutwardNodeImp[DO, UO, EO, BO])(
|
||||||
dFn: DI => DO,
|
dFn: DI => DO,
|
||||||
uFn: UO => UI,
|
uFn: UO => UI)(
|
||||||
num: Range.Inclusive = 0 to 999)(
|
|
||||||
implicit valName: ValName)
|
implicit valName: ValName)
|
||||||
extends MixedNode(inner, outer)(num, num)
|
extends MixedNode(inner, outer)
|
||||||
{
|
{
|
||||||
protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
|
protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
|
||||||
require (oStars + iStars <= 1, s"${name} (an adapter) appears left of a :*= ${iStars} times and right of a :=* ${oStars} times; at most once is allowed${lazyModule.line}")
|
require (oStars + iStars <= 1, s"${name} (an adapter) appears left of a :*= ${iStars} times and right of a :=* ${oStars} times; at most once is allowed${lazyModule.line}")
|
||||||
if (oStars > 0) {
|
if (oStars > 0) {
|
||||||
require (iKnown >= oKnown, s"${name} (an adapter) has ${oKnown} outputs and ${iKnown} inputs; cannot assign ${iKnown-oKnown} edges to resolve :=*${lazyModule.line}")
|
require (iKnown >= oKnown, s"${name} (an adapter) has ${oKnown} outputs and ${iKnown} inputs; cannot assign ${iKnown-oKnown} edges to resolve :=*${lazyModule.line}")
|
||||||
(0, iKnown - oKnown)
|
(0, iKnown - oKnown)
|
||||||
} else {
|
} else if (iStars > 0) {
|
||||||
require (oKnown >= iKnown, s"${name} (an adapter) has ${oKnown} outputs and ${iKnown} inputs; cannot assign ${oKnown-iKnown} edges to resolve :*=${lazyModule.line}")
|
require (oKnown >= iKnown, s"${name} (an adapter) has ${oKnown} outputs and ${iKnown} inputs; cannot assign ${oKnown-iKnown} edges to resolve :*=${lazyModule.line}")
|
||||||
(oKnown - iKnown, 0)
|
(oKnown - iKnown, 0)
|
||||||
|
} else {
|
||||||
|
require (oKnown == iKnown, s"${name} (an adapter) has ${oKnown} outputs and ${iKnown} inputs; these do not match")
|
||||||
|
(0, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
protected[diplomacy] def mapParamsD(n: Int, p: Seq[DI]): Seq[DO] = {
|
protected[diplomacy] def mapParamsD(n: Int, p: Seq[DI]): Seq[DO] = {
|
||||||
@ -464,10 +446,9 @@ class MixedAdapterNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
|||||||
|
|
||||||
class AdapterNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(
|
class AdapterNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(
|
||||||
dFn: D => D,
|
dFn: D => D,
|
||||||
uFn: U => U,
|
uFn: U => U)(
|
||||||
num: Range.Inclusive = 0 to 999)(
|
|
||||||
implicit valName: ValName)
|
implicit valName: ValName)
|
||||||
extends MixedAdapterNode[D, U, EI, B, D, U, EO, B](imp, imp)(dFn, uFn, num)
|
extends MixedAdapterNode[D, U, EI, B, D, U, EO, B](imp, imp)(dFn, uFn)
|
||||||
|
|
||||||
// IdentityNodes automatically connect their inputs to outputs
|
// IdentityNodes automatically connect their inputs to outputs
|
||||||
class IdentityNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])()(implicit valName: ValName)
|
class IdentityNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])()(implicit valName: ValName)
|
||||||
@ -486,39 +467,39 @@ class MixedNexusNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data](
|
|||||||
outer: OutwardNodeImp[DO, UO, EO, BO])(
|
outer: OutwardNodeImp[DO, UO, EO, BO])(
|
||||||
dFn: Seq[DI] => DO,
|
dFn: Seq[DI] => DO,
|
||||||
uFn: Seq[UO] => UI,
|
uFn: Seq[UO] => UI,
|
||||||
numPO: Range.Inclusive = 1 to 999,
|
// no inputs and no outputs is always allowed
|
||||||
numPI: Range.Inclusive = 1 to 999)(
|
inputRequiresOutput: Boolean = true,
|
||||||
|
outputRequiresInput: Boolean = true)(
|
||||||
implicit valName: ValName)
|
implicit valName: ValName)
|
||||||
extends MixedNode(inner, outer)(numPO, numPI)
|
extends MixedNode(inner, outer)
|
||||||
{
|
{
|
||||||
// require (numPO.end >= 1, s"${name} does not accept outputs${lazyModule.line}")
|
|
||||||
// require (numPI.end >= 1, s"${name} does not accept inputs${lazyModule.line}")
|
|
||||||
|
|
||||||
protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
|
protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
|
||||||
require (iStars == 0, s"${name} (a nexus) appears left of :*= (perhaps you should flip the '*' to :=*?)${lazyModule.line}")
|
// a nexus treats :=* as a weak pointer
|
||||||
require (oStars == 0, s"${name} (a nexus) appears right of a :=* (perhaps you should flip the '*' to :*=?)${lazyModule.line}")
|
require (!outputRequiresInput || oKnown == 0 || iStars + iKnown != 0, s"${name} (a nexus) has ${oKnown} required outputs and no possible inputs")
|
||||||
(0, 0)
|
require (!inputRequiresOutput || iKnown == 0 || oStars + oKnown != 0, s"${name} (a nexus) has ${iKnown} required inputs and no possible outputs")
|
||||||
|
if (iKnown == 0 && oKnown == 0) (0, 0) else (1, 1)
|
||||||
}
|
}
|
||||||
protected[diplomacy] def mapParamsD(n: Int, p: Seq[DI]): Seq[DO] = { val a = dFn(p); Seq.fill(n)(a) }
|
protected[diplomacy] def mapParamsD(n: Int, p: Seq[DI]): Seq[DO] = { if (n > 0) { val a = dFn(p); Seq.fill(n)(a) } else Nil }
|
||||||
protected[diplomacy] def mapParamsU(n: Int, p: Seq[UO]): Seq[UI] = { val a = uFn(p); Seq.fill(n)(a) }
|
protected[diplomacy] def mapParamsU(n: Int, p: Seq[UO]): Seq[UI] = { if (n > 0) { val a = uFn(p); Seq.fill(n)(a) } else Nil }
|
||||||
}
|
}
|
||||||
|
|
||||||
class NexusNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(
|
class NexusNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(
|
||||||
dFn: Seq[D] => D,
|
dFn: Seq[D] => D,
|
||||||
uFn: Seq[U] => U,
|
uFn: Seq[U] => U,
|
||||||
numPO: Range.Inclusive = 1 to 999,
|
inputRequiresOutput: Boolean = true,
|
||||||
numPI: Range.Inclusive = 1 to 999)(
|
outputRequiresInput: Boolean = true)(
|
||||||
implicit valName: ValName)
|
implicit valName: ValName)
|
||||||
extends MixedNexusNode[D, U, EI, B, D, U, EO, B](imp, imp)(dFn, uFn, numPO, numPI)
|
extends MixedNexusNode[D, U, EI, B, D, U, EO, B](imp, imp)(dFn, uFn, inputRequiresOutput, outputRequiresInput)
|
||||||
|
|
||||||
// There are no Mixed SourceNodes
|
// There are no Mixed SourceNodes
|
||||||
class SourceNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(po: Seq[D])(implicit valName: ValName)
|
class SourceNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(po: Seq[D])(implicit valName: ValName)
|
||||||
extends MixedNode(imp, imp)(po.size to po.size, 0 to 0)
|
extends MixedNode(imp, imp)
|
||||||
{
|
{
|
||||||
protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
|
protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
|
||||||
require (oStars <= 1, s"${name} (a source) appears right of a :=* ${oStars} times; at most once is allowed${lazyModule.line}")
|
require (oStars <= 1, s"${name} (a source) appears right of a :=* ${oStars} times; at most once is allowed${lazyModule.line}")
|
||||||
require (iStars == 0, s"${name} (a source) cannot appear left of a :*=${lazyModule.line}")
|
require (iStars == 0, s"${name} (a source) cannot appear left of a :*=${lazyModule.line}")
|
||||||
require (iKnown == 0, s"${name} (a source) cannot appear left of a :=${lazyModule.line}")
|
require (iKnown == 0, s"${name} (a source) cannot appear left of a :=${lazyModule.line}")
|
||||||
|
require (po.size == oKnown || oStars == 1, s"${name} (a source) has only ${oKnown} outputs connected out of ${po.size}")
|
||||||
require (po.size >= oKnown, s"${name} (a source) has ${oKnown} outputs out of ${po.size}; cannot assign ${po.size - oKnown} edges to resolve :=*${lazyModule.line}")
|
require (po.size >= oKnown, s"${name} (a source) has ${oKnown} outputs out of ${po.size}; cannot assign ${po.size - oKnown} edges to resolve :=*${lazyModule.line}")
|
||||||
(0, po.size - oKnown)
|
(0, po.size - oKnown)
|
||||||
}
|
}
|
||||||
@ -528,12 +509,13 @@ class SourceNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(po: Seq
|
|||||||
|
|
||||||
// There are no Mixed SinkNodes
|
// There are no Mixed SinkNodes
|
||||||
class SinkNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(pi: Seq[U])(implicit valName: ValName)
|
class SinkNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(pi: Seq[U])(implicit valName: ValName)
|
||||||
extends MixedNode(imp, imp)(0 to 0, pi.size to pi.size)
|
extends MixedNode(imp, imp)
|
||||||
{
|
{
|
||||||
protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
|
protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
|
||||||
require (iStars <= 1, s"${name} (a sink) appears left of a :*= ${iStars} times; at most once is allowed${lazyModule.line}")
|
require (iStars <= 1, s"${name} (a sink) appears left of a :*= ${iStars} times; at most once is allowed${lazyModule.line}")
|
||||||
require (oStars == 0, s"${name} (a sink) cannot appear right of a :=*${lazyModule.line}")
|
require (oStars == 0, s"${name} (a sink) cannot appear right of a :=*${lazyModule.line}")
|
||||||
require (oKnown == 0, s"${name} (a sink) cannot appear right of a :=${lazyModule.line}")
|
require (oKnown == 0, s"${name} (a sink) cannot appear right of a :=${lazyModule.line}")
|
||||||
|
require (pi.size == iKnown || iStars == 1, s"${name} (a sink) has only ${iKnown} inputs connected out of ${pi.size}")
|
||||||
require (pi.size >= iKnown, s"${name} (a sink) has ${iKnown} inputs out of ${pi.size}; cannot assign ${pi.size - iKnown} edges to resolve :*=${lazyModule.line}")
|
require (pi.size >= iKnown, s"${name} (a sink) has ${iKnown} inputs out of ${pi.size}; cannot assign ${pi.size - iKnown} edges to resolve :*=${lazyModule.line}")
|
||||||
(pi.size - iKnown, 0)
|
(pi.size - iKnown, 0)
|
||||||
}
|
}
|
||||||
@ -544,9 +526,7 @@ class SinkNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(pi: Seq[U
|
|||||||
class MixedTestNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data] protected[diplomacy](
|
class MixedTestNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data] protected[diplomacy](
|
||||||
node: NodeHandle [DI, UI, EI, BI, DO, UO, EO, BO], clone: CloneLazyModule)(
|
node: NodeHandle [DI, UI, EI, BI, DO, UO, EO, BO], clone: CloneLazyModule)(
|
||||||
implicit valName: ValName)
|
implicit valName: ValName)
|
||||||
extends MixedNode(node.inner, node.outer)(
|
extends MixedNode(node.inner, node.outer)
|
||||||
numPI = node.inward .uiParams.size to node.inward .uiParams.size,
|
|
||||||
numPO = node.outward.doParams.size to node.outward.doParams.size)
|
|
||||||
{
|
{
|
||||||
// The devices connected to this test node must recreate these parameters:
|
// The devices connected to this test node must recreate these parameters:
|
||||||
def iParams: Seq[DI] = node.inward .diParams
|
def iParams: Seq[DI] = node.inward .diParams
|
||||||
@ -555,6 +535,8 @@ class MixedTestNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data] protected[di
|
|||||||
protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
|
protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
|
||||||
require (oStars <= 1, s"${name} (a test node) appears right of a :=* ${oStars} times; at most once is allowed${lazyModule.line}")
|
require (oStars <= 1, s"${name} (a test node) appears right of a :=* ${oStars} times; at most once is allowed${lazyModule.line}")
|
||||||
require (iStars <= 1, s"${name} (a test node) appears left of a :*= ${iStars} times; at most once is allowed${lazyModule.line}")
|
require (iStars <= 1, s"${name} (a test node) appears left of a :*= ${iStars} times; at most once is allowed${lazyModule.line}")
|
||||||
|
require (node.inward .uiParams.size == iKnown || iStars == 1, s"${name} (a test node) has only ${iKnown} inputs connected out of ${node.inward.uiParams.size}")
|
||||||
|
require (node.outward.doParams.size == oKnown || oStars == 1, s"${name} (a test node) has only ${oKnown} outputs connected out of ${node.outward.doParams.size}")
|
||||||
(node.inward.uiParams.size - iKnown, node.outward.doParams.size - oKnown)
|
(node.inward.uiParams.size - iKnown, node.outward.doParams.size - oKnown)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,19 +23,18 @@ case class IntSourceNode(portParams: Seq[IntSourcePortParameters])(implicit valN
|
|||||||
case class IntSinkNode(portParams: Seq[IntSinkPortParameters])(implicit valName: ValName) extends SinkNode(IntImp)(portParams)
|
case class IntSinkNode(portParams: Seq[IntSinkPortParameters])(implicit valName: ValName) extends SinkNode(IntImp)(portParams)
|
||||||
case class IntAdapterNode(
|
case class IntAdapterNode(
|
||||||
sourceFn: IntSourcePortParameters => IntSourcePortParameters = { s => s },
|
sourceFn: IntSourcePortParameters => IntSourcePortParameters = { s => s },
|
||||||
sinkFn: IntSinkPortParameters => IntSinkPortParameters = { s => s },
|
sinkFn: IntSinkPortParameters => IntSinkPortParameters = { s => s })(
|
||||||
num: Range.Inclusive = 0 to 999)(
|
|
||||||
implicit valName: ValName)
|
implicit valName: ValName)
|
||||||
extends AdapterNode(IntImp)(sourceFn, sinkFn, num)
|
extends AdapterNode(IntImp)(sourceFn, sinkFn)
|
||||||
case class IntIdentityNode()(implicit valName: ValName) extends IdentityNode(IntImp)()
|
case class IntIdentityNode()(implicit valName: ValName) extends IdentityNode(IntImp)()
|
||||||
|
|
||||||
case class IntNexusNode(
|
case class IntNexusNode(
|
||||||
sourceFn: Seq[IntSourcePortParameters] => IntSourcePortParameters,
|
sourceFn: Seq[IntSourcePortParameters] => IntSourcePortParameters,
|
||||||
sinkFn: Seq[IntSinkPortParameters] => IntSinkPortParameters,
|
sinkFn: Seq[IntSinkPortParameters] => IntSinkPortParameters,
|
||||||
numSourcePorts: Range.Inclusive = 0 to 128,
|
inputRequiresOutput: Boolean = true,
|
||||||
numSinkPorts: Range.Inclusive = 0 to 128)(
|
outputRequiresInput: Boolean = true)(
|
||||||
implicit valName: ValName)
|
implicit valName: ValName)
|
||||||
extends NexusNode(IntImp)(sourceFn, sinkFn, numSourcePorts, numSinkPorts)
|
extends NexusNode(IntImp)(sourceFn, sinkFn, inputRequiresOutput, outputRequiresInput)
|
||||||
|
|
||||||
object IntSyncImp extends SimpleNodeImp[IntSourcePortParameters, IntSinkPortParameters, IntEdge, SyncInterrupts]
|
object IntSyncImp extends SimpleNodeImp[IntSourcePortParameters, IntSinkPortParameters, IntEdge, SyncInterrupts]
|
||||||
{
|
{
|
||||||
|
@ -6,7 +6,7 @@ import Chisel._
|
|||||||
import freechips.rocketchip.config.Parameters
|
import freechips.rocketchip.config.Parameters
|
||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
|
|
||||||
case class TLNodeNumbererNode(nodeAddressOffset: Option[Int] = None)(implicit valName: ValName) extends TLCustomNode(0 to 999, 0 to 999)
|
case class TLNodeNumbererNode(nodeAddressOffset: Option[Int] = None)(implicit valName: ValName) extends TLCustomNode
|
||||||
{
|
{
|
||||||
def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
|
def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
|
||||||
require (oStars + iStars <= 1, s"${name} (a custom adapter) appears left of a :*= ${iStars} times and right of a :=* ${oStars} times; at most once is allowed${lazyModule.line}")
|
require (oStars + iStars <= 1, s"${name} (a custom adapter) appears left of a :*= ${iStars} times and right of a :=* ${oStars} times; at most once is allowed${lazyModule.line}")
|
||||||
|
@ -49,26 +49,20 @@ case class TLManagerNode(portParams: Seq[TLManagerPortParameters])(implicit valN
|
|||||||
|
|
||||||
case class TLAdapterNode(
|
case class TLAdapterNode(
|
||||||
clientFn: TLClientPortParameters => TLClientPortParameters = { s => s },
|
clientFn: TLClientPortParameters => TLClientPortParameters = { s => s },
|
||||||
managerFn: TLManagerPortParameters => TLManagerPortParameters = { s => s },
|
managerFn: TLManagerPortParameters => TLManagerPortParameters = { s => s })(
|
||||||
num: Range.Inclusive = 0 to 999)(
|
|
||||||
implicit valName: ValName)
|
implicit valName: ValName)
|
||||||
extends AdapterNode(TLImp)(clientFn, managerFn, num)
|
extends AdapterNode(TLImp)(clientFn, managerFn)
|
||||||
|
|
||||||
case class TLIdentityNode()(implicit valName: ValName) extends IdentityNode(TLImp)()
|
case class TLIdentityNode()(implicit valName: ValName) extends IdentityNode(TLImp)()
|
||||||
|
|
||||||
case class TLNexusNode(
|
case class TLNexusNode(
|
||||||
clientFn: Seq[TLClientPortParameters] => TLClientPortParameters,
|
clientFn: Seq[TLClientPortParameters] => TLClientPortParameters,
|
||||||
managerFn: Seq[TLManagerPortParameters] => TLManagerPortParameters,
|
managerFn: Seq[TLManagerPortParameters] => TLManagerPortParameters)(
|
||||||
numClientPorts: Range.Inclusive = 1 to 999,
|
|
||||||
numManagerPorts: Range.Inclusive = 1 to 999)(
|
|
||||||
implicit valName: ValName)
|
implicit valName: ValName)
|
||||||
extends NexusNode(TLImp)(clientFn, managerFn, numClientPorts, numManagerPorts)
|
extends NexusNode(TLImp)(clientFn, managerFn)
|
||||||
|
|
||||||
abstract class TLCustomNode(
|
abstract class TLCustomNode(implicit valName: ValName)
|
||||||
numClientPorts: Range.Inclusive,
|
extends CustomNode(TLImp)
|
||||||
numManagerPorts: Range.Inclusive)(
|
|
||||||
implicit valName: ValName)
|
|
||||||
extends CustomNode(TLImp)(numClientPorts, numManagerPorts)
|
|
||||||
|
|
||||||
// Asynchronous crossings
|
// Asynchronous crossings
|
||||||
|
|
||||||
@ -86,10 +80,9 @@ object TLAsyncImp extends SimpleNodeImp[TLAsyncClientPortParameters, TLAsyncMana
|
|||||||
|
|
||||||
case class TLAsyncAdapterNode(
|
case class TLAsyncAdapterNode(
|
||||||
clientFn: TLAsyncClientPortParameters => TLAsyncClientPortParameters = { s => s },
|
clientFn: TLAsyncClientPortParameters => TLAsyncClientPortParameters = { s => s },
|
||||||
managerFn: TLAsyncManagerPortParameters => TLAsyncManagerPortParameters = { s => s },
|
managerFn: TLAsyncManagerPortParameters => TLAsyncManagerPortParameters = { s => s })(
|
||||||
num: Range.Inclusive = 0 to 999)(
|
|
||||||
implicit valName: ValName)
|
implicit valName: ValName)
|
||||||
extends AdapterNode(TLAsyncImp)(clientFn, managerFn, num)
|
extends AdapterNode(TLAsyncImp)(clientFn, managerFn)
|
||||||
|
|
||||||
case class TLAsyncIdentityNode()(implicit valName: ValName) extends IdentityNode(TLAsyncImp)()
|
case class TLAsyncIdentityNode()(implicit valName: ValName) extends IdentityNode(TLAsyncImp)()
|
||||||
|
|
||||||
@ -119,10 +112,9 @@ object TLRationalImp extends SimpleNodeImp[TLRationalClientPortParameters, TLRat
|
|||||||
|
|
||||||
case class TLRationalAdapterNode(
|
case class TLRationalAdapterNode(
|
||||||
clientFn: TLRationalClientPortParameters => TLRationalClientPortParameters = { s => s },
|
clientFn: TLRationalClientPortParameters => TLRationalClientPortParameters = { s => s },
|
||||||
managerFn: TLRationalManagerPortParameters => TLRationalManagerPortParameters = { s => s },
|
managerFn: TLRationalManagerPortParameters => TLRationalManagerPortParameters = { s => s })(
|
||||||
num: Range.Inclusive = 0 to 999)(
|
|
||||||
implicit valName: ValName)
|
implicit valName: ValName)
|
||||||
extends AdapterNode(TLRationalImp)(clientFn, managerFn, num)
|
extends AdapterNode(TLRationalImp)(clientFn, managerFn)
|
||||||
|
|
||||||
case class TLRationalIdentityNode()(implicit valName: ValName) extends IdentityNode(TLRationalImp)()
|
case class TLRationalIdentityNode()(implicit valName: ValName) extends IdentityNode(TLRationalImp)()
|
||||||
|
|
||||||
|
@ -9,11 +9,9 @@ import freechips.rocketchip.diplomacy._
|
|||||||
case class SplitterArg[T](newSize: Int, ports: Seq[T])
|
case class SplitterArg[T](newSize: Int, ports: Seq[T])
|
||||||
case class TLSplitterNode(
|
case class TLSplitterNode(
|
||||||
clientFn: SplitterArg[TLClientPortParameters] => Seq[TLClientPortParameters],
|
clientFn: SplitterArg[TLClientPortParameters] => Seq[TLClientPortParameters],
|
||||||
managerFn: SplitterArg[TLManagerPortParameters] => Seq[TLManagerPortParameters],
|
managerFn: SplitterArg[TLManagerPortParameters] => Seq[TLManagerPortParameters])(
|
||||||
numClientPorts: Range.Inclusive = 0 to 999,
|
|
||||||
numManagerPorts: Range.Inclusive = 0 to 999)(
|
|
||||||
implicit valName: ValName)
|
implicit valName: ValName)
|
||||||
extends TLCustomNode(numClientPorts, numManagerPorts)
|
extends TLCustomNode
|
||||||
{
|
{
|
||||||
def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
|
def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) = {
|
||||||
require (oKnown == 0, s"${name} (a splitter) appears right of a := or :*=; use a :=* instead${lazyModule.line}")
|
require (oKnown == 0, s"${name} (a splitter) appears right of a := or :*=; use a :=* instead${lazyModule.line}")
|
||||||
|
@ -31,8 +31,6 @@ private case object ForceFanoutKey extends Field(ForceFanoutParams(false, false,
|
|||||||
class TLXbar(policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Parameters) extends LazyModule
|
class TLXbar(policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Parameters) extends LazyModule
|
||||||
{
|
{
|
||||||
val node = TLNexusNode(
|
val node = TLNexusNode(
|
||||||
numClientPorts = 1 to 999,
|
|
||||||
numManagerPorts = 1 to 999,
|
|
||||||
clientFn = { seq =>
|
clientFn = { seq =>
|
||||||
seq(0).copy(
|
seq(0).copy(
|
||||||
minLatency = seq.map(_.minLatency).min,
|
minLatency = seq.map(_.minLatency).min,
|
||||||
@ -159,20 +157,20 @@ class TLXbar(policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Parame
|
|||||||
val addressA = (in zip edgesIn) map { case (i, e) => e.address(i.a.bits) }
|
val addressA = (in zip edgesIn) map { case (i, e) => e.address(i.a.bits) }
|
||||||
val addressC = (in zip edgesIn) map { case (i, e) => e.address(i.c.bits) }
|
val addressC = (in zip edgesIn) map { case (i, e) => e.address(i.c.bits) }
|
||||||
|
|
||||||
val requestAIO = Vec(addressA.map { i => Vec(outputPorts.map { o => o(i) }) })
|
val requestAIO = addressA.map { i => outputPorts.map { o => o(i) } }
|
||||||
val requestCIO = Vec(addressC.map { i => Vec(outputPorts.map { o => o(i) }) })
|
val requestCIO = addressC.map { i => outputPorts.map { o => o(i) } }
|
||||||
val requestBOI = Vec(out.map { o => Vec(inputIdRanges.map { i => i.contains(o.b.bits.source) }) })
|
val requestBOI = out.map { o => inputIdRanges.map { i => i.contains(o.b.bits.source) } }
|
||||||
val requestDOI = Vec(out.map { o => Vec(inputIdRanges.map { i => i.contains(o.d.bits.source) }) })
|
val requestDOI = out.map { o => inputIdRanges.map { i => i.contains(o.d.bits.source) } }
|
||||||
val requestEIO = Vec(in.map { i => Vec(outputIdRanges.map { o => o.map(_.contains(i.e.bits.sink)).getOrElse(Bool(false)) }) })
|
val requestEIO = in.map { i => outputIdRanges.map { o => o.map(_.contains(i.e.bits.sink)).getOrElse(Bool(false)) } }
|
||||||
|
|
||||||
val beatsAI = Vec((in zip edgesIn) map { case (i, e) => e.numBeats1(i.a.bits) })
|
val beatsAI = (in zip edgesIn) map { case (i, e) => e.numBeats1(i.a.bits) }
|
||||||
val beatsBO = Vec((out zip edgesOut) map { case (o, e) => e.numBeats1(o.b.bits) })
|
val beatsBO = (out zip edgesOut) map { case (o, e) => e.numBeats1(o.b.bits) }
|
||||||
val beatsCI = Vec((in zip edgesIn) map { case (i, e) => e.numBeats1(i.c.bits) })
|
val beatsCI = (in zip edgesIn) map { case (i, e) => e.numBeats1(i.c.bits) }
|
||||||
val beatsDO = Vec((out zip edgesOut) map { case (o, e) => e.numBeats1(o.d.bits) })
|
val beatsDO = (out zip edgesOut) map { case (o, e) => e.numBeats1(o.d.bits) }
|
||||||
val beatsEI = Vec((in zip edgesIn) map { case (i, e) => e.numBeats1(i.e.bits) })
|
val beatsEI = (in zip edgesIn) map { case (i, e) => e.numBeats1(i.e.bits) }
|
||||||
|
|
||||||
// Which pairs support support transfers
|
// Which pairs support support transfers
|
||||||
def transpose[T](x: Seq[Seq[T]]) = Seq.tabulate(x(0).size) { i => Seq.tabulate(x.size) { j => x(j)(i) } }
|
def transpose[T](x: Seq[Seq[T]]) = if (x.isEmpty) Nil else Seq.tabulate(x(0).size) { i => Seq.tabulate(x.size) { j => x(j)(i) } }
|
||||||
def filter[T](data: Seq[T], mask: Seq[Boolean]) = (data zip mask).filter(_._2).map(_._1)
|
def filter[T](data: Seq[T], mask: Seq[Boolean]) = (data zip mask).filter(_._2).map(_._1)
|
||||||
|
|
||||||
// Fanout the input sources to the output sinks
|
// Fanout the input sources to the output sinks
|
||||||
|
Loading…
Reference in New Issue
Block a user