From ff583e9e1f5c136d65f510c35584fe2ffff46815 Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Wed, 20 May 2020 15:44:07 -0700 Subject: [PATCH 01/27] first attempt decoupling --- .../src/main/scala/ConfigFragments.scala | 23 +++++++++--- .../src/main/scala/CoreRegistrar.scala | 37 +++++++++++++++++++ .../chipyard/src/main/scala/Subsystem.scala | 33 ++++++++++------- .../chipyard/src/main/scala/TestSuites.scala | 11 +++--- .../scala/stage/phases/AddDefaultTests.scala | 4 +- 5 files changed, 82 insertions(+), 26 deletions(-) create mode 100644 generators/chipyard/src/main/scala/CoreRegistrar.scala diff --git a/generators/chipyard/src/main/scala/ConfigFragments.scala b/generators/chipyard/src/main/scala/ConfigFragments.scala index 72eaa414..3db4f326 100644 --- a/generators/chipyard/src/main/scala/ConfigFragments.scala +++ b/generators/chipyard/src/main/scala/ConfigFragments.scala @@ -3,7 +3,7 @@ package chipyard.config import chisel3._ import chisel3.util.{log2Up} -import freechips.rocketchip.config.{Field, Parameters, Config} +import freechips.rocketchip.config.{Field, Parameters, Config, View} import freechips.rocketchip.subsystem.{SystemBusKey, RocketTilesKey, WithRoccExample, WithNMemoryChannels, WithNBigCores, WithRV32, CacheBlockBytes} import freechips.rocketchip.diplomacy.{LazyModule, ValName} import freechips.rocketchip.devices.tilelink.BootROMParams @@ -13,7 +13,6 @@ import freechips.rocketchip.rocket.{RocketCoreParams, MulDivParams, DCacheParams import freechips.rocketchip.util.{AsyncResetReg} import boom.common.{BoomTilesKey} -import ariane.{ArianeTilesKey} import testchipip._ import hwacha.{Hwacha} @@ -23,6 +22,7 @@ import sifive.blocks.devices.uart._ import sifive.blocks.devices.spi._ import chipyard.{BuildTop, BuildSystem} +import chipyard.{CoreRegistrar, CoreRegisterEntryBase} /** * TODO: Why do we need this? @@ -147,8 +147,21 @@ class WithControlCore extends Config((site, here, up) => { case MaxHartIdBits => log2Up(up(RocketTilesKey, site).size + up(BoomTilesKey, site).size + 1) }) +trait TraceIOMatch { + this: CoreRegisterEntryBase => + val matchTile: (View, View, View) => PartialFunction[Field[Seq[TileParams]],Any] = ((site, here, up) => { + // TODO: XXX What's the "tile" here? + case tilesKey => up(tilesKey) map (tile => tile.copy(trace = true)) + }) +} + class WithTraceIO extends Config((site, here, up) => { - case BoomTilesKey => up(BoomTilesKey) map (tile => tile.copy(trace = true)) - case ArianeTilesKey => up(ArianeTilesKey) map (tile => tile.copy(trace = true)) - case TracePortKey => Some(TracePortParams()) + val coreMatch = (coreList: List[CoreRegisterEntryBase]) => coreList match { + case coreEntry :: tail => coreEntry.matchTile(site, here, up) orElse coreMatch(tail) + case Nil => { + case BoomTilesKey => up(BoomTilesKey) map (tile => tile.copy(trace = true)) + case TracePortKey => Some(TracePortParams()) + } + } + coreMatch(CoreRegistrar.cores) }) diff --git a/generators/chipyard/src/main/scala/CoreRegistrar.scala b/generators/chipyard/src/main/scala/CoreRegistrar.scala new file mode 100644 index 00000000..a0b1625c --- /dev/null +++ b/generators/chipyard/src/main/scala/CoreRegistrar.scala @@ -0,0 +1,37 @@ +package chipyard + +import chisel3._ + +import freechips.rocketchip.config.{Parameters, Config, Field} +import freechips.rocketchip.subsystem.{SystemBusKey, RocketTilesKey, RocketCrossingParams} +import freechips.rocketchip.devices.tilelink.{BootROMParams} +import freechips.rocketchip.diplomacy.{SynchronousCrossing, AsynchronousCrossing, RationalCrossing} +import freechips.rocketchip.rocket._ +import freechips.rocketchip.tile._ + +import ariane.{ArianeTile, ArianeTilesKey, ArianeCrossingKey, ArianeTileParams} + +import chipyard.config.TraceIOMatch + +// Third-party core entries +sealed trait CoreRegisterEntryBase { + type Tile + type TitleParams + def tilesKey: Field[Seq[TitleParams]] + def crossingKey: Field[Seq[RocketCrossingParams]] +} + +class CoreRegisterEntry[TileT <: BaseTile, TileParamsT <: CoreParams](tk: Field[Seq[TileParamsT]], ck: Field[Seq[RocketCrossingParams]]) + extends CoreRegisterEntryBase with TraceIOMatch { + type Tile = TileT + type TileParams = TileParamsT + def tilesKey = tk + def crossingKey = ck +} + +object CoreRegistrar { + val cores: List[CoreRegisterEntryBase] = List( + // ADD YOUR CORE DEFINITION HERE + new CoreRegisterEntry[ArianeTile, ArianeTileParams](ArianeTilesKey, ArianeCrossingKey) + ) +} \ No newline at end of file diff --git a/generators/chipyard/src/main/scala/Subsystem.scala b/generators/chipyard/src/main/scala/Subsystem.scala index 99c31472..fcb58fc4 100644 --- a/generators/chipyard/src/main/scala/Subsystem.scala +++ b/generators/chipyard/src/main/scala/Subsystem.scala @@ -22,7 +22,6 @@ import freechips.rocketchip.subsystem._ import freechips.rocketchip.amba.axi4._ import boom.common.{BoomTile, BoomTilesKey, BoomCrossingKey, BoomTileParams} -import ariane.{ArianeTile, ArianeTilesKey, ArianeCrossingKey, ArianeTileParams} import testchipip.{DromajoHelper} @@ -36,14 +35,17 @@ trait HasChipyardTiles extends HasTiles protected val rocketTileParams = p(RocketTilesKey) protected val boomTileParams = p(BoomTilesKey) - protected val arianeTileParams = p(ArianeTilesKey) + protected val coreTileParams = CoreRegistrar.cores map (coreType => p(coreType.tilesKey)) // crossing can either be per tile or global (aka only 1 crossing specified) private val rocketCrossings = perTileOrGlobalSetting(p(RocketCrossingKey), rocketTileParams.size) private val boomCrossings = perTileOrGlobalSetting(p(BoomCrossingKey), boomTileParams.size) - private val arianeCrossings = perTileOrGlobalSetting(p(ArianeCrossingKey), arianeTileParams.size) + private val coreCrossings = (CoreRegistrar.cores zip coreTileParams) map ((coreType, tileParams) => + perTileOrGlobalSetting(p(coreType.crossingKey), tileParams.size)) - val allTilesInfo = (rocketTileParams ++ boomTileParams ++ arianeTileParams) zip (rocketCrossings ++ boomCrossings ++ arianeCrossings) + // TODO: XXX The "tiles" below scan for hartId but it is not in CoreParams. Should that be added in later + // revision, or I have to use reflection to get that parameter? + val allTilesInfo = (rocketTileParams ++ boomTileParams ++ coreTileParams) zip (rocketCrossings ++ boomCrossings ++ coreCrossings) // Make a tile and wire its nodes into the system, // according to the specified type of clock crossing. @@ -55,17 +57,22 @@ trait HasChipyardTiles extends HasTiles val tiles = allTilesInfo.sortWith(_._1.hartId < _._1.hartId).map { case (param, crossing) => { - val tile = param match { - case r: RocketTileParams => { - LazyModule(new RocketTile(r, crossing, PriorityMuxHartIdFromSeq(rocketTileParams), logicalTreeNode)) - } - case b: BoomTileParams => { - LazyModule(new BoomTile(b, crossing, PriorityMuxHartIdFromSeq(boomTileParams), logicalTreeNode)) - } - case a: ArianeTileParams => { - LazyModule(new ArianeTile(a, crossing, PriorityMuxHartIdFromSeq(arianeTileParams), logicalTreeNode)) + val tileMatch = coreAndtileParamsList => { + case (coreType, tileParams) :: tail => (param => { + case a: coreType.TileParams => { + LazyModule(new coreType.Tile(a, crossing, PriorityMuxHartIdFromSeq(tileParams), logicalTreeNode)) + } + }) orElse tileMatch(tail) + case Nil => param => { + case r: RocketTileParams => { + LazyModule(new RocketTile(r, crossing, PriorityMuxHartIdFromSeq(rocketTileParams), logicalTreeNode)) + } + case b: BoomTileParams => { + LazyModule(new BoomTile(b, crossing, PriorityMuxHartIdFromSeq(boomTileParams), logicalTreeNode)) + } } } + val tile = tileMatch(CoreRegistrar.cores zip coreTileParams) connectMasterPortsToSBus(tile, crossing) connectSlavePortsToCBus(tile, crossing) connectInterrupts(tile, debugOpt, clintOpt, plicOpt) diff --git a/generators/chipyard/src/main/scala/TestSuites.scala b/generators/chipyard/src/main/scala/TestSuites.scala index 9fdef05a..f90e3d23 100644 --- a/generators/chipyard/src/main/scala/TestSuites.scala +++ b/generators/chipyard/src/main/scala/TestSuites.scala @@ -3,12 +3,11 @@ package chipyard import scala.collection.mutable.{LinkedHashSet} import freechips.rocketchip.subsystem.{RocketTilesKey} -import freechips.rocketchip.tile.{XLen} -import freechips.rocketchip.config.{Parameters} +import freechips.rocketchip.tile.{XLen, CoreParams} +import freechips.rocketchip.config.{Parameters, Field} import freechips.rocketchip.system.{TestGeneration, RegressionTestSuite, RocketTestSuite} import boom.common.{BoomTilesKey} -import ariane.{ArianeTilesKey} /** * A set of pre-chosen regression tests @@ -144,11 +143,11 @@ class TestSuiteHelper } /** - * Add Ariane tests (asm, bmark, regression) + * Add third-party core (including Ariane) tests (asm, bmark, regression) */ - def addArianeTestSuites(implicit p: Parameters) = { + def addThirdPartyTestSuites[TileParams <: CoreParams](tilesKey: Field[Seq[TileParams]])(implicit p: Parameters) = { val xlen = p(XLen) - p(ArianeTilesKey).find(_.hartId == 0).map { tileParams => + p(tilesKey).find(_.hartId == 0).map { tileParams => val coreParams = tileParams.core val vm = coreParams.useVM val env = if (vm) List("p","v") else List("p") diff --git a/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala b/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala index fce5d432..3d367ffa 100644 --- a/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala +++ b/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala @@ -17,7 +17,7 @@ import freechips.rocketchip.stage.phases.{RocketTestSuiteAnnotation} import freechips.rocketchip.system.{RocketTestSuite, TestGeneration} import freechips.rocketchip.util.HasRocketChipStageUtils -import chipyard.TestSuiteHelper +import chipyard.{TestSuiteHelper, CoreRegistrar} class AddDefaultTests extends Phase with PreservesAll[Phase] with HasRocketChipStageUtils { // Make sure we run both after RocketChip's version of this phase, and Rocket Chip's annotation emission phase @@ -32,7 +32,7 @@ class AddDefaultTests extends Phase with PreservesAll[Phase] with HasRocketChipS val suiteHelper = new TestSuiteHelper suiteHelper.addRocketTestSuites suiteHelper.addBoomTestSuites - suiteHelper.addArianeTestSuites + CoreRegistrar.cores map suiteHelper.addThirdPartyTestSuites(_.tilesKey) // if hwacha parameter exists then generate its tests // TODO: find a more elegant way to do this. either through From adb85c98caed9190abae7a927ee68fb61e5b4a33 Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Thu, 21 May 2020 12:35:26 -0700 Subject: [PATCH 02/27] Some Revisions --- .../src/main/scala/ConfigFragments.scala | 21 +++++-------- .../src/main/scala/CoreRegistrar.scala | 31 ++++++++++++------- .../chipyard/src/main/scala/Subsystem.scala | 30 ++++++++---------- 3 files changed, 39 insertions(+), 43 deletions(-) diff --git a/generators/chipyard/src/main/scala/ConfigFragments.scala b/generators/chipyard/src/main/scala/ConfigFragments.scala index 3db4f326..6eca517f 100644 --- a/generators/chipyard/src/main/scala/ConfigFragments.scala +++ b/generators/chipyard/src/main/scala/ConfigFragments.scala @@ -147,21 +147,14 @@ class WithControlCore extends Config((site, here, up) => { case MaxHartIdBits => log2Up(up(RocketTilesKey, site).size + up(BoomTilesKey, site).size + 1) }) -trait TraceIOMatch { - this: CoreRegisterEntryBase => - val matchTile: (View, View, View) => PartialFunction[Field[Seq[TileParams]],Any] = ((site, here, up) => { - // TODO: XXX What's the "tile" here? - case tilesKey => up(tilesKey) map (tile => tile.copy(trace = true)) - }) -} - class WithTraceIO extends Config((site, here, up) => { - val coreMatch = (coreList: List[CoreRegisterEntryBase]) => coreList match { - case coreEntry :: tail => coreEntry.matchTile(site, here, up) orElse coreMatch(tail) - case Nil => { - case BoomTilesKey => up(BoomTilesKey) map (tile => tile.copy(trace = true)) - case TracePortKey => Some(TracePortParams()) + val coreMatch: List[CoreRegisterEntryBase] => PartialFunction[Any,Any] = + coreList => coreList match { + case coreEntry :: tail => coreEntry.enableTileTrace(site, here, up) orElse coreMatch(tail) + case Nil => { + case BoomTilesKey => up(BoomTilesKey) map (tile => tile.copy(trace = true)) + case TracePortKey => Some(TracePortParams()) + } } - } coreMatch(CoreRegistrar.cores) }) diff --git a/generators/chipyard/src/main/scala/CoreRegistrar.scala b/generators/chipyard/src/main/scala/CoreRegistrar.scala index a0b1625c..b1503361 100644 --- a/generators/chipyard/src/main/scala/CoreRegistrar.scala +++ b/generators/chipyard/src/main/scala/CoreRegistrar.scala @@ -2,36 +2,43 @@ package chipyard import chisel3._ -import freechips.rocketchip.config.{Parameters, Config, Field} +import freechips.rocketchip.config.{Parameters, Config, Field, View} import freechips.rocketchip.subsystem.{SystemBusKey, RocketTilesKey, RocketCrossingParams} -import freechips.rocketchip.devices.tilelink.{BootROMParams} -import freechips.rocketchip.diplomacy.{SynchronousCrossing, AsynchronousCrossing, RationalCrossing} +import freechips.rocketchip.diplomacy.LazyModule +import freechips.rocketchip.diplomaticobjectmodel.logicaltree.LogicalTreeNode import freechips.rocketchip.rocket._ import freechips.rocketchip.tile._ import ariane.{ArianeTile, ArianeTilesKey, ArianeCrossingKey, ArianeTileParams} -import chipyard.config.TraceIOMatch - // Third-party core entries sealed trait CoreRegisterEntryBase { - type Tile - type TitleParams - def tilesKey: Field[Seq[TitleParams]] + type TileParams <: CoreParams + def tilesKey: Field[Seq[TileParams]] def crossingKey: Field[Seq[RocketCrossingParams]] + def enableTileTrace(site: View, here: View, up: View): PartialFunction[Any, Any] + def instantiateTile(param: TileParams, crossing: RocketCrossingParams, + logicalTreeNode: LogicalTreeNode, p: Parameters): Option[BaseTile] } -class CoreRegisterEntry[TileT <: BaseTile, TileParamsT <: CoreParams](tk: Field[Seq[TileParamsT]], ck: Field[Seq[RocketCrossingParams]]) - extends CoreRegisterEntryBase with TraceIOMatch { - type Tile = TileT +class CoreRegisterEntry[TileParamsT <: CoreParams, TileT <: BaseTile](tk: Field[Seq[TileParamsT]], ck: Field[Seq[RocketCrossingParams]], + tileInstantiator: (TileParamsT, RocketCrossingParams, LookupByHartIdImpl, LogicalTreeNode, Parameters) => TileT) extends CoreRegisterEntryBase { type TileParams = TileParamsT def tilesKey = tk def crossingKey = ck + def enableTileTrace(site: View, here: View, up: View): PartialFunction[Any, Any] = { + case in if in == tilesKey => up(this.tilesKey) map (tile => tile.copy(trace = true)) + } + def instantiateTile(param: TileParams, crossing: RocketCrossingParams, + logicalTreeNode: LogicalTreeNode, p: Parameters): Option[BaseTile] = param match { + case a: TileParams => Some(tileInstantiator(a, crossing, PriorityMuxHartIdFromSeq(p(tilesKey)), logicalTreeNode, p)) + case _ => None + } } object CoreRegistrar { val cores: List[CoreRegisterEntryBase] = List( // ADD YOUR CORE DEFINITION HERE - new CoreRegisterEntry[ArianeTile, ArianeTileParams](ArianeTilesKey, ArianeCrossingKey) + new CoreRegisterEntry[ArianeTileParams, ArianeTile](ArianeTilesKey, ArianeCrossingKey, ((a, b, c, d, p) => {new ArianeTile(a, b, c, d)})) ) } \ No newline at end of file diff --git a/generators/chipyard/src/main/scala/Subsystem.scala b/generators/chipyard/src/main/scala/Subsystem.scala index fcb58fc4..7b554d2a 100644 --- a/generators/chipyard/src/main/scala/Subsystem.scala +++ b/generators/chipyard/src/main/scala/Subsystem.scala @@ -40,12 +40,13 @@ trait HasChipyardTiles extends HasTiles // crossing can either be per tile or global (aka only 1 crossing specified) private val rocketCrossings = perTileOrGlobalSetting(p(RocketCrossingKey), rocketTileParams.size) private val boomCrossings = perTileOrGlobalSetting(p(BoomCrossingKey), boomTileParams.size) - private val coreCrossings = (CoreRegistrar.cores zip coreTileParams) map ((coreType, tileParams) => - perTileOrGlobalSetting(p(coreType.crossingKey), tileParams.size)) + private val coreCrossings = (CoreRegistrar.cores zip coreTileParams) map (_ match { + case (coreType, tileParams) => perTileOrGlobalSetting(p(coreType.crossingKey), tileParams.size) + }) // TODO: XXX The "tiles" below scan for hartId but it is not in CoreParams. Should that be added in later // revision, or I have to use reflection to get that parameter? - val allTilesInfo = (rocketTileParams ++ boomTileParams ++ coreTileParams) zip (rocketCrossings ++ boomCrossings ++ coreCrossings) + val allTilesInfo = (rocketTileParams ++ boomTileParams ++ coreTileParams.flatten) zip (rocketCrossings ++ boomCrossings ++ coreCrossings.flatten) // Make a tile and wire its nodes into the system, // according to the specified type of clock crossing. @@ -57,22 +58,17 @@ trait HasChipyardTiles extends HasTiles val tiles = allTilesInfo.sortWith(_._1.hartId < _._1.hartId).map { case (param, crossing) => { - val tileMatch = coreAndtileParamsList => { - case (coreType, tileParams) :: tail => (param => { - case a: coreType.TileParams => { - LazyModule(new coreType.Tile(a, crossing, PriorityMuxHartIdFromSeq(tileParams), logicalTreeNode)) - } - }) orElse tileMatch(tail) - case Nil => param => { - case r: RocketTileParams => { - LazyModule(new RocketTile(r, crossing, PriorityMuxHartIdFromSeq(rocketTileParams), logicalTreeNode)) - } - case b: BoomTileParams => { - LazyModule(new BoomTile(b, crossing, PriorityMuxHartIdFromSeq(boomTileParams), logicalTreeNode)) - } + val tile = param match { + case r: RocketTileParams => { + LazyModule(new RocketTile(r, crossing, PriorityMuxHartIdFromSeq(rocketTileParams), logicalTreeNode)) } + case b: BoomTileParams => { + LazyModule(new BoomTile(b, crossing, PriorityMuxHartIdFromSeq(boomTileParams), logicalTreeNode)) + } + case _ => LazyModule( + (CoreRegistrar.cores collect (core => core.instantiateTile(param, crossing, paramList, logicalTreeNode, p)).unlift()) (0) + ) } - val tile = tileMatch(CoreRegistrar.cores zip coreTileParams) connectMasterPortsToSBus(tile, crossing) connectSlavePortsToCBus(tile, crossing) connectInterrupts(tile, debugOpt, clintOpt, plicOpt) From 15c1f5adba5d6c56748573beaa32432a437338d4 Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Mon, 25 May 2020 10:47:58 -0700 Subject: [PATCH 03/27] Sync works to my laptop --- .../src/main/scala/ConfigFragments.scala | 7 +++++ .../src/main/scala/CoreRegistrar.scala | 30 +++++++++++++++++-- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/generators/chipyard/src/main/scala/ConfigFragments.scala b/generators/chipyard/src/main/scala/ConfigFragments.scala index 6eca517f..cdf84327 100644 --- a/generators/chipyard/src/main/scala/ConfigFragments.scala +++ b/generators/chipyard/src/main/scala/ConfigFragments.scala @@ -23,6 +23,7 @@ import sifive.blocks.devices.spi._ import chipyard.{BuildTop, BuildSystem} import chipyard.{CoreRegistrar, CoreRegisterEntryBase} +import chipyard.hlist /** * TODO: Why do we need this? @@ -147,6 +148,12 @@ class WithControlCore extends Config((site, here, up) => { case MaxHartIdBits => log2Up(up(RocketTilesKey, site).size + up(BoomTilesKey, site).size + 1) }) +class WithTraceIOHMap extends ConfigHMap { + override def apply[I](v: I) = (site, here, up) => { + + } +} + class WithTraceIO extends Config((site, here, up) => { val coreMatch: List[CoreRegisterEntryBase] => PartialFunction[Any,Any] = coreList => coreList match { diff --git a/generators/chipyard/src/main/scala/CoreRegistrar.scala b/generators/chipyard/src/main/scala/CoreRegistrar.scala index b1503361..766172d1 100644 --- a/generators/chipyard/src/main/scala/CoreRegistrar.scala +++ b/generators/chipyard/src/main/scala/CoreRegistrar.scala @@ -1,5 +1,8 @@ package chipyard +import scala.reflect.ClassTag +import scala.reflect.runtime.universe._ + import chisel3._ import freechips.rocketchip.config.{Parameters, Config, Field, View} @@ -16,16 +19,27 @@ sealed trait CoreRegisterEntryBase { type TileParams <: CoreParams def tilesKey: Field[Seq[TileParams]] def crossingKey: Field[Seq[RocketCrossingParams]] + + def findTilesWithFilter(view: View, p: Any => View): PartialFunction[Any, Seq[AnyRef]] + def enableTileTrace(site: View, here: View, up: View): PartialFunction[Any, Any] def instantiateTile(param: TileParams, crossing: RocketCrossingParams, logicalTreeNode: LogicalTreeNode, p: Parameters): Option[BaseTile] } -class CoreRegisterEntry[TileParamsT <: CoreParams, TileT <: BaseTile](tk: Field[Seq[TileParamsT]], ck: Field[Seq[RocketCrossingParams]], - tileInstantiator: (TileParamsT, RocketCrossingParams, LookupByHartIdImpl, LogicalTreeNode, Parameters) => TileT) extends CoreRegisterEntryBase { +class CoreRegisterEntry[TileParamsT <: CoreParams, TileT <: BaseTile]( + tk: Field[Seq[TileParamsT]], + ck: Field[Seq[RocketCrossingParams]], + tileInstantiator: (TileParamsT, RocketCrossingParams, LookupByHartIdImpl, LogicalTreeNode, Parameters) => TileT +) extends CoreRegisterEntryBase { type TileParams = TileParamsT def tilesKey = tk def crossingKey = ck + + def findTilesWithFilter(view: View, p: Any => View) = { + case key if (key == tk && p(tk)) => view(tk) + } + def enableTileTrace(site: View, here: View, up: View): PartialFunction[Any, Any] = { case in if in == tilesKey => up(this.tilesKey) map (tile => tile.copy(trace = true)) } @@ -41,4 +55,14 @@ object CoreRegistrar { // ADD YOUR CORE DEFINITION HERE new CoreRegisterEntry[ArianeTileParams, ArianeTile](ArianeTilesKey, ArianeCrossingKey, ((a, b, c, d, p) => {new ArianeTile(a, b, c, d)})) ) -} \ No newline at end of file +} + +// Core Generic Config - change properties in the given map +class GenericConfig(properties: Map[String, Any], filterFunc: Any => Bool = (_ => true)) { + val configFunc: (View, View, View) => PartialFunction[Any, Any] = ((site, here, up) => key => { + val tiles = CoreRegistrar.cores flatMap _.findTilesWithFilter(up, filterFunc).lift(key) + if (tiles.size == 0) None else Some(tiles map (tile => { + val method = ClassTag(tile.getClass).member(TermName(methodName)).asMethod + })).unlift + }).unlift +} From c0bafa306c694764d3593bab8d4717023c434821 Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Mon, 25 May 2020 13:22:28 -0700 Subject: [PATCH 04/27] Config Done --- .../src/main/scala/ConfigFragments.scala | 22 ++---- .../chipyard/src/main/scala/CoreManager.scala | 76 +++++++++++++++++++ .../src/main/scala/CoreRegistrar.scala | 68 ----------------- .../chipyard/src/main/scala/TestSuites.scala | 2 +- 4 files changed, 82 insertions(+), 86 deletions(-) create mode 100644 generators/chipyard/src/main/scala/CoreManager.scala delete mode 100644 generators/chipyard/src/main/scala/CoreRegistrar.scala diff --git a/generators/chipyard/src/main/scala/ConfigFragments.scala b/generators/chipyard/src/main/scala/ConfigFragments.scala index cdf84327..e87b833a 100644 --- a/generators/chipyard/src/main/scala/ConfigFragments.scala +++ b/generators/chipyard/src/main/scala/ConfigFragments.scala @@ -148,20 +148,8 @@ class WithControlCore extends Config((site, here, up) => { case MaxHartIdBits => log2Up(up(RocketTilesKey, site).size + up(BoomTilesKey, site).size + 1) }) -class WithTraceIOHMap extends ConfigHMap { - override def apply[I](v: I) = (site, here, up) => { - - } -} - -class WithTraceIO extends Config((site, here, up) => { - val coreMatch: List[CoreRegisterEntryBase] => PartialFunction[Any,Any] = - coreList => coreList match { - case coreEntry :: tail => coreEntry.enableTileTrace(site, here, up) orElse coreMatch(tail) - case Nil => { - case BoomTilesKey => up(BoomTilesKey) map (tile => tile.copy(trace = true)) - case TracePortKey => Some(TracePortParams()) - } - } - coreMatch(CoreRegistrar.cores) -}) +class WithTraceIO extends Config((site, here, up) => + GenericConfig(Map("trace" -> true)) (site, here, up) orElse { + case BoomTilesKey => up(BoomTilesKey) map (tile => tile.copy(trace = true)) + case TracePortKey => Some(TracePortParams()) + }) diff --git a/generators/chipyard/src/main/scala/CoreManager.scala b/generators/chipyard/src/main/scala/CoreManager.scala new file mode 100644 index 00000000..72c5dc85 --- /dev/null +++ b/generators/chipyard/src/main/scala/CoreManager.scala @@ -0,0 +1,76 @@ +package chipyard + +import scala.reflect.ClassTag +import scala.reflect.runtime.universe._ + +import chisel3._ + +import freechips.rocketchip.config.{Parameters, Config, Field, View} +import freechips.rocketchip.subsystem.{SystemBusKey, RocketTilesKey, RocketCrossingParams} +import freechips.rocketchip.diplomacy.LazyModule +import freechips.rocketchip.diplomaticobjectmodel.logicaltree.LogicalTreeNode +import freechips.rocketchip.rocket._ +import freechips.rocketchip.tile._ + +import ariane.{ArianeTile, ArianeTilesKey, ArianeCrossingKey, ArianeTileParams} + +// Third-party core entries +sealed trait CoreEntryBase { + def updateWithFilter(view: View, p: Any => View): (Map[String, Any] => PartialFunction[Any, Seq[AnyRef]]) + + def instantiateTile(param: TileParams, crossing: RocketCrossingParams, + logicalTreeNode: LogicalTreeNode, p: Parameters): Option[BaseTile] +} + +class CoreEntry[TileParamsT <: CoreParams, TileT <: BaseTile]( + tk: Field[Seq[TileParamsT]], + ck: Field[Seq[RocketCrossingParams]] +) extends CoreEntryBase { + private val mirror = runtimeMirror(getClass.getClassLoader) + private val paramClass = mirror.runtimeClass(typeOf[TileParamsT].typeSymbol.asClass) + private val paramNames = Map((paramClass.getDeclaredFields map _.getName).zipWithIndex) + private val paramCtr = paramClass.getConstructors.head + + private val tileClass = mirror.runtimeClass(typeOf[TileT].typeSymbol.asClass) + private val tileCtr = paramClass.getConstructors.head + + // copy() function in + def copyTileParam(tileParam: AnyRef, properties: Map[String, Any]) = { + val values = foo.productIterator.toList + val indexedProperties = properties map (key => (paramNames(key), properties(key))) + val newValues = (0 until values.size) map + (i => if (indexedProperties contains i) indexedProperties(i) else values(i)) + paramCtr.newInstance(newValues:_*) + } + + def updateWithFilter(view: View, p: Any => View) = { + case key if (key == tk && p(tk)) => view(tk) map + (tile => properties => copyTileParam(tile, properties)) + } + + def instantiateTile(param: TileParams, crossing: RocketCrossingParams, + logicalTreeNode: LogicalTreeNode, p: Parameters): Option[BaseTile] = param match { + case a: TileParams => Some(tileCtr.newInstance(a, crossing, PriorityMuxHartIdFromSeq(p(tilesKey)), logicalTreeNode, p)) + case _ => None + } +} + +object CoreManager { + val cores: List[CoreEntryBase] = List( + // ADD YOUR CORE DEFINITION HERE + new CoreEntry[ArianeTileParams, ArianeTile](ArianeTilesKey, ArianeCrossingKey) + ) +} + +// Core Generic Config - change properties in the given map +class GenericConfig(properties: Map[String, Any], filterFunc: Any => Bool) { + val configFunc: (View, View, View) => PartialFunction[Any, Any] = ((site, here, up) => key => { + val tiles = CoreManager.cores flatMap _.updateWithFilter(up, filterFunc).lift(key) + if (tiles.size == 0) None else Some(tiles map _(properties)) + }).unlift +} + +object GenericConfig { + def apply(properties: Map[String, Any], filterFunc: Any => Bool = (_ => true)) = + new GenericConfig(properties, filterFunc).configFunc +} diff --git a/generators/chipyard/src/main/scala/CoreRegistrar.scala b/generators/chipyard/src/main/scala/CoreRegistrar.scala deleted file mode 100644 index 766172d1..00000000 --- a/generators/chipyard/src/main/scala/CoreRegistrar.scala +++ /dev/null @@ -1,68 +0,0 @@ -package chipyard - -import scala.reflect.ClassTag -import scala.reflect.runtime.universe._ - -import chisel3._ - -import freechips.rocketchip.config.{Parameters, Config, Field, View} -import freechips.rocketchip.subsystem.{SystemBusKey, RocketTilesKey, RocketCrossingParams} -import freechips.rocketchip.diplomacy.LazyModule -import freechips.rocketchip.diplomaticobjectmodel.logicaltree.LogicalTreeNode -import freechips.rocketchip.rocket._ -import freechips.rocketchip.tile._ - -import ariane.{ArianeTile, ArianeTilesKey, ArianeCrossingKey, ArianeTileParams} - -// Third-party core entries -sealed trait CoreRegisterEntryBase { - type TileParams <: CoreParams - def tilesKey: Field[Seq[TileParams]] - def crossingKey: Field[Seq[RocketCrossingParams]] - - def findTilesWithFilter(view: View, p: Any => View): PartialFunction[Any, Seq[AnyRef]] - - def enableTileTrace(site: View, here: View, up: View): PartialFunction[Any, Any] - def instantiateTile(param: TileParams, crossing: RocketCrossingParams, - logicalTreeNode: LogicalTreeNode, p: Parameters): Option[BaseTile] -} - -class CoreRegisterEntry[TileParamsT <: CoreParams, TileT <: BaseTile]( - tk: Field[Seq[TileParamsT]], - ck: Field[Seq[RocketCrossingParams]], - tileInstantiator: (TileParamsT, RocketCrossingParams, LookupByHartIdImpl, LogicalTreeNode, Parameters) => TileT -) extends CoreRegisterEntryBase { - type TileParams = TileParamsT - def tilesKey = tk - def crossingKey = ck - - def findTilesWithFilter(view: View, p: Any => View) = { - case key if (key == tk && p(tk)) => view(tk) - } - - def enableTileTrace(site: View, here: View, up: View): PartialFunction[Any, Any] = { - case in if in == tilesKey => up(this.tilesKey) map (tile => tile.copy(trace = true)) - } - def instantiateTile(param: TileParams, crossing: RocketCrossingParams, - logicalTreeNode: LogicalTreeNode, p: Parameters): Option[BaseTile] = param match { - case a: TileParams => Some(tileInstantiator(a, crossing, PriorityMuxHartIdFromSeq(p(tilesKey)), logicalTreeNode, p)) - case _ => None - } -} - -object CoreRegistrar { - val cores: List[CoreRegisterEntryBase] = List( - // ADD YOUR CORE DEFINITION HERE - new CoreRegisterEntry[ArianeTileParams, ArianeTile](ArianeTilesKey, ArianeCrossingKey, ((a, b, c, d, p) => {new ArianeTile(a, b, c, d)})) - ) -} - -// Core Generic Config - change properties in the given map -class GenericConfig(properties: Map[String, Any], filterFunc: Any => Bool = (_ => true)) { - val configFunc: (View, View, View) => PartialFunction[Any, Any] = ((site, here, up) => key => { - val tiles = CoreRegistrar.cores flatMap _.findTilesWithFilter(up, filterFunc).lift(key) - if (tiles.size == 0) None else Some(tiles map (tile => { - val method = ClassTag(tile.getClass).member(TermName(methodName)).asMethod - })).unlift - }).unlift -} diff --git a/generators/chipyard/src/main/scala/TestSuites.scala b/generators/chipyard/src/main/scala/TestSuites.scala index f90e3d23..a4944355 100644 --- a/generators/chipyard/src/main/scala/TestSuites.scala +++ b/generators/chipyard/src/main/scala/TestSuites.scala @@ -147,7 +147,7 @@ class TestSuiteHelper */ def addThirdPartyTestSuites[TileParams <: CoreParams](tilesKey: Field[Seq[TileParams]])(implicit p: Parameters) = { val xlen = p(XLen) - p(tilesKey).find(_.hartId == 0).map { tileParams => + p(tilesKey).asInstanceOf[Seq[CoreParams]].find(_.hartId == 0).map { tileParams => val coreParams = tileParams.core val vm = coreParams.useVM val env = if (vm) List("p","v") else List("p") From 2edfcb9022f9904e99820477423c9ba57ec4463c Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Mon, 25 May 2020 13:58:04 -0700 Subject: [PATCH 05/27] Subsystem done --- .../chipyard/src/main/scala/CoreManager.scala | 32 +++++++++-------- .../chipyard/src/main/scala/Subsystem.scala | 34 ++++++++----------- 2 files changed, 32 insertions(+), 34 deletions(-) diff --git a/generators/chipyard/src/main/scala/CoreManager.scala b/generators/chipyard/src/main/scala/CoreManager.scala index 72c5dc85..39c3a678 100644 --- a/generators/chipyard/src/main/scala/CoreManager.scala +++ b/generators/chipyard/src/main/scala/CoreManager.scala @@ -17,9 +17,8 @@ import ariane.{ArianeTile, ArianeTilesKey, ArianeCrossingKey, ArianeTileParams} // Third-party core entries sealed trait CoreEntryBase { def updateWithFilter(view: View, p: Any => View): (Map[String, Any] => PartialFunction[Any, Seq[AnyRef]]) - - def instantiateTile(param: TileParams, crossing: RocketCrossingParams, - logicalTreeNode: LogicalTreeNode, p: Parameters): Option[BaseTile] + def instantiateTile(crossingLookup: (Seq[RocketCrossingParams], Int) => ClockCrossingType) + (implicit logicalTreeNode: LogicalTreeNode, p: Parameters): (CoreParams, ClockCrossingType, BaseTile) } class CoreEntry[TileParamsT <: CoreParams, TileT <: BaseTile]( @@ -48,20 +47,18 @@ class CoreEntry[TileParamsT <: CoreParams, TileT <: BaseTile]( (tile => properties => copyTileParam(tile, properties)) } - def instantiateTile(param: TileParams, crossing: RocketCrossingParams, - logicalTreeNode: LogicalTreeNode, p: Parameters): Option[BaseTile] = param match { - case a: TileParams => Some(tileCtr.newInstance(a, crossing, PriorityMuxHartIdFromSeq(p(tilesKey)), logicalTreeNode, p)) - case _ => None + def instantiateTile(crossingLookup: (Seq[RocketCrossingParams], Int) => ClockCrossingType) + (implicit logicalTreeNode: LogicalTreeNode, p: Parameters) = { + val tileParams = p(tk) + val crossings = crossingLookup(p(ck), tileParams.size) + (tileParams zip crossings) map ((param, crossing) => ( + param, + crossing, + LazyModule(tileCtr(param, crossing, PriorityMuxHartIdFromSeq(tileParams), logicalTreeNode)) + )) } } -object CoreManager { - val cores: List[CoreEntryBase] = List( - // ADD YOUR CORE DEFINITION HERE - new CoreEntry[ArianeTileParams, ArianeTile](ArianeTilesKey, ArianeCrossingKey) - ) -} - // Core Generic Config - change properties in the given map class GenericConfig(properties: Map[String, Any], filterFunc: Any => Bool) { val configFunc: (View, View, View) => PartialFunction[Any, Any] = ((site, here, up) => key => { @@ -74,3 +71,10 @@ object GenericConfig { def apply(properties: Map[String, Any], filterFunc: Any => Bool = (_ => true)) = new GenericConfig(properties, filterFunc).configFunc } + +object CoreManager { + val cores: List[CoreEntryBase] = List( + // ADD YOUR CORE DEFINITION HERE + new CoreEntry[ArianeTileParams, ArianeTile](ArianeTilesKey, ArianeCrossingKey) + ) +} diff --git a/generators/chipyard/src/main/scala/Subsystem.scala b/generators/chipyard/src/main/scala/Subsystem.scala index 7b554d2a..c7924c9a 100644 --- a/generators/chipyard/src/main/scala/Subsystem.scala +++ b/generators/chipyard/src/main/scala/Subsystem.scala @@ -35,18 +35,25 @@ trait HasChipyardTiles extends HasTiles protected val rocketTileParams = p(RocketTilesKey) protected val boomTileParams = p(BoomTilesKey) - protected val coreTileParams = CoreRegistrar.cores map (coreType => p(coreType.tilesKey)) // crossing can either be per tile or global (aka only 1 crossing specified) private val rocketCrossings = perTileOrGlobalSetting(p(RocketCrossingKey), rocketTileParams.size) private val boomCrossings = perTileOrGlobalSetting(p(BoomCrossingKey), boomTileParams.size) - private val coreCrossings = (CoreRegistrar.cores zip coreTileParams) map (_ match { - case (coreType, tileParams) => perTileOrGlobalSetting(p(coreType.crossingKey), tileParams.size) - }) - // TODO: XXX The "tiles" below scan for hartId but it is not in CoreParams. Should that be added in later + private val rocketTilesInfo = (rocketTileParams zip rocketCrossings) map ((param, crossing) => ( + param, + crossing, + LazyModule(new RocketTile(param, crossing, PriorityMuxHartIdFromSeq(rocketTileParams), logicalTreeNode)) + )) + private val boomTilesInfo = (boomTileParams zip boomCrossings) map ((param, crossing) => ( + param, + crossing, + LazyModule(new RocketTile(param, crossing, PriorityMuxHartIdFromSeq(boomCrossings), logicalTreeNode)) + )) + + // TODO: XXX The "tiles" below scan for hartId but it is not in CoreParams. Should that be added in later // revision, or I have to use reflection to get that parameter? - val allTilesInfo = (rocketTileParams ++ boomTileParams ++ coreTileParams.flatten) zip (rocketCrossings ++ boomCrossings ++ coreCrossings.flatten) + val allTilesInfo = rocketTilesInfo ++ boomTilesInfo ++ (CoreManager.cores map _.instantiateTile(perTileOrGlobalSetting _)) // Make a tile and wire its nodes into the system, // according to the specified type of clock crossing. @@ -56,19 +63,7 @@ trait HasChipyardTiles extends HasTiles // There is something weird with registering tile-local interrupt controllers to the CLINT. // TODO: investigate why val tiles = allTilesInfo.sortWith(_._1.hartId < _._1.hartId).map { - case (param, crossing) => { - - val tile = param match { - case r: RocketTileParams => { - LazyModule(new RocketTile(r, crossing, PriorityMuxHartIdFromSeq(rocketTileParams), logicalTreeNode)) - } - case b: BoomTileParams => { - LazyModule(new BoomTile(b, crossing, PriorityMuxHartIdFromSeq(boomTileParams), logicalTreeNode)) - } - case _ => LazyModule( - (CoreRegistrar.cores collect (core => core.instantiateTile(param, crossing, paramList, logicalTreeNode, p)).unlift()) (0) - ) - } + case (param, crossing, tile) => { connectMasterPortsToSBus(tile, crossing) connectSlavePortsToCBus(tile, crossing) connectInterrupts(tile, debugOpt, clintOpt, plicOpt) @@ -77,7 +72,6 @@ trait HasChipyardTiles extends HasTiles } } - def coreMonitorBundles = tiles.map { case r: RocketTile => r.module.core.rocketImpl.coreMonitorBundle case b: BoomTile => b.module.core.coreMonitorBundle From a120edd36431edf382a7a5f22728420357e9c8f9 Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Mon, 25 May 2020 21:50:44 -0700 Subject: [PATCH 06/27] Pass Scala Compilation --- .../src/main/scala/ConfigFragments.scala | 3 +- .../chipyard/src/main/scala/CoreManager.scala | 57 ++++++++++--------- .../chipyard/src/main/scala/Subsystem.scala | 29 +++++----- .../chipyard/src/main/scala/TestSuites.scala | 6 +- .../scala/stage/phases/AddDefaultTests.scala | 4 +- 5 files changed, 53 insertions(+), 46 deletions(-) diff --git a/generators/chipyard/src/main/scala/ConfigFragments.scala b/generators/chipyard/src/main/scala/ConfigFragments.scala index e87b833a..697dc4ec 100644 --- a/generators/chipyard/src/main/scala/ConfigFragments.scala +++ b/generators/chipyard/src/main/scala/ConfigFragments.scala @@ -22,8 +22,7 @@ import sifive.blocks.devices.uart._ import sifive.blocks.devices.spi._ import chipyard.{BuildTop, BuildSystem} -import chipyard.{CoreRegistrar, CoreRegisterEntryBase} -import chipyard.hlist +import chipyard.GenericConfig /** * TODO: Why do we need this? diff --git a/generators/chipyard/src/main/scala/CoreManager.scala b/generators/chipyard/src/main/scala/CoreManager.scala index 39c3a678..d92f839c 100644 --- a/generators/chipyard/src/main/scala/CoreManager.scala +++ b/generators/chipyard/src/main/scala/CoreManager.scala @@ -7,7 +7,7 @@ import chisel3._ import freechips.rocketchip.config.{Parameters, Config, Field, View} import freechips.rocketchip.subsystem.{SystemBusKey, RocketTilesKey, RocketCrossingParams} -import freechips.rocketchip.diplomacy.LazyModule +import freechips.rocketchip.diplomacy.{LazyModule, ClockCrossingType, ValName} import freechips.rocketchip.diplomaticobjectmodel.logicaltree.LogicalTreeNode import freechips.rocketchip.rocket._ import freechips.rocketchip.tile._ @@ -16,59 +16,64 @@ import ariane.{ArianeTile, ArianeTilesKey, ArianeCrossingKey, ArianeTileParams} // Third-party core entries sealed trait CoreEntryBase { - def updateWithFilter(view: View, p: Any => View): (Map[String, Any] => PartialFunction[Any, Seq[AnyRef]]) - def instantiateTile(crossingLookup: (Seq[RocketCrossingParams], Int) => ClockCrossingType) - (implicit logicalTreeNode: LogicalTreeNode, p: Parameters): (CoreParams, ClockCrossingType, BaseTile) + def tileParamsLookup(implicit p: Parameters): Seq[TileParams] + def updateWithFilter(view: View, p: Any => Boolean): PartialFunction[Any, Map[String, Any] => Any] + def instantiateTile(crossingLookup: (Seq[RocketCrossingParams], Int) => Seq[RocketCrossingParams], logicalTreeNode: LogicalTreeNode) + (implicit p: Parameters, valName: ValName): Seq[(TileParams, RocketCrossingParams, BaseTile)] } -class CoreEntry[TileParamsT <: CoreParams, TileT <: BaseTile]( +class CoreEntry[TileParamsT <: TileParams with Product: TypeTag, TileT <: BaseTile : TypeTag]( tk: Field[Seq[TileParamsT]], ck: Field[Seq[RocketCrossingParams]] ) extends CoreEntryBase { private val mirror = runtimeMirror(getClass.getClassLoader) private val paramClass = mirror.runtimeClass(typeOf[TileParamsT].typeSymbol.asClass) - private val paramNames = Map((paramClass.getDeclaredFields map _.getName).zipWithIndex) + private val paramNames = (paramClass.getDeclaredFields map (f => f.getName)).zipWithIndex.toMap private val paramCtr = paramClass.getConstructors.head private val tileClass = mirror.runtimeClass(typeOf[TileT].typeSymbol.asClass) private val tileCtr = paramClass.getConstructors.head // copy() function in - def copyTileParam(tileParam: AnyRef, properties: Map[String, Any]) = { - val values = foo.productIterator.toList - val indexedProperties = properties map (key => (paramNames(key), properties(key))) + def copyTileParam(tileParam: TileParamsT, properties: Map[String, Any]) = { + val values = tileParam.productIterator.toList + val indexedProperties = properties map { case (key, value) => (paramNames(key), value) } val newValues = (0 until values.size) map - (i => if (indexedProperties contains i) indexedProperties(i) else values(i)) + (i => (if (indexedProperties contains i) indexedProperties(i) else values(i)).asInstanceOf[AnyRef]) paramCtr.newInstance(newValues:_*) } - def updateWithFilter(view: View, p: Any => View) = { - case key if (key == tk && p(tk)) => view(tk) map - (tile => properties => copyTileParam(tile, properties)) + def tileParamsLookup(implicit p: Parameters) = p(tk) + + def updateWithFilter(view: View, p: Any => Boolean): PartialFunction[Any, Map[String, Any] => Any] = { + case key if (key == tk && p(tk)) => properties => view(tk) map + (tile => copyTileParam(tile, properties)) } - def instantiateTile(crossingLookup: (Seq[RocketCrossingParams], Int) => ClockCrossingType) - (implicit logicalTreeNode: LogicalTreeNode, p: Parameters) = { + def instantiateTile(crossingLookup: (Seq[RocketCrossingParams], Int) => Seq[RocketCrossingParams], logicalTreeNode: LogicalTreeNode) + (implicit p: Parameters, valName: ValName) = { val tileParams = p(tk) val crossings = crossingLookup(p(ck), tileParams.size) - (tileParams zip crossings) map ((param, crossing) => ( - param, - crossing, - LazyModule(tileCtr(param, crossing, PriorityMuxHartIdFromSeq(tileParams), logicalTreeNode)) - )) + (tileParams zip crossings) map { + case (param, crossing) => ( + param, + crossing, + LazyModule(tileCtr.newInstance(param, crossing, PriorityMuxHartIdFromSeq(tileParams), logicalTreeNode).asInstanceOf[TileT]) + ) + } } } // Core Generic Config - change properties in the given map -class GenericConfig(properties: Map[String, Any], filterFunc: Any => Bool) { - val configFunc: (View, View, View) => PartialFunction[Any, Any] = ((site, here, up) => key => { - val tiles = CoreManager.cores flatMap _.updateWithFilter(up, filterFunc).lift(key) - if (tiles.size == 0) None else Some(tiles map _(properties)) - }).unlift +class GenericConfig(properties: Map[String, Any], filterFunc: Any => Boolean) { + val configFunc: (View, View, View) => PartialFunction[Any, Any] = (site, here, up) => scala.Function.unlift((key: Any) => { + val tiles = CoreManager.cores flatMap (core => core.updateWithFilter(up, filterFunc).lift(key)) + if (tiles.size == 0) None else Some(tiles map (tile => tile(properties))) + }) } object GenericConfig { - def apply(properties: Map[String, Any], filterFunc: Any => Bool = (_ => true)) = + def apply(properties: Map[String, Any], filterFunc: Any => Boolean = (_ => true)) = new GenericConfig(properties, filterFunc).configFunc } diff --git a/generators/chipyard/src/main/scala/Subsystem.scala b/generators/chipyard/src/main/scala/Subsystem.scala index c7924c9a..1b766099 100644 --- a/generators/chipyard/src/main/scala/Subsystem.scala +++ b/generators/chipyard/src/main/scala/Subsystem.scala @@ -40,20 +40,23 @@ trait HasChipyardTiles extends HasTiles private val rocketCrossings = perTileOrGlobalSetting(p(RocketCrossingKey), rocketTileParams.size) private val boomCrossings = perTileOrGlobalSetting(p(BoomCrossingKey), boomTileParams.size) - private val rocketTilesInfo = (rocketTileParams zip rocketCrossings) map ((param, crossing) => ( - param, - crossing, - LazyModule(new RocketTile(param, crossing, PriorityMuxHartIdFromSeq(rocketTileParams), logicalTreeNode)) - )) - private val boomTilesInfo = (boomTileParams zip boomCrossings) map ((param, crossing) => ( - param, - crossing, - LazyModule(new RocketTile(param, crossing, PriorityMuxHartIdFromSeq(boomCrossings), logicalTreeNode)) - )) + private val rocketTilesInfo = (rocketTileParams zip rocketCrossings) map { + case (param, crossing) => ( + param, + crossing, + LazyModule(new RocketTile(param, crossing, PriorityMuxHartIdFromSeq(rocketTileParams), logicalTreeNode)) + ) + } + private val boomTilesInfo = (boomTileParams zip boomCrossings) map { + case (param, crossing) => ( + param, + crossing, + LazyModule(new BoomTile(param, crossing, PriorityMuxHartIdFromSeq(boomTileParams), logicalTreeNode)) + ) + } - // TODO: XXX The "tiles" below scan for hartId but it is not in CoreParams. Should that be added in later - // revision, or I have to use reflection to get that parameter? - val allTilesInfo = rocketTilesInfo ++ boomTilesInfo ++ (CoreManager.cores map _.instantiateTile(perTileOrGlobalSetting _)) + val allTilesInfo = rocketTilesInfo ++ boomTilesInfo ++ + (CoreManager.cores flatMap (core => core.instantiateTile(perTileOrGlobalSetting _, logicalTreeNode))) // Make a tile and wire its nodes into the system, // according to the specified type of clock crossing. diff --git a/generators/chipyard/src/main/scala/TestSuites.scala b/generators/chipyard/src/main/scala/TestSuites.scala index a4944355..9041be61 100644 --- a/generators/chipyard/src/main/scala/TestSuites.scala +++ b/generators/chipyard/src/main/scala/TestSuites.scala @@ -3,7 +3,7 @@ package chipyard import scala.collection.mutable.{LinkedHashSet} import freechips.rocketchip.subsystem.{RocketTilesKey} -import freechips.rocketchip.tile.{XLen, CoreParams} +import freechips.rocketchip.tile.{XLen, TileParams} import freechips.rocketchip.config.{Parameters, Field} import freechips.rocketchip.system.{TestGeneration, RegressionTestSuite, RocketTestSuite} @@ -145,9 +145,9 @@ class TestSuiteHelper /** * Add third-party core (including Ariane) tests (asm, bmark, regression) */ - def addThirdPartyTestSuites[TileParams <: CoreParams](tilesKey: Field[Seq[TileParams]])(implicit p: Parameters) = { + def addThirdPartyTestSuites(tiles: Seq[TileParams])(implicit p: Parameters) = { val xlen = p(XLen) - p(tilesKey).asInstanceOf[Seq[CoreParams]].find(_.hartId == 0).map { tileParams => + tiles.find(_.hartId == 0).map { tileParams => val coreParams = tileParams.core val vm = coreParams.useVM val env = if (vm) List("p","v") else List("p") diff --git a/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala b/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala index 3d367ffa..cbd2e1a7 100644 --- a/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala +++ b/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala @@ -17,7 +17,7 @@ import freechips.rocketchip.stage.phases.{RocketTestSuiteAnnotation} import freechips.rocketchip.system.{RocketTestSuite, TestGeneration} import freechips.rocketchip.util.HasRocketChipStageUtils -import chipyard.{TestSuiteHelper, CoreRegistrar} +import chipyard.{TestSuiteHelper, CoreManager} class AddDefaultTests extends Phase with PreservesAll[Phase] with HasRocketChipStageUtils { // Make sure we run both after RocketChip's version of this phase, and Rocket Chip's annotation emission phase @@ -32,7 +32,7 @@ class AddDefaultTests extends Phase with PreservesAll[Phase] with HasRocketChipS val suiteHelper = new TestSuiteHelper suiteHelper.addRocketTestSuites suiteHelper.addBoomTestSuites - CoreRegistrar.cores map suiteHelper.addThirdPartyTestSuites(_.tilesKey) + CoreManager.cores map (core => suiteHelper.addThirdPartyTestSuites(core.tileParamsLookup)) // if hwacha parameter exists then generate its tests // TODO: find a more elegant way to do this. either through From 8f39791d940e748d0a25c06a957b0b9fd40e275c Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Thu, 28 May 2020 22:46:13 -0700 Subject: [PATCH 07/27] Git ignores vscode and scala plugins --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 47cb4d87..eaddd6e1 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,10 @@ target *# *~ .idea +.bloop +.metals +project/metals.sbt +.vscode .DS_Store env.sh riscv-tools-install From 71bac7b7c9f28a47662c2334914faaf8606744a9 Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Fri, 29 May 2020 20:23:53 -0700 Subject: [PATCH 08/27] Fixed runtime error --- generators/chipyard/src/main/scala/CoreManager.scala | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/generators/chipyard/src/main/scala/CoreManager.scala b/generators/chipyard/src/main/scala/CoreManager.scala index d92f839c..22212795 100644 --- a/generators/chipyard/src/main/scala/CoreManager.scala +++ b/generators/chipyard/src/main/scala/CoreManager.scala @@ -13,8 +13,9 @@ import freechips.rocketchip.rocket._ import freechips.rocketchip.tile._ import ariane.{ArianeTile, ArianeTilesKey, ArianeCrossingKey, ArianeTileParams} +import chipsalliance.rocketchip.config.Parameters -// Third-party core entries +// Base trait for all third-party core entries sealed trait CoreEntryBase { def tileParamsLookup(implicit p: Parameters): Seq[TileParams] def updateWithFilter(view: View, p: Any => Boolean): PartialFunction[Any, Map[String, Any] => Any] @@ -22,6 +23,7 @@ sealed trait CoreEntryBase { (implicit p: Parameters, valName: ValName): Seq[(TileParams, RocketCrossingParams, BaseTile)] } +// Implementation of third-party core entries class CoreEntry[TileParamsT <: TileParams with Product: TypeTag, TileT <: BaseTile : TypeTag]( tk: Field[Seq[TileParamsT]], ck: Field[Seq[RocketCrossingParams]] @@ -32,9 +34,9 @@ class CoreEntry[TileParamsT <: TileParams with Product: TypeTag, TileT <: BaseTi private val paramCtr = paramClass.getConstructors.head private val tileClass = mirror.runtimeClass(typeOf[TileT].typeSymbol.asClass) - private val tileCtr = paramClass.getConstructors.head + private val tileCtr = tileClass.getConstructors.head - // copy() function in + // Reflective version of copy() def copyTileParam(tileParam: TileParamsT, properties: Map[String, Any]) = { val values = tileParam.productIterator.toList val indexedProperties = properties map { case (key, value) => (paramNames(key), value) } @@ -58,7 +60,7 @@ class CoreEntry[TileParamsT <: TileParams with Product: TypeTag, TileT <: BaseTi case (param, crossing) => ( param, crossing, - LazyModule(tileCtr.newInstance(param, crossing, PriorityMuxHartIdFromSeq(tileParams), logicalTreeNode).asInstanceOf[TileT]) + LazyModule(tileCtr.newInstance(param, crossing, PriorityMuxHartIdFromSeq(tileParams), logicalTreeNode, p.asInstanceOf[Parameters]).asInstanceOf[TileT]) ) } } From 3fcfc133b1a4e1840ca7f6cd08fd5eb43938aaab Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Sun, 31 May 2020 10:51:11 -0700 Subject: [PATCH 09/27] Add Rocket and Boom to CoreManager --- .../src/main/scala/ConfigFragments.scala | 6 +- .../chipyard/src/main/scala/CoreManager.scala | 7 +- .../chipyard/src/main/scala/Subsystem.scala | 24 +----- .../chipyard/src/main/scala/TestSuites.scala | 81 +------------------ .../scala/stage/phases/AddDefaultTests.scala | 5 +- 5 files changed, 12 insertions(+), 111 deletions(-) diff --git a/generators/chipyard/src/main/scala/ConfigFragments.scala b/generators/chipyard/src/main/scala/ConfigFragments.scala index 697dc4ec..dfe225e4 100644 --- a/generators/chipyard/src/main/scala/ConfigFragments.scala +++ b/generators/chipyard/src/main/scala/ConfigFragments.scala @@ -148,7 +148,9 @@ class WithControlCore extends Config((site, here, up) => { }) class WithTraceIO extends Config((site, here, up) => - GenericConfig(Map("trace" -> true)) (site, here, up) orElse { - case BoomTilesKey => up(BoomTilesKey) map (tile => tile.copy(trace = true)) + GenericConfig(Map("trace" -> true), { + case RocketTilesKey => false + case _ => true + }) (site, here, up) orElse { case TracePortKey => Some(TracePortParams()) }) diff --git a/generators/chipyard/src/main/scala/CoreManager.scala b/generators/chipyard/src/main/scala/CoreManager.scala index 22212795..ec467d8f 100644 --- a/generators/chipyard/src/main/scala/CoreManager.scala +++ b/generators/chipyard/src/main/scala/CoreManager.scala @@ -6,12 +6,13 @@ import scala.reflect.runtime.universe._ import chisel3._ import freechips.rocketchip.config.{Parameters, Config, Field, View} -import freechips.rocketchip.subsystem.{SystemBusKey, RocketTilesKey, RocketCrossingParams} +import freechips.rocketchip.subsystem.{SystemBusKey, RocketTilesKey, RocketCrossingParams, RocketCrossingKey} import freechips.rocketchip.diplomacy.{LazyModule, ClockCrossingType, ValName} import freechips.rocketchip.diplomaticobjectmodel.logicaltree.LogicalTreeNode import freechips.rocketchip.rocket._ import freechips.rocketchip.tile._ +import boom.common.{BoomTile, BoomTilesKey, BoomCrossingKey, BoomTileParams} import ariane.{ArianeTile, ArianeTilesKey, ArianeCrossingKey, ArianeTileParams} import chipsalliance.rocketchip.config.Parameters @@ -34,7 +35,7 @@ class CoreEntry[TileParamsT <: TileParams with Product: TypeTag, TileT <: BaseTi private val paramCtr = paramClass.getConstructors.head private val tileClass = mirror.runtimeClass(typeOf[TileT].typeSymbol.asClass) - private val tileCtr = tileClass.getConstructors.head + private val tileCtr = tileClass.getConstructors.filter(ctr => ctr.getParameterTypes()(4) == classOf[Parameters]).head // Reflective version of copy() def copyTileParam(tileParam: TileParamsT, properties: Map[String, Any]) = { @@ -82,6 +83,8 @@ object GenericConfig { object CoreManager { val cores: List[CoreEntryBase] = List( // ADD YOUR CORE DEFINITION HERE + new CoreEntry[RocketTileParams, RocketTile](RocketTilesKey, RocketCrossingKey), + new CoreEntry[BoomTileParams, BoomTile](BoomTilesKey, BoomCrossingKey), new CoreEntry[ArianeTileParams, ArianeTile](ArianeTilesKey, ArianeCrossingKey) ) } diff --git a/generators/chipyard/src/main/scala/Subsystem.scala b/generators/chipyard/src/main/scala/Subsystem.scala index 1b766099..889e5f6f 100644 --- a/generators/chipyard/src/main/scala/Subsystem.scala +++ b/generators/chipyard/src/main/scala/Subsystem.scala @@ -33,29 +33,7 @@ trait HasChipyardTiles extends HasTiles val module: HasChipyardTilesModuleImp - protected val rocketTileParams = p(RocketTilesKey) - protected val boomTileParams = p(BoomTilesKey) - - // crossing can either be per tile or global (aka only 1 crossing specified) - private val rocketCrossings = perTileOrGlobalSetting(p(RocketCrossingKey), rocketTileParams.size) - private val boomCrossings = perTileOrGlobalSetting(p(BoomCrossingKey), boomTileParams.size) - - private val rocketTilesInfo = (rocketTileParams zip rocketCrossings) map { - case (param, crossing) => ( - param, - crossing, - LazyModule(new RocketTile(param, crossing, PriorityMuxHartIdFromSeq(rocketTileParams), logicalTreeNode)) - ) - } - private val boomTilesInfo = (boomTileParams zip boomCrossings) map { - case (param, crossing) => ( - param, - crossing, - LazyModule(new BoomTile(param, crossing, PriorityMuxHartIdFromSeq(boomTileParams), logicalTreeNode)) - ) - } - - val allTilesInfo = rocketTilesInfo ++ boomTilesInfo ++ + val allTilesInfo: Seq[(TileParams, RocketCrossingParams, BaseTile)] = (CoreManager.cores flatMap (core => core.instantiateTile(perTileOrGlobalSetting _, logicalTreeNode))) // Make a tile and wire its nodes into the system, diff --git a/generators/chipyard/src/main/scala/TestSuites.scala b/generators/chipyard/src/main/scala/TestSuites.scala index 9041be61..6fba4b2a 100644 --- a/generators/chipyard/src/main/scala/TestSuites.scala +++ b/generators/chipyard/src/main/scala/TestSuites.scala @@ -62,86 +62,6 @@ class TestSuiteHelper def addSuite(s: RocketTestSuite) { suites += (s.makeTargetName -> s) } def addSuites(s: Seq[RocketTestSuite]) { s.foreach(addSuite) } - /** - * Add BOOM tests (asm, bmark, regression) - */ - def addBoomTestSuites(implicit p: Parameters) = { - val xlen = p(XLen) - p(BoomTilesKey).find(_.hartId == 0).map { tileParams => - val coreParams = tileParams.core - val vm = coreParams.useVM - val env = if (vm) List("p","v") else List("p") - coreParams.fpu foreach { case cfg => - if (xlen == 32) { - addSuites(env.map(rv32uf)) - if (cfg.fLen >= 64) { - addSuites(env.map(rv32ud)) - } - } else if (cfg.fLen >= 64) { - addSuites(env.map(rv64ud)) - addSuites(env.map(rv64uf)) - addSuite(rv32udBenchmarks) - } - } - if (coreParams.useAtomics) { - if (tileParams.dcache.flatMap(_.scratch).isEmpty) { - addSuites(env.map(if (xlen == 64) rv64ua else rv32ua)) - } else { - addSuites(env.map(if (xlen == 64) rv64uaSansLRSC else rv32uaSansLRSC)) - } - } - if (coreParams.useCompressed) addSuites(env.map(if (xlen == 64) rv64uc else rv32uc)) - val (rvi, rvu) = - if (xlen == 64) ((if (vm) rv64i else rv64pi), rv64u) - else ((if (vm) rv32i else rv32pi), rv32u) - - addSuites(rvi.map(_("p"))) - addSuites(rvu.map(_("p"))) - addSuites((if (vm) List("v") else List()).flatMap(env => rvu.map(_(env)))) - addSuite(benchmarks) - addSuite(new RegressionTestSuite(if (xlen == 64) rv64RegrTestNames else rv32RegrTestNames)) - } - } - - /** - * Add Rocket tests (asm, bmark, regression) - */ - def addRocketTestSuites(implicit p: Parameters) = { - val xlen = p(XLen) - p(RocketTilesKey).find(_.hartId == 0).map { tileParams => - val coreParams = tileParams.core - val vm = coreParams.useVM - val env = if (vm) List("p","v") else List("p") - coreParams.fpu foreach { case cfg => - if (xlen == 32) { - addSuites(env.map(rv32uf)) - if (cfg.fLen >= 64) - addSuites(env.map(rv32ud)) - } else { - addSuite(rv32udBenchmarks) - addSuites(env.map(rv64uf)) - if (cfg.fLen >= 64) - addSuites(env.map(rv64ud)) - } - } - if (coreParams.useAtomics) { - if (tileParams.dcache.flatMap(_.scratch).isEmpty) - addSuites(env.map(if (xlen == 64) rv64ua else rv32ua)) - else - addSuites(env.map(if (xlen == 64) rv64uaSansLRSC else rv32uaSansLRSC)) - } - if (coreParams.useCompressed) addSuites(env.map(if (xlen == 64) rv64uc else rv32uc)) - val (rvi, rvu) = - if (xlen == 64) ((if (vm) rv64i else rv64pi), rv64u) - else ((if (vm) rv32i else rv32pi), rv32u) - - addSuites(rvi.map(_("p"))) - addSuites((if (vm) List("v") else List()).flatMap(env => rvu.map(_(env)))) - addSuite(benchmarks) - addSuite(new RegressionTestSuite(if (xlen == 64) rv64RegrTestNames else rv32RegrTestNames)) - } - } - /** * Add third-party core (including Ariane) tests (asm, bmark, regression) */ @@ -175,6 +95,7 @@ class TestSuiteHelper else ((if (vm) rv32i else rv32pi), rv32u) addSuites(rvi.map(_("p"))) + addSuites(rvu.map(_("p"))) addSuites((if (vm) List("v") else List()).flatMap(env => rvu.map(_(env)))) addSuite(benchmarks) addSuite(new RegressionTestSuite(if (xlen == 64) rv64RegrTestNames else rv32RegrTestNames)) diff --git a/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala b/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala index 464c8ff5..f8ae3177 100644 --- a/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala +++ b/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala @@ -33,11 +33,8 @@ class AddDefaultTests extends Phase with PreservesAll[Phase] with HasRocketChipS val suiteHelper = new TestSuiteHelper // Use Xlen as a proxy for detecting if we are a processor-like target // The underlying test suites expect this field to be defined - if (p.lift(XLen).nonEmpty) { - suiteHelper.addRocketTestSuites - suiteHelper.addBoomTestSuites + if (p.lift(XLen).nonEmpty) CoreManager.cores map (core => suiteHelper.addThirdPartyTestSuites(core.tileParamsLookup)) - } // if hwacha parameter exists then generate its tests // TODO: find a more elegant way to do this. either through From 0743abd9db6446f5194c6dc5f4425a2d93794c80 Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Sun, 31 May 2020 15:09:22 -0700 Subject: [PATCH 10/27] Add comments --- generators/chipyard/src/main/scala/CoreManager.scala | 11 +++++++++-- generators/chipyard/src/main/scala/Subsystem.scala | 3 ++- generators/chipyard/src/main/scala/TestSuites.scala | 4 ++-- .../src/main/scala/stage/phases/AddDefaultTests.scala | 4 ++-- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/generators/chipyard/src/main/scala/CoreManager.scala b/generators/chipyard/src/main/scala/CoreManager.scala index ec467d8f..ecee820f 100644 --- a/generators/chipyard/src/main/scala/CoreManager.scala +++ b/generators/chipyard/src/main/scala/CoreManager.scala @@ -29,15 +29,17 @@ class CoreEntry[TileParamsT <: TileParams with Product: TypeTag, TileT <: BaseTi tk: Field[Seq[TileParamsT]], ck: Field[Seq[RocketCrossingParams]] ) extends CoreEntryBase { + // Use reflection to get the parameter's constructor private val mirror = runtimeMirror(getClass.getClassLoader) private val paramClass = mirror.runtimeClass(typeOf[TileParamsT].typeSymbol.asClass) private val paramNames = (paramClass.getDeclaredFields map (f => f.getName)).zipWithIndex.toMap private val paramCtr = paramClass.getConstructors.head + // Use reflection to get the tile's constructor private val tileClass = mirror.runtimeClass(typeOf[TileT].typeSymbol.asClass) private val tileCtr = tileClass.getConstructors.filter(ctr => ctr.getParameterTypes()(4) == classOf[Parameters]).head - // Reflective version of copy() + // Version of case class' copy() using reflection, where fields to be updated are passed by a map def copyTileParam(tileParam: TileParamsT, properties: Map[String, Any]) = { val values = tileParam.productIterator.toList val indexedProperties = properties map { case (key, value) => (paramNames(key), value) } @@ -46,13 +48,16 @@ class CoreEntry[TileParamsT <: TileParams with Product: TypeTag, TileT <: BaseTi paramCtr.newInstance(newValues:_*) } + // Tile parameter lookup using correct type def tileParamsLookup(implicit p: Parameters) = p(tk) + // If this core meet the requirement given by p, update parameter fields in the map def updateWithFilter(view: View, p: Any => Boolean): PartialFunction[Any, Map[String, Any] => Any] = { case key if (key == tk && p(tk)) => properties => view(tk) map (tile => copyTileParam(tile, properties)) } + // Instantiate a tile and zip it with its parameter info, used by subsystem def instantiateTile(crossingLookup: (Seq[RocketCrossingParams], Int) => Seq[RocketCrossingParams], logicalTreeNode: LogicalTreeNode) (implicit p: Parameters, valName: ValName) = { val tileParams = p(tk) @@ -75,14 +80,16 @@ class GenericConfig(properties: Map[String, Any], filterFunc: Any => Boolean) { }) } +// Wrapper object of the class above object GenericConfig { def apply(properties: Map[String, Any], filterFunc: Any => Boolean = (_ => true)) = new GenericConfig(properties, filterFunc).configFunc } +// A list of all cores. object CoreManager { val cores: List[CoreEntryBase] = List( - // ADD YOUR CORE DEFINITION HERE + // TODO ADD YOUR CORE DEFINITION HERE new CoreEntry[RocketTileParams, RocketTile](RocketTilesKey, RocketCrossingKey), new CoreEntry[BoomTileParams, BoomTile](BoomTilesKey, BoomCrossingKey), new CoreEntry[ArianeTileParams, ArianeTile](ArianeTilesKey, ArianeCrossingKey) diff --git a/generators/chipyard/src/main/scala/Subsystem.scala b/generators/chipyard/src/main/scala/Subsystem.scala index 889e5f6f..6410ac4e 100644 --- a/generators/chipyard/src/main/scala/Subsystem.scala +++ b/generators/chipyard/src/main/scala/Subsystem.scala @@ -33,7 +33,8 @@ trait HasChipyardTiles extends HasTiles val module: HasChipyardTilesModuleImp - val allTilesInfo: Seq[(TileParams, RocketCrossingParams, BaseTile)] = + // Generate tiles info from the list of cores in CoreManager + val allTilesInfo: Seq[(TileParams, RocketCrossingParams, BaseTile)] = (CoreManager.cores flatMap (core => core.instantiateTile(perTileOrGlobalSetting _, logicalTreeNode))) // Make a tile and wire its nodes into the system, diff --git a/generators/chipyard/src/main/scala/TestSuites.scala b/generators/chipyard/src/main/scala/TestSuites.scala index 6fba4b2a..2261000f 100644 --- a/generators/chipyard/src/main/scala/TestSuites.scala +++ b/generators/chipyard/src/main/scala/TestSuites.scala @@ -63,9 +63,9 @@ class TestSuiteHelper def addSuites(s: Seq[RocketTestSuite]) { s.foreach(addSuite) } /** - * Add third-party core (including Ariane) tests (asm, bmark, regression) + * Add generic tests (asm, bmark, regression) for all cores. */ - def addThirdPartyTestSuites(tiles: Seq[TileParams])(implicit p: Parameters) = { + def addGenericTestSuites(tiles: Seq[TileParams])(implicit p: Parameters) = { val xlen = p(XLen) tiles.find(_.hartId == 0).map { tileParams => val coreParams = tileParams.core diff --git a/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala b/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala index f8ae3177..a36131b1 100644 --- a/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala +++ b/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala @@ -22,7 +22,7 @@ import chipyard.{TestSuiteHelper, CoreManager} class AddDefaultTests extends Phase with PreservesAll[Phase] with HasRocketChipStageUtils { // Make sure we run both after RocketChip's version of this phase, and Rocket Chip's annotation emission phase - // because the RocketTestSuiteAnnotation is not serializable (but is not marked as such). + // because the RocketTestSuiteAnnotation is not serializable (but is not marked as such). override val prerequisites = Seq( Dependency[freechips.rocketchip.stage.phases.GenerateFirrtlAnnos], Dependency[freechips.rocketchip.stage.phases.AddDefaultTests]) @@ -34,7 +34,7 @@ class AddDefaultTests extends Phase with PreservesAll[Phase] with HasRocketChipS // Use Xlen as a proxy for detecting if we are a processor-like target // The underlying test suites expect this field to be defined if (p.lift(XLen).nonEmpty) - CoreManager.cores map (core => suiteHelper.addThirdPartyTestSuites(core.tileParamsLookup)) + CoreManager.cores map (core => suiteHelper.addGenericTestSuites(core.tileParamsLookup)) // if hwacha parameter exists then generate its tests // TODO: find a more elegant way to do this. either through From aa606e580a60515fdc375c30b9ace5b074efd8fc Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Mon, 1 Jun 2020 18:41:21 -0700 Subject: [PATCH 11/27] Change names --- .../src/main/scala/ConfigFragments.scala | 13 +++--- .../chipyard/src/main/scala/CoreManager.scala | 46 ++++++++++--------- 2 files changed, 30 insertions(+), 29 deletions(-) diff --git a/generators/chipyard/src/main/scala/ConfigFragments.scala b/generators/chipyard/src/main/scala/ConfigFragments.scala index dfe225e4..cad47f72 100644 --- a/generators/chipyard/src/main/scala/ConfigFragments.scala +++ b/generators/chipyard/src/main/scala/ConfigFragments.scala @@ -22,7 +22,7 @@ import sifive.blocks.devices.uart._ import sifive.blocks.devices.spi._ import chipyard.{BuildTop, BuildSystem} -import chipyard.GenericConfig +import chipyard.GenericCoreConfig /** * TODO: Why do we need this? @@ -147,10 +147,9 @@ class WithControlCore extends Config((site, here, up) => { case MaxHartIdBits => log2Up(up(RocketTilesKey, site).size + up(BoomTilesKey, site).size + 1) }) -class WithTraceIO extends Config((site, here, up) => - GenericConfig(Map("trace" -> true), { - case RocketTilesKey => false - case _ => true - }) (site, here, up) orElse { +class WithTraceIO extends GenericCoreConfig( + properties = Map("trace" -> true), + specialCase = (site, here, up) => { case TracePortKey => Some(TracePortParams()) - }) + } +) \ No newline at end of file diff --git a/generators/chipyard/src/main/scala/CoreManager.scala b/generators/chipyard/src/main/scala/CoreManager.scala index ecee820f..2756a42b 100644 --- a/generators/chipyard/src/main/scala/CoreManager.scala +++ b/generators/chipyard/src/main/scala/CoreManager.scala @@ -26,65 +26,67 @@ sealed trait CoreEntryBase { // Implementation of third-party core entries class CoreEntry[TileParamsT <: TileParams with Product: TypeTag, TileT <: BaseTile : TypeTag]( - tk: Field[Seq[TileParamsT]], - ck: Field[Seq[RocketCrossingParams]] + tilesKey: Field[Seq[TileParamsT]], + crossingKey: Field[Seq[RocketCrossingParams]] ) extends CoreEntryBase { // Use reflection to get the parameter's constructor private val mirror = runtimeMirror(getClass.getClassLoader) private val paramClass = mirror.runtimeClass(typeOf[TileParamsT].typeSymbol.asClass) private val paramNames = (paramClass.getDeclaredFields map (f => f.getName)).zipWithIndex.toMap - private val paramCtr = paramClass.getConstructors.head + private val paramCtor = paramClass.getConstructors.head // Use reflection to get the tile's constructor private val tileClass = mirror.runtimeClass(typeOf[TileT].typeSymbol.asClass) - private val tileCtr = tileClass.getConstructors.filter(ctr => ctr.getParameterTypes()(4) == classOf[Parameters]).head + private val tileCtor = tileClass.getConstructors.filter(ctor => ctor.getParameterTypes()(4) == classOf[Parameters]).head // Version of case class' copy() using reflection, where fields to be updated are passed by a map def copyTileParam(tileParam: TileParamsT, properties: Map[String, Any]) = { val values = tileParam.productIterator.toList - val indexedProperties = properties map { case (key, value) => (paramNames(key), value) } + //val filteredProperties = properties filter { case (key, value) => paramNames contains key } + val indexedProperties = /*filteredProperties*/ properties map { case (key, value) => (paramNames(key), value) } val newValues = (0 until values.size) map (i => (if (indexedProperties contains i) indexedProperties(i) else values(i)).asInstanceOf[AnyRef]) - paramCtr.newInstance(newValues:_*) + paramCtor.newInstance(newValues:_*) } // Tile parameter lookup using correct type - def tileParamsLookup(implicit p: Parameters) = p(tk) + def tileParamsLookup(implicit p: Parameters) = p(tilesKey) // If this core meet the requirement given by p, update parameter fields in the map def updateWithFilter(view: View, p: Any => Boolean): PartialFunction[Any, Map[String, Any] => Any] = { - case key if (key == tk && p(tk)) => properties => view(tk) map + case key if (key == tilesKey && p(tilesKey)) => properties => view(tilesKey) map (tile => copyTileParam(tile, properties)) } // Instantiate a tile and zip it with its parameter info, used by subsystem def instantiateTile(crossingLookup: (Seq[RocketCrossingParams], Int) => Seq[RocketCrossingParams], logicalTreeNode: LogicalTreeNode) (implicit p: Parameters, valName: ValName) = { - val tileParams = p(tk) - val crossings = crossingLookup(p(ck), tileParams.size) + val tileParams = p(tilesKey) + val crossings = crossingLookup(p(crossingKey), tileParams.size) (tileParams zip crossings) map { case (param, crossing) => ( param, crossing, - LazyModule(tileCtr.newInstance(param, crossing, PriorityMuxHartIdFromSeq(tileParams), logicalTreeNode, p.asInstanceOf[Parameters]).asInstanceOf[TileT]) + LazyModule(tileCtor.newInstance(param, crossing, PriorityMuxHartIdFromSeq(tileParams), logicalTreeNode, p.asInstanceOf[Parameters]).asInstanceOf[TileT]) ) } } } -// Core Generic Config - change properties in the given map -class GenericConfig(properties: Map[String, Any], filterFunc: Any => Boolean) { - val configFunc: (View, View, View) => PartialFunction[Any, Any] = (site, here, up) => scala.Function.unlift((key: Any) => { +// Generic Core Config - change properties in the given map +class GenericCoreConfig( + // Parameter properties to be changed and their new values. Any field not in a core's parameters will be ignored. + properties: Map[String, Any], + // Function for filtering the list of TilesKey. + filterFunc: Any => Boolean = (_ => true), + // Handling special cases where partial function input is not a TilesKey. + specialCase: (View, View, View) => PartialFunction[Any, Any] = ((_, _, _) => Map.empty) +) extends Config((site, here, up) => + scala.Function.unlift((key: Any) => { val tiles = CoreManager.cores flatMap (core => core.updateWithFilter(up, filterFunc).lift(key)) if (tiles.size == 0) None else Some(tiles map (tile => tile(properties))) - }) -} - -// Wrapper object of the class above -object GenericConfig { - def apply(properties: Map[String, Any], filterFunc: Any => Boolean = (_ => true)) = - new GenericConfig(properties, filterFunc).configFunc -} + }).orElse(specialCase(site, here, up)) +) // A list of all cores. object CoreManager { From 02c8aac346df1f889fa7d4810a76b3db2daedd67 Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Wed, 3 Jun 2020 20:22:41 -0700 Subject: [PATCH 12/27] Revised generic config --- .../src/main/scala/ConfigFragments.scala | 11 +- .../chipyard/src/main/scala/CoreManager.scala | 47 ++----- .../src/main/scala/GenericCoreConfig.scala | 133 ++++++++++++++++++ .../scala/stage/phases/AddDefaultTests.scala | 11 +- 4 files changed, 153 insertions(+), 49 deletions(-) create mode 100644 generators/chipyard/src/main/scala/GenericCoreConfig.scala diff --git a/generators/chipyard/src/main/scala/ConfigFragments.scala b/generators/chipyard/src/main/scala/ConfigFragments.scala index cad47f72..4d0e0725 100644 --- a/generators/chipyard/src/main/scala/ConfigFragments.scala +++ b/generators/chipyard/src/main/scala/ConfigFragments.scala @@ -59,14 +59,7 @@ class WithSPIFlash(size: BigInt = 0x10000000) extends Config((site, here, up) => SPIFlashParams(rAddress = 0x10040000, fAddress = 0x20000000, fSize = size)) }) -class WithL2TLBs(entries: Int) extends Config((site, here, up) => { - case RocketTilesKey => up(RocketTilesKey) map (tile => tile.copy( - core = tile.core.copy(nL2TLBEntries = entries) - )) - case BoomTilesKey => up(BoomTilesKey) map (tile => tile.copy( - core = tile.core.copy(nL2TLBEntries = entries) - )) -}) +class WithL2TLBs(entries: Int) extends GenericCoreConfig(Map("core" -> Map("nL2TLBEntries" -> entries))) class WithTracegenSystem extends Config((site, here, up) => { case BuildSystem => (p: Parameters) => LazyModule(new tracegen.TraceGenSystem()(p)) @@ -148,7 +141,7 @@ class WithControlCore extends Config((site, here, up) => { }) class WithTraceIO extends GenericCoreConfig( - properties = Map("trace" -> true), + newValues = Map("trace" -> true), specialCase = (site, here, up) => { case TracePortKey => Some(TracePortParams()) } diff --git a/generators/chipyard/src/main/scala/CoreManager.scala b/generators/chipyard/src/main/scala/CoreManager.scala index 2756a42b..57b63743 100644 --- a/generators/chipyard/src/main/scala/CoreManager.scala +++ b/generators/chipyard/src/main/scala/CoreManager.scala @@ -14,10 +14,10 @@ import freechips.rocketchip.tile._ import boom.common.{BoomTile, BoomTilesKey, BoomCrossingKey, BoomTileParams} import ariane.{ArianeTile, ArianeTilesKey, ArianeCrossingKey, ArianeTileParams} -import chipsalliance.rocketchip.config.Parameters // Base trait for all third-party core entries sealed trait CoreEntryBase { + val name: String def tileParamsLookup(implicit p: Parameters): Seq[TileParams] def updateWithFilter(view: View, p: Any => Boolean): PartialFunction[Any, Map[String, Any] => Any] def instantiateTile(crossingLookup: (Seq[RocketCrossingParams], Int) => Seq[RocketCrossingParams], logicalTreeNode: LogicalTreeNode) @@ -26,36 +26,22 @@ sealed trait CoreEntryBase { // Implementation of third-party core entries class CoreEntry[TileParamsT <: TileParams with Product: TypeTag, TileT <: BaseTile : TypeTag]( + val name: String, tilesKey: Field[Seq[TileParamsT]], crossingKey: Field[Seq[RocketCrossingParams]] ) extends CoreEntryBase { - // Use reflection to get the parameter's constructor - private val mirror = runtimeMirror(getClass.getClassLoader) - private val paramClass = mirror.runtimeClass(typeOf[TileParamsT].typeSymbol.asClass) - private val paramNames = (paramClass.getDeclaredFields map (f => f.getName)).zipWithIndex.toMap - private val paramCtor = paramClass.getConstructors.head - // Use reflection to get the tile's constructor + private val mirror = runtimeMirror(getClass.getClassLoader) private val tileClass = mirror.runtimeClass(typeOf[TileT].typeSymbol.asClass) private val tileCtor = tileClass.getConstructors.filter(ctor => ctor.getParameterTypes()(4) == classOf[Parameters]).head - // Version of case class' copy() using reflection, where fields to be updated are passed by a map - def copyTileParam(tileParam: TileParamsT, properties: Map[String, Any]) = { - val values = tileParam.productIterator.toList - //val filteredProperties = properties filter { case (key, value) => paramNames contains key } - val indexedProperties = /*filteredProperties*/ properties map { case (key, value) => (paramNames(key), value) } - val newValues = (0 until values.size) map - (i => (if (indexedProperties contains i) indexedProperties(i) else values(i)).asInstanceOf[AnyRef]) - paramCtor.newInstance(newValues:_*) - } - // Tile parameter lookup using correct type def tileParamsLookup(implicit p: Parameters) = p(tilesKey) // If this core meet the requirement given by p, update parameter fields in the map def updateWithFilter(view: View, p: Any => Boolean): PartialFunction[Any, Map[String, Any] => Any] = { - case key if (key == tilesKey && p(tilesKey)) => properties => view(tilesKey) map - (tile => copyTileParam(tile, properties)) + case key if (key == tilesKey && p(tilesKey)) => newValues => view(tilesKey) map + (tile => CopyParam(tile, newValues)) } // Instantiate a tile and zip it with its parameter info, used by subsystem @@ -73,27 +59,12 @@ class CoreEntry[TileParamsT <: TileParams with Product: TypeTag, TileT <: BaseTi } } -// Generic Core Config - change properties in the given map -class GenericCoreConfig( - // Parameter properties to be changed and their new values. Any field not in a core's parameters will be ignored. - properties: Map[String, Any], - // Function for filtering the list of TilesKey. - filterFunc: Any => Boolean = (_ => true), - // Handling special cases where partial function input is not a TilesKey. - specialCase: (View, View, View) => PartialFunction[Any, Any] = ((_, _, _) => Map.empty) -) extends Config((site, here, up) => - scala.Function.unlift((key: Any) => { - val tiles = CoreManager.cores flatMap (core => core.updateWithFilter(up, filterFunc).lift(key)) - if (tiles.size == 0) None else Some(tiles map (tile => tile(properties))) - }).orElse(specialCase(site, here, up)) -) - // A list of all cores. object CoreManager { val cores: List[CoreEntryBase] = List( - // TODO ADD YOUR CORE DEFINITION HERE - new CoreEntry[RocketTileParams, RocketTile](RocketTilesKey, RocketCrossingKey), - new CoreEntry[BoomTileParams, BoomTile](BoomTilesKey, BoomCrossingKey), - new CoreEntry[ArianeTileParams, ArianeTile](ArianeTilesKey, ArianeCrossingKey) + // TODO ADD YOUR CORE DEFINITION HERE; note that the + new CoreEntry[RocketTileParams, RocketTile]("Rocket", RocketTilesKey, RocketCrossingKey), + new CoreEntry[BoomTileParams, BoomTile]("Boom", BoomTilesKey, BoomCrossingKey), + new CoreEntry[ArianeTileParams, ArianeTile]("Ariane", ArianeTilesKey, ArianeCrossingKey) ) } diff --git a/generators/chipyard/src/main/scala/GenericCoreConfig.scala b/generators/chipyard/src/main/scala/GenericCoreConfig.scala new file mode 100644 index 00000000..ac099742 --- /dev/null +++ b/generators/chipyard/src/main/scala/GenericCoreConfig.scala @@ -0,0 +1,133 @@ +package chipyard + +import scala.reflect.ClassTag +import scala.reflect.runtime.universe._ + +import chisel3._ + +import freechips.rocketchip.config.{Parameters, Config, Field, View} +import freechips.rocketchip.subsystem.{SystemBusKey, RocketTilesKey, RocketCrossingParams, RocketCrossingKey} +import freechips.rocketchip.diplomacy.{LazyModule, ClockCrossingType, ValName} +import freechips.rocketchip.diplomaticobjectmodel.logicaltree.LogicalTreeNode +import freechips.rocketchip.rocket._ +import freechips.rocketchip.tile._ + +import boom.common.{BoomTile, BoomTilesKey, BoomCrossingKey, BoomTileParams} +import ariane.{ArianeTile, ArianeTilesKey, ArianeCrossingKey, ArianeTileParams} + +// Extractor object accompanied class +// This is used to check the convertibility for those wrapped in Option, since Option's type is erased at runtime. +trait SubParameterBase { + def toProduct: Product + def cast(p: Any): Any +} +final class SubParameter[T <: Product](param: T) extends SubParameterBase { + def toProduct: Product = param + def cast(p: Any) = p.asInstanceOf[T] +} + +// Extractor object that help identify the parameter case classes. +// Add your customized nested parameter classes (or their commom base classes) here. +object CustomizedSubParameter { + def unapply(param: Product): Option[Product] = param match { + // ADD YOUR NESTED PARAMETER CLASS HERE, in the format shown below in SubParameter + case _ => None + } +} + +// Standard nested +object SubParameter { + def unapply(param: Product): Option[SubParameterBase] = param match { + case p: TileParams => Some(new SubParameter(p)) + case p: CoreParams => Some(new SubParameter(p)) + case p: ICacheParams => Some(new SubParameter(p)) + case p: DCacheParams => Some(new SubParameter(p)) + case p: MulDivParams => Some(new SubParameter(p)) + case p: FPUParams => Some(new SubParameter(p)) + case p: BTBParams => Some(new SubParameter(p)) + case p: BHTParams => Some(new SubParameter(p)) + case CustomizedSubParameter(p) => Some(new SubParameter(p)) + case _ => None + } +} + +// Dynamic update helper for Parameter class. +class CopyParam(paramExtracted: SubParameterBase) { + // Constructor for corresponding TileParams + private val param: Product = paramExtracted.toProduct + private val paramClass = param.getClass + private val paramNames = (paramClass.getDeclaredFields map (f => f.getName)) + private val paramCtor = paramClass.getConstructors.head + + // Function to build value entry + private def buildEntry(value: Any): Any = value match { + case Some(v) => Some(buildEntry(v)) + case SubParameter(p) => new CopyParam(p) + case v => v + } + + // Value of the case class + private val entries = param.productIterator.toList map (v => buildEntry(v)) + + // Update one value entry + private def updateEntry(entry: Any, newValue: Any): Any = entry match { + case Some(e) => newValue match { + case Some(v) => Some(updateEntry(e, v)) + case None => None + } + case e: CopyParam => newValue match { + case newValues: Map[String, Any] => e.update(newValues) + case v => paramExtracted.cast(v) + } + // Use cast() to check the type of the new value. Here I assume that all entries in the parameters class are simple values + // (like Int, BigInt and String), which are all final. This may breaks if a polymorphic type is added (unless it's a case + // class and registered above). + case e => e.getClass.cast(newValue) + } + + // Update the entire parameter object. + def update(newValues: Map[String, Any]): Any = { + val filteredValues = newValues.filter({ case (key, value) => paramNames contains key }) + val newValueList = entries.zipWithIndex map { + case (value, i) if newValues contains paramNames(i) => updateEntry(value, filteredValues(paramNames(i))).asInstanceOf[AnyRef] + case (value, i) => (value match { + case Some(v) => v match { + case copyParam: CopyParam => Some(copyParam.param) + case _ => Some(v) + } + case copyParam: CopyParam => copyParam.param + case _ => value + }).asInstanceOf[AnyRef] + } + paramCtor.newInstance(newValueList:_*) + } + + // For debug purpose - print what's in the object + override def toString(): String = paramClass.getSimpleName + "(" + entries.toString + ")" +} + +object CopyParam { + def apply(param: Product, newValues: Map[String, Any]): Any = param match { + case SubParameter(p) => new CopyParam(p).update(newValues) + case _ => throw new Exception("param is not a known Parameter type: add your custom parameter class to GenericCoreConfig.scala to fix it") + } +} + +// Change parameters for all registered cores in CoreManager. +class GenericCoreConfig ( + // Key-value pairs to be updated (keys are the name of fields). Any field not in a core's parameters will be ignored. + // If a field is a case class containing parameters (or an Option of that), you can use another Map containing the key-value pairs to + // update that case class. Using a new case class instance as the value is also acceptable. + // If a field is an Option, you should wrap your new values with Some() or set it to None. This also applies when a new case + // class instance is used for an Option field. + newValues: Map[String, Any], + // Function for filtering the list of TilesKey. + filterFunc: Any => Boolean = (_ => true), + // Handling special cases where partial function input is not a TilesKey. + specialCase: (View, View, View) => PartialFunction[Any, Any] = ((_, _, _) => Map.empty) +) extends Config((site, here, up) => + scala.Function.unlift((key: Any) => { + val tiles = CoreManager.cores flatMap (core => core.updateWithFilter(up, filterFunc).lift(key)) + if (tiles.size == 0) None else Some(tiles(0)(newValues)) + }).orElse(specialCase(site, here, up)) +) \ No newline at end of file diff --git a/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala b/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala index a36131b1..5855613e 100644 --- a/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala +++ b/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala @@ -33,8 +33,15 @@ class AddDefaultTests extends Phase with PreservesAll[Phase] with HasRocketChipS val suiteHelper = new TestSuiteHelper // Use Xlen as a proxy for detecting if we are a processor-like target // The underlying test suites expect this field to be defined - if (p.lift(XLen).nonEmpty) - CoreManager.cores map (core => suiteHelper.addGenericTestSuites(core.tileParamsLookup)) + if (p.lift(XLen).nonEmpty) { + val customizedSuite: Map[String, TestSuiteHelper => Unit] = Map( + // DEFINE CUSTOMIZED TEST HERE, using format ({Core name} -> _.{Test suite builder in TestSuiteHelper}) + ) + CoreManager.cores map (core => customizedSuite.get(core.name) match { + case Some(builder) => builder(suiteHelper) + case None => suiteHelper.addGenericTestSuites(core.tileParamsLookup) + }) + } // if hwacha parameter exists then generate its tests // TODO: find a more elegant way to do this. either through From e021f161dca48ea7b8136208a6c7e1b5c5aff23a Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Wed, 3 Jun 2020 20:57:31 -0700 Subject: [PATCH 13/27] Remove Debug message --- generators/chipyard/src/main/scala/GenericCoreConfig.scala | 3 --- 1 file changed, 3 deletions(-) diff --git a/generators/chipyard/src/main/scala/GenericCoreConfig.scala b/generators/chipyard/src/main/scala/GenericCoreConfig.scala index ac099742..63bc749f 100644 --- a/generators/chipyard/src/main/scala/GenericCoreConfig.scala +++ b/generators/chipyard/src/main/scala/GenericCoreConfig.scala @@ -101,9 +101,6 @@ class CopyParam(paramExtracted: SubParameterBase) { } paramCtor.newInstance(newValueList:_*) } - - // For debug purpose - print what's in the object - override def toString(): String = paramClass.getSimpleName + "(" + entries.toString + ")" } object CopyParam { From 0f116cb7174bd7baab083975527289c5aa7fed4a Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Thu, 4 Jun 2020 00:17:05 -0700 Subject: [PATCH 14/27] Tile construction delayed --- generators/chipyard/src/main/scala/CoreManager.scala | 10 ++++++++-- generators/chipyard/src/main/scala/Subsystem.scala | 9 +++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/generators/chipyard/src/main/scala/CoreManager.scala b/generators/chipyard/src/main/scala/CoreManager.scala index 57b63743..9dc55eff 100644 --- a/generators/chipyard/src/main/scala/CoreManager.scala +++ b/generators/chipyard/src/main/scala/CoreManager.scala @@ -21,7 +21,7 @@ sealed trait CoreEntryBase { def tileParamsLookup(implicit p: Parameters): Seq[TileParams] def updateWithFilter(view: View, p: Any => Boolean): PartialFunction[Any, Map[String, Any] => Any] def instantiateTile(crossingLookup: (Seq[RocketCrossingParams], Int) => Seq[RocketCrossingParams], logicalTreeNode: LogicalTreeNode) - (implicit p: Parameters, valName: ValName): Seq[(TileParams, RocketCrossingParams, BaseTile)] + (implicit p: Parameters, valName: ValName): Seq[(TileParams, RocketCrossingParams, () => BaseTile)] } // Implementation of third-party core entries @@ -53,7 +53,13 @@ class CoreEntry[TileParamsT <: TileParams with Product: TypeTag, TileT <: BaseTi case (param, crossing) => ( param, crossing, - LazyModule(tileCtor.newInstance(param, crossing, PriorityMuxHartIdFromSeq(tileParams), logicalTreeNode, p.asInstanceOf[Parameters]).asInstanceOf[TileT]) + (() => LazyModule(tileCtor.newInstance( + param, + crossing, + PriorityMuxHartIdFromSeq(tileParams), + logicalTreeNode, + p.asInstanceOf[Parameters] + ).asInstanceOf[TileT])) ) } } diff --git a/generators/chipyard/src/main/scala/Subsystem.scala b/generators/chipyard/src/main/scala/Subsystem.scala index 6410ac4e..fa5988e2 100644 --- a/generators/chipyard/src/main/scala/Subsystem.scala +++ b/generators/chipyard/src/main/scala/Subsystem.scala @@ -34,7 +34,9 @@ trait HasChipyardTiles extends HasTiles val module: HasChipyardTilesModuleImp // Generate tiles info from the list of cores in CoreManager - val allTilesInfo: Seq[(TileParams, RocketCrossingParams, BaseTile)] = + // Note: the 0-arity function is used to delay the construction of tiles to make sure that they are created + // in order + val allTilesInfo: Seq[(TileParams, RocketCrossingParams, () => BaseTile)] = (CoreManager.cores flatMap (core => core.instantiateTile(perTileOrGlobalSetting _, logicalTreeNode))) // Make a tile and wire its nodes into the system, @@ -44,8 +46,11 @@ trait HasChipyardTiles extends HasTiles // This MUST be performed in order of hartid // There is something weird with registering tile-local interrupt controllers to the CLINT. // TODO: investigate why + require((allTilesInfo map (info => info._1.hartId)).max == allTilesInfo.size - 1) val tiles = allTilesInfo.sortWith(_._1.hartId < _._1.hartId).map { - case (param, crossing, tile) => { + case (param, crossing, tileCtor) => { + val tile = tileCtor() + connectMasterPortsToSBus(tile, crossing) connectSlavePortsToCBus(tile, crossing) connectInterrupts(tile, debugOpt, clintOpt, plicOpt) From 98f6f9292eceede4c4e213991487275b58456560 Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Sat, 6 Jun 2020 16:22:59 -0700 Subject: [PATCH 15/27] Change Generic Config --- .../src/main/scala/ConfigFragments.scala | 21 +- .../chipyard/src/main/scala/CoreManager.scala | 12 +- .../src/main/scala/GenericCoreConfig.scala | 253 +++++++++++------- 3 files changed, 169 insertions(+), 117 deletions(-) diff --git a/generators/chipyard/src/main/scala/ConfigFragments.scala b/generators/chipyard/src/main/scala/ConfigFragments.scala index 4d0e0725..da1372db 100644 --- a/generators/chipyard/src/main/scala/ConfigFragments.scala +++ b/generators/chipyard/src/main/scala/ConfigFragments.scala @@ -13,6 +13,7 @@ import freechips.rocketchip.rocket.{RocketCoreParams, MulDivParams, DCacheParams import freechips.rocketchip.util.{AsyncResetReg} import boom.common.{BoomTilesKey} +import ariane.ArianeTilesKey import testchipip._ import hwacha.{Hwacha} @@ -22,7 +23,8 @@ import sifive.blocks.devices.uart._ import sifive.blocks.devices.spi._ import chipyard.{BuildTop, BuildSystem} -import chipyard.GenericCoreConfig +import chipyard.TilesKey +import chipyard.TileSeq._ /** * TODO: Why do we need this? @@ -59,7 +61,11 @@ class WithSPIFlash(size: BigInt = 0x10000000) extends Config((site, here, up) => SPIFlashParams(rAddress = 0x10040000, fAddress = 0x20000000, fSize = size)) }) -class WithL2TLBs(entries: Int) extends GenericCoreConfig(Map("core" -> Map("nL2TLBEntries" -> entries))) +class WithL2TLBs(entries: Int) extends Config((site, here, up) => { + case TilesKey(tilesKey) => up(tilesKey) tileMap (tile => tile.copy( + core = tile.core.copy(nL2TLBEntries = entries) + )) +}) class WithTracegenSystem extends Config((site, here, up) => { case BuildSystem => (p: Parameters) => LazyModule(new tracegen.TraceGenSystem()(p)) @@ -140,9 +146,8 @@ class WithControlCore extends Config((site, here, up) => { case MaxHartIdBits => log2Up(up(RocketTilesKey, site).size + up(BoomTilesKey, site).size + 1) }) -class WithTraceIO extends GenericCoreConfig( - newValues = Map("trace" -> true), - specialCase = (site, here, up) => { - case TracePortKey => Some(TracePortParams()) - } -) \ No newline at end of file +class WithTraceIO extends Config((site, here, up) => { + case BoomTilesKey => up(BoomTilesKey) map (tile => tile.copy(trace = true)) + case ArianeTilesKey => up(ArianeTilesKey) map (tile => tile.copy(trace = true)) + case TracePortKey => Some(TracePortParams()) +}) \ No newline at end of file diff --git a/generators/chipyard/src/main/scala/CoreManager.scala b/generators/chipyard/src/main/scala/CoreManager.scala index 9dc55eff..b5129217 100644 --- a/generators/chipyard/src/main/scala/CoreManager.scala +++ b/generators/chipyard/src/main/scala/CoreManager.scala @@ -18,8 +18,10 @@ import ariane.{ArianeTile, ArianeTilesKey, ArianeCrossingKey, ArianeTileParams} // Base trait for all third-party core entries sealed trait CoreEntryBase { val name: String + + def keyEqual(key: Any): Boolean def tileParamsLookup(implicit p: Parameters): Seq[TileParams] - def updateWithFilter(view: View, p: Any => Boolean): PartialFunction[Any, Map[String, Any] => Any] + def instantiateTile(crossingLookup: (Seq[RocketCrossingParams], Int) => Seq[RocketCrossingParams], logicalTreeNode: LogicalTreeNode) (implicit p: Parameters, valName: ValName): Seq[(TileParams, RocketCrossingParams, () => BaseTile)] } @@ -35,15 +37,11 @@ class CoreEntry[TileParamsT <: TileParams with Product: TypeTag, TileT <: BaseTi private val tileClass = mirror.runtimeClass(typeOf[TileT].typeSymbol.asClass) private val tileCtor = tileClass.getConstructors.filter(ctor => ctor.getParameterTypes()(4) == classOf[Parameters]).head + def keyEqual(key: Any) = key == tilesKey + // Tile parameter lookup using correct type def tileParamsLookup(implicit p: Parameters) = p(tilesKey) - // If this core meet the requirement given by p, update parameter fields in the map - def updateWithFilter(view: View, p: Any => Boolean): PartialFunction[Any, Map[String, Any] => Any] = { - case key if (key == tilesKey && p(tilesKey)) => newValues => view(tilesKey) map - (tile => CopyParam(tile, newValues)) - } - // Instantiate a tile and zip it with its parameter info, used by subsystem def instantiateTile(crossingLookup: (Seq[RocketCrossingParams], Int) => Seq[RocketCrossingParams], logicalTreeNode: LogicalTreeNode) (implicit p: Parameters, valName: ValName) = { diff --git a/generators/chipyard/src/main/scala/GenericCoreConfig.scala b/generators/chipyard/src/main/scala/GenericCoreConfig.scala index 63bc749f..159b8b69 100644 --- a/generators/chipyard/src/main/scala/GenericCoreConfig.scala +++ b/generators/chipyard/src/main/scala/GenericCoreConfig.scala @@ -15,116 +15,165 @@ import freechips.rocketchip.tile._ import boom.common.{BoomTile, BoomTilesKey, BoomCrossingKey, BoomTileParams} import ariane.{ArianeTile, ArianeTilesKey, ArianeCrossingKey, ArianeTileParams} -// Extractor object accompanied class -// This is used to check the convertibility for those wrapped in Option, since Option's type is erased at runtime. -trait SubParameterBase { - def toProduct: Product - def cast(p: Any): Any -} -final class SubParameter[T <: Product](param: T) extends SubParameterBase { - def toProduct: Product = param - def cast(p: Any) = p.asInstanceOf[T] +// Case class to change common parameters visible in the base traits. Some fields in the base traits may not be configurable as a +// case class constructor parameter for some cores, and those field will be ignored when applied. +case class GenericCoreParams( + val bootFreqHz: BigInt, + val useVM: Boolean, + val useUser: Boolean, + val useSupervisor: Boolean, + val useDebug: Boolean, + val useAtomics: Boolean, + val useAtomicsOnlyForIO: Boolean, + val useCompressed: Boolean, + override val useVector: Boolean, + val useSCIE: Boolean, + val useRVE: Boolean, + val mulDiv: Option[MulDivParams], + val fpu: Option[FPUParams], + val fetchWidth: Int, + val decodeWidth: Int, + val retireWidth: Int, + val instBits: Int, + val nLocalInterrupts: Int, + val nPMPs: Int, + val pmpGranularity: Int, + val nBreakpoints: Int, + val useBPWatch: Boolean, + val nPerfCounters: Int, + val haveBasicCounters: Boolean, + val haveFSDirty: Boolean, + val misaWritable: Boolean, + val haveCFlush: Boolean, + val nL2TLBEntries: Int, + val mtvecInit: Option[BigInt], + val mtvecWritable: Boolean, + // The original object + val _origin: CoreParams +) extends CoreParams { + def this(coreParams: CoreParams) = this( + bootFreqHz = coreParams.bootFreqHz, + useVM = coreParams.useVM, + useUser = coreParams.useUser, + useSupervisor = coreParams.useSupervisor, + useDebug = coreParams.useDebug, + useAtomics = coreParams.useAtomics, + useAtomicsOnlyForIO = coreParams.useAtomicsOnlyForIO, + useCompressed = coreParams.useCompressed, + useVector = coreParams.useVector, + useSCIE = coreParams.useSCIE, + useRVE = coreParams.useRVE, + mulDiv = coreParams.mulDiv, + fpu = coreParams.fpu, + fetchWidth = coreParams.fetchWidth, + decodeWidth = coreParams.decodeWidth, + retireWidth = coreParams.retireWidth, + instBits = coreParams.instBits, + nLocalInterrupts = coreParams.nLocalInterrupts, + nPMPs = coreParams.nPMPs, + pmpGranularity = coreParams.pmpGranularity, + nBreakpoints = coreParams.nBreakpoints, + useBPWatch = coreParams.useBPWatch, + nPerfCounters = coreParams.nPerfCounters, + haveBasicCounters = coreParams.haveBasicCounters, + haveFSDirty = coreParams.haveFSDirty, + misaWritable = coreParams.misaWritable, + haveCFlush = coreParams.haveCFlush, + nL2TLBEntries = coreParams.nL2TLBEntries, + mtvecInit = coreParams.mtvecInit, + mtvecWritable = coreParams.mtvecWritable, + + _origin = coreParams + ) + + // Reflection Info of this class + val fieldNames = (this.getClass.getDeclaredFields map (f => f.getName)).init + + // Convert back to core-specific tile + def convert: CoreParams = { + // Reflection of target class + val paramClass = _origin.getClass + val paramNames = (paramClass.getDeclaredFields map (f => f.getName)) + val paramCtor = paramClass.getConstructors.head + + // Build a list of parameter in the original parameter class + val nameDict = paramNames.zipWithIndex.toMap + val indexList = fieldNames map (n => nameDict.get(n)) + val fieldList = this.productIterator.toList.init + val fieldDict = ((indexList zip fieldList) collect { case (Some(i), v) => (i, v) }).toMap + val newValues = _origin.asInstanceOf[Product].productIterator.toList.zipWithIndex map + { case (v, i) => (if (fieldDict contains i) fieldDict(i) else v).asInstanceOf[AnyRef] } + + paramCtor.newInstance(newValues:_*).asInstanceOf[CoreParams] + } + + // Implement abstract function as placeholder + def lrscCycles: Int = _origin.lrscCycles } -// Extractor object that help identify the parameter case classes. -// Add your customized nested parameter classes (or their commom base classes) here. -object CustomizedSubParameter { - def unapply(param: Product): Option[Product] = param match { - // ADD YOUR NESTED PARAMETER CLASS HERE, in the format shown below in SubParameter - case _ => None +case class GenericTileParams( + val core: GenericCoreParams, + val icache: Option[ICacheParams], + val dcache: Option[DCacheParams], + val btb: Option[BTBParams], + val hartId: Int, + val beuAddr: Option[BigInt], + val blockerCtrlAddr: Option[BigInt], + val name: Option[String], + // The original object + val _origin: TileParams +) extends TileParams { + // Copy constructor to build the params + def this(tileParams: TileParams) = this( + core = new GenericCoreParams(tileParams.core), + icache = tileParams.icache, + dcache = tileParams.dcache, + btb = tileParams.btb, + hartId = tileParams.hartId, + beuAddr = tileParams.beuAddr, + blockerCtrlAddr = tileParams.blockerCtrlAddr, + name = tileParams.name, + + _origin = tileParams + ) + + // Reflection Info of this class + val fieldNames = (this.getClass.getDeclaredFields map (f => f.getName)).init + + // Convert back to core-specific tile + def convert: TileParams = { + // Reflection of target class + val paramClass = _origin.getClass + val paramNames = (paramClass.getDeclaredFields map (f => f.getName)) + val paramCtor = paramClass.getConstructors.head + + // Build a list of parameter in the original parameter class + val nameDict = paramNames.zipWithIndex.toMap + val indexList = fieldNames map (n => nameDict.get(n)) + val fieldList = this.productIterator.toList.updated(0, core.convert).init + val fieldDict = ((indexList zip fieldList) collect { case (Some(i), v) => (i, v) }).toMap + val newValues = _origin.asInstanceOf[Product].productIterator.toList.zipWithIndex map + { case (v, i) => (if (fieldDict contains i) fieldDict(i) else v).asInstanceOf[AnyRef] } + + paramCtor.newInstance(newValues:_*).asInstanceOf[TileParams] } } -// Standard nested -object SubParameter { - def unapply(param: Product): Option[SubParameterBase] = param match { - case p: TileParams => Some(new SubParameter(p)) - case p: CoreParams => Some(new SubParameter(p)) - case p: ICacheParams => Some(new SubParameter(p)) - case p: DCacheParams => Some(new SubParameter(p)) - case p: MulDivParams => Some(new SubParameter(p)) - case p: FPUParams => Some(new SubParameter(p)) - case p: BTBParams => Some(new SubParameter(p)) - case p: BHTParams => Some(new SubParameter(p)) - case CustomizedSubParameter(p) => Some(new SubParameter(p)) - case _ => None - } +// Extractor to capture TilesKey +object TilesKey { + def unapply(key: Any): Option[Field[Seq[_]]] = + if ((CoreManager.cores filter (core => core.keyEqual(key))).size != 0) Some(key.asInstanceOf[Field[Seq[_]]]) else None } -// Dynamic update helper for Parameter class. -class CopyParam(paramExtracted: SubParameterBase) { - // Constructor for corresponding TileParams - private val param: Product = paramExtracted.toProduct - private val paramClass = param.getClass - private val paramNames = (paramClass.getDeclaredFields map (f => f.getName)) - private val paramCtor = paramClass.getConstructors.head +class TileSeq(list: Seq[Any]) { + def tileMap(f: GenericTileParams => GenericTileParams): Seq[TileParams] = { + // If this is not an unpacked tile key, simply throw a type exception + // Static type checking is not possible when this class is used with TilesKey extractor + val tileList = list.asInstanceOf[Seq[TileParams]] - // Function to build value entry - private def buildEntry(value: Any): Any = value match { - case Some(v) => Some(buildEntry(v)) - case SubParameter(p) => new CopyParam(p) - case v => v - } - - // Value of the case class - private val entries = param.productIterator.toList map (v => buildEntry(v)) - - // Update one value entry - private def updateEntry(entry: Any, newValue: Any): Any = entry match { - case Some(e) => newValue match { - case Some(v) => Some(updateEntry(e, v)) - case None => None - } - case e: CopyParam => newValue match { - case newValues: Map[String, Any] => e.update(newValues) - case v => paramExtracted.cast(v) - } - // Use cast() to check the type of the new value. Here I assume that all entries in the parameters class are simple values - // (like Int, BigInt and String), which are all final. This may breaks if a polymorphic type is added (unless it's a case - // class and registered above). - case e => e.getClass.cast(newValue) - } - - // Update the entire parameter object. - def update(newValues: Map[String, Any]): Any = { - val filteredValues = newValues.filter({ case (key, value) => paramNames contains key }) - val newValueList = entries.zipWithIndex map { - case (value, i) if newValues contains paramNames(i) => updateEntry(value, filteredValues(paramNames(i))).asInstanceOf[AnyRef] - case (value, i) => (value match { - case Some(v) => v match { - case copyParam: CopyParam => Some(copyParam.param) - case _ => Some(v) - } - case copyParam: CopyParam => copyParam.param - case _ => value - }).asInstanceOf[AnyRef] - } - paramCtor.newInstance(newValueList:_*) + tileList map (tileParams => f(new GenericTileParams(tileParams)).convert) } } - -object CopyParam { - def apply(param: Product, newValues: Map[String, Any]): Any = param match { - case SubParameter(p) => new CopyParam(p).update(newValues) - case _ => throw new Exception("param is not a known Parameter type: add your custom parameter class to GenericCoreConfig.scala to fix it") - } +object TileSeq { + implicit def convertSeq(s: Seq[Any]) = new TileSeq(s) } - -// Change parameters for all registered cores in CoreManager. -class GenericCoreConfig ( - // Key-value pairs to be updated (keys are the name of fields). Any field not in a core's parameters will be ignored. - // If a field is a case class containing parameters (or an Option of that), you can use another Map containing the key-value pairs to - // update that case class. Using a new case class instance as the value is also acceptable. - // If a field is an Option, you should wrap your new values with Some() or set it to None. This also applies when a new case - // class instance is used for an Option field. - newValues: Map[String, Any], - // Function for filtering the list of TilesKey. - filterFunc: Any => Boolean = (_ => true), - // Handling special cases where partial function input is not a TilesKey. - specialCase: (View, View, View) => PartialFunction[Any, Any] = ((_, _, _) => Map.empty) -) extends Config((site, here, up) => - scala.Function.unlift((key: Any) => { - val tiles = CoreManager.cores flatMap (core => core.updateWithFilter(up, filterFunc).lift(key)) - if (tiles.size == 0) None else Some(tiles(0)(newValues)) - }).orElse(specialCase(site, here, up)) -) \ No newline at end of file From 119a44b1219a6930bcf895d91cd9b7f7d0867f7f Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Sat, 13 Jun 2020 01:36:14 -0700 Subject: [PATCH 16/27] Use config to manage core registration and custom tests --- .../src/main/scala/ConfigFragments.scala | 9 +- .../chipyard/src/main/scala/CoreManager.scala | 53 +++++++++- ...reConfig.scala => GenericCoreParams.scala} | 97 +++++++------------ .../chipyard/src/main/scala/Subsystem.scala | 2 +- .../chipyard/src/main/scala/TestSuites.scala | 15 +++ .../scala/stage/phases/AddDefaultTests.scala | 16 ++- 6 files changed, 111 insertions(+), 81 deletions(-) rename generators/chipyard/src/main/scala/{GenericCoreConfig.scala => GenericCoreParams.scala} (69%) diff --git a/generators/chipyard/src/main/scala/ConfigFragments.scala b/generators/chipyard/src/main/scala/ConfigFragments.scala index da1372db..8336bdc5 100644 --- a/generators/chipyard/src/main/scala/ConfigFragments.scala +++ b/generators/chipyard/src/main/scala/ConfigFragments.scala @@ -23,8 +23,7 @@ import sifive.blocks.devices.uart._ import sifive.blocks.devices.spi._ import chipyard.{BuildTop, BuildSystem} -import chipyard.TilesKey -import chipyard.TileSeq._ +import chipyard.{GenericTilesKey, GenericTileConfig} /** * TODO: Why do we need this? @@ -61,8 +60,8 @@ class WithSPIFlash(size: BigInt = 0x10000000) extends Config((site, here, up) => SPIFlashParams(rAddress = 0x10040000, fAddress = 0x20000000, fSize = size)) }) -class WithL2TLBs(entries: Int) extends Config((site, here, up) => { - case TilesKey(tilesKey) => up(tilesKey) tileMap (tile => tile.copy( +class WithL2TLBs(entries: Int) extends GenericTileConfig((site, here, up) => { + case GenericTilesKey(key) => up(GenericTilesKey(key)) map (tile => tile.copy( core = tile.core.copy(nL2TLBEntries = entries) )) }) @@ -150,4 +149,4 @@ class WithTraceIO extends Config((site, here, up) => { case BoomTilesKey => up(BoomTilesKey) map (tile => tile.copy(trace = true)) case ArianeTilesKey => up(ArianeTilesKey) map (tile => tile.copy(trace = true)) case TracePortKey => Some(TracePortParams()) -}) \ No newline at end of file +}) diff --git a/generators/chipyard/src/main/scala/CoreManager.scala b/generators/chipyard/src/main/scala/CoreManager.scala index b5129217..d013cc7c 100644 --- a/generators/chipyard/src/main/scala/CoreManager.scala +++ b/generators/chipyard/src/main/scala/CoreManager.scala @@ -15,6 +15,21 @@ import freechips.rocketchip.tile._ import boom.common.{BoomTile, BoomTilesKey, BoomCrossingKey, BoomTileParams} import ariane.{ArianeTile, ArianeTilesKey, ArianeCrossingKey, ArianeTileParams} +case object CoreEntryKey extends Field[Seq[CoreEntryBase]](Nil) + +// If this key is encountered by a GenericTilesKey extractor, throw immediately +// Inside the body of GenericTileConfig, suppressed will be set to true to prevent the extractor from throwing +case class GenericTilesKeyChecker(suppressed: Boolean) extends Field[Int](0) +case class GenericTilesKeyImp(key: Field[Seq[TileParams]]) extends Field[Seq[GenericTileParams]](Nil) +object GenericTilesKey { + def apply(key: Field[Seq[TileParams]]) = GenericTilesKeyImp(key) + def unapply(key: Any): Option[Field[Seq[TileParams]]] = key match { + case GenericTilesKeyChecker(suppressed) if !suppressed => throw new Exception("GenericTilesKey must be in GenericTilesConfig") + case GenericTilesKeyImp(key) => Some(key) + case _ => None + } +} + // Base trait for all third-party core entries sealed trait CoreEntryBase { val name: String @@ -45,6 +60,11 @@ class CoreEntry[TileParamsT <: TileParams with Product: TypeTag, TileT <: BaseTi // Instantiate a tile and zip it with its parameter info, used by subsystem def instantiateTile(crossingLookup: (Seq[RocketCrossingParams], Int) => Seq[RocketCrossingParams], logicalTreeNode: LogicalTreeNode) (implicit p: Parameters, valName: ValName) = { + // Sanity check of GenericTilesKey outside of GenericTileConfig + // People would shoot themselves in the foot easily with this design, so a sanity check is necessary + // Simply trigger the exception by looking up the checker key + p(GenericTilesKeyChecker(false)) + val tileParams = p(tilesKey) val crossings = crossingLookup(p(crossingKey), tileParams.size) (tileParams zip crossings) map { @@ -63,12 +83,41 @@ class CoreEntry[TileParamsT <: TileParams with Product: TypeTag, TileT <: BaseTi } } +// Config fragment to register a core +class RegisterCore[TileParamsT <: TileParams with Product: TypeTag, TileT <: BaseTile : TypeTag]( + name: String, + tilesKey: Field[Seq[TileParamsT]], + crossingKey: Field[Seq[RocketCrossingParams]] +) extends Config((site, here, up) => { + case CoreEntryKey => new CoreEntry[TileParamsT, TileT](name, tilesKey, crossingKey) +: up(CoreEntryKey) +}) + +// The config used along with GenericTilesKey. +// It change a lookup for registered tile parameter into a lookup with GenericTilesKey in the function body temporarily. +class GenericTileConfig(f: (View, View, View) => PartialFunction[Any, Any]) extends Config( + new Config((site, here, up) => { + case GenericTilesKeyChecker(_) => up(GenericTilesKeyChecker(true)) + case key if CoreManager.keyMatch(up, key) => up(GenericTilesKey(key.asInstanceOf[Field[Seq[TileParams]]])) map (t => t.convert) + }) ++ + new Config(f) ++ + new Config((site, here, up) => { + case GenericTilesKeyChecker(_) => up(GenericTilesKeyChecker(false)) + case GenericTilesKey(key) => up(key) map (t => new GenericTileParams(t)) + }) +) + // A list of all cores. object CoreManager { - val cores: List[CoreEntryBase] = List( - // TODO ADD YOUR CORE DEFINITION HERE; note that the + // Built-in cores. + val base_cores: List[CoreEntryBase] = List( new CoreEntry[RocketTileParams, RocketTile]("Rocket", RocketTilesKey, RocketCrossingKey), new CoreEntry[BoomTileParams, BoomTile]("Boom", BoomTilesKey, BoomCrossingKey), new CoreEntry[ArianeTileParams, ArianeTile]("Ariane", ArianeTilesKey, ArianeCrossingKey) ) + + // Look up all cores that are registered in the current config view. + def cores(view: View): Seq[CoreEntryBase] = view(CoreEntryKey) ++ base_cores + + // Check if the key is among the currently registered cores. + def keyMatch(view: View, key: Any) = (cores(view) filter (c => c.keyEqual(key))).size != 0 } diff --git a/generators/chipyard/src/main/scala/GenericCoreConfig.scala b/generators/chipyard/src/main/scala/GenericCoreParams.scala similarity index 69% rename from generators/chipyard/src/main/scala/GenericCoreConfig.scala rename to generators/chipyard/src/main/scala/GenericCoreParams.scala index 159b8b69..28db42b1 100644 --- a/generators/chipyard/src/main/scala/GenericCoreConfig.scala +++ b/generators/chipyard/src/main/scala/GenericCoreParams.scala @@ -15,6 +15,36 @@ import freechips.rocketchip.tile._ import boom.common.{BoomTile, BoomTilesKey, BoomCrossingKey, BoomTileParams} import ariane.{ArianeTile, ArianeTilesKey, ArianeCrossingKey, ArianeTileParams} +// Trait for generic case class of base trait for copying +trait ConcreteBaseTrait[Base] { + this: Product => + val _origin: Base + + // Convert back to core-specific tile + def convert: Base = { + // Reflection Info of this class + val fieldNames = (this.getClass.getDeclaredFields map (f => f.getName)).init + + // Reflection of target class + val paramClass = _origin.getClass + val paramNames = (paramClass.getDeclaredFields map (f => f.getName)) + val paramCtor = paramClass.getConstructors.head + + // Build a list of parameter in the original parameter class + val nameDict = paramNames.zipWithIndex.toMap + val indexList = fieldNames map (n => nameDict.get(n)) + val fieldList = this.productIterator.toList map { + case c: ConcreteBaseTrait[_] => c.convert + case v => v + } + val fieldDict = ((indexList zip fieldList) collect { case (Some(i), v) => (i, v) }).toMap + val newValues = _origin.asInstanceOf[Product].productIterator.toList.zipWithIndex map + { case (v, i) => (if (fieldDict contains i) fieldDict(i) else v).asInstanceOf[AnyRef] } + + paramCtor.newInstance(newValues:_*).asInstanceOf[Base] + } +} + // Case class to change common parameters visible in the base traits. Some fields in the base traits may not be configurable as a // case class constructor parameter for some cores, and those field will be ignored when applied. case class GenericCoreParams( @@ -50,7 +80,7 @@ case class GenericCoreParams( val mtvecWritable: Boolean, // The original object val _origin: CoreParams -) extends CoreParams { +) extends CoreParams with ConcreteBaseTrait[CoreParams] { def this(coreParams: CoreParams) = this( bootFreqHz = coreParams.bootFreqHz, useVM = coreParams.useVM, @@ -86,27 +116,6 @@ case class GenericCoreParams( _origin = coreParams ) - // Reflection Info of this class - val fieldNames = (this.getClass.getDeclaredFields map (f => f.getName)).init - - // Convert back to core-specific tile - def convert: CoreParams = { - // Reflection of target class - val paramClass = _origin.getClass - val paramNames = (paramClass.getDeclaredFields map (f => f.getName)) - val paramCtor = paramClass.getConstructors.head - - // Build a list of parameter in the original parameter class - val nameDict = paramNames.zipWithIndex.toMap - val indexList = fieldNames map (n => nameDict.get(n)) - val fieldList = this.productIterator.toList.init - val fieldDict = ((indexList zip fieldList) collect { case (Some(i), v) => (i, v) }).toMap - val newValues = _origin.asInstanceOf[Product].productIterator.toList.zipWithIndex map - { case (v, i) => (if (fieldDict contains i) fieldDict(i) else v).asInstanceOf[AnyRef] } - - paramCtor.newInstance(newValues:_*).asInstanceOf[CoreParams] - } - // Implement abstract function as placeholder def lrscCycles: Int = _origin.lrscCycles } @@ -121,8 +130,8 @@ case class GenericTileParams( val blockerCtrlAddr: Option[BigInt], val name: Option[String], // The original object - val _origin: TileParams -) extends TileParams { + val _origin: TileParams, +) extends TileParams with ConcreteBaseTrait[TileParams] { // Copy constructor to build the params def this(tileParams: TileParams) = this( core = new GenericCoreParams(tileParams.core), @@ -136,44 +145,4 @@ case class GenericTileParams( _origin = tileParams ) - - // Reflection Info of this class - val fieldNames = (this.getClass.getDeclaredFields map (f => f.getName)).init - - // Convert back to core-specific tile - def convert: TileParams = { - // Reflection of target class - val paramClass = _origin.getClass - val paramNames = (paramClass.getDeclaredFields map (f => f.getName)) - val paramCtor = paramClass.getConstructors.head - - // Build a list of parameter in the original parameter class - val nameDict = paramNames.zipWithIndex.toMap - val indexList = fieldNames map (n => nameDict.get(n)) - val fieldList = this.productIterator.toList.updated(0, core.convert).init - val fieldDict = ((indexList zip fieldList) collect { case (Some(i), v) => (i, v) }).toMap - val newValues = _origin.asInstanceOf[Product].productIterator.toList.zipWithIndex map - { case (v, i) => (if (fieldDict contains i) fieldDict(i) else v).asInstanceOf[AnyRef] } - - paramCtor.newInstance(newValues:_*).asInstanceOf[TileParams] - } -} - -// Extractor to capture TilesKey -object TilesKey { - def unapply(key: Any): Option[Field[Seq[_]]] = - if ((CoreManager.cores filter (core => core.keyEqual(key))).size != 0) Some(key.asInstanceOf[Field[Seq[_]]]) else None -} - -class TileSeq(list: Seq[Any]) { - def tileMap(f: GenericTileParams => GenericTileParams): Seq[TileParams] = { - // If this is not an unpacked tile key, simply throw a type exception - // Static type checking is not possible when this class is used with TilesKey extractor - val tileList = list.asInstanceOf[Seq[TileParams]] - - tileList map (tileParams => f(new GenericTileParams(tileParams)).convert) - } -} -object TileSeq { - implicit def convertSeq(s: Seq[Any]) = new TileSeq(s) } diff --git a/generators/chipyard/src/main/scala/Subsystem.scala b/generators/chipyard/src/main/scala/Subsystem.scala index fa5988e2..4ac92c4e 100644 --- a/generators/chipyard/src/main/scala/Subsystem.scala +++ b/generators/chipyard/src/main/scala/Subsystem.scala @@ -37,7 +37,7 @@ trait HasChipyardTiles extends HasTiles // Note: the 0-arity function is used to delay the construction of tiles to make sure that they are created // in order val allTilesInfo: Seq[(TileParams, RocketCrossingParams, () => BaseTile)] = - (CoreManager.cores flatMap (core => core.instantiateTile(perTileOrGlobalSetting _, logicalTreeNode))) + (CoreManager.cores(p) flatMap (core => core.instantiateTile(perTileOrGlobalSetting _, logicalTreeNode))) // Make a tile and wire its nodes into the system, // according to the specified type of clock crossing. diff --git a/generators/chipyard/src/main/scala/TestSuites.scala b/generators/chipyard/src/main/scala/TestSuites.scala index 2261000f..5a929010 100644 --- a/generators/chipyard/src/main/scala/TestSuites.scala +++ b/generators/chipyard/src/main/scala/TestSuites.scala @@ -2,6 +2,7 @@ package chipyard import scala.collection.mutable.{LinkedHashSet} +import freechips.rocketchip.config.{Parameters, Config, Field, View} import freechips.rocketchip.subsystem.{RocketTilesKey} import freechips.rocketchip.tile.{XLen, TileParams} import freechips.rocketchip.config.{Parameters, Field} @@ -102,3 +103,17 @@ class TestSuiteHelper } } } + +/** + * Config key of custom test suite. + */ +case object TestSuitesKey extends Field[(Seq[TileParams], TestSuiteHelper, Parameters) => Unit]((tiles, helper, p) => helper.addGenericTestSuites(tiles)(p)) + +/** + * Config fragment to add custom test suite factory function. + * + * @param suiteFactory Test suite factory function. It takes a list of TileParams to be instantiated and the test suite helper. + */ +class WithTestSuite(suiteFactory: (Seq[TileParams], TestSuiteHelper, Parameters) => Unit) extends Config((site, here, up) => { + case TestSuitesKey => suiteFactory +}) diff --git a/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala b/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala index 5855613e..b170706e 100644 --- a/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala +++ b/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala @@ -19,6 +19,7 @@ import freechips.rocketchip.util.HasRocketChipStageUtils import freechips.rocketchip.tile.XLen import chipyard.{TestSuiteHelper, CoreManager} +import chipyard.TestSuitesKey class AddDefaultTests extends Phase with PreservesAll[Phase] with HasRocketChipStageUtils { // Make sure we run both after RocketChip's version of this phase, and Rocket Chip's annotation emission phase @@ -33,15 +34,12 @@ class AddDefaultTests extends Phase with PreservesAll[Phase] with HasRocketChipS val suiteHelper = new TestSuiteHelper // Use Xlen as a proxy for detecting if we are a processor-like target // The underlying test suites expect this field to be defined - if (p.lift(XLen).nonEmpty) { - val customizedSuite: Map[String, TestSuiteHelper => Unit] = Map( - // DEFINE CUSTOMIZED TEST HERE, using format ({Core name} -> _.{Test suite builder in TestSuiteHelper}) - ) - CoreManager.cores map (core => customizedSuite.get(core.name) match { - case Some(builder) => builder(suiteHelper) - case None => suiteHelper.addGenericTestSuites(core.tileParamsLookup) - }) - } + if (p.lift(XLen).nonEmpty) + // If a custom test suite is set up, use the custom test suite + if (p.lift(TestSuitesKey).nonEmpty) + CoreManager.cores(p) map (core => p(TestSuitesKey).apply(core.tileParamsLookup, suiteHelper, p)) + else + CoreManager.cores(p) map (core => suiteHelper.addGenericTestSuites(core.tileParamsLookup)) // if hwacha parameter exists then generate its tests // TODO: find a more elegant way to do this. either through From 486cc5fce14c69c07cc55145fafc5c4c7d1d7a8c Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Sat, 20 Jun 2020 13:57:11 -0700 Subject: [PATCH 17/27] [firechip] Add a small target that should fit on all hosts --- .../firechip/src/main/scala/TargetConfigs.scala | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/generators/firechip/src/main/scala/TargetConfigs.scala b/generators/firechip/src/main/scala/TargetConfigs.scala index 63b4d2fe..830188f3 100644 --- a/generators/firechip/src/main/scala/TargetConfigs.scala +++ b/generators/firechip/src/main/scala/TargetConfigs.scala @@ -125,6 +125,20 @@ class FireSimQuadRocketConfig extends Config( new WithFireSimConfigTweaks ++ new chipyard.QuadRocketConfig) +// Should fit on all supported hosts +class FireSimSmallSystemConfig extends Config( + new WithDefaultFireSimBridges ++ + new WithDefaultMemModel ++ + new WithBootROM ++ + new WithPeripheryBusFrequency(BigInt(3200000000L)) ++ + new WithoutClockGating ++ + new WithoutTLMonitors ++ + new freechips.rocketchip.subsystem.WithExtMemSize(1 << 28) ++ + new testchipip.WithTSI ++ + new testchipip.WithBlockDevice ++ + new chipyard.config.WithUART ++ + new freechips.rocketchip.subsystem.WithInclusiveCache(nWays = 2, capacityKB = 64) ++ + new chipyard.RocketConfig) //***************************************************************** // Boom config, base off chipyard's LargeBoomConfig From 1c5bc7d0fff0dc20c8952e50b8bb724ede6da464 Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Wed, 24 Jun 2020 20:55:37 -0700 Subject: [PATCH 18/27] Integrate with new Rocket tile API --- .../src/main/scala/ConfigFragments.scala | 17 +-- .../chipyard/src/main/scala/CoreManager.scala | 123 ------------------ ...icCoreParams.scala => GenericParams.scala} | 37 +++++- .../chipyard/src/main/scala/TestSuites.scala | 26 ++-- .../scala/stage/phases/AddDefaultTests.scala | 8 +- 5 files changed, 56 insertions(+), 155 deletions(-) delete mode 100644 generators/chipyard/src/main/scala/CoreManager.scala rename generators/chipyard/src/main/scala/{GenericCoreParams.scala => GenericParams.scala} (82%) diff --git a/generators/chipyard/src/main/scala/ConfigFragments.scala b/generators/chipyard/src/main/scala/ConfigFragments.scala index 1d6281cf..d66d3a07 100644 --- a/generators/chipyard/src/main/scala/ConfigFragments.scala +++ b/generators/chipyard/src/main/scala/ConfigFragments.scala @@ -26,7 +26,7 @@ import sifive.blocks.devices.uart._ import sifive.blocks.devices.spi._ import chipyard.{BuildTop, BuildSystem} -import chipyard.{GenericTilesKey, GenericTileConfig} +import chipyard.GenericCanAttachTile /** * TODO: Why do we need this? @@ -65,11 +65,8 @@ class WithSPIFlash(size: BigInt = 0x10000000) extends Config((site, here, up) => class WithL2TLBs(entries: Int) extends Config((site, here, up) => { case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { - case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( - core = tp.tileParams.core.copy(nL2TLBEntries = entries))) - case tp: BoomTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( - core = tp.tileParams.core.copy(nL2TLBEntries = entries))) - case other => other + case GenericCanAttachTile(tp) => tp.copy(tileParams = tp.tileParams.copy( + core = tp.tileParams.core.copy(nL2TLBEntries = entries))).convert } }) @@ -110,7 +107,6 @@ class WithMultiRoCCHwacha(harts: Int*) extends Config((site, here, up) => { } }) - class WithTraceIO extends Config((site, here, up) => { case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { case tp: BoomTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( @@ -124,10 +120,7 @@ class WithTraceIO extends Config((site, here, up) => { class WithNPerfCounters(n: Int = 29) extends Config((site, here, up) => { case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { - case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( - core = tp.tileParams.core.copy(nPerfCounters = n))) - case tp: BoomTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( - core = tp.tileParams.core.copy(nPerfCounters = n))) - case other => other + case GenericCanAttachTile(tp) => tp.copy(tileParams = tp.tileParams.copy( + core = tp.tileParams.core.copy(nPerfCounters = n))).convert } }) diff --git a/generators/chipyard/src/main/scala/CoreManager.scala b/generators/chipyard/src/main/scala/CoreManager.scala deleted file mode 100644 index d013cc7c..00000000 --- a/generators/chipyard/src/main/scala/CoreManager.scala +++ /dev/null @@ -1,123 +0,0 @@ -package chipyard - -import scala.reflect.ClassTag -import scala.reflect.runtime.universe._ - -import chisel3._ - -import freechips.rocketchip.config.{Parameters, Config, Field, View} -import freechips.rocketchip.subsystem.{SystemBusKey, RocketTilesKey, RocketCrossingParams, RocketCrossingKey} -import freechips.rocketchip.diplomacy.{LazyModule, ClockCrossingType, ValName} -import freechips.rocketchip.diplomaticobjectmodel.logicaltree.LogicalTreeNode -import freechips.rocketchip.rocket._ -import freechips.rocketchip.tile._ - -import boom.common.{BoomTile, BoomTilesKey, BoomCrossingKey, BoomTileParams} -import ariane.{ArianeTile, ArianeTilesKey, ArianeCrossingKey, ArianeTileParams} - -case object CoreEntryKey extends Field[Seq[CoreEntryBase]](Nil) - -// If this key is encountered by a GenericTilesKey extractor, throw immediately -// Inside the body of GenericTileConfig, suppressed will be set to true to prevent the extractor from throwing -case class GenericTilesKeyChecker(suppressed: Boolean) extends Field[Int](0) -case class GenericTilesKeyImp(key: Field[Seq[TileParams]]) extends Field[Seq[GenericTileParams]](Nil) -object GenericTilesKey { - def apply(key: Field[Seq[TileParams]]) = GenericTilesKeyImp(key) - def unapply(key: Any): Option[Field[Seq[TileParams]]] = key match { - case GenericTilesKeyChecker(suppressed) if !suppressed => throw new Exception("GenericTilesKey must be in GenericTilesConfig") - case GenericTilesKeyImp(key) => Some(key) - case _ => None - } -} - -// Base trait for all third-party core entries -sealed trait CoreEntryBase { - val name: String - - def keyEqual(key: Any): Boolean - def tileParamsLookup(implicit p: Parameters): Seq[TileParams] - - def instantiateTile(crossingLookup: (Seq[RocketCrossingParams], Int) => Seq[RocketCrossingParams], logicalTreeNode: LogicalTreeNode) - (implicit p: Parameters, valName: ValName): Seq[(TileParams, RocketCrossingParams, () => BaseTile)] -} - -// Implementation of third-party core entries -class CoreEntry[TileParamsT <: TileParams with Product: TypeTag, TileT <: BaseTile : TypeTag]( - val name: String, - tilesKey: Field[Seq[TileParamsT]], - crossingKey: Field[Seq[RocketCrossingParams]] -) extends CoreEntryBase { - // Use reflection to get the tile's constructor - private val mirror = runtimeMirror(getClass.getClassLoader) - private val tileClass = mirror.runtimeClass(typeOf[TileT].typeSymbol.asClass) - private val tileCtor = tileClass.getConstructors.filter(ctor => ctor.getParameterTypes()(4) == classOf[Parameters]).head - - def keyEqual(key: Any) = key == tilesKey - - // Tile parameter lookup using correct type - def tileParamsLookup(implicit p: Parameters) = p(tilesKey) - - // Instantiate a tile and zip it with its parameter info, used by subsystem - def instantiateTile(crossingLookup: (Seq[RocketCrossingParams], Int) => Seq[RocketCrossingParams], logicalTreeNode: LogicalTreeNode) - (implicit p: Parameters, valName: ValName) = { - // Sanity check of GenericTilesKey outside of GenericTileConfig - // People would shoot themselves in the foot easily with this design, so a sanity check is necessary - // Simply trigger the exception by looking up the checker key - p(GenericTilesKeyChecker(false)) - - val tileParams = p(tilesKey) - val crossings = crossingLookup(p(crossingKey), tileParams.size) - (tileParams zip crossings) map { - case (param, crossing) => ( - param, - crossing, - (() => LazyModule(tileCtor.newInstance( - param, - crossing, - PriorityMuxHartIdFromSeq(tileParams), - logicalTreeNode, - p.asInstanceOf[Parameters] - ).asInstanceOf[TileT])) - ) - } - } -} - -// Config fragment to register a core -class RegisterCore[TileParamsT <: TileParams with Product: TypeTag, TileT <: BaseTile : TypeTag]( - name: String, - tilesKey: Field[Seq[TileParamsT]], - crossingKey: Field[Seq[RocketCrossingParams]] -) extends Config((site, here, up) => { - case CoreEntryKey => new CoreEntry[TileParamsT, TileT](name, tilesKey, crossingKey) +: up(CoreEntryKey) -}) - -// The config used along with GenericTilesKey. -// It change a lookup for registered tile parameter into a lookup with GenericTilesKey in the function body temporarily. -class GenericTileConfig(f: (View, View, View) => PartialFunction[Any, Any]) extends Config( - new Config((site, here, up) => { - case GenericTilesKeyChecker(_) => up(GenericTilesKeyChecker(true)) - case key if CoreManager.keyMatch(up, key) => up(GenericTilesKey(key.asInstanceOf[Field[Seq[TileParams]]])) map (t => t.convert) - }) ++ - new Config(f) ++ - new Config((site, here, up) => { - case GenericTilesKeyChecker(_) => up(GenericTilesKeyChecker(false)) - case GenericTilesKey(key) => up(key) map (t => new GenericTileParams(t)) - }) -) - -// A list of all cores. -object CoreManager { - // Built-in cores. - val base_cores: List[CoreEntryBase] = List( - new CoreEntry[RocketTileParams, RocketTile]("Rocket", RocketTilesKey, RocketCrossingKey), - new CoreEntry[BoomTileParams, BoomTile]("Boom", BoomTilesKey, BoomCrossingKey), - new CoreEntry[ArianeTileParams, ArianeTile]("Ariane", ArianeTilesKey, ArianeCrossingKey) - ) - - // Look up all cores that are registered in the current config view. - def cores(view: View): Seq[CoreEntryBase] = view(CoreEntryKey) ++ base_cores - - // Check if the key is among the currently registered cores. - def keyMatch(view: View, key: Any) = (cores(view) filter (c => c.keyEqual(key))).size != 0 -} diff --git a/generators/chipyard/src/main/scala/GenericCoreParams.scala b/generators/chipyard/src/main/scala/GenericParams.scala similarity index 82% rename from generators/chipyard/src/main/scala/GenericCoreParams.scala rename to generators/chipyard/src/main/scala/GenericParams.scala index 28db42b1..8ed0d0f3 100644 --- a/generators/chipyard/src/main/scala/GenericCoreParams.scala +++ b/generators/chipyard/src/main/scala/GenericParams.scala @@ -6,15 +6,12 @@ import scala.reflect.runtime.universe._ import chisel3._ import freechips.rocketchip.config.{Parameters, Config, Field, View} -import freechips.rocketchip.subsystem.{SystemBusKey, RocketTilesKey, RocketCrossingParams, RocketCrossingKey} +import freechips.rocketchip.subsystem._ import freechips.rocketchip.diplomacy.{LazyModule, ClockCrossingType, ValName} import freechips.rocketchip.diplomaticobjectmodel.logicaltree.LogicalTreeNode import freechips.rocketchip.rocket._ import freechips.rocketchip.tile._ -import boom.common.{BoomTile, BoomTilesKey, BoomCrossingKey, BoomTileParams} -import ariane.{ArianeTile, ArianeTilesKey, ArianeCrossingKey, ArianeTileParams} - // Trait for generic case class of base trait for copying trait ConcreteBaseTrait[Base] { this: Product => @@ -146,3 +143,35 @@ case class GenericTileParams( _origin = tileParams ) } + +case class GenericTileCrossingParamsLike( + val crossingType: ClockCrossingType, + val master: TilePortParamsLike, + val slave: TilePortParamsLike, + val _origin: TileCrossingParamsLike +) extends TileCrossingParamsLike with ConcreteBaseTrait[TileCrossingParamsLike] { + def this(crossing: TileCrossingParamsLike) = this( + crossingType = crossing.crossingType, + master = crossing.master, + slave = crossing.slave, + _origin = crossing + ) +} + +case class GenericCanAttachTileImpl( + val tileParams: GenericTileParams, + val crossingParams: TileCrossingParamsLike, + val lookup: LookupByHartIdImpl, + val _origin: CanAttachTile, +) extends ConcreteBaseTrait[CanAttachTile] { + def this(param: CanAttachTile) = this( + tileParams = new GenericTileParams(param.tileParams), + crossingParams = new GenericTileCrossingParamsLike(param.crossingParams), + lookup = param.lookup, + _origin = param + ) +} + +object GenericCanAttachTile { + def unapply(tile: CanAttachTile) = Some(new GenericCanAttachTileImpl(tile)) +} diff --git a/generators/chipyard/src/main/scala/TestSuites.scala b/generators/chipyard/src/main/scala/TestSuites.scala index a3565a53..77aab39b 100644 --- a/generators/chipyard/src/main/scala/TestSuites.scala +++ b/generators/chipyard/src/main/scala/TestSuites.scala @@ -3,8 +3,8 @@ package chipyard import scala.collection.mutable.{LinkedHashSet} import freechips.rocketchip.subsystem._ -import freechips.rocketchip.tile.{XLen} -import freechips.rocketchip.config.{Parameters} +import freechips.rocketchip.tile.{XLen, TileParams} +import freechips.rocketchip.config.{Parameters, Field, Config} import freechips.rocketchip.system.{TestGeneration, RegressionTestSuite, RocketTestSuite} import boom.common.{BoomTileAttachParams} @@ -83,16 +83,17 @@ class TestSuiteHelper if (cfg.fLen >= 64) addSuites(env.map(rv64ud)) } - if (coreParams.useAtomics) { - if (tileParams.dcache.flatMap(_.scratch).isEmpty) - addSuites(env.map(if (xlen == 64) rv64ua else rv32ua)) - else - addSuites(env.map(if (xlen == 64) rv64uaSansLRSC else rv32uaSansLRSC)) - } - if (coreParams.useCompressed) addSuites(env.map(if (xlen == 64) rv64uc else rv32uc)) - val (rvi, rvu) = - if (xlen == 64) ((if (vm) rv64i else rv64pi), rv64u) - else ((if (vm) rv32i else rv32pi), rv32u) + } + if (coreParams.useAtomics) { + if (tileParams.dcache.flatMap(_.scratch).isEmpty) + addSuites(env.map(if (xlen == 64) rv64ua else rv32ua)) + else + addSuites(env.map(if (xlen == 64) rv64uaSansLRSC else rv32uaSansLRSC)) + } + if (coreParams.useCompressed) addSuites(env.map(if (xlen == 64) rv64uc else rv32uc)) + val (rvi, rvu) = + if (xlen == 64) ((if (vm) rv64i else rv64pi), rv64u) + else ((if (vm) rv32i else rv32pi), rv32u) addSuites(rvi.map(_("p"))) addSuites(rvu.map(_("p"))) @@ -116,4 +117,3 @@ case object TestSuitesKey extends Field[(Seq[TileParams], TestSuiteHelper, Param class WithTestSuite(suiteFactory: (Seq[TileParams], TestSuiteHelper, Parameters) => Unit) extends Config((site, here, up) => { case TestSuitesKey => suiteFactory }) - diff --git a/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala b/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala index b170706e..623dbce4 100644 --- a/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala +++ b/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala @@ -15,10 +15,11 @@ import firrtl.options.Viewer.view import freechips.rocketchip.stage.RocketChipOptions import freechips.rocketchip.stage.phases.{RocketTestSuiteAnnotation} import freechips.rocketchip.system.{RocketTestSuite, TestGeneration} +import freechips.rocketchip.subsystem.{TilesLocated, InSubsystem} import freechips.rocketchip.util.HasRocketChipStageUtils import freechips.rocketchip.tile.XLen -import chipyard.{TestSuiteHelper, CoreManager} +import chipyard.TestSuiteHelper import chipyard.TestSuitesKey class AddDefaultTests extends Phase with PreservesAll[Phase] with HasRocketChipStageUtils { @@ -34,12 +35,13 @@ class AddDefaultTests extends Phase with PreservesAll[Phase] with HasRocketChipS val suiteHelper = new TestSuiteHelper // Use Xlen as a proxy for detecting if we are a processor-like target // The underlying test suites expect this field to be defined + val tileParams = p(TilesLocated(InSubsystem)) map (tp => tp.tileParams) if (p.lift(XLen).nonEmpty) // If a custom test suite is set up, use the custom test suite if (p.lift(TestSuitesKey).nonEmpty) - CoreManager.cores(p) map (core => p(TestSuitesKey).apply(core.tileParamsLookup, suiteHelper, p)) + p(TestSuitesKey).apply(tileParams, suiteHelper, p) else - CoreManager.cores(p) map (core => suiteHelper.addGenericTestSuites(core.tileParamsLookup)) + suiteHelper.addGenericTestSuites(tileParams) // if hwacha parameter exists then generate its tests // TODO: find a more elegant way to do this. either through From 1dd3ea4aebdcc720af33495fb12b364b643b76de Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Sat, 27 Jun 2020 13:44:52 -0700 Subject: [PATCH 19/27] Update TargetConfigs.scala --- generators/firechip/src/main/scala/TargetConfigs.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/generators/firechip/src/main/scala/TargetConfigs.scala b/generators/firechip/src/main/scala/TargetConfigs.scala index 830188f3..87662b03 100644 --- a/generators/firechip/src/main/scala/TargetConfigs.scala +++ b/generators/firechip/src/main/scala/TargetConfigs.scala @@ -125,7 +125,8 @@ class FireSimQuadRocketConfig extends Config( new WithFireSimConfigTweaks ++ new chipyard.QuadRocketConfig) -// Should fit on all supported hosts +// A stripped down configuration that should fit on all supported hosts. +// Flat to avoid having to reorganize the config class hierarchy to remove certain features class FireSimSmallSystemConfig extends Config( new WithDefaultFireSimBridges ++ new WithDefaultMemModel ++ From c85d8c4211c3c888a0ba0b80a92ee5d5b23bbc39 Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Mon, 29 Jun 2020 11:42:34 -0700 Subject: [PATCH 20/27] Remove generic parameter from this PR --- .../src/main/scala/ConfigFragments.scala | 48 +++-- .../src/main/scala/GenericParams.scala | 177 ------------------ .../chipyard/src/main/scala/TestSuites.scala | 13 +- .../src/main/scala/config/BoomConfigs.scala | 1 + .../src/main/scala/config/HeteroConfigs.scala | 1 + .../src/main/scala/config/RocketConfigs.scala | 1 + .../scala/stage/phases/AddDefaultTests.scala | 18 +- 7 files changed, 42 insertions(+), 217 deletions(-) delete mode 100644 generators/chipyard/src/main/scala/GenericParams.scala diff --git a/generators/chipyard/src/main/scala/ConfigFragments.scala b/generators/chipyard/src/main/scala/ConfigFragments.scala index d66d3a07..da048ff1 100644 --- a/generators/chipyard/src/main/scala/ConfigFragments.scala +++ b/generators/chipyard/src/main/scala/ConfigFragments.scala @@ -25,8 +25,7 @@ import sifive.blocks.devices.gpio._ import sifive.blocks.devices.uart._ import sifive.blocks.devices.spi._ -import chipyard.{BuildTop, BuildSystem} -import chipyard.GenericCanAttachTile +import chipyard.{BuildTop, BuildSystem, TestSuitesKey, TestSuiteHelper} /** * TODO: Why do we need this? @@ -65,8 +64,11 @@ class WithSPIFlash(size: BigInt = 0x10000000) extends Config((site, here, up) => class WithL2TLBs(entries: Int) extends Config((site, here, up) => { case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { - case GenericCanAttachTile(tp) => tp.copy(tileParams = tp.tileParams.copy( - core = tp.tileParams.core.copy(nL2TLBEntries = entries))).convert + case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( + core = tp.tileParams.core.copy(nL2TLBEntries = entries))) + case tp: BoomTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( + core = tp.tileParams.core.copy(nL2TLBEntries = entries))) + case other => other } }) @@ -97,15 +99,18 @@ class WithMultiRoCC extends Config((site, here, up) => { * * @param harts harts to specify which will get a Hwacha */ -class WithMultiRoCCHwacha(harts: Int*) extends Config((site, here, up) => { - case MultiRoCCKey => { - up(MultiRoCCKey, site) ++ harts.distinct.map{ i => - (i -> Seq((p: Parameters) => { - LazyModule(new Hwacha()(p)).suggestName("hwacha") - })) +class WithMultiRoCCHwacha(harts: Int*) extends Config( + new chipyard.config.WithHwachaTest ++ + new Config((site, here, up) => { + case MultiRoCCKey => { + up(MultiRoCCKey, site) ++ harts.distinct.map{ i => + (i -> Seq((p: Parameters) => { + LazyModule(new Hwacha()(p)).suggestName("hwacha") + })) + } } - } -}) + }) +) class WithTraceIO extends Config((site, here, up) => { case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { @@ -120,7 +125,22 @@ class WithTraceIO extends Config((site, here, up) => { class WithNPerfCounters(n: Int = 29) extends Config((site, here, up) => { case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { - case GenericCanAttachTile(tp) => tp.copy(tileParams = tp.tileParams.copy( - core = tp.tileParams.core.copy(nPerfCounters = n))).convert + case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( + core = tp.tileParams.core.copy(nPerfCounters = n))) + case tp: BoomTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( + core = tp.tileParams.core.copy(nPerfCounters = n))) + case other => other } }) + +class WithHwachaTest extends Config((site, here, up) => { + case TestSuitesKey => (tileParams: Seq[TileParams], suiteHelper: TestSuiteHelper, p: Parameters) => { + up(TestSuitesKey).apply(tileParams, suiteHelper, p) + import hwacha.HwachaTestSuites._ + suiteHelper.addSuites(rv64uv.map(_("p"))) + suiteHelper.addSuites(rv64uv.map(_("vp"))) + suiteHelper.addSuite(rv64sv("p")) + suiteHelper.addSuite(hwachaBmarks) + "SRC_EXTENSION = $(base_dir)/hwacha/$(src_path)/*.scala" + "\nDISASM_EXTENSION = --extension=hwacha" + } +}) \ No newline at end of file diff --git a/generators/chipyard/src/main/scala/GenericParams.scala b/generators/chipyard/src/main/scala/GenericParams.scala deleted file mode 100644 index 8ed0d0f3..00000000 --- a/generators/chipyard/src/main/scala/GenericParams.scala +++ /dev/null @@ -1,177 +0,0 @@ -package chipyard - -import scala.reflect.ClassTag -import scala.reflect.runtime.universe._ - -import chisel3._ - -import freechips.rocketchip.config.{Parameters, Config, Field, View} -import freechips.rocketchip.subsystem._ -import freechips.rocketchip.diplomacy.{LazyModule, ClockCrossingType, ValName} -import freechips.rocketchip.diplomaticobjectmodel.logicaltree.LogicalTreeNode -import freechips.rocketchip.rocket._ -import freechips.rocketchip.tile._ - -// Trait for generic case class of base trait for copying -trait ConcreteBaseTrait[Base] { - this: Product => - val _origin: Base - - // Convert back to core-specific tile - def convert: Base = { - // Reflection Info of this class - val fieldNames = (this.getClass.getDeclaredFields map (f => f.getName)).init - - // Reflection of target class - val paramClass = _origin.getClass - val paramNames = (paramClass.getDeclaredFields map (f => f.getName)) - val paramCtor = paramClass.getConstructors.head - - // Build a list of parameter in the original parameter class - val nameDict = paramNames.zipWithIndex.toMap - val indexList = fieldNames map (n => nameDict.get(n)) - val fieldList = this.productIterator.toList map { - case c: ConcreteBaseTrait[_] => c.convert - case v => v - } - val fieldDict = ((indexList zip fieldList) collect { case (Some(i), v) => (i, v) }).toMap - val newValues = _origin.asInstanceOf[Product].productIterator.toList.zipWithIndex map - { case (v, i) => (if (fieldDict contains i) fieldDict(i) else v).asInstanceOf[AnyRef] } - - paramCtor.newInstance(newValues:_*).asInstanceOf[Base] - } -} - -// Case class to change common parameters visible in the base traits. Some fields in the base traits may not be configurable as a -// case class constructor parameter for some cores, and those field will be ignored when applied. -case class GenericCoreParams( - val bootFreqHz: BigInt, - val useVM: Boolean, - val useUser: Boolean, - val useSupervisor: Boolean, - val useDebug: Boolean, - val useAtomics: Boolean, - val useAtomicsOnlyForIO: Boolean, - val useCompressed: Boolean, - override val useVector: Boolean, - val useSCIE: Boolean, - val useRVE: Boolean, - val mulDiv: Option[MulDivParams], - val fpu: Option[FPUParams], - val fetchWidth: Int, - val decodeWidth: Int, - val retireWidth: Int, - val instBits: Int, - val nLocalInterrupts: Int, - val nPMPs: Int, - val pmpGranularity: Int, - val nBreakpoints: Int, - val useBPWatch: Boolean, - val nPerfCounters: Int, - val haveBasicCounters: Boolean, - val haveFSDirty: Boolean, - val misaWritable: Boolean, - val haveCFlush: Boolean, - val nL2TLBEntries: Int, - val mtvecInit: Option[BigInt], - val mtvecWritable: Boolean, - // The original object - val _origin: CoreParams -) extends CoreParams with ConcreteBaseTrait[CoreParams] { - def this(coreParams: CoreParams) = this( - bootFreqHz = coreParams.bootFreqHz, - useVM = coreParams.useVM, - useUser = coreParams.useUser, - useSupervisor = coreParams.useSupervisor, - useDebug = coreParams.useDebug, - useAtomics = coreParams.useAtomics, - useAtomicsOnlyForIO = coreParams.useAtomicsOnlyForIO, - useCompressed = coreParams.useCompressed, - useVector = coreParams.useVector, - useSCIE = coreParams.useSCIE, - useRVE = coreParams.useRVE, - mulDiv = coreParams.mulDiv, - fpu = coreParams.fpu, - fetchWidth = coreParams.fetchWidth, - decodeWidth = coreParams.decodeWidth, - retireWidth = coreParams.retireWidth, - instBits = coreParams.instBits, - nLocalInterrupts = coreParams.nLocalInterrupts, - nPMPs = coreParams.nPMPs, - pmpGranularity = coreParams.pmpGranularity, - nBreakpoints = coreParams.nBreakpoints, - useBPWatch = coreParams.useBPWatch, - nPerfCounters = coreParams.nPerfCounters, - haveBasicCounters = coreParams.haveBasicCounters, - haveFSDirty = coreParams.haveFSDirty, - misaWritable = coreParams.misaWritable, - haveCFlush = coreParams.haveCFlush, - nL2TLBEntries = coreParams.nL2TLBEntries, - mtvecInit = coreParams.mtvecInit, - mtvecWritable = coreParams.mtvecWritable, - - _origin = coreParams - ) - - // Implement abstract function as placeholder - def lrscCycles: Int = _origin.lrscCycles -} - -case class GenericTileParams( - val core: GenericCoreParams, - val icache: Option[ICacheParams], - val dcache: Option[DCacheParams], - val btb: Option[BTBParams], - val hartId: Int, - val beuAddr: Option[BigInt], - val blockerCtrlAddr: Option[BigInt], - val name: Option[String], - // The original object - val _origin: TileParams, -) extends TileParams with ConcreteBaseTrait[TileParams] { - // Copy constructor to build the params - def this(tileParams: TileParams) = this( - core = new GenericCoreParams(tileParams.core), - icache = tileParams.icache, - dcache = tileParams.dcache, - btb = tileParams.btb, - hartId = tileParams.hartId, - beuAddr = tileParams.beuAddr, - blockerCtrlAddr = tileParams.blockerCtrlAddr, - name = tileParams.name, - - _origin = tileParams - ) -} - -case class GenericTileCrossingParamsLike( - val crossingType: ClockCrossingType, - val master: TilePortParamsLike, - val slave: TilePortParamsLike, - val _origin: TileCrossingParamsLike -) extends TileCrossingParamsLike with ConcreteBaseTrait[TileCrossingParamsLike] { - def this(crossing: TileCrossingParamsLike) = this( - crossingType = crossing.crossingType, - master = crossing.master, - slave = crossing.slave, - _origin = crossing - ) -} - -case class GenericCanAttachTileImpl( - val tileParams: GenericTileParams, - val crossingParams: TileCrossingParamsLike, - val lookup: LookupByHartIdImpl, - val _origin: CanAttachTile, -) extends ConcreteBaseTrait[CanAttachTile] { - def this(param: CanAttachTile) = this( - tileParams = new GenericTileParams(param.tileParams), - crossingParams = new GenericTileCrossingParamsLike(param.crossingParams), - lookup = param.lookup, - _origin = param - ) -} - -object GenericCanAttachTile { - def unapply(tile: CanAttachTile) = Some(new GenericCanAttachTileImpl(tile)) -} diff --git a/generators/chipyard/src/main/scala/TestSuites.scala b/generators/chipyard/src/main/scala/TestSuites.scala index 77aab39b..9ca2c08c 100644 --- a/generators/chipyard/src/main/scala/TestSuites.scala +++ b/generators/chipyard/src/main/scala/TestSuites.scala @@ -107,13 +107,8 @@ class TestSuiteHelper /** * Config key of custom test suite. */ -case object TestSuitesKey extends Field[(Seq[TileParams], TestSuiteHelper, Parameters) => Unit]((tiles, helper, p) => helper.addGenericTestSuites(tiles)(p)) - -/** - * Config fragment to add custom test suite factory function. - * - * @param suiteFactory Test suite factory function. It takes a list of TileParams to be instantiated and the test suite helper. - */ -class WithTestSuite(suiteFactory: (Seq[TileParams], TestSuiteHelper, Parameters) => Unit) extends Config((site, here, up) => { - case TestSuitesKey => suiteFactory +case object TestSuitesKey extends Field[(Seq[TileParams], TestSuiteHelper, Parameters) => String]((tiles, helper, p) => { + helper.addGenericTestSuites(tiles)(p) + // Return an empty string as makefile additional snippets + "" }) diff --git a/generators/chipyard/src/main/scala/config/BoomConfigs.scala b/generators/chipyard/src/main/scala/config/BoomConfigs.scala index 7b66e3b3..414f10af 100644 --- a/generators/chipyard/src/main/scala/config/BoomConfigs.scala +++ b/generators/chipyard/src/main/scala/config/BoomConfigs.scala @@ -106,6 +106,7 @@ class HwachaLargeBoomConfig extends Config( new chipyard.config.WithBootROM ++ new chipyard.config.WithUART ++ new chipyard.config.WithL2TLBs(1024) ++ + new chipyard.config.WithHwachaTest ++ new hwacha.DefaultHwachaConfig ++ // use Hwacha vector accelerator new freechips.rocketchip.subsystem.WithNoMMIOPort ++ new freechips.rocketchip.subsystem.WithNoSlavePort ++ diff --git a/generators/chipyard/src/main/scala/config/HeteroConfigs.scala b/generators/chipyard/src/main/scala/config/HeteroConfigs.scala index a7d1c133..4930ddee 100644 --- a/generators/chipyard/src/main/scala/config/HeteroConfigs.scala +++ b/generators/chipyard/src/main/scala/config/HeteroConfigs.scala @@ -36,6 +36,7 @@ class HwachaLargeBoomAndHwachaRocketConfig extends Config( new chipyard.config.WithBootROM ++ new chipyard.config.WithUART ++ new chipyard.config.WithL2TLBs(1024) ++ + new chipyard.config.WithHwachaTest ++ new hwacha.DefaultHwachaConfig ++ // add hwacha to all harts new boom.common.WithNLargeBooms(1) ++ new freechips.rocketchip.subsystem.WithNoMMIOPort ++ diff --git a/generators/chipyard/src/main/scala/config/RocketConfigs.scala b/generators/chipyard/src/main/scala/config/RocketConfigs.scala index 06257c7b..566e2757 100644 --- a/generators/chipyard/src/main/scala/config/RocketConfigs.scala +++ b/generators/chipyard/src/main/scala/config/RocketConfigs.scala @@ -34,6 +34,7 @@ class HwachaRocketConfig extends Config( new chipyard.config.WithBootROM ++ new chipyard.config.WithUART ++ new chipyard.config.WithL2TLBs(1024) ++ + new chipyard.config.WithHwachaTest ++ new hwacha.DefaultHwachaConfig ++ // use Hwacha vector accelerator new freechips.rocketchip.subsystem.WithNoMMIOPort ++ new freechips.rocketchip.subsystem.WithNoSlavePort ++ diff --git a/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala b/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala index 623dbce4..177d26b0 100644 --- a/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala +++ b/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala @@ -38,24 +38,8 @@ class AddDefaultTests extends Phase with PreservesAll[Phase] with HasRocketChipS val tileParams = p(TilesLocated(InSubsystem)) map (tp => tp.tileParams) if (p.lift(XLen).nonEmpty) // If a custom test suite is set up, use the custom test suite - if (p.lift(TestSuitesKey).nonEmpty) - p(TestSuitesKey).apply(tileParams, suiteHelper, p) - else - suiteHelper.addGenericTestSuites(tileParams) + annotations += CustomMakefragSnippet(p(TestSuitesKey).apply(tileParams, suiteHelper, p)) - // if hwacha parameter exists then generate its tests - // TODO: find a more elegant way to do this. either through - // trying to disambiguate BuildRoCC, having a AccelParamsKey, - // or having the Accelerator/Tile add its own tests - import hwacha.HwachaTestSuites._ - if (Try(p(hwacha.HwachaNLanes)).getOrElse(0) > 0) { - suiteHelper.addSuites(rv64uv.map(_("p"))) - suiteHelper.addSuites(rv64uv.map(_("vp"))) - suiteHelper.addSuite(rv64sv("p")) - suiteHelper.addSuite(hwachaBmarks) - annotations += CustomMakefragSnippet( - "SRC_EXTENSION = $(base_dir)/hwacha/$(src_path)/*.scala" + "\nDISASM_EXTENSION = --extension=hwacha") - } RocketTestSuiteAnnotation(suiteHelper.suites.values.toSeq) +: annotations } From d77c4afb36ec37414dadbef63904376f8e0853d3 Mon Sep 17 00:00:00 2001 From: Zitao Fang Date: Mon, 29 Jun 2020 12:05:24 -0700 Subject: [PATCH 21/27] Rollback .gitignore --- .gitignore | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.gitignore b/.gitignore index 57467069..35d9b2d8 100644 --- a/.gitignore +++ b/.gitignore @@ -10,10 +10,6 @@ target *# *~ .idea -.bloop -.metals -project/metals.sbt -.vscode .DS_Store env.sh riscv-tools-install From 863f723708f39304293e6aba52bca2d47e130c85 Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Tue, 30 Jun 2020 12:26:26 -0700 Subject: [PATCH 22/27] Pipe through AXI4 MMIO and Slave ports to ChipTop | IOBinders fix * Fixes bug with AXI4 MMIO ports not being generated properly due to IOBinders issue. Additionally adds IOCells to AXI4 ports so that they appear in ChipTop * Change IOBinders to also require passing p: Parameters to child functions. Serialization of type targets via ClassTags fails for compound types, so we cannot use `BaseSubsystem with HasSomeTrait` as the type target in OverrideIOBinders. --- .circleci/config.yml | 9 ++ .circleci/defaults.sh | 32 ++--- .../chipyard/src/main/scala/ChipTop.scala | 3 +- .../chipyard/src/main/scala/IOBinders.scala | 117 ++++++++++-------- .../src/main/scala/config/RocketConfigs.scala | 18 +++ .../src/main/scala/BridgeBinders.scala | 39 +++--- tools/barstools | 2 +- 7 files changed, 132 insertions(+), 88 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ab123661..b6556850 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -287,6 +287,11 @@ jobs: steps: - prepare-rtl: project-key: "chipyard-spiflashread" + prepare-chipyard-mmios: + executor: main-env + steps: + - prepare-rtl: + project-key: "chipyard-mmios" chipyard-rocket-run-tests: executor: main-env steps: @@ -531,6 +536,10 @@ workflows: - install-riscv-toolchain - install-verilator + - prepare-chipyard-mmios: + requires: + - install-riscv-toolchain + # Run the respective tests # Run the example tests diff --git a/.circleci/defaults.sh b/.circleci/defaults.sh index b9aeeb3b..7cb8c1e2 100755 --- a/.circleci/defaults.sh +++ b/.circleci/defaults.sh @@ -47,23 +47,25 @@ LOCAL_FIRESIM_DIR=$LOCAL_CHIPYARD_DIR/sims/firesim/sim # key value store to get the build strings declare -A mapping -mapping["chipyard-rocket"]="SUB_PROJECT=chipyard" -mapping["chipyard-sha3"]="SUB_PROJECT=chipyard CONFIG=Sha3RocketConfig" -mapping["chipyard-streaming-fir"]="SUB_PROJECT=chipyard CONFIG=StreamingFIRRocketConfig" -mapping["chipyard-streaming-passthrough"]="SUB_PROJECT=chipyard CONFIG=StreamingPassthroughRocketConfig" -mapping["chipyard-hetero"]="SUB_PROJECT=chipyard CONFIG=LargeBoomAndRocketConfig" -mapping["chipyard-boom"]="SUB_PROJECT=chipyard CONFIG=SmallBoomConfig" -mapping["chipyard-blkdev"]="SUB_PROJECT=chipyard CONFIG=SimBlockDeviceRocketConfig" -mapping["chipyard-hwacha"]="SUB_PROJECT=chipyard CONFIG=HwachaRocketConfig" -mapping["chipyard-gemmini"]="SUB_PROJECT=chipyard CONFIG=GemminiRocketConfig" -mapping["chipyard-ariane"]="SUB_PROJECT=chipyard CONFIG=ArianeConfig" -mapping["chipyard-spiflashread"]="SUB_PROJECT=chipyard CONFIG=LargeSPIFlashROMRocketConfig" -mapping["chipyard-spiflashwrite"]="SUB_PROJECT=chipyard CONFIG=SmallSPIFlashRocketConfig" -mapping["tracegen"]="SUB_PROJECT=chipyard CONFIG=NonBlockingTraceGenL2Config TOP=TraceGenSystem" -mapping["tracegen-boom"]="SUB_PROJECT=chipyard CONFIG=BoomTraceGenConfig TOP=TraceGenSystem" -mapping["chipyard-nvdla"]="SUB_PROJECT=chipyard CONFIG=SmallNVDLARocketConfig" +mapping["chipyard-rocket"]="" +mapping["chipyard-sha3"]=" CONFIG=Sha3RocketConfig" +mapping["chipyard-streaming-fir"]=" CONFIG=StreamingFIRRocketConfig" +mapping["chipyard-streaming-passthrough"]=" CONFIG=StreamingPassthroughRocketConfig" +mapping["chipyard-hetero"]=" CONFIG=LargeBoomAndRocketConfig" +mapping["chipyard-boom"]=" CONFIG=SmallBoomConfig" +mapping["chipyard-blkdev"]=" CONFIG=SimBlockDeviceRocketConfig" +mapping["chipyard-hwacha"]=" CONFIG=HwachaRocketConfig" +mapping["chipyard-gemmini"]=" CONFIG=GemminiRocketConfig" +mapping["chipyard-ariane"]=" CONFIG=ArianeConfig" +mapping["chipyard-spiflashread"]=" CONFIG=LargeSPIFlashROMRocketConfig" +mapping["chipyard-spiflashwrite"]=" CONFIG=SmallSPIFlashRocketConfig" +mapping["chipyard-mmios"]=" CONFIG=MMIORocketConfig verilog" +mapping["tracegen"]=" CONFIG=NonBlockingTraceGenL2Config TOP=TraceGenSystem" +mapping["tracegen-boom"]=" CONFIG=BoomTraceGenConfig TOP=TraceGenSystem" +mapping["chipyard-nvdla"]=" CONFIG=SmallNVDLARocketConfig" mapping["firesim"]="SCALA_TEST=firesim.firesim.RocketNICF1Tests" mapping["firesim-multiclock"]="SCALA_TEST=firesim.firesim.RocketMulticlockF1Tests" mapping["fireboom"]="SCALA_TEST=firesim.firesim.BoomF1Tests" mapping["icenet"]="SUB_PROJECT=icenet" mapping["testchipip"]="SUB_PROJECT=testchipip" + diff --git a/generators/chipyard/src/main/scala/ChipTop.scala b/generators/chipyard/src/main/scala/ChipTop.scala index d0b4df02..ea0c804d 100644 --- a/generators/chipyard/src/main/scala/ChipTop.scala +++ b/generators/chipyard/src/main/scala/ChipTop.scala @@ -70,12 +70,13 @@ abstract class BaseChipTop()(implicit val p: Parameters) extends RawModule with val lSystem = p(BuildSystem)(p).suggestName("system") val system = withClockAndReset(systemClock, systemReset) { Module(lSystem.module) } + // Call all of the IOBinders and provide them with a default clock and reset withClockAndReset(systemClock, systemReset) { // Call each IOBinder on both the lazyModule instance and the module // instance. Generally, an IOBinder PF should only be defined on one, so // this should not lead to two invocations. - val (_ports, _iocells, _harnessFunctions) = p(IOBinders).values.flatMap(f => f(lSystem) ++ f(system)).unzip3 + val (_ports, _iocells, _harnessFunctions) = p(IOBinders).values.flatMap(f => f(lSystem, p) ++ f(system, p)).unzip3 // We ignore _ports for now... iocells ++= _iocells.flatten harnessFunctions ++= _harnessFunctions.flatten diff --git a/generators/chipyard/src/main/scala/IOBinders.scala b/generators/chipyard/src/main/scala/IOBinders.scala index 1a366d19..2b7cd41c 100644 --- a/generators/chipyard/src/main/scala/IOBinders.scala +++ b/generators/chipyard/src/main/scala/IOBinders.scala @@ -9,7 +9,7 @@ import freechips.rocketchip.diplomacy.{LazyModule} import freechips.rocketchip.devices.debug._ import freechips.rocketchip.subsystem._ import freechips.rocketchip.system.{SimAXIMem} -import freechips.rocketchip.amba.axi4.{AXI4Bundle, AXI4SlaveNode, AXI4EdgeParameters} +import freechips.rocketchip.amba.axi4.{AXI4Bundle, AXI4SlaveNode, AXI4MasterNode, AXI4EdgeParameters} import freechips.rocketchip.util._ import freechips.rocketchip.groundtest.{GroundTestSubsystemModuleImp, GroundTestSubsystem} @@ -48,17 +48,17 @@ type TestHarnessFunction = (chipyard.TestHarness) => Seq[Any] // 3. An optional function to call inside the test harness (e.g. to connect the IOs) type IOBinderTuple = (Seq[Data], Seq[IOCell], Option[TestHarnessFunction]) -case object IOBinders extends Field[Map[String, (Any) => Seq[IOBinderTuple]]]( - Map[String, (Any) => Seq[IOBinderTuple]]().withDefaultValue((Any) => Nil) +case object IOBinders extends Field[Map[String, (Any, Parameters) => Seq[IOBinderTuple]]]( + Map[String, (Any, Parameters) => Seq[IOBinderTuple]]().withDefaultValue((Any, Parameters) => Nil) ) // This macro overrides previous matches on some Top mixin. This is useful for // binders which drive IO, since those typically cannot be composed -class OverrideIOBinder[T](fn: => (T) => Seq[IOBinderTuple])(implicit tag: ClassTag[T]) extends Config((site, here, up) => { +class OverrideIOBinder[T](fn: => (T, Parameters) => Seq[IOBinderTuple])(implicit tag: ClassTag[T]) extends Config((site, here, up) => { case IOBinders => up(IOBinders, site) + (tag.runtimeClass.toString -> - ((t: Any) => { + ((t: Any, p: Parameters) => { t match { - case system: T => fn(system) + case system: T => fn(system, p) case _ => Nil } }) @@ -67,12 +67,12 @@ class OverrideIOBinder[T](fn: => (T) => Seq[IOBinderTuple])(implicit tag: ClassT // This macro composes with previous matches on some Top mixin. This is useful for // annotation-like binders, since those can typically be composed -class ComposeIOBinder[T](fn: => (T) => Seq[IOBinderTuple])(implicit tag: ClassTag[T]) extends Config((site, here, up) => { +class ComposeIOBinder[T](fn: => (T, Parameters) => Seq[IOBinderTuple])(implicit tag: ClassTag[T]) extends Config((site, here, up) => { case IOBinders => up(IOBinders, site) + (tag.runtimeClass.toString -> - ((t: Any) => { + ((t: Any, p: Parameters) => { t match { - case system: T => (up(IOBinders, site)(tag.runtimeClass.toString)(system) - ++ fn(system)) + case system: T => (up(IOBinders, site)(tag.runtimeClass.toString)(system, p) + ++ fn(system, p)) case _ => Nil } }) @@ -185,10 +185,19 @@ object AddIOCells { (port, ios) } - def axi4(io: Seq[AXI4Bundle], node: AXI4SlaveNode): Seq[(AXI4Bundle, AXI4EdgeParameters, Seq[IOCell])] = { + def axi4(io: Seq[AXI4Bundle], node: AXI4SlaveNode, name: String): Seq[(AXI4Bundle, AXI4EdgeParameters, Seq[IOCell])] = { io.zip(node.in).zipWithIndex.map{ case ((mem_axi4, (_, edge)), i) => { - val (port, ios) = IOCell.generateIOFromSignal(mem_axi4, Some(s"iocell_mem_axi4_${i}")) - port.suggestName(s"mem_axi4_${i}") + val (port, ios) = IOCell.generateIOFromSignal(mem_axi4, Some(s"iocell_${name}_axi4_slave_${i}")) + port.suggestName(s"${name}_axi4_slave_${i}") + (port, edge, ios) + }} + } + def axi4(io: Seq[AXI4Bundle], node: AXI4MasterNode, name: String): Seq[(AXI4Bundle, AXI4EdgeParameters, Seq[IOCell])] = { + io.zip(node.out).zipWithIndex.map{ case ((mem_axi4, (_, edge)), i) => { + //val (port, ios) = IOCell.generateIOFromSignal(mem_axi4, Some(s"iocell_${name}_axi4_master_${i}")) + val port = IO(Flipped(AXI4Bundle(edge.bundle))) + val ios = IOCell.generateFromSignal(mem_axi4, port, Some(s"iocell_${name}_axi4_master_${i}")) + port.suggestName(s"${name}_axi4_master_${i}") (port, edge, ios) }} } @@ -202,7 +211,7 @@ object AddIOCells { // DOC include start: WithGPIOTiedOff class WithGPIOTiedOff extends OverrideIOBinder({ - (system: HasPeripheryGPIOModuleImp) => { + (system: HasPeripheryGPIOModuleImp, p) => { val (ports2d, ioCells2d) = AddIOCells.gpio(system.gpio) val harnessFn = (th: chipyard.TestHarness) => { ports2d.flatten.foreach(_ <> AnalogConst(0)); Nil } Seq((ports2d.flatten, ioCells2d.flatten, Some(harnessFn))) @@ -211,7 +220,7 @@ class WithGPIOTiedOff extends OverrideIOBinder({ // DOC include end: WithGPIOTiedOff class WithUARTAdapter extends OverrideIOBinder({ - (system: HasPeripheryUARTModuleImp) => { + (system: HasPeripheryUARTModuleImp, p) => { val (ports, ioCells2d) = AddIOCells.uart(system.uart) val harnessFn = (th: chipyard.TestHarness) => { UARTAdapter.connect(ports)(system.p); Nil } Seq((ports, ioCells2d.flatten, Some(harnessFn))) @@ -219,7 +228,7 @@ class WithUARTAdapter extends OverrideIOBinder({ }) class WithSimSPIFlashModel(rdOnly: Boolean = true) extends OverrideIOBinder({ - (system: HasPeripherySPIFlashModuleImp) => { + (system: HasPeripherySPIFlashModuleImp, p) => { val (ports, ioCells2d) = AddIOCells.spi(system.qspi, "qspi") val harnessFn = (th: chipyard.TestHarness) => { SimSPIFlashModel.connect(ports, th.reset, rdOnly)(system.p); Nil } Seq((ports, ioCells2d.flatten, Some(harnessFn))) @@ -227,7 +236,7 @@ class WithSimSPIFlashModel(rdOnly: Boolean = true) extends OverrideIOBinder({ }) class WithSimBlockDevice extends OverrideIOBinder({ - (system: CanHavePeripheryBlockDeviceModuleImp) => system.bdev.map { bdev => + (system: CanHavePeripheryBlockDeviceModuleImp, p) => system.bdev.map { bdev => val (port, ios) = AddIOCells.blockDev(bdev) val harnessFn = (th: chipyard.TestHarness) => { SimBlockDevice.connect(th.clock, th.reset.asBool, Some(port))(system.p) @@ -238,7 +247,7 @@ class WithSimBlockDevice extends OverrideIOBinder({ }) class WithBlockDeviceModel extends OverrideIOBinder({ - (system: CanHavePeripheryBlockDeviceModuleImp) => system.bdev.map { bdev => + (system: CanHavePeripheryBlockDeviceModuleImp, p) => system.bdev.map { bdev => val (port, ios) = AddIOCells.blockDev(bdev) val harnessFn = (th: chipyard.TestHarness) => { BlockDeviceModel.connect(Some(port))(system.p) @@ -249,11 +258,11 @@ class WithBlockDeviceModel extends OverrideIOBinder({ }) class WithLoopbackNIC extends OverrideIOBinder({ - (system: CanHavePeripheryIceNICModuleImp) => system.connectNicLoopback(); Nil + (system: CanHavePeripheryIceNICModuleImp, p) => system.connectNicLoopback(); Nil }) class WithSimNIC extends OverrideIOBinder({ - (system: CanHavePeripheryIceNICModuleImp) => system.connectSimNetwork(system.clock, system.reset.asBool); Nil + (system: CanHavePeripheryIceNICModuleImp, p) => system.connectSimNetwork(system.clock, system.reset.asBool); Nil }) // Note: The parameters instance is accessible only through the BaseSubsystem @@ -262,16 +271,16 @@ class WithSimNIC extends OverrideIOBinder({ // accessible to the IOBinder // DOC include start: WithSimAXIMem class WithSimAXIMem extends OverrideIOBinder({ - (system: CanHaveMasterAXI4MemPort with BaseSubsystem) => { - val peiTuples = AddIOCells.axi4(system.mem_axi4, system.memAXI4Node) + (system: CanHaveMasterAXI4MemPort, p) => { + val peiTuples = AddIOCells.axi4(system.mem_axi4, system.memAXI4Node, "mem") // TODO: we are inlining the connectMem method of SimAXIMem because // it takes in a dut rather than seq of axi4 ports val harnessFn = (th: chipyard.TestHarness) => { peiTuples.map { case (port, edge, ios) => - val mem = LazyModule(new SimAXIMem(edge, size = system.p(ExtMem).get.master.size)(system.p)) + val mem = LazyModule(new SimAXIMem(edge, size = p(ExtMem).get.master.size)(p)) Module(mem.module).suggestName("mem") mem.io_axi4.head <> port - } + } Nil } Seq((peiTuples.map(_._1), peiTuples.flatMap(_._3), Some(harnessFn))) @@ -280,12 +289,12 @@ class WithSimAXIMem extends OverrideIOBinder({ // DOC include end: WithSimAXIMem class WithBlackBoxSimMem extends OverrideIOBinder({ - (system: CanHaveMasterAXI4MemPort with BaseSubsystem) => { - val peiTuples = AddIOCells.axi4(system.mem_axi4, system.memAXI4Node) + (system: CanHaveMasterAXI4MemPort, p) => { + val peiTuples = AddIOCells.axi4(system.mem_axi4, system.memAXI4Node, "mem") val harnessFn = (th: chipyard.TestHarness) => { peiTuples.map { case (port, edge, ios) => - val memSize = system.p(ExtMem).get.master.size - val lineSize = system.p(CacheBlockBytes) + val memSize = p(ExtMem).get.master.size + val lineSize = p(CacheBlockBytes) val mem = Module(new SimDRAM(memSize, lineSize, edge.bundle)) mem.io.axi <> port mem.io.clock := th.clock @@ -298,15 +307,26 @@ class WithBlackBoxSimMem extends OverrideIOBinder({ }) class WithSimAXIMMIO extends OverrideIOBinder({ - (system: CanHaveMasterAXI4MMIOPort with BaseSubsystem) => SimAXIMem.connectMMIO(system)(system.p); Nil + (system: CanHaveMasterAXI4MMIOPort, p) => { + val peiTuples = AddIOCells.axi4(system.mmio_axi4, system.mmioAXI4Node, "mmio_mem") + val harnessFn = (th: chipyard.TestHarness) => { + peiTuples.zipWithIndex.map { case ((port, edge, ios), i) => + val mmio_mem = LazyModule(new SimAXIMem(edge, size = 4096)(p)) + Module(mmio_mem.module).suggestName(s"mmio_mem_${i}") + mmio_mem.io_axi4.head <> port + } + Nil + } + Seq((peiTuples.map(_._1), peiTuples.flatMap(_._3), Some(harnessFn))) + } }) class WithDontTouchPorts extends OverrideIOBinder({ - (system: DontTouch) => system.dontTouchPorts(); Nil + (system: DontTouch, p) => system.dontTouchPorts(); Nil }) class WithTieOffInterrupts extends OverrideIOBinder({ - (system: HasExtInterruptsModuleImp) => { + (system: HasExtInterruptsModuleImp, p) => { val (port, ioCells) = IOCell.generateIOFromSignal(system.interrupts, Some("iocell_interrupts")) port.suggestName("interrupts") val harnessFn = (th: chipyard.TestHarness) => { port := 0.U; Nil } @@ -315,26 +335,21 @@ class WithTieOffInterrupts extends OverrideIOBinder({ }) class WithTieOffL2FBusAXI extends OverrideIOBinder({ - (system: CanHaveSlaveAXI4Port with BaseSubsystem) => { - system.l2_frontend_bus_axi4.foreach(axi => { - axi.tieoff() - experimental.DataMirror.directionOf(axi.ar.ready) match { - case ActualDirection.Input => - axi.r.bits := DontCare - axi.b.bits := DontCare - case ActualDirection.Output => - axi.aw.bits := DontCare - axi.ar.bits := DontCare - axi.w.bits := DontCare - case _ => throw new Exception("Unknown AXI port direction") + (system: CanHaveSlaveAXI4Port, p) => { + val peiTuples = AddIOCells.axi4(system.l2_frontend_bus_axi4, system.l2FrontendAXI4Node, "l2_fbus") + val harnessFn = (th: chipyard.TestHarness) => { + peiTuples.zipWithIndex.map { case ((port, edge, ios), i) => + port := DontCare // tieoff doesn't completely tie-off, for some reason + port.tieoff() } - }) - Nil + Nil + } + Seq((peiTuples.map(_._1), peiTuples.flatMap(_._3), Some(harnessFn))) } }) class WithTiedOffDebug extends OverrideIOBinder({ - (system: HasPeripheryDebugModuleImp) => { + (system: HasPeripheryDebugModuleImp, p) => { val (psdPort, resetctrlOpt, debugPortOpt, ioCells) = AddIOCells.debug(system.psd, system.resetctrl, system.debug)(system.p) val harnessFn = (th: chipyard.TestHarness) => { @@ -352,7 +367,7 @@ class WithTiedOffDebug extends OverrideIOBinder({ }) class WithSimDebug extends OverrideIOBinder({ - (system: HasPeripheryDebugModuleImp) => { + (system: HasPeripheryDebugModuleImp, p) => { val (psdPort, resetctrlPortOpt, debugPortOpt, ioCells) = AddIOCells.debug(system.psd, system.resetctrl, system.debug)(system.p) val harnessFn = (th: chipyard.TestHarness) => { @@ -367,7 +382,7 @@ class WithSimDebug extends OverrideIOBinder({ }) class WithTiedOffSerial extends OverrideIOBinder({ - (system: CanHavePeripherySerialModuleImp) => system.serial.map({ serial => + (system: CanHavePeripherySerialModuleImp, p) => system.serial.map({ serial => val (port, ioCells) = AddIOCells.serial(serial) val harnessFn = (th: chipyard.TestHarness) => { SerialAdapter.tieoff(port) @@ -378,7 +393,7 @@ class WithTiedOffSerial extends OverrideIOBinder({ }) class WithSimSerial extends OverrideIOBinder({ - (system: CanHavePeripherySerialModuleImp) => system.serial.map({ serial => + (system: CanHavePeripherySerialModuleImp, p) => system.serial.map({ serial => val (port, ioCells) = AddIOCells.serial(serial) val harnessFn = (th: chipyard.TestHarness) => { val ser_success = SerialAdapter.connectSimSerial(port, th.clock, th.harnessReset) @@ -390,7 +405,7 @@ class WithSimSerial extends OverrideIOBinder({ }) class WithTraceGenSuccessBinder extends OverrideIOBinder({ - (system: TraceGenSystemModuleImp) => { + (system: TraceGenSystemModuleImp, p) => { val (successPort, ioCells) = IOCell.generateIOFromSignal(system.success, Some("iocell_success")) successPort.suggestName("success") val harnessFn = (th: chipyard.TestHarness) => { when (successPort) { th.success := true.B }; Nil } @@ -399,7 +414,7 @@ class WithTraceGenSuccessBinder extends OverrideIOBinder({ }) class WithSimDromajoBridge extends ComposeIOBinder({ - (system: CanHaveTraceIOModuleImp) => { + (system: CanHaveTraceIOModuleImp, p) => { system.traceIO match { case Some(t) => t.traces.map(tileTrace => SimDromajoBridge(tileTrace)(system.p)) } Nil } diff --git a/generators/chipyard/src/main/scala/config/RocketConfigs.scala b/generators/chipyard/src/main/scala/config/RocketConfigs.scala index 06257c7b..3dc7d22d 100644 --- a/generators/chipyard/src/main/scala/config/RocketConfigs.scala +++ b/generators/chipyard/src/main/scala/config/RocketConfigs.scala @@ -542,3 +542,21 @@ class LargeNVDLARocketConfig extends Config( new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ new freechips.rocketchip.system.BaseConfig) + +class MMIORocketConfig extends Config( + new chipyard.iobinders.WithUARTAdapter ++ + new chipyard.iobinders.WithTieOffInterrupts ++ + new chipyard.iobinders.WithBlackBoxSimMem ++ + new chipyard.iobinders.WithTiedOffDebug ++ + new chipyard.iobinders.WithSimSerial ++ + new chipyard.iobinders.WithTieOffL2FBusAXI ++ // Tie-off the incoming MMIO port + new chipyard.iobinders.WithSimAXIMMIO ++ // Attach a simulated memory to the outwards MMIO port + new testchipip.WithTSI ++ + new chipyard.config.WithBootROM ++ + new chipyard.config.WithUART ++ + new chipyard.config.WithL2TLBs(1024) ++ + new freechips.rocketchip.subsystem.WithInclusiveCache ++ + new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ + new freechips.rocketchip.subsystem.WithNBigCores(1) ++ + new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ + new freechips.rocketchip.system.BaseConfig) diff --git a/generators/firechip/src/main/scala/BridgeBinders.scala b/generators/firechip/src/main/scala/BridgeBinders.scala index eeb19559..6af7bd0a 100644 --- a/generators/firechip/src/main/scala/BridgeBinders.scala +++ b/generators/firechip/src/main/scala/BridgeBinders.scala @@ -35,29 +35,28 @@ object MainMemoryConsts { } class WithSerialBridge extends OverrideIOBinder({ - (system: CanHavePeripherySerialModuleImp) => - system.serial.foreach(s => SerialBridge(system.clock, s, MainMemoryConsts.globalName)(system.p)); Nil + (system: CanHavePeripherySerialModuleImp, p) => + system.serial.foreach(s => SerialBridge(system.clock, s, MainMemoryConsts.globalName)(p)); Nil }) class WithNICBridge extends OverrideIOBinder({ - (system: CanHavePeripheryIceNICModuleImp) => - system.net.foreach(n => NICBridge(system.clock, n)(system.p)); Nil + (system: CanHavePeripheryIceNICModuleImp, p) => + system.net.foreach(n => NICBridge(system.clock, n)(p)); Nil }) class WithUARTBridge extends OverrideIOBinder({ - (system: HasPeripheryUARTModuleImp) => - system.uart.foreach(u => UARTBridge(system.clock, u)(system.p)); Nil + (system: HasPeripheryUARTModuleImp, p) => + system.uart.foreach(u => UARTBridge(system.clock, u)(p)); Nil }) class WithBlockDeviceBridge extends OverrideIOBinder({ - (system: CanHavePeripheryBlockDeviceModuleImp) => - system.bdev.foreach(b => BlockDevBridge(system.clock, b, system.reset.toBool)(system.p)); Nil + (system: CanHavePeripheryBlockDeviceModuleImp, p) => + system.bdev.foreach(b => BlockDevBridge(system.clock, b, system.reset.toBool)(p)); Nil }) class WithFASEDBridge extends OverrideIOBinder({ - (system: CanHaveMasterAXI4MemPort with BaseSubsystem) => { - implicit val p = system.p + (system: CanHaveMasterAXI4MemPort, p) => { (system.mem_axi4 zip system.memAXI4Node.in).foreach({ case (axi4, (_, edge)) => val nastiKey = NastiParameters(axi4.r.bits.data.getWidth, axi4.ar.bits.addr.getWidth, @@ -73,26 +72,26 @@ class WithFASEDBridge extends OverrideIOBinder({ }) class WithTracerVBridge extends ComposeIOBinder({ - (system: CanHaveTraceIOModuleImp) => - system.traceIO.foreach(_.traces.map(tileTrace => TracerVBridge(tileTrace)(system.p))); Nil + (system: CanHaveTraceIOModuleImp, p) => + system.traceIO.foreach(_.traces.map(tileTrace => TracerVBridge(tileTrace)(p))); Nil }) class WithDromajoBridge extends ComposeIOBinder({ - (system: CanHaveTraceIOModuleImp) => { - system.traceIO.foreach(_.traces.map(tileTrace => DromajoBridge(tileTrace)(system.p))); Nil + (system: CanHaveTraceIOModuleImp, p) => { + system.traceIO.foreach(_.traces.map(tileTrace => DromajoBridge(tileTrace)(p))); Nil } }) class WithTraceGenBridge extends OverrideIOBinder({ - (system: TraceGenSystemModuleImp) => + (system: TraceGenSystemModuleImp, p) => GroundTestBridge(system.clock, system.success)(system.p); Nil }) class WithFireSimMultiCycleRegfile extends ComposeIOBinder({ - (system: HasTilesModuleImp) => { + (system: HasTilesModuleImp, p) => { system.outer.tiles.map { case r: RocketTile => { annotate(MemModelAnnotation(r.module.core.rocketImpl.rf.rf)) @@ -116,13 +115,13 @@ class WithFireSimMultiCycleRegfile extends ComposeIOBinder({ }) class WithTiedOffSystemGPIO extends OverrideIOBinder({ - (system: HasPeripheryGPIOModuleImp) => + (system: HasPeripheryGPIOModuleImp, p) => system.gpio.foreach(_.pins.foreach(_.i.ival := false.B)); Nil }) class WithTiedOffSystemDebug extends OverrideIOBinder({ - (system: HasPeripheryDebugModuleImp) => { - Debug.tieoffDebug(system.debug, system.resetctrl, Some(system.psd))(system.p) + (system: HasPeripheryDebugModuleImp, p) => { + Debug.tieoffDebug(system.debug, system.resetctrl, Some(system.psd))(p) // tieoffDebug doesn't actually tie everything off :/ system.debug.foreach { d => d.clockeddmi.foreach({ cdmi => cdmi.dmi.req.bits := DontCare }) @@ -133,7 +132,7 @@ class WithTiedOffSystemDebug extends OverrideIOBinder({ }) class WithTiedOffSystemInterrupts extends OverrideIOBinder({ - (system: HasExtInterruptsModuleImp) => + (system: HasExtInterruptsModuleImp, p) => system.interrupts := 0.U; Nil }) diff --git a/tools/barstools b/tools/barstools index 7e6e19b8..aa1c90c4 160000 --- a/tools/barstools +++ b/tools/barstools @@ -1 +1 @@ -Subproject commit 7e6e19b8adf3b625b31b09173ecae5f634c83e1b +Subproject commit aa1c90c4ccb73c2c379550f3296892cc81e8a195 From a7047c4ba2e7b9c4a2433a3e8ff0346bc3a67ab5 Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Wed, 1 Jul 2020 12:21:51 -0700 Subject: [PATCH 23/27] Fix FireChip BridgeBinders --- .../chipyard/src/main/scala/ChipTop.scala | 3 +- .../chipyard/src/main/scala/IOBinders.scala | 84 +++++++++++-------- .../src/main/scala/BridgeBinders.scala | 54 ++++++------ 3 files changed, 79 insertions(+), 62 deletions(-) diff --git a/generators/chipyard/src/main/scala/ChipTop.scala b/generators/chipyard/src/main/scala/ChipTop.scala index ea0c804d..d0b4df02 100644 --- a/generators/chipyard/src/main/scala/ChipTop.scala +++ b/generators/chipyard/src/main/scala/ChipTop.scala @@ -70,13 +70,12 @@ abstract class BaseChipTop()(implicit val p: Parameters) extends RawModule with val lSystem = p(BuildSystem)(p).suggestName("system") val system = withClockAndReset(systemClock, systemReset) { Module(lSystem.module) } - // Call all of the IOBinders and provide them with a default clock and reset withClockAndReset(systemClock, systemReset) { // Call each IOBinder on both the lazyModule instance and the module // instance. Generally, an IOBinder PF should only be defined on one, so // this should not lead to two invocations. - val (_ports, _iocells, _harnessFunctions) = p(IOBinders).values.flatMap(f => f(lSystem, p) ++ f(system, p)).unzip3 + val (_ports, _iocells, _harnessFunctions) = p(IOBinders).values.flatMap(f => f(lSystem) ++ f(system)).unzip3 // We ignore _ports for now... iocells ++= _iocells.flatten harnessFunctions ++= _harnessFunctions.flatten diff --git a/generators/chipyard/src/main/scala/IOBinders.scala b/generators/chipyard/src/main/scala/IOBinders.scala index 2b7cd41c..115723ab 100644 --- a/generators/chipyard/src/main/scala/IOBinders.scala +++ b/generators/chipyard/src/main/scala/IOBinders.scala @@ -5,7 +5,7 @@ import chisel3._ import chisel3.experimental.{Analog, IO} import freechips.rocketchip.config.{Field, Config, Parameters} -import freechips.rocketchip.diplomacy.{LazyModule} +import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImpLike} import freechips.rocketchip.devices.debug._ import freechips.rocketchip.subsystem._ import freechips.rocketchip.system.{SimAXIMem} @@ -48,17 +48,32 @@ type TestHarnessFunction = (chipyard.TestHarness) => Seq[Any] // 3. An optional function to call inside the test harness (e.g. to connect the IOs) type IOBinderTuple = (Seq[Data], Seq[IOCell], Option[TestHarnessFunction]) -case object IOBinders extends Field[Map[String, (Any, Parameters) => Seq[IOBinderTuple]]]( - Map[String, (Any, Parameters) => Seq[IOBinderTuple]]().withDefaultValue((Any, Parameters) => Nil) +case object IOBinders extends Field[Map[String, (Any) => Seq[IOBinderTuple]]]( + Map[String, (Any) => Seq[IOBinderTuple]]().withDefaultValue((Any) => Nil) ) +// Note: The parameters instance is accessible only through LazyModule +// or LazyModuleImpLike. The self-type requirement in traits like +// CanHaveMasterAXI4MemPort is insufficient to make it accessible to the IOBinder +// As a result, IOBinders only work on Modules which inherit LazyModule or +// or LazyModuleImpLike +object GetSystemParameters { + def apply(s: Any): Parameters = { + s match { + case s: LazyModule => s.p + case s: LazyModuleImpLike => s.p + case _ => throw new Exception(s"Trying to get Parameters from a system that is not LazyModule or LazyModuleImpLike") + } + } +} + // This macro overrides previous matches on some Top mixin. This is useful for // binders which drive IO, since those typically cannot be composed -class OverrideIOBinder[T](fn: => (T, Parameters) => Seq[IOBinderTuple])(implicit tag: ClassTag[T]) extends Config((site, here, up) => { +class OverrideIOBinder[T](fn: => (T) => Seq[IOBinderTuple])(implicit tag: ClassTag[T]) extends Config((site, here, up) => { case IOBinders => up(IOBinders, site) + (tag.runtimeClass.toString -> - ((t: Any, p: Parameters) => { + ((t: Any) => { t match { - case system: T => fn(system, p) + case system: T => fn(system) case _ => Nil } }) @@ -67,12 +82,12 @@ class OverrideIOBinder[T](fn: => (T, Parameters) => Seq[IOBinderTuple])(implicit // This macro composes with previous matches on some Top mixin. This is useful for // annotation-like binders, since those can typically be composed -class ComposeIOBinder[T](fn: => (T, Parameters) => Seq[IOBinderTuple])(implicit tag: ClassTag[T]) extends Config((site, here, up) => { +class ComposeIOBinder[T](fn: => (T) => Seq[IOBinderTuple])(implicit tag: ClassTag[T]) extends Config((site, here, up) => { case IOBinders => up(IOBinders, site) + (tag.runtimeClass.toString -> - ((t: Any, p: Parameters) => { + ((t: Any) => { t match { - case system: T => (up(IOBinders, site)(tag.runtimeClass.toString)(system, p) - ++ fn(system, p)) + case system: T => (up(IOBinders, site)(tag.runtimeClass.toString)(system) + ++ fn(system)) case _ => Nil } }) @@ -211,7 +226,7 @@ object AddIOCells { // DOC include start: WithGPIOTiedOff class WithGPIOTiedOff extends OverrideIOBinder({ - (system: HasPeripheryGPIOModuleImp, p) => { + (system: HasPeripheryGPIOModuleImp) => { val (ports2d, ioCells2d) = AddIOCells.gpio(system.gpio) val harnessFn = (th: chipyard.TestHarness) => { ports2d.flatten.foreach(_ <> AnalogConst(0)); Nil } Seq((ports2d.flatten, ioCells2d.flatten, Some(harnessFn))) @@ -220,7 +235,7 @@ class WithGPIOTiedOff extends OverrideIOBinder({ // DOC include end: WithGPIOTiedOff class WithUARTAdapter extends OverrideIOBinder({ - (system: HasPeripheryUARTModuleImp, p) => { + (system: HasPeripheryUARTModuleImp) => { val (ports, ioCells2d) = AddIOCells.uart(system.uart) val harnessFn = (th: chipyard.TestHarness) => { UARTAdapter.connect(ports)(system.p); Nil } Seq((ports, ioCells2d.flatten, Some(harnessFn))) @@ -228,7 +243,7 @@ class WithUARTAdapter extends OverrideIOBinder({ }) class WithSimSPIFlashModel(rdOnly: Boolean = true) extends OverrideIOBinder({ - (system: HasPeripherySPIFlashModuleImp, p) => { + (system: HasPeripherySPIFlashModuleImp) => { val (ports, ioCells2d) = AddIOCells.spi(system.qspi, "qspi") val harnessFn = (th: chipyard.TestHarness) => { SimSPIFlashModel.connect(ports, th.reset, rdOnly)(system.p); Nil } Seq((ports, ioCells2d.flatten, Some(harnessFn))) @@ -236,7 +251,7 @@ class WithSimSPIFlashModel(rdOnly: Boolean = true) extends OverrideIOBinder({ }) class WithSimBlockDevice extends OverrideIOBinder({ - (system: CanHavePeripheryBlockDeviceModuleImp, p) => system.bdev.map { bdev => + (system: CanHavePeripheryBlockDeviceModuleImp) => system.bdev.map { bdev => val (port, ios) = AddIOCells.blockDev(bdev) val harnessFn = (th: chipyard.TestHarness) => { SimBlockDevice.connect(th.clock, th.reset.asBool, Some(port))(system.p) @@ -247,7 +262,7 @@ class WithSimBlockDevice extends OverrideIOBinder({ }) class WithBlockDeviceModel extends OverrideIOBinder({ - (system: CanHavePeripheryBlockDeviceModuleImp, p) => system.bdev.map { bdev => + (system: CanHavePeripheryBlockDeviceModuleImp) => system.bdev.map { bdev => val (port, ios) = AddIOCells.blockDev(bdev) val harnessFn = (th: chipyard.TestHarness) => { BlockDeviceModel.connect(Some(port))(system.p) @@ -258,26 +273,23 @@ class WithBlockDeviceModel extends OverrideIOBinder({ }) class WithLoopbackNIC extends OverrideIOBinder({ - (system: CanHavePeripheryIceNICModuleImp, p) => system.connectNicLoopback(); Nil + (system: CanHavePeripheryIceNICModuleImp) => system.connectNicLoopback(); Nil }) class WithSimNIC extends OverrideIOBinder({ - (system: CanHavePeripheryIceNICModuleImp, p) => system.connectSimNetwork(system.clock, system.reset.asBool); Nil + (system: CanHavePeripheryIceNICModuleImp) => system.connectSimNetwork(system.clock, system.reset.asBool); Nil }) -// Note: The parameters instance is accessible only through the BaseSubsystem -// or some parent class (IsAttachable, BareSubsystem -> LazyModule). The -// self-type requirement in CanHaveMasterAXI4MemPort is insufficient to make it -// accessible to the IOBinder // DOC include start: WithSimAXIMem class WithSimAXIMem extends OverrideIOBinder({ - (system: CanHaveMasterAXI4MemPort, p) => { + (system: CanHaveMasterAXI4MemPort) => { + implicit val p: Parameters = GetSystemParameters(system) val peiTuples = AddIOCells.axi4(system.mem_axi4, system.memAXI4Node, "mem") // TODO: we are inlining the connectMem method of SimAXIMem because // it takes in a dut rather than seq of axi4 ports val harnessFn = (th: chipyard.TestHarness) => { peiTuples.map { case (port, edge, ios) => - val mem = LazyModule(new SimAXIMem(edge, size = p(ExtMem).get.master.size)(p)) + val mem = LazyModule(new SimAXIMem(edge, size = p(ExtMem).get.master.size)) Module(mem.module).suggestName("mem") mem.io_axi4.head <> port } @@ -289,7 +301,8 @@ class WithSimAXIMem extends OverrideIOBinder({ // DOC include end: WithSimAXIMem class WithBlackBoxSimMem extends OverrideIOBinder({ - (system: CanHaveMasterAXI4MemPort, p) => { + (system: CanHaveMasterAXI4MemPort) => { + implicit val p: Parameters = GetSystemParameters(system) val peiTuples = AddIOCells.axi4(system.mem_axi4, system.memAXI4Node, "mem") val harnessFn = (th: chipyard.TestHarness) => { peiTuples.map { case (port, edge, ios) => @@ -307,11 +320,12 @@ class WithBlackBoxSimMem extends OverrideIOBinder({ }) class WithSimAXIMMIO extends OverrideIOBinder({ - (system: CanHaveMasterAXI4MMIOPort, p) => { + (system: CanHaveMasterAXI4MMIOPort) => { + implicit val p: Parameters = GetSystemParameters(system) val peiTuples = AddIOCells.axi4(system.mmio_axi4, system.mmioAXI4Node, "mmio_mem") val harnessFn = (th: chipyard.TestHarness) => { peiTuples.zipWithIndex.map { case ((port, edge, ios), i) => - val mmio_mem = LazyModule(new SimAXIMem(edge, size = 4096)(p)) + val mmio_mem = LazyModule(new SimAXIMem(edge, size = 4096)) Module(mmio_mem.module).suggestName(s"mmio_mem_${i}") mmio_mem.io_axi4.head <> port } @@ -322,11 +336,11 @@ class WithSimAXIMMIO extends OverrideIOBinder({ }) class WithDontTouchPorts extends OverrideIOBinder({ - (system: DontTouch, p) => system.dontTouchPorts(); Nil + (system: DontTouch) => system.dontTouchPorts(); Nil }) class WithTieOffInterrupts extends OverrideIOBinder({ - (system: HasExtInterruptsModuleImp, p) => { + (system: HasExtInterruptsModuleImp) => { val (port, ioCells) = IOCell.generateIOFromSignal(system.interrupts, Some("iocell_interrupts")) port.suggestName("interrupts") val harnessFn = (th: chipyard.TestHarness) => { port := 0.U; Nil } @@ -335,7 +349,7 @@ class WithTieOffInterrupts extends OverrideIOBinder({ }) class WithTieOffL2FBusAXI extends OverrideIOBinder({ - (system: CanHaveSlaveAXI4Port, p) => { + (system: CanHaveSlaveAXI4Port) => { val peiTuples = AddIOCells.axi4(system.l2_frontend_bus_axi4, system.l2FrontendAXI4Node, "l2_fbus") val harnessFn = (th: chipyard.TestHarness) => { peiTuples.zipWithIndex.map { case ((port, edge, ios), i) => @@ -349,7 +363,7 @@ class WithTieOffL2FBusAXI extends OverrideIOBinder({ }) class WithTiedOffDebug extends OverrideIOBinder({ - (system: HasPeripheryDebugModuleImp, p) => { + (system: HasPeripheryDebugModuleImp) => { val (psdPort, resetctrlOpt, debugPortOpt, ioCells) = AddIOCells.debug(system.psd, system.resetctrl, system.debug)(system.p) val harnessFn = (th: chipyard.TestHarness) => { @@ -367,7 +381,7 @@ class WithTiedOffDebug extends OverrideIOBinder({ }) class WithSimDebug extends OverrideIOBinder({ - (system: HasPeripheryDebugModuleImp, p) => { + (system: HasPeripheryDebugModuleImp) => { val (psdPort, resetctrlPortOpt, debugPortOpt, ioCells) = AddIOCells.debug(system.psd, system.resetctrl, system.debug)(system.p) val harnessFn = (th: chipyard.TestHarness) => { @@ -382,7 +396,7 @@ class WithSimDebug extends OverrideIOBinder({ }) class WithTiedOffSerial extends OverrideIOBinder({ - (system: CanHavePeripherySerialModuleImp, p) => system.serial.map({ serial => + (system: CanHavePeripherySerialModuleImp) => system.serial.map({ serial => val (port, ioCells) = AddIOCells.serial(serial) val harnessFn = (th: chipyard.TestHarness) => { SerialAdapter.tieoff(port) @@ -393,7 +407,7 @@ class WithTiedOffSerial extends OverrideIOBinder({ }) class WithSimSerial extends OverrideIOBinder({ - (system: CanHavePeripherySerialModuleImp, p) => system.serial.map({ serial => + (system: CanHavePeripherySerialModuleImp) => system.serial.map({ serial => val (port, ioCells) = AddIOCells.serial(serial) val harnessFn = (th: chipyard.TestHarness) => { val ser_success = SerialAdapter.connectSimSerial(port, th.clock, th.harnessReset) @@ -405,7 +419,7 @@ class WithSimSerial extends OverrideIOBinder({ }) class WithTraceGenSuccessBinder extends OverrideIOBinder({ - (system: TraceGenSystemModuleImp, p) => { + (system: TraceGenSystemModuleImp) => { val (successPort, ioCells) = IOCell.generateIOFromSignal(system.success, Some("iocell_success")) successPort.suggestName("success") val harnessFn = (th: chipyard.TestHarness) => { when (successPort) { th.success := true.B }; Nil } @@ -414,7 +428,7 @@ class WithTraceGenSuccessBinder extends OverrideIOBinder({ }) class WithSimDromajoBridge extends ComposeIOBinder({ - (system: CanHaveTraceIOModuleImp, p) => { + (system: CanHaveTraceIOModuleImp) => { system.traceIO match { case Some(t) => t.traces.map(tileTrace => SimDromajoBridge(tileTrace)(system.p)) } Nil } diff --git a/generators/firechip/src/main/scala/BridgeBinders.scala b/generators/firechip/src/main/scala/BridgeBinders.scala index 6af7bd0a..eba57451 100644 --- a/generators/firechip/src/main/scala/BridgeBinders.scala +++ b/generators/firechip/src/main/scala/BridgeBinders.scala @@ -26,7 +26,7 @@ import ariane.ArianeTile import boom.common.{BoomTile} -import chipyard.iobinders.{IOBinders, OverrideIOBinder, ComposeIOBinder} +import chipyard.iobinders.{IOBinders, OverrideIOBinder, ComposeIOBinder, GetSystemParameters} import testchipip.{CanHaveTraceIOModuleImp} object MainMemoryConsts { @@ -35,63 +35,67 @@ object MainMemoryConsts { } class WithSerialBridge extends OverrideIOBinder({ - (system: CanHavePeripherySerialModuleImp, p) => - system.serial.foreach(s => SerialBridge(system.clock, s, MainMemoryConsts.globalName)(p)); Nil + (system: CanHavePeripherySerialModuleImp) => + system.serial.foreach(s => SerialBridge(system.clock, s, MainMemoryConsts.globalName)(system.p)); Nil }) class WithNICBridge extends OverrideIOBinder({ - (system: CanHavePeripheryIceNICModuleImp, p) => - system.net.foreach(n => NICBridge(system.clock, n)(p)); Nil + (system: CanHavePeripheryIceNICModuleImp) => + system.net.foreach(n => NICBridge(system.clock, n)(system.p)); Nil }) class WithUARTBridge extends OverrideIOBinder({ - (system: HasPeripheryUARTModuleImp, p) => - system.uart.foreach(u => UARTBridge(system.clock, u)(p)); Nil + (system: HasPeripheryUARTModuleImp) => + system.uart.foreach(u => UARTBridge(system.clock, u)(system.p)); Nil }) class WithBlockDeviceBridge extends OverrideIOBinder({ - (system: CanHavePeripheryBlockDeviceModuleImp, p) => - system.bdev.foreach(b => BlockDevBridge(system.clock, b, system.reset.toBool)(p)); Nil + (system: CanHavePeripheryBlockDeviceModuleImp) => + system.bdev.foreach(b => BlockDevBridge(system.clock, b, system.reset.toBool)(system.p)); Nil }) class WithFASEDBridge extends OverrideIOBinder({ - (system: CanHaveMasterAXI4MemPort, p) => { + (system: CanHaveMasterAXI4MemPort) => { + implicit val p: Parameters = GetSystemParameters(system) (system.mem_axi4 zip system.memAXI4Node.in).foreach({ case (axi4, (_, edge)) => val nastiKey = NastiParameters(axi4.r.bits.data.getWidth, axi4.ar.bits.addr.getWidth, axi4.ar.bits.id.getWidth) - FASEDBridge(system.module.clock, axi4, system.module.reset.toBool, - CompleteConfig(p(firesim.configs.MemModelKey), - nastiKey, - Some(AXI4EdgeSummary(edge)), - Some(MainMemoryConsts.globalName))) + system match { + case s: BaseSubsystem => FASEDBridge(s.module.clock, axi4, s.module.reset.toBool, + CompleteConfig(p(firesim.configs.MemModelKey), + nastiKey, + Some(AXI4EdgeSummary(edge)), + Some(MainMemoryConsts.globalName))) + case _ => throw new Exception("Attempting to attach FASED Bridge to misconfigured design") + } }) Nil } }) class WithTracerVBridge extends ComposeIOBinder({ - (system: CanHaveTraceIOModuleImp, p) => - system.traceIO.foreach(_.traces.map(tileTrace => TracerVBridge(tileTrace)(p))); Nil + (system: CanHaveTraceIOModuleImp) => + system.traceIO.foreach(_.traces.map(tileTrace => TracerVBridge(tileTrace)(system.p))); Nil }) class WithDromajoBridge extends ComposeIOBinder({ - (system: CanHaveTraceIOModuleImp, p) => { - system.traceIO.foreach(_.traces.map(tileTrace => DromajoBridge(tileTrace)(p))); Nil + (system: CanHaveTraceIOModuleImp) => { + system.traceIO.foreach(_.traces.map(tileTrace => DromajoBridge(tileTrace)(system.p))); Nil } }) class WithTraceGenBridge extends OverrideIOBinder({ - (system: TraceGenSystemModuleImp, p) => + (system: TraceGenSystemModuleImp) => GroundTestBridge(system.clock, system.success)(system.p); Nil }) class WithFireSimMultiCycleRegfile extends ComposeIOBinder({ - (system: HasTilesModuleImp, p) => { + (system: HasTilesModuleImp) => { system.outer.tiles.map { case r: RocketTile => { annotate(MemModelAnnotation(r.module.core.rocketImpl.rf.rf)) @@ -115,13 +119,13 @@ class WithFireSimMultiCycleRegfile extends ComposeIOBinder({ }) class WithTiedOffSystemGPIO extends OverrideIOBinder({ - (system: HasPeripheryGPIOModuleImp, p) => + (system: HasPeripheryGPIOModuleImp) => system.gpio.foreach(_.pins.foreach(_.i.ival := false.B)); Nil }) class WithTiedOffSystemDebug extends OverrideIOBinder({ - (system: HasPeripheryDebugModuleImp, p) => { - Debug.tieoffDebug(system.debug, system.resetctrl, Some(system.psd))(p) + (system: HasPeripheryDebugModuleImp) => { + Debug.tieoffDebug(system.debug, system.resetctrl, Some(system.psd))(system.p) // tieoffDebug doesn't actually tie everything off :/ system.debug.foreach { d => d.clockeddmi.foreach({ cdmi => cdmi.dmi.req.bits := DontCare }) @@ -132,7 +136,7 @@ class WithTiedOffSystemDebug extends OverrideIOBinder({ }) class WithTiedOffSystemInterrupts extends OverrideIOBinder({ - (system: HasExtInterruptsModuleImp, p) => + (system: HasExtInterruptsModuleImp) => system.interrupts := 0.U; Nil }) From 661038f992b281b0f39ea58c45216128e476a18f Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Fri, 3 Jul 2020 16:21:30 -0700 Subject: [PATCH 24/27] Deduplicate across Chiypard configs into a ChipyardBaseConfig --- docs/Customization/Heterogeneous-SoCs.rst | 51 +- .../src/main/scala/ConfigFragments.scala | 13 + .../main/scala/config/AbstractConfig.scala | 26 + .../src/main/scala/config/ArianeConfigs.scala | 35 +- .../src/main/scala/config/BoomConfigs.scala | 141 +----- .../src/main/scala/config/HeteroConfigs.scala | 104 +--- .../src/main/scala/config/RocketConfigs.scala | 461 ++---------------- .../RocketConfigs.scala.patch | 16 +- 8 files changed, 129 insertions(+), 718 deletions(-) create mode 100644 generators/chipyard/src/main/scala/config/AbstractConfig.scala diff --git a/docs/Customization/Heterogeneous-SoCs.rst b/docs/Customization/Heterogeneous-SoCs.rst index c640e31c..155d623d 100644 --- a/docs/Customization/Heterogeneous-SoCs.rst +++ b/docs/Customization/Heterogeneous-SoCs.rst @@ -8,7 +8,7 @@ Creating a Rocket and BOOM System ------------------------------------------- Instantiating an SoC with Rocket and BOOM cores is all done with the configuration system and two specific config fragments. -Both BOOM and Rocket have config fragments labelled ``WithNBoomCores(X)`` and ``WithNBigCores(X)`` that automatically create ``X`` copies of the core/tile [1]_. +Both BOOM and Rocket have config fragments labelled ``WithN{Small|Medium|Large|etc.}BoomCores(X)`` and ``WithNBigCores(X)`` that automatically create ``X`` copies of the core/tile [1]_. When used together you can create a heterogeneous system. The following example shows a dual core BOOM with a single core Rocket. @@ -18,52 +18,6 @@ The following example shows a dual core BOOM with a single core Rocket. :start-after: DOC include start: DualBoomAndRocket :end-before: DOC include end: DualBoomAndRocket -In this example, the ``WithNBoomCores`` and ``WithNBigCores`` config fragments set up the default parameters for the multiple BOOM and Rocket cores, respectively. -However, for BOOM, an extra config fragment called ``WithLargeBooms`` is added to override the default parameters with a different set of more common default parameters. -This config fragment applies to all BOOM cores in the system and changes the parameters for each. - -Great! Now you have a heterogeneous setup with BOOMs and Rockets. -The final thing you need to make this system work is to renumber the ``hartId``'s of the cores so that each core has a unique ``hartId`` (a ``hartId`` is the hardware thread id of the core). -The ``WithRenumberHarts`` config fragment solves this by assigning a unique ``hartId`` to all cores in the system (it can label the Rocket cores first or the BOOM cores first). -The reason this is needed is because by default the ``WithN...Cores(X)`` config fragment assumes that there are only BOOM or only Rocket cores in the system. -Thus, without the ``WithRenumberHarts`` config fragment, each set of cores is labeled starting from zero causing multiple cores to be assigned the same ``hartId``. - -Another alternative option to create a multi heterogeneous core system is to override the parameters yourself so you can specify the core parameters per core. -The config fragment to add to your system would look something like the following. - -.. code-block:: scala - - // create 6 cores (4 boom and 2 rocket) - class WithHeterCoresSetup extends Config((site, here, up) => { - case BoomTilesKey => { - val boomTile0 = BoomTileParams(...) // params for boom core 0 - val boomTile1 = BoomTileParams(...) // params for boom core 1 - val boomTile2 = BoomTileParams(...) // params for boom core 2 - val boomTile3 = BoomTileParams(...) // params for boom core 3 - Seq(boomTile0, boomTile1, boomTile2, boomTile3) - } - - case RocketTilesKey => { - val rocketTile0 = RocketTileParams(...) // params for rocket core 0 - val rocketTile1 = RocketTileParams(...) // params for rocket core 1 - Seq(rocketTile0, rocketTile1) - } - }) - -Then you could use this new config fragment like the following. - -.. code-block:: scala - - class SixCoreConfig extends Config( - new WithTSI ++ - new WithBootROM ++ - new WithUART ++ - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new WithHeterCoresSetup ++ - new freechips.rocketchip.system.BaseConfig) - -Note, in this setup you need to specify the ``hartId`` of each core in the "TileParams", where each ``hartId`` is unique. Adding Hwachas ------------------------------------------- @@ -92,8 +46,7 @@ An example is shown below with two BOOM cores, and one Rocket tile with a RoCC a :start-after: DOC include start: DualBoomAndRocketOneHwacha :end-before: DOC include end: DualBoomAndRocketOneHwacha -In this example, the ``WithRenumberHarts`` relabels the ``hartId``'s of all the BOOM/Rocket cores. -Then after that is applied to the parameters, the ``WithMultiRoCCHwacha`` config fragment assigns a Hwacha accelerator to a particular ``hartId`` (in this case, the ``hartId`` of ``2`` corresponds to the Rocket core). +The ``WithMultiRoCCHwacha`` config fragment assigns a Hwacha accelerator to a particular ``hartId`` (in this case, the ``hartId`` of ``2`` corresponds to the Rocket core). Finally, the ``WithMultiRoCC`` config fragment is called. This config fragment sets the ``BuildRoCC`` key to use the ``MultiRoCCKey`` instead of the default. This must be used after all the RoCC parameters are set because it needs to override the ``BuildRoCC`` parameter. diff --git a/generators/chipyard/src/main/scala/ConfigFragments.scala b/generators/chipyard/src/main/scala/ConfigFragments.scala index ad33fa47..024f5695 100644 --- a/generators/chipyard/src/main/scala/ConfigFragments.scala +++ b/generators/chipyard/src/main/scala/ConfigFragments.scala @@ -130,3 +130,16 @@ class WithNPerfCounters(n: Int = 29) extends Config((site, here, up) => { case other => other } }) + +class WithRocketICacheScratchpad extends Config((site, here, up) => { + case RocketTilesKey => up(RocketTilesKey, site) map { r => + r.copy(icache = r.icache.map(_.copy(itimAddr = Some(0x100000 + r.hartId * 0x10000)))) + } +}) + +class WithRocketDCacheScratchpad extends Config((site, here, up) => { + case RocketTilesKey => up(RocketTilesKey, site) map { r => + r.copy(dcache = r.dcache.map(_.copy(nSets = 32, nWays = 1, scratch = Some(0x200000 + r.hartId * 0x10000)))) + } +}) + diff --git a/generators/chipyard/src/main/scala/config/AbstractConfig.scala b/generators/chipyard/src/main/scala/config/AbstractConfig.scala new file mode 100644 index 00000000..22f64925 --- /dev/null +++ b/generators/chipyard/src/main/scala/config/AbstractConfig.scala @@ -0,0 +1,26 @@ +package chipyard.config + +import freechips.rocketchip.config.{Config} + +// -------------- +// Chipyard abstract ("base") configuration +// NOTE: This configuration is NOT INSTANTIABLE, as it defines a empty system with no tiles +// -------------- + +class AbstractConfig extends Config( + new chipyard.iobinders.WithUARTAdapter ++ // display UART with a SimUARTAdapter + new chipyard.iobinders.WithTieOffInterrupts ++ // tie off top-level interrupts + new chipyard.iobinders.WithBlackBoxSimMem ++ // drive the master AXI4 memory with a blackbox DRAMSim model + new chipyard.iobinders.WithTiedOffDebug ++ // tie off debug (since we are using SimSerial for testing) + new chipyard.iobinders.WithSimSerial ++ // drive TSI with SimSerial for testing + new testchipip.WithTSI ++ // use testchipip serial offchip link + new chipyard.config.WithBootROM ++ // use default bootrom + new chipyard.config.WithUART ++ // add a UART + new chipyard.config.WithL2TLBs(1024) ++ // use L2 TLBs + new freechips.rocketchip.subsystem.WithNoMMIOPort ++ // no top-level MMIO master port (overrides default set in rocketchip) + new freechips.rocketchip.subsystem.WithNoSlavePort ++ // no top-level MMIO slave port (overrides default set in rocketchip) + new freechips.rocketchip.subsystem.WithInclusiveCache ++ // use Sifive L2 cache + new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ // no external interrupts + new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ // hierarchical buses including mbus+l2 + new freechips.rocketchip.system.BaseConfig) // "base" rocketchip system + diff --git a/generators/chipyard/src/main/scala/config/ArianeConfigs.scala b/generators/chipyard/src/main/scala/config/ArianeConfigs.scala index 6fb2ef00..7bc985aa 100644 --- a/generators/chipyard/src/main/scala/config/ArianeConfigs.scala +++ b/generators/chipyard/src/main/scala/config/ArianeConfigs.scala @@ -9,34 +9,11 @@ import freechips.rocketchip.config.{Config} // --------------------- class ArianeConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ // display UART with a SimUARTAdapter - new chipyard.iobinders.WithTieOffInterrupts ++ // tie off top-level interrupts - new chipyard.iobinders.WithSimAXIMem ++ // drive the master AXI4 memory with a SimAXIMem - new chipyard.iobinders.WithTiedOffDebug ++ // tie off debug (since we are using SimSerial for testing) - new chipyard.iobinders.WithSimSerial ++ // drive TSI with SimSerial for testing - new testchipip.WithTSI ++ // use testchipip serial offchip link - new chipyard.config.WithBootROM ++ // use default bootrom - new chipyard.config.WithUART ++ // add a UART - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ // no top-level MMIO master port (overrides default set in rocketchip) - new freechips.rocketchip.subsystem.WithNoSlavePort ++ // no top-level MMIO slave port (overrides default set in rocketchip) - new freechips.rocketchip.subsystem.WithInclusiveCache ++ // use Sifive L2 cache - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ // no external interrupts - new ariane.WithNArianeCores(1) ++ // single Ariane core - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ // hierarchical buses including mbus+l2 - new freechips.rocketchip.system.BaseConfig) // "base" rocketchip system + new ariane.WithNArianeCores(1) ++ // single Ariane core + new chipyard.config.AbstractConfig) class dmiArianeConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithSimAXIMem ++ - new chipyard.iobinders.WithTiedOffSerial ++ - new chipyard.iobinders.WithSimDebug ++ // add SimDebug and use it to drive simulation - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ - new ariane.WithNArianeCores(1) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new chipyard.iobinders.WithTiedOffSerial ++ // Tie off the serial port, override default instantiation of SimSerial + new chipyard.iobinders.WithSimDebug ++ // add SimDebug and use it to drive simulation, override default tie-off debug + new ariane.WithNArianeCores(1) ++ // single Ariane core + new chipyard.config.AbstractConfig) diff --git a/generators/chipyard/src/main/scala/config/BoomConfigs.scala b/generators/chipyard/src/main/scala/config/BoomConfigs.scala index 7b66e3b3..1f41c252 100644 --- a/generators/chipyard/src/main/scala/config/BoomConfigs.scala +++ b/generators/chipyard/src/main/scala/config/BoomConfigs.scala @@ -7,151 +7,40 @@ import freechips.rocketchip.config.{Config} // --------------------- class SmallBoomConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ // display UART with a SimUARTAdapter - new chipyard.iobinders.WithTieOffInterrupts ++ // tie off top-level interrupts - new chipyard.iobinders.WithBlackBoxSimMem ++ // drive the master AXI4 memory with a SimAXIMem - new chipyard.iobinders.WithTiedOffDebug ++ // tie off debug (since we are using SimSerial for testing) - new chipyard.iobinders.WithSimSerial ++ // drive TSI with SimSerial for testing - new testchipip.WithTSI ++ // use testchipip serial offchip link - new chipyard.config.WithBootROM ++ // use default bootrom - new chipyard.config.WithUART ++ // add a UART - new chipyard.config.WithL2TLBs(1024) ++ // use L2 TLBs - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ // no top-level MMIO master port (overrides default set in rocketchip) - new freechips.rocketchip.subsystem.WithNoSlavePort ++ // no top-level MMIO slave port (overrides default set in rocketchip) - new freechips.rocketchip.subsystem.WithInclusiveCache ++ // use Sifive L2 cache - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ // no external interrupts new boom.common.WithNSmallBooms(1) ++ // small boom config - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ // hierarchical buses including mbus+l2 - new freechips.rocketchip.system.BaseConfig) // "base" rocketchip system + new chipyard.config.AbstractConfig) class MediumBoomConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithL2TLBs(1024) ++ - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ - new boom.common.WithNMediumBooms(1) ++ // medium boom config - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new boom.common.WithNMediumBooms(1) ++ // medium boom config + new chipyard.config.AbstractConfig) class LargeBoomConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithL2TLBs(1024) ++ - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ new boom.common.WithNLargeBooms(1) ++ // large boom config - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new chipyard.config.AbstractConfig) class MegaBoomConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithL2TLBs(1024) ++ - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ - new boom.common.WithNMegaBooms(1) ++ // mega boom config - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new boom.common.WithBoomBranchPrintf ++ + new boom.common.WithNMegaBooms(1) ++ // mega boom config + new chipyard.config.AbstractConfig) class DualSmallBoomConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithL2TLBs(1024) ++ - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ - new boom.common.WithNSmallBooms(2) ++ // 2 boom cores - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new boom.common.WithNSmallBooms(2) ++ // 2 boom cores + new chipyard.config.AbstractConfig) class HwachaLargeBoomConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithL2TLBs(1024) ++ - new hwacha.DefaultHwachaConfig ++ // use Hwacha vector accelerator - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ + new hwacha.DefaultHwachaConfig ++ // use Hwacha vector accelerator new boom.common.WithNLargeBooms(1) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new chipyard.config.AbstractConfig) class LoopbackNICLargeBoomConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ - new chipyard.iobinders.WithLoopbackNIC ++ // drive NIC IOs with loopback - new testchipip.WithTSI ++ - new icenet.WithIceNIC ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithL2TLBs(1024) ++ - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ + new chipyard.iobinders.WithLoopbackNIC ++ // drive NIC IOs with loopback + new icenet.WithIceNIC ++ // build a NIC new boom.common.WithNLargeBooms(1) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new chipyard.config.AbstractConfig) class DromajoBoomConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ new chipyard.iobinders.WithSimDromajoBridge ++ // attach Dromajo - new testchipip.WithTSI ++ new chipyard.config.WithTraceIO ++ // enable the traceio - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithL2TLBs(1024) ++ - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ new boom.common.WithNSmallBooms(1) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new chipyard.config.AbstractConfig) diff --git a/generators/chipyard/src/main/scala/config/HeteroConfigs.scala b/generators/chipyard/src/main/scala/config/HeteroConfigs.scala index a7d1c133..9eb0b2f5 100644 --- a/generators/chipyard/src/main/scala/config/HeteroConfigs.scala +++ b/generators/chipyard/src/main/scala/config/HeteroConfigs.scala @@ -7,108 +7,38 @@ import freechips.rocketchip.config.{Config} // --------------------- class LargeBoomAndRocketConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ // display UART with a SimUARTAdapter - new chipyard.iobinders.WithTieOffInterrupts ++ // tie off top-level interrupts - new chipyard.iobinders.WithBlackBoxSimMem ++ // drive the master AXI4 memory with a SimAXIMem - new chipyard.iobinders.WithTiedOffDebug ++ // tie off debug (since we are using SimSerial for testing) - new chipyard.iobinders.WithSimSerial ++ // drive TSI with SimSerial for testing - new testchipip.WithTSI ++ // use testchipip serial offchip link - new chipyard.config.WithBootROM ++ // use default bootrom - new chipyard.config.WithUART ++ // add a UART - new chipyard.config.WithL2TLBs(1024) ++ // use L2 TLBs new boom.common.WithNLargeBooms(1) ++ // single-core boom - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ // no top-level MMIO master port (overrides default set in rocketchip) - new freechips.rocketchip.subsystem.WithNoSlavePort ++ // no top-level MMIO slave port (overrides default set in rocketchip) - new freechips.rocketchip.subsystem.WithInclusiveCache ++ // use Sifive L2 cache - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ // no external interrupts new freechips.rocketchip.subsystem.WithNBigCores(1) ++ // single rocket-core - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ // hierarchical buses including mbus+l2 - new freechips.rocketchip.system.BaseConfig) // "base" rocketchip system + new chipyard.config.AbstractConfig) // DOC include start: BoomAndRocketWithHwacha class HwachaLargeBoomAndHwachaRocketConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithL2TLBs(1024) ++ - new hwacha.DefaultHwachaConfig ++ // add hwacha to all harts - new boom.common.WithNLargeBooms(1) ++ - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ - new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new hwacha.DefaultHwachaConfig ++ // add hwacha to all harts + new boom.common.WithNLargeBooms(1) ++ // add 1 boom core + new freechips.rocketchip.subsystem.WithNBigCores(1) ++ // add 1 rocket core + new chipyard.config.AbstractConfig) // DOC include end: BoomAndRocketWithHwacha -// DOC include start: DualBoomAndRocketOneHwacha +// DOC include start: DualBoomAndRocketOneHwacha class LargeBoomAndHwachaRocketConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ new chipyard.config.WithMultiRoCC ++ // support heterogeneous rocc new chipyard.config.WithMultiRoCCHwacha(1) ++ // put hwacha on hart-1 (rocket) - new chipyard.config.WithL2TLBs(1024) ++ - new boom.common.WithNLargeBooms(1) ++ - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ - new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new hwacha.DefaultHwachaConfig ++ // set default hwacha config keys + new boom.common.WithNLargeBooms(1) ++ // add 1 boom core + new freechips.rocketchip.subsystem.WithNBigCores(1) ++ // add 1 rocket core + new chipyard.config.AbstractConfig) // DOC include end: DualBoomAndRocketOneHwacha // DOC include start: DualBoomAndRocket class DualLargeBoomAndDualRocketConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithL2TLBs(1024) ++ - new boom.common.WithNLargeBooms(2) ++ // 2 boom cores - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ - new freechips.rocketchip.subsystem.WithNBigCores(2) ++ // 2 rocket cores - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new boom.common.WithNLargeBooms(2) ++ // add 2 boom cores + new freechips.rocketchip.subsystem.WithNBigCores(2) ++ // add 2 rocket cores + new chipyard.config.AbstractConfig) // DOC include end: DualBoomAndRocket class LargeBoomAndRocketWithControlCoreConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithL2TLBs(1024) ++ - new freechips.rocketchip.subsystem.WithNSmallCores(1) ++ // Add a small control core - new boom.common.WithNLargeBooms(1) ++ - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ - new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) - + new freechips.rocketchip.subsystem.WithNSmallCores(1) ++ // Add a small "control" core + new boom.common.WithNLargeBooms(1) ++ // Add 1 boom core + new freechips.rocketchip.subsystem.WithNBigCores(1) ++ // add 1 rocket core + new chipyard.config.AbstractConfig) diff --git a/generators/chipyard/src/main/scala/config/RocketConfigs.scala b/generators/chipyard/src/main/scala/config/RocketConfigs.scala index 3dc7d22d..8e6e4867 100644 --- a/generators/chipyard/src/main/scala/config/RocketConfigs.scala +++ b/generators/chipyard/src/main/scala/config/RocketConfigs.scala @@ -7,556 +7,179 @@ import freechips.rocketchip.config.{Config} // -------------- class RocketConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ // display UART with a SimUARTAdapter - new chipyard.iobinders.WithTieOffInterrupts ++ // tie off top-level interrupts - new chipyard.iobinders.WithBlackBoxSimMem ++ // drive the master AXI4 memory with a blackbox DRAMSim model - new chipyard.iobinders.WithTiedOffDebug ++ // tie off debug (since we are using SimSerial for testing) - new chipyard.iobinders.WithSimSerial ++ // drive TSI with SimSerial for testing - new testchipip.WithTSI ++ // use testchipip serial offchip link - new chipyard.config.WithBootROM ++ // use default bootrom - new chipyard.config.WithUART ++ // add a UART - new chipyard.config.WithL2TLBs(1024) ++ // use L2 TLBs - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ // no top-level MMIO master port (overrides default set in rocketchip) - new freechips.rocketchip.subsystem.WithNoSlavePort ++ // no top-level MMIO slave port (overrides default set in rocketchip) - new freechips.rocketchip.subsystem.WithInclusiveCache ++ // use Sifive L2 cache - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ // no external interrupts new freechips.rocketchip.subsystem.WithNBigCores(1) ++ // single rocket-core - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ // hierarchical buses including mbus+l2 - new freechips.rocketchip.system.BaseConfig) // "base" rocketchip system + new chipyard.config.AbstractConfig) class HwachaRocketConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithL2TLBs(1024) ++ new hwacha.DefaultHwachaConfig ++ // use Hwacha vector accelerator - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new chipyard.config.AbstractConfig) // DOC include start: GemminiRocketConfig class GemminiRocketConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithL2TLBs(1024) ++ new gemmini.DefaultGemminiConfig ++ // use Gemmini systolic array GEMM accelerator - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new chipyard.config.AbstractConfig) // DOC include end: GemminiRocketConfig -class RoccRocketConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithL2TLBs(1024) ++ - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithRoccExample ++ // use example RoCC-based accelerator - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ - new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) - // DOC include start: JtagRocket class jtagRocketConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithSimDebug ++ // add SimJtag and SimSerial, use both to drive sim - new chipyard.iobinders.WithSimSerial ++ - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithL2TLBs(1024) ++ + new chipyard.iobinders.WithSimDebug ++ // add SimDebug, in addition to default SimSerial new freechips.rocketchip.subsystem.WithJtagDTM ++ // sets DTM communication interface to JTAG - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new chipyard.config.AbstractConfig) // DOC include end: JtagRocket // DOC include start: DmiRocket class dmiRocketConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTiedOffSerial ++ - new chipyard.iobinders.WithSimDebug ++ // add SimDebug and use it to drive simulation - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithL2TLBs(1024) ++ - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ + new chipyard.iobinders.WithTiedOffSerial ++ // tie-off serial, override default add SimSerial + new chipyard.iobinders.WithSimDebug ++ // add SimDebug, override default tie-off debug new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new chipyard.config.AbstractConfig) // DOC include end: DmiRocket // DOC include start: GCDTLRocketConfig class GCDTLRocketConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ - new testchipip.WithTSI ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithL2TLBs(1024) ++ new chipyard.example.WithGCD(useAXI4=false, useBlackBox=false) ++ // Use GCD Chisel, connect Tilelink - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new chipyard.config.AbstractConfig) // DOC include end: GCDTLRocketConfig // DOC include start: GCDAXI4BlackBoxRocketConfig class GCDAXI4BlackBoxRocketConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ - new testchipip.WithTSI ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithL2TLBs(1024) ++ new chipyard.example.WithGCD(useAXI4=true, useBlackBox=true) ++ // Use GCD blackboxed verilog, connect by AXI4->Tilelink - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new chipyard.config.AbstractConfig) // DOC include end: GCDAXI4BlackBoxRocketConfig class LargeSPIFlashROMRocketConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ new chipyard.iobinders.WithSimSPIFlashModel(true) ++ // add the SPI flash model in the harness (read-only) - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ new chipyard.config.WithSPIFlash ++ // add the SPI flash controller - new chipyard.config.WithL2TLBs(1024) ++ - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new chipyard.config.AbstractConfig) class SmallSPIFlashRocketConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ new chipyard.iobinders.WithSimSPIFlashModel(false) ++ // add the SPI flash model in the harness (writeable) - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ new chipyard.config.WithSPIFlash(0x100000) ++ // add the SPI flash controller (1 MiB) - new chipyard.config.WithL2TLBs(1024) ++ - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new chipyard.config.AbstractConfig) class SimAXIRocketConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithSimAXIMem ++ // drive the master AXI4 memory with a SimAXIMem, a 1-cycle magic memory - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithL2TLBs(1024) ++ - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ + new chipyard.iobinders.WithSimAXIMem ++ // drive the master AXI4 memory with a SimAXIMem, a 1-cycle magic memory, instead of default SimDRAM new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new chipyard.config.AbstractConfig) class SimBlockDeviceRocketConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ new chipyard.iobinders.WithSimBlockDevice ++ // drive block-device IOs with SimBlockDevice - new testchipip.WithTSI ++ new testchipip.WithBlockDevice ++ // add block-device module to peripherybus - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithL2TLBs(1024) ++ - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new chipyard.config.AbstractConfig) class BlockDeviceModelRocketConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ new chipyard.iobinders.WithBlockDeviceModel ++ // drive block-device IOs with a BlockDeviceModel - new testchipip.WithTSI ++ new testchipip.WithBlockDevice ++ // add block-device module to periphery bus - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithL2TLBs(1024) ++ - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new chipyard.config.AbstractConfig) // DOC include start: GPIORocketConfig class GPIORocketConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ new chipyard.iobinders.WithGPIOTiedOff ++ // tie off GPIO inputs into the top - new testchipip.WithTSI ++ new chipyard.config.WithGPIO ++ // add GPIOs to the peripherybus - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithL2TLBs(1024) ++ - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new chipyard.config.AbstractConfig) // DOC include end: GPIORocketConfig class QuadRocketConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithL2TLBs(1024) ++ - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ new freechips.rocketchip.subsystem.WithNBigCores(4) ++ // quad-core (4 RocketTiles) - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new chipyard.config.AbstractConfig) class RV32RocketConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ new freechips.rocketchip.subsystem.WithRV32 ++ // set RocketTiles to be 32-bit - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new chipyard.config.AbstractConfig) class GB1MemoryRocketConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithL2TLBs(1024) ++ new freechips.rocketchip.subsystem.WithExtMemSize((1<<30) * 1L) ++ // use 1GB simulated external memory - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new chipyard.config.AbstractConfig) // DOC include start: Sha3Rocket class Sha3RocketConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithL2TLBs(1024) ++ new sha3.WithSha3Accel ++ // add SHA3 rocc accelerator - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new chipyard.config.AbstractConfig) // DOC include end: Sha3Rocket // DOC include start: InitZeroRocketConfig class InitZeroRocketConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithL2TLBs(1024) ++ new chipyard.example.WithInitZero(0x88000000L, 0x1000L) ++ // add InitZero - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new chipyard.config.AbstractConfig) // DOC include end: InitZeroRocketConfig class LoopbackNICRocketConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ new chipyard.iobinders.WithLoopbackNIC ++ // drive NIC IOs with loopback - new testchipip.WithTSI ++ new icenet.WithIceNIC ++ // add an IceNIC - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithL2TLBs(1024) ++ - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new chipyard.config.AbstractConfig) // DOC include start: l1scratchpadrocket -class L1ScratchpadSmallRocketConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ +class ScratchpadOnlyRocketConfig extends Config( new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ // remove offchip mem port new freechips.rocketchip.subsystem.WithNBanks(0) ++ new freechips.rocketchip.subsystem.WithNoMemPort ++ - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use rocket l1 scratchpad - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ - new freechips.rocketchip.subsystem.WithNSmallCores(1) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use rocket l1 DCache scratchpad as base phys mem + new freechips.rocketchip.subsystem.WithNBigCores(1) ++ + new chipyard.config.AbstractConfig) // DOC include end: l1scratchpadrocket +class L1ScratchpadRocketConfig extends Config( + new chipyard.config.WithRocketICacheScratchpad ++ // use rocket ICache scratchpad + new chipyard.config.WithRocketDCacheScratchpad ++ // use rocket DCache scratchpad + new freechips.rocketchip.subsystem.WithNBigCores(1) ++ + new chipyard.config.AbstractConfig) + // DOC include start: mbusscratchpadrocket class MbusScratchpadRocketConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ - new testchipip.WithTSI ++ new testchipip.WithBackingScratchpad ++ // add mbus backing scratchpad - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithL2TLBs(1024) ++ new freechips.rocketchip.subsystem.WithNoMemPort ++ // remove offchip mem port - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new chipyard.config.AbstractConfig) // DOC include end: mbusscratchpadrocket // DOC include start: RingSystemBusRocket class RingSystemBusRocketConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithL2TLBs(1024) ++ new testchipip.WithRingSystemBus ++ // Ring-topology system bus - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new chipyard.config.AbstractConfig) // DOC include end: RingSystemBusRocket class StreamingPassthroughRocketConfig extends Config( new chipyard.example.WithStreamingPassthrough ++ // use top with tilelink-controlled streaming passthrough - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithL2TLBs(1024) ++ - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new chipyard.config.AbstractConfig) // DOC include start: StreamingFIRRocketConfig class StreamingFIRRocketConfig extends Config ( new chipyard.example.WithStreamingFIR ++ // use top with tilelink-controlled streaming FIR - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithL2TLBs(1024) ++ - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new chipyard.config.AbstractConfig) // DOC include end: StreamingFIRRocketConfig class SmallNVDLARocketConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithL2TLBs(1024) ++ new nvidia.blocks.dla.WithNVDLA("small") ++ // add a small NVDLA - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new chipyard.config.AbstractConfig) class LargeNVDLARocketConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithL2TLBs(1024) ++ new nvidia.blocks.dla.WithNVDLA("large", true) ++ // add a large NVDLA with synth. rams - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new chipyard.config.AbstractConfig) class MMIORocketConfig extends Config( - new chipyard.iobinders.WithUARTAdapter ++ - new chipyard.iobinders.WithTieOffInterrupts ++ - new chipyard.iobinders.WithBlackBoxSimMem ++ - new chipyard.iobinders.WithTiedOffDebug ++ - new chipyard.iobinders.WithSimSerial ++ new chipyard.iobinders.WithTieOffL2FBusAXI ++ // Tie-off the incoming MMIO port new chipyard.iobinders.WithSimAXIMMIO ++ // Attach a simulated memory to the outwards MMIO port - new testchipip.WithTSI ++ - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithL2TLBs(1024) ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ - new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ + new freechips.rocketchip.subsystem.WithDefaultMMIOPort ++ // add default external master port + new freechips.rocketchip.subsystem.WithDefaultSlavePort ++ // add default external slave port new freechips.rocketchip.subsystem.WithNBigCores(1) ++ - new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ - new freechips.rocketchip.system.BaseConfig) + new chipyard.config.AbstractConfig) diff --git a/scripts/tutorial-patches/RocketConfigs.scala.patch b/scripts/tutorial-patches/RocketConfigs.scala.patch index cc9910c7..351f8ca2 100644 --- a/scripts/tutorial-patches/RocketConfigs.scala.patch +++ b/scripts/tutorial-patches/RocketConfigs.scala.patch @@ -1,13 +1,13 @@ diff --git a/generators/chipyard/src/main/scala/config/RocketConfigs.scala b/generators/chipyard/src/main/scala/config/RocketConfigs.scala -index f29c580..0bd36ca 100644 +index 8e6e486..fc3a811 100644 --- a/generators/chipyard/src/main/scala/config/RocketConfigs.scala +++ b/generators/chipyard/src/main/scala/config/RocketConfigs.scala -@@ -333,7 +333,7 @@ class Sha3RocketConfig extends Config( - new chipyard.config.WithBootROM ++ - new chipyard.config.WithUART ++ - new chipyard.config.WithL2TLBs(1024) ++ +@@ -105,7 +105,7 @@ class GB1MemoryRocketConfig extends Config( + + // DOC include start: Sha3Rocket + class Sha3RocketConfig extends Config( - new sha3.WithSha3Accel ++ // add SHA3 rocc accelerator +// new sha3.WithSha3Accel ++ // add SHA3 rocc accelerator - new freechips.rocketchip.subsystem.WithNoMMIOPort ++ - new freechips.rocketchip.subsystem.WithNoSlavePort ++ - new freechips.rocketchip.subsystem.WithInclusiveCache ++ + new freechips.rocketchip.subsystem.WithNBigCores(1) ++ + new chipyard.config.AbstractConfig) + // DOC include end: Sha3Rocket From b55e579c91386f86bcd945412e6d4ac6ba301edc Mon Sep 17 00:00:00 2001 From: Albert Ou Date: Tue, 7 Jul 2020 23:00:14 -0700 Subject: [PATCH 25/27] Override default baud rate for FireChip This avoids target software needing to explicitly set the divisor to match the UART bridge. --- generators/chipyard/src/main/scala/ConfigFragments.scala | 6 +++--- generators/firechip/src/main/scala/TargetConfigs.scala | 7 ++++--- generators/sifive-blocks | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/generators/chipyard/src/main/scala/ConfigFragments.scala b/generators/chipyard/src/main/scala/ConfigFragments.scala index da048ff1..dde0e6d8 100644 --- a/generators/chipyard/src/main/scala/ConfigFragments.scala +++ b/generators/chipyard/src/main/scala/ConfigFragments.scala @@ -51,9 +51,9 @@ class WithGPIO extends Config((site, here, up) => { }) // DOC include end: gpio config fragment -class WithUART extends Config((site, here, up) => { +class WithUART(baudrate: BigInt = 115200) extends Config((site, here, up) => { case PeripheryUARTKey => Seq( - UARTParams(address = 0x54000000L, nTxEntries = 256, nRxEntries = 256)) + UARTParams(address = 0x54000000L, nTxEntries = 256, nRxEntries = 256, initBaudRate = baudrate)) }) class WithSPIFlash(size: BigInt = 0x10000000) extends Config((site, here, up) => { @@ -143,4 +143,4 @@ class WithHwachaTest extends Config((site, here, up) => { suiteHelper.addSuite(hwachaBmarks) "SRC_EXTENSION = $(base_dir)/hwacha/$(src_path)/*.scala" + "\nDISASM_EXTENSION = --extension=hwacha" } -}) \ No newline at end of file +}) diff --git a/generators/firechip/src/main/scala/TargetConfigs.scala b/generators/firechip/src/main/scala/TargetConfigs.scala index 2828580a..8aef9f8c 100644 --- a/generators/firechip/src/main/scala/TargetConfigs.scala +++ b/generators/firechip/src/main/scala/TargetConfigs.scala @@ -69,7 +69,8 @@ class WithNVDLASmall extends nvidia.blocks.dla.WithNVDLA("small") class WithFireSimConfigTweaks extends Config( // Required*: When using FireSim-as-top to provide a correct path to the target bootrom source new WithBootROM ++ - // Optional*: Removing this will require target-software changes to properly capture UART output + // Optional*: Removing this will require adjusting the UART baud rate and + // potential target-software changes to properly capture UART output new WithPeripheryBusFrequency(BigInt(3200000000L)) ++ // Required: Existing FAME-1 transform cannot handle black-box clock gates new WithoutClockGating ++ @@ -85,8 +86,8 @@ class WithFireSimConfigTweaks extends Config( new testchipip.WithTSI ++ // Optional: Removing this will require using an initramfs under linux new testchipip.WithBlockDevice ++ - // Required*: - new chipyard.config.WithUART + // Required*: Scale default baud rate with periphery bus frequency + new chipyard.config.WithUART(BigInt(3686400L)) ) /******************************************************************************* diff --git a/generators/sifive-blocks b/generators/sifive-blocks index c1dee823..c240e629 160000 --- a/generators/sifive-blocks +++ b/generators/sifive-blocks @@ -1 +1 @@ -Subproject commit c1dee8234c23c8fc454108e59ecba20987f95cde +Subproject commit c240e629e2fc111cbb12e4fe707be898b5204984 From 763ba42b4c35915d1824b662fe73976697b0662b Mon Sep 17 00:00:00 2001 From: Albert Ou Date: Wed, 8 Jul 2020 12:36:09 -0700 Subject: [PATCH 26/27] Bump testchipip for FDT alignment and minLatency fixes --- generators/testchipip | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generators/testchipip b/generators/testchipip index 29eb87c9..8b5c89a5 160000 --- a/generators/testchipip +++ b/generators/testchipip @@ -1 +1 @@ -Subproject commit 29eb87c938a2106249b85e3b3dffd00046f5077c +Subproject commit 8b5c89a5f7120e64a7ac5ce5210165426a58f3de From 11c87777fe7ce8dba0854d2bcc65321f8e0d27a7 Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Thu, 9 Jul 2020 11:29:58 -0700 Subject: [PATCH 27/27] Remove BOOM debug print --- generators/chipyard/src/main/scala/config/BoomConfigs.scala | 2 -- 1 file changed, 2 deletions(-) diff --git a/generators/chipyard/src/main/scala/config/BoomConfigs.scala b/generators/chipyard/src/main/scala/config/BoomConfigs.scala index 1f41c252..8b7cd31e 100644 --- a/generators/chipyard/src/main/scala/config/BoomConfigs.scala +++ b/generators/chipyard/src/main/scala/config/BoomConfigs.scala @@ -19,7 +19,6 @@ class LargeBoomConfig extends Config( new chipyard.config.AbstractConfig) class MegaBoomConfig extends Config( - new boom.common.WithBoomBranchPrintf ++ new boom.common.WithNMegaBooms(1) ++ // mega boom config new chipyard.config.AbstractConfig) @@ -43,4 +42,3 @@ class DromajoBoomConfig extends Config( new chipyard.config.WithTraceIO ++ // enable the traceio new boom.common.WithNSmallBooms(1) ++ new chipyard.config.AbstractConfig) -