1
0

Heterogeneous Tiles (#550)

Fundamental new features:

* Added tile package: This package is intended to hold components re-usable across different types of tile. Will be the future location of TL2-RoCC accelerators and new diplomatic versions of intra-tile interfaces.
* Adopted [ModuleName]Params convention: Code base was very inconsistent about what to name case classes that provide parameters to modules. Settled on calling them [ModuleName]Params to distinguish them from config.Parameters and config.Config. So far applied mostly only to case classes defined within rocket and tile.
* Defined RocketTileParams: A nested case class containing case classes for all the components of a tile (L1 caches and core). Allows all such parameters to vary per-tile.
* Defined RocketCoreParams: All the parameters that can be varied per-core.
* Defined L1CacheParams: A trait defining the parameters common to L1 caches, made concrete in different derived case classes.
* Defined RocketTilesKey: A sequence of RocketTileParams, one for every tile to be created.
* Provided HeterogeneousDualCoreConfig: An example of making a heterogeneous chip with two cores, one big and one little.
* Changes to legacy code: ReplacementPolicy moved to package util. L1Metadata moved to package tile. Legacy L2 cache agent removed because it can no longer share the metadata array implementation with the L1. Legacy GroundTests on life support.

Additional changes that got rolled in along the way:

* rocket: 	Fix critical path through BTB for I$ index bits > pgIdxBits
* coreplex: tiles connected via :=*
* groundtest: updated to use TileParams
* tilelink: cache cork requirements are relaxed to allow more cacheless masters
This commit is contained in:
Henry Cook
2017-02-09 13:59:09 -08:00
committed by GitHub
parent f9acd4988c
commit e8c8d2af71
57 changed files with 1084 additions and 1933 deletions

View File

@ -7,12 +7,23 @@ import Chisel._
import config._
import coreplex._
import diplomacy._
import uncore.converters._
import tile._
import uncore.devices._
import uncore.tilelink2._
import util._
class RocketTile(val c: RocketConfig)(implicit p: Parameters) extends BaseTile()(p)
case class RocketTileParams(
core: RocketCoreParams = RocketCoreParams(),
icache: Option[ICacheParams] = Some(ICacheParams()),
dcache: Option[DCacheParams] = Some(DCacheParams()),
rocc: Seq[RoCCParams] = Nil,
btb: Option[BTBParams] = Some(BTBParams()),
dataScratchpadBytes: Int = 0) extends TileParams {
require(icache.isDefined)
require(dcache.isDefined)
}
class RocketTile(val rocketParams: RocketTileParams)(implicit p: Parameters) extends BaseTile(rocketParams)(p)
with CanHaveLegacyRoccs // implies CanHaveSharedFPU with CanHavePTW with HasHellaCache
with CanHaveScratchpad { // implies CanHavePTW with HasHellaCache with HasICacheFrontend
@ -28,7 +39,7 @@ class RocketTileModule(outer: RocketTile) extends BaseTileModule(outer, () => ne
with CanHaveLegacyRoccsModule
with CanHaveScratchpadModule {
val core = Module(p(BuildCore)(outer.c, outer.p))
val core = Module(p(BuildCore)(outer.p))
core.io.interrupts := io.interrupts
core.io.hartid := io.hartid
outer.frontend.module.io.cpu <> core.io.imem
@ -44,25 +55,34 @@ class RocketTileModule(outer: RocketTile) extends BaseTileModule(outer, () => ne
core.io.rocc.interrupt := lr.module.io.core.interrupt
}
// TODO eliminate this redundancy
val h = dcachePorts.size
val c = core.dcacheArbPorts
val o = outer.nDCachePorts
require(h == c, s"port list size was $h, core expected $c")
require(h == o, s"port list size was $h, outer counted $o")
// TODO figure out how to move the below into their respective mix-ins
require(dcachePorts.size == core.dcacheArbPorts)
dcacheArb.io.requestor <> dcachePorts
ptwOpt foreach { ptw => ptw.io.requestor <> ptwPorts }
}
class AsyncRocketTile(c: RocketConfig)(implicit p: Parameters) extends LazyModule {
val rocket = LazyModule(new RocketTile(c))
class AsyncRocketTile(rtp: RocketTileParams)(implicit p: Parameters) extends LazyModule {
val rocket = LazyModule(new RocketTile(rtp))
val masterNodes = rocket.masterNodes.map(_ => TLAsyncOutputNode())
val slaveNode = rocket.slaveNode.map(_ => TLAsyncInputNode())
val masterNode = TLAsyncOutputNode()
val source = LazyModule(new TLAsyncCrossingSource)
source.node :=* rocket.masterNode
masterNode :=* source.node
(rocket.masterNodes zip masterNodes) foreach { case (r,n) => n := TLAsyncCrossingSource()(r) }
(rocket.slaveNode zip slaveNode) foreach { case (r,n) => r := TLAsyncCrossingSink()(n) }
val slaveNode = TLAsyncInputNode()
val sink = LazyModule(new TLAsyncCrossingSink)
rocket.slaveNode :*= sink.node
sink.node :*= slaveNode
lazy val module = new LazyModuleImp(this) {
val io = new Bundle {
val master = masterNodes.head.bundleOut // TODO fix after Chisel #366
val slave = slaveNode.map(_.bundleIn)
val master = masterNode.bundleOut
val slave = slaveNode.bundleIn
val hartid = UInt(INPUT, p(XLen))
val interrupts = new TileInterrupts()(p).asInput
val resetVector = UInt(INPUT, p(XLen))
@ -74,19 +94,23 @@ class AsyncRocketTile(c: RocketConfig)(implicit p: Parameters) extends LazyModul
}
}
class RationalRocketTile(c: RocketConfig)(implicit p: Parameters) extends LazyModule {
val rocket = LazyModule(new RocketTile(c))
class RationalRocketTile(rtp: RocketTileParams)(implicit p: Parameters) extends LazyModule {
val rocket = LazyModule(new RocketTile(rtp))
val masterNodes = rocket.masterNodes.map(_ => TLRationalOutputNode())
val slaveNode = rocket.slaveNode.map(_ => TLRationalInputNode())
val masterNode = TLRationalOutputNode()
val source = LazyModule(new TLRationalCrossingSource)
source.node :=* rocket.masterNode
masterNode :=* source.node
(rocket.masterNodes zip masterNodes) foreach { case (r,n) => n := TLRationalCrossingSource()(r) }
(rocket.slaveNode zip slaveNode) foreach { case (r,n) => r := TLRationalCrossingSink()(n) }
val slaveNode = TLRationalInputNode()
val sink = LazyModule(new TLRationalCrossingSink)
rocket.slaveNode :*= sink.node
sink.node :*= slaveNode
lazy val module = new LazyModuleImp(this) {
val io = new Bundle {
val master = masterNodes.head.bundleOut // TODO fix after Chisel #366
val slave = slaveNode.map(_.bundleIn)
val master = masterNode.bundleOut
val slave = slaveNode.bundleIn
val hartid = UInt(INPUT, p(XLen))
val interrupts = new TileInterrupts()(p).asInput
val resetVector = UInt(INPUT, p(XLen))