From 60614055e360adefc416999f48e205c421a0ac77 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Sat, 23 Sep 2017 00:04:50 -0700 Subject: [PATCH] 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 {