Closed seldridge closed 2 years ago
Although this should be caught by CheckCombLoop but I feel hw canonicalizer should not cause assertion failures. Maybe we can add a verification that rejects trivial loops between result and operands like %0 = comb.xor %0
(it might hit the performance though).
FYI, this assertion failure comes from the following transition:
hw.module @Foo() -> (b: i1) {
%true = hw.constant true
%0 = comb.xor %0, %true : i1
hw.output %0 : i1
}
==> flatten xor operands
hw.module @Foo() -> (b: i1) {
%true = hw.constant true
%0 = comb.xor %0, %true, %true: i1
hw.output %0 : i1
}
==> remove %true, %true
hw.module @Foo() -> (b: i1) {
%0 = comb.xor %0 : i1
hw.output %0 : i1
}
andrewl@gamma28:/scratch/andrewl/circt/build$ ./bin/circt-opt --firrtl-check-comb-cycles ../loop.mlir ../loop.mlir:3:5: error: detected combinational cycle in a FIRRTL module firrtl.module @Foo(out %b: !firrtl.uint<1>) { ^ ../loop.mlir:3:28: note: Foo.b firrtl.module @Foo(out %b: !firrtl.uint<1>) { ^ ../loop.mlir:3:28: note: Foo.b
It's really weird:
andrewl@gamma28:/scratch/andrewl/circt/build$ ./bin/firtool --parse-only ../loop.fir |./bin/circt-opt --firrtl-check-comb-cycles
<stdin>:3:5: error: detected combinational cycle in a FIRRTL module
firrtl.module @Foo(out %b: !firrtl.uint<1>) {
^
<stdin>:3:28: note: Foo.b
firrtl.module @Foo(out %b: !firrtl.uint<1>) {
^
<stdin>:3:28: note: Foo.b
andrewl@gamma28:/scratch/andrewl/circt/build$ ./bin/firtool ../loop.fir
// Generated by CIRCT unknown git version
module Foo( // ../loop.fir:2:10
output b);
wire _GEN; // ../loop.fir:5:10
assign _GEN = ~(~_GEN); // ../loop.fir:5:10
assign b = ~_GEN; // ../loop.fir:2:10, :5:10
endmodule
The following circuit should trip combinational loop checking, but does not:
This gets into HW dialect and crashes on malformed IR of a unary
xor
. πI expect the problem is the read of an output port is not being checked for combinational loops.