diff options
| author | Adam Izraelevitz | 2018-03-21 14:24:25 -0700 |
|---|---|---|
| committer | GitHub | 2018-03-21 14:24:25 -0700 |
| commit | 6ea4ac666e4ce8dfaca1545660f372fccff610f5 (patch) | |
| tree | 8f2125855557962d642386fe8b49ed0396f562c2 /src/test | |
| parent | 6b195e4a5348eed2e714e1183024588c5f91a283 (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.scala | 2 | ||||
| -rw-r--r-- | src/test/scala/firrtlTests/PassTests.scala | 3 | ||||
| -rw-r--r-- | src/test/scala/firrtlTests/transforms/DedupTests.scala | 336 | ||||
| -rw-r--r-- | src/test/scala/firrtlTests/transforms/GroupComponentsSpec.scala | 290 |
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) + } +} |
