Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements wrt connecting RocketTiles to SystemBus #1039

Merged
merged 11 commits into from
Oct 12, 2017
67 changes: 36 additions & 31 deletions src/main/scala/coreplex/Configs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down Expand 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)
})
})

Expand Down Expand Up @@ -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) => {
Expand Down
24 changes: 24 additions & 0 deletions src/main/scala/coreplex/PeripheryBus.scala
Original file line number Diff line number Diff line change
Expand 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
Expand Down
94 changes: 84 additions & 10 deletions src/main/scala/coreplex/RocketCoreplex.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
}
}
Expand Down
33 changes: 15 additions & 18 deletions src/main/scala/coreplex/SystemBus.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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
adapters.in :=* tile_sink.node
master_splitter.node :=* adapters.out
tile_sink.node
}

def fromRationalTiles(dir: RationalDirection, addBuffers: Int = 0, name: Option[String] = None): TLRationalInwardNode = {
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") }
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 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
}

Expand Down
Loading