summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/src/main/scala/chisel3/Module.scala10
-rw-r--r--core/src/main/scala/chisel3/RawModule.scala4
-rw-r--r--core/src/main/scala/chisel3/aop/Aspect.scala94
-rw-r--r--core/src/main/scala/chisel3/experimental/Trace.scala2
-rw-r--r--core/src/main/scala/chisel3/package.scala6
-rw-r--r--src/main/scala/chisel3/aop/AspectLibrary.scala94
-rw-r--r--src/main/scala/chisel3/aop/Select.scala1228
-rw-r--r--src/main/scala/chisel3/aop/injecting/InjectStatement.scala46
-rw-r--r--src/main/scala/chisel3/aop/injecting/InjectingAspect.scala192
-rw-r--r--src/main/scala/chisel3/aop/injecting/InjectingTransform.scala92
-rw-r--r--src/main/scala/chisel3/aop/inspecting/InspectingAspect.scala44
-rw-r--r--src/main/scala/chisel3/stage/ChiselPhase.scala2
-rw-r--r--src/main/scala/chisel3/stage/ChiselStage.scala10
-rw-r--r--src/main/scala/chisel3/stage/phases/AspectPhase.scala62
-rw-r--r--src/main/scala/chisel3/stage/phases/Emitter.scala2
-rw-r--r--src/main/scala/chisel3/stage/phases/MaybeAspectPhase.scala36
-rw-r--r--src/main/scala/chisel3/util/Decoupled.scala2
-rw-r--r--src/test/scala/chiselTests/AbstractModule.scala20
-rw-r--r--src/test/scala/chiselTests/AdderTree.scala35
-rw-r--r--src/test/scala/chiselTests/AnalogIntegrationSpec.scala150
-rw-r--r--src/test/scala/chiselTests/AnalogSpec.scala352
-rw-r--r--src/test/scala/chiselTests/AnnotatingDiamondSpec.scala166
-rw-r--r--src/test/scala/chiselTests/AnnotationNoDedup.scala79
-rw-r--r--src/test/scala/chiselTests/AsTypeOfTester.scala155
-rw-r--r--src/test/scala/chiselTests/Assert.scala205
-rw-r--r--src/test/scala/chiselTests/AsyncResetSpec.scala274
-rw-r--r--src/test/scala/chiselTests/AutoClonetypeSpec.scala444
-rw-r--r--src/test/scala/chiselTests/AutoNestedCloneSpec.scala136
-rw-r--r--src/test/scala/chiselTests/BetterNamingTests.scala101
-rw-r--r--src/test/scala/chiselTests/BitwiseOps.scala28
-rw-r--r--src/test/scala/chiselTests/BlackBox.scala225
-rw-r--r--src/test/scala/chiselTests/BlackBoxImpl.scala139
-rw-r--r--src/test/scala/chiselTests/BoringUtilsSpec.scala135
-rw-r--r--src/test/scala/chiselTests/BulkConnectSpec.scala139
-rw-r--r--src/test/scala/chiselTests/BundleElementsSpec.scala564
-rw-r--r--src/test/scala/chiselTests/BundleLiteralSpec.scala356
-rw-r--r--src/test/scala/chiselTests/BundleSpec.scala187
-rw-r--r--src/test/scala/chiselTests/BundleWire.scala69
-rw-r--r--src/test/scala/chiselTests/ChiselEnum.scala824
-rw-r--r--src/test/scala/chiselTests/ChiselSpec.scala368
-rw-r--r--src/test/scala/chiselTests/ChiselTestUtilitiesSpec.scala57
-rw-r--r--src/test/scala/chiselTests/Clock.scala36
-rw-r--r--src/test/scala/chiselTests/CloneModuleSpec.scala155
-rw-r--r--src/test/scala/chiselTests/CompatibilityInteroperabilitySpec.scala820
-rw-r--r--src/test/scala/chiselTests/CompatibilitySpec.scala639
-rw-r--r--src/test/scala/chiselTests/CompileOptionsTest.scala194
-rw-r--r--src/test/scala/chiselTests/ComplexAssign.scala52
-rw-r--r--src/test/scala/chiselTests/ConnectSpec.scala196
-rw-r--r--src/test/scala/chiselTests/Counter.scala90
-rw-r--r--src/test/scala/chiselTests/CustomBundle.scala24
-rw-r--r--src/test/scala/chiselTests/DataEqualitySpec.scala257
-rw-r--r--src/test/scala/chiselTests/DataPrint.scala116
-rw-r--r--src/test/scala/chiselTests/Decoder.scala59
-rw-r--r--src/test/scala/chiselTests/DecoupledSpec.scala111
-rw-r--r--src/test/scala/chiselTests/DedupSpec.scala84
-rw-r--r--src/test/scala/chiselTests/Direction.scala443
-rw-r--r--src/test/scala/chiselTests/DontTouchSpec.scala61
-rw-r--r--src/test/scala/chiselTests/EnableShiftRegister.scala53
-rw-r--r--src/test/scala/chiselTests/EnumSpec.scala19
-rw-r--r--src/test/scala/chiselTests/ExtModule.scala137
-rw-r--r--src/test/scala/chiselTests/ExtModuleImpl.scala159
-rw-r--r--src/test/scala/chiselTests/FixedPointSpec.scala171
-rw-r--r--src/test/scala/chiselTests/GCD.scala59
-rw-r--r--src/test/scala/chiselTests/Harness.scala85
-rw-r--r--src/test/scala/chiselTests/IOCompatibility.scala59
-rw-r--r--src/test/scala/chiselTests/IllegalRefSpec.scala74
-rw-r--r--src/test/scala/chiselTests/ImplicitConversionsSpec.scala48
-rw-r--r--src/test/scala/chiselTests/InlineSpec.scala96
-rw-r--r--src/test/scala/chiselTests/InstanceNameSpec.scala62
-rw-r--r--src/test/scala/chiselTests/IntegerMathSpec.scala32
-rw-r--r--src/test/scala/chiselTests/IntervalRangeSpec.scala237
-rw-r--r--src/test/scala/chiselTests/IntervalSpec.scala962
-rw-r--r--src/test/scala/chiselTests/InvalidateAPISpec.scala239
-rw-r--r--src/test/scala/chiselTests/LiteralExtractorSpec.scala158
-rw-r--r--src/test/scala/chiselTests/LiteralToTargetSpec.scala30
-rw-r--r--src/test/scala/chiselTests/LoadMemoryFromFileSpec.scala270
-rw-r--r--src/test/scala/chiselTests/Math.scala52
-rw-r--r--src/test/scala/chiselTests/Mem.scala241
-rw-r--r--src/test/scala/chiselTests/MemorySearch.scala58
-rw-r--r--src/test/scala/chiselTests/MigrateCompileOptionsSpec.scala133
-rw-r--r--src/test/scala/chiselTests/MixedVecSpec.scala299
-rw-r--r--src/test/scala/chiselTests/Module.scala286
-rw-r--r--src/test/scala/chiselTests/ModuleExplicitResetSpec.scala24
-rw-r--r--src/test/scala/chiselTests/MulLookup.scala38
-rw-r--r--src/test/scala/chiselTests/MultiAssign.scala82
-rw-r--r--src/test/scala/chiselTests/MultiClockSpec.scala290
-rw-r--r--src/test/scala/chiselTests/MultiIOModule.scala56
-rw-r--r--src/test/scala/chiselTests/MuxSpec.scala72
-rw-r--r--src/test/scala/chiselTests/NamingAnnotationTest.scala267
-rw-r--r--src/test/scala/chiselTests/NewAnnotationsSpec.scala72
-rw-r--r--src/test/scala/chiselTests/OneHotMuxSpec.scala318
-rw-r--r--src/test/scala/chiselTests/OptionBundle.scala62
-rw-r--r--src/test/scala/chiselTests/Padding.scala43
-rw-r--r--src/test/scala/chiselTests/ParameterizedModule.scala40
-rw-r--r--src/test/scala/chiselTests/PopCount.scala25
-rw-r--r--src/test/scala/chiselTests/PrintableSpec.scala393
-rw-r--r--src/test/scala/chiselTests/Printf.scala83
-rw-r--r--src/test/scala/chiselTests/QueueFlushSpec.scala294
-rw-r--r--src/test/scala/chiselTests/QueueSpec.scala294
-rw-r--r--src/test/scala/chiselTests/RangeSpec.scala12
-rw-r--r--src/test/scala/chiselTests/RawModuleSpec.scala90
-rw-r--r--src/test/scala/chiselTests/RebindingSpec.scala32
-rw-r--r--src/test/scala/chiselTests/RecordSpec.scala416
-rw-r--r--src/test/scala/chiselTests/ReduceTreeSpec.scala106
-rw-r--r--src/test/scala/chiselTests/Reg.scala91
-rw-r--r--src/test/scala/chiselTests/ResetSpec.scala115
-rw-r--r--src/test/scala/chiselTests/Risc.scala123
-rw-r--r--src/test/scala/chiselTests/SIntOps.scala151
-rw-r--r--src/test/scala/chiselTests/ScalaIntervalSimulatorTest.scala97
-rw-r--r--src/test/scala/chiselTests/Stack.scala77
-rw-r--r--src/test/scala/chiselTests/Stop.scala29
-rw-r--r--src/test/scala/chiselTests/SwitchSpec.scala53
-rw-r--r--src/test/scala/chiselTests/Tbl.scala62
-rw-r--r--src/test/scala/chiselTests/TesterDriverSpec.scala44
-rw-r--r--src/test/scala/chiselTests/ToTargetSpec.scala69
-rw-r--r--src/test/scala/chiselTests/TransitNameSpec.scala53
-rw-r--r--src/test/scala/chiselTests/UIntOps.scala290
-rw-r--r--src/test/scala/chiselTests/Util.scala69
-rw-r--r--src/test/scala/chiselTests/Vec.scala542
-rw-r--r--src/test/scala/chiselTests/VecLiteralSpec.scala529
-rw-r--r--src/test/scala/chiselTests/VecToTargetSpec.scala86
-rw-r--r--src/test/scala/chiselTests/VectorPacketIO.scala71
-rw-r--r--src/test/scala/chiselTests/VerificationSpec.scala156
-rw-r--r--src/test/scala/chiselTests/WarningSpec.scala40
-rw-r--r--src/test/scala/chiselTests/When.scala168
-rw-r--r--src/test/scala/chiselTests/WidthSpec.scala250
-rw-r--r--src/test/scala/chiselTests/WireSpec.scala36
-rw-r--r--src/test/scala/chiselTests/aop/InjectionSpec.scala180
-rw-r--r--src/test/scala/chiselTests/aop/SelectSpec.scala230
-rw-r--r--src/test/scala/chiselTests/experimental/DataMirrorSpec.scala91
-rw-r--r--src/test/scala/chiselTests/experimental/DataView.scala557
-rw-r--r--src/test/scala/chiselTests/experimental/DataViewIntegrationSpec.scala57
-rw-r--r--src/test/scala/chiselTests/experimental/DataViewTargetSpec.scala176
-rw-r--r--src/test/scala/chiselTests/experimental/FlatIOSpec.scala68
-rw-r--r--src/test/scala/chiselTests/experimental/ForceNames.scala128
-rw-r--r--src/test/scala/chiselTests/experimental/GroupSpec.scala115
-rw-r--r--src/test/scala/chiselTests/experimental/ModuleDataProductSpec.scala91
-rw-r--r--src/test/scala/chiselTests/experimental/ProgrammaticPortsSpec.scala73
-rw-r--r--src/test/scala/chiselTests/experimental/TraceSpec.scala328
-rw-r--r--src/test/scala/chiselTests/experimental/Tuple.scala163
-rw-r--r--src/test/scala/chiselTests/experimental/hierarchy/Annotations.scala32
-rw-r--r--src/test/scala/chiselTests/experimental/hierarchy/DefinitionSpec.scala599
-rw-r--r--src/test/scala/chiselTests/experimental/hierarchy/Examples.scala340
-rw-r--r--src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala1146
-rw-r--r--src/test/scala/chiselTests/experimental/hierarchy/SeparateElaborationSpec.scala495
-rw-r--r--src/test/scala/chiselTests/experimental/hierarchy/Utils.scala21
-rw-r--r--src/test/scala/chiselTests/naming/NamePluginSpec.scala362
-rw-r--r--src/test/scala/chiselTests/naming/PrefixSpec.scala550
-rw-r--r--src/test/scala/chiselTests/naming/ReflectiveNamingSpec.scala161
-rw-r--r--src/test/scala/chiselTests/stage/ChiselAnnotationsSpec.scala67
-rw-r--r--src/test/scala/chiselTests/stage/ChiselMainSpec.scala325
-rw-r--r--src/test/scala/chiselTests/stage/ChiselOptionsViewSpec.scala41
-rw-r--r--src/test/scala/chiselTests/stage/ChiselStageSpec.scala293
-rw-r--r--src/test/scala/chiselTests/stage/phases/AddImplicitOutputAnnotationFileSpec.scala41
-rw-r--r--src/test/scala/chiselTests/stage/phases/AddImplicitOutputFileSpec.scala45
-rw-r--r--src/test/scala/chiselTests/stage/phases/AddSerializationAnnotationsSpec.scala55
-rw-r--r--src/test/scala/chiselTests/stage/phases/ChecksSpec.scala43
-rw-r--r--src/test/scala/chiselTests/stage/phases/ConvertSpec.scala65
-rw-r--r--src/test/scala/chiselTests/stage/phases/ElaborateSpec.scala44
-rw-r--r--src/test/scala/chiselTests/stage/phases/EmitterSpec.scala59
-rw-r--r--src/test/scala/chiselTests/util/BitPatSpec.scala51
-rw-r--r--src/test/scala/chiselTests/util/BitSetSpec.scala145
-rw-r--r--src/test/scala/chiselTests/util/CatSpec.scala63
-rw-r--r--src/test/scala/chiselTests/util/PriorityMuxSpec.scala60
-rw-r--r--src/test/scala/chiselTests/util/experimental/PlaSpec.scala111
-rw-r--r--src/test/scala/chiselTests/util/experimental/TruthTableSpec.scala126
-rw-r--r--src/test/scala/chiselTests/util/random/LFSRSpec.scala182
-rw-r--r--src/test/scala/chiselTests/util/random/PRNGSpec.scala97
-rw-r--r--src/test/scala/cookbook/Bundle2UInt.scala31
-rw-r--r--src/test/scala/cookbook/CookbookSpec.scala22
-rw-r--r--src/test/scala/cookbook/FSM.scala66
-rw-r--r--src/test/scala/cookbook/RegOfVec.scala33
-rw-r--r--src/test/scala/cookbook/UInt2Bundle.scala30
-rw-r--r--src/test/scala/cookbook/UInt2VecOfBool.scala29
-rw-r--r--src/test/scala/cookbook/VecOfBool2UInt.scala28
-rw-r--r--src/test/scala/examples/ImplicitStateVendingMachine.scala31
-rw-r--r--src/test/scala/examples/SimpleVendingMachine.scala98
-rw-r--r--src/test/scala/examples/VendingMachineGenerator.scala130
-rw-r--r--src/test/scala/examples/VendingMachineUtils.scala39
179 files changed, 983 insertions, 28230 deletions
diff --git a/core/src/main/scala/chisel3/Module.scala b/core/src/main/scala/chisel3/Module.scala
index a2d5cec6..63bf9129 100644
--- a/core/src/main/scala/chisel3/Module.scala
+++ b/core/src/main/scala/chisel3/Module.scala
@@ -147,7 +147,7 @@ object Module extends SourceInfoDoc {
*
* @note Module instantiations must be wrapped in a Module() call.
*/
-abstract class Module(implicit moduleCompileOptions: CompileOptions) extends RawModule {
+abstract class Module[T](implicit moduleCompileOptions: CompileOptions) extends RawModule {
// Implicit clock and reset pins
final val clock: Clock = IO(Input(Clock())).suggestName("clock")
final val reset: Reset = IO(Input(mkReset)).suggestName("reset")
@@ -394,10 +394,10 @@ package internal {
// FIXME This almost certainly doesn't work since clonePorts is not a real thing...
pushCommand(DefInvalid(sourceInfo, clonePorts.ref))
}
- if (proto.isInstanceOf[Module]) {
- clonePorts("clock") := Module.clock
- clonePorts("reset") := Module.reset
- }
+ // if (proto.isInstanceOf[Module]) {
+ // clonePorts("clock") := Module.clock
+ // clonePorts("reset") := Module.reset
+ // }
clonePorts
}
}
diff --git a/core/src/main/scala/chisel3/RawModule.scala b/core/src/main/scala/chisel3/RawModule.scala
index 9668313a..717fd33c 100644
--- a/core/src/main/scala/chisel3/RawModule.scala
+++ b/core/src/main/scala/chisel3/RawModule.scala
@@ -173,11 +173,11 @@ abstract class RawModule(implicit moduleCompileOptions: CompileOptions) extends
}
}
-trait RequireAsyncReset extends Module {
+trait RequireAsyncReset extends Module[Any] {
override private[chisel3] def mkReset: AsyncReset = AsyncReset()
}
-trait RequireSyncReset extends Module {
+trait RequireSyncReset extends Module[Any] {
override private[chisel3] def mkReset: Bool = Bool()
}
diff --git a/core/src/main/scala/chisel3/aop/Aspect.scala b/core/src/main/scala/chisel3/aop/Aspect.scala
index dd014357..d5499946 100644
--- a/core/src/main/scala/chisel3/aop/Aspect.scala
+++ b/core/src/main/scala/chisel3/aop/Aspect.scala
@@ -1,47 +1,47 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chisel3.aop
-
-import chisel3.RawModule
-import firrtl.annotations.{Annotation, NoTargetAnnotation}
-import firrtl.options.Unserializable
-import firrtl.AnnotationSeq
-
-/** Represents an aspect of a Chisel module, by specifying
- * what behavior should be done to instance, via the FIRRTL Annotation Mechanism
- * @tparam T Type of top-level module
- */
-abstract class Aspect[T <: RawModule] extends Annotation with Unserializable with NoTargetAnnotation {
-
- /** variable to save [[AnnotationSeq]] from [[chisel3.stage.phases.AspectPhase]]
- * to be used at [[chisel3.aop.injecting.InjectorAspect]], exposes annotations to [[chisel3.internal.DynamicContext]]
- */
- private[aop] var annotationsInAspect: AnnotationSeq = Seq()
-
- /** Convert this Aspect to a seq of FIRRTL annotation
- * @param top
- * @return
- */
- def toAnnotation(top: T): AnnotationSeq
-
- /** Called by [[chisel3.stage.phases.AspectPhase]] to resolve this Aspect into annotations
- * @param top
- * @return
- */
- private[chisel3] def resolveAspect(top: RawModule, remainingAnnotations: AnnotationSeq): AnnotationSeq = {
- annotationsInAspect = remainingAnnotations
- toAnnotation(top.asInstanceOf[T])
- }
-}
-
-/** Holds utility functions for Aspect stuff */
-object Aspect {
-
- /** Converts elaborated Chisel components to FIRRTL modules
- * @param chiselIR
- * @return
- */
- def getFirrtl(chiselIR: chisel3.internal.firrtl.Circuit): firrtl.ir.Circuit = {
- chisel3.internal.firrtl.Converter.convert(chiselIR)
- }
-}
+// // SPDX-License-Identifier: Apache-2.0
+
+// package chisel3.aop
+
+// import chisel3.RawModule
+// import firrtl.annotations.{Annotation, NoTargetAnnotation}
+// import firrtl.options.Unserializable
+// import firrtl.AnnotationSeq
+
+// /** Represents an aspect of a Chisel module, by specifying
+// * what behavior should be done to instance, via the FIRRTL Annotation Mechanism
+// * @tparam T Type of top-level module
+// */
+// abstract class Aspect[T <: RawModule] extends Annotation with Unserializable with NoTargetAnnotation {
+
+// /** variable to save [[AnnotationSeq]] from [[chisel3.stage.phases.AspectPhase]]
+// * to be used at [[chisel3.aop.injecting.InjectorAspect]], exposes annotations to [[chisel3.internal.DynamicContext]]
+// */
+// private[aop] var annotationsInAspect: AnnotationSeq = Seq()
+
+// /** Convert this Aspect to a seq of FIRRTL annotation
+// * @param top
+// * @return
+// */
+// def toAnnotation(top: T): AnnotationSeq
+
+// /** Called by [[chisel3.stage.phases.AspectPhase]] to resolve this Aspect into annotations
+// * @param top
+// * @return
+// */
+// private[chisel3] def resolveAspect(top: RawModule, remainingAnnotations: AnnotationSeq): AnnotationSeq = {
+// annotationsInAspect = remainingAnnotations
+// toAnnotation(top.asInstanceOf[T])
+// }
+// }
+
+// /** Holds utility functions for Aspect stuff */
+// object Aspect {
+
+// /** Converts elaborated Chisel components to FIRRTL modules
+// * @param chiselIR
+// * @return
+// */
+// def getFirrtl(chiselIR: chisel3.internal.firrtl.Circuit): firrtl.ir.Circuit = {
+// chisel3.internal.firrtl.Converter.convert(chiselIR)
+// }
+// }
diff --git a/core/src/main/scala/chisel3/experimental/Trace.scala b/core/src/main/scala/chisel3/experimental/Trace.scala
index eb2ed46a..a31cef10 100644
--- a/core/src/main/scala/chisel3/experimental/Trace.scala
+++ b/core/src/main/scala/chisel3/experimental/Trace.scala
@@ -23,7 +23,7 @@ object Trace {
/** Trace a Instance name. */
@deprecated("switch to traceNameV2 (until Chisel 3.6)", "3.5.5")
- def traceName(x: Module): Unit = traceName(x: RawModule)
+ def traceName(x: Module[Any]): Unit = traceName(x: RawModule)
/** Trace a Instance name. */
@deprecated("switch to traceNameV2 (until Chisel 3.6)", "3.5.5")
diff --git a/core/src/main/scala/chisel3/package.scala b/core/src/main/scala/chisel3/package.scala
index afffad1c..bd279914 100644
--- a/core/src/main/scala/chisel3/package.scala
+++ b/core/src/main/scala/chisel3/package.scala
@@ -209,8 +209,8 @@ package object chisel3 {
type InstanceId = internal.InstanceId
- @deprecated("MultiIOModule is now just Module", "Chisel 3.5")
- type MultiIOModule = chisel3.Module
+ // @deprecated("MultiIOModule is now just Module", "Chisel 3.5")
+ // type MultiIOModule = chisel3.Module[Any]
/** Implicit for custom Printable string interpolator */
implicit class PrintableHelper(val sc: StringContext) extends AnyVal {
@@ -367,7 +367,7 @@ package object chisel3 {
"duplicated with DataMirror.fullModulePorts, this returns an internal API, will be removed in Chisel 3.6",
"Chisel 3.5"
)
- def getModulePorts(m: Module): Seq[Port] = m.getPorts
+ def getModulePorts(m: Module[Any]): Seq[Port] = m.getPorts
class BindingException(message: String) extends ChiselException(message)
diff --git a/src/main/scala/chisel3/aop/AspectLibrary.scala b/src/main/scala/chisel3/aop/AspectLibrary.scala
index 04ac2384..fb6a2dbc 100644
--- a/src/main/scala/chisel3/aop/AspectLibrary.scala
+++ b/src/main/scala/chisel3/aop/AspectLibrary.scala
@@ -1,53 +1,53 @@
-// SPDX-License-Identifier: Apache-2.0
+// // SPDX-License-Identifier: Apache-2.0
-package chisel3.aop
+// package chisel3.aop
-import chisel3.RawModule
-import firrtl.options.{OptionsException, RegisteredLibrary, ShellOption}
+// import chisel3.RawModule
+// import firrtl.options.{OptionsException, RegisteredLibrary, ShellOption}
-/** Enables adding aspects to a design from the commandline, e.g.
- * sbt> runMain chisel3.stage.ChiselMain --module <module> --with-aspect <aspect>
- */
-final class AspectLibrary() extends RegisteredLibrary {
- val name = "AspectLibrary"
+// /** Enables adding aspects to a design from the commandline, e.g.
+// * sbt> runMain chisel3.stage.ChiselMain --module <module> --with-aspect <aspect>
+// */
+// final class AspectLibrary() extends RegisteredLibrary {
+// val name = "AspectLibrary"
- import scala.reflect.runtime.universe._
+// import scala.reflect.runtime.universe._
- private def apply(aspectName: String): Aspect[RawModule] = {
- try {
- // If a regular class, instantiate, otherwise try as a singleton object
- try {
- val x = Class.forName(aspectName).asInstanceOf[Class[_ <: Aspect[RawModule]]]
- x.newInstance()
- } catch {
- case e: InstantiationException =>
- val rm = runtimeMirror(getClass.getClassLoader)
- val x = rm.staticModule(aspectName)
- try {
- rm.reflectModule(x).instance.asInstanceOf[Aspect[RawModule]]
- } catch {
- case _: Exception => throw e
- }
- }
- } catch {
- case e: ClassNotFoundException =>
- throw new OptionsException(s"Unable to locate aspect '$aspectName'! (Did you misspell it?)", e)
- case e: InstantiationException =>
- throw new OptionsException(
- s"Unable to create instance of aspect '$aspectName'! (Does this class take parameters?)",
- e
- )
- }
- }
+// private def apply(aspectName: String): Aspect[RawModule] = {
+// try {
+// // If a regular class, instantiate, otherwise try as a singleton object
+// try {
+// val x = Class.forName(aspectName).asInstanceOf[Class[_ <: Aspect[RawModule]]]
+// x.newInstance()
+// } catch {
+// case e: InstantiationException =>
+// val rm = runtimeMirror(getClass.getClassLoader)
+// val x = rm.staticModule(aspectName)
+// try {
+// rm.reflectModule(x).instance.asInstanceOf[Aspect[RawModule]]
+// } catch {
+// case _: Exception => throw e
+// }
+// }
+// } catch {
+// case e: ClassNotFoundException =>
+// throw new OptionsException(s"Unable to locate aspect '$aspectName'! (Did you misspell it?)", e)
+// case e: InstantiationException =>
+// throw new OptionsException(
+// s"Unable to create instance of aspect '$aspectName'! (Does this class take parameters?)",
+// e
+// )
+// }
+// }
- val options = Seq(
- new ShellOption[String](
- longOption = "with-aspect",
- toAnnotationSeq = {
- case aspectName: String => Seq(apply(aspectName))
- },
- helpText = "The name/class of an aspect to compile with (must be a class/object without arguments!)",
- helpValueName = Some("<package>.<aspect>")
- )
- )
-}
+// val options = Seq(
+// new ShellOption[String](
+// longOption = "with-aspect",
+// toAnnotationSeq = {
+// case aspectName: String => Seq(apply(aspectName))
+// },
+// helpText = "The name/class of an aspect to compile with (must be a class/object without arguments!)",
+// helpValueName = Some("<package>.<aspect>")
+// )
+// )
+// }
diff --git a/src/main/scala/chisel3/aop/Select.scala b/src/main/scala/chisel3/aop/Select.scala
index 738d6f31..19317f2a 100644
--- a/src/main/scala/chisel3/aop/Select.scala
+++ b/src/main/scala/chisel3/aop/Select.scala
@@ -1,614 +1,614 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chisel3.aop
-
-import chisel3._
-import chisel3.internal.{HasId}
-import chisel3.experimental.BaseModule
-import chisel3.experimental.FixedPoint
-import chisel3.internal.firrtl.{Definition => DefinitionIR, _}
-import chisel3.experimental.hierarchy._
-import chisel3.internal.PseudoModule
-import chisel3.internal.BaseModule.ModuleClone
-import firrtl.annotations.ReferenceTarget
-import scala.reflect.runtime.universe.TypeTag
-
-import scala.collection.mutable
-import chisel3.internal.naming.chiselName
-
-/** Use to select Chisel components in a module, after that module has been constructed
- * Useful for adding additional Chisel annotations or for use within an [[Aspect]]
- */
-object Select {
-
- /** Return just leaf components of expanded node
- *
- * @param d Component to find leafs if aggregate typed. Intermediate fields/indicies are not included
- */
- def getLeafs(d: Data): Seq[Data] = d match {
- case r: Record => r.elementsIterator.flatMap(getLeafs).toSeq
- case v: Vec[_] => v.getElements.flatMap(getLeafs)
- case other => Seq(other)
- }
-
- /** Return all expanded components, including intermediate aggregate nodes
- *
- * @param d Component to find leafs if aggregate typed. Intermediate fields/indicies ARE included
- */
- def getIntermediateAndLeafs(d: Data): Seq[Data] = d match {
- case r: Record => r +: r.elementsIterator.flatMap(getIntermediateAndLeafs).toSeq
- case v: Vec[_] => v +: v.getElements.flatMap(getIntermediateAndLeafs)
- case other => Seq(other)
- }
-
- /** Selects all instances/modules directly instantiated within given definition
- *
- * @param parent
- */
- def instancesIn(parent: Hierarchy[BaseModule]): Seq[Instance[BaseModule]] = {
- check(parent)
- implicit val mg = new chisel3.internal.MacroGenerated {}
- parent.proto._component.get match {
- case d: DefModule =>
- d.commands.collect {
- case d: DefInstance =>
- d.id match {
- case p: chisel3.internal.BaseModule.IsClone[_] =>
- parent._lookup { x => new Instance(Clone(p)).asInstanceOf[Instance[BaseModule]] }
- case other: BaseModule =>
- parent._lookup { x => other }
- }
- }
- case other => Nil
- }
- }
-
- /** Selects all Instances of instances/modules directly instantiated within given module, of provided type
- *
- * @note IMPORTANT: this function requires summoning a TypeTag[T], which will fail if T is an inner class.
- * @note IMPORTANT: this function ignores type parameters. E.g. instancesOf[List[Int]] would return List[String].
- *
- * @param parent hierarchy which instantiates the returned Definitions
- */
- def instancesOf[T <: BaseModule: TypeTag](parent: Hierarchy[BaseModule]): Seq[Instance[T]] = {
- check(parent)
- implicit val mg = new chisel3.internal.MacroGenerated {}
- parent.proto._component.get match {
- case d: DefModule =>
- d.commands.flatMap {
- case d: DefInstance =>
- d.id match {
- case p: chisel3.internal.BaseModule.IsClone[_] =>
- val i = parent._lookup { x => new Instance(Clone(p)).asInstanceOf[Instance[BaseModule]] }
- if (i.isA[T]) Some(i.asInstanceOf[Instance[T]]) else None
- case other: BaseModule =>
- val i = parent._lookup { x => other }
- if (i.isA[T]) Some(i.asInstanceOf[Instance[T]]) else None
- }
- case other => None
- }
- case other => Nil
- }
- }
-
- /** Selects all Instances directly and indirectly instantiated within given root hierarchy, of provided type
- *
- * @note IMPORTANT: this function requires summoning a TypeTag[T], which will fail if T is an inner class.
- * @note IMPORTANT: this function ignores type parameters. E.g. allInstancesOf[List[Int]] would return List[String].
- *
- * @param root top of the hierarchy to search for instances/modules of given type
- */
- def allInstancesOf[T <: BaseModule: TypeTag](root: Hierarchy[BaseModule]): Seq[Instance[T]] = {
- val soFar = if (root.isA[T]) Seq(root.toInstance.asInstanceOf[Instance[T]]) else Nil
- val allLocalInstances = instancesIn(root)
- soFar ++ (allLocalInstances.flatMap(allInstancesOf[T]))
- }
-
- /** Selects the Definitions of all instances/modules directly instantiated within given module
- *
- * @param parent
- */
- def definitionsIn(parent: Hierarchy[BaseModule]): Seq[Definition[BaseModule]] = {
- type DefType = Definition[BaseModule]
- implicit val mg = new chisel3.internal.MacroGenerated {}
- check(parent)
- val defs = parent.proto._component.get match {
- case d: DefModule =>
- d.commands.collect {
- case i: DefInstance =>
- i.id match {
- case p: chisel3.internal.BaseModule.IsClone[_] =>
- parent._lookup { x => new Definition(Proto(p.getProto)).asInstanceOf[Definition[BaseModule]] }
- case other: BaseModule =>
- parent._lookup { x => other.toDefinition }
- }
- }
- case other => Nil
- }
- val (_, defList) = defs.foldLeft((Set.empty[DefType], List.empty[DefType])) {
- case ((set, list), definition: Definition[BaseModule]) =>
- if (set.contains(definition)) (set, list) else (set + definition, definition +: list)
- }
- defList.reverse
- }
-
- /** Selects all Definitions of instances/modules directly instantiated within given module, of provided type
- *
- * @note IMPORTANT: this function requires summoning a TypeTag[T], which will fail if T is an inner class.
- * @note IMPORTANT: this function ignores type parameters. E.g. definitionsOf[List[Int]] would return List[String].
- *
- * @param parent hierarchy which instantiates the returned Definitions
- */
- def definitionsOf[T <: BaseModule: TypeTag](parent: Hierarchy[BaseModule]): Seq[Definition[T]] = {
- check(parent)
- implicit val mg = new chisel3.internal.MacroGenerated {}
- type DefType = Definition[T]
- val defs = parent.proto._component.get match {
- case d: DefModule =>
- d.commands.flatMap {
- case d: DefInstance =>
- d.id match {
- case p: chisel3.internal.BaseModule.IsClone[_] =>
- val d = parent._lookup { x => new Definition(Clone(p)).asInstanceOf[Definition[BaseModule]] }
- if (d.isA[T]) Some(d.asInstanceOf[Definition[T]]) else None
- case other: BaseModule =>
- val d = parent._lookup { x => other.toDefinition }
- if (d.isA[T]) Some(d.asInstanceOf[Definition[T]]) else None
- }
- case other => None
- }
- }
- val (_, defList) = defs.foldLeft((Set.empty[DefType], List.empty[DefType])) {
- case ((set, list), definition: Definition[T]) =>
- if (set.contains(definition)) (set, list) else (set + definition, definition +: list)
- }
- defList.reverse
- }
-
- /** Selects all Definition's directly and indirectly instantiated within given root hierarchy, of provided type
- *
- * @note IMPORTANT: this function requires summoning a TypeTag[T], which will fail if T is an inner class, i.e.
- * a class defined within another class.
- * @note IMPORTANT: this function ignores type parameters. E.g. allDefinitionsOf[List[Int]] would return List[String].
- *
- * @param root top of the hierarchy to search for definitions of given type
- */
- def allDefinitionsOf[T <: BaseModule: TypeTag](root: Hierarchy[BaseModule]): Seq[Definition[T]] = {
- type DefType = Definition[T]
- val allDefSet = mutable.HashSet[Definition[BaseModule]]()
- val defSet = mutable.HashSet[DefType]()
- val defList = mutable.ArrayBuffer[DefType]()
- def rec(hier: Definition[BaseModule]): Unit = {
- if (hier.isA[T] && !defSet.contains(hier.asInstanceOf[DefType])) {
- defSet += hier.asInstanceOf[DefType]
- defList += hier.asInstanceOf[DefType]
- }
- allDefSet += hier
- val allDefs = definitionsIn(hier)
- allDefs.collect {
- case d if !allDefSet.contains(d) => rec(d)
- }
- }
- rec(root.toDefinition)
- defList.toList
- }
-
- /** Collects all components selected by collector within module and all children modules it instantiates
- * directly or indirectly
- * Accepts a collector function, rather than a collector partial function (see [[collectDeep]])
- *
- * @note This API will not work with the new experimental hierarchy package. Instead, use allInstancesOf or allDefinitionsOf.
- *
- * @param module Module to collect components, as well as all children module it directly and indirectly instantiates
- * @param collector Collector function to pick, given a module, which components to collect
- * @param tag Required for generics to work, should ignore this
- * @tparam T Type of the component that will be collected
- */
- def getDeep[T](module: BaseModule)(collector: BaseModule => Seq[T]): Seq[T] = {
- check(module)
- val myItems = collector(module)
- val deepChildrenItems = instances(module).flatMap { i =>
- getDeep(i)(collector)
- }
- myItems ++ deepChildrenItems
- }
-
- /** Collects all components selected by collector within module and all children modules it instantiates
- * directly or indirectly
- * Accepts a collector partial function, rather than a collector function (see [[getDeep]])
- *
- * @note This API will not work with the new experimental hierarchy package. Instead, use allInstancesOf or allDefinitionsOf.
- *
- * @param module Module to collect components, as well as all children module it directly and indirectly instantiates
- * @param collector Collector partial function to pick, given a module, which components to collect
- * @param tag Required for generics to work, should ignore this
- * @tparam T Type of the component that will be collected
- */
- def collectDeep[T](module: BaseModule)(collector: PartialFunction[BaseModule, T]): Iterable[T] = {
- check(module)
- val myItems = collector.lift(module)
- val deepChildrenItems = instances(module).flatMap { i =>
- collectDeep(i)(collector)
- }
- myItems ++ deepChildrenItems
- }
-
- /** Selects all modules directly instantiated within given module
- *
- * @note This API will not work with the new experimental hierarchy package. Instead, use instancesIn or definitionsIn.
- *
- * @param module
- */
- def instances(module: BaseModule): Seq[BaseModule] = {
- check(module)
- module._component.get match {
- case d: DefModule =>
- d.commands.flatMap {
- case i: DefInstance =>
- i.id match {
- case m: ModuleClone[_] if !m._madeFromDefinition => None
- case _: PseudoModule =>
- throw new Exception(
- "instances, collectDeep, and getDeep are currently incompatible with Definition/Instance!"
- )
- case other => Some(other)
- }
- case _ => None
- }
- case other => Nil
- }
- }
-
- /** Selects all registers directly instantiated within given module
- * @param module
- */
- def registers(module: BaseModule): Seq[Data] = {
- check(module)
- module._component.get.asInstanceOf[DefModule].commands.collect {
- case r: DefReg => r.id
- case r: DefRegInit => r.id
- }
- }
-
- /** Selects all ios on a given module
- * @param module
- */
- def ios(module: BaseModule): Seq[Data] = {
- check(module)
- module._component.get.asInstanceOf[DefModule].ports.map(_.id)
- }
-
- /** Selects all ios directly on a given Instance or Definition of a module
- * @param parent the Definition or Instance to get the IOs of
- */
- def ios[T <: BaseModule](parent: Hierarchy[T]): Seq[Data] = {
- check(parent)
- implicit val mg = new chisel3.internal.MacroGenerated {}
- parent._lookup { x => ios(parent.proto) }
- }
-
- /** Selects all SyncReadMems directly contained within given module
- * @param module
- */
- def syncReadMems(module: BaseModule): Seq[SyncReadMem[_]] = {
- check(module)
- module._component.get.asInstanceOf[DefModule].commands.collect {
- case r: DefSeqMemory => r.id.asInstanceOf[SyncReadMem[_]]
- }
- }
-
- /** Selects all Mems directly contained within given module
- * @param module
- */
- def mems(module: BaseModule): Seq[Mem[_]] = {
- check(module)
- module._component.get.asInstanceOf[DefModule].commands.collect {
- case r: DefMemory => r.id.asInstanceOf[Mem[_]]
- }
- }
-
- /** Selects all arithmetic or logical operators directly instantiated within given module
- * @param module
- */
- def ops(module: BaseModule): Seq[(String, Data)] = {
- check(module)
- module._component.get.asInstanceOf[DefModule].commands.collect {
- case d: DefPrim[_] => (d.op.name, d.id)
- }
- }
-
- /** Selects a kind of arithmetic or logical operator directly instantiated within given module
- * The kind of operators are contained in [[chisel3.internal.firrtl.PrimOp]]
- * @param opKind the kind of operator, e.g. "mux", "add", or "bits"
- * @param module
- */
- def ops(opKind: String)(module: BaseModule): Seq[Data] = {
- check(module)
- module._component.get.asInstanceOf[DefModule].commands.collect {
- case d: DefPrim[_] if d.op.name == opKind => d.id
- }
- }
-
- /** Selects all wires in a module
- * @param module
- */
- def wires(module: BaseModule): Seq[Data] = {
- check(module)
- module._component.get.asInstanceOf[DefModule].commands.collect {
- case r: DefWire => r.id
- }
- }
-
- /** Selects all memory ports, including their direction and memory
- * @param module
- */
- def memPorts(module: BaseModule): Seq[(Data, MemPortDirection, MemBase[_])] = {
- check(module)
- module._component.get.asInstanceOf[DefModule].commands.collect {
- case r: DefMemPort[_] => (r.id, r.dir, r.source.id.asInstanceOf[MemBase[_ <: Data]])
- }
- }
-
- /** Selects all memory ports of a given direction, including their memory
- * @param dir The direction of memory ports to select
- * @param module
- */
- def memPorts(dir: MemPortDirection)(module: BaseModule): Seq[(Data, MemBase[_])] = {
- check(module)
- module._component.get.asInstanceOf[DefModule].commands.collect {
- case r: DefMemPort[_] if r.dir == dir => (r.id, r.source.id.asInstanceOf[MemBase[_ <: Data]])
- }
- }
-
- /** Selects all components who have been set to be invalid, even if they are later connected to
- * @param module
- */
- def invalids(module: BaseModule): Seq[Data] = {
- check(module)
- module._component.get.asInstanceOf[DefModule].commands.collect {
- case DefInvalid(_, arg) => getData(arg)
- }
- }
-
- /** Selects all components who are attached to a given signal, within a module
- * @param module
- */
- def attachedTo(module: BaseModule)(signal: Data): Set[Data] = {
- check(module)
- module._component.get
- .asInstanceOf[DefModule]
- .commands
- .collect {
- case Attach(_, seq) if seq.contains(signal) => seq
- }
- .flatMap { seq => seq.map(_.id.asInstanceOf[Data]) }
- .toSet
- }
-
- /** Selects all connections to a signal or its parent signal(s) (if the signal is an element of an aggregate signal)
- * The when predicates surrounding each connection are included in the returned values
- *
- * E.g. if signal = io.foo.bar, connectionsTo will return all connections to io, io.foo, and io.bar
- * @param module
- * @param signal
- */
- def connectionsTo(module: BaseModule)(signal: Data): Seq[PredicatedConnect] = {
- check(module)
- val sensitivitySignals = getIntermediateAndLeafs(signal).toSet
- val predicatedConnects = mutable.ArrayBuffer[PredicatedConnect]()
- val isPort = module._component.get
- .asInstanceOf[DefModule]
- .ports
- .flatMap { p => getIntermediateAndLeafs(p.id) }
- .contains(signal)
- var prePredicates: Seq[Predicate] = Nil
- var seenDef = isPort
- searchWhens(
- module,
- (cmd: Command, preds) => {
- cmd match {
- case cmd: DefinitionIR if cmd.id.isInstanceOf[Data] =>
- val x = getIntermediateAndLeafs(cmd.id.asInstanceOf[Data])
- if (x.contains(signal)) prePredicates = preds
- case Connect(_, loc @ Node(d: Data), exp) =>
- val effected = getEffected(loc).toSet
- if (sensitivitySignals.intersect(effected).nonEmpty) {
- val expData = getData(exp)
- prePredicates.reverse
- .zip(preds.reverse)
- .foreach(x => assert(x._1 == x._2, s"Prepredicates $x must match for signal $signal"))
- predicatedConnects += PredicatedConnect(preds.dropRight(prePredicates.size), d, expData, isBulk = false)
- }
- case BulkConnect(_, loc @ Node(d: Data), exp) =>
- val effected = getEffected(loc).toSet
- if (sensitivitySignals.intersect(effected).nonEmpty) {
- val expData = getData(exp)
- prePredicates.reverse
- .zip(preds.reverse)
- .foreach(x => assert(x._1 == x._2, s"Prepredicates $x must match for signal $signal"))
- predicatedConnects += PredicatedConnect(preds.dropRight(prePredicates.size), d, expData, isBulk = true)
- }
- case other =>
- }
- }
- )
- predicatedConnects.toSeq
- }
-
- /** Selects all stop statements, and includes the predicates surrounding the stop statement
- *
- * @param module
- */
- def stops(module: BaseModule): Seq[Stop] = {
- val stops = mutable.ArrayBuffer[Stop]()
- searchWhens(
- module,
- (cmd: Command, preds: Seq[Predicate]) => {
- cmd match {
- case chisel3.internal.firrtl.Stop(_, _, clock, ret) =>
- stops += Stop(preds, ret, getId(clock).asInstanceOf[Clock])
- case other =>
- }
- }
- )
- stops.toSeq
- }
-
- /** Selects all printf statements, and includes the predicates surrounding the printf statement
- *
- * @param module
- */
- def printfs(module: BaseModule): Seq[Printf] = {
- val printfs = mutable.ArrayBuffer[Printf]()
- searchWhens(
- module,
- (cmd: Command, preds: Seq[Predicate]) => {
- cmd match {
- case chisel3.internal.firrtl.Printf(id, _, clock, pable) =>
- printfs += Printf(id, preds, pable, getId(clock).asInstanceOf[Clock])
- case other =>
- }
- }
- )
- printfs.toSeq
- }
-
- // Checks that a module has finished its construction
- private def check(module: BaseModule): Unit = {
- require(module.isClosed, "Can't use Selector on modules that have not finished construction!")
- require(module._component.isDefined, "Can't use Selector on modules that don't have components!")
- }
- private def check(hierarchy: Hierarchy[BaseModule]): Unit = check(hierarchy.proto)
-
- // Given a loc, return all subcomponents of id that could be assigned to in connect
- private def getEffected(a: Arg): Seq[Data] = a match {
- case Node(id: Data) => getIntermediateAndLeafs(id)
- case Slot(imm, name) => Seq(imm.id.asInstanceOf[Record].elements(name))
- case Index(imm, value) => getEffected(imm)
- }
-
- // Given an arg, return the corresponding id. Don't use on a loc of a connect.
- private def getId(a: Arg): HasId = a match {
- case Node(id) => id
- case l: ULit => l.num.U(l.w)
- case l: SLit => l.num.S(l.w)
- case l: FPLit => FixedPoint(l.num, l.w, l.binaryPoint)
- case other =>
- sys.error(s"Something went horribly wrong! I was expecting ${other} to be a lit or a node!")
- }
-
- private def getData(a: Arg): Data = a match {
- case Node(data: Data) => data
- case other =>
- sys.error(s"Something went horribly wrong! I was expecting ${other} to be Data!")
- }
-
- // Given an id, either get its name or its value, if its a lit
- private def getName(i: HasId): String = try {
- i.toTarget match {
- case r: ReferenceTarget =>
- val str = r.serialize
- str.splitAt(str.indexOf('>'))._2.drop(1)
- }
- } catch {
- case e: ChiselException =>
- i.getOptionRef.get match {
- case l: LitArg => l.num.intValue.toString
- }
- }
-
- // Collects when predicates as it searches through a module, then applying processCommand to non-when related commands
- private def searchWhens(module: BaseModule, processCommand: (Command, Seq[Predicate]) => Unit) = {
- check(module)
- module._component.get.asInstanceOf[DefModule].commands.foldLeft((Seq.empty[Predicate], Option.empty[Predicate])) {
- (blah, cmd) =>
- (blah, cmd) match {
- case ((preds, o), cmd) =>
- cmd match {
- case WhenBegin(_, Node(pred: Bool)) => (When(pred) +: preds, None)
- case WhenBegin(_, l: LitArg) if l.num == BigInt(1) => (When(true.B) +: preds, None)
- case WhenBegin(_, l: LitArg) if l.num == BigInt(0) => (When(false.B) +: preds, None)
- case other: WhenBegin =>
- sys.error(s"Something went horribly wrong! I was expecting ${other.pred} to be a lit or a bool!")
- case _: WhenEnd => (preds.tail, Some(preds.head))
- case AltBegin(_) if o.isDefined => (o.get.not +: preds, o)
- case _: AltBegin =>
- sys.error(s"Something went horribly wrong! I was expecting ${o} to be nonEmpty!")
- case OtherwiseEnd(_, _) => (preds.tail, None)
- case other =>
- processCommand(cmd, preds)
- (preds, o)
- }
- }
- }
- }
-
- trait Serializeable {
- def serialize: String
- }
-
- /** Used to indicates a when's predicate (or its otherwise predicate)
- */
- trait Predicate extends Serializeable {
- val bool: Bool
- def not: Predicate
- }
-
- /** Used to represent [[chisel3.when]] predicate
- *
- * @param bool the when predicate
- */
- case class When(bool: Bool) extends Predicate {
- def not: WhenNot = WhenNot(bool)
- def serialize: String = s"${getName(bool)}"
- }
-
- /** Used to represent the `otherwise` predicate of a [[chisel3.when]]
- *
- * @param bool the when predicate corresponding to this otherwise predicate
- */
- case class WhenNot(bool: Bool) extends Predicate {
- def not: When = When(bool)
- def serialize: String = s"!${getName(bool)}"
- }
-
- /** Used to represent a connection or bulk connection
- *
- * Additionally contains the sequence of when predicates seen when the connection is declared
- *
- * @param preds
- * @param loc
- * @param exp
- * @param isBulk
- */
- case class PredicatedConnect(preds: Seq[Predicate], loc: Data, exp: Data, isBulk: Boolean) extends Serializeable {
- def serialize: String = {
- val moduleTarget = loc.toTarget.moduleTarget.serialize
- s"$moduleTarget: when(${preds.map(_.serialize).mkString(" & ")}): ${getName(loc)} ${if (isBulk) "<>" else ":="} ${getName(exp)}"
- }
- }
-
- /** Used to represent a [[chisel3.stop]]
- *
- * @param preds
- * @param ret
- * @param clock
- */
- case class Stop(preds: Seq[Predicate], ret: Int, clock: Clock) extends Serializeable {
- def serialize: String = {
- s"stop when(${preds.map(_.serialize).mkString(" & ")}) on ${getName(clock)}: $ret"
- }
- }
-
- /** Used to represent a [[chisel3.printf]]
- *
- * @param preds
- * @param pable
- * @param clock
- */
- case class Printf(id: printf.Printf, preds: Seq[Predicate], pable: Printable, clock: Clock) extends Serializeable {
- def serialize: String = {
- s"printf when(${preds.map(_.serialize).mkString(" & ")}) on ${getName(clock)}: $pable"
- }
- }
-}
+// // SPDX-License-Identifier: Apache-2.0
+
+// package chisel3.aop
+
+// import chisel3._
+// import chisel3.internal.{HasId}
+// import chisel3.experimental.BaseModule
+// import chisel3.experimental.FixedPoint
+// import chisel3.internal.firrtl.{Definition => DefinitionIR, _}
+// import chisel3.experimental.hierarchy._
+// import chisel3.internal.PseudoModule
+// import chisel3.internal.BaseModule.ModuleClone
+// import firrtl.annotations.ReferenceTarget
+// import scala.reflect.runtime.universe.TypeTag
+
+// import scala.collection.mutable
+// import chisel3.internal.naming.chiselName
+
+// /** Use to select Chisel components in a module, after that module has been constructed
+// * Useful for adding additional Chisel annotations or for use within an [[Aspect]]
+// */
+// object Select {
+
+// /** Return just leaf components of expanded node
+// *
+// * @param d Component to find leafs if aggregate typed. Intermediate fields/indicies are not included
+// */
+// def getLeafs(d: Data): Seq[Data] = d match {
+// case r: Record => r.elementsIterator.flatMap(getLeafs).toSeq
+// case v: Vec[_] => v.getElements.flatMap(getLeafs)
+// case other => Seq(other)
+// }
+
+// /** Return all expanded components, including intermediate aggregate nodes
+// *
+// * @param d Component to find leafs if aggregate typed. Intermediate fields/indicies ARE included
+// */
+// def getIntermediateAndLeafs(d: Data): Seq[Data] = d match {
+// case r: Record => r +: r.elementsIterator.flatMap(getIntermediateAndLeafs).toSeq
+// case v: Vec[_] => v +: v.getElements.flatMap(getIntermediateAndLeafs)
+// case other => Seq(other)
+// }
+
+// /** Selects all instances/modules directly instantiated within given definition
+// *
+// * @param parent
+// */
+// def instancesIn(parent: Hierarchy[BaseModule]): Seq[Instance[BaseModule]] = {
+// check(parent)
+// implicit val mg = new chisel3.internal.MacroGenerated {}
+// parent.proto._component.get match {
+// case d: DefModule =>
+// d.commands.collect {
+// case d: DefInstance =>
+// d.id match {
+// case p: chisel3.internal.BaseModule.IsClone[_] =>
+// parent._lookup { x => new Instance(Clone(p)).asInstanceOf[Instance[BaseModule]] }
+// case other: BaseModule =>
+// parent._lookup { x => other }
+// }
+// }
+// case other => Nil
+// }
+// }
+
+// /** Selects all Instances of instances/modules directly instantiated within given module, of provided type
+// *
+// * @note IMPORTANT: this function requires summoning a TypeTag[T], which will fail if T is an inner class.
+// * @note IMPORTANT: this function ignores type parameters. E.g. instancesOf[List[Int]] would return List[String].
+// *
+// * @param parent hierarchy which instantiates the returned Definitions
+// */
+// def instancesOf[T <: BaseModule: TypeTag](parent: Hierarchy[BaseModule]): Seq[Instance[T]] = {
+// check(parent)
+// implicit val mg = new chisel3.internal.MacroGenerated {}
+// parent.proto._component.get match {
+// case d: DefModule =>
+// d.commands.flatMap {
+// case d: DefInstance =>
+// d.id match {
+// case p: chisel3.internal.BaseModule.IsClone[_] =>
+// val i = parent._lookup { x => new Instance(Clone(p)).asInstanceOf[Instance[BaseModule]] }
+// if (i.isA[T]) Some(i.asInstanceOf[Instance[T]]) else None
+// case other: BaseModule =>
+// val i = parent._lookup { x => other }
+// if (i.isA[T]) Some(i.asInstanceOf[Instance[T]]) else None
+// }
+// case other => None
+// }
+// case other => Nil
+// }
+// }
+
+// /** Selects all Instances directly and indirectly instantiated within given root hierarchy, of provided type
+// *
+// * @note IMPORTANT: this function requires summoning a TypeTag[T], which will fail if T is an inner class.
+// * @note IMPORTANT: this function ignores type parameters. E.g. allInstancesOf[List[Int]] would return List[String].
+// *
+// * @param root top of the hierarchy to search for instances/modules of given type
+// */
+// def allInstancesOf[T <: BaseModule: TypeTag](root: Hierarchy[BaseModule]): Seq[Instance[T]] = {
+// val soFar = if (root.isA[T]) Seq(root.toInstance.asInstanceOf[Instance[T]]) else Nil
+// val allLocalInstances = instancesIn(root)
+// soFar ++ (allLocalInstances.flatMap(allInstancesOf[T]))
+// }
+
+// /** Selects the Definitions of all instances/modules directly instantiated within given module
+// *
+// * @param parent
+// */
+// def definitionsIn(parent: Hierarchy[BaseModule]): Seq[Definition[BaseModule]] = {
+// type DefType = Definition[BaseModule]
+// implicit val mg = new chisel3.internal.MacroGenerated {}
+// check(parent)
+// val defs = parent.proto._component.get match {
+// case d: DefModule =>
+// d.commands.collect {
+// case i: DefInstance =>
+// i.id match {
+// case p: chisel3.internal.BaseModule.IsClone[_] =>
+// parent._lookup { x => new Definition(Proto(p.getProto)).asInstanceOf[Definition[BaseModule]] }
+// case other: BaseModule =>
+// parent._lookup { x => other.toDefinition }
+// }
+// }
+// case other => Nil
+// }
+// val (_, defList) = defs.foldLeft((Set.empty[DefType], List.empty[DefType])) {
+// case ((set, list), definition: Definition[BaseModule]) =>
+// if (set.contains(definition)) (set, list) else (set + definition, definition +: list)
+// }
+// defList.reverse
+// }
+
+// /** Selects all Definitions of instances/modules directly instantiated within given module, of provided type
+// *
+// * @note IMPORTANT: this function requires summoning a TypeTag[T], which will fail if T is an inner class.
+// * @note IMPORTANT: this function ignores type parameters. E.g. definitionsOf[List[Int]] would return List[String].
+// *
+// * @param parent hierarchy which instantiates the returned Definitions
+// */
+// def definitionsOf[T <: BaseModule: TypeTag](parent: Hierarchy[BaseModule]): Seq[Definition[T]] = {
+// check(parent)
+// implicit val mg = new chisel3.internal.MacroGenerated {}
+// type DefType = Definition[T]
+// val defs = parent.proto._component.get match {
+// case d: DefModule =>
+// d.commands.flatMap {
+// case d: DefInstance =>
+// d.id match {
+// case p: chisel3.internal.BaseModule.IsClone[_] =>
+// val d = parent._lookup { x => new Definition(Clone(p)).asInstanceOf[Definition[BaseModule]] }
+// if (d.isA[T]) Some(d.asInstanceOf[Definition[T]]) else None
+// case other: BaseModule =>
+// val d = parent._lookup { x => other.toDefinition }
+// if (d.isA[T]) Some(d.asInstanceOf[Definition[T]]) else None
+// }
+// case other => None
+// }
+// }
+// val (_, defList) = defs.foldLeft((Set.empty[DefType], List.empty[DefType])) {
+// case ((set, list), definition: Definition[T]) =>
+// if (set.contains(definition)) (set, list) else (set + definition, definition +: list)
+// }
+// defList.reverse
+// }
+
+// /** Selects all Definition's directly and indirectly instantiated within given root hierarchy, of provided type
+// *
+// * @note IMPORTANT: this function requires summoning a TypeTag[T], which will fail if T is an inner class, i.e.
+// * a class defined within another class.
+// * @note IMPORTANT: this function ignores type parameters. E.g. allDefinitionsOf[List[Int]] would return List[String].
+// *
+// * @param root top of the hierarchy to search for definitions of given type
+// */
+// def allDefinitionsOf[T <: BaseModule: TypeTag](root: Hierarchy[BaseModule]): Seq[Definition[T]] = {
+// type DefType = Definition[T]
+// val allDefSet = mutable.HashSet[Definition[BaseModule]]()
+// val defSet = mutable.HashSet[DefType]()
+// val defList = mutable.ArrayBuffer[DefType]()
+// def rec(hier: Definition[BaseModule]): Unit = {
+// if (hier.isA[T] && !defSet.contains(hier.asInstanceOf[DefType])) {
+// defSet += hier.asInstanceOf[DefType]
+// defList += hier.asInstanceOf[DefType]
+// }
+// allDefSet += hier
+// val allDefs = definitionsIn(hier)
+// allDefs.collect {
+// case d if !allDefSet.contains(d) => rec(d)
+// }
+// }
+// rec(root.toDefinition)
+// defList.toList
+// }
+
+// /** Collects all components selected by collector within module and all children modules it instantiates
+// * directly or indirectly
+// * Accepts a collector function, rather than a collector partial function (see [[collectDeep]])
+// *
+// * @note This API will not work with the new experimental hierarchy package. Instead, use allInstancesOf or allDefinitionsOf.
+// *
+// * @param module Module to collect components, as well as all children module it directly and indirectly instantiates
+// * @param collector Collector function to pick, given a module, which components to collect
+// * @param tag Required for generics to work, should ignore this
+// * @tparam T Type of the component that will be collected
+// */
+// def getDeep[T](module: BaseModule)(collector: BaseModule => Seq[T]): Seq[T] = {
+// check(module)
+// val myItems = collector(module)
+// val deepChildrenItems = instances(module).flatMap { i =>
+// getDeep(i)(collector)
+// }
+// myItems ++ deepChildrenItems
+// }
+
+// /** Collects all components selected by collector within module and all children modules it instantiates
+// * directly or indirectly
+// * Accepts a collector partial function, rather than a collector function (see [[getDeep]])
+// *
+// * @note This API will not work with the new experimental hierarchy package. Instead, use allInstancesOf or allDefinitionsOf.
+// *
+// * @param module Module to collect components, as well as all children module it directly and indirectly instantiates
+// * @param collector Collector partial function to pick, given a module, which components to collect
+// * @param tag Required for generics to work, should ignore this
+// * @tparam T Type of the component that will be collected
+// */
+// def collectDeep[T](module: BaseModule)(collector: PartialFunction[BaseModule, T]): Iterable[T] = {
+// check(module)
+// val myItems = collector.lift(module)
+// val deepChildrenItems = instances(module).flatMap { i =>
+// collectDeep(i)(collector)
+// }
+// myItems ++ deepChildrenItems
+// }
+
+// /** Selects all modules directly instantiated within given module
+// *
+// * @note This API will not work with the new experimental hierarchy package. Instead, use instancesIn or definitionsIn.
+// *
+// * @param module
+// */
+// def instances(module: BaseModule): Seq[BaseModule] = {
+// check(module)
+// module._component.get match {
+// case d: DefModule =>
+// d.commands.flatMap {
+// case i: DefInstance =>
+// i.id match {
+// case m: ModuleClone[_] if !m._madeFromDefinition => None
+// case _: PseudoModule =>
+// throw new Exception(
+// "instances, collectDeep, and getDeep are currently incompatible with Definition/Instance!"
+// )
+// case other => Some(other)
+// }
+// case _ => None
+// }
+// case other => Nil
+// }
+// }
+
+// /** Selects all registers directly instantiated within given module
+// * @param module
+// */
+// def registers(module: BaseModule): Seq[Data] = {
+// check(module)
+// module._component.get.asInstanceOf[DefModule].commands.collect {
+// case r: DefReg => r.id
+// case r: DefRegInit => r.id
+// }
+// }
+
+// /** Selects all ios on a given module
+// * @param module
+// */
+// def ios(module: BaseModule): Seq[Data] = {
+// check(module)
+// module._component.get.asInstanceOf[DefModule].ports.map(_.id)
+// }
+
+// /** Selects all ios directly on a given Instance or Definition of a module
+// * @param parent the Definition or Instance to get the IOs of
+// */
+// def ios[T <: BaseModule](parent: Hierarchy[T]): Seq[Data] = {
+// check(parent)
+// implicit val mg = new chisel3.internal.MacroGenerated {}
+// parent._lookup { x => ios(parent.proto) }
+// }
+
+// /** Selects all SyncReadMems directly contained within given module
+// * @param module
+// */
+// def syncReadMems(module: BaseModule): Seq[SyncReadMem[_]] = {
+// check(module)
+// module._component.get.asInstanceOf[DefModule].commands.collect {
+// case r: DefSeqMemory => r.id.asInstanceOf[SyncReadMem[_]]
+// }
+// }
+
+// /** Selects all Mems directly contained within given module
+// * @param module
+// */
+// def mems(module: BaseModule): Seq[Mem[_]] = {
+// check(module)
+// module._component.get.asInstanceOf[DefModule].commands.collect {
+// case r: DefMemory => r.id.asInstanceOf[Mem[_]]
+// }
+// }
+
+// /** Selects all arithmetic or logical operators directly instantiated within given module
+// * @param module
+// */
+// def ops(module: BaseModule): Seq[(String, Data)] = {
+// check(module)
+// module._component.get.asInstanceOf[DefModule].commands.collect {
+// case d: DefPrim[_] => (d.op.name, d.id)
+// }
+// }
+
+// /** Selects a kind of arithmetic or logical operator directly instantiated within given module
+// * The kind of operators are contained in [[chisel3.internal.firrtl.PrimOp]]
+// * @param opKind the kind of operator, e.g. "mux", "add", or "bits"
+// * @param module
+// */
+// def ops(opKind: String)(module: BaseModule): Seq[Data] = {
+// check(module)
+// module._component.get.asInstanceOf[DefModule].commands.collect {
+// case d: DefPrim[_] if d.op.name == opKind => d.id
+// }
+// }
+
+// /** Selects all wires in a module
+// * @param module
+// */
+// def wires(module: BaseModule): Seq[Data] = {
+// check(module)
+// module._component.get.asInstanceOf[DefModule].commands.collect {
+// case r: DefWire => r.id
+// }
+// }
+
+// /** Selects all memory ports, including their direction and memory
+// * @param module
+// */
+// def memPorts(module: BaseModule): Seq[(Data, MemPortDirection, MemBase[_])] = {
+// check(module)
+// module._component.get.asInstanceOf[DefModule].commands.collect {
+// case r: DefMemPort[_] => (r.id, r.dir, r.source.id.asInstanceOf[MemBase[_ <: Data]])
+// }
+// }
+
+// /** Selects all memory ports of a given direction, including their memory
+// * @param dir The direction of memory ports to select
+// * @param module
+// */
+// def memPorts(dir: MemPortDirection)(module: BaseModule): Seq[(Data, MemBase[_])] = {
+// check(module)
+// module._component.get.asInstanceOf[DefModule].commands.collect {
+// case r: DefMemPort[_] if r.dir == dir => (r.id, r.source.id.asInstanceOf[MemBase[_ <: Data]])
+// }
+// }
+
+// /** Selects all components who have been set to be invalid, even if they are later connected to
+// * @param module
+// */
+// def invalids(module: BaseModule): Seq[Data] = {
+// check(module)
+// module._component.get.asInstanceOf[DefModule].commands.collect {
+// case DefInvalid(_, arg) => getData(arg)
+// }
+// }
+
+// /** Selects all components who are attached to a given signal, within a module
+// * @param module
+// */
+// def attachedTo(module: BaseModule)(signal: Data): Set[Data] = {
+// check(module)
+// module._component.get
+// .asInstanceOf[DefModule]
+// .commands
+// .collect {
+// case Attach(_, seq) if seq.contains(signal) => seq
+// }
+// .flatMap { seq => seq.map(_.id.asInstanceOf[Data]) }
+// .toSet
+// }
+
+// /** Selects all connections to a signal or its parent signal(s) (if the signal is an element of an aggregate signal)
+// * The when predicates surrounding each connection are included in the returned values
+// *
+// * E.g. if signal = io.foo.bar, connectionsTo will return all connections to io, io.foo, and io.bar
+// * @param module
+// * @param signal
+// */
+// def connectionsTo(module: BaseModule)(signal: Data): Seq[PredicatedConnect] = {
+// check(module)
+// val sensitivitySignals = getIntermediateAndLeafs(signal).toSet
+// val predicatedConnects = mutable.ArrayBuffer[PredicatedConnect]()
+// val isPort = module._component.get
+// .asInstanceOf[DefModule]
+// .ports
+// .flatMap { p => getIntermediateAndLeafs(p.id) }
+// .contains(signal)
+// var prePredicates: Seq[Predicate] = Nil
+// var seenDef = isPort
+// searchWhens(
+// module,
+// (cmd: Command, preds) => {
+// cmd match {
+// case cmd: DefinitionIR if cmd.id.isInstanceOf[Data] =>
+// val x = getIntermediateAndLeafs(cmd.id.asInstanceOf[Data])
+// if (x.contains(signal)) prePredicates = preds
+// case Connect(_, loc @ Node(d: Data), exp) =>
+// val effected = getEffected(loc).toSet
+// if (sensitivitySignals.intersect(effected).nonEmpty) {
+// val expData = getData(exp)
+// prePredicates.reverse
+// .zip(preds.reverse)
+// .foreach(x => assert(x._1 == x._2, s"Prepredicates $x must match for signal $signal"))
+// predicatedConnects += PredicatedConnect(preds.dropRight(prePredicates.size), d, expData, isBulk = false)
+// }
+// case BulkConnect(_, loc @ Node(d: Data), exp) =>
+// val effected = getEffected(loc).toSet
+// if (sensitivitySignals.intersect(effected).nonEmpty) {
+// val expData = getData(exp)
+// prePredicates.reverse
+// .zip(preds.reverse)
+// .foreach(x => assert(x._1 == x._2, s"Prepredicates $x must match for signal $signal"))
+// predicatedConnects += PredicatedConnect(preds.dropRight(prePredicates.size), d, expData, isBulk = true)
+// }
+// case other =>
+// }
+// }
+// )
+// predicatedConnects.toSeq
+// }
+
+// /** Selects all stop statements, and includes the predicates surrounding the stop statement
+// *
+// * @param module
+// */
+// def stops(module: BaseModule): Seq[Stop] = {
+// val stops = mutable.ArrayBuffer[Stop]()
+// searchWhens(
+// module,
+// (cmd: Command, preds: Seq[Predicate]) => {
+// cmd match {
+// case chisel3.internal.firrtl.Stop(_, _, clock, ret) =>
+// stops += Stop(preds, ret, getId(clock).asInstanceOf[Clock])
+// case other =>
+// }
+// }
+// )
+// stops.toSeq
+// }
+
+// /** Selects all printf statements, and includes the predicates surrounding the printf statement
+// *
+// * @param module
+// */
+// def printfs(module: BaseModule): Seq[Printf] = {
+// val printfs = mutable.ArrayBuffer[Printf]()
+// searchWhens(
+// module,
+// (cmd: Command, preds: Seq[Predicate]) => {
+// cmd match {
+// case chisel3.internal.firrtl.Printf(id, _, clock, pable) =>
+// printfs += Printf(id, preds, pable, getId(clock).asInstanceOf[Clock])
+// case other =>
+// }
+// }
+// )
+// printfs.toSeq
+// }
+
+// // Checks that a module has finished its construction
+// private def check(module: BaseModule): Unit = {
+// require(module.isClosed, "Can't use Selector on modules that have not finished construction!")
+// require(module._component.isDefined, "Can't use Selector on modules that don't have components!")
+// }
+// private def check(hierarchy: Hierarchy[BaseModule]): Unit = check(hierarchy.proto)
+
+// // Given a loc, return all subcomponents of id that could be assigned to in connect
+// private def getEffected(a: Arg): Seq[Data] = a match {
+// case Node(id: Data) => getIntermediateAndLeafs(id)
+// case Slot(imm, name) => Seq(imm.id.asInstanceOf[Record].elements(name))
+// case Index(imm, value) => getEffected(imm)
+// }
+
+// // Given an arg, return the corresponding id. Don't use on a loc of a connect.
+// private def getId(a: Arg): HasId = a match {
+// case Node(id) => id
+// case l: ULit => l.num.U(l.w)
+// case l: SLit => l.num.S(l.w)
+// case l: FPLit => FixedPoint(l.num, l.w, l.binaryPoint)
+// case other =>
+// sys.error(s"Something went horribly wrong! I was expecting ${other} to be a lit or a node!")
+// }
+
+// private def getData(a: Arg): Data = a match {
+// case Node(data: Data) => data
+// case other =>
+// sys.error(s"Something went horribly wrong! I was expecting ${other} to be Data!")
+// }
+
+// // Given an id, either get its name or its value, if its a lit
+// private def getName(i: HasId): String = try {
+// i.toTarget match {
+// case r: ReferenceTarget =>
+// val str = r.serialize
+// str.splitAt(str.indexOf('>'))._2.drop(1)
+// }
+// } catch {
+// case e: ChiselException =>
+// i.getOptionRef.get match {
+// case l: LitArg => l.num.intValue.toString
+// }
+// }
+
+// // Collects when predicates as it searches through a module, then applying processCommand to non-when related commands
+// private def searchWhens(module: BaseModule, processCommand: (Command, Seq[Predicate]) => Unit) = {
+// check(module)
+// module._component.get.asInstanceOf[DefModule].commands.foldLeft((Seq.empty[Predicate], Option.empty[Predicate])) {
+// (blah, cmd) =>
+// (blah, cmd) match {
+// case ((preds, o), cmd) =>
+// cmd match {
+// case WhenBegin(_, Node(pred: Bool)) => (When(pred) +: preds, None)
+// case WhenBegin(_, l: LitArg) if l.num == BigInt(1) => (When(true.B) +: preds, None)
+// case WhenBegin(_, l: LitArg) if l.num == BigInt(0) => (When(false.B) +: preds, None)
+// case other: WhenBegin =>
+// sys.error(s"Something went horribly wrong! I was expecting ${other.pred} to be a lit or a bool!")
+// case _: WhenEnd => (preds.tail, Some(preds.head))
+// case AltBegin(_) if o.isDefined => (o.get.not +: preds, o)
+// case _: AltBegin =>
+// sys.error(s"Something went horribly wrong! I was expecting ${o} to be nonEmpty!")
+// case OtherwiseEnd(_, _) => (preds.tail, None)
+// case other =>
+// processCommand(cmd, preds)
+// (preds, o)
+// }
+// }
+// }
+// }
+
+// trait Serializeable {
+// def serialize: String
+// }
+
+// /** Used to indicates a when's predicate (or its otherwise predicate)
+// */
+// trait Predicate extends Serializeable {
+// val bool: Bool
+// def not: Predicate
+// }
+
+// /** Used to represent [[chisel3.when]] predicate
+// *
+// * @param bool the when predicate
+// */
+// case class When(bool: Bool) extends Predicate {
+// def not: WhenNot = WhenNot(bool)
+// def serialize: String = s"${getName(bool)}"
+// }
+
+// /** Used to represent the `otherwise` predicate of a [[chisel3.when]]
+// *
+// * @param bool the when predicate corresponding to this otherwise predicate
+// */
+// case class WhenNot(bool: Bool) extends Predicate {
+// def not: When = When(bool)
+// def serialize: String = s"!${getName(bool)}"
+// }
+
+// /** Used to represent a connection or bulk connection
+// *
+// * Additionally contains the sequence of when predicates seen when the connection is declared
+// *
+// * @param preds
+// * @param loc
+// * @param exp
+// * @param isBulk
+// */
+// case class PredicatedConnect(preds: Seq[Predicate], loc: Data, exp: Data, isBulk: Boolean) extends Serializeable {
+// def serialize: String = {
+// val moduleTarget = loc.toTarget.moduleTarget.serialize
+// s"$moduleTarget: when(${preds.map(_.serialize).mkString(" & ")}): ${getName(loc)} ${if (isBulk) "<>" else ":="} ${getName(exp)}"
+// }
+// }
+
+// /** Used to represent a [[chisel3.stop]]
+// *
+// * @param preds
+// * @param ret
+// * @param clock
+// */
+// case class Stop(preds: Seq[Predicate], ret: Int, clock: Clock) extends Serializeable {
+// def serialize: String = {
+// s"stop when(${preds.map(_.serialize).mkString(" & ")}) on ${getName(clock)}: $ret"
+// }
+// }
+
+// /** Used to represent a [[chisel3.printf]]
+// *
+// * @param preds
+// * @param pable
+// * @param clock
+// */
+// case class Printf(id: printf.Printf, preds: Seq[Predicate], pable: Printable, clock: Clock) extends Serializeable {
+// def serialize: String = {
+// s"printf when(${preds.map(_.serialize).mkString(" & ")}) on ${getName(clock)}: $pable"
+// }
+// }
+// }
diff --git a/src/main/scala/chisel3/aop/injecting/InjectStatement.scala b/src/main/scala/chisel3/aop/injecting/InjectStatement.scala
index dbe1fd7b..be12cf32 100644
--- a/src/main/scala/chisel3/aop/injecting/InjectStatement.scala
+++ b/src/main/scala/chisel3/aop/injecting/InjectStatement.scala
@@ -1,26 +1,26 @@
-// SPDX-License-Identifier: Apache-2.0
+// // SPDX-License-Identifier: Apache-2.0
-package chisel3.aop.injecting
+// package chisel3.aop.injecting
-import chisel3.stage.phases.AspectPhase
-import firrtl.annotations.{Annotation, ModuleTarget, NoTargetAnnotation, SingleTargetAnnotation}
+// import chisel3.stage.phases.AspectPhase
+// import firrtl.annotations.{Annotation, ModuleTarget, NoTargetAnnotation, SingleTargetAnnotation}
-/** Contains all information needed to inject statements into a module
- *
- * Generated when a [[InjectingAspect]] is consumed by a [[AspectPhase]]
- * Consumed by [[InjectingTransform]]
- *
- * @param module Module to inject code into at the end of the module
- * @param s Statements to inject
- * @param modules Additional modules that may be instantiated by s
- * @param annotations Additional annotations that should be passed down compiler
- */
-case class InjectStatement(
- module: ModuleTarget,
- s: firrtl.ir.Statement,
- modules: Seq[firrtl.ir.DefModule],
- annotations: Seq[Annotation])
- extends SingleTargetAnnotation[ModuleTarget] {
- val target: ModuleTarget = module
- override def duplicate(n: ModuleTarget): Annotation = this.copy(module = n)
-}
+// /** Contains all information needed to inject statements into a module
+// *
+// * Generated when a [[InjectingAspect]] is consumed by a [[AspectPhase]]
+// * Consumed by [[InjectingTransform]]
+// *
+// * @param module Module to inject code into at the end of the module
+// * @param s Statements to inject
+// * @param modules Additional modules that may be instantiated by s
+// * @param annotations Additional annotations that should be passed down compiler
+// */
+// case class InjectStatement(
+// module: ModuleTarget,
+// s: firrtl.ir.Statement,
+// modules: Seq[firrtl.ir.DefModule],
+// annotations: Seq[Annotation])
+// extends SingleTargetAnnotation[ModuleTarget] {
+// val target: ModuleTarget = module
+// override def duplicate(n: ModuleTarget): Annotation = this.copy(module = n)
+// }
diff --git a/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala b/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala
index ecce19e1..8682785b 100644
--- a/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala
+++ b/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala
@@ -1,108 +1,108 @@
-// SPDX-License-Identifier: Apache-2.0
+// // SPDX-License-Identifier: Apache-2.0
-package chisel3.aop.injecting
+// package chisel3.aop.injecting
-import chisel3.{withClockAndReset, Module, ModuleAspect, RawModule}
-import chisel3.aop._
-import chisel3.internal.{Builder, DynamicContext}
-import chisel3.internal.firrtl.DefModule
-import chisel3.stage.{ChiselOptions, DesignAnnotation}
-import firrtl.annotations.ModuleTarget
-import firrtl.stage.RunFirrtlTransformAnnotation
-import firrtl.options.Viewer.view
-import firrtl.{ir, _}
+// import chisel3.{withClockAndReset, Module, ModuleAspect, RawModule}
+// import chisel3.aop._
+// import chisel3.internal.{Builder, DynamicContext}
+// import chisel3.internal.firrtl.DefModule
+// import chisel3.stage.{ChiselOptions, DesignAnnotation}
+// import firrtl.annotations.ModuleTarget
+// import firrtl.stage.RunFirrtlTransformAnnotation
+// import firrtl.options.Viewer.view
+// import firrtl.{ir, _}
-import scala.collection.mutable
+// import scala.collection.mutable
-/** Aspect to inject Chisel code into a module of type M
- *
- * @param selectRoots Given top-level module, pick the instances of a module to apply the aspect (root module)
- * @param injection Function to generate Chisel hardware that will be injected to the end of module m
- * Signals in m can be referenced and assigned to as if inside m (yes, it is a bit magical)
- * @tparam T Type of top-level module
- * @tparam M Type of root module (join point)
- */
-case class InjectingAspect[T <: RawModule, M <: RawModule](
- selectRoots: T => Iterable[M],
- injection: M => Unit)
- extends InjectorAspect[T, M](
- selectRoots,
- injection
- )
+// /** Aspect to inject Chisel code into a module of type M
+// *
+// * @param selectRoots Given top-level module, pick the instances of a module to apply the aspect (root module)
+// * @param injection Function to generate Chisel hardware that will be injected to the end of module m
+// * Signals in m can be referenced and assigned to as if inside m (yes, it is a bit magical)
+// * @tparam T Type of top-level module
+// * @tparam M Type of root module (join point)
+// */
+// case class InjectingAspect[T <: RawModule, M <: RawModule](
+// selectRoots: T => Iterable[M],
+// injection: M => Unit)
+// extends InjectorAspect[T, M](
+// selectRoots,
+// injection
+// )
-/** Extend to inject Chisel code into a module of type M
- *
- * @param selectRoots Given top-level module, pick the instances of a module to apply the aspect (root module)
- * @param injection Function to generate Chisel hardware that will be injected to the end of module m
- * Signals in m can be referenced and assigned to as if inside m (yes, it is a bit magical)
- * @tparam T Type of top-level module
- * @tparam M Type of root module (join point)
- */
-abstract class InjectorAspect[T <: RawModule, M <: RawModule](
- selectRoots: T => Iterable[M],
- injection: M => Unit)
- extends Aspect[T] {
- final def toAnnotation(top: T): AnnotationSeq = {
- val moduleNames =
- Select.allDefinitionsOf[chisel3.experimental.BaseModule](top.toDefinition).map { i => i.toTarget.module }.toSeq
- toAnnotation(selectRoots(top), top.name, moduleNames)
- }
+// /** Extend to inject Chisel code into a module of type M
+// *
+// * @param selectRoots Given top-level module, pick the instances of a module to apply the aspect (root module)
+// * @param injection Function to generate Chisel hardware that will be injected to the end of module m
+// * Signals in m can be referenced and assigned to as if inside m (yes, it is a bit magical)
+// * @tparam T Type of top-level module
+// * @tparam M Type of root module (join point)
+// */
+// abstract class InjectorAspect[T <: RawModule, M <: RawModule](
+// selectRoots: T => Iterable[M],
+// injection: M => Unit)
+// extends Aspect[T] {
+// final def toAnnotation(top: T): AnnotationSeq = {
+// val moduleNames =
+// Select.allDefinitionsOf[chisel3.experimental.BaseModule](top.toDefinition).map { i => i.toTarget.module }.toSeq
+// toAnnotation(selectRoots(top), top.name, moduleNames)
+// }
- /** Returns annotations which contain all injection logic
- *
- * @param modules The modules to inject into
- * @param circuit Top level circuit
- * @param moduleNames The names of all existing modules in the original circuit, to avoid name collisions
- * @return
- */
- final def toAnnotation(modules: Iterable[M], circuit: String, moduleNames: Seq[String]): AnnotationSeq = {
- RunFirrtlTransformAnnotation(new InjectingTransform) +: modules.map { module =>
- val chiselOptions = view[ChiselOptions](annotationsInAspect)
- val dynamicContext =
- new DynamicContext(
- annotationsInAspect,
- chiselOptions.throwOnFirstError,
- chiselOptions.warnReflectiveNaming,
- chiselOptions.warningsAsErrors
- )
- // Add existing module names into the namespace. If injection logic instantiates new modules
- // which would share the same name, they will get uniquified accordingly
- moduleNames.foreach { n =>
- dynamicContext.globalNamespace.name(n)
- }
+// /** Returns annotations which contain all injection logic
+// *
+// * @param modules The modules to inject into
+// * @param circuit Top level circuit
+// * @param moduleNames The names of all existing modules in the original circuit, to avoid name collisions
+// * @return
+// */
+// final def toAnnotation(modules: Iterable[M], circuit: String, moduleNames: Seq[String]): AnnotationSeq = {
+// RunFirrtlTransformAnnotation(new InjectingTransform) +: modules.map { module =>
+// val chiselOptions = view[ChiselOptions](annotationsInAspect)
+// val dynamicContext =
+// new DynamicContext(
+// annotationsInAspect,
+// chiselOptions.throwOnFirstError,
+// chiselOptions.warnReflectiveNaming,
+// chiselOptions.warningsAsErrors
+// )
+// // Add existing module names into the namespace. If injection logic instantiates new modules
+// // which would share the same name, they will get uniquified accordingly
+// moduleNames.foreach { n =>
+// dynamicContext.globalNamespace.name(n)
+// }
- val (chiselIR, _) = Builder.build(
- Module(new ModuleAspect(module) {
- module match {
- case x: Module => withClockAndReset(x.clock, x.reset) { injection(module) }
- case x: RawModule => injection(module)
- }
- }),
- dynamicContext
- )
+// val (chiselIR, _) = Builder.build(
+// Module(new ModuleAspect(module) {
+// module match {
+// case x: Module => withClockAndReset(x.clock, x.reset) { injection(module) }
+// case x: RawModule => injection(module)
+// }
+// }),
+// dynamicContext
+// )
- val comps = chiselIR.components.map {
- case x: DefModule if x.name == module.name => x.copy(id = module)
- case other => other
- }
+// val comps = chiselIR.components.map {
+// case x: DefModule if x.name == module.name => x.copy(id = module)
+// case other => other
+// }
- val annotations = chiselIR.annotations.map(_.toFirrtl).filterNot { a => a.isInstanceOf[DesignAnnotation[_]] }
+// val annotations = chiselIR.annotations.map(_.toFirrtl).filterNot { a => a.isInstanceOf[DesignAnnotation[_]] }
- /** Statements to be injected via aspect. */
- val stmts = mutable.ArrayBuffer[ir.Statement]()
+// /** Statements to be injected via aspect. */
+// val stmts = mutable.ArrayBuffer[ir.Statement]()
- /** Modules to be injected via aspect. */
- val modules = Aspect.getFirrtl(chiselIR.copy(components = comps)).modules.flatMap {
- // for "container" modules, inject their statements
- case m: firrtl.ir.Module if m.name == module.name =>
- stmts += m.body
- Nil
- // for modules to be injected
- case other: firrtl.ir.DefModule =>
- Seq(other)
- }
+// /** Modules to be injected via aspect. */
+// val modules = Aspect.getFirrtl(chiselIR.copy(components = comps)).modules.flatMap {
+// // for "container" modules, inject their statements
+// case m: firrtl.ir.Module if m.name == module.name =>
+// stmts += m.body
+// Nil
+// // for modules to be injected
+// case other: firrtl.ir.DefModule =>
+// Seq(other)
+// }
- InjectStatement(ModuleTarget(circuit, module.name), ir.Block(stmts.toSeq), modules, annotations)
- }.toSeq
- }
-}
+// InjectStatement(ModuleTarget(circuit, module.name), ir.Block(stmts.toSeq), modules, annotations)
+// }.toSeq
+// }
+// }
diff --git a/src/main/scala/chisel3/aop/injecting/InjectingTransform.scala b/src/main/scala/chisel3/aop/injecting/InjectingTransform.scala
index 8a0b6ecb..a7d47243 100644
--- a/src/main/scala/chisel3/aop/injecting/InjectingTransform.scala
+++ b/src/main/scala/chisel3/aop/injecting/InjectingTransform.scala
@@ -1,46 +1,46 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chisel3.aop.injecting
-
-import firrtl.{ir, ChirrtlForm, CircuitForm, CircuitState, Transform}
-
-import scala.collection.mutable
-
-/** Appends statements contained in [[InjectStatement]] annotations to the end of their corresponding modules
- *
- * Implemented with Chisel Aspects and the [[chisel3.aop.injecting]] library
- */
-class InjectingTransform extends Transform {
- override def inputForm: CircuitForm = ChirrtlForm
- override def outputForm: CircuitForm = ChirrtlForm
-
- override def execute(state: CircuitState): CircuitState = {
-
- val addStmtMap = mutable.HashMap[String, Seq[ir.Statement]]()
- val addModules = mutable.ArrayBuffer[ir.DefModule]()
-
- // Populate addStmtMap and addModules, return annotations in InjectStatements, and omit InjectStatement annotation
- val newAnnotations = state.annotations.flatMap {
- case InjectStatement(mt, s, addedModules, annotations) =>
- addModules ++= addedModules
- addStmtMap(mt.module) = s +: addStmtMap.getOrElse(mt.module, Nil)
- annotations
- case other => Seq(other)
- }
-
- // Append all statements to end of corresponding modules
- val newModules = state.circuit.modules.map { m: ir.DefModule =>
- m match {
- case m: ir.Module if addStmtMap.contains(m.name) =>
- m.copy(body = ir.Block(m.body +: addStmtMap(m.name)))
- case m: _root_.firrtl.ir.ExtModule if addStmtMap.contains(m.name) =>
- ir.Module(m.info, m.name, m.ports, ir.Block(addStmtMap(m.name)))
- case other: ir.DefModule => other
- }
- }
-
- // Return updated circuit and annotations
- val newCircuit = state.circuit.copy(modules = newModules ++ addModules)
- state.copy(annotations = newAnnotations, circuit = newCircuit)
- }
-}
+// // SPDX-License-Identifier: Apache-2.0
+
+// package chisel3.aop.injecting
+
+// import firrtl.{ir, ChirrtlForm, CircuitForm, CircuitState, Transform}
+
+// import scala.collection.mutable
+
+// /** Appends statements contained in [[InjectStatement]] annotations to the end of their corresponding modules
+// *
+// * Implemented with Chisel Aspects and the [[chisel3.aop.injecting]] library
+// */
+// class InjectingTransform extends Transform {
+// override def inputForm: CircuitForm = ChirrtlForm
+// override def outputForm: CircuitForm = ChirrtlForm
+
+// override def execute(state: CircuitState): CircuitState = {
+
+// val addStmtMap = mutable.HashMap[String, Seq[ir.Statement]]()
+// val addModules = mutable.ArrayBuffer[ir.DefModule]()
+
+// // Populate addStmtMap and addModules, return annotations in InjectStatements, and omit InjectStatement annotation
+// val newAnnotations = state.annotations.flatMap {
+// case InjectStatement(mt, s, addedModules, annotations) =>
+// addModules ++= addedModules
+// addStmtMap(mt.module) = s +: addStmtMap.getOrElse(mt.module, Nil)
+// annotations
+// case other => Seq(other)
+// }
+
+// // Append all statements to end of corresponding modules
+// val newModules = state.circuit.modules.map { m: ir.DefModule =>
+// m match {
+// case m: ir.Module if addStmtMap.contains(m.name) =>
+// m.copy(body = ir.Block(m.body +: addStmtMap(m.name)))
+// case m: _root_.firrtl.ir.ExtModule if addStmtMap.contains(m.name) =>
+// ir.Module(m.info, m.name, m.ports, ir.Block(addStmtMap(m.name)))
+// case other: ir.DefModule => other
+// }
+// }
+
+// // Return updated circuit and annotations
+// val newCircuit = state.circuit.copy(modules = newModules ++ addModules)
+// state.copy(annotations = newAnnotations, circuit = newCircuit)
+// }
+// }
diff --git a/src/main/scala/chisel3/aop/inspecting/InspectingAspect.scala b/src/main/scala/chisel3/aop/inspecting/InspectingAspect.scala
index 1340f253..9c9dc987 100644
--- a/src/main/scala/chisel3/aop/inspecting/InspectingAspect.scala
+++ b/src/main/scala/chisel3/aop/inspecting/InspectingAspect.scala
@@ -1,26 +1,26 @@
-// SPDX-License-Identifier: Apache-2.0
+// // SPDX-License-Identifier: Apache-2.0
-package chisel3.aop.inspecting
+// package chisel3.aop.inspecting
-import chisel3.RawModule
-import chisel3.aop.Aspect
-import firrtl.AnnotationSeq
+// import chisel3.RawModule
+// import chisel3.aop.Aspect
+// import firrtl.AnnotationSeq
-/** Use for inspecting an elaborated design and printing out results
- *
- * @param inspect Given top-level design, print things and return nothing
- * @tparam T Type of top-level module
- */
-case class InspectingAspect[T <: RawModule](inspect: T => Unit) extends InspectorAspect[T](inspect)
+// /** Use for inspecting an elaborated design and printing out results
+// *
+// * @param inspect Given top-level design, print things and return nothing
+// * @tparam T Type of top-level module
+// */
+// case class InspectingAspect[T <: RawModule](inspect: T => Unit) extends InspectorAspect[T](inspect)
-/** Extend to make custom inspections of an elaborated design and printing out results
- *
- * @param inspect Given top-level design, print things and return nothing
- * @tparam T Type of top-level module
- */
-abstract class InspectorAspect[T <: RawModule](inspect: T => Unit) extends Aspect[T] {
- override def toAnnotation(top: T): AnnotationSeq = {
- inspect(top)
- Nil
- }
-}
+// /** Extend to make custom inspections of an elaborated design and printing out results
+// *
+// * @param inspect Given top-level design, print things and return nothing
+// * @tparam T Type of top-level module
+// */
+// abstract class InspectorAspect[T <: RawModule](inspect: T => Unit) extends Aspect[T] {
+// override def toAnnotation(top: T): AnnotationSeq = {
+// inspect(top)
+// Nil
+// }
+// }
diff --git a/src/main/scala/chisel3/stage/ChiselPhase.scala b/src/main/scala/chisel3/stage/ChiselPhase.scala
index 6c7affbc..fe6ab29a 100644
--- a/src/main/scala/chisel3/stage/ChiselPhase.scala
+++ b/src/main/scala/chisel3/stage/ChiselPhase.scala
@@ -18,7 +18,7 @@ private[chisel3] object ChiselPhase {
Dependency[chisel3.stage.phases.Checks],
Dependency[chisel3.stage.phases.AddImplicitOutputFile],
Dependency[chisel3.stage.phases.AddImplicitOutputAnnotationFile],
- Dependency[chisel3.stage.phases.MaybeAspectPhase],
+ // Dependency[chisel3.stage.phases.MaybeAspectPhase],
Dependency[chisel3.stage.phases.AddSerializationAnnotations],
Dependency[chisel3.stage.phases.Convert],
Dependency[chisel3.stage.phases.MaybeFirrtlStage]
diff --git a/src/main/scala/chisel3/stage/ChiselStage.scala b/src/main/scala/chisel3/stage/ChiselStage.scala
index 1224a8f1..dd9a3ae7 100644
--- a/src/main/scala/chisel3/stage/ChiselStage.scala
+++ b/src/main/scala/chisel3/stage/ChiselStage.scala
@@ -158,7 +158,7 @@ object ChiselStage {
Dependency[chisel3.stage.phases.Elaborate],
Dependency[chisel3.stage.phases.AddImplicitOutputFile],
Dependency[chisel3.stage.phases.AddImplicitOutputAnnotationFile],
- Dependency[chisel3.stage.phases.MaybeAspectPhase],
+ // Dependency[chisel3.stage.phases.MaybeAspectPhase],
Dependency[chisel3.stage.phases.Convert]
)
}
@@ -179,7 +179,7 @@ object ChiselStage {
override val targets = Seq(
Dependency[chisel3.stage.phases.AddImplicitOutputFile],
Dependency[chisel3.stage.phases.AddImplicitOutputAnnotationFile],
- Dependency[chisel3.stage.phases.MaybeAspectPhase],
+ // Dependency[chisel3.stage.phases.MaybeAspectPhase],
Dependency[chisel3.stage.phases.Convert]
)
}
@@ -207,7 +207,7 @@ object ChiselStage {
Dependency[chisel3.stage.phases.Elaborate],
Dependency[chisel3.stage.phases.AddImplicitOutputFile],
Dependency[chisel3.stage.phases.AddImplicitOutputAnnotationFile],
- Dependency[chisel3.stage.phases.MaybeAspectPhase],
+ // Dependency[chisel3.stage.phases.MaybeAspectPhase],
Dependency[chisel3.stage.phases.Convert],
Dependency[firrtl.stage.phases.Compiler]
)
@@ -233,7 +233,7 @@ object ChiselStage {
Dependency[chisel3.stage.phases.Elaborate],
Dependency[chisel3.stage.phases.AddImplicitOutputFile],
Dependency[chisel3.stage.phases.AddImplicitOutputAnnotationFile],
- Dependency[chisel3.stage.phases.MaybeAspectPhase],
+ // Dependency[chisel3.stage.phases.MaybeAspectPhase],
Dependency[chisel3.stage.phases.Convert],
Dependency[firrtl.stage.phases.Compiler]
)
@@ -258,7 +258,7 @@ object ChiselStage {
Dependency[chisel3.stage.phases.Elaborate],
Dependency[chisel3.stage.phases.AddImplicitOutputFile],
Dependency[chisel3.stage.phases.AddImplicitOutputAnnotationFile],
- Dependency[chisel3.stage.phases.MaybeAspectPhase],
+ // Dependency[chisel3.stage.phases.MaybeAspectPhase],
Dependency[chisel3.stage.phases.Convert],
Dependency[firrtl.stage.phases.Compiler]
)
diff --git a/src/main/scala/chisel3/stage/phases/AspectPhase.scala b/src/main/scala/chisel3/stage/phases/AspectPhase.scala
index efe2c3a4..414dc075 100644
--- a/src/main/scala/chisel3/stage/phases/AspectPhase.scala
+++ b/src/main/scala/chisel3/stage/phases/AspectPhase.scala
@@ -1,36 +1,36 @@
-// SPDX-License-Identifier: Apache-2.0
+// // SPDX-License-Identifier: Apache-2.0
-package chisel3.stage.phases
+// package chisel3.stage.phases
-import chisel3.aop.Aspect
-import chisel3.RawModule
-import chisel3.stage.DesignAnnotation
-import firrtl.AnnotationSeq
-import firrtl.options.Phase
+// import chisel3.aop.Aspect
+// import chisel3.RawModule
+// import chisel3.stage.DesignAnnotation
+// import firrtl.AnnotationSeq
+// import firrtl.options.Phase
-import scala.collection.mutable
+// import scala.collection.mutable
-/** Phase that consumes all Aspects and calls their toAnnotationSeq methods.
- *
- * Consumes the [[chisel3.stage.DesignAnnotation]] and converts every [[Aspect]] into their annotations prior to executing FIRRTL
- */
-class AspectPhase extends Phase {
- def transform(annotations: AnnotationSeq): AnnotationSeq = {
- var dut: Option[RawModule] = None
- val aspects = mutable.ArrayBuffer[Aspect[_]]()
+// /** Phase that consumes all Aspects and calls their toAnnotationSeq methods.
+// *
+// * Consumes the [[chisel3.stage.DesignAnnotation]] and converts every [[Aspect]] into their annotations prior to executing FIRRTL
+// */
+// class AspectPhase extends Phase {
+// def transform(annotations: AnnotationSeq): AnnotationSeq = {
+// var dut: Option[RawModule] = None
+// val aspects = mutable.ArrayBuffer[Aspect[_]]()
- val remainingAnnotations = annotations.flatMap {
- case DesignAnnotation(d) =>
- dut = Some(d)
- Nil
- case a: Aspect[_] =>
- aspects += a
- Nil
- case other => Seq(other)
- }
- if (dut.isDefined) {
- val newAnnotations = aspects.flatMap { _.resolveAspect(dut.get, remainingAnnotations) }
- remainingAnnotations ++ newAnnotations
- } else annotations
- }
-}
+// val remainingAnnotations = annotations.flatMap {
+// case DesignAnnotation(d) =>
+// dut = Some(d)
+// Nil
+// case a: Aspect[_] =>
+// aspects += a
+// Nil
+// case other => Seq(other)
+// }
+// if (dut.isDefined) {
+// val newAnnotations = aspects.flatMap { _.resolveAspect(dut.get, remainingAnnotations) }
+// remainingAnnotations ++ newAnnotations
+// } else annotations
+// }
+// }
diff --git a/src/main/scala/chisel3/stage/phases/Emitter.scala b/src/main/scala/chisel3/stage/phases/Emitter.scala
index 254f8add..82a24950 100644
--- a/src/main/scala/chisel3/stage/phases/Emitter.scala
+++ b/src/main/scala/chisel3/stage/phases/Emitter.scala
@@ -29,7 +29,7 @@ class Emitter extends Phase {
Dependency[Elaborate],
Dependency[AddImplicitOutputFile],
Dependency[AddImplicitOutputAnnotationFile],
- Dependency[MaybeAspectPhase]
+ // Dependency[MaybeAspectPhase]
)
override def optionalPrerequisites = Seq.empty
override def optionalPrerequisiteOf = Seq(Dependency[Convert])
diff --git a/src/main/scala/chisel3/stage/phases/MaybeAspectPhase.scala b/src/main/scala/chisel3/stage/phases/MaybeAspectPhase.scala
index dcd0dfe0..0afebd3b 100644
--- a/src/main/scala/chisel3/stage/phases/MaybeAspectPhase.scala
+++ b/src/main/scala/chisel3/stage/phases/MaybeAspectPhase.scala
@@ -1,23 +1,23 @@
-// SPDX-License-Identifier: Apache-2.0
+// // SPDX-License-Identifier: Apache-2.0
-package chisel3.stage.phases
+// package chisel3.stage.phases
-import chisel3.aop.Aspect
-import firrtl.AnnotationSeq
-import firrtl.options.{Dependency, Phase}
+// import chisel3.aop.Aspect
+// import firrtl.AnnotationSeq
+// import firrtl.options.{Dependency, Phase}
-/** Run [[AspectPhase]] if a [[chisel3.aop.Aspect]] is present.
- */
-class MaybeAspectPhase extends Phase {
+// /** Run [[AspectPhase]] if a [[chisel3.aop.Aspect]] is present.
+// */
+// class MaybeAspectPhase extends Phase {
- override def prerequisites = Seq(Dependency[Elaborate])
- override def optionalPrerequisites = Seq.empty
- override def optionalPrerequisiteOf = Seq.empty
- override def invalidates(a: Phase) = false
+// override def prerequisites = Seq(Dependency[Elaborate])
+// override def optionalPrerequisites = Seq.empty
+// override def optionalPrerequisiteOf = Seq.empty
+// override def invalidates(a: Phase) = false
- def transform(annotations: AnnotationSeq): AnnotationSeq = {
- if (annotations.collectFirst { case a: Aspect[_] => annotations }.isDefined) {
- new AspectPhase().transform(annotations)
- } else annotations
- }
-}
+// def transform(annotations: AnnotationSeq): AnnotationSeq = {
+// if (annotations.collectFirst { case a: Aspect[_] => annotations }.isDefined) {
+// new AspectPhase().transform(annotations)
+// } else annotations
+// }
+// }
diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala
index f8c8f9e9..aa223697 100644
--- a/src/main/scala/chisel3/util/Decoupled.scala
+++ b/src/main/scala/chisel3/util/Decoupled.scala
@@ -22,7 +22,7 @@ import scala.annotation.nowarn
abstract class ReadyValidIO[+T <: Data](gen: T) extends Bundle {
// Compatibility hack for rocket-chip
private val genType = (DataMirror.internal.isSynthesizable(gen), chisel3.internal.Builder.currentModule) match {
- case (true, Some(module: Module)) if !module.compileOptions.declaredTypeMustBeUnbound => chiselTypeOf(gen)
+ // case (true, Some(module: Module)) if !module.compileOptions.declaredTypeMustBeUnbound => chiselTypeOf(gen)
case _ => gen
}
diff --git a/src/test/scala/chiselTests/AbstractModule.scala b/src/test/scala/chiselTests/AbstractModule.scala
new file mode 100644
index 00000000..dc381120
--- /dev/null
+++ b/src/test/scala/chiselTests/AbstractModule.scala
@@ -0,0 +1,20 @@
+package chiselTests
+
+import chisel3._
+import chisel3.stage.ChiselStage
+
+class AbstractModule[T <: Data](params: T) extends Module[T] {
+ val node = IO(params)
+}
+
+class AbstractModuleContainer extends Module {
+ val mod1 = Module(new AbstractModule[UInt](Input(UInt(0.W))))
+ val mod2 = Module(new AbstractModule[UInt](Output(UInt(0.W))))
+ mod2.node := mod1.node
+}
+
+class AbstractModuleSpec extends ChiselPropSpec with Utils {
+ property("Abstract module should elaborate") {
+ ChiselStage.elaborate { new AbstractModuleContainer }
+ }
+}
diff --git a/src/test/scala/chiselTests/AdderTree.scala b/src/test/scala/chiselTests/AdderTree.scala
deleted file mode 100644
index 29ef97a4..00000000
--- a/src/test/scala/chiselTests/AdderTree.scala
+++ /dev/null
@@ -1,35 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.testers.BasicTester
-
-class AdderTree[T <: Bits with Num[T]](genType: T, vecSize: Int) extends Module {
- val io = IO(new Bundle {
- val numIn = Input(Vec(vecSize, genType))
- val numOut = Output(genType)
- })
- io.numOut := io.numIn.reduceTree((a: T, b: T) => (a + b))
-}
-
-class AdderTreeTester(bitWidth: Int, numsToAdd: List[Int]) extends BasicTester {
- val genType = UInt(bitWidth.W)
- val dut = Module(new AdderTree(genType, numsToAdd.size))
- dut.io.numIn := VecInit(numsToAdd.map(x => x.asUInt(bitWidth.W)))
- val sumCorrect = dut.io.numOut === (numsToAdd.reduce(_ + _) % (1 << bitWidth)).asUInt(bitWidth.W)
- assert(sumCorrect)
- stop()
-}
-
-class AdderTreeSpec extends ChiselPropSpec {
- property("All numbers should be added correctly by an Adder Tree") {
- forAll(safeUIntN(20)) {
- case (w: Int, v: List[Int]) => {
- whenever(v.size > 0 && w > 0) {
- assertTesterPasses { new AdderTreeTester(w, v.map(x => math.abs(x) % (1 << w)).toList) }
- }
- }
- }
- }
-}
diff --git a/src/test/scala/chiselTests/AnalogIntegrationSpec.scala b/src/test/scala/chiselTests/AnalogIntegrationSpec.scala
deleted file mode 100644
index 035a9d91..00000000
--- a/src/test/scala/chiselTests/AnalogIntegrationSpec.scala
+++ /dev/null
@@ -1,150 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.util._
-import chisel3.testers.{BasicTester, TesterDriver}
-import chisel3.experimental._
-
-/* This test is different from AnalogSpec in that it uses more complicated black boxes that can each
- * drive the bidirectional bus. It was created to evaluate Analog with synthesis tools since the
- * simple tests in AnalogSpec don't anything interesting in them to synthesize.
- */
-
-class AnalogBlackBoxPort extends Bundle {
- val in = Input(Valid(UInt(32.W)))
- val out = Output(UInt(32.W))
-}
-
-// This IO can be used for a single BlackBox or to group multiple
-// Has multiple ports for driving and checking but only one shared bus
-class AnalogBlackBoxIO(val n: Int) extends Bundle {
- require(n > 0)
- val bus = Analog(32.W)
- val port = Vec(n, new AnalogBlackBoxPort)
-}
-
-// Assigns bus to out
-// Assigns in.bits + index to bus when in.valid
-class AnalogBlackBox(index: Int) extends BlackBox(Map("index" -> index)) {
- val io = IO(new AnalogBlackBoxIO(1))
-}
-
-// This interface exists to give a common interface type for AnalogBlackBoxModule and
-// AnalogBlackBoxWrapper. This is the standard way to deal with the deprecation and removal of the
-// Module.io virtual method (same for BlackBox.io).
-// See https://github.com/freechipsproject/chisel3/pull/1550 for more information
-trait AnalogBlackBoxModuleIntf extends Module {
- def io: AnalogBlackBoxIO
-}
-
-// AnalogBlackBox wrapper, which extends Module to present the common io._ interface
-class AnalogBlackBoxModule(index: Int) extends AnalogBlackBoxModuleIntf {
- val io = IO(new AnalogBlackBoxIO(1))
- val impl = Module(new AnalogBlackBox(index))
- io <> impl.io
-}
-
-// Wraps up n blackboxes, connecing their buses and simply forwarding their ports up
-class AnalogBlackBoxWrapper(n: Int, idxs: Seq[Int]) extends AnalogBlackBoxModuleIntf {
- require(n > 0)
- val io = IO(new AnalogBlackBoxIO(n))
- val bbs = idxs.map(i => Module(new AnalogBlackBoxModule(i)))
- io.bus <> bbs.head.io.bus // Always bulk connect io.bus to first bus
- io.port <> bbs.flatMap(_.io.port) // Connect ports
- attach(bbs.map(_.io.bus): _*) // Attach all the buses
-}
-
-// Common superclass for AnalogDUT and AnalogSmallDUT
-abstract class AnalogDUTModule(numBlackBoxes: Int) extends Module {
- require(numBlackBoxes > 0)
- val io = IO(new Bundle {
- val ports = Vec(numBlackBoxes, new AnalogBlackBoxPort)
- })
-}
-
-/** Single test case for lots of things
- *
- * $ - Wire at top connecting child inouts (Done in AnalogDUT)
- * $ - Port inout connected to 1 or more children inouts (AnalogBackBoxWrapper)
- * $ - Multiple port inouts connected (AnalogConnector)
- */
-class AnalogDUT extends AnalogDUTModule(5) { // 5 BlackBoxes
- val mods = Seq(
- Module(new AnalogBlackBoxWrapper(1, Seq(0))),
- Module(new AnalogBlackBoxModule(1)),
- Module(new AnalogBlackBoxWrapper(2, Seq(2, 3))), // 2 blackboxes
- Module(new AnalogBlackBoxModule(4))
- )
- // Connect all ports to top
- io.ports <> mods.flatMap(_.io.port)
- // Attach first 3 Modules
- attach(mods.take(3).map(_.io.bus): _*)
- // Attach last module to 1st through AnalogConnector
- val con = Module(new AnalogConnector)
- attach(con.io.bus1, mods.head.io.bus)
- attach(con.io.bus2, mods.last.io.bus)
-}
-
-/** Same as [[AnalogDUT]] except it omits [[AnalogConnector]] because that is currently not
- * supported by Verilator
- * @todo Delete once Verilator can handle [[AnalogDUT]]
- */
-class AnalogSmallDUT extends AnalogDUTModule(4) { // 4 BlackBoxes
- val mods = Seq(
- Module(new AnalogBlackBoxWrapper(1, Seq(0))),
- Module(new AnalogBlackBoxModule(1)),
- Module(new AnalogBlackBoxWrapper(2, Seq(2, 3))) // 2 BlackBoxes
- )
- // Connect all ports to top
- io.ports <> mods.flatMap(_.io.port)
- // Attach first 3 Modules
- attach(mods.take(3).map(_.io.bus): _*)
-}
-
-// This tester is primarily intended to be able to pass the dut to synthesis
-class AnalogIntegrationTester(mod: => AnalogDUTModule) extends BasicTester {
- val BusValue = 2.U(32.W) // arbitrary
-
- val dut = Module(mod)
-
- val expectedValue = Wire(UInt(32.W))
- expectedValue := BusValue // Overridden each cycle
-
- val (cycle, done) = Counter(true.B, dut.io.ports.size)
- for ((dut, idx) <- dut.io.ports.zipWithIndex) {
- printf(p"@$cycle: BlackBox #$idx: $dut\n")
- // Defaults
- dut.in.valid := false.B
- dut.in.bits := BusValue
- // Error checking
- assert(dut.out === expectedValue)
-
- when(cycle === idx.U) {
- expectedValue := BusValue + idx.U
- dut.in.valid := true.B
-
- }
- }
- when(done) { stop() }
-}
-
-class AnalogIntegrationSpec extends ChiselFlatSpec {
- behavior.of("Verilator")
- it should "support simple bidirectional wires" in {
- assertTesterPasses(
- new AnalogIntegrationTester(new AnalogSmallDUT),
- Seq("/chisel3/AnalogBlackBox.v"),
- TesterDriver.verilatorOnly
- )
- }
- // Use this test once Verilator supports alias
- ignore should "support arbitrary bidirectional wires" in {
- assertTesterPasses(
- new AnalogIntegrationTester(new AnalogDUT),
- Seq("/chisel3/AnalogBlackBox.v"),
- TesterDriver.verilatorOnly
- )
- }
-}
diff --git a/src/test/scala/chiselTests/AnalogSpec.scala b/src/test/scala/chiselTests/AnalogSpec.scala
deleted file mode 100644
index 3d03af78..00000000
--- a/src/test/scala/chiselTests/AnalogSpec.scala
+++ /dev/null
@@ -1,352 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.stage.ChiselStage
-import chisel3.util._
-import chisel3.testers.{BasicTester, TesterDriver}
-import chisel3.experimental.{attach, Analog, BaseModule}
-
-// IO for Modules that just connect bus to out
-class AnalogReaderIO extends Bundle {
- val bus = Analog(32.W)
- val out = Output(UInt(32.W))
-}
-// IO for Modules that drive bus from in (there should be only 1)
-class AnalogWriterIO extends Bundle {
- val bus = Analog(32.W)
- val in = Input(UInt(32.W))
-}
-
-trait AnalogReader {
- def out: UInt
- def bus: Analog
-}
-
-class AnalogReaderBlackBox extends BlackBox with AnalogReader {
- val io = IO(new AnalogReaderIO)
- def out = io.out
- def bus = io.bus
-}
-
-class AnalogReaderWrapper extends Module with AnalogReader {
- val io = IO(new AnalogReaderIO)
- def out = io.out
- def bus = io.bus
- val mod = Module(new AnalogReaderBlackBox)
- io <> mod.io
-}
-class AnalogWriterBlackBox extends BlackBox {
- val io = IO(new AnalogWriterIO)
-}
-// Connects two Analog ports
-class AnalogConnector extends Module {
- val io = IO(new Bundle {
- val bus1 = Analog(32.W)
- val bus2 = Analog(32.W)
- })
- io.bus1 <> io.bus2
-}
-
-class VecAnalogReaderWrapper extends RawModule with AnalogReader {
- val vecbus = IO(Vec(1, Analog(32.W)))
- val out = IO(Output(UInt(32.W)))
- val mod = Module(new AnalogReaderBlackBox)
- def bus = vecbus(0)
- mod.io.bus <> bus
- out := mod.io.out
-}
-
-class VecBundleAnalogReaderWrapper extends RawModule with AnalogReader {
- val vecBunBus = IO(
- Vec(
- 1,
- new Bundle {
- val analog = Analog(32.W)
- }
- )
- )
- def bus = vecBunBus(0).analog
- val out = IO(Output(UInt(32.W)))
- val mod = Module(new AnalogReaderBlackBox)
- mod.io.bus <> bus
- out := mod.io.out
-}
-
-// Parent class for tests connecing up AnalogReaders and AnalogWriters
-abstract class AnalogTester extends BasicTester {
- final val BusValue = "hdeadbeef".U
-
- final val (cycle, done) = Counter(true.B, 2)
- when(done) { stop() }
-
- final val writer = Module(new AnalogWriterBlackBox)
- writer.io.in := BusValue
-
- final def check(reader: BaseModule with AnalogReader): Unit =
- assert(reader.out === BusValue)
-}
-
-class AnalogSpec extends ChiselFlatSpec with Utils {
- behavior.of("Analog")
-
- it should "NOT be bindable to registers" in {
- a[ChiselException] should be thrownBy extractCause[ChiselException] {
- ChiselStage.elaborate {
- new Module {
- val io = IO(new Bundle {})
- val reg = Reg(Analog(32.W))
- }
- }
- }
- }
-
- it should "NOT be bindable to a direction" in {
- 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 extractCause[ChiselException] {
- ChiselStage.elaborate {
- new Module {
- val io = IO(new Bundle {
- val a = Output(Analog(32.W))
- })
- }
- }
- }
- }
-
- it should "be flippable" in {
- ChiselStage.elaborate {
- new Module {
- val io = IO(new Bundle {
- val a = Flipped(Analog(32.W))
- })
- }
- }
- }
-
- // 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 extractCause[ChiselException] {
- ChiselStage.elaborate {
- new Module {
- val io = IO(new Bundle {})
- val mem = Mem(16, Analog(32.W))
- }
- }
- }
- }
-
- it should "NOT be bindable to Mem ports" in {
- 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)
- }
- }
- }
- }
-
- // TODO This should probably be caught in Chisel
- // Also note this relies on executing Firrtl from Chisel directly
- it should "NOT be connectable to UInts" in {
- a[Exception] should be thrownBy {
- runTester {
- new BasicTester {
- val uint = WireDefault(0.U(32.W))
- val sint = Wire(Analog(32.W))
- sint := uint
- }
- }
- }
- }
-
- it should "work with 2 blackboxes bulk connected" in {
- assertTesterPasses(
- new AnalogTester {
- val mod = Module(new AnalogReaderBlackBox)
- mod.io.bus <> writer.io.bus
- check(mod)
- },
- Seq("/chisel3/AnalogBlackBox.v"),
- TesterDriver.verilatorOnly
- )
- }
-
- it should "error if any bulk connected more than once" in {
- 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 extractCause[ChiselException] {
- ChiselStage.elaborate(new Module {
- val io = IO(new Bundle {})
- val wires = List.fill(2)(Wire(Analog(32.W)))
- wires(0) <> DontCare
- wires(0) <> wires(1)
- })
- }
- }
-
- it should "allow DontCare connection" in {
- ChiselStage.elaborate(new Module {
- val io = IO(new Bundle {
- val a = Analog(1.W)
- })
- io.a := DontCare
- })
- ChiselStage.elaborate(new Module {
- val io = IO(new Bundle {
- val a = Analog(1.W)
- })
- io.a <> DontCare
- })
- }
-
- it should "work in bidirectional Aggregate wires" in {
- class MyBundle extends Bundle {
- val x = Input(UInt(8.W))
- val y = Analog(8.W)
- }
- ChiselStage.elaborate(new Module {
- val io = IO(new Bundle {
- val a = new MyBundle
- })
- val w = Wire(new MyBundle)
- w <> io.a
- })
- ChiselStage.elaborate(new Module {
- val io = IO(new Bundle {
- val a = Vec(1, new MyBundle)
- })
- val w = Wire(Vec(1, new MyBundle))
- w <> io.a
- })
- }
-
- it should "work with 3 blackboxes attached" in {
- assertTesterPasses(
- new AnalogTester {
- val mods = Seq.fill(2)(Module(new AnalogReaderBlackBox))
- attach(writer.io.bus, mods(0).io.bus, mods(1).io.bus)
- mods.foreach(check(_))
- },
- Seq("/chisel3/AnalogBlackBox.v"),
- TesterDriver.verilatorOnly
- )
- }
-
- it should "work with 3 blackboxes separately attached via a wire" in {
- assertTesterPasses(
- new AnalogTester {
- val mods = Seq.fill(2)(Module(new AnalogReaderBlackBox))
- val busWire = Wire(Analog(32.W))
- attach(busWire, writer.io.bus)
- attach(busWire, mods(0).io.bus)
- attach(mods(1).io.bus, busWire)
- mods.foreach(check(_))
- },
- Seq("/chisel3/AnalogBlackBox.v"),
- TesterDriver.verilatorOnly
- )
- }
-
- // This does not currently work in Verilator unless Firrtl does constant prop and dead code
- // elimination on these wires
- ignore should "work with intermediate wires attached to each other" in {
- assertTesterPasses(
- new AnalogTester {
- val mod = Module(new AnalogReaderBlackBox)
- val busWire = Seq.fill(2)(Wire(Analog(32.W)))
- attach(busWire(0), writer.io.bus)
- attach(busWire(1), mod.io.bus)
- attach(busWire(0), busWire(1))
- check(mod)
- },
- Seq("/chisel3/AnalogBlackBox.v"),
- TesterDriver.verilatorOnly
- )
- }
-
- it should "work with blackboxes at different levels of the module hierarchy" in {
- assertTesterPasses(
- new AnalogTester {
- val mods = Seq(Module(new AnalogReaderBlackBox), Module(new AnalogReaderWrapper))
- val busWire = Wire(writer.io.bus.cloneType)
- attach(writer.io.bus, mods(0).bus, mods(1).bus)
- mods.foreach(check(_))
- },
- Seq("/chisel3/AnalogBlackBox.v"),
- TesterDriver.verilatorOnly
- )
- }
-
- // This does not currently work in Verilator, but does work in VCS
- ignore should "support two analog ports in the same module" in {
- assertTesterPasses(
- new AnalogTester {
- val reader = Module(new AnalogReaderBlackBox)
- val connector = Module(new AnalogConnector)
- connector.io.bus1 <> writer.io.bus
- reader.io.bus <> connector.io.bus2
- check(reader)
- },
- Seq("/chisel3/AnalogBlackBox.v"),
- TesterDriver.verilatorOnly
- )
- }
-
- it should "NOT support conditional connection of analog types" in {
- a[ChiselException] should be thrownBy {
- assertTesterPasses(
- new AnalogTester {
- val mod = Module(new AnalogReaderBlackBox)
- when(cycle > 3.U) {
- mod.io.bus <> writer.io.bus
- }
- check(mod)
- },
- Seq("/chisel3/AnalogBlackBox.v")
- )
- }
- }
-
- it should "work with Vecs of Analog" in {
- assertTesterPasses(
- new AnalogTester {
- val mod = Module(new VecAnalogReaderWrapper)
- mod.bus <> writer.io.bus
- check(mod)
- },
- Seq("/chisel3/AnalogBlackBox.v"),
- TesterDriver.verilatorOnly
- )
- }
-
- it should "work with Vecs of Bundles of Analog" in {
- assertTesterPasses(
- new AnalogTester {
- val mod = Module(new VecBundleAnalogReaderWrapper)
- mod.bus <> writer.io.bus
- check(mod)
- },
- Seq("/chisel3/AnalogBlackBox.v"),
- TesterDriver.verilatorOnly
- )
- }
-}
diff --git a/src/test/scala/chiselTests/AnnotatingDiamondSpec.scala b/src/test/scala/chiselTests/AnnotatingDiamondSpec.scala
deleted file mode 100644
index af73d5d4..00000000
--- a/src/test/scala/chiselTests/AnnotatingDiamondSpec.scala
+++ /dev/null
@@ -1,166 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.experimental.{annotate, ChiselAnnotation, RunFirrtlTransform}
-import chisel3.internal.InstanceId
-import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage}
-import chisel3.testers.BasicTester
-import firrtl.{CircuitForm, CircuitState, DependencyAPIMigration, LowForm, Transform}
-import firrtl.annotations.{CircuitName, CircuitTarget, SingleTargetAnnotation, Target}
-import firrtl.stage.Forms
-import org.scalatest._
-import org.scalatest.freespec.AnyFreeSpec
-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: 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)
- extends ChiselAnnotation
- with RunFirrtlTransform {
- def toFirrtl: IdentityAnnotation = IdentityAnnotation(target.toNamed, value)
- def transformClass: Class[IdentityTransform] = classOf[IdentityTransform]
-}
-object identify {
- def apply(component: InstanceId, value: String): Unit = {
- val anno = IdentityChiselAnnotation(component, value)
- annotate(anno)
- }
-}
-
-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 {
- case IdentityAnnotation(t, value) => IdentityAnnotation(t, value + ":seen")
- case other => other
- }
- state.copy(annotations = annosx)
- }
-}
-
-/** A diamond circuit Top instantiates A and B and both A and B instantiate C
- * Illustrations of annotations of various components and modules in both
- * relative and absolute cases
- *
- * This is currently not much of a test, read the printout to see what annotations look like
- */
-/**
- * This class has parameterizable widths, it will generate different hardware
- * @param widthC io width
- */
-class ModC(widthC: Int) extends Module {
- val io = IO(new Bundle {
- val in = Input(UInt(widthC.W))
- val out = Output(UInt(widthC.W))
- })
- io.out := io.in
-
- identify(this, s"ModC($widthC)")
-
- identify(io.out, s"ModC(ignore param)")
-}
-
-/**
- * instantiates a C of a particular size, ModA does not generate different hardware
- * based on it's parameter
- * @param annoParam parameter is only used in annotation not in circuit
- */
-class ModA(annoParam: Int) extends Module {
- val io = IO(new Bundle {
- val in = Input(UInt())
- val out = Output(UInt())
- })
- val modC = Module(new ModC(16))
- modC.io.in := io.in
- io.out := modC.io.out
-
- identify(this, s"ModA(ignore param)")
-
- identify(io.out, s"ModA.io.out($annoParam)")
- identify(io.out, s"ModA.io.out(ignore_param)")
-}
-
-class ModB(widthB: Int) extends Module {
- val io = IO(new Bundle {
- val in = Input(UInt(widthB.W))
- val out = Output(UInt(widthB.W))
- })
- val modC = Module(new ModC(widthB))
- modC.io.in := io.in
- io.out := modC.io.out
-
- identify(io.in, s"modB.io.in annotated from inside modB")
-}
-
-class TopOfDiamond extends Module {
- val io = IO(new Bundle {
- val in = Input(UInt(32.W))
- val out = Output(UInt(32.W))
- })
- val x = Reg(UInt(32.W))
- val y = Reg(UInt(32.W))
-
- val modA = Module(new ModA(64))
- val modB = Module(new ModB(32))
-
- x := io.in
- modA.io.in := x
- modB.io.in := x
-
- y := modA.io.out + modB.io.out
- io.out := y
-
- identify(this, s"TopOfDiamond\nWith\nSome new lines")
-
- identify(modB.io.in, s"modB.io.in annotated from outside modB")
-}
-
-class DiamondTester extends BasicTester {
- val dut = Module(new TopOfDiamond)
-
- stop()
-}
-
-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 {
-
- 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
deleted file mode 100644
index 2150f925..00000000
--- a/src/test/scala/chiselTests/AnnotationNoDedup.scala
+++ /dev/null
@@ -1,79 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.experimental.doNotDedup
-import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage}
-import firrtl.stage.FirrtlCircuitAnnotation
-import org.scalatest.freespec.AnyFreeSpec
-import org.scalatest.matchers.should.Matchers
-
-class MuchUsedModule extends Module {
- val io = IO(new Bundle {
- val in = Input(UInt(16.W))
- val out = Output(UInt(16.W))
- })
- io.out := io.in +% 1.U
-}
-
-class UsesMuchUsedModule(addAnnos: Boolean) extends Module {
- val io = IO(new Bundle {
- val in = Input(UInt(16.W))
- val out = Output(UInt(16.W))
- })
-
- val mod0 = Module(new MuchUsedModule)
- val mod1 = Module(new MuchUsedModule)
- val mod2 = Module(new MuchUsedModule)
- val mod3 = Module(new MuchUsedModule)
-
- mod0.io.in := io.in
- mod1.io.in := mod0.io.out
- mod2.io.in := mod1.io.out
- mod3.io.in := mod2.io.out
- io.out := mod3.io.out
-
- if (addAnnos) {
- doNotDedup(mod1)
- doNotDedup(mod3)
- }
-}
-
-class AnnotationNoDedup extends AnyFreeSpec with Matchers {
- val stage = new ChiselStage
- "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 {
- 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 {
- 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 :")
- }
- }
-}
diff --git a/src/test/scala/chiselTests/AsTypeOfTester.scala b/src/test/scala/chiselTests/AsTypeOfTester.scala
deleted file mode 100644
index a1668914..00000000
--- a/src/test/scala/chiselTests/AsTypeOfTester.scala
+++ /dev/null
@@ -1,155 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.experimental.{DataMirror, FixedPoint}
-import chisel3.testers.BasicTester
-
-class AsTypeOfBundleTester extends BasicTester {
- class MultiTypeBundle extends Bundle {
- val u = UInt(4.W)
- val s = SInt(4.W)
- val fp = FixedPoint(4.W, 3.BP)
- }
-
- val bun = new MultiTypeBundle
-
- val bunAsTypeOf = ((4 << 8) + (15 << 4) + (12 << 0)).U.asTypeOf(bun)
-
- assert(bunAsTypeOf.u === 4.U)
- assert(bunAsTypeOf.s === -1.S)
- assert(bunAsTypeOf.fp === FixedPoint.fromDouble(-0.5, 4.W, 3.BP))
-
- stop()
-}
-
-class AsTypeOfBundleZeroWidthTester extends BasicTester {
- class ZeroWidthBundle extends Bundle {
- val a = UInt(0.W)
- val b = UInt(1.W)
- val c = UInt(0.W)
- }
-
- val bun = new ZeroWidthBundle
-
- val bunAsTypeOf = 1.U.asTypeOf(bun)
-
- assert(bunAsTypeOf.a === 0.U)
- assert(bunAsTypeOf.b === 1.U)
- assert(bunAsTypeOf.c === 0.U)
-
- stop()
-}
-
-class AsTypeOfVecTester extends BasicTester {
- val vec = ((15 << 12) + (0 << 8) + (1 << 4) + (2 << 0)).U.asTypeOf(Vec(4, SInt(4.W)))
-
- assert(vec(0) === 2.S)
- assert(vec(1) === 1.S)
- assert(vec(2) === 0.S)
- assert(vec(3) === -1.S)
-
- stop()
-}
-
-class AsTypeOfTruncationTester extends BasicTester {
- val truncate = (64 + 3).U.asTypeOf(UInt(3.W))
- val expand = 1.U.asTypeOf(UInt(3.W))
-
- assert(DataMirror.widthOf(truncate).get == 3)
- assert(truncate === 3.U)
- assert(DataMirror.widthOf(expand).get == 3)
- assert(expand === 1.U)
-
- stop()
-}
-
-class ResetAsTypeOfBoolTester extends BasicTester {
- assert(reset.asTypeOf(Bool()) === reset.asBool)
- stop()
-}
-
-class AsTypeOfClockTester extends BasicTester {
- class MyBundle extends Bundle {
- val x = UInt(4.W)
- val y = Clock()
- }
- assert(true.B.asTypeOf(Clock()).asUInt.asBool === true.B)
-
- assert(0x1f.U.asTypeOf(new MyBundle).asUInt === 0x1f.U)
- stop()
-}
-
-class AsChiselEnumTester extends BasicTester {
- object MyEnum extends ChiselEnum {
- val foo, bar = Value
- val fizz = Value(2.U)
- }
- class MyBundle extends Bundle {
- val a = Bool()
- val b = Bool()
- }
-
- // To
- assert(2.U.asTypeOf(MyEnum()) === MyEnum.fizz)
- assert(VecInit(2.U.asBools).asTypeOf(MyEnum()) === MyEnum.fizz)
- assert(2.U.asTypeOf(new MyBundle).asTypeOf(MyEnum()) === MyEnum.fizz)
-
- // From
- assert(MyEnum.foo.asUInt === 0.U)
- val vec = MyEnum.bar.asTypeOf(Vec(2, Bool()))
- assert(vec(0) === 1.U)
- assert(vec(1) === 0.U)
- val bun = MyEnum.fizz.asTypeOf(new MyBundle)
- assert(bun.b === 0.U)
- assert(bun.a === 1.U)
-
- // In aggregate
- class OtherBundle extends Bundle {
- val enum = MyEnum()
- val foo = Bool()
- }
- val wire = Wire(new OtherBundle)
- wire.enum := MyEnum.fizz
- wire.foo := true.B
-
- assert(wire.asUInt === 5.U)
- val other = 5.U.asTypeOf(new OtherBundle)
- assert(other.enum === MyEnum.fizz)
- assert(other.foo === true.B)
-
- stop()
-}
-
-class AsTypeOfSpec extends ChiselFlatSpec {
- behavior.of("asTypeOf")
-
- it should "work with Bundles containing Bits Types" in {
- assertTesterPasses { new AsTypeOfBundleTester }
- }
-
- it should "work with Bundles that have fields of zero width" in {
- assertTesterPasses { new AsTypeOfBundleZeroWidthTester }
- }
-
- it should "work with Vecs containing Bits Types" in {
- assertTesterPasses { new AsTypeOfVecTester }
- }
-
- it should "expand and truncate UInts of different width" in {
- assertTesterPasses { new AsTypeOfTruncationTester }
- }
-
- it should "work for casting implicit Reset to Bool" in {
- assertTesterPasses { new ResetAsTypeOfBoolTester }
- }
-
- it should "work for casting to and from ChiselEnums" in {
- assertTesterPasses(new AsChiselEnumTester)
- }
-
- it should "work for casting to and from Clock" in {
- assertTesterPasses(new AsTypeOfClockTester)
- }
-}
diff --git a/src/test/scala/chiselTests/Assert.scala b/src/test/scala/chiselTests/Assert.scala
deleted file mode 100644
index 5e7b6496..00000000
--- a/src/test/scala/chiselTests/Assert.scala
+++ /dev/null
@@ -1,205 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.stage.ChiselStage
-import chisel3.testers.BasicTester
-import chisel3.util._
-
-class FailingAssertTester() extends BasicTester {
- assert(false.B)
- // Wait to come out of reset
- val (_, done) = Counter(!reset.asBool, 4)
- when(done) {
- stop()
- }
-}
-
-class SucceedingAssertTester() extends BasicTester {
- assert(true.B)
- // Wait to come out of reset
- val (_, done) = Counter(!reset.asBool, 4)
- when(done) {
- stop()
- }
-}
-
-class PipelinedResetModule extends Module {
- val io = IO(new Bundle {})
- val a = RegInit(0xbeef.U)
- val b = RegInit(0xbeef.U)
- assert(a === b)
-}
-
-// This relies on reset being asserted for 3 or more cycles
-class PipelinedResetTester extends BasicTester {
- val module = Module(new PipelinedResetModule)
-
- module.reset := RegNext(RegNext(RegNext(reset)))
-
- val (_, done) = Counter(!reset.asBool, 4)
- when(done) {
- stop()
- }
-}
-
-class ModuloAssertTester extends BasicTester {
- assert((4.U % 2.U) === 0.U)
- stop()
-}
-
-class FormattedAssertTester extends BasicTester {
- val foobar = Wire(UInt(32.W))
- foobar := 123.U
- assert(foobar === 123.U, "Error! Wire foobar =/= %x! This is 100%% wrong.\n", foobar)
- stop()
-}
-
-class BadUnescapedPercentAssertTester extends BasicTester {
- assert(1.U === 1.U, "I'm 110% sure this is an invalid message")
- stop()
-}
-
-class PrintableFormattedAssertTester extends BasicTester {
- val foobar = Wire(UInt(32.W))
- foobar := 123.U
- assert(foobar === 123.U, cf"Error! Wire foobar =/= $foobar%x This is 100%% wrong.\n")
- stop()
-}
-
-class PrintableBadUnescapedPercentAssertTester extends BasicTester {
- assert(1.U === 1.U, p"I'm 110% sure this is an invalid message")
- stop()
-}
-
-class PrintableAssumeTester extends Module {
- val in = IO(Input(UInt(8.W)))
- val out = IO(Output(UInt(8.W)))
-
- val w = Wire(UInt(8.W))
- w := 255.U
- assume(w === 255.U, cf"Assumption failed, Wire w =/= $w%x")
-
- out := in
-}
-
-class PrintableScopeTester extends Module {
- val in = IO(Input(UInt(8.W)))
- val out = IO(Output(UInt(8.W)))
- out := in
-
- val w = Wire(UInt(8.W))
- w := 255.U
-
- val printableWire = cf"$w"
- val printablePort = cf"$in"
-}
-
-class AssertPrintableWireScope extends BasicTester {
- val mod = Module(new PrintableScopeTester)
- assert(1.U === 2.U, mod.printableWire)
- stop()
-}
-
-class AssertPrintablePortScope extends BasicTester {
- val mod = Module(new PrintableScopeTester)
- mod.in := 255.U
- assert(1.U === 1.U, mod.printablePort)
- stop()
-}
-
-class AssertPrintableFailingWhenScope extends BasicTester {
- val mod = Module(new PrintableWhenScopeTester)
- assert(1.U === 1.U, mod.printable)
- stop()
-}
-
-class AssumePrintableWireScope extends BasicTester {
- val mod = Module(new PrintableScopeTester)
- assume(1.U === 1.U, mod.printableWire)
- stop()
-}
-
-class AssumePrintablePortScope extends BasicTester {
- val mod = Module(new PrintableScopeTester)
- mod.in := 255.U
- assume(1.U === 1.U, mod.printablePort)
- stop()
-}
-
-class PrintableWhenScopeTester extends Module {
- val in = IO(Input(UInt(8.W)))
- val out = IO(Output(UInt(8.W)))
-
- out := in
-
- val w = Wire(UInt(8.W))
- w := 255.U
- var printable = cf""
- when(true.B) {
- printable = cf"$w"
- }
-}
-
-class AssertSpec extends ChiselFlatSpec with Utils {
- "A failing assertion" should "fail the testbench" in {
- assert(!runTester { new FailingAssertTester })
- }
- "A succeeding assertion" should "not fail the testbench" in {
- assertTesterPasses { new SucceedingAssertTester }
- }
- "An assertion" should "not assert until we come out of reset" in {
- assertTesterPasses { new PipelinedResetTester }
- }
-
- "Assert Printables" should "respect port scoping" in {
- assertTesterPasses { new AssertPrintablePortScope }
- }
- "Assert Printables" should "respect wire scoping" in {
- a[ChiselException] should be thrownBy { ChiselStage.elaborate(new AssertPrintableWireScope) }
- }
- "Assume Printables" should "respect port scoping" in {
- assertTesterPasses { new AssumePrintablePortScope }
- }
-
- "Assume Printables" should "respect wire scoping" in {
- a[ChiselException] should be thrownBy { ChiselStage.elaborate(new AssumePrintableWireScope) }
- }
-
- "Assert Printables" should "respect when scope" in {
- a[ChiselException] should be thrownBy { ChiselStage.elaborate(new AssertPrintableFailingWhenScope) }
- }
-
- "Assertions" should "allow the modulo operator % in the message" in {
- assertTesterPasses { new ModuloAssertTester }
- }
- they should "allow printf-style format strings with arguments" in {
- assertTesterPasses { new FormattedAssertTester }
- }
- they should "allow printf-style format strings in Assumes" in {
- val chirrtl = ChiselStage.emitChirrtl(new PrintableAssumeTester)
- chirrtl should include(
- """assume(w === 255.U, cf\"Assumption failed, Wire w =/= $w%%%%x\")\n", w)"""
- )
- }
- they should "not allow unescaped % in the message" in {
- a[java.util.UnknownFormatConversionException] should be thrownBy {
- extractCause[java.util.UnknownFormatConversionException] {
- ChiselStage.elaborate { new BadUnescapedPercentAssertTester }
- }
- }
- }
-
- they should "allow printable format strings with arguments" in {
- assertTesterPasses { new FormattedAssertTester }
- }
- they should "not allow unescaped % in the printable message" in {
- a[java.util.UnknownFormatConversionException] should be thrownBy {
- extractCause[java.util.UnknownFormatConversionException] {
- ChiselStage.elaborate { new BadUnescapedPercentAssertTester }
- }
- }
- }
-
-}
diff --git a/src/test/scala/chiselTests/AsyncResetSpec.scala b/src/test/scala/chiselTests/AsyncResetSpec.scala
deleted file mode 100644
index ac7ae0d1..00000000
--- a/src/test/scala/chiselTests/AsyncResetSpec.scala
+++ /dev/null
@@ -1,274 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.stage.ChiselStage
-import chisel3.util.{Counter, Queue}
-import chisel3.testers.BasicTester
-import firrtl.checks.CheckResets.NonLiteralAsyncResetValueException
-
-class AsyncResetTester extends BasicTester {
- val (_, cDiv) = Counter(true.B, 4)
- // First rising edge when count === 3
- val slowClk = cDiv.asClock
-
- val (count, done) = Counter(true.B, 16)
-
- val asyncResetNext = RegInit(false.B)
- asyncResetNext := count === 4.U
- val asyncReset = asyncResetNext.asAsyncReset
-
- val reg = withClockAndReset(slowClk, asyncReset) {
- RegInit(123.U(8.W))
- }
- reg := 5.U // Normal connection
-
- when(count === 3.U) {
- assert(reg === 5.U)
- }
- when(count >= 5.U && count < 7.U) {
- assert(reg === 123.U)
- }.elsewhen(count >= 7.U) {
- assert(reg === 5.U)
- }
-
- when(done) {
- stop()
- }
-}
-
-class AsyncResetAggregateTester extends BasicTester {
- class MyBundle extends Bundle {
- val x = UInt(8.W)
- val y = UInt(8.W)
- }
- val (_, cDiv) = Counter(true.B, 4)
- // First rising edge when count === 3
- val slowClk = cDiv.asClock
-
- val (count, done) = Counter(true.B, 16)
-
- val asyncResetNext = RegInit(false.B)
- asyncResetNext := count === 4.U
- val asyncReset = asyncResetNext.asAsyncReset
-
- val reg = withClockAndReset(slowClk, asyncReset) {
- val init = Wire(Vec(2, new MyBundle))
- init(0).x := 0.U
- init(0).y := 0.U
- init(1).x := 0.U
- init(1).y := 0.U
- RegInit(init)
- }
- reg(0).x := 5.U // Normal connections
- reg(0).y := 6.U
- reg(1).x := 7.U
- reg(1).y := 8.U
-
- when(count === 3.U) {
- assert(reg(0).x === 5.U)
- assert(reg(0).y === 6.U)
- assert(reg(1).x === 7.U)
- assert(reg(1).y === 8.U)
- }
- when(count >= 5.U && count < 7.U) {
- assert(reg(0).x === 0.U)
- assert(reg(0).y === 0.U)
- assert(reg(1).x === 0.U)
- assert(reg(1).y === 0.U)
- }.elsewhen(count >= 7.U) {
- assert(reg(0).x === 5.U)
- assert(reg(0).y === 6.U)
- assert(reg(1).x === 7.U)
- assert(reg(1).y === 8.U)
- }
-
- when(done) {
- stop()
- }
-}
-
-class AsyncResetQueueTester extends BasicTester {
- val (_, cDiv) = Counter(true.B, 4)
- val slowClk = cDiv.asClock
-
- val (count, done) = Counter(true.B, 16)
-
- val asyncResetNext = RegNext(false.B, false.B)
- val asyncReset = asyncResetNext.asAsyncReset
-
- val queue = withClockAndReset(slowClk, asyncReset) {
- Module(new Queue(UInt(8.W), 4))
- }
- queue.io.enq.valid := true.B
- queue.io.enq.bits := count
-
- queue.io.deq.ready := false.B
-
- val doCheck = RegNext(false.B, false.B)
- when(queue.io.count === 3.U) {
- asyncResetNext := true.B
- doCheck := true.B
- }
- when(doCheck) {
- assert(queue.io.count === 0.U)
- }
-
- when(done) {
- stop()
- }
-}
-
-class AsyncResetDontCareModule extends RawModule {
- import chisel3.util.Valid
- val monoPort = IO(Output(AsyncReset()))
- monoPort := DontCare
- val monoWire = Wire(AsyncReset())
- monoWire := DontCare
- val monoAggPort = IO(Output(Valid(AsyncReset())))
- monoAggPort := DontCare
- val monoAggWire = Wire(Valid(AsyncReset()))
- monoAggWire := DontCare
-
- // Can't bulk connect to Wire so only ports here
- val bulkPort = IO(Output(AsyncReset()))
- bulkPort <> DontCare
- val bulkAggPort = IO(Output(Valid(AsyncReset())))
- bulkAggPort <> DontCare
-}
-
-class AsyncResetSpec extends ChiselFlatSpec with Utils {
-
- behavior.of("AsyncReset")
-
- it should "be able to be connected to DontCare" in {
- ChiselStage.elaborate(new AsyncResetDontCareModule)
- }
-
- it should "be allowed with literal reset values" in {
- ChiselStage.elaborate(new BasicTester {
- withReset(reset.asAsyncReset)(RegInit(123.U))
- })
- }
-
- it should "NOT be allowed with non-literal reset values" in {
- a[NonLiteralAsyncResetValueException] should be thrownBy extractCause[NonLiteralAsyncResetValueException] {
- compile(new BasicTester {
- val x = WireInit(123.U + 456.U)
- withReset(reset.asAsyncReset)(RegInit(x))
- })
- }
- }
-
- it should "NOT be allowed to connect directly to a Bool" in {
- a[ChiselException] should be thrownBy extractCause[ChiselException] {
- ChiselStage.elaborate(new BasicTester {
- val bool = Wire(Bool())
- val areset = reset.asAsyncReset
- bool := areset
- })
- }
- }
-
- it should "simulate correctly" in {
- assertTesterPasses(new AsyncResetTester)
- }
-
- it should "simulate correctly with aggregates" in {
- assertTesterPasses(new AsyncResetAggregateTester)
- }
-
- it should "allow casting to and from Bool" in {
- ChiselStage.elaborate(new BasicTester {
- val r: Reset = reset
- val a: AsyncReset = WireInit(r.asAsyncReset)
- val b: Bool = a.asBool
- val c: AsyncReset = b.asAsyncReset
- })
- }
-
- it should "allow changing the reset type of whole modules like Queue" in {
- assertTesterPasses(new AsyncResetQueueTester)
- }
-
- it should "support SInt regs" in {
- assertTesterPasses(new BasicTester {
- // Also check that it traces through wires
- val initValue = Wire(SInt())
- val reg = withReset(reset.asAsyncReset)(RegNext(initValue, 27.S))
- initValue := -43.S
- val (count, done) = Counter(true.B, 4)
- when(count === 0.U) {
- chisel3.assert(reg === 27.S)
- }.otherwise {
- chisel3.assert(reg === -43.S)
- }
- when(done) { stop() }
- })
- }
-
- it should "support Fixed regs" in {
- assertTesterPasses(new BasicTester {
- val reg = withReset(reset.asAsyncReset)(RegNext(-6.0.F(2.BP), 3.F(2.BP)))
- val (count, done) = Counter(true.B, 4)
- when(count === 0.U) {
- chisel3.assert(reg === 3.F(2.BP))
- }.otherwise {
- chisel3.assert(reg === -6.0.F(2.BP))
- }
- when(done) { stop() }
- })
- }
-
- it should "support Interval regs" in {
- import chisel3.experimental._
- assertTesterPasses(new BasicTester {
- val reg = withReset(reset.asAsyncReset) {
- val x = RegInit(Interval(range"[0,13]"), 13.I)
- x := 7.I
- x
- }
- val (count, done) = Counter(true.B, 4)
- when(count === 0.U) {
- chisel3.assert(reg === 13.I)
- }.otherwise {
- chisel3.assert(reg === 7.I)
- }
- when(done) { stop() }
- })
- }
-
- it should "allow literals cast to Bundles as reset values" in {
- class MyBundle extends Bundle {
- val x = UInt(16.W)
- val y = UInt(16.W)
- }
- assertTesterPasses(new BasicTester {
- val reg = withReset(reset.asAsyncReset) {
- RegNext(0xbad0cad0L.U.asTypeOf(new MyBundle), 0xdeadbeefL.U.asTypeOf(new MyBundle))
- }
- val (count, done) = Counter(true.B, 4)
- when(count === 0.U) {
- chisel3.assert(reg.asUInt === 0xdeadbeefL.U)
- }.otherwise {
- chisel3.assert(reg.asUInt === 0xbad0cad0L.U)
- }
- when(done) { stop() }
- })
- }
- it should "allow literals cast to Vecs as reset values" in {
- assertTesterPasses(new BasicTester {
- val reg = withReset(reset.asAsyncReset) {
- RegNext(0xbad0cad0L.U.asTypeOf(Vec(4, UInt(8.W))), 0xdeadbeefL.U.asTypeOf(Vec(4, UInt(8.W))))
- }
- val (count, done) = Counter(true.B, 4)
- when(count === 0.U) {
- chisel3.assert(reg.asUInt === 0xdeadbeefL.U)
- }.otherwise {
- chisel3.assert(reg.asUInt === 0xbad0cad0L.U)
- }
- when(done) { stop() }
- })
- }
-}
diff --git a/src/test/scala/chiselTests/AutoClonetypeSpec.scala b/src/test/scala/chiselTests/AutoClonetypeSpec.scala
deleted file mode 100644
index 353ae58c..00000000
--- a/src/test/scala/chiselTests/AutoClonetypeSpec.scala
+++ /dev/null
@@ -1,444 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.testers.TestUtils
-import chisel3.util.QueueIO
-import chisel3.stage.ChiselStage.elaborate
-import chisel3.experimental.AutoCloneType
-import scala.collection.immutable.ListMap
-
-class BundleWithIntArg(val i: Int) extends Bundle {
- val out = UInt(i.W)
-}
-
-class BundleWithImplicit()(implicit val ii: Int) extends Bundle {
- val out = UInt(ii.W)
-}
-
-class BundleWithArgAndImplicit(val i: Int)(implicit val ii: Int) extends Bundle {
- val out1 = UInt(i.W)
- val out2 = UInt(ii.W)
-}
-
-class BaseBundleVal(val i: Int) extends Bundle {
- val inner = UInt(i.W)
-}
-class SubBundle(i: Int, val i2: Int) extends BaseBundleVal(i) {
- val inner2 = UInt(i2.W)
-}
-class SubBundleInvalid(i: Int, val i2: Int) extends BaseBundleVal(i + 1) {
- val inner2 = UInt(i2.W)
-}
-
-class BaseBundleNonVal(i: Int) extends Bundle {
- val inner = UInt(i.W)
-}
-class SubBundleVal(val i: Int, val i2: Int) extends BaseBundleNonVal(i) {
- val inner2 = UInt(i2.W)
-}
-
-class ModuleWithInner extends Module {
- class InnerBundle(val i: Int) extends Bundle {
- val out = UInt(i.W)
- }
-
- val io = IO(new Bundle {})
-
- val myWire = Wire(new InnerBundle(14))
- require(myWire.i == 14)
-}
-
-object CompanionObjectWithBundle {
- class ParameterizedInner(val i: Int) extends Bundle {
- val data = UInt(i.W)
- }
- class Inner extends Bundle {
- val data = UInt(8.W)
- }
-}
-
-class NestedAnonymousBundle extends Bundle {
- val a = Output(new Bundle {
- val a = UInt(8.W)
- })
-}
-
-// A Bundle with an argument that is also a field.
-// Not necessarily good style (and not necessarily recommended), but allowed to preserve compatibility.
-class BundleWithArgumentField(val x: Data, val y: Data) extends Bundle
-
-// Needs to be top-level so that reflective autoclonetype works
-class InheritingBundle extends QueueIO(UInt(8.W), 8) {
- val error = Output(Bool())
-}
-
-class RecordAutoCloneType[T <: Data](gen: T) extends Record with AutoCloneType {
- lazy val elements = ListMap("value" -> gen)
- // This is a weird thing to do, but as only Bundles have these methods, it should be legal
- protected def _elementsImpl: Iterable[(String, Any)] = elements
- protected def _usingPlugin = false
-}
-
-// Records that don't mixin AutoCloneType should still be able to implement the related methods
-// NOTE: This is a very weird thing to do, don't do it.
-class RecordWithVerbotenMethods(w: Int) extends Record {
- lazy val elements = ListMap("value" -> UInt(w.W))
- override def cloneType: this.type = (new RecordWithVerbotenMethods(w)).asInstanceOf[this.type]
- // Verboten methods
- protected def _usingPlugin = false
- protected override def _cloneTypeImpl = this.cloneType
-
- protected def _elementsImpl: Iterable[(String, Any)] = Nil
-}
-
-class AutoClonetypeSpec extends ChiselFlatSpec with Utils {
-
- "Bundles with Scala args" should "not need clonetype" in {
- elaborate {
- new Module {
- val io = IO(new Bundle {})
-
- val myWire = Wire(new BundleWithIntArg(8))
- assert(myWire.i == 8)
- }
- }
- }
-
- "Bundles with Scala implicit args" should "not need clonetype" in {
- elaborate {
- new Module {
- val io = IO(new Bundle {})
-
- implicit val implicitInt: Int = 4
- val myWire = Wire(new BundleWithImplicit())
-
- assert(myWire.ii == 4)
- }
- }
- }
-
- "Bundles with Scala explicit and impicit args" should "not need clonetype" in {
- elaborate {
- new Module {
- val io = IO(new Bundle {})
-
- implicit val implicitInt: Int = 4
- val myWire = Wire(new BundleWithArgAndImplicit(8))
-
- assert(myWire.i == 8)
- assert(myWire.ii == 4)
- }
- }
- }
-
- "Subtyped Bundles" should "not need clonetype" in {
- elaborate {
- new Module {
- val io = IO(new Bundle {})
-
- val myWire = Wire(new SubBundle(8, 4))
-
- assert(myWire.i == 8)
- assert(myWire.i2 == 4)
- }
- }
- elaborate {
- new Module {
- val io = IO(new Bundle {})
-
- val myWire = Wire(new SubBundleVal(8, 4))
-
- assert(myWire.i == 8)
- assert(myWire.i2 == 4)
- }
- }
- }
-
- "Autoclonetype" should "work outside of a builder context" in {
- new BundleWithIntArg(8).cloneType
- }
-
- "Subtyped Bundles that don't clone well" should "be now be supported!" in {
- elaborate {
- new Module {
- val io = IO(new Bundle {})
- val myWire = Wire(new SubBundleInvalid(8, 4))
- }
- }
- }
-
- "Inner bundles with Scala args" should "not need clonetype" in {
- elaborate { new ModuleWithInner }
- }
-
- "Bundles with arguments as fields" should "not need clonetype" in {
- elaborate {
- new Module {
- val io = IO(Output(new BundleWithArgumentField(UInt(8.W), UInt(8.W))))
- io.x := 1.U
- io.y := 1.U
- }
- }
- }
-
- it should "also work when giving directions to the fields" in {
- elaborate {
- new Module {
- val io = IO(new BundleWithArgumentField(Input(UInt(8.W)), Output(UInt(8.W))))
- io.y := io.x
- }
- }
- }
-
- "Bundles inside companion objects" should "not need clonetype" in {
- 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 {
- val io = IO(Output(new CompanionObjectWithBundle.ParameterizedInner(8)))
- io.data := 1.U
- }
- }
- }
-
- "Nested directioned anonymous Bundles" should "not need clonetype" in {
- elaborate {
- new Module {
- val io = IO(new NestedAnonymousBundle)
- val a = WireDefault(io)
- io.a.a := 1.U
- }
- }
- }
-
- "3.0 null compatibility" should "not need clonetype" in {
- elaborate {
- new Module {
- class InnerClassThing {
- def createBundle: Bundle = new Bundle {
- val a = Output(UInt(8.W))
- }
- }
- val io = IO((new InnerClassThing).createBundle)
- val a = WireDefault(io)
- }
- }
- }
-
- "Aliased fields" should "be caught" in {
- a[ChiselException] should be thrownBy extractCause[ChiselException] {
- elaborate {
- new Module {
- val bundleFieldType = UInt(8.W)
- val io = IO(Output(new Bundle {
- val a = bundleFieldType
- }))
- io.a := 0.U
- }
- }
- }
- }
-
- "Aliased fields from inadequate autoclonetype" should "be caught" in {
- a[ChiselException] should be thrownBy extractCause[ChiselException] {
- class BadBundle(val typeTuple: (Data, Int)) extends Bundle {
- val a = typeTuple._1
- }
-
- elaborate {
- new Module {
- val io = IO(Output(new BadBundle(UInt(8.W), 1)))
- io.a := 0.U
- }
- }
- }
- }
-
- "Wrapped IO construction without parent reference" should "not fail for autoclonetype" in {
- class TestModule extends Module {
- def thunk[T](f: => T): T = f
- val works = thunk(IO(new Bundle {
- val x = Output(UInt(3.W))
- }))
- }
- elaborate { new TestModule }
- }
-
- "Wrapped IO construction with parent references" should "not fail for autoclonetype" in {
- class TestModule(blah: Int) extends Module {
- // Note that this currently fails only if f: =>T on Scala 2.11.12
- // This works successfully with 2.12.11
- def thunk[T](f: => T): T = f
- val broken = thunk(IO(new Bundle {
- val x = Output(UInt(blah.W))
- }))
- }
- elaborate { new TestModule(3) }
- }
-
- "Autoclonetype" should "support Bundles with if-blocks" in {
- class MyModule(n: Int) extends MultiIOModule {
- val io = IO(new Bundle {
- val in = Input(UInt(8.W))
- val out = Output(UInt(8.W))
- if (n > 4) {
- println("Here we are!")
- }
- })
- io.out := io.in
- }
- elaborate(new MyModule(3))
- }
-
- behavior.of("Compiler Plugin Autoclonetype")
-
- it should "NOT break code that extends chisel3.util Bundles if they use the plugin" in {
- class MyModule extends MultiIOModule {
- val io = IO(new InheritingBundle)
- io.deq <> io.enq
- io.count := 0.U
- io.error := true.B
- }
- elaborate(new MyModule)
- }
-
- it should "support Bundles with non-val parameters" in {
- class MyBundle(i: Int) extends Bundle {
- val foo = UInt(i.W)
- }
- elaborate {
- new MultiIOModule {
- val in = IO(Input(new MyBundle(8)))
- val out = IO(Output(new MyBundle(8)))
- out := in
- }
- }
- }
-
- it should "support type-parameterized Bundles" in {
- class MyBundle[T <: Data](gen: T) extends Bundle {
- val foo = gen
- }
- elaborate {
- new MultiIOModule {
- val in = IO(Input(new MyBundle(UInt(8.W))))
- val out = IO(Output(new MyBundle(UInt(8.W))))
- out := in
- }
- }
- }
-
- it should "support Bundles with non-val implicit parameters" in {
- class MyBundle(implicit i: Int) extends Bundle {
- val foo = UInt(i.W)
- }
- elaborate {
- new MultiIOModule {
- implicit val x = 8
- val in = IO(Input(new MyBundle))
- val out = IO(Output(new MyBundle))
- out := in
- }
- }
- }
-
- it should "support Bundles with multiple parameter lists" in {
- class MyBundle(i: Int)(j: Int, jj: Int)(k: UInt) extends Bundle {
- val foo = UInt((i + j + jj + k.getWidth).W)
- }
- elaborate {
- new MultiIOModule {
- val in = IO(Input(new MyBundle(8)(8, 8)(UInt(8.W))))
- val out = IO(Output(new MyBundle(8)(8, 8)(UInt(8.W))))
- out := in
- }
- }
- }
-
- it should "support Bundles that implement their own cloneType" in {
- class MyBundle(i: Int) extends Bundle {
- val foo = UInt(i.W)
- }
- elaborate {
- new MultiIOModule {
- val in = IO(Input(new MyBundle(8)))
- val out = IO(Output(new MyBundle(8)))
- out := in
- }
- }
- }
-
- it should "support Bundles that capture type parameters from their parent scope" in {
- class MyModule[T <: Data](gen: T) extends MultiIOModule {
- class MyBundle(n: Int) extends Bundle {
- val foo = Vec(n, gen)
- }
- val in = IO(Input(new MyBundle(4)))
- val out = IO(Output(new MyBundle(4)))
- out := in
- }
- elaborate(new MyModule(UInt(8.W)))
- }
-
- it should "work for higher-kinded types" in {
- class DataGen[T <: Data](gen: T) {
- def newType: T = gen.cloneType
- }
- class MyBundle[A <: Data, B <: DataGen[A]](gen: B) extends Bundle {
- val foo = gen.newType
- }
- class MyModule extends MultiIOModule {
- val io = IO(Output(new MyBundle[UInt, DataGen[UInt]](new DataGen(UInt(3.W)))))
- io.foo := 0.U
- }
- elaborate(new MyModule)
- }
-
- it should "support Bundles with vararg arguments" in {
- // Without the fix, this doesn't even compile
- // Extra parameter lists to make this a complex test case
- class VarArgsBundle(x: Int)(y: Int, widths: Int*) extends Bundle {
- def mkField(idx: Int): Option[UInt] =
- (x +: y +: widths).lift(idx).map(w => UInt(w.W))
- val foo = mkField(0)
- val bar = mkField(1)
- val fizz = mkField(2)
- val buzz = mkField(3)
- }
- class MyModule extends Module {
- val in = IO(Input(new VarArgsBundle(1)(2, 3, 4)))
- val out = IO(Output(new VarArgsBundle(1)(2, 3, 4)))
- out := in
- }
- elaborate(new MyModule)
- }
-
- it should "support Records that mixin AutoCloneType" in {
- class MyModule extends Module {
- val gen = new RecordAutoCloneType(UInt(8.W))
- val in = IO(Input(gen))
- val out = IO(Output(gen))
- out := in
- }
- elaborate(new MyModule)
- }
-
- it should "support Records that don't mixin AutoCloneType and use forbidden methods" in {
- class MyModule extends Module {
- val gen = new RecordWithVerbotenMethods(8)
- val in = IO(Input(gen))
- val out = IO(Output(gen))
- out := in
- }
- elaborate(new MyModule)
- }
-}
diff --git a/src/test/scala/chiselTests/AutoNestedCloneSpec.scala b/src/test/scala/chiselTests/AutoNestedCloneSpec.scala
deleted file mode 100644
index b75c0c00..00000000
--- a/src/test/scala/chiselTests/AutoNestedCloneSpec.scala
+++ /dev/null
@@ -1,136 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-import chisel3._
-import chisel3.testers.TestUtils
-import chisel3.stage.ChiselStage.elaborate
-import org.scalatest.matchers.should.Matchers
-
-class BundleWithAnonymousInner(val w: Int) extends Bundle {
- val inner = new Bundle {
- val foo = Input(UInt(w.W))
- }
-}
-
-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 {
- class Outer(val w: Int) extends Module {
- class Middle(val w: Int) {
- class InnerIOType extends Bundle {
- val in = Input(UInt(w.W))
- }
- def getIO: InnerIOType = new InnerIOType
- }
- val io = IO(new Bundle {})
- val myWire = Wire((new Middle(w)).getIO)
- }
- new Outer(2)
- }
- }
-
- it should "clone an anonymous inner bundle successfully" in {
- elaborate {
- class TestTop(val w: Int) extends Module {
- val io = IO(new Bundle {})
- val myWire = Wire(new Bundle { val a = UInt(w.W) })
- }
- new TestTop(2)
- }
- }
-
- it should "pick the correct $outer instance for an anonymous inner bundle" in {
- elaborate {
- class Inner(val w: Int) extends Module {
- val io = IO(new Bundle {
- val in = Input(UInt(w.W))
- val out = Output(UInt(w.W))
- })
- }
- class Outer(val w: Int) extends Module {
- val io = IO(new Bundle {
- val in = Input(UInt(w.W))
- val out = Output(UInt(w.W))
- })
- val i = Module(new Inner(w))
- val iw = Wire(chiselTypeOf(i.io))
- iw <> io
- i.io <> iw
- }
- new Outer(2)
- }
- }
-
- it should "clone an anonymous, bound, inner bundle of another bundle successfully" in {
- elaborate {
- class TestModule(w: Int) extends Module {
- val io = IO(new BundleWithAnonymousInner(w))
- val w0 = WireDefault(io)
- val w1 = WireDefault(io.inner)
- }
- new TestModule(8)
- }
- }
-
- it should "clone an anonymous, inner bundle of a Module, bound to another bundle successfully" in {
- elaborate {
- class TestModule(w: Int) extends Module {
- val bun = new Bundle {
- val foo = UInt(w.W)
- }
- val io = IO(new Bundle {
- val inner = Input(bun)
- })
- val w0 = WireDefault(io)
- val w1 = WireDefault(io.inner)
- }
- new TestModule(8)
- }
- }
-
- it should "clone a double-nested anonymous Bundle" in {
- elaborate {
- class TestModule() extends Module {
- val io = IO(new Bundle {
- val inner = Input(new Bundle {
- val x = UInt(8.W)
- })
- })
- }
- new TestModule()
- }
- }
-
- it should "support an anonymous doubly-nested inner bundle" in {
- elaborate {
- class Outer(val w: Int) extends Module {
- class Middle(val w: Int) {
- def getIO: Bundle = new Bundle {
- val in = Input(UInt(w.W))
- }
- }
- val io = IO(new Bundle {})
- val myWire = Wire((new Middle(w)).getIO)
- }
- new Outer(2)
- }
- }
-
- it should "support anonymous Inner bundles that capture type parameters from outer Bundles" in {
- elaborate(new MultiIOModule {
- class MyBundle[T <: Data](n: Int, gen: T) extends Bundle {
- val foo = new Bundle {
- val x = Input(Vec(n, gen))
- }
- val bar = Output(Option(new { def mkBundle = new Bundle { val x = Vec(n, gen) } }).get.mkBundle)
- }
- val io = IO(new MyBundle(4, UInt(8.W)))
- val myWire = WireInit(io.foo)
- val myWire2 = WireInit(io.bar)
- io.bar.x := io.foo.x
- })
- }
-}
diff --git a/src/test/scala/chiselTests/BetterNamingTests.scala b/src/test/scala/chiselTests/BetterNamingTests.scala
deleted file mode 100644
index 8fd1c11f..00000000
--- a/src/test/scala/chiselTests/BetterNamingTests.scala
+++ /dev/null
@@ -1,101 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.stage.ChiselStage
-import chisel3.util._
-
-import scala.collection.mutable
-
-// Defined outside of the class so we don't get $ in name
-class Other(w: Int) extends Module {
- val io = IO(new Bundle {
- val a = UInt(w.W)
- })
-}
-
-// Check the names of the Modules (not instances)
-class PerNameIndexing(count: Int) extends NamedModuleTester {
- def genModName(prefix: String, idx: Int): String = if (idx == 0) prefix else s"${prefix}_$idx"
- val wires = Seq.tabulate(count) { i =>
- expectModuleName(Module(new Other(i)), genModName("Other", i))
- }
- val queues = Seq.tabulate(count) { i =>
- expectModuleName(Module(new Queue(UInt(i.W), 16)), genModName("Queue", i))
- }
-}
-
-// Note this only checks Iterable[Chisel.Data] which excludes Maps
-class IterableNaming extends NamedModuleTester {
- val seq = Seq.tabulate(3) { i =>
- Seq.tabulate(2) { j => expectName(WireDefault((i * j).U), s"seq_${i}_${j}") }
- }
- val optSet = Some(
- Set(
- expectName(WireDefault(0.U), "optSet_0"),
- expectName(WireDefault(1.U), "optSet_1"),
- expectName(WireDefault(2.U), "optSet_2"),
- expectName(WireDefault(3.U), "optSet_3")
- )
- )
-
- val stack = {
- val s = mutable.Stack[Module]()
- for (i <- 0 until 4) {
- val j = 3 - i
- s.push(expectName(Module(new Other(i)), s"stack_$j"))
- }
- s
- }
- def streamFrom(x: Int): Stream[Module] =
- expectName(Module(new Other(x)), s"list_$x") #:: streamFrom(x + 1)
- val stream = streamFrom(0) // Check that we don't get into infinite loop
- val list = stream.take(8).toList
-}
-
-class DigitFieldNamesInRecord extends NamedModuleTester {
- val wire = Wire(new CustomBundle("0" -> UInt(32.W), "1" -> UInt(32.W)))
- expectName(wire("0"), "wire.0")
- expectName(wire("1"), "wire.1")
-}
-
-/* Better Naming Tests
- *
- * These tests are intended to validate that Chisel picks better names
- */
-class BetterNamingTests extends ChiselFlatSpec {
-
- behavior.of("Better Naming")
-
- it should "provide unique counters for each name" in {
- var module: PerNameIndexing = null
- 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
- 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
- ChiselStage.elaborate { module = new DigitFieldNamesInRecord; module }
- assert(module.getNameFailures() == Nil)
- }
-
- "Literals" should "not impact temporary name suffixes" in {
- class MyModule(withLits: Boolean) extends Module {
- val io = IO(new Bundle {})
- if (withLits) {
- List(8.U, -3.S, 1.25.F(2.BP))
- }
- WireDefault(3.U)
- }
- val withLits = ChiselStage.emitChirrtl(new MyModule(true))
- val noLits = ChiselStage.emitChirrtl(new MyModule(false))
- withLits should equal(noLits)
- }
-}
diff --git a/src/test/scala/chiselTests/BitwiseOps.scala b/src/test/scala/chiselTests/BitwiseOps.scala
deleted file mode 100644
index 2c050bfa..00000000
--- a/src/test/scala/chiselTests/BitwiseOps.scala
+++ /dev/null
@@ -1,28 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.testers.BasicTester
-
-class BitwiseOpsTester(w: Int, _a: Int, _b: Int) extends BasicTester {
- val mask = (1 << w) - 1
- val a = _a.asUInt(w.W)
- val b = _b.asUInt(w.W)
- assert(~a === (mask & ~_a).asUInt)
- assert((a & b) === (_a & _b).asUInt)
- assert((a | b) === (_a | _b).asUInt)
- assert((a ^ b) === (_a ^ _b).asUInt)
- assert((a.orR) === (_a != 0).asBool)
- assert((a.andR) === (s"%${w}s".format(BigInt(_a).toString(2)).foldLeft(true)(_ && _ == '1')).asBool)
- stop()
-}
-
-class BitwiseOpsSpec extends ChiselPropSpec {
- property("All bit-wise ops should return the correct result") {
- forAll(safeUIntPair) {
- case (w: Int, a: Int, b: Int) =>
- assertTesterPasses { new BitwiseOpsTester(w, a, b) }
- }
- }
-}
diff --git a/src/test/scala/chiselTests/BlackBox.scala b/src/test/scala/chiselTests/BlackBox.scala
deleted file mode 100644
index f923a94a..00000000
--- a/src/test/scala/chiselTests/BlackBox.scala
+++ /dev/null
@@ -1,225 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.experimental._
-import chisel3.stage.ChiselStage
-import chisel3.testers.{BasicTester, TesterDriver}
-import chisel3.util._
-
-class BlackBoxInverter extends BlackBox {
- val io = IO(new Bundle() {
- val in = Input(Bool())
- val out = Output(Bool())
- })
-}
-
-// Due to the removal of "val io", this technically works
-// This style is discouraged, please use "val io"
-class BlackBoxInverterSuggestName extends BlackBox {
- override def desiredName: String = "BlackBoxInverter"
- val foo = IO(new Bundle() {
- val in = Input(Bool())
- val out = Output(Bool())
- }).suggestName("io")
-}
-
-class BlackBoxPassthrough extends BlackBox {
- val io = IO(new Bundle() {
- val in = Input(Bool())
- val out = Output(Bool())
- })
-}
-
-// Test Flip on top-level IO
-class BlackBoxPassthrough2 extends BlackBox {
- val io = IO(Flipped(new Bundle() {
- val in = Output(Bool())
- val out = Input(Bool())
- }))
-}
-
-class BlackBoxRegister extends BlackBox {
- val io = IO(new Bundle() {
- val clock = Input(Clock())
- val in = Input(Bool())
- val out = Output(Bool())
- })
-}
-
-class BlackBoxTester extends BasicTester {
- val blackBoxPos = Module(new BlackBoxInverter)
- val blackBoxNeg = Module(new BlackBoxInverter)
-
- blackBoxPos.io.in := 1.U
- blackBoxNeg.io.in := 0.U
-
- assert(blackBoxNeg.io.out === 1.U)
- assert(blackBoxPos.io.out === 0.U)
- stop()
-}
-
-class BlackBoxTesterSuggestName extends BasicTester {
- val blackBoxPos = Module(new BlackBoxInverterSuggestName)
- val blackBoxNeg = Module(new BlackBoxInverterSuggestName)
-
- blackBoxPos.foo.in := 1.U
- blackBoxNeg.foo.in := 0.U
-
- assert(blackBoxNeg.foo.out === 1.U)
- assert(blackBoxPos.foo.out === 0.U)
- stop()
-}
-
-class BlackBoxFlipTester extends BasicTester {
- val blackBox = Module(new BlackBoxPassthrough2)
-
- blackBox.io.in := 1.U
- assert(blackBox.io.out === 1.U)
- stop()
-}
-
-/** Instantiate multiple BlackBoxes with similar interfaces but different
- * functionality. Used to detect failures in BlackBox naming and module
- * deduplication.
- */
-
-class MultiBlackBoxTester extends BasicTester {
- val blackBoxInvPos = Module(new BlackBoxInverter)
- val blackBoxInvNeg = Module(new BlackBoxInverter)
- val blackBoxPassPos = Module(new BlackBoxPassthrough)
- val blackBoxPassNeg = Module(new BlackBoxPassthrough)
-
- blackBoxInvPos.io.in := 1.U
- blackBoxInvNeg.io.in := 0.U
- blackBoxPassPos.io.in := 1.U
- blackBoxPassNeg.io.in := 0.U
-
- assert(blackBoxInvNeg.io.out === 1.U)
- assert(blackBoxInvPos.io.out === 0.U)
- assert(blackBoxPassNeg.io.out === 0.U)
- assert(blackBoxPassPos.io.out === 1.U)
- stop()
-}
-
-class BlackBoxWithClockTester extends BasicTester {
- val blackBox = Module(new BlackBoxRegister)
- val model = Reg(Bool())
-
- val (cycles, end) = Counter(true.B, 15)
-
- val impetus = cycles(0)
- blackBox.io.clock := clock
- blackBox.io.in := impetus
- model := impetus
-
- when(cycles > 0.U) {
- assert(blackBox.io.out === model)
- }
- when(end) { stop() }
-}
-
-class BlackBoxConstant(value: Int) extends BlackBox(Map("VALUE" -> value, "WIDTH" -> log2Ceil(value + 1))) {
- require(value >= 0, "value must be a UInt!")
- val io = IO(new Bundle {
- val out = Output(UInt(log2Ceil(value + 1).W))
- })
-}
-
-class BlackBoxStringParam(str: String) extends BlackBox(Map("STRING" -> str)) {
- val io = IO(new Bundle {
- val out = UInt(32.W)
- })
-}
-
-class BlackBoxRealParam(dbl: Double) extends BlackBox(Map("REAL" -> dbl)) {
- val io = IO(new Bundle {
- val out = UInt(64.W)
- })
-}
-
-class BlackBoxTypeParam(w: Int, raw: String) extends BlackBox(Map("T" -> RawParam(raw))) {
- val io = IO(new Bundle {
- val out = UInt(w.W)
- })
-}
-
-class BlackBoxNoIO extends BlackBox {
- // Whoops! typo
- val ioo = IO(new Bundle {
- val out = Output(UInt(8.W))
- })
-}
-
-class BlackBoxUIntIO extends BlackBox {
- val io = IO(Output(UInt(8.W)))
-}
-
-class BlackBoxWithParamsTester extends BasicTester {
- val blackBoxOne = Module(new BlackBoxConstant(1))
- val blackBoxFour = Module(new BlackBoxConstant(4))
- val blackBoxStringParamOne = Module(new BlackBoxStringParam("one"))
- val blackBoxStringParamTwo = Module(new BlackBoxStringParam("two"))
- val blackBoxRealParamOne = Module(new BlackBoxRealParam(1.0))
- val blackBoxRealParamNeg = Module(new BlackBoxRealParam(-1.0))
- val blackBoxTypeParamBit = Module(new BlackBoxTypeParam(1, "bit"))
- val blackBoxTypeParamWord = Module(new BlackBoxTypeParam(32, "bit [31:0]"))
-
- val (cycles, end) = Counter(true.B, 4)
-
- assert(blackBoxOne.io.out === 1.U)
- assert(blackBoxFour.io.out === 4.U)
- assert(blackBoxStringParamOne.io.out === 1.U)
- assert(blackBoxStringParamTwo.io.out === 2.U)
- assert(blackBoxRealParamOne.io.out === 0x3ff0000000000000L.U)
- assert(blackBoxRealParamNeg.io.out === BigInt("bff0000000000000", 16).U)
- assert(blackBoxTypeParamBit.io.out === 1.U)
- assert(blackBoxTypeParamWord.io.out === "hdeadbeef".U(32.W))
-
- when(end) { stop() }
-}
-
-class BlackBoxSpec extends ChiselFlatSpec {
- "A BlackBoxed inverter" should "work" in {
- assertTesterPasses({ new BlackBoxTester }, Seq("/chisel3/BlackBoxTest.v"), TesterDriver.verilatorOnly)
- }
- "A BlackBoxed with flipped IO" should "work" in {
- assertTesterPasses({ new BlackBoxFlipTester }, Seq("/chisel3/BlackBoxTest.v"), TesterDriver.verilatorOnly)
- }
- "Multiple BlackBoxes" should "work" in {
- assertTesterPasses({ new MultiBlackBoxTester }, Seq("/chisel3/BlackBoxTest.v"), TesterDriver.verilatorOnly)
- }
- "A BlackBoxed register" should "work" in {
- assertTesterPasses({ new BlackBoxWithClockTester }, Seq("/chisel3/BlackBoxTest.v"), TesterDriver.verilatorOnly)
- }
- "BlackBoxes with parameters" should "work" in {
- assertTesterPasses({ new BlackBoxWithParamsTester }, Seq("/chisel3/BlackBoxTest.v"), TesterDriver.verilatorOnly)
- }
- "DataMirror.modulePorts" should "work with BlackBox" in {
- ChiselStage.elaborate(new Module {
- val io = IO(new Bundle {})
- val m = Module(new BlackBoxPassthrough)
- assert(DataMirror.modulePorts(m) == Seq("in" -> m.io.in, "out" -> m.io.out))
- })
- }
- "A BlackBox using suggestName(\"io\")" should "work (but don't do this)" in {
- assertTesterPasses({ new BlackBoxTesterSuggestName }, Seq("/chisel3/BlackBoxTest.v"), TesterDriver.verilatorOnly)
- }
-
- "A BlackBox with no 'val io'" should "give a reasonable error message" in {
- (the[ChiselException] thrownBy {
- ChiselStage.elaborate(new Module {
- val inst = Module(new BlackBoxNoIO)
- })
- }).getMessage should include("must have a port named 'io' of type Record")
- }
-
- "A BlackBox with non-Record 'val io'" should "give a reasonable error message" in {
- (the[ChiselException] thrownBy {
- ChiselStage.elaborate(new Module {
- val inst = Module(new BlackBoxUIntIO)
- })
- }).getMessage should include("must have a port named 'io' of type Record")
- }
-}
diff --git a/src/test/scala/chiselTests/BlackBoxImpl.scala b/src/test/scala/chiselTests/BlackBoxImpl.scala
deleted file mode 100644
index 4cc72dd0..00000000
--- a/src/test/scala/chiselTests/BlackBoxImpl.scala
+++ /dev/null
@@ -1,139 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import java.io.File
-
-import chisel3._
-import chisel3.util.{HasBlackBoxInline, HasBlackBoxPath, HasBlackBoxResource}
-import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage}
-import firrtl.transforms.BlackBoxNotFoundException
-import org.scalacheck.Test.Failed
-import org.scalatest.Succeeded
-import org.scalatest.freespec.AnyFreeSpec
-import org.scalatest.matchers.should.Matchers
-
-class BlackBoxAdd(n: Int) extends HasBlackBoxInline {
- val io = IO(new Bundle {
- val in = Input(UInt(16.W))
- val out = Output(UInt(16.W))
- })
-
- setInline(
- "BlackBoxAdd.v",
- s"""
- |module BlackBoxAdd(
- | input [15:0] in,
- | output [15:0] out
- |);
- | assign out = in + $n;
- |endmodule
- """.stripMargin
- )
-}
-
-class UsesBlackBoxAddViaInline extends Module {
- val io = IO(new Bundle {
- val in = Input(UInt(16.W))
- val out = Output(UInt(16.W))
- })
-
- val blackBoxAdd = Module(new BlackBoxAdd(5))
- blackBoxAdd.io.in := io.in
- io.out := blackBoxAdd.io.out
-}
-
-class BlackBoxMinus extends HasBlackBoxResource {
- val io = IO(new Bundle {
- val in1 = Input(UInt(16.W))
- val in2 = Input(UInt(16.W))
- val out = Output(UInt(16.W))
- })
- addResource("/chisel3/BlackBoxTest.v")
-}
-
-class BlackBoxMinusPath extends HasBlackBoxPath {
- val io = IO(new Bundle {
- val in1 = Input(UInt(16.W))
- val in2 = Input(UInt(16.W))
- val out = Output(UInt(16.W))
- })
- addPath(new File("src/test/resources/chisel3/BlackBoxTest.v").getCanonicalPath)
-}
-
-class UsesBlackBoxMinusViaResource extends Module {
- val io = IO(new Bundle {
- val in1 = Input(UInt(16.W))
- val in2 = Input(UInt(16.W))
- val out = Output(UInt(16.W))
- })
-
- val mod0 = Module(new BlackBoxMinus)
-
- mod0.io.in1 := io.in1
- mod0.io.in2 := io.in2
- io.out := mod0.io.out
-}
-
-class UsesBlackBoxMinusViaPath extends Module {
- val io = IO(new Bundle {
- val in1 = Input(UInt(16.W))
- val in2 = Input(UInt(16.W))
- val out = Output(UInt(16.W))
- })
-
- val mod0 = Module(new BlackBoxMinusPath)
-
- mod0.io.in1 := io.in1
- mod0.io.in2 := io.in2
- io.out := mod0.io.out
-}
-
-class BlackBoxResourceNotFound extends HasBlackBoxResource {
- val io = IO(new Bundle {})
- addResource("/missing.resource")
-}
-
-class UsesMissingBlackBoxResource extends RawModule {
- val foo = Module(new BlackBoxResourceNotFound)
-}
-
-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 {
- 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 {
- 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 {
- 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
- }
- "Resource files that do not exist produce Chisel errors" in {
- assertThrows[BlackBoxNotFoundException] {
- ChiselStage.emitChirrtl(new UsesMissingBlackBoxResource)
- }
- }
- }
-}
diff --git a/src/test/scala/chiselTests/BoringUtilsSpec.scala b/src/test/scala/chiselTests/BoringUtilsSpec.scala
deleted file mode 100644
index 9be2d75a..00000000
--- a/src/test/scala/chiselTests/BoringUtilsSpec.scala
+++ /dev/null
@@ -1,135 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.util.Counter
-import chisel3.testers._
-import chisel3.experimental.{BaseModule, ChiselAnnotation, RunFirrtlTransform}
-import chisel3.util.experimental.BoringUtils
-
-import firrtl.{ChirrtlForm, CircuitForm, CircuitState, DependencyAPIMigration, Transform}
-import firrtl.annotations.{Annotation, NoTargetAnnotation}
-import firrtl.options.Dependency
-import firrtl.transforms.{DontTouchAnnotation, NoDedupAnnotation}
-import firrtl.passes.wiring.{WiringException, WiringTransform}
-import firrtl.stage.Forms
-
-abstract class ShouldntAssertTester(cyclesToWait: BigInt = 4) extends BasicTester {
- val dut: BaseModule
- val (_, done) = Counter(true.B, 2)
- when(done) { stop() }
-}
-
-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 {
-
- class BoringInverter extends Module {
- val io = IO(new Bundle {})
- val a = Wire(UInt(1.W))
- val notA = Wire(UInt(1.W))
- val b = Wire(UInt(1.W))
- a := 0.U
- notA := ~a
- b := a
- chisel3.assert(b === 1.U)
- BoringUtils.addSource(notA, "x")
- BoringUtils.addSink(b, "x")
- }
-
- behavior.of("BoringUtils.{addSink, addSource}")
-
- it should "connect two wires within a module" in {
- runTester(
- new ShouldntAssertTester { val dut = Module(new BoringInverter) },
- annotations = TesterDriver.verilatorOnly
- ) should be(true)
- }
-
- trait WireX { this: BaseModule =>
- val x = Wire(UInt(4.W))
- chisel3.experimental.annotate(new ChiselAnnotation {
- def toFirrtl: Annotation = DontTouchAnnotation(x.toNamed)
- })
- }
-
- class Source extends RawModule with WireX {
- val in = IO(Input(UInt()))
- x := in
- }
-
- class Sink extends RawModule with WireX {
- val out = IO(Output(UInt()))
- x := 0.U // Default value. Output is zero unless we bore...
- out := x
- }
-
- class Top(val width: Int) extends Module {
- /* From the perspective of deduplication, all sources are identical and all sinks are identical. */
- val sources = Seq.fill(3)(Module(new Source))
- val sinks = Seq.fill(6)(Module(new Sink))
-
- /* Sources are differentiated by their input connections only. */
- sources.zip(Seq(0, 1, 2)).map { case (a, b) => a.in := b.U }
-
- /* Sinks are differentiated by their post-boring outputs. */
- sinks.zip(Seq(0, 1, 1, 2, 2, 2)).map { case (a, b) => chisel3.assert(a.out === b.U) }
- }
-
- /** This is testing a complicated wiring pattern and exercising
- * the necessity of disabling deduplication for sources and sinks.
- * Without disabling deduplication, this test will fail.
- */
- class TopTester extends ShouldntAssertTester {
- val dut = Module(new Top(4))
- BoringUtils.bore(dut.sources(1).x, Seq(dut.sinks(1).x, dut.sinks(2).x))
- BoringUtils.bore(dut.sources(2).x, Seq(dut.sinks(3).x, dut.sinks(4).x, dut.sinks(5).x))
- }
-
- trait FailViaDedup { this: TopTester =>
- case object FooAnnotation extends NoTargetAnnotation
- chisel3.experimental.annotate(new ChiselAnnotation with RunFirrtlTransform {
- def toFirrtl: Annotation = FooAnnotation
- def transformClass: Class[_ <: Transform] = classOf[StripNoDedupAnnotation]
- })
- }
-
- behavior.of("BoringUtils.bore")
-
- it should "connect across modules using BoringUtils.bore" in {
- runTester(new TopTester, annotations = TesterDriver.verilatorOnly) should be(true)
- }
-
- it should "throw an exception if NoDedupAnnotations are removed" in {
- intercept[WiringException] {
- runTester(new TopTester with FailViaDedup, annotations = Seq(TesterDriver.VerilatorBackend))
- }.getMessage should startWith("Unable to determine source mapping for sink")
- }
-
- class InternalBore extends RawModule {
- val in = IO(Input(Bool()))
- val out = IO(Output(Bool()))
- out := false.B
- BoringUtils.bore(in, Seq(out))
- }
-
- class InternalBoreTester extends ShouldntAssertTester {
- val dut = Module(new InternalBore)
- dut.in := true.B
- chisel3.assert(dut.out === true.B)
- }
-
- it should "work for an internal (same module) BoringUtils.bore" in {
- runTester(new InternalBoreTester, annotations = TesterDriver.verilatorOnly) should be(true)
- }
-
-}
diff --git a/src/test/scala/chiselTests/BulkConnectSpec.scala b/src/test/scala/chiselTests/BulkConnectSpec.scala
deleted file mode 100644
index 0a1616d3..00000000
--- a/src/test/scala/chiselTests/BulkConnectSpec.scala
+++ /dev/null
@@ -1,139 +0,0 @@
-package chiselTests
-
-import chisel3._
-import chisel3.util.Decoupled
-import chisel3.stage.ChiselStage
-import chisel3.testers.BasicTester
-
-class BulkConnectSpec extends ChiselPropSpec {
- property("Chisel connects should emit FIRRTL bulk connects when possible") {
- val chirrtl = ChiselStage.emitChirrtl(new Module {
- val io = IO(new Bundle {
- val inMono = Input(Vec(4, UInt(8.W)))
- val outMono = Output(Vec(4, UInt(8.W)))
- val inBi = Input(Vec(4, UInt(8.W)))
- val outBi = Output(Vec(4, UInt(8.W)))
- })
- io.outMono := io.inMono
- io.outBi <> io.inBi
- })
- chirrtl should include("io.outMono <= io.inMono")
- chirrtl should include("io.outBi <= io.inBi")
- }
-
- property("Chisel connects should not emit FIRRTL bulk connects for Stringly-typed connections") {
- object Foo {
- import Chisel._
- // Chisel._ bundle
- class BundleParent extends Bundle {
- val foo = UInt(width = 8)
- }
- class BundleChild extends BundleParent {
- val bar = UInt(width = 8)
- }
- }
-
- import Foo._
-
- // chisel3._ bundle
- class MyBundle(child: Boolean) extends Bundle {
- val fizz = UInt(8.W)
- val buzz = if (child) new BundleChild else new BundleParent
- }
-
- val chirrtl = ChiselStage.emitChirrtl(new Module {
- // Checking MonoConnect
- val in = IO(Input(new MyBundle(true)))
- val out = IO(Output(new MyBundle(false)))
- out := in
-
- // Checking BulkConnect (with Decoupled)
- val enq = IO(Flipped(Decoupled(new BundleChild)))
- val deq = IO(Decoupled(new BundleParent))
- deq <> enq
- })
-
- chirrtl should include("out.buzz.foo <= in.buzz.foo")
- chirrtl should include("out.fizz <= in.fizz")
- chirrtl should include("deq.bits <- enq.bits")
- chirrtl should include("deq.valid <= enq.valid")
- chirrtl should include("enq.ready <= deq.ready")
-
- chirrtl shouldNot include("deq <= enq")
- chirrtl shouldNot include("deq.bits.foo <= enq.bits.foo")
- chirrtl shouldNot include("deq.bits.foo <- enq.bits.foo")
- chirrtl shouldNot include("deq.bits.bar")
- }
-
- property("Chisel connects should not emit FIRRTL bulk connects between differing FIRRTL types") {
- val chirrtl = ChiselStage.emitChirrtl(new Module {
- val in = IO(Flipped(new Bundle {
- val foo = Flipped(new Bundle {
- val bar = Input(UInt(8.W))
- })
- }))
- val out = IO(Output(new Bundle {
- val foo = new Bundle {
- val bar = UInt(8.W)
- }
- }))
- // Both of these connections are legal in Chisel, but in and out do not have the same type
- out := in
- out <> in
- })
- // out <- in is illegal FIRRTL
- exactly(2, chirrtl.split('\n')) should include("out.foo.bar <= in.foo.bar")
- chirrtl shouldNot include("out <= in")
- chirrtl shouldNot include("out <- in")
- }
-
- property("Chisel connects should not emit a FIRRTL bulk connect for a bidirectional MonoConnect") {
- val chirrtl = ChiselStage.emitChirrtl(new Module {
- val enq = IO(Flipped(Decoupled(UInt(8.W))))
- val deq = IO(Decoupled(UInt(8.W)))
-
- // Implicitly create a MonoConnect from enq to a wire
- // enq is a Decoupled and so has input/output signals
- // We should not bulk connect in this case
- val wire = WireDefault(enq)
- dontTouch(wire)
- deq <> enq
- })
-
- chirrtl shouldNot include("wire <= enq")
- chirrtl should include("wire.bits <= enq.bits")
- chirrtl should include("wire.valid <= enq.valid")
- chirrtl should include("wire.ready <= enq.ready")
- chirrtl should include("deq <= enq")
- }
-
- property("Chisel connects should not emit a FIRRTL bulk connect for BlackBox IO Bundles") {
- class MyBundle extends Bundle {
- val O: Bool = Output(Bool())
- val I: Bool = Input(Bool())
- }
-
- val chirrtl = ChiselStage.emitChirrtl(new Module {
- val io: MyBundle = IO(Flipped(new MyBundle))
-
- val bb = Module(new BlackBox {
- val io: MyBundle = IO(Flipped(new MyBundle))
- })
-
- io <> bb.io
- })
- // There won't be a bb.io Bundle in FIRRTL, so connections have to be done element-wise
- chirrtl should include("bb.O <= io.O")
- chirrtl should include("io.I <= bb.I")
- }
-
- property("MonoConnect should bulk connect undirectioned internal wires") {
- val chirrtl = ChiselStage.emitChirrtl(new Module {
- val io = IO(new Bundle {})
- val w1 = Wire(Vec(2, UInt(8.W)))
- val w2 = Wire(Vec(2, UInt(8.W)))
- w2 := w1
- })
- chirrtl should include("w2 <= w1")
- }
-}
diff --git a/src/test/scala/chiselTests/BundleElementsSpec.scala b/src/test/scala/chiselTests/BundleElementsSpec.scala
deleted file mode 100644
index afca3d81..00000000
--- a/src/test/scala/chiselTests/BundleElementsSpec.scala
+++ /dev/null
@@ -1,564 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.experimental.FixedPoint
-import chisel3.stage.ChiselStage
-import chisel3.util.Decoupled
-import org.scalatest.exceptions.TestFailedException
-import org.scalatest.freespec.AnyFreeSpec
-import org.scalatest.matchers.should.Matchers
-
-import scala.language.reflectiveCalls
-
-/* Rich and complicated bundle examples
- */
-trait BpipSuperTraitWithField {
- val bpipSuperTraitGood = SInt(17.W)
- def bpipSuperTraitBad = SInt(22.W)
-}
-
-trait BpipTraitWithField extends BpipSuperTraitWithField {
- val bpipTraitGood = SInt(17.W)
- def bpipTraitBad = SInt(22.W)
-}
-
-class BpipOneField extends Bundle with BpipTraitWithField {
- val bpipOneFieldOne = SInt(8.W)
- val bpipOneFieldTwo = SInt(8.W)
-}
-
-class BpipTwoField extends BpipOneField {
- val bpipTwoFieldOne = SInt(8.W)
- val bpipTwoFieldTwo = Vec(4, UInt(12.W))
- val myInt = 7
- val baz = Decoupled(UInt(16.W))
-}
-
-class BpipDecoupled extends BpipOneField {
- val bpipDecoupledSInt = SInt(8.W)
- val bpipDecoupledVec = Vec(4, UInt(12.W))
- val bpipDecoupledDecoupled = Decoupled(UInt(16.W))
-}
-
-class HasDecoupledBundleByInheritance extends Module {
- val out1 = IO(Output(new BpipDecoupled))
- assertElementsMatchExpected(out1)(
- "bpipDecoupledDecoupled" -> _.bpipDecoupledDecoupled,
- "bpipDecoupledVec" -> _.bpipDecoupledVec,
- "bpipDecoupledSInt" -> _.bpipDecoupledSInt,
- "bpipOneFieldTwo" -> _.bpipOneFieldTwo,
- "bpipOneFieldOne" -> _.bpipOneFieldOne,
- "bpipTraitGood" -> _.bpipTraitGood,
- "bpipSuperTraitGood" -> _.bpipSuperTraitGood
- )
-}
-
-/* plugin should not affect the seq detection */
-class DebugProblem3 extends Module {
- val out1 = IO(Output(new BpipTwoField))
- assertElementsMatchExpected(out1)(
- "baz" -> _.baz,
- "bpipTwoFieldTwo" -> _.bpipTwoFieldTwo,
- "bpipTwoFieldOne" -> _.bpipTwoFieldOne,
- "bpipOneFieldTwo" -> _.bpipOneFieldTwo,
- "bpipOneFieldOne" -> _.bpipOneFieldOne,
- "bpipTraitGood" -> _.bpipTraitGood,
- "bpipSuperTraitGood" -> _.bpipSuperTraitGood
- )
-}
-
-class BpipBadSeqBundle extends Bundle {
- val bpipBadSeqBundleGood = UInt(999.W)
- val bpipBadSeqBundleBad = Seq(UInt(16.W), UInt(8.W), UInt(4.W))
-}
-
-class HasBadSeqBundle extends Module {
- val out1 = IO(Output(new BpipBadSeqBundle))
-}
-
-class BpipBadSeqBundleWithIgnore extends Bundle with IgnoreSeqInBundle {
- val goodFieldWithIgnore = UInt(999.W)
- val badSeqFieldWithIgnore = Seq(UInt(16.W), UInt(8.W), UInt(4.W))
-}
-
-class UsesIgnoreSeqInBundle extends Module {
- val out1 = IO(Output(new BpipBadSeqBundleWithIgnore))
-}
-
-/* This is mostly a test of the field order */
-class BpipP8_1 extends Bundle {
- val field_1_1 = UInt(11.W)
- val field_1_2 = UInt(12.W)
-}
-
-class BpipP8_2 extends BpipP8_1 {
- val field_2_1 = UInt(11.W)
- val field_2_2 = UInt(12.W)
-}
-
-class BpipP8_3 extends BpipP8_2 {
- val field_3_1 = UInt(11.W)
- val field_3_2 = UInt(12.W)
-}
-
-/* plugin should not affect the seq detection */
-class ForFieldOrderingTest extends Module {
- val out1 = IO(Output(new BpipP8_3))
- out1 := DontCare
- assertElementsMatchExpected(out1)(
- "field_3_2" -> _.field_3_2,
- "field_3_1" -> _.field_3_1,
- "field_2_2" -> _.field_2_2,
- "field_2_1" -> _.field_2_1,
- "field_1_2" -> _.field_1_2,
- "field_1_1" -> _.field_1_1
- )
-}
-
-/* plugin should allow parameter var fields */
-class HasValParamsToBundle extends Module {
- // The following block does not work, suggesting that ParamIsField is not a case we need to solve
- class BpipParamIsField0(val paramField0: UInt) extends Bundle
- class BpipParamIsField1(val paramField1: UInt) extends BpipParamIsField0(UInt(66.W))
-
- val out3 = IO(Output(new BpipParamIsField1(UInt(10.W))))
- val out4 = IO(Output(new BpipParamIsField1(UInt(10.W))))
- out3 := DontCare
- assertElementsMatchExpected(out3)("paramField0" -> _.paramField0, "paramField1" -> _.paramField1)
- assertElementsMatchExpected(out4)("paramField0" -> _.paramField0, "paramField1" -> _.paramField1)
-}
-
-class HasGenParamsPassedToSuperclasses extends Module {
-
- class OtherBundle extends Bundle {
- val otherField = UInt(55.W)
- }
-
- class BpipWithGen[T <: Data, TT <: Data](gen: T, gen2: => TT) extends Bundle {
- val superFoo = gen
- val superQux = gen2
- }
-
-// class BpipDemoBundle[T <: Data](gen: T, gen2: => T) extends BpipTwoField with BpipVarmint {
- class BpipUsesWithGen[T <: Data](gen: T, gen2: => T) extends BpipWithGen(gen, gen2) {
- // val foo = gen
- val bar = Bool()
- val qux = gen2
- val bad = 444
- val baz = Decoupled(UInt(16.W))
- }
-
- val out1 = IO(Output(new BpipUsesWithGen(UInt(4.W), new OtherBundle)))
- val out2 = IO(Output(new BpipUsesWithGen(UInt(4.W), FixedPoint(10.W, 4.BP))))
-
- out1 := DontCare
-
- assertElementsMatchExpected(out1)(
- "baz" -> _.baz,
- "qux" -> _.qux,
- "bar" -> _.bar,
- "superQux" -> _.superQux,
- "superFoo" -> _.superFoo
- )
- assertElementsMatchExpected(out2)(
- "baz" -> _.baz,
- "qux" -> _.qux,
- "bar" -> _.bar,
- "superQux" -> _.superQux,
- "superFoo" -> _.superFoo
- )
-}
-
-/* Testing whether gen fields superFoo and superQux can be found when they are
- * declared in a superclass
- *
- */
-class UsesGenFiedldsInSuperClass extends Module {
- class BpipWithGen[T <: Data](gen: T) extends Bundle {
- val superFoo = gen
- val superQux = gen
- }
-
- class BpipUsesWithGen[T <: Data](gen: T) extends BpipWithGen(gen) {}
-
- val out = IO(Output(new BpipUsesWithGen(UInt(4.W))))
-
- out := DontCare
-
- assertElementsMatchExpected(out)()
-}
-
-/* Testing whether gen fields superFoo and superQux can be found when they are
- * declared in a superclass
- *
- */
-class BpipBadBundleWithHardware extends Bundle {
- val bpipWithHardwareGood = UInt(8.W)
- val bpipWithHardwareBad = 244.U(16.W)
-}
-
-class HasHardwareFieldsInBundle extends Module {
- val out = IO(Output(new BpipBadBundleWithHardware))
- assertElementsMatchExpected(out)()
-}
-
-/* This is legal because of =>
- */
-class UsesBundleWithGeneratorField extends Module {
- class BpipWithGen[T <: Data](gen: => T) extends Bundle {
- val superFoo = gen
- val superQux = gen
- }
-
- class BpipUsesWithGen[T <: Data](gen: => T) extends BpipWithGen(gen)
-
- val out = IO(Output(new BpipUsesWithGen(UInt(4.W))))
-
- out := DontCare
-
- assertElementsMatchExpected(out)("superQux" -> _.superQux, "superFoo" -> _.superFoo)
-}
-
-/* Testing whether gen fields superFoo and superQux can be found when they are
- * declared in a superclass
- *
- */
-class BundleElementsSpec extends AnyFreeSpec with Matchers {
-
- /** Tests a whole bunch of different Bundle constructions
- */
- class BpipIsComplexBundle extends Module {
-
- trait BpipVarmint {
- val varmint = Bool()
-
- def vermin = Bool()
-
- private val puppy = Bool()
- }
-
- abstract class BpipAbstractBundle extends Bundle {
- def doNothing: Unit
-
- val fromAbstractBundle = UInt(22.W)
- }
-
- class BpipOneField extends Bundle {
- val fieldOne = SInt(8.W)
- }
-
- class BpipTwoField extends BpipOneField {
- val fieldTwo = SInt(8.W)
- val fieldThree = Vec(4, UInt(12.W))
- }
-
- class BpipAnimalBundle(w1: Int, w2: Int) extends Bundle {
- val dog = SInt(w1.W)
- val fox = UInt(w2.W)
- }
-
- class BpipDemoBundle[T <: Data](gen: T, gen2: => T) extends BpipTwoField with BpipVarmint {
- val foo = gen
- val bar = Bool()
- val qux = gen2
- val bad = 44
- val baz = Decoupled(UInt(16.W))
- val animals = new BpipAnimalBundle(4, 8)
- }
-
- val out = IO(Output(new BpipDemoBundle(UInt(4.W), FixedPoint(10.W, 4.BP))))
-
- val out2 = IO(Output(new BpipAbstractBundle {
- override def doNothing: Unit = ()
-
- val notAbstract: Bool = Bool()
- }))
-
- val out4 = IO(Output(new BpipAnimalBundle(99, 100)))
- val out5 = IO(Output(new BpipTwoField))
-
- out := DontCare
- out5 := DontCare
-
- assertElementsMatchExpected(out)(
- "animals" -> _.animals,
- "baz" -> _.baz,
- "qux" -> _.qux,
- "bar" -> _.bar,
- "varmint" -> _.varmint,
- "fieldThree" -> _.fieldThree,
- "fieldTwo" -> _.fieldTwo,
- "fieldOne" -> _.fieldOne,
- "foo" -> _.foo
- )
- assertElementsMatchExpected(out5)("fieldThree" -> _.fieldThree, "fieldTwo" -> _.fieldTwo, "fieldOne" -> _.fieldOne)
- assertElementsMatchExpected(out2)("notAbstract" -> _.notAbstract, "fromAbstractBundle" -> _.fromAbstractBundle)
- assertElementsMatchExpected(out4)("fox" -> _.fox, "dog" -> _.dog)
- }
-
- "Complex Bundle with inheritance, traits and params. DebugProblem1" in {
- ChiselStage.emitFirrtl(new BpipIsComplexBundle)
- }
-
- "Decoupled Bundle with inheritance" in {
- ChiselStage.emitFirrtl(new HasDecoupledBundleByInheritance)
- }
-
- "Simple bundle inheritance. DebugProblem3" in {
- ChiselStage.emitFirrtl(new DebugProblem3)
- }
-
- "Bundles containing Seq[Data] should be compile erorr. HasBadSeqBundle" in {
- intercept[ChiselException] {
- ChiselStage.emitFirrtl(new HasBadSeqBundle)
- }
- }
-
- "IgnoreSeqInBundle allows Seq[Data] in bundle" in {
- ChiselStage.emitFirrtl(new UsesIgnoreSeqInBundle)
- }
-
- "Simple field ordering test." in {
- ChiselStage.emitFirrtl(new ForFieldOrderingTest)
- }
-
- "Val params to Bundle should be an Exception." in {
- ChiselStage.emitFirrtl(new HasValParamsToBundle)
- }
-
- "Should handle gen params passed to superclasses" in {
- ChiselStage.emitFirrtl(new HasGenParamsPassedToSuperclasses)
- }
-
- "Aliased fields should be detected and throw an exception, because gen: Data, with no =>" in {
- intercept[AliasedAggregateFieldException] {
- ChiselStage.emitFirrtl(new UsesGenFiedldsInSuperClass)
- }
- }
-
- "Error when bundle fields are hardware, such as literal values. HasHardwareFieldsInBundle" in {
- val e = intercept[ExpectedChiselTypeException] {
- ChiselStage.emitFirrtl(new HasHardwareFieldsInBundle)
- }
- e.getMessage should include(
- "Bundle: BpipBadBundleWithHardware contains hardware fields: bpipWithHardwareBad: UInt<16>(244)"
- )
- }
-
- "Aliased fields not created when using gen: => Data" in {
- ChiselStage.emitFirrtl(new UsesBundleWithGeneratorField)
- }
-
- class OptionBundle(val hasIn: Boolean) extends Bundle {
- val in = if (hasIn) {
- Some(Input(Bool()))
- } else {
- None
- }
- val out = Output(Bool())
- }
-
- class UsesBundleWithOptionFields extends Module {
- val outTrue = IO(Output(new OptionBundle(hasIn = true)))
- val outFalse = IO(Output(new OptionBundle(hasIn = false)))
- //NOTE: The _.in.get _.in is an optional field
- assertElementsMatchExpected(outTrue)("out" -> _.out, "in" -> _.in.get)
- assertElementsMatchExpected(outFalse)("out" -> _.out)
- }
-
- "plugin should work with Bundles with Option fields" in {
- ChiselStage.emitFirrtl(new UsesBundleWithOptionFields)
- }
-
- "plugin should work with enums in bundles" in {
- object Enum0 extends ChiselEnum {
- val s0, s1, s2 = Value
- }
-
- ChiselStage.emitFirrtl(new Module {
- val out = IO(Output(new Bundle {
- val a = UInt(8.W)
- val b = Bool()
- val c = Enum0.Type
- }))
- assertElementsMatchExpected(out)("b" -> _.b, "a" -> _.a)
- })
- }
-
- "plugin will NOT see fields that are Data but declared in some way as Any" in {
- //This is not incompatible with chisel not using the plugin, but this code is considered bad practice
-
- ChiselStage.emitFirrtl(new Module {
- val out = IO(Output(new Bundle {
- val a = UInt(8.W)
- val b: Any = Bool()
- }))
-
- intercept[TestFailedException] {
- assert(out.elements.keys.exists(_ == "b"))
- }
- })
- }
-
- "plugin tests should fail properly in the following cases" - {
-
- class BundleAB extends Bundle {
- val a = Output(UInt(8.W))
- val b = Output(Bool())
- }
-
- def checkAssertion(checks: (BundleAB => (String, Data))*)(expectedMessage: String): Unit = {
- intercept[AssertionError] {
- ChiselStage.emitFirrtl(new Module {
- val out = IO(new BundleAB)
- assertElementsMatchExpected(out)(checks: _*)
- })
- }.getMessage should include(expectedMessage)
- }
-
- "one of the expected data values is wrong" in {
- checkAssertion("b" -> _.b, "a" -> _.b)("field 'a' data field BundleElementsSpec_Anon.out.a")
- }
-
- "one of the expected field names in wrong" in {
- checkAssertion("b" -> _.b, "z" -> _.a)("field: 'a' did not match expected 'z'")
- }
-
- "fields that are expected are not returned by the elements method" in {
- checkAssertion("b" -> _.b, "a" -> _.a, "c" -> _.a)("#elements is missing the 'c' field")
- }
-
- "fields returned by the element are not specified in the expected fields" in {
- checkAssertion("b" -> _.b)("expected fields did not include 'a' field found in #elements")
- }
-
- "multiple errors between elements method and expected fields are shown in the assertion error message" in {
- checkAssertion()(
- "expected fields did not include 'b' field found in #elements," +
- " expected fields did not include 'a' field found in #elements"
- )
- }
- }
-
- "plugin should error correctly when bundles contain only a Option field" in {
- ChiselStage.emitFirrtl(new Module {
- val io = IO(new Bundle {
- val foo = Input(UInt(8.W))
- val x = new Bundle {
- val y = if (false) Some(Input(UInt(8.W))) else None
- }
- })
- assertElementsMatchExpected(io)("x" -> _.x, "foo" -> _.foo)
- assertElementsMatchExpected(io.x)()
- })
- }
-
- "plugin should handle fields using the boolean to option construct" in {
- case class ALUConfig(
- xLen: Int,
- mul: Boolean,
- b: Boolean)
-
- class OptionalBundle extends Bundle {
- val optionBundleA = Input(UInt(3.W))
- val optionBundleB = Input(UInt(7.W))
- }
-
- class ALU(c: ALUConfig) extends Module {
-
- class BpipOptionBundle extends Bundle with IgnoreSeqInBundle {
- val bpipUIntVal = Input(UInt(8.W))
- lazy val bpipUIntLazyVal = Input(UInt(8.W))
- var bpipUIntVar = Input(UInt(8.W))
-
- def bpipUIntDef = Input(UInt(8.W))
-
- val bpipOptionUInt = Some(Input(UInt(16.W)))
- val bpipOptionOfBundle = if (c.b) Some(new OptionalBundle) else None
- val bpipSeqData = Seq(UInt(8.W), UInt(8.W))
- }
-
- val io = IO(new BpipOptionBundle)
- assertElementsMatchExpected(io)(
- "bpipUIntLazyVal" -> _.bpipUIntLazyVal,
- "bpipOptionUInt" -> _.bpipOptionUInt.get,
- "bpipUIntVar" -> _.bpipUIntVar,
- "bpipUIntVal" -> _.bpipUIntVal
- )
- }
-
- ChiselStage.emitFirrtl(new ALU(ALUConfig(10, mul = true, b = false)))
- }
-
- "TraceSpec test, different version found in TraceSpec.scala" in {
- class Bundle0 extends Bundle {
- val a = UInt(8.W)
- val b = Bool()
- val c = Enum0.Type
- }
-
- class Bundle1 extends Bundle {
- val a = new Bundle0
- val b = Vec(4, Vec(4, Bool()))
- }
-
- class Module0 extends Module {
- val i = IO(Input(new Bundle1))
- val o = IO(Output(new Bundle1))
- val r = Reg(new Bundle1)
- o := r
- r := i
-
- assertElementsMatchExpected(i)("b" -> _.b, "a" -> _.a)
- assertElementsMatchExpected(o)("b" -> _.b, "a" -> _.a)
- assertElementsMatchExpected(r)("b" -> _.b, "a" -> _.a)
- }
-
- class Module1 extends Module {
- val i = IO(Input(new Bundle1))
- val m0 = Module(new Module0)
- m0.i := i
- m0.o := DontCare
- assertElementsMatchExpected(i)("b" -> _.b, "a" -> _.a)
- }
-
- object Enum0 extends ChiselEnum {
- val s0, s1, s2 = Value
- }
-
- ChiselStage.emitFirrtl(new Module1)
- }
-}
-/* Checks that the elements method of a bundle matches the testers idea of what the bundle field names and their
- * associated data match and that they have the same number of fields in the same order
- */
-object assertElementsMatchExpected {
- def apply[T <: Bundle](bun: T)(checks: (T => (String, Data))*): Unit = {
- val expected = checks.map { fn => fn(bun) }
- val elements = bun.elements
- val missingMsg = "missing field in #elements"
- val extraMsg = "extra field in #elements"
- val paired = elements.toSeq.zipAll(expected, missingMsg -> UInt(1.W), extraMsg -> UInt(1.W))
- val errorsStrings = paired.flatMap {
- case (element, expected) =>
- val (elementName, elementData) = element
- val (expectedName, expectedData) = expected
- if (elementName == missingMsg) {
- Some(s"#elements is missing the '$expectedName' field")
- } else if (expectedName == extraMsg) {
- Some(s"expected fields did not include '$elementName' field found in #elements")
- } else if (elementName != expectedName) {
- Some(s"field: '$elementName' did not match expected '$expectedName'")
- } else if (elementData != expectedData) {
- Some(
- s"field '$elementName' data field ${elementData}(${elementData.hashCode}) did not match expected $expectedData(${expectedData.hashCode})"
- )
- } else {
- None
- }
- }
- assert(errorsStrings.isEmpty, s"Bundle: ${bun.getClass.getName}: " + errorsStrings.mkString(", "))
- }
-}
diff --git a/src/test/scala/chiselTests/BundleLiteralSpec.scala b/src/test/scala/chiselTests/BundleLiteralSpec.scala
deleted file mode 100644
index f90e230d..00000000
--- a/src/test/scala/chiselTests/BundleLiteralSpec.scala
+++ /dev/null
@@ -1,356 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.stage.ChiselStage
-import chisel3.testers.BasicTester
-import chisel3.experimental.BundleLiterals._
-import chisel3.experimental.VecLiterals.AddVecLiteralConstructor
-import chisel3.experimental.{BundleLiteralException, ChiselRange, FixedPoint, Interval}
-
-class BundleLiteralSpec extends ChiselFlatSpec with Utils {
- object MyEnum extends ChiselEnum {
- val sA, sB = Value
- }
- object MyEnumB extends ChiselEnum {
- val sA, sB = Value
- }
- class MyBundle extends Bundle {
- val a = UInt(8.W)
- val b = Bool()
- val c = MyEnum()
- }
-
- class LongBundle extends Bundle {
- val a = UInt(48.W)
- val b = SInt(32.W)
- val c = FixedPoint(16.W, 4.BP)
- }
-
- "bundle literals" should "pack" in {
- assertTesterPasses {
- new BasicTester {
- val bundleLit = (new MyBundle).Lit(_.a -> 42.U, _.b -> false.B, _.c -> MyEnum.sB)
- bundleLit.litOption should equal(Some(169)) // packed as 42 (8-bit), false=0 (1-bit), sB=1 (1-bit)
- chisel3.assert(bundleLit.asUInt() === bundleLit.litOption.get.U) // sanity-check consistency with runtime
-
- val longBundleLit =
- (new LongBundle).Lit(_.a -> 0xdeaddeadbeefL.U, _.b -> (-0x0beef00dL).S(32.W), _.c -> 4.5.F(16.W, 4.BP))
- longBundleLit.litOption should equal(
- Some(
- (BigInt(0xdeaddeadbeefL) << 48)
- + (BigInt(0xffffffffL - 0xbeef00dL + 1) << 16)
- + BigInt(72)
- )
- )
- chisel3.assert(longBundleLit.asUInt() === longBundleLit.litOption.get.U)
-
- stop()
- }
- }
- }
-
- "bundle literals" should "work in RTL" in {
- val outsideBundleLit = (new MyBundle).Lit(_.a -> 42.U, _.b -> true.B, _.c -> MyEnum.sB)
- assertTesterPasses {
- new BasicTester {
- // TODO: add direct bundle compare operations, when that feature is added
- chisel3.assert(outsideBundleLit.a === 42.U)
- chisel3.assert(outsideBundleLit.b === true.B)
- chisel3.assert(outsideBundleLit.c === MyEnum.sB)
- chisel3.assert(outsideBundleLit.isLit())
- chisel3.assert(outsideBundleLit.litValue().U === outsideBundleLit.asUInt())
- val bundleLit = (new MyBundle).Lit(_.a -> 42.U, _.b -> true.B, _.c -> MyEnum.sB)
- chisel3.assert(bundleLit.a === 42.U)
- chisel3.assert(bundleLit.b === true.B)
- chisel3.assert(bundleLit.c === MyEnum.sB)
-
- chisel3.assert(bundleLit.a === outsideBundleLit.a)
- chisel3.assert(bundleLit.b === outsideBundleLit.b)
- chisel3.assert(bundleLit.c === outsideBundleLit.c)
-
- val bundleWire = Wire(new MyBundle)
- bundleWire := outsideBundleLit
-
- chisel3.assert(bundleWire.a === 42.U)
- chisel3.assert(bundleWire.b === true.B)
- chisel3.assert(bundleWire.c === MyEnum.sB)
-
- stop()
- }
- }
- }
-
- "bundle literals of vec literals" should "work" in {
- assertTesterPasses(new BasicTester {
- val range = range"[0,4].2"
- val bundleWithVecs = new Bundle {
- val a = Vec(2, UInt(4.W))
- val b = Vec(2, Interval(range))
- }.Lit(
- _.a -> Vec(2, UInt(4.W)).Lit(0 -> 0xa.U, 1 -> 0xb.U),
- _.b -> Vec(2, Interval(range)).Lit(0 -> (1.5).I(range), 1 -> (0.25).I(range))
- )
- chisel3.assert(bundleWithVecs.a(0) === 0xa.U)
- chisel3.assert(bundleWithVecs.a(1) === 0xb.U)
- chisel3.assert(bundleWithVecs.b(0) === (1.5).I(range))
- chisel3.assert(bundleWithVecs.b(1) === (0.25).I(range))
- stop()
- })
- }
-
- "partial bundle literals" should "work in RTL" in {
- assertTesterPasses {
- new BasicTester {
- val bundleLit = (new MyBundle).Lit(_.a -> 42.U)
- chisel3.assert(bundleLit.a === 42.U)
-
- val bundleWire = Wire(new MyBundle)
- bundleWire := bundleLit
-
- chisel3.assert(bundleWire.a === 42.U)
-
- stop()
- }
- }
- }
-
- class MyOuterBundle extends Bundle {
- val a = new MyBundle
- val b = new Bundle {
- val c = Bool()
- val d = UInt(8.W)
- val e = MyEnum()
- }
- val f = MyEnum()
- }
-
- "contained bundles" should "work" in {
- assertTesterPasses {
- new BasicTester {
- // Specify the inner Bundle value as a Bundle literal
- val explicitBundleLit = (new MyOuterBundle).Lit(
- _.a -> (new MyBundle).Lit(_.a -> 42.U, _.b -> true.B, _.c -> MyEnum.sB)
- )
- chisel3.assert(explicitBundleLit.a.a === 42.U)
- chisel3.assert(explicitBundleLit.a.b === true.B)
- chisel3.assert(explicitBundleLit.a.c === MyEnum.sB)
- chisel3.assert(explicitBundleLit.a.isLit())
- chisel3.assert(explicitBundleLit.a.litValue().U === explicitBundleLit.a.asUInt())
-
- // Specify the inner Bundle fields directly
- val expandedBundleLit = (new MyOuterBundle).Lit(
- _.a.a -> 42.U,
- _.a.b -> true.B,
- _.b.c -> false.B,
- _.b.d -> 255.U,
- _.b.e -> MyEnum.sB,
- _.f -> MyEnum.sB
- )
- chisel3.assert(expandedBundleLit.a.a === 42.U)
- chisel3.assert(expandedBundleLit.a.b === true.B)
- chisel3.assert(expandedBundleLit.f === MyEnum.sB)
- chisel3.assert(expandedBundleLit.b.c === false.B)
- chisel3.assert(expandedBundleLit.b.d === 255.U)
- chisel3.assert(expandedBundleLit.b.e === MyEnum.sB)
- chisel3.assert(!expandedBundleLit.a.isLit()) // element e is missing
- chisel3.assert(expandedBundleLit.b.isLit())
- chisel3.assert(!expandedBundleLit.isLit()) // element a.e is missing
- chisel3.assert(expandedBundleLit.b.litValue().U === expandedBundleLit.b.asUInt())
-
- // Anonymously contruct the inner Bundle literal
- // A bit of weird syntax that depends on implementation details of the Bundle literal constructor
- val childBundleLit =
- (new MyOuterBundle).Lit(b => b.b -> b.b.Lit(_.c -> false.B, _.d -> 255.U, _.e -> MyEnum.sB))
- chisel3.assert(childBundleLit.b.c === false.B)
- chisel3.assert(childBundleLit.b.d === 255.U)
- chisel3.assert(childBundleLit.b.e === MyEnum.sB)
- chisel3.assert(childBundleLit.b.isLit())
- chisel3.assert(!childBundleLit.isLit()) // elements a and f are missing
- chisel3.assert(childBundleLit.b.litValue().U === childBundleLit.b.asUInt())
-
- stop()
- }
- }
- }
-
- "Bundle literals" should "assign" in {
- assertTesterPasses {
- new BasicTester {
- val bundleWire = Wire(Output(new MyBundle))
- val bundleLit = (new MyBundle).Lit(_.a -> 42.U, _.b -> true.B, _.c -> MyEnum.sB)
- bundleWire := bundleLit
-
- chisel3.assert(bundleWire.a === 42.U)
- chisel3.assert(bundleWire.b === true.B)
- chisel3.assert(bundleWire.c === MyEnum.sB)
- stop()
- }
- }
- }
-
- "partially initialized Bundle literals" should "assign" in {
- assertTesterPasses {
- new BasicTester {
- val bundleWire = Wire(Output(new MyBundle))
- val bundleLit = (new MyBundle).Lit(_.a -> 42.U)
- bundleWire := bundleLit
-
- chisel3.assert(bundleWire.a === 42.U)
- stop()
- }
- }
- }
-
- "Bundle literals" should "work as register reset values" in {
- assertTesterPasses {
- new BasicTester {
- val r = RegInit((new MyBundle).Lit(_.a -> 42.U, _.b -> true.B, _.c -> MyEnum.sB))
- r := (r.asUInt + 1.U).asTypeOf(new MyBundle) // prevent constprop
-
- // check reset values on first cycle out of reset
- chisel3.assert(r.a === 42.U)
- chisel3.assert(r.b === true.B)
- chisel3.assert(r.c === MyEnum.sB)
- stop()
- }
- }
- }
-
- "partially initialized Bundle literals" should "work as register reset values" in {
- assertTesterPasses {
- new BasicTester {
- val r = RegInit((new MyBundle).Lit(_.a -> 42.U))
- r.a := r.a + 1.U // prevent const prop
- chisel3.assert(r.a === 42.U) // coming out of reset
- stop()
- }
- }
- }
-
- "Fields extracted from BundleLiterals" should "work as register reset values" in {
- assertTesterPasses {
- new BasicTester {
- val r = RegInit((new MyBundle).Lit(_.a -> 42.U).a)
- r := r + 1.U // prevent const prop
- chisel3.assert(r === 42.U) // coming out of reset
- stop()
- }
- }
- }
-
- "DontCare fields extracted from BundleLiterals" should "work as register reset values" in {
- assertTesterPasses {
- new BasicTester {
- val r = RegInit((new MyBundle).Lit(_.a -> 42.U).b)
- r := reset.asBool
- printf(p"r = $r\n") // Can't assert because reset value is DontCare
- stop()
- }
- }
- }
-
- "DontCare fields extracted from BundleLiterals" should "work in other Expressions" in {
- assertTesterPasses {
- new BasicTester {
- val x = (new MyBundle).Lit(_.a -> 42.U).b || true.B
- chisel3.assert(x === true.B)
- stop()
- }
- }
- }
-
- "bundle literals with bad field specifiers" should "fail" in {
- 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] {
- 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] {
- 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] {
- 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] {
- 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] {
- 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")
- }
-
- "partial bundle literals" should "fail to pack" in {
- ChiselStage.elaborate {
- new RawModule {
- val bundleLit = (new MyBundle).Lit(_.a -> 42.U)
- bundleLit.litOption should equal(None)
- }
- }
- }
-}
diff --git a/src/test/scala/chiselTests/BundleSpec.scala b/src/test/scala/chiselTests/BundleSpec.scala
deleted file mode 100644
index 2d34b263..00000000
--- a/src/test/scala/chiselTests/BundleSpec.scala
+++ /dev/null
@@ -1,187 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.util.Decoupled
-import chisel3.stage.ChiselStage
-import chisel3.testers.BasicTester
-
-trait BundleSpecUtils {
- class BundleFooBar extends Bundle {
- val foo = UInt(16.W)
- val bar = UInt(16.W)
- }
- class BundleBarFoo extends Bundle {
- val bar = UInt(16.W)
- val foo = UInt(16.W)
- }
- class BundleFoo extends Bundle {
- val foo = UInt(16.W)
- }
- class BundleBar extends Bundle {
- val bar = UInt(16.W)
- }
-
- class BadSeqBundle extends Bundle {
- val bar = Seq(UInt(16.W), UInt(8.W), UInt(4.W))
- }
-
- class BadSeqBundleWithIgnoreSeqInBundle extends Bundle with IgnoreSeqInBundle {
- val bar = Seq(UInt(16.W), UInt(8.W), UInt(4.W))
- }
-
- class MyModule(output: Bundle, input: Bundle) extends Module {
- val io = IO(new Bundle {
- val in = Input(input)
- val out = Output(output)
- })
- io.out <> io.in
- }
-
- class BundleSerializationTest extends BasicTester {
- // Note that foo is higher order because its defined earlier in the Bundle
- val bundle = Wire(new BundleFooBar)
- bundle.foo := 0x1234.U
- bundle.bar := 0x5678.U
- // To UInt
- val uint = bundle.asUInt
- assert(uint.getWidth == 32) // elaboration time
- assert(uint === "h12345678".asUInt(32.W))
- // Back to Bundle
- val bundle2 = uint.asTypeOf(new BundleFooBar)
- assert(0x1234.U === bundle2.foo)
- assert(0x5678.U === bundle2.bar)
- stop()
- }
-}
-
-class BundleSpec extends ChiselFlatSpec with BundleSpecUtils with Utils {
- "Bundles with the same fields but in different orders" should "bulk connect" in {
- ChiselStage.elaborate { new MyModule(new BundleFooBar, new BundleBarFoo) }
- }
-
- "Bundles" should "follow UInt serialization/deserialization API" in {
- assertTesterPasses { new BundleSerializationTest }
- }
-
- "Bulk connect on Bundles" should "check that the fields match" in {
- (the[ChiselException] thrownBy extractCause[ChiselException] {
- ChiselStage.elaborate { new MyModule(new BundleFooBar, new BundleFoo) }
- }).getMessage should include("Right Record missing field")
-
- (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 extractCause[ChiselException] {
- ChiselStage.elaborate {
- new Module {
- val io = IO(new Bundle {
- val b = new BadSeqBundle
- })
- }
- }
- }).getMessage should include("Public Seq members cannot be used to define Bundle elements")
- }
-
- "Bundles" should "be allowed to have Seq if need be" in {
- assertTesterPasses {
- new BasicTester {
- val m = Module(new Module {
- val io = IO(new Bundle {
- val b = new BadSeqBundleWithIgnoreSeqInBundle
- })
- })
- stop()
- }
- }
- }
-
- "Bundles" should "be allowed to have non-Chisel Seqs" in {
- assertTesterPasses {
- new BasicTester {
- val m = Module(new Module {
- val io = IO(new Bundle {
- val f = Output(UInt(8.W))
- val unrelated = (0 to 10).toSeq
- val unrelated2 = Seq("Hello", "World", "Chisel")
- })
- io.f := 0.U
- })
- stop()
- }
- }
- }
-
- "Bundles" should "with aliased fields, should show a helpful error message" in {
- class AliasedBundle extends Bundle {
- val a = UInt(8.W)
- val b = a
- val c = SInt(8.W)
- val d = c
- }
-
- (the[ChiselException] thrownBy extractCause[ChiselException] {
- ChiselStage.elaborate {
- new Module {
- val io = IO(Output(new AliasedBundle))
- io.a := 0.U
- io.b := 1.U
- }
- }
- }).getMessage should include("contains aliased fields named (a,b),(c,d)")
- }
-
- "Bundles" should "not have bound hardware" in {
- (the[ChiselException] thrownBy extractCause[ChiselException] {
- ChiselStage.elaborate {
- new Module {
- class MyBundle(val foo: UInt) extends Bundle
- val in = IO(Input(new MyBundle(123.U))) // This should error: value passed in instead of type
- val out = IO(Output(new MyBundle(UInt(8.W))))
-
- out := in
- }
- }
- }).getMessage should include("MyBundle contains hardware fields: foo: UInt<7>(123)")
- }
- "Bundles" should "not recursively contain aggregates with bound hardware" in {
- (the[ChiselException] thrownBy extractCause[ChiselException] {
- ChiselStage.elaborate {
- new Module {
- class MyBundle(val foo: UInt) extends Bundle
- val out = IO(Output(Vec(2, UInt(8.W))))
- val in = IO(Input(new MyBundle(out(0)))) // This should error: Bound aggregate passed
- out := in
- }
- }
- }).getMessage should include("Bundle: MyBundle contains hardware fields: foo: BundleSpec_Anon.out")
- }
- "Unbound bundles sharing a field" should "not error" in {
- ChiselStage.elaborate {
- new RawModule {
- val foo = new Bundle {
- val x = UInt(8.W)
- }
- val bar = new Bundle {
- val y = foo.x
- }
- }
- }
- }
-
- // This tests the interaction of override def cloneType and the plugin.
- // We are commenting it for now because although this code fails to compile
- // as expected when just copied here, the test version is not seeing the failure.
- // """
- // class BundleBaz(w: Int) extends Bundle {
- // val baz = UInt(w.W)
- // // This is a compiler error when using the plugin, which we test below.
- // override def cloneType = (new BundleBaz(w)).asInstanceOf[this.type]
- // }
- // """ shouldNot compile
-
-}
diff --git a/src/test/scala/chiselTests/BundleWire.scala b/src/test/scala/chiselTests/BundleWire.scala
deleted file mode 100644
index 3b58d52a..00000000
--- a/src/test/scala/chiselTests/BundleWire.scala
+++ /dev/null
@@ -1,69 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-import chisel3._
-import chisel3.testers.BasicTester
-
-class Coord extends Bundle {
- val x = UInt(32.W)
- val y = UInt(32.W)
-}
-
-class BundleWire(n: Int) extends Module {
- val io = IO(new Bundle {
- val in = Input(new Coord)
- val outs = Output(Vec(n, new Coord))
- })
- val coords = Wire(Vec(n, new Coord))
- for (i <- 0 until n) {
- coords(i) := io.in
- io.outs(i) := coords(i)
- }
-}
-
-class BundleToUnitTester extends BasicTester {
- val bundle1 = Wire(new Bundle {
- val a = UInt(4.W)
- val b = UInt(4.W)
- })
- val bundle2 = Wire(new Bundle {
- val a = UInt(2.W)
- val b = UInt(6.W)
- })
-
- // 0b00011011 split as 0001 1011 and as 00 011011
- bundle1.a := 1.U
- bundle1.b := 11.U
- bundle2.a := 0.U
- bundle2.b := 27.U
-
- assert(bundle1.asUInt() === bundle2.asUInt())
-
- stop()
-}
-
-class BundleWireTester(n: Int, x: Int, y: Int) extends BasicTester {
- val dut = Module(new BundleWire(n))
- dut.io.in.x := x.asUInt
- dut.io.in.y := y.asUInt
- for (elt <- dut.io.outs) {
- assert(elt.x === x.asUInt)
- assert(elt.y === y.asUInt)
- }
- stop()
-}
-
-class BundleWireSpec extends ChiselPropSpec {
-
- property("All vec elems should match the inputs") {
- forAll(vecSizes, safeUInts, safeUInts) { (n: Int, x: Int, y: Int) =>
- assertTesterPasses { new BundleWireTester(n, x, y) }
- }
- }
-}
-
-class BundleToUIntSpec extends ChiselPropSpec {
- property("Bundles with same data but different, underlying elements should compare as UInt") {
- assertTesterPasses(new BundleToUnitTester)
- }
-}
diff --git a/src/test/scala/chiselTests/ChiselEnum.scala b/src/test/scala/chiselTests/ChiselEnum.scala
deleted file mode 100644
index dbad273b..00000000
--- a/src/test/scala/chiselTests/ChiselEnum.scala
+++ /dev/null
@@ -1,824 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.experimental.AffectsChiselPrefix
-import chisel3.internal.firrtl.UnknownWidth
-import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage}
-import chisel3.util._
-import chisel3.testers.BasicTester
-import org.scalatest.Assertion
-import org.scalatest.freespec.AnyFreeSpec
-import org.scalatest.matchers.should.Matchers
-
-object EnumExample extends ChiselEnum {
- val e0, e1, e2 = Value
-
- val e100 = Value(100.U)
- val e101 = Value(101.U)
-
- val litValues = List(0.U, 1.U, 2.U, 100.U, 101.U)
-}
-
-object OtherEnum extends ChiselEnum {
- val otherEnum = Value
-}
-
-object NonLiteralEnumType extends ChiselEnum {
- val nonLit = Value(UInt())
-}
-
-object NonIncreasingEnum extends ChiselEnum {
- val x = Value(2.U)
- val y = Value(2.U)
-}
-
-class SimpleConnector(inType: Data, outType: Data) extends Module {
- val io = IO(new Bundle {
- val in = Input(inType)
- val out = Output(outType)
- })
-
- io.out := io.in
-}
-
-class CastToUInt extends Module {
- val io = IO(new Bundle {
- val in = Input(EnumExample())
- val out = Output(UInt())
- })
-
- io.out := io.in.asUInt()
-}
-
-class CastFromLit(in: UInt) extends Module {
- val io = IO(new Bundle {
- val out = Output(EnumExample())
- val valid = Output(Bool())
- })
-
- io.out := EnumExample(in)
- io.valid := io.out.isValid
-}
-
-class CastFromNonLit extends Module {
- val io = IO(new Bundle {
- val in = Input(UInt(EnumExample.getWidth.W))
- val out = Output(EnumExample())
- val valid = Output(Bool())
- })
-
- io.out := EnumExample(io.in)
- io.valid := io.out.isValid
-}
-
-class SafeCastFromNonLit extends Module {
- val io = IO(new Bundle {
- val in = Input(UInt(EnumExample.getWidth.W))
- val out = Output(EnumExample())
- val valid = Output(Bool())
- })
-
- val (enum, valid) = EnumExample.safe(io.in)
- io.out := enum
- io.valid := valid
-}
-
-class CastFromNonLitWidth(w: Option[Int] = None) extends Module {
- val width = if (w.isDefined) w.get.W else UnknownWidth()
-
- val io = IO(new Bundle {
- val in = Input(UInt(width))
- val out = Output(EnumExample())
- })
-
- io.out := EnumExample(io.in)
-}
-
-class EnumOps(val xType: ChiselEnum, val yType: ChiselEnum) extends Module {
- val io = IO(new Bundle {
- val x = Input(xType())
- val y = Input(yType())
-
- val lt = Output(Bool())
- val le = Output(Bool())
- val gt = Output(Bool())
- val ge = Output(Bool())
- val eq = Output(Bool())
- val ne = Output(Bool())
- })
-
- io.lt := io.x < io.y
- io.le := io.x <= io.y
- io.gt := io.x > io.y
- io.ge := io.x >= io.y
- io.eq := io.x === io.y
- io.ne := io.x =/= io.y
-}
-
-object ChiselEnumFSM {
- object State extends ChiselEnum {
- val sNone, sOne1, sTwo1s = Value
-
- val correct_annotation_map = Map[String, BigInt]("sNone" -> 0, "sOne1" -> 1, "sTwo1s" -> 2)
- }
-}
-
-class ChiselEnumFSM extends Module {
- import ChiselEnumFSM.State
- import ChiselEnumFSM.State._
-
- // This FSM detects two 1's one after the other
- val io = IO(new Bundle {
- val in = Input(Bool())
- val out = Output(Bool())
- val state = Output(State())
- })
-
- val state = RegInit(sNone)
-
- io.out := (state === sTwo1s)
- io.state := state
-
- switch(state) {
- is(sNone) {
- when(io.in) {
- state := sOne1
- }
- }
- is(sOne1) {
- when(io.in) {
- state := sTwo1s
- }.otherwise {
- state := sNone
- }
- }
- is(sTwo1s) {
- when(!io.in) {
- state := sNone
- }
- }
- }
-}
-
-object Opcode extends ChiselEnum {
- val load = Value(0x03.U)
- val imm = Value(0x13.U)
- val auipc = Value(0x17.U)
- val store = Value(0x23.U)
- val reg = Value(0x33.U)
- val lui = Value(0x37.U)
- val br = Value(0x63.U)
- val jalr = Value(0x67.U)
- val jal = Value(0x6f.U)
-}
-
-class LoadStoreExample extends Module {
- val io = IO(new Bundle {
- val opcode = Input(Opcode())
- val load_or_store = Output(Bool())
- })
- io.load_or_store := io.opcode.isOneOf(Opcode.load, Opcode.store)
- printf(p"${io.opcode}")
-}
-
-class CastToUIntTester extends BasicTester {
- for ((enum, lit) <- EnumExample.all.zip(EnumExample.litValues)) {
- val mod = Module(new CastToUInt)
- mod.io.in := enum
- assert(mod.io.out === lit)
- }
- stop()
-}
-
-class CastFromLitTester extends BasicTester {
- for ((enum, lit) <- EnumExample.all.zip(EnumExample.litValues)) {
- val mod = Module(new CastFromLit(lit))
- assert(mod.io.out === enum)
- assert(mod.io.valid === true.B)
- }
- stop()
-}
-
-class CastFromNonLitTester extends BasicTester {
- for ((enum, lit) <- EnumExample.all.zip(EnumExample.litValues)) {
- val mod = Module(new CastFromNonLit)
- mod.io.in := lit
- assert(mod.io.out === enum)
- assert(mod.io.valid === true.B)
- }
-
- val invalid_values =
- (1 until (1 << EnumExample.getWidth)).filter(!EnumExample.litValues.map(_.litValue).contains(_)).map(_.U)
-
- for (invalid_val <- invalid_values) {
- val mod = Module(new CastFromNonLit)
- mod.io.in := invalid_val
-
- assert(mod.io.valid === false.B)
- }
-
- stop()
-}
-
-class SafeCastFromNonLitTester extends BasicTester {
- for ((enum, lit) <- EnumExample.all.zip(EnumExample.litValues)) {
- val mod = Module(new SafeCastFromNonLit)
- mod.io.in := lit
- assert(mod.io.out === enum)
- assert(mod.io.valid === true.B)
- }
-
- val invalid_values =
- (1 until (1 << EnumExample.getWidth)).filter(!EnumExample.litValues.map(_.litValue).contains(_)).map(_.U)
-
- for (invalid_val <- invalid_values) {
- val mod = Module(new SafeCastFromNonLit)
- mod.io.in := invalid_val
-
- assert(mod.io.valid === false.B)
- }
-
- stop()
-}
-
-class CastToInvalidEnumTester extends BasicTester {
- val invalid_value: UInt = EnumExample.litValues.last + 1.U
- Module(new CastFromLit(invalid_value))
-}
-
-class EnumOpsTester extends BasicTester {
- for {
- x <- EnumExample.all
- y <- EnumExample.all
- } {
- val mod = Module(new EnumOps(EnumExample, EnumExample))
- mod.io.x := x
- mod.io.y := y
-
- assert(mod.io.lt === (x.asUInt() < y.asUInt()))
- assert(mod.io.le === (x.asUInt() <= y.asUInt()))
- assert(mod.io.gt === (x.asUInt() > y.asUInt()))
- assert(mod.io.ge === (x.asUInt() >= y.asUInt()))
- assert(mod.io.eq === (x.asUInt() === y.asUInt()))
- assert(mod.io.ne === (x.asUInt() =/= y.asUInt()))
- }
- stop()
-}
-
-class InvalidEnumOpsTester extends BasicTester {
- val mod = Module(new EnumOps(EnumExample, OtherEnum))
- mod.io.x := EnumExample.e0
- mod.io.y := OtherEnum.otherEnum
-}
-
-class IsLitTester extends BasicTester {
- for (e <- EnumExample.all) {
- val wire = WireDefault(e)
-
- assert(e.isLit)
- assert(!wire.isLit)
- }
- stop()
-}
-
-class NextTester extends BasicTester {
- for ((e, n) <- EnumExample.all.zip(EnumExample.litValues.tail :+ EnumExample.litValues.head)) {
- assert(e.next.litValue == n.litValue)
- val w = WireDefault(e)
- assert(w.next === EnumExample(n))
- }
- stop()
-}
-
-class WidthTester extends BasicTester {
- assert(EnumExample.getWidth == EnumExample.litValues.last.getWidth)
- assert(EnumExample.all.forall(_.getWidth == EnumExample.litValues.last.getWidth))
- assert(EnumExample.all.forall { e =>
- val w = WireDefault(e)
- w.getWidth == EnumExample.litValues.last.getWidth
- })
- stop()
-}
-
-class ChiselEnumFSMTester extends BasicTester {
- import ChiselEnumFSM.State._
-
- val dut = Module(new ChiselEnumFSM)
-
- // Inputs and expected results
- val inputs: Vec[Bool] = VecInit(false.B, true.B, false.B, true.B, true.B, true.B, false.B, true.B, true.B, false.B)
- val expected: Vec[Bool] =
- VecInit(false.B, false.B, false.B, false.B, false.B, true.B, true.B, false.B, false.B, true.B)
- val expected_state = VecInit(sNone, sNone, sOne1, sNone, sOne1, sTwo1s, sTwo1s, sNone, sOne1, sTwo1s)
-
- val cntr = Counter(inputs.length)
- val cycle = cntr.value
-
- dut.io.in := inputs(cycle)
- assert(dut.io.out === expected(cycle))
- assert(dut.io.state === expected_state(cycle))
-
- when(cntr.inc()) {
- stop()
- }
-}
-
-class IsOneOfTester extends BasicTester {
- import EnumExample._
-
- // is one of itself
- assert(e0.isOneOf(e0))
-
- // is one of Seq of itself
- assert(e0.isOneOf(Seq(e0)))
- assert(e0.isOneOf(Seq(e0, e0, e0, e0)))
- assert(e0.isOneOf(e0, e0, e0, e0))
-
- // is one of Seq of multiple elements
- val subset = Seq(e0, e1, e2)
- assert(e0.isOneOf(subset))
- assert(e1.isOneOf(subset))
- assert(e2.isOneOf(subset))
-
- // is not element not in subset
- assert(!e100.isOneOf(subset))
- assert(!e101.isOneOf(subset))
-
- // test multiple elements with variable number of arguments
- assert(e0.isOneOf(e0, e1, e2))
- assert(e1.isOneOf(e0, e1, e2))
- assert(e2.isOneOf(e0, e1, e2))
- assert(!e100.isOneOf(e0, e1, e2))
- assert(!e101.isOneOf(e0, e1, e2))
-
- // is not another value
- assert(!e0.isOneOf(e1))
- assert(!e2.isOneOf(e101))
-
- stop()
-}
-
-class ChiselEnumSpec extends ChiselFlatSpec with Utils {
- import chisel3.internal.ChiselException
-
- behavior.of("ChiselEnum")
-
- it should "fail to instantiate non-literal enums with the Value function" in {
- 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 extractCause[ExceptionInInitializerError] {
- ChiselStage.elaborate(new SimpleConnector(NonIncreasingEnum(), NonIncreasingEnum()))
- }
- }
-
- it should "connect enums of the same type" in {
- 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 extractCause[ChiselException] {
- ChiselStage.elaborate(new SimpleConnector(EnumExample(), UInt()))
- }
- }
-
- it should "fail to connect enums of different types" in {
- a[ChiselException] should be thrownBy extractCause[ChiselException] {
- ChiselStage.elaborate(new SimpleConnector(EnumExample(), OtherEnum()))
- }
-
- a[ChiselException] should be thrownBy extractCause[ChiselException] {
- ChiselStage.elaborate(new SimpleConnector(EnumExample.Type(), OtherEnum.Type()))
- }
- }
-
- it should "cast enums to UInts correctly" in {
- assertTesterPasses(new CastToUIntTester)
- }
-
- it should "cast literal UInts to enums correctly" in {
- assertTesterPasses(new CastFromLitTester)
- }
-
- it should "cast non-literal UInts to enums correctly and detect illegal casts" in {
- assertTesterPasses(new CastFromNonLitTester)
- }
-
- it should "safely cast non-literal UInts to enums correctly and detect illegal casts" in {
- assertTesterPasses(new SafeCastFromNonLitTester)
- }
-
- it should "prevent illegal literal casts to enums" in {
- 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)
- ChiselStage.elaborate(new CastFromNonLitWidth(Some(w)))
-
- 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 extractCause[ChiselException] {
- ChiselStage.elaborate(new CastFromNonLitWidth(Some(w)))
- }
- }
- }
-
- it should "execute enum comparison operations correctly" in {
- assertTesterPasses(new EnumOpsTester)
- }
-
- it should "fail to compare enums of different types" in {
- a[ChiselException] should be thrownBy extractCause[ChiselException] {
- ChiselStage.elaborate(new InvalidEnumOpsTester)
- }
- }
-
- it should "correctly check whether or not enums are literal" in {
- assertTesterPasses(new IsLitTester)
- }
-
- it should "return the correct next values for enums" in {
- assertTesterPasses(new NextTester)
- }
-
- it should "return the correct widths for enums" in {
- assertTesterPasses(new WidthTester)
- }
-
- it should "maintain Scala-level type-safety" in {
- def foo(e: EnumExample.Type): Unit = {}
-
- "foo(EnumExample.e1); foo(EnumExample.e1.next)" should compile
- "foo(OtherEnum.otherEnum)" shouldNot compile
- }
-
- it should "prevent enums from being declared without names" in {
- "object UnnamedEnum extends ChiselEnum { Value }" shouldNot compile
- }
-
- "ChiselEnum FSM" should "work" in {
- assertTesterPasses(new ChiselEnumFSMTester)
- }
-
- "Casting a UInt to an Enum" should "warn if the UInt can express illegal states" in {
- object MyEnum extends ChiselEnum {
- val e0, e1, e2 = Value
- }
-
- class MyModule extends Module {
- val in = IO(Input(UInt(2.W)))
- val out = IO(Output(MyEnum()))
- out := MyEnum(in)
- }
- val (log, _) = grabLog(ChiselStage.elaborate(new MyModule))
- log should include("warn")
- log should include("Casting non-literal UInt")
- }
-
- it should "NOT warn if the Enum is total" in {
- object TotalEnum extends ChiselEnum {
- val e0, e1, e2, e3 = Value
- }
-
- class MyModule extends Module {
- val in = IO(Input(UInt(2.W)))
- val out = IO(Output(TotalEnum()))
- out := TotalEnum(in)
- }
- val (log, _) = grabLog(ChiselStage.elaborate(new MyModule))
- (log should not).include("warn")
- }
-
- it should "suppress warning using suppressEnumCastWarning" in {
- object TestEnum extends ChiselEnum {
- val e0, e1, e2 = Value
- }
-
- class MyModule extends Module {
- val in = IO(Input(UInt(2.W)))
- val out = IO(Output(TestEnum()))
- suppressEnumCastWarning {
- val res = TestEnum(in)
- out := res
- }
- }
- val (log, _) = grabLog(ChiselStage.elaborate(new MyModule))
- (log should not).include("warn")
- }
-
- it should "suppress exactly one warning using suppressEnumCastWarning" in {
- object TestEnum1 extends ChiselEnum {
- val e0, e1, e2 = Value
- }
- object TestEnum2 extends ChiselEnum {
- val e0, e1, e2 = Value
- }
-
- class MyModule extends Module {
- val in = IO(Input(UInt(2.W)))
- val out1 = IO(Output(TestEnum1()))
- val out2 = IO(Output(TestEnum2()))
- suppressEnumCastWarning {
- out1 := TestEnum1(in)
- }
- out2 := TestEnum2(in)
- }
- val (log, _) = grabLog(ChiselStage.elaborate(new MyModule))
- log should include("warn")
- log should include("TestEnum2") // not suppressed
- (log should not).include("TestEnum1") // suppressed
- }
-
- "Casting a UInt to an Enum with .safe" should "NOT warn" in {
- object MyEnum extends ChiselEnum {
- val e0, e1, e2 = Value
- }
-
- class MyModule extends Module {
- val in = IO(Input(UInt(2.W)))
- val out = IO(Output(MyEnum()))
- out := MyEnum.safe(in)._1
- }
- val (log, _) = grabLog(ChiselStage.elaborate(new MyModule))
- (log should not).include("warn")
- }
-
- it should "NOT generate any validity logic if the Enum is total" in {
- object TotalEnum extends ChiselEnum {
- val e0, e1, e2, e3 = Value
- }
-
- class MyModule extends Module {
- val in = IO(Input(UInt(2.W)))
- val out = IO(Output(TotalEnum()))
- val (res, valid) = TotalEnum.safe(in)
- assert(valid.litToBoolean, "It should be true.B")
- out := res
- }
- val (log, _) = grabLog(ChiselStage.elaborate(new MyModule))
- (log should not).include("warn")
- }
-
- it should "correctly check if the enumeration is one of the values in a given sequence" in {
- assertTesterPasses(new IsOneOfTester)
- }
-
- it should "work with Printables" in {
- ChiselStage.emitChirrtl(new LoadStoreExample) should include(
- """printf(clock, UInt<1>("h1"), "%c%c%c%c%c", _chiselTestsOpcodePrintable[0], _chiselTestsOpcodePrintable[1], _chiselTestsOpcodePrintable[2], _chiselTestsOpcodePrintable[3], _chiselTestsOpcodePrintable[4])"""
- )
- }
-}
-
-class ChiselEnumAnnotator extends Module {
- import EnumExample._
-
- object LocalEnum extends ChiselEnum {
- val le0, le1 = Value
- val le2 = Value
- val le100 = Value(100.U)
- }
-
- val io = IO(new Bundle {
- val in = Input(EnumExample())
- val out = Output(EnumExample())
- val other = Output(OtherEnum())
- val local = Output(LocalEnum())
- })
-
- class Bund extends Bundle {
- val field = EnumExample()
- val other = OtherEnum()
- val local = LocalEnum()
- val vec = Vec(5, EnumExample())
- val inner_bundle1 = new Bundle {
- val x = UInt(4.W)
- val y = Vec(3, UInt(4.W))
- val e = EnumExample()
- val v = Vec(3, EnumExample())
- }
- val inner_bundle2 = new Bundle {}
- val inner_bundle3 = new Bundle {
- val x = Bool()
- }
- val inner_bundle4 = new Bundle {
- val inner_inner_bundle = new Bundle {}
- }
- }
-
- val simple = Wire(EnumExample())
- val vec = VecInit(e0, e1, e2)
- val vec_of_vecs = VecInit(VecInit(e0, e1), VecInit(e100, e101))
-
- val bund = Wire(new Bund())
- val vec_of_bundles = Wire(Vec(5, new Bund()))
-
- io.out := e101
- io.other := OtherEnum.otherEnum
- io.local := LocalEnum.le0
- simple := e100
- bund := DontCare
- vec_of_bundles := DontCare
-
- // Make sure that dynamically indexing into a Vec of enums will not cause an elaboration error.
- // The components created here will not be annotated.
- val cycle = RegInit(0.U)
- cycle := cycle + 1.U
-
- val indexed1 = vec_of_vecs(cycle)(cycle)
- val indexed2 = vec_of_bundles(cycle)
-}
-
-class ChiselEnumAnnotatorWithChiselName extends Module {
- import EnumExample._
-
- object LocalEnum extends ChiselEnum with AffectsChiselPrefix {
- val le0, le1 = Value
- val le2 = Value
- val le100 = Value(100.U)
- }
-
- val io = IO(new Bundle {
- val in = Input(EnumExample())
- val out = Output(EnumExample())
- val other = Output(OtherEnum())
- val local = Output(LocalEnum())
- })
-
- class Bund extends Bundle {
- val field = EnumExample()
- val other = OtherEnum()
- val local = LocalEnum()
- val vec = Vec(5, EnumExample())
- val inner_bundle1 = new Bundle {
- val x = UInt(4.W)
- val y = Vec(3, UInt(4.W))
- val e = EnumExample()
- val v = Vec(3, EnumExample())
- }
- val inner_bundle2 = new Bundle {}
- val inner_bundle3 = new Bundle {
- val x = Bool()
- }
- val inner_bundle4 = new Bundle {
- val inner_inner_bundle = new Bundle {}
- }
- }
-
- val simple = Wire(EnumExample())
- val vec = VecInit(e0, e1, e2)
- val vec_of_vecs = VecInit(VecInit(e0, e1), VecInit(e100, e101))
-
- val bund = Wire(new Bund())
- val vec_of_bundles = Wire(Vec(5, new Bund()))
-
- io.out := e101
- io.other := OtherEnum.otherEnum
- io.local := LocalEnum.le0
- simple := e100
- bund := DontCare
- vec_of_bundles := DontCare
-
- // Make sure that dynamically indexing into a Vec of enums will not cause an elaboration error.
- // The components created here will not be annotated.
- val cycle = RegInit(0.U)
- cycle := cycle + 1.U
-
- val indexed1 = vec_of_vecs(cycle)(cycle)
- val indexed2 = vec_of_bundles(cycle)
-}
-
-class ChiselEnumAnnotationSpec extends AnyFreeSpec with Matchers {
- import chisel3.experimental.EnumAnnotations._
- import firrtl.annotations.{Annotation, ComponentName}
-
- val enumExampleName = "EnumExample"
- val otherEnumName = "OtherEnum"
- val localEnumName = "LocalEnum"
-
- case class CorrectDefAnno(typeName: String, definition: Map[String, BigInt])
- case class CorrectCompAnno(targetName: String, typeName: String)
- case class CorrectVecAnno(targetName: String, typeName: String, fields: Set[Seq[String]])
-
- val correctDefAnnos = Seq(
- CorrectDefAnno(otherEnumName, Map("otherEnum" -> 0)),
- CorrectDefAnno(enumExampleName, Map("e0" -> 0, "e1" -> 1, "e2" -> 2, "e100" -> 100, "e101" -> 101)),
- CorrectDefAnno(localEnumName, Map("le0" -> 0, "le1" -> 1, "le2" -> 2, "le100" -> 100))
- )
-
- val correctCompAnnos = Seq(
- CorrectCompAnno("io.other", otherEnumName),
- CorrectCompAnno("io.local", localEnumName),
- CorrectCompAnno("io.out", enumExampleName),
- CorrectCompAnno("io.in", enumExampleName),
- CorrectCompAnno("simple", enumExampleName),
- CorrectCompAnno("bund.field", enumExampleName),
- CorrectCompAnno("bund.other", otherEnumName),
- CorrectCompAnno("bund.local", localEnumName),
- CorrectCompAnno("bund.inner_bundle1.e", enumExampleName)
- )
-
- val correctVecAnnos = Seq(
- CorrectVecAnno("vec", enumExampleName, Set()),
- CorrectVecAnno("vec_of_vecs", enumExampleName, Set()),
- CorrectVecAnno(
- "vec_of_bundles",
- enumExampleName,
- Set(Seq("field"), Seq("vec"), Seq("inner_bundle1", "e"), Seq("inner_bundle1", "v"))
- ),
- CorrectVecAnno("vec_of_bundles", otherEnumName, Set(Seq("other"))),
- CorrectVecAnno("vec_of_bundles", localEnumName, Set(Seq("local"))),
- CorrectVecAnno("bund.vec", enumExampleName, Set()),
- CorrectVecAnno("bund.inner_bundle1.v", enumExampleName, Set())
- )
-
- def printAnnos(annos: Seq[Annotation]) {
- println("Enum definitions:")
- annos.foreach {
- case EnumDefAnnotation(enumTypeName, definition) => println(s"\t$enumTypeName: $definition")
- case _ =>
- }
- println("Enum components:")
- annos.foreach {
- case EnumComponentAnnotation(target, enumTypeName) => println(s"\t$target => $enumTypeName")
- case _ =>
- }
- println("Enum vecs:")
- annos.foreach {
- case EnumVecAnnotation(target, enumTypeName, fields) => println(s"\t$target[$fields] => $enumTypeName")
- case _ =>
- }
- }
-
- def isCorrect(anno: EnumDefAnnotation, correct: CorrectDefAnno): Boolean = {
- (anno.typeName == correct.typeName ||
- anno.typeName.endsWith("." + correct.typeName) ||
- anno.typeName.endsWith("$" + correct.typeName)) &&
- anno.definition == correct.definition
- }
-
- def isCorrect(anno: EnumComponentAnnotation, correct: CorrectCompAnno): Boolean = {
- (anno.target match {
- case ComponentName(name, _) => name == correct.targetName
- case _ => throw new Exception("Unknown target type in EnumComponentAnnotation")
- }) &&
- (anno.enumTypeName == correct.typeName || anno.enumTypeName.endsWith("." + correct.typeName) ||
- anno.enumTypeName.endsWith("$" + correct.typeName))
- }
-
- def isCorrect(anno: EnumVecAnnotation, correct: CorrectVecAnno): Boolean = {
- (anno.target match {
- case ComponentName(name, _) => name == correct.targetName
- case _ => throw new Exception("Unknown target type in EnumVecAnnotation")
- }) &&
- (anno.typeName == correct.typeName || anno.typeName.endsWith("." + correct.typeName) ||
- anno.typeName.endsWith("$" + correct.typeName)) &&
- anno.fields.map(_.toSeq).toSet == correct.fields
- }
-
- def allCorrectDefs(annos: Seq[EnumDefAnnotation], corrects: Seq[CorrectDefAnno]): Boolean = {
- corrects.forall(c => annos.exists(isCorrect(_, c))) &&
- correctDefAnnos.length == annos.length
- }
-
- // Because temporary variables might be formed and annotated, we do not check that every component or vector
- // annotation is accounted for in the correct results listed above
- def allCorrectComps(annos: Seq[EnumComponentAnnotation], corrects: Seq[CorrectCompAnno]): Boolean =
- corrects.forall(c => annos.exists(isCorrect(_, c)))
-
- def allCorrectVecs(annos: Seq[EnumVecAnnotation], corrects: Seq[CorrectVecAnno]): Boolean =
- corrects.forall(c => annos.exists(isCorrect(_, c)))
-
- def test(strongEnumAnnotatorGen: () => Module) {
- val annos = (new ChiselStage).execute(
- Array("--target-dir", "test_run_dir", "--no-run-firrtl"),
- Seq(ChiselGeneratorAnnotation(strongEnumAnnotatorGen))
- )
-
- 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)
-
- }
-
- "Test that strong enums annotate themselves appropriately" in {
- test(() => new ChiselEnumAnnotator)
- test(() => new ChiselEnumAnnotatorWithChiselName)
- }
-}
diff --git a/src/test/scala/chiselTests/ChiselSpec.scala b/src/test/scala/chiselTests/ChiselSpec.scala
deleted file mode 100644
index e00afcf6..00000000
--- a/src/test/scala/chiselTests/ChiselSpec.scala
+++ /dev/null
@@ -1,368 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.aop.Aspect
-import chisel3.stage.{
- ChiselGeneratorAnnotation,
- ChiselStage,
- NoRunFirrtlCompilerAnnotation,
- PrintFullStackTraceAnnotation
-}
-import chisel3.testers._
-import firrtl.annotations.Annotation
-import firrtl.ir.Circuit
-import firrtl.util.BackendCompilationUtilities
-import firrtl.{AnnotationSeq, EmittedVerilogCircuitAnnotation}
-import _root_.logger.Logger
-import firrtl.stage.FirrtlCircuitAnnotation
-import org.scalacheck._
-import org.scalatest._
-import org.scalatest.flatspec.AnyFlatSpec
-import org.scalatest.freespec.AnyFreeSpec
-import org.scalatest.funspec.AnyFunSpec
-import org.scalatest.propspec.AnyPropSpec
-import org.scalatest.matchers.should.Matchers
-import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
-
-import java.io.{ByteArrayOutputStream, PrintStream}
-import java.security.Permission
-import scala.reflect.ClassTag
-
-/** Common utility functions for Chisel unit tests. */
-trait ChiselRunners extends Assertions with BackendCompilationUtilities {
- def runTester(
- t: => BasicTester,
- additionalVResources: Seq[String] = Seq(),
- annotations: AnnotationSeq = Seq()
- ): Boolean = {
- // Change this to enable Treadle as a backend
- val defaultBackend = {
- val useTreadle = sys.env.get("CHISEL3_CI_USE_TREADLE").isDefined
- if (useTreadle) chisel3.testers.TreadleBackend else chisel3.testers.TesterDriver.defaultBackend
- }
- val hasBackend = TestUtils.containsBackend(annotations)
- val annos: Seq[Annotation] = if (hasBackend) annotations else defaultBackend +: annotations
- TesterDriver.execute(() => t, additionalVResources, annos)
- }
- def assertTesterPasses(
- t: => BasicTester,
- additionalVResources: Seq[String] = Seq(),
- annotations: AnnotationSeq = Seq()
- ): Unit = {
- assert(runTester(t, additionalVResources, annotations))
- }
- def assertTesterFails(
- t: => BasicTester,
- additionalVResources: Seq[String] = Seq(),
- annotations: Seq[chisel3.aop.Aspect[_]] = Seq()
- ): Unit = {
- assert(!runTester(t, additionalVResources, annotations))
- }
-
- def assertKnownWidth(expected: Int)(gen: => Data): Unit = {
- assertTesterPasses(new BasicTester {
- val x = gen
- assert(x.getWidth === expected)
- // Sanity check that firrtl doesn't change the width
- x := 0.U.asTypeOf(chiselTypeOf(x))
- val (_, done) = chisel3.util.Counter(true.B, 2)
- when(done) {
- chisel3.assert(~(x.asUInt) === -1.S(expected.W).asUInt)
- stop()
- }
- })
- }
-
- def assertInferredWidth(expected: Int)(gen: => Data): Unit = {
- assertTesterPasses(new BasicTester {
- val x = gen
- assert(!x.isWidthKnown, s"Asserting that width should be inferred yet width is known to Chisel!")
- x := 0.U.asTypeOf(chiselTypeOf(x))
- val (_, done) = chisel3.util.Counter(true.B, 2)
- when(done) {
- chisel3.assert(~(x.asUInt) === -1.S(expected.W).asUInt)
- stop()
- }
- })
- }
-
- /** 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 = {
- (new ChiselStage)
- .execute(
- Array("--target-dir", createTestDirectory(this.getClass.getSimpleName).toString),
- Seq(ChiselGeneratorAnnotation(() => t))
- )
- .collectFirst {
- case EmittedVerilogCircuitAnnotation(a) => a.value
- }
- .getOrElse(fail("No Verilog circuit was emitted by the FIRRTL compiler!"))
- }
-
- def elaborateAndGetModule[A <: RawModule](t: => A): A = {
- var res: Any = null
- ChiselStage.elaborate {
- res = t
- res.asInstanceOf[A]
- }
- res.asInstanceOf[A]
- }
-
- /** Compiles a Chisel Module to FIRRTL
- * NOTE: This uses the "test_run_dir" as the default directory for generated code.
- * @param t the generator for the module
- * @return The FIRRTL Circuit and Annotations _before_ FIRRTL compilation
- */
- def getFirrtlAndAnnos(t: => RawModule, providedAnnotations: Seq[Annotation] = Nil): (Circuit, Seq[Annotation]) = {
- val args = Array(
- "--target-dir",
- createTestDirectory(this.getClass.getSimpleName).toString,
- "--no-run-firrtl",
- "--full-stacktrace"
- )
- val annos = (new ChiselStage).execute(args, Seq(ChiselGeneratorAnnotation(() => t)) ++ providedAnnotations)
- val circuit = annos.collectFirst {
- case FirrtlCircuitAnnotation(c) => c
- }.getOrElse(fail("No FIRRTL Circuit found!!"))
- (circuit, annos)
- }
-}
-
-/** Spec base class for BDD-style testers. */
-abstract class ChiselFlatSpec extends AnyFlatSpec with ChiselRunners with Matchers
-
-/** Spec base class for BDD-style testers. */
-abstract class ChiselFreeSpec extends AnyFreeSpec with ChiselRunners with Matchers
-
-/** Spec base class for BDD-style testers. */
-abstract class ChiselFunSpec extends AnyFunSpec with ChiselRunners with Matchers
-
-/** Spec base class for property-based testers. */
-abstract class ChiselPropSpec extends AnyPropSpec with ChiselRunners with ScalaCheckPropertyChecks with Matchers {
-
- // Constrain the default number of instances generated for every use of forAll.
- implicit override val generatorDrivenConfig: PropertyCheckConfiguration =
- PropertyCheckConfiguration(minSuccessful = 8, minSize = 1, sizeRange = 3)
-
- // Generator for small positive integers.
- val smallPosInts = Gen.choose(1, 4)
-
- // Generator for positive (ascending or descending) ranges.
- def posRange: Gen[Range] = for {
- dir <- Gen.oneOf(true, false)
- step <- Gen.choose(1, 3)
- m <- Gen.choose(1, 10)
- n <- Gen.choose(1, 10)
- } yield {
- if (dir) {
- Range(m, (m + n) * step, step)
- } else {
- Range((m + n) * step, m, -step)
- }
- }
-
- // Generator for widths considered "safe".
- val safeUIntWidth = Gen.choose(1, 30)
-
- // Generators for integers that fit within "safe" widths.
- val safeUInts = Gen.choose(0, (1 << 30))
-
- // Generators for vector sizes.
- val vecSizes = Gen.choose(0, 4)
-
- // Generator for string representing an arbitrary integer.
- val binaryString = for (i <- Arbitrary.arbitrary[Int]) yield "b" + i.toBinaryString
-
- // Generator for a sequence of Booleans of size n.
- def enSequence(n: Int): Gen[List[Boolean]] = Gen.containerOfN[List, Boolean](n, Gen.oneOf(true, false))
-
- // Generator which gives a width w and a list (of size n) of numbers up to w bits.
- def safeUIntN(n: Int): Gen[(Int, List[Int])] = for {
- w <- smallPosInts
- i <- Gen.containerOfN[List, Int](n, Gen.choose(0, (1 << w) - 1))
- } yield (w, i)
-
- // Generator which gives a width w and a numbers up to w bits.
- val safeUInt = for {
- w <- smallPosInts
- i <- Gen.choose(0, (1 << w) - 1)
- } yield (w, i)
-
- // Generator which gives a width w and a list (of size n) of a pair of numbers up to w bits.
- def safeUIntPairN(n: Int): Gen[(Int, List[(Int, Int)])] = for {
- w <- smallPosInts
- i <- Gen.containerOfN[List, Int](n, Gen.choose(0, (1 << w) - 1))
- j <- Gen.containerOfN[List, Int](n, Gen.choose(0, (1 << w) - 1))
- } yield (w, i.zip(j))
-
- // Generator which gives a width w and a pair of numbers up to w bits.
- val safeUIntPair = for {
- w <- smallPosInts
- i <- Gen.choose(0, (1 << w) - 1)
- j <- Gen.choose(0, (1 << w) - 1)
- } yield (w, i, j)
-}
-
-trait Utils {
-
- /** Run some Scala thunk and return STDOUT and STDERR as strings.
- * @param thunk some Scala code
- * @return a tuple containing STDOUT, STDERR, and what the thunk returns
- */
- def grabStdOutErr[T](thunk: => T): (String, String, T) = {
- val stdout, stderr = new ByteArrayOutputStream()
- val ret = scala.Console.withOut(stdout) { scala.Console.withErr(stderr) { thunk } }
- (stdout.toString, stderr.toString, ret)
- }
-
- /** Run some Scala thunk and return all logged messages as Strings
- * @param thunk some Scala code
- * @return a tuple containing LOGGED, and what the thunk returns
- */
- def grabLog[T](thunk: => T): (String, T) = {
- val baos = new ByteArrayOutputStream()
- val stream = new PrintStream(baos, true, "utf-8")
- val ret = Logger.makeScope(Nil) {
- Logger.setOutput(stream)
- thunk
- }
- (baos.toString, ret)
- }
-
- /** Encodes a System.exit exit code
- * @param status the exit code
- */
- private case class ExitException(status: Int) extends SecurityException(s"Found a sys.exit with code $status")
-
- /** A security manager that converts calls to System.exit into [[ExitException]]s by explicitly disabling the ability of
- * a thread to actually exit. For more information, see:
- * - https://docs.oracle.com/javase/tutorial/essential/environment/security.html
- */
- private class ExceptOnExit extends SecurityManager {
- override def checkPermission(perm: Permission): Unit = {}
- override def checkPermission(perm: Permission, context: Object): Unit = {}
- override def checkExit(status: Int): Unit = {
- super.checkExit(status)
- throw ExitException(status)
- }
- }
-
- /** Encodes a file that some code tries to write to
- * @param the file name
- */
- private case class WriteException(file: String) extends SecurityException(s"Tried to write to file $file")
-
- /** A security manager that converts writes to any file into [[WriteException]]s.
- */
- private class ExceptOnWrite extends SecurityManager {
- override def checkPermission(perm: Permission): Unit = {}
- override def checkPermission(perm: Permission, context: Object): Unit = {}
- override def checkWrite(file: String): Unit = {
- super.checkWrite(file)
- throw WriteException(file)
- }
- }
-
- /** Run some Scala code (a thunk) in an environment where all System.exit are caught and returned. This avoids a
- * situation where a test results in something actually exiting and killing the entire test. This is necessary if you
- * want to test a command line program, e.g., the `main` method of [[firrtl.options.Stage Stage]].
- *
- * NOTE: THIS WILL NOT WORK IN SITUATIONS WHERE THE THUNK IS CATCHING ALL [[Exception]]s OR [[Throwable]]s, E.G.,
- * SCOPT. IF THIS IS HAPPENING THIS WILL NOT WORK. REPEAT THIS WILL NOT WORK.
- * @param thunk some Scala code
- * @return either the output of the thunk (`Right[T]`) or an exit code (`Left[Int]`)
- */
- def catchStatus[T](thunk: => T): Either[Int, T] = {
- try {
- System.setSecurityManager(new ExceptOnExit())
- Right(thunk)
- } catch {
- case ExitException(a) => Left(a)
- } finally {
- System.setSecurityManager(null)
- }
- }
-
- /** Run some Scala code (a thunk) in an environment where file writes are caught and the file that a program tries to
- * write to is returned. This is useful if you want to test that some thunk either tries to write to a specific file
- * or doesn't try to write at all.
- */
- def catchWrites[T](thunk: => T): Either[String, T] = {
- throw new Exception("Do not use, not thread-safe")
- try {
- System.setSecurityManager(new ExceptOnWrite())
- Right(thunk)
- } catch {
- case WriteException(a) => Left(a)
- } finally {
- System.setSecurityManager(null)
- }
- }
-
- /** A tester which runs generator and uses an aspect to check the returned object
- * @param gen function to generate a Chisel module
- * @param f a function to check the Chisel module
- * @tparam T the Chisel module class
- */
- def aspectTest[T <: RawModule](gen: () => T)(f: T => Unit)(implicit scalaMajorVersion: Int): Unit = {
- // Runs chisel stage
- def run[T <: RawModule](gen: () => T, annotations: AnnotationSeq): AnnotationSeq = {
- new ChiselStage().run(
- Seq(ChiselGeneratorAnnotation(gen), NoRunFirrtlCompilerAnnotation, PrintFullStackTraceAnnotation) ++ annotations
- )
- }
- // Creates a wrapping aspect to contain checking function
- case object BuiltAspect extends Aspect[T] {
- override def toAnnotation(top: T): AnnotationSeq = { f(top); Nil }
- }
- val currentMajorVersion = scala.util.Properties.versionNumberString.split('.')(1).toInt
- if (currentMajorVersion >= scalaMajorVersion) {
- run(gen, Seq(BuiltAspect))
- }
- }
-
- /** 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 => ()
- case h :: t => throw h
- }
- }
-
- }
-}
diff --git a/src/test/scala/chiselTests/ChiselTestUtilitiesSpec.scala b/src/test/scala/chiselTests/ChiselTestUtilitiesSpec.scala
deleted file mode 100644
index 451ba885..00000000
--- a/src/test/scala/chiselTests/ChiselTestUtilitiesSpec.scala
+++ /dev/null
@@ -1,57 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import org.scalatest.exceptions.TestFailedException
-
-class ChiselTestUtilitiesSpec extends ChiselFlatSpec {
- // Who tests the testers?
- "assertKnownWidth" should "error when the expected width is wrong" in {
- intercept[TestFailedException] {
- assertKnownWidth(7) {
- Wire(UInt(8.W))
- }
- }
- }
-
- it should "error when the width is unknown" in {
- intercept[ChiselException] {
- assertKnownWidth(7) {
- Wire(UInt())
- }
- }
- }
-
- it should "work if the width is correct" in {
- assertKnownWidth(8) {
- Wire(UInt(8.W))
- }
- }
-
- "assertInferredWidth" should "error if the width is known" in {
- intercept[TestFailedException] {
- assertInferredWidth(8) {
- Wire(UInt(8.W))
- }
- }
- }
-
- it should "error if the expected width is wrong" in {
- a[TestFailedException] shouldBe thrownBy {
- assertInferredWidth(8) {
- val w = Wire(UInt())
- w := 2.U(2.W)
- w
- }
- }
- }
-
- it should "pass if the width is correct" in {
- assertInferredWidth(4) {
- val w = Wire(UInt())
- w := 2.U(4.W)
- w
- }
- }
-}
diff --git a/src/test/scala/chiselTests/Clock.scala b/src/test/scala/chiselTests/Clock.scala
deleted file mode 100644
index c28e1344..00000000
--- a/src/test/scala/chiselTests/Clock.scala
+++ /dev/null
@@ -1,36 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.stage.ChiselStage
-import chisel3.testers.BasicTester
-
-class ClockAsUIntTester extends BasicTester {
- assert(true.B.asClock.asUInt === 1.U)
- assert(true.B.asClock.asBool === true.B)
- stop()
-}
-
-class WithClockAndNoReset extends RawModule {
- val clock1 = IO(Input(Clock()))
- val clock2 = IO(Input(Clock()))
- val in = IO(Input(Bool()))
- val out = IO(Output(Bool()))
- val a = withClock(clock2) {
- RegNext(in)
- }
-
- out := a
-}
-
-class ClockSpec extends ChiselPropSpec {
- property("Bool.asClock.asUInt should pass a signal through unaltered") {
- assertTesterPasses { new ClockAsUIntTester }
- }
-
- property("Should be able to use withClock in a module with no reset") {
- val circuit = 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
deleted file mode 100644
index 4a70db85..00000000
--- a/src/test/scala/chiselTests/CloneModuleSpec.scala
+++ /dev/null
@@ -1,155 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.stage.ChiselStage
-import chisel3.util.{log2Ceil, Decoupled, DeqIO, EnqIO, Queue, QueueIO}
-import chisel3.experimental.{CloneModuleAsRecord, IO}
-import chisel3.testers.BasicTester
-
-class MultiIOQueue[T <: Data](gen: T, val entries: Int) extends Module {
- val clk = IO(Input(Clock()))
- val rst = IO(Input(Reset()))
- val enq = IO(Flipped(EnqIO(gen)))
- val deq = IO(Flipped(DeqIO(gen)))
- val count = IO(Output(UInt(log2Ceil(entries + 1).W)))
- val impl = withClockAndReset(clk, rst) { Module(new Queue(gen, entries)) }
- impl.io.enq <> enq
- deq <> impl.io.deq
- count := impl.io.count
-}
-
-class QueueClone(multiIO: Boolean = false) extends Module {
- val io = IO(new QueueIO(UInt(32.W), 4))
- if (multiIO) {
- val q1 = Module(new MultiIOQueue(UInt(32.W), 2))
- val q2_io = CloneModuleAsRecord(q1)
- q1.clk := clock
- q1.rst := reset
- q1.enq <> io.enq
- q2_io("clk").asInstanceOf[Clock] := clock
- q2_io("rst").asInstanceOf[Reset] := reset
- q2_io("enq").asInstanceOf[q1.enq.type] <> q1.deq
- io.deq <> q2_io("deq").asInstanceOf[q1.deq.type]
- io.count := q1.count + q2_io("count").asInstanceOf[q1.count.type]
- } else {
- val q1 = Module(new Queue(UInt(32.W), 2))
- val q2_io = CloneModuleAsRecord(q1)
- q1.io.enq <> io.enq
- val q2_io_bundle = q2_io("io").asInstanceOf[q1.io.type]
- q2_io_bundle.enq <> q1.io.deq
- io.deq <> q2_io_bundle.deq
- io.count := q1.io.count + q2_io_bundle.count
- }
-}
-
-class QueueCloneTester(x: Int, multiIO: Boolean = false) extends BasicTester {
- val dut = Module(new QueueClone(multiIO))
- val start = RegNext(dut.io.enq.fire, true.B)
- val accept = RegNext(dut.io.deq.valid, false.B)
- dut.io.enq.bits := x.U
- dut.io.enq.valid := start
- dut.io.deq.ready := accept
- when(dut.io.deq.fire) {
- assert(dut.io.deq.bits === x.U)
- stop()
- }
-}
-
-class CloneModuleAsRecordAnnotate extends Module {
- override def desiredName = "Top"
- val in = IO(Flipped(Decoupled(UInt(8.W))))
- val out = IO(Decoupled(UInt(8.W)))
-
- val q1 = Module(new Queue(UInt(8.W), 4))
- val q2 = CloneModuleAsRecord(q1)
- val q2_io = q2("io").asInstanceOf[q1.io.type]
- // Also make a wire to check that cloning works, can be connected to, and annotated
- val q2_wire = {
- val w = Wire(chiselTypeOf(q2))
- w <> q2
- w
- }
- // But connect to the original (using last connect semantics to override connects to wire
- q1.io.enq <> in
- q2_io.enq <> q1.io.deq
- out <> q2_io.deq
-}
-
-class CloneModuleSpec extends ChiselPropSpec {
-
- val xVals = Table(
- ("x"), // First tuple defines column names
- (42), // Subsequent tuples define the data
- (63),
- (99)
- )
-
- property("QueueCloneTester should return the correct result") {
- forAll(xVals) { (x: Int) =>
- assertTesterPasses { new QueueCloneTester(x) }
- }
- }
-
- property("QueueClone's cloned queues should share the same module") {
- val c = ChiselStage.convert(new QueueClone)
- assert(c.modules.length == 2)
- }
-
- property("Clone of MultiIOModule should simulate correctly") {
- forAll(xVals) { (x: Int) =>
- assertTesterPasses { new QueueCloneTester(x, multiIO = true) }
- }
- }
-
- property("Clones of MultiIOModules should share the same module") {
- val c = ChiselStage.convert(new QueueClone(multiIO = true))
- assert(c.modules.length == 3)
- }
-
- property("Cloned Modules should annotate correctly") {
- // Hackily get the actually Module object out
- var mod: CloneModuleAsRecordAnnotate = null
- val res = ChiselStage.convert {
- mod = new CloneModuleAsRecordAnnotate
- mod
- }
- // ********** Checking the output of CloneModuleAsRecord **********
- // Note that we overrode desiredName so that Top is named "Top"
- mod.q1.io.enq.toTarget.serialize should be("~Top|Queue>io.enq")
- mod.q2_io.deq.toTarget.serialize should be("~Top|Queue>io.deq")
- mod.q1.io.enq.toAbsoluteTarget.serialize should be("~Top|Top/q1:Queue>io.enq")
- mod.q2_io.deq.toAbsoluteTarget.serialize should be("~Top|Top/q2:Queue>io.deq")
- // Legacy APIs that nevertheless were tricky to get right
- mod.q1.io.enq.toNamed.serialize should be("Top.Queue.io.enq")
- mod.q2_io.deq.toNamed.serialize should be("Top.Queue.io.deq")
- mod.q1.io.enq.instanceName should be("io.enq")
- mod.q2_io.deq.instanceName should be("io.deq")
- mod.q1.io.enq.pathName should be("Top.q1.io.enq")
- mod.q2_io.deq.pathName should be("Top.q2.io.deq")
- mod.q1.io.enq.parentPathName should be("Top.q1")
- mod.q2_io.deq.parentPathName should be("Top.q2")
- mod.q1.io.enq.parentModName should be("Queue")
- mod.q2_io.deq.parentModName should be("Queue")
-
- // ********** Checking the wire cloned from the output of CloneModuleAsRecord **********
- val wire_io = mod.q2_wire("io").asInstanceOf[QueueIO[UInt]]
- mod.q2_wire.toTarget.serialize should be("~Top|Top>q2_wire")
- wire_io.enq.toTarget.serialize should be("~Top|Top>q2_wire.io.enq")
- mod.q2_wire.toAbsoluteTarget.serialize should be("~Top|Top>q2_wire")
- wire_io.enq.toAbsoluteTarget.serialize should be("~Top|Top>q2_wire.io.enq")
- // Legacy APIs
- mod.q2_wire.toNamed.serialize should be("Top.Top.q2_wire")
- wire_io.enq.toNamed.serialize should be("Top.Top.q2_wire.io.enq")
- mod.q2_wire.instanceName should be("q2_wire")
- wire_io.enq.instanceName should be("q2_wire.io.enq")
- mod.q2_wire.pathName should be("Top.q2_wire")
- wire_io.enq.pathName should be("Top.q2_wire.io.enq")
- mod.q2_wire.parentPathName should be("Top")
- wire_io.enq.parentPathName should be("Top")
- mod.q2_wire.parentModName should be("Top")
- wire_io.enq.parentModName should be("Top")
- }
-
-}
diff --git a/src/test/scala/chiselTests/CompatibilityInteroperabilitySpec.scala b/src/test/scala/chiselTests/CompatibilityInteroperabilitySpec.scala
deleted file mode 100644
index d388c093..00000000
--- a/src/test/scala/chiselTests/CompatibilityInteroperabilitySpec.scala
+++ /dev/null
@@ -1,820 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import scala.collection.immutable.ListMap
-import chisel3.stage.ChiselStage.emitChirrtl
-
-// Keep Chisel._ separate from chisel3._ below
-object CompatibilityComponents {
- import Chisel._
- import Chisel3Components._
-
- class ChiselBundle extends Bundle {
- val a = UInt(width = 32)
- val b = UInt(width = 32).flip
- }
- class ChiselRecord extends Record {
- val elements = ListMap("a" -> UInt(width = 32), "b" -> UInt(width = 32).flip)
- override def cloneType: this.type = (new ChiselRecord).asInstanceOf[this.type]
- }
-
- abstract class ChiselDriverModule(_io: => Record) extends Module {
- val io = _io
- io.elements("a").asUInt := UInt(123)
- assert(io.elements("b").asUInt === UInt(123))
- }
- abstract class ChiselPassthroughModule(_io: => Record) extends Module {
- val io = _io
- io.elements("b").asUInt := io.elements("a").asUInt
- }
-
- class ChiselBundleModuleA extends ChiselDriverModule(new ChiselBundle)
- class ChiselBundleModuleB extends ChiselPassthroughModule((new ChiselBundle).flip)
- class ChiselRecordModuleA extends ChiselDriverModule(new ChiselRecord)
- class ChiselRecordModuleB extends ChiselPassthroughModule((new ChiselRecord).flip)
-
- class ChiselModuleChisel3BundleA extends ChiselDriverModule(new Chisel3Bundle)
- class ChiselModuleChisel3BundleB extends ChiselPassthroughModule((new Chisel3Bundle).flip)
- class ChiselModuleChisel3RecordA extends ChiselDriverModule(new Chisel3Record)
- class ChiselModuleChisel3RecordB extends ChiselPassthroughModule((new Chisel3Record).flip)
-}
-
-object Chisel3Components {
- import chisel3._
- import CompatibilityComponents._
-
- class Chisel3Bundle extends Bundle {
- val a = Output(UInt(32.W))
- val b = Input(UInt(32.W))
- }
-
- class Chisel3Record extends Record {
- val elements = ListMap("a" -> Output(UInt(32.W)), "b" -> Input(UInt(32.W)))
- override def cloneType: this.type = (new Chisel3Record).asInstanceOf[this.type]
- }
-
- abstract class Chisel3DriverModule(_io: => Record) extends Module {
- val io = IO(_io)
- io.elements("a").asUInt := 123.U
- assert(io.elements("b").asUInt === 123.U)
- }
- abstract class Chisel3PassthroughModule(_io: => Record) extends Module {
- val io = IO(_io)
- io.elements("b").asUInt := io.elements("a").asUInt
- }
-
- class Chisel3BundleModuleA extends Chisel3DriverModule(new Chisel3Bundle)
- class Chisel3BundleModuleB extends Chisel3PassthroughModule(Flipped(new Chisel3Bundle))
- class Chisel3RecordModuleA extends Chisel3DriverModule(new Chisel3Record)
- class Chisel3RecordModuleB extends Chisel3PassthroughModule(Flipped(new Chisel3Record))
-
- class Chisel3ModuleChiselBundleA extends Chisel3DriverModule(new ChiselBundle)
- class Chisel3ModuleChiselBundleB extends Chisel3PassthroughModule(Flipped(new ChiselBundle))
- class Chisel3ModuleChiselRecordA extends Chisel3DriverModule(new ChiselRecord)
- class Chisel3ModuleChiselRecordB extends Chisel3PassthroughModule(Flipped(new ChiselRecord))
-}
-
-class CompatibilityInteroperabilitySpec extends ChiselFlatSpec {
-
- "Modules defined in the Chisel._" should "successfully bulk connect in chisel3._" in {
- import chisel3._
- import chisel3.testers.BasicTester
- import CompatibilityComponents._
-
- assertTesterPasses(new BasicTester {
- val a = Module(new ChiselBundleModuleA)
- val b = Module(new ChiselBundleModuleB)
- b.io <> a.io
- stop()
- })
- assertTesterPasses(new BasicTester {
- val a = Module(new ChiselRecordModuleA)
- val b = Module(new ChiselRecordModuleB)
- b.io <> a.io
- stop()
- })
- }
-
- "Moduless defined in the chisel3._" should "successfully bulk connect in Chisel._" in {
- import Chisel._
- import chisel3.testers.BasicTester
- import Chisel3Components._
-
- assertTesterPasses(new BasicTester {
- val a = Module(new Chisel3BundleModuleA)
- val b = Module(new Chisel3BundleModuleB)
- b.io <> a.io
- stop()
- })
- assertTesterPasses(new BasicTester {
- val a = Module(new Chisel3RecordModuleA)
- val b = Module(new Chisel3RecordModuleB)
- b.io <> a.io
- stop()
- })
- }
-
- "Bundles defined in Chisel._" should "work in chisel3._ Modules" in {
- import chisel3._
- import chisel3.testers.BasicTester
- import Chisel3Components._
-
- assertTesterPasses(new BasicTester {
- val a = Module(new Chisel3ModuleChiselBundleA)
- val b = Module(new Chisel3ModuleChiselBundleB)
- b.io <> a.io
- stop()
- })
- assertTesterPasses(new BasicTester {
- val a = Module(new Chisel3ModuleChiselRecordA)
- val b = Module(new Chisel3ModuleChiselRecordB)
- b.io <> a.io
- stop()
- })
- }
-
- "Bundles defined in chisel3._" should "work in Chisel._ Modules" in {
- import chisel3._
- import chisel3.testers.BasicTester
- import CompatibilityComponents._
-
- assertTesterPasses(new BasicTester {
- val a = Module(new ChiselModuleChisel3BundleA)
- val b = Module(new ChiselModuleChisel3BundleB)
- b.io <> a.io
- stop()
- })
- assertTesterPasses(new BasicTester {
- val a = Module(new ChiselModuleChisel3RecordA)
- val b = Module(new ChiselModuleChisel3RecordB)
- b.io <> a.io
- stop()
- })
- }
-
- "Similar Bundles defined in the chisel3._ and Chisel._" should
- "successfully bulk connect in chisel3._" in {
- import chisel3._
- import chisel3.testers.BasicTester
- import Chisel3Components._
- import CompatibilityComponents._
-
- assertTesterPasses(new BasicTester {
- val a = Module(new ChiselBundleModuleA)
- val b = Module(new Chisel3BundleModuleB)
- b.io <> a.io
- stop()
- })
- assertTesterPasses(new BasicTester {
- val a = Module(new Chisel3BundleModuleA)
- val b = Module(new ChiselBundleModuleB)
- b.io <> a.io
- stop()
- })
- assertTesterPasses(new BasicTester {
- val a = Module(new ChiselRecordModuleA)
- val b = Module(new Chisel3RecordModuleB)
- b.io <> a.io
- stop()
- })
- assertTesterPasses(new BasicTester {
- val a = Module(new Chisel3RecordModuleA)
- val b = Module(new ChiselRecordModuleB)
- b.io <> a.io
- stop()
- })
- }
- they should "successfully bulk connect in Chisel._" in {
- import Chisel._
- import chisel3.testers.BasicTester
- import Chisel3Components._
- import CompatibilityComponents._
-
- assertTesterPasses(new BasicTester {
- val a = Module(new ChiselBundleModuleA)
- val b = Module(new Chisel3BundleModuleB)
- b.io <> a.io
- stop()
- })
- assertTesterPasses(new BasicTester {
- val a = Module(new Chisel3BundleModuleA)
- val b = Module(new ChiselBundleModuleB)
- b.io <> a.io
- stop()
- })
- assertTesterPasses(new BasicTester {
- val a = Module(new ChiselRecordModuleA)
- val b = Module(new Chisel3RecordModuleB)
- b.io <> a.io
- stop()
- })
- assertTesterPasses(new BasicTester {
- val a = Module(new Chisel3RecordModuleA)
- val b = Module(new ChiselRecordModuleB)
- b.io <> a.io
- stop()
- })
- }
-
- "An instance of a chisel3.Module inside a Chisel.Module" should "have its inputs invalidated" in {
- compile {
- import Chisel._
- new Module {
- val io = new Bundle {
- val in = UInt(INPUT, width = 32)
- val cond = Bool(INPUT)
- val out = UInt(OUTPUT, width = 32)
- }
- val children =
- Seq(Module(new PassthroughModule), Module(new PassthroughMultiIOModule), Module(new PassthroughRawModule))
- io.out := children.map(_.io.out).reduce(_ + _)
- children.foreach { child =>
- when(io.cond) {
- child.io.in := io.in
- }
- }
- }
- }
- }
-
- "Compatibility Modules" should "have Bool as their reset type" in {
- compile {
- import Chisel._
- class Intf extends Bundle {
- val in = Bool(INPUT)
- val en = Bool(INPUT)
- val out = Bool(OUTPUT)
- }
- class Child extends Module {
- val io = new Intf
- io.out := Mux(io.en, io.in, reset)
- }
- new Module {
- val io = new Intf
- val child = Module(new Child)
- io <> child.io
- }
- }
- }
-
- "Compatibility Modules" should "be instantiable inside chisel3 Modules" in {
- compile {
- object Compat {
- import Chisel._
- class Intf extends Bundle {
- val in = Input(UInt(8.W))
- val out = Output(UInt(8.W))
- }
- class OldMod extends Module {
- val io = IO(new Intf)
- io.out := Reg(next = io.in)
- }
- }
- import chisel3._
- import Compat._
- new Module {
- val io = IO(new Intf)
- io <> Module(new Module {
- val io = IO(new Intf)
- val inst = Module(new OldMod)
- io <> inst.io
- }).io
- }
- }
- }
-
- "A chisel3 Bundle that instantiates a Chisel Bundle" should "bulk connect correctly" in {
- compile {
- object Compat {
- import Chisel._
- class BiDir extends Bundle {
- val a = Input(UInt(8.W))
- val b = Output(UInt(8.W))
- }
- class Struct extends Bundle {
- val a = UInt(8.W)
- }
- }
- import chisel3._
- import Compat._
- class Bar extends Bundle {
- val bidir1 = new BiDir
- val bidir2 = Flipped(new BiDir)
- val struct1 = Output(new Struct)
- val struct2 = Input(new Struct)
- }
- // Check every connection both ways to see that chisel3 <>'s commutativity holds
- class Child extends RawModule {
- val deq = IO(new Bar)
- val enq = IO(Flipped(new Bar))
- enq <> deq
- deq <> enq
- }
- new RawModule {
- val deq = IO(new Bar)
- val enq = IO(Flipped(new Bar))
- // Also important to check connections to child ports
- val c1 = Module(new Child)
- val c2 = Module(new Child)
- c1.enq <> enq
- enq <> c1.enq
- c2.enq <> c1.deq
- c1.deq <> c2.enq
- deq <> c2.deq
- c2.deq <> deq
- }
- }
- }
-
- "A unidirectional but flipped Bundle" should "bulk connect in import chisel3._ code correctly" in {
- object Compat {
- import Chisel._
- class MyBundle(extraFlip: Boolean) extends Bundle {
- private def maybeFlip[T <: Data](t: T): T = if (extraFlip) t.flip else t
- val foo = maybeFlip(new Bundle {
- val bar = UInt(INPUT, width = 8)
- })
- }
- }
- import chisel3._
- import Compat._
- class Top(extraFlip: Boolean) extends RawModule {
- val port = IO(new MyBundle(extraFlip))
- val wire = Wire(new MyBundle(extraFlip))
- port <> DontCare
- wire <> DontCare
- port <> wire
- wire <> port
- port.foo <> wire.foo
- wire.foo <> port.foo
- }
- compile(new Top(true))
- compile(new Top(false))
- }
-
- "A unidirectional but flipped Bundle with something close to NotStrict compileOptions, but not exactly" should "bulk connect in import chisel3._ code correctly" in {
- object Compat {
- import Chisel.{defaultCompileOptions => _, _}
- // arbitrary thing to make this *not* exactly NotStrict
- implicit val defaultCompileOptions = new chisel3.ExplicitCompileOptions.CompileOptionsClass(
- connectFieldsMustMatch = false,
- declaredTypeMustBeUnbound = false,
- dontTryConnectionsSwapped = false,
- dontAssumeDirectionality = false,
- checkSynthesizable = false,
- explicitInvalidate = false,
- inferModuleReset = true // different from NotStrict, to ensure case class equivalence to NotStrict is false
- ) {
- override def emitStrictConnects = false
- }
-
- class MyBundle(extraFlip: Boolean) extends Bundle {
- private def maybeFlip[T <: Data](t: T): T = if (extraFlip) t.flip else t
- val foo = maybeFlip(new Bundle {
- val bar = UInt(INPUT, width = 8)
- })
- }
- }
- import chisel3._
- import Compat.{defaultCompileOptions => _, _}
- class Top(extraFlip: Boolean) extends RawModule {
- val port = IO(new MyBundle(extraFlip))
- val wire = Wire(new MyBundle(extraFlip))
- port <> DontCare
- wire <> DontCare
- port <> wire
- wire <> port
- port.foo <> wire.foo
- wire.foo <> port.foo
- }
- compile(new Top(true))
- compile(new Top(false))
- }
-
- "A Chisel.Bundle with only unspecified directions" should "work with D/I" in {
-
- object Compat {
- import Chisel._
- import chisel3.experimental.hierarchy.{instantiable, public}
-
- class CompatBiDirUnspecifiedBundle extends Bundle {
- val out = Bool()
- val in = Flipped(Bool())
- }
-
- @instantiable
- class CompatModule extends Module {
- @public val io = IO(new CompatBiDirUnspecifiedBundle)
- }
- }
-
- object Chisel3 {
- import chisel3._
- import chisel3.experimental.hierarchy.Instance
- class Example extends Module {
- val mod = Module(new Compat.CompatModule())
- mod.io.in <> DontCare
- val inst = Instance(mod.toDefinition)
- inst.io.in <> mod.io.out
- mod.io.in <> inst.io.out
- }
- }
- compile(new Chisel3.Example)
- }
-
- "A Chisel.Bundle with mixed Specified and Unspecified directions" should "work with D/I" in {
-
- object Compat {
- import Chisel._
- import chisel3.experimental.hierarchy.{instantiable, public}
-
- class CompatBiDirMixedBundle extends Bundle {
- val out = Bool()
- val in = Flipped(Bool())
- val explicit = Output(Bool())
- }
-
- @instantiable
- class CompatModule extends Module {
- @public val io = IO(new CompatBiDirMixedBundle)
- }
- }
-
- object Chisel3 {
- import chisel3._
- import chisel3.experimental.hierarchy.Instance
- class Example extends Module {
- val mod = Module(new Compat.CompatModule)
- mod.io.in <> DontCare
- val inst = Instance(mod.toDefinition)
- inst.io.in <> mod.io.out
- mod.io.in <> inst.io.out
- }
- }
- compile(new Chisel3.Example)
- }
-
- "A Chisel.Bundle with only unspecified vec direction" should "work with D/I" in {
-
- object Compat {
- import Chisel._
- import chisel3.experimental.hierarchy.{instantiable, public}
-
- class CompatBiDirUnspecifiedVecBundle extends Bundle {
- val out = Vec(3, Bool())
- val in = Flipped(Vec(3, Bool()))
- }
-
- @instantiable
- class CompatModule extends Module {
- @public val io = IO(new CompatBiDirUnspecifiedVecBundle)
- }
- }
-
- object Chisel3 {
- import chisel3._
- import chisel3.experimental.hierarchy.Instance
- class Example extends Module {
- val mod = Module(new Compat.CompatModule())
- mod.io.in <> DontCare
- val inst = Instance(mod.toDefinition)
- inst.io.in <> mod.io.out
- mod.io.in <> inst.io.out
- }
- }
- compile(new Chisel3.Example)
- }
-
- "A chisel3.Bundle with only unspecified directions" should "work with D/I" in {
-
- object Chisel3 {
- import chisel3._
- import chisel3.experimental.hierarchy.{instantiable, public, Instance}
-
- class BiDirUnspecifiedBundle extends Bundle {
- val out = Bool()
- val in = Flipped(Bool())
- }
-
- @instantiable
- class MyModule extends Module {
- @public val io = IO(new BiDirUnspecifiedBundle)
- io <> DontCare
- }
-
- class Example extends Module {
- val mod = Module(new MyModule())
- mod.io.in <> DontCare
- val inst = Instance(mod.toDefinition)
- inst.io.in <> mod.io.out
- mod.io.in <> inst.io.out
- }
- }
- compile(new Chisel3.Example)
- }
-
- "A chisel3.Bundle with mixed Specified and Unspecified directions" should "work with D/I" in {
-
- object Chisel3 {
- import chisel3._
- import chisel3.experimental.hierarchy.{instantiable, public, Instance}
-
- class BiDirMixedBundle extends Bundle {
- val out = Bool()
- val in = Flipped(Bool())
- val explicit = Output(Bool())
- }
-
- @instantiable
- class MyModule extends Module {
- @public val io = IO(new BiDirMixedBundle)
- io <> DontCare
- }
- class Example extends Module {
- val mod = Module(new MyModule)
- mod.io.in <> DontCare
- val inst = Instance(mod.toDefinition)
- inst.io.in <> mod.io.out
- mod.io.in <> inst.io.out
- }
- }
- compile(new Chisel3.Example)
- }
-
- "A chisel3.Bundle with only unspecified vec direction" should "work with D/I" in {
-
- object Chisel3 {
- import chisel3._
- import chisel3.experimental.hierarchy.{instantiable, public, Instance}
-
- class BiDirUnspecifiedVecBundle extends Bundle {
- val out = Vec(3, Bool())
- val in = Flipped(Vec(3, Bool()))
- }
-
- @instantiable
- class MyModule extends Module {
- @public val io = IO(new BiDirUnspecifiedVecBundle)
- io <> DontCare
- }
-
- class Example extends Module {
- val mod = Module(new MyModule())
- mod.io.in <> DontCare
- val inst = Instance(mod.toDefinition)
- inst.io.in <> mod.io.out
- mod.io.in <> inst.io.out
- }
- }
- compile(new Chisel3.Example)
- }
-
- "A chisel3.Bundle with only unspecified vec direction within an unspecified direction parent Bundle" should "work with D/I" in {
-
- object Chisel3 {
- import chisel3._
- import chisel3.experimental.hierarchy.{instantiable, public, Instance}
-
- class UnspecifiedVecBundle extends Bundle {
- val vec = Vec(3, Bool())
- }
-
- class UnspecifiedParentBundle extends Bundle {
- val out = new UnspecifiedVecBundle
- }
-
- @instantiable
- class MyModule extends Module {
- @public val io = IO(new UnspecifiedParentBundle)
- io <> DontCare
- }
-
- class Example extends Module {
- val mod = Module(new MyModule())
-
- val wire = Wire(new UnspecifiedParentBundle)
- wire.out.vec <> mod.io.out.vec
- val inst = Instance(mod.toDefinition)
- wire.out.vec <> inst.io.out.vec
-
- }
- }
- compile(new Chisel3.Example)
- }
-
- "A undirectioned Chisel.Bundle used in a MixedVec " should "bulk connect in import chisel3._ code correctly" in {
-
- object Compat {
-
- import Chisel._
- import chisel3.util.MixedVec
-
- class ChiselModule extends Module {
- val io = IO(new Bundle {
- val out = MixedVec(Seq.fill(3) { Bool() })
- val in = Flipped(MixedVec(Seq.fill(3) { Bool() }))
- })
- io.out := RegNext(io.in)
- }
-
- }
- object Chisel3 {
- import chisel3._
-
- class Chisel3Module extends Compat.ChiselModule
-
- class Example extends Module {
- val oldMod = Module(new Compat.ChiselModule)
- val newMod = Module(new Chisel3Module)
-
- oldMod.io.in <> DontCare
- newMod.io.in <> DontCare
-
- }
- }
- compile(new Chisel3.Example)
- }
-
- "A undirectioned Chisel.Bundle with Records with undirectioned and directioned fields " should "work" in {
-
- object Compat {
-
- import Chisel._
-
- class ChiselModule(gen: () => Data) extends Module {
- val io = IO(new Bundle {
- val mixed = new Chisel3.MyRecord(gen)
- })
- }
-
- }
- object Chisel3 {
- import chisel3._
- import scala.collection.immutable.SeqMap
-
- class MyRecord(gen: () => Data) extends Record with chisel3.experimental.AutoCloneType {
- val elements = SeqMap("genDirectioned" -> Output(gen()), "genUndirectioned" -> gen())
- }
-
- class Example extends Module {
- val newMod = Module(new Compat.ChiselModule(() => Bool()))
- }
- }
- compile(new Chisel3.Example)
- }
-
- "A BlackBox with Chisel._ fields in its IO" should "bulk connect in import chisel3._ code correctly" in {
- object Compat {
- import Chisel._
- class LegacyChiselIO extends Bundle {
- val foo = Output(Bool())
- val bar = Output(Bool())
- }
- }
- object Chisel3 {
- import chisel3._
- import chisel3.util.Valid
-
- class FooModuleIO extends Bundle {
- val quz = Input(new QuzIO)
- val foo = Output(Bool())
- val bar = Input(Bool())
- }
- class QuzIO extends Bundle {
- val q = Flipped(Valid(new Compat.LegacyChiselIO))
- }
- class FooModule extends Module {
- val io = IO(new FooModuleIO)
- io <> DontCare
- }
- class FooMirrorBlackBox extends BlackBox {
- val io = IO(Flipped(new FooModuleIO))
- }
- class Top extends Module {
- val foo = Module(new FooModule)
- val mirror = Module(new FooMirrorBlackBox)
- foo.io <> mirror.io
- }
- }
- val chirrtl = emitChirrtl(new Chisel3.Top)
- chirrtl should include("foo.io.bar <= mirror.bar")
- chirrtl should include("mirror.foo <= foo.io.foo")
- chirrtl should include("foo.io.quz.q.bits <- mirror.quz.q.bits")
- chirrtl should include("foo.io.quz.q.valid <= mirror.quz.q.valid")
- }
-
- "A chisel3.Bundle bulk connected to a Chisel Bundle in either direction" should "work even with mismatched fields" in {
- object Compat {
- import Chisel._
- class FooBundle extends Bundle {
- val foo = UInt(width = 8)
- }
- }
- object Chisel3 {
- import chisel3._
- class BarBundle extends Bundle {
- val bar = UInt(8.W)
- }
- class MyModule(swap: Boolean) extends Module {
- val in = IO(Input(if (swap) new Compat.FooBundle else new BarBundle))
- val out = IO(Output(if (swap) new BarBundle else new Compat.FooBundle))
- out <> DontCare
- out <> in
- }
- }
- val chirrtl0 = emitChirrtl(new Chisel3.MyModule(true))
- chirrtl0 shouldNot include("<=")
- chirrtl0 should include("out <- in")
- val chirrtl1 = emitChirrtl(new Chisel3.MyModule(true))
- chirrtl1 shouldNot include("<=")
- chirrtl1 should include("out <- in")
- }
-
- it should "work with missing fields in the Chisel._" in {
- object Compat {
- import Chisel._
- class FooBundle extends Bundle {
- val foo = UInt(width = 8)
- }
- }
- object Chisel3 {
- import chisel3._
- class FooBarBundle extends Bundle {
- val foo = UInt(8.W)
- val bar = UInt(8.W)
- }
-
- class MyModule(swap: Boolean) extends Module {
- val in = IO(Input(if (swap) new Compat.FooBundle else new FooBarBundle))
- val out = IO(Output(if (swap) new FooBarBundle else new Compat.FooBundle))
- out <> DontCare
- out <> in
- }
- }
- val chirrtl0 = emitChirrtl(new Chisel3.MyModule(true))
- chirrtl0 shouldNot include("<=")
- chirrtl0 should include("out <- in")
- val chirrtl1 = emitChirrtl(new Chisel3.MyModule(true))
- chirrtl1 shouldNot include("<=")
- chirrtl1 should include("out <- in")
- }
-
- it should "work with missing fields in the chisel3._" in {
- object Compat {
- import Chisel._
- class FooBundle extends Bundle {
- val foo = UInt(width = 8)
- }
- }
- object Chisel3 {
- import chisel3._
- class FooBarBundle extends Bundle {
- val foo = UInt(8.W)
- val bar = UInt(8.W)
- }
-
- class MyModule(swap: Boolean) extends Module {
- val in = IO(Input(if (swap) new Compat.FooBundle else new FooBarBundle))
- val out = IO(Output(if (swap) new FooBarBundle else new Compat.FooBundle))
- out <> DontCare
- out <> in
- }
- }
- val chirrtl0 = emitChirrtl(new Chisel3.MyModule(true))
- chirrtl0 shouldNot include("<=")
- chirrtl0 should include("out <- in")
- val chirrtl1 = emitChirrtl(new Chisel3.MyModule(true))
- chirrtl1 shouldNot include("<=")
- chirrtl1 should include("out <- in")
- }
-
- it should "emit FIRRTL connects if possible" in {
- object Compat {
- import Chisel._
- class FooBarBundle extends Bundle {
- val foo = UInt(8.W)
- val bar = Flipped(UInt(8.W))
- }
- }
- object Chisel3 {
- import chisel3._
- class FooBarBundle extends Bundle {
- val foo = Output(UInt(8.W))
- val bar = Input(UInt(8.W))
- }
- class MyModule(swap: Boolean) extends Module {
- val in = IO(Flipped((if (swap) new Compat.FooBarBundle else new FooBarBundle)))
- val out = IO(if (swap) new FooBarBundle else new Compat.FooBarBundle)
- out <> DontCare
- out <> in
- }
- }
- val chirrtl0 = emitChirrtl(new Chisel3.MyModule(true))
- chirrtl0 should include("out <= in")
- chirrtl0 shouldNot include("out <- in")
- val chirrtl1 = emitChirrtl(new Chisel3.MyModule(true))
- chirrtl1 should include("out <= in")
- chirrtl1 shouldNot include("out <- in")
- }
-}
diff --git a/src/test/scala/chiselTests/CompatibilitySpec.scala b/src/test/scala/chiselTests/CompatibilitySpec.scala
deleted file mode 100644
index 5a3b43e6..00000000
--- a/src/test/scala/chiselTests/CompatibilitySpec.scala
+++ /dev/null
@@ -1,639 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3.stage.ChiselStage
-import chisel3.testers.BasicTester
-
-import org.scalacheck.Gen
-import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks
-
-import scala.collection.immutable.ListMap
-
-// Need separate import to override compile options from Chisel._
-object CompatibilityCustomCompileOptions {
- import Chisel.{defaultCompileOptions => _, _}
- implicit val customCompileOptions =
- chisel3.ExplicitCompileOptions.NotStrict.copy(inferModuleReset = true)
- class Foo extends Module {
- val io = new Bundle {}
- }
-}
-
-class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyChecks with Utils {
- import Chisel._
-
- behavior.of("Chisel compatibility layer")
-
- it should "accept direction arguments" in {
- ChiselStage.elaborate(new Module {
- // Choose a random direction
- val directionArgument: Direction = Gen.oneOf(INPUT, OUTPUT, NODIR).sample.get
- val expectedDirection = directionArgument match {
- case NODIR => OUTPUT
- case other => other
- }
- // Choose a random width
- val width = Gen.choose(1, 2048).sample.get
- val io = new Bundle {
- val b = Bool(directionArgument)
- val u = UInt(directionArgument, width)
- }
- io.b shouldBe a[Bool]
- io.b.getWidth shouldEqual 1
- io.b.dir shouldEqual (expectedDirection)
- io.u shouldBe a[UInt]
- io.u.getWidth shouldEqual width
- io.u.dir shouldEqual (expectedDirection)
- })
- }
-
- it should "accept single argument U/SInt factory methods" in {
- // Choose a random value
- val value: Int = Gen.choose(0, Int.MaxValue).sample.get
- val l = UInt(value)
- l shouldBe a[UInt]
- l shouldBe 'lit
- l.getWidth shouldEqual BigInt(value).bitLength
- l.litValue() shouldEqual value
- }
-
- it should "map utility objects into the package object" in {
- val value: Int = Gen.choose(2, 2048).sample.get
- log2Up(value) shouldBe (1.max(BigInt(value - 1).bitLength))
- log2Ceil(value) shouldBe (BigInt(value - 1).bitLength)
- log2Down(value) shouldBe ((1.max(BigInt(value - 1).bitLength)) - (if (value > 0 && ((value & (value - 1)) == 0)) 0
- else 1))
- log2Floor(value) shouldBe (BigInt(value - 1).bitLength - (if (value > 0 && ((value & (value - 1)) == 0)) 0 else 1))
- isPow2(BigInt(1) << value) shouldBe true
- isPow2((BigInt(1) << value) - 1) shouldBe false
- }
-
- it should "make BitPats available" in {
- val value: Int = Gen.choose(1, Int.MaxValue).sample.get
- val binaryString = value.toBinaryString
- val maskPosition = Gen.choose(0, binaryString.length - 1).sample.get
- val bs = new StringBuilder(binaryString)
- bs(maskPosition) = '?'
- val bitPatString = bs.toString
- val bp = BitPat("b" + bitPatString)
- bp shouldBe a[BitPat]
- bp.getWidth shouldEqual binaryString.length
-
- }
-
- it should "successfully compile a complete module" in {
- class Dummy extends Module {
- // The following just checks that we can create objects with nothing more than the Chisel compatibility package.
- val io = new Bundle {}
- val data = UInt(width = 3)
- val wire = Wire(data)
- new ArbiterIO(data, 2) shouldBe a[ArbiterIO[UInt]]
- Module(new LockingRRArbiter(data, 2, 2, None)) shouldBe a[LockingRRArbiter[UInt]]
- Module(new RRArbiter(data, 2)) shouldBe a[RRArbiter[UInt]]
- Module(new Arbiter(data, 2)) shouldBe a[Arbiter[UInt]]
- new Counter(2) shouldBe a[Counter]
- new ValidIO(data) shouldBe a[ValidIO[UInt]]
- new DecoupledIO(data) shouldBe a[DecoupledIO[UInt]]
- new QueueIO(data, 2) shouldBe a[QueueIO[UInt]]
- Module(new Pipe(data, 2)) shouldBe a[Pipe[UInt]]
-
- FillInterleaved(2, wire) shouldBe a[UInt]
- PopCount(wire) shouldBe a[UInt]
- Fill(2, wire) shouldBe a[UInt]
- Reverse(wire) shouldBe a[UInt]
- Cat(wire, wire) shouldBe a[UInt]
- Log2(wire) shouldBe a[UInt]
- // 'switch' and 'is' are tested below in Risc
- Counter(2) shouldBe a[Counter]
- DecoupledIO(wire) shouldBe a[DecoupledIO[UInt]]
- val dcd = Wire(Decoupled(data))
- dcd shouldBe a[DecoupledIO[UInt]]
- Queue(dcd) shouldBe a[DecoupledIO[UInt]]
- Queue(dcd, 0) shouldBe a[DecoupledIO[UInt]]
- Enum(UInt(), 2) shouldBe a[List[UInt]]
- ListLookup(wire, List(wire), Array((BitPat("b1"), List(wire)))) shouldBe a[List[UInt]]
- Lookup(wire, wire, Seq((BitPat("b1"), wire))) shouldBe a[UInt]
- Mux1H(wire, Seq(wire)) shouldBe a[UInt]
- PriorityMux(Seq(Bool(false)), Seq(data)) shouldBe a[UInt]
- MuxLookup(wire, wire, Seq((wire, wire))) shouldBe a[UInt]
- MuxCase(wire, Seq((Bool(true), wire))) shouldBe a[UInt]
- OHToUInt(wire) shouldBe a[UInt]
- PriorityEncoder(wire) shouldBe a[UInt]
- UIntToOH(wire) shouldBe a[UInt]
- PriorityEncoderOH(wire) shouldBe a[UInt]
- RegNext(wire) shouldBe a[UInt]
- RegInit(wire) shouldBe a[UInt]
- RegEnable(wire, Bool(true)) shouldBe a[UInt]
- ShiftRegister(wire, 2) shouldBe a[UInt]
- Valid(data) shouldBe a[ValidIO[UInt]]
- Pipe(Wire(Valid(data)), 2) shouldBe a[ValidIO[UInt]]
- }
- ChiselStage.elaborate { new Dummy }
- }
- // Verify we can elaborate a design expressed in Chisel2
- class Chisel2CompatibleRisc extends Module {
- val io = new Bundle {
- val isWr = Bool(INPUT)
- val wrAddr = UInt(INPUT, 8)
- val wrData = Bits(INPUT, 32)
- val boot = Bool(INPUT)
- val valid = Bool(OUTPUT)
- val out = Bits(OUTPUT, 32)
- }
- val file = Mem(256, Bits(width = 32))
- val code = Mem(256, Bits(width = 32))
- val pc = Reg(init = UInt(0, 8))
-
- val add_op :: imm_op :: Nil = Enum(2)
-
- val inst = code(pc)
- val op = inst(31, 24)
- val rci = inst(23, 16)
- val rai = inst(15, 8)
- val rbi = inst(7, 0)
-
- val ra = Mux(rai === Bits(0), Bits(0), file(rai))
- val rb = Mux(rbi === Bits(0), Bits(0), file(rbi))
- val rc = Wire(Bits(width = 32))
-
- io.valid := Bool(false)
- io.out := Bits(0)
- rc := Bits(0)
-
- when(io.isWr) {
- code(io.wrAddr) := io.wrData
- }.elsewhen(io.boot) {
- pc := UInt(0)
- }.otherwise {
- switch(op) {
- is(add_op) { rc := ra +% rb }
- is(imm_op) { rc := (rai << 8) | rbi }
- }
- io.out := rc
- when(rci === UInt(255)) {
- io.valid := Bool(true)
- }.otherwise {
- file(rci) := rc
- }
- pc := pc +% UInt(1)
- }
- }
-
- it should "Chisel2CompatibleRisc should elaborate" in {
- ChiselStage.elaborate { new Chisel2CompatibleRisc }
- }
-
- it should "not try to assign directions to Analog" in {
- ChiselStage.elaborate(new Module {
- val io = new Bundle {
- val port = chisel3.experimental.Analog(32.W)
- }
- })
- }
-
- class SmallBundle extends Bundle {
- val f1 = UInt(width = 4)
- val f2 = UInt(width = 5)
- }
- class BigBundle extends SmallBundle {
- val f3 = UInt(width = 6)
- }
-
- "A Module with missing bundle fields when compiled with the Chisel compatibility package" should "not throw an exception" in {
-
- class ConnectFieldMismatchModule extends Module {
- val io = new Bundle {
- val in = (new SmallBundle).asInput
- val out = (new BigBundle).asOutput
- }
- io.out := io.in
- }
- 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 {
-
- class CreateRegFromBoundTypeModule extends Module {
- val io = new Bundle {
- val in = (new SmallBundle).asInput
- val out = (new BigBundle).asOutput
- }
- val badReg = Reg(UInt(7, width = 4))
- }
- ChiselStage.elaborate { new CreateRegFromBoundTypeModule() }
- }
-
- "A Module with unwrapped IO when compiled with the Chisel compatibility package" should "not throw an exception" in {
-
- class RequireIOWrapModule extends Module {
- val io = new Bundle {
- val in = UInt(width = 32).asInput
- val out = Bool().asOutput
- }
- io.out := io.in(1)
- }
- ChiselStage.elaborate { new RequireIOWrapModule() }
- }
-
- "A Module without val io" should "throw an exception" in {
- class ModuleWithoutValIO extends Module {
- val foo = IO(new Bundle {
- val in = UInt(width = 32).asInput
- val out = Bool().asOutput
- })
- foo.out := foo.in(1)
- }
- val e = intercept[Exception](
- ChiselStage.elaborate { new ModuleWithoutValIO }
- )
- e.getMessage should include("must have a 'val io' Bundle")
- }
-
- "A Module connecting output as source to input as sink when compiled with the Chisel compatibility package" should "not throw an exception" in {
-
- class SimpleModule extends Module {
- val io = new Bundle {
- val in = (UInt(width = 3)).asInput
- val out = (UInt(width = 4)).asOutput
- }
- }
- class SwappedConnectionModule extends SimpleModule {
- val child = Module(new SimpleModule)
- io.in := child.io.out
- }
- ChiselStage.elaborate { new SwappedConnectionModule() }
- }
-
- "Vec ports" should "give default directions to children so they can be used in chisel3.util" in {
- import Chisel._
- ChiselStage.elaborate(new Module {
- val io = new Bundle {
- val in = Vec(1, UInt(width = 8)).flip
- val out = UInt(width = 8)
- }
- io.out := RegEnable(io.in(0), true.B)
- })
- }
-
- "Reset" should "still walk, talk, and quack like a Bool" in {
- import Chisel._
- ChiselStage.elaborate(new Module {
- val io = new Bundle {
- val in = Bool(INPUT)
- val out = Bool(OUTPUT)
- }
- io.out := io.in && reset
- })
- }
-
- "Data.dir" should "give the correct direction for io" in {
- import Chisel._
- ChiselStage.elaborate(new Module {
- val io = (new Bundle {
- val foo = Bool(OUTPUT)
- val bar = Bool().flip
- }).flip
- Chisel.assert(io.foo.dir == INPUT)
- Chisel.assert(io.bar.dir == OUTPUT)
- })
- }
-
- // 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 extractCause[chisel3.ExpectedHardwareException] {
- ChiselStage.elaborate(new Module {
- val io = new Bundle {}
- UInt(INPUT).dir
- })
- }
- }
-
- "Mux return value" should "be able to be used on the RHS" in {
- import Chisel._
- 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
- val b = Vec(2, UInt(width = 8)).asInput
- val c = gen.asInput
- val d = gen.asInput
- val en = Bool(INPUT)
- val y = Vec(2, UInt(width = 8)).asOutput
- val z = gen.asOutput
- }
- io.y := Mux(io.en, io.a, io.b)
- io.z := Mux(io.en, io.c, io.d)
- })
- }
-
- "Chisel3 IO constructs" should "be useable in Chisel2" in {
- import Chisel._
- ChiselStage.elaborate(new Module {
- val io = IO(new Bundle {
- val in = Input(Bool())
- val foo = Output(Bool())
- val bar = Flipped(Bool())
- })
- Chisel.assert(io.in.dir == INPUT)
- Chisel.assert(io.foo.dir == OUTPUT)
- Chisel.assert(io.bar.dir == INPUT)
- })
- }
-
- behavior.of("BitPat")
-
- it should "support old operators" in {
- class Foo extends Module {
- val io = IO(new Bundle {})
-
- info("Deprecated method DC hasn't been removed")
- val bp = BitPat.DC(4)
- }
-
- ChiselStage.elaborate(new Foo)
- }
-
- behavior.of("Enum")
-
- it should "support apply[T <: Bits](nodeType: T, n: Int): List[T]" in {
- class Foo extends Module {
- val io = IO(new Bundle {})
-
- info("works for a UInt")
- Enum(UInt(), 4) shouldBe a[List[UInt]]
-
- info("throw an exception for non-UInt types")
- intercept[IllegalArgumentException] {
- Enum(SInt(), 4)
- }.getMessage should include("Only UInt supported for enums")
-
- info("throw an exception if the bit width is specified")
- intercept[IllegalArgumentException] {
- Enum(UInt(width = 8), 4)
- }.getMessage should include("Bit width may no longer be specified for enums")
- }
-
- ChiselStage.elaborate(new Foo)
- }
-
- behavior.of("Queue")
-
- it should "support deprecated constructors" in {
- class Foo extends Module {
- val io = IO(new Bundle {})
-
- info("reset: Option[Bool] constructor works")
- val option = Module(new Queue(UInt(), 4, false, false, Some(Bool(true))))
-
- info("reset: Bool constructor works")
- val explicit = Module(new Queue(UInt(), 4, false, false, Bool(true)))
- }
-
- ChiselStage.elaborate(new Foo)
- }
-
- behavior.of("LFSR16")
-
- it should "still exist" in {
- class Foo extends Module {
- val io = IO(new Bundle {})
-
- info("Still exists")
- val lfsr = LFSR16()
-
- info("apply method returns a UInt")
- lfsr shouldBe a[UInt]
-
- info("returned UInt has a width of 16")
- lfsr.getWidth should be(16)
- }
-
- ChiselStage.elaborate(new Foo)
- }
-
- behavior.of("Mem")
-
- it should "support deprecated apply methods" in {
- class Foo extends Module {
- val io = IO(new Bundle {})
-
- info("apply[T <: Data](t: T, size: BigInt): Mem[T] works")
- val memBigInt = Mem(UInt(), 8: BigInt)
- memBigInt shouldBe a[Mem[UInt]]
-
- info("apply[T <: Data](t: T, size: Int): Mem[T] works")
- val memInt = Mem(SInt(), 16: Int)
- memInt shouldBe a[Mem[SInt]]
- }
-
- ChiselStage.elaborate(new Foo)
- }
-
- behavior.of("SeqMem")
-
- it should "support deprecated apply methods" in {
- class Foo extends Module {
- val io = IO(new Bundle {})
-
- info("apply[T <: Data](t: T, size: BigInt): SeqMem[T] works")
- val seqMemBigInt = SeqMem(UInt(), 8: BigInt)
- seqMemBigInt shouldBe a[SeqMem[UInt]]
-
- info("apply[T <: Data](t: T, size: Int): SeqMem[T] works")
- val seqMemInt = SeqMem(UInt(), 16: Int)
- seqMemInt shouldBe a[SeqMem[UInt]]
- }
-
- ChiselStage.elaborate(new Foo)
- }
-
- it should "support data-types of mixed directionality" in {
- class Foo extends Module {
- val io = IO(new Bundle {})
- val tpe = new Bundle { val foo = UInt(OUTPUT, width = 4); val bar = UInt(width = 4) }
- // NOTE for some reason, the old bug this hit did not occur when `tpe` is inlined
- val mem = SeqMem(tpe, 8)
- mem(3.U)
-
- }
- ChiselStage.elaborate((new Foo))
- }
-
- behavior.of("debug")
-
- it should "still exist" in {
- class Foo extends Module {
- val io = IO(new Bundle {})
-
- val data = UInt(width = 2)
- debug(data)
- }
-
- ChiselStage.elaborate(new Foo)
- }
-
- behavior.of("Data methods")
-
- behavior.of("Wire")
-
- it should "support legacy methods" in {
- class Foo extends Module {
- val io = IO(new Bundle {})
-
- info("apply[T <: Data](dummy: Int = 0, init: T): T works")
- val first = Wire(init = UInt("hdeadbeef"))
- first shouldBe a[UInt]
-
- info("apply[T <: Data](t: T, init: T): T works")
- val second = Wire(SInt(), SInt(-100))
- second shouldBe a[SInt]
-
- info("apply[T <: Data](t: T, init: DontCare.type): T works")
- val third = Wire(UInt(), chisel3.DontCare)
- third shouldBe a[UInt]
- }
-
- ChiselStage.elaborate(new Foo)
- }
-
- behavior.of("Vec")
-
- it should "support legacy methods" in {
- class Foo extends BasicTester {
- val seq = Seq(Wire(UInt(0, width = 4)), Wire(UInt(1, width = 4)), Wire(UInt(2, width = 4)))
- val vec = Vec(seq)
-
- info("read works")
- chisel3.assert(vec.read(UInt(0)) === UInt(0))
-
- info("write works")
- vec.write(UInt(1), UInt(3))
- chisel3.assert(vec.read(UInt(1)) === UInt(3))
-
- val (_, done) = Counter(Bool(true), 4)
- when(done) { stop }
- }
-
- assertTesterPasses(new Foo)
- }
-
- behavior.of("Bits methods")
-
- it should "support legacy methods" in {
- class Foo extends Module {
- val io = new Bundle {}
-
- val u = UInt(8)
- val s = SInt(-4)
-
- info("asBits works")
- s.asBits shouldBe a[Bits]
-
- info("toSInt works")
- u.toSInt shouldBe a[SInt]
-
- info("toUInt works")
- s.toUInt shouldBe a[UInt]
-
- info("toBools works")
- s.toBools shouldBe a[Seq[Bool]]
- }
-
- ChiselStage.elaborate(new Foo)
- }
-
- it should "properly propagate custom compileOptions in Chisel.Module" in {
- import CompatibilityCustomCompileOptions._
- var result: Foo = null
- ChiselStage.elaborate({ result = new Foo; result })
- (result.compileOptions should be).theSameInstanceAs(customCompileOptions)
- }
-
- it should "properly set the refs of Records" in {
- class MyRecord extends Record {
- val foo = Vec(1, Bool()).asInput
- val bar = Vec(1, Bool())
- val elements = ListMap("in" -> foo, "out" -> bar)
- def cloneType = (new MyRecord).asInstanceOf[this.type]
- }
- class Foo extends Module {
- val io = IO(new MyRecord)
- io.bar := io.foo
- }
- val verilog = ChiselStage.emitVerilog(new Foo)
- // Check that the names are correct (and that the FIRRTL is valid)
- verilog should include("assign io_out_0 = io_in_0;")
- }
-
- it should "ignore .suggestName on field io" in {
- class MyModule extends Module {
- val io = new Bundle {
- val foo = UInt(width = 8).asInput
- val bar = UInt(width = 8).asOutput
- }
- io.suggestName("potato")
- io.bar := io.foo
- }
- val verilog = ChiselStage.emitVerilog(new MyModule)
- verilog should include("input [7:0] io_foo")
- verilog should include("output [7:0] io_bar")
- }
-
- it should "properly name field io" in {
- class MyModule extends Module {
- val io = new Bundle {
- val foo = UInt(width = 8).asInput
- val bar = UInt(width = 8).asOutput
- }
- val wire = Wire(init = io.foo)
- io.bar := wire
- }
- val verilog = ChiselStage.emitVerilog(new MyModule)
- verilog should include("input [7:0] io_foo")
- verilog should include("output [7:0] io_bar")
- }
-
- it should "properly handle hardware construction before val io is initialized" in {
- class MyModule extends Module {
- val foo = Wire(init = UInt(8))
- val io = new Bundle {
- val in = UInt(INPUT, width = 8)
- val en = Bool(INPUT)
- val out = UInt(OUTPUT, width = 8)
- }
- io.out := foo
- when(io.en) {
- io.out := io.in
- }
- }
- // Just check that this doesn't crash during elaboration. For more info see:
- // https://github.com/chipsalliance/chisel3/issues/1802
- //
- ChiselStage.elaborate(new MyModule)
- }
-
- behavior.of("BlackBox")
-
- it should "have invalidated ports in a compatibility context" in {
- class ExtModuleInvalidatedTester extends Module {
- val io = IO(new Bundle {
- val in = Input(UInt(8.W))
- val out = Output(UInt(8.W))
- })
- val inst = Module(new BlackBox {
- val io = IO(new Bundle {
- val in = Input(UInt(8.W))
- val out = Output(UInt(8.W))
- })
- })
- inst.io.in := io.in
- io.out := inst.io.out
- }
-
- val chirrtl = ChiselStage.emitChirrtl(new ExtModuleInvalidatedTester)
- chirrtl should include("inst.in is invalid")
- chirrtl should include("inst.out is invalid")
- }
-}
diff --git a/src/test/scala/chiselTests/CompileOptionsTest.scala b/src/test/scala/chiselTests/CompileOptionsTest.scala
deleted file mode 100644
index b39d8ee3..00000000
--- a/src/test/scala/chiselTests/CompileOptionsTest.scala
+++ /dev/null
@@ -1,194 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.CompileOptions._
-import chisel3.stage.ChiselStage
-
-class CompileOptionsSpec extends ChiselFlatSpec with Utils {
-
- abstract class StrictModule extends Module()(chisel3.ExplicitCompileOptions.Strict)
- abstract class NotStrictModule extends Module()(chisel3.ExplicitCompileOptions.NotStrict)
-
- class SmallBundle extends Bundle {
- val f1 = UInt(4.W)
- val f2 = UInt(5.W)
- }
- class BigBundle extends SmallBundle {
- val f3 = UInt(6.W)
- }
-
- "A Module with missing bundle fields when compiled with implicit Strict.CompileOption " should "throw an exception" in {
- a[ChiselException] should be thrownBy extractCause[ChiselException] {
- import chisel3.ExplicitCompileOptions.Strict
-
- class ConnectFieldMismatchModule extends Module {
- val io = IO(new Bundle {
- val in = Input(new SmallBundle)
- val out = Output(new BigBundle)
- })
- io.out := io.in
- }
- ChiselStage.elaborate { new ConnectFieldMismatchModule() }
- }
- }
-
- "A Module with missing bundle fields when compiled with implicit NotStrict.CompileOption " should "not throw an exception" in {
- import chisel3.ExplicitCompileOptions.NotStrict
-
- class ConnectFieldMismatchModule extends Module {
- val io = IO(new Bundle {
- val in = Input(new SmallBundle)
- val out = Output(new BigBundle)
- })
- io.out := io.in
- }
- 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 extractCause[BindingException] {
- import chisel3.ExplicitCompileOptions.Strict
-
- class CreateRegFromBoundTypeModule extends Module {
- val io = IO(new Bundle {
- val in = Input(new SmallBundle)
- val out = Output(new BigBundle)
- })
- val badReg = Reg(7.U(4.W))
- }
- ChiselStage.elaborate { new CreateRegFromBoundTypeModule() }
- }
- }
-
- "A Module in which a Reg is created with a bound type when compiled with implicit NotStrict.CompileOption " should "not throw an exception" in {
- import chisel3.ExplicitCompileOptions.NotStrict
-
- class CreateRegFromBoundTypeModule extends Module {
- val io = IO(new Bundle {
- val in = Input(new SmallBundle)
- val out = Output(new BigBundle)
- })
- val badReg = Reg(7.U(4.W))
- }
- ChiselStage.elaborate { new CreateRegFromBoundTypeModule() }
- }
-
- "A Module with wrapped IO when compiled with implicit Strict.CompileOption " should "not throw an exception" in {
- import chisel3.ExplicitCompileOptions.Strict
-
- class RequireIOWrapModule extends Module {
- val io = IO(new Bundle {
- val in = Input(UInt(32.W))
- val out = Output(Bool())
- })
- io.out := io.in(1)
- }
- 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 extractCause[BindingException] {
- import chisel3.ExplicitCompileOptions.Strict
-
- class RequireIOWrapModule extends Module {
- val io = new Bundle {
- val in = Input(UInt(32.W))
- val out = Output(Bool())
- }
- io.out := io.in(1)
- }
- 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 extractCause[ChiselException] {
- import chisel3.ExplicitCompileOptions.Strict
-
- class SimpleModule extends Module {
- val io = IO(new Bundle {
- val in = Input(UInt(3.W))
- val out = Output(UInt(4.W))
- })
- }
- class SwappedConnectionModule extends SimpleModule {
- val child = Module(new SimpleModule)
- io.in := child.io.out
- }
- ChiselStage.elaborate { new SwappedConnectionModule() }
- }
- }
-
- "A Module connecting output as source to input as sink when compiled with implicit NotStrict.CompileOption " should "not throw an exception" in {
- import chisel3.ExplicitCompileOptions.NotStrict
-
- class SimpleModule extends Module {
- val io = IO(new Bundle {
- val in = Input(UInt(3.W))
- val out = Output(UInt(4.W))
- })
- }
- class SwappedConnectionModule extends SimpleModule {
- val child = Module(new SimpleModule)
- io.in := child.io.out
- }
- 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 extractCause[ChiselException] {
- // Verify we can suppress the inclusion of default compileOptions
- import Chisel.{defaultCompileOptions => _}
- import chisel3.ExplicitCompileOptions.Strict
-
- class SimpleModule extends Module {
- val io = IO(new Bundle {
- val in = Input(UInt(3.W))
- val out = Output(UInt(4.W))
- })
- val noDir = Wire(UInt(3.W))
- }
-
- class DirectionLessConnectionModule extends SimpleModule {
- val a = 0.U(3.W)
- val b = Wire(UInt(3.W))
- val child = Module(new SimpleModule)
- b := child.noDir
- }
- ChiselStage.elaborate { new DirectionLessConnectionModule() }
- }
- }
-
- "Strict.copy()" should "be equivalent in all CompileOptions traits" in {
- import chisel3.ExplicitCompileOptions.Strict
- val copiedCompileOptions = Strict.copy()
- assert(copiedCompileOptions.connectFieldsMustMatch == Strict.connectFieldsMustMatch)
- assert(copiedCompileOptions.declaredTypeMustBeUnbound == Strict.declaredTypeMustBeUnbound)
- assert(copiedCompileOptions.dontTryConnectionsSwapped == Strict.dontTryConnectionsSwapped)
- assert(copiedCompileOptions.dontAssumeDirectionality == Strict.dontAssumeDirectionality)
- assert(copiedCompileOptions.checkSynthesizable == Strict.checkSynthesizable)
- assert(copiedCompileOptions.explicitInvalidate == Strict.explicitInvalidate)
- assert(copiedCompileOptions.inferModuleReset == Strict.inferModuleReset)
- assert(copiedCompileOptions.migrateInferModuleReset == Strict.migrateInferModuleReset)
- assert(copiedCompileOptions.emitStrictConnects == Strict.emitStrictConnects)
- }
-
- "NotStrict.copy()" should "be equivalent in all CompileOptions traits" in {
- import chisel3.ExplicitCompileOptions.NotStrict
- val copiedCompileOptions = NotStrict.copy()
- assert(copiedCompileOptions.connectFieldsMustMatch == NotStrict.connectFieldsMustMatch)
- assert(copiedCompileOptions.declaredTypeMustBeUnbound == NotStrict.declaredTypeMustBeUnbound)
- assert(copiedCompileOptions.dontTryConnectionsSwapped == NotStrict.dontTryConnectionsSwapped)
- assert(copiedCompileOptions.dontAssumeDirectionality == NotStrict.dontAssumeDirectionality)
- assert(copiedCompileOptions.checkSynthesizable == NotStrict.checkSynthesizable)
- assert(copiedCompileOptions.explicitInvalidate == NotStrict.explicitInvalidate)
- assert(copiedCompileOptions.inferModuleReset == NotStrict.inferModuleReset)
- assert(copiedCompileOptions.migrateInferModuleReset == NotStrict.migrateInferModuleReset)
- assert(copiedCompileOptions.emitStrictConnects == NotStrict.emitStrictConnects)
- }
-
-}
diff --git a/src/test/scala/chiselTests/ComplexAssign.scala b/src/test/scala/chiselTests/ComplexAssign.scala
deleted file mode 100644
index 99313967..00000000
--- a/src/test/scala/chiselTests/ComplexAssign.scala
+++ /dev/null
@@ -1,52 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.testers.BasicTester
-import chisel3.util._
-import org.scalacheck.Shrink
-
-class Complex[T <: Data](val re: T, val im: T) extends Bundle
-
-class ComplexAssign(w: Int) extends Module {
- val io = IO(new Bundle {
- val e = Input(Bool())
- val in = Input(new Complex(UInt(w.W), UInt(w.W)))
- val out = Output(new Complex(UInt(w.W), UInt(w.W)))
- })
- when(io.e) {
- val tmp = Wire(new Complex(UInt(w.W), UInt(w.W)))
- tmp := io.in
- io.out.re := tmp.re
- io.out.im := tmp.im
- }.otherwise {
- io.out.re := 0.U
- io.out.im := 0.U
- }
-}
-
-class ComplexAssignTester(enList: List[Boolean], re: Int, im: Int) extends BasicTester {
- val (cnt, wrap) = Counter(true.B, enList.size)
- val dut = Module(new ComplexAssign(32))
- dut.io.in.re := re.asUInt
- dut.io.in.im := im.asUInt
- dut.io.e := VecInit(enList.map(_.asBool))(cnt)
- val re_correct = dut.io.out.re === Mux(dut.io.e, dut.io.in.re, 0.U)
- val im_correct = dut.io.out.im === Mux(dut.io.e, dut.io.in.im, 0.U)
- assert(re_correct && im_correct)
- when(wrap) {
- stop()
- }
-}
-
-class ComplexAssignSpec extends ChiselPropSpec {
- property("All complex assignments should return the correct result") {
- // Disable shrinking on error.
- implicit val noShrinkListVal = Shrink[List[Boolean]](_ => Stream.empty)
- implicit val noShrinkInt = Shrink[Int](_ => Stream.empty)
- forAll(enSequence(2), safeUInts, safeUInts) { (en: List[Boolean], re: Int, im: Int) =>
- assertTesterPasses { new ComplexAssignTester(en, re, im) }
- }
- }
-}
diff --git a/src/test/scala/chiselTests/ConnectSpec.scala b/src/test/scala/chiselTests/ConnectSpec.scala
deleted file mode 100644
index 3a2b6d93..00000000
--- a/src/test/scala/chiselTests/ConnectSpec.scala
+++ /dev/null
@@ -1,196 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import org.scalatest._
-
-import chisel3._
-import chisel3.experimental.{Analog, FixedPoint}
-import chisel3.stage.ChiselStage
-import chisel3.testers.BasicTester
-
-abstract class CrossCheck extends Bundle {
- val in: Data
- val out: Data
-}
-
-class CrossConnects(inType: Data, outType: Data) extends Module {
- val io = IO(new Bundle {
- val in = Input(inType)
- val out = Output(outType)
- })
- io.out := io.in
-}
-
-class PipeInternalWires extends Module {
- import chisel3.util.Pipe
- val io = IO(new Bundle {
- val a = Input(Bool())
- val b = Input(UInt(32.W))
- })
- val pipe = Module(new Pipe(UInt(32.W), 32))
- pipe.io.enq.valid <> io.a
- pipe.io.enq.bits <> io.b
-}
-
-class CrossConnectTester(inType: Data, outType: Data) extends BasicTester {
- val dut = Module(new CrossConnects(inType, outType))
- dut.io := DontCare
- stop()
-}
-
-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] {
- extractCause[ChiselException] {
- ChiselStage.elaborate { new CrossConnectTester(UInt(16.W), SInt(16.W)) }
- }
- }
- }
- property("SInt := FixedPoint should fail") {
- 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] {
- extractCause[ChiselException] {
- ChiselStage.elaborate { new CrossConnectTester(SInt(16.W), UInt(16.W)) }
- }
- }
- }
- property("UInt := FixedPoint should fail") {
- 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] {
- 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] {
- extractCause[ChiselException] {
- ChiselStage.elaborate { new CrossConnectTester(SInt(16.W), FixedPoint(16.W, 8.BP)) }
- }
- }
- }
- property("FixedPoint := UInt should fail") {
- intercept[ChiselException] {
- extractCause[ChiselException] {
- ChiselStage.elaborate { new CrossConnectTester(UInt(16.W), FixedPoint(16.W, 8.BP)) }
- }
- }
- }
-
- property("Analog := Analog should fail") {
- intercept[ChiselException] {
- extractCause[ChiselException] {
- ChiselStage.elaborate { new CrossConnectTester(Analog(16.W), Analog(16.W)) }
- }
- }
- }
- property("Analog := FixedPoint should fail") {
- intercept[ChiselException] {
- extractCause[ChiselException] {
- ChiselStage.elaborate { new CrossConnectTester(Analog(16.W), FixedPoint(16.W, 8.BP)) }
- }
- }
- }
- property("FixedPoint := Analog should fail") {
- intercept[ChiselException] {
- extractCause[ChiselException] {
- ChiselStage.elaborate { new CrossConnectTester(FixedPoint(16.W, 8.BP), Analog(16.W)) }
- }
- }
- }
- property("Analog := UInt should fail") {
- intercept[ChiselException] {
- extractCause[ChiselException] {
- ChiselStage.elaborate { new CrossConnectTester(Analog(16.W), UInt(16.W)) }
- }
- }
- }
- property("Analog := SInt should fail") {
- intercept[ChiselException] {
- extractCause[ChiselException] {
- ChiselStage.elaborate { new CrossConnectTester(Analog(16.W), SInt(16.W)) }
- }
- }
- }
- property("UInt := Analog should fail") {
- intercept[ChiselException] {
- extractCause[ChiselException] {
- ChiselStage.elaborate { new CrossConnectTester(UInt(16.W), Analog(16.W)) }
- }
- }
- }
- property("SInt := Analog should fail") {
- intercept[ChiselException] {
- extractCause[ChiselException] {
- ChiselStage.elaborate { new CrossConnectTester(SInt(16.W), Analog(16.W)) }
- }
- }
- }
- property("Pipe internal connections should succeed") {
- ChiselStage.elaborate(new PipeInternalWires)
- }
-
- property("Connect error messages should have meaningful information") {
- class InnerExample extends Module {
- val myReg = RegInit(0.U(8.W))
- }
-
- class OuterAssignExample extends Module {
- val inner = Module(new InnerExample())
- inner.myReg := false.B // ERROR
- }
-
- val assignError = the[ChiselException] thrownBy { ChiselStage.elaborate { new OuterAssignExample } }
- val expectedAssignError = """.*@: myReg in InnerExample cannot be written from module OuterAssignExample."""
- (assignError.getMessage should fullyMatch).regex(expectedAssignError)
-
- class OuterReadExample extends Module {
- val myReg = RegInit(0.U(8.W))
- val inner = Module(new InnerExample())
- myReg := inner.myReg // ERROR
- }
-
- val readError = the[ChiselException] thrownBy { ChiselStage.elaborate { new OuterReadExample } }
- val expectedReadError = """.*@: myReg in InnerExample cannot be read from module OuterReadExample."""
- (readError.getMessage should fullyMatch).regex(expectedReadError)
-
- val typeMismatchError = the[ChiselException] thrownBy {
- ChiselStage.elaborate {
- new RawModule {
- val myUInt = Wire(UInt(4.W))
- val mySInt = Wire(SInt(4.W))
- myUInt := mySInt
- }
- }
- }
- val expectedTypeMismatchError = """.*@: Sink \(UInt<4>\) and Source \(SInt<4>\) have different types."""
- (typeMismatchError.getMessage should fullyMatch).regex(expectedTypeMismatchError)
- }
-}
diff --git a/src/test/scala/chiselTests/Counter.scala b/src/test/scala/chiselTests/Counter.scala
deleted file mode 100644
index 0e2a339a..00000000
--- a/src/test/scala/chiselTests/Counter.scala
+++ /dev/null
@@ -1,90 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.testers.BasicTester
-import chisel3.util._
-
-class CountTester(max: Int) extends BasicTester {
- val cnt = Counter(max)
- assert(cnt.n == max)
- when(true.B) { cnt.inc() }
- val expected = if (max == 0) 0.U else (max - 1).U
- when(cnt.value === expected) {
- stop()
- }
-}
-
-class EnableTester(seed: Int) extends BasicTester {
- val ens = RegInit(seed.asUInt)
- ens := ens >> 1
-
- val (cntEnVal, _) = Counter(ens(0), 32)
- val (_, done) = Counter(true.B, 33)
-
- when(done) {
- assert(cntEnVal === popCount(seed).asUInt)
- stop()
- }
-}
-
-class ResetTester(n: Int) extends BasicTester {
- val triggerReset = WireInit(false.B)
- val wasReset = RegNext(triggerReset)
- val (value, _) = Counter(0 until 8, reset = triggerReset)
-
- triggerReset := value === (n - 1).U
-
- when(wasReset) {
- assert(value === 0.U)
- stop()
- }
-}
-
-class WrapTester(max: Int) extends BasicTester {
- val (cnt, wrap) = Counter(true.B, max)
- when(wrap) {
- assert(cnt === (max - 1).asUInt)
- stop()
- }
-}
-
-class RangeTester(r: Range) extends BasicTester {
- val (cnt, wrap) = Counter(r)
- val checkWrap = RegInit(false.B)
-
- when(checkWrap) {
- assert(cnt === r.head.U)
- stop()
- }.elsewhen(wrap) {
- assert(cnt === r.last.U)
- checkWrap := true.B
- }
-}
-
-class CounterSpec extends ChiselPropSpec {
- property("Counter should count up") {
- for (i <- 0 until 4) {
- assertTesterPasses(new CountTester(i))
- }
- }
-
- property("Counter can be en/disabled") {
- forAll(safeUInts) { (seed: Int) => whenever(seed >= 0) { assertTesterPasses { new EnableTester(seed) } } }
- }
-
- property("Counter can be reset") {
- forAll(smallPosInts) { (seed: Int) => assertTesterPasses { new ResetTester(seed) } }
- }
-
- property("Counter should wrap") {
- forAll(smallPosInts) { (max: Int) => assertTesterPasses { new WrapTester(max) } }
- }
-
- property("Counter should handle a range") {
- forAll(posRange) { (r: Range) =>
- assertTesterPasses { new RangeTester(r) }
- }
- }
-}
diff --git a/src/test/scala/chiselTests/CustomBundle.scala b/src/test/scala/chiselTests/CustomBundle.scala
deleted file mode 100644
index ee964d2d..00000000
--- a/src/test/scala/chiselTests/CustomBundle.scala
+++ /dev/null
@@ -1,24 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.experimental.{requireIsChiselType, DataMirror}
-import scala.collection.immutable.ListMap
-
-// An example of how Record might be extended
-// In this case, CustomBundle is a Record constructed from a Tuple of (String, Data)
-// it is a possible implementation of a programmatic "Bundle"
-// (and can by connected to MyBundle below)
-final class CustomBundle(elts: (String, Data)*) extends Record {
- val elements = ListMap(elts.map {
- case (field, elt) =>
- requireIsChiselType(elt)
- field -> elt
- }: _*)
- def apply(elt: String): Data = elements(elt)
- override def cloneType: this.type = {
- val cloned = elts.map { case (n, d) => n -> DataMirror.internal.chiselTypeClone(d) }
- (new CustomBundle(cloned: _*)).asInstanceOf[this.type]
- }
-}
diff --git a/src/test/scala/chiselTests/DataEqualitySpec.scala b/src/test/scala/chiselTests/DataEqualitySpec.scala
deleted file mode 100644
index 8fbbaf94..00000000
--- a/src/test/scala/chiselTests/DataEqualitySpec.scala
+++ /dev/null
@@ -1,257 +0,0 @@
-package chiselTests
-
-import chisel3._
-import chisel3.experimental.VecLiterals._
-import chisel3.experimental.BundleLiterals._
-import chisel3.experimental.{Analog, ChiselRange, FixedPoint, Interval}
-import chisel3.stage.ChiselStage
-import chisel3.testers.BasicTester
-import chisel3.util.Valid
-
-class EqualityModule(lhsGen: => Data, rhsGen: => Data) extends Module {
- val out = IO(Output(Bool()))
-
- val lhs = lhsGen
- val rhs = rhsGen
-
- out := lhs === rhs
-}
-
-class EqualityTester(lhsGen: => Data, rhsGen: => Data) extends BasicTester {
- val module = Module(new EqualityModule(lhsGen, rhsGen))
-
- assert(module.out)
-
- stop()
-}
-
-class AnalogBundle extends Bundle {
- val analog = Analog(32.W)
-}
-
-class AnalogExceptionModule extends Module {
- class AnalogExceptionModuleIO extends Bundle {
- val bundle1 = new AnalogBundle
- val bundle2 = new AnalogBundle
- }
-
- val io = IO(new AnalogExceptionModuleIO)
-}
-
-class AnalogExceptionTester extends BasicTester {
- val module = Module(new AnalogExceptionModule)
-
- module.io.bundle1 <> DontCare
- module.io.bundle2 <> DontCare
-
- assert(module.io.bundle1 === module.io.bundle2)
-
- stop()
-}
-
-class DataEqualitySpec extends ChiselFlatSpec with Utils {
- object MyEnum extends ChiselEnum {
- val sA, sB = Value
- }
- object MyEnumB extends ChiselEnum {
- val sA, sB = Value
- }
- class MyBundle extends Bundle {
- val a = UInt(8.W)
- val b = Bool()
- val c = MyEnum()
- }
- class LongBundle extends Bundle {
- val a = UInt(48.W)
- val b = SInt(32.W)
- val c = FixedPoint(16.W, 4.BP)
- }
- class RuntimeSensitiveBundle(gen: => Bundle) extends Bundle {
- val a = UInt(8.W)
- val b: Bundle = gen
- }
-
- behavior.of("UInt === UInt")
- it should "pass with equal values" in {
- assertTesterPasses {
- new EqualityTester(0.U, 0.U)
- }
- }
- it should "fail with differing values" in {
- assertTesterFails {
- new EqualityTester(0.U, 1.U)
- }
- }
-
- behavior.of("SInt === SInt")
- it should "pass with equal values" in {
- assertTesterPasses {
- new EqualityTester(0.S, 0.S)
- }
- }
- it should "fail with differing values" in {
- assertTesterFails {
- new EqualityTester(0.S, 1.S)
- }
- }
-
- behavior.of("Reset === Reset")
- it should "pass with equal values" in {
- assertTesterPasses {
- new EqualityTester(true.B, true.B)
- }
- }
- it should "fail with differing values" in {
- assertTesterFails {
- new EqualityTester(true.B, false.B)
- }
- }
-
- behavior.of("AsyncReset === AsyncReset")
- it should "pass with equal values" in {
- assertTesterPasses {
- new EqualityTester(true.B.asAsyncReset, true.B.asAsyncReset)
- }
- }
- it should "fail with differing values" in {
- assertTesterFails {
- new EqualityTester(true.B.asAsyncReset, false.B.asAsyncReset)
- }
- }
-
- behavior.of("Interval === Interval")
- it should "pass with equal values" in {
- assertTesterPasses {
- new EqualityTester(2.I, 2.I)
- }
- }
- it should "fail with differing values" in {
- assertTesterFails {
- new EqualityTester(2.I, 3.I)
- }
- }
-
- behavior.of("FixedPoint === FixedPoint")
- it should "pass with equal values" in {
- assertTesterPasses {
- new EqualityTester(4.5.F(16.W, 4.BP), 4.5.F(16.W, 4.BP))
- }
- }
- it should "fail with differing values" in {
- assertTesterFails {
- new EqualityTester(4.5.F(16.W, 4.BP), 4.6.F(16.W, 4.BP))
- }
- }
-
- behavior.of("ChiselEnum === ChiselEnum")
- it should "pass with equal values" in {
- assertTesterPasses {
- new EqualityTester(MyEnum.sA, MyEnum.sA)
- }
- }
- it should "fail with differing values" in {
- assertTesterFails {
- new EqualityTester(MyEnum.sA, MyEnum.sB)
- }
- }
-
- behavior.of("Vec === Vec")
- it should "pass with equal sizes, equal values" in {
- assertTesterPasses {
- new EqualityTester(
- Vec(3, UInt(8.W)).Lit(0 -> 1.U, 1 -> 2.U, 2 -> 3.U),
- Vec(3, UInt(8.W)).Lit(0 -> 1.U, 1 -> 2.U, 2 -> 3.U)
- )
- }
- }
- it should "fail with equal sizes, differing values" in {
- assertTesterFails {
- new EqualityTester(
- Vec(3, UInt(8.W)).Lit(0 -> 1.U, 1 -> 2.U, 2 -> 3.U),
- Vec(3, UInt(8.W)).Lit(0 -> 0.U, 1 -> 1.U, 2 -> 2.U)
- )
- }
- }
- it should "throw a ChiselException with differing sizes" in {
- (the[ChiselException] thrownBy extractCause[ChiselException] {
- assertTesterFails {
- new EqualityTester(
- Vec(3, UInt(8.W)).Lit(0 -> 1.U, 1 -> 2.U, 2 -> 3.U),
- Vec(4, UInt(8.W)).Lit(0 -> 1.U, 1 -> 2.U, 2 -> 3.U, 3 -> 4.U)
- )
- }
- }).getMessage should include("Vec sizes differ")
- }
-
- behavior.of("Bundle === Bundle")
- it should "pass with equal type, equal values" in {
- assertTesterPasses {
- new EqualityTester(
- (new MyBundle).Lit(_.a -> 42.U, _.b -> false.B, _.c -> MyEnum.sB),
- (new MyBundle).Lit(_.a -> 42.U, _.b -> false.B, _.c -> MyEnum.sB)
- )
- }
- }
- it should "fail with equal type, differing values" in {
- assertTesterFails {
- new EqualityTester(
- (new MyBundle).Lit(_.a -> 42.U, _.b -> false.B, _.c -> MyEnum.sB),
- (new MyBundle).Lit(_.a -> 42.U, _.b -> false.B, _.c -> MyEnum.sA)
- )
- }
- }
- it should "throw a ChiselException with differing runtime types" in {
- (the[ChiselException] thrownBy extractCause[ChiselException] {
- assertTesterFails {
- new EqualityTester(
- (new RuntimeSensitiveBundle(new MyBundle)).Lit(
- _.a -> 1.U,
- _.b -> (new MyBundle).Lit(
- _.a -> 42.U,
- _.b -> false.B,
- _.c -> MyEnum.sB
- )
- ),
- (new RuntimeSensitiveBundle(new LongBundle)).Lit(
- _.a -> 1.U,
- _.b -> (new LongBundle).Lit(
- _.a -> 42.U,
- _.b -> 0.S,
- _.c -> 4.5.F(16.W, 4.BP)
- )
- )
- )
- }
- }).getMessage should include("Runtime types differ")
- }
-
- behavior.of("DontCare === DontCare")
- it should "pass with two invalids" in {
- assertTesterPasses {
- new EqualityTester(Valid(UInt(8.W)).Lit(_.bits -> 123.U), Valid(UInt(8.W)).Lit(_.bits -> 123.U))
- }
- }
- it should "exhibit the same behavior as comparing two invalidated wires" in {
- // Also check that two invalidated wires are equal
- assertTesterPasses {
- new EqualityTester(WireInit(UInt(8.W), DontCare), WireInit(UInt(8.W), DontCare))
- }
-
- // Compare the verilog generated from both test cases and verify that they both are equal to true
- val verilog1 = ChiselStage.emitVerilog(
- new EqualityModule(Valid(UInt(8.W)).Lit(_.bits -> 123.U), Valid(UInt(8.W)).Lit(_.bits -> 123.U))
- )
- val verilog2 =
- ChiselStage.emitVerilog(new EqualityModule(WireInit(UInt(8.W), DontCare), WireInit(UInt(8.W), DontCare)))
-
- verilog1 should include("assign out = 1'h1;")
- verilog2 should include("assign out = 1'h1;")
- }
-
- behavior.of("Analog === Analog")
- it should "throw a ChiselException" in {
- (the[ChiselException] thrownBy extractCause[ChiselException] {
- assertTesterFails { new AnalogExceptionTester }
- }).getMessage should include("Equality isn't defined for Analog values")
- }
-}
diff --git a/src/test/scala/chiselTests/DataPrint.scala b/src/test/scala/chiselTests/DataPrint.scala
deleted file mode 100644
index 82fa1519..00000000
--- a/src/test/scala/chiselTests/DataPrint.scala
+++ /dev/null
@@ -1,116 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import org.scalatest._
-
-import chisel3._
-import chisel3.experimental.FixedPoint
-import chisel3.experimental.BundleLiterals._
-import chisel3.stage.ChiselStage
-import org.scalatest.matchers.should.Matchers
-
-class DataPrintSpec extends ChiselFlatSpec with Matchers {
- object EnumTest extends ChiselEnum {
- val sNone, sOne, sTwo = Value
- }
-
- class BundleTest extends Bundle {
- val a = UInt(8.W)
- val b = Bool()
- }
-
- class PartialBundleTest extends Bundle {
- val a = UInt(8.W)
- val b = Bool()
- val c = SInt(8.W)
- val e = FixedPoint(5.W, 3.BP)
- val f = EnumTest.Type()
- }
-
- "Data types" should "have a meaningful string representation" in {
- 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>")
- Bool().toString should be("Bool")
- Clock().toString should be("Clock")
- FixedPoint(5.W, 3.BP).toString should be("FixedPoint<5><<3>>")
- Vec(3, UInt(2.W)).toString should be("UInt<2>[3]")
- EnumTest.Type().toString should be("EnumTest")
- (new BundleTest).toString should be("BundleTest")
- new Bundle { val a = UInt(8.W) }.toString should be("AnonymousBundle")
- new Bundle { val a = UInt(8.W) }.a.toString should be("UInt<8>")
- }
- }
- }
-
- class BoundDataModule extends Module { // not in the test to avoid anon naming suffixes
- Wire(UInt()).toString should be("BoundDataModule.?: Wire[UInt]")
- Reg(SInt()).toString should be("BoundDataModule.?: Reg[SInt]")
- val io = IO(Output(Bool())) // needs a name so elaboration doesn't fail
- io.toString should be("BoundDataModule.io: IO[Bool]")
- val m = Mem(4, UInt(2.W))
- m(2).toString should be("BoundDataModule.?: MemPort[UInt<2>]")
- (2.U + 2.U).toString should be("BoundDataModule.?: OpResult[UInt<2>]")
- Wire(Vec(3, UInt(2.W))).toString should be("BoundDataModule.?: Wire[UInt<2>[3]]")
-
- class InnerModule extends Module {
- val io = IO(Output(new Bundle {
- val a = UInt(4.W)
- }))
- }
- val inner = Module(new InnerModule)
- inner.clock.toString should be("InnerModule.clock: IO[Clock]")
- inner.io.a.toString should be("InnerModule.io.a: IO[UInt<4>]")
-
- class FooTypeTest extends Bundle {
- val foo = Vec(2, UInt(8.W))
- val fizz = UInt(8.W)
- }
- val tpe = new FooTypeTest
- val fooio: FooTypeTest = IO(Input(tpe))
- fooio.foo(0).toString should be("BoundDataModule.fooio.foo[0]: IO[UInt<8>]")
-
- class NestedBundle extends Bundle {
- val nestedFoo = UInt(8.W)
- val nestedFooVec = Vec(2, UInt(8.W))
- }
- class NestedType extends Bundle {
- val foo = new NestedBundle
- }
-
- val nestedTpe = new NestedType
- val nestedio = IO(Input(nestedTpe))
- (nestedio.foo.nestedFoo.toString should be("BoundDataModule.nestedio.foo.nestedFoo: IO[UInt<8>]"))
- (nestedio.foo.nestedFooVec(0).toString should be("BoundDataModule.nestedio.foo.nestedFooVec[0]: IO[UInt<8>]"))
- }
-
- "Bound data types" should "have a meaningful string representation" in {
- ChiselStage.elaborate { new BoundDataModule }
- }
-
- "Literals" should "have a meaningful string representation" in {
- 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)")
- false.B.toString should be("Bool(false)")
- true.B.toString should be("Bool(true)")
- 2.25.F(6.W, 2.BP).toString should be("FixedPoint<6><<2>>(2.25)")
- -2.25.F(6.W, 2.BP).toString should be("FixedPoint<6><<2>>(-2.25)")
- Vec(3, UInt(4.W)).toString should be("UInt<4>[3]")
- EnumTest.sNone.toString should be("EnumTest(0=sNone)")
- EnumTest.sTwo.toString should be("EnumTest(2=sTwo)")
- EnumTest(1.U).toString should be("EnumTest(1=sOne)")
- (new BundleTest).Lit(_.a -> 2.U, _.b -> false.B).toString should be("BundleTest(a=UInt<8>(2), b=Bool(false))")
- (new PartialBundleTest).Lit().toString should be(
- "PartialBundleTest(a=UInt<8>(DontCare), b=Bool(DontCare), c=SInt<8>(DontCare), e=FixedPoint<5><<3>>(DontCare), f=EnumTest(DontCare))"
- )
- DontCare.toString should be("DontCare()")
- }
- }
- }
-}
diff --git a/src/test/scala/chiselTests/Decoder.scala b/src/test/scala/chiselTests/Decoder.scala
deleted file mode 100644
index 0c644b49..00000000
--- a/src/test/scala/chiselTests/Decoder.scala
+++ /dev/null
@@ -1,59 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import org.scalacheck._
-
-import chisel3._
-import chisel3.testers.BasicTester
-import chisel3.util._
-
-class Decoder(bitpats: List[String]) extends Module {
- val io = IO(new Bundle {
- val inst = Input(UInt(32.W))
- val matched = Output(Bool())
- })
- io.matched := VecInit(bitpats.map(BitPat(_) === io.inst)).reduce(_ || _)
-}
-
-class DecoderTester(pairs: List[(String, String)]) extends BasicTester {
- val (insts, bitpats) = pairs.unzip
- val (cnt, wrap) = Counter(true.B, pairs.size)
- val dut = Module(new Decoder(bitpats))
- dut.io.inst := VecInit(insts.map(_.asUInt))(cnt)
- when(!dut.io.matched) {
- assert(cnt === 0.U)
- stop()
- }
- when(wrap) {
- stop()
- }
-}
-
-class DecoderSpec extends ChiselPropSpec {
-
- // Use a single Int to make both a specific instruction and a BitPat that will match it
- val bitpatPair = for (seed <- Arbitrary.arbitrary[Int]) yield {
- val rnd = new scala.util.Random(seed)
- val bs = seed.toBinaryString
- val bp = bs.map(if (rnd.nextBoolean) _ else "?")
-
- // The following randomly throws in white space and underscores which are legal and ignored.
- val bpp = bp.map { a =>
- if (rnd.nextBoolean) {
- a
- } else {
- a + (if (rnd.nextBoolean) "_" else " ")
- }
- }.mkString
-
- ("b" + bs, "b" + bpp)
- }
- private def nPairs(n: Int) = Gen.containerOfN[List, (String, String)](n, bitpatPair)
-
- property("BitPat wildcards should be usable in decoding") {
- forAll(nPairs(4)) { (pairs: List[(String, String)]) =>
- assertTesterPasses { new DecoderTester(pairs) }
- }
- }
-}
diff --git a/src/test/scala/chiselTests/DecoupledSpec.scala b/src/test/scala/chiselTests/DecoupledSpec.scala
deleted file mode 100644
index 69d74aab..00000000
--- a/src/test/scala/chiselTests/DecoupledSpec.scala
+++ /dev/null
@@ -1,111 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-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 {
- ChiselStage.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)
- })
- }
-
- "Decoupled.map" should "apply a function to a wrapped Data" in {
- val chirrtl = ChiselStage
- .emitChirrtl(new Module {
- val enq = IO(Flipped(Decoupled(UInt(8.W))))
- val deq = IO(Decoupled(UInt(8.W)))
- deq <> enq.map(_ + 1.U)
- })
-
- // Check for data assignment
- chirrtl should include("""node _deq_map_bits_T = add(enq.bits, UInt<1>("h1")""")
- chirrtl should include("""node _deq_map_bits = tail(_deq_map_bits_T, 1)""")
- chirrtl should include("""_deq_map.bits <= _deq_map_bits""")
- chirrtl should include("""deq <= _deq_map""")
-
- // Check for back-pressure (ready signal is driven in the opposite direction of bits + valid)
- chirrtl should include("""enq.ready <= _deq_map.ready""")
- }
-
- "Decoupled.map" should "apply a function to a wrapped Bundle" in {
- class TestBundle extends Bundle {
- val foo = UInt(8.W)
- val bar = UInt(8.W)
- val fizz = Bool()
- val buzz = Bool()
- }
-
- // Add one to foo, subtract one from bar, set fizz to false and buzz to true
- def func(t: TestBundle): TestBundle = {
- val res = Wire(new TestBundle)
-
- res.foo := t.foo + 1.U
- res.bar := t.bar - 1.U
- res.fizz := false.B
- res.buzz := true.B
-
- res
- }
-
- val chirrtl = ChiselStage
- .emitChirrtl(new Module {
- val enq = IO(Flipped(Decoupled(new TestBundle)))
- val deq = IO(Decoupled(new TestBundle))
- deq <> enq.map(func)
- })
-
- // Check for data assignment
- chirrtl should include("""wire _deq_map_bits : { foo : UInt<8>, bar : UInt<8>, fizz : UInt<1>, buzz : UInt<1>}""")
-
- chirrtl should include("""node _deq_map_bits_res_foo_T = add(enq.bits.foo, UInt<1>("h1")""")
- chirrtl should include("""node _deq_map_bits_res_foo_T_1 = tail(_deq_map_bits_res_foo_T, 1)""")
- chirrtl should include("""_deq_map_bits.foo <= _deq_map_bits_res_foo_T_1""")
-
- chirrtl should include("""node _deq_map_bits_res_bar_T = sub(enq.bits.bar, UInt<1>("h1")""")
- chirrtl should include("""node _deq_map_bits_res_bar_T_1 = tail(_deq_map_bits_res_bar_T, 1)""")
- chirrtl should include("""_deq_map_bits.bar <= _deq_map_bits_res_bar_T_1""")
-
- chirrtl should include("""_deq_map_bits.fizz <= UInt<1>("h0")""")
- chirrtl should include("""_deq_map_bits.buzz <= UInt<1>("h1")""")
-
- chirrtl should include("""_deq_map.bits <= _deq_map_bits""")
- chirrtl should include("""deq <= _deq_map""")
-
- // Check for back-pressure (ready signal is driven in the opposite direction of bits + valid)
- chirrtl should include("""enq.ready <= _deq_map.ready""")
- }
-
- "Decoupled.map" should "apply a function to a wrapped Bundle and return a different typed DecoupledIO" in {
- class TestBundle extends Bundle {
- val foo = UInt(8.W)
- val bar = UInt(8.W)
- }
-
- val chirrtl = ChiselStage
- .emitChirrtl(new Module {
- val enq = IO(Flipped(Decoupled(new TestBundle)))
- val deq = IO(Decoupled(UInt(8.W)))
- deq <> enq.map(bundle => bundle.foo & bundle.bar)
- })
-
- // Check that the _map wire wraps a UInt and not a TestBundle
- chirrtl should include("""wire _deq_map : { flip ready : UInt<1>, valid : UInt<1>, bits : UInt<8>}""")
-
- // Check for data assignment
- chirrtl should include("""node _deq_map_bits = and(enq.bits.foo, enq.bits.bar)""")
- chirrtl should include("""_deq_map.bits <= _deq_map_bits""")
- chirrtl should include("""deq <= _deq_map""")
-
- // Check for back-pressure (ready signal is driven in the opposite direction of bits + valid)
- chirrtl should include("""enq.ready <= _deq_map.ready""")
- }
-}
diff --git a/src/test/scala/chiselTests/DedupSpec.scala b/src/test/scala/chiselTests/DedupSpec.scala
deleted file mode 100644
index f2f2ed45..00000000
--- a/src/test/scala/chiselTests/DedupSpec.scala
+++ /dev/null
@@ -1,84 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.util._
-
-class DedupIO extends Bundle {
- val in = Flipped(Decoupled(UInt(32.W)))
- val out = Decoupled(UInt(32.W))
-}
-
-class DedupQueues(n: Int) extends Module {
- require(n > 0)
- val io = IO(new DedupIO)
- val queues = Seq.fill(n)(Module(new Queue(UInt(32.W), 4)))
- var port = io.in
- for (q <- queues) {
- q.io.enq <> port
- port = q.io.deq
- }
- io.out <> port
-}
-
-/* This module creates a Queue in a nested function (such that it is not named via reflection). The
- * default naming for instances prior to #470 caused otherwise identical instantiations of this
- * module to have different instance names for the queues which prevented deduplication.
- * NestedDedup instantiates this module twice to ensure it is deduplicated properly.
- */
-class DedupSubModule extends Module {
- val io = IO(new DedupIO)
- io.out <> Queue(io.in, 4)
-}
-
-class NestedDedup extends Module {
- val io = IO(new DedupIO)
- val inst0 = Module(new DedupSubModule)
- val inst1 = Module(new DedupSubModule)
- inst0.io.in <> io.in
- inst1.io.in <> inst0.io.out
- io.out <> inst1.io.out
-}
-
-object DedupConsts {
- val foo = 3.U
-}
-
-class SharedConstantValDedup extends Module {
- val io = IO(new Bundle {
- val in = Input(UInt(8.W))
- val out = Output(UInt(8.W))
- })
- io.out := io.in + DedupConsts.foo
-}
-
-class SharedConstantValDedupTop extends Module {
- val io = IO(new Bundle {
- val in = Input(UInt(8.W))
- val out = Output(UInt(8.W))
- })
- val inst0 = Module(new SharedConstantValDedup)
- val inst1 = Module(new SharedConstantValDedup)
- inst0.io.in := io.in
- inst1.io.in := io.in
- io.out := inst0.io.out + inst1.io.out
-}
-
-class DedupSpec extends ChiselFlatSpec {
- private val ModuleRegex = """\s*module\s+(\w+)\b.*""".r
- def countModules(verilog: String): Int =
- (verilog.split("\n").collect { case ModuleRegex(name) => name }).size
-
- "Deduplication" should "occur" in {
- assert(countModules(compile { new DedupQueues(4) }) === 2)
- }
-
- it should "properly dedup modules with deduped submodules" in {
- assert(countModules(compile { new NestedDedup }) === 3)
- }
-
- it should "dedup modules that share a literal" in {
- assert(countModules(compile { new SharedConstantValDedupTop }) === 2)
- }
-}
diff --git a/src/test/scala/chiselTests/Direction.scala b/src/test/scala/chiselTests/Direction.scala
deleted file mode 100644
index ddbd99d2..00000000
--- a/src/test/scala/chiselTests/Direction.scala
+++ /dev/null
@@ -1,443 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import org.scalatest._
-import chisel3._
-import chisel3.experimental.OpaqueType
-import chisel3.stage.ChiselStage
-import org.scalatest.matchers.should.Matchers
-
-import scala.collection.immutable.SeqMap
-
-class DirectionedBundle extends Bundle {
- val in = Input(UInt(32.W))
- val out = Output(UInt(32.W))
-}
-
-class DirectionHaver extends Module {
- val io = IO(new Bundle {
- val in = Input(UInt(32.W))
- val out = Output(UInt(32.W))
- val inBundle = Input(new DirectionedBundle) // should override elements
- val outBundle = Output(new DirectionedBundle) // should override elements
- })
-}
-
-class GoodDirection extends DirectionHaver {
- io.out := 0.U
- io.outBundle.in := 0.U
- io.outBundle.out := 0.U
-}
-
-class BadDirection extends DirectionHaver {
- io.in := 0.U
-}
-
-class BadSubDirection extends DirectionHaver {
- io.inBundle.out := 0.U
-}
-
-class TopDirectionOutput extends Module {
- val io = IO(Output(new DirectionedBundle))
- io.in := 42.U
- io.out := 117.U
-}
-
-class DirectionSpec extends ChiselPropSpec with Matchers with Utils {
-
- //TODO: In Chisel3 these are actually FIRRTL errors. Remove from tests?
-
- property("Outputs should be assignable") {
- ChiselStage.elaborate(new GoodDirection)
- }
-
- property("Inputs should not be assignable") {
- a[Exception] should be thrownBy extractCause[Exception] {
- ChiselStage.elaborate(new BadDirection)
- }
- a[Exception] should be thrownBy extractCause[Exception] {
- ChiselStage.elaborate(new BadSubDirection)
- }
- }
-
- property("Top-level forced outputs should be assignable") {
- ChiselStage.elaborate(new TopDirectionOutput)
- }
-
- property("Empty Vecs with directioned sample_element should not cause direction errors") {
- ChiselStage.elaborate(new Module {
- val io = IO(new Bundle {
- val foo = Input(UInt(8.W))
- val x = Vec(0, Output(UInt(8.W)))
- })
- })
- ChiselStage.elaborate(new Module {
- val io = IO(new Bundle {
- val foo = Input(UInt(8.W))
- val x = Flipped(Vec(0, Output(UInt(8.W))))
- })
- })
- ChiselStage.elaborate(new Module {
- val io = IO(new Bundle {
- val foo = Input(UInt(8.W))
- val x = Output(Vec(0, UInt(8.W)))
- })
- })
- }
-
- property(
- "Empty Vecs with no direction on the sample_element should not cause direction errors, as Chisel and chisel3 directions are merged"
- ) {
- ChiselStage.elaborate(new Module {
- val io = IO(new Bundle {
- val foo = Input(UInt(8.W))
- val x = Vec(0, UInt(8.W))
- })
- })
- }
-
- property("Empty Bundles should not cause direction errors") {
- ChiselStage.elaborate(new Module {
- val io = IO(new Bundle {
- val foo = Input(UInt(8.W))
- val x = new Bundle {}
- })
- })
- ChiselStage.elaborate(new Module {
- val io = IO(new Bundle {
- val foo = Input(UInt(8.W))
- val x = Flipped(new Bundle {})
- })
- })
- ChiselStage.elaborate(new Module {
- val io = IO(new Bundle {
- val foo = Input(UInt(8.W))
- val x = new Bundle {
- val y = if (false) Some(Input(UInt(8.W))) else None
- }
- })
- })
- }
-
- property(
- "Explicitly directioned but empty Bundles should not cause direction errors because Chisel and chisel3 directionality are merged"
- ) {
- ChiselStage.elaborate(new Module {
- val io = IO(new Bundle {
- val foo = UInt(8.W)
- val x = Input(new Bundle {})
- })
- })
- }
-
- import chisel3.experimental.{DataMirror, Direction}
-
- property("Directions should be preserved through cloning and binding of Bundles") {
- ChiselStage.elaborate(new Module {
- class MyBundle extends Bundle {
- val foo = Input(UInt(8.W))
- val bar = Output(UInt(8.W))
- }
- class MyOuterBundle extends Bundle {
- val fizz = new MyBundle
- val buzz = Flipped(new MyBundle)
- }
- val a = new MyOuterBundle
- val b = IO(a)
- val specifiedDirs = Seq(
- a.fizz.foo -> SpecifiedDirection.Input,
- a.fizz.bar -> SpecifiedDirection.Output,
- a.fizz -> SpecifiedDirection.Unspecified,
- a.buzz.foo -> SpecifiedDirection.Input,
- a.buzz.bar -> SpecifiedDirection.Output,
- a.buzz -> SpecifiedDirection.Flip
- )
- val actualDirs = Seq(
- b.fizz.foo -> Direction.Input,
- b.fizz.bar -> Direction.Output,
- b.fizz -> Direction.Bidirectional(Direction.Default),
- b.buzz.foo -> Direction.Output,
- b.buzz.bar -> Direction.Input,
- b.buzz -> Direction.Bidirectional(Direction.Flipped)
- )
- for ((data, dir) <- specifiedDirs) {
- DataMirror.specifiedDirectionOf(data) shouldBe (dir)
- }
- for ((data, dir) <- actualDirs) {
- DataMirror.directionOf(data) shouldBe (dir)
- }
- }.asInstanceOf[Module]) // The cast works around weird reflection behavior (bug?)
- }
-
- property("Directions should be preserved through cloning and binding of Vecs") {
- ChiselStage.elaborate(new Module {
- val a = Vec(1, Input(UInt(8.W)))
- val b = Vec(1, a)
- val c = Vec(1, Flipped(a))
- val io0 = IO(b)
- val io1 = IO(c)
- val specifiedDirs = Seq(
- a(0) -> SpecifiedDirection.Input,
- b(0)(0) -> SpecifiedDirection.Input,
- a -> SpecifiedDirection.Unspecified,
- b -> SpecifiedDirection.Unspecified,
- c(0) -> SpecifiedDirection.Flip,
- c(0)(0) -> SpecifiedDirection.Input,
- c -> SpecifiedDirection.Unspecified
- )
- val actualDirs = Seq(
- io0(0)(0) -> Direction.Input,
- io0(0) -> Direction.Input,
- io0 -> Direction.Input,
- io1(0)(0) -> Direction.Output,
- io1(0) -> Direction.Output,
- io1 -> Direction.Output
- )
- for ((data, dir) <- specifiedDirs) {
- DataMirror.specifiedDirectionOf(data) shouldBe (dir)
- }
- for ((data, dir) <- actualDirs) {
- DataMirror.directionOf(data) shouldBe (dir)
- }
- }.asInstanceOf[Module]) // The cast works around weird reflection behavior (bug?)
- }
-
- property("Using Vec and Flipped together should calculate directions properly") {
- class MyModule extends RawModule {
- class MyBundle extends Bundle {
- val a = Input(Bool())
- val b = Output(Bool())
- }
-
- val index = IO(Input(UInt(1.W)))
-
- // Check all permutations of Vec and Flipped.
- val regularVec = IO(Vec(2, new MyBundle))
- regularVec <> DontCare
- assert(DataMirror.directionOf(regularVec.head.a) == Direction.Input)
- assert(DataMirror.directionOf(regularVec.head.b) == Direction.Output)
- assert(DataMirror.directionOf(regularVec(index).a) == Direction.Input)
- assert(DataMirror.directionOf(regularVec(index).b) == Direction.Output)
-
- val vecFlipped = IO(Vec(2, Flipped(new MyBundle)))
- vecFlipped <> DontCare
- assert(DataMirror.directionOf(vecFlipped.head.a) == Direction.Output)
- assert(DataMirror.directionOf(vecFlipped.head.b) == Direction.Input)
- assert(DataMirror.directionOf(vecFlipped(index).a) == Direction.Output)
- assert(DataMirror.directionOf(vecFlipped(index).b) == Direction.Input)
-
- val flippedVec = IO(Flipped(Vec(2, new MyBundle)))
- flippedVec <> DontCare
- assert(DataMirror.directionOf(flippedVec.head.a) == Direction.Output)
- assert(DataMirror.directionOf(flippedVec.head.b) == Direction.Input)
- assert(DataMirror.directionOf(flippedVec(index).a) == Direction.Output)
- assert(DataMirror.directionOf(flippedVec(index).b) == Direction.Input)
-
- // Flipped(Vec(Flipped())) should be equal to non-flipped.
- val flippedVecFlipped = IO(Flipped(Vec(2, Flipped(new MyBundle))))
- flippedVecFlipped <> DontCare
- assert(DataMirror.directionOf(flippedVecFlipped.head.a) == Direction.Input)
- assert(DataMirror.directionOf(flippedVecFlipped.head.b) == Direction.Output)
- assert(DataMirror.directionOf(flippedVecFlipped(index).a) == Direction.Input)
- assert(DataMirror.directionOf(flippedVecFlipped(index).b) == Direction.Output)
- }
-
- val emitted: String = ChiselStage.emitChirrtl(new MyModule)
- val firrtl: String = ChiselStage.convert(new MyModule).serialize
-
- // Check that emitted directions are correct.
- Seq(emitted, firrtl).foreach { o =>
- {
- // Chisel Emitter formats spacing a little differently than the
- // FIRRTL Emitter :-(
- val s = o.replace("{flip a", "{ flip a")
- assert(s.contains("output regularVec : { flip a : UInt<1>, b : UInt<1>}[2]"))
- assert(s.contains("input vecFlipped : { flip a : UInt<1>, b : UInt<1>}[2]"))
- assert(s.contains("input flippedVec : { flip a : UInt<1>, b : UInt<1>}[2]"))
- assert(s.contains("output flippedVecFlipped : { flip a : UInt<1>, b : UInt<1>}[2]"))
- }
- }
- }
-
- property("Vec with Input/Output should calculate directions properly") {
- class MyModule extends RawModule {
- class MyBundle extends Bundle {
- val a = Input(Bool())
- val b = Output(Bool())
- }
-
- val index = IO(Input(UInt(1.W)))
-
- val inputVec = IO(Vec(2, Input(new MyBundle)))
- inputVec <> DontCare
- assert(DataMirror.directionOf(inputVec.head.a) == Direction.Input)
- assert(DataMirror.directionOf(inputVec.head.b) == Direction.Input)
- assert(DataMirror.directionOf(inputVec(index).a) == Direction.Input)
- assert(DataMirror.directionOf(inputVec(index).b) == Direction.Input)
-
- val vecInput = IO(Input(Vec(2, new MyBundle)))
- vecInput <> DontCare
- assert(DataMirror.directionOf(vecInput.head.a) == Direction.Input)
- assert(DataMirror.directionOf(vecInput.head.b) == Direction.Input)
- assert(DataMirror.directionOf(vecInput(index).a) == Direction.Input)
- assert(DataMirror.directionOf(vecInput(index).b) == Direction.Input)
-
- val vecInputFlipped = IO(Input(Vec(2, Flipped(new MyBundle))))
- vecInputFlipped <> DontCare
- assert(DataMirror.directionOf(vecInputFlipped.head.a) == Direction.Input)
- assert(DataMirror.directionOf(vecInputFlipped.head.b) == Direction.Input)
- assert(DataMirror.directionOf(vecInputFlipped(index).a) == Direction.Input)
- assert(DataMirror.directionOf(vecInputFlipped(index).b) == Direction.Input)
-
- val outputVec = IO(Vec(2, Output(new MyBundle)))
- outputVec <> DontCare
- assert(DataMirror.directionOf(outputVec.head.a) == Direction.Output)
- assert(DataMirror.directionOf(outputVec.head.b) == Direction.Output)
- assert(DataMirror.directionOf(outputVec(index).a) == Direction.Output)
- assert(DataMirror.directionOf(outputVec(index).b) == Direction.Output)
-
- val vecOutput = IO(Output(Vec(2, new MyBundle)))
- vecOutput <> DontCare
- assert(DataMirror.directionOf(vecOutput.head.a) == Direction.Output)
- assert(DataMirror.directionOf(vecOutput.head.b) == Direction.Output)
- assert(DataMirror.directionOf(vecOutput(index).a) == Direction.Output)
- assert(DataMirror.directionOf(vecOutput(index).b) == Direction.Output)
-
- val vecOutputFlipped = IO(Output(Vec(2, Flipped(new MyBundle))))
- vecOutputFlipped <> DontCare
- assert(DataMirror.directionOf(vecOutputFlipped.head.a) == Direction.Output)
- assert(DataMirror.directionOf(vecOutputFlipped.head.b) == Direction.Output)
- assert(DataMirror.directionOf(vecOutputFlipped(index).a) == Direction.Output)
- assert(DataMirror.directionOf(vecOutputFlipped(index).b) == Direction.Output)
- }
-
- val emitted: String = ChiselStage.emitChirrtl(new MyModule)
- val firrtl: String = ChiselStage.convert(new MyModule).serialize
-
- // Check that emitted directions are correct.
- Seq(emitted, firrtl).foreach { o =>
- {
- // Chisel Emitter formats spacing a little differently than the
- // FIRRTL Emitter :-(
- val s = o.replace("{a", "{ a")
- assert(s.contains("input inputVec : { a : UInt<1>, b : UInt<1>}[2]"))
- assert(s.contains("input vecInput : { a : UInt<1>, b : UInt<1>}[2]"))
- assert(s.contains("input vecInputFlipped : { a : UInt<1>, b : UInt<1>}[2]"))
- assert(s.contains("output outputVec : { a : UInt<1>, b : UInt<1>}[2]"))
- assert(s.contains("output vecOutput : { a : UInt<1>, b : UInt<1>}[2]"))
- assert(s.contains("output vecOutputFlipped : { a : UInt<1>, b : UInt<1>}[2]"))
- }
- }
- }
- property("Can now describe a Decoupled bundle using Flipped, not Input/Output in chisel3") {
- class Decoupled extends Bundle {
- val bits = UInt(3.W)
- val valid = Bool()
- val ready = Flipped(Bool())
- }
- class MyModule extends RawModule {
- val incoming = IO(Flipped(new Decoupled))
- val outgoing = IO(new Decoupled)
-
- outgoing <> incoming
- }
-
- val emitted: String = ChiselStage.emitChirrtl(new MyModule)
-
- // Check that emitted directions are correct.
- assert(emitted.contains("input incoming : { bits : UInt<3>, valid : UInt<1>, flip ready : UInt<1>}"))
- assert(emitted.contains("output outgoing : { bits : UInt<3>, valid : UInt<1>, flip ready : UInt<1>}"))
- assert(emitted.contains("outgoing <= incoming"))
- }
- property("Can now mix Input/Output and Flipped within the same bundle") {
- class Decoupled extends Bundle {
- val bits = UInt(3.W)
- val valid = Bool()
- val ready = Flipped(Bool())
- }
- class DecoupledAndMonitor extends Bundle {
- val producer = new Decoupled()
- val consumer = Flipped(new Decoupled())
- val monitor = Input(new Decoupled()) // Same as Flipped(stripFlipsIn(..))
- val driver = Output(new Decoupled()) // Same as stripFlipsIn(..)
- }
- class MyModule extends RawModule {
- val io = IO(Flipped(new DecoupledAndMonitor()))
- io.consumer <> io.producer
- io.monitor.bits := io.driver.bits
- io.monitor.valid := io.driver.valid
- io.monitor.ready := io.driver.ready
- }
-
- val emitted: String = ChiselStage.emitChirrtl(new MyModule)
-
- assert(
- emitted.contains(
- "input io : { producer : { bits : UInt<3>, valid : UInt<1>, flip ready : UInt<1>}, flip consumer : { bits : UInt<3>, valid : UInt<1>, flip ready : UInt<1>}, flip monitor : { bits : UInt<3>, valid : UInt<1>, ready : UInt<1>}, driver : { bits : UInt<3>, valid : UInt<1>, ready : UInt<1>}}"
- )
- )
- assert(emitted.contains("io.consumer <= io.producer"))
- assert(emitted.contains("io.monitor.bits <= io.driver.bits"))
- assert(emitted.contains("io.monitor.valid <= io.driver.valid"))
- assert(emitted.contains("io.monitor.ready <= io.driver.ready"))
- }
- property("Bugfix: marking Vec fields with mixed directionality as Output/Input clears inner directions") {
- class Decoupled extends Bundle {
- val bits = UInt(3.W)
- val valid = Bool()
- val ready = Flipped(Bool())
- }
- class Coercing extends Bundle {
- val source = Output(Vec(1, new Decoupled()))
- val sink = Input(Vec(1, new Decoupled()))
- }
- class MyModule extends RawModule {
- val io = IO(new Coercing())
- val source = IO(Output(Vec(1, new Decoupled())))
- val sink = IO(Input(Vec(1, new Decoupled())))
- }
-
- val emitted: String = ChiselStage.emitChirrtl(new MyModule)
-
- assert(
- emitted.contains(
- "output io : { source : { bits : UInt<3>, valid : UInt<1>, ready : UInt<1>}[1], flip sink : { bits : UInt<3>, valid : UInt<1>, ready : UInt<1>}[1]}"
- )
- )
- assert(
- emitted.contains(
- "output source : { bits : UInt<3>, valid : UInt<1>, ready : UInt<1>}[1]"
- )
- )
- assert(
- emitted.contains(
- "input sink : { bits : UInt<3>, valid : UInt<1>, ready : UInt<1>}[1]"
- )
- )
- }
- property("Bugfix: clearing all flips inside an opaque type") {
-
- class Decoupled extends Bundle {
- val bits = UInt(3.W)
- val valid = Bool()
- val ready = Flipped(Bool())
- }
- class MyOpaqueType extends Record with OpaqueType {
- val k = new Decoupled()
- val elements = SeqMap("" -> k)
- override def cloneType: this.type = (new MyOpaqueType).asInstanceOf[this.type]
- }
- class MyModule extends RawModule {
- val w = Wire(new MyOpaqueType())
- }
-
- val emitted: String = ChiselStage.emitChirrtl(new MyModule)
-
- assert(
- emitted.contains(
- "wire w : { bits : UInt<3>, valid : UInt<1>, flip ready : UInt<1>}"
- )
- )
- }
-}
diff --git a/src/test/scala/chiselTests/DontTouchSpec.scala b/src/test/scala/chiselTests/DontTouchSpec.scala
deleted file mode 100644
index 4b21840e..00000000
--- a/src/test/scala/chiselTests/DontTouchSpec.scala
+++ /dev/null
@@ -1,61 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.stage.ChiselStage
-
-class HasDeadCodeChild(withDontTouch: Boolean) extends Module {
- val io = IO(new Bundle {
- val a = Input(UInt(32.W))
- val b = Output(UInt(32.W))
- val c = Output(Vec(2, UInt(32.W)))
- })
- io.b := io.a
- io.c := DontCare
- if (withDontTouch) {
- dontTouch(io.c)
- }
-}
-
-class HasDeadCode(withDontTouch: Boolean) extends Module {
- val io = IO(new Bundle {
- val a = Input(UInt(32.W))
- val b = Output(UInt(32.W))
- })
- val inst = Module(new HasDeadCodeChild(withDontTouch))
- inst.io.a := io.a
- io.b := inst.io.b
- val dead = WireDefault(io.a + 1.U)
- if (withDontTouch) {
- dontTouch(dead)
- }
-}
-
-class DontTouchSpec extends ChiselFlatSpec with Utils {
- val deadSignals = List(
- "io_c_0",
- "io_c_1",
- "dead"
- )
- "Dead code" should "be removed by default" in {
- val verilog = compile(new HasDeadCode(false))
- for (signal <- deadSignals) {
- (verilog should not).include(signal)
- }
- }
- it should "NOT be removed if marked dontTouch" in {
- val verilog = compile(new HasDeadCode(true))
- for (signal <- deadSignals) {
- verilog should include(signal)
- }
- }
- "Dont touch" should "only work on bound hardware" in {
- 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
deleted file mode 100644
index 4d407169..00000000
--- a/src/test/scala/chiselTests/EnableShiftRegister.scala
+++ /dev/null
@@ -1,53 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-import chisel3._
-import chisel3.stage.ChiselStage
-
-class EnableShiftRegister extends Module {
- val io = IO(new Bundle {
- val in = Input(UInt(4.W))
- val shift = Input(Bool())
- val out = Output(UInt(4.W))
- })
- val r0 = RegInit(0.U(4.W))
- val r1 = RegInit(0.U(4.W))
- val r2 = RegInit(0.U(4.W))
- val r3 = RegInit(0.U(4.W))
- when(io.shift) {
- r0 := io.in
- r1 := r0
- r2 := r1
- r3 := r2
- }
- io.out := r3
-}
-
-/*
-class EnableShiftRegisterTester(c: EnableShiftRegister) extends Tester(c) {
- val reg = Array.fill(4){ 0 }
- for (t <- 0 until 16) {
- val in = rnd.nextInt(16)
- val shift = rnd.nextInt(2)
- println("SHIFT " + shift + " IN " + in)
- poke(c.io.in, in)
- poke(c.io.shift, shift)
- step(1)
- if (shift == 1) {
- for (i <- 3 to 1 by -1)
- reg(i) = reg(i-1)
- reg(0) = in
- }
- expect(c.io.out, reg(3))
- }
-}
- */
-
-class EnableShiftRegisterSpec extends ChiselPropSpec {
-
- property("EnableShiftRegister should elaborate") {
- ChiselStage.elaborate { new EnableShiftRegister }
- }
-
- ignore("EnableShiftRegisterTester should return the correct result") {}
-}
diff --git a/src/test/scala/chiselTests/EnumSpec.scala b/src/test/scala/chiselTests/EnumSpec.scala
deleted file mode 100644
index 254439af..00000000
--- a/src/test/scala/chiselTests/EnumSpec.scala
+++ /dev/null
@@ -1,19 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.util.Enum
-import chisel3.testers.BasicTester
-
-class EnumSpec extends ChiselFlatSpec {
-
- "1-entry Enums" should "work" in {
- assertTesterPasses(new BasicTester {
- val onlyState :: Nil = Enum(1)
- val wire = WireDefault(onlyState)
- chisel3.assert(wire === onlyState)
- stop()
- })
- }
-}
diff --git a/src/test/scala/chiselTests/ExtModule.scala b/src/test/scala/chiselTests/ExtModule.scala
deleted file mode 100644
index 3ab4cc32..00000000
--- a/src/test/scala/chiselTests/ExtModule.scala
+++ /dev/null
@@ -1,137 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.experimental._
-import chisel3.stage.ChiselStage
-import chisel3.testers.{BasicTester, TesterDriver}
-
-// Avoid collisions with regular BlackBox tests by putting ExtModule blackboxes
-// in their own scope.
-package extmoduletests {
-
- import chisel3.experimental.ExtModule
-
- class BlackBoxInverter extends ExtModule {
- val in = IO(Input(Bool()))
- val out = IO(Output(Bool()))
- }
-
- class BlackBoxPassthrough extends ExtModule {
- val in = IO(Input(Bool()))
- val out = IO(Output(Bool()))
- }
-}
-
-class ExtModuleTester extends BasicTester {
- val blackBoxPos = Module(new extmoduletests.BlackBoxInverter)
- val blackBoxNeg = Module(new extmoduletests.BlackBoxInverter)
-
- blackBoxPos.in := 1.U
- blackBoxNeg.in := 0.U
-
- assert(blackBoxNeg.out === 1.U)
- assert(blackBoxPos.out === 0.U)
- stop()
-}
-
-/** Instantiate multiple BlackBoxes with similar interfaces but different
- * functionality. Used to detect failures in BlackBox naming and module
- * deduplication.
- */
-
-class MultiExtModuleTester extends BasicTester {
- val blackBoxInvPos = Module(new extmoduletests.BlackBoxInverter)
- val blackBoxInvNeg = Module(new extmoduletests.BlackBoxInverter)
- val blackBoxPassPos = Module(new extmoduletests.BlackBoxPassthrough)
- val blackBoxPassNeg = Module(new extmoduletests.BlackBoxPassthrough)
-
- blackBoxInvPos.in := 1.U
- blackBoxInvNeg.in := 0.U
- blackBoxPassPos.in := 1.U
- blackBoxPassNeg.in := 0.U
-
- assert(blackBoxInvNeg.out === 1.U)
- assert(blackBoxInvPos.out === 0.U)
- assert(blackBoxPassNeg.out === 0.U)
- assert(blackBoxPassPos.out === 1.U)
- stop()
-}
-
-class ExtModuleWithSuggestName extends ExtModule {
- val in = IO(Input(UInt(8.W)))
- in.suggestName("foo")
- val out = IO(Output(UInt(8.W)))
-}
-
-class ExtModuleWithSuggestNameTester extends Module {
- val in = IO(Input(UInt(8.W)))
- val out = IO(Output(UInt(8.W)))
- val inst = Module(new ExtModuleWithSuggestName)
- inst.in := in
- out := inst.out
-}
-
-class SimpleIOBundle extends Bundle {
- val in = Input(UInt(8.W))
- val out = Output(UInt(8.W))
-}
-
-class ExtModuleWithFlatIO extends ExtModule {
- val badIO = FlatIO(new SimpleIOBundle)
-}
-
-class ExtModuleWithFlatIOTester extends Module {
- val io = IO(new SimpleIOBundle)
- val inst = Module(new ExtModuleWithFlatIO)
- io <> inst.badIO
-}
-
-class ExtModuleInvalidatedTester extends Module {
- val in = IO(Input(UInt(8.W)))
- val out = IO(Output(UInt(8.W)))
- val inst = Module(new ExtModule {
- val in = IO(Input(UInt(8.W)))
- val out = IO(Output(UInt(8.W)))
- })
- inst.in := in
- out := inst.out
-}
-
-class ExtModuleSpec extends ChiselFlatSpec {
- "A ExtModule inverter" should "work" in {
- assertTesterPasses({ new ExtModuleTester }, Seq("/chisel3/BlackBoxTest.v"), TesterDriver.verilatorOnly)
- }
- "Multiple ExtModules" should "work" in {
- assertTesterPasses({ new MultiExtModuleTester }, Seq("/chisel3/BlackBoxTest.v"), TesterDriver.verilatorOnly)
- }
- "DataMirror.modulePorts" should "work with ExtModule" in {
- ChiselStage.elaborate(new Module {
- val io = IO(new Bundle {})
- val m = Module(new extmoduletests.BlackBoxPassthrough)
- assert(DataMirror.modulePorts(m) == Seq("in" -> m.in, "out" -> m.out))
- })
- }
-
- behavior.of("ExtModule")
-
- it should "work with .suggestName (aka it should not require reflection for naming)" in {
- val chirrtl = ChiselStage.emitChirrtl(new ExtModuleWithSuggestNameTester)
- chirrtl should include("input foo : UInt<8>")
- chirrtl should include("inst.foo <= in")
- }
-
- it should "work with FlatIO" in {
- val chirrtl = ChiselStage.emitChirrtl(new ExtModuleWithFlatIOTester)
- chirrtl should include("io.out <= inst.out")
- chirrtl should include("inst.in <= io.in")
- chirrtl shouldNot include("badIO")
- }
-
- it should "not have invalidated ports in a chisel3._ context" in {
- val chirrtl = ChiselStage.emitChirrtl(new ExtModuleInvalidatedTester)
- chirrtl shouldNot include("inst.in is invalid")
- chirrtl shouldNot include("inst.out is invalid")
- }
-}
diff --git a/src/test/scala/chiselTests/ExtModuleImpl.scala b/src/test/scala/chiselTests/ExtModuleImpl.scala
deleted file mode 100644
index bb5c07bf..00000000
--- a/src/test/scala/chiselTests/ExtModuleImpl.scala
+++ /dev/null
@@ -1,159 +0,0 @@
-// See LICENSE for license details.
-
-package chiselTests
-
-import java.io.File
-
-import chisel3._
-import chisel3.experimental.ExtModule
-import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage}
-import chisel3.util.{HasExtModuleInline, HasExtModulePath, HasExtModuleResource}
-import firrtl.options.TargetDirAnnotation
-import firrtl.stage.FirrtlCircuitAnnotation
-import firrtl.transforms.BlackBoxNotFoundException
-import org.scalatest.freespec.AnyFreeSpec
-import org.scalatest.matchers.should.Matchers
-
-//scalastyle:off magic.number
-
-class ExtModuleAdd(n: Int) extends ExtModule with HasExtModuleInline {
- val io = IO(new Bundle {
- val in = Input(UInt(16.W))
- val out = Output(UInt(16.W))
- })
-
- //scalastyle:off regex
- setInline(
- "ExtModuleAdd.v",
- s"""
- |module ExtModuleAdd(
- | input [15:0] in,
- | output [15:0] out
- |);
- | assign out = in + $n;
- |endmodule
- """.stripMargin
- )
-}
-
-class UsesExtModuleAddViaInline extends Module {
- val io = IO(new Bundle {
- val in = Input(UInt(16.W))
- val out = Output(UInt(16.W))
- })
-
- val blackBoxAdd = Module(new ExtModuleAdd(5))
- blackBoxAdd.io.in := io.in
- io.out := blackBoxAdd.io.out
-}
-
-class ExtModuleMinus extends ExtModule with HasExtModuleResource {
- val io = IO(new Bundle {
- val in1 = Input(UInt(16.W))
- val in2 = Input(UInt(16.W))
- val out = Output(UInt(16.W))
- })
- addResource("/chisel3/BlackBoxTest.v")
-}
-
-class ExtModuleMinusPath extends ExtModule with HasExtModulePath {
- val io = IO(new Bundle {
- val in1 = Input(UInt(16.W))
- val in2 = Input(UInt(16.W))
- val out = Output(UInt(16.W))
- })
- addPath(
- new File("src/test/resources/chisel3/BlackBoxTest.v").getCanonicalPath
- )
-}
-
-class UsesExtModuleMinusViaResource extends Module {
- val io = IO(new Bundle {
- val in1 = Input(UInt(16.W))
- val in2 = Input(UInt(16.W))
- val out = Output(UInt(16.W))
- })
-
- val mod0 = Module(new ExtModuleMinus)
-
- mod0.io.in1 := io.in1
- mod0.io.in2 := io.in2
- io.out := mod0.io.out
-}
-
-class UsesExtModuleMinusViaPath extends Module {
- val io = IO(new Bundle {
- val in1 = Input(UInt(16.W))
- val in2 = Input(UInt(16.W))
- val out = Output(UInt(16.W))
- })
-
- val mod0 = Module(new ExtModuleMinusPath)
-
- mod0.io.in1 := io.in1
- mod0.io.in2 := io.in2
- io.out := mod0.io.out
-}
-
-class ExtModuleResourceNotFound extends HasExtModuleResource {
- val io = IO(new Bundle {})
- addResource("/missing.resource")
-}
-
-class UsesMissingExtModuleResource extends RawModule {
- val foo = Module(new ExtModuleResourceNotFound)
-}
-
-class ExtModuleImplSpec extends AnyFreeSpec with Matchers {
- "ExtModule can have verilator source implementation" - {
-
- "Implementations can be contained in-line" in {
- val targetDir = "test_run_dir/extmodule-inline"
-
- val annotations = Seq(
- TargetDirAnnotation(targetDir),
- ChiselGeneratorAnnotation(() => new UsesExtModuleAddViaInline)
- )
- val newAnnotations = (new ChiselStage).transform(annotations)
-
- newAnnotations.exists(_.isInstanceOf[FirrtlCircuitAnnotation]) should be(true)
- val verilogOutput = new File(targetDir, "ExtModuleAdd.v")
- verilogOutput.exists() should be(true)
- verilogOutput.delete()
- }
-
- "Implementations can be contained in resource files" in {
- val targetDir = "test_run_dir/extmodule-resource"
- val annotations = Seq(
- TargetDirAnnotation(targetDir),
- ChiselGeneratorAnnotation(() => new UsesExtModuleMinusViaResource)
- )
- val newAnnotations = (new ChiselStage).transform(annotations)
-
- newAnnotations.exists(_.isInstanceOf[FirrtlCircuitAnnotation]) should be(true)
- val verilogOutput = new File(targetDir, "BlackBoxTest.v")
- verilogOutput.exists() should be(true)
- verilogOutput.delete()
- }
-
- "Implementations can be contained in arbitrary files" in {
- val targetDir = "test_run_dir/extmodule-path"
- val annotations = Seq(
- TargetDirAnnotation(targetDir),
- ChiselGeneratorAnnotation(() => new UsesExtModuleMinusViaPath)
- )
- val newAnnotations = (new ChiselStage).transform(annotations)
-
- newAnnotations.exists(_.isInstanceOf[FirrtlCircuitAnnotation]) should be(true)
- val verilogOutput = new File(targetDir, "BlackBoxTest.v")
- verilogOutput.exists() should be(true)
- verilogOutput.delete()
- }
-
- "Resource files that do not exist produce Chisel errors" in {
- assertThrows[BlackBoxNotFoundException] {
- ChiselStage.emitChirrtl(new UsesMissingExtModuleResource)
- }
- }
- }
-}
diff --git a/src/test/scala/chiselTests/FixedPointSpec.scala b/src/test/scala/chiselTests/FixedPointSpec.scala
deleted file mode 100644
index aedd195e..00000000
--- a/src/test/scala/chiselTests/FixedPointSpec.scala
+++ /dev/null
@@ -1,171 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-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
-import org.scalatest.matchers.should.Matchers
-
-class FixedPointLiteralSpec extends AnyFlatSpec with Matchers {
- behavior.of("fixed point utilities")
-
- they should "allow conversion between doubles and the bigints needed to represent them" in {
- val initialDouble = 0.125
- val bigInt = FixedPoint.toBigInt(initialDouble, 4)
- val finalDouble = FixedPoint.toDouble(bigInt, 4)
-
- initialDouble should be(finalDouble)
- }
-
- they should "have their literals support to double and to BigDecimal" in {
- val d = -7.125
- val lit1 = d.F(3.BP)
- lit1.litToDouble should be(d)
-
- val d2 = BigDecimal("1232123213131123.125")
- val lit2 = d2.F(3.BP)
- lit2.litToBigDecimal should be(d2)
-
- // Numbers that are too big will throw exception
- intercept[ChiselException] {
- lit2.litToDouble
- }
- }
-}
-
-//noinspection TypeAnnotation,EmptyParenMethodAccessedAsParameterless
-class FixedPointFromBitsTester extends BasicTester {
- val uint = 3.U(4.W)
- val sint = (-3).S
-
- val fp = FixedPoint.fromDouble(3.0, 4.W, 0.BP)
- val fp_tpe = FixedPoint(4.W, 1.BP)
- val uint_result = FixedPoint.fromDouble(1.5, 4.W, 1.BP)
- val sint_result = FixedPoint.fromDouble(-1.5, 4.W, 1.BP)
- val fp_result = FixedPoint.fromDouble(1.5, 4.W, 1.BP)
-
- val uint2fp = uint.asTypeOf(fp_tpe)
- val sint2fp = sint.asTypeOf(fp_tpe)
- val fp2fp = fp.asTypeOf(fp_tpe)
-
- val uintToFp = uint.asFixedPoint(1.BP)
- val sintToFp = sint.asFixedPoint(1.BP)
- val fpToFp = fp.asFixedPoint(1.BP)
-
- val negativefp = (-3.5).F(4.BP)
- val positivefp = 3.5.F(4.BP)
-
- assert(-positivefp === negativefp)
- assert(positivefp === -negativefp)
-
- assert(uint2fp === uint_result)
- assert(sint2fp === sint_result)
- assert(fp2fp === fp_result)
-
- assert(uintToFp === uint_result)
- assert(sintToFp === sint_result)
- assert(fpToFp === fp_result)
-
- assert(positivefp.abs() === positivefp)
- assert(negativefp.abs() === positivefp)
- assert(negativefp.abs() =/= negativefp)
-
- val f1bp5 = 1.5.F(1.BP)
- val f6bp0 = 6.0.F(0.BP)
- val f6bp2 = 6.0.F(2.BP)
-
- val f1bp5shiftleft2 = Wire(FixedPoint(Width(), BinaryPoint()))
- val f6bp0shiftright2 = Wire(FixedPoint(Width(), BinaryPoint()))
- val f6bp2shiftright2 = Wire(FixedPoint(Width(), BinaryPoint()))
-
- f1bp5shiftleft2 := f1bp5 << 2
- f6bp0shiftright2 := f6bp0 >> 2
- f6bp2shiftright2 := f6bp2 >> 2
-
- assert(f1bp5shiftleft2 === f6bp0)
- assert(f1bp5shiftleft2 === 6.0.F(8.BP))
-
- // shifting does not move binary point, so in first case below one bit is lost in shift
- assert(f6bp0shiftright2 === 1.0.F(0.BP))
- assert(f6bp2shiftright2 === 1.5.F(2.BP))
-
- stop()
-}
-
-class FixedPointMuxTester extends BasicTester {
- val largeWidthLowPrecision = 6.0.F(4.W, 0.BP)
- val smallWidthHighPrecision = 0.25.F(2.W, 2.BP)
- val unknownWidthLowPrecision = 6.0.F(0.BP)
- val unknownFixed = Wire(FixedPoint())
- unknownFixed := smallWidthHighPrecision
-
- assert(Mux(true.B, largeWidthLowPrecision, smallWidthHighPrecision) === 6.0.F(0.BP))
- assert(Mux(false.B, largeWidthLowPrecision, smallWidthHighPrecision) === 0.25.F(2.BP))
- assert(Mux(false.B, largeWidthLowPrecision, unknownFixed) === 0.25.F(2.BP))
- assert(Mux(true.B, unknownWidthLowPrecision, smallWidthHighPrecision) === 6.0.F(0.BP))
-
- stop()
-}
-
-class SBP extends Module {
- val io = IO(new Bundle {
- val in = Input(FixedPoint(6.W, 2.BP))
- val out = Output(FixedPoint(4.W, 0.BP))
- })
- io.out := io.in.setBinaryPoint(0)
-}
-
-class SBPTester extends BasicTester {
- val dut = Module(new SBP)
- dut.io.in := 3.75.F(2.BP)
-
- assert(dut.io.out === 3.0.F(0.BP))
-
- val test = Wire(FixedPoint(10.W, 5.BP))
- // Initialize test, avoiding a "Reference test is not fully initialized" error from firrtl.
- test := 0.0.F(5.BP)
- val q = test.setBinaryPoint(18)
- assert(q.getWidth.U === 23.U)
-
- stop()
-}
-
-class FixedPointLitExtractTester extends BasicTester {
- assert(-4.75.F(2.BP)(1) === false.B)
- assert(-4.75.F(2.BP)(2) === true.B)
- assert(-4.75.F(2.BP)(100) === true.B)
- assert(-4.75.F(2.BP)(3, 0) === "b1101".U)
- assert(-4.75.F(2.BP)(9, 0) === "b1111101101".U)
-
- assert(-4.75.F(6.W, 2.BP)(1) === false.B)
- assert(-4.75.F(6.W, 2.BP)(2) === true.B)
- assert(-4.75.F(6.W, 2.BP)(100) === true.B)
- assert(-4.75.F(6.W, 2.BP)(3, 0) === "b1101".U)
- assert(-4.75.F(6.W, 2.BP)(9, 0) === "b1111101101".U)
- stop()
-}
-
-class FixedPointSpec extends ChiselPropSpec with Utils {
- property("should allow set binary point") {
- assertTesterPasses { new SBPTester }
- }
- property("should allow fromBits") {
- assertTesterPasses { new FixedPointFromBitsTester }
- }
- property("should mux different widths and binary points") {
- assertTesterPasses { new FixedPointMuxTester }
- }
- property("Negative shift amounts are invalid") {
- 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
deleted file mode 100644
index f03d4e61..00000000
--- a/src/test/scala/chiselTests/GCD.scala
+++ /dev/null
@@ -1,59 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.stage.ChiselStage
-import chisel3.testers.BasicTester
-
-class GCD extends Module {
- val io = IO(new Bundle {
- val a = Input(UInt(32.W))
- val b = Input(UInt(32.W))
- val e = Input(Bool())
- val z = Output(UInt(32.W))
- val v = Output(Bool())
- })
- val x = Reg(UInt(32.W))
- val y = Reg(UInt(32.W))
- when(x > y) { x := x -% y }.otherwise { y := y -% x }
- when(io.e) { x := io.a; y := io.b }
- io.z := x
- io.v := y === 0.U
-}
-
-class GCDTester(a: Int, b: Int, z: Int) extends BasicTester {
- val dut = Module(new GCD)
- val first = RegInit(true.B)
- dut.io.a := a.U
- dut.io.b := b.U
- dut.io.e := first
- when(first) { first := false.B }
- when(!first && dut.io.v) {
- assert(dut.io.z === z.U)
- stop()
- }
-}
-
-class GCDSpec extends ChiselPropSpec {
-
- //TODO: use generators and this function to make z's
- def gcd(a: Int, b: Int): Int = if (b == 0) a else gcd(b, a % b)
-
- val gcds = Table(
- ("a", "b", "z"), // First tuple defines column names
- (64, 48, 16), // Subsequent tuples define the data
- (12, 9, 3),
- (48, 64, 16)
- )
-
- property("GCD should elaborate") {
- ChiselStage.elaborate { new GCD }
- }
-
- property("GCDTester should return the correct result") {
- forAll(gcds) { (a: Int, b: Int, z: Int) =>
- assertTesterPasses { new GCDTester(a, b, z) }
- }
- }
-}
diff --git a/src/test/scala/chiselTests/Harness.scala b/src/test/scala/chiselTests/Harness.scala
deleted file mode 100644
index d4330cd6..00000000
--- a/src/test/scala/chiselTests/Harness.scala
+++ /dev/null
@@ -1,85 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import java.io.File
-
-class HarnessSpec extends ChiselPropSpec {
-
- def makeTrivialVerilog: (File => File) = makeHarness((prefix: String) => s"""
-module ${prefix};
- initial begin
- $$display("$prefix!");
- $$finish;
- end
-endmodule
-""", ".v") _
-
- def makeFailingVerilog: (File => File) = makeHarness(
- (prefix: String) => s"""
-module $prefix;
- initial begin
- assert (1 == 0) else $$error("My specific, expected error message!");
- $$display("$prefix!");
- $$finish;
- end
-endmodule
-""",
- ".v"
- ) _
-
- def makeCppHarness: (File => File) = makeHarness(
- (prefix: String) => s"""
-#include "V$prefix.h"
-#include "verilated.h"
-
-vluint64_t main_time = 0;
-double sc_time_stamp () { return main_time; }
-
-int main(int argc, char **argv, char **env) {
- Verilated::commandArgs(argc, argv);
- V${prefix}* top = new V${prefix};
- while (!Verilated::gotFinish()) { top->eval(); }
- delete top;
- exit(0);
-}
-
-void vl_finish(const char* filename, int linenum, const char* hier) {
- Verilated::flushCall();
- exit(0);
-}
-""",
- ".cpp"
- ) _
-
- /** Compiles a C++ emulator from Verilog and returns the path to the
- * executable and the executable filename as a tuple.
- */
- def simpleHarnessBackend(make: File => File): (File, String) = {
- val target = "test"
- val path = createTestDirectory(target)
- val fname = new File(path, target)
-
- val cppHarness = makeCppHarness(fname)
-
- make(fname)
- verilogToCpp(target, path, Seq(), cppHarness).!
- cppToExe(target, path).!
- (path, target)
- }
-
- property("Test making trivial verilog harness and executing") {
- val (path, target) = simpleHarnessBackend(makeTrivialVerilog)
-
- assert(executeExpectingSuccess(target, path))
- }
-
- property("Test that assertion failues in Verilog are caught") {
- val (path, target) = simpleHarnessBackend(makeFailingVerilog)
-
- assert(!executeExpectingSuccess(target, path))
- assert(executeExpectingFailure(target, path))
- assert(executeExpectingFailure(target, path, "My specific, expected error message!"))
- assert(!executeExpectingFailure(target, path, "A string that doesn't match any test output"))
- }
-}
diff --git a/src/test/scala/chiselTests/IOCompatibility.scala b/src/test/scala/chiselTests/IOCompatibility.scala
deleted file mode 100644
index 3e01a7a5..00000000
--- a/src/test/scala/chiselTests/IOCompatibility.scala
+++ /dev/null
@@ -1,59 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.stage.ChiselStage
-import org.scalatest._
-import org.scalatest.matchers.should.Matchers
-
-class IOCSimpleIO extends Bundle {
- val in = Input(UInt(32.W))
- val out = Output(UInt(32.W))
-}
-
-class IOCPlusOne extends Module {
- val io = IO(new IOCSimpleIO)
- io.out := io.in + 1.U
-}
-
-class IOCModuleVec(val n: Int) extends Module {
- val io = IO(new Bundle {
- val ins = Vec(n, Input(UInt(32.W)))
- val outs = Vec(n, Output(UInt(32.W)))
- })
- val pluses = VecInit(Seq.fill(n) { Module(new IOCPlusOne).io })
- for (i <- 0 until n) {
- pluses(i).in := io.ins(i)
- io.outs(i) := pluses(i).out
- }
-}
-
-class IOCModuleWire extends Module {
- val io = IO(new IOCSimpleIO)
- val inc = Wire(chiselTypeOf(Module(new IOCPlusOne).io))
- inc.in := io.in
- io.out := inc.out
-}
-
-class IOCompatibilitySpec extends ChiselPropSpec with Matchers with Utils {
-
- property("IOCModuleVec should elaborate") {
- ChiselStage.elaborate { new IOCModuleVec(2) }
- }
-
- property("IOCModuleWire should elaborate") {
- ChiselStage.elaborate { new IOCModuleWire }
- }
-
- class IOUnwrapped extends Module {
- val io = new IOCSimpleIO
- io.out := io.in
- }
-
- property("Unwrapped IO should generate an exception") {
- a[BindingException] should be thrownBy extractCause[BindingException] {
- ChiselStage.elaborate(new IOUnwrapped)
- }
- }
-}
diff --git a/src/test/scala/chiselTests/IllegalRefSpec.scala b/src/test/scala/chiselTests/IllegalRefSpec.scala
deleted file mode 100644
index 219df5af..00000000
--- a/src/test/scala/chiselTests/IllegalRefSpec.scala
+++ /dev/null
@@ -1,74 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.stage.ChiselStage
-
-object IllegalRefSpec {
- class IllegalRefInner extends RawModule {
- val io = IO(new Bundle {
- val i = Input(Bool())
- val o = Output(Bool())
- })
- val x = io.i & io.i
- io.o := io.i
- }
-
- class IllegalRefOuter(useConnect: Boolean) extends RawModule {
- val io = IO(new Bundle {
- val a = Input(Bool())
- val b = Input(Bool())
- val out = Output(Bool())
- })
-
- val inst = Module(new IllegalRefInner)
- io.out := inst.io.o
- inst.io.i := io.a
- val x = WireInit(io.b)
- if (useConnect) {
- val z = WireInit(inst.x) // oops
- } else {
- val z = inst.x & inst.x // oops
- }
- }
-
- class CrossWhenConnect(useConnect: Boolean) extends RawModule {
- val io = IO(new Bundle {
- val i = Input(Bool())
- val o = Output(Bool())
- })
- private var tmp: Option[Bool] = None
- when(io.i) {
- val x = io.i & io.i
- tmp = Some(x)
- }
- if (useConnect) {
- io.o := tmp.get
- } else {
- val z = tmp.get & tmp.get
- io.o := io.i
- }
- }
-}
-
-class IllegalRefSpec extends ChiselFlatSpec with Utils {
- import IllegalRefSpec._
-
- val variants = Map("a connect" -> true, "an op" -> false)
-
- variants.foreach {
- case (k, v) =>
- s"Illegal cross-module references in ${k}" should "fail" in {
- a[ChiselException] should be thrownBy extractCause[ChiselException] {
- ChiselStage.elaborate { new IllegalRefOuter(v) }
- }
- }
-
- s"Using a signal that has escaped its enclosing when scope in ${k}" should "fail" in {
- a[ChiselException] should be thrownBy extractCause[ChiselException] {
- ChiselStage.elaborate { new CrossWhenConnect(v) }
- }
- }
- }
-}
diff --git a/src/test/scala/chiselTests/ImplicitConversionsSpec.scala b/src/test/scala/chiselTests/ImplicitConversionsSpec.scala
deleted file mode 100644
index 4bccf636..00000000
--- a/src/test/scala/chiselTests/ImplicitConversionsSpec.scala
+++ /dev/null
@@ -1,48 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-
-class ImplicitConversionsSpec extends ChiselFlatSpec {
- ".data on arbitrary Data objects" should "not work" in {
- assertTypeError("UInt(8.W).data")
- assertTypeError("8.S.data")
- assertTypeError("(new Bundle {}).data")
- assertTypeError("VecInit(1.U).data")
- }
-
- ".target on arbitrary Data objects" should "not work" in {
- assertTypeError("UInt(8.W).target")
- assertTypeError("8.S.target")
- assertTypeError("(new Bundle {}).target")
- assertTypeError("VecInit(1.U).target")
- }
-
- ".x on Strings and Numerical values" should "not work" in {
- assertTypeError("3.x")
- assertTypeError("3L.x")
- assertTypeError("BigInt(-4).x")
- assertTypeError("false.x")
- assertTypeError(""""a".x""")
- }
-
- ".bigint on Strings and Numerical values" should "not work" in {
- assertTypeError("3.bigint")
- assertTypeError("3L.bigint")
- assertTypeError("BigInt(-4).bigint")
- assertTypeError("false.bigint")
- assertTypeError(""""a".bigint""")
- }
-
- ".target on DecoupledIO" should "not work" in {
- 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
- }
- }
-}
diff --git a/src/test/scala/chiselTests/InlineSpec.scala b/src/test/scala/chiselTests/InlineSpec.scala
deleted file mode 100644
index 09a92e45..00000000
--- a/src/test/scala/chiselTests/InlineSpec.scala
+++ /dev/null
@@ -1,96 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage}
-import chisel3.util.experimental.{FlattenInstance, InlineInstance}
-import firrtl.passes.InlineAnnotation
-import firrtl.stage.{FirrtlCircuitAnnotation, FirrtlStage}
-import firrtl.transforms.FlattenAnnotation
-import firrtl.analyses.InstanceGraph
-import firrtl.{ir => fir}
-import org.scalatest.freespec.AnyFreeSpec
-import org.scalatest.matchers.should.Matchers
-
-class InlineSpec extends AnyFreeSpec with ChiselRunners with Matchers {
-
- trait Internals { this: Module =>
- val io = IO(new Bundle { val a = Input(Bool()) })
- }
- class Sub extends Module with Internals
- trait HasSub { this: Module with Internals =>
- val sub = Module(new Sub)
- sub.io.a := io.a
- }
-
- class Foo extends Module with Internals with InlineInstance with HasSub
- class Bar extends Module with Internals with HasSub
- class Baz extends Module with Internals with HasSub
- class Qux extends Module with Internals with HasSub
-
- 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("."))
-
- val chiselStage = new ChiselStage
- val firrtlStage = new FirrtlStage
-
- "Module Inlining" - {
- class Top extends Module with Internals {
- val x = Module(new Foo)
- val y = Module(new Bar with InlineInstance)
- val z = Module(new Bar)
- Seq(x, y, z).map(_.io.a := io.a)
- }
- "should compile to low FIRRTL" - {
- 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")
- }
- }
-
- "Module Flattening" - {
- class Top extends Module with Internals {
- val x = Module(new Qux with FlattenInstance)
- x.io.a := io.a
- }
- "should compile to low FIRRTL" - {
- 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
deleted file mode 100644
index cc5980f4..00000000
--- a/src/test/scala/chiselTests/InstanceNameSpec.scala
+++ /dev/null
@@ -1,62 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.stage.ChiselStage
-import chisel3.util.Queue
-
-class InstanceNameModule extends Module {
- val io = IO(new Bundle {
- val foo = Input(UInt(32.W))
- val bar = Output(UInt(32.W))
- })
- val x = 3.U
- val y = UInt(8.W)
- val z = new Bundle {
- val foo = UInt(8.W)
- }
-
- val q = Module(new Queue(UInt(32.W), 4))
-
- io.bar := io.foo + x
-}
-
-class InstanceNameSpec extends ChiselFlatSpec with Utils {
- behavior.of("instanceName")
- val moduleName = "InstanceNameModule"
- var m: InstanceNameModule = _
- ChiselStage.elaborate { m = new InstanceNameModule; m }
-
- val deprecationMsg = "Accessing the .instanceName or .toTarget of non-hardware Data is deprecated"
-
- it should "work with module IO" in {
- val io = m.io.pathName
- assert(io == moduleName + ".io")
- }
-
- it should "work for literals" in {
- val x = m.x.pathName
- assert(x == moduleName + ".UInt<2>(\"h03\")")
- }
-
- it should "work with non-hardware values (but be deprecated)" in {
- val (ylog, y) = grabLog(m.y.pathName)
- val (zlog, z) = grabLog(m.z.pathName)
- ylog should include(deprecationMsg)
- assert(y == moduleName + ".y")
- zlog should include(deprecationMsg)
- assert(z == moduleName + ".z")
- }
-
- it should "work with non-hardware bundle elements (but be deprecated)" in {
- val (log, foo) = grabLog(m.z.foo.pathName)
- log should include(deprecationMsg)
- assert(foo == moduleName + ".z.foo")
- }
-
- it should "work with modules" in {
- val q = m.q.pathName
- assert(q == moduleName + ".q")
- }
-}
diff --git a/src/test/scala/chiselTests/IntegerMathSpec.scala b/src/test/scala/chiselTests/IntegerMathSpec.scala
deleted file mode 100644
index 166e47bd..00000000
--- a/src/test/scala/chiselTests/IntegerMathSpec.scala
+++ /dev/null
@@ -1,32 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.testers.BasicTester
-
-class IntegerMathTester extends BasicTester {
-
- //TODO: Add more operators
-
- /* absolute values tests */
-
- val uint = 3.U(4.W)
- val sint = (-3).S
- val sintpos = 3.S
- val wrongSIntPos = 4.S
-
- assert(uint.abs() === uint)
- assert(sint.abs() === sintpos)
- assert(sintpos.abs() === sintpos)
-
- assert(sint.abs() =/= wrongSIntPos)
-
- stop()
-}
-
-class IntegerMathSpec extends ChiselPropSpec {
- property("All integer ops should return the correct result") {
- assertTesterPasses { new IntegerMathTester }
- }
-}
diff --git a/src/test/scala/chiselTests/IntervalRangeSpec.scala b/src/test/scala/chiselTests/IntervalRangeSpec.scala
deleted file mode 100644
index 777e08d6..00000000
--- a/src/test/scala/chiselTests/IntervalRangeSpec.scala
+++ /dev/null
@@ -1,237 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.experimental._
-import _root_.firrtl.{ir => firrtlir}
-import chisel3.internal.firrtl.{BinaryPoint, IntervalRange, KnownBinaryPoint, UnknownBinaryPoint}
-import org.scalatest.freespec.AnyFreeSpec
-import org.scalatest.matchers.should.Matchers
-
-class IntervalRangeSpec extends AnyFreeSpec with Matchers {
-
- "IntervalRanges" - {
- def C(b: BigDecimal): firrtlir.Bound = firrtlir.Closed(b)
-
- def O(b: BigDecimal): firrtlir.Bound = firrtlir.Open(b)
-
- def U(): firrtlir.Bound = firrtlir.UnknownBound
-
- def UBP(): BinaryPoint = UnknownBinaryPoint
-
- def checkRange(r: IntervalRange, l: firrtlir.Bound, u: firrtlir.Bound, b: BinaryPoint): Unit = {
- r.lowerBound should be(l)
- r.upperBound should be(u)
- r.binaryPoint should be(b)
- }
-
- def checkBinaryPoint(r: IntervalRange, b: BinaryPoint): Unit = {
- r.binaryPoint should be(b)
- }
-
- "IntervalRange describes the range of values of the Interval Type" - {
- "Factory methods can create IntervalRanges" - {
- "ranges can start or end open or closed, default binary point is none" in {
- checkRange(range"[0,10]", C(0), C(10), 0.BP)
- checkRange(range"[-1,10)", C(-1), O(10), 0.BP)
- checkRange(range"(11,12]", O(11), C(12), 0.BP)
- checkRange(range"(-21,-10)", O(-21), O(-10), 0.BP)
- }
-
- "ranges can have unknown bounds" in {
- checkRange(range"[?,10]", U(), C(10), 0.BP)
- checkRange(range"(?,10]", U(), C(10), 0.BP)
- checkRange(range"[-1,?]", C(-1), U(), 0.BP)
- checkRange(range"[-1,?)", C(-1), U(), 0.BP)
- checkRange(range"[?,?]", U(), U(), 0.BP)
- checkRange(range"[?,?].?", U(), U(), UBP())
- }
-
- "binary points can be specified" in {
- checkBinaryPoint(range"[?,10].0", 0.BP)
- checkBinaryPoint(range"[?,10].2", 2.BP)
- checkBinaryPoint(range"[?,10].?", UBP())
- }
- "malformed ranges will throw ChiselException or are compile time errors" in {
- // must be a cleverer way to show this
- intercept[ChiselException] {
- range"[19,5]"
- }
- assertDoesNotCompile(""" range"?,10] """)
- assertDoesNotCompile(""" range"?,? """)
- }
- }
- }
-
- "Ranges can be specified for UInt, SInt, and FixedPoint" - {
- "invalid range specifiers should fail at compile time" in {
- assertDoesNotCompile(""" range"" """)
- assertDoesNotCompile(""" range"[]" """)
- assertDoesNotCompile(""" range"0" """)
- assertDoesNotCompile(""" range"[0]" """)
- assertDoesNotCompile(""" range"[0, 1" """)
- assertDoesNotCompile(""" range"0, 1]" """)
- assertDoesNotCompile(""" range"[0, 1, 2]" """)
- assertDoesNotCompile(""" range"[a]" """)
- assertDoesNotCompile(""" range"[a, b]" """)
- assertCompiles(""" range"[0, 1]" """) // syntax sanity check
- }
-
- "range macros should allow open and closed bounds" in {
- range"[-1, 1)" should be(range"[-1,1).0")
- range"[-1, 1)" should be(IntervalRange(C(-1), O(1), 0.BP))
- range"[-1, 1]" should be(IntervalRange(C(-1), C(1), 0.BP))
- range"(-1, 1]" should be(IntervalRange(O(-1), C(1), 0.BP))
- range"(-1, 1)" should be(IntervalRange(O(-1), O(1), 0.BP))
- }
-
- "range specifiers should be whitespace tolerant" in {
- range"[-1,1)" should be(IntervalRange(C(-1), O(1), 0.BP))
- range" [-1,1) " should be(IntervalRange(C(-1), O(1), 0.BP))
- range" [ -1 , 1 ) " should be(IntervalRange(C(-1), O(1), 0.BP))
- range" [ -1 , 1 ) " should be(IntervalRange(C(-1), O(1), 0.BP))
- }
-
- "range macros should work with interpolated variables" in {
- val a = 10
- val b = -3
-
- range"[$b, $a)" should be(IntervalRange(C(b), O(a), 0.BP))
- range"[${a + b}, $a)" should be(IntervalRange(C(a + b), O(a), 0.BP))
- range"[${-3 - 7}, ${-3 + a})" should be(IntervalRange(C(-10), O(-3 + a), 0.BP))
-
- def number(n: Int): Int = n
-
- range"[${number(1)}, ${number(3)})" should be(IntervalRange(C(1), O(3), 0.BP))
- }
-
- "UInt should get the correct width from a range" in {
- UInt(range"[0, 8)").getWidth should be(3)
- UInt(range"[0, 8]").getWidth should be(4)
- UInt(range"[0, 0]").getWidth should be(1)
- }
-
- "SInt should get the correct width from a range" in {
- SInt(range"[0, 8)").getWidth should be(4)
- SInt(range"[0, 8]").getWidth should be(5)
- SInt(range"[-4, 4)").getWidth should be(3)
- SInt(range"[0, 0]").getWidth should be(1)
- }
-
- "UInt should check that the range is valid" in {
- an[ChiselException] should be thrownBy {
- UInt(range"[1, 0]")
- }
- an[ChiselException] should be thrownBy {
- UInt(range"[-1, 1]")
- }
- an[ChiselException] should be thrownBy {
- UInt(range"(0,0]")
- }
- an[ChiselException] should be thrownBy {
- UInt(range"[0,0)")
- }
- an[ChiselException] should be thrownBy {
- UInt(range"(0,0)")
- }
- an[ChiselException] should be thrownBy {
- UInt(range"(0,1)")
- }
- }
-
- "SInt should check that the range is valid" in {
- an[ChiselException] should be thrownBy {
- SInt(range"[1, 0]")
- }
- an[ChiselException] should be thrownBy {
- SInt(range"(0,0]")
- }
- an[ChiselException] should be thrownBy {
- SInt(range"[0,0)")
- }
- an[ChiselException] should be thrownBy {
- SInt(range"(0,0)")
- }
- an[ChiselException] should be thrownBy {
- SInt(range"(0,1)")
- }
- }
- }
-
- "shift operations should work on ranges" - {
- "<<, shiftLeft affects the bounds but not the binary point" in {
- checkRange(range"[0,7].1", C(0), C(7), 1.BP)
- checkRange(range"[0,7].1" << 1, C(0), C(14), 1.BP)
-
- checkRange(range"[2,7].2", C(2), C(7), 2.BP)
- checkRange(range"[2,7].2" << 1, C(4), C(14), 2.BP)
- }
-
- ">>, shiftRight affects the bounds but not the binary point" in {
- checkRange(range"[0,7].0", C(0), C(7), 0.BP)
- checkRange(range"[0,7].0" >> 1, C(0), C(3), 0.BP)
-
- checkRange(range"[0,7].1", C(0), C(7), 1.BP)
- checkRange(range"[0,7].1" >> 1, C(0), C(3.5), 1.BP)
-
- checkRange(range"[2,7].2", C(2), C(7), 2.BP)
- checkRange(range"[2,7].2" >> 1, C(1), C(3.5), 2.BP)
-
- checkRange(range"[2,7].2", C(2), C(7), 2.BP)
- checkRange(range"[2,7].2" >> 2, C(0.5), C(1.75), 2.BP)
-
- // the 7(b111) >> 3 => 0.875(b0.111) but since
- // binary point is two, lopping must occur so 0.875 becomes 0.75
- checkRange(range"[-8,7].2", C(-8), C(7), 2.BP)
- checkRange(range"[-8,7].2" >> 3, C(-1), C(0.75), 2.BP)
-
- checkRange(range"(0,7).0", O(0), O(7), 0.BP)
- checkRange(range"(0,7).0" >> 1, O(0), O(3), 0.BP)
-
- checkRange(range"(0,7).1", O(0), O(7), 1.BP)
- checkRange(range"(0,7).1" >> 1, O(0), O(3.5), 1.BP)
-
- checkRange(range"(2,7).2", O(2), O(7), 2.BP)
- checkRange(range"(2,7).2" >> 1, O(1), O(3.5), 2.BP)
-
- checkRange(range"(2,7).2", O(2), O(7), 2.BP)
- checkRange(range"(2,7).2" >> 2, O(0.5), O(1.75), 2.BP)
-
- // the 7(b111) >> 3 => 0.875(b0.111) but since
- // binary point is two, lopping must occur so 0.875 becomes 0.75
- checkRange(range"(-8,7).2", O(-8), O(7), 2.BP)
- checkRange(range"(-8,7).2" >> 3, O(-1), O(0.75), 2.BP)
- }
-
- "set precision can change the bounds due to precision loss, direction of change is always to lower value" in {
- intercept[ChiselException] {
- checkRange(range"[-7.875,7.875].3".setPrecision(UnknownBinaryPoint), C(-7.875), C(7.875), 5.BP)
- }
-
- checkRange(range"[-7.875,7.875].3", C(-7.875), C(7.875), 3.BP)
- checkRange(range"[1.25,2].2".setPrecision(1.BP), C(1.0), C(2), 1.BP)
- checkRange(range"[-7.875,7.875].3".setPrecision(5.BP), C(-7.875), C(7.875), 5.BP)
- checkRange(range"[-7.875,7.875].3".setPrecision(1.BP), C(-8.0), C(7.5), 1.BP)
- }
- }
-
- "get possible values should return all values from high to low" in {
- var range = range"[0,4]"
- range.getLowestPossibleValue should be(Some(0))
- range.getHighestPossibleValue should be(Some(4))
- range.getPossibleValues should be(Seq(0, 1, 2, 3, 4))
-
- range = range"(0,4)"
- range.getLowestPossibleValue should be(Some(1))
- range.getHighestPossibleValue should be(Some(3))
- range.getPossibleValues should be(Seq(1, 2, 3))
-
- range = range"(-1,4).1"
- range.getLowestPossibleValue should be(Some(-0.5))
- range.getHighestPossibleValue should be(Some(3.5))
- range.getPossibleValues should be(Seq(-0.5, 0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5))
- }
- }
-
-}
diff --git a/src/test/scala/chiselTests/IntervalSpec.scala b/src/test/scala/chiselTests/IntervalSpec.scala
deleted file mode 100644
index a2d36579..00000000
--- a/src/test/scala/chiselTests/IntervalSpec.scala
+++ /dev/null
@@ -1,962 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import scala.language.reflectiveCalls
-import _root_.firrtl.ir.{Closed, Open}
-import chisel3._
-import chisel3.internal.firrtl.{IntervalRange, KnownBinaryPoint}
-import chisel3.internal.sourceinfo.{SourceInfo, UnlocatableSourceInfo}
-import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage}
-import chisel3.testers.BasicTester
-import cookbook.CookbookTester
-import firrtl.options.TargetDirAnnotation
-import firrtl.passes.CheckTypes.InvalidConnect
-import firrtl.passes.CheckWidths.{DisjointSqueeze, InvalidRange}
-import firrtl.passes.{PassExceptions, WrapWithRemainder}
-import firrtl.stage.{CompilerAnnotation, FirrtlCircuitAnnotation}
-import firrtl.{
- HighFirrtlCompiler,
- LowFirrtlCompiler,
- MiddleFirrtlCompiler,
- MinimumVerilogCompiler,
- NoneCompiler,
- SystemVerilogCompiler,
- VerilogCompiler
-}
-import org.scalatest.freespec.AnyFreeSpec
-import org.scalatest.matchers.should.Matchers
-
-//noinspection TypeAnnotation
-
-object IntervalTestHelper {
-
- /** Compiles a Chisel Module to Verilog
- * NOTE: This uses the "test_run_dir" as the default directory for generated code.
- * @param compilerName the generator for the module
- * @param gen the generator for the module
- * @return the Verilog code as a string.
- */
- def makeFirrtl[T <: RawModule](compilerName: String)(gen: () => T): String = {
- (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"
- )
- }
-
- }
-}
-
-import chiselTests.IntervalTestHelper.makeFirrtl
-import chisel3.experimental._
-import chisel3.experimental.Interval
-
-class IntervalTest1 extends Module {
- val io = IO(new Bundle {
- val in1 = Input(Interval(range"[0,4]"))
- val in2 = Input(Interval(range"[0,4].3"))
- val out = Output(Interval(range"[0,8].3"))
- })
-
- io.out := io.in1 + io.in2
-}
-
-class IntervalTester extends CookbookTester(10) {
-
- val dut = Module(new IntervalTest1)
-
- dut.io.in1 := BigInt(4).I
- dut.io.in2 := 4.I
- assert(dut.io.out === 8.I)
-
- val i = Interval(range"[0,10)")
- stop()
-}
-
-class IntervalTest2 extends Module {
- val io = IO(new Bundle {
- val p = Input(Bool())
- val in1 = Input(Interval(range"[0,4]"))
- val in2 = Input(Interval(range"[0,6]"))
- val out = Output(Interval())
- })
-
- io.out := Mux(io.p, io.in1, io.in2)
-}
-
-class IntervalTester2 extends CookbookTester(10) {
-
- val dut = Module(new IntervalTest2)
-
- dut.io.p := 1.U
- dut.io.in1 := 4.I
- dut.io.in2 := 5.I
- assert(dut.io.out === 4.I)
-
- stop()
-}
-
-class IntervalAddTester extends BasicTester {
-
- val in1 = Wire(Interval(range"[0,4]"))
- val in2 = Wire(Interval(range"[0,4]"))
-
- in1 := 2.I
- in2 := 2.I
-
- 5.U
-
- val result = in1 +& in2
-
- assert(result === 4.I)
-
- stop()
-
-}
-
-class IntervalSetBinaryPointTester extends BasicTester {
- implicit val sourceinfo: SourceInfo = UnlocatableSourceInfo
- val in1 = Wire(Interval(range"[0,4].4"))
- val in2 = in1.setPrecision(2)
-
- assert(in2.binaryPoint == KnownBinaryPoint(2))
-
- in1 := 2.I
-
- val shiftedLeft = in1.increasePrecision(2)
-
- assert(
- shiftedLeft.binaryPoint == KnownBinaryPoint(6),
- s"Error: increasePrecision result ${shiftedLeft.range} expected bt = 2"
- )
-
- val shiftedRight = in1.decreasePrecision(2)
-
- assert(
- shiftedRight.binaryPoint == KnownBinaryPoint(2),
- s"Error: increasePrecision result ${shiftedRight.range} expected bt = 2"
- )
-
- stop()
-}
-
-class MoreIntervalShiftTester extends BasicTester {
- implicit val sourceinfo: SourceInfo = UnlocatableSourceInfo
-
- val in1 = Wire(Interval(range"[0,4].4"))
- val in2 = in1.setPrecision(2)
-
- assert(in2.binaryPoint == KnownBinaryPoint(2))
-
- val toShiftLeft = Wire(Interval(range"[0,4].4"))
- val shiftedLeft = in1.increasePrecision(2)
-
- assert(
- shiftedLeft.binaryPoint == KnownBinaryPoint(2),
- s"Error: decreasePrecision result ${shiftedLeft.range} expected bt = 2"
- )
-
- val toShiftRight = Wire(Interval(range"[0,4].4"))
- val shiftedRight = in1.decreasePrecision(2)
-
- assert(
- shiftedRight.binaryPoint == KnownBinaryPoint(6),
- s"Error: decreasePrecision result ${shiftedRight.range} expected bt = 2"
- )
-
- stop()
-}
-
-/**
- * This is a reality check not a test. Makes it easier to figure out
- * what is going on in other places
- * @param range a range for inputs
- * @param targetRange a range for outputs
- * @param startNum start here
- * @param endNum end here
- * @param incNum increment by this
- */
-class ClipSqueezeWrapDemo(
- range: IntervalRange,
- targetRange: IntervalRange,
- startNum: Double,
- endNum: Double,
- incNum: Double)
- extends BasicTester {
-
- val binaryPointAsInt = range.binaryPoint.asInstanceOf[KnownBinaryPoint].value
-// val startValue = Interval.fromDouble(startNum, binaryPoint = binaryPointAsInt)
-// val increment = Interval.fromDouble(incNum, binaryPoint = binaryPointAsInt)
-// val endValue = Interval.fromDouble(endNum, binaryPoint = binaryPointAsInt)
- val startValue = startNum.I(range.binaryPoint)
- val increment = incNum.I(range.binaryPoint)
- val endValue = endNum.I(range.binaryPoint)
-
- val counter = RegInit(Interval(range), startValue)
-
- counter := (counter + increment).squeeze(counter)
- when(counter > endValue) {
- stop()
- }
-
- val clipped = counter.clip(0.U.asInterval(targetRange))
- val squeezed = counter.squeeze(0.U.asInterval(targetRange))
- val wrapped = counter.wrap(0.U.asInterval(targetRange))
-
- when(counter === startValue) {
- printf(cf"Target range is $range\n")
- printf("value clip squeeze wrap\n")
- }
-
- printf(
- " %d %d %d %d\n",
- counter.asSInt(),
- clipped.asSInt(),
- squeezed.asSInt(),
- wrapped.asSInt()
- )
-}
-
-class SqueezeFunctionalityTester(range: IntervalRange, startNum: BigDecimal, endNum: BigDecimal, increment: BigDecimal)
- extends BasicTester {
-
- val counter = RegInit(0.U(10.W))
- counter := counter + 1.U
- when(counter > 10.U) {
- stop()
- }
-
- val squeezeInterval = Wire(Interval(range))
- squeezeInterval := 0.I
-
- val squeezeTemplate = Wire(Interval(range))
-
- val ss = WireInit(Interval(range), (-10).S.asInterval(range))
-
- val toSqueeze = counter.asInterval(range) - ss
-
- squeezeTemplate := toSqueeze.squeeze(squeezeInterval)
-
- printf(
- cf"SqueezeTest $counter%d ${toSqueeze.asSInt()}%d.squeeze($range) => ${squeezeTemplate.asSInt()}%d\n"
- )
-}
-
-/**
- * Demonstrate a simple counter register with an Interval type
- */
-class IntervalRegisterTester extends BasicTester {
-
- val range = range"[-2,5]"
- val counter = RegInit(Interval(range), (-1).I)
- counter := (counter + 1.I)
- .squeeze(counter) // this works with other types, why not Interval
- when(counter > 4.I) {
- stop()
- }
-}
-
-//noinspection ScalaStyle
-class IntervalWrapTester extends BasicTester {
-
- val t1 = Wire(Interval(range"[-2, 12]"))
- t1 := (-2).I
- val u1 = 0.U(3.W)
- val r1 = RegInit(u1)
- r1 := u1
- val t2 = t1.wrap(u1)
- val t3 = t1.wrap(r1)
-
- assert(
- t2.range.upper == Closed(7),
- s"t1 upper ${t2.range.upper} expected ${Closed(7)}"
- )
- assert(
- t3.range.upper == Closed(7),
- s"t1 upper ${t3.range.upper} expected ${Closed(7)}"
- )
-
- val in1 = WireInit(Interval(range"[0,9].6"), 0.I)
- val in2 = WireInit(Interval(range"[1,6).4"), 2.I)
- val in3 = in1.wrap(in2)
-
- assert(
- in3.range.lower == Closed(1),
- s"in3 lower ${in3.range.lower} expected ${Closed(1)}"
- )
- assert(
- in3.range.upper == Open(6),
- s"in3 upper ${in3.range.upper} expected ${Open(6)}"
- )
- assert(
- in3.binaryPoint == KnownBinaryPoint(6),
- s"in3 binaryPoint ${in3.binaryPoint} expected ${KnownBinaryPoint(2)}"
- )
-
- val enclosedRange = range"[-2, 5]"
- val base = Wire(Interval(range"[-4, 6]"))
- val enclosed = WireInit(Interval(enclosedRange), 0.I)
- val enclosing = WireInit(Interval(range"[-6, 8]"), 0.I)
- val overlapLeft = WireInit(Interval(range"[-10,-2]"), (-3).I)
- val overlapRight = WireInit(Interval(range"[-1,10]"), 0.I)
-
- val w1 = base.wrap(enclosed)
- val w2 = base.wrap(enclosing)
- val w3 = base.wrap(overlapLeft)
- val w4 = base.wrap(overlapRight)
- val w7 = base.wrap(enclosedRange)
-
- base := 6.I
-
- assert(w1 === (-2).I)
- assert(w2 === 6.I)
- assert(w3 === (-3).I)
- assert(w4 === 6.I)
- assert(w7 === (-2).I)
-
- stop()
-}
-
-class IntervalClipTester extends BasicTester {
-
- val enclosedRange = range"[-2, 5]"
- val base = Wire(Interval(range"[-4, 6]"))
- val enclosed = Wire(Interval(enclosedRange))
- val enclosing = Wire(Interval(range"[-6, 8]"))
- val overlapLeft = Wire(Interval(range"[-10,-2]"))
- val overlapRight = Wire(Interval(range"[-1,10]"))
- val disjointLeft = Wire(Interval(range"[-14,-7]"))
- val disjointRight = Wire(Interval(range"[7,11]"))
-
- enclosed := DontCare
- enclosing := DontCare
- overlapLeft := DontCare
- overlapRight := DontCare
- disjointLeft := DontCare
- disjointRight := DontCare
-
- val enclosedResult = base.clip(enclosed)
- val enclosingResult = base.clip(enclosing)
- val overlapLeftResult = base.clip(overlapLeft)
- val overlapRightResult = base.clip(overlapRight)
- val disjointLeftResult = base.clip(disjointLeft)
- val disjointRightResult = base.clip(disjointRight)
- val enclosedViaRangeString = base.clip(enclosedRange)
-
- base := 6.I
-
- assert(enclosedResult === 5.I)
- assert(enclosingResult === 6.I)
- assert(overlapLeftResult === (-2).I)
- assert(overlapRightResult === 6.I)
- assert(disjointLeftResult === (-7).I)
- assert(disjointRightResult === 7.I)
-
- assert(enclosedViaRangeString === 5.I)
-
- stop()
-}
-
-class IntervalChainedAddTester extends BasicTester {
-
- val intervalResult = Wire(Interval())
- val uintResult = Wire(UInt())
-
- intervalResult := 1.I + 1.I + 1.I + 1.I + 1.I + 1.I + 1.I
- uintResult := 1.U +& 1.U +& 1.U +& 1.U +& 1.U +& 1.U +& 1.U
-
- assert(intervalResult === 7.I)
- assert(uintResult === 7.U)
- stop()
-}
-
-class IntervalChainedMulTester extends BasicTester {
-
- val intervalResult = Wire(Interval())
- val uintResult = Wire(UInt())
-
- intervalResult := 2.I * 2.I * 2.I * 2.I * 2.I * 2.I * 2.I
- uintResult := 2.U * 2.U * 2.U * 2.U * 2.U * 2.U * 2.U
-
- assert(intervalResult === 128.I)
- assert(uintResult === 128.U)
- stop()
-}
-
-class IntervalChainedSubTester extends BasicTester {
- val intervalResult1 = Wire(Interval())
- val intervalResult2 = Wire(Interval())
- val uIntResult = Wire(UInt())
- val sIntResult = Wire(SInt())
- val fixedResult = Wire(FixedPoint())
-
- intervalResult1 := 17.I - 2.I - 2.I - 2.I - 2.I - 2.I - 2.I // gives same result as -& operand version below
- intervalResult2 := 17.I -& 2.I -& 2.I -& 2.I -& 2.I -& 2.I -& 2.I
- uIntResult := 17.U -& 2.U -& 2.U -& 2.U -& 2.U -& 2.U -& 2.U
- fixedResult := 17.0.F(0.BP) -& 2.0.F(0.BP) -& 2.0.F(0.BP) -& 2.0.F(0.BP) -& 2.0
- .F(0.BP) -& 2.0.F(0.BP) -& 2.0.F(0.BP)
- sIntResult := 17.S -& 2.S -& 2.S -& 2.S -& 2.S -& 2.S -& 2.S
-
- assert(uIntResult === 5.U)
- assert(sIntResult === 5.S)
- assert(fixedResult.asUInt === 5.U)
- assert(intervalResult1 === 5.I)
- assert(intervalResult2 === 5.I)
-
- val negativeInterval = (-3.5).I(4.BP)
- val positiveInterval = 3.5.I(4.BP)
-
- assert(negativeInterval =/= positiveInterval)
- assert(-negativeInterval === positiveInterval)
- assert(negativeInterval === -positiveInterval)
-
- stop()
-}
-
-//TODO: need tests for dynamic shifts on intervals
-class IntervalSpec extends AnyFreeSpec with Matchers with ChiselRunners {
-
- type TempFirrtlException = Exception
-
- "Test a simple interval add" in {
- assertTesterPasses { new IntervalAddTester }
- }
- "Intervals can be created" in {
- assertTesterPasses { new IntervalTester }
- }
- "Test a simple interval mux" in {
- assertTesterPasses { new IntervalTester2 }
- }
- "Intervals can have binary points set" in {
- assertTesterPasses { new IntervalSetBinaryPointTester }
- }
- "Interval literals that don't fit in explicit ranges are caught by chisel" - {
- "case 1: does not fit in specified width" in {
- intercept[ChiselException] {
- ChiselGeneratorAnnotation(() =>
- new BasicTester {
- val x = 5.I(3.W, 0.BP)
- }
- ).elaborate
- }
- }
- "case 2: doesn't fit in specified range" in {
- intercept[ChiselException] {
- ChiselGeneratorAnnotation(() =>
- new BasicTester {
- val x = 5.I(range"[0,4]")
- }
- ).elaborate
- }
- }
- }
-
- "Interval literals support to double and to BigDecimal" in {
- val d = -7.125
- val lit1 = d.I(3.BP)
- lit1.litToDouble should be(d)
-
- val d2 = BigDecimal("1232123213131123.125")
- val lit2 = d2.I(3.BP)
- lit2.litToBigDecimal should be(d2)
-
- // Numbers that are too big will throw exception
- intercept[ChiselException] {
- lit2.litToDouble
- }
- }
-
- "Interval literals creation handles edge cases" - {
- "value at closed boundaries works" in {
- val inputRange = range"[-6, 6].2"
- val in1 = (-6.0).I(inputRange)
- val in2 = 6.0.I(inputRange)
- BigDecimal(in1.litValue()) / (1 << inputRange.binaryPoint.get) should be(-6)
- BigDecimal(in2.litValue()) / (1 << inputRange.binaryPoint.get) should be(6)
- intercept[ChiselException] {
- (-6.25).I(inputRange)
- }
- intercept[ChiselException] {
- (6.25).I(inputRange)
- }
- }
- "value at open boundaries works" in {
- val inputRange = range"(-6, 6).2"
- val in1 = (-5.75).I(inputRange)
- val in2 = 5.75.I(inputRange)
- BigDecimal(in1.litValue()) / (1 << inputRange.binaryPoint.get) should be(-5.75)
- BigDecimal(in2.litValue()) / (1 << inputRange.binaryPoint.get) should be(5.75)
- intercept[ChiselException] {
- (-6.0).I(inputRange)
- }
- intercept[ChiselException] {
- (6.0).I(inputRange)
- }
- }
- "values not precisely at open boundaries works but are converted to nearest match" in {
- val inputRange = range"(-6, 6).2"
- val in1 = (-5.95).I(inputRange)
- val in2 = 5.95.I(inputRange)
- BigDecimal(in1.litValue()) / (1 << inputRange.binaryPoint.get) should be(-5.75)
- BigDecimal(in2.litValue()) / (1 << inputRange.binaryPoint.get) should be(5.75)
- intercept[ChiselException] {
- (-6.1).I(inputRange)
- }
- intercept[ChiselException] {
- (6.1).I(inputRange)
- }
- }
- }
-
- "Let's take a look at the results of squeeze over small range" in {
- assertTesterPasses {
- new ClipSqueezeWrapDemo(
- range = range"[-10,33].0",
- targetRange = range"[-4,17].0",
- startNum = -4.0,
- endNum = 30.0,
- incNum = 1.0
- )
- }
- assertTesterPasses {
- new ClipSqueezeWrapDemo(
- range = range"[-2,5].1",
- targetRange = range"[-1,3].1",
- startNum = -2.0,
- endNum = 5.0,
- incNum = 0.5
- )
- }
- }
- "Intervals can be squeezed into another intervals range" in {
- assertTesterPasses {
- new SqueezeFunctionalityTester(
- range"[-2,5]",
- BigDecimal(-10),
- BigDecimal(10),
- BigDecimal(1.0)
- )
- }
- }
- "Intervals can be wrapped with wrap operator" in {
- assertTesterPasses { new IntervalWrapTester }
- }
-
- "Interval compile pathologies: clip, wrap, and squeeze have different behavior" - {
- "wrap target range is completely left of source" in {
- intercept[TempFirrtlException] {
- assertTesterPasses(new BasicTester {
- val base = Wire(Interval(range"[-4, 6]"))
- base := 6.I
- val disjointLeft = WireInit(Interval(range"[-7,-5]"), (-6).I)
- val w5 = base.wrap(disjointLeft)
- stop()
- })
- }
- }
- "wrap target range is completely right of source" in {
- intercept[TempFirrtlException] {
- assertTesterPasses(new BasicTester {
- val base = Wire(Interval(range"[-4, 6]"))
- base := 6.I
- val disjointLeft = WireInit(Interval(range"[7,10]"), 8.I)
- val w5 = base.wrap(disjointLeft)
- stop()
- })
- }
- }
- "clip target range is completely left of source" in {
- assertTesterPasses(new BasicTester {
- val base = Wire(Interval(range"[-4, 6]"))
- base := 6.I
- val disjointLeft = WireInit(Interval(range"[-7,-5]"), (-6).I)
- val w5 = base.clip(disjointLeft)
- chisel3.assert(w5 === (-5).I)
- stop()
- })
- }
- "clip target range is completely right of source" in {
- assertTesterPasses(new BasicTester {
- val base = Wire(Interval(range"[-4, 6]"))
- base := 6.I
- val disjointLeft = WireInit(Interval(range"[7,10]"), 8.I)
- val w5 = base.clip(disjointLeft)
- chisel3.assert(w5.asSInt === 7.S)
- stop()
- })
- }
- "squeeze target range is completely right of source" in {
- intercept[TempFirrtlException] {
- assertTesterPasses(new BasicTester {
- val base = Wire(Interval(range"[-4, 6]"))
- base := 6.I
- val disjointLeft = WireInit(Interval(range"[7,10]"), 8.I)
- val w5 = base.squeeze(disjointLeft)
- chisel3.assert(w5.asSInt === 6.S)
- stop()
- })
- }
- }
- "squeeze target range is completely left of source" in {
- intercept[TempFirrtlException] {
- assertTesterPasses(new BasicTester {
- val base = Wire(Interval(range"[-4, 6]"))
- base := 6.I
- val disjointLeft = WireInit(Interval(range"[-7, -5]"), 8.I)
- val w5 = base.squeeze(disjointLeft)
- stop()
- })
- }
- }
-
- def makeCircuit(operation: String, sourceRange: IntervalRange, targetRange: IntervalRange): () => RawModule = {
- () =>
- new Module {
- val io = IO(new Bundle { val out = Output(Interval()) })
- val base = Wire(Interval(sourceRange))
- base := 6.I
-
- val disjointLeft = WireInit(Interval(targetRange), 8.I)
- val w5 = operation match {
- case "clip" => base.clip(disjointLeft)
- case "wrap" => base.wrap(disjointLeft)
- case "squeeze" => base.squeeze(disjointLeft)
- }
- io.out := w5
- }
- }
-
- "disjoint ranges should error when used with clip, wrap and squeeze" - {
-
- def mustGetException(disjointLeft: Boolean, operation: String): Boolean = {
- val (rangeA, rangeB) = if (disjointLeft) {
- (range"[-4, 6]", range"[7,10]")
- } else {
- (range"[7,10]", range"[-4, 6]")
- }
- try {
- makeFirrtl("low")(makeCircuit(operation, rangeA, rangeB))
- false
- } catch {
- case _: InvalidConnect | _: PassExceptions | _: InvalidRange | _: WrapWithRemainder | _: DisjointSqueeze =>
- true
- case _: Throwable =>
- false
- }
- }
-
- "Range A disjoint left, operation clip should generate useful error" in {
- mustGetException(disjointLeft = true, "clip") should be(false)
- }
- "Range A largely out of bounds left, operation wrap should generate useful error" in {
- mustGetException(disjointLeft = true, "wrap") should be(true)
- }
- "Range A disjoint left, operation squeeze should generate useful error" in {
- mustGetException(disjointLeft = true, "squeeze") should be(true)
- }
- "Range A disjoint right, operation clip should generate useful error" in {
- mustGetException(disjointLeft = false, "clip") should be(true)
- }
- "Range A disjoint right, operation wrap should generate useful error" in {
- mustGetException(disjointLeft = false, "wrap") should be(true)
- }
- "Range A disjoint right, operation squeeze should generate useful error" in {
- mustGetException(disjointLeft = false, "squeeze") should be(true)
- }
- }
-
- "Errors are sometimes inconsistent or incorrectly labelled as Firrtl Internal Error" - {
- "squeeze disjoint is not internal error when defined in BasicTester" in {
- intercept[DisjointSqueeze] {
- makeFirrtl("low")(() =>
- new BasicTester {
- val base = Wire(Interval(range"[-4, 6]"))
- val base2 = Wire(Interval(range"[-4, 6]"))
- base := 6.I
- base2 := 5.I
- val disjointLeft = WireInit(Interval(range"[7,10]"), 8.I)
- val w5 = base.squeeze(disjointLeft)
- stop()
- }
- )
- }
- }
- "wrap disjoint is not internal error when defined in BasicTester" in {
- intercept[DisjointSqueeze] {
- makeFirrtl("low")(() =>
- new BasicTester {
- val base = Wire(Interval(range"[-4, 6]"))
- val base2 = Wire(Interval(range"[-4, 6]"))
- base := 6.I
- base2 := 5.I
- val disjointLeft = WireInit(Interval(range"[7,10]"), 8.I)
- val w5 = base.squeeze(disjointLeft)
- stop()
- }
- )
- }
- }
- "squeeze disjoint from Module gives exception" in {
- intercept[DisjointSqueeze] {
- makeFirrtl("low")(() =>
- new Module {
- val io = IO(new Bundle {
- val out = Output(Interval())
- })
- val base = Wire(Interval(range"[-4, 6]"))
- base := 6.I
-
- val disjointLeft = WireInit(Interval(range"[7,10]"), 8.I)
- val w5 = base.squeeze(disjointLeft)
- io.out := w5
- }
- )
- }
- }
- "clip disjoint from Module gives no error" in {
- makeFirrtl("low")(() =>
- new Module {
- val io = IO(new Bundle {
- val out = Output(Interval())
- })
- val base = Wire(Interval(range"[-4, 6]"))
- base := 6.I
-
- val disjointLeft = WireInit(Interval(range"[7,10]"), 8.I)
- val w5 = base.clip(disjointLeft)
- io.out := w5
- }
- )
- }
- "wrap disjoint from Module wrap with remainder" in {
- intercept[WrapWithRemainder] {
- makeFirrtl("low")(() =>
- new Module {
- val io = IO(new Bundle {
- val out = Output(Interval())
- })
- val base = Wire(Interval(range"[-4, 6]"))
- base := 6.I
-
- val disjointLeft = WireInit(Interval(range"[7,10]"), 8.I)
- val w5 = base.wrap(disjointLeft)
- io.out := w5
- }
- )
- }
- }
- }
-
- "assign literal out of range of interval" in {
- intercept[firrtl.passes.CheckTypes.InvalidConnect] {
- assertTesterPasses(new BasicTester {
- val base = Wire(Interval(range"[-4, 6]"))
- base := (-8).I
- })
- }
- }
- }
-
- "Intervals should catch assignment of literals outside of range" - {
- "when literal is too small" in {
- intercept[InvalidConnect] {
- makeFirrtl("low")(() =>
- new Module {
- val io = IO(new Bundle { val out = Output(Interval()) })
- val base = Wire(Interval(range"[-4, 6]"))
- base := (-7).I
- io.out := base
- }
- )
- }
- }
- "when literal is too big" in {
- intercept[InvalidConnect] {
- makeFirrtl("low")(() =>
- new Module {
- val io = IO(new Bundle { val out = Output(Interval()) })
- val base = Wire(Interval(range"[-4, 6]"))
- base := 9.I
- io.out := base
- }
- )
- }
- }
- }
-
- "Intervals can be shifted left" in {
- assertTesterPasses(new BasicTester {
- val i1 = 3.0.I(range"[0,4]")
- val shifted1 = i1 << 2
- val shiftUInt = WireInit(1.U(8.W))
- val shifted2 = i1 << shiftUInt
-
- chisel3.assert(shifted1 === 12.I, "shifted 1 should be 12, it wasn't")
- chisel3.assert(shifted2 === 6.I, "shifted 2 should be 6 it wasn't")
- stop()
- })
- }
-
- "Intervals can be shifted right" in {
- assertTesterPasses(new BasicTester {
- val i1 = 12.0.I(range"[0,15]")
- val shifted1 = i1 >> 2
- val shiftUInt = 1.U
- val shifted2 = i1 >> shiftUInt
-
- chisel3.assert(shifted1 === 3.I)
- chisel3.assert(shifted2 === 6.I)
- stop()
- })
- }
-
- "Intervals can be used to construct registers" in {
- assertTesterPasses { new IntervalRegisterTester }
- }
- "Intervals can be clipped with clip (saturate) operator" in {
- assertTesterPasses { new IntervalClipTester }
- }
- "Intervals adds same answer as UInt" in {
- assertTesterPasses { new IntervalChainedAddTester }
- }
- "Intervals should produce canonically smaller ranges via inference" in {
- val loFirrtl = makeFirrtl("low")(() =>
- new Module {
- val io = IO(new Bundle {
- val in = Input(Interval(range"[0,1]"))
- val out = Output(Interval())
- })
-
- val intervalResult = Wire(Interval())
-
- intervalResult := 1.I + 1.I + 1.I + 1.I + 1.I + 1.I + 1.I
- io.out := intervalResult
- }
- )
- loFirrtl.contains("output io_out : SInt<4>") should be(true)
-
- }
- "Intervals multiplication same answer as UInt" in {
- assertTesterPasses { new IntervalChainedMulTester }
- }
- "Intervals subs same answer as UInt" in {
- assertTesterPasses { new IntervalChainedSubTester }
- }
- "Test clip, wrap and a variety of ranges" - {
- """range"[0.0,10.0].2" => range"[2,6].2"""" in {
- assertTesterPasses(new BasicTester {
-
- val sourceRange = range"[0.0,10.0].2"
- val targetRange = range"[2,6].2"
-
- val sourceSimulator = ScalaIntervalSimulator(sourceRange)
- val targetSimulator = ScalaIntervalSimulator(targetRange)
-
- for (sourceValue <- sourceSimulator.allValues) {
- val clippedValue = Wire(Interval(targetRange))
- clippedValue := sourceSimulator
- .makeLit(sourceValue)
- .clip(clippedValue)
-
- val goldClippedValue =
- targetSimulator.makeLit(targetSimulator.clip(sourceValue))
-
- // Useful for debugging
- // printf(s"source value $sourceValue clipped gold value %d compare to clipped value %d\n",
- // goldClippedValue.asSInt(), clippedValue.asSInt())
-
- chisel3.assert(goldClippedValue === clippedValue)
-
- val wrappedValue = Wire(Interval(targetRange))
- wrappedValue := sourceSimulator
- .makeLit(sourceValue)
- .wrap(wrappedValue)
-
- val goldWrappedValue =
- targetSimulator.makeLit(targetSimulator.wrap(sourceValue))
-
- // Useful for debugging
- // printf(s"source value $sourceValue wrapped gold value %d compare to wrapped value %d\n",
- // goldWrappedValue.asSInt(), wrappedValue.asSInt())
-
- chisel3.assert(goldWrappedValue === wrappedValue)
- }
-
- stop()
- })
- }
- }
-
- "Test squeeze over a variety of ranges" - {
- """range"[2,6].2""" in {
- assertTesterPasses(new BasicTester {
-
- val sourceRange = range"[0.0,10.0].2"
- val targetRange = range"[2,6].3"
-
- val sourceSimulator = ScalaIntervalSimulator(sourceRange)
- val targetSimulator = ScalaIntervalSimulator(targetRange)
-
- for (sourceValue <- sourceSimulator.allValues) {
- val squeezedValue = Wire(Interval(targetRange))
- squeezedValue := sourceSimulator
- .makeLit(sourceValue)
- .clip(squeezedValue)
-
- val goldSqueezedValue =
- targetSimulator.makeLit(targetSimulator.clip(sourceValue))
-
- // Useful for debugging
- // printf(s"source value $sourceValue squeezed gold value %d compare to squeezed value %d\n",
- // goldSqueezedValue.asSInt(), squeezedValue.asSInt())
-
- chisel3.assert(goldSqueezedValue === squeezedValue)
- }
-
- stop()
- })
- }
- }
-
- "test asInterval" - {
- "use with UInt" in {
- assertTesterPasses(new BasicTester {
- val u1 = Wire(UInt(5.W))
- u1 := 7.U
- val i1 = u1.asInterval(range"[0,15]")
- val i2 = u1.asInterval(range"[0,15].2")
- printf("i1 %d\n", i1.asUInt)
- chisel3.assert(i1 === 7.I, "i1")
- stop()
- })
- }
- "use with SInt" in {
- assertTesterPasses(new BasicTester {
- val s1 = Wire(SInt(5.W))
- s1 := 7.S
- val s2 = Wire(SInt(5.W))
- s2 := 7.S
- val i1 = s1.asInterval(range"[-16,15]")
- val i2 = s1.asInterval(range"[-16,15].1")
- printf("i1 %d\n", i1.asSInt)
- printf("i2 %d\n", i2.asSInt)
- chisel3.assert(i1 === 7.I, "i1 is wrong")
- chisel3.assert(i2 === (3.5).I(binaryPoint = 1.BP), "i2 is wrong")
- stop()
- })
- }
- "more SInt tests" in {
- assertTesterPasses(new BasicTester {
- chisel3.assert(7.S.asInterval(range"[-16,15].1") === 3.5.I(binaryPoint = 1.BP), "adding binary point")
- stop()
- })
- }
- }
-}
diff --git a/src/test/scala/chiselTests/InvalidateAPISpec.scala b/src/test/scala/chiselTests/InvalidateAPISpec.scala
deleted file mode 100644
index dbd353a0..00000000
--- a/src/test/scala/chiselTests/InvalidateAPISpec.scala
+++ /dev/null
@@ -1,239 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-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 with Utils {
-
- def myGenerateFirrtl(t: => Module): String = ChiselStage.emitChirrtl(t)
- def compileFirrtl(t: => Module): Unit = {
- val testDir = createTestDirectory(this.getClass.getSimpleName)
-
- (new ChiselStage).execute(
- Array[String]("-td", testDir.getAbsolutePath, "--compiler", "verilog"),
- Seq(ChiselGeneratorAnnotation(() => t))
- )
- }
- class TrivialInterface extends Bundle {
- val in = Input(Bool())
- val out = Output(Bool())
- }
-
- property("an output connected to DontCare should emit a Firrtl \"is invalid\" with Strict CompileOptions") {
- import chisel3.ExplicitCompileOptions.Strict
- class ModuleWithDontCare extends Module {
- val io = IO(new TrivialInterface)
- io.out := DontCare
- io.out := io.in
- }
- val firrtlOutput = myGenerateFirrtl(new ModuleWithDontCare)
- firrtlOutput should include("io.out is invalid")
- }
-
- property("an output without a DontCare should NOT emit a Firrtl \"is invalid\" with Strict CompileOptions") {
- import chisel3.ExplicitCompileOptions.Strict
- class ModuleWithoutDontCare extends Module {
- val io = IO(new TrivialInterface)
- io.out := io.in
- }
- val firrtlOutput = myGenerateFirrtl(new ModuleWithoutDontCare)
- (firrtlOutput should not).include("is invalid")
- }
-
- property("an output without a DontCare should emit a Firrtl \"is invalid\" with NotStrict CompileOptions") {
- import chisel3.ExplicitCompileOptions.NotStrict
- class ModuleWithoutDontCare extends Module {
- val io = IO(new TrivialInterface)
- io.out := io.in
- }
- val firrtlOutput = myGenerateFirrtl(new ModuleWithoutDontCare)
- firrtlOutput should include("io is invalid")
- }
-
- property("a bundle with a DontCare should emit a Firrtl \"is invalid\" with Strict CompileOptions") {
- import chisel3.ExplicitCompileOptions.Strict
- class ModuleWithoutDontCare extends Module {
- val io = IO(new TrivialInterface)
- io <> DontCare
- }
- val firrtlOutput = myGenerateFirrtl(new ModuleWithoutDontCare)
- firrtlOutput should include("io.out is invalid")
- firrtlOutput should include("io.in is invalid")
- }
-
- property("a Vec with a DontCare should emit a Firrtl \"is invalid\" with Strict CompileOptions and bulk connect") {
- import chisel3.ExplicitCompileOptions.Strict
- val nElements = 5
- class ModuleWithoutDontCare extends Module {
- val io = IO(new Bundle {
- val outs = Output(Vec(nElements, Bool()))
- })
- io.outs <> DontCare
- }
- val firrtlOutput = myGenerateFirrtl(new ModuleWithoutDontCare)
- for (i <- 0 until nElements)
- firrtlOutput should include(s"io.outs[$i] is invalid")
- }
-
- property("a Vec with a DontCare should emit a Firrtl \"is invalid\" with Strict CompileOptions and mono connect") {
- import chisel3.ExplicitCompileOptions.Strict
- val nElements = 5
- class ModuleWithoutDontCare extends Module {
- val io = IO(new Bundle {
- val ins = Input(Vec(nElements, Bool()))
- })
- io.ins := DontCare
- }
- val firrtlOutput = myGenerateFirrtl(new ModuleWithoutDontCare)
- for (i <- 0 until nElements)
- firrtlOutput should include(s"io.ins[$i] is invalid")
- }
-
- property("a DontCare cannot be a connection sink (LHS) for := ") {
- import chisel3.ExplicitCompileOptions.Strict
- class ModuleWithDontCareSink extends Module {
- val io = IO(new TrivialInterface)
- DontCare := io.in
- }
- val exception = intercept[ChiselException] {
- extractCause[ChiselException] {
- ChiselStage.elaborate(new ModuleWithDontCareSink)
- }
- }
- exception.getMessage should include("DontCare cannot be a connection sink")
- }
-
- property("a DontCare cannot be a connection sink (LHS) for <>") {
- import chisel3.ExplicitCompileOptions.Strict
- class ModuleWithDontCareSink extends Module {
- val io = IO(new TrivialInterface)
- DontCare <> io.in
- }
- val exception = intercept[BiConnectException] {
- extractCause[BiConnectException] {
- ChiselStage.elaborate(new ModuleWithDontCareSink)
- }
- }
- exception.getMessage should include("DontCare cannot be a connection sink (LHS)")
- }
-
- property("FIRRTL should complain about partial initialization with Strict CompileOptions and conditional connect") {
- import chisel3.ExplicitCompileOptions.Strict
- class ModuleWithIncompleteAssignment extends Module {
- val io = IO(new Bundle {
- val out = Output(Bool())
- })
- val counter = Counter(8)
- when(counter.inc()) {
- io.out := true.B
- }
- }
- val exception = intercept[RefNotInitializedException] {
- compileFirrtl(new ModuleWithIncompleteAssignment)
- }
- exception.getMessage should include("is not fully initialized")
- }
-
- property(
- "FIRRTL should not complain about partial initialization with Strict CompileOptions and conditional connect after unconditional connect"
- ) {
- import chisel3.ExplicitCompileOptions.Strict
- class ModuleWithUnconditionalAssignment extends Module {
- val io = IO(new Bundle {
- val out = Output(Bool())
- })
- val counter = Counter(8)
- io.out := false.B
- when(counter.inc()) {
- io.out := true.B
- }
- }
- compileFirrtl(new ModuleWithUnconditionalAssignment)
- }
-
- property(
- "FIRRTL should not complain about partial initialization with Strict CompileOptions and conditional connect with otherwise clause"
- ) {
- import chisel3.ExplicitCompileOptions.Strict
- class ModuleWithConditionalAndOtherwiseAssignment extends Module {
- val io = IO(new Bundle {
- val out = Output(Bool())
- })
- val counter = Counter(8)
- when(counter.inc()) {
- io.out := true.B
- }.otherwise {
- io.out := false.B
- }
- }
-
- compileFirrtl(new ModuleWithConditionalAndOtherwiseAssignment)
- }
-
- property(
- "an output without a DontCare should NOT emit a Firrtl \"is invalid\" with overriden NotStrict CompileOptions"
- ) {
- import chisel3.ExplicitCompileOptions.NotStrict
- class ModuleWithoutDontCare extends Module {
- override val compileOptions = chisel3.ExplicitCompileOptions.NotStrict.copy(explicitInvalidate = true)
- val io = IO(new TrivialInterface)
- io.out := io.in
- }
- val firrtlOutput = myGenerateFirrtl(new ModuleWithoutDontCare)
- (firrtlOutput should not).include("is invalid")
- }
-
- property(
- "an output without a DontCare should NOT emit a Firrtl \"is invalid\" with overriden NotStrict CompileOptions module definition"
- ) {
- import chisel3.ExplicitCompileOptions.NotStrict
- abstract class ExplicitInvalidateModule
- extends Module()(chisel3.ExplicitCompileOptions.NotStrict.copy(explicitInvalidate = true))
- class ModuleWithoutDontCare extends ExplicitInvalidateModule {
- val io = IO(new TrivialInterface)
- io.out := io.in
- }
- val firrtlOutput = myGenerateFirrtl(new ModuleWithoutDontCare)
- (firrtlOutput should not).include("is invalid")
- }
-
- property("an output without a DontCare should emit a Firrtl \"is invalid\" with overriden Strict CompileOptions") {
- import chisel3.ExplicitCompileOptions.Strict
- class ModuleWithoutDontCare extends Module {
- override val compileOptions = chisel3.ExplicitCompileOptions.Strict.copy(explicitInvalidate = false)
- val io = IO(new TrivialInterface)
- io.out := io.in
- }
- val firrtlOutput = myGenerateFirrtl(new ModuleWithoutDontCare)
- firrtlOutput should include("is invalid")
- }
-
- property(
- "an output without a DontCare should emit a Firrtl \"is invalid\" with overriden Strict CompileOptions module definition"
- ) {
- import chisel3.ExplicitCompileOptions.Strict
- abstract class ImplicitInvalidateModule
- extends Module()(chisel3.ExplicitCompileOptions.NotStrict.copy(explicitInvalidate = false))
- class ModuleWithoutDontCare extends ImplicitInvalidateModule {
- val io = IO(new TrivialInterface)
- io.out := io.in
- }
- val firrtlOutput = myGenerateFirrtl(new ModuleWithoutDontCare)
- firrtlOutput should include("is invalid")
- }
-
- property("a clock should be able to be connected to a DontCare") {
- class ClockConnectedToDontCare extends Module {
- val foo = IO(Output(Clock()))
- foo := DontCare
- }
- myGenerateFirrtl(new ClockConnectedToDontCare) should include("foo is invalid")
- }
-}
diff --git a/src/test/scala/chiselTests/LiteralExtractorSpec.scala b/src/test/scala/chiselTests/LiteralExtractorSpec.scala
deleted file mode 100644
index 3906057f..00000000
--- a/src/test/scala/chiselTests/LiteralExtractorSpec.scala
+++ /dev/null
@@ -1,158 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.experimental._
-import chisel3.experimental.BundleLiterals._
-import chisel3.stage.ChiselStage
-import chisel3.testers.BasicTester
-import scala.collection.immutable.ListMap
-
-class LiteralExtractorSpec extends ChiselFlatSpec {
- "litValue" should "return the literal value" in {
- assert(0.U.litValue === BigInt(0))
- assert(1.U.litValue === BigInt(1))
- assert(42.U.litValue === BigInt(42))
- assert(42.U.litValue === 42.U.litValue)
-
- assert(0.S.litValue === BigInt(0))
- assert(-1.S.litValue === BigInt(-1))
- assert(-42.S.litValue === BigInt(-42))
-
- assert(true.B.litValue === BigInt(1))
- assert(false.B.litValue === BigInt(0))
-
- assert(1.25.F(2.BP).litValue === BigInt("101", 2))
- assert(2.25.F(2.BP).litValue === BigInt("1001", 2))
-
- assert(-1.25.F(2.BP).litValue === BigInt("-101", 2))
- assert(-2.25.F(2.BP).litValue === BigInt("-1001", 2))
- }
-
- "litToBoolean" should "return the literal value" in {
- assert(true.B.litToBoolean === true)
- assert(false.B.litToBoolean === false)
-
- assert(1.B.litToBoolean === true)
- assert(0.B.litToBoolean === false)
- }
-
- "litToDouble" should "return the literal value" in {
- assert(1.25.F(2.BP).litToDouble == 1.25)
- assert(2.25.F(2.BP).litToDouble == 2.25)
-
- assert(-1.25.F(2.BP).litToDouble == -1.25)
- assert(-2.25.F(2.BP).litToDouble == -2.25)
-
- // test rounding
- assert(1.24.F(1.BP).litToDouble == 1.0)
- assert(1.25.F(1.BP).litToDouble == 1.5)
- }
-
- "litOption" should "return None for non-literal hardware" in {
- ChiselStage.elaborate {
- new RawModule {
- val a = Wire(UInt())
- assert(a.litOption == None)
- }
- }
- }
-
- "doubles and big decimals" should "round trip properly" in {
- intercept[ChiselException] {
- Num.toBigDecimal(BigInt("1" * 109, 2), 0.BP) // this only works if number takes less than 109 bits
- }
-
- intercept[ChiselException] {
- Num.toDouble(BigInt("1" * 54, 2), 0.BP) // this only works if number takes less than 54 bits
- }
-
- val bigInt108 = BigInt("1" * 108, 2)
- val bigDecimal = Num.toBigDecimal(bigInt108, 2)
-
- val bigIntFromBigDecimal = Num.toBigInt(bigDecimal, 2)
-
- bigIntFromBigDecimal should be(bigInt108)
-
- val bigInt53 = BigInt("1" * 53, 2)
-
- val double = Num.toDouble(bigInt53, 2)
-
- val bigIntFromDouble = Num.toBigInt(double, 2)
-
- bigIntFromDouble should be(bigInt53)
- }
-
- "encoding and decoding of Intervals" should "round trip" in {
- val rangeMin = BigDecimal(-31.5)
- val rangeMax = BigDecimal(32.5)
- val range = range"($rangeMin, $rangeMax).2"
- for (value <- (rangeMin - 4) to (rangeMax + 4) by 2.25) {
- if (value < rangeMin || value > rangeMax) {
- intercept[ChiselException] {
- val literal = value.I(range)
- }
- } else {
- val literal = value.I(range)
- literal.isLit() should be(true)
- literal.litValue().toDouble / 4.0 should be(value)
- }
- }
- }
-
- "literals declared outside a builder context" should "compare with those inside builder context" in {
- class InsideBundle extends Bundle {
- val x = SInt(8.W)
- val y = FixedPoint(8.W, 4.BP)
- }
-
- class LitInsideOutsideTester(outsideLiteral: InsideBundle) extends BasicTester {
- val insideLiteral = (new InsideBundle).Lit(_.x -> 7.S, _.y -> 6.125.F(4.BP))
-
- // the following errors with "assertion failed"
-
- println(outsideLiteral === insideLiteral)
- // chisel3.assert(outsideLiteral === insideLiteral)
-
- // the following lines of code error
- // with "chisel3.internal.BundleLitBinding cannot be cast to chisel3.internal.ElementLitBinding"
-
- chisel3.assert(outsideLiteral.x === insideLiteral.x)
- chisel3.assert(outsideLiteral.y === insideLiteral.y)
- chisel3.assert(outsideLiteral.x === 7.S)
- chisel3.assert(outsideLiteral.y === 6.125.F(4.BP))
-
- stop()
- }
-
- val outsideLiteral = (new InsideBundle).Lit(_.x -> 7.S, _.y -> 6.125.F(4.BP))
- assertTesterPasses { new LitInsideOutsideTester(outsideLiteral) }
-
- }
-
- "bundle literals" should "do the right thing" in {
- class MyBundle extends Bundle {
- val a = UInt(8.W)
- val b = Bool()
- }
- val myBundleLiteral = (new MyBundle).Lit(_.a -> 42.U, _.b -> true.B)
- assert(myBundleLiteral.a.litValue == 42)
- assert(myBundleLiteral.b.litValue == 1)
- assert(myBundleLiteral.b.litToBoolean == true)
- }
-
- "record literals" should "do the right thing" in {
- class MyRecord extends Record {
- override val elements = ListMap(
- "a" -> UInt(8.W),
- "b" -> Bool()
- )
- override def cloneType = (new MyRecord).asInstanceOf[this.type]
- }
-
- val myRecordLiteral = new (MyRecord).Lit(_.elements("a") -> 42.U, _.elements("b") -> true.B)
- assert(myRecordLiteral.elements("a").litValue == 42)
- assert(myRecordLiteral.elements("b").litValue == 1)
- }
-}
diff --git a/src/test/scala/chiselTests/LiteralToTargetSpec.scala b/src/test/scala/chiselTests/LiteralToTargetSpec.scala
deleted file mode 100644
index b1caecfa..00000000
--- a/src/test/scala/chiselTests/LiteralToTargetSpec.scala
+++ /dev/null
@@ -1,30 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.stage.ChiselStage
-
-import org.scalatest._
-import org.scalatest.freespec.AnyFreeSpec
-import org.scalatest.matchers.should.Matchers
-
-class LiteralToTargetSpec extends AnyFreeSpec with Matchers {
-
- "Literal Data should fail to be converted to ReferenceTarget" in {
-
- (the[chisel3.internal.ChiselException] thrownBy {
-
- class Bar extends RawModule {
- val a = 1.U
- }
-
- class Foo extends RawModule {
- val bar = Module(new Bar)
- bar.a.toTarget
- }
-
- ChiselStage.elaborate(new Foo)
- } should have).message("Illegal component name: UInt<1>(\"h01\") (note: literals are illegal)")
- }
-}
diff --git a/src/test/scala/chiselTests/LoadMemoryFromFileSpec.scala b/src/test/scala/chiselTests/LoadMemoryFromFileSpec.scala
deleted file mode 100644
index 8e5e48b4..00000000
--- a/src/test/scala/chiselTests/LoadMemoryFromFileSpec.scala
+++ /dev/null
@@ -1,270 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import java.io.File
-
-import chisel3._
-import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage}
-import chisel3.util.experimental.{loadMemoryFromFile, loadMemoryFromFileInline}
-import chisel3.util.log2Ceil
-import firrtl.annotations.MemoryLoadFileType
-import org.scalatest.freespec.AnyFreeSpec
-import org.scalatest.matchers.should.Matchers
-
-class UsesThreeMems(memoryDepth: Int, memoryType: Data) extends Module {
- val io = IO(new Bundle {
- val address = Input(UInt(memoryType.getWidth.W))
- val value1 = Output(memoryType)
- val value2 = Output(memoryType)
- val value3 = Output(memoryType)
- })
-
- val memory1 = Mem(memoryDepth, memoryType)
- val memory2 = Mem(memoryDepth, memoryType)
- val memory3 = Mem(memoryDepth, memoryType)
- loadMemoryFromFile(memory1, "./mem1")
- loadMemoryFromFile(memory2, "./mem1")
- loadMemoryFromFile(memory3, "./mem1")
-
- io.value1 := memory1(io.address)
- io.value2 := memory2(io.address)
- io.value3 := memory3(io.address)
-}
-
-class UsesThreeMemsInline(
- memoryDepth: Int,
- memoryType: Data,
- memoryFile: String,
- hexOrBinary: MemoryLoadFileType.FileType)
- extends Module {
- val io = IO(new Bundle {
- val address = Input(UInt(memoryType.getWidth.W))
- val value1 = Output(memoryType)
- val value2 = Output(memoryType)
- val value3 = Output(memoryType)
- })
-
- val memory1 = Mem(memoryDepth, memoryType)
- val memory2 = Mem(memoryDepth, memoryType)
- val memory3 = Mem(memoryDepth, memoryType)
- loadMemoryFromFileInline(memory1, memoryFile, hexOrBinary)
- loadMemoryFromFileInline(memory2, memoryFile, hexOrBinary)
- loadMemoryFromFileInline(memory3, memoryFile, hexOrBinary)
-
- io.value1 := memory1(io.address)
- io.value2 := memory2(io.address)
- io.value3 := memory3(io.address)
-}
-
-class UsesMem(memoryDepth: Int, memoryType: Data) extends Module {
- val io = IO(new Bundle {
- val address = Input(UInt(memoryType.getWidth.W))
- val value = Output(memoryType)
- val value1 = Output(memoryType)
- val value2 = Output(memoryType)
- })
-
- val memory = Mem(memoryDepth, memoryType)
- loadMemoryFromFile(memory, "./mem1")
-
- io.value := memory(io.address)
-
- val low1 = Module(new UsesMemLow(memoryDepth, memoryType))
- val low2 = Module(new UsesMemLow(memoryDepth, memoryType))
-
- low2.io.address := io.address
- low1.io.address := io.address
- io.value1 := low1.io.value
- io.value2 := low2.io.value
-}
-
-class UsesMemLow(memoryDepth: Int, memoryType: Data) extends Module {
- val io = IO(new Bundle {
- val address = Input(UInt(memoryType.getWidth.W))
- val value = Output(memoryType)
- })
-
- val memory = Mem(memoryDepth, memoryType)
-
- loadMemoryFromFile(memory, "./mem2")
-
- io.value := memory(io.address)
-}
-
-class FileHasSuffix(memoryDepth: Int, memoryType: Data) extends Module {
- val io = IO(new Bundle {
- val address = Input(UInt(memoryType.getWidth.W))
- val value = Output(memoryType)
- val value2 = Output(memoryType)
- })
-
- val memory = Mem(memoryDepth, memoryType)
-
- loadMemoryFromFile(memory, "./mem1.txt")
-
- io.value := memory(io.address)
-
- val low = Module(new UsesMemLow(memoryDepth, memoryType))
-
- low.io.address := io.address
- io.value2 := low.io.value
-}
-
-class MemoryShape extends Bundle {
- val a = UInt(8.W)
- val b = SInt(8.W)
- val c = Bool()
-}
-
-class HasComplexMemory(memoryDepth: Int) extends Module {
- val io = IO(new Bundle {
- val address = Input(UInt(log2Ceil(memoryDepth).W))
- val value = Output(new MemoryShape)
- })
-
- val memory = Mem(memoryDepth, new MemoryShape)
-
- loadMemoryFromFile(memory, "./mem", MemoryLoadFileType.Hex)
-
- io.value := memory(io.address)
-}
-
-class HasBinarySupport(memoryDepth: Int, memoryType: Data) extends Module {
- val io = IO(new Bundle {
- val address = Input(UInt(memoryType.getWidth.W))
- val value = Output(memoryType)
- })
-
- val memory = Mem(memoryDepth, memoryType)
-
- loadMemoryFromFile(memory, "./mem", MemoryLoadFileType.Binary)
-
- io.value := memory(io.address)
-}
-
-/**
- * The following tests are a bit incomplete and check that the output verilog is properly constructed
- * For more complete working examples
- * @see <a href="https://github.com/freechipsproject/chisel-testers">Chisel Testers</a> LoadMemoryFromFileSpec.scala
- */
-class LoadMemoryFromFileSpec extends AnyFreeSpec with Matchers {
- def fileExistsWithMem(file: File, mem: Option[String] = None): Unit = {
- info(s"$file exists")
- file.exists() should be(true)
- mem.foreach(m => {
- info(s"Memory $m is referenced in $file")
- val found = io.Source.fromFile(file).getLines.exists { _.contains(s"""readmemh("$m"""") }
- found should be(true)
- })
- file.delete()
- }
-
- "Users can specify a source file to load memory from" in {
- val testDirName = "test_run_dir/load_memory_spec"
-
- val result = (new ChiselStage).execute(
- args = Array("-X", "verilog", "--target-dir", testDirName),
- 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 = (new ChiselStage).execute(
- args = Array("-X", "verilog", "--target-dir", testDirName),
- annotations = Seq(ChiselGeneratorAnnotation(() => new UsesThreeMems(memoryDepth = 8, memoryType = UInt(16.W))))
- )
-
- 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 = (new ChiselStage).execute(
- args = Array("-X", "verilog", "--target-dir", complexTestDirName),
- annotations = Seq(ChiselGeneratorAnnotation(() => new HasComplexMemory(memoryDepth = 8)))
- )
-
- 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()
- }
-
- }
-
- "Has binary format support" in {
- val testDirName = "test_run_dir/binary_memory_load"
-
- val result = (new ChiselStage).execute(
- args = Array("-X", "verilog", "--target-dir", testDirName),
- annotations = Seq(ChiselGeneratorAnnotation(() => new HasBinarySupport(memoryDepth = 8, memoryType = UInt(16.W))))
- )
-
- val dir = new File(testDirName)
- val file = new File(dir, s"HasBinarySupport.HasBinarySupport.memory.v")
- file.exists() should be(true)
- val fileText = io.Source.fromFile(file).getLines().mkString("\n")
- fileText should include(s"""$$readmemb("./mem", HasBinarySupport.memory);""")
- file.delete()
- }
-
- "Module with more than one hex memory inline should work" in {
- val testDirName = "test_run_dir/load_three_memory_spec_inline"
-
- val result = (new ChiselStage).execute(
- args = Array("-X", "verilog", "--target-dir", testDirName),
- annotations = Seq(
- ChiselGeneratorAnnotation(() =>
- new UsesThreeMemsInline(memoryDepth = 8, memoryType = UInt(16.W), "./testmem.h", MemoryLoadFileType.Hex)
- )
- )
- )
- val dir = new File(testDirName)
- val file = new File(dir, s"UsesThreeMemsInline.v")
- file.exists() should be(true)
- val fileText = io.Source.fromFile(file).getLines().mkString("\n")
- fileText should include(s"""$$readmemh("./testmem.h", memory1);""")
- fileText should include(s"""$$readmemh("./testmem.h", memory2);""")
- fileText should include(s"""$$readmemh("./testmem.h", memory3);""")
- }
-
- "Module with more than one bin memory inline should work" in {
- val testDirName = "test_run_dir/load_three_memory_spec_inline"
-
- val result = (new ChiselStage).execute(
- args = Array("-X", "verilog", "--target-dir", testDirName),
- annotations = Seq(
- ChiselGeneratorAnnotation(() =>
- new UsesThreeMemsInline(memoryDepth = 8, memoryType = UInt(16.W), "testmem.bin", MemoryLoadFileType.Binary)
- )
- )
- )
- val dir = new File(testDirName)
- val file = new File(dir, s"UsesThreeMemsInline.v")
- file.exists() should be(true)
- val fileText = io.Source.fromFile(file).getLines().mkString("\n")
- fileText should include(s"""$$readmemb("testmem.bin", memory1);""")
- fileText should include(s"""$$readmemb("testmem.bin", memory2);""")
- fileText should include(s"""$$readmemb("testmem.bin", memory3);""")
- }
-}
diff --git a/src/test/scala/chiselTests/Math.scala b/src/test/scala/chiselTests/Math.scala
deleted file mode 100644
index 42eff6ad..00000000
--- a/src/test/scala/chiselTests/Math.scala
+++ /dev/null
@@ -1,52 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import org.scalacheck.Shrink
-
-class Math extends ChiselPropSpec {
- import chisel3.util._
- // Disable shrinking on error.
- implicit val noShrinkListVal = Shrink[List[Int]](_ => Stream.empty)
- implicit val noShrinkInt = Shrink[Int](_ => Stream.empty)
-
- property("unsignedBitLength is computed correctly") {
- forAll(safeUIntWidth) {
- case (width: Int) =>
- for (offset <- List(-1, 0, 1)) {
- val n = (1 << width) + offset
- if (n >= 0) {
- val d = unsignedBitLength(n)
- val t = if (n == 0) 0 else if (offset < 0) width else width + 1
- d shouldEqual (t)
- }
- }
- }
- }
-
- property("signedBitLength is computed correctly") {
- forAll(safeUIntWidth) {
- case (width: Int) =>
- for (offset <- List(-1, 0, 1)) {
- for (mult <- List(-1, +1)) {
- val n = ((1 << (width - 1)) + offset) * mult
- val d = signedBitLength(n)
- val t = n match {
- case -2 => 2
- case -1 => 1
- case 0 => 0
- case 1 => 2
- case 2 => 3
- case _ =>
- if (n > 0) {
- if (offset < 0) width else width + 1
- } else {
- if (offset > 0) width + 1 else width
- }
- }
- d shouldEqual (t)
- }
- }
- }
- }
-}
diff --git a/src/test/scala/chiselTests/Mem.scala b/src/test/scala/chiselTests/Mem.scala
deleted file mode 100644
index c5fcc6b1..00000000
--- a/src/test/scala/chiselTests/Mem.scala
+++ /dev/null
@@ -1,241 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.stage.ChiselStage
-import chisel3.util._
-import chisel3.testers.BasicTester
-
-class MemVecTester extends BasicTester {
- val mem = Mem(2, Vec(2, UInt(8.W)))
-
- // Circuit style tester is definitely the wrong abstraction here
- val (cnt, wrap) = Counter(true.B, 2)
- mem(0)(0) := 1.U
-
- when(cnt === 1.U) {
- assert(mem.read(0.U)(0) === 1.U)
- stop()
- }
-}
-
-class SyncReadMemTester extends BasicTester {
- val (cnt, _) = Counter(true.B, 5)
- val mem = SyncReadMem(2, UInt(2.W))
- val rdata = mem.read(cnt - 1.U, cnt =/= 0.U)
-
- switch(cnt) {
- is(0.U) { mem.write(cnt, 3.U) }
- is(1.U) { mem.write(cnt, 2.U) }
- is(2.U) { assert(rdata === 3.U) }
- is(3.U) { assert(rdata === 2.U) }
- is(4.U) { stop() }
- }
-}
-
-class SyncReadMemWriteCollisionTester extends BasicTester {
- val (cnt, _) = Counter(true.B, 5)
-
- // Write-first
- val m0 = SyncReadMem(2, UInt(2.W), SyncReadMem.WriteFirst)
- val rd0 = m0.read(cnt)
- m0.write(cnt, cnt)
-
- // Read-first
- val m1 = SyncReadMem(2, UInt(2.W), SyncReadMem.ReadFirst)
- val rd1 = m1.read(cnt)
- m1.write(cnt, cnt)
-
- // Read data from address 0
- when(cnt === 3.U) {
- assert(rd0 === 2.U)
- assert(rd1 === 0.U)
- }
-
- when(cnt === 4.U) {
- stop()
- }
-}
-
-class SyncReadMemWithZeroWidthTester extends BasicTester {
- val (cnt, _) = Counter(true.B, 3)
- val mem = SyncReadMem(2, UInt(0.W))
- val rdata = mem.read(0.U, true.B)
-
- switch(cnt) {
- is(1.U) { assert(rdata === 0.U) }
- is(2.U) { stop() }
- }
-}
-
-// TODO this can't actually simulate with FIRRTL behavioral mems
-class HugeSMemTester(size: BigInt) extends BasicTester {
- val (cnt, _) = Counter(true.B, 5)
- val mem = SyncReadMem(size, UInt(8.W))
- val rdata = mem.read(cnt - 1.U, cnt =/= 0.U)
-
- switch(cnt) {
- is(0.U) { mem.write(cnt, 3.U) }
- is(1.U) { mem.write(cnt, 2.U) }
- is(2.U) { assert(rdata === 3.U) }
- is(3.U) { assert(rdata === 2.U) }
- is(4.U) { stop() }
- }
-}
-class HugeCMemTester(size: BigInt) extends BasicTester {
- val (cnt, _) = Counter(true.B, 5)
- val mem = Mem(size, UInt(8.W))
- val rdata = mem.read(cnt)
-
- switch(cnt) {
- is(0.U) { mem.write(cnt, 3.U) }
- is(1.U) { mem.write(cnt, 2.U) }
- is(2.U) { assert(rdata === 3.U) }
- is(3.U) { assert(rdata === 2.U) }
- is(4.U) { stop() }
- }
-}
-
-class SyncReadMemBundleTester extends BasicTester {
- val (cnt, _) = Counter(true.B, 5)
- val tpe = new Bundle {
- val foo = UInt(2.W)
- }
- val mem = SyncReadMem(2, tpe)
- val rdata = mem.read(cnt - 1.U, cnt =/= 0.U)
-
- switch(cnt) {
- is(0.U) {
- val w = Wire(tpe)
- w.foo := 3.U
- mem.write(cnt, w)
- }
- is(1.U) {
- val w = Wire(tpe)
- w.foo := 2.U
- mem.write(cnt, w)
- }
- is(2.U) { assert(rdata.foo === 3.U) }
- is(3.U) { assert(rdata.foo === 2.U) }
- is(4.U) { stop() }
- }
-}
-
-class MemBundleTester extends BasicTester {
- val tpe = new Bundle {
- val foo = UInt(2.W)
- }
- val mem = Mem(2, tpe)
-
- // Circuit style tester is definitely the wrong abstraction here
- val (cnt, wrap) = Counter(true.B, 2)
- mem(0) := {
- val w = Wire(tpe)
- w.foo := 1.U
- w
- }
-
- when(cnt === 1.U) {
- assert(mem.read(0.U).foo === 1.U)
- stop()
- }
-}
-
-private class TrueDualPortMemoryIO(val addrW: Int, val dataW: Int) extends Bundle {
- require(addrW > 0, "address width must be greater than 0")
- require(dataW > 0, "data width must be greater than 0")
-
- val clka = Input(Clock())
- val ena = Input(Bool())
- val wea = Input(Bool())
- val addra = Input(UInt(addrW.W))
- val dia = Input(UInt(dataW.W))
- val doa = Output(UInt(dataW.W))
-
- val clkb = Input(Clock())
- val enb = Input(Bool())
- val web = Input(Bool())
- val addrb = Input(UInt(addrW.W))
- val dib = Input(UInt(dataW.W))
- val dob = Output(UInt(dataW.W))
-}
-
-private class TrueDualPortMemory(addrW: Int, dataW: Int) extends RawModule {
- val io = IO(new TrueDualPortMemoryIO(addrW, dataW))
- val ram = SyncReadMem(1 << addrW, UInt(dataW.W))
-
- // Port a
- withClock(io.clka) {
- io.doa := DontCare
- when(io.ena) {
- when(io.wea) {
- ram(io.addra) := io.dia
- }
- io.doa := ram(io.addra)
- }
- }
-
- // Port b
- withClock(io.clkb) {
- io.dob := DontCare
- when(io.enb) {
- when(io.web) {
- ram(io.addrb) := io.dib
- }
- io.dob := ram(io.addrb)
- }
- }
-}
-
-class MemorySpec extends ChiselPropSpec {
- property("Mem of Vec should work") {
- assertTesterPasses { new MemVecTester }
- }
-
- property("SyncReadMem should work") {
- assertTesterPasses { new SyncReadMemTester }
- }
-
- property("SyncReadMems of Bundles should work") {
- assertTesterPasses { new SyncReadMemBundleTester }
- }
-
- property("Mems of Bundles should work") {
- assertTesterPasses { new MemBundleTester }
- }
-
- property("SyncReadMem write collision behaviors should work") {
- assertTesterPasses { new SyncReadMemWriteCollisionTester }
- }
-
- property("SyncReadMem should work with zero width entry") {
- assertTesterPasses { new SyncReadMemWithZeroWidthTester }
- }
-
- property("Massive memories should be emitted in Verilog") {
- val addrWidth = 65
- val size = BigInt(1) << addrWidth
- val smem = compile(new HugeSMemTester(size))
- smem should include(s"reg /* sparse */ [7:0] mem [0:$addrWidth'd${size - 1}];")
- val cmem = compile(new HugeCMemTester(size))
- cmem should include(s"reg /* sparse */ [7:0] mem [0:$addrWidth'd${size - 1}];")
- }
-
- property("Implicit conversions with Mem indices should work") {
- """
- |import chisel3._
- |import chisel3.util.ImplicitConversions._
- |class MyModule extends Module {
- | val io = IO(new Bundle {})
- | val mem = Mem(32, UInt(8.W))
- | mem(0) := 0.U
- |}
- |""".stripMargin should compile
- }
-
- property("memories in modules without implicit clock should compile without warning or error") {
- val stage = new ChiselStage
- stage.emitVerilog(new TrueDualPortMemory(4, 32))
- }
-}
diff --git a/src/test/scala/chiselTests/MemorySearch.scala b/src/test/scala/chiselTests/MemorySearch.scala
deleted file mode 100644
index df1c6b32..00000000
--- a/src/test/scala/chiselTests/MemorySearch.scala
+++ /dev/null
@@ -1,58 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.stage.ChiselStage
-
-class MemorySearch extends Module {
- val io = IO(new Bundle {
- val target = Input(UInt(4.W))
- val en = Input(Bool())
- val done = Output(Bool())
- val address = Output(UInt(3.W))
- })
- val vals = Array(0, 4, 15, 14, 2, 5, 13)
- val index = RegInit(0.U(3.W))
- val elts = VecInit(vals.map(_.asUInt(4.W)))
- // val elts = Mem(UInt(32.W), 8) TODO ????
- val elt = elts(index)
- val end = !io.en && ((elt === io.target) || (index === 7.U))
- when(io.en) {
- index := 0.U
- }.elsewhen(!end) {
- index := index +% 1.U
- }
- io.done := end
- io.address := index
-}
-
-/*
-class MemorySearchTester(c: MemorySearch) extends Tester(c) {
- val list = c.vals
- val n = 8
- val maxT = n * (list.length + 3)
- for (k <- 0 until n) {
- val target = rnd.nextInt(16)
- poke(c.io.en, 1)
- poke(c.io.target, target)
- step(1)
- poke(c.io.en, 0)
- do {
- step(1)
- } while (peek(c.io.done) == 0 && t < maxT)
- val addr = peek(c.io.address).toInt
- expect(addr == list.length || list(addr) == target,
- "LOOKING FOR " + target + " FOUND " + addr)
- }
-}
- */
-
-class MemorySearchSpec extends ChiselPropSpec {
-
- property("MemorySearch should elaborate") {
- ChiselStage.elaborate { new EnableShiftRegister }
- }
-
- ignore("MemorySearch should return the correct result") {}
-}
diff --git a/src/test/scala/chiselTests/MigrateCompileOptionsSpec.scala b/src/test/scala/chiselTests/MigrateCompileOptionsSpec.scala
deleted file mode 100644
index 091f7f28..00000000
--- a/src/test/scala/chiselTests/MigrateCompileOptionsSpec.scala
+++ /dev/null
@@ -1,133 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3.stage.ChiselStage
-import chisel3.ImplicitInvalidate
-import chisel3.ExplicitCompileOptions
-
-import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks
-
-object MigrationExamples {
- object InferResets {
- import Chisel.{defaultCompileOptions => _, _}
- import chisel3.RequireSyncReset
- implicit val migrateIR = new chisel3.CompileOptions {
- val connectFieldsMustMatch = false
- val declaredTypeMustBeUnbound = false
- val dontTryConnectionsSwapped = false
- val dontAssumeDirectionality = false
- val checkSynthesizable = false
- val explicitInvalidate = false
- val inferModuleReset = false
-
- override val migrateInferModuleReset = true
- }
-
- class Foo extends Module {
- val io = new Bundle {}
- }
- class FooWithRequireSyncReset extends Module with RequireSyncReset {
- val io = new Bundle {}
- }
- }
- object ExplicitInvalidate {
- import chisel3.ImplicitInvalidate
- val migrateEI = new chisel3.CompileOptions {
- val connectFieldsMustMatch = false
- val declaredTypeMustBeUnbound = false
- val dontTryConnectionsSwapped = false
- val dontAssumeDirectionality = false
- val checkSynthesizable = false
- val explicitInvalidate = true
- val inferModuleReset = false
- }
- object ChiselChildren {
- import Chisel.{defaultCompileOptions => _, _}
- implicit val options = migrateEI
- class Foo extends Module {
- val io = new Bundle {
- val out = Output(UInt(width = 3))
- }
- }
- class FooWithImplicitInvalidate extends Module with ImplicitInvalidate {
- val io = new Bundle {
- val out = Output(UInt(width = 3))
- }
- }
- class FooWire extends Module {
- val io = new Bundle {}
- val wire = Wire(Bool())
- }
- class FooWireWithImplicitInvalidate extends Module with ImplicitInvalidate {
- val io = new Bundle {}
- val wire = Wire(Bool())
- }
- }
- object chisel3Children {
- import chisel3._
- class Foo extends Module {
- val in = IO(chisel3.Input(UInt(3.W)))
- }
- }
- object ChiselParents {
- import Chisel.{defaultCompileOptions => _, _}
- implicit val options = migrateEI
-
- class FooParent extends Module {
- val io = new Bundle {}
- val i = Module(new chisel3Children.Foo)
- }
- class FooParentWithImplicitInvalidate extends Module with ImplicitInvalidate {
- val io = new Bundle {}
- val i = Module(new chisel3Children.Foo)
- }
- }
- }
-}
-
-class MigrateCompileOptionsSpec extends ChiselFunSpec with Utils {
- import Chisel.{defaultCompileOptions => _, _}
- import chisel3.RequireSyncReset
-
- describe("(0): Migrating infer resets") {
- import MigrationExamples.InferResets._
- it("(0.a): Error if migrating, but not extended RequireSyncReset") {
- intercept[Exception] { ChiselStage.elaborate(new Foo) }
- }
- it("(0.b): Not error if migrating, and you mix with RequireSyncReset") {
- ChiselStage.elaborate(new FooWithRequireSyncReset)
- }
- }
-
- describe("(1): Migrating explicit invalidate") {
- import MigrationExamples.ExplicitInvalidate._
-
- it("(1.a): error if migrating module input, but not extending ImplicitInvalidate") {
- intercept[_root_.firrtl.passes.CheckInitialization.RefNotInitializedException] {
- ChiselStage.emitVerilog(new ChiselChildren.Foo)
- }
- }
- it("(1.b): succeed if migrating module input with extending ImplicitInvalidate") {
- ChiselStage.emitVerilog(new ChiselChildren.FooWithImplicitInvalidate)
- }
-
- it("(1.c): error if migrating instance output, but not extending ImplicitInvalidate") {
- intercept[_root_.firrtl.passes.CheckInitialization.RefNotInitializedException] {
- ChiselStage.emitVerilog(new ChiselParents.FooParent)
- }
- }
- it("(1.d): succeed if migrating instance output with extending ImplicitInvalidate") {
- ChiselStage.emitVerilog(new ChiselParents.FooParentWithImplicitInvalidate)
- }
-
- it("(1.e): error if migrating wire declaration, but not extending ImplicitInvalidate") {
- intercept[_root_.firrtl.passes.CheckInitialization.RefNotInitializedException] {
- ChiselStage.emitVerilog(new ChiselChildren.FooWire)
- }
- }
- it("(1.f): succeed if migrating wire declaration with extending ImplicitInvalidate") {
- ChiselStage.emitVerilog(new ChiselChildren.FooWireWithImplicitInvalidate)
- }
- }
-}
diff --git a/src/test/scala/chiselTests/MixedVecSpec.scala b/src/test/scala/chiselTests/MixedVecSpec.scala
deleted file mode 100644
index ee19d653..00000000
--- a/src/test/scala/chiselTests/MixedVecSpec.scala
+++ /dev/null
@@ -1,299 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.stage.ChiselStage
-import chisel3.testers.BasicTester
-import chisel3.util._
-import org.scalacheck.Shrink
-
-class MixedVecAssignTester(w: Int, values: List[Int]) extends BasicTester {
- val v = MixedVecInit(values.map(v => v.U(w.W)))
- for ((a, b) <- v.zip(values)) {
- assert(a === b.asUInt)
- }
- stop()
-}
-
-class MixedVecRegTester(w: Int, values: List[Int]) extends BasicTester {
- val valuesInit = MixedVecInit(values.map(v => v.U(w.W)))
- val reg = Reg(MixedVec(chiselTypeOf(valuesInit)))
-
- val doneReg = RegInit(false.B)
- doneReg := true.B
-
- when(!doneReg) {
- // First cycle: write to reg
- reg := valuesInit
- }.otherwise {
- // Second cycle: read back from reg
- for ((a, b) <- reg.zip(values)) {
- assert(a === b.asUInt)
- }
- stop()
- }
-}
-
-class MixedVecIOPassthroughModule[T <: Data](hvec: MixedVec[T]) extends Module {
- val io = IO(new Bundle {
- val in = Input(hvec)
- val out = Output(hvec)
- })
- io.out := io.in
-}
-
-class MixedVecIOTester(boundVals: Seq[Data]) extends BasicTester {
- val v = MixedVecInit(boundVals)
- val dut = Module(new MixedVecIOPassthroughModule(MixedVec(chiselTypeOf(v))))
- dut.io.in := v
- for ((a, b) <- dut.io.out.zip(boundVals)) {
- assert(a.asUInt === b.asUInt)
- }
- stop()
-}
-
-class MixedVecZeroEntryTester extends BasicTester {
- def zeroEntryMixedVec: MixedVec[Data] = MixedVec(Seq.empty)
-
- require(zeroEntryMixedVec.getWidth == 0)
-
- val bundleWithZeroEntryVec = new Bundle {
- val foo = Bool()
- val bar = zeroEntryMixedVec
- }
- require(0.U.asTypeOf(bundleWithZeroEntryVec).getWidth == 1)
- require(bundleWithZeroEntryVec.asUInt.getWidth == 1)
-
- val m = Module(new Module {
- val io = IO(Output(bundleWithZeroEntryVec))
- io.foo := false.B
- })
- WireDefault(m.io.bar)
-
- stop()
-}
-
-class MixedVecUIntDynamicIndexTester extends BasicTester {
- val wire = Wire(MixedVec(Seq(UInt(8.W), UInt(16.W), UInt(4.W), UInt(7.W))))
- val n = wire.length
-
- for (i <- 0 until n) {
- wire(i) := i.U
- }
-
- val vecWire = VecInit(wire.toSeq)
-
- val (cycle, done) = Counter(true.B, n)
- assert(vecWire(cycle) === cycle)
-
- when(done) { stop() }
-}
-
-class MixedVecTestBundle extends Bundle {
- val x = UInt(8.W)
- val y = UInt(8.W)
-}
-
-class MixedVecSmallTestBundle extends Bundle {
- val x = UInt(3.W)
- val y = UInt(3.W)
-}
-
-class MixedVecFromVecTester extends BasicTester {
- val wire = Wire(MixedVec(Vec(3, UInt(8.W))))
- wire := MixedVecInit(Seq(20.U, 40.U, 80.U))
-
- assert(wire(0) === 20.U)
- assert(wire(1) === 40.U)
- assert(wire(2) === 80.U)
-
- stop()
-}
-
-class MixedVecConnectWithVecTester extends BasicTester {
- val mixedVecType = MixedVec(Vec(3, UInt(8.W)))
-
- val m = Module(new MixedVecIOPassthroughModule(mixedVecType))
- m.io.in := VecInit(Seq(20.U, 40.U, 80.U))
- val wire = m.io.out
-
- assert(wire(0) === 20.U)
- assert(wire(1) === 40.U)
- assert(wire(2) === 80.U)
-
- stop()
-}
-
-class MixedVecConnectWithSeqTester extends BasicTester {
- val mixedVecType = MixedVec(Vec(3, UInt(8.W)))
-
- val m = Module(new MixedVecIOPassthroughModule(mixedVecType))
- m.io.in := Seq(20.U, 40.U, 80.U)
- val wire = m.io.out
-
- assert(wire(0) === 20.U)
- assert(wire(1) === 40.U)
- assert(wire(2) === 80.U)
-
- stop()
-}
-
-class MixedVecOneBitTester extends BasicTester {
- val flag = RegInit(false.B)
-
- val oneBit = Reg(MixedVec(Seq(UInt(1.W))))
- when(!flag) {
- oneBit(0) := 1.U(1.W)
- flag := true.B
- }.otherwise {
- assert(oneBit(0) === 1.U)
- assert(oneBit.asUInt === 1.U)
- stop()
- }
-}
-
-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)
- implicit val noShrinkInt = Shrink[Int](_ => Stream.empty)
-
- property("MixedVec varargs API should work") {
- assertTesterPasses {
- new BasicTester {
- val wire = Wire(MixedVec(UInt(1.W), UInt(8.W)))
- wire(0) := 1.U
- wire(1) := 101.U
-
- chisel3.assert(wire(0) === 1.U)
- chisel3.assert(wire(1) + 1.U === 102.U)
-
- val wireInit = MixedVecInit(1.U, 101.U)
- chisel3.assert(wireInit(0) === 1.U)
- chisel3.assert(wireInit(1) + 1.U === 102.U)
-
- stop()
- }
- }
- }
-
- property("MixedVecs should be assignable") {
- forAll(safeUIntN(8)) {
- case (w: Int, v: List[Int]) =>
- assertTesterPasses {
- new MixedVecAssignTester(w, v)
- }
- }
- }
-
- property("MixedVecs should be usable as the type for Reg()") {
- forAll(safeUIntN(8)) {
- case (w: Int, v: List[Int]) =>
- assertTesterPasses {
- new MixedVecRegTester(w, v)
- }
- }
- }
-
- property("MixedVecs should be passed through IO") {
- forAll(safeUIntN(8)) {
- case (w: Int, v: List[Int]) =>
- assertTesterPasses {
- new MixedVecIOTester(v.map(i => i.U(w.W)))
- }
- }
- }
-
- property("MixedVecs should work with mixed types") {
- assertTesterPasses {
- new MixedVecIOTester(Seq(true.B, 168.U(8.W), 888.U(10.W), -3.S))
- }
- }
-
- property("MixedVecs should not be able to take hardware types") {
- 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 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 extractCause[ExpectedChiselTypeException] {
- ChiselStage.elaborate(new Module {
- val io = IO(new Bundle {
- val v = Input(MixedVec(Seq(UInt(8.W), Bool())))
- })
- val illegal = MixedVec(io.v)
- })
- }
- }
-
- property("MixedVecs with zero entries should compile and have zero width") {
- assertTesterPasses { new MixedVecZeroEntryTester }
- }
-
- property("MixedVecs of UInts should be dynamically indexable (via VecInit)") {
- assertTesterPasses { new MixedVecUIntDynamicIndexTester }
- }
-
- property("MixedVecs should be creatable from Vecs") {
- assertTesterPasses { new MixedVecFromVecTester }
- }
-
- property("It should be possible to bulk connect a MixedVec and a Vec") {
- assertTesterPasses { new MixedVecConnectWithVecTester }
- }
-
- property("It should be possible to bulk connect a MixedVec and a Seq") {
- assertTesterPasses { new MixedVecConnectWithSeqTester }
- }
-
- property("MixedVecs of a single 1 bit element should compile and work") {
- assertTesterPasses { new MixedVecOneBitTester }
- }
-
- property("Connecting a MixedVec and something of different size should report a ChiselException") {
- 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())))
- })
- val seq = Seq.fill(5)(0.U)
- io.out := seq
- })
- }
- 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())))
- })
- val seq = VecInit(Seq(100.U(8.W)))
- io.out := seq
- })
- }
- }
-
- property("MixedVec connections should emit FIRRTL bulk connects when possible") {
- val chirrtl = ChiselStage.emitChirrtl(new Module {
- val io = IO(new Bundle {
- val inMono = Input(MixedVec(Seq(UInt(8.W), UInt(16.W), UInt(4.W), UInt(7.W))))
- val outMono = Output(MixedVec(Seq(UInt(8.W), UInt(16.W), UInt(4.W), UInt(7.W))))
- val inBi = Input(MixedVec(Seq(UInt(8.W), UInt(16.W), UInt(4.W), UInt(7.W))))
- val outBi = Output(MixedVec(Seq(UInt(8.W), UInt(16.W), UInt(4.W), UInt(7.W))))
- })
- // Explicit upcast avoids weird issue where Scala 2.12 overloading resolution calls version of := accepting Seq[T] instead of normal Data version
- io.outMono := (io.inMono: Data)
- io.outBi <> io.inBi
- })
- chirrtl should include("io.outMono <= io.inMono @[MixedVecSpec.scala")
- chirrtl should include("io.outBi <= io.inBi @[MixedVecSpec.scala")
- }
-}
diff --git a/src/test/scala/chiselTests/Module.scala b/src/test/scala/chiselTests/Module.scala
deleted file mode 100644
index b0fece3b..00000000
--- a/src/test/scala/chiselTests/Module.scala
+++ /dev/null
@@ -1,286 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.experimental.DataMirror
-import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage, NoRunFirrtlCompilerAnnotation}
-import firrtl.annotations.NoTargetAnnotation
-import firrtl.options.Unserializable
-
-import scala.io.Source
-import scala.annotation.nowarn
-
-class SimpleIO extends Bundle {
- val in = Input(UInt(32.W))
- val out = Output(UInt(32.W))
-}
-
-class PlusOne extends Module {
- val io = IO(new SimpleIO)
- val myReg = RegInit(0.U(8.W))
- dontTouch(myReg)
- io.out := io.in + 1.asUInt
-}
-
-class ModuleVec(val n: Int) extends Module {
- val io = IO(new Bundle {
- val ins = Input(Vec(n, UInt(32.W)))
- val outs = Output(Vec(n, UInt(32.W)))
- })
- val pluses = VecInit(Seq.fill(n) { Module(new PlusOne).io })
- for (i <- 0 until n) {
- pluses(i).in := io.ins(i)
- io.outs(i) := pluses(i).out
- }
-}
-
-class ModuleWire extends Module {
- val io = IO(new SimpleIO)
- val inc = Wire(chiselTypeOf(Module(new PlusOne).io))
- inc.in := io.in
- io.out := inc.out
-}
-
-class ModuleWhen extends Module {
- val io = IO(new Bundle {
- val s = new SimpleIO
- val en = Output(Bool())
- })
- when(io.en) {
- val inc = Module(new PlusOne).io
- inc.in := io.s.in
- io.s.out := inc.out
- }.otherwise { io.s.out := io.s.in }
-}
-
-class ModuleForgetWrapper extends Module {
- val io = IO(new SimpleIO)
- val inst = new PlusOne
-}
-
-class ModuleDoubleWrap extends Module {
- val io = IO(new SimpleIO)
- val inst = Module(Module(new PlusOne))
-}
-
-class ModuleRewrap extends Module {
- val io = IO(new SimpleIO)
- val inst = Module(new PlusOne)
- val inst2 = Module(inst)
-}
-
-class ModuleWrapper(gen: => Module) extends Module {
- val io = IO(new Bundle {})
- val child = Module(gen)
- override val desiredName = s"${child.desiredName}Wrapper"
-}
-
-class NullModuleWrapper extends Module {
- val io = IO(new Bundle {})
- override lazy val desiredName = s"${child.desiredName}Wrapper"
- println(s"My name is ${name}")
- val child = Module(new ModuleWire)
-}
-
-class ModuleSpec extends ChiselPropSpec with Utils {
-
- property("ModuleVec should elaborate") {
- ChiselStage.elaborate { new ModuleVec(2) }
- }
-
- ignore("ModuleVecTester should return the correct result") {}
-
- property("ModuleWire should elaborate") {
- ChiselStage.elaborate { new ModuleWire }
- }
-
- ignore("ModuleWireTester should return the correct result") {}
-
- property("ModuleWhen should elaborate") {
- ChiselStage.elaborate { new ModuleWhen }
- }
-
- ignore("ModuleWhenTester should return the correct result") {}
-
- property("Forgetting a Module() wrapper should result in an error") {
- (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 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 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") {
- ChiselStage.elaborate(new Module {
- val io = IO(new Bundle {
- val clock2 = Input(Clock())
- })
- assert(Module.clock eq this.clock)
- withClock(io.clock2) { assert(Module.clock eq io.clock2) }
- })
- }
- property("object Module.reset should return a reference to the currently in scope reset") {
- ChiselStage.elaborate(new Module {
- val io = IO(new Bundle {
- val reset2 = Input(Bool())
- })
- assert(Module.reset eq this.reset)
- withReset(io.reset2) { assert(Module.reset eq io.reset2) }
- })
- }
- 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)
- ChiselStage.elaborate(new Module {
- val io = IO(new Bundle {})
- assert(Module.currentModule.get eq this)
- assert(checkModule(this))
- })
- }
-
- property("object chisel3.util.experimental.getAnnotations should return current annotations.") {
- case class DummyAnnotation() extends NoTargetAnnotation with Unserializable
- (new ChiselStage).transform(
- Seq(
- ChiselGeneratorAnnotation(() =>
- new RawModule {
- assert(chisel3.util.experimental.getAnnotations().contains(DummyAnnotation()))
- }
- ),
- DummyAnnotation(),
- NoRunFirrtlCompilerAnnotation
- )
- )
- }
-
- property("DataMirror.modulePorts should work") {
- ChiselStage.elaborate(new Module {
- val io = IO(new Bundle {})
- val m = Module(new chisel3.Module {
- val a = IO(UInt(8.W))
- val b = IO(Bool())
- })
- assert(DataMirror.modulePorts(m) == Seq("clock" -> m.clock, "reset" -> m.reset, "a" -> m.a, "b" -> m.b))
- })
- }
-
- property("DataMirror.modulePorts should replace deprecated <module>.getPorts") {
- class MyModule extends Module {
- val io = IO(new Bundle {
- val in = Input(UInt(8.W))
- val out = Output(Vec(2, UInt(8.W)))
- })
- val extra = IO(Input(UInt(8.W)))
- val delay = RegNext(io.in)
- io.out(0) := delay
- io.out(1) := delay + extra
- }
- var mod: MyModule = null
- ChiselStage.elaborate {
- mod = new MyModule
- mod
- }
- // Note that this is just top-level ports, Aggregates are not flattened
- (DataMirror.modulePorts(mod) should contain).theSameElementsInOrderAs(
- Seq(
- "clock" -> mod.clock,
- "reset" -> mod.reset,
- "io" -> mod.io,
- "extra" -> mod.extra
- )
- )
- // Delete this when the deprecated API is deleted
- // Note this also uses deprecated Port
- import chisel3.internal.firrtl.Port
- import SpecifiedDirection.{Input => IN, Unspecified}
- (mod.getPorts should contain).theSameElementsInOrderAs(
- Seq(
- Port(mod.clock, IN),
- Port(mod.reset, IN),
- Port(mod.io, Unspecified),
- Port(mod.extra, IN)
- )
- ): @nowarn // delete when Port and getPorts become private
- }
-
- property("DataMirror.fullModulePorts should return all ports including children of Aggregates") {
- class MyModule extends Module {
- val io = IO(new Bundle {
- val in = Input(UInt(8.W))
- val out = Output(Vec(2, UInt(8.W)))
- })
- val extra = IO(Input(UInt(8.W)))
- val delay = RegNext(io.in)
- io.out(0) := delay
- io.out(1) := delay + extra
- }
- var mod: MyModule = null
- ChiselStage.elaborate {
- mod = new MyModule
- mod
- }
- val expected = Seq(
- "clock" -> mod.clock,
- "reset" -> mod.reset,
- "io" -> mod.io,
- "io_out" -> mod.io.out,
- "io_out_0" -> mod.io.out(0),
- "io_out_1" -> mod.io.out(1),
- "io_in" -> mod.io.in,
- "extra" -> mod.extra
- )
- (DataMirror.fullModulePorts(mod) should contain).theSameElementsInOrderAs(expected)
- }
-
- property("A desiredName parameterized by a submodule should work") {
- 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[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") {
- def foo = {
- class Foo1 extends RawModule {
- assert(name == "Foo1")
- }
- new Foo1
- }
- ChiselStage.elaborate(foo)
- }
- property("The name of an anonymous module should include '_Anon'") {
- trait Foo { this: RawModule =>
- assert(name.contains("_Anon"))
- }
- ChiselStage.elaborate(new RawModule with Foo)
- }
-
- property("getVerilogString(new PlusOne() should produce a valid Verilog string") {
- val s = getVerilogString(new PlusOne())
- assert(s.contains("assign io_out = io_in + 32'h1"))
- assert(s.contains("RANDOMIZE_REG_INIT"))
- }
-
- property("getVerilogString(new PlusOne() should produce a valid Verilog string with arguments") {
- val s = getVerilogString(new PlusOne(), Array("--emission-options=disableRegisterRandomization"))
- assert(s.contains("assign io_out = io_in + 32'h1"))
- assert(!s.contains("RANDOMIZE_REG_INIT"))
- }
-
- property("emitVerilog((new PlusOne()..) shall produce a valid Verilog file in a subfolder") {
- emitVerilog(new PlusOne(), Array("--target-dir", "generated"))
- val s = Source.fromFile("generated/PlusOne.v").mkString("")
- assert(s.contains("assign io_out = io_in + 32'h1"))
- }
-}
diff --git a/src/test/scala/chiselTests/ModuleExplicitResetSpec.scala b/src/test/scala/chiselTests/ModuleExplicitResetSpec.scala
deleted file mode 100644
index 1a55fb3f..00000000
--- a/src/test/scala/chiselTests/ModuleExplicitResetSpec.scala
+++ /dev/null
@@ -1,24 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3.stage.ChiselStage
-
-class ModuleExplicitResetSpec extends ChiselFlatSpec {
-
- "A Module with an explicit reset in compatibility mode" should "elaborate" in {
- import Chisel._
- val myReset = true.B
- class ModuleExplicitReset(reset: Bool) extends Module(_reset = reset) {
- val io = new Bundle {
- val done = Bool(OUTPUT)
- }
-
- io.done := false.B
- }
-
- ChiselStage.elaborate {
- new ModuleExplicitReset(myReset)
- }
- }
-}
diff --git a/src/test/scala/chiselTests/MulLookup.scala b/src/test/scala/chiselTests/MulLookup.scala
deleted file mode 100644
index 0f67ea34..00000000
--- a/src/test/scala/chiselTests/MulLookup.scala
+++ /dev/null
@@ -1,38 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.testers.BasicTester
-
-class MulLookup(val w: Int) extends Module {
- val io = IO(new Bundle {
- val x = Input(UInt(w.W))
- val y = Input(UInt(w.W))
- val z = Output(UInt((2 * w).W))
- })
- val tbl = VecInit(
- for {
- i <- 0 until 1 << w
- j <- 0 until 1 << w
- } yield (i * j).asUInt((2 * w).W)
- )
- io.z := tbl(((io.x << w) | io.y))
-}
-
-class MulLookupTester(w: Int, x: Int, y: Int) extends BasicTester {
- val dut = Module(new MulLookup(w))
- dut.io.x := x.asUInt
- dut.io.y := y.asUInt
- assert(dut.io.z === (x * y).asUInt)
- stop()
-}
-
-class MulLookupSpec extends ChiselPropSpec {
-
- property("Mul lookup table should return the correct result") {
- forAll(smallPosInts, smallPosInts) { (x: Int, y: Int) =>
- assertTesterPasses { new MulLookupTester(3, x, y) }
- }
- }
-}
diff --git a/src/test/scala/chiselTests/MultiAssign.scala b/src/test/scala/chiselTests/MultiAssign.scala
deleted file mode 100644
index 4cb51feb..00000000
--- a/src/test/scala/chiselTests/MultiAssign.scala
+++ /dev/null
@@ -1,82 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.testers.BasicTester
-import chisel3.stage.ChiselStage
-import chisel3.util._
-
-class LastAssignTester() extends BasicTester {
- val countOnClockCycles = true.B
- val (cnt, wrap) = Counter(countOnClockCycles, 2)
-
- val test = Wire(UInt(4.W))
- assert(test === 7.U) // allow read references before assign references
-
- test := 13.U
- assert(test === 7.U) // output value should be position-independent
-
- test := 7.U
- assert(test === 7.U) // this obviously should work
-
- when(cnt === 1.U) {
- stop()
- }
-}
-
-class MultiAssignSpec extends ChiselFlatSpec {
- "The last assignment" should "be used when multiple assignments happen" in {
- assertTesterPasses { new LastAssignTester }
- }
-}
-
-class IllegalAssignSpec extends ChiselFlatSpec with Utils {
- "Reassignments to literals" should "be disallowed" in {
- intercept[chisel3.internal.ChiselException] {
- extractCause[ChiselException] {
- ChiselStage.elaborate {
- new BasicTester {
- 15.U := 7.U
- }
- }
- }
- }
- }
-
- "Reassignments to ops" should "be disallowed" in {
- intercept[chisel3.internal.ChiselException] {
- extractCause[ChiselException] {
- ChiselStage.elaborate {
- new BasicTester {
- (15.U + 1.U) := 7.U
- }
- }
- }
- }
- }
-
- "Reassignments to bit slices" should "be disallowed" in {
- intercept[chisel3.internal.ChiselException] {
- 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] {
- 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
deleted file mode 100644
index 29ec6509..00000000
--- a/src/test/scala/chiselTests/MultiClockSpec.scala
+++ /dev/null
@@ -1,290 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.util.Counter
-import chisel3.testers.{BasicTester, TesterDriver}
-import chisel3.stage.ChiselStage
-
-/** Multi-clock test of a Reg using a different clock via withClock */
-class ClockDividerTest extends BasicTester {
- val cDiv = RegInit(true.B) // start with falling edge to simplify clock relationship assert
- cDiv := !cDiv
- val clock2 = cDiv.asClock
-
- val reg1 = RegInit(0.U(8.W))
- reg1 := reg1 + 1.U
- val reg2 = withClock(clock2) { RegInit(0.U(8.W)) }
- reg2 := reg2 + 1.U
-
- when(reg1 < 10.U) {
- assert(reg2 === reg1 / 2.U) // 1:2 clock relationship
- }
-
- when(reg1 === 10.U) {
- stop()
- }
-}
-
-class MultiClockSubModuleTest extends BasicTester {
- class SubModule extends Module {
- val io = IO(new Bundle {
- val out = Output(UInt())
- })
- val (cycle, _) = Counter(true.B, 10)
- io.out := cycle
- }
-
- val (cycle, done) = Counter(true.B, 10)
- val cDiv = RegInit(true.B) // start with falling edge to simplify clock relationship assert
- cDiv := !cDiv
-
- val otherClock = cDiv.asClock
- val otherReset = cycle < 3.U
-
- val inst = withClockAndReset(otherClock, otherReset) { Module(new SubModule) }
-
- when(done) {
- // The counter in inst should come out of reset later and increment at half speed
- assert(inst.io.out === 3.U)
- stop()
- }
-}
-
-/** Test withReset changing the reset of a Reg */
-class WithResetTest extends BasicTester {
- val reset2 = WireDefault(false.B)
- val reg = withReset(reset2 || reset.asBool) { RegInit(0.U(8.W)) }
- reg := reg + 1.U
-
- val (cycle, done) = Counter(true.B, 10)
- when(cycle < 7.U) {
- assert(reg === cycle)
- }.elsewhen(cycle === 7.U) {
- reset2 := true.B
- }.elsewhen(cycle === 8.U) {
- assert(reg === 0.U)
- }
- when(done) { stop() }
-}
-
-/** Test Mem ports with different clocks */
-class MultiClockMemTest extends BasicTester {
- val cDiv = RegInit(true.B)
- cDiv := !cDiv
- val clock2 = cDiv.asClock
-
- val mem = Mem(8, UInt(32.W))
-
- val (cycle, done) = Counter(true.B, 20)
-
- // Write port 1 walks through writing 123
- val waddr = RegInit(0.U(3.W))
- waddr := waddr + 1.U
- when(cycle < 8.U) {
- mem(waddr) := 123.U
- }
-
- val raddr = waddr - 1.U
- val rdata = mem(raddr)
-
- // Check each write from write port 1
- when(cycle > 0.U && cycle < 9.U) {
- assert(rdata === 123.U)
- }
-
- // Write port 2 walks through writing 456 on 2nd time through
- withClock(clock2) {
- when(cycle >= 8.U && cycle < 16.U) {
- mem(waddr) := 456.U // write 456 to different address
- }
- }
-
- // Check that every even address gets 456
- when(cycle > 8.U && cycle < 17.U) {
- when(raddr % 2.U === 0.U) {
- assert(rdata === 456.U)
- }.otherwise {
- assert(rdata === 123.U)
- }
- }
-
- when(done) { stop() }
-}
-
-class MultiClockSpec extends ChiselFlatSpec with Utils {
-
- "withClock" should "scope the clock of registers" in {
- assertTesterPasses(new ClockDividerTest)
- }
-
- it should "scope ports of memories" in {
- assertTesterPasses(new MultiClockMemTest, annotations = TesterDriver.verilatorOnly)
- }
-
- it should "return like a normal Scala block" in {
- ChiselStage.elaborate(new BasicTester {
- assert(withClock(this.clock) { 5 } == 5)
- })
- }
-
- "Differing clocks at memory and port instantiation" should "warn" in {
- class modMemDifferingClock extends Module {
- val myClock = IO(Input(Clock()))
- val mem = withClock(myClock) { Mem(4, UInt(8.W)) }
- val port0 = mem(0.U)
- }
- val (logMemDifferingClock, _) = grabLog(ChiselStage.elaborate(new modMemDifferingClock))
- logMemDifferingClock should include("memory is different")
-
- class modSyncReadMemDifferingClock extends Module {
- val myClock = IO(Input(Clock()))
- val mem = withClock(myClock) { SyncReadMem(4, UInt(8.W)) }
- val port0 = mem(0.U)
- }
- val (logSyncReadMemDifferingClock, _) = grabLog(ChiselStage.elaborate(new modSyncReadMemDifferingClock))
- logSyncReadMemDifferingClock should include("memory is different")
- }
-
- "Differing clocks at memory and write accessor instantiation" should "warn" in {
- class modMemWriteDifferingClock extends Module {
- val myClock = IO(Input(Clock()))
- val mem = withClock(myClock) { Mem(4, UInt(8.W)) }
- mem(1.U) := 1.U
- }
- val (logMemWriteDifferingClock, _) = grabLog(ChiselStage.elaborate(new modMemWriteDifferingClock))
- logMemWriteDifferingClock should include("memory is different")
-
- class modSyncReadMemWriteDifferingClock extends Module {
- val myClock = IO(Input(Clock()))
- val mem = withClock(myClock) { SyncReadMem(4, UInt(8.W)) }
- mem.write(1.U, 1.U)
- }
- val (logSyncReadMemWriteDifferingClock, _) = grabLog(ChiselStage.elaborate(new modSyncReadMemWriteDifferingClock))
- logSyncReadMemWriteDifferingClock should include("memory is different")
- }
-
- "Differing clocks at memory and read accessor instantiation" should "warn" in {
- class modSyncReadMemReadDifferingClock extends Module {
- val myClock = IO(Input(Clock()))
- val mem = withClock(myClock) { SyncReadMem(4, UInt(8.W)) }
- val readVal = mem.read(0.U)
- }
- val (logSyncReadMemReadDifferingClock, _) = grabLog(ChiselStage.elaborate(new modSyncReadMemReadDifferingClock))
- logSyncReadMemReadDifferingClock should include("memory is different")
- }
-
- "Passing clock parameter to memory port instantiation" should "not warn" in {
- class modMemPortClock extends Module {
- val myClock = IO(Input(Clock()))
- val mem = Mem(4, UInt(8.W))
- val port0 = mem(0.U, myClock)
- }
- val (logMemPortClock, _) = grabLog(ChiselStage.elaborate(new modMemPortClock))
- (logMemPortClock should not).include("memory is different")
-
- class modSyncReadMemPortClock extends Module {
- val myClock = IO(Input(Clock()))
- val mem = SyncReadMem(4, UInt(8.W))
- val port0 = mem(0.U, myClock)
- }
- val (logSyncReadMemPortClock, _) = grabLog(ChiselStage.elaborate(new modSyncReadMemPortClock))
- (logSyncReadMemPortClock should not).include("memory is different")
- }
-
- "Passing clock parameter to memory write accessor" should "not warn" in {
- class modMemWriteClock extends Module {
- val myClock = IO(Input(Clock()))
- val mem = Mem(4, UInt(8.W))
- mem.write(0.U, 0.U, myClock)
- }
- val (logMemWriteClock, _) = grabLog(ChiselStage.elaborate(new modMemWriteClock))
- (logMemWriteClock should not).include("memory is different")
-
- class modSyncReadMemWriteClock extends Module {
- val myClock = IO(Input(Clock()))
- val mem = SyncReadMem(4, UInt(8.W))
- mem.write(0.U, 0.U, myClock)
- }
- val (logSyncReadMemWriteClock, _) = grabLog(ChiselStage.elaborate(new modSyncReadMemWriteClock))
- (logSyncReadMemWriteClock should not).include("memory is different")
- }
-
- "Passing clock parameter to memory read accessor" should "not warn" in {
- class modMemReadClock extends Module {
- val myClock = IO(Input(Clock()))
- val mem = Mem(4, UInt(8.W))
- val readVal = mem.read(0.U, myClock)
- }
- val (logMemReadClock, _) = grabLog(ChiselStage.elaborate(new modMemReadClock))
- (logMemReadClock should not).include("memory is different")
-
- class modSyncReadMemReadClock extends Module {
- val myClock = IO(Input(Clock()))
- val mem = SyncReadMem(4, UInt(8.W))
- val readVal = mem.read(0.U, myClock)
- }
- val (logSyncReadMemReadClock, _) = grabLog(ChiselStage.elaborate(new modSyncReadMemReadClock))
- (logSyncReadMemReadClock should not).include("memory is different")
- }
-
- "withReset" should "scope the reset of registers" in {
- assertTesterPasses(new WithResetTest)
- }
-
- it should "scope the clock and reset of Modules" in {
- assertTesterPasses(new MultiClockSubModuleTest)
- }
-
- it should "return like a normal Scala block" in {
- ChiselStage.elaborate(new BasicTester {
- assert(withReset(this.reset) { 5 } == 5)
- })
- }
- it should "support literal Bools" in {
- assertTesterPasses(new BasicTester {
- val reg = withReset(true.B) {
- RegInit(6.U)
- }
- reg := reg - 1.U
- // The reg is always in reset so will never decrement
- chisel3.assert(reg === 6.U)
- val (_, done) = Counter(true.B, 4)
- when(done) { stop() }
- })
- }
-
- "withClockAndReset" should "return like a normal Scala block" in {
- ChiselStage.elaborate(new BasicTester {
- assert(withClockAndReset(this.clock, this.reset) { 5 } == 5)
- })
- }
-
- it should "scope the clocks and resets of asserts" in {
- // Check that assert can fire
- assertTesterFails(new BasicTester {
- withClockAndReset(clock, reset) {
- chisel3.assert(0.U === 1.U)
- }
- val (_, done) = Counter(true.B, 2)
- when(done) { stop() }
- })
- // Check that reset will block
- assertTesterPasses(new BasicTester {
- withClockAndReset(clock, true.B) {
- chisel3.assert(0.U === 1.U)
- }
- val (_, done) = Counter(true.B, 2)
- when(done) { stop() }
- })
- // Check that no rising edge will block
- assertTesterPasses(new BasicTester {
- withClockAndReset(false.B.asClock, reset) {
- chisel3.assert(0.U === 1.U)
- }
- val (_, done) = Counter(true.B, 2)
- when(done) { stop() }
- })
- }
-}
diff --git a/src/test/scala/chiselTests/MultiIOModule.scala b/src/test/scala/chiselTests/MultiIOModule.scala
deleted file mode 100644
index c65d8fc4..00000000
--- a/src/test/scala/chiselTests/MultiIOModule.scala
+++ /dev/null
@@ -1,56 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.testers.BasicTester
-
-class MultiIOPlusOne extends Module {
- val in = IO(Input(UInt(32.W)))
- val out = IO(Output(UInt(32.W)))
-
- out := in + 1.asUInt
-}
-
-class MultiIOTester extends BasicTester {
- val plusModule = Module(new MultiIOPlusOne)
- plusModule.in := 42.U
- assert(plusModule.out === 43.U)
- stop()
-}
-
-// Demonstrate multiple IOs with inheritance where the IO is assigned to internally
-trait LiteralOutputTrait extends Module {
- val myLiteralIO = IO(Output(UInt(32.W)))
- myLiteralIO := 2.U
-}
-
-// Demonstrate multiple IOs with inheritance where the IO is not assigned
-// (and must be assigned by what extends this trait).
-trait MultiIOTrait extends Module {
- val myTraitIO = IO(Output(UInt(32.W)))
-}
-
-// Composition of the two above traits, example of IO composition directly using multiple top-level
-// IOs rather than indirectly by constraining the type of the single .io field.
-class ComposedMultiIOModule extends Module with LiteralOutputTrait with MultiIOTrait {
- val topModuleIO = IO(Input(UInt(32.W)))
- myTraitIO := topModuleIO
-}
-
-class ComposedMultiIOTester extends BasicTester {
- val composedModule = Module(new ComposedMultiIOModule)
- composedModule.topModuleIO := 42.U
- assert(composedModule.myTraitIO === 42.U)
- assert(composedModule.myLiteralIO === 2.U)
- stop()
-}
-
-class MultiIOSpec extends ChiselFlatSpec {
- "Multiple IOs in MultiIOModule" should "work" in {
- assertTesterPasses({ new MultiIOTester })
- }
- "Composed MultiIO Modules" should "work" in {
- assertTesterPasses({ new ComposedMultiIOTester })
- }
-}
diff --git a/src/test/scala/chiselTests/MuxSpec.scala b/src/test/scala/chiselTests/MuxSpec.scala
deleted file mode 100644
index 03505f2d..00000000
--- a/src/test/scala/chiselTests/MuxSpec.scala
+++ /dev/null
@@ -1,72 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.stage.ChiselStage
-import chisel3.util.{log2Ceil, MuxLookup}
-import chisel3.testers.BasicTester
-
-class MuxTester extends BasicTester {
- assert(Mux(0.B, 1.U, 2.U) === 2.U)
- assert(Mux(1.B, 1.U, 2.U) === 1.U)
- val dontCareMux1 = Wire(UInt())
- dontCareMux1 := Mux(0.B, DontCare, 4.U) // note: Mux output of type Element
- assert(dontCareMux1 === 4.U)
-
- val dontCareMux2 = Wire(UInt())
- dontCareMux2 := Mux(1.B, 3.U, DontCare) // note: Mux output of type Element
- assert(dontCareMux2 === 3.U)
-
- Mux(0.B, 3.U, DontCare) // just to make sure nothing crashes, any result is valid
- stop()
-}
-
-class MuxSpec extends ChiselFlatSpec {
- "Mux" should "pass basic checks" in {
- assertTesterPasses { new MuxTester }
- }
-}
-
-class MuxLookupWrapper(keyWidth: Int, default: Int, mapping: () => Seq[(UInt, UInt)]) extends RawModule {
- val outputWidth = log2Ceil(default).max(keyWidth) // make room for default value
- val key = IO(Input(UInt(keyWidth.W)))
- val output = IO(Output(UInt(outputWidth.W)))
- output := MuxLookup(key, default.U, mapping())
-}
-
-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>("h$default")"""
-
- // 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") {
- ChiselStage.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") {
- (ChiselStage.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") {
- ChiselStage.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") {
- ChiselStage.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") {
- (ChiselStage.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
deleted file mode 100644
index a3f39c51..00000000
--- a/src/test/scala/chiselTests/NamingAnnotationTest.scala
+++ /dev/null
@@ -1,267 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.experimental.chiselName
-import chisel3.experimental.AffectsChiselPrefix
-import chisel3.internal.InstanceId
-import chisel3.stage.ChiselStage
-
-import scala.collection.mutable.ListBuffer
-
-trait NamedModuleTester extends Module with AffectsChiselPrefix {
- val expectedNameMap = ListBuffer[(InstanceId, String)]()
- val expectedModuleNameMap = ListBuffer[(Module, String)]()
-
- /** Expects some name for a node that is propagated to FIRRTL.
- * The node is returned allowing this to be called inline.
- */
- def expectName[T <: InstanceId](node: T, fullName: String): T = {
- expectedNameMap += ((node, fullName))
- node
- }
-
- /** Expects some name for a module declaration that is propagated to FIRRTL.
- * The node is returned allowing this to be called inline.
- */
- def expectModuleName[T <: Module](node: T, fullName: String): T = {
- expectedModuleNameMap += ((node, fullName))
- node
- }
-
- /** After this module has been elaborated, returns a list of (node, expected name, actual name)
- * that did not match expectations.
- * Returns an empty list if everything was fine.
- */
- def getNameFailures(): List[(InstanceId, String, String)] = {
- val failures = ListBuffer[(InstanceId, String, String)]()
- for ((ref, expectedName) <- expectedNameMap) {
- if (ref.instanceName != expectedName) {
- failures += ((ref, expectedName, ref.instanceName))
- }
- }
- for ((mod, expectedModuleName) <- expectedModuleNameMap) {
- if (mod.name != expectedModuleName) {
- failures += ((mod, expectedModuleName, mod.name))
- }
- }
- failures.toList
- }
-}
-class OuterNamedNonModule extends AffectsChiselPrefix {
- val value = Wire(Bool())
-}
-
-class NonModule extends AffectsChiselPrefix {
- val value = Wire(Bool())
- class InnerNamedNonModule extends AffectsChiselPrefix {
- val value = Wire(Bool())
- }
- val inner = new InnerNamedNonModule
- val outer = new OuterNamedNonModule
-}
-
-class NamedModule extends NamedModuleTester {
- def FunctionMockupInner(): UInt = {
- val my2A = 1.U
- val my2B = expectName(my2A +& 2.U, "test_myNested_my2B")
- val my2C = my2B +& 3.U // should get named at enclosing scope
- my2C
- }
-
- def FunctionMockup(): UInt = {
- val myNested = expectName(FunctionMockupInner(), "test_myNested")
- val myA = expectName(1.U + myNested, "test_myA")
- val myB = expectName(myA +& 2.U, "test_myB")
- val myC = expectName(myB +& 3.U, "test_myC")
-
- val myD = Seq(myC +& 1.U, myC +& 2.U)
- for ((d, i) <- myD.zipWithIndex)
- expectName(d, s"test_myD_$i")
-
- myC +& 4.U // named at enclosing scope
- }
-
- // chiselName "implicitly" applied
- def ImplicitlyNamed(): UInt = {
- val implicitA = expectName(1.U + 2.U, "test3_implicitA")
- val implicitB = expectName(implicitA + 3.U, "test3_implicitB")
- implicitB + 2.U // named at enclosing scope
- }
-
- // Ensure this applies a partial name if there is no return value
- def NoReturnFunction() {
- val noreturn = expectName(1.U + 2.U, "noreturn")
- }
-
- 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")
- expectName(test4.outer.value, "test4_outer_value")
-
- // Test that contents of for loops are named
- for (i <- 0 until 1) {
- val forInner = expectName(test3 + i.U, "forInner")
- }
-
- // Test that contents of anonymous functions are named
- Seq((0, "anonInner"), (1, "anonInner_1"), (2, "anonInner_2")).foreach {
- case (in, name) =>
- val anonInner = expectName(test3 + in.U, name)
- }
-
- NoReturnFunction()
-}
-
-class NameCollisionModule extends NamedModuleTester {
- def repeatedCalls(name: String): UInt = {
- val test = expectName(1.U + 3.U, s"${name}_test") // should disambiguate by invocation order
- test + 2.U
- }
-
- // chiselName applied by default to this
- def innerNamedFunction() {
- // ... but not this inner function
- def innerUnnamedFunction() {
- val a = repeatedCalls("a")
- val b = repeatedCalls("b")
- }
-
- innerUnnamedFunction()
- }
-
- val test = expectName(1.U + 2.U, "test")
- innerNamedFunction()
-}
-
-/** Ensure no crash happens if a named function is enclosed in a non-named module
- */
-class NonNamedModule extends NamedModuleTester {
- @chiselName
- def NamedFunction(): UInt = {
- val myVal = 1.U + 2.U
- myVal
- }
-
- val test = NamedFunction()
-}
-
-/** Ensure no crash happens if a named function is enclosed in a non-named function in a named
- * module.
- */
-object NonNamedHelper {
- @chiselName
- def NamedFunction(): UInt = {
- val myVal = 1.U + 2.U
- myVal
- }
-
- def NonNamedFunction(): UInt = {
- val myVal = NamedFunction()
- myVal
- }
-
- @chiselName
- def NonBuilderFunction(): Int = {
- 1 + 1
- }
-}
-
-@chiselName
-class NonNamedFunction extends NamedModuleTester {
- val test = NonNamedHelper.NamedFunction()
-}
-
-/** Ensure broken links in the chain are simply dropped
- */
-@chiselName
-class PartialNamedModule extends NamedModuleTester {
- // Create an inner function that is the extent of the implicit naming
- def innerNamedFunction(): UInt = {
- def innerUnnamedFunction(): UInt = {
- @chiselName
- def disconnectedNamedFunction(): UInt = {
- val a = expectName(1.U + 2.U, "test_a")
- val b = expectName(a + 2.U, "test_b")
- b
- }
- disconnectedNamedFunction()
- }
- innerUnnamedFunction() + 1.U
- }
-
- val test = innerNamedFunction()
-}
-
-@chiselName
-class NoChiselNamePrefixTester extends NamedModuleTester {
- @chiselName
- class NoChiselNamePrefixClass extends chisel3.experimental.NoChiselNamePrefix {
- val a = expectName(1.U +& 2.U, "a")
- }
- val inst = new NoChiselNamePrefixClass
- class NormalClass {
- val b = 1.U +& 2.U
- }
- val foo = new NormalClass with AffectsChiselPrefix
- expectName(foo.b, "foo_b")
- val bar = new NormalClass with chisel3.experimental.NoChiselNamePrefix
- expectName(bar.b, "b")
-
- // Check that we're not matching by name but actual type
- trait NoChiselNamePrefix
- class FakeNoChiselNamePrefix extends NoChiselNamePrefix with AffectsChiselPrefix {
- val c = 1.U +& 2.U
- }
- val fizz = new FakeNoChiselNamePrefix
- expectName(fizz.c, "fizz_c")
-}
-
-/** A simple test that checks the recursive function val naming annotation both compiles and
- * generates the expected names.
- */
-class NamingAnnotationSpec extends ChiselPropSpec {
- property("NamedModule should have function hierarchical names") {
- // TODO: clean up test style
- var module: NamedModule = null
- ChiselStage.elaborate { module = new NamedModule; module }
- assert(module.getNameFailures() == Nil)
- }
-
- property("NameCollisionModule should disambiguate collisions") {
- // TODO: clean up test style
- var module: NameCollisionModule = null
- 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
- ChiselStage.elaborate { module = new PartialNamedModule; module }
- assert(module.getNameFailures() == Nil)
- }
-
- property("NonNamedModule should elaborate") {
- ChiselStage.elaborate { new NonNamedModule }
- }
-
- property("NonNamedFunction should elaborate") {
- ChiselStage.elaborate { new NonNamedFunction }
- }
-
- property("NonBuilderFunction should run outside a Builder context") {
- NonNamedHelper.NonBuilderFunction() should be(2)
- }
-
- property("NoChiselNamePrefix should prevent prefixing when using @chiselName") {
- var module: NoChiselNamePrefixTester = null
- ChiselStage.elaborate { module = new NoChiselNamePrefixTester; module }
- assert(module.getNameFailures().isEmpty)
- }
-}
diff --git a/src/test/scala/chiselTests/NewAnnotationsSpec.scala b/src/test/scala/chiselTests/NewAnnotationsSpec.scala
deleted file mode 100644
index 38e1c1d9..00000000
--- a/src/test/scala/chiselTests/NewAnnotationsSpec.scala
+++ /dev/null
@@ -1,72 +0,0 @@
-package chiselTests
-import chisel3._
-import chisel3.experimental.{annotate, ChiselMultiAnnotation}
-import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage}
-import firrtl.stage.FirrtlCircuitAnnotation
-import org.scalatest.freespec.AnyFreeSpec
-import org.scalatest.matchers.should.Matchers
-import firrtl.transforms.NoDedupAnnotation
-import firrtl.transforms.DontTouchAnnotation
-
-class NewAnnotationsSpec extends AnyFreeSpec with Matchers {
-
- class MuchUsedModule extends Module {
- val io = IO(new Bundle {
- val in = Input(UInt(16.W))
- val out = Output(UInt(16.W))
- })
- io.out := io.in +% 1.U
- }
-
- class UsesMuchUsedModule extends Module {
- val io = IO(new Bundle {
- val in = Input(UInt(16.W))
- val out = Output(UInt(16.W))
- })
-
- val mod0 = Module(new MuchUsedModule)
- val mod1 = Module(new MuchUsedModule)
- val mod2 = Module(new MuchUsedModule)
- val mod3 = Module(new MuchUsedModule)
-
- mod0.io.in := io.in
- mod1.io.in := mod0.io.out
- mod2.io.in := mod1.io.out
- mod3.io.in := mod2.io.out
- io.out := mod3.io.out
-
- // Give two annotations as single element of the seq - ensures previous API works by wrapping into a seq.
- annotate(new ChiselMultiAnnotation { def toFirrtl = Seq(new NoDedupAnnotation(mod2.toNamed)) })
- annotate(new ChiselMultiAnnotation { def toFirrtl = Seq(new NoDedupAnnotation(mod3.toNamed)) })
-
- // Pass multiple annotations in the same seq - should get emitted out correctly.
- annotate(new ChiselMultiAnnotation {
- def toFirrtl =
- Seq(new DontTouchAnnotation(mod1.io.in.toNamed), new DontTouchAnnotation(mod1.io.out.toNamed))
- })
- }
-
- val stage = new ChiselStage
- "Ensure all annotations continue to be passed / digested correctly with the new API" - {
- "NoDedup and DontTouch work as expected" in {
- val dutAnnos = stage
- .execute(
- Array("-X", "low", "--target-dir", "test_run_dir"),
- Seq(ChiselGeneratorAnnotation(() => new UsesMuchUsedModule))
- )
-
- val dontTouchAnnos = dutAnnos.collect { case DontTouchAnnotation(target) => target.serialize }
- val noDedupAnnos = dutAnnos.collect { case NoDedupAnnotation(target) => target.serialize }
- require(dontTouchAnnos.size == 2, s"Exactly two DontTouch Annotations expected but got $dontTouchAnnos ")
- require(noDedupAnnos.size == 2, s"Exactly two NoDedup Annotations expected but got $noDedupAnnos ")
- val dontTouchAnnosCombined = dontTouchAnnos.mkString(",")
- val noDedupAnnosCombined = noDedupAnnos.mkString(",")
-
- noDedupAnnosCombined should include("~UsesMuchUsedModule|MuchUsedModule_2")
- noDedupAnnosCombined should include("~UsesMuchUsedModule|MuchUsedModule_3")
- dontTouchAnnosCombined should include("~UsesMuchUsedModule|UsesMuchUsedModule/mod1:MuchUsedModule>io_out")
- dontTouchAnnosCombined should include("~UsesMuchUsedModule|UsesMuchUsedModule/mod1:MuchUsedModule>io_in")
-
- }
- }
-}
diff --git a/src/test/scala/chiselTests/OneHotMuxSpec.scala b/src/test/scala/chiselTests/OneHotMuxSpec.scala
deleted file mode 100644
index b069b219..00000000
--- a/src/test/scala/chiselTests/OneHotMuxSpec.scala
+++ /dev/null
@@ -1,318 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.experimental.FixedPoint
-import chisel3.internal.ChiselException
-import chisel3.testers.BasicTester
-import chisel3.util.{Mux1H, UIntToOH}
-import org.scalatest._
-import org.scalatest.freespec.AnyFreeSpec
-import org.scalatest.matchers.should.Matchers
-
-class OneHotMuxSpec extends AnyFreeSpec with Matchers with ChiselRunners {
- "simple one hot mux with uint should work" in {
- assertTesterPasses(new SimpleOneHotTester)
- }
- "simple one hot mux with sint should work" in {
- assertTesterPasses(new SIntOneHotTester)
- }
- "simple one hot mux with fixed point should work" in {
- assertTesterPasses(new FixedPointOneHotTester)
- }
- "simple one hot mux with all same fixed point should work" in {
- assertTesterPasses(new AllSameFixedPointOneHotTester)
- }
- "simple one hot mux with all same parameterized sint values should work" in {
- assertTesterPasses(new ParameterizedOneHotTester)
- }
- "simple one hot mux with all same parameterized aggregates containing fixed values should work" in {
- assertTesterPasses(new ParameterizedAggregateOneHotTester)
- }
- "simple one hot mux with all aggregates containing inferred width fixed values should NOT work" in {
- intercept[ChiselException] {
- assertTesterPasses(new InferredWidthAggregateOneHotTester)
- }
- }
- "simple one hot mux with all fixed width bundles but with different bundles should Not work" in {
- intercept[IllegalArgumentException] {
- assertTesterPasses(new DifferentBundleOneHotTester)
- }
- }
- "UIntToOH with output width greater than 2^(input width)" in {
- assertTesterPasses(new UIntToOHTester)
- }
- "UIntToOH should not accept width of zero (until zero-width wires are fixed" in {
- intercept[IllegalArgumentException] {
- assertTesterPasses(new BasicTester {
- val out = UIntToOH(0.U, 0)
- })
- }
- }
-
-}
-
-class SimpleOneHotTester extends BasicTester {
- val out = Wire(UInt())
- out := Mux1H(
- Seq(
- false.B -> 2.U,
- false.B -> 4.U,
- true.B -> 8.U,
- false.B -> 11.U
- )
- )
-
- assert(out === 8.U)
-
- stop()
-}
-
-class SIntOneHotTester extends BasicTester {
- val out = Wire(SInt())
- out := Mux1H(
- Seq(
- false.B -> (-3).S,
- true.B -> (-5).S,
- false.B -> (-7).S,
- false.B -> (-11).S
- )
- )
-
- assert(out === (-5).S)
-
- stop()
-}
-
-class FixedPointOneHotTester extends BasicTester {
- val out = Wire(FixedPoint(8.W, 4.BP))
-
- out := Mux1H(
- Seq(
- false.B -> (-1.5).F(1.BP),
- true.B -> (-2.25).F(2.BP),
- false.B -> (-4.125).F(3.BP),
- false.B -> (-11.625).F(3.BP)
- )
- )
-
- assert(out === (-2.25).F(4.BP))
-
- stop()
-}
-
-class AllSameFixedPointOneHotTester extends BasicTester {
- val out = Wire(FixedPoint(12.W, 3.BP))
-
- out := Mux1H(
- Seq(
- false.B -> (-1.5).F(12.W, 3.BP),
- true.B -> (-2.25).F(12.W, 3.BP),
- false.B -> (-4.125).F(12.W, 3.BP),
- false.B -> (-11.625).F(12.W, 3.BP)
- )
- )
-
- assert(out === (-2.25).F(14.W, 4.BP))
-
- stop()
-}
-
-class ParameterizedOneHotTester extends BasicTester {
- val values: Seq[Int] = Seq(-3, -5, -7, -11)
- for ((v, i) <- values.zipWithIndex) {
- val dut = Module(new ParameterizedOneHot(values.map(_.S), SInt(8.W)))
- dut.io.selectors := (1 << i).U(4.W).asBools
-
- assert(dut.io.out.asUInt() === v.S(8.W).asUInt())
- }
-
- stop()
-}
-
-class Agg1 extends Bundle {
- val v = Vec(2, FixedPoint(8.W, 4.BP))
- val a = new Bundle {
- val f1 = FixedPoint(7.W, 3.BP)
- val f2 = FixedPoint(9.W, 5.BP)
- }
-}
-
-object Agg1 extends HasMakeLit[Agg1] {
- def makeLit(n: Int): Agg1 = {
- val x = n.toDouble / 4.0
- val (d: Double, e: Double, f: Double, g: Double) = (x, x * 2.0, x * 3.0, x * 4.0)
-
- val w = Wire(new Agg1)
- w.v(0) := d.F(4.BP)
- w.v(1) := e.F(4.BP)
- w.a.f1 := f.F(3.BP)
- w.a.f2 := g.F(5.BP)
- w
- }
-}
-class Agg2 extends Bundle {
- val v = Vec(2, FixedPoint(8.W, 4.BP))
- val a = new Bundle {
- val f1 = FixedPoint(7.W, 3.BP)
- val f2 = FixedPoint(9.W, 5.BP)
- }
-}
-
-object Agg2 extends HasMakeLit[Agg2] {
- def makeLit(n: Int): Agg2 = {
- val x = n.toDouble / 4.0
- val (d: Double, e: Double, f: Double, g: Double) = (x, x * 2.0, x * 3.0, x * 4.0)
-
- val w = Wire(new Agg2)
- w.v(0) := d.F(4.BP)
- w.v(1) := e.F(4.BP)
- w.a.f1 := f.F(3.BP)
- w.a.f2 := g.F(5.BP)
- w
- }
-}
-
-class ParameterizedAggregateOneHotTester extends BasicTester {
- val values = (0 until 4).map { n => Agg1.makeLit(n) }
- for ((v, i) <- values.zipWithIndex) {
- val dut = Module(new ParameterizedAggregateOneHot(Agg1, new Agg1))
- dut.io.selectors := (1 << i).U(4.W).asBools
-
- assert(dut.io.out.asUInt() === values(i).asUInt())
- }
-
- stop()
-}
-
-trait HasMakeLit[T] {
- def makeLit(n: Int): T
-}
-
-class ParameterizedOneHot[T <: Data](values: Seq[T], outGen: T) extends Module {
- val io = IO(new Bundle {
- val selectors = Input(Vec(4, Bool()))
- val out = Output(outGen)
- })
-
- val terms = io.selectors.zip(values)
- io.out := Mux1H(terms)
-}
-
-class ParameterizedAggregateOneHot[T <: Data](valGen: HasMakeLit[T], outGen: T) extends Module {
- val io = IO(new Bundle {
- val selectors = Input(Vec(4, Bool()))
- val out = Output(outGen)
- })
-
- val values = (0 until 4).map { n => valGen.makeLit(n) }
- val terms = io.selectors.zip(values)
- io.out := Mux1H(terms)
-}
-
-class Bundle1 extends Bundle {
- val a = FixedPoint()
- val b = new Bundle {
- val c = FixedPoint()
- }
-}
-
-class InferredWidthAggregateOneHotTester extends BasicTester {
- val b0 = Wire(new Bundle1)
- b0.a := -0.25.F(2.BP)
- b0.b.c := -0.125.F(3.BP)
-
- val b1 = Wire(new Bundle1)
- b1.a := -0.0625.F(3.BP)
- b1.b.c := -0.03125.F(4.BP)
-
- val b2 = Wire(new Bundle1)
- b2.a := -0.015625.F(5.BP)
- b2.b.c := -0.0078125.F(6.BP)
-
- val b3 = Wire(new Bundle1)
- b3.a := -0.0078125.F(7.BP)
- b3.b.c := -0.00390625.F(8.BP)
-
- val o1 = Mux1H(
- Seq(
- false.B -> b0,
- false.B -> b1,
- true.B -> b2,
- false.B -> b3
- )
- )
-
- assert(o1.a === -0.015625.F(5.BP))
- assert(o1.b.c === -0.0078125.F(6.BP))
-
- val o2 = Mux1H(
- Seq(
- false.B -> b0,
- true.B -> b1,
- false.B -> b2,
- false.B -> b3
- )
- )
-
- assert(o2.a === -0.0625.F(3.BP))
- assert(o2.b.c === -0.03125.F(4.BP))
-
- stop()
-}
-
-class Bundle2 extends Bundle {
- val a = FixedPoint(10.W, 4.BP)
- val b = new Bundle {
- val c = FixedPoint(10.W, 4.BP)
- }
-}
-
-class Bundle3 extends Bundle {
- val a = FixedPoint(10.W, 4.BP)
- val b = new Bundle {
- val c = FixedPoint(10.W, 4.BP)
- }
-}
-
-class DifferentBundleOneHotTester extends BasicTester {
- val b0 = Wire(new Bundle2)
- b0.a := -0.25.F(2.BP)
- b0.b.c := -0.125.F(3.BP)
-
- val b1 = Wire(new Bundle2)
- b1.a := -0.0625.F(3.BP)
- b1.b.c := -0.03125.F(4.BP)
-
- val b2 = Wire(new Bundle3)
- b2.a := -0.015625.F(5.BP)
- b2.b.c := -0.0078125.F(6.BP)
-
- val b3 = Wire(new Bundle3)
- b3.a := -0.0078125.F(7.BP)
- b3.b.c := -0.00390625.F(8.BP)
-
- val o1 = Mux1H(
- Seq(
- false.B -> b0,
- false.B -> b1,
- true.B -> b2,
- false.B -> b3
- )
- )
-
- stop()
-}
-
-class UIntToOHTester extends BasicTester {
- val out = UIntToOH(1.U, 3)
- require(out.getWidth == 3)
- assert(out === 2.U)
-
- val out2 = UIntToOH(0.U, 1)
- require(out2.getWidth == 1)
- assert(out2 === 1.U)
-
- stop()
-}
diff --git a/src/test/scala/chiselTests/OptionBundle.scala b/src/test/scala/chiselTests/OptionBundle.scala
deleted file mode 100644
index 628e117d..00000000
--- a/src/test/scala/chiselTests/OptionBundle.scala
+++ /dev/null
@@ -1,62 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.stage.ChiselStage
-import chisel3.testers.BasicTester
-
-class OptionBundle(val hasIn: Boolean) extends Bundle {
- val in = if (hasIn) {
- Some(Input(Bool()))
- } else {
- None
- }
- val out = Output(Bool())
-}
-
-class OptionBundleModule(val hasIn: Boolean) extends Module {
- val io = IO(new OptionBundle(hasIn))
- if (hasIn) {
- io.out := io.in.get
- } else {
- io.out := false.B
- }
-}
-
-class SomeOptionBundleTester(expected: Boolean) extends BasicTester {
- val mod = Module(new OptionBundleModule(true))
- mod.io.in.get := expected.asBool
- assert(mod.io.out === expected.asBool)
- stop()
-}
-
-class NoneOptionBundleTester() extends BasicTester {
- val mod = Module(new OptionBundleModule(false))
- assert(mod.io.out === false.B)
- stop()
-}
-
-class InvalidOptionBundleTester() extends BasicTester {
- val mod = Module(new OptionBundleModule(false))
- mod.io.in.get := true.B
- assert(false.B)
- stop()
-}
-
-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) }
- }
-
- "A Bundle with an Option field" should "compile if the Option field is None" in {
- assertTesterPasses { new NoneOptionBundleTester() }
- }
-
- "A Bundle with an Option field" should "assert out accessing a None Option field" in {
- 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
deleted file mode 100644
index 7950c203..00000000
--- a/src/test/scala/chiselTests/Padding.scala
+++ /dev/null
@@ -1,43 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.stage.ChiselStage
-
-class Padder extends Module {
- val io = IO(new Bundle {
- val a = Input(UInt(4.W))
- val asp = Output(SInt(8.W))
- val aup = Output(UInt(8.W))
- })
- io.asp := io.a.asSInt
- io.aup := io.a.asUInt
-}
-
-/*
-class PadsTester(c: Pads) extends Tester(c) {
- def pads(x: BigInt, s: Int, w: Int) = {
- val sign = (x & (1 << (s-1)))
- val wmask = (1 << w) - 1
- val bmask = (1 << s) - 1
- if (sign == 0) x else ((~bmask | x) & wmask)
- }
- for (t <- 0 until 16) {
- val test_a = rnd.nextInt(1 << 4)
- poke(c.io.a, test_a)
- step(1)
- expect(c.io.asp, pads(test_a, 4, 8))
- expect(c.io.aup, test_a)
- }
-}
- */
-
-class PadderSpec extends ChiselPropSpec {
-
- property("Padder should elaborate") {
- ChiselStage.elaborate { new Padder }
- }
-
- ignore("PadderTester should return the correct result") {}
-}
diff --git a/src/test/scala/chiselTests/ParameterizedModule.scala b/src/test/scala/chiselTests/ParameterizedModule.scala
deleted file mode 100644
index 3ad054f8..00000000
--- a/src/test/scala/chiselTests/ParameterizedModule.scala
+++ /dev/null
@@ -1,40 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.testers.BasicTester
-
-class ParameterizedModule(invert: Boolean) extends Module {
- val io = IO(new Bundle {
- val in = Input(Bool())
- val out = Output(Bool())
- })
- if (invert) {
- io.out := !io.in
- } else {
- io.out := io.in
- }
-}
-
-/** A simple test to check Module deduplication doesn't affect correctness (two
- * modules with the same name but different contents aren't aliased). Doesn't
- * check that deduplication actually happens, though.
- */
-class ParameterizedModuleTester() extends BasicTester {
- val invert = Module(new ParameterizedModule(true))
- val noninvert = Module(new ParameterizedModule(false))
-
- invert.io.in := true.B
- noninvert.io.in := true.B
- assert(invert.io.out === false.B)
- assert(noninvert.io.out === true.B)
-
- stop()
-}
-
-class ParameterizedModuleSpec extends ChiselFlatSpec {
- "Different parameterized modules" should "have different behavior" in {
- assertTesterPasses(new ParameterizedModuleTester())
- }
-}
diff --git a/src/test/scala/chiselTests/PopCount.scala b/src/test/scala/chiselTests/PopCount.scala
deleted file mode 100644
index eaea7a2c..00000000
--- a/src/test/scala/chiselTests/PopCount.scala
+++ /dev/null
@@ -1,25 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.util.PopCount
-import chisel3.testers.BasicTester
-
-class PopCountTester(n: Int) extends BasicTester {
- val x = RegInit(0.U(n.W))
- x := x + 1.U
- when(RegNext(x === ~0.U(n.W))) { stop() }
-
- val result = PopCount(x.asBools)
- val expected = x.asBools.foldLeft(0.U)(_ +& _)
- assert(result === expected)
-
- require(result.getWidth == BigInt(n).bitLength)
-}
-
-class PopCountSpec extends ChiselPropSpec {
- property("Mul lookup table should return the correct result") {
- forAll(smallPosInts) { (n: Int) => assertTesterPasses { new PopCountTester(n) } }
- }
-}
diff --git a/src/test/scala/chiselTests/PrintableSpec.scala b/src/test/scala/chiselTests/PrintableSpec.scala
deleted file mode 100644
index 8039918d..00000000
--- a/src/test/scala/chiselTests/PrintableSpec.scala
+++ /dev/null
@@ -1,393 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.experimental.ChiselAnnotation
-import chisel3.stage.ChiselStage
-import chisel3.testers.BasicTester
-import firrtl.annotations.{ReferenceTarget, SingleTargetAnnotation}
-import org.scalatest.flatspec.AnyFlatSpec
-import org.scalatest.matchers.should.Matchers
-import chisel3.util._
-import org.scalactic.source.Position
-import java.io.File
-
-/** Dummy [[printf]] annotation.
- * @param target target of component to be annotated
- */
-case class PrintfAnnotation(target: ReferenceTarget) extends SingleTargetAnnotation[ReferenceTarget] {
- def duplicate(n: ReferenceTarget): PrintfAnnotation = this.copy(target = n)
-}
-
-object PrintfAnnotation {
-
- /** Create annotation for a given [[printf]].
- * @param c component to be annotated
- */
- def annotate(c: VerificationStatement): Unit = {
- chisel3.experimental.annotate(new ChiselAnnotation {
- def toFirrtl: PrintfAnnotation = PrintfAnnotation(c.toTarget)
- })
- }
-}
-
-/* Printable Tests */
-class PrintableSpec extends AnyFlatSpec with Matchers with Utils {
- // This regex is brittle, it specifically finds the clock and enable signals followed by commas
- private val PrintfRegex = """\s*printf\(\w+, [^,]+,(.*)\).*""".r
- private val StringRegex = """([^"]*)"(.*?)"(.*)""".r
- private case class Printf(str: String, args: Seq[String])
- private def getPrintfs(firrtl: String): Seq[Printf] = {
- def processArgs(str: String): Seq[String] =
- str.split(",").map(_.trim).filter(_.nonEmpty)
- def processBody(str: String): (String, Seq[String]) = {
- str match {
- case StringRegex(_, fmt, args) =>
- (fmt, processArgs(args))
- case _ => fail(s"Regex to process Printf should work on $str!")
- }
- }
- firrtl.split("\n").collect {
- case PrintfRegex(matched) =>
- val (str, args) = processBody(matched)
- Printf(str, args)
- }
- }
-
- // Generates firrtl, gets Printfs
- // Calls fail() if failed match; else calls the partial function which could have its own check
- private def generateAndCheck(gen: => RawModule)(check: PartialFunction[Seq[Printf], Unit])(implicit pos: Position) = {
- val firrtl = ChiselStage.emitChirrtl(gen)
- val printfs = getPrintfs(firrtl)
- if (!check.isDefinedAt(printfs)) {
- fail()
- } else {
- check(printfs)
- }
- }
-
- behavior.of("Printable & Custom Interpolator")
-
- it should "pass exact strings through" in {
- class MyModule extends BasicTester {
- printf(p"An exact string")
- }
- generateAndCheck(new MyModule) {
- case Seq(Printf("An exact string", Seq())) =>
- }
- }
- it should "handle Printable and String concatination" in {
- class MyModule extends BasicTester {
- printf(p"First " + PString("Second ") + "Third")
- }
- generateAndCheck(new MyModule) {
- case Seq(Printf("First Second Third", Seq())) =>
- }
- }
- it should "call toString on non-Printable objects" in {
- class MyModule extends BasicTester {
- val myInt = 1234
- printf(p"myInt = $myInt")
- }
- generateAndCheck(new MyModule) {
- case Seq(Printf("myInt = 1234", Seq())) =>
- }
- }
- it should "generate proper printf for simple Decimal printing" in {
- class MyModule extends BasicTester {
- val myWire = WireDefault(1234.U)
- printf(p"myWire = ${Decimal(myWire)}")
- }
- generateAndCheck(new MyModule) {
- case Seq(Printf("myWire = %d", Seq("myWire"))) =>
- }
- }
- it should "handle printing literals" in {
- class MyModule extends BasicTester {
- printf(Decimal(10.U(32.W)))
- }
- generateAndCheck(new MyModule) {
- case Seq(Printf("%d", Seq(lit))) =>
- assert(lit contains "UInt<32>")
- }
- }
- it should "correctly escape percent" in {
- class MyModule extends BasicTester {
- printf(p"%")
- }
- generateAndCheck(new MyModule) {
- case Seq(Printf("%%", Seq())) =>
- }
- }
- it should "correctly emit tab" in {
- class MyModule extends BasicTester {
- printf(p"\t")
- }
- generateAndCheck(new MyModule) {
- case Seq(Printf("\\t", Seq())) =>
- }
- }
- it should "support names of circuit elements including submodule IO" in {
- // Submodule IO is a subtle issue because the Chisel element has a different
- // parent module
- class MySubModule extends Module {
- val io = IO(new Bundle {
- val fizz = UInt(32.W)
- })
- }
- class MyBundle extends Bundle {
- val foo = UInt(32.W)
- }
- class MyModule extends BasicTester {
- override def desiredName: String = "MyModule"
- val myWire = Wire(new MyBundle)
- val myInst = Module(new MySubModule)
- printf(p"${Name(myWire.foo)}")
- printf(p"${FullName(myWire.foo)}")
- printf(p"${FullName(myInst.io.fizz)}")
- }
- generateAndCheck(new MyModule) {
- case Seq(Printf("foo", Seq()), Printf("myWire.foo", Seq()), Printf("myInst.io.fizz", Seq())) =>
- }
- }
- it should "handle printing ports of submodules" in {
- class MySubModule extends Module {
- val io = IO(new Bundle {
- val fizz = UInt(32.W)
- })
- }
- class MyModule extends BasicTester {
- val myInst = Module(new MySubModule)
- printf(p"${myInst.io.fizz}")
- }
- generateAndCheck(new MyModule) {
- case Seq(Printf("%d", Seq("myInst.io.fizz"))) =>
- }
- }
- it should "print UInts and SInts as Decimal by default" in {
- class MyModule extends BasicTester {
- val myUInt = WireDefault(0.U)
- val mySInt = WireDefault(-1.S)
- printf(p"$myUInt & $mySInt")
- }
- generateAndCheck(new MyModule) {
- case Seq(Printf("%d & %d", Seq("myUInt", "mySInt"))) =>
- }
- }
- it should "print Vecs like Scala Seqs by default" in {
- class MyModule extends BasicTester {
- val myVec = Wire(Vec(4, UInt(32.W)))
- myVec.foreach(_ := 0.U)
- printf(p"$myVec")
- }
- generateAndCheck(new MyModule) {
- case Seq(Printf("Vec(%d, %d, %d, %d)", Seq("myVec[0]", "myVec[1]", "myVec[2]", "myVec[3]"))) =>
- }
- }
- it should "print Bundles like Scala Maps by default" in {
- class MyModule extends BasicTester {
- val myBun = Wire(new Bundle {
- val foo = UInt(32.W)
- val bar = UInt(32.W)
- })
- myBun.foo := 0.U
- myBun.bar := 0.U
- printf(p"$myBun")
- }
- generateAndCheck(new MyModule) {
- case Seq(Printf("AnonymousBundle(foo -> %d, bar -> %d)", Seq("myBun.foo", "myBun.bar"))) =>
- }
- }
- it should "get emitted with a name and annotated" in {
-
- /** Test circuit containing annotated and renamed [[printf]]s. */
- class PrintfAnnotationTest extends Module {
- val myBun = Wire(new Bundle {
- val foo = UInt(32.W)
- val bar = UInt(32.W)
- })
- myBun.foo := 0.U
- myBun.bar := 0.U
- val howdy = printf(p"hello ${myBun}")
- PrintfAnnotation.annotate(howdy)
- PrintfAnnotation.annotate(printf(p"goodbye $myBun"))
- PrintfAnnotation.annotate(printf(p"adieu $myBun").suggestName("farewell"))
- }
-
- // compile circuit
- val testDir = new File("test_run_dir", "PrintfAnnotationTest")
- (new ChiselStage).emitSystemVerilog(
- gen = new PrintfAnnotationTest,
- args = Array("-td", testDir.getPath)
- )
-
- // read in annotation file
- val annoFile = new File(testDir, "PrintfAnnotationTest.anno.json")
- annoFile should exist
- val annoLines = scala.io.Source.fromFile(annoFile).getLines.toList
-
- // check for expected annotations
- exactly(3, annoLines) should include("chiselTests.PrintfAnnotation")
- exactly(1, annoLines) should include("~PrintfAnnotationTest|PrintfAnnotationTest>farewell")
- exactly(1, annoLines) should include("~PrintfAnnotationTest|PrintfAnnotationTest>printf")
- exactly(1, annoLines) should include("~PrintfAnnotationTest|PrintfAnnotationTest>howdy")
-
- // read in FIRRTL file
- val firFile = new File(testDir, "PrintfAnnotationTest.fir")
- firFile should exist
- val firLines = scala.io.Source.fromFile(firFile).getLines.toList
-
- // check that verification components have expected names
- exactly(1, firLines) should include(
- """printf(clock, UInt<1>("h1"), "hello AnonymousBundle(foo -> %d, bar -> %d)", myBun.foo, myBun.bar) : howdy"""
- )
- exactly(1, firLines) should include(
- """printf(clock, UInt<1>("h1"), "goodbye AnonymousBundle(foo -> %d, bar -> %d)", myBun.foo, myBun.bar) : printf"""
- )
- exactly(1, firLines) should include(
- """printf(clock, UInt<1>("h1"), "adieu AnonymousBundle(foo -> %d, bar -> %d)", myBun.foo, myBun.bar) : farewell"""
- )
- }
-
- // Unit tests for cf
- it should "print regular scala variables with cf format specifier" in {
-
- class MyModule extends BasicTester {
- val f1 = 20.4517
- val i1 = 10
- val str1 = "String!"
- printf(
- cf"F1 = $f1 D1 = $i1 F1 formatted = $f1%2.2f str1 = $str1%s i1_str = $i1%s i1_hex=$i1%x"
- )
-
- }
-
- generateAndCheck(new MyModule) {
- case Seq(Printf("F1 = 20.4517 D1 = 10 F1 formatted = 20.45 str1 = String! i1_str = 10 i1_hex=a", Seq())) =>
- }
- }
-
- it should "print chisel bits with cf format specifier" in {
-
- class MyBundle extends Bundle {
- val foo = UInt(32.W)
- val bar = UInt(32.W)
- override def toPrintable: Printable = {
- cf"Bundle : " +
- cf"Foo : $foo%x Bar : $bar%x"
- }
- }
- class MyModule extends BasicTester {
- val b1 = 10.U
- val w1 = Wire(new MyBundle)
- w1.foo := 5.U
- w1.bar := 10.U
- printf(cf"w1 = $w1")
- }
- generateAndCheck(new MyModule) {
- case Seq(Printf("w1 = Bundle : Foo : %x Bar : %x", Seq("w1.foo", "w1.bar"))) =>
- }
- }
-
- it should "support names of circuit elements using format specifier including submodule IO with cf format specifier" in {
- // Submodule IO is a subtle issue because the Chisel element has a different
- // parent module
- class MySubModule extends Module {
- val io = IO(new Bundle {
- val fizz = UInt(32.W)
- })
- }
- class MyBundle extends Bundle {
- val foo = UInt(32.W)
- }
- class MyModule extends BasicTester {
- override def desiredName: String = "MyModule"
- val myWire = Wire(new MyBundle)
- val myInst = Module(new MySubModule)
- printf(cf"${myWire.foo}%n")
- printf(cf"${myWire.foo}%N")
- printf(cf"${myInst.io.fizz}%N")
- }
- generateAndCheck(new MyModule) {
- case Seq(Printf("foo", Seq()), Printf("myWire.foo", Seq()), Printf("myInst.io.fizz", Seq())) =>
- }
- }
-
- it should "correctly print strings after modifier" in {
- class MyModule extends BasicTester {
- val b1 = 10.U
- printf(cf"This is here $b1%x!!!! And should print everything else")
- }
- generateAndCheck(new MyModule) {
- case Seq(Printf("This is here %x!!!! And should print everything else", Seq("UInt<4>(\"ha\")"))) =>
- }
- }
-
- it should "correctly print strings with a lot of literal %% and different format specifiers for Wires" in {
- class MyModule extends BasicTester {
- val b1 = 10.U
- val b2 = 20.U
- printf(cf"%% $b1%x%%$b2%b = ${b1 % b2}%d %%%% Tail String")
- }
-
- generateAndCheck(new MyModule) {
- case Seq(Printf("%% %x%%%b = %d %%%% Tail String", Seq(lita, litb, _))) =>
- assert(lita.contains("UInt<4>") && litb.contains("UInt<5>"))
- }
- }
-
- it should "not allow unescaped % in the message" in {
- class MyModule extends BasicTester {
- printf(cf"This should error out for sure because of % - it should be %%")
- }
- a[java.util.UnknownFormatConversionException] should be thrownBy {
- extractCause[java.util.UnknownFormatConversionException] {
- ChiselStage.elaborate { new MyModule }
- }
- }
- }
-
- it should "allow Printables to be expanded and used" in {
- class MyModule extends BasicTester {
- val w1 = 20.U
- val f1 = 30.2
- val i1 = 14
- val pable = cf"w1 = $w1%b f1 = $f1%2.2f"
- printf(cf"Trying to expand printable $pable and mix with i1 = $i1%d")
- }
- generateAndCheck(new MyModule) {
- case Seq(Printf("Trying to expand printable w1 = %b f1 = 30.20 and mix with i1 = 14", Seq(lit))) =>
- assert(lit.contains("UInt<5>"))
- }
- }
-
- it should "fail with a single % in the message" in {
- class MyModule extends BasicTester {
- printf(cf"%")
- }
- a[java.util.UnknownFormatConversionException] should be thrownBy {
- extractCause[java.util.UnknownFormatConversionException] {
- ChiselStage.elaborate { new MyModule }
- }
- }
- }
-
- it should "fail when passing directly to StirngContext.cf a string with literal \\ correctly escaped " in {
- a[StringContext.InvalidEscapeException] should be thrownBy {
- extractCause[StringContext.InvalidEscapeException] {
- val s_seq = Seq("Test with literal \\ correctly escaped")
- StringContext(s_seq: _*).cf(Seq(): _*)
- }
- }
- }
-
- it should "pass correctly escaped \\ when using Printable.pack" in {
- class MyModule extends BasicTester {
- printf(Printable.pack("\\ \\]"))
- }
- generateAndCheck(new MyModule) {
- case Seq(Printf("\\\\ \\\\]", Seq())) =>
- }
- }
-}
diff --git a/src/test/scala/chiselTests/Printf.scala b/src/test/scala/chiselTests/Printf.scala
deleted file mode 100644
index 6c9f05f0..00000000
--- a/src/test/scala/chiselTests/Printf.scala
+++ /dev/null
@@ -1,83 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.testers.BasicTester
-import chisel3.stage.ChiselStage
-
-class SinglePrintfTester() extends BasicTester {
- val x = 254.U
- printf("x=%x", x)
- stop()
-}
-
-class ASCIIPrintfTester() extends BasicTester {
- printf((0x20 to 0x7e).map(_.toChar).mkString.replace("%", "%%"))
- stop()
-}
-
-class MultiPrintfTester() extends BasicTester {
- val x = 254.U
- val y = 255.U
- printf("x=%x y=%x", x, y)
- stop()
-}
-
-class ASCIIPrintableTester extends BasicTester {
- printf(PString((0x20 to 0x7e).map(_.toChar).mkString("")))
- stop()
-}
-
-class ScopeTesterModule extends Module {
- val in = IO(Input(UInt(8.W)))
- val out = IO(Output(UInt(8.W)))
- out := in
-
- val w = Wire(UInt(8.W))
- w := 125.U
-
- val p = cf"$in"
- val wp = cf"$w"
-}
-
-class PrintablePrintfScopeTester extends BasicTester {
- ChiselStage.elaborate {
- new Module {
- val mod = Module(new ScopeTesterModule)
- printf(mod.p)
- }
- }
- stop()
-}
-
-class PrintablePrintfWireScopeTester extends BasicTester {
- ChiselStage.elaborate {
- new Module {
- val mod = Module(new ScopeTesterModule)
- printf(mod.wp)
- }
- }
- stop()
-}
-
-class PrintfSpec extends ChiselFlatSpec {
- "A printf with a single argument" should "run" in {
- assertTesterPasses { new SinglePrintfTester }
- }
- "A printf with multiple arguments" should "run" in {
- assertTesterPasses { new MultiPrintfTester }
- }
- "A printf with ASCII characters 1-127" should "run" in {
- assertTesterPasses { new ASCIIPrintfTester }
- }
- "A printf with Printable ASCII characters 1-127" should "run" in {
- assertTesterPasses { new ASCIIPrintableTester }
- }
- "A printf with Printable" should "respect port scopes" in {
- assertTesterPasses { new PrintablePrintfScopeTester }
- }
- "A printf with Printable" should "respect wire scopes" in {
- a[ChiselException] should be thrownBy { assertTesterPasses { new PrintablePrintfWireScopeTester } }
- }
-}
diff --git a/src/test/scala/chiselTests/QueueFlushSpec.scala b/src/test/scala/chiselTests/QueueFlushSpec.scala
deleted file mode 100644
index d70f9605..00000000
--- a/src/test/scala/chiselTests/QueueFlushSpec.scala
+++ /dev/null
@@ -1,294 +0,0 @@
-package chiselTests
-
-import org.scalacheck._
-
-import chisel3._
-import chisel3.testers.{BasicTester, TesterDriver}
-import chisel3.util._
-import chisel3.util.random.LFSR
-import treadle.WriteVcdAnnotation
-
-/** Test elements can be enqueued and dequeued when flush is tied to false
- *
- * @param elements The sequence of elements used in the queue
- * @param queueDepth The max number of entries in the queue
- * @param bitWidth Integer size of the data type used in the queue
- * @param tap Integer tap('seed') for the LFSR
- * @param useSyncReadMem True uses SyncReadMem instead of Mem as an internal memory element
- */
-class ThingsPassThroughFlushQueueTester(
- elements: Seq[Int],
- queueDepth: Int,
- bitWidth: Int,
- tap: Int,
- useSyncReadMem: Boolean)
- extends ThingsPassThroughTester(elements, queueDepth, bitWidth, tap, useSyncReadMem, hasFlush = true)
-
-/** Generic flush queue tester base class
- *
- * @param elements The sequence of elements used in the queue
- * @param queueDepth The max number of entries in the queue
- * @param bitWidth Integer size of the data type used in the queue
- * @param tap Integer tap('seed') for the LFSR
- * @param useSyncReadMem True uses SyncReadMem instead of Mem as an internal memory element
- */
-abstract class FlushQueueTesterBase(
- elements: Seq[Int],
- queueDepth: Int,
- bitWidth: Int,
- tap: Int,
- useSyncReadMem: Boolean)
- extends BasicTester {
- val q = Module(new Queue(UInt(bitWidth.W), queueDepth, hasFlush = true))
- val elems = VecInit(elements.map(_.U))
- val inCnt = Counter(elements.length + 1)
- val outCnt = RegInit(0.U(log2Ceil(elements.length).W))
- val currQCnt = RegInit(0.U(log2Ceil(5).W))
-
- val flush: Bool = WireInit(false.B)
- val flushRegister = RegNext(flush, init = false.B)
- q.io.flush.get := flush
- q.io.enq.valid := (inCnt.value < elements.length.U)
- q.io.deq.ready := LFSR(16)(tap)
-
- q.io.enq.bits := elems(inCnt.value)
- when(q.io.enq.fire) {
- inCnt.inc()
- currQCnt := currQCnt + 1.U //counts how many items have been enqueued
- }
- when(q.io.deq.fire) {
- assert(flushRegister === false.B) //check queue isn't flushed (can't dequeue an empty queue)
- }
- when(flushRegister) { //Internal signal maybe_full is a register so some signals update on the next cycle
- //check that queue gets flushed when queue is full
- assert(q.io.count === 0.U)
- assert(!q.io.deq.valid, "Expected to not be able to dequeue when flush is asserted the previous cycle")
- assert(
- q.io.enq.ready,
- "Expected enqueue to be ready when flush was asserted the previous cycle because queue should be empty"
- )
- }
- when(inCnt.value === elements.length.U) { //stop when all entries are enqueued
- stop()
- }
-}
-
-/** Test queue can flush at random times
- *
- * @param elements The sequence of elements used in the queue
- * @param queueDepth The max number of entries in the queue
- * @param bitWidth Integer size of the data type used in the queue
- * @param tap Integer tap('seed') for the LFSR
- * @param useSyncReadMem True uses SyncReadMem instead of Mem as an internal memory element
- */
-class QueueGetsFlushedTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean)
- extends FlushQueueTesterBase(elements, queueDepth, bitWidth, tap, useSyncReadMem) {
- flush := LFSR(16)((tap + 3) % 16) //testing a flush when flush is called randomly
- val halfCnt = (queueDepth + 1) / 2
-
- when(q.io.deq.fire) {
- //ensure that what comes out is what comes in
- assert(currQCnt <= queueDepth.U)
- assert(elems(outCnt) === q.io.deq.bits)
- outCnt := outCnt + 1.U
- when(currQCnt > 0.U) {
- currQCnt := Mux(q.io.enq.fire, currQCnt, (currQCnt - 1.U))
- }
- }
- when(flush) {
- assert(currQCnt === 0.U || q.io.deq.valid)
- outCnt := outCnt + Mux(q.io.enq.fire, (currQCnt + 1.U), currQCnt)
- currQCnt := 0.U //resets the number of items currently inside queue
- }
-}
-
-/** Test queue can flush when empty
- *
- * @param elements The sequence of elements used in the queue
- * @param queueDepth The max number of entries in the queue
- * @param bitWidth Integer size of the data type used in the queue
- * @param tap Integer tap('seed') for the LFSR
- * @param useSyncReadMem True uses SyncReadMem instead of Mem as an internal memory element
- */
-class EmptyFlushEdgecaseTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean)
- extends FlushQueueTesterBase(elements, queueDepth, bitWidth, tap, useSyncReadMem) {
- val cycleCounter = Counter(elements.length + 1)
- cycleCounter.inc() //counts every cycle
-
- //testing a flush when queue is empty
- flush := (cycleCounter.value === 0.U && inCnt.value === 0.U) //flushed only before anything is enqueued
- q.io.enq.valid := (inCnt.value < elements.length.U) && !flush
-
- when(q.io.deq.fire) {
- assert(elems(outCnt) === q.io.deq.bits)
- outCnt := outCnt + 1.U
- }
-}
-
-/** Test queue can enqueue during a flush
- *
- * @param elements The sequence of elements used in the queue
- * @param queueDepth The max number of entries in the queue
- * @param bitWidth Integer size of the data type used in the queue
- * @param tap Integer tap('seed') for the LFSR
- * @param useSyncReadMem True uses SyncReadMem instead of Mem as an internal memory element
- */
-class EnqueueEmptyFlushEdgecaseTester(
- elements: Seq[Int],
- queueDepth: Int,
- bitWidth: Int,
- tap: Int,
- useSyncReadMem: Boolean)
- extends FlushQueueTesterBase(elements, queueDepth, bitWidth, tap, useSyncReadMem) {
- val cycleCounter = Counter(elements.length + 1)
- val outCounter = Counter(elements.length + 1)
-
- //testing an enqueue during a flush
- flush := (cycleCounter.value === 0.U && inCnt.value === 0.U) //flushed only before anything is enqueued
- cycleCounter.inc() //counts every cycle
-
- when(q.io.deq.fire) {
- //flush and enqueue were both active on the first cycle,
- //so that element is flushed immediately which makes outCnt off by one
- assert(elems(outCounter.value + 1.U) === q.io.deq.bits) //ensure that what comes out is what comes in
- outCounter.inc()
- }
-}
-
-/** Test queue can flush when full
- *
- * @param elements The sequence of elements used in the queue
- * @param queueDepth The max number of entries in the queue
- * @param bitWidth Integer size of the data type used in the queue
- * @param tap Integer tap('seed') for the LFSR
- * @param useSyncReadMem True uses SyncReadMem instead of Mem as an internal memory element
- */
-class FullQueueFlushEdgecaseTester(
- elements: Seq[Int],
- queueDepth: Int,
- bitWidth: Int,
- tap: Int,
- useSyncReadMem: Boolean)
- extends FlushQueueTesterBase(elements, queueDepth, bitWidth, tap, useSyncReadMem) {
-
- //testing a flush when queue is full
- flush := (currQCnt === queueDepth.U)
-
- when(q.io.deq.fire) {
- //ensure that what comes out is what comes in
- assert(currQCnt <= queueDepth.U)
- assert(elems(outCnt) === q.io.deq.bits)
- outCnt := outCnt + 1.U
- when(currQCnt > 0.U) {
- currQCnt := currQCnt - 1.U
- }
- }
- when(flush) {
- outCnt := outCnt + currQCnt
- currQCnt := 0.U //resets the number of items currently inside queue
- assert(currQCnt === 0.U || q.io.deq.valid)
- }
-}
-
-/** Test queue can dequeue on the same cycle as a flush
- *
- * @param elements The sequence of elements used in the queue
- * @param queueDepth The max number of entries in the queue
- * @param bitWidth Integer size of the data type used in the queue
- * @param tap Integer tap('seed') for the LFSR
- * @param useSyncReadMem True uses SyncReadMem instead of Mem as an internal memory element
- */
-class DequeueFullQueueEdgecaseTester(
- elements: Seq[Int],
- queueDepth: Int,
- bitWidth: Int,
- tap: Int,
- useSyncReadMem: Boolean)
- extends FlushQueueTesterBase(elements, queueDepth, bitWidth, tap, useSyncReadMem) {
- //Queue should be able to dequeue when queue is not empty and flush is high
-
- //testing a flush when dequeue is called
- flush := currQCnt === (queueDepth / 2).U
- q.io.enq.valid := !flushRegister
- q.io.deq.ready := flush
-
- when(q.io.deq.fire) {
- //ensure that what comes out is what comes in
- assert(currQCnt <= queueDepth.U)
- assert(elems(outCnt) === q.io.deq.bits)
- assert(currQCnt > 0.U)
- }
- when(flush) {
- //The outcount register is one count behind because the dequeue happens at the same time as the flush
- outCnt := outCnt + currQCnt + 1.U
- currQCnt := 0.U //resets the number of items currently inside queue
- assert(currQCnt === 0.U || q.io.deq.valid)
- }
- when(flushRegister) {
- //check that queue gets flushed when queue is full
- assert(q.io.deq.fire === false.B)
- }
-
-}
-
-class QueueFlushSpec extends ChiselPropSpec {
- // Disable shrinking on error.
- implicit val noShrinkListVal = Shrink[List[Int]](_ => Stream.empty)
- implicit val noShrinkInt = Shrink[Int](_ => Stream.empty)
-
- property("Queue should have things pass through") {
- forAll(vecSizes, safeUIntN(20), Gen.choose(0, 15), Gen.oneOf(true, false)) { (depth, se, tap, isSync) =>
- whenever(se._1 >= 1 && depth >= 1 && se._2.nonEmpty) {
- assertTesterPasses {
- new ThingsPassThroughFlushQueueTester(se._2, depth, se._1, tap, isSync)
- }
- }
- }
- }
- property("Queue should flush when requested") {
- forAll(vecSizes, safeUIntN(20), Gen.choose(0, 15), Gen.oneOf(true, false)) { (depth, se, tap, isSync) =>
- whenever(se._1 >= 1 && depth >= 1 && se._2.nonEmpty) {
- assertTesterPasses {
- new QueueGetsFlushedTester(se._2, depth, se._1, tap, isSync)
- }
- }
- }
- }
- property("Queue flush when queue is empty") {
- forAll(vecSizes, safeUIntN(20), Gen.choose(0, 15), Gen.oneOf(true, false)) { (depth, se, tap, isSync) =>
- whenever(se._1 >= 1 && depth >= 1 && se._2.nonEmpty) {
- assertTesterPasses {
- new EmptyFlushEdgecaseTester(se._2, depth, se._1, tap, isSync)
- }
- }
- }
- }
- property("Test queue can enqueue during a flush") {
- forAll(vecSizes, safeUIntN(20), Gen.choose(0, 15), Gen.oneOf(true, false)) { (depth, se, tap, isSync) =>
- whenever(se._1 >= 1 && depth >= 1 && se._2.nonEmpty) {
- assertTesterPasses {
- new EnqueueEmptyFlushEdgecaseTester(se._2, depth, se._1, tap, isSync)
- }
- }
- }
- }
- property("Queue flush when queue is full") {
- forAll(vecSizes, safeUIntN(20), Gen.choose(0, 15), Gen.oneOf(true, false)) { (depth, se, tap, isSync) =>
- whenever(se._1 >= 1 && depth >= 1 && se._2.nonEmpty) {
- assertTesterPasses {
- new FullQueueFlushEdgecaseTester(se._2, depth, se._1, tap, isSync)
- }
- }
- }
- }
- property("Queue should be able to dequeue when flush is high") {
- forAll(Gen.choose(3, 5), safeUIntN(20), Gen.choose(0, 15), Gen.oneOf(true, false)) { (depth, se, tap, isSync) =>
- whenever(se._1 >= 1 && depth >= 1 && se._2.nonEmpty) {
- assertTesterPasses(
- new DequeueFullQueueEdgecaseTester(se._2, depth, se._1, tap, isSync),
- annotations = Seq(WriteVcdAnnotation)
- )
- }
- }
- }
-}
diff --git a/src/test/scala/chiselTests/QueueSpec.scala b/src/test/scala/chiselTests/QueueSpec.scala
deleted file mode 100644
index eaeb7f01..00000000
--- a/src/test/scala/chiselTests/QueueSpec.scala
+++ /dev/null
@@ -1,294 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import org.scalacheck._
-
-import chisel3._
-import chisel3.testers.BasicTester
-import chisel3.util._
-import chisel3.util.random.LFSR
-
-class ThingsPassThroughTester(
- elements: Seq[Int],
- queueDepth: Int,
- bitWidth: Int,
- tap: Int,
- useSyncReadMem: Boolean,
- hasFlush: Boolean)
- extends BasicTester {
- val q = Module(new Queue(UInt(bitWidth.W), queueDepth, useSyncReadMem = useSyncReadMem, hasFlush = hasFlush))
- val elems = VecInit(elements.map {
- _.asUInt()
- })
- val inCnt = Counter(elements.length + 1)
- val outCnt = Counter(elements.length + 1)
-
- q.io.enq.valid := (inCnt.value < elements.length.U)
- q.io.deq.ready := LFSR(16)(tap)
- q.io.flush.foreach { _ := false.B } //Flush behavior is tested in QueueFlushSpec
- q.io.enq.bits := elems(inCnt.value)
- when(q.io.enq.fire) {
- inCnt.inc()
- }
- when(q.io.deq.fire) {
- //ensure that what comes out is what comes in
- assert(elems(outCnt.value) === q.io.deq.bits)
- outCnt.inc()
- }
- when(outCnt.value === elements.length.U) {
- stop()
- }
-}
-
-class QueueReasonableReadyValid(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean)
- extends BasicTester {
- val q = Module(new Queue(UInt(bitWidth.W), queueDepth, useSyncReadMem = useSyncReadMem))
- val elems = VecInit(elements.map {
- _.asUInt()
- })
- val inCnt = Counter(elements.length + 1)
- val outCnt = Counter(elements.length + 1)
-
- q.io.enq.valid := (inCnt.value < elements.length.U)
- //Queue should be full or ready
- assert(q.io.enq.ready || q.io.count === queueDepth.U)
-
- q.io.deq.ready := LFSR(16)(tap)
- //Queue should be empty or valid
- assert(q.io.deq.valid || q.io.count === 0.U)
-
- q.io.enq.bits := elems(inCnt.value)
- when(q.io.enq.fire) {
- inCnt.inc()
- }
- when(q.io.deq.fire) {
- outCnt.inc()
- }
- when(outCnt.value === elements.length.U) {
- stop()
- }
-}
-
-class CountIsCorrectTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean)
- extends BasicTester {
- val q = Module(new Queue(UInt(bitWidth.W), queueDepth, useSyncReadMem = useSyncReadMem))
- val elems = VecInit(elements.map {
- _.asUInt(bitWidth.W)
- })
- val inCnt = Counter(elements.length + 1)
- val outCnt = Counter(elements.length + 1)
-
- q.io.enq.valid := (inCnt.value < elements.length.U)
- q.io.deq.ready := LFSR(16)(tap)
-
- q.io.enq.bits := elems(inCnt.value)
- when(q.io.enq.fire) {
- inCnt.inc()
- assert(q.io.count === (inCnt.value - outCnt.value))
- }
- when(q.io.deq.fire) {
- outCnt.inc()
- assert(q.io.count === (inCnt.value - outCnt.value))
- }
- //assert(q.io.count === (inCnt.value - outCnt.value))
-
- when(outCnt.value === elements.length.U) {
- stop()
- }
-}
-
-class QueueSinglePipeTester(elements: Seq[Int], bitWidth: Int, tap: Int, useSyncReadMem: Boolean) extends BasicTester {
- val q = Module(new Queue(UInt(bitWidth.W), 1, pipe = true, useSyncReadMem = useSyncReadMem))
- val elems = VecInit(elements.map {
- _.asUInt(bitWidth.W)
- })
- val inCnt = Counter(elements.length + 1)
- val outCnt = Counter(elements.length + 1)
-
- q.io.enq.valid := (inCnt.value < elements.length.U)
- q.io.deq.ready := LFSR(16)(tap)
-
- assert(q.io.enq.ready || (q.io.count === 1.U && !q.io.deq.ready))
-
- q.io.enq.bits := elems(inCnt.value)
- when(q.io.enq.fire) {
- inCnt.inc()
- }
- when(q.io.deq.fire) {
- outCnt.inc()
- }
-
- when(outCnt.value === elements.length.U) {
- stop()
- }
-}
-
-class QueuePipeTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean)
- extends BasicTester {
- val q = Module(new Queue(UInt(bitWidth.W), queueDepth, pipe = true, useSyncReadMem = useSyncReadMem))
- val elems = VecInit(elements.map {
- _.asUInt(bitWidth.W)
- })
- val inCnt = Counter(elements.length + 1)
- val outCnt = Counter(elements.length + 1)
-
- q.io.enq.valid := (inCnt.value < elements.length.U)
- q.io.deq.ready := LFSR(16)(tap)
-
- assert(q.io.enq.ready || (q.io.count === queueDepth.U && !q.io.deq.ready))
-
- q.io.enq.bits := elems(inCnt.value)
- when(q.io.enq.fire) {
- inCnt.inc()
- }
- when(q.io.deq.fire) {
- outCnt.inc()
- }
-
- when(outCnt.value === elements.length.U) {
- stop()
- }
-}
-
-class QueueFlowTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean)
- extends BasicTester {
- val q = Module(new Queue(UInt(bitWidth.W), queueDepth, flow = true, useSyncReadMem = useSyncReadMem))
- val elems = VecInit(elements.map {
- _.asUInt()
- })
- val inCnt = Counter(elements.length + 1)
- val outCnt = Counter(elements.length + 1)
-
- q.io.enq.valid := (inCnt.value < elements.length.U)
- //Queue should be full or ready
- assert(q.io.enq.ready || q.io.count === queueDepth.U)
-
- q.io.deq.ready := LFSR(16)(tap)
- //Queue should be empty or valid
- assert(q.io.deq.valid || (q.io.count === 0.U && !q.io.enq.fire))
-
- q.io.enq.bits := elems(inCnt.value)
- when(q.io.enq.fire) {
- inCnt.inc()
- }
- when(q.io.deq.fire) {
- outCnt.inc()
- }
- when(outCnt.value === elements.length.U) {
- stop()
- }
-}
-
-class QueueFactoryTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean)
- extends BasicTester {
- val enq = Wire(Decoupled(UInt(bitWidth.W)))
- val deq = Queue(enq, queueDepth, useSyncReadMem = useSyncReadMem)
-
- val elems = VecInit(elements.map {
- _.asUInt()
- })
- val inCnt = Counter(elements.length + 1)
- val outCnt = Counter(elements.length + 1)
-
- enq.valid := (inCnt.value < elements.length.U)
- deq.ready := LFSR(16)(tap)
-
- enq.bits := elems(inCnt.value)
- when(enq.fire) {
- inCnt.inc()
- }
- when(deq.fire) {
- //ensure that what comes out is what comes in
- assert(elems(outCnt.value) === deq.bits)
- outCnt.inc()
- }
- when(outCnt.value === elements.length.U) {
- stop()
- }
-}
-
-class QueueSpec extends ChiselPropSpec {
- // Disable shrinking on error.
- implicit val noShrinkListVal = Shrink[List[Int]](_ => Stream.empty)
- implicit val noShrinkInt = Shrink[Int](_ => Stream.empty)
-
- property("Queue should have things pass through") {
- forAll(vecSizes, safeUIntN(20), Gen.choose(0, 15), Gen.oneOf(true, false)) { (depth, se, tap, isSync) =>
- whenever(se._1 >= 1 && depth >= 1 && se._2.nonEmpty) {
- assertTesterPasses {
- new ThingsPassThroughTester(se._2, depth, se._1, tap, isSync, false)
- }
- }
- }
- }
-
- property("Queue should have reasonable ready/valid") {
- forAll(vecSizes, safeUIntN(20), Gen.choose(0, 15), Gen.oneOf(true, false)) { (depth, se, tap, isSync) =>
- whenever(se._1 >= 1 && depth >= 1 && se._2.nonEmpty) {
- assertTesterPasses {
- new QueueReasonableReadyValid(se._2, depth, se._1, tap, isSync)
- }
- }
- }
- }
-
- property("Queue should have correct count") {
- forAll(vecSizes, safeUIntN(20), Gen.choose(0, 15), Gen.oneOf(true, false)) { (depth, se, tap, isSync) =>
- whenever(se._1 >= 1 && depth >= 1 && se._2.nonEmpty) {
- assertTesterPasses {
- new CountIsCorrectTester(se._2, depth, se._1, tap, isSync)
- }
- }
- }
- }
-
- property("Queue pipe should work for 1-element queues") {
- forAll(safeUIntN(20), Gen.choose(0, 15), Gen.oneOf(true, false)) { (se, tap, isSync) =>
- whenever(se._1 >= 1 && se._2.nonEmpty) {
- assertTesterPasses {
- new QueueSinglePipeTester(se._2, se._1, tap, isSync)
- }
- }
- }
- }
-
- property("Queue pipe should work for more general queues") {
- forAll(vecSizes, safeUIntN(20), Gen.choose(0, 15), Gen.oneOf(true, false)) { (depth, se, tap, isSync) =>
- whenever(se._1 >= 1 && depth >= 1 && se._2.nonEmpty) {
- assertTesterPasses {
- new QueuePipeTester(se._2, depth, se._1, tap, isSync)
- }
- }
- }
- }
-
- property("Queue flow should work") {
- forAll(vecSizes, safeUIntN(20), Gen.choose(0, 15), Gen.oneOf(true, false)) { (depth, se, tap, isSync) =>
- whenever(se._1 >= 1 && depth >= 1 && se._2.nonEmpty) {
- assertTesterPasses {
- new QueueFlowTester(se._2, depth, se._1, tap, isSync)
- }
- }
- }
- }
-
- property("Queue companion object factory method should work") {
- forAll(vecSizes, safeUIntN(20), Gen.choose(0, 15), Gen.oneOf(true, false)) { (depth, se, tap, isSync) =>
- whenever(se._1 >= 1 && se._2.nonEmpty) {
- assertTesterPasses {
- new QueueFactoryTester(se._2, depth, se._1, tap, isSync)
- }
- }
- }
- }
-
- property("Queue.irrevocable should elaborate") {
- class IrrevocableQueue extends Module {
- val in = Wire(Decoupled(Bool()))
- val iQueue = Queue.irrevocable(in, 1)
- }
- (new chisel3.stage.phases.Elaborate)
- .transform(Seq(chisel3.stage.ChiselGeneratorAnnotation(() => new IrrevocableQueue)))
- }
-}
diff --git a/src/test/scala/chiselTests/RangeSpec.scala b/src/test/scala/chiselTests/RangeSpec.scala
deleted file mode 100644
index bc723bf6..00000000
--- a/src/test/scala/chiselTests/RangeSpec.scala
+++ /dev/null
@@ -1,12 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.experimental.ChiselRange
-import chisel3.internal.firrtl._
-import firrtl.ir.{Closed, Open}
-import org.scalatest.freespec.AnyFreeSpec
-import org.scalatest.matchers.should.Matchers
-
-class RangeSpec extends AnyFreeSpec with Matchers {}
diff --git a/src/test/scala/chiselTests/RawModuleSpec.scala b/src/test/scala/chiselTests/RawModuleSpec.scala
deleted file mode 100644
index 95687e82..00000000
--- a/src/test/scala/chiselTests/RawModuleSpec.scala
+++ /dev/null
@@ -1,90 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.stage.ChiselStage
-import chisel3.testers.BasicTester
-
-class UnclockedPlusOne extends RawModule {
- val in = IO(Input(UInt(32.W)))
- val out = IO(Output(UInt(32.W)))
-
- out := in + 1.asUInt
-}
-
-class RawModuleTester extends BasicTester {
- val plusModule = Module(new UnclockedPlusOne)
- plusModule.in := 42.U
- assert(plusModule.out === 43.U)
- stop()
-}
-
-class PlusOneModule extends Module {
- val io = IO(new Bundle {
- val in = Input(UInt(32.W))
- val out = Output(UInt(32.W))
- })
- io.out := io.in + 1.asUInt
-}
-
-class RawModuleWithImplicitModule extends RawModule {
- val in = IO(Input(UInt(32.W)))
- val out = IO(Output(UInt(32.W)))
- val clk = IO(Input(Clock()))
- val rst = IO(Input(Bool()))
-
- withClockAndReset(clk, rst) {
- val plusModule = Module(new PlusOneModule)
- plusModule.io.in := in
- out := plusModule.io.out
- }
-}
-
-class ImplicitModuleInRawModuleTester extends BasicTester {
- val plusModule = Module(new RawModuleWithImplicitModule)
- plusModule.clk := clock
- plusModule.rst := reset
- plusModule.in := 42.U
- assert(plusModule.out === 43.U)
- stop()
-}
-
-class RawModuleWithDirectImplicitModule extends RawModule {
- val plusModule = Module(new PlusOneModule)
-}
-
-class ImplicitModuleDirectlyInRawModuleTester extends BasicTester {
- val plusModule = Module(new RawModuleWithDirectImplicitModule)
- stop()
-}
-
-class RawModuleSpec extends ChiselFlatSpec with Utils {
- "RawModule" should "elaborate" in {
- ChiselStage.elaborate { new RawModuleWithImplicitModule }
- }
-
- "RawModule" should "work" in {
- assertTesterPasses({ new RawModuleTester })
- }
-
- "ImplicitModule in a withClock block in a RawModule" should "work" in {
- assertTesterPasses({ new ImplicitModuleInRawModuleTester })
- }
-
- "ImplicitModule directly in a RawModule" should "fail" in {
- intercept[chisel3.internal.ChiselException] {
- extractCause[ChiselException] {
- ChiselStage.elaborate { new RawModuleWithDirectImplicitModule }
- }
- }
- }
-
- "ImplicitModule directly in a RawModule in an ImplicitModule" should "fail" in {
- intercept[chisel3.internal.ChiselException] {
- extractCause[ChiselException] {
- ChiselStage.elaborate { new ImplicitModuleDirectlyInRawModuleTester }
- }
- }
- }
-}
diff --git a/src/test/scala/chiselTests/RebindingSpec.scala b/src/test/scala/chiselTests/RebindingSpec.scala
deleted file mode 100644
index 5dc0589e..00000000
--- a/src/test/scala/chiselTests/RebindingSpec.scala
+++ /dev/null
@@ -1,32 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.stage.ChiselStage
-
-class RebindingSpec extends ChiselFlatSpec with Utils {
- "Rebinding a literal" should "fail" in {
- a[BindingException] should be thrownBy extractCause[BindingException] {
- ChiselStage.elaborate {
- new Module {
- val io = IO(new Bundle {
- val a = 4.U
- })
- }
- }
- }
- }
-
- "Rebinding a hardware type" should "fail" in {
- 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
deleted file mode 100644
index 5a5bcf67..00000000
--- a/src/test/scala/chiselTests/RecordSpec.scala
+++ /dev/null
@@ -1,416 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.stage.ChiselStage
-import chisel3.testers.BasicTester
-import chisel3.util.{Counter, Queue}
-import chisel3.experimental.{DataMirror, OpaqueType}
-
-import scala.collection.immutable.SeqMap
-
-trait RecordSpecUtils {
- class MyBundle extends Bundle {
- val foo = UInt(32.W)
- val bar = UInt(32.W)
- }
- // Useful for constructing types from CustomBundle
- // This is a def because each call to this needs to return a new instance
- def fooBarType: CustomBundle = new CustomBundle("foo" -> UInt(32.W), "bar" -> UInt(32.W))
-
- class MyModule(output: => Record, input: => Record) extends Module {
- val io = IO(new Bundle {
- val in = Input(input)
- val out = Output(output)
- })
- io.out <> io.in
- }
-
- class ConnectionTestModule(output: => Record, input: => Record) extends Module {
- val io = IO(new Bundle {
- val inMono = Input(input)
- val outMono = Output(output)
- val inBi = Input(input)
- val outBi = Output(output)
- })
- io.outMono := io.inMono
- io.outBi <> io.inBi
- }
-
- class RecordSerializationTest extends BasicTester {
- val recordType = new CustomBundle("fizz" -> UInt(16.W), "buzz" -> UInt(16.W))
- val record = Wire(recordType)
- // Note that "buzz" was added later than "fizz" and is therefore higher order
- record("fizz") := "hdead".U
- record("buzz") := "hbeef".U
- // To UInt
- val uint = record.asUInt
- assert(uint.getWidth == 32) // elaboration time
- assert(uint === "hbeefdead".U)
- // Back to Record
- val record2 = uint.asTypeOf(recordType)
- assert("hdead".U === record2("fizz").asUInt)
- assert("hbeef".U === record2("buzz").asUInt)
- stop()
- }
-
- class RecordQueueTester extends BasicTester {
- val queue = Module(new Queue(fooBarType, 4))
- queue.io <> DontCare
- queue.io.enq.valid := false.B
- val (cycle, done) = Counter(true.B, 4)
-
- when(cycle === 0.U) {
- queue.io.enq.bits("foo") := 1234.U
- queue.io.enq.bits("bar") := 5678.U
- queue.io.enq.valid := true.B
- }
- when(cycle === 1.U) {
- queue.io.deq.ready := true.B
- assert(queue.io.deq.valid === true.B)
- assert(queue.io.deq.bits("foo").asUInt === 1234.U)
- assert(queue.io.deq.bits("bar").asUInt === 5678.U)
- }
- when(done) {
- stop()
- }
- }
-
- class AliasedRecord extends Module {
- val field = UInt(32.W)
- val io = IO(new CustomBundle("in" -> Input(field), "out" -> Output(field)))
- }
-
- class RecordIOModule extends Module {
- val io = IO(new CustomBundle("in" -> Input(UInt(32.W)), "out" -> Output(UInt(32.W))))
- io("out") := io("in")
- }
-
- class RecordIOTester extends BasicTester {
- val mod = Module(new RecordIOModule)
- mod.io("in") := 1234.U
- assert(mod.io("out").asUInt === 1234.U)
- stop()
- }
-
- class RecordDigitTester extends BasicTester {
- val wire = Wire(new CustomBundle("0" -> UInt(32.W)))
- wire("0") := 123.U
- assert(wire("0").asUInt === 123.U)
- stop()
- }
-
- class RecordTypeTester extends BasicTester {
- val wire0 = Wire(new CustomBundle("0" -> UInt(32.W)))
- val wire1 = Reg(new CustomBundle("0" -> UInt(32.W)))
- val wire2 = Wire(new CustomBundle("1" -> UInt(32.W)))
- require(DataMirror.checkTypeEquivalence(wire0, wire1))
- require(!DataMirror.checkTypeEquivalence(wire1, wire2))
- }
-
- class SingleElementRecord extends Record with OpaqueType {
- private val underlying = UInt(8.W)
- val elements = SeqMap("" -> underlying)
- override def cloneType: this.type = (new SingleElementRecord).asInstanceOf[this.type]
-
- def +(that: SingleElementRecord): SingleElementRecord = {
- val _w = Wire(new SingleElementRecord)
- _w.underlying := this.underlying + that.underlying
- _w
- }
- }
-
- class SingleElementRecordModule extends Module {
- val in1 = IO(Input(new SingleElementRecord))
- val in2 = IO(Input(new SingleElementRecord))
- val out = IO(Output(new SingleElementRecord))
-
- val r = new SingleElementRecord
-
- out := in1 + in2
- }
-
- class InnerRecord extends Record with OpaqueType {
- val k = new InnerInnerRecord
- val elements = SeqMap("" -> k)
- override def cloneType: this.type = (new InnerRecord).asInstanceOf[this.type]
- }
-
- class InnerInnerRecord extends Record with OpaqueType {
- val k = new SingleElementRecord
- val elements = SeqMap("" -> k)
- override def cloneType: this.type = (new InnerInnerRecord).asInstanceOf[this.type]
- }
-
- class NestedRecordModule extends Module {
- val in = IO(Input(new InnerRecord))
- val out = IO(Output(new InnerRecord))
- val inst = Module(new InnerModule)
- inst.io.foo := in
- out := inst.io.bar
- }
- class InnerModule extends Module {
- val io = IO(new Bundle {
- val foo = Input(new InnerRecord)
- val bar = Output(new InnerRecord)
- })
-
- // DO NOT do this; just for testing element connections
- io.bar.elements.head._2 := io.foo.elements.head._2
- }
-
- class NamedSingleElementRecord extends Record with OpaqueType {
- private val underlying = UInt(8.W)
- val elements = SeqMap("unused" -> underlying)
-
- override def cloneType: this.type = (new NamedSingleElementRecord).asInstanceOf[this.type]
- }
-
- class NamedSingleElementModule extends Module {
- val in = IO(Input(new NamedSingleElementRecord))
- val out = IO(Output(new NamedSingleElementRecord))
- out := in
- }
-
- class ErroneousOverride extends Record with OpaqueType {
- private val underlyingA = UInt(8.W)
- private val underlyingB = UInt(8.W)
- val elements = SeqMap("x" -> underlyingA, "y" -> underlyingB)
-
- override def opaqueType = true
- override def cloneType: this.type = (new ErroneousOverride).asInstanceOf[this.type]
- }
-
- class ErroneousOverrideModule extends Module {
- val in = IO(Input(new ErroneousOverride))
- val out = IO(Output(new ErroneousOverride))
- out := in
- }
-
- class NotActuallyOpaqueType extends Record with OpaqueType {
- private val underlyingA = UInt(8.W)
- private val underlyingB = UInt(8.W)
- val elements = SeqMap("x" -> underlyingA, "y" -> underlyingB)
-
- override def opaqueType = false
- override def cloneType: this.type = (new NotActuallyOpaqueType).asInstanceOf[this.type]
- }
-
- class NotActuallyOpaqueTypeModule extends Module {
- val in = IO(Input(new NotActuallyOpaqueType))
- val out = IO(Output(new NotActuallyOpaqueType))
- out := in
- }
-
- // Illustrate how to dyanmically decide between OpaqueType or not
- sealed trait MaybeBoxed[T <: Data] extends Record {
- def underlying: T
- def boxed: Boolean
- }
- object MaybeBoxed {
- def apply[T <: Data](gen: T, boxed: Boolean): MaybeBoxed[T] = {
- if (boxed) new Boxed(gen) else new Unboxed(gen)
- }
- }
- class Boxed[T <: Data](gen: T) extends MaybeBoxed[T] {
- def boxed = true
- lazy val elements = SeqMap("underlying" -> gen.cloneType)
- def underlying = elements.head._2
- override def cloneType: this.type = (new Boxed(gen)).asInstanceOf[this.type]
- }
- class Unboxed[T <: Data](gen: T) extends MaybeBoxed[T] with OpaqueType {
- def boxed = false
- lazy val elements = SeqMap("" -> gen.cloneType)
- def underlying = elements.head._2
- override def cloneType: this.type = (new Unboxed(gen)).asInstanceOf[this.type]
- }
-}
-
-class RecordSpec extends ChiselFlatSpec with RecordSpecUtils with Utils {
- behavior.of("Records")
-
- they should "bulk connect similarly to Bundles" in {
- ChiselStage.elaborate { new MyModule(fooBarType, fooBarType) }
- }
-
- they should "bulk connect to Bundles" in {
- ChiselStage.elaborate { new MyModule(new MyBundle, fooBarType) }
- }
-
- they should "emit FIRRTL bulk connects when possible" in {
- val chirrtl = (new ChiselStage).emitChirrtl(
- gen = new ConnectionTestModule(fooBarType, fooBarType)
- )
- chirrtl should include("io.outMono <= io.inMono @[RecordSpec.scala")
- chirrtl should include("io.outBi <= io.inBi @[RecordSpec.scala")
- }
-
- they should "not allow aliased fields" in {
- class AliasedFieldRecord extends Record {
- val foo = UInt(8.W)
- val elements = SeqMap("foo" -> foo, "bar" -> foo)
- override def cloneType: AliasedFieldRecord.this.type = (new AliasedFieldRecord).asInstanceOf[this.type]
- }
-
- val e = intercept[AliasedAggregateFieldException] {
- ChiselStage.elaborate {
- new Module {
- val io = IO(new AliasedFieldRecord)
- }
- }
- }
- e.getMessage should include("contains aliased fields named (bar,foo)")
- }
-
- they should "support OpaqueType for maps with single unnamed elements" in {
- val singleElementChirrtl = ChiselStage.emitChirrtl { new SingleElementRecordModule }
- singleElementChirrtl should include("input in1 : UInt<8>")
- singleElementChirrtl should include("input in2 : UInt<8>")
- singleElementChirrtl should include("add(in1, in2)")
- }
-
- they should "work correctly for toTarget in nested OpaqueType Records" in {
- var mod: NestedRecordModule = null
- ChiselStage.elaborate { mod = new NestedRecordModule; mod }
- val testStrings = Seq(
- mod.inst.io.foo.toTarget.serialize,
- mod.inst.io.foo.k.toTarget.serialize,
- mod.inst.io.foo.k.k.toTarget.serialize,
- mod.inst.io.foo.elements.head._2.toTarget.serialize,
- mod.inst.io.foo.k.elements.head._2.toTarget.serialize,
- mod.inst.io.foo.k.k.elements.head._2.toTarget.serialize
- )
- testStrings.foreach(x => assert(x == "~NestedRecordModule|InnerModule>io.foo"))
- }
-
- they should "work correctly with DataMirror in nested OpaqueType Records" in {
- var mod: NestedRecordModule = null
- ChiselStage.elaborate { mod = new NestedRecordModule; mod }
- val ports = chisel3.experimental.DataMirror.fullModulePorts(mod.inst)
- val expectedPorts = Seq(
- ("clock", mod.inst.clock),
- ("reset", mod.inst.reset),
- ("io", mod.inst.io),
- ("io_bar", mod.inst.io.bar),
- ("io_bar", mod.inst.io.bar.k),
- ("io_bar", mod.inst.io.bar.k.k),
- ("io_bar", mod.inst.io.bar.k.k.elements.head._2),
- ("io_foo", mod.inst.io.foo),
- ("io_foo", mod.inst.io.foo.k),
- ("io_foo", mod.inst.io.foo.k.k),
- ("io_foo", mod.inst.io.foo.k.k.elements.head._2)
- )
- ports shouldBe expectedPorts
- }
-
- they should "work correctly when connecting nested OpaqueType elements" in {
- val nestedRecordChirrtl = ChiselStage.emitChirrtl { new NestedRecordModule }
- nestedRecordChirrtl should include("input in : UInt<8>")
- nestedRecordChirrtl should include("output out : UInt<8>")
- nestedRecordChirrtl should include("inst.io.foo <= in")
- nestedRecordChirrtl should include("out <= inst.io.bar")
- nestedRecordChirrtl should include("output io : { flip foo : UInt<8>, bar : UInt<8>}")
- nestedRecordChirrtl should include("io.bar <= io.foo")
- }
-
- they should "throw an error when map contains a named element and OpaqueType is mixed in" in {
- (the[Exception] thrownBy extractCause[Exception] {
- ChiselStage.elaborate { new NamedSingleElementModule }
- }).getMessage should include("Opaque types must have exactly one element with an empty name")
- }
-
- they should "throw an error when map contains more than one element and OpaqueType is mixed in" in {
- (the[Exception] thrownBy extractCause[Exception] {
- ChiselStage.elaborate { new ErroneousOverrideModule }
- }).getMessage should include("Opaque types must have exactly one element with an empty name")
- }
-
- they should "work correctly when an OpaqueType overrides the def as false" in {
- val chirrtl = ChiselStage.emitChirrtl(new NotActuallyOpaqueTypeModule)
- chirrtl should include("input in : { y : UInt<8>, x : UInt<8>}")
- chirrtl should include("output out : { y : UInt<8>, x : UInt<8>}")
- chirrtl should include("out <= in")
- }
-
- they should "support conditional OpaqueTypes via traits and factory methods" in {
- class MyModule extends Module {
- val in0 = IO(Input(MaybeBoxed(UInt(8.W), true)))
- val out0 = IO(Output(MaybeBoxed(UInt(8.W), true)))
- val in1 = IO(Input(MaybeBoxed(UInt(8.W), false)))
- val out1 = IO(Output(MaybeBoxed(UInt(8.W), false)))
- out0 := in0
- out1 := in1
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- chirrtl should include("input in0 : { underlying : UInt<8>}")
- chirrtl should include("input in1 : UInt<8>")
- }
-
- they should "work with .toTarget" in {
- var m: SingleElementRecordModule = null
- ChiselStage.elaborate { m = new SingleElementRecordModule; m }
- val q = m.in1.toTarget.toString
- assert(q == "~SingleElementRecordModule|SingleElementRecordModule>in1")
- }
-
- they should "work (but warn) with .toTarget on non-data OpaqueType Record" in {
- var m: SingleElementRecordModule = null
- ChiselStage.elaborate { m = new SingleElementRecordModule; m }
- val (log, q) = grabLog(m.r.toTarget)
- log should include(".toTarget of non-hardware Data is deprecated")
- assert(q.toString == "~SingleElementRecordModule|SingleElementRecordModule>r")
- }
-
- they should "follow UInt serialization/deserialization API" in {
- assertTesterPasses { new RecordSerializationTest }
- }
-
- they should "work as the type of a Queue" in {
- assertTesterPasses { new RecordQueueTester }
- }
-
- they should "work as the type of a Module's io" in {
- assertTesterPasses { new RecordIOTester }
- }
-
- they should "support digits as names of fields" in {
- assertTesterPasses { new RecordDigitTester }
- }
-
- "Bulk connect on Record" should "check that the fields match" in {
- (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 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 {
- ChiselStage.elaborate(new Module {
- val gen = new CustomBundle("foo" -> UInt(32.W))
- val io = IO(Output(gen))
- val wire = Wire(gen)
- io := wire
- })
- }
-
- "CustomBundle" should "check the types" in {
- ChiselStage.elaborate { new RecordTypeTester }
- }
-
- "Record with unstable elements" should "error" in {
- class MyRecord extends Record {
- def elements = SeqMap("a" -> UInt(8.W))
- override def cloneType: this.type = (new MyRecord).asInstanceOf[this.type]
- }
- val e = the[ChiselException] thrownBy {
- ChiselStage.elaborate(new Module {
- val io = IO(Input(new MyRecord))
- })
- }
- e.getMessage should include("does not return the same objects when calling .elements multiple times")
- }
-}
diff --git a/src/test/scala/chiselTests/ReduceTreeSpec.scala b/src/test/scala/chiselTests/ReduceTreeSpec.scala
deleted file mode 100644
index 3f078106..00000000
--- a/src/test/scala/chiselTests/ReduceTreeSpec.scala
+++ /dev/null
@@ -1,106 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.util._
-import chisel3.testers.BasicTester
-
-class Arbiter[T <: Data: Manifest](n: Int, private val gen: T) extends Module {
- val io = IO(new Bundle {
- val in = Flipped(Vec(n, new DecoupledIO(gen)))
- val out = new DecoupledIO(gen)
- })
-
- def arbitrateTwo(a: DecoupledIO[T], b: DecoupledIO[T]) = {
-
- val idleA :: idleB :: hasA :: hasB :: Nil = Enum(4)
- val regData = Reg(gen)
- val regState = RegInit(idleA)
- val out = Wire(new DecoupledIO(gen))
-
- a.ready := regState === idleA
- b.ready := regState === idleB
- out.valid := (regState === hasA || regState === hasB)
-
- switch(regState) {
- is(idleA) {
- when(a.valid) {
- regData := a.bits
- regState := hasA
- }.otherwise {
- regState := idleB
- }
- }
- is(idleB) {
- when(b.valid) {
- regData := b.bits
- regState := hasB
- }.otherwise {
- regState := idleA
- }
- }
- is(hasA) {
- when(out.ready) {
- regState := idleB
- }
- }
- is(hasB) {
- when(out.ready) {
- regState := idleA
- }
- }
- }
-
- out.bits := regData.asUInt + 1.U
- out
- }
-
- io.out <> io.in.reduceTree(arbitrateTwo)
-}
-
-class ReduceTreeBalancedTester(nodes: Int) extends BasicTester {
-
- val cnt = RegInit(0.U(8.W))
- val min = RegInit(99.U(8.W))
- val max = RegInit(0.U(8.W))
-
- val dut = Module(new Arbiter(nodes, UInt(16.W)))
- for (i <- 0 until nodes) {
- dut.io.in(i).valid := true.B
- dut.io.in(i).bits := 0.U
- }
- dut.io.out.ready := true.B
-
- when(dut.io.out.valid) {
- val hops = dut.io.out.bits
- when(hops < min) {
- min := hops
- }
- when(hops > max) {
- max := hops
- }
- }
-
- when(!(max === 0.U || min === 99.U)) {
- assert(max - min <= 1.U)
- }
-
- cnt := cnt + 1.U
- when(cnt === 10.U) {
- stop()
- }
-}
-
-class ReduceTreeBalancedSpec extends ChiselPropSpec {
- property("Tree shall be fair and shall have a maximum difference of one hop for each node") {
-
- // This test will fail for 5 nodes due to an unbalanced tree.
- // A fix is on the way.
- for (n <- 1 to 5) {
- assertTesterPasses {
- new ReduceTreeBalancedTester(n)
- }
- }
- }
-}
diff --git a/src/test/scala/chiselTests/Reg.scala b/src/test/scala/chiselTests/Reg.scala
deleted file mode 100644
index c814a030..00000000
--- a/src/test/scala/chiselTests/Reg.scala
+++ /dev/null
@@ -1,91 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.util._
-import chisel3.experimental.DataMirror
-import chisel3.stage.ChiselStage
-import chisel3.testers.BasicTester
-import org.scalacheck.Gen
-
-class RegSpec extends ChiselFlatSpec {
- "Reg" should "be of the same type and width as t" in {
- class RegOutTypeWidthTester extends BasicTester {
- val reg = Reg(UInt(2.W))
- DataMirror.widthOf(reg) should be(2.W)
- }
- ChiselStage.elaborate { new RegOutTypeWidthTester }
- }
-
- "RegNext" should "be of unknown width" in {
- class RegUnknownWidthTester extends BasicTester {
- val reg1 = RegNext(2.U(3.W))
- DataMirror.widthOf(reg1).known should be(false)
- val reg2 = RegNext(2.U(3.W), 4.U)
- DataMirror.widthOf(reg2).known should be(false)
- val reg3 = RegNext(2.U(3.W), 4.U(5.W))
- DataMirror.widthOf(reg3).known should be(false)
- }
- ChiselStage.elaborate { new RegUnknownWidthTester }
- }
-
- "RegInit" should "have width only if specified in the literal" in {
- class RegForcedWidthTester extends BasicTester {
- val reg1 = RegInit(20.U)
- DataMirror.widthOf(reg1).known should be(false)
- val reg2 = RegInit(20.U(7.W))
- DataMirror.widthOf(reg2) should be(7.W)
- }
- ChiselStage.elaborate { new RegForcedWidthTester }
- }
-}
-
-class ShiftTester(n: Int) extends BasicTester {
- val (cntVal, done) = Counter(true.B, n)
- val start = 23.U
- val sr = ShiftRegister(cntVal + start, n)
- when(done) {
- assert(sr === start)
- stop()
- }
-}
-
-class ShiftResetTester(n: Int) extends BasicTester {
- val (cntVal, done) = Counter(true.B, n - 1)
- val start = 23.U
- val sr = ShiftRegister(cntVal + 23.U, n, 1.U, true.B)
- when(done) {
- assert(sr === (if (n == 0) cntVal + 23.U else 1.U))
- stop()
- }
-}
-
-class ShiftRegisterSpec extends ChiselPropSpec {
- property("ShiftRegister should shift") {
- forAll(Gen.choose(0, 4)) { (shift: Int) => assertTesterPasses { new ShiftTester(shift) } }
- }
-
- property("ShiftRegister should reset all values inside") {
- forAll(Gen.choose(0, 4)) { (shift: Int) => assertTesterPasses { new ShiftResetTester(shift) } }
- }
-}
-
-class ShiftsTester(n: Int) extends BasicTester {
- val (cntVal, done) = Counter(true.B, n)
- val start = 23.U
- val srs = ShiftRegisters(cntVal + start, n)
- when(RegNext(done)) {
- srs.zipWithIndex.foreach {
- case (data, index) =>
- assert(data === (23 + n - 1 - index).U)
- }
- stop()
- }
-}
-
-class ShiftRegistersSpec extends ChiselPropSpec {
- property("ShiftRegisters should shift") {
- forAll(Gen.choose(0, 4)) { (shift: Int) => assertTesterPasses { new ShiftsTester(shift) } }
- }
-}
diff --git a/src/test/scala/chiselTests/ResetSpec.scala b/src/test/scala/chiselTests/ResetSpec.scala
deleted file mode 100644
index fe0273b3..00000000
--- a/src/test/scala/chiselTests/ResetSpec.scala
+++ /dev/null
@@ -1,115 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.stage.ChiselStage
-import chisel3.util.{Counter, Queue}
-import chisel3.testers.BasicTester
-
-class ResetAgnosticModule extends RawModule {
- val clk = IO(Input(Clock()))
- val rst = IO(Input(Reset()))
- val out = IO(Output(UInt(8.W)))
-
- val reg = withClockAndReset(clk, rst)(RegInit(0.U(8.W)))
- reg := reg + 1.U
- out := reg
-}
-
-class AbstractResetDontCareModule extends RawModule {
- import chisel3.util.Valid
- val monoPort = IO(Output(Reset()))
- monoPort := DontCare
- val monoWire = Wire(Reset())
- monoWire := DontCare
- val monoAggPort = IO(Output(Valid(Reset())))
- monoAggPort := DontCare
- val monoAggWire = Wire(Valid(Reset()))
- monoAggWire := DontCare
-
- // Can't bulk connect to Wire so only ports here
- val bulkPort = IO(Output(Reset()))
- bulkPort <> DontCare
- val bulkAggPort = IO(Output(Valid(Reset())))
- bulkAggPort <> DontCare
-}
-
-class ResetSpec extends ChiselFlatSpec with Utils {
-
- behavior.of("Reset")
-
- it should "be able to be connected to DontCare" in {
- ChiselStage.elaborate(new AbstractResetDontCareModule)
- }
-
- it should "be able to drive Bool" in {
- ChiselStage.emitVerilog(new RawModule {
- val in = IO(Input(Bool()))
- val out = IO(Output(Bool()))
- val w = Wire(Reset())
- w := in
- out := w
- })
- }
-
- it should "be able to drive AsyncReset" in {
- ChiselStage.emitVerilog(new RawModule {
- val in = IO(Input(AsyncReset()))
- val out = IO(Output(AsyncReset()))
- val w = Wire(Reset())
- w := in
- out := w
- })
- }
-
- it should "allow writing modules that are reset agnostic" in {
- val sync = compile(new Module {
- val io = IO(new Bundle {
- val out = Output(UInt(8.W))
- })
- val inst = Module(new ResetAgnosticModule)
- inst.clk := clock
- inst.rst := reset
- assert(inst.rst.isInstanceOf[chisel3.ResetType])
- io.out := inst.out
- })
- sync should include("always @(posedge clk)")
-
- val async = compile(new Module {
- val io = IO(new Bundle {
- val out = Output(UInt(8.W))
- })
- val inst = Module(new ResetAgnosticModule)
- inst.clk := clock
- inst.rst := reset.asTypeOf(AsyncReset())
- assert(inst.rst.isInstanceOf[chisel3.ResetType])
- io.out := inst.out
- })
- async should include("always @(posedge clk or posedge rst)")
- }
-
- behavior.of("Users")
-
- they should "be able to force implicit reset to be synchronous" in {
- val fir = ChiselStage.emitChirrtl(new Module 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 = ChiselStage.emitChirrtl(new Module 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] should be thrownBy extractCause[ChiselException] {
- ChiselStage.elaborate(new Module with RequireAsyncReset {
- val mod = Module(new Module with RequireSyncReset)
- })
- }
- }
-}
diff --git a/src/test/scala/chiselTests/Risc.scala b/src/test/scala/chiselTests/Risc.scala
deleted file mode 100644
index e0eacb90..00000000
--- a/src/test/scala/chiselTests/Risc.scala
+++ /dev/null
@@ -1,123 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.stage.ChiselStage
-import chisel3.util._
-
-class Risc extends Module {
- val io = IO(new Bundle {
- val isWr = Input(Bool())
- val wrAddr = Input(UInt(8.W))
- val wrData = Input(Bits(32.W))
- val boot = Input(Bool())
- val valid = Output(Bool())
- val out = Output(Bits(32.W))
- })
- val memSize = 256
- val file = Mem(memSize, Bits(32.W))
- val code = Mem(memSize, Bits(32.W))
- val pc = RegInit(0.U(8.W))
-
- val add_op :: imm_op :: Nil = Enum(2)
-
- val inst = code(pc)
- val op = inst(31, 24)
- val rci = inst(23, 16)
- val rai = inst(15, 8)
- val rbi = inst(7, 0)
-
- val ra = Mux(rai === 0.U, 0.U, file(rai))
- val rb = Mux(rbi === 0.U, 0.U, file(rbi))
- val rc = Wire(Bits(32.W))
-
- io.valid := false.B
- io.out := 0.U
- rc := 0.U
-
- when(io.isWr) {
- code(io.wrAddr) := io.wrData
- }.elsewhen(io.boot) {
- pc := 0.U
- }.otherwise {
- switch(op) {
- is(add_op) { rc := ra +% rb }
- is(imm_op) { rc := (rai << 8) | rbi }
- }
- io.out := rc
- when(rci === 255.U) {
- io.valid := true.B
- }.otherwise {
- file(rci) := rc
- }
- pc := pc +% 1.U
- }
-}
-
-/*
-class RiscTester(c: Risc) extends Tester(c) {
- def wr(addr: BigInt, data: BigInt) = {
- poke(c.io.isWr, 1)
- poke(c.io.wrAddr, addr)
- poke(c.io.wrData, data)
- step(1)
- }
- def boot() = {
- poke(c.io.isWr, 0)
- poke(c.io.boot, 1)
- step(1)
- }
- def tick(isBoot: Boolean) = {
- if (isBoot)
- poke(c.io.boot, 0)
- step(1)
- }
- def I (op: UInt, rc: Int, ra: Int, rb: Int) = {
- // val cr = Cat(op, rc.asUInt(8.W), ra.asUInt(8.W), rb.asUInt(8.W)).litValue()
- val cr = op.litValue() << 24 | rc << 16 | ra << 8 | rb
- println("I = " + cr)
- cr
- }
-
- val app = Array(I(c.imm_op, 1, 0, 1), // r1 <- 1
- I(c.add_op, 1, 1, 1), // r1 <- r1 + r1
- I(c.add_op, 1, 1, 1), // r1 <- r1 + r1
- I(c.add_op, 255, 1, 0)) // rh <- r1
- wr(0, 0) // skip reset
- for (addr <- 0 until app.length)
- wr(addr, app(addr))
- def dump(k: Int) {
- println("K = " + k)
- peek(c.ra)
- peek(c.rb)
- peek(c.rc)
- peek(c.io.out)
- peek(c.pc)
- peek(c.inst)
- peek(c.op)
- peek(c.rci)
- peek(c.rai)
- peek(c.rbi)
- peekAt(c.file, 1)
- }
- boot()
- dump(0)
- var k = 0
- do {
- tick(k == 0); k += 1
- dump(k)
- } while (!(peek(c.io.valid) == 1 || k > 10))
- expect(k <= 10, "TIME LIMIT")
- expect(c.io.out, 4)
-}
- */
-
-class RiscSpec extends ChiselPropSpec {
-
- property("Risc should elaborate") {
- 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
deleted file mode 100644
index ebbd2012..00000000
--- a/src/test/scala/chiselTests/SIntOps.scala
+++ /dev/null
@@ -1,151 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.stage.ChiselStage
-import chisel3.testers.BasicTester
-
-class SIntOps extends Module {
- val io = IO(new Bundle {
- val a = Input(SInt(16.W))
- val b = Input(SInt(16.W))
- val addout = Output(SInt(16.W))
- val subout = Output(SInt(16.W))
- val timesout = Output(SInt(16.W))
- val divout = Output(SInt(16.W))
- val modout = Output(SInt(16.W))
- val lshiftout = Output(SInt(16.W))
- val rshiftout = Output(SInt(16.W))
- val lessout = Output(Bool())
- val greatout = Output(Bool())
- val eqout = Output(Bool())
- val noteqout = Output(Bool())
- val lesseqout = Output(Bool())
- val greateqout = Output(Bool())
- val negout = Output(SInt(16.W))
- })
-
- val a = io.a
- val b = io.b
-
- io.addout := a +% b
- io.subout := a -% b
- // TODO:
- //io.timesout := (a * b)(15, 0)
- //io.divout := a / Mux(b === 0.S, 1.S, b)
- //io.divout := (a / b)(15, 0)
- //io.modout := 0.S
- //io.lshiftout := (a << 12)(15, 0) // (a << ub(3, 0))(15, 0).toSInt
- io.rshiftout := (a >> 8) // (a >> ub).toSInt
- io.lessout := a < b
- io.greatout := a > b
- io.eqout := a === b
- io.noteqout := (a =/= b)
- io.lesseqout := a <= b
- io.greateqout := a >= b
- io.negout := -a(15, 0).asSInt
- io.negout := (0.S -% a)
-}
-
-/*
-class SIntOpsTester(c: SIntOps) extends Tester(c) {
- def sintExpect(d: Bits, x: BigInt) {
- val mask = (1 << 16) - 1
- val sbit = (1 << 15)
- val y = x & mask
- val r = if ((y & sbit) == 0) y else (-(~y)-1)
- expect(d, r)
- }
- for (t <- 0 until 16) {
- val test_a = (1 << 15) - rnd.nextInt(1 << 16)
- val test_b = (1 << 15) - rnd.nextInt(1 << 16)
- poke(c.io.a, test_a)
- poke(c.io.b, test_b)
- step(1)
- sintExpect(c.io.addout, test_a + test_b)
- sintExpect(c.io.subout, test_a - test_b)
- sintExpect(c.io.timesout, test_a * test_b)
- // sintExpect(c.io.divout, if (test_b == 0) 0 else test_a / test_b)
- sintExpect(c.io.divout, test_a * test_b)
- // sintExpect(c.io.modout, test_a % test_b)
- // sintExpect(c.io.lshiftout, test_a << (test_b&15))
- // sintExpect(c.io.rshiftout, test_a >> test_b)
- sintExpect(c.io.lshiftout, test_a << 12)
- sintExpect(c.io.rshiftout, test_a >> 8)
- sintExpect(c.io.negout, -test_a)
- expect(c.io.lessout, int(test_a < test_b))
- expect(c.io.greatout, int(test_a > test_b))
- expect(c.io.eqout, int(test_a == test_b))
- expect(c.io.noteqout, int(test_a != test_b))
- expect(c.io.lessout, int(test_a <= test_b))
- expect(c.io.greateqout, int(test_a >= test_b))
- }
-}
- */
-
-class SIntLitExtractTester extends BasicTester {
- assert(-5.S.extract(1) === true.B)
- assert(-5.S.extract(2) === false.B)
- assert(-5.S.extract(100) === true.B)
- assert(-5.S(3, 0) === "b1011".U)
- assert(-5.S(9, 0) === "b1111111011".U)
- assert(-5.S(4.W)(1) === true.B)
- assert(-5.S(4.W)(2) === false.B)
- assert(-5.S(4.W)(100) === true.B)
- assert(-5.S(4.W)(3, 0) === "b1011".U)
- assert(-5.S(4.W)(9, 0) === "b1111111011".U)
- stop()
-}
-
-class SIntOpsSpec extends ChiselPropSpec with Utils {
-
- property("SIntOps should elaborate") {
- ChiselStage.elaborate { new SIntOps }
- }
-
- property("Negative shift amounts are invalid") {
- a[ChiselException] should be thrownBy extractCause[ChiselException] {
- ChiselStage.elaborate(new NegativeShift(SInt()))
- }
- }
-
- ignore("SIntOpsTester should return the correct result") {}
-
- property("Bit extraction on literals should work for all non-negative indices") {
- assertTesterPasses(new SIntLitExtractTester)
- }
-
- // We use WireDefault with 2 arguments because of
- // https://www.chisel-lang.org/api/3.4.1/chisel3/WireDefault$.html
- // Single Argument case 2
- property("modulo divide should give min width of arguments") {
- assertKnownWidth(4) {
- val x = WireDefault(SInt(8.W), DontCare)
- val y = WireDefault(SInt(4.W), DontCare)
- val op = x % y
- WireDefault(chiselTypeOf(op), op)
- }
- assertKnownWidth(4) {
- val x = WireDefault(SInt(4.W), DontCare)
- val y = WireDefault(SInt(8.W), DontCare)
- val op = x % y
- WireDefault(chiselTypeOf(op), op)
- }
- }
-
- property("division should give the width of the numerator + 1") {
- assertKnownWidth(9) {
- val x = WireDefault(SInt(8.W), DontCare)
- val y = WireDefault(SInt(4.W), DontCare)
- val op = x / y
- WireDefault(chiselTypeOf(op), op)
- }
- assertKnownWidth(5) {
- val x = WireDefault(SInt(4.W), DontCare)
- val y = WireDefault(SInt(8.W), DontCare)
- val op = x / y
- WireDefault(chiselTypeOf(op), op)
- }
- }
-}
diff --git a/src/test/scala/chiselTests/ScalaIntervalSimulatorTest.scala b/src/test/scala/chiselTests/ScalaIntervalSimulatorTest.scala
deleted file mode 100644
index 94f5ccc7..00000000
--- a/src/test/scala/chiselTests/ScalaIntervalSimulatorTest.scala
+++ /dev/null
@@ -1,97 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.experimental._
-import org.scalatest.freespec.AnyFreeSpec
-import org.scalatest.matchers.should.Matchers
-
-class ScalaIntervalSimulatorSpec extends AnyFreeSpec with Matchers {
- "clip tests" - {
- "Should work for closed ranges" in {
- val sim = ScalaIntervalSimulator(range"[2,4]")
- sim.clip(BigDecimal(1.0)) should be(2.0)
- sim.clip(BigDecimal(2.0)) should be(2.0)
- sim.clip(BigDecimal(3.0)) should be(3.0)
- sim.clip(BigDecimal(4.0)) should be(4.0)
- sim.clip(BigDecimal(5.0)) should be(4.0)
- }
- "Should work for closed ranges with binary point" in {
- val sim = ScalaIntervalSimulator(range"[2,6].2")
- sim.clip(BigDecimal(1.75)) should be(2.0)
- sim.clip(BigDecimal(2.0)) should be(2.0)
- sim.clip(BigDecimal(2.25)) should be(2.25)
- sim.clip(BigDecimal(2.5)) should be(2.5)
- sim.clip(BigDecimal(5.75)) should be(5.75)
- sim.clip(BigDecimal(6.0)) should be(6.0)
- sim.clip(BigDecimal(6.25)) should be(6.0)
- sim.clip(BigDecimal(6.5)) should be(6.0)
- sim.clip(BigDecimal(8.5)) should be(6.0)
- }
- "Should work for open ranges" in {
- val sim = ScalaIntervalSimulator(range"(2,4)")
- sim.clip(BigDecimal(1.0)) should be(3.0)
- sim.clip(BigDecimal(2.0)) should be(3.0)
- sim.clip(BigDecimal(3.0)) should be(3.0)
- sim.clip(BigDecimal(4.0)) should be(3.0)
- sim.clip(BigDecimal(5.0)) should be(3.0)
- }
- "Should work for open ranges with binary point" in {
- val sim = ScalaIntervalSimulator(range"(2,6).2")
- sim.clip(BigDecimal(1.75)) should be(2.25)
- sim.clip(BigDecimal(2.0)) should be(2.25)
- sim.clip(BigDecimal(2.25)) should be(2.25)
- sim.clip(BigDecimal(2.5)) should be(2.5)
- sim.clip(BigDecimal(5.75)) should be(5.75)
- sim.clip(BigDecimal(6.0)) should be(5.75)
- sim.clip(BigDecimal(6.25)) should be(5.75)
- sim.clip(BigDecimal(6.5)) should be(5.75)
- sim.clip(BigDecimal(8.5)) should be(5.75)
- }
- }
- "wrap tests" - {
- "Should work for closed ranges" in {
- val sim = ScalaIntervalSimulator(range"[2,6]")
- sim.wrap(BigDecimal(1.0)) should be(6.0)
- sim.wrap(BigDecimal(2.0)) should be(2.0)
- sim.wrap(BigDecimal(3.0)) should be(3.0)
- sim.wrap(BigDecimal(4.0)) should be(4.0)
- sim.wrap(BigDecimal(5.0)) should be(5.0)
- sim.wrap(BigDecimal(6.0)) should be(6.0)
- sim.wrap(BigDecimal(7.0)) should be(2.0)
- }
- "Should work for closed ranges with binary point" in {
- val sim = ScalaIntervalSimulator(range"[2,6].2")
- sim.wrap(BigDecimal(1.75)) should be(6.0)
- sim.wrap(BigDecimal(2.0)) should be(2.0)
- sim.wrap(BigDecimal(2.25)) should be(2.25)
- sim.wrap(BigDecimal(2.5)) should be(2.5)
- sim.wrap(BigDecimal(5.75)) should be(5.75)
- sim.wrap(BigDecimal(6.0)) should be(6.0)
- sim.wrap(BigDecimal(6.25)) should be(2.0)
- sim.wrap(BigDecimal(6.5)) should be(2.25)
- }
- "Should work for open ranges" in {
- val sim = ScalaIntervalSimulator(range"(2,6)")
- sim.wrap(BigDecimal(1.0)) should be(4.0)
- sim.wrap(BigDecimal(2.0)) should be(5.0)
- sim.wrap(BigDecimal(3.0)) should be(3.0)
- sim.wrap(BigDecimal(4.0)) should be(4.0)
- sim.wrap(BigDecimal(5.0)) should be(5.0)
- sim.wrap(BigDecimal(6.0)) should be(3.0)
- sim.wrap(BigDecimal(7.0)) should be(4.0)
- }
- "Should work for open ranges with binary point" in {
- val sim = ScalaIntervalSimulator(range"(2,6).2")
- sim.wrap(BigDecimal(1.75)) should be(5.5)
- sim.wrap(BigDecimal(2.0)) should be(5.75)
- sim.wrap(BigDecimal(2.25)) should be(2.25)
- sim.wrap(BigDecimal(2.5)) should be(2.5)
- sim.wrap(BigDecimal(5.75)) should be(5.75)
- sim.wrap(BigDecimal(6.0)) should be(2.25)
- sim.wrap(BigDecimal(6.25)) should be(2.5)
- sim.wrap(BigDecimal(7.0)) should be(3.25)
- }
- }
-}
diff --git a/src/test/scala/chiselTests/Stack.scala b/src/test/scala/chiselTests/Stack.scala
deleted file mode 100644
index 085f4e34..00000000
--- a/src/test/scala/chiselTests/Stack.scala
+++ /dev/null
@@ -1,77 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.stage.ChiselStage
-import chisel3.util._
-
-class ChiselStack(val depth: Int) extends Module {
- val io = IO(new Bundle {
- val push = Input(Bool())
- val pop = Input(Bool())
- val en = Input(Bool())
- val dataIn = Input(UInt(32.W))
- val dataOut = Output(UInt(32.W))
- })
-
- val stack_mem = Mem(depth, UInt(32.W))
- val sp = RegInit(0.U(log2Ceil(depth + 1).W))
- val out = RegInit(0.U(32.W))
-
- when(io.en) {
- when(io.push && (sp < depth.asUInt)) {
- stack_mem(sp) := io.dataIn
- sp := sp +% 1.U
- }.elsewhen(io.pop && (sp > 0.U)) {
- sp := sp -% 1.U
- }
- when(sp > 0.U) {
- out := stack_mem(sp -% 1.U)
- }
- }
- io.dataOut := out
-}
-
-/*
-class StackTester(c: Stack) extends Tester(c) {
- var nxtDataOut = 0
- var dataOut = 0
- val stack = new ScalaStack[Int]()
-
- for (t <- 0 until 16) {
- val enable = rnd.nextInt(2)
- val push = rnd.nextInt(2)
- val pop = rnd.nextInt(2)
- val dataIn = rnd.nextInt(256)
-
- if (enable == 1) {
- dataOut = nxtDataOut
- if (push == 1 && stack.length < c.depth) {
- stack.push(dataIn)
- } else if (pop == 1 && stack.length > 0) {
- stack.pop()
- }
- if (stack.length > 0) {
- nxtDataOut = stack.top
- }
- }
-
- poke(c.io.pop, pop)
- poke(c.io.push, push)
- poke(c.io.en, enable)
- poke(c.io.dataIn, dataIn)
- step(1)
- expect(c.io.dataOut, dataOut)
- }
-}
- */
-
-class StackSpec extends ChiselPropSpec {
-
- property("Stack should elaborate") {
- ChiselStage.elaborate { new ChiselStack(2) }
- }
-
- ignore("StackTester should return the correct result") {}
-}
diff --git a/src/test/scala/chiselTests/Stop.scala b/src/test/scala/chiselTests/Stop.scala
deleted file mode 100644
index 25aae2d9..00000000
--- a/src/test/scala/chiselTests/Stop.scala
+++ /dev/null
@@ -1,29 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.testers.BasicTester
-
-class StopTester() extends BasicTester {
- stop()
-}
-
-class StopImmediatelyTester extends BasicTester {
- val cycle = RegInit(0.asUInt(4.W))
- cycle := cycle + 1.U
- when(cycle === 4.U) {
- stop()
- }
- assert(cycle =/= 5.U, "Simulation did not exit upon executing stop()")
-}
-
-class StopSpec extends ChiselFlatSpec {
- "stop()" should "stop and succeed the testbench" in {
- assertTesterPasses { new StopTester }
- }
-
- it should "end the simulation immediately" in {
- assertTesterPasses { new StopImmediatelyTester }
- }
-}
diff --git a/src/test/scala/chiselTests/SwitchSpec.scala b/src/test/scala/chiselTests/SwitchSpec.scala
deleted file mode 100644
index 52f50a53..00000000
--- a/src/test/scala/chiselTests/SwitchSpec.scala
+++ /dev/null
@@ -1,53 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.stage.ChiselStage
-import chisel3.util.{is, switch}
-
-class SwitchSpec extends ChiselFlatSpec with Utils {
- "switch" should "require literal conditions" in {
- 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)
- switch(state) {
- is(wire) { state := 1.U }
- }
- })
- }
- }
- it should "require mutually exclusive conditions" in {
- 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) {
- is(0.U) { state := 1.U }
- is(1.U) { state := 2.U }
- is(0.U) { state := 3.U }
- }
- })
- }
- }
- it should "provide useful source locators" in {
- val chirrtl = ChiselStage.emitChirrtl(new Module {
- val io = IO(new Bundle {
- val in = Input(UInt(2.W))
- val out = Output(UInt(2.W))
- })
-
- io.out := 0.U
- switch(io.in) {
- is(0.U) { io.out := 3.U }
- is(1.U) { io.out := 0.U }
- is(2.U) { io.out := 1.U }
- is(3.U) { io.out := 3.U }
- }
- })
-
- (chirrtl should not).include("Conditional.scala")
- }
-}
diff --git a/src/test/scala/chiselTests/Tbl.scala b/src/test/scala/chiselTests/Tbl.scala
deleted file mode 100644
index 5e127770..00000000
--- a/src/test/scala/chiselTests/Tbl.scala
+++ /dev/null
@@ -1,62 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.testers.BasicTester
-import chisel3.util._
-
-class Tbl(w: Int, n: Int) extends Module {
- val io = IO(new Bundle {
- val wi = Input(UInt(log2Ceil(n).W))
- val ri = Input(UInt(log2Ceil(n).W))
- val we = Input(Bool())
- val d = Input(UInt(w.W))
- val o = Output(UInt(w.W))
- })
- val m = Mem(n, UInt(w.W))
- io.o := m(io.ri)
- when(io.we) {
- m(io.wi) := io.d
- when(io.ri === io.wi) {
- io.o := io.d
- }
- }
-}
-
-class TblTester(w: Int, n: Int, idxs: List[Int], values: List[Int]) extends BasicTester {
- val (cnt, wrap) = Counter(true.B, idxs.size)
- val dut = Module(new Tbl(w, n))
- val vvalues = VecInit(values.map(_.asUInt))
- val vidxs = VecInit(idxs.map(_.asUInt))
- val prev_idx = vidxs(cnt - 1.U)
- val prev_value = vvalues(cnt - 1.U)
- dut.io.wi := vidxs(cnt)
- dut.io.ri := prev_idx
- dut.io.we := true.B //TODO enSequence
- dut.io.d := vvalues(cnt)
- when(cnt > 0.U) {
- when(prev_idx === vidxs(cnt)) {
- assert(dut.io.o === vvalues(cnt))
- }.otherwise {
- assert(dut.io.o === prev_value)
- }
- }
- when(wrap) {
- stop()
- }
-}
-
-class TblSpec extends ChiselPropSpec {
- property("All table reads should return the previous write") {
- forAll(safeUIntPairN(8)) {
- case (w: Int, pairs: List[(Int, Int)]) =>
- // Provide an appropriate whenever clause.
- // ScalaTest will try and shrink the values on error to determine the smallest values that cause the error.
- whenever(w > 0 && pairs.length > 0) {
- val (idxs, values) = pairs.unzip
- assertTesterPasses { new TblTester(w, 1 << w, idxs, values) }
- }
- }
- }
-}
diff --git a/src/test/scala/chiselTests/TesterDriverSpec.scala b/src/test/scala/chiselTests/TesterDriverSpec.scala
deleted file mode 100644
index c3cc232f..00000000
--- a/src/test/scala/chiselTests/TesterDriverSpec.scala
+++ /dev/null
@@ -1,44 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.testers.BasicTester
-import chisel3.util._
-
-/** Extend BasicTester with a simple circuit and finish method. TesterDriver will call the
- * finish method after the FinishTester's constructor has completed, which will alter the
- * circuit after the constructor has finished.
- */
-class FinishTester extends BasicTester {
- val test_wire_width = 2
- val test_wire_override_value = 3
-
- val counter = Counter(1)
-
- when(counter.inc()) {
- stop()
- }
-
- val test_wire = WireDefault(1.U(test_wire_width.W))
-
- // though we just set test_wire to 1, the assert below will pass because
- // the finish will change its value
- assert(test_wire === test_wire_override_value.asUInt)
-
- /** In finish we use last connect semantics to alter the test_wire in the circuit
- * with a new value
- */
- override def finish(): Unit = {
- test_wire := test_wire_override_value.asUInt
- }
-}
-
-class TesterDriverSpec extends ChiselFlatSpec {
- "TesterDriver calls BasicTester's finish method which" should
- "allow modifications of test circuit after the tester's constructor is done" in {
- assertTesterPasses {
- new FinishTester
- }
- }
-}
diff --git a/src/test/scala/chiselTests/ToTargetSpec.scala b/src/test/scala/chiselTests/ToTargetSpec.scala
deleted file mode 100644
index de46cdcb..00000000
--- a/src/test/scala/chiselTests/ToTargetSpec.scala
+++ /dev/null
@@ -1,69 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.stage.ChiselStage
-import chisel3.util.Queue
-import chisel3.internal.ChiselException
-
-class ToTargetSpec extends ChiselFlatSpec with Utils {
-
- var m: InstanceNameModule = _
- ChiselStage.elaborate { m = new InstanceNameModule; m }
-
- val mn = "InstanceNameModule"
- val top = s"~$mn|$mn"
-
- behavior.of(".toTarget")
-
- val deprecationMsg = "Accessing the .instanceName or .toTarget of non-hardware Data is deprecated"
-
- it should "work with module IO" in {
- val io = m.io.toTarget.toString
- assert(io == s"$top>io")
- }
-
- it should "not work for literals" in {
- a[ChiselException] shouldBe thrownBy {
- m.x.toTarget.toString
- }
- }
-
- it should "work with non-hardware values (but be deprecated)" in {
- val (ylog, y) = grabLog(m.y.toTarget.toString)
- val (zlog, z) = grabLog(m.z.toTarget.toString)
- assert(y == s"$top>y")
- ylog should include(deprecationMsg)
- assert(z == s"$top>z")
- zlog should include(deprecationMsg)
- }
-
- it should "work with non-hardware bundle elements (but be deprecated)" in {
- val (log, foo) = grabLog(m.z.foo.toTarget.toString)
- log should include(deprecationMsg)
- assert(foo == s"$top>z.foo")
- }
-
- it should "work with modules" in {
- val q = m.q.toTarget.toString
- assert(q == s"~$mn|Queue")
- }
-
- it should "warn on non-hardware types and provide information" in {
- class Example extends Module {
- val tpe = UInt(8.W)
-
- val in = IO(Input(tpe))
- val out = IO(Output(tpe))
- out := in
- }
-
- var e: Example = null
- chisel3.stage.ChiselStage.elaborate { e = new Example; e }
- val (log, foo) = grabLog(e.tpe.toTarget)
- log should include(
- "Accessing the .instanceName or .toTarget of non-hardware Data is deprecated: 'tpe', in module 'Example'"
- )
- }
-}
diff --git a/src/test/scala/chiselTests/TransitNameSpec.scala b/src/test/scala/chiselTests/TransitNameSpec.scala
deleted file mode 100644
index ae08336d..00000000
--- a/src/test/scala/chiselTests/TransitNameSpec.scala
+++ /dev/null
@@ -1,53 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-package chiselTests
-
-import chisel3._
-import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage}
-import chisel3.util.TransitName
-
-import org.scalatest.flatspec.AnyFlatSpec
-import org.scalatest.matchers.should.Matchers
-
-class TransitNameSpec extends AnyFlatSpec with Matchers {
-
- class MyModule extends RawModule {
- val io = IO(new Bundle {})
- override val desiredName: String = "MyModule"
- }
-
- /** A top-level module that instantiates three copies of MyModule */
- class Top extends RawModule {
-
- /* Assign the IO of a new MyModule instance to value "foo". The instance will be named "MyModule". */
- val foo = Module(new MyModule).io
-
- /* Assign the IO of a new MyModule instance to value "bar". The instance will be named "bar". */
- val bar = {
- val x = Module(new MyModule)
- TransitName(x.io, x) // TransitName returns the first argument
- }
-
- /* Assign the IO of a new MyModule instance to value "baz". The instance will be named "baz_generated". */
- val baz = {
- val x = Module(new MyModule)
- TransitName.withSuffix("_generated")(x.io, x) // TransitName returns the first argument
- }
-
- }
-
- it should "transit a name" in {
-
- val firrtl = (new ChiselStage)
- .emitFirrtl(new Top, Array("--target-dir", "test_run_dir/TransitNameSpec"))
-
- info("""output FIRRTL includes "inst MyModule"""")
- firrtl should include("inst MyModule of MyModule")
-
- 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
deleted file mode 100644
index 2f55da9a..00000000
--- a/src/test/scala/chiselTests/UIntOps.scala
+++ /dev/null
@@ -1,290 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import org.scalatest._
-import chisel3.stage.ChiselStage
-import chisel3.testers.BasicTester
-import chisel3.util._
-import org.scalacheck.Shrink
-import org.scalatest.matchers.should.Matchers
-
-class UIntOps extends Module {
- val io = IO(new Bundle {
- val a = Input(UInt(32.W))
- val b = Input(UInt(32.W))
- val addout = Output(UInt(32.W))
- val subout = Output(UInt(32.W))
- val addampout = Output(UInt(33.W))
- val subampout = Output(UInt(33.W))
- val timesout = Output(UInt(32.W))
- val divout = Output(UInt(32.W))
- val modout = Output(UInt(32.W))
- val lshiftout = Output(UInt(32.W))
- val rshiftout = Output(UInt(32.W))
- val lrotateout = Output(UInt(32.W))
- val rrotateout = Output(UInt(32.W))
- val lessout = Output(Bool())
- val greatout = Output(Bool())
- val eqout = Output(Bool())
- val noteqout = Output(Bool())
- val lesseqout = Output(Bool())
- val greateqout = Output(Bool())
- })
-
- dontTouch(io)
-
- val a = io.a
- val b = io.b
-
- io.addout := a +% b
- io.subout := a -% b
- io.addampout := a +& b
- io.subampout := a -& b
- io.timesout := (a * b)(31, 0)
- io.divout := a / Mux(b === 0.U, 1.U, b)
- io.modout := a % b
- io.lshiftout := (a << b(3, 0))(31, 0)
- io.rshiftout := a >> b
- io.lrotateout := a.rotateLeft(5)
- io.rrotateout := a.rotateRight(5)
- io.lessout := a < b
- io.greatout := a > b
- io.eqout := a === b
- io.noteqout := (a =/= b)
- io.lesseqout := a <= b
- io.greateqout := a >= b
-}
-
-// Note a and b need to be "safe"
-class UIntOpsTester(a: Long, b: Long) extends BasicTester {
- require(a >= 0 && b >= 0)
-
- val dut = Module(new UIntOps)
- dut.io.a := a.asUInt(32.W)
- dut.io.b := b.asUInt(32.W)
-
- assert(dut.io.addout === (a + b).U(32.W))
- assert(dut.io.subout === (a - b).S(32.W).asUInt)
- assert(dut.io.addampout === (a + b).U(33.W))
- assert(dut.io.subampout === (a - b).S(33.W).asUInt)
- assert(dut.io.timesout === (a * b).U(32.W))
- assert(dut.io.divout === (a / (b.max(1))).U(32.W))
- assert(dut.io.modout === (a % (b.max(1))).U(32.W))
- assert(dut.io.lshiftout === (a << (b % 16)).U(32.W))
- assert(dut.io.rshiftout === (a >> b).U(32.W))
- assert(
- dut.io.lrotateout === s"h${Integer.rotateLeft(a.toInt, 5).toHexString}"
- .U(32.W)
- )
- assert(
- dut.io.rrotateout === s"h${Integer.rotateRight(a.toInt, 5).toHexString}"
- .U(32.W)
- )
- assert(dut.io.lessout === (a < b).B)
- assert(dut.io.greatout === (a > b).B)
- assert(dut.io.eqout === (a == b).B)
- assert(dut.io.noteqout === (a != b).B)
- assert(dut.io.lesseqout === (a <= b).B)
- assert(dut.io.greateqout === (a >= b).B)
-
- stop()
-}
-
-class GoodBoolConversion extends Module {
- val io = IO(new Bundle {
- val u = Input(UInt(1.W))
- val b = Output(Bool())
- })
- io.b := io.u.asBool
-}
-
-class BadBoolConversion extends Module {
- val io = IO(new Bundle {
- val u = Input(UInt(5.W))
- val b = Output(Bool())
- })
- io.b := io.u.asBool
-}
-
-class NegativeShift(t: => Bits) extends Module {
- val io = IO(new Bundle {})
- Reg(t) >> -1
-}
-
-class BasicRotate extends BasicTester {
- val shiftAmount = random.LFSR(4)
- val ctr = RegInit(0.U(4.W))
-
- val rotL = 1.U(3.W).rotateLeft(shiftAmount)
- val rotR = 1.U(3.W).rotateRight(shiftAmount)
-
- printf("Shift amount: %d rotateLeft:%b rotateRight:%b\n", shiftAmount, rotL, rotR)
-
- switch(shiftAmount % 3.U) {
- is(0.U, 3.U) {
- assert(rotL === "b001".U)
- assert(rotR === "b001".U)
- }
- is(1.U) {
- assert(rotL === "b010".U)
- assert(rotR === "b100".U)
- }
- is(2.U) {
- assert(rotL === "b100".U)
- assert(rotR === "b010".U)
- }
- }
-
- ctr := ctr + 1.U
-
- when(ctr === 15.U) {
- stop()
- }
-}
-
-/** rotating a w-bit word left by n should be equivalent to rotating it by w - n
- * to the left
- */
-class MatchedRotateLeftAndRight(w: Int = 13) extends BasicTester {
- val initValue = BigInt(w, scala.util.Random)
- println(s"Initial value: ${initValue.toString(2)}")
-
- val maxWidthBits = log2Ceil(w + 1)
- val shiftAmount1 = RegInit(0.U(w.W))
- val shiftAmount2 = RegInit(w.U(w.W))
- shiftAmount1 := shiftAmount1 + 1.U
- shiftAmount2 := shiftAmount2 - 1.U
-
- val value = RegInit(initValue.U(w.W))
-
- val out1 = value.rotateLeft(shiftAmount1)
- val out2 = value.rotateRight(shiftAmount2)
-
- printf("rotateLeft by %d: %b\n", shiftAmount1, out1)
-
- assert(out1 === out2)
- when(shiftAmount1 === w.U) {
- assert(out1 === initValue.U)
- stop()
- }
-}
-
-class UIntLitExtractTester extends BasicTester {
- assert("b101010".U.extract(2) === false.B)
- assert("b101010".U.extract(3) === true.B)
- assert("b101010".U.extract(100) === false.B)
- assert("b101010".U(3, 0) === "b1010".U)
- assert("b101010".U(9, 0) === "b0000101010".U)
-
- assert("b101010".U(6.W)(2) === false.B)
- assert("b101010".U(6.W)(3) === true.B)
- assert("b101010".U(6.W)(100) === false.B)
- assert("b101010".U(6.W)(3, 0) === "b1010".U)
- assert("b101010".U(6.W)(9, 0) === "b0000101010".U)
- stop()
-}
-
-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") {
- ChiselStage.elaborate(new GoodBoolConversion)
- }
-
- property("Bools cannot be created from >1 bit UInts") {
- a[Exception] should be thrownBy extractCause[Exception] { ChiselStage.elaborate(new BadBoolConversion) }
- }
-
- property("Out-of-bounds extraction from known-width UInts") {
- a[ChiselException] should be thrownBy extractCause[ChiselException] {
- ChiselStage.elaborate(new RawModule {
- val u = IO(Input(UInt(2.W)))
- u(2, 1)
- })
- }
- }
-
- property("Out-of-bounds single-bit extraction from known-width UInts") {
- a[ChiselException] should be thrownBy extractCause[ChiselException] {
- ChiselStage.elaborate(new RawModule {
- val u = IO(Input(UInt(2.W)))
- u(2)
- })
- }
- }
-
- property("UIntOps should elaborate") {
- ChiselStage.elaborate { new UIntOps }
- }
-
- property("UIntOpsTester should return the correct result") {
- assertTesterPasses { new UIntOpsTester(123, 7) }
- }
-
- property("Negative shift amounts are invalid") {
- a[ChiselException] should be thrownBy extractCause[ChiselException] {
- ChiselStage.elaborate(new NegativeShift(UInt()))
- }
- }
-
- property("rotateLeft and rotateRight should work for dynamic shift values") {
- assertTesterPasses(new BasicRotate)
- }
-
- property(
- "rotateLeft and rotateRight should be consistent for dynamic shift values"
- ) {
- assertTesterPasses(new MatchedRotateLeftAndRight)
- }
-
- property("Bit extraction on literals should work for all non-negative indices") {
- assertTesterPasses(new UIntLitExtractTester)
- }
-
- property("asBools should support chained apply") {
- ChiselStage.elaborate(new Module {
- val io = IO(new Bundle {
- val in = Input(UInt(8.W))
- val out = Output(Bool())
- })
- io.out := io.in.asBools()(2)
- })
- }
-
- // We use WireDefault with 2 arguments because of
- // https://www.chisel-lang.org/api/3.4.1/chisel3/WireDefault$.html
- // Single Argument case 2
- property("modulo divide should give min width of arguments") {
- assertKnownWidth(4) {
- val x = WireDefault(UInt(8.W), DontCare)
- val y = WireDefault(UInt(4.W), DontCare)
- val op = x % y
- WireDefault(chiselTypeOf(op), op)
- }
- assertKnownWidth(4) {
- val x = WireDefault(UInt(4.W), DontCare)
- val y = WireDefault(UInt(8.W), DontCare)
- val op = x % y
- WireDefault(chiselTypeOf(op), op)
- }
- }
-
- property("division should give the width of the numerator") {
- assertKnownWidth(8) {
- val x = WireDefault(UInt(8.W), DontCare)
- val y = WireDefault(UInt(4.W), DontCare)
- val op = x / y
- WireDefault(chiselTypeOf(op), op)
- }
- assertKnownWidth(4) {
- val x = WireDefault(UInt(4.W), DontCare)
- val y = WireDefault(UInt(8.W), DontCare)
- val op = x / y
- WireDefault(chiselTypeOf(op), op)
- }
- }
-}
diff --git a/src/test/scala/chiselTests/Util.scala b/src/test/scala/chiselTests/Util.scala
deleted file mode 100644
index d2f8bd9b..00000000
--- a/src/test/scala/chiselTests/Util.scala
+++ /dev/null
@@ -1,69 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-// Useful utilities for tests
-
-package chiselTests
-
-import chisel3._
-import chisel3.experimental.Interval
-import chisel3.internal.firrtl.{IntervalRange, KnownBinaryPoint, Width}
-import _root_.firrtl.{ir => firrtlir}
-
-class PassthroughModuleIO extends Bundle {
- val in = Input(UInt(32.W))
- val out = Output(UInt(32.W))
-}
-
-trait AbstractPassthroughModule extends RawModule {
- val io = IO(new PassthroughModuleIO)
- io.out := io.in
-}
-
-class PassthroughModule extends Module with AbstractPassthroughModule
-class PassthroughMultiIOModule extends Module with AbstractPassthroughModule
-class PassthroughRawModule extends RawModule with AbstractPassthroughModule
-
-case class ScalaIntervalSimulator(intervalRange: IntervalRange) {
- val binaryPoint: Int = intervalRange.binaryPoint.asInstanceOf[KnownBinaryPoint].value
- val epsilon: Double = 1.0 / math.pow(2.0, binaryPoint.toDouble)
-
- val (lower, upper) = (intervalRange.lowerBound, intervalRange.upperBound) match {
-
- case (firrtlir.Closed(lower1), firrtlir.Closed(upper1)) => (lower1, upper1)
- case (firrtlir.Closed(lower1), firrtlir.Open(upper1)) => (lower1, upper1 - epsilon)
- case (firrtlir.Open(lower1), firrtlir.Closed(upper1)) => (lower1 + epsilon, upper1)
- case (firrtlir.Open(lower1), firrtlir.Open(upper1)) => (lower1 + epsilon, upper1 - epsilon)
- case _ =>
- throw new Exception(s"lower and upper bounds must be defined, range here is $intervalRange")
- }
-
- def clip(value: BigDecimal): BigDecimal = {
-
- if (value < lower) {
- lower
- } else if (value > upper) {
- upper
- } else {
- value
- }
- }
-
- def wrap(value: BigDecimal): BigDecimal = {
-
- if (value < lower) {
- upper + (value - lower) + epsilon
- } else if (value > upper) {
- ((value - upper) - epsilon) + lower
- } else {
- value
- }
- }
-
- def allValues: Iterator[BigDecimal] = {
- (lower to upper by epsilon).toIterator
- }
-
- def makeLit(value: BigDecimal): Interval = {
- Interval.fromDouble(value.toDouble, width = Width(), binaryPoint = binaryPoint.BP)
- }
-}
diff --git a/src/test/scala/chiselTests/Vec.scala b/src/test/scala/chiselTests/Vec.scala
deleted file mode 100644
index e46774dd..00000000
--- a/src/test/scala/chiselTests/Vec.scala
+++ /dev/null
@@ -1,542 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import org.scalacheck._
-
-import chisel3._
-import chisel3.stage.ChiselStage
-import chisel3.testers.{BasicTester, TesterDriver}
-import chisel3.util._
-import org.scalacheck.Shrink
-import scala.annotation.tailrec
-
-class LitTesterMod(vecSize: Int) extends Module {
- val io = IO(new Bundle {
- val out = Output(Vec(vecSize, UInt()))
- })
- io.out := VecInit(Seq.fill(vecSize) { 0.U })
-}
-
-class RegTesterMod(vecSize: Int) extends Module {
- val io = IO(new Bundle {
- val in = Input(Vec(vecSize, UInt()))
- val out = Output(Vec(vecSize, UInt()))
- })
- val vecReg = RegNext(io.in, VecInit(Seq.fill(vecSize) { 0.U }))
- io.out := vecReg
-}
-
-class IOTesterMod(vecSize: Int) extends Module {
- val io = IO(new Bundle {
- val in = Input(Vec(vecSize, UInt()))
- val out = Output(Vec(vecSize, UInt()))
- })
- io.out := io.in
-}
-
-class OneBitUnitRegVec extends Module {
- val io = IO(new Bundle {
- val out = Output(UInt(1.W))
- })
- val oneBitUnitRegVec = Reg(Vec(1, UInt(1.W)))
- oneBitUnitRegVec(0) := 1.U(1.W)
- io.out := oneBitUnitRegVec(0)
-}
-
-class LitTester(w: Int, values: List[Int]) extends BasicTester {
- val dut = Module(new LitTesterMod(values.length))
- for (a <- dut.io.out)
- assert(a === 0.U)
- stop()
-}
-
-class RegTester(w: Int, values: List[Int]) extends BasicTester {
- val v = VecInit(values.map(_.U(w.W)))
- val dut = Module(new RegTesterMod(values.length))
- val doneReg = RegInit(false.B)
- dut.io.in := v
- when(doneReg) {
- for ((a, b) <- dut.io.out.zip(values))
- assert(a === b.U)
- stop()
- }.otherwise {
- doneReg := true.B
- for (a <- dut.io.out)
- assert(a === 0.U)
- }
-}
-
-class IOTester(w: Int, values: List[Int]) extends BasicTester {
- val v = VecInit(values.map(_.U(w.W))) // Does this need a Wire? No. It's a Vec of Lits and hence synthesizeable.
- val dut = Module(new IOTesterMod(values.length))
- dut.io.in := v
- for ((a, b) <- dut.io.out.zip(values)) {
- assert(a === b.U)
- }
- stop()
-}
-
-class IOTesterModFill(vecSize: Int) extends Module {
- // This should generate a BindingException when we attempt to wire up the Vec.fill elements
- // since they're pure types and hence unsynthesizeable.
- val io = IO(new Bundle {
- val in = Input(VecInit(Seq.fill(vecSize) { UInt() }))
- val out = Output(VecInit(Seq.fill(vecSize) { UInt() }))
- })
- io.out := io.in
-}
-
-class ValueTester(w: Int, values: List[Int]) extends BasicTester {
- val v = VecInit(values.map(_.asUInt(w.W)))
- for ((a, b) <- v.zip(values)) {
- assert(a === b.asUInt)
- }
- stop()
-}
-
-class TabulateTester(n: Int) extends BasicTester {
- val v = VecInit(Range(0, n).map(i => (i * 2).asUInt))
- val x = VecInit(Array.tabulate(n) { i => (i * 2).asUInt })
- val u = VecInit.tabulate(n)(i => (i * 2).asUInt)
-
- assert(v.asUInt() === x.asUInt())
- assert(v.asUInt() === u.asUInt())
- assert(x.asUInt() === u.asUInt())
-
- stop()
-}
-
-class FillTester(n: Int, value: Int) extends BasicTester {
- val x = VecInit(Array.fill(n)(value.U))
- val u = VecInit.fill(n)(value.U)
-
- assert(x.asUInt() === u.asUInt(), cf"Expected Vec to be filled like $x, instead VecInit.fill created $u")
- stop()
-}
-
-object VecMultiDimTester {
-
- @tailrec
- private def assert2DIsCorrect(n: Int, arr: Vec[Vec[UInt]], compArr: Seq[Seq[Int]]): Unit = {
- val compareRow = arr(n).zip(compArr(n))
- compareRow.foreach(x => assert(x._1 === x._2.U))
- if (n != 0) assert2DIsCorrect(n - 1, arr, compArr)
- }
-
- @tailrec
- private def assert3DIsCorrect(n: Int, m: Int, arr: Vec[Vec[Vec[UInt]]], compArr: Seq[Seq[Seq[Int]]]): Unit = {
- assert2DIsCorrect(m - 1, arr(n), compArr(n))
- if (n != 0) assert3DIsCorrect(n - 1, m, arr, compArr)
- }
-
- class TabulateTester2D(n: Int, m: Int) extends BasicTester {
- def gen(x: Int, y: Int): UInt = (x + y).asUInt
- def genCompVec(x: Int, y: Int): Int = x + y
- val vec = VecInit.tabulate(n, m) { gen }
- val compArr = Seq.tabulate(n, m) { genCompVec }
-
- assert2DIsCorrect(n - 1, vec, compArr)
- stop()
- }
-
- class TabulateTester3D(n: Int, m: Int, p: Int) extends BasicTester {
- def gen(x: Int, y: Int, z: Int): UInt = (x + y + z).asUInt
- def genCompVec(x: Int, y: Int, z: Int): Int = x + y + z
- val vec = VecInit.tabulate(n, m, p) { gen }
- val compArr = Seq.tabulate(n, m, p) { genCompVec }
-
- assert3DIsCorrect(n - 1, m, vec, compArr)
- stop()
- }
-
- class Fill2DTester(n: Int, m: Int, value: Int) extends BasicTester {
- val u = VecInit.fill(n, m)(value.U)
- val compareArr = Seq.fill(n, m)(value)
-
- assert2DIsCorrect(n - 1, u, compareArr)
- stop()
- }
-
- class Fill3DTester(n: Int, m: Int, p: Int, value: Int) extends BasicTester {
- val u = VecInit.fill(n, m, p)(value.U)
- val compareArr = Seq.fill(n, m, p)(value)
-
- assert3DIsCorrect(n - 1, m, u, compareArr)
- stop()
- }
-
- class BidirectionalTester2DFill(n: Int, m: Int) extends BasicTester {
- val mod = Module(new PassthroughModule)
- val vec2D = VecInit.fill(n, m)(mod.io)
- for {
- vec1D <- vec2D
- module <- vec1D
- } yield {
- module <> Module(new PassthroughModuleTester).io
- }
- stop()
- }
-
- class BidirectionalTester3DFill(n: Int, m: Int, p: Int) extends BasicTester {
- val mod = Module(new PassthroughModule)
- val vec3D = VecInit.fill(n, m, p)(mod.io)
-
- for {
- vec2D <- vec3D
- vec1D <- vec2D
- module <- vec1D
- } yield {
- module <> (Module(new PassthroughModuleTester).io)
- }
- stop()
- }
-
- class TabulateModuleTester(value: Int) extends Module {
- val io = IO(Flipped(new PassthroughModuleIO))
- // This drives the input of a PassthroughModule
- io.in := value.U
- }
-
- class BidirectionalTester2DTabulate(n: Int, m: Int) extends BasicTester {
- val vec2D = VecInit.tabulate(n, m) { (x, y) => Module(new TabulateModuleTester(x + y + 1)).io }
-
- for {
- x <- 0 until n
- y <- 0 until m
- } yield {
- val value = x + y + 1
- val receiveMod = Module(new PassthroughModule).io
- vec2D(x)(y) <> receiveMod
- assert(receiveMod.out === value.U)
- }
- stop()
- }
-
- class BidirectionalTester3DTabulate(n: Int, m: Int, p: Int) extends BasicTester {
- val vec3D = VecInit.tabulate(n, m, p) { (x, y, z) => Module(new TabulateModuleTester(x + y + z + 1)).io }
-
- for {
- x <- 0 until n
- y <- 0 until m
- z <- 0 until p
- } yield {
- val value = x + y + z + 1
- val receiveMod = Module(new PassthroughModule).io
- vec3D(x)(y)(z) <> receiveMod
- assert(receiveMod.out === value.U)
- }
- stop()
- }
-}
-
-class IterateTester(start: Int, len: Int)(f: UInt => UInt) extends BasicTester {
- val controlVec = VecInit(Seq.iterate(start.U, len)(f))
- val testVec = VecInit.iterate(start.U, len)(f)
- assert(
- controlVec.asUInt() === testVec.asUInt(),
- cf"Expected Vec to be filled like $controlVec, instead created $testVec\n"
- )
- stop()
-}
-
-class ShiftRegisterTester(n: Int) extends BasicTester {
- val (cnt, wrap) = Counter(true.B, n * 2)
- val shifter = Reg(Vec(n, UInt((log2Ceil(n).max(1)).W)))
- (shifter, shifter.drop(1)).zipped.foreach(_ := _)
- shifter(n - 1) := cnt
- when(cnt >= n.asUInt) {
- val expected = cnt - n.asUInt
- assert(shifter(0) === expected)
- }
- when(wrap) {
- stop()
- }
-}
-
-class HugeVecTester(n: Int) extends BasicTester {
- require(n > 0)
- val myVec = Wire(Vec(n, UInt()))
- myVec.foreach { x =>
- x := 123.U
- assert(x === 123.U)
- }
- stop()
-}
-
-class OneBitUnitRegVecTester extends BasicTester {
- val dut = Module(new OneBitUnitRegVec)
- assert(dut.io.out === 1.U)
- stop()
-}
-
-class ZeroEntryVecTester extends BasicTester {
- require(Vec(0, Bool()).getWidth == 0)
-
- val bundleWithZeroEntryVec = new Bundle {
- val foo = Bool()
- val bar = Vec(0, Bool())
- }
- require(0.U.asTypeOf(bundleWithZeroEntryVec).getWidth == 1)
- require(bundleWithZeroEntryVec.asUInt.getWidth == 1)
-
- val m = Module(new Module {
- val io = IO(Output(bundleWithZeroEntryVec))
- io.foo := false.B
- })
- WireDefault(m.io.bar)
-
- stop()
-}
-
-class PassthroughModuleTester extends Module {
- val io = IO(Flipped(new PassthroughModuleIO))
- // This drives the input of a PassthroughModule
- io.in := 123.U
- assert(io.out === 123.U)
-}
-
-class ModuleIODynamicIndexTester(n: Int) extends BasicTester {
- val duts = VecInit.fill(n)(Module(new PassthroughModule).io)
- val tester = Module(new PassthroughModuleTester)
-
- val (cycle, done) = Counter(true.B, n)
- for ((m, i) <- duts.zipWithIndex) {
- when(cycle =/= i.U) {
- m.in := 0.U // default
- assert(m.out === 0.U)
- }.otherwise {
- m.in := DontCare
- }
- }
- // only connect one dut per cycle
- duts(cycle) <> tester.io
- assert(duts(cycle).out === 123.U)
-
- when(done) { stop() }
-}
-
-class ReduceTreeTester() extends BasicTester {
- class FooIO[T <: Data](n: Int, private val gen: T) extends Bundle {
- val in = Flipped(Vec(n, new DecoupledIO(gen)))
- val out = new DecoupledIO(gen)
- }
-
- class Foo[T <: Data](n: Int, private val gen: T) extends Module {
- val io = IO(new FooIO(n, gen))
-
- def foo(a: DecoupledIO[T], b: DecoupledIO[T]) = {
- a.ready := true.B
- b.ready := true.B
- val out = Wire(new DecoupledIO(gen))
-
- out.valid := true.B
-
- val regSel = RegInit(false.B)
- out.bits := Mux(regSel, a.bits, b.bits)
- out.ready := a.ready
- out
- }
-
- io.out <> io.in.reduceTree(foo)
- }
-
- val dut = Module(new Foo(5, UInt(5.W)))
- dut.io := DontCare
- stop()
-}
-
-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)
-
- property("Vecs should be assignable") {
- forAll(safeUIntN(8)) {
- case (w: Int, v: List[Int]) =>
- assertTesterPasses { new ValueTester(w, v) }
- }
- }
-
- property("Vecs should be passed through vec IO") {
- forAll(safeUIntN(8)) {
- case (w: Int, v: List[Int]) =>
- assertTesterPasses { new IOTester(w, v) }
- }
- }
-
- 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 extractCause[BindingException] {
- ChiselStage.elaborate(new IOTesterModFill(w))
- }
- }
- }
-
- property("A Reg of a Vec should operate correctly") {
- forAll(safeUIntN(8)) {
- case (w: Int, v: List[Int]) =>
- assertTesterPasses { new RegTester(w, v) }
- }
- }
-
- property("A Vec of lit should operate correctly") {
- forAll(safeUIntN(8)) {
- case (w: Int, v: List[Int]) =>
- assertTesterPasses { new LitTester(w, v) }
- }
- }
-
- property("VecInit should tabulate correctly") {
- forAll(smallPosInts) { (n: Int) => assertTesterPasses { new TabulateTester(n) } }
- }
-
- property("VecInit should tabulate 2D vec correctly") {
- forAll(smallPosInts, smallPosInts) { (n: Int, m: Int) =>
- assertTesterPasses { new VecMultiDimTester.TabulateTester2D(n, m) }
- }
- }
-
- property("VecInit should tabulate 3D vec correctly") {
- forAll(smallPosInts, smallPosInts, smallPosInts) { (n: Int, m: Int, p: Int) =>
- assertTesterPasses { new VecMultiDimTester.TabulateTester3D(n, m, p) }
- }
- }
-
- property("VecInit should fill correctly") {
- forAll(smallPosInts, Gen.choose(0, 50)) { (n: Int, value: Int) => assertTesterPasses { new FillTester(n, value) } }
- }
-
- property("VecInit should fill 2D vec correctly") {
- forAll(smallPosInts, smallPosInts, Gen.choose(0, 50)) { (n: Int, m: Int, value: Int) =>
- assertTesterPasses { new VecMultiDimTester.Fill2DTester(n, m, value) }
- }
- }
-
- property("VecInit should fill 3D vec correctly") {
- forAll(smallPosInts, smallPosInts, smallPosInts, Gen.choose(0, 50)) { (n: Int, m: Int, p: Int, value: Int) =>
- assertTesterPasses { new VecMultiDimTester.Fill3DTester(n, m, p, value) }
- }
- }
-
- property("VecInit should support 2D fill bidirectional wire connection") {
- forAll(smallPosInts, smallPosInts) { (n: Int, m: Int) =>
- assertTesterPasses { new VecMultiDimTester.BidirectionalTester2DFill(n, m) }
- }
- }
-
- property("VecInit should support 3D fill bidirectional wire connection") {
- forAll(smallPosInts, smallPosInts, smallPosInts) { (n: Int, m: Int, p: Int) =>
- assertTesterPasses { new VecMultiDimTester.BidirectionalTester3DFill(n, m, p) }
- }
- }
-
- property("VecInit should support 2D tabulate bidirectional wire connection") {
- forAll(smallPosInts, smallPosInts) { (n: Int, m: Int) =>
- assertTesterPasses { new VecMultiDimTester.BidirectionalTester2DTabulate(n, m) }
- }
- }
-
- property("VecInit should support 3D tabulate bidirectional wire connection") {
- forAll(smallPosInts, smallPosInts, smallPosInts) { (n: Int, m: Int, p: Int) =>
- assertTesterPasses { new VecMultiDimTester.BidirectionalTester3DTabulate(n, m, p) }
- }
- }
-
- property("VecInit should iterate correctly") {
- forAll(Gen.choose(1, 10), smallPosInts) { (start: Int, len: Int) =>
- assertTesterPasses { new IterateTester(start, len)(x => x + 50.U) }
- }
- }
-
- property("Regs of vecs should be usable as shift registers") {
- forAll(smallPosInts) { (n: Int) => assertTesterPasses { new ShiftRegisterTester(n) } }
- }
-
- property("Infering widths on huge Vecs should not cause a stack overflow") {
- assertTesterPasses(new HugeVecTester(10000), annotations = TesterDriver.verilatorOnly)
- }
-
- property("A Reg of a Vec of a single 1 bit element should compile and work") {
- assertTesterPasses { new OneBitUnitRegVecTester }
- }
-
- property("A Vec with zero entries should compile and have zero width") {
- assertTesterPasses { new ZeroEntryVecTester }
- }
-
- property("Dynamic indexing of a Vec of Module IOs should work") {
- assertTesterPasses { new ModuleIODynamicIndexTester(4) }
- }
-
- property("It should be possible to bulk connect a Vec and a Seq") {
- ChiselStage.elaborate(new Module {
- val io = IO(new Bundle {
- val out = Output(Vec(4, UInt(8.W)))
- })
- val seq = Seq.fill(4)(0.U)
- io.out <> seq
- })
- }
-
- property("Bulk connecting a Vec and Seq of different sizes should report a ChiselException") {
- a[ChiselException] should be thrownBy extractCause[ChiselException] {
- ChiselStage.elaborate(new Module {
- val io = IO(new Bundle {
- val out = Output(Vec(4, UInt(8.W)))
- })
- val seq = Seq.fill(5)(0.U)
- io.out <> seq
- })
- }
- }
-
- property("It should be possible to initialize a Vec with DontCare") {
- ChiselStage.elaborate(new Module {
- val io = IO(new Bundle {
- val out = Output(Vec(4, UInt(8.W)))
- })
- io.out := VecInit(Seq(4.U, 5.U, DontCare, 2.U))
- })
- }
-
- property("Indexing a Chisel type Vec by a hardware type should give a sane error message") {
- a[ExpectedHardwareException] should be thrownBy extractCause[ChiselException] {
- ChiselStage.elaborate {
- new Module {
- val io = IO(new Bundle {})
- val foo = Vec(2, Bool())
- foo(0.U) := false.B
- }
- }
- }
- }
-
- property("reduceTree should preserve input/output type") {
- assertTesterPasses { new ReduceTreeTester() }
- }
-
- property("Vecs of empty Bundles and empty Records should work") {
- class MyModule(gen: Record) extends Module {
- val idx = IO(Input(UInt(2.W)))
- val in = IO(Input(gen))
- val out = IO(Output(gen))
-
- val reg = RegInit(0.U.asTypeOf(Vec(4, gen)))
- reg(idx) := in
- out := reg(idx)
- }
- class EmptyBundle extends Bundle
- class EmptyRecord extends Record {
- val elements = collection.immutable.ListMap.empty
- override def cloneType = (new EmptyRecord).asInstanceOf[this.type]
- }
- for (gen <- List(new EmptyBundle, new EmptyRecord)) {
- val chirrtl = ChiselStage.emitChirrtl(new MyModule(gen))
- chirrtl should include("input in : { }")
- chirrtl should include("reg reg : { }[4]")
- }
- }
-}
diff --git a/src/test/scala/chiselTests/VecLiteralSpec.scala b/src/test/scala/chiselTests/VecLiteralSpec.scala
deleted file mode 100644
index dcc96b17..00000000
--- a/src/test/scala/chiselTests/VecLiteralSpec.scala
+++ /dev/null
@@ -1,529 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.experimental.BundleLiterals.AddBundleLiteralConstructor
-import chisel3.experimental.VecLiterals._
-import chisel3.experimental.{FixedPoint, VecLiteralException}
-import chisel3.stage.ChiselStage
-import chisel3.testers.BasicTester
-import chisel3.util.Counter
-import scala.language.reflectiveCalls
-
-class VecLiteralSpec extends ChiselFreeSpec with Utils {
- object MyEnum extends ChiselEnum {
- val sA, sB, sC = Value
- }
- object MyEnumB extends ChiselEnum {
- val sA, sB = Value
- }
-
- "Vec literals should work with chisel Enums" in {
- val enumVec = Vec(3, MyEnum()).Lit(0 -> MyEnum.sA, 1 -> MyEnum.sB, 2 -> MyEnum.sC)
- enumVec(0).toString should include(MyEnum.sA.toString)
- enumVec(1).toString should include(MyEnum.sB.toString)
- enumVec(2).toString should include(MyEnum.sC.toString)
- }
-
- "improperly constructed vec literals should be detected" - {
- "indices in vec literal muse be greater than zero and less than length" in {
- val e = intercept[VecLiteralException] {
- Vec(2, UInt(4.W)).Lit(0 -> 1.U, 1 -> 2.U, 2 -> 3.U, 3 -> 4.U, -2 -> 7.U)
- }
- e.getMessage should include(
- "VecLiteral: The following indices (2,3,-2) are less than zero or greater or equal to than Vec length"
- )
- }
-
- "indices in vec literals must not be repeated" in {
- val e = intercept[VecLiteralException] {
- Vec(2, UInt(4.W)).Lit(0 -> 1.U, 1 -> 2.U, 2 -> 3.U, 2 -> 3.U, 2 -> 3.U, 3 -> 4.U)
- }
- e.getMessage should include("VecLiteral: has duplicated indices 2(3 times)")
- }
- "lits must fit in vec element width" in {
- val e = intercept[VecLiteralException] {
- Vec(2, SInt(4.W)).Lit(0 -> 0xab.S, 1 -> 0xbc.S)
- }
- e.getMessage should include(
- "VecLiteral: Vec[SInt<4>] has the following incorrectly typed or sized initializers: " +
- "0 -> SInt<9>(171),1 -> SInt<9>(188)"
- )
- }
-
- "all lits must be the same type but width can be equal or smaller than the Vec's element width" in {
- val v = Vec(2, SInt(4.W)).Lit(0 -> 1.S, 1 -> -2.S)
- v(0).toString should include(1.S(4.W).toString)
- v(1).toString should include((-2).S(4.W).toString)
- v.toString should include("SInt<4>[2](0=SLit(1,<4>), 1=SLit(-2,<4>)")
- }
-
- "all lits must be the same type but width cannot be greater than Vec's element width" in {
- val e = intercept[VecLiteralException] {
- val v = Vec(2, SInt(4.W)).Lit(0 -> 11.S, 1 -> -0xffff.S)
- }
- e.getMessage should include(
- "VecLiteral: Vec[SInt<4>] has the following incorrectly typed or sized initializers: 0 -> SInt<5>(11),1 -> SInt<17>(-65535)"
- )
- }
- }
-
- //NOTE: I had problems where this would not work if this class declaration was inside test scope
- class HasVecInit extends Module {
- val initValue = Vec(4, UInt(8.W)).Lit(0 -> 0xab.U(8.W), 1 -> 0xcd.U(8.W), 2 -> 0xef.U(8.W), 3 -> 0xff.U(8.W))
- val y = RegInit(initValue)
- }
-
- "Vec literals should work when used to initialize a reg of vec" in {
- val firrtl = (new ChiselStage).emitFirrtl(new HasVecInit, args = Array("--full-stacktrace"))
- firrtl should include("""_y_WIRE[0] <= UInt<8>("hab")""")
- firrtl should include("""_y_WIRE[1] <= UInt<8>("hcd")""")
- firrtl should include("""_y_WIRE[2] <= UInt<8>("hef")""")
- firrtl should include("""_y_WIRE[3] <= UInt<8>("hff")""")
- firrtl should include(""" reset => (reset, _y_WIRE)""".stripMargin)
- }
-
- //NOTE: I had problems where this would not work if this class declaration was inside test scope
- class HasPartialVecInit extends Module {
- val initValue = Vec(4, UInt(8.W)).Lit(0 -> 0xab.U(8.W), 2 -> 0xef.U(8.W), 3 -> 0xff.U(8.W))
- val y = RegInit(initValue)
- }
-
- "Vec literals should work when used to partially initialize a reg of vec" in {
- val firrtl = (new ChiselStage).emitFirrtl(new HasPartialVecInit, args = Array("--full-stacktrace"))
- firrtl should include("""_y_WIRE[0] <= UInt<8>("hab")""")
- firrtl should include("""_y_WIRE[1] is invalid""")
- firrtl should include("""_y_WIRE[2] <= UInt<8>("hef")""")
- firrtl should include("""_y_WIRE[3] <= UInt<8>("hff")""")
- firrtl should include(""" reset => (reset, _y_WIRE)""".stripMargin)
- }
-
- class ResetRegWithPartialVecLiteral extends Module {
- val in = IO(Input(Vec(4, UInt(8.W))))
- val out = IO(Output(Vec(4, UInt(8.W))))
- val initValue = Vec(4, UInt(8.W)).Lit(0 -> 0xab.U(8.W), 2 -> 0xef.U(8.W), 3 -> 0xff.U(8.W))
- val y = RegInit(initValue)
- when(in(1) > 0.U) {
- y(1) := in(1)
- }
- when(in(2) > 0.U) {
- y(2) := in(2)
- }
- out := y
- }
-
- "Vec literals should only init specified fields when used to partially initialize a reg of vec" in {
- println(ChiselStage.emitFirrtl(new ResetRegWithPartialVecLiteral))
- assertTesterPasses(new BasicTester {
- val m = Module(new ResetRegWithPartialVecLiteral)
- val (counter, wrapped) = Counter(true.B, 8)
- m.in := DontCare
- when(counter < 2.U) {
- m.in(1) := 0xff.U
- m.in(2) := 0xff.U
- }.elsewhen(counter === 2.U) {
- chisel3.assert(m.out(1) === 0xff.U)
- chisel3.assert(m.out(2) === 0xff.U)
- }.elsewhen(counter === 3.U) {
- m.in(1) := 0.U
- m.in(2) := 0.U
- m.reset := true.B
- }.elsewhen(counter > 2.U) {
- // m.out(1) should not be reset, m.out(2) should be reset
- chisel3.assert(m.out(1) === 0xff.U)
- chisel3.assert(m.out(2) === 0xef.U)
- }
- when(wrapped) {
- stop()
- }
- })
- }
-
- "lowest of vec literal contains least significant bits and " in {
- val y = Vec(4, UInt(8.W)).Lit(0 -> 0xab.U(8.W), 1 -> 0xcd.U(8.W), 2 -> 0xef.U(8.W), 3 -> 0xff.U(8.W))
- y.litValue should be(BigInt("FFEFCDAB", 16))
- }
-
- "the order lits are specified does not matter" in {
- val y = Vec(4, UInt(8.W)).Lit(3 -> 0xff.U(8.W), 2 -> 0xef.U(8.W), 1 -> 0xcd.U(8.W), 0 -> 0xab.U(8.W))
- y.litValue should be(BigInt("FFEFCDAB", 16))
- }
-
- "regardless of the literals widths, packing should be done based on the width of the Vec's gen" in {
- val z = Vec(4, UInt(8.W)).Lit(0 -> 0x2.U, 1 -> 0x2.U, 2 -> 0x2.U, 3 -> 0x3.U)
- z.litValue should be(BigInt("03020202", 16))
- }
-
- "packing sparse vec lits should not pack, litOption returns None" in {
- // missing sub-listeral for index 2
- val z = Vec(4, UInt(8.W)).Lit(0 -> 0x2.U, 1 -> 0x2.U, 3 -> 0x3.U)
-
- z.litOption should be(None)
- }
-
- "registers can be initialized with a Vec literal" in {
- assertTesterPasses(new BasicTester {
- val y = RegInit(Vec(4, UInt(8.W)).Lit(0 -> 0xab.U(8.W), 1 -> 0xcd.U(8.W), 2 -> 0xef.U(8.W), 3 -> 0xff.U(8.W)))
- chisel3.assert(y.asUInt === BigInt("FFEFCDAB", 16).U)
- stop()
- })
- }
-
- "how does asUInt work" in {
- assertTesterPasses(new BasicTester {
- val vec1 = Vec(4, UInt(16.W)).Lit(0 -> 0xdd.U, 1 -> 0xcc.U, 2 -> 0xbb.U, 3 -> 0xaa.U)
-
- val vec2 = VecInit(Seq(0xdd.U, 0xcc.U, 0xbb.U, 0xaa.U))
- printf("vec1 %x\n", vec1.asUInt())
- printf("vec2 %x\n", vec2.asUInt())
- stop()
- })
- }
-
- "Vec literals uint conversion" in {
- class M1 extends Module {
- val out1 = IO(Output(UInt(64.W)))
- val out2 = IO(Output(UInt(64.W)))
-
- val v1 = Vec(4, UInt(16.W)).Lit(0 -> 0xdd.U, 1 -> 0xcc.U, 2 -> 0xbb.U, 3 -> 0xaa.U)
- out1 := v1.asUInt
-
- val v2 = VecInit(0xdd.U(16.W), 0xcc.U, 0xbb.U, 0xaa.U)
- out2 := v2.asUInt
- }
-
- assertTesterPasses(new BasicTester {
- val m = Module(new M1)
- chisel3.assert(m.out1 === m.out2)
- stop()
- })
- }
-
- "VecLits should work properly with .asUInt" in {
- val outsideVecLit = Vec(4, UInt(16.W)).Lit(0 -> 0xdd.U, 1 -> 0xcc.U, 2 -> 0xbb.U, 3 -> 0xaa.U)
-
- assertTesterPasses {
- new BasicTester {
- chisel3.assert(outsideVecLit(0) === 0xdd.U, "v(0)")
- stop()
- }
- }
- }
-
- "bundle literals should work in RTL" in {
- val outsideVecLit = Vec(4, UInt(16.W)).Lit(0 -> 0xdd.U, 1 -> 0xcc.U, 2 -> 0xbb.U, 3 -> 0xaa.U)
-
- assertTesterPasses {
- new BasicTester {
- chisel3.assert(outsideVecLit(0) === 0xdd.U, "v(0)")
- chisel3.assert(outsideVecLit(1) === 0xcc.U)
- chisel3.assert(outsideVecLit(2) === 0xbb.U)
- chisel3.assert(outsideVecLit(3) === 0xaa.U)
-
- chisel3.assert(outsideVecLit.litValue.U === outsideVecLit.asUInt())
-
- val insideVecLit = Vec(4, UInt(16.W)).Lit(0 -> 0xdd.U, 1 -> 0xcc.U, 2 -> 0xbb.U, 3 -> 0xaa.U)
- chisel3.assert(insideVecLit(0) === 0xdd.U)
- chisel3.assert(insideVecLit(1) === 0xcc.U)
- chisel3.assert(insideVecLit(2) === 0xbb.U)
- chisel3.assert(insideVecLit(3) === 0xaa.U)
-
- chisel3.assert(insideVecLit(0) === outsideVecLit(0))
- chisel3.assert(insideVecLit(1) === outsideVecLit(1))
- chisel3.assert(insideVecLit(2) === outsideVecLit(2))
- chisel3.assert(insideVecLit(3) === outsideVecLit(3))
-
- val vecWire1 = Wire(Vec(4, UInt(16.W)))
- vecWire1 := outsideVecLit
-
- chisel3.assert(vecWire1(0) === 0xdd.U)
- chisel3.assert(vecWire1(1) === 0xcc.U)
- chisel3.assert(vecWire1(2) === 0xbb.U)
- chisel3.assert(vecWire1(3) === 0xaa.U)
-
- val vecWire2 = Wire(Vec(4, UInt(16.W)))
- vecWire2 := insideVecLit
-
- chisel3.assert(vecWire2(0) === 0xdd.U)
- chisel3.assert(vecWire2(1) === 0xcc.U)
- chisel3.assert(vecWire2(2) === 0xbb.U)
- chisel3.assert(vecWire2(3) === 0xaa.U)
-
- stop()
- }
- }
- }
-
- "partial vec literals should work in RTL" in {
- assertTesterPasses {
- new BasicTester {
- val vecLit = Vec(4, UInt(8.W)).Lit(0 -> 42.U, 2 -> 5.U)
- chisel3.assert(vecLit(0) === 42.U)
- chisel3.assert(vecLit(2) === 5.U)
-
- val vecWire = Wire(Vec(4, UInt(8.W)))
- vecWire := vecLit
-
- chisel3.assert(vecWire(0) === 42.U)
- chisel3.assert(vecWire(2) === 5.U)
-
- stop()
- }
- }
- }
-
- "nested vec literals should be constructable" in {
- val outerVec = Vec(2, Vec(3, UInt(4.W))).Lit(
- 0 -> Vec(3, UInt(4.W)).Lit(0 -> 1.U, 1 -> 2.U, 2 -> 3.U),
- 1 -> Vec(3, UInt(4.W)).Lit(0 -> 4.U, 1 -> 5.U, 2 -> 6.U)
- )
-
- outerVec.litValue should be(BigInt("654321", 16))
- outerVec(0).litValue should be(BigInt("321", 16))
- outerVec(1).litValue should be(BigInt("654", 16))
- outerVec(0)(0).litValue should be(BigInt(1))
- outerVec(0)(1).litValue should be(BigInt(2))
- outerVec(0)(2).litValue should be(BigInt(3))
- outerVec(1)(0).litValue should be(BigInt(4))
- outerVec(1)(1).litValue should be(BigInt(5))
- outerVec(1)(2).litValue should be(BigInt(6))
- }
-
- "contained vecs should work" in {
- assertTesterPasses {
- new BasicTester {
- val outerVec = Vec(2, Vec(3, UInt(4.W))).Lit(
- 0 -> Vec(3, UInt(4.W)).Lit(0 -> 1.U, 1 -> 2.U, 2 -> 3.U),
- 1 -> Vec(3, UInt(4.W)).Lit(0 -> 4.U, 1 -> 5.U, 2 -> 6.U)
- )
-
- chisel3.assert(outerVec(0)(0) === 1.U)
- chisel3.assert(outerVec(0)(1) === 2.U)
- chisel3.assert(outerVec(0)(2) === 3.U)
- chisel3.assert(outerVec(1)(0) === 4.U)
- chisel3.assert(outerVec(1)(1) === 5.U)
- chisel3.assert(outerVec(1)(2) === 6.U)
-
- val v0 = outerVec(0)
- val v1 = outerVec(1)
- chisel3.assert(v0(0) === 1.U)
- chisel3.assert(v0(1) === 2.U)
- chisel3.assert(v0(2) === 3.U)
- chisel3.assert(v1(0) === 4.U)
- chisel3.assert(v1(1) === 5.U)
- chisel3.assert(v1(2) === 6.U)
-
- stop()
- }
- }
- }
-
- //TODO: decide what behavior here should be
- "This doesn't work should it" ignore {
- assertTesterPasses {
- new BasicTester {
- def vecFactory = Vec(2, FixedPoint(8.W, 4.BP))
-
- val vecWire1 = Wire(Output(vecFactory))
- val vecLit1 = vecFactory.Lit(0 -> (1.5).F(8.W, 4.BP))
- val vecLit2 = vecFactory.Lit(1 -> (3.25).F(8.W, 4.BP))
-
- vecWire1 := vecLit1
- vecWire1 := vecLit2
- printf("vw1(0) %x vw1(1) %x\n", vecWire1(0).asUInt(), vecWire1(1).asUInt())
- chisel3.assert(vecWire1(0) === (1.5).F(8.W, 4.BP))
- chisel3.assert(vecWire1(1) === (3.25).F(8.W, 4.BP))
- stop()
- }
- }
- }
-
- "partially initialized Vec literals should assign" in {
- assertTesterPasses {
- new BasicTester {
- def vecFactory = Vec(2, FixedPoint(8.W, 4.BP))
-
- val vecWire1 = Wire(Output(vecFactory))
- val vecWire2 = Wire(Output(vecFactory))
- val vecLit1 = vecFactory.Lit(0 -> (1.5).F(8.W, 4.BP))
- val vecLit2 = vecFactory.Lit(1 -> (3.25).F(8.W, 4.BP))
-
- vecWire1 := vecLit1
- vecWire2 := vecLit2
- vecWire1(1) := (0.5).F(8.W, 4.BP)
- printf("vw1(0) %x vw1(1) %x\n", vecWire1(0).asUInt(), vecWire1(1).asUInt())
- chisel3.assert(vecWire1(0) === (1.5).F(8.W, 4.BP))
- chisel3.assert(vecWire1(1) === (0.5).F(8.W, 4.BP)) // Last connect won
- chisel3.assert(vecWire2(1) === (3.25).F(8.W, 4.BP))
- stop()
- }
- }
- }
-
- "Vec literals should work as register reset values" in {
- assertTesterPasses {
- new BasicTester {
- val r = RegInit(Vec(3, UInt(11.W)).Lit(0 -> 0xa.U, 1 -> 0xb.U, 2 -> 0xc.U))
- r := (r.asUInt + 1.U).asTypeOf(Vec(3, UInt(11.W))) // prevent constprop
-
- // check reset values on first cycle out of reset
- chisel3.assert(r(0) === 0xa.U)
- chisel3.assert(r(1) === 0xb.U)
- chisel3.assert(r(2) === 0xc.U)
- stop()
- }
- }
- }
-
- "partially initialized Vec literals should work as register reset values" in {
- assertTesterPasses {
- new BasicTester {
- val r = RegInit(Vec(3, UInt(11.W)).Lit(0 -> 0xa.U, 2 -> 0xc.U))
- r := (r.asUInt + 1.U).asTypeOf(Vec(3, UInt(11.W))) // prevent constprop
- // check reset values on first cycle out of reset
- chisel3.assert(r(0) === 0xa.U)
- chisel3.assert(r(2) === 0xc.U)
- stop()
- }
- }
- }
-
- "Fields extracted from Vec Literals should work as register reset values" in {
- assertTesterPasses {
- new BasicTester {
- val r = RegInit(Vec(3, UInt(11.W)).Lit(0 -> 0xa.U, 2 -> 0xc.U).apply(0))
- r := r + 1.U // prevent const prop
- chisel3.assert(r === 0xa.U) // coming out of reset
- stop()
- }
- }
- }
-
- "DontCare fields extracted from Vec Literals should work as register reset values" in {
- assertTesterPasses {
- new BasicTester {
- val r = RegInit(Vec(3, Bool()).Lit(0 -> true.B).apply(2))
- r := reset.asBool
- printf(p"r = $r\n") // Can't assert because reset value is DontCare
- stop()
- }
- }
- }
-
- "DontCare fields extracted from Vec Literals should work in other Expressions" in {
- assertTesterPasses {
- new BasicTester {
- val x = Vec(3, Bool()).Lit(0 -> true.B).apply(2) || true.B
- chisel3.assert(x === true.B)
- stop()
- }
- }
- }
-
- "vec literals with non-literal values should fail" in {
- val exc = intercept[VecLiteralException] {
- extractCause[VecLiteralException] {
- ChiselStage.elaborate {
- new RawModule {
- (Vec(3, UInt(11.W)).Lit(0 -> UInt()))
- }
- }
- }
- }
- exc.getMessage should include("field 0 specified with non-literal value UInt")
- }
-
- "vec literals are instantiated on connect and are not bulk connected" in {
- class VecExample5 extends RawModule {
- val out = IO(Output(Vec(2, UInt(4.W))))
- val bundle = Vec(2, UInt(4.W)).Lit(
- 0 -> 0xa.U,
- 1 -> 0xb.U
- )
- out := bundle
- }
-
- val firrtl = (new chisel3.stage.ChiselStage).emitFirrtl(new VecExample5, args = Array("--full-stacktrace"))
- firrtl should include("""out[0] <= UInt<4>("ha")""")
- firrtl should include("""out[1] <= UInt<4>("hb")""")
- }
-
- class SubBundle extends Bundle {
- val foo = UInt(8.W)
- val bar = UInt(4.W)
- }
-
- class VecExample extends RawModule {
- val out = IO(Output(Vec(2, new SubBundle)))
- val bundle = Vec(2, new SubBundle).Lit(
- 0 -> (new SubBundle).Lit(_.foo -> 42.U, _.bar -> 22.U),
- 1 -> (new SubBundle).Lit(_.foo -> 7.U, _.bar -> 3.U)
- )
- out := bundle
- }
-
- "vec literals can contain bundles and should not be bulk connected" in {
- val chirrtl = (new chisel3.stage.ChiselStage).emitChirrtl(new VecExample, args = Array("--full-stacktrace"))
- chirrtl should include("""out[0].bar <= UInt<5>("h16")""")
- chirrtl should include("""out[0].foo <= UInt<6>("h2a")""")
- chirrtl should include("""out[1].bar <= UInt<2>("h3")""")
- chirrtl should include("""out[1].foo <= UInt<3>("h7")""")
- }
-
- "vec literals can have bundle children" in {
- val vec = Vec(2, new SubBundle).Lit(
- 0 -> (new SubBundle).Lit(_.foo -> 0xab.U, _.bar -> 0xc.U),
- 1 -> (new SubBundle).Lit(_.foo -> 0xde.U, _.bar -> 0xf.U)
- )
- vec.litValue.toString(16) should be("defabc")
- }
-
- "vec literals can have bundle children assembled incrementally" in {
- val bundle1 = (new SubBundle).Lit(_.foo -> 0xab.U, _.bar -> 0xc.U)
- val bundle2 = (new SubBundle).Lit(_.foo -> 0xde.U, _.bar -> 0xf.U)
-
- bundle1.litValue.toString(16) should be("abc")
- bundle2.litValue.toString(16) should be("def")
-
- val vec = Vec(2, new SubBundle).Lit(0 -> bundle1, 1 -> bundle2)
-
- vec.litValue.toString(16) should be("defabc")
- }
-
- "bundles can contain vec lits" in {
- val vec1 = Vec(3, UInt(4.W)).Lit(0 -> 0xa.U, 1 -> 0xb.U, 2 -> 0xc.U)
- val vec2 = Vec(2, UInt(4.W)).Lit(0 -> 0xd.U, 1 -> 0xe.U)
- val bundle = (new Bundle {
- val foo = Vec(3, UInt(4.W))
- val bar = Vec(2, UInt(4.W))
- }).Lit(_.foo -> vec1, _.bar -> vec2)
- bundle.litValue.toString(16) should be("cbaed")
- }
-
- "bundles can contain vec lits in-line" in {
- val bundle = (new Bundle {
- val foo = Vec(3, UInt(4.W))
- val bar = Vec(2, UInt(4.W))
- }).Lit(
- _.foo -> Vec(3, UInt(4.W)).Lit(0 -> 0xa.U, 1 -> 0xb.U, 2 -> 0xc.U),
- _.bar -> Vec(2, UInt(4.W)).Lit(0 -> 0xd.U, 1 -> 0xe.U)
- )
- bundle.litValue.toString(16) should be("cbaed")
- }
-
- "Vec.Lit is a trivial Vec literal factory" in {
- val vec = Vec.Lit(0xa.U, 0xb.U)
- vec(0).litValue should be(0xa)
- vec(1).litValue should be(0xb)
- }
-
- "Vec.Lit bases it's element width on the widest literal supplied" in {
- val vec = Vec.Lit(0xa.U, 0xbbbb.U)
- vec(0).litValue should be(0xa)
- vec(1).litValue should be(0xbbbb)
- vec.length should be(2)
- vec.getWidth should be(16 * 2)
- vec.litValue should be(BigInt("bbbb000a", 16))
- }
-}
diff --git a/src/test/scala/chiselTests/VecToTargetSpec.scala b/src/test/scala/chiselTests/VecToTargetSpec.scala
deleted file mode 100644
index 20c6f306..00000000
--- a/src/test/scala/chiselTests/VecToTargetSpec.scala
+++ /dev/null
@@ -1,86 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.stage.ChiselStage
-
-trait VecToTargetSpecUtils extends Utils {
- this: ChiselFunSpec =>
-
- class Foo extends RawModule {
- val vec = IO(Input(Vec(4, Bool())))
-
- // Index a Vec with a Scala literal.
- val scalaLit = 0
- val vecSubaccessScalaLit = vec(scalaLit)
-
- // Index a Vec with a Chisel literal.
- val chiselLit = 0.U
- val vecSubaccessChiselLit = vec(chiselLit)
-
- // Index a Vec with a node.
- val node = IO(Input(UInt(2.W)))
- val vecSubaccessNode = vec(node)
-
- // Put an otherwise un-targetable Vec subaccess into a temp.
- val vecSubaccessTmp = WireInit(vecSubaccessNode)
- }
-
- val expectedError = "You cannot target Vec subaccess:"
-
- def conversionSucceeds(data: InstanceId) = {
- describe(".toTarget") {
- it("should convert successfully") {
- data.toTarget
- }
- }
-
- describe(".toNamed") {
- it("should convert successfully") {
- data.toNamed
- }
- }
- }
-
- def conversionFails(data: InstanceId) = {
- describe(".toTarget") {
- it("should fail to convert with a useful error message") {
- (the[ChiselException] thrownBy extractCause[ChiselException] {
- data.toTarget
- }).getMessage should include(expectedError)
- }
- }
-
- describe(".toNamed") {
- it("should fail to convert with a useful error message") {
- (the[ChiselException] thrownBy extractCause[ChiselException] {
- data.toNamed
- }).getMessage should include(expectedError)
- }
- }
- }
-}
-
-class VecToTargetSpec extends ChiselFunSpec with VecToTargetSpecUtils {
- describe("Vec subaccess") {
- var foo: Foo = null
- ChiselStage.elaborate { foo = new Foo; foo }
-
- describe("with a Scala literal") {
- (it should behave).like(conversionSucceeds(foo.vecSubaccessScalaLit))
- }
-
- describe("with a Chisel literal") {
- (it should behave).like(conversionFails(foo.vecSubaccessChiselLit))
- }
-
- describe("with a Node") {
- (it should behave).like(conversionFails(foo.vecSubaccessNode))
- }
-
- describe("with an un-targetable construct that is assigned to a temporary") {
- (it should behave).like(conversionSucceeds(foo.vecSubaccessTmp))
- }
- }
-}
diff --git a/src/test/scala/chiselTests/VectorPacketIO.scala b/src/test/scala/chiselTests/VectorPacketIO.scala
deleted file mode 100644
index 1474177f..00000000
--- a/src/test/scala/chiselTests/VectorPacketIO.scala
+++ /dev/null
@@ -1,71 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.testers.BasicTester
-import chisel3.util._
-
-/**
- * This test used to fail when assignment statements were
- * contained in DeqIO and EnqIO constructors.
- * The symptom is creation of a firrtl file
- * with missing declarations, the problem is exposed by
- * the creation of the val outs in VectorPacketIO
- *
- * NOTE: The problem does not exist now because the initialization
- * code has been removed from DeqIO and EnqIO
- *
- * IMPORTANT: The canonical way to initialize a decoupled inteface is still being debated.
- */
-class Packet extends Bundle {
- val header = UInt(1.W)
-}
-
-/**
- * The problem occurs with just the ins or the outs
- * lines also.
- * The problem does not occur if the Vec is taken out
- */
-class VectorPacketIO(val n: Int) extends Bundle {
- val ins = Vec(n, chisel3.util.DeqIO(new Packet()))
- val outs = Vec(n, chisel3.util.EnqIO(new Packet()))
-}
-
-/**
- * a module uses the vector based IO bundle
- * the value of n does not affect the error
- */
-class BrokenVectorPacketModule extends Module {
- val n = 4
- val io = IO(new VectorPacketIO(n))
-
- // Avoid a "Reference io is not fully initialized" error from firrtl.
- for (i <- 0 until n) {
- io.outs(i) <> io.ins(i)
- }
-
- /* the following method of initializing the circuit may change in the future */
- io.ins.foreach(_.nodeq())
- io.outs.foreach(_.noenq())
-}
-
-class VectorPacketIOUnitTester extends BasicTester {
- val dut = Module(new BrokenVectorPacketModule)
- dut.io <> DontCare
-
- // This counter just makes the test end quicker
- val c = Counter(1)
- when(c.inc()) {
- stop()
- }
-}
-
-class VectorPacketIOUnitTesterSpec extends ChiselFlatSpec {
- "a circuit using an io containing a vector of EnqIO wrapped packets" should
- "compile and run" in {
- assertTesterPasses {
- new VectorPacketIOUnitTester
- }
- }
-}
diff --git a/src/test/scala/chiselTests/VerificationSpec.scala b/src/test/scala/chiselTests/VerificationSpec.scala
deleted file mode 100644
index 32cee9e3..00000000
--- a/src/test/scala/chiselTests/VerificationSpec.scala
+++ /dev/null
@@ -1,156 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.experimental.{ChiselAnnotation, verification => formal}
-import chisel3.stage.ChiselStage
-import firrtl.annotations.{ReferenceTarget, SingleTargetAnnotation}
-import org.scalatest.matchers.should.Matchers
-
-import java.io.File
-
-class SimpleTest extends Module {
- val io = IO(new Bundle {
- val in = Input(UInt(8.W))
- val out = Output(UInt(8.W))
- })
- io.out := io.in
- cover(io.in === 3.U)
- when(io.in === 3.U) {
- assume(io.in =/= 2.U)
- assert(io.out === io.in)
- }
-}
-
-/** Dummy verification annotation.
- * @param target target of component to be annotated
- */
-case class VerifAnnotation(target: ReferenceTarget) extends SingleTargetAnnotation[ReferenceTarget] {
- def duplicate(n: ReferenceTarget): VerifAnnotation = this.copy(target = n)
-}
-
-object VerifAnnotation {
-
- /** Create annotation for a given verification component.
- * @param c component to be annotated
- */
- def annotate(c: VerificationStatement): Unit = {
- chisel3.experimental.annotate(new ChiselAnnotation {
- def toFirrtl: VerifAnnotation = VerifAnnotation(c.toTarget)
- })
- }
-}
-
-class VerificationSpec extends ChiselPropSpec with Matchers {
-
- def assertContains(s: Seq[String], x: String): Unit = {
- val containsLine = s.map(_.contains(x)).reduce(_ || _)
- assert(containsLine, s"\n $x\nwas not found in`\n ${s.mkString("\n ")}``")
- }
-
- property("basic equality check should work") {
- val fir = ChiselStage.emitChirrtl(new SimpleTest)
- val lines = fir.split("\n").map(_.trim)
-
- // reset guard around the verification statement
- assertContains(lines, "when _T_2 : @[VerificationSpec.scala")
- assertContains(lines, "cover(clock, _T, UInt<1>(\"h1\"), \"\")")
-
- assertContains(lines, "when _T_6 : @[VerificationSpec.scala")
- assertContains(lines, "assume(clock, _T_4, UInt<1>(\"h1\"), \"\")")
-
- assertContains(lines, "when _T_10 : @[VerificationSpec.scala")
- assertContains(lines, "assert(clock, _T_8, UInt<1>(\"h1\"), \"\")")
- }
-
- property("annotation of verification constructs should work") {
-
- /** Circuit that contains and annotates verification nodes. */
- class AnnotationTest extends Module {
- val io = IO(new Bundle {
- val in = Input(UInt(8.W))
- val out = Output(UInt(8.W))
- })
- io.out := io.in
- val cov = cover(io.in === 3.U)
- val assm = chisel3.assume(io.in =/= 2.U)
- val asst = chisel3.assert(io.out === io.in)
- VerifAnnotation.annotate(cov)
- VerifAnnotation.annotate(assm)
- VerifAnnotation.annotate(asst)
- }
-
- // compile circuit
- val testDir = new File("test_run_dir", "VerificationAnnotationTests")
- (new ChiselStage).emitSystemVerilog(
- gen = new AnnotationTest,
- args = Array("-td", testDir.getPath)
- )
-
- // read in annotation file
- val annoFile = new File(testDir, "AnnotationTest.anno.json")
- annoFile should exist
- val annoLines = scala.io.Source.fromFile(annoFile).getLines.toList
-
- // check for expected verification annotations
- exactly(3, annoLines) should include("chiselTests.VerifAnnotation")
- exactly(1, annoLines) should include("~AnnotationTest|AnnotationTest>asst")
- exactly(1, annoLines) should include("~AnnotationTest|AnnotationTest>assm")
- exactly(1, annoLines) should include("~AnnotationTest|AnnotationTest>cov")
-
- // read in FIRRTL file
- val firFile = new File(testDir, "AnnotationTest.fir")
- firFile should exist
- val firLines = scala.io.Source.fromFile(firFile).getLines.toList
-
- // check that verification components have expected names
- (exactly(1, firLines) should include).regex("^\\s*cover\\(.*\\) : cov")
- (exactly(1, firLines) should include).regex("^\\s*assume\\(.*\\) : assm")
- (exactly(1, firLines) should include).regex("^\\s*assert\\(.*\\) : asst")
- }
-
- property("annotation of verification constructs with suggested name should work") {
-
- /** Circuit that annotates a renamed verification nodes. */
- class AnnotationRenameTest extends Module {
- val io = IO(new Bundle {
- val in = Input(UInt(8.W))
- val out = Output(UInt(8.W))
- })
- io.out := io.in
-
- val goodbye = chisel3.assert(io.in === 1.U)
- goodbye.suggestName("hello")
- VerifAnnotation.annotate(goodbye)
-
- VerifAnnotation.annotate(chisel3.assume(io.in =/= 2.U).suggestName("howdy"))
- }
-
- // compile circuit
- val testDir = new File("test_run_dir", "VerificationAnnotationRenameTests")
- (new ChiselStage).emitSystemVerilog(
- gen = new AnnotationRenameTest,
- args = Array("-td", testDir.getPath)
- )
-
- // read in annotation file
- val annoFile = new File(testDir, "AnnotationRenameTest.anno.json")
- annoFile should exist
- val annoLines = scala.io.Source.fromFile(annoFile).getLines.toList
-
- // check for expected verification annotations
- exactly(2, annoLines) should include("chiselTests.VerifAnnotation")
- exactly(1, annoLines) should include("~AnnotationRenameTest|AnnotationRenameTest>hello")
- exactly(1, annoLines) should include("~AnnotationRenameTest|AnnotationRenameTest>howdy")
-
- // read in FIRRTL file
- val firFile = new File(testDir, "AnnotationRenameTest.fir")
- firFile should exist
- val firLines = scala.io.Source.fromFile(firFile).getLines.toList
-
- // check that verification components have expected names
- (exactly(1, firLines) should include).regex("^\\s*assert\\(.*\\) : hello")
- (exactly(1, firLines) should include).regex("^\\s*assume\\(.*\\) : howdy")
- }
-}
diff --git a/src/test/scala/chiselTests/WarningSpec.scala b/src/test/scala/chiselTests/WarningSpec.scala
deleted file mode 100644
index 1bb9e6dc..00000000
--- a/src/test/scala/chiselTests/WarningSpec.scala
+++ /dev/null
@@ -1,40 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.util._
-import chisel3.stage.ChiselStage
-
-class WarningSpec extends ChiselFlatSpec with Utils {
- behavior.of("Warnings")
-
- object MyEnum extends ChiselEnum {
- val e0, e1, e2 = Value
- }
-
- class MyModule extends Module {
- val in = IO(Input(UInt(2.W)))
- val out1 = IO(Output(MyEnum()))
- val out2 = IO(Output(MyEnum()))
- def func(out: EnumType): Unit = {
- out := MyEnum(in)
- }
- func(out1)
- func(out2)
- }
-
- "Warnings" should "be de-duplicated" in {
- val (log, _) = grabLog(ChiselStage.elaborate(new MyModule))
- def countSubstring(s: String, sub: String) =
- s.sliding(sub.length).count(_ == sub)
- countSubstring(log, "Casting non-literal UInt") should be(1)
- }
-
- "Warnings" should "be treated as errors with warningsAsErrors" in {
- a[ChiselException] should be thrownBy extractCause[ChiselException] {
- val args = Array("--warnings-as-errors")
- (new ChiselStage).emitChirrtl(new MyModule, args)
- }
- }
-}
diff --git a/src/test/scala/chiselTests/When.scala b/src/test/scala/chiselTests/When.scala
deleted file mode 100644
index 032a8eac..00000000
--- a/src/test/scala/chiselTests/When.scala
+++ /dev/null
@@ -1,168 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.stage.ChiselStage
-import chisel3.testers.BasicTester
-import chisel3.util._
-
-class WhenTester() extends BasicTester {
- val cnt = Counter(4)
- when(true.B) { cnt.inc() }
-
- val out = Wire(UInt(3.W))
- when(cnt.value === 0.U) {
- out := 1.U
- }.elsewhen(cnt.value === 1.U) {
- out := 2.U
- }.elsewhen(cnt.value === 2.U) {
- out := 3.U
- }.otherwise {
- out := 0.U
- }
-
- assert(out === cnt.value + 1.U)
-
- when(cnt.value === 3.U) {
- stop()
- }
-}
-
-class OverlappedWhenTester() extends BasicTester {
- val cnt = Counter(4)
- when(true.B) { cnt.inc() }
-
- val out = Wire(UInt(3.W))
- when(cnt.value <= 0.U) {
- out := 1.U
- }.elsewhen(cnt.value <= 1.U) {
- out := 2.U
- }.elsewhen(cnt.value <= 2.U) {
- out := 3.U
- }.otherwise {
- out := 0.U
- }
-
- assert(out === cnt.value + 1.U)
-
- when(cnt.value === 3.U) {
- stop()
- }
-}
-
-class NoOtherwiseOverlappedWhenTester() extends BasicTester {
- val cnt = Counter(4)
- when(true.B) { cnt.inc() }
-
- val out = Wire(UInt(3.W))
- when(cnt.value <= 0.U) {
- out := 1.U
- }.elsewhen(cnt.value <= 1.U) {
- out := 2.U
- }.elsewhen(cnt.value <= 2.U) {
- out := 3.U
- }.elsewhen(cnt.value <= 3.U) {
- out := 0.U
- }.otherwise {
- out := DontCare
- }
-
- assert(out === cnt.value + 1.U)
-
- when(cnt.value === 3.U) {
- stop()
- }
-}
-
-class SubmoduleWhenTester extends BasicTester {
- val (cycle, done) = Counter(true.B, 3)
- when(done) { stop() }
- val children =
- Seq(Module(new PassthroughModule), Module(new PassthroughMultiIOModule), Module(new PassthroughRawModule))
- children.foreach { child =>
- when(cycle === 1.U) {
- child.io.in := "hdeadbeef".U
- assert(child.io.out === "hdeadbeef".U)
- }.otherwise {
- child.io.in := "h0badcad0".U
- assert(child.io.out === "h0badcad0".U)
- }
- }
-}
-
-class WhenCondTester extends BasicTester {
- val pred = Wire(Vec(4, Bool()))
- val (cycle, done) = Counter(true.B, 1 << pred.size)
- // Cycle through every predicate
- pred := cycle.asBools
- val Seq(a, b, c, d) = pred // Just for nicer accessors
- // When want the when predicates on connection to optimize away,
- // it's not necessary but it makes the Verilog prettier
- val w1, w2, w3, w4, w5, w6, w7 = WireInit(Bool(), DontCare)
- when(a) {
- w1 := when.cond
- when(b) {
- w2 := when.cond
- }.elsewhen(c) {
- w3 := when.cond
- }.elsewhen(d) {
- w4 := when.cond
- }.otherwise {
- w5 := when.cond
- }
- }.otherwise {
- w6 := when.cond
- }
- w7 := when.cond
-
- assert(w1 === a)
- assert(w2 === (a && b))
- assert(w3 === (a && !b && c))
- assert(w4 === (a && !b && !c && d))
- assert(w5 === (a && !b && !c && !d))
- assert(w6 === !a)
- assert(w7)
-
- when(done) { stop() }
-}
-
-class WhenSpec extends ChiselFlatSpec with Utils {
- "When, elsewhen, and otherwise with orthogonal conditions" should "work" in {
- assertTesterPasses { new WhenTester }
- }
- "When, elsewhen, and otherwise with overlapped conditions" should "work" in {
- assertTesterPasses { new OverlappedWhenTester }
- }
- "When and elsewhen without otherwise with overlapped conditions" should "work" in {
- assertTesterPasses { new NoOtherwiseOverlappedWhenTester }
- }
- "Conditional connections to submodule ports" should "be handled properly" in {
- assertTesterPasses(new SubmoduleWhenTester)
- }
- "when.cond" should "give the current when condition" in {
- assertTesterPasses(new WhenCondTester)
- }
-
- "Returning in a when scope" should "give a reasonable error message" in {
- 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))
- val cond = Input(Bool())
- val out = Output(UInt(8.W))
- })
- def func(): UInt = {
- when(io.cond) {
- // This is bad, do not do this!!!
- return io.foo
- }
- return io.bar
- }
- io.out := func()
- })
- }
- e.getMessage should include("Cannot exit from a when() block with a \"return\"")
- }
-}
diff --git a/src/test/scala/chiselTests/WidthSpec.scala b/src/test/scala/chiselTests/WidthSpec.scala
deleted file mode 100644
index 77a09e1c..00000000
--- a/src/test/scala/chiselTests/WidthSpec.scala
+++ /dev/null
@@ -1,250 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-
-class SimpleBundle extends Bundle {
- val x = UInt(4.W)
- val y = UInt()
-}
-object SimpleBundle {
- def intoWire(): SimpleBundle = {
- val w = Wire(new SimpleBundle)
- w.x := 0.U(4.W)
- w.y := 0.U(4.W)
- w
- }
-}
-
-class WidthSpec extends ChiselFlatSpec {
- "Literals without specified widths" should "get the minimum legal width" in {
- "hdeadbeef".U.getWidth should be(32)
- "h_dead_beef".U.getWidth should be(32)
- "h0a".U.getWidth should be(4)
- "h1a".U.getWidth should be(5)
- "h0".U.getWidth should be(1)
- 1.U.getWidth should be(1)
- 1.S.getWidth should be(2)
- }
-}
-
-abstract class WireRegWidthSpecImpl extends ChiselFlatSpec {
- def name: String
- def builder[T <: Data](x: T): T
-
- behavior.of(name)
-
- it should "set the width if the template type has a set width" in {
- assertKnownWidth(4) {
- builder(UInt(4.W))
- }
- assertKnownWidth(4) {
- val w = builder(new SimpleBundle)
- w := SimpleBundle.intoWire()
- w.x
- }
- assertKnownWidth(4) {
- val x = builder(Vec(1, UInt(4.W)))
- x(0)
- }
- }
-
- it should "infer the width if the template type has no width" in {
- assertInferredWidth(4) {
- val w = builder(UInt())
- w := 0.U(4.W)
- w
- }
- assertInferredWidth(4) {
- val w = builder(new SimpleBundle)
- w := SimpleBundle.intoWire()
- w.y
- }
- assertInferredWidth(4) {
- val w = builder(Vec(1, UInt()))
- w(0) := 0.U(4.W)
- w(0)
- }
- }
-}
-
-class WireWidthSpec extends WireRegWidthSpecImpl {
- def name: String = "Wire"
- def builder[T <: Data](x: T): T = Wire(x)
-}
-class RegWidthSpec extends WireRegWidthSpecImpl {
- def name: String = "Reg"
- def builder[T <: Data](x: T): T = Reg(x)
-}
-
-abstract class WireDefaultRegInitSpecImpl extends ChiselFlatSpec {
- def name: String
- def builder1[T <: Data](x: T): T
- def builder2[T <: Data](x: T, y: T): T
-
- behavior.of(s"$name (Single Argument)")
-
- it should "set width if passed a literal with forced width" in {
- assertKnownWidth(4) {
- builder1(3.U(4.W))
- }
- }
-
- it should "NOT set width if passed a literal without a forced width" in {
- assertInferredWidth(4) {
- val w = builder1(3.U)
- w := 3.U(4.W)
- w
- }
- }
-
- it should "NOT set width if passed a non-literal" in {
- assertInferredWidth(4) {
- val w = WireDefault(3.U(4.W))
- builder1(w)
- }
- }
-
- it should "copy the widths of aggregates" in {
- assertInferredWidth(4) {
- val w = builder1(SimpleBundle.intoWire())
- w.y
- }
- assertKnownWidth(4) {
- val w = builder1(SimpleBundle.intoWire())
- w.x
- }
- assertInferredWidth(4) {
- val x = Wire(Vec(1, UInt()))
- x(0) := 0.U(4.W)
- val w = builder1(x)
- w(0)
- }
- assertKnownWidth(4) {
- val x = Wire(Vec(1, UInt(4.W)))
- x(0) := 0.U(4.W)
- val w = builder1(x)
- w(0)
- }
- }
-
- behavior.of(s"$name (Double Argument)")
-
- it should "set the width if the template type has a set width" in {
- assertKnownWidth(4) {
- WireDefault(UInt(4.W), 0.U)
- }
- assertKnownWidth(4) {
- WireDefault(UInt(4.W), 0.U(2.W))
- }
- assertKnownWidth(4) {
- val w = WireDefault(new SimpleBundle, SimpleBundle.intoWire())
- w.x
- }
- assertKnownWidth(4) {
- val x = Wire(Vec(1, UInt()))
- x(0) := 0.U(4.W)
- val w = WireDefault(Vec(1, UInt(4.W)), x)
- w(0)
- }
- }
-
- it should "infer the width if the template type has no width" in {
- val templates = Seq(
- () => 0.U,
- () => 0.U(2.W),
- () => WireDefault(0.U),
- () => WireDefault(0.U(2.W))
- )
- for (gen <- templates) {
- assertInferredWidth(4) {
- val w = WireDefault(UInt(), gen())
- w := 0.U(4.W)
- w
- }
- }
- assertInferredWidth(4) {
- val w = WireDefault(new SimpleBundle, SimpleBundle.intoWire())
- w.y
- }
- assertInferredWidth(4) {
- val x = Wire(Vec(1, UInt()))
- x(0) := 0.U(4.W)
- val w = WireDefault(Vec(1, UInt()), x)
- w(0)
- }
- }
-}
-
-class WireDefaultWidthSpec extends WireDefaultRegInitSpecImpl {
- def name: String = "WireDefault"
- def builder1[T <: Data](x: T): T = WireDefault(x)
- def builder2[T <: Data](x: T, y: T): T = WireDefault(x, y)
-}
-
-class RegInitWidthSpec extends WireDefaultRegInitSpecImpl {
- def name: String = "RegInit"
- def builder1[T <: Data](x: T): T = RegInit(x)
- def builder2[T <: Data](x: T, y: T): T = RegInit(x, y)
-}
-
-class OpWidthSpec extends ChiselFlatSpec {
- import firrtl._
- import firrtl.ir._
-
- val maxWidth = 5
- val uIntOps: Seq[((UInt, UInt) => UInt, PrimOp)] =
- Seq(
- (_ +& _, PrimOps.Add),
- (_ -& _, PrimOps.Sub),
- (_ * _, PrimOps.Mul),
- (_ / _, PrimOps.Div),
- (_ % _, PrimOps.Rem),
- (_ << _, PrimOps.Dshl),
- (_ >> _, PrimOps.Dshr)
- )
-
- assertTesterPasses(new chisel3.testers.BasicTester {
- for (i <- 0 to maxWidth) {
- for (j <- 0 to maxWidth) {
- for ((cOp, fOp) <- uIntOps) {
- val args = Seq(i, j).map(w => Reference("", UIntType(IntWidth(w))))
- fOp.propagateType(DoPrim(fOp, args, Nil, UnknownType)) match {
- case UIntType(IntWidth(w)) =>
- val x = 0.U(maxWidth.W).head(i)
- val y = 0.U(maxWidth.W).head(j)
- assert(w == cOp(x, y).getWidth)
- }
- }
- }
- }
- stop()
- })
-
- val sIntOps: Seq[((SInt, SInt) => SInt, PrimOp)] =
- Seq(
- (_ +& _, PrimOps.Add),
- (_ -& _, PrimOps.Sub),
- (_ * _, PrimOps.Mul),
- (_ / _, PrimOps.Div),
- (_ % _, PrimOps.Rem)
- )
-
- assertTesterPasses(new chisel3.testers.BasicTester {
- for (i <- 0 to maxWidth) {
- for (j <- 0 to maxWidth) {
- for ((cOp, fOp) <- sIntOps) {
- val args = Seq(i, j).map(w => Reference("", SIntType(IntWidth(w))))
- fOp.propagateType(DoPrim(fOp, args, Nil, UnknownType)) match {
- case SIntType(IntWidth(w)) =>
- val x = 0.U(maxWidth.W).head(i).asSInt
- val y = 0.U(maxWidth.W).head(j).asSInt
- assert(w == cOp(x, y).getWidth)
- }
- }
- }
- }
- stop()
- })
-}
diff --git a/src/test/scala/chiselTests/WireSpec.scala b/src/test/scala/chiselTests/WireSpec.scala
deleted file mode 100644
index 058a7f08..00000000
--- a/src/test/scala/chiselTests/WireSpec.scala
+++ /dev/null
@@ -1,36 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.stage.ChiselStage
-
-class WireSpec extends ChiselFlatSpec {
- "WireDefault.apply" should "work" in {
- assertCompiles("WireDefault(UInt(4.W), 2.U)")
- }
- it should "allow DontCare" in {
- assertCompiles("WireDefault(UInt(4.W), DontCare)")
- }
- it should "not allow DontCare to affect type inference" in {
- assertCompiles("val x: UInt = WireDefault(UInt(4.W), DontCare)")
- }
- it should "not allow init argument to affect type inference" in {
- assertDoesNotCompile("val x: UInt = WireDefault(UInt(4.W), 2.S)")
- }
- it should "have source locator information on wires" in {
- class Dummy extends chisel3.Module {
- val in = IO(Input(Bool()))
- val out = IO(Output(Bool()))
-
- val wire = WireInit(Bool(), true.B)
- val wire2 = Wire(Bool())
- wire2 := in
- out := in & wire & wire2
- }
-
- val chirrtl = ChiselStage.emitChirrtl(new Dummy)
- chirrtl should include("wire wire : UInt<1> @[WireSpec.scala")
- chirrtl should include("wire wire2 : UInt<1> @[WireSpec.scala")
- }
-}
diff --git a/src/test/scala/chiselTests/aop/InjectionSpec.scala b/src/test/scala/chiselTests/aop/InjectionSpec.scala
deleted file mode 100644
index 1b69efa3..00000000
--- a/src/test/scala/chiselTests/aop/InjectionSpec.scala
+++ /dev/null
@@ -1,180 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.aop
-
-import chisel3.testers.{BasicTester, TesterDriver}
-import chiselTests.{ChiselFlatSpec, Utils}
-import chisel3._
-import chisel3.aop.Select
-import chisel3.aop.injecting.InjectingAspect
-import logger.{LogLevel, LogLevelAnnotation}
-
-object InjectionHierarchy {
-
- class SubmoduleManipulationTester extends BasicTester {
- val moduleSubmoduleA = Module(new SubmoduleA)
- }
-
- class MultiModuleInjectionTester extends BasicTester {
- val subA0 = Module(new SubmoduleA)
- val subA1 = Module(new SubmoduleA)
- }
-
- class SubmoduleA extends Module {
- val io = IO(new Bundle {
- val out = Output(Bool())
- })
- io.out := false.B
- }
-
- class SubmoduleB extends Module {
- val io = IO(new Bundle {
- val in = Input(Bool())
- })
- }
-
- class SubmoduleC extends experimental.ExtModule with util.HasExtModuleInline {
- val io = IO(new Bundle {
- val in = Input(Bool())
- })
- //scalastyle:off regex
- setInline(
- "SubmoduleC.v",
- s"""
- |module SubmoduleC(
- | input io_in
- |);
- |endmodule
- """.stripMargin
- )
- }
-
- class AspectTester(results: Seq[Int]) extends BasicTester {
- val values = VecInit(results.map(_.U))
- val counter = RegInit(0.U(results.length.W))
- counter := counter + 1.U
- when(counter >= values.length.U) {
- stop()
- }.otherwise {
- when(reset.asBool() === false.B) {
- assert(counter === values(counter))
- }
- }
- }
-}
-
-class InjectionSpec extends ChiselFlatSpec with Utils {
- import InjectionHierarchy._
- val correctValueAspect = InjectingAspect(
- { dut: AspectTester => Seq(dut) },
- { dut: AspectTester =>
- for (i <- 0 until dut.values.length) {
- dut.values(i) := i.U
- }
- }
- )
-
- val wrongValueAspect = InjectingAspect(
- { dut: AspectTester => Seq(dut) },
- { dut: AspectTester =>
- for (i <- 0 until dut.values.length) {
- dut.values(i) := (i + 1).U
- }
- }
- )
-
- val manipulateSubmoduleAspect = InjectingAspect(
- { dut: SubmoduleManipulationTester => Seq(dut) },
- { dut: SubmoduleManipulationTester =>
- val moduleSubmoduleB = Module(new SubmoduleB)
- moduleSubmoduleB.io.in := dut.moduleSubmoduleA.io.out
- //if we're here then we've elaborated correctly
- stop()
- }
- )
-
- val duplicateSubmoduleAspect = InjectingAspect(
- { dut: SubmoduleManipulationTester => Seq(dut) },
- { _: SubmoduleManipulationTester =>
- // By creating a second SubmoduleA, the module names would conflict unless they were uniquified
- val moduleSubmoduleA2 = Module(new SubmoduleA)
- //if we're here then we've elaborated correctly
- stop()
- }
- )
-
- val addingExternalModules = InjectingAspect(
- { dut: SubmoduleManipulationTester => Seq(dut) },
- { _: SubmoduleManipulationTester =>
- // By creating a second SubmoduleA, the module names would conflict unless they were uniquified
- val moduleSubmoduleC = Module(new SubmoduleC)
- moduleSubmoduleC.io <> DontCare
- //if we're here then we've elaborated correctly
- stop()
- }
- )
-
- val multiModuleInjectionAspect = InjectingAspect(
- { top: MultiModuleInjectionTester =>
- Select.collectDeep(top) { case m: SubmoduleA => m }
- },
- { m: Module =>
- val wire = Wire(Bool())
- wire := m.reset.asBool()
- dontTouch(wire)
- stop()
- }
- )
-
- "Test" should "pass if inserted the correct values" in {
- assertTesterPasses { new AspectTester(Seq(0, 1, 2)) }
- }
- "Test" should "fail if inserted the wrong values" in {
- assertTesterFails { new AspectTester(Seq(9, 9, 9)) }
- }
- "Test" should "pass if pass wrong values, but correct with aspect" in {
- assertTesterPasses({ new AspectTester(Seq(9, 9, 9)) }, Nil, Seq(correctValueAspect) ++ TesterDriver.verilatorOnly)
- }
- "Test" should "pass if pass wrong values, then wrong aspect, then correct aspect" in {
- assertTesterPasses(
- new AspectTester(Seq(9, 9, 9)),
- Nil,
- Seq(wrongValueAspect, correctValueAspect) ++ TesterDriver.verilatorOnly
- )
- }
- "Test" should "fail if pass wrong values, then correct aspect, then wrong aspect" in {
- assertTesterFails({ new AspectTester(Seq(9, 9, 9)) }, Nil, Seq(correctValueAspect, wrongValueAspect))
- }
-
- "Test" should "pass if the submodules in SubmoduleManipulationTester can be manipulated by manipulateSubmoduleAspect" in {
- assertTesterPasses(
- { new SubmoduleManipulationTester },
- Nil,
- Seq(manipulateSubmoduleAspect) ++ TesterDriver.verilatorOnly
- )
- }
-
- "Module name collisions when adding a new module" should "be resolved" in {
- assertTesterPasses(
- { new SubmoduleManipulationTester },
- Nil,
- Seq(duplicateSubmoduleAspect) ++ TesterDriver.verilatorOnly
- )
- }
-
- "Adding external modules" should "work" in {
- assertTesterPasses(
- { new SubmoduleManipulationTester },
- Nil,
- Seq(addingExternalModules) ++ TesterDriver.verilatorOnly
- )
- }
-
- "Injection into multiple submodules of the same class" should "work" in {
- assertTesterPasses(
- { new MultiModuleInjectionTester },
- Nil,
- Seq(multiModuleInjectionAspect) ++ TesterDriver.verilatorOnly
- )
- }
-}
diff --git a/src/test/scala/chiselTests/aop/SelectSpec.scala b/src/test/scala/chiselTests/aop/SelectSpec.scala
deleted file mode 100644
index 72802c80..00000000
--- a/src/test/scala/chiselTests/aop/SelectSpec.scala
+++ /dev/null
@@ -1,230 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.aop
-
-import chisel3.testers.BasicTester
-import chiselTests.ChiselFlatSpec
-import chisel3._
-import chisel3.aop.Select.{PredicatedConnect, When, WhenNot}
-import chisel3.aop.{Aspect, Select}
-import chisel3.experimental.ExtModule
-import chisel3.stage.{ChiselGeneratorAnnotation, DesignAnnotation}
-import firrtl.AnnotationSeq
-
-import scala.reflect.runtime.universe.TypeTag
-
-class SelectTester(results: Seq[Int]) extends BasicTester {
- val values = VecInit(results.map(_.U))
- val counter = RegInit(0.U(results.length.W))
- val added = counter + 1.U
- counter := added
- val overflow = counter >= values.length.U
- val nreset = reset.asBool() === false.B
- val selected = values(counter)
- val zero = 0.U + 0.U
- var p: printf.Printf = null
- when(overflow) {
- counter := zero
- stop()
- }.otherwise {
- when(nreset) {
- assert(counter === values(counter))
- p = printf("values(%d) = %d\n", counter, selected)
- }
-
- }
-}
-
-case class SelectAspect[T <: RawModule, X](selector: T => Seq[X], desired: T => Seq[X]) extends Aspect[T] {
- override def toAnnotation(top: T): AnnotationSeq = {
- val results = selector(top)
- val desiredSeq = desired(top)
- assert(
- results.length == desiredSeq.length,
- s"Failure! Results $results have different length than desired $desiredSeq!"
- )
- val mismatches = results.zip(desiredSeq).flatMap {
- case (res, des) if res != des => Seq((res, des))
- case other => Nil
- }
- assert(
- mismatches.isEmpty,
- s"Failure! The following selected items do not match their desired item:\n" + mismatches.map {
- case (res: Select.Serializeable, des: Select.Serializeable) =>
- s" ${res.serialize} does not match:\n ${des.serialize}"
- case (res, des) => s" $res does not match:\n $des"
- }.mkString("\n")
- )
- Nil
- }
-}
-
-class SelectSpec extends ChiselFlatSpec {
-
- def execute[T <: RawModule, X](
- dut: () => T,
- selector: T => Seq[X],
- desired: T => Seq[X]
- )(
- implicit tTag: TypeTag[T]
- ): Unit = {
- val ret = new chisel3.stage.ChiselStage().run(
- Seq(
- new chisel3.stage.ChiselGeneratorAnnotation(dut),
- SelectAspect(selector, desired),
- new chisel3.stage.ChiselOutputFileAnnotation("test_run_dir/Select.fir")
- )
- )
- }
-
- "Test" should "pass if selecting correct registers" in {
- execute(
- () => new SelectTester(Seq(0, 1, 2)),
- { dut: SelectTester => Select.registers(dut) },
- { dut: SelectTester => Seq(dut.counter) }
- )
- }
-
- "Test" should "pass if selecting correct wires" in {
- execute(
- () => new SelectTester(Seq(0, 1, 2)),
- { dut: SelectTester => Select.wires(dut) },
- { dut: SelectTester => Seq(dut.values) }
- )
- }
-
- "Test" should "pass if selecting correct printfs" in {
- execute(
- () => new SelectTester(Seq(0, 1, 2)),
- { dut: SelectTester => Seq(Select.printfs(dut).last.toString) },
- { dut: SelectTester =>
- Seq(
- Select
- .Printf(
- dut.p,
- Seq(
- When(Select.ops("eq")(dut).last.asInstanceOf[Bool]),
- When(dut.nreset),
- WhenNot(dut.overflow)
- ),
- dut.p.pable,
- dut.clock
- )
- .toString
- )
- }
- )
- }
-
- "Test" should "pass if selecting correct connections" in {
- execute(
- () => new SelectTester(Seq(0, 1, 2)),
- { dut: SelectTester => Select.connectionsTo(dut)(dut.counter) },
- { dut: SelectTester =>
- Seq(
- PredicatedConnect(Nil, dut.counter, dut.added, false),
- PredicatedConnect(Seq(When(dut.overflow)), dut.counter, dut.zero, false)
- )
- }
- )
- }
-
- "Test" should "pass if selecting ops by kind" in {
- execute(
- () => new SelectTester(Seq(0, 1, 2)),
- { dut: SelectTester => Select.ops("tail")(dut) },
- { dut: SelectTester => Seq(dut.added, dut.zero) }
- )
- }
-
- "Test" should "pass if selecting ops" in {
- execute(
- () => new SelectTester(Seq(0, 1, 2)),
- { dut: SelectTester => Select.ops(dut).collect { case ("tail", d) => d } },
- { dut: SelectTester => Seq(dut.added, dut.zero) }
- )
- }
-
- "Test" should "pass if selecting correct stops" in {
- execute(
- () => new SelectTester(Seq(0, 1, 2)),
- { dut: SelectTester => Seq(Select.stops(dut).last) },
- { dut: SelectTester =>
- Seq(
- Select.Stop(
- Seq(
- When(Select.ops("eq")(dut)(1).asInstanceOf[Bool]),
- When(dut.overflow)
- ),
- 0,
- dut.clock
- )
- )
- }
- )
- }
-
- "Blackboxes" should "be supported in Select.instances" in {
- class BB extends ExtModule {}
- class Top extends RawModule {
- val bb = Module(new BB)
- }
- val top = ChiselGeneratorAnnotation(() => {
- new Top()
- }).elaborate(1).asInstanceOf[DesignAnnotation[Top]].design
- val bbs = Select.collectDeep(top) { case b: BB => b }
- assert(bbs.size == 1)
- }
-
- "CloneModuleAsRecord" should "NOT show up in Select aspects" in {
- import chisel3.experimental.CloneModuleAsRecord
- class Child extends RawModule {
- val in = IO(Input(UInt(8.W)))
- val out = IO(Output(UInt(8.W)))
- out := in
- }
- class Top extends Module {
- val in = IO(Input(UInt(8.W)))
- val out = IO(Output(UInt(8.W)))
- val inst0 = Module(new Child)
- val inst1 = CloneModuleAsRecord(inst0)
- inst0.in := in
- inst1("in") := inst0.out
- out := inst1("out")
- }
- val top = ChiselGeneratorAnnotation(() => {
- new Top()
- }).elaborate.collectFirst { case DesignAnnotation(design: Top) => design }.get
- Select.collectDeep(top) { case x => x } should equal(Seq(top, top.inst0))
- Select.getDeep(top)(x => Seq(x)) should equal(Seq(top, top.inst0))
- Select.instances(top) should equal(Seq(top.inst0))
- }
-
- "Using Definition/Instance with Injecting Aspects" should "throw an error" in {
- import chisel3.experimental.CloneModuleAsRecord
- import chisel3.experimental.hierarchy._
- @instantiable
- class Child extends RawModule {
- @public val in = IO(Input(UInt(8.W)))
- @public val out = IO(Output(UInt(8.W)))
- out := in
- }
- class Top extends Module {
- val in = IO(Input(UInt(8.W)))
- val out = IO(Output(UInt(8.W)))
- val definition = Definition(new Child)
- val inst0 = Instance(definition)
- val inst1 = Instance(definition)
- inst0.in := in
- inst1.in := inst0.out
- out := inst1.out
- }
- val top = ChiselGeneratorAnnotation(() => {
- new Top()
- }).elaborate.collectFirst { case DesignAnnotation(design: Top) => design }.get
- intercept[Exception] { Select.collectDeep(top) { case x => x } }
- intercept[Exception] { Select.getDeep(top)(x => Seq(x)) }
- intercept[Exception] { Select.instances(top) }
- }
-
-}
diff --git a/src/test/scala/chiselTests/experimental/DataMirrorSpec.scala b/src/test/scala/chiselTests/experimental/DataMirrorSpec.scala
deleted file mode 100644
index 09fdf3c4..00000000
--- a/src/test/scala/chiselTests/experimental/DataMirrorSpec.scala
+++ /dev/null
@@ -1,91 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.experimental
-
-import chisel3._
-import chisel3.util.Valid
-import chisel3.stage.ChiselStage
-import chisel3.experimental.DataMirror
-import chiselTests.ChiselFlatSpec
-
-object DataMirrorSpec {
- import org.scalatest.matchers.should.Matchers._
- class GrandChild(parent: RawModule) extends Module {
- DataMirror.getParent(this) should be(Some(parent))
- }
- class Child(parent: RawModule) extends Module {
- val inst = Module(new GrandChild(this))
- DataMirror.getParent(inst) should be(Some(this))
- DataMirror.getParent(this) should be(Some(parent))
- }
- class Parent extends Module {
- val inst = Module(new Child(this))
- DataMirror.getParent(inst) should be(Some(this))
- DataMirror.getParent(this) should be(None)
- }
-}
-
-class DataMirrorSpec extends ChiselFlatSpec {
- import DataMirrorSpec._
-
- behavior.of("DataMirror")
-
- def assertBinding(x: Data, io: Boolean, wire: Boolean, reg: Boolean) = {
- DataMirror.isIO(x) should be(io)
- DataMirror.isWire(x) should be(wire)
- DataMirror.isReg(x) should be(reg)
- }
-
- def assertIO(x: Data) = assertBinding(x, true, false, false)
-
- def assertWire(x: Data) = assertBinding(x, false, true, false)
-
- def assertReg(x: Data) = assertBinding(x, false, false, true)
-
- def assertNone(x: Data) = assertBinding(x, false, false, false)
-
- it should "validate bindings" in {
- class MyModule extends Module {
- val typ = UInt(4.W)
- val vectyp = Vec(8, UInt(4.W))
- val io = IO(new Bundle {
- val in = Input(UInt(4.W))
- val vec = Input(vectyp)
- val out = Output(UInt(4.W))
- })
- val vec = Wire(vectyp)
- val regvec = Reg(vectyp)
- val wire = Wire(UInt(4.W))
- val reg = RegNext(wire)
-
- assertIO(io)
- assertIO(io.in)
- assertIO(io.out)
- assertIO(io.vec(1))
- assertIO(io.vec)
- assertWire(vec)
- assertWire(vec(0))
- assertWire(wire)
- assertReg(reg)
- assertReg(regvec)
- assertReg(regvec(2))
- assertNone(typ)
- assertNone(vectyp)
- }
- ChiselStage.elaborate(new MyModule)
- }
-
- it should "support getParent for normal modules" in {
- ChiselStage.elaborate(new Parent)
- }
-
- it should "support getParent for normal modules even when used in a D/I context" in {
- import chisel3.experimental.hierarchy._
- class Top extends Module {
- val defn = Definition(new Parent)
- val inst = Instance(defn)
- DataMirror.getParent(this) should be(None)
- }
- ChiselStage.elaborate(new Top)
- }
-}
diff --git a/src/test/scala/chiselTests/experimental/DataView.scala b/src/test/scala/chiselTests/experimental/DataView.scala
deleted file mode 100644
index cefc893c..00000000
--- a/src/test/scala/chiselTests/experimental/DataView.scala
+++ /dev/null
@@ -1,557 +0,0 @@
-// See LICENSE for license details.
-
-package chiselTests.experimental
-
-import chiselTests.ChiselFlatSpec
-import chisel3._
-import chisel3.experimental.dataview._
-import chisel3.experimental.conversions._
-import chisel3.experimental.DataMirror.internal.chiselTypeClone
-import chisel3.experimental.{Analog, HWTuple2}
-import chisel3.stage.ChiselStage
-import chisel3.util.{Decoupled, DecoupledIO}
-
-object SimpleBundleDataView {
- class BundleA(val w: Int) extends Bundle {
- val foo = UInt(w.W)
- }
- class BundleB(val w: Int) extends Bundle {
- val bar = UInt(w.W)
- }
- implicit val v1 = DataView[BundleA, BundleB](a => new BundleB(a.w), _.foo -> _.bar)
- implicit val v2 = v1.invert(b => new BundleA(b.w))
-}
-
-object VecBundleDataView {
- class MyBundle extends Bundle {
- val foo = UInt(8.W)
- val bar = UInt(8.W)
- }
- implicit val v1: DataView[MyBundle, Vec[UInt]] = DataView(_ => Vec(2, UInt(8.W)), _.foo -> _(1), _.bar -> _(0))
- implicit val v2 = v1.invert(_ => new MyBundle)
-}
-
-object FlatDecoupledDataView {
- class FizzBuzz extends Bundle {
- val fizz = UInt(8.W)
- val buzz = UInt(8.W)
- }
- class FlatDecoupled extends Bundle {
- val valid = Output(Bool())
- val ready = Input(Bool())
- val fizz = Output(UInt(8.W))
- val buzz = Output(UInt(8.W))
- }
- implicit val view = DataView[FlatDecoupled, DecoupledIO[FizzBuzz]](
- _ => Decoupled(new FizzBuzz),
- _.valid -> _.valid,
- _.ready -> _.ready,
- _.fizz -> _.bits.fizz,
- _.buzz -> _.bits.buzz
- )
- implicit val view2 = view.invert(_ => new FlatDecoupled)
-}
-
-class DataViewSpec extends ChiselFlatSpec {
-
- behavior.of("DataView")
-
- it should "support simple Bundle viewing" in {
- import SimpleBundleDataView._
- class MyModule extends Module {
- val in = IO(Input(new BundleA(8)))
- val out = IO(Output(new BundleB(8)))
- out := in.viewAs[BundleB]
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- chirrtl should include("out.bar <= in.foo")
- }
-
- it should "be a bidirectional mapping" in {
- import SimpleBundleDataView._
- class MyModule extends Module {
- val in = IO(Input(new BundleA(8)))
- val out = IO(Output(new BundleB(8)))
- out.viewAs[BundleA] := in
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- chirrtl should include("out.bar <= in.foo")
- }
-
- it should "handle viewing UInts as UInts" in {
- class MyModule extends Module {
- val in = IO(Input(UInt(8.W)))
- val foo = IO(Output(UInt(8.W)))
- val bar = IO(Output(UInt(8.W)))
- foo := in.viewAs[UInt]
- bar.viewAs[UInt] := in
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- chirrtl should include("foo <= in")
- chirrtl should include("bar <= in")
- }
-
- it should "handle viewing Analogs as Analogs" in {
- class MyModule extends Module {
- val foo = IO(Analog(8.W))
- val bar = IO(Analog(8.W))
- foo <> bar.viewAs[Analog]
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- chirrtl should include("attach (foo, bar)")
- }
-
- it should "handle viewing Bundles as their same concrete type" in {
- class MyBundle extends Bundle {
- val foo = UInt(8.W)
- }
- class MyModule extends Module {
- val in = IO(Input(new MyBundle))
- val fizz = IO(Output(new MyBundle))
- val buzz = IO(Output(new MyBundle))
- fizz := in.viewAs[MyBundle]
- buzz.viewAs[MyBundle] := in
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- chirrtl should include("fizz <= in")
- chirrtl should include("buzz <= in")
- }
-
- it should "handle viewing Vecs as their same concrete type" in {
- class MyModule extends Module {
- val in = IO(Input(Vec(1, UInt(8.W))))
- val fizz = IO(Output(Vec(1, UInt(8.W))))
- val buzz = IO(Output(Vec(1, UInt(8.W))))
- fizz := in.viewAs[Vec[UInt]]
- buzz.viewAs[Vec[UInt]] := in
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- chirrtl should include("fizz <= in")
- chirrtl should include("buzz <= in")
- }
-
- it should "handle viewing Vecs as Bundles and vice versa" in {
- import VecBundleDataView._
- class MyModule extends Module {
- val in = IO(Input(new MyBundle))
- val out = IO(Output(Vec(2, UInt(8.W))))
- val out2 = IO(Output(Vec(2, UInt(8.W))))
- out := in.viewAs[Vec[UInt]]
- out2.viewAs[MyBundle] := in
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- chirrtl should include("out[0] <= in.bar")
- chirrtl should include("out[1] <= in.foo")
- chirrtl should include("out2[0] <= in.bar")
- chirrtl should include("out2[1] <= in.foo")
- }
-
- it should "work with bidirectional connections for nested types" in {
- import FlatDecoupledDataView._
- class MyModule extends Module {
- val enq = IO(Flipped(Decoupled(new FizzBuzz)))
- val deq = IO(new FlatDecoupled)
- val deq2 = IO(new FlatDecoupled)
- deq <> enq.viewAs[FlatDecoupled]
- deq2.viewAs[DecoupledIO[FizzBuzz]] <> enq
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- chirrtl should include("deq.valid <= enq.valid")
- chirrtl should include("enq.ready <= deq.ready")
- chirrtl should include("deq.fizz <= enq.bits.fizz")
- chirrtl should include("deq.buzz <= enq.bits.buzz")
- chirrtl should include("deq2.valid <= enq.valid")
- chirrtl should include("enq.ready <= deq2.ready")
- chirrtl should include("deq2.fizz <= enq.bits.fizz")
- chirrtl should include("deq2.buzz <= enq.bits.buzz")
- }
-
- it should "support viewing a Bundle as a Parent Bundle type" in {
- class Foo extends Bundle {
- val foo = UInt(8.W)
- }
- class Bar extends Foo {
- val bar = UInt(8.W)
- }
- class MyModule extends Module {
- val fooIn = IO(Input(new Foo))
- val barOut = IO(Output(new Bar))
- barOut.viewAsSupertype(new Foo) := fooIn
-
- val barIn = IO(Input(new Bar))
- val fooOut = IO(Output(new Foo))
- fooOut := barIn.viewAsSupertype(new Foo)
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- chirrtl should include("barOut.foo <= fooIn.foo")
- chirrtl should include("fooOut.foo <= barIn.foo")
- }
-
- it should "be easy to make a PartialDataView viewing a Bundle as a Parent Bundle type" in {
- class Foo(x: Int) extends Bundle {
- val foo = UInt(x.W)
- }
- class Bar(val x: Int) extends Foo(x) {
- val bar = UInt(x.W)
- }
- implicit val view = PartialDataView.supertype[Bar, Foo](b => new Foo(b.x))
- class MyModule extends Module {
- val fooIn = IO(Input(new Foo(8)))
- val barOut = IO(Output(new Bar(8)))
- barOut.viewAs[Foo] := fooIn
-
- val barIn = IO(Input(new Bar(8)))
- val fooOut = IO(Output(new Foo(8)))
- fooOut := barIn.viewAs[Foo]
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- chirrtl should include("barOut.foo <= fooIn.foo")
- chirrtl should include("fooOut.foo <= barIn.foo")
- }
-
- it should "error if viewing a parent Bundle as a child Bundle type" in {
- assertTypeError("""
- class Foo extends Bundle {
- val foo = UInt(8.W)
- }
- class Bar extends Foo {
- val bar = UInt(8.W)
- }
- class MyModule extends Module {
- val barIn = IO(Input(new Bar))
- val fooOut = IO(Output(new Foo))
- fooOut.viewAs(new Bar) := barIn
- }
- """)
- }
-
- it should "work in UInt operations" in {
- class MyBundle extends Bundle {
- val value = UInt(8.W)
- }
- class MyModule extends Module {
- val a = IO(Input(UInt(8.W)))
- val b = IO(Input(new MyBundle))
- val cond = IO(Input(Bool()))
- val and, mux, bitsCat = IO(Output(UInt(8.W)))
- // Chisel unconditionally emits a node, so name it at least
- val x = a.viewAs[UInt] & b.viewAs[MyBundle].value
- and.viewAs[UInt] := x
-
- val y = Mux(cond.viewAs[Bool], a.viewAs[UInt], b.value.viewAs[UInt])
- mux.viewAs[UInt] := y
-
- // TODO should we have a macro so that we don't need .apply?
- val aBits = a.viewAs[UInt].apply(3, 0)
- val bBits = b.viewAs[MyBundle].value(3, 0)
- val abCat = aBits.viewAs[UInt] ## bBits.viewAs[UInt]
- bitsCat := abCat
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- val expected = List(
- "node x = and(a, b.value)",
- "and <= x",
- "node y = mux(cond, a, b.value)",
- "mux <= y",
- "node aBits = bits(a, 3, 0)",
- "node bBits = bits(b.value, 3, 0)",
- "node abCat = cat(aBits, bBits)",
- "bitsCat <= abCat"
- )
- for (line <- expected) {
- chirrtl should include(line)
- }
- }
-
- it should "support .asUInt of Views" in {
- import VecBundleDataView._
- class MyModule extends Module {
- val barIn = IO(Input(new MyBundle))
- val fooOut = IO(Output(UInt()))
- val cat = barIn.viewAs[Vec[UInt]].asUInt
- fooOut := cat
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- chirrtl should include("node cat = cat(barIn.foo, barIn.bar)")
- chirrtl should include("fooOut <= cat")
- }
-
- it should "be composable" in {
- // Given DataView[A, B] and DataView[B, C], derive DataView[A, C]
- class Foo(val foo: UInt) extends Bundle
- class Bar(val bar: UInt) extends Bundle
- class Fizz(val fizz: UInt) extends Bundle
-
- implicit val foo2bar = DataView[Foo, Bar](f => new Bar(chiselTypeClone(f.foo)), _.foo -> _.bar)
- implicit val bar2fizz = DataView[Bar, Fizz](b => new Fizz(chiselTypeClone(b.bar)), _.bar -> _.fizz)
-
- implicit val foo2fizz: DataView[Foo, Fizz] = foo2bar.andThen(bar2fizz)
-
- class MyModule extends Module {
- val a, b = IO(Input(new Foo(UInt(8.W))))
- val y, z = IO(Output(new Fizz(UInt(8.W))))
- y := a.viewAs[Fizz]
- z := b.viewAs[Bar].viewAs[Fizz]
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- chirrtl should include("y.fizz <= a.foo")
- chirrtl should include("z.fizz <= b.foo")
- }
-
- it should "enable using Seq like Data" in {
- class MyModule extends Module {
- val a, b, c, d = IO(Input(UInt(8.W)))
- val sel = IO(Input(Bool()))
- val y, z = IO(Output(UInt(8.W)))
- // Unclear why the implicit conversion does not work in this case for Seq
- // That being said, it's easy enough to cast via `.viewAs` with or without
- Seq(y, z) := Mux(sel, Seq(a, b).viewAs, Seq(c, d).viewAs[Vec[UInt]])
- }
- // Verilog instead of CHIRRTL because the optimizations make it much prettier
- val verilog = ChiselStage.emitVerilog(new MyModule)
- verilog should include("assign y = sel ? a : c;")
- verilog should include("assign z = sel ? b : d;")
- }
-
- // This example should be turned into a built-in feature
- it should "enable viewing Seqs as Vecs" in {
-
- class MyModule extends Module {
- val a, b, c = IO(Input(UInt(8.W)))
- val x, y, z = IO(Output(UInt(8.W)))
- Seq(x, y, z) := VecInit(a, b, c)
- }
- // Verilog instead of CHIRRTL because the optimizations make it much prettier
- val verilog = ChiselStage.emitVerilog(new MyModule)
- verilog should include("assign x = a;")
- verilog should include("assign y = b;")
- verilog should include("assign z = c;")
- }
-
- it should "support recursive composition of views" in {
- class MyModule extends Module {
- val a, b, c, d = IO(Input(UInt(8.W)))
- val w, x, y, z = IO(Output(UInt(8.W)))
-
- // A little annoying that we need the type annotation on VecInit to get the implicit conversion to work
- // Note that one can just use the Seq on the RHS so there is an alternative (may lack discoverability)
- // We could also overload `VecInit` instead of relying on the implicit conversion
- Seq((w, x), (y, z)) := VecInit[HWTuple2[UInt, UInt]]((a, b), (c, d))
- }
- val verilog = ChiselStage.emitVerilog(new MyModule)
- verilog should include("assign w = a;")
- verilog should include("assign x = b;")
- verilog should include("assign y = c;")
- verilog should include("assign z = d;")
- }
-
- it should "support dynamic indexing for Vec identity views" in {
- class MyModule extends Module {
- val dataIn = IO(Input(UInt(8.W)))
- val addr = IO(Input(UInt(2.W)))
- val dataOut = IO(Output(UInt(8.W)))
-
- val vec = RegInit(0.U.asTypeOf(Vec(4, UInt(8.W))))
- val view = vec.viewAs[Vec[UInt]]
- // Dynamic indexing is more of a "generator" in Chisel3 than an individual node
- // This style is not recommended, this is just testing the behavior
- val selected = view(addr)
- selected := dataIn
- dataOut := selected
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- chirrtl should include("vec[addr] <= dataIn")
- chirrtl should include("dataOut <= vec[addr]")
- }
-
- it should "support dynamic indexing for Vecs that correspond 1:1 in a view" in {
- class MyBundle extends Bundle {
- val foo = Vec(4, UInt(8.W))
- val bar = UInt(2.W)
- }
- implicit val myView = DataView[(Vec[UInt], UInt), MyBundle](
- _ => new MyBundle,
- _._1 -> _.foo,
- _._2 -> _.bar
- )
- class MyModule extends Module {
- val dataIn = IO(Input(UInt(8.W)))
- val addr = IO(Input(UInt(2.W)))
- val dataOut = IO(Output(UInt(8.W)))
-
- val vec = RegInit(0.U.asTypeOf(Vec(4, UInt(8.W))))
- val addrReg = Reg(UInt(2.W))
- val view = (vec, addrReg).viewAs[MyBundle]
- // Dynamic indexing is more of a "generator" in Chisel3 than an individual node
- // This style is not recommended, this is just testing the behavior
- val selected = view.foo(view.bar)
- view.bar := addr
- selected := dataIn
- dataOut := selected
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- chirrtl should include("vec[addrReg] <= dataIn")
- chirrtl should include("dataOut <= vec[addrReg]")
- }
-
- it should "error if you try to dynamically index a Vec view that does not correspond to a Vec target" in {
- class MyModule extends Module {
- val inA, inB = IO(Input(UInt(8.W)))
- val outA, outB = IO(Output(UInt(8.W)))
- val idx = IO(Input(UInt(1.W)))
-
- val a, b, c, d = RegInit(0.U)
-
- // Dynamic indexing is more of a "generator" in Chisel3 than an individual node
- // This style is not recommended, this is just testing the behavior
- val selected = Seq((a, b), (c, d)).apply(idx)
- selected := (inA, inB)
- (outA, outB) := selected
- }
- (the[InvalidViewException] thrownBy {
- ChiselStage.emitChirrtl(new MyModule)
- }).getMessage should include("Dynamic indexing of Views is not yet supported")
- }
-
- it should "error if the mapping is non-total in the view" in {
- class MyBundle(val foo: UInt, val bar: UInt) extends Bundle
- implicit val dv = DataView[UInt, MyBundle](_ => new MyBundle(UInt(), UInt()), _ -> _.bar)
- class MyModule extends Module {
- val tpe = new MyBundle(UInt(8.W), UInt(8.W))
- val in = IO(Input(UInt(8.W)))
- val out = IO(Output(tpe))
- out := in.viewAs[MyBundle]
- }
- val err = the[InvalidViewException] thrownBy (ChiselStage.emitVerilog(new MyModule))
- err.toString should include("View field '_.foo' is missing")
- }
-
- it should "error if the mapping is non-total in the target" in {
- implicit val dv = DataView[(UInt, UInt), UInt](_ => UInt(), _._1 -> _)
- class MyModule extends Module {
- val a, b = IO(Input(UInt(8.W)))
- val out = IO(Output(UInt(8.W)))
- out := (a, b).viewAs[UInt]
- }
- val err = the[InvalidViewException] thrownBy (ChiselStage.emitVerilog(new MyModule))
- err.toString should include("Target field '_._2' is missing")
- }
-
- it should "error if the mapping contains Data that are not part of the Target" in {
- class BundleA extends Bundle {
- val foo = UInt(8.W)
- }
- class BundleB extends Bundle {
- val fizz = UInt(8.W)
- val buzz = UInt(8.W)
- }
- implicit val dv = DataView[BundleA, BundleB](_ => new BundleB, _.foo -> _.fizz, (_, b) => (3.U, b.buzz))
- class MyModule extends Module {
- val in = IO(Input(new BundleA))
- val out = IO(Output(new BundleB))
- out := in.viewAs[BundleB]
- }
- val err = the[InvalidViewException] thrownBy (ChiselStage.emitVerilog(new MyModule))
- err.toString should include("View mapping must only contain Elements within the Target")
- }
-
- it should "error if the mapping contains Data that are not part of the View" in {
- class BundleA extends Bundle {
- val foo = UInt(8.W)
- }
- class BundleB extends Bundle {
- val fizz = UInt(8.W)
- val buzz = UInt(8.W)
- }
- implicit val dv = DataView[BundleA, BundleB](_ => new BundleB, _.foo -> _.fizz, (_, b) => (3.U, b.buzz))
- implicit val dv2 = dv.invert(_ => new BundleA)
- class MyModule extends Module {
- val in = IO(Input(new BundleA))
- val out = IO(Output(new BundleB))
- out.viewAs[BundleA] := in
- }
- val err = the[InvalidViewException] thrownBy (ChiselStage.emitVerilog(new MyModule))
- err.toString should include("View mapping must only contain Elements within the View")
- }
-
- it should "error if a view has a width that does not match the target" in {
- class BundleA extends Bundle {
- val foo = UInt(8.W)
- }
- class BundleB extends Bundle {
- val bar = UInt(4.W)
- }
- implicit val dv = DataView[BundleA, BundleB](_ => new BundleB, _.foo -> _.bar)
- class MyModule extends Module {
- val in = IO(Input(new BundleA))
- val out = IO(Output(new BundleB))
- out := in.viewAs[BundleB]
- }
- val err = the[InvalidViewException] thrownBy ChiselStage.emitChirrtl(new MyModule)
- val expected = """View field _\.bar UInt<4> has width <4> that is incompatible with target value .+'s width <8>""".r
- (err.getMessage should fullyMatch).regex(expected)
- }
-
- it should "error if a view has a known width when the target width is unknown" in {
- class BundleA extends Bundle {
- val foo = UInt()
- }
- class BundleB extends Bundle {
- val bar = UInt(4.W)
- }
- implicit val dv = DataView[BundleA, BundleB](_ => new BundleB, _.foo -> _.bar)
- class MyModule extends Module {
- val in = IO(Input(new BundleA))
- val out = IO(Output(new BundleB))
- out := in.viewAs[BundleB]
- }
- val err = the[InvalidViewException] thrownBy ChiselStage.emitChirrtl(new MyModule)
- val expected =
- """View field _\.bar UInt<4> has width <4> that is incompatible with target value .+'s width <unknown>""".r
- (err.getMessage should fullyMatch).regex(expected)
- }
-
- it should "support invalidation" in {
- class MyModule extends Module {
- val a, b, c, d, e, f = IO(Output(UInt(8.W)))
- val foo = (a, b).viewAs
- val bar = (c, d).viewAs
- val fizz = (e, f).viewAs
- foo := DontCare
- bar <> DontCare
- fizz._1 := DontCare
- fizz._2 <> DontCare
- }
-
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- val expected = ('a' to 'f').map(c => s"$c is invalid")
- for (line <- expected) {
- chirrtl should include(line)
- }
- }
-
- behavior.of("PartialDataView")
-
- it should "still error if the mapping is non-total in the view" in {
- class MyBundle(val foo: UInt, val bar: UInt) extends Bundle
- implicit val dv = PartialDataView[UInt, MyBundle](_ => new MyBundle(UInt(), UInt()), _ -> _.bar)
- class MyModule extends Module {
- val in = IO(Input(UInt(8.W)))
- val out = IO(Output(new MyBundle(UInt(8.W), UInt(8.W))))
- out := in.viewAs[MyBundle]
- }
- val err = the[InvalidViewException] thrownBy (ChiselStage.emitVerilog(new MyModule))
- err.toString should include("View field '_.foo' is missing")
- }
-
- it should "NOT error if the mapping is non-total in the target" in {
- implicit val dv = PartialDataView[(UInt, UInt), UInt](_ => UInt(), _._2 -> _)
- class MyModule extends Module {
- val a, b = IO(Input(UInt(8.W)))
- val out = IO(Output(UInt(8.W)))
- out := (a, b).viewAs[UInt]
- }
- val verilog = ChiselStage.emitVerilog(new MyModule)
- verilog should include("assign out = b;")
- }
-}
diff --git a/src/test/scala/chiselTests/experimental/DataViewIntegrationSpec.scala b/src/test/scala/chiselTests/experimental/DataViewIntegrationSpec.scala
deleted file mode 100644
index 4704a942..00000000
--- a/src/test/scala/chiselTests/experimental/DataViewIntegrationSpec.scala
+++ /dev/null
@@ -1,57 +0,0 @@
-// See LICENSE for license details.
-
-package chiselTests.experimental
-
-import chisel3._
-import chisel3.experimental.{BaseModule, ExtModule}
-import chisel3.experimental.dataview._
-import chisel3.util.{log2Ceil, Decoupled, DecoupledIO, Queue, QueueIO}
-import chiselTests.ChiselFlatSpec
-import firrtl.transforms.DontTouchAnnotation
-
-// Let's put it all together!
-object DataViewIntegrationSpec {
-
- class QueueIntf[T <: Data](gen: T, entries: Int) extends Bundle {
- val ports = new QueueIO(gen, entries)
- // Let's grab a reference to something internal too
- // Output because can't have directioned and undirectioned stuff
- val enq_ptr = Output(UInt(log2Ceil(entries).W))
- }
-
- // It's not clear if a view of a Module ever _can_ be total since internal nodes are part of the Module
- implicit def queueView[T <: Data] = PartialDataView[Queue[T], QueueIntf[T]](
- q => new QueueIntf(q.gen, q.entries),
- _.io -> _.ports,
- // Some token internal signal
- _.enq_ptr.value -> _.enq_ptr
- )
-
- object MyQueue {
- def apply[T <: Data](enq: DecoupledIO[T], n: Int): QueueIntf[T] = {
- val queue = Module(new Queue[T](enq.bits.cloneType, n))
- val view = queue.viewAs[QueueIntf[T]]
- view.ports.enq <> enq
- view
- }
- }
-
- class MyModule extends Module {
- val enq = IO(Flipped(Decoupled(UInt(8.W))))
- val deq = IO(Decoupled(UInt(8.W)))
-
- val queue = MyQueue(enq, 4)
- deq <> queue.ports.deq
- dontTouch(queue.enq_ptr)
- }
-}
-
-class DataViewIntegrationSpec extends ChiselFlatSpec {
- import DataViewIntegrationSpec.MyModule
-
- "Users" should "be able to view and annotate Modules" in {
- val (_, annos) = getFirrtlAndAnnos(new MyModule)
- val ts = annos.collect { case DontTouchAnnotation(t) => t.serialize }
- ts should equal(Seq("~MyModule|Queue>enq_ptr_value"))
- }
-}
diff --git a/src/test/scala/chiselTests/experimental/DataViewTargetSpec.scala b/src/test/scala/chiselTests/experimental/DataViewTargetSpec.scala
deleted file mode 100644
index ddeeab6e..00000000
--- a/src/test/scala/chiselTests/experimental/DataViewTargetSpec.scala
+++ /dev/null
@@ -1,176 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.experimental
-
-import chisel3._
-import chisel3.experimental.dataview._
-import chisel3.experimental.conversions._
-import chisel3.experimental.{annotate, ChiselAnnotation}
-import chiselTests.ChiselFlatSpec
-
-object DataViewTargetSpec {
- import firrtl.annotations._
- private case class DummyAnno(target: ReferenceTarget, id: Int) extends SingleTargetAnnotation[ReferenceTarget] {
- override def duplicate(n: ReferenceTarget) = this.copy(target = n)
- }
- private def mark(d: Data, id: Int) = annotate(new ChiselAnnotation {
- override def toFirrtl: Annotation = DummyAnno(d.toTarget, id)
- })
- private def markAbs(d: Data, id: Int) = annotate(new ChiselAnnotation {
- override def toFirrtl: Annotation = DummyAnno(d.toAbsoluteTarget, id)
- })
-}
-
-class DataViewTargetSpec extends ChiselFlatSpec {
- import DataViewTargetSpec._
- private val checks: Seq[Data => String] = Seq(
- _.toTarget.toString,
- _.toAbsoluteTarget.toString,
- _.instanceName,
- _.pathName,
- _.parentPathName,
- _.parentModName
- )
-
- // Check helpers
- private def checkAll(impl: Data, refs: String*): Unit = {
- refs.size should be(checks.size)
- for ((check, value) <- checks.zip(refs)) {
- check(impl) should be(value)
- }
- }
- private def checkSameAs(impl: Data, refs: Data*): Unit =
- for (ref <- refs) {
- checkAll(impl, checks.map(_(ref)): _*)
- }
-
- behavior.of("DataView Naming")
-
- it should "support views of Elements" in {
- class MyChild extends Module {
- val out = IO(Output(UInt(8.W)))
- val insideView = out.viewAs[UInt]
- out := 0.U
- }
- class MyParent extends Module {
- val out = IO(Output(UInt(8.W)))
- val inst = Module(new MyChild)
- out := inst.out
- }
- val m = elaborateAndGetModule(new MyParent)
- val outsideView = m.inst.out.viewAs[UInt]
- checkSameAs(m.inst.out, m.inst.insideView, outsideView)
- }
-
- it should "support 1:1 mappings of Aggregates and their children" in {
- class MyBundle extends Bundle {
- val foo = UInt(8.W)
- val bars = Vec(2, UInt(8.W))
- }
- implicit val dv =
- DataView[MyBundle, Vec[UInt]](_ => Vec(3, UInt(8.W)), _.foo -> _(0), _.bars(0) -> _(1), _.bars(1) -> _(2))
- class MyChild extends Module {
- val out = IO(Output(new MyBundle))
- val outView = out.viewAs[Vec[UInt]] // Note different type
- val outFooView = out.foo.viewAs[UInt]
- val outBarsView = out.bars.viewAs[Vec[UInt]]
- val outBars0View = out.bars(0).viewAs[UInt]
- out := 0.U.asTypeOf(new MyBundle)
- }
- class MyParent extends Module {
- val out = IO(Output(new MyBundle))
- val inst = Module(new MyChild)
- out := inst.out
- }
- val m = elaborateAndGetModule(new MyParent)
- val outView = m.inst.out.viewAs[Vec[UInt]] // Note different type
- val outFooView = m.inst.out.foo.viewAs[UInt]
- val outBarsView = m.inst.out.bars.viewAs[Vec[UInt]]
- val outBars0View = m.inst.out.bars(0).viewAs[UInt]
-
- checkSameAs(m.inst.out, m.inst.outView, outView)
- checkSameAs(m.inst.out.foo, m.inst.outFooView, m.inst.outView(0), outFooView, outView(0))
- checkSameAs(m.inst.out.bars, m.inst.outBarsView, outBarsView)
- checkSameAs(
- m.inst.out.bars(0),
- m.inst.outBars0View,
- outBars0View,
- m.inst.outView(1),
- outView(1),
- m.inst.outBarsView(0),
- outBarsView(0)
- )
- }
-
- // Ideally this would work 1:1 but that requires changing the binding
- it should "support annotation renaming of Aggregate children of Aggregate views" in {
- class MyBundle extends Bundle {
- val foo = Vec(2, UInt(8.W))
- }
- class MyChild extends Module {
- val out = IO(Output(new MyBundle))
- val outView = out.viewAs[MyBundle]
- mark(out.foo, 0)
- mark(outView.foo, 1)
- markAbs(out.foo, 2)
- markAbs(outView, 3)
- out := 0.U.asTypeOf(new MyBundle)
- }
- class MyParent extends Module {
- val out = IO(Output(new MyBundle))
- val inst = Module(new MyChild)
- out := inst.out
- }
- val (_, annos) = getFirrtlAndAnnos(new MyParent)
- val pairs = annos.collect { case DummyAnno(t, idx) => (idx, t.toString) }.sortBy(_._1)
- val expected = Seq(
- 0 -> "~MyParent|MyChild>out.foo",
- 1 -> "~MyParent|MyChild>out.foo",
- 2 -> "~MyParent|MyParent/inst:MyChild>out.foo",
- 3 -> "~MyParent|MyParent/inst:MyChild>out"
- )
- pairs should equal(expected)
- }
-
- it should "support annotating views that cannot be mapped to a single ReferenceTarget" in {
- class MyBundle extends Bundle {
- val a, b = Input(UInt(8.W))
- val c, d = Output(UInt(8.W))
- }
- // Note that each use of a Tuple as Data causes an implicit conversion creating a View
- class MyChild extends Module {
- val io = IO(new MyBundle)
- (io.c, io.d) := (io.a, io.b)
- // The type annotations create the views via the implicit conversion
- val view1: Data = (io.a, io.b)
- val view2: Data = (io.c, io.d)
- mark(view1, 0)
- mark(view2, 1)
- markAbs(view1, 2)
- markAbs(view2, 3)
- mark((io.b, io.d), 4) // Mix it up for fun
- }
- class MyParent extends Module {
- val io = IO(new MyBundle)
- val inst = Module(new MyChild)
- io <> inst.io
- }
- val (_, annos) = getFirrtlAndAnnos(new MyParent)
- val pairs = annos.collect { case DummyAnno(t, idx) => (idx, t.toString) }.sorted
- val expected = Seq(
- 0 -> "~MyParent|MyChild>io.a",
- 0 -> "~MyParent|MyChild>io.b",
- 1 -> "~MyParent|MyChild>io.c",
- 1 -> "~MyParent|MyChild>io.d",
- 2 -> "~MyParent|MyParent/inst:MyChild>io.a",
- 2 -> "~MyParent|MyParent/inst:MyChild>io.b",
- 3 -> "~MyParent|MyParent/inst:MyChild>io.c",
- 3 -> "~MyParent|MyParent/inst:MyChild>io.d",
- 4 -> "~MyParent|MyChild>io.b",
- 4 -> "~MyParent|MyChild>io.d"
- )
- pairs should equal(expected)
- }
-
- // TODO check these properties when using @instance API (especially preservation of totality)
-}
diff --git a/src/test/scala/chiselTests/experimental/FlatIOSpec.scala b/src/test/scala/chiselTests/experimental/FlatIOSpec.scala
deleted file mode 100644
index fb3f64c7..00000000
--- a/src/test/scala/chiselTests/experimental/FlatIOSpec.scala
+++ /dev/null
@@ -1,68 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.experimental
-
-import chisel3._
-import chisel3.util.Valid
-import chisel3.stage.ChiselStage.emitChirrtl
-import chisel3.experimental.{Analog, FlatIO}
-import chiselTests.ChiselFlatSpec
-
-class FlatIOSpec extends ChiselFlatSpec {
- behavior.of("FlatIO")
-
- it should "create ports without a prefix" in {
- class MyModule extends RawModule {
- val io = FlatIO(new Bundle {
- val in = Input(UInt(8.W))
- val out = Output(UInt(8.W))
- })
- io.out := io.in
- }
- val chirrtl = emitChirrtl(new MyModule)
- chirrtl should include("input in : UInt<8>")
- chirrtl should include("output out : UInt<8>")
- chirrtl should include("out <= in")
- }
-
- it should "support bulk connections between FlatIOs and regular IOs" in {
- class MyModule extends RawModule {
- val in = FlatIO(Input(Valid(UInt(8.W))))
- val out = IO(Output(Valid(UInt(8.W))))
- out := in
- }
- val chirrtl = emitChirrtl(new MyModule)
- chirrtl should include("out.bits <= bits")
- chirrtl should include("out.valid <= valid")
- }
-
- it should "dynamically indexing Vecs inside of FlatIOs" in {
- class MyModule extends RawModule {
- val io = FlatIO(new Bundle {
- val addr = Input(UInt(2.W))
- val in = Input(Vec(4, UInt(8.W)))
- val out = Output(Vec(4, UInt(8.W)))
- })
- io.out(io.addr) := io.in(io.addr)
- }
- val chirrtl = emitChirrtl(new MyModule)
- chirrtl should include("out[addr] <= in[addr]")
- }
-
- it should "support Analog members" in {
- class MyBundle extends Bundle {
- val foo = Output(UInt(8.W))
- val bar = Analog(8.W)
- }
- class MyModule extends RawModule {
- val io = FlatIO(new Bundle {
- val in = Flipped(new MyBundle)
- val out = new MyBundle
- })
- io.out <> io.in
- }
- val chirrtl = emitChirrtl(new MyModule)
- chirrtl should include("out.foo <= in.foo")
- chirrtl should include("attach (out.bar, in.bar)")
- }
-}
diff --git a/src/test/scala/chiselTests/experimental/ForceNames.scala b/src/test/scala/chiselTests/experimental/ForceNames.scala
deleted file mode 100644
index 9ba825c4..00000000
--- a/src/test/scala/chiselTests/experimental/ForceNames.scala
+++ /dev/null
@@ -1,128 +0,0 @@
-// See LICENSE for license details.
-
-package chiselTests
-
-import firrtl._
-import chisel3._
-import chisel3.experimental.annotate
-import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage}
-import chisel3.util.experimental.{forceName, ForceNameAnnotation, ForceNamesTransform, InlineInstance}
-import firrtl.annotations.{Annotation, ReferenceTarget}
-import firrtl.options.{Dependency, TargetDirAnnotation}
-import firrtl.stage.RunFirrtlTransformAnnotation
-import logger.{LogLevel, LogLevelAnnotation}
-
-/** Object containing Modules used for testing */
-object ForceNamesHierarchy {
- class WrapperExample extends Module {
- val in = IO(Input(UInt(3.W)))
- val out = IO(Output(UInt(3.W)))
- val inst = Module(new Wrapper)
- inst.in := in
- out := inst.out
- forceName(out, "outt")
- }
- class Wrapper extends Module with InlineInstance {
- val in = IO(Input(UInt(3.W)))
- val out = IO(Output(UInt(3.W)))
- val inst = Module(new MyLeaf)
- forceName(inst, "inst")
- inst.in := in
- out := inst.out
- }
- class MyLeaf extends Module {
- val in = IO(Input(UInt(3.W)))
- val out = IO(Output(UInt(3.W)))
- out := in
- }
- class RenamePortsExample extends Module {
- val in = IO(Input(UInt(3.W)))
- val out = IO(Output(UInt(3.W)))
- val inst = Module(new MyLeaf)
- inst.in := in
- out := inst.out
- forceName(inst.in, "inn")
- }
- class ConflictingName extends Module {
- val in = IO(Input(UInt(3.W)))
- val out = IO(Output(UInt(3.W)))
- out := in
- forceName(out, "in")
- }
- class BundleName extends Module {
- val in = IO(new Bundle {
- val a = Input(UInt(3.W))
- val b = Input(UInt(3.W))
- })
- val out = IO(Output(UInt(3.W)))
- out := in.a + in.b
- }
-}
-
-class ForceNamesSpec extends ChiselFlatSpec with Utils {
-
- def run[T <: RawModule](
- dut: => T,
- testName: String,
- inputAnnos: Seq[Annotation] = Nil,
- info: LogLevel.Value = LogLevel.None
- ): Iterable[String] = {
- def stage = new ChiselStage {
- override val targets = Seq(
- Dependency[chisel3.stage.phases.Elaborate],
- Dependency[chisel3.stage.phases.Convert],
- Dependency[firrtl.stage.phases.Compiler]
- )
- }
-
- val annos = List(
- TargetDirAnnotation("test_run_dir/ForceNames"),
- LogLevelAnnotation(info),
- ChiselGeneratorAnnotation(() => dut)
- ) ++ inputAnnos
-
- val ret = stage.execute(Array(), annos)
- val verilog = ret.collectFirst {
- case e: EmittedVerilogCircuitAnnotation => e.value.value
- }.get
-
- verilog.split("\\\n")
- }
- "Force Names on a wrapping instance" should "work" in {
- val verilog = run(new ForceNamesHierarchy.WrapperExample, "wrapper")
- exactly(1, verilog) should include("MyLeaf inst")
- }
- "Force Names on an instance port" should "work" in {
- val verilog = run(new ForceNamesHierarchy.RenamePortsExample, "instports")
- atLeast(1, verilog) should include("input [2:0] inn")
- }
- "Force Names with a conflicting name" should "error" in {
- intercept[CustomTransformException] {
- run(new ForceNamesHierarchy.ConflictingName, "conflicts")
- }
- }
- "Force Names of an intermediate bundle" should "error" in {
- intercept[CustomTransformException] {
- run(
- new ForceNamesHierarchy.BundleName,
- "bundlename",
- Seq(ForceNameAnnotation(ReferenceTarget("BundleName", "BundleName", Nil, "in", Nil), "inn"))
- )
- }
- }
-
- "Force Name of non-hardware value" should "warn" in {
- class Example extends Module {
- val tpe = UInt(8.W)
- forceName(tpe, "foobar")
-
- val in = IO(Input(tpe))
- val out = IO(Output(tpe))
- out := in
- }
-
- val (log, foo) = grabLog(chisel3.stage.ChiselStage.elaborate(new Example))
- log should include("deprecated")
- log should include("Using forceName 'foobar' on non-hardware value UInt<8>")
- }
-}
diff --git a/src/test/scala/chiselTests/experimental/GroupSpec.scala b/src/test/scala/chiselTests/experimental/GroupSpec.scala
deleted file mode 100644
index 5e0c34bb..00000000
--- a/src/test/scala/chiselTests/experimental/GroupSpec.scala
+++ /dev/null
@@ -1,115 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.experimental
-
-import chiselTests.ChiselFlatSpec
-import chisel3._
-import chisel3.RawModule
-import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage}
-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 = {
- (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 {
- 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)
- }
-}
diff --git a/src/test/scala/chiselTests/experimental/ModuleDataProductSpec.scala b/src/test/scala/chiselTests/experimental/ModuleDataProductSpec.scala
deleted file mode 100644
index 713f9d04..00000000
--- a/src/test/scala/chiselTests/experimental/ModuleDataProductSpec.scala
+++ /dev/null
@@ -1,91 +0,0 @@
-// See LICENSE for license details.
-
-package chiselTests.experimental
-
-import chisel3._
-import chisel3.experimental.{BaseModule, ExtModule}
-import chisel3.experimental.dataview.DataProduct
-import chiselTests.ChiselFlatSpec
-
-object ModuleDataProductSpec {
- class MyBundle extends Bundle {
- val foo = UInt(8.W)
- val bar = UInt(8.W)
- }
- trait MyIntf extends BaseModule {
- val in = IO(Input(new MyBundle))
- val out = IO(Output(new MyBundle))
- }
- class Passthrough extends RawModule {
- val in = IO(Input(UInt(8.W)))
- val out = IO(Output(UInt(8.W)))
- out := in
- }
- class MyUserModule extends Module with MyIntf {
- val inst = Module(new Passthrough)
- inst.in := in.foo
- val r = RegNext(in)
- out := r
- }
-
- class MyExtModule extends ExtModule with MyIntf
- class MyExtModuleWrapper extends RawModule with MyIntf {
- val inst = Module(new MyExtModule)
- inst.in := in
- out := inst.out
- }
-}
-
-class ModuleDataProductSpec extends ChiselFlatSpec {
- import ModuleDataProductSpec._
-
- behavior.of("DataProduct")
-
- it should "work for UserModules (recursively)" in {
- val m = elaborateAndGetModule(new MyUserModule)
- val expected = Seq(
- m.clock -> "m.clock",
- m.reset -> "m.reset",
- m.in -> "m.in",
- m.in.foo -> "m.in.foo",
- m.in.bar -> "m.in.bar",
- m.out -> "m.out",
- m.out.foo -> "m.out.foo",
- m.out.bar -> "m.out.bar",
- m.r -> "m.r",
- m.r.foo -> "m.r.foo",
- m.r.bar -> "m.r.bar",
- m.inst.in -> "m.inst.in",
- m.inst.out -> "m.inst.out"
- )
-
- val impl = implicitly[DataProduct[MyUserModule]]
- val set = impl.dataSet(m)
- for ((d, _) <- expected) {
- set(d) should be(true)
- }
- val it = impl.dataIterator(m, "m")
- it.toList should contain theSameElementsAs (expected)
- }
-
- it should "work for (wrapped) ExtModules" in {
- val m = elaborateAndGetModule(new MyExtModuleWrapper).inst
- val expected = Seq(
- m.in -> "m.in",
- m.in.foo -> "m.in.foo",
- m.in.bar -> "m.in.bar",
- m.out -> "m.out",
- m.out.foo -> "m.out.foo",
- m.out.bar -> "m.out.bar"
- )
-
- val impl = implicitly[DataProduct[MyExtModule]]
- val set = impl.dataSet(m)
- for ((d, _) <- expected) {
- set(d) should be(true)
- }
- val it = impl.dataIterator(m, "m")
- it.toList should contain theSameElementsAs (expected)
- }
-
-}
diff --git a/src/test/scala/chiselTests/experimental/ProgrammaticPortsSpec.scala b/src/test/scala/chiselTests/experimental/ProgrammaticPortsSpec.scala
deleted file mode 100644
index 64aabb4b..00000000
--- a/src/test/scala/chiselTests/experimental/ProgrammaticPortsSpec.scala
+++ /dev/null
@@ -1,73 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-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
-class PrivatePort extends NamedModuleTester {
- private val port = expectName(IO(Input(UInt(8.W))), "foo")
- port.suggestName("foo")
-}
-
-// Example of using composition to add ports to a Module
-class CompositionalPort(module: NamedModuleTester, name: String) {
- import chisel3.experimental.IO
- val foo = module.expectName(IO(Output(Bool())), name)
- foo.suggestName(name)
- foo := true.B
-}
-
-class CompositionalPortTester extends NamedModuleTester {
- val a = new CompositionalPort(this, "cheese")
- val b = new CompositionalPort(this, "tart")
-}
-
-class PortsWinTester extends NamedModuleTester {
- val wire = expectName(Wire(UInt()), "wire_1")
- val foo = expectName(Wire(UInt()).suggestName("wire"), "wire_2")
- val output = expectName(IO(Output(UInt())).suggestName("wire"), "wire")
-}
-
-class ProgrammaticPortsSpec extends ChiselFlatSpec with Utils {
-
- private def doTest(testMod: => NamedModuleTester): Unit = {
- var module: NamedModuleTester = null
- ChiselStage.elaborate { module = testMod; module }
- assert(module.getNameFailures() == Nil)
- }
-
- "Programmatic port creation" should "be supported" in {
- doTest(new PrivatePort)
- }
-
- "Calling IO outside of a Module definition" should "be supported" in {
- doTest(new CompositionalPortTester)
- }
-
- "Ports" should "always win over internal components in naming" in {
- doTest(new PortsWinTester)
- }
-
- "Module" should "ignore suggestName on clock and reset" in {
- doTest(new Module with NamedModuleTester {
- val io = IO(new Bundle {
- val foo = Output(UInt(8.W))
- })
- expectName(clock.suggestName("tart"), "clock")
- expectName(reset.suggestName("teser"), "reset")
- })
- }
-
- "SuggestName collisions on ports" should "be illegal" in {
- a[ChiselException] should be thrownBy extractCause[ChiselException] {
- ChiselStage.elaborate(new Module {
- val foo = IO(UInt(8.W)).suggestName("apple")
- val bar = IO(UInt(8.W)).suggestName("apple")
- })
- }
- }
-}
diff --git a/src/test/scala/chiselTests/experimental/TraceSpec.scala b/src/test/scala/chiselTests/experimental/TraceSpec.scala
deleted file mode 100644
index 1d67ba0b..00000000
--- a/src/test/scala/chiselTests/experimental/TraceSpec.scala
+++ /dev/null
@@ -1,328 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.experimental.Trace._
-import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage, DesignAnnotation}
-import chisel3.util.experimental.InlineInstance
-import firrtl.AnnotationSeq
-import firrtl.annotations.TargetToken.{Instance, OfModule, Ref}
-import firrtl.annotations.{CompleteTarget, InstanceTarget, ReferenceTarget}
-import org.scalatest.matchers.should.Matchers
-
-class TraceSpec extends ChiselFlatSpec with Matchers {
-
- def refTarget(topName: String, ref: String, path: Seq[(Instance, OfModule)] = Seq()) =
- ReferenceTarget(topName, topName, path, ref, Seq())
-
- def instTarget(topName: String, instance: String, ofModule: String, path: Seq[(Instance, OfModule)] = Seq()) =
- InstanceTarget(topName, topName, path, instance, ofModule)
-
- def compile(testName: String, gen: () => Module): (os.Path, AnnotationSeq) = {
- val testDir = os.Path(createTestDirectory(testName).getAbsolutePath)
- val annos = (new ChiselStage).execute(
- Array("--target-dir", s"$testDir"),
- Seq(
- ChiselGeneratorAnnotation(gen)
- )
- )
- (testDir, annos)
- }
-
- "TraceFromAnnotations" should "be able to get nested name." in {
- class Bundle0 extends Bundle {
- val a = UInt(8.W)
- val b = Bool()
- val c = Enum0.Type
- }
-
- class Bundle1 extends Bundle {
- val a = new Bundle0
- val b = Vec(4, Vec(4, Bool()))
- }
-
- class Module0 extends Module {
- val i = IO(Input(new Bundle1))
- val o = IO(Output(new Bundle1))
- val r = Reg(new Bundle1)
- o := r
- r := i
-
- traceName(r)
- traceName(i)
- traceName(o)
- }
-
- class Module1 extends Module {
- val i = IO(Input(new Bundle1))
- val m0 = Module(new Module0)
- m0.i := i
- m0.o := DontCare
- }
-
- object Enum0 extends ChiselEnum {
- val s0, s1, s2 = Value
- }
-
- val (testDir, annos) = compile("TraceFromAnnotaions", () => new Module1)
- val dut = annos.collectFirst { case DesignAnnotation(dut) => dut }.get.asInstanceOf[Module1]
- // out of Builder.
-
- val oneTarget = finalTarget(annos)(dut.m0.r.a.a).head
- val ioTarget = finalTarget(annos)(dut.m0.i.b(1)(2)).head
-
- val topName = "Module1"
- oneTarget should be(refTarget(topName, "r_a_a", Seq(Instance("m0") -> OfModule("Module0"))))
-
- ioTarget should be(refTarget(topName, "i_b_1_2", Seq(Instance("m0") -> OfModule("Module0"))))
-
- // Below codes doesn't needs to be a FIRRTL Transform.
- def generateVerilatorConfigFile(data: Seq[Data], annos: AnnotationSeq): String =
- """`verilator_config
- |lint_off -rule unused
- |lint_off -rule declfilename
- |""".stripMargin +
- data
- .flatMap(finalTarget(annos))
- .toSet
- .map { target: CompleteTarget =>
- s"""public_flat_rd -module "${target.tokens.collectFirst {
- case OfModule(m) => m
- }.get}" -var "${target.tokens.collectFirst { case Ref(r) => r }.get}""""
- }
- .mkString("\n") + "\n"
-
- def verilatorTemplate(data: Seq[Data], annos: AnnotationSeq): String = {
- val vpiNames = data.flatMap(finalTarget(annos)).map { ct =>
- s"""TOP.${ct.circuit}.${ct.path.map { case (Instance(i), _) => i }.mkString(".")}.${ct.tokens.collectFirst {
- case Ref(r) => r
- }.get}"""
- }
- s"""
- |#include "V${topName}.h"
- |#include "verilated_vpi.h"
- |#include <memory>
- |#include <verilated.h>
- |
- |int vpiGetInt(const char name[]) {
- | vpiHandle vh1 = vpi_handle_by_name((PLI_BYTE8 *)name, NULL);
- | if (!vh1)
- | vl_fatal(__FILE__, __LINE__, "sim_main", "No handle found");
- | s_vpi_value v;
- | v.format = vpiIntVal;
- | vpi_get_value(vh1, &v);
- | return v.value.integer;
- |}
- |
- |int main(int argc, char **argv) {
- | const std::unique_ptr<VerilatedContext> contextp{new VerilatedContext};
- | contextp->commandArgs(argc, argv);
- | const std::unique_ptr<V$topName> top{new V$topName{contextp.get(), "TOP"}};
- | top->reset = 0;
- | top->clock = 0;
- | int a_b = 1;
- | top->i_a_b = a_b;
- | bool started = false;
- | int ticks = 20;
- | while (ticks--) {
- | contextp->timeInc(1);
- | top->clock = !top->clock;
- | if (!top->clock) {
- | if (contextp->time() > 1 && contextp->time() < 10) {
- | top->reset = 1;
- | } else {
- | top->reset = 0;
- | started = true;
- | }
- | a_b = a_b ? 0 : 1;
- | top->i_a_b = a_b;
- | }
- | top->eval();
- | VerilatedVpi::callValueCbs();
- | if (started && !top->clock) {
- | const int i = top->i_a_b;
- | const int o = vpiGetInt("${vpiNames.head}");
- | if (i == o)
- | vl_fatal(__FILE__, __LINE__, "sim_main", "${vpiNames.head} should be the old value of Module1.i_a_b");
- | printf("${vpiNames.head}=%d Module1.m0.o_a_b=%d\\n", i, o);
- | }
- | }
- | top->final();
- | return 0;
- |}
- |""".stripMargin
- }
-
- val config = os.temp(dir = testDir, contents = generateVerilatorConfigFile(Seq(dut.m0.o.a.b), annos))
- val verilog = testDir / s"$topName.v"
- val cpp = os.temp(dir = testDir, suffix = ".cpp", contents = verilatorTemplate(Seq(dut.m0.o.a.b), annos))
- val exe = testDir / "obj_dir" / s"V$topName"
- os.proc("verilator", "-Wall", "--cc", "--exe", "--build", "--vpi", s"$cpp", s"$verilog", s"$config")
- .call(stdout = os.Inherit, stderr = os.Inherit, cwd = testDir)
- assert(
- os.proc(s"$exe").call(stdout = os.Inherit, stderr = os.Inherit).exitCode == 0,
- "verilator should exit peacefully"
- )
- }
-
- "TraceFromCollideBundle" should "work" in {
- class CollideModule extends Module {
- val a = IO(
- Input(
- Vec(
- 2,
- new Bundle {
- val b = Flipped(Bool())
- val c = Vec(
- 2,
- new Bundle {
- val d = UInt(2.W)
- val e = Flipped(UInt(3.W))
- }
- )
- val c_1_e = UInt(4.W)
- }
- )
- )
- )
- val a_0_c = IO(Output(UInt(5.W)))
- val a__0 = IO(Output(UInt(5.W)))
- a_0_c := DontCare
- a__0 := DontCare
-
- traceName(a)
- traceName(a_0_c)
- traceName(a__0)
- }
-
- val (_, annos) = compile("TraceFromCollideBundle", () => new CollideModule)
- val dut = annos.collectFirst { case DesignAnnotation(dut) => dut }.get.asInstanceOf[CollideModule]
-
- val topName = "CollideModule"
-
- val a0 = finalTarget(annos)(dut.a(0))
- val a__0 = finalTarget(annos)(dut.a__0).head
- val a__0_ref = refTarget(topName, "a__0")
- a0.foreach(_ shouldNot be(a__0_ref))
- a__0 should be(a__0_ref)
-
- val a0_c = finalTarget(annos)(dut.a(0).c)
- val a_0_c = finalTarget(annos)(dut.a_0_c).head
- val a_0_c_ref = refTarget(topName, "a_0_c")
- a0_c.foreach(_ shouldNot be(a_0_c_ref))
- a_0_c should be(a_0_c_ref)
-
- val a0_c1_e = finalTarget(annos)(dut.a(0).c(1).e).head
- val a0_c_1_e = finalTarget(annos)(dut.a(0).c_1_e).head
- a0_c1_e should be(refTarget(topName, "a_0_c__1_e"))
- a0_c_1_e should be(refTarget(topName, "a_0_c_1_e"))
- }
-
- "Inline should work" should "work" in {
- class Module0 extends Module {
- val i = IO(Input(Bool()))
- val o = IO(Output(Bool()))
- traceName(i)
- o := !i
- }
-
- class Module1 extends Module {
- val i = IO(Input(Bool()))
- val o = IO(Output(Bool()))
- val m0 = Module(new Module0 with InlineInstance)
- m0.i := i
- o := m0.o
- }
-
- val (_, annos) = compile("Inline", () => new Module1)
- val dut = annos.collectFirst { case DesignAnnotation(dut) => dut }.get.asInstanceOf[Module1]
-
- val m0_i = finalTarget(annos)(dut.m0.i).head
- m0_i should be(refTarget("Module1", "m0_i"))
- }
-
- "Constant Propagation" should "be turned off by traceName" in {
- class Module0 extends Module {
- val i = WireDefault(1.U)
- val i0 = i + 1.U
- val o = IO(Output(UInt(2.W)))
- traceName(i0)
- o := i0
- }
-
- val (_, annos) = compile("ConstantProp", () => new Module0)
- val dut = annos.collectFirst { case DesignAnnotation(dut) => dut }.get.asInstanceOf[Module0]
-
- val i0 = finalTarget(annos)(dut.i0).head
- i0 should be(refTarget("Module0", "i0"))
- }
-
- "Nested Module" should "work" in {
- class Io extends Bundle {
- val i = Input(Bool())
- val o = Output(Bool())
- }
-
- class Not extends Module {
- val io = IO(new Io)
- io.o := !io.i
- }
-
- class M1 extends Module {
- val io = IO(new Io)
- val not = Module(new Not)
- not.io <> io
- }
-
- class M2 extends Module {
- val io = IO(new Io)
- val m1 = Module(new M1 with InlineInstance)
- val not = Module(new Not)
-
- m1.io.i := io.i
- not.io.i := io.i
-
- io.o := m1.io.o && not.io.o
- }
-
- class M3 extends Module {
- val io = IO(new Io)
- val m2 = Module(new M2)
- io <> m2.io
- traceName(m2.not)
- traceName(m2.m1.not)
- }
-
- val (_, annos) = compile("NestedModule", () => new M3)
- val m3 = annos.collectFirst { case DesignAnnotation(dut) => dut }.get.asInstanceOf[M3]
-
- val m2_m1_not = finalTarget(annos)(m3.m2.m1.not).head
- val m2_not = finalTarget(annos)(m3.m2.not).head
-
- m2_m1_not should be(instTarget("M3", "m1_not", "Not", Seq(Instance("m2") -> OfModule("M2"))))
- m2_not should be(instTarget("M3", "not", "Not", Seq(Instance("m2") -> OfModule("M2"))))
- }
-
- "All traced signal" should "generate" in {
- class M extends Module {
- val a = Wire(Bool())
- val b = Wire(Vec(2, Bool()))
- a := DontCare
- b := DontCare
- Seq(a, b).foreach(traceName)
- }
- val (_, annos) = compile("NestedModule", () => new M)
- val dut = annos.collectFirst { case DesignAnnotation(dut) => dut }.get.asInstanceOf[M]
- val allTargets = finalTargetMap(annos)
- allTargets(dut.a.toAbsoluteTarget) should be(Seq(refTarget("M", "a")))
- allTargets(dut.b.toAbsoluteTarget) should be(
- Seq(
- refTarget("M", "b_0"),
- refTarget("M", "b_1")
- )
- )
- allTargets(dut.b(0).toAbsoluteTarget) should be(Seq(refTarget("M", "b_0")))
- allTargets(dut.b(1).toAbsoluteTarget) should be(Seq(refTarget("M", "b_1")))
- }
-}
diff --git a/src/test/scala/chiselTests/experimental/Tuple.scala b/src/test/scala/chiselTests/experimental/Tuple.scala
deleted file mode 100644
index b57766e7..00000000
--- a/src/test/scala/chiselTests/experimental/Tuple.scala
+++ /dev/null
@@ -1,163 +0,0 @@
-// See LICENSE for license details.
-
-package chiselTests.experimental
-
-import chiselTests.ChiselFlatSpec
-import chisel3._
-import chisel3.experimental.conversions._
-import chisel3.stage.ChiselStage
-
-class TupleSpec extends ChiselFlatSpec {
-
- behavior.of("Tuple")
-
- it should "enable using Tuple2 like Data" in {
- class MyModule extends Module {
- val a, b, c, d = IO(Input(UInt(8.W)))
- val sel = IO(Input(Bool()))
- val y, z = IO(Output(UInt(8.W)))
- (y, z) := Mux(sel, (a, b), (c, d))
- }
- // Verilog instead of CHIRRTL because the optimizations make it much prettier
- val verilog = ChiselStage.emitVerilog(new MyModule)
- verilog should include("assign y = sel ? a : c;")
- verilog should include("assign z = sel ? b : d;")
- }
-
- it should "support nesting of tuples" in {
- class MyModule extends Module {
- val a, b, c, d = IO(Input(UInt(8.W)))
- val w, x, y, z = IO(Output(UInt(8.W)))
- ((w, x), (y, z)) := ((a, b), (c, d))
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- chirrtl should include("w <= a")
- chirrtl should include("x <= b")
- chirrtl should include("y <= c")
- chirrtl should include("z <= d")
- }
-
- it should "enable using Tuple3 like Data" in {
- class MyModule extends Module {
- val a, b, c = IO(Input(UInt(8.W)))
- val f, g, h = IO(Input(UInt(8.W)))
- val sel = IO(Input(Bool()))
- val v, w, x = IO(Output(UInt(8.W)))
- (v, w, x) := Mux(sel, (a, b, c), (f, g, h))
- }
- // Verilog instead of CHIRRTL because the optimizations make it much prettier
- val verilog = ChiselStage.emitVerilog(new MyModule)
- verilog should include("assign v = sel ? a : f;")
- verilog should include("assign w = sel ? b : g;")
- verilog should include("assign x = sel ? c : h;")
- }
-
- it should "enable using Tuple4 like Data" in {
- class MyModule extends Module {
- val a, b, c, d = IO(Input(UInt(8.W)))
- val f, g, h, i = IO(Input(UInt(8.W)))
- val sel = IO(Input(Bool()))
- val v, w, x, y = IO(Output(UInt(8.W)))
- (v, w, x, y) := Mux(sel, (a, b, c, d), (f, g, h, i))
- }
- // Verilog instead of CHIRRTL because the optimizations make it much prettier
- val verilog = ChiselStage.emitVerilog(new MyModule)
- verilog should include("assign v = sel ? a : f;")
- verilog should include("assign w = sel ? b : g;")
- verilog should include("assign x = sel ? c : h;")
- verilog should include("assign y = sel ? d : i;")
- }
-
- it should "enable using Tuple5 like Data" in {
- class MyModule extends Module {
- val a0, a1, a2, a3, a4 = IO(Input(UInt(8.W)))
- val b0, b1, b2, b3, b4 = IO(Input(UInt(8.W)))
- val sel = IO(Input(Bool()))
- val z0, z1, z2, z3, z4 = IO(Output(UInt(8.W)))
- (z0, z1, z2, z3, z4) := Mux(sel, (a0, a1, a2, a3, a4), (b0, b1, b2, b3, b4))
- }
- // Verilog instead of CHIRRTL because the optimizations make it much prettier
- val verilog = ChiselStage.emitVerilog(new MyModule)
- for (i <- 0 until 5) {
- verilog should include(s"assign z$i = sel ? a$i : b$i;")
- }
- }
-
- it should "enable using Tuple6 like Data" in {
- class MyModule extends Module {
- val a0, a1, a2, a3, a4, a5 = IO(Input(UInt(8.W)))
- val b0, b1, b2, b3, b4, b5 = IO(Input(UInt(8.W)))
- val sel = IO(Input(Bool()))
- val z0, z1, z2, z3, z4, z5 = IO(Output(UInt(8.W)))
- (z0, z1, z2, z3, z4, z5) := Mux(sel, (a0, a1, a2, a3, a4, a5), (b0, b1, b2, b3, b4, b5))
- }
- // Verilog instead of CHIRRTL because the optimizations make it much prettier
- val verilog = ChiselStage.emitVerilog(new MyModule)
- for (i <- 0 until 6) {
- verilog should include(s"assign z$i = sel ? a$i : b$i;")
- }
- }
-
- it should "enable using Tuple7 like Data" in {
- class MyModule extends Module {
- val a0, a1, a2, a3, a4, a5, a6 = IO(Input(UInt(8.W)))
- val b0, b1, b2, b3, b4, b5, b6 = IO(Input(UInt(8.W)))
- val sel = IO(Input(Bool()))
- val z0, z1, z2, z3, z4, z5, z6 = IO(Output(UInt(8.W)))
- (z0, z1, z2, z3, z4, z5, z6) := Mux(sel, (a0, a1, a2, a3, a4, a5, a6), (b0, b1, b2, b3, b4, b5, b6))
- }
- // Verilog instead of CHIRRTL because the optimizations make it much prettier
- val verilog = ChiselStage.emitVerilog(new MyModule)
- for (i <- 0 until 7) {
- verilog should include(s"assign z$i = sel ? a$i : b$i;")
- }
- }
-
- it should "enable using Tuple8 like Data" in {
- class MyModule extends Module {
- val a0, a1, a2, a3, a4, a5, a6, a7 = IO(Input(UInt(8.W)))
- val b0, b1, b2, b3, b4, b5, b6, b7 = IO(Input(UInt(8.W)))
- val sel = IO(Input(Bool()))
- val z0, z1, z2, z3, z4, z5, z6, z7 = IO(Output(UInt(8.W)))
- (z0, z1, z2, z3, z4, z5, z6, z7) := Mux(sel, (a0, a1, a2, a3, a4, a5, a6, a7), (b0, b1, b2, b3, b4, b5, b6, b7))
- }
- // Verilog instead of CHIRRTL because the optimizations make it much prettier
- val verilog = ChiselStage.emitVerilog(new MyModule)
- for (i <- 0 until 8) {
- verilog should include(s"assign z$i = sel ? a$i : b$i;")
- }
- }
-
- it should "enable using Tuple9 like Data" in {
- class MyModule extends Module {
- val a0, a1, a2, a3, a4, a5, a6, a7, a8 = IO(Input(UInt(8.W)))
- val b0, b1, b2, b3, b4, b5, b6, b7, b8 = IO(Input(UInt(8.W)))
- val sel = IO(Input(Bool()))
- val z0, z1, z2, z3, z4, z5, z6, z7, z8 = IO(Output(UInt(8.W)))
- (z0, z1, z2, z3, z4, z5, z6, z7, z8) :=
- Mux(sel, (a0, a1, a2, a3, a4, a5, a6, a7, a8), (b0, b1, b2, b3, b4, b5, b6, b7, b8))
- }
- // Verilog instead of CHIRRTL because the optimizations make it much prettier
- val verilog = ChiselStage.emitVerilog(new MyModule)
- for (i <- 0 until 9) {
- verilog should include(s"assign z$i = sel ? a$i : b$i;")
- }
- }
-
- it should "enable using Tuple10 like Data" in {
- class MyModule extends Module {
- val a0, a1, a2, a3, a4, a5, a6, a7, a8, a9 = IO(Input(UInt(8.W)))
- val b0, b1, b2, b3, b4, b5, b6, b7, b8, b9 = IO(Input(UInt(8.W)))
- val sel = IO(Input(Bool()))
- val z0, z1, z2, z3, z4, z5, z6, z7, z8, z9 = IO(Output(UInt(8.W)))
- (z0, z1, z2, z3, z4, z5, z6, z7, z8, z9) :=
- Mux(sel, (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9), (b0, b1, b2, b3, b4, b5, b6, b7, b8, b9))
- }
- // Verilog instead of CHIRRTL because the optimizations make it much prettier
- val verilog = ChiselStage.emitVerilog(new MyModule)
- for (i <- 0 until 10) {
- verilog should include(s"assign z$i = sel ? a$i : b$i;")
- }
- }
-
-}
diff --git a/src/test/scala/chiselTests/experimental/hierarchy/Annotations.scala b/src/test/scala/chiselTests/experimental/hierarchy/Annotations.scala
deleted file mode 100644
index ec71fe09..00000000
--- a/src/test/scala/chiselTests/experimental/hierarchy/Annotations.scala
+++ /dev/null
@@ -1,32 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.experimental.hierarchy
-
-import _root_.firrtl.annotations._
-import chisel3.experimental.{annotate, BaseModule}
-import chisel3.{Data, MemBase}
-import chisel3.experimental.hierarchy.{Definition, Hierarchy, Instance}
-
-// These annotations exist purely for testing purposes
-private[hierarchy] object Annotations {
- case class MarkAnnotation(target: IsMember, tag: String) extends SingleTargetAnnotation[IsMember] {
- def duplicate(n: IsMember): Annotation = this.copy(target = n)
- }
- case class MarkChiselHierarchyAnnotation[B <: BaseModule](d: Hierarchy[B], tag: String, isAbsolute: Boolean)
- extends chisel3.experimental.ChiselAnnotation {
- def toFirrtl = MarkAnnotation(d.toTarget, tag)
- }
- case class MarkChiselAnnotation(d: Data, tag: String, isAbsolute: Boolean)
- extends chisel3.experimental.ChiselAnnotation {
- def toFirrtl = if (isAbsolute) MarkAnnotation(d.toAbsoluteTarget, tag) else MarkAnnotation(d.toTarget, tag)
- }
- case class MarkChiselMemAnnotation[T <: Data](m: MemBase[T], tag: String, isAbsolute: Boolean)
- extends chisel3.experimental.ChiselAnnotation {
- def toFirrtl = if (isAbsolute) MarkAnnotation(m.toAbsoluteTarget, tag) else MarkAnnotation(m.toTarget, tag)
- }
- def mark(d: Data, tag: String): Unit = annotate(MarkChiselAnnotation(d, tag, false))
- def mark[T <: Data](d: MemBase[T], tag: String): Unit = annotate(MarkChiselMemAnnotation(d, tag, false))
- def mark[B <: BaseModule](d: Hierarchy[B], tag: String): Unit = annotate(MarkChiselHierarchyAnnotation(d, tag, true))
- def amark(d: Data, tag: String): Unit = annotate(MarkChiselAnnotation(d, tag, true))
- def amark[B <: BaseModule](d: Hierarchy[B], tag: String): Unit = annotate(MarkChiselHierarchyAnnotation(d, tag, true))
-}
diff --git a/src/test/scala/chiselTests/experimental/hierarchy/DefinitionSpec.scala b/src/test/scala/chiselTests/experimental/hierarchy/DefinitionSpec.scala
deleted file mode 100644
index 6ff4a3eb..00000000
--- a/src/test/scala/chiselTests/experimental/hierarchy/DefinitionSpec.scala
+++ /dev/null
@@ -1,599 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-package experimental.hierarchy
-
-import chisel3._
-import chisel3.experimental.BaseModule
-import chisel3.experimental.hierarchy.{instantiable, public, Definition, Instance}
-
-// TODO/Notes
-// - In backport, clock/reset are not automatically assigned. I think this is fixed in 3.5
-// - CircuitTarget for annotations on the definition are wrong - needs to be fixed.
-class DefinitionSpec extends ChiselFunSpec with Utils {
- import Annotations._
- import Examples._
- describe("0: Definition instantiation") {
- it("0.0: module name of a definition should be correct") {
- class Top extends Module {
- val definition = Definition(new AddOne)
- }
- val (chirrtl, _) = getFirrtlAndAnnos(new Top)
- chirrtl.serialize should include("module AddOne :")
- }
- it("0.2: accessing internal fields through non-generated means is hard to do") {
- class Top extends Module {
- val definition = Definition(new AddOne)
- //definition.lookup(_.in) // Uncommenting this line will give the following error:
- //"You are trying to access a macro-only API. Please use the @public annotation instead."
- definition.in
- }
- val (chirrtl, _) = getFirrtlAndAnnos(new Top)
- chirrtl.serialize should include("module AddOne :")
- }
- it("0.2: reset inference is not defaulted to Bool for definitions") {
- class Top extends Module with RequireAsyncReset {
- val definition = Definition(new HasUninferredReset)
- val i0 = Instance(definition)
- i0.in := 0.U
- }
- val (chirrtl, _) = getFirrtlAndAnnos(new Top)
- chirrtl.serialize should include("inst i0 of HasUninferredReset")
- }
- it("0.3: module names of repeated definition should be sequential") {
- class Top extends Module {
- val k = Module(
- new AddTwoParameterized(
- 4,
- (x: Int) =>
- Seq.tabulate(x) { j =>
- val addOneDef = Definition(new AddOneParameterized(x + j))
- val addOne = Instance(addOneDef)
- addOne
- }
- )
- )
- }
- val (chirrtl, _) = getFirrtlAndAnnos(new Top)
- chirrtl.serialize should include("module AddOneParameterized :")
- chirrtl.serialize should include("module AddOneParameterized_1 :")
- chirrtl.serialize should include("module AddOneParameterized_2 :")
- chirrtl.serialize should include("module AddOneParameterized_3 :")
- }
- it("0.4: multiple instantiations should have sequential names") {
- class Top extends Module {
- val addOneDef = Definition(new AddOneParameterized(4))
- val addOne = Instance(addOneDef)
- val otherAddOne = Module(new AddOneParameterized(4))
- }
- val (chirrtl, _) = getFirrtlAndAnnos(new Top)
- chirrtl.serialize should include("module AddOneParameterized :")
- chirrtl.serialize should include("module AddOneParameterized_1 :")
- }
- it("0.5: nested definitions should have sequential names") {
- class Top extends Module {
- val k = Module(
- new AddTwoWithNested(
- 4,
- (x: Int) =>
- Seq.tabulate(x) { j =>
- val addOneDef = Definition(new AddOneWithNested(x + j))
- val addOne = Instance(addOneDef)
- addOne
- }
- )
- )
- }
- val (chirrtl, _) = getFirrtlAndAnnos(new Top)
- chirrtl.serialize should include("module AddOneWithNested :")
- chirrtl.serialize should include("module AddOneWithNested_1 :")
- chirrtl.serialize should include("module AddOneWithNested_2 :")
- chirrtl.serialize should include("module AddOneWithNested_3 :")
- }
- }
- describe("1: Annotations on definitions in same chisel compilation") {
- it("1.0: should work on a single definition, annotating the definition") {
- class Top extends Module {
- val definition: Definition[AddOne] = Definition(new AddOne)
- mark(definition, "mark")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddOne".mt, "mark"))
- }
- it("1.1: should work on a single definition, annotating an inner wire") {
- class Top extends Module {
- val definition: Definition[AddOne] = Definition(new AddOne)
- mark(definition.innerWire, "i0.innerWire")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddOne>innerWire".rt, "i0.innerWire"))
- }
- it("1.2: should work on a two nested definitions, annotating the definition") {
- class Top extends Module {
- val definition: Definition[AddTwo] = Definition(new AddTwo)
- mark(definition.definition, "i0.i0")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddOne".mt, "i0.i0"))
- }
- it("1.2: should work on an instance in a definition, annotating the instance") {
- class Top extends Module {
- val definition: Definition[AddTwo] = Definition(new AddTwo)
- mark(definition.i0, "i0.i0")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddTwo/i0:AddOne".it, "i0.i0"))
- }
- it("1.2: should work on a definition in an instance, annotating the definition") {
- class Top extends Module {
- val definition: Definition[AddTwo] = Definition(new AddTwo)
- val i0 = Instance(definition)
- mark(i0.definition, "i0.i0")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddOne".mt, "i0.i0"))
- }
- it("1.3: should work on a wire in an instance in a definition") {
- class Top extends Module {
- val definition: Definition[AddTwo] = Definition(new AddTwo)
- mark(definition.i0.innerWire, "i0.i0.innerWire")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddTwo/i0:AddOne>innerWire".rt, "i0.i0.innerWire"))
- }
- it("1.4: should work on a nested module in a definition, annotating the module") {
- class Top extends Module {
- val definition: Definition[AddTwoMixedModules] = Definition(new AddTwoMixedModules)
- mark(definition.i1, "i0.i1")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddTwoMixedModules/i1:AddOne_1".it, "i0.i1"))
- }
- // Can you define an instantiable container? I think not.
- // Instead, we can test the instantiable container in a definition
- it("1.5: should work on an instantiable container, annotating a wire in the defintion") {
- class Top extends Module {
- val definition: Definition[AddOneWithInstantiableWire] = Definition(new AddOneWithInstantiableWire)
- mark(definition.wireContainer.innerWire, "i0.innerWire")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddOneWithInstantiableWire>innerWire".rt, "i0.innerWire"))
- }
- it("1.6: should work on an instantiable container, annotating a module") {
- class Top extends Module {
- val definition = Definition(new AddOneWithInstantiableModule)
- mark(definition.moduleContainer.i0, "i0.i0")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddOneWithInstantiableModule/i0:AddOne".it, "i0.i0"))
- }
- it("1.7: should work on an instantiable container, annotating an instance") {
- class Top extends Module {
- val definition = Definition(new AddOneWithInstantiableInstance)
- mark(definition.instanceContainer.i0, "i0.i0")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddOneWithInstantiableInstance/i0:AddOne".it, "i0.i0"))
- }
- it("1.8: should work on an instantiable container, annotating an instantiable container's module") {
- class Top extends Module {
- val definition = Definition(new AddOneWithInstantiableInstantiable)
- mark(definition.containerContainer.container.i0, "i0.i0")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddOneWithInstantiableInstantiable/i0:AddOne".it, "i0.i0"))
- }
- it("1.9: should work on public member which references public member of another instance") {
- class Top extends Module {
- val definition = Definition(new AddOneWithInstantiableInstantiable)
- mark(definition.containerContainer.container.i0, "i0.i0")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddOneWithInstantiableInstantiable/i0:AddOne".it, "i0.i0"))
- }
- it("1.10: should work for targets on definition to have correct circuit name") {
- class Top extends Module {
- val definition = Definition(new AddOneWithAnnotation)
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddOneWithAnnotation>innerWire".rt, "innerWire"))
- }
- }
- describe("2: Annotations on designs not in the same chisel compilation") {
- it("2.0: should work on an innerWire, marked in a different compilation") {
- val first = elaborateAndGetModule(new AddTwo)
- class Top(x: AddTwo) extends Module {
- val parent = Definition(new ViewerParent(x, false, true))
- }
- val (_, annos) = getFirrtlAndAnnos(new Top(first))
- annos should contain(MarkAnnotation("~AddTwo|AddTwo/i0:AddOne>innerWire".rt, "first"))
- }
- it("2.1: should work on an innerWire, marked in a different compilation, in instanced instantiable") {
- val first = elaborateAndGetModule(new AddTwo)
- class Top(x: AddTwo) extends Module {
- val parent = Definition(new ViewerParent(x, true, false))
- }
- val (_, annos) = getFirrtlAndAnnos(new Top(first))
- annos should contain(MarkAnnotation("~AddTwo|AddTwo/i0:AddOne>innerWire".rt, "second"))
- }
- it("2.2: should work on an innerWire, marked in a different compilation, in instanced module") {
- val first = elaborateAndGetModule(new AddTwo)
- class Top(x: AddTwo) extends Module {
- val parent = Definition(new ViewerParent(x, false, false))
- mark(parent.viewer.x.i0.innerWire, "third")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top(first))
- annos should contain(MarkAnnotation("~AddTwo|AddTwo/i0:AddOne>innerWire".rt, "third"))
- }
- }
- describe("3: @public") {
- it("3.0: should work on multi-vals") {
- class Top() extends Module {
- val mv = Definition(new MultiVal())
- mark(mv.x, "mv.x")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|MultiVal>x".rt, "mv.x"))
- }
- it("3.1: should work on lazy vals") {
- class Top() extends Module {
- val lv = Definition(new LazyVal())
- mark(lv.x, lv.y)
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|LazyVal>x".rt, "Hi"))
- }
- it("3.2: should work on islookupables") {
- class Top() extends Module {
- val p = Parameters("hi", 0)
- val up = Definition(new UsesParameters(p))
- mark(up.x, up.y.string + up.y.int)
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|UsesParameters>x".rt, "hi0"))
- }
- it("3.3: should work on lists") {
- class Top() extends Module {
- val i = Definition(new HasList())
- mark(i.x(1), i.y(1).toString)
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|HasList>x_1".rt, "2"))
- }
- it("3.4: should work on seqs") {
- class Top() extends Module {
- val i = Definition(new HasSeq())
- mark(i.x(1), i.y(1).toString)
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|HasSeq>x_1".rt, "2"))
- }
- it("3.5: should work on options") {
- class Top() extends Module {
- val i = Definition(new HasOption())
- i.x.map(x => mark(x, "x"))
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|HasOption>x".rt, "x"))
- }
- it("3.6: should work on vecs") {
- class Top() extends Module {
- val i = Definition(new HasVec())
- mark(i.x, "blah")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|HasVec>x".rt, "blah"))
- }
- it("3.7: should work on statically indexed vectors external to module") {
- class Top() extends Module {
- val i = Definition(new HasVec())
- mark(i.x(1), "blah")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|HasVec>x[1]".rt, "blah"))
- }
- it("3.8: should work on statically indexed vectors internal to module") {
- class Top() extends Module {
- val i = Definition(new HasIndexedVec())
- mark(i.y, "blah")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|HasIndexedVec>x[1]".rt, "blah"))
- }
- ignore("3.9: should work on vals in constructor arguments") {
- class Top() extends Module {
- val i = Definition(new HasPublicConstructorArgs(10))
- //mark(i.x, i.int.toString)
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|HasPublicConstructorArgs>x".rt, "10"))
- }
- it("3.10: should work on unimplemented vals in abstract classes/traits") {
- class Top() extends Module {
- val i = Definition(new ConcreteHasBlah())
- def f(d: Definition[HasBlah]): Unit = {
- mark(d, d.blah.toString)
- }
- f(i)
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|ConcreteHasBlah".mt, "10"))
- }
- it("3.11: should work on eithers") {
- class Top() extends Module {
- val i = Definition(new HasEither())
- i.x.map(x => mark(x, "xright")).left.map(x => mark(x, "xleft"))
- i.y.map(x => mark(x, "yright")).left.map(x => mark(x, "yleft"))
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|HasEither>x".rt, "xright"))
- annos should contain(MarkAnnotation("~Top|HasEither>y".rt, "yleft"))
- }
- it("3.12: should work on tuple2") {
- class Top() extends Module {
- val i = Definition(new HasTuple2())
- mark(i.xy._1, "x")
- mark(i.xy._2, "y")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|HasTuple2>x".rt, "x"))
- annos should contain(MarkAnnotation("~Top|HasTuple2>y".rt, "y"))
- }
- it("3.13: should work on Mems/SyncReadMems") {
- class Top() extends Module {
- val i = Definition(new HasMems())
- mark(i.mem, "Mem")
- mark(i.syncReadMem, "SyncReadMem")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|HasMems>mem".rt, "Mem"))
- annos should contain(MarkAnnotation("~Top|HasMems>syncReadMem".rt, "SyncReadMem"))
- }
- it("3.14: should not create memory ports") {
- class Top() extends Module {
- val i = Definition(new HasMems())
- i.mem(0) := 100.U // should be illegal!
- }
- val failure = intercept[ChiselException] {
- getFirrtlAndAnnos(new Top)
- }
- assert(
- failure.getMessage ==
- "Cannot create a memory port in a different module (Top) than where the memory is (HasMems)."
- )
- }
- }
- describe("4: toDefinition") {
- it("4.0: should work on modules") {
- class Top() extends Module {
- val i = Module(new AddOne())
- f(i.toDefinition)
- }
- def f(i: Definition[AddOne]): Unit = mark(i.innerWire, "blah")
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddOne>innerWire".rt, "blah"))
- }
- it("4.2: should work on seqs of modules") {
- class Top() extends Module {
- val is = Seq(Module(new AddTwo()), Module(new AddTwo())).map(_.toDefinition)
- mark(f(is), "blah")
- }
- def f(i: Seq[Definition[AddTwo]]): Data = i.head.i0.innerWire
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddTwo/i0:AddOne>innerWire".rt, "blah"))
- }
- it("4.2: should work on options of modules") {
- class Top() extends Module {
- val is: Option[Definition[AddTwo]] = Some(Module(new AddTwo())).map(_.toDefinition)
- mark(f(is), "blah")
- }
- def f(i: Option[Definition[AddTwo]]): Data = i.get.i0.innerWire
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddTwo/i0:AddOne>innerWire".rt, "blah"))
- }
- }
- describe("5: Absolute Targets should work as expected") {
- it("5.0: toAbsoluteTarget on a port of a definition") {
- class Top() extends Module {
- val i = Definition(new AddTwo())
- amark(i.in, "blah")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddTwo>in".rt, "blah"))
- }
- it("5.1: toAbsoluteTarget on a subinstance's data within a definition") {
- class Top() extends Module {
- val i = Definition(new AddTwo())
- amark(i.i0.innerWire, "blah")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddTwo/i0:AddOne>innerWire".rt, "blah"))
- }
- it("5.2: toAbsoluteTarget on a submodule's data within a definition") {
- class Top() extends Module {
- val i = Definition(new AddTwoMixedModules())
- amark(i.i1.in, "blah")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddTwoMixedModules/i1:AddOne_1>in".rt, "blah"))
- }
- it("5.3: toAbsoluteTarget on a submodule's data, in an aggregate, within a definition") {
- class Top() extends Module {
- val i = Definition(new InstantiatesHasVec())
- amark(i.i1.x.head, "blah")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|InstantiatesHasVec/i1:HasVec_1>x[0]".rt, "blah"))
- }
- }
- describe("6: @instantiable traits should work as expected") {
- class MyBundle extends Bundle {
- val in = Input(UInt(8.W))
- val out = Output(UInt(8.W))
- }
- @instantiable
- trait ModuleIntf extends BaseModule {
- @public val io = IO(new MyBundle)
- }
- @instantiable
- class ModuleWithCommonIntf(suffix: String = "") extends Module with ModuleIntf {
- override def desiredName: String = super.desiredName + suffix
- @public val sum = io.in + 1.U
-
- io.out := sum
- }
- class BlackBoxWithCommonIntf extends BlackBox with ModuleIntf
-
- it("6.0: A Module that implements an @instantiable trait should be definable as that trait") {
- class Top extends Module {
- val i: Definition[ModuleIntf] = Definition(new ModuleWithCommonIntf)
- mark(i.io.in, "gotcha")
- mark(i, "inst")
- }
- val expected = List(
- "~Top|ModuleWithCommonIntf>io.in".rt -> "gotcha",
- "~Top|ModuleWithCommonIntf".mt -> "inst"
- )
- val (chirrtl, annos) = getFirrtlAndAnnos(new Top)
- for (e <- expected.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
- it(
- "6.1 An @instantiable Module that implements an @instantiable trait should be able to use extension methods from both"
- ) {
- class Top extends Module {
- val i: Definition[ModuleWithCommonIntf] = Definition(new ModuleWithCommonIntf)
- mark(i.io.in, "gotcha")
- mark(i.sum, "also this")
- mark(i, "inst")
- }
- val expected = List(
- "~Top|ModuleWithCommonIntf>io.in".rt -> "gotcha",
- "~Top|ModuleWithCommonIntf>sum".rt -> "also this",
- "~Top|ModuleWithCommonIntf".mt -> "inst"
- )
- val (chirrtl, annos) = getFirrtlAndAnnos(new Top)
- for (e <- expected.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
- it("6.2 A BlackBox that implements an @instantiable trait should be instantiable as that trait") {
- class Top extends Module {
- val m: ModuleIntf = Module(new BlackBoxWithCommonIntf)
- val d: Definition[ModuleIntf] = m.toDefinition
- mark(d.io.in, "gotcha")
- mark(d, "module")
- }
- val expected = List(
- "~Top|BlackBoxWithCommonIntf>in".rt -> "gotcha",
- "~Top|BlackBoxWithCommonIntf".mt -> "module"
- )
- val (chirrtl, annos) = getFirrtlAndAnnos(new Top)
- for (e <- expected.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
- it("6.3 It should be possible to have Vectors of @instantiable traits mixing concrete subclasses") {
- class Top extends Module {
- val definition = Definition(new ModuleWithCommonIntf("X"))
- val insts: Seq[Definition[ModuleIntf]] = Vector(
- Module(new ModuleWithCommonIntf("Y")).toDefinition,
- Module(new BlackBoxWithCommonIntf).toDefinition,
- definition
- )
- mark(insts(0).io.in, "foo")
- mark(insts(1).io.in, "bar")
- mark(insts(2).io.in, "fizz")
- }
- val expected = List(
- "~Top|ModuleWithCommonIntfY>io.in".rt -> "foo",
- "~Top|BlackBoxWithCommonIntf>in".rt -> "bar",
- "~Top|ModuleWithCommonIntfX>io.in".rt -> "fizz"
- )
- val (chirrtl, annos) = getFirrtlAndAnnos(new Top)
- for (e <- expected.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
- }
- describe("7: @instantiable and @public should compose with DataView") {
- import chisel3.experimental.dataview._
- ignore("7.0: should work on simple Views") {
- @instantiable
- class MyModule extends RawModule {
- val in = IO(Input(UInt(8.W)))
- @public val out = IO(Output(UInt(8.W)))
- val sum = in + 1.U
- out := sum + 1.U
- @public val foo = in.viewAs[UInt]
- @public val bar = sum.viewAs[UInt]
- }
- class Top extends RawModule {
- val foo = IO(Input(UInt(8.W)))
- val bar = IO(Output(UInt(8.W)))
- val d = Definition(new MyModule)
- val i = Instance(d)
- i.foo := foo
- bar := i.out
- mark(d.out, "out")
- mark(d.foo, "foo")
- mark(d.bar, "bar")
- }
- val expectedAnnos = List(
- "~Top|MyModule>out".rt -> "out",
- "~Top|MyModule>in".rt -> "foo",
- "~Top|MyModule>sum".rt -> "bar"
- )
- val expectedLines = List(
- "i.in <= foo",
- "bar <= i.out"
- )
- val (chirrtl, annos) = getFirrtlAndAnnos(new Top)
- val text = chirrtl.serialize
- for (line <- expectedLines) {
- text should include(line)
- }
- for (e <- expectedAnnos.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
- ignore("7.1: should work on Aggregate Views that are mapped 1:1") {
- import chiselTests.experimental.SimpleBundleDataView._
- @instantiable
- class MyModule extends RawModule {
- private val a = IO(Input(new BundleA(8)))
- private val b = IO(Output(new BundleA(8)))
- @public val in = a.viewAs[BundleB]
- @public val out = b.viewAs[BundleB]
- out := in
- }
- class Top extends RawModule {
- val foo = IO(Input(new BundleB(8)))
- val bar = IO(Output(new BundleB(8)))
- val d = Definition(new MyModule)
- val i = Instance(d)
- i.in := foo
- bar.bar := i.out.bar
- mark(d.in, "in")
- mark(d.in.bar, "in_bar")
- }
- val expectedAnnos = List(
- "~Top|MyModule>a".rt -> "in",
- "~Top|MyModule>a.foo".rt -> "in_bar"
- )
- val expectedLines = List(
- "i.a <= foo",
- "bar <= i.b.foo"
- )
- val (chirrtl, annos) = getFirrtlAndAnnos(new Top)
- val text = chirrtl.serialize
- for (line <- expectedLines) {
- text should include(line)
- }
- for (e <- expectedAnnos.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
- }
-}
diff --git a/src/test/scala/chiselTests/experimental/hierarchy/Examples.scala b/src/test/scala/chiselTests/experimental/hierarchy/Examples.scala
deleted file mode 100644
index 27725c49..00000000
--- a/src/test/scala/chiselTests/experimental/hierarchy/Examples.scala
+++ /dev/null
@@ -1,340 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.experimental.hierarchy
-
-import chisel3._
-import chisel3.util.Valid
-import chisel3.experimental.hierarchy._
-import chisel3.experimental.BaseModule
-
-object Examples {
- import Annotations._
- @instantiable
- class AddOne extends Module {
- @public val in = IO(Input(UInt(32.W)))
- @public val out = IO(Output(UInt(32.W)))
- @public val innerWire = Wire(UInt(32.W))
- innerWire := in + 1.U
- out := innerWire
- }
- @instantiable
- class AddOneWithAnnotation extends Module {
- @public val in = IO(Input(UInt(32.W)))
- @public val out = IO(Output(UInt(32.W)))
- @public val innerWire = Wire(UInt(32.W))
- mark(innerWire, "innerWire")
- innerWire := in + 1.U
- out := innerWire
- }
- @instantiable
- class AddOneWithAbsoluteAnnotation extends Module {
- @public val in = IO(Input(UInt(32.W)))
- @public val out = IO(Output(UInt(32.W)))
- @public val innerWire = Wire(UInt(32.W))
- amark(innerWire, "innerWire")
- innerWire := in + 1.U
- out := innerWire
- }
- @instantiable
- class AddOneParameterized(width: Int) extends Module {
- @public val in = IO(Input(UInt(width.W)))
- @public val out = IO(Output(UInt(width.W)))
- out := in + 1.U
- }
- class AddOneWithNested(width: Int) extends Module {
- @public val in = IO(Input(UInt(width.W)))
- @public val out = IO(Output(UInt(width.W)))
- val addOneDef = Seq.fill(3)(Definition(new AddOne))
- out := in + 1.U
- }
- @instantiable
- class AddOneBlackBox extends BlackBox {
- @public val io = IO(new Bundle {
- val in = Input(UInt(32.W))
- val out = Output(UInt(32.W))
- })
- }
-
- @instantiable
- class AddTwo extends Module {
- @public val in = IO(Input(UInt(32.W)))
- @public val out = IO(Output(UInt(32.W)))
- @public val definition = Definition(new AddOne)
- @public val i0: Instance[AddOne] = Instance(definition)
- @public val i1: Instance[AddOne] = Instance(definition)
- i0.in := in
- i1.in := i0.out
- out := i1.out
- }
- @instantiable
- class AddTwoMixedModules extends Module {
- @public val in = IO(Input(UInt(32.W)))
- @public val out = IO(Output(UInt(32.W)))
- val definition = Definition(new AddOne)
- @public val i0: Instance[AddOne] = Instance(definition)
- @public val i1 = Module(new AddOne)
- i0.in := in
- i1.in := i0.out
- out := i1.out
- }
- @instantiable
- class AddTwoParameterized(width: Int, makeParameterizedOnes: Int => Seq[Instance[AddOneParameterized]])
- extends Module {
- val in = IO(Input(UInt(width.W)))
- val out = IO(Output(UInt(width.W)))
- val addOnes = makeParameterizedOnes(width)
- addOnes.head.in := in
- out := addOnes.last.out
- addOnes.zip(addOnes.tail).foreach { case (head, tail) => tail.in := head.out }
- }
- @instantiable
- class AddTwoWithNested(width: Int, makeParameterizedOnes: Int => Seq[Instance[AddOneWithNested]]) extends Module {
- val in = IO(Input(UInt(width.W)))
- val out = IO(Output(UInt(width.W)))
- val addOnes = makeParameterizedOnes(width)
- }
-
- @instantiable
- class AddFour extends Module {
- @public val in = IO(Input(UInt(32.W)))
- @public val out = IO(Output(UInt(32.W)))
- @public val definition = Definition(new AddTwoMixedModules)
- @public val i0 = Instance(definition)
- @public val i1 = Instance(definition)
- i0.in := in
- i1.in := i0.out
- out := i1.out
- }
- @instantiable
- class AggregatePortModule extends Module {
- @public val io = IO(new Bundle {
- val in = Input(UInt(32.W))
- val out = Output(UInt(32.W))
- })
- io.out := io.in
- }
- @instantiable
- class WireContainer {
- @public val innerWire = Wire(UInt(32.W))
- }
- @instantiable
- class AddOneWithInstantiableWire extends Module {
- @public val in = IO(Input(UInt(32.W)))
- @public val out = IO(Output(UInt(32.W)))
- @public val wireContainer = new WireContainer()
- wireContainer.innerWire := in + 1.U
- out := wireContainer.innerWire
- }
- @instantiable
- class AddOneContainer {
- @public val i0 = Module(new AddOne)
- }
- @instantiable
- class AddOneWithInstantiableModule extends Module {
- @public val in = IO(Input(UInt(32.W)))
- @public val out = IO(Output(UInt(32.W)))
- @public val moduleContainer = new AddOneContainer()
- moduleContainer.i0.in := in
- out := moduleContainer.i0.out
- }
- @instantiable
- class AddOneInstanceContainer {
- val definition = Definition(new AddOne)
- @public val i0 = Instance(definition)
- }
- @instantiable
- class AddOneWithInstantiableInstance extends Module {
- @public val in = IO(Input(UInt(32.W)))
- @public val out = IO(Output(UInt(32.W)))
- @public val instanceContainer = new AddOneInstanceContainer()
- instanceContainer.i0.in := in
- out := instanceContainer.i0.out
- }
- @instantiable
- class AddOneContainerContainer {
- @public val container = new AddOneContainer
- }
- @instantiable
- class AddOneWithInstantiableInstantiable extends Module {
- @public val in = IO(Input(UInt(32.W)))
- @public val out = IO(Output(UInt(32.W)))
- @public val containerContainer = new AddOneContainerContainer()
- containerContainer.container.i0.in := in
- out := containerContainer.container.i0.out
- }
- @instantiable
- class Viewer(val y: AddTwo, markPlease: Boolean) {
- @public val x = y
- if (markPlease) mark(x.i0.innerWire, "first")
- }
- @instantiable
- class ViewerParent(val x: AddTwo, markHere: Boolean, markThere: Boolean) extends Module {
- @public val viewer = new Viewer(x, markThere)
- if (markHere) mark(viewer.x.i0.innerWire, "second")
- }
- @instantiable
- class MultiVal() extends Module {
- @public val (x, y) = (Wire(UInt(3.W)), Wire(UInt(3.W)))
- }
- @instantiable
- class LazyVal() extends Module {
- @public val x = Wire(UInt(3.W))
- @public lazy val y = "Hi"
- }
- case class Parameters(string: String, int: Int) extends IsLookupable
- @instantiable
- class UsesParameters(p: Parameters) extends Module {
- @public val y = p
- @public val x = Wire(UInt(3.W))
- }
- @instantiable
- class HasList() extends Module {
- @public val y = List(1, 2, 3)
- @public val x = List.fill(3)(Wire(UInt(3.W)))
- }
- @instantiable
- class HasSeq() extends Module {
- @public val y = Seq(1, 2, 3)
- @public val x = Seq.fill(3)(Wire(UInt(3.W)))
- }
- @instantiable
- class HasOption() extends Module {
- @public val x: Option[UInt] = Some(Wire(UInt(3.W)))
- }
- @instantiable
- class HasEither() extends Module {
- @public val x: Either[Bool, UInt] = Right(Wire(UInt(3.W)).suggestName("x"))
- @public val y: Either[Bool, UInt] = Left(Wire(Bool()).suggestName("y"))
- }
- @instantiable
- class HasTuple2() extends Module {
- val x = Wire(UInt(3.W))
- val y = Wire(Bool())
- @public val xy = (x, y)
- }
- @instantiable
- class HasVec() extends Module {
- @public val x = VecInit(1.U, 2.U, 3.U)
- }
- @instantiable
- class HasIndexedVec() extends Module {
- val x = VecInit(1.U, 2.U, 3.U)
- @public val y = x(1)
- }
- @instantiable
- class HasSubFieldAccess extends Module {
- val in = IO(Input(Valid(UInt(8.W))))
- @public val valid = in.valid
- @public val bits = in.bits
- }
- @instantiable
- class HasPublicConstructorArgs(@public val int: Int) extends Module {
- @public val x = Wire(UInt(3.W))
- }
- @instantiable
- class InstantiatesHasVec() extends Module {
- @public val i0 = Instance(Definition(new HasVec()))
- @public val i1 = Module(new HasVec())
- }
- @instantiable
- class HasUninferredReset() extends Module {
- @public val in = IO(Input(UInt(3.W)))
- @public val out = IO(Output(UInt(3.W)))
- out := RegNext(in)
- }
- @instantiable
- abstract class HasBlah() extends Module {
- @public val blah: Int
- }
-
- @instantiable
- class ConcreteHasBlah() extends HasBlah {
- val blah = 10
- }
- @instantiable
- class HasTypeParams[D <: Data](d: D) extends Module {
- @public val blah = Wire(d)
- }
-
- @instantiable
- class HasMultipleTypeParamsInside extends Module {
- val tpDef0 = Definition(new HasTypeParams(Bool()))
- val tpDef1 = Definition(new HasTypeParams(UInt(4.W)))
- val i00 = Instance(tpDef0)
- val i01 = Instance(tpDef0)
- val i10 = Instance(tpDef1)
- val i11 = Instance(tpDef1)
- }
-
- @instantiable
- class HasMems() extends Module {
- @public val mem = Mem(8, UInt(32.W))
- @public val syncReadMem = SyncReadMem(8, UInt(32.W))
- }
-
- @instantiable
- class LeafInstantiable(val bundle: Data) {
- @public val bundle = bundle
- }
-
- @instantiable
- class NestedInstantiable(val in: LeafInstantiable, val out: LeafInstantiable) {
- @public val in = in
- @public val out = out
- }
-
- @instantiable
- class AddOneNestedInstantiableData(width: Int) extends Module {
- @public val in = IO(Input(UInt(width.W)))
- @public val out = IO(Output(UInt(width.W)))
- out := in + 1.U
-
- @public val leafOut = new LeafInstantiable(out)
- @public val leafIn = new LeafInstantiable(in)
- @public val nested = new NestedInstantiable(in = leafIn, out = leafOut)
-
- }
-
- class AddTwoNestedInstantiableData(width: Int) extends Module {
- val in = IO(Input(UInt(width.W)))
- val out = IO(Output(UInt(width.W)))
- val addOneDef = Definition(new AddOneNestedInstantiableData(width))
- val i0 = Instance(addOneDef)
- val i1 = Instance(addOneDef)
- i0.in := in
- i1.in := i0.out
- out := i1.out
-
- // both are equivalent to the above
- i1.leafIn.bundle := i0.leafOut.bundle
- i1.nested.in.bundle := i0.nested.out.bundle
- }
-
- class AddTwoNestedInstantiableDataSubmodule(addOneDef: Definition[AddOneNestedInstantiableData]) extends Module {
- val in = IO(Input(UInt(addOneDef.in.getWidth.W)))
- val out = IO(Output(UInt(addOneDef.out.getWidth.W)))
- val i0 = Instance(addOneDef)
- val i1 = Instance(addOneDef)
- i0.in := in
- i1.in := i0.out
- out := i1.out
-
- // both are equivalent to the above
- i1.leafIn.bundle := i0.leafOut.bundle
- i1.nested.in.bundle := i0.nested.out.bundle
- }
-
- class AddTwoNestedInstantiableDataWrapper(width: Int) extends Module {
- val in = IO(Input(UInt(width.W)))
- val out = IO(Output(UInt(width.W)))
-
- val original = Module(new AddOneNestedInstantiableData(width))
- val copy = Module(new AddTwoNestedInstantiableDataSubmodule(original.toDefinition))
-
- original.in := in
- copy.in := original.out
- out := copy.out
-
- }
-
-}
diff --git a/src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala b/src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala
deleted file mode 100644
index 6596cd51..00000000
--- a/src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala
+++ /dev/null
@@ -1,1146 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-package experimental.hierarchy
-
-import chisel3._
-import chisel3.experimental.BaseModule
-import chisel3.experimental.hierarchy.{instantiable, public, Definition, Instance}
-import chisel3.util.{DecoupledIO, Valid}
-
-// TODO/Notes
-// - In backport, clock/reset are not automatically assigned. I think this is fixed in 3.5
-// - CircuitTarget for annotations on the definition are wrong - needs to be fixed.
-class InstanceSpec extends ChiselFunSpec with Utils {
- import Annotations._
- import Examples._
- describe("0: Instance instantiation") {
- it("0.0: name of an instance should be correct") {
- class Top extends Module {
- val definition = Definition(new AddOne)
- val i0 = Instance(definition)
- }
- val (chirrtl, _) = getFirrtlAndAnnos(new Top)
- chirrtl.serialize should include("inst i0 of AddOne")
- }
- it("0.1: name of an instanceclone should not error") {
- class Top extends Module {
- val definition = Definition(new AddTwo)
- val i0 = Instance(definition)
- val i = i0.i0 // This should not error
- }
- val (chirrtl, _) = getFirrtlAndAnnos(new Top)
- chirrtl.serialize should include("inst i0 of AddTwo")
- }
- it("0.2: accessing internal fields through non-generated means is hard to do") {
- class Top extends Module {
- val definition = Definition(new AddOne)
- val i0 = Instance(definition)
- //i0.lookup(_.in) // Uncommenting this line will give the following error:
- //"You are trying to access a macro-only API. Please use the @public annotation instead."
- i0.in
- }
- val (chirrtl, _) = getFirrtlAndAnnos(new Top)
- chirrtl.serialize should include("inst i0 of AddOne")
- }
- it("0.3: BlackBoxes should be supported") {
- class Top extends Module {
- val in = IO(Input(UInt(32.W)))
- val out = IO(Output(UInt(32.W)))
- val io = IO(new Bundle {
- val in = Input(UInt(32.W))
- val out = Output(UInt(32.W))
- })
- val definition = Definition(new AddOneBlackBox)
- val i0 = Instance(definition)
- val i1 = Instance(definition)
- i0.io.in := in
- out := i0.io.out
- io <> i1.io
- }
- val chirrtl = getFirrtlAndAnnos(new Top)._1.serialize
- chirrtl should include("inst i0 of AddOneBlackBox")
- chirrtl should include("inst i1 of AddOneBlackBox")
- chirrtl should include("i0.in <= in")
- chirrtl should include("out <= i0.out")
- chirrtl should include("i1.in <= io.in")
- chirrtl should include("io.out <= i1.out")
- }
- }
- describe("1: Annotations on instances in same chisel compilation") {
- it("1.0: should work on a single instance, annotating the instance") {
- class Top extends Module {
- val definition: Definition[AddOne] = Definition(new AddOne)
- val i0: Instance[AddOne] = Instance(definition)
- mark(i0, "i0")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i0:AddOne".it, "i0"))
- }
- it("1.1: should work on a single instance, annotating an inner wire") {
- class Top extends Module {
- val definition: Definition[AddOne] = Definition(new AddOne)
- val i0: Instance[AddOne] = Instance(definition)
- mark(i0.innerWire, "i0.innerWire")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i0:AddOne>innerWire".rt, "i0.innerWire"))
- }
- it("1.2: should work on a two nested instances, annotating the instance") {
- class Top extends Module {
- val definition: Definition[AddTwo] = Definition(new AddTwo)
- val i0: Instance[AddTwo] = Instance(definition)
- mark(i0.i0, "i0.i0")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i0:AddTwo/i0:AddOne".it, "i0.i0"))
- }
- it("1.3: should work on a two nested instances, annotating the inner wire") {
- class Top extends Module {
- val definition: Definition[AddTwo] = Definition(new AddTwo)
- val i0: Instance[AddTwo] = Instance(definition)
- mark(i0.i0.innerWire, "i0.i0.innerWire")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i0:AddTwo/i0:AddOne>innerWire".rt, "i0.i0.innerWire"))
- }
- it("1.4: should work on a nested module in an instance, annotating the module") {
- class Top extends Module {
- val definition: Definition[AddTwoMixedModules] = Definition(new AddTwoMixedModules)
- val i0: Instance[AddTwoMixedModules] = Instance(definition)
- mark(i0.i1, "i0.i1")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i0:AddTwoMixedModules/i1:AddOne_1".it, "i0.i1"))
- }
- it("1.5: should work on an instantiable container, annotating a wire") {
- class Top extends Module {
- val definition: Definition[AddOneWithInstantiableWire] = Definition(new AddOneWithInstantiableWire)
- val i0: Instance[AddOneWithInstantiableWire] = Instance(definition)
- mark(i0.wireContainer.innerWire, "i0.innerWire")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i0:AddOneWithInstantiableWire>innerWire".rt, "i0.innerWire"))
- }
- it("1.6: should work on an instantiable container, annotating a module") {
- class Top extends Module {
- val definition = Definition(new AddOneWithInstantiableModule)
- val i0 = Instance(definition)
- mark(i0.moduleContainer.i0, "i0.i0")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i0:AddOneWithInstantiableModule/i0:AddOne".it, "i0.i0"))
- }
- it("1.7: should work on an instantiable container, annotating an instance") {
- class Top extends Module {
- val definition = Definition(new AddOneWithInstantiableInstance)
- val i0 = Instance(definition)
- mark(i0.instanceContainer.i0, "i0.i0")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i0:AddOneWithInstantiableInstance/i0:AddOne".it, "i0.i0"))
- }
- it("1.8: should work on an instantiable container, annotating an instantiable container's module") {
- class Top extends Module {
- val definition = Definition(new AddOneWithInstantiableInstantiable)
- val i0 = Instance(definition)
- mark(i0.containerContainer.container.i0, "i0.i0")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i0:AddOneWithInstantiableInstantiable/i0:AddOne".it, "i0.i0"))
- }
- it("1.9: should work on public member which references public member of another instance") {
- class Top extends Module {
- val definition = Definition(new AddOneWithInstantiableInstantiable)
- val i0 = Instance(definition)
- mark(i0.containerContainer.container.i0, "i0.i0")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i0:AddOneWithInstantiableInstantiable/i0:AddOne".it, "i0.i0"))
- }
- it("1.10: should work for targets on definition to have correct circuit name") {
- class Top extends Module {
- val definition = Definition(new AddOneWithAnnotation)
- val i0 = Instance(definition)
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddOneWithAnnotation>innerWire".rt, "innerWire"))
- }
- it("1.11: should work on things with type parameters") {
- class Top extends Module {
- val definition = Definition(new HasTypeParams[UInt](UInt(3.W)))
- val i0 = Instance(definition)
- mark(i0.blah, "blah")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i0:HasTypeParams>blah".rt, "blah"))
- }
- }
- describe("2: Annotations on designs not in the same chisel compilation") {
- it("2.0: should work on an innerWire, marked in a different compilation") {
- val first = elaborateAndGetModule(new AddTwo)
- class Top(x: AddTwo) extends Module {
- val parent = Instance(Definition(new ViewerParent(x, false, true)))
- }
- val (_, annos) = getFirrtlAndAnnos(new Top(first))
- annos should contain(MarkAnnotation("~AddTwo|AddTwo/i0:AddOne>innerWire".rt, "first"))
- }
- it("2.1: should work on an innerWire, marked in a different compilation, in instanced instantiable") {
- val first = elaborateAndGetModule(new AddTwo)
- class Top(x: AddTwo) extends Module {
- val parent = Instance(Definition(new ViewerParent(x, true, false)))
- }
- val (_, annos) = getFirrtlAndAnnos(new Top(first))
- annos should contain(MarkAnnotation("~AddTwo|AddTwo/i0:AddOne>innerWire".rt, "second"))
- }
- it("2.2: should work on an innerWire, marked in a different compilation, in instanced module") {
- val first = elaborateAndGetModule(new AddTwo)
- class Top(x: AddTwo) extends Module {
- val parent = Instance(Definition(new ViewerParent(x, false, false)))
- mark(parent.viewer.x.i0.innerWire, "third")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top(first))
- annos should contain(MarkAnnotation("~AddTwo|AddTwo/i0:AddOne>innerWire".rt, "third"))
- }
- }
- describe("3: @public") {
- it("3.0: should work on multi-vals") {
- class Top() extends Module {
- val mv = Instance(Definition(new MultiVal()))
- mark(mv.x, "mv.x")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/mv:MultiVal>x".rt, "mv.x"))
- }
- it("3.1: should work on lazy vals") {
- class Top() extends Module {
- val lv = Instance(Definition(new LazyVal()))
- mark(lv.x, lv.y)
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/lv:LazyVal>x".rt, "Hi"))
- }
- it("3.2: should work on islookupables") {
- class Top() extends Module {
- val p = Parameters("hi", 0)
- val up = Instance(Definition(new UsesParameters(p)))
- mark(up.x, up.y.string + up.y.int)
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/up:UsesParameters>x".rt, "hi0"))
- }
- it("3.3: should work on lists") {
- class Top() extends Module {
- val i = Instance(Definition(new HasList()))
- mark(i.x(1), i.y(1).toString)
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:HasList>x_1".rt, "2"))
- }
- it("3.4: should work on seqs") {
- class Top() extends Module {
- val i = Instance(Definition(new HasSeq()))
- mark(i.x(1), i.y(1).toString)
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:HasSeq>x_1".rt, "2"))
- }
- it("3.5: should work on options") {
- class Top() extends Module {
- val i = Instance(Definition(new HasOption()))
- i.x.map(x => mark(x, "x"))
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:HasOption>x".rt, "x"))
- }
- it("3.6: should work on vecs") {
- class Top() extends Module {
- val i = Instance(Definition(new HasVec()))
- mark(i.x, "blah")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:HasVec>x".rt, "blah"))
- }
- it("3.7: should work on statically indexed vectors external to module") {
- class Top() extends Module {
- val i = Instance(Definition(new HasVec()))
- mark(i.x(1), "blah")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:HasVec>x[1]".rt, "blah"))
- }
- it("3.8: should work on statically indexed vectors internal to module") {
- class Top() extends Module {
- val i = Instance(Definition(new HasIndexedVec()))
- mark(i.y, "blah")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:HasIndexedVec>x[1]".rt, "blah"))
- }
- it("3.9: should work on accessed subfields of aggregate ports") {
- class Top extends Module {
- val input = IO(Input(Valid(UInt(8.W))))
- val i = Instance(Definition(new HasSubFieldAccess))
- i.valid := input.valid
- i.bits := input.bits
- mark(i.valid, "valid")
- mark(i.bits, "bits")
- }
- val expected = List(
- "~Top|Top/i:HasSubFieldAccess>in.valid".rt -> "valid",
- "~Top|Top/i:HasSubFieldAccess>in.bits".rt -> "bits"
- )
- val lines = List(
- "i.in.valid <= input.valid",
- "i.in.bits <= input.bits"
- )
- val (chirrtl, annos) = getFirrtlAndAnnos(new Top)
- val text = chirrtl.serialize
- for (line <- lines) {
- text should include(line)
- }
- for (e <- expected.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
- ignore("3.10: should work on vals in constructor arguments") {
- class Top() extends Module {
- val i = Instance(Definition(new HasPublicConstructorArgs(10)))
- //mark(i.x, i.int.toString)
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:HasPublicConstructorArgs>x".rt, "10"))
- }
- it("3.11: should work on eithers") {
- class Top() extends Module {
- val i = Instance(Definition(new HasEither()))
- i.x.map(x => mark(x, "xright")).left.map(x => mark(x, "xleft"))
- i.y.map(x => mark(x, "yright")).left.map(x => mark(x, "yleft"))
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:HasEither>x".rt, "xright"))
- annos should contain(MarkAnnotation("~Top|Top/i:HasEither>y".rt, "yleft"))
- }
- it("3.12: should work on tuple2") {
- class Top() extends Module {
- val i = Instance(Definition(new HasTuple2()))
- mark(i.xy._1, "x")
- mark(i.xy._2, "y")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:HasTuple2>x".rt, "x"))
- annos should contain(MarkAnnotation("~Top|Top/i:HasTuple2>y".rt, "y"))
- }
-
- it("3.13: should properly support val modifiers") {
- class SupClass extends Module {
- val value = 10
- val overriddenVal = 10
- }
- trait SupTrait {
- def x: Int
- def y: Int
- }
- @instantiable class SubClass() extends SupClass with SupTrait {
- // This errors
- //@public private val privateVal = 10
- // This errors
- //@public protected val protectedVal = 10
- @public override val overriddenVal = 12
- @public final val finalVal = 12
- @public lazy val lazyValue = 12
- @public val value = value
- @public final override lazy val x: Int = 3
- @public override final lazy val y: Int = 4
- }
- }
- it("3.13: should work with Mems/SyncReadMems") {
- class Top() extends Module {
- val i = Instance(Definition(new HasMems()))
- mark(i.mem, "Mem")
- mark(i.syncReadMem, "SyncReadMem")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:HasMems>mem".rt, "Mem"))
- annos should contain(MarkAnnotation("~Top|Top/i:HasMems>syncReadMem".rt, "SyncReadMem"))
- }
- it("(3.p): should make connectable IOs on nested IsInstantiables that have IO Datas in them") {
- val (chirrtl, _) = getFirrtlAndAnnos(new AddTwoNestedInstantiableData(4))
- exactly(3, chirrtl.serialize.split('\n')) should include("i1.in <= i0.out")
- }
- it(
- "(3.q): should make connectable IOs on nested IsInstantiables's Data when the Instance and Definition do not have the same parent"
- ) {
- val (chirrtl, _) = getFirrtlAndAnnos(new AddTwoNestedInstantiableDataWrapper(4))
- exactly(3, chirrtl.serialize.split('\n')) should include("i1.in <= i0.out")
- }
- }
- describe("4: toInstance") {
- it("4.0: should work on modules") {
- class Top() extends Module {
- val i = Module(new AddOne())
- f(i.toInstance)
- }
- def f(i: Instance[AddOne]): Unit = mark(i.innerWire, "blah")
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddOne>innerWire".rt, "blah"))
- }
- it("4.1: should work on isinstantiables") {
- class Top() extends Module {
- val i = Module(new AddTwo())
- val v = new Viewer(i, false)
- mark(f(v.toInstance), "blah")
- }
- def f(i: Instance[Viewer]): Data = i.x.i0.innerWire
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddTwo/i0:AddOne>innerWire".rt, "blah"))
- }
- it("4.2: should work on seqs of modules") {
- class Top() extends Module {
- val is = Seq(Module(new AddTwo()), Module(new AddTwo())).map(_.toInstance)
- mark(f(is), "blah")
- }
- def f(i: Seq[Instance[AddTwo]]): Data = i.head.i0.innerWire
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddTwo/i0:AddOne>innerWire".rt, "blah"))
- }
- it("4.3: should work on seqs of isInstantiables") {
- class Top() extends Module {
- val i = Module(new AddTwo())
- val vs = Seq(new Viewer(i, false), new Viewer(i, false)).map(_.toInstance)
- mark(f(vs), "blah")
- }
- def f(i: Seq[Instance[Viewer]]): Data = i.head.x.i0.innerWire
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddTwo/i0:AddOne>innerWire".rt, "blah"))
- }
- it("4.2: should work on options of modules") {
- class Top() extends Module {
- val is: Option[Instance[AddTwo]] = Some(Module(new AddTwo())).map(_.toInstance)
- mark(f(is), "blah")
- }
- def f(i: Option[Instance[AddTwo]]): Data = i.get.i0.innerWire
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddTwo/i0:AddOne>innerWire".rt, "blah"))
- }
- }
- describe("5: Absolute Targets should work as expected") {
- it("5.0: toAbsoluteTarget on a port of an instance") {
- class Top() extends Module {
- val i = Instance(Definition(new AddTwo()))
- amark(i.in, "blah")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:AddTwo>in".rt, "blah"))
- }
- it("5.1: toAbsoluteTarget on a subinstance's data within an instance") {
- class Top() extends Module {
- val i = Instance(Definition(new AddTwo()))
- amark(i.i0.innerWire, "blah")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:AddTwo/i0:AddOne>innerWire".rt, "blah"))
- }
- it("5.2: toAbsoluteTarget on a submodule's data within an instance") {
- class Top() extends Module {
- val i = Instance(Definition(new AddTwoMixedModules()))
- amark(i.i1.in, "blah")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:AddTwoMixedModules/i1:AddOne_1>in".rt, "blah"))
- }
- it("5.3: toAbsoluteTarget on a submodule's data, in an aggregate, within an instance") {
- class Top() extends Module {
- val i = Instance(Definition(new InstantiatesHasVec()))
- amark(i.i1.x.head, "blah")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:InstantiatesHasVec/i1:HasVec_1>x[0]".rt, "blah"))
- }
- it("5.4: toAbsoluteTarget on a submodule's data, in an aggregate, within an instance, ILit") {
- class MyBundle extends Bundle { val x = UInt(3.W) }
- @instantiable
- class HasVec() extends Module {
- @public val x = Wire(Vec(3, new MyBundle()))
- }
- @instantiable
- class InstantiatesHasVec() extends Module {
- @public val i0 = Instance(Definition(new HasVec()))
- @public val i1 = Module(new HasVec())
- }
- class Top() extends Module {
- val i = Instance(Definition(new InstantiatesHasVec()))
- amark(i.i1.x.head.x, "blah")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:InstantiatesHasVec/i1:HasVec_1>x[0].x".rt, "blah"))
- }
- it("5.5: toAbsoluteTarget on a subinstance") {
- class Top() extends Module {
- val i = Instance(Definition(new AddTwo()))
- amark(i.i1, "blah")
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:AddTwo/i1:AddOne".it, "blah"))
- }
- it("5.6: should work for absolute targets on definition to have correct circuit name") {
- class Top extends Module {
- val definition = Definition(new AddOneWithAbsoluteAnnotation)
- val i0 = Instance(definition)
- }
- val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddOneWithAbsoluteAnnotation>innerWire".rt, "innerWire"))
- }
- }
- describe("6: @instantiable traits should work as expected") {
- class MyBundle extends Bundle {
- val in = Input(UInt(8.W))
- val out = Output(UInt(8.W))
- }
- @instantiable
- trait ModuleIntf extends BaseModule {
- @public val io = IO(new MyBundle)
- }
- @instantiable
- class ModuleWithCommonIntf(suffix: String = "") extends Module with ModuleIntf {
- override def desiredName: String = super.desiredName + suffix
- @public val sum = io.in + 1.U
-
- io.out := sum
- }
- class BlackBoxWithCommonIntf extends BlackBox with ModuleIntf
-
- it("6.0: A Module that implements an @instantiable trait should be instantiable as that trait") {
- class Top extends Module {
- val i: Instance[ModuleIntf] = Instance(Definition(new ModuleWithCommonIntf))
- mark(i.io.in, "gotcha")
- mark(i, "inst")
- }
- val expected = List(
- "~Top|Top/i:ModuleWithCommonIntf>io.in".rt -> "gotcha",
- "~Top|Top/i:ModuleWithCommonIntf".it -> "inst"
- )
- val (chirrtl, annos) = getFirrtlAndAnnos(new Top)
- for (e <- expected.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
- it(
- "6.1 An @instantiable Module that implements an @instantiable trait should be able to use extension methods from both"
- ) {
- class Top extends Module {
- val i: Instance[ModuleWithCommonIntf] = Instance(Definition(new ModuleWithCommonIntf))
- mark(i.io.in, "gotcha")
- mark(i.sum, "also this")
- mark(i, "inst")
- }
- val expected = List(
- "~Top|Top/i:ModuleWithCommonIntf>io.in".rt -> "gotcha",
- "~Top|Top/i:ModuleWithCommonIntf>sum".rt -> "also this",
- "~Top|Top/i:ModuleWithCommonIntf".it -> "inst"
- )
- val (chirrtl, annos) = getFirrtlAndAnnos(new Top)
- for (e <- expected.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
- it("6.2 A BlackBox that implements an @instantiable trait should be instantiable as that trait") {
- class Top extends Module {
- val i: Instance[ModuleIntf] = Module(new BlackBoxWithCommonIntf).toInstance
- mark(i.io.in, "gotcha")
- mark(i, "module")
- }
- val expected = List(
- "~Top|BlackBoxWithCommonIntf>in".rt -> "gotcha",
- "~Top|BlackBoxWithCommonIntf".mt -> "module"
- )
- val (chirrtl, annos) = getFirrtlAndAnnos(new Top)
- for (e <- expected.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
- it("6.3 It should be possible to have Vectors of @instantiable traits mixing concrete subclasses") {
- class Top extends Module {
- val proto = Definition(new ModuleWithCommonIntf("X"))
- val insts: Seq[Instance[ModuleIntf]] = Vector(
- Module(new ModuleWithCommonIntf("Y")).toInstance,
- Module(new BlackBoxWithCommonIntf).toInstance,
- Instance(proto)
- )
- mark(insts(0).io.in, "foo")
- mark(insts(1).io.in, "bar")
- mark(insts(2).io.in, "fizz")
- }
- val expected = List(
- "~Top|ModuleWithCommonIntfY>io.in".rt -> "foo",
- "~Top|BlackBoxWithCommonIntf>in".rt -> "bar",
- "~Top|Top/insts_2:ModuleWithCommonIntfX>io.in".rt -> "fizz"
- )
- val (chirrtl, annos) = getFirrtlAndAnnos(new Top)
- for (e <- expected.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
- }
- // TODO don't forget to test this with heterogeneous Views (eg. viewing a tuple of a port and non-port as a single Bundle)
- describe("7: @instantiable and @public should compose with DataView") {
- import chisel3.experimental.dataview._
- it("7.0: should work on simple Views") {
- @instantiable
- class MyModule extends RawModule {
- val in = IO(Input(UInt(8.W)))
- @public val out = IO(Output(UInt(8.W)))
- val sum = in + 1.U
- out := sum + 1.U
- @public val foo = in.viewAs[UInt]
- @public val bar = sum.viewAs[UInt]
- }
- class Top extends RawModule {
- val foo = IO(Input(UInt(8.W)))
- val bar = IO(Output(UInt(8.W)))
- val i = Instance(Definition(new MyModule))
- i.foo := foo
- bar := i.out
- mark(i.out, "out")
- mark(i.foo, "foo")
- mark(i.bar, "bar")
- }
- val expectedAnnos = List(
- "~Top|Top/i:MyModule>out".rt -> "out",
- "~Top|Top/i:MyModule>in".rt -> "foo",
- "~Top|Top/i:MyModule>sum".rt -> "bar"
- )
- val expectedLines = List(
- "i.in <= foo",
- "bar <= i.out"
- )
- val (chirrtl, annos) = getFirrtlAndAnnos(new Top)
- val text = chirrtl.serialize
- for (line <- expectedLines) {
- text should include(line)
- }
- for (e <- expectedAnnos.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
-
- ignore("7.1: should work on Aggregate Views") {
- import chiselTests.experimental.FlatDecoupledDataView._
- type RegDecoupled = DecoupledIO[FizzBuzz]
- @instantiable
- class MyModule extends RawModule {
- private val a = IO(Flipped(new FlatDecoupled))
- private val b = IO(new FlatDecoupled)
- @public val enq = a.viewAs[RegDecoupled]
- @public val deq = b.viewAs[RegDecoupled]
- @public val enq_valid = enq.valid // Also return a subset of the view
- deq <> enq
- }
- class Top extends RawModule {
- val foo = IO(Flipped(new RegDecoupled(new FizzBuzz)))
- val bar = IO(new RegDecoupled(new FizzBuzz))
- val i = Instance(Definition(new MyModule))
- i.enq <> foo
- i.enq_valid := foo.valid // Make sure connections also work for @public on elements of a larger Aggregate
- i.deq.ready := bar.ready
- bar.valid := i.deq.valid
- bar.bits := i.deq.bits
- mark(i.enq, "enq")
- mark(i.enq.bits, "enq.bits")
- mark(i.deq.bits.fizz, "deq.bits.fizz")
- mark(i.enq_valid, "enq_valid")
- }
- val expectedAnnos = List(
- "~Top|Top/i:MyModule>a".rt -> "enq", // Not split, checks 1:1
- "~Top|Top/i:MyModule>a.fizz".rt -> "enq.bits", // Split, checks non-1:1 inner Aggregate
- "~Top|Top/i:MyModule>a.buzz".rt -> "enq.bits",
- "~Top|Top/i:MyModule>b.fizz".rt -> "deq.bits.fizz", // Checks 1 inner Element
- "~Top|Top/i:MyModule>a.valid".rt -> "enq_valid"
- )
- val expectedLines = List(
- "i.a.valid <= foo.valid",
- "foo.ready <= i.a.ready",
- "i.a.fizz <= foo.bits.fizz",
- "i.a.buzz <= foo.bits.buzz",
- "bar.valid <= i.b.valid",
- "i.b.ready <= bar.ready",
- "bar.bits.fizz <= i.b.fizz",
- "bar.bits.buzz <= i.b.buzz"
- )
- val (chirrtl, annos) = getFirrtlAndAnnos(new Top)
- val text = chirrtl.serialize
- for (line <- expectedLines) {
- text should include(line)
- }
- for (e <- expectedAnnos.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
-
- it("7.2: should work on views of views") {
- import chiselTests.experimental.SimpleBundleDataView._
- @instantiable
- class MyModule extends RawModule {
- private val a = IO(Input(UInt(8.W)))
- private val b = IO(Output(new BundleA(8)))
- @public val in = a.viewAs[UInt].viewAs[UInt]
- @public val out = b.viewAs[BundleB].viewAs[BundleA].viewAs[BundleB]
- out.bar := in
- }
- class Top extends RawModule {
- val foo = IO(Input(UInt(8.W)))
- val bar = IO(Output(new BundleB(8)))
- val i = Instance(Definition(new MyModule))
- i.in := foo
- bar := i.out
- bar.bar := i.out.bar
- mark(i.in, "in")
- mark(i.out.bar, "out_bar")
- }
- val expected = List(
- "~Top|Top/i:MyModule>a".rt -> "in",
- "~Top|Top/i:MyModule>b.foo".rt -> "out_bar"
- )
- val lines = List(
- "i.a <= foo",
- "bar.bar <= i.b.foo"
- )
- val (chirrtl, annos) = getFirrtlAndAnnos(new Top)
- val text = chirrtl.serialize
- for (line <- lines) {
- text should include(line)
- }
- for (e <- expected.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
-
- it("7.3: should work with DataView + implicit conversion") {
- import chisel3.experimental.conversions._
- @instantiable
- class MyModule extends RawModule {
- private val a = IO(Input(UInt(8.W)))
- private val b = IO(Output(UInt(8.W)))
- @public val ports = Seq(a, b)
- b := a
- }
- class Top extends RawModule {
- val foo = IO(Input(UInt(8.W)))
- val bar = IO(Output(UInt(8.W)))
- val i = Instance(Definition(new MyModule))
- i.ports <> Seq(foo, bar)
- mark(i.ports, "i.ports")
- }
- val expected = List(
- // Not 1:1 so will get split out
- "~Top|Top/i:MyModule>a".rt -> "i.ports",
- "~Top|Top/i:MyModule>b".rt -> "i.ports"
- )
- val lines = List(
- "i.a <= foo",
- "bar <= i.b"
- )
- val (chirrtl, annos) = getFirrtlAndAnnos(new Top)
- val text = chirrtl.serialize
- for (line <- lines) {
- text should include(line)
- }
- for (e <- expected.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
-
- it("7.4: should work on Views of BlackBoxes") {
- @instantiable
- class MyBlackBox extends BlackBox {
- @public val io = IO(new Bundle {
- val in = Input(UInt(8.W))
- val out = Output(UInt(8.W))
- })
- @public val innerView = io.viewAs
- @public val foo = io.in.viewAs[UInt]
- @public val bar = io.out.viewAs[UInt]
- }
- class Top extends RawModule {
- val foo = IO(Input(UInt(8.W)))
- val bar = IO(Output(UInt(8.W)))
- val i = Instance(Definition(new MyBlackBox))
- val outerView = i.io.viewAs
- i.foo := foo
- bar := i.bar
- mark(i.foo, "i.foo")
- mark(i.bar, "i.bar")
- mark(i.innerView.in, "i.innerView.in")
- mark(outerView.out, "outerView.out")
- }
- val inst = "~Top|Top/i:MyBlackBox"
- val expectedAnnos = List(
- s"$inst>in".rt -> "i.foo",
- s"$inst>out".rt -> "i.bar",
- s"$inst>in".rt -> "i.innerView.in",
- s"$inst>out".rt -> "outerView.out"
- )
- val expectedLines = List(
- "i.in <= foo",
- "bar <= i.out"
- )
- val (chirrtl, annos) = getFirrtlAndAnnos(new Top)
- val text = chirrtl.serialize
- for (line <- expectedLines) {
- text should include(line)
- }
- for (e <- expectedAnnos.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
-
- }
-
- describe("8: @instantiable and @public should compose with CloneModuleAsRecord") {
- it("8.0: it should support @public on a CMAR Record in Definitions") {
- @instantiable
- class HasCMAR extends Module {
- @public val in = IO(Input(UInt(8.W)))
- @public val out = IO(Output(UInt(8.W)))
- @public val m = Module(new AggregatePortModule)
- @public val c = experimental.CloneModuleAsRecord(m)
- }
- class Top extends Module {
- val d = Definition(new HasCMAR)
- mark(d.c("io"), "c.io")
- val bun = d.c("io").asInstanceOf[Record]
- mark(bun.elements("out"), "c.io.out")
- }
- val expected = List(
- "~Top|HasCMAR/c:AggregatePortModule>io".rt -> "c.io",
- "~Top|HasCMAR/c:AggregatePortModule>io.out".rt -> "c.io.out"
- )
- val (_, annos) = getFirrtlAndAnnos(new Top)
- for (e <- expected.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
- it("8.1: it should support @public on a CMAR Record in Instances") {
- @instantiable
- class HasCMAR extends Module {
- @public val in = IO(Input(UInt(8.W)))
- @public val out = IO(Output(UInt(8.W)))
- @public val m = Module(new AggregatePortModule)
- @public val c = experimental.CloneModuleAsRecord(m)
- }
- class Top extends Module {
- val i = Instance(Definition(new HasCMAR))
- mark(i.c("io"), "i.c.io")
- val bun = i.c("io").asInstanceOf[Record]
- mark(bun.elements("out"), "i.c.io.out")
- }
- val expected = List(
- "~Top|Top/i:HasCMAR/c:AggregatePortModule>io".rt -> "i.c.io",
- "~Top|Top/i:HasCMAR/c:AggregatePortModule>io.out".rt -> "i.c.io.out"
- )
- val (_, annos) = getFirrtlAndAnnos(new Top)
- for (e <- expected.map(MarkAnnotation.tupled)) {
- annos should contain(e)
- }
- }
- }
- describe("9: isA[..]") {
- it("9.0: it should work on simple classes") {
- class Top extends Module {
- val d = Definition(new AddOne)
- require(d.isA[AddOne])
- }
- getFirrtlAndAnnos(new Top)
- }
- it("9.1: it should not work on inner classes") {
- class InnerClass extends Module
- class Top extends Module {
- val d = Definition(new InnerClass)
- "require(d.isA[Module])" should compile // ensures that the test below is checking something useful
- "require(d.isA[InnerClass])" shouldNot compile
- }
- getFirrtlAndAnnos(new Top)
- }
- it("9.2: it should work on super classes") {
- class InnerClass extends Module
- class Top extends Module {
- val d = Definition(new InnerClass)
- require(d.isA[Module])
- }
- getFirrtlAndAnnos(new Top)
- }
- it("9.2: it should work after casts") {
- class Top extends Module {
- val d0: Definition[Module] = Definition(new AddOne)
- require(d0.isA[AddOne])
- val d1: Definition[Module] = Definition((new AddOne).asInstanceOf[Module])
- require(d1.isA[AddOne])
- val i0: Instance[Module] = Instance(d0)
- require(i0.isA[AddOne])
- val i1: Instance[Module] = Instance(d1)
- require(i1.isA[AddOne])
- val i2: Instance[Module] = Instance(Definition(new AddOne))
- require(i2.isA[AddOne])
- }
- getFirrtlAndAnnos(new Top)
- }
- it("9.3 it should ignore type parameters (even though it would be nice if it didn't)") {
- class Top extends Module {
- val d0: Definition[Module] = Definition(new HasTypeParams(Bool()))
- require(d0.isA[HasTypeParams[Bool]])
- require(d0.isA[HasTypeParams[_]])
- require(d0.isA[HasTypeParams[UInt]])
- require(!d0.isA[HasBlah])
- }
- getFirrtlAndAnnos(new Top)
- }
- }
- describe("10: Select APIs") {
- it("10.0: instancesOf") {
- val aspect = aop.inspecting.InspectingAspect({ m: AddTwoMixedModules =>
- val targets = aop.Select.instancesOf[AddOne](m.toDefinition).map { i: Instance[AddOne] => i.toTarget }
- targets should be(
- Seq(
- "~AddTwoMixedModules|AddTwoMixedModules/i0:AddOne".it,
- "~AddTwoMixedModules|AddTwoMixedModules/i1:AddOne_1".it
- )
- )
- })
- getFirrtlAndAnnos(new AddTwoMixedModules, Seq(aspect))
- }
- it("10.1: instancesIn") {
- val aspect = aop.inspecting.InspectingAspect({ m: AddTwoMixedModules =>
- val insts = aop.Select.instancesIn(m.toDefinition)
- val abs = insts.map { i: Instance[BaseModule] => i.toAbsoluteTarget }
- val rel = insts.map { i: Instance[BaseModule] => i.toTarget }
- abs should be(
- Seq(
- "~AddTwoMixedModules|AddTwoMixedModules/i0:AddOne".it,
- "~AddTwoMixedModules|AddTwoMixedModules/i1:AddOne_1".it
- )
- )
- rel should be(
- Seq(
- "~AddTwoMixedModules|AddTwoMixedModules/i0:AddOne".it,
- "~AddTwoMixedModules|AddTwoMixedModules/i1:AddOne_1".it
- )
- )
- })
- getFirrtlAndAnnos(new AddTwoMixedModules, Seq(aspect))
- }
- it("10.2: allInstancesOf") {
- val aspect = aop.inspecting.InspectingAspect({ m: AddFour =>
- val insts = aop.Select.allInstancesOf[AddOne](m.toDefinition)
- val abs = insts.map { i: Instance[AddOne] => i.in.toAbsoluteTarget }
- val rel = insts.map { i: Instance[AddOne] => i.in.toTarget }
- rel should be(
- Seq(
- "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>in".rt,
- "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>in".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>in".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>in".rt
- )
- )
- abs should be(
- Seq(
- "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>in".rt,
- "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>in".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>in".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>in".rt
- )
- )
- })
- getFirrtlAndAnnos(new AddFour, Seq(aspect))
- }
- it("10.3: definitionsOf") {
- val aspect = aop.inspecting.InspectingAspect({ m: AddTwoMixedModules =>
- val targets = aop.Select.definitionsOf[AddOne](m.toDefinition).map { i: Definition[AddOne] => i.in.toTarget }
- targets should be(
- Seq(
- "~AddTwoMixedModules|AddOne>in".rt,
- "~AddTwoMixedModules|AddOne_1>in".rt
- )
- )
- })
- getFirrtlAndAnnos(new AddTwoMixedModules, Seq(aspect))
- }
- it("10.4: definitionsIn") {
- val aspect = aop.inspecting.InspectingAspect({ m: AddTwoMixedModules =>
- val targets = aop.Select.definitionsIn(m.toDefinition).map { i: Definition[BaseModule] => i.toTarget }
- targets should be(
- Seq(
- "~AddTwoMixedModules|AddOne".mt,
- "~AddTwoMixedModules|AddOne_1".mt
- )
- )
- })
- getFirrtlAndAnnos(new AddTwoMixedModules, Seq(aspect))
- }
- it("10.5: allDefinitionsOf") {
- val aspect = aop.inspecting.InspectingAspect({ m: AddFour =>
- val targets = aop.Select.allDefinitionsOf[AddOne](m.toDefinition).map { i: Definition[AddOne] => i.in.toTarget }
- targets should be(
- Seq(
- "~AddFour|AddOne>in".rt,
- "~AddFour|AddOne_1>in".rt
- )
- )
- })
- getFirrtlAndAnnos(new AddFour, Seq(aspect))
- }
- it("10.6: Select.collectDeep should fail when combined with hierarchy package") {
- val aspect = aop.inspecting.InspectingAspect({ m: AddFour =>
- aop.Select.collectDeep(m) { case m: AddOne => m.toTarget }
- })
- intercept[Exception] { getFirrtlAndAnnos(new AddFour, Seq(aspect)) }
- }
- it("10.7: Select.getDeep should fail when combined with hierarchy package") {
- val aspect = aop.inspecting.InspectingAspect({ m: AddFour =>
- aop.Select.getDeep(m) { m: BaseModule => Nil }
- })
- intercept[Exception] { getFirrtlAndAnnos(new AddFour, Seq(aspect)) }
- }
- it("10.8: Select.instances should fail when combined with hierarchy package") {
- val aspect = aop.inspecting.InspectingAspect({ m: AddFour =>
- aop.Select.instances(m)
- })
- intercept[Exception] { getFirrtlAndAnnos(new AddFour, Seq(aspect)) }
- }
- it("10.9: allInstancesOf.ios") {
- val aspect = aop.inspecting.InspectingAspect({ m: AddFour =>
- val abs = aop.Select.allInstancesOf[AddOne](m.toDefinition).flatMap { i: Instance[AddOne] =>
- aop.Select.ios(i).map(_.toAbsoluteTarget)
- }
- val rel = aop.Select.allInstancesOf[AddOne](m.toDefinition).flatMap { i: Instance[AddOne] =>
- aop.Select.ios(i).map(_.toTarget)
- }
- abs should be(
- Seq(
- "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>clock".rt,
- "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>reset".rt,
- "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>in".rt,
- "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>out".rt,
- "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>clock".rt,
- "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>reset".rt,
- "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>in".rt,
- "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>out".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>clock".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>reset".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>in".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>out".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>clock".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>reset".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>in".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>out".rt
- )
- )
-
- rel should be(
- Seq(
- "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>clock".rt,
- "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>reset".rt,
- "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>in".rt,
- "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>out".rt,
- "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>clock".rt,
- "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>reset".rt,
- "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>in".rt,
- "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>out".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>clock".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>reset".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>in".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>out".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>clock".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>reset".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>in".rt,
- "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>out".rt
- )
- )
- })
- getFirrtlAndAnnos(new AddFour, Seq(aspect))
- }
- it("10.10: allDefinitionsOf.ios") {
- val aspect = aop.inspecting.InspectingAspect({ m: AddFour =>
- val abs = aop.Select.allDefinitionsOf[AddOne](m.toDefinition).flatMap { i: Definition[AddOne] =>
- aop.Select.ios(i).map(_.toAbsoluteTarget)
- }
- val rel = aop.Select.allDefinitionsOf[AddOne](m.toDefinition).flatMap { i: Definition[AddOne] =>
- aop.Select.ios(i).map(_.toTarget)
- }
- abs should be(
- Seq(
- "~AddFour|AddOne>clock".rt,
- "~AddFour|AddOne>reset".rt,
- "~AddFour|AddOne>in".rt,
- "~AddFour|AddOne>out".rt,
- "~AddFour|AddOne_1>clock".rt,
- "~AddFour|AddOne_1>reset".rt,
- "~AddFour|AddOne_1>in".rt,
- "~AddFour|AddOne_1>out".rt
- )
- )
-
- rel should be(
- Seq(
- "~AddFour|AddOne>clock".rt,
- "~AddFour|AddOne>reset".rt,
- "~AddFour|AddOne>in".rt,
- "~AddFour|AddOne>out".rt,
- "~AddFour|AddOne_1>clock".rt,
- "~AddFour|AddOne_1>reset".rt,
- "~AddFour|AddOne_1>in".rt,
- "~AddFour|AddOne_1>out".rt
- )
- )
-
- })
- getFirrtlAndAnnos(new AddFour, Seq(aspect))
- }
- it("10.11 Select.instancesIn for typed BaseModules") {
- val aspect = aop.inspecting.InspectingAspect({ m: HasMultipleTypeParamsInside =>
- val targets = aop.Select.instancesIn(m.toDefinition).map { i: Instance[BaseModule] => i.toTarget }
- targets should be(
- Seq(
- "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i00:HasTypeParams".it,
- "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i01:HasTypeParams".it,
- "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i10:HasTypeParams_1".it,
- "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i11:HasTypeParams_1".it
- )
- )
- })
- getFirrtlAndAnnos(new HasMultipleTypeParamsInside, Seq(aspect))
- }
- it("10.12 Select.instancesOf for typed BaseModules if type is ignored") {
- val aspect = aop.inspecting.InspectingAspect({ m: HasMultipleTypeParamsInside =>
- val targets =
- aop.Select.instancesOf[HasTypeParams[_]](m.toDefinition).map { i: Instance[HasTypeParams[_]] => i.toTarget }
- targets should be(
- Seq(
- "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i00:HasTypeParams".it,
- "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i01:HasTypeParams".it,
- "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i10:HasTypeParams_1".it,
- "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i11:HasTypeParams_1".it
- )
- )
- })
- getFirrtlAndAnnos(new HasMultipleTypeParamsInside, Seq(aspect))
- }
- it(
- "10.13 Select.instancesOf for typed BaseModules even type is specified wrongly (should be ignored, even though we wish it weren't)"
- ) {
- val aspect = aop.inspecting.InspectingAspect({ m: HasMultipleTypeParamsInside =>
- val targets = aop.Select.instancesOf[HasTypeParams[SInt]](m.toDefinition).map { i: Instance[HasTypeParams[_]] =>
- i.toTarget
- }
- targets should be(
- Seq(
- "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i00:HasTypeParams".it,
- "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i01:HasTypeParams".it,
- "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i10:HasTypeParams_1".it,
- "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i11:HasTypeParams_1".it
- )
- )
- })
- getFirrtlAndAnnos(new HasMultipleTypeParamsInside, Seq(aspect))
- }
- }
-}
diff --git a/src/test/scala/chiselTests/experimental/hierarchy/SeparateElaborationSpec.scala b/src/test/scala/chiselTests/experimental/hierarchy/SeparateElaborationSpec.scala
deleted file mode 100644
index 25bbc474..00000000
--- a/src/test/scala/chiselTests/experimental/hierarchy/SeparateElaborationSpec.scala
+++ /dev/null
@@ -1,495 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.experimental.hierarchy
-
-import chiselTests.ChiselFunSpec
-import chisel3._
-import chisel3.stage.{ChiselCircuitAnnotation, ChiselGeneratorAnnotation, ChiselStage, DesignAnnotation}
-import chisel3.experimental.hierarchy.{Definition, Instance}
-import chisel3.experimental.hierarchy.ImportDefinitionAnnotation
-import firrtl.AnnotationSeq
-import firrtl.options.TargetDirAnnotation
-
-import scala.io.Source
-
-class SeparateElaborationSpec extends ChiselFunSpec with Utils {
- import Examples._
-
- /** Return a [[DesignAnnotation]] from a list of annotations. */
- private def getDesignAnnotation[T <: RawModule](annos: AnnotationSeq): DesignAnnotation[T] = {
- val designAnnos = annos.flatMap { a =>
- a match {
- case a: DesignAnnotation[T] => Some(a)
- case _ => None
- }
- }
- require(designAnnos.length == 1, s"Exactly one DesignAnnotation should exist, but found: $designAnnos.")
- designAnnos.head
- }
-
- /** Elaborates [[AddOne]] and returns its [[Definition]]. */
- private def getAddOneDefinition(testDir: String): Definition[AddOne] = {
- val dutAnnos = (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new AddOne),
- TargetDirAnnotation(testDir)
- )
- )
-
- // Grab DUT definition to pass into testbench
- getDesignAnnotation(dutAnnos).design.asInstanceOf[AddOne].toDefinition
- }
-
- /** Return [[Definition]]s of all modules in a circuit. */
- private def allModulesToImportedDefs(annos: AnnotationSeq): Seq[ImportDefinitionAnnotation[_]] = {
- annos.flatMap { a =>
- a match {
- case a: ChiselCircuitAnnotation =>
- a.circuit.components.map { c => ImportDefinitionAnnotation(c.id.toDefinition) }
- case _ => Seq.empty
- }
- }
- }
-
- describe("(0): Name conflicts") {
- it("(0.a): should not occur between a Module and an Instance of a previously elaborated Definition.") {
- val testDir = createTestDirectory(this.getClass.getSimpleName).toString
-
- val dutDef = getAddOneDefinition(testDir)
-
- class Testbench(defn: Definition[AddOne]) extends Module {
- val mod = Module(new AddOne)
- val inst = Instance(defn)
-
- // Tie inputs to a value so ChiselStage does not complain
- mod.in := 0.U
- inst.in := 0.U
- dontTouch(mod.out)
- }
-
- (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new Testbench(dutDef)),
- TargetDirAnnotation(testDir),
- ImportDefinitionAnnotation(dutDef)
- )
- )
-
- val tb_rtl = Source.fromFile(s"$testDir/Testbench.v").getLines.mkString
- tb_rtl should include("module AddOne_1(")
- tb_rtl should include("AddOne_1 mod (")
- (tb_rtl should not).include("module AddOne(")
- tb_rtl should include("AddOne inst (")
- }
-
- it(
- "(0.b): should not occur between an Instance of a Definition and an Instance of a previously elaborated Definition."
- ) {
- val testDir = createTestDirectory(this.getClass.getSimpleName).toString
-
- val dutDef = getAddOneDefinition(testDir)
-
- class Testbench(defn: Definition[AddOne]) extends Module {
- val inst0 = Instance(Definition(new AddOne))
- val inst1 = Instance(defn)
-
- // Tie inputs to a value so ChiselStage does not complain
- inst0.in := 0.U
- inst1.in := 0.U
- dontTouch(inst0.out)
- }
-
- (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new Testbench(dutDef)),
- TargetDirAnnotation(testDir),
- ImportDefinitionAnnotation(dutDef)
- )
- )
-
- val tb_rtl = Source.fromFile(s"$testDir/Testbench.v").getLines.mkString
- tb_rtl should include("module AddOne_1(")
- tb_rtl should include("AddOne_1 inst0 (")
- (tb_rtl should not).include("module AddOne(")
- tb_rtl should include("AddOne inst1 (")
- }
- }
-
- describe("(1): Repeat Module definitions") {
- it("(1.a): should not occur when elaborating multiple Instances separately from its Definition.") {
- val testDir = createTestDirectory(this.getClass.getSimpleName).toString
-
- val dutDef = getAddOneDefinition(testDir)
-
- class Testbench(defn: Definition[AddOne]) extends Module {
- val inst0 = Instance(defn)
- val inst1 = Instance(defn)
-
- inst0.in := 0.U
- inst1.in := 0.U
- }
-
- // If there is a repeat module definition, FIRRTL emission will fail
- (new ChiselStage).emitFirrtl(
- gen = new Testbench(dutDef),
- args = Array("-td", testDir, "--full-stacktrace"),
- annotations = Seq(ImportDefinitionAnnotation(dutDef))
- )
- }
- }
-
- describe("(2): Multiple imported Definitions of modules without submodules") {
- it(
- "(2.a): should work if a list of imported Definitions is passed between Stages."
- ) {
- val testDir = createTestDirectory(this.getClass.getSimpleName).toString
-
- val dutAnnos0 = (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new AddOneParameterized(4)),
- TargetDirAnnotation(s"$testDir/dutDef0")
- )
- )
- val dutDef0 = getDesignAnnotation(dutAnnos0).design.asInstanceOf[AddOneParameterized].toDefinition
-
- val dutAnnos1 = (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new AddOneParameterized(8)),
- TargetDirAnnotation(s"$testDir/dutDef1"),
- // pass in previously elaborated Definitions
- ImportDefinitionAnnotation(dutDef0)
- )
- )
- val dutDef1 = getDesignAnnotation(dutAnnos1).design.asInstanceOf[AddOneParameterized].toDefinition
-
- class Testbench(defn0: Definition[AddOneParameterized], defn1: Definition[AddOneParameterized]) extends Module {
- val inst0 = Instance(defn0)
- val inst1 = Instance(defn1)
-
- // Tie inputs to a value so ChiselStage does not complain
- inst0.in := 0.U
- inst1.in := 0.U
- }
-
- (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new Testbench(dutDef0, dutDef1)),
- TargetDirAnnotation(testDir),
- ImportDefinitionAnnotation(dutDef0),
- ImportDefinitionAnnotation(dutDef1)
- )
- )
-
- val dutDef0_rtl = Source.fromFile(s"$testDir/dutDef0/AddOneParameterized.v").getLines.mkString
- dutDef0_rtl should include("module AddOneParameterized(")
- val dutDef1_rtl = Source.fromFile(s"$testDir/dutDef1/AddOneParameterized_1.v").getLines.mkString
- dutDef1_rtl should include("module AddOneParameterized_1(")
-
- val tb_rtl = Source.fromFile(s"$testDir/Testbench.v").getLines.mkString
- tb_rtl should include("AddOneParameterized inst0 (")
- tb_rtl should include("AddOneParameterized_1 inst1 (")
- (tb_rtl should not).include("module AddOneParameterized(")
- (tb_rtl should not).include("module AddOneParameterized_1(")
- }
-
- it(
- "(2.b): should throw an exception if information is not passed between Stages."
- ) {
- val testDir = createTestDirectory(this.getClass.getSimpleName).toString
-
- val dutAnnos0 = (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new AddOneParameterized(4)),
- TargetDirAnnotation(s"$testDir/dutDef0")
- )
- )
- val dutDef0 = getDesignAnnotation(dutAnnos0).design.asInstanceOf[AddOneParameterized].toDefinition
-
- val dutAnnos1 = (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new AddOneParameterized(8)),
- TargetDirAnnotation(s"$testDir/dutDef1")
- )
- )
- val dutDef1 = getDesignAnnotation(dutAnnos1).design.asInstanceOf[AddOneParameterized].toDefinition
-
- class Testbench(defn0: Definition[AddOneParameterized], defn1: Definition[AddOneParameterized]) extends Module {
- val inst0 = Instance(defn0)
- val inst1 = Instance(defn1)
-
- // Tie inputs to a value so ChiselStage does not complain
- inst0.in := 0.U
- inst1.in := 0.U
- }
-
- // Because these elaborations have no knowledge of each other, they create
- // modules of the same name
- val dutDef0_rtl = Source.fromFile(s"$testDir/dutDef0/AddOneParameterized.v").getLines.mkString
- dutDef0_rtl should include("module AddOneParameterized(")
- val dutDef1_rtl = Source.fromFile(s"$testDir/dutDef1/AddOneParameterized.v").getLines.mkString
- dutDef1_rtl should include("module AddOneParameterized(")
-
- val errMsg = intercept[ChiselException] {
- (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new Testbench(dutDef0, dutDef1)),
- TargetDirAnnotation(testDir),
- ImportDefinitionAnnotation(dutDef0),
- ImportDefinitionAnnotation(dutDef1)
- )
- )
- }
- errMsg.getMessage should include(
- "Expected distinct imported Definition names but found duplicates for: AddOneParameterized"
- )
- }
- }
-
- describe("(3): Multiple imported Definitions of modules with submodules") {
- it(
- "(3.a): should work if a list of imported Definitions for all modules is passed between Stages."
- ) {
- val testDir = createTestDirectory(this.getClass.getSimpleName).toString
-
- val dutAnnos0 = (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new AddTwoMixedModules),
- TargetDirAnnotation(s"$testDir/dutDef0")
- )
- )
- val dutDef0 = getDesignAnnotation(dutAnnos0).design.asInstanceOf[AddTwoMixedModules].toDefinition
- val importDefinitionAnnos0 = allModulesToImportedDefs(dutAnnos0)
-
- val dutAnnos1 = (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new AddTwoMixedModules),
- TargetDirAnnotation(s"$testDir/dutDef1")
- ) ++ importDefinitionAnnos0
- )
- val dutDef1 = getDesignAnnotation(dutAnnos1).design.asInstanceOf[AddTwoMixedModules].toDefinition
- val importDefinitionAnnos1 = allModulesToImportedDefs(dutAnnos1)
-
- class Testbench(defn0: Definition[AddTwoMixedModules], defn1: Definition[AddTwoMixedModules]) extends Module {
- val inst0 = Instance(defn0)
- val inst1 = Instance(defn1)
-
- // Tie inputs to a value so ChiselStage does not complain
- inst0.in := 0.U
- inst1.in := 0.U
- }
-
- val dutDef0_rtl = Source.fromFile(s"$testDir/dutDef0/AddTwoMixedModules.v").getLines.mkString
- dutDef0_rtl should include("module AddOne(")
- dutDef0_rtl should include("module AddTwoMixedModules(")
- val dutDef1_rtl = Source.fromFile(s"$testDir/dutDef1/AddTwoMixedModules_1.v").getLines.mkString
- dutDef1_rtl should include("module AddOne_2(")
- dutDef1_rtl should include("module AddTwoMixedModules_1(")
-
- (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new Testbench(dutDef0, dutDef1)),
- TargetDirAnnotation(testDir)
- ) ++ importDefinitionAnnos0 ++ importDefinitionAnnos1
- )
-
- val tb_rtl = Source.fromFile(s"$testDir/Testbench.v").getLines.mkString
- tb_rtl should include("AddTwoMixedModules inst0 (")
- tb_rtl should include("AddTwoMixedModules_1 inst1 (")
- (tb_rtl should not).include("module AddTwoMixedModules(")
- (tb_rtl should not).include("module AddTwoMixedModules_1(")
- }
- }
-
- it(
- "(3.b): should throw an exception if submodules are not passed between Definition elaborations."
- ) {
- val testDir = createTestDirectory(this.getClass.getSimpleName).toString
-
- val dutAnnos0 = (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new AddTwoMixedModules),
- TargetDirAnnotation(s"$testDir/dutDef0")
- )
- )
- val dutDef0 = getDesignAnnotation(dutAnnos0).design.asInstanceOf[AddTwoMixedModules].toDefinition
- val importDefinitionAnnos0 = allModulesToImportedDefs(dutAnnos0)
-
- val dutAnnos1 = (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new AddTwoMixedModules),
- ImportDefinitionAnnotation(dutDef0),
- TargetDirAnnotation(s"$testDir/dutDef1")
- )
- )
- val dutDef1 = getDesignAnnotation(dutAnnos1).design.asInstanceOf[AddTwoMixedModules].toDefinition
- val importDefinitionAnnos1 = allModulesToImportedDefs(dutAnnos1)
-
- class Testbench(defn0: Definition[AddTwoMixedModules], defn1: Definition[AddTwoMixedModules]) extends Module {
- val inst0 = Instance(defn0)
- val inst1 = Instance(defn1)
-
- // Tie inputs to a value so ChiselStage does not complain
- inst0.in := 0.U
- inst1.in := 0.U
- }
-
- val dutDef0_rtl = Source.fromFile(s"$testDir/dutDef0/AddTwoMixedModules.v").getLines.mkString
- dutDef0_rtl should include("module AddOne(")
- dutDef0_rtl should include("module AddTwoMixedModules(")
- val dutDef1_rtl = Source.fromFile(s"$testDir/dutDef1/AddTwoMixedModules_1.v").getLines.mkString
- dutDef1_rtl should include("module AddOne(")
- dutDef1_rtl should include("module AddTwoMixedModules_1(")
-
- val errMsg = intercept[ChiselException] {
- (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new Testbench(dutDef0, dutDef1)),
- TargetDirAnnotation(testDir)
- ) ++ importDefinitionAnnos0 ++ importDefinitionAnnos1
- )
- }
- errMsg.getMessage should include(
- "Expected distinct imported Definition names but found duplicates for: AddOne"
- )
- }
-
- describe("(4): With ExtMod Names") {
- it("(4.a): should pick correct ExtMod names when passed") {
- val testDir = createTestDirectory(this.getClass.getSimpleName).toString
-
- val dutDef = getAddOneDefinition(testDir)
-
- class Testbench(defn: Definition[AddOne]) extends Module {
- val mod = Module(new AddOne)
- val inst = Instance(defn)
-
- // Tie inputs to a value so ChiselStage does not complain
- mod.in := 0.U
- inst.in := 0.U
- dontTouch(mod.out)
- }
-
- (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new Testbench(dutDef)),
- TargetDirAnnotation(testDir),
- ImportDefinitionAnnotation(dutDef, Some("CustomPrefix_AddOne_CustomSuffix"))
- )
- )
-
- val tb_rtl = Source.fromFile(s"$testDir/Testbench.v").getLines.mkString
-
- tb_rtl should include("module AddOne_1(")
- tb_rtl should include("AddOne_1 mod (")
- (tb_rtl should not).include("module AddOne(")
- tb_rtl should include("CustomPrefix_AddOne_CustomSuffix inst (")
- }
- }
-
- it(
- "(4.b): should work if a list of imported Definitions is passed between Stages with ExtModName."
- ) {
- val testDir = createTestDirectory(this.getClass.getSimpleName).toString
-
- val dutAnnos0 = (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new AddOneParameterized(4)),
- TargetDirAnnotation(s"$testDir/dutDef0")
- )
- )
- val dutDef0 = getDesignAnnotation(dutAnnos0).design.asInstanceOf[AddOneParameterized].toDefinition
-
- val dutAnnos1 = (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new AddOneParameterized(8)),
- TargetDirAnnotation(s"$testDir/dutDef1"),
- // pass in previously elaborated Definitions
- ImportDefinitionAnnotation(dutDef0)
- )
- )
- val dutDef1 = getDesignAnnotation(dutAnnos1).design.asInstanceOf[AddOneParameterized].toDefinition
-
- class Testbench(defn0: Definition[AddOneParameterized], defn1: Definition[AddOneParameterized]) extends Module {
- val inst0 = Instance(defn0)
- val inst1 = Instance(defn1)
-
- // Tie inputs to a value so ChiselStage does not complain
- inst0.in := 0.U
- inst1.in := 0.U
- }
-
- (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new Testbench(dutDef0, dutDef1)),
- TargetDirAnnotation(testDir),
- ImportDefinitionAnnotation(dutDef0, Some("Inst1_Prefix_AddOnePramaterized_Inst1_Suffix")),
- ImportDefinitionAnnotation(dutDef1, Some("Inst2_Prefix_AddOnePrameterized_1_Inst2_Suffix"))
- )
- )
-
- val dutDef0_rtl = Source.fromFile(s"$testDir/dutDef0/AddOneParameterized.v").getLines.mkString
- dutDef0_rtl should include("module AddOneParameterized(")
- val dutDef1_rtl = Source.fromFile(s"$testDir/dutDef1/AddOneParameterized_1.v").getLines.mkString
- dutDef1_rtl should include("module AddOneParameterized_1(")
-
- val tb_rtl = Source.fromFile(s"$testDir/Testbench.v").getLines.mkString
- tb_rtl should include("Inst1_Prefix_AddOnePramaterized_Inst1_Suffix inst0 (")
- tb_rtl should include("Inst2_Prefix_AddOnePrameterized_1_Inst2_Suffix inst1 (")
- (tb_rtl should not).include("module AddOneParameterized(")
- (tb_rtl should not).include("module AddOneParameterized_1(")
- }
-
- it(
- "(4.c): should throw an exception if a list of imported Definitions is passed between Stages with same ExtModName."
- ) {
- val testDir = createTestDirectory(this.getClass.getSimpleName).toString
-
- val dutAnnos0 = (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new AddOneParameterized(4)),
- TargetDirAnnotation(s"$testDir/dutDef0")
- )
- )
- val importDefinitionAnnos0 = allModulesToImportedDefs(dutAnnos0)
- val dutDef0 = getDesignAnnotation(dutAnnos0).design.asInstanceOf[AddOneParameterized].toDefinition
-
- val dutAnnos1 = (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new AddOneParameterized(8)),
- TargetDirAnnotation(s"$testDir/dutDef1"),
- // pass in previously elaborated Definitions
- ImportDefinitionAnnotation(dutDef0)
- )
- )
- val importDefinitionAnnos1 = allModulesToImportedDefs(dutAnnos1)
- val dutDef1 = getDesignAnnotation(dutAnnos1).design.asInstanceOf[AddOneParameterized].toDefinition
-
- class Testbench(defn0: Definition[AddOneParameterized], defn1: Definition[AddOneParameterized]) extends Module {
- val inst0 = Instance(defn0)
- val inst1 = Instance(defn1)
-
- // Tie inputs to a value so ChiselStage does not complain
- inst0.in := 0.U
- inst1.in := 0.U
- }
-
- val dutDef0_rtl = Source.fromFile(s"$testDir/dutDef0/AddOneParameterized.v").getLines.mkString
- dutDef0_rtl should include("module AddOneParameterized(")
- val dutDef1_rtl = Source.fromFile(s"$testDir/dutDef1/AddOneParameterized_1.v").getLines.mkString
- dutDef1_rtl should include("module AddOneParameterized_1(")
-
- val errMsg = intercept[ChiselException] {
- (new ChiselStage).run(
- Seq(
- ChiselGeneratorAnnotation(() => new Testbench(dutDef0, dutDef1)),
- TargetDirAnnotation(testDir),
- ImportDefinitionAnnotation(dutDef0, Some("Inst1_Prefix_AddOnePrameterized_Inst1_Suffix")),
- ImportDefinitionAnnotation(dutDef1, Some("Inst1_Prefix_AddOnePrameterized_Inst1_Suffix"))
- )
- )
- }
- errMsg.getMessage should include(
- "Expected distinct overrideDef names but found duplicates for: Inst1_Prefix_AddOnePrameterized_Inst1_Suffix"
- )
- }
-}
diff --git a/src/test/scala/chiselTests/experimental/hierarchy/Utils.scala b/src/test/scala/chiselTests/experimental/hierarchy/Utils.scala
deleted file mode 100644
index a2e51765..00000000
--- a/src/test/scala/chiselTests/experimental/hierarchy/Utils.scala
+++ /dev/null
@@ -1,21 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.experimental.hierarchy
-
-import chisel3._
-import _root_.firrtl.annotations._
-import chisel3.stage.{ChiselCircuitAnnotation, CircuitSerializationAnnotation, DesignAnnotation}
-import chiselTests.ChiselRunners
-import firrtl.stage.FirrtlCircuitAnnotation
-import org.scalatest.matchers.should.Matchers
-
-trait Utils extends ChiselRunners with chiselTests.Utils with Matchers {
- import Annotations._
- // TODO promote to standard API (in FIRRTL) and perhaps even implement with a macro
- implicit class Str2RefTarget(str: String) {
- def rt: ReferenceTarget = Target.deserialize(str).asInstanceOf[ReferenceTarget]
- def it: InstanceTarget = Target.deserialize(str).asInstanceOf[InstanceTarget]
- def mt: ModuleTarget = Target.deserialize(str).asInstanceOf[ModuleTarget]
- def ct: CircuitTarget = Target.deserialize(str).asInstanceOf[CircuitTarget]
- }
-}
diff --git a/src/test/scala/chiselTests/naming/NamePluginSpec.scala b/src/test/scala/chiselTests/naming/NamePluginSpec.scala
deleted file mode 100644
index a787bb80..00000000
--- a/src/test/scala/chiselTests/naming/NamePluginSpec.scala
+++ /dev/null
@@ -1,362 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.naming
-
-import chisel3._
-import chisel3.stage.ChiselStage
-import chisel3.aop.Select
-import chisel3.experimental.{prefix, treedump}
-import chiselTests.{ChiselFlatSpec, Utils}
-
-class NamePluginSpec extends ChiselFlatSpec with Utils {
- implicit val minimumScalaVersion: Int = 12
-
- "Scala plugin" should "name internally scoped components" in {
- class Test extends Module {
- { val mywire = Wire(UInt(3.W)) }
- }
- aspectTest(() => new Test) { top: Test =>
- Select.wires(top).head.toTarget.ref should be("mywire")
- }
- }
-
- "Scala plugin" should "name internally scoped instances" in {
- class Inner extends Module {}
- class Test extends Module {
- { val myinstance = Module(new Inner) }
- }
- aspectTest(() => new Test) { top: Test =>
- Select.instances(top).head.instanceName should be("myinstance")
- }
- }
-
- "Scala plugin" should "interact with prefixing" in {
- class Test extends Module {
- def builder() = {
- val wire = Wire(UInt(3.W))
- }
- prefix("first") {
- builder()
- }
- prefix("second") {
- builder()
- }
- }
- aspectTest(() => new Test) { top: Test =>
- Select.wires(top).map(_.instanceName) should be(List("first_wire", "second_wire"))
- }
- }
-
- "Scala plugin" should "interact with prefixing so last val name wins" in {
- class Test extends Module {
- def builder() = {
- val wire1 = Wire(UInt(3.W))
- val wire2 = Wire(UInt(3.W))
- wire2
- }
- {
- val x1 = prefix("first") {
- builder()
- }
- }
- {
- val x2 = prefix("second") {
- builder()
- }
- }
- }
- aspectTest(() => new Test) { top: Test =>
- Select.wires(top).map(_.instanceName) should be(List("x1_first_wire1", "x1", "x2_second_wire1", "x2"))
- }
- }
-
- "Scala plugin" should "name verification ops" in {
- class Test extends Module {
- val foo, bar = IO(Input(UInt(8.W)))
-
- {
- val x1 = chisel3.assert(1.U === 1.U)
- val x2 = cover(foo =/= bar)
- val x3 = chisel3.assume(foo =/= 123.U)
- val x4 = printf("foo = %d\n", foo)
- }
- }
- val chirrtl = ChiselStage.emitChirrtl(new Test)
- (chirrtl should include).regex("assert.*: x1")
- (chirrtl should include).regex("cover.*: x2")
- (chirrtl should include).regex("assume.*: x3")
- (chirrtl should include).regex("printf.*: x4")
- }
-
- "Naming on option" should "work" in {
-
- class Test extends Module {
- def builder(): Option[UInt] = {
- val a = Wire(UInt(3.W))
- Some(a)
- }
-
- { val blah = builder() }
- }
- aspectTest(() => new Test) { top: Test =>
- Select.wires(top).map(_.instanceName) should be(List("blah"))
- }
- }
-
- "Naming on iterables" should "work" in {
-
- class Test extends Module {
- def builder(): Seq[UInt] = {
- val a = Wire(UInt(3.W))
- val b = Wire(UInt(3.W))
- Seq(a, b)
- }
- {
- val blah = {
- builder()
- }
- }
- }
- aspectTest(() => new Test) { top: Test =>
- Select.wires(top).map(_.instanceName) should be(List("blah_0", "blah_1"))
- }
- }
-
- "Naming on nested iterables" should "work" in {
-
- class Test extends Module {
- def builder(): Seq[Seq[UInt]] = {
- val a = Wire(UInt(3.W))
- val b = Wire(UInt(3.W))
- val c = Wire(UInt(3.W))
- val d = Wire(UInt(3.W))
- Seq(Seq(a, b), Seq(c, d))
- }
- {
- val blah = {
- builder()
- }
- }
- }
- aspectTest(() => new Test) { top: Test =>
- Select.wires(top).map(_.instanceName) should be(
- List(
- "blah_0_0",
- "blah_0_1",
- "blah_1_0",
- "blah_1_1"
- )
- )
- }
- }
-
- "Naming on custom case classes" should "not work" in {
- case class Container(a: UInt, b: UInt)
-
- class Test extends Module {
- def builder(): Container = {
- val a = Wire(UInt(3.W))
- val b = Wire(UInt(3.W))
- Container(a, b)
- }
-
- { val blah = builder() }
- }
- aspectTest(() => new Test) { top: Test =>
- Select.wires(top).map(_.instanceName) should be(List("a", "b"))
- }
- }
-
- "Multiple names on an IO within a module" should "get the first name" in {
- class Test extends RawModule {
- {
- val a = IO(Output(UInt(3.W)))
- val b = a
- }
- }
-
- aspectTest(() => new Test) { top: Test =>
- Select.ios(top).map(_.instanceName) should be(List("a"))
- }
- }
-
- "Multiple names on a non-IO" should "get the first name" in {
- class Test extends Module {
- {
- val a = Wire(UInt(3.W))
- val b = a
- }
- }
-
- aspectTest(() => new Test) { top: Test =>
- Select.wires(top).map(_.instanceName) should be(List("a"))
- }
- }
-
- "Outer Expression, First Statement naming" should "apply to IO" in {
- class Test extends RawModule {
- {
- val widthOpt: Option[Int] = Some(4)
- val out = widthOpt.map { w =>
- val port = IO(Output(UInt(w.W)))
- port
- }
- val foo = out
- val bar = out.get
- }
- }
-
- aspectTest(() => new Test) { top: Test =>
- Select.ios(top).map(_.instanceName) should be(List("out"))
- }
- }
-
- "Outer Expression, First Statement naming" should "apply to non-IO" in {
- class Test extends RawModule {
- {
- val widthOpt: Option[Int] = Some(4)
- val fizz = widthOpt.map { w =>
- val wire = Wire(UInt(w.W))
- wire
- }
- val foo = fizz
- val bar = fizz.get
- }
- }
-
- aspectTest(() => new Test) { top: Test =>
- Select.wires(top).map(_.instanceName) should be(List("fizz"))
- }
- }
-
- "autoSeed" should "NOT override automatic naming for IO" in {
- class Test extends RawModule {
- {
- val a = IO(Output(UInt(3.W)))
- a.autoSeed("b")
- }
- }
-
- aspectTest(() => new Test) { top: Test =>
- Select.ios(top).map(_.instanceName) should be(List("a"))
- }
- }
-
- "autoSeed" should "override automatic naming for non-IO" in {
- class Test extends Module {
- {
- val a = Wire(UInt(3.W))
- a.autoSeed("b")
- }
- }
-
- aspectTest(() => new Test) { top: Test =>
- Select.wires(top).map(_.instanceName) should be(List("b"))
- }
- }
-
- "Unapply assignments" should "still be named" in {
- class Test extends Module {
- {
- val (a, b) = (Wire(UInt(3.W)), Wire(UInt(3.W)))
- }
- }
-
- aspectTest(() => new Test) { top: Test =>
- Select.wires(top).map(_.instanceName) should be(List("a", "b"))
- }
- }
-
- "Unapply assignments" should "not override already named things" in {
- class Test extends Module {
- {
- val x = Wire(UInt(3.W))
- val (a, b) = (x, Wire(UInt(3.W)))
- }
- }
-
- aspectTest(() => new Test) { top: Test =>
- Select.wires(top).map(_.instanceName) should be(List("x", "b"))
- }
- }
-
- "Case class unapply assignments" should "be named" in {
- case class Foo(x: UInt, y: UInt)
- class Test extends Module {
- {
- def func() = Foo(Wire(UInt(3.W)), Wire(UInt(3.W)))
- val Foo(a, b) = func()
- }
- }
-
- aspectTest(() => new Test) { top: Test =>
- Select.wires(top).map(_.instanceName) should be(List("a", "b"))
- }
- }
-
- "Complex unapply assignments" should "be named" in {
- case class Foo(x: UInt, y: UInt)
- class Test extends Module {
- {
- val w = Wire(UInt(3.W))
- def func() = {
- val x = Foo(Wire(UInt(3.W)), Wire(UInt(3.W)))
- (x, w) :: Nil
- }
- val ((Foo(a, _), c) :: Nil) = func()
- }
- }
-
- aspectTest(() => new Test) { top: Test =>
- Select.wires(top).map(_.instanceName) should be(List("w", "a", "_WIRE"))
- }
- }
-
- "Recursive types" should "not infinitely loop" in {
- // When this fails, it causes a StackOverflow when compiling the tests
- // Unfortunately, this doesn't seem to work with assertCompiles(...), it probably ignores the
- // custom project scalacOptions
- def func(x: String) = {
- // We only check types of vals, we don't actually want to run this code though
- val y = scala.xml.XML.loadFile(x)
- y
- }
- }
-
- "Nested val declarations" should "all be named" in {
- class Test extends Module {
- {
- val a = {
- val b = {
- val c = Wire(UInt(3.W))
- Wire(UInt(3.W))
- }
- Wire(UInt(3.W))
- }
- }
- }
-
- aspectTest(() => new Test) { top: Test =>
- Select.wires(top).map(_.instanceName) should be(List("a_b_c", "a_b", "a"))
- }
- }
-
- behavior.of("Unnamed values (aka \"Temporaries\")")
-
- they should "be declared by starting the name with '_'" in {
- class Test extends Module {
- {
- val a = {
- val b = {
- val _c = Wire(UInt(3.W))
- 4.U // literal so there is no name
- }
- b
- }
- }
- }
- aspectTest(() => new Test) { top: Test =>
- Select.wires(top).map(_.instanceName) should be(List("_a_b_c"))
- }
- }
-}
diff --git a/src/test/scala/chiselTests/naming/PrefixSpec.scala b/src/test/scala/chiselTests/naming/PrefixSpec.scala
deleted file mode 100644
index d8cb3348..00000000
--- a/src/test/scala/chiselTests/naming/PrefixSpec.scala
+++ /dev/null
@@ -1,550 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.naming
-
-import chisel3._
-import chisel3.stage.ChiselStage
-import chisel3.aop.Select
-import chisel3.experimental.{dump, noPrefix, prefix, treedump}
-import chiselTests.{ChiselPropSpec, Utils}
-import chisel3.experimental.AffectsChiselPrefix
-
-class PrefixSpec extends ChiselPropSpec with Utils {
- implicit val minimumMajorVersion: Int = 12
- property("Scala plugin should interact with prefixing so last plugin name wins?") {
- class Test extends Module {
- def builder(): UInt = {
- val wire1 = Wire(UInt(3.W))
- val wire2 = Wire(UInt(3.W))
- wire2
- }
-
- {
- val x1 = prefix("first") {
- builder()
- }
- }
- {
- val x2 = prefix("second") {
- builder()
- }
- }
- }
- aspectTest(() => new Test) { top: Test =>
- Select.wires(top).map(_.instanceName) should be(List("x1_first_wire1", "x1", "x2_second_wire1", "x2"))
- }
- }
-
- property("Nested prefixes should work") {
- class Test extends Module {
- def builder2(): UInt = {
- val wire1 = Wire(UInt(3.W))
- val wire2 = Wire(UInt(3.W))
- wire2
- }
- def builder(): UInt = {
- val wire1 = Wire(UInt(3.W))
- val wire2 = Wire(UInt(3.W))
- prefix("foo") {
- builder2()
- }
- }
- { val x1 = builder() }
- { val x2 = builder() }
- }
- aspectTest(() => new Test) { top: Test =>
- Select.wires(top).map(_.instanceName) should be(
- List(
- "x1_wire1",
- "x1_wire2",
- "x1_foo_wire1",
- "x1",
- "x2_wire1",
- "x2_wire2",
- "x2_foo_wire1",
- "x2"
- )
- )
- }
- }
-
- property("Prefixing seeded with signal") {
- class Test extends Module {
- def builder(): UInt = {
- val wire = Wire(UInt(3.W))
- wire := 3.U
- wire
- }
- {
- val x1 = Wire(UInt(3.W))
- x1 := {
- builder()
- }
- val x2 = Wire(UInt(3.W))
- x2 := {
- builder()
- }
- }
- }
- aspectTest(() => new Test) { top: Test =>
- Select.wires(top).map(_.instanceName) should be(List("x1", "x1_wire", "x2", "x2_wire"))
- }
- }
-
- property("Automatic prefixing should work") {
-
- class Test extends Module {
- def builder(): UInt = {
- val a = Wire(UInt(3.W))
- val b = Wire(UInt(3.W))
- b
- }
-
- {
- val ADAM = builder()
- val JACOB = builder()
- }
- }
- aspectTest(() => new Test) { top: Test =>
- Select.wires(top).map(_.instanceName) should be(List("ADAM_a", "ADAM", "JACOB_a", "JACOB"))
- }
- }
-
- property("No prefixing annotation on defs should work") {
-
- class Test extends Module {
- def builder(): UInt = noPrefix {
- val a = Wire(UInt(3.W))
- val b = Wire(UInt(3.W))
- b
- }
-
- { val noprefix = builder() }
- }
- aspectTest(() => new Test) { top: Test =>
- Select.wires(top).map(_.instanceName) should be(List("a", "noprefix"))
- }
- }
-
- property("Prefixing on temps should work") {
-
- class Test extends Module {
- def builder(): UInt = {
- val a = Wire(UInt(3.W))
- val b = Wire(UInt(3.W))
- a +& (b * a)
- }
-
- { val blah = builder() }
- }
- aspectTest(() => new Test) { top: Test =>
- Select.ops(top).map(x => (x._1, x._2.instanceName)) should be(
- List(
- ("mul", "_blah_T"),
- ("add", "blah")
- )
- )
- }
- }
-
- property("Prefixing should not leak into child modules") {
- class Child extends Module {
- {
- val wire = Wire(UInt())
- }
- }
-
- class Test extends Module {
- {
- val child = prefix("InTest") {
- Module(new Child)
- }
- }
- }
- aspectTest(() => new Test) { top: Test =>
- Select.wires(Select.instances(top).head).map(_.instanceName) should be(List("wire"))
- }
- }
-
- property("Prefixing should not leak into child modules, example 2") {
- class Child extends Module {
- {
- val wire = Wire(UInt())
- }
- }
-
- class Test extends Module {
- val x = IO(Input(UInt(3.W)))
- val y = {
- lazy val module = new Child
- val child = Module(module)
- }
- }
- aspectTest(() => new Test) { top: Test =>
- Select.wires(Select.instances(top).head).map(_.instanceName) should be(List("wire"))
- }
- }
-
- property("Instance names should not be added to prefix") {
- class Child(tpe: UInt) extends Module {
- {
- val io = IO(Input(tpe))
- }
- }
-
- class Test extends Module {
- {
- lazy val module = {
- val x = UInt(3.W)
- new Child(x)
- }
- val child = Module(module)
- }
- }
- aspectTest(() => new Test) { top: Test =>
- Select.ios(Select.instances(top).head).map(_.instanceName) should be(List("clock", "reset", "io"))
- }
- }
-
- property("Prefixing should not be caused by nested Iterable[Iterable[Any]]") {
- class Test extends Module {
- {
- val iia = {
- val wire = Wire(UInt(3.W))
- List(List("Blah"))
- }
- }
- }
- aspectTest(() => new Test) { top: Test =>
- Select.wires(top).map(_.instanceName) should be(List("wire"))
- }
- }
-
- property("Prefixing should be caused by nested Iterable[Iterable[Data]]") {
- class Test extends Module {
- {
- val iia = {
- val wire = Wire(UInt(3.W))
- List(List(3.U))
- }
- }
- }
- aspectTest(() => new Test) { top: Test =>
- Select.wires(top).map(_.instanceName) should be(List("iia_wire"))
- }
- }
-
- property("Prefixing should NOT be influenced by suggestName") {
- class Test extends Module {
- {
- val wire = {
- val x = Wire(UInt(3.W)) // wire_x
- Wire(UInt(3.W)).suggestName("foo")
- }
- }
- }
- aspectTest(() => new Test) { top: Test =>
- Select.wires(top).map(_.instanceName) should be(List("wire_x", "foo"))
- }
- }
-
- property("Prefixing should be influenced by the \"current name\" of the signal") {
- class Test extends Module {
- {
- val wire = {
- val y = Wire(UInt(3.W)).suggestName("foo")
- val x = Wire(UInt(3.W)) // wire_x
- y
- }
-
- val wire2 = Wire(UInt(3.W))
- wire2 := {
- val x = Wire(UInt(3.W)) // wire2_x
- x + 1.U
- }
- wire2.suggestName("bar")
-
- val wire3 = Wire(UInt(3.W))
- wire3.suggestName("fizz")
- wire3 := {
- val x = Wire(UInt(3.W)) // fizz_x
- x + 1.U
- }
- }
- }
- aspectTest(() => new Test) { top: Test =>
- Select.wires(top).map(_.instanceName) should be(List("foo", "wire_x", "bar", "wire2_x", "fizz", "fizz_x"))
- }
- }
-
- property("Prefixing have intuitive behavior") {
- class Test extends Module {
- {
- val wire = {
- val x = Wire(UInt(3.W)).suggestName("mywire")
- val y = Wire(UInt(3.W)).suggestName("mywire2")
- y := x
- y
- }
- }
- }
- aspectTest(() => new Test) { top: Test =>
- Select.wires(top).map(_.instanceName) should be(List("wire_mywire", "mywire2"))
- }
- }
-
- property("Prefixing on connection to subfields work") {
- class Test extends Module {
- {
- val wire = Wire(new Bundle {
- val x = UInt(3.W)
- val y = UInt(3.W)
- val vec = Vec(4, UInt(3.W))
- })
- wire.x := RegNext(3.U)
- wire.y := RegNext(3.U)
- wire.vec(0) := RegNext(3.U)
- wire.vec(wire.x) := RegNext(3.U)
- wire.vec(1.U) := RegNext(3.U)
- }
- }
- aspectTest(() => new Test) { top: Test =>
- Select.registers(top).map(_.instanceName) should be(
- List(
- "wire_x_REG",
- "wire_y_REG",
- "wire_vec_0_REG",
- "wire_vec_REG",
- "wire_vec_1_REG"
- )
- )
- }
- }
-
- property("Prefixing on connection to IOs should work") {
- class Child extends Module {
- val in = IO(Input(UInt(3.W)))
- val out = IO(Output(UInt(3.W)))
- out := RegNext(in)
- }
- class Test extends Module {
- {
- val child = Module(new Child)
- child.in := RegNext(3.U)
- }
- }
- aspectTest(() => new Test) { top: Test =>
- Select.registers(top).map(_.instanceName) should be(
- List(
- "child_in_REG"
- )
- )
- Select.registers(Select.instances(top).head).map(_.instanceName) should be(
- List(
- "out_REG"
- )
- )
- }
- }
-
- property("Prefixing on bulk connects should work") {
- class Child extends Module {
- val in = IO(Input(UInt(3.W)))
- val out = IO(Output(UInt(3.W)))
- out := RegNext(in)
- }
- class Test extends Module {
- {
- val child = Module(new Child)
- child.in <> RegNext(3.U)
- }
- }
- aspectTest(() => new Test) { top: Test =>
- Select.registers(top).map(_.instanceName) should be(
- List(
- "child_in_REG"
- )
- )
- Select.registers(Select.instances(top).head).map(_.instanceName) should be(
- List(
- "out_REG"
- )
- )
- }
- }
-
- property("Connections should use the non-prefixed name of the connected Data") {
- class Test extends Module {
- prefix("foo") {
- val x = Wire(UInt(8.W))
- x := {
- val w = Wire(UInt(8.W))
- w := 3.U
- w + 1.U
- }
- }
- }
- aspectTest(() => new Test) { top: Test =>
- Select.wires(top).map(_.instanceName) should be(List("foo_x", "foo_x_w"))
- }
- }
-
- property("Connections to aggregate fields should use the non-prefixed aggregate name") {
- class Test extends Module {
- prefix("foo") {
- val x = Wire(new Bundle { val bar = UInt(8.W) })
- x.bar := {
- val w = Wire(new Bundle { val fizz = UInt(8.W) })
- w.fizz := 3.U
- w.fizz + 1.U
- }
- }
- }
- aspectTest(() => new Test) { top: Test =>
- Select.wires(top).map(_.instanceName) should be(List("foo_x", "foo_x_bar_w"))
- }
- }
-
- property("Prefixing with wires in recursive functions should grow linearly") {
- class Test extends Module {
- def func(bools: Seq[Bool]): Bool = {
- if (bools.isEmpty) true.B
- else {
- val w = Wire(Bool())
- w := bools.head && func(bools.tail)
- w
- }
- }
- val in = IO(Input(Vec(4, Bool())))
- val x = func(in)
- }
- aspectTest(() => new Test) { top: Test =>
- Select.wires(top).map(_.instanceName) should be(List("x", "x_w_w", "x_w_w_w", "x_w_w_w_w"))
- }
- }
-
- property("Prefixing should work for verification ops") {
- class Test extends Module {
- val foo, bar = IO(Input(UInt(8.W)))
-
- {
- val x5 = {
- val x1 = chisel3.assert(1.U === 1.U)
- val x2 = cover(foo =/= bar)
- val x3 = chisel3.assume(foo =/= 123.U)
- val x4 = printf("foo = %d\n", foo)
- x1
- }
- }
- }
- val chirrtl = ChiselStage.emitChirrtl(new Test)
- (chirrtl should include).regex("assert.*: x5")
- (chirrtl should include).regex("cover.*: x5_x2")
- (chirrtl should include).regex("assume.*: x5_x3")
- (chirrtl should include).regex("printf.*: x5_x4")
- }
-
- property("Leading '_' in val names should be ignored in prefixes") {
- class Test extends Module {
- {
- val a = {
- val _b = {
- val c = Wire(UInt(3.W))
- 4.U // literal because there is no name
- }
- _b
- }
- }
- }
- aspectTest(() => new Test) { top: Test =>
- Select.wires(top).map(_.instanceName) should be(List("a_b_c"))
- }
- }
-
- // This checks that we don't just blanket ignore leading _ in prefixes
- property("User-specified prefixes with '_' should be respected") {
- class Test extends Module {
- {
- val a = {
- val _b = prefix("_b") {
- val c = Wire(UInt(3.W))
- }
- 4.U
- }
- }
- }
- aspectTest(() => new Test) { top: Test =>
- Select.wires(top).map(_.instanceName) should be(List("a__b_c"))
- }
- }
-
- property("Leading '_' in signal names should be ignored in prefixes from connections") {
- class Test extends Module {
- {
- val a = {
- val b = {
- val _c = IO(Output(UInt(3.W))) // port so not selected as wire
- _c := {
- val d = Wire(UInt(3.W))
- d
- }
- 4.U // literal so there is no name
- }
- b
- }
- }
- }
- aspectTest(() => new Test) { top: Test =>
- Select.wires(top).map(_.instanceName) should be(List("a_b_c_d"))
- }
- }
-
- property("Prefixing of AffectsChiselPrefix objects should work") {
- class NotAData extends AffectsChiselPrefix {
- val value = Wire(UInt(3.W))
- }
- class NotADataUnprefixed {
- val value = Wire(UInt(3.W))
- }
- class Test extends Module {
- {
- val nonData = new NotAData
- // Instance name of nonData.value should be nonData_value
- nonData.value := RegNext(3.U)
-
- val nonData2 = new NotADataUnprefixed
- // Instance name of nonData2.value should be value
- nonData2.value := RegNext(3.U)
- }
- }
- aspectTest(() => new Test) { top: Test =>
- Select.wires(top).map(_.instanceName) should be(List("nonData_value", "value"))
- }
- }
- property("Prefixing should not be affected by repeated calls of suggestName") {
- class Test extends Module {
- val in = IO(Input(UInt(3.W)))
- val prefixed = {
- val wire = Wire(UInt(3.W)).suggestName("wire") // "prefixed_wire"
- wire := in
-
- val thisShouldNotBeHere = {
- // Second suggestName doesn't modify the instanceName since it was
- // already suggested, but also should not modify the prefix either
-
- // Incorrect behavior would rename the wire to
- // "prefixed_thisShouldNotBeHere_wire"
- wire.suggestName("wire")
-
- val out = IO(Output(UInt(3.W)))
- out := wire
- out
- }
- thisShouldNotBeHere
- }
- }
- aspectTest(() => new Test) { top: Test =>
- Select.wires(top).map(_.instanceName) should be(List("prefixed_wire"))
- }
- }
-}
diff --git a/src/test/scala/chiselTests/naming/ReflectiveNamingSpec.scala b/src/test/scala/chiselTests/naming/ReflectiveNamingSpec.scala
deleted file mode 100644
index baa991dd..00000000
--- a/src/test/scala/chiselTests/naming/ReflectiveNamingSpec.scala
+++ /dev/null
@@ -1,161 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.naming
-
-import chisel3._
-import chiselTests.{ChiselFlatSpec, Utils}
-
-class ReflectiveNamingSpec extends ChiselFlatSpec with Utils {
-
- behavior.of("Reflective naming")
-
- private def emitChirrtl(gen: => RawModule): String = {
- // Annoyingly need to emit files to use CLI
- val targetDir = createTestDirectory(this.getClass.getSimpleName).toString
- val args = Array("--warn:reflective-naming", "-td", targetDir)
- (new chisel3.stage.ChiselStage).emitChirrtl(gen, args)
- }
-
- it should "NOT warn when no names are changed" in {
- class Example extends Module {
- val foo, bar = IO(Input(UInt(8.W)))
- val out = IO(Output(UInt(8.W)))
-
- val sum = foo +& bar
- out := sum
- }
- val (log, chirrtl) = grabLog(emitChirrtl(new Example))
- log should equal("")
- chirrtl should include("node sum = add(foo, bar)")
- }
-
- it should "warn when changing the name of a node" in {
- class Example extends Module {
- val foo, bar = IO(Input(UInt(8.W)))
- val out = IO(Output(UInt(8.W)))
-
- val sum = foo +& bar
- val fuzz = sum
- out := sum
- }
- val (log, chirrtl) = grabLog(emitChirrtl(new Example))
- log should include("'sum' is renamed by reflection to 'fuzz'")
- chirrtl should include("node fuzz = add(foo, bar)")
- }
-
- // This also checks correct prefix reversing
- it should "warn when changing the name of a node with a prefix in the name" in {
- class Example extends Module {
- val foo, bar = IO(Input(UInt(8.W)))
- val out = IO(Output(UInt(8.W)))
-
- // This is sketch, don't do this
- var fuzz = 0.U
- out := {
- val sum = {
- val node = foo +& bar
- fuzz = node
- node +% 0.U
- }
- sum
- }
- }
- val (log, chirrtl) = grabLog(emitChirrtl(new Example))
- log should include("'out_sum_node' is renamed by reflection to 'fuzz'")
- chirrtl should include("node fuzz = add(foo, bar)")
- }
-
- it should "warn when changing the name of a Module instance" in {
- import chisel3.util._
- class Example extends Module {
- val enq = IO(Flipped(Decoupled(UInt(8.W))))
- val deq = IO(Decoupled(UInt(8.W)))
-
- val q = Module(new Queue(UInt(8.W), 4))
- q.io.enq <> enq
- deq <> q.io.deq
-
- val fuzz = q
- }
- val (log, chirrtl) = grabLog(emitChirrtl(new Example))
- log should include("'q' is renamed by reflection to 'fuzz'")
- chirrtl should include("inst fuzz of Queue")
- }
-
- it should "warn when changing the name of an Instance" in {
- import chisel3.experimental.hierarchy.{Definition, Instance}
- import chiselTests.experimental.hierarchy.Examples.AddOne
- class Example extends Module {
- val defn = Definition(new AddOne)
- val inst = Instance(defn)
- val fuzz = inst
- }
- val (log, chirrtl) = grabLog(emitChirrtl(new Example))
- log should include("'inst' is renamed by reflection to 'fuzz'")
- chirrtl should include("inst fuzz of AddOne")
- }
-
- it should "warn when changing the name of a Mem" in {
- class Example extends Module {
- val mem = SyncReadMem(8, UInt(8.W))
-
- val fuzz = mem
- }
- val (log, chirrtl) = grabLog(emitChirrtl(new Example))
- log should include("'mem' is renamed by reflection to 'fuzz'")
- chirrtl should include("smem fuzz")
- }
-
- it should "NOT warn when changing the name of a verification statement" in {
- class Example extends Module {
- val in = IO(Input(UInt(8.W)))
- val z = chisel3.assert(in =/= 123.U)
- val fuzz = z
- }
- val (log, chirrtl) = grabLog(emitChirrtl(new Example))
- log should equal("")
- // But the name is actually changed
- (chirrtl should include).regex("assert.*: fuzz")
- }
-
- it should "NOT warn when \"naming\" a literal" in {
- class Example extends Module {
- val out = IO(Output(UInt(8.W)))
-
- val sum = 0.U
- val fuzz = sum
- out := sum
- }
- val (log, chirrtl) = grabLog(emitChirrtl(new Example))
- log should equal("")
- chirrtl should include("out <= UInt")
- }
-
- it should "NOT warn when \"naming\" a field of an Aggregate" in {
- class Example extends Module {
- val io = IO(new Bundle {
- val in = Input(UInt(8.W))
- val out = Output(UInt(8.W))
- })
- val in = io.in
- val out = io.out
- out := in
- }
- val (log, chirrtl) = grabLog(emitChirrtl(new Example))
- log should equal("")
- chirrtl should include("io.out <= io.in")
- }
-
- it should "NOT warn when \"naming\" unbound Data" in {
- class Example extends Module {
- val in = IO(Input(UInt(8.W)))
- val out = IO(Output(UInt(8.W)))
- val z = UInt(8.W)
- val a = z
- out := in
- }
- val (log, chirrtl) = grabLog(emitChirrtl(new Example))
- log should equal("")
- chirrtl should include("out <= in")
- }
-}
diff --git a/src/test/scala/chiselTests/stage/ChiselAnnotationsSpec.scala b/src/test/scala/chiselTests/stage/ChiselAnnotationsSpec.scala
deleted file mode 100644
index 9dac820c..00000000
--- a/src/test/scala/chiselTests/stage/ChiselAnnotationsSpec.scala
+++ /dev/null
@@ -1,67 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.stage
-
-import chisel3._
-import chisel3.stage.{ChiselCircuitAnnotation, ChiselGeneratorAnnotation, DesignAnnotation}
-import firrtl.options.OptionsException
-import org.scalatest.flatspec.AnyFlatSpec
-import org.scalatest.matchers.should.Matchers
-
-class ChiselAnnotationsSpecFoo extends RawModule {
- val in = IO(Input(Bool()))
- val out = IO(Output(Bool()))
- out := ~in
-}
-
-class ChiselAnnotationsSpecBaz(name: String) extends ChiselAnnotationsSpecFoo {
- override val desiredName = name
-}
-
-class ChiselAnnotationsSpecQux extends ChiselAnnotationsSpecFoo {
- /* This printf requires an implicit clock and reset, but RawModule has none. This will thereby fail elaboration. */
- printf("hello")
-}
-
-class ChiselAnnotation
-
-class ChiselAnnotationsSpec extends AnyFlatSpec with Matchers {
-
- behavior.of("ChiselGeneratorAnnotation elaboration")
-
- it should "elaborate to a ChiselCircuitAnnotation" in {
- val annotation = ChiselGeneratorAnnotation(() => new ChiselAnnotationsSpecFoo)
- val res = annotation.elaborate
- res(0) shouldBe a[ChiselCircuitAnnotation]
- res(1) shouldBe a[DesignAnnotation[ChiselAnnotationsSpecFoo]]
- }
-
- it should "throw an exception if elaboration fails" in {
- val annotation = ChiselGeneratorAnnotation(() => new ChiselAnnotationsSpecQux)
- intercept[ChiselException] { annotation.elaborate }
- }
-
- behavior.of("ChiselGeneratorAnnotation when stringly constructing from Module names")
-
- it should "elaborate from a String" in {
- val annotation = ChiselGeneratorAnnotation("chiselTests.stage.ChiselAnnotationsSpecFoo")
- val res = annotation.elaborate
- res(0) shouldBe a[ChiselCircuitAnnotation]
- res(1) shouldBe a[DesignAnnotation[ChiselAnnotationsSpecFoo]]
- }
-
- it should "throw an exception if elaboration from a String refers to nonexistant class" in {
- val bar = "chiselTests.stage.ChiselAnnotationsSpecBar"
- val annotation = ChiselGeneratorAnnotation(bar)
- intercept[OptionsException] { annotation.elaborate }.getMessage should startWith(s"Unable to locate module '$bar'")
- }
-
- it should "throw an exception if elaboration from a String refers to an anonymous class" in {
- val baz = "chiselTests.stage.ChiselAnnotationsSpecBaz"
- val annotation = ChiselGeneratorAnnotation(baz)
- intercept[OptionsException] { annotation.elaborate }.getMessage should startWith(
- s"Unable to create instance of module '$baz'"
- )
- }
-
-}
diff --git a/src/test/scala/chiselTests/stage/ChiselMainSpec.scala b/src/test/scala/chiselTests/stage/ChiselMainSpec.scala
deleted file mode 100644
index e8773111..00000000
--- a/src/test/scala/chiselTests/stage/ChiselMainSpec.scala
+++ /dev/null
@@ -1,325 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.stage
-
-import chisel3._
-import chisel3.stage.ChiselMain
-import java.io.File
-
-import chisel3.aop.inspecting.{InspectingAspect, InspectorAspect}
-import org.scalatest.GivenWhenThen
-import org.scalatest.featurespec.AnyFeatureSpec
-import org.scalatest.matchers.should.Matchers
-import org.scalatest.Inside._
-import org.scalatest.EitherValues._
-
-import scala.io.Source
-import firrtl.Parser
-
-object ChiselMainSpec {
-
- /** A module that connects two different types together resulting in an elaboration error */
- class DifferentTypesModule extends RawModule {
- val in = IO(Input(UInt(1.W)))
- val out = IO(Output(SInt(1.W)))
- out := in
- }
-
- /** A module that connects two of the same types together */
- class SameTypesModule extends Module {
- val in = IO(Input(UInt(1.W)))
- val out = IO(Output(UInt(1.W)))
- out := in
- }
-
- /** A module that fails a requirement */
- class FailingRequirementModule extends RawModule {
- require(false, "the user wrote a failing requirement")
- }
-
- /** A module that triggers a Builder.error (as opposed to exception) */
- class BuilderErrorModule extends RawModule {
- val w = Wire(UInt(8.W))
- w(3, -1)
- }
-}
-
-case class TestClassAspect()
- extends InspectorAspect[RawModule]({ _: RawModule =>
- println("Ran inspectingAspect")
- })
-
-case object TestObjectAspect
- extends InspectorAspect[RawModule]({ _: RawModule =>
- println("Ran inspectingAspect")
- })
-
-class ChiselMainSpec extends AnyFeatureSpec with GivenWhenThen with Matchers with chiselTests.Utils {
-
- import ChiselMainSpec._
-
- class ChiselMainFixture {
- Given("a Chisel stage")
- val stage = ChiselMain
- }
-
- class TargetDirectoryFixture(dirName: String) {
- val dir = new File(s"test_run_dir/ChiselStageSpec/$dirName")
- val buildDir = new File(dir + "/build")
- dir.mkdirs()
- }
-
- case class ChiselMainTest(
- args: Array[String],
- generator: Option[Class[_ <: RawModule]] = None,
- files: Seq[String] = Seq.empty,
- stdout: Seq[Either[String, String]] = Seq.empty,
- stderr: Seq[Either[String, String]] = Seq.empty,
- result: Int = 0,
- fileChecks: Map[String, File => Unit] = Map.empty) {
- def testName: String = "args" + args.mkString("_")
- def argsString: String = args.mkString(" ")
- }
-
- /** A test of ChiselMain that is going to involve catching an exception.
- * @param args command line arguments (excluding --module) to pass in
- * @param generator the module to build (used to generate --module)
- * @param message snippets of text that should appear (Right) or not appear (Left) in the exception message
- * @param stdout snippets of text that should appear (Right) or not appear (Left) in STDOUT
- * @param stderr snippets of text that should appear (Right) or not appear (Left) in STDERR
- * @param stackTrace snippets of text that should appear (Right) or not appear (Left) in the stack trace
- * @tparam the type of exception that should occur
- */
- case class ChiselMainExceptionTest[A <: Throwable](
- args: Array[String],
- generator: Option[Class[_ <: RawModule]] = None,
- message: Seq[Either[String, String]] = Seq.empty,
- stdout: Seq[Either[String, String]] = Seq.empty,
- stderr: Seq[Either[String, String]] = Seq.empty,
- stackTrace: Seq[Either[String, String]] = Seq.empty) {
- def testName: String = "args" + args.mkString("_")
- def argsString: String = args.mkString(" ")
- }
-
- def runStageExpectFiles(p: ChiselMainTest): Unit = {
- Scenario(s"""User runs Chisel Stage with '${p.argsString}'""") {
- val f = new ChiselMainFixture
- val td = new TargetDirectoryFixture(p.testName)
-
- p.files.foreach(f => new File(td.buildDir + s"/$f").delete())
-
- When(s"""the user tries to compile with '${p.argsString}'""")
- val module: Array[String] =
- (if (p.generator.nonEmpty) { Array("--module", p.generator.get.getName) }
- else { Array.empty[String] })
- f.stage.main(Array("-td", td.buildDir.toString) ++ module ++ p.args)
- val (stdout, stderr, result) =
- grabStdOutErr {
- catchStatus {
- f.stage.main(Array("-td", td.buildDir.toString) ++ module ++ p.args)
- }
- }
-
- p.stdout.foreach {
- case Right(a) =>
- Then(s"""STDOUT should include "$a"""")
- stdout should include(a)
- case Left(a) =>
- Then(s"""STDOUT should not include "$a"""")
- (stdout should not).include(a)
- }
-
- p.stderr.foreach {
- case Right(a) =>
- Then(s"""STDERR should include "$a"""")
- stderr should include(a)
- case Left(a) =>
- Then(s"""STDERR should not include "$a"""")
- (stderr should not).include(a)
- }
-
- p.result match {
- case 0 =>
- And(s"the exit code should be 0")
- result shouldBe a[Right[_, _]]
- case a =>
- And(s"the exit code should be $a")
- result shouldBe (Left(a))
- }
-
- p.files.foreach { f =>
- And(s"file '$f' should be emitted in the target directory")
- val out = new File(td.buildDir + s"/$f")
- out should (exist)
- p.fileChecks.get(f).map(_(out))
- }
- }
- }
-
- /** Run a ChiselMainExceptionTest and verify that all the properties it spells out hold.
- * @param p the test to run
- * @tparam the type of the exception to catch (you shouldn't have to explicitly provide this)
- */
- def runStageExpectException[A <: Throwable: scala.reflect.ClassTag](p: ChiselMainExceptionTest[A]): Unit = {
- Scenario(s"""User runs Chisel Stage with '${p.argsString}'""") {
- val f = new ChiselMainFixture
- val td = new TargetDirectoryFixture(p.testName)
-
- When(s"""the user tries to compile with '${p.argsString}'""")
- val module: Array[String] =
- (if (p.generator.nonEmpty) { Array("--module", p.generator.get.getName) }
- else { Array.empty[String] })
- val (stdout, stderr, result) =
- grabStdOutErr {
- catchStatus {
- intercept[A] {
- f.stage.main(Array("-td", td.buildDir.toString) ++ module ++ p.args)
- }
- }
- }
-
- Then("the expected exception was thrown")
- (result should be).a('right)
- val exception = result.right.get
- info(s""" - Exception was a "${exception.getClass.getName}"""")
-
- val message = exception.getMessage
- p.message.foreach {
- case Right(a) =>
- Then(s"""STDOUT should include "$a"""")
- message should include(a)
- case Left(a) =>
- Then(s"""STDOUT should not include "$a"""")
- (message should not).include(a)
- }
-
- p.stdout.foreach {
- case Right(a) =>
- Then(s"""STDOUT should include "$a"""")
- stdout should include(a)
- case Left(a) =>
- Then(s"""STDOUT should not include "$a"""")
- (stdout should not).include(a)
- }
-
- p.stderr.foreach {
- case Right(a) =>
- Then(s"""STDERR should include "$a"""")
- stderr should include(a)
- case Left(a) =>
- Then(s"""STDERR should not include "$a"""")
- (stderr should not).include(a)
- }
-
- val stackTraceString = exception.getStackTrace.mkString("\n")
- p.stackTrace.foreach {
- case Left(a) =>
- And(s"""the stack does not include "$a"""")
- (stackTraceString should not).include(a)
- case Right(a) =>
- And(s"""the stack trace includes "$a"""")
- stackTraceString should include(a)
- }
-
- }
- }
-
- info("As a Chisel user")
- info("I compile a design")
- Feature("show elaborating message") {
- runStageExpectFiles(
- ChiselMainTest(args = Array("-X", "high"), generator = Some(classOf[SameTypesModule]))
- )
- }
-
- info("I screw up and compile some bad code")
- Feature("Stack trace trimming of ChiselException") {
- Seq(
- ChiselMainExceptionTest[chisel3.internal.ChiselException](
- args = Array("-X", "low"),
- generator = Some(classOf[DifferentTypesModule]),
- stackTrace = Seq(Left("java"), Right(classOf[DifferentTypesModule].getName))
- ),
- ChiselMainExceptionTest[chisel3.internal.ChiselException](
- args = Array("-X", "low", "--full-stacktrace"),
- generator = Some(classOf[DifferentTypesModule]),
- stackTrace = Seq(Right("java"), Right(classOf[DifferentTypesModule].getName))
- )
- ).foreach(runStageExpectException)
- }
- Feature("Stack trace trimming of user exceptions") {
- Seq(
- ChiselMainExceptionTest[java.lang.IllegalArgumentException](
- args = Array("-X", "low"),
- generator = Some(classOf[FailingRequirementModule]),
- stackTrace = Seq(Right(classOf[FailingRequirementModule].getName), Left("java"))
- ),
- ChiselMainExceptionTest[java.lang.IllegalArgumentException](
- args = Array("-X", "low", "--full-stacktrace"),
- generator = Some(classOf[FailingRequirementModule]),
- stackTrace = Seq(Right(classOf[FailingRequirementModule].getName), Right("java"))
- )
- ).foreach(runStageExpectException)
- }
- Feature("Stack trace trimming and Builder.error errors") {
- Seq(
- ChiselMainExceptionTest[chisel3.internal.ChiselException](
- args = Array("-X", "low"),
- generator = Some(classOf[BuilderErrorModule]),
- message = Seq(Right("Fatal errors during hardware elaboration")),
- stdout = Seq(
- Right(
- "ChiselMainSpec.scala:43: Invalid bit range (3,-1) in class chiselTests.stage.ChiselMainSpec$BuilderErrorModule"
- )
- )
- )
- ).foreach(runStageExpectException)
- }
-
- Feature("Specifying a custom output file") {
- runStageExpectFiles(
- ChiselMainTest(
- args = Array("--chisel-output-file", "Foo", "--no-run-firrtl"),
- generator = Some(classOf[SameTypesModule]),
- files = Seq("Foo.fir"),
- fileChecks = Map(
- "Foo.fir" -> { file =>
- And("It should be valid FIRRTL")
- Parser.parse(Source.fromFile(file).mkString)
- }
- )
- )
- )
- runStageExpectFiles(
- ChiselMainTest(
- args = Array("--chisel-output-file", "Foo.pb", "--no-run-firrtl"),
- generator = Some(classOf[SameTypesModule]),
- files = Seq("Foo.pb"),
- fileChecks = Map(
- "Foo.pb" -> { file =>
- And("It should be valid ProtoBuf")
- firrtl.proto.FromProto.fromFile(file.toString)
- }
- )
- )
- )
- }
-
- info("As an aspect writer")
- info("I write an aspect")
- Feature("Running aspects via the command line") {
- Seq(
- ChiselMainTest(
- args = Array("-X", "high", "--with-aspect", "chiselTests.stage.TestClassAspect"),
- generator = Some(classOf[SameTypesModule]),
- stdout = Seq(Right("Ran inspectingAspect"))
- ),
- ChiselMainTest(
- args = Array("-X", "high", "--with-aspect", "chiselTests.stage.TestObjectAspect"),
- generator = Some(classOf[SameTypesModule]),
- stdout = Seq(Right("Ran inspectingAspect"))
- )
- ).foreach(runStageExpectFiles)
- }
-
-}
diff --git a/src/test/scala/chiselTests/stage/ChiselOptionsViewSpec.scala b/src/test/scala/chiselTests/stage/ChiselOptionsViewSpec.scala
deleted file mode 100644
index b164ff20..00000000
--- a/src/test/scala/chiselTests/stage/ChiselOptionsViewSpec.scala
+++ /dev/null
@@ -1,41 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.stage
-
-import firrtl.options.Viewer.view
-import firrtl.RenameMap
-
-import chisel3.stage._
-import chisel3.internal.firrtl.Circuit
-import org.scalatest.flatspec.AnyFlatSpec
-import org.scalatest.matchers.should.Matchers
-
-class ChiselOptionsViewSpec extends AnyFlatSpec with Matchers {
-
- behavior.of(ChiselOptionsView.getClass.getName)
-
- it should "construct a view from an AnnotationSeq" in {
- val bar = Circuit("bar", Seq.empty, Seq.empty, RenameMap())
- val annotations = Seq(
- NoRunFirrtlCompilerAnnotation,
- PrintFullStackTraceAnnotation,
- ChiselOutputFileAnnotation("foo"),
- ChiselCircuitAnnotation(bar)
- )
- val out = view[ChiselOptions](annotations)
-
- info("runFirrtlCompiler was set to false")
- out.runFirrtlCompiler should be(false)
-
- info("printFullStackTrace was set to true")
- out.printFullStackTrace should be(true)
-
- info("outputFile was set to 'foo'")
- out.outputFile should be(Some("foo"))
-
- info("chiselCircuit was set to circuit 'bar'")
- out.chiselCircuit should be(Some(bar))
-
- }
-
-}
diff --git a/src/test/scala/chiselTests/stage/ChiselStageSpec.scala b/src/test/scala/chiselTests/stage/ChiselStageSpec.scala
deleted file mode 100644
index f0f383da..00000000
--- a/src/test/scala/chiselTests/stage/ChiselStageSpec.scala
+++ /dev/null
@@ -1,293 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.stage
-
-import chisel3._
-import chisel3.stage.ChiselStage
-import chisel3.testers.TesterDriver.createTestDirectory
-
-import chiselTests.Utils
-
-import org.scalatest.flatspec.AnyFlatSpec
-import org.scalatest.matchers.should.Matchers
-
-import firrtl.options.Dependency
-
-object ChiselStageSpec {
-
- class Bar extends Module {
- val in = IO(Input(UInt(4.W)))
- val out = IO(Output(UInt(4.W)))
- out := ~in
- }
-
- class Foo extends Module {
- val addr = IO(Input(UInt(4.W)))
- val out = IO(Output(Bool()))
- val memory = SyncReadMem(8, Bool())
- val bar = Module(new Bar)
- bar.in := addr
- out := memory(bar.out)
- }
-
- class UserExceptionModule extends RawModule {
- assert(false, "User threw an exception")
- }
-
- class UserExceptionNoStackTrace extends RawModule {
- throw new Exception("Something bad happened") with scala.util.control.NoStackTrace
- }
-
- class RecoverableError extends RawModule {
- 3.U >> -1
- }
-
-}
-
-class ChiselStageSpec extends AnyFlatSpec with Matchers with Utils {
-
- import ChiselStageSpec._
-
- private trait ChiselStageFixture {
- val stage = new ChiselStage
- }
-
- behavior.of("ChiselStage$.emitChirrtl")
-
- it should "return a CHIRRTL string" in {
- ChiselStage.emitChirrtl(new Foo) should include("infer mport")
- }
-
- behavior.of("ChiselStage$.emitFirrtl")
-
- it should "return a High FIRRTL string" in {
- ChiselStage.emitFirrtl(new Foo) should include("mem memory")
- }
-
- it should "return a flattened FIRRTL string with '-e high'" in {
- val args = Array("-e", "high", "-td", createTestDirectory(this.getClass.getSimpleName).toString)
- (new ChiselStage)
- .emitFirrtl(new Foo, args) should include("module Bar")
- }
-
- behavior.of("ChiselStage$.emitVerilog")
-
- it should "return a Verilog string" in {
- ChiselStage.emitVerilog(new Foo) should include("endmodule")
- }
-
- it should "return a flattened Verilog string with '-e verilog'" in {
- val args = Array("-e", "verilog", "-td", createTestDirectory(this.getClass.getSimpleName).toString)
- (new ChiselStage)
- .emitVerilog(new Foo, args) should include("module Bar")
- }
-
- behavior.of("ChiselStage$.elaborate")
-
- ignore should "generate a Chisel circuit from a Chisel module" in {
- info("no files were written")
- catchWrites { ChiselStage.elaborate(new Foo) } shouldBe a[Right[_, _]]
- }
-
- behavior.of("ChiselStage$.convert")
-
- ignore should "generate a CHIRRTL circuit from a Chisel module" in {
- info("no files were written")
- catchWrites { ChiselStage.convert(new Foo) } shouldBe a[Right[_, _]]
- }
-
- ignore should "generate a FIRRTL circuit from a CHIRRTL circuit" in {
- info("no files were written")
- catchWrites {
- ChiselStage.convert(ChiselStage.elaborate(new Foo))
- } shouldBe a[Right[_, _]]
- }
-
- behavior.of("ChiselStage$.emitChirrtl")
-
- ignore should "generate a CHIRRTL string from a Chisel module" in {
- val wrapped = catchWrites { ChiselStage.emitChirrtl(new Foo) }
-
- info("no files were written")
- wrapped shouldBe a[Right[_, _]]
-
- info("returned string looks like FIRRTL")
- wrapped.right.get should include("circuit")
- }
-
- behavior.of("ChiselStage$.emitFirrtl")
-
- ignore should "generate a FIRRTL string from a Chisel module" in {
- val wrapped = catchWrites { ChiselStage.emitFirrtl(new Foo) }
-
- info("no files were written")
- wrapped shouldBe a[Right[_, _]]
-
- info("returned string looks like FIRRTL")
- wrapped.right.get should include("circuit")
- }
-
- behavior.of("ChiselStage$.emitVerilog")
-
- ignore should "generate a Verilog string from a Chisel module" in {
- val wrapped = catchWrites { ChiselStage.emitVerilog(new Foo) }
-
- info("no files were written")
- wrapped shouldBe a[Right[_, _]]
-
- info("returned string looks like Verilog")
- wrapped.right.get should include("endmodule")
- }
-
- behavior.of("ChiselStage$.emitSystemVerilog")
-
- ignore should "generate a SystemvVerilog string from a Chisel module" in {
- val wrapped = catchWrites { ChiselStage.emitSystemVerilog(new Foo) }
- info("no files were written")
- wrapped shouldBe a[Right[_, _]]
-
- info("returned string looks like Verilog")
- wrapped.right.get should include("endmodule")
- }
-
- behavior.of("ChiselStage phase ordering")
-
- it should "only run elaboration once" in new ChiselStageFixture {
- info("Phase order is:\n" + stage.phaseManager.prettyPrint(" "))
-
- val order = stage.phaseManager.flattenedTransformOrder.map(Dependency.fromTransform)
-
- info("Elaborate only runs once")
- exactly(1, order) should be(Dependency[chisel3.stage.phases.Elaborate])
- }
-
- behavior.of("ChiselStage$ exception handling")
-
- it should "truncate a user exception" in {
- info("The user's java.lang.AssertionError was thrown")
- val exception = intercept[java.lang.AssertionError] {
- ChiselStage.emitChirrtl(new UserExceptionModule)
- }
-
- val message = exception.getMessage
- info("The exception includes the user's message")
- message should include("User threw an exception")
-
- info("The stack trace is trimmed")
- (exception.getStackTrace.mkString("\n") should not).include("java")
- }
-
- it should "NOT add a stack trace to an exception with no stack trace" in {
- val exception = intercept[java.lang.Exception] {
- ChiselStage.emitChirrtl(new UserExceptionNoStackTrace)
- }
-
- val message = exception.getMessage
- info("The exception includes the user's message")
- message should include("Something bad happened")
-
- info("The exception should not contain a stack trace")
- exception.getStackTrace should be(Array())
- }
-
- it should "NOT include a stack trace for recoverable errors" in {
- val exception = intercept[java.lang.Exception] {
- ChiselStage.emitChirrtl(new RecoverableError)
- }
-
- val message = exception.getMessage
- info("The exception includes the standard error message")
- message should include("Fatal errors during hardware elaboration. Look above for error list.")
-
- info("The exception should not contain a stack trace")
- exception.getStackTrace should be(Array())
- }
-
- behavior.of("ChiselStage exception handling")
-
- it should "truncate a user exception" in {
- info("The user's java.lang.AssertionError was thrown")
- val exception = intercept[java.lang.AssertionError] {
- (new ChiselStage).emitChirrtl(new UserExceptionModule)
- }
-
- info(s""" - Exception was a ${exception.getClass.getName}""")
-
- val message = exception.getMessage
- info("The exception includes the user's message")
- message should include("User threw an exception")
-
- val stackTrace = exception.getStackTrace.mkString("\n")
- info("The stack trace is trimmed")
- (stackTrace should not).include("java")
-
- info("The stack trace include information about running --full-stacktrace")
- stackTrace should include("--full-stacktrace")
- }
-
- it should """not truncate a user exception with "--full-stacktrace"""" in {
- info("The user's java.lang.AssertionError was thrown")
- val exception = intercept[java.lang.AssertionError] {
- (new ChiselStage).emitChirrtl(new UserExceptionModule, Array("--full-stacktrace"))
- }
-
- info(s""" - Exception was a ${exception.getClass.getName}""")
-
- val message = exception.getMessage
- info("The exception includes the user's message")
- message should include("User threw an exception")
-
- info("The stack trace is not trimmed")
- exception.getStackTrace.mkString("\n") should include("java")
- }
-
- it should "NOT add a stack trace to an exception with no stack trace" in {
- val exception = intercept[java.lang.Exception] {
- (new ChiselStage).emitChirrtl(new UserExceptionNoStackTrace)
- }
-
- val message = exception.getMessage
- info("The exception includes the user's message")
- message should include("Something bad happened")
-
- info("The exception should not contain a stack trace")
- exception.getStackTrace should be(Array())
- }
-
- it should "NOT include a stack trace for recoverable errors" in {
- val exception = intercept[java.lang.Exception] {
- (new ChiselStage).emitChirrtl(new RecoverableError)
- }
-
- val message = exception.getMessage
- info("The exception includes the standard error message")
- message should include("Fatal errors during hardware elaboration. Look above for error list.")
-
- info("The exception should not contain a stack trace")
- exception.getStackTrace should be(Array())
- }
-
- it should "include a stack trace for recoverable errors with '--throw-on-first-error'" in {
- val exception = intercept[java.lang.Exception] {
- (new ChiselStage).emitChirrtl(new RecoverableError, Array("--throw-on-first-error"))
- }
-
- val stackTrace = exception.getStackTrace.mkString("\n")
- info("The exception should contain a truncated stack trace")
- stackTrace shouldNot include("java")
-
- info("The stack trace include information about running --full-stacktrace")
- stackTrace should include("--full-stacktrace")
- }
-
- it should "include an untruncated stack trace for recoverable errors when given both '--throw-on-first-error' and '--full-stacktrace'" in {
- val exception = intercept[java.lang.Exception] {
- val args = Array("--throw-on-first-error", "--full-stacktrace")
- (new ChiselStage).emitChirrtl(new RecoverableError, args)
- }
-
- val stackTrace = exception.getStackTrace.mkString("\n")
- info("The exception should contain a truncated stack trace")
- stackTrace should include("java")
- }
-}
diff --git a/src/test/scala/chiselTests/stage/phases/AddImplicitOutputAnnotationFileSpec.scala b/src/test/scala/chiselTests/stage/phases/AddImplicitOutputAnnotationFileSpec.scala
deleted file mode 100644
index faf411ed..00000000
--- a/src/test/scala/chiselTests/stage/phases/AddImplicitOutputAnnotationFileSpec.scala
+++ /dev/null
@@ -1,41 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.stage.phases
-
-import chisel3.RawModule
-import chisel3.stage.ChiselGeneratorAnnotation
-import chisel3.stage.phases.{AddImplicitOutputAnnotationFile, Elaborate}
-
-import firrtl.AnnotationSeq
-import firrtl.options.{OutputAnnotationFileAnnotation, Phase}
-import org.scalatest.flatspec.AnyFlatSpec
-import org.scalatest.matchers.should.Matchers
-
-class AddImplicitOutputAnnotationFileSpec extends AnyFlatSpec with Matchers {
-
- class Foo extends RawModule { override val desiredName = "Foo" }
-
- class Fixture { val phase: Phase = new AddImplicitOutputAnnotationFile }
-
- behavior.of(classOf[AddImplicitOutputAnnotationFile].toString)
-
- it should "not override an existing OutputAnnotationFileAnnotation" in new Fixture {
- val annotations: AnnotationSeq =
- Seq(ChiselGeneratorAnnotation(() => new Foo), OutputAnnotationFileAnnotation("Bar"))
-
- Seq(new Elaborate, phase)
- .foldLeft(annotations)((a, p) => p.transform(a))
- .collect { case a: OutputAnnotationFileAnnotation => a.file }
- .toSeq should be(Seq("Bar"))
- }
-
- it should "generate an OutputAnnotationFileAnnotation from a ChiselCircuitAnnotation" in new Fixture {
- val annotations: AnnotationSeq = Seq(ChiselGeneratorAnnotation(() => new Foo))
-
- Seq(new Elaborate, phase)
- .foldLeft(annotations)((a, p) => p.transform(a))
- .collect { case a: OutputAnnotationFileAnnotation => a.file }
- .toSeq should be(Seq("Foo"))
- }
-
-}
diff --git a/src/test/scala/chiselTests/stage/phases/AddImplicitOutputFileSpec.scala b/src/test/scala/chiselTests/stage/phases/AddImplicitOutputFileSpec.scala
deleted file mode 100644
index 20274e7a..00000000
--- a/src/test/scala/chiselTests/stage/phases/AddImplicitOutputFileSpec.scala
+++ /dev/null
@@ -1,45 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.stage.phases
-
-import chisel3.RawModule
-import chisel3.stage.{ChiselGeneratorAnnotation, ChiselOutputFileAnnotation}
-import chisel3.stage.phases.{AddImplicitOutputFile, Elaborate}
-
-import firrtl.AnnotationSeq
-import firrtl.options.{Phase, StageOptions, TargetDirAnnotation}
-import firrtl.options.Viewer.view
-import org.scalatest.flatspec.AnyFlatSpec
-import org.scalatest.matchers.should.Matchers
-
-class AddImplicitOutputFileSpec extends AnyFlatSpec with Matchers {
-
- class Foo extends RawModule { override val desiredName = "Foo" }
-
- class Fixture { val phase: Phase = new AddImplicitOutputFile }
-
- behavior.of(classOf[AddImplicitOutputFile].toString)
-
- it should "not override an existing ChiselOutputFileAnnotation" in new Fixture {
- val annotations: AnnotationSeq = Seq(ChiselGeneratorAnnotation(() => new Foo), ChiselOutputFileAnnotation("Bar"))
-
- Seq(new Elaborate, phase)
- .foldLeft(annotations)((a, p) => p.transform(a))
- .collect { case a: ChiselOutputFileAnnotation => a.file }
- .toSeq should be(Seq("Bar"))
- }
-
- it should "generate a ChiselOutputFileAnnotation from a ChiselCircuitAnnotation" in new Fixture {
- val annotations: AnnotationSeq = Seq(ChiselGeneratorAnnotation(() => new Foo), TargetDirAnnotation("test_run_dir"))
-
- Seq(new Elaborate, phase)
- .foldLeft(annotations)((a, p) => p.transform(a))
- .collect { case a: ChiselOutputFileAnnotation => a.file }
- .toSeq should be(Seq("Foo"))
- }
-
- it should "do nothing to an empty annotation sequence" in new Fixture {
- phase.transform(AnnotationSeq(Seq.empty)).toSeq should be(empty)
- }
-
-}
diff --git a/src/test/scala/chiselTests/stage/phases/AddSerializationAnnotationsSpec.scala b/src/test/scala/chiselTests/stage/phases/AddSerializationAnnotationsSpec.scala
deleted file mode 100644
index 57633eac..00000000
--- a/src/test/scala/chiselTests/stage/phases/AddSerializationAnnotationsSpec.scala
+++ /dev/null
@@ -1,55 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.stage.phases
-
-import chisel3.RawModule
-import chisel3.stage.{ChiselGeneratorAnnotation, ChiselOutputFileAnnotation, CircuitSerializationAnnotation}
-import chisel3.stage.CircuitSerializationAnnotation._
-import chisel3.stage.phases.{AddImplicitOutputFile, AddSerializationAnnotations, Elaborate}
-
-import firrtl.AnnotationSeq
-import firrtl.options.{Dependency, Phase, PhaseManager, TargetDirAnnotation}
-import firrtl.options.Viewer.view
-import org.scalatest.flatspec.AnyFlatSpec
-import org.scalatest.matchers.should.Matchers
-
-class AddSerializationAnnotationsSpec extends AnyFlatSpec with Matchers {
-
- class Foo extends RawModule { override val desiredName = "Foo" }
-
- class Fixture {
- val phase: Phase = new AddSerializationAnnotations
- val manager = new PhaseManager(Dependency[AddSerializationAnnotations] :: Nil)
- }
-
- behavior.of(classOf[AddSerializationAnnotations].toString)
-
- it should "default to FirrtlFileFormat" in new Fixture {
- val annotations: AnnotationSeq = Seq(ChiselGeneratorAnnotation(() => new Foo), ChiselOutputFileAnnotation("Bar"))
-
- manager
- .transform(annotations)
- .collect { case CircuitSerializationAnnotation(_, filename, format) => (filename, format) }
- .toSeq should be(Seq(("Bar", FirrtlFileFormat)))
- }
-
- it should "support ProtoBufFileFormat" in new Fixture {
- val annotations: AnnotationSeq = Seq(ChiselGeneratorAnnotation(() => new Foo), ChiselOutputFileAnnotation("Bar.pb"))
-
- manager
- .transform(annotations)
- .collect { case CircuitSerializationAnnotation(_, filename, format) => (filename, format) }
- .toSeq should be(Seq(("Bar", ProtoBufFileFormat)))
- }
-
- it should "support explicitly asking for FirrtlFileFormat" in new Fixture {
- val annotations: AnnotationSeq =
- Seq(ChiselGeneratorAnnotation(() => new Foo), ChiselOutputFileAnnotation("Bar.pb.fir"))
-
- manager
- .transform(annotations)
- .collect { case CircuitSerializationAnnotation(_, filename, format) => (filename, format) }
- .toSeq should be(Seq(("Bar.pb", FirrtlFileFormat)))
- }
-
-}
diff --git a/src/test/scala/chiselTests/stage/phases/ChecksSpec.scala b/src/test/scala/chiselTests/stage/phases/ChecksSpec.scala
deleted file mode 100644
index 3d42efdd..00000000
--- a/src/test/scala/chiselTests/stage/phases/ChecksSpec.scala
+++ /dev/null
@@ -1,43 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.stage.phases
-
-import chisel3.stage.{ChiselOutputFileAnnotation, NoRunFirrtlCompilerAnnotation, PrintFullStackTraceAnnotation}
-import chisel3.stage.phases.Checks
-
-import firrtl.AnnotationSeq
-import firrtl.annotations.NoTargetAnnotation
-import firrtl.options.{OptionsException, Phase}
-import org.scalatest.flatspec.AnyFlatSpec
-import org.scalatest.matchers.should.Matchers
-
-class ChecksSpec extends AnyFlatSpec with Matchers {
-
- def checkExceptionMessage(phase: Phase, annotations: AnnotationSeq, messageStart: String): Unit =
- intercept[OptionsException] { phase.transform(annotations) }.getMessage should startWith(messageStart)
-
- class Fixture { val phase: Phase = new Checks }
-
- behavior.of(classOf[Checks].toString)
-
- it should "do nothing on sane annotation sequences" in new Fixture {
- val a = Seq(NoRunFirrtlCompilerAnnotation, PrintFullStackTraceAnnotation)
- phase.transform(a).toSeq should be(a)
- }
-
- it should "throw an OptionsException if more than one NoRunFirrtlCompilerAnnotation is specified" in new Fixture {
- val a = Seq(NoRunFirrtlCompilerAnnotation, NoRunFirrtlCompilerAnnotation)
- checkExceptionMessage(phase, a, "At most one NoRunFirrtlCompilerAnnotation")
- }
-
- it should "throw an OptionsException if more than one PrintFullStackTraceAnnotation is specified" in new Fixture {
- val a = Seq(PrintFullStackTraceAnnotation, PrintFullStackTraceAnnotation)
- checkExceptionMessage(phase, a, "At most one PrintFullStackTraceAnnotation")
- }
-
- it should "throw an OptionsException if more than one ChiselOutputFileAnnotation is specified" in new Fixture {
- val a = Seq(ChiselOutputFileAnnotation("foo"), ChiselOutputFileAnnotation("bar"))
- checkExceptionMessage(phase, a, "At most one Chisel output file")
- }
-
-}
diff --git a/src/test/scala/chiselTests/stage/phases/ConvertSpec.scala b/src/test/scala/chiselTests/stage/phases/ConvertSpec.scala
deleted file mode 100644
index 46a2994b..00000000
--- a/src/test/scala/chiselTests/stage/phases/ConvertSpec.scala
+++ /dev/null
@@ -1,65 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.stage.phases
-
-import chisel3._
-import chisel3.experimental.{ChiselAnnotation, RunFirrtlTransform}
-import chisel3.stage.ChiselGeneratorAnnotation
-import chisel3.stage.phases.{Convert, Elaborate}
-
-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 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
-}
-
-case class ConvertSpecFirrtlAnnotation(name: String) extends NoTargetAnnotation
-
-case class ConvertSpecChiselAnnotation(name: String) extends ChiselAnnotation with RunFirrtlTransform {
- def toFirrtl: Annotation = ConvertSpecFirrtlAnnotation(name)
- def transformClass: Class[_ <: Transform] = classOf[ConvertSpecFirrtlTransform]
-}
-
-class ConvertSpecFoo extends RawModule {
- override val desiredName: String = "foo"
-
- val in = IO(Input(Bool()))
- val out = IO(Output(Bool()))
-
- experimental.annotate(ConvertSpecChiselAnnotation("bar"))
-}
-
-class ConvertSpec extends AnyFlatSpec with Matchers {
-
- class Fixture { val phase: Phase = new Convert }
-
- behavior.of(classOf[Convert].toString)
-
- it should "convert a Chisel Circuit to a FIRRTL Circuit" in new Fixture {
- val annos: AnnotationSeq = Seq(ChiselGeneratorAnnotation(() => new ConvertSpecFoo))
-
- val annosx = Seq(new Elaborate, phase)
- .foldLeft(annos)((a, p) => p.transform(a))
-
- info("FIRRTL circuit generated")
- annosx.collect { case a: FirrtlCircuitAnnotation => a.circuit.main }.toSeq should be(Seq("foo"))
-
- info("FIRRTL annotations generated")
- annosx.collect { case a: ConvertSpecFirrtlAnnotation => a.name }.toSeq should be(Seq("bar"))
-
- info("FIRRTL transform annotations generated")
- annosx.collect { case a: RunFirrtlTransformAnnotation => a.transform.getClass }.toSeq should be(
- Seq(classOf[ConvertSpecFirrtlTransform])
- )
- }
-
-}
diff --git a/src/test/scala/chiselTests/stage/phases/ElaborateSpec.scala b/src/test/scala/chiselTests/stage/phases/ElaborateSpec.scala
deleted file mode 100644
index 90bb229b..00000000
--- a/src/test/scala/chiselTests/stage/phases/ElaborateSpec.scala
+++ /dev/null
@@ -1,44 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.stage.phases
-
-import chisel3._
-import chisel3.stage.{ChiselCircuitAnnotation, ChiselGeneratorAnnotation}
-import chisel3.stage.phases.Elaborate
-
-import firrtl.options.Phase
-import org.scalatest.flatspec.AnyFlatSpec
-import org.scalatest.matchers.should.Matchers
-
-class ElaborateSpec extends AnyFlatSpec with Matchers {
-
- class Foo extends Module {
- override def desiredName: String = "Foo"
- val io = IO(new Bundle {
- val in = Input(Bool())
- val out = Output(Bool())
- })
-
- io.out := ~io.in
- }
-
- class Bar extends Foo {
- override def desiredName: String = "Bar"
- }
-
- class Fixture { val phase: Phase = new Elaborate }
-
- behavior.of(classOf[Elaborate].toString)
-
- it should "expand ChiselGeneratorAnnotations into ChiselCircuitAnnotations and delete originals" in new Fixture {
- val annotations = Seq(ChiselGeneratorAnnotation(() => new Foo), ChiselGeneratorAnnotation(() => new Bar))
- val out = phase.transform(annotations)
-
- info("original annotations removed")
- out.collect { case a: ChiselGeneratorAnnotation => a } should be(empty)
-
- info("circuits created with the expected names")
- out.collect { case a: ChiselCircuitAnnotation => a.circuit.name } should be(Seq("Foo", "Bar"))
- }
-
-}
diff --git a/src/test/scala/chiselTests/stage/phases/EmitterSpec.scala b/src/test/scala/chiselTests/stage/phases/EmitterSpec.scala
deleted file mode 100644
index 9b7d4f42..00000000
--- a/src/test/scala/chiselTests/stage/phases/EmitterSpec.scala
+++ /dev/null
@@ -1,59 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.stage.phases
-
-import chisel3.RawModule
-import chisel3.stage.{ChiselCircuitAnnotation, ChiselGeneratorAnnotation, ChiselOutputFileAnnotation}
-import chisel3.stage.phases.{Convert, Elaborate, Emitter}
-
-import firrtl.{AnnotationSeq, EmittedFirrtlCircuitAnnotation}
-import firrtl.annotations.DeletedAnnotation
-import firrtl.options.{Phase, TargetDirAnnotation}
-
-import java.io.File
-import org.scalatest.flatspec.AnyFlatSpec
-import org.scalatest.matchers.should.Matchers
-
-class EmitterSpec extends AnyFlatSpec with Matchers {
-
- class FooModule extends RawModule { override val desiredName = "Foo" }
- class BarModule extends RawModule { override val desiredName = "Bar" }
-
- class Fixture { val phase: Phase = new Emitter }
-
- behavior.of(classOf[Emitter].toString)
-
- it should "do nothing if no ChiselOutputFileAnnotations are present" in new Fixture {
- val dir = new File("test_run_dir/EmitterSpec")
- val annotations =
- (new Elaborate).transform(Seq(TargetDirAnnotation(dir.toString), ChiselGeneratorAnnotation(() => new FooModule)))
- val annotationsx = phase.transform(annotations)
-
- val Seq(fooFile, barFile) = Seq("Foo.fir", "Bar.fir").map(f => new File(dir + "/" + f))
-
- info(s"$fooFile does not exist")
- fooFile should not(exist)
-
- info("annotations are unmodified")
- annotationsx.toSeq should be(annotations.toSeq)
- }
-
- it should "emit a ChiselCircuitAnnotation to a specific file" in new Fixture {
- val dir = new File("test_run_dir/EmitterSpec")
- val circuit = (new Elaborate)
- .transform(Seq(ChiselGeneratorAnnotation(() => new BarModule)))
- .collectFirst { case a: ChiselCircuitAnnotation => a }
- .get
- val annotations =
- phase.transform(Seq(TargetDirAnnotation(dir.toString), circuit, ChiselOutputFileAnnotation("Baz")))
-
- val bazFile = new File(dir + "/Baz.fir")
-
- info(s"$bazFile exists")
- bazFile should (exist)
-
- info("a deleted EmittedFirrtlCircuitAnnotation should be generated")
- annotations.collect { case a @ DeletedAnnotation(_, _: EmittedFirrtlCircuitAnnotation) => a }.size should be(1)
- }
-
-}
diff --git a/src/test/scala/chiselTests/util/BitPatSpec.scala b/src/test/scala/chiselTests/util/BitPatSpec.scala
deleted file mode 100644
index 38ffc3ba..00000000
--- a/src/test/scala/chiselTests/util/BitPatSpec.scala
+++ /dev/null
@@ -1,51 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.util
-
-import chisel3.util.BitPat
-import org.scalatest.flatspec.AnyFlatSpec
-import org.scalatest.matchers.should.Matchers
-
-class BitPatSpec extends AnyFlatSpec with Matchers {
- behavior.of(classOf[BitPat].toString)
-
- it should "convert a BitPat to readable form" in {
- val testPattern = "0" * 32 + "1" * 32 + "?" * 32 + "?01" * 32
- BitPat("b" + testPattern).toString should be(s"BitPat($testPattern)")
- }
-
- it should "convert a BitPat to raw form" in {
- val testPattern = "0" * 32 + "1" * 32 + "?" * 32 + "?01" * 32
- BitPat("b" + testPattern).rawString should be(testPattern)
- }
-
- it should "not fail if BitPat width is 0" in {
- intercept[IllegalArgumentException] { BitPat("b") }
- }
-
- it should "concat BitPat via ##" in {
- (BitPat.Y(4) ## BitPat.dontCare(3) ## BitPat.N(2)).toString should be(s"BitPat(1111???00)")
- }
-
- it should "throw when BitPat apply to a Hardware" in {
- intercept[java.lang.IllegalArgumentException] {
- chisel3.stage.ChiselStage.emitChirrtl(new chisel3.Module {
- BitPat(chisel3.Reg(chisel3.Bool()))
- })
- }
- }
-
- it should "index and return new BitPat" in {
- val b = BitPat("b1001???")
- b(0) should be(BitPat.dontCare(1))
- b(6) should be(BitPat.Y())
- b(5) should be(BitPat.N())
- }
-
- it should "slice and return new BitPat" in {
- val b = BitPat("b1001???")
- b(2, 0) should be(BitPat("b???"))
- b(4, 3) should be(BitPat("b01"))
- b(6, 6) should be(BitPat("b1"))
- }
-}
diff --git a/src/test/scala/chiselTests/util/BitSetSpec.scala b/src/test/scala/chiselTests/util/BitSetSpec.scala
deleted file mode 100644
index cf5f54cf..00000000
--- a/src/test/scala/chiselTests/util/BitSetSpec.scala
+++ /dev/null
@@ -1,145 +0,0 @@
-package chiselTests.util
-
-import chisel3.util.experimental.BitSet
-import chisel3.util.BitPat
-import org.scalatest.flatspec.AnyFlatSpec
-import org.scalatest.matchers.should.Matchers
-
-class BitSetSpec extends AnyFlatSpec with Matchers {
- behavior.of(classOf[BitSet].toString)
-
- it should "reject unequal width when constructing a BitSet" in {
- intercept[IllegalArgumentException] {
- BitSet.fromString("""b0010
- |b00010
- |""".stripMargin)
- }
- }
-
- it should "return empty subtraction result correctly" in {
- val aBitPat = BitPat("b10?")
- val bBitPat = BitPat("b1??")
-
- aBitPat.subtract(bBitPat).isEmpty should be(true)
- }
-
- it should "return nonempty subtraction result correctly" in {
- val aBitPat = BitPat("b10?")
- val bBitPat = BitPat("b1??")
- val cBitPat = BitPat("b11?")
- val dBitPat = BitPat("b100")
-
- val diffBitPat = bBitPat.subtract(aBitPat)
- bBitPat.cover(diffBitPat) should be(true)
- diffBitPat.equals(cBitPat) should be(true)
-
- val largerdiffBitPat = bBitPat.subtract(dBitPat)
- aBitPat.cover(dBitPat) should be(true)
- largerdiffBitPat.cover(diffBitPat) should be(true)
- }
-
- it should "be able to handle complex subtract between BitSet" in {
- val aBitSet = BitSet.fromString("""b?01?0
- |b11111
- |b00000
- |""".stripMargin)
- val bBitSet = BitSet.fromString(
- """b?1111
- |b?0000
- |""".stripMargin
- )
- val expected = BitPat("b?01?0")
-
- expected.equals(aBitSet.subtract(bBitSet)) should be(true)
- }
-
- it should "be generated from BitPat union" in {
- val aBitSet = BitSet.fromString("""b001?0
- |b000??""".stripMargin)
- val aBitPat = BitPat("b000??")
- val bBitPat = BitPat("b001?0")
- val cBitPat = BitPat("b00000")
- aBitPat.cover(cBitPat) should be(true)
- aBitSet.cover(bBitPat) should be(true)
-
- aBitSet.equals(aBitPat.union(bBitPat)) should be(true)
- }
-
- it should "be generated from BitPat subtraction" in {
- val aBitSet = BitSet.fromString("""b001?0
- |b000??""".stripMargin)
- val aBitPat = BitPat("b00???")
- val bBitPat = BitPat("b001?1")
-
- aBitSet.equals(aBitPat.subtract(bBitPat)) should be(true)
- }
-
- it should "union two BitSet together" in {
- val aBitSet = BitSet.fromString("""b001?0
- |b001?1
- |""".stripMargin)
- val bBitSet = BitSet.fromString(
- """b000??
- |b01???
- |""".stripMargin
- )
- val cBitPat = BitPat("b0????")
- cBitPat.equals(aBitSet.union(bBitSet)) should be(true)
- }
-
- it should "be decoded" in {
- import chisel3._
- import chisel3.util.experimental.decode.decoder
- // [0 - 256] part into: [0 - 31], [32 - 47, 64 - 127], [192 - 255]
- // "0011????" "10??????" is empty to error
- chisel3.stage.ChiselStage.emitSystemVerilog(new Module {
- val in = IO(Input(UInt(8.W)))
- val out = IO(Output(UInt(4.W)))
- out := decoder.bitset(
- in,
- Seq(
- BitSet.fromString(
- "b000?????"
- ),
- BitSet.fromString(
- """b0010????
- |b01??????
- |""".stripMargin
- ),
- BitSet.fromString(
- "b11??????"
- )
- ),
- errorBit = true
- )
- })
- }
-
- it should "be decoded with DontCare error" in {
- import chisel3._
- import chisel3.util.experimental.decode.decoder
- // [0 - 256] part into: [0 - 31], [32 - 47, 64 - 127], [192 - 255]
- // "0011????" "10??????" is empty to error
- chisel3.stage.ChiselStage.emitSystemVerilog(new Module {
- val in = IO(Input(UInt(8.W)))
- val out = IO(Output(UInt(4.W)))
- out := decoder.bitset(
- in,
- Seq(
- BitSet.fromString(
- "b000?????"
- ),
- BitSet.fromString(
- """b0010????
- |b01??????
- |""".stripMargin
- ),
- BitSet.fromString(
- "b11??????"
- )
- ),
- errorBit = false
- )
- })
- }
-}
diff --git a/src/test/scala/chiselTests/util/CatSpec.scala b/src/test/scala/chiselTests/util/CatSpec.scala
deleted file mode 100644
index a75c4ec0..00000000
--- a/src/test/scala/chiselTests/util/CatSpec.scala
+++ /dev/null
@@ -1,63 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.util
-
-import chisel3._
-import chisel3.stage.ChiselStage
-import chisel3.util.Cat
-import chisel3.experimental.noPrefix
-
-import chiselTests.ChiselFlatSpec
-
-object CatSpec {
-
- class JackIsATypeSystemGod extends Module {
- val in = IO(Input(Vec(0, UInt(8.W))))
- val out = IO(Output(UInt(8.W)))
-
- out := Cat(in)
- }
-
-}
-
-class CatSpec extends ChiselFlatSpec {
-
- import CatSpec._
-
- behavior.of("util.Cat")
-
- it should "not fail to elaborate a zero-element Vec" in {
-
- ChiselStage.elaborate(new JackIsATypeSystemGod)
-
- }
-
- it should "not override the names of its arguments" in {
- class MyModule extends RawModule {
- val a, b, c, d = IO(Input(UInt(8.W)))
- val out = IO(Output(UInt()))
-
- out := Cat(a, b, c, d)
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- for (name <- Seq("a", "b", "c", "d")) {
- chirrtl should include(s"input $name : UInt<8>")
- }
- }
-
- it should "have prefixed naming" in {
- class MyModule extends RawModule {
- val in = IO(Input(Vec(8, UInt(8.W))))
- val out = IO(Output(UInt()))
-
- // noPrefix to avoid `out` as prefix
- out := noPrefix(Cat(in))
- }
- val chirrtl = ChiselStage.emitChirrtl(new MyModule)
- chirrtl should include("node lo_lo = cat(in[6], in[7])")
- chirrtl should include("node lo_hi = cat(in[4], in[5])")
- chirrtl should include("node hi_lo = cat(in[2], in[3])")
- chirrtl should include("node hi_hi = cat(in[0], in[1])")
- }
-
-}
diff --git a/src/test/scala/chiselTests/util/PriorityMuxSpec.scala b/src/test/scala/chiselTests/util/PriorityMuxSpec.scala
deleted file mode 100644
index 32cf2431..00000000
--- a/src/test/scala/chiselTests/util/PriorityMuxSpec.scala
+++ /dev/null
@@ -1,60 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.util
-
-import chisel3._
-import chisel3.util.{is, switch, Counter, PriorityMux}
-import chisel3.testers.BasicTester
-import chisel3.stage.ChiselStage.emitChirrtl
-
-import chiselTests.ChiselFlatSpec
-
-class PriorityMuxTester extends BasicTester {
-
- val sel = Wire(UInt(3.W))
- sel := 0.U // default
-
- val elts = Seq(5.U, 6.U, 7.U)
- val muxed = PriorityMux(sel, elts)
-
- // Priority is given to lowest order bit
- val tests = Seq(
- 1.U -> elts(0),
- 2.U -> elts(1),
- 3.U -> elts(0),
- 4.U -> elts(2),
- 5.U -> elts(0),
- 6.U -> elts(1),
- 7.U -> elts(0)
- )
- val (cycle, done) = Counter(0 until tests.size + 1)
-
- for (((in, out), idx) <- tests.zipWithIndex) {
- when(cycle === idx.U) {
- sel := in
- assert(muxed === out)
- }
- }
-
- when(done) {
- stop()
- }
-}
-
-class PriorityMuxSpec extends ChiselFlatSpec {
- behavior.of("PriorityMux")
-
- it should "be functionally correct" in {
- assertTesterPasses(new PriorityMuxTester)
- }
-
- it should "be stack safe" in {
- emitChirrtl(new RawModule {
- val n = 1 << 15
- val in = IO(Input(Vec(n, UInt(8.W))))
- val sel = IO(Input(UInt(n.W)))
- val out = IO(Output(UInt(8.W)))
- out := PriorityMux(sel, in)
- })
- }
-}
diff --git a/src/test/scala/chiselTests/util/experimental/PlaSpec.scala b/src/test/scala/chiselTests/util/experimental/PlaSpec.scala
deleted file mode 100644
index 156249a2..00000000
--- a/src/test/scala/chiselTests/util/experimental/PlaSpec.scala
+++ /dev/null
@@ -1,111 +0,0 @@
-package chiselTests.util.experimental
-
-import chisel3._
-import chisel3.stage.PrintFullStackTraceAnnotation
-import chisel3.testers.BasicTester
-import chisel3.util.{pla, BitPat}
-import chiselTests.ChiselFlatSpec
-
-class PlaSpec extends ChiselFlatSpec {
- "A 1-of-8 decoder (eg. 74xx138 without enables)" should "be generated correctly" in {
- assertTesterPasses(new BasicTester {
- val table = Seq(
- (BitPat("b000"), BitPat("b00000001")),
- (BitPat("b001"), BitPat("b00000010")),
- (BitPat("b010"), BitPat("b00000100")),
- (BitPat("b011"), BitPat("b00001000")),
- (BitPat("b100"), BitPat("b00010000")),
- (BitPat("b101"), BitPat("b00100000")),
- (BitPat("b110"), BitPat("b01000000")),
- (BitPat("b111"), BitPat("b10000000"))
- )
- table.foreach {
- case (i, o) =>
- val (plaIn, plaOut) = pla(table)
- plaIn := WireDefault(i.value.U(3.W))
- chisel3.assert(
- plaOut === o.value.U(8.W),
- "Input " + i.toString + " produced incorrect output BitPat(%b)",
- plaOut
- )
- }
- stop()
- })
- }
-
- "An active-low 1-of-8 decoder (eg. inverted 74xx138 without enables)" should "be generated correctly" in {
- assertTesterPasses(new BasicTester {
- val table = Seq(
- (BitPat("b000"), BitPat("b00000001")),
- (BitPat("b001"), BitPat("b00000010")),
- (BitPat("b010"), BitPat("b00000100")),
- (BitPat("b011"), BitPat("b00001000")),
- (BitPat("b100"), BitPat("b00010000")),
- (BitPat("b101"), BitPat("b00100000")),
- (BitPat("b110"), BitPat("b01000000")),
- (BitPat("b111"), BitPat("b10000000"))
- )
- table.foreach {
- case (i, o) =>
- val (plaIn, plaOut) = pla(table, BitPat("b11111111"))
- plaIn := WireDefault(i.value.U(3.W))
- chisel3.assert(
- plaOut === ~o.value.U(8.W),
- "Input " + i.toString + " produced incorrect output BitPat(%b)",
- plaOut
- )
- }
- stop()
- })
- }
-
- "#2112" should "be generated correctly" in {
- assertTesterPasses(new BasicTester {
- val table = Seq(
- (BitPat("b000"), BitPat("b?01")),
- (BitPat("b111"), BitPat("b?01"))
- )
- table.foreach {
- case (i, o) =>
- val (plaIn, plaOut) = pla(table)
- plaIn := WireDefault(i.value.U(3.W))
- chisel3.assert(o === plaOut, "Input " + i.toString + " produced incorrect output BitPat(%b)", plaOut)
- }
- stop()
- })
- }
-
- "A simple PLA" should "be generated correctly" in {
- assertTesterPasses(new BasicTester {
- val table = Seq(
- (BitPat("b0000"), BitPat("b1")),
- (BitPat("b0001"), BitPat("b1")),
- (BitPat("b0010"), BitPat("b0")),
- (BitPat("b0011"), BitPat("b1")),
- (BitPat("b0100"), BitPat("b1")),
- (BitPat("b0101"), BitPat("b0")),
- (BitPat("b0110"), BitPat("b0")),
- (BitPat("b0111"), BitPat("b0")),
- (BitPat("b1000"), BitPat("b0")),
- (BitPat("b1001"), BitPat("b0")),
- (BitPat("b1010"), BitPat("b1")),
- (BitPat("b1011"), BitPat("b0")),
- (BitPat("b1100"), BitPat("b0")),
- (BitPat("b1101"), BitPat("b1")),
- (BitPat("b1110"), BitPat("b1")),
- (BitPat("b1111"), BitPat("b1"))
- )
- table.foreach {
- case (i, o) =>
- val (plaIn, plaOut) = pla(table)
- plaIn := WireDefault(i.value.U(4.W))
- chisel3.assert(
- plaOut === o.value.U(1.W),
- "Input " + i.toString + " produced incorrect output BitPat(%b)",
- plaOut
- )
- }
- stop()
- })
- }
-}
diff --git a/src/test/scala/chiselTests/util/experimental/TruthTableSpec.scala b/src/test/scala/chiselTests/util/experimental/TruthTableSpec.scala
deleted file mode 100644
index b5dcee6b..00000000
--- a/src/test/scala/chiselTests/util/experimental/TruthTableSpec.scala
+++ /dev/null
@@ -1,126 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.util.experimental
-
-import chisel3._
-import chisel3.util.BitPat
-import chisel3.util.experimental.decode.{decoder, TruthTable}
-import org.scalatest.flatspec.AnyFlatSpec
-
-class TruthTableSpec extends AnyFlatSpec {
- val table = TruthTable(
- Map(
- // BitPat("b000") -> BitPat("b0"),
- BitPat("b001") -> BitPat("b?"),
- BitPat("b010") -> BitPat("b?"),
- // BitPat("b011") -> BitPat("b0"),
- BitPat("b100") -> BitPat("b1"),
- BitPat("b101") -> BitPat("b1"),
- // BitPat("b110") -> BitPat("b0"),
- BitPat("b111") -> BitPat("b1")
- ),
- BitPat("b0")
- )
- val str = """001->?
- |010->?
- |100->1
- |101->1
- |111->1
- |0""".stripMargin
- "TruthTable" should "serialize" in {
- assert(table.toString contains "001->?")
- assert(table.toString contains "010->?")
- assert(table.toString contains "100->1")
- assert(table.toString contains "111->1")
- assert(table.toString contains " 0")
- }
- "TruthTable" should "deserialize" in {
- val table2 = TruthTable.fromString(str)
- assert(table2 === table)
- assert(table2.hashCode === table.hashCode)
- }
- "TruthTable" should "merge same key" in {
- assert(
- TruthTable.fromString(
- """001100->??1
- |001100->1??
- |???
- |""".stripMargin
- ) == TruthTable.fromString(
- """001100->1?1
- |???
- |""".stripMargin
- )
- )
- }
- "TruthTable" should "crash when merging 0 and 1" in {
- intercept[IllegalArgumentException] {
- TruthTable.fromString(
- """0->0
- |0->1
- |???
- |""".stripMargin
- )
- }
- }
- "TruthTable" should "be reproducible" in {
- class Foo extends Module {
-
- val io = IO(new Bundle {
- val in = Input(UInt(4.W))
- val out = Output(UInt(16.W))
- })
-
- val table = TruthTable(
- (0 until 16).map { i =>
- BitPat(i.U(4.W)) -> BitPat((1 << i).U(16.W))
- },
- BitPat.dontCare(16)
- )
-
- io.out := decoder.qmc(io.in, table)
- }
- assert(chisel3.stage.ChiselStage.emitChirrtl(new Foo) == chisel3.stage.ChiselStage.emitChirrtl(new Foo))
- }
- "TruthTable" should "accept unknown input width" in {
- val t = TruthTable(
- Seq(
- BitPat(0.U) -> BitPat.dontCare(1),
- BitPat(1.U) -> BitPat.dontCare(1),
- BitPat(2.U) -> BitPat.dontCare(1),
- BitPat(3.U) -> BitPat.dontCare(1),
- BitPat(4.U) -> BitPat.dontCare(1),
- BitPat(5.U) -> BitPat.dontCare(1),
- BitPat(6.U) -> BitPat.dontCare(1),
- BitPat(7.U) -> BitPat.dontCare(1)
- ),
- BitPat.N(1)
- )
- assert(t.toString contains "000->?")
- assert(t.toString contains "001->?")
- assert(t.toString contains "010->?")
- assert(t.toString contains "011->?")
- assert(t.toString contains "100->?")
- assert(t.toString contains "101->?")
- assert(t.toString contains "110->?")
- assert(t.toString contains "111->?")
- assert(t.toString contains " 0")
- }
-
- "Using TruthTable.fromEspressoOutput" should "merge rows on conflict" in {
- val mapping = List(
- (BitPat("b110"), BitPat("b001")),
- (BitPat("b111"), BitPat("b001")),
- (BitPat("b111"), BitPat("b010")),
- (BitPat("b111"), BitPat("b100"))
- )
-
- assert(
- TruthTable.fromEspressoOutput(mapping, BitPat("b?")) ==
- TruthTable.fromString("""110->001
- |111->111
- |?
- |""".stripMargin)
- )
- }
-}
diff --git a/src/test/scala/chiselTests/util/random/LFSRSpec.scala b/src/test/scala/chiselTests/util/random/LFSRSpec.scala
deleted file mode 100644
index d47c2d7d..00000000
--- a/src/test/scala/chiselTests/util/random/LFSRSpec.scala
+++ /dev/null
@@ -1,182 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests.util.random
-
-import chisel3._
-import chisel3.stage.ChiselStage
-import chisel3.util.{Cat, Counter, Enum}
-import chisel3.util.random._
-import chisel3.testers.{BasicTester, TesterDriver}
-import chiselTests.{ChiselFlatSpec, Utils}
-
-import math.pow
-
-class FooLFSR(val reduction: LFSRReduce, seed: Option[BigInt]) extends PRNG(4, seed) with LFSR {
- def delta(s: Seq[Bool]): Seq[Bool] = s
-}
-
-class LFSRMaxPeriod(gen: => UInt) extends BasicTester {
-
- val rv = gen
- val started = RegNext(true.B, false.B)
- val seed = withReset(!started) { RegInit(rv) }
-
- val (_, wrap) = Counter(started, math.pow(2.0, rv.getWidth).toInt - 1)
-
- when(rv === seed && started) {
- chisel3.assert(wrap)
- stop()
- }
-
- val last = RegNext(rv)
- chisel3.assert(rv =/= last, "LFSR last value (0b%b) was equal to current value (0b%b)", rv, last)
-
-}
-
-/**
- * This test creates two 4 sided dice.
- * Each cycle it adds them together and adds a count to the bin corresponding to that value
- * The asserts check that the bins show the correct distribution.
- */
-class LFSRDistribution(gen: => UInt, cycles: Int = 10000) extends BasicTester {
-
- val rv = gen
- val bins = Reg(Vec(8, UInt(32.W)))
-
- // Use tap points on each LFSR so values are more independent
- val die0 = Cat(Seq.tabulate(2) { i => rv(i) })
- val die1 = Cat(Seq.tabulate(2) { i => rv(i + 2) })
-
- val (trial, done) = Counter(true.B, cycles)
-
- val rollValue = die0 +& die1 // Note +& is critical because sum will need an extra bit.
-
- bins(rollValue) := bins(rollValue) + 1.U
-
- when(done) {
- printf(p"bins: $bins\n") // Note using the printable interpolator p"" to print out a Vec
-
- // test that the distribution feels right.
- assert(bins(1) > bins(0))
- assert(bins(2) > bins(1))
- assert(bins(3) > bins(2))
- assert(bins(4) < bins(3))
- assert(bins(5) < bins(4))
- assert(bins(6) < bins(5))
- assert(bins(7) === 0.U)
-
- stop()
- }
-}
-
-/** This tests that after reset an LFSR is not locked up. This manually sets the seed of the LFSR at run-time to the
- * value that would cause it to lock up. It then asserts reset. The next cycle it checks that the value is NOT the
- * locked up value.
- * @param gen an LFSR to test
- * @param lockUpValue the value that would lock up the LFSR
- */
-class LFSRResetTester(gen: => LFSR, lockUpValue: BigInt) extends BasicTester {
-
- val lfsr = Module(gen)
- lfsr.io.seed.valid := false.B
- lfsr.io.seed.bits := DontCare
- lfsr.io.increment := true.B
-
- val (count, done) = Counter(true.B, 5)
-
- lfsr.io.seed.valid := count === 1.U
- lfsr.io.seed.bits := lockUpValue.U(lfsr.width.W).asBools
- lfsr.io.increment := true.B
-
- when(count === 2.U) {
- assert(lfsr.io.out.asUInt === lockUpValue.U, "LFSR is NOT locked up, but should be!")
- }
-
- lfsr.reset := count === 3.U
-
- when(count === 4.U) {
- assert(lfsr.io.out.asUInt =/= lockUpValue.U, "LFSR is locked up, but should not be after reset!")
- }
-
- when(done) {
- stop()
- }
-
-}
-
-class LFSRSpec extends ChiselFlatSpec with Utils {
-
- def periodCheck(gen: (Int, Set[Int], LFSRReduce) => PRNG, reduction: LFSRReduce, range: Range): Unit = {
- val testName = s"have a maximal period over a range of widths (${range.head} to ${range.last})" +
- s" using ${reduction.getClass}"
- it should testName in {
- range.foreach { width =>
- LFSR.tapsMaxPeriod(width).foreach { taps =>
- info(s"""width $width okay using taps: ${taps.mkString(", ")}""")
- assertTesterPasses(
- new LFSRMaxPeriod(PRNG(gen(width, taps, reduction))),
- annotations = TesterDriver.verilatorOnly
- )
- }
- }
- }
- }
-
- behavior.of("LFSR")
-
- it should "throw an exception if initialized to a seed of zero for XOR configuration" in {
- {
- 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 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 {
- assertTesterPasses(new LFSRResetTester(new FooLFSR(XOR, None), 0))
- }
-
- it should "reset correctly without a seed for XNOR configuration" in {
- assertTesterPasses(new LFSRResetTester(new FooLFSR(XNOR, None), 15))
- }
-
- behavior.of("MaximalPeriodGaloisLFSR")
-
- it should "throw an exception if no LFSR taps are known" in {
- {
- 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)
- periodCheck((w: Int, t: Set[Int], r: LFSRReduce) => new GaloisLFSR(w, t, reduction = r), XNOR, 2 to 16)
-
- ignore should "have a sane distribution for larger widths" in {
- ((17 to 32) ++ Seq(64, 128, 256, 512, 1024, 2048, 4096)).foreach { width =>
- info(s"width $width okay!")
- assertTesterPasses(new LFSRDistribution(LFSR(width), math.pow(2, 22).toInt))
- }
- }
-
- behavior.of("MaximalPeriodFibonacciLFSR")
-
- periodCheck((w: Int, t: Set[Int], r: LFSRReduce) => new FibonacciLFSR(w, t, reduction = r), XOR, 2 to 16)
- periodCheck((w: Int, t: Set[Int], r: LFSRReduce) => new FibonacciLFSR(w, t, reduction = r), XNOR, 2 to 16)
-
- behavior.of("LFSR maximal period taps")
-
- it should "contain all the expected widths" in {
- ((2 to 786) ++ Seq(1024, 2048, 4096)).foreach(LFSR.tapsMaxPeriod.keys should contain(_))
- }
-
-}
diff --git a/src/test/scala/chiselTests/util/random/PRNGSpec.scala b/src/test/scala/chiselTests/util/random/PRNGSpec.scala
deleted file mode 100644
index 36fdf9cb..00000000
--- a/src/test/scala/chiselTests/util/random/PRNGSpec.scala
+++ /dev/null
@@ -1,97 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-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, Utils}
-
-class CyclePRNG(width: Int, seed: Option[BigInt], step: Int, updateSeed: Boolean)
- extends PRNG(width, seed, step, updateSeed) {
-
- def delta(s: Seq[Bool]): Seq[Bool] = s.last +: s.dropRight(1)
-
-}
-
-class PRNGStepTest extends BasicTester {
-
- val count2: UInt = Counter(true.B, 2)._1
- val count4: UInt = Counter(true.B, 4)._1
-
- val a: UInt = PRNG(new CyclePRNG(16, Some(1), 1, false), true.B)
- val b: UInt = PRNG(new CyclePRNG(16, Some(1), 2, false), count2 === 1.U)
- val c: UInt = PRNG(new CyclePRNG(16, Some(1), 4, false), count4 === 3.U)
-
- val (_, done) = Counter(true.B, 16)
-
- when(count2 === 0.U) {
- assert(a === b, "1-step and 2-step PRNGs did not agree! (0b%b != 0b%b)", a, b)
- }
-
- when(count4 === 0.U) {
- assert(a === c, "1-step and 4-step PRNGs did not agree!")
- }
-
- when(done) {
- stop()
- }
-
-}
-
-class PRNGUpdateSeedTest(updateSeed: Boolean, seed: BigInt, expected: BigInt) extends BasicTester {
-
- val a: CyclePRNG = Module(new CyclePRNG(16, Some(1), 1, updateSeed))
-
- val (count, done) = Counter(true.B, 4)
-
- a.io.increment := true.B
- a.io.seed.valid := count === 2.U
- a.io.seed.bits := seed.U(a.width.W).asBools
-
- when(count === 3.U) {
- assert(a.io.out.asUInt === expected.U, "Output didn't match!")
- }
-
- when(done) {
- stop()
- }
-
-}
-
-class PRNGSpec extends ChiselFlatSpec with Utils {
-
- behavior.of("PRNG")
-
- it should "throw an exception if the step size is < 1" in {
- {
- 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 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 {
- assertTesterPasses(new PRNGStepTest)
- }
-
- it should "handle state update without and with updateSeed enabled" in {
- info("without updateSeed okay!")
- assertTesterPasses(new PRNGUpdateSeedTest(false, 3, 3))
-
- info("with updateSeed okay!")
- assertTesterPasses(new PRNGUpdateSeedTest(true, 3, 6))
- }
-
-}
diff --git a/src/test/scala/cookbook/Bundle2UInt.scala b/src/test/scala/cookbook/Bundle2UInt.scala
deleted file mode 100644
index 21d06df7..00000000
--- a/src/test/scala/cookbook/Bundle2UInt.scala
+++ /dev/null
@@ -1,31 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package cookbook
-
-import chisel3._
-
-/* ### How do I create a UInt from an instance of a Bundle?
- *
- * Call asUInt on the Bundle instance
- */
-class Bundle2UInt extends CookbookTester(1) {
- // Example
- class MyBundle extends Bundle {
- val foo = UInt(4.W)
- val bar = UInt(4.W)
- }
- val bundle = Wire(new MyBundle)
- bundle.foo := 0xc.U
- bundle.bar := 0x3.U
- val uint = bundle.asUInt
- printf(p"$uint") // 195
-
- // Test
- assert(uint === 0xc3.U)
-}
-
-class Bundle2UIntSpec extends CookbookSpec {
- "Bundle2UInt" should "work" in {
- assertTesterPasses { new Bundle2UInt }
- }
-}
diff --git a/src/test/scala/cookbook/CookbookSpec.scala b/src/test/scala/cookbook/CookbookSpec.scala
deleted file mode 100644
index 7d6c9726..00000000
--- a/src/test/scala/cookbook/CookbookSpec.scala
+++ /dev/null
@@ -1,22 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package cookbook
-
-import chisel3._
-import chisel3.util._
-import chisel3.testers.BasicTester
-
-import chiselTests.ChiselFlatSpec
-
-/** Tester for concise cookbook tests
- *
- * Provides a length of test after which the test will pass
- */
-abstract class CookbookTester(length: Int) extends BasicTester {
- require(length >= 0, "Simulation length must be non-negative!")
-
- val (cycle, done) = Counter(true.B, length + 1) // + 1 cycle because done is actually wrap
- when(done) { stop() }
-}
-
-abstract class CookbookSpec extends ChiselFlatSpec
diff --git a/src/test/scala/cookbook/FSM.scala b/src/test/scala/cookbook/FSM.scala
deleted file mode 100644
index 40f8abc7..00000000
--- a/src/test/scala/cookbook/FSM.scala
+++ /dev/null
@@ -1,66 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package cookbook
-
-import chisel3._
-import chisel3.util._
-
-/* ### How do I create a finite state machine?
- *
- * Use ChiselEnum to construct the states and switch & is to construct the FSM
- * control logic
- */
-
-class DetectTwoOnes extends Module {
- val io = IO(new Bundle {
- val in = Input(Bool())
- val out = Output(Bool())
- })
-
- object State extends ChiselEnum {
- val sNone, sOne1, sTwo1s = Value
- }
-
- val state = RegInit(State.sNone)
-
- io.out := (state === State.sTwo1s)
-
- switch(state) {
- is(State.sNone) {
- when(io.in) {
- state := State.sOne1
- }
- }
- is(State.sOne1) {
- when(io.in) {
- state := State.sTwo1s
- }.otherwise {
- state := State.sNone
- }
- }
- is(State.sTwo1s) {
- when(!io.in) {
- state := State.sNone
- }
- }
- }
-}
-
-class DetectTwoOnesTester extends CookbookTester(10) {
-
- val dut = Module(new DetectTwoOnes)
-
- // Inputs and expected results
- val inputs: Vec[Bool] = VecInit(false.B, true.B, false.B, true.B, true.B, true.B, false.B, true.B, true.B, false.B)
- val expected: Vec[Bool] =
- VecInit(false.B, false.B, false.B, false.B, false.B, true.B, true.B, false.B, false.B, true.B)
-
- dut.io.in := inputs(cycle)
- assert(dut.io.out === expected(cycle))
-}
-
-class FSMSpec extends CookbookSpec {
- "DetectTwoOnes" should "work" in {
- assertTesterPasses { new DetectTwoOnesTester }
- }
-}
diff --git a/src/test/scala/cookbook/RegOfVec.scala b/src/test/scala/cookbook/RegOfVec.scala
deleted file mode 100644
index ddb615c7..00000000
--- a/src/test/scala/cookbook/RegOfVec.scala
+++ /dev/null
@@ -1,33 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package cookbook
-
-import chisel3._
-
-/* ### How do I create a Reg of type Vec?
- *
- * For information, please see the API documentation for Vec
- * (https://chisel.eecs.berkeley.edu/api/index.html#chisel3.Vec)
- */
-class RegOfVec extends CookbookTester(2) {
- // Reg of Vec of 32-bit UInts without initialization
- val regOfVec = Reg(Vec(4, UInt(32.W)))
- regOfVec(0) := 123.U // a couple of assignments
- regOfVec(2) := regOfVec(0)
-
- // Reg of Vec of 32-bit UInts initialized to zero
- // Note that Seq.fill constructs 4 32-bit UInt literals with the value 0
- // Vec(...) then constructs a Wire of these literals
- // The Reg is then initialized to the value of the Wire (which gives it the same type)
- val initRegOfVec = RegInit(VecInit(Seq.fill(4)(0.U(32.W))))
-
- // Simple test (cycle comes from superclass)
- when(cycle === 2.U) { assert(regOfVec(2) === 123.U) }
- for (elt <- initRegOfVec) { assert(elt === 0.U) }
-}
-
-class RegOfVecSpec extends CookbookSpec {
- "RegOfVec" should "work" in {
- assertTesterPasses { new RegOfVec }
- }
-}
diff --git a/src/test/scala/cookbook/UInt2Bundle.scala b/src/test/scala/cookbook/UInt2Bundle.scala
deleted file mode 100644
index f5180c90..00000000
--- a/src/test/scala/cookbook/UInt2Bundle.scala
+++ /dev/null
@@ -1,30 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package cookbook
-
-import chisel3._
-
-/* ### How do I create a Bundle from a UInt?
- *
- * On an instance of the Bundle, call the method fromBits with the UInt as the argument
- */
-class UInt2Bundle extends CookbookTester(1) {
- // Example
- class MyBundle extends Bundle {
- val foo = UInt(4.W)
- val bar = UInt(4.W)
- }
- val uint = 0xb4.U
- val bundle = uint.asTypeOf(new MyBundle)
- printf(p"$bundle") // Bundle(foo -> 11, bar -> 4)
-
- // Test
- assert(bundle.foo === 0xb.U)
- assert(bundle.bar === 0x4.U)
-}
-
-class UInt2BundleSpec extends CookbookSpec {
- "UInt2Bundle" should "work" in {
- assertTesterPasses { new UInt2Bundle }
- }
-}
diff --git a/src/test/scala/cookbook/UInt2VecOfBool.scala b/src/test/scala/cookbook/UInt2VecOfBool.scala
deleted file mode 100644
index 9aaf63e9..00000000
--- a/src/test/scala/cookbook/UInt2VecOfBool.scala
+++ /dev/null
@@ -1,29 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package cookbook
-
-import chisel3._
-
-/* ### How do I create a Vec of Bools from a UInt?
- *
- * Use the builtin function [[chisel3.Bits.asBools]] to create a Scala Seq of Bool,
- * then wrap the resulting Seq in Vec(...)
- */
-class UInt2VecOfBool extends CookbookTester(1) {
- // Example
- val uint = 0xc.U
- val vec = VecInit(uint.asBools)
- printf(p"$vec") // Vec(0, 0, 1, 1)
-
- // Test
- assert(vec(0) === false.B)
- assert(vec(1) === false.B)
- assert(vec(2) === true.B)
- assert(vec(3) === true.B)
-}
-
-class UInt2VecOfBoolSpec extends CookbookSpec {
- "UInt2VecOfBool" should "work" in {
- assertTesterPasses { new UInt2VecOfBool }
- }
-}
diff --git a/src/test/scala/cookbook/VecOfBool2UInt.scala b/src/test/scala/cookbook/VecOfBool2UInt.scala
deleted file mode 100644
index ca1413dc..00000000
--- a/src/test/scala/cookbook/VecOfBool2UInt.scala
+++ /dev/null
@@ -1,28 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package cookbook
-
-import chisel3._
-
-/* ### How do I create a UInt from a Vec of Bool?
- *
- * Use the builtin function asUInt
- */
-class VecOfBool2UInt extends CookbookTester(1) {
- // Example
- val vec = VecInit(true.B, false.B, true.B, true.B)
- val uint = vec.asUInt
- printf(p"$uint") // 13
-
- /* Test
- *
- * (remember leftmost Bool in Vec is low order bit)
- */
- assert(0xd.U === uint)
-}
-
-class VecOfBool2UIntSpec extends CookbookSpec {
- "VecOfBool2UInt" should "work" in {
- assertTesterPasses { new VecOfBool2UInt }
- }
-}
diff --git a/src/test/scala/examples/ImplicitStateVendingMachine.scala b/src/test/scala/examples/ImplicitStateVendingMachine.scala
deleted file mode 100644
index 36ac82ab..00000000
--- a/src/test/scala/examples/ImplicitStateVendingMachine.scala
+++ /dev/null
@@ -1,31 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package examples
-
-import chiselTests.ChiselFlatSpec
-import chisel3._
-
-// Vending machine implemented with an implicit state machine
-class ImplicitStateVendingMachine extends SimpleVendingMachine {
- // We let the value of nickel be 1 and dime be 2 for efficiency reasons
- val value = RegInit(0.asUInt(3.W))
- val incValue = WireDefault(0.asUInt(3.W))
- val doDispense = value >= 4.U // 4 * nickel as 1 == $0.20
-
- when(doDispense) {
- value := 0.U // No change given
- }.otherwise {
- value := value + incValue
- }
-
- when(io.nickel) { incValue := 1.U }
- when(io.dime) { incValue := 2.U }
-
- io.dispense := doDispense
-}
-
-class ImplicitStateVendingMachineSpec extends ChiselFlatSpec {
- "An vending machine implemented with implicit state" should "work" in {
- assertTesterPasses { new SimpleVendingMachineTester(new ImplicitStateVendingMachine) }
- }
-}
diff --git a/src/test/scala/examples/SimpleVendingMachine.scala b/src/test/scala/examples/SimpleVendingMachine.scala
deleted file mode 100644
index 819669a3..00000000
--- a/src/test/scala/examples/SimpleVendingMachine.scala
+++ /dev/null
@@ -1,98 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package examples
-
-import chiselTests.ChiselFlatSpec
-import chisel3.testers.{BasicTester, TesterDriver}
-import chisel3._
-import chisel3.util._
-
-class SimpleVendingMachineIO extends Bundle {
- val nickel = Input(Bool())
- val dime = Input(Bool())
- val dispense = Output(Bool())
-}
-
-// Superclass for vending machines with very simple IO
-abstract class SimpleVendingMachine extends Module {
- val io = IO(new SimpleVendingMachineIO)
- assert(!(io.nickel && io.dime), "Only one of nickel or dime can be input at a time!")
-}
-
-// Vending machine implemented with a Finite State Machine
-class FSMVendingMachine extends SimpleVendingMachine {
- val sIdle :: s5 :: s10 :: s15 :: sOk :: Nil = Enum(5)
- val state = RegInit(sIdle)
-
- switch(state) {
- is(sIdle) {
- when(io.nickel) { state := s5 }
- when(io.dime) { state := s10 }
- }
- is(s5) {
- when(io.nickel) { state := s10 }
- when(io.dime) { state := s15 }
- }
- is(s10) {
- when(io.nickel) { state := s15 }
- when(io.dime) { state := sOk }
- }
- is(s15) {
- when(io.nickel) { state := sOk }
- when(io.dime) { state := sOk }
- }
- is(sOk) {
- state := sIdle
- }
- }
- io.dispense := (state === sOk)
-}
-
-class VerilogVendingMachine extends BlackBox {
- // Because this is a blackbox, we must explicitly add clock and reset
- val io = IO(new SimpleVendingMachineIO {
- val clock = Input(Clock())
- val reset = Input(Reset())
- })
-}
-
-// Shim because Blackbox io is slightly different than normal Chisel Modules
-class VerilogVendingMachineWrapper extends SimpleVendingMachine {
- val impl = Module(new VerilogVendingMachine)
- impl.io.clock := clock
- impl.io.reset := reset
- impl.io.nickel := io.nickel
- impl.io.dime := io.dime
- io.dispense := impl.io.dispense
-}
-
-// Accept a reference to a SimpleVendingMachine so it can be constructed inside
-// the tester (in a call to Module.apply as required by Chisel
-class SimpleVendingMachineTester(mod: => SimpleVendingMachine) extends BasicTester {
-
- val dut = Module(mod)
-
- val (cycle, done) = Counter(true.B, 10)
- when(done) { stop(); stop() } // Stop twice because of Verilator
-
- val nickelInputs = VecInit(true.B, true.B, true.B, true.B, true.B, false.B, false.B, false.B, true.B, false.B)
- val dimeInputs = VecInit(false.B, false.B, false.B, false.B, false.B, true.B, true.B, false.B, false.B, true.B)
- val expected = VecInit(false.B, false.B, false.B, false.B, true.B, false.B, false.B, true.B, false.B, false.B)
-
- dut.io.nickel := nickelInputs(cycle)
- dut.io.dime := dimeInputs(cycle)
- assert(dut.io.dispense === expected(cycle))
-}
-
-class SimpleVendingMachineSpec extends ChiselFlatSpec {
- "An FSM implementation of a vending machine" should "work" in {
- assertTesterPasses { new SimpleVendingMachineTester(new FSMVendingMachine) }
- }
- "An Verilog implementation of a vending machine" should "work" in {
- assertTesterPasses(
- new SimpleVendingMachineTester(new VerilogVendingMachineWrapper),
- List("/chisel3/VerilogVendingMachine.v"),
- annotations = TesterDriver.verilatorOnly
- )
- }
-}
diff --git a/src/test/scala/examples/VendingMachineGenerator.scala b/src/test/scala/examples/VendingMachineGenerator.scala
deleted file mode 100644
index 4adae987..00000000
--- a/src/test/scala/examples/VendingMachineGenerator.scala
+++ /dev/null
@@ -1,130 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package examples
-
-import chiselTests.ChiselFlatSpec
-import chisel3.testers.BasicTester
-import chisel3._
-import chisel3.util._
-
-import VendingMachineUtils._
-
-class VendingMachineIO(val legalCoins: Seq[Coin]) extends Bundle {
- require(legalCoins.size >= 1, "The vending machine must accept at least 1 coin!")
- // Order of coins by value
- val coins: Seq[Coin] = legalCoins.sortBy(_.value)
- // Map of coin names to their relative position in value (ie. index in inputs)
- val indexMap: Map[String, Int] = coins.map(_.name).zipWithIndex.toMap
-
- require(
- coins.map(_.value % coins.head.value == 0).reduce(_ && _),
- "All coins must be a multiple of the lowest value coin!"
- )
-
- val inputs = Input(Vec(legalCoins.size, Bool()))
- val dispense = Output(Bool())
-
- def apply(coin: String): Unit = {
- val idx = indexMap(coin)
- inputs(idx) := true.B
- }
-}
-
-// Superclass for parameterized vending machines
-abstract class ParameterizedVendingMachine(legalCoins: Seq[Coin], val sodaCost: Int) extends Module {
- val io = IO(new VendingMachineIO(legalCoins))
- // Enforce one hot
- if (io.inputs.size > 1) {
- for (input <- io.inputs) {
- when(input) {
- assert(io.inputs.filterNot(_ == input).map(!_).reduce(_ && _), "Only 1 coin can be input in a given cycle!")
- }
- }
- }
-}
-
-class VendingMachineGenerator(
- legalCoins: Seq[Coin],
- sodaCost: Int)
- extends ParameterizedVendingMachine(legalCoins, sodaCost) {
- require(sodaCost > 0, "Sodas must actually cost something!")
-
- // All coin values are normalized to a multiple of the minimum coin value
- val minCoin = io.coins.head.value
- val maxCoin = io.coins.last.value
- val maxValue = (sodaCost + maxCoin - minCoin) / minCoin // normalize to minimum value
-
- val width = log2Ceil(maxValue + 1).W
- val value = RegInit(0.asUInt(width))
- val incValue = WireDefault(0.asUInt(width))
- val doDispense = value >= (sodaCost / minCoin).U
-
- when(doDispense) {
- value := 0.U // No change given
- }.otherwise {
- value := value + incValue
- }
-
- for ((coin, index) <- io.coins.zipWithIndex) {
- when(io.inputs(index)) { incValue := (coin.value / minCoin).U }
- }
- io.dispense := doDispense
-}
-
-class ParameterizedVendingMachineTester(
- mod: => ParameterizedVendingMachine,
- testLength: Int)
- extends BasicTester {
- require(testLength > 0, "Test length must be positive!")
-
- // Construct the module
- val dut = Module(mod)
- val coins = dut.io.coins
-
- // Inputs and expected results
- // Do random testing
- private val _rand = scala.util.Random
- val inputs: Seq[Option[Coin]] = Seq.fill(testLength)(coins.lift(_rand.nextInt(coins.size + 1)))
- val expected: Seq[Boolean] = getExpectedResults(inputs, dut.sodaCost)
-
- val inputVec: Vec[UInt] = VecInit(inputs.map {
- case Some(coin) => (1 << dut.io.indexMap(coin.name)).asUInt(coins.size.W)
- case None => 0.asUInt(coins.size.W)
- })
- val expectedVec: Vec[Bool] = VecInit(expected.map(_.B))
-
- val (idx, done) = Counter(true.B, testLength + 1)
- when(done) { stop(); stop() } // Two stops for Verilator
-
- dut.io.inputs := inputVec(idx).asBools
- assert(dut.io.dispense === expectedVec(idx))
-}
-
-class VendingMachineGeneratorSpec extends ChiselFlatSpec {
- behavior.of("The vending machine generator")
-
- it should "generate a vending machine that accepts only nickels and dimes and costs $0.20" in {
- val coins = Seq(Nickel, Dime)
- assertTesterPasses {
- new ParameterizedVendingMachineTester(new VendingMachineGenerator(coins, 20), 100)
- }
- }
- it should "generate a vending machine that only accepts one kind of coin" in {
- val coins = Seq(Nickel)
- assertTesterPasses {
- new ParameterizedVendingMachineTester(new VendingMachineGenerator(coins, 30), 100)
- }
- }
- it should "generate a more realistic vending machine that costs $1.50" in {
- val coins = Seq(Penny, Nickel, Dime, Quarter)
- assertTesterPasses {
- new ParameterizedVendingMachineTester(new VendingMachineGenerator(coins, 150), 100)
- }
- }
- it should "generate a Harry Potter themed vending machine" in {
- val coins = Seq(Knut, Sickle) // Galleons are worth too much
- assertTesterPasses {
- new ParameterizedVendingMachineTester(new VendingMachineGenerator(coins, Galleon.value), 100)
- }
- }
-}
diff --git a/src/test/scala/examples/VendingMachineUtils.scala b/src/test/scala/examples/VendingMachineUtils.scala
deleted file mode 100644
index 8d5aea57..00000000
--- a/src/test/scala/examples/VendingMachineUtils.scala
+++ /dev/null
@@ -1,39 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package examples
-
-import scala.collection.mutable
-
-/* Useful utilities for testing vending machines */
-object VendingMachineUtils {
- abstract class Coin(val name: String, val value: Int)
- // US Coins
- case object Penny extends Coin("penny", 1)
- case object Nickel extends Coin("nickel", 5)
- case object Dime extends Coin("dime", 10)
- case object Quarter extends Coin("quarter", 25)
-
- // Harry Potter Coins
- case object Knut extends Coin("knut", Penny.value * 2) // Assuming 1 Knut is worth $0.02
- case object Sickle extends Coin("sickle", Knut.value * 29)
- case object Galleon extends Coin("galleon", Sickle.value * 17)
-
- def getExpectedResults(inputs: Seq[Option[Coin]], sodaCost: Int): Seq[Boolean] = {
- var value = 0
- val outputs = mutable.ArrayBuffer.empty[Boolean]
- for (input <- inputs) {
- val incValue = input match {
- case Some(coin) => coin.value
- case None => 0
- }
- if (value >= sodaCost) {
- outputs.append(true)
- value = 0
- } else {
- outputs.append(false)
- value += incValue
- }
- }
- outputs.toSeq
- }
-}