diff options
| author | Albert Magyar | 2020-05-17 23:18:20 -0700 |
|---|---|---|
| committer | Albert Magyar | 2020-06-04 22:25:12 -0700 |
| commit | 14099e1d6b7937206cfc5309cbb0e044afc358d0 (patch) | |
| tree | 94e4d331ceec8785ea293a8e4f8f26016e466afe /src | |
| parent | b7483348abbd9de30b206ab43dea803d32b334b8 (diff) | |
Add test case for retype-based component renaming in DedupModules
Diffstat (limited to 'src')
| -rw-r--r-- | src/test/scala/firrtlTests/transforms/DedupTests.scala | 54 |
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) + } } |
