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
|
package firrtlTests
import java.io.StringWriter
import org.scalatest.FlatSpec
import org.scalatest.Matchers
import org.scalatest.junit.JUnitRunner
import firrtl.ir.Circuit
import firrtl.{
HighFirrtlCompiler,
LowFirrtlCompiler,
VerilogCompiler,
Compiler,
Parser
}
import firrtl.Annotations.AnnotationMap
/**
* An example methodology for testing Firrtl compilers.
*
* Given an input Firrtl circuit (expressed as a string),
* the compiler is executed. The output of the compiler
* should be compared against the check string.
*/
abstract class CompilerSpec extends FlatSpec {
def parse (s: String): Circuit = Parser.parse(s.split("\n").toIterator)
val writer = new StringWriter()
def compiler: Compiler
def input: String
def check: String
def getOutput: String = {
compiler.compile(parse(input), new AnnotationMap(Seq.empty), writer)
writer.toString()
}
}
/**
* An example test for testing the HighFirrtlCompiler.
*
* Given an input Firrtl circuit (expressed as a string),
* the compiler is executed. The output of the compiler
* is parsed again and compared (in-memory) to the parsed
* input.
*/
class HighFirrtlCompilerSpec extends CompilerSpec with Matchers {
val compiler = new HighFirrtlCompiler()
val input =
"""circuit Top :
module Top :
input a : UInt<1>[2]
node x = a
"""
val check = input
"Any circuit" should "match exactly to its input" in {
(parse(getOutput)) should be (parse(check))
}
}
/**
* An example test for testing the LoweringCompiler.
*
* Given an input Firrtl circuit (expressed as a string),
* the compiler is executed. The output of the compiler is
* a lowered version of the input circuit. The output is
* string compared to the correct lowered circuit.
*/
class LowFirrtlCompilerSpec extends CompilerSpec with Matchers {
val compiler = new LowFirrtlCompiler()
val input =
"""
circuit Top :
module Top :
input a : UInt<1>[2]
node x = a
"""
val check = Seq(
"circuit Top :",
" module Top :",
" input a_0 : UInt<1>",
" input a_1 : UInt<1>",
" node x_0 = a_0",
" node x_1 = a_1\n\n"
).reduce(_ + "\n" + _)
"A circuit" should "match exactly to its lowered state" in {
(parse(getOutput)) should be (parse(check))
}
}
/**
* An example test for testing the VerilogCompiler.
*
* Given an input Firrtl circuit (expressed as a string),
* the compiler is executed. The output of the compiler is
* the corresponding Verilog. The output is string compared
* to the correct Verilog.
*/
class VerilogCompilerSpec extends CompilerSpec with Matchers {
val compiler = new VerilogCompiler()
val input =
"""
circuit Top :
module Top :
input a : UInt<1>[2]
output b : UInt<1>[2]
b <= a
"""
val check = Seq(
"`ifdef RANDOMIZE_GARBAGE_ASSIGN",
"`define RANDOMIZE",
"`endif",
"`ifdef RANDOMIZE_INVALID_ASSIGN",
"`define RANDOMIZE",
"`endif",
"`ifdef RANDOMIZE_REG_INIT",
"`define RANDOMIZE",
"`endif",
"`ifdef RANDOMIZE_MEM_INIT",
"`define RANDOMIZE",
"`endif",
"",
"module Top(",
" input a_0,",
" input a_1,",
" output b_0,",
" output b_1",
");",
" assign b_0 = a_0;",
" assign b_1 = a_1;",
"endmodule\n"
).reduce(_ + "\n" + _)
"A circuit's verilog output" should "match the given string" in {
(getOutput) should be (check)
}
}
|