aboutsummaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/scala/firrtl/testutils/FirrtlSpec.scala101
1 files changed, 62 insertions, 39 deletions
diff --git a/src/test/scala/firrtl/testutils/FirrtlSpec.scala b/src/test/scala/firrtl/testutils/FirrtlSpec.scala
index 4cc9382f..1dc56b15 100644
--- a/src/test/scala/firrtl/testutils/FirrtlSpec.scala
+++ b/src/test/scala/firrtl/testutils/FirrtlSpec.scala
@@ -5,7 +5,7 @@ package firrtl.testutils
import java.io._
import java.security.Permission
-import logger.LazyLogging
+import logger.{LazyLogging, LogLevel, LogLevelAnnotation}
import org.scalatest._
import org.scalatestplus.scalacheck._
@@ -13,6 +13,7 @@ import org.scalatestplus.scalacheck._
import firrtl._
import firrtl.ir._
import firrtl.Parser.UseInfo
+import firrtl.options.{Dependency, PreservesAll}
import firrtl.stage.{FirrtlFileAnnotation, InfoModeAnnotation, RunFirrtlTransformAnnotation}
import firrtl.analyses.{GetNamespace, ModuleNamespaceAnnotation}
import firrtl.annotations._
@@ -30,30 +31,46 @@ class CheckLowForm extends SeqTransform {
)
}
-trait FirrtlRunners extends BackendCompilationUtilities {
+case class RenameTopAnnotation(newTopName: String) extends NoTargetAnnotation
- val cppHarnessResourceName: String = "/firrtl/testTop.cpp"
- /** Extra transforms to run by default */
- val extraCheckTransforms = Seq(new CheckLowForm)
+object RenameTop extends Transform with PreservesAll[Transform] {
+ def inputForm = UnknownForm
+ def outputForm = UnknownForm
- private class RenameTop(newTopPrefix: String) extends Transform {
- def inputForm: LowForm.type = LowForm
- def outputForm: LowForm.type = LowForm
+ override val optionalPrerequisites = Seq(Dependency[RenameModules])
- def execute(state: CircuitState): CircuitState = {
- val namespace = state.annotations.collectFirst {
- case m: ModuleNamespaceAnnotation => m
- }.get.namespace
+ override val dependents = Seq(Dependency[VerilogEmitter], Dependency[MinimumVerilogEmitter])
- val newTopName = namespace.newName(newTopPrefix)
- val modulesx = state.circuit.modules.map {
- case mod: Module if mod.name == state.circuit.main => mod.mapString(_ => newTopName)
- case other => other
- }
+ def execute(state: CircuitState): CircuitState = {
+ val c = state.circuit
+ val ns = Namespace(c)
+
+ val newTopName = state.annotations.collectFirst({
+ case RenameTopAnnotation(name) =>
+ require(ns.tryName(name))
+ name
+ }).getOrElse(c.main)
- state.copy(circuit = state.circuit.copy(main = newTopName, modules = modulesx))
+ state.annotations.collect {
+ case ModuleNamespaceAnnotation(mustNotCollideNS) => require(mustNotCollideNS.tryName(newTopName))
}
+
+ val modulesx = c.modules.map {
+ case m: Module if (m.name == c.main) => m.copy(name = newTopName)
+ case m => m
+ }
+
+ val renames = RenameMap()
+ renames.record(CircuitTarget(c.main), CircuitTarget(newTopName))
+ state.copy(circuit = c.copy(main = newTopName, modules = modulesx), renames = Some(renames))
}
+}
+
+trait FirrtlRunners extends BackendCompilationUtilities {
+
+ val cppHarnessResourceName: String = "/firrtl/testTop.cpp"
+ /** Extra transforms to run by default */
+ val extraCheckTransforms = Seq(new CheckLowForm)
/** Check equivalence of Firrtl transforms using yosys
*
@@ -67,29 +84,35 @@ trait FirrtlRunners extends BackendCompilationUtilities {
customAnnotations: AnnotationSeq = Seq.empty,
resets: Seq[(Int, String, Int)] = Seq.empty): Unit = {
val circuit = Parser.parse(input.split("\n").toIterator)
- val compiler = new MinimumVerilogCompiler
val prefix = circuit.main
val testDir = createTestDirectory(prefix + "_equivalence_test")
- val firrtlWriter = new PrintWriter(s"${testDir.getAbsolutePath}/$prefix.fir")
- firrtlWriter.write(input)
- firrtlWriter.close()
-
- val customVerilog = compiler.compileAndEmit(CircuitState(circuit, HighForm, customAnnotations),
- new GetNamespace +: new RenameTop(s"${prefix}_custom") +: customTransforms)
- val namespaceAnnotation = customVerilog.annotations.collectFirst { case m: ModuleNamespaceAnnotation => m }.get
- val customTop = customVerilog.circuit.main
- val customFile = new PrintWriter(s"${testDir.getAbsolutePath}/$customTop.v")
- customFile.write(customVerilog.getEmittedCircuit.value)
- customFile.close()
-
- val referenceVerilog = compiler.compileAndEmit(CircuitState(circuit, HighForm, Seq(namespaceAnnotation)),
- Seq(new RenameModules, new RenameTop(s"${prefix}_reference")))
- val referenceTop = referenceVerilog.circuit.main
- val referenceFile = new PrintWriter(s"${testDir.getAbsolutePath}/$referenceTop.v")
- referenceFile.write(referenceVerilog.getEmittedCircuit.value)
- referenceFile.close()
-
- assert(yosysExpectSuccess(customTop, referenceTop, testDir, resets))
+
+ def toAnnos(xforms: Seq[Transform]) = xforms.map(RunFirrtlTransformAnnotation(_))
+
+ 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)
+ }
+
+ val customName = s"${prefix}_custom"
+ val customAnnos = getBaseAnnos(customName) ++: toAnnos((new GetNamespace) +: customTransforms) ++: customAnnotations
+
+ val customResult = (new firrtl.stage.FirrtlStage).run(customAnnos)
+ val nsAnno = customResult.collectFirst { case m: ModuleNamespaceAnnotation => m }.get
+
+ val refSuggestedName = s"${prefix}_ref"
+ val refAnnos = getBaseAnnos(refSuggestedName) ++: Seq(RunFirrtlTransformAnnotation(new RenameModules), nsAnno)
+
+ val refResult = (new firrtl.stage.FirrtlStage).run(refAnnos)
+ val refName = refResult.collectFirst({ case stage.FirrtlCircuitAnnotation(c) => c.main }).getOrElse(refSuggestedName)
+
+ assert(yosysExpectSuccess(customName, refName, testDir, resets))
}
/** Compiles input Firrtl to Verilog */