aboutsummaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
authorSchuyler Eldridge2020-05-04 17:05:58 -0400
committerGitHub2020-05-04 17:05:58 -0400
commit0e8e1296c6cac59b9af883fd95e9ad67afdb28d1 (patch)
tree3283fe625276b0dc4e0baa092affc8b2c785b7e5 /src/test
parentee0d4079c6076b0af1f9e557f69e7346cdd89d4f (diff)
parent9624121164e0c65f7ce81048a8c0621882f1d55b (diff)
Merge pull request #1556 from freechipsproject/legalize-andreduce
Add LegalizeAndReductionsTransform
Diffstat (limited to 'src/test')
-rw-r--r--src/test/scala/firrtlTests/CustomTransformSpec.scala21
-rw-r--r--src/test/scala/firrtlTests/LoweringCompilersSpec.scala10
-rw-r--r--src/test/scala/firrtlTests/transforms/LegalizeReductions.scala110
3 files changed, 129 insertions, 12 deletions
diff --git a/src/test/scala/firrtlTests/CustomTransformSpec.scala b/src/test/scala/firrtlTests/CustomTransformSpec.scala
index ef1dc86d..d736ec3c 100644
--- a/src/test/scala/firrtlTests/CustomTransformSpec.scala
+++ b/src/test/scala/firrtlTests/CustomTransformSpec.scala
@@ -9,7 +9,7 @@ import firrtl.ir._
import firrtl.stage.{FirrtlSourceAnnotation, FirrtlStage, Forms, RunFirrtlTransformAnnotation}
import firrtl.options.Dependency
-import firrtl.transforms.IdentityTransform
+import firrtl.transforms.{IdentityTransform, LegalizeAndReductionsTransform}
import firrtl.testutils._
@@ -149,17 +149,18 @@ class CustomTransformSpec extends FirrtlFlatSpec {
))
}
- they should "run right before the emitter when inputForm=LowForm" in {
+ 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!""")
+ def testOrder(after: Seq[Dependency[Transform]], before: Seq[Dependency[Transform]]): Unit = {
+ val expectedSlice: Seq[Dependency[Transform]] = before ++: custom +: after
- val compiler = new firrtl.stage.transforms.Compiler(Seq(custom, emitter))
+ info(expectedSlice.map(_.getSimpleName).mkString(" -> ") + " ok!")
+
+ val compiler = new firrtl.stage.transforms.Compiler(custom +: after)
info("Transform Order: \n" + compiler.prettyPrint(" "))
- val expectedSlice = preceders ++ Seq(custom, emitter)
compiler
.flattenedTransformOrder
@@ -172,10 +173,10 @@ class CustomTransformSpec extends FirrtlFlatSpec {
.map(target => new firrtl.stage.transforms.Compiler(target))
.map(_.flattenedTransformOrder.map(Dependency.fromTransform(_)))
- Seq( (Dependency[LowFirrtlEmitter], Seq(low.last) ),
- (Dependency[MinimumVerilogEmitter], Seq(lowMinOpt.last)),
- (Dependency[VerilogEmitter], Seq(lowOpt.last) ),
- (Dependency[SystemVerilogEmitter], Seq(lowOpt.last) )
+ Seq( (Seq(Dependency[LowFirrtlEmitter]), Seq(low.last) ),
+ (Seq(Dependency[LegalizeAndReductionsTransform], Dependency[MinimumVerilogEmitter]), Seq(lowMinOpt.last)),
+ (Seq(Dependency[LegalizeAndReductionsTransform], Dependency[VerilogEmitter]), Seq(lowOpt.last) ),
+ (Seq(Dependency[LegalizeAndReductionsTransform], Dependency[SystemVerilogEmitter]), Seq(lowOpt.last) )
).foreach((testOrder _).tupled)
}
diff --git a/src/test/scala/firrtlTests/LoweringCompilersSpec.scala b/src/test/scala/firrtlTests/LoweringCompilersSpec.scala
index 4a7a1700..b9143b26 100644
--- a/src/test/scala/firrtlTests/LoweringCompilersSpec.scala
+++ b/src/test/scala/firrtlTests/LoweringCompilersSpec.scala
@@ -348,7 +348,10 @@ class LoweringCompilersSpec extends FlatSpec with Matchers {
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)
+ val patches = Seq(
+ Add(60, Seq(Dependency[firrtl.transforms.LegalizeAndReductionsTransform]))
+ )
+ compare(expected, tm, patches)
}
it should "schedule inputForm=LowForm after LowFirrtlOptimizations for the VerilogEmitter" in {
@@ -356,7 +359,10 @@ class LoweringCompilersSpec extends FlatSpec with Matchers {
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)
+ val patches = Seq(
+ Add(67, Seq(Dependency[firrtl.transforms.LegalizeAndReductionsTransform]))
+ )
+ compare(expected, tm, patches)
}
}
diff --git a/src/test/scala/firrtlTests/transforms/LegalizeReductions.scala b/src/test/scala/firrtlTests/transforms/LegalizeReductions.scala
new file mode 100644
index 00000000..664701c3
--- /dev/null
+++ b/src/test/scala/firrtlTests/transforms/LegalizeReductions.scala
@@ -0,0 +1,110 @@
+// See LICENSE for license details.
+
+package firrtlTests.transforms
+
+import firrtl._
+import firrtl.ir.StringLit
+import firrtl.testutils._
+
+import org.scalatest.flatspec.AnyFlatSpec
+
+import java.io.File
+
+object LegalizeAndReductionsTransformSpec extends FirrtlRunners {
+ private case class Test(
+ name: String,
+ op: String,
+ input: BigInt,
+ expected: BigInt,
+ forceWidth: Option[Int] = None
+ ) {
+ def toFirrtl: String = {
+ val width = forceWidth.getOrElse(input.bitLength)
+ val inputLit = s"""UInt("h${input.toString(16)}")"""
+ val expectLit = s"""UInt("h${expected.toString(16)}")"""
+ val assertMsg = StringLit(s"Assertion failed! $op($inputLit) != $expectLit!\n").verilogEscape
+ // Reset the register to something different from the input
+ val regReset = if (input == 0) 1 else 0
+ s"""
+circuit $name :
+ module $name :
+ input clock : Clock
+ input reset : UInt<1>
+
+ node input = $inputLit
+ node expected = $expectLit
+
+ reg r : UInt<$width>, clock with : (reset => (reset, UInt($regReset)))
+ r <= input
+ node expr = $op(r)
+ node equal = eq(expr, expected)
+
+ reg count : UInt<2>, clock with : (reset => (reset, UInt(0)))
+ count <= tail(add(count, UInt(1)), 1)
+
+ when not(reset) :
+ when eq(count, UInt(1)) :
+ printf(clock, UInt(1), "input = %x, expected = %x, expr = %x, equal = %x\\n", input, expected, expr, equal)
+ when not(equal) :
+ printf(clock, UInt(1), $assertMsg)
+ stop(clock, UInt(1), 1)
+ else :
+ stop(clock, UInt(1), 0)
+"""
+ }
+ }
+
+ private def executeTest(test: Test): Unit = {
+ import firrtl.stage._
+ import firrtl.options.TargetDirAnnotation
+ val prefix = test.name
+ val testDir = createTestDirectory(s"LegalizeReductions.$prefix")
+ // Run FIRRTL
+ val annos =
+ FirrtlSourceAnnotation(test.toFirrtl) ::
+ TargetDirAnnotation(testDir.toString) ::
+ CompilerAnnotation(new MinimumVerilogCompiler) ::
+ Nil
+ val resultAnnos = (new FirrtlStage).run(annos)
+ val outputFilename = resultAnnos.collectFirst { case OutputFileAnnotation(f) => f }
+ outputFilename.toRight(s"Output file not found!")
+ // Copy Verilator harness
+ val harness = new File(testDir, "top.cpp")
+ copyResourceToFile(cppHarnessResourceName, harness)
+ // Run Verilator
+ verilogToCpp(prefix, testDir, Nil, harness, suppressVcd = true) #&&
+ cppToExe(prefix, testDir) !
+ loggingProcessLogger
+ // Run binary
+ if (!executeExpectingSuccess(prefix, testDir)) {
+ throw new Exception("Test failed!") with scala.util.control.NoStackTrace
+ }
+ }
+}
+
+
+class LegalizeAndReductionsTransformSpec extends AnyFlatSpec {
+
+ import LegalizeAndReductionsTransformSpec._
+
+ behavior of "LegalizeAndReductionsTransform"
+
+ private val tests =
+ // name primop input expected width
+ Test("andreduce_ones", "andr", BigInt("1"*68, 2), 1) ::
+ Test("andreduce_zero", "andr", 0, 0, Some(68)) ::
+ Test("orreduce_ones", "orr", BigInt("1"*68, 2), 1) ::
+ Test("orreduce_high_one", "orr", BigInt("1" + "0"*67, 2), 1) ::
+ Test("orreduce_zero", "orr", 0, 0, Some(68)) ::
+ Test("xorreduce_high_one", "xorr", BigInt("1" + "0"*67, 2), 1) ::
+ Test("xorreduce_high_low_one", "xorr", BigInt("1" + "0"*66 + "1", 2), 0) ::
+ Test("xorreduce_zero", "xorr", 0, 0, Some(68)) ::
+ Nil
+
+ for (test <- tests) {
+ it should s"support ${test.name}" in {
+ executeTest(test)
+ }
+ }
+
+}