aboutsummaryrefslogtreecommitdiff
path: root/src/test/scala/firrtl/testutils
diff options
context:
space:
mode:
authorchick2020-08-14 19:47:53 -0700
committerJack Koenig2020-08-14 19:47:53 -0700
commit6fc742bfaf5ee508a34189400a1a7dbffe3f1cac (patch)
tree2ed103ee80b0fba613c88a66af854ae9952610ce /src/test/scala/firrtl/testutils
parentb516293f703c4de86397862fee1897aded2ae140 (diff)
All of src/ formatted with scalafmt
Diffstat (limited to 'src/test/scala/firrtl/testutils')
-rw-r--r--src/test/scala/firrtl/testutils/FirrtlSpec.scala145
-rw-r--r--src/test/scala/firrtl/testutils/LeanTransformSpec.scala19
-rw-r--r--src/test/scala/firrtl/testutils/PassTests.scala108
3 files changed, 151 insertions, 121 deletions
diff --git a/src/test/scala/firrtl/testutils/FirrtlSpec.scala b/src/test/scala/firrtl/testutils/FirrtlSpec.scala
index dfc20352..a0c41085 100644
--- a/src/test/scala/firrtl/testutils/FirrtlSpec.scala
+++ b/src/test/scala/firrtl/testutils/FirrtlSpec.scala
@@ -46,11 +46,13 @@ object RenameTop extends Transform {
val c = state.circuit
val ns = Namespace(c)
- val newTopName = state.annotations.collectFirst({
- case RenameTopAnnotation(name) =>
- require(ns.tryName(name))
- name
- }).getOrElse(c.main)
+ val newTopName = state.annotations
+ .collectFirst({
+ case RenameTopAnnotation(name) =>
+ require(ns.tryName(name))
+ name
+ })
+ .getOrElse(c.main)
state.annotations.collect {
case ModuleNamespaceAnnotation(mustNotCollideNS) => require(mustNotCollideNS.tryName(newTopName))
@@ -70,6 +72,7 @@ object RenameTop extends Transform {
trait FirrtlRunners extends BackendCompilationUtilities {
val cppHarnessResourceName: String = "/firrtl/testTop.cpp"
+
/** Extra transforms to run by default */
val extraCheckTransforms = Seq(new CheckLowForm)
@@ -80,10 +83,12 @@ trait FirrtlRunners extends BackendCompilationUtilities {
* @param customAnnotations Optional Firrtl annotations
* @param timesteps the maximum number of timesteps to consider
*/
- def firrtlEquivalenceTest(input: String,
- customTransforms: Seq[Transform] = Seq.empty,
- customAnnotations: AnnotationSeq = Seq.empty,
- timesteps: Int = 1): Unit = {
+ def firrtlEquivalenceTest(
+ input: String,
+ customTransforms: Seq[Transform] = Seq.empty,
+ customAnnotations: AnnotationSeq = Seq.empty,
+ timesteps: Int = 1
+ ): Unit = {
val circuit = Parser.parse(input.split("\n").toIterator)
val prefix = circuit.main
val testDir = createTestDirectory(prefix + "_equivalence_test")
@@ -93,12 +98,12 @@ trait FirrtlRunners extends BackendCompilationUtilities {
def getBaseAnnos(topName: String) = {
val baseTransforms = RenameTop +: extraCheckTransforms
TargetDirAnnotation(testDir.toString) +:
- InfoModeAnnotation("ignore") +:
- RenameTopAnnotation(topName) +:
- stage.FirrtlCircuitAnnotation(circuit) +:
- stage.CompilerAnnotation("mverilog") +:
- stage.OutputFileAnnotation(topName) +:
- toAnnos(baseTransforms)
+ InfoModeAnnotation("ignore") +:
+ RenameTopAnnotation(topName) +:
+ stage.FirrtlCircuitAnnotation(circuit) +:
+ stage.CompilerAnnotation("mverilog") +:
+ stage.OutputFileAnnotation(topName) +:
+ toAnnos(baseTransforms)
}
val customName = s"${prefix}_custom"
@@ -111,7 +116,8 @@ trait FirrtlRunners extends BackendCompilationUtilities {
val refAnnos = getBaseAnnos(refSuggestedName) ++: Seq(RunFirrtlTransformAnnotation(new RenameModules), nsAnno)
val refResult = (new firrtl.stage.FirrtlStage).execute(Array.empty, refAnnos)
- val refName = refResult.collectFirst({ case stage.FirrtlCircuitAnnotation(c) => c.main }).getOrElse(refSuggestedName)
+ val refName =
+ refResult.collectFirst({ case stage.FirrtlCircuitAnnotation(c) => c.main }).getOrElse(refSuggestedName)
assert(BackendCompilationUtilities.yosysExpectSuccess(customName, refName, testDir, timesteps))
}
@@ -123,6 +129,7 @@ trait FirrtlRunners extends BackendCompilationUtilities {
val res = compiler.compileAndEmit(CircuitState(circuit, HighForm, annotations), extraCheckTransforms)
res.getEmittedCircuit.value
}
+
/** Compile a Firrtl file
*
* @param prefix is the name of the Firrtl file without path or file extension
@@ -130,25 +137,27 @@ trait FirrtlRunners extends BackendCompilationUtilities {
* @param annotations Optional Firrtl annotations
*/
def compileFirrtlTest(
- prefix: String,
- srcDir: String,
- customTransforms: Seq[Transform] = Seq.empty,
- annotations: AnnotationSeq = Seq.empty): File = {
+ prefix: String,
+ srcDir: String,
+ customTransforms: Seq[Transform] = Seq.empty,
+ annotations: AnnotationSeq = Seq.empty
+ ): File = {
val testDir = createTestDirectory(prefix)
val inputFile = new File(testDir, s"${prefix}.fir")
copyResourceToFile(s"${srcDir}/${prefix}.fir", inputFile)
val annos =
FirrtlFileAnnotation(inputFile.toString) +:
- TargetDirAnnotation(testDir.toString) +:
- InfoModeAnnotation("ignore") +:
- annotations ++:
- (customTransforms ++ extraCheckTransforms).map(RunFirrtlTransformAnnotation(_))
+ TargetDirAnnotation(testDir.toString) +:
+ InfoModeAnnotation("ignore") +:
+ annotations ++:
+ (customTransforms ++ extraCheckTransforms).map(RunFirrtlTransformAnnotation(_))
(new firrtl.stage.FirrtlStage).execute(Array.empty, annos)
testDir
}
+
/** Execute a Firrtl Test
*
* @param prefix is the name of the Firrtl file without path or file extension
@@ -157,25 +166,26 @@ trait FirrtlRunners extends BackendCompilationUtilities {
* @param annotations Optional Firrtl annotations
*/
def runFirrtlTest(
- prefix: String,
- srcDir: String,
- verilogPrefixes: Seq[String] = Seq.empty,
- customTransforms: Seq[Transform] = Seq.empty,
- annotations: AnnotationSeq = Seq.empty) = {
+ prefix: String,
+ srcDir: String,
+ verilogPrefixes: Seq[String] = Seq.empty,
+ customTransforms: Seq[Transform] = Seq.empty,
+ annotations: AnnotationSeq = Seq.empty
+ ) = {
val testDir = compileFirrtlTest(prefix, srcDir, customTransforms, annotations)
val harness = new File(testDir, s"top.cpp")
copyResourceToFile(cppHarnessResourceName, harness)
// Note file copying side effect
- val verilogFiles = verilogPrefixes map { vprefix =>
+ 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) !
- loggingProcessLogger
+ cppToExe(prefix, testDir) !
+ loggingProcessLogger
assert(executeExpectingSuccess(prefix, testDir))
}
}
@@ -201,6 +211,7 @@ trait FirrtlMatchers extends Matchers {
require(!s.contains("\n"))
s.replaceAll("\\s+", " ").trim
}
+
/** Helper to make circuits that are the same appear the same */
def canonicalize(circuit: Circuit): Circuit = {
import firrtl.Mappers._
@@ -208,19 +219,21 @@ trait FirrtlMatchers extends Matchers {
circuit.map(onModule)
}
def parse(str: String) = Parser.parse(str.split("\n").toIterator, UseInfo)
+
/** Helper for executing tests
* compiler will be run on input then emitted result will each be split into
* lines and normalized.
*/
def executeTest(
- input: String,
- expected: Seq[String],
- compiler: Compiler,
- annotations: Seq[Annotation] = Seq.empty) = {
+ input: String,
+ expected: Seq[String],
+ compiler: Compiler,
+ annotations: Seq[Annotation] = Seq.empty
+ ) = {
val finalState = compiler.compileAndEmit(CircuitState(parse(input), ChirrtlForm, annotations))
- val lines = finalState.getEmittedCircuit.value split "\n" map normalized
+ val lines = finalState.getEmittedCircuit.value.split("\n").map(normalized)
for (e <- expected) {
- lines should contain (e)
+ lines should contain(e)
}
}
}
@@ -239,10 +252,12 @@ object FirrtlCheckers extends FirrtlMatchers {
case Some(res) => res
// Otherwise keep digging
case None =>
- require(node.isInstanceOf[Product] || !node.isInstanceOf[FirrtlNode],
- "Error! Unexpected FirrtlNode that does not implement Product!")
+ require(
+ node.isInstanceOf[Product] || !node.isInstanceOf[FirrtlNode],
+ "Error! Unexpected FirrtlNode that does not implement Product!"
+ )
val iter = node match {
- case p: Product => p.productIterator
+ case p: Product => p.productIterator
case i: Iterable[Any] => i.iterator
case _ => Iterator.empty
}
@@ -296,57 +311,63 @@ class TestFirrtlFlatSpec extends FirrtlFlatSpec {
import FirrtlCheckers._
val c = parse("""
- |circuit Test:
- | module Test :
- | input in : UInt<8>
- | output out : UInt<8>
- | out <= in
- |""".stripMargin)
+ |circuit Test:
+ | module Test :
+ | input in : UInt<8>
+ | output out : UInt<8>
+ | out <= in
+ |""".stripMargin)
val state = CircuitState(c, ChirrtlForm)
val compiled = (new LowFirrtlCompiler).compileAndEmit(state, List.empty)
// While useful, ScalaTest helpers should be used over search
- behavior of "Search"
+ behavior.of("Search")
it should "be supported on Circuit" in {
- assert(c search {
- case Connect(_, Reference("out",_, _, _), Reference("in", _, _, _)) => true
+ assert(c.search {
+ case Connect(_, Reference("out", _, _, _), Reference("in", _, _, _)) => true
})
}
it should "be supported on CircuitStates" in {
- assert(state search {
- case Connect(_, Reference("out", _, _, _), Reference("in",_, _, _)) => true
+ assert(state.search {
+ case Connect(_, Reference("out", _, _, _), Reference("in", _, _, _)) => true
})
}
it should "be supported on the results of compilers" in {
- assert(compiled search {
- case Connect(_, WRef("out",_,_,_), WRef("in",_,_,_)) => true
+ assert(compiled.search {
+ case Connect(_, WRef("out", _, _, _), WRef("in", _, _, _)) => true
})
}
// Use these!!!
- behavior of "ScalaTest helpers"
+ behavior.of("ScalaTest helpers")
they should "work for lines of emitted text" in {
- compiled should containLine (s"input in : UInt<8>")
- compiled should containLine (s"output out : UInt<8>")
- compiled should containLine (s"out <= in")
+ compiled should containLine(s"input in : UInt<8>")
+ compiled should containLine(s"output out : UInt<8>")
+ compiled should containLine(s"out <= in")
}
they should "work for partial functions matching on subtrees" in {
val UInt8 = UIntType(IntWidth(8)) // BigInt unapply is weird
compiled should containTree { case Port(_, "in", Input, UInt8) => true }
compiled should containTree { case Port(_, "out", Output, UInt8) => true }
- compiled should containTree { case Connect(_, WRef("out",_,_,_), WRef("in",_,_,_)) => true }
+ compiled should containTree { case Connect(_, WRef("out", _, _, _), WRef("in", _, _, _)) => true }
}
}
/** Super class for execution driven Firrtl tests */
-abstract class ExecutionTest(name: String, dir: String, vFiles: Seq[String] = Seq.empty, annotations: AnnotationSeq = Seq.empty) extends FirrtlPropSpec {
+abstract class ExecutionTest(
+ name: String,
+ dir: String,
+ vFiles: Seq[String] = Seq.empty,
+ annotations: AnnotationSeq = Seq.empty)
+ extends FirrtlPropSpec {
property(s"$name should execute correctly") {
runFirrtlTest(name, dir, vFiles, annotations = annotations)
}
}
+
/** Super class for compilation driven Firrtl tests */
abstract class CompilationTest(name: String, dir: String) extends FirrtlPropSpec {
property(s"$name should compile correctly") {
@@ -444,7 +465,9 @@ abstract class EquivalenceTest(transforms: Seq[Transform], name: String, dir: St
throw new FileNotFoundException(s"Resource '$fileName'")
}
val source = scala.io.Source.fromInputStream(in)
- val input = try source.mkString finally source.close()
+ val input =
+ try source.mkString
+ finally source.close()
s"$name with ${transforms.map(_.name).mkString(", ")}" should
s"be equivalent to $name without ${transforms.map(_.name).mkString(", ")}" in {
diff --git a/src/test/scala/firrtl/testutils/LeanTransformSpec.scala b/src/test/scala/firrtl/testutils/LeanTransformSpec.scala
index c1f0943a..4ae6a7be 100644
--- a/src/test/scala/firrtl/testutils/LeanTransformSpec.scala
+++ b/src/test/scala/firrtl/testutils/LeanTransformSpec.scala
@@ -1,6 +1,6 @@
package firrtl.testutils
-import firrtl.{AnnotationSeq, CircuitState, EmitCircuitAnnotation, ir}
+import firrtl.{ir, AnnotationSeq, CircuitState, EmitCircuitAnnotation}
import firrtl.options.Dependency
import firrtl.passes.RemoveEmpty
import firrtl.stage.TransformManager.TransformDependency
@@ -11,30 +11,33 @@ class VerilogTransformSpec extends LeanTransformSpec(Seq(Dependency[firrtl.Veril
class LowFirrtlTransformSpec extends LeanTransformSpec(Seq(Dependency[firrtl.LowFirrtlEmitter]))
/** The new cool kid on the block, creates a custom compiler for your transform. */
-class LeanTransformSpec(protected val transforms: Seq[TransformDependency]) extends AnyFlatSpec with FirrtlMatchers with LazyLogging {
+class LeanTransformSpec(protected val transforms: Seq[TransformDependency])
+ extends AnyFlatSpec
+ with FirrtlMatchers
+ with LazyLogging {
private val compiler = new firrtl.stage.transforms.Compiler(transforms)
private val emitterAnnos = LeanTransformSpec.deriveEmitCircuitAnnotations(transforms)
protected def compile(src: String): CircuitState = compile(src, Seq())
protected def compile(src: String, annos: AnnotationSeq): CircuitState = compile(firrtl.Parser.parse(src), annos)
- protected def compile(c: ir.Circuit): CircuitState = compile(c, Seq())
- protected def compile(c: ir.Circuit, annos: AnnotationSeq): CircuitState =
+ protected def compile(c: ir.Circuit): CircuitState = compile(c, Seq())
+ protected def compile(c: ir.Circuit, annos: AnnotationSeq): CircuitState =
compiler.transform(CircuitState(c, emitterAnnos ++ annos))
- protected def execute(input: String, check: String): CircuitState = execute(input, check ,Seq())
+ protected def execute(input: String, check: String): CircuitState = execute(input, check, Seq())
protected def execute(input: String, check: String, inAnnos: AnnotationSeq): CircuitState = {
val finalState = compiler.transform(CircuitState(parse(input), inAnnos))
val actual = RemoveEmpty.run(parse(finalState.getEmittedCircuit.value)).serialize
val expected = parse(check).serialize
logger.debug(actual)
logger.debug(expected)
- actual should be (expected)
+ actual should be(expected)
finalState
}
}
private object LeanTransformSpec {
private def deriveEmitCircuitAnnotations(transforms: Iterable[TransformDependency]): AnnotationSeq = {
- val emitters = transforms.map(_.getObject()).collect{ case e: firrtl.Emitter => e }
+ val emitters = transforms.map(_.getObject()).collect { case e: firrtl.Emitter => e }
emitters.map(e => EmitCircuitAnnotation(e.getClass)).toSeq
}
}
@@ -47,4 +50,4 @@ trait MakeCompiler {
new firrtl.stage.transforms.Compiler(Seq(Dependency[firrtl.MinimumVerilogEmitter]) ++ transforms)
protected def makeLowFirrtlCompiler(transforms: Seq[TransformDependency] = Seq()) =
new firrtl.stage.transforms.Compiler(Seq(Dependency[firrtl.LowFirrtlEmitter]) ++ transforms)
-} \ No newline at end of file
+}
diff --git a/src/test/scala/firrtl/testutils/PassTests.scala b/src/test/scala/firrtl/testutils/PassTests.scala
index 49dea199..7a5dc306 100644
--- a/src/test/scala/firrtl/testutils/PassTests.scala
+++ b/src/test/scala/firrtl/testutils/PassTests.scala
@@ -15,49 +15,53 @@ import org.scalatest.flatspec.AnyFlatSpec
// An example methodology for testing Firrtl Passes
// Spec class should extend this class
abstract class SimpleTransformSpec extends AnyFlatSpec with FirrtlMatchers with Compiler with LazyLogging {
- // Utility function
- def squash(c: Circuit): Circuit = RemoveEmpty.run(c)
-
- // Executes the test. Call in tests.
- // annotations cannot have default value because scalatest trait Suite has a default value
- def execute(input: String, check: String, annotations: Seq[Annotation]): CircuitState = {
- val finalState = compileAndEmit(CircuitState(parse(input), ChirrtlForm, annotations))
- val actual = RemoveEmpty.run(parse(finalState.getEmittedCircuit.value)).serialize
- val expected = parse(check).serialize
- logger.debug(actual)
- logger.debug(expected)
- (actual) should be (expected)
- finalState
- }
-
- def executeWithAnnos(input: String, check: String, annotations: Seq[Annotation],
- checkAnnotations: Seq[Annotation]): CircuitState = {
- val finalState = compileAndEmit(CircuitState(parse(input), ChirrtlForm, annotations))
- val actual = RemoveEmpty.run(parse(finalState.getEmittedCircuit.value)).serialize
- val expected = parse(check).serialize
- logger.debug(actual)
- logger.debug(expected)
- (actual) should be (expected)
-
- annotations.foreach { anno =>
- logger.debug(anno.serialize)
- }
-
- finalState.annotations.toSeq.foreach { anno =>
- logger.debug(anno.serialize)
- }
- checkAnnotations.foreach { check =>
- (finalState.annotations.toSeq) should contain (check)
- }
- finalState
- }
- // Executes the test, should throw an error
- // No default to be consistent with execute
- def failingexecute(input: String, annotations: Seq[Annotation]): Exception = {
- intercept[PassExceptions] {
- compile(CircuitState(parse(input), ChirrtlForm, annotations), Seq.empty)
- }
- }
+ // Utility function
+ def squash(c: Circuit): Circuit = RemoveEmpty.run(c)
+
+ // Executes the test. Call in tests.
+ // annotations cannot have default value because scalatest trait Suite has a default value
+ def execute(input: String, check: String, annotations: Seq[Annotation]): CircuitState = {
+ val finalState = compileAndEmit(CircuitState(parse(input), ChirrtlForm, annotations))
+ val actual = RemoveEmpty.run(parse(finalState.getEmittedCircuit.value)).serialize
+ val expected = parse(check).serialize
+ logger.debug(actual)
+ logger.debug(expected)
+ (actual) should be(expected)
+ finalState
+ }
+
+ def executeWithAnnos(
+ input: String,
+ check: String,
+ annotations: Seq[Annotation],
+ checkAnnotations: Seq[Annotation]
+ ): CircuitState = {
+ val finalState = compileAndEmit(CircuitState(parse(input), ChirrtlForm, annotations))
+ val actual = RemoveEmpty.run(parse(finalState.getEmittedCircuit.value)).serialize
+ val expected = parse(check).serialize
+ logger.debug(actual)
+ logger.debug(expected)
+ (actual) should be(expected)
+
+ annotations.foreach { anno =>
+ logger.debug(anno.serialize)
+ }
+
+ finalState.annotations.toSeq.foreach { anno =>
+ logger.debug(anno.serialize)
+ }
+ checkAnnotations.foreach { check =>
+ (finalState.annotations.toSeq) should contain(check)
+ }
+ finalState
+ }
+ // Executes the test, should throw an error
+ // No default to be consistent with execute
+ def failingexecute(input: String, annotations: Seq[Annotation]): Exception = {
+ intercept[PassExceptions] {
+ compile(CircuitState(parse(input), ChirrtlForm, annotations), Seq.empty)
+ }
+ }
}
@deprecated(
@@ -86,19 +90,19 @@ object ReRunResolveAndCheck extends Transform with DependencyAPIMigration with I
}
trait LowTransformSpec extends SimpleTransformSpec {
- def emitter = new LowFirrtlEmitter
- def transform: Transform
- def transforms: Seq[Transform] = transform +: ReRunResolveAndCheck +: Forms.LowForm.map(_.getObject)
+ def emitter = new LowFirrtlEmitter
+ def transform: Transform
+ def transforms: Seq[Transform] = transform +: ReRunResolveAndCheck +: Forms.LowForm.map(_.getObject)
}
trait MiddleTransformSpec extends SimpleTransformSpec {
- def emitter = new MiddleFirrtlEmitter
- def transform: Transform
- def transforms: Seq[Transform] = transform +: ReRunResolveAndCheck +: Forms.MidForm.map(_.getObject)
+ def emitter = new MiddleFirrtlEmitter
+ def transform: Transform
+ def transforms: Seq[Transform] = transform +: ReRunResolveAndCheck +: Forms.MidForm.map(_.getObject)
}
trait HighTransformSpec extends SimpleTransformSpec {
- def emitter = new HighFirrtlEmitter
- def transform: Transform
- def transforms = transform +: ReRunResolveAndCheck +: Forms.HighForm.map(_.getObject)
+ def emitter = new HighFirrtlEmitter
+ def transform: Transform
+ def transforms = transform +: ReRunResolveAndCheck +: Forms.HighForm.map(_.getObject)
}