diff --git a/src/main/scala/diplomacy/Nodes.scala b/src/main/scala/diplomacy/Nodes.scala index 838cb489..16b655df 100644 --- a/src/main/scala/diplomacy/Nodes.scala +++ b/src/main/scala/diplomacy/Nodes.scala @@ -23,9 +23,11 @@ object CardinalityInferenceDirection { case object NO_INFERENCE extends T } -case object CardinalityInferenceDirectionKey extends +private case object CardinalityInferenceDirectionKey extends Field[CardinalityInferenceDirection.T](CardinalityInferenceDirection.NO_INFERENCE) +private case object MonitorsEnabled extends Field[Boolean](true) + // DI = Downwards flowing Parameters received on the inner side of the node // UI = Upwards flowing Parameters generated by the inner side of the node // EI = Edge Parameters describing a connection on the inner side of the node @@ -249,7 +251,7 @@ abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( lazy val bundleIn = wireI(flipI(HeterogeneousBag(edgesIn .map(inner.bundleI(_))))) // connects the outward part of a node with the inward part of this node - private def bind(h: OutwardNodeHandle[DI, UI, BI], binding: NodeBinding, enableMonitoring: Boolean) + private def bind(h: OutwardNodeHandle[DI, UI, BI], binding: NodeBinding) (implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = { val x = this // x := y val y = h.outward @@ -276,14 +278,14 @@ abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( (x.bundleIn(iStart+j), y.bundleOut(oStart+j)) } } - val (out, newbinding) = inner.connect(edges _, bundles _, enableMonitoring) + val (out, newbinding) = inner.connect(edges _, bundles _, p(MonitorsEnabled)) LazyModule.stack.head.bindings = newbinding :: LazyModule.stack.head.bindings out } - override def := (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = bind(h, BIND_ONCE, true) - override def :*= (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = bind(h, BIND_STAR, true) - override def :=* (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = bind(h, BIND_QUERY, true) + 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] = { p(CardinalityInferenceDirectionKey) match { case CardinalityInferenceDirection.SOURCE_TO_SINK => this :=* h @@ -292,10 +294,6 @@ abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( } } - def connectButDontMonitor(h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = bind(h, BIND_ONCE, false) - def connectButDontMonitorSlaves(h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = bind(h, BIND_STAR, false) - def connectButDontMonitorMasters(h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[MonitorBase] = bind(h, BIND_QUERY, false) - // meta-data for printing the node graph protected[diplomacy] def colour = inner.colour protected[diplomacy] def reverse = inner.reverse diff --git a/src/main/scala/diplomacy/package.scala b/src/main/scala/diplomacy/package.scala index 93714d62..2fd34f4c 100644 --- a/src/main/scala/diplomacy/package.scala +++ b/src/main/scala/diplomacy/package.scala @@ -34,4 +34,10 @@ package object diplomacy def FlipStar[T](body: Parameters => T)(implicit p: Parameters) = body(p.alterPartial { case CardinalityInferenceDirectionKey => p(CardinalityInferenceDirectionKey).flip }) + def EnableMonitors[T](body: Parameters => T)(implicit p: Parameters) = body(p.alterPartial { + case MonitorsEnabled => true + }) + def DisableMonitors[T](body: Parameters => T)(implicit p: Parameters) = body(p.alterPartial { + case MonitorsEnabled => false + }) } diff --git a/src/main/scala/rocket/Frontend.scala b/src/main/scala/rocket/Frontend.scala index 465e521d..ee824da0 100644 --- a/src/main/scala/rocket/Frontend.scala +++ b/src/main/scala/rocket/Frontend.scala @@ -8,7 +8,7 @@ import Chisel.ImplicitConversions._ import chisel3.core.withReset import freechips.rocketchip.config._ import freechips.rocketchip.coreplex._ -import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp} +import freechips.rocketchip.diplomacy._ import freechips.rocketchip.tilelink._ import freechips.rocketchip.tile._ import freechips.rocketchip.util._ @@ -61,7 +61,7 @@ class Frontend(val icacheParams: ICacheParams, hartid: Int)(implicit p: Paramete masterNode := icache.masterNode // Avoid breaking tile dedup due to address constants in the monitor - icache.slaveNode.map { _ connectButDontMonitor slaveNode } + DisableMonitors { implicit p => icache.slaveNode.map { _ := slaveNode } } } class FrontendBundle(outer: Frontend) extends CoreBundle()(outer.p) { diff --git a/src/main/scala/rocket/ScratchpadSlavePort.scala b/src/main/scala/rocket/ScratchpadSlavePort.scala index 5c942d2f..9a1b9088 100644 --- a/src/main/scala/rocket/ScratchpadSlavePort.scala +++ b/src/main/scala/rocket/ScratchpadSlavePort.scala @@ -103,16 +103,18 @@ trait CanHaveScratchpad extends HasHellaCache with HasICacheFrontend with HasCor val slaveNode = TLInputNode() // Up to two uses for this input node: // 1) Frontend always exists, but may or may not have a scratchpad node + // 2) ScratchpadSlavePort always has a node, but only exists when the HellaCache has a scratchpad val fg = LazyModule(new TLFragmenter(fetchWidth*coreInstBytes, p(CacheBlockBytes), earlyAck=true)) val ww = LazyModule(new TLWidthWidget(xLen/8)) - frontend.slaveNode connectButDontMonitorSlaves fg.node - fg.node connectButDontMonitorSlaves ww.node - ww.node connectButDontMonitorSlaves slaveNode - - // 2) ScratchpadSlavePort always has a node, but only exists when the HellaCache has a scratchpad val scratch = tileParams.dcache.flatMap(d => d.scratch.map(s => LazyModule(new ScratchpadSlavePort(AddressSet(s, d.dataScratchpadBytes-1))))) - scratch foreach { lm => lm.node connectButDontMonitor TLFragmenter(xLen/8, p(CacheBlockBytes), earlyAck=true)(slaveNode) } + + DisableMonitors { implicit p => + frontend.slaveNode :*= fg.node + fg.node :*= ww.node + ww.node :*= slaveNode + scratch foreach { lm => lm.node := TLFragmenter(xLen/8, p(CacheBlockBytes), earlyAck=true)(slaveNode) } + } def findScratchpadFromICache: Option[AddressSet] = scratch.map { s => val finalNode = frontend.masterNode.edgesOut.head.manager.managers.find(_.nodePath.last == s.node) diff --git a/src/main/scala/tile/RocketTile.scala b/src/main/scala/tile/RocketTile.scala index a98917b9..74cbf56c 100644 --- a/src/main/scala/tile/RocketTile.scala +++ b/src/main/scala/tile/RocketTile.scala @@ -191,7 +191,7 @@ abstract class RocketTileWrapper(rtp: RocketTileParams, hartid: Int)(implicit p: def optionalSlaveBuffer(in: TLOutwardNode): TLOutwardNode = { if (rtp.boundaryBuffers) { val sbuf = LazyModule(new TLBuffer(BufferParams.flow, BufferParams.none, BufferParams.none, BufferParams.none, BufferParams.none)) - sbuf.node connectButDontMonitorSlaves in + DisableMonitors { implicit p => sbuf.node :*= in } sbuf.node } else { in @@ -217,7 +217,7 @@ class SyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) masterNode :=* optionalMasterBuffer(rocket.masterNode) val slaveNode = new TLInputNode() { override def reverse = true } - rocket.slaveNode connectButDontMonitorSlaves optionalSlaveBuffer(slaveNode) + DisableMonitors { implicit p => rocket.slaveNode :*= optionalSlaveBuffer(slaveNode) } // Fully async interrupts need synchronizers. // Others need no synchronization. @@ -237,8 +237,11 @@ class AsyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters val slaveNode = new TLAsyncInputNode() { override def reverse = true } val sink = LazyModule(new TLAsyncCrossingSink) - rocket.slaveNode connectButDontMonitorSlaves sink.node - sink.node connectButDontMonitorSlaves slaveNode + + DisableMonitors { implicit p => + rocket.slaveNode :*= sink.node + sink.node :*= slaveNode + } // Fully async interrupts need synchronizers, // as do those coming from the periphery clock. @@ -261,8 +264,11 @@ class RationalRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Paramet val slaveNode = new TLRationalInputNode() { override def reverse = true } val sink = LazyModule(new TLRationalCrossingSink(SlowToFast)) - sink.node connectButDontMonitorSlaves slaveNode - rocket.slaveNode connectButDontMonitorSlaves optionalSlaveBuffer(sink.node) + + DisableMonitors { implicit p => + sink.node :*= slaveNode + rocket.slaveNode :*= optionalSlaveBuffer(sink.node) + } // Fully async interrupts need synchronizers. // Those coming from periphery clock need a