diff options
Diffstat (limited to 'src/main/scala/firrtl/annotations')
| -rw-r--r-- | src/main/scala/firrtl/annotations/TargetUtils.scala | 46 |
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) + } +} |
