blob: 3ab4cc32b1a7cfcbdf741859b562bd07e6f70b07 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
// SPDX-License-Identifier: Apache-2.0
package chiselTests
import chisel3._
import chisel3.experimental._
import chisel3.stage.ChiselStage
import chisel3.testers.{BasicTester, TesterDriver}
// Avoid collisions with regular BlackBox tests by putting ExtModule blackboxes
// in their own scope.
package extmoduletests {
import chisel3.experimental.ExtModule
class BlackBoxInverter extends ExtModule {
val in = IO(Input(Bool()))
val out = IO(Output(Bool()))
}
class BlackBoxPassthrough extends ExtModule {
val in = IO(Input(Bool()))
val out = IO(Output(Bool()))
}
}
class ExtModuleTester extends BasicTester {
val blackBoxPos = Module(new extmoduletests.BlackBoxInverter)
val blackBoxNeg = Module(new extmoduletests.BlackBoxInverter)
blackBoxPos.in := 1.U
blackBoxNeg.in := 0.U
assert(blackBoxNeg.out === 1.U)
assert(blackBoxPos.out === 0.U)
stop()
}
/** Instantiate multiple BlackBoxes with similar interfaces but different
* functionality. Used to detect failures in BlackBox naming and module
* deduplication.
*/
class MultiExtModuleTester extends BasicTester {
val blackBoxInvPos = Module(new extmoduletests.BlackBoxInverter)
val blackBoxInvNeg = Module(new extmoduletests.BlackBoxInverter)
val blackBoxPassPos = Module(new extmoduletests.BlackBoxPassthrough)
val blackBoxPassNeg = Module(new extmoduletests.BlackBoxPassthrough)
blackBoxInvPos.in := 1.U
blackBoxInvNeg.in := 0.U
blackBoxPassPos.in := 1.U
blackBoxPassNeg.in := 0.U
assert(blackBoxInvNeg.out === 1.U)
assert(blackBoxInvPos.out === 0.U)
assert(blackBoxPassNeg.out === 0.U)
assert(blackBoxPassPos.out === 1.U)
stop()
}
class ExtModuleWithSuggestName extends ExtModule {
val in = IO(Input(UInt(8.W)))
in.suggestName("foo")
val out = IO(Output(UInt(8.W)))
}
class ExtModuleWithSuggestNameTester extends Module {
val in = IO(Input(UInt(8.W)))
val out = IO(Output(UInt(8.W)))
val inst = Module(new ExtModuleWithSuggestName)
inst.in := in
out := inst.out
}
class SimpleIOBundle extends Bundle {
val in = Input(UInt(8.W))
val out = Output(UInt(8.W))
}
class ExtModuleWithFlatIO extends ExtModule {
val badIO = FlatIO(new SimpleIOBundle)
}
class ExtModuleWithFlatIOTester extends Module {
val io = IO(new SimpleIOBundle)
val inst = Module(new ExtModuleWithFlatIO)
io <> inst.badIO
}
class ExtModuleInvalidatedTester extends Module {
val in = IO(Input(UInt(8.W)))
val out = IO(Output(UInt(8.W)))
val inst = Module(new ExtModule {
val in = IO(Input(UInt(8.W)))
val out = IO(Output(UInt(8.W)))
})
inst.in := in
out := inst.out
}
class ExtModuleSpec extends ChiselFlatSpec {
"A ExtModule inverter" should "work" in {
assertTesterPasses({ new ExtModuleTester }, Seq("/chisel3/BlackBoxTest.v"), TesterDriver.verilatorOnly)
}
"Multiple ExtModules" should "work" in {
assertTesterPasses({ new MultiExtModuleTester }, Seq("/chisel3/BlackBoxTest.v"), TesterDriver.verilatorOnly)
}
"DataMirror.modulePorts" should "work with ExtModule" in {
ChiselStage.elaborate(new Module {
val io = IO(new Bundle {})
val m = Module(new extmoduletests.BlackBoxPassthrough)
assert(DataMirror.modulePorts(m) == Seq("in" -> m.in, "out" -> m.out))
})
}
behavior.of("ExtModule")
it should "work with .suggestName (aka it should not require reflection for naming)" in {
val chirrtl = ChiselStage.emitChirrtl(new ExtModuleWithSuggestNameTester)
chirrtl should include("input foo : UInt<8>")
chirrtl should include("inst.foo <= in")
}
it should "work with FlatIO" in {
val chirrtl = ChiselStage.emitChirrtl(new ExtModuleWithFlatIOTester)
chirrtl should include("io.out <= inst.out")
chirrtl should include("inst.in <= io.in")
chirrtl shouldNot include("badIO")
}
it should "not have invalidated ports in a chisel3._ context" in {
val chirrtl = ChiselStage.emitChirrtl(new ExtModuleInvalidatedTester)
chirrtl shouldNot include("inst.in is invalid")
chirrtl shouldNot include("inst.out is invalid")
}
}
|