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
|
// See LICENSE for license details.
package chiselTests
import firrtl._
import chisel3._
import chisel3.experimental.annotate
import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage}
import chisel3.util.experimental.{forceName, ForceNameAnnotation, ForceNamesTransform, InlineInstance}
import firrtl.annotations.{Annotation, ReferenceTarget}
import firrtl.options.{Dependency, TargetDirAnnotation}
import firrtl.stage.RunFirrtlTransformAnnotation
import logger.{LogLevel, LogLevelAnnotation}
/** Object containing Modules used for testing */
object ForceNamesHierarchy {
class WrapperExample extends Module {
val in = IO(Input(UInt(3.W)))
val out = IO(Output(UInt(3.W)))
val inst = Module(new Wrapper)
inst.in := in
out := inst.out
forceName(out, "outt")
}
class Wrapper extends Module with InlineInstance {
val in = IO(Input(UInt(3.W)))
val out = IO(Output(UInt(3.W)))
val inst = Module(new MyLeaf)
forceName(inst, "inst")
inst.in := in
out := inst.out
}
class MyLeaf extends Module {
val in = IO(Input(UInt(3.W)))
val out = IO(Output(UInt(3.W)))
out := in
}
class RenamePortsExample extends Module {
val in = IO(Input(UInt(3.W)))
val out = IO(Output(UInt(3.W)))
val inst = Module(new MyLeaf)
inst.in := in
out := inst.out
forceName(inst.in, "inn")
}
class ConflictingName extends Module {
val in = IO(Input(UInt(3.W)))
val out = IO(Output(UInt(3.W)))
out := in
forceName(out, "in")
}
class BundleName extends Module {
val in = IO(new Bundle {
val a = Input(UInt(3.W))
val b = Input(UInt(3.W))
})
val out = IO(Output(UInt(3.W)))
out := in.a + in.b
}
}
class ForceNamesSpec extends ChiselFlatSpec {
def run[T <: RawModule](
dut: => T,
testName: String,
inputAnnos: Seq[Annotation] = Nil,
info: LogLevel.Value = LogLevel.None
): Iterable[String] = {
def stage = new ChiselStage {
override val targets = Seq(
Dependency[chisel3.stage.phases.Elaborate],
Dependency[chisel3.stage.phases.Convert],
Dependency[firrtl.stage.phases.Compiler]
)
}
val annos = List(
TargetDirAnnotation("test_run_dir/ForceNames"),
LogLevelAnnotation(info),
ChiselGeneratorAnnotation(() => dut)
) ++ inputAnnos
val ret = stage.execute(Array(), annos)
val verilog = ret.collectFirst {
case e: EmittedVerilogCircuitAnnotation => e.value.value
}.get
verilog.split("\\\n")
}
"Force Names on a wrapping instance" should "work" in {
val verilog = run(new ForceNamesHierarchy.WrapperExample, "wrapper")
exactly(1, verilog) should include("MyLeaf inst")
}
"Force Names on an instance port" should "work" in {
val verilog = run(new ForceNamesHierarchy.RenamePortsExample, "instports")
atLeast(1, verilog) should include("input [2:0] inn")
}
"Force Names with a conflicting name" should "error" in {
intercept[CustomTransformException] {
run(new ForceNamesHierarchy.ConflictingName, "conflicts")
}
}
"Force Names of an intermediate bundle" should "error" in {
intercept[CustomTransformException] {
run(
new ForceNamesHierarchy.BundleName,
"bundlename",
Seq(ForceNameAnnotation(ReferenceTarget("BundleName", "BundleName", Nil, "in", Nil), "inn"))
)
}
}
}
|