aboutsummaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
authorSchuyler Eldridge2020-03-11 14:32:32 -0400
committerGitHub2020-03-11 14:32:32 -0400
commit026c18dd76d4e2121c7f6c582d15e4d5a3ab842b (patch)
tree0537dff3091db3da167c0fffc3388a5966c46204 /src/test
parent646c91e71b8bfb1b0d0f22e81ca113147637ce71 (diff)
parentabf226471249a1cbb8de33d0c4bc8526f9aafa70 (diff)
Merge pull request #1123 from freechipsproject/dependency-api-2
- Use Dependency API for transform scheduling - Add tests that old order/behavior is preserved Or: "Now you're thinking with dependencies."
Diffstat (limited to 'src/test')
-rw-r--r--src/test/scala/firrtlTests/AnnotationTests.scala2
-rw-r--r--src/test/scala/firrtlTests/CInferMDirSpec.scala2
-rw-r--r--src/test/scala/firrtlTests/CustomTransformSpec.scala153
-rw-r--r--src/test/scala/firrtlTests/LoweringCompilersSpec.scala349
-rw-r--r--src/test/scala/firrtlTests/VerilogEmitterTests.scala22
-rw-r--r--src/test/scala/firrtlTests/annotationTests/TargetDirAnnotationSpec.scala42
-rw-r--r--src/test/scala/firrtlTests/stage/phases/CompilerSpec.scala41
-rw-r--r--src/test/scala/firrtlTests/transforms/BlackBoxSourceHelperSpec.scala5
8 files changed, 544 insertions, 72 deletions
diff --git a/src/test/scala/firrtlTests/AnnotationTests.scala b/src/test/scala/firrtlTests/AnnotationTests.scala
index 03e3198e..a1c6580d 100644
--- a/src/test/scala/firrtlTests/AnnotationTests.scala
+++ b/src/test/scala/firrtlTests/AnnotationTests.scala
@@ -627,7 +627,7 @@ class JsonAnnotationTests extends AnnotationTests with BackendCompilationUtiliti
override def inputForm: CircuitForm = UnknownForm
override def outputForm: CircuitForm = UnknownForm
- protected def execute(state: CircuitState): CircuitState = state
+ def execute(state: CircuitState): CircuitState = state
}
"annotation order" should "should be preserved" in {
diff --git a/src/test/scala/firrtlTests/CInferMDirSpec.scala b/src/test/scala/firrtlTests/CInferMDirSpec.scala
index e03d1ab9..715e0cda 100644
--- a/src/test/scala/firrtlTests/CInferMDirSpec.scala
+++ b/src/test/scala/firrtlTests/CInferMDirSpec.scala
@@ -7,7 +7,7 @@ import firrtl.ir._
import firrtl.passes._
import firrtl.transforms._
-class CInferMDir extends LowTransformSpec {
+class CInferMDirSpec extends LowTransformSpec {
object CInferMDirCheckPass extends Pass {
// finds the memory and check its read port
def checkStmt(s: Statement): Boolean = s match {
diff --git a/src/test/scala/firrtlTests/CustomTransformSpec.scala b/src/test/scala/firrtlTests/CustomTransformSpec.scala
index 04cbf276..809f2b1e 100644
--- a/src/test/scala/firrtlTests/CustomTransformSpec.scala
+++ b/src/test/scala/firrtlTests/CustomTransformSpec.scala
@@ -6,12 +6,15 @@ import firrtl.ir.Circuit
import firrtl._
import firrtl.passes.Pass
import firrtl.ir._
-import firrtl.stage.{FirrtlSourceAnnotation, FirrtlStage, RunFirrtlTransformAnnotation}
+import firrtl.stage.{FirrtlSourceAnnotation, FirrtlStage, Forms, RunFirrtlTransformAnnotation}
+import firrtl.options.Dependency
+import firrtl.transforms.IdentityTransform
-class CustomTransformSpec extends FirrtlFlatSpec {
- behavior of "Custom Transforms"
+import scala.reflect.runtime
- they should "be able to introduce high firrtl" in {
+object CustomTransformSpec {
+
+ class ReplaceExtModuleTransform extends SeqTransform with FirrtlMatchers {
// Simple module
val delayModuleString = """
|circuit Delay :
@@ -31,38 +34,99 @@ class CustomTransformSpec extends FirrtlFlatSpec {
val delayModuleCircuit = parse(delayModuleString)
val delayModule = delayModuleCircuit.modules.find(_.name == delayModuleCircuit.main).get
- class ReplaceExtModuleTransform extends SeqTransform {
- class ReplaceExtModule extends Pass {
- def run(c: Circuit): Circuit = c.copy(
- modules = c.modules map {
- case ExtModule(_, "Delay", _, _, _) => delayModule
- case other => other
- }
- )
- }
- def transforms = Seq(new ReplaceExtModule)
- def inputForm = LowForm
- def outputForm = HighForm
+ class ReplaceExtModule extends Pass {
+ def run(c: Circuit): Circuit = c.copy(
+ modules = c.modules map {
+ case ExtModule(_, "Delay", _, _, _) => delayModule
+ case other => other
+ }
+ )
}
-
- runFirrtlTest("CustomTransform", "/features", customTransforms = List(new ReplaceExtModuleTransform))
+ def transforms = Seq(new ReplaceExtModule)
+ def inputForm = LowForm
+ def outputForm = HighForm
}
- they should "not cause \"Internal Errors\"" in {
- val input = """
+ val input = """
|circuit test :
| module test :
| output out : UInt
| out <= UInt(123)""".stripMargin
- val errorString = "My Custom Transform failed!"
- class ErroringTransform extends Transform {
+ val errorString = "My Custom Transform failed!"
+ class ErroringTransform extends Transform {
+ def inputForm = HighForm
+ def outputForm = HighForm
+ def execute(state: CircuitState): CircuitState = {
+ require(false, errorString)
+ state
+ }
+ }
+
+ object MutableState {
+ var count: Int = 0
+ }
+
+ class FirstTransform extends Transform {
+ def inputForm = HighForm
+ def outputForm = HighForm
+
+ def execute(state: CircuitState): CircuitState = {
+ require(MutableState.count == 0, s"Count was ${MutableState.count}, expected 0")
+ MutableState.count = 1
+ state
+ }
+ }
+
+ class SecondTransform extends Transform {
+ def inputForm = HighForm
+ def outputForm = HighForm
+
+ def execute(state: CircuitState): CircuitState = {
+ require(MutableState.count == 1, s"Count was ${MutableState.count}, expected 1")
+ MutableState.count = 2
+ state
+ }
+ }
+
+ class ThirdTransform extends Transform {
+ def inputForm = HighForm
+ def outputForm = HighForm
+
+ def execute(state: CircuitState): CircuitState = {
+ require(MutableState.count == 2, s"Count was ${MutableState.count}, expected 2")
+ MutableState.count = 3
+ state
+ }
+ }
+
+ class IdentityLowForm extends IdentityTransform(LowForm) {
+ override val name = ">>>>> IdentityLowForm <<<<<"
+ }
+
+ object Foo {
+ class A extends Transform {
def inputForm = HighForm
def outputForm = HighForm
- def execute(state: CircuitState): CircuitState = {
- require(false, errorString)
- state
+ def execute(s: CircuitState) = {
+ assert(name.endsWith("A"))
+ s
}
}
+ }
+
+}
+
+class CustomTransformSpec extends FirrtlFlatSpec {
+
+ import CustomTransformSpec._
+
+ behavior of "Custom Transforms"
+
+ they should "be able to introduce high firrtl" in {
+ runFirrtlTest("CustomTransform", "/features", customTransforms = List(new ReplaceExtModuleTransform))
+ }
+
+ they should "not cause \"Internal Errors\"" in {
val optionsManager = new ExecutionOptionsManager("test") with HasFirrtlOptions {
firrtlOptions = FirrtlExecutionOptions(
firrtlSource = Some(input),
@@ -73,15 +137,38 @@ class CustomTransformSpec extends FirrtlFlatSpec {
}).getMessage should include (errorString)
}
- object Foo {
- class A extends Transform {
- def inputForm = HighForm
- def outputForm = HighForm
- def execute(s: CircuitState) = {
- assert(name.endsWith("A"))
- s
- }
+ they should "preserve the input order" in {
+ runFirrtlTest("CustomTransform", "/features", customTransforms = List(
+ new FirstTransform,
+ new SecondTransform,
+ new ThirdTransform,
+ new ReplaceExtModuleTransform
+ ))
+ }
+
+ they should "run right before the emitter when inputForm=LowForm" in {
+
+ val custom = Dependency[IdentityLowForm]
+
+ def testOrder(emitter: Dependency[Emitter], preceders: Seq[Dependency[Transform]]): Unit = {
+ info(s"""${preceders.map(_.getSimpleName).mkString(" -> ")} -> ${custom.getSimpleName} -> ${emitter.getSimpleName} ok!""")
+
+ val compiler = new firrtl.stage.transforms.Compiler(Seq(custom, emitter))
+ info("Transform Order: \n" + compiler.prettyPrint(" "))
+
+ val expectedSlice = preceders ++ Seq(custom, emitter)
+
+ compiler
+ .flattenedTransformOrder
+ .map(Dependency.fromTransform(_))
+ .containsSlice(expectedSlice) should be (true)
}
+
+ Seq( (Dependency[LowFirrtlEmitter], Seq(Forms.LowForm.last) ),
+ (Dependency[MinimumVerilogEmitter], Seq(Forms.LowFormMinimumOptimized.last) ),
+ (Dependency[VerilogEmitter], Seq(Forms.LowFormOptimized.last) ),
+ (Dependency[SystemVerilogEmitter], Seq(Forms.LowFormOptimized.last) )
+ ).foreach((testOrder _).tupled)
}
they should "work if placed inside an object" in {
diff --git a/src/test/scala/firrtlTests/LoweringCompilersSpec.scala b/src/test/scala/firrtlTests/LoweringCompilersSpec.scala
new file mode 100644
index 00000000..f3183599
--- /dev/null
+++ b/src/test/scala/firrtlTests/LoweringCompilersSpec.scala
@@ -0,0 +1,349 @@
+// See LICENSE for license details.
+
+package firrtlTests
+
+import org.scalatest.{FlatSpec, Matchers}
+
+import firrtl._
+import firrtl.passes
+import firrtl.options.Dependency
+import firrtl.stage.{Forms, TransformManager}
+import firrtl.transforms.IdentityTransform
+
+sealed trait PatchAction { val line: Int }
+
+case class Add(line: Int, transforms: Seq[Dependency[Transform]]) extends PatchAction
+case class Del(line: Int) extends PatchAction
+
+object Transforms {
+ class IdentityTransformDiff(val inputForm: CircuitForm, val outputForm: CircuitForm) extends Transform {
+ override def execute(state: CircuitState): CircuitState = state
+ override def name: String = s">>>>> $inputForm -> $outputForm <<<<<"
+ }
+ import firrtl.{ChirrtlForm => C, HighForm => H, MidForm => M, LowForm => L, UnknownForm => U}
+ class ChirrtlToChirrtl extends IdentityTransformDiff(C, C)
+ class HighToChirrtl extends IdentityTransformDiff(H, C)
+ class HighToHigh extends IdentityTransformDiff(H, H)
+ class MidToMid extends IdentityTransformDiff(M, M)
+ class MidToChirrtl extends IdentityTransformDiff(M, C)
+ class MidToHigh extends IdentityTransformDiff(M, H)
+ class LowToChirrtl extends IdentityTransformDiff(L, C)
+ class LowToHigh extends IdentityTransformDiff(L, H)
+ class LowToMid extends IdentityTransformDiff(L, M)
+ class LowToLow extends IdentityTransformDiff(L, L)
+}
+
+class LoweringCompilersSpec extends FlatSpec with Matchers {
+
+ def legacyTransforms(a: CoreTransform): Seq[Transform] = a match {
+ case _: ChirrtlToHighFirrtl => Seq(
+ passes.CheckChirrtl,
+ passes.CInferTypes,
+ passes.CInferMDir,
+ passes.RemoveCHIRRTL)
+ case _: IRToWorkingIR => Seq(passes.ToWorkingIR)
+ case _: ResolveAndCheck => Seq(
+ passes.CheckHighForm,
+ passes.ResolveKinds,
+ passes.InferTypes,
+ passes.CheckTypes,
+ passes.Uniquify,
+ passes.ResolveKinds,
+ passes.InferTypes,
+ passes.ResolveFlows,
+ passes.CheckFlows,
+ new passes.InferBinaryPoints,
+ new passes.TrimIntervals,
+ new passes.InferWidths,
+ passes.CheckWidths,
+ new firrtl.transforms.InferResets)
+ case _: HighFirrtlToMiddleFirrtl => Seq(
+ passes.PullMuxes,
+ passes.ReplaceAccesses,
+ passes.ExpandConnects,
+ passes.RemoveAccesses,
+ passes.Uniquify,
+ passes.ExpandWhens,
+ passes.CheckInitialization,
+ passes.ResolveKinds,
+ passes.InferTypes,
+ passes.CheckTypes,
+ passes.ResolveFlows,
+ new passes.InferWidths,
+ passes.CheckWidths,
+ new passes.RemoveIntervals,
+ passes.ConvertFixedToSInt,
+ passes.ZeroWidth,
+ passes.InferTypes)
+ case _: MiddleFirrtlToLowFirrtl => Seq(
+ passes.LowerTypes,
+ passes.ResolveKinds,
+ passes.InferTypes,
+ passes.ResolveFlows,
+ new passes.InferWidths,
+ passes.Legalize,
+ firrtl.transforms.RemoveReset,
+ passes.ResolveFlows,
+ new firrtl.transforms.CheckCombLoops,
+ new checks.CheckResets,
+ new firrtl.transforms.RemoveWires)
+ case _: LowFirrtlOptimization => Seq(
+ passes.RemoveValidIf,
+ new firrtl.transforms.ConstantPropagation,
+ passes.PadWidths,
+ new firrtl.transforms.ConstantPropagation,
+ passes.Legalize,
+ passes.memlib.VerilogMemDelays, // TODO move to Verilog emitter
+ new firrtl.transforms.ConstantPropagation,
+ passes.SplitExpressions,
+ new firrtl.transforms.CombineCats,
+ passes.CommonSubexpressionElimination,
+ new firrtl.transforms.DeadCodeElimination)
+ case _: MinimumLowFirrtlOptimization => Seq(
+ passes.RemoveValidIf,
+ passes.Legalize,
+ passes.memlib.VerilogMemDelays, // TODO move to Verilog emitter
+ passes.SplitExpressions)
+ }
+
+ def compare(a: Seq[Transform], b: TransformManager, patches: Seq[PatchAction] = Seq.empty): Unit = {
+ info(s"""Transform Order:\n${b.prettyPrint(" ")}""")
+
+ val m = new scala.collection.mutable.HashMap[Int, Seq[Dependency[Transform]]].withDefault(_ => Seq.empty)
+ a.map(Dependency.fromTransform).zipWithIndex.foreach{ case (t, idx) => m(idx) = Seq(t) }
+
+ patches.foreach {
+ case Add(line, txs) => m(line - 1) = m(line - 1) ++ txs
+ case Del(line) => m.remove(line - 1)
+ }
+
+ val patched = scala.collection.immutable.TreeMap(m.toArray:_*).values.flatten
+
+ patched
+ .zip(b.flattenedTransformOrder.map(Dependency.fromTransform))
+ .foreach{ case (aa, bb) => bb should be (aa) }
+
+ info(s"found ${b.flattenedTransformOrder.size} transforms")
+ patched.size should be (b.flattenedTransformOrder.size)
+ }
+
+ behavior of "ChirrtlToHighFirrtl"
+
+ it should "replicate the old order" in {
+ val tm = new TransformManager(Forms.MinimalHighForm, Forms.ChirrtlForm)
+ compare(legacyTransforms(new firrtl.ChirrtlToHighFirrtl), tm)
+ }
+
+ behavior of "IRToWorkingIR"
+
+ it should "replicate the old order" in {
+ val tm = new TransformManager(Forms.WorkingIR, Forms.MinimalHighForm)
+ compare(legacyTransforms(new firrtl.IRToWorkingIR), tm)
+ }
+
+ behavior of "ResolveAndCheck"
+
+ it should "replicate the old order" in {
+ val tm = new TransformManager(Forms.Resolved, Forms.WorkingIR)
+ val patches = Seq(
+ Add(14, Seq(Dependency.fromTransform(firrtl.passes.CheckTypes)))
+ )
+ compare(legacyTransforms(new ResolveAndCheck), tm, patches)
+ }
+
+ behavior of "HighFirrtlToMiddleFirrtl"
+
+ it should "replicate the old order" in {
+ val tm = new TransformManager(Forms.MidForm, Forms.Deduped)
+ val patches = Seq(
+ Add(5, Seq(Dependency(firrtl.passes.ResolveKinds),
+ Dependency(firrtl.passes.InferTypes))),
+ Del(6),
+ Del(7),
+ Add(6, Seq(Dependency[firrtl.passes.ExpandWhensAndCheck])),
+ Del(10),
+ Del(11),
+ Del(12),
+ Add(11, Seq(Dependency(firrtl.passes.ResolveFlows),
+ Dependency[firrtl.passes.InferWidths])),
+ Del(13)
+ )
+ compare(legacyTransforms(new HighFirrtlToMiddleFirrtl), tm, patches)
+ }
+
+ behavior of "MiddleFirrtlToLowFirrtl"
+
+ it should "replicate the old order" in {
+ val tm = new TransformManager(Forms.LowForm, Forms.MidForm)
+ compare(legacyTransforms(new MiddleFirrtlToLowFirrtl), tm)
+ }
+
+ behavior of "MinimumLowFirrtlOptimization"
+
+ it should "replicate the old order" in {
+ val tm = new TransformManager(Forms.LowFormMinimumOptimized, Forms.LowForm)
+ compare(legacyTransforms(new MinimumLowFirrtlOptimization), tm)
+ }
+
+ behavior of "LowFirrtlOptimization"
+
+ it should "replicate the old order" in {
+ val tm = new TransformManager(Forms.LowFormOptimized, Forms.LowForm)
+ val patches = Seq(
+ Add(7, Seq(Dependency(firrtl.passes.Legalize)))
+ )
+ compare(legacyTransforms(new LowFirrtlOptimization), tm, patches)
+ }
+
+ behavior of "VerilogMinimumOptimized"
+
+ it should "replicate the old order" in {
+ val legacy = Seq(
+ new firrtl.transforms.BlackBoxSourceHelper,
+ new firrtl.transforms.FixAddingNegativeLiterals,
+ new firrtl.transforms.ReplaceTruncatingArithmetic,
+ new firrtl.transforms.InlineBitExtractionsTransform,
+ new firrtl.transforms.InlineCastsTransform,
+ new firrtl.transforms.LegalizeClocksTransform,
+ new firrtl.transforms.FlattenRegUpdate,
+ firrtl.passes.VerilogModulusCleanup,
+ new firrtl.transforms.VerilogRename,
+ firrtl.passes.VerilogPrep,
+ new firrtl.AddDescriptionNodes)
+ val tm = new TransformManager(Forms.VerilogMinimumOptimized, (new firrtl.VerilogEmitter).prerequisites)
+ compare(legacy, tm)
+ }
+
+ behavior of "VerilogOptimized"
+
+ it should "replicate the old order" in {
+ val legacy = Seq(
+ new firrtl.transforms.BlackBoxSourceHelper,
+ new firrtl.transforms.FixAddingNegativeLiterals,
+ new firrtl.transforms.ReplaceTruncatingArithmetic,
+ new firrtl.transforms.InlineBitExtractionsTransform,
+ new firrtl.transforms.InlineCastsTransform,
+ new firrtl.transforms.LegalizeClocksTransform,
+ new firrtl.transforms.FlattenRegUpdate,
+ new firrtl.transforms.DeadCodeElimination,
+ firrtl.passes.VerilogModulusCleanup,
+ new firrtl.transforms.VerilogRename,
+ firrtl.passes.VerilogPrep,
+ new firrtl.AddDescriptionNodes)
+ val tm = new TransformManager(Forms.VerilogOptimized, Forms.LowFormOptimized)
+ compare(legacy, tm)
+ }
+
+ behavior of "Legacy Custom Transforms"
+
+ it should "work for Chirrtl -> Chirrtl" in {
+ val expected = new Transforms.ChirrtlToChirrtl :: new firrtl.ChirrtlEmitter :: Nil
+ val tm = new TransformManager(Dependency[firrtl.ChirrtlEmitter] :: Dependency[Transforms.ChirrtlToChirrtl] :: Nil)
+ compare(expected, tm)
+ }
+
+ it should "work for High -> High" in {
+ val expected =
+ new TransformManager(Forms.HighForm).flattenedTransformOrder ++
+ Some(new Transforms.HighToHigh) ++
+ (new TransformManager(Forms.MidForm, Forms.HighForm).flattenedTransformOrder)
+ val tm = new TransformManager(Forms.MidForm :+ Dependency[Transforms.HighToHigh])
+ compare(expected, tm)
+ }
+
+ it should "work for High -> Chirrtl" in {
+ val expected =
+ new TransformManager(Forms.HighForm).flattenedTransformOrder ++
+ Some(new Transforms.HighToChirrtl) ++
+ (new TransformManager(Forms.HighForm, Forms.ChirrtlForm).flattenedTransformOrder)
+ val tm = new TransformManager(Forms.HighForm :+ Dependency[Transforms.HighToChirrtl])
+ compare(expected, tm)
+ }
+
+ it should "work for Mid -> Mid" in {
+ val expected =
+ new TransformManager(Forms.MidForm).flattenedTransformOrder ++
+ Some(new Transforms.MidToMid) ++
+ (new TransformManager(Forms.LowForm, Forms.MidForm).flattenedTransformOrder)
+ val tm = new TransformManager(Forms.LowForm :+ Dependency[Transforms.MidToMid])
+ compare(expected, tm)
+ }
+
+ it should "work for Mid -> High" in {
+ val expected =
+ new TransformManager(Forms.MidForm).flattenedTransformOrder ++
+ Some(new Transforms.MidToHigh) ++
+ (new TransformManager(Forms.LowForm, Forms.MinimalHighForm).flattenedTransformOrder)
+ val tm = new TransformManager(Forms.LowForm :+ Dependency[Transforms.MidToHigh])
+ compare(expected, tm)
+ }
+
+ it should "work for Mid -> Chirrtl" in {
+ val expected =
+ new TransformManager(Forms.MidForm).flattenedTransformOrder ++
+ Some(new Transforms.MidToChirrtl) ++
+ (new TransformManager(Forms.LowForm, Forms.ChirrtlForm).flattenedTransformOrder)
+ val tm = new TransformManager(Forms.LowForm :+ Dependency[Transforms.MidToChirrtl])
+ compare(expected, tm)
+ }
+
+ it should "work for Low -> Low" in {
+ val expected =
+ new TransformManager(Forms.LowFormOptimized).flattenedTransformOrder ++
+ Seq(new Transforms.LowToLow)
+ val tm = new TransformManager(Forms.LowFormOptimized :+ Dependency[Transforms.LowToLow])
+ compare(expected, tm)
+ }
+
+ it should "work for Low -> Mid" in {
+ val expected =
+ new TransformManager(Forms.LowFormOptimized).flattenedTransformOrder ++
+ Seq(new Transforms.LowToMid) ++
+ (new TransformManager(Forms.LowFormOptimized, Forms.MidForm).flattenedTransformOrder)
+ val tm = new TransformManager(Forms.LowFormOptimized :+ Dependency[Transforms.LowToMid])
+ compare(expected, tm)
+ }
+
+ it should "work for Low -> High" in {
+ val expected =
+ new TransformManager(Forms.LowFormOptimized).flattenedTransformOrder ++
+ Seq(new Transforms.LowToHigh) ++
+ (new TransformManager(Forms.LowFormOptimized, Forms.MinimalHighForm).flattenedTransformOrder)
+ val tm = new TransformManager(Forms.LowFormOptimized :+ Dependency[Transforms.LowToHigh])
+ compare(expected, tm)
+ }
+
+ it should "work for Low -> Chirrtl" in {
+ val expected =
+ new TransformManager(Forms.LowFormOptimized).flattenedTransformOrder ++
+ Seq(new Transforms.LowToChirrtl) ++
+ (new TransformManager(Forms.LowFormOptimized, Forms.ChirrtlForm).flattenedTransformOrder)
+ val tm = new TransformManager(Forms.LowFormOptimized :+ Dependency[Transforms.LowToChirrtl])
+ compare(expected, tm)
+ }
+
+ it should "schedule inputForm=LowForm after MiddleFirrtlToLowFirrtl for the LowFirrtlEmitter" in {
+ val expected =
+ new TransformManager(Forms.LowForm).flattenedTransformOrder ++
+ Seq(new Transforms.LowToLow, new firrtl.LowFirrtlEmitter)
+ val tm = (new TransformManager(Seq(Dependency[firrtl.LowFirrtlEmitter], Dependency[Transforms.LowToLow])))
+ compare(expected, tm)
+ }
+
+ it should "schedule inputForm=LowForm after MinimumLowFirrtlOptimizations for the MinimalVerilogEmitter" in {
+ val expected =
+ new TransformManager(Forms.LowFormMinimumOptimized).flattenedTransformOrder ++
+ Seq(new Transforms.LowToLow, new firrtl.MinimumVerilogEmitter)
+ val tm = (new TransformManager(Seq(Dependency[firrtl.MinimumVerilogEmitter], Dependency[Transforms.LowToLow])))
+ compare(expected, tm)
+ }
+
+ it should "schedule inputForm=LowForm after LowFirrtlOptimizations for the VerilogEmitter" in {
+ val expected =
+ new TransformManager(Forms.LowFormOptimized).flattenedTransformOrder ++
+ Seq(new Transforms.LowToLow, new firrtl.VerilogEmitter)
+ val tm = (new TransformManager(Seq(Dependency[firrtl.VerilogEmitter], Dependency[Transforms.LowToLow])))
+ compare(expected, tm)
+ }
+
+}
diff --git a/src/test/scala/firrtlTests/VerilogEmitterTests.scala b/src/test/scala/firrtlTests/VerilogEmitterTests.scala
index c5d0eacc..825d706f 100644
--- a/src/test/scala/firrtlTests/VerilogEmitterTests.scala
+++ b/src/test/scala/firrtlTests/VerilogEmitterTests.scala
@@ -13,12 +13,12 @@ class DoPrimVerilog extends FirrtlFlatSpec {
"Xorr" should "emit correctly" in {
val compiler = new VerilogCompiler
val input =
- """circuit Xorr :
- | module Xorr :
+ """circuit Xorr :
+ | module Xorr :
| input a: UInt<4>
| output b: UInt<1>
| b <= xorr(a)""".stripMargin
- val check =
+ val check =
"""module Xorr(
| input [3:0] a,
| output b
@@ -31,12 +31,12 @@ class DoPrimVerilog extends FirrtlFlatSpec {
"Andr" should "emit correctly" in {
val compiler = new VerilogCompiler
val input =
- """circuit Andr :
- | module Andr :
+ """circuit Andr :
+ | module Andr :
| input a: UInt<4>
| output b: UInt<1>
| b <= andr(a)""".stripMargin
- val check =
+ val check =
"""module Andr(
| input [3:0] a,
| output b
@@ -49,12 +49,12 @@ class DoPrimVerilog extends FirrtlFlatSpec {
"Orr" should "emit correctly" in {
val compiler = new VerilogCompiler
val input =
- """circuit Orr :
- | module Orr :
+ """circuit Orr :
+ | module Orr :
| input a: UInt<4>
| output b: UInt<1>
| b <= orr(a)""".stripMargin
- val check =
+ val check =
"""module Orr(
| input [3:0] a,
| output b
@@ -187,8 +187,8 @@ class DoPrimVerilog extends FirrtlFlatSpec {
|""".stripMargin
val check =
"""module Test(
- | input [7:0] in,
- | output out
+ | input [7:0] in,
+ | output out
|);
| wire [7:0] _GEN_0;
| assign out = _GEN_0[0];
diff --git a/src/test/scala/firrtlTests/annotationTests/TargetDirAnnotationSpec.scala b/src/test/scala/firrtlTests/annotationTests/TargetDirAnnotationSpec.scala
index eb061d8f..ea4127bc 100644
--- a/src/test/scala/firrtlTests/annotationTests/TargetDirAnnotationSpec.scala
+++ b/src/test/scala/firrtlTests/annotationTests/TargetDirAnnotationSpec.scala
@@ -5,24 +5,25 @@ package annotationTests
import firrtlTests._
import firrtl._
+import firrtl.annotations.{Annotation, NoTargetAnnotation}
+
+case object FoundTargetDirTransformRanAnnotation extends NoTargetAnnotation
+case object FoundTargetDirTransformFoundTargetDirAnnotation extends NoTargetAnnotation
/** Looks for [[TargetDirAnnotation]] */
-class FindTargetDirTransform(expected: String) extends Transform {
+class FindTargetDirTransform extends Transform {
def inputForm = HighForm
def outputForm = HighForm
- var foundTargetDir = false
- var run = false
+
def execute(state: CircuitState): CircuitState = {
- run = true
- state.annotations.collectFirst {
- case TargetDirAnnotation(expected) =>
- foundTargetDir = true
- }
- state
+ val a: Option[Annotation] = state.annotations.collectFirst {
+ case TargetDirAnnotation("a/b/c") => FoundTargetDirTransformFoundTargetDirAnnotation }
+ state.copy(annotations = state.annotations ++ a ++ Some(FoundTargetDirTransformRanAnnotation))
}
}
class TargetDirAnnotationSpec extends FirrtlFlatSpec {
+
behavior of "The target directory"
val input =
@@ -35,7 +36,7 @@ class TargetDirAnnotationSpec extends FirrtlFlatSpec {
val targetDir = "a/b/c"
it should "be available as an annotation when using execution options" in {
- val findTargetDir = new FindTargetDirTransform(targetDir) // looks for the annotation
+ val findTargetDir = new FindTargetDirTransform // looks for the annotation
val optionsManager = new ExecutionOptionsManager("TargetDir") with HasFirrtlOptions {
commonOptions = commonOptions.copy(targetDirName = targetDir,
@@ -44,11 +45,13 @@ class TargetDirAnnotationSpec extends FirrtlFlatSpec {
firrtlSource = Some(input),
customTransforms = Seq(findTargetDir))
}
- Driver.execute(optionsManager)
+ val annotations: Seq[Annotation] = Driver.execute(optionsManager) match {
+ case a: FirrtlExecutionSuccess => a.circuitState.annotations
+ case _ => fail
+ }
- // Check that FindTargetDirTransform transform is run and finds the annotation
- findTargetDir.run should be (true)
- findTargetDir.foundTargetDir should be (true)
+ annotations should contain (FoundTargetDirTransformRanAnnotation)
+ annotations should contain (FoundTargetDirTransformFoundTargetDirAnnotation)
// Delete created directory
val dir = new java.io.File(targetDir)
@@ -57,13 +60,16 @@ class TargetDirAnnotationSpec extends FirrtlFlatSpec {
}
it should "NOT be available as an annotation when using a raw compiler" in {
- val findTargetDir = new FindTargetDirTransform(targetDir) // looks for the annotation
+ val findTargetDir = new FindTargetDirTransform // looks for the annotation
val compiler = new VerilogCompiler
val circuit = Parser.parse(input split "\n")
- compiler.compileAndEmit(CircuitState(circuit, HighForm), Seq(findTargetDir))
+
+ val annotations: Seq[Annotation] = compiler
+ .compileAndEmit(CircuitState(circuit, HighForm), Seq(findTargetDir))
+ .annotations
// Check that FindTargetDirTransform does not find the annotation
- findTargetDir.run should be (true)
- findTargetDir.foundTargetDir should be (false)
+ annotations should contain (FoundTargetDirTransformRanAnnotation)
+ annotations should not contain (FoundTargetDirTransformFoundTargetDirAnnotation)
}
}
diff --git a/src/test/scala/firrtlTests/stage/phases/CompilerSpec.scala b/src/test/scala/firrtlTests/stage/phases/CompilerSpec.scala
index a8176316..f2620051 100644
--- a/src/test/scala/firrtlTests/stage/phases/CompilerSpec.scala
+++ b/src/test/scala/firrtlTests/stage/phases/CompilerSpec.scala
@@ -4,9 +4,11 @@ package firrtlTests.stage.phases
import org.scalatest.{FlatSpec, Matchers}
+import scala.collection.mutable
+
import firrtl.{Compiler => _, _}
-import firrtl.options.Phase
-import firrtl.stage.{CompilerAnnotation, FirrtlCircuitAnnotation, RunFirrtlTransformAnnotation}
+import firrtl.options.{Phase, PreservesAll}
+import firrtl.stage.{CompilerAnnotation, FirrtlCircuitAnnotation, Forms, RunFirrtlTransformAnnotation}
import firrtl.stage.phases.Compiler
class CompilerSpec extends FlatSpec with Matchers {
@@ -40,7 +42,7 @@ class CompilerSpec extends FlatSpec with Matchers {
val expected = Seq(FirrtlCircuitAnnotation(circuitOut))
- phase.transform(input).toSeq should be (expected)
+ phase.transform(input).collect{ case a: FirrtlCircuitAnnotation => a }.toSeq should be (expected)
}
it should "compile multiple FirrtlCircuitAnnotations" in new Fixture {
@@ -140,4 +142,37 @@ class CompilerSpec extends FlatSpec with Matchers {
.size should be (20)
}
+ it should "run transforms in sequential order" in new Fixture {
+ import CompilerSpec.{FirstTransform, SecondTransform}
+
+ val circuitIn = Parser.parse(chirrtl("top"))
+ val annotations =
+ Seq( FirrtlCircuitAnnotation(circuitIn),
+ CompilerAnnotation(new VerilogCompiler),
+ RunFirrtlTransformAnnotation(new FirstTransform),
+ RunFirrtlTransformAnnotation(new SecondTransform) )
+ phase.transform(annotations)
+
+ CompilerSpec.globalState.toSeq should be (Seq(classOf[FirstTransform], classOf[SecondTransform]))
+ }
+
+}
+
+object CompilerSpec {
+
+ private[CompilerSpec] val globalState: mutable.Queue[Class[_ <: Transform]] = mutable.Queue.empty[Class[_ <: Transform]]
+
+ class LoggingTransform extends Transform with PreservesAll[Transform] {
+ override def inputForm = UnknownForm
+ override def outputForm = UnknownForm
+ override def prerequisites = Forms.HighForm
+ def execute(c: CircuitState): CircuitState = {
+ globalState += this.getClass
+ c
+ }
+ }
+
+ class FirstTransform extends LoggingTransform
+ class SecondTransform extends LoggingTransform
+
}
diff --git a/src/test/scala/firrtlTests/transforms/BlackBoxSourceHelperSpec.scala b/src/test/scala/firrtlTests/transforms/BlackBoxSourceHelperSpec.scala
index 213ead77..feba5a24 100644
--- a/src/test/scala/firrtlTests/transforms/BlackBoxSourceHelperSpec.scala
+++ b/src/test/scala/firrtlTests/transforms/BlackBoxSourceHelperSpec.scala
@@ -100,11 +100,6 @@ class BlacklBoxSourceHelperTransformSpec extends LowTransformSpec {
new java.io.File(s"test_run_dir/${BlackBoxSourceHelper.defaultFileListName}").exists should be (true)
}
- "verilog compiler" should "have BlackBoxSourceHelper transform" in {
- val verilogCompiler = new VerilogEmitter
- verilogCompiler.transforms.map { x => x.getClass } should contain (classOf[BlackBoxSourceHelper])
- }
-
"verilog header files" should "be available but not mentioned in the file list" in {
// Issue #917 - We don't want to list Verilog header files ("*.vh") in our file list.
// We don't actually verify that the generated verilog code works,