Merge pull request #1039 from freechipsproject/tile-crossing-params
Improvements wrt connecting RocketTiles to SystemBus
This commit is contained in:
@ -71,31 +71,32 @@ class WithNSmallCores(n: Int) extends Config((site, here, up) => {
|
||||
}
|
||||
})
|
||||
|
||||
class WithNTinyCores(n: Int) extends Config((site, here, up) => {
|
||||
case XLen => 32
|
||||
case RocketTilesKey => {
|
||||
val tiny = RocketTileParams(
|
||||
core = RocketCoreParams(
|
||||
useVM = false,
|
||||
fpu = None,
|
||||
mulDiv = Some(MulDivParams(mulUnroll = 8))),
|
||||
btb = None,
|
||||
dcache = Some(DCacheParams(
|
||||
rowBits = site(SystemBusKey).beatBits,
|
||||
nSets = 256, // 16Kb scratchpad
|
||||
nWays = 1,
|
||||
nTLBEntries = 4,
|
||||
nMSHRs = 0,
|
||||
blockBytes = site(CacheBlockBytes),
|
||||
scratch = Some(0x80000000L))),
|
||||
icache = Some(ICacheParams(
|
||||
rowBits = site(SystemBusKey).beatBits,
|
||||
nSets = 64,
|
||||
nWays = 1,
|
||||
nTLBEntries = 4,
|
||||
blockBytes = site(CacheBlockBytes))))
|
||||
List.tabulate(n)(i => tiny.copy(hartid = i))
|
||||
}
|
||||
class With1TinyCore extends Config((site, here, up) => {
|
||||
case XLen => 32
|
||||
case RocketTilesKey => List(RocketTileParams(
|
||||
core = RocketCoreParams(
|
||||
useVM = false,
|
||||
fpu = None,
|
||||
mulDiv = Some(MulDivParams(mulUnroll = 8))),
|
||||
btb = None,
|
||||
dcache = Some(DCacheParams(
|
||||
rowBits = site(SystemBusKey).beatBits,
|
||||
nSets = 256, // 16Kb scratchpad
|
||||
nWays = 1,
|
||||
nTLBEntries = 4,
|
||||
nMSHRs = 0,
|
||||
blockBytes = site(CacheBlockBytes),
|
||||
scratch = Some(0x80000000L))),
|
||||
icache = Some(ICacheParams(
|
||||
rowBits = site(SystemBusKey).beatBits,
|
||||
nSets = 64,
|
||||
nWays = 1,
|
||||
nTLBEntries = 4,
|
||||
blockBytes = site(CacheBlockBytes)))))
|
||||
case RocketCrossingKey => List(RocketCrossingParams(
|
||||
crossingType = SynchronousCrossing(),
|
||||
master = TileMasterPortParams(cork = Some(true))
|
||||
))
|
||||
})
|
||||
|
||||
class WithNBanksPerMemChannel(n: Int) extends Config((site, here, up) => {
|
||||
@ -153,10 +154,8 @@ class WithBufferlessBroadcastHub extends Config((site, here, up) => {
|
||||
class WithStatelessBridge extends Config((site, here, up) => {
|
||||
case BankedL2Key => up(BankedL2Key, site).copy(coherenceManager = { coreplex =>
|
||||
implicit val p = coreplex.p
|
||||
val cork = LazyModule(new TLCacheCork(unsafe = true))
|
||||
val ww = LazyModule(new TLWidthWidget(coreplex.sbusBeatBytes))
|
||||
ww.node :*= cork.node
|
||||
(cork.node, ww.node, () => None)
|
||||
(ww.node, ww.node, () => None)
|
||||
})
|
||||
})
|
||||
|
||||
@ -242,15 +241,21 @@ class WithBootROMFile(bootROMFile: String) extends Config((site, here, up) => {
|
||||
})
|
||||
|
||||
class WithSynchronousRocketTiles extends Config((site, here, up) => {
|
||||
case RocketCrossing => SynchronousCrossing()
|
||||
case RocketCrossingKey => up(RocketCrossingKey, site) map { r =>
|
||||
r.copy(crossingType = SynchronousCrossing())
|
||||
}
|
||||
})
|
||||
|
||||
class WithAynchronousRocketTiles(depth: Int, sync: Int) extends Config((site, here, up) => {
|
||||
case RocketCrossing => AsynchronousCrossing(depth, sync)
|
||||
case RocketCrossingKey => up(RocketCrossingKey, site) map { r =>
|
||||
r.copy(crossingType = AsynchronousCrossing(depth, sync))
|
||||
}
|
||||
})
|
||||
|
||||
class WithRationalRocketTiles extends Config((site, here, up) => {
|
||||
case RocketCrossing => RationalCrossing()
|
||||
case RocketCrossingKey => up(RocketCrossingKey, site) map { r =>
|
||||
r.copy(crossingType = RationalCrossing())
|
||||
}
|
||||
})
|
||||
|
||||
class WithEdgeDataBits(dataBits: Int) extends Config((site, here, up) => {
|
||||
|
@ -31,6 +31,30 @@ class PeripheryBus(params: PeripheryBusParams)(implicit p: Parameters) extends T
|
||||
TLFragmenter(params.beatBytes, maxXferBytes)(outwardBufNode)
|
||||
}
|
||||
|
||||
def toSyncSlaves(adapt: () => TLNodeChain, name: Option[String]): TLOutwardNode = SinkCardinality { implicit p =>
|
||||
val adapters = adapt()
|
||||
adapters.in :=? outwardBufNode
|
||||
adapters.out
|
||||
}
|
||||
|
||||
def toAsyncSlaves(sync: Int, adapt: () => TLNodeChain, name: Option[String]): TLAsyncOutwardNode = SinkCardinality { implicit p =>
|
||||
val adapters = adapt()
|
||||
val source = LazyModule(new TLAsyncCrossingSource(sync))
|
||||
name.foreach{ n => source.suggestName(s"${busName}_${n}_TLAsyncCrossingSource")}
|
||||
adapters.in :=? outwardNode
|
||||
source.node :=? adapters.out
|
||||
source.node
|
||||
}
|
||||
|
||||
def toRationalSlaves(adapt: () => TLNodeChain, name: Option[String]): TLRationalOutwardNode = SinkCardinality { implicit p =>
|
||||
val adapters = adapt()
|
||||
val source = LazyModule(new TLRationalCrossingSource())
|
||||
name.foreach{ n => source.suggestName(s"${busName}_${n}_TLRationalCrossingSource")}
|
||||
adapters.in :=? outwardNode
|
||||
source.node :=? adapters.out
|
||||
source.node
|
||||
}
|
||||
|
||||
val fromSystemBus: TLInwardNode = {
|
||||
val atomics = LazyModule(new TLAtomicAutomata(arithmetic = params.arithmetic))
|
||||
inwardBufNode := atomics.node
|
||||
|
@ -11,8 +11,74 @@ import freechips.rocketchip.tile._
|
||||
import freechips.rocketchip.tilelink._
|
||||
import freechips.rocketchip.util._
|
||||
|
||||
case class TLNodeChain(in: TLInwardNode, out: TLOutwardNode)
|
||||
|
||||
// TODO: how specific are these to RocketTiles?
|
||||
case class TileMasterPortParams(
|
||||
addBuffers: Int = 0,
|
||||
blockerCtrlAddr: Option[BigInt] = None,
|
||||
cork: Option[Boolean] = None) {
|
||||
def adapterChain(coreplex: HasPeripheryBus)
|
||||
(implicit p: Parameters): () => TLNodeChain = {
|
||||
|
||||
val blockerParams = blockerCtrlAddr.map(BasicBusBlockerParams(_, coreplex.pbus.beatBytes, coreplex.sbus.beatBytes, deadlock = true))
|
||||
|
||||
val tile_master_cork = cork.map(u => (LazyModule(new TLCacheCork(unsafe = u))))
|
||||
val tile_master_blocker = blockerParams.map(bp => LazyModule(new BasicBusBlocker(bp)))
|
||||
val tile_master_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.allUncacheable))
|
||||
val tile_master_buffer = LazyModule(new TLBufferChain(addBuffers))
|
||||
|
||||
tile_master_blocker.foreach { _.controlNode := coreplex.pbus.toVariableWidthSlaves }
|
||||
|
||||
val nodes = List(
|
||||
Some(tile_master_buffer.node),
|
||||
Some(tile_master_fixer.node),
|
||||
tile_master_blocker.map(_.node),
|
||||
tile_master_cork.map(_.node)
|
||||
).flatMap(b=>b)
|
||||
|
||||
nodes.init zip nodes.tail foreach { case(front, back) => front :=* back }
|
||||
|
||||
() => TLNodeChain(in = nodes.last, out = nodes.head)
|
||||
}
|
||||
}
|
||||
|
||||
case class TileSlavePortParams(
|
||||
addBuffers: Int = 0,
|
||||
blockerCtrlAddr: Option[BigInt] = None) {
|
||||
def adapterChain(coreplex: HasPeripheryBus)
|
||||
(implicit p: Parameters): () => TLNodeChain = {
|
||||
|
||||
val blockerParams = blockerCtrlAddr.map(BasicBusBlockerParams(_, coreplex.pbus.beatBytes, coreplex.sbus.beatBytes))
|
||||
|
||||
val tile_slave_blocker = blockerParams.map(bp => LazyModule(new BasicBusBlocker(bp)))
|
||||
val tile_slave_buffer = LazyModule(new TLBufferChain(addBuffers))
|
||||
|
||||
tile_slave_blocker.foreach { _.controlNode := coreplex.pbus.toVariableWidthSlaves }
|
||||
|
||||
val nodes = List(
|
||||
Some(tile_slave_buffer.node),
|
||||
tile_slave_blocker.map(_.node)
|
||||
).flatMap(b=>b)
|
||||
|
||||
nodes.init zip nodes.tail foreach { case(front, back) => front :=* back }
|
||||
|
||||
() => TLNodeChain(in = nodes.last, out = nodes.head)
|
||||
}
|
||||
}
|
||||
|
||||
case class RocketCrossingParams(
|
||||
crossingType: CoreplexClockCrossing = SynchronousCrossing(),
|
||||
master: TileMasterPortParams = TileMasterPortParams(),
|
||||
slave: TileSlavePortParams = TileSlavePortParams()) {
|
||||
def knownRatio: Option[Int] = crossingType match {
|
||||
case RationalCrossing(_) => Some(2)
|
||||
case _ => None
|
||||
}
|
||||
}
|
||||
|
||||
case object RocketTilesKey extends Field[Seq[RocketTileParams]](Nil)
|
||||
case object RocketCrossing extends Field[CoreplexClockCrossing](SynchronousCrossing())
|
||||
case object RocketCrossingKey extends Field[Seq[RocketCrossingParams]](List(RocketCrossingParams()))
|
||||
|
||||
trait HasRocketTiles extends HasTiles
|
||||
with HasPeripheryBus
|
||||
@ -21,35 +87,43 @@ trait HasRocketTiles extends HasTiles
|
||||
with HasPeripheryDebug {
|
||||
val module: HasRocketTilesModuleImp
|
||||
|
||||
private val crossing = p(RocketCrossing)
|
||||
protected val tileParams = p(RocketTilesKey)
|
||||
private val NumRocketTiles = tileParams.size
|
||||
private val crossingParams = p(RocketCrossingKey)
|
||||
private val crossings = crossingParams.size match {
|
||||
case 1 => List.fill(NumRocketTiles) { crossingParams.head }
|
||||
case NumRocketTiles => crossingParams
|
||||
case _ => throw new Exception("RocketCrossingKey.size must == 1 or == RocketTilesKey.size")
|
||||
}
|
||||
|
||||
// Make a wrapper for each tile that will wire it to coreplex devices and crossbars,
|
||||
// according to the specified type of clock crossing.
|
||||
val tiles: Seq[BaseTile] = localIntNodes.zip(tileParams).map { case (lip, tp) =>
|
||||
private val crossingTuples = localIntNodes.zip(tileParams).zip(crossings)
|
||||
val tiles: Seq[BaseTile] = crossingTuples.map { case ((lip, tp), crossing) =>
|
||||
val pWithExtra = p.alterPartial {
|
||||
case TileKey => tp
|
||||
case BuildRoCC => tp.rocc
|
||||
case SharedMemoryTLEdge => sharedMemoryTLEdge
|
||||
case RocketCrossingKey => List(crossing)
|
||||
}
|
||||
|
||||
val wrapper = crossing match {
|
||||
val wrapper = crossing.crossingType match {
|
||||
case SynchronousCrossing(params) => {
|
||||
val wrapper = LazyModule(new SyncRocketTile(tp)(pWithExtra))
|
||||
sbus.fromSyncTiles(params, tp.externalMasterBuffers, tp.name) :=* wrapper.masterNode
|
||||
FlipRendering { implicit p => wrapper.slaveNode :*= pbus.toSyncSlaves(tp.name, tp.externalSlaveBuffers) }
|
||||
sbus.fromSyncTiles(params, crossing.master.adapterChain(this), tp.name) :=* wrapper.masterNode
|
||||
FlipRendering { implicit p => wrapper.slaveNode :*= pbus.toSyncSlaves(crossing.slave.adapterChain(this), tp.name) }
|
||||
wrapper
|
||||
}
|
||||
case AsynchronousCrossing(depth, sync) => {
|
||||
val wrapper = LazyModule(new AsyncRocketTile(tp)(pWithExtra))
|
||||
sbus.fromAsyncTiles(depth, sync, tp.externalMasterBuffers, tp.name) :=* wrapper.masterNode
|
||||
FlipRendering { implicit p => wrapper.slaveNode :*= pbus.toAsyncSlaves(sync, tp.name, tp.externalSlaveBuffers) }
|
||||
sbus.fromAsyncTiles(depth, sync, crossing.master.adapterChain(this), tp.name) :=* wrapper.masterNode
|
||||
FlipRendering { implicit p => wrapper.slaveNode :*= pbus.toAsyncSlaves(sync, crossing.slave.adapterChain(this), tp.name) }
|
||||
wrapper
|
||||
}
|
||||
case RationalCrossing(direction) => {
|
||||
val wrapper = LazyModule(new RationalRocketTile(tp)(pWithExtra))
|
||||
sbus.fromRationalTiles(direction, tp.externalMasterBuffers, tp.name) :=* wrapper.masterNode
|
||||
FlipRendering { implicit p => wrapper.slaveNode :*= pbus.toRationalSlaves(tp.name, tp.externalSlaveBuffers) }
|
||||
sbus.fromRationalTiles(direction, crossing.master.adapterChain(this), tp.name) :=* wrapper.masterNode
|
||||
FlipRendering { implicit p => wrapper.slaveNode :*= pbus.toRationalSlaves(crossing.slave.adapterChain(this), tp.name) }
|
||||
wrapper
|
||||
}
|
||||
}
|
||||
|
@ -27,9 +27,6 @@ class SystemBus(params: SystemBusParams)(implicit p: Parameters) extends TLBusWr
|
||||
protected def inwardSplitNode: TLInwardNode = master_splitter.node
|
||||
protected def outwardSplitNode: TLOutwardNode = master_splitter.node
|
||||
|
||||
private val tile_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.allUncacheable))
|
||||
tile_fixer.suggestName(s"${busName}_tile_TLFIFOFixer")
|
||||
master_splitter.node :=* tile_fixer.node
|
||||
|
||||
private val port_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.all))
|
||||
port_fixer.suggestName(s"${busName}_port_TLFIFOFixer")
|
||||
@ -55,33 +52,33 @@ class SystemBus(params: SystemBusParams)(implicit p: Parameters) extends TLBusWr
|
||||
|
||||
def fromFrontBus: TLInwardNode = master_splitter.node
|
||||
|
||||
def fromSyncTiles(params: BufferParams, addBuffers: Int = 0, name: Option[String] = None): TLInwardNode = {
|
||||
val tile_buf = LazyModule(new TLBuffer(params))
|
||||
name.foreach { n => tile_buf.suggestName(s"${busName}_${n}_TLBuffer") }
|
||||
val (in, out) = bufferChain(addBuffers, name = name)
|
||||
def fromSyncTiles(params: BufferParams, adapt: () => TLNodeChain, name: Option[String] = None): TLInwardNode = {
|
||||
val adapters = adapt() // wanted to be called inside SystemBus scope
|
||||
val tile_sink = LazyModule(new TLBuffer(params))
|
||||
name.foreach { n => tile_sink.suggestName(s"${busName}_${n}_TLBuffer") }
|
||||
|
||||
tile_fixer.node :=* out
|
||||
in :=* tile_buf.node
|
||||
tile_buf.node
|
||||
}
|
||||
|
||||
def fromRationalTiles(dir: RationalDirection, addBuffers: Int = 0, name: Option[String] = None): TLRationalInwardNode = {
|
||||
val tile_sink = LazyModule(new TLRationalCrossingSink(direction = dir))
|
||||
name.foreach { n => tile_sink.suggestName(s"${busName}_${n}_TLRationalCrossingSink") }
|
||||
val (in, out) = bufferChain(addBuffers, name = name)
|
||||
|
||||
tile_fixer.node :=* out
|
||||
in :=* tile_sink.node
|
||||
adapters.in :=* tile_sink.node
|
||||
master_splitter.node :=* adapters.out
|
||||
tile_sink.node
|
||||
}
|
||||
|
||||
def fromAsyncTiles(depth: Int, sync: Int, addBuffers: Int = 0, name: Option[String] = None): TLAsyncInwardNode = {
|
||||
def fromRationalTiles(dir: RationalDirection, adapt: () => TLNodeChain, name: Option[String] = None): TLRationalInwardNode = {
|
||||
val adapters = adapt() // wanted to be called inside SystemBus scope
|
||||
val tile_sink = LazyModule(new TLRationalCrossingSink(direction = dir))
|
||||
name.foreach { n => tile_sink.suggestName(s"${busName}_${n}_TLRationalCrossingSink") }
|
||||
|
||||
adapters.in :=* tile_sink.node
|
||||
master_splitter.node :=* adapters.out
|
||||
tile_sink.node
|
||||
}
|
||||
|
||||
def fromAsyncTiles(depth: Int, sync: Int, adapt: () => TLNodeChain, name: Option[String] = None): TLAsyncInwardNode = {
|
||||
val adapters = adapt() // wanted to be called inside SystemBus scope
|
||||
val tile_sink = LazyModule(new TLAsyncCrossingSink(depth, sync))
|
||||
name.foreach { n => tile_sink.suggestName(s"${busName}_${n}_TLAsyncCrossingSink") }
|
||||
val (in, out) = bufferChain(addBuffers, name = name)
|
||||
|
||||
tile_fixer.node :=* out
|
||||
in :=* tile_sink.node
|
||||
adapters.in :=* tile_sink.node
|
||||
master_splitter.node :=* adapters.out
|
||||
tile_sink.node
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user