Skip to content

Commit

Permalink
tile: use BundleBridgeBlockDuringReset for tile trace interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
hcook committed Oct 1, 2020
1 parent 2036f7d commit 91d57cf
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 30 deletions.
36 changes: 36 additions & 0 deletions src/main/scala/prci/BundleBridgeBlockDuringReset.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// See LICENSE.SiFive for license details.

package freechips.rocketchip.prci

import chisel3._
import freechips.rocketchip.config.{Parameters}
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.diplomacy.BundleBridgeNexus.fillN
import freechips.rocketchip.util.{BlockDuringReset, Blockable}

object BundleBridgeBlockDuringReset {
def apply[T <: Data : Blockable](
resetCrossingType: ResetCrossingType,
name: Option[String] = None,
registered: Boolean = false,
default: Option[() => T] = None,
inputRequiresOutput: Boolean = false,
shouldBeInlined: Boolean = true
)(implicit p: Parameters): BundleBridgeNexusNode[T] = {
val nexus = LazyModule(new BundleBridgeNexus[T](
inputFn = (s: Seq[T]) => {
val data = BundleBridgeNexus.requireOne[T](registered)(s)
resetCrossingType match {
case _: NoResetCrossing => data
case s: StretchedResetCrossing => BlockDuringReset(data, s.cycles)
}
},
outputFn = fillN[T](registered) _,
default = default,
inputRequiresOutput = inputRequiresOutput,
shouldBeInlined = shouldBeInlined
))
name.foreach(nexus.suggestName(_))
nexus.node
}
}
6 changes: 3 additions & 3 deletions src/main/scala/subsystem/HasTiles.scala
Original file line number Diff line number Diff line change
Expand Up @@ -319,9 +319,9 @@ trait CanAttachTile {
context.tileHaltXbarNode :=* domain.crossIntOut(NoCrossing, domain.tile.haltNode)
context.tileWFIXbarNode :=* domain.crossIntOut(NoCrossing, domain.tile.wfiNode)
context.tileCeaseXbarNode :=* domain.crossIntOut(NoCrossing, domain.tile.ceaseNode)
// TODO should context be forced to have a trace sink connected here,
// or the below trace wiring just legacy support that should be deprecated?
domain.traceNexusNode := domain.tile.traceNode
// TODO should context be forced to have a trace sink connected here?
// for now this just ensures domain.trace[Core]Node has been crossed without connecting it externally
domain.crossTracesOut()
}

/** Connect inputs to the tile that are assumed to be constant during normal operation, and so are not clock-crossed. */
Expand Down
27 changes: 11 additions & 16 deletions src/main/scala/tile/BaseTile.scala
Original file line number Diff line number Diff line change
Expand Up @@ -238,20 +238,23 @@ abstract class BaseTile private (val crossing: ClockCrossingType, q: Parameters)
val mmioAddressPrefixNode: BundleBridgeInwardNode[UInt] =
mmioAddressPrefixNexusNode :=* BundleBridgeNameNode("mmio_address_prefix")

protected def traceRetireWidth = tileParams.core.retireWidth
protected def traceCoreParams = new TraceCoreParams()
protected def traceCoreSignalName = "tracecore"
// TODO: Any node marked "consumed by the core" or "driven by the core"
// should be moved to either be: a member of a BaseTile subclass,
// or actually just a member of the core itself,
// should be moved to either be: a member of a specific BaseTile subclass,
// or actually just a member of the core's LazyModule itself,
// assuming the core itself is diplomatic.
// Then we probably don't need the above parameters exposed here either.
// Then these nodes should just become IdentityNodes of their respective type

protected def traceRetireWidth = tileParams.core.retireWidth
/** Node for the core to drive legacy "raw" instruction trace. */
val traceSourceNode = BundleBridgeSource(() => Vec(traceRetireWidth, new TracedInstruction()))
/** Node for external consumers to source a legacy instruction trace from the core. */
val traceNode: BundleBridgeOutwardNode[Vec[TracedInstruction]] =
BundleBridgeNameNode("trace") := traceSourceNode
val traceNode: BundleBridgeOutwardNode[Vec[TracedInstruction]] = traceSourceNode

