diff --git a/.circleci/config.yml b/.circleci/config.yml index dc018859..d91e7115 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -338,6 +338,7 @@ jobs: steps: - run-tests: project-key: "chipyard-ariane" + timeout: "30m" # Order and dependencies of jobs to run workflows: diff --git a/.circleci/defaults.sh b/.circleci/defaults.sh index 552ac1db..7d4fdaa3 100755 --- a/.circleci/defaults.sh +++ b/.circleci/defaults.sh @@ -47,7 +47,6 @@ mapping["chipyard-rocket"]="SUB_PROJECT=chipyard" mapping["chipyard-sha3"]="SUB_PROJECT=chipyard CONFIG=Sha3RocketConfig" mapping["chipyard-hetero"]="SUB_PROJECT=chipyard CONFIG=LargeBoomAndRocketConfig" mapping["chipyard-boom"]="SUB_PROJECT=chipyard CONFIG=SmallBoomConfig" -mapping["rocketchip"]="SUB_PROJECT=rocketchip" mapping["chipyard-blkdev"]="SUB_PROJECT=chipyard CONFIG=SimBlockDeviceRocketConfig" mapping["chipyard-hwacha"]="SUB_PROJECT=chipyard CONFIG=HwachaRocketConfig" mapping["chipyard-gemmini"]="SUB_PROJECT=chipyard CONFIG=GemminiRocketConfig" diff --git a/build.sbt b/build.sbt index 05f05d7b..b0e8c84d 100644 --- a/build.sbt +++ b/build.sbt @@ -166,6 +166,7 @@ lazy val gemmini = (project in file("generators/gemmini")) lazy val tapeout = conditionalDependsOn(project in file("./tools/barstools/tapeout/")) .dependsOn(chisel_testers, chipyard) .settings(commonSettings) + .settings(libraryDependencies ++= Seq("io.github.daviddenton" %% "handlebars-scala-fork" % "2.3.0")) lazy val mdf = (project in file("./tools/barstools/mdf/scalalib/")) .settings(commonSettings) diff --git a/common.mk b/common.mk index a98e0e24..696e0f83 100644 --- a/common.mk +++ b/common.mk @@ -58,7 +58,11 @@ $(FIRRTL_FILE) $(ANNO_FILE): generator_temp # AG: must re-elaborate if ariane sources have changed... otherwise just run firrtl compile generator_temp: $(SCALA_SOURCES) $(sim_files) $(EXTRA_GENERATOR_REQS) mkdir -p $(build_dir) - cd $(base_dir) && $(SBT) "project $(SBT_PROJECT)" "runMain $(GENERATOR_PACKAGE).Generator $(build_dir) $(MODEL_PACKAGE) $(MODEL) $(CONFIG_PACKAGE) $(CONFIG)" + cd $(base_dir) && $(SBT) "project $(SBT_PROJECT)" "runMain $(GENERATOR_PACKAGE).Generator \ + --target-dir $(build_dir) \ + --name $(long_name) \ + --top-module $(MODEL_PACKAGE).$(MODEL) \ + --legacy-configs $(CONFIG_PACKAGE).$(CONFIG)" .PHONY: firrtl firrtl: $(FIRRTL_FILE) diff --git a/generators/ariane b/generators/ariane index e02436d2..621201b1 160000 --- a/generators/ariane +++ b/generators/ariane @@ -1 +1 @@ -Subproject commit e02436d2aaf934b6e58d5e11e87276ba0d840f2a +Subproject commit 621201b1d5a929ab0e89f1a857b76a33e7e2e8a8 diff --git a/generators/boom b/generators/boom index a26504f3..90911dde 160000 --- a/generators/boom +++ b/generators/boom @@ -1 +1 @@ -Subproject commit a26504f34db8327a5d4d9bb3a342dddf79e02b35 +Subproject commit 90911dde1b8730f10c958d172f26f72d718be5ae diff --git a/generators/chipyard/src/main/scala/ChipTop.scala b/generators/chipyard/src/main/scala/ChipTop.scala index 328891a8..d0b4df02 100644 --- a/generators/chipyard/src/main/scala/ChipTop.scala +++ b/generators/chipyard/src/main/scala/ChipTop.scala @@ -12,7 +12,42 @@ import chipyard.iobinders.{IOBinders, TestHarnessFunction, IOBinderTuple} import barstools.iocell.chisel._ -case object BuildSystem extends Field[Parameters => RawModule]((p: Parameters) => Module(LazyModule(new DigitalTop()(p)).suggestName("system").module)) +case object BuildSystem extends Field[Parameters => LazyModule]((p: Parameters) => LazyModule(new DigitalTop()(p))) + +/** + * Chipyard provides three baseline, top-level reset schemes, set using the + * [[GlobalResetSchemeKey]] in a Parameters instance. These are: + * + * 1) Synchronous: The input coming to the chip is synchronous to the provided + * clocks and will be used without modification as a synchronous reset. + * This is safe only for use in FireSim and SW simulation. + * + * 2) Asynchronous: The input reset is asynchronous to the input clock, but it + * is caught and synchronized to that clock before it is dissemenated. + * Thus, downsteam modules will be emitted with synchronously reset state + * elements. + * + * 3) Asynchronous Full: The input reset is asynchronous to the input clock, + * and is used globally as an async reset. Downstream modules will be emitted + * with asynchronously reset state elements. + * + */ +sealed trait GlobalResetScheme { + def pinIsAsync: Boolean +} +sealed trait HasAsyncInput { self: GlobalResetScheme => + def pinIsAsync = true +} + +sealed trait HasSyncInput { self: GlobalResetScheme => + def pinIsAsync = false +} + +case object GlobalResetSynchronous extends GlobalResetScheme with HasSyncInput +case object GlobalResetAsynchronous extends GlobalResetScheme with HasAsyncInput +case object GlobalResetAsynchronousFull extends GlobalResetScheme with HasAsyncInput +case object GlobalResetSchemeKey extends Field[GlobalResetScheme](GlobalResetSynchronous) + /** * The base class used for building chips. This constructor instantiates a module specified by the BuildSystem parameter, @@ -26,16 +61,21 @@ abstract class BaseChipTop()(implicit val p: Parameters) extends RawModule with // A list of functions to call in the test harness val harnessFunctions = ArrayBuffer.empty[TestHarnessFunction] // The system clock + // These are given so that IOCell can use DataMirror and generate ports with + // the right flow (Input/Output) val systemClock = Wire(Input(Clock())) - // The system reset (synchronous to clock) - val systemReset = Wire(Input(Bool())) + val systemReset = Wire(Input(Reset())) // The system module specified by BuildSystem - val system = withClockAndReset(systemClock, systemReset) { p(BuildSystem)(p) } + 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) { - val (_ports, _iocells, _harnessFunctions) = p(IOBinders).values.map(_(system)).flatten.unzip3 + // 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 // We ignore _ports for now... iocells ++= _iocells.flatten harnessFunctions ++= _harnessFunctions.flatten @@ -45,13 +85,22 @@ abstract class BaseChipTop()(implicit val p: Parameters) extends RawModule with /** * A simple clock and reset implementation that punches out clock and reset ports with the same - * names as the implicit clock and reset for standard Module classes. Reset is synchronous to - * clock, which may not be a good idea to use for tapeouts. + * names as the implicit clock and reset for standard Module classes. Three basic reset schemes + * are provided. See [[GlobalResetScheme]]. */ trait HasChipTopSimpleClockAndReset { this: BaseChipTop => val (clock, systemClockIO) = IOCell.generateIOFromSignal(systemClock, Some("iocell_clock")) - val (reset, systemResetIO) = IOCell.generateIOFromSignal(systemReset, Some("iocell_reset")) + val (reset, systemResetIO) = p(GlobalResetSchemeKey) match { + case GlobalResetSynchronous => + IOCell.generateIOFromSignal(systemReset, Some("iocell_reset")) + case GlobalResetAsynchronousFull => + IOCell.generateIOFromSignal(systemReset, Some("iocell_reset"), abstractResetAsAsync = true) + case GlobalResetAsynchronous => + val asyncResetCore = Wire(Input(AsyncReset())) + systemReset := ResetCatchAndSync(systemClock, asyncResetCore.asBool) + IOCell.generateIOFromSignal(asyncResetCore, Some("iocell_reset"), abstractResetAsAsync = true) + } iocells ++= systemClockIO iocells ++= systemResetIO @@ -68,35 +117,5 @@ trait HasChipTopSimpleClockAndReset { this: BaseChipTop => } -/** - * Variant of HasChipTopSimpleClockAndReset that adds a reset synchronizer so that the top-level reset - * can be asynchronous with clock, which is useful for tapeout configs. - */ -trait HasChipTopSimpleClockAndCaughtReset { this: BaseChipTop => - - val asyncResetCore = Wire(Input(Bool())) - systemReset := ResetCatchAndSync(systemClock, asyncResetCore) - - val (clock, systemClockIO) = IOCell.generateIOFromSignal(systemClock, Some("iocell_clock")) - val (areset, asyncResetIO) = IOCell.generateIOFromSignal(asyncResetCore, Some("iocell_areset")) - - iocells ++= systemClockIO - iocells ++= asyncResetIO - - // Add a TestHarnessFunction that connects clock and areset - harnessFunctions += { (th: TestHarness) => { - // Connect clock; it's not done implicitly with RawModule - clock := th.clock - // Connect reset; it's not done implicitly with RawModule - // Note that we need to use dutReset, not harnessReset - areset := th.dutReset - Nil - } } - -} - class ChipTop()(implicit p: Parameters) extends BaseChipTop()(p) with HasChipTopSimpleClockAndReset - -class ChipTopCaughtReset()(implicit p: Parameters) extends BaseChipTop()(p) - with HasChipTopSimpleClockAndCaughtReset diff --git a/generators/chipyard/src/main/scala/ConfigFragments.scala b/generators/chipyard/src/main/scala/ConfigFragments.scala index 495c3367..dee1a40a 100644 --- a/generators/chipyard/src/main/scala/ConfigFragments.scala +++ b/generators/chipyard/src/main/scala/ConfigFragments.scala @@ -21,7 +21,7 @@ import hwacha.{Hwacha} import sifive.blocks.devices.gpio._ import sifive.blocks.devices.uart._ -import chipyard.{BuildTop, BuildSystem, ChipTopCaughtReset} +import chipyard.{BuildTop, BuildSystem} /** * TODO: Why do we need this? @@ -66,7 +66,7 @@ class WithL2TLBs(entries: Int) extends Config((site, here, up) => { }) class WithTracegenSystem extends Config((site, here, up) => { - case BuildSystem => (p: Parameters) => Module(LazyModule(new tracegen.TraceGenSystem()(p)).suggestName("Top").module) + case BuildSystem => (p: Parameters) => LazyModule(new tracegen.TraceGenSystem()(p)) }) @@ -150,13 +150,3 @@ class WithControlCore extends Config((site, here, up) => { ) case MaxHartIdBits => log2Up(up(RocketTilesKey, site).size + up(BoomTilesKey, site).size + 1) }) - - -/** - * Config fragment to use ChipTopCaughtReset as the top module, which adds a reset synchronizer to - * the top-level reset, allowing it to be asynchronous with the clock. - * NOTE: You must remember to set TOP=WithChipTopCaughtReset when building with this config - */ -class WithChipTopCaughtReset extends Config((site, here, up) => { - case BuildTop => (p: Parameters) => Module(new ChipTopCaughtReset()(p).suggestName("top")) -}) diff --git a/generators/chipyard/src/main/scala/Generator.scala b/generators/chipyard/src/main/scala/Generator.scala index 4baba357..d5a53a06 100644 --- a/generators/chipyard/src/main/scala/Generator.scala +++ b/generators/chipyard/src/main/scala/Generator.scala @@ -1,40 +1,6 @@ package chipyard -import scala.util.Try +import firrtl.options.{StageMain} +import chipyard.stage.ChipyardStage -import chisel3._ - -import freechips.rocketchip.config.{Parameters} -import freechips.rocketchip.util.{GeneratorApp} -import freechips.rocketchip.system.{TestGeneration} - -object Generator extends GeneratorApp { - // add unique test suites - override def addTestSuites { - implicit val p: Parameters = params - TestSuiteHelper.addRocketTestSuites - TestSuiteHelper.addBoomTestSuites - TestSuiteHelper.addArianeTestSuites - - // 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) { - TestGeneration.addSuites(rv64uv.map(_("p"))) - TestGeneration.addSuites(rv64uv.map(_("vp"))) - TestGeneration.addSuite(rv64sv("p")) - TestGeneration.addSuite(hwachaBmarks) - } - } - - // specify the name that the generator outputs files as - override lazy val longName = names.topModuleProject + "." + names.topModuleClass + "." + names.configs - - // generate files - generateFirrtl - generateAnno - generateTestSuiteMakefrags - generateArtefacts -} +object Generator extends StageMain(new ChipyardStage) diff --git a/generators/chipyard/src/main/scala/IOBinders.scala b/generators/chipyard/src/main/scala/IOBinders.scala index 6388c3db..e3c79f3a 100644 --- a/generators/chipyard/src/main/scala/IOBinders.scala +++ b/generators/chipyard/src/main/scala/IOBinders.scala @@ -8,6 +8,7 @@ import freechips.rocketchip.config.{Field, Config, Parameters} import freechips.rocketchip.diplomacy.{LazyModule} import freechips.rocketchip.devices.debug._ import freechips.rocketchip.subsystem._ +import freechips.rocketchip.system.{SimAXIMem} import freechips.rocketchip.util._ import sifive.blocks.devices.gpio._ @@ -117,17 +118,28 @@ object AddIOCells { /** * Add IO cells to a debug module and name the IO ports. * @param gpios A PSDIO bundle + * @param resetctrlOpt An optional ResetCtrlIO bundle * @param debugOpt An optional DebugIO bundle * @return Returns a tuple3 of (Top-level PSDIO IO; Optional top-level DebugIO IO; a list of IOCell module references) */ - def debug(psd: PSDIO, debugOpt: Option[DebugIO]): (PSDIO, Option[DebugIO], Seq[IOCell]) = { - val (psdPort, psdIOs) = IOCell.generateIOFromSignal(psd, Some("iocell_psd")) - val optTuple = debugOpt.map(d => IOCell.generateIOFromSignal(d, Some("iocell_debug"))) - val debugPortOpt: Option[DebugIO] = optTuple.map(_._1) - val debugIOs: Seq[IOCell] = optTuple.map(_._2).toSeq.flatten + def debug(psd: PSDIO, resetctrlOpt: Option[ResetCtrlIO], debugOpt: Option[DebugIO])(implicit p: Parameters): + (PSDIO, Option[ResetCtrlIO], Option[DebugIO], Seq[IOCell]) = { + val (psdPort, psdIOs) = IOCell.generateIOFromSignal( + psd, Some("iocell_psd"), abstractResetAsAsync = p(GlobalResetSchemeKey).pinIsAsync) + val debugTuple = debugOpt.map(d => + IOCell.generateIOFromSignal(d, Some("iocell_debug"), abstractResetAsAsync = p(GlobalResetSchemeKey).pinIsAsync)) + val debugPortOpt: Option[DebugIO] = debugTuple.map(_._1) + val debugIOs: Seq[IOCell] = debugTuple.map(_._2).toSeq.flatten debugPortOpt.foreach(_.suggestName("debug")) + + val resetctrlTuple = resetctrlOpt.map(d => + IOCell.generateIOFromSignal(d, Some("iocell_resetctrl"), abstractResetAsAsync = p(GlobalResetSchemeKey).pinIsAsync)) + val resetctrlPortOpt: Option[ResetCtrlIO] = resetctrlTuple.map(_._1) + val resetctrlIOs: Seq[IOCell] = resetctrlTuple.map(_._2).toSeq.flatten + resetctrlPortOpt.foreach(_.suggestName("resetctrl")) + psdPort.suggestName("psd") - (psdPort, debugPortOpt, psdIOs ++ debugIOs) + (psdPort, resetctrlPortOpt, debugPortOpt, psdIOs ++ debugIOs ++ resetctrlIOs) } /** @@ -176,29 +188,32 @@ class WithSimNIC extends OverrideIOBinder({ (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: CanHaveMasterAXI4MemPortModuleImp) => system.connectSimAXIMem(); Nil + (system: CanHaveMasterAXI4MemPort with BaseSubsystem) => SimAXIMem.connectMem(system)(system.p); Nil }) // DOC include end: WithSimAXIMem class WithBlackBoxSimMem extends OverrideIOBinder({ - (system: CanHaveMasterAXI4MemPortModuleImp) => { - (system.mem_axi4 zip system.outer.memAXI4Node).foreach { case (io, node) => + (system: CanHaveMasterAXI4MemPort with BaseSubsystem) => { + (system.mem_axi4 zip system.memAXI4Node.in).foreach { case (io, (_, edge)) => val memSize = system.p(ExtMem).get.master.size val lineSize = system.p(CacheBlockBytes) - (io zip node.in).foreach { case (axi4, (_, edge)) => - val mem = Module(new SimDRAM(memSize, lineSize, edge.bundle)) - mem.io.axi <> axi4 - mem.io.clock := system.clock - mem.io.reset := system.reset - } - }; Nil + val mem = Module(new SimDRAM(memSize, lineSize, edge.bundle)) + mem.io.axi <> io + mem.io.clock := system.module.clock + mem.io.reset := system.module.reset + } + Nil } }) class WithSimAXIMMIO extends OverrideIOBinder({ - (system: CanHaveMasterAXI4MMIOPortModuleImp) => system.connectSimAXIMMIO(); Nil + (system: CanHaveMasterAXI4MMIOPort with BaseSubsystem) => SimAXIMem.connectMMIO(system)(system.p); Nil }) class WithDontTouchPorts extends OverrideIOBinder({ @@ -215,7 +230,7 @@ class WithTieOffInterrupts extends OverrideIOBinder({ }) class WithTieOffL2FBusAXI extends OverrideIOBinder({ - (system: CanHaveSlaveAXI4PortModuleImp) => { + (system: CanHaveSlaveAXI4Port with BaseSubsystem) => { system.l2_frontend_bus_axi4.foreach(axi => { axi.tieoff() experimental.DataMirror.directionOf(axi.ar.ready) match { @@ -235,23 +250,28 @@ class WithTieOffL2FBusAXI extends OverrideIOBinder({ class WithTiedOffDebug extends OverrideIOBinder({ (system: HasPeripheryDebugModuleImp) => { - val (psdPort, debugPortOpt, ioCells) = AddIOCells.debug(system.psd, system.debug) + val (psdPort, resetctrlOpt, debugPortOpt, ioCells) = + AddIOCells.debug(system.psd, system.resetctrl, system.debug)(system.p) val harnessFn = (th: chipyard.TestHarness) => { - Debug.tieoffDebug(debugPortOpt, psdPort) + Debug.tieoffDebug(debugPortOpt, resetctrlOpt, Some(psdPort))(system.p) // tieoffDebug doesn't actually tie everything off :/ - debugPortOpt.foreach(_.clockeddmi.foreach({ cdmi => cdmi.dmi.req.bits := DontCare })) + debugPortOpt.foreach { d => + d.clockeddmi.foreach({ cdmi => cdmi.dmi.req.bits := DontCare }) + d.dmactiveAck := DontCare + } Nil } - Seq((Seq(psdPort) ++ debugPortOpt.toSeq, ioCells, Some(harnessFn))) + Seq((Seq(psdPort) ++ resetctrlOpt ++ debugPortOpt.toSeq, Nil, Some(harnessFn))) } }) class WithSimDebug extends OverrideIOBinder({ (system: HasPeripheryDebugModuleImp) => { - val (psdPort, debugPortOpt, ioCells) = AddIOCells.debug(system.psd, system.debug) + val (psdPort, resetctrlPortOpt, debugPortOpt, ioCells) = + AddIOCells.debug(system.psd, system.resetctrl, system.debug)(system.p) val harnessFn = (th: chipyard.TestHarness) => { val dtm_success = Wire(Bool()) - Debug.connectDebug(debugPortOpt, psdPort, th.clock, th.harnessReset, dtm_success)(system.p) + Debug.connectDebug(debugPortOpt, resetctrlPortOpt, psdPort, th.clock, th.harnessReset, dtm_success)(system.p) when (dtm_success) { th.success := true.B } th.dutReset := th.harnessReset | debugPortOpt.map { debug => AsyncResetReg(debug.ndreset).asBool }.getOrElse(false.B) Nil diff --git a/generators/chipyard/src/main/scala/Subsystem.scala b/generators/chipyard/src/main/scala/Subsystem.scala index 96443a9f..8fe0871b 100644 --- a/generators/chipyard/src/main/scala/Subsystem.scala +++ b/generators/chipyard/src/main/scala/Subsystem.scala @@ -52,26 +52,20 @@ trait HasChipyardTiles extends HasTiles // TODO: investigate why val tiles = allTilesInfo.sortWith(_._1.hartId < _._1.hartId).map { case (param, crossing) => { - val (tile, rocketLogicalTree) = param match { + + val tile = param match { case r: RocketTileParams => { - val t = LazyModule(new RocketTile(r, crossing, PriorityMuxHartIdFromSeq(rocketTileParams), logicalTreeNode)) - (t, t.rocketLogicalTree) + LazyModule(new RocketTile(r, crossing, PriorityMuxHartIdFromSeq(rocketTileParams), logicalTreeNode)) } case b: BoomTileParams => { - val t = LazyModule(new BoomTile(b, crossing, PriorityMuxHartIdFromSeq(boomTileParams), logicalTreeNode)) - (t, t.rocketLogicalTree) // TODO FIX rocketLogicalTree is not a member of the superclass, both child classes define it separately + LazyModule(new BoomTile(b, crossing, PriorityMuxHartIdFromSeq(boomTileParams), logicalTreeNode)) } case a: ArianeTileParams => { - val t = LazyModule(new ArianeTile(a, crossing, PriorityMuxHartIdFromSeq(arianeTileParams), logicalTreeNode)) - (t, t.rocketLogicalTree) // TODO FIX rocketLogicalTree is not a member of the superclass, both child classes define it separately + LazyModule(new ArianeTile(a, crossing, PriorityMuxHartIdFromSeq(arianeTileParams), logicalTreeNode)) } } connectMasterPortsToSBus(tile, crossing) connectSlavePortsToCBus(tile, crossing) - - def treeNode: RocketTileLogicalTreeNode = new RocketTileLogicalTreeNode(rocketLogicalTree.getOMInterruptTargets) - LogicalModuleTree.add(logicalTreeNode, rocketLogicalTree) - connectInterrupts(tile, debugOpt, clintOpt, plicOpt) tile diff --git a/generators/chipyard/src/main/scala/System.scala b/generators/chipyard/src/main/scala/System.scala index f18a2068..6d99ca6a 100644 --- a/generators/chipyard/src/main/scala/System.scala +++ b/generators/chipyard/src/main/scala/System.scala @@ -38,8 +38,5 @@ class System(implicit p: Parameters) extends Subsystem class SystemModule[+L <: System](_outer: L) extends SubsystemModuleImp(_outer) with HasRTCModuleImp with HasExtInterruptsModuleImp - with CanHaveMasterAXI4MemPortModuleImp - with CanHaveMasterAXI4MMIOPortModuleImp - with CanHaveSlaveAXI4PortModuleImp with HasPeripheryBootROMModuleImp with DontTouch diff --git a/generators/chipyard/src/main/scala/TestHarness.scala b/generators/chipyard/src/main/scala/TestHarness.scala index 4aaef747..a82d3a33 100644 --- a/generators/chipyard/src/main/scala/TestHarness.scala +++ b/generators/chipyard/src/main/scala/TestHarness.scala @@ -25,9 +25,8 @@ class TestHarness(implicit val p: Parameters) extends Module { val dut = p(BuildTop)(p) io.success := false.B - // dutReset can be overridden via a harnessFunction, but by default it is just reset - val dutReset = Wire(Bool()) - dutReset := reset + // dutReset assignment can be overridden via a harnessFunction, but by default it is just reset + val dutReset = WireDefault(if (p(GlobalResetSchemeKey).pinIsAsync) reset.asAsyncReset else reset) dut.harnessFunctions.foreach(_(this)) diff --git a/generators/chipyard/src/main/scala/TestSuites.scala b/generators/chipyard/src/main/scala/TestSuites.scala index 7d901c62..9fdef05a 100644 --- a/generators/chipyard/src/main/scala/TestSuites.scala +++ b/generators/chipyard/src/main/scala/TestSuites.scala @@ -5,8 +5,7 @@ import scala.collection.mutable.{LinkedHashSet} import freechips.rocketchip.subsystem.{RocketTilesKey} import freechips.rocketchip.tile.{XLen} import freechips.rocketchip.config.{Parameters} -import freechips.rocketchip.util.{GeneratorApp} -import freechips.rocketchip.system.{TestGeneration, RegressionTestSuite} +import freechips.rocketchip.system.{TestGeneration, RegressionTestSuite, RocketTestSuite} import boom.common.{BoomTilesKey} import ariane.{ArianeTilesKey} @@ -56,10 +55,13 @@ object RegressionTestSuites /** * Helper functions to add BOOM or Rocket tests */ -object TestSuiteHelper +class TestSuiteHelper { import freechips.rocketchip.system.DefaultTestSuites._ import RegressionTestSuites._ + val suites = collection.mutable.ListMap[String, RocketTestSuite]() + def addSuite(s: RocketTestSuite) { suites += (s.makeTargetName -> s) } + def addSuites(s: Seq[RocketTestSuite]) { s.foreach(addSuite) } /** * Add BOOM tests (asm, bmark, regression) @@ -72,33 +74,33 @@ object TestSuiteHelper val env = if (vm) List("p","v") else List("p") coreParams.fpu foreach { case cfg => if (xlen == 32) { - TestGeneration.addSuites(env.map(rv32uf)) + addSuites(env.map(rv32uf)) if (cfg.fLen >= 64) { - TestGeneration.addSuites(env.map(rv32ud)) + addSuites(env.map(rv32ud)) } } else if (cfg.fLen >= 64) { - TestGeneration.addSuites(env.map(rv64ud)) - TestGeneration.addSuites(env.map(rv64uf)) - TestGeneration.addSuite(rv32udBenchmarks) + addSuites(env.map(rv64ud)) + addSuites(env.map(rv64uf)) + addSuite(rv32udBenchmarks) } } if (coreParams.useAtomics) { if (tileParams.dcache.flatMap(_.scratch).isEmpty) { - TestGeneration.addSuites(env.map(if (xlen == 64) rv64ua else rv32ua)) + addSuites(env.map(if (xlen == 64) rv64ua else rv32ua)) } else { - TestGeneration.addSuites(env.map(if (xlen == 64) rv64uaSansLRSC else rv32uaSansLRSC)) + addSuites(env.map(if (xlen == 64) rv64uaSansLRSC else rv32uaSansLRSC)) } } - if (coreParams.useCompressed) TestGeneration.addSuites(env.map(if (xlen == 64) rv64uc else rv32uc)) + 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) - TestGeneration.addSuites(rvi.map(_("p"))) - TestGeneration.addSuites(rvu.map(_("p"))) - TestGeneration.addSuites((if (vm) List("v") else List()).flatMap(env => rvu.map(_(env)))) - TestGeneration.addSuite(benchmarks) - TestGeneration.addSuite(new RegressionTestSuite(if (xlen == 64) rv64RegrTestNames else rv32RegrTestNames)) + 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)) } } @@ -113,31 +115,31 @@ object TestSuiteHelper val env = if (vm) List("p","v") else List("p") coreParams.fpu foreach { case cfg => if (xlen == 32) { - TestGeneration.addSuites(env.map(rv32uf)) + addSuites(env.map(rv32uf)) if (cfg.fLen >= 64) - TestGeneration.addSuites(env.map(rv32ud)) + addSuites(env.map(rv32ud)) } else { - TestGeneration.addSuite(rv32udBenchmarks) - TestGeneration.addSuites(env.map(rv64uf)) + addSuite(rv32udBenchmarks) + addSuites(env.map(rv64uf)) if (cfg.fLen >= 64) - TestGeneration.addSuites(env.map(rv64ud)) + addSuites(env.map(rv64ud)) } } if (coreParams.useAtomics) { if (tileParams.dcache.flatMap(_.scratch).isEmpty) - TestGeneration.addSuites(env.map(if (xlen == 64) rv64ua else rv32ua)) + addSuites(env.map(if (xlen == 64) rv64ua else rv32ua)) else - TestGeneration.addSuites(env.map(if (xlen == 64) rv64uaSansLRSC else rv32uaSansLRSC)) + addSuites(env.map(if (xlen == 64) rv64uaSansLRSC else rv32uaSansLRSC)) } - if (coreParams.useCompressed) TestGeneration.addSuites(env.map(if (xlen == 64) rv64uc else rv32uc)) + 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) - TestGeneration.addSuites(rvi.map(_("p"))) - TestGeneration.addSuites((if (vm) List("v") else List()).flatMap(env => rvu.map(_(env)))) - TestGeneration.addSuite(benchmarks) - TestGeneration.addSuite(new RegressionTestSuite(if (xlen == 64) rv64RegrTestNames else rv32RegrTestNames)) + 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)) } } @@ -152,32 +154,31 @@ object TestSuiteHelper val env = if (vm) List("p","v") else List("p") coreParams.fpu foreach { case cfg => if (xlen == 32) { - TestGeneration.addSuites(env.map(rv32uf)) + addSuites(env.map(rv32uf)) if (cfg.fLen >= 64) - TestGeneration.addSuites(env.map(rv32ud)) + addSuites(env.map(rv32ud)) } else { - TestGeneration.addSuite(rv32udBenchmarks) - TestGeneration.addSuites(env.map(rv64uf)) + addSuite(rv32udBenchmarks) + addSuites(env.map(rv64uf)) if (cfg.fLen >= 64) - TestGeneration.addSuites(env.map(rv64ud)) + addSuites(env.map(rv64ud)) } } if (coreParams.useAtomics) { if (tileParams.dcache.flatMap(_.scratch).isEmpty) - TestGeneration.addSuites(env.map(if (xlen == 64) rv64ua else rv32ua)) + addSuites(env.map(if (xlen == 64) rv64ua else rv32ua)) else - TestGeneration.addSuites(env.map(if (xlen == 64) rv64uaSansLRSC else rv32uaSansLRSC)) + addSuites(env.map(if (xlen == 64) rv64uaSansLRSC else rv32uaSansLRSC)) } - if (coreParams.useCompressed) TestGeneration.addSuites(env.map(if (xlen == 64) rv64uc else rv32uc)) + 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) - TestGeneration.addSuites(rvi.map(_("p"))) - TestGeneration.addSuites((if (vm) List("v") else List()).flatMap(env => rvu.map(_(env)))) - TestGeneration.addSuite(benchmarks) - TestGeneration.addSuite(new RegressionTestSuite(if (xlen == 64) rv64RegrTestNames else rv32RegrTestNames)) + 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)) } } - } diff --git a/generators/chipyard/src/main/scala/stage/ChipyardAnnotations.scala b/generators/chipyard/src/main/scala/stage/ChipyardAnnotations.scala new file mode 100644 index 00000000..dfee1596 --- /dev/null +++ b/generators/chipyard/src/main/scala/stage/ChipyardAnnotations.scala @@ -0,0 +1,20 @@ +// See LICENSE for license details. +// Based on Rocket Chip's stage implementation + +package chipyard.stage + +import freechips.rocketchip.stage.ConfigsAnnotation +import firrtl.options.{HasShellOptions, ShellOption} + +/** This hijacks the existing ConfigAnnotation to accept the legacy _-delimited format */ +private[stage] object UnderscoreDelimitedConfigsAnnotation extends HasShellOptions { + override val options = Seq( + new ShellOption[String]( + longOption = "legacy-configs", + toAnnotationSeq = a => Seq(new ConfigsAnnotation(a.split("_"))), + helpText = "A string of underscore-delimited configs (configs have decreasing precendence from left to right).", + shortOption = Some("LC") + ) + ) +} + diff --git a/generators/chipyard/src/main/scala/stage/ChipyardCli.scala b/generators/chipyard/src/main/scala/stage/ChipyardCli.scala new file mode 100644 index 00000000..7d293c36 --- /dev/null +++ b/generators/chipyard/src/main/scala/stage/ChipyardCli.scala @@ -0,0 +1,15 @@ +// See LICENSE for license details. +// Based on Rocket Chip's stage implementation + +package chipyard.stage + +import firrtl.options.Shell + +trait ChipyardCli { this: Shell => + + parser.note("Chipyard Generator Options") + Seq( + UnderscoreDelimitedConfigsAnnotation + ) + .foreach(_.addOptions(parser)) +} diff --git a/generators/chipyard/src/main/scala/stage/ChipyardStage.scala b/generators/chipyard/src/main/scala/stage/ChipyardStage.scala new file mode 100644 index 00000000..a24afd43 --- /dev/null +++ b/generators/chipyard/src/main/scala/stage/ChipyardStage.scala @@ -0,0 +1,36 @@ +// See LICENSE for license details. +// Based on Rocket Chip's stage implementation + +package chipyard.stage + +import chisel3.stage.{ChiselCli, ChiselStage} +import firrtl.options.PhaseManager.PhaseDependency +import firrtl.options.{Phase, PreservesAll, Shell} +import firrtl.stage.FirrtlCli +import freechips.rocketchip.stage.RocketChipCli +import freechips.rocketchip.system.RocketChipStage + +import firrtl.options.{Phase, PhaseManager, PreservesAll, Shell, Stage, StageError, StageMain} +import firrtl.options.phases.DeletedWrapper + +class ChipyardStage extends ChiselStage with PreservesAll[Phase] { + override val shell = new Shell("chipyard") with ChipyardCli with RocketChipCli with ChiselCli with FirrtlCli + override val targets: Seq[PhaseDependency] = Seq( + classOf[freechips.rocketchip.stage.phases.Checks], + classOf[freechips.rocketchip.stage.phases.TransformAnnotations], + classOf[freechips.rocketchip.stage.phases.PreElaboration], + classOf[chisel3.stage.phases.Checks], + classOf[chisel3.stage.phases.Elaborate], + classOf[freechips.rocketchip.stage.phases.GenerateROMs], + classOf[chisel3.stage.phases.AddImplicitOutputFile], + classOf[chisel3.stage.phases.AddImplicitOutputAnnotationFile], + classOf[chisel3.stage.phases.MaybeAspectPhase], + classOf[chisel3.stage.phases.Emitter], + classOf[chisel3.stage.phases.Convert], + classOf[freechips.rocketchip.stage.phases.GenerateFirrtlAnnos], + classOf[freechips.rocketchip.stage.phases.AddDefaultTests], + classOf[chipyard.stage.phases.AddDefaultTests], + classOf[chipyard.stage.phases.GenerateTestSuiteMakefrags], + classOf[freechips.rocketchip.stage.phases.GenerateArtefacts], + ) +} diff --git a/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala b/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala new file mode 100644 index 00000000..277d04b5 --- /dev/null +++ b/generators/chipyard/src/main/scala/stage/phases/AddDefaultTests.scala @@ -0,0 +1,62 @@ +// See LICENSE for license details. +// Based on Rocket Chip's stage implementation + +package chipyard.stage.phases + +import scala.util.Try +import scala.collection.mutable + +import chipsalliance.rocketchip.config.Parameters +import chisel3.stage.phases.Elaborate +import firrtl.AnnotationSeq +import firrtl.annotations.{Annotation, NoTargetAnnotation} +import firrtl.options.{Phase, PreservesAll} +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.util.HasRocketChipStageUtils + +import chipyard.TestSuiteHelper + +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). + override val prerequisites = Seq( + classOf[freechips.rocketchip.stage.phases.GenerateFirrtlAnnos], + classOf[freechips.rocketchip.stage.phases.AddDefaultTests]) + override val dependents = Seq(classOf[freechips.rocketchip.stage.phases.GenerateTestSuiteMakefrags]) + + private def addTestSuiteAnnotations(implicit p: Parameters): Seq[Annotation] = { + val annotations = mutable.ArrayBuffer[Annotation]() + val suiteHelper = new TestSuiteHelper + suiteHelper.addRocketTestSuites + suiteHelper.addBoomTestSuites + suiteHelper.addArianeTestSuites + + // 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 + } + + + override def transform(annotations: AnnotationSeq): AnnotationSeq = { + val (testSuiteAnnos, oAnnos) = annotations.partition { + case RocketTestSuiteAnnotation(_) => true + case o => false + } + implicit val p = getConfig(view[RocketChipOptions](annotations).configNames.get).toInstance + addTestSuiteAnnotations ++ oAnnos + } +} diff --git a/generators/chipyard/src/main/scala/stage/phases/GenerateTestSuiteMakefrags.scala b/generators/chipyard/src/main/scala/stage/phases/GenerateTestSuiteMakefrags.scala new file mode 100644 index 00000000..76f99ab7 --- /dev/null +++ b/generators/chipyard/src/main/scala/stage/phases/GenerateTestSuiteMakefrags.scala @@ -0,0 +1,49 @@ +// See LICENSE for license details. +// Based on Rocket Chip's stage implementation + +package chipyard.stage.phases + +import scala.collection.mutable + +import firrtl.AnnotationSeq +import firrtl.annotations.{Annotation, NoTargetAnnotation} +import firrtl.options.{Phase, PreservesAll, StageOptions, Unserializable} +import firrtl.options.Viewer.view +import freechips.rocketchip.stage.RocketChipOptions +import freechips.rocketchip.stage.phases.{RocketTestSuiteAnnotation} +import freechips.rocketchip.system.TestGeneration +import freechips.rocketchip.util.HasRocketChipStageUtils + +trait MakefragSnippet { self: Annotation => + def toMakefrag: String +} + +case class CustomMakefragSnippet(val toMakefrag: String) extends NoTargetAnnotation with MakefragSnippet with Unserializable + +/** Generates a make script to run tests in [[RocketTestSuiteAnnotation]]. */ +class GenerateTestSuiteMakefrags extends Phase with PreservesAll[Phase] with HasRocketChipStageUtils { + + // Our annotations tend not to be serializable, but are not marked as such. + override val prerequisites = Seq(classOf[freechips.rocketchip.stage.phases.GenerateFirrtlAnnos], + classOf[chipyard.stage.phases.AddDefaultTests]) + + override def transform(annotations: AnnotationSeq): AnnotationSeq = { + val targetDir = view[StageOptions](annotations).targetDir + val fileName = s"${view[RocketChipOptions](annotations).longName.get}.d" + + val makefragBuilder = new mutable.StringBuilder() + val outputAnnotations = annotations.flatMap { + case RocketTestSuiteAnnotation(tests) => + // Unfortunately the gen method of TestGeneration is rocketchip package + // private, so we either have to copy code in or use the stateful form + TestGeneration.addSuites(tests) + None + case a: MakefragSnippet => + makefragBuilder :+ ("\n" + a.toMakefrag) + None + case a => Some(a) + } + writeOutputFile(targetDir, fileName, TestGeneration.generateMakeFrag ++ makefragBuilder.toString) + outputAnnotations + } +} diff --git a/generators/firechip/src/main/scala/BridgeBinders.scala b/generators/firechip/src/main/scala/BridgeBinders.scala index bd19ee98..043f1f4e 100644 --- a/generators/firechip/src/main/scala/BridgeBinders.scala +++ b/generators/firechip/src/main/scala/BridgeBinders.scala @@ -8,7 +8,7 @@ import chisel3.experimental.annotate import freechips.rocketchip.config.{Field, Config, Parameters} import freechips.rocketchip.diplomacy.{LazyModule} import freechips.rocketchip.devices.debug.{Debug, HasPeripheryDebugModuleImp} -import freechips.rocketchip.subsystem.{CanHaveMasterAXI4MemPortModuleImp, HasExtInterruptsModuleImp} +import freechips.rocketchip.subsystem.{CanHaveMasterAXI4MemPort, HasExtInterruptsModuleImp, BaseSubsystem} import freechips.rocketchip.tile.{RocketTile} import sifive.blocks.devices.uart.HasPeripheryUARTModuleImp import sifive.blocks.devices.gpio.{HasPeripheryGPIOModuleImp} @@ -56,19 +56,17 @@ class WithBlockDeviceBridge extends OverrideIOBinder({ class WithFASEDBridge extends OverrideIOBinder({ - (system: CanHaveMasterAXI4MemPortModuleImp) => { + (system: CanHaveMasterAXI4MemPort with BaseSubsystem) => { implicit val p = system.p - (system.mem_axi4 zip system.outer.memAXI4Node).flatMap({ case (io, node) => - (io zip node.in).map({ case (axi4Bundle, (_, edge)) => - val nastiKey = NastiParameters(axi4Bundle.r.bits.data.getWidth, - axi4Bundle.ar.bits.addr.getWidth, - axi4Bundle.ar.bits.id.getWidth) - FASEDBridge(system.clock, axi4Bundle, system.reset.toBool, - CompleteConfig(p(firesim.configs.MemModelKey), - nastiKey, - Some(AXI4EdgeSummary(edge)), - Some(MainMemoryConsts.globalName))) - }) + (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))) }) Nil } @@ -116,9 +114,12 @@ class WithTiedOffSystemGPIO extends OverrideIOBinder({ class WithTiedOffSystemDebug extends OverrideIOBinder({ (system: HasPeripheryDebugModuleImp) => { - Debug.tieoffDebug(system.debug, system.psd) + Debug.tieoffDebug(system.debug, system.resetctrl, Some(system.psd))(system.p) // tieoffDebug doesn't actually tie everything off :/ - system.debug.foreach(_.clockeddmi.foreach({ cdmi => cdmi.dmi.req.bits := DontCare })) + system.debug.foreach { d => + d.clockeddmi.foreach({ cdmi => cdmi.dmi.req.bits := DontCare }) + d.dmactiveAck := DontCare + } Nil } }) diff --git a/generators/firechip/src/main/scala/FireSim.scala b/generators/firechip/src/main/scala/FireSim.scala index fc65f136..923e1cd1 100644 --- a/generators/firechip/src/main/scala/FireSim.scala +++ b/generators/firechip/src/main/scala/FireSim.scala @@ -34,14 +34,24 @@ class FireSim(implicit val p: Parameters) extends RawModule { val reset = WireInit(false.B) withClockAndReset(clock, reset) { // Instantiate multiple instances of the DUT to implement supernode - val targets = Seq.fill(p(NumNodes))(p(BuildSystem)(p)) + val targets = Seq.fill(p(NumNodes)) { + // It's not a RC bump without some hacks... + // Copy the AsyncClockGroupsKey to generate a fresh node on each + // instantiation of the dut, otherwise the initial instance will be + // reused across each node + import freechips.rocketchip.subsystem.AsyncClockGroupsKey + val lazyModule = p(BuildSystem)(p.alterPartial({ + case AsyncClockGroupsKey => p(AsyncClockGroupsKey).copy + })) + (lazyModule, Module(lazyModule.module)) + } val peekPokeBridge = PeekPokeBridge(clock, reset) // A Seq of partial functions that will instantiate the right bridge only - // if that Mixin trait is present in the target's class instance + // if that Mixin trait is present in the target's LazyModule class instance // // Apply each partial function to each DUT instance - for ((target) <- targets) { - p(IOBinders).values.map(_(target)) + for ((lazyModule, module) <- targets) { + p(IOBinders).values.foreach(f => f(lazyModule) ++ f(module)) NodeIdx.increment() } } diff --git a/generators/firechip/src/main/scala/FireSimMulticlockPOC.scala b/generators/firechip/src/main/scala/FireSimMulticlockPOC.scala index b16f99c7..fdc2939f 100644 --- a/generators/firechip/src/main/scala/FireSimMulticlockPOC.scala +++ b/generators/firechip/src/main/scala/FireSimMulticlockPOC.scala @@ -64,7 +64,7 @@ class WithSingleRationalTileDomain(multiplier: Int, divisor: Int) extends Config class HalfRateUncore extends WithSingleRationalTileDomain(2,1) class WithFiresimMulticlockTop extends Config((site, here, up) => { - case BuildSystem => (p: Parameters) => Module(LazyModule(new FiresimMulticlockTop()(p)).suggestName("system").module) + case BuildSystem => (p: Parameters) => LazyModule(new FiresimMulticlockTop()(p)).suggestName("system") }) // Complete Config @@ -88,16 +88,19 @@ class FireSimMulticlockPOC(implicit val p: Parameters) extends RawModule { val reset = WireInit(false.B) withClockAndReset(refClock, reset) { // Instantiate multiple instances of the DUT to implement supernode - val targets = Seq.fill(p(NumNodes))(p(BuildSystem)(p)) + val targets = Seq.fill(p(NumNodes)) { + val lazyModule = p(BuildSystem)(p) + (lazyModule, Module(lazyModule.module)) + } val peekPokeBridge = PeekPokeBridge(refClock, reset) // A Seq of partial functions that will instantiate the right bridge only // if that Mixin trait is present in the target's class instance // // Apply each partial function to each DUT instance - for ((target) <- targets) { - p(IOBinders).values.map(_(target)) + for ((lazyModule, module) <- targets) { + p(IOBinders).values.foreach(f => f(lazyModule) ++ f(module)) } - targets.collect({ case t: HasAdditionalClocks => t.clocks := clockBridge.io.clocks }) + targets.collect({ case (_, t: HasAdditionalClocks) => t.clocks := clockBridge.io.clocks }) } } diff --git a/generators/firechip/src/main/scala/Generator.scala b/generators/firechip/src/main/scala/Generator.scala index 18aeefc8..852b9fbd 100644 --- a/generators/firechip/src/main/scala/Generator.scala +++ b/generators/firechip/src/main/scala/Generator.scala @@ -9,7 +9,7 @@ import chisel3.internal.firrtl.{Circuit, Port} import freechips.rocketchip.diplomacy.{ValName, AutoBundle} import freechips.rocketchip.devices.debug.DebugIO -import freechips.rocketchip.util.{HasGeneratorUtilities, ParsedInputNames, ElaborationArtefacts} +import midas.rocketchip.util.{HasGeneratorUtilities, ParsedInputNames, ElaborationArtefacts} import freechips.rocketchip.system.DefaultTestSuites._ import freechips.rocketchip.system.{TestGeneration, RegressionTestSuite} import freechips.rocketchip.config.Parameters @@ -24,9 +24,11 @@ import chipyard.TestSuiteHelper trait HasTestSuites { def addTestSuites(targetName: String, params: Parameters) { - TestSuiteHelper.addRocketTestSuites(params) - TestSuiteHelper.addBoomTestSuites(params) - TestSuiteHelper.addArianeTestSuites(params) + val suiteHelper = new TestSuiteHelper + suiteHelper.addRocketTestSuites(params) + suiteHelper.addBoomTestSuites(params) + suiteHelper.addArianeTestSuites(params) + TestGeneration.addSuites(suiteHelper.suites.values.toSeq) TestGeneration.addSuite(FastBlockdevTests) TestGeneration.addSuite(SlowBlockdevTests) if (!targetName.contains("NoNIC")) @@ -47,7 +49,7 @@ trait IsFireSimGeneratorLike extends HasFireSimGeneratorUtilities with HasTestSu /** Output software test Makefrags, which provide targets for integration testing. */ def generateTestSuiteMakefrags { addTestSuites(names.topModuleClass, targetParams) - writeOutputFile(s"$longName.d", TestGeneration.generateMakefrag) // Subsystem-specific test suites + writeOutputFile(s"$longName.d", TestGeneration.generateMakeFrag) // Subsystem-specific test suites } // Output miscellaneous files produced as a side-effect of elaboration @@ -68,12 +70,3 @@ object FireSimGenerator extends App with IsFireSimGeneratorLike { generateTestSuiteMakefrags generateArtefacts } - -// For now, provide a separate generator app when not specifically building for FireSim -object Generator extends freechips.rocketchip.util.GeneratorApp with HasTestSuites { - override lazy val longName = names.topModuleProject + "." + names.topModuleClass + "." + names.configs - generateFirrtl - generateAnno - generateTestSuiteMakefrags - generateArtefacts -} diff --git a/generators/firechip/src/main/scala/TargetConfigs.scala b/generators/firechip/src/main/scala/TargetConfigs.scala index 04d9a8f6..63199c0e 100644 --- a/generators/firechip/src/main/scala/TargetConfigs.scala +++ b/generators/firechip/src/main/scala/TargetConfigs.scala @@ -41,7 +41,7 @@ class WithBootROM extends Config((site, here, up) => { }) class WithPeripheryBusFrequency(freq: BigInt) extends Config((site, here, up) => { - case PeripheryBusKey => up(PeripheryBusKey).copy(frequency=freq) + case PeripheryBusKey => up(PeripheryBusKey).copy(dtsFrequency = Some(freq)) }) diff --git a/generators/firechip/src/test/scala/ScalaTestSuite.scala b/generators/firechip/src/test/scala/ScalaTestSuite.scala index 83d57e24..68797432 100644 --- a/generators/firechip/src/test/scala/ScalaTestSuite.scala +++ b/generators/firechip/src/test/scala/ScalaTestSuite.scala @@ -137,7 +137,7 @@ abstract class FireSimTestSuite( } class RocketF1Tests extends FireSimTestSuite("FireSim", "DDR3FRFCFSLLC4MB_FireSimQuadRocketConfig", "WithSynthAsserts_BaseF1Config") -class BoomF1Tests extends FireSimTestSuite("FireSim", "DDR3FRFCFSLLC4MB_FireSimBoomConfig", "BaseF1Config") +class BoomF1Tests extends FireSimTestSuite("FireSim", "DDR3FRFCFSLLC4MB_FireSimLargeBoomConfig", "BaseF1Config") class RocketNICF1Tests extends FireSimTestSuite("FireSim", "WithNIC_DDR3FRFCFSLLC4MB_FireSimRocketConfig", "BaseF1Config") { runSuite("verilator")(NICLoopbackTests) } diff --git a/generators/hwacha b/generators/hwacha index ef5e5196..2706502d 160000 --- a/generators/hwacha +++ b/generators/hwacha @@ -1 +1 @@ -Subproject commit ef5e5196b685536890396a08a9f5024eb8b7928e +Subproject commit 2706502daf862c9a7a39126eb7e7209eaf984f76 diff --git a/generators/icenet b/generators/icenet index b1f957e6..4522a397 160000 --- a/generators/icenet +++ b/generators/icenet @@ -1 +1 @@ -Subproject commit b1f957e6eb022c662f0fb33c7ddfbddc686bfde5 +Subproject commit 4522a3979be092c4221f186bdd93bf330fdca134 diff --git a/generators/rocket-chip b/generators/rocket-chip index 4f0cdea8..9b1907ea 160000 --- a/generators/rocket-chip +++ b/generators/rocket-chip @@ -1 +1 @@ -Subproject commit 4f0cdea85c8a2b849fd582ccc8497892001d06b0 +Subproject commit 9b1907eacbeb268d47e204e3de1818823d605ba4 diff --git a/generators/sifive-blocks b/generators/sifive-blocks index 1bc0ef18..3e35a94d 160000 --- a/generators/sifive-blocks +++ b/generators/sifive-blocks @@ -1 +1 @@ -Subproject commit 1bc0ef18d6653f1133cb9293e8ee8620f9417c78 +Subproject commit 3e35a94d46d88506d5b14b2c34f05b8651844452 diff --git a/generators/testchipip b/generators/testchipip index d06d7c7d..b8d6f210 160000 --- a/generators/testchipip +++ b/generators/testchipip @@ -1 +1 @@ -Subproject commit d06d7c7dc274420a5fc5600ba8bdb2003cc9b0cd +Subproject commit b8d6f2101947e9f80f896dbaa5802946e2a3b9f0 diff --git a/generators/tracegen/src/main/scala/System.scala b/generators/tracegen/src/main/scala/System.scala index 18307678..cb5d0af8 100644 --- a/generators/tracegen/src/main/scala/System.scala +++ b/generators/tracegen/src/main/scala/System.scala @@ -49,4 +49,3 @@ class TraceGenSystem(implicit p: Parameters) extends BaseSubsystem class TraceGenSystemModuleImp(outer: TraceGenSystem) extends BaseSubsystemModuleImp(outer) with HasTraceGenTilesModuleImp - with CanHaveMasterAXI4MemPortModuleImp diff --git a/project/build.properties b/project/build.properties index c0bab049..8522443d 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.2.8 +sbt.version=1.3.2 diff --git a/project/plugins.sbt b/project/plugins.sbt index 3321d801..a30249c9 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -14,5 +14,6 @@ addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.6") addSbtPlugin("com.simplytyped" % "sbt-antlr4" % "0.8.1") addSbtPlugin("com.github.gseitz" % "sbt-protobuf" % "0.6.3") addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.9.4") +addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.6.1") libraryDependencies += "com.github.os72" % "protoc-jar" % "3.5.1.1" diff --git a/sims/firesim b/sims/firesim index 7c121894..f82e115c 160000 --- a/sims/firesim +++ b/sims/firesim @@ -1 +1 @@ -Subproject commit 7c121894e97f32b2fdaf719673c2a2f2ecbe5312 +Subproject commit f82e115c6641c5fe33f756abeb8093f64b0d0a80 diff --git a/tools/barstools b/tools/barstools index db677636..e230e8cf 160000 --- a/tools/barstools +++ b/tools/barstools @@ -1 +1 @@ -Subproject commit db6776367c7a8f4850266d72f81cd4c90561731a +Subproject commit e230e8cf3f7c0bc3c958cab22c5d90d195ca6b01 diff --git a/tools/chisel3 b/tools/chisel3 index d1a61262..7a343dce 160000 --- a/tools/chisel3 +++ b/tools/chisel3 @@ -1 +1 @@ -Subproject commit d1a61262630b5ea77ebe21a453df9645cb7e4185 +Subproject commit 7a343dce95a370f6cb7b9cf80e0694ac82dc94f8 diff --git a/tools/firrtl b/tools/firrtl index f738fbe8..eb637777 160000 --- a/tools/firrtl +++ b/tools/firrtl @@ -1 +1 @@ -Subproject commit f738fbe8667ed6b76ec00a15960b9c3a42b8654a +Subproject commit eb637777e3c4d77435cfd13358c521ed1b766ba8 diff --git a/variables.mk b/variables.mk index 4953c968..c851cccf 100644 --- a/variables.mk +++ b/variables.mk @@ -38,43 +38,18 @@ ifeq ($(SUB_PROJECT),chipyard) TB ?= TestDriver TOP ?= ChipTop endif -# for Rocket-chip developers -ifeq ($(SUB_PROJECT),rocketchip) - SBT_PROJECT ?= rocketchip - MODEL ?= TestHarness - VLOG_MODEL ?= TestHarness - MODEL_PACKAGE ?= freechips.rocketchip.system - CONFIG ?= DefaultConfig - CONFIG_PACKAGE ?= freechips.rocketchip.system - GENERATOR_PACKAGE ?= freechips.rocketchip.system - TB ?= TestDriver - TOP ?= ExampleRocketSystem -endif # for Hwacha developers ifeq ($(SUB_PROJECT),hwacha) - SBT_PROJECT ?= hwacha + SBT_PROJECT ?= chipyard MODEL ?= TestHarness VLOG_MODEL ?= TestHarness MODEL_PACKAGE ?= freechips.rocketchip.system CONFIG ?= HwachaConfig CONFIG_PACKAGE ?= hwacha - GENERATOR_PACKAGE ?= hwacha + GENERATOR_PACKAGE ?= chipyard TB ?= TestDriver TOP ?= ExampleRocketSystem endif -# Stand-in firechip variables: -# TODO: need a seperate generator and test harnesses for each target -#ifeq ($(SUB_PROJECT),firechip) -# SBT_PROJECT ?= $(SUB_PROJECT) -# MODEL ?= TestHarness -# VLOG_MODEL ?= TestHarness -# MODEL_PACKAGE ?= freechips.rocketchip.system -# CONFIG ?= FireSimRocketChipConfig -# CONFIG_PACKAGE ?= firesim.firesim -# GENERATOR_PACKAGE ?= firesim.firesim -# TB ?= TestDriver -# TOP ?= FireSimNoNIC -#endif ######################################################################################### # path to rocket-chip and testchipip @@ -87,11 +62,6 @@ CHIPYARD_FIRRTL_DIR = $(base_dir)/tools/firrtl # names of various files needed to compile and run things ######################################################################################### long_name = $(MODEL_PACKAGE).$(MODEL).$(CONFIG) - -# match the long_name to what the specific generator will output -ifeq ($(GENERATOR_PACKAGE),freechips.rocketchip.system) - long_name=$(CONFIG_PACKAGE).$(CONFIG) -endif ifeq ($(GENERATOR_PACKAGE),hwacha) long_name=$(MODEL_PACKAGE).$(CONFIG) endif