diff options
| author | Donggyu Kim | 2016-08-30 18:51:17 -0700 |
|---|---|---|
| committer | Donggyu Kim | 2016-09-07 16:58:06 -0700 |
| commit | d7bf6fb7b415d35f967d247119b8975c3dc885a3 (patch) | |
| tree | be6afdc75f2f209f4a412d5aafae5015da98cc2a /src/main/scala/firrtl/Utils.scala | |
| parent | 296a65ebb895d100c3cbde6df7c0303d6942e5d5 (diff) | |
refactor checks
Diffstat (limited to 'src/main/scala/firrtl/Utils.scala')
| -rw-r--r-- | src/main/scala/firrtl/Utils.scala | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/src/main/scala/firrtl/Utils.scala b/src/main/scala/firrtl/Utils.scala index ea8ff4b7..29c37294 100644 --- a/src/main/scala/firrtl/Utils.scala +++ b/src/main/scala/firrtl/Utils.scala @@ -662,3 +662,56 @@ class MemoizedHash[T](val t: T) { case _ => false } } + +/** + * Maintains a one to many graph of each modules instantiated child module. + * This graph can be searched for a path from a child module back to one of + * it's parents. If one is found a recursive loop has happened + * The graph is a map between the name of a node to set of names of that nodes children + */ +class ModuleGraph { + val nodes = HashMap[String, HashSet[String]]() + + /** + * Add a child to a parent node + * A parent node is created if it does not already exist + * + * @param parent module that instantiates another module + * @param child module instantiated by parent + * @return a list indicating a path from child to parent, empty if no such path + */ + def add(parent: String, child: String): List[String] = { + val childSet = nodes.getOrElseUpdate(parent, new HashSet[String]) + childSet += child + pathExists(child, parent, List(child, parent)) + } + + /** + * Starting at the name of a given child explore the tree of all children in depth first manner. + * Return the first path (a list of strings) that goes from child to parent, + * or an empty list of no such path is found. + * + * @param child starting name + * @param parent name to find in children (recursively) + * @param path + * @return + */ + def pathExists(child: String, parent: String, path: List[String] = Nil): List[String] = { + nodes.get(child) match { + case Some(children) => + if(children(parent)) { + parent :: path + } + else { + children.foreach { grandchild => + val newPath = pathExists(grandchild, parent, grandchild :: path) + if(newPath.nonEmpty) { + return newPath + } + } + Nil + } + case _ => Nil + } + } +} |
