aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlbert Magyar2020-05-17 23:18:20 -0700
committerAlbert Magyar2020-06-04 22:25:12 -0700
commit14099e1d6b7937206cfc5309cbb0e044afc358d0 (patch)
tree94e4d331ceec8785ea293a8e4f8f26016e466afe /src
parentb7483348abbd9de30b206ab43dea803d32b334b8 (diff)
Add test case for retype-based component renaming in DedupModules
Diffstat (limited to 'src')
-rw-r--r--src/test/scala/firrtlTests/transforms/DedupTests.scala54
1 files changed, 54 insertions, 0 deletions
diff --git a/src/test/scala/firrtlTests/transforms/DedupTests.scala b/src/test/scala/firrtlTests/transforms/DedupTests.scala
index 6e0be81d..bb12c759 100644
--- a/src/test/scala/firrtlTests/transforms/DedupTests.scala
+++ b/src/test/scala/firrtlTests/transforms/DedupTests.scala
@@ -3,6 +3,7 @@
package firrtlTests
package transforms
+import firrtl._
import firrtl.RenameMap
import firrtl.annotations._
import firrtl.transforms.{DedupModules, NoCircuitDedupAnnotation}
@@ -761,5 +762,58 @@ class DedupModuleTests extends HighTransformSpec {
),0))
cs.deletedAnnotations.isEmpty should be (true)
}
+
+ "dedup" should "properly rename target components after retyping" in {
+ val input = """
+ |circuit top:
+ | module top:
+ | input ia: {z: {y: {x: UInt<1>}}, a: UInt<1>}
+ | input ib: {a: {b: {c: UInt<1>}}, z: UInt<1>}
+ | output oa: {z: {y: {x: UInt<1>}}, a: UInt<1>}
+ | output ob: {a: {b: {c: UInt<1>}}, z: UInt<1>}
+ | inst a of a
+ | a.i <= ia
+ | oa <= a.o
+ | inst b of b
+ | b.q <= ib
+ | ob <= b.r
+ | module a:
+ | input i: {z: {y: {x: UInt<1>}}, a: UInt<1>}
+ | output o: {z: {y: {x: UInt<1>}}, a: UInt<1>}
+ | o <= i
+ | module b:
+ | input q: {a: {b: {c: UInt<1>}}, z: UInt<1>}
+ | output r: {a: {b: {c: UInt<1>}}, z: UInt<1>}
+ | r <= q
+ |""".stripMargin
+
+ case class DummyRTAnnotation(target: ReferenceTarget) extends SingleTargetAnnotation[ReferenceTarget] {
+ def duplicate(n: ReferenceTarget) = DummyRTAnnotation(n)
+ }
+
+ val annA = DummyRTAnnotation(ReferenceTarget("top", "a", Nil, "i", Seq(TargetToken.Field("a"))))
+ val annB = DummyRTAnnotation(ReferenceTarget("top", "b", Nil, "q", Seq(TargetToken.Field("a"))))
+
+
+ val cs = CircuitState(Parser.parseString(input, Parser.IgnoreInfo), Seq(annA, annB))
+
+ val deduper = new stage.transforms.Compiler(stage.Forms.Deduped, Nil)
+ val csDeduped = deduper.execute(cs)
+
+ /*
+ During dedup, input q of b gets "retyped." The connections get updated to reflect this
+ retyping, and annotations with a non-empty "component" must get renamed to reflect this
+ retyping. Since the "retyping" maps b.q.a onto a.i.z in its structural significance and
+ connection, and since failure to rename "component" will result in annotations that are
+ fundamentally illegal, the deduplication of these modules (if it occurs) must include a rename
+ mapping from ~top|b>q.a to ~top|a>i.z to best capture the retyping.
+ */
+ val aPath = Seq((TargetToken.Instance("a"), TargetToken.OfModule("a")))
+ val bPath = Seq((TargetToken.Instance("b"), TargetToken.OfModule("a")))
+ val expectedAnnA = DummyRTAnnotation(ReferenceTarget("top", "top", aPath, "i", Seq(TargetToken.Field("a"))))
+ val expectedAnnB = DummyRTAnnotation(ReferenceTarget("top", "top", aPath, "i", Seq(TargetToken.Field("a"))))
+ csDeduped.annotations.toSeq should contain (expectedAnnA)
+ csDeduped.annotations.toSeq should contain (expectedAnnB)
+ }
}