diff --git a/src/main/scala/coreplex/RocketCoreplex.scala b/src/main/scala/coreplex/RocketCoreplex.scala index 93e6544e..66a66acf 100644 --- a/src/main/scala/coreplex/RocketCoreplex.scala +++ b/src/main/scala/coreplex/RocketCoreplex.scala @@ -11,15 +11,64 @@ 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 TilePortParams( - addBuffers: Int = 0, - blockerCtrlAddr: Option[BigInt] = None) +case class TileMasterPortParams( + addBuffers: Int = 0, + blockerCtrlAddr: Option[BigInt] = None, + cork: Boolean = false) { + def adapterChain(coreplex: HasPeripheryBus) + (implicit p: Parameters): () => TLNodeChain = { + + val blockerParams = blockerCtrlAddr.map(BusBlockerParams(_, coreplex.pbus.beatBytes, coreplex.sbus.beatBytes, 1)) + + val tile_master_cork = cork.option(LazyModule(new TLCacheCork)) + val tile_master_blocker = blockerParams.map(bp => LazyModule(new BusBlocker(bp))) + val tile_master_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.allUncacheable)) + val tile_master_buffer = LazyModule(new TLBufferChain(addBuffers)) + + 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 } + + tile_master_blocker.foreach { _.controlNode := coreplex.pbus.toVariableWidthSlaves } + + () => TLNodeChain(nodes.last, nodes.head) + } +} + +case class TileSlavePortParams( + addBuffers: Int = 0, + blockerCtrlAddr: Option[BigInt] = None) { + def adapterChain(coreplex: HasPeripheryBus) + (implicit p: Parameters): () => TLNodeChain = { + + val blockerParams = blockerCtrlAddr.map(BusBlockerParams(_, coreplex.pbus.beatBytes, coreplex.sbus.beatBytes, 1)) + + val tile_slave_blocker = blockerParams.map(bp => LazyModule(new BusBlocker(bp))) + val tile_slave_buffer = LazyModule(new TLBufferChain(addBuffers)) + + 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 } + + tile_slave_blocker.foreach { _.controlNode := coreplex.pbus.toVariableWidthSlaves } + + () => TLNodeChain(nodes.last, nodes.head) + } +} case class RocketCrossingParams( crossingType: CoreplexClockCrossing = SynchronousCrossing(), - master: TilePortParams = TilePortParams(), - slave: TilePortParams = TilePortParams()) { + master: TileMasterPortParams = TileMasterPortParams(), + slave: TileSlavePortParams = TileSlavePortParams()) { def knownRatio: Option[Int] = crossingType match { case RationalCrossing(_) => Some(2) case _ => None @@ -59,19 +108,19 @@ trait HasRocketTiles extends HasTiles val wrapper = crossing.crossingType match { case SynchronousCrossing(params) => { val wrapper = LazyModule(new SyncRocketTile(tp)(pWithExtra)) - sbus.fromSyncTiles(params, crossing.master, tp.name) :=* wrapper.masterNode + sbus.fromSyncTiles(params, crossing.master.adapterChain(this), tp.name) :=* wrapper.masterNode FlipRendering { implicit p => wrapper.slaveNode :*= pbus.toSyncSlaves(tp.name, crossing.slave.addBuffers) } wrapper } case AsynchronousCrossing(depth, sync) => { val wrapper = LazyModule(new AsyncRocketTile(tp)(pWithExtra)) - sbus.fromAsyncTiles(depth, sync, crossing.master, tp.name) :=* wrapper.masterNode + sbus.fromAsyncTiles(depth, sync, crossing.master.adapterChain(this), tp.name) :=* wrapper.masterNode FlipRendering { implicit p => wrapper.slaveNode :*= pbus.toAsyncSlaves(sync, tp.name, crossing.slave.addBuffers) } wrapper } case RationalCrossing(direction) => { val wrapper = LazyModule(new RationalRocketTile(tp)(pWithExtra)) - sbus.fromRationalTiles(direction, crossing.master, tp.name) :=* wrapper.masterNode + sbus.fromRationalTiles(direction, crossing.master.adapterChain(this), tp.name) :=* wrapper.masterNode FlipRendering { implicit p => wrapper.slaveNode :*= pbus.toRationalSlaves(tp.name, crossing.slave.addBuffers) } wrapper } diff --git a/src/main/scala/coreplex/SystemBus.scala b/src/main/scala/coreplex/SystemBus.scala index a755662e..c07138f9 100644 --- a/src/main/scala/coreplex/SystemBus.scala +++ b/src/main/scala/coreplex/SystemBus.scala @@ -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,34 +52,33 @@ class SystemBus(params: SystemBusParams)(implicit p: Parameters) extends TLBusWr def fromFrontBus: TLInwardNode = master_splitter.node - def fromSyncTiles(params: BufferParams, port: TilePortParams, 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(port.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, port: TilePortParams, name: Option[String] = None): TLRationalInwardNode = { - // TODO val tile_blocker = port.blockerCtrlAddr.map(a => LazyModule(new BusBlocker(BusBlockerParams(a, , )))) - val tile_sink = LazyModule(new TLRationalCrossingSink(direction = dir)) - name.foreach { n => tile_sink.suggestName(s"${busName}_${n}_TLRationalCrossingSink") } - val (in, out) = bufferChain(port.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, port: TilePortParams, 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(port.addBuffers, name = name) - tile_fixer.node :=* out - in :=* tile_sink.node + adapters.in :=* tile_sink.node + master_splitter.node :=* adapters.out tile_sink.node } diff --git a/src/main/scala/groundtest/Coreplex.scala b/src/main/scala/groundtest/Coreplex.scala index e45dbc3f..b9ee65cf 100644 --- a/src/main/scala/groundtest/Coreplex.scala +++ b/src/main/scala/groundtest/Coreplex.scala @@ -25,7 +25,9 @@ class GroundTestCoreplex(implicit p: Parameters) extends BaseCoreplex }) )} - tiles.flatMap(_.dcacheOpt).foreach { sbus.fromSyncTiles(BufferParams.default, TilePortParams()) :=* _.node } + tiles.flatMap(_.dcacheOpt).foreach { + sbus.fromSyncTiles(BufferParams.default, TileMasterPortParams().adapterChain(this)) :=* _.node + } val pbusRAM = LazyModule(new TLRAM(AddressSet(testRamAddr, 0xffff), false, pbus.beatBytes)) pbusRAM.node := pbus.toVariableWidthSlaves