coreplex: refactor crossings to use node pattern
This commit is contained in:
parent
6276ea4291
commit
e30906589f
@ -15,80 +15,116 @@ case class SynchronousCrossing(params: BufferParams = BufferParams.default) exte
|
|||||||
case class RationalCrossing(direction: RationalDirection = FastToSlow) extends CoreplexClockCrossing
|
case class RationalCrossing(direction: RationalDirection = FastToSlow) extends CoreplexClockCrossing
|
||||||
case class AsynchronousCrossing(depth: Int, sync: Int = 3) extends CoreplexClockCrossing
|
case class AsynchronousCrossing(depth: Int, sync: Int = 3) extends CoreplexClockCrossing
|
||||||
|
|
||||||
trait HasCrossingHelper extends LazyScope
|
trait HasCrossingMethods extends LazyScope
|
||||||
{
|
{
|
||||||
this: LazyModule =>
|
this: LazyModule =>
|
||||||
val crossing: CoreplexClockCrossing
|
|
||||||
|
|
||||||
def cross(x: TLCrossableNode): TLOutwardNode = {
|
// TileLink
|
||||||
val out = x.node.parentsOut.exists(_ eq this) // is the crossing exiting the wrapper?
|
|
||||||
crossing match {
|
def crossTLSyncInOut(out: Boolean)(params: BufferParams = BufferParams.default)(implicit p: Parameters): TLNode = {
|
||||||
case SynchronousCrossing(params) => {
|
this { LazyModule(new TLBuffer(params)).node }
|
||||||
this { TLBuffer(params)(x.node) }
|
|
||||||
}
|
}
|
||||||
case RationalCrossing(direction) => {
|
|
||||||
def sourceGen = LazyModule(new TLRationalCrossingSource)
|
def crossTLAsyncInOut(out: Boolean)(depth: Int = 8, sync: Int = 3)(implicit p: Parameters): TLNode = {
|
||||||
def sinkGen = LazyModule(new TLRationalCrossingSink(direction))
|
|
||||||
val source = if (out) this { sourceGen } else sourceGen
|
|
||||||
val sink = if (out) sinkGen else this { sinkGen }
|
|
||||||
source.node :=? x.node
|
|
||||||
sink.node :=? source.node
|
|
||||||
sink.node
|
|
||||||
}
|
|
||||||
case AsynchronousCrossing(depth, sync) => {
|
|
||||||
def sourceGen = LazyModule(new TLAsyncCrossingSource(sync))
|
def sourceGen = LazyModule(new TLAsyncCrossingSource(sync))
|
||||||
def sinkGen = LazyModule(new TLAsyncCrossingSink(depth, sync))
|
def sinkGen = LazyModule(new TLAsyncCrossingSink(depth, sync))
|
||||||
val source = if (out) this { sourceGen } else sourceGen
|
val source = if (out) this { sourceGen } else sourceGen
|
||||||
val sink = if (out) sinkGen else this { sinkGen }
|
val sink = if (out) sinkGen else this { sinkGen }
|
||||||
source.node :=? x.node
|
|
||||||
sink.node :=? source.node
|
sink.node :=? source.node
|
||||||
sink.node
|
NodeHandle(source.node, sink.node)
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def cross(
|
def crossTLRationalInOut(out: Boolean)(direction: RationalDirection)(implicit p: Parameters): TLNode = {
|
||||||
name: Option[String] = None,
|
def sourceGen = LazyModule(new TLRationalCrossingSource)
|
||||||
alreadyRegistered: Boolean = false,
|
def sinkGen = LazyModule(new TLRationalCrossingSink(if (out) direction else direction.flip))
|
||||||
overrideCrossing: Option[CoreplexClockCrossing] = None)
|
val source = if (out) this { sourceGen } else sourceGen
|
||||||
(x: IntCrossableNode): IntOutwardNode = {
|
val sink = if (out) sinkGen else this { sinkGen }
|
||||||
val out = x.node.parentsOut.exists(_ eq this) // is the crossing exiting the wrapper?
|
sink.node :=? source.node
|
||||||
overrideCrossing.getOrElse(crossing) match {
|
NodeHandle(source.node, sink.node)
|
||||||
case SynchronousCrossing(_) => {
|
}
|
||||||
|
|
||||||
|
def crossTLSyncIn (params: BufferParams = BufferParams.default)(implicit p: Parameters): TLNode = crossTLSyncInOut(false)(params)
|
||||||
|
def crossTLSyncOut(params: BufferParams = BufferParams.default)(implicit p: Parameters): TLNode = crossTLSyncInOut(true )(params)
|
||||||
|
def crossTLAsyncIn (depth: Int = 8, sync: Int = 3)(implicit p: Parameters): TLNode = crossTLAsyncInOut(false)(depth, sync)
|
||||||
|
def crossTLAsyncOut(depth: Int = 8, sync: Int = 3)(implicit p: Parameters): TLNode = crossTLAsyncInOut(true )(depth, sync)
|
||||||
|
def crossTLRationalIn (direction: RationalDirection)(implicit p: Parameters): TLNode = crossTLRationalInOut(false)(direction)
|
||||||
|
def crossTLRationalOut(direction: RationalDirection)(implicit p: Parameters): TLNode = crossTLRationalInOut(true )(direction)
|
||||||
|
|
||||||
|
def crossTLIn(arg: CoreplexClockCrossing)(implicit p: Parameters): TLNode = arg match {
|
||||||
|
case x: SynchronousCrossing => crossTLSyncIn(x.params)
|
||||||
|
case x: AsynchronousCrossing => crossTLAsyncIn(x.depth, x.sync)
|
||||||
|
case x: RationalCrossing => crossTLRationalIn(x.direction)
|
||||||
|
}
|
||||||
|
|
||||||
|
def crossTLOut(arg: CoreplexClockCrossing)(implicit p: Parameters): TLNode = arg match {
|
||||||
|
case x: SynchronousCrossing => crossTLSyncOut(x.params)
|
||||||
|
case x: AsynchronousCrossing => crossTLAsyncOut(x.depth, x.sync)
|
||||||
|
case x: RationalCrossing => crossTLRationalOut(x.direction)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interrupts
|
||||||
|
|
||||||
|
def crossIntSyncInOut(out: Boolean)(alreadyRegistered: Boolean = false)(implicit p: Parameters): IntNode = {
|
||||||
def sourceGen = LazyModule(new IntSyncCrossingSource(alreadyRegistered))
|
def sourceGen = LazyModule(new IntSyncCrossingSource(alreadyRegistered))
|
||||||
def sinkGen = LazyModule(new IntSyncCrossingSink(0))
|
def sinkGen = LazyModule(new IntSyncCrossingSink(0))
|
||||||
val source = if (out) this { sourceGen } else sourceGen
|
val source = if (out) this { sourceGen } else sourceGen
|
||||||
val sink = if (out) sinkGen else this { sinkGen }
|
val sink = if (out) sinkGen else this { sinkGen }
|
||||||
name.map(_ + "SyncSource").foreach(source.suggestName)
|
|
||||||
name.map(_ + "SyncSink").foreach(sink.suggestName)
|
|
||||||
source.node :=? x.node
|
|
||||||
sink.node :=? source.node
|
sink.node :=? source.node
|
||||||
sink.node
|
NodeHandle(source.node, sink.node)
|
||||||
}
|
}
|
||||||
case RationalCrossing(_) => {
|
|
||||||
def sourceGen = LazyModule(new IntSyncCrossingSource(alreadyRegistered))
|
def crossIntAsyncInOut(out: Boolean)(sync: Int = 3, alreadyRegistered: Boolean = false)(implicit p: Parameters): IntNode = {
|
||||||
def sinkGen = LazyModule(new IntSyncCrossingSink(1))
|
|
||||||
val source = if (out) this { sourceGen } else sourceGen
|
|
||||||
val sink = if (out) sinkGen else this { sinkGen }
|
|
||||||
name.map(_ + "SyncSource").foreach(source.suggestName)
|
|
||||||
name.map(_ + "SyncSink").foreach(sink.suggestName)
|
|
||||||
source.node :=? x.node
|
|
||||||
sink.node :=? source.node
|
|
||||||
sink.node
|
|
||||||
}
|
|
||||||
case AsynchronousCrossing(_, sync) => {
|
|
||||||
def sourceGen = LazyModule(new IntSyncCrossingSource(alreadyRegistered))
|
def sourceGen = LazyModule(new IntSyncCrossingSource(alreadyRegistered))
|
||||||
def sinkGen = LazyModule(new IntSyncCrossingSink(sync))
|
def sinkGen = LazyModule(new IntSyncCrossingSink(sync))
|
||||||
val source = if (out) this { sourceGen } else sourceGen
|
val source = if (out) this { sourceGen } else sourceGen
|
||||||
val sink = if (out) sinkGen else this { sinkGen }
|
val sink = if (out) sinkGen else this { sinkGen }
|
||||||
name.map(_ + "SyncSource").foreach(source.suggestName)
|
|
||||||
name.map(_ + "SyncSink").foreach(sink.suggestName)
|
|
||||||
source.node :=? x.node
|
|
||||||
sink.node :=? source.node
|
sink.node :=? source.node
|
||||||
sink.node
|
NodeHandle(source.node, sink.node)
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class CrossingWrapper(val crossing: CoreplexClockCrossing)(implicit p: Parameters) extends SimpleLazyModule with HasCrossingHelper
|
def crossIntRationalInOut(out: Boolean)(alreadyRegistered: Boolean = false)(implicit p: Parameters): IntNode = {
|
||||||
|
def sourceGen = LazyModule(new IntSyncCrossingSource(alreadyRegistered))
|
||||||
|
def sinkGen = LazyModule(new IntSyncCrossingSink(1))
|
||||||
|
val source = if (out) this { sourceGen } else sourceGen
|
||||||
|
val sink = if (out) sinkGen else this { sinkGen }
|
||||||
|
sink.node :=? source.node
|
||||||
|
NodeHandle(source.node, sink.node)
|
||||||
|
}
|
||||||
|
|
||||||
|
def crossIntSyncIn (alreadyRegistered: Boolean = false)(implicit p: Parameters): IntNode = crossIntSyncInOut(false)(alreadyRegistered)
|
||||||
|
def crossIntSyncOut(alreadyRegistered: Boolean = false)(implicit p: Parameters): IntNode = crossIntSyncInOut(true )(alreadyRegistered)
|
||||||
|
def crossIntAsyncIn (sync: Int = 3, alreadyRegistered: Boolean = false)(implicit p: Parameters): IntNode = crossIntAsyncInOut(false)(sync, alreadyRegistered)
|
||||||
|
def crossIntAsyncOut(sync: Int = 3, alreadyRegistered: Boolean = false)(implicit p: Parameters): IntNode = crossIntAsyncInOut(true )(sync, alreadyRegistered)
|
||||||
|
def crossIntRationalIn (alreadyRegistered: Boolean = false)(implicit p: Parameters): IntNode = crossIntRationalInOut(false)(alreadyRegistered)
|
||||||
|
def crossIntRationalOut(alreadyRegistered: Boolean = false)(implicit p: Parameters): IntNode = crossIntRationalInOut(true )(alreadyRegistered)
|
||||||
|
|
||||||
|
def crossIntIn(arg: CoreplexClockCrossing, alreadyRegistered: Boolean)(implicit p: Parameters): IntNode = arg match {
|
||||||
|
case x: SynchronousCrossing => crossIntSyncIn(alreadyRegistered)
|
||||||
|
case x: AsynchronousCrossing => crossIntAsyncIn(x.sync, alreadyRegistered)
|
||||||
|
case x: RationalCrossing => crossIntRationalIn(alreadyRegistered)
|
||||||
|
}
|
||||||
|
|
||||||
|
def crossIntOut(arg: CoreplexClockCrossing, alreadyRegistered: Boolean)(implicit p: Parameters): IntNode = arg match {
|
||||||
|
case x: SynchronousCrossing => crossIntSyncOut(alreadyRegistered)
|
||||||
|
case x: AsynchronousCrossing => crossIntAsyncOut(x.sync, alreadyRegistered)
|
||||||
|
case x: RationalCrossing => crossIntRationalOut(alreadyRegistered)
|
||||||
|
}
|
||||||
|
|
||||||
|
def crossIntIn (arg: CoreplexClockCrossing)(implicit p: Parameters): IntNode = crossIntIn (arg, false)
|
||||||
|
def crossIntOut(arg: CoreplexClockCrossing)(implicit p: Parameters): IntNode = crossIntOut(arg, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
trait HasCrossing extends HasCrossingMethods
|
||||||
|
{
|
||||||
|
this: LazyModule =>
|
||||||
|
val crossing: CoreplexClockCrossing
|
||||||
|
|
||||||
|
def crossTLIn (implicit p: Parameters): TLNode = crossTLIn (crossing)
|
||||||
|
def crossTLOut (implicit p: Parameters): TLNode = crossTLOut (crossing)
|
||||||
|
def crossIntIn (implicit p: Parameters): IntNode = crossIntIn (crossing)
|
||||||
|
def crossIntOut(implicit p: Parameters): IntNode = crossIntOut(crossing)
|
||||||
|
def crossIntIn (alreadyRegistered: Boolean)(implicit p: Parameters): IntNode = crossIntIn (crossing, alreadyRegistered)
|
||||||
|
def crossIntOut(alreadyRegistered: Boolean)(implicit p: Parameters): IntNode = crossIntOut(crossing, alreadyRegistered)
|
||||||
|
}
|
||||||
|
|
||||||
|
class CrossingWrapper(val crossing: CoreplexClockCrossing)(implicit p: Parameters) extends SimpleLazyModule with HasCrossing
|
||||||
|
@ -49,7 +49,7 @@ case class TileSlavePortParams(
|
|||||||
.map(bp => LazyModule(new BasicBusBlocker(bp)))
|
.map(bp => LazyModule(new BasicBusBlocker(bp)))
|
||||||
|
|
||||||
tile_slave_blocker.foreach { _.controlNode := coreplex.pbus.toVariableWidthSlaves }
|
tile_slave_blocker.foreach { _.controlNode := coreplex.pbus.toVariableWidthSlaves }
|
||||||
(TLBuffer.chain(addBuffers) ++ tile_slave_blocker.map(_.node))
|
(Seq() ++ tile_slave_blocker.map(_.node) ++ TLBuffer.chain(addBuffers))
|
||||||
.foldLeft(slaveNode)(_ :*= _)
|
.foldLeft(slaveNode)(_ :*= _)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -103,10 +103,10 @@ trait HasRocketTiles extends HasTiles
|
|||||||
).suggestName(tp.name)
|
).suggestName(tp.name)
|
||||||
|
|
||||||
// Connect the master ports of the tile to the system bus
|
// Connect the master ports of the tile to the system bus
|
||||||
sbus.fromTile(tp.name) { implicit p => crossing.master.adapt(this)(wrapper.cross(wrapper.masterNode)) }
|
sbus.fromTile(tp.name) { implicit p => crossing.master.adapt(this)(wrapper.crossTLOut :=* wrapper.masterNode) }
|
||||||
|
|
||||||
// Connect the slave ports of the tile to the periphery bus
|
// Connect the slave ports of the tile to the periphery bus
|
||||||
pbus.toTile(tp.name) { implicit p => crossing.slave.adapt(this)(wrapper.slaveNode) } // !!! wrapper.cross
|
pbus.toTile(tp.name) { implicit p => crossing.slave.adapt(this)(wrapper.slaveNode :*= wrapper.crossTLIn) }
|
||||||
|
|
||||||
// Handle all the different types of interrupts crossing to or from the tile:
|
// Handle all the different types of interrupts crossing to or from the tile:
|
||||||
// 1. Debug interrupt is definitely asynchronous in all cases.
|
// 1. Debug interrupt is definitely asynchronous in all cases.
|
||||||
@ -120,18 +120,13 @@ trait HasRocketTiles extends HasTiles
|
|||||||
|
|
||||||
val asyncIntXbar = LazyModule(new IntXbar).suggestName(tp.name.map(_ + "AsyncIntXbar"))
|
val asyncIntXbar = LazyModule(new IntXbar).suggestName(tp.name.map(_ + "AsyncIntXbar"))
|
||||||
asyncIntXbar.intnode := debug.intnode // debug
|
asyncIntXbar.intnode := debug.intnode // debug
|
||||||
wrapper.intXbar.intnode := wrapper.cross( // 1. always crosses
|
wrapper.intXbar.intnode := wrapper.crossIntAsyncIn() := asyncIntXbar.intnode // 1. always crosses
|
||||||
name = tp.name.map(_ + "AsyncIntXbar"),
|
|
||||||
overrideCrossing = Some(AsynchronousCrossing(8,3))
|
|
||||||
)(x = asyncIntXbar.intnode)
|
|
||||||
|
|
||||||
val periphIntXbar = LazyModule(new IntXbar).suggestName(tp.name.map(_ + "PeriphIntXbar"))
|
val periphIntXbar = LazyModule(new IntXbar).suggestName(tp.name.map(_ + "PeriphIntXbar"))
|
||||||
periphIntXbar.intnode := clint.intnode // msip+mtip
|
periphIntXbar.intnode := clint.intnode // msip+mtip
|
||||||
periphIntXbar.intnode := plic.intnode // meip
|
periphIntXbar.intnode := plic.intnode // meip
|
||||||
if (tp.core.useVM) periphIntXbar.intnode := plic.intnode // seip
|
if (tp.core.useVM) periphIntXbar.intnode := plic.intnode // seip
|
||||||
wrapper.intXbar.intnode := wrapper.cross( // 2. conditionally crosses
|
wrapper.intXbar.intnode := wrapper.crossIntIn := periphIntXbar.intnode // 2. conditionally crosses
|
||||||
name = tp.name.map(_ + "PeriphIntXbar")
|
|
||||||
)(x = periphIntXbar.intnode)
|
|
||||||
|
|
||||||
val coreIntXbar = LazyModule(new IntXbar).suggestName(tp.name.map(_ + "CoreIntXbar"))
|
val coreIntXbar = LazyModule(new IntXbar).suggestName(tp.name.map(_ + "CoreIntXbar"))
|
||||||
lip.foreach { coreIntXbar.intnode := _ } // lip
|
lip.foreach { coreIntXbar.intnode := _ } // lip
|
||||||
@ -139,7 +134,7 @@ trait HasRocketTiles extends HasTiles
|
|||||||
|
|
||||||
wrapper.rocket.intOutputNode.foreach { i => // 4. conditionally crosses
|
wrapper.rocket.intOutputNode.foreach { i => // 4. conditionally crosses
|
||||||
plic.intnode := FlipRendering { implicit p =>
|
plic.intnode := FlipRendering { implicit p =>
|
||||||
wrapper.cross(name = tp.name.map(_ + "PeriphIntOutput"))(x = i)
|
wrapper.crossIntIn := i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ package object interrupts
|
|||||||
{
|
{
|
||||||
type IntInwardNode = InwardNodeHandle[IntSourcePortParameters, IntSinkPortParameters, Vec[Bool]]
|
type IntInwardNode = InwardNodeHandle[IntSourcePortParameters, IntSinkPortParameters, Vec[Bool]]
|
||||||
type IntOutwardNode = OutwardNodeHandle[IntSourcePortParameters, IntSinkPortParameters, Vec[Bool]]
|
type IntOutwardNode = OutwardNodeHandle[IntSourcePortParameters, IntSinkPortParameters, Vec[Bool]]
|
||||||
|
type IntNode = NodeHandle[IntSourcePortParameters, IntSinkPortParameters, Vec[Bool], IntSourcePortParameters, IntSinkPortParameters, Vec[Bool]]
|
||||||
type IntSyncInwardNode = InwardNodeHandle[IntSourcePortParameters, IntSinkPortParameters, SyncInterrupts]
|
type IntSyncInwardNode = InwardNodeHandle[IntSourcePortParameters, IntSinkPortParameters, SyncInterrupts]
|
||||||
type IntSyncOutwardNode = OutwardNodeHandle[IntSourcePortParameters, IntSinkPortParameters, SyncInterrupts]
|
type IntSyncOutwardNode = OutwardNodeHandle[IntSourcePortParameters, IntSinkPortParameters, SyncInterrupts]
|
||||||
}
|
}
|
||||||
|
@ -191,7 +191,7 @@ class RocketTileWrapper(
|
|||||||
params: RocketTileParams,
|
params: RocketTileParams,
|
||||||
val crossing: CoreplexClockCrossing,
|
val crossing: CoreplexClockCrossing,
|
||||||
val boundaryBuffers: Boolean = false)
|
val boundaryBuffers: Boolean = false)
|
||||||
(implicit p: Parameters) extends BaseTile(params) with HasCrossingHelper {
|
(implicit p: Parameters) extends BaseTile(params) with HasCrossing {
|
||||||
|
|
||||||
val rocket = LazyModule(new RocketTile(params))
|
val rocket = LazyModule(new RocketTile(params))
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user