From 3656e975a1b0f6310b19243c25d2b7e6ddfdd98a Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Mon, 11 Sep 2017 19:31:44 -0700 Subject: [PATCH 01/32] diplomacy: ValName captures val bindings for Nodes --- macros/src/main/scala/ValName.scala | 22 ++++++++++++++++++++++ project/build.scala | 3 ++- src/main/scala/diplomacy/ValName.scala | 13 +++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 macros/src/main/scala/ValName.scala create mode 100644 src/main/scala/diplomacy/ValName.scala diff --git a/macros/src/main/scala/ValName.scala b/macros/src/main/scala/ValName.scala new file mode 100644 index 00000000..a76e13a8 --- /dev/null +++ b/macros/src/main/scala/ValName.scala @@ -0,0 +1,22 @@ +// See LICENSE.SiFive for license details. + +package freechips.rocketchip.macros + +import scala.language.experimental.macros +import scala.reflect.macros.blackbox.Context + +case class ValNameImpl(name: String) + +object ValNameImpl +{ + implicit def materialize: ValNameImpl = macro detail + def detail(c: Context): c.Expr[ValNameImpl] = { + import c.universe._ + def allOwners(s: c.Symbol): Seq[c.Symbol] = + if (s == `NoSymbol`) Nil else s +: allOwners(s.owner) + val terms = allOwners(c.internal.enclosingOwner).filter(_.isTerm).map(_.asTerm) + terms.filter(_.isVal).map(_.name.toString).find(_(0) != '$').map { s => + c.Expr[ValNameImpl] { q"_root_.freechips.rocketchip.macros.ValNameImpl(${s})" } + }.getOrElse(c.abort(c.enclosingPosition, "Not a valid application.")) + } +} diff --git a/project/build.scala b/project/build.scala index 529f035f..e7fa0a79 100644 --- a/project/build.scala +++ b/project/build.scala @@ -21,7 +21,8 @@ object BuildSettings extends Build { lazy val chisel = project in file("chisel3") lazy val hardfloat = project.dependsOn(chisel) - lazy val rocketchip = (project in file(".")).settings(chipSettings).dependsOn(chisel, hardfloat) + lazy val macros = project in file("macros") + lazy val rocketchip = (project in file(".")).settings(chipSettings).dependsOn(chisel, hardfloat, macros) lazy val addons = settingKey[Seq[String]]("list of addons used for this build") lazy val make = inputKey[Unit]("trigger backend-specific makefile command") diff --git a/src/main/scala/diplomacy/ValName.scala b/src/main/scala/diplomacy/ValName.scala new file mode 100644 index 00000000..0cc57d1c --- /dev/null +++ b/src/main/scala/diplomacy/ValName.scala @@ -0,0 +1,13 @@ +// See LICENSE.SiFive for license details. + +package freechips.rocketchip.diplomacy + +import scala.language.experimental.macros +import freechips.rocketchip.macros.ValNameImpl + +case class ValName(name: String) + +object ValName +{ + implicit def materialize(implicit x: ValNameImpl): ValName = ValName(x.name) +} From d89ee9d9d4c2dae9bbbd3253bf73e9b1a81b74bc Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Mon, 11 Sep 2017 23:33:44 -0700 Subject: [PATCH 02/32] nodes: grab a name on construction --- src/main/scala/amba/ahb/Nodes.scala | 21 ++++---- src/main/scala/amba/ahb/RegisterRouter.scala | 10 +--- src/main/scala/amba/ahb/ToTL.scala | 2 +- src/main/scala/amba/apb/Nodes.scala | 21 ++++---- src/main/scala/amba/apb/RegisterRouter.scala | 10 +--- src/main/scala/amba/axi4/Nodes.scala | 21 ++++---- src/main/scala/amba/axi4/RegisterRouter.scala | 10 +--- src/main/scala/amba/axi4/ToTL.scala | 2 +- src/main/scala/diplomacy/Nodes.scala | 47 +++++++++------- src/main/scala/tile/RocketTile.scala | 6 +-- src/main/scala/tilelink/Buffer.scala | 2 +- src/main/scala/tilelink/IntNodes.scala | 21 ++++---- src/main/scala/tilelink/NodeNumberer.scala | 2 +- src/main/scala/tilelink/Nodes.scala | 54 ++++++++++--------- src/main/scala/tilelink/RegisterRouter.scala | 21 ++------ src/main/scala/tilelink/ToAHB.scala | 2 +- src/main/scala/tilelink/ToAPB.scala | 2 +- src/main/scala/tilelink/ToAXI4.scala | 2 +- 18 files changed, 121 insertions(+), 135 deletions(-) diff --git a/src/main/scala/amba/ahb/Nodes.scala b/src/main/scala/amba/ahb/Nodes.scala index 86671b45..7cbc8fc6 100644 --- a/src/main/scala/amba/ahb/Nodes.scala +++ b/src/main/scala/amba/ahb/Nodes.scala @@ -25,23 +25,24 @@ object AHBImp extends NodeImp[AHBMasterPortParameters, AHBSlavePortParameters, A } // Nodes implemented inside modules -case class AHBIdentityNode() extends IdentityNode(AHBImp) -case class AHBMasterNode(portParams: Seq[AHBMasterPortParameters]) extends SourceNode(AHBImp)(portParams) -case class AHBSlaveNode(portParams: Seq[AHBSlavePortParameters]) extends SinkNode(AHBImp)(portParams) +case class AHBIdentityNode()(implicit valName: ValName) extends IdentityNode(AHBImp) +case class AHBMasterNode(portParams: Seq[AHBMasterPortParameters])(implicit valName: ValName) extends SourceNode(AHBImp)(portParams) +case class AHBSlaveNode(portParams: Seq[AHBSlavePortParameters])(implicit valName: ValName) extends SinkNode(AHBImp)(portParams) case class AHBNexusNode( masterFn: Seq[AHBMasterPortParameters] => AHBMasterPortParameters, slaveFn: Seq[AHBSlavePortParameters] => AHBSlavePortParameters, numMasterPorts: Range.Inclusive = 1 to 999, - numSlavePorts: Range.Inclusive = 1 to 999) + numSlavePorts: Range.Inclusive = 1 to 999)( + implicit valName: ValName) extends NexusNode(AHBImp)(masterFn, slaveFn, numMasterPorts, numSlavePorts) // Nodes passed from an inner module -case class AHBOutputNode() extends OutputNode(AHBImp) -case class AHBInputNode() extends InputNode(AHBImp) +case class AHBOutputNode()(implicit valName: ValName) extends OutputNode(AHBImp) +case class AHBInputNode()(implicit valName: ValName) extends InputNode(AHBImp) // Nodes used for external ports -case class AHBBlindOutputNode(portParams: Seq[AHBSlavePortParameters]) extends BlindOutputNode(AHBImp)(portParams) -case class AHBBlindInputNode(portParams: Seq[AHBMasterPortParameters]) extends BlindInputNode(AHBImp)(portParams) +case class AHBBlindOutputNode(portParams: Seq[AHBSlavePortParameters])(implicit valName: ValName) extends BlindOutputNode(AHBImp)(portParams) +case class AHBBlindInputNode(portParams: Seq[AHBMasterPortParameters])(implicit valName: ValName) extends BlindInputNode(AHBImp)(portParams) -case class AHBInternalOutputNode(portParams: Seq[AHBSlavePortParameters]) extends InternalOutputNode(AHBImp)(portParams) -case class AHBInternalInputNode(portParams: Seq[AHBMasterPortParameters]) extends InternalInputNode(AHBImp)(portParams) +case class AHBInternalOutputNode(portParams: Seq[AHBSlavePortParameters])(implicit valName: ValName) extends InternalOutputNode(AHBImp)(portParams) +case class AHBInternalInputNode(portParams: Seq[AHBMasterPortParameters])(implicit valName: ValName) extends InternalInputNode(AHBImp)(portParams) diff --git a/src/main/scala/amba/ahb/RegisterRouter.scala b/src/main/scala/amba/ahb/RegisterRouter.scala index 0b9b19ea..720e2162 100644 --- a/src/main/scala/amba/ahb/RegisterRouter.scala +++ b/src/main/scala/amba/ahb/RegisterRouter.scala @@ -10,8 +10,8 @@ import freechips.rocketchip.tilelink.{IntSourceNode, IntSourcePortSimple} import freechips.rocketchip.util.{HeterogeneousBag, MaskGen} import scala.math.{min,max} -class AHBRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false) - extends AHBSlaveNode(Seq(AHBSlavePortParameters( +case class AHBRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false)(implicit valName: ValName) + extends SinkNode(AHBImp)(Seq(AHBSlavePortParameters( Seq(AHBSlaveParameters( address = Seq(address), executable = executable, @@ -67,12 +67,6 @@ class AHBRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int } } -object AHBRegisterNode -{ - def apply(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false) = - new AHBRegisterNode(address, concurrency, beatBytes, undefZero, executable) -} - // These convenience methods below combine to make it possible to create a AHB // register mapped device from a totally abstract register mapped device. diff --git a/src/main/scala/amba/ahb/ToTL.scala b/src/main/scala/amba/ahb/ToTL.scala index d63f8f38..c18eab94 100644 --- a/src/main/scala/amba/ahb/ToTL.scala +++ b/src/main/scala/amba/ahb/ToTL.scala @@ -9,7 +9,7 @@ import freechips.rocketchip.diplomacy._ import freechips.rocketchip.tilelink._ import freechips.rocketchip.util.MaskGen -case class AHBToTLNode() extends MixedAdapterNode(AHBImp, TLImp)( +case class AHBToTLNode()(implicit valName: ValName) extends MixedAdapterNode(AHBImp, TLImp)( dFn = { case AHBMasterPortParameters(masters) => TLClientPortParameters(clients = masters.map { m => TLClientParameters(name = m.name, nodePath = m.nodePath) diff --git a/src/main/scala/amba/apb/Nodes.scala b/src/main/scala/amba/apb/Nodes.scala index a3618129..9364077c 100644 --- a/src/main/scala/amba/apb/Nodes.scala +++ b/src/main/scala/amba/apb/Nodes.scala @@ -26,23 +26,24 @@ object APBImp extends NodeImp[APBMasterPortParameters, APBSlavePortParameters, A } // Nodes implemented inside modules -case class APBIdentityNode() extends IdentityNode(APBImp) -case class APBMasterNode(portParams: Seq[APBMasterPortParameters]) extends SourceNode(APBImp)(portParams) -case class APBSlaveNode(portParams: Seq[APBSlavePortParameters]) extends SinkNode(APBImp)(portParams) +case class APBIdentityNode()(implicit valName: ValName) extends IdentityNode(APBImp) +case class APBMasterNode(portParams: Seq[APBMasterPortParameters])(implicit valName: ValName) extends SourceNode(APBImp)(portParams) +case class APBSlaveNode(portParams: Seq[APBSlavePortParameters])(implicit valName: ValName) extends SinkNode(APBImp)(portParams) case class APBNexusNode( masterFn: Seq[APBMasterPortParameters] => APBMasterPortParameters, slaveFn: Seq[APBSlavePortParameters] => APBSlavePortParameters, numMasterPorts: Range.Inclusive = 1 to 1, - numSlavePorts: Range.Inclusive = 1 to 1) + numSlavePorts: Range.Inclusive = 1 to 1)( + implicit valName: ValName) extends NexusNode(APBImp)(masterFn, slaveFn, numMasterPorts, numSlavePorts) // Nodes passed from an inner module -case class APBOutputNode() extends OutputNode(APBImp) -case class APBInputNode() extends InputNode(APBImp) +case class APBOutputNode()(implicit valName: ValName) extends OutputNode(APBImp) +case class APBInputNode()(implicit valName: ValName) extends InputNode(APBImp) // Nodes used for external ports -case class APBBlindOutputNode(portParams: Seq[APBSlavePortParameters]) extends BlindOutputNode(APBImp)(portParams) -case class APBBlindInputNode(portParams: Seq[APBMasterPortParameters]) extends BlindInputNode(APBImp)(portParams) +case class APBBlindOutputNode(portParams: Seq[APBSlavePortParameters])(implicit valName: ValName) extends BlindOutputNode(APBImp)(portParams) +case class APBBlindInputNode(portParams: Seq[APBMasterPortParameters])(implicit valName: ValName) extends BlindInputNode(APBImp)(portParams) -case class APBInternalOutputNode(portParams: Seq[APBSlavePortParameters]) extends InternalOutputNode(APBImp)(portParams) -case class APBInternalInputNode(portParams: Seq[APBMasterPortParameters]) extends InternalInputNode(APBImp)(portParams) +case class APBInternalOutputNode(portParams: Seq[APBSlavePortParameters])(implicit valName: ValName) extends InternalOutputNode(APBImp)(portParams) +case class APBInternalInputNode(portParams: Seq[APBMasterPortParameters])(implicit valName: ValName) extends InternalInputNode(APBImp)(portParams) diff --git a/src/main/scala/amba/apb/RegisterRouter.scala b/src/main/scala/amba/apb/RegisterRouter.scala index 1cd52a63..3c136552 100644 --- a/src/main/scala/amba/apb/RegisterRouter.scala +++ b/src/main/scala/amba/apb/RegisterRouter.scala @@ -10,8 +10,8 @@ import freechips.rocketchip.tilelink.{IntSourceNode, IntSourcePortSimple} import freechips.rocketchip.util.HeterogeneousBag import scala.math.{min,max} -class APBRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false) - extends APBSlaveNode(Seq(APBSlavePortParameters( +case class APBRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false)(implicit valName: ValName) + extends SinkNode(APBImp)(Seq(APBSlavePortParameters( Seq(APBSlaveParameters( address = Seq(address), executable = executable, @@ -51,12 +51,6 @@ class APBRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int } } -object APBRegisterNode -{ - def apply(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false) = - new APBRegisterNode(address, concurrency, beatBytes, undefZero, executable) -} - // These convenience methods below combine to make it possible to create a APB // register mapped device from a totally abstract register mapped device. diff --git a/src/main/scala/amba/axi4/Nodes.scala b/src/main/scala/amba/axi4/Nodes.scala index dacbefcc..8b68470c 100644 --- a/src/main/scala/amba/axi4/Nodes.scala +++ b/src/main/scala/amba/axi4/Nodes.scala @@ -26,22 +26,23 @@ object AXI4Imp extends NodeImp[AXI4MasterPortParameters, AXI4SlavePortParameters } // Nodes implemented inside modules -case class AXI4IdentityNode() extends IdentityNode(AXI4Imp) -case class AXI4MasterNode(portParams: Seq[AXI4MasterPortParameters]) extends SourceNode(AXI4Imp)(portParams) -case class AXI4SlaveNode(portParams: Seq[AXI4SlavePortParameters]) extends SinkNode(AXI4Imp)(portParams) +case class AXI4IdentityNode()(implicit valName: ValName) extends IdentityNode(AXI4Imp) +case class AXI4MasterNode(portParams: Seq[AXI4MasterPortParameters])(implicit valName: ValName) extends SourceNode(AXI4Imp)(portParams) +case class AXI4SlaveNode(portParams: Seq[AXI4SlavePortParameters])(implicit valName: ValName) extends SinkNode(AXI4Imp)(portParams) case class AXI4AdapterNode( masterFn: AXI4MasterPortParameters => AXI4MasterPortParameters, slaveFn: AXI4SlavePortParameters => AXI4SlavePortParameters, - numPorts: Range.Inclusive = 0 to 999) + numPorts: Range.Inclusive = 0 to 999)( + implicit valName: ValName) extends AdapterNode(AXI4Imp)(masterFn, slaveFn, numPorts) // Nodes passed from an inner module -case class AXI4OutputNode() extends OutputNode(AXI4Imp) -case class AXI4InputNode() extends InputNode(AXI4Imp) +case class AXI4OutputNode()(implicit valName: ValName) extends OutputNode(AXI4Imp) +case class AXI4InputNode()(implicit valName: ValName) extends InputNode(AXI4Imp) // Nodes used for external ports -case class AXI4BlindOutputNode(portParams: Seq[AXI4SlavePortParameters]) extends BlindOutputNode(AXI4Imp)(portParams) -case class AXI4BlindInputNode(portParams: Seq[AXI4MasterPortParameters]) extends BlindInputNode(AXI4Imp)(portParams) +case class AXI4BlindOutputNode(portParams: Seq[AXI4SlavePortParameters])(implicit valName: ValName) extends BlindOutputNode(AXI4Imp)(portParams) +case class AXI4BlindInputNode(portParams: Seq[AXI4MasterPortParameters])(implicit valName: ValName) extends BlindInputNode(AXI4Imp)(portParams) -case class AXI4InternalOutputNode(portParams: Seq[AXI4SlavePortParameters]) extends InternalOutputNode(AXI4Imp)(portParams) -case class AXI4InternalInputNode(portParams: Seq[AXI4MasterPortParameters]) extends InternalInputNode(AXI4Imp)(portParams) +case class AXI4InternalOutputNode(portParams: Seq[AXI4SlavePortParameters])(implicit valName: ValName) extends InternalOutputNode(AXI4Imp)(portParams) +case class AXI4InternalInputNode(portParams: Seq[AXI4MasterPortParameters])(implicit valName: ValName) extends InternalInputNode(AXI4Imp)(portParams) diff --git a/src/main/scala/amba/axi4/RegisterRouter.scala b/src/main/scala/amba/axi4/RegisterRouter.scala index 20d431b0..9f9b3082 100644 --- a/src/main/scala/amba/axi4/RegisterRouter.scala +++ b/src/main/scala/amba/axi4/RegisterRouter.scala @@ -10,8 +10,8 @@ import freechips.rocketchip.tilelink.{IntSourceNode, IntSourcePortSimple} import freechips.rocketchip.util.{HeterogeneousBag, MaskGen} import scala.math.{min,max} -class AXI4RegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false) - extends AXI4SlaveNode(Seq(AXI4SlavePortParameters( +case class AXI4RegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false)(implicit valName: ValName) + extends SinkNode(AXI4Imp)(Seq(AXI4SlavePortParameters( Seq(AXI4SlaveParameters( address = Seq(address), executable = executable, @@ -77,12 +77,6 @@ class AXI4RegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int } } -object AXI4RegisterNode -{ - def apply(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false) = - new AXI4RegisterNode(address, concurrency, beatBytes, undefZero, executable) -} - // These convenience methods below combine to make it possible to create a AXI4 // register mapped device from a totally abstract register mapped device. diff --git a/src/main/scala/amba/axi4/ToTL.scala b/src/main/scala/amba/axi4/ToTL.scala index 54610873..8d77556d 100644 --- a/src/main/scala/amba/axi4/ToTL.scala +++ b/src/main/scala/amba/axi4/ToTL.scala @@ -9,7 +9,7 @@ import freechips.rocketchip.diplomacy._ import freechips.rocketchip.tilelink._ import freechips.rocketchip.util._ -case class AXI4ToTLNode() extends MixedAdapterNode(AXI4Imp, TLImp)( +case class AXI4ToTLNode()(implicit valName: ValName) extends MixedAdapterNode(AXI4Imp, TLImp)( dFn = { case AXI4MasterPortParameters(masters, userBits) => masters.foreach { m => require (m.maxFlight.isDefined, "AXI4 must include a transaction maximum per ID to convert to TL") } val maxFlight = masters.map(_.maxFlight.get).max diff --git a/src/main/scala/diplomacy/Nodes.scala b/src/main/scala/diplomacy/Nodes.scala index 7fc892e8..75c1f1a5 100644 --- a/src/main/scala/diplomacy/Nodes.scala +++ b/src/main/scala/diplomacy/Nodes.scala @@ -67,7 +67,7 @@ trait OutwardNodeImp[DO, UO, EO, BO <: Data] abstract class NodeImp[D, U, EO, EI, B <: Data] extends Object with InwardNodeImp[D, U, EI, B] with OutwardNodeImp[D, U, EO, B] -abstract class BaseNode +abstract class BaseNode(implicit val valName: ValName) { require (!LazyModule.stack.isEmpty, "You cannot create a node outside a LazyModule!") @@ -178,7 +178,8 @@ abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( inner: InwardNodeImp [DI, UI, EI, BI], outer: OutwardNodeImp[DO, UO, EO, BO])( protected[diplomacy] val numPO: Range.Inclusive, - protected[diplomacy] val numPI: Range.Inclusive) + protected[diplomacy] val numPI: Range.Inclusive)( + implicit valName: ValName) extends BaseNode with InwardNode[DI, UI, BI] with OutwardNode[DO, UO, BO] { protected[diplomacy] def resolveStar(iKnown: Int, oKnown: Int, iStar: Int, oStar: Int): (Int, Int) @@ -308,7 +309,8 @@ abstract class MixedCustomNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( inner: InwardNodeImp [DI, UI, EI, BI], outer: OutwardNodeImp[DO, UO, EO, BO])( numPO: Range.Inclusive, - numPI: Range.Inclusive) + numPI: Range.Inclusive)( + implicit valName: ValName) extends MixedNode(inner, outer)(numPO, numPI) { def resolveStar(iKnown: Int, oKnown: Int, iStars: Int, oStars: Int): (Int, Int) @@ -318,7 +320,8 @@ 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])( numPO: Range.Inclusive, - numPI: Range.Inclusive) + numPI: Range.Inclusive)( + implicit valName: ValName) extends MixedCustomNode(imp, imp)(numPO, numPI) class MixedAdapterNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( @@ -326,7 +329,8 @@ class MixedAdapterNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( outer: OutwardNodeImp[DO, UO, EO, BO])( dFn: DI => DO, uFn: UO => UI, - num: Range.Inclusive = 0 to 999) + num: Range.Inclusive = 0 to 999)( + implicit valName: ValName) extends MixedNode(inner, outer)(num, num) { val externalIn: Boolean = true @@ -358,7 +362,8 @@ class MixedNexusNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( dFn: Seq[DI] => DO, uFn: Seq[UO] => UI, numPO: Range.Inclusive = 1 to 999, - numPI: Range.Inclusive = 1 to 999) + numPI: Range.Inclusive = 1 to 999)( + implicit valName: ValName) extends MixedNode(inner, outer)(numPO, numPI) { // require (numPO.end >= 1, s"${name} does not accept outputs${lazyModule.line}") @@ -379,14 +384,16 @@ class MixedNexusNode[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])( dFn: D => D, uFn: U => U, - num: Range.Inclusive = 0 to 999) + num: Range.Inclusive = 0 to 999)( + implicit valName: ValName) extends MixedAdapterNode[D, U, EI, B, D, U, EO, B](imp, imp)(dFn, uFn, num) class NexusNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])( dFn: Seq[D] => D, uFn: Seq[U] => U, numPO: Range.Inclusive = 1 to 999, - numPI: Range.Inclusive = 1 to 999) + numPI: Range.Inclusive = 1 to 999)( + implicit valName: ValName) extends MixedNexusNode[D, U, EI, B, D, U, EO, B](imp, imp)(dFn, uFn, numPO, numPI) case class SplitterArg[T](newSize: Int, ports: Seq[T]) @@ -396,7 +403,8 @@ class MixedSplitterNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( dFn: SplitterArg[DI] => Seq[DO], uFn: SplitterArg[UO] => Seq[UI], numPO: Range.Inclusive = 1 to 999, - numPI: Range.Inclusive = 1 to 999) + numPI: Range.Inclusive = 1 to 999)( + implicit valName: ValName) extends MixedNode(inner, outer)(numPO, numPI) { override val externalIn: Boolean = true @@ -425,20 +433,21 @@ class SplitterNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])( dFn: SplitterArg[D] => Seq[D], uFn: SplitterArg[U] => Seq[U], numPO: Range.Inclusive = 1 to 999, - numPI: Range.Inclusive = 1 to 999) + numPI: Range.Inclusive = 1 to 999)( + implicit valName: ValName) extends MixedSplitterNode[D, U, EI, B, D, U, EO, B](imp, imp)(dFn, uFn, numPO, numPI) -class IdentityNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B]) +class IdentityNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(implicit valName: ValName) extends AdapterNode(imp)({s => s}, {s => s}) -class OutputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B]) extends IdentityNode(imp) +class OutputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(implicit valName: ValName) extends IdentityNode(imp) { override val externalIn: Boolean = false override val externalOut: Boolean = true override lazy val bundleIn = bundleOut } -class InputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B]) extends IdentityNode(imp) +class InputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(implicit valName: ValName) extends IdentityNode(imp) { override val externalIn: Boolean = true override val externalOut: Boolean = false @@ -446,7 +455,7 @@ class InputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B]) extends override lazy val bundleOut = bundleIn } -class SourceNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(po: Seq[D]) +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) { override val externalIn: Boolean = false @@ -465,7 +474,7 @@ class SourceNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(po: Seq override lazy val bundleIn = { require(false, s"${name} has no bundleIn; try bundleOut?"); bundleOut } } -class SinkNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(pi: Seq[U]) +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) { override val externalIn: Boolean = true @@ -484,7 +493,7 @@ class SinkNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(pi: Seq[U override lazy val bundleOut = { require(false, s"${name} has no bundleOut; try bundleIn?"); bundleIn } } -class BlindOutputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(pi: Seq[U]) +class BlindOutputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(pi: Seq[U])(implicit valName: ValName) extends SinkNode(imp)(pi) { override val externalIn: Boolean = false @@ -492,7 +501,7 @@ class BlindOutputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(pi override lazy val bundleOut = bundleIn } -class BlindInputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(po: Seq[D]) +class BlindInputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(po: Seq[D])(implicit valName: ValName) extends SourceNode(imp)(po) { override val externalOut: Boolean = false @@ -500,7 +509,7 @@ class BlindInputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(po: override lazy val bundleIn = bundleOut } -class InternalOutputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(pi: Seq[U]) +class InternalOutputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(pi: Seq[U])(implicit valName: ValName) extends SinkNode(imp)(pi) { override val externalIn: Boolean = false @@ -509,7 +518,7 @@ class InternalOutputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B]) override lazy val bundleOut = bundleIn } -class InternalInputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(po: Seq[D]) +class InternalInputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(po: Seq[D])(implicit valName: ValName) extends SourceNode(imp)(po) { override val externalIn: Boolean = false diff --git a/src/main/scala/tile/RocketTile.scala b/src/main/scala/tile/RocketTile.scala index caa6f1a1..14d91e6f 100644 --- a/src/main/scala/tile/RocketTile.scala +++ b/src/main/scala/tile/RocketTile.scala @@ -244,7 +244,7 @@ class SyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) val masterNode = TLOutputNode() masterNode :=* optionalMasterBuffer(rocket.masterNode) - val slaveNode = new TLInputNode() { override def reverse = true } + val slaveNode = new TLInputNode()(ValName("slave")) { override def reverse = true } DisableMonitors { implicit p => rocket.slaveNode :*= optionalSlaveBuffer(slaveNode) } // Fully async interrupts need synchronizers. @@ -265,7 +265,7 @@ class AsyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters source.node :=* rocket.masterNode masterNode :=* source.node - val slaveNode = new TLAsyncInputNode() { override def reverse = true } + val slaveNode = new TLAsyncInputNode()(ValName("slave")) { override def reverse = true } val sink = LazyModule(new TLAsyncCrossingSink) DisableMonitors { implicit p => @@ -294,7 +294,7 @@ class RationalRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Paramet source.node :=* optionalMasterBuffer(rocket.masterNode) masterNode :=* source.node - val slaveNode = new TLRationalInputNode() { override def reverse = true } + val slaveNode = new TLRationalInputNode()(ValName("slave")) { override def reverse = true } val sink = LazyModule(new TLRationalCrossingSink(SlowToFast)) DisableMonitors { implicit p => diff --git a/src/main/scala/tilelink/Buffer.scala b/src/main/scala/tilelink/Buffer.scala index 4ce803cc..6242a1a9 100644 --- a/src/main/scala/tilelink/Buffer.scala +++ b/src/main/scala/tilelink/Buffer.scala @@ -13,7 +13,7 @@ class TLBufferNode ( b: BufferParams, c: BufferParams, d: BufferParams, - e: BufferParams)(implicit p: Parameters) extends TLAdapterNode( + e: BufferParams)(implicit valName: ValName) extends TLAdapterNode( clientFn = { p => p.copy(minLatency = p.minLatency + b.latency + c.latency) }, managerFn = { p => p.copy(minLatency = p.minLatency + a.latency + d.latency) } ) { diff --git a/src/main/scala/tilelink/IntNodes.scala b/src/main/scala/tilelink/IntNodes.scala index 3b9cab83..c9deea7b 100644 --- a/src/main/scala/tilelink/IntNodes.scala +++ b/src/main/scala/tilelink/IntNodes.scala @@ -88,25 +88,26 @@ object IntImp extends NodeImp[IntSourcePortParameters, IntSinkPortParameters, In pu.copy(sinks = pu.sinks.map { s => s.copy (nodePath = node +: s.nodePath) }) } -case class IntIdentityNode() extends IdentityNode(IntImp) -case class IntSourceNode(portParams: Seq[IntSourcePortParameters]) extends SourceNode(IntImp)(portParams) -case class IntSinkNode(portParams: Seq[IntSinkPortParameters]) extends SinkNode(IntImp)(portParams) +case class IntIdentityNode()(implicit valName: ValName) extends IdentityNode(IntImp) +case class IntSourceNode(portParams: Seq[IntSourcePortParameters])(implicit valName: ValName) extends SourceNode(IntImp)(portParams) +case class IntSinkNode(portParams: Seq[IntSinkPortParameters])(implicit valName: ValName) extends SinkNode(IntImp)(portParams) case class IntNexusNode( sourceFn: Seq[IntSourcePortParameters] => IntSourcePortParameters, sinkFn: Seq[IntSinkPortParameters] => IntSinkPortParameters, numSourcePorts: Range.Inclusive = 0 to 128, - numSinkPorts: Range.Inclusive = 0 to 128) + numSinkPorts: Range.Inclusive = 0 to 128)( + implicit valName: ValName) extends NexusNode(IntImp)(sourceFn, sinkFn, numSourcePorts, numSinkPorts) -case class IntOutputNode() extends OutputNode(IntImp) -case class IntInputNode() extends InputNode(IntImp) +case class IntOutputNode()(implicit valName: ValName) extends OutputNode(IntImp) +case class IntInputNode()(implicit valName: ValName) extends InputNode(IntImp) -case class IntBlindOutputNode(portParams: Seq[IntSinkPortParameters]) extends BlindOutputNode(IntImp)(portParams) -case class IntBlindInputNode(portParams: Seq[IntSourcePortParameters]) extends BlindInputNode(IntImp)(portParams) +case class IntBlindOutputNode(portParams: Seq[IntSinkPortParameters])(implicit valName: ValName) extends BlindOutputNode(IntImp)(portParams) +case class IntBlindInputNode(portParams: Seq[IntSourcePortParameters])(implicit valName: ValName) extends BlindInputNode(IntImp)(portParams) -case class IntInternalOutputNode(portParams: Seq[IntSinkPortParameters]) extends InternalOutputNode(IntImp)(portParams) -case class IntInternalInputNode(portParams: Seq[IntSourcePortParameters]) extends InternalInputNode(IntImp)(portParams) +case class IntInternalOutputNode(portParams: Seq[IntSinkPortParameters])(implicit valName: ValName) extends InternalOutputNode(IntImp)(portParams) +case class IntInternalInputNode(portParams: Seq[IntSourcePortParameters])(implicit valName: ValName) extends InternalInputNode(IntImp)(portParams) class IntXbar()(implicit p: Parameters) extends LazyModule { diff --git a/src/main/scala/tilelink/NodeNumberer.scala b/src/main/scala/tilelink/NodeNumberer.scala index 1f7fa6f3..cee8508b 100644 --- a/src/main/scala/tilelink/NodeNumberer.scala +++ b/src/main/scala/tilelink/NodeNumberer.scala @@ -7,7 +7,7 @@ import chisel3.internal.sourceinfo.SourceInfo import freechips.rocketchip.config.Parameters import freechips.rocketchip.diplomacy._ -case class TLNodeNumbererNode(nodeAddressOffset: Option[Int] = None) extends TLCustomNode(0 to 999, 0 to 999) +case class TLNodeNumbererNode(nodeAddressOffset: Option[Int] = None)(implicit valName: ValName) extends TLCustomNode(0 to 999, 0 to 999) { val externalIn = true val externalOut = true diff --git a/src/main/scala/tilelink/Nodes.scala b/src/main/scala/tilelink/Nodes.scala index 4d4912f4..273d9659 100644 --- a/src/main/scala/tilelink/Nodes.scala +++ b/src/main/scala/tilelink/Nodes.scala @@ -64,57 +64,61 @@ object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TL } // Nodes implemented inside modules -case class TLIdentityNode() extends IdentityNode(TLImp) -case class TLClientNode(portParams: Seq[TLClientPortParameters]) extends SourceNode(TLImp)(portParams) -case class TLManagerNode(portParams: Seq[TLManagerPortParameters]) extends SinkNode(TLImp)(portParams) +case class TLIdentityNode()(implicit valName: ValName) extends IdentityNode(TLImp) +case class TLClientNode(portParams: Seq[TLClientPortParameters])(implicit valName: ValName) extends SourceNode(TLImp)(portParams) +case class TLManagerNode(portParams: Seq[TLManagerPortParameters])(implicit valName: ValName) extends SinkNode(TLImp)(portParams) object TLClientNode { - def apply(params: TLClientParameters) = + def apply(params: TLClientParameters)(implicit valName: ValName) = new TLClientNode(Seq(TLClientPortParameters(Seq(params)))) } object TLManagerNode { - def apply(beatBytes: Int, params: TLManagerParameters) = + def apply(beatBytes: Int, params: TLManagerParameters)(implicit valName: ValName) = new TLManagerNode(Seq(TLManagerPortParameters(Seq(params), beatBytes, minLatency = 0))) } case class TLAdapterNode( clientFn: TLClientPortParameters => TLClientPortParameters, managerFn: TLManagerPortParameters => TLManagerPortParameters, - num: Range.Inclusive = 0 to 999) + num: Range.Inclusive = 0 to 999)( + implicit valName: ValName) extends AdapterNode(TLImp)(clientFn, managerFn, num) case class TLNexusNode( clientFn: Seq[TLClientPortParameters] => TLClientPortParameters, managerFn: Seq[TLManagerPortParameters] => TLManagerPortParameters, numClientPorts: Range.Inclusive = 1 to 999, - numManagerPorts: Range.Inclusive = 1 to 999) + numManagerPorts: Range.Inclusive = 1 to 999)( + implicit valName: ValName) extends NexusNode(TLImp)(clientFn, managerFn, numClientPorts, numManagerPorts) case class TLSplitterNode( clientFn: SplitterArg[TLClientPortParameters] => Seq[TLClientPortParameters], managerFn: SplitterArg[TLManagerPortParameters] => Seq[TLManagerPortParameters], numClientPorts: Range.Inclusive = 0 to 999, - numManagerPorts: Range.Inclusive = 0 to 999) + numManagerPorts: Range.Inclusive = 0 to 999)( + implicit valName: ValName) extends SplitterNode(TLImp)(clientFn, managerFn, numClientPorts, numManagerPorts) abstract class TLCustomNode( numClientPorts: Range.Inclusive, - numManagerPorts: Range.Inclusive) + numManagerPorts: Range.Inclusive)( + implicit valName: ValName) extends CustomNode(TLImp)(numClientPorts, numManagerPorts) // Nodes passed from an inner module -case class TLOutputNode() extends OutputNode(TLImp) -case class TLInputNode() extends InputNode(TLImp) +case class TLOutputNode()(implicit valName: ValName) extends OutputNode(TLImp) +case class TLInputNode()(implicit valName: ValName) extends InputNode(TLImp) // Nodes used for external ports -case class TLBlindOutputNode(portParams: Seq[TLManagerPortParameters]) extends BlindOutputNode(TLImp)(portParams) -case class TLBlindInputNode(portParams: Seq[TLClientPortParameters]) extends BlindInputNode(TLImp)(portParams) +case class TLBlindOutputNode(portParams: Seq[TLManagerPortParameters])(implicit valName: ValName) extends BlindOutputNode(TLImp)(portParams) +case class TLBlindInputNode(portParams: Seq[TLClientPortParameters])(implicit valName: ValName) extends BlindInputNode(TLImp)(portParams) -case class TLInternalOutputNode(portParams: Seq[TLManagerPortParameters]) extends InternalOutputNode(TLImp)(portParams) -case class TLInternalInputNode(portParams: Seq[TLClientPortParameters]) extends InternalInputNode(TLImp)(portParams) +case class TLInternalOutputNode(portParams: Seq[TLManagerPortParameters])(implicit valName: ValName) extends InternalOutputNode(TLImp)(portParams) +case class TLInternalInputNode(portParams: Seq[TLClientPortParameters])(implicit valName: ValName) extends InternalInputNode(TLImp)(portParams) /** Synthesizeable unit tests */ import freechips.rocketchip.unittest._ @@ -156,16 +160,16 @@ object TLAsyncImp extends NodeImp[TLAsyncClientPortParameters, TLAsyncManagerPor pu.copy(base = pu.base.copy(managers = pu.base.managers.map { m => m.copy (nodePath = node +: m.nodePath) })) } -case class TLAsyncIdentityNode() extends IdentityNode(TLAsyncImp) -case class TLAsyncOutputNode() extends OutputNode(TLAsyncImp) -case class TLAsyncInputNode() extends InputNode(TLAsyncImp) +case class TLAsyncIdentityNode()(implicit valName: ValName) extends IdentityNode(TLAsyncImp) +case class TLAsyncOutputNode()(implicit valName: ValName) extends OutputNode(TLAsyncImp) +case class TLAsyncInputNode()(implicit valName: ValName) extends InputNode(TLAsyncImp) -case class TLAsyncSourceNode(sync: Int) +case class TLAsyncSourceNode(sync: Int)(implicit valName: ValName) extends MixedAdapterNode(TLImp, TLAsyncImp)( dFn = { p => TLAsyncClientPortParameters(p) }, uFn = { p => p.base.copy(minLatency = sync+1) }) // discard cycles in other clock domain -case class TLAsyncSinkNode(depth: Int, sync: Int) +case class TLAsyncSinkNode(depth: Int, sync: Int)(implicit valName: ValName) extends MixedAdapterNode(TLAsyncImp, TLImp)( dFn = { p => p.base.copy(minLatency = sync+1) }, uFn = { p => TLAsyncManagerPortParameters(depth, p) }) @@ -186,16 +190,16 @@ object TLRationalImp extends NodeImp[TLRationalClientPortParameters, TLRationalM pu.copy(base = pu.base.copy(managers = pu.base.managers.map { m => m.copy (nodePath = node +: m.nodePath) })) } -case class TLRationalIdentityNode() extends IdentityNode(TLRationalImp) -case class TLRationalOutputNode() extends OutputNode(TLRationalImp) -case class TLRationalInputNode() extends InputNode(TLRationalImp) +case class TLRationalIdentityNode()(implicit valName: ValName) extends IdentityNode(TLRationalImp) +case class TLRationalOutputNode()(implicit valName: ValName) extends OutputNode(TLRationalImp) +case class TLRationalInputNode()(implicit valName: ValName) extends InputNode(TLRationalImp) -case class TLRationalSourceNode() +case class TLRationalSourceNode()(implicit valName: ValName) extends MixedAdapterNode(TLImp, TLRationalImp)( dFn = { p => TLRationalClientPortParameters(p) }, uFn = { p => p.base.copy(minLatency = 1) }) // discard cycles from other clock domain -case class TLRationalSinkNode(direction: RationalDirection) +case class TLRationalSinkNode(direction: RationalDirection)(implicit valName: ValName) extends MixedAdapterNode(TLRationalImp, TLImp)( dFn = { p => p.base.copy(minLatency = 1) }, uFn = { p => TLRationalManagerPortParameters(direction, p) }) diff --git a/src/main/scala/tilelink/RegisterRouter.scala b/src/main/scala/tilelink/RegisterRouter.scala index 4c2c52df..5ecd5398 100644 --- a/src/main/scala/tilelink/RegisterRouter.scala +++ b/src/main/scala/tilelink/RegisterRouter.scala @@ -9,15 +9,16 @@ import freechips.rocketchip.regmapper._ import freechips.rocketchip.util.HeterogeneousBag import scala.math.{min,max} -class TLRegisterNode( +case class TLRegisterNode( address: Seq[AddressSet], device: Device, deviceKey: String = "reg/control", concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, - executable: Boolean = false) - extends TLManagerNode(Seq(TLManagerPortParameters( + executable: Boolean = false)( + implicit valName: ValName) + extends SinkNode(TLImp)(Seq(TLManagerPortParameters( Seq(TLManagerParameters( address = address, resources = Seq(Resource(device, deviceKey)), @@ -81,20 +82,6 @@ class TLRegisterNode( } } -object TLRegisterNode -{ - def apply( - address: Seq[AddressSet], - device: Device, - deviceKey: String = "reg/control", - concurrency: Int = 0, - beatBytes: Int = 4, - undefZero: Boolean = true, - executable: Boolean = false) = - new TLRegisterNode(address, device, deviceKey, concurrency, beatBytes, undefZero, executable) -} - -// These convenience methods below combine to make it possible to create a TL2 // register mapped device from a totally abstract register mapped device. // See GPIO.scala in this directory for an example diff --git a/src/main/scala/tilelink/ToAHB.scala b/src/main/scala/tilelink/ToAHB.scala index cadae46e..bf61964d 100644 --- a/src/main/scala/tilelink/ToAHB.scala +++ b/src/main/scala/tilelink/ToAHB.scala @@ -11,7 +11,7 @@ import freechips.rocketchip.util._ import scala.math.{min, max} import AHBParameters._ -case class TLToAHBNode() extends MixedAdapterNode(TLImp, AHBImp)( +case class TLToAHBNode()(implicit valName: ValName) extends MixedAdapterNode(TLImp, AHBImp)( dFn = { case TLClientPortParameters(clients, unsafeAtomics, minLatency) => val masters = clients.map { case c => AHBMasterParameters(name = c.name, nodePath = c.nodePath) } AHBMasterPortParameters(masters) diff --git a/src/main/scala/tilelink/ToAPB.scala b/src/main/scala/tilelink/ToAPB.scala index 2d0bf2ae..e6ed742a 100644 --- a/src/main/scala/tilelink/ToAPB.scala +++ b/src/main/scala/tilelink/ToAPB.scala @@ -10,7 +10,7 @@ import freechips.rocketchip.amba.apb._ import scala.math.{min, max} import APBParameters._ -case class TLToAPBNode() extends MixedAdapterNode(TLImp, APBImp)( +case class TLToAPBNode()(implicit valName: ValName) extends MixedAdapterNode(TLImp, APBImp)( dFn = { case TLClientPortParameters(clients, unsafeAtomics, minLatency) => val masters = clients.map { case c => APBMasterParameters(name = c.name, nodePath = c.nodePath) } APBMasterPortParameters(masters) diff --git a/src/main/scala/tilelink/ToAXI4.scala b/src/main/scala/tilelink/ToAXI4.scala index a4588006..21385abb 100644 --- a/src/main/scala/tilelink/ToAXI4.scala +++ b/src/main/scala/tilelink/ToAXI4.scala @@ -10,7 +10,7 @@ import freechips.rocketchip.util._ import freechips.rocketchip.amba.axi4._ import scala.math.{min, max} -case class TLToAXI4Node(beatBytes: Int, stripBits: Int = 0) extends MixedAdapterNode(TLImp, AXI4Imp)( +case class TLToAXI4Node(beatBytes: Int, stripBits: Int = 0)(implicit valName: ValName) extends MixedAdapterNode(TLImp, AXI4Imp)( dFn = { p => p.clients.foreach { c => require (c.sourceId.start % (1 << stripBits) == 0 && From 87d597c70d2a2b2e85e5957133b1e43222c57904 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Tue, 12 Sep 2017 12:09:58 -0700 Subject: [PATCH 03/32] ahb apb: remove unintentional var --- src/main/scala/amba/ahb/Test.scala | 2 +- src/main/scala/amba/apb/Test.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/amba/ahb/Test.scala b/src/main/scala/amba/ahb/Test.scala index 507c306e..dde3a403 100644 --- a/src/main/scala/amba/ahb/Test.scala +++ b/src/main/scala/amba/ahb/Test.scala @@ -21,7 +21,7 @@ class AHBFuzzNative(aFlow: Boolean, txns: Int)(implicit p: Parameters) extends L { val fuzz = LazyModule(new TLFuzzer(txns)) val model = LazyModule(new TLRAMModel("AHBFuzzNative")) - var xbar = LazyModule(new AHBFanout) + val xbar = LazyModule(new AHBFanout) val ram = LazyModule(new AHBRAM(AddressSet(0x0, 0xff))) val gpio = LazyModule(new RRTest0(0x100)) diff --git a/src/main/scala/amba/apb/Test.scala b/src/main/scala/amba/apb/Test.scala index 948ab197..9b762fc1 100644 --- a/src/main/scala/amba/apb/Test.scala +++ b/src/main/scala/amba/apb/Test.scala @@ -20,7 +20,7 @@ class APBFuzzBridge(aFlow: Boolean, txns: Int)(implicit p: Parameters) extends L { val fuzz = LazyModule(new TLFuzzer(txns)) val model = LazyModule(new TLRAMModel("APBFuzzMaster")) - var xbar = LazyModule(new APBFanout) + val xbar = LazyModule(new APBFanout) val ram = LazyModule(new APBRAM(AddressSet(0x0, 0xff))) val gpio = LazyModule(new RRTest0(0x100)) From dfc815f4d364c33f009937b38da4d8204a5319c7 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Tue, 12 Sep 2017 12:10:39 -0700 Subject: [PATCH 04/32] rocket: invoke LazyModule at point of use/binding --- src/main/scala/groundtest/Tile.scala | 3 ++- src/main/scala/rocket/HellaCache.scala | 5 ++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/scala/groundtest/Tile.scala b/src/main/scala/groundtest/Tile.scala index f5ae3c3a..78a4aa63 100644 --- a/src/main/scala/groundtest/Tile.scala +++ b/src/main/scala/groundtest/Tile.scala @@ -5,6 +5,7 @@ package freechips.rocketchip.groundtest import Chisel._ import freechips.rocketchip.config._ +import freechips.rocketchip.diplomacy._ import freechips.rocketchip.coreplex._ import freechips.rocketchip.rocket.{HellaCache, RocketCoreParams} import freechips.rocketchip.tile._ @@ -29,7 +30,7 @@ case object GroundTestTilesKey extends Field[Seq[GroundTestTileParams]] abstract class GroundTestTile(params: GroundTestTileParams)(implicit p: Parameters) extends BaseTile(params)(p) { val slave = None - val dcacheOpt = params.dcache.map { dc => HellaCache(0, dc.nMSHRs == 0) } + val dcacheOpt = params.dcache.map { dc => LazyModule(HellaCache(0, dc.nMSHRs == 0)) } dcacheOpt.foreach { tileBus.node := _.node } override lazy val module = new GroundTestTileModule(this, () => new GroundTestTileBundle(this)) diff --git a/src/main/scala/rocket/HellaCache.scala b/src/main/scala/rocket/HellaCache.scala index a4253671..718c1287 100644 --- a/src/main/scala/rocket/HellaCache.scala +++ b/src/main/scala/rocket/HellaCache.scala @@ -195,8 +195,7 @@ class HellaCacheModule(outer: HellaCache) extends LazyModuleImp(outer) object HellaCache { def apply(hartid: Int, blocking: Boolean, scratch: () => Option[AddressSet] = () => None)(implicit p: Parameters) = { - if (blocking) LazyModule(new DCache(hartid, scratch)) - else LazyModule(new NonBlockingDCache(hartid)) + if (blocking) new DCache(hartid, scratch) else new NonBlockingDCache(hartid) } } @@ -208,7 +207,7 @@ trait HasHellaCache extends HasTileLinkMasterPort with HasTileParameters { def findScratchpadFromICache: Option[AddressSet] val hartid: Int var nDCachePorts = 0 - val dcache = HellaCache(hartid, tileParams.dcache.get.nMSHRs == 0, findScratchpadFromICache _) + val dcache = LazyModule(HellaCache(hartid, tileParams.dcache.get.nMSHRs == 0, findScratchpadFromICache _)) tileBus.node := dcache.node } From 1fedabcb555b74a287b5c23932a35cc21e965dcc Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Tue, 12 Sep 2017 12:12:49 -0700 Subject: [PATCH 05/32] tilelink: invoke LazyModule() at point of monitor binding --- src/main/scala/tilelink/Nodes.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/tilelink/Nodes.scala b/src/main/scala/tilelink/Nodes.scala index 273d9659..697ddd9a 100644 --- a/src/main/scala/tilelink/Nodes.scala +++ b/src/main/scala/tilelink/Nodes.scala @@ -9,7 +9,7 @@ import freechips.rocketchip.diplomacy._ import freechips.rocketchip.util.RationalDirection import scala.collection.mutable.ListBuffer -case object TLMonitorBuilder extends Field[TLMonitorArgs => TLMonitorBase](args => LazyModule(new TLMonitor(args))) +case object TLMonitorBuilder extends Field[TLMonitorArgs => TLMonitorBase](args => new TLMonitor(args)) case object TLCombinationalCheck extends Field[Boolean](false) object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TLEdgeOut, TLEdgeIn, TLBundle] @@ -26,7 +26,7 @@ object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TL override def connect(edges: () => Seq[TLEdgeIn], bundles: () => Seq[(TLBundle, TLBundle)], enableMonitoring: Boolean) (implicit p: Parameters, sourceInfo: SourceInfo): (Option[TLMonitorBase], () => Unit) = { - val monitor = if (enableMonitoring) Some(p(TLMonitorBuilder)(TLMonitorArgs(edges, sourceInfo, p))) else None + val monitor = if (enableMonitoring) Some(LazyModule(p(TLMonitorBuilder)(TLMonitorArgs(edges, sourceInfo, p)))) else None (monitor, () => { val eval = bundles () monitor.foreach { m => (eval zip m.module.io.in) foreach { case ((i,o), m) => m := TLBundleSnoop(o,i) } } From 17ba209ed014253f7d14640070022f88f09e3c3a Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Tue, 12 Sep 2017 12:16:28 -0700 Subject: [PATCH 06/32] coreplex: name LazyModules --- src/main/scala/coreplex/Configs.scala | 13 ++++++++++--- src/main/scala/coreplex/Ports.scala | 8 ++++++-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/main/scala/coreplex/Configs.scala b/src/main/scala/coreplex/Configs.scala index 46865cde..563f6f85 100644 --- a/src/main/scala/coreplex/Configs.scala +++ b/src/main/scala/coreplex/Configs.scala @@ -185,14 +185,21 @@ class WithRoccExample extends Config((site, here, up) => { Seq( RoCCParams( opcodes = OpcodeSet.custom0, - generator = (p: Parameters) => LazyModule(new AccumulatorExample()(p))), + generator = (p: Parameters) => { + val accumulator = LazyModule(new AccumulatorExample()(p)) + accumulator}), RoCCParams( opcodes = OpcodeSet.custom1, - generator = (p: Parameters) => LazyModule(new TranslatorExample()(p)), + generator = (p: Parameters) => { + val translator = LazyModule(new TranslatorExample()(p)) + translator}, nPTWPorts = 1), RoCCParams( opcodes = OpcodeSet.custom2, - generator = (p: Parameters) => LazyModule(new CharacterCountExample()(p))) + generator = (p: Parameters) => { + val counter = LazyModule(new CharacterCountExample()(p)) + counter + }) )) } }) diff --git a/src/main/scala/coreplex/Ports.scala b/src/main/scala/coreplex/Ports.scala index 4af44050..f1c1ae53 100644 --- a/src/main/scala/coreplex/Ports.scala +++ b/src/main/scala/coreplex/Ports.scala @@ -69,7 +69,10 @@ trait HasMasterAXI4MemPortBundle { val mem_axi4: HeterogeneousBag[AXI4Bundle] val nMemoryChannels: Int def connectSimAXIMem(dummy: Int = 1) = { - if (nMemoryChannels > 0) Module(LazyModule(new SimAXIMem(nMemoryChannels)).module).io.axi4 <> mem_axi4 + if (nMemoryChannels > 0) { + val mem = LazyModule(new SimAXIMem(nMemoryChannels)) + Module(mem.module).io.axi4 <> mem_axi4 + } } } @@ -107,7 +110,8 @@ trait HasMasterAXI4MMIOPortBundle { implicit val p: Parameters val mmio_axi4: HeterogeneousBag[AXI4Bundle] def connectSimAXIMMIO(dummy: Int = 1) { - Module(LazyModule(new SimAXIMem(1, 4096)).module).io.axi4 <> mmio_axi4 + val mmio_mem = LazyModule(new SimAXIMem(1, 4096)) + Module(mmio_mem.module).io.axi4 <> mmio_axi4 } } From 6fa5250e1fb56e25e70985f553afd0e2d4b3f5eb Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Tue, 12 Sep 2017 12:22:47 -0700 Subject: [PATCH 07/32] config: fix warning --- src/main/scala/config/Config.scala | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/scala/config/Config.scala b/src/main/scala/config/Config.scala index 45fec790..5ae84865 100644 --- a/src/main/scala/config/Config.scala +++ b/src/main/scala/config/Config.scala @@ -10,8 +10,10 @@ abstract class Field[T] private (val default: Option[T]) abstract class View { final def apply[T](pname: Field[T]): T = apply(pname, this) - final def apply[T](pname: Field[T], site: View): T = find(pname, site) match { - case Some(x) => x.asInstanceOf[T] + final def apply[T](pname: Field[T], site: View): T = { + val out = find(pname, site) + require (out.isDefined, s"Key ${pname} is not defined in Parameters") + out.get } final def lift[T](pname: Field[T]): Option[T] = lift(pname, this) From 53f6999ea8d58081f07b4335aeb74d6e2d7388e6 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Wed, 13 Sep 2017 13:44:06 -0700 Subject: [PATCH 08/32] Splitter: reuse TLCustom node instead of special diplomacy case --- src/main/scala/diplomacy/Nodes.scala | 41 -------------------------- src/main/scala/tilelink/Nodes.scala | 8 ----- src/main/scala/tilelink/Splitter.scala | 31 +++++++++++++++++++ 3 files changed, 31 insertions(+), 49 deletions(-) diff --git a/src/main/scala/diplomacy/Nodes.scala b/src/main/scala/diplomacy/Nodes.scala index 75c1f1a5..6b4490f3 100644 --- a/src/main/scala/diplomacy/Nodes.scala +++ b/src/main/scala/diplomacy/Nodes.scala @@ -396,47 +396,6 @@ class NexusNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])( implicit valName: ValName) extends MixedNexusNode[D, U, EI, B, D, U, EO, B](imp, imp)(dFn, uFn, numPO, numPI) -case class SplitterArg[T](newSize: Int, ports: Seq[T]) -class MixedSplitterNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( - inner: InwardNodeImp [DI, UI, EI, BI], - outer: OutwardNodeImp[DO, UO, EO, BO])( - dFn: SplitterArg[DI] => Seq[DO], - uFn: SplitterArg[UO] => Seq[UI], - numPO: Range.Inclusive = 1 to 999, - numPI: Range.Inclusive = 1 to 999)( - implicit valName: ValName) - extends MixedNode(inner, outer)(numPO, numPI) -{ - override val externalIn: Boolean = true - override val externalOut: Boolean = true - - protected[diplomacy] 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 (iStars == 0, s"${name} (a splitter) cannot appear left of a :*=; did you mean :=*?${lazyModule.line}") - (0, iKnown) - } - protected[diplomacy] def mapParamsD(n: Int, p: Seq[DI]): Seq[DO] = { - require (p.size == 0 || n % p.size == 0, s"Diplomacy bug; splitter inputs do not divide outputs") - val out = dFn(SplitterArg(n, p)) - require (out.size == n, s"${name} created the wrong number of outputs from inputs${lazyModule.line}") - out - } - protected[diplomacy] def mapParamsU(n: Int, p: Seq[UO]): Seq[UI] = { - require (n == 0 || p.size % n == 0, s"Diplomacy bug; splitter outputs indivisable by inputs") - val out = uFn(SplitterArg(n, p)) - require (out.size == n, s"${name} created the wrong number of inputs from outputs${lazyModule.line}") - out - } -} - -class SplitterNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])( - dFn: SplitterArg[D] => Seq[D], - uFn: SplitterArg[U] => Seq[U], - numPO: Range.Inclusive = 1 to 999, - numPI: Range.Inclusive = 1 to 999)( - implicit valName: ValName) - extends MixedSplitterNode[D, U, EI, B, D, U, EO, B](imp, imp)(dFn, uFn, numPO, numPI) - class IdentityNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(implicit valName: ValName) extends AdapterNode(imp)({s => s}, {s => s}) diff --git a/src/main/scala/tilelink/Nodes.scala b/src/main/scala/tilelink/Nodes.scala index 697ddd9a..9d74db5f 100644 --- a/src/main/scala/tilelink/Nodes.scala +++ b/src/main/scala/tilelink/Nodes.scala @@ -95,14 +95,6 @@ case class TLNexusNode( implicit valName: ValName) extends NexusNode(TLImp)(clientFn, managerFn, numClientPorts, numManagerPorts) -case class TLSplitterNode( - clientFn: SplitterArg[TLClientPortParameters] => Seq[TLClientPortParameters], - managerFn: SplitterArg[TLManagerPortParameters] => Seq[TLManagerPortParameters], - numClientPorts: Range.Inclusive = 0 to 999, - numManagerPorts: Range.Inclusive = 0 to 999)( - implicit valName: ValName) - extends SplitterNode(TLImp)(clientFn, managerFn, numClientPorts, numManagerPorts) - abstract class TLCustomNode( numClientPorts: Range.Inclusive, numManagerPorts: Range.Inclusive)( diff --git a/src/main/scala/tilelink/Splitter.scala b/src/main/scala/tilelink/Splitter.scala index abebecc3..39207ddc 100644 --- a/src/main/scala/tilelink/Splitter.scala +++ b/src/main/scala/tilelink/Splitter.scala @@ -6,6 +6,37 @@ import Chisel._ import freechips.rocketchip.config.Parameters import freechips.rocketchip.diplomacy._ +case class SplitterArg[T](newSize: Int, ports: Seq[T]) +case class TLSplitterNode( + clientFn: SplitterArg[TLClientPortParameters] => Seq[TLClientPortParameters], + managerFn: SplitterArg[TLManagerPortParameters] => Seq[TLManagerPortParameters], + numClientPorts: Range.Inclusive = 0 to 999, + numManagerPorts: Range.Inclusive = 0 to 999)( + implicit valName: ValName) + extends TLCustomNode(numClientPorts, numManagerPorts) +{ + val externalIn = true + val externalOut = true + + 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 (iStars == 0, s"${name} (a splitter) cannot appear left of a :*=; did you mean :=*?${lazyModule.line}") + (0, iKnown) + } + def mapParamsD(n: Int, p: Seq[TLClientPortParameters]): Seq[TLClientPortParameters] = { + require (p.size == 0 || n % p.size == 0, s"Diplomacy bug; splitter inputs do not divide outputs") + val out = clientFn(SplitterArg(n, p)) + require (out.size == n, s"${name} created the wrong number of outputs from inputs${lazyModule.line}") + out + } + def mapParamsU(n: Int, p: Seq[TLManagerPortParameters]): Seq[TLManagerPortParameters] = { + require (n == 0 || p.size % n == 0, s"Diplomacy bug; splitter outputs indivisable by inputs") + val out = managerFn(SplitterArg(n, p)) + require (out.size == n, s"${name} created the wrong number of inputs from outputs${lazyModule.line}") + out + } +} + class TLSplitter(policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Parameters) extends LazyModule { val node = TLSplitterNode( From 9217baf9d415c06fe17d96dffa72f5a05ac879ac Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Wed, 13 Sep 2017 18:06:03 -0700 Subject: [PATCH 09/32] diplomacy: change API to auto-create node bundles => cross-module refs --- src/main/scala/amba/ahb/Nodes.scala | 17 +- src/main/scala/amba/ahb/Parameters.scala | 4 +- src/main/scala/amba/ahb/RegisterRouter.scala | 12 +- src/main/scala/amba/ahb/SRAM.scala | 6 +- src/main/scala/amba/ahb/Test.scala | 19 +- src/main/scala/amba/ahb/ToTL.scala | 7 +- src/main/scala/amba/ahb/Xbar.scala | 22 +- src/main/scala/amba/apb/Nodes.scala | 17 +- src/main/scala/amba/apb/Parameters.scala | 3 +- src/main/scala/amba/apb/RegisterRouter.scala | 12 +- src/main/scala/amba/apb/SRAM.scala | 6 +- src/main/scala/amba/apb/Test.scala | 2 +- src/main/scala/amba/apb/Xbar.scala | 22 +- src/main/scala/amba/axi4/Buffer.scala | 7 +- src/main/scala/amba/axi4/Deinterleaver.scala | 7 +- src/main/scala/amba/axi4/Fragmenter.scala | 7 +- src/main/scala/amba/axi4/IdIndexer.scala | 7 +- src/main/scala/amba/axi4/Nodes.scala | 18 +- src/main/scala/amba/axi4/Parameters.scala | 3 +- src/main/scala/amba/axi4/RegisterRouter.scala | 21 +- src/main/scala/amba/axi4/SRAM.scala | 6 +- src/main/scala/amba/axi4/Test.scala | 21 +- src/main/scala/amba/axi4/ToTL.scala | 7 +- src/main/scala/amba/axi4/UserYanker.scala | 7 +- src/main/scala/coreplex/BaseCoreplex.scala | 2 +- src/main/scala/coreplex/InterruptBus.scala | 6 +- src/main/scala/coreplex/Ports.scala | 44 ++-- src/main/scala/coreplex/RTC.scala | 4 +- src/main/scala/coreplex/RocketCoreplex.scala | 2 +- src/main/scala/coreplex/SystemBus.scala | 2 +- src/main/scala/devices/debug/Debug.scala | 62 +++--- src/main/scala/devices/debug/Periphery.scala | 4 +- src/main/scala/devices/tilelink/BootROM.scala | 25 +-- .../scala/devices/tilelink/BusBlocker.scala | 11 +- .../scala/devices/tilelink/BusBypass.scala | 22 +- src/main/scala/devices/tilelink/Clint.scala | 10 +- src/main/scala/devices/tilelink/Error.scala | 7 +- src/main/scala/devices/tilelink/MaskROM.scala | 23 +- src/main/scala/devices/tilelink/Plic.scala | 17 +- src/main/scala/devices/tilelink/TestRAM.scala | 9 +- src/main/scala/devices/tilelink/Zero.scala | 7 +- src/main/scala/diplomacy/LazyModule.scala | 57 +++-- src/main/scala/diplomacy/Nodes.scala | 199 +++++++----------- src/main/scala/rocket/BusErrorUnit.scala | 9 +- src/main/scala/rocket/Frontend.scala | 10 +- src/main/scala/rocket/HellaCache.scala | 7 +- src/main/scala/rocket/ICache.scala | 15 +- src/main/scala/rocket/PTW.scala | 2 +- .../scala/rocket/ScratchpadSlavePort.scala | 16 +- src/main/scala/tile/BaseTile.scala | 5 +- src/main/scala/tile/Interrupts.scala | 3 +- src/main/scala/tile/LazyRoCC.scala | 14 +- src/main/scala/tile/RocketTile.scala | 38 ++-- src/main/scala/tilelink/AsyncCrossing.scala | 26 +-- src/main/scala/tilelink/AtomicAutomata.scala | 9 +- src/main/scala/tilelink/Broadcast.scala | 7 +- src/main/scala/tilelink/Buffer.scala | 18 +- src/main/scala/tilelink/CacheCork.scala | 7 +- src/main/scala/tilelink/Delayer.scala | 9 +- src/main/scala/tilelink/Edges.scala | 16 +- src/main/scala/tilelink/FIFOFixer.scala | 7 +- src/main/scala/tilelink/Filter.scala | 6 +- src/main/scala/tilelink/Fragmenter.scala | 11 +- src/main/scala/tilelink/Fuzzer.scala | 10 +- src/main/scala/tilelink/HintHandler.scala | 9 +- src/main/scala/tilelink/IntNodes.scala | 48 ++--- src/main/scala/tilelink/Isolation.scala | 10 +- src/main/scala/tilelink/Map.scala | 10 +- src/main/scala/tilelink/Monitor.scala | 4 +- src/main/scala/tilelink/NodeNumberer.scala | 12 +- src/main/scala/tilelink/Nodes.scala | 89 +++----- src/main/scala/tilelink/Parameters.scala | 8 +- src/main/scala/tilelink/PatternPusher.scala | 17 +- src/main/scala/tilelink/RAMModel.scala | 9 +- .../scala/tilelink/RationalCrossing.scala | 41 ++-- src/main/scala/tilelink/RegisterRouter.scala | 22 +- .../scala/tilelink/RegisterRouterTest.scala | 7 +- src/main/scala/tilelink/SRAM.scala | 12 +- src/main/scala/tilelink/SourceShrinker.scala | 7 +- src/main/scala/tilelink/Splitter.scala | 19 +- src/main/scala/tilelink/ToAHB.scala | 7 +- src/main/scala/tilelink/ToAPB.scala | 7 +- src/main/scala/tilelink/ToAXI4.scala | 7 +- src/main/scala/tilelink/WidthWidget.scala | 9 +- src/main/scala/tilelink/Xbar.scala | 113 +++++----- src/main/scala/unittest/UnitTest.scala | 23 +- 86 files changed, 575 insertions(+), 933 deletions(-) diff --git a/src/main/scala/amba/ahb/Nodes.scala b/src/main/scala/amba/ahb/Nodes.scala index 7cbc8fc6..32ae76c6 100644 --- a/src/main/scala/amba/ahb/Nodes.scala +++ b/src/main/scala/amba/ahb/Nodes.scala @@ -4,12 +4,13 @@ package freechips.rocketchip.amba.ahb import Chisel._ import chisel3.internal.sourceinfo.SourceInfo +import freechips.rocketchip.config.Parameters import freechips.rocketchip.diplomacy._ object AHBImp extends NodeImp[AHBMasterPortParameters, AHBSlavePortParameters, AHBEdgeParameters, AHBEdgeParameters, AHBBundle] { - def edgeO(pd: AHBMasterPortParameters, pu: AHBSlavePortParameters): AHBEdgeParameters = AHBEdgeParameters(pd, pu) - def edgeI(pd: AHBMasterPortParameters, pu: AHBSlavePortParameters): AHBEdgeParameters = AHBEdgeParameters(pd, pu) + def edgeO(pd: AHBMasterPortParameters, pu: AHBSlavePortParameters, p: Parameters): AHBEdgeParameters = AHBEdgeParameters(pd, pu, p) + def edgeI(pd: AHBMasterPortParameters, pu: AHBSlavePortParameters, p: Parameters): AHBEdgeParameters = AHBEdgeParameters(pd, pu, p) def bundleO(eo: AHBEdgeParameters): AHBBundle = AHBBundle(eo.bundle) def bundleI(ei: AHBEdgeParameters): AHBBundle = AHBBundle(ei.bundle) @@ -25,7 +26,6 @@ object AHBImp extends NodeImp[AHBMasterPortParameters, AHBSlavePortParameters, A } // Nodes implemented inside modules -case class AHBIdentityNode()(implicit valName: ValName) extends IdentityNode(AHBImp) case class AHBMasterNode(portParams: Seq[AHBMasterPortParameters])(implicit valName: ValName) extends SourceNode(AHBImp)(portParams) case class AHBSlaveNode(portParams: Seq[AHBSlavePortParameters])(implicit valName: ValName) extends SinkNode(AHBImp)(portParams) case class AHBNexusNode( @@ -36,13 +36,4 @@ case class AHBNexusNode( implicit valName: ValName) extends NexusNode(AHBImp)(masterFn, slaveFn, numMasterPorts, numSlavePorts) -// Nodes passed from an inner module -case class AHBOutputNode()(implicit valName: ValName) extends OutputNode(AHBImp) -case class AHBInputNode()(implicit valName: ValName) extends InputNode(AHBImp) - -// Nodes used for external ports -case class AHBBlindOutputNode(portParams: Seq[AHBSlavePortParameters])(implicit valName: ValName) extends BlindOutputNode(AHBImp)(portParams) -case class AHBBlindInputNode(portParams: Seq[AHBMasterPortParameters])(implicit valName: ValName) extends BlindInputNode(AHBImp)(portParams) - -case class AHBInternalOutputNode(portParams: Seq[AHBSlavePortParameters])(implicit valName: ValName) extends InternalOutputNode(AHBImp)(portParams) -case class AHBInternalInputNode(portParams: Seq[AHBMasterPortParameters])(implicit valName: ValName) extends InternalInputNode(AHBImp)(portParams) +case class AHBIdentityNode()(implicit valName: ValName) extends IdentityNode(AHBImp)() diff --git a/src/main/scala/amba/ahb/Parameters.scala b/src/main/scala/amba/ahb/Parameters.scala index 30df7a40..34ddfd34 100644 --- a/src/main/scala/amba/ahb/Parameters.scala +++ b/src/main/scala/amba/ahb/Parameters.scala @@ -3,6 +3,7 @@ package freechips.rocketchip.amba.ahb import Chisel._ +import freechips.rocketchip.config.Parameters import freechips.rocketchip.diplomacy._ import scala.math.max @@ -90,7 +91,8 @@ object AHBBundleParameters case class AHBEdgeParameters( master: AHBMasterPortParameters, - slave: AHBSlavePortParameters) + slave: AHBSlavePortParameters, + params: Parameters) { val bundle = AHBBundleParameters(master, slave) } diff --git a/src/main/scala/amba/ahb/RegisterRouter.scala b/src/main/scala/amba/ahb/RegisterRouter.scala index 720e2162..edae7f6b 100644 --- a/src/main/scala/amba/ahb/RegisterRouter.scala +++ b/src/main/scala/amba/ahb/RegisterRouter.scala @@ -24,7 +24,7 @@ case class AHBRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: // Calling this method causes the matching AHB bundle to be // configured to route all requests to the listed RegFields. def regmap(mapping: RegField.Map*) = { - val ahb = bundleIn(0) + val (ahb, _) = this.in(0) val indexBits = log2Up((address.mask+1)/beatBytes) val params = RegMapperParams(indexBits, beatBytes, 1) @@ -76,13 +76,11 @@ abstract class AHBRegisterRouterBase(address: AddressSet, interrupts: Int, concu val intnode = IntSourceNode(IntSourcePortSimple(num = interrupts)) } -case class AHBRegBundleArg(interrupts: HeterogeneousBag[Vec[Bool]], in: HeterogeneousBag[AHBBundle])(implicit val p: Parameters) +case class AHBRegBundleArg()(implicit val p: Parameters) class AHBRegBundleBase(arg: AHBRegBundleArg) extends Bundle { implicit val p = arg.p - val interrupts = arg.interrupts - val in = arg.in } class AHBRegBundle[P](val params: P, arg: AHBRegBundleArg) extends AHBRegBundleBase(arg) @@ -90,8 +88,8 @@ class AHBRegBundle[P](val params: P, arg: AHBRegBundleArg) extends AHBRegBundleB class AHBRegModule[P, B <: AHBRegBundleBase](val params: P, bundleBuilder: => B, router: AHBRegisterRouterBase) extends LazyModuleImp(router) with HasRegMap { - val io = bundleBuilder - val interrupts = if (io.interrupts.isEmpty) Vec(0, Bool()) else io.interrupts(0) + val io = IO(bundleBuilder) + val interrupts = if (router.intnode.in.isEmpty) Vec(0, Bool()) else router.intnode.in(0)._1 def regmap(mapping: RegField.Map*) = router.node.regmap(mapping:_*) } @@ -104,5 +102,5 @@ class AHBRegisterRouter[B <: AHBRegBundleBase, M <: LazyModuleImp] require (isPow2(size)) // require (size >= 4096) ... not absolutely required, but highly recommended - lazy val module = moduleBuilder(bundleBuilder(AHBRegBundleArg(intnode.bundleOut, node.bundleIn)), this) + lazy val module = moduleBuilder(bundleBuilder(AHBRegBundleArg()), this) } diff --git a/src/main/scala/amba/ahb/SRAM.scala b/src/main/scala/amba/ahb/SRAM.scala index ff8b93fa..ca783184 100644 --- a/src/main/scala/amba/ahb/SRAM.scala +++ b/src/main/scala/amba/ahb/SRAM.scala @@ -22,15 +22,11 @@ class AHBRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4 require ((address.mask & (beatBytes-1)) == beatBytes-1) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - } - def bigBits(x: BigInt, tail: List[Boolean] = List.empty[Boolean]): List[Boolean] = if (x == 0) tail.reverse else bigBits(x >> 1, ((x & 1) == 1) :: tail) val mask = bigBits(address.mask >> log2Ceil(beatBytes)) - val in = io.in(0) + val (in, _) = node.in(0) // The mask and address during the address phase val a_access = in.htrans === AHBParameters.TRANS_NONSEQ || in.htrans === AHBParameters.TRANS_SEQ diff --git a/src/main/scala/amba/ahb/Test.scala b/src/main/scala/amba/ahb/Test.scala index dde3a403..857ec063 100644 --- a/src/main/scala/amba/ahb/Test.scala +++ b/src/main/scala/amba/ahb/Test.scala @@ -30,7 +30,7 @@ class AHBFuzzNative(aFlow: Boolean, txns: Int)(implicit p: Parameters) extends L ram.node := xbar.node gpio.node := xbar.node - lazy val module = new LazyModuleImp(this) with HasUnitTestIO { + lazy val module = new LazyModuleImp(this) with UnitTestModule { io.finished := fuzz.module.io.finished } } @@ -42,7 +42,7 @@ class AHBNativeTest(aFlow: Boolean, txns: Int = 5000, timeout: Int = 500000)(imp class AHBFuzzMaster(aFlow: Boolean, txns: Int)(implicit p: Parameters) extends LazyModule { - val node = AHBOutputNode() + val node = AHBIdentityNode() val fuzz = LazyModule(new TLFuzzer(txns)) val model = LazyModule(new TLRAMModel("AHBFuzzMaster")) @@ -55,10 +55,9 @@ class AHBFuzzMaster(aFlow: Boolean, txns: Int)(implicit p: Parameters) extends L model.node)))) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val out = node.bundleOut + val io = IO(new Bundle { val finished = Bool(OUTPUT) - } + }) io.finished := fuzz.module.io.finished } @@ -66,7 +65,7 @@ class AHBFuzzMaster(aFlow: Boolean, txns: Int)(implicit p: Parameters) extends L class AHBFuzzSlave()(implicit p: Parameters) extends LazyModule { - val node = AHBInputNode() + val node = AHBIdentityNode() val ram = LazyModule(new TLTestRAM(AddressSet(0x0, 0xfff))) ram.node := @@ -77,11 +76,7 @@ class AHBFuzzSlave()(implicit p: Parameters) extends LazyModule AHBToTL()( node))))) - lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - } - } + lazy val module = new LazyModuleImp(this) { } } class AHBFuzzBridge(aFlow: Boolean, txns: Int)(implicit p: Parameters) extends LazyModule @@ -91,7 +86,7 @@ class AHBFuzzBridge(aFlow: Boolean, txns: Int)(implicit p: Parameters) extends L slave.node := master.node - lazy val module = new LazyModuleImp(this) with HasUnitTestIO { + lazy val module = new LazyModuleImp(this) with UnitTestModule { io.finished := master.module.io.finished } } diff --git a/src/main/scala/amba/ahb/ToTL.scala b/src/main/scala/amba/ahb/ToTL.scala index c18eab94..7eb353dc 100644 --- a/src/main/scala/amba/ahb/ToTL.scala +++ b/src/main/scala/amba/ahb/ToTL.scala @@ -41,12 +41,7 @@ class AHBToTL()(implicit p: Parameters) extends LazyModule val node = AHBToTLNode() lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - val out = node.bundleOut - } - - ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => + (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => val beatBytes = edgeOut.manager.beatBytes val d_send = RegInit(Bool(false)) diff --git a/src/main/scala/amba/ahb/Xbar.scala b/src/main/scala/amba/ahb/Xbar.scala index a19837c5..5298a441 100644 --- a/src/main/scala/amba/ahb/Xbar.scala +++ b/src/main/scala/amba/ahb/Xbar.scala @@ -16,35 +16,31 @@ class AHBFanout()(implicit p: Parameters) extends LazyModule { slaveFn = { seq => seq(0).copy(slaves = seq.flatMap(_.slaves)) }) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - val out = node.bundleOut - } - // Require consistent bus widths - val port0 = node.edgesOut(0).slave - node.edgesOut.foreach { edge => + val (io_out, edgesOut) = node.out.unzip + val port0 = edgesOut(0).slave + edgesOut.foreach { edge => val port = edge.slave require (port.beatBytes == port0.beatBytes, s"${port.slaves.map(_.name)} ${port.beatBytes} vs ${port0.slaves.map(_.name)} ${port0.beatBytes}") } - val port_addrs = node.edgesOut.map(_.slave.slaves.map(_.address).flatten) + val port_addrs = edgesOut.map(_.slave.slaves.map(_.address).flatten) val routingMask = AddressDecoder(port_addrs) val route_addrs = port_addrs.map(_.map(_.widen(~routingMask)).distinct) - val in = io.in(0) + val (in, _) = node.in(0) val a_sel = Vec(route_addrs.map(seq => seq.map(_.contains(in.haddr)).reduce(_ || _))) val d_sel = Reg(a_sel) when (in.hready) { d_sel := a_sel } - (a_sel zip io.out) foreach { case (sel, out) => + (a_sel zip io_out) foreach { case (sel, out) => out := in out.hsel := in.hsel && sel } - in.hreadyout := !Mux1H(d_sel, io.out.map(!_.hreadyout)) - in.hresp := Mux1H(d_sel, io.out.map(_.hresp)) - in.hrdata := Mux1H(d_sel, io.out.map(_.hrdata)) + in.hreadyout := !Mux1H(d_sel, io_out.map(!_.hreadyout)) + in.hresp := Mux1H(d_sel, io_out.map(_.hresp)) + in.hrdata := Mux1H(d_sel, io_out.map(_.hrdata)) } } diff --git a/src/main/scala/amba/apb/Nodes.scala b/src/main/scala/amba/apb/Nodes.scala index 9364077c..3eefee8c 100644 --- a/src/main/scala/amba/apb/Nodes.scala +++ b/src/main/scala/amba/apb/Nodes.scala @@ -9,8 +9,8 @@ import freechips.rocketchip.diplomacy._ object APBImp extends NodeImp[APBMasterPortParameters, APBSlavePortParameters, APBEdgeParameters, APBEdgeParameters, APBBundle] { - def edgeO(pd: APBMasterPortParameters, pu: APBSlavePortParameters): APBEdgeParameters = APBEdgeParameters(pd, pu) - def edgeI(pd: APBMasterPortParameters, pu: APBSlavePortParameters): APBEdgeParameters = APBEdgeParameters(pd, pu) + def edgeO(pd: APBMasterPortParameters, pu: APBSlavePortParameters, p: Parameters): APBEdgeParameters = APBEdgeParameters(pd, pu, p) + def edgeI(pd: APBMasterPortParameters, pu: APBSlavePortParameters, p: Parameters): APBEdgeParameters = APBEdgeParameters(pd, pu, p) def bundleO(eo: APBEdgeParameters): APBBundle = APBBundle(eo.bundle) def bundleI(ei: APBEdgeParameters): APBBundle = APBBundle(ei.bundle) @@ -25,8 +25,6 @@ object APBImp extends NodeImp[APBMasterPortParameters, APBSlavePortParameters, A pu.copy(slaves = pu.slaves.map { m => m.copy (nodePath = node +: m.nodePath) }) } -// Nodes implemented inside modules -case class APBIdentityNode()(implicit valName: ValName) extends IdentityNode(APBImp) case class APBMasterNode(portParams: Seq[APBMasterPortParameters])(implicit valName: ValName) extends SourceNode(APBImp)(portParams) case class APBSlaveNode(portParams: Seq[APBSlavePortParameters])(implicit valName: ValName) extends SinkNode(APBImp)(portParams) case class APBNexusNode( @@ -37,13 +35,4 @@ case class APBNexusNode( implicit valName: ValName) extends NexusNode(APBImp)(masterFn, slaveFn, numMasterPorts, numSlavePorts) -// Nodes passed from an inner module -case class APBOutputNode()(implicit valName: ValName) extends OutputNode(APBImp) -case class APBInputNode()(implicit valName: ValName) extends InputNode(APBImp) - -// Nodes used for external ports -case class APBBlindOutputNode(portParams: Seq[APBSlavePortParameters])(implicit valName: ValName) extends BlindOutputNode(APBImp)(portParams) -case class APBBlindInputNode(portParams: Seq[APBMasterPortParameters])(implicit valName: ValName) extends BlindInputNode(APBImp)(portParams) - -case class APBInternalOutputNode(portParams: Seq[APBSlavePortParameters])(implicit valName: ValName) extends InternalOutputNode(APBImp)(portParams) -case class APBInternalInputNode(portParams: Seq[APBMasterPortParameters])(implicit valName: ValName) extends InternalInputNode(APBImp)(portParams) +case class APBIdentityNode()(implicit valName: ValName) extends IdentityNode(APBImp)() diff --git a/src/main/scala/amba/apb/Parameters.scala b/src/main/scala/amba/apb/Parameters.scala index e0d74cbf..e6c733f8 100644 --- a/src/main/scala/amba/apb/Parameters.scala +++ b/src/main/scala/amba/apb/Parameters.scala @@ -78,7 +78,8 @@ object APBBundleParameters case class APBEdgeParameters( master: APBMasterPortParameters, - slave: APBSlavePortParameters) + slave: APBSlavePortParameters, + params: Parameters) { val bundle = APBBundleParameters(master, slave) } diff --git a/src/main/scala/amba/apb/RegisterRouter.scala b/src/main/scala/amba/apb/RegisterRouter.scala index 3c136552..ebff2756 100644 --- a/src/main/scala/amba/apb/RegisterRouter.scala +++ b/src/main/scala/amba/apb/RegisterRouter.scala @@ -24,7 +24,7 @@ case class APBRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: // Calling this method causes the matching APB bundle to be // configured to route all requests to the listed RegFields. def regmap(mapping: RegField.Map*) = { - val apb = bundleIn(0) + val (apb, _) = this.in(0) val indexBits = log2Up((address.mask+1)/beatBytes) val params = RegMapperParams(indexBits, beatBytes, 1) @@ -60,13 +60,11 @@ abstract class APBRegisterRouterBase(address: AddressSet, interrupts: Int, concu val intnode = IntSourceNode(IntSourcePortSimple(num = interrupts)) } -case class APBRegBundleArg(interrupts: HeterogeneousBag[Vec[Bool]], in: HeterogeneousBag[APBBundle])(implicit val p: Parameters) +case class APBRegBundleArg()(implicit val p: Parameters) class APBRegBundleBase(arg: APBRegBundleArg) extends Bundle { implicit val p = arg.p - val interrupts = arg.interrupts - val in = arg.in } class APBRegBundle[P](val params: P, arg: APBRegBundleArg) extends APBRegBundleBase(arg) @@ -74,8 +72,8 @@ class APBRegBundle[P](val params: P, arg: APBRegBundleArg) extends APBRegBundleB class APBRegModule[P, B <: APBRegBundleBase](val params: P, bundleBuilder: => B, router: APBRegisterRouterBase) extends LazyModuleImp(router) with HasRegMap { - val io = bundleBuilder - val interrupts = if (io.interrupts.isEmpty) Vec(0, Bool()) else io.interrupts(0) + val io = IO(bundleBuilder) + val interrupts = if (router.intnode.in.isEmpty) Vec(0, Bool()) else router.intnode.in(0)._1 def regmap(mapping: RegField.Map*) = router.node.regmap(mapping:_*) } @@ -88,5 +86,5 @@ class APBRegisterRouter[B <: APBRegBundleBase, M <: LazyModuleImp] require (isPow2(size)) // require (size >= 4096) ... not absolutely required, but highly recommended - lazy val module = moduleBuilder(bundleBuilder(APBRegBundleArg(intnode.bundleOut, node.bundleIn)), this) + lazy val module = moduleBuilder(bundleBuilder(APBRegBundleArg()), this) } diff --git a/src/main/scala/amba/apb/SRAM.scala b/src/main/scala/amba/apb/SRAM.scala index 59e26dc5..1da18bb4 100644 --- a/src/main/scala/amba/apb/SRAM.scala +++ b/src/main/scala/amba/apb/SRAM.scala @@ -22,11 +22,7 @@ class APBRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4 require ((address.mask & (beatBytes-1)) == beatBytes-1) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - } - - val in = io.in(0) + val (in, _) = node.in(0) def bigBits(x: BigInt, tail: List[Boolean] = List.empty[Boolean]): List[Boolean] = if (x == 0) tail.reverse else bigBits(x >> 1, ((x & 1) == 1) :: tail) diff --git a/src/main/scala/amba/apb/Test.scala b/src/main/scala/amba/apb/Test.scala index 9b762fc1..93d922a7 100644 --- a/src/main/scala/amba/apb/Test.scala +++ b/src/main/scala/amba/apb/Test.scala @@ -34,7 +34,7 @@ class APBFuzzBridge(aFlow: Boolean, txns: Int)(implicit p: Parameters) extends L TLDelayer(0.2)( model.node)))) - lazy val module = new LazyModuleImp(this) with HasUnitTestIO { + lazy val module = new LazyModuleImp(this) with UnitTestModule { io.finished := fuzz.module.io.finished } } diff --git a/src/main/scala/amba/apb/Xbar.scala b/src/main/scala/amba/apb/Xbar.scala index d7742f40..c72e6547 100644 --- a/src/main/scala/amba/apb/Xbar.scala +++ b/src/main/scala/amba/apb/Xbar.scala @@ -16,34 +16,30 @@ class APBFanout()(implicit p: Parameters) extends LazyModule { slaveFn = { seq => seq(0).copy(slaves = seq.flatMap(_.slaves)) }) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - val out = node.bundleOut - } - - val in = io.in(0) + val (in, _) = node.in(0) // Require consistent bus widths - val port0 = node.edgesOut(0).slave - node.edgesOut.foreach { edge => + val (io_out, edgesOut) = node.out.unzip + val port0 = edgesOut(0).slave + edgesOut.foreach { edge => val port = edge.slave require (port.beatBytes == port0.beatBytes, s"${port.slaves.map(_.name)} ${port.beatBytes} vs ${port0.slaves.map(_.name)} ${port0.beatBytes}") } - val port_addrs = node.edgesOut.map(_.slave.slaves.map(_.address).flatten) + val port_addrs = edgesOut.map(_.slave.slaves.map(_.address).flatten) val routingMask = AddressDecoder(port_addrs) val route_addrs = port_addrs.map(_.map(_.widen(~routingMask)).distinct) val sel = Vec(route_addrs.map(seq => seq.map(_.contains(in.paddr)).reduce(_ || _))) - (sel zip io.out) foreach { case (sel, out) => + (sel zip io_out) foreach { case (sel, out) => out := in out.psel := sel && in.psel out.penable := sel && in.penable } - in.pready := !Mux1H(sel, io.out.map(!_.pready)) - in.pslverr := Mux1H(sel, io.out.map(_.pslverr)) - in.prdata := Mux1H(sel, io.out.map(_.prdata)) + in.pready := !Mux1H(sel, io_out.map(!_.pready)) + in.pslverr := Mux1H(sel, io_out.map(_.pslverr)) + in.prdata := Mux1H(sel, io_out.map(_.prdata)) } } diff --git a/src/main/scala/amba/axi4/Buffer.scala b/src/main/scala/amba/axi4/Buffer.scala index 3f81fa67..ef04cd3a 100644 --- a/src/main/scala/amba/axi4/Buffer.scala +++ b/src/main/scala/amba/axi4/Buffer.scala @@ -26,11 +26,6 @@ class AXI4Buffer( slaveFn = { p => p.copy(minLatency = p.minLatency + min(aw.latency,ar.latency) + min(r.latency,b.latency)) }) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - val out = node.bundleOut - } - def buffer[T <: Data](config: BufferParams, data: IrrevocableIO[T]): IrrevocableIO[T] = { if (config.isDefined) { Queue.irrevocable(data, config.depth, pipe=config.pipe, flow=config.flow) @@ -39,7 +34,7 @@ class AXI4Buffer( } } - ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => + (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => out.aw <> buffer(aw, in .aw) out.w <> buffer(w, in .w) in .b <> buffer(b, out.b) diff --git a/src/main/scala/amba/axi4/Deinterleaver.scala b/src/main/scala/amba/axi4/Deinterleaver.scala index 74948a77..4a454e01 100644 --- a/src/main/scala/amba/axi4/Deinterleaver.scala +++ b/src/main/scala/amba/axi4/Deinterleaver.scala @@ -22,12 +22,7 @@ class AXI4Deinterleaver(maxReadBytes: Int)(implicit p: Parameters) extends LazyM }) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - val out = node.bundleOut - } - - ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => + (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => val endId = edgeOut.master.endId val beatBytes = edgeOut.slave.beatBytes val beats = (maxReadBytes+beatBytes-1) / beatBytes diff --git a/src/main/scala/amba/axi4/Fragmenter.scala b/src/main/scala/amba/axi4/Fragmenter.scala index f1be60ee..2e9aaea6 100644 --- a/src/main/scala/amba/axi4/Fragmenter.scala +++ b/src/main/scala/amba/axi4/Fragmenter.scala @@ -26,12 +26,7 @@ class AXI4Fragmenter()(implicit p: Parameters) extends LazyModule slaveFn = { sp => sp.copy(slaves = sp.slaves .map(s => mapSlave(s, sp.beatBytes))) }) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - val out = node.bundleOut - } - - ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => + (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => val slave = edgeOut.slave val slaves = slave.slaves val beatBytes = slave.beatBytes diff --git a/src/main/scala/amba/axi4/IdIndexer.scala b/src/main/scala/amba/axi4/IdIndexer.scala index afb0c028..76f217fc 100644 --- a/src/main/scala/amba/axi4/IdIndexer.scala +++ b/src/main/scala/amba/axi4/IdIndexer.scala @@ -42,12 +42,7 @@ class AXI4IdIndexer(idBits: Int)(implicit p: Parameters) extends LazyModule }) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - val out = node.bundleOut - } - - ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => + (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => // Leave everything mostly untouched out.ar <> in.ar diff --git a/src/main/scala/amba/axi4/Nodes.scala b/src/main/scala/amba/axi4/Nodes.scala index 8b68470c..b0037626 100644 --- a/src/main/scala/amba/axi4/Nodes.scala +++ b/src/main/scala/amba/axi4/Nodes.scala @@ -9,8 +9,8 @@ import freechips.rocketchip.diplomacy._ object AXI4Imp extends NodeImp[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4EdgeParameters, AXI4EdgeParameters, AXI4Bundle] { - def edgeO(pd: AXI4MasterPortParameters, pu: AXI4SlavePortParameters): AXI4EdgeParameters = AXI4EdgeParameters(pd, pu) - def edgeI(pd: AXI4MasterPortParameters, pu: AXI4SlavePortParameters): AXI4EdgeParameters = AXI4EdgeParameters(pd, pu) + def edgeO(pd: AXI4MasterPortParameters, pu: AXI4SlavePortParameters, p: Parameters): AXI4EdgeParameters = AXI4EdgeParameters(pd, pu, p) + def edgeI(pd: AXI4MasterPortParameters, pu: AXI4SlavePortParameters, p: Parameters): AXI4EdgeParameters = AXI4EdgeParameters(pd, pu, p) def bundleO(eo: AXI4EdgeParameters): AXI4Bundle = AXI4Bundle(eo.bundle) def bundleI(ei: AXI4EdgeParameters): AXI4Bundle = AXI4Bundle(ei.bundle) @@ -25,8 +25,6 @@ object AXI4Imp extends NodeImp[AXI4MasterPortParameters, AXI4SlavePortParameters pu.copy(slaves = pu.slaves.map { m => m.copy (nodePath = node +: m.nodePath) }) } -// Nodes implemented inside modules -case class AXI4IdentityNode()(implicit valName: ValName) extends IdentityNode(AXI4Imp) case class AXI4MasterNode(portParams: Seq[AXI4MasterPortParameters])(implicit valName: ValName) extends SourceNode(AXI4Imp)(portParams) case class AXI4SlaveNode(portParams: Seq[AXI4SlavePortParameters])(implicit valName: ValName) extends SinkNode(AXI4Imp)(portParams) case class AXI4AdapterNode( @@ -35,14 +33,4 @@ case class AXI4AdapterNode( numPorts: Range.Inclusive = 0 to 999)( implicit valName: ValName) extends AdapterNode(AXI4Imp)(masterFn, slaveFn, numPorts) - -// Nodes passed from an inner module -case class AXI4OutputNode()(implicit valName: ValName) extends OutputNode(AXI4Imp) -case class AXI4InputNode()(implicit valName: ValName) extends InputNode(AXI4Imp) - -// Nodes used for external ports -case class AXI4BlindOutputNode(portParams: Seq[AXI4SlavePortParameters])(implicit valName: ValName) extends BlindOutputNode(AXI4Imp)(portParams) -case class AXI4BlindInputNode(portParams: Seq[AXI4MasterPortParameters])(implicit valName: ValName) extends BlindInputNode(AXI4Imp)(portParams) - -case class AXI4InternalOutputNode(portParams: Seq[AXI4SlavePortParameters])(implicit valName: ValName) extends InternalOutputNode(AXI4Imp)(portParams) -case class AXI4InternalInputNode(portParams: Seq[AXI4MasterPortParameters])(implicit valName: ValName) extends InternalInputNode(AXI4Imp)(portParams) +case class AXI4IdentityNode()(implicit valName: ValName) extends IdentityNode(AXI4Imp)() diff --git a/src/main/scala/amba/axi4/Parameters.scala b/src/main/scala/amba/axi4/Parameters.scala index 19226fe5..01069f10 100644 --- a/src/main/scala/amba/axi4/Parameters.scala +++ b/src/main/scala/amba/axi4/Parameters.scala @@ -124,7 +124,8 @@ object AXI4BundleParameters case class AXI4EdgeParameters( master: AXI4MasterPortParameters, - slave: AXI4SlavePortParameters) + slave: AXI4SlavePortParameters, + params: Parameters) { val bundle = AXI4BundleParameters(master, slave) } diff --git a/src/main/scala/amba/axi4/RegisterRouter.scala b/src/main/scala/amba/axi4/RegisterRouter.scala index 9f9b3082..be601889 100644 --- a/src/main/scala/amba/axi4/RegisterRouter.scala +++ b/src/main/scala/amba/axi4/RegisterRouter.scala @@ -26,11 +26,12 @@ case class AXI4RegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes // Calling this method causes the matching AXI4 bundle to be // configured to route all requests to the listed RegFields. def regmap(mapping: RegField.Map*) = { - val ar = bundleIn(0).ar - val aw = bundleIn(0).aw - val w = bundleIn(0).w - val r = bundleIn(0).r - val b = bundleIn(0).b + val (io, _) = this.in(0) + val ar = io.ar + val aw = io.aw + val w = io.w + val r = io.r + val b = io.b val params = RegMapperParams(log2Up((address.mask+1)/beatBytes), beatBytes, ar.bits.params.idBits + ar.bits.params.userBits) val in = Wire(Decoupled(new RegMapperInput(params))) @@ -86,13 +87,11 @@ abstract class AXI4RegisterRouterBase(address: AddressSet, interrupts: Int, conc val intnode = IntSourceNode(IntSourcePortSimple(num = interrupts)) } -case class AXI4RegBundleArg(interrupts: HeterogeneousBag[Vec[Bool]], in: HeterogeneousBag[AXI4Bundle])(implicit val p: Parameters) +case class AXI4RegBundleArg()(implicit val p: Parameters) class AXI4RegBundleBase(arg: AXI4RegBundleArg) extends Bundle { implicit val p = arg.p - val interrupts = arg.interrupts - val in = arg.in } class AXI4RegBundle[P](val params: P, arg: AXI4RegBundleArg) extends AXI4RegBundleBase(arg) @@ -100,8 +99,8 @@ class AXI4RegBundle[P](val params: P, arg: AXI4RegBundleArg) extends AXI4RegBund class AXI4RegModule[P, B <: AXI4RegBundleBase](val params: P, bundleBuilder: => B, router: AXI4RegisterRouterBase) extends LazyModuleImp(router) with HasRegMap { - val io = bundleBuilder - val interrupts = if (io.interrupts.isEmpty) Vec(0, Bool()) else io.interrupts(0) + val io = IO(bundleBuilder) + val interrupts = if (router.intnode.in.isEmpty) Vec(0, Bool()) else router.intnode.in(0)._1 def regmap(mapping: RegField.Map*) = router.node.regmap(mapping:_*) } @@ -114,5 +113,5 @@ class AXI4RegisterRouter[B <: AXI4RegBundleBase, M <: LazyModuleImp] require (isPow2(size)) // require (size >= 4096) ... not absolutely required, but highly recommended - lazy val module = moduleBuilder(bundleBuilder(AXI4RegBundleArg(intnode.bundleOut, node.bundleIn)), this) + lazy val module = moduleBuilder(bundleBuilder(AXI4RegBundleArg()), this) } diff --git a/src/main/scala/amba/axi4/SRAM.scala b/src/main/scala/amba/axi4/SRAM.scala index 680c0098..21be636e 100644 --- a/src/main/scala/amba/axi4/SRAM.scala +++ b/src/main/scala/amba/axi4/SRAM.scala @@ -24,15 +24,11 @@ class AXI4RAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = require ((address.mask & (beatBytes-1)) == beatBytes-1) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - } - def bigBits(x: BigInt, tail: List[Boolean] = List.empty[Boolean]): List[Boolean] = if (x == 0) tail.reverse else bigBits(x >> 1, ((x & 1) == 1) :: tail) val mask = bigBits(address.mask >> log2Ceil(beatBytes)) - val in = io.in(0) + val (in, _) = node.in(0) val mem = SeqMem(1 << mask.filter(b=>b).size, Vec(beatBytes, Bits(width = 8))) val r_addr = Cat((mask zip (in.ar.bits.addr >> log2Ceil(beatBytes)).toBools).filter(_._1).map(_._2).reverse) diff --git a/src/main/scala/amba/axi4/Test.scala b/src/main/scala/amba/axi4/Test.scala index c3f7c0ef..ff6ca6c4 100644 --- a/src/main/scala/amba/axi4/Test.scala +++ b/src/main/scala/amba/axi4/Test.scala @@ -30,7 +30,7 @@ class AXI4LiteFuzzRAM(txns: Int)(implicit p: Parameters) extends LazyModule ram.node := AXI4UserYanker()(AXI4IdIndexer(0)(TLToAXI4(4, true )(TLFragmenter(4, 16)(xbar.node)))) gpio.node := AXI4UserYanker()(AXI4IdIndexer(0)(TLToAXI4(4, false)(TLFragmenter(4, 16)(xbar.node)))) - lazy val module = new LazyModuleImp(this) with HasUnitTestIO { + lazy val module = new LazyModuleImp(this) with UnitTestModule { io.finished := fuzz.module.io.finished } } @@ -53,7 +53,7 @@ class AXI4FullFuzzRAM(txns: Int)(implicit p: Parameters) extends LazyModule ram.node := AXI4Fragmenter()(AXI4Deinterleaver(16)(TLToAXI4(4,false)(xbar.node))) gpio.node := AXI4Fragmenter()(AXI4Deinterleaver(16)(TLToAXI4(4,true )(xbar.node))) - lazy val module = new LazyModuleImp(this) with HasUnitTestIO { + lazy val module = new LazyModuleImp(this) with UnitTestModule { io.finished := fuzz.module.io.finished } } @@ -69,7 +69,7 @@ trait HasFuzzTarget { class AXI4FuzzMaster(txns: Int)(implicit p: Parameters) extends LazyModule with HasFuzzTarget { - val node = AXI4OutputNode() + val node = AXI4IdentityNode() val fuzz = LazyModule(new TLFuzzer(txns, overrideAddress = Some(fuzzAddr))) val model = LazyModule(new TLRAMModel("AXI4FuzzMaster")) @@ -84,10 +84,9 @@ class AXI4FuzzMaster(txns: Int)(implicit p: Parameters) extends LazyModule with model.node)))))) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val out = node.bundleOut + val io = IO(new Bundle { val finished = Bool(OUTPUT) - } + }) io.finished := fuzz.module.io.finished } @@ -95,7 +94,7 @@ class AXI4FuzzMaster(txns: Int)(implicit p: Parameters) extends LazyModule with class AXI4FuzzSlave()(implicit p: Parameters) extends LazyModule with HasFuzzTarget { - val node = AXI4InputNode() + val node = AXI4IdentityNode() val xbar = LazyModule(new TLXbar) val ram = LazyModule(new TLRAM(fuzzAddr)) val error= LazyModule(new TLError(ErrorParams(Seq(AddressSet(0x1800, 0xff)), maxTransfer = 256))) @@ -114,11 +113,7 @@ class AXI4FuzzSlave()(implicit p: Parameters) extends LazyModule with HasFuzzTar AXI4IdIndexer(2)( node)))))))) - lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - } - } + lazy val module = new LazyModuleImp(this) { } } class AXI4FuzzBridge(txns: Int)(implicit p: Parameters) extends LazyModule @@ -128,7 +123,7 @@ class AXI4FuzzBridge(txns: Int)(implicit p: Parameters) extends LazyModule slave.node := master.node - lazy val module = new LazyModuleImp(this) with HasUnitTestIO { + lazy val module = new LazyModuleImp(this) with UnitTestModule { io.finished := master.module.io.finished } } diff --git a/src/main/scala/amba/axi4/ToTL.scala b/src/main/scala/amba/axi4/ToTL.scala index 8d77556d..a76f468e 100644 --- a/src/main/scala/amba/axi4/ToTL.scala +++ b/src/main/scala/amba/axi4/ToTL.scala @@ -44,12 +44,7 @@ class AXI4ToTL()(implicit p: Parameters) extends LazyModule val node = AXI4ToTLNode() lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - val out = node.bundleOut - } - - ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => + (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => val numIds = edgeIn.master.endId val beatBytes = edgeOut.manager.beatBytes val beatCountBits = AXI4Parameters.lenBits + (1 << AXI4Parameters.sizeBits) - 1 diff --git a/src/main/scala/amba/axi4/UserYanker.scala b/src/main/scala/amba/axi4/UserYanker.scala index 58afdedb..ae1af03b 100644 --- a/src/main/scala/amba/axi4/UserYanker.scala +++ b/src/main/scala/amba/axi4/UserYanker.scala @@ -22,12 +22,7 @@ class AXI4UserYanker(capMaxFlight: Option[Int] = None)(implicit p: Parameters) e slaveFn = { sp => sp }) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - val out = node.bundleOut - } - - ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => + (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => val bits = edgeIn.bundle.userBits val need_bypass = edgeOut.slave.minLatency < 1 require (bits > 0) // useless UserYanker! diff --git a/src/main/scala/coreplex/BaseCoreplex.scala b/src/main/scala/coreplex/BaseCoreplex.scala index 579d6a97..963bf2b2 100644 --- a/src/main/scala/coreplex/BaseCoreplex.scala +++ b/src/main/scala/coreplex/BaseCoreplex.scala @@ -21,7 +21,7 @@ abstract class BareCoreplex(implicit p: Parameters) extends LazyModule with Bind lazy val json = JSON(bindingTree) } -abstract class BareCoreplexModule[+L <: BareCoreplex](_outer: L) extends LazyMultiIOModuleImp(_outer) { +abstract class BareCoreplexModule[+L <: BareCoreplex](_outer: L) extends LazyModuleImp(_outer) { val outer = _outer ElaborationArtefacts.add("graphml", outer.graphML) ElaborationArtefacts.add("dts", outer.dts) diff --git a/src/main/scala/coreplex/InterruptBus.scala b/src/main/scala/coreplex/InterruptBus.scala index 3499a751..4c04d992 100644 --- a/src/main/scala/coreplex/InterruptBus.scala +++ b/src/main/scala/coreplex/InterruptBus.scala @@ -44,7 +44,7 @@ abstract trait HasExtInterrupts extends HasInterruptBus { } val nExtInterrupts = p(NExtTopInterrupts) - val extInterrupts = IntInternalInputNode(IntSourcePortSimple(num = nExtInterrupts, resources = device.int)) + val extInterrupts = IntSourceNode(IntSourcePortSimple(num = nExtInterrupts, resources = device.int)) } /** This trait should be used if the External Interrupts have NOT @@ -77,9 +77,9 @@ trait HasExtInterruptsBundle { /** This trait performs the translation from a UInt IO into Diplomatic Interrupts. * The wiring must be done in the concrete LazyModuleImp. */ -trait HasExtInterruptsModuleImp extends LazyMultiIOModuleImp with HasExtInterruptsBundle { +trait HasExtInterruptsModuleImp extends LazyModuleImp with HasExtInterruptsBundle { val outer: HasExtInterrupts val interrupts = IO(UInt(INPUT, width = outer.nExtInterrupts)) - outer.extInterrupts.bundleIn.flatten.zipWithIndex.foreach { case(o, i) => o := interrupts(i) } + outer.extInterrupts.in.map(_._1).flatten.zipWithIndex.foreach { case(o, i) => o := interrupts(i) } } diff --git a/src/main/scala/coreplex/Ports.scala b/src/main/scala/coreplex/Ports.scala index f1c1ae53..4eb975ab 100644 --- a/src/main/scala/coreplex/Ports.scala +++ b/src/main/scala/coreplex/Ports.scala @@ -33,7 +33,7 @@ trait HasMasterAXI4MemPort extends HasMemoryBus { private val params = p(ExtMem) private val device = new MemoryDevice - val mem_axi4 = AXI4BlindOutputNode(Seq.tabulate(nMemoryChannels) { channel => + val mem_axi4 = AXI4SlaveNode(Seq.tabulate(nMemoryChannels) { channel => val base = AddressSet(params.base, params.size-1) val filter = AddressSet(channel * cacheBlockBytes, ~((nMemoryChannels-1) * cacheBlockBytes)) @@ -77,9 +77,10 @@ trait HasMasterAXI4MemPortBundle { } /** Actually generates the corresponding IO in the concrete Module */ -trait HasMasterAXI4MemPortModuleImp extends LazyMultiIOModuleImp with HasMasterAXI4MemPortBundle { +trait HasMasterAXI4MemPortModuleImp extends LazyModuleImp with HasMasterAXI4MemPortBundle { val outer: HasMasterAXI4MemPort - val mem_axi4 = IO(outer.mem_axi4.bundleOut) + val mem_axi4 = IO(HeterogeneousBag(outer.mem_axi4.in.map(_._1.cloneType))) + (mem_axi4 zip outer.mem_axi4.in) foreach { case (i, (o, _)) => i <> o } val nMemoryChannels = outer.nMemoryChannels } @@ -87,7 +88,7 @@ trait HasMasterAXI4MemPortModuleImp extends LazyMultiIOModuleImp with HasMasterA trait HasMasterAXI4MMIOPort extends HasSystemBus { private val params = p(ExtBus) private val device = new SimpleBus("mmio", Nil) - val mmio_axi4 = AXI4BlindOutputNode(Seq(AXI4SlavePortParameters( + val mmio_axi4 = AXI4SlaveNode(Seq(AXI4SlavePortParameters( slaves = Seq(AXI4SlaveParameters( address = List(AddressSet(params.base, params.size-1)), resources = device.ranges, @@ -116,15 +117,16 @@ trait HasMasterAXI4MMIOPortBundle { } /** Actually generates the corresponding IO in the concrete Module */ -trait HasMasterAXI4MMIOPortModuleImp extends LazyMultiIOModuleImp with HasMasterAXI4MMIOPortBundle { +trait HasMasterAXI4MMIOPortModuleImp extends LazyModuleImp with HasMasterAXI4MMIOPortBundle { val outer: HasMasterAXI4MMIOPort - val mmio_axi4 = IO(outer.mmio_axi4.bundleOut) + val mmio_axi4 = IO(HeterogeneousBag(outer.mmio_axi4.in.map(_._1.cloneType))) + (mmio_axi4 zip outer.mmio_axi4.in) foreach { case (i, (o, _)) => i <> o } } /** Adds an AXI4 port to the system intended to be a slave on an MMIO device bus */ trait HasSlaveAXI4Port extends HasSystemBus { private val params = p(ExtIn) - val l2FrontendAXI4Node = AXI4BlindInputNode(Seq(AXI4MasterPortParameters( + val l2FrontendAXI4Node = AXI4MasterNode(Seq(AXI4MasterPortParameters( masters = Seq(AXI4MasterParameters( name = "AXI4 periphery", id = IdRange(0, 1 << params.idBits)))))) @@ -155,16 +157,17 @@ trait HasSlaveAXI4PortBundle { } /** Actually generates the corresponding IO in the concrete Module */ -trait HasSlaveAXI4PortModuleImp extends LazyMultiIOModuleImp with HasSlaveAXI4PortBundle { +trait HasSlaveAXI4PortModuleImp extends LazyModuleImp with HasSlaveAXI4PortBundle { val outer: HasSlaveAXI4Port - val l2_frontend_bus_axi4 = IO(outer.l2FrontendAXI4Node.bundleIn) + val l2_frontend_bus_axi4 = IO(HeterogeneousBag(outer.l2FrontendAXI4Node.out.map(_._1.cloneType)).flip) + (outer.l2FrontendAXI4Node.out zip l2_frontend_bus_axi4) foreach { case ((i, _), o) => i <> o } } /** Adds a TileLink port to the system intended to master an MMIO device bus */ trait HasMasterTLMMIOPort extends HasSystemBus { private val params = p(ExtBus) private val device = new SimpleBus("mmio", Nil) - val mmio_tl = TLBlindOutputNode(Seq(TLManagerPortParameters( + val mmio_tl = TLManagerNode(Seq(TLManagerPortParameters( managers = Seq(TLManagerParameters( address = List(AddressSet(params.base, params.size-1)), resources = device.ranges, @@ -196,9 +199,10 @@ trait HasMasterTLMMIOPortBundle { } /** Actually generates the corresponding IO in the concrete Module */ -trait HasMasterTLMMIOPortModuleImp extends LazyMultiIOModuleImp with HasMasterTLMMIOPortBundle { +trait HasMasterTLMMIOPortModuleImp extends LazyModuleImp with HasMasterTLMMIOPortBundle { val outer: HasMasterTLMMIOPort - val mmio_tl = IO(outer.mmio_tl.bundleOut) + val mmio_tl = IO(HeterogeneousBag(outer.mmio_tl.in.map(_._1.cloneType))) + (mmio_tl zip outer.mmio_tl.out) foreach { case (i, (o, _)) => i <> o } } /** Adds an TL port to the system intended to be a slave on an MMIO device bus. @@ -206,7 +210,7 @@ trait HasMasterTLMMIOPortModuleImp extends LazyMultiIOModuleImp with HasMasterTL */ trait HasSlaveTLPort extends HasSystemBus { private val params = p(ExtIn) - val l2FrontendTLNode = TLBlindInputNode(Seq(TLClientPortParameters( + val l2FrontendTLNode = TLClientNode(Seq(TLClientPortParameters( clients = Seq(TLClientParameters( name = "Front Port (TL)", sourceId = IdRange(0, 1 << params.idBits)))))) @@ -233,9 +237,10 @@ trait HasSlaveTLPortBundle { } /** Actually generates the corresponding IO in the concrete Module */ -trait HasSlaveTLPortModuleImp extends LazyMultiIOModuleImp with HasSlaveTLPortBundle { +trait HasSlaveTLPortModuleImp extends LazyModuleImp with HasSlaveTLPortBundle { val outer: HasSlaveTLPort - val l2_frontend_bus_tl = IO(outer.l2FrontendTLNode.bundleIn) + val l2_frontend_bus_tl = IO(HeterogeneousBag(outer.l2FrontendTLNode.out.map(_._1.cloneType)).flip) + (outer.l2FrontendTLNode.in zip l2_frontend_bus_tl) foreach { case ((i, _), o) => i <> o } } /** Memory with AXI port for use in elaboratable test harnesses. */ @@ -245,7 +250,7 @@ class SimAXIMem(channels: Int, forceSize: BigInt = 0)(implicit p: Parameters) ex val size = totalSize / channels require(totalSize % channels == 0) - val node = AXI4BlindInputNode(Seq.fill(channels) { + val node = AXI4MasterNode(Seq.fill(channels) { AXI4MasterPortParameters(Seq(AXI4MasterParameters( name = "dut", id = IdRange(0, 1 << config.idBits) @@ -258,8 +263,9 @@ class SimAXIMem(channels: Int, forceSize: BigInt = 0)(implicit p: Parameters) ex } lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val axi4 = node.bundleIn - } + val io = IO(new Bundle { + val axi4 = HeterogeneousBag(node.out.map(_._1.cloneType)).flip + }) + (node.out zip io.axi4) foreach { case ((i, _), o) => i <> o } } } diff --git a/src/main/scala/coreplex/RTC.scala b/src/main/scala/coreplex/RTC.scala index b7fdba34..e21e29e1 100644 --- a/src/main/scala/coreplex/RTC.scala +++ b/src/main/scala/coreplex/RTC.scala @@ -3,10 +3,10 @@ package freechips.rocketchip.coreplex import Chisel._ -import freechips.rocketchip.diplomacy.{LazyMultiIOModuleImp, DTSTimebase} +import freechips.rocketchip.diplomacy.{LazyModuleImp, DTSTimebase} import freechips.rocketchip.devices.tilelink.HasPeripheryClint -trait HasRTCModuleImp extends LazyMultiIOModuleImp { +trait HasRTCModuleImp extends LazyModuleImp { val outer: HasPeripheryClint private val pbusFreq = outer.p(PeripheryBusKey).frequency private val rtcFreq = outer.p(DTSTimebase) diff --git a/src/main/scala/coreplex/RocketCoreplex.scala b/src/main/scala/coreplex/RocketCoreplex.scala index 6bac3fd4..7532cf31 100644 --- a/src/main/scala/coreplex/RocketCoreplex.scala +++ b/src/main/scala/coreplex/RocketCoreplex.scala @@ -98,7 +98,7 @@ trait HasRocketTilesBundle { val rocket_tile_inputs: Vec[ClockedRocketTileInputs] } -trait HasRocketTilesModuleImp extends LazyMultiIOModuleImp +trait HasRocketTilesModuleImp extends LazyModuleImp with HasRocketTilesBundle with HasResetVectorWire with HasPeripheryDebugModuleImp { diff --git a/src/main/scala/coreplex/SystemBus.scala b/src/main/scala/coreplex/SystemBus.scala index 8e69c289..98f0c5ba 100644 --- a/src/main/scala/coreplex/SystemBus.scala +++ b/src/main/scala/coreplex/SystemBus.scala @@ -22,7 +22,7 @@ class SystemBus(params: SystemBusParams)(implicit p: Parameters) extends TLBusWr private val master_splitter = LazyModule(new TLSplitter) // Allows cycle-free connection to external networks master_splitter.suggestName(s"${busName}_master_TLSplitter") inwardNode :=* master_splitter.node - def busView = master_splitter.node.edgesIn.head + def busView = master_splitter.node.in.head._2 protected def inwardSplitNode: TLInwardNode = master_splitter.node protected def outwardSplitNode: TLOutwardNode = master_splitter.node diff --git a/src/main/scala/devices/debug/Debug.scala b/src/main/scala/devices/debug/Debug.scala index 112ca367..8d26d50b 100644 --- a/src/main/scala/devices/debug/Debug.scala +++ b/src/main/scala/devices/debug/Debug.scala @@ -288,14 +288,12 @@ class TLDebugModuleOuter(device: Device)(implicit p: Parameters) extends LazyMod lazy val module = new LazyModuleImp(this) { - val nComponents = intnode.bundleOut.size + val nComponents = intnode.out.size - val io = new Bundle { + val io = IO(new Bundle { val ctrl = (new DebugCtrlBundle(nComponents)) - val tlIn = dmiNode.bundleIn - val debugInterrupts = intnode.bundleOut val innerCtrl = new DecoupledIO(new DebugInternalBundle()) - } + }) //----DMCONTROL (The whole point of 'Outer' is to maintain this register on dmiClock (e.g. TCK) domain, so that it // can be written even if 'Inner' is not being clocked or is in reset. This allows halting @@ -356,7 +354,7 @@ class TLDebugModuleOuter(device: Device)(implicit p: Parameters) extends LazyMod debugIntNxt := debugIntRegs for (component <- 0 until nComponents) { - io.debugInterrupts(component)(0) := debugIntRegs(component) + intnode.out(component)._1(0) := debugIntRegs(component) } // Halt request registers are set & cleared by writes to DMCONTROL.haltreq @@ -393,9 +391,9 @@ class TLDebugModuleOuterAsync(device: Device)(implicit p: Parameters) extends La val dmiXbar = LazyModule (new TLXbar()) val dmOuter = LazyModule( new TLDebugModuleOuter(device)) - val intnode = IntOutputNode() + val intnode = IntIdentityNode() - val dmiInnerNode = TLAsyncOutputNode() + val dmiInnerNode = TLAsyncIdentityNode() intnode :*= dmOuter.intnode @@ -405,15 +403,13 @@ class TLDebugModuleOuterAsync(device: Device)(implicit p: Parameters) extends La lazy val module = new LazyModuleImp(this) { - val nComponents = intnode.bundleOut.size + val nComponents = intnode.out.size - val io = new Bundle { + val io = IO(new Bundle { val dmi = new DMIIO()(p).flip() - val dmiInner = dmiInnerNode.bundleOut val ctrl = new DebugCtrlBundle(nComponents) - val debugInterrupts = intnode.bundleOut val innerCtrl = new AsyncBundle(depth=1, new DebugInternalBundle()) - } + }) dmi2tl.module.io.dmi <> io.dmi @@ -447,13 +443,11 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p: val nComponents = getNComponents() - val io = new Bundle { - val hart_in = tlNode.bundleIn - val dmi_in = dmiNode.bundleIn + val io = IO(new Bundle { val dmactive = Bool(INPUT) val innerCtrl = (new DecoupledIO(new DebugInternalBundle())).flip val debugUnavail = Vec(nComponents, Bool()).asInput - } + }) //-------------------------------------------------------------- // Import constants for shorter variable names @@ -1012,25 +1006,23 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p: class TLDebugModuleInnerAsync(device: Device, getNComponents: () => Int)(implicit p: Parameters) extends LazyModule{ val dmInner = LazyModule(new TLDebugModuleInner(device, getNComponents)(p)) - val dmiNode = TLAsyncInputNode() - val tlNode = TLInputNode() + val dmiNode = TLAsyncIdentityNode() + val tlNode = TLIdentityNode() dmInner.dmiNode := TLAsyncCrossingSink(depth=1)(dmiNode) dmInner.tlNode := tlNode lazy val module = new LazyModuleImp(this) { - val io = new Bundle { + val io = IO(new Bundle { // this comes from tlClk domain. - val tl_in = tlNode.bundleIn // These are all asynchronous and come from Outer - val dmi_in = dmiNode.bundleIn val dmactive = Bool(INPUT) val innerCtrl = new AsyncBundle(1, new DebugInternalBundle()).flip // This comes from tlClk domain. val debugUnavail = Vec(getNComponents(), Bool()).asInput val psd = new PSDTestMode().asInput - } + }) dmInner.module.io.innerCtrl := FromAsyncBundle(io.innerCtrl) dmInner.module.io.dmactive := ~ResetCatchAndSync(clock, ~io.dmactive, "dmactiveSync", io.psd) @@ -1049,26 +1041,24 @@ class TLDebugModule(implicit p: Parameters) extends LazyModule { override val alwaysExtended = true } - val node = TLInputNode() - val intnode = IntOutputNode() + val node = TLIdentityNode() + val intnode = IntIdentityNode() val dmOuter = LazyModule(new TLDebugModuleOuterAsync(device)(p)) - val dmInner = LazyModule(new TLDebugModuleInnerAsync(device, () => {intnode.bundleOut.size})(p)) + val dmInner = LazyModule(new TLDebugModuleInnerAsync(device, () => {intnode.edges._2.size})(p)) dmInner.dmiNode := dmOuter.dmiInnerNode dmInner.tlNode := node intnode :*= dmOuter.intnode lazy val module = new LazyModuleImp(this) { - val nComponents = intnode.bundleOut.size + val nComponents = intnode.out.size - val io = new Bundle { + val io = IO(new Bundle { val ctrl = new DebugCtrlBundle(nComponents) val dmi = new ClockedDMIIO().flip - val in = node.bundleIn - val debugInterrupts = intnode.bundleOut val psd = new PSDTestMode().asInput - } + }) dmOuter.module.io.dmi <> io.dmi.dmi dmOuter.module.reset := io.dmi.dmiReset @@ -1102,16 +1092,14 @@ class ClockedDMIIO(implicit val p: Parameters) extends ParameterizedBundle()(p){ class DMIToTL(implicit p: Parameters) extends LazyModule { - val node = TLClientNode(TLClientParameters("debug")) + val node = TLClientNode(Seq(TLClientPortParameters(Seq(TLClientParameters("debug"))))) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { + val io = IO(new Bundle { val dmi = new DMIIO()(p).flip() - val out = node.bundleOut - } + }) - val tl = io.out(0) - val edge = node.edgesOut(0) + val (tl, edge) = node.out(0) val src = Wire(init = 0.U) val addr = Wire(init = (io.dmi.req.bits.addr << 2)) diff --git a/src/main/scala/devices/debug/Periphery.scala b/src/main/scala/devices/debug/Periphery.scala index 3d563daa..128fc128 100644 --- a/src/main/scala/devices/debug/Periphery.scala +++ b/src/main/scala/devices/debug/Periphery.scala @@ -54,9 +54,9 @@ trait HasPeripheryDebugBundle { } debug.psd.foreach { _ <> psd } } - } -trait HasPeripheryDebugModuleImp extends LazyMultiIOModuleImp with HasPeripheryDebugBundle { + +trait HasPeripheryDebugModuleImp extends LazyModuleImp with HasPeripheryDebugBundle { val outer: HasPeripheryDebug val debug = IO(new DebugIO) diff --git a/src/main/scala/devices/tilelink/BootROM.scala b/src/main/scala/devices/tilelink/BootROM.scala index 60ac4303..1110171c 100644 --- a/src/main/scala/devices/tilelink/BootROM.scala +++ b/src/main/scala/devices/tilelink/BootROM.scala @@ -23,25 +23,22 @@ case object BootROMParams extends Field[BootROMParams] class TLROM(val base: BigInt, val size: Int, contentsDelayed: => Seq[Byte], executable: Boolean = true, beatBytes: Int = 4, resources: Seq[Resource] = new SimpleDevice("rom", Seq("sifive,rom0")).reg("mem"))(implicit p: Parameters) extends LazyModule { - val node = TLManagerNode(beatBytes, TLManagerParameters ( - address = List(AddressSet(base, size-1)), - resources = resources, - regionType = RegionType.UNCACHED, - executable = executable, - supportsGet = TransferSizes(1, beatBytes), - fifoId = Some(0))) + val node = TLManagerNode(Seq(TLManagerPortParameters( + Seq(TLManagerParameters( + address = List(AddressSet(base, size-1)), + resources = resources, + regionType = RegionType.UNCACHED, + executable = executable, + supportsGet = TransferSizes(1, beatBytes), + fifoId = Some(0))), + beatBytes = beatBytes))) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - } - val contents = contentsDelayed val wrapSize = 1 << log2Ceil(contents.size) require (wrapSize <= size) - val in = io.in(0) - val edge = node.edgesIn(0) + val (in, edge) = node.in(0) val words = (contents ++ Seq.fill(wrapSize-contents.size)(0.toByte)).grouped(beatBytes).toSeq val bigs = words.map(_.foldRight(BigInt(0)){ case (x,y) => (x.toInt & 0xff) | y << 8}) @@ -78,7 +75,7 @@ trait HasPeripheryBootROM extends HasPeripheryBus { } /** Coreplex will power-on running at 0x10040 (BootROM) */ -trait HasPeripheryBootROMModuleImp extends LazyMultiIOModuleImp +trait HasPeripheryBootROMModuleImp extends LazyModuleImp with HasResetVectorWire { val outer: HasPeripheryBootROM global_reset_vector := outer.resetVector.U diff --git a/src/main/scala/devices/tilelink/BusBlocker.scala b/src/main/scala/devices/tilelink/BusBlocker.scala index dbf4314a..7d5f476f 100644 --- a/src/main/scala/devices/tilelink/BusBlocker.scala +++ b/src/main/scala/devices/tilelink/BusBlocker.scala @@ -81,20 +81,13 @@ class BusBlocker(params: BusBlockerParams)(implicit p: Parameters) extends TLBus beatBytes = params.controlBeatBytes) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val ctl = controlNode.bundleIn - val in = nodeIn.bundleIn - val out = nodeOut.bundleOut - } - // We need to be able to represent +1 larger than the largest populated address - val addressBits = log2Ceil(nodeOut.edgesOut(0).manager.maxAddress+1+1) + val addressBits = log2Ceil(nodeOut.out(0)._2.manager.maxAddress+1+1) val pmps = RegInit(Vec.fill(params.pmpRegisters) { DevicePMP(addressBits, params.pageBits) }) val blocks = pmps.tail.map(_.blockPriorAddress) :+ Bool(false) controlNode.regmap(0 -> (pmps zip blocks).map { case (p, b) => p.fields(b) }.toList.flatten) - val in = io.in(0) - val edge = nodeIn.edgesIn(0) + val (in, edge) = nodeIn.in(0) // Determine if a request is allowed val needW = in.a.bits.opcode =/= TLMessages.Get diff --git a/src/main/scala/devices/tilelink/BusBypass.scala b/src/main/scala/devices/tilelink/BusBypass.scala index 784d9c86..b93ffb97 100644 --- a/src/main/scala/devices/tilelink/BusBypass.scala +++ b/src/main/scala/devices/tilelink/BusBypass.scala @@ -12,8 +12,8 @@ import scala.math.min abstract class TLBusBypassBase(beatBytes: Int)(implicit p: Parameters) extends LazyModule { - protected val nodeIn = TLInputNode() - protected val nodeOut = TLOutputNode() + protected val nodeIn = TLIdentityNode() + protected val nodeOut = TLIdentityNode() val node = NodeHandle(nodeIn, nodeOut) protected val bar = LazyModule(new TLBusBypassBar) @@ -28,11 +28,9 @@ abstract class TLBusBypassBase(beatBytes: Int)(implicit p: Parameters) extends L class TLBusBypass(beatBytes: Int)(implicit p: Parameters) extends TLBusBypassBase(beatBytes) { lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = nodeIn.bundleIn - val out = nodeOut.bundleOut + val io = IO(new Bundle { val bypass = Bool(INPUT) - } + }) bar.module.io.bypass := io.bypass } } @@ -47,17 +45,13 @@ class TLBusBypassBar(implicit p: Parameters) extends LazyModule managerFn = { seq => seq(1) }) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - val out = node.bundleOut + val io = IO(new Bundle { val bypass = Bool(INPUT) - } + }) - val in = io.in(0) - val out0 = io.out(0) - val out1 = io.out(1) + val (in, edge) = node.in(0) + val Seq((out0,_), (out1,_)) = node.out - val edge = node.edgesIn(0) val bce = edge.manager.anySupportAcquireB && edge.client.anySupportProbe // We need to be locked to the given bypass direction until all transactions stop diff --git a/src/main/scala/devices/tilelink/Clint.scala b/src/main/scala/devices/tilelink/Clint.scala index 13627529..1cd759a5 100644 --- a/src/main/scala/devices/tilelink/Clint.scala +++ b/src/main/scala/devices/tilelink/Clint.scala @@ -53,11 +53,9 @@ class CoreplexLocalInterrupter(params: ClintParams)(implicit p: Parameters) exte sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) }) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { + val io = IO(new Bundle { val rtcTick = Bool(INPUT) - val int = intnode.bundleOut - val in = node.bundleIn - } + }) val time = Seq.fill(timeWidth/regWidth)(Reg(init=UInt(0, width = regWidth))) when (io.rtcTick) { @@ -66,11 +64,11 @@ class CoreplexLocalInterrupter(params: ClintParams)(implicit p: Parameters) exte reg := newTime >> i } - val nTiles = intnode.edgesOut.size + val nTiles = intnode.out.size val timecmp = Seq.fill(nTiles) { Seq.fill(timeWidth/regWidth)(Reg(UInt(width = regWidth))) } val ipi = Seq.fill(nTiles) { RegInit(UInt(0, width = 1)) } - io.int.zipWithIndex.foreach { case (int, i) => + intnode.in.map(_._1).zipWithIndex.foreach { case (int, i) => int(0) := ShiftRegister(ipi(i)(0), params.intStages) // msip int(1) := ShiftRegister(time.asUInt >= timecmp(i).asUInt, params.intStages) // mtip } diff --git a/src/main/scala/devices/tilelink/Error.scala b/src/main/scala/devices/tilelink/Error.scala index d054922e..a1a4d945 100644 --- a/src/main/scala/devices/tilelink/Error.scala +++ b/src/main/scala/devices/tilelink/Error.scala @@ -40,15 +40,10 @@ class TLError(params: ErrorParams, beatBytes: Int = 4)(implicit p: Parameters) e minLatency = 1))) // no bypass needed for this device lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - } - import TLMessages._ import TLPermissions._ - val edge = node.edgesIn(0) - val in = io.in(0) + val (in, edge) = node.in(0) val a = Queue(in.a, 1) val c = Queue(in.c, 1) val da = Wire(in.d) diff --git a/src/main/scala/devices/tilelink/MaskROM.scala b/src/main/scala/devices/tilelink/MaskROM.scala index ce801a4e..d40526ae 100644 --- a/src/main/scala/devices/tilelink/MaskROM.scala +++ b/src/main/scala/devices/tilelink/MaskROM.scala @@ -24,21 +24,18 @@ trait HasPeripheryMaskROMSlave extends HasPeripheryBus { class TLMaskROM(c: MaskROMParams)(implicit p: Parameters) extends LazyModule { val beatBytes = c.width/8 - val node = TLManagerNode(beatBytes, TLManagerParameters( - address = AddressSet.misaligned(c.address, c.depth*beatBytes), - resources = new SimpleDevice("rom", Seq("sifive,maskrom0")).reg("mem"), - regionType = RegionType.UNCACHED, - executable = true, - supportsGet = TransferSizes(1, beatBytes), - fifoId = Some(0))) // requests are handled in order + val node = TLManagerNode(Seq(TLManagerPortParameters( + Seq(TLManagerParameters( + address = AddressSet.misaligned(c.address, c.depth*beatBytes), + resources = new SimpleDevice("rom", Seq("sifive,maskrom0")).reg("mem"), + regionType = RegionType.UNCACHED, + executable = true, + supportsGet = TransferSizes(1, beatBytes), + fifoId = Some(0))), // requests are handled in order + beatBytes = beatBytes))) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - } - - val in = io.in(0) - val edge = node.edgesIn(0) + val (in, edge)= node.in(0) val rom = ROMGenerator(ROMConfig(c.name, c.depth, c.width)) rom.io.clock := clock diff --git a/src/main/scala/devices/tilelink/Plic.scala b/src/main/scala/devices/tilelink/Plic.scala index 44268ca1..a0ee455a 100644 --- a/src/main/scala/devices/tilelink/Plic.scala +++ b/src/main/scala/devices/tilelink/Plic.scala @@ -91,12 +91,12 @@ class TLPLIC(params: PLICParams)(implicit p: Parameters) extends LazyModule sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) }) /* Negotiated sizes */ - def nDevices: Int = intnode.edgesIn.map(_.source.num).sum + def nDevices: Int = intnode.in.map(_._2.source.num).sum def nPriorities = min(params.maxPriorities, nDevices) - def nHarts = intnode.edgesOut.map(_.source.num).sum + def nHarts = intnode.out.map(_._2.source.num).sum // Assign all the devices unique ranges - lazy val sources = intnode.edgesIn.map(_.source) + lazy val sources = intnode.in.map(_._2.source) lazy val flatSources = (sources zip sources.map(_.num).scanLeft(0)(_+_).init).map { case (s, o) => s.sources.map(z => z.copy(range = z.range.offset(o))) }.flatten @@ -109,16 +109,13 @@ class TLPLIC(params: PLICParams)(implicit p: Parameters) extends LazyModule } lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val tl_in = node.bundleIn - val devices = intnode.bundleIn - val harts = intnode.bundleOut - } + val (io_devices, edgesIn) = intnode.in.unzip + val (io_harts, _) = intnode.out.unzip // Compact the interrupt vector the same way - val interrupts = (intnode.edgesIn zip io.devices).map { case (e, i) => i.take(e.source.num) }.flatten + val interrupts = intnode.in.map { case (i, e) => i.take(e.source.num) }.flatten // This flattens the harts into an MSMSMSMSMS... or MMMMM.... sequence - val harts = io.harts.flatten + val harts = io_harts.flatten println(s"Interrupt map (${nHarts} harts ${nDevices} interrupts):") flatSources.foreach { s => diff --git a/src/main/scala/devices/tilelink/TestRAM.scala b/src/main/scala/devices/tilelink/TestRAM.scala index 8f2ef3f6..adad547d 100644 --- a/src/main/scala/devices/tilelink/TestRAM.scala +++ b/src/main/scala/devices/tilelink/TestRAM.scala @@ -29,16 +29,11 @@ class TLTestRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int require ((address.mask & (beatBytes-1)) == beatBytes-1) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - } - def bigBits(x: BigInt, tail: List[Boolean] = List.empty[Boolean]): List[Boolean] = if (x == 0) tail.reverse else bigBits(x >> 1, ((x & 1) == 1) :: tail) val mask = bigBits(address.mask >> log2Ceil(beatBytes)) - val in = io.in(0) - val edge = node.edgesIn(0) + val (in, edge) = node.in(0) val addrBits = (mask zip edge.addr_hi(in.a.bits).toBools).filter(_._1).map(_._2) val memAddress = Cat(addrBits.reverse) @@ -75,7 +70,7 @@ class TLRAMZeroDelay(ramBeatBytes: Int, txns: Int)(implicit p: Parameters) exten model.node := fuzz.node ram.node := TLDelayer(0.25)(model.node) - lazy val module = new LazyModuleImp(this) with HasUnitTestIO { + lazy val module = new LazyModuleImp(this) with UnitTestModule { io.finished := fuzz.module.io.finished } } diff --git a/src/main/scala/devices/tilelink/Zero.scala b/src/main/scala/devices/tilelink/Zero.scala index 458d141e..229fc55d 100644 --- a/src/main/scala/devices/tilelink/Zero.scala +++ b/src/main/scala/devices/tilelink/Zero.scala @@ -24,12 +24,7 @@ class TLZero(address: AddressSet, resources: Seq[Resource], executable: Boolean minLatency = 1))) // no bypass needed for this device lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - } - - val in = io.in(0) - val edge = node.edgesIn(0) + val (in, edge) = node.in(0) val a = Queue(in.a, 2) val hasData = edge.hasData(a.bits) diff --git a/src/main/scala/diplomacy/LazyModule.scala b/src/main/scala/diplomacy/LazyModule.scala index 9dcdc2a8..4ef75b11 100644 --- a/src/main/scala/diplomacy/LazyModule.scala +++ b/src/main/scala/diplomacy/LazyModule.scala @@ -6,6 +6,7 @@ import Chisel._ import chisel3.experimental.{BaseModule, RawModule, MultiIOModule, withClockAndReset} import chisel3.internal.sourceinfo.{SourceInfo, SourceLine, UnlocatableSourceInfo} import freechips.rocketchip.config.Parameters +import scala.collection.immutable.ListMap abstract class LazyModule()(implicit val p: Parameters) { @@ -54,15 +55,6 @@ abstract class LazyModule()(implicit val p: Parameters) def module: LazyModuleImpLike - protected[diplomacy] def instantiate() = { - children.reverse.foreach { c => - // !!! fix chisel3 so we can pass the desired sourceInfo - // implicit val sourceInfo = c.module.outer.info - Module(c.module) - } - bindings.reverse.foreach { f => f () } - } - def omitGraphML: Boolean = !nodes.exists(!_.omitGraphML) && !children.exists(!_.omitGraphML) lazy val graphML: String = parent.map(_.graphML).getOrElse { val buf = new StringBuilder @@ -144,6 +136,8 @@ object LazyModule sealed trait LazyModuleImpLike extends BaseModule { val wrapper: LazyModule + val auto: AutoBundle + protected[diplomacy] val dangles: Seq[Dangle] // .module had better not be accessed while LazyModules are still being built! require (LazyModule.stack.isEmpty, s"${wrapper.name}.module was constructed before LazyModule() was run on ${LazyModule.stack.head.name}") @@ -152,18 +146,47 @@ sealed trait LazyModuleImpLike extends BaseModule suggestName(wrapper.instanceName) implicit val p = wrapper.p + + protected[diplomacy] def instantiate() = { + val childDangles = wrapper.children.reverse.flatMap { c => + implicit val sourceInfo = c.info + Module(c.module).dangles + } + val nodeDangles = wrapper.nodes.reverse.flatMap(_.instantiate()) + val (toConnect, toForward) = (nodeDangles ++ childDangles).groupBy(_.source).partition(_._2.size == 2) + val forward = toForward.map(_._2(0)).toList + toConnect.foreach { case (_, Seq(a, b)) => + require (a.flipped != b.flipped) + if (a.flipped) { a.data <> b.data } else { b.data <> a.data } + } + val auto = IO(new AutoBundle(forward.map { d => (d.name, d.data, d.flipped) }:_*)) + val dangles = (forward zip auto.elements) map { case (d, (_, io)) => + if (d.flipped) { d.data <> io } else { io <> d.data } + d.copy(data = io, name = wrapper.valName.getOrElse("anon") + "_" + d.name) + } + wrapper.bindings.reverse.foreach { f => f () } + (auto, dangles) + } } -abstract class LazyModuleImp(val wrapper: LazyModule) extends Module with LazyModuleImpLike { - wrapper.instantiate() -} - -abstract class LazyMultiIOModuleImp(val wrapper: LazyModule) extends MultiIOModule with LazyModuleImpLike { - wrapper.instantiate() +abstract class LazyModuleImp(val wrapper: LazyModule) extends MultiIOModule with LazyModuleImpLike { + val (auto, dangles) = instantiate() } abstract class LazyRawModuleImp(val wrapper: LazyModule) extends RawModule with LazyModuleImpLike { - withClockAndReset(Bool(false).asClock, Bool(true)) { - wrapper.instantiate() + val (auto, dangles) = withClockAndReset(Bool(false).asClock, Bool(true)) { + instantiate() } } + +case class HalfEdge(serial: Int, index: Int) +case class Dangle(source: HalfEdge, sink: HalfEdge, flipped: Boolean, name: String, data: Data) + +final class AutoBundle(elts: (String, Data, Boolean)*) extends Record { + // !!! need to fix-up name collision better than appending _# + val elements = ListMap(elts.zipWithIndex map { case ((field, elt, flip), i) => + (field + "_" + i) -> (if (flip) elt.cloneType.flip else elt.cloneType) + }:_*) + + override def cloneType = (new AutoBundle(elts:_*)).asInstanceOf[this.type] +} diff --git a/src/main/scala/diplomacy/Nodes.scala b/src/main/scala/diplomacy/Nodes.scala index 6b4490f3..c129a183 100644 --- a/src/main/scala/diplomacy/Nodes.scala +++ b/src/main/scala/diplomacy/Nodes.scala @@ -34,7 +34,7 @@ private case object MonitorsEnabled extends Field[Boolean](true) // BI = Bundle type used when connecting to the inner side of the node trait InwardNodeImp[DI, UI, EI, BI <: Data] { - def edgeI(pd: DI, pu: UI): EI + def edgeI(pd: DI, pu: UI, p: Parameters): EI def bundleI(ei: EI): BI def colour: String def reverse: Boolean = false @@ -55,7 +55,7 @@ trait InwardNodeImp[DI, UI, EI, BI <: Data] // BO = Bundle type used when connecting to the outer side of the node trait OutwardNodeImp[DO, UO, EO, BO <: Data] { - def edgeO(pd: DO, pu: UO): EO + def edgeO(pd: DO, pu: UO, p: Parameters): EO def bundleO(eo: EO): BO // optional methods to track node graph @@ -75,11 +75,11 @@ abstract class BaseNode(implicit val valName: ValName) val index = lazyModule.nodes.size lazyModule.nodes = this :: lazyModule.nodes - val externalIn: Boolean - val externalOut: Boolean + val serial = BaseNode.serial + BaseNode.serial = BaseNode.serial + 1 + protected[diplomacy] def instantiate(): Seq[Dangle] - def nodename = getClass.getName.split('.').last - def name = lazyModule.name + "." + nodename + def name = lazyModule.name + "." + valName.name def omitGraphML = outputs.isEmpty && inputs.isEmpty lazy val nodedebugstring: String = "" @@ -91,6 +91,11 @@ abstract class BaseNode(implicit val valName: ValName) protected[diplomacy] def reverse: Boolean } +object BaseNode +{ + protected[diplomacy] var serial = 0 +} + case class NodeHandle[DI, UI, BI <: Data, DO, UO, BO <: Data] (inward: InwardNode[DI, UI, BI], outward: OutwardNode[DO, UO, BO]) extends Object with InwardNodeHandle[DI, UI, BI] with OutwardNodeHandle[DO, UO, BO] @@ -138,7 +143,6 @@ trait InwardNode[DI, UI, BI <: Data] extends BaseNode with InwardNodeHandle[DI, protected[diplomacy] val iStar: Int protected[diplomacy] val iPortMapping: Seq[(Int, Int)] protected[diplomacy] val iParams: Seq[UI] - protected[diplomacy] val bundleIn: HeterogeneousBag[BI] } trait OutwardNodeHandle[DO, UO, BO <: Data] @@ -171,10 +175,9 @@ trait OutwardNode[DO, UO, BO <: Data] extends BaseNode with OutwardNodeHandle[DO protected[diplomacy] val oStar: Int protected[diplomacy] val oPortMapping: Seq[(Int, Int)] protected[diplomacy] val oParams: Seq[DO] - protected[diplomacy] val bundleOut: HeterogeneousBag[BO] } -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]( inner: InwardNodeImp [DI, UI, EI, BI], outer: OutwardNodeImp[DO, UO, EO, BO])( protected[diplomacy] val numPO: Range.Inclusive, @@ -213,22 +216,22 @@ abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( (oSum.init zip oSum.tail, iSum.init zip iSum.tail, oStar, iStar) } - lazy val oPorts = oBindings.flatMap { case (i, n, _, _) => + lazy val oPorts = oBindings.flatMap { case (i, n, _, p) => val (start, end) = n.iPortMapping(i) - (start until end) map { j => (j, n) } + (start until end) map { j => (j, n, p) } } - lazy val iPorts = iBindings.flatMap { case (i, n, _, _) => + lazy val iPorts = iBindings.flatMap { case (i, n, _, p) => val (start, end) = n.oPortMapping(i) - (start until end) map { j => (j, n) } + (start until end) map { j => (j, n, p) } } protected[diplomacy] lazy val oParams: Seq[DO] = { - val o = mapParamsD(oPorts.size, iPorts.map { case (i, n) => n.oParams(i) }) + val o = mapParamsD(oPorts.size, iPorts.map { case (i, n, _) => n.oParams(i) }) require (o.size == oPorts.size, s"Bug in diplomacy; ${name} has ${o.size} != ${oPorts.size} down/up outer parameters${lazyModule.line}") o.map(outer.mixO(_, this)) } protected[diplomacy] lazy val iParams: Seq[UI] = { - val i = mapParamsU(iPorts.size, oPorts.map { case (o, n) => n.iParams(o) }) + val i = mapParamsU(iPorts.size, oPorts.map { case (o, n, _) => n.iParams(o) }) require (i.size == iPorts.size, s"Bug in diplomacy; ${name} has ${i.size} != ${iPorts.size} up/down inner parameters${lazyModule.line}") i.map(inner.mixI(_, this)) } @@ -236,23 +239,48 @@ abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( protected[diplomacy] def gco = if (iParams.size != 1) None else inner.getO(iParams(0)) protected[diplomacy] def gci = if (oParams.size != 1) None else outer.getI(oParams(0)) - lazy val edgesOut = (oPorts zip oParams).map { case ((i, n), o) => outer.edgeO(o, n.iParams(i)) } - lazy val edgesIn = (iPorts zip iParams).map { case ((o, n), i) => inner.edgeI(n.oParams(o), i) } - lazy val externalEdgesOut = if (externalOut) {edgesOut} else { Seq() } - lazy val externalEdgesIn = if (externalIn) {edgesIn} else { Seq() } + protected[diplomacy] lazy val edgesOut = (oPorts zip oParams).map { case ((i, n, p), o) => outer.edgeO(o, n.iParams(i), p) } + protected[diplomacy] lazy val edgesIn = (iPorts zip iParams).map { case ((o, n, p), i) => inner.edgeI(n.oParams(o), i, p) } - lazy val paramsOut: Seq[Parameters] = (oPortMapping zip oBindings).flatMap { case ((s, e), b) => Seq.fill(e-s) { b._4 } } - lazy val paramsIn: Seq[Parameters] = (iPortMapping zip iBindings).flatMap { case ((s, e), b) => Seq.fill(e-s) { b._4 } } + // If you need access to the edges of a foreign Node, use this method (in/out create bundles) + lazy val edges = (edgesIn, edgesOut) - val flip = false // needed for blind nodes - private def flipO(b: HeterogeneousBag[BO]) = if (flip) b.flip else b - private def flipI(b: HeterogeneousBag[BI]) = if (flip) b else b.flip - val wire = false // needed if you want to grab access to from inside a module - private def wireO(b: HeterogeneousBag[BO]) = if (wire) Wire(b) else b - private def wireI(b: HeterogeneousBag[BI]) = if (wire) Wire(b) else b + protected[diplomacy] lazy val bundleOut: Seq[BO] = edgesOut.map(e => Wire(outer.bundleO(e))) + protected[diplomacy] lazy val bundleIn: Seq[BI] = edgesIn .map(e => Wire(inner.bundleI(e))) - lazy val bundleOut = wireO(flipO(HeterogeneousBag(edgesOut.map(outer.bundleO(_))))) - lazy val bundleIn = wireI(flipI(HeterogeneousBag(edgesIn .map(inner.bundleI(_))))) + protected[diplomacy] def danglesOut: Seq[Dangle] = oPorts.zipWithIndex.map { case ((j, n, _), i) => + Dangle( + source = HalfEdge(serial, i), + sink = HalfEdge(n.serial, j), + flipped= false, + name = valName.name + "_out", + data = bundleOut(i)) + } + protected[diplomacy] def danglesIn: Seq[Dangle] = iPorts.zipWithIndex.map { case ((j, n, _), i) => + Dangle( + source = HalfEdge(n.serial, j), + sink = HalfEdge(serial, i), + flipped= true, + name = valName.name + "_in", + data = bundleIn(i)) + } + + // Used by LazyModules.module.instantiate + private var bundlesSafeNow = false + protected[diplomacy] def instantiate() = { + bundlesSafeNow = true + danglesOut ++ danglesIn + } + + // Accessors to the result of negotiation to be used in LazyModuleImp: + def out: Seq[(BO, EO)] = { + require(bundlesSafeNow, s"${name}.out should only be called from the context of it's module implementation") + bundleOut zip edgesOut + } + def in: Seq[(BI, EI)] = { + require(bundlesSafeNow, s"${name}.in should only be called from the context of it's module implementation") + bundleIn zip edgesIn + } // connects the outward part of a node with the inward part of this node private def bind(h: OutwardNodeHandle[DI, UI, BI], binding: NodeBinding) @@ -268,23 +296,7 @@ abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( case BIND_STAR => BIND_QUERY case BIND_QUERY => BIND_STAR }) x.iPush(o, y, binding) - def edges() = { - val (iStart, iEnd) = x.iPortMapping(i) - val (oStart, oEnd) = y.oPortMapping(o) - require (iEnd - iStart == oEnd - oStart, s"Bug in diplomacy; ${iEnd-iStart} != ${oEnd-oStart} means port resolution failed") - Seq.tabulate(iEnd - iStart) { j => x.edgesIn(iStart+j) } - } - def bundles() = { - val (iStart, iEnd) = x.iPortMapping(i) - val (oStart, oEnd) = y.oPortMapping(o) - require (iEnd - iStart == oEnd - oStart, s"Bug in diplomacy; ${iEnd-iStart} != ${oEnd-oStart} means port resolution failed") - Seq.tabulate(iEnd - iStart) { j => - (x.bundleIn(iStart+j), y.bundleOut(oStart+j)) - } - } - val (out, newbinding) = inner.connect(edges _, bundles _, p(MonitorsEnabled)) - LazyModule.stack.head.bindings = newbinding :: LazyModule.stack.head.bindings - out + None // !!! create monitors } override def := (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = bind(h, BIND_ONCE) @@ -333,9 +345,6 @@ class MixedAdapterNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( implicit valName: ValName) extends MixedNode(inner, outer)(num, num) { - val externalIn: Boolean = true - val externalOut: Boolean = true - 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}") if (oStars > 0) { @@ -356,6 +365,24 @@ 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])( + dFn: D => D, + uFn: U => U, + num: Range.Inclusive = 0 to 999)( + implicit valName: ValName) + extends MixedAdapterNode[D, U, EI, B, D, U, EO, B](imp, imp)(dFn, uFn, num) + +// 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) + extends AdapterNode(imp)({ s => s }, { s => s }) +{ + override protected[diplomacy] def instantiate() = { + val dangles = super.instantiate() + (out zip in) map { case ((o, _), (i, _)) => o <> i } + dangles + } +} + class MixedNexusNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( inner: InwardNodeImp [DI, UI, EI, BI], outer: OutwardNodeImp[DO, UO, EO, BO])( @@ -369,9 +396,6 @@ class MixedNexusNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( // require (numPO.end >= 1, s"${name} does not accept outputs${lazyModule.line}") // require (numPI.end >= 1, s"${name} does not accept inputs${lazyModule.line}") - val externalIn: Boolean = true - val externalOut: Boolean = true - 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}") require (oStars == 0, s"${name} (a nexus) appears right of a :=* (perhaps you should flip the '*' to :*=?)${lazyModule.line}") @@ -381,13 +405,6 @@ class MixedNexusNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( protected[diplomacy] def mapParamsU(n: Int, p: Seq[UO]): Seq[UI] = { val a = uFn(p); Seq.fill(n)(a) } } -class AdapterNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])( - dFn: D => D, - uFn: U => U, - num: Range.Inclusive = 0 to 999)( - implicit valName: ValName) - extends MixedAdapterNode[D, U, EI, B, D, U, EO, B](imp, imp)(dFn, uFn, num) - class NexusNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])( dFn: Seq[D] => D, uFn: Seq[U] => U, @@ -396,30 +413,10 @@ class NexusNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])( implicit valName: ValName) extends MixedNexusNode[D, U, EI, B, D, U, EO, B](imp, imp)(dFn, uFn, numPO, numPI) -class IdentityNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(implicit valName: ValName) - extends AdapterNode(imp)({s => s}, {s => s}) - -class OutputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(implicit valName: ValName) extends IdentityNode(imp) -{ - override val externalIn: Boolean = false - override val externalOut: Boolean = true - override lazy val bundleIn = bundleOut -} - -class InputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(implicit valName: ValName) extends IdentityNode(imp) -{ - override val externalIn: Boolean = true - override val externalOut: Boolean = false - - override lazy val bundleOut = bundleIn -} - +// 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) extends MixedNode(imp, imp)(po.size to po.size, 0 to 0) { - override val externalIn: Boolean = false - override val externalOut: Boolean = true - 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 (iStars == 0, s"${name} (a source) cannot appear left of a :*=${lazyModule.line}") @@ -429,16 +426,12 @@ class SourceNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(po: Seq } protected[diplomacy] def mapParamsD(n: Int, p: Seq[D]): Seq[D] = po protected[diplomacy] def mapParamsU(n: Int, p: Seq[U]): Seq[U] = Seq() - - override lazy val bundleIn = { require(false, s"${name} has no bundleIn; try bundleOut?"); bundleOut } } +// 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) extends MixedNode(imp, imp)(0 to 0, pi.size to pi.size) { - override val externalIn: Boolean = true - override val externalOut: Boolean = false - 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 (oStars == 0, s"${name} (a sink) cannot appear right of a :=*${lazyModule.line}") @@ -448,40 +441,4 @@ class SinkNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(pi: Seq[U } protected[diplomacy] def mapParamsD(n: Int, p: Seq[D]): Seq[D] = Seq() protected[diplomacy] def mapParamsU(n: Int, p: Seq[U]): Seq[U] = pi - - override lazy val bundleOut = { require(false, s"${name} has no bundleOut; try bundleIn?"); bundleIn } -} - -class BlindOutputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(pi: Seq[U])(implicit valName: ValName) - extends SinkNode(imp)(pi) -{ - override val externalIn: Boolean = false - override val flip = true - override lazy val bundleOut = bundleIn -} - -class BlindInputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(po: Seq[D])(implicit valName: ValName) - extends SourceNode(imp)(po) -{ - override val externalOut: Boolean = false - override val flip = true - override lazy val bundleIn = bundleOut -} - -class InternalOutputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(pi: Seq[U])(implicit valName: ValName) - extends SinkNode(imp)(pi) -{ - override val externalIn: Boolean = false - override val externalOut: Boolean = false - override val wire = true - override lazy val bundleOut = bundleIn -} - -class InternalInputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(po: Seq[D])(implicit valName: ValName) - extends SourceNode(imp)(po) -{ - override val externalIn: Boolean = false - override val externalOut: Boolean = false - override val wire = true - override lazy val bundleIn = bundleOut } diff --git a/src/main/scala/rocket/BusErrorUnit.scala b/src/main/scala/rocket/BusErrorUnit.scala index fb263db3..7ba2bc2d 100644 --- a/src/main/scala/rocket/BusErrorUnit.scala +++ b/src/main/scala/rocket/BusErrorUnit.scala @@ -37,11 +37,9 @@ class BusErrorUnit[T <: BusErrors](t: => T, params: BusErrorUnitParams)(implicit beatBytes = p(XLen)/8) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val tl = node.bundleIn - val interrupt = intNode.bundleOut + val io = IO(new Bundle { val errors = t.flip - } + }) val sources = io.errors.toErrorList val mask = sources.map(_.nonEmpty.B).asUInt @@ -61,7 +59,8 @@ class BusErrorUnit[T <: BusErrors](t: => T, params: BusErrorUnitParams)(implicit } } - io.interrupt.head(0) := (accrued & interrupt).orR + val (int_out, _) = intNode.out(0) + int_out(0) := (accrued & interrupt).orR def reg(r: UInt) = RegField(regWidth, r) def maskedReg(r: UInt, m: UInt) = RegField(regWidth, r, RegWriteFn((v, d) => { when (v) { r := d & m }; true })) diff --git a/src/main/scala/rocket/Frontend.scala b/src/main/scala/rocket/Frontend.scala index dd102957..948e9676 100644 --- a/src/main/scala/rocket/Frontend.scala +++ b/src/main/scala/rocket/Frontend.scala @@ -56,8 +56,8 @@ class FrontendIO(implicit p: Parameters) extends CoreBundle()(p) { class Frontend(val icacheParams: ICacheParams, hartid: Int)(implicit p: Parameters) extends LazyModule { lazy val module = new FrontendModule(this) val icache = LazyModule(new ICache(icacheParams, hartid)) - val masterNode = TLOutputNode() - val slaveNode = TLInputNode() + val masterNode = TLIdentityNode() + val slaveNode = TLIdentityNode() masterNode := icache.masterNode // Avoid breaking tile dedup due to address constants in the monitor @@ -68,16 +68,14 @@ class FrontendBundle(outer: Frontend) extends CoreBundle()(outer.p) with HasExternallyDrivenTileConstants { val cpu = new FrontendIO().flip val ptw = new TLBPTWIO() - val tl_out = outer.masterNode.bundleOut - val tl_in = outer.slaveNode.bundleIn val errors = new ICacheErrors } class FrontendModule(outer: Frontend) extends LazyModuleImp(outer) with HasCoreParameters with HasL1ICacheParameters { - val io = new FrontendBundle(outer) - implicit val edge = outer.masterNode.edgesOut.head + val io = IO(new FrontendBundle(outer)) + implicit val edge = outer.masterNode.out(0)._2 val icache = outer.icache.module require(fetchWidth*coreInstBytes == outer.icacheParams.fetchBytes) diff --git a/src/main/scala/rocket/HellaCache.scala b/src/main/scala/rocket/HellaCache.scala index 718c1287..3463758c 100644 --- a/src/main/scala/rocket/HellaCache.scala +++ b/src/main/scala/rocket/HellaCache.scala @@ -176,15 +176,14 @@ class HellaCacheBundle(outer: HellaCache)(implicit p: Parameters) extends CoreBu val hartid = UInt(INPUT, hartIdLen) val cpu = (new HellaCacheIO).flip val ptw = new TLBPTWIO() - val mem = outer.node.bundleOut val errors = new DCacheErrors } class HellaCacheModule(outer: HellaCache) extends LazyModuleImp(outer) with HasL1HellaCacheParameters { - implicit val edge = outer.node.edgesOut(0) - val io = new HellaCacheBundle(outer) - val tl_out = io.mem(0) + implicit val edge = outer.node.out(0)._2 + val tl_out = outer.node.out(0)._1 + val io = IO(new HellaCacheBundle(outer)) private val fifoManagers = edge.manager.managers.filter(TLFIFOFixer.allUncacheable) fifoManagers.foreach { m => diff --git a/src/main/scala/rocket/ICache.scala b/src/main/scala/rocket/ICache.scala index 4d60ca08..cf0a6b4d 100644 --- a/src/main/scala/rocket/ICache.scala +++ b/src/main/scala/rocket/ICache.scala @@ -45,9 +45,9 @@ class ICacheErrors(implicit p: Parameters) extends CoreBundle()(p) class ICache(val icacheParams: ICacheParams, val hartid: Int)(implicit p: Parameters) extends LazyModule { lazy val module = new ICacheModule(this) - val masterNode = TLClientNode(TLClientParameters( + val masterNode = TLClientNode(Seq(TLClientPortParameters(Seq(TLClientParameters( sourceId = IdRange(0, 1 + icacheParams.prefetch.toInt), // 0=refill, 1=hint - name = s"Core ${hartid} ICache")) + name = s"Core ${hartid} ICache"))))) val size = icacheParams.nSets * icacheParams.nWays * icacheParams.blockBytes val device = new SimpleDevice("itim", Seq("sifive,itim0")) @@ -91,8 +91,6 @@ class ICacheBundle(outer: ICache) extends CoreBundle()(outer.p) { val resp = Valid(new ICacheResp(outer)) val invalidate = Bool(INPUT) - val tl_out = outer.masterNode.bundleOut - val tl_in = outer.slaveNode.map(_.bundleIn) val errors = new ICacheErrors val perf = new ICachePerfEvents().asOutput @@ -109,11 +107,10 @@ class ICacheModule(outer: ICache) extends LazyModuleImp(outer) with HasL1ICacheParameters { override val cacheParams = outer.icacheParams // Use the local parameters - val io = new ICacheBundle(outer) - val edge_out = outer.masterNode.edgesOut.head - val tl_out = io.tl_out.head - val edge_in = outer.slaveNode.map(_.edgesIn.head) - val tl_in = io.tl_in.map(_.head) + val io = IO(new ICacheBundle(outer)) + val (tl_out, edge_out) = outer.masterNode.out(0) + val tl_in = outer.slaveNode.map(_.in(0)._1) + val edge_in = outer.slaveNode.map(_.in(0)._2) val tECC = cacheParams.tagECC val dECC = cacheParams.dataECC diff --git a/src/main/scala/rocket/PTW.scala b/src/main/scala/rocket/PTW.scala index 0f77fb32..1cab0d93 100644 --- a/src/main/scala/rocket/PTW.scala +++ b/src/main/scala/rocket/PTW.scala @@ -283,7 +283,7 @@ trait CanHavePTW extends HasHellaCache { trait CanHavePTWModule extends HasHellaCacheModule { val outer: CanHavePTW val ptwPorts = ListBuffer(outer.dcache.module.io.ptw) - val ptw = Module(new PTW(outer.nPTWPorts)(outer.dcache.node.edgesOut(0), outer.p)) + val ptw = Module(new PTW(outer.nPTWPorts)(outer.dcache.node.out(0)._2, outer.p)) if (outer.usingPTW) dcachePorts += ptw.io.mem } diff --git a/src/main/scala/rocket/ScratchpadSlavePort.scala b/src/main/scala/rocket/ScratchpadSlavePort.scala index 08959679..45a0f952 100644 --- a/src/main/scala/rocket/ScratchpadSlavePort.scala +++ b/src/main/scala/rocket/ScratchpadSlavePort.scala @@ -30,13 +30,11 @@ class ScratchpadSlavePort(address: AddressSet, coreDataBytes: Int, usingAtomics: minLatency = 1))) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val tl_in = node.bundleIn + val io = IO(new Bundle { val dmem = new HellaCacheIO - } + }) - val tl_in = io.tl_in(0) - val edge = node.edgesIn(0) + val (tl_in, edge) = node.in(0) val s_ready :: s_wait :: s_replay :: s_grant :: Nil = Enum(UInt(), 4) val state = Reg(init = s_ready) @@ -104,7 +102,7 @@ trait CanHaveScratchpad extends HasHellaCache with HasICacheFrontend { LazyModule(new ScratchpadSlavePort(AddressSet(s, d.dataScratchpadBytes-1), xBytes, tileParams.core.useAtomics))) } - val intOutputNode = tileParams.core.tileControlAddr.map(dummy => IntOutputNode()) + val intOutputNode = tileParams.core.tileControlAddr.map(dummy => IntIdentityNode()) val busErrorUnit = tileParams.core.tileControlAddr map { a => val beu = LazyModule(new BusErrorUnit(new L1BusErrors, BusErrorUnitParams(a))) intOutputNode.get := beu.intNode @@ -112,7 +110,7 @@ trait CanHaveScratchpad extends HasHellaCache with HasICacheFrontend { } // connect any combination of ITIM, DTIM, and BusErrorUnit - val slaveNode = TLInputNode() + val slaveNode = TLIdentityNode() DisableMonitors { implicit p => val xbarPorts = scratch.map(lm => (lm.node, xBytes)) ++ @@ -129,7 +127,7 @@ trait CanHaveScratchpad extends HasHellaCache with HasICacheFrontend { } def findScratchpadFromICache: Option[AddressSet] = scratch.map { s => - val finalNode = frontend.masterNode.edgesOut.head.manager.managers.find(_.nodePath.last == s.node) + val finalNode = frontend.masterNode.out.head._2.manager.managers.find(_.nodePath.last == s.node) require (finalNode.isDefined, "Could not find the scratch pad; not reachable via icache?") require (finalNode.get.address.size == 1, "Scratchpad address space was fragmented!") finalNode.get.address(0) @@ -140,8 +138,6 @@ trait CanHaveScratchpad extends HasHellaCache with HasICacheFrontend { trait CanHaveScratchpadBundle extends HasHellaCacheBundle with HasICacheFrontendBundle { val outer: CanHaveScratchpad - val slave = outer.slaveNode.bundleIn - val intOutput = outer.intOutputNode.map(_.bundleOut) } trait CanHaveScratchpadModule extends HasHellaCacheModule with HasICacheFrontendModule { diff --git a/src/main/scala/tile/BaseTile.scala b/src/main/scala/tile/BaseTile.scala index 644ccb6a..a6f5bebe 100644 --- a/src/main/scala/tile/BaseTile.scala +++ b/src/main/scala/tile/BaseTile.scala @@ -66,21 +66,20 @@ abstract class BareTileBundle[+L <: BareTile](_outer: L) extends GenericParamete abstract class BareTileModule[+L <: BareTile, +B <: BareTileBundle[L]](_outer: L, _io: () => B) extends LazyModuleImp(_outer) { val outer = _outer - val io = _io () + val io = IO(_io ()) } /** Uses TileLink master port to connect caches and accelerators to the coreplex */ trait HasTileLinkMasterPort { implicit val p: Parameters val module: HasTileLinkMasterPortModule - val masterNode = TLOutputNode() + val masterNode = TLIdentityNode() val tileBus = LazyModule(new TLXbar) // TileBus xbar for cache backends to connect to masterNode := tileBus.node } trait HasTileLinkMasterPortBundle { val outer: HasTileLinkMasterPort - val master = outer.masterNode.bundleOut } trait HasTileLinkMasterPortModule { diff --git a/src/main/scala/tile/Interrupts.scala b/src/main/scala/tile/Interrupts.scala index 7e438f97..4df8564e 100644 --- a/src/main/scala/tile/Interrupts.scala +++ b/src/main/scala/tile/Interrupts.scala @@ -38,7 +38,6 @@ trait HasExternalInterrupts extends HasTileParameters { trait HasExternalInterruptsBundle { val outer: HasExternalInterrupts - val interrupts = outer.intNode.bundleIn } trait HasExternalInterruptsModule { @@ -57,6 +56,6 @@ trait HasExternalInterruptsModule { val core_ips = core.lip - (async_ips ++ periph_ips ++ seip ++ core_ips).zip(io.interrupts(0)).foreach { case(c, i) => c := i } + (async_ips ++ periph_ips ++ seip ++ core_ips).zip(outer.intNode.in(0)._1).foreach { case(c, i) => c := i } } } diff --git a/src/main/scala/tile/LazyRoCC.scala b/src/main/scala/tile/LazyRoCC.scala index 5ce96169..663ef7bc 100644 --- a/src/main/scala/tile/LazyRoCC.scala +++ b/src/main/scala/tile/LazyRoCC.scala @@ -60,13 +60,11 @@ class RoCCCoreIO(implicit p: Parameters) extends CoreBundle()(p) { abstract class LazyRoCC(implicit p: Parameters) extends LazyModule { val module: LazyRoCCModule - val atlNode: TLMixedNode = TLOutputNode() - val tlNode: TLMixedNode = TLOutputNode() + val atlNode: TLMixedNode = TLIdentityNode() + val tlNode: TLMixedNode = TLIdentityNode() } class RoCCIO(outer: LazyRoCC)(implicit p: Parameters) extends RoCCCoreIO()(p) { - val atl = outer.atlNode.bundleOut - val tl = outer.tlNode.bundleOut // Should be handled differently, eventually val ptw = Vec(p(RoccNPTWPorts), new TLBPTWIO) val fpu_req = Decoupled(new FPInput) @@ -74,7 +72,7 @@ class RoCCIO(outer: LazyRoCC)(implicit p: Parameters) extends RoCCCoreIO()(p) { } class LazyRoCCModule(outer: LazyRoCC) extends LazyModuleImp(outer) { - val io = new RoCCIO(outer) + val io = IO(new RoCCIO(outer)) } /** Mixins for including RoCC **/ @@ -263,7 +261,7 @@ class TranslatorExampleModule(outer: TranslatorExample)(implicit p: Parameters) class CharacterCountExample(implicit p: Parameters) extends LazyRoCC { override lazy val module = new CharacterCountExampleModule(this) - override val atlNode = TLClientNode(TLClientParameters("CharacterCountRoCC")) + override val atlNode = TLClientNode(Seq(TLClientPortParameters(Seq(TLClientParameters("CharacterCountRoCC"))))) } class CharacterCountExampleModule(outer: CharacterCountExample)(implicit p: Parameters) extends LazyRoCCModule(outer) @@ -286,7 +284,7 @@ class CharacterCountExampleModule(outer: CharacterCountExample)(implicit p: Para val s_idle :: s_acq :: s_gnt :: s_check :: s_resp :: Nil = Enum(Bits(), 5) val state = Reg(init = s_idle) - val tl_out = io.atl.head + val (tl_out, edgesOut) = outer.atlNode.out(0) val gnt = tl_out.d.bits val recv_data = Reg(UInt(width = cacheDataBits)) val recv_beat = Reg(UInt(width = log2Up(cacheDataBeats+1)), init = UInt(0)) @@ -309,7 +307,7 @@ class CharacterCountExampleModule(outer: CharacterCountExample)(implicit p: Para io.resp.bits.rd := resp_rd io.resp.bits.data := count tl_out.a.valid := (state === s_acq) - tl_out.a.bits := outer.atlNode.edgesOut(0).Get( + tl_out.a.bits := edgesOut.Get( fromSource = UInt(0), toAddress = addr_block << blockOffset, lgSize = UInt(lgCacheBlockBytes))._2 diff --git a/src/main/scala/tile/RocketTile.scala b/src/main/scala/tile/RocketTile.scala index 14d91e6f..1b42a963 100644 --- a/src/main/scala/tile/RocketTile.scala +++ b/src/main/scala/tile/RocketTile.scala @@ -82,7 +82,7 @@ class RocketTile(val rocketParams: RocketTileParams, val hartid: Int)(implicit p })) // Find all the caches - val outer = masterNode.edgesOut + val outer = masterNode.out.map(_._2) .flatMap(_.manager.managers) .filter(_.supportsAcquireB) .flatMap(_.resources.headOption) @@ -115,7 +115,7 @@ class RocketTile(val rocketParams: RocketTileParams, val hartid: Int)(implicit p Resource(cpuDevice, "reg").bind(ResourceInt(BigInt(hartid))) Resource(intcDevice, "reg").bind(ResourceInt(BigInt(hartid))) - intNode.edgesIn.flatMap(_.source.sources).map { case s => + intNode.in.flatMap(_._2.source.sources).map { case s => for (i <- s.range.start until s.range.end) { csrIntMap.lift(i).foreach { j => s.resources.foreach { r => @@ -181,12 +181,12 @@ class RocketTileModule(outer: RocketTile) extends BaseTileModule(outer, () => ne abstract class RocketTileWrapper(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends LazyModule { val rocket = LazyModule(new RocketTile(rtp, hartid)) - val masterNode: OutputNode[_,_,_,_,_] - val slaveNode: InputNode[_,_,_,_,_] - val intOutputNode = rocket.intOutputNode.map(dummy => IntOutputNode()) - val asyncIntNode = IntInputNode() - val periphIntNode = IntInputNode() - val coreIntNode = IntInputNode() + val masterNode: IdentityNode[_,_,_,_,_] + val slaveNode: IdentityNode[_,_,_,_,_] + val asyncIntNode = IntIdentityNode() + val periphIntNode = IntIdentityNode() + val coreIntNode = IntIdentityNode() + val intOutputNode = rocket.intOutputNode.map(dummy => IntIdentityNode()) val intXbar = LazyModule(new IntXbar) rocket.intNode := intXbar.intnode @@ -220,18 +220,12 @@ abstract class RocketTileWrapper(rtp: RocketTileParams, hartid: Int)(implicit p: } lazy val module = new LazyModuleImp(this) { - val io = new CoreBundle + val io = IO(new CoreBundle with HasExternallyDrivenTileConstants with CanHaveInstructionTracePort with CanHaltAndCatchFire { - val master = masterNode.bundleOut - val slave = slaveNode.bundleIn - val outputInterrupts = intOutputNode.map(_.bundleOut) - val asyncInterrupts = asyncIntNode.bundleIn - val periphInterrupts = periphIntNode.bundleIn - val coreInterrupts = coreIntNode.bundleIn val halt_and_catch_fire = rocket.module.io.halt_and_catch_fire.map(_.cloneType) - } + }) // signals that do not change based on crossing type: rocket.module.io.hartid := io.hartid rocket.module.io.reset_vector := io.reset_vector @@ -241,10 +235,10 @@ abstract class RocketTileWrapper(rtp: RocketTileParams, hartid: Int)(implicit p: } class SyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends RocketTileWrapper(rtp, hartid) { - val masterNode = TLOutputNode() + val masterNode = TLIdentityNode() masterNode :=* optionalMasterBuffer(rocket.masterNode) - val slaveNode = new TLInputNode()(ValName("slave")) { override def reverse = true } + val slaveNode = new TLIdentityNode() { override def reverse = true } DisableMonitors { implicit p => rocket.slaveNode :*= optionalSlaveBuffer(slaveNode) } // Fully async interrupts need synchronizers. @@ -260,12 +254,12 @@ class SyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) } class AsyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends RocketTileWrapper(rtp, hartid) { - val masterNode = TLAsyncOutputNode() + val masterNode = TLAsyncIdentityNode() val source = LazyModule(new TLAsyncCrossingSource) source.node :=* rocket.masterNode masterNode :=* source.node - val slaveNode = new TLAsyncInputNode()(ValName("slave")) { override def reverse = true } + val slaveNode = new TLAsyncIdentityNode() { override def reverse = true } val sink = LazyModule(new TLAsyncCrossingSink) DisableMonitors { implicit p => @@ -289,12 +283,12 @@ class AsyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters } class RationalRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends RocketTileWrapper(rtp, hartid) { - val masterNode = TLRationalOutputNode() + val masterNode = TLRationalIdentityNode() val source = LazyModule(new TLRationalCrossingSource) source.node :=* optionalMasterBuffer(rocket.masterNode) masterNode :=* source.node - val slaveNode = new TLRationalInputNode()(ValName("slave")) { override def reverse = true } + val slaveNode = new TLRationalIdentityNode() { override def reverse = true } val sink = LazyModule(new TLRationalCrossingSink(SlowToFast)) DisableMonitors { implicit p => diff --git a/src/main/scala/tilelink/AsyncCrossing.scala b/src/main/scala/tilelink/AsyncCrossing.scala index 5d8ba48e..de29c051 100644 --- a/src/main/scala/tilelink/AsyncCrossing.scala +++ b/src/main/scala/tilelink/AsyncCrossing.scala @@ -13,12 +13,7 @@ class TLAsyncCrossingSource(sync: Int = 3)(implicit p: Parameters) extends LazyM val node = TLAsyncSourceNode(sync) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - val out = node.bundleOut - } - - ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => + (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => val sink_reset_n = out.a.sink_reset_n val bce = edgeIn.manager.anySupportAcquireB && edgeIn.client.anySupportProbe val depth = edgeOut.manager.depth @@ -47,12 +42,7 @@ class TLAsyncCrossingSink(depth: Int = 8, sync: Int = 3)(implicit p: Parameters) val node = TLAsyncSinkNode(depth, sync) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - val out = node.bundleOut - } - - ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => + (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => val source_reset_n = in.a.source_reset_n val bce = edgeOut.manager.anySupportAcquireB && edgeOut.client.anySupportProbe @@ -97,8 +87,8 @@ object TLAsyncCrossingSink class TLAsyncCrossing(depth: Int = 8, sync: Int = 3)(implicit p: Parameters) extends LazyModule { - val nodeIn = TLInputNode() - val nodeOut = TLOutputNode() + val nodeIn = TLIdentityNode() + val nodeOut = TLIdentityNode() val node = NodeHandle(nodeIn, nodeOut) val source = LazyModule(new TLAsyncCrossingSource(sync)) @@ -109,14 +99,12 @@ class TLAsyncCrossing(depth: Int = 8, sync: Int = 3)(implicit p: Parameters) ext val out = (nodeOut := sink.node) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = nodeIn.bundleIn + val io = IO(new Bundle { val in_clock = Clock(INPUT) val in_reset = Bool(INPUT) - val out = nodeOut.bundleOut val out_clock = Clock(INPUT) val out_reset = Bool(INPUT) - } + }) source.module.clock := io.in_clock source.module.reset := io.in_reset @@ -147,7 +135,7 @@ class TLRAMAsyncCrossing(txns: Int)(implicit p: Parameters) extends LazyModule { cross.node := TLFragmenter(4, 256)(TLDelayer(0.1)(model.node)) val monitor = (ram.node := cross.node) - lazy val module = new LazyModuleImp(this) with HasUnitTestIO { + lazy val module = new LazyModuleImp(this) with UnitTestModule { io.finished := fuzz.module.io.finished // Shove the RAM into another clock domain diff --git a/src/main/scala/tilelink/AtomicAutomata.scala b/src/main/scala/tilelink/AtomicAutomata.scala index 293c5127..adb76daa 100644 --- a/src/main/scala/tilelink/AtomicAutomata.scala +++ b/src/main/scala/tilelink/AtomicAutomata.scala @@ -29,12 +29,7 @@ class TLAtomicAutomata(logical: Boolean = true, arithmetic: Boolean = true, conc })}) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - val out = node.bundleOut - } - - ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => + (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => val managers = edgeOut.manager.managers val beatBytes = edgeOut.manager.beatBytes @@ -297,7 +292,7 @@ class TLRAMAtomicAutomata(txns: Int)(implicit p: Parameters) extends LazyModule model.node := fuzz.node ram.node := TLFragmenter(4, 256)(TLDelayer(0.1)(TLAtomicAutomata()(TLDelayer(0.1)(model.node)))) - lazy val module = new LazyModuleImp(this) with HasUnitTestIO { + lazy val module = new LazyModuleImp(this) with UnitTestModule { io.finished := fuzz.module.io.finished } } diff --git a/src/main/scala/tilelink/Broadcast.scala b/src/main/scala/tilelink/Broadcast.scala index 5b24bf90..3e203a13 100644 --- a/src/main/scala/tilelink/Broadcast.scala +++ b/src/main/scala/tilelink/Broadcast.scala @@ -53,12 +53,7 @@ class TLBroadcast(lineBytes: Int, numTrackers: Int = 4, bufferless: Boolean = fa ) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - val out = node.bundleOut - } - - ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => + (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => val clients = edgeIn.client.clients val managers = edgeOut.manager.managers val lineShift = log2Ceil(lineBytes) diff --git a/src/main/scala/tilelink/Buffer.scala b/src/main/scala/tilelink/Buffer.scala index 6242a1a9..84e42d1d 100644 --- a/src/main/scala/tilelink/Buffer.scala +++ b/src/main/scala/tilelink/Buffer.scala @@ -35,12 +35,7 @@ class TLBuffer( val node = new TLBufferNode(a, b, c, d, e) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - val out = node.bundleOut - } - - ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => + (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => out.a <> a(in .a) in .d <> d(out.d) @@ -80,8 +75,8 @@ object TLBuffer class TLBufferChain(depth: Int)(implicit p: Parameters) extends LazyModule { - val nodeIn = TLInputNode() - val nodeOut = TLOutputNode() + val nodeIn = TLIdentityNode() + val nodeOut = TLIdentityNode() val node = NodeHandle(nodeIn, nodeOut) val buf_chain = if (depth > 0) { @@ -96,12 +91,7 @@ class TLBufferChain(depth: Int)(implicit p: Parameters) extends LazyModule { buf_chain.head.node :=? nodeIn nodeOut :=? buf_chain.last.node - lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = nodeIn.bundleIn - val out = nodeOut.bundleOut - } - } + lazy val module = new LazyModuleImp(this) { } } object TLBufferChain diff --git a/src/main/scala/tilelink/CacheCork.scala b/src/main/scala/tilelink/CacheCork.scala index 29f18dbc..9503e97d 100644 --- a/src/main/scala/tilelink/CacheCork.scala +++ b/src/main/scala/tilelink/CacheCork.scala @@ -24,12 +24,7 @@ class TLCacheCork(unsafe: Boolean = false)(implicit p: Parameters) extends LazyM supportsAcquireT = if (m.regionType == RegionType.UNCACHED) m.supportsPutFull else m.supportsAcquireT)})}) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - val out = node.bundleOut - } - - ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => + (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => val clients = edgeIn.client.clients val caches = clients.filter(_.supportsProbe) require (clients.size == 1 || caches.size == 0 || unsafe, "Only one client can safely use a TLCacheCork") diff --git a/src/main/scala/tilelink/Delayer.scala b/src/main/scala/tilelink/Delayer.scala index 6bb69413..2bbe1fcc 100644 --- a/src/main/scala/tilelink/Delayer.scala +++ b/src/main/scala/tilelink/Delayer.scala @@ -10,15 +10,10 @@ import freechips.rocketchip.diplomacy._ // q is the probability to delay a request class TLDelayer(q: Double)(implicit p: Parameters) extends LazyModule { - val node = TLIdentityNode() + val node = TLAdapterNode() require (0.0 <= q && q < 1) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - val out = node.bundleOut - } - def feed[T <: Data](sink: DecoupledIO[T], source: DecoupledIO[T], noise: T) { val allow = UInt((q * 65535.0).toInt) <= LFSR16(source.valid) sink.valid := source.valid && allow @@ -27,7 +22,7 @@ class TLDelayer(q: Double)(implicit p: Parameters) extends LazyModule when (!sink.valid) { sink.bits := noise } } - (io.in zip io.out) foreach { case (in, out) => + (node.in zip node.out) foreach { case ((in, _), (out, _)) => val anoise = Wire(in.a.bits) anoise.opcode := LFSRNoiseMaker(3) anoise.param := LFSRNoiseMaker(3) diff --git a/src/main/scala/tilelink/Edges.scala b/src/main/scala/tilelink/Edges.scala index d0e9ecc5..4734cbda 100644 --- a/src/main/scala/tilelink/Edges.scala +++ b/src/main/scala/tilelink/Edges.scala @@ -4,13 +4,15 @@ package freechips.rocketchip.tilelink import Chisel._ import chisel3.internal.sourceinfo.SourceInfo +import freechips.rocketchip.config.Parameters import freechips.rocketchip.diplomacy._ import freechips.rocketchip.util._ class TLEdge( client: TLClientPortParameters, - manager: TLManagerPortParameters) - extends TLEdgeParameters(client, manager) + manager: TLManagerPortParameters, + params: Parameters) + extends TLEdgeParameters(client, manager, params) { def isAligned(address: UInt, lgSize: UInt): Bool = { if (maxLgSize == 0) Bool(true) else { @@ -262,8 +264,9 @@ class TLEdge( class TLEdgeOut( client: TLClientPortParameters, - manager: TLManagerPortParameters) - extends TLEdge(client, manager) + manager: TLManagerPortParameters, + params: Parameters) + extends TLEdge(client, manager, params) { // Transfers def Acquire(fromSource: UInt, toAddress: UInt, lgSize: UInt, growPermissions: UInt) = { @@ -476,8 +479,9 @@ class TLEdgeOut( class TLEdgeIn( client: TLClientPortParameters, - manager: TLManagerPortParameters) - extends TLEdge(client, manager) + manager: TLManagerPortParameters, + params: Parameters) + extends TLEdge(client, manager, params) { // Transfers def Probe(fromAddress: UInt, toSource: UInt, lgSize: UInt, capPermissions: UInt) = { diff --git a/src/main/scala/tilelink/FIFOFixer.scala b/src/main/scala/tilelink/FIFOFixer.scala index e647b986..7cb78921 100644 --- a/src/main/scala/tilelink/FIFOFixer.scala +++ b/src/main/scala/tilelink/FIFOFixer.scala @@ -41,12 +41,7 @@ class TLFIFOFixer(policy: TLFIFOFixer.Policy = TLFIFOFixer.all)(implicit p: Para }) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - val out = node.bundleOut - } - - ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => + (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => val (fixMap, splatMap) = fifoMap(edgeOut.manager.managers) // Do we need to serialize the request to this manager? diff --git a/src/main/scala/tilelink/Filter.scala b/src/main/scala/tilelink/Filter.scala index be20dfe4..db155654 100644 --- a/src/main/scala/tilelink/Filter.scala +++ b/src/main/scala/tilelink/Filter.scala @@ -49,11 +49,9 @@ class TLFilter( })}) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - val out = node.bundleOut + (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => + out <> in } - io.out <> io.in } } diff --git a/src/main/scala/tilelink/Fragmenter.scala b/src/main/scala/tilelink/Fragmenter.scala index 0903227e..1f4e8dc7 100644 --- a/src/main/scala/tilelink/Fragmenter.scala +++ b/src/main/scala/tilelink/Fragmenter.scala @@ -52,12 +52,7 @@ class TLFragmenter(val minSize: Int, val maxSize: Int, val alwaysMin: Boolean = managerFn = { m => m.copy(managers = m.managers.map(mapManager)) }) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - val out = node.bundleOut - } - - ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => + (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => // All managers must share a common FIFO domain (responses might end up interleaved) val manager = edgeOut.manager val managers = manager.managers @@ -249,7 +244,7 @@ class TLFragmenter(val minSize: Int, val maxSize: Int, val alwaysMin: Boolean = val aFrag = Mux(aOrig > limit, limit, aOrig) val aOrigOH1 = UIntToOH1(aOrig, log2Ceil(maxSize)) val aFragOH1 = UIntToOH1(aFrag, log2Up(maxDownSize)) - val aHasData = node.edgesIn(0).hasData(in_a.bits) + val aHasData = edgeIn.hasData(in_a.bits) val aMask = Mux(aHasData, UInt(0), aFragOH1) val gennum = RegInit(UInt(0, width = counterBits)) @@ -317,7 +312,7 @@ class TLRAMFragmenter(ramBeatBytes: Int, maxSize: Int, txns: Int)(implicit p: Pa TLBuffer(BufferParams.flow)( model.node))))))))) - lazy val module = new LazyModuleImp(this) with HasUnitTestIO { + lazy val module = new LazyModuleImp(this) with UnitTestModule { io.finished := fuzz.module.io.finished } } diff --git a/src/main/scala/tilelink/Fuzzer.scala b/src/main/scala/tilelink/Fuzzer.scala index c37ad450..beac41f1 100644 --- a/src/main/scala/tilelink/Fuzzer.scala +++ b/src/main/scala/tilelink/Fuzzer.scala @@ -107,13 +107,11 @@ class TLFuzzer( val node = TLClientNode(Seq(TLClientPortParameters(clientParams))) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val out = node.bundleOut + val io = IO(new Bundle { val finished = Bool(OUTPUT) - } + }) - val out = io.out(0) - val edge = node.edgesOut(0) + val (out, edge) = node.out(0) // Extract useful parameters from the TL edge val maxTransfer = edge.manager.maxTransfer @@ -245,7 +243,7 @@ class TLFuzzRAM(txns: Int)(implicit p: Parameters) extends LazyModule val monitor = (ram.node := cross.node) gpio.node := TLFragmenter(4, 32)(TLBuffer()(xbar.node)) - lazy val module = new LazyModuleImp(this) with HasUnitTestIO { + lazy val module = new LazyModuleImp(this) with UnitTestModule { io.finished := fuzz.module.io.finished // Shove the RAM into another clock domain diff --git a/src/main/scala/tilelink/HintHandler.scala b/src/main/scala/tilelink/HintHandler.scala index 40df8ed2..ee97b2d8 100644 --- a/src/main/scala/tilelink/HintHandler.scala +++ b/src/main/scala/tilelink/HintHandler.scala @@ -16,12 +16,7 @@ class TLHintHandler(supportManagers: Boolean = true, supportClients: Boolean = f 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) { - val io = new Bundle { - val in = node.bundleIn - val out = node.bundleOut - } - - ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => + (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => // Don't add support for clients if there is no BCE channel val bce = edgeOut.manager.anySupportAcquireB && edgeIn.client.anySupportProbe require (!supportClients || bce) @@ -118,7 +113,7 @@ class TLRAMHintHandler(txns: Int)(implicit p: Parameters) extends LazyModule { model.node := fuzz.node ram.node := TLFragmenter(4, 256)(TLDelayer(0.1)(TLHintHandler()(TLDelayer(0.1)(model.node)))) - lazy val module = new LazyModuleImp(this) with HasUnitTestIO { + lazy val module = new LazyModuleImp(this) with UnitTestModule { io.finished := fuzz.module.io.finished } } diff --git a/src/main/scala/tilelink/IntNodes.scala b/src/main/scala/tilelink/IntNodes.scala index c9deea7b..dc33640d 100644 --- a/src/main/scala/tilelink/IntNodes.scala +++ b/src/main/scala/tilelink/IntNodes.scala @@ -61,12 +61,12 @@ object IntSinkPortSimple Seq.fill(ports)(IntSinkPortParameters(Seq.fill(sinks)(IntSinkParameters()))) } -case class IntEdge(source: IntSourcePortParameters, sink: IntSinkPortParameters) +case class IntEdge(source: IntSourcePortParameters, sink: IntSinkPortParameters, params: Parameters) object IntImp extends NodeImp[IntSourcePortParameters, IntSinkPortParameters, IntEdge, IntEdge, Vec[Bool]] { - def edgeO(pd: IntSourcePortParameters, pu: IntSinkPortParameters): IntEdge = IntEdge(pd, pu) - def edgeI(pd: IntSourcePortParameters, pu: IntSinkPortParameters): IntEdge = IntEdge(pd, pu) + def edgeO(pd: IntSourcePortParameters, pu: IntSinkPortParameters, p: Parameters): IntEdge = IntEdge(pd, pu, p) + def edgeI(pd: IntSourcePortParameters, pu: IntSinkPortParameters, p: Parameters): IntEdge = IntEdge(pd, pu, p) def bundleO(eo: IntEdge): Vec[Bool] = Vec(eo.source.num, Bool()) def bundleI(ei: IntEdge): Vec[Bool] = Vec(ei.source.num, Bool()) @@ -75,22 +75,21 @@ object IntImp extends NodeImp[IntSourcePortParameters, IntSinkPortParameters, In override def labelI(ei: IntEdge) = ei.source.sources.map(_.range.size).sum.toString override def labelO(eo: IntEdge) = eo.source.sources.map(_.range.size).sum.toString - def connect(bo: => Vec[Bool], bi: => Vec[Bool], ei: => IntEdge)(implicit p: Parameters, sourceInfo: SourceInfo): (Option[LazyModule], () => Unit) = { - (None, () => { - // Cannot use bulk connect, because the widths could differ - (bo zip bi) foreach { case (o, i) => i := o } - }) - } - override def mixO(pd: IntSourcePortParameters, node: OutwardNode[IntSourcePortParameters, IntSinkPortParameters, Vec[Bool]]): IntSourcePortParameters = pd.copy(sources = pd.sources.map { s => s.copy (nodePath = node +: s.nodePath) }) override def mixI(pu: IntSinkPortParameters, node: InwardNode[IntSourcePortParameters, IntSinkPortParameters, Vec[Bool]]): IntSinkPortParameters = pu.copy(sinks = pu.sinks.map { s => s.copy (nodePath = node +: s.nodePath) }) } -case class IntIdentityNode()(implicit valName: ValName) extends IdentityNode(IntImp) case class IntSourceNode(portParams: Seq[IntSourcePortParameters])(implicit valName: ValName) extends SourceNode(IntImp)(portParams) case class IntSinkNode(portParams: Seq[IntSinkPortParameters])(implicit valName: ValName) extends SinkNode(IntImp)(portParams) +case class IntAdapterNode( + sourceFn: IntSourcePortParameters => IntSourcePortParameters = { s => s }, + sinkFn: IntSinkPortParameters => IntSinkPortParameters = { s => s }, + num: Range.Inclusive = 0 to 999)( + implicit valName: ValName) + extends AdapterNode(IntImp)(sourceFn, sinkFn, num) +case class IntIdentityNode()(implicit valName: ValName) extends IdentityNode(IntImp)() case class IntNexusNode( sourceFn: Seq[IntSourcePortParameters] => IntSourcePortParameters, @@ -100,15 +99,6 @@ case class IntNexusNode( implicit valName: ValName) extends NexusNode(IntImp)(sourceFn, sinkFn, numSourcePorts, numSinkPorts) -case class IntOutputNode()(implicit valName: ValName) extends OutputNode(IntImp) -case class IntInputNode()(implicit valName: ValName) extends InputNode(IntImp) - -case class IntBlindOutputNode(portParams: Seq[IntSinkPortParameters])(implicit valName: ValName) extends BlindOutputNode(IntImp)(portParams) -case class IntBlindInputNode(portParams: Seq[IntSourcePortParameters])(implicit valName: ValName) extends BlindInputNode(IntImp)(portParams) - -case class IntInternalOutputNode(portParams: Seq[IntSinkPortParameters])(implicit valName: ValName) extends InternalOutputNode(IntImp)(portParams) -case class IntInternalInputNode(portParams: Seq[IntSourcePortParameters])(implicit valName: ValName) extends InternalInputNode(IntImp)(portParams) - class IntXbar()(implicit p: Parameters) extends LazyModule { val intnode = IntNexusNode( @@ -120,27 +110,17 @@ class IntXbar()(implicit p: Parameters) extends LazyModule }) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = intnode.bundleIn - val out = intnode.bundleOut - } - - val cat = (intnode.edgesIn zip io.in).map{ case (e, i) => i.take(e.source.num) }.flatten - io.out.foreach { _ := cat } + val cat = intnode.in.map { case (i, e) => i.take(e.source.num) }.flatten + intnode.out.foreach { case (o, _) => o := cat } } } class IntXing(sync: Int = 3)(implicit p: Parameters) extends LazyModule { - val intnode = IntIdentityNode() + val intnode = IntAdapterNode() lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = intnode.bundleIn - val out = intnode.bundleOut - } - - (io.in zip io.out) foreach { case (in, out) => + (intnode.in zip intnode.out) foreach { case ((in, _), (out, _)) => out := SynchronizerShiftReg(in, sync) } } diff --git a/src/main/scala/tilelink/Isolation.scala b/src/main/scala/tilelink/Isolation.scala index f437e867..dcd153fc 100644 --- a/src/main/scala/tilelink/Isolation.scala +++ b/src/main/scala/tilelink/Isolation.scala @@ -11,15 +11,13 @@ import freechips.rocketchip.util.AsyncBundle // READ the comments in the TLIsolation object before you instantiate this module class TLIsolation(fOut: (Bool, UInt) => UInt, fIn: (Bool, UInt) => UInt)(implicit p: Parameters) extends LazyModule { - val node = TLAsyncIdentityNode() + val node = TLAsyncAdapterNode() lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - val out = node.bundleOut + val io = IO(new Bundle { val iso_out = Bool(INPUT) // Isolate from client to manager val iso_in = Bool(INPUT) // Isolate from manager to client - } + }) def ISOo[T <: Data](x: T): T = x.fromBits(fOut(io.iso_out, x.asUInt)) def ISOi[T <: Data](x: T): T = x.fromBits(fIn (io.iso_in, x.asUInt)) @@ -53,7 +51,7 @@ class TLIsolation(fOut: (Bool, UInt) => UInt, fIn: (Bool, UInt) => UInt)(implici y.sink_reset_n := Bool(false) } - ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => + (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => ABo(out.a, in .a) ABi(in .d, out.d) diff --git a/src/main/scala/tilelink/Map.scala b/src/main/scala/tilelink/Map.scala index 05c17185..89d1b9ee 100644 --- a/src/main/scala/tilelink/Map.scala +++ b/src/main/scala/tilelink/Map.scala @@ -20,14 +20,8 @@ class TLMap(fn: AddressSet => BigInt)(implicit p: Parameters) extends LazyModule AddressSet(fn(a), a.mask)))))}) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - val out = node.bundleOut - } - - io.out <> io.in - - ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => + (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => + out <> in val convert = edgeIn.manager.managers.flatMap(_.address) zip edgeOut.manager.managers.flatMap(_.address) def forward(x: UInt) = convert.map { case (i, o) => Mux(i.contains(x), UInt(o.base) | (x & UInt(o.mask)), UInt(0)) }.reduce(_ | _) diff --git a/src/main/scala/tilelink/Monitor.scala b/src/main/scala/tilelink/Monitor.scala index 5b06ffd5..ec4a8a97 100644 --- a/src/main/scala/tilelink/Monitor.scala +++ b/src/main/scala/tilelink/Monitor.scala @@ -16,9 +16,9 @@ abstract class TLMonitorBase(args: TLMonitorArgs) extends MonitorBase()(args.sou lazy val module = new LazyModuleImp(this) { val edges = args.edge() - val io = new Bundle { + val io = IO(new Bundle { val in = HeterogeneousBag(edges.map(p => new TLBundleSnoop(p.bundle))).flip - } + }) (edges zip io.in).foreach { case (e, in) => legalize(in, e, reset) } } diff --git a/src/main/scala/tilelink/NodeNumberer.scala b/src/main/scala/tilelink/NodeNumberer.scala index cee8508b..6c3d17be 100644 --- a/src/main/scala/tilelink/NodeNumberer.scala +++ b/src/main/scala/tilelink/NodeNumberer.scala @@ -9,9 +9,6 @@ import freechips.rocketchip.diplomacy._ case class TLNodeNumbererNode(nodeAddressOffset: Option[Int] = None)(implicit valName: ValName) extends TLCustomNode(0 to 999, 0 to 999) { - val externalIn = true - val externalOut = true - 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}") if (oStars > 0) { @@ -46,15 +43,10 @@ class TLNodeNumberer(nodeAddressOffset: Option[Int] = None)(implicit p: Paramete val node = TLNodeNumbererNode(nodeAddressOffset) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - val out = node.bundleOut - } - - val minNodeOffset = log2Ceil(node.edgesOut.map(_.manager.maxAddress).max) + val minNodeOffset = log2Ceil(node.out.map(_._2.manager.maxAddress).max) val nodeOffset = nodeAddressOffset.getOrElse(minNodeOffset) - (io.in zip io.out).zipWithIndex foreach { case ((in, out), i) => + (node.in zip node.out).zipWithIndex foreach { case (((in, _), (out, _)), i) => out <> in // a&c address already get truncated in.b.bits.address := (UInt(i+1) << nodeOffset) | out.b.bits.address diff --git a/src/main/scala/tilelink/Nodes.scala b/src/main/scala/tilelink/Nodes.scala index 9d74db5f..9b96147a 100644 --- a/src/main/scala/tilelink/Nodes.scala +++ b/src/main/scala/tilelink/Nodes.scala @@ -14,8 +14,8 @@ case object TLCombinationalCheck extends Field[Boolean](false) object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TLEdgeOut, TLEdgeIn, TLBundle] { - def edgeO(pd: TLClientPortParameters, pu: TLManagerPortParameters): TLEdgeOut = new TLEdgeOut(pd, pu) - def edgeI(pd: TLClientPortParameters, pu: TLManagerPortParameters): TLEdgeIn = new TLEdgeIn(pd, pu) + def edgeO(pd: TLClientPortParameters, pu: TLManagerPortParameters, p: Parameters): TLEdgeOut = new TLEdgeOut(pd, pu, p) + def edgeI(pd: TLClientPortParameters, pu: TLManagerPortParameters, p: Parameters): TLEdgeIn = new TLEdgeIn(pd, pu, p) def bundleO(eo: TLEdgeOut): TLBundle = TLBundle(eo.bundle) def bundleI(ei: TLEdgeIn): TLBundle = TLBundle(ei.bundle) @@ -63,30 +63,18 @@ object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TL } } -// Nodes implemented inside modules -case class TLIdentityNode()(implicit valName: ValName) extends IdentityNode(TLImp) case class TLClientNode(portParams: Seq[TLClientPortParameters])(implicit valName: ValName) extends SourceNode(TLImp)(portParams) case class TLManagerNode(portParams: Seq[TLManagerPortParameters])(implicit valName: ValName) extends SinkNode(TLImp)(portParams) -object TLClientNode -{ - def apply(params: TLClientParameters)(implicit valName: ValName) = - new TLClientNode(Seq(TLClientPortParameters(Seq(params)))) -} - -object TLManagerNode -{ - def apply(beatBytes: Int, params: TLManagerParameters)(implicit valName: ValName) = - new TLManagerNode(Seq(TLManagerPortParameters(Seq(params), beatBytes, minLatency = 0))) -} - case class TLAdapterNode( - clientFn: TLClientPortParameters => TLClientPortParameters, - managerFn: TLManagerPortParameters => TLManagerPortParameters, + clientFn: TLClientPortParameters => TLClientPortParameters = { s => s }, + managerFn: TLManagerPortParameters => TLManagerPortParameters = { s => s }, num: Range.Inclusive = 0 to 999)( implicit valName: ValName) extends AdapterNode(TLImp)(clientFn, managerFn, num) +case class TLIdentityNode()(implicit valName: ValName) extends IdentityNode(TLImp)() + case class TLNexusNode( clientFn: Seq[TLClientPortParameters] => TLClientPortParameters, managerFn: Seq[TLManagerPortParameters] => TLManagerPortParameters, @@ -101,43 +89,12 @@ abstract class TLCustomNode( implicit valName: ValName) extends CustomNode(TLImp)(numClientPorts, numManagerPorts) -// Nodes passed from an inner module -case class TLOutputNode()(implicit valName: ValName) extends OutputNode(TLImp) -case class TLInputNode()(implicit valName: ValName) extends InputNode(TLImp) - -// Nodes used for external ports -case class TLBlindOutputNode(portParams: Seq[TLManagerPortParameters])(implicit valName: ValName) extends BlindOutputNode(TLImp)(portParams) -case class TLBlindInputNode(portParams: Seq[TLClientPortParameters])(implicit valName: ValName) extends BlindInputNode(TLImp)(portParams) - -case class TLInternalOutputNode(portParams: Seq[TLManagerPortParameters])(implicit valName: ValName) extends InternalOutputNode(TLImp)(portParams) -case class TLInternalInputNode(portParams: Seq[TLClientPortParameters])(implicit valName: ValName) extends InternalInputNode(TLImp)(portParams) - -/** Synthesizeable unit tests */ -import freechips.rocketchip.unittest._ - -class TLInputNodeTest(txns: Int = 5000, timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) { - class Acceptor extends LazyModule { - val node = TLInputNode() - val tlram = LazyModule(new TLRAM(AddressSet(0x54321000, 0xfff))) - tlram.node := node - - lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - } - } - } - - val fuzzer = LazyModule(new TLFuzzer(txns)) - LazyModule(new Acceptor).node := TLFragmenter(4, 64)(fuzzer.node) - - io.finished := Module(fuzzer.module).io.finished -} +// Asynchronous crossings object TLAsyncImp extends NodeImp[TLAsyncClientPortParameters, TLAsyncManagerPortParameters, TLAsyncEdgeParameters, TLAsyncEdgeParameters, TLAsyncBundle] { - def edgeO(pd: TLAsyncClientPortParameters, pu: TLAsyncManagerPortParameters): TLAsyncEdgeParameters = TLAsyncEdgeParameters(pd, pu) - def edgeI(pd: TLAsyncClientPortParameters, pu: TLAsyncManagerPortParameters): TLAsyncEdgeParameters = TLAsyncEdgeParameters(pd, pu) + def edgeO(pd: TLAsyncClientPortParameters, pu: TLAsyncManagerPortParameters, p: Parameters): TLAsyncEdgeParameters = TLAsyncEdgeParameters(pd, pu, p) + def edgeI(pd: TLAsyncClientPortParameters, pu: TLAsyncManagerPortParameters, p: Parameters): TLAsyncEdgeParameters = TLAsyncEdgeParameters(pd, pu, p) def bundleO(eo: TLAsyncEdgeParameters): TLAsyncBundle = new TLAsyncBundle(eo.bundle) def bundleI(ei: TLAsyncEdgeParameters): TLAsyncBundle = new TLAsyncBundle(ei.bundle) @@ -152,9 +109,14 @@ object TLAsyncImp extends NodeImp[TLAsyncClientPortParameters, TLAsyncManagerPor pu.copy(base = pu.base.copy(managers = pu.base.managers.map { m => m.copy (nodePath = node +: m.nodePath) })) } -case class TLAsyncIdentityNode()(implicit valName: ValName) extends IdentityNode(TLAsyncImp) -case class TLAsyncOutputNode()(implicit valName: ValName) extends OutputNode(TLAsyncImp) -case class TLAsyncInputNode()(implicit valName: ValName) extends InputNode(TLAsyncImp) +case class TLAsyncAdapterNode( + clientFn: TLAsyncClientPortParameters => TLAsyncClientPortParameters = { s => s }, + managerFn: TLAsyncManagerPortParameters => TLAsyncManagerPortParameters = { s => s }, + num: Range.Inclusive = 0 to 999)( + implicit valName: ValName) + extends AdapterNode(TLAsyncImp)(clientFn, managerFn, num) + +case class TLAsyncIdentityNode()(implicit valName: ValName) extends IdentityNode(TLAsyncImp)() case class TLAsyncSourceNode(sync: Int)(implicit valName: ValName) extends MixedAdapterNode(TLImp, TLAsyncImp)( @@ -166,10 +128,12 @@ case class TLAsyncSinkNode(depth: Int, sync: Int)(implicit valName: ValName) dFn = { p => p.base.copy(minLatency = sync+1) }, uFn = { p => TLAsyncManagerPortParameters(depth, p) }) +// Rationally related crossings + object TLRationalImp extends NodeImp[TLRationalClientPortParameters, TLRationalManagerPortParameters, TLRationalEdgeParameters, TLRationalEdgeParameters, TLRationalBundle] { - def edgeO(pd: TLRationalClientPortParameters, pu: TLRationalManagerPortParameters): TLRationalEdgeParameters = TLRationalEdgeParameters(pd, pu) - def edgeI(pd: TLRationalClientPortParameters, pu: TLRationalManagerPortParameters): TLRationalEdgeParameters = TLRationalEdgeParameters(pd, pu) + def edgeO(pd: TLRationalClientPortParameters, pu: TLRationalManagerPortParameters, p: Parameters): TLRationalEdgeParameters = TLRationalEdgeParameters(pd, pu, p) + def edgeI(pd: TLRationalClientPortParameters, pu: TLRationalManagerPortParameters, p: Parameters): TLRationalEdgeParameters = TLRationalEdgeParameters(pd, pu, p) def bundleO(eo: TLRationalEdgeParameters): TLRationalBundle = new TLRationalBundle(eo.bundle) def bundleI(ei: TLRationalEdgeParameters): TLRationalBundle = new TLRationalBundle(ei.bundle) @@ -182,9 +146,14 @@ object TLRationalImp extends NodeImp[TLRationalClientPortParameters, TLRationalM pu.copy(base = pu.base.copy(managers = pu.base.managers.map { m => m.copy (nodePath = node +: m.nodePath) })) } -case class TLRationalIdentityNode()(implicit valName: ValName) extends IdentityNode(TLRationalImp) -case class TLRationalOutputNode()(implicit valName: ValName) extends OutputNode(TLRationalImp) -case class TLRationalInputNode()(implicit valName: ValName) extends InputNode(TLRationalImp) +case class TLRationalAdapterNode( + clientFn: TLRationalClientPortParameters => TLRationalClientPortParameters = { s => s }, + managerFn: TLRationalManagerPortParameters => TLRationalManagerPortParameters = { s => s }, + num: Range.Inclusive = 0 to 999)( + implicit valName: ValName) + extends AdapterNode(TLRationalImp)(clientFn, managerFn, num) + +case class TLRationalIdentityNode()(implicit valName: ValName) extends IdentityNode(TLRationalImp)() case class TLRationalSourceNode()(implicit valName: ValName) extends MixedAdapterNode(TLImp, TLRationalImp)( diff --git a/src/main/scala/tilelink/Parameters.scala b/src/main/scala/tilelink/Parameters.scala index 50eb607c..b4f5c7ce 100644 --- a/src/main/scala/tilelink/Parameters.scala +++ b/src/main/scala/tilelink/Parameters.scala @@ -3,6 +3,7 @@ package freechips.rocketchip.tilelink import Chisel._ +import freechips.rocketchip.config.Parameters import freechips.rocketchip.diplomacy._ import freechips.rocketchip.util.RationalDirection import scala.math.max @@ -312,7 +313,8 @@ object TLBundleParameters case class TLEdgeParameters( client: TLClientPortParameters, - manager: TLManagerPortParameters) + manager: TLManagerPortParameters, + params: Parameters) { val maxTransfer = max(client.maxTransfer, manager.maxTransfer) val maxLgSize = log2Ceil(maxTransfer) @@ -340,7 +342,7 @@ object TLAsyncBundleParameters def union(x: Seq[TLAsyncBundleParameters]) = x.foldLeft(emptyBundleParams)((x,y) => x.union(y)) } -case class TLAsyncEdgeParameters(client: TLAsyncClientPortParameters, manager: TLAsyncManagerPortParameters) +case class TLAsyncEdgeParameters(client: TLAsyncClientPortParameters, manager: TLAsyncManagerPortParameters, params: Parameters) { val bundle = TLAsyncBundleParameters(manager.depth, TLBundleParameters(client.base, manager.base)) } @@ -348,7 +350,7 @@ case class TLAsyncEdgeParameters(client: TLAsyncClientPortParameters, manager: T case class TLRationalManagerPortParameters(direction: RationalDirection, base: TLManagerPortParameters) case class TLRationalClientPortParameters(base: TLClientPortParameters) -case class TLRationalEdgeParameters(client: TLRationalClientPortParameters, manager: TLRationalManagerPortParameters) +case class TLRationalEdgeParameters(client: TLRationalClientPortParameters, manager: TLRationalManagerPortParameters, params: Parameters) { val bundle = TLBundleParameters(client.base, manager.base) } diff --git a/src/main/scala/tilelink/PatternPusher.scala b/src/main/scala/tilelink/PatternPusher.scala index b384f133..cb9d384e 100644 --- a/src/main/scala/tilelink/PatternPusher.scala +++ b/src/main/scala/tilelink/PatternPusher.scala @@ -38,13 +38,12 @@ class TLPatternPusher(name: String, pattern: Seq[Pattern])(implicit p: Parameter val node = TLClientNode(Seq(TLClientPortParameters(Seq(TLClientParameters(name = name))))) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val tl_out = node.bundleOut + val io = IO(new Bundle { val run = Bool(INPUT) val done = Bool(OUTPUT) - } + }) - val edgeOut = node.edgesOut(0) + val (tl_out, edgeOut) = node.out(0) pattern.foreach { p => require (p.size <= log2Ceil(edgeOut.manager.beatBytes), "Patterns must fit in a single beat") } @@ -56,8 +55,8 @@ class TLPatternPusher(name: String, pattern: Seq[Pattern])(implicit p: Parameter val end = step === UInt(pattern.size) io.done := end && !flight - val a = io.tl_out(0).a - val d = io.tl_out(0).d + val a = tl_out.a + val d = tl_out.d // Expected response? val check = Vec(pattern.map(p => Bool(p.dataIn.isDefined)))(step) holdUnless a.fire() @@ -80,8 +79,8 @@ class TLPatternPusher(name: String, pattern: Seq[Pattern])(implicit p: Parameter d.ready := Bool(true) // Tie off unused channels - io.tl_out(0).b.ready := Bool(true) - io.tl_out(0).c.valid := Bool(false) - io.tl_out(0).e.valid := Bool(false) + tl_out.b.ready := Bool(true) + tl_out.c.valid := Bool(false) + tl_out.e.valid := Bool(false) } } diff --git a/src/main/scala/tilelink/RAMModel.scala b/src/main/scala/tilelink/RAMModel.scala index 0d74e8e0..c121c002 100644 --- a/src/main/scala/tilelink/RAMModel.scala +++ b/src/main/scala/tilelink/RAMModel.scala @@ -24,15 +24,10 @@ import freechips.rocketchip.util._ class TLRAMModel(log: String = "")(implicit p: Parameters) extends LazyModule { - val node = TLIdentityNode() + val node = TLAdapterNode() lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - val out = node.bundleOut - } - - ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => + (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => val edge = edgeIn val endAddress = edge.manager.maxAddress + 1 val endSourceId = edge.client.endSourceId diff --git a/src/main/scala/tilelink/RationalCrossing.scala b/src/main/scala/tilelink/RationalCrossing.scala index 5283b30d..f84a7355 100644 --- a/src/main/scala/tilelink/RationalCrossing.scala +++ b/src/main/scala/tilelink/RationalCrossing.scala @@ -20,12 +20,7 @@ class TLRationalCrossingSource(implicit p: Parameters) extends LazyModule val node = TLRationalSourceNode() lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - val out = node.bundleOut - } - - ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => + (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => val bce = edgeIn.manager.anySupportAcquireB && edgeIn.client.anySupportProbe val direction = edgeOut.manager.direction @@ -56,12 +51,7 @@ class TLRationalCrossingSink(direction: RationalDirection = Symmetric)(implicit val node = TLRationalSinkNode(direction) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - val out = node.bundleOut - } - - ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => + (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => val bce = edgeOut.manager.anySupportAcquireB && edgeOut.client.anySupportProbe val direction = edgeIn.manager.direction @@ -109,8 +99,8 @@ object TLRationalCrossingSink class TLRationalCrossing(direction: RationalDirection = Symmetric)(implicit p: Parameters) extends LazyModule { - val nodeIn = TLInputNode() - val nodeOut = TLOutputNode() + val nodeIn = TLIdentityNode() + val nodeOut = TLIdentityNode() val node = NodeHandle(nodeIn, nodeOut) val source = LazyModule(new TLRationalCrossingSource) @@ -121,14 +111,12 @@ class TLRationalCrossing(direction: RationalDirection = Symmetric)(implicit p: P val out = (nodeOut := sink.node) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = nodeIn.bundleIn + val io = IO(new Bundle { val in_clock = Clock(INPUT) val in_reset = Bool(INPUT) - val out = nodeOut.bundleOut val out_clock = Clock(INPUT) val out_reset = Bool(INPUT) - } + }) source.module.clock := io.in_clock source.module.reset := io.in_reset @@ -150,7 +138,7 @@ class TLRationalCrossing(direction: RationalDirection = Symmetric)(implicit p: P import freechips.rocketchip.unittest._ class TLRAMRationalCrossingSource(name: String, txns: Int)(implicit p: Parameters) extends LazyModule { - val node = TLRationalOutputNode() + val node = TLRationalIdentityNode() val fuzz = LazyModule(new TLFuzzer(txns)) val model = LazyModule(new TLRAMModel(name)) @@ -158,25 +146,20 @@ class TLRAMRationalCrossingSource(name: String, txns: Int)(implicit p: Parameter node := TLRationalCrossingSource()(TLDelayer(0.25)(model.node)) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { + val io = IO(new Bundle { val finished = Bool(OUTPUT) - val out = node.bundleOut - } + }) io.finished := fuzz.module.io.finished } } class TLRAMRationalCrossingSink(direction: RationalDirection)(implicit p: Parameters) extends LazyModule { - val node = TLRationalInputNode() + val node = TLRationalIdentityNode() val ram = LazyModule(new TLRAM(AddressSet(0x0, 0x3ff))) ram.node := TLFragmenter(4, 256)(TLDelayer(0.25)(TLRationalCrossingSink(direction)(node))) - lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - } - } + lazy val module = new LazyModuleImp(this) { } } class TLRAMRationalCrossing(txns: Int)(implicit p: Parameters) extends LazyModule { @@ -196,7 +179,7 @@ class TLRAMRationalCrossing(txns: Int)(implicit p: Parameters) extends LazyModul val fix_fast_sink = LazyModule(new TLRAMRationalCrossingSink(SlowToFast)) fix_fast_sink.node := fix_slow_source.node - lazy val module = new LazyModuleImp(this) with HasUnitTestIO { + lazy val module = new LazyModuleImp(this) with UnitTestModule { io.finished := sym_fast_source.module.io.finished && sym_slow_source.module.io.finished && diff --git a/src/main/scala/tilelink/RegisterRouter.scala b/src/main/scala/tilelink/RegisterRouter.scala index 5ecd5398..403f8da7 100644 --- a/src/main/scala/tilelink/RegisterRouter.scala +++ b/src/main/scala/tilelink/RegisterRouter.scala @@ -40,9 +40,9 @@ case class TLRegisterNode( // Calling this method causes the matching TL2 bundle to be // configured to route all requests to the listed RegFields. def regmap(mapping: RegField.Map*) = { - val a = bundleIn(0).a - val d = bundleIn(0).d - val edge = edgesIn(0) + val (bundleIn, edge) = this.in(0) + val a = bundleIn.a + val d = bundleIn.d // Please forgive me ... val baseEnd = 0 @@ -76,9 +76,9 @@ case class TLRegisterNode( d.bits.opcode := Mux(out.bits.read, TLMessages.AccessAckData, TLMessages.AccessAck) // Tie off unused channels - bundleIn(0).b.valid := Bool(false) - bundleIn(0).c.ready := Bool(true) - bundleIn(0).e.ready := Bool(true) + bundleIn.b.valid := Bool(false) + bundleIn.c.ready := Bool(true) + bundleIn.e.ready := Bool(true) } } @@ -92,13 +92,11 @@ abstract class TLRegisterRouterBase(devname: String, devcompat: Seq[String], val val intnode = IntSourceNode(IntSourcePortSimple(num = interrupts, resources = Seq(Resource(device, "int")))) } -case class TLRegBundleArg(interrupts: HeterogeneousBag[Vec[Bool]], in: HeterogeneousBag[TLBundle])(implicit val p: Parameters) +case class TLRegBundleArg()(implicit val p: Parameters) class TLRegBundleBase(arg: TLRegBundleArg) extends Bundle { implicit val p = arg.p - val interrupts = arg.interrupts - val in = arg.in } class TLRegBundle[P](val params: P, arg: TLRegBundleArg)(implicit p: Parameters) extends TLRegBundleBase(arg) @@ -106,8 +104,8 @@ class TLRegBundle[P](val params: P, arg: TLRegBundleArg)(implicit p: Parameters) class TLRegModule[P, B <: TLRegBundleBase](val params: P, bundleBuilder: => B, router: TLRegisterRouterBase) extends LazyModuleImp(router) with HasRegMap { - val io = bundleBuilder - val interrupts = if (io.interrupts.isEmpty) Vec(0, Bool()) else io.interrupts(0) + val io = IO(bundleBuilder) + val interrupts = if (router.intnode.in.isEmpty) Vec(0, Bool()) else router.intnode.in(0)._1 val address = router.address def regmap(mapping: RegField.Map*) = router.node.regmap(mapping:_*) } @@ -129,5 +127,5 @@ class TLRegisterRouter[B <: TLRegBundleBase, M <: LazyModuleImp]( require (isPow2(size)) // require (size >= 4096) ... not absolutely required, but highly recommended - lazy val module = moduleBuilder(bundleBuilder(TLRegBundleArg(intnode.bundleOut, node.bundleIn)), this) + lazy val module = moduleBuilder(bundleBuilder(TLRegBundleArg()), this) } diff --git a/src/main/scala/tilelink/RegisterRouterTest.scala b/src/main/scala/tilelink/RegisterRouterTest.scala index ef70cf73..a43e00f1 100644 --- a/src/main/scala/tilelink/RegisterRouterTest.scala +++ b/src/main/scala/tilelink/RegisterRouterTest.scala @@ -3,6 +3,7 @@ package freechips.rocketchip.tilelink import Chisel._ +import chisel3.experimental.MultiIOModule import freechips.rocketchip.config.Parameters import freechips.rocketchip.diplomacy._ import freechips.rocketchip.regmapper._ @@ -222,7 +223,7 @@ trait RRTest1Bundle { } -trait RRTest1Module extends Module with HasRegMap +trait RRTest1Module extends MultiIOModule with HasRegMap { val clocks = Module(new Pow2ClockDivider(2)) @@ -261,7 +262,7 @@ class FuzzRRTest0(txns: Int)(implicit p: Parameters) extends LazyModule { rrtr.node := TLFragmenter(4, 32)(TLDelayer(0.1)(fuzz.node)) - lazy val module = new LazyModuleImp(this) with HasUnitTestIO { + lazy val module = new LazyModuleImp(this) with UnitTestModule { io.finished := fuzz.module.io.finished } } @@ -276,7 +277,7 @@ class FuzzRRTest1(txns: Int)(implicit p: Parameters) extends LazyModule { rrtr.node := TLFragmenter(4, 32)(TLDelayer(0.1)(fuzz.node)) - lazy val module = new LazyModuleImp(this) with HasUnitTestIO { + lazy val module = new LazyModuleImp(this) with UnitTestModule { io.finished := fuzz.module.io.finished } } diff --git a/src/main/scala/tilelink/SRAM.scala b/src/main/scala/tilelink/SRAM.scala index 84a0a86c..a3845c9a 100644 --- a/src/main/scala/tilelink/SRAM.scala +++ b/src/main/scala/tilelink/SRAM.scala @@ -29,18 +29,12 @@ class TLRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4, // We require the address range to include an entire beat (for the write mask) require ((address.mask & (beatBytes-1)) == beatBytes-1) - lazy val module = new Implementation - @chiselName class Implementation extends LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - } - + lazy val module = new LazyModuleImp(this) { def bigBits(x: BigInt, tail: List[Boolean] = List.empty[Boolean]): List[Boolean] = if (x == 0) tail.reverse else bigBits(x >> 1, ((x & 1) == 1) :: tail) val mask = bigBits(address.mask >> log2Ceil(beatBytes)) - val in = io.in(0) - val edge = node.edgesIn(0) + val (in, edge) = node.in(0) val addrBits = (mask zip edge.addr_hi(in.a.bits).toBools).filter(_._1).map(_._2) val a_legal = address.contains(in.a.bits.address) @@ -101,7 +95,7 @@ class TLRAMSimple(ramBeatBytes: Int, txns: Int)(implicit p: Parameters) extends model.node := fuzz.node ram.node := TLDelayer(0.25)(model.node) - lazy val module = new LazyModuleImp(this) with HasUnitTestIO { + lazy val module = new LazyModuleImp(this) with UnitTestModule { io.finished := fuzz.module.io.finished } } diff --git a/src/main/scala/tilelink/SourceShrinker.scala b/src/main/scala/tilelink/SourceShrinker.scala index 5f7aa3d8..fee37b33 100644 --- a/src/main/scala/tilelink/SourceShrinker.scala +++ b/src/main/scala/tilelink/SourceShrinker.scala @@ -23,12 +23,7 @@ class TLSourceShrinker(maxInFlight: Int)(implicit p: Parameters) extends LazyMod managerFn = { mp => mp.copy(managers = mp.managers.map(_.copy(fifoId = None))) }) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - val out = node.bundleOut - } - - ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => + (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => // Acquires cannot pass this adapter; it makes Probes impossible require (!edgeIn.client.anySupportProbe || !edgeOut.manager.anySupportAcquireB) diff --git a/src/main/scala/tilelink/Splitter.scala b/src/main/scala/tilelink/Splitter.scala index 39207ddc..f5da7e6c 100644 --- a/src/main/scala/tilelink/Splitter.scala +++ b/src/main/scala/tilelink/Splitter.scala @@ -15,9 +15,6 @@ case class TLSplitterNode( implicit valName: ValName) extends TLCustomNode(numClientPorts, numManagerPorts) { - val externalIn = true - val externalOut = true - 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 (iStars == 0, s"${name} (a splitter) cannot appear left of a :*=; did you mean :=*?${lazyModule.line}") @@ -65,18 +62,14 @@ class TLSplitter(policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Pa }) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - val out = node.bundleOut - } - def group[T](x: Seq[T]) = - if (x.isEmpty) Nil else x.grouped(node.edgesIn.size).toList.transpose + if (x.isEmpty) Nil else x.grouped(node.in.size).toList.transpose - if (node.edgesOut.size == node.edgesIn.size) { - io.out <> io.in - } else ((node.edgesIn zip io.in) zip (group(node.edgesOut) zip group(io.out))) foreach { - case ((edgeIn, io_in), (edgesOut, io_out)) => + if (node.out.size == node.in.size) { + (node.in zip node.out) foreach { case ((i, _), (o, _)) => o <> i } + } else (node.in zip group(node.out)) foreach { + case ((io_in, edgeIn), seq) => + val (io_out, edgesOut) = seq.unzip // Grab the port ID mapping val outputIdRanges = TLXbar.mapOutputIds(edgesOut.map(_.manager)) diff --git a/src/main/scala/tilelink/ToAHB.scala b/src/main/scala/tilelink/ToAHB.scala index bf61964d..955d9afb 100644 --- a/src/main/scala/tilelink/ToAHB.scala +++ b/src/main/scala/tilelink/ToAHB.scala @@ -53,12 +53,7 @@ class TLToAHB(val aFlow: Boolean = false)(implicit p: Parameters) extends LazyMo val node = TLToAHBNode() lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - val out = node.bundleOut - } - - ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => + (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => val beatBytes = edgeOut.slave.beatBytes val maxTransfer = edgeOut.slave.maxTransfer val lgMax = log2Ceil(maxTransfer) diff --git a/src/main/scala/tilelink/ToAPB.scala b/src/main/scala/tilelink/ToAPB.scala index e6ed742a..d3835072 100644 --- a/src/main/scala/tilelink/ToAPB.scala +++ b/src/main/scala/tilelink/ToAPB.scala @@ -38,12 +38,7 @@ class TLToAPB(val aFlow: Boolean = true)(implicit p: Parameters) extends LazyMod val node = TLToAPBNode() lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - val out = node.bundleOut - } - - ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => + (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => val beatBytes = edgeOut.slave.beatBytes val lgBytes = log2Ceil(beatBytes) diff --git a/src/main/scala/tilelink/ToAXI4.scala b/src/main/scala/tilelink/ToAXI4.scala index 21385abb..fdf9c4d5 100644 --- a/src/main/scala/tilelink/ToAXI4.scala +++ b/src/main/scala/tilelink/ToAXI4.scala @@ -53,12 +53,7 @@ class TLToAXI4(val beatBytes: Int, val combinational: Boolean = true, val adapte val node = TLToAXI4Node(beatBytes, stripBits) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - val out = node.bundleOut - } - - ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => + (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => val slaves = edgeOut.slave.slaves // All pairs of slaves must promise that they will never interleave data diff --git a/src/main/scala/tilelink/WidthWidget.scala b/src/main/scala/tilelink/WidthWidget.scala index 6bc5e37c..3c6feee3 100644 --- a/src/main/scala/tilelink/WidthWidget.scala +++ b/src/main/scala/tilelink/WidthWidget.scala @@ -17,11 +17,6 @@ class TLWidthWidget(innerBeatBytes: Int)(implicit p: Parameters) extends LazyMod managerFn = { case m => m.copy(beatBytes = innerBeatBytes) }) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - val out = node.bundleOut - } - def merge[T <: TLDataChannel](edgeIn: TLEdge, in: DecoupledIO[T], edgeOut: TLEdge, out: DecoupledIO[T]) = { val inBytes = edgeIn.manager.beatBytes val outBytes = edgeOut.manager.beatBytes @@ -154,7 +149,7 @@ class TLWidthWidget(innerBeatBytes: Int)(implicit p: Parameters) extends LazyMod } } - ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => + (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => // If the master is narrower than the slave, the D channel must be narrowed. // This is tricky, because the D channel has no address data. @@ -220,7 +215,7 @@ class TLRAMWidthWidget(first: Int, second: Int, txns: Int)(implicit p: Parameter TLWidthWidget(second)( TLWidthWidget(first)(TLDelayer(0.1)(model.node)))})) - lazy val module = new LazyModuleImp(this) with HasUnitTestIO { + lazy val module = new LazyModuleImp(this) with UnitTestModule { io.finished := fuzz.module.io.finished } } diff --git a/src/main/scala/tilelink/Xbar.scala b/src/main/scala/tilelink/Xbar.scala index 26c91801..4a800231 100644 --- a/src/main/scala/tilelink/Xbar.scala +++ b/src/main/scala/tilelink/Xbar.scala @@ -63,22 +63,21 @@ class TLXbar(policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Parame }) lazy val module = new LazyModuleImp(this) { - val io = new Bundle { - val in = node.bundleIn - val out = node.bundleOut + if ((node.in.size * node.out.size) > (8*32)) { + println (s"!!! WARNING !!!") + println (s" Your TLXbar ($name) is very large, with ${node.in.size} Masters and ${node.out.size} Slaves.") + println (s"!!! WARNING !!!") } - if ((io.in.size * io.out.size) > (8*32)) { - println (s"!!! WARNING !!!") - println (s" Your TLXbar ($name) is very large, with ${io.in.size} Masters and ${io.out.size} Slaves.") - println (s"!!! WARNING !!!") - } + val (io_in, edgesIn) = node.in.unzip + val (io_out, edgesOut) = node.out.unzip + // Grab the port ID mapping - val inputIdRanges = TLXbar.mapInputIds(node.edgesIn.map(_.client)) - val outputIdRanges = TLXbar.mapOutputIds(node.edgesOut.map(_.manager)) + val inputIdRanges = TLXbar.mapInputIds(edgesIn.map(_.client)) + val outputIdRanges = TLXbar.mapOutputIds(edgesOut.map(_.manager)) // Find a good mask for address decoding - val port_addrs = node.edgesOut.map(_.manager.managers.map(_.address).flatten) + val port_addrs = edgesOut.map(_.manager.managers.map(_.address).flatten) val routingMask = AddressDecoder(port_addrs) val route_addrs = port_addrs.map(seq => AddressSet.unify(seq.map(_.widen(~routingMask)).distinct)) val outputPorts = route_addrs.map(seq => (addr: UInt) => seq.map(_.contains(addr)).reduce(_ || _)) @@ -97,70 +96,70 @@ class TLXbar(policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Parame // Print the ID mapping if (false) { println(s"XBar ${name} mapping:") - (node.edgesIn zip inputIdRanges).zipWithIndex.foreach { case ((edge, id), i) => + (edgesIn zip inputIdRanges).zipWithIndex.foreach { case ((edge, id), i) => println(s"\t$i assigned ${id} for ${edge.client.clients.map(_.name).mkString(", ")}") } println("") } // We need an intermediate size of bundle with the widest possible identifiers - val wide_bundle = TLBundleParameters.union(io.in.map(_.params) ++ io.out.map(_.params)) + val wide_bundle = TLBundleParameters.union(io_in.map(_.params) ++ io_out.map(_.params)) // Handle size = 1 gracefully (Chisel3 empty range is broken) def trim(id: UInt, size: Int) = if (size <= 1) UInt(0) else id(log2Ceil(size)-1, 0) // Transform input bundle sources (sinks use global namespace on both sides) - val in = Wire(Vec(io.in.size, TLBundle(wide_bundle))) + val in = Wire(Vec(io_in.size, TLBundle(wide_bundle))) for (i <- 0 until in.size) { val r = inputIdRanges(i) - in(i).a <> io.in(i).a - io.in(i).d <> in(i).d - in(i).a.bits.source := io.in(i).a.bits.source | UInt(r.start) - io.in(i).d.bits.source := trim(in(i).d.bits.source, r.size) + in(i).a <> io_in(i).a + io_in(i).d <> in(i).d + in(i).a.bits.source := io_in(i).a.bits.source | UInt(r.start) + io_in(i).d.bits.source := trim(in(i).d.bits.source, r.size) - if (node.edgesIn(i).client.anySupportProbe && node.edgesOut.exists(_.manager.anySupportAcquireB)) { - in(i).c <> io.in(i).c - in(i).e <> io.in(i).e - io.in(i).b <> in(i).b - in(i).c.bits.source := io.in(i).c.bits.source | UInt(r.start) - io.in(i).b.bits.source := trim(in(i).b.bits.source, r.size) + if (edgesIn(i).client.anySupportProbe && edgesOut.exists(_.manager.anySupportAcquireB)) { + in(i).c <> io_in(i).c + in(i).e <> io_in(i).e + io_in(i).b <> in(i).b + in(i).c.bits.source := io_in(i).c.bits.source | UInt(r.start) + io_in(i).b.bits.source := trim(in(i).b.bits.source, r.size) } else { in(i).c.valid := Bool(false) in(i).e.valid := Bool(false) in(i).b.ready := Bool(false) - io.in(i).c.ready := Bool(true) - io.in(i).e.ready := Bool(true) - io.in(i).b.valid := Bool(false) + io_in(i).c.ready := Bool(true) + io_in(i).e.ready := Bool(true) + io_in(i).b.valid := Bool(false) } } // Transform output bundle sinks (sources use global namespace on both sides) - val out = Wire(Vec(io.out.size, TLBundle(wide_bundle))) + val out = Wire(Vec(io_out.size, TLBundle(wide_bundle))) for (i <- 0 until out.size) { val r = outputIdRanges(i) - io.out(i).a <> out(i).a - out(i).d <> io.out(i).d - out(i).d.bits.sink := io.out(i).d.bits.sink | UInt(r.map(_.start).getOrElse(0)) + io_out(i).a <> out(i).a + out(i).d <> io_out(i).d + out(i).d.bits.sink := io_out(i).d.bits.sink | UInt(r.map(_.start).getOrElse(0)) - if (node.edgesOut(i).manager.anySupportAcquireB && node.edgesIn.exists(_.client.anySupportProbe)) { - io.out(i).c <> out(i).c - io.out(i).e <> out(i).e - out(i).b <> io.out(i).b - io.out(i).e.bits.sink := trim(out(i).e.bits.sink, r.map(_.size).getOrElse(0)) + if (edgesOut(i).manager.anySupportAcquireB && edgesIn.exists(_.client.anySupportProbe)) { + io_out(i).c <> out(i).c + io_out(i).e <> out(i).e + out(i).b <> io_out(i).b + io_out(i).e.bits.sink := trim(out(i).e.bits.sink, r.map(_.size).getOrElse(0)) } else { out(i).c.ready := Bool(false) out(i).e.ready := Bool(false) out(i).b.valid := Bool(false) - io.out(i).c.valid := Bool(false) - io.out(i).e.valid := Bool(false) - io.out(i).b.ready := Bool(true) + io_out(i).c.valid := Bool(false) + io_out(i).e.valid := Bool(false) + io_out(i).b.ready := Bool(true) } } - val addressA = (in zip node.edgesIn) map { case (i, e) => e.address(i.a.bits) } - val addressC = (in zip node.edgesIn) map { case (i, e) => e.address(i.c.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 requestAIO = Vec(addressA.map { i => Vec(outputPorts.map { o => o(i) }) }) val requestCIO = Vec(addressC.map { i => Vec(outputPorts.map { o => o(i) }) }) @@ -168,28 +167,28 @@ class TLXbar(policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Parame val requestDOI = Vec(out.map { o => Vec(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 beatsAI = Vec((in zip node.edgesIn) map { case (i, e) => e.numBeats1(i.a.bits) }) - val beatsBO = Vec((out zip node.edgesOut) map { case (o, e) => e.numBeats1(o.b.bits) }) - val beatsCI = Vec((in zip node.edgesIn) map { case (i, e) => e.numBeats1(i.c.bits) }) - val beatsDO = Vec((out zip node.edgesOut) map { case (o, e) => e.numBeats1(o.d.bits) }) - val beatsEI = Vec((in zip node.edgesIn) map { case (i, e) => e.numBeats1(i.e.bits) }) + val beatsAI = Vec((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 beatsCI = Vec((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 beatsEI = Vec((in zip edgesIn) map { case (i, e) => e.numBeats1(i.e.bits) }) // 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 filter[T](data: Seq[T], mask: Seq[Boolean]) = (data zip mask).filter(_._2).map(_._1) // Fanout the input sources to the output sinks - val portsAOI = transpose((in zip requestAIO) map { case (i, r) => TLXbar.fanout(i.a, r, node.paramsOut.map(_(ForceFanoutKey).a)) }) - val portsBIO = transpose((out zip requestBOI) map { case (o, r) => TLXbar.fanout(o.b, r, node.paramsIn .map(_(ForceFanoutKey).b)) }) - val portsCOI = transpose((in zip requestCIO) map { case (i, r) => TLXbar.fanout(i.c, r, node.paramsOut.map(_(ForceFanoutKey).c)) }) - val portsDIO = transpose((out zip requestDOI) map { case (o, r) => TLXbar.fanout(o.d, r, node.paramsIn .map(_(ForceFanoutKey).d)) }) - val portsEOI = transpose((in zip requestEIO) map { case (i, r) => TLXbar.fanout(i.e, r, node.paramsOut.map(_(ForceFanoutKey).e)) }) + val portsAOI = transpose((in zip requestAIO) map { case (i, r) => TLXbar.fanout(i.a, r, edgesOut.map(_.params(ForceFanoutKey).a)) }) + val portsBIO = transpose((out zip requestBOI) map { case (o, r) => TLXbar.fanout(o.b, r, edgesIn .map(_.params(ForceFanoutKey).b)) }) + val portsCOI = transpose((in zip requestCIO) map { case (i, r) => TLXbar.fanout(i.c, r, edgesOut.map(_.params(ForceFanoutKey).c)) }) + val portsDIO = transpose((out zip requestDOI) map { case (o, r) => TLXbar.fanout(o.d, r, edgesIn .map(_.params(ForceFanoutKey).d)) }) + val portsEOI = transpose((in zip requestEIO) map { case (i, r) => TLXbar.fanout(i.e, r, edgesOut.map(_.params(ForceFanoutKey).e)) }) // Arbitrate amongst the sources for (o <- 0 until out.size) { val allowI = Seq.tabulate(in.size) { i => - node.edgesIn(i).client.anySupportProbe && - node.edgesOut(o).manager.anySupportAcquireB + edgesIn(i).client.anySupportProbe && + edgesOut(o).manager.anySupportAcquireB } TLArbiter(policy)(out(o).a, (beatsAI zip portsAOI(o) ):_*) TLArbiter(policy)(out(o).c, filter(beatsCI zip portsCOI(o), allowI):_*) @@ -198,8 +197,8 @@ class TLXbar(policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Parame for (i <- 0 until in.size) { val allowO = Seq.tabulate(out.size) { o => - node.edgesIn(i).client.anySupportProbe && - node.edgesOut(o).manager.anySupportAcquireB + edgesIn(i).client.anySupportProbe && + edgesOut(o).manager.anySupportAcquireB } TLArbiter(policy)(in(i).b, filter(beatsBO zip portsBIO(i), allowO):_*) TLArbiter(policy)(in(i).d, (beatsDO zip portsDIO(i) ):_*) @@ -264,7 +263,7 @@ class TLRAMXbar(nManagers: Int, txns: Int)(implicit p: Parameters) extends LazyM ram.node := TLFragmenter(4, 256)(TLDelayer(0.1)(xbar.node)) } - lazy val module = new LazyModuleImp(this) with HasUnitTestIO { + lazy val module = new LazyModuleImp(this) with UnitTestModule { io.finished := fuzz.module.io.finished } } @@ -287,7 +286,7 @@ class TLMulticlientXbar(nManagers: Int, nClients: Int, txns: Int)(implicit p: Pa ram.node := TLFragmenter(4, 256)(TLDelayer(0.1)(xbar.node)) } - lazy val module = new LazyModuleImp(this) with HasUnitTestIO { + lazy val module = new LazyModuleImp(this) with UnitTestModule { io.finished := fuzzers.last.module.io.finished } } diff --git a/src/main/scala/unittest/UnitTest.scala b/src/main/scala/unittest/UnitTest.scala index a0b34a87..08e7b6b4 100644 --- a/src/main/scala/unittest/UnitTest.scala +++ b/src/main/scala/unittest/UnitTest.scala @@ -3,17 +3,28 @@ package freechips.rocketchip.unittest import Chisel._ +import chisel3.experimental.MultiIOModule import freechips.rocketchip.config._ import freechips.rocketchip.util.SimpleTimer -trait HasUnitTestIO { - val io = new Bundle { - val finished = Bool(OUTPUT) - val start = Bool(INPUT) - } +trait UnitTestIO { + val finished = Bool(OUTPUT) + val start = Bool(INPUT) } -abstract class UnitTest(val timeout: Int = 4096) extends Module with HasUnitTestIO { +trait HasUnitTestIO { + val io: UnitTestIO +} + +trait UnitTestLegacyModule extends HasUnitTestIO { + val io = new Bundle with UnitTestIO +} + +trait UnitTestModule extends MultiIOModule with HasUnitTestIO { + val io = IO(new Bundle with UnitTestIO) +} + +abstract class UnitTest(val timeout: Int = 4096) extends Module with UnitTestLegacyModule { val testName = this.getClass.getSimpleName when (io.start) { printf(s"Started UnitTest $testName\n") } From b9a2e4c243bd487aff1161c6465c9e7b0e405949 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 15 Sep 2017 14:44:07 -0700 Subject: [PATCH 10/32] diplomacy: API beautification --- src/main/scala/coreplex/Ports.scala | 12 ++++++------ src/main/scala/coreplex/SystemBus.scala | 2 +- src/main/scala/devices/debug/Debug.scala | 6 +++--- src/main/scala/devices/tilelink/BusBlocker.scala | 2 +- src/main/scala/devices/tilelink/Clint.scala | 3 ++- src/main/scala/devices/tilelink/Plic.scala | 6 +++--- src/main/scala/diplomacy/Nodes.scala | 4 +++- src/main/scala/rocket/Frontend.scala | 2 +- src/main/scala/rocket/HellaCache.scala | 4 ++-- src/main/scala/rocket/ICache.scala | 2 ++ src/main/scala/rocket/PTW.scala | 2 +- src/main/scala/rocket/ScratchpadSlavePort.scala | 2 +- src/main/scala/tile/Interrupts.scala | 3 ++- src/main/scala/tile/RocketTile.scala | 4 ++-- src/main/scala/tilelink/NodeNumberer.scala | 2 +- src/main/scala/tilelink/RegisterRouter.scala | 2 ++ src/main/scala/util/HeterogeneousBag.scala | 5 +++++ 17 files changed, 38 insertions(+), 25 deletions(-) diff --git a/src/main/scala/coreplex/Ports.scala b/src/main/scala/coreplex/Ports.scala index 4eb975ab..a526561c 100644 --- a/src/main/scala/coreplex/Ports.scala +++ b/src/main/scala/coreplex/Ports.scala @@ -79,7 +79,7 @@ trait HasMasterAXI4MemPortBundle { /** Actually generates the corresponding IO in the concrete Module */ trait HasMasterAXI4MemPortModuleImp extends LazyModuleImp with HasMasterAXI4MemPortBundle { val outer: HasMasterAXI4MemPort - val mem_axi4 = IO(HeterogeneousBag(outer.mem_axi4.in.map(_._1.cloneType))) + val mem_axi4 = IO(HeterogeneousBag.fromNode(outer.mem_axi4.in)) (mem_axi4 zip outer.mem_axi4.in) foreach { case (i, (o, _)) => i <> o } val nMemoryChannels = outer.nMemoryChannels } @@ -119,7 +119,7 @@ trait HasMasterAXI4MMIOPortBundle { /** Actually generates the corresponding IO in the concrete Module */ trait HasMasterAXI4MMIOPortModuleImp extends LazyModuleImp with HasMasterAXI4MMIOPortBundle { val outer: HasMasterAXI4MMIOPort - val mmio_axi4 = IO(HeterogeneousBag(outer.mmio_axi4.in.map(_._1.cloneType))) + val mmio_axi4 = IO(HeterogeneousBag.fromNode(outer.mmio_axi4.in)) (mmio_axi4 zip outer.mmio_axi4.in) foreach { case (i, (o, _)) => i <> o } } @@ -159,7 +159,7 @@ trait HasSlaveAXI4PortBundle { /** Actually generates the corresponding IO in the concrete Module */ trait HasSlaveAXI4PortModuleImp extends LazyModuleImp with HasSlaveAXI4PortBundle { val outer: HasSlaveAXI4Port - val l2_frontend_bus_axi4 = IO(HeterogeneousBag(outer.l2FrontendAXI4Node.out.map(_._1.cloneType)).flip) + val l2_frontend_bus_axi4 = IO(HeterogeneousBag.fromNode(outer.l2FrontendAXI4Node.out).flip) (outer.l2FrontendAXI4Node.out zip l2_frontend_bus_axi4) foreach { case ((i, _), o) => i <> o } } @@ -201,7 +201,7 @@ trait HasMasterTLMMIOPortBundle { /** Actually generates the corresponding IO in the concrete Module */ trait HasMasterTLMMIOPortModuleImp extends LazyModuleImp with HasMasterTLMMIOPortBundle { val outer: HasMasterTLMMIOPort - val mmio_tl = IO(HeterogeneousBag(outer.mmio_tl.in.map(_._1.cloneType))) + val mmio_tl = IO(HeterogeneousBag.fromNode(outer.mmio_tl.in)) (mmio_tl zip outer.mmio_tl.out) foreach { case (i, (o, _)) => i <> o } } @@ -239,7 +239,7 @@ trait HasSlaveTLPortBundle { /** Actually generates the corresponding IO in the concrete Module */ trait HasSlaveTLPortModuleImp extends LazyModuleImp with HasSlaveTLPortBundle { val outer: HasSlaveTLPort - val l2_frontend_bus_tl = IO(HeterogeneousBag(outer.l2FrontendTLNode.out.map(_._1.cloneType)).flip) + val l2_frontend_bus_tl = IO(HeterogeneousBag.fromNode(outer.l2FrontendTLNode.out).flip) (outer.l2FrontendTLNode.in zip l2_frontend_bus_tl) foreach { case ((i, _), o) => i <> o } } @@ -264,7 +264,7 @@ class SimAXIMem(channels: Int, forceSize: BigInt = 0)(implicit p: Parameters) ex lazy val module = new LazyModuleImp(this) { val io = IO(new Bundle { - val axi4 = HeterogeneousBag(node.out.map(_._1.cloneType)).flip + val axi4 = HeterogeneousBag.fromNode(node.out).flip }) (node.out zip io.axi4) foreach { case ((i, _), o) => i <> o } } diff --git a/src/main/scala/coreplex/SystemBus.scala b/src/main/scala/coreplex/SystemBus.scala index 98f0c5ba..384da306 100644 --- a/src/main/scala/coreplex/SystemBus.scala +++ b/src/main/scala/coreplex/SystemBus.scala @@ -22,7 +22,7 @@ class SystemBus(params: SystemBusParams)(implicit p: Parameters) extends TLBusWr private val master_splitter = LazyModule(new TLSplitter) // Allows cycle-free connection to external networks master_splitter.suggestName(s"${busName}_master_TLSplitter") inwardNode :=* master_splitter.node - def busView = master_splitter.node.in.head._2 + def busView = master_splitter.node.edges.in.head protected def inwardSplitNode: TLInwardNode = master_splitter.node protected def outwardSplitNode: TLOutwardNode = master_splitter.node diff --git a/src/main/scala/devices/debug/Debug.scala b/src/main/scala/devices/debug/Debug.scala index 8d26d50b..60577171 100644 --- a/src/main/scala/devices/debug/Debug.scala +++ b/src/main/scala/devices/debug/Debug.scala @@ -353,8 +353,9 @@ class TLDebugModuleOuter(device: Device)(implicit p: Parameters) extends LazyMod debugIntNxt := debugIntRegs + val (intnode_out, _) = intnode.out.unzip for (component <- 0 until nComponents) { - intnode.out(component)._1(0) := debugIntRegs(component) + intnode_out(component)(0) := debugIntRegs(component) } // Halt request registers are set & cleared by writes to DMCONTROL.haltreq @@ -1015,7 +1016,6 @@ class TLDebugModuleInnerAsync(device: Device, getNComponents: () => Int)(implici lazy val module = new LazyModuleImp(this) { val io = IO(new Bundle { - // this comes from tlClk domain. // These are all asynchronous and come from Outer val dmactive = Bool(INPUT) val innerCtrl = new AsyncBundle(1, new DebugInternalBundle()).flip @@ -1045,7 +1045,7 @@ class TLDebugModule(implicit p: Parameters) extends LazyModule { val intnode = IntIdentityNode() val dmOuter = LazyModule(new TLDebugModuleOuterAsync(device)(p)) - val dmInner = LazyModule(new TLDebugModuleInnerAsync(device, () => {intnode.edges._2.size})(p)) + val dmInner = LazyModule(new TLDebugModuleInnerAsync(device, () => {intnode.edges.out.size})(p)) dmInner.dmiNode := dmOuter.dmiInnerNode dmInner.tlNode := node diff --git a/src/main/scala/devices/tilelink/BusBlocker.scala b/src/main/scala/devices/tilelink/BusBlocker.scala index 7d5f476f..b057ab8d 100644 --- a/src/main/scala/devices/tilelink/BusBlocker.scala +++ b/src/main/scala/devices/tilelink/BusBlocker.scala @@ -82,7 +82,7 @@ class BusBlocker(params: BusBlockerParams)(implicit p: Parameters) extends TLBus lazy val module = new LazyModuleImp(this) { // We need to be able to represent +1 larger than the largest populated address - val addressBits = log2Ceil(nodeOut.out(0)._2.manager.maxAddress+1+1) + val addressBits = log2Ceil(nodeOut.edges.out(0).manager.maxAddress+1+1) val pmps = RegInit(Vec.fill(params.pmpRegisters) { DevicePMP(addressBits, params.pageBits) }) val blocks = pmps.tail.map(_.blockPriorAddress) :+ Bool(false) controlNode.regmap(0 -> (pmps zip blocks).map { case (p, b) => p.fields(b) }.toList.flatten) diff --git a/src/main/scala/devices/tilelink/Clint.scala b/src/main/scala/devices/tilelink/Clint.scala index 1cd759a5..1419c137 100644 --- a/src/main/scala/devices/tilelink/Clint.scala +++ b/src/main/scala/devices/tilelink/Clint.scala @@ -68,7 +68,8 @@ class CoreplexLocalInterrupter(params: ClintParams)(implicit p: Parameters) exte val timecmp = Seq.fill(nTiles) { Seq.fill(timeWidth/regWidth)(Reg(UInt(width = regWidth))) } val ipi = Seq.fill(nTiles) { RegInit(UInt(0, width = 1)) } - intnode.in.map(_._1).zipWithIndex.foreach { case (int, i) => + val (intnode_in, _) = intnode.in.unzip + intnode_in.zipWithIndex.foreach { case (int, i) => int(0) := ShiftRegister(ipi(i)(0), params.intStages) // msip int(1) := ShiftRegister(time.asUInt >= timecmp(i).asUInt, params.intStages) // mtip } diff --git a/src/main/scala/devices/tilelink/Plic.scala b/src/main/scala/devices/tilelink/Plic.scala index a0ee455a..73c9d681 100644 --- a/src/main/scala/devices/tilelink/Plic.scala +++ b/src/main/scala/devices/tilelink/Plic.scala @@ -91,12 +91,12 @@ class TLPLIC(params: PLICParams)(implicit p: Parameters) extends LazyModule sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) }) /* Negotiated sizes */ - def nDevices: Int = intnode.in.map(_._2.source.num).sum + def nDevices: Int = intnode.edges.in.map(_.source.num).sum def nPriorities = min(params.maxPriorities, nDevices) - def nHarts = intnode.out.map(_._2.source.num).sum + def nHarts = intnode.edges.out.map(_.source.num).sum // Assign all the devices unique ranges - lazy val sources = intnode.in.map(_._2.source) + lazy val sources = intnode.edges.in.map(_.source) lazy val flatSources = (sources zip sources.map(_.num).scanLeft(0)(_+_).init).map { case (s, o) => s.sources.map(z => z.copy(range = z.range.offset(o))) }.flatten diff --git a/src/main/scala/diplomacy/Nodes.scala b/src/main/scala/diplomacy/Nodes.scala index c129a183..98a80b50 100644 --- a/src/main/scala/diplomacy/Nodes.scala +++ b/src/main/scala/diplomacy/Nodes.scala @@ -96,6 +96,7 @@ object BaseNode protected[diplomacy] var serial = 0 } +// !!! rename the nodes we bind? case class NodeHandle[DI, UI, BI <: Data, DO, UO, BO <: Data] (inward: InwardNode[DI, UI, BI], outward: OutwardNode[DO, UO, BO]) extends Object with InwardNodeHandle[DI, UI, BI] with OutwardNodeHandle[DO, UO, BO] @@ -177,6 +178,7 @@ trait OutwardNode[DO, UO, BO <: Data] extends BaseNode with OutwardNodeHandle[DO protected[diplomacy] val oParams: Seq[DO] } +case class Edges[EI, EO](in: EI, out: EO) sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( inner: InwardNodeImp [DI, UI, EI, BI], outer: OutwardNodeImp[DO, UO, EO, BO])( @@ -243,7 +245,7 @@ sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( protected[diplomacy] lazy val edgesIn = (iPorts zip iParams).map { case ((o, n, p), i) => inner.edgeI(n.oParams(o), i, p) } // If you need access to the edges of a foreign Node, use this method (in/out create bundles) - lazy val edges = (edgesIn, edgesOut) + lazy val edges = Edges(edgesIn, edgesOut) protected[diplomacy] lazy val bundleOut: Seq[BO] = edgesOut.map(e => Wire(outer.bundleO(e))) protected[diplomacy] lazy val bundleIn: Seq[BI] = edgesIn .map(e => Wire(inner.bundleI(e))) diff --git a/src/main/scala/rocket/Frontend.scala b/src/main/scala/rocket/Frontend.scala index 948e9676..ee224f53 100644 --- a/src/main/scala/rocket/Frontend.scala +++ b/src/main/scala/rocket/Frontend.scala @@ -75,7 +75,7 @@ class FrontendModule(outer: Frontend) extends LazyModuleImp(outer) with HasCoreParameters with HasL1ICacheParameters { val io = IO(new FrontendBundle(outer)) - implicit val edge = outer.masterNode.out(0)._2 + implicit val edge = outer.masterNode.edges.out(0) val icache = outer.icache.module require(fetchWidth*coreInstBytes == outer.icacheParams.fetchBytes) diff --git a/src/main/scala/rocket/HellaCache.scala b/src/main/scala/rocket/HellaCache.scala index 3463758c..558e0259 100644 --- a/src/main/scala/rocket/HellaCache.scala +++ b/src/main/scala/rocket/HellaCache.scala @@ -181,8 +181,8 @@ class HellaCacheBundle(outer: HellaCache)(implicit p: Parameters) extends CoreBu class HellaCacheModule(outer: HellaCache) extends LazyModuleImp(outer) with HasL1HellaCacheParameters { - implicit val edge = outer.node.out(0)._2 - val tl_out = outer.node.out(0)._1 + implicit val edge = outer.node.edges.out(0) + val (tl_out, _) = outer.node.out(0) val io = IO(new HellaCacheBundle(outer)) private val fifoManagers = edge.manager.managers.filter(TLFIFOFixer.allUncacheable) diff --git a/src/main/scala/rocket/ICache.scala b/src/main/scala/rocket/ICache.scala index cf0a6b4d..c7c2fabb 100644 --- a/src/main/scala/rocket/ICache.scala +++ b/src/main/scala/rocket/ICache.scala @@ -109,6 +109,8 @@ class ICacheModule(outer: ICache) extends LazyModuleImp(outer) val io = IO(new ICacheBundle(outer)) val (tl_out, edge_out) = outer.masterNode.out(0) + // Option.unzip does not exist :-( + // val (tl_in, edge_in) = outer.slaveNode.map(_.in(0)).unzip val tl_in = outer.slaveNode.map(_.in(0)._1) val edge_in = outer.slaveNode.map(_.in(0)._2) diff --git a/src/main/scala/rocket/PTW.scala b/src/main/scala/rocket/PTW.scala index 1cab0d93..4618715f 100644 --- a/src/main/scala/rocket/PTW.scala +++ b/src/main/scala/rocket/PTW.scala @@ -283,7 +283,7 @@ trait CanHavePTW extends HasHellaCache { trait CanHavePTWModule extends HasHellaCacheModule { val outer: CanHavePTW val ptwPorts = ListBuffer(outer.dcache.module.io.ptw) - val ptw = Module(new PTW(outer.nPTWPorts)(outer.dcache.node.out(0)._2, outer.p)) + val ptw = Module(new PTW(outer.nPTWPorts)(outer.dcache.node.edges.out(0), outer.p)) if (outer.usingPTW) dcachePorts += ptw.io.mem } diff --git a/src/main/scala/rocket/ScratchpadSlavePort.scala b/src/main/scala/rocket/ScratchpadSlavePort.scala index 45a0f952..5f769962 100644 --- a/src/main/scala/rocket/ScratchpadSlavePort.scala +++ b/src/main/scala/rocket/ScratchpadSlavePort.scala @@ -127,7 +127,7 @@ trait CanHaveScratchpad extends HasHellaCache with HasICacheFrontend { } def findScratchpadFromICache: Option[AddressSet] = scratch.map { s => - val finalNode = frontend.masterNode.out.head._2.manager.managers.find(_.nodePath.last == s.node) + val finalNode = frontend.masterNode.edges.out.head.manager.managers.find(_.nodePath.last == s.node) require (finalNode.isDefined, "Could not find the scratch pad; not reachable via icache?") require (finalNode.get.address.size == 1, "Scratchpad address space was fragmented!") finalNode.get.address(0) diff --git a/src/main/scala/tile/Interrupts.scala b/src/main/scala/tile/Interrupts.scala index 4df8564e..dcccada3 100644 --- a/src/main/scala/tile/Interrupts.scala +++ b/src/main/scala/tile/Interrupts.scala @@ -56,6 +56,7 @@ trait HasExternalInterruptsModule { val core_ips = core.lip - (async_ips ++ periph_ips ++ seip ++ core_ips).zip(outer.intNode.in(0)._1).foreach { case(c, i) => c := i } + val (interrupts, _) = outer.intNode.in(0) + (async_ips ++ periph_ips ++ seip ++ core_ips).zip(interrupts).foreach { case(c, i) => c := i } } } diff --git a/src/main/scala/tile/RocketTile.scala b/src/main/scala/tile/RocketTile.scala index 1b42a963..710ce335 100644 --- a/src/main/scala/tile/RocketTile.scala +++ b/src/main/scala/tile/RocketTile.scala @@ -82,7 +82,7 @@ class RocketTile(val rocketParams: RocketTileParams, val hartid: Int)(implicit p })) // Find all the caches - val outer = masterNode.out.map(_._2) + val outer = masterNode.edges.out .flatMap(_.manager.managers) .filter(_.supportsAcquireB) .flatMap(_.resources.headOption) @@ -115,7 +115,7 @@ class RocketTile(val rocketParams: RocketTileParams, val hartid: Int)(implicit p Resource(cpuDevice, "reg").bind(ResourceInt(BigInt(hartid))) Resource(intcDevice, "reg").bind(ResourceInt(BigInt(hartid))) - intNode.in.flatMap(_._2.source.sources).map { case s => + intNode.edges.in.flatMap(_.source.sources).map { case s => for (i <- s.range.start until s.range.end) { csrIntMap.lift(i).foreach { j => s.resources.foreach { r => diff --git a/src/main/scala/tilelink/NodeNumberer.scala b/src/main/scala/tilelink/NodeNumberer.scala index 6c3d17be..eb5c0a9b 100644 --- a/src/main/scala/tilelink/NodeNumberer.scala +++ b/src/main/scala/tilelink/NodeNumberer.scala @@ -43,7 +43,7 @@ class TLNodeNumberer(nodeAddressOffset: Option[Int] = None)(implicit p: Paramete val node = TLNodeNumbererNode(nodeAddressOffset) lazy val module = new LazyModuleImp(this) { - val minNodeOffset = log2Ceil(node.out.map(_._2.manager.maxAddress).max) + val minNodeOffset = log2Ceil(node.edges.out.map(_.manager.maxAddress).max) val nodeOffset = nodeAddressOffset.getOrElse(minNodeOffset) (node.in zip node.out).zipWithIndex foreach { case (((in, _), (out, _)), i) => diff --git a/src/main/scala/tilelink/RegisterRouter.scala b/src/main/scala/tilelink/RegisterRouter.scala index 403f8da7..bf523af7 100644 --- a/src/main/scala/tilelink/RegisterRouter.scala +++ b/src/main/scala/tilelink/RegisterRouter.scala @@ -129,3 +129,5 @@ class TLRegisterRouter[B <: TLRegBundleBase, M <: LazyModuleImp]( lazy val module = moduleBuilder(bundleBuilder(TLRegBundleArg()), this) } + +// !!! eliminate third trait diff --git a/src/main/scala/util/HeterogeneousBag.scala b/src/main/scala/util/HeterogeneousBag.scala index aec7e321..a48743ea 100644 --- a/src/main/scala/util/HeterogeneousBag.scala +++ b/src/main/scala/util/HeterogeneousBag.scala @@ -17,3 +17,8 @@ final case class HeterogeneousBag[T <: Data](elts: Seq[T]) extends Record with c override def hashCode: Int = super[Record].hashCode override def equals(that: Any): Boolean = super[Record].equals(that) } + +object HeterogeneousBag +{ + def fromNode[D <: Data, E](elts: Seq[(D, E)]) = new HeterogeneousBag(elts.map(_._1.cloneType)) +} From 16969eb1f6f6a7071ffc9e2352ef557e0b8cb35b Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 22 Sep 2017 14:57:36 -0700 Subject: [PATCH 11/32] diplomacy: spelling fix --- src/main/scala/diplomacy/Nodes.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/scala/diplomacy/Nodes.scala b/src/main/scala/diplomacy/Nodes.scala index 98a80b50..3a78802e 100644 --- a/src/main/scala/diplomacy/Nodes.scala +++ b/src/main/scala/diplomacy/Nodes.scala @@ -135,7 +135,7 @@ trait InwardNode[DI, UI, BI <: Data] extends BaseNode with InwardNodeHandle[DI, 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 it's .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)) } @@ -167,7 +167,7 @@ trait OutwardNode[DO, UO, BO <: Data] extends BaseNode with OutwardNodeHandle[DO 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 it's .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)) } @@ -276,11 +276,11 @@ sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( // Accessors to the result of negotiation to be used in LazyModuleImp: def out: Seq[(BO, EO)] = { - require(bundlesSafeNow, s"${name}.out should only be called from the context of it's module implementation") + require(bundlesSafeNow, s"${name}.out should only be called from the context of its module implementation") bundleOut zip edgesOut } def in: Seq[(BI, EI)] = { - require(bundlesSafeNow, s"${name}.in should only be called from the context of it's module implementation") + require(bundlesSafeNow, s"${name}.in should only be called from the context of its module implementation") bundleIn zip edgesIn } From cfb7f1340823b4eff953341ce771c5f95c74b333 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 22 Sep 2017 22:23:58 -0700 Subject: [PATCH 12/32] diplomacy: capture SourceInfo at point of := in Edge parameters --- src/main/scala/amba/ahb/Nodes.scala | 4 +-- src/main/scala/amba/ahb/Parameters.scala | 4 ++- src/main/scala/amba/apb/Nodes.scala | 4 +-- src/main/scala/amba/apb/Parameters.scala | 4 ++- src/main/scala/amba/axi4/Nodes.scala | 4 +-- src/main/scala/amba/axi4/Parameters.scala | 4 ++- src/main/scala/diplomacy/Nodes.scala | 44 +++++++++++------------ src/main/scala/tilelink/Edges.scala | 15 ++++---- src/main/scala/tilelink/IntNodes.scala | 6 ++-- src/main/scala/tilelink/Nodes.scala | 12 +++---- src/main/scala/tilelink/Parameters.scala | 8 +++-- 11 files changed, 60 insertions(+), 49 deletions(-) diff --git a/src/main/scala/amba/ahb/Nodes.scala b/src/main/scala/amba/ahb/Nodes.scala index 32ae76c6..5d2f2bb8 100644 --- a/src/main/scala/amba/ahb/Nodes.scala +++ b/src/main/scala/amba/ahb/Nodes.scala @@ -9,8 +9,8 @@ import freechips.rocketchip.diplomacy._ object AHBImp extends NodeImp[AHBMasterPortParameters, AHBSlavePortParameters, AHBEdgeParameters, AHBEdgeParameters, AHBBundle] { - def edgeO(pd: AHBMasterPortParameters, pu: AHBSlavePortParameters, p: Parameters): AHBEdgeParameters = AHBEdgeParameters(pd, pu, p) - def edgeI(pd: AHBMasterPortParameters, pu: AHBSlavePortParameters, p: Parameters): AHBEdgeParameters = AHBEdgeParameters(pd, pu, p) + def edgeO(pd: AHBMasterPortParameters, pu: AHBSlavePortParameters, p: Parameters, sourceInfo: SourceInfo): AHBEdgeParameters = AHBEdgeParameters(pd, pu, p, sourceInfo) + def edgeI(pd: AHBMasterPortParameters, pu: AHBSlavePortParameters, p: Parameters, sourceInfo: SourceInfo): AHBEdgeParameters = AHBEdgeParameters(pd, pu, p, sourceInfo) def bundleO(eo: AHBEdgeParameters): AHBBundle = AHBBundle(eo.bundle) def bundleI(ei: AHBEdgeParameters): AHBBundle = AHBBundle(ei.bundle) diff --git a/src/main/scala/amba/ahb/Parameters.scala b/src/main/scala/amba/ahb/Parameters.scala index 34ddfd34..bd62c3a3 100644 --- a/src/main/scala/amba/ahb/Parameters.scala +++ b/src/main/scala/amba/ahb/Parameters.scala @@ -3,6 +3,7 @@ package freechips.rocketchip.amba.ahb import Chisel._ +import chisel3.internal.sourceinfo.SourceInfo import freechips.rocketchip.config.Parameters import freechips.rocketchip.diplomacy._ import scala.math.max @@ -92,7 +93,8 @@ object AHBBundleParameters case class AHBEdgeParameters( master: AHBMasterPortParameters, slave: AHBSlavePortParameters, - params: Parameters) + params: Parameters, + sourceInfo: SourceInfo) { val bundle = AHBBundleParameters(master, slave) } diff --git a/src/main/scala/amba/apb/Nodes.scala b/src/main/scala/amba/apb/Nodes.scala index 3eefee8c..59acd587 100644 --- a/src/main/scala/amba/apb/Nodes.scala +++ b/src/main/scala/amba/apb/Nodes.scala @@ -9,8 +9,8 @@ import freechips.rocketchip.diplomacy._ object APBImp extends NodeImp[APBMasterPortParameters, APBSlavePortParameters, APBEdgeParameters, APBEdgeParameters, APBBundle] { - def edgeO(pd: APBMasterPortParameters, pu: APBSlavePortParameters, p: Parameters): APBEdgeParameters = APBEdgeParameters(pd, pu, p) - def edgeI(pd: APBMasterPortParameters, pu: APBSlavePortParameters, p: Parameters): APBEdgeParameters = APBEdgeParameters(pd, pu, p) + def edgeO(pd: APBMasterPortParameters, pu: APBSlavePortParameters, p: Parameters, sourceInfo: SourceInfo): APBEdgeParameters = APBEdgeParameters(pd, pu, p, sourceInfo) + def edgeI(pd: APBMasterPortParameters, pu: APBSlavePortParameters, p: Parameters, sourceInfo: SourceInfo): APBEdgeParameters = APBEdgeParameters(pd, pu, p, sourceInfo) def bundleO(eo: APBEdgeParameters): APBBundle = APBBundle(eo.bundle) def bundleI(ei: APBEdgeParameters): APBBundle = APBBundle(ei.bundle) diff --git a/src/main/scala/amba/apb/Parameters.scala b/src/main/scala/amba/apb/Parameters.scala index e6c733f8..77aa6624 100644 --- a/src/main/scala/amba/apb/Parameters.scala +++ b/src/main/scala/amba/apb/Parameters.scala @@ -3,6 +3,7 @@ package freechips.rocketchip.amba.apb import Chisel._ +import chisel3.internal.sourceinfo.SourceInfo import freechips.rocketchip.config.Parameters import freechips.rocketchip.diplomacy._ import scala.math.max @@ -79,7 +80,8 @@ object APBBundleParameters case class APBEdgeParameters( master: APBMasterPortParameters, slave: APBSlavePortParameters, - params: Parameters) + params: Parameters, + sourceInfo: SourceInfo) { val bundle = APBBundleParameters(master, slave) } diff --git a/src/main/scala/amba/axi4/Nodes.scala b/src/main/scala/amba/axi4/Nodes.scala index b0037626..89d9fce8 100644 --- a/src/main/scala/amba/axi4/Nodes.scala +++ b/src/main/scala/amba/axi4/Nodes.scala @@ -9,8 +9,8 @@ import freechips.rocketchip.diplomacy._ object AXI4Imp extends NodeImp[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4EdgeParameters, AXI4EdgeParameters, AXI4Bundle] { - def edgeO(pd: AXI4MasterPortParameters, pu: AXI4SlavePortParameters, p: Parameters): AXI4EdgeParameters = AXI4EdgeParameters(pd, pu, p) - def edgeI(pd: AXI4MasterPortParameters, pu: AXI4SlavePortParameters, p: Parameters): AXI4EdgeParameters = AXI4EdgeParameters(pd, pu, p) + def edgeO(pd: AXI4MasterPortParameters, pu: AXI4SlavePortParameters, p: Parameters, sourceInfo: SourceInfo): AXI4EdgeParameters = AXI4EdgeParameters(pd, pu, p, sourceInfo) + def edgeI(pd: AXI4MasterPortParameters, pu: AXI4SlavePortParameters, p: Parameters, sourceInfo: SourceInfo): AXI4EdgeParameters = AXI4EdgeParameters(pd, pu, p, sourceInfo) def bundleO(eo: AXI4EdgeParameters): AXI4Bundle = AXI4Bundle(eo.bundle) def bundleI(ei: AXI4EdgeParameters): AXI4Bundle = AXI4Bundle(ei.bundle) diff --git a/src/main/scala/amba/axi4/Parameters.scala b/src/main/scala/amba/axi4/Parameters.scala index 01069f10..c58cc4d1 100644 --- a/src/main/scala/amba/axi4/Parameters.scala +++ b/src/main/scala/amba/axi4/Parameters.scala @@ -3,6 +3,7 @@ package freechips.rocketchip.amba.axi4 import Chisel._ +import chisel3.internal.sourceinfo.SourceInfo import freechips.rocketchip.config.Parameters import freechips.rocketchip.diplomacy._ import scala.math.max @@ -125,7 +126,8 @@ object AXI4BundleParameters case class AXI4EdgeParameters( master: AXI4MasterPortParameters, slave: AXI4SlavePortParameters, - params: Parameters) + params: Parameters, + sourceInfo: SourceInfo) { val bundle = AXI4BundleParameters(master, slave) } diff --git a/src/main/scala/diplomacy/Nodes.scala b/src/main/scala/diplomacy/Nodes.scala index 3a78802e..906963ee 100644 --- a/src/main/scala/diplomacy/Nodes.scala +++ b/src/main/scala/diplomacy/Nodes.scala @@ -34,7 +34,7 @@ private case object MonitorsEnabled extends Field[Boolean](true) // BI = Bundle type used when connecting to the inner side of the node trait InwardNodeImp[DI, UI, EI, BI <: Data] { - def edgeI(pd: DI, pu: UI, p: Parameters): EI + def edgeI(pd: DI, pu: UI, p: Parameters, sourceInfo: SourceInfo): EI def bundleI(ei: EI): BI def colour: String def reverse: Boolean = false @@ -55,7 +55,7 @@ trait InwardNodeImp[DI, UI, EI, BI <: Data] // BO = Bundle type used when connecting to the outer side of the node trait OutwardNodeImp[DO, UO, EO, BO <: Data] { - def edgeO(pd: DO, pu: UO, p: Parameters): EO + def edgeO(pd: DO, pu: UO, p: Parameters, sourceInfo: SourceInfo): EO def bundleO(eo: EO): BO // optional methods to track node graph @@ -127,7 +127,7 @@ trait InwardNode[DI, UI, BI <: Data] extends BaseNode with InwardNodeHandle[DI, 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)]() + private val accPI = ListBuffer[(Int, OutwardNode[DI, UI, BI], NodeBinding, Parameters, SourceInfo)]() private var iRealized = false protected[diplomacy] def iPushed = accPI.size @@ -136,7 +136,7 @@ trait InwardNode[DI, UI, BI <: Data] extends BaseNode with InwardNodeHandle[DI, 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) - accPI += ((index, node, binding, p)) + accPI += ((index, node, binding, p, sourceInfo)) } protected[diplomacy] lazy val iBindings = { iRealized = true; accPI.result() } @@ -159,7 +159,7 @@ trait OutwardNode[DO, UO, BO <: Data] extends BaseNode with OutwardNodeHandle[DO 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)]() + private val accPO = ListBuffer[(Int, InwardNode [DO, UO, BO], NodeBinding, Parameters, SourceInfo)]() private var oRealized = false protected[diplomacy] def oPushed = accPO.size @@ -168,7 +168,7 @@ trait OutwardNode[DO, UO, BO <: Data] extends BaseNode with OutwardNodeHandle[DO 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) - accPO += ((index, node, binding, p)) + accPO += ((index, node, binding, p, sourceInfo)) } protected[diplomacy] lazy val oBindings = { oRealized = true; accPO.result() } @@ -192,22 +192,22 @@ sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( protected[diplomacy] def mapParamsU(n: Int, p: Seq[UO]): Seq[UI] protected[diplomacy] lazy val (oPortMapping, iPortMapping, oStar, iStar) = { - val oStars = oBindings.filter { case (_,_,b,_) => b == BIND_STAR }.size - val iStars = iBindings.filter { case (_,_,b,_) => b == BIND_STAR }.size - val oKnown = oBindings.map { case (_, n, b, _) => b match { + val oStars = oBindings.filter { case (_,_,b,_,_) => b == BIND_STAR }.size + val iStars = iBindings.filter { case (_,_,b,_,_) => b == BIND_STAR }.size + val oKnown = oBindings.map { case (_, n, b, _, _) => b match { case BIND_ONCE => 1 case BIND_QUERY => n.iStar case BIND_STAR => 0 }}.foldLeft(0)(_+_) - val iKnown = iBindings.map { case (_, n, b, _) => b match { + val iKnown = iBindings.map { case (_, n, b, _, _) => b match { case BIND_ONCE => 1 case BIND_QUERY => n.oStar case BIND_STAR => 0 }}.foldLeft(0)(_+_) val (iStar, oStar) = resolveStar(iKnown, oKnown, iStars, oStars) - val oSum = oBindings.map { case (_, n, b, _) => b match { + val oSum = oBindings.map { case (_, n, b, _, _) => b match { case BIND_ONCE => 1 case BIND_QUERY => n.iStar case BIND_STAR => oStar }}.scanLeft(0)(_+_) - val iSum = iBindings.map { case (_, n, b, _) => b match { + val iSum = iBindings.map { case (_, n, b, _, _) => b match { case BIND_ONCE => 1 case BIND_QUERY => n.oStar case BIND_STAR => iStar }}.scanLeft(0)(_+_) @@ -218,22 +218,22 @@ sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( (oSum.init zip oSum.tail, iSum.init zip iSum.tail, oStar, iStar) } - lazy val oPorts = oBindings.flatMap { case (i, n, _, p) => + lazy val oPorts = oBindings.flatMap { case (i, n, _, p, s) => val (start, end) = n.iPortMapping(i) - (start until end) map { j => (j, n, p) } + (start until end) map { j => (j, n, p, s) } } - lazy val iPorts = iBindings.flatMap { case (i, n, _, p) => + lazy val iPorts = iBindings.flatMap { case (i, n, _, p, s) => val (start, end) = n.oPortMapping(i) - (start until end) map { j => (j, n, p) } + (start until end) map { j => (j, n, p, s) } } protected[diplomacy] lazy val oParams: Seq[DO] = { - val o = mapParamsD(oPorts.size, iPorts.map { case (i, n, _) => n.oParams(i) }) + val o = mapParamsD(oPorts.size, iPorts.map { case (i, n, _, _) => n.oParams(i) }) require (o.size == oPorts.size, s"Bug in diplomacy; ${name} has ${o.size} != ${oPorts.size} down/up outer parameters${lazyModule.line}") o.map(outer.mixO(_, this)) } protected[diplomacy] lazy val iParams: Seq[UI] = { - val i = mapParamsU(iPorts.size, oPorts.map { case (o, n, _) => n.iParams(o) }) + val i = mapParamsU(iPorts.size, oPorts.map { case (o, n, _, _) => n.iParams(o) }) require (i.size == iPorts.size, s"Bug in diplomacy; ${name} has ${i.size} != ${iPorts.size} up/down inner parameters${lazyModule.line}") i.map(inner.mixI(_, this)) } @@ -241,8 +241,8 @@ sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( protected[diplomacy] def gco = if (iParams.size != 1) None else inner.getO(iParams(0)) protected[diplomacy] def gci = if (oParams.size != 1) None else outer.getI(oParams(0)) - protected[diplomacy] lazy val edgesOut = (oPorts zip oParams).map { case ((i, n, p), o) => outer.edgeO(o, n.iParams(i), p) } - protected[diplomacy] lazy val edgesIn = (iPorts zip iParams).map { case ((o, n, p), i) => inner.edgeI(n.oParams(o), i, p) } + protected[diplomacy] lazy val edgesOut = (oPorts zip oParams).map { case ((i, n, p, s), o) => outer.edgeO(o, n.iParams(i), p, s) } + protected[diplomacy] lazy val edgesIn = (iPorts zip iParams).map { case ((o, n, p, s), i) => inner.edgeI(n.oParams(o), i, p, s) } // If you need access to the edges of a foreign Node, use this method (in/out create bundles) lazy val edges = Edges(edgesIn, edgesOut) @@ -250,7 +250,7 @@ sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( protected[diplomacy] lazy val bundleOut: Seq[BO] = edgesOut.map(e => Wire(outer.bundleO(e))) protected[diplomacy] lazy val bundleIn: Seq[BI] = edgesIn .map(e => Wire(inner.bundleI(e))) - protected[diplomacy] def danglesOut: Seq[Dangle] = oPorts.zipWithIndex.map { case ((j, n, _), i) => + protected[diplomacy] def danglesOut: Seq[Dangle] = oPorts.zipWithIndex.map { case ((j, n, _, _), i) => Dangle( source = HalfEdge(serial, i), sink = HalfEdge(n.serial, j), @@ -258,7 +258,7 @@ sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( name = valName.name + "_out", data = bundleOut(i)) } - protected[diplomacy] def danglesIn: Seq[Dangle] = iPorts.zipWithIndex.map { case ((j, n, _), i) => + protected[diplomacy] def danglesIn: Seq[Dangle] = iPorts.zipWithIndex.map { case ((j, n, _, _), i) => Dangle( source = HalfEdge(n.serial, j), sink = HalfEdge(serial, i), diff --git a/src/main/scala/tilelink/Edges.scala b/src/main/scala/tilelink/Edges.scala index 4734cbda..55c21711 100644 --- a/src/main/scala/tilelink/Edges.scala +++ b/src/main/scala/tilelink/Edges.scala @@ -11,8 +11,9 @@ import freechips.rocketchip.util._ class TLEdge( client: TLClientPortParameters, manager: TLManagerPortParameters, - params: Parameters) - extends TLEdgeParameters(client, manager, params) + params: Parameters, + sourceInfo: SourceInfo) + extends TLEdgeParameters(client, manager, params, sourceInfo) { def isAligned(address: UInt, lgSize: UInt): Bool = { if (maxLgSize == 0) Bool(true) else { @@ -265,8 +266,9 @@ class TLEdge( class TLEdgeOut( client: TLClientPortParameters, manager: TLManagerPortParameters, - params: Parameters) - extends TLEdge(client, manager, params) + params: Parameters, + sourceInfo: SourceInfo) + extends TLEdge(client, manager, params, sourceInfo) { // Transfers def Acquire(fromSource: UInt, toAddress: UInt, lgSize: UInt, growPermissions: UInt) = { @@ -480,8 +482,9 @@ class TLEdgeOut( class TLEdgeIn( client: TLClientPortParameters, manager: TLManagerPortParameters, - params: Parameters) - extends TLEdge(client, manager, params) + params: Parameters, + sourceInfo: SourceInfo) + extends TLEdge(client, manager, params, sourceInfo) { // Transfers def Probe(fromAddress: UInt, toSource: UInt, lgSize: UInt, capPermissions: UInt) = { diff --git a/src/main/scala/tilelink/IntNodes.scala b/src/main/scala/tilelink/IntNodes.scala index dc33640d..c0339b77 100644 --- a/src/main/scala/tilelink/IntNodes.scala +++ b/src/main/scala/tilelink/IntNodes.scala @@ -61,12 +61,12 @@ object IntSinkPortSimple Seq.fill(ports)(IntSinkPortParameters(Seq.fill(sinks)(IntSinkParameters()))) } -case class IntEdge(source: IntSourcePortParameters, sink: IntSinkPortParameters, params: Parameters) +case class IntEdge(source: IntSourcePortParameters, sink: IntSinkPortParameters, params: Parameters, sourceInfo: SourceInfo) object IntImp extends NodeImp[IntSourcePortParameters, IntSinkPortParameters, IntEdge, IntEdge, Vec[Bool]] { - def edgeO(pd: IntSourcePortParameters, pu: IntSinkPortParameters, p: Parameters): IntEdge = IntEdge(pd, pu, p) - def edgeI(pd: IntSourcePortParameters, pu: IntSinkPortParameters, p: Parameters): IntEdge = IntEdge(pd, pu, p) + def edgeO(pd: IntSourcePortParameters, pu: IntSinkPortParameters, p: Parameters, sourceInfo: SourceInfo): IntEdge = IntEdge(pd, pu, p, sourceInfo) + def edgeI(pd: IntSourcePortParameters, pu: IntSinkPortParameters, p: Parameters, sourceInfo: SourceInfo): IntEdge = IntEdge(pd, pu, p, sourceInfo) def bundleO(eo: IntEdge): Vec[Bool] = Vec(eo.source.num, Bool()) def bundleI(ei: IntEdge): Vec[Bool] = Vec(ei.source.num, Bool()) diff --git a/src/main/scala/tilelink/Nodes.scala b/src/main/scala/tilelink/Nodes.scala index 9b96147a..6119990b 100644 --- a/src/main/scala/tilelink/Nodes.scala +++ b/src/main/scala/tilelink/Nodes.scala @@ -14,8 +14,8 @@ case object TLCombinationalCheck extends Field[Boolean](false) object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TLEdgeOut, TLEdgeIn, TLBundle] { - def edgeO(pd: TLClientPortParameters, pu: TLManagerPortParameters, p: Parameters): TLEdgeOut = new TLEdgeOut(pd, pu, p) - def edgeI(pd: TLClientPortParameters, pu: TLManagerPortParameters, p: Parameters): TLEdgeIn = new TLEdgeIn(pd, pu, p) + def edgeO(pd: TLClientPortParameters, pu: TLManagerPortParameters, p: Parameters, sourceInfo: SourceInfo): TLEdgeOut = new TLEdgeOut(pd, pu, p, sourceInfo) + def edgeI(pd: TLClientPortParameters, pu: TLManagerPortParameters, p: Parameters, sourceInfo: SourceInfo): TLEdgeIn = new TLEdgeIn (pd, pu, p, sourceInfo) def bundleO(eo: TLEdgeOut): TLBundle = TLBundle(eo.bundle) def bundleI(ei: TLEdgeIn): TLBundle = TLBundle(ei.bundle) @@ -93,8 +93,8 @@ abstract class TLCustomNode( object TLAsyncImp extends NodeImp[TLAsyncClientPortParameters, TLAsyncManagerPortParameters, TLAsyncEdgeParameters, TLAsyncEdgeParameters, TLAsyncBundle] { - def edgeO(pd: TLAsyncClientPortParameters, pu: TLAsyncManagerPortParameters, p: Parameters): TLAsyncEdgeParameters = TLAsyncEdgeParameters(pd, pu, p) - def edgeI(pd: TLAsyncClientPortParameters, pu: TLAsyncManagerPortParameters, p: Parameters): TLAsyncEdgeParameters = TLAsyncEdgeParameters(pd, pu, p) + def edgeO(pd: TLAsyncClientPortParameters, pu: TLAsyncManagerPortParameters, p: Parameters, sourceInfo: SourceInfo): TLAsyncEdgeParameters = TLAsyncEdgeParameters(pd, pu, p, sourceInfo) + def edgeI(pd: TLAsyncClientPortParameters, pu: TLAsyncManagerPortParameters, p: Parameters, sourceInfo: SourceInfo): TLAsyncEdgeParameters = TLAsyncEdgeParameters(pd, pu, p, sourceInfo) def bundleO(eo: TLAsyncEdgeParameters): TLAsyncBundle = new TLAsyncBundle(eo.bundle) def bundleI(ei: TLAsyncEdgeParameters): TLAsyncBundle = new TLAsyncBundle(ei.bundle) @@ -132,8 +132,8 @@ case class TLAsyncSinkNode(depth: Int, sync: Int)(implicit valName: ValName) object TLRationalImp extends NodeImp[TLRationalClientPortParameters, TLRationalManagerPortParameters, TLRationalEdgeParameters, TLRationalEdgeParameters, TLRationalBundle] { - def edgeO(pd: TLRationalClientPortParameters, pu: TLRationalManagerPortParameters, p: Parameters): TLRationalEdgeParameters = TLRationalEdgeParameters(pd, pu, p) - def edgeI(pd: TLRationalClientPortParameters, pu: TLRationalManagerPortParameters, p: Parameters): TLRationalEdgeParameters = TLRationalEdgeParameters(pd, pu, p) + def edgeO(pd: TLRationalClientPortParameters, pu: TLRationalManagerPortParameters, p: Parameters, sourceInfo: SourceInfo): TLRationalEdgeParameters = TLRationalEdgeParameters(pd, pu, p, sourceInfo) + def edgeI(pd: TLRationalClientPortParameters, pu: TLRationalManagerPortParameters, p: Parameters, sourceInfo: SourceInfo): TLRationalEdgeParameters = TLRationalEdgeParameters(pd, pu, p, sourceInfo) def bundleO(eo: TLRationalEdgeParameters): TLRationalBundle = new TLRationalBundle(eo.bundle) def bundleI(ei: TLRationalEdgeParameters): TLRationalBundle = new TLRationalBundle(ei.bundle) diff --git a/src/main/scala/tilelink/Parameters.scala b/src/main/scala/tilelink/Parameters.scala index b4f5c7ce..4853addf 100644 --- a/src/main/scala/tilelink/Parameters.scala +++ b/src/main/scala/tilelink/Parameters.scala @@ -3,6 +3,7 @@ package freechips.rocketchip.tilelink import Chisel._ +import chisel3.internal.sourceinfo.SourceInfo import freechips.rocketchip.config.Parameters import freechips.rocketchip.diplomacy._ import freechips.rocketchip.util.RationalDirection @@ -314,7 +315,8 @@ object TLBundleParameters case class TLEdgeParameters( client: TLClientPortParameters, manager: TLManagerPortParameters, - params: Parameters) + params: Parameters, + sourceInfo: SourceInfo) { val maxTransfer = max(client.maxTransfer, manager.maxTransfer) val maxLgSize = log2Ceil(maxTransfer) @@ -342,7 +344,7 @@ object TLAsyncBundleParameters def union(x: Seq[TLAsyncBundleParameters]) = x.foldLeft(emptyBundleParams)((x,y) => x.union(y)) } -case class TLAsyncEdgeParameters(client: TLAsyncClientPortParameters, manager: TLAsyncManagerPortParameters, params: Parameters) +case class TLAsyncEdgeParameters(client: TLAsyncClientPortParameters, manager: TLAsyncManagerPortParameters, params: Parameters, sourceInfo: SourceInfo) { val bundle = TLAsyncBundleParameters(manager.depth, TLBundleParameters(client.base, manager.base)) } @@ -350,7 +352,7 @@ case class TLAsyncEdgeParameters(client: TLAsyncClientPortParameters, manager: T case class TLRationalManagerPortParameters(direction: RationalDirection, base: TLManagerPortParameters) case class TLRationalClientPortParameters(base: TLClientPortParameters) -case class TLRationalEdgeParameters(client: TLRationalClientPortParameters, manager: TLRationalManagerPortParameters, params: Parameters) +case class TLRationalEdgeParameters(client: TLRationalClientPortParameters, manager: TLRationalManagerPortParameters, params: Parameters, sourceInfo: SourceInfo) { val bundle = TLBundleParameters(client.base, manager.base) } From bc225a4e82df3e40bcfffdd5b406a03f01950ae9 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 22 Sep 2017 16:55:12 -0700 Subject: [PATCH 13/32] diplomacy: place Monitors inside LazyModules sinks We used to place Monitors at the point of the ':='. This was problematic because the clock domain might be wrong. Thus, we needed to shove Monitors a lot. Furthermore, now that we have cross-module ':=', you might not even have access to the wires at the point where ':=' is invoked. --- src/main/scala/diplomacy/Monitor.scala | 10 ---- src/main/scala/diplomacy/Nodes.scala | 47 +++++++++---------- src/main/scala/tilelink/AsyncCrossing.scala | 23 ++------- src/main/scala/tilelink/Fuzzer.scala | 8 +--- src/main/scala/tilelink/Monitor.scala | 20 ++++---- src/main/scala/tilelink/Nodes.scala | 23 ++------- .../scala/tilelink/RationalCrossing.scala | 15 ++---- 7 files changed, 41 insertions(+), 105 deletions(-) delete mode 100644 src/main/scala/diplomacy/Monitor.scala diff --git a/src/main/scala/diplomacy/Monitor.scala b/src/main/scala/diplomacy/Monitor.scala deleted file mode 100644 index 63efc8a7..00000000 --- a/src/main/scala/diplomacy/Monitor.scala +++ /dev/null @@ -1,10 +0,0 @@ -// See LICENSE.SiFive for license details. - -package freechips.rocketchip.diplomacy - -import chisel3.internal.sourceinfo.{SourceInfo, SourceLine} -import freechips.rocketchip.config.Parameters - -abstract class MonitorBase(implicit val sourceInfo: SourceInfo, p: Parameters) extends LazyModule()(p) { - override val module: LazyModuleImp -} diff --git a/src/main/scala/diplomacy/Nodes.scala b/src/main/scala/diplomacy/Nodes.scala index 906963ee..c5137ceb 100644 --- a/src/main/scala/diplomacy/Nodes.scala +++ b/src/main/scala/diplomacy/Nodes.scala @@ -36,12 +36,9 @@ trait InwardNodeImp[DI, UI, EI, BI <: Data] { def edgeI(pd: DI, pu: UI, p: Parameters, sourceInfo: SourceInfo): EI def bundleI(ei: EI): BI + def monitor(bundle: BI, edge: EI) {} def colour: String def reverse: Boolean = false - def connect(edges: () => Seq[EI], bundles: () => Seq[(BI, BI)], enableMonitoring: Boolean) - (implicit p: Parameters, sourceInfo: SourceInfo): (Option[MonitorBase], () => Unit) = { - (None, () => bundles().foreach { case (i, o) => i <> o }) - } // optional methods to track node graph def mixI(pu: UI, node: InwardNode[DI, UI, BI]): UI = pu // insert node into parameters @@ -104,14 +101,10 @@ case class NodeHandle[DI, UI, BI <: Data, DO, UO, BO <: Data] trait InwardNodeHandle[DI, UI, BI <: Data] { protected[diplomacy] val inward: InwardNode[DI, UI, BI] - def := (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = - inward.:=(h)(p, sourceInfo) - def :*= (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = - inward.:*=(h)(p, sourceInfo) - def :=* (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = - inward.:=*(h)(p, sourceInfo) - def :=? (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = - inward.:=?(h)(p, sourceInfo) + def := (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo) { inward.:=(h)(p, sourceInfo) } + def :*= (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo) { inward.:*=(h)(p, sourceInfo) } + def :=* (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo) { inward.:=*(h)(p, sourceInfo) } + def :=? (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo) { inward.:=?(h)(p, sourceInfo) } } sealed trait NodeBinding @@ -267,13 +260,7 @@ sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( data = bundleIn(i)) } - // Used by LazyModules.module.instantiate private var bundlesSafeNow = false - protected[diplomacy] def instantiate() = { - bundlesSafeNow = true - danglesOut ++ danglesIn - } - // Accessors to the result of negotiation to be used in LazyModuleImp: def out: Seq[(BO, EO)] = { require(bundlesSafeNow, s"${name}.out should only be called from the context of its module implementation") @@ -284,9 +271,19 @@ sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( bundleIn zip edgesIn } + // Used by LazyModules.module.instantiate + protected val identity = false + protected[diplomacy] def instantiate() = { + bundlesSafeNow = true + if (!identity) { + (iPorts zip in) foreach { + case ((_, _, p, _), (b, e)) => if (p(MonitorsEnabled)) inner.monitor(b, e) + } } + danglesOut ++ danglesIn + } + // connects the outward part of a node with the inward part of this node - private def bind(h: OutwardNodeHandle[DI, UI, BI], binding: NodeBinding) - (implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = { + private def bind(h: OutwardNodeHandle[DI, UI, BI], binding: NodeBinding)(implicit p: Parameters, sourceInfo: SourceInfo) { val x = this // x := y val y = h.outward val info = sourceLine(sourceInfo, " at ", "") @@ -298,13 +295,12 @@ sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( case BIND_STAR => BIND_QUERY case BIND_QUERY => BIND_STAR }) x.iPush(o, y, binding) - None // !!! create monitors } - override def := (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = bind(h, BIND_ONCE) - override def :*= (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = bind(h, BIND_STAR) - override def :=* (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = bind(h, BIND_QUERY) - override def :=? (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = { + override def := (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo) = bind(h, BIND_ONCE) + override def :*= (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo) = bind(h, BIND_STAR) + override def :=* (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo) = bind(h, BIND_QUERY) + override def :=? (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo) = { p(CardinalityInferenceDirectionKey) match { case CardinalityInferenceDirection.SOURCE_TO_SINK => this :=* h case CardinalityInferenceDirection.SINK_TO_SOURCE => this :*= h @@ -378,6 +374,7 @@ class AdapterNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])( class IdentityNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])()(implicit valName: ValName) extends AdapterNode(imp)({ s => s }, { s => s }) { + protected override val identity = true override protected[diplomacy] def instantiate() = { val dangles = super.instantiate() (out zip in) map { case ((o, _), (i, _)) => o <> i } diff --git a/src/main/scala/tilelink/AsyncCrossing.scala b/src/main/scala/tilelink/AsyncCrossing.scala index de29c051..f312f4e8 100644 --- a/src/main/scala/tilelink/AsyncCrossing.scala +++ b/src/main/scala/tilelink/AsyncCrossing.scala @@ -94,9 +94,9 @@ class TLAsyncCrossing(depth: Int = 8, sync: Int = 3)(implicit p: Parameters) ext val source = LazyModule(new TLAsyncCrossingSource(sync)) val sink = LazyModule(new TLAsyncCrossingSink(depth, sync)) - val _ = (sink.node := source.node) // no monitor - val in = (source.node := nodeIn) - val out = (nodeOut := sink.node) + sink.node := source.node + source.node := nodeIn + nodeOut := sink.node lazy val module = new LazyModuleImp(this) { val io = IO(new Bundle { @@ -108,17 +108,8 @@ class TLAsyncCrossing(depth: Int = 8, sync: Int = 3)(implicit p: Parameters) ext source.module.clock := io.in_clock source.module.reset := io.in_reset - in.foreach { lm => - lm.module.clock := io.in_clock - lm.module.reset := io.in_reset - } - sink.module.clock := io.out_clock sink.module.reset := io.out_reset - out.foreach { lm => - lm.module.clock := io.out_clock - lm.module.reset := io.out_reset - } } } @@ -133,7 +124,7 @@ class TLRAMAsyncCrossing(txns: Int)(implicit p: Parameters) extends LazyModule { model.node := fuzz.node cross.node := TLFragmenter(4, 256)(TLDelayer(0.1)(model.node)) - val monitor = (ram.node := cross.node) + ram.node := cross.node lazy val module = new LazyModuleImp(this) with UnitTestModule { io.finished := fuzz.module.io.finished @@ -147,12 +138,6 @@ class TLRAMAsyncCrossing(txns: Int)(implicit p: Parameters) extends LazyModule { cross.module.io.in_reset := reset cross.module.io.out_clock := clocks.io.clock_out cross.module.io.out_reset := reset - - // Push the Monitor into the right clock domain - monitor.foreach { m => - m.module.clock := clocks.io.clock_out - m.module.reset := reset - } } } diff --git a/src/main/scala/tilelink/Fuzzer.scala b/src/main/scala/tilelink/Fuzzer.scala index beac41f1..c2e6a769 100644 --- a/src/main/scala/tilelink/Fuzzer.scala +++ b/src/main/scala/tilelink/Fuzzer.scala @@ -240,7 +240,7 @@ class TLFuzzRAM(txns: Int)(implicit p: Parameters) extends LazyModule ram2.node := TLFragmenter(16, 256)(xbar2.node) xbar.node := TLWidthWidget(16)(TLHintHandler()(xbar2.node)) cross.node := TLFragmenter(4, 256)(TLBuffer()(xbar.node)) - val monitor = (ram.node := cross.node) + ram.node := cross.node gpio.node := TLFragmenter(4, 32)(TLBuffer()(xbar.node)) lazy val module = new LazyModuleImp(this) with UnitTestModule { @@ -255,12 +255,6 @@ class TLFuzzRAM(txns: Int)(implicit p: Parameters) extends LazyModule cross.module.io.in_reset := reset cross.module.io.out_clock := clocks.io.clock_out cross.module.io.out_reset := reset - - // Push the Monitor into the right clock domain - monitor.foreach { m => - m.module.clock := clocks.io.clock_out - m.module.reset := reset - } } } diff --git a/src/main/scala/tilelink/Monitor.scala b/src/main/scala/tilelink/Monitor.scala index ec4a8a97..11ddd0ec 100644 --- a/src/main/scala/tilelink/Monitor.scala +++ b/src/main/scala/tilelink/Monitor.scala @@ -8,26 +8,22 @@ import freechips.rocketchip.config.Parameters import freechips.rocketchip.diplomacy._ import freechips.rocketchip.util.{HeterogeneousBag, PlusArg} -case class TLMonitorArgs(edge: () => Seq[TLEdge], sourceInfo: SourceInfo, p: Parameters) +case class TLMonitorArgs(edge: TLEdge) -abstract class TLMonitorBase(args: TLMonitorArgs) extends MonitorBase()(args.sourceInfo, args.p) +abstract class TLMonitorBase(args: TLMonitorArgs) extends Module { - def legalize(bundle: TLBundleSnoop, edge: TLEdge, reset: Bool): Unit - - lazy val module = new LazyModuleImp(this) { - val edges = args.edge() - val io = IO(new Bundle { - val in = HeterogeneousBag(edges.map(p => new TLBundleSnoop(p.bundle))).flip - }) - - (edges zip io.in).foreach { case (e, in) => legalize(in, e, reset) } + val io = new Bundle { + val in = new TLBundleSnoop(args.edge.bundle).flip } + + def legalize(bundle: TLBundleSnoop, edge: TLEdge, reset: Bool): Unit + legalize(io.in, args.edge, reset) } class TLMonitor(args: TLMonitorArgs) extends TLMonitorBase(args) { def extra = { - sourceInfo match { + args.edge.sourceInfo match { case SourceLine(filename, line, col) => s" (connected at $filename:$line:$col)" case _ => "" } diff --git a/src/main/scala/tilelink/Nodes.scala b/src/main/scala/tilelink/Nodes.scala index 6119990b..499b89cb 100644 --- a/src/main/scala/tilelink/Nodes.scala +++ b/src/main/scala/tilelink/Nodes.scala @@ -10,7 +10,6 @@ import freechips.rocketchip.util.RationalDirection import scala.collection.mutable.ListBuffer case object TLMonitorBuilder extends Field[TLMonitorArgs => TLMonitorBase](args => new TLMonitor(args)) -case object TLCombinationalCheck extends Field[Boolean](false) object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TLEdgeOut, TLEdgeIn, TLBundle] { @@ -24,25 +23,9 @@ object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TL override def labelI(ei: TLEdgeIn) = (ei.manager.beatBytes * 8).toString override def labelO(eo: TLEdgeOut) = (eo.manager.beatBytes * 8).toString - override def connect(edges: () => Seq[TLEdgeIn], bundles: () => Seq[(TLBundle, TLBundle)], enableMonitoring: Boolean) - (implicit p: Parameters, sourceInfo: SourceInfo): (Option[TLMonitorBase], () => Unit) = { - val monitor = if (enableMonitoring) Some(LazyModule(p(TLMonitorBuilder)(TLMonitorArgs(edges, sourceInfo, p)))) else None - (monitor, () => { - val eval = bundles () - monitor.foreach { m => (eval zip m.module.io.in) foreach { case ((i,o), m) => m := TLBundleSnoop(o,i) } } - eval.foreach { case (bi, bo) => - bi <> bo - if (p(TLCombinationalCheck)) { - // It is forbidden for valid to depend on ready in TL2 - // If someone did that, then this will create a detectable combinational loop - bo.a.ready := bi.a.ready && bo.a.valid - bi.b.ready := bo.b.ready && bi.b.valid - bo.c.ready := bi.c.ready && bo.c.valid - bi.d.ready := bo.d.ready && bi.d.valid - bo.e.ready := bi.e.ready && bo.e.valid - } - } - }) + override def monitor(bundle: TLBundle, edge: TLEdgeIn) { + val monitor = Module(edge.params(TLMonitorBuilder)(TLMonitorArgs(edge))) + monitor.io.in := TLBundleSnoop(bundle, bundle) } override def mixO(pd: TLClientPortParameters, node: OutwardNode[TLClientPortParameters, TLManagerPortParameters, TLBundle]): TLClientPortParameters = diff --git a/src/main/scala/tilelink/RationalCrossing.scala b/src/main/scala/tilelink/RationalCrossing.scala index f84a7355..008f000e 100644 --- a/src/main/scala/tilelink/RationalCrossing.scala +++ b/src/main/scala/tilelink/RationalCrossing.scala @@ -106,9 +106,9 @@ class TLRationalCrossing(direction: RationalDirection = Symmetric)(implicit p: P val source = LazyModule(new TLRationalCrossingSource) val sink = LazyModule(new TLRationalCrossingSink(direction)) - val _ = (sink.node := source.node) // no monitor - val in = (source.node := nodeIn) - val out = (nodeOut := sink.node) + sink.node := source.node + source.node := nodeIn + nodeOut := sink.node lazy val module = new LazyModuleImp(this) { val io = IO(new Bundle { @@ -120,17 +120,8 @@ class TLRationalCrossing(direction: RationalDirection = Symmetric)(implicit p: P source.module.clock := io.in_clock source.module.reset := io.in_reset - in.foreach { lm => - lm.module.clock := io.in_clock - lm.module.reset := io.in_reset - } - sink.module.clock := io.out_clock sink.module.reset := io.out_reset - out.foreach { lm => - lm.module.clock := io.out_clock - lm.module.reset := io.out_reset - } } } From 60614055e360adefc416999f48e205c421a0ac77 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Sat, 23 Sep 2017 00:04:50 -0700 Subject: [PATCH 14/32] diplomacy: eliminate some wasted IdentityNodes using cross-module refs --- src/main/scala/devices/debug/Debug.scala | 25 ++++---- .../scala/devices/tilelink/BusBypass.scala | 1 + src/main/scala/rocket/Frontend.scala | 8 +-- src/main/scala/rocket/ICache.scala | 14 ++--- src/main/scala/tile/RocketTile.scala | 57 ++++++++++--------- src/main/scala/tilelink/AsyncCrossing.scala | 7 +-- src/main/scala/tilelink/Buffer.scala | 30 ++++------ src/main/scala/tilelink/Bus.scala | 2 +- .../scala/tilelink/RationalCrossing.scala | 7 +-- 9 files changed, 64 insertions(+), 87 deletions(-) diff --git a/src/main/scala/devices/debug/Debug.scala b/src/main/scala/devices/debug/Debug.scala index 60577171..37f85ff2 100644 --- a/src/main/scala/devices/debug/Debug.scala +++ b/src/main/scala/devices/debug/Debug.scala @@ -392,15 +392,12 @@ class TLDebugModuleOuterAsync(device: Device)(implicit p: Parameters) extends La val dmiXbar = LazyModule (new TLXbar()) val dmOuter = LazyModule( new TLDebugModuleOuter(device)) - val intnode = IntIdentityNode() + val intnode = dmOuter.intnode - val dmiInnerNode = TLAsyncIdentityNode() - - intnode :*= dmOuter.intnode + val dmiInnerNode = TLAsyncCrossingSource()(dmiXbar.node) dmiXbar.node := dmi2tl.node dmOuter.dmiNode := dmiXbar.node - dmiInnerNode := TLAsyncCrossingSource()(dmiXbar.node) lazy val module = new LazyModuleImp(this) { @@ -1006,12 +1003,12 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p: // Also is the Sink side of hartsel & resumereq fields of DMCONTROL. class TLDebugModuleInnerAsync(device: Device, getNComponents: () => Int)(implicit p: Parameters) extends LazyModule{ - val dmInner = LazyModule(new TLDebugModuleInner(device, getNComponents)(p)) - val dmiNode = TLAsyncIdentityNode() - val tlNode = TLIdentityNode() + val dmInner = LazyModule(new TLDebugModuleInner(device, getNComponents)) + val dmiXing = LazyModule(new TLAsyncCrossingSink(depth=1)) + val dmiNode: TLAsyncInwardNode = dmiXing.node + val tlNode = dmInner.tlNode - dmInner.dmiNode := TLAsyncCrossingSink(depth=1)(dmiNode) - dmInner.tlNode := tlNode + dmInner.dmiNode := dmiXing.node lazy val module = new LazyModuleImp(this) { @@ -1041,15 +1038,13 @@ class TLDebugModule(implicit p: Parameters) extends LazyModule { override val alwaysExtended = true } - val node = TLIdentityNode() - val intnode = IntIdentityNode() - val dmOuter = LazyModule(new TLDebugModuleOuterAsync(device)(p)) val dmInner = LazyModule(new TLDebugModuleInnerAsync(device, () => {intnode.edges.out.size})(p)) + val node = dmInner.tlNode + val intnode = dmOuter.intnode + dmInner.dmiNode := dmOuter.dmiInnerNode - dmInner.tlNode := node - intnode :*= dmOuter.intnode lazy val module = new LazyModuleImp(this) { val nComponents = intnode.out.size diff --git a/src/main/scala/devices/tilelink/BusBypass.scala b/src/main/scala/devices/tilelink/BusBypass.scala index b93ffb97..4621074c 100644 --- a/src/main/scala/devices/tilelink/BusBypass.scala +++ b/src/main/scala/devices/tilelink/BusBypass.scala @@ -20,6 +20,7 @@ abstract class TLBusBypassBase(beatBytes: Int)(implicit p: Parameters) extends L protected val everything = Seq(AddressSet(0, BigInt("ffffffffffffffffffffffffffffffff", 16))) // 128-bit protected val error = LazyModule(new TLError(ErrorParams(everything), beatBytes)) + // order matters bar.node := nodeIn error.node := bar.node nodeOut := bar.node diff --git a/src/main/scala/rocket/Frontend.scala b/src/main/scala/rocket/Frontend.scala index ee224f53..7319e7ea 100644 --- a/src/main/scala/rocket/Frontend.scala +++ b/src/main/scala/rocket/Frontend.scala @@ -56,12 +56,8 @@ class FrontendIO(implicit p: Parameters) extends CoreBundle()(p) { class Frontend(val icacheParams: ICacheParams, hartid: Int)(implicit p: Parameters) extends LazyModule { lazy val module = new FrontendModule(this) val icache = LazyModule(new ICache(icacheParams, hartid)) - val masterNode = TLIdentityNode() - val slaveNode = TLIdentityNode() - - masterNode := icache.masterNode - // Avoid breaking tile dedup due to address constants in the monitor - DisableMonitors { implicit p => icache.slaveNode.map { _ := slaveNode } } + val masterNode = icache.masterNode + val slaveNode = icache.slaveNode } class FrontendBundle(outer: Frontend) extends CoreBundle()(outer.p) diff --git a/src/main/scala/rocket/ICache.scala b/src/main/scala/rocket/ICache.scala index c7c2fabb..8e03e1fe 100644 --- a/src/main/scala/rocket/ICache.scala +++ b/src/main/scala/rocket/ICache.scala @@ -51,9 +51,9 @@ class ICache(val icacheParams: ICacheParams, val hartid: Int)(implicit p: Parame val size = icacheParams.nSets * icacheParams.nWays * icacheParams.blockBytes val device = new SimpleDevice("itim", Seq("sifive,itim0")) - val slaveNode = icacheParams.itimAddr.map { itimAddr => - val wordBytes = icacheParams.fetchBytes - TLManagerNode(Seq(TLManagerPortParameters( + private val wordBytes = icacheParams.fetchBytes + val slaveNode = + TLManagerNode(icacheParams.itimAddr.toSeq.map { itimAddr => TLManagerPortParameters( Seq(TLManagerParameters( address = Seq(AddressSet(itimAddr, size-1)), resources = device.reg("mem"), @@ -64,8 +64,7 @@ class ICache(val icacheParams: ICacheParams, val hartid: Int)(implicit p: Parame supportsGet = TransferSizes(1, wordBytes), fifoId = Some(0))), // requests handled in FIFO order beatBytes = wordBytes, - minLatency = 1))) - } + minLatency = 1)}) } class ICacheResp(outer: ICache) extends Bundle { @@ -110,9 +109,8 @@ class ICacheModule(outer: ICache) extends LazyModuleImp(outer) val io = IO(new ICacheBundle(outer)) val (tl_out, edge_out) = outer.masterNode.out(0) // Option.unzip does not exist :-( - // val (tl_in, edge_in) = outer.slaveNode.map(_.in(0)).unzip - val tl_in = outer.slaveNode.map(_.in(0)._1) - val edge_in = outer.slaveNode.map(_.in(0)._2) + val tl_in = outer.slaveNode.in.headOption.map(_._1) + val edge_in = outer.slaveNode.in.headOption.map(_._2) val tECC = cacheParams.tagECC val dECC = cacheParams.dataECC diff --git a/src/main/scala/tile/RocketTile.scala b/src/main/scala/tile/RocketTile.scala index 710ce335..4b68c949 100644 --- a/src/main/scala/tile/RocketTile.scala +++ b/src/main/scala/tile/RocketTile.scala @@ -57,7 +57,7 @@ class RocketTile(val rocketParams: RocketTileParams, val hartid: Int)(implicit p val dtim = scratch.map(d => Map( "sifive,dtim" -> ofRef(d.device))).getOrElse(Map()) - val itim = if (!frontend.icache.slaveNode.isDefined) Map() else Map( + val itim = if (frontend.icache.slaveNode.edges.in.isEmpty) Map() else Map( "sifive,itim" -> ofRef(frontend.icache.device)) val icache = rocketParams.icache.map(i => Map( @@ -181,12 +181,10 @@ class RocketTileModule(outer: RocketTile) extends BaseTileModule(outer, () => ne abstract class RocketTileWrapper(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends LazyModule { val rocket = LazyModule(new RocketTile(rtp, hartid)) - val masterNode: IdentityNode[_,_,_,_,_] - val slaveNode: IdentityNode[_,_,_,_,_] - val asyncIntNode = IntIdentityNode() - val periphIntNode = IntIdentityNode() - val coreIntNode = IntIdentityNode() - val intOutputNode = rocket.intOutputNode.map(dummy => IntIdentityNode()) + val asyncIntNode : IntInwardNode + val periphIntNode : IntInwardNode + val coreIntNode : IntInwardNode + val intOutputNode = rocket.intOutputNode val intXbar = LazyModule(new IntXbar) rocket.intNode := intXbar.intnode @@ -235,8 +233,7 @@ abstract class RocketTileWrapper(rtp: RocketTileParams, hartid: Int)(implicit p: } class SyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends RocketTileWrapper(rtp, hartid) { - val masterNode = TLIdentityNode() - masterNode :=* optionalMasterBuffer(rocket.masterNode) + val masterNode = optionalMasterBuffer(rocket.masterNode) val slaveNode = new TLIdentityNode() { override def reverse = true } DisableMonitors { implicit p => rocket.slaveNode :*= optionalSlaveBuffer(slaveNode) } @@ -244,20 +241,23 @@ class SyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) // Fully async interrupts need synchronizers. // Others need no synchronization. val xing = LazyModule(new IntXing(3)) - xing.intnode := asyncIntNode + val asyncIntNode = xing.intnode - intXbar.intnode := xing.intnode - intXbar.intnode := periphIntNode - intXbar.intnode := coreIntNode + val periphIntNode = IntIdentityNode() + val coreIntNode = IntIdentityNode() + + // order here matters + intXbar.intnode := xing.intnode + intXbar.intnode := periphIntNode + intXbar.intnode := coreIntNode def outputInterruptXingLatency = 0 } class AsyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends RocketTileWrapper(rtp, hartid) { - val masterNode = TLAsyncIdentityNode() val source = LazyModule(new TLAsyncCrossingSource) source.node :=* rocket.masterNode - masterNode :=* source.node + val masterNode = source.node val slaveNode = new TLAsyncIdentityNode() { override def reverse = true } val sink = LazyModule(new TLAsyncCrossingSink) @@ -272,21 +272,22 @@ class AsyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters // Others need no synchronization. val asyncXing = LazyModule(new IntXing(3)) val periphXing = LazyModule(new IntXing(3)) - asyncXing.intnode := asyncIntNode - periphXing.intnode := periphIntNode + val asyncIntNode = asyncXing.intnode + val periphIntNode = periphXing.intnode + val coreIntNode = IntIdentityNode() - intXbar.intnode := asyncXing.intnode - intXbar.intnode := periphXing.intnode - intXbar.intnode := coreIntNode + // order here matters + intXbar.intnode := asyncXing.intnode + intXbar.intnode := periphXing.intnode + intXbar.intnode := coreIntNode def outputInterruptXingLatency = 3 } class RationalRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends RocketTileWrapper(rtp, hartid) { - val masterNode = TLRationalIdentityNode() val source = LazyModule(new TLRationalCrossingSource) source.node :=* optionalMasterBuffer(rocket.masterNode) - masterNode :=* source.node + val masterNode = source.node val slaveNode = new TLRationalIdentityNode() { override def reverse = true } val sink = LazyModule(new TLRationalCrossingSink(SlowToFast)) @@ -302,12 +303,14 @@ class RationalRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Paramet // Others need no synchronization. val asyncXing = LazyModule(new IntXing(3)) val periphXing = LazyModule(new IntXing(1)) - asyncXing.intnode := asyncIntNode - periphXing.intnode := periphIntNode + val asyncIntNode = asyncXing.intnode + val periphIntNode = periphXing.intnode + val coreIntNode = IntIdentityNode() - intXbar.intnode := asyncXing.intnode - intXbar.intnode := periphXing.intnode - intXbar.intnode := coreIntNode + // order here matters + intXbar.intnode := asyncXing.intnode + intXbar.intnode := periphXing.intnode + intXbar.intnode := coreIntNode def outputInterruptXingLatency = 1 } diff --git a/src/main/scala/tilelink/AsyncCrossing.scala b/src/main/scala/tilelink/AsyncCrossing.scala index f312f4e8..3e9c5c2f 100644 --- a/src/main/scala/tilelink/AsyncCrossing.scala +++ b/src/main/scala/tilelink/AsyncCrossing.scala @@ -87,16 +87,11 @@ object TLAsyncCrossingSink class TLAsyncCrossing(depth: Int = 8, sync: Int = 3)(implicit p: Parameters) extends LazyModule { - val nodeIn = TLIdentityNode() - val nodeOut = TLIdentityNode() - val node = NodeHandle(nodeIn, nodeOut) - val source = LazyModule(new TLAsyncCrossingSource(sync)) val sink = LazyModule(new TLAsyncCrossingSink(depth, sync)) + val node = NodeHandle(source.node, sink.node) sink.node := source.node - source.node := nodeIn - nodeOut := sink.node lazy val module = new LazyModuleImp(this) { val io = IO(new Bundle { diff --git a/src/main/scala/tilelink/Buffer.scala b/src/main/scala/tilelink/Buffer.scala index 84e42d1d..bd35a614 100644 --- a/src/main/scala/tilelink/Buffer.scala +++ b/src/main/scala/tilelink/Buffer.scala @@ -74,31 +74,25 @@ object TLBuffer } class TLBufferChain(depth: Int)(implicit p: Parameters) extends LazyModule { - - val nodeIn = TLIdentityNode() - val nodeOut = TLIdentityNode() - val node = NodeHandle(nodeIn, nodeOut) - - val buf_chain = if (depth > 0) { - val chain = List.fill(depth)(LazyModule(new TLBuffer(BufferParams.default))) - - (chain.init zip chain.tail) foreach { case(prev, next) => next.node :=? prev.node } - chain + val buf_chain = List.fill(depth)(LazyModule(new TLBuffer(BufferParams.default))) + val node = if (depth > 0) { + (buf_chain.init zip buf_chain.tail) foreach { case (prev, next) => next.node :=? prev.node } + NodeHandle(buf_chain.head.node, buf_chain.last.node) } else { - List(LazyModule(new TLBuffer(BufferParams.none))) + TLIdentityNode() } - - buf_chain.head.node :=? nodeIn - nodeOut :=? buf_chain.last.node - lazy val module = new LazyModuleImp(this) { } } object TLBufferChain { def apply(depth: Int)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = { - val buffer = LazyModule(new TLBufferChain(depth)) - buffer.node :=? x - buffer.node + if (depth > 0) { + val buffer = LazyModule(new TLBufferChain(depth)) + buffer.node :=? x + buffer.node + } else { + x + } } } diff --git a/src/main/scala/tilelink/Bus.scala b/src/main/scala/tilelink/Bus.scala index b08fa109..4abbf5ab 100644 --- a/src/main/scala/tilelink/Bus.scala +++ b/src/main/scala/tilelink/Bus.scala @@ -71,7 +71,7 @@ abstract class TLBusWrapper(params: TLBusParams, val busName: String)(implicit p SourceCardinality { implicit p => val chain = LazyModule(new TLBufferChain(depth)) name.foreach { n => chain.suggestName(s"${busName}_${n}_TLBufferChain")} - (chain.nodeIn, chain.nodeOut) + (chain.node, chain.node) } } diff --git a/src/main/scala/tilelink/RationalCrossing.scala b/src/main/scala/tilelink/RationalCrossing.scala index 008f000e..c448774d 100644 --- a/src/main/scala/tilelink/RationalCrossing.scala +++ b/src/main/scala/tilelink/RationalCrossing.scala @@ -99,16 +99,11 @@ object TLRationalCrossingSink class TLRationalCrossing(direction: RationalDirection = Symmetric)(implicit p: Parameters) extends LazyModule { - val nodeIn = TLIdentityNode() - val nodeOut = TLIdentityNode() - val node = NodeHandle(nodeIn, nodeOut) - val source = LazyModule(new TLRationalCrossingSource) val sink = LazyModule(new TLRationalCrossingSink(direction)) + val node = NodeHandle(source.node, sink.node) sink.node := source.node - source.node := nodeIn - nodeOut := sink.node lazy val module = new LazyModuleImp(this) { val io = IO(new Bundle { From 5323cf88ddd1c8ed879b7efd445c200b89184b9e Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Mon, 25 Sep 2017 11:25:46 -0700 Subject: [PATCH 15/32] util: add Option.unzip --- src/main/scala/rocket/ICache.scala | 3 +-- src/main/scala/util/package.scala | 4 ++++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/scala/rocket/ICache.scala b/src/main/scala/rocket/ICache.scala index 8e03e1fe..f5abe304 100644 --- a/src/main/scala/rocket/ICache.scala +++ b/src/main/scala/rocket/ICache.scala @@ -109,8 +109,7 @@ class ICacheModule(outer: ICache) extends LazyModuleImp(outer) val io = IO(new ICacheBundle(outer)) val (tl_out, edge_out) = outer.masterNode.out(0) // Option.unzip does not exist :-( - val tl_in = outer.slaveNode.in.headOption.map(_._1) - val edge_in = outer.slaveNode.in.headOption.map(_._2) + val (tl_in, edge_in) = outer.slaveNode.in.headOption.unzip val tECC = cacheParams.tagECC val dECC = cacheParams.dataECC diff --git a/src/main/scala/util/package.scala b/src/main/scala/util/package.scala index 9661201c..37b06da1 100644 --- a/src/main/scala/util/package.scala +++ b/src/main/scala/util/package.scala @@ -6,6 +6,10 @@ import Chisel._ import scala.math.min package object util { + implicit class UnzippableOption[S, T](val x: Option[(S, T)]) { + def unzip = (x.map(_._1), x.map(_._2)) + } + implicit class UIntIsOneOf(val x: UInt) extends AnyVal { def isOneOf(s: Seq[UInt]): Bool = s.map(x === _).reduce(_||_) From fef5054cec35387a4f0d8568fa8e27503613233c Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Mon, 25 Sep 2017 16:12:34 -0700 Subject: [PATCH 16/32] diplomacy: disambiguate names only when necessary If two (or more) 'auto_' things have the same name, append _0 and _1 to them. The order of definitions is unaffected; ie: a => a_0 b => b_0 b => b_1 c => c a => a_1 --- src/main/scala/diplomacy/LazyModule.scala | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/main/scala/diplomacy/LazyModule.scala b/src/main/scala/diplomacy/LazyModule.scala index 4ef75b11..ab22641f 100644 --- a/src/main/scala/diplomacy/LazyModule.scala +++ b/src/main/scala/diplomacy/LazyModule.scala @@ -7,6 +7,7 @@ import chisel3.experimental.{BaseModule, RawModule, MultiIOModule, withClockAndR import chisel3.internal.sourceinfo.{SourceInfo, SourceLine, UnlocatableSourceInfo} import freechips.rocketchip.config.Parameters import scala.collection.immutable.ListMap +import scala.util.matching._ abstract class LazyModule()(implicit val p: Parameters) { @@ -183,10 +184,20 @@ case class HalfEdge(serial: Int, index: Int) case class Dangle(source: HalfEdge, sink: HalfEdge, flipped: Boolean, name: String, data: Data) final class AutoBundle(elts: (String, Data, Boolean)*) extends Record { - // !!! need to fix-up name collision better than appending _# - val elements = ListMap(elts.zipWithIndex map { case ((field, elt, flip), i) => - (field + "_" + i) -> (if (flip) elt.cloneType.flip else elt.cloneType) - }:_*) + // We need to preserve the order of elts, despite grouping by name to disambiguate things + val elements = ListMap() ++ elts.zipWithIndex.map(makeElements).groupBy(_._1).values.flatMap { + case Seq((key, element, i)) => Seq(i -> (key -> element)) + case seq => seq.zipWithIndex.map { case ((key, element, i), j) => i -> (key + "_" + j -> element) } + }.toList.sortBy(_._1).map(_._2) + require (elements.size == elts.size) + + private def makeElements(tuple: ((String, Data, Boolean), Int)) = { + val ((key, data, flip), i) = tuple + // trim trailing _0_1_2 stuff so that when we append _# we don't create collisions + val regex = new Regex("(_[0-9]+)*$") + val element = if (flip) data.cloneType.flip else data.cloneType + (regex.replaceAllIn(key, ""), element, i) + } override def cloneType = (new AutoBundle(elts:_*)).asInstanceOf[this.type] } From 0111213beaaac60644d0007cf8b60aba1dfd06bb Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Mon, 25 Sep 2017 17:47:40 -0700 Subject: [PATCH 17/32] ValName: trim whitespace from symbol names --- macros/src/main/scala/ValName.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/macros/src/main/scala/ValName.scala b/macros/src/main/scala/ValName.scala index a76e13a8..962073b3 100644 --- a/macros/src/main/scala/ValName.scala +++ b/macros/src/main/scala/ValName.scala @@ -16,7 +16,8 @@ object ValNameImpl if (s == `NoSymbol`) Nil else s +: allOwners(s.owner) val terms = allOwners(c.internal.enclosingOwner).filter(_.isTerm).map(_.asTerm) terms.filter(_.isVal).map(_.name.toString).find(_(0) != '$').map { s => - c.Expr[ValNameImpl] { q"_root_.freechips.rocketchip.macros.ValNameImpl(${s})" } + val trim = s.replaceAll("\\s", "") + c.Expr[ValNameImpl] { q"_root_.freechips.rocketchip.macros.ValNameImpl(${trim})" } }.getOrElse(c.abort(c.enclosingPosition, "Not a valid application.")) } } From d22ec1eddfe1f73ed85e0bf750920a3eb878345a Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Mon, 25 Sep 2017 17:49:45 -0700 Subject: [PATCH 18/32] diplomacy: beautify node signal prefixes --- src/main/scala/diplomacy/Nodes.scala | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/main/scala/diplomacy/Nodes.scala b/src/main/scala/diplomacy/Nodes.scala index c5137ceb..0afd9830 100644 --- a/src/main/scala/diplomacy/Nodes.scala +++ b/src/main/scala/diplomacy/Nodes.scala @@ -7,6 +7,7 @@ import chisel3.internal.sourceinfo.SourceInfo import freechips.rocketchip.config.{Parameters,Field} import freechips.rocketchip.util.HeterogeneousBag import scala.collection.mutable.ListBuffer +import scala.util.matching._ object CardinalityInferenceDirection { val cases = Seq(SOURCE_TO_SINK, SINK_TO_SOURCE, NO_INFERENCE) @@ -80,6 +81,14 @@ abstract class BaseNode(implicit val valName: ValName) def omitGraphML = outputs.isEmpty && inputs.isEmpty lazy val nodedebugstring: String = "" + def wirePrefix = { + val camelCase = "([a-z])([A-Z])".r + val decamel = camelCase.replaceAllIn(valName.name, _ match { case camelCase(l, h) => l + "_" + h }) + val trimNode = "_?node$".r + val name = trimNode.replaceFirstIn(decamel.toLowerCase, "") + if (name.isEmpty) "" else name + "_" + } + protected[diplomacy] def gci: Option[BaseNode] // greatest common inner protected[diplomacy] def gco: Option[BaseNode] // greatest common outer protected[diplomacy] def outputs: Seq[(BaseNode, String)] @@ -248,7 +257,7 @@ sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( source = HalfEdge(serial, i), sink = HalfEdge(n.serial, j), flipped= false, - name = valName.name + "_out", + name = wirePrefix + "out", data = bundleOut(i)) } protected[diplomacy] def danglesIn: Seq[Dangle] = iPorts.zipWithIndex.map { case ((j, n, _, _), i) => @@ -256,7 +265,7 @@ sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( source = HalfEdge(n.serial, j), sink = HalfEdge(serial, i), flipped= true, - name = valName.name + "_in", + name = wirePrefix + "in", data = bundleIn(i)) } From 870ed3d219b48ea50b490325e4af9711c8ab35c9 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Mon, 25 Sep 2017 18:09:03 -0700 Subject: [PATCH 19/32] diplomacy: fix the order of auto signals --- src/main/scala/diplomacy/LazyModule.scala | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/scala/diplomacy/LazyModule.scala b/src/main/scala/diplomacy/LazyModule.scala index ab22641f..2337e95a 100644 --- a/src/main/scala/diplomacy/LazyModule.scala +++ b/src/main/scala/diplomacy/LazyModule.scala @@ -154,12 +154,13 @@ sealed trait LazyModuleImpLike extends BaseModule Module(c.module).dangles } val nodeDangles = wrapper.nodes.reverse.flatMap(_.instantiate()) - val (toConnect, toForward) = (nodeDangles ++ childDangles).groupBy(_.source).partition(_._2.size == 2) - val forward = toForward.map(_._2(0)).toList - toConnect.foreach { case (_, Seq(a, b)) => + val allDangles = nodeDangles ++ childDangles + val done = Set() ++ allDangles.groupBy(_.source).values.filter(_.size == 2).map { case Seq(a, b) => require (a.flipped != b.flipped) if (a.flipped) { a.data <> b.data } else { b.data <> a.data } + a.source } + val forward = allDangles.filter(d => !done(d.source)) val auto = IO(new AutoBundle(forward.map { d => (d.name, d.data, d.flipped) }:_*)) val dangles = (forward zip auto.elements) map { case (d, (_, io)) => if (d.flipped) { d.data <> io } else { io <> d.data } From 76c2aa16613312d82337c35fef91ebc005cd3a90 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Tue, 26 Sep 2017 12:28:59 -0700 Subject: [PATCH 20/32] diplomacy: introduce the typing-saving SimpleNodeImp --- src/main/scala/amba/ahb/Nodes.scala | 12 ++++-------- src/main/scala/amba/apb/Nodes.scala | 12 ++++-------- src/main/scala/amba/axi4/Nodes.scala | 12 ++++-------- src/main/scala/diplomacy/Nodes.scala | 15 +++++++++++++++ src/main/scala/tilelink/IntNodes.scala | 11 ++++------- src/main/scala/tilelink/Nodes.scala | 21 +++++++-------------- 6 files changed, 38 insertions(+), 45 deletions(-) diff --git a/src/main/scala/amba/ahb/Nodes.scala b/src/main/scala/amba/ahb/Nodes.scala index 5d2f2bb8..16a2c884 100644 --- a/src/main/scala/amba/ahb/Nodes.scala +++ b/src/main/scala/amba/ahb/Nodes.scala @@ -7,17 +7,13 @@ import chisel3.internal.sourceinfo.SourceInfo import freechips.rocketchip.config.Parameters import freechips.rocketchip.diplomacy._ -object AHBImp extends NodeImp[AHBMasterPortParameters, AHBSlavePortParameters, AHBEdgeParameters, AHBEdgeParameters, AHBBundle] +object AHBImp extends SimpleNodeImp[AHBMasterPortParameters, AHBSlavePortParameters, AHBEdgeParameters, AHBBundle] { - def edgeO(pd: AHBMasterPortParameters, pu: AHBSlavePortParameters, p: Parameters, sourceInfo: SourceInfo): AHBEdgeParameters = AHBEdgeParameters(pd, pu, p, sourceInfo) - def edgeI(pd: AHBMasterPortParameters, pu: AHBSlavePortParameters, p: Parameters, sourceInfo: SourceInfo): AHBEdgeParameters = AHBEdgeParameters(pd, pu, p, sourceInfo) - - def bundleO(eo: AHBEdgeParameters): AHBBundle = AHBBundle(eo.bundle) - def bundleI(ei: AHBEdgeParameters): AHBBundle = AHBBundle(ei.bundle) + def edge(pd: AHBMasterPortParameters, pu: AHBSlavePortParameters, p: Parameters, sourceInfo: SourceInfo): AHBEdgeParameters = AHBEdgeParameters(pd, pu, p, sourceInfo) + def bundle(e: AHBEdgeParameters): AHBBundle = AHBBundle(e.bundle) def colour = "#00ccff" // bluish - override def labelI(ei: AHBEdgeParameters) = (ei.slave.beatBytes * 8).toString - override def labelO(eo: AHBEdgeParameters) = (eo.slave.beatBytes * 8).toString + override def label(e: AHBEdgeParameters) = (e.slave.beatBytes * 8).toString override def mixO(pd: AHBMasterPortParameters, node: OutwardNode[AHBMasterPortParameters, AHBSlavePortParameters, AHBBundle]): AHBMasterPortParameters = pd.copy(masters = pd.masters.map { c => c.copy (nodePath = node +: c.nodePath) }) diff --git a/src/main/scala/amba/apb/Nodes.scala b/src/main/scala/amba/apb/Nodes.scala index 59acd587..117b3529 100644 --- a/src/main/scala/amba/apb/Nodes.scala +++ b/src/main/scala/amba/apb/Nodes.scala @@ -7,17 +7,13 @@ import chisel3.internal.sourceinfo.SourceInfo import freechips.rocketchip.config.Parameters import freechips.rocketchip.diplomacy._ -object APBImp extends NodeImp[APBMasterPortParameters, APBSlavePortParameters, APBEdgeParameters, APBEdgeParameters, APBBundle] +object APBImp extends SimpleNodeImp[APBMasterPortParameters, APBSlavePortParameters, APBEdgeParameters, APBBundle] { - def edgeO(pd: APBMasterPortParameters, pu: APBSlavePortParameters, p: Parameters, sourceInfo: SourceInfo): APBEdgeParameters = APBEdgeParameters(pd, pu, p, sourceInfo) - def edgeI(pd: APBMasterPortParameters, pu: APBSlavePortParameters, p: Parameters, sourceInfo: SourceInfo): APBEdgeParameters = APBEdgeParameters(pd, pu, p, sourceInfo) - - def bundleO(eo: APBEdgeParameters): APBBundle = APBBundle(eo.bundle) - def bundleI(ei: APBEdgeParameters): APBBundle = APBBundle(ei.bundle) + def edge(pd: APBMasterPortParameters, pu: APBSlavePortParameters, p: Parameters, sourceInfo: SourceInfo): APBEdgeParameters = APBEdgeParameters(pd, pu, p, sourceInfo) + def bundle(e: APBEdgeParameters): APBBundle = APBBundle(e.bundle) def colour = "#00ccff" // bluish - override def labelI(ei: APBEdgeParameters) = (ei.slave.beatBytes * 8).toString - override def labelO(eo: APBEdgeParameters) = (eo.slave.beatBytes * 8).toString + override def label(e: APBEdgeParameters) = (e.slave.beatBytes * 8).toString override def mixO(pd: APBMasterPortParameters, node: OutwardNode[APBMasterPortParameters, APBSlavePortParameters, APBBundle]): APBMasterPortParameters = pd.copy(masters = pd.masters.map { c => c.copy (nodePath = node +: c.nodePath) }) diff --git a/src/main/scala/amba/axi4/Nodes.scala b/src/main/scala/amba/axi4/Nodes.scala index 89d9fce8..683981e4 100644 --- a/src/main/scala/amba/axi4/Nodes.scala +++ b/src/main/scala/amba/axi4/Nodes.scala @@ -7,17 +7,13 @@ import chisel3.internal.sourceinfo.SourceInfo import freechips.rocketchip.config.Parameters import freechips.rocketchip.diplomacy._ -object AXI4Imp extends NodeImp[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4EdgeParameters, AXI4EdgeParameters, AXI4Bundle] +object AXI4Imp extends SimpleNodeImp[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4EdgeParameters, AXI4Bundle] { - def edgeO(pd: AXI4MasterPortParameters, pu: AXI4SlavePortParameters, p: Parameters, sourceInfo: SourceInfo): AXI4EdgeParameters = AXI4EdgeParameters(pd, pu, p, sourceInfo) - def edgeI(pd: AXI4MasterPortParameters, pu: AXI4SlavePortParameters, p: Parameters, sourceInfo: SourceInfo): AXI4EdgeParameters = AXI4EdgeParameters(pd, pu, p, sourceInfo) - - def bundleO(eo: AXI4EdgeParameters): AXI4Bundle = AXI4Bundle(eo.bundle) - def bundleI(ei: AXI4EdgeParameters): AXI4Bundle = AXI4Bundle(ei.bundle) + def edge(pd: AXI4MasterPortParameters, pu: AXI4SlavePortParameters, p: Parameters, sourceInfo: SourceInfo): AXI4EdgeParameters = AXI4EdgeParameters(pd, pu, p, sourceInfo) + def bundle(e: AXI4EdgeParameters): AXI4Bundle = AXI4Bundle(e.bundle) def colour = "#00ccff" // bluish - override def labelI(ei: AXI4EdgeParameters) = (ei.slave.beatBytes * 8).toString - override def labelO(eo: AXI4EdgeParameters) = (eo.slave.beatBytes * 8).toString + override def label(e: AXI4EdgeParameters) = (e.slave.beatBytes * 8).toString override def mixO(pd: AXI4MasterPortParameters, node: OutwardNode[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4Bundle]): AXI4MasterPortParameters = pd.copy(masters = pd.masters.map { c => c.copy (nodePath = node +: c.nodePath) }) diff --git a/src/main/scala/diplomacy/Nodes.scala b/src/main/scala/diplomacy/Nodes.scala index 0afd9830..3d4263d1 100644 --- a/src/main/scala/diplomacy/Nodes.scala +++ b/src/main/scala/diplomacy/Nodes.scala @@ -65,6 +65,21 @@ trait OutwardNodeImp[DO, UO, EO, BO <: Data] abstract class NodeImp[D, U, EO, EI, B <: Data] extends Object with InwardNodeImp[D, U, EI, B] with OutwardNodeImp[D, U, EO, B] +// If your edges have the same direction, using this saves you some typing +abstract class SimpleNodeImp[D, U, E, B <: Data] + extends NodeImp[D, U, E, E, B] +{ + def edge(pd: D, pu: U, p: Parameters, sourceInfo: SourceInfo): E + def edgeO(pd: D, pu: U, p: Parameters, sourceInfo: SourceInfo) = edge(pd, pu, p, sourceInfo) + def edgeI(pd: D, pu: U, p: Parameters, sourceInfo: SourceInfo) = edge(pd, pu, p, sourceInfo) + def bundle(e: E): B + def bundleO(e: E) = bundle(e) + def bundleI(e: E) = bundle(e) + def label(e: E): String = "" + override def labelO(e: E) = label(e) + override def labelI(e: E) = label(e) +} + abstract class BaseNode(implicit val valName: ValName) { require (!LazyModule.stack.isEmpty, "You cannot create a node outside a LazyModule!") diff --git a/src/main/scala/tilelink/IntNodes.scala b/src/main/scala/tilelink/IntNodes.scala index c0339b77..60b186dc 100644 --- a/src/main/scala/tilelink/IntNodes.scala +++ b/src/main/scala/tilelink/IntNodes.scala @@ -63,17 +63,14 @@ object IntSinkPortSimple case class IntEdge(source: IntSourcePortParameters, sink: IntSinkPortParameters, params: Parameters, sourceInfo: SourceInfo) -object IntImp extends NodeImp[IntSourcePortParameters, IntSinkPortParameters, IntEdge, IntEdge, Vec[Bool]] +object IntImp extends SimpleNodeImp[IntSourcePortParameters, IntSinkPortParameters, IntEdge, Vec[Bool]] { - def edgeO(pd: IntSourcePortParameters, pu: IntSinkPortParameters, p: Parameters, sourceInfo: SourceInfo): IntEdge = IntEdge(pd, pu, p, sourceInfo) - def edgeI(pd: IntSourcePortParameters, pu: IntSinkPortParameters, p: Parameters, sourceInfo: SourceInfo): IntEdge = IntEdge(pd, pu, p, sourceInfo) - def bundleO(eo: IntEdge): Vec[Bool] = Vec(eo.source.num, Bool()) - def bundleI(ei: IntEdge): Vec[Bool] = Vec(ei.source.num, Bool()) + def edge(pd: IntSourcePortParameters, pu: IntSinkPortParameters, p: Parameters, sourceInfo: SourceInfo): IntEdge = IntEdge(pd, pu, p, sourceInfo) + def bundle(e: IntEdge): Vec[Bool] = Vec(e.source.num, Bool()) def colour = "#0000ff" // blue override def reverse = true - override def labelI(ei: IntEdge) = ei.source.sources.map(_.range.size).sum.toString - override def labelO(eo: IntEdge) = eo.source.sources.map(_.range.size).sum.toString + override def label(e: IntEdge) = e.source.sources.map(_.range.size).sum.toString override def mixO(pd: IntSourcePortParameters, node: OutwardNode[IntSourcePortParameters, IntSinkPortParameters, Vec[Bool]]): IntSourcePortParameters = pd.copy(sources = pd.sources.map { s => s.copy (nodePath = node +: s.nodePath) }) diff --git a/src/main/scala/tilelink/Nodes.scala b/src/main/scala/tilelink/Nodes.scala index 499b89cb..be5281e7 100644 --- a/src/main/scala/tilelink/Nodes.scala +++ b/src/main/scala/tilelink/Nodes.scala @@ -74,17 +74,13 @@ abstract class TLCustomNode( // Asynchronous crossings -object TLAsyncImp extends NodeImp[TLAsyncClientPortParameters, TLAsyncManagerPortParameters, TLAsyncEdgeParameters, TLAsyncEdgeParameters, TLAsyncBundle] +object TLAsyncImp extends SimpleNodeImp[TLAsyncClientPortParameters, TLAsyncManagerPortParameters, TLAsyncEdgeParameters, TLAsyncBundle] { - def edgeO(pd: TLAsyncClientPortParameters, pu: TLAsyncManagerPortParameters, p: Parameters, sourceInfo: SourceInfo): TLAsyncEdgeParameters = TLAsyncEdgeParameters(pd, pu, p, sourceInfo) - def edgeI(pd: TLAsyncClientPortParameters, pu: TLAsyncManagerPortParameters, p: Parameters, sourceInfo: SourceInfo): TLAsyncEdgeParameters = TLAsyncEdgeParameters(pd, pu, p, sourceInfo) - - def bundleO(eo: TLAsyncEdgeParameters): TLAsyncBundle = new TLAsyncBundle(eo.bundle) - def bundleI(ei: TLAsyncEdgeParameters): TLAsyncBundle = new TLAsyncBundle(ei.bundle) + def edge(pd: TLAsyncClientPortParameters, pu: TLAsyncManagerPortParameters, p: Parameters, sourceInfo: SourceInfo): TLAsyncEdgeParameters = TLAsyncEdgeParameters(pd, pu, p, sourceInfo) + def bundle(e: TLAsyncEdgeParameters): TLAsyncBundle = new TLAsyncBundle(e.bundle) def colour = "#ff0000" // red - override def labelI(ei: TLAsyncEdgeParameters) = ei.manager.depth.toString - override def labelO(eo: TLAsyncEdgeParameters) = eo.manager.depth.toString + override def label(e: TLAsyncEdgeParameters) = e.manager.depth.toString override def mixO(pd: TLAsyncClientPortParameters, node: OutwardNode[TLAsyncClientPortParameters, TLAsyncManagerPortParameters, TLAsyncBundle]): TLAsyncClientPortParameters = pd.copy(base = pd.base.copy(clients = pd.base.clients.map { c => c.copy (nodePath = node +: c.nodePath) })) @@ -113,13 +109,10 @@ case class TLAsyncSinkNode(depth: Int, sync: Int)(implicit valName: ValName) // Rationally related crossings -object TLRationalImp extends NodeImp[TLRationalClientPortParameters, TLRationalManagerPortParameters, TLRationalEdgeParameters, TLRationalEdgeParameters, TLRationalBundle] +object TLRationalImp extends SimpleNodeImp[TLRationalClientPortParameters, TLRationalManagerPortParameters, TLRationalEdgeParameters, TLRationalBundle] { - def edgeO(pd: TLRationalClientPortParameters, pu: TLRationalManagerPortParameters, p: Parameters, sourceInfo: SourceInfo): TLRationalEdgeParameters = TLRationalEdgeParameters(pd, pu, p, sourceInfo) - def edgeI(pd: TLRationalClientPortParameters, pu: TLRationalManagerPortParameters, p: Parameters, sourceInfo: SourceInfo): TLRationalEdgeParameters = TLRationalEdgeParameters(pd, pu, p, sourceInfo) - - def bundleO(eo: TLRationalEdgeParameters): TLRationalBundle = new TLRationalBundle(eo.bundle) - def bundleI(ei: TLRationalEdgeParameters): TLRationalBundle = new TLRationalBundle(ei.bundle) + def edge(pd: TLRationalClientPortParameters, pu: TLRationalManagerPortParameters, p: Parameters, sourceInfo: SourceInfo): TLRationalEdgeParameters = TLRationalEdgeParameters(pd, pu, p, sourceInfo) + def bundle(e: TLRationalEdgeParameters): TLRationalBundle = new TLRationalBundle(e.bundle) def colour = "#00ff00" // green From a27e853101371e8651b8683954290d360857286a Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Tue, 26 Sep 2017 13:23:54 -0700 Subject: [PATCH 21/32] diplomacy: move rendering properties to edges FlipRendering { implicit p => ... } now changes the render direction of edges. diplomatic NodeImps can specify a default render flip using the new 'render' method. --- src/main/scala/amba/ahb/Nodes.scala | 8 ++--- src/main/scala/amba/apb/Nodes.scala | 8 ++--- src/main/scala/amba/axi4/Nodes.scala | 8 ++--- src/main/scala/coreplex/RocketCoreplex.scala | 6 ++-- src/main/scala/diplomacy/LazyModule.scala | 11 +++---- src/main/scala/diplomacy/Nodes.scala | 31 ++++++++++---------- src/main/scala/diplomacy/package.scala | 3 ++ src/main/scala/tile/RocketTile.scala | 26 +++++----------- src/main/scala/tilelink/IntNodes.scala | 9 ++---- src/main/scala/tilelink/Nodes.scala | 27 +++++++---------- 10 files changed, 59 insertions(+), 78 deletions(-) diff --git a/src/main/scala/amba/ahb/Nodes.scala b/src/main/scala/amba/ahb/Nodes.scala index 16a2c884..c104f9d9 100644 --- a/src/main/scala/amba/ahb/Nodes.scala +++ b/src/main/scala/amba/ahb/Nodes.scala @@ -9,11 +9,9 @@ import freechips.rocketchip.diplomacy._ object AHBImp extends SimpleNodeImp[AHBMasterPortParameters, AHBSlavePortParameters, AHBEdgeParameters, AHBBundle] { - def edge(pd: AHBMasterPortParameters, pu: AHBSlavePortParameters, p: Parameters, sourceInfo: SourceInfo): AHBEdgeParameters = AHBEdgeParameters(pd, pu, p, sourceInfo) - def bundle(e: AHBEdgeParameters): AHBBundle = AHBBundle(e.bundle) - - def colour = "#00ccff" // bluish - override def label(e: AHBEdgeParameters) = (e.slave.beatBytes * 8).toString + def edge(pd: AHBMasterPortParameters, pu: AHBSlavePortParameters, p: Parameters, sourceInfo: SourceInfo) = AHBEdgeParameters(pd, pu, p, sourceInfo) + def bundle(e: AHBEdgeParameters) = AHBBundle(e.bundle) + def render(e: AHBEdgeParameters) = RenderedEdge(colour = "#00ccff" /* bluish */, label = (e.slave.beatBytes * 8).toString) override def mixO(pd: AHBMasterPortParameters, node: OutwardNode[AHBMasterPortParameters, AHBSlavePortParameters, AHBBundle]): AHBMasterPortParameters = pd.copy(masters = pd.masters.map { c => c.copy (nodePath = node +: c.nodePath) }) diff --git a/src/main/scala/amba/apb/Nodes.scala b/src/main/scala/amba/apb/Nodes.scala index 117b3529..47e67dbc 100644 --- a/src/main/scala/amba/apb/Nodes.scala +++ b/src/main/scala/amba/apb/Nodes.scala @@ -9,11 +9,9 @@ import freechips.rocketchip.diplomacy._ object APBImp extends SimpleNodeImp[APBMasterPortParameters, APBSlavePortParameters, APBEdgeParameters, APBBundle] { - def edge(pd: APBMasterPortParameters, pu: APBSlavePortParameters, p: Parameters, sourceInfo: SourceInfo): APBEdgeParameters = APBEdgeParameters(pd, pu, p, sourceInfo) - def bundle(e: APBEdgeParameters): APBBundle = APBBundle(e.bundle) - - def colour = "#00ccff" // bluish - override def label(e: APBEdgeParameters) = (e.slave.beatBytes * 8).toString + def edge(pd: APBMasterPortParameters, pu: APBSlavePortParameters, p: Parameters, sourceInfo: SourceInfo) = APBEdgeParameters(pd, pu, p, sourceInfo) + def bundle(e: APBEdgeParameters) = APBBundle(e.bundle) + def render(e: APBEdgeParameters) = RenderedEdge(colour = "#00ccff" /* bluish */, (e.slave.beatBytes * 8).toString) override def mixO(pd: APBMasterPortParameters, node: OutwardNode[APBMasterPortParameters, APBSlavePortParameters, APBBundle]): APBMasterPortParameters = pd.copy(masters = pd.masters.map { c => c.copy (nodePath = node +: c.nodePath) }) diff --git a/src/main/scala/amba/axi4/Nodes.scala b/src/main/scala/amba/axi4/Nodes.scala index 683981e4..1227f710 100644 --- a/src/main/scala/amba/axi4/Nodes.scala +++ b/src/main/scala/amba/axi4/Nodes.scala @@ -9,11 +9,9 @@ import freechips.rocketchip.diplomacy._ object AXI4Imp extends SimpleNodeImp[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4EdgeParameters, AXI4Bundle] { - def edge(pd: AXI4MasterPortParameters, pu: AXI4SlavePortParameters, p: Parameters, sourceInfo: SourceInfo): AXI4EdgeParameters = AXI4EdgeParameters(pd, pu, p, sourceInfo) - def bundle(e: AXI4EdgeParameters): AXI4Bundle = AXI4Bundle(e.bundle) - - def colour = "#00ccff" // bluish - override def label(e: AXI4EdgeParameters) = (e.slave.beatBytes * 8).toString + def edge(pd: AXI4MasterPortParameters, pu: AXI4SlavePortParameters, p: Parameters, sourceInfo: SourceInfo) = AXI4EdgeParameters(pd, pu, p, sourceInfo) + def bundle(e: AXI4EdgeParameters) = AXI4Bundle(e.bundle) + def render(e: AXI4EdgeParameters) = RenderedEdge(colour = "#00ccff" /* bluish */, label = (e.slave.beatBytes * 8).toString) override def mixO(pd: AXI4MasterPortParameters, node: OutwardNode[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4Bundle]): AXI4MasterPortParameters = pd.copy(masters = pd.masters.map { c => c.copy (nodePath = node +: c.nodePath) }) diff --git a/src/main/scala/coreplex/RocketCoreplex.scala b/src/main/scala/coreplex/RocketCoreplex.scala index 7532cf31..04689407 100644 --- a/src/main/scala/coreplex/RocketCoreplex.scala +++ b/src/main/scala/coreplex/RocketCoreplex.scala @@ -46,19 +46,19 @@ trait HasRocketTiles extends HasSystemBus case SynchronousCrossing(params) => { val wrapper = LazyModule(new SyncRocketTile(tp, i)(pWithExtra)) sbus.fromSyncTiles(params, tp.externalMasterBuffers, tp.name) :=* wrapper.masterNode - wrapper.slaveNode :*= pbus.toSyncSlaves(tp.name, tp.externalSlaveBuffers) + FlipRendering { implicit p => wrapper.slaveNode :*= pbus.toSyncSlaves(tp.name, tp.externalSlaveBuffers) } wrapper } case AsynchronousCrossing(depth, sync) => { val wrapper = LazyModule(new AsyncRocketTile(tp, i)(pWithExtra)) sbus.fromAsyncTiles(depth, sync, tp.externalMasterBuffers, tp.name) :=* wrapper.masterNode - wrapper.slaveNode :*= pbus.toAsyncSlaves(sync, tp.name, tp.externalSlaveBuffers) + FlipRendering { implicit p => wrapper.slaveNode :*= pbus.toAsyncSlaves(sync, tp.name, tp.externalSlaveBuffers) } wrapper } case RationalCrossing(direction) => { val wrapper = LazyModule(new RationalRocketTile(tp, i)(pWithExtra)) sbus.fromRationalTiles(direction, tp.externalMasterBuffers, tp.name) :=* wrapper.masterNode - wrapper.slaveNode :*= pbus.toRationalSlaves(tp.name, tp.externalSlaveBuffers) + FlipRendering { implicit p => wrapper.slaveNode :*= pbus.toRationalSlaves(tp.name, tp.externalSlaveBuffers) } wrapper } } diff --git a/src/main/scala/diplomacy/LazyModule.scala b/src/main/scala/diplomacy/LazyModule.scala index 2337e95a..2d8cc512 100644 --- a/src/main/scala/diplomacy/LazyModule.scala +++ b/src/main/scala/diplomacy/LazyModule.scala @@ -88,10 +88,11 @@ abstract class LazyModule()(implicit val p: Parameters) buf ++= s"""${pad}\n""" } private def edgesGraphML(buf: StringBuilder, pad: String) { - nodes.filter(!_.omitGraphML) foreach { n => n.outputs.filter(!_._1.omitGraphML).foreach { case (o, l) => + nodes.filter(!_.omitGraphML) foreach { n => n.outputs.filter(!_._1.omitGraphML).foreach { case (o, edge) => + val RenderedEdge(colour, label, flipped) = edge buf ++= pad buf ++= """" } else { @@ -99,13 +100,13 @@ abstract class LazyModule()(implicit val p: Parameters) buf ++= s""" target=\"${o.lazyModule.index}::${o.index}\">""" } buf ++= s"""""" - if (o.reverse) { + if (flipped) { buf ++= s"""""" } else { buf ++= s"""""" } - buf ++= s"""""" - buf ++= s"""${l}""" + buf ++= s"""""" + buf ++= s"""${label}""" buf ++= s"""\n""" } } children.filter(!_.omitGraphML).foreach { c => c.edgesGraphML(buf, pad) } diff --git a/src/main/scala/diplomacy/Nodes.scala b/src/main/scala/diplomacy/Nodes.scala index 3d4263d1..626b7b8c 100644 --- a/src/main/scala/diplomacy/Nodes.scala +++ b/src/main/scala/diplomacy/Nodes.scala @@ -28,6 +28,12 @@ private case object CardinalityInferenceDirectionKey extends Field[CardinalityInferenceDirection.T](CardinalityInferenceDirection.NO_INFERENCE) private case object MonitorsEnabled extends Field[Boolean](true) +private case object RenderFlipped extends Field[Boolean](false) + +case class RenderedEdge( + colour: String, + label: String = "", + flipped: Boolean = false) // prefer to draw the arrow pointing the opposite direction of other edges // DI = Downwards flowing Parameters received on the inner side of the node // UI = Upwards flowing Parameters generated by the inner side of the node @@ -37,14 +43,14 @@ trait InwardNodeImp[DI, UI, EI, BI <: Data] { def edgeI(pd: DI, pu: UI, p: Parameters, sourceInfo: SourceInfo): EI def bundleI(ei: EI): BI + + // Edge functions def monitor(bundle: BI, edge: EI) {} - def colour: String - def reverse: Boolean = false + def render(e: EI): RenderedEdge // optional methods to track node graph def mixI(pu: UI, node: InwardNode[DI, UI, BI]): UI = pu // insert node into parameters def getO(pu: UI): Option[BaseNode] = None // most-outward common node - def labelI(ei: EI) = "" } // DO = Downwards flowing Parameters generated by the outer side of the node @@ -59,7 +65,6 @@ trait OutwardNodeImp[DO, UO, EO, BO <: Data] // optional methods to track node graph def mixO(pd: DO, node: OutwardNode[DO, UO, BO]): DO = pd // insert node into parameters def getI(pd: DO): Option[BaseNode] = None // most-inward common node - def labelO(eo: EO) = "" } abstract class NodeImp[D, U, EO, EI, B <: Data] @@ -75,9 +80,6 @@ abstract class SimpleNodeImp[D, U, E, B <: Data] def bundle(e: E): B def bundleO(e: E) = bundle(e) def bundleI(e: E) = bundle(e) - def label(e: E): String = "" - override def labelO(e: E) = label(e) - override def labelI(e: E) = label(e) } abstract class BaseNode(implicit val valName: ValName) @@ -106,10 +108,8 @@ abstract class BaseNode(implicit val valName: ValName) protected[diplomacy] def gci: Option[BaseNode] // greatest common inner protected[diplomacy] def gco: Option[BaseNode] // greatest common outer - protected[diplomacy] def outputs: Seq[(BaseNode, String)] - protected[diplomacy] def inputs: Seq[(BaseNode, String)] - protected[diplomacy] def colour: String - protected[diplomacy] def reverse: Boolean + protected[diplomacy] def inputs: Seq[(BaseNode, RenderedEdge)] + protected[diplomacy] def outputs: Seq[(BaseNode, RenderedEdge)] } object BaseNode @@ -333,10 +333,11 @@ sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( } // meta-data for printing the node graph - protected[diplomacy] def colour = inner.colour - protected[diplomacy] def reverse = inner.reverse - protected[diplomacy] def outputs = oPorts.map(_._2) zip edgesOut.map(e => outer.labelO(e)) - protected[diplomacy] def inputs = iPorts.map(_._2) zip edgesIn .map(e => inner.labelI(e)) + protected[diplomacy] def inputs = (iPorts zip edgesIn) map { case ((_, n, p, _), e) => + val re = inner.render(e) + (n, re.copy(flipped = re.flipped != p(RenderFlipped))) + } + protected[diplomacy] def outputs = oPorts map { case (i, n, _, _) => (n, n.inputs(i)._2) } } abstract class MixedCustomNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( diff --git a/src/main/scala/diplomacy/package.scala b/src/main/scala/diplomacy/package.scala index 713396bb..1ac46a24 100644 --- a/src/main/scala/diplomacy/package.scala +++ b/src/main/scala/diplomacy/package.scala @@ -47,4 +47,7 @@ package object diplomacy def DisableMonitors[T](body: Parameters => T)(implicit p: Parameters) = body(p.alterPartial { case MonitorsEnabled => false }) + def FlipRendering[T](body: Parameters => T)(implicit p: Parameters) = body(p.alterPartial { + case RenderFlipped => !p(RenderFlipped) + }) } diff --git a/src/main/scala/tile/RocketTile.scala b/src/main/scala/tile/RocketTile.scala index 4b68c949..8f5ca043 100644 --- a/src/main/scala/tile/RocketTile.scala +++ b/src/main/scala/tile/RocketTile.scala @@ -199,13 +199,13 @@ abstract class RocketTileWrapper(rtp: RocketTileParams, hartid: Int)(implicit p: } } - def optionalSlaveBuffer(in: TLOutwardNode): TLOutwardNode = { + def optionalSlaveBuffer(out: TLInwardNode): TLInwardNode = { if (rtp.boundaryBuffers) { val sbuf = LazyModule(new TLBuffer(BufferParams.flow, BufferParams.none, BufferParams.none, BufferParams.none, BufferParams.none)) - DisableMonitors { implicit p => sbuf.node :*= in } + DisableMonitors { implicit p => out :*= sbuf.node } sbuf.node } else { - in + out } } @@ -234,9 +234,7 @@ abstract class RocketTileWrapper(rtp: RocketTileParams, hartid: Int)(implicit p: class SyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends RocketTileWrapper(rtp, hartid) { val masterNode = optionalMasterBuffer(rocket.masterNode) - - val slaveNode = new TLIdentityNode() { override def reverse = true } - DisableMonitors { implicit p => rocket.slaveNode :*= optionalSlaveBuffer(slaveNode) } + val slaveNode = optionalSlaveBuffer(rocket.slaveNode) // Fully async interrupts need synchronizers. // Others need no synchronization. @@ -259,13 +257,9 @@ class AsyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters source.node :=* rocket.masterNode val masterNode = source.node - val slaveNode = new TLAsyncIdentityNode() { override def reverse = true } val sink = LazyModule(new TLAsyncCrossingSink) - - DisableMonitors { implicit p => - rocket.slaveNode :*= sink.node - sink.node :*= slaveNode - } + DisableMonitors { implicit p => rocket.slaveNode :*= sink.node } + val slaveNode = sink.node // Fully async interrupts need synchronizers, // as do those coming from the periphery clock. @@ -289,13 +283,9 @@ class RationalRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Paramet source.node :=* optionalMasterBuffer(rocket.masterNode) val masterNode = source.node - val slaveNode = new TLRationalIdentityNode() { override def reverse = true } val sink = LazyModule(new TLRationalCrossingSink(SlowToFast)) - - DisableMonitors { implicit p => - sink.node :*= slaveNode - rocket.slaveNode :*= optionalSlaveBuffer(sink.node) - } + DisableMonitors { implicit p => optionalSlaveBuffer(rocket.slaveNode) :*= sink.node } + val slaveNode = sink.node // Fully async interrupts need synchronizers. // Those coming from periphery clock need a diff --git a/src/main/scala/tilelink/IntNodes.scala b/src/main/scala/tilelink/IntNodes.scala index 60b186dc..2cc6aa61 100644 --- a/src/main/scala/tilelink/IntNodes.scala +++ b/src/main/scala/tilelink/IntNodes.scala @@ -65,12 +65,9 @@ case class IntEdge(source: IntSourcePortParameters, sink: IntSinkPortParameters, object IntImp extends SimpleNodeImp[IntSourcePortParameters, IntSinkPortParameters, IntEdge, Vec[Bool]] { - def edge(pd: IntSourcePortParameters, pu: IntSinkPortParameters, p: Parameters, sourceInfo: SourceInfo): IntEdge = IntEdge(pd, pu, p, sourceInfo) - def bundle(e: IntEdge): Vec[Bool] = Vec(e.source.num, Bool()) - - def colour = "#0000ff" // blue - override def reverse = true - override def label(e: IntEdge) = e.source.sources.map(_.range.size).sum.toString + def edge(pd: IntSourcePortParameters, pu: IntSinkPortParameters, p: Parameters, sourceInfo: SourceInfo) = IntEdge(pd, pu, p, sourceInfo) + def bundle(e: IntEdge) = Vec(e.source.num, Bool()) + def render(e: IntEdge) = RenderedEdge(colour = "#0000ff" /* blue */, label = e.source.sources.map(_.range.size).sum.toString, flipped = true) override def mixO(pd: IntSourcePortParameters, node: OutwardNode[IntSourcePortParameters, IntSinkPortParameters, Vec[Bool]]): IntSourcePortParameters = pd.copy(sources = pd.sources.map { s => s.copy (nodePath = node +: s.nodePath) }) diff --git a/src/main/scala/tilelink/Nodes.scala b/src/main/scala/tilelink/Nodes.scala index be5281e7..605c1662 100644 --- a/src/main/scala/tilelink/Nodes.scala +++ b/src/main/scala/tilelink/Nodes.scala @@ -13,15 +13,13 @@ case object TLMonitorBuilder extends Field[TLMonitorArgs => TLMonitorBase](args object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TLEdgeOut, TLEdgeIn, TLBundle] { - def edgeO(pd: TLClientPortParameters, pu: TLManagerPortParameters, p: Parameters, sourceInfo: SourceInfo): TLEdgeOut = new TLEdgeOut(pd, pu, p, sourceInfo) - def edgeI(pd: TLClientPortParameters, pu: TLManagerPortParameters, p: Parameters, sourceInfo: SourceInfo): TLEdgeIn = new TLEdgeIn (pd, pu, p, sourceInfo) + def edgeO(pd: TLClientPortParameters, pu: TLManagerPortParameters, p: Parameters, sourceInfo: SourceInfo) = new TLEdgeOut(pd, pu, p, sourceInfo) + def edgeI(pd: TLClientPortParameters, pu: TLManagerPortParameters, p: Parameters, sourceInfo: SourceInfo) = new TLEdgeIn (pd, pu, p, sourceInfo) - def bundleO(eo: TLEdgeOut): TLBundle = TLBundle(eo.bundle) - def bundleI(ei: TLEdgeIn): TLBundle = TLBundle(ei.bundle) + def bundleO(eo: TLEdgeOut) = TLBundle(eo.bundle) + def bundleI(ei: TLEdgeIn) = TLBundle(ei.bundle) - def colour = "#000000" // black - override def labelI(ei: TLEdgeIn) = (ei.manager.beatBytes * 8).toString - override def labelO(eo: TLEdgeOut) = (eo.manager.beatBytes * 8).toString + def render(ei: TLEdgeIn) = RenderedEdge(colour = "#000000" /* black */, label = (ei.manager.beatBytes * 8).toString) override def monitor(bundle: TLBundle, edge: TLEdgeIn) { val monitor = Module(edge.params(TLMonitorBuilder)(TLMonitorArgs(edge))) @@ -76,11 +74,9 @@ abstract class TLCustomNode( object TLAsyncImp extends SimpleNodeImp[TLAsyncClientPortParameters, TLAsyncManagerPortParameters, TLAsyncEdgeParameters, TLAsyncBundle] { - def edge(pd: TLAsyncClientPortParameters, pu: TLAsyncManagerPortParameters, p: Parameters, sourceInfo: SourceInfo): TLAsyncEdgeParameters = TLAsyncEdgeParameters(pd, pu, p, sourceInfo) - def bundle(e: TLAsyncEdgeParameters): TLAsyncBundle = new TLAsyncBundle(e.bundle) - - def colour = "#ff0000" // red - override def label(e: TLAsyncEdgeParameters) = e.manager.depth.toString + def edge(pd: TLAsyncClientPortParameters, pu: TLAsyncManagerPortParameters, p: Parameters, sourceInfo: SourceInfo) = TLAsyncEdgeParameters(pd, pu, p, sourceInfo) + def bundle(e: TLAsyncEdgeParameters) = new TLAsyncBundle(e.bundle) + def render(e: TLAsyncEdgeParameters) = RenderedEdge(colour = "#ff0000" /* red */, label = e.manager.depth.toString) override def mixO(pd: TLAsyncClientPortParameters, node: OutwardNode[TLAsyncClientPortParameters, TLAsyncManagerPortParameters, TLAsyncBundle]): TLAsyncClientPortParameters = pd.copy(base = pd.base.copy(clients = pd.base.clients.map { c => c.copy (nodePath = node +: c.nodePath) })) @@ -111,10 +107,9 @@ case class TLAsyncSinkNode(depth: Int, sync: Int)(implicit valName: ValName) object TLRationalImp extends SimpleNodeImp[TLRationalClientPortParameters, TLRationalManagerPortParameters, TLRationalEdgeParameters, TLRationalBundle] { - def edge(pd: TLRationalClientPortParameters, pu: TLRationalManagerPortParameters, p: Parameters, sourceInfo: SourceInfo): TLRationalEdgeParameters = TLRationalEdgeParameters(pd, pu, p, sourceInfo) - def bundle(e: TLRationalEdgeParameters): TLRationalBundle = new TLRationalBundle(e.bundle) - - def colour = "#00ff00" // green + def edge(pd: TLRationalClientPortParameters, pu: TLRationalManagerPortParameters, p: Parameters, sourceInfo: SourceInfo) = TLRationalEdgeParameters(pd, pu, p, sourceInfo) + def bundle(e: TLRationalEdgeParameters) = new TLRationalBundle(e.bundle) + def render(e: TLRationalEdgeParameters) = RenderedEdge(colour = "#00ff00" /* green */) override def mixO(pd: TLRationalClientPortParameters, node: OutwardNode[TLRationalClientPortParameters, TLRationalManagerPortParameters, TLRationalBundle]): TLRationalClientPortParameters = pd.copy(base = pd.base.copy(clients = pd.base.clients.map { c => c.copy (nodePath = node +: c.nodePath) })) From a2b423d647fdba6960f8b80c11cf46f12cae2c26 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Tue, 26 Sep 2017 14:40:45 -0700 Subject: [PATCH 22/32] diplomacy: add LazyScope to post-hoc add children to a LazyModule --- src/main/scala/diplomacy/LazyModule.scala | 31 +++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/src/main/scala/diplomacy/LazyModule.scala b/src/main/scala/diplomacy/LazyModule.scala index 2d8cc512..f65e4870 100644 --- a/src/main/scala/diplomacy/LazyModule.scala +++ b/src/main/scala/diplomacy/LazyModule.scala @@ -172,16 +172,43 @@ sealed trait LazyModuleImpLike extends BaseModule } } -abstract class LazyModuleImp(val wrapper: LazyModule) extends MultiIOModule with LazyModuleImpLike { +class LazyModuleImp(val wrapper: LazyModule) extends MultiIOModule with LazyModuleImpLike { val (auto, dangles) = instantiate() } -abstract class LazyRawModuleImp(val wrapper: LazyModule) extends RawModule with LazyModuleImpLike { +class LazyRawModuleImp(val wrapper: LazyModule) extends RawModule with LazyModuleImpLike { val (auto, dangles) = withClockAndReset(Bool(false).asClock, Bool(true)) { instantiate() } } +class SimpleLazyModule(implicit p: Parameters) extends LazyModule +{ + lazy val module = new LazyModuleImp(this) +} + +trait LazyScope +{ + this: LazyModule => + def apply[T](body: => T)(implicit p: Parameters) = { + require (!LazyModule.stack.exists(x => x eq this)) + LazyModule.stack = this :: LazyModule.stack + val out = body + require (LazyModule.stack.head eq this) + LazyModule.stack = LazyModule.stack.tail + out + } +} + +object LazyScope +{ + def apply[T](name: String)(body: => T)(implicit p: Parameters) = { + val scope = LazyModule(new SimpleLazyModule with LazyScope) + scope.suggestName(name) + scope { body } + } +} + case class HalfEdge(serial: Int, index: Int) case class Dangle(source: HalfEdge, sink: HalfEdge, flipped: Boolean, name: String, data: Data) From da40573a64619bc942f98188c35436d9be572484 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Tue, 26 Sep 2017 14:56:50 -0700 Subject: [PATCH 23/32] diplomacy: replace LazyModule.stack with an optional scope --- src/main/scala/diplomacy/LazyModule.scala | 23 ++++++++++++----------- src/main/scala/diplomacy/Nodes.scala | 5 ++--- src/main/scala/diplomacy/Resources.scala | 4 ++-- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/main/scala/diplomacy/LazyModule.scala b/src/main/scala/diplomacy/LazyModule.scala index f65e4870..567afd04 100644 --- a/src/main/scala/diplomacy/LazyModule.scala +++ b/src/main/scala/diplomacy/LazyModule.scala @@ -15,9 +15,9 @@ abstract class LazyModule()(implicit val p: Parameters) protected[diplomacy] var children = List[LazyModule]() protected[diplomacy] var nodes = List[BaseNode]() protected[diplomacy] var info: SourceInfo = UnlocatableSourceInfo - protected[diplomacy] val parent = LazyModule.stack.headOption + protected[diplomacy] val parent = LazyModule.scope - LazyModule.stack = this :: LazyModule.stack + LazyModule.scope = Some(this) parent.foreach(p => p.children = this :: p.children) private var suggestedName: Option[String] = None @@ -120,16 +120,16 @@ abstract class LazyModule()(implicit val p: Parameters) object LazyModule { - protected[diplomacy] var stack = List[LazyModule]() + protected[diplomacy] var scope: Option[LazyModule] = None private var index = 0 def apply[T <: LazyModule](bc: T)(implicit sourceInfo: SourceInfo): T = { // Make sure the user put LazyModule around modules in the correct order // If this require fails, probably some grandchild was missing a LazyModule // ... or you applied LazyModule twice - require (!stack.isEmpty, s"LazyModule() applied to ${bc.name} twice ${sourceLine(sourceInfo)}") - require (stack.head eq bc, s"LazyModule() applied to ${bc.name} before ${stack.head.name} ${sourceLine(sourceInfo)}") - stack = stack.tail + require (scope.isDefined, s"LazyModule() applied to ${bc.name} twice ${sourceLine(sourceInfo)}") + require (scope.get eq bc, s"LazyModule() applied to ${bc.name} before ${scope.get.name} ${sourceLine(sourceInfo)}") + scope = bc.parent bc.info = sourceInfo bc } @@ -142,7 +142,7 @@ sealed trait LazyModuleImpLike extends BaseModule protected[diplomacy] val dangles: Seq[Dangle] // .module had better not be accessed while LazyModules are still being built! - require (LazyModule.stack.isEmpty, s"${wrapper.name}.module was constructed before LazyModule() was run on ${LazyModule.stack.head.name}") + require (!LazyModule.scope.isDefined, s"${wrapper.name}.module was constructed before LazyModule() was run on ${LazyModule.scope.get.name}") override def desiredName = wrapper.moduleName suggestName(wrapper.instanceName) @@ -191,11 +191,12 @@ trait LazyScope { this: LazyModule => def apply[T](body: => T)(implicit p: Parameters) = { - require (!LazyModule.stack.exists(x => x eq this)) - LazyModule.stack = this :: LazyModule.stack + val saved = LazyModule.scope + LazyModule.scope = Some(this) val out = body - require (LazyModule.stack.head eq this) - LazyModule.stack = LazyModule.stack.tail + require (LazyModule.scope.isDefined, s"LazyScope ${name} tried to exit, but scope was empty!") + require (LazyModule.scope.get eq this, s"LazyScope ${name} exited before LazyModule ${LazyModule.scope.get.name} was closed") + LazyModule.scope = saved out } } diff --git a/src/main/scala/diplomacy/Nodes.scala b/src/main/scala/diplomacy/Nodes.scala index 626b7b8c..aa858af3 100644 --- a/src/main/scala/diplomacy/Nodes.scala +++ b/src/main/scala/diplomacy/Nodes.scala @@ -84,9 +84,9 @@ abstract class SimpleNodeImp[D, U, E, B <: Data] abstract class BaseNode(implicit val valName: ValName) { - require (!LazyModule.stack.isEmpty, "You cannot create a node outside a LazyModule!") + require (LazyModule.scope.isDefined, "You cannot create a node outside a LazyModule!") - val lazyModule = LazyModule.stack.head + val lazyModule = LazyModule.scope.get val index = lazyModule.nodes.size lazyModule.nodes = this :: lazyModule.nodes @@ -311,7 +311,6 @@ sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( val x = this // x := y val y = h.outward val info = sourceLine(sourceInfo, " at ", "") - require (!LazyModule.stack.isEmpty, s"${y.name} cannot be connected to ${x.name} outside of LazyModule scope" + info) val i = x.iPushed val o = y.oPushed y.oPush(i, x, binding match { diff --git a/src/main/scala/diplomacy/Resources.scala b/src/main/scala/diplomacy/Resources.scala index 6a48e667..d62f829e 100644 --- a/src/main/scala/diplomacy/Resources.scala +++ b/src/main/scala/diplomacy/Resources.scala @@ -179,7 +179,7 @@ trait BindingScope private case class ExpandedValue(path: Seq[String], labels: Seq[String], value: Seq[ResourceValue]) private lazy val eval: Unit = { - require (LazyModule.stack.isEmpty, "May not evaluate binding while still constructing LazyModules") + require (!LazyModule.scope.isDefined, "May not evaluate binding while still constructing LazyModules") parentScope.foreach { _.eval } resourceBindings = parentScope.map(_.resourceBindings).getOrElse(Nil) BindingScope.active = Some(this) @@ -224,7 +224,7 @@ trait BindingScope object BindingScope { protected[diplomacy] var active: Option[BindingScope] = None - protected[diplomacy] def find(m: Option[LazyModule] = LazyModule.stack.headOption): Option[BindingScope] = m.flatMap { + protected[diplomacy] def find(m: Option[LazyModule] = LazyModule.scope): Option[BindingScope] = m.flatMap { case s: BindingScope => Some(s) case x => find(x.parent) } From 31a934bec08124c3aa91706cb812e100d6ded837 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Tue, 26 Sep 2017 14:58:18 -0700 Subject: [PATCH 24/32] coreplex: buses are now LazyModules with LazyScope --- src/main/scala/coreplex/FrontBus.scala | 2 +- src/main/scala/coreplex/MemoryBus.scala | 2 +- src/main/scala/coreplex/PeripheryBus.scala | 2 +- src/main/scala/coreplex/SystemBus.scala | 2 +- src/main/scala/tilelink/Bus.scala | 3 ++- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/scala/coreplex/FrontBus.scala b/src/main/scala/coreplex/FrontBus.scala index 60be007e..98d080bc 100644 --- a/src/main/scala/coreplex/FrontBus.scala +++ b/src/main/scala/coreplex/FrontBus.scala @@ -53,7 +53,7 @@ trait HasFrontBus extends HasSystemBus { private val frontbusParams = p(FrontBusKey) val frontbusBeatBytes = frontbusParams.beatBytes - val fbus = new FrontBus(frontbusParams) + val fbus = LazyModule(new FrontBus(frontbusParams)) sbus.fromFrontBus := fbus.toSystemBus diff --git a/src/main/scala/coreplex/MemoryBus.scala b/src/main/scala/coreplex/MemoryBus.scala index 4127426a..879a08e9 100644 --- a/src/main/scala/coreplex/MemoryBus.scala +++ b/src/main/scala/coreplex/MemoryBus.scala @@ -66,7 +66,7 @@ trait HasMemoryBus extends HasSystemBus with HasPeripheryBus with HasInterruptBu private val (in, out) = coherenceManager(p, this) private val mask = ~BigInt((nBanks-1) * blockBytes) val memBuses = Seq.tabulate(nMemoryChannels) { channel => - val mbus = new MemoryBus(mbusParams) + val mbus = LazyModule(new MemoryBus(mbusParams)) for (bank <- 0 until nBanksPerChannel) { val offset = (bank * nMemoryChannels) + channel ForceFanout(a = true) { implicit p => in := sbus.toMemoryBus } diff --git a/src/main/scala/coreplex/PeripheryBus.scala b/src/main/scala/coreplex/PeripheryBus.scala index 1de255ed..3272a3b1 100644 --- a/src/main/scala/coreplex/PeripheryBus.scala +++ b/src/main/scala/coreplex/PeripheryBus.scala @@ -45,7 +45,7 @@ trait HasPeripheryBus extends HasSystemBus { private val pbusParams = p(PeripheryBusKey) val pbusBeatBytes = pbusParams.beatBytes - val pbus = new PeripheryBus(pbusParams) + val pbus = LazyModule(new PeripheryBus(pbusParams)) // The peripheryBus hangs off of systemBus; here we convert TL-UH -> TL-UL pbus.fromSystemBus := sbus.toPeripheryBus() diff --git a/src/main/scala/coreplex/SystemBus.scala b/src/main/scala/coreplex/SystemBus.scala index 384da306..6721ead8 100644 --- a/src/main/scala/coreplex/SystemBus.scala +++ b/src/main/scala/coreplex/SystemBus.scala @@ -122,7 +122,7 @@ trait HasSystemBus extends HasInterruptBus { private val sbusParams = p(SystemBusKey) val sbusBeatBytes = sbusParams.beatBytes - val sbus = new SystemBus(sbusParams) + val sbus = LazyModule(new SystemBus(sbusParams)) def sharedMemoryTLEdge: TLEdge = sbus.busView def paddrBits: Int = sbus.busView.bundle.addressBits diff --git a/src/main/scala/tilelink/Bus.scala b/src/main/scala/tilelink/Bus.scala index 4abbf5ab..5f2d018b 100644 --- a/src/main/scala/tilelink/Bus.scala +++ b/src/main/scala/tilelink/Bus.scala @@ -21,7 +21,8 @@ trait TLBusParams { def blockOffset: Int = log2Up(blockBytes) } -abstract class TLBusWrapper(params: TLBusParams, val busName: String)(implicit p: Parameters) extends TLBusParams { +abstract class TLBusWrapper(params: TLBusParams, val busName: String)(implicit p: Parameters) + extends SimpleLazyModule with LazyScope with TLBusParams { val beatBytes = params.beatBytes val blockBytes = params.blockBytes From d87536ff8bbb285aae7e5bcff437a1545b3f3430 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Tue, 26 Sep 2017 18:47:16 -0700 Subject: [PATCH 25/32] diplomacy: make NodeHandle recursively composable --- src/main/scala/diplomacy/Nodes.scala | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/scala/diplomacy/Nodes.scala b/src/main/scala/diplomacy/Nodes.scala index aa858af3..46ba6a47 100644 --- a/src/main/scala/diplomacy/Nodes.scala +++ b/src/main/scala/diplomacy/Nodes.scala @@ -119,8 +119,12 @@ object BaseNode // !!! rename the nodes we bind? case class NodeHandle[DI, UI, BI <: Data, DO, UO, BO <: Data] - (inward: InwardNode[DI, UI, BI], outward: OutwardNode[DO, UO, BO]) + (inwardHandle: InwardNodeHandle[DI, UI, BI], outwardHandle: OutwardNodeHandle[DO, UO, BO]) extends Object with InwardNodeHandle[DI, UI, BI] with OutwardNodeHandle[DO, UO, BO] +{ + val inward = inwardHandle.inward + val outward = outwardHandle.outward +} trait InwardNodeHandle[DI, UI, BI <: Data] { From 5af08966d8ed7d3316e4d09182ef62e476302cba Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Wed, 27 Sep 2017 00:57:18 -0700 Subject: [PATCH 26/32] coreplex: fix WithoutTLMonitors closes #1017 --- src/main/scala/coreplex/Configs.scala | 2 +- src/main/scala/diplomacy/Nodes.scala | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/scala/coreplex/Configs.scala b/src/main/scala/coreplex/Configs.scala index 563f6f85..44dbcadd 100644 --- a/src/main/scala/coreplex/Configs.scala +++ b/src/main/scala/coreplex/Configs.scala @@ -270,7 +270,7 @@ class WithNBitPeripheryBus(nBits: Int) extends Config ((site, here, up) => { }) class WithoutTLMonitors extends Config ((site, here, up) => { - case TLMonitorBuilder => (args: TLMonitorArgs) => None + case MonitorsEnabled => false }) class WithNExtTopInterrupts(nExtInts: Int) extends Config((site, here, up) => { diff --git a/src/main/scala/diplomacy/Nodes.scala b/src/main/scala/diplomacy/Nodes.scala index 46ba6a47..2d67584c 100644 --- a/src/main/scala/diplomacy/Nodes.scala +++ b/src/main/scala/diplomacy/Nodes.scala @@ -27,8 +27,8 @@ object CardinalityInferenceDirection { private case object CardinalityInferenceDirectionKey extends Field[CardinalityInferenceDirection.T](CardinalityInferenceDirection.NO_INFERENCE) -private case object MonitorsEnabled extends Field[Boolean](true) -private case object RenderFlipped extends Field[Boolean](false) +case object MonitorsEnabled extends Field[Boolean](true) +case object RenderFlipped extends Field[Boolean](false) case class RenderedEdge( colour: String, From e35d3df6eabc67851f46203649caaa9d263ae3ba Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Wed, 27 Sep 2017 11:46:06 -0700 Subject: [PATCH 27/32] diplomacy: detect and report cycles in the diplomatic graph --- src/main/scala/diplomacy/Nodes.scala | 86 ++++++++++++++++++---------- 1 file changed, 56 insertions(+), 30 deletions(-) diff --git a/src/main/scala/diplomacy/Nodes.scala b/src/main/scala/diplomacy/Nodes.scala index 2d67584c..40da6ab3 100644 --- a/src/main/scala/diplomacy/Nodes.scala +++ b/src/main/scala/diplomacy/Nodes.scala @@ -199,6 +199,11 @@ trait OutwardNode[DO, UO, BO <: Data] extends BaseNode with OutwardNodeHandle[DO protected[diplomacy] val oParams: Seq[DO] } +abstract class CycleException(kind: String, loop: Seq[String]) extends Exception(s"Diplomatic ${kind} cycle detected involving ${loop}") +case class StarCycleException(loop: Seq[String] = Nil) extends CycleException("star", loop) +case class DownwardCycleException(loop: Seq[String] = Nil) extends CycleException("downward", loop) +case class UpwardCycleException(loop: Seq[String] = Nil) extends CycleException("upward", loop) + case class Edges[EI, EO](in: EI, out: EO) sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( inner: InwardNodeImp [DI, UI, EI, BI], @@ -212,31 +217,37 @@ sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( protected[diplomacy] def mapParamsD(n: Int, p: Seq[DI]): Seq[DO] protected[diplomacy] def mapParamsU(n: Int, p: Seq[UO]): Seq[UI] + private var starCycleGuard = false protected[diplomacy] lazy val (oPortMapping, iPortMapping, oStar, iStar) = { - val oStars = oBindings.filter { case (_,_,b,_,_) => b == BIND_STAR }.size - val iStars = iBindings.filter { case (_,_,b,_,_) => b == BIND_STAR }.size - val oKnown = oBindings.map { case (_, n, b, _, _) => b match { - case BIND_ONCE => 1 - case BIND_QUERY => n.iStar - case BIND_STAR => 0 }}.foldLeft(0)(_+_) - val iKnown = iBindings.map { case (_, n, b, _, _) => b match { - case BIND_ONCE => 1 - case BIND_QUERY => n.oStar - case BIND_STAR => 0 }}.foldLeft(0)(_+_) - val (iStar, oStar) = resolveStar(iKnown, oKnown, iStars, oStars) - val oSum = oBindings.map { case (_, n, b, _, _) => b match { - case BIND_ONCE => 1 - case BIND_QUERY => n.iStar - case BIND_STAR => oStar }}.scanLeft(0)(_+_) - val iSum = iBindings.map { case (_, n, b, _, _) => b match { - case BIND_ONCE => 1 - case BIND_QUERY => n.oStar - case BIND_STAR => iStar }}.scanLeft(0)(_+_) - val oTotal = oSum.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) + try { + if (starCycleGuard) throw StarCycleException() + val oStars = oBindings.filter { case (_,_,b,_,_) => b == BIND_STAR }.size + val iStars = iBindings.filter { case (_,_,b,_,_) => b == BIND_STAR }.size + val oKnown = oBindings.map { case (_, n, b, _, _) => b match { + case BIND_ONCE => 1 + case BIND_QUERY => n.iStar + case BIND_STAR => 0 }}.foldLeft(0)(_+_) + val iKnown = iBindings.map { case (_, n, b, _, _) => b match { + case BIND_ONCE => 1 + case BIND_QUERY => n.oStar + case BIND_STAR => 0 }}.foldLeft(0)(_+_) + val (iStar, oStar) = resolveStar(iKnown, oKnown, iStars, oStars) + val oSum = oBindings.map { case (_, n, b, _, _) => b match { + case BIND_ONCE => 1 + case BIND_QUERY => n.iStar + case BIND_STAR => oStar }}.scanLeft(0)(_+_) + val iSum = iBindings.map { case (_, n, b, _, _) => b match { + case BIND_ONCE => 1 + case BIND_QUERY => n.oStar + case BIND_STAR => iStar }}.scanLeft(0)(_+_) + val oTotal = oSum.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) + } catch { + case c: StarCycleException => throw c.copy(loop = s"${name}${lazyModule.line}" +: c.loop) + } } lazy val oPorts = oBindings.flatMap { case (i, n, _, p, s) => @@ -248,15 +259,30 @@ sealed abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( (start until end) map { j => (j, n, p, s) } } + private var oParamsCycleGuard = false protected[diplomacy] lazy val oParams: Seq[DO] = { - val o = mapParamsD(oPorts.size, iPorts.map { case (i, n, _, _) => n.oParams(i) }) - require (o.size == oPorts.size, s"Bug in diplomacy; ${name} has ${o.size} != ${oPorts.size} down/up outer parameters${lazyModule.line}") - o.map(outer.mixO(_, this)) + try { + if (oParamsCycleGuard) throw DownwardCycleException() + oParamsCycleGuard = true + val o = mapParamsD(oPorts.size, iPorts.map { case (i, n, _, _) => n.oParams(i) }) + require (o.size == oPorts.size, s"Bug in diplomacy; ${name} has ${o.size} != ${oPorts.size} down/up outer parameters${lazyModule.line}") + o.map(outer.mixO(_, this)) + } catch { + case c: DownwardCycleException => throw c.copy(loop = s"${name}${lazyModule.line}" +: c.loop) + } } + + private var iParamsCycleGuard = false protected[diplomacy] lazy val iParams: Seq[UI] = { - val i = mapParamsU(iPorts.size, oPorts.map { case (o, n, _, _) => n.iParams(o) }) - require (i.size == iPorts.size, s"Bug in diplomacy; ${name} has ${i.size} != ${iPorts.size} up/down inner parameters${lazyModule.line}") - i.map(inner.mixI(_, this)) + try { + if (iParamsCycleGuard) throw UpwardCycleException() + iParamsCycleGuard = true + val i = mapParamsU(iPorts.size, oPorts.map { case (o, n, _, _) => n.iParams(o) }) + require (i.size == iPorts.size, s"Bug in diplomacy; ${name} has ${i.size} != ${iPorts.size} up/down inner parameters${lazyModule.line}") + i.map(inner.mixI(_, this)) + } catch { + case c: UpwardCycleException => throw c.copy(loop = s"${name}${lazyModule.line}" +: c.loop) + } } protected[diplomacy] def gco = if (iParams.size != 1) None else inner.getO(iParams(0)) From 0268959c24364ecc1ed66b73fad2e3ce19993e36 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Wed, 27 Sep 2017 12:02:04 -0700 Subject: [PATCH 28/32] rocket: move interrupt synchronizers to correct side of crossing --- src/main/scala/coreplex/RocketCoreplex.scala | 6 +++++- src/main/scala/tile/RocketTile.scala | 6 ------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/main/scala/coreplex/RocketCoreplex.scala b/src/main/scala/coreplex/RocketCoreplex.scala index 04689407..766aee01 100644 --- a/src/main/scala/coreplex/RocketCoreplex.scala +++ b/src/main/scala/coreplex/RocketCoreplex.scala @@ -84,7 +84,11 @@ trait HasRocketTiles extends HasSystemBus lip.foreach { coreIntXbar.intnode := _ } // lip wrapper.coreIntNode := coreIntXbar.intnode - wrapper.intOutputNode.foreach { plic.intnode := _ } + wrapper.intOutputNode.foreach { case int => + val rocketIntXing = LazyModule(new IntXing(wrapper.outputInterruptXingLatency)) + rocketIntXing.intnode := int + plic.intnode := rocketIntXing.intnode + } wrapper } diff --git a/src/main/scala/tile/RocketTile.scala b/src/main/scala/tile/RocketTile.scala index 8f5ca043..b9aaa542 100644 --- a/src/main/scala/tile/RocketTile.scala +++ b/src/main/scala/tile/RocketTile.scala @@ -211,12 +211,6 @@ abstract class RocketTileWrapper(rtp: RocketTileParams, hartid: Int)(implicit p: def outputInterruptXingLatency: Int - rocket.intOutputNode.foreach { rocketIntOutputNode => - val outXing = LazyModule(new IntXing(outputInterruptXingLatency)) - intOutputNode.get := outXing.intnode - outXing.intnode := rocketIntOutputNode - } - lazy val module = new LazyModuleImp(this) { val io = IO(new CoreBundle with HasExternallyDrivenTileConstants From ce01ab2700f5161cd86700ae48f4c0d52430058e Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Wed, 27 Sep 2017 12:27:16 -0700 Subject: [PATCH 29/32] RegisterRouter: correctly create interrupts vector --- src/main/scala/amba/ahb/RegisterRouter.scala | 2 +- src/main/scala/amba/apb/RegisterRouter.scala | 2 +- src/main/scala/amba/axi4/RegisterRouter.scala | 2 +- src/main/scala/tilelink/RegisterRouter.scala | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/scala/amba/ahb/RegisterRouter.scala b/src/main/scala/amba/ahb/RegisterRouter.scala index edae7f6b..da1960d7 100644 --- a/src/main/scala/amba/ahb/RegisterRouter.scala +++ b/src/main/scala/amba/ahb/RegisterRouter.scala @@ -89,7 +89,7 @@ class AHBRegModule[P, B <: AHBRegBundleBase](val params: P, bundleBuilder: => B, extends LazyModuleImp(router) with HasRegMap { val io = IO(bundleBuilder) - val interrupts = if (router.intnode.in.isEmpty) Vec(0, Bool()) else router.intnode.in(0)._1 + val interrupts = if (router.intnode.out.isEmpty) Vec(0, Bool()) else router.intnode.out(0)._1 def regmap(mapping: RegField.Map*) = router.node.regmap(mapping:_*) } diff --git a/src/main/scala/amba/apb/RegisterRouter.scala b/src/main/scala/amba/apb/RegisterRouter.scala index ebff2756..f83c38c9 100644 --- a/src/main/scala/amba/apb/RegisterRouter.scala +++ b/src/main/scala/amba/apb/RegisterRouter.scala @@ -73,7 +73,7 @@ class APBRegModule[P, B <: APBRegBundleBase](val params: P, bundleBuilder: => B, extends LazyModuleImp(router) with HasRegMap { val io = IO(bundleBuilder) - val interrupts = if (router.intnode.in.isEmpty) Vec(0, Bool()) else router.intnode.in(0)._1 + val interrupts = if (router.intnode.out.isEmpty) Vec(0, Bool()) else router.intnode.out(0)._1 def regmap(mapping: RegField.Map*) = router.node.regmap(mapping:_*) } diff --git a/src/main/scala/amba/axi4/RegisterRouter.scala b/src/main/scala/amba/axi4/RegisterRouter.scala index be601889..32d0b1de 100644 --- a/src/main/scala/amba/axi4/RegisterRouter.scala +++ b/src/main/scala/amba/axi4/RegisterRouter.scala @@ -100,7 +100,7 @@ class AXI4RegModule[P, B <: AXI4RegBundleBase](val params: P, bundleBuilder: => extends LazyModuleImp(router) with HasRegMap { val io = IO(bundleBuilder) - val interrupts = if (router.intnode.in.isEmpty) Vec(0, Bool()) else router.intnode.in(0)._1 + val interrupts = if (router.intnode.out.isEmpty) Vec(0, Bool()) else router.intnode.out(0)._1 def regmap(mapping: RegField.Map*) = router.node.regmap(mapping:_*) } diff --git a/src/main/scala/tilelink/RegisterRouter.scala b/src/main/scala/tilelink/RegisterRouter.scala index bf523af7..dc49e797 100644 --- a/src/main/scala/tilelink/RegisterRouter.scala +++ b/src/main/scala/tilelink/RegisterRouter.scala @@ -105,7 +105,7 @@ class TLRegModule[P, B <: TLRegBundleBase](val params: P, bundleBuilder: => B, r extends LazyModuleImp(router) with HasRegMap { val io = IO(bundleBuilder) - val interrupts = if (router.intnode.in.isEmpty) Vec(0, Bool()) else router.intnode.in(0)._1 + val interrupts = if (router.intnode.out.isEmpty) Vec(0, Bool()) else router.intnode.out(0)._1 val address = router.address def regmap(mapping: RegField.Map*) = router.node.regmap(mapping:_*) } From e07d86aecdcff68f35aa50f6003c72ec5f439c52 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Wed, 27 Sep 2017 12:46:29 -0700 Subject: [PATCH 30/32] rocket: flip interrupt rendering so cores are on top --- src/main/scala/coreplex/RocketCoreplex.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/coreplex/RocketCoreplex.scala b/src/main/scala/coreplex/RocketCoreplex.scala index 766aee01..b4992a3c 100644 --- a/src/main/scala/coreplex/RocketCoreplex.scala +++ b/src/main/scala/coreplex/RocketCoreplex.scala @@ -86,7 +86,7 @@ trait HasRocketTiles extends HasSystemBus wrapper.intOutputNode.foreach { case int => val rocketIntXing = LazyModule(new IntXing(wrapper.outputInterruptXingLatency)) - rocketIntXing.intnode := int + FlipRendering { implicit p => rocketIntXing.intnode := int } plic.intnode := rocketIntXing.intnode } From 9307092d147b086eeb066cb30fbc455228049480 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Wed, 27 Sep 2017 14:20:39 -0700 Subject: [PATCH 31/32] coreplex: draw the FrontBus at the bottom and SystemBus at the top --- src/main/scala/coreplex/FrontBus.scala | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/scala/coreplex/FrontBus.scala b/src/main/scala/coreplex/FrontBus.scala index 98d080bc..2ece4503 100644 --- a/src/main/scala/coreplex/FrontBus.scala +++ b/src/main/scala/coreplex/FrontBus.scala @@ -55,6 +55,5 @@ trait HasFrontBus extends HasSystemBus { val fbus = LazyModule(new FrontBus(frontbusParams)) - sbus.fromFrontBus := fbus.toSystemBus - + FlipRendering { implicit p => sbus.fromFrontBus := fbus.toSystemBus } } From feae216f05eb17292525ca28fc402dd2b0518294 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Wed, 27 Sep 2017 15:18:42 -0700 Subject: [PATCH 32/32] clint: output interrupts in the correct direction --- src/main/scala/devices/tilelink/Clint.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/devices/tilelink/Clint.scala b/src/main/scala/devices/tilelink/Clint.scala index 1419c137..5083ba9b 100644 --- a/src/main/scala/devices/tilelink/Clint.scala +++ b/src/main/scala/devices/tilelink/Clint.scala @@ -68,8 +68,8 @@ class CoreplexLocalInterrupter(params: ClintParams)(implicit p: Parameters) exte val timecmp = Seq.fill(nTiles) { Seq.fill(timeWidth/regWidth)(Reg(UInt(width = regWidth))) } val ipi = Seq.fill(nTiles) { RegInit(UInt(0, width = 1)) } - val (intnode_in, _) = intnode.in.unzip - intnode_in.zipWithIndex.foreach { case (int, i) => + val (intnode_out, _) = intnode.out.unzip + intnode_out.zipWithIndex.foreach { case (int, i) => int(0) := ShiftRegister(ipi(i)(0), params.intStages) // msip int(1) := ShiftRegister(time.asUInt >= timecmp(i).asUInt, params.intStages) // mtip }