diff options
| author | Albert Magyar | 2018-06-28 22:15:28 -0700 |
|---|---|---|
| committer | Jack Koenig | 2018-06-28 22:15:28 -0700 |
| commit | 4ee238fc482aab582130cc4c3bb067cc3e872ce4 (patch) | |
| tree | 98e6fa5a1789c3d52d03510661c009b9ee450fbd /src | |
| parent | 3243f05a69b4b77761699be412f349a9b8b9193f (diff) | |
Make CheckCombLoops find combinational nodes with self-edges (#837)
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/scala/firrtl/transforms/CheckCombLoops.scala | 8 | ||||
| -rw-r--r-- | src/test/scala/firrtlTests/CheckCombLoopsSpec.scala | 15 |
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 : |
