[FIRRTL] Support Aliasing in InferDomains
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 2.2k
- Forks
- 524
- Avg merge
- 3d 2h
- Merged PRs (30d)
- 46
Description
The `InferDomains` pass presently makes an assumption that modules are hard boundaries through which it doesn't have to look across. This is too conservative as it prevents unification of instance output ports which alias instance input ports.
Consider the following:
``` firrtl
FIRRTL version 7.0.0
circuit Foo:
domain ClockDomain:
module Bar:
input A: Domain of ClockDomain
output B: Domain of ClockDomain
domain_define B = A
public module Foo:
input A: Domain of ClockDomain
input in: UInt<1> domains [A]
inst bar of Bar
domain_define bar.A = A
wire X: Domain of ClockDomain
domain_define X = bar.B
wire x: UInt<1> domains [X]
connect x, in
```
When compiled, this errors on `connect x, in` and reports a nice error which, surprisingly, indicates that the error reporting knows that these alias, but the pass doesn't:
``` console
circt/Foo.fir:22:5: error: illegal domain crossing in operation between operands x and in
connect x, in
^
circt/Foo.fir:22:5: note: see current operation: "firrtl.matchingconnect"(%2, %arg1) : (!firrtl.uint<1>, !firrtl.uint<1>) -> ()
circt/Foo.fir:20:5: note: x has domains [bar.B : ClockDomain]
wire x: UInt<1> domains [X]
^
circt/Foo.fir:13:11: note: in has domains [A : ClockDomain]
input in: UInt<1> domains [A]
^
circt/Foo.fir:15:5: note: output instance port bar.B declared here
inst bar of Bar
^
circt/Foo.fir:7:12: note: output module port B declared here
output B: Domain of ClockDomain
^
circt/Foo.fir:9:5: note: output module port B aliases input module port A
domain_define B = A
^
circt/Foo.fir:6:11: note: input module port A declared here
input A: Domain of ClockDomain
^
circt/Foo.fir:15:5: note: input instance port bar.A declared here
inst bar of Bar
^
circt/Foo.fir:16:5: note: input instance port bar.A aliases input module port A
domain_define bar.A = A
^
circt/Foo.fir:12:11: note: input module port A declared here
input A: Domain of ClockDomain
^
circt/Foo.fir:12:11: note: input module port A declared here
```
This likely requires a somewhat different visitation algorithm for `InferDomains`, though the core unification algorithm is entirely sound. Specifically, the pass currently works bottom up. While this continues to work in this example, there could be arbitrary aliasing that goes both upwards and downwards requiring tracking things across the entire circuit.
It is entirely fine to have external modules be hard boundaries, though.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the InferDomains pass and the supplied FIRRTL reproducer; inspect how its current bottom-up visitation handles module and instance aliases. Done means the example no longer reports an illegal domain crossing while external modules remain hard boundaries.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100