b8098d18be
The reason for the :=? operator was for when you have an adapter chain whose direction of cardinality you could not know. We used explicit directives to tell these compositions which way to go. Unfortunately, that makes the API leaky. You think the chain of adapters is just one adapter, but you have to use strange Cardinality scopes to use it. That's just bad. The new :*=* just automagically figures it out from the graph.
86 lines
3.0 KiB
Scala
86 lines
3.0 KiB
Scala
// See LICENSE.SiFive for license details.
|
|
|
|
package freechips.rocketchip.tilelink
|
|
|
|
import Chisel._
|
|
import freechips.rocketchip.config.{Field, Parameters}
|
|
import freechips.rocketchip.diplomacy._
|
|
|
|
case object TLBusDelayProbability extends Field[Double](0.0)
|
|
|
|
/** Specifies widths of various attachement points in the SoC */
|
|
trait TLBusParams {
|
|
val beatBytes: Int
|
|
val blockBytes: Int
|
|
val masterBuffering: BufferParams
|
|
val slaveBuffering: BufferParams
|
|
|
|
def beatBits: Int = beatBytes * 8
|
|
def blockBits: Int = blockBytes * 8
|
|
def blockBeats: Int = blockBytes / beatBytes
|
|
def blockOffset: Int = log2Up(blockBytes)
|
|
}
|
|
|
|
abstract class TLBusWrapper(params: TLBusParams, val busName: String)(implicit p: Parameters)
|
|
extends SimpleLazyModule with LazyScope with TLBusParams {
|
|
|
|
val beatBytes = params.beatBytes
|
|
val blockBytes = params.blockBytes
|
|
val masterBuffering = params.masterBuffering
|
|
val slaveBuffering = params.slaveBuffering
|
|
require(blockBytes % beatBytes == 0)
|
|
private val delayProb = p(TLBusDelayProbability)
|
|
|
|
protected val xbar = LazyModule(new TLXbar)
|
|
xbar.suggestName(busName)
|
|
|
|
private val master_buffer = LazyModule(new TLBuffer(masterBuffering))
|
|
master_buffer.suggestName(s"${busName}_master_TLBuffer")
|
|
private val slave_buffer = LazyModule(new TLBuffer(slaveBuffering))
|
|
slave_buffer.suggestName(s"${busName}_slave_TLBuffer")
|
|
private val slave_frag = LazyModule(new TLFragmenter(beatBytes, blockBytes))
|
|
slave_frag.suggestName(s"${busName}_slave_TLFragmenter")
|
|
|
|
private val slave_ww = LazyModule(new TLWidthWidget(beatBytes))
|
|
slave_ww.suggestName(s"${busName}_slave_TLWidthWidget")
|
|
|
|
private val delayedNode = if (delayProb > 0.0) {
|
|
val firstDelay = LazyModule(new TLDelayer(delayProb))
|
|
val flowDelay = LazyModule(new TLBuffer(BufferParams.flow))
|
|
val secondDelay = LazyModule(new TLDelayer(delayProb))
|
|
firstDelay.node :*= xbar.node
|
|
flowDelay.node :*= firstDelay.node
|
|
secondDelay.node :*= flowDelay.node
|
|
secondDelay.node
|
|
} else {
|
|
xbar.node
|
|
}
|
|
|
|
xbar.node :=* master_buffer.node
|
|
slave_buffer.node :*= delayedNode
|
|
slave_frag.node :*= slave_buffer.node
|
|
slave_ww.node :*= slave_buffer.node
|
|
|
|
protected def outwardNode: TLOutwardNode = delayedNode
|
|
protected def outwardBufNode: TLOutwardNode = slave_buffer.node
|
|
protected def outwardFragNode: TLOutwardNode = slave_frag.node
|
|
protected def outwardWWNode: TLOutwardNode = slave_ww.node
|
|
protected def inwardNode: TLInwardNode = xbar.node
|
|
protected def inwardBufNode: TLInwardNode = master_buffer.node
|
|
|
|
def bufferFromMasters: TLInwardNode = inwardBufNode
|
|
|
|
def bufferToSlaves: TLOutwardNode = outwardBufNode
|
|
|
|
def toSyncSlaves(name: Option[String] = None, addBuffers: Int = 0): TLOutwardNode = {
|
|
TLBuffer.chain(addBuffers).foldRight(outwardBufNode)(_ :*= _)
|
|
}
|
|
|
|
def toVariableWidthSlaves: TLOutwardNode = outwardFragNode
|
|
|
|
def toFixedWidthSlaves: TLOutwardNode = outwardWWNode
|
|
|
|
def toFixedWidthPorts: TLOutwardNode = outwardWWNode // TODO, do/don't buffer here; knowing we will after the necessary port conversions
|
|
|
|
}
|