Skip to content

Commit 39f6c69

Browse files
authored
Add ChiselEnum to BundleLiterals (#1215) (#1266)
(cherry picked from commit 03bbb25)
1 parent 43de442 commit 39f6c69

File tree

2 files changed

+45
-6
lines changed

2 files changed

+45
-6
lines changed

chiselFrontend/src/main/scala/chisel3/Aggregate.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import scala.language.experimental.macros
88

99
import chisel3.experimental.BaseModule
1010
import chisel3.experimental.BundleLiteralException
11+
import chisel3.experimental.EnumType
1112
import chisel3.internal._
1213
import chisel3.internal.Builder.pushCommand
1314
import chisel3.internal.firrtl._
@@ -550,6 +551,15 @@ abstract class Record(private[chisel3] implicit val compileOptions: CompileOptio
550551
value.topBinding.asInstanceOf[BundleLitBinding].litMap.map { case (valueField, valueValue) =>
551552
remap(valueField) -> valueValue
552553
}
554+
case field: EnumType => {
555+
if (!(field typeEquivalent value)) {
556+
throw new BundleLiteralException(s"field $fieldName $field specified with non-type-equivalent enum value $value")
557+
}
558+
val litArg = valueBinding match {
559+
case ElementLitBinding(litArg) => litArg
560+
}
561+
Seq(field -> litArg)
562+
}
553563
case _ => throw new BundleLiteralException(s"unsupported field $fieldName of type $field")
554564
}
555565
} // don't convert to a Map yet to preserve duplicate keys

src/test/scala/chiselTests/BundleLiteralSpec.scala

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,32 +6,44 @@ import chisel3._
66
import chisel3.testers.BasicTester
77
import chisel3.experimental.BundleLiterals._
88
import chisel3.experimental.BundleLiteralException
9+
import chisel3.experimental.ChiselEnum
910

