Open
Description
firrtl.circuit "A" {
firrtl.module @A(in %clock: !firrtl.clock, in %u: !firrtl.uint<1>, in %cond: !firrtl.uint<1>, out %a: !firrtl.uint<2>) attributes {convention = #firrtl<convention scalarized>} {
%c0_ui2 = firrtl.constant 0 : !firrtl.uint<2>
%cat_1 = firrtl.cat %u, %c0_ui2 {name = "cat_1"} : (!firrtl.uint<1>, !firrtl.uint<2>) -> !firrtl.uint<3>
%cat_2 = firrtl.cat %cat_1, %u {name = "cat_2"} : (!firrtl.uint<3>, !firrtl.uint<1>) -> !firrtl.uint<4>
%0 = firrtl.bits %cat_2 2 to 1 : (!firrtl.uint<4>) -> !firrtl.uint<2>
firrtl.matchingconnect %a, %0 : !firrtl.uint<2>
}
}
Even though %0 is constant 0 it's not optimized at FIRRTL. At core dialect operands are flattened to comb.concat, and it's obviously canonicalized.
This issue causes this kind of unstable behavior for register optimizations:
FIRRTL version 5.0.0
circuit A:
public module A :
input clock : Clock
input u: UInt<1>
input cond : UInt<1>
output a : UInt<2>
output b: UInt<2>
reg r_a : UInt<2>, clock
reg r_b : UInt<2>, clock
connect a, r_a
connect b, r_b
node cat_1 = cat(u, UInt<2>(0))
node cat_2 = cat(cat_1, u)
node next_a = bits(cat_2, 3, 1)
when cond :
connect r_a, next_a
connect r_b, UInt<1>(0)
Output:
reg [1:0] r_a;
always @(posedge clock) begin
if (cond)
r_a <= 2'h0;
end // always @(posedge)
assign a = r_a;
assign b = 2'h0;
Currently only r_b
is optimized because the driver of r_b
is mux(cond, 0, r_b)
whereas r_a
cannot be optimized since the driver of r_a
is mux(cond, cat, r_a)
(specifically this condition
circt/lib/Dialect/FIRRTL/FIRRTLFolds.cpp
Line 3125 in b33791d
Metadata
Metadata
Assignees
Labels
No labels