From 72427067ebb870d021b748d55fe09aa9761f6410 Mon Sep 17 00:00:00 2001 From: Schuyler Eldridge Date: Fri, 7 Feb 2020 14:54:58 -0500 Subject: Add Target utility referringModule This adds a utility method, referringModule, to the Target object that behaves like IsMember.pathlessTarget except that it returns the module of an InstanceTarget. This is useful for situations where you want to get at "the module" a target is pointing at, but you want behavior to get an actual module from an instance. Signed-off-by: Schuyler Eldridge --- src/main/scala/firrtl/annotations/Target.scala | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src') 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 -- cgit v1.2.3 From 64762d2e064917233b24d193e487fc6a03f11ad2 Mon Sep 17 00:00:00 2001 From: Schuyler Eldridge Date: Fri, 7 Feb 2020 14:57:51 -0500 Subject: Rename modules when duplicating instances Change the behavior of EliminateTargetPaths to generate ModuleTarget renames when instances are duplicated. Previously, only InstanceTarget renames would be generated. In effect, annotations targeting a duplicated module when be duplicated to point at the original and duplicated module. Signed-off-by: Schuyler Eldridge --- .../annotations/transforms/EliminateTargetPaths.scala | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'src') 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) } } -- cgit v1.2.3 From bcbe60dec0c92b22f7aa98669cdec21c3111acd4 Mon Sep 17 00:00:00 2001 From: Schuyler Eldridge Date: Fri, 7 Feb 2020 14:59:27 -0500 Subject: Test EliminateTargetPaths ModuleTarget anno duping Add a test that EliminateTargetPaths properly duplicates an annotation pointing at a ModuleTarget. Signed-off-by: Schuyler Eldridge --- .../annotationTests/EliminateTargetPathsSpec.scala | 24 ++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'src') 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)) + } } -- cgit v1.2.3