Description
A firrtl.layerblock
is supposed to contain no operations which write outside the layerblock
. Improve the verifier for the layerblock
to be able to check this.
The problem is specifically with a connect
involving non-passively typed aggregate operands. When the operands have this type, one of three things could be happening:
- The source could be driving the destination.
- The destination could be driving the source.
- The source and destination could be driving each other, i.e., both (1) and (2) for some ground types.
I made a decision in #7462 to not verify this as it is tricky and we didn't have infrastructure in place to do it. Additionally, the aggressive conversion of connect
to matchingconnect
(which requires passive types) almost immediately makes this verifier unnecessary. Additionally, anything parsed from FIRRTL text will use the emitConnect
utility which intentionally doesn't create constructions like below. This can likely only come up for manually crafted MLIR or by passes that choose to create connects like this. That said, not checking this is far from ideal.
An example of problematic connects that should be rejected are:
firrtl.module @ConnectTests() {
%a = firrtl.wire : !firrtl.uint<1>
%b = firrtl.wire : !firrtl.bundle<a: uint<1>>
%c = firrtl.wire : !firrtl.bundle<a flip: uint<1>>
%d = firrtl.wire : !firrtl.bundle<a : bundle< a flip : uint<1>>>
%e = firrtl.wire : !firrtl.bundle<a flip : bundle< a flip : uint<1>>>
firrtl.layerblock @A {
%_a = firrtl.wire : !firrtl.uint<1>
%_b = firrtl.wire : !firrtl.bundle<a: uint<1>>
%_c = firrtl.wire : !firrtl.bundle<a flip: uint<1>>
%_d = firrtl.wire : !firrtl.bundle<a : bundle< a flip : uint<1>>>
%_e = firrtl.wire : !firrtl.bundle<a flip : bundle< a flip : uint<1>>>
firrtl.connect %a, %_a : !firrtl.uint<1>
firrtl.connect %b, %_b : !firrtl.bundle<a: uint<1>>
firrtl.connect %_c, %c : !firrtl.bundle<a flip: uint<1>>
firrtl.connect %_d, %d : !firrtl.bundle<a : bundle< a flip : uint<1>>>
firrtl.connect %e, %_e : !firrtl.bundle<a flip : bundle< a flip : uint<1>>>
}
}
Note that all of these examples are cases of (1) or (2). No case of (3) is shown. That would occur if you have a type which contains a bundle which has opposite direction leaves.