summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chiselFrontend/src/main/scala/chisel3/Aggregate.scala10
-rw-r--r--src/test/scala/chiselTests/BundleLiteralSpec.scala41
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")
+ }
+
}