aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/firrtl/annotations
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/scala/firrtl/annotations')
-rw-r--r--src/main/scala/firrtl/annotations/TargetUtils.scala46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/main/scala/firrtl/annotations/TargetUtils.scala b/src/main/scala/firrtl/annotations/TargetUtils.scala
new file mode 100644
index 00000000..164c430b
--- /dev/null
+++ b/src/main/scala/firrtl/annotations/TargetUtils.scala
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: Apache-2.0
+
+package firrtl.annotations
+
+import firrtl._
+import firrtl.analyses.InstanceKeyGraph
+import firrtl.analyses.InstanceKeyGraph.InstanceKey
+import firrtl.annotations.TargetToken._
+
+object TargetUtils {
+
+ /** Turns an instance path into a corresponding [[IsModule]]
+ *
+ * @note First InstanceKey is treated as the [[CircuitTarget]]
+ * @param path Instance path
+ * @param start Module in instance path to be starting [[ModuleTarget]]
+ * @return [[IsModule]] corresponding to Instance path
+ */
+ def instKeyPathToTarget(path: Seq[InstanceKey], start: Option[String] = None): IsModule = {
+ val head = path.head
+ val startx = start.getOrElse(head.module)
+ val top: IsModule = CircuitTarget(head.module).module(startx) // ~Top|Start
+ val pathx = path.dropWhile(_.module != startx)
+ if (pathx.isEmpty) top
+ else pathx.tail.foldLeft(top) { case (acc, key) => acc.instOf(key.name, key.module) }
+ }
+
+ /** Calculates all [[InstanceTarget]]s that refer to the given [[IsModule]]
+ *
+ * {{{
+ * ~Top|Top/a:A/b:B/c:C unfolds to:
+ * * ~Top|Top/a:A/b:B/c:C
+ * * ~Top|A/b:B/c:C
+ * * ~Top|B/c:C
+ * }}}
+ * @note [[ModuleTarget]] arguments return an empty Iterable
+ */
+ def unfoldInstanceTargets(ismod: IsModule): Iterable[InstanceTarget] = {
+ // concretely use List which is fast in practice
+ def rec(im: IsModule): List[InstanceTarget] = im match {
+ case inst: InstanceTarget => inst :: rec(inst.stripHierarchy(1))
+ case _ => Nil
+ }
+ rec(ismod)
+ }
+}