@@ -5,6 +5,7 @@ package chiselTests
55import chisel3 ._
66import chisel3 .choice .{Case , Group , ModuleChoice }
77import chiselTests .{ChiselFlatSpec , MatchesAndOmits , Utils }
8+ import chisel3 .experimental .hierarchy .Definition
89import _root_ .circt .stage .ChiselStage
910
1011object Platform extends Group {
@@ -17,54 +18,69 @@ class TargetIO(width: Int) extends Bundle {
1718 val out = UInt (width.W )
1819}
1920
20- class FPGATarget extends FixedIOExtModule [TargetIO ](new TargetIO (8 ))
21+ class FPGATarget extends FixedIORawModule [TargetIO ](new TargetIO (8 )) {
22+ io.out := io.in
23+ }
2124
2225class ASICTarget extends FixedIOExtModule [TargetIO ](new TargetIO (8 ))
2326
24- class VerifTarget extends FixedIORawModule [TargetIO ](new TargetIO (8 ))
27+ class VerifTarget extends FixedIORawModule [TargetIO ](new TargetIO (8 )) {
28+ io.out := io.in
29+ }
2530
26- class ModuleChoiceSpec extends ChiselFlatSpec with Utils with MatchesAndOmits {
27- it should " emit options and cases" in {
28- class ModuleWithChoice extends Module {
29- val out = IO (UInt (8 .W ))
31+ class ModuleWithChoice [T <: Data ](
32+ default : => FixedIOBaseModule [T ]
33+ )(alternateImpls : Seq [(Case , () => FixedIOBaseModule [T ])])
34+ extends Module {
35+ val inst = ModuleChoice (default)(alternateImpls)
36+ val io = IO (inst.cloneType)
37+ io <> inst
38+ }
3039
31- val inst =
32- ModuleChoice (new VerifTarget )(Seq (Platform .FPGA -> new FPGATarget , Platform .ASIC -> new ASICTarget ))
40+ class ModuleChoiceSpec extends ChiselFlatSpec with Utils with FileCheck {
41+ it should " emit options and cases" in {
42+ class ModuleWithValidChoices
43+ extends ModuleWithChoice (new VerifTarget )(Seq (Platform .FPGA -> new FPGATarget , Platform .ASIC -> new ASICTarget ))
44+
45+ generateFirrtlAndFileCheck(new ModuleWithValidChoices )(
46+ """ |CHECK: option Platform :
47+ |CHECK-NEXT: FPGA
48+ |CHECK-NEXT: ASIC
49+ |CHECK: instchoice inst of VerifTarget, Platform :
50+ |CHECK-NEXT: FPGA => FPGATarget
51+ |CHECK-NEXT: ASIC => ASICTarget""" .stripMargin
52+ )
53+ }
3354
34- inst.in := 42 .U (8 .W )
35- out := inst.out
55+ it should " emit options and cases for Modules including definitions" in {
56+ class ModuleWithValidChoices
57+ extends ModuleWithChoice (new VerifTarget )(Seq (Platform .FPGA -> new FPGATarget , Platform .ASIC -> new ASICTarget ))
58+ class TopWithDefinition extends Module {
59+ val definitionWithChoice = Definition (new ModuleWithValidChoices )
3660 }
3761
38- val chirrtl = ChiselStage .emitCHIRRTL(new ModuleWithChoice , Array (" --full-stacktrace" ))
39-
40- info(" CHIRRTL emission looks correct" )
41- matchesAndOmits(chirrtl)(
42- " option Platform :" ,
43- " FPGA" ,
44- " ASIC" ,
45- " instchoice inst of VerifTarget, Platform :" ,
46- " FPGA => FPGATarget" ,
47- " ASIC => ASICTarget"
48- )()
62+ generateFirrtlAndFileCheck(new TopWithDefinition )(
63+ """ |CHECK: option Platform :
64+ |CHECK-NEXT: FPGA
65+ |CHECK-NEXT: ASIC
66+ |CHECK: instchoice inst of VerifTarget, Platform :
67+ |CHECK-NEXT: FPGA => FPGATarget
68+ |CHECK-NEXT: ASIC => ASICTarget""" .stripMargin
69+ )
4970 }
5071
5172 it should " require that all cases are part of the same option" in {
5273
53- class MixedOptions extends Module {
54- object Performance extends Group {
55- object Fast extends Case
56- object Small extends Case
57- }
58-
59- val out = IO (UInt (8 .W ))
60-
61- val inst =
62- ModuleChoice (new VerifTarget )(Seq (Platform .FPGA -> new FPGATarget , Performance .Fast -> new ASICTarget ))
63-
64- inst.in := 42 .U (8 .W )
65- out := inst.out
74+ object Performance extends Group {
75+ object Fast extends Case
76+ object Small extends Case
6677 }
6778
79+ class MixedOptions
80+ extends ModuleWithChoice (new VerifTarget )(
81+ Seq (Platform .FPGA -> new FPGATarget , Performance .Fast -> new ASICTarget )
82+ )
83+
6884 intercept[IllegalArgumentException ] { ChiselStage .emitCHIRRTL(new MixedOptions ) }.getMessage() should include(
6985 " cannot mix choices from different groups: Platform, Performance"
7086 )
@@ -73,33 +89,33 @@ class ModuleChoiceSpec extends ChiselFlatSpec with Utils with MatchesAndOmits {
7389
7490 it should " require that at least one alternative is present" in {
7591
76- class MixedOptions extends Module {
77- val out = IO (UInt (8 .W ))
78-
79- val inst =
80- ModuleChoice (new VerifTarget )(Seq ())
92+ class NoAlternatives extends ModuleWithChoice (new VerifTarget )(Seq ())
8193
82- inst.in := 42 .U (8 .W )
83- out := inst.out
84- }
85-
86- intercept[IllegalArgumentException ] { ChiselStage .emitCHIRRTL(new MixedOptions ) }.getMessage() should include(
94+ intercept[IllegalArgumentException ] { ChiselStage .emitCHIRRTL(new NoAlternatives ) }.getMessage() should include(
8795 " at least one alternative must be specified"
8896 )
8997
9098 }
9199
92- it should " require that all cases are distinct" in {
100+ it should " allow a subset of options to be provided" in {
101+
102+ class SubsetOptions extends ModuleWithChoice (new VerifTarget )(Seq (Platform .FPGA -> new FPGATarget ))
93103
94- class MixedOptions extends Module {
95- val out = IO (UInt (8 .W ))
104+ // Note, because of a quirk in how [[Case]]s are registered, only those referenced
105+ // in the Module here are going to be captured. This will be fixed in a forthcoming PR
106+ // that implements an [[addLayer]] like feature for [[Group]]s
107+ generateFirrtlAndFileCheck(new SubsetOptions )(
108+ """ |CHECK: option Platform :
109+ |CHECK-NEXT: FPGA
110+ |CHECK: instchoice inst of VerifTarget, Platform :
111+ |CHECK-NEXT: FPGA => FPGATarget""" .stripMargin
112+ )
113+ }
96114
97- val inst =
98- ModuleChoice (new VerifTarget )(Seq (Platform .FPGA -> new FPGATarget , Platform .FPGA -> new ASICTarget ))
115+ it should " require that all cases are distinct" in {
99116
100- inst.in := 42 .U (8 .W )
101- out := inst.out
102- }
117+ class MixedOptions
118+ extends ModuleWithChoice (new VerifTarget )(Seq (Platform .FPGA -> new FPGATarget , Platform .FPGA -> new ASICTarget ))
103119
104120 intercept[IllegalArgumentException ] { ChiselStage .emitCHIRRTL(new MixedOptions ) }.getMessage() should include(
105121 " duplicate case 'FPGA'"
@@ -109,17 +125,9 @@ class ModuleChoiceSpec extends ChiselFlatSpec with Utils with MatchesAndOmits {
109125
110126 it should " require that all IO bundles are type equivalent" in {
111127
112- class MixedIO extends Module {
113- val out = IO (UInt (8 .W ))
128+ class Target16 extends FixedIOExtModule [TargetIO ](new TargetIO (16 ))
114129
115- class Target16 extends FixedIOExtModule [TargetIO ](new TargetIO (16 ))
116-
117- val inst =
118- ModuleChoice (new VerifTarget )(Seq (Platform .FPGA -> new Target16 ))
119-
120- inst.in := 42 .U (8 .W )
121- out := inst.out
122- }
130+ class MixedIO extends ModuleWithChoice (new VerifTarget )(Seq (Platform .FPGA -> new Target16 ))
123131
124132 intercept[ChiselException ] { ChiselStage .emitCHIRRTL(new MixedIO , Array (" --throw-on-first-error" )) }
125133 .getMessage() should include(
0 commit comments