protected def traceCoreParams = new TraceCoreParams()
/** Node for core to drive instruction trace conforming to RISC-V Processor Trace spec V1.0 */
val traceCoreSourceNode = BundleBridgeSource(() => new TraceCoreInterface(traceCoreParams))
/** Node for external consumers to source a V1.0 instruction trace from the core. */
val traceCoreNode: BundleBridgeOutwardNode[TraceCoreInterface] = traceCoreSourceNode

/** Node to broadcast collected trace sideband signals into the tile. */
val traceAuxNexusNode = BundleBridgeNexus[TraceAux](default = Some(() => {
Expand All @@ -266,14 +269,6 @@ abstract class BaseTile private (val crossing: ClockCrossingType, q: Parameters)
val traceAuxNode: BundleBridgeInwardNode[TraceAux] =
traceAuxSinkNode := traceAuxNexusNode :=* BundleBridgeNameNode("trace_aux")

/** Node for core to drive instruction trace conforming to RISC-V Processor Trace spec V1.0 */
val traceCoreSourceNode = BundleBridgeSource(() => new TraceCoreInterface(traceCoreParams))
/** Node to broadcast V1.0 instruction trace to external consumers. */
val traceCoreNexusNode = BundleBroadcast[TraceCoreInterface]()
/** Node for external consumers to source a V1.0 instruction trace from the core. */
val traceCoreNode: BundleBridgeOutwardNode[TraceCoreInterface] =
BundleBridgeNameNode(traceCoreSignalName) :*= traceCoreNexusNode := traceCoreSourceNode

/** Node for watchpoints to control trace driven by core. */
val bpwatchSourceNode = BundleBridgeSource(() => Vec(tileParams.core.nBreakpoints, new BPWatch(traceRetireWidth)))
/** Node to broadcast watchpoints to control trace. */
Expand Down
30 changes: 19 additions & 11 deletions src/main/scala/tile/TilePRCIDomain.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ import freechips.rocketchip.prci._
import freechips.rocketchip.rocket.{TracedInstruction}
import freechips.rocketchip.subsystem.{TileCrossingParamsLike, CrossesToOnlyOneResetDomain}
import freechips.rocketchip.tilelink._
import freechips.rocketchip.util.{BlockDuringReset}

import freechips.rocketchip.util.{TraceCoreInterface}

/** A wrapper containing all logic within a managed reset domain for a tile.
*
Expand Down Expand Up @@ -48,16 +47,25 @@ abstract class TilePRCIDomain[T <: BaseTile](
val clockNode = FixedClockBroadcast(None) :=* tapClockNode
lazy val clockBundle = tapClockNode.in.head._1

private val traceSignalName = "trace"
private val traceCoreSignalName = "tracecore"
/** Node to broadcast legacy "raw" instruction trace while surpressing it during (async) reset. */
val traceNexusNode = BundleBridgeNexus(
inputFn = (s: Seq[Vec[TracedInstruction]]) => {
val data = BundleBridgeNexus.requireOne[Vec[TracedInstruction]](false)(s)
crossingParams.resetCrossingType match {
case _: NoResetCrossing => data
case s: StretchedResetCrossing => BlockDuringReset(data, s.cycles)
}
}
)
val traceNode: BundleBridgeIdentityNode[Vec[TracedInstruction]] = BundleBridgeNameNode(traceSignalName)
/** Node to broadcast standardized instruction trace while surpressing it during (async) reset. */
val traceCoreNode: BundleBridgeIdentityNode[TraceCoreInterface] = BundleBridgeNameNode(traceCoreSignalName)

/** Function to handle all trace crossings when tile is instantiated inside domains */
def crossTracesOut(): Unit = this {
val traceNexusNode = BundleBridgeBlockDuringReset[Vec[TracedInstruction]](
resetCrossingType = crossingParams.resetCrossingType,
name = Some(traceSignalName))
traceNode :*= traceNexusNode := tile.traceNode

val traceCoreNexusNode = BundleBridgeBlockDuringReset[TraceCoreInterface](
resetCrossingType = crossingParams.resetCrossingType,
name = Some(traceCoreSignalName))
traceCoreNode :*= traceCoreNexusNode := tile.traceCoreNode
}

/** External code looking to connect and clock-cross the interrupts driven into this tile can call this. */
def crossIntIn(crossingType: ClockCrossingType): IntInwardNode = {
Expand Down

0 comments on commit 91d57cf

Please sign in to comment.