Skip to content

Commit 4c10d0e

Browse files
mergify[bot]davidbiancolinjackkoenig
authored
Dev/biancolin/fix module choice under di (backport #4569) (#4570)
* Fix ModuleChoice under D/I (#4569) * Use FileCheck in ModuleChoice tests; add a test * DRY out module definitions in ModuleChoiceSpec * Add a ModuleChoice test using Definition * Ensure Groups are propagated to parent builder under D/I (cherry picked from commit 0070570) # Conflicts: # core/src/main/scala/chisel3/experimental/hierarchy/core/Definition.scala * Resolve backport conflicts * Tweak tests back to 6.x-style --------- Co-authored-by: David Biancolin <[email protected]> Co-authored-by: Jack Koenig <[email protected]> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
1 parent 320dfe8 commit 4c10d0e

File tree

2 files changed

+66
-51
lines changed

2 files changed

+66
-51
lines changed

core/src/main/scala/chisel3/experimental/hierarchy/core/Definition.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ object Definition extends SourceInfoDoc {
117117
Builder.components ++= ir._circuit.components
118118
Builder.annotations ++= ir._circuit.annotations
119119
Builder.newAnnotations ++= ir._circuit.newAnnotations
120+
Builder.options ++= dynamicContext.options
120121
module._circuit = Builder.currentModule
121122
module.toDefinition
122123
}

src/test/scala/chiselTests/ModuleChoiceSpec.scala

Lines changed: 65 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package chiselTests
55
import chisel3._
66
import chisel3.choice.{Case, Group, ModuleChoice}
77
import chiselTests.{ChiselFlatSpec, MatchesAndOmits, Utils}
8+
import chisel3.experimental.hierarchy.Definition
89
import _root_.circt.stage.ChiselStage
910

1011
object Platform extends Group {
@@ -17,26 +18,50 @@ 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

2225
class 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+
}
30+
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+
}
2539

2640
class ModuleChoiceSpec extends ChiselFlatSpec with Utils with MatchesAndOmits {
2741
it should "emit options and cases" in {
28-
class ModuleWithChoice extends Module {
29-
val out = IO(UInt(8.W))
42+
class ModuleWithValidChoices
43+
extends ModuleWithChoice(new VerifTarget)(Seq(Platform.FPGA -> new FPGATarget, Platform.ASIC -> new ASICTarget))
3044

31-
val inst =
32-
ModuleChoice(new VerifTarget)(Seq(Platform.FPGA -> new FPGATarget, Platform.ASIC -> new ASICTarget))
45+
val chirrtl = ChiselStage.emitCHIRRTL(new ModuleWithValidChoices)
46+
info("CHIRRTL emission looks correct")
47+
matchesAndOmits(chirrtl)(
48+
"option Platform :",
49+
"FPGA",
50+
"ASIC",
51+
"instchoice inst of VerifTarget, Platform :",
52+
"FPGA => FPGATarget",
53+
"ASIC => ASICTarget"
54+
)()
55+
}
3356

34-
inst.in := 42.U(8.W)
35-
out := inst.out
57+
it should "emit options and cases for Modules including definitions" in {
58+
class ModuleWithValidChoices
59+
extends ModuleWithChoice(new VerifTarget)(Seq(Platform.FPGA -> new FPGATarget, Platform.ASIC -> new ASICTarget))
60+
class TopWithDefinition extends Module {
61+
val definitionWithChoice = Definition(new ModuleWithValidChoices)
3662
}
3763

38-
val chirrtl = ChiselStage.emitCHIRRTL(new ModuleWithChoice, Array("--full-stacktrace"))
39-
64+
val chirrtl = ChiselStage.emitCHIRRTL(new TopWithDefinition)
4065
info("CHIRRTL emission looks correct")
4166
matchesAndOmits(chirrtl)(
4267
"option Platform :",
@@ -50,21 +75,16 @@ class ModuleChoiceSpec extends ChiselFlatSpec with Utils with MatchesAndOmits {
5075

5176
it should "require that all cases are part of the same option" in {
5277

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
78+
object Performance extends Group {
79+
object Fast extends Case
80+
object Small extends Case
6681
}
6782

83+
class MixedOptions
84+
extends ModuleWithChoice(new VerifTarget)(
85+
Seq(Platform.FPGA -> new FPGATarget, Performance.Fast -> new ASICTarget)
86+
)
87+
6888
intercept[IllegalArgumentException] { ChiselStage.emitCHIRRTL(new MixedOptions) }.getMessage() should include(
6989
"cannot mix choices from different groups: Platform, Performance"
7090
)
@@ -73,33 +93,35 @@ class ModuleChoiceSpec extends ChiselFlatSpec with Utils with MatchesAndOmits {
7393

7494
it should "require that at least one alternative is present" in {
7595

76-
class MixedOptions extends Module {
77-
val out = IO(UInt(8.W))
96+
class NoAlternatives extends ModuleWithChoice(new VerifTarget)(Seq())
7897

79-
val inst =
80-
ModuleChoice(new VerifTarget)(Seq())
81-
82-
inst.in := 42.U(8.W)
83-
out := inst.out
84-
}
85-
86-
intercept[IllegalArgumentException] { ChiselStage.emitCHIRRTL(new MixedOptions) }.getMessage() should include(
98+
intercept[IllegalArgumentException] { ChiselStage.emitCHIRRTL(new NoAlternatives) }.getMessage() should include(
8799
"at least one alternative must be specified"
88100
)
89101

90102
}
91103

92-
it should "require that all cases are distinct" in {
104+
it should "allow a subset of options to be provided" in {
93105

94-
class MixedOptions extends Module {
95-
val out = IO(UInt(8.W))
106+
class SubsetOptions extends ModuleWithChoice(new VerifTarget)(Seq(Platform.FPGA -> new FPGATarget))
107+
108+
// Note, because of a quirk in how [[Case]]s are registered, only those referenced
109+
// in the Module here are going to be captured. This will be fixed in a forthcoming PR
110+
// that implements an [[addLayer]] like feature for [[Group]]s
111+
val chirrtl = ChiselStage.emitCHIRRTL(new SubsetOptions)
112+
info("CHIRRTL emission looks correct")
113+
matchesAndOmits(chirrtl)(
114+
"option Platform :",
115+
"FPGA",
116+
"instchoice inst of VerifTarget, Platform :",
117+
"FPGA => FPGATarget"
118+
)()
119+
}
96120

97-
val inst =
98-
ModuleChoice(new VerifTarget)(Seq(Platform.FPGA -> new FPGATarget, Platform.FPGA -> new ASICTarget))
121+
it should "require that all cases are distinct" in {
99122

100-
inst.in := 42.U(8.W)
101-
out := inst.out
102-
}
123+
class MixedOptions
124+
extends ModuleWithChoice(new VerifTarget)(Seq(Platform.FPGA -> new FPGATarget, Platform.FPGA -> new ASICTarget))
103125

104126
intercept[IllegalArgumentException] { ChiselStage.emitCHIRRTL(new MixedOptions) }.getMessage() should include(
105127
"duplicate case 'FPGA'"
@@ -109,17 +131,9 @@ class ModuleChoiceSpec extends ChiselFlatSpec with Utils with MatchesAndOmits {
109131

110132
it should "require that all IO bundles are type equivalent" in {
111133

112-
class MixedIO extends Module {
113-
val out = IO(UInt(8.W))
114-
115-
class Target16 extends FixedIOExtModule[TargetIO](new TargetIO(16))
134+
class Target16 extends FixedIOExtModule[TargetIO](new TargetIO(16))
116135

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-
}
136+
class MixedIO extends ModuleWithChoice(new VerifTarget)(Seq(Platform.FPGA -> new Target16))
123137

124138
intercept[ChiselException] { ChiselStage.emitCHIRRTL(new MixedIO, Array("--throw-on-first-error")) }
125139
.getMessage() should include(

0 commit comments

Comments
 (0)