1011
class BundleLiteralSpec extends ChiselFlatSpec {
12+
object MyEnum extends ChiselEnum {
13+
val sA, sB = Value
14+
}
15+
object MyEnumB extends ChiselEnum {
16+
val sA, sB = Value
17+
}
1118
class MyBundle extends Bundle {
1219
val a = UInt(8.W)
1320
val b = Bool()
21+
val c = MyEnum()
1422
}
1523

1624
"bundle literals" should "work in RTL" in {
17-
val outsideBundleLit = (new MyBundle).Lit(_.a -> 42.U, _.b -> true.B)
25+
val outsideBundleLit = (new MyBundle).Lit(_.a -> 42.U, _.b -> true.B, _.c -> MyEnum.sB)
1826
assertTesterPasses{ new BasicTester{
1927
// TODO: add direct bundle compare operations, when that feature is added
2028
chisel3.assert(outsideBundleLit.a === 42.U)
2129
chisel3.assert(outsideBundleLit.b === true.B)
30+
chisel3.assert(outsideBundleLit.c === MyEnum.sB)
2231

23-
val bundleLit = (new MyBundle).Lit(_.a -> 42.U, _.b -> true.B)
32+
val bundleLit = (new MyBundle).Lit(_.a -> 42.U, _.b -> true.B, _.c -> MyEnum.sB)
2433
chisel3.assert(bundleLit.a === 42.U)
2534
chisel3.assert(bundleLit.b === true.B)
35+
chisel3.assert(bundleLit.c === MyEnum.sB)
2636

2737
chisel3.assert(bundleLit.a === outsideBundleLit.a)
2838
chisel3.assert(bundleLit.b === outsideBundleLit.b)
39+
chisel3.assert(bundleLit.c === outsideBundleLit.c)
2940

3041
val bundleWire = Wire(new MyBundle)
3142
bundleWire := outsideBundleLit
3243

3344
chisel3.assert(bundleWire.a === 42.U)
3445
chisel3.assert(bundleWire.b === true.B)
46+
chisel3.assert(bundleWire.c === MyEnum.sB)
3547

3648
stop()
3749
} }
@@ -56,35 +68,42 @@ class BundleLiteralSpec extends ChiselFlatSpec {
5668
val b = new Bundle {
5769
val c = Bool()
5870
val d = UInt(8.W)
71+
val e = MyEnum()
5972
}
73+
val f = MyEnum()
6074
}
6175

6276
"contained bundles" should "work" in {
6377
assertTesterPasses{ new BasicTester{
6478
// Specify the inner Bundle value as a Bundle literal
6579
val explicitBundleLit = (new MyOuterBundle).Lit(
66-
_.a -> (new MyBundle).Lit(_.a -> 42.U, _.b -> true.B)
80+
_.a -> (new MyBundle).Lit(_.a -> 42.U, _.b -> true.B, _.c -> MyEnum.sB)
6781
)
6882
chisel3.assert(explicitBundleLit.a.a === 42.U)
6983
chisel3.assert(explicitBundleLit.a.b === true.B)
84+
chisel3.assert(explicitBundleLit.a.c === MyEnum.sB)
7085

7186
// Specify the inner Bundle fields directly
7287
val expandedBundleLit = (new MyOuterBundle).Lit(
7388
_.a.a -> 42.U, _.a.b -> true.B,
74-
_.b.c -> false.B, _.b.d -> 255.U
89+
_.b.c -> false.B, _.b.d -> 255.U, _.b.e -> MyEnum.sB,
90+
_.f -> MyEnum.sB
7591
)
7692
chisel3.assert(expandedBundleLit.a.a === 42.U)
7793
chisel3.assert(expandedBundleLit.a.b === true.B)
94+
chisel3.assert(expandedBundleLit.f === MyEnum.sB)
7895
chisel3.assert(expandedBundleLit.b.c === false.B)
7996
chisel3.assert(expandedBundleLit.b.d === 255.U)
97+
chisel3.assert(expandedBundleLit.b.e === MyEnum.sB)
8098

8199
// Anonymously contruct the inner Bundle literal
82100
// A bit of weird syntax that depends on implementation details of the Bundle literal constructor
83101
val childBundleLit = (new MyOuterBundle).Lit(
84-
b => b.b -> b.b.Lit(_.c -> false.B, _.d -> 255.U)
102+
b => b.b -> b.b.Lit(_.c -> false.B, _.d -> 255.U, _.e -> MyEnum.sB)
85103
)
86104
chisel3.assert(childBundleLit.b.c === false.B)
87105
chisel3.assert(childBundleLit.b.d === 255.U)
106+
chisel3.assert(childBundleLit.b.e === MyEnum.sB)
88107

89108
stop()
90109
} }
@@ -93,11 +112,12 @@ class BundleLiteralSpec extends ChiselFlatSpec {
93112
"Bundle literals" should "assign" in {
94113
assertTesterPasses{ new BasicTester{
95114
val bundleWire = Wire(Output(new MyBundle))
96-
val bundleLit = (new MyBundle).Lit(_.a -> 42.U, _.b -> true.B)
115+
val bundleLit = (new MyBundle).Lit(_.a -> 42.U, _.b -> true.B, _.c -> MyEnum.sB)
97116
bundleWire := bundleLit
98117

99118
chisel3.assert(bundleWire.a === 42.U)
100119
chisel3.assert(bundleWire.b === true.B)
120+
chisel3.assert(bundleWire.c === MyEnum.sB)
101121
stop()
102122
} }
103123
}
@@ -152,4 +172,13 @@ class BundleLiteralSpec extends ChiselFlatSpec {
152172
exc.getMessage should include ("non-type-equivalent value")
153173
exc.getMessage should include (".b")
154174
}
175+
176+
"bundle literals with non-type-equivalent enum element fields" should "fail" in {
177+
val exc = intercept[BundleLiteralException] { elaborate { new RawModule {
178+
(new MyBundle).Lit(_.c -> MyEnumB.sB)
179+
}}}
180+
exc.getMessage should include ("non-type-equivalent enum value")
181+
exc.getMessage should include (".c")
182+
}
183+
155184
}

0 commit comments

Comments
 (0)