From 532db478c0649b1556523e51f34541e6a9d4c53a Mon Sep 17 00:00:00 2001 From: abejgonzalez Date: Tue, 20 Aug 2024 11:42:23 -0700 Subject: [PATCH] For FireSim, support FIRRTL2 bridge + Chisel 6 annos - All targets now compile w/ Chisel6 - Remove Chisel3 references as much as possible --- .github/scripts/check-commit.sh | 2 +- .gitmodules | 12 +--- build.sbt | 61 +++++++++++------ common.mk | 4 +- .../src/main/makefrag/bridges/build.mk | 5 +- .../chip/src/main/makefrag/firesim/build.mk | 5 +- .../chip/src/main/scala/FireSim.scala | 4 +- .../chip/src/main/scala/Generator.scala | 35 ++++++++++ project/plugins.sbt | 3 + sims/firesim | 2 +- sims/firesim-staging/Makefile | 2 +- tools/dsptools-chisel3 | 1 - tools/firrtl2 | 1 + tools/fixedpoint-chisel3 | 1 - tools/midas-targetutils | 1 - .../src/main/scala/ChipyardAnnotations.scala | 66 ------------------- .../src/main/scala/ChipyardCli.scala | 17 ----- .../src/main/scala/ChipyardOptions.scala | 40 ----------- .../src/main/scala/ChipyardStage.scala | 41 ------------ .../src/main/scala/StageUtils.scala | 48 -------------- .../src/main/scala/package.scala | 24 ------- .../main/scala/phases/AddDefaultTests.scala | 52 --------------- .../src/main/scala/phases/Checks.scala | 47 ------------- .../main/scala/phases/GenerateArtefacts.scala | 26 -------- .../scala/phases/GenerateFirrtlAnnos.scala | 36 ---------- .../phases/GenerateTestSuiteMakefrags.scala | 49 -------------- .../main/scala/phases/PreElaboration.scala | 43 ------------ .../scala/phases/TransformAnnotations.scala | 21 ------ .../stage/src/main/scala/ChipyardStage.scala | 15 +---- 29 files changed, 99 insertions(+), 565 deletions(-) create mode 100644 generators/firechip/chip/src/main/scala/Generator.scala delete mode 160000 tools/dsptools-chisel3 create mode 160000 tools/firrtl2 delete mode 160000 tools/fixedpoint-chisel3 delete mode 160000 tools/midas-targetutils delete mode 100644 tools/stage-chisel3/src/main/scala/ChipyardAnnotations.scala delete mode 100644 tools/stage-chisel3/src/main/scala/ChipyardCli.scala delete mode 100644 tools/stage-chisel3/src/main/scala/ChipyardOptions.scala delete mode 100644 tools/stage-chisel3/src/main/scala/ChipyardStage.scala delete mode 100644 tools/stage-chisel3/src/main/scala/StageUtils.scala delete mode 100644 tools/stage-chisel3/src/main/scala/package.scala delete mode 100644 tools/stage-chisel3/src/main/scala/phases/AddDefaultTests.scala delete mode 100644 tools/stage-chisel3/src/main/scala/phases/Checks.scala delete mode 100644 tools/stage-chisel3/src/main/scala/phases/GenerateArtefacts.scala delete mode 100644 tools/stage-chisel3/src/main/scala/phases/GenerateFirrtlAnnos.scala delete mode 100644 tools/stage-chisel3/src/main/scala/phases/GenerateTestSuiteMakefrags.scala delete mode 100644 tools/stage-chisel3/src/main/scala/phases/PreElaboration.scala delete mode 100644 tools/stage-chisel3/src/main/scala/phases/TransformAnnotations.scala diff --git a/.github/scripts/check-commit.sh b/.github/scripts/check-commit.sh index b2a0d1ec0f..ac4fc0a410 100755 --- a/.github/scripts/check-commit.sh +++ b/.github/scripts/check-commit.sh @@ -83,7 +83,7 @@ dir="software" branches=("master" "dev") search -submodules=("DRAMSim2" "axe" "dsptools" "dsptools-chisel3" "rocket-dsp-utils" "torture" "fixedpoint" "fixedpoint-chisel3" "cde" "midas-targetutils") +submodules=("DRAMSim2" "axe" "dsptools" "rocket-dsp-utils" "torture" "fixedpoint" "cde" "firrtl2") dir="tools" branches=("master" "dev" "main") search diff --git a/.gitmodules b/.gitmodules index 75643ec7f9..f233483ca2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -115,12 +115,6 @@ [submodule "tools/circt"] path = tools/circt url = https://github.com/llvm/circt.git -[submodule "tools/dsptools-fixedpoint"] - path = tools/dsptools-chisel3 - url = https://github.com/ucb-bar/dsptools.git -[submodule "tools/fixedpoint-chisel3"] - path = tools/fixedpoint-chisel3 - url = https://github.com/ucb-bar/fixedpoint.git [submodule "tools/install-circt"] path = tools/install-circt url = https://github.com/circt/install-circt.git @@ -139,9 +133,6 @@ [submodule "tools/fixedpoint"] path = tools/fixedpoint url = https://github.com/ucb-bar/fixedpoint.git -[submodule "tools/midas-targetutils"] - path = tools/midas-targetutils - url = https://github.com/firesim/midas-targetutils.git [submodule "generators/rerocc"] path = generators/rerocc url = https://github.com/ucb-bar/rerocc.git @@ -157,3 +148,6 @@ [submodule "generators/ara"] path = generators/ara url = https://github.com/ucb-bar/ara-wrapper.git +[submodule "tools/firrtl2"] + path = tools/firrtl2 + url = https://github.com/ucb-bar/firrtl2.git diff --git a/build.sbt b/build.sbt index 0015b80ad6..431bf6068a 100644 --- a/build.sbt +++ b/build.sbt @@ -1,10 +1,10 @@ import Tests._ -val chisel6 = sys.env.get("USE_CHISEL6").isDefined val chisel6Version = "6.5.0" +val chiselTestVersion = "6.0.0" +val scalaVersionFromChisel = "2.13.12" + val chisel3Version = "3.6.1" -val chiselTestVersion = if (chisel6) "6.0.0" else "0.6.0" -val scalaVersionFromChisel = if (chisel6) "2.13.12" else "2.13.10" // This gives us a nicer handle to the root project instead of using the // implicit one @@ -97,7 +97,7 @@ lazy val chisel3Settings = Seq( addCompilerPlugin("edu.berkeley.cs" % "chisel3-plugin" % chisel3Version cross CrossVersion.full) ) -lazy val chiselSettings = (if (chisel6) chisel6Settings else chisel3Settings) ++ Seq( +lazy val chiselSettings = chisel6Settings ++ Seq( libraryDependencies ++= Seq( "org.apache.commons" % "commons-lang3" % "3.12.0", "org.apache.commons" % "commons-text" % "1.9" @@ -118,7 +118,7 @@ lazy val scalaTestSettings = Seq( lazy val hardfloat = freshProject("hardfloat", file("generators/hardfloat/hardfloat")) .settings(chiselSettings) .settings(commonSettings) - .dependsOn(if (chisel6) midas_standalone_target_utils else midas_target_utils) + .dependsOn(midas_target_utils) .settings(scalaTestSettings) lazy val rocketMacros = (project in rocketChipDir / "macros") @@ -153,7 +153,6 @@ lazy val testchipip = (project in file("generators/testchipip")) .settings(libraryDependencies ++= rocketLibDeps.value) .settings(commonSettings) -val stageDir = if (chisel6) "tools/stage/src/main/scala" else "tools/stage-chisel3/src/main/scala" lazy val chipyard = (project in file("generators/chipyard")) .dependsOn(testchipip, rocketchip, boom, rocketchip_blocks, rocketchip_inclusive_cache, dsptools, rocket_dsp_utils, @@ -167,7 +166,7 @@ lazy val chipyard = (project in file("generators/chipyard")) ) ) .settings(commonSettings) - .settings(Compile / unmanagedSourceDirectories += file(stageDir)) + .settings(Compile / unmanagedSourceDirectories += file("tools/stage/src/main/scala")) lazy val compressacc = (project in file("generators/compress-acc")) .dependsOn(rocketchip) @@ -270,13 +269,11 @@ lazy val tapeout = (project in file("./tools/tapeout/")) .settings(scalaVersion := "2.13.10") // stuck on chisel3 2.13.10 .settings(libraryDependencies ++= Seq("com.typesafe.play" %% "play-json" % "2.9.2")) -val fixedpointDir = if (chisel6) "./tools/fixedpoint" else "./tools/fixedpoint-chisel3" -lazy val fixedpoint = freshProject("fixedpoint", file(fixedpointDir)) +lazy val fixedpoint = freshProject("fixedpoint", file("./tools/fixedpoint")) .settings(chiselSettings) .settings(commonSettings) -val dsptoolsDir = if (chisel6) "./tools/dsptools" else "./tools/dsptools-chisel3" -lazy val dsptools = freshProject("dsptools", file(dsptoolsDir)) +lazy val dsptools = freshProject("dsptools", file("./tools/dsptools")) .dependsOn(fixedpoint) .settings( chiselSettings, @@ -322,6 +319,39 @@ lazy val chipyard_fpga = (project in file("./fpga")) // Components of FireSim +lazy val firrtl2 = freshProject("firrtl2", file("./tools/firrtl2")) + .enablePlugins(BuildInfoPlugin) + .enablePlugins(Antlr4Plugin) + .settings(commonSettings) + .settings( + sourceDirectory := file("./tools/firrtl2/src"), + scalacOptions ++= Seq( + "-language:reflectiveCalls", + "-language:existentials", + "-language:implicitConversions"), + libraryDependencies ++= Seq( + "org.scalatest" %% "scalatest" % "3.2.14" % "test", + "org.scalatestplus" %% "scalacheck-1-15" % "3.2.11.0" % "test", + "com.github.scopt" %% "scopt" % "4.1.0", + "org.json4s" %% "json4s-native" % "4.1.0-M4", + "org.apache.commons" % "commons-text" % "1.10.0", + "com.lihaoyi" %% "os-lib" % "0.8.1", + "org.scala-lang.modules" %% "scala-parallel-collections" % "1.0.4"), + Antlr4 / antlr4GenVisitor := true, + Antlr4 / antlr4GenListener := true, + Antlr4 / antlr4PackageName := Option("firrtl2.antlr"), + Antlr4 / antlr4Version := "4.9.3", + Antlr4 / javaSource := (Compile / sourceManaged).value, + buildInfoPackage := "firrtl2", + buildInfoUsePackageAsPath := true, + buildInfoKeys := Seq[BuildInfoKey](buildInfoPackage, version, scalaVersion, sbtVersion) + ) + +lazy val firrtl2_bridge = freshProject("firrtl2_bridge", file("./tools/firrtl2/bridge")) + .dependsOn(firrtl2) + .settings(commonSettings) + .settings(chiselSettings) + lazy val firesimAsLibrary = sys.env.get("FIRESIM_STANDALONE") == None lazy val firesimDir = if(firesimAsLibrary) { file("sims/firesim") @@ -329,7 +359,6 @@ lazy val firesimDir = if(firesimAsLibrary) { file("sims/firesim-staging/firesim-symlink") } -// TODO: AJG: Fix // Contains annotations & firrtl passes you may wish to use in rocket-chip without // introducing a circular dependency between RC and MIDAS // this should be minimally dependent on firesim @@ -337,12 +366,6 @@ lazy val midas_target_utils = (project in firesimDir / "sim/midas/targetutils") .settings(commonSettings) .settings(chiselSettings) -// compiles with chisel6 (only the APIs) -lazy val midas_standalone_target_utils = (project in file("tools/midas-targetutils")) - .settings(commonSettings) - .settings(chiselSettings) -// TODO: AJG: ^ Fix - // Provides API for bridges to be created in the target. // Includes target-side of FireSim-provided bridges and their interfaces that are shared // between FireSim and the target. Minimal in scope (should only depend on Chisel/Firrtl2) @@ -375,7 +398,7 @@ lazy val firechip_bridgestubs = (project in file("generators/firechip/bridgestub // FireSim top-level project that includes the FireSim harness, CC files, etc needed for FireSim. lazy val firechip = (project in file("generators/firechip/chip")) - .dependsOn(chipyard, firesim_lib % "compile->compile;test->test", firechip_bridgestubs, firechip_bridgeinterfaces) + .dependsOn(chipyard, firesim_lib % "compile->compile;test->test", firechip_bridgestubs, firechip_bridgeinterfaces, firrtl2_bridge) .settings( chiselSettings, commonSettings, diff --git a/common.mk b/common.mk index 94521ea008..54bea233c3 100644 --- a/common.mk +++ b/common.mk @@ -88,9 +88,9 @@ CHECK_SUBMODULES_COMMAND = echo "Checking all submodules in generators/ are init SCALA_EXT = scala VLOG_EXT = sv v FIRESIM_DIR = $(if $(FIRESIM_STANDALONE),sims/firesim-staging/firesim-symlink,sims/firesim) -FIRESIM_SOURCE_DIRS = $(addprefix $(FIRESIM_DIR)/,sim/firesim-lib sim/midas/targetutils) $(addprefix generators/firechip/,core bridge-interfaces) +FIRESIM_SOURCE_DIRS = $(addprefix $(FIRESIM_DIR)/,sim/firesim-lib sim/midas/targetutils) $(addprefix generators/firechip/,core bridge-interfaces) tools/firrtl2 CHIPYARD_SOURCE_DIRS = \ - $(filter-out $(base_dir)/generators/firechip,$(wildcard $(addprefix $(base_dir)/,generators/* fpga/fpga-shells fpga/src tools/stage tools/stage-chisel3))) \ + $(filter-out $(base_dir)/generators/firechip,$(wildcard $(addprefix $(base_dir)/,generators/* fpga/fpga-shells fpga/src tools/stage))) \ $(addprefix $(base_dir)/,$(FIRESIM_SOURCE_DIRS)) CHIPYARD_SCALA_SOURCES = $(call lookup_srcs_by_multiple_type,$(CHIPYARD_SOURCE_DIRS),$(SCALA_EXT)) CHIPYARD_VLOG_SOURCES = $(call lookup_srcs_by_multiple_type,$(CHIPYARD_SOURCE_DIRS),$(VLOG_EXT)) diff --git a/generators/firechip/bridgestubs/src/main/makefrag/bridges/build.mk b/generators/firechip/bridgestubs/src/main/makefrag/bridges/build.mk index ec6199f620..dc75dee212 100644 --- a/generators/firechip/bridgestubs/src/main/makefrag/bridges/build.mk +++ b/generators/firechip/bridgestubs/src/main/makefrag/bridges/build.mk @@ -9,6 +9,7 @@ TARGET_COPY_TO_MIDAS_SCALA_DIRS := \ # this rule always is run, but may not update the timestamp of the targets (depending on what the Chipyard make does). # if that is the case (Chipyard make doesn't update it's outputs), then downstream rules *should* be skipped. # all other chipyard collateral is located in chipyard's generated sources area. +# note: using different GENERATOR_PACKAGE to generate a *.sfc.fir file $(FIRRTL_FILE) $(ANNO_FILE) &: SHELL := /usr/bin/env bash # needed for running source in recipe $(FIRRTL_FILE) $(ANNO_FILE) &: firesim_target_symlink_hook @mkdir -p $(@D) @@ -20,9 +21,9 @@ $(FIRRTL_FILE) $(ANNO_FILE) &: firesim_target_symlink_hook VLOG_MODEL=$(DESIGN) \ CONFIG=$(TARGET_CONFIG) \ CONFIG_PACKAGE=$(TARGET_CONFIG_PACKAGE) \ - GENERATOR_PACKAGE=chipyard \ + GENERATOR_PACKAGE=firechip.core.firesim \ TB=unused \ TOP=unused # $(long_name) must be same as Chipyard - ln -sf $(CHIPYARD_STAGING_DIR)/generated-src/$(long_name)/$(long_name).fir $(FIRRTL_FILE) + ln -sf $(CHIPYARD_STAGING_DIR)/generated-src/$(long_name)/$(long_name).sfc.fir $(FIRRTL_FILE) ln -sf $(CHIPYARD_STAGING_DIR)/generated-src/$(long_name)/$(long_name).anno.json $(ANNO_FILE) diff --git a/generators/firechip/chip/src/main/makefrag/firesim/build.mk b/generators/firechip/chip/src/main/makefrag/firesim/build.mk index fd8f0cdf9c..bf73ffd739 100644 --- a/generators/firechip/chip/src/main/makefrag/firesim/build.mk +++ b/generators/firechip/chip/src/main/makefrag/firesim/build.mk @@ -9,6 +9,7 @@ TARGET_COPY_TO_MIDAS_SCALA_DIRS := \ # this rule always is run, but may not update the timestamp of the targets (depending on what the Chipyard make does). # if that is the case (Chipyard make doesn't update it's outputs), then downstream rules *should* be skipped. # all other chipyard collateral is located in chipyard's generated sources area. +# note: using different GENERATOR_PACKAGE to generate a *.sfc.fir file $(FIRRTL_FILE) $(ANNO_FILE) &: SHELL := /usr/bin/env bash # needed for running source in recipe $(FIRRTL_FILE) $(ANNO_FILE) &: firesim_target_symlink_hook @mkdir -p $(@D) @@ -20,11 +21,11 @@ $(FIRRTL_FILE) $(ANNO_FILE) &: firesim_target_symlink_hook VLOG_MODEL=$(DESIGN) \ CONFIG=$(TARGET_CONFIG) \ CONFIG_PACKAGE=$(TARGET_CONFIG_PACKAGE) \ - GENERATOR_PACKAGE=chipyard \ + GENERATOR_PACKAGE=firechip.core.firesim \ TB=unused \ TOP=unused # $(long_name) must be same as Chipyard - ln -sf $(CHIPYARD_STAGING_DIR)/generated-src/$(long_name)/$(long_name).fir $(FIRRTL_FILE) + ln -sf $(CHIPYARD_STAGING_DIR)/generated-src/$(long_name)/$(long_name).sfc.fir $(FIRRTL_FILE) ln -sf $(CHIPYARD_STAGING_DIR)/generated-src/$(long_name)/$(long_name).anno.json $(ANNO_FILE) # .d needed to run metasim CI tests ln -sf $(CHIPYARD_STAGING_DIR)/generated-src/$(long_name)/$(long_name).d $(GENERATED_DIR)/$(long_name).d diff --git a/generators/firechip/chip/src/main/scala/FireSim.scala b/generators/firechip/chip/src/main/scala/FireSim.scala index 4c9700f6be..ff2169bf4f 100644 --- a/generators/firechip/chip/src/main/scala/FireSim.scala +++ b/generators/firechip/chip/src/main/scala/FireSim.scala @@ -73,8 +73,8 @@ class FireSimClockBridgeInstantiator extends HarnessClockInstantiator { // for all cover statments in an RC-based design, emit an annotation class FireSimPropertyLibrary extends property.BasePropertyLibrary { - def generateProperty(prop_param: property.BasePropertyParameters)(implicit sourceInfo: chisel3.internal.sourceinfo.SourceInfo): Unit = { - if (!(prop_param.cond.isLit) && chisel3.experimental.DataMirror.internal.isSynthesizable(prop_param.cond)) { + def generateProperty(prop_param: property.BasePropertyParameters)(implicit sourceInfo: chisel3.experimental.SourceInfo): Unit = { + if (!(prop_param.cond.isLit) && chisel3.reflect.DataMirror.internal.isSynthesizable(prop_param.cond)) { annotate(new chisel3.experimental.ChiselAnnotation { val implicitClock = chisel3.Module.clock val implicitReset = chisel3.Module.reset diff --git a/generators/firechip/chip/src/main/scala/Generator.scala b/generators/firechip/chip/src/main/scala/Generator.scala new file mode 100644 index 0000000000..c950e0cf4a --- /dev/null +++ b/generators/firechip/chip/src/main/scala/Generator.scala @@ -0,0 +1,35 @@ +package firechip.core.firesim + +import firrtl.{AnnotationSeq} +import firrtl.options.{StageMain, Phase, Dependency, StageOptions} +import firrtl.options.Viewer.view +import chipyard.stage._ +import chipyard.stage.phases.{PreservesAll} + +object Generator extends StageMain(new FireSimStage) + +class FireSimStage extends ChipyardStage { + override def extraPostPhases = Seq(Dependency[LegacyFirrtl2Emission]) +} + +final class LegacyFirrtl2Emission extends Phase with PreservesAll with HasChipyardStageUtils { + override val prerequisites = Seq(Dependency[chipyard.stage.ChipyardChiselStage]) + + override def transform(annotations: AnnotationSeq): AnnotationSeq = { + val targetDir = view[StageOptions](annotations).targetDir + val fileName = s"${view[ChipyardOptions](annotations).longName.get}.sfc.fir" + + val annos = annotations.filterNot(_.isInstanceOf[firrtl.options.TargetDirAnnotation]) + + val converted = firrtl2.bridge.ChiselBridge.annosToState(annos) + val emitter = new firrtl2.ChirrtlEmitter + val circuit = converted.copy(annotations = converted.annotations ++ Seq( + firrtl2.EmitCircuitAnnotation(classOf[firrtl2.ChirrtlEmitter]) + )) + val emitted = emitter.execute(circuit) + val emittedCircuit = emitted.annotations.collectFirst { case firrtl2.EmittedFirrtlCircuitAnnotation(circuit) => circuit }.get + writeOutputFile(targetDir, fileName, emittedCircuit.value) + + annotations + } +} diff --git a/project/plugins.sbt b/project/plugins.sbt index 36e1e8b64a..02c7ce7fd9 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,3 +1,6 @@ addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.1.1") addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.10.4") addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.5.6") +addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "1.1.1") +addSbtPlugin("com.simplytyped" % "sbt-antlr4" % "0.8.2") +addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.11.0") diff --git a/sims/firesim b/sims/firesim index 418e2fa5c7..4736aa6c10 160000 --- a/sims/firesim +++ b/sims/firesim @@ -1 +1 @@ -Subproject commit 418e2fa5c7093824b2017f2eeea17c04e43cc3ce +Subproject commit 4736aa6c103879b885ab4b97c0a696bcfcc01bb5 diff --git a/sims/firesim-staging/Makefile b/sims/firesim-staging/Makefile index e38b95a046..e1b4ba70e0 100644 --- a/sims/firesim-staging/Makefile +++ b/sims/firesim-staging/Makefile @@ -14,7 +14,7 @@ sim_dir=$(abspath .) include $(base_dir)/variables.mk ######################################################################################### -# generate firrtl + annos needed for firesim +# generate firrtl + annos needed for firesim (should also produce a *.sfc.fir file) ######################################################################################### .PHONY: default default: firrtl diff --git a/tools/dsptools-chisel3 b/tools/dsptools-chisel3 deleted file mode 160000 index 8f43366395..0000000000 --- a/tools/dsptools-chisel3 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 8f4336639578d2e2dbaf61e542ee1f0fa8d79e63 diff --git a/tools/firrtl2 b/tools/firrtl2 new file mode 160000 index 0000000000..09156cae09 --- /dev/null +++ b/tools/firrtl2 @@ -0,0 +1 @@ +Subproject commit 09156cae09cb37c530322c6005649d2380c3eb0e diff --git a/tools/fixedpoint-chisel3 b/tools/fixedpoint-chisel3 deleted file mode 160000 index 36ce43c90c..0000000000 --- a/tools/fixedpoint-chisel3 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 36ce43c90ce9cfc63e7698fa1e27fd122c878e9e diff --git a/tools/midas-targetutils b/tools/midas-targetutils deleted file mode 160000 index d0fc62d2b4..0000000000 --- a/tools/midas-targetutils +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d0fc62d2b463a438f8d721a2dcfcddf315f3d760 diff --git a/tools/stage-chisel3/src/main/scala/ChipyardAnnotations.scala b/tools/stage-chisel3/src/main/scala/ChipyardAnnotations.scala deleted file mode 100644 index b9c04eb89d..0000000000 --- a/tools/stage-chisel3/src/main/scala/ChipyardAnnotations.scala +++ /dev/null @@ -1,66 +0,0 @@ -// See LICENSE for license details. -// Based on Rocket Chip's stage implementation - -package chipyard.stage - -import chisel3.experimental.BaseModule -import firrtl.annotations.{Annotation, NoTargetAnnotation} -import firrtl.options.{HasShellOptions, ShellOption, Unserializable} - -trait ChipyardOption extends Unserializable { this: Annotation => } - -/** 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 => { - val split = a.split(':') - assert(split.length == 2, s"'${a}' split by ':' doesn't yield two things") - val packageName = split.head - val configs = split.last.split("_") - Seq(new ConfigsAnnotation(configs map { config => if (config contains ".") s"${config}" else s"${packageName}.${config}" } )) - }, - helpText = "A string of underscore-delimited configs (configs have decreasing precendence from left to right).", - shortOption = Some("LC") - ) - ) -} - -/** Paths to config classes */ -case class ConfigsAnnotation(configNames: Seq[String]) extends NoTargetAnnotation with ChipyardOption -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") - ) - ) -} - -case class TopModuleAnnotation(clazz: Class[_ <: Any]) extends NoTargetAnnotation with ChipyardOption -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") - ) - ) -} - -/** Optional base name for generated files' filenames */ -case class OutputBaseNameAnnotation(outputBaseName: String) extends NoTargetAnnotation with ChipyardOption -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/tools/stage-chisel3/src/main/scala/ChipyardCli.scala b/tools/stage-chisel3/src/main/scala/ChipyardCli.scala deleted file mode 100644 index d6071ff35f..0000000000 --- a/tools/stage-chisel3/src/main/scala/ChipyardCli.scala +++ /dev/null @@ -1,17 +0,0 @@ -// 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( - TopModuleAnnotation, - ConfigsAnnotation, - OutputBaseNameAnnotation, - UnderscoreDelimitedConfigsAnnotation - ).foreach(_.addOptions(parser)) -} diff --git a/tools/stage-chisel3/src/main/scala/ChipyardOptions.scala b/tools/stage-chisel3/src/main/scala/ChipyardOptions.scala deleted file mode 100644 index 8d8eb6e35e..0000000000 --- a/tools/stage-chisel3/src/main/scala/ChipyardOptions.scala +++ /dev/null @@ -1,40 +0,0 @@ -// See LICENSE - -package chipyard.stage - -class ChipyardOptions 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, - ): ChipyardOptions = { - - new ChipyardOptions( - 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/tools/stage-chisel3/src/main/scala/ChipyardStage.scala b/tools/stage-chisel3/src/main/scala/ChipyardStage.scala deleted file mode 100644 index 717a9f956f..0000000000 --- a/tools/stage-chisel3/src/main/scala/ChipyardStage.scala +++ /dev/null @@ -1,41 +0,0 @@ -// 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 firrtl.options.{Phase, PhaseManager, PreservesAll, Shell, Stage, StageError, StageMain, Dependency} -import firrtl.options.phases.DeletedWrapper - -final class ChipyardChiselStage extends ChiselStage { - - override val targets = Seq( - Dependency[chisel3.stage.phases.Checks], - Dependency[chisel3.stage.phases.Elaborate], - Dependency[chisel3.stage.phases.AddImplicitOutputFile], - Dependency[chisel3.stage.phases.AddImplicitOutputAnnotationFile], - Dependency[chisel3.stage.phases.MaybeAspectPhase], - Dependency[chisel3.stage.phases.Emitter], - Dependency[chisel3.stage.phases.Convert] - ) - -} - -class ChipyardStage extends ChiselStage { - override val shell = new Shell("chipyard") with ChipyardCli with ChiselCli with FirrtlCli - override val targets: Seq[PhaseDependency] = Seq( - Dependency[chipyard.stage.phases.Checks], - Dependency[chipyard.stage.phases.TransformAnnotations], - Dependency[chipyard.stage.phases.PreElaboration], - Dependency[ChipyardChiselStage], - Dependency[chipyard.stage.phases.GenerateFirrtlAnnos], - Dependency[chipyard.stage.phases.AddDefaultTests], - Dependency[chipyard.stage.phases.GenerateTestSuiteMakefrags], - Dependency[chipyard.stage.phases.GenerateArtefacts], - ) - override final def invalidates(a: Phase): Boolean = false -} diff --git a/tools/stage-chisel3/src/main/scala/StageUtils.scala b/tools/stage-chisel3/src/main/scala/StageUtils.scala deleted file mode 100644 index 6cfa7174d4..0000000000 --- a/tools/stage-chisel3/src/main/scala/StageUtils.scala +++ /dev/null @@ -1,48 +0,0 @@ -// See LICENSE - -package chipyard.stage - -import java.io.{File, FileWriter} - -import org.chipsalliance.cde.config.{Config, Parameters} -import chisel3.internal.firrtl.Circuit -import freechips.rocketchip.util.{BlackBoxedROM, ROMGenerator} - -trait HasChipyardStageUtils { - - def getConfig(fullConfigClassNames: Seq[String]): Config = { - new Config(fullConfigClassNames.foldRight(Parameters.empty) { case (currentName, config) => - val currentConfig = try { - Class.forName(currentName).newInstance.asInstanceOf[Config] - } catch { - case e: java.lang.ClassNotFoundException => - throw new Exception(s"""Unable to find part "$currentName" from "$fullConfigClassNames", did you misspell it or specify the wrong package path?""", e) - } - currentConfig ++ config - }) - } - - def enumerateROMs(circuit: Circuit): String = { - val res = new StringBuilder - val configs = - circuit.components flatMap { m => - m.id match { - case rom: BlackBoxedROM => Some((rom.name, ROMGenerator.lookup(rom))) - case _ => None - } - } - configs foreach { case (name, c) => - res append s"name ${name} depth ${c.depth} width ${c.width}\n" - } - res.toString - } - - def writeOutputFile(targetDir: String, fname: String, contents: String): File = { - val f = new File(targetDir, fname) - val fw = new FileWriter(f) - fw.write(contents) - fw.close - f - } - -} diff --git a/tools/stage-chisel3/src/main/scala/package.scala b/tools/stage-chisel3/src/main/scala/package.scala deleted file mode 100644 index 5dc89f9cb1..0000000000 --- a/tools/stage-chisel3/src/main/scala/package.scala +++ /dev/null @@ -1,24 +0,0 @@ -// See LICENSE - -package chipyard - -import firrtl.AnnotationSeq -import firrtl.options.OptionsView - -package object stage { - - implicit object ChipyardOptionsView extends OptionsView[ChipyardOptions] { - - def view(annotations: AnnotationSeq): ChipyardOptions = annotations - .collect { case a: ChipyardOption => a } - .foldLeft(new ChipyardOptions()){ (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/tools/stage-chisel3/src/main/scala/phases/AddDefaultTests.scala b/tools/stage-chisel3/src/main/scala/phases/AddDefaultTests.scala deleted file mode 100644 index 3434f392a1..0000000000 --- a/tools/stage-chisel3/src/main/scala/phases/AddDefaultTests.scala +++ /dev/null @@ -1,52 +0,0 @@ -// 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 org.chipsalliance.cde.config.Parameters -import chisel3.stage.phases.Elaborate -import firrtl.AnnotationSeq -import firrtl.annotations.{Annotation, NoTargetAnnotation} -import firrtl.options._ -import firrtl.options.Viewer._ -import freechips.rocketchip.system.{RocketTestSuite, TestGeneration} -import freechips.rocketchip.subsystem.{TilesLocated, InSubsystem, MaxXLen} - -import chipyard.TestSuiteHelper -import chipyard.TestSuitesKey -import chipyard.stage._ - -/** Annotation that contains a list of [[RocketTestSuite]]s to run */ -case class ChipyardTestSuiteAnnotation(tests: Seq[RocketTestSuite]) extends NoTargetAnnotation with Unserializable - - -class AddDefaultTests extends Phase with PreservesAll[Phase] with HasChipyardStageUtils { - override val prerequisites = Seq(Dependency[ChipyardChiselStage]) - override val dependents = Seq(Dependency[GenerateTestSuiteMakefrags]) - - private def addTestSuiteAnnotations(implicit p: Parameters): Seq[Annotation] = { - val annotations = mutable.ArrayBuffer[Annotation]() - val suiteHelper = new TestSuiteHelper - // Use Xlen as a proxy for detecting if we are a processor-like target - // The underlying test suites expect this field to be defined - val tileParams = p(TilesLocated(InSubsystem)) map (tp => tp.tileParams) - if (p.lift(MaxXLen).nonEmpty) - // If a custom test suite is set up, use the custom test suite - annotations += CustomMakefragSnippet(p(TestSuitesKey).apply(tileParams, suiteHelper, p)) - - ChipyardTestSuiteAnnotation(suiteHelper.suites.values.toSeq) +: annotations.toSeq - } - - - override def transform(annotations: AnnotationSeq): AnnotationSeq = { - val (testSuiteAnnos, oAnnos) = annotations.partition { - case ChipyardTestSuiteAnnotation(_) => true - case o => false - } - implicit val p = getConfig(view[ChipyardOptions](annotations).configNames.get).toInstance - addTestSuiteAnnotations(p) ++ oAnnos - } -} diff --git a/tools/stage-chisel3/src/main/scala/phases/Checks.scala b/tools/stage-chisel3/src/main/scala/phases/Checks.scala deleted file mode 100644 index 465f673ad5..0000000000 --- a/tools/stage-chisel3/src/main/scala/phases/Checks.scala +++ /dev/null @@ -1,47 +0,0 @@ -// See LICENSE - -package chipyard.stage.phases - -import firrtl.AnnotationSeq -import firrtl.annotations.Annotation -import firrtl.options.{OptionsException, Phase, PreservesAll, TargetDirAnnotation} -import chipyard.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/tools/stage-chisel3/src/main/scala/phases/GenerateArtefacts.scala b/tools/stage-chisel3/src/main/scala/phases/GenerateArtefacts.scala deleted file mode 100644 index f05d2279a3..0000000000 --- a/tools/stage-chisel3/src/main/scala/phases/GenerateArtefacts.scala +++ /dev/null @@ -1,26 +0,0 @@ -// See LICENSE - -package chipyard.stage.phases - -import firrtl.AnnotationSeq -import firrtl.options.{Dependency, Phase, PreservesAll, StageOptions} -import firrtl.options.Viewer.view -import chipyard.stage._ -import freechips.rocketchip.util.{ElaborationArtefacts} - -/** Writes [[ElaborationArtefacts]] into files */ -class GenerateArtefacts extends Phase with PreservesAll[Phase] with HasChipyardStageUtils { - - override val prerequisites = Seq(Dependency[chipyard.stage.ChipyardChiselStage]) - - override def transform(annotations: AnnotationSeq): AnnotationSeq = { - val targetDir = view[StageOptions](annotations).targetDir - - ElaborationArtefacts.files.foreach { case (extension, contents) => - writeOutputFile(targetDir, s"${view[ChipyardOptions](annotations).longName.get}.${extension}", contents ()) - } - - annotations - } - -} diff --git a/tools/stage-chisel3/src/main/scala/phases/GenerateFirrtlAnnos.scala b/tools/stage-chisel3/src/main/scala/phases/GenerateFirrtlAnnos.scala deleted file mode 100644 index 7e19d40600..0000000000 --- a/tools/stage-chisel3/src/main/scala/phases/GenerateFirrtlAnnos.scala +++ /dev/null @@ -1,36 +0,0 @@ -// See LICENSE - -package chipyard.stage.phases - -import firrtl.AnnotationSeq -import firrtl.annotations.{DeletedAnnotation, JsonProtocol} -import firrtl.options.Viewer.view -import firrtl.options._ -import chipyard.stage._ - -/** Writes FIRRTL annotations into a file */ -class GenerateFirrtlAnnos extends Phase with PreservesAll[Phase] with HasChipyardStageUtils { - - override val prerequisites = Seq(Dependency[chipyard.stage.ChipyardChiselStage]) - - override def transform(annotations: AnnotationSeq): AnnotationSeq = { - val targetDir = view[StageOptions](annotations).targetDir - val fileName = s"${view[ChipyardOptions](annotations).longName.get}.anno.json" - - val annos = annotations.view.flatMap { - // Remove TargetDirAnnotation so that we can pass as argument to FIRRTL - // Remove CustomFileEmission, those are serialized automatically by Stages - case (_: Unserializable | _: TargetDirAnnotation | _: CustomFileEmission) => - None - case DeletedAnnotation(_, (_: Unserializable | _: CustomFileEmission)) => - None - case a => - Some(a) - } - - writeOutputFile(targetDir, fileName, JsonProtocol.serialize(annos.toSeq)) - - annotations - } - -} diff --git a/tools/stage-chisel3/src/main/scala/phases/GenerateTestSuiteMakefrags.scala b/tools/stage-chisel3/src/main/scala/phases/GenerateTestSuiteMakefrags.scala deleted file mode 100644 index 78dd3b962d..0000000000 --- a/tools/stage-chisel3/src/main/scala/phases/GenerateTestSuiteMakefrags.scala +++ /dev/null @@ -1,49 +0,0 @@ -// 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, Dependency} -import firrtl.options.Viewer.view -import chipyard.stage._ -import freechips.rocketchip.system.TestGeneration - -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 HasChipyardStageUtils { - - // Our annotations tend not to be serializable, but are not marked as such. - override val prerequisites = Seq(Dependency[chipyard.stage.phases.GenerateFirrtlAnnos], - Dependency[chipyard.stage.phases.AddDefaultTests]) - - override def transform(annotations: AnnotationSeq): AnnotationSeq = { - val targetDir = view[StageOptions](annotations).targetDir - val fileName = s"${view[ChipyardOptions](annotations).longName.get}.d" - - val makefragBuilder = new mutable.StringBuilder() - val outputAnnotations = annotations.flatMap { - case ChipyardTestSuiteAnnotation(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 - } - - override final def invalidates(a: Phase): Boolean = false -} diff --git a/tools/stage-chisel3/src/main/scala/phases/PreElaboration.scala b/tools/stage-chisel3/src/main/scala/phases/PreElaboration.scala deleted file mode 100644 index 68992e7cfd..0000000000 --- a/tools/stage-chisel3/src/main/scala/phases/PreElaboration.scala +++ /dev/null @@ -1,43 +0,0 @@ -// See LICENSE - -package chipyard.stage.phases - -import chisel3.RawModule -import chisel3.stage.ChiselGeneratorAnnotation -import firrtl.AnnotationSeq -import firrtl.options.Viewer.view -import firrtl.options.{Dependency, Phase, PreservesAll, StageOptions} -import org.chipsalliance.cde.config.{Field, Parameters} -import freechips.rocketchip.diplomacy._ -import chipyard.stage._ - -case object TargetDirKey extends Field[String](".") - -/** Constructs a generator function that returns a top module with given config parameters */ -class PreElaboration extends Phase with PreservesAll[Phase] with HasChipyardStageUtils { - - override val prerequisites = Seq(Dependency[Checks]) - override val dependents = Seq(Dependency[chisel3.stage.phases.Elaborate]) - - override def transform(annotations: AnnotationSeq): AnnotationSeq = { - - val stageOpts = view[StageOptions](annotations) - val rOpts = view[ChipyardOptions](annotations) - val topMod = rOpts.topModule.get - - val config = getConfig(rOpts.configNames.get).alterPartial { - case TargetDirKey => stageOpts.targetDir - } - - 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/tools/stage-chisel3/src/main/scala/phases/TransformAnnotations.scala b/tools/stage-chisel3/src/main/scala/phases/TransformAnnotations.scala deleted file mode 100644 index 0b66f6a6c1..0000000000 --- a/tools/stage-chisel3/src/main/scala/phases/TransformAnnotations.scala +++ /dev/null @@ -1,21 +0,0 @@ -// See LICENSE - -package chipyard.stage.phases - -import chisel3.stage.ChiselOutputFileAnnotation -import firrtl.AnnotationSeq -import firrtl.options.Viewer.view -import firrtl.options.{Dependency, Phase, PreservesAll} -import chipyard.stage._ - -/** Transforms RocketChipAnnotations into those used by other stages */ -class TransformAnnotations extends Phase with PreservesAll[Phase] with HasChipyardStageUtils { - - override val prerequisites = Seq(Dependency[Checks]) - override val dependents = Seq(Dependency[chisel3.stage.phases.AddImplicitOutputFile]) - - override def transform(annotations: AnnotationSeq): AnnotationSeq = { - /** Construct output file annotation for emission */ - new ChiselOutputFileAnnotation(view[ChipyardOptions](annotations).longName.get) +: annotations - } -} diff --git a/tools/stage/src/main/scala/ChipyardStage.scala b/tools/stage/src/main/scala/ChipyardStage.scala index 4b74ebbb73..04c9e1c371 100644 --- a/tools/stage/src/main/scala/ChipyardStage.scala +++ b/tools/stage/src/main/scala/ChipyardStage.scala @@ -11,7 +11,6 @@ import firrtl.options.{Phase, PhaseManager, Shell, Stage, StageError, StageMain, final class ChipyardChiselStage extends ChiselStage { override def run(annotations: AnnotationSeq): AnnotationSeq = { - val pm = new PhaseManager( targets = Seq( Dependency[chisel3.stage.phases.Checks], @@ -36,12 +35,12 @@ final class ChipyardChiselStage extends ChiselStage { } class ChipyardStage extends ChiselStage { + def extraPostPhases: Seq[PhaseManager.PhaseDependency] = Seq.empty override val shell = new Shell("chipyard") with ChipyardCli with circt.stage.CLI { // These are added by firrtl.options.Shell (which we must extend because we are a Stage) override protected def includeLoggerOptions = false } override def run(annotations: AnnotationSeq): AnnotationSeq = { - val pm = new PhaseManager( targets = Seq( Dependency[chipyard.stage.phases.Checks], @@ -52,7 +51,7 @@ class ChipyardStage extends ChiselStage { Dependency[chipyard.stage.phases.AddDefaultTests], Dependency[chipyard.stage.phases.GenerateTestSuiteMakefrags], Dependency[chipyard.stage.phases.GenerateArtefacts], - ), + ) ++ extraPostPhases, currentState = Seq( Dependency[firrtl.stage.phases.AddDefaults], Dependency[firrtl.stage.phases.Checks] @@ -60,15 +59,5 @@ class ChipyardStage extends ChiselStage { ) pm.transform(annotations) } - // override val targets: Seq[PhaseDependency] = Seq( - // Dependency[chipyard.stage.phases.Checks], - // Dependency[chipyard.stage.phases.TransformAnnotations], - // Dependency[chipyard.stage.phases.PreElaboration], - // Dependency[ChipyardChiselStage], - // Dependency[chipyard.stage.phases.GenerateFirrtlAnnos], - // Dependency[chipyard.stage.phases.AddDefaultTests], - // Dependency[chipyard.stage.phases.GenerateTestSuiteMakefrags], - // Dependency[chipyard.stage.phases.GenerateArtefacts], - // ) override final def invalidates(a: Phase): Boolean = false }