diff options
| author | Schuyler Eldridge | 2020-02-10 14:14:43 -0500 |
|---|---|---|
| committer | GitHub | 2020-02-10 14:14:43 -0500 |
| commit | 1b475c42ebfeb279c0fba013cadbb00545ecaa8f (patch) | |
| tree | 78f40aed32968ec2c26f2c58bcfb7b8bd5fec7c4 | |
| parent | dc9709c55bfa9f2dc7ee9a400e141ce5deb7269c (diff) | |
| parent | bcbe60dec0c92b22f7aa98669cdec21c3111acd4 (diff) | |
Merge pull request #1370 from freechipsproject/issue-1309
Rename Modules Duplicated by EliminateTargetPaths
3 files changed, 49 insertions, 1 deletions
diff --git a/src/main/scala/firrtl/annotations/Target.scala b/src/main/scala/firrtl/annotations/Target.scala index 1571f98e..c7cb98d2 100644 --- a/src/main/scala/firrtl/annotations/Target.scala +++ b/src/main/scala/firrtl/annotations/Target.scala @@ -185,6 +185,19 @@ object Target { } }.tryToComplete } + + /** Returns the module that a [[Target]] "refers" to. + * + * For a [[ModuleTarget]] or a [[ReferenceTarget]], this is simply the deepest module. For an [[InstanceTarget]] this + * is *the module of the instance*. + * + * @note This differs from [[InstanceTarget.pathlessTarget]] which refers to the module instantiating the instance. + */ + def referringModule(a: IsMember): ModuleTarget = a match { + case b: ModuleTarget => b + case b: InstanceTarget => b.ofModuleTarget + case b: ReferenceTarget => b.pathlessTarget.moduleTarget + } } /** Represents incomplete or non-standard [[Target]]s diff --git a/src/main/scala/firrtl/annotations/transforms/EliminateTargetPaths.scala b/src/main/scala/firrtl/annotations/transforms/EliminateTargetPaths.scala index 2f20430b..e40b80f8 100644 --- a/src/main/scala/firrtl/annotations/transforms/EliminateTargetPaths.scala +++ b/src/main/scala/firrtl/annotations/transforms/EliminateTargetPaths.scala @@ -4,6 +4,7 @@ package firrtl.annotations.transforms import firrtl.Mappers._ import firrtl.analyses.InstanceGraph +import firrtl.annotations.ModuleTarget import firrtl.annotations.TargetToken.{Instance, OfModule} import firrtl.annotations.analysis.DuplicationHelper import firrtl.annotations._ @@ -114,16 +115,26 @@ class EliminateTargetPaths extends Transform { val finalModuleList = duplicatedModuleList.filter(m => newUsedOfModules.contains(m.name) || (!newUsedOfModules.contains(m.name) && !oldUsedOfModules.contains(m.name)) ) + lazy val finalModuleSet = finalModuleList.map{ case a: DefModule => a.name }.toSet // Records how targets have been renamed val renameMap = RenameMap() - // Foreach target, calculate the pathless version and only rename targets that are instantiated + /* Foreach target, calculate the pathless version and only rename targets that are instantiated. Additionally, rename + * module targets + */ targets.foreach { t => val newTsx = dupMap.makePathless(t) val newTs = newTsx.filter(c => newUsedOfModules.contains(c.moduleOpt.get)) if(newTs.nonEmpty) { renameMap.record(t, newTs) + val m = Target.referringModule(t) + val duplicatedModules = newTs.map(Target.referringModule) + val oldModule: Option[ModuleTarget] = m match { + case a: ModuleTarget if finalModuleSet(a.module) => Some(a) + case _ => None + } + renameMap.record(m, (duplicatedModules ++ oldModule).distinct) } } diff --git a/src/test/scala/firrtlTests/annotationTests/EliminateTargetPathsSpec.scala b/src/test/scala/firrtlTests/annotationTests/EliminateTargetPathsSpec.scala index 7aac277f..9d7df718 100644 --- a/src/test/scala/firrtlTests/annotationTests/EliminateTargetPathsSpec.scala +++ b/src/test/scala/firrtlTests/annotationTests/EliminateTargetPathsSpec.scala @@ -372,4 +372,28 @@ class EliminateTargetPathsSpec extends FirrtlPropSpec with FirrtlMatchers { .annotations .collect{ case a: firrtl.annotations.transforms.ResolvePaths => a } should be (empty) } + + property("It should rename module annotations") { + val input = + """|circuit Foo: + | module Bar: + | node x = UInt<1>(0) + | skip + | module Foo: + | inst bar of Bar""".stripMargin + val Bar_x = CircuitTarget("Foo").module("Bar").ref("x") + val output = CircuitState(passes.ToWorkingIR.run(Parser.parse(input)), UnknownForm, Seq(DontTouchAnnotation(Bar_x))) + .resolvePaths(Seq(CircuitTarget("Foo").module("Foo").instOf("bar", "Bar"))) + + info(output.circuit.serialize) + + val newBar_x = CircuitTarget("Foo").module("Bar___Foo_bar").ref("x") + + output + .annotations + .filter{ + case _: DeletedAnnotation => false + case _ => true + } should contain (DontTouchAnnotation(newBar_x)) + } } |
