coreplex: improve tile attachment adapters
This commit is contained in:
parent
2175758050
commit
95a2e6ef27
@ -31,27 +31,19 @@ class PeripheryBus(params: PeripheryBusParams)(implicit p: Parameters) extends T
|
|||||||
TLFragmenter(params.beatBytes, maxXferBytes)(outwardBufNode)
|
TLFragmenter(params.beatBytes, maxXferBytes)(outwardBufNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
def toSyncSlaves(adapt: () => TLNodeChain, name: Option[String]): TLOutwardNode = SinkCardinality { implicit p =>
|
def toSyncSlaves(adapt: TLOutwardNode => TLOutwardNode, name: Option[String]): TLOutwardNode = adapt(outwardBufNode)
|
||||||
val adapters = adapt()
|
|
||||||
adapters.in :=? outwardBufNode
|
|
||||||
adapters.out
|
|
||||||
}
|
|
||||||
|
|
||||||
def toAsyncSlaves(sync: Int, adapt: () => TLNodeChain, name: Option[String]): TLAsyncOutwardNode = SinkCardinality { implicit p =>
|
def toAsyncSlaves(sync: Int, adapt: TLOutwardNode => TLOutwardNode, name: Option[String]): TLAsyncOutwardNode = SinkCardinality { implicit p =>
|
||||||
val adapters = adapt()
|
|
||||||
val source = LazyModule(new TLAsyncCrossingSource(sync))
|
val source = LazyModule(new TLAsyncCrossingSource(sync))
|
||||||
name.foreach{ n => source.suggestName(s"${busName}_${n}_TLAsyncCrossingSource")}
|
name.foreach{ n => source.suggestName(s"${busName}_${n}_TLAsyncCrossingSource")}
|
||||||
adapters.in :=? outwardNode
|
source.node :*= adapt(outwardNode)
|
||||||
source.node :=? adapters.out
|
|
||||||
source.node
|
source.node
|
||||||
}
|
}
|
||||||
|
|
||||||
def toRationalSlaves(adapt: () => TLNodeChain, name: Option[String]): TLRationalOutwardNode = SinkCardinality { implicit p =>
|
def toRationalSlaves(adapt: TLOutwardNode => TLOutwardNode, name: Option[String]): TLRationalOutwardNode = SinkCardinality { implicit p =>
|
||||||
val adapters = adapt()
|
|
||||||
val source = LazyModule(new TLRationalCrossingSource())
|
val source = LazyModule(new TLRationalCrossingSource())
|
||||||
name.foreach{ n => source.suggestName(s"${busName}_${n}_TLRationalCrossingSource")}
|
name.foreach{ n => source.suggestName(s"${busName}_${n}_TLRationalCrossingSource")}
|
||||||
adapters.in :=? outwardNode
|
source.node :*= adapt(outwardNode)
|
||||||
source.node :=? adapters.out
|
|
||||||
source.node
|
source.node
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
package freechips.rocketchip.coreplex
|
package freechips.rocketchip.coreplex
|
||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
|
import chisel3.internal.sourceinfo.SourceInfo
|
||||||
import freechips.rocketchip.config.{Field, Parameters}
|
import freechips.rocketchip.config.{Field, Parameters}
|
||||||
import freechips.rocketchip.devices.tilelink._
|
import freechips.rocketchip.devices.tilelink._
|
||||||
import freechips.rocketchip.devices.debug.{HasPeripheryDebug, HasPeripheryDebugModuleImp}
|
import freechips.rocketchip.devices.debug.{HasPeripheryDebug, HasPeripheryDebugModuleImp}
|
||||||
@ -12,59 +13,57 @@ import freechips.rocketchip.tilelink._
|
|||||||
import freechips.rocketchip.interrupts._
|
import freechips.rocketchip.interrupts._
|
||||||
import freechips.rocketchip.util._
|
import freechips.rocketchip.util._
|
||||||
|
|
||||||
case class TLNodeChain(in: TLInwardNode, out: TLOutwardNode)
|
|
||||||
|
|
||||||
// TODO: how specific are these to RocketTiles?
|
// TODO: how specific are these to RocketTiles?
|
||||||
case class TileMasterPortParams(
|
case class TileMasterPortParams(
|
||||||
addBuffers: Int = 0,
|
addBuffers: Int = 0,
|
||||||
blockerCtrlAddr: Option[BigInt] = None,
|
blockerCtrlAddr: Option[BigInt] = None,
|
||||||
cork: Option[Boolean] = None) {
|
cork: Option[Boolean] = None) {
|
||||||
def adapterChain(coreplex: HasPeripheryBus)
|
def adapt(coreplex: HasPeripheryBus)
|
||||||
(implicit p: Parameters): () => TLNodeChain = {
|
(masterNode: TLOutwardNode)
|
||||||
|
(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
||||||
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_cork = cork.map(u => (LazyModule(new TLCacheCork(unsafe = u))))
|
||||||
val tile_master_blocker = blockerParams.map(bp => LazyModule(new BasicBusBlocker(bp)))
|
val tile_master_blocker =
|
||||||
|
blockerCtrlAddr
|
||||||
|
.map(BasicBusBlockerParams(_, coreplex.pbus.beatBytes, coreplex.sbus.beatBytes, deadlock = true))
|
||||||
|
.map(bp => LazyModule(new BasicBusBlocker(bp)))
|
||||||
val tile_master_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.allUncacheable))
|
val tile_master_fixer = LazyModule(new TLFIFOFixer(TLFIFOFixer.allUncacheable))
|
||||||
val tile_master_buffer = LazyModule(new TLBufferChain(addBuffers))
|
val tile_master_buffer = LazyModule(new TLBufferChain(addBuffers))
|
||||||
|
|
||||||
tile_master_blocker.foreach { _.controlNode := coreplex.pbus.toVariableWidthSlaves }
|
tile_master_blocker.foreach { _.controlNode := coreplex.pbus.toVariableWidthSlaves }
|
||||||
|
|
||||||
val nodes = List(
|
val node: Option[TLNode] = SourceCardinality { implicit p =>
|
||||||
Some(tile_master_buffer.node),
|
TLNodeChain(List(
|
||||||
Some(tile_master_fixer.node),
|
Some(tile_master_buffer.node),
|
||||||
tile_master_blocker.map(_.node),
|
Some(tile_master_fixer.node),
|
||||||
tile_master_cork.map(_.node)
|
tile_master_blocker.map(_.node),
|
||||||
).flatMap(b=>b)
|
tile_master_cork.map(_.node)).flatten)
|
||||||
|
}
|
||||||
nodes.init zip nodes.tail foreach { case(front, back) => front :=* back }
|
node.foreach { _ :=* masterNode }
|
||||||
|
node.getOrElse(masterNode)
|
||||||
() => TLNodeChain(in = nodes.last, out = nodes.head)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case class TileSlavePortParams(
|
case class TileSlavePortParams(
|
||||||
addBuffers: Int = 0,
|
addBuffers: Int = 0,
|
||||||
blockerCtrlAddr: Option[BigInt] = None) {
|
blockerCtrlAddr: Option[BigInt] = None) {
|
||||||
def adapterChain(coreplex: HasPeripheryBus)
|
def adapt(coreplex: HasPeripheryBus)
|
||||||
(implicit p: Parameters): () => TLNodeChain = {
|
(masterNode: TLOutwardNode)
|
||||||
|
(implicit p: Parameters, sourceInfo: SourceInfo): TLOutwardNode = {
|
||||||
val blockerParams = blockerCtrlAddr.map(BasicBusBlockerParams(_, coreplex.pbus.beatBytes, coreplex.sbus.beatBytes))
|
val tile_slave_blocker =
|
||||||
|
blockerCtrlAddr
|
||||||
val tile_slave_blocker = blockerParams.map(bp => LazyModule(new BasicBusBlocker(bp)))
|
.map(BasicBusBlockerParams(_, coreplex.pbus.beatBytes, coreplex.sbus.beatBytes))
|
||||||
|
.map(bp => LazyModule(new BasicBusBlocker(bp)))
|
||||||
val tile_slave_buffer = LazyModule(new TLBufferChain(addBuffers))
|
val tile_slave_buffer = LazyModule(new TLBufferChain(addBuffers))
|
||||||
|
|
||||||
tile_slave_blocker.foreach { _.controlNode := coreplex.pbus.toVariableWidthSlaves }
|
tile_slave_blocker.foreach { _.controlNode := coreplex.pbus.toVariableWidthSlaves }
|
||||||
|
|
||||||
val nodes = List(
|
val node: Option[TLNode] = SinkCardinality { implicit p =>
|
||||||
Some(tile_slave_buffer.node),
|
TLNodeChain(List(
|
||||||
tile_slave_blocker.map(_.node)
|
Some(tile_slave_buffer.node),
|
||||||
).flatMap(b=>b)
|
tile_slave_blocker.map(_.node)).flatten)
|
||||||
|
}
|
||||||
nodes.init zip nodes.tail foreach { case(front, back) => front :=* back }
|
node.foreach { _ :*= masterNode }
|
||||||
|
node.getOrElse(masterNode)
|
||||||
() => TLNodeChain(in = nodes.last, out = nodes.head)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,20 +110,20 @@ trait HasRocketTiles extends HasTiles
|
|||||||
val wrapper = crossing.crossingType match {
|
val wrapper = crossing.crossingType match {
|
||||||
case SynchronousCrossing(params) => {
|
case SynchronousCrossing(params) => {
|
||||||
val wrapper = LazyModule(new SyncRocketTile(tp)(pWithExtra))
|
val wrapper = LazyModule(new SyncRocketTile(tp)(pWithExtra))
|
||||||
sbus.fromSyncTiles(params, crossing.master.adapterChain(this), tp.name) :=* wrapper.masterNode
|
sbus.fromSyncTiles(params, crossing.master.adapt(this) _, tp.name) :=* wrapper.masterNode
|
||||||
FlipRendering { implicit p => wrapper.slaveNode :*= pbus.toSyncSlaves(crossing.slave.adapterChain(this), tp.name) }
|
FlipRendering { implicit p => wrapper.slaveNode:*= pbus.toSyncSlaves(crossing.slave.adapt(this) _, tp.name) }
|
||||||
wrapper
|
wrapper
|
||||||
}
|
}
|
||||||
case AsynchronousCrossing(depth, sync) => {
|
case AsynchronousCrossing(depth, sync) => {
|
||||||
val wrapper = LazyModule(new AsyncRocketTile(tp)(pWithExtra))
|
val wrapper = LazyModule(new AsyncRocketTile(tp)(pWithExtra))
|
||||||
sbus.fromAsyncTiles(depth, sync, crossing.master.adapterChain(this), tp.name) :=* wrapper.masterNode
|
sbus.fromAsyncTiles(depth, sync, crossing.master.adapt(this) _, tp.name) :=* wrapper.masterNode
|
||||||
FlipRendering { implicit p => wrapper.slaveNode :*= pbus.toAsyncSlaves(sync, crossing.slave.adapterChain(this), tp.name) }
|
FlipRendering { implicit p => wrapper.slaveNode :*= pbus.toAsyncSlaves(sync, crossing.slave.adapt(this) _, tp.name) }
|
||||||
wrapper
|
wrapper
|
||||||
}
|
}
|
||||||
case RationalCrossing(direction) => {
|
case RationalCrossing(direction) => {
|
||||||
val wrapper = LazyModule(new RationalRocketTile(tp)(pWithExtra))
|
val wrapper = LazyModule(new RationalRocketTile(tp)(pWithExtra))
|
||||||
sbus.fromRationalTiles(direction, crossing.master.adapterChain(this), tp.name) :=* wrapper.masterNode
|
sbus.fromRationalTiles(direction, crossing.master.adapt(this) _, tp.name) :=* wrapper.masterNode
|
||||||
FlipRendering { implicit p => wrapper.slaveNode :*= pbus.toRationalSlaves(crossing.slave.adapterChain(this), tp.name) }
|
FlipRendering { implicit p => wrapper.slaveNode :*= pbus.toRationalSlaves(crossing.slave.adapt(this) _, tp.name) }
|
||||||
wrapper
|
wrapper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,33 +52,27 @@ class SystemBus(params: SystemBusParams)(implicit p: Parameters) extends TLBusWr
|
|||||||
|
|
||||||
def fromFrontBus: TLInwardNode = master_splitter.node
|
def fromFrontBus: TLInwardNode = master_splitter.node
|
||||||
|
|
||||||
def fromSyncTiles(params: BufferParams, adapt: () => TLNodeChain, name: Option[String] = None): TLInwardNode = {
|
def fromSyncTiles(params: BufferParams, adapt: TLOutwardNode => TLOutwardNode, name: Option[String] = None): TLInwardNode = {
|
||||||
val adapters = adapt() // wanted to be called inside SystemBus scope
|
|
||||||
val tile_sink = LazyModule(new TLBuffer(params))
|
val tile_sink = LazyModule(new TLBuffer(params))
|
||||||
name.foreach { n => tile_sink.suggestName(s"${busName}_${n}_TLBuffer") }
|
name.foreach { n => tile_sink.suggestName(s"${busName}_${n}_TLBuffer") }
|
||||||
|
|
||||||
adapters.in :=* tile_sink.node
|
master_splitter.node :=* adapt(tile_sink.node)
|
||||||
master_splitter.node :=* adapters.out
|
|
||||||
tile_sink.node
|
tile_sink.node
|
||||||
}
|
}
|
||||||
|
|
||||||
def fromRationalTiles(dir: RationalDirection, adapt: () => TLNodeChain, name: Option[String] = None): TLRationalInwardNode = {
|
def fromRationalTiles(dir: RationalDirection, adapt: TLOutwardNode => TLOutwardNode, name: Option[String] = None): TLRationalInwardNode = {
|
||||||
val adapters = adapt() // wanted to be called inside SystemBus scope
|
|
||||||
val tile_sink = LazyModule(new TLRationalCrossingSink(direction = dir))
|
val tile_sink = LazyModule(new TLRationalCrossingSink(direction = dir))
|
||||||
name.foreach { n => tile_sink.suggestName(s"${busName}_${n}_TLRationalCrossingSink") }
|
name.foreach { n => tile_sink.suggestName(s"${busName}_${n}_TLRationalCrossingSink") }
|
||||||
|
|
||||||
adapters.in :=* tile_sink.node
|
master_splitter.node :=* adapt(tile_sink.node)
|
||||||
master_splitter.node :=* adapters.out
|
|
||||||
tile_sink.node
|
tile_sink.node
|
||||||
}
|
}
|
||||||
|
|
||||||
def fromAsyncTiles(depth: Int, sync: Int, adapt: () => TLNodeChain, name: Option[String] = None): TLAsyncInwardNode = {
|
def fromAsyncTiles(depth: Int, sync: Int, adapt: TLOutwardNode => TLOutwardNode, name: Option[String] = None): TLAsyncInwardNode = {
|
||||||
val adapters = adapt() // wanted to be called inside SystemBus scope
|
|
||||||
val tile_sink = LazyModule(new TLAsyncCrossingSink(depth, sync))
|
val tile_sink = LazyModule(new TLAsyncCrossingSink(depth, sync))
|
||||||
name.foreach { n => tile_sink.suggestName(s"${busName}_${n}_TLAsyncCrossingSink") }
|
name.foreach { n => tile_sink.suggestName(s"${busName}_${n}_TLAsyncCrossingSink") }
|
||||||
|
|
||||||
adapters.in :=* tile_sink.node
|
master_splitter.node :=* adapt(tile_sink.node)
|
||||||
master_splitter.node :=* adapters.out
|
|
||||||
tile_sink.node
|
tile_sink.node
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ class GroundTestCoreplex(implicit p: Parameters) extends BaseCoreplex
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
tiles.flatMap(_.dcacheOpt).foreach {
|
tiles.flatMap(_.dcacheOpt).foreach {
|
||||||
sbus.fromSyncTiles(BufferParams.default, TileMasterPortParams().adapterChain(this)) :=* _.node
|
sbus.fromSyncTiles(BufferParams.default, TileMasterPortParams().adapt(this) _) :=* _.node
|
||||||
}
|
}
|
||||||
|
|
||||||
val pbusRAM = LazyModule(new TLRAM(AddressSet(testRamAddr, 0xffff), true, false, pbus.beatBytes))
|
val pbusRAM = LazyModule(new TLRAM(AddressSet(testRamAddr, 0xffff), true, false, pbus.beatBytes))
|
||||||
|
@ -73,15 +73,18 @@ object TLBuffer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TLBufferChain(depth: Int)(implicit p: Parameters) extends LazyModule {
|
object TLNodeChain {
|
||||||
val buf_chain = List.fill(depth)(LazyModule(new TLBuffer(BufferParams.default)))
|
def apply(nodes: Seq[TLNode])(implicit p: Parameters): Option[TLNode] = if(nodes.size > 0) {
|
||||||
val node = if (depth > 0) {
|
(nodes.init zip nodes.tail) foreach { case (prev, next) => next :=? prev }
|
||||||
(buf_chain.init zip buf_chain.tail) foreach { case (prev, next) => next.node :=? prev.node }
|
Some(NodeHandle(nodes.head, nodes.last))
|
||||||
NodeHandle(buf_chain.head.node, buf_chain.last.node)
|
|
||||||
} else {
|
} else {
|
||||||
TLIdentityNode()
|
None
|
||||||
}
|
}
|
||||||
lazy val module = new LazyModuleImp(this) { }
|
}
|
||||||
|
|
||||||
|
class TLBufferChain(depth: Int)(implicit p: Parameters) extends SimpleLazyModule {
|
||||||
|
val buf_chain = List.fill(depth)(LazyModule(new TLBuffer(BufferParams.default)))
|
||||||
|
val node = TLNodeChain(buf_chain.map(_.node)).getOrElse(TLIdentityNode())
|
||||||
}
|
}
|
||||||
|
|
||||||
object TLBufferChain
|
object TLBufferChain
|
||||||
|
@ -9,6 +9,7 @@ package object tilelink
|
|||||||
{
|
{
|
||||||
type TLInwardNode = InwardNodeHandle[TLClientPortParameters, TLManagerPortParameters, TLBundle]
|
type TLInwardNode = InwardNodeHandle[TLClientPortParameters, TLManagerPortParameters, TLBundle]
|
||||||
type TLOutwardNode = OutwardNodeHandle[TLClientPortParameters, TLManagerPortParameters, TLBundle]
|
type TLOutwardNode = OutwardNodeHandle[TLClientPortParameters, TLManagerPortParameters, TLBundle]
|
||||||
|
type TLNode = TLInwardNode with TLOutwardNode
|
||||||
type TLAsyncInwardNode = InwardNodeHandle[TLAsyncClientPortParameters, TLAsyncManagerPortParameters, TLAsyncBundle]
|
type TLAsyncInwardNode = InwardNodeHandle[TLAsyncClientPortParameters, TLAsyncManagerPortParameters, TLAsyncBundle]
|
||||||
type TLAsyncOutwardNode = OutwardNodeHandle[TLAsyncClientPortParameters, TLAsyncManagerPortParameters, TLAsyncBundle]
|
type TLAsyncOutwardNode = OutwardNodeHandle[TLAsyncClientPortParameters, TLAsyncManagerPortParameters, TLAsyncBundle]
|
||||||
type TLRationalInwardNode = InwardNodeHandle[TLRationalClientPortParameters, TLRationalManagerPortParameters, TLRationalBundle]
|
type TLRationalInwardNode = InwardNodeHandle[TLRationalClientPortParameters, TLRationalManagerPortParameters, TLRationalBundle]
|
||||||
|
Loading…
Reference in New Issue
Block a user