From 4e69127e1897c8e3ca809748cc9491597cdfcc06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksandar=20Kondi=C4=87?= Date: Mon, 24 Jul 2023 13:18:12 +0200 Subject: [PATCH] Refactor tests (#2) * Use new FixedPoint instead of chisel's FixedPoint in all tests * Remove irrelevant test cases * Reformat files with scalafmt * Add scalafmt to CI --- .github/workflows/test.yml | 2 + project/plugins.sbt | 2 + src/main/scala/fixedpoint/FixedPoint.scala | 4 +- src/test/scala/AsTypeOfTester.scala | 127 +----- src/test/scala/BundleLiteralSpec.scala | 332 +------------- src/test/scala/ChiselSpec.scala | 8 +- src/test/scala/ConnectSpec.scala | 132 +----- src/test/scala/DataEqualitySpec.scala | 185 +------- src/test/scala/DataPrint.scala | 79 +--- src/test/scala/FixedPointSpec.scala | 10 +- src/test/scala/LiteralExtractorSpec.scala | 91 +--- src/test/scala/OneHotMuxSpec.scala | 94 +--- src/test/scala/UIntOps.scala | 288 ------------ src/test/scala/VecLiteralSpec.scala | 483 +-------------------- 14 files changed, 48 insertions(+), 1789 deletions(-) create mode 100644 project/plugins.sbt delete mode 100644 src/test/scala/UIntOps.scala diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b8cce31..64c8aef 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -74,5 +74,7 @@ jobs: sudo make install verilator --version + - name: Check scalafmt + run: sbt scalafmtCheckAll - name: Run tests run: sbt test diff --git a/project/plugins.sbt b/project/plugins.sbt new file mode 100644 index 0000000..cda0008 --- /dev/null +++ b/project/plugins.sbt @@ -0,0 +1,2 @@ +val scalafmtPluginVersion = "2.4.6" +addSbtPlugin("org.scalameta" % "sbt-scalafmt" % scalafmtPluginVersion) diff --git a/src/main/scala/fixedpoint/FixedPoint.scala b/src/main/scala/fixedpoint/FixedPoint.scala index 92e1ebb..a813586 100644 --- a/src/main/scala/fixedpoint/FixedPoint.scala +++ b/src/main/scala/fixedpoint/FixedPoint.scala @@ -201,8 +201,8 @@ sealed class FixedPoint private[fixedpoint] (width: Width, private var _inferred } private def additiveOp( - that: FixedPoint, - f: (SInt, SInt) => SInt + that: FixedPoint, + f: (SInt, SInt) => SInt )( implicit sourceInfo: SourceInfo, compileOptions: CompileOptions diff --git a/src/test/scala/AsTypeOfTester.scala b/src/test/scala/AsTypeOfTester.scala index 98b8c55..1f51e50 100644 --- a/src/test/scala/AsTypeOfTester.scala +++ b/src/test/scala/AsTypeOfTester.scala @@ -1,9 +1,8 @@ // SPDX-License-Identifier: Apache-2.0 - -import chisel3._ -import chisel3.experimental.{DataMirror, FixedPoint} import chisel3.testers.BasicTester +import chisel3.{fromDoubleToLiteral => _, fromIntToBinaryPoint => _, _} +import fixedpoint._ class AsTypeOfBundleTester extends BasicTester { class MultiTypeBundle extends Bundle { @@ -23,132 +22,10 @@ class AsTypeOfBundleTester extends BasicTester { stop() } -class AsTypeOfBundleZeroWidthTester extends BasicTester { - class ZeroWidthBundle extends Bundle { - val a = UInt(0.W) - val b = UInt(1.W) - val c = UInt(0.W) - } - - val bun = new ZeroWidthBundle - - val bunAsTypeOf = 1.U.asTypeOf(bun) - - assert(bunAsTypeOf.a === 0.U) - assert(bunAsTypeOf.b === 1.U) - assert(bunAsTypeOf.c === 0.U) - - stop() -} - -class AsTypeOfVecTester extends BasicTester { - val vec = ((15 << 12) + (0 << 8) + (1 << 4) + (2 << 0)).U.asTypeOf(Vec(4, SInt(4.W))) - - assert(vec(0) === 2.S) - assert(vec(1) === 1.S) - assert(vec(2) === 0.S) - assert(vec(3) === -1.S) - - stop() -} - -class AsTypeOfTruncationTester extends BasicTester { - val truncate = (64 + 3).U.asTypeOf(UInt(3.W)) - val expand = 1.U.asTypeOf(UInt(3.W)) - - assert(DataMirror.widthOf(truncate).get == 3) - assert(truncate === 3.U) - assert(DataMirror.widthOf(expand).get == 3) - assert(expand === 1.U) - - stop() -} - -class ResetAsTypeOfBoolTester extends BasicTester { - assert(reset.asTypeOf(Bool()) === reset.asBool) - stop() -} - -class AsTypeOfClockTester extends BasicTester { - class MyBundle extends Bundle { - val x = UInt(4.W) - val y = Clock() - } - assert(true.B.asTypeOf(Clock()).asUInt.asBool === true.B) - - assert(0x1f.U.asTypeOf(new MyBundle).asUInt === 0x1f.U) - stop() -} - -class AsChiselEnumTester extends BasicTester { - object MyEnum extends ChiselEnum { - val foo, bar = Value - val fizz = Value(2.U) - } - class MyBundle extends Bundle { - val a = Bool() - val b = Bool() - } - - // To - assert(2.U.asTypeOf(MyEnum()) === MyEnum.fizz) - assert(VecInit(2.U.asBools).asTypeOf(MyEnum()) === MyEnum.fizz) - assert(2.U.asTypeOf(new MyBundle).asTypeOf(MyEnum()) === MyEnum.fizz) - - // From - assert(MyEnum.foo.asUInt === 0.U) - val vec = MyEnum.bar.asTypeOf(Vec(2, Bool())) - assert(vec(0) === 1.U) - assert(vec(1) === 0.U) - val bun = MyEnum.fizz.asTypeOf(new MyBundle) - assert(bun.b === 0.U) - assert(bun.a === 1.U) - - // In aggregate - class OtherBundle extends Bundle { - val enum = MyEnum() - val foo = Bool() - } - val wire = Wire(new OtherBundle) - wire.enum := MyEnum.fizz - wire.foo := true.B - - assert(wire.asUInt === 5.U) - val other = 5.U.asTypeOf(new OtherBundle) - assert(other.enum === MyEnum.fizz) - assert(other.foo === true.B) - - stop() -} - class AsTypeOfSpec extends ChiselFlatSpec { behavior.of("asTypeOf") it should "work with Bundles containing Bits Types" in { assertTesterPasses { new AsTypeOfBundleTester } } - - it should "work with Bundles that have fields of zero width" in { - assertTesterPasses { new AsTypeOfBundleZeroWidthTester } - } - - it should "work with Vecs containing Bits Types" in { - assertTesterPasses { new AsTypeOfVecTester } - } - - it should "expand and truncate UInts of different width" in { - assertTesterPasses { new AsTypeOfTruncationTester } - } - - it should "work for casting implicit Reset to Bool" in { - assertTesterPasses { new ResetAsTypeOfBoolTester } - } - - it should "work for casting to and from ChiselEnums" in { - assertTesterPasses(new AsChiselEnumTester) - } - - it should "work for casting to and from Clock" in { - assertTesterPasses(new AsTypeOfClockTester) - } } diff --git a/src/test/scala/BundleLiteralSpec.scala b/src/test/scala/BundleLiteralSpec.scala index da3ad1d..a0ce57d 100644 --- a/src/test/scala/BundleLiteralSpec.scala +++ b/src/test/scala/BundleLiteralSpec.scala @@ -1,28 +1,11 @@ // SPDX-License-Identifier: Apache-2.0 - -import chisel3._ -import chisel3.stage.ChiselStage -import chisel3.testers.BasicTester +import chisel3.{fromDoubleToLiteral => _, fromIntToBinaryPoint => _, _} import chisel3.experimental.BundleLiterals._ -import chisel3.experimental.VecLiterals.AddVecLiteralConstructor -import chisel3.experimental.{BundleLiteralException, ChiselRange, Interval} -import fixedpoint.{FixedPoint, fromIntToBinaryPoint, fromDoubleToLiteral} -import org.scalatest.flatspec.AnyFlatSpec -import org.scalatest.matchers.should.Matchers +import chisel3.testers.BasicTester +import fixedpoint._ class BundleLiteralSpec extends ChiselFlatSpec with Utils { - object MyEnum extends ChiselEnum { - val sA, sB = Value - } - object MyEnumB extends ChiselEnum { - val sA, sB = Value - } - class MyBundle extends Bundle { - val a = UInt(8.W) - val b = Bool() - val c = MyEnum() - } class LongBundle extends Bundle { val a = UInt(48.W) @@ -33,10 +16,6 @@ class BundleLiteralSpec extends ChiselFlatSpec with Utils { "bundle literals" should "pack" in { assertTesterPasses { new BasicTester { - val bundleLit = (new MyBundle).Lit(_.a -> 42.U, _.b -> false.B, _.c -> MyEnum.sB) - bundleLit.litOption should equal(Some(169)) // packed as 42 (8-bit), false=0 (1-bit), sB=1 (1-bit) - chisel3.assert(bundleLit.asUInt() === bundleLit.litOption.get.U) // sanity-check consistency with runtime - val longBundleLit = (new LongBundle).Lit(_.a -> 0xdeaddeadbeefL.U, _.b -> (-0x0beef00dL).S(32.W), _.c -> 4.5.F(16.W, 4.BP)) longBundleLit.litOption should equal( @@ -46,313 +25,10 @@ class BundleLiteralSpec extends ChiselFlatSpec with Utils { + BigInt(72) ) ) - chisel3.assert(longBundleLit.asUInt() === longBundleLit.litOption.get.U) - - stop() - } - } - } - - "bundle literals" should "work in RTL" in { - val outsideBundleLit = (new MyBundle).Lit(_.a -> 42.U, _.b -> true.B, _.c -> MyEnum.sB) - assertTesterPasses { - new BasicTester { - // TODO: add direct bundle compare operations, when that feature is added - chisel3.assert(outsideBundleLit.a === 42.U) - chisel3.assert(outsideBundleLit.b === true.B) - chisel3.assert(outsideBundleLit.c === MyEnum.sB) - chisel3.assert(outsideBundleLit.isLit()) - chisel3.assert(outsideBundleLit.litValue().U === outsideBundleLit.asUInt()) - val bundleLit = (new MyBundle).Lit(_.a -> 42.U, _.b -> true.B, _.c -> MyEnum.sB) - chisel3.assert(bundleLit.a === 42.U) - chisel3.assert(bundleLit.b === true.B) - chisel3.assert(bundleLit.c === MyEnum.sB) - - chisel3.assert(bundleLit.a === outsideBundleLit.a) - chisel3.assert(bundleLit.b === outsideBundleLit.b) - chisel3.assert(bundleLit.c === outsideBundleLit.c) - - val bundleWire = Wire(new MyBundle) - bundleWire := outsideBundleLit - - chisel3.assert(bundleWire.a === 42.U) - chisel3.assert(bundleWire.b === true.B) - chisel3.assert(bundleWire.c === MyEnum.sB) - - stop() - } - } - } - - "bundle literals of vec literals" should "work" in { - assertTesterPasses(new BasicTester { - val range = range"[0,4].2" - val bundleWithVecs = new Bundle { - val a = Vec(2, UInt(4.W)) - val b = Vec(2, Interval(range)) - }.Lit( - _.a -> Vec(2, UInt(4.W)).Lit(0 -> 0xa.U, 1 -> 0xb.U), - _.b -> Vec(2, Interval(range)).Lit(0 -> (1.5).I(range), 1 -> (0.25).I(range)) - ) - chisel3.assert(bundleWithVecs.a(0) === 0xa.U) - chisel3.assert(bundleWithVecs.a(1) === 0xb.U) - chisel3.assert(bundleWithVecs.b(0) === (1.5).I(range)) - chisel3.assert(bundleWithVecs.b(1) === (0.25).I(range)) - stop() - }) - } - - "partial bundle literals" should "work in RTL" in { - assertTesterPasses { - new BasicTester { - val bundleLit = (new MyBundle).Lit(_.a -> 42.U) - chisel3.assert(bundleLit.a === 42.U) - - val bundleWire = Wire(new MyBundle) - bundleWire := bundleLit - - chisel3.assert(bundleWire.a === 42.U) + chisel3.assert(longBundleLit.asUInt === longBundleLit.litOption.get.U) stop() } } } - - class MyOuterBundle extends Bundle { - val a = new MyBundle - val b = new Bundle { - val c = Bool() - val d = UInt(8.W) - val e = MyEnum() - } - val f = MyEnum() - } - - "contained bundles" should "work" in { - assertTesterPasses { - new BasicTester { - // Specify the inner Bundle value as a Bundle literal - val explicitBundleLit = (new MyOuterBundle).Lit( - _.a -> (new MyBundle).Lit(_.a -> 42.U, _.b -> true.B, _.c -> MyEnum.sB) - ) - chisel3.assert(explicitBundleLit.a.a === 42.U) - chisel3.assert(explicitBundleLit.a.b === true.B) - chisel3.assert(explicitBundleLit.a.c === MyEnum.sB) - chisel3.assert(explicitBundleLit.a.isLit()) - chisel3.assert(explicitBundleLit.a.litValue().U === explicitBundleLit.a.asUInt()) - - // Specify the inner Bundle fields directly - val expandedBundleLit = (new MyOuterBundle).Lit( - _.a.a -> 42.U, - _.a.b -> true.B, - _.b.c -> false.B, - _.b.d -> 255.U, - _.b.e -> MyEnum.sB, - _.f -> MyEnum.sB - ) - chisel3.assert(expandedBundleLit.a.a === 42.U) - chisel3.assert(expandedBundleLit.a.b === true.B) - chisel3.assert(expandedBundleLit.f === MyEnum.sB) - chisel3.assert(expandedBundleLit.b.c === false.B) - chisel3.assert(expandedBundleLit.b.d === 255.U) - chisel3.assert(expandedBundleLit.b.e === MyEnum.sB) - chisel3.assert(!expandedBundleLit.a.isLit()) // element e is missing - chisel3.assert(expandedBundleLit.b.isLit()) - chisel3.assert(!expandedBundleLit.isLit()) // element a.e is missing - chisel3.assert(expandedBundleLit.b.litValue().U === expandedBundleLit.b.asUInt()) - - // Anonymously contruct the inner Bundle literal - // A bit of weird syntax that depends on implementation details of the Bundle literal constructor - val childBundleLit = - (new MyOuterBundle).Lit(b => b.b -> b.b.Lit(_.c -> false.B, _.d -> 255.U, _.e -> MyEnum.sB)) - chisel3.assert(childBundleLit.b.c === false.B) - chisel3.assert(childBundleLit.b.d === 255.U) - chisel3.assert(childBundleLit.b.e === MyEnum.sB) - chisel3.assert(childBundleLit.b.isLit()) - chisel3.assert(!childBundleLit.isLit()) // elements a and f are missing - chisel3.assert(childBundleLit.b.litValue().U === childBundleLit.b.asUInt()) - - stop() - } - } - } - - "Bundle literals" should "assign" in { - assertTesterPasses { - new BasicTester { - val bundleWire = Wire(Output(new MyBundle)) - val bundleLit = (new MyBundle).Lit(_.a -> 42.U, _.b -> true.B, _.c -> MyEnum.sB) - bundleWire := bundleLit - - chisel3.assert(bundleWire.a === 42.U) - chisel3.assert(bundleWire.b === true.B) - chisel3.assert(bundleWire.c === MyEnum.sB) - stop() - } - } - } - - "partially initialized Bundle literals" should "assign" in { - assertTesterPasses { - new BasicTester { - val bundleWire = Wire(Output(new MyBundle)) - val bundleLit = (new MyBundle).Lit(_.a -> 42.U) - bundleWire := bundleLit - - chisel3.assert(bundleWire.a === 42.U) - stop() - } - } - } - - "Bundle literals" should "work as register reset values" in { - assertTesterPasses { - new BasicTester { - val r = RegInit((new MyBundle).Lit(_.a -> 42.U, _.b -> true.B, _.c -> MyEnum.sB)) - r := (r.asUInt + 1.U).asTypeOf(new MyBundle) // prevent constprop - - // check reset values on first cycle out of reset - chisel3.assert(r.a === 42.U) - chisel3.assert(r.b === true.B) - chisel3.assert(r.c === MyEnum.sB) - stop() - } - } - } - - "partially initialized Bundle literals" should "work as register reset values" in { - assertTesterPasses { - new BasicTester { - val r = RegInit((new MyBundle).Lit(_.a -> 42.U)) - r.a := r.a + 1.U // prevent const prop - chisel3.assert(r.a === 42.U) // coming out of reset - stop() - } - } - } - - "Fields extracted from BundleLiterals" should "work as register reset values" in { - assertTesterPasses { - new BasicTester { - val r = RegInit((new MyBundle).Lit(_.a -> 42.U).a) - r := r + 1.U // prevent const prop - chisel3.assert(r === 42.U) // coming out of reset - stop() - } - } - } - - "DontCare fields extracted from BundleLiterals" should "work as register reset values" in { - assertTesterPasses { - new BasicTester { - val r = RegInit((new MyBundle).Lit(_.a -> 42.U).b) - r := reset.asBool - printf(p"r = $r\n") // Can't assert because reset value is DontCare - stop() - } - } - } - - "DontCare fields extracted from BundleLiterals" should "work in other Expressions" in { - assertTesterPasses { - new BasicTester { - val x = (new MyBundle).Lit(_.a -> 42.U).b || true.B - chisel3.assert(x === true.B) - stop() - } - } - } - - "bundle literals with bad field specifiers" should "fail" in { - val exc = intercept[BundleLiteralException] { - extractCause[BundleLiteralException] { - ChiselStage.elaborate { - new RawModule { - val bundle = new MyBundle - bundle.Lit(x => bundle.a -> 0.U) // DONT DO THIS, this gets past a syntax error to exercise the failure - } - } - } - } - exc.getMessage should include("not a field") - } - - "bundle literals with duplicate fields" should "fail" in { - val exc = intercept[BundleLiteralException] { - extractCause[BundleLiteralException] { - ChiselStage.elaborate { - new RawModule { - (new MyBundle).Lit(_.a -> 0.U, _.a -> 0.U) - } - } - } - } - exc.getMessage should include("duplicate") - exc.getMessage should include(".a") - } - - "bundle literals with non-literal values" should "fail" in { - val exc = intercept[BundleLiteralException] { - extractCause[BundleLiteralException] { - ChiselStage.elaborate { - new RawModule { - (new MyBundle).Lit(_.a -> UInt()) - } - } - } - } - exc.getMessage should include("non-literal value") - exc.getMessage should include(".a") - } - - "bundle literals with non-type-equivalent element fields" should "fail" in { - val exc = intercept[BundleLiteralException] { - extractCause[BundleLiteralException] { - ChiselStage.elaborate { - new RawModule { - (new MyBundle).Lit(_.a -> true.B) - } - } - } - } - exc.getMessage should include("non-type-equivalent value") - exc.getMessage should include(".a") - } - - "bundle literals with non-type-equivalent sub-bundles" should "fail" in { - val exc = intercept[BundleLiteralException] { - extractCause[BundleLiteralException] { - ChiselStage.elaborate { - new RawModule { - (new MyOuterBundle).Lit(_.b -> (new MyBundle).Lit(_.a -> 0.U)) - } - } - } - } - exc.getMessage should include("non-type-equivalent value") - exc.getMessage should include(".b") - } - - "bundle literals with non-type-equivalent enum element fields" should "fail" in { - val exc = intercept[BundleLiteralException] { - extractCause[BundleLiteralException] { - ChiselStage.elaborate { - new RawModule { - (new MyBundle).Lit(_.c -> MyEnumB.sB) - } - } - } - } - exc.getMessage should include("non-type-equivalent enum value") - exc.getMessage should include(".c") - } - - "partial bundle literals" should "fail to pack" in { - ChiselStage.elaborate { - new RawModule { - val bundleLit = (new MyBundle).Lit(_.a -> 42.U) - bundleLit.litOption should equal(None) - } - } - } } diff --git a/src/test/scala/ChiselSpec.scala b/src/test/scala/ChiselSpec.scala index be74a48..4fdd762 100644 --- a/src/test/scala/ChiselSpec.scala +++ b/src/test/scala/ChiselSpec.scala @@ -1,10 +1,14 @@ // SPDX-License-Identifier: Apache-2.0 - import _root_.logger.Logger import chisel3._ import chisel3.aop.Aspect -import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage, NoRunFirrtlCompilerAnnotation, PrintFullStackTraceAnnotation} +import chisel3.stage.{ + ChiselGeneratorAnnotation, + ChiselStage, + NoRunFirrtlCompilerAnnotation, + PrintFullStackTraceAnnotation +} import chisel3.testers._ import firrtl.annotations.Annotation import firrtl.ir.Circuit diff --git a/src/test/scala/ConnectSpec.scala b/src/test/scala/ConnectSpec.scala index bcde438..6035e10 100644 --- a/src/test/scala/ConnectSpec.scala +++ b/src/test/scala/ConnectSpec.scala @@ -1,17 +1,10 @@ // SPDX-License-Identifier: Apache-2.0 - -import org.scalatest._ - -import chisel3._ -import chisel3.experimental.{Analog, FixedPoint} +import chisel3.experimental.Analog import chisel3.stage.ChiselStage import chisel3.testers.BasicTester - -abstract class CrossCheck extends Bundle { - val in: Data - val out: Data -} +import chisel3.{fromDoubleToLiteral => _, fromIntToBinaryPoint => _, _} +import fixedpoint._ class CrossConnects(inType: Data, outType: Data) extends Module { val io = IO(new Bundle { @@ -21,17 +14,6 @@ class CrossConnects(inType: Data, outType: Data) extends Module { io.out := io.in } -class PipeInternalWires extends Module { - import chisel3.util.Pipe - val io = IO(new Bundle { - val a = Input(Bool()) - val b = Input(UInt(32.W)) - }) - val pipe = Module(new Pipe(UInt(32.W), 32)) - pipe.io.enq.valid <> io.a - pipe.io.enq.bits <> io.b -} - class CrossConnectTester(inType: Data, outType: Data) extends BasicTester { val dut = Module(new CrossConnects(inType, outType)) dut.io := DontCare @@ -39,16 +21,6 @@ class CrossConnectTester(inType: Data, outType: Data) extends BasicTester { } class ConnectSpec extends ChiselPropSpec with Utils { - property("SInt := SInt should succeed") { - assertTesterPasses { new CrossConnectTester(SInt(16.W), SInt(16.W)) } - } - property("SInt := UInt should fail") { - intercept[ChiselException] { - extractCause[ChiselException] { - ChiselStage.elaborate { new CrossConnectTester(UInt(16.W), SInt(16.W)) } - } - } - } property("SInt := FixedPoint should fail") { intercept[ChiselException] { extractCause[ChiselException] { @@ -56,16 +28,6 @@ class ConnectSpec extends ChiselPropSpec with Utils { } } } - property("UInt := UInt should succeed") { - assertTesterPasses { new CrossConnectTester(UInt(16.W), UInt(16.W)) } - } - property("UInt := SInt should fail") { - intercept[ChiselException] { - extractCause[ChiselException] { - ChiselStage.elaborate { new CrossConnectTester(SInt(16.W), UInt(16.W)) } - } - } - } property("UInt := FixedPoint should fail") { intercept[ChiselException] { extractCause[ChiselException] { @@ -73,18 +35,6 @@ class ConnectSpec extends ChiselPropSpec with Utils { } } } - - property("Clock := Clock should succeed") { - assertTesterPasses { new CrossConnectTester(Clock(), Clock()) } - } - property("Clock := UInt should fail") { - intercept[ChiselException] { - extractCause[ChiselException] { - ChiselStage.elaborate { new CrossConnectTester(Clock(), UInt(16.W)) } - } - } - } - property("FixedPoint := FixedPoint should succeed") { assertTesterPasses { new CrossConnectTester(FixedPoint(16.W, 8.BP), FixedPoint(16.W, 8.BP)) } } @@ -102,14 +52,6 @@ class ConnectSpec extends ChiselPropSpec with Utils { } } } - - property("Analog := Analog should fail") { - intercept[ChiselException] { - extractCause[ChiselException] { - ChiselStage.elaborate { new CrossConnectTester(Analog(16.W), Analog(16.W)) } - } - } - } property("Analog := FixedPoint should fail") { intercept[ChiselException] { extractCause[ChiselException] { @@ -124,72 +66,4 @@ class ConnectSpec extends ChiselPropSpec with Utils { } } } - property("Analog := UInt should fail") { - intercept[ChiselException] { - extractCause[ChiselException] { - ChiselStage.elaborate { new CrossConnectTester(Analog(16.W), UInt(16.W)) } - } - } - } - property("Analog := SInt should fail") { - intercept[ChiselException] { - extractCause[ChiselException] { - ChiselStage.elaborate { new CrossConnectTester(Analog(16.W), SInt(16.W)) } - } - } - } - property("UInt := Analog should fail") { - intercept[ChiselException] { - extractCause[ChiselException] { - ChiselStage.elaborate { new CrossConnectTester(UInt(16.W), Analog(16.W)) } - } - } - } - property("SInt := Analog should fail") { - intercept[ChiselException] { - extractCause[ChiselException] { - ChiselStage.elaborate { new CrossConnectTester(SInt(16.W), Analog(16.W)) } - } - } - } - property("Pipe internal connections should succeed") { - ChiselStage.elaborate(new PipeInternalWires) - } - - property("Connect error messages should have meaningful information") { - class InnerExample extends Module { - val myReg = RegInit(0.U(8.W)) - } - - class OuterAssignExample extends Module { - val inner = Module(new InnerExample()) - inner.myReg := false.B // ERROR - } - - val assignError = the[ChiselException] thrownBy { ChiselStage.elaborate { new OuterAssignExample } } - val expectedAssignError = """.*@: myReg in InnerExample cannot be written from module OuterAssignExample.""" - (assignError.getMessage should fullyMatch).regex(expectedAssignError) - - class OuterReadExample extends Module { - val myReg = RegInit(0.U(8.W)) - val inner = Module(new InnerExample()) - myReg := inner.myReg // ERROR - } - - val readError = the[ChiselException] thrownBy { ChiselStage.elaborate { new OuterReadExample } } - val expectedReadError = """.*@: myReg in InnerExample cannot be read from module OuterReadExample.""" - (readError.getMessage should fullyMatch).regex(expectedReadError) - - val typeMismatchError = the[ChiselException] thrownBy { - ChiselStage.elaborate { - new RawModule { - val myUInt = Wire(UInt(4.W)) - val mySInt = Wire(SInt(4.W)) - myUInt := mySInt - } - } - } - val expectedTypeMismatchError = """.*@: Sink \(UInt<4>\) and Source \(SInt<4>\) have different types.""" - (typeMismatchError.getMessage should fullyMatch).regex(expectedTypeMismatchError) - } } diff --git a/src/test/scala/DataEqualitySpec.scala b/src/test/scala/DataEqualitySpec.scala index db475ce..c9a5946 100644 --- a/src/test/scala/DataEqualitySpec.scala +++ b/src/test/scala/DataEqualitySpec.scala @@ -1,14 +1,9 @@ // SPDX-License-Identifier: Apache-2.0 - -import chisel3._ -import chisel3.experimental.VecLiterals._ +import chisel3.{fromDoubleToLiteral => _, fromIntToBinaryPoint => _, _} import chisel3.experimental.BundleLiterals._ -import chisel3.experimental.{Analog, ChiselRange, Interval} -import chisel3.stage.ChiselStage import chisel3.testers.BasicTester -import chisel3.util.Valid -import fixedpoint.{FixedPoint, fromDoubleToLiteral, fromIntToBinaryPoint} +import fixedpoint._ class EqualityModule(lhsGen: => Data, rhsGen: => Data) extends Module { val out = IO(Output(Bool())) @@ -27,112 +22,28 @@ class EqualityTester(lhsGen: => Data, rhsGen: => Data) extends BasicTester { stop() } -class AnalogBundle extends Bundle { - val analog = Analog(32.W) -} - -class AnalogExceptionModule extends Module { - class AnalogExceptionModuleIO extends Bundle { - val bundle1 = new AnalogBundle - val bundle2 = new AnalogBundle - } - - val io = IO(new AnalogExceptionModuleIO) -} - -class AnalogExceptionTester extends BasicTester { - val module = Module(new AnalogExceptionModule) - - module.io.bundle1 <> DontCare - module.io.bundle2 <> DontCare - - assert(module.io.bundle1 === module.io.bundle2) - - stop() -} - class DataEqualitySpec extends ChiselFlatSpec with Utils { object MyEnum extends ChiselEnum { val sA, sB = Value } - object MyEnumB extends ChiselEnum { - val sA, sB = Value - } + class MyBundle extends Bundle { val a = UInt(8.W) val b = Bool() val c = MyEnum() } + class LongBundle extends Bundle { val a = UInt(48.W) val b = SInt(32.W) val c = FixedPoint(16.W, 4.BP) } + class RuntimeSensitiveBundle(gen: => Bundle) extends Bundle { val a = UInt(8.W) val b: Bundle = gen } - behavior.of("UInt === UInt") - it should "pass with equal values" in { - assertTesterPasses { - new EqualityTester(0.U, 0.U) - } - } - it should "fail with differing values" in { - assertTesterFails { - new EqualityTester(0.U, 1.U) - } - } - - behavior.of("SInt === SInt") - it should "pass with equal values" in { - assertTesterPasses { - new EqualityTester(0.S, 0.S) - } - } - it should "fail with differing values" in { - assertTesterFails { - new EqualityTester(0.S, 1.S) - } - } - - behavior.of("Reset === Reset") - it should "pass with equal values" in { - assertTesterPasses { - new EqualityTester(true.B, true.B) - } - } - it should "fail with differing values" in { - assertTesterFails { - new EqualityTester(true.B, false.B) - } - } - - behavior.of("AsyncReset === AsyncReset") - it should "pass with equal values" in { - assertTesterPasses { - new EqualityTester(true.B.asAsyncReset, true.B.asAsyncReset) - } - } - it should "fail with differing values" in { - assertTesterFails { - new EqualityTester(true.B.asAsyncReset, false.B.asAsyncReset) - } - } - - behavior.of("Interval === Interval") - it should "pass with equal values" in { - assertTesterPasses { - new EqualityTester(2.I, 2.I) - } - } - it should "fail with differing values" in { - assertTesterFails { - new EqualityTester(2.I, 3.I) - } - } - behavior.of("FixedPoint === FixedPoint") it should "pass with equal values" in { assertTesterPasses { @@ -145,63 +56,7 @@ class DataEqualitySpec extends ChiselFlatSpec with Utils { } } - behavior.of("ChiselEnum === ChiselEnum") - it should "pass with equal values" in { - assertTesterPasses { - new EqualityTester(MyEnum.sA, MyEnum.sA) - } - } - it should "fail with differing values" in { - assertTesterFails { - new EqualityTester(MyEnum.sA, MyEnum.sB) - } - } - - behavior.of("Vec === Vec") - it should "pass with equal sizes, equal values" in { - assertTesterPasses { - new EqualityTester( - Vec(3, UInt(8.W)).Lit(0 -> 1.U, 1 -> 2.U, 2 -> 3.U), - Vec(3, UInt(8.W)).Lit(0 -> 1.U, 1 -> 2.U, 2 -> 3.U) - ) - } - } - it should "fail with equal sizes, differing values" in { - assertTesterFails { - new EqualityTester( - Vec(3, UInt(8.W)).Lit(0 -> 1.U, 1 -> 2.U, 2 -> 3.U), - Vec(3, UInt(8.W)).Lit(0 -> 0.U, 1 -> 1.U, 2 -> 2.U) - ) - } - } - it should "throw a ChiselException with differing sizes" in { - (the[ChiselException] thrownBy extractCause[ChiselException] { - assertTesterFails { - new EqualityTester( - Vec(3, UInt(8.W)).Lit(0 -> 1.U, 1 -> 2.U, 2 -> 3.U), - Vec(4, UInt(8.W)).Lit(0 -> 1.U, 1 -> 2.U, 2 -> 3.U, 3 -> 4.U) - ) - } - }).getMessage should include("Vec sizes differ") - } - behavior.of("Bundle === Bundle") - it should "pass with equal type, equal values" in { - assertTesterPasses { - new EqualityTester( - (new MyBundle).Lit(_.a -> 42.U, _.b -> false.B, _.c -> MyEnum.sB), - (new MyBundle).Lit(_.a -> 42.U, _.b -> false.B, _.c -> MyEnum.sB) - ) - } - } - it should "fail with equal type, differing values" in { - assertTesterFails { - new EqualityTester( - (new MyBundle).Lit(_.a -> 42.U, _.b -> false.B, _.c -> MyEnum.sB), - (new MyBundle).Lit(_.a -> 42.U, _.b -> false.B, _.c -> MyEnum.sA) - ) - } - } it should "throw a ChiselException with differing runtime types" in { (the[ChiselException] thrownBy extractCause[ChiselException] { assertTesterFails { @@ -226,34 +81,4 @@ class DataEqualitySpec extends ChiselFlatSpec with Utils { } }).getMessage should include("Runtime types differ") } - - behavior.of("DontCare === DontCare") - it should "pass with two invalids" in { - assertTesterPasses { - new EqualityTester(Valid(UInt(8.W)).Lit(_.bits -> 123.U), Valid(UInt(8.W)).Lit(_.bits -> 123.U)) - } - } - it should "exhibit the same behavior as comparing two invalidated wires" in { - // Also check that two invalidated wires are equal - assertTesterPasses { - new EqualityTester(WireInit(UInt(8.W), DontCare), WireInit(UInt(8.W), DontCare)) - } - - // Compare the verilog generated from both test cases and verify that they both are equal to true - val verilog1 = ChiselStage.emitVerilog( - new EqualityModule(Valid(UInt(8.W)).Lit(_.bits -> 123.U), Valid(UInt(8.W)).Lit(_.bits -> 123.U)) - ) - val verilog2 = - ChiselStage.emitVerilog(new EqualityModule(WireInit(UInt(8.W), DontCare), WireInit(UInt(8.W), DontCare))) - - verilog1 should include("assign out = 1'h1;") - verilog2 should include("assign out = 1'h1;") - } - - behavior.of("Analog === Analog") - it should "throw a ChiselException" in { - (the[ChiselException] thrownBy extractCause[ChiselException] { - assertTesterFails { new AnalogExceptionTester } - }).getMessage should include("Equality isn't defined for Analog values") - } } diff --git a/src/test/scala/DataPrint.scala b/src/test/scala/DataPrint.scala index f798f6f..cc65b2e 100644 --- a/src/test/scala/DataPrint.scala +++ b/src/test/scala/DataPrint.scala @@ -1,24 +1,16 @@ // SPDX-License-Identifier: Apache-2.0 - -import org.scalatest._ - -import chisel3._ import chisel3.experimental.BundleLiterals._ import chisel3.stage.ChiselStage +import chisel3.{fromDoubleToLiteral => _, fromIntToBinaryPoint => _, _} +import fixedpoint._ import org.scalatest.matchers.should.Matchers -import fixedpoint.{FixedPoint, fromIntToBinaryPoint, fromDoubleToLiteral} class DataPrintSpec extends ChiselFlatSpec with Matchers { object EnumTest extends ChiselEnum { val sNone, sOne, sTwo = Value } - class BundleTest extends Bundle { - val a = UInt(8.W) - val b = Bool() - } - class PartialBundleTest extends Bundle { val a = UInt(8.W) val b = Bool() @@ -30,86 +22,19 @@ class DataPrintSpec extends ChiselFlatSpec with Matchers { "Data types" should "have a meaningful string representation" in { ChiselStage.elaborate { new RawModule { - UInt().toString should be("UInt") - UInt(8.W).toString should be("UInt<8>") - SInt(15.W).toString should be("SInt<15>") - Bool().toString should be("Bool") - Clock().toString should be("Clock") FixedPoint(5.W, 3.BP).toString should be("FixedPoint<5><<3>>") - Vec(3, UInt(2.W)).toString should be("UInt<2>[3]") - EnumTest.Type().toString should be("EnumTest") - (new BundleTest).toString should be("BundleTest") - new Bundle { val a = UInt(8.W) }.toString should be("AnonymousBundle") - new Bundle { val a = UInt(8.W) }.a.toString should be("UInt<8>") } } } - class BoundDataModule extends Module { // not in the test to avoid anon naming suffixes - Wire(UInt()).toString should be("BoundDataModule.?: Wire[UInt]") - Reg(SInt()).toString should be("BoundDataModule.?: Reg[SInt]") - val io = IO(Output(Bool())) // needs a name so elaboration doesn't fail - io.toString should be("BoundDataModule.io: IO[Bool]") - val m = Mem(4, UInt(2.W)) - m(2).toString should be("BoundDataModule.?: MemPort[UInt<2>]") - (2.U + 2.U).toString should be("BoundDataModule.?: OpResult[UInt<2>]") - Wire(Vec(3, UInt(2.W))).toString should be("BoundDataModule.?: Wire[UInt<2>[3]]") - - class InnerModule extends Module { - val io = IO(Output(new Bundle { - val a = UInt(4.W) - })) - } - val inner = Module(new InnerModule) - inner.clock.toString should be("InnerModule.clock: IO[Clock]") - inner.io.a.toString should be("InnerModule.io.a: IO[UInt<4>]") - - class FooTypeTest extends Bundle { - val foo = Vec(2, UInt(8.W)) - val fizz = UInt(8.W) - } - val tpe = new FooTypeTest - val fooio: FooTypeTest = IO(Input(tpe)) - fooio.foo(0).toString should be("BoundDataModule.fooio.foo[0]: IO[UInt<8>]") - - class NestedBundle extends Bundle { - val nestedFoo = UInt(8.W) - val nestedFooVec = Vec(2, UInt(8.W)) - } - class NestedType extends Bundle { - val foo = new NestedBundle - } - - val nestedTpe = new NestedType - val nestedio = IO(Input(nestedTpe)) - (nestedio.foo.nestedFoo.toString should be("BoundDataModule.nestedio.foo.nestedFoo: IO[UInt<8>]")) - (nestedio.foo.nestedFooVec(0).toString should be("BoundDataModule.nestedio.foo.nestedFooVec[0]: IO[UInt<8>]")) - } - - "Bound data types" should "have a meaningful string representation" in { - ChiselStage.elaborate { new BoundDataModule } - } - "Literals" should "have a meaningful string representation" in { ChiselStage.elaborate { new RawModule { - 3.U.toString should be("UInt<2>(3)") - 3.U(5.W).toString should be("UInt<5>(3)") - (-1.S).toString should be("SInt<1>(-1)") - false.B.toString should be("Bool(false)") - true.B.toString should be("Bool(true)") 2.25.F(6.W, 2.BP).toString should be("FixedPoint<6><<2>>(2.25)") (-2.25).F(6.W, 2.BP).toString should be("FixedPoint<6><<2>>(-2.25)") - Vec(3, UInt(4.W)).toString should be("UInt<4>[3]") - EnumTest.sNone.toString should be("EnumTest(0=sNone)") - EnumTest.sTwo.toString should be("EnumTest(2=sTwo)") - EnumTest(1.U).toString should be("EnumTest(1=sOne)") - (new BundleTest).Lit(_.a -> 2.U, _.b -> false.B).toString should be("BundleTest(a=UInt<8>(2), b=Bool(false))") - println((new PartialBundleTest).Lit().toString) (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/FixedPointSpec.scala b/src/test/scala/FixedPointSpec.scala index 8b183cf..09e8e55 100644 --- a/src/test/scala/FixedPointSpec.scala +++ b/src/test/scala/FixedPointSpec.scala @@ -1,13 +1,12 @@ // SPDX-License-Identifier: Apache-2.0 - -import chisel3.{Mux => _, _} +import chisel3.{fromBigDecimalToLiteral => _, fromDoubleToLiteral => _, fromIntToBinaryPoint => _, Mux => _, _} import chisel3.internal.firrtl.Width import chisel3.stage.ChiselStage import chisel3.testers.BasicTester import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers -import fixedpoint.{BinaryPoint, FixedPoint, fromBigDecimalToLiteral, fromDoubleToLiteral, fromIntToBinaryPoint} +import fixedpoint._ import fixedpoint.shadow.Mux class FixedPointLiteralSpec extends AnyFlatSpec with Matchers { @@ -134,6 +133,11 @@ class SBPTester extends BasicTester { stop() } +class NegativeShift(t: => Bits) extends Module { + val io = IO(new Bundle {}) + Reg(t) >> -1 +} + class FixedPointLitExtractTester extends BasicTester { assert(-4.75.F(2.BP)(1) === false.B) assert(-4.75.F(2.BP)(2) === true.B) diff --git a/src/test/scala/LiteralExtractorSpec.scala b/src/test/scala/LiteralExtractorSpec.scala index ed501ff..93ab407 100644 --- a/src/test/scala/LiteralExtractorSpec.scala +++ b/src/test/scala/LiteralExtractorSpec.scala @@ -1,28 +1,13 @@ // SPDX-License-Identifier: Apache-2.0 - -import chisel3._ -import chisel3.experimental.{FixedPoint=>_, _} import chisel3.experimental.BundleLiterals._ -import chisel3.stage.ChiselStage +import chisel3.experimental.{FixedPoint => _, _} import chisel3.testers.BasicTester -import scala.collection.immutable.ListMap -import fixedpoint.{FixedPoint, fromIntToBinaryPoint, fromDoubleToLiteral, fromBigDecimalToLiteral, NumBP} +import chisel3.{fromDoubleToLiteral => _, fromIntToBinaryPoint => _, _} +import fixedpoint._ class LiteralExtractorSpec extends ChiselFlatSpec { "litValue" should "return the literal value" in { - assert(0.U.litValue === BigInt(0)) - assert(1.U.litValue === BigInt(1)) - assert(42.U.litValue === BigInt(42)) - assert(42.U.litValue === 42.U.litValue) - - assert(0.S.litValue === BigInt(0)) - assert(-1.S.litValue === BigInt(-1)) - assert(-42.S.litValue === BigInt(-42)) - - assert(true.B.litValue === BigInt(1)) - assert(false.B.litValue === BigInt(0)) - assert(1.25.F(2.BP).litValue === BigInt("101", 2)) assert(2.25.F(2.BP).litValue === BigInt("1001", 2)) @@ -30,14 +15,6 @@ class LiteralExtractorSpec extends ChiselFlatSpec { assert(-2.25.F(2.BP).litValue === BigInt("-1001", 2)) } - "litToBoolean" should "return the literal value" in { - assert(true.B.litToBoolean === true) - assert(false.B.litToBoolean === false) - - assert(1.B.litToBoolean === true) - assert(0.B.litToBoolean === false) - } - "litToDouble" should "return the literal value" in { assert(1.25.F(2.BP).litToDouble == 1.25) assert(2.25.F(2.BP).litToDouble == 2.25) @@ -50,15 +27,6 @@ class LiteralExtractorSpec extends ChiselFlatSpec { assert(1.25.F(1.BP).litToDouble == 1.5) } - "litOption" should "return None for non-literal hardware" in { - ChiselStage.elaborate { - new RawModule { - val a = Wire(UInt()) - assert(a.litOption == None) - } - } - } - "doubles and big decimals" should "round trip properly" in { intercept[ChiselException] { NumBP.toBigDecimal(BigInt("1" * 109, 2), 0.BP) // this only works if number takes less than 109 bits @@ -84,31 +52,13 @@ class LiteralExtractorSpec extends ChiselFlatSpec { bigIntFromDouble should be(bigInt53) } - "encoding and decoding of Intervals" should "round trip" in { - val rangeMin = BigDecimal(-31.5) - val rangeMax = BigDecimal(32.5) - val range = range"($rangeMin, $rangeMax).2" - for (value <- (rangeMin - 4) to (rangeMax + 4) by 2.25) { - if (value < rangeMin || value > rangeMax) { - intercept[ChiselException] { - val literal = value.I(range) - } - } else { - val literal = value.I(range) - literal.isLit() should be(true) - literal.litValue().toDouble / 4.0 should be(value) - } - } - } - "literals declared outside a builder context" should "compare with those inside builder context" in { class InsideBundle extends Bundle { - val x = SInt(8.W) - val y = FixedPoint(8.W, 4.BP) + val x = FixedPoint(8.W, 4.BP) } class LitInsideOutsideTester(outsideLiteral: InsideBundle) extends BasicTester { - val insideLiteral = (new InsideBundle).Lit(_.x -> 7.S, _.y -> 6.125.F(8.W, 4.BP)) + val insideLiteral = (new InsideBundle).Lit(_.x -> 6.125.F(8.W, 4.BP)) // the following errors with "assertion failed" @@ -119,40 +69,13 @@ class LiteralExtractorSpec extends ChiselFlatSpec { // with "chisel3.internal.BundleLitBinding cannot be cast to chisel3.internal.ElementLitBinding" chisel3.assert(outsideLiteral.x === insideLiteral.x) - chisel3.assert(outsideLiteral.y === insideLiteral.y) - chisel3.assert(outsideLiteral.x === 7.S) - chisel3.assert(outsideLiteral.y === 6.125.F(4.BP)) + chisel3.assert(outsideLiteral.x === 6.125.F(4.BP)) stop() } - val outsideLiteral = (new InsideBundle).Lit(_.x -> 7.S, _.y -> 6.125.F(8.W, 4.BP)) + val outsideLiteral = (new InsideBundle).Lit(_.x -> 6.125.F(8.W, 4.BP)) assertTesterPasses { new LitInsideOutsideTester(outsideLiteral) } } - - "bundle literals" should "do the right thing" in { - class MyBundle extends Bundle { - val a = UInt(8.W) - val b = Bool() - } - val myBundleLiteral = (new MyBundle).Lit(_.a -> 42.U, _.b -> true.B) - assert(myBundleLiteral.a.litValue == 42) - assert(myBundleLiteral.b.litValue == 1) - assert(myBundleLiteral.b.litToBoolean == true) - } - - "record literals" should "do the right thing" in { - class MyRecord extends Record { - override val elements = ListMap( - "a" -> UInt(8.W), - "b" -> Bool() - ) - override def cloneType = (new MyRecord).asInstanceOf[this.type] - } - - val myRecordLiteral = new (MyRecord).Lit(_.elements("a") -> 42.U, _.elements("b") -> true.B) - assert(myRecordLiteral.elements("a").litValue == 42) - assert(myRecordLiteral.elements("b").litValue == 1) - } } diff --git a/src/test/scala/OneHotMuxSpec.scala b/src/test/scala/OneHotMuxSpec.scala index ae0fb76..8c214fa 100644 --- a/src/test/scala/OneHotMuxSpec.scala +++ b/src/test/scala/OneHotMuxSpec.scala @@ -1,31 +1,20 @@ // SPDX-License-Identifier: Apache-2.0 - -import chisel3._ import chisel3.internal.ChiselException import chisel3.testers.BasicTester -import chisel3.util.UIntToOH +import chisel3.{fromDoubleToLiteral => _, fromIntToBinaryPoint => _, _} +import fixedpoint._ +import fixedpoint.shadow.Mux1H import org.scalatest.freespec.AnyFreeSpec import org.scalatest.matchers.should.Matchers -import fixedpoint.{FixedPoint, fromIntToBinaryPoint, fromDoubleToLiteral} -import fixedpoint.shadow.Mux1H class OneHotMuxSpec extends AnyFreeSpec with Matchers with ChiselRunners { - "simple one hot mux with uint should work" in { - assertTesterPasses(new SimpleOneHotTester) - } - "simple one hot mux with sint should work" in { - assertTesterPasses(new SIntOneHotTester) - } "simple one hot mux with fixed point should work" in { assertTesterPasses(new FixedPointOneHotTester) } "simple one hot mux with all same fixed point should work" in { assertTesterPasses(new AllSameFixedPointOneHotTester) } - "simple one hot mux with all same parameterized sint values should work" in { - assertTesterPasses(new ParameterizedOneHotTester) - } "simple one hot mux with all same parameterized aggregates containing fixed values should work" in { assertTesterPasses(new ParameterizedAggregateOneHotTester) } @@ -39,49 +28,6 @@ class OneHotMuxSpec extends AnyFreeSpec with Matchers with ChiselRunners { assertTesterPasses(new DifferentBundleOneHotTester) } } - "UIntToOH with output width greater than 2^(input width)" in { - assertTesterPasses(new UIntToOHTester) - } - "UIntToOH should not accept width of zero (until zero-width wires are fixed" in { - intercept[IllegalArgumentException] { - assertTesterPasses(new BasicTester { - val out = UIntToOH(0.U, 0) - }) - } - } - -} - -class SimpleOneHotTester extends BasicTester { - val out = Wire(UInt()) - out := Mux1H( - Seq( - false.B -> 2.U, - false.B -> 4.U, - true.B -> 8.U, - false.B -> 11.U - ) - ) - - assert(out === 8.U) - - stop() -} - -class SIntOneHotTester extends BasicTester { - val out = Wire(SInt()) - out := Mux1H( - Seq( - false.B -> (-3).S, - true.B -> (-5).S, - false.B -> (-7).S, - false.B -> (-11).S - ) - ) - - assert(out === (-5).S) - - stop() } class FixedPointOneHotTester extends BasicTester { @@ -118,18 +64,6 @@ class AllSameFixedPointOneHotTester extends BasicTester { stop() } -class ParameterizedOneHotTester extends BasicTester { - val values: Seq[Int] = Seq(-3, -5, -7, -11) - for ((v, i) <- values.zipWithIndex) { - val dut = Module(new ParameterizedOneHot(values.map(_.S), SInt(8.W))) - dut.io.selectors := (1 << i).U(4.W).asBools - - assert(dut.io.out.asUInt() === v.S(8.W).asUInt()) - } - - stop() -} - class Agg1 extends Bundle { val v = Vec(2, FixedPoint(8.W, 4.BP)) val a = new Bundle { @@ -189,16 +123,6 @@ trait HasMakeLit[T] { def makeLit(n: Int): T } -class ParameterizedOneHot[T <: Data](values: Seq[T], outGen: T) extends Module { - val io = IO(new Bundle { - val selectors = Input(Vec(4, Bool())) - val out = Output(outGen) - }) - - val terms = io.selectors.zip(values) - io.out := Mux1H(terms) -} - class ParameterizedAggregateOneHot[T <: Data](valGen: HasMakeLit[T], outGen: T) extends Module { val io = IO(new Bundle { val selectors = Input(Vec(4, Bool())) @@ -303,15 +227,3 @@ class DifferentBundleOneHotTester extends BasicTester { stop() } - -class UIntToOHTester extends BasicTester { - val out = UIntToOH(1.U, 3) - require(out.getWidth == 3) - assert(out === 2.U) - - val out2 = UIntToOH(0.U, 1) - require(out2.getWidth == 1) - assert(out2 === 1.U) - - stop() -} diff --git a/src/test/scala/UIntOps.scala b/src/test/scala/UIntOps.scala deleted file mode 100644 index 86b1b7c..0000000 --- a/src/test/scala/UIntOps.scala +++ /dev/null @@ -1,288 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - - -import chisel3._ -import chisel3.stage.ChiselStage -import chisel3.testers.BasicTester -import chisel3.util._ -import org.scalacheck.Shrink -import org.scalatest.matchers.should.Matchers - -class UIntOps extends Module { - val io = IO(new Bundle { - val a = Input(UInt(32.W)) - val b = Input(UInt(32.W)) - val addout = Output(UInt(32.W)) - val subout = Output(UInt(32.W)) - val addampout = Output(UInt(33.W)) - val subampout = Output(UInt(33.W)) - val timesout = Output(UInt(32.W)) - val divout = Output(UInt(32.W)) - val modout = Output(UInt(32.W)) - val lshiftout = Output(UInt(32.W)) - val rshiftout = Output(UInt(32.W)) - val lrotateout = Output(UInt(32.W)) - val rrotateout = Output(UInt(32.W)) - val lessout = Output(Bool()) - val greatout = Output(Bool()) - val eqout = Output(Bool()) - val noteqout = Output(Bool()) - val lesseqout = Output(Bool()) - val greateqout = Output(Bool()) - }) - - dontTouch(io) - - val a = io.a - val b = io.b - - io.addout := a +% b - io.subout := a -% b - io.addampout := a +& b - io.subampout := a -& b - io.timesout := (a * b)(31, 0) - io.divout := a / Mux(b === 0.U, 1.U, b) - io.modout := a % b - io.lshiftout := (a << b(3, 0))(31, 0) - io.rshiftout := a >> b - io.lrotateout := a.rotateLeft(5) - io.rrotateout := a.rotateRight(5) - io.lessout := a < b - io.greatout := a > b - io.eqout := a === b - io.noteqout := (a =/= b) - io.lesseqout := a <= b - io.greateqout := a >= b -} - -// Note a and b need to be "safe" -class UIntOpsTester(a: Long, b: Long) extends BasicTester { - require(a >= 0 && b >= 0) - - val dut = Module(new UIntOps) - dut.io.a := a.asUInt(32.W) - dut.io.b := b.asUInt(32.W) - - assert(dut.io.addout === (a + b).U(32.W)) - assert(dut.io.subout === (a - b).S(32.W).asUInt) - assert(dut.io.addampout === (a + b).U(33.W)) - assert(dut.io.subampout === (a - b).S(33.W).asUInt) - assert(dut.io.timesout === (a * b).U(32.W)) - assert(dut.io.divout === (a / (b.max(1))).U(32.W)) - assert(dut.io.modout === (a % (b.max(1))).U(32.W)) - assert(dut.io.lshiftout === (a << (b % 16)).U(32.W)) - assert(dut.io.rshiftout === (a >> b).U(32.W)) - assert( - dut.io.lrotateout === s"h${Integer.rotateLeft(a.toInt, 5).toHexString}" - .U(32.W) - ) - assert( - dut.io.rrotateout === s"h${Integer.rotateRight(a.toInt, 5).toHexString}" - .U(32.W) - ) - assert(dut.io.lessout === (a < b).B) - assert(dut.io.greatout === (a > b).B) - assert(dut.io.eqout === (a == b).B) - assert(dut.io.noteqout === (a != b).B) - assert(dut.io.lesseqout === (a <= b).B) - assert(dut.io.greateqout === (a >= b).B) - - stop() -} - -class GoodBoolConversion extends Module { - val io = IO(new Bundle { - val u = Input(UInt(1.W)) - val b = Output(Bool()) - }) - io.b := io.u.asBool -} - -class BadBoolConversion extends Module { - val io = IO(new Bundle { - val u = Input(UInt(5.W)) - val b = Output(Bool()) - }) - io.b := io.u.asBool -} - -class NegativeShift(t: => Bits) extends Module { - val io = IO(new Bundle {}) - Reg(t) >> -1 -} - -class BasicRotate extends BasicTester { - val shiftAmount = random.LFSR(4) - val ctr = RegInit(0.U(4.W)) - - val rotL = 1.U(3.W).rotateLeft(shiftAmount) - val rotR = 1.U(3.W).rotateRight(shiftAmount) - - printf("Shift amount: %d rotateLeft:%b rotateRight:%b\n", shiftAmount, rotL, rotR) - - switch(shiftAmount % 3.U) { - is(0.U, 3.U) { - assert(rotL === "b001".U) - assert(rotR === "b001".U) - } - is(1.U) { - assert(rotL === "b010".U) - assert(rotR === "b100".U) - } - is(2.U) { - assert(rotL === "b100".U) - assert(rotR === "b010".U) - } - } - - ctr := ctr + 1.U - - when(ctr === 15.U) { - stop() - } -} - -/** rotating a w-bit word left by n should be equivalent to rotating it by w - n - * to the left - */ -class MatchedRotateLeftAndRight(w: Int = 13) extends BasicTester { - val initValue = BigInt(w, scala.util.Random) - println(s"Initial value: ${initValue.toString(2)}") - - val maxWidthBits = log2Ceil(w + 1) - val shiftAmount1 = RegInit(0.U(w.W)) - val shiftAmount2 = RegInit(w.U(w.W)) - shiftAmount1 := shiftAmount1 + 1.U - shiftAmount2 := shiftAmount2 - 1.U - - val value = RegInit(initValue.U(w.W)) - - val out1 = value.rotateLeft(shiftAmount1) - val out2 = value.rotateRight(shiftAmount2) - - printf("rotateLeft by %d: %b\n", shiftAmount1, out1) - - assert(out1 === out2) - when(shiftAmount1 === w.U) { - assert(out1 === initValue.U) - stop() - } -} - -class UIntLitExtractTester extends BasicTester { - assert("b101010".U.extract(2) === false.B) - assert("b101010".U.extract(3) === true.B) - assert("b101010".U.extract(100) === false.B) - assert("b101010".U(3, 0) === "b1010".U) - assert("b101010".U(9, 0) === "b0000101010".U) - - assert("b101010".U(6.W)(2) === false.B) - assert("b101010".U(6.W)(3) === true.B) - assert("b101010".U(6.W)(100) === false.B) - assert("b101010".U(6.W)(3, 0) === "b1010".U) - assert("b101010".U(6.W)(9, 0) === "b0000101010".U) - stop() -} - -class UIntOpsSpec extends ChiselPropSpec with Matchers with Utils { - // Disable shrinking on error. - implicit val noShrinkListVal = Shrink[List[Int]](_ => Stream.empty) - implicit val noShrinkInt = Shrink[Int](_ => Stream.empty) - - property("Bools can be created from 1 bit UInts") { - ChiselStage.elaborate(new GoodBoolConversion) - } - - property("Bools cannot be created from >1 bit UInts") { - a[Exception] should be thrownBy extractCause[Exception] { ChiselStage.elaborate(new BadBoolConversion) } - } - - property("Out-of-bounds extraction from known-width UInts") { - a[ChiselException] should be thrownBy extractCause[ChiselException] { - ChiselStage.elaborate(new RawModule { - val u = IO(Input(UInt(2.W))) - u(2, 1) - }) - } - } - - property("Out-of-bounds single-bit extraction from known-width UInts") { - a[ChiselException] should be thrownBy extractCause[ChiselException] { - ChiselStage.elaborate(new RawModule { - val u = IO(Input(UInt(2.W))) - u(2) - }) - } - } - - property("UIntOps should elaborate") { - ChiselStage.elaborate { new UIntOps } - } - - property("UIntOpsTester should return the correct result") { - assertTesterPasses { new UIntOpsTester(123, 7) } - } - - property("Negative shift amounts are invalid") { - a[ChiselException] should be thrownBy extractCause[ChiselException] { - ChiselStage.elaborate(new NegativeShift(UInt())) - } - } - - property("rotateLeft and rotateRight should work for dynamic shift values") { - assertTesterPasses(new BasicRotate) - } - - property( - "rotateLeft and rotateRight should be consistent for dynamic shift values" - ) { - assertTesterPasses(new MatchedRotateLeftAndRight) - } - - property("Bit extraction on literals should work for all non-negative indices") { - assertTesterPasses(new UIntLitExtractTester) - } - - property("asBools should support chained apply") { - ChiselStage.elaborate(new Module { - val io = IO(new Bundle { - val in = Input(UInt(8.W)) - val out = Output(Bool()) - }) - io.out := io.in.asBools()(2) - }) - } - - // We use WireDefault with 2 arguments because of - // https://www.chisel-lang.org/api/3.4.1/chisel3/WireDefault$.html - // Single Argument case 2 - property("modulo divide should give min width of arguments") { - assertKnownWidth(4) { - val x = WireDefault(UInt(8.W), DontCare) - val y = WireDefault(UInt(4.W), DontCare) - val op = x % y - WireDefault(chiselTypeOf(op), op) - } - assertKnownWidth(4) { - val x = WireDefault(UInt(4.W), DontCare) - val y = WireDefault(UInt(8.W), DontCare) - val op = x % y - WireDefault(chiselTypeOf(op), op) - } - } - - property("division should give the width of the numerator") { - assertKnownWidth(8) { - val x = WireDefault(UInt(8.W), DontCare) - val y = WireDefault(UInt(4.W), DontCare) - val op = x / y - WireDefault(chiselTypeOf(op), op) - } - assertKnownWidth(4) { - val x = WireDefault(UInt(4.W), DontCare) - val y = WireDefault(UInt(8.W), DontCare) - val op = x / y - WireDefault(chiselTypeOf(op), op) - } - } -} diff --git a/src/test/scala/VecLiteralSpec.scala b/src/test/scala/VecLiteralSpec.scala index becc923..73a69da 100644 --- a/src/test/scala/VecLiteralSpec.scala +++ b/src/test/scala/VecLiteralSpec.scala @@ -1,324 +1,13 @@ // SPDX-License-Identifier: Apache-2.0 - -import chisel3._ -import chisel3.experimental.BundleLiterals.AddBundleLiteralConstructor import chisel3.experimental.VecLiterals._ -import chisel3.experimental.VecLiteralException -import chisel3.stage.ChiselStage import chisel3.testers.BasicTester -import chisel3.util.Counter +import chisel3.{fromDoubleToLiteral => _, fromIntToBinaryPoint => _, _} +import fixedpoint._ + import scala.language.reflectiveCalls -import fixedpoint.{FixedPoint, fromIntToBinaryPoint, fromDoubleToLiteral} class VecLiteralSpec extends ChiselFreeSpec with Utils { - object MyEnum extends ChiselEnum { - val sA, sB, sC = Value - } - object MyEnumB extends ChiselEnum { - val sA, sB = Value - } - - "Vec literals should work with chisel Enums" in { - val enumVec = Vec(3, MyEnum()).Lit(0 -> MyEnum.sA, 1 -> MyEnum.sB, 2 -> MyEnum.sC) - enumVec(0).toString should include(MyEnum.sA.toString) - enumVec(1).toString should include(MyEnum.sB.toString) - enumVec(2).toString should include(MyEnum.sC.toString) - } - - "improperly constructed vec literals should be detected" - { - "indices in vec literal muse be greater than zero and less than length" in { - val e = intercept[VecLiteralException] { - Vec(2, UInt(4.W)).Lit(0 -> 1.U, 1 -> 2.U, 2 -> 3.U, 3 -> 4.U, -2 -> 7.U) - } - e.getMessage should include( - "VecLiteral: The following indices (2,3,-2) are less than zero or greater or equal to than Vec length" - ) - } - - "indices in vec literals must not be repeated" in { - val e = intercept[VecLiteralException] { - Vec(2, UInt(4.W)).Lit(0 -> 1.U, 1 -> 2.U, 2 -> 3.U, 2 -> 3.U, 2 -> 3.U, 3 -> 4.U) - } - e.getMessage should include("VecLiteral: has duplicated indices 2(3 times)") - } - "lits must fit in vec element width" in { - val e = intercept[VecLiteralException] { - Vec(2, SInt(4.W)).Lit(0 -> 0xab.S, 1 -> 0xbc.S) - } - e.getMessage should include( - "VecLiteral: Vec[SInt<4>] has the following incorrectly typed or sized initializers: " + - "0 -> SInt<9>(171),1 -> SInt<9>(188)" - ) - } - - "all lits must be the same type but width can be equal or smaller than the Vec's element width" in { - val v = Vec(2, SInt(4.W)).Lit(0 -> 1.S, 1 -> -2.S) - v(0).toString should include(1.S(4.W).toString) - v(1).toString should include((-2).S(4.W).toString) - v.toString should include("SInt<4>[2](0=SLit(1,<4>), 1=SLit(-2,<4>)") - } - - "all lits must be the same type but width cannot be greater than Vec's element width" in { - val e = intercept[VecLiteralException] { - val v = Vec(2, SInt(4.W)).Lit(0 -> 11.S, 1 -> -0xffff.S) - } - e.getMessage should include( - "VecLiteral: Vec[SInt<4>] has the following incorrectly typed or sized initializers: 0 -> SInt<5>(11),1 -> SInt<17>(-65535)" - ) - } - } - - //NOTE: I had problems where this would not work if this class declaration was inside test scope - class HasVecInit extends Module { - val initValue = Vec(4, UInt(8.W)).Lit(0 -> 0xab.U(8.W), 1 -> 0xcd.U(8.W), 2 -> 0xef.U(8.W), 3 -> 0xff.U(8.W)) - val y = RegInit(initValue) - } - - "Vec literals should work when used to initialize a reg of vec" in { - val firrtl = (new ChiselStage).emitFirrtl(new HasVecInit, args = Array("--full-stacktrace")) - firrtl should include("""_y_WIRE[0] <= UInt<8>("hab")""") - firrtl should include("""_y_WIRE[1] <= UInt<8>("hcd")""") - firrtl should include("""_y_WIRE[2] <= UInt<8>("hef")""") - firrtl should include("""_y_WIRE[3] <= UInt<8>("hff")""") - firrtl should include(""" reset => (reset, _y_WIRE)""".stripMargin) - } - - //NOTE: I had problems where this would not work if this class declaration was inside test scope - class HasPartialVecInit extends Module { - val initValue = Vec(4, UInt(8.W)).Lit(0 -> 0xab.U(8.W), 2 -> 0xef.U(8.W), 3 -> 0xff.U(8.W)) - val y = RegInit(initValue) - } - - "Vec literals should work when used to partially initialize a reg of vec" in { - val firrtl = (new ChiselStage).emitFirrtl(new HasPartialVecInit, args = Array("--full-stacktrace")) - firrtl should include("""_y_WIRE[0] <= UInt<8>("hab")""") - firrtl should include("""_y_WIRE[1] is invalid""") - firrtl should include("""_y_WIRE[2] <= UInt<8>("hef")""") - firrtl should include("""_y_WIRE[3] <= UInt<8>("hff")""") - firrtl should include(""" reset => (reset, _y_WIRE)""".stripMargin) - } - - class ResetRegWithPartialVecLiteral extends Module { - val in = IO(Input(Vec(4, UInt(8.W)))) - val out = IO(Output(Vec(4, UInt(8.W)))) - val initValue = Vec(4, UInt(8.W)).Lit(0 -> 0xab.U(8.W), 2 -> 0xef.U(8.W), 3 -> 0xff.U(8.W)) - val y = RegInit(initValue) - when(in(1) > 0.U) { - y(1) := in(1) - } - when(in(2) > 0.U) { - y(2) := in(2) - } - out := y - } - - "Vec literals should only init specified fields when used to partially initialize a reg of vec" in { - println(ChiselStage.emitFirrtl(new ResetRegWithPartialVecLiteral)) - assertTesterPasses(new BasicTester { - val m = Module(new ResetRegWithPartialVecLiteral) - val (counter, wrapped) = Counter(true.B, 8) - m.in := DontCare - when(counter < 2.U) { - m.in(1) := 0xff.U - m.in(2) := 0xff.U - }.elsewhen(counter === 2.U) { - chisel3.assert(m.out(1) === 0xff.U) - chisel3.assert(m.out(2) === 0xff.U) - }.elsewhen(counter === 3.U) { - m.in(1) := 0.U - m.in(2) := 0.U - m.reset := true.B - }.elsewhen(counter > 2.U) { - // m.out(1) should not be reset, m.out(2) should be reset - chisel3.assert(m.out(1) === 0xff.U) - chisel3.assert(m.out(2) === 0xef.U) - } - when(wrapped) { - stop() - } - }) - } - - "lowest of vec literal contains least significant bits and " in { - val y = Vec(4, UInt(8.W)).Lit(0 -> 0xab.U(8.W), 1 -> 0xcd.U(8.W), 2 -> 0xef.U(8.W), 3 -> 0xff.U(8.W)) - y.litValue should be(BigInt("FFEFCDAB", 16)) - } - - "the order lits are specified does not matter" in { - val y = Vec(4, UInt(8.W)).Lit(3 -> 0xff.U(8.W), 2 -> 0xef.U(8.W), 1 -> 0xcd.U(8.W), 0 -> 0xab.U(8.W)) - y.litValue should be(BigInt("FFEFCDAB", 16)) - } - - "regardless of the literals widths, packing should be done based on the width of the Vec's gen" in { - val z = Vec(4, UInt(8.W)).Lit(0 -> 0x2.U, 1 -> 0x2.U, 2 -> 0x2.U, 3 -> 0x3.U) - z.litValue should be(BigInt("03020202", 16)) - } - - "packing sparse vec lits should not pack, litOption returns None" in { - // missing sub-listeral for index 2 - val z = Vec(4, UInt(8.W)).Lit(0 -> 0x2.U, 1 -> 0x2.U, 3 -> 0x3.U) - - z.litOption should be(None) - } - - "registers can be initialized with a Vec literal" in { - assertTesterPasses(new BasicTester { - val y = RegInit(Vec(4, UInt(8.W)).Lit(0 -> 0xab.U(8.W), 1 -> 0xcd.U(8.W), 2 -> 0xef.U(8.W), 3 -> 0xff.U(8.W))) - chisel3.assert(y.asUInt === BigInt("FFEFCDAB", 16).U) - stop() - }) - } - - "how does asUInt work" in { - assertTesterPasses(new BasicTester { - val vec1 = Vec(4, UInt(16.W)).Lit(0 -> 0xdd.U, 1 -> 0xcc.U, 2 -> 0xbb.U, 3 -> 0xaa.U) - - val vec2 = VecInit(Seq(0xdd.U, 0xcc.U, 0xbb.U, 0xaa.U)) - printf("vec1 %x\n", vec1.asUInt()) - printf("vec2 %x\n", vec2.asUInt()) - stop() - }) - } - - "Vec literals uint conversion" in { - class M1 extends Module { - val out1 = IO(Output(UInt(64.W))) - val out2 = IO(Output(UInt(64.W))) - - val v1 = Vec(4, UInt(16.W)).Lit(0 -> 0xdd.U, 1 -> 0xcc.U, 2 -> 0xbb.U, 3 -> 0xaa.U) - out1 := v1.asUInt - - val v2 = VecInit(0xdd.U(16.W), 0xcc.U, 0xbb.U, 0xaa.U) - out2 := v2.asUInt - } - - assertTesterPasses(new BasicTester { - val m = Module(new M1) - chisel3.assert(m.out1 === m.out2) - stop() - }) - } - - "VecLits should work properly with .asUInt" in { - val outsideVecLit = Vec(4, UInt(16.W)).Lit(0 -> 0xdd.U, 1 -> 0xcc.U, 2 -> 0xbb.U, 3 -> 0xaa.U) - - assertTesterPasses { - new BasicTester { - chisel3.assert(outsideVecLit(0) === 0xdd.U, "v(0)") - stop() - } - } - } - - "bundle literals should work in RTL" in { - val outsideVecLit = Vec(4, UInt(16.W)).Lit(0 -> 0xdd.U, 1 -> 0xcc.U, 2 -> 0xbb.U, 3 -> 0xaa.U) - - assertTesterPasses { - new BasicTester { - chisel3.assert(outsideVecLit(0) === 0xdd.U, "v(0)") - chisel3.assert(outsideVecLit(1) === 0xcc.U) - chisel3.assert(outsideVecLit(2) === 0xbb.U) - chisel3.assert(outsideVecLit(3) === 0xaa.U) - - chisel3.assert(outsideVecLit.litValue.U === outsideVecLit.asUInt()) - - val insideVecLit = Vec(4, UInt(16.W)).Lit(0 -> 0xdd.U, 1 -> 0xcc.U, 2 -> 0xbb.U, 3 -> 0xaa.U) - chisel3.assert(insideVecLit(0) === 0xdd.U) - chisel3.assert(insideVecLit(1) === 0xcc.U) - chisel3.assert(insideVecLit(2) === 0xbb.U) - chisel3.assert(insideVecLit(3) === 0xaa.U) - - chisel3.assert(insideVecLit(0) === outsideVecLit(0)) - chisel3.assert(insideVecLit(1) === outsideVecLit(1)) - chisel3.assert(insideVecLit(2) === outsideVecLit(2)) - chisel3.assert(insideVecLit(3) === outsideVecLit(3)) - - val vecWire1 = Wire(Vec(4, UInt(16.W))) - vecWire1 := outsideVecLit - - chisel3.assert(vecWire1(0) === 0xdd.U) - chisel3.assert(vecWire1(1) === 0xcc.U) - chisel3.assert(vecWire1(2) === 0xbb.U) - chisel3.assert(vecWire1(3) === 0xaa.U) - - val vecWire2 = Wire(Vec(4, UInt(16.W))) - vecWire2 := insideVecLit - - chisel3.assert(vecWire2(0) === 0xdd.U) - chisel3.assert(vecWire2(1) === 0xcc.U) - chisel3.assert(vecWire2(2) === 0xbb.U) - chisel3.assert(vecWire2(3) === 0xaa.U) - - stop() - } - } - } - - "partial vec literals should work in RTL" in { - assertTesterPasses { - new BasicTester { - val vecLit = Vec(4, UInt(8.W)).Lit(0 -> 42.U, 2 -> 5.U) - chisel3.assert(vecLit(0) === 42.U) - chisel3.assert(vecLit(2) === 5.U) - - val vecWire = Wire(Vec(4, UInt(8.W))) - vecWire := vecLit - - chisel3.assert(vecWire(0) === 42.U) - chisel3.assert(vecWire(2) === 5.U) - - stop() - } - } - } - - "nested vec literals should be constructable" in { - val outerVec = Vec(2, Vec(3, UInt(4.W))).Lit( - 0 -> Vec(3, UInt(4.W)).Lit(0 -> 1.U, 1 -> 2.U, 2 -> 3.U), - 1 -> Vec(3, UInt(4.W)).Lit(0 -> 4.U, 1 -> 5.U, 2 -> 6.U) - ) - - outerVec.litValue should be(BigInt("654321", 16)) - outerVec(0).litValue should be(BigInt("321", 16)) - outerVec(1).litValue should be(BigInt("654", 16)) - outerVec(0)(0).litValue should be(BigInt(1)) - outerVec(0)(1).litValue should be(BigInt(2)) - outerVec(0)(2).litValue should be(BigInt(3)) - outerVec(1)(0).litValue should be(BigInt(4)) - outerVec(1)(1).litValue should be(BigInt(5)) - outerVec(1)(2).litValue should be(BigInt(6)) - } - - "contained vecs should work" in { - assertTesterPasses { - new BasicTester { - val outerVec = Vec(2, Vec(3, UInt(4.W))).Lit( - 0 -> Vec(3, UInt(4.W)).Lit(0 -> 1.U, 1 -> 2.U, 2 -> 3.U), - 1 -> Vec(3, UInt(4.W)).Lit(0 -> 4.U, 1 -> 5.U, 2 -> 6.U) - ) - - chisel3.assert(outerVec(0)(0) === 1.U) - chisel3.assert(outerVec(0)(1) === 2.U) - chisel3.assert(outerVec(0)(2) === 3.U) - chisel3.assert(outerVec(1)(0) === 4.U) - chisel3.assert(outerVec(1)(1) === 5.U) - chisel3.assert(outerVec(1)(2) === 6.U) - - val v0 = outerVec(0) - val v1 = outerVec(1) - chisel3.assert(v0(0) === 1.U) - chisel3.assert(v0(1) === 2.U) - chisel3.assert(v0(2) === 3.U) - chisel3.assert(v1(0) === 4.U) - chisel3.assert(v1(1) === 5.U) - chisel3.assert(v1(2) === 6.U) - - stop() - } - } - } - //TODO: decide what behavior here should be "This doesn't work should it" ignore { assertTesterPasses { @@ -360,170 +49,4 @@ class VecLiteralSpec extends ChiselFreeSpec with Utils { } } } - - "Vec literals should work as register reset values" in { - assertTesterPasses { - new BasicTester { - val r = RegInit(Vec(3, UInt(11.W)).Lit(0 -> 0xa.U, 1 -> 0xb.U, 2 -> 0xc.U)) - r := (r.asUInt + 1.U).asTypeOf(Vec(3, UInt(11.W))) // prevent constprop - - // check reset values on first cycle out of reset - chisel3.assert(r(0) === 0xa.U) - chisel3.assert(r(1) === 0xb.U) - chisel3.assert(r(2) === 0xc.U) - stop() - } - } - } - - "partially initialized Vec literals should work as register reset values" in { - assertTesterPasses { - new BasicTester { - val r = RegInit(Vec(3, UInt(11.W)).Lit(0 -> 0xa.U, 2 -> 0xc.U)) - r := (r.asUInt + 1.U).asTypeOf(Vec(3, UInt(11.W))) // prevent constprop - // check reset values on first cycle out of reset - chisel3.assert(r(0) === 0xa.U) - chisel3.assert(r(2) === 0xc.U) - stop() - } - } - } - - "Fields extracted from Vec Literals should work as register reset values" in { - assertTesterPasses { - new BasicTester { - val r = RegInit(Vec(3, UInt(11.W)).Lit(0 -> 0xa.U, 2 -> 0xc.U).apply(0)) - r := r + 1.U // prevent const prop - chisel3.assert(r === 0xa.U) // coming out of reset - stop() - } - } - } - - "DontCare fields extracted from Vec Literals should work as register reset values" in { - assertTesterPasses { - new BasicTester { - val r = RegInit(Vec(3, Bool()).Lit(0 -> true.B).apply(2)) - r := reset.asBool - printf(p"r = $r\n") // Can't assert because reset value is DontCare - stop() - } - } - } - - "DontCare fields extracted from Vec Literals should work in other Expressions" in { - assertTesterPasses { - new BasicTester { - val x = Vec(3, Bool()).Lit(0 -> true.B).apply(2) || true.B - chisel3.assert(x === true.B) - stop() - } - } - } - - "vec literals with non-literal values should fail" in { - val exc = intercept[VecLiteralException] { - extractCause[VecLiteralException] { - ChiselStage.elaborate { - new RawModule { - (Vec(3, UInt(11.W)).Lit(0 -> UInt())) - } - } - } - } - exc.getMessage should include("field 0 specified with non-literal value UInt") - } - - "vec literals are instantiated on connect and are not bulk connected" in { - class VecExample5 extends RawModule { - val out = IO(Output(Vec(2, UInt(4.W)))) - val bundle = Vec(2, UInt(4.W)).Lit( - 0 -> 0xa.U, - 1 -> 0xb.U - ) - out := bundle - } - - val firrtl = (new chisel3.stage.ChiselStage).emitFirrtl(new VecExample5, args = Array("--full-stacktrace")) - firrtl should include("""out[0] <= UInt<4>("ha")""") - firrtl should include("""out[1] <= UInt<4>("hb")""") - } - - class SubBundle extends Bundle { - val foo = UInt(8.W) - val bar = UInt(4.W) - } - - class VecExample extends RawModule { - val out = IO(Output(Vec(2, new SubBundle))) - val bundle = Vec(2, new SubBundle).Lit( - 0 -> (new SubBundle).Lit(_.foo -> 42.U, _.bar -> 22.U), - 1 -> (new SubBundle).Lit(_.foo -> 7.U, _.bar -> 3.U) - ) - out := bundle - } - - "vec literals can contain bundles and should not be bulk connected" in { - val chirrtl = (new chisel3.stage.ChiselStage).emitChirrtl(new VecExample, args = Array("--full-stacktrace")) - chirrtl should include("""out[0].bar <= UInt<5>("h16")""") - chirrtl should include("""out[0].foo <= UInt<6>("h2a")""") - chirrtl should include("""out[1].bar <= UInt<2>("h3")""") - chirrtl should include("""out[1].foo <= UInt<3>("h7")""") - } - - "vec literals can have bundle children" in { - val vec = Vec(2, new SubBundle).Lit( - 0 -> (new SubBundle).Lit(_.foo -> 0xab.U, _.bar -> 0xc.U), - 1 -> (new SubBundle).Lit(_.foo -> 0xde.U, _.bar -> 0xf.U) - ) - vec.litValue.toString(16) should be("defabc") - } - - "vec literals can have bundle children assembled incrementally" in { - val bundle1 = (new SubBundle).Lit(_.foo -> 0xab.U, _.bar -> 0xc.U) - val bundle2 = (new SubBundle).Lit(_.foo -> 0xde.U, _.bar -> 0xf.U) - - bundle1.litValue.toString(16) should be("abc") - bundle2.litValue.toString(16) should be("def") - - val vec = Vec(2, new SubBundle).Lit(0 -> bundle1, 1 -> bundle2) - - vec.litValue.toString(16) should be("defabc") - } - - "bundles can contain vec lits" in { - val vec1 = Vec(3, UInt(4.W)).Lit(0 -> 0xa.U, 1 -> 0xb.U, 2 -> 0xc.U) - val vec2 = Vec(2, UInt(4.W)).Lit(0 -> 0xd.U, 1 -> 0xe.U) - val bundle = (new Bundle { - val foo = Vec(3, UInt(4.W)) - val bar = Vec(2, UInt(4.W)) - }).Lit(_.foo -> vec1, _.bar -> vec2) - bundle.litValue.toString(16) should be("cbaed") - } - - "bundles can contain vec lits in-line" in { - val bundle = (new Bundle { - val foo = Vec(3, UInt(4.W)) - val bar = Vec(2, UInt(4.W)) - }).Lit( - _.foo -> Vec(3, UInt(4.W)).Lit(0 -> 0xa.U, 1 -> 0xb.U, 2 -> 0xc.U), - _.bar -> Vec(2, UInt(4.W)).Lit(0 -> 0xd.U, 1 -> 0xe.U) - ) - bundle.litValue.toString(16) should be("cbaed") - } - - "Vec.Lit is a trivial Vec literal factory" in { - val vec = Vec.Lit(0xa.U, 0xb.U) - vec(0).litValue should be(0xa) - vec(1).litValue should be(0xb) - } - - "Vec.Lit bases it's element width on the widest literal supplied" in { - val vec = Vec.Lit(0xa.U, 0xbbbb.U) - vec(0).litValue should be(0xa) - vec(1).litValue should be(0xbbbb) - vec.length should be(2) - vec.getWidth should be(16 * 2) - vec.litValue should be(BigInt("bbbb000a", 16)) - } }