aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlbert Magyar2018-06-28 22:15:28 -0700
committerJack Koenig2018-06-28 22:15:28 -0700
commit4ee238fc482aab582130cc4c3bb067cc3e872ce4 (patch)
tree98e6fa5a1789c3d52d03510661c009b9ee450fbd /src
parent3243f05a69b4b77761699be412f349a9b8b9193f (diff)
Make CheckCombLoops find combinational nodes with self-edges (#837)
Diffstat (limited to 'src')
-rw-r--r--src/main/scala/firrtl/transforms/CheckCombLoops.scala8
-rw-r--r--src/test/scala/firrtlTests/CheckCombLoopsSpec.scala15
2 files changed, 21 insertions, 2 deletions
diff --git a/src/main/scala/firrtl/transforms/CheckCombLoops.scala b/src/main/scala/firrtl/transforms/CheckCombLoops.scala
index a4dad11b..e1e6cf63 100644
--- a/src/main/scala/firrtl/transforms/CheckCombLoops.scala
+++ b/src/main/scala/firrtl/transforms/CheckCombLoops.scala
@@ -199,8 +199,12 @@ class CheckCombLoops extends Transform {
val moduleGraph = DiGraph(internalDeps)
moduleGraphs(m.name) = moduleGraph
simplifiedModuleGraphs(m.name) = moduleGraphs(m.name).simplify((m.ports map { p => LogicNode(p.name) }).toSet)
- for (scc <- moduleGraphs(m.name).findSCCs.filter(_.length > 1)) {
- val sccSubgraph = moduleGraphs(m.name).subgraph(scc.toSet)
+ // Find combinational nodes with self-edges; this is *NOT* the same as length-1 SCCs!
+ for (unitLoopNode <- moduleGraph.getVertices.filter(v => moduleGraph.getEdges(v).contains(v))) {
+ errors.append(new CombLoopException(m.info, m.name, Seq(unitLoopNode.name)))
+ }
+ for (scc <- moduleGraph.findSCCs.filter(_.length > 1)) {
+ val sccSubgraph = moduleGraph.subgraph(scc.toSet)
val cycle = findCycleInSCC(sccSubgraph)
(cycle zip cycle.tail).foreach({ case (a,b) => require(moduleGraph.getEdges(a).contains(b)) })
val expandedCycle = expandInstancePaths(m.name, moduleGraphs, moduleDeps, Seq(m.name), cycle.reverse)
diff --git a/src/test/scala/firrtlTests/CheckCombLoopsSpec.scala b/src/test/scala/firrtlTests/CheckCombLoopsSpec.scala
index 06cbb8e4..d09b4d06 100644
--- a/src/test/scala/firrtlTests/CheckCombLoopsSpec.scala
+++ b/src/test/scala/firrtlTests/CheckCombLoopsSpec.scala
@@ -70,6 +70,21 @@ class CheckCombLoopsSpec extends SimpleTransformSpec {
}
}
+ "Single-element combinational loop" should "throw an exception" in {
+ val input = """circuit loop :
+ | module loop :
+ | output y : UInt<8>
+ | wire w : UInt<8>
+ | w <= w
+ | y <= w
+ |""".stripMargin
+
+ val writer = new java.io.StringWriter
+ intercept[CheckCombLoops.CombLoopException] {
+ compile(CircuitState(parse(input), ChirrtlForm), writer)
+ }
+ }
+
"Node combinational loop" should "throw an exception" in {
val input = """circuit hasloops :
| module hasloops :