diff options
| author | Schuyler Eldridge | 2020-06-02 16:43:02 -0400 |
|---|---|---|
| committer | Schuyler Eldridge | 2020-06-25 13:46:15 -0400 |
| commit | 305e9da16392f5ce8c3532469eea271c1d0b6654 (patch) | |
| tree | c0521247fd995bbe8753fa22ded6b6fa30eb2ab9 /src | |
| parent | 4c0ab1892c683d5b96708d39a239eee214e702b8 (diff) | |
Test ManipulateNamesSpec
Add tests for the ManipulateNames transform.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@ibm.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/test/scala/firrtlTests/transforms/ManipulateNamesSpec.scala | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/src/test/scala/firrtlTests/transforms/ManipulateNamesSpec.scala b/src/test/scala/firrtlTests/transforms/ManipulateNamesSpec.scala new file mode 100644 index 00000000..82cc997d --- /dev/null +++ b/src/test/scala/firrtlTests/transforms/ManipulateNamesSpec.scala @@ -0,0 +1,176 @@ +// See LICENSE for license details. + +package firrtlTests.transforms + +import firrtl.{ir, CircuitState, FirrtlUserException, Namespace, Parser} +import firrtl.annotations.CircuitTarget +import firrtl.options.Dependency +import firrtl.testutils.FirrtlCheckers._ +import firrtl.transforms.{ + ManipulateNames, + ManipulateNamesBlocklistAnnotation, + ManipulateNamesAllowlistAnnotation +} + +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers + +object ManipulateNamesSpec { + + class AddPrefix extends ManipulateNames { + override def manipulate = (a: String, b: Namespace) => Some(b.newName("prefix_" + a)) + } + +} + +class ManipulateNamesSpec extends AnyFlatSpec with Matchers { + + import ManipulateNamesSpec._ + + class CircuitFixture { + protected val input = + """|circuit Foo: + | module Bar: + | node a = UInt<1>(0) + | module Foo: + | inst bar of Bar + | inst bar2 of Bar + |""".stripMargin + val `~Foo` = CircuitTarget("Foo") + val `~Foo|Foo` = `~Foo`.module("Foo") + val `~Foo|Foo/bar:Bar` = `~Foo|Foo`.instOf("bar", "Bar") + val `~Foo|Foo/bar2:Bar` = `~Foo|Foo`.instOf("bar2", "Bar") + val `~Foo|Bar` = `~Foo`.module("Bar") + val `~Foo|Bar>a` = `~Foo|Bar`.ref("a") + val tm = new firrtl.stage.transforms.Compiler(Seq(Dependency[AddPrefix])) + } + + behavior of "ManipulateNames" + + it should "rename everything by default" in new CircuitFixture { + val state = CircuitState(Parser.parse(input), Seq.empty) + val statex = tm.execute(state) + val expected: Seq[PartialFunction[Any, Boolean]] = Seq( + { case ir.Circuit(_, _, "prefix_Foo") => true }, + { case ir.Module(_, "prefix_Foo", _, _) => true}, + { case ir.Module(_, "prefix_Bar", _, _) => true} + ) + expected.foreach(statex should containTree (_)) + } + + it should "do nothing if the circuit is blocklisted" in new CircuitFixture { + val annotations = Seq(ManipulateNamesBlocklistAnnotation(Seq(Seq(`~Foo`)), Dependency[AddPrefix])) + val state = CircuitState(Parser.parse(input), annotations) + val statex = tm.execute(state) + state.circuit.serialize should be (statex.circuit.serialize) + } + + it should "not rename the circuit if the top module is blocklisted" in new CircuitFixture { + val annotations = Seq(ManipulateNamesBlocklistAnnotation(Seq(Seq(`~Foo|Foo`)), Dependency[AddPrefix])) + val state = CircuitState(Parser.parse(input), annotations) + val expected: Seq[PartialFunction[Any, Boolean]] = Seq( + { case ir.Circuit(_, _, "Foo") => true }, + { case ir.Module(_, "Foo", _, _) => true}, + { case ir.Module(_, "prefix_Bar", _, _) => true} + ) + val statex = tm.execute(state) + expected.foreach(statex should containTree (_)) + } + + it should "not rename instances if blocklisted" in new CircuitFixture { + val annotations = Seq(ManipulateNamesBlocklistAnnotation(Seq(Seq(`~Foo|Foo/bar:Bar`)), Dependency[AddPrefix])) + val state = CircuitState(Parser.parse(input), annotations) + val expected: Seq[PartialFunction[Any, Boolean]] = Seq( + { case ir.DefInstance(_, "bar", "prefix_Bar", _) => true}, + { case ir.Module(_, "prefix_Bar", _, _) => true} + ) + val statex = tm.execute(state) + expected.foreach(statex should containTree (_)) + } + + it should "do nothing if the circuit is not allowlisted" in new CircuitFixture { + val annotations = Seq( + ManipulateNamesAllowlistAnnotation(Seq(Seq(`~Foo|Foo`)), Dependency[AddPrefix]) + ) + val state = CircuitState(Parser.parse(input), annotations) + val statex = tm.execute(state) + state.circuit.serialize should be (statex.circuit.serialize) + } + + it should "rename only the circuit if allowlisted" in new CircuitFixture { + val annotations = Seq( + ManipulateNamesAllowlistAnnotation(Seq(Seq(`~Foo`)), Dependency[AddPrefix]), + ManipulateNamesAllowlistAnnotation(Seq(Seq(`~Foo|Foo`)), Dependency[AddPrefix]) + ) + val state = CircuitState(Parser.parse(input), annotations) + val statex = tm.execute(state) + val expected: Seq[PartialFunction[Any, Boolean]] = Seq( + { case ir.Circuit(_, _, "prefix_Foo") => true }, + { case ir.Module(_, "prefix_Foo", _, _) => true}, + { case ir.DefInstance(_, "bar", "Bar", _) => true}, + { case ir.DefInstance(_, "bar2", "Bar", _) => true}, + { case ir.Module(_, "Bar", _, _) => true}, + { case ir.DefNode(_, "a", _) => true} + ) + expected.foreach(statex should containTree (_)) + } + + it should "rename an instance via allowlisting" in new CircuitFixture { + val annotations = Seq( + ManipulateNamesAllowlistAnnotation(Seq(Seq(`~Foo`)), Dependency[AddPrefix]), + ManipulateNamesAllowlistAnnotation(Seq(Seq(`~Foo|Foo/bar:Bar`)), Dependency[AddPrefix]) + ) + val state = CircuitState(Parser.parse(input), annotations) + val statex = tm.execute(state) + val expected: Seq[PartialFunction[Any, Boolean]] = Seq( + { case ir.Circuit(_, _, "Foo") => true }, + { case ir.Module(_, "Foo", _, _) => true}, + { case ir.DefInstance(_, "prefix_bar", "Bar", _) => true}, + { case ir.DefInstance(_, "bar2", "Bar", _) => true}, + { case ir.Module(_, "Bar", _, _) => true}, + { case ir.DefNode(_, "a", _) => true} + ) + expected.foreach(statex should containTree (_)) + } + + it should "rename a node via allowlisting" in new CircuitFixture { + val annotations = Seq( + ManipulateNamesAllowlistAnnotation(Seq(Seq(`~Foo`)), Dependency[AddPrefix]), + ManipulateNamesAllowlistAnnotation(Seq(Seq(`~Foo|Bar>a`)), Dependency[AddPrefix]) + ) + val state = CircuitState(Parser.parse(input), annotations) + val statex = tm.execute(state) + val expected: Seq[PartialFunction[Any, Boolean]] = Seq( + { case ir.Circuit(_, _, "Foo") => true }, + { case ir.Module(_, "Foo", _, _) => true}, + { case ir.DefInstance(_, "bar", "Bar", _) => true}, + { case ir.DefInstance(_, "bar2", "Bar", _) => true}, + { case ir.Module(_, "Bar", _, _) => true}, + { case ir.DefNode(_, "prefix_a", _) => true} + ) + expected.foreach(statex should containTree (_)) + } + + it should "throw user errors on circuits that haven't been run through LowerTypes" in { + val input = + """|circuit Foo: + | module Foo: + | wire bar: {a: UInt<1>, b: UInt<1>} + | node baz = bar.a + |""".stripMargin + val state = CircuitState(Parser.parse(input), Seq.empty) + intercept [FirrtlUserException] { + (new AddPrefix).transform(state) + }.getMessage should include ("LowerTypes") + } + + behavior of "ManipulateNamesBlocklistAnnotation" + + it should "throw an exception if a non-local target is skipped" in new CircuitFixture { + val barA = CircuitTarget("Foo").module("Foo").instOf("bar", "Bar").ref("a") + assertThrows[java.lang.IllegalArgumentException]{ + Seq(ManipulateNamesBlocklistAnnotation(Seq(Seq(barA)), Dependency[AddPrefix])) + } + } + +} |
