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
|
// See LICENSE for license details.
package firrtlTests
import java.io._
import com.typesafe.scalalogging.LazyLogging
import scala.sys.process._
import org.scalatest._
import org.scalatest.prop._
import scala.io.Source
import firrtl._
import firrtl.Parser.IgnoreInfo
import firrtl.annotations
import firrtl.util.BackendCompilationUtilities
trait FirrtlRunners extends BackendCompilationUtilities {
def parse(str: String) = Parser.parse(str.split("\n").toIterator, IgnoreInfo)
lazy val cppHarness = new File(s"/top.cpp")
/** Compiles input Firrtl to Verilog */
def compileToVerilog(input: String, annotations: AnnotationMap = AnnotationMap(Seq.empty)): String = {
val circuit = Parser.parse(input.split("\n").toIterator)
val compiler = new VerilogCompiler
val writer = new java.io.StringWriter
compiler.compile(CircuitState(circuit, HighForm, Some(annotations)), writer)
writer.toString
}
/** Compile a Firrtl file
*
* @param prefix is the name of the Firrtl file without path or file extension
* @param srcDir directory where all Resources for this test are located
* @param annotations Optional Firrtl annotations
*/
def compileFirrtlTest(
prefix: String,
srcDir: String,
customTransforms: Seq[Transform] = Seq.empty,
annotations: AnnotationMap = new AnnotationMap(Seq.empty)): File = {
val testDir = createTempDirectory(prefix)
copyResourceToFile(s"${srcDir}/${prefix}.fir", new File(testDir, s"${prefix}.fir"))
Driver.compile(
s"$testDir/$prefix.fir",
s"$testDir/$prefix.v",
new VerilogCompiler(),
Parser.IgnoreInfo,
customTransforms,
annotations)
testDir
}
/** Execute a Firrtl Test
*
* @param prefix is the name of the Firrtl file without path or file extension
* @param srcDir directory where all Resources for this test are located
* @param verilogPrefixes names of option Verilog resources without path or file extension
* @param annotations Optional Firrtl annotations
*/
def runFirrtlTest(
prefix: String,
srcDir: String,
verilogPrefixes: Seq[String] = Seq.empty,
customTransforms: Seq[Transform] = Seq.empty,
annotations: AnnotationMap = new AnnotationMap(Seq.empty)) = {
val testDir = compileFirrtlTest(prefix, srcDir, customTransforms, annotations)
val harness = new File(testDir, s"top.cpp")
copyResourceToFile(cppHarness.toString, harness)
// Note file copying side effect
val verilogFiles = verilogPrefixes map { vprefix =>
val file = new File(testDir, s"$vprefix.v")
copyResourceToFile(s"$srcDir/$vprefix.v", file)
file
}
verilogToCpp(prefix, testDir, verilogFiles, harness).!
cppToExe(prefix, testDir).!
assert(executeExpectingSuccess(prefix, testDir))
}
}
trait FirrtlMatchers {
// Replace all whitespace with a single space and remove leading and
// trailing whitespace
// Note this is intended for single-line strings, no newlines
def normalized(s: String): String = {
require(!s.contains("\n"))
s.replaceAll("\\s+", " ").trim
}
}
abstract class FirrtlPropSpec extends PropSpec with PropertyChecks with FirrtlRunners with LazyLogging
abstract class FirrtlFlatSpec extends FlatSpec with Matchers with FirrtlRunners with FirrtlMatchers with LazyLogging
/** Super class for execution driven Firrtl tests */
abstract class ExecutionTest(name: String, dir: String, vFiles: Seq[String] = Seq.empty) extends FirrtlPropSpec {
property(s"$name should execute correctly") {
runFirrtlTest(name, dir, vFiles)
}
}
/** Super class for compilation driven Firrtl tests */
abstract class CompilationTest(name: String, dir: String) extends FirrtlPropSpec {
property(s"$name should compile correctly") {
compileFirrtlTest(name, dir)
}
}
|