aboutsummaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
authorAdam Izraelevitz2018-03-21 14:24:25 -0700
committerGitHub2018-03-21 14:24:25 -0700
commit6ea4ac666e4ce8dfaca1545660f372fccff610f5 (patch)
tree8f2125855557962d642386fe8b49ed0396f562c2 /src/test
parent6b195e4a5348eed2e714e1183024588c5f91a283 (diff)
GroupModule Transform (#766)
* Added grouping pass * Added InfoMagnet and infomappers * Changed return type of execute to allow final CircuitState inspection * Updated dedup. Now is name-agnostic * Added GroupAndDedup transform
Diffstat (limited to 'src/test')
-rw-r--r--src/test/scala/firrtlTests/AttachSpec.scala2
-rw-r--r--src/test/scala/firrtlTests/PassTests.scala3
-rw-r--r--src/test/scala/firrtlTests/transforms/DedupTests.scala336
-rw-r--r--src/test/scala/firrtlTests/transforms/GroupComponentsSpec.scala290
4 files changed, 491 insertions, 140 deletions
diff --git a/src/test/scala/firrtlTests/AttachSpec.scala b/src/test/scala/firrtlTests/AttachSpec.scala
index cf92ec1c..c9c609df 100644
--- a/src/test/scala/firrtlTests/AttachSpec.scala
+++ b/src/test/scala/firrtlTests/AttachSpec.scala
@@ -48,7 +48,7 @@ class InoutVerilogSpec extends FirrtlFlatSpec {
|);
|endmodule
|""".stripMargin.split("\n") map normalized
- executeTest(input, check, compiler)
+ executeTest(input, check, compiler, Seq(dontDedup("A"), dontDedup("B")))
}
it should "attach two instances" in {
diff --git a/src/test/scala/firrtlTests/PassTests.scala b/src/test/scala/firrtlTests/PassTests.scala
index 847643ef..6f94275e 100644
--- a/src/test/scala/firrtlTests/PassTests.scala
+++ b/src/test/scala/firrtlTests/PassTests.scala
@@ -20,13 +20,14 @@ abstract class SimpleTransformSpec extends FlatSpec with FirrtlMatchers with Com
// 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]): Unit = {
+ 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
}
// Executes the test, should throw an error
// No default to be consistent with execute
diff --git a/src/test/scala/firrtlTests/transforms/DedupTests.scala b/src/test/scala/firrtlTests/transforms/DedupTests.scala
index e88bd506..6fab902e 100644
--- a/src/test/scala/firrtlTests/transforms/DedupTests.scala
+++ b/src/test/scala/firrtlTests/transforms/DedupTests.scala
@@ -3,150 +3,210 @@
package firrtlTests
package transform
-import org.scalatest.FlatSpec
-import org.scalatest.Matchers
-import org.scalatest.junit.JUnitRunner
-
-import firrtl.ir.Circuit
-import firrtl.Parser
-import firrtl.passes.PassExceptions
-import firrtl.annotations.{
- Named,
- CircuitName,
- ModuleName,
- Annotation
-}
-import firrtl.transforms.{DedupModules, NoDedupAnnotation}
+import firrtl.annotations._
+import firrtl.transforms.{DedupModules}
/**
* Tests inline instances transformation
*/
class DedupModuleTests extends HighTransformSpec {
- def transform = new DedupModules
- "The module A" should "be deduped" in {
- val input =
- """circuit Top :
- | module Top :
- | inst a1 of A
- | inst a2 of A_
- | module A :
- | output x: UInt<1>
- | x <= UInt(1)
- | module A_ :
- | output x: UInt<1>
- | x <= UInt(1)
- """.stripMargin
- val check =
- """circuit Top :
- | module Top :
- | inst a1 of A
- | inst a2 of A
- | module A :
- | output x: UInt<1>
- | x <= UInt(1)
- """.stripMargin
- execute(input, check, Seq.empty)
- }
- "The module A and B" should "be deduped" in {
- val input =
- """circuit Top :
- | module Top :
- | inst a1 of A
- | inst a2 of A_
- | module A :
- | output x: UInt<1>
- | inst b of B
- | x <= b.x
- | module A_ :
- | output x: UInt<1>
- | inst b of B_
- | x <= b.x
- | module B :
- | output x: UInt<1>
- | x <= UInt(1)
- | module B_ :
- | output x: UInt<1>
- | x <= UInt(1)
- """.stripMargin
- val check =
- """circuit Top :
- | module Top :
- | inst a1 of A
- | inst a2 of A
- | module A :
- | output x: UInt<1>
- | inst b of B
- | x <= b.x
- | module B :
- | output x: UInt<1>
- | x <= UInt(1)
- """.stripMargin
- execute(input, check, Seq.empty)
- }
- "The module A and B with comments" should "be deduped" in {
- val input =
- """circuit Top :
- | module Top :
- | inst a1 of A
- | inst a2 of A_
- | module A : @[yy 2:2]
- | output x: UInt<1> @[yy 2:2]
- | inst b of B @[yy 2:2]
- | x <= b.x @[yy 2:2]
- | module A_ : @[xx 1:1]
- | output x: UInt<1> @[xx 1:1]
- | inst b of B_ @[xx 1:1]
- | x <= b.x @[xx 1:1]
- | module B :
- | output x: UInt<1>
- | x <= UInt(1)
- | module B_ :
- | output x: UInt<1>
- | x <= UInt(1)
- """.stripMargin
- val check =
- """circuit Top :
- | module Top :
- | inst a1 of A
- | inst a2 of A
- | module A : @[yy 2:2]
- | output x: UInt<1> @[yy 2:2]
- | inst b of B @[yy 2:2]
- | x <= b.x @[yy 2:2]
- | module B :
- | output x: UInt<1>
- | x <= UInt(1)
- """.stripMargin
- execute(input, check, Seq.empty)
- }
- "The module B, but not A, with comments" should "be deduped if not annotated" in {
- val input =
- """circuit Top :
- | module Top :
- | inst a1 of A
- | inst a2 of A_
- | module A : @[yy 2:2]
- | output x: UInt<1> @[yy 2:2]
- | x <= UInt(1)
- | module A_ : @[xx 1:1]
- | output x: UInt<1> @[xx 1:1]
- | x <= UInt(1)
- """.stripMargin
- val check =
- """circuit Top :
- | module Top :
- | inst a1 of A
- | inst a2 of A_
- | module A : @[yy 2:2]
- | output x: UInt<1> @[yy 2:2]
- | x <= UInt(1)
- | module A_ : @[xx 1:1]
- | output x: UInt<1> @[xx 1:1]
- | x <= UInt(1)
- """.stripMargin
- execute(input, check, Seq(dontDedup("A")))
- }
+ def transform = new DedupModules
+ "The module A" should "be deduped" in {
+ val input =
+ """circuit Top :
+ | module Top :
+ | inst a1 of A
+ | inst a2 of A_
+ | module A :
+ | output x: UInt<1>
+ | x <= UInt(1)
+ | module A_ :
+ | output x: UInt<1>
+ | x <= UInt(1)
+ """.stripMargin
+ val check =
+ """circuit Top :
+ | module Top :
+ | inst a1 of A
+ | inst a2 of A
+ | module A :
+ | output x: UInt<1>
+ | x <= UInt(1)
+ """.stripMargin
+ execute(input, check, Seq.empty)
+ }
+ "The module A and B" should "be deduped" in {
+ val input =
+ """circuit Top :
+ | module Top :
+ | inst a1 of A
+ | inst a2 of A_
+ | module A :
+ | output x: UInt<1>
+ | inst b of B
+ | x <= b.x
+ | module A_ :
+ | output x: UInt<1>
+ | inst b of B_
+ | x <= b.x
+ | module B :
+ | output x: UInt<1>
+ | x <= UInt(1)
+ | module B_ :
+ | output x: UInt<1>
+ | x <= UInt(1)
+ """.stripMargin
+ val check =
+ """circuit Top :
+ | module Top :
+ | inst a1 of A
+ | inst a2 of A
+ | module A :
+ | output x: UInt<1>
+ | inst b of B
+ | x <= b.x
+ | module B :
+ | output x: UInt<1>
+ | x <= UInt(1)
+ """.stripMargin
+ execute(input, check, Seq.empty)
+ }
+ "The module A and B with comments" should "be deduped" in {
+ val input =
+ """circuit Top :
+ | module Top :
+ | inst a1 of A
+ | inst a2 of A_
+ | module A : @[yy 2:2]
+ | output x: UInt<1> @[yy 2:2]
+ | inst b of B @[yy 2:2]
+ | x <= b.x @[yy 2:2]
+ | module A_ : @[xx 1:1]
+ | output x: UInt<1> @[xx 1:1]
+ | inst b of B_ @[xx 1:1]
+ | x <= b.x @[xx 1:1]
+ | module B :
+ | output x: UInt<1>
+ | x <= UInt(1)
+ | module B_ :
+ | output x: UInt<1>
+ | x <= UInt(1)
+ """.stripMargin
+ val check =
+ """circuit Top :
+ | module Top :
+ | inst a1 of A
+ | inst a2 of A
+ | module A : @[yy 2:2]
+ | output x: UInt<1> @[yy 2:2]
+ | inst b of B @[yy 2:2]
+ | x <= b.x @[yy 2:2]
+ | module B :
+ | output x: UInt<1>
+ | x <= UInt(1)
+ """.stripMargin
+ execute(input, check, Seq.empty)
+ }
+ "A_ but not A" should "be deduped if not annotated" in {
+ val input =
+ """circuit Top :
+ | module Top :
+ | inst a1 of A
+ | inst a2 of A_
+ | module A : @[yy 2:2]
+ | output x: UInt<1> @[yy 2:2]
+ | x <= UInt(1)
+ | module A_ : @[xx 1:1]
+ | output x: UInt<1> @[xx 1:1]
+ | x <= UInt(1)
+ """.stripMargin
+ val check =
+ """circuit Top :
+ | module Top :
+ | inst a1 of A
+ | inst a2 of A_
+ | module A : @[yy 2:2]
+ | output x: UInt<1> @[yy 2:2]
+ | x <= UInt(1)
+ | module A_ : @[xx 1:1]
+ | output x: UInt<1> @[xx 1:1]
+ | x <= UInt(1)
+ """.stripMargin
+ execute(input, check, Seq(dontDedup("A")))
+ }
+ "The module A and A_" should "be deduped even with different port names and info, and annotations should remap" in {
+ val input =
+ """circuit Top :
+ | module Top :
+ | output out: UInt<1>
+ | inst a1 of A
+ | inst a2 of A_
+ | out <= and(a1.x, a2.y)
+ | module A : @[yy 2:2]
+ | output x: UInt<1> @[yy 2:2]
+ | x <= UInt(1)
+ | module A_ : @[xx 1:1]
+ | output y: UInt<1> @[xx 1:1]
+ | y <= UInt(1)
+ """.stripMargin
+ val check =
+ """circuit Top :
+ | module Top :
+ | output out: UInt<1>
+ | inst a1 of A
+ | inst a2 of A
+ | out <= and(a1.x, a2.x)
+ | module A : @[yy 2:2]
+ | output x: UInt<1> @[yy 2:2]
+ | x <= UInt(1)
+ """.stripMargin
+ case class DummyAnnotation(target: ComponentName) extends SingleTargetAnnotation[ComponentName] {
+ override def duplicate(n: ComponentName): Annotation = DummyAnnotation(n)
+ }
+
+ val mname = ModuleName("Top", CircuitName("Top"))
+ val finalState = execute(input, check, Seq(DummyAnnotation(ComponentName("a2.y", mname))))
+
+ finalState.annotations.collect({ case d: DummyAnnotation => d }).head should be(DummyAnnotation(ComponentName("a2.x", mname)))
+
+ }
+ "The module A and B" should "be deduped with the first module in order" in {
+ val input =
+ """circuit Top :
+ | module Top :
+ | inst a1 of A
+ | inst a2 of A_
+ | module A :
+ | output x: UInt<1>
+ | inst b of B_
+ | x <= b.x
+ | module A_ :
+ | output x: UInt<1>
+ | inst b of B
+ | x <= b.x
+ | module B :
+ | output x: UInt<1>
+ | x <= UInt(1)
+ | module B_ :
+ | output x: UInt<1>
+ | x <= UInt(1)
+ """.stripMargin
+ val check =
+ """circuit Top :
+ | module Top :
+ | inst a1 of A
+ | inst a2 of A
+ | module A :
+ | output x: UInt<1>
+ | inst b of B
+ | x <= b.x
+ | module B :
+ | output x: UInt<1>
+ | x <= UInt(1)
+ """.stripMargin
+ execute(input, check, Seq.empty)
+ }
}
// Execution driven tests for inlining modules
diff --git a/src/test/scala/firrtlTests/transforms/GroupComponentsSpec.scala b/src/test/scala/firrtlTests/transforms/GroupComponentsSpec.scala
new file mode 100644
index 00000000..3a32ec71
--- /dev/null
+++ b/src/test/scala/firrtlTests/transforms/GroupComponentsSpec.scala
@@ -0,0 +1,290 @@
+package firrtlTests
+package transforms
+
+import firrtl.annotations.{CircuitName, ComponentName, ModuleName}
+import firrtl.transforms.{GroupAnnotation, GroupComponents}
+
+class GroupComponentsSpec extends LowTransformSpec {
+ def transform = new GroupComponents()
+ val top = "Top"
+ def topComp(name: String): ComponentName = ComponentName(name, ModuleName(top, CircuitName(top)))
+ "The register r" should "be grouped" in {
+ val input =
+ s"""circuit $top :
+ | module $top :
+ | input clk: Clock
+ | input data: UInt<16>
+ | output out: UInt<16>
+ | reg r: UInt<16>, clk
+ | r <= data
+ | out <= r
+ """.stripMargin
+ val groups = Seq(
+ GroupAnnotation(Seq(topComp("r")), "MyReg", "rInst", Some("_OUT"), Some("_IN"))
+ )
+ val check =
+ s"""circuit Top :
+ | module $top :
+ | input clk: Clock
+ | input data: UInt<16>
+ | output out: UInt<16>
+ | inst rInst of MyReg
+ | rInst.clk_IN <= clk
+ | out <= rInst.r_OUT
+ | rInst.data_IN <= data
+ | module MyReg :
+ | input clk_IN: Clock
+ | output r_OUT: UInt<16>
+ | input data_IN: UInt<16>
+ | reg r: UInt<16>, clk_IN
+ | r_OUT <= r
+ | r <= data_IN
+ """.stripMargin
+ execute(input, check, groups)
+ }
+
+ "The two sets of instances" should "be grouped" in {
+ val input =
+ s"""circuit $top :
+ | module $top :
+ | output out: UInt<16>
+ | inst c1a of Const1A
+ | inst c2a of Const2A
+ | inst c1b of Const1B
+ | inst c2b of Const2B
+ | node asum = add(c1a.out, c2a.out)
+ | node bsum = add(c1b.out, c2b.out)
+ | out <= add(asum, bsum)
+ | module Const1A :
+ | output out: UInt<8>
+ | out <= UInt(1)
+ | module Const2A :
+ | output out: UInt<8>
+ | out <= UInt(2)
+ | module Const1B :
+ | output out: UInt<8>
+ | out <= UInt(1)
+ | module Const2B :
+ | output out: UInt<8>
+ | out <= UInt(2)
+ """.stripMargin
+ val groups = Seq(
+ GroupAnnotation(Seq(topComp("c1a"), topComp("c2a")/*, topComp("asum")*/), "A", "cA", Some("_OUT"), Some("_IN")),
+ GroupAnnotation(Seq(topComp("c1b"), topComp("c2b")/*, topComp("bsum")*/), "B", "cB", Some("_OUT"), Some("_IN"))
+ )
+ val check =
+ s"""circuit Top :
+ | module $top :
+ | output out: UInt<16>
+ | inst cA of A
+ | inst cB of B
+ | node asum = add(cA.c1a_out_OUT, cA.c2a_out_OUT)
+ | node bsum = add(cB.c1b_out_OUT, cB.c2b_out_OUT)
+ | out <= add(asum, bsum)
+ | module A :
+ | output c1a_out_OUT: UInt<8>
+ | output c2a_out_OUT: UInt<8>
+ | inst c1a of Const1A
+ | inst c2a of Const2A
+ | c1a_out_OUT <= c1a.out
+ | c2a_out_OUT <= c2a.out
+ | module B :
+ | output c1b_out_OUT: UInt<8>
+ | output c2b_out_OUT: UInt<8>
+ | inst c1b of Const1B
+ | inst c2b of Const2B
+ | c1b_out_OUT <= c1b.out
+ | c2b_out_OUT <= c2b.out
+ | module Const1A :
+ | output out: UInt<8>
+ | out <= UInt(1)
+ | module Const2A :
+ | output out: UInt<8>
+ | out <= UInt(2)
+ | module Const1B :
+ | output out: UInt<8>
+ | out <= UInt(1)
+ | module Const2B :
+ | output out: UInt<8>
+ | out <= UInt(2)
+ """.stripMargin
+ execute(input, check, groups)
+ }
+ "The two sets of instances" should "be grouped with their nodes" in {
+ val input =
+ s"""circuit $top :
+ | module $top :
+ | output out: UInt<16>
+ | inst c1a of Const1A
+ | inst c2a of Const2A
+ | inst c1b of Const1B
+ | inst c2b of Const2B
+ | node asum = add(c1a.out, c2a.out)
+ | node bsum = add(c1b.out, c2b.out)
+ | out <= add(asum, bsum)
+ | module Const1A :
+ | output out: UInt<8>
+ | out <= UInt(1)
+ | module Const2A :
+ | output out: UInt<8>
+ | out <= UInt(2)
+ | module Const1B :
+ | output out: UInt<8>
+ | out <= UInt(1)
+ | module Const2B :
+ | output out: UInt<8>
+ | out <= UInt(2)
+ """.stripMargin
+ val groups = Seq(
+ GroupAnnotation(Seq(topComp("c1a"), topComp("c2a"), topComp("asum")), "A", "cA", Some("_OUT"), Some("_IN")),
+ GroupAnnotation(Seq(topComp("c1b"), topComp("c2b"), topComp("bsum")), "B", "cB", Some("_OUT"), Some("_IN"))
+ )
+ val check =
+ s"""circuit Top :
+ | module $top :
+ | output out: UInt<16>
+ | inst cA of A
+ | inst cB of B
+ | out <= add(cA.asum_OUT, cB.bsum_OUT)
+ | module A :
+ | output asum_OUT: UInt<9>
+ | inst c1a of Const1A
+ | inst c2a of Const2A
+ | node asum = add(c1a.out, c2a.out)
+ | asum_OUT <= asum
+ | module B :
+ | output bsum_OUT: UInt<9>
+ | inst c1b of Const1B
+ | inst c2b of Const2B
+ | node bsum = add(c1b.out, c2b.out)
+ | bsum_OUT <= bsum
+ | module Const1A :
+ | output out: UInt<8>
+ | out <= UInt(1)
+ | module Const2A :
+ | output out: UInt<8>
+ | out <= UInt(2)
+ | module Const1B :
+ | output out: UInt<8>
+ | out <= UInt(1)
+ | module Const2B :
+ | output out: UInt<8>
+ | out <= UInt(2)
+ """.stripMargin
+ execute(input, check, groups)
+ }
+
+ "The two sets of instances" should "be grouped with one not grouped" in {
+ val input =
+ s"""circuit $top :
+ | module $top :
+ | output out: UInt<16>
+ | inst c1a of Const1A
+ | inst c2a of Const2A
+ | inst c1b of Const1B
+ | inst c2b of Const2B
+ | node asum = add(c1a.out, c2a.out)
+ | node bsum = add(c1b.out, c2b.out)
+ | inst pass of PassThrough
+ | pass.in <= add(asum, bsum)
+ | out <= pass.out
+ | module Const1A :
+ | output out: UInt<8>
+ | out <= UInt(1)
+ | module Const2A :
+ | output out: UInt<8>
+ | out <= UInt(2)
+ | module Const1B :
+ | output out: UInt<8>
+ | out <= UInt(1)
+ | module Const2B :
+ | output out: UInt<8>
+ | out <= UInt(2)
+ | module PassThrough :
+ | input in: UInt
+ | output out: UInt
+ | out <= in
+ """.stripMargin
+ val groups = Seq(
+ GroupAnnotation(Seq(topComp("c1a"), topComp("c2a"), topComp("asum")), "A", "cA", Some("_OUT"), Some("_IN")),
+ GroupAnnotation(Seq(topComp("c1b"), topComp("c2b"), topComp("bsum")), "B", "cB", Some("_OUT"), Some("_IN"))
+ )
+ val check =
+ s"""circuit Top :
+ | module $top :
+ | output out: UInt<16>
+ | inst cA of A
+ | inst cB of B
+ | inst pass of PassThrough
+ | out <= pass.out
+ | pass.in <= add(cA.asum_OUT, cB.bsum_OUT)
+ | module A :
+ | output asum_OUT: UInt<9>
+ | inst c1a of Const1A
+ | inst c2a of Const2A
+ | node asum = add(c1a.out, c2a.out)
+ | asum_OUT <= asum
+ | module B :
+ | output bsum_OUT: UInt<9>
+ | inst c1b of Const1B
+ | inst c2b of Const2B
+ | node bsum = add(c1b.out, c2b.out)
+ | bsum_OUT <= bsum
+ | module Const1A :
+ | output out: UInt<8>
+ | out <= UInt(1)
+ | module Const2A :
+ | output out: UInt<8>
+ | out <= UInt(2)
+ | module Const1B :
+ | output out: UInt<8>
+ | out <= UInt(1)
+ | module Const2B :
+ | output out: UInt<8>
+ | out <= UInt(2)
+ | module PassThrough :
+ | input in: UInt<10>
+ | output out: UInt<10>
+ | out <= in
+ """.stripMargin
+ execute(input, check, groups)
+ }
+
+ "The two sets of instances" should "be grouped with a connection between them" in {
+ val input =
+ s"""circuit $top :
+ | module $top :
+ | input in: UInt<16>
+ | output out: UInt<16>
+ | node first = in
+ | node second = not(first)
+ | out <= second
+ """.stripMargin
+ val groups = Seq(
+ GroupAnnotation(Seq(topComp("first")), "First", "first"),
+ GroupAnnotation(Seq(topComp("second")), "Second", "second")
+ )
+ val check =
+ s"""circuit $top :
+ | module $top :
+ | input in: UInt<16>
+ | output out: UInt<16>
+ | inst first_0 of First
+ | inst second_0 of Second
+ | first_0.in <= in
+ | second_0.first <= first_0.first_0
+ | out <= second_0.second_0
+ | module First :
+ | input in: UInt<16>
+ | output first_0: UInt<16>
+ | node first = in
+ | first_0 <= first
+ | module Second :
+ | input first: UInt<16>
+ | output second_0: UInt<16>
+ | node second = not(first)
+ | second_0 <= second
+ """.stripMargin
+ execute(input, check, groups)
+ }
+}