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) }))