diff --git a/Makefrag b/Makefrag
index d4b65209254..f1d8d8efa2e 100644
--- a/Makefrag
+++ b/Makefrag
@@ -6,14 +6,9 @@ endif
MODEL ?= TestHarness
PROJECT ?= freechips.rocketchip.system
CFG_PROJECT ?= $(PROJECT)
-CONFIG ?= $(CFG_PROJECT).DefaultConfig
+CONFIG ?= DefaultConfig
# TODO: For now must match rocketchip.Generator
-comma := ,
-space := $() $()
-splitConfigs := $(subst $(comma), ,$(CONFIG))
-configBases := $(foreach config,$(splitConfigs),$(lastword $(subst ., ,$(config))))
-CONFIG_STR := $(subst $(space),_,$(configBases))
-long_name = $(PROJECT).$(CONFIG_STR)
+long_name = $(PROJECT).$(CONFIG)
VLSI_MEM_GEN ?= $(base_dir)/scripts/vlsi_mem_gen
diff --git a/README.md b/README.md
index f5486623539..7cc69911c9b 100644
--- a/README.md
+++ b/README.md
@@ -284,25 +284,14 @@ Chisel generated Verilog code and its associated C++ code generated by
Verilator.
$ ls $ROCKETCHIP/emulator/generated-src
+ DefaultConfig.dts
+ DefaultConfig.graphml
+ DefaultConfig.json
+ DefaultConfig.memmap.json
freechips.rocketchip.system.DefaultConfig
- freechips.rocketchip.system.DefaultConfig.0x0.0.regmap.json
- freechips.rocketchip.system.DefaultConfig.0x0.1.regmap.json
- freechips.rocketchip.system.DefaultConfig.0x2000000.0.regmap.json
- freechips.rocketchip.system.DefaultConfig.0x40.0.regmap.json
- freechips.rocketchip.system.DefaultConfig.0xc000000.0.regmap.json
- freechips.rocketchip.system.DefaultConfig.anno.json
- freechips.rocketchip.system.DefaultConfig.behav_srams.v
- freechips.rocketchip.system.DefaultConfig.conf
freechips.rocketchip.system.DefaultConfig.d
- freechips.rocketchip.system.DefaultConfig.dts
freechips.rocketchip.system.DefaultConfig.fir
- freechips.rocketchip.system.DefaultConfig.graphml
- freechips.rocketchip.system.DefaultConfig.json
- freechips.rocketchip.system.DefaultConfig.memmap.json
- freechips.rocketchip.system.DefaultConfig.plusArgs
- freechips.rocketchip.system.DefaultConfig.rom.conf
freechips.rocketchip.system.DefaultConfig.v
- TestHarness.anno.json
$ ls $ROCKETCHIP/emulator/generated-src/freechips.rocketchip.system.DefaultConfig
VTestHarness__1.cpp
VTestHarness__2.cpp
@@ -334,7 +323,7 @@ writeback stage, perhaps, because of a instruction cache miss at PC
You can generate synthesizable Verilog with the following commands:
$ cd $ROCKETCHIP/vsim
- $ make verilog CONFIG=freechips.rocketchip.system.DefaultFPGAConfig
+ $ make verilog CONFIG=DefaultFPGAConfig
The Verilog used for the FPGA tools will be generated in
vsim/generated-src. Please proceed further with the directions shown in
@@ -348,7 +337,7 @@ tests and benchmarks in simulation with the following commands
(again assuming you have N cores on your host machine):
$ cd $ROCKETCHIP/vsim
- $ make -jN run CONFIG=freechips.rocketchip.system.DefaultFPGAConfig
+ $ make -jN run CONFIG=DefaultFPGAConfig
The generated output looks similar to those generated from the emulator.
Look into vsim/output/\*.out for the output of the executed assembly
@@ -365,25 +354,15 @@ Now take a look at vsim/generated-src, and the contents of the
Top.DefaultConfig.conf file:
$ cd $ROCKETCHIP/vsim/generated-src
- freechips.rocketchip.system.DefaultConfig
- freechips.rocketchip.system.DefaultConfig.0x0.0.regmap.json
- freechips.rocketchip.system.DefaultConfig.0x0.1.regmap.json
- freechips.rocketchip.system.DefaultConfig.0x2000000.0.regmap.json
- freechips.rocketchip.system.DefaultConfig.0x40.0.regmap.json
- freechips.rocketchip.system.DefaultConfig.0xc000000.0.regmap.json
- freechips.rocketchip.system.DefaultConfig.anno.json
+ DefaultConfig.dts
+ DefaultConfig.graphml
+ DefaultConfig.json
+ DefaultConfig.memmap.json
freechips.rocketchip.system.DefaultConfig.behav_srams.v
freechips.rocketchip.system.DefaultConfig.conf
freechips.rocketchip.system.DefaultConfig.d
- freechips.rocketchip.system.DefaultConfig.dts
freechips.rocketchip.system.DefaultConfig.fir
- freechips.rocketchip.system.DefaultConfig.graphml
- freechips.rocketchip.system.DefaultConfig.json
- freechips.rocketchip.system.DefaultConfig.memmap.json
- freechips.rocketchip.system.DefaultConfig.plusArgs
- freechips.rocketchip.system.DefaultConfig.rom.conf
freechips.rocketchip.system.DefaultConfig.v
- TestHarness.anno.json
$ cat $ROCKETCHIP/vsim/generated-src/*.conf
name data_arrays_0_ext depth 512 width 256 ports mrw mask_gran 8
name tag_array_ext depth 64 width 88 ports mrw mask_gran 22
@@ -416,26 +395,26 @@ tests and benchmarks.
## How can I parameterize my Rocket chip?
By now, you probably figured out that all generated files have a configuration
-name attached, e.g. `freechips.rocketchip.system.DefaultConfig`. Take a look at
-`src/main/scala/system/Configs.scala`. Search for `NSets` and `NWays` defined in
-`BaseConfig`. You can change those numbers to get a Rocket core with different
+name attached, e.g. DefaultConfig. Take a look at
+src/main/scala/system/Configs.scala. Search for NSets and NWays defined in
+BaseConfig. You can change those numbers to get a Rocket core with different
cache parameters. For example, by changing L1I, NWays to 4, you will get
a 32KB 4-way set-associative L1 instruction cache rather than a 16KB 2-way
set-associative L1 instruction cache.
-Towards the end, you can also find that `DefaultSmallConfig` inherits all
-parameters from `BaseConfig` but overrides the same parameters of
-`WithNSmallCores`.
+Towards the end, you can also find that DefaultSmallConfig inherits all
+parameters from BaseConfig but overrides the same parameters of
+WithNSmallCores.
-Now take a look at `vsim/Makefile`. Search for the `CONFIG` variable.
-By default, it is set to `freechips.rocketchip.system.DefaultConfig`. You can also change the
+Now take a look at vsim/Makefile. Search for the CONFIG variable.
+By default, it is set to DefaultConfig. You can also change the
CONFIG variable on the make command line:
$ cd $ROCKETCHIP/vsim
- $ make -jN CONFIG=freechips.rocketchip.system.DefaultSmallConfig run-asm-tests
+ $ make -jN CONFIG=DefaultSmallConfig run-asm-tests
Or, even by defining CONFIG as an environment variable:
- $ export CONFIG=freechips.rocketchip.system.DefaultSmallConfig
+ $ export CONFIG=DefaultSmallConfig
$ make -jN run-asm-tests
This parameterization is one of the many strengths of processor
@@ -452,7 +431,7 @@ you can create your own Configuration(s) and compose them with Config's ++ opera
}
class MyConfig extends Config (new WithNExtInterrupts(16) ++ new DefaultSmallConfig)
-Then you can build as usual with `CONFIG=.MyConfig`.
+Then you can build as usual with CONFIG=MyConfig.
## Debugging with GDB
@@ -471,11 +450,11 @@ For that we need to add a Remote Bit-Bang client to the emulator. We can do so b
To build the emulator with `DefaultConfigRBB` configuration we use the command:
rocket-chip$ cd emulator
- emulator$ CONFIG=freechips.rocketchip.system.DefaultConfigRBB make
+ emulator$ CONFIG=DefaultConfigRBB make
We can also build a debug version capable of generating VCD waveforms using the command:
- emulator$ CONFIG=freechips.rocketchip.system.DefaultConfigRBB make debug
+ emulator$ CONFIG=DefaultConfigRBB make debug
By default the emulator is generated under the name `emulator-freechips.rocketchip.system-DefaultConfigRBB` in the first case and `emulator-freechips.rocketchip.system-DefaultConfigRBB-debug` in the second.
diff --git a/build.sbt b/build.sbt
index dc204983cad..dd06845b7dc 100644
--- a/build.sbt
+++ b/build.sbt
@@ -1,7 +1,9 @@
// See LICENSE.Berkeley for license details.
+import sbt.complete._
import sbt.complete.DefaultParsers._
-import scala.sys.process._
+import xerial.sbt.pack._
+import sys.process._
enablePlugins(PackPlugin)
@@ -14,7 +16,6 @@ lazy val commonSettings = Seq(
scalacOptions ++= Seq("-deprecation","-unchecked","-Xsource:2.11"),
libraryDependencies ++= Seq("org.scala-lang" % "scala-reflect" % scalaVersion.value),
libraryDependencies ++= Seq("org.json4s" %% "json4s-jackson" % "3.6.1"),
- libraryDependencies ++= Seq("org.scalatest" %% "scalatest" % "3.0.8" % "test"),
addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full),
resolvers ++= Seq(
Resolver.sonatypeRepo("snapshots"),
diff --git a/emulator/Makefrag-verilator b/emulator/Makefrag-verilator
index 8011a42aef6..d6423ada0ad 100644
--- a/emulator/Makefrag-verilator
+++ b/emulator/Makefrag-verilator
@@ -10,7 +10,7 @@ verilog = \
$(generated_dir)/%.fir $(generated_dir)/%.d: $(FIRRTL_JAR) $(chisel_srcs) $(bootrom_img)
mkdir -p $(dir $@)
- cd $(base_dir) && $(SBT) "runMain $(PROJECT).Generator -td $(generated_dir) -T $(PROJECT).$(MODEL) -C $(CONFIG)"
+ cd $(base_dir) && $(SBT) "runMain $(PROJECT).Generator $(generated_dir) $(PROJECT) $(MODEL) $(CFG_PROJECT) $(CONFIG)"
%.v %.conf: %.fir $(FIRRTL_JAR)
mkdir -p $(dir $@)
@@ -69,7 +69,7 @@ VERILATOR_FLAGS := --top-module $(MODEL) \
--threads $(VERILATOR_THREADS) -Wno-UNOPTTHREADS \
-Wno-STMTDLY --x-assign unique \
-I$(vsrc) \
- -O3 -CFLAGS "$(CXXFLAGS) -DVERILATOR -DTEST_HARNESS=V$(MODEL) -include $(csrc)/verilator.h -include $(generated_dir)/$(long_name).plusArgs"
+ -O3 -CFLAGS "$(CXXFLAGS) -DVERILATOR -DTEST_HARNESS=V$(MODEL) -include $(csrc)/verilator.h -include $(generated_dir)/$(PROJECT).$(CONFIG).plusArgs"
cppfiles = $(addprefix $(csrc)/, $(addsuffix .cc, $(CXXSRCS)))
headers = $(wildcard $(csrc)/*.h)
diff --git a/regression/Makefile b/regression/Makefile
index 3b660c9ccd5..67983ad9e7f 100644
--- a/regression/Makefile
+++ b/regression/Makefile
@@ -46,22 +46,22 @@ endif
ifeq ($(SUITE),RocketSuiteA)
PROJECT=freechips.rocketchip.system
-CONFIGS=$(PROJECT).DefaultConfig
+CONFIGS=DefaultConfig
endif
ifeq ($(SUITE),RocketSuiteB)
PROJECT=freechips.rocketchip.system
-CONFIGS=$(PROJECT).DefaultBufferlessConfig
+CONFIGS=DefaultBufferlessConfig
endif
ifeq ($(SUITE),RocketSuiteC)
PROJECT=freechips.rocketchip.system
-CONFIGS=$(PROJECT).TinyConfig
+CONFIGS=TinyConfig
endif
ifeq ($(SUITE),UnittestSuite)
PROJECT=freechips.rocketchip.unittest
-CONFIGS=$(PROJECT).AMBAUnitTestConfig $(PROJECT).TLSimpleUnitTestConfig $(PROJECT).TLWidthUnitTestConfig
+CONFIGS=AMBAUnitTestConfig TLSimpleUnitTestConfig TLWidthUnitTestConfig
endif
ifeq ($(SUITE), JtagDtmSuite)
@@ -69,13 +69,13 @@ PROJECT=freechips.rocketchip.system
export JTAG_DTM_ENABLE_SBA ?= off
ifeq ($(JTAG_DTM_ENABLE_SBA), off)
-CONFIGS_32=$(PROJECT).WithJtagDTMSystem,$(PROJECT).DefaultRV32Config
-CONFIGS_64=$(PROJECT).WithJtagDTMSystem,$(PROJECT).DefaultConfig
+CONFIGS_32=WithJtagDTMSystem_DefaultRV32Config
+CONFIGS_64=WithJtagDTMSystem_DefaultConfig
endif
ifeq ($(JTAG_DTM_ENABLE_SBA), on)
-CONFIGS_32=$(PROJECT).WithJtagDTMSystem,$(PROJECT).WithDebugSBASystem,$(PROJECT).DefaultRV32Config
-CONFIGS_64=$(PROJECT).WithJtagDTMSystem,$(PROJECT).WithDebugSBASystem,$(PROJECT).DefaultConfig
+CONFIGS_32=WithJtagDTMSystem_WithDebugSBASystem_DefaultRV32Config
+CONFIGS_64=WithJtagDTMSystem_WithDebugSBASystem_DefaultConfig
endif
CONFIGS += $(CONFIGS_32)
@@ -89,18 +89,18 @@ endif
ifeq ($(SUITE), Miscellaneous)
PROJECT=freechips.rocketchip.system
CONFIGS=\
- $(PROJECT).DefaultSmallConfig \
- $(PROJECT).DualBankConfig \
- $(PROJECT).DualChannelConfig \
- $(PROJECT).DualChannelDualBankConfig \
- $(PROJECT).RoccExampleConfig \
- $(PROJECT).Edge128BitConfig \
- $(PROJECT).Edge32BitConfig \
- $(PROJECT).QuadChannelBenchmarkConfig \
- $(PROJECT).EightChannelConfig \
- $(PROJECT).DualCoreConfig \
- $(PROJECT).MemPortOnlyConfig \
- $(PROJECT).MMIOPortOnlyConfig
+ DefaultSmallConfig \
+ DualBankConfig \
+ DualChannelConfig \
+ DualChannelDualBankConfig \
+ RoccExampleConfig \
+ Edge128BitConfig \
+ Edge32BitConfig \
+ QuadChannelBenchmarkConfig \
+ EightChannelConfig \
+ DualCoreConfig \
+ MemPortOnlyConfig \
+ MMIOPortOnlyConfig
endif
# These are the named regression targets. While it's expected you run them in
diff --git a/src/main/scala/groundtest/Generator.scala b/src/main/scala/groundtest/Generator.scala
index 6279c67b4e3..b3ffeb8616b 100644
--- a/src/main/scala/groundtest/Generator.scala
+++ b/src/main/scala/groundtest/Generator.scala
@@ -2,7 +2,11 @@
package freechips.rocketchip.groundtest
-import firrtl.options.StageMain
-import freechips.rocketchip.system.RocketChipStage
+import freechips.rocketchip.util.GeneratorApp
-object Generator extends StageMain(new RocketChipStage)
+object Generator extends GeneratorApp {
+ generateFirrtl
+ generateAnno
+ generateTestSuiteMakefrags // TODO: Needed only for legacy make targets
+ generateArtefacts
+}
diff --git a/src/main/scala/stage/RocketChipAnnotations.scala b/src/main/scala/stage/RocketChipAnnotations.scala
deleted file mode 100644
index f0c2c1302cf..00000000000
--- a/src/main/scala/stage/RocketChipAnnotations.scala
+++ /dev/null
@@ -1,52 +0,0 @@
-// See LICENSE.SiFive for license details.
-
-package freechips.rocketchip.stage
-
-import chisel3.experimental.BaseModule
-import firrtl.annotations.{Annotation, NoTargetAnnotation}
-import firrtl.options.{HasShellOptions, ShellOption, Unserializable}
-
-sealed trait RocketChipOption extends Unserializable { this: Annotation => }
-
-/* required options */
-
-/** Path to top module class */
-case class TopModuleAnnotation(clazz: Class[_ <: Any]) extends NoTargetAnnotation with RocketChipOption
-private[stage] object TopModuleAnnotation extends HasShellOptions {
- override val options = Seq(
- new ShellOption[String](
- longOption = "top-module",
- toAnnotationSeq = a => Seq(TopModuleAnnotation(Class.forName(a).asInstanceOf[Class[_ <: BaseModule]])),
- helpText = "",
- shortOption = Some("T")
- )
- )
-}
-
-/** Paths to config classes */
-case class ConfigsAnnotation(configNames: Seq[String]) extends NoTargetAnnotation with RocketChipOption
-private[stage] object ConfigsAnnotation extends HasShellOptions {
- override val options = Seq(
- new ShellOption[Seq[String]](
- longOption = "configs",
- toAnnotationSeq = a => Seq(ConfigsAnnotation(a)),
- helpText = "",
- shortOption = Some("C")
- )
- )
-}
-
-/* optional options */
-
-/** Optional base name for generated files' filenames */
-case class OutputBaseNameAnnotation(outputBaseName: String) extends NoTargetAnnotation with RocketChipOption
-private[stage] object OutputBaseNameAnnotation extends HasShellOptions {
- override val options = Seq(
- new ShellOption[String](
- longOption = "name",
- toAnnotationSeq = a => Seq(OutputBaseNameAnnotation(a)),
- helpText = "",
- shortOption = Some("n")
- )
- )
-}
diff --git a/src/main/scala/stage/RocketChipCli.scala b/src/main/scala/stage/RocketChipCli.scala
deleted file mode 100644
index 30becb6ceeb..00000000000
--- a/src/main/scala/stage/RocketChipCli.scala
+++ /dev/null
@@ -1,17 +0,0 @@
-// See LICENSE.SiFive for license details.
-
-package freechips.rocketchip.stage
-
-import firrtl.options.Shell
-
-trait RocketChipCli { this: Shell =>
-
- parser.note("Rocket Chip Compiler Options")
- Seq(
- TopModuleAnnotation,
- ConfigsAnnotation,
- OutputBaseNameAnnotation,
- )
- .foreach(_.addOptions(parser))
-
-}
diff --git a/src/main/scala/stage/RocketChipOptions.scala b/src/main/scala/stage/RocketChipOptions.scala
deleted file mode 100644
index 2fac6a276ff..00000000000
--- a/src/main/scala/stage/RocketChipOptions.scala
+++ /dev/null
@@ -1,41 +0,0 @@
-// See LICENSE.SiFive for license details.
-
-package freechips.rocketchip.stage
-
-class RocketChipOptions private[stage] (
- val topModule: Option[Class[_ <: Any]] = None,
- val configNames: Option[Seq[String]] = None,
- val outputBaseName: Option[String] = None) {
-
- private[stage] def copy(
- topModule: Option[Class[_ <: Any]] = topModule,
- configNames: Option[Seq[String]] = configNames,
- outputBaseName: Option[String] = outputBaseName,
- ): RocketChipOptions = {
-
- new RocketChipOptions(
- topModule=topModule,
- configNames=configNames,
- outputBaseName=outputBaseName,
- )
- }
-
- lazy val topPackage: Option[String] = topModule match {
- case Some(a) => Some(a.getPackage.getName)
- case _ => None
- }
-
- lazy val configClass: Option[String] = configNames match {
- case Some(names) =>
- val classNames = names.map{ n => n.split('.').last }
- Some(classNames.mkString("_"))
- case _ => None
- }
-
- lazy val longName: Option[String] = outputBaseName match {
- case Some(name) => Some(name)
- case _ =>
- if (!topPackage.isEmpty && !configClass.isEmpty) Some(s"${topPackage.get}.${configClass.get}") else None
- }
-}
-
diff --git a/src/main/scala/stage/package.scala b/src/main/scala/stage/package.scala
deleted file mode 100644
index db5b42234d1..00000000000
--- a/src/main/scala/stage/package.scala
+++ /dev/null
@@ -1,24 +0,0 @@
-// See LICENSE.SiFive for license details.
-
-package freechips.rocketchip
-
-import firrtl.AnnotationSeq
-import firrtl.options.OptionsView
-
-package object stage {
-
- implicit object RocketChipOptionsView extends OptionsView[RocketChipOptions] {
-
- def view(annotations: AnnotationSeq): RocketChipOptions = annotations
- .collect { case a: RocketChipOption => a }
- .foldLeft(new RocketChipOptions()){ (c, x) =>
- x match {
- case TopModuleAnnotation(a) => c.copy(topModule = Some(a))
- case ConfigsAnnotation(a) => c.copy(configNames = Some(a))
- case OutputBaseNameAnnotation(a) => c.copy(outputBaseName = Some(a))
- }
- }
-
- }
-
-}
diff --git a/src/main/scala/stage/phases/AddDefaultTests.scala b/src/main/scala/stage/phases/AddDefaultTests.scala
deleted file mode 100644
index 1fdd8b9a44a..00000000000
--- a/src/main/scala/stage/phases/AddDefaultTests.scala
+++ /dev/null
@@ -1,140 +0,0 @@
-// See LICENSE.SiFive for license details.
-
-package freechips.rocketchip.stage.phases
-
-
-import chipsalliance.rocketchip.config.Parameters
-import chisel3.stage.phases.Elaborate
-import firrtl.AnnotationSeq
-import firrtl.annotations.NoTargetAnnotation
-import firrtl.options.{Phase, PreservesAll}
-import firrtl.options.Viewer.view
-import freechips.rocketchip.stage.RocketChipOptions
-import freechips.rocketchip.subsystem.RocketTilesKey
-import freechips.rocketchip.system.{DefaultTestSuites, RegressionTestSuite, RocketTestSuite, TestGeneration}
-import freechips.rocketchip.tile.XLen
-import freechips.rocketchip.util.HasRocketChipStageUtils
-import freechips.rocketchip.system.DefaultTestSuites._
-
-import scala.collection.mutable
-
-/** Annotation that contains a list of [[RocketTestSuite]]s to run */
-case class RocketTestSuiteAnnotation(tests: Seq[RocketTestSuite]) extends NoTargetAnnotation
-
-/** Generates [[RocketTestSuiteAnnotation]] depending on whether the top-module project is part of
- * [[freechips.rocketchip.system]] or not (e.g. for unit tests).
- */
-class AddDefaultTests extends Phase with PreservesAll[Phase] with HasRocketChipStageUtils {
-
- override val prerequisites = Seq(classOf[Checks], classOf[Elaborate])
- override val dependents = Seq(classOf[GenerateTestSuiteMakefrags])
-
- def GenerateDefaultTestSuites(): List[RocketTestSuite] = {
- List(DefaultTestSuites.groundtest64("p"), DefaultTestSuites.emptyBmarks, DefaultTestSuites.singleRegression)
- }
-
- def GenerateSystemTestSuites(annotations: AnnotationSeq): scala.collection.mutable.Buffer[RocketTestSuite] = {
- val params: Parameters = getConfig(view[RocketChipOptions](annotations).configNames.get).toInstance
- val xlen = params(XLen)
- val tests = scala.collection.mutable.Buffer[RocketTestSuite]()
-
- val regressionTests = mutable.LinkedHashSet(
- "rv64ud-v-fcvt",
- "rv64ud-p-fdiv",
- "rv64ud-v-fadd",
- "rv64uf-v-fadd",
- "rv64um-v-mul",
- "rv64mi-p-breakpoint",
- "rv64uc-v-rvc",
- "rv64ud-v-structural",
- "rv64si-p-wfi",
- "rv64um-v-divw",
- "rv64ua-v-lrsc",
- "rv64ui-v-fence_i",
- "rv64ud-v-fcvt_w",
- "rv64uf-v-fmin",
- "rv64ui-v-sb",
- "rv64ua-v-amomax_d",
- "rv64ud-v-move",
- "rv64ud-v-fclass",
- "rv64ua-v-amoand_d",
- "rv64ua-v-amoxor_d",
- "rv64si-p-sbreak",
- "rv64ud-v-fmadd",
- "rv64uf-v-ldst",
- "rv64um-v-mulh",
- "rv64si-p-dirty",
- "rv32mi-p-ma_addr",
- "rv32mi-p-csr",
- "rv32ui-p-sh",
- "rv32ui-p-lh",
- "rv32uc-p-rvc",
- "rv32mi-p-sbreak",
- "rv32ui-p-sll")
-
- // TODO: for now only generate tests for the first core in the first subsystem
- params(RocketTilesKey).headOption.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) {
- tests ++= env.map(rv32uf)
- if (cfg.fLen >= 64)
- tests ++= env.map(rv32ud)
- } else {
- tests += rv32udBenchmarks
- tests ++= env.map(rv64uf)
- if (cfg.fLen >= 64)
- tests ++= env.map(rv64ud)
- }
- }
- if (coreParams.useAtomics) {
- if (tileParams.dcache.flatMap(_.scratch).isEmpty)
- tests ++= env.map(if (xlen == 64) rv64ua else rv32ua)
- else
- tests ++= env.map(if (xlen == 64) rv64uaSansLRSC else rv32uaSansLRSC)
- }
- if (coreParams.useCompressed) tests ++= 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)
-
- tests ++= rvi.map(_ ("p"))
- tests ++= (if (vm) List("v") else List()).flatMap(env => rvu.map(_ (env)))
- tests += benchmarks
-
- /* Filter the regression tests based on what the Rocket Chip configuration supports */
- val extensions = {
- val fd = coreParams.fpu.map {
- case cfg if cfg.fLen >= 64 => "fd"
- case _ => "f"
- }
- val m = coreParams.mulDiv.map { case _ => "m" }
- fd ++ m ++ Seq(if (coreParams.useRVE) Some("e") else Some("i"),
- if (coreParams.useAtomics) Some("a") else None,
- if (coreParams.useCompressed) Some("c") else None)
- .flatten
- .mkString("")
- }
- val re = s"""^rv$xlen[usm][$extensions].+""".r
- regressionTests.retain {
- case re() => true
- case _ => false
- }
- tests += new RegressionTestSuite(regressionTests)
- }
- tests
- }
-
- override def transform(annotations: AnnotationSeq): AnnotationSeq = {
- val ropts = view[RocketChipOptions](annotations)
- val tests = ropts.topPackage.get match {
- case "freechips.rocketchip.system" => GenerateSystemTestSuites(annotations)
- case _ => GenerateDefaultTestSuites()
- }
-
- RocketTestSuiteAnnotation(tests) +: annotations
- }
-
-}
diff --git a/src/main/scala/stage/phases/Checks.scala b/src/main/scala/stage/phases/Checks.scala
deleted file mode 100644
index fbfd8bb757a..00000000000
--- a/src/main/scala/stage/phases/Checks.scala
+++ /dev/null
@@ -1,47 +0,0 @@
-// See LICENSE.SiFive for license details.
-
-package freechips.rocketchip.stage.phases
-
-import firrtl.AnnotationSeq
-import firrtl.annotations.Annotation
-import firrtl.options.{OptionsException, Phase, PreservesAll, TargetDirAnnotation}
-import freechips.rocketchip.stage._
-
-import scala.collection.mutable
-
-/** Checks for the correct type and number of command line arguments */
-class Checks extends Phase with PreservesAll[Phase] {
-
- override def transform(annotations: AnnotationSeq): AnnotationSeq = {
- val targetDir, topModule, configNames, outputBaseName = mutable.ListBuffer[Annotation]()
-
- annotations.foreach {
- case a: TargetDirAnnotation => a +=: targetDir
- case a: TopModuleAnnotation => a +=: topModule
- case a: ConfigsAnnotation => a +=: configNames
- case a: OutputBaseNameAnnotation => a +=: outputBaseName
- case _ =>
- }
-
- def required(annoList: mutable.ListBuffer[Annotation], option: String): Unit = {
- if (annoList.size != 1) {
- throw new OptionsException(s"Exactly one $option required")
- }
- }
-
- def optional(annoList: mutable.ListBuffer[Annotation], option: String): Unit = {
- if (annoList.size > 1) {
- throw new OptionsException(s"Too many $option options have been specified")
- }
- }
-
- required(targetDir, "target directory")
- required(topModule, "top module")
- required(configNames, "configs string (','-delimited)")
-
- optional(outputBaseName, "output base name")
-
- annotations
- }
-
-}
diff --git a/src/main/scala/stage/phases/GenerateArtefacts.scala b/src/main/scala/stage/phases/GenerateArtefacts.scala
deleted file mode 100644
index b678906d2d3..00000000000
--- a/src/main/scala/stage/phases/GenerateArtefacts.scala
+++ /dev/null
@@ -1,27 +0,0 @@
-// See LICENSE.SiFive for license details.
-
-package freechips.rocketchip.stage.phases
-
-import chisel3.stage.phases.Elaborate
-import firrtl.AnnotationSeq
-import firrtl.options.{Phase, PreservesAll, StageOptions}
-import firrtl.options.Viewer.view
-import freechips.rocketchip.stage.RocketChipOptions
-import freechips.rocketchip.util.{ElaborationArtefacts, HasRocketChipStageUtils}
-
-/** Writes [[ElaborationArtefacts]] into files */
-class GenerateArtefacts extends Phase with PreservesAll[Phase] with HasRocketChipStageUtils {
-
- override val prerequisites = Seq(classOf[Checks], classOf[Elaborate])
-
- override def transform(annotations: AnnotationSeq): AnnotationSeq = {
- val targetDir = view[StageOptions](annotations).targetDir
-
- ElaborationArtefacts.files.foreach { case (extension, contents) =>
- writeOutputFile(targetDir, s"${view[RocketChipOptions](annotations).longName.get}.${extension}", contents ())
- }
-
- annotations
- }
-
-}
diff --git a/src/main/scala/stage/phases/GenerateFirrtlAnnos.scala b/src/main/scala/stage/phases/GenerateFirrtlAnnos.scala
deleted file mode 100644
index c6641ef8048..00000000000
--- a/src/main/scala/stage/phases/GenerateFirrtlAnnos.scala
+++ /dev/null
@@ -1,42 +0,0 @@
-// See LICENSE.SiFive for license details.
-
-package freechips.rocketchip.stage.phases
-
-import chisel3.stage.phases.{Convert, Elaborate, MaybeAspectPhase}
-import firrtl.AnnotationSeq
-import firrtl.annotations.{Annotation, DeletedAnnotation, JsonProtocol}
-import firrtl.options.Viewer.view
-import firrtl.options.{Phase, PreservesAll, StageOptions, TargetDirAnnotation, Unserializable}
-import freechips.rocketchip.stage.RocketChipOptions
-import freechips.rocketchip.util.HasRocketChipStageUtils
-
-/** Writes FIRRTL annotations into a file */
-class GenerateFirrtlAnnos extends Phase with PreservesAll[Phase] with HasRocketChipStageUtils {
-
- override val prerequisites = Seq(classOf[Checks], classOf[Elaborate], classOf[Convert], classOf[MaybeAspectPhase])
-
- override def transform(annotations: AnnotationSeq): AnnotationSeq = {
- val targetDir = view[StageOptions](annotations).targetDir
- val fileName = s"${view[RocketChipOptions](annotations).longName.get}.anno.json"
-
- val annos = scala.collection.mutable.Buffer[Annotation]()
- annotations.flatMap {
- case a: Unserializable =>
- Some(a)
- case a: TargetDirAnnotation =>
- /** Don't serialize, in case of downstream FIRRTL call */
- Some(a)
- case a @ DeletedAnnotation(_, _: Unserializable) =>
- /** [[DeletedAnnotation]]s of unserializable annotations cannot be serialized */
- Some(a)
- case a =>
- annos += a
- Some(a)
- }
-
- writeOutputFile(targetDir, fileName, JsonProtocol.serialize(annos))
-
- annotations
- }
-
-}
diff --git a/src/main/scala/stage/phases/GenerateROMs.scala b/src/main/scala/stage/phases/GenerateROMs.scala
deleted file mode 100644
index 7203cb2caa1..00000000000
--- a/src/main/scala/stage/phases/GenerateROMs.scala
+++ /dev/null
@@ -1,31 +0,0 @@
-// See LICENSE.SiFive for license details.
-
-package freechips.rocketchip.stage.phases
-
-import chisel3.stage.ChiselCircuitAnnotation
-import chisel3.stage.phases.{Convert, Elaborate}
-import firrtl.AnnotationSeq
-import firrtl.options.{Phase, PreservesAll, StageOptions}
-import firrtl.options.Viewer.view
-import freechips.rocketchip.stage.RocketChipOptions
-import freechips.rocketchip.util.HasRocketChipStageUtils
-
-/** Dumps ROM information into a file */
-class GenerateROMs extends Phase with PreservesAll[Phase] with HasRocketChipStageUtils {
-
- override val prerequisites = Seq(classOf[Checks], classOf[Elaborate])
- override val dependents = Seq(classOf[Convert])
-
- override def transform(annotations: AnnotationSeq): AnnotationSeq = {
- val targetDir = view[StageOptions](annotations).targetDir
- val fileName = s"${view[RocketChipOptions](annotations).longName.get}.rom.conf"
-
- annotations.flatMap {
- case a: ChiselCircuitAnnotation =>
- writeOutputFile(targetDir, fileName, enumerateROMs(a.circuit))
- Some(a)
- case a => Some(a)
- }
- }
-
-}
diff --git a/src/main/scala/stage/phases/GenerateTestSuiteMakefrags.scala b/src/main/scala/stage/phases/GenerateTestSuiteMakefrags.scala
deleted file mode 100644
index 94f7866770d..00000000000
--- a/src/main/scala/stage/phases/GenerateTestSuiteMakefrags.scala
+++ /dev/null
@@ -1,33 +0,0 @@
-// See LICENSE.SiFive for license details.
-
-package freechips.rocketchip.stage.phases
-
-import chisel3.stage.phases.Elaborate
-import firrtl.AnnotationSeq
-import firrtl.options.{Phase, PreservesAll, StageOptions}
-import firrtl.options.Viewer.view
-import freechips.rocketchip.stage.RocketChipOptions
-import freechips.rocketchip.system.TestGeneration
-import freechips.rocketchip.util.HasRocketChipStageUtils
-
-/** Generates a make script to run tests in [[RocketTestSuiteAnnotation]]. */
-class GenerateTestSuiteMakefrags extends Phase with PreservesAll[Phase] with HasRocketChipStageUtils {
-
- override val prerequisites = Seq(classOf[Checks], classOf[Elaborate])
-
- override def transform(annotations: AnnotationSeq): AnnotationSeq = {
- val targetDir = view[StageOptions](annotations).targetDir
- val fileName = s"${view[RocketChipOptions](annotations).longName.get}.d"
-
- annotations.flatMap {
- case a: RocketTestSuiteAnnotation =>
- val makefrag = a.tests.groupBy(_.kind)
- .map { case (kind, s) => TestGeneration.gen(kind, s) }
- .mkString("\n")
- writeOutputFile(targetDir, fileName, makefrag)
- Some(a)
- case a => Some(a)
- }
- }
-
-}
diff --git a/src/main/scala/stage/phases/PreElaboration.scala b/src/main/scala/stage/phases/PreElaboration.scala
deleted file mode 100644
index 3a9435dca15..00000000000
--- a/src/main/scala/stage/phases/PreElaboration.scala
+++ /dev/null
@@ -1,39 +0,0 @@
-// See LICENSE.SiFive for license details.
-
-package freechips.rocketchip.stage.phases
-
-import chisel3.RawModule
-import chisel3.stage.ChiselGeneratorAnnotation
-import firrtl.AnnotationSeq
-import firrtl.options.Viewer.view
-import firrtl.options.{Phase, PreservesAll}
-import freechips.rocketchip.config.Parameters
-import freechips.rocketchip.diplomacy._
-import freechips.rocketchip.stage.RocketChipOptions
-import freechips.rocketchip.util.HasRocketChipStageUtils
-
-/** Constructs a generator function that returns a top module with given config parameters */
-class PreElaboration extends Phase with PreservesAll[Phase] with HasRocketChipStageUtils {
-
- override val prerequisites = Seq(classOf[Checks])
- override val dependents = Seq(classOf[chisel3.stage.phases.Elaborate])
-
- override def transform(annotations: AnnotationSeq): AnnotationSeq = {
-
- val rOpts = view[RocketChipOptions](annotations)
- val topMod = rOpts.topModule.get
-
- val config = getConfig(rOpts.configNames.get)
-
- val gen = () =>
- topMod
- .getConstructor(classOf[Parameters])
- .newInstance(config) match {
- case a: RawModule => a
- case a: LazyModule => LazyModule(a).module
- }
-
- ChiselGeneratorAnnotation(gen) +: annotations
- }
-
-}
diff --git a/src/main/scala/stage/phases/TransformAnnotations.scala b/src/main/scala/stage/phases/TransformAnnotations.scala
deleted file mode 100644
index a49bd55a10b..00000000000
--- a/src/main/scala/stage/phases/TransformAnnotations.scala
+++ /dev/null
@@ -1,23 +0,0 @@
-// See LICENSE.SiFive for license details.
-
-package freechips.rocketchip.stage.phases
-
-import chisel3.stage.ChiselOutputFileAnnotation
-import chisel3.stage.phases.Emitter
-import firrtl.AnnotationSeq
-import firrtl.options.Viewer.view
-import firrtl.options.{Phase, PreservesAll}
-import freechips.rocketchip.stage.RocketChipOptions
-import freechips.rocketchip.util.HasRocketChipStageUtils
-
-/** Transforms RocketChipAnnotations into those used by other stages */
-class TransformAnnotations extends Phase with PreservesAll[Phase] with HasRocketChipStageUtils {
-
- override val prerequisites = Seq(classOf[Checks])
- override val dependents = Seq(classOf[Emitter])
-
- override def transform(annotations: AnnotationSeq): AnnotationSeq = {
- /** Construct output file annotation for emission */
- new ChiselOutputFileAnnotation(view[RocketChipOptions](annotations).longName.get) +: annotations
- }
-}
diff --git a/src/main/scala/system/Generator.scala b/src/main/scala/system/Generator.scala
new file mode 100644
index 00000000000..f430d985f09
--- /dev/null
+++ b/src/main/scala/system/Generator.scala
@@ -0,0 +1,111 @@
+// See LICENSE.SiFive for license details.
+
+package freechips.rocketchip.system
+
+import freechips.rocketchip.subsystem.RocketTilesKey
+import freechips.rocketchip.tile.XLen
+import freechips.rocketchip.util.GeneratorApp
+
+import scala.collection.mutable.LinkedHashSet
+
+/** A Generator for platforms containing Rocket Subsystemes */
+object Generator extends GeneratorApp {
+
+ override def addTestSuites {
+ import DefaultTestSuites._
+ val xlen = params(XLen)
+
+ val regressionTests = LinkedHashSet(
+ "rv64ud-v-fcvt",
+ "rv64ud-p-fdiv",
+ "rv64ud-v-fadd",
+ "rv64uf-v-fadd",
+ "rv64um-v-mul",
+ "rv64mi-p-breakpoint",
+ "rv64uc-v-rvc",
+ "rv64ud-v-structural",
+ "rv64si-p-wfi",
+ "rv64um-v-divw",
+ "rv64ua-v-lrsc",
+ "rv64ui-v-fence_i",
+ "rv64ud-v-fcvt_w",
+ "rv64uf-v-fmin",
+ "rv64ui-v-sb",
+ "rv64ua-v-amomax_d",
+ "rv64ud-v-move",
+ "rv64ud-v-fclass",
+ "rv64ua-v-amoand_d",
+ "rv64ua-v-amoxor_d",
+ "rv64si-p-sbreak",
+ "rv64ud-v-fmadd",
+ "rv64uf-v-ldst",
+ "rv64um-v-mulh",
+ "rv64si-p-dirty",
+ "rv32mi-p-ma_addr",
+ "rv32mi-p-csr",
+ "rv32ui-p-sh",
+ "rv32ui-p-lh",
+ "rv32uc-p-rvc",
+ "rv32mi-p-sbreak",
+ "rv32ui-p-sll")
+
+ // TODO: for now only generate tests for the first core in the first subsystem
+ params(RocketTilesKey).headOption.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) {
+ TestGeneration.addSuites(env.map(rv32uf))
+ if (cfg.fLen >= 64)
+ TestGeneration.addSuites(env.map(rv32ud))
+ } else {
+ TestGeneration.addSuite(rv32udBenchmarks)
+ TestGeneration.addSuites(env.map(rv64uf))
+ if (cfg.fLen >= 64)
+ TestGeneration.addSuites(env.map(rv64ud))
+ }
+ }
+ if (coreParams.useAtomics) {
+ if (tileParams.dcache.flatMap(_.scratch).isEmpty)
+ TestGeneration.addSuites(env.map(if (xlen == 64) rv64ua else rv32ua))
+ else
+ TestGeneration.addSuites(env.map(if (xlen == 64) rv64uaSansLRSC else rv32uaSansLRSC))
+ }
+ if (coreParams.useCompressed) TestGeneration.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)
+
+ /* Filter the regression tests based on what the Rocket Chip configuration supports */
+ val extensions = {
+ val fd = coreParams.fpu.map {
+ case cfg if cfg.fLen >= 64 => "fd"
+ case _ => "f"
+ }
+ val m = coreParams.mulDiv.map{ case _ => "m" }
+ fd ++ m ++ Seq( if (coreParams.useRVE) Some("e") else Some("i"),
+ if (coreParams.useAtomics) Some("a") else None,
+ if (coreParams.useCompressed) Some("c") else None )
+ .flatten
+ .mkString("")
+ }
+ val re = s"""^rv$xlen[usm][$extensions].+""".r
+ regressionTests.retain{
+ case re() => true
+ case _ => false
+ }
+ TestGeneration.addSuite(new RegressionTestSuite(regressionTests))
+ }
+ }
+
+ generateFirrtl
+ generateAnno
+ generateTestSuiteMakefrags
+ generateROMs
+ generateArtefacts
+}
diff --git a/src/main/scala/system/RocketChipStageGenerator.scala b/src/main/scala/system/RocketChipStageGenerator.scala
deleted file mode 100644
index ddfb60edc54..00000000000
--- a/src/main/scala/system/RocketChipStageGenerator.scala
+++ /dev/null
@@ -1,35 +0,0 @@
-// See LICENSE.SiFive for license details.
-
-package freechips.rocketchip.system
-
-import chisel3.stage.{ChiselCli, ChiselStage}
-import firrtl.options.PhaseManager.PhaseDependency
-import firrtl.options.{Phase, PreservesAll, Shell, StageMain}
-import firrtl.stage.FirrtlCli
-import freechips.rocketchip.stage.RocketChipCli
-
-class RocketChipStage extends ChiselStage with PreservesAll[Phase] {
-
- override val shell = new Shell("rocket-chip") 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[freechips.rocketchip.stage.phases.GenerateTestSuiteMakefrags],
- classOf[freechips.rocketchip.stage.phases.GenerateArtefacts],
- )
-
- // TODO: need a RunPhaseAnnotation to inject phases into ChiselStage
-}
-
-object Generator extends StageMain(new RocketChipStage)
diff --git a/src/main/scala/system/RocketTestSuite.scala b/src/main/scala/system/RocketTestSuite.scala
index 3129e83e11e..d4c809c9714 100644
--- a/src/main/scala/system/RocketTestSuite.scala
+++ b/src/main/scala/system/RocketTestSuite.scala
@@ -61,15 +61,16 @@ object TestGeneration {
def addSuites(s: Seq[RocketTestSuite]) { s.foreach(addSuite) }
- private[rocketchip] def gen(kind: String, s: Seq[RocketTestSuite]) = {
- if(s.length > 0) {
- val envs = s.groupBy(_.envName)
- val targets = s.map(t => s"$$(${t.makeTargetName})").mkString(" ")
- s.map(_.toString).mkString("\n") +
- envs.filterKeys(_ != "").map( {
- case (env,envsuites) => {
- val suites = envsuites.map(t => s"$$(${t.makeTargetName})").mkString(" ")
- s"""
+ def generateMakefrag: String = {
+ def gen(kind: String, s: Seq[RocketTestSuite]) = {
+ if(s.length > 0) {
+ val envs = s.groupBy(_.envName)
+ val targets = s.map(t => s"$$(${t.makeTargetName})").mkString(" ")
+ s.map(_.toString).mkString("\n") +
+ envs.filterKeys(_ != "").map( {
+ case (env,envsuites) => {
+ val suites = envsuites.map(t => s"$$(${t.makeTargetName})").mkString(" ")
+ s"""
run-$kind-$env-tests: $$(addprefix $$(output_dir)/, $$(addsuffix .out, $suites))
\t@echo; perl -ne 'print " [$$$$1] $$$$ARGV \\t$$$$2\\n" if( /\\*{3}(.{8})\\*{3}(.*)/ || /ASSERTION (FAILED):(.*)/i )' $$^ /dev/null | perl -pe 'BEGIN { $$$$failed = 0 } $$$$failed = 1 if(/FAILED/i); END { exit($$$$failed) }'
run-$kind-$env-tests-debug: $$(addprefix $$(output_dir)/, $$(addsuffix .vpd, $suites))
@@ -88,10 +89,9 @@ run-$kind-tests-fst: $$(addprefix $$(output_dir)/, $$(addsuffix .fst, $targets))
run-$kind-tests-fast: $$(addprefix $$(output_dir)/, $$(addsuffix .run, $targets))
\t@echo; perl -ne 'print " [$$$$1] $$$$ARGV \\t$$$$2\\n" if( /\\*{3}(.{8})\\*{3}(.*)/ || /ASSERTION (FAILED):(.*)/i )' $$^ /dev/null | perl -pe 'BEGIN { $$$$failed = 0 } $$$$failed = 1 if(/FAILED/i); END { exit($$$$failed) }'
"""
- } else { "\n" }
- }
+ } else { "\n" }
+ }
- def generateMakeFrag: String = {
suites.values.toSeq.groupBy(_.kind).map { case (kind, s) => gen(kind, s) }.mkString("\n")
}
@@ -99,7 +99,7 @@ run-$kind-tests-fast: $$(addprefix $$(output_dir)/, $$(addsuffix .run, $targets)
object DefaultTestSuites {
val rv32uiNames = LinkedHashSet(
- "simple", "add", "addi", "and", "andi", "auipc", "beq", "bge", "bgeu", "blt", "bltu", "bne", "fence_i",
+ "simple", "add", "addi", "and", "andi", "auipc", "beq", "bge", "bgeu", "blt", "bltu", "bne", "fence_i",
"jal", "jalr", "lb", "lbu", "lh", "lhu", "lui", "lw", "or", "ori", "sb", "sh", "sw", "sll", "slli",
"slt", "slti", "sra", "srai", "srl", "srli", "sub", "xor", "xori")
val rv32ui = new AssemblyTestSuite("rv32ui", rv32uiNames)(_)
diff --git a/src/main/scala/unittest/Generator.scala b/src/main/scala/unittest/Generator.scala
index 01ef16886e5..1fd96632f4c 100644
--- a/src/main/scala/unittest/Generator.scala
+++ b/src/main/scala/unittest/Generator.scala
@@ -2,7 +2,9 @@
package freechips.rocketchip.unittest
-import firrtl.options.StageMain
-import freechips.rocketchip.system.RocketChipStage
-
-object Generator extends StageMain(new RocketChipStage)
+object Generator extends freechips.rocketchip.util.GeneratorApp {
+ generateFirrtl
+ generateAnno
+ generateTestSuiteMakefrags // TODO: Needed only for legacy make targets
+ generateArtefacts
+}
diff --git a/src/main/scala/util/GeneratorUtils.scala b/src/main/scala/util/GeneratorUtils.scala
index 8d00dd85066..4578906ffb1 100644
--- a/src/main/scala/util/GeneratorUtils.scala
+++ b/src/main/scala/util/GeneratorUtils.scala
@@ -2,14 +2,36 @@
package freechips.rocketchip.util
+import Chisel._
+import chisel3.RawModule
+import chisel3.internal.firrtl.Circuit
+// TODO: better job of Makefrag generation for non-RocketChip testing platforms
import java.io.{File, FileWriter}
-import Chisel.throwException
-import chipsalliance.rocketchip.config.{Config, Parameters}
-import chisel3.internal.firrtl.Circuit
+import firrtl.annotations.JsonProtocol
+import freechips.rocketchip.config._
+import freechips.rocketchip.diplomacy._
+import freechips.rocketchip.system.{DefaultTestSuites, TestGeneration}
-trait HasRocketChipStageUtils {
+/** Representation of the information this Generator needs to collect from external sources. */
+case class ParsedInputNames(
+ targetDir: String,
+ topModuleProject: String,
+ topModuleClass: String,
+ configProject: String,
+ configs: String,
+ outputBaseName: Option[String]) {
+ val configClasses: Seq[String] = configs.split('_')
+ def prepend(prefix: String, suffix: String) =
+ if (prefix == "" || prefix == "_root_") suffix else (prefix + "." + suffix)
+ val fullConfigClasses: Seq[String] = configClasses.map(x => prepend(configProject, x))
+ val fullTopModuleClass: String = prepend(topModuleProject, topModuleClass)
+}
+/** Common utilities we supply to all Generators. In particular, supplies the
+ * canonical ways of building various JVM elaboration-time structures.
+ */
+trait HasGeneratorUtilities {
def getConfig(fullConfigClassNames: Seq[String]): Config = {
new Config(fullConfigClassNames.foldRight(Parameters.empty) { case (currentName, config) =>
val currentConfig = try {
@@ -22,6 +44,22 @@ trait HasRocketChipStageUtils {
})
}
+ def getParameters(names: Seq[String]): Parameters = getParameters(getConfig(names))
+
+ def getParameters(config: Config): Parameters = config.toInstance
+
+ def elaborate(fullTopModuleClassName: String, params: Parameters): Circuit = {
+ val top = () =>
+ Class.forName(fullTopModuleClassName)
+ .getConstructor(classOf[Parameters])
+ .newInstance(params) match {
+ case m: RawModule => m
+ case l: LazyModule => LazyModule(l).module
+ }
+
+ Driver.elaborate(top)
+ }
+
def enumerateROMs(circuit: Circuit): String = {
val res = new StringBuilder
val configs =
@@ -36,6 +74,73 @@ trait HasRocketChipStageUtils {
}
res.toString
}
+}
+
+/** Standardized command line interface for Scala entry point */
+trait GeneratorApp extends App with HasGeneratorUtilities {
+ lazy val names: ParsedInputNames = {
+ require(args.size == 5 || args.size == 6, "Usage: sbt> " +
+ "run TargetDir TopModuleProjectName TopModuleName " +
+ "ConfigProjectName ConfigNameString [OutputFilesBaseName]")
+ val base =
+ ParsedInputNames(
+ targetDir = args(0),
+ topModuleProject = args(1),
+ topModuleClass = args(2),
+ configProject = args(3),
+ configs = args(4),
+ outputBaseName = None)
+
+ if (args.size == 6) {
+ base.copy(outputBaseName = Some(args(5)))
+ } else {
+ base
+ }
+ }
+
+ // Canonical ways of building various JVM elaboration-time structures
+ lazy val td: String = names.targetDir
+ lazy val config: Config = getConfig(names.fullConfigClasses)
+ lazy val params: Parameters = config.toInstance
+ lazy val circuit: Circuit = elaborate(names.fullTopModuleClass, params)
+
+ // Exhaustive name used to interface with external build tool targets
+ lazy val longName: String = names.outputBaseName.getOrElse(names.configProject + "." + names.configs)
+
+ /** Output FIRRTL, which an external compiler can turn into Verilog. */
+ def generateFirrtl {
+ Driver.dumpFirrtl(circuit, Some(new File(td, s"$longName.fir"))) // FIRRTL
+ }
+
+ def generateAnno {
+ val annotationFile = new File(td, s"$longName.anno.json")
+ val af = new FileWriter(annotationFile)
+ af.write(JsonProtocol.serialize(circuit.annotations.map(_.toFirrtl)))
+ af.close()
+ }
+
+ /** Output software test Makefrags, which provide targets for integration testing. */
+ def generateTestSuiteMakefrags {
+ addTestSuites
+ writeOutputFile(td, s"$longName.d", TestGeneration.generateMakefrag) // Subsystem-specific test suites
+ }
+
+ def addTestSuites {
+ TestGeneration.addSuite(DefaultTestSuites.groundtest64("p"))
+ TestGeneration.addSuite(DefaultTestSuites.emptyBmarks)
+ TestGeneration.addSuite(DefaultTestSuites.singleRegression)
+ }
+
+ def generateROMs {
+ writeOutputFile(td, s"$longName.rom.conf", enumerateROMs(circuit))
+ }
+
+ /** Output files created as a side-effect of elaboration */
+ def generateArtefacts {
+ ElaborationArtefacts.files.foreach { case (extension, contents) =>
+ writeOutputFile(td, s"$longName.$extension", contents ())
+ }
+ }
def writeOutputFile(targetDir: String, fname: String, contents: String): File = {
val f = new File(targetDir, fname)
@@ -44,7 +149,6 @@ trait HasRocketChipStageUtils {
fw.close
f
}
-
}
object ElaborationArtefacts {
diff --git a/src/test/scala/generatorTests/StageGeneratorSpec.scala b/src/test/scala/generatorTests/StageGeneratorSpec.scala
deleted file mode 100644
index e5487a19185..00000000000
--- a/src/test/scala/generatorTests/StageGeneratorSpec.scala
+++ /dev/null
@@ -1,44 +0,0 @@
-// See LICENSE.SiFive for license details.
-
-package generatorTests
-
-import java.io.File
-
-import chisel3.aop.injecting.InjectingAspect
-import chisel3._
-import firrtl.options.TargetDirAnnotation
-import freechips.rocketchip.stage.{ConfigsAnnotation, TopModuleAnnotation}
-import freechips.rocketchip.system.{RocketChipStage, TestHarness}
-import org.scalatest.FlatSpec
-
-/** run via SBT with
- * > testOnly generatorTests.StageGeneratorSpec
- *
- * Output can be viewed in the testbuild directory. The wire named "hello" should show up in the generated
- * *.anno.json file.
- */
-class StageGeneratorSpec extends FlatSpec {
-
- val dummyAspect = InjectingAspect(
- {dut: TestHarness => Seq(dut.dut)},
- {dut: freechips.rocketchip.system.ExampleRocketSystemModuleImp[freechips.rocketchip.system.ExampleRocketSystem] =>
- val dummyWire = Wire(UInt(3.W)).suggestName("hello")
- dummyWire := 5.U
- dontTouch(dummyWire)
- }
- )
-
- "Test" should "pass" in {
- val dirName = System.getProperty("user.dir") + "/testbuild"
- val dir = new File(dirName)
- if (!dir.exists()) dir.mkdirs()
-
- new RocketChipStage().run(Seq(
- new TargetDirAnnotation(dirName),
- new TopModuleAnnotation(Class.forName("freechips.rocketchip.system.TestHarness")),
- new ConfigsAnnotation(Seq("freechips.rocketchip.system.DefaultConfig")),
- dummyAspect
- ))
- }
-
-}
\ No newline at end of file
diff --git a/vsim/Makefrag b/vsim/Makefrag
index 278384769af..f28f192a210 100644
--- a/vsim/Makefrag
+++ b/vsim/Makefrag
@@ -64,14 +64,14 @@ VCS_OPTS = -notice -line +lint=all,noVCDE,noONGS,noUI -error=PCWM-L -timescale=1
# Build the simulator
#--------------------------------------------------------------------
-simv = $(sim_dir)/simv-$(PROJECT)-$(CONFIG_STR)
+simv = $(sim_dir)/simv-$(PROJECT)-$(CONFIG)
$(simv) : $(sim_vsrcs) $(sim_csrcs)
cd $(sim_dir) && \
rm -rf csrc && \
$(VCS) $(VCS_OPTS) -o $(simv) \
-debug_pp \
-simv_debug = $(sim_dir)/simv-$(PROJECT)-$(CONFIG_STR)-debug
+simv_debug = $(sim_dir)/simv-$(PROJECT)-$(CONFIG)-debug
$(simv_debug) : $(sim_vsrcs) $(sim_csrcs)
cd $(sim_dir) && \
rm -rf csrc && \
diff --git a/vsim/Makefrag-verilog b/vsim/Makefrag-verilog
index 13e35373d37..9b0afa159a2 100644
--- a/vsim/Makefrag-verilog
+++ b/vsim/Makefrag-verilog
@@ -10,7 +10,7 @@ verilog = $(generated_dir)/$(long_name).v
$(generated_dir)/%.fir $(generated_dir)/%.d: $(FIRRTL_JAR) $(chisel_srcs) $(bootrom_img)
mkdir -p $(dir $@)
- cd $(base_dir) && $(SBT) "runMain $(PROJECT).Generator -td $(generated_dir) -T $(PROJECT).$(MODEL) -C $(CONFIG)"
+ cd $(base_dir) && $(SBT) "runMain $(PROJECT).Generator $(generated_dir) $(PROJECT) $(MODEL) $(CFG_PROJECT) $(CONFIG)"
$(generated_dir)/%.v $(generated_dir)/%.conf: $(generated_dir)/%.fir $(FIRRTL_JAR)
mkdir -p $(dir $@)