diff options
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/Aggregate.scala | 10 | ||||
| -rw-r--r-- | src/test/scala/chiselTests/BundleLiteralSpec.scala | 41 |
2 files changed, 45 insertions, 6 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/Aggregate.scala index 1619fd17..42b40ed9 100644 --- a/chiselFrontend/src/main/scala/chisel3/Aggregate.scala +++ b/chiselFrontend/src/main/scala/chisel3/Aggregate.scala @@ -8,6 +8,7 @@ import scala.language.experimental.macros import chisel3.experimental.BaseModule import chisel3.experimental.BundleLiteralException +import chisel3.experimental.EnumType import chisel3.internal._ import chisel3.internal.Builder.pushCommand import chisel3.internal.firrtl._ @@ -550,6 +551,15 @@ abstract class Record(private[chisel3] implicit val compileOptions: CompileOptio value.topBinding.asInstanceOf[BundleLitBinding].litMap.map { case (valueField, valueValue) => remap(valueField) -> valueValue } + case field: EnumType => { + if (!(field typeEquivalent value)) { + throw new BundleLiteralException(s"field $fieldName $field specified with non-type-equivalent enum value $value") + } + val litArg = valueBinding match { + case ElementLitBinding(litArg) => litArg + } + Seq(field -> litArg) + } case _ => throw new BundleLiteralException(s"unsupported field $fieldName of type $field") } } // don't convert to a Map yet to preserve duplicate keys diff --git a/src/test/scala/chiselTests/BundleLiteralSpec.scala b/src/test/scala/chiselTests/BundleLiteralSpec.scala index ec0bad66..eea22e11 100644 --- a/src/test/scala/chiselTests/BundleLiteralSpec.scala +++ b/src/test/scala/chiselTests/BundleLiteralSpec.scala @@ -6,32 +6,44 @@ import chisel3._ import chisel3.testers.BasicTester import chisel3.experimental.BundleLiterals._ import chisel3.experimental.BundleLiteralException +import chisel3.experimental.ChiselEnum class BundleLiteralSpec extends ChiselFlatSpec { + 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() } "bundle literals" should "work in RTL" in { - val outsideBundleLit = (new MyBundle).Lit(_.a -> 42.U, _.b -> true.B) + 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) - val bundleLit = (new MyBundle).Lit(_.a -> 42.U, _.b -> true.B) + 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() } } @@ -56,35 +68,42 @@ class BundleLiteralSpec extends ChiselFlatSpec { 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) + _.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) // 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.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) // 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) + 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) stop() } } @@ -93,11 +112,12 @@ class BundleLiteralSpec extends ChiselFlatSpec { "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) + 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() } } } @@ -152,4 +172,13 @@ class BundleLiteralSpec extends ChiselFlatSpec { exc.getMessage should include ("non-type-equivalent value") exc.getMessage should include (".b") } + + "bundle literals with non-type-equivalent enum element fields" should "fail" in { + val exc = intercept[BundleLiteralException] { elaborate { new RawModule { + (new MyBundle).Lit(_.c -> MyEnumB.sB) + }}} + exc.getMessage should include ("non-type-equivalent enum value") + exc.getMessage should include (".c") + } + } |
