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
|
// SPDX-License-Identifier: Apache-2.0
package firrtl.analysis
import firrtl.analyses._
import firrtl.ir
import firrtl.options.Dependency
import org.scalatest.flatspec.AnyFlatSpec
class SymbolTableSpec extends AnyFlatSpec {
behavior.of("SymbolTable")
private val src =
"""circuit m:
| module child:
| input x : UInt<2>
| skip
| module m:
| input clk : Clock
| input x : UInt<1>
| output y : UInt<3>
| wire z : SInt<1>
| node a = cat(asUInt(z), x)
| inst i of child
| reg r: SInt<4>, clk
| mem m:
| data-type => UInt<8>
| depth => 31
| reader => r
| read-latency => 1
| write-latency => 1
| read-under-write => undefined
|""".stripMargin
it should "find all declarations in module m before InferTypes" in {
val c = firrtl.Parser.parse(src)
val m = c.modules.find(_.name == "m").get
val syms = SymbolTable.scanModule(m, new LocalSymbolTable with WithMap)
assert(syms.size == 8)
assert(syms("clk").tpe == ir.ClockType && syms("clk").kind == firrtl.PortKind)
assert(syms("x").tpe == ir.UIntType(ir.IntWidth(1)) && syms("x").kind == firrtl.PortKind)
assert(syms("y").tpe == ir.UIntType(ir.IntWidth(3)) && syms("y").kind == firrtl.PortKind)
assert(syms("z").tpe == ir.SIntType(ir.IntWidth(1)) && syms("z").kind == firrtl.WireKind)
// The expression type which determines the node type is only known after InferTypes.
assert(syms("a").tpe == ir.UnknownType && syms("a").kind == firrtl.NodeKind)
// The type of the instance is unknown because we scanned the module before InferTypes and the table
// uses only local information.
assert(syms("i").tpe == ir.UnknownType && syms("i").kind == firrtl.InstanceKind)
assert(syms("r").tpe == ir.SIntType(ir.IntWidth(4)) && syms("r").kind == firrtl.RegKind)
val mType = firrtl.passes.MemPortUtils.memType(
// only dataType, depth and reader, writer, readwriter properties affect the data type
ir.DefMemory(
ir.NoInfo,
"???",
ir.UIntType(ir.IntWidth(8)),
32,
10,
10,
Seq("r"),
Seq(),
Seq(),
ir.ReadUnderWrite.New
)
)
assert(syms("m").tpe == mType && syms("m").kind == firrtl.MemKind)
}
it should "find all declarations in module m after InferTypes" in {
val c = firrtl.Parser.parse(src)
val inferTypesCompiler = new firrtl.stage.TransformManager(Seq(Dependency(firrtl.passes.InferTypes)))
val inferredC = inferTypesCompiler.execute(firrtl.CircuitState(c, Seq())).circuit
val m = inferredC.modules.find(_.name == "m").get
val syms = SymbolTable.scanModule(m, new LocalSymbolTable with WithMap)
// The node type is now known
assert(syms("a").tpe == ir.UIntType(ir.IntWidth(2)) && syms("a").kind == firrtl.NodeKind)
// The type of the instance is now known because it has been filled in by InferTypes.
val iType = ir.BundleType(Seq(ir.Field("x", ir.Flip, ir.UIntType(ir.IntWidth(2)))))
assert(syms("i").tpe == iType && syms("i").kind == firrtl.InstanceKind)
}
behavior.of("WithSeq")
it should "preserve declaration order" in {
val c = firrtl.Parser.parse(src)
val m = c.modules.find(_.name == "m").get
val syms = SymbolTable.scanModule(m, new LocalSymbolTable with WithSeq)
assert(syms.getSymbols.map(_.name) == Seq("clk", "x", "y", "z", "a", "i", "r", "m"))
}
behavior.of("ModuleTypesSymbolTable")
it should "derive the module type from the module types map" in {
val c = firrtl.Parser.parse(src)
val m = c.modules.find(_.name == "m").get
val childType = ir.BundleType(Seq(ir.Field("x", ir.Flip, ir.UIntType(ir.IntWidth(2)))))
val moduleTypes = Map("child" -> childType)
val syms = SymbolTable.scanModule(m, new ModuleTypesSymbolTable(moduleTypes) with WithMap)
assert(syms.size == 8)
assert(syms("i").tpe == childType && syms("i").kind == firrtl.InstanceKind)
}
}
|