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

PathNotFoundException in CheckCombLoops transform #2547

Open
@tymcauley

Description

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions