Skip to content
This repository has been archived by the owner on Aug 20, 2024. It is now read-only.

PathNotFoundException in CheckCombLoops transform #2547

Open
5 tasks done
tymcauley opened this issue Aug 28, 2022 · 0 comments
Open
5 tasks done

PathNotFoundException in CheckCombLoops transform #2547

tymcauley opened this issue Aug 28, 2022 · 0 comments

Comments

@tymcauley
Copy link

tymcauley commented Aug 28, 2022

Checklist

  • Did you specify the current behavior?
  • Did you specify the expected behavior?
  • Did you provide a code example showing the problem?
  • Did you describe your environment?
  • Did you specify relevant external information?

What is the current behavior?

If you try to emit Verilog for the CycleTest module in the following design, the CheckCombLoops transform will throw a PathNotFoundException:

import chisel3._

class CycleTest extends Module {
  val m = Module(new Passthrough)
  m.in := m.out
}

class Passthrough extends Module {
  val in = IO(Input(Bool()))
  val out = IO(Output(Bool()))
  out := in
}

What is the expected behavior?

The CheckCombLoops transform should emit a CombLoopException.

Steps to Reproduce

Here's a Scastie which reproduces the error: https://scastie.scala-lang.org/X4WMiHaDQLWs9nc1IAZviA

Here's the relevant portion of the stacktrace:

firrtl.graph.PathNotFoundException: Unreachable node
	at firrtl.graph.DiGraph.path(DiGraph.scala:225)
	at firrtl.graph.DiGraph.path(DiGraph.scala:207)
	at firrtl.transforms.CheckCombLoops.$anonfun$expandInstancePaths$2(CheckCombLoops.scala:187)
	at scala.collection.immutable.List.map(List.scala:250)
	at scala.collection.immutable.List.map(List.scala:79)
	at firrtl.transforms.CheckCombLoops.expandInstancePaths(CheckCombLoops.scala:182)
	at firrtl.transforms.CheckCombLoops.$anonfun$run$18(CheckCombLoops.scala:281)
	at scala.collection.immutable.List.foreach(List.scala:333)
	at firrtl.transforms.CheckCombLoops.$anonfun$run$7(CheckCombLoops.scala:274)
	at firrtl.transforms.CheckCombLoops.$anonfun$run$7$adapted(CheckCombLoops.scala:252)
	at scala.collection.immutable.List.foreach(List.scala:333)
	at firrtl.transforms.CheckCombLoops.run(CheckCombLoops.scala:252)
	at firrtl.transforms.CheckCombLoops.execute(CheckCombLoops.scala:319)
	at firrtl.Transform.transform(Compiler.scala:280)
	at firrtl.Transform.transform$(Compiler.scala:280)
	at firrtl.transforms.CheckCombLoops.transform(CheckCombLoops.scala:101)

It looks like the m.in := m.out connection in the CycleTest module is the source of the problem. It creates two connected LogicNodes which have the same inst (m in this case). Since they have the same inst, the if statement on line 184 of expandInstancePaths matches, and on line 187 we try to find the path from out to in inside the Passthrough module, but no such path exists (only the reverse of that path exists). Thus, line 187 throws the PathNotFoundException.

Adding an intermediate wire in the parent module (CycleTest) does indeed cause the PathNotFoundException to go away, and we get the expected CombLoopException. Not that we'd want to require users to do that, it just further illustrates the cause of the bug: there needs to be a direct connection from a module's output-to-input port to fool the expandInstancePaths method into thinking that this is an internal path in that module.

Your environment

  • Chisel Version: 3.5.4
  • FIRRTL Version: 1.5.4
  • OS: macOS 12.5.1

External Information

N/A

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant