summaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/scala/chisel3/testers/TestUtils.scala9
-rw-r--r--src/test/scala/chiselTests/AutoClonetypeSpec.scala199
-rw-r--r--src/test/scala/chiselTests/AutoNestedCloneSpec.scala65
-rw-r--r--src/test/scala/chiselTests/BlackBoxImpl.scala1
-rw-r--r--src/test/scala/chiselTests/BundleSpec.scala33
-rw-r--r--src/test/scala/chiselTests/CompatibilityInteroperabilitySpec.scala5
-rw-r--r--src/test/scala/chiselTests/CompatibilitySpec.scala33
-rw-r--r--src/test/scala/chiselTests/CompileOptionsTest.scala2
-rw-r--r--src/test/scala/chiselTests/ComplexAssign.scala5
-rw-r--r--src/test/scala/chiselTests/ConnectSpec.scala35
-rw-r--r--src/test/scala/chiselTests/DataPrint.scala56
-rw-r--r--src/test/scala/chiselTests/FixedPointSpec.scala3
-rw-r--r--src/test/scala/chiselTests/Harness.scala5
-rw-r--r--src/test/scala/chiselTests/InlineSpec.scala1
-rw-r--r--src/test/scala/chiselTests/IntervalSpec.scala9
-rw-r--r--src/test/scala/chiselTests/InvalidateAPISpec.scala2
-rw-r--r--src/test/scala/chiselTests/LoadMemoryFromFileSpec.scala1
-rw-r--r--src/test/scala/chiselTests/Module.scala66
-rw-r--r--src/test/scala/chiselTests/PrintableSpec.scala9
-rw-r--r--src/test/scala/chiselTests/QueueFlushSpec.scala20
-rw-r--r--src/test/scala/chiselTests/QueueSpec.scala30
-rw-r--r--src/test/scala/chiselTests/RecordSpec.scala25
-rw-r--r--src/test/scala/chiselTests/SIntOps.scala2
-rw-r--r--src/test/scala/chiselTests/StrongEnum.scala4
-rw-r--r--src/test/scala/chiselTests/TransitNameSpec.scala1
-rw-r--r--src/test/scala/chiselTests/UIntOps.scala84
-rw-r--r--src/test/scala/chiselTests/Vec.scala34
-rw-r--r--src/test/scala/chiselTests/VecLiteralSpec.scala48
-rw-r--r--src/test/scala/chiselTests/VerificationSpec.scala (renamed from src/test/scala/chiselTests/experimental/verification/VerificationSpec.scala)35
-rw-r--r--src/test/scala/chiselTests/aop/SelectSpec.scala7
-rw-r--r--src/test/scala/chiselTests/experimental/DataView.scala123
-rw-r--r--src/test/scala/chiselTests/experimental/DataViewTargetSpec.scala3
-rw-r--r--src/test/scala/chiselTests/experimental/TraceSpec.scala309
-rw-r--r--src/test/scala/chiselTests/experimental/Tuple.scala163
-rw-r--r--src/test/scala/chiselTests/experimental/hierarchy/Annotations.scala12
-rw-r--r--src/test/scala/chiselTests/experimental/hierarchy/DefinitionSpec.scala55
-rw-r--r--src/test/scala/chiselTests/experimental/hierarchy/Examples.scala53
-rw-r--r--src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala156
-rw-r--r--src/test/scala/chiselTests/util/BitPatSpec.scala10
-rw-r--r--src/test/scala/chiselTests/util/BitSetSpec.scala119
-rw-r--r--src/test/scala/chiselTests/util/experimental/TruthTableSpec.scala31
41 files changed, 1464 insertions, 399 deletions
diff --git a/src/test/scala/chisel3/testers/TestUtils.scala b/src/test/scala/chisel3/testers/TestUtils.scala
index c72c779a..338f9cd4 100644
--- a/src/test/scala/chisel3/testers/TestUtils.scala
+++ b/src/test/scala/chisel3/testers/TestUtils.scala
@@ -12,13 +12,4 @@ object TestUtils {
// Useful because TesterDriver.Backend is chisel3 package private
def containsBackend(annos: AnnotationSeq): Boolean =
annos.collectFirst { case b: Backend => b }.isDefined
-
- // Allows us to check that the compiler plugin cloneType is actually working
- val usingPlugin: Boolean = (new Bundle { def check = _usingPlugin }).check
- def elaborateNoReflectiveAutoCloneType(f: => RawModule): Circuit = {
- ChiselStage.elaborate {
- chisel3.internal.Builder.allowReflectiveAutoCloneType = !usingPlugin
- f
- }
- }
}
diff --git a/src/test/scala/chiselTests/AutoClonetypeSpec.scala b/src/test/scala/chiselTests/AutoClonetypeSpec.scala
index fcbc4785..ef58f1ed 100644
--- a/src/test/scala/chiselTests/AutoClonetypeSpec.scala
+++ b/src/test/scala/chiselTests/AutoClonetypeSpec.scala
@@ -5,6 +5,7 @@ package chiselTests
import chisel3._
import chisel3.testers.TestUtils
import chisel3.util.QueueIO
+import chisel3.stage.ChiselStage.elaborate
class BundleWithIntArg(val i: Int) extends Bundle {
val out = UInt(i.W)
@@ -71,14 +72,11 @@ class InheritingBundle extends QueueIO(UInt(8.W), 8) {
val error = Output(Bool())
}
-// TODO all `.suggestNames` are due to https://github.com/chipsalliance/chisel3/issues/1802
class AutoClonetypeSpec extends ChiselFlatSpec with Utils {
- val usingPlugin: Boolean = TestUtils.usingPlugin
- val elaborate = TestUtils.elaborateNoReflectiveAutoCloneType _
"Bundles with Scala args" should "not need clonetype" in {
elaborate { new Module {
- val io = IO(new Bundle{}).suggestName("io")
+ val io = IO(new Bundle{})
val myWire = Wire(new BundleWithIntArg(8))
assert(myWire.i == 8)
@@ -87,7 +85,7 @@ class AutoClonetypeSpec extends ChiselFlatSpec with Utils {
"Bundles with Scala implicit args" should "not need clonetype" in {
elaborate { new Module {
- val io = IO(new Bundle{}).suggestName("io")
+ val io = IO(new Bundle{})
implicit val implicitInt: Int = 4
val myWire = Wire(new BundleWithImplicit())
@@ -98,7 +96,7 @@ class AutoClonetypeSpec extends ChiselFlatSpec with Utils {
"Bundles with Scala explicit and impicit args" should "not need clonetype" in {
elaborate { new Module {
- val io = IO(new Bundle{}).suggestName("io")
+ val io = IO(new Bundle{})
implicit val implicitInt: Int = 4
val myWire = Wire(new BundleWithArgAndImplicit(8))
@@ -110,7 +108,7 @@ class AutoClonetypeSpec extends ChiselFlatSpec with Utils {
"Subtyped Bundles" should "not need clonetype" in {
elaborate { new Module {
- val io = IO(new Bundle{}).suggestName("io")
+ val io = IO(new Bundle{})
val myWire = Wire(new SubBundle(8, 4))
@@ -118,7 +116,7 @@ class AutoClonetypeSpec extends ChiselFlatSpec with Utils {
assert(myWire.i2 == 4)
} }
elaborate { new Module {
- val io = IO(new Bundle{}).suggestName("io")
+ val io = IO(new Bundle{})
val myWire = Wire(new SubBundleVal(8, 4))
@@ -131,23 +129,12 @@ class AutoClonetypeSpec extends ChiselFlatSpec with Utils {
new BundleWithIntArg(8).cloneType
}
- def checkSubBundleInvalid() = {
+ "Subtyped Bundles that don't clone well" should "be now be supported!" in {
elaborate { new Module {
- val io = IO(new Bundle{}).suggestName("io")
+ val io = IO(new Bundle{})
val myWire = Wire(new SubBundleInvalid(8, 4))
} }
}
- if (usingPlugin) {
- "Subtyped Bundles that don't clone well" should "be now be supported!" in {
- checkSubBundleInvalid()
- }
- } else {
- "Subtyped Bundles that don't clone well" should "be caught" in {
- a [ChiselException] should be thrownBy extractCause[ChiselException] {
- checkSubBundleInvalid()
- }
- }
- }
"Inner bundles with Scala args" should "not need clonetype" in {
elaborate { new ModuleWithInner }
@@ -155,7 +142,7 @@ class AutoClonetypeSpec extends ChiselFlatSpec with Utils {
"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)))).suggestName("io")
+ val io = IO(Output(new BundleWithArgumentField(UInt(8.W), UInt(8.W))))
io.x := 1.U
io.y := 1.U
} }
@@ -163,28 +150,28 @@ class AutoClonetypeSpec extends ChiselFlatSpec with Utils {
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)))).suggestName("io")
+ 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)).suggestName("io")
+ 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))).suggestName("io")
+ 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).suggestName("io")
+ val io = IO(new NestedAnonymousBundle)
val a = WireDefault(io)
io.a.a := 1.U
} }
@@ -197,7 +184,7 @@ class AutoClonetypeSpec extends ChiselFlatSpec with Utils {
val a = Output(UInt(8.W))
}
}
- val io = IO((new InnerClassThing).createBundle).suggestName("io")
+ val io = IO((new InnerClassThing).createBundle)
val a = WireDefault(io)
} }
}
@@ -208,7 +195,7 @@ class AutoClonetypeSpec extends ChiselFlatSpec with Utils {
val bundleFieldType = UInt(8.W)
val io = IO(Output(new Bundle {
val a = bundleFieldType
- })).suggestName("io")
+ }))
io.a := 0.U
} }
}
@@ -221,7 +208,7 @@ class AutoClonetypeSpec extends ChiselFlatSpec with Utils {
}
elaborate { new Module {
- val io = IO(Output(new BadBundle(UInt(8.W), 1))).suggestName("io")
+ val io = IO(Output(new BadBundle(UInt(8.W), 1)))
io.a := 0.U
} }
}
@@ -265,101 +252,97 @@ class AutoClonetypeSpec extends ChiselFlatSpec with Utils {
behavior of "Compiler Plugin Autoclonetype"
- // New tests from the plugin
- if (usingPlugin) {
- 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 "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 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 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 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 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)
- override def cloneType = new MyBundle(i).asInstanceOf[this.type]
- }
- elaborate { new MultiIOModule {
- val in = IO(Input(new MyBundle(8)))
- val out = IO(Output(new MyBundle(8)))
- 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
+ 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)
}
- elaborate(new MyModule(UInt(8.W)))
+ 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 "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)
}
}
diff --git a/src/test/scala/chiselTests/AutoNestedCloneSpec.scala b/src/test/scala/chiselTests/AutoNestedCloneSpec.scala
index 401766e2..258d0823 100644
--- a/src/test/scala/chiselTests/AutoNestedCloneSpec.scala
+++ b/src/test/scala/chiselTests/AutoNestedCloneSpec.scala
@@ -3,6 +3,7 @@
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 {
@@ -11,10 +12,7 @@ class BundleWithAnonymousInner(val w: Int) extends Bundle {
}
}
-// TODO all `.suggestNames` are due to https://github.com/chipsalliance/chisel3/issues/1802
class AutoNestedCloneSpec extends ChiselFlatSpec with Matchers with Utils {
- val usingPlugin: Boolean = TestUtils.usingPlugin
- val elaborate = TestUtils.elaborateNoReflectiveAutoCloneType _
behavior of "autoCloneType of inner Bundle in Chisel3"
@@ -27,7 +25,7 @@ class AutoNestedCloneSpec extends ChiselFlatSpec with Matchers with Utils {
}
def getIO: InnerIOType = new InnerIOType
}
- val io = IO(new Bundle {}).suggestName("io")
+ val io = IO(new Bundle {})
val myWire = Wire((new Middle(w)).getIO)
}
new Outer(2)
@@ -37,7 +35,7 @@ class AutoNestedCloneSpec extends ChiselFlatSpec with Matchers with Utils {
it should "clone an anonymous inner bundle successfully" in {
elaborate {
class TestTop(val w: Int) extends Module {
- val io = IO(new Bundle {}).suggestName("io")
+ val io = IO(new Bundle {})
val myWire = Wire(new Bundle{ val a = UInt(w.W) })
}
new TestTop(2)
@@ -50,13 +48,13 @@ class AutoNestedCloneSpec extends ChiselFlatSpec with Matchers with Utils {
val io = IO(new Bundle{
val in = Input(UInt(w.W))
val out = Output(UInt(w.W))
- }).suggestName("io")
+ })
}
class Outer(val w: Int) extends Module {
val io = IO(new Bundle{
val in = Input(UInt(w.W))
val out = Output(UInt(w.W))
- }).suggestName("io")
+ })
val i = Module(new Inner(w))
val iw = Wire(chiselTypeOf(i.io))
iw <> io
@@ -69,7 +67,7 @@ class AutoNestedCloneSpec extends ChiselFlatSpec with Matchers with Utils {
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) ).suggestName("io")
+ val io = IO(new BundleWithAnonymousInner(w))
val w0 = WireDefault(io)
val w1 = WireDefault(io.inner)
}
@@ -85,7 +83,7 @@ class AutoNestedCloneSpec extends ChiselFlatSpec with Matchers with Utils {
}
val io = IO(new Bundle {
val inner = Input(bun)
- }).suggestName("io")
+ })
val w0 = WireDefault(io)
val w1 = WireDefault(io.inner)
}
@@ -100,42 +98,39 @@ class AutoNestedCloneSpec extends ChiselFlatSpec with Matchers with Utils {
val inner = Input(new Bundle {
val x = UInt(8.W)
})
- }).suggestName("io")
+ })
}
new TestModule()
}
}
- if (usingPlugin) {
- // This works with the plugin, but is a null pointer exception when using reflective autoclonetype
- 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))
- }
+ 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 {}).suggestName("io")
- val myWire = Wire((new Middle(w)).getIO)
}
- new Outer(2)
+ 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)
+ 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 io = IO(new MyBundle(4, UInt(8.W)))
- val myWire = WireInit(io.foo)
- val myWire2 = WireInit(io.bar)
- io.bar.x := io.foo.x
- })
- }
+ 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/BlackBoxImpl.scala b/src/test/scala/chiselTests/BlackBoxImpl.scala
index a9a6fa29..2fa3d8a6 100644
--- a/src/test/scala/chiselTests/BlackBoxImpl.scala
+++ b/src/test/scala/chiselTests/BlackBoxImpl.scala
@@ -7,7 +7,6 @@ import java.io.File
import chisel3._
import chisel3.util.{HasBlackBoxInline, HasBlackBoxResource, HasBlackBoxPath}
import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage}
-import firrtl.FirrtlExecutionSuccess
import firrtl.transforms.BlackBoxNotFoundException
import org.scalacheck.Test.Failed
import org.scalatest.Succeeded
diff --git a/src/test/scala/chiselTests/BundleSpec.scala b/src/test/scala/chiselTests/BundleSpec.scala
index 1d392f5c..d9f82e6d 100644
--- a/src/test/scala/chiselTests/BundleSpec.scala
+++ b/src/test/scala/chiselTests/BundleSpec.scala
@@ -10,25 +10,20 @@ trait BundleSpecUtils {
class BundleFooBar extends Bundle {
val foo = UInt(16.W)
val bar = UInt(16.W)
- override def cloneType: this.type = (new BundleFooBar).asInstanceOf[this.type]
}
class BundleBarFoo extends Bundle {
val bar = UInt(16.W)
val foo = UInt(16.W)
- override def cloneType: this.type = (new BundleBarFoo).asInstanceOf[this.type]
}
class BundleFoo extends Bundle {
val foo = UInt(16.W)
- override def cloneType: this.type = (new BundleFoo).asInstanceOf[this.type]
}
class BundleBar extends Bundle {
val bar = UInt(16.W)
- override def cloneType: this.type = (new BundleBar).asInstanceOf[this.type]
}
class BadSeqBundle extends Bundle {
val bar = Seq(UInt(16.W), UInt(8.W), UInt(4.W))
- override def cloneType: this.type = (new BadSeqBundle).asInstanceOf[this.type]
}
class MyModule(output: Bundle, input: Bundle) extends Module {
@@ -116,17 +111,21 @@ class BundleSpec extends ChiselFlatSpec with BundleSpecUtils with Utils {
}
}
- "Bundles" should "not have aliased fields" in {
+ "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 Bundle {
- val a = UInt(8.W)
- val b = a
- }))
+ val io = IO(Output(new AliasedBundle))
io.a := 0.U
io.b := 1.U
} }
- }).getMessage should include("aliased fields")
+ }).getMessage should include("contains aliased fields named (a,b),(c,d)")
}
"Bundles" should "not have bound hardware" in {
@@ -162,4 +161,16 @@ class BundleSpec extends ChiselFlatSpec with BundleSpecUtils with Utils {
}
}
}
+
+ // 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/CompatibilityInteroperabilitySpec.scala b/src/test/scala/chiselTests/CompatibilityInteroperabilitySpec.scala
index 1795cc1f..4b03dfa5 100644
--- a/src/test/scala/chiselTests/CompatibilityInteroperabilitySpec.scala
+++ b/src/test/scala/chiselTests/CompatibilityInteroperabilitySpec.scala
@@ -12,8 +12,6 @@ object CompatibilityComponents {
class ChiselBundle extends Bundle {
val a = UInt(width = 32)
val b = UInt(width = 32).flip
-
- override def cloneType: this.type = (new ChiselBundle).asInstanceOf[this.type]
}
class ChiselRecord extends Record {
val elements = ListMap("a" -> UInt(width = 32), "b" -> UInt(width = 32).flip)
@@ -48,8 +46,6 @@ object Chisel3Components {
class Chisel3Bundle extends Bundle {
val a = Output(UInt(32.W))
val b = Input(UInt(32.W))
-
- override def cloneType: this.type = (new Chisel3Bundle).asInstanceOf[this.type]
}
class Chisel3Record extends Record {
@@ -341,7 +337,6 @@ class CompatibiltyInteroperabilitySpec extends ChiselFlatSpec {
val foo = maybeFlip(new Bundle {
val bar = UInt(INPUT, width = 8)
})
- override def cloneType = (new MyBundle(extraFlip)).asInstanceOf[this.type]
}
}
import chisel3._
diff --git a/src/test/scala/chiselTests/CompatibilitySpec.scala b/src/test/scala/chiselTests/CompatibilitySpec.scala
index 2d4ad517..7ac67b7c 100644
--- a/src/test/scala/chiselTests/CompatibilitySpec.scala
+++ b/src/test/scala/chiselTests/CompatibilitySpec.scala
@@ -195,11 +195,9 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck
class SmallBundle extends Bundle {
val f1 = UInt(width = 4)
val f2 = UInt(width = 5)
- override def cloneType: this.type = (new SmallBundle).asInstanceOf[this.type]
}
class BigBundle extends SmallBundle {
val f3 = UInt(width = 6)
- override def cloneType: this.type = (new BigBundle).asInstanceOf[this.type]
}
"A Module with missing bundle fields when compiled with the Chisel compatibility package" should "not throw an exception" in {
@@ -538,6 +536,9 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck
info("toUInt works")
s.toUInt shouldBe a [UInt]
+
+ info("toBools works")
+ s.toBools shouldBe a [Seq[Bool]]
}
ChiselStage.elaborate(new Foo)
@@ -566,4 +567,32 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck
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")
+ }
+
}
diff --git a/src/test/scala/chiselTests/CompileOptionsTest.scala b/src/test/scala/chiselTests/CompileOptionsTest.scala
index 9c88c1e0..1ecf97f0 100644
--- a/src/test/scala/chiselTests/CompileOptionsTest.scala
+++ b/src/test/scala/chiselTests/CompileOptionsTest.scala
@@ -14,11 +14,9 @@ class CompileOptionsSpec extends ChiselFlatSpec with Utils {
class SmallBundle extends Bundle {
val f1 = UInt(4.W)
val f2 = UInt(5.W)
- override def cloneType: this.type = (new SmallBundle).asInstanceOf[this.type]
}
class BigBundle extends SmallBundle {
val f3 = UInt(6.W)
- override def cloneType: this.type = (new BigBundle).asInstanceOf[this.type]
}
"A Module with missing bundle fields when compiled with implicit Strict.CompileOption " should "throw an exception" in {
diff --git a/src/test/scala/chiselTests/ComplexAssign.scala b/src/test/scala/chiselTests/ComplexAssign.scala
index 36fb59c2..222b6373 100644
--- a/src/test/scala/chiselTests/ComplexAssign.scala
+++ b/src/test/scala/chiselTests/ComplexAssign.scala
@@ -7,10 +7,7 @@ import chisel3.testers.BasicTester
import chisel3.util._
import org.scalacheck.Shrink
-class Complex[T <: Data](val re: T, val im: T) extends Bundle {
- override def cloneType: this.type =
- new Complex(re.cloneType, im.cloneType).asInstanceOf[this.type]
-}
+class Complex[T <: Data](val re: T, val im: T) extends Bundle
class ComplexAssign(w: Int) extends Module {
val io = IO(new Bundle {
diff --git a/src/test/scala/chiselTests/ConnectSpec.scala b/src/test/scala/chiselTests/ConnectSpec.scala
index 367864e6..f9ef5946 100644
--- a/src/test/scala/chiselTests/ConnectSpec.scala
+++ b/src/test/scala/chiselTests/ConnectSpec.scala
@@ -2,6 +2,8 @@
package chiselTests
+import org.scalatest._
+
import chisel3._
import chisel3.experimental.{Analog, FixedPoint}
import chisel3.stage.ChiselStage
@@ -126,4 +128,37 @@ class ConnectSpec extends ChiselPropSpec with Utils {
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/DataPrint.scala b/src/test/scala/chiselTests/DataPrint.scala
index b5f96c4d..7fb790a8 100644
--- a/src/test/scala/chiselTests/DataPrint.scala
+++ b/src/test/scala/chiselTests/DataPrint.scala
@@ -20,6 +20,14 @@ class DataPrintSpec extends ChiselFlatSpec with Matchers {
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")
@@ -31,18 +39,20 @@ class DataPrintSpec extends ChiselFlatSpec with Matchers {
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("UInt(Wire in BoundDataModule)")
- Reg(SInt()).toString should be("SInt(Reg in BoundDataModule)")
+ 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("Bool(IO in unelaborated BoundDataModule)")
+ io.toString should be("BoundDataModule.io: IO[Bool]")
val m = Mem(4, UInt(2.W))
- m(2).toString should be("UInt<2>(MemPort in BoundDataModule)")
- (2.U + 2.U).toString should be("UInt<2>(OpResult in BoundDataModule)")
- Wire(Vec(3, UInt(2.W))).toString should be ("UInt<2>[3](Wire in BoundDataModule)")
+ 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 {
@@ -50,8 +60,31 @@ class DataPrintSpec extends ChiselFlatSpec with Matchers {
}))
}
val inner = Module(new InnerModule)
- inner.clock.toString should be ("Clock(IO clock in InnerModule)")
- inner.io.a.toString should be ("UInt<4>(IO io_a in 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 {
@@ -67,13 +100,12 @@ class DataPrintSpec extends ChiselFlatSpec with Matchers {
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 Bundle {
- val a = UInt(8.W)
- }.toString should be ("AnonymousBundle")
+ (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/FixedPointSpec.scala b/src/test/scala/chiselTests/FixedPointSpec.scala
index a1acdb17..2530bb13 100644
--- a/src/test/scala/chiselTests/FixedPointSpec.scala
+++ b/src/test/scala/chiselTests/FixedPointSpec.scala
@@ -60,6 +60,9 @@ class FixedPointFromBitsTester extends BasicTester {
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)
diff --git a/src/test/scala/chiselTests/Harness.scala b/src/test/scala/chiselTests/Harness.scala
index 23379498..51576566 100644
--- a/src/test/scala/chiselTests/Harness.scala
+++ b/src/test/scala/chiselTests/Harness.scala
@@ -4,10 +4,7 @@ package chiselTests
import java.io.File
-import firrtl.util.BackendCompilationUtilities
-
-class HarnessSpec extends ChiselPropSpec
- with BackendCompilationUtilities {
+class HarnessSpec extends ChiselPropSpec {
def makeTrivialVerilog: (File => File) = makeHarness((prefix: String) => s"""
module ${prefix};
diff --git a/src/test/scala/chiselTests/InlineSpec.scala b/src/test/scala/chiselTests/InlineSpec.scala
index 397eac2e..59a1e984 100644
--- a/src/test/scala/chiselTests/InlineSpec.scala
+++ b/src/test/scala/chiselTests/InlineSpec.scala
@@ -5,7 +5,6 @@ package chiselTests
import chisel3._
import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage}
import chisel3.util.experimental.{InlineInstance, FlattenInstance}
-import firrtl.FirrtlExecutionSuccess
import firrtl.passes.InlineAnnotation
import firrtl.stage.{FirrtlCircuitAnnotation, FirrtlStage}
import firrtl.transforms.FlattenAnnotation
diff --git a/src/test/scala/chiselTests/IntervalSpec.scala b/src/test/scala/chiselTests/IntervalSpec.scala
index abc619e5..c223260d 100644
--- a/src/test/scala/chiselTests/IntervalSpec.scala
+++ b/src/test/scala/chiselTests/IntervalSpec.scala
@@ -15,7 +15,7 @@ import firrtl.passes.CheckTypes.InvalidConnect
import firrtl.passes.CheckWidths.{DisjointSqueeze, InvalidRange}
import firrtl.passes.{PassExceptions, WrapWithRemainder}
import firrtl.stage.{CompilerAnnotation, FirrtlCircuitAnnotation}
-import firrtl.{FIRRTLException, HighFirrtlCompiler, LowFirrtlCompiler, MiddleFirrtlCompiler, MinimumVerilogCompiler, NoneCompiler, SystemVerilogCompiler, VerilogCompiler}
+import firrtl.{HighFirrtlCompiler, LowFirrtlCompiler, MiddleFirrtlCompiler, MinimumVerilogCompiler, NoneCompiler, SystemVerilogCompiler, VerilogCompiler}
import org.scalatest.freespec.AnyFreeSpec
import org.scalatest.matchers.should.Matchers
@@ -406,6 +406,13 @@ class IntervalChainedSubTester extends BasicTester {
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()
}
diff --git a/src/test/scala/chiselTests/InvalidateAPISpec.scala b/src/test/scala/chiselTests/InvalidateAPISpec.scala
index b7db33cc..52ad02b4 100644
--- a/src/test/scala/chiselTests/InvalidateAPISpec.scala
+++ b/src/test/scala/chiselTests/InvalidateAPISpec.scala
@@ -105,7 +105,7 @@ class InvalidateAPISpec extends ChiselPropSpec with Matchers with BackendCompila
ChiselStage.elaborate(new ModuleWithDontCareSink)
}
}
- exception.getMessage should include("DontCare cannot be a connection sink (LHS)")
+ exception.getMessage should include("DontCare cannot be a connection sink")
}
property("a DontCare cannot be a connection sink (LHS) for <>") {
diff --git a/src/test/scala/chiselTests/LoadMemoryFromFileSpec.scala b/src/test/scala/chiselTests/LoadMemoryFromFileSpec.scala
index 8a998496..74e587bc 100644
--- a/src/test/scala/chiselTests/LoadMemoryFromFileSpec.scala
+++ b/src/test/scala/chiselTests/LoadMemoryFromFileSpec.scala
@@ -8,7 +8,6 @@ import chisel3._
import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage}
import chisel3.util.experimental.{loadMemoryFromFile,loadMemoryFromFileInline}
import chisel3.util.log2Ceil
-import firrtl.FirrtlExecutionSuccess
import firrtl.annotations.MemoryLoadFileType
import org.scalatest.freespec.AnyFreeSpec
import org.scalatest.matchers.should.Matchers
diff --git a/src/test/scala/chiselTests/Module.scala b/src/test/scala/chiselTests/Module.scala
index 7703e876..f0d6dbe7 100644
--- a/src/test/scala/chiselTests/Module.scala
+++ b/src/test/scala/chiselTests/Module.scala
@@ -9,6 +9,7 @@ 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))
@@ -167,6 +168,71 @@ class ModuleSpec extends ChiselPropSpec with Utils {
"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")
}
diff --git a/src/test/scala/chiselTests/PrintableSpec.scala b/src/test/scala/chiselTests/PrintableSpec.scala
index 25b54966..c7e819ec 100644
--- a/src/test/scala/chiselTests/PrintableSpec.scala
+++ b/src/test/scala/chiselTests/PrintableSpec.scala
@@ -3,7 +3,7 @@
package chiselTests
import chisel3._
-import chisel3.experimental.{BaseSim, ChiselAnnotation}
+import chisel3.experimental.ChiselAnnotation
import chisel3.stage.ChiselStage
import chisel3.testers.BasicTester
import firrtl.annotations.{ReferenceTarget, SingleTargetAnnotation}
@@ -23,7 +23,7 @@ object PrintfAnnotation {
/** Create annotation for a given [[printf]].
* @param c component to be annotated
*/
- def annotate(c: BaseSim): Unit = {
+ def annotate(c: VerificationStatement): Unit = {
chisel3.experimental.annotate(new ChiselAnnotation {
def toFirrtl: PrintfAnnotation = PrintfAnnotation(c.toTarget)
})
@@ -139,7 +139,6 @@ class PrintableSpec extends AnyFlatSpec with Matchers {
}
class MyBundle extends Bundle {
val foo = UInt(32.W)
- override def cloneType: this.type = (new MyBundle).asInstanceOf[this.type]
}
class MyModule extends BasicTester {
override def desiredName: String = "MyModule"
@@ -246,7 +245,7 @@ class PrintableSpec extends AnyFlatSpec with Matchers {
// 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>SIM")
+ exactly(1, annoLines) should include ("~PrintfAnnotationTest|PrintfAnnotationTest>printf")
exactly(1, annoLines) should include ("~PrintfAnnotationTest|PrintfAnnotationTest>howdy")
// read in FIRRTL file
@@ -256,7 +255,7 @@ class PrintableSpec extends AnyFlatSpec with Matchers {
// 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) : SIM""")
+ 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""")
}
}
diff --git a/src/test/scala/chiselTests/QueueFlushSpec.scala b/src/test/scala/chiselTests/QueueFlushSpec.scala
index 11a411a8..9e0c6bb4 100644
--- a/src/test/scala/chiselTests/QueueFlushSpec.scala
+++ b/src/test/scala/chiselTests/QueueFlushSpec.scala
@@ -40,11 +40,11 @@ abstract class FlushQueueTesterBase(elements: Seq[Int], queueDepth: Int, bitWidt
q.io.deq.ready := LFSR(16)(tap)
q.io.enq.bits := elems(inCnt.value)
- when(q.io.enq.fire()) {
+ when(q.io.enq.fire) {
inCnt.inc()
currQCnt := currQCnt + 1.U //counts how many items have been enqueued
}
- when(q.io.deq.fire()) {
+ 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
@@ -70,18 +70,18 @@ class QueueGetsFlushedTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int,
flush := LFSR(16)((tap + 3) % 16) //testing a flush when flush is called randomly
val halfCnt = (queueDepth + 1)/2
- when(q.io.deq.fire()) {
+ 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))
+ 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)
+ outCnt := outCnt + Mux(q.io.enq.fire, (currQCnt + 1.U), currQCnt)
currQCnt := 0.U //resets the number of items currently inside queue
}
}
@@ -102,7 +102,7 @@ class EmptyFlushEdgecaseTester (elements: Seq[Int], queueDepth: Int, bitWidth: I
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()) {
+ when(q.io.deq.fire) {
assert(elems(outCnt) === q.io.deq.bits)
outCnt := outCnt + 1.U
}
@@ -124,7 +124,7 @@ class EnqueueEmptyFlushEdgecaseTester (elements: Seq[Int], queueDepth: Int, bitW
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()) {
+ 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
@@ -145,7 +145,7 @@ class FullQueueFlushEdgecaseTester (elements: Seq[Int], queueDepth: Int, bitWidt
//testing a flush when queue is full
flush := (currQCnt === queueDepth.U)
- when(q.io.deq.fire()) {
+ 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)
@@ -177,7 +177,7 @@ class DequeueFullQueueEdgecaseTester (elements: Seq[Int], queueDepth: Int, bitWi
q.io.enq.valid := !flushRegister
q.io.deq.ready := flush
- when(q.io.deq.fire()) {
+ 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)
@@ -191,7 +191,7 @@ class DequeueFullQueueEdgecaseTester (elements: Seq[Int], queueDepth: Int, bitWi
}
when(flushRegister) {
//check that queue gets flushed when queue is full
- assert(q.io.deq.fire() === false.B)
+ assert(q.io.deq.fire === false.B)
}
}
diff --git a/src/test/scala/chiselTests/QueueSpec.scala b/src/test/scala/chiselTests/QueueSpec.scala
index 51b899cb..9eb6c20c 100644
--- a/src/test/scala/chiselTests/QueueSpec.scala
+++ b/src/test/scala/chiselTests/QueueSpec.scala
@@ -21,10 +21,10 @@ class ThingsPassThroughTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int
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()) {
+ when(q.io.enq.fire) {
inCnt.inc()
}
- when(q.io.deq.fire()) {
+ when(q.io.deq.fire) {
//ensure that what comes out is what comes in
assert(elems(outCnt.value) === q.io.deq.bits)
outCnt.inc()
@@ -51,10 +51,10 @@ class QueueReasonableReadyValid(elements: Seq[Int], queueDepth: Int, bitWidth: I
assert(q.io.deq.valid || q.io.count === 0.U)
q.io.enq.bits := elems(inCnt.value)
- when(q.io.enq.fire()) {
+ when(q.io.enq.fire) {
inCnt.inc()
}
- when(q.io.deq.fire()) {
+ when(q.io.deq.fire) {
outCnt.inc()
}
when(outCnt.value === elements.length.U) {
@@ -74,11 +74,11 @@ class CountIsCorrectTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, t
q.io.deq.ready := LFSR(16)(tap)
q.io.enq.bits := elems(inCnt.value)
- when(q.io.enq.fire()) {
+ when(q.io.enq.fire) {
inCnt.inc()
assert(q.io.count === (inCnt.value - outCnt.value))
}
- when(q.io.deq.fire()) {
+ when(q.io.deq.fire) {
outCnt.inc()
assert(q.io.count === (inCnt.value - outCnt.value))
}
@@ -103,10 +103,10 @@ class QueueSinglePipeTester(elements: Seq[Int], bitWidth: Int, tap: Int, useSync
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()) {
+ when(q.io.enq.fire) {
inCnt.inc()
}
- when(q.io.deq.fire()) {
+ when(q.io.deq.fire) {
outCnt.inc()
}
@@ -129,10 +129,10 @@ class QueuePipeTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: I
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()) {
+ when(q.io.enq.fire) {
inCnt.inc()
}
- when(q.io.deq.fire()) {
+ when(q.io.deq.fire) {
outCnt.inc()
}
@@ -155,13 +155,13 @@ class QueueFlowTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: I
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()))
+ 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()) {
+ when(q.io.enq.fire) {
inCnt.inc()
}
- when(q.io.deq.fire()) {
+ when(q.io.deq.fire) {
outCnt.inc()
}
when(outCnt.value === elements.length.U) {
@@ -183,10 +183,10 @@ class QueueFactoryTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap
deq.ready := LFSR(16)(tap)
enq.bits := elems(inCnt.value)
- when(enq.fire()) {
+ when(enq.fire) {
inCnt.inc()
}
- when(deq.fire()) {
+ when(deq.fire) {
//ensure that what comes out is what comes in
assert(elems(outCnt.value) === deq.bits)
outCnt.inc()
diff --git a/src/test/scala/chiselTests/RecordSpec.scala b/src/test/scala/chiselTests/RecordSpec.scala
index c21d455c..e6986efb 100644
--- a/src/test/scala/chiselTests/RecordSpec.scala
+++ b/src/test/scala/chiselTests/RecordSpec.scala
@@ -8,11 +8,12 @@ import chisel3.testers.BasicTester
import chisel3.util.{Counter, Queue}
import chisel3.experimental.DataMirror
+import scala.collection.immutable.SeqMap
+
trait RecordSpecUtils {
class MyBundle extends Bundle {
val foo = UInt(32.W)
val bar = UInt(32.W)
- override def cloneType: this.type = (new MyBundle).asInstanceOf[this.type]
}
// Useful for constructing types from CustomBundle
// This is a def because each call to this needs to return a new instance
@@ -65,6 +66,11 @@ trait RecordSpecUtils {
}
}
+ 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")
@@ -104,6 +110,23 @@ class RecordSpec extends ChiselFlatSpec with RecordSpecUtils with Utils {
ChiselStage.elaborate { new MyModule(new MyBundle, fooBarType) }
}
+ 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 = this
+ }
+
+ 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 "follow UInt serialization/deserialization API" in {
assertTesterPasses { new RecordSerializationTest }
}
diff --git a/src/test/scala/chiselTests/SIntOps.scala b/src/test/scala/chiselTests/SIntOps.scala
index f2e238e9..222d0ba7 100644
--- a/src/test/scala/chiselTests/SIntOps.scala
+++ b/src/test/scala/chiselTests/SIntOps.scala
@@ -44,7 +44,7 @@ class SIntOps extends Module {
io.noteqout := (a =/= b)
io.lesseqout := a <= b
io.greateqout := a >= b
- // io.negout := -a(15, 0).toSInt
+ io.negout := -a(15, 0).asSInt
io.negout := (0.S -% a)
}
diff --git a/src/test/scala/chiselTests/StrongEnum.scala b/src/test/scala/chiselTests/StrongEnum.scala
index d7dea571..404c3f66 100644
--- a/src/test/scala/chiselTests/StrongEnum.scala
+++ b/src/test/scala/chiselTests/StrongEnum.scala
@@ -257,8 +257,8 @@ class IsLitTester extends BasicTester {
for (e <- EnumExample.all) {
val wire = WireDefault(e)
- assert(e.isLit())
- assert(!wire.isLit())
+ assert(e.isLit)
+ assert(!wire.isLit)
}
stop()
}
diff --git a/src/test/scala/chiselTests/TransitNameSpec.scala b/src/test/scala/chiselTests/TransitNameSpec.scala
index b21818d6..656c6731 100644
--- a/src/test/scala/chiselTests/TransitNameSpec.scala
+++ b/src/test/scala/chiselTests/TransitNameSpec.scala
@@ -6,7 +6,6 @@ import chisel3._
import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage}
import chisel3.util.TransitName
-import firrtl.FirrtlExecutionSuccess
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
diff --git a/src/test/scala/chiselTests/UIntOps.scala b/src/test/scala/chiselTests/UIntOps.scala
index 62d00de2..bc6454b8 100644
--- a/src/test/scala/chiselTests/UIntOps.scala
+++ b/src/test/scala/chiselTests/UIntOps.scala
@@ -6,6 +6,7 @@ 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
@@ -22,6 +23,8 @@ class UIntOps extends Module {
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())
@@ -30,6 +33,8 @@ class UIntOps extends Module {
val greateqout = Output(Bool())
})
+ dontTouch(io)
+
val a = io.a
val b = io.b
@@ -42,6 +47,8 @@ class UIntOps extends Module {
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
@@ -67,6 +74,14 @@ class UIntOpsTester(a: Long, b: Long) extends BasicTester {
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)
@@ -98,6 +113,65 @@ class NegativeShift(t: => Bits) extends Module {
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(2) === false.B)
assert("b101010".U(3) === true.B)
@@ -140,6 +214,16 @@ class UIntOpsSpec extends ChiselPropSpec with Matchers with Utils {
}
}
+ 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)
}
diff --git a/src/test/scala/chiselTests/Vec.scala b/src/test/scala/chiselTests/Vec.scala
index 97aea909..24ba0bf8 100644
--- a/src/test/scala/chiselTests/Vec.scala
+++ b/src/test/scala/chiselTests/Vec.scala
@@ -313,6 +313,36 @@ class ModuleIODynamicIndexTester(n: Int) extends BasicTester {
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)
@@ -456,4 +486,8 @@ class VecSpec extends ChiselPropSpec with Utils {
}}
}
}
+
+ property("reduceTree should preserve input/output type") {
+ assertTesterPasses { new ReduceTreeTester() }
+ }
}
diff --git a/src/test/scala/chiselTests/VecLiteralSpec.scala b/src/test/scala/chiselTests/VecLiteralSpec.scala
index d91cd2f4..74d8c005 100644
--- a/src/test/scala/chiselTests/VecLiteralSpec.scala
+++ b/src/test/scala/chiselTests/VecLiteralSpec.scala
@@ -142,17 +142,17 @@ class VecLiteralSpec extends ChiselFreeSpec with Utils {
"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))
+ 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))
+ 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))
+ z.litValue should be(BigInt("03020202", 16))
}
"packing sparse vec lits should not pack, litOption returns None" in {
@@ -221,7 +221,7 @@ class VecLiteralSpec extends ChiselFreeSpec with Utils {
chisel3.assert(outsideVecLit(2) === 0xBB.U)
chisel3.assert(outsideVecLit(3) === 0xAA.U)
- chisel3.assert(outsideVecLit.litValue().U === outsideVecLit.asUInt())
+ 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)
@@ -277,15 +277,15 @@ class VecLiteralSpec extends ChiselFreeSpec with Utils {
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))
+ 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 {
@@ -473,19 +473,19 @@ class VecLiteralSpec extends ChiselFreeSpec with Utils {
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.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")
+ 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")
+ vec.litValue.toString(16) should be("defabc")
}
"bundles can contain vec lits" in {
@@ -495,7 +495,7 @@ class VecLiteralSpec extends ChiselFreeSpec with Utils {
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")
+ bundle.litValue.toString(16) should be("cbaed")
}
"bundles can contain vec lits in-line" in {
@@ -506,21 +506,21 @@ class VecLiteralSpec extends ChiselFreeSpec with Utils {
_.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")
+ 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(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(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))
+ vec.litValue should be(BigInt("bbbb000a", 16))
}
}
diff --git a/src/test/scala/chiselTests/experimental/verification/VerificationSpec.scala b/src/test/scala/chiselTests/VerificationSpec.scala
index 1e080739..2d7144df 100644
--- a/src/test/scala/chiselTests/experimental/verification/VerificationSpec.scala
+++ b/src/test/scala/chiselTests/VerificationSpec.scala
@@ -1,15 +1,14 @@
// SPDX-License-Identifier: Apache-2.0
-package chiselTests.experimental.verification
+package chiselTests
import chisel3._
import chisel3.experimental.{ChiselAnnotation, verification => formal}
import chisel3.stage.ChiselStage
-import chiselTests.ChiselPropSpec
import firrtl.annotations.{ReferenceTarget, SingleTargetAnnotation}
+import org.scalatest.matchers.should.Matchers
import java.io.File
-import org.scalatest.matchers.should.Matchers
class SimpleTest extends Module {
val io = IO(new Bundle{
@@ -17,10 +16,10 @@ class SimpleTest extends Module {
val out = Output(UInt(8.W))
})
io.out := io.in
- formal.cover(io.in === 3.U)
+ cover(io.in === 3.U)
when (io.in === 3.U) {
- formal.assume(io.in =/= 2.U)
- formal.assert(io.out === io.in)
+ assume(io.in =/= 2.U)
+ assert(io.out === io.in)
}
}
@@ -35,7 +34,7 @@ object VerifAnnotation {
/** Create annotation for a given verification component.
* @param c component to be annotated
*/
- def annotate(c: experimental.BaseSim): Unit = {
+ def annotate(c: VerificationStatement): Unit = {
chisel3.experimental.annotate(new ChiselAnnotation {
def toFirrtl: VerifAnnotation = VerifAnnotation(c.toTarget)
})
@@ -60,8 +59,8 @@ class VerificationSpec extends ChiselPropSpec with Matchers {
assertContains(lines, "when _T_6 : @[VerificationSpec.scala")
assertContains(lines, "assume(clock, _T_4, UInt<1>(\"h1\"), \"\")")
- assertContains(lines, "when _T_9 : @[VerificationSpec.scala")
- assertContains(lines, "assert(clock, _T_7, 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") {
@@ -72,9 +71,9 @@ class VerificationSpec extends ChiselPropSpec with Matchers {
val out = Output(UInt(8.W))
})
io.out := io.in
- val cov = formal.cover(io.in === 3.U)
- val assm = formal.assume(io.in =/= 2.U)
- val asst = formal.assert(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)
@@ -93,7 +92,7 @@ class VerificationSpec extends ChiselPropSpec with Matchers {
val annoLines = scala.io.Source.fromFile(annoFile).getLines.toList
// check for expected verification annotations
- exactly(3, annoLines) should include ("chiselTests.experimental.verification.VerifAnnotation")
+ 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")
@@ -106,7 +105,7 @@ class VerificationSpec extends ChiselPropSpec with Matchers {
// check that verification components have expected names
exactly(1, firLines) should include ("cover(clock, _T, UInt<1>(\"h1\"), \"\") : cov")
exactly(1, firLines) should include ("assume(clock, _T_3, UInt<1>(\"h1\"), \"\") : assm")
- exactly(1, firLines) should include ("assert(clock, _T_6, UInt<1>(\"h1\"), \"\") : asst")
+ exactly(1, firLines) should include ("assert(clock, _T_7, UInt<1>(\"h1\"), \"\") : asst")
}
property("annotation of verification constructs with suggested name should work") {
@@ -118,11 +117,11 @@ class VerificationSpec extends ChiselPropSpec with Matchers {
})
io.out := io.in
- val goodbye = formal.assert(io.in === 1.U)
+ val goodbye = chisel3.assert(io.in === 1.U)
goodbye.suggestName("hello")
VerifAnnotation.annotate(goodbye)
- VerifAnnotation.annotate(formal.assume(io.in =/= 2.U).suggestName("howdy"))
+ VerifAnnotation.annotate(chisel3.assume(io.in =/= 2.U).suggestName("howdy"))
}
// compile circuit
@@ -138,7 +137,7 @@ class VerificationSpec extends ChiselPropSpec with Matchers {
val annoLines = scala.io.Source.fromFile(annoFile).getLines.toList
// check for expected verification annotations
- exactly(2, annoLines) should include ("chiselTests.experimental.verification.VerifAnnotation")
+ exactly(2, annoLines) should include ("chiselTests.VerifAnnotation")
exactly(1, annoLines) should include ("~AnnotationRenameTest|AnnotationRenameTest>hello")
exactly(1, annoLines) should include ("~AnnotationRenameTest|AnnotationRenameTest>howdy")
@@ -149,6 +148,6 @@ class VerificationSpec extends ChiselPropSpec with Matchers {
// check that verification components have expected names
exactly(1, firLines) should include ("assert(clock, _T, UInt<1>(\"h1\"), \"\") : hello")
- exactly(1, firLines) should include ("assume(clock, _T_3, UInt<1>(\"h1\"), \"\") : howdy")
+ exactly(1, firLines) should include ("assume(clock, _T_4, UInt<1>(\"h1\"), \"\") : howdy")
}
}
diff --git a/src/test/scala/chiselTests/aop/SelectSpec.scala b/src/test/scala/chiselTests/aop/SelectSpec.scala
index e09e78c8..2b47c6b8 100644
--- a/src/test/scala/chiselTests/aop/SelectSpec.scala
+++ b/src/test/scala/chiselTests/aop/SelectSpec.scala
@@ -133,11 +133,10 @@ class SelectSpec extends ChiselFlatSpec {
{ dut: SelectTester =>
Seq(Select.Stop(
Seq(
- When(Select.ops("eq")(dut).dropRight(1).last.asInstanceOf[Bool]),
- When(dut.nreset),
- WhenNot(dut.overflow)
+ When(Select.ops("eq")(dut)(1).asInstanceOf[Bool]),
+ When(dut.overflow)
),
- 1,
+ 0,
dut.clock
))
}
diff --git a/src/test/scala/chiselTests/experimental/DataView.scala b/src/test/scala/chiselTests/experimental/DataView.scala
index d1620e88..7c5d170b 100644
--- a/src/test/scala/chiselTests/experimental/DataView.scala
+++ b/src/test/scala/chiselTests/experimental/DataView.scala
@@ -5,7 +5,9 @@ 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.HWTuple2
import chisel3.stage.ChiselStage
import chisel3.util.{Decoupled, DecoupledIO}
@@ -50,69 +52,6 @@ object FlatDecoupledDataView {
implicit val view2 = view.invert(_ => new FlatDecoupled)
}
-// This should become part of Chisel in a later PR
-object Tuple2DataProduct {
- implicit def tuple2DataProduct[A : DataProduct, B : DataProduct] = new DataProduct[(A, B)] {
- def dataIterator(tup: (A, B), path: String): Iterator[(Data, String)] = {
- val dpa = implicitly[DataProduct[A]]
- val dpb = implicitly[DataProduct[B]]
- val (a, b) = tup
- dpa.dataIterator(a, s"$path._1") ++ dpb.dataIterator(b, s"$path._2")
- }
- }
-}
-
-// This should become part of Chisel in a later PR
-object HWTuple {
- import Tuple2DataProduct._
-
- class HWTuple2[A <: Data, B <: Data](val _1: A, val _2: B) extends Bundle
-
- implicit def view[T1 : DataProduct, T2 : DataProduct, V1 <: Data, V2 <: Data](
- implicit v1: DataView[T1, V1], v2: DataView[T2, V2]
- ): DataView[(T1, T2), HWTuple2[V1, V2]] =
- DataView.mapping(
- { case (a, b) => new HWTuple2(a.viewAs[V1].cloneType, b.viewAs[V2].cloneType)},
- { case ((a, b), hwt) =>
- Seq(a.viewAs[V1] -> hwt._1,
- b.viewAs[V2] -> hwt._2)
- }
- )
-
- implicit def tuple2hwtuple[T1 : DataProduct, T2 : DataProduct, V1 <: Data, V2 <: Data](
- tup: (T1, T2))(implicit v1: DataView[T1, V1], v2: DataView[T2, V2]
- ): HWTuple2[V1, V2] = tup.viewAs[HWTuple2[V1, V2]]
-}
-
-// This should become part of Chisel in a later PR
-object SeqDataProduct {
- // Should we special case Seq[Data]?
- implicit def seqDataProduct[A : DataProduct]: DataProduct[Seq[A]] = new DataProduct[Seq[A]] {
- def dataIterator(a: Seq[A], path: String): Iterator[(Data, String)] = {
- val dpa = implicitly[DataProduct[A]]
- a.iterator
- .zipWithIndex
- .flatMap { case (elt, idx) =>
- dpa.dataIterator(elt, s"$path[$idx]")
- }
- }
- }
-}
-
-object SeqToVec {
- import SeqDataProduct._
-
- // TODO this would need a better way to determine the prototype for the Vec
- implicit def seqVec[A : DataProduct, B <: Data](implicit dv: DataView[A, B]): DataView[Seq[A], Vec[B]] =
- DataView.mapping[Seq[A], Vec[B]](
- xs => Vec(xs.size, chiselTypeClone(xs.head.viewAs[B])), // xs.head is not correct in general
- { case (s, v) => s.zip(v).map { case (a, b) => a.viewAs[B] -> b } }
- )
-
- implicit def seq2Vec[A : DataProduct, B <: Data](xs: Seq[A])(implicit dv: DataView[A, B]): Vec[B] =
- xs.viewAs[Vec[B]]
-}
-
class DataViewSpec extends ChiselFlatSpec {
behavior of "DataView"
@@ -327,15 +266,14 @@ class DataViewSpec extends ChiselFlatSpec {
chirrtl should include ("z.fizz <= b.foo")
}
- // This example should be turned into a built-in feature
- it should "enable implementing \"HardwareTuple\"" in {
- import HWTuple._
-
+ 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)))
- (y, z) := Mux(sel, (a, b), (c, d))
+ // 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)
@@ -343,25 +281,8 @@ class DataViewSpec extends ChiselFlatSpec {
verilog should include ("assign z = sel ? b : d;")
}
- it should "support nesting of tuples" in {
- import Tuple2DataProduct._
- import HWTuple._
-
- 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")
- }
-
// This example should be turned into a built-in feature
it should "enable viewing Seqs as Vecs" in {
- import SeqToVec._
class MyModule extends Module {
val a, b, c = IO(Input(UInt(8.W)))
@@ -376,11 +297,6 @@ class DataViewSpec extends ChiselFlatSpec {
}
it should "support recursive composition of views" in {
- import Tuple2DataProduct._
- import SeqDataProduct._
- import SeqToVec._
- import HWTuple._
-
class MyModule extends Module {
val a, b, c, d = IO(Input(UInt(8.W)))
val w, x, y, z = IO(Output(UInt(8.W)))
@@ -397,12 +313,26 @@ class DataViewSpec extends ChiselFlatSpec {
verilog should include ("assign z = d;")
}
- it should "error if you try to dynamically index a Vec view" in {
- import SeqDataProduct._
- import SeqToVec._
- import Tuple2DataProduct._
- import HWTuple._
+ 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 "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)))
@@ -411,6 +341,7 @@ class DataViewSpec extends ChiselFlatSpec {
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
@@ -434,7 +365,6 @@ class DataViewSpec extends ChiselFlatSpec {
}
it should "error if the mapping is non-total in the target" in {
- import Tuple2DataProduct._
implicit val dv = DataView[(UInt, UInt), UInt](_ => UInt(), _._1 -> _)
class MyModule extends Module {
val a, b = IO(Input(UInt(8.W)))
@@ -533,7 +463,6 @@ class DataViewSpec extends ChiselFlatSpec {
}
it should "NOT error if the mapping is non-total in the target" in {
- import Tuple2DataProduct._
implicit val dv = PartialDataView[(UInt, UInt), UInt](_ => UInt(), _._2 -> _)
class MyModule extends Module {
val a, b = IO(Input(UInt(8.W)))
diff --git a/src/test/scala/chiselTests/experimental/DataViewTargetSpec.scala b/src/test/scala/chiselTests/experimental/DataViewTargetSpec.scala
index 92091631..a17b0f40 100644
--- a/src/test/scala/chiselTests/experimental/DataViewTargetSpec.scala
+++ b/src/test/scala/chiselTests/experimental/DataViewTargetSpec.scala
@@ -4,8 +4,8 @@ package chiselTests.experimental
import chisel3._
import chisel3.experimental.dataview._
+import chisel3.experimental.conversions._
import chisel3.experimental.{ChiselAnnotation, annotate}
-import chisel3.stage.ChiselStage
import chiselTests.ChiselFlatSpec
object DataViewTargetSpec {
@@ -127,7 +127,6 @@ class DataViewTargetSpec extends ChiselFlatSpec {
}
it should "support annotating views that cannot be mapped to a single ReferenceTarget" in {
- import HWTuple._
class MyBundle extends Bundle {
val a, b = Input(UInt(8.W))
val c, d = Output(UInt(8.W))
diff --git a/src/test/scala/chiselTests/experimental/TraceSpec.scala b/src/test/scala/chiselTests/experimental/TraceSpec.scala
new file mode 100644
index 00000000..59548921
--- /dev/null
+++ b/src/test/scala/chiselTests/experimental/TraceSpec.scala
@@ -0,0 +1,309 @@
+// SPDX-License-Identifier: Apache-2.0
+
+package chiselTests
+
+import chisel3._
+import chisel3.experimental.ChiselEnum
+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
new file mode 100644
index 00000000..5f897fbc
--- /dev/null
+++ b/src/test/scala/chiselTests/experimental/Tuple.scala
@@ -0,0 +1,163 @@
+// 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
index 43111fdd..eba412f1 100644
--- a/src/test/scala/chiselTests/experimental/hierarchy/Annotations.scala
+++ b/src/test/scala/chiselTests/experimental/hierarchy/Annotations.scala
@@ -5,24 +5,20 @@ package chiselTests.experimental.hierarchy
import _root_.firrtl.annotations._
import chisel3.experimental.{annotate, BaseModule}
import chisel3.Data
-import chisel3.experimental.hierarchy.{Instance, Definition}
+import chisel3.experimental.hierarchy.{Instance, Definition, Hierarchy}
object Annotations {
case class MarkAnnotation(target: IsMember, tag: String) extends SingleTargetAnnotation[IsMember] {
def duplicate(n: IsMember): Annotation = this.copy(target = n)
}
- case class MarkChiselInstanceAnnotation[B <: BaseModule](d: Instance[B], tag: String, isAbsolute: Boolean) extends chisel3.experimental.ChiselAnnotation {
- def toFirrtl = MarkAnnotation(d.toTarget, tag)
- }
- case class MarkChiselDefinitionAnnotation[B <: BaseModule](d: Definition[B], tag: String, isAbsolute: Boolean) extends chisel3.experimental.ChiselAnnotation {
+ 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)
}
def mark(d: Data, tag: String): Unit = annotate(MarkChiselAnnotation(d, tag, false))
- def mark[B <: BaseModule](d: Instance[B], tag: String): Unit = annotate(MarkChiselInstanceAnnotation(d, tag, false))
- def mark[B <: BaseModule](d: Definition[B], tag: String): Unit = annotate(MarkChiselDefinitionAnnotation(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: Instance[B], tag: String): Unit = annotate(MarkChiselInstanceAnnotation(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
index 19261c36..f33f7869 100644
--- a/src/test/scala/chiselTests/experimental/hierarchy/DefinitionSpec.scala
+++ b/src/test/scala/chiselTests/experimental/hierarchy/DefinitionSpec.scala
@@ -40,6 +40,44 @@ class DefinitionSpec extends ChiselFunSpec with Utils {
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") {
@@ -97,7 +135,7 @@ class DefinitionSpec extends ChiselFunSpec with Utils {
mark(definition.i1, "i0.i1")
}
val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddTwoMixedModules/i1:AddOne_2".it, "i0.i1"))
+ 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
@@ -258,6 +296,17 @@ class DefinitionSpec extends ChiselFunSpec with Utils {
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"))
+ }
}
describe("4: toDefinition") {
it("4.0: should work on modules") {
@@ -311,7 +360,7 @@ class DefinitionSpec extends ChiselFunSpec with Utils {
amark(i.i1.in, "blah")
}
val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|AddTwoMixedModules/i1:AddOne_2>in".rt, "blah"))
+ 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 {
@@ -319,7 +368,7 @@ class DefinitionSpec extends ChiselFunSpec with Utils {
amark(i.i1.x.head, "blah")
}
val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|InstantiatesHasVec/i1:HasVec_2>x[0]".rt, "blah"))
+ annos should contain(MarkAnnotation("~Top|InstantiatesHasVec/i1:HasVec_1>x[0]".rt, "blah"))
}
}
describe("6: @instantiable traits should work as expected") {
diff --git a/src/test/scala/chiselTests/experimental/hierarchy/Examples.scala b/src/test/scala/chiselTests/experimental/hierarchy/Examples.scala
index 23b8c9c0..c0f504ff 100644
--- a/src/test/scala/chiselTests/experimental/hierarchy/Examples.scala
+++ b/src/test/scala/chiselTests/experimental/hierarchy/Examples.scala
@@ -36,6 +36,19 @@ object Examples {
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 AddTwo extends Module {
@public val in = IO(Input(UInt(32.W)))
@public val out = IO(Output(UInt(32.W)))
@@ -58,6 +71,33 @@ object Examples {
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))
@@ -183,4 +223,17 @@ object Examples {
@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)
+ }
}
diff --git a/src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala b/src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala
index 3866bf87..9ceb9b40 100644
--- a/src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala
+++ b/src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala
@@ -89,7 +89,7 @@ class InstanceSpec extends ChiselFunSpec with Utils {
mark(i0.i1, "i0.i1")
}
val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain (MarkAnnotation("~Top|Top/i0:AddTwoMixedModules/i1:AddOne_2".it, "i0.i1"))
+ 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 {
@@ -144,6 +144,15 @@ class InstanceSpec extends ChiselFunSpec with Utils {
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") {
@@ -353,7 +362,7 @@ class InstanceSpec extends ChiselFunSpec with Utils {
amark(i.i1.in, "blah")
}
val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:AddTwoMixedModules/i1:AddOne_2>in".rt, "blah"))
+ 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 {
@@ -361,7 +370,7 @@ class InstanceSpec extends ChiselFunSpec with Utils {
amark(i.i1.x.head, "blah")
}
val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:InstantiatesHasVec/i1:HasVec_2>x[0]".rt, "blah"))
+ 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) }
@@ -379,7 +388,7 @@ class InstanceSpec extends ChiselFunSpec with Utils {
amark(i.i1.x.head.x, "blah")
}
val (_, annos) = getFirrtlAndAnnos(new Top)
- annos should contain(MarkAnnotation("~Top|Top/i:InstantiatesHasVec/i1:HasVec_2>x[0].x".rt, "blah"))
+ 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 {
@@ -620,7 +629,7 @@ class InstanceSpec extends ChiselFunSpec with Utils {
}
it("7.3: should work with DataView + implicit conversion") {
- import chiselTests.experimental.SeqToVec._
+ import chisel3.experimental.conversions._
@instantiable
class MyModule extends RawModule {
private val a = IO(Input(UInt(8.W)))
@@ -705,5 +714,142 @@ class InstanceSpec extends ChiselFunSpec with Utils {
}
}
}
+ 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)
+ }
+ }
+ 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)) }
+ }
+ }
}
diff --git a/src/test/scala/chiselTests/util/BitPatSpec.scala b/src/test/scala/chiselTests/util/BitPatSpec.scala
index 0c83493f..549e8bca 100644
--- a/src/test/scala/chiselTests/util/BitPatSpec.scala
+++ b/src/test/scala/chiselTests/util/BitPatSpec.scala
@@ -24,10 +24,18 @@ class BitPatSpec extends AnyFlatSpec with Matchers {
intercept[IllegalArgumentException]{BitPat("b")}
}
- it should "contact BitPat via ##" in {
+ 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))
diff --git a/src/test/scala/chiselTests/util/BitSetSpec.scala b/src/test/scala/chiselTests/util/BitSetSpec.scala
new file mode 100644
index 00000000..8120cc97
--- /dev/null
+++ b/src/test/scala/chiselTests/util/BitSetSpec.scala
@@ -0,0 +1,119 @@
+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??????"
+ )
+ ), true)
+ })
+ }
+
+}
diff --git a/src/test/scala/chiselTests/util/experimental/TruthTableSpec.scala b/src/test/scala/chiselTests/util/experimental/TruthTableSpec.scala
index 743a3cd8..255effaf 100644
--- a/src/test/scala/chiselTests/util/experimental/TruthTableSpec.scala
+++ b/src/test/scala/chiselTests/util/experimental/TruthTableSpec.scala
@@ -2,8 +2,9 @@
package chiselTests.util.experimental
+import chisel3._
import chisel3.util.BitPat
-import chisel3.util.experimental.decode.TruthTable
+import chisel3.util.experimental.decode.{TruthTable, decoder}
import org.scalatest.flatspec.AnyFlatSpec
class TruthTableSpec extends AnyFlatSpec {
@@ -34,16 +35,16 @@ class TruthTableSpec extends AnyFlatSpec {
assert(table.toString contains " 0")
}
"TruthTable" should "deserialize" in {
- assert(TruthTable(str) == table)
+ assert(TruthTable.fromString(str) == table)
}
"TruthTable" should "merge same key" in {
assert(
- TruthTable(
+ TruthTable.fromString(
"""001100->??1
|001100->1??
|???
|""".stripMargin
- ) == TruthTable(
+ ) == TruthTable.fromString(
"""001100->1?1
|???
|""".stripMargin
@@ -52,7 +53,7 @@ class TruthTableSpec extends AnyFlatSpec {
}
"TruthTable" should "crash when merging 0 and 1" in {
intercept[IllegalArgumentException] {
- TruthTable(
+ TruthTable.fromString(
"""0->0
|0->1
|???
@@ -60,4 +61,24 @@ class TruthTableSpec extends AnyFlatSpec {
)
}
}
+ "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))
+ }
}