Merge pull request #909 from freechipsproject/tile-buffer
add optional tile boundary buffers
This commit is contained in:
commit
71a250b071
@ -17,7 +17,8 @@ case class RocketTileParams(
|
|||||||
dcache: Option[DCacheParams] = Some(DCacheParams()),
|
dcache: Option[DCacheParams] = Some(DCacheParams()),
|
||||||
rocc: Seq[RoCCParams] = Nil,
|
rocc: Seq[RoCCParams] = Nil,
|
||||||
btb: Option[BTBParams] = Some(BTBParams()),
|
btb: Option[BTBParams] = Some(BTBParams()),
|
||||||
dataScratchpadBytes: Int = 0) extends TileParams {
|
dataScratchpadBytes: Int = 0,
|
||||||
|
boundaryBuffers: Boolean = false) extends TileParams {
|
||||||
require(icache.isDefined)
|
require(icache.isDefined)
|
||||||
require(dcache.isDefined)
|
require(dcache.isDefined)
|
||||||
}
|
}
|
||||||
@ -174,6 +175,26 @@ abstract class RocketTileWrapper(rtp: RocketTileParams, hartid: Int)(implicit p:
|
|||||||
|
|
||||||
rocket.intNode := intXbar.intnode
|
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) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = new CoreBundle with HasExternallyDrivenTileConstants {
|
val io = new CoreBundle with HasExternallyDrivenTileConstants {
|
||||||
val master = masterNode.bundleOut
|
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) {
|
class SyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends RocketTileWrapper(rtp, hartid) {
|
||||||
val masterNode = TLOutputNode()
|
val masterNode = TLOutputNode()
|
||||||
masterNode :=* rocket.masterNode
|
masterNode :=* optionalMasterBuffer(rocket.masterNode)
|
||||||
|
|
||||||
val slaveNode = new TLInputNode() { override def reverse = true }
|
val slaveNode = new TLInputNode() { override def reverse = true }
|
||||||
rocket.slaveNode connectButDontMonitorSlaves slaveNode
|
rocket.slaveNode connectButDontMonitorSlaves optionalSlaveBuffer(slaveNode)
|
||||||
|
|
||||||
// Fully async interrupts need synchronizers.
|
// Fully async interrupts need synchronizers.
|
||||||
// Others need no synchronization.
|
// 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) {
|
class RationalRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends RocketTileWrapper(rtp, hartid) {
|
||||||
val masterNode = TLRationalOutputNode()
|
val masterNode = TLRationalOutputNode()
|
||||||
val source = LazyModule(new TLRationalCrossingSource)
|
val source = LazyModule(new TLRationalCrossingSource)
|
||||||
source.node :=* rocket.masterNode
|
source.node :=* optionalMasterBuffer(rocket.masterNode)
|
||||||
masterNode :=* source.node
|
masterNode :=* source.node
|
||||||
|
|
||||||
val slaveNode = new TLRationalInputNode() { override def reverse = true }
|
val slaveNode = new TLRationalInputNode() { override def reverse = true }
|
||||||
val sink = LazyModule(new TLRationalCrossingSink(SlowToFast))
|
val sink = LazyModule(new TLRationalCrossingSink(SlowToFast))
|
||||||
rocket.slaveNode connectButDontMonitorSlaves sink.node
|
|
||||||
sink.node connectButDontMonitorSlaves slaveNode
|
sink.node connectButDontMonitorSlaves slaveNode
|
||||||
|
rocket.slaveNode connectButDontMonitorSlaves optionalSlaveBuffer(sink.node)
|
||||||
|
|
||||||
// Fully async interrupts need synchronizers.
|
// Fully async interrupts need synchronizers.
|
||||||
// Those coming from periphery clock need a
|
// Those coming from periphery clock need a
|
||||||
|
@ -49,7 +49,8 @@ case object SlowToFast extends RationalDirection {
|
|||||||
|
|
||||||
final class RationalIO[T <: Data](gen: T) extends Bundle
|
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 valid = Bool()
|
||||||
val source = UInt(width = 2)
|
val source = UInt(width = 2)
|
||||||
val ready = Bool().flip
|
val ready = Bool().flip
|
||||||
@ -83,7 +84,8 @@ class RationalCrossingSource[T <: Data](gen: T, direction: RationalDirection = S
|
|||||||
|
|
||||||
deq.valid := enq.valid
|
deq.valid := enq.valid
|
||||||
deq.source := count
|
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))
|
enq.ready := Mux(equal, deq.ready, count(1) =/= deq.sink(0))
|
||||||
|
|
||||||
when (enq.fire()) { count := Cat(count(0), !count(1)) }
|
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.ready := deq.ready
|
||||||
enq.sink := count
|
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))
|
deq.valid := Mux(equal, enq.valid, count(1) =/= enq.source(0))
|
||||||
|
|
||||||
when (deq.fire()) { count := Cat(count(0), !count(1)) }
|
when (deq.fire()) { count := Cat(count(0), !count(1)) }
|
||||||
@ -160,7 +162,7 @@ object ToRational
|
|||||||
object FromRational
|
object FromRational
|
||||||
{
|
{
|
||||||
def apply[T <: Data](x: RationalIO[T], direction: RationalDirection = Symmetric): DecoupledIO[T] = {
|
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.enq <> x
|
||||||
sink.io.deq
|
sink.io.deq
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user