From cb3529bbc35df2cfc8fcdba0cf948883133c0a0e Mon Sep 17 00:00:00 2001 From: Yunsup Lee Date: Sun, 30 Jul 2017 22:31:19 -0700 Subject: [PATCH 1/2] util: tweak rational crossings to avoid mux in source --- src/main/scala/util/RationalCrossing.scala | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/scala/util/RationalCrossing.scala b/src/main/scala/util/RationalCrossing.scala index 4f722bfd..214a7273 100644 --- a/src/main/scala/util/RationalCrossing.scala +++ b/src/main/scala/util/RationalCrossing.scala @@ -49,7 +49,8 @@ case object SlowToFast extends RationalDirection { final class RationalIO[T <: Data](gen: T) extends Bundle { - val bits = gen.chiselCloneType + val bits0 = gen.chiselCloneType + val bits1 = gen.chiselCloneType val valid = Bool() val source = UInt(width = 2) val ready = Bool().flip @@ -83,7 +84,8 @@ class RationalCrossingSource[T <: Data](gen: T, direction: RationalDirection = S deq.valid := enq.valid deq.source := count - deq.bits := Mux(equal, enq.bits, RegEnable(enq.bits, equal)) + deq.bits0 := enq.bits + deq.bits1 := RegEnable(enq.bits, equal) enq.ready := Mux(equal, deq.ready, count(1) =/= deq.sink(0)) when (enq.fire()) { count := Cat(count(0), !count(1)) } @@ -118,7 +120,7 @@ class RationalCrossingSink[T <: Data](gen: T, direction: RationalDirection = Sym enq.ready := deq.ready enq.sink := count - deq.bits := enq.bits + deq.bits := Mux(equal, enq.bits0, enq.bits1) deq.valid := Mux(equal, enq.valid, count(1) =/= enq.source(0)) when (deq.fire()) { count := Cat(count(0), !count(1)) } @@ -160,7 +162,7 @@ object ToRational object FromRational { def apply[T <: Data](x: RationalIO[T], direction: RationalDirection = Symmetric): DecoupledIO[T] = { - val sink = Module(new RationalCrossingSink(x.bits, direction)) + val sink = Module(new RationalCrossingSink(x.bits0, direction)) sink.io.enq <> x sink.io.deq } From f473e6bad05c8e0c948d6b03e7728fd6b871d632 Mon Sep 17 00:00:00 2001 From: Yunsup Lee Date: Mon, 31 Jul 2017 15:40:54 -0700 Subject: [PATCH 2/2] tile: add optional boundary buffers --- src/main/scala/tile/RocketTile.scala | 31 +++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/src/main/scala/tile/RocketTile.scala b/src/main/scala/tile/RocketTile.scala index 4bb6661e..7323a30b 100644 --- a/src/main/scala/tile/RocketTile.scala +++ b/src/main/scala/tile/RocketTile.scala @@ -17,7 +17,8 @@ case class RocketTileParams( dcache: Option[DCacheParams] = Some(DCacheParams()), rocc: Seq[RoCCParams] = Nil, btb: Option[BTBParams] = Some(BTBParams()), - dataScratchpadBytes: Int = 0) extends TileParams { + dataScratchpadBytes: Int = 0, + boundaryBuffers: Boolean = false) extends TileParams { require(icache.isDefined) require(dcache.isDefined) } @@ -174,6 +175,26 @@ abstract class RocketTileWrapper(rtp: RocketTileParams, hartid: Int)(implicit p: rocket.intNode := intXbar.intnode + def optionalMasterBuffer(in: TLOutwardNode): TLOutwardNode = { + if (rtp.boundaryBuffers) { + val mbuf = LazyModule(new TLBuffer(BufferParams.none, BufferParams.flow, BufferParams.none, BufferParams.flow, BufferParams.default)) + mbuf.node :=* in + mbuf.node + } else { + in + } + } + + def optionalSlaveBuffer(in: TLOutwardNode): TLOutwardNode = { + if (rtp.boundaryBuffers) { + val sbuf = LazyModule(new TLBuffer(BufferParams.flow, BufferParams.none, BufferParams.none, BufferParams.none, BufferParams.none)) + sbuf.node connectButDontMonitorSlaves in + sbuf.node + } else { + in + } + } + lazy val module = new LazyModuleImp(this) { val io = new CoreBundle with HasExternallyDrivenTileConstants { val master = masterNode.bundleOut @@ -190,10 +211,10 @@ abstract class RocketTileWrapper(rtp: RocketTileParams, hartid: Int)(implicit p: class SyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends RocketTileWrapper(rtp, hartid) { val masterNode = TLOutputNode() - masterNode :=* rocket.masterNode + masterNode :=* optionalMasterBuffer(rocket.masterNode) val slaveNode = new TLInputNode() { override def reverse = true } - rocket.slaveNode connectButDontMonitorSlaves slaveNode + rocket.slaveNode connectButDontMonitorSlaves optionalSlaveBuffer(slaveNode) // Fully async interrupts need synchronizers. // Others need no synchronization. @@ -232,13 +253,13 @@ class AsyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters class RationalRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends RocketTileWrapper(rtp, hartid) { val masterNode = TLRationalOutputNode() val source = LazyModule(new TLRationalCrossingSource) - source.node :=* rocket.masterNode + source.node :=* optionalMasterBuffer(rocket.masterNode) masterNode :=* source.node val slaveNode = new TLRationalInputNode() { override def reverse = true } val sink = LazyModule(new TLRationalCrossingSink(SlowToFast)) - rocket.slaveNode connectButDontMonitorSlaves sink.node sink.node connectButDontMonitorSlaves slaveNode + rocket.slaveNode connectButDontMonitorSlaves optionalSlaveBuffer(sink.node) // Fully async interrupts need synchronizers. // Those coming from periphery clock need a