From 05c76a984440899c70b0bfecd0f722b05a0feba5 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Fri, 5 Jun 2020 22:27:00 +0000 Subject: [PATCH 1/9] verilator_4_016 --> v4.016 (#1459) (#1464) Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> (cherry picked from commit 803ccbb705288a90c2020a1e13ec714f25ffcb13) Co-authored-by: apaj --- SETUP.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SETUP.md b/SETUP.md index 6bb0e1f2752..5f5e6f4f4e2 100644 --- a/SETUP.md +++ b/SETUP.md @@ -39,7 +39,7 @@ Note that both [PeekPokeTester](https://github.com/freechipsproject/chisel-teste 3. In the Verilator repository directory, check out a known good version: ``` git pull - git checkout verilator_4_016 + git checkout v4.016 ``` 4. In the Verilator repository directory, build and install: From d312bbd5081abfba7b8f71389162c7f3be222c51 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 8 Jun 2020 18:19:56 +0000 Subject: [PATCH 2/9] Grouping Chisel API (#1073) (#1469) * Added group chisel API * Removed println * Added scaladoc * Added more tests * Cleaned spacing and removed println Co-authored-by: Chick Markley Co-authored-by: Jim Lawson Co-authored-by: Schuyler Eldridge (cherry picked from commit 161938b84013a6c3307abc2707f541deddf487b4) Co-authored-by: Adam Izraelevitz --- .../chisel3/util/experimental/group.scala | 67 ++++++++++ .../chiselTests/experimental/GroupSpec.scala | 118 ++++++++++++++++++ 2 files changed, 185 insertions(+) create mode 100644 src/main/scala/chisel3/util/experimental/group.scala create mode 100644 src/test/scala/chiselTests/experimental/GroupSpec.scala diff --git a/src/main/scala/chisel3/util/experimental/group.scala b/src/main/scala/chisel3/util/experimental/group.scala new file mode 100644 index 00000000000..87214ca9c61 --- /dev/null +++ b/src/main/scala/chisel3/util/experimental/group.scala @@ -0,0 +1,67 @@ +// See LICENSE for license details. + +package chisel3.util.experimental + +import chisel3._ +import chisel3.experimental.{ChiselAnnotation, RunFirrtlTransform, annotate} +import chisel3.internal.requireIsHardware +import firrtl.Transform +import firrtl.transforms.{GroupAnnotation, GroupComponents} + +/** Marks that a module to be ignored in Dedup Transform in Firrtl pass + * + * @example {{{ + * class MyModule extends Module { + * val io = IO(new Bundle{ + * val a = Input(Bool()) + * val b = Output(Bool()) + * }) + * val reg1 = RegInit(0.U) + * reg1 := io.a + * val reg2 = RegNext(reg1) + * io.b := reg2 + * group(Seq(reg1, reg2), "DosRegisters", "doubleReg") + * } + * }}} + * + * @note Intermediate wires will get pulled into the new instance, but intermediate registers will not + * because they are also connected to their module's clock port. This means that if you want + * a register to be included in a group, it must be explicitly referred to in the input list. + */ +object group { + + /** Marks a set of components (and their interconnected components) to be included in a new + * instance hierarchy. + * + * @note Intermediate wires will get pulled into the new instance, but intermediate registers will not + * because they are also connected to their module's clock port. This means that if you want + * a register to be included in a group, it must be explicitly referred to in the input list. + * + * @param components components in this group + * @param newModule suggested name of the new module + * @param newInstance suggested name of the instance of the new module + * @param outputSuffix suggested suffix of any output ports of the new module + * @param inputSuffix suggested suffix of any input ports of the new module + * @param compileOptions necessary for backwards compatibility + * @tparam T Parent type of input components + */ + def apply[T <: Data]( + components: Seq[T], + newModule: String, + newInstance: String, + outputSuffix: Option[String] = None, + inputSuffix: Option[String] = None + )(implicit compileOptions: CompileOptions): Unit = { + if (compileOptions.checkSynthesizable) { + components.foreach { data => + requireIsHardware(data, s"Component ${data.toString} is marked to group, but is not bound.") + } + } + annotate(new ChiselAnnotation with RunFirrtlTransform { + def toFirrtl = GroupAnnotation(components.map(_.toNamed), newModule, newInstance, outputSuffix, inputSuffix) + + override def transformClass: Class[_ <: Transform] = classOf[GroupComponents] + }) + } +} + diff --git a/src/test/scala/chiselTests/experimental/GroupSpec.scala b/src/test/scala/chiselTests/experimental/GroupSpec.scala new file mode 100644 index 00000000000..593179f4f90 --- /dev/null +++ b/src/test/scala/chiselTests/experimental/GroupSpec.scala @@ -0,0 +1,118 @@ +// See LICENSE for license details. + +package chiselTests.experimental + +import chiselTests.ChiselFlatSpec +import chisel3._ +import chisel3.RawModule +import chisel3.stage.{ChiselGeneratorAnnotation, ChiselMain} +import chisel3.util.experimental.group +import firrtl.analyses.InstanceGraph +import firrtl.options.TargetDirAnnotation +import firrtl.stage.CompilerAnnotation +import firrtl.{LowFirrtlCompiler, ir => fir} + +import scala.collection.mutable + +class GroupSpec extends ChiselFlatSpec { + + def collectInstances(c: fir.Circuit, top: Option[String] = None): Seq[String] = new InstanceGraph(c) + .fullHierarchy.values.flatten.toSeq + .map( v => (top.getOrElse(v.head.name) +: v.tail.map(_.name)).mkString(".") ) + + def collectDeclarations(m: fir.DefModule): Set[String] = { + val decs = mutable.HashSet[String]() + def onStmt(s: fir.Statement): fir.Statement = s.mapStmt(onStmt) match { + case d: fir.IsDeclaration => decs += d.name; d + case other => other + } + m.mapStmt(onStmt) + decs.toSet + } + + def lower[T <: RawModule](gen: () => T): fir.Circuit = { + (ChiselMain.stage.run( + Seq( + CompilerAnnotation(new LowFirrtlCompiler()), + TargetDirAnnotation("test_run_dir"), + ChiselGeneratorAnnotation(gen) + ) + ) collectFirst { + case firrtl.stage.FirrtlCircuitAnnotation(circuit) => circuit + }).get + } + + "Module Grouping" should "compile to low FIRRTL" in { + class MyModule extends Module { + val io = IO(new Bundle{ + val a = Input(Bool()) + val b = Output(Bool()) + }) + val reg1 = RegInit(0.U) + reg1 := io.a + val reg2 = RegNext(reg1) + io.b := reg2 + group(Seq(reg1, reg2), "DosRegisters", "doubleReg") + } + + val firrtlCircuit = lower(() => new MyModule) + firrtlCircuit.modules.collect { + case m: fir.Module if m.name == "MyModule" => + Set("doubleReg") should be (collectDeclarations(m)) + case m: fir.Module if m.name == "DosRegisters" => + Set("reg1", "reg2") should be (collectDeclarations(m)) + } + val instances = collectInstances(firrtlCircuit, Some("MyModule")).toSet + Set("MyModule", "MyModule.doubleReg") should be (instances) + } + + "Module Grouping" should "not include intermediate registers" in { + class MyModule extends Module { + val io = IO(new Bundle{ + val a = Input(Bool()) + val b = Output(Bool()) + }) + val reg1 = RegInit(0.U) + reg1 := io.a + val reg2 = RegNext(reg1) + val reg3 = RegNext(reg2) + io.b := reg3 + group(Seq(reg1, reg3), "DosRegisters", "doubleReg") + } + + val firrtlCircuit = lower(() => new MyModule) + firrtlCircuit.modules.collect { + case m: fir.Module if m.name == "MyModule" => + Set("reg2", "doubleReg") should be (collectDeclarations(m)) + case m: fir.Module if m.name == "DosRegisters" => + Set("reg1", "reg3") should be (collectDeclarations(m)) + } + val instances = collectInstances(firrtlCircuit, Some("MyModule")).toSet + Set("MyModule", "MyModule.doubleReg") should be (instances) + } + + "Module Grouping" should "include intermediate wires" in { + class MyModule extends Module { + val io = IO(new Bundle{ + val a = Input(Bool()) + val b = Output(Bool()) + }) + val reg1 = RegInit(0.U) + reg1 := io.a + val wire = WireInit(reg1) + val reg3 = RegNext(wire) + io.b := reg3 + group(Seq(reg1, reg3), "DosRegisters", "doubleReg") + } + + val firrtlCircuit = lower(() => new MyModule) + firrtlCircuit.modules.collect { + case m: fir.Module if m.name == "MyModule" => + Set("doubleReg") should be (collectDeclarations(m)) + case m: fir.Module if m.name == "DosRegisters" => + Set("reg1", "reg3", "wire") should be (collectDeclarations(m)) + } + val instances = collectInstances(firrtlCircuit, Some("MyModule")).toSet + Set("MyModule", "MyModule.doubleReg") should be (instances) + } +} From 4d5fc762de1f6f04d3e2a82e1039477b45ae8cbb Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 8 Jun 2020 19:48:06 +0000 Subject: [PATCH 3/9] Report Builder.error errors as exceptions outside hardware context (#1425) (#1470) * Immediately throw Builder.error errors outside hardware context * Add example of hidden no-hardware-context error from #1422 Co-authored-by: Schuyler Eldridge (cherry picked from commit 99ac8a134b134713913036013ffdec98ec92c73a) Co-authored-by: Albert Magyar --- core/src/main/scala/chisel3/internal/Builder.scala | 8 +++++++- src/test/scala/chiselTests/ImplicitConversionsSpec.scala | 7 ++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/chisel3/internal/Builder.scala b/core/src/main/scala/chisel3/internal/Builder.scala index 7e521812161..bacc9fee9a1 100644 --- a/core/src/main/scala/chisel3/internal/Builder.scala +++ b/core/src/main/scala/chisel3/internal/Builder.scala @@ -387,7 +387,13 @@ private[chisel3] object Builder { } def errors: ErrorLog = dynamicContext.errors - def error(m: => String): Unit = if (dynamicContextVar.value.isDefined) errors.error(m) + def error(m: => String): Unit = { + if (dynamicContextVar.value.isDefined) { + errors.error(m) + } else { + throwException(m) + } + } def warning(m: => String): Unit = if (dynamicContextVar.value.isDefined) errors.warning(m) def deprecated(m: => String, location: Option[String] = None): Unit = if (dynamicContextVar.value.isDefined) errors.deprecated(m, location) diff --git a/src/test/scala/chiselTests/ImplicitConversionsSpec.scala b/src/test/scala/chiselTests/ImplicitConversionsSpec.scala index d5939b24721..bde4371755f 100644 --- a/src/test/scala/chiselTests/ImplicitConversionsSpec.scala +++ b/src/test/scala/chiselTests/ImplicitConversionsSpec.scala @@ -39,5 +39,10 @@ class ImplicitConversionsSpec extends ChiselFlatSpec { import chisel3.util._ assertTypeError("Decoupled(UInt(8.W)).target") } -} + "X.B for X not in [0,1]" should "throw an exception, even outside hardware context" in { + a [ChiselException] should be thrownBy { + 65.B + } + } +} From a219f7b2424f97c9e569aa1cc150f46049393e93 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Sat, 20 Jun 2020 00:48:10 +0000 Subject: [PATCH 4/9] Memoize the hashcode of the ChiselCircuitAnnotation (#1485) (#1487) (cherry picked from commit 9bda7a75686e075df038b2c24fbd30ad8ae0d941) Co-authored-by: Jack Koenig --- src/main/scala/chisel3/stage/ChiselAnnotations.scala | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/scala/chisel3/stage/ChiselAnnotations.scala b/src/main/scala/chisel3/stage/ChiselAnnotations.scala index 11697d7debb..e49064566ec 100644 --- a/src/main/scala/chisel3/stage/ChiselAnnotations.scala +++ b/src/main/scala/chisel3/stage/ChiselAnnotations.scala @@ -90,7 +90,12 @@ object ChiselGeneratorAnnotation extends HasShellOptions { /** Stores a Chisel Circuit * @param circuit a Chisel Circuit */ -case class ChiselCircuitAnnotation(circuit: Circuit) extends NoTargetAnnotation with ChiselOption +case class ChiselCircuitAnnotation(circuit: Circuit) extends NoTargetAnnotation with ChiselOption { + /* Caching the hashCode for a large circuit is necessary due to repeated queries. + * Not caching the hashCode will cause severe performance degredations for large [[Circuit]]s. + */ + override lazy val hashCode: Int = circuit.hashCode +} case class ChiselOutputFileAnnotation(file: String) extends NoTargetAnnotation with ChiselOption From 6dbad2fbb783e70e6a0c4826b26e3b976a66eeb4 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 22 Jun 2020 18:07:40 +0000 Subject: [PATCH 5/9] Bump 'removed in 3.3' deprecations to 3.4 (#1439) (#1488) * Closes #1385 Co-authored-by: Schuyler Eldridge (cherry picked from commit 1692b8a1c25fab175d4dff200ed3b15b22260edf) Co-authored-by: Albert Magyar --- core/src/main/scala/chisel3/core/package.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/main/scala/chisel3/core/package.scala b/core/src/main/scala/chisel3/core/package.scala index 92c4617bd19..6d5bea1375f 100644 --- a/core/src/main/scala/chisel3/core/package.scala +++ b/core/src/main/scala/chisel3/core/package.scala @@ -62,16 +62,16 @@ package object core { // These provide temporary compatibility for those who foolishly imported from chisel3.core @deprecated("Avoid importing from chisel3.core, these are not public APIs and may change at any time. " + - " Use chisel3.RawModule instead. This alias will be removed in 3.3.", "since the beginning of time") + " Use chisel3.RawModule instead. This alias will be removed in 3.4.", "since the beginning of time") type RawModule = chisel3.RawModule @deprecated("Avoid importing from chisel3.core, these are not public APIs and may change at any time. " + - "Use chisel3.MultiIOModule instead. This alias will be removed in 3.3.", "since the beginning of time") + "Use chisel3.MultiIOModule instead. This alias will be removed in 3.4.", "since the beginning of time") type MultiIOModule = chisel3.MultiIOModule @deprecated("Avoid importing from chisel3.core, these are not public APIs and may change at any time. " + - " Use chisel3.RawModule instead. This alias will be removed in 3.3.", "since the beginning of time") + " Use chisel3.RawModule instead. This alias will be removed in 3.4.", "since the beginning of time") type UserModule = chisel3.RawModule @deprecated("Avoid importing from chisel3.core, these are not public APIs and may change at any time. " + - "Use chisel3.MultiIOModule instead. This alias will be removed in 3.3.", "since the beginning of time") + "Use chisel3.MultiIOModule instead. This alias will be removed in 3.4.", "since the beginning of time") type ImplicitModule = chisel3.MultiIOModule @deprecated("Use the version in chisel3._", "3.2") From 4bd52508272f07ef931375cba892b33661703ee2 Mon Sep 17 00:00:00 2001 From: Jack Koenig Date: Mon, 22 Jun 2020 11:24:30 -0700 Subject: [PATCH 6/9] Bump Mima check to 3.3.1 (#1461) --- build.sbt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.sbt b/build.sbt index 33798966e4a..fc5e4927f96 100644 --- a/build.sbt +++ b/build.sbt @@ -126,7 +126,7 @@ lazy val macros = (project in file("macros")). settings(name := "chisel3-macros"). settings(commonSettings: _*). settings(publishSettings: _*). - settings(mimaPreviousArtifacts := Set("edu.berkeley.cs" %% "chisel3-macros" % "3.3.0")) + settings(mimaPreviousArtifacts := Set("edu.berkeley.cs" %% "chisel3-macros" % "3.3.1")) lazy val core = (project in file("core")). settings(commonSettings: _*). @@ -143,7 +143,7 @@ lazy val core = (project in file("core")). "-Xlint:infer-any" // "-Xlint:missing-interpolator" ), - mimaPreviousArtifacts := Set("edu.berkeley.cs" %% "chisel3-core" % "3.3.0") + mimaPreviousArtifacts := Set("edu.berkeley.cs" %% "chisel3-core" % "3.3.1") ). dependsOn(macros) @@ -165,7 +165,7 @@ lazy val chisel = (project in file(".")). dependsOn(core). aggregate(macros, core). settings( - mimaPreviousArtifacts := Set("edu.berkeley.cs" %% "chisel3" % "3.3.0"), + mimaPreviousArtifacts := Set("edu.berkeley.cs" %% "chisel3" % "3.3.1"), scalacOptions in Test ++= Seq("-language:reflectiveCalls"), scalacOptions in Compile in doc ++= Seq( "-diagrams", From b03eceeb81bd6e26447b077a616e02c8baefa9f5 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 22 Jun 2020 20:39:34 +0000 Subject: [PATCH 7/9] Canonicalize construction of Decoupled with no payload (#785) (#1491) * Canonicalize construction of empty Decoupled * Change signature after dev meeting discussion * Make EmptyBundle private and final * Add test case for Decoupled with no payload * Apply suggestions from code review Co-authored-by: Richard Lin Co-authored-by: Albert Magyar Co-authored-by: Schuyler Eldridge Co-authored-by: Adam Izraelevitz Co-authored-by: Richard Lin Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> (cherry picked from commit 28e1a244bcc75a1138d25f5aa43ef22e23ef3ed7) Co-authored-by: Jack Koenig --- src/main/scala/chisel3/util/Decoupled.scala | 9 +++++++++ .../scala/chiselTests/DecoupledSpec.scala | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 src/test/scala/chiselTests/DecoupledSpec.scala diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index 6a3aad2461b..82511ee5231 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -92,6 +92,15 @@ object Decoupled /** Wraps some Data with a DecoupledIO interface. */ def apply[T <: Data](gen: T): DecoupledIO[T] = new DecoupledIO(gen) + // TODO: use a proper empty data type, this is a quick and dirty solution + private final class EmptyBundle extends Bundle + + // Both of these methods return DecoupledIO parameterized by the most generic type: Data + /** Returns a [[DecoupledIO]] inteface with no payload */ + def apply(): DecoupledIO[Data] = apply(new EmptyBundle) + /** Returns a [[DecoupledIO]] inteface with no payload */ + def empty: DecoupledIO[Data] = Decoupled() + /** Downconverts an IrrevocableIO output to a DecoupledIO, dropping guarantees of irrevocability. * * @note unsafe (and will error) on the producer (input) side of an IrrevocableIO diff --git a/src/test/scala/chiselTests/DecoupledSpec.scala b/src/test/scala/chiselTests/DecoupledSpec.scala new file mode 100644 index 00000000000..c251df8215b --- /dev/null +++ b/src/test/scala/chiselTests/DecoupledSpec.scala @@ -0,0 +1,19 @@ +// See LICENSE for license details. + +package chiselTests + +import chisel3._ +import chisel3.util.Decoupled + +class DecoupledSpec extends ChiselFlatSpec { + "Decoupled() and Decoupled.empty" should "give DecoupledIO with empty payloads" in { + elaborate(new Module { + val io = IO(new Bundle { + val in = Flipped(Decoupled()) + val out = Decoupled.empty + }) + io.out <> io.in + assert(io.asUInt.widthOption.get === 4) + }) + } +} From 4e783e2c98f1d28472968f1def6b26f112e199d5 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 23 Jun 2020 16:26:22 -0400 Subject: [PATCH 8/9] Remove Deprecated Usages of chisel3.Driver, CircuitForm (bp #1481) (#1492) * Add containsCause exception search testing util * Use ChiselStage in Tests * Remove Driver usage in Emitter * Remove Driver usage in ChiselSpec * Remove Driver usage from Chisel._ package * Deprecate Driver Execution classes * Code simplification in internal Chisel._ method * Clarify chiselTests.Utils.extractCause Scaladoc Co-authored-by: Chick Markley Co-authored-by: Schuyler Eldridge Signed-off-by: Schuyler Eldridge --- src/main/scala/chisel3/Driver.scala | 3 + src/main/scala/chisel3/compatibility.scala | 21 ++++- .../chisel3/internal/firrtl/Emitter.scala | 2 +- .../scala/chisel3/testers/TesterDriver.scala | 68 +++++++++-------- src/test/scala/chiselTests/AnalogSpec.scala | 42 +++++----- .../chiselTests/AnnotatingDiamondSpec.scala | 71 ++++++++--------- .../scala/chiselTests/AnnotationNoDedup.scala | 48 ++++++------ src/test/scala/chiselTests/Assert.scala | 7 +- .../scala/chiselTests/AsyncResetSpec.scala | 15 ++-- .../scala/chiselTests/AutoClonetypeSpec.scala | 37 ++++----- .../chiselTests/AutoNestedCloneSpec.scala | 19 ++--- .../scala/chiselTests/BetterNamingTests.scala | 12 +-- src/test/scala/chiselTests/BlackBox.scala | 3 +- src/test/scala/chiselTests/BlackBoxImpl.scala | 45 +++++------ .../scala/chiselTests/BoringUtilsSpec.scala | 17 +++-- .../scala/chiselTests/BundleLiteralSpec.scala | 76 ++++++++++++++----- src/test/scala/chiselTests/BundleSpec.scala | 21 ++--- src/test/scala/chiselTests/ChiselSpec.scala | 71 +++++++++++------ src/test/scala/chiselTests/Clock.scala | 3 +- .../scala/chiselTests/CloneModuleSpec.scala | 5 +- .../scala/chiselTests/CompatibilitySpec.scala | 61 +++++++-------- .../chiselTests/CompileOptionsTest.scala | 33 ++++---- src/test/scala/chiselTests/ConnectSpec.scala | 61 +++++++++++---- src/test/scala/chiselTests/DataPrint.scala | 7 +- .../scala/chiselTests/DecoupledSpec.scala | 3 +- src/test/scala/chiselTests/Direction.scala | 51 ++++++------- .../scala/chiselTests/DontTouchSpec.scala | 8 +- .../chiselTests/EnableShiftRegister.scala | 3 +- src/test/scala/chiselTests/ExtModule.scala | 3 +- .../scala/chiselTests/FixedPointSpec.scala | 7 +- src/test/scala/chiselTests/GCD.scala | 3 +- .../scala/chiselTests/IOCompatibility.scala | 11 +-- src/test/scala/chiselTests/InlineSpec.scala | 57 +++++++++----- .../scala/chiselTests/InstanceNameSpec.scala | 3 +- src/test/scala/chiselTests/IntervalSpec.scala | 44 ++++------- .../scala/chiselTests/InvalidateAPISpec.scala | 17 +++-- .../chiselTests/LiteralExtractorSpec.scala | 3 +- .../chiselTests/LoadMemoryFromFileSpec.scala | 72 ++++++++---------- src/test/scala/chiselTests/MemorySearch.scala | 3 +- .../MissingCloneBindingExceptionSpec.scala | 11 +-- src/test/scala/chiselTests/MixedVecSpec.scala | 23 +++--- src/test/scala/chiselTests/Module.scala | 37 ++++----- .../chiselTests/ModuleExplicitResetSpec.scala | 4 +- src/test/scala/chiselTests/MultiAssign.scala | 43 +++++++---- .../scala/chiselTests/MultiClockSpec.scala | 7 +- src/test/scala/chiselTests/MuxSpec.scala | 14 ++-- .../chiselTests/NamingAnnotationTest.scala | 15 ++-- src/test/scala/chiselTests/OptionBundle.scala | 7 +- src/test/scala/chiselTests/Padding.scala | 3 +- .../scala/chiselTests/PrintableSpec.scala | 25 +++--- .../scala/chiselTests/RawModuleSpec.scala | 13 +++- .../scala/chiselTests/RebindingSpec.scala | 11 +-- src/test/scala/chiselTests/RecordSpec.scala | 19 ++--- src/test/scala/chiselTests/Reg.scala | 7 +- src/test/scala/chiselTests/ResetSpec.scala | 13 ++-- src/test/scala/chiselTests/Risc.scala | 3 +- src/test/scala/chiselTests/SIntOps.scala | 9 ++- src/test/scala/chiselTests/Stack.scala | 3 +- src/test/scala/chiselTests/StrongEnum.scala | 67 ++++++++-------- src/test/scala/chiselTests/SwitchSpec.scala | 11 +-- .../scala/chiselTests/TransitNameSpec.scala | 20 ++--- src/test/scala/chiselTests/UIntOps.scala | 16 ++-- src/test/scala/chiselTests/Vec.scala | 19 ++--- src/test/scala/chiselTests/When.scala | 7 +- .../chiselTests/experimental/GroupSpec.scala | 18 ++--- .../experimental/ProgrammaticPortsSpec.scala | 10 +-- .../chiselTests/stage/ChiselMainSpec.scala | 8 +- .../stage/phases/ConvertSpec.scala | 10 ++- .../chiselTests/util/random/LFSRSpec.scala | 20 +++-- .../chiselTests/util/random/PRNGSpec.scala | 15 ++-- 70 files changed, 852 insertions(+), 672 deletions(-) diff --git a/src/main/scala/chisel3/Driver.scala b/src/main/scala/chisel3/Driver.scala index 571fff6066e..6ac0a5c169a 100644 --- a/src/main/scala/chisel3/Driver.scala +++ b/src/main/scala/chisel3/Driver.scala @@ -61,6 +61,7 @@ trait BackendCompilationUtilities extends FirrtlBackendCompilationUtilities { /** * This family provides return values from the chisel3 and possibly firrtl compile steps */ +@deprecated("This will be removed in Chisel 3.5", "Chisel3 3.4") trait ChiselExecutionResult /** @@ -69,6 +70,7 @@ trait ChiselExecutionResult * @param emitted The emitted Chirrrl text * @param firrtlResultOption Optional Firrtl result, @see freechipsproject/firrtl for details */ +@deprecated("This will be removed in Chisel 3.5", "Chisel 3.4") case class ChiselExecutionSuccess( circuitOption: Option[Circuit], emitted: String, @@ -80,6 +82,7 @@ case class ChiselExecutionSuccess( * * @param message A clue might be provided here. */ +@deprecated("This will be removed in Chisel 3.5", "Chisel 3.4") case class ChiselExecutionFailure(message: String) extends ChiselExecutionResult @deprecated("Please switch to chisel3.stage.ChiselStage. Driver will be removed in 3.4.", "3.2.4") diff --git a/src/main/scala/chisel3/compatibility.scala b/src/main/scala/chisel3/compatibility.scala index 9584fad68e7..255592e52d8 100644 --- a/src/main/scala/chisel3/compatibility.scala +++ b/src/main/scala/chisel3/compatibility.scala @@ -4,6 +4,7 @@ * while moving to the more standard package naming convention `chisel3` (lowercase c). */ import chisel3._ // required for implicit conversions. +import chisel3.stage.{ChiselCircuitAnnotation, ChiselOutputFileAnnotation, ChiselStage, phases} package object Chisel { // scalastyle:ignore package.object.name number.of.types number.of.methods import chisel3.internal.firrtl.Width @@ -400,14 +401,26 @@ package object Chisel { // scalastyle:ignore package.object.name number.of.t object chiselMain { import java.io.File + private var target_dir: Option[String] = None + + private def parseArgs(args: Array[String]): Unit = { + for (i <- args.indices) { + if (args(i) == "--targetDir") { + target_dir = Some(args(i + 1)) + } + } + } + def apply[T <: Module](args: Array[String], gen: () => T): Unit = Predef.assert(false, "No more chiselMain in Chisel3") def run[T <: Module] (args: Array[String], gen: () => T): Unit = { - val circuit = Driver.elaborate(gen) - Driver.parseArgs(args) - val output_file = new File(Driver.targetDir + "/" + circuit.name + ".fir") - Driver.dumpFirrtl(circuit, Option(output_file)) + val circuit = ChiselStage.elaborate(gen()) + parseArgs(args) + val output_file = new File(target_dir.getOrElse(new File(".").getCanonicalPath) + "/" + circuit.name + ".fir") + + (new phases.Emitter).transform(Seq(ChiselCircuitAnnotation(circuit), + ChiselOutputFileAnnotation(output_file.toString))) } } diff --git a/src/main/scala/chisel3/internal/firrtl/Emitter.scala b/src/main/scala/chisel3/internal/firrtl/Emitter.scala index 1341b5f61d3..2124fa25167 100644 --- a/src/main/scala/chisel3/internal/firrtl/Emitter.scala +++ b/src/main/scala/chisel3/internal/firrtl/Emitter.scala @@ -186,7 +186,7 @@ private class Emitter(circuit: Circuit) { private def withIndent(f: => Unit) { indent(); f; unindent() } private val res = new StringBuilder() - res ++= s";${Driver.chiselVersionString}\n" + res ++= s";${BuildInfo.toString}\n" res ++= s"circuit ${circuit.name} : " withIndent { circuit.components.foreach(c => res ++= emit(c)) } res ++= newline diff --git a/src/main/scala/chisel3/testers/TesterDriver.scala b/src/main/scala/chisel3/testers/TesterDriver.scala index 7e3730a3820..2724da166f2 100644 --- a/src/main/scala/chisel3/testers/TesterDriver.scala +++ b/src/main/scala/chisel3/testers/TesterDriver.scala @@ -7,34 +7,53 @@ import java.io._ import chisel3.aop.Aspect import chisel3.experimental.RunFirrtlTransform -import chisel3.stage.phases.AspectPhase -import chisel3.stage.{ChiselCircuitAnnotation, ChiselStage, DesignAnnotation} +import chisel3.stage.phases.{AspectPhase, Convert, Elaborate, Emitter} +import chisel3.stage.{ + ChiselCircuitAnnotation, + ChiselGeneratorAnnotation, + ChiselOutputFileAnnotation, + ChiselStage, + DesignAnnotation +} import firrtl.{Driver => _, _} +import firrtl.options.{Dependency, Phase, PhaseManager} +import firrtl.stage.{FirrtlCircuitAnnotation, FirrtlStage} import firrtl.transforms.BlackBoxSourceHelper.writeResourceToDirectory object TesterDriver extends BackendCompilationUtilities { + /** Set the target directory to the name of the top module after elaboration */ + final class AddImplicitTesterDirectory extends Phase { + override def prerequisites = Seq(Dependency[Elaborate]) + override def optionalPrerequisites = Seq.empty + override def optionalPrerequisiteOf = Seq(Dependency[Emitter]) + override def invalidates(a: Phase) = false + + override def transform(a: AnnotationSeq) = a.flatMap { + case a@ ChiselCircuitAnnotation(circuit) => + Seq(a, TargetDirAnnotation( + firrtl.util.BackendCompilationUtilities.createTestDirectory(circuit.name) + .getAbsolutePath + .toString)) + case a => Seq(a) + } + } + /** For use with modules that should successfully be elaborated by the * frontend, and which can be turned into executables with assertions. */ def execute(t: () => BasicTester, additionalVResources: Seq[String] = Seq(), annotations: AnnotationSeq = Seq() ): Boolean = { - // Invoke the chisel compiler to get the circuit's IR - val (circuit, dut) = new chisel3.stage.ChiselGeneratorAnnotation(finishWrapper(t)).elaborate.toSeq match { - case Seq(ChiselCircuitAnnotation(cir), d:DesignAnnotation[_]) => (cir, d) - } - - // Set up a bunch of file handlers based on a random temp filename, - // plus the quirks of Verilator's naming conventions - val target = circuit.name + val pm = new PhaseManager( + targets = Seq(Dependency[AddImplicitTesterDirectory], + Dependency[Emitter], + Dependency[Convert])) - val path = createTestDirectory(target) - val fname = new File(path, target) + val annotationsx = pm.transform(ChiselGeneratorAnnotation(t) +: annotations) - // For now, dump the IR out to a file - Driver.dumpFirrtl(circuit, Some(new File(fname.toString + ".fir"))) - val firrtlCircuit = Driver.toFirrtl(circuit) + val target: String = annotationsx.collectFirst { case FirrtlCircuitAnnotation(cir) => cir.main }.get + val path = annotationsx.collectFirst { case TargetDirAnnotation(dir) => dir }.map(new File(_)).get // Copy CPP harness and other Verilog sources from resources into files val cppHarness = new File(path, "top.cpp") @@ -47,24 +66,7 @@ object TesterDriver extends BackendCompilationUtilities { writeResourceToDirectory(name, path) }) - // Compile firrtl - val transforms = circuit.annotations.collect { - case anno: RunFirrtlTransform => anno.transformClass - }.distinct - .filterNot(_ == classOf[Transform]) - .map { transformClass: Class[_ <: Transform] => transformClass.newInstance() } - val newAnnotations = circuit.annotations.map(_.toFirrtl).toList ++ annotations ++ Seq(dut) - val resolvedAnnotations = new AspectPhase().transform(newAnnotations).toList - val optionsManager = new ExecutionOptionsManager("chisel3") with HasChiselExecutionOptions with HasFirrtlOptions { - commonOptions = CommonOptions(topName = target, targetDirName = path.getAbsolutePath) - firrtlOptions = FirrtlExecutionOptions(compilerName = "verilog", annotations = resolvedAnnotations, - customTransforms = transforms, - firrtlCircuit = Some(firrtlCircuit)) - } - firrtl.Driver.execute(optionsManager) match { - case _: FirrtlExecutionFailure => return false - case _ => - } + (new FirrtlStage).execute(Array("--compiler", "verilog"), annotationsx) // Use sys.Process to invoke a bunch of backend stuff, then run the resulting exe if ((verilogToCpp(target, path, additionalVFiles, cppHarness) #&& diff --git a/src/test/scala/chiselTests/AnalogSpec.scala b/src/test/scala/chiselTests/AnalogSpec.scala index c443ce7bdaf..7fca6b7be53 100644 --- a/src/test/scala/chiselTests/AnalogSpec.scala +++ b/src/test/scala/chiselTests/AnalogSpec.scala @@ -3,6 +3,7 @@ package chiselTests import chisel3._ +import chisel3.stage.ChiselStage import chisel3.util._ import chisel3.testers.BasicTester import chisel3.experimental.{Analog, attach, BaseModule} @@ -82,12 +83,12 @@ abstract class AnalogTester extends BasicTester { assert(reader.out === BusValue) } -class AnalogSpec extends ChiselFlatSpec { +class AnalogSpec extends ChiselFlatSpec with Utils { behavior of "Analog" it should "NOT be bindable to registers" in { - a [ChiselException] should be thrownBy { - elaborate { new Module { + a [ChiselException] should be thrownBy extractCause[ChiselException] { + ChiselStage.elaborate { new Module { val io = IO(new Bundle {}) val reg = Reg(Analog(32.W)) }} @@ -95,15 +96,15 @@ class AnalogSpec extends ChiselFlatSpec { } it should "NOT be bindable to a direction" in { - a [ChiselException] should be thrownBy { - elaborate { new Module { + a [ChiselException] should be thrownBy extractCause[ChiselException] { + ChiselStage.elaborate { new Module { val io = IO(new Bundle { val a = Input(Analog(32.W)) }) }} } - a [ChiselException] should be thrownBy { - elaborate { new Module { + a [ChiselException] should be thrownBy extractCause[ChiselException] { + ChiselStage.elaborate { new Module { val io = IO(new Bundle { val a = Output(Analog(32.W)) }) @@ -112,7 +113,7 @@ class AnalogSpec extends ChiselFlatSpec { } it should "be flippable" in { - elaborate { new Module { + ChiselStage.elaborate { new Module { val io = IO(new Bundle { val a = Flipped(Analog(32.W)) }) @@ -122,8 +123,8 @@ class AnalogSpec extends ChiselFlatSpec { // There is no binding on the type of a memory // Should this be an error? ignore should "NOT be a legal type for Mem" in { - a [ChiselException] should be thrownBy { - elaborate { new Module { + a [ChiselException] should be thrownBy extractCause[ChiselException] { + ChiselStage.elaborate { new Module { val io = IO(new Bundle {}) val mem = Mem(16, Analog(32.W)) }} @@ -131,8 +132,8 @@ class AnalogSpec extends ChiselFlatSpec { } it should "NOT be bindable to Mem ports" in { - a [ChiselException] should be thrownBy { - elaborate { new Module { + a [ChiselException] should be thrownBy extractCause[ChiselException] { + ChiselStage.elaborate { new Module { val io = IO(new Bundle {}) val mem = Mem(16, Analog(32.W)) val port = mem(5.U) @@ -161,16 +162,16 @@ class AnalogSpec extends ChiselFlatSpec { } it should "error if any bulk connected more than once" in { - a [ChiselException] should be thrownBy { - elaborate(new Module { + a [ChiselException] should be thrownBy extractCause[ChiselException] { + ChiselStage.elaborate(new Module { val io = IO(new Bundle {}) val wires = List.fill(3)(Wire(Analog(32.W))) wires(0) <> wires(1) wires(0) <> wires(2) }) } - a [ChiselException] should be thrownBy { - elaborate(new Module { + a [ChiselException] should be thrownBy extractCause[ChiselException] { + ChiselStage.elaborate(new Module { val io = IO(new Bundle {}) val wires = List.fill(2)(Wire(Analog(32.W))) wires(0) <> DontCare @@ -180,13 +181,13 @@ class AnalogSpec extends ChiselFlatSpec { } it should "allow DontCare connection" in { - elaborate(new Module { + ChiselStage.elaborate(new Module { val io = IO(new Bundle { val a = Analog(1.W) }) io.a := DontCare }) - elaborate(new Module { + ChiselStage.elaborate(new Module { val io = IO(new Bundle { val a = Analog(1.W) }) @@ -199,14 +200,14 @@ class AnalogSpec extends ChiselFlatSpec { val x = Input(UInt(8.W)) val y = Analog(8.W) } - elaborate(new Module { + ChiselStage.elaborate(new Module { val io = IO(new Bundle { val a = new MyBundle }) val w = Wire(new MyBundle) w <> io.a }) - elaborate(new Module { + ChiselStage.elaborate(new Module { val io = IO(new Bundle { val a = Vec(1, new MyBundle) }) @@ -295,4 +296,3 @@ class AnalogSpec extends ChiselFlatSpec { }, Seq("/chisel3/AnalogBlackBox.v")) } } - diff --git a/src/test/scala/chiselTests/AnnotatingDiamondSpec.scala b/src/test/scala/chiselTests/AnnotatingDiamondSpec.scala index f63fcb3d54e..70a62555eae 100644 --- a/src/test/scala/chiselTests/AnnotatingDiamondSpec.scala +++ b/src/test/scala/chiselTests/AnnotatingDiamondSpec.scala @@ -5,13 +5,16 @@ package chiselTests import chisel3._ import chisel3.experimental.{ChiselAnnotation, RunFirrtlTransform, annotate} import chisel3.internal.InstanceId +import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} import chisel3.testers.BasicTester -import firrtl.{CircuitForm, CircuitState, LowForm, Transform} +import firrtl.{CircuitForm, CircuitState, DependencyAPIMigration, LowForm, Transform} import firrtl.annotations.{ + CircuitName, + CircuitTarget, SingleTargetAnnotation, - ModuleName, - Named + Target } +import firrtl.stage.Forms import org.scalatest._ import org.scalatest.freespec.AnyFreeSpec import org.scalatest.matchers.should.Matchers @@ -19,8 +22,8 @@ import org.scalatest.matchers.should.Matchers /** These annotations and the IdentityTransform class serve as an example of how to write a * Chisel/Firrtl library */ -case class IdentityAnnotation(target: Named, value: String) extends SingleTargetAnnotation[Named] { - def duplicate(n: Named): IdentityAnnotation = this.copy(target = n) +case class IdentityAnnotation(target: Target, value: String) extends SingleTargetAnnotation[Target] { + def duplicate(n: Target): IdentityAnnotation = this.copy(target = n) } /** ChiselAnnotation that corresponds to the above FIRRTL annotation */ case class IdentityChiselAnnotation(target: InstanceId, value: String) @@ -35,9 +38,11 @@ object identify { // scalastyle:ignore object.name } } -class IdentityTransform extends Transform { - def inputForm: CircuitForm = LowForm - def outputForm: CircuitForm = LowForm +class IdentityTransform extends Transform with DependencyAPIMigration { + override def prerequisites = Forms.LowForm + override def optionalPrerequisites = Seq.empty + override def optionalPrerequisiteOf = Forms.LowEmitters + override def invalidates(a: Transform) = false def execute(state: CircuitState): CircuitState = { val annosx = state.annotations.map { @@ -133,33 +138,29 @@ class DiamondTester extends BasicTester { class AnnotatingDiamondSpec extends AnyFreeSpec with Matchers { - """ - |Diamond is an example of a module that has two sub-modules A and B who both instantiate their - |own instances of module C. This highlights the difference between specific and general - |annotation scopes - """.stripMargin - { - - """ - |annotations are not resolved at after circuit elaboration, - |that happens only after emit has been called on circuit""".stripMargin in { - - Driver.execute(Array("--target-dir", "test_run_dir"), () => new TopOfDiamond) match { - case ChiselExecutionSuccess(Some(circuit), emitted, _) => - val annos = circuit.annotations.map(_.toFirrtl) - annos.count(_.isInstanceOf[IdentityAnnotation]) should be (10) - - annos.count { - case IdentityAnnotation(ModuleName("ModC", _), "ModC(16)") => true - case _ => false - } should be (1) - - annos.count { - case IdentityAnnotation(ModuleName("ModC_1", _), "ModC(32)") => true - case _ => false - } should be (1) - case _ => - assert(false) - } + """|Diamond is an example of a module that has two sub-modules A and B who both instantiate their + |own instances of module C. This highlights the difference between specific and general + |annotation scopes""".stripMargin - { + + """|annotations are not resolved at after circuit elaboration, + |that happens only after emit has been called on circuit""".stripMargin in { + + val annos = (new ChiselStage) + .execute(Array("--target-dir", "test_run_dir", "--no-run-firrtl"), + Seq(ChiselGeneratorAnnotation(() => new TopOfDiamond))) + .filter { + case _: IdentityAnnotation => true + case _ => false + }.toSeq + + info("Found ten (10) 'IdentityAnnotation's") + annos should have length (10) + + info("Found IdentityAnnotation targeting '~*|ModC' with value 'ModC(16)'") + annos should contain (IdentityAnnotation(CircuitTarget("TopOfDiamond").module("ModC"), "ModC(16)")) + + info("Found IdentityAnnotation targeting '~*|ModC_1:seen' with value 'ModC(32)'") + annos should contain (IdentityAnnotation(CircuitTarget("TopOfDiamond").module("ModC_1"), "ModC(32)")) } } } diff --git a/src/test/scala/chiselTests/AnnotationNoDedup.scala b/src/test/scala/chiselTests/AnnotationNoDedup.scala index d9cf6110360..ff0005b4689 100644 --- a/src/test/scala/chiselTests/AnnotationNoDedup.scala +++ b/src/test/scala/chiselTests/AnnotationNoDedup.scala @@ -4,7 +4,8 @@ package chiselTests import chisel3._ import chisel3.experimental.doNotDedup -import firrtl.FirrtlExecutionSuccess +import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} +import firrtl.stage.FirrtlCircuitAnnotation import org.scalatest.freespec.AnyFreeSpec import org.scalatest.matchers.should.Matchers @@ -41,33 +42,34 @@ class UsesMuchUsedModule(addAnnos: Boolean) extends Module { } class AnnotationNoDedup extends AnyFreeSpec with Matchers { + val stage = new ChiselStage // scalastyle:off line.size.limit "Firrtl provides transform that reduces identical modules to a single instance" - { "Annotations can be added which will prevent this deduplication for specific modules instances" in { - Driver.execute(Array("-X", "low", "--target-dir", "test_run_dir"), () => new UsesMuchUsedModule(addAnnos = true)) match { - case ChiselExecutionSuccess(_, _, Some(firrtlResult: FirrtlExecutionSuccess)) => - val lowFirrtl = firrtlResult.emitted - - lowFirrtl should include ("module MuchUsedModule :") - lowFirrtl should include ("module MuchUsedModule_1 :") - lowFirrtl should include ("module MuchUsedModule_3 :") - lowFirrtl should not include "module MuchUsedModule_2 :" - lowFirrtl should not include "module MuchUsedModule_4 :" - case _ => - } + val lowFirrtl = stage + .execute(Array("-X", "low", "--target-dir", "test_run_dir"), + Seq(ChiselGeneratorAnnotation(() => new UsesMuchUsedModule(addAnnos = true)))) + .collectFirst { + case FirrtlCircuitAnnotation(circuit) => circuit.serialize + }.getOrElse(fail) + lowFirrtl should include ("module MuchUsedModule :") + lowFirrtl should include ("module MuchUsedModule_1 :") + lowFirrtl should include ("module MuchUsedModule_3 :") + lowFirrtl should not include "module MuchUsedModule_2 :" + lowFirrtl should not include "module MuchUsedModule_4 :" } "Turning off these annotations dedups all the occurrences" in { - Driver.execute(Array("-X", "low", "--target-dir", "test_run_dir"), () => new UsesMuchUsedModule(addAnnos = false)) match { - case ChiselExecutionSuccess(_, _, Some(firrtlResult: FirrtlExecutionSuccess)) => - val lowFirrtl = firrtlResult.emitted - - lowFirrtl should include ("module MuchUsedModule :") - lowFirrtl should not include "module MuchUsedModule_1 :" - lowFirrtl should not include "module MuchUsedModule_3 :" - lowFirrtl should not include "module MuchUsedModule_2 :" - lowFirrtl should not include "module MuchUsedModule_4 :" - case _ => - } + val lowFirrtl = stage + .execute(Array("-X", "low", "--target-dir", "test_run_dir"), + Seq(ChiselGeneratorAnnotation(() => new UsesMuchUsedModule(addAnnos = false)))) + .collectFirst { + case FirrtlCircuitAnnotation(circuit) => circuit.serialize + }.getOrElse(fail) + lowFirrtl should include ("module MuchUsedModule :") + lowFirrtl should not include "module MuchUsedModule_1 :" + lowFirrtl should not include "module MuchUsedModule_3 :" + lowFirrtl should not include "module MuchUsedModule_2 :" + lowFirrtl should not include "module MuchUsedModule_4 :" } } // scalastyle:on line.size.limit diff --git a/src/test/scala/chiselTests/Assert.scala b/src/test/scala/chiselTests/Assert.scala index 3bea2e4f359..f564100f35a 100644 --- a/src/test/scala/chiselTests/Assert.scala +++ b/src/test/scala/chiselTests/Assert.scala @@ -3,6 +3,7 @@ package chiselTests import chisel3._ +import chisel3.stage.ChiselStage import chisel3.testers.BasicTester import chisel3.util._ @@ -60,7 +61,7 @@ class BadUnescapedPercentAssertTester extends BasicTester { stop() } -class AssertSpec extends ChiselFlatSpec { +class AssertSpec extends ChiselFlatSpec with Utils { "A failing assertion" should "fail the testbench" in { assert(!runTester{ new FailingAssertTester }) } @@ -78,7 +79,9 @@ class AssertSpec extends ChiselFlatSpec { } they should "not allow unescaped % in the message" in { a [java.util.UnknownFormatConversionException] should be thrownBy { - elaborate { new BadUnescapedPercentAssertTester } + extractCause[java.util.UnknownFormatConversionException] { + ChiselStage.elaborate { new BadUnescapedPercentAssertTester } + } } } } diff --git a/src/test/scala/chiselTests/AsyncResetSpec.scala b/src/test/scala/chiselTests/AsyncResetSpec.scala index a6bf3a8a824..4f1bd13403e 100644 --- a/src/test/scala/chiselTests/AsyncResetSpec.scala +++ b/src/test/scala/chiselTests/AsyncResetSpec.scala @@ -3,6 +3,7 @@ package chiselTests import chisel3._ +import chisel3.stage.ChiselStage import chisel3.util.{Counter, Queue} import chisel3.testers.BasicTester import firrtl.checks.CheckResets.NonLiteralAsyncResetValueException @@ -137,22 +138,22 @@ class AsyncResetDontCareModule extends RawModule { bulkAggPort <> DontCare } -class AsyncResetSpec extends ChiselFlatSpec { +class AsyncResetSpec extends ChiselFlatSpec with Utils { behavior of "AsyncReset" it should "be able to be connected to DontCare" in { - elaborate(new AsyncResetDontCareModule) + ChiselStage.elaborate(new AsyncResetDontCareModule) } it should "be allowed with literal reset values" in { - elaborate(new BasicTester { + ChiselStage.elaborate(new BasicTester { withReset(reset.asAsyncReset)(RegInit(123.U)) }) } it should "NOT be allowed with non-literal reset values" in { - a [NonLiteralAsyncResetValueException] shouldBe thrownBy { + a [NonLiteralAsyncResetValueException] should be thrownBy extractCause[NonLiteralAsyncResetValueException] { compile(new BasicTester { val x = WireInit(123.U + 456.U) withReset(reset.asAsyncReset)(RegInit(x)) @@ -161,8 +162,8 @@ class AsyncResetSpec extends ChiselFlatSpec { } it should "NOT be allowed to connect directly to a Bool" in { - a [ChiselException] shouldBe thrownBy { - elaborate(new BasicTester { + a [ChiselException] should be thrownBy extractCause[ChiselException] { + ChiselStage.elaborate(new BasicTester { val bool = Wire(Bool()) val areset = reset.asAsyncReset bool := areset @@ -179,7 +180,7 @@ class AsyncResetSpec extends ChiselFlatSpec { } it should "allow casting to and from Bool" in { - elaborate(new BasicTester { + ChiselStage.elaborate(new BasicTester { val r: Reset = reset val a: AsyncReset = WireInit(r.asAsyncReset) val b: Bool = a.asBool diff --git a/src/test/scala/chiselTests/AutoClonetypeSpec.scala b/src/test/scala/chiselTests/AutoClonetypeSpec.scala index 7ab20e5a736..88f6378b3c1 100644 --- a/src/test/scala/chiselTests/AutoClonetypeSpec.scala +++ b/src/test/scala/chiselTests/AutoClonetypeSpec.scala @@ -3,6 +3,7 @@ package chiselTests import chisel3._ +import chisel3.stage.ChiselStage class BundleWithIntArg(val i: Int) extends Bundle { val out = UInt(i.W) @@ -64,9 +65,9 @@ class NestedAnonymousBundle extends Bundle { // Not necessarily good style (and not necessarily recommended), but allowed to preserve compatibility. class BundleWithArgumentField(val x: Data, val y: Data) extends Bundle -class AutoClonetypeSpec extends ChiselFlatSpec { +class AutoClonetypeSpec extends ChiselFlatSpec with Utils { "Bundles with Scala args" should "not need clonetype" in { - elaborate { new Module { + ChiselStage.elaborate { new Module { val io = IO(new Bundle{}) val myWire = Wire(new BundleWithIntArg(8)) @@ -75,7 +76,7 @@ class AutoClonetypeSpec extends ChiselFlatSpec { } "Bundles with Scala implicit args" should "not need clonetype" in { - elaborate { new Module { + ChiselStage.elaborate { new Module { val io = IO(new Bundle{}) implicit val implicitInt: Int = 4 @@ -86,7 +87,7 @@ class AutoClonetypeSpec extends ChiselFlatSpec { } "Bundles with Scala explicit and impicit args" should "not need clonetype" in { - elaborate { new Module { + ChiselStage.elaborate { new Module { val io = IO(new Bundle{}) implicit val implicitInt: Int = 4 @@ -98,7 +99,7 @@ class AutoClonetypeSpec extends ChiselFlatSpec { } "Subtyped Bundles" should "not need clonetype" in { - elaborate { new Module { + ChiselStage.elaborate { new Module { val io = IO(new Bundle{}) val myWire = Wire(new SubBundle(8, 4)) @@ -106,7 +107,7 @@ class AutoClonetypeSpec extends ChiselFlatSpec { assert(myWire.i == 8) assert(myWire.i2 == 4) } } - elaborate { new Module { + ChiselStage.elaborate { new Module { val io = IO(new Bundle{}) val myWire = Wire(new SubBundleVal(8, 4)) @@ -117,8 +118,8 @@ class AutoClonetypeSpec extends ChiselFlatSpec { } "Subtyped Bundles that don't clone well" should "be caught" in { - a [ChiselException] should be thrownBy { - elaborate { new Module { + a [ChiselException] should be thrownBy extractCause[ChiselException] { + ChiselStage.elaborate { new Module { val io = IO(new Bundle{}) val myWire = Wire(new SubBundleInvalid(8, 4)) } } @@ -126,11 +127,11 @@ class AutoClonetypeSpec extends ChiselFlatSpec { } "Inner bundles with Scala args" should "not need clonetype" in { - elaborate { new ModuleWithInner } + ChiselStage.elaborate { new ModuleWithInner } } "Bundles with arguments as fields" should "not need clonetype" in { - elaborate { new Module { + ChiselStage.elaborate { new Module { val io = IO(Output(new BundleWithArgumentField(UInt(8.W), UInt(8.W)))) io.x := 1.U io.y := 1.U @@ -138,21 +139,21 @@ class AutoClonetypeSpec extends ChiselFlatSpec { } "Bundles inside companion objects" should "not need clonetype" in { - elaborate { new Module { + ChiselStage.elaborate { new Module { val io = IO(Output(new CompanionObjectWithBundle.Inner)) io.data := 1.U } } } "Parameterized bundles inside companion objects" should "not need clonetype" in { - elaborate { new Module { + ChiselStage.elaborate { new Module { val io = IO(Output(new CompanionObjectWithBundle.ParameterizedInner(8))) io.data := 1.U } } } "Nested directioned anonymous Bundles" should "not need clonetype" in { - elaborate { new Module { + ChiselStage.elaborate { new Module { val io = IO(new NestedAnonymousBundle) val a = WireDefault(io) io.a.a := 1.U @@ -160,7 +161,7 @@ class AutoClonetypeSpec extends ChiselFlatSpec { } "3.0 null compatibility" should "not need clonetype" in { - elaborate { new Module { + ChiselStage.elaborate { new Module { class InnerClassThing { def createBundle: Bundle = new Bundle { val a = Output(UInt(8.W)) @@ -172,8 +173,8 @@ class AutoClonetypeSpec extends ChiselFlatSpec { } "Aliased fields" should "be caught" in { - a [ChiselException] should be thrownBy { - elaborate { new Module { + a [ChiselException] should be thrownBy extractCause[ChiselException] { + ChiselStage.elaborate { new Module { val bundleFieldType = UInt(8.W) val io = IO(Output(new Bundle { val a = bundleFieldType @@ -184,12 +185,12 @@ class AutoClonetypeSpec extends ChiselFlatSpec { } "Aliased fields from inadequate autoclonetype" should "be caught" in { - a [ChiselException] should be thrownBy { + a [ChiselException] should be thrownBy extractCause[ChiselException] { class BadBundle(val typeTuple: (Data, Int)) extends Bundle { val a = typeTuple._1 } - elaborate { new Module { + ChiselStage.elaborate { new Module { val io = IO(Output(new BadBundle(UInt(8.W), 1))) io.a := 0.U } } diff --git a/src/test/scala/chiselTests/AutoNestedCloneSpec.scala b/src/test/scala/chiselTests/AutoNestedCloneSpec.scala index 743440bf56b..7dd0b070fb8 100644 --- a/src/test/scala/chiselTests/AutoNestedCloneSpec.scala +++ b/src/test/scala/chiselTests/AutoNestedCloneSpec.scala @@ -4,6 +4,7 @@ package chiselTests import Chisel.ChiselException import org.scalatest._ import chisel3._ +import chisel3.stage.ChiselStage import org.scalatest.matchers.should.Matchers class BundleWithAnonymousInner(val w: Int) extends Bundle { @@ -12,11 +13,11 @@ class BundleWithAnonymousInner(val w: Int) extends Bundle { } } -class AutoNestedCloneSpec extends ChiselFlatSpec with Matchers { +class AutoNestedCloneSpec extends ChiselFlatSpec with Matchers with Utils { behavior of "autoCloneType of inner Bundle in Chisel3" it should "clone a doubly-nested inner bundle successfully" in { - elaborate { + ChiselStage.elaborate { class Outer(val w: Int) extends Module { class Middle(val w: Int) { class InnerIOType extends Bundle { @@ -32,7 +33,7 @@ class AutoNestedCloneSpec extends ChiselFlatSpec with Matchers { } it should "clone an anonymous inner bundle successfully" in { - elaborate { + ChiselStage.elaborate { class TestTop(val w: Int) extends Module { val io = IO(new Bundle {}) val myWire = Wire(new Bundle{ val a = UInt(w.W) }) @@ -42,7 +43,7 @@ class AutoNestedCloneSpec extends ChiselFlatSpec with Matchers { } it should "pick the correct $outer instance for an anonymous inner bundle" in { - elaborate { + ChiselStage.elaborate { class Inner(val w: Int) extends Module { val io = IO(new Bundle{ val in = Input(UInt(w.W)) @@ -64,7 +65,7 @@ class AutoNestedCloneSpec extends ChiselFlatSpec with Matchers { } it should "clone an anonymous, bound, inner bundle of another bundle successfully" in { - elaborate { + ChiselStage.elaborate { class TestModule(w: Int) extends Module { val io = IO(new BundleWithAnonymousInner(w) ) val w0 = WireDefault(io) @@ -75,7 +76,7 @@ class AutoNestedCloneSpec extends ChiselFlatSpec with Matchers { } it should "clone an anonymous, inner bundle of a Module, bound to another bundle successfully" in { - elaborate { + ChiselStage.elaborate { class TestModule(w: Int) extends Module { val bun = new Bundle { val foo = UInt(w.W) @@ -91,7 +92,7 @@ class AutoNestedCloneSpec extends ChiselFlatSpec with Matchers { } it should "clone a double-nested anonymous Bundle" in { - elaborate { + ChiselStage.elaborate { class TestModule() extends Module { val io = IO(new Bundle { val inner = Input(new Bundle { @@ -105,7 +106,7 @@ class AutoNestedCloneSpec extends ChiselFlatSpec with Matchers { // Test ignored because the compatibility null-inserting autoclonetype doesn't trip this ignore should "fail on anonymous doubly-nested inner bundle with clear error" in { - intercept[ChiselException] { elaborate { + intercept[ChiselException] { extractCause[ChiselException] { ChiselStage.elaborate { class Outer(val w: Int) extends Module { class Middle(val w: Int) { def getIO: Bundle = new Bundle { @@ -116,6 +117,6 @@ class AutoNestedCloneSpec extends ChiselFlatSpec with Matchers { val myWire = Wire((new Middle(w)).getIO) } new Outer(2) - }}.getMessage should include("Unable to determine instance") + }}}.getMessage should include("Unable to determine instance") } } diff --git a/src/test/scala/chiselTests/BetterNamingTests.scala b/src/test/scala/chiselTests/BetterNamingTests.scala index 0ac28899190..032b634e590 100644 --- a/src/test/scala/chiselTests/BetterNamingTests.scala +++ b/src/test/scala/chiselTests/BetterNamingTests.scala @@ -3,6 +3,7 @@ package chiselTests import chisel3._ +import chisel3.stage.ChiselStage import chisel3.util._ import scala.collection.mutable @@ -63,19 +64,19 @@ class BetterNamingTests extends ChiselFlatSpec { it should "provide unique counters for each name" in { var module: PerNameIndexing = null - elaborate { module = new PerNameIndexing(4); module } + ChiselStage.elaborate { module = new PerNameIndexing(4); module } assert(module.getNameFailures() == Nil) } it should "provide names for things defined in Iterable[HasId] and Option[HasId]" in { var module: IterableNaming = null - elaborate { module = new IterableNaming; module } + ChiselStage.elaborate { module = new IterableNaming; module } assert(module.getNameFailures() == Nil) } it should "allow digits to be field names in Records" in { var module: DigitFieldNamesInRecord = null - elaborate { module = new DigitFieldNamesInRecord; module } + ChiselStage.elaborate { module = new DigitFieldNamesInRecord; module } assert(module.getNameFailures() == Nil) } @@ -87,8 +88,9 @@ class BetterNamingTests extends ChiselFlatSpec { } WireDefault(3.U) } - val withLits = chisel3.Driver.emit(() => new MyModule(true)) - val noLits = chisel3.Driver.emit(() => new MyModule(false)) + val stage = new ChiselStage + val withLits = stage.emitChirrtl(new MyModule(true)) + val noLits = stage.emitChirrtl(new MyModule(false)) withLits should equal (noLits) } } diff --git a/src/test/scala/chiselTests/BlackBox.scala b/src/test/scala/chiselTests/BlackBox.scala index 70ddd4dad9e..d33355fdea1 100644 --- a/src/test/scala/chiselTests/BlackBox.scala +++ b/src/test/scala/chiselTests/BlackBox.scala @@ -4,6 +4,7 @@ package chiselTests import chisel3._ import chisel3.experimental._ +import chisel3.stage.ChiselStage import chisel3.testers.BasicTester import chisel3.util._ @@ -169,7 +170,7 @@ class BlackBoxSpec extends ChiselFlatSpec { Seq("/chisel3/BlackBoxTest.v")) } "DataMirror.modulePorts" should "work with BlackBox" in { - elaborate(new Module { + ChiselStage.elaborate(new Module { val io = IO(new Bundle { }) val m = Module(new BlackBoxPassthrough) assert(DataMirror.modulePorts(m) == Seq( diff --git a/src/test/scala/chiselTests/BlackBoxImpl.scala b/src/test/scala/chiselTests/BlackBoxImpl.scala index 9871f2518b4..da89a326914 100644 --- a/src/test/scala/chiselTests/BlackBoxImpl.scala +++ b/src/test/scala/chiselTests/BlackBoxImpl.scala @@ -6,6 +6,7 @@ import java.io.File import chisel3._ import chisel3.util.{HasBlackBoxInline, HasBlackBoxResource, HasBlackBoxPath} +import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} import firrtl.FirrtlExecutionSuccess import org.scalacheck.Test.Failed import org.scalatest.Succeeded @@ -91,39 +92,29 @@ class UsesBlackBoxMinusViaPath extends Module { class BlackBoxImplSpec extends AnyFreeSpec with Matchers { val targetDir = "test_run_dir" + val stage = new ChiselStage "BlackBox can have verilator source implementation" - { "Implementations can be contained in-line" in { - Driver.execute(Array("-X", "verilog", "--target-dir", targetDir), () => new UsesBlackBoxAddViaInline) match { - case ChiselExecutionSuccess(_, _, Some(_: FirrtlExecutionSuccess)) => - val verilogOutput = new File(targetDir, "BlackBoxAdd.v") - verilogOutput.exists() should be (true) - verilogOutput.delete() - Succeeded - case _ => - Failed - } + stage.execute(Array("-X", "verilog", "--target-dir", targetDir), + Seq(ChiselGeneratorAnnotation(() => new UsesBlackBoxAddViaInline))) + val verilogOutput = new File(targetDir, "BlackBoxAdd.v") + verilogOutput.exists() should be (true) + verilogOutput.delete() } "Implementations can be contained in resource files" in { - Driver.execute(Array("-X", "low", "--target-dir", targetDir), () => new UsesBlackBoxMinusViaResource) match { - case ChiselExecutionSuccess(_, _, Some(_: FirrtlExecutionSuccess)) => - val verilogOutput = new File(targetDir, "BlackBoxTest.v") - verilogOutput.exists() should be (true) - verilogOutput.delete() - Succeeded - case _ => - Failed - } + stage.execute(Array("-X", "low", "--target-dir", targetDir), + Seq(ChiselGeneratorAnnotation(() => new UsesBlackBoxMinusViaResource))) + val verilogOutput = new File(targetDir, "BlackBoxTest.v") + verilogOutput.exists() should be (true) + verilogOutput.delete() } "Implementations can be contained in arbitrary files" in { - Driver.execute(Array("-X", "low", "--target-dir", targetDir), () => new UsesBlackBoxMinusViaPath) match { - case ChiselExecutionSuccess(_, _, Some(_: FirrtlExecutionSuccess)) => - val verilogOutput = new File(targetDir, "BlackBoxTest.v") - verilogOutput.exists() should be (true) - verilogOutput.delete() - Succeeded - case _ => - Failed - } + stage.execute(Array("-X", "low", "--target-dir", targetDir), + Seq(ChiselGeneratorAnnotation(() => new UsesBlackBoxMinusViaPath))) + val verilogOutput = new File(targetDir, "BlackBoxTest.v") + verilogOutput.exists() should be (true) + verilogOutput.delete() + Succeeded } } } diff --git a/src/test/scala/chiselTests/BoringUtilsSpec.scala b/src/test/scala/chiselTests/BoringUtilsSpec.scala index 755ba60ba6d..997466c0172 100644 --- a/src/test/scala/chiselTests/BoringUtilsSpec.scala +++ b/src/test/scala/chiselTests/BoringUtilsSpec.scala @@ -8,10 +8,12 @@ import chisel3.testers.BasicTester import chisel3.experimental.{BaseModule, ChiselAnnotation, RunFirrtlTransform} import chisel3.util.experimental.BoringUtils -import firrtl.{CircuitForm, CircuitState, ChirrtlForm, Transform} +import firrtl.{CircuitForm, CircuitState, ChirrtlForm, DependencyAPIMigration, Transform} import firrtl.annotations.{Annotation, NoTargetAnnotation} +import firrtl.options.Dependency import firrtl.transforms.{DontTouchAnnotation, NoDedupAnnotation} -import firrtl.passes.wiring.WiringException +import firrtl.passes.wiring.{WiringException, WiringTransform} +import firrtl.stage.Forms abstract class ShouldntAssertTester(cyclesToWait: BigInt = 4) extends BasicTester { val dut: BaseModule @@ -19,11 +21,14 @@ abstract class ShouldntAssertTester(cyclesToWait: BigInt = 4) extends BasicTeste when (done) { stop() } } -class StripNoDedupAnnotation extends Transform { - def inputForm: CircuitForm = ChirrtlForm - def outputForm: CircuitForm = ChirrtlForm - def execute(state: CircuitState): CircuitState = +class StripNoDedupAnnotation extends Transform with DependencyAPIMigration { + override def prerequisites = Forms.ChirrtlForm + override def optionalPrerequisites = Seq.empty + override def optionalPrerequisiteOf = Dependency[WiringTransform] +: Forms.ChirrtlEmitters + override def invalidates(a: Transform) = false + def execute(state: CircuitState): CircuitState = { state.copy(annotations = state.annotations.filter{ case _: NoDedupAnnotation => false; case _ => true }) + } } class BoringUtilsSpec extends ChiselFlatSpec with ChiselRunners { diff --git a/src/test/scala/chiselTests/BundleLiteralSpec.scala b/src/test/scala/chiselTests/BundleLiteralSpec.scala index eea22e11595..baf1022ec9f 100644 --- a/src/test/scala/chiselTests/BundleLiteralSpec.scala +++ b/src/test/scala/chiselTests/BundleLiteralSpec.scala @@ -3,12 +3,13 @@ package chiselTests import chisel3._ +import chisel3.stage.ChiselStage import chisel3.testers.BasicTester import chisel3.experimental.BundleLiterals._ import chisel3.experimental.BundleLiteralException import chisel3.experimental.ChiselEnum -class BundleLiteralSpec extends ChiselFlatSpec { +class BundleLiteralSpec extends ChiselFlatSpec with Utils { object MyEnum extends ChiselEnum { val sA, sB = Value } @@ -134,49 +135,84 @@ class BundleLiteralSpec extends ChiselFlatSpec { } "bundle literals with bad field specifiers" should "fail" in { - val exc = intercept[BundleLiteralException] { elaborate { new RawModule { - val bundle = new MyBundle - bundle.Lit(x => bundle.a -> 0.U) // DONT DO THIS, this gets past a syntax error to exercise the failure - }}} + val exc = intercept[BundleLiteralException] { + extractCause[BundleLiteralException] { + ChiselStage.elaborate { + new RawModule { + val bundle = new MyBundle + bundle.Lit(x => bundle.a -> 0.U) // DONT DO THIS, this gets past a syntax error to exercise the failure + } + } + } + } exc.getMessage should include ("not a field") } "bundle literals with duplicate fields" should "fail" in { - val exc = intercept[BundleLiteralException] { elaborate { new RawModule { - (new MyBundle).Lit(_.a -> 0.U, _.a -> 0.U) - }}} + val exc = intercept[BundleLiteralException] { + extractCause[BundleLiteralException] { + ChiselStage.elaborate { + new RawModule { + (new MyBundle).Lit(_.a -> 0.U, _.a -> 0.U) + } + } + } + } exc.getMessage should include ("duplicate") exc.getMessage should include (".a") } "bundle literals with non-literal values" should "fail" in { - val exc = intercept[BundleLiteralException] { elaborate { new RawModule { - (new MyBundle).Lit(_.a -> UInt()) - }}} + val exc = intercept[BundleLiteralException] { + extractCause[BundleLiteralException] { + ChiselStage.elaborate { new RawModule { + (new MyBundle).Lit(_.a -> UInt()) + } + } + } + } exc.getMessage should include ("non-literal value") exc.getMessage should include (".a") } "bundle literals with non-type-equivalent element fields" should "fail" in { - val exc = intercept[BundleLiteralException] { elaborate { new RawModule { - (new MyBundle).Lit(_.a -> true.B) - }}} + val exc = intercept[BundleLiteralException] { + extractCause[BundleLiteralException] { + ChiselStage.elaborate { + new RawModule { + (new MyBundle).Lit(_.a -> true.B) + } + } + } + } exc.getMessage should include ("non-type-equivalent value") exc.getMessage should include (".a") } "bundle literals with non-type-equivalent sub-bundles" should "fail" in { - val exc = intercept[BundleLiteralException] { elaborate { new RawModule { - (new MyOuterBundle).Lit(_.b -> (new MyBundle).Lit(_.a -> 0.U)) - }}} + val exc = intercept[BundleLiteralException] { + extractCause[BundleLiteralException] { + ChiselStage.elaborate { + new RawModule { + (new MyOuterBundle).Lit(_.b -> (new MyBundle).Lit(_.a -> 0.U)) + } + } + } + } exc.getMessage should include ("non-type-equivalent value") exc.getMessage should include (".b") } "bundle literals with non-type-equivalent enum element fields" should "fail" in { - val exc = intercept[BundleLiteralException] { elaborate { new RawModule { - (new MyBundle).Lit(_.c -> MyEnumB.sB) - }}} + val exc = intercept[BundleLiteralException] { + extractCause[BundleLiteralException] { + ChiselStage.elaborate { + new RawModule { + (new MyBundle).Lit(_.c -> MyEnumB.sB) + } + } + } + } exc.getMessage should include ("non-type-equivalent enum value") exc.getMessage should include (".c") } diff --git a/src/test/scala/chiselTests/BundleSpec.scala b/src/test/scala/chiselTests/BundleSpec.scala index c5f40c8a1b2..d19e5d5f128 100644 --- a/src/test/scala/chiselTests/BundleSpec.scala +++ b/src/test/scala/chiselTests/BundleSpec.scala @@ -3,6 +3,7 @@ package chiselTests import chisel3._ +import chisel3.stage.ChiselStage import chisel3.testers.BasicTester trait BundleSpecUtils { @@ -55,9 +56,9 @@ trait BundleSpecUtils { } } -class BundleSpec extends ChiselFlatSpec with BundleSpecUtils { +class BundleSpec extends ChiselFlatSpec with BundleSpecUtils with Utils { "Bundles with the same fields but in different orders" should "bulk connect" in { - elaborate { new MyModule(new BundleFooBar, new BundleBarFoo) } + ChiselStage.elaborate { new MyModule(new BundleFooBar, new BundleBarFoo) } } "Bundles" should "follow UInt serialization/deserialization API" in { @@ -65,18 +66,18 @@ class BundleSpec extends ChiselFlatSpec with BundleSpecUtils { } "Bulk connect on Bundles" should "check that the fields match" in { - (the [ChiselException] thrownBy { - elaborate { new MyModule(new BundleFooBar, new BundleFoo) } + (the [ChiselException] thrownBy extractCause[ChiselException] { + ChiselStage.elaborate { new MyModule(new BundleFooBar, new BundleFoo) } }).getMessage should include ("Right Record missing field") - (the [ChiselException] thrownBy { - elaborate { new MyModule(new BundleFoo, new BundleFooBar) } + (the [ChiselException] thrownBy extractCause[ChiselException] { + ChiselStage.elaborate { new MyModule(new BundleFoo, new BundleFooBar) } }).getMessage should include ("Left Record missing field") } "Bundles" should "not be able to use Seq for constructing hardware" in { - (the[ChiselException] thrownBy { - elaborate { + (the[ChiselException] thrownBy extractCause[ChiselException] { + ChiselStage.elaborate { new Module { val io = IO(new Bundle { val b = new BadSeqBundle @@ -116,8 +117,8 @@ class BundleSpec extends ChiselFlatSpec with BundleSpecUtils { } "Bundles" should "not have aliased fields" in { - (the[ChiselException] thrownBy { - elaborate { new Module { + (the[ChiselException] thrownBy extractCause[ChiselException] { + ChiselStage.elaborate { new Module { val io = IO(Output(new Bundle { val a = UInt(8.W) val b = a diff --git a/src/test/scala/chiselTests/ChiselSpec.scala b/src/test/scala/chiselTests/ChiselSpec.scala index 31d6d322ea6..19860198649 100644 --- a/src/test/scala/chiselTests/ChiselSpec.scala +++ b/src/test/scala/chiselTests/ChiselSpec.scala @@ -6,12 +6,15 @@ import org.scalatest._ import org.scalatest.prop._ import org.scalacheck._ import chisel3._ +import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} import chisel3.testers._ -import firrtl.{AnnotationSeq, CommonOptions, ExecutionOptionsManager, FirrtlExecutionFailure, FirrtlExecutionSuccess, HasFirrtlOptions} +import firrtl.{AnnotationSeq, CommonOptions, EmittedVerilogCircuitAnnotation, ExecutionOptionsManager, FirrtlExecutionFailure, FirrtlExecutionSuccess, HasFirrtlOptions} +import firrtl.annotations.DeletedAnnotation import firrtl.util.BackendCompilationUtilities import java.io.ByteArrayOutputStream import java.security.Permission import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks +import scala.reflect.ClassTag /** Common utility functions for Chisel unit tests. */ trait ChiselRunners extends Assertions with BackendCompilationUtilities { @@ -33,7 +36,6 @@ trait ChiselRunners extends Assertions with BackendCompilationUtilities { ): Unit = { assert(!runTester(t, additionalVResources, annotations)) } - def elaborate(t: => RawModule): Unit = Driver.elaborate(() => t) def assertKnownWidth(expected: Int)(gen: => Data): Unit = { assertTesterPasses(new BasicTester { @@ -62,34 +64,18 @@ trait ChiselRunners extends Assertions with BackendCompilationUtilities { }) } - /** Given a generator, return the Firrtl that it generates. - * - * @param t Module generator - * @return Firrtl representation as a String - */ - def generateFirrtl(t: => RawModule): String = Driver.emit(() => t) - /** Compiles a Chisel Module to Verilog * NOTE: This uses the "test_run_dir" as the default directory for generated code. * @param t the generator for the module * @return the Verilog code as a string. */ def compile(t: => RawModule): String = { - val testDir = createTestDirectory(this.getClass.getSimpleName) - val manager = new ExecutionOptionsManager("compile") with HasFirrtlOptions - with HasChiselExecutionOptions { - commonOptions = CommonOptions(targetDirName = testDir.toString) - } - - Driver.execute(manager, () => t) match { - case ChiselExecutionSuccess(_, _, Some(firrtlExecRes)) => - firrtlExecRes match { - case FirrtlExecutionSuccess(_, verilog) => verilog - case FirrtlExecutionFailure(msg) => fail(msg) - } - case ChiselExecutionSuccess(_, _, None) => fail() // This shouldn't happen - case ChiselExecutionFailure(msg) => fail(msg) - } + (new ChiselStage) + .execute(Array("--target-dir", createTestDirectory(this.getClass.getSimpleName).toString), + Seq(ChiselGeneratorAnnotation(() => t))) + .collectFirst { + case DeletedAnnotation(_, EmittedVerilogCircuitAnnotation(a)) => a.value + }.getOrElse(fail("No Verilog circuit was emitted by the FIRRTL compiler!")) } } @@ -283,4 +269,41 @@ trait Utils { } } + /** Run some code and rethrow an exception with a specific type if an exception of that type occurs anywhere in the + * stack trace. + * + * This is useful for "extracting" one exception that may be wrapped by other exceptions. + * + * Example usage: + * {{{ + * a [ChiselException] should be thrownBy extractCause[ChiselException] { /* ... */ } + * }}} + * + * @param thunk some code to run + * @tparam A the type of the exception to extract + * @return nothing + */ + def extractCause[A <: Throwable : ClassTag](thunk: => Any): Unit = { + def unrollCauses(a: Throwable): Seq[Throwable] = a match { + case null => Seq.empty + case _ => a +: unrollCauses(a.getCause) + } + + val exceptions: Seq[_ <: Throwable] = try { + thunk + Seq.empty + } catch { + case a: Throwable => unrollCauses(a) + } + + exceptions.collectFirst{ case a: A => a } match { + case Some(a) => throw a + case None => exceptions match { + case Nil => Unit + case h :: t => throw h + } + } + + } + } diff --git a/src/test/scala/chiselTests/Clock.scala b/src/test/scala/chiselTests/Clock.scala index 5dea66dc34f..4b10d3b4483 100644 --- a/src/test/scala/chiselTests/Clock.scala +++ b/src/test/scala/chiselTests/Clock.scala @@ -3,6 +3,7 @@ package chiselTests import chisel3._ +import chisel3.stage.ChiselStage import chisel3.testers.BasicTester class ClockAsUIntTester extends BasicTester { @@ -30,7 +31,7 @@ class ClockSpec extends ChiselPropSpec { } property("Should be able to use withClock in a module with no reset") { - val circuit = Driver.emit { () => new WithClockAndNoReset } + val circuit = (new ChiselStage).emitChirrtl(new WithClockAndNoReset) circuit.contains("reg a : UInt<1>, clock2") should be (true) } } diff --git a/src/test/scala/chiselTests/CloneModuleSpec.scala b/src/test/scala/chiselTests/CloneModuleSpec.scala index b3bc2b16fa0..7752a6b215c 100644 --- a/src/test/scala/chiselTests/CloneModuleSpec.scala +++ b/src/test/scala/chiselTests/CloneModuleSpec.scala @@ -3,6 +3,7 @@ package chiselTests import chisel3._ +import chisel3.stage.ChiselStage import chisel3.util.{Queue, EnqIO, DeqIO, QueueIO, log2Ceil} import chisel3.experimental.{CloneModuleAsRecord, IO} import chisel3.testers.BasicTester @@ -71,7 +72,7 @@ class CloneModuleSpec extends ChiselPropSpec { } property("QueueClone's cloned queues should share the same module") { - val c = Driver.toFirrtl(Driver.elaborate(() => new QueueClone)) + val c = ChiselStage.convert(new QueueClone) assert(c.modules.length == 2) } @@ -82,7 +83,7 @@ class CloneModuleSpec extends ChiselPropSpec { } property("Clones of MultiIOModules should share the same module") { - val c = Driver.toFirrtl(Driver.elaborate(() => new QueueClone(multiIO=true))) + val c = ChiselStage.convert(new QueueClone(multiIO=true)) assert(c.modules.length == 3) } diff --git a/src/test/scala/chiselTests/CompatibilitySpec.scala b/src/test/scala/chiselTests/CompatibilitySpec.scala index 9d509cf368b..09ec40eeea8 100644 --- a/src/test/scala/chiselTests/CompatibilitySpec.scala +++ b/src/test/scala/chiselTests/CompatibilitySpec.scala @@ -2,6 +2,7 @@ package chiselTests +import chisel3.stage.ChiselStage import chisel3.testers.BasicTester import org.scalacheck.Gen @@ -17,13 +18,13 @@ object CompatibilityCustomCompileOptions { } } -class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyChecks { +class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyChecks with Utils { import Chisel._ behavior of "Chisel compatibility layer" it should "accept direction arguments" in { - elaborate(new Module { + ChiselStage.elaborate(new Module { // Choose a random direction val directionArgument: Direction = Gen.oneOf(INPUT, OUTPUT, NODIR).sample.get val expectedDirection = directionArgument match { @@ -126,7 +127,7 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck Valid(data) shouldBe a [ValidIO[UInt]] Pipe(Wire(Valid(data)), 2) shouldBe a [ValidIO[UInt]] } - elaborate { new Dummy } + ChiselStage.elaborate { new Dummy } } // Verify we can elaborate a design expressed in Chisel2 class Chisel2CompatibleRisc extends Module { @@ -178,11 +179,11 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck } it should "Chisel2CompatibleRisc should elaborate" in { - elaborate { new Chisel2CompatibleRisc } + ChiselStage.elaborate { new Chisel2CompatibleRisc } } it should "not try to assign directions to Analog" in { - elaborate(new Module { + ChiselStage.elaborate(new Module { val io = new Bundle { val port = chisel3.experimental.Analog(32.W) } @@ -210,7 +211,7 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck } io.out := io.in } - elaborate { new ConnectFieldMismatchModule() } + ChiselStage.elaborate { new ConnectFieldMismatchModule() } } "A Module in which a Reg is created with a bound type when compiled with the Chisel compatibility package" should "not throw an exception" in { @@ -222,7 +223,7 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck } val badReg = Reg(UInt(7, width=4)) } - elaborate { new CreateRegFromBoundTypeModule() } + ChiselStage.elaborate { new CreateRegFromBoundTypeModule() } } "A Module with unwrapped IO when compiled with the Chisel compatibility package" should "not throw an exception" in { @@ -234,7 +235,7 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck } io.out := io.in(1) } - elaborate { new RequireIOWrapModule() } + ChiselStage.elaborate { new RequireIOWrapModule() } } "A Module connecting output as source to input as sink when compiled with the Chisel compatibility package" should "not throw an exception" in { @@ -249,7 +250,7 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck val child = Module(new SimpleModule) io.in := child.io.out } - elaborate { new SwappedConnectionModule() } + ChiselStage.elaborate { new SwappedConnectionModule() } } "A Module with directionless connections when compiled with the Chisel compatibility package" should "not throw an exception" in { @@ -268,12 +269,12 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck val child = Module(new SimpleModule) b := child.noDir } - elaborate { new DirectionLessConnectionModule() } + ChiselStage.elaborate { new DirectionLessConnectionModule() } } "Vec ports" should "give default directions to children so they can be used in chisel3.util" in { import Chisel._ - elaborate(new Module { + ChiselStage.elaborate(new Module { val io = new Bundle { val in = Vec(1, UInt(width = 8)).flip val out = UInt(width = 8) @@ -284,7 +285,7 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck "Reset" should "still walk, talk, and quack like a Bool" in { import Chisel._ - elaborate(new Module { + ChiselStage.elaborate(new Module { val io = new Bundle { val in = Bool(INPUT) val out = Bool(OUTPUT) @@ -295,7 +296,7 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck "Data.dir" should "give the correct direction for io" in { import Chisel._ - elaborate(new Module { + ChiselStage.elaborate(new Module { val io = (new Bundle { val foo = Bool(OUTPUT) val bar = Bool().flip @@ -308,8 +309,8 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck // Note: This is a regression (see https://github.com/freechipsproject/chisel3/issues/668) it should "fail for Chisel types" in { import Chisel._ - an [chisel3.ExpectedHardwareException] should be thrownBy { - elaborate(new Module { + an [chisel3.ExpectedHardwareException] should be thrownBy extractCause[chisel3.ExpectedHardwareException] { + ChiselStage.elaborate(new Module { val io = new Bundle { } UInt(INPUT).dir }) @@ -318,7 +319,7 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck "Mux return value" should "be able to be used on the RHS" in { import Chisel._ - elaborate(new Module { + ChiselStage.elaborate(new Module { val gen = new Bundle { val foo = UInt(width = 8) } val io = new Bundle { val a = Vec(2, UInt(width = 8)).asInput @@ -336,7 +337,7 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck "Chisel3 IO constructs" should "be useable in Chisel2" in { import Chisel._ - elaborate(new Module { + ChiselStage.elaborate(new Module { val io = IO(new Bundle { val in = Input(Bool()) val foo = Output(Bool()) @@ -366,7 +367,7 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck // (UInt(4) != bp) shouldBe a [Bool] } - elaborate(new Foo) + ChiselStage.elaborate(new Foo) } behavior of "Enum" @@ -389,7 +390,7 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck }.getMessage should include ("Bit width may no longer be specified for enums") } - elaborate(new Foo) + ChiselStage.elaborate(new Foo) } behavior of "Queue" @@ -405,7 +406,7 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck val explicit = Module(new Queue(UInt(), 4, false, false, Bool(true))) } - elaborate(new Foo) + ChiselStage.elaborate(new Foo) } behavior of "LFSR16" @@ -424,7 +425,7 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck lfsr.getWidth should be (16) } - elaborate(new Foo) + ChiselStage.elaborate(new Foo) } behavior of "Mem" @@ -442,7 +443,7 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck memInt shouldBe a [Mem[SInt]] } - elaborate(new Foo) + ChiselStage.elaborate(new Foo) } behavior of "SeqMem" @@ -460,7 +461,7 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck seqMemInt shouldBe a [SeqMem[UInt]] } - elaborate(new Foo) + ChiselStage.elaborate(new Foo) } behavior of "debug" @@ -473,7 +474,7 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck debug(data) } - elaborate(new Foo) + ChiselStage.elaborate(new Foo) } behavior of "Data methods" @@ -491,7 +492,7 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck Vec.fill(4)(wire).toBits.getWidth should be (wire.getWidth * 4) } - elaborate(new Foo) + ChiselStage.elaborate(new Foo) } behavior of "Wire" @@ -513,7 +514,7 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck third shouldBe a [UInt] } - elaborate(new Foo) + ChiselStage.elaborate(new Foo) } behavior of "Vec" @@ -562,7 +563,7 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck UInt(1).toBool shouldBe a [Bool] } - elaborate(new Foo) + ChiselStage.elaborate(new Foo) } behavior of "UInt" @@ -575,7 +576,7 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck (UInt(1) != UInt(1)) shouldBe a [Bool] } - elaborate(new Foo) + ChiselStage.elaborate(new Foo) } behavior of "SInt" @@ -588,13 +589,13 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck (SInt(-1) != SInt(-1)) shouldBe a [Bool] } - elaborate(new Foo) + ChiselStage.elaborate(new Foo) } it should "properly propagate custom compileOptions in Chisel.Module" in { import CompatibilityCustomCompileOptions._ var result: Foo = null - elaborate({result = new Foo; result}) + ChiselStage.elaborate({result = new Foo; result}) result.compileOptions should be theSameInstanceAs (customCompileOptions) } diff --git a/src/test/scala/chiselTests/CompileOptionsTest.scala b/src/test/scala/chiselTests/CompileOptionsTest.scala index 10be4ffb801..1bd0327aa74 100644 --- a/src/test/scala/chiselTests/CompileOptionsTest.scala +++ b/src/test/scala/chiselTests/CompileOptionsTest.scala @@ -4,8 +4,9 @@ package chiselTests import chisel3._ import chisel3.CompileOptions._ +import chisel3.stage.ChiselStage -class CompileOptionsSpec extends ChiselFlatSpec { +class CompileOptionsSpec extends ChiselFlatSpec with Utils { abstract class StrictModule extends Module()(chisel3.ExplicitCompileOptions.Strict) abstract class NotStrictModule extends Module()(chisel3.ExplicitCompileOptions.NotStrict) @@ -22,7 +23,7 @@ class CompileOptionsSpec extends ChiselFlatSpec { // scalastyle:off line.size.limit "A Module with missing bundle fields when compiled with implicit Strict.CompileOption " should "throw an exception" in { - a [ChiselException] should be thrownBy { + a [ChiselException] should be thrownBy extractCause[ChiselException] { import chisel3.ExplicitCompileOptions.Strict class ConnectFieldMismatchModule extends Module { @@ -32,7 +33,7 @@ class CompileOptionsSpec extends ChiselFlatSpec { }) io.out := io.in } - elaborate { new ConnectFieldMismatchModule() } + ChiselStage.elaborate { new ConnectFieldMismatchModule() } } } @@ -46,11 +47,11 @@ class CompileOptionsSpec extends ChiselFlatSpec { }) io.out := io.in } - elaborate { new ConnectFieldMismatchModule() } + ChiselStage.elaborate { new ConnectFieldMismatchModule() } } "A Module in which a Reg is created with a bound type when compiled with implicit Strict.CompileOption " should "throw an exception" in { - a [BindingException] should be thrownBy { + a [BindingException] should be thrownBy extractCause[BindingException] { import chisel3.ExplicitCompileOptions.Strict class CreateRegFromBoundTypeModule extends Module { @@ -60,7 +61,7 @@ class CompileOptionsSpec extends ChiselFlatSpec { }) val badReg = Reg(7.U(4.W)) } - elaborate { new CreateRegFromBoundTypeModule() } + ChiselStage.elaborate { new CreateRegFromBoundTypeModule() } } } @@ -74,7 +75,7 @@ class CompileOptionsSpec extends ChiselFlatSpec { }) val badReg = Reg(7.U(4.W)) } - elaborate { new CreateRegFromBoundTypeModule() } + ChiselStage.elaborate { new CreateRegFromBoundTypeModule() } } "A Module with wrapped IO when compiled with implicit Strict.CompileOption " should "not throw an exception" in { @@ -87,11 +88,11 @@ class CompileOptionsSpec extends ChiselFlatSpec { }) io.out := io.in(1) } - elaborate { new RequireIOWrapModule() } + ChiselStage.elaborate { new RequireIOWrapModule() } } "A Module with unwrapped IO when compiled with implicit Strict.CompileOption " should "throw an exception" in { - a [BindingException] should be thrownBy { + a [BindingException] should be thrownBy extractCause[BindingException] { import chisel3.ExplicitCompileOptions.Strict class RequireIOWrapModule extends Module { @@ -101,14 +102,14 @@ class CompileOptionsSpec extends ChiselFlatSpec { } io.out := io.in(1) } - elaborate { + ChiselStage.elaborate { new RequireIOWrapModule() } } } "A Module connecting output as source to input as sink when compiled with implicit Strict.CompileOption " should "throw an exception" in { - a [ChiselException] should be thrownBy { + a [ChiselException] should be thrownBy extractCause[ChiselException] { import chisel3.ExplicitCompileOptions.Strict class SimpleModule extends Module { @@ -121,7 +122,7 @@ class CompileOptionsSpec extends ChiselFlatSpec { val child = Module(new SimpleModule) io.in := child.io.out } - elaborate { new SwappedConnectionModule() } + ChiselStage.elaborate { new SwappedConnectionModule() } } } @@ -138,11 +139,11 @@ class CompileOptionsSpec extends ChiselFlatSpec { val child = Module(new SimpleModule) io.in := child.io.out } - elaborate { new SwappedConnectionModule() } + ChiselStage.elaborate { new SwappedConnectionModule() } } "A Module with directionless connections when compiled with implicit Strict.CompileOption " should "throw an exception" in { - a [ChiselException] should be thrownBy { + a [ChiselException] should be thrownBy extractCause[ChiselException] { // Verify we can suppress the inclusion of default compileOptions import Chisel.{defaultCompileOptions => _} import chisel3.ExplicitCompileOptions.Strict @@ -161,7 +162,7 @@ class CompileOptionsSpec extends ChiselFlatSpec { val child = Module(new SimpleModule) b := child.noDir } - elaborate { new DirectionLessConnectionModule() } + ChiselStage.elaborate { new DirectionLessConnectionModule() } } } @@ -182,7 +183,7 @@ class CompileOptionsSpec extends ChiselFlatSpec { val child = Module(new SimpleModule) b := child.noDir } - elaborate { new DirectionLessConnectionModule() } + ChiselStage.elaborate { new DirectionLessConnectionModule() } } // scalastyle:on line.size.limit } diff --git a/src/test/scala/chiselTests/ConnectSpec.scala b/src/test/scala/chiselTests/ConnectSpec.scala index 51814998707..b9c9e173627 100644 --- a/src/test/scala/chiselTests/ConnectSpec.scala +++ b/src/test/scala/chiselTests/ConnectSpec.scala @@ -4,6 +4,7 @@ package chiselTests import chisel3._ import chisel3.experimental.{Analog, FixedPoint} +import chisel3.stage.ChiselStage import chisel3.testers.BasicTester abstract class CrossCheck extends Bundle { @@ -36,65 +37,93 @@ class CrossConnectTester(inType: Data, outType: Data) extends BasicTester { stop() } -class ConnectSpec extends ChiselPropSpec { +class ConnectSpec extends ChiselPropSpec with Utils { property("SInt := SInt should succeed") { assertTesterPasses{ new CrossConnectTester(SInt(16.W), SInt(16.W)) } } property("SInt := UInt should fail") { - intercept[ChiselException]{ elaborate { new CrossConnectTester(UInt(16.W), SInt(16.W)) } } + intercept[ChiselException]{ + extractCause[ChiselException] { + ChiselStage.elaborate { new CrossConnectTester(UInt(16.W), SInt(16.W)) } } } } property("SInt := FixedPoint should fail") { - intercept[ChiselException]{ elaborate { new CrossConnectTester(FixedPoint(16.W, 8.BP), UInt(16.W)) } } + intercept[ChiselException]{ + extractCause[ChiselException] { + ChiselStage.elaborate { new CrossConnectTester(FixedPoint(16.W, 8.BP), UInt(16.W)) } } } } property("UInt := UInt should succeed") { assertTesterPasses{ new CrossConnectTester(UInt(16.W), UInt(16.W)) } } property("UInt := SInt should fail") { - intercept[ChiselException]{ elaborate { new CrossConnectTester(SInt(16.W), UInt(16.W)) } } + intercept[ChiselException]{ + extractCause[ChiselException] { + ChiselStage.elaborate { new CrossConnectTester(SInt(16.W), UInt(16.W)) } } } } property("UInt := FixedPoint should fail") { - intercept[ChiselException]{ elaborate { new CrossConnectTester(FixedPoint(16.W, 8.BP), UInt(16.W)) } } + intercept[ChiselException]{ + extractCause[ChiselException] { + ChiselStage.elaborate { new CrossConnectTester(FixedPoint(16.W, 8.BP), UInt(16.W)) } } } } property("Clock := Clock should succeed") { assertTesterPasses{ new CrossConnectTester(Clock(), Clock()) } } property("Clock := UInt should fail") { - intercept[ChiselException]{ elaborate { new CrossConnectTester(Clock(), UInt(16.W)) } } + intercept[ChiselException]{ + extractCause[ChiselException] { + ChiselStage.elaborate { new CrossConnectTester(Clock(), UInt(16.W)) } } } } property("FixedPoint := FixedPoint should succeed") { assertTesterPasses{ new CrossConnectTester(FixedPoint(16.W, 8.BP), FixedPoint(16.W, 8.BP)) } } property("FixedPoint := SInt should fail") { - intercept[ChiselException]{ elaborate { new CrossConnectTester(SInt(16.W), FixedPoint(16.W, 8.BP)) } } + intercept[ChiselException]{ + extractCause[ChiselException] { + ChiselStage.elaborate { new CrossConnectTester(SInt(16.W), FixedPoint(16.W, 8.BP)) } } } } property("FixedPoint := UInt should fail") { - intercept[ChiselException]{ elaborate { new CrossConnectTester(UInt(16.W), FixedPoint(16.W, 8.BP)) } } + intercept[ChiselException]{ + extractCause[ChiselException] { + ChiselStage.elaborate { new CrossConnectTester(UInt(16.W), FixedPoint(16.W, 8.BP)) } } } } property("Analog := Analog should fail") { - intercept[ChiselException]{ elaborate { new CrossConnectTester(Analog(16.W), Analog(16.W)) } } + intercept[ChiselException]{ + extractCause[ChiselException] { + ChiselStage.elaborate { new CrossConnectTester(Analog(16.W), Analog(16.W)) } } } } property("Analog := FixedPoint should fail") { - intercept[ChiselException]{ elaborate { new CrossConnectTester(Analog(16.W), FixedPoint(16.W, 8.BP)) } } + intercept[ChiselException]{ + extractCause[ChiselException] { + ChiselStage.elaborate { new CrossConnectTester(Analog(16.W), FixedPoint(16.W, 8.BP)) } } } } property("FixedPoint := Analog should fail") { - intercept[ChiselException]{ elaborate { new CrossConnectTester(FixedPoint(16.W, 8.BP), Analog(16.W)) } } + intercept[ChiselException]{ + extractCause[ChiselException] { + ChiselStage.elaborate { new CrossConnectTester(FixedPoint(16.W, 8.BP), Analog(16.W)) } } } } property("Analog := UInt should fail") { - intercept[ChiselException]{ elaborate { new CrossConnectTester(Analog(16.W), UInt(16.W)) } } + intercept[ChiselException]{ + extractCause[ChiselException] { + ChiselStage.elaborate { new CrossConnectTester(Analog(16.W), UInt(16.W)) } } } } property("Analog := SInt should fail") { - intercept[ChiselException]{ elaborate { new CrossConnectTester(Analog(16.W), SInt(16.W)) } } + intercept[ChiselException]{ + extractCause[ChiselException] { + ChiselStage.elaborate { new CrossConnectTester(Analog(16.W), SInt(16.W)) } } } } property("UInt := Analog should fail") { - intercept[ChiselException]{ elaborate { new CrossConnectTester(UInt(16.W), Analog(16.W)) } } + intercept[ChiselException]{ + extractCause[ChiselException] { + ChiselStage.elaborate { new CrossConnectTester(UInt(16.W), Analog(16.W)) } } } } property("SInt := Analog should fail") { - intercept[ChiselException]{ elaborate { new CrossConnectTester(SInt(16.W), Analog(16.W)) } } + intercept[ChiselException]{ + extractCause[ChiselException] { + ChiselStage.elaborate { new CrossConnectTester(SInt(16.W), Analog(16.W)) } } } } property("Pipe internal connections should succeed") { - elaborate( new PipeInternalWires) + ChiselStage.elaborate( new PipeInternalWires) } } diff --git a/src/test/scala/chiselTests/DataPrint.scala b/src/test/scala/chiselTests/DataPrint.scala index caf6e15960a..5f59e6baea9 100644 --- a/src/test/scala/chiselTests/DataPrint.scala +++ b/src/test/scala/chiselTests/DataPrint.scala @@ -7,6 +7,7 @@ import org.scalatest._ import chisel3._ import chisel3.experimental.{ChiselEnum, FixedPoint} import chisel3.experimental.BundleLiterals._ +import chisel3.stage.ChiselStage import org.scalatest.matchers.should.Matchers class DataPrintSpec extends ChiselFlatSpec with Matchers { @@ -20,7 +21,7 @@ class DataPrintSpec extends ChiselFlatSpec with Matchers { } "Data types" should "have a meaningful string representation" in { - elaborate { new RawModule { + ChiselStage.elaborate { new RawModule { UInt().toString should be ("UInt") UInt(8.W).toString should be ("UInt<8>") SInt(15.W).toString should be ("SInt<15>") @@ -54,11 +55,11 @@ class DataPrintSpec extends ChiselFlatSpec with Matchers { } "Bound data types" should "have a meaningful string representation" in { - elaborate { new BoundDataModule } + ChiselStage.elaborate { new BoundDataModule } } "Literals" should "have a meaningful string representation" in { - elaborate { new RawModule { + ChiselStage.elaborate { new RawModule { 3.U.toString should be ("UInt<2>(3)") 3.U(5.W).toString should be ("UInt<5>(3)") -1.S.toString should be ("SInt<1>(-1)") diff --git a/src/test/scala/chiselTests/DecoupledSpec.scala b/src/test/scala/chiselTests/DecoupledSpec.scala index c251df8215b..78c8458d1a3 100644 --- a/src/test/scala/chiselTests/DecoupledSpec.scala +++ b/src/test/scala/chiselTests/DecoupledSpec.scala @@ -3,11 +3,12 @@ package chiselTests import chisel3._ +import chisel3.stage.ChiselStage import chisel3.util.Decoupled class DecoupledSpec extends ChiselFlatSpec { "Decoupled() and Decoupled.empty" should "give DecoupledIO with empty payloads" in { - elaborate(new Module { + ChiselStage.elaborate(new Module { val io = IO(new Bundle { val in = Flipped(Decoupled()) val out = Decoupled.empty diff --git a/src/test/scala/chiselTests/Direction.scala b/src/test/scala/chiselTests/Direction.scala index f3c50829e90..52d7a20b591 100644 --- a/src/test/scala/chiselTests/Direction.scala +++ b/src/test/scala/chiselTests/Direction.scala @@ -4,6 +4,7 @@ package chiselTests import org.scalatest._ import chisel3._ +import chisel3.stage.ChiselStage import org.scalatest.matchers.should.Matchers class DirectionedBundle extends Bundle { @@ -40,41 +41,41 @@ class TopDirectionOutput extends Module { io.out := 117.U } -class DirectionSpec extends ChiselPropSpec with Matchers { +class DirectionSpec extends ChiselPropSpec with Matchers with Utils { //TODO: In Chisel3 these are actually FIRRTL errors. Remove from tests? property("Outputs should be assignable") { - elaborate(new GoodDirection) + ChiselStage.elaborate(new GoodDirection) } property("Inputs should not be assignable") { - a[Exception] should be thrownBy { - elaborate(new BadDirection) + a[Exception] should be thrownBy extractCause[Exception] { + ChiselStage.elaborate(new BadDirection) } - a[Exception] should be thrownBy { - elaborate(new BadSubDirection) + a[Exception] should be thrownBy extractCause[Exception] { + ChiselStage.elaborate(new BadSubDirection) } } property("Top-level forced outputs should be assignable") { - elaborate(new TopDirectionOutput) + ChiselStage.elaborate(new TopDirectionOutput) } property("Empty Vecs with directioned sample_element should not cause direction errors") { - elaborate(new Module { + ChiselStage.elaborate(new Module { val io = IO(new Bundle { val foo = Input(UInt(8.W)) val x = Vec(0, Output(UInt(8.W))) }) }) - elaborate(new Module { + ChiselStage.elaborate(new Module { val io = IO(new Bundle { val foo = Input(UInt(8.W)) val x = Flipped(Vec(0, Output(UInt(8.W)))) }) }) - elaborate(new Module { + ChiselStage.elaborate(new Module { val io = IO(new Bundle { val foo = Input(UInt(8.W)) val x = Output(Vec(0, UInt(8.W))) @@ -83,8 +84,8 @@ class DirectionSpec extends ChiselPropSpec with Matchers { } property("Empty Vecs with no direction on the sample_element *should* cause direction errors") { - an [Exception] should be thrownBy { - elaborate(new Module { + an [Exception] should be thrownBy extractCause[Exception] { + ChiselStage.elaborate(new Module { val io = IO(new Bundle { val foo = Input(UInt(8.W)) val x = Vec(0, UInt(8.W)) @@ -94,19 +95,19 @@ class DirectionSpec extends ChiselPropSpec with Matchers { } property("Empty Bundles should not cause direction errors") { - elaborate(new Module { + ChiselStage.elaborate(new Module { val io = IO(new Bundle { val foo = Input(UInt(8.W)) val x = new Bundle {} }) }) - elaborate(new Module { + ChiselStage.elaborate(new Module { val io = IO(new Bundle { val foo = Input(UInt(8.W)) val x = Flipped(new Bundle {}) }) }) - elaborate(new Module { + ChiselStage.elaborate(new Module { val io = IO(new Bundle { val foo = Input(UInt(8.W)) val x = new Bundle { @@ -117,8 +118,8 @@ class DirectionSpec extends ChiselPropSpec with Matchers { } property("Explicitly directioned but empty Bundles should cause direction errors") { - an [Exception] should be thrownBy { - elaborate(new Module { + an [Exception] should be thrownBy extractCause[Exception] { + ChiselStage.elaborate(new Module { val io = IO(new Bundle { val foo = UInt(8.W) val x = Input(new Bundle {}) @@ -130,7 +131,7 @@ class DirectionSpec extends ChiselPropSpec with Matchers { import chisel3.experimental.{DataMirror, Direction} property("Directions should be preserved through cloning and binding of Bundles") { - elaborate(new MultiIOModule { + ChiselStage.elaborate(new MultiIOModule { class MyBundle extends Bundle { val foo = Input(UInt(8.W)) val bar = Output(UInt(8.W)) @@ -167,7 +168,7 @@ class DirectionSpec extends ChiselPropSpec with Matchers { } property("Directions should be preserved through cloning and binding of Vecs") { - elaborate(new MultiIOModule { + ChiselStage.elaborate(new MultiIOModule { val a = Vec(1, Input(UInt(8.W))) val b = Vec(1, a) val c = Vec(1, Flipped(a)) @@ -239,10 +240,8 @@ class DirectionSpec extends ChiselPropSpec with Matchers { assert(DataMirror.directionOf(flippedVecFlipped(index).b) == Direction.Output) } - val elaborated = Driver.elaborate(() => new MyModule) - - val emitted: String = Driver.emit(elaborated) - val firrtl: String = Driver.toFirrtl(elaborated).serialize + val emitted: String = (new ChiselStage).emitChirrtl(new MyModule) + val firrtl: String = ChiselStage.convert(new MyModule).serialize // Check that emitted directions are correct. Seq(emitted, firrtl).foreach { o => { @@ -308,10 +307,8 @@ class DirectionSpec extends ChiselPropSpec with Matchers { assert(DataMirror.directionOf(vecOutputFlipped(index).b) == Direction.Output) } - val elaborated = Driver.elaborate(() => new MyModule) - - val emitted: String = Driver.emit(elaborated) - val firrtl: String = Driver.toFirrtl(elaborated).serialize + val emitted: String = (new ChiselStage).emitChirrtl(new MyModule) + val firrtl: String = ChiselStage.convert(new MyModule).serialize // Check that emitted directions are correct. Seq(emitted, firrtl).foreach { o => { diff --git a/src/test/scala/chiselTests/DontTouchSpec.scala b/src/test/scala/chiselTests/DontTouchSpec.scala index ead4ffc9767..e80c6199c2c 100644 --- a/src/test/scala/chiselTests/DontTouchSpec.scala +++ b/src/test/scala/chiselTests/DontTouchSpec.scala @@ -3,6 +3,7 @@ package chiselTests import chisel3._ +import chisel3.stage.ChiselStage class HasDeadCodeChild(withDontTouch: Boolean) extends Module { val io = IO(new Bundle { @@ -31,7 +32,7 @@ class HasDeadCode(withDontTouch: Boolean) extends Module { } } -class DontTouchSpec extends ChiselFlatSpec { +class DontTouchSpec extends ChiselFlatSpec with Utils{ val deadSignals = List( "io_c_0", "io_c_1", @@ -50,12 +51,11 @@ class DontTouchSpec extends ChiselFlatSpec { } } "Dont touch" should "only work on bound hardware" in { - a [chisel3.BindingException] should be thrownBy { - elaborate(new Module { + a [chisel3.BindingException] should be thrownBy extractCause[BindingException] { + ChiselStage.elaborate(new Module { val io = IO(new Bundle { }) dontTouch(new Bundle { val a = UInt(32.W) } ) }) } } } - diff --git a/src/test/scala/chiselTests/EnableShiftRegister.scala b/src/test/scala/chiselTests/EnableShiftRegister.scala index d6bfc94dd0b..5f023df86a1 100644 --- a/src/test/scala/chiselTests/EnableShiftRegister.scala +++ b/src/test/scala/chiselTests/EnableShiftRegister.scala @@ -2,6 +2,7 @@ package chiselTests import chisel3._ +import chisel3.stage.ChiselStage class EnableShiftRegister extends Module { val io = IO(new Bundle { @@ -47,7 +48,7 @@ class EnableShiftRegisterTester(c: EnableShiftRegister) extends Tester(c) { class EnableShiftRegisterSpec extends ChiselPropSpec { property("EnableShiftRegister should elaborate") { - elaborate { new EnableShiftRegister } + ChiselStage.elaborate { new EnableShiftRegister } } ignore("EnableShiftRegisterTester should return the correct result") { } diff --git a/src/test/scala/chiselTests/ExtModule.scala b/src/test/scala/chiselTests/ExtModule.scala index 0349d180e3a..582a05ae287 100644 --- a/src/test/scala/chiselTests/ExtModule.scala +++ b/src/test/scala/chiselTests/ExtModule.scala @@ -4,6 +4,7 @@ package chiselTests import chisel3._ import chisel3.experimental._ +import chisel3.stage.ChiselStage import chisel3.testers.BasicTester // Avoid collisions with regular BlackBox tests by putting ExtModule blackboxes @@ -68,7 +69,7 @@ class ExtModuleSpec extends ChiselFlatSpec { Seq("/chisel3/BlackBoxTest.v")) } "DataMirror.modulePorts" should "work with ExtModule" in { - elaborate(new Module { + ChiselStage.elaborate(new Module { val io = IO(new Bundle { }) val m = Module(new ExtModule.BlackBoxPassthrough) assert(DataMirror.modulePorts(m) == Seq( diff --git a/src/test/scala/chiselTests/FixedPointSpec.scala b/src/test/scala/chiselTests/FixedPointSpec.scala index 7d6ec6a32be..c5aab7e43bf 100644 --- a/src/test/scala/chiselTests/FixedPointSpec.scala +++ b/src/test/scala/chiselTests/FixedPointSpec.scala @@ -5,6 +5,7 @@ package chiselTests import chisel3._ import chisel3.experimental.FixedPoint import chisel3.internal.firrtl.{BinaryPoint, Width} +import chisel3.stage.ChiselStage import chisel3.testers.BasicTester import org.scalatest._ import org.scalatest.flatspec.AnyFlatSpec @@ -148,7 +149,7 @@ class FixedPointLitExtractTester extends BasicTester { stop() } -class FixedPointSpec extends ChiselPropSpec { +class FixedPointSpec extends ChiselPropSpec with Utils { property("should allow set binary point") { assertTesterPasses { new SBPTester } } @@ -159,7 +160,9 @@ class FixedPointSpec extends ChiselPropSpec { assertTesterPasses { new FixedPointMuxTester } } property("Negative shift amounts are invalid") { - a [ChiselException] should be thrownBy { elaborate(new NegativeShift(FixedPoint(1.W, 0.BP))) } + a [ChiselException] should be thrownBy extractCause[ChiselException] { + ChiselStage.elaborate(new NegativeShift(FixedPoint(1.W, 0.BP))) + } } property("Bit extraction on literals should work for all non-negative indices") { assertTesterPasses(new FixedPointLitExtractTester) diff --git a/src/test/scala/chiselTests/GCD.scala b/src/test/scala/chiselTests/GCD.scala index 5c9641bec5c..a80670a94d1 100644 --- a/src/test/scala/chiselTests/GCD.scala +++ b/src/test/scala/chiselTests/GCD.scala @@ -3,6 +3,7 @@ package chiselTests import chisel3._ +import chisel3.stage.ChiselStage import chisel3.testers.BasicTester class GCD extends Module { @@ -47,7 +48,7 @@ class GCDSpec extends ChiselPropSpec { ( 48, 64, 16)) property("GCD should elaborate") { - elaborate { new GCD } + ChiselStage.elaborate { new GCD } } property("GCDTester should return the correct result") { diff --git a/src/test/scala/chiselTests/IOCompatibility.scala b/src/test/scala/chiselTests/IOCompatibility.scala index 488842d4247..fc6cdc2c1b7 100644 --- a/src/test/scala/chiselTests/IOCompatibility.scala +++ b/src/test/scala/chiselTests/IOCompatibility.scala @@ -3,6 +3,7 @@ package chiselTests import chisel3._ +import chisel3.stage.ChiselStage import org.scalatest._ import org.scalatest.matchers.should.Matchers @@ -35,14 +36,14 @@ class IOCModuleWire extends Module { io.out := inc.out } -class IOCompatibilitySpec extends ChiselPropSpec with Matchers { +class IOCompatibilitySpec extends ChiselPropSpec with Matchers with Utils { property("IOCModuleVec should elaborate") { - elaborate { new IOCModuleVec(2) } + ChiselStage.elaborate { new IOCModuleVec(2) } } property("IOCModuleWire should elaborate") { - elaborate { new IOCModuleWire } + ChiselStage.elaborate { new IOCModuleWire } } @@ -52,8 +53,8 @@ class IOCompatibilitySpec extends ChiselPropSpec with Matchers { } property("Unwrapped IO should generate an exception") { - a [BindingException] should be thrownBy { - elaborate(new IOUnwrapped) + a [BindingException] should be thrownBy extractCause[BindingException] { + ChiselStage.elaborate(new IOUnwrapped) } } } diff --git a/src/test/scala/chiselTests/InlineSpec.scala b/src/test/scala/chiselTests/InlineSpec.scala index a7d95fad96d..fae927ec08f 100644 --- a/src/test/scala/chiselTests/InlineSpec.scala +++ b/src/test/scala/chiselTests/InlineSpec.scala @@ -3,9 +3,11 @@ package chiselTests import chisel3._ +import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} import chisel3.util.experimental.{InlineInstance, FlattenInstance} import firrtl.FirrtlExecutionSuccess import firrtl.passes.InlineAnnotation +import firrtl.stage.{FirrtlCircuitAnnotation, FirrtlStage} import firrtl.transforms.FlattenAnnotation import firrtl.analyses.InstanceGraph import firrtl.{ir => fir} @@ -32,6 +34,9 @@ class InlineSpec extends AnyFreeSpec with ChiselRunners with Matchers { .fullHierarchy.values.flatten.toSeq .map( v => (top.getOrElse(v.head.name) +: v.tail.map(_.name)).mkString(".") ) + val chiselStage = new ChiselStage + val firrtlStage = new FirrtlStage + "Module Inlining" - { class Top extends Module with Internals { val x = Module(new Foo) @@ -40,16 +45,22 @@ class InlineSpec extends AnyFreeSpec with ChiselRunners with Matchers { Seq(x, y, z).map(_.io.a := io.a) } "should compile to low FIRRTL" - { - Driver.execute(Array("-X", "low", "--target-dir", "test_run_dir"), () => new Top) match { - case ChiselExecutionSuccess(Some(chiselCircuit), _, Some(firrtlResult: FirrtlExecutionSuccess)) => - "emitting TWO InlineAnnotation at the CHIRRTL level" in { - chiselCircuit.annotations.map(_.toFirrtl).collect{ case a: InlineAnnotation => a }.size should be (2) - } - "low FIRRTL should contain only instance z" in { - val instances = collectInstances(firrtlResult.circuitState.circuit, Some("Top")).toSet - Set("Top", "Top.x_sub", "Top.y_sub", "Top.z", "Top.z.sub") should be (instances) - } - } + val chiselAnnotations = + chiselStage + .execute(Array("--no-run-firrtl", "--target-dir", "test_run_dir"), + Seq(ChiselGeneratorAnnotation(() => new Top))) + + chiselAnnotations.collect{ case a: InlineAnnotation => a } should have length (2) + + val instanceNames = + firrtlStage + .execute(Array("-X", "low"), chiselAnnotations) + .collectFirst { + case FirrtlCircuitAnnotation(circuit) => circuit + }.map(collectInstances(_, Some("Top"))) + .getOrElse(fail) + + instanceNames should contain theSameElementsAs Set("Top", "Top.x_sub", "Top.y_sub", "Top.z", "Top.z.sub") } } @@ -59,16 +70,22 @@ class InlineSpec extends AnyFreeSpec with ChiselRunners with Matchers { x.io.a := io.a } "should compile to low FIRRTL" - { - Driver.execute(Array("-X", "low", "--target-dir", "test_run_dir"), () => new Top) match { - case ChiselExecutionSuccess(Some(chiselCircuit), chirrtl, Some(firrtlResult: FirrtlExecutionSuccess)) => - "emitting ONE FlattenAnnotation at the CHIRRTL level" in { - chiselCircuit.annotations.map(_.toFirrtl).collect{ case a: FlattenAnnotation => a }.size should be (1) - } - "low FIRRTL should contain instance x only" in { - val instances = collectInstances(firrtlResult.circuitState.circuit, Some("Top")).toSet - Set("Top", "Top.x") should be (instances) - } - } + val chiselAnnotations = + chiselStage + .execute(Array("--no-run-firrtl", "--target-dir", "test_run_dir"), + Seq(ChiselGeneratorAnnotation(() => new Top))) + + chiselAnnotations.collect{ case a: FlattenAnnotation => a} should have length(1) + + val instanceNames = + firrtlStage + .execute(Array("-X", "low"), chiselAnnotations) + .collectFirst { + case FirrtlCircuitAnnotation(circuit) => circuit + }.map(collectInstances(_, Some("Top"))) + .getOrElse(fail) + + instanceNames should contain theSameElementsAs Set("Top", "Top.x") } } } diff --git a/src/test/scala/chiselTests/InstanceNameSpec.scala b/src/test/scala/chiselTests/InstanceNameSpec.scala index afd9af934cb..d896785b195 100644 --- a/src/test/scala/chiselTests/InstanceNameSpec.scala +++ b/src/test/scala/chiselTests/InstanceNameSpec.scala @@ -3,6 +3,7 @@ package chiselTests import chisel3._ +import chisel3.stage.ChiselStage import chisel3.util.Queue class InstanceNameModule extends Module { @@ -25,7 +26,7 @@ class InstanceNameSpec extends ChiselFlatSpec { behavior of "instanceName" val moduleName = "InstanceNameModule" var m: InstanceNameModule = _ - elaborate { m = new InstanceNameModule; m } + ChiselStage.elaborate { m = new InstanceNameModule; m } it should "work with module IO" in { val io = m.io.pathName diff --git a/src/test/scala/chiselTests/IntervalSpec.scala b/src/test/scala/chiselTests/IntervalSpec.scala index d7b77e09249..1f81344263c 100644 --- a/src/test/scala/chiselTests/IntervalSpec.scala +++ b/src/test/scala/chiselTests/IntervalSpec.scala @@ -32,30 +32,18 @@ object IntervalTestHelper { */ //scalastyle:off cyclomatic.complexity def makeFirrtl[T <: RawModule](compilerName: String)(gen: () => T): String = { - val c = compilerName match { - case "none" => new NoneCompiler() - case "high" => new HighFirrtlCompiler() - case "lo" => new LowFirrtlCompiler() - case "low" => new LowFirrtlCompiler() - case "middle" => new MiddleFirrtlCompiler() - case "verilog" => new VerilogCompiler() - case "mverilog" => new MinimumVerilogCompiler() - case "sverilog" => new SystemVerilogCompiler() - case _ => - throw new Exception( - s"Unknown compiler name '$compilerName'! (Did you misspell it?)" - ) - } - val compiler = CompilerAnnotation(c) - val annotations = Seq(new ChiselGeneratorAnnotation(gen), TargetDirAnnotation("test_run_dir/IntervalSpec"), compiler) - val processed = (new ChiselStage).run(annotations) - processed.collectFirst { case FirrtlCircuitAnnotation(source) => source } match { - case Some(circuit) => circuit.serialize - case _ => - throw new Exception( - s"makeFirrtl($compilerName) failed to generate firrtl circuit" - ) - } + (new ChiselStage) + .execute(Array("--compiler", compilerName, + "--target-dir", "test_run_dir/IntervalSpec"), + Seq(ChiselGeneratorAnnotation(gen))) + .collectFirst { case FirrtlCircuitAnnotation(source) => source } match { + case Some(circuit) => circuit.serialize + case _ => + throw new Exception( + s"makeFirrtl($compilerName) failed to generate firrtl circuit" + ) + } + } } @@ -714,7 +702,7 @@ class IntervalSpec extends AnyFreeSpec with Matchers with ChiselRunners { } "squeeze disjoint from Module gives exception" in { intercept[DisjointSqueeze] { - makeFirrtl("lo")( + makeFirrtl("low")( () => new Module { val io = IO(new Bundle { @@ -731,7 +719,7 @@ class IntervalSpec extends AnyFreeSpec with Matchers with ChiselRunners { } } "clip disjoint from Module gives no error" in { - makeFirrtl("lo")( + makeFirrtl("low")( () => new Module { val io = IO(new Bundle { @@ -748,7 +736,7 @@ class IntervalSpec extends AnyFreeSpec with Matchers with ChiselRunners { } "wrap disjoint from Module wrap with remainder" in { intercept[WrapWithRemainder] { - makeFirrtl("lo")( + makeFirrtl("low")( () => new Module { val io = IO(new Bundle { @@ -779,7 +767,7 @@ class IntervalSpec extends AnyFreeSpec with Matchers with ChiselRunners { "Intervals should catch assignment of literals outside of range" - { "when literal is too small" in { intercept[InvalidConnect] { - makeFirrtl("lo")( + makeFirrtl("low")( () => new Module { val io = IO(new Bundle { val out = Output(Interval()) }) diff --git a/src/test/scala/chiselTests/InvalidateAPISpec.scala b/src/test/scala/chiselTests/InvalidateAPISpec.scala index 574fc88b6fd..f0841ef0a1b 100644 --- a/src/test/scala/chiselTests/InvalidateAPISpec.scala +++ b/src/test/scala/chiselTests/InvalidateAPISpec.scala @@ -3,18 +3,21 @@ package chiselTests import chisel3._ +import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} import chisel3.util.Counter import firrtl.passes.CheckInitialization.RefNotInitializedException import firrtl.util.BackendCompilationUtilities import org.scalatest._ import org.scalatest.matchers.should.Matchers -class InvalidateAPISpec extends ChiselPropSpec with Matchers with BackendCompilationUtilities { +class InvalidateAPISpec extends ChiselPropSpec with Matchers with BackendCompilationUtilities with Utils { - def myGenerateFirrtl(t: => Module): String = Driver.emit(() => t) + def myGenerateFirrtl(t: => Module): String = (new ChiselStage).emitChirrtl(t) def compileFirrtl(t: => Module): Unit = { val testDir = createTestDirectory(this.getClass.getSimpleName) - Driver.execute(Array[String]("-td", testDir.getAbsolutePath, "--compiler", "verilog"), () => t) + + (new ChiselStage).execute(Array[String]("-td", testDir.getAbsolutePath, "--compiler", "verilog"), + Seq(ChiselGeneratorAnnotation(() => t))) } class TrivialInterface extends Bundle { val in = Input(Bool()) @@ -99,7 +102,9 @@ class InvalidateAPISpec extends ChiselPropSpec with Matchers with BackendCompila DontCare := io.in } val exception = intercept[ChiselException] { - elaborate(new ModuleWithDontCareSink) + extractCause[ChiselException] { + ChiselStage.elaborate(new ModuleWithDontCareSink) + } } exception.getMessage should include("DontCare cannot be a connection sink (LHS)") } @@ -111,7 +116,9 @@ class InvalidateAPISpec extends ChiselPropSpec with Matchers with BackendCompila DontCare <> io.in } val exception = intercept[BiConnectException] { - elaborate(new ModuleWithDontCareSink) + extractCause[BiConnectException] { + ChiselStage.elaborate(new ModuleWithDontCareSink) + } } exception.getMessage should include("DontCare cannot be a connection sink (LHS)") } diff --git a/src/test/scala/chiselTests/LiteralExtractorSpec.scala b/src/test/scala/chiselTests/LiteralExtractorSpec.scala index 8735a0ae37e..0c485368737 100644 --- a/src/test/scala/chiselTests/LiteralExtractorSpec.scala +++ b/src/test/scala/chiselTests/LiteralExtractorSpec.scala @@ -5,6 +5,7 @@ package chiselTests import chisel3._ import chisel3.experimental._ import chisel3.experimental.BundleLiterals._ +import chisel3.stage.ChiselStage import chisel3.testers.BasicTester import scala.collection.immutable.ListMap @@ -50,7 +51,7 @@ class LiteralExtractorSpec extends ChiselFlatSpec { } "litOption" should "return None for non-literal hardware" in { - elaborate { new RawModule { + ChiselStage.elaborate { new RawModule { val a = Wire(UInt()) assert(a.litOption == None) }} diff --git a/src/test/scala/chiselTests/LoadMemoryFromFileSpec.scala b/src/test/scala/chiselTests/LoadMemoryFromFileSpec.scala index 9835ba101f5..529d90af078 100644 --- a/src/test/scala/chiselTests/LoadMemoryFromFileSpec.scala +++ b/src/test/scala/chiselTests/LoadMemoryFromFileSpec.scala @@ -5,6 +5,7 @@ package chiselTests import java.io.File import chisel3._ +import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} import chisel3.util.experimental.loadMemoryFromFile import chisel3.util.log2Ceil import firrtl.FirrtlExecutionSuccess @@ -126,64 +127,53 @@ class LoadMemoryFromFileSpec extends AnyFreeSpec with Matchers { "Users can specify a source file to load memory from" in { val testDirName = "test_run_dir/load_memory_spec" - val result = Driver.execute( + val result = (new ChiselStage).execute( args = Array("-X", "verilog", "--target-dir", testDirName), - dut = () => new UsesMem(memoryDepth = 8, memoryType = UInt(16.W)) ) - - result match { - case ChiselExecutionSuccess(_, _, Some(FirrtlExecutionSuccess(_, _))) => - val dir = new File(testDirName) - fileExistsWithMem(new File(dir, "UsesMem.UsesMem.memory.v"), Some("./mem1")) - fileExistsWithMem(new File(dir, "UsesMem.UsesMemLow.memory.v"), Some("./mem2")) - fileExistsWithMem(new File(dir, "firrtl_black_box_resource_files.f")) - case _=> - throw new Exception("Failed compile") - } + annotations = Seq(ChiselGeneratorAnnotation(() => new UsesMem(memoryDepth = 8, memoryType = UInt(16.W)))) + ) + + val dir = new File(testDirName) + fileExistsWithMem(new File(dir, "UsesMem.UsesMem.memory.v"), Some("./mem1")) + fileExistsWithMem(new File(dir, "UsesMem.UsesMemLow.memory.v"), Some("./mem2")) + fileExistsWithMem(new File(dir, "firrtl_black_box_resource_files.f")) + } "Calling a module that loads memories from a file more than once should work" in { val testDirName = "test_run_dir/load_three_memory_spec" - val result = Driver.execute( + val result = (new ChiselStage).execute( args = Array("-X", "verilog", "--target-dir", testDirName), - dut = () => new UsesThreeMems(memoryDepth = 8, memoryType = UInt(16.W)) + annotations = Seq(ChiselGeneratorAnnotation(() => new UsesThreeMems(memoryDepth = 8, memoryType = UInt(16.W)))) ) - result match { - case ChiselExecutionSuccess(_, _, Some(FirrtlExecutionSuccess(_, _))) => - val dir = new File(testDirName) - fileExistsWithMem( new File(dir, "UsesThreeMems.UsesThreeMems.memory1.v"), Some("./mem1")) - fileExistsWithMem( new File(dir, "UsesThreeMems.UsesThreeMems.memory2.v"), Some("./mem1")) - fileExistsWithMem( new File(dir, "UsesThreeMems.UsesThreeMems.memory3.v"), Some("./mem1")) - fileExistsWithMem( new File(dir, "firrtl_black_box_resource_files.f")) - case _=> - throw new Exception("Failed compile") - } } + val dir = new File(testDirName) + fileExistsWithMem( new File(dir, "UsesThreeMems.UsesThreeMems.memory1.v"), Some("./mem1")) + fileExistsWithMem( new File(dir, "UsesThreeMems.UsesThreeMems.memory2.v"), Some("./mem1")) + fileExistsWithMem( new File(dir, "UsesThreeMems.UsesThreeMems.memory3.v"), Some("./mem1")) + fileExistsWithMem( new File(dir, "firrtl_black_box_resource_files.f")) + + } "In this example the memory has a complex memory type containing a bundle" in { val complexTestDirName = "test_run_dir/complex_memory_load" - val result = Driver.execute( + val result = (new ChiselStage).execute( args = Array("-X", "verilog", "--target-dir", complexTestDirName), - dut = () => new HasComplexMemory(memoryDepth = 8) + annotations = Seq(ChiselGeneratorAnnotation(() => new HasComplexMemory(memoryDepth = 8))) ) - result match { - case ChiselExecutionSuccess(_, _, Some(FirrtlExecutionSuccess(emitType, firrtlEmitted))) => - val dir = new File(complexTestDirName) - val memoryElements = Seq("a", "b", "c") - - memoryElements.foreach { element => - val file = new File(dir, s"HasComplexMemory.HasComplexMemory.memory_$element.v") - file.exists() should be (true) - val fileText = io.Source.fromFile(file).getLines().mkString("\n") - fileText should include (s"""$$readmemh("./mem_$element", HasComplexMemory.memory_$element);""") - file.delete() - } - - case _=> - fail(s"Failed compile") + val dir = new File(complexTestDirName) + val memoryElements = Seq("a", "b", "c") + + memoryElements.foreach { element => + val file = new File(dir, s"HasComplexMemory.HasComplexMemory.memory_$element.v") + file.exists() should be (true) + val fileText = io.Source.fromFile(file).getLines().mkString("\n") + fileText should include (s"""$$readmemh("./mem_$element", HasComplexMemory.memory_$element);""") + file.delete() } + } } diff --git a/src/test/scala/chiselTests/MemorySearch.scala b/src/test/scala/chiselTests/MemorySearch.scala index 3264f4dd387..e9da5a4eda6 100644 --- a/src/test/scala/chiselTests/MemorySearch.scala +++ b/src/test/scala/chiselTests/MemorySearch.scala @@ -3,6 +3,7 @@ package chiselTests import chisel3._ +import chisel3.stage.ChiselStage class MemorySearch extends Module { val io = IO(new Bundle { @@ -50,7 +51,7 @@ class MemorySearchTester(c: MemorySearch) extends Tester(c) { class MemorySearchSpec extends ChiselPropSpec { property("MemorySearch should elaborate") { - elaborate { new EnableShiftRegister } + ChiselStage.elaborate { new EnableShiftRegister } } ignore("MemorySearch should return the correct result") { } diff --git a/src/test/scala/chiselTests/MissingCloneBindingExceptionSpec.scala b/src/test/scala/chiselTests/MissingCloneBindingExceptionSpec.scala index 50dbb341723..856a91f7762 100644 --- a/src/test/scala/chiselTests/MissingCloneBindingExceptionSpec.scala +++ b/src/test/scala/chiselTests/MissingCloneBindingExceptionSpec.scala @@ -2,12 +2,13 @@ package chiselTests import Chisel.ChiselException +import chisel3.stage.ChiselStage import org.scalatest._ import org.scalatest.matchers.should.Matchers -class MissingCloneBindingExceptionSpec extends ChiselFlatSpec with Matchers { +class MissingCloneBindingExceptionSpec extends ChiselFlatSpec with Matchers with Utils { behavior of "missing cloneType in Chisel3" - ( the[ChiselException] thrownBy { + ( the [ChiselException] thrownBy extractCause[ChiselException] { import chisel3._ class Test extends Module { @@ -26,11 +27,11 @@ class MissingCloneBindingExceptionSpec extends ChiselFlatSpec with Matchers { }) } - elaborate(new TestTop) + ChiselStage.elaborate(new TestTop) }).getMessage should include("make all parameters immutable") behavior of "missing cloneType in Chisel2" - ( the[ChiselException] thrownBy { + ( the [ChiselException] thrownBy extractCause[ChiselException] { import Chisel._ class Test extends Module { @@ -49,6 +50,6 @@ class MissingCloneBindingExceptionSpec extends ChiselFlatSpec with Matchers { } } - elaborate(new TestTop) + ChiselStage.elaborate(new TestTop) }).getMessage should include("make all parameters immutable") } diff --git a/src/test/scala/chiselTests/MixedVecSpec.scala b/src/test/scala/chiselTests/MixedVecSpec.scala index 5dd302709ef..1c823b1816f 100644 --- a/src/test/scala/chiselTests/MixedVecSpec.scala +++ b/src/test/scala/chiselTests/MixedVecSpec.scala @@ -3,6 +3,7 @@ package chiselTests import chisel3._ +import chisel3.stage.ChiselStage import chisel3.testers.BasicTester import chisel3.util._ import org.scalacheck.Shrink @@ -152,7 +153,7 @@ class MixedVecOneBitTester extends BasicTester { } } -class MixedVecSpec extends ChiselPropSpec { +class MixedVecSpec extends ChiselPropSpec with Utils { // Disable shrinking on error. // Not sure why this needs to be here, but the test behaves very weirdly without it (e.g. empty Lists, etc). implicit val noShrinkListVal = Shrink[List[Int]](_ => Stream.empty) @@ -208,22 +209,22 @@ class MixedVecSpec extends ChiselPropSpec { } property("MixedVecs should not be able to take hardware types") { - a [ExpectedChiselTypeException] should be thrownBy { - elaborate(new Module { + a [ExpectedChiselTypeException] should be thrownBy extractCause[ExpectedChiselTypeException] { + ChiselStage.elaborate(new Module { val io = IO(new Bundle {}) val hw = Wire(MixedVec(Seq(UInt(8.W), Bool()))) val illegal = MixedVec(hw) }) } - a [ExpectedChiselTypeException] should be thrownBy { - elaborate(new Module { + a [ExpectedChiselTypeException] should be thrownBy extractCause[ExpectedChiselTypeException] { + ChiselStage.elaborate(new Module { val io = IO(new Bundle {}) val hw = Reg(MixedVec(Seq(UInt(8.W), Bool()))) val illegal = MixedVec(hw) }) } - a [ExpectedChiselTypeException] should be thrownBy { - elaborate(new Module { + a [ExpectedChiselTypeException] should be thrownBy extractCause[ExpectedChiselTypeException] { + ChiselStage.elaborate(new Module { val io = IO(new Bundle { val v = Input(MixedVec(Seq(UInt(8.W), Bool()))) }) @@ -257,8 +258,8 @@ class MixedVecSpec extends ChiselPropSpec { } property("Connecting a MixedVec and something of different size should report a ChiselException") { - an [IllegalArgumentException] should be thrownBy { - elaborate(new Module { + an [IllegalArgumentException] should be thrownBy extractCause[IllegalArgumentException] { + ChiselStage.elaborate(new Module { val io = IO(new Bundle { val out = Output(MixedVec(Seq(UInt(8.W), Bool()))) }) @@ -266,8 +267,8 @@ class MixedVecSpec extends ChiselPropSpec { io.out := seq }) } - an [IllegalArgumentException] should be thrownBy { - elaborate(new Module { + an [IllegalArgumentException] should be thrownBy extractCause[IllegalArgumentException] { + ChiselStage.elaborate(new Module { val io = IO(new Bundle { val out = Output(MixedVec(Seq(UInt(8.W), Bool()))) }) diff --git a/src/test/scala/chiselTests/Module.scala b/src/test/scala/chiselTests/Module.scala index d8cae51026d..f4b51927ad5 100644 --- a/src/test/scala/chiselTests/Module.scala +++ b/src/test/scala/chiselTests/Module.scala @@ -3,6 +3,7 @@ package chiselTests import chisel3._ +import chisel3.stage.ChiselStage import chisel3.experimental.DataMirror class SimpleIO extends Bundle { @@ -75,46 +76,46 @@ class NullModuleWrapper extends Module { val child = Module(new ModuleWire) } -class ModuleSpec extends ChiselPropSpec { +class ModuleSpec extends ChiselPropSpec with Utils { property("ModuleVec should elaborate") { - elaborate { new ModuleVec(2) } + ChiselStage.elaborate { new ModuleVec(2) } } ignore("ModuleVecTester should return the correct result") { } property("ModuleWire should elaborate") { - elaborate { new ModuleWire } + ChiselStage.elaborate { new ModuleWire } } ignore("ModuleWireTester should return the correct result") { } property("ModuleWhen should elaborate") { - elaborate { new ModuleWhen } + ChiselStage.elaborate { new ModuleWhen } } ignore("ModuleWhenTester should return the correct result") { } property("Forgetting a Module() wrapper should result in an error") { - (the [ChiselException] thrownBy { - elaborate { new ModuleForgetWrapper } + (the [ChiselException] thrownBy extractCause[ChiselException] { + ChiselStage.elaborate { new ModuleForgetWrapper } }).getMessage should include("attempted to instantiate a Module without wrapping it") } property("Double wrapping a Module should result in an error") { - (the [ChiselException] thrownBy { - elaborate { new ModuleDoubleWrap } + (the [ChiselException] thrownBy extractCause[ChiselException] { + ChiselStage.elaborate { new ModuleDoubleWrap } }).getMessage should include("Called Module() twice without instantiating a Module") } property("Rewrapping an already instantiated Module should result in an error") { - (the [ChiselException] thrownBy { - elaborate { new ModuleRewrap } + (the [ChiselException] thrownBy extractCause[ChiselException] { + ChiselStage.elaborate { new ModuleRewrap } }).getMessage should include("This is probably due to rewrapping a Module instance") } property("object Module.clock should return a reference to the currently in scope clock") { - elaborate(new Module { + ChiselStage.elaborate(new Module { val io = IO(new Bundle { val clock2 = Input(Clock()) }) @@ -123,7 +124,7 @@ class ModuleSpec extends ChiselPropSpec { }) } property("object Module.reset should return a reference to the currently in scope reset") { - elaborate(new Module { + ChiselStage.elaborate(new Module { val io = IO(new Bundle { val reset2 = Input(Bool()) }) @@ -133,14 +134,14 @@ class ModuleSpec extends ChiselPropSpec { } property("object Module.currentModule should return an Option reference to the current Module") { def checkModule(mod: Module): Boolean = Module.currentModule.map(_ eq mod).getOrElse(false) - elaborate(new Module { + ChiselStage.elaborate(new Module { val io = IO(new Bundle { }) assert(Module.currentModule.get eq this) assert(checkModule(this)) }) } property("DataMirror.modulePorts should work") { - elaborate(new Module { + ChiselStage.elaborate(new Module { val io = IO(new Bundle { }) val m = Module(new chisel3.MultiIOModule { val a = IO(UInt(8.W)) @@ -152,10 +153,10 @@ class ModuleSpec extends ChiselPropSpec { }) } property("A desiredName parameterized by a submodule should work") { - Driver.elaborate(() => new ModuleWrapper(new ModuleWire)).name should be ("ModuleWireWrapper") + ChiselStage.elaborate(new ModuleWrapper(new ModuleWire)).name should be ("ModuleWireWrapper") } property("A name generating a null pointer exception should provide a good error message") { - (the [Exception] thrownBy (Driver.elaborate(() => new NullModuleWrapper))) + (the [ChiselException] thrownBy extractCause[ChiselException] (ChiselStage.elaborate(new NullModuleWrapper))) .getMessage should include ("desiredName of chiselTests.NullModuleWrapper is null") } property("The name of a module in a function should be sane") { @@ -165,12 +166,12 @@ class ModuleSpec extends ChiselPropSpec { } new Foo1 } - Driver.elaborate(() => foo) + ChiselStage.elaborate(foo) } property("The name of an anonymous module should include '_Anon'") { trait Foo { this: RawModule => assert(name.contains("_Anon")) } - Driver.elaborate(() => new RawModule with Foo) + ChiselStage.elaborate(new RawModule with Foo) } } diff --git a/src/test/scala/chiselTests/ModuleExplicitResetSpec.scala b/src/test/scala/chiselTests/ModuleExplicitResetSpec.scala index af2db95fca2..184c2bffb82 100644 --- a/src/test/scala/chiselTests/ModuleExplicitResetSpec.scala +++ b/src/test/scala/chiselTests/ModuleExplicitResetSpec.scala @@ -2,6 +2,8 @@ package chiselTests +import chisel3.stage.ChiselStage + class ModuleExplicitResetSpec extends ChiselFlatSpec { "A Module with an explicit reset in compatibility mode" should "elaborate" in { @@ -15,7 +17,7 @@ class ModuleExplicitResetSpec extends ChiselFlatSpec { io.done := false.B } - elaborate { + ChiselStage.elaborate { new ModuleExplicitReset(myReset) } } diff --git a/src/test/scala/chiselTests/MultiAssign.scala b/src/test/scala/chiselTests/MultiAssign.scala index 8da5bc42368..b232bd75f75 100644 --- a/src/test/scala/chiselTests/MultiAssign.scala +++ b/src/test/scala/chiselTests/MultiAssign.scala @@ -4,6 +4,7 @@ package chiselTests import chisel3._ import chisel3.testers.BasicTester +import chisel3.stage.ChiselStage import chisel3.util._ class LastAssignTester() extends BasicTester { @@ -30,36 +31,52 @@ class MultiAssignSpec extends ChiselFlatSpec { } } -class IllegalAssignSpec extends ChiselFlatSpec { +class IllegalAssignSpec extends ChiselFlatSpec with Utils { "Reassignments to literals" should "be disallowed" in { intercept[chisel3.internal.ChiselException] { - elaborate{ new BasicTester { - 15.U := 7.U - }} + extractCause[ChiselException] { + ChiselStage.elaborate{ + new BasicTester { + 15.U := 7.U + } + } + } } } "Reassignments to ops" should "be disallowed" in { intercept[chisel3.internal.ChiselException] { - elaborate{ new BasicTester { - (15.U + 1.U) := 7.U - }} + extractCause[ChiselException] { + ChiselStage.elaborate{ + new BasicTester { + (15.U + 1.U) := 7.U + } + } + } } } "Reassignments to bit slices" should "be disallowed" in { intercept[chisel3.internal.ChiselException] { - elaborate{ new BasicTester { - (15.U)(1, 0) := 7.U - }} + extractCause[ChiselException] { + ChiselStage.elaborate{ + new BasicTester { + (15.U)(1, 0) := 7.U + } + } + } } } "Bulk-connecting two read-only nodes" should "be disallowed" in { intercept[chisel3.internal.ChiselException] { - elaborate{ new BasicTester { - (15.U + 1.U) <> 7.U - }} + extractCause[ChiselException] { + ChiselStage.elaborate{ + new BasicTester { + (15.U + 1.U) <> 7.U + } + } + } } } } diff --git a/src/test/scala/chiselTests/MultiClockSpec.scala b/src/test/scala/chiselTests/MultiClockSpec.scala index 770a9e9a27a..1a71570d596 100644 --- a/src/test/scala/chiselTests/MultiClockSpec.scala +++ b/src/test/scala/chiselTests/MultiClockSpec.scala @@ -5,6 +5,7 @@ package chiselTests import chisel3._ import chisel3.util.Counter import chisel3.testers.BasicTester +import chisel3.stage.ChiselStage /** Multi-clock test of a Reg using a different clock via withClock */ class ClockDividerTest extends BasicTester { @@ -123,7 +124,7 @@ class MultiClockSpec extends ChiselFlatSpec { } it should "return like a normal Scala block" in { - elaborate(new BasicTester { + ChiselStage.elaborate(new BasicTester { assert(withClock(this.clock) { 5 } == 5) }) } @@ -137,7 +138,7 @@ class MultiClockSpec extends ChiselFlatSpec { } it should "return like a normal Scala block" in { - elaborate(new BasicTester { + ChiselStage.elaborate(new BasicTester { assert(withReset(this.reset) { 5 } == 5) }) } @@ -155,7 +156,7 @@ class MultiClockSpec extends ChiselFlatSpec { } "withClockAndReset" should "return like a normal Scala block" in { - elaborate(new BasicTester { + ChiselStage.elaborate(new BasicTester { assert(withClockAndReset(this.clock, this.reset) { 5 } == 5) }) } diff --git a/src/test/scala/chiselTests/MuxSpec.scala b/src/test/scala/chiselTests/MuxSpec.scala index 46710133a28..a995ea76594 100644 --- a/src/test/scala/chiselTests/MuxSpec.scala +++ b/src/test/scala/chiselTests/MuxSpec.scala @@ -3,6 +3,7 @@ package chiselTests import chisel3._ +import chisel3.stage.ChiselStage import chisel3.util.{MuxLookup, log2Ceil} import chisel3.testers.BasicTester @@ -37,34 +38,35 @@ class MuxLookupWrapper(keyWidth: Int, default: Int, mapping: () => Seq[(UInt, UI class MuxLookupExhaustiveSpec extends ChiselPropSpec { val keyWidth = 2 val default = 9 // must be less than 10 to avoid hex/decimal mismatches - val firrtlLit = s"""UInt<4>("h0$default")""" + val firrtlLit = s"""UInt<4>("h$default")""" + val stage = new ChiselStage // Assumes there are no literals with 'UInt<4>("h09")' in the output FIRRTL // Assumes no binary recoding in output val incomplete = () => Seq(0.U -> 1.U, 1.U -> 2.U, 2.U -> 3.U) property("The default value should not be optimized away for an incomplete MuxLookup") { - Driver.emit { () => new MuxLookupWrapper(keyWidth, default, incomplete) } should include (firrtlLit) + stage.emitChirrtl(new MuxLookupWrapper(keyWidth, default, incomplete)) should include (firrtlLit) } val exhaustive = () => (3.U -> 0.U) +: incomplete() property("The default value should be optimized away for an exhaustive MuxLookup") { - Driver.emit { () => new MuxLookupWrapper(keyWidth, default, exhaustive) } should not include (firrtlLit) + stage.emitChirrtl(new MuxLookupWrapper(keyWidth, default, exhaustive)) should not include (firrtlLit) } val overlap = () => (4096.U -> 0.U) +: incomplete() property("The default value should not be optimized away for a MuxLookup with 2^{keyWidth} non-distinct mappings") { - Driver.emit { () => new MuxLookupWrapper(keyWidth, default, overlap) } should include (firrtlLit) + stage.emitChirrtl(new MuxLookupWrapper(keyWidth, default, overlap)) should include (firrtlLit) } val nonLiteral = () => { val foo = Wire(UInt()); (foo -> 1.U) +: incomplete() } property("The default value should not be optimized away for a MuxLookup with a non-literal") { - Driver.emit { () => new MuxLookupWrapper(keyWidth, default, nonLiteral) } should include (firrtlLit) + stage.emitChirrtl(new MuxLookupWrapper(keyWidth, default, nonLiteral)) should include (firrtlLit) } val nonLiteralStillFull = () => { val foo = Wire(UInt()); (foo -> 1.U) +: exhaustive() } property("The default value should be optimized away for a MuxLookup with a non-literal that is still full") { - Driver.emit { () => new MuxLookupWrapper(keyWidth, default, nonLiteralStillFull) } should not include (firrtlLit) + stage.emitChirrtl(new MuxLookupWrapper(keyWidth, default, nonLiteralStillFull)) should not include (firrtlLit) } } diff --git a/src/test/scala/chiselTests/NamingAnnotationTest.scala b/src/test/scala/chiselTests/NamingAnnotationTest.scala index a02dfe56ef9..41cba1de31a 100644 --- a/src/test/scala/chiselTests/NamingAnnotationTest.scala +++ b/src/test/scala/chiselTests/NamingAnnotationTest.scala @@ -5,6 +5,7 @@ package chiselTests import chisel3._ import chisel3.experimental.chiselName import chisel3.internal.InstanceId +import chisel3.stage.ChiselStage import scala.collection.mutable.ListBuffer @@ -102,7 +103,7 @@ class NamedModule extends NamedModuleTester { val test = expectName(FunctionMockup(), "test") val test2 = expectName(test +& 2.U, "test2") val test3 = expectName(ImplicitlyNamed(), "test3") - + val test4 = new NonModule expectName(test4.value, "test4_value") expectName(test4.inner.value, "test4_inner_value") @@ -237,30 +238,30 @@ class NamingAnnotationSpec extends ChiselPropSpec { property("NamedModule should have function hierarchical names") { // TODO: clean up test style var module: NamedModule = null - elaborate { module = new NamedModule; module } + ChiselStage.elaborate { module = new NamedModule; module } assert(module.getNameFailures() == Nil) } property("NameCollisionModule should disambiguate collisions") { // TODO: clean up test style var module: NameCollisionModule = null - elaborate { module = new NameCollisionModule; module } + ChiselStage.elaborate { module = new NameCollisionModule; module } assert(module.getNameFailures() == Nil) } property("PartialNamedModule should have partial names") { // TODO: clean up test style var module: PartialNamedModule = null - elaborate { module = new PartialNamedModule; module } + ChiselStage.elaborate { module = new PartialNamedModule; module } assert(module.getNameFailures() == Nil) } property("NonNamedModule should elaborate") { - elaborate { new NonNamedModule } + ChiselStage.elaborate { new NonNamedModule } } property("NonNamedFunction should elaborate") { - elaborate { new NonNamedFunction } + ChiselStage.elaborate { new NonNamedFunction } } property("NonBuilderFunction should run outside a Builder context") { @@ -269,7 +270,7 @@ class NamingAnnotationSpec extends ChiselPropSpec { property("NoChiselNamePrefix should prevent prefixing when using @chiselName") { var module: NoChiselNamePrefixTester = null - elaborate { module = new NoChiselNamePrefixTester; module } + ChiselStage.elaborate { module = new NoChiselNamePrefixTester; module } assert(module.getNameFailures().isEmpty) } } diff --git a/src/test/scala/chiselTests/OptionBundle.scala b/src/test/scala/chiselTests/OptionBundle.scala index b9b50baaab9..33529633d0e 100644 --- a/src/test/scala/chiselTests/OptionBundle.scala +++ b/src/test/scala/chiselTests/OptionBundle.scala @@ -3,6 +3,7 @@ package chiselTests import chisel3._ +import chisel3.stage.ChiselStage import chisel3.testers.BasicTester class OptionBundle(val hasIn: Boolean) extends Bundle { @@ -43,7 +44,7 @@ class InvalidOptionBundleTester() extends BasicTester { stop() } -class OptionBundleSpec extends ChiselFlatSpec { +class OptionBundleSpec extends ChiselFlatSpec with Utils { "A Bundle with an Option field" should "work properly if the Option field is not None" in { assertTesterPasses { new SomeOptionBundleTester(true) } assertTesterPasses { new SomeOptionBundleTester(false) } @@ -54,8 +55,8 @@ class OptionBundleSpec extends ChiselFlatSpec { } "A Bundle with an Option field" should "assert out accessing a None Option field" in { - a [Exception] should be thrownBy { - elaborate { new InvalidOptionBundleTester() } + a [Exception] should be thrownBy extractCause[Exception] { + ChiselStage.elaborate { new InvalidOptionBundleTester() } } } } diff --git a/src/test/scala/chiselTests/Padding.scala b/src/test/scala/chiselTests/Padding.scala index 6f256b645a6..228d9e265e3 100644 --- a/src/test/scala/chiselTests/Padding.scala +++ b/src/test/scala/chiselTests/Padding.scala @@ -3,6 +3,7 @@ package chiselTests import chisel3._ +import chisel3.stage.ChiselStage class Padder extends Module { val io = IO(new Bundle { @@ -35,7 +36,7 @@ class PadsTester(c: Pads) extends Tester(c) { class PadderSpec extends ChiselPropSpec { property("Padder should elaborate") { - elaborate { new Padder } + ChiselStage.elaborate { new Padder } } ignore("PadderTester should return the correct result") { } diff --git a/src/test/scala/chiselTests/PrintableSpec.scala b/src/test/scala/chiselTests/PrintableSpec.scala index 3fa77072b21..8e39d40527d 100644 --- a/src/test/scala/chiselTests/PrintableSpec.scala +++ b/src/test/scala/chiselTests/PrintableSpec.scala @@ -3,6 +3,7 @@ package chiselTests import chisel3._ +import chisel3.stage.ChiselStage import chisel3.testers.BasicTester import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers @@ -37,7 +38,7 @@ class PrintableSpec extends AnyFlatSpec with Matchers { class MyModule extends BasicTester { printf(p"An exact string") } - val firrtl = Driver.emit(() => new MyModule) + val firrtl = (new ChiselStage).emitChirrtl(new MyModule) getPrintfs(firrtl) match { case Seq(Printf("An exact string", Seq())) => case e => fail() @@ -47,7 +48,7 @@ class PrintableSpec extends AnyFlatSpec with Matchers { class MyModule extends BasicTester { printf(p"First " + PString("Second ") + "Third") } - val firrtl = Driver.emit(() => new MyModule) + val firrtl = (new ChiselStage).emitChirrtl(new MyModule) getPrintfs(firrtl) match { case Seq(Printf("First Second Third", Seq())) => case e => fail() @@ -58,7 +59,7 @@ class PrintableSpec extends AnyFlatSpec with Matchers { val myInt = 1234 printf(p"myInt = $myInt") } - val firrtl = Driver.emit(() => new MyModule) + val firrtl = (new ChiselStage).emitChirrtl(new MyModule) getPrintfs(firrtl) match { case Seq(Printf("myInt = 1234", Seq())) => case e => fail() @@ -69,7 +70,7 @@ class PrintableSpec extends AnyFlatSpec with Matchers { val myWire = WireDefault(1234.U) printf(p"myWire = ${Decimal(myWire)}") } - val firrtl = Driver.emit(() => new MyModule) + val firrtl = (new ChiselStage).emitChirrtl(new MyModule) getPrintfs(firrtl) match { case Seq(Printf("myWire = %d", Seq("myWire"))) => case e => fail() @@ -79,7 +80,7 @@ class PrintableSpec extends AnyFlatSpec with Matchers { class MyModule extends BasicTester { printf(Decimal(10.U(32.W))) } - val firrtl = Driver.emit(() => new MyModule) + val firrtl = (new ChiselStage).emitChirrtl(new MyModule) getPrintfs(firrtl) match { case Seq(Printf("%d", Seq(lit))) => assert(lit contains "UInt<32>") @@ -90,7 +91,7 @@ class PrintableSpec extends AnyFlatSpec with Matchers { class MyModule extends BasicTester { printf(p"%") } - val firrtl = Driver.emit(() => new MyModule) + val firrtl = (new ChiselStage).emitChirrtl(new MyModule) getPrintfs(firrtl) match { case Seq(Printf("%%", Seq())) => case e => fail() @@ -100,7 +101,7 @@ class PrintableSpec extends AnyFlatSpec with Matchers { class MyModule extends BasicTester { printf(p"\t") } - val firrtl = Driver.emit(() => new MyModule) + val firrtl = (new ChiselStage).emitChirrtl(new MyModule) getPrintfs(firrtl) match { case Seq(Printf("\\t", Seq())) => case e => fail() @@ -126,7 +127,7 @@ class PrintableSpec extends AnyFlatSpec with Matchers { printf(p"${FullName(myWire.foo)}") printf(p"${FullName(myInst.io.fizz)}") } - val firrtl = Driver.emit(() => new MyModule) + val firrtl = (new ChiselStage).emitChirrtl(new MyModule) println(firrtl) // scalastyle:ignore regex getPrintfs(firrtl) match { case Seq(Printf("foo", Seq()), @@ -145,7 +146,7 @@ class PrintableSpec extends AnyFlatSpec with Matchers { val myInst = Module(new MySubModule) printf(p"${myInst.io.fizz}") } - val firrtl = Driver.emit(() => new MyModule) + val firrtl = (new ChiselStage).emitChirrtl(new MyModule) getPrintfs(firrtl) match { case Seq(Printf("%d", Seq("myInst.io.fizz"))) => case e => fail() @@ -157,7 +158,7 @@ class PrintableSpec extends AnyFlatSpec with Matchers { val mySInt = WireDefault(-1.S) printf(p"$myUInt & $mySInt") } - val firrtl = Driver.emit(() => new MyModule) + val firrtl = (new ChiselStage).emitChirrtl(new MyModule) getPrintfs(firrtl) match { case Seq(Printf("%d & %d", Seq("myUInt", "mySInt"))) => case e => fail() @@ -169,7 +170,7 @@ class PrintableSpec extends AnyFlatSpec with Matchers { myVec foreach (_ := 0.U) printf(p"$myVec") } - val firrtl = Driver.emit(() => new MyModule) + val firrtl = (new ChiselStage).emitChirrtl(new MyModule) getPrintfs(firrtl) match { case Seq(Printf("Vec(%d, %d, %d, %d)", Seq("myVec[0]", "myVec[1]", "myVec[2]", "myVec[3]"))) => @@ -186,7 +187,7 @@ class PrintableSpec extends AnyFlatSpec with Matchers { myBun.bar := 0.U printf(p"$myBun") } - val firrtl = Driver.emit(() => new MyModule) + val firrtl = (new ChiselStage).emitChirrtl(new MyModule) getPrintfs(firrtl) match { case Seq(Printf("AnonymousBundle(foo -> %d, bar -> %d)", Seq("myBun.foo", "myBun.bar"))) => diff --git a/src/test/scala/chiselTests/RawModuleSpec.scala b/src/test/scala/chiselTests/RawModuleSpec.scala index 45d6b58ae1d..192e66a36c9 100644 --- a/src/test/scala/chiselTests/RawModuleSpec.scala +++ b/src/test/scala/chiselTests/RawModuleSpec.scala @@ -3,6 +3,7 @@ package chiselTests import chisel3._ +import chisel3.stage.ChiselStage import chisel3.testers.BasicTester class UnclockedPlusOne extends RawModule { @@ -58,9 +59,9 @@ class ImplicitModuleDirectlyInRawModuleTester extends BasicTester { stop() } -class RawModuleSpec extends ChiselFlatSpec { +class RawModuleSpec extends ChiselFlatSpec with Utils { "RawModule" should "elaborate" in { - elaborate { new RawModuleWithImplicitModule } + ChiselStage.elaborate { new RawModuleWithImplicitModule } } "RawModule" should "work" in { @@ -74,13 +75,17 @@ class RawModuleSpec extends ChiselFlatSpec { "ImplicitModule directly in a RawModule" should "fail" in { intercept[chisel3.internal.ChiselException] { - elaborate { new RawModuleWithDirectImplicitModule } + extractCause[ChiselException] { + ChiselStage.elaborate { new RawModuleWithDirectImplicitModule } + } } } "ImplicitModule directly in a RawModule in an ImplicitModule" should "fail" in { intercept[chisel3.internal.ChiselException] { - elaborate { new ImplicitModuleDirectlyInRawModuleTester } + extractCause[ChiselException] { + ChiselStage.elaborate { new ImplicitModuleDirectlyInRawModuleTester } + } } } } diff --git a/src/test/scala/chiselTests/RebindingSpec.scala b/src/test/scala/chiselTests/RebindingSpec.scala index f7a79ace398..c246d68290e 100644 --- a/src/test/scala/chiselTests/RebindingSpec.scala +++ b/src/test/scala/chiselTests/RebindingSpec.scala @@ -3,11 +3,12 @@ package chiselTests import chisel3._ +import chisel3.stage.ChiselStage -class RebindingSpec extends ChiselFlatSpec { +class RebindingSpec extends ChiselFlatSpec with Utils { "Rebinding a literal" should "fail" in { - a [BindingException] should be thrownBy { - elaborate { new Module { + a [BindingException] should be thrownBy extractCause[BindingException] { + ChiselStage.elaborate { new Module { val io = IO(new Bundle { val a = 4.U }) @@ -16,8 +17,8 @@ class RebindingSpec extends ChiselFlatSpec { } "Rebinding a hardware type" should "fail" in { - a [BindingException] should be thrownBy { - elaborate { new Module { + a [BindingException] should be thrownBy extractCause[BindingException] { + ChiselStage.elaborate { new Module { val io = IO(new Bundle { val a = Reg(UInt(32.W)) }) diff --git a/src/test/scala/chiselTests/RecordSpec.scala b/src/test/scala/chiselTests/RecordSpec.scala index 412429815df..b80090c3580 100644 --- a/src/test/scala/chiselTests/RecordSpec.scala +++ b/src/test/scala/chiselTests/RecordSpec.scala @@ -3,6 +3,7 @@ package chiselTests import chisel3._ +import chisel3.stage.ChiselStage import chisel3.testers.BasicTester import chisel3.util.{Counter, Queue} import chisel3.experimental.{DataMirror, requireIsChiselType} @@ -109,15 +110,15 @@ trait RecordSpecUtils { } } -class RecordSpec extends ChiselFlatSpec with RecordSpecUtils { +class RecordSpec extends ChiselFlatSpec with RecordSpecUtils with Utils { behavior of "Records" they should "bulk connect similarly to Bundles" in { - elaborate { new MyModule(fooBarType, fooBarType) } + ChiselStage.elaborate { new MyModule(fooBarType, fooBarType) } } they should "bulk connect to Bundles" in { - elaborate { new MyModule(new MyBundle, fooBarType) } + ChiselStage.elaborate { new MyModule(new MyBundle, fooBarType) } } they should "follow UInt serialization/deserialization API" in { @@ -137,17 +138,17 @@ class RecordSpec extends ChiselFlatSpec with RecordSpecUtils { } "Bulk connect on Record" should "check that the fields match" in { - (the [ChiselException] thrownBy { - elaborate { new MyModule(fooBarType, new CustomBundle("bar" -> UInt(32.W))) } + (the [ChiselException] thrownBy extractCause[ChiselException] { + ChiselStage.elaborate { new MyModule(fooBarType, new CustomBundle("bar" -> UInt(32.W))) } }).getMessage should include ("Right Record missing field") - (the [ChiselException] thrownBy { - elaborate { new MyModule(new CustomBundle("bar" -> UInt(32.W)), fooBarType) } + (the [ChiselException] thrownBy extractCause[ChiselException] { + ChiselStage.elaborate { new MyModule(new CustomBundle("bar" -> UInt(32.W)), fooBarType) } }).getMessage should include ("Left Record missing field") } "CustomBundle" should "work like built-in aggregates" in { - elaborate(new Module { + ChiselStage.elaborate(new Module { val gen = new CustomBundle("foo" -> UInt(32.W)) val io = IO(Output(gen)) val wire = Wire(gen) @@ -156,6 +157,6 @@ class RecordSpec extends ChiselFlatSpec with RecordSpecUtils { } "CustomBundle" should "check the types" in { - elaborate { new RecordTypeTester } + ChiselStage.elaborate { new RecordTypeTester } } } diff --git a/src/test/scala/chiselTests/Reg.scala b/src/test/scala/chiselTests/Reg.scala index c4df0742050..576c75017d7 100644 --- a/src/test/scala/chiselTests/Reg.scala +++ b/src/test/scala/chiselTests/Reg.scala @@ -5,6 +5,7 @@ package chiselTests import chisel3._ import chisel3.util._ import chisel3.experimental.DataMirror +import chisel3.stage.ChiselStage import chisel3.testers.BasicTester class RegSpec extends ChiselFlatSpec { @@ -13,7 +14,7 @@ class RegSpec extends ChiselFlatSpec { val reg = Reg(UInt(2.W)) DataMirror.widthOf(reg) should be (2.W) } - elaborate{ new RegOutTypeWidthTester } + ChiselStage.elaborate{ new RegOutTypeWidthTester } } "RegNext" should "be of unknown width" in { @@ -25,7 +26,7 @@ class RegSpec extends ChiselFlatSpec { val reg3 = RegNext(2.U(3.W), 4.U(5.W)) DataMirror.widthOf(reg3).known should be (false) } - elaborate { new RegUnknownWidthTester } + ChiselStage.elaborate { new RegUnknownWidthTester } } "RegInit" should "have width only if specified in the literal" in { @@ -35,7 +36,7 @@ class RegSpec extends ChiselFlatSpec { val reg2 = RegInit(20.U(7.W)) DataMirror.widthOf(reg2) should be (7.W) } - elaborate{ new RegForcedWidthTester } + ChiselStage.elaborate{ new RegForcedWidthTester } } } diff --git a/src/test/scala/chiselTests/ResetSpec.scala b/src/test/scala/chiselTests/ResetSpec.scala index d08be8fa262..9d67637dbd9 100644 --- a/src/test/scala/chiselTests/ResetSpec.scala +++ b/src/test/scala/chiselTests/ResetSpec.scala @@ -3,6 +3,7 @@ package chiselTests import chisel3._ +import chisel3.stage.ChiselStage import chisel3.util.{Counter, Queue} import chisel3.testers.BasicTester @@ -35,12 +36,12 @@ class AbstractResetDontCareModule extends RawModule { } -class ResetSpec extends ChiselFlatSpec { +class ResetSpec extends ChiselFlatSpec with Utils { behavior of "Reset" it should "be able to be connected to DontCare" in { - elaborate(new AbstractResetDontCareModule) + ChiselStage.elaborate(new AbstractResetDontCareModule) } it should "allow writing modules that are reset agnostic" in { @@ -72,22 +73,22 @@ class ResetSpec extends ChiselFlatSpec { behavior of "Users" they should "be able to force implicit reset to be synchronous" in { - val fir = generateFirrtl(new MultiIOModule with RequireSyncReset { + val fir = (new ChiselStage).emitChirrtl(new MultiIOModule with RequireSyncReset { reset shouldBe a [Bool] }) fir should include ("input reset : UInt<1>") } they should "be able to force implicit reset to be asynchronous" in { - val fir = generateFirrtl(new MultiIOModule with RequireAsyncReset { + val fir = (new ChiselStage).emitChirrtl(new MultiIOModule with RequireAsyncReset { reset shouldBe an [AsyncReset] }) fir should include ("input reset : AsyncReset") } "Chisel" should "error if sync and async modules are nested" in { - a [ChiselException] shouldBe thrownBy { - elaborate(new MultiIOModule with RequireAsyncReset { + a [ChiselException] should be thrownBy extractCause[ChiselException] { + ChiselStage.elaborate(new MultiIOModule with RequireAsyncReset { val mod = Module(new MultiIOModule with RequireSyncReset) }) } diff --git a/src/test/scala/chiselTests/Risc.scala b/src/test/scala/chiselTests/Risc.scala index 21b638e52f3..de39e7232f4 100644 --- a/src/test/scala/chiselTests/Risc.scala +++ b/src/test/scala/chiselTests/Risc.scala @@ -3,6 +3,7 @@ package chiselTests import chisel3._ +import chisel3.stage.ChiselStage import chisel3.util._ class Risc extends Module { @@ -117,7 +118,7 @@ class RiscTester(c: Risc) extends Tester(c) { class RiscSpec extends ChiselPropSpec { property("Risc should elaborate") { - elaborate { new Risc } + ChiselStage.elaborate { new Risc } } ignore("RiscTester should return the correct result") { } diff --git a/src/test/scala/chiselTests/SIntOps.scala b/src/test/scala/chiselTests/SIntOps.scala index 9309c915e9e..5baf52b897b 100644 --- a/src/test/scala/chiselTests/SIntOps.scala +++ b/src/test/scala/chiselTests/SIntOps.scala @@ -3,6 +3,7 @@ package chiselTests import chisel3._ +import chisel3.stage.ChiselStage import chisel3.testers.BasicTester class SIntOps extends Module { @@ -97,14 +98,16 @@ class SIntLitExtractTester extends BasicTester { stop() } -class SIntOpsSpec extends ChiselPropSpec { +class SIntOpsSpec extends ChiselPropSpec with Utils { property("SIntOps should elaborate") { - elaborate { new SIntOps } + ChiselStage.elaborate { new SIntOps } } property("Negative shift amounts are invalid") { - a [ChiselException] should be thrownBy { elaborate(new NegativeShift(SInt())) } + a [ChiselException] should be thrownBy extractCause[ChiselException] { + ChiselStage.elaborate(new NegativeShift(SInt())) + } } ignore("SIntOpsTester should return the correct result") { } diff --git a/src/test/scala/chiselTests/Stack.scala b/src/test/scala/chiselTests/Stack.scala index 3c13273aa61..36f82960ce7 100644 --- a/src/test/scala/chiselTests/Stack.scala +++ b/src/test/scala/chiselTests/Stack.scala @@ -3,6 +3,7 @@ package chiselTests import chisel3._ +import chisel3.stage.ChiselStage import chisel3.util._ class ChiselStack(val depth: Int) extends Module { @@ -69,7 +70,7 @@ class StackTester(c: Stack) extends Tester(c) { class StackSpec extends ChiselPropSpec { property("Stack should elaborate") { - elaborate { new ChiselStack(2) } + ChiselStage.elaborate { new ChiselStack(2) } } ignore("StackTester should return the correct result") { } diff --git a/src/test/scala/chiselTests/StrongEnum.scala b/src/test/scala/chiselTests/StrongEnum.scala index 0ebabe16c0b..f052e783f9e 100644 --- a/src/test/scala/chiselTests/StrongEnum.scala +++ b/src/test/scala/chiselTests/StrongEnum.scala @@ -6,6 +6,7 @@ import chisel3._ import chisel3.experimental.ChiselEnum import chisel3.internal.firrtl.UnknownWidth import chisel3.internal.naming.chiselName +import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} import chisel3.util._ import chisel3.testers.BasicTester import org.scalatest.Assertion @@ -269,41 +270,41 @@ class StrongEnumFSMTester extends BasicTester { } } -class StrongEnumSpec extends ChiselFlatSpec { +class StrongEnumSpec extends ChiselFlatSpec with Utils { import chisel3.internal.ChiselException behavior of "Strong enum tester" it should "fail to instantiate non-literal enums with the Value function" in { - an [ExceptionInInitializerError] should be thrownBy { - elaborate(new SimpleConnector(NonLiteralEnumType(), NonLiteralEnumType())) + an [ExceptionInInitializerError] should be thrownBy extractCause[ExceptionInInitializerError] { + ChiselStage.elaborate(new SimpleConnector(NonLiteralEnumType(), NonLiteralEnumType())) } } it should "fail to instantiate non-increasing enums with the Value function" in { - an [ExceptionInInitializerError] should be thrownBy { - elaborate(new SimpleConnector(NonIncreasingEnum(), NonIncreasingEnum())) + an [ExceptionInInitializerError] should be thrownBy extractCause[ExceptionInInitializerError] { + ChiselStage.elaborate(new SimpleConnector(NonIncreasingEnum(), NonIncreasingEnum())) } } it should "connect enums of the same type" in { - elaborate(new SimpleConnector(EnumExample(), EnumExample())) - elaborate(new SimpleConnector(EnumExample(), EnumExample.Type())) + ChiselStage.elaborate(new SimpleConnector(EnumExample(), EnumExample())) + ChiselStage.elaborate(new SimpleConnector(EnumExample(), EnumExample.Type())) } it should "fail to connect a strong enum to a UInt" in { - a [ChiselException] should be thrownBy { - elaborate(new SimpleConnector(EnumExample(), UInt())) + a [ChiselException] should be thrownBy extractCause[ChiselException] { + ChiselStage.elaborate(new SimpleConnector(EnumExample(), UInt())) } } it should "fail to connect enums of different types" in { - a [ChiselException] should be thrownBy { - elaborate(new SimpleConnector(EnumExample(), OtherEnum())) + a [ChiselException] should be thrownBy extractCause[ChiselException] { + ChiselStage.elaborate(new SimpleConnector(EnumExample(), OtherEnum())) } - a [ChiselException] should be thrownBy { - elaborate(new SimpleConnector(EnumExample.Type(), OtherEnum.Type())) + a [ChiselException] should be thrownBy extractCause[ChiselException] { + ChiselStage.elaborate(new SimpleConnector(EnumExample.Type(), OtherEnum.Type())) } } @@ -320,22 +321,22 @@ class StrongEnumSpec extends ChiselFlatSpec { } it should "prevent illegal literal casts to enums" in { - a [ChiselException] should be thrownBy { - elaborate(new CastToInvalidEnumTester) + a [ChiselException] should be thrownBy extractCause[ChiselException] { + ChiselStage.elaborate(new CastToInvalidEnumTester) } } it should "only allow non-literal casts to enums if the width is smaller than or equal to the enum width" in { for (w <- 0 to EnumExample.getWidth) - elaborate(new CastFromNonLitWidth(Some(w))) + ChiselStage.elaborate(new CastFromNonLitWidth(Some(w))) - a [ChiselException] should be thrownBy { - elaborate(new CastFromNonLitWidth) + a [ChiselException] should be thrownBy extractCause[ChiselException] { + ChiselStage.elaborate(new CastFromNonLitWidth) } for (w <- (EnumExample.getWidth + 1) to (EnumExample.getWidth + 100)) { - a [ChiselException] should be thrownBy { - elaborate(new CastFromNonLitWidth(Some(w))) + a [ChiselException] should be thrownBy extractCause[ChiselException] { + ChiselStage.elaborate(new CastFromNonLitWidth(Some(w))) } } } @@ -345,8 +346,8 @@ class StrongEnumSpec extends ChiselFlatSpec { } it should "fail to compare enums of different types" in { - a [ChiselException] should be thrownBy { - elaborate(new InvalidEnumOpsTester) + a [ChiselException] should be thrownBy extractCause[ChiselException] { + ChiselStage.elaborate(new InvalidEnumOpsTester) } } @@ -597,23 +598,17 @@ class StrongEnumAnnotationSpec extends AnyFreeSpec with Matchers { corrects.forall(c => annos.exists(isCorrect(_, c))) def test(strongEnumAnnotatorGen: () => Module) { - Driver.execute(Array("--target-dir", "test_run_dir"), strongEnumAnnotatorGen) match { - case ChiselExecutionSuccess(Some(circuit), emitted, _) => - val annos = circuit.annotations.map(_.toFirrtl) + val annos = (new ChiselStage).execute(Array("--target-dir", "test_run_dir", "--no-run-firrtl"), + Seq(ChiselGeneratorAnnotation(strongEnumAnnotatorGen))) - printAnnos(annos) + val enumDefAnnos = annos.collect { case a: EnumDefAnnotation => a } + val enumCompAnnos = annos.collect { case a: EnumComponentAnnotation => a } + val enumVecAnnos = annos.collect { case a: EnumVecAnnotation => a } - val enumDefAnnos = annos.collect { case a: EnumDefAnnotation => a } - val enumCompAnnos = annos.collect { case a: EnumComponentAnnotation => a } - val enumVecAnnos = annos.collect { case a: EnumVecAnnotation => a } + allCorrectDefs(enumDefAnnos, correctDefAnnos) should be(true) + allCorrectComps(enumCompAnnos, correctCompAnnos) should be(true) + allCorrectVecs(enumVecAnnos, correctVecAnnos) should be(true) - allCorrectDefs(enumDefAnnos, correctDefAnnos) should be(true) - allCorrectComps(enumCompAnnos, correctCompAnnos) should be(true) - allCorrectVecs(enumVecAnnos, correctVecAnnos) should be(true) - - case _ => - assert(false) - } } "Test that strong enums annotate themselves appropriately" in { diff --git a/src/test/scala/chiselTests/SwitchSpec.scala b/src/test/scala/chiselTests/SwitchSpec.scala index 2991a928098..79849c769cb 100644 --- a/src/test/scala/chiselTests/SwitchSpec.scala +++ b/src/test/scala/chiselTests/SwitchSpec.scala @@ -3,12 +3,13 @@ package chiselTests import chisel3._ +import chisel3.stage.ChiselStage import chisel3.util._ -class SwitchSpec extends ChiselFlatSpec { +class SwitchSpec extends ChiselFlatSpec with Utils { "switch" should "require literal conditions" in { - a [java.lang.IllegalArgumentException] should be thrownBy { - elaborate(new Module { + a [java.lang.IllegalArgumentException] should be thrownBy extractCause[IllegalArgumentException] { + ChiselStage.elaborate(new Module { val io = IO(new Bundle {}) val state = RegInit(0.U) val wire = WireDefault(0.U) @@ -19,8 +20,8 @@ class SwitchSpec extends ChiselFlatSpec { } } it should "require mutually exclusive conditions" in { - a [java.lang.IllegalArgumentException] should be thrownBy { - elaborate(new Module { + a [java.lang.IllegalArgumentException] should be thrownBy extractCause[IllegalArgumentException] { + ChiselStage.elaborate(new Module { val io = IO(new Bundle {}) val state = RegInit(0.U) switch (state) { diff --git a/src/test/scala/chiselTests/TransitNameSpec.scala b/src/test/scala/chiselTests/TransitNameSpec.scala index b729f244bd8..af45988a4cc 100644 --- a/src/test/scala/chiselTests/TransitNameSpec.scala +++ b/src/test/scala/chiselTests/TransitNameSpec.scala @@ -3,6 +3,7 @@ package chiselTests import chisel3._ +import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} import chisel3.util.TransitName import firrtl.FirrtlExecutionSuccess @@ -38,18 +39,17 @@ class TransitNameSpec extends AnyFlatSpec with Matchers { it should "transit a name" in { - Driver.execute(Array("-X", "high", "--target-dir", "test_run_dir/TransitNameSpec"), () => new Top) match { - case ChiselExecutionSuccess(_,_,Some(FirrtlExecutionSuccess(_,a))) => - info("""output FIRRTL includes "inst MyModule"""") - a should include ("inst MyModule of MyModule") + val firrtl = (new ChiselStage) + .emitFirrtl(new Top, Array("--target-dir", "test_run_dir/TransitNameSpec")) - info("""output FIRRTL includes "inst bar"""") - a should include ("inst bar of MyModule") + info("""output FIRRTL includes "inst MyModule"""") + firrtl should include ("inst MyModule of MyModule") - info("""output FIRRTL includes "inst baz_generated"""") - a should include ("inst baz_generated of MyModule") - case _ => fail - } + info("""output FIRRTL includes "inst bar"""") + firrtl should include ("inst bar of MyModule") + + info("""output FIRRTL includes "inst baz_generated"""") + firrtl should include ("inst baz_generated of MyModule") } } diff --git a/src/test/scala/chiselTests/UIntOps.scala b/src/test/scala/chiselTests/UIntOps.scala index 0c7e2dcda48..a13077ba130 100644 --- a/src/test/scala/chiselTests/UIntOps.scala +++ b/src/test/scala/chiselTests/UIntOps.scala @@ -4,6 +4,7 @@ package chiselTests import chisel3._ import org.scalatest._ +import chisel3.stage.ChiselStage import chisel3.testers.BasicTester import org.scalacheck.Shrink import org.scalatest.matchers.should.Matchers @@ -112,21 +113,21 @@ class UIntLitExtractTester extends BasicTester { stop() } -class UIntOpsSpec extends ChiselPropSpec with Matchers { +class UIntOpsSpec extends ChiselPropSpec with Matchers with Utils { // Disable shrinking on error. implicit val noShrinkListVal = Shrink[List[Int]](_ => Stream.empty) implicit val noShrinkInt = Shrink[Int](_ => Stream.empty) property("Bools can be created from 1 bit UInts") { - elaborate(new GoodBoolConversion) + ChiselStage.elaborate(new GoodBoolConversion) } property("Bools cannot be created from >1 bit UInts") { - a [Exception] should be thrownBy { elaborate(new BadBoolConversion) } + a [Exception] should be thrownBy extractCause[Exception] { ChiselStage.elaborate(new BadBoolConversion) } } property("UIntOps should elaborate") { - elaborate { new UIntOps } + ChiselStage.elaborate { new UIntOps } } property("UIntOpsTester should return the correct result") { @@ -134,7 +135,9 @@ class UIntOpsSpec extends ChiselPropSpec with Matchers { } property("Negative shift amounts are invalid") { - a [ChiselException] should be thrownBy { elaborate(new NegativeShift(UInt())) } + a [ChiselException] should be thrownBy extractCause[ChiselException] { + ChiselStage.elaborate(new NegativeShift(UInt())) + } } property("Bit extraction on literals should work for all non-negative indices") { @@ -142,7 +145,7 @@ class UIntOpsSpec extends ChiselPropSpec with Matchers { } property("asBools should support chained apply") { - elaborate(new Module { + ChiselStage.elaborate(new Module { val io = IO(new Bundle { val in = Input(UInt(8.W)) val out = Output(Bool()) @@ -151,4 +154,3 @@ class UIntOpsSpec extends ChiselPropSpec with Matchers { }) } } - diff --git a/src/test/scala/chiselTests/Vec.scala b/src/test/scala/chiselTests/Vec.scala index 2f67f375a35..bca9afb8f90 100644 --- a/src/test/scala/chiselTests/Vec.scala +++ b/src/test/scala/chiselTests/Vec.scala @@ -3,6 +3,7 @@ package chiselTests import chisel3._ +import chisel3.stage.ChiselStage import chisel3.testers.BasicTester import chisel3.util._ import org.scalacheck.Shrink @@ -180,7 +181,7 @@ class ModuleIODynamicIndexTester(n: Int) extends BasicTester { when (done) { stop() } } -class VecSpec extends ChiselPropSpec { +class VecSpec extends ChiselPropSpec with Utils { // Disable shrinking on error. implicit val noShrinkListVal = Shrink[List[Int]](_ => Stream.empty) implicit val noShrinkInt = Shrink[Int](_ => Stream.empty) @@ -200,8 +201,8 @@ class VecSpec extends ChiselPropSpec { property("Vec.fill with a pure type should generate an exception") { // We don't really need a sequence of random widths here, since any should throw an exception. forAll(safeUIntWidth) { case(w: Int) => - an[BindingException] should be thrownBy { - elaborate(new IOTesterModFill(w)) + an[BindingException] should be thrownBy extractCause[BindingException] { + ChiselStage.elaborate(new IOTesterModFill(w)) } } } @@ -243,7 +244,7 @@ class VecSpec extends ChiselPropSpec { } property("It should be possible to bulk connect a Vec and a Seq") { - elaborate(new Module { + ChiselStage.elaborate(new Module { val io = IO(new Bundle { val out = Output(Vec(4, UInt(8.W))) }) @@ -253,8 +254,8 @@ class VecSpec extends ChiselPropSpec { } property("Bulk connecting a Vec and Seq of different sizes should report a ChiselException") { - a [ChiselException] should be thrownBy { - elaborate(new Module { + a [ChiselException] should be thrownBy extractCause[ChiselException] { + ChiselStage.elaborate(new Module { val io = IO(new Bundle { val out = Output(Vec(4, UInt(8.W))) }) @@ -265,7 +266,7 @@ class VecSpec extends ChiselPropSpec { } property("It should be possible to initialize a Vec with DontCare") { - elaborate(new Module { + ChiselStage.elaborate(new Module { val io = IO(new Bundle { val out = Output(Vec(4, UInt(8.W))) }) @@ -274,8 +275,8 @@ class VecSpec extends ChiselPropSpec { } property("Indexing a Chisel type Vec by a hardware type should give a sane error message") { - assertThrows[ExpectedHardwareException] { - elaborate{ + a [ExpectedHardwareException] should be thrownBy extractCause[ChiselException] { + ChiselStage.elaborate{ new Module { val io = IO(new Bundle{}) val foo = Vec(2, Bool()) diff --git a/src/test/scala/chiselTests/When.scala b/src/test/scala/chiselTests/When.scala index df9c8cce185..9f4f35b06d7 100644 --- a/src/test/scala/chiselTests/When.scala +++ b/src/test/scala/chiselTests/When.scala @@ -3,6 +3,7 @@ package chiselTests import chisel3._ +import chisel3.stage.ChiselStage import chisel3.testers.BasicTester import chisel3.util._ @@ -91,7 +92,7 @@ class SubmoduleWhenTester extends BasicTester { } } -class WhenSpec extends ChiselFlatSpec { +class WhenSpec extends ChiselFlatSpec with Utils { "When, elsewhen, and otherwise with orthogonal conditions" should "work" in { assertTesterPasses{ new WhenTester } } @@ -106,8 +107,8 @@ class WhenSpec extends ChiselFlatSpec { } "Returning in a when scope" should "give a reasonable error message" in { - val e = the [ChiselException] thrownBy { - elaborate(new Module { + val e = the [ChiselException] thrownBy extractCause[ChiselException] { + ChiselStage.elaborate(new Module { val io = IO(new Bundle { val foo = Input(UInt(8.W)) val bar = Input(UInt(8.W)) diff --git a/src/test/scala/chiselTests/experimental/GroupSpec.scala b/src/test/scala/chiselTests/experimental/GroupSpec.scala index 593179f4f90..f1820f5b19b 100644 --- a/src/test/scala/chiselTests/experimental/GroupSpec.scala +++ b/src/test/scala/chiselTests/experimental/GroupSpec.scala @@ -5,7 +5,7 @@ package chiselTests.experimental import chiselTests.ChiselFlatSpec import chisel3._ import chisel3.RawModule -import chisel3.stage.{ChiselGeneratorAnnotation, ChiselMain} +import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} import chisel3.util.experimental.group import firrtl.analyses.InstanceGraph import firrtl.options.TargetDirAnnotation @@ -31,15 +31,13 @@ class GroupSpec extends ChiselFlatSpec { } def lower[T <: RawModule](gen: () => T): fir.Circuit = { - (ChiselMain.stage.run( - Seq( - CompilerAnnotation(new LowFirrtlCompiler()), - TargetDirAnnotation("test_run_dir"), - ChiselGeneratorAnnotation(gen) - ) - ) collectFirst { - case firrtl.stage.FirrtlCircuitAnnotation(circuit) => circuit - }).get + (new ChiselStage) + .execute(Array("--compiler", "low", + "--target-dir", "test_run_dir"), + Seq(ChiselGeneratorAnnotation(gen))) + .collectFirst { + case firrtl.stage.FirrtlCircuitAnnotation(circuit) => circuit + }.get } "Module Grouping" should "compile to low FIRRTL" in { diff --git a/src/test/scala/chiselTests/experimental/ProgrammaticPortsSpec.scala b/src/test/scala/chiselTests/experimental/ProgrammaticPortsSpec.scala index 09e401f26d3..2cfc5f8d5a8 100644 --- a/src/test/scala/chiselTests/experimental/ProgrammaticPortsSpec.scala +++ b/src/test/scala/chiselTests/experimental/ProgrammaticPortsSpec.scala @@ -4,6 +4,7 @@ package chiselTests package experimental import chisel3._ +import chisel3.stage.ChiselStage // NOTE This is currently an experimental API and subject to change // Example using a private port @@ -31,11 +32,11 @@ class PortsWinTester extends NamedModuleTester { val output = expectName(IO(Output(UInt())).suggestName("wire"), "wire") } -class ProgrammaticPortsSpec extends ChiselFlatSpec { +class ProgrammaticPortsSpec extends ChiselFlatSpec with Utils { private def doTest(testMod: => NamedModuleTester): Unit = { var module: NamedModuleTester = null - elaborate { module = testMod; module } + ChiselStage.elaborate { module = testMod; module } assert(module.getNameFailures() == Nil) } @@ -63,12 +64,11 @@ class ProgrammaticPortsSpec extends ChiselFlatSpec { } "SuggestName collisions on ports" should "be illegal" in { - a [ChiselException] should be thrownBy { - elaborate(new MultiIOModule { + a [ChiselException] should be thrownBy extractCause[ChiselException] { + ChiselStage.elaborate(new MultiIOModule { val foo = IO(UInt(8.W)).suggestName("apple") val bar = IO(UInt(8.W)).suggestName("apple") }) } } } - diff --git a/src/test/scala/chiselTests/stage/ChiselMainSpec.scala b/src/test/scala/chiselTests/stage/ChiselMainSpec.scala index e2c3dccc8db..036e15b1712 100644 --- a/src/test/scala/chiselTests/stage/ChiselMainSpec.scala +++ b/src/test/scala/chiselTests/stage/ChiselMainSpec.scala @@ -69,7 +69,7 @@ class ChiselMainSpec extends AnyFeatureSpec with GivenWhenThen with Matchers wit } def runStageExpectFiles(p: ChiselMainTest): Unit = { - scenario(s"""User runs Chisel Stage with '${p.argsString}'""") { + Scenario(s"""User runs Chisel Stage with '${p.argsString}'""") { val f = new ChiselMainFixture val td = new TargetDirectoryFixture(p.testName) @@ -123,7 +123,7 @@ class ChiselMainSpec extends AnyFeatureSpec with GivenWhenThen with Matchers wit info("As a Chisel user") info("I screw up and compile some bad code") - feature("Stack trace trimming") { + Feature("Stack trace trimming") { Seq( ChiselMainTest(args = Array("-X", "low"), generator = Some(classOf[DifferentTypesModule]), @@ -135,7 +135,7 @@ class ChiselMainSpec extends AnyFeatureSpec with GivenWhenThen with Matchers wit result = 1) ).foreach(runStageExpectFiles) } - feature("Report properly trimmed stack traces") { + Feature("Report properly trimmed stack traces") { Seq( ChiselMainTest(args = Array("-X", "low"), generator = Some(classOf[FailingRequirementModule]), @@ -150,7 +150,7 @@ class ChiselMainSpec extends AnyFeatureSpec with GivenWhenThen with Matchers wit info("As an aspect writer") info("I write an aspect") - feature("Running aspects via the command line") { + Feature("Running aspects via the command line") { Seq( ChiselMainTest(args = Array( "-X", "high", "--with-aspect", "chiselTests.stage.TestClassAspect" ), generator = Some(classOf[SameTypesModule]), diff --git a/src/test/scala/chiselTests/stage/phases/ConvertSpec.scala b/src/test/scala/chiselTests/stage/phases/ConvertSpec.scala index d7fbada4d41..5383b08ab26 100644 --- a/src/test/scala/chiselTests/stage/phases/ConvertSpec.scala +++ b/src/test/scala/chiselTests/stage/phases/ConvertSpec.scala @@ -8,16 +8,18 @@ import chisel3.experimental.{ChiselAnnotation, RunFirrtlTransform} import chisel3.stage.ChiselGeneratorAnnotation import chisel3.stage.phases.{Convert, Elaborate} -import firrtl.{AnnotationSeq, CircuitForm, CircuitState, Transform, UnknownForm} +import firrtl.{AnnotationSeq, CircuitForm, CircuitState, DependencyAPIMigration, Transform, UnknownForm} import firrtl.annotations.{Annotation, NoTargetAnnotation} import firrtl.options.Phase import firrtl.stage.{FirrtlCircuitAnnotation, RunFirrtlTransformAnnotation} import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers -class ConvertSpecFirrtlTransform extends Transform { - def inputForm: CircuitForm = UnknownForm - def outputForm: CircuitForm = UnknownForm +class ConvertSpecFirrtlTransform extends Transform with DependencyAPIMigration { + override def prerequisites = Seq.empty + override def optionalPrerequisites = Seq.empty + override def optionalPrerequisiteOf = Seq.empty + override def invalidates(a: Transform) = false def execute(state: CircuitState): CircuitState = state } diff --git a/src/test/scala/chiselTests/util/random/LFSRSpec.scala b/src/test/scala/chiselTests/util/random/LFSRSpec.scala index ce0abf69357..003e0961e1b 100644 --- a/src/test/scala/chiselTests/util/random/LFSRSpec.scala +++ b/src/test/scala/chiselTests/util/random/LFSRSpec.scala @@ -3,11 +3,12 @@ package chiselTests.util.random import chisel3._ +import chisel3.stage.ChiselStage import chisel3.util.{Counter, Enum} import chisel3.util.random._ import chisel3.testers.BasicTester -import chiselTests.{ChiselFlatSpec, LFSRDistribution, LFSRMaxPeriod} +import chiselTests.{ChiselFlatSpec, LFSRDistribution, LFSRMaxPeriod, Utils} import math.pow @@ -50,7 +51,7 @@ class LFSRResetTester(gen: => LFSR, lockUpValue: BigInt) extends BasicTester { } -class LFSRSpec extends ChiselFlatSpec { +class LFSRSpec extends ChiselFlatSpec with Utils { def periodCheck(gen: (Int, Set[Int], LFSRReduce) => PRNG, reduction: LFSRReduce, range: Range): Unit = { it should s"have a maximal period over a range of widths (${range.head} to ${range.last}) using ${reduction.getClass}" in { @@ -67,13 +68,15 @@ class LFSRSpec extends ChiselFlatSpec { behavior of "LFSR" it should "throw an exception if initialized to a seed of zero for XOR configuration" in { - { the [IllegalArgumentException] thrownBy elaborate(new FooLFSR(XOR, Some(0))) } - .getMessage should include ("Seed cannot be zero") + { the [IllegalArgumentException] thrownBy extractCause[IllegalArgumentException] { + ChiselStage.elaborate(new FooLFSR(XOR, Some(0))) } + }.getMessage should include ("Seed cannot be zero") } it should "throw an exception if initialized to a seed of all ones for XNOR configuration" in { - { the [IllegalArgumentException] thrownBy elaborate(new FooLFSR(XNOR, Some(15))) } - .getMessage should include ("Seed cannot be all ones") + { the [IllegalArgumentException] thrownBy extractCause[IllegalArgumentException] { + ChiselStage.elaborate(new FooLFSR(XNOR, Some(15))) } + }.getMessage should include ("Seed cannot be all ones") } it should "reset correctly without a seed for XOR configuration" in { @@ -87,8 +90,9 @@ class LFSRSpec extends ChiselFlatSpec { behavior of "MaximalPeriodGaloisLFSR" it should "throw an exception if no LFSR taps are known" in { - { the [IllegalArgumentException] thrownBy elaborate(new MaxPeriodGaloisLFSR(787)) } - .getMessage should include ("No max period LFSR taps stored for requested width") + { the [IllegalArgumentException] thrownBy extractCause[IllegalArgumentException] { + ChiselStage.elaborate(new MaxPeriodGaloisLFSR(787)) } + }.getMessage should include ("No max period LFSR taps stored for requested width") } periodCheck((w: Int, t: Set[Int], r: LFSRReduce) => new GaloisLFSR(w, t, reduction=r), XOR, 2 to 16) diff --git a/src/test/scala/chiselTests/util/random/PRNGSpec.scala b/src/test/scala/chiselTests/util/random/PRNGSpec.scala index 341fb685ea2..bf10a1c0c7d 100644 --- a/src/test/scala/chiselTests/util/random/PRNGSpec.scala +++ b/src/test/scala/chiselTests/util/random/PRNGSpec.scala @@ -3,11 +3,12 @@ package chiselTests.util.random import chisel3._ +import chisel3.stage.ChiselStage import chisel3.testers.BasicTester import chisel3.util.Counter import chisel3.util.random.PRNG -import chiselTests.ChiselFlatSpec +import chiselTests.{ChiselFlatSpec, Utils} class CyclePRNG(width: Int, seed: Option[BigInt], step: Int, updateSeed: Boolean) extends PRNG(width, seed, step, updateSeed) { @@ -61,18 +62,20 @@ class PRNGUpdateSeedTest(updateSeed: Boolean, seed: BigInt, expected: BigInt) ex } -class PRNGSpec extends ChiselFlatSpec { +class PRNGSpec extends ChiselFlatSpec with Utils { behavior of "PRNG" it should "throw an exception if the step size is < 1" in { - { the [IllegalArgumentException] thrownBy elaborate(new CyclePRNG(0, Some(1), 1, true)) } - .getMessage should include ("Width must be greater than zero!") + { the [IllegalArgumentException] thrownBy extractCause[IllegalArgumentException] { + ChiselStage.elaborate(new CyclePRNG(0, Some(1), 1, true)) } + }.getMessage should include ("Width must be greater than zero!") } it should "throw an exception if the step size is <= 0" in { - { the [IllegalArgumentException] thrownBy elaborate(new CyclePRNG(1, Some(1), 0, true)) } - .getMessage should include ("Step size must be greater than one!") + { the [IllegalArgumentException] thrownBy extractCause[IllegalArgumentException] { + ChiselStage.elaborate(new CyclePRNG(1, Some(1), 0, true)) } + }.getMessage should include ("Step size must be greater than one!") } it should "handle non-unary steps" in { From cc2971feb15d4bc8cb4a8138b5a095ccbc92dcc3 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 24 Jun 2020 04:19:42 +0000 Subject: [PATCH 9/9] Add missing finishWrapper call in TesterDriver (#1496) (#1498) Signed-off-by: Schuyler Eldridge Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> (cherry picked from commit a1edc8f4cd525c8475e847ff7ddd9cb8fc1d3c51) Co-authored-by: Schuyler Eldridge --- src/main/scala/chisel3/testers/TesterDriver.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/chisel3/testers/TesterDriver.scala b/src/main/scala/chisel3/testers/TesterDriver.scala index 2724da166f2..03fb18996ed 100644 --- a/src/main/scala/chisel3/testers/TesterDriver.scala +++ b/src/main/scala/chisel3/testers/TesterDriver.scala @@ -50,7 +50,7 @@ object TesterDriver extends BackendCompilationUtilities { Dependency[Emitter], Dependency[Convert])) - val annotationsx = pm.transform(ChiselGeneratorAnnotation(t) +: annotations) + val annotationsx = pm.transform(ChiselGeneratorAnnotation(finishWrapper(t)) +: annotations) val target: String = annotationsx.collectFirst { case FirrtlCircuitAnnotation(cir) => cir.main }.get val path = annotationsx.collectFirst { case TargetDirAnnotation(dir) => dir }.map(new File(_)).get