1
0

diplomacy: eliminate some wasted IdentityNodes using cross-module refs

This commit is contained in:
Wesley W. Terpstra 2017-09-23 00:04:50 -07:00
parent bc225a4e82
commit 60614055e3
9 changed files with 64 additions and 87 deletions

View File

@ -392,15 +392,12 @@ class TLDebugModuleOuterAsync(device: Device)(implicit p: Parameters) extends La
val dmiXbar = LazyModule (new TLXbar()) val dmiXbar = LazyModule (new TLXbar())
val dmOuter = LazyModule( new TLDebugModuleOuter(device)) val dmOuter = LazyModule( new TLDebugModuleOuter(device))
val intnode = IntIdentityNode() val intnode = dmOuter.intnode
val dmiInnerNode = TLAsyncIdentityNode() val dmiInnerNode = TLAsyncCrossingSource()(dmiXbar.node)
intnode :*= dmOuter.intnode
dmiXbar.node := dmi2tl.node dmiXbar.node := dmi2tl.node
dmOuter.dmiNode := dmiXbar.node dmOuter.dmiNode := dmiXbar.node
dmiInnerNode := TLAsyncCrossingSource()(dmiXbar.node)
lazy val module = new LazyModuleImp(this) { 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. // Also is the Sink side of hartsel & resumereq fields of DMCONTROL.
class TLDebugModuleInnerAsync(device: Device, getNComponents: () => Int)(implicit p: Parameters) extends LazyModule{ class TLDebugModuleInnerAsync(device: Device, getNComponents: () => Int)(implicit p: Parameters) extends LazyModule{
val dmInner = LazyModule(new TLDebugModuleInner(device, getNComponents)(p)) val dmInner = LazyModule(new TLDebugModuleInner(device, getNComponents))
val dmiNode = TLAsyncIdentityNode() val dmiXing = LazyModule(new TLAsyncCrossingSink(depth=1))
val tlNode = TLIdentityNode() val dmiNode: TLAsyncInwardNode = dmiXing.node
val tlNode = dmInner.tlNode
dmInner.dmiNode := TLAsyncCrossingSink(depth=1)(dmiNode) dmInner.dmiNode := dmiXing.node
dmInner.tlNode := tlNode
lazy val module = new LazyModuleImp(this) { lazy val module = new LazyModuleImp(this) {
@ -1041,15 +1038,13 @@ class TLDebugModule(implicit p: Parameters) extends LazyModule {
override val alwaysExtended = true override val alwaysExtended = true
} }
val node = TLIdentityNode()
val intnode = IntIdentityNode()
val dmOuter = LazyModule(new TLDebugModuleOuterAsync(device)(p)) val dmOuter = LazyModule(new TLDebugModuleOuterAsync(device)(p))
val dmInner = LazyModule(new TLDebugModuleInnerAsync(device, () => {intnode.edges.out.size})(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.dmiNode := dmOuter.dmiInnerNode
dmInner.tlNode := node
intnode :*= dmOuter.intnode
lazy val module = new LazyModuleImp(this) { lazy val module = new LazyModuleImp(this) {
val nComponents = intnode.out.size val nComponents = intnode.out.size

View File

@ -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 everything = Seq(AddressSet(0, BigInt("ffffffffffffffffffffffffffffffff", 16))) // 128-bit
protected val error = LazyModule(new TLError(ErrorParams(everything), beatBytes)) protected val error = LazyModule(new TLError(ErrorParams(everything), beatBytes))
// order matters
bar.node := nodeIn bar.node := nodeIn
error.node := bar.node error.node := bar.node
nodeOut := bar.node nodeOut := bar.node

View File

@ -56,12 +56,8 @@ class FrontendIO(implicit p: Parameters) extends CoreBundle()(p) {
class Frontend(val icacheParams: ICacheParams, hartid: Int)(implicit p: Parameters) extends LazyModule { class Frontend(val icacheParams: ICacheParams, hartid: Int)(implicit p: Parameters) extends LazyModule {
lazy val module = new FrontendModule(this) lazy val module = new FrontendModule(this)
val icache = LazyModule(new ICache(icacheParams, hartid)) val icache = LazyModule(new ICache(icacheParams, hartid))
val masterNode = TLIdentityNode() val masterNode = icache.masterNode
val slaveNode = TLIdentityNode() val slaveNode = icache.slaveNode
masterNode := icache.masterNode
// Avoid breaking tile dedup due to address constants in the monitor
DisableMonitors { implicit p => icache.slaveNode.map { _ := slaveNode } }
} }
class FrontendBundle(outer: Frontend) extends CoreBundle()(outer.p) class FrontendBundle(outer: Frontend) extends CoreBundle()(outer.p)

View File

@ -51,9 +51,9 @@ class ICache(val icacheParams: ICacheParams, val hartid: Int)(implicit p: Parame
val size = icacheParams.nSets * icacheParams.nWays * icacheParams.blockBytes val size = icacheParams.nSets * icacheParams.nWays * icacheParams.blockBytes
val device = new SimpleDevice("itim", Seq("sifive,itim0")) val device = new SimpleDevice("itim", Seq("sifive,itim0"))
val slaveNode = icacheParams.itimAddr.map { itimAddr => private val wordBytes = icacheParams.fetchBytes
val wordBytes = icacheParams.fetchBytes val slaveNode =
TLManagerNode(Seq(TLManagerPortParameters( TLManagerNode(icacheParams.itimAddr.toSeq.map { itimAddr => TLManagerPortParameters(
Seq(TLManagerParameters( Seq(TLManagerParameters(
address = Seq(AddressSet(itimAddr, size-1)), address = Seq(AddressSet(itimAddr, size-1)),
resources = device.reg("mem"), resources = device.reg("mem"),
@ -64,8 +64,7 @@ class ICache(val icacheParams: ICacheParams, val hartid: Int)(implicit p: Parame
supportsGet = TransferSizes(1, wordBytes), supportsGet = TransferSizes(1, wordBytes),
fifoId = Some(0))), // requests handled in FIFO order fifoId = Some(0))), // requests handled in FIFO order
beatBytes = wordBytes, beatBytes = wordBytes,
minLatency = 1))) minLatency = 1)})
}
} }
class ICacheResp(outer: ICache) extends Bundle { class ICacheResp(outer: ICache) extends Bundle {
@ -110,9 +109,8 @@ class ICacheModule(outer: ICache) extends LazyModuleImp(outer)
val io = IO(new ICacheBundle(outer)) val io = IO(new ICacheBundle(outer))
val (tl_out, edge_out) = outer.masterNode.out(0) val (tl_out, edge_out) = outer.masterNode.out(0)
// Option.unzip does not exist :-( // Option.unzip does not exist :-(
// val (tl_in, edge_in) = outer.slaveNode.map(_.in(0)).unzip val tl_in = outer.slaveNode.in.headOption.map(_._1)
val tl_in = outer.slaveNode.map(_.in(0)._1) val edge_in = outer.slaveNode.in.headOption.map(_._2)
val edge_in = outer.slaveNode.map(_.in(0)._2)
val tECC = cacheParams.tagECC val tECC = cacheParams.tagECC
val dECC = cacheParams.dataECC val dECC = cacheParams.dataECC

View File

@ -57,7 +57,7 @@ class RocketTile(val rocketParams: RocketTileParams, val hartid: Int)(implicit p
val dtim = scratch.map(d => Map( val dtim = scratch.map(d => Map(
"sifive,dtim" -> ofRef(d.device))).getOrElse(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)) "sifive,itim" -> ofRef(frontend.icache.device))
val icache = rocketParams.icache.map(i => Map( 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 { abstract class RocketTileWrapper(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends LazyModule {
val rocket = LazyModule(new RocketTile(rtp, hartid)) val rocket = LazyModule(new RocketTile(rtp, hartid))
val masterNode: IdentityNode[_,_,_,_,_] val asyncIntNode : IntInwardNode
val slaveNode: IdentityNode[_,_,_,_,_] val periphIntNode : IntInwardNode
val asyncIntNode = IntIdentityNode() val coreIntNode : IntInwardNode
val periphIntNode = IntIdentityNode() val intOutputNode = rocket.intOutputNode
val coreIntNode = IntIdentityNode()
val intOutputNode = rocket.intOutputNode.map(dummy => IntIdentityNode())
val intXbar = LazyModule(new IntXbar) val intXbar = LazyModule(new IntXbar)
rocket.intNode := intXbar.intnode 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) { class SyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends RocketTileWrapper(rtp, hartid) {
val masterNode = TLIdentityNode() val masterNode = optionalMasterBuffer(rocket.masterNode)
masterNode :=* optionalMasterBuffer(rocket.masterNode)
val slaveNode = new TLIdentityNode() { override def reverse = true } val slaveNode = new TLIdentityNode() { override def reverse = true }
DisableMonitors { implicit p => rocket.slaveNode :*= optionalSlaveBuffer(slaveNode) } 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. // Fully async interrupts need synchronizers.
// Others need no synchronization. // Others need no synchronization.
val xing = LazyModule(new IntXing(3)) val xing = LazyModule(new IntXing(3))
xing.intnode := asyncIntNode val asyncIntNode = xing.intnode
intXbar.intnode := xing.intnode val periphIntNode = IntIdentityNode()
intXbar.intnode := periphIntNode val coreIntNode = IntIdentityNode()
intXbar.intnode := coreIntNode
// order here matters
intXbar.intnode := xing.intnode
intXbar.intnode := periphIntNode
intXbar.intnode := coreIntNode
def outputInterruptXingLatency = 0 def outputInterruptXingLatency = 0
} }
class AsyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends RocketTileWrapper(rtp, hartid) { class AsyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends RocketTileWrapper(rtp, hartid) {
val masterNode = TLAsyncIdentityNode()
val source = LazyModule(new TLAsyncCrossingSource) val source = LazyModule(new TLAsyncCrossingSource)
source.node :=* rocket.masterNode source.node :=* rocket.masterNode
masterNode :=* source.node val masterNode = source.node
val slaveNode = new TLAsyncIdentityNode() { override def reverse = true } val slaveNode = new TLAsyncIdentityNode() { override def reverse = true }
val sink = LazyModule(new TLAsyncCrossingSink) val sink = LazyModule(new TLAsyncCrossingSink)
@ -272,21 +272,22 @@ class AsyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters
// Others need no synchronization. // Others need no synchronization.
val asyncXing = LazyModule(new IntXing(3)) val asyncXing = LazyModule(new IntXing(3))
val periphXing = LazyModule(new IntXing(3)) val periphXing = LazyModule(new IntXing(3))
asyncXing.intnode := asyncIntNode val asyncIntNode = asyncXing.intnode
periphXing.intnode := periphIntNode val periphIntNode = periphXing.intnode
val coreIntNode = IntIdentityNode()
intXbar.intnode := asyncXing.intnode // order here matters
intXbar.intnode := periphXing.intnode intXbar.intnode := asyncXing.intnode
intXbar.intnode := coreIntNode intXbar.intnode := periphXing.intnode
intXbar.intnode := coreIntNode
def outputInterruptXingLatency = 3 def outputInterruptXingLatency = 3
} }
class RationalRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends RocketTileWrapper(rtp, hartid) { class RationalRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends RocketTileWrapper(rtp, hartid) {
val masterNode = TLRationalIdentityNode()
val source = LazyModule(new TLRationalCrossingSource) val source = LazyModule(new TLRationalCrossingSource)
source.node :=* optionalMasterBuffer(rocket.masterNode) source.node :=* optionalMasterBuffer(rocket.masterNode)
masterNode :=* source.node val masterNode = source.node
val slaveNode = new TLRationalIdentityNode() { override def reverse = true } val slaveNode = new TLRationalIdentityNode() { override def reverse = true }
val sink = LazyModule(new TLRationalCrossingSink(SlowToFast)) val sink = LazyModule(new TLRationalCrossingSink(SlowToFast))
@ -302,12 +303,14 @@ class RationalRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Paramet
// Others need no synchronization. // Others need no synchronization.
val asyncXing = LazyModule(new IntXing(3)) val asyncXing = LazyModule(new IntXing(3))
val periphXing = LazyModule(new IntXing(1)) val periphXing = LazyModule(new IntXing(1))
asyncXing.intnode := asyncIntNode val asyncIntNode = asyncXing.intnode
periphXing.intnode := periphIntNode val periphIntNode = periphXing.intnode
val coreIntNode = IntIdentityNode()
intXbar.intnode := asyncXing.intnode // order here matters
intXbar.intnode := periphXing.intnode intXbar.intnode := asyncXing.intnode
intXbar.intnode := coreIntNode intXbar.intnode := periphXing.intnode
intXbar.intnode := coreIntNode
def outputInterruptXingLatency = 1 def outputInterruptXingLatency = 1
} }

View File

@ -87,16 +87,11 @@ object TLAsyncCrossingSink
class TLAsyncCrossing(depth: Int = 8, sync: Int = 3)(implicit p: Parameters) extends LazyModule 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 source = LazyModule(new TLAsyncCrossingSource(sync))
val sink = LazyModule(new TLAsyncCrossingSink(depth, sync)) val sink = LazyModule(new TLAsyncCrossingSink(depth, sync))
val node = NodeHandle(source.node, sink.node)
sink.node := source.node sink.node := source.node
source.node := nodeIn
nodeOut := sink.node
lazy val module = new LazyModuleImp(this) { lazy val module = new LazyModuleImp(this) {
val io = IO(new Bundle { val io = IO(new Bundle {

View File

@ -74,31 +74,25 @@ object TLBuffer
} }
class TLBufferChain(depth: Int)(implicit p: Parameters) extends LazyModule { class TLBufferChain(depth: Int)(implicit p: Parameters) extends LazyModule {
val buf_chain = List.fill(depth)(LazyModule(new TLBuffer(BufferParams.default)))
val nodeIn = TLIdentityNode() val node = if (depth > 0) {
val nodeOut = TLIdentityNode() (buf_chain.init zip buf_chain.tail) foreach { case (prev, next) => next.node :=? prev.node }
val node = NodeHandle(nodeIn, nodeOut) NodeHandle(buf_chain.head.node, buf_chain.last.node)
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
} else { } else {
List(LazyModule(new TLBuffer(BufferParams.none))) TLIdentityNode()
} }
buf_chain.head.node :=? nodeIn
nodeOut :=? buf_chain.last.node
lazy val module = new LazyModuleImp(this) { } lazy val module = new LazyModuleImp(this) { }
} }
object TLBufferChain object TLBufferChain
{ {
def apply(depth: Int)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = { def apply(depth: Int)(x: TLOutwardNode)(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
val buffer = LazyModule(new TLBufferChain(depth)) if (depth > 0) {
buffer.node :=? x val buffer = LazyModule(new TLBufferChain(depth))
buffer.node buffer.node :=? x
buffer.node
} else {
x
}
} }
} }

View File

@ -71,7 +71,7 @@ abstract class TLBusWrapper(params: TLBusParams, val busName: String)(implicit p
SourceCardinality { implicit p => SourceCardinality { implicit p =>
val chain = LazyModule(new TLBufferChain(depth)) val chain = LazyModule(new TLBufferChain(depth))
name.foreach { n => chain.suggestName(s"${busName}_${n}_TLBufferChain")} name.foreach { n => chain.suggestName(s"${busName}_${n}_TLBufferChain")}
(chain.nodeIn, chain.nodeOut) (chain.node, chain.node)
} }
} }

View File

@ -99,16 +99,11 @@ object TLRationalCrossingSink
class TLRationalCrossing(direction: RationalDirection = Symmetric)(implicit p: Parameters) extends LazyModule 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 source = LazyModule(new TLRationalCrossingSource)
val sink = LazyModule(new TLRationalCrossingSink(direction)) val sink = LazyModule(new TLRationalCrossingSink(direction))
val node = NodeHandle(source.node, sink.node)
sink.node := source.node sink.node := source.node
source.node := nodeIn
nodeOut := sink.node
lazy val module = new LazyModuleImp(this) { lazy val module = new LazyModuleImp(this) {
val io = IO(new Bundle { val io = IO(new Bundle {