-
Notifications
You must be signed in to change notification settings - Fork 368
Open
Labels
Description
Lowering the following with circt-verilog
module combo ( input a, b, c, d, e, output reg z);
always @ (*) begin
z = ((a & b) | (c ^ d) & ~e);
end
endmodule
results in this MLIR:
hw.module @combo(in %a : i1, in %b : i1, in %c : i1, in %d : i1, in %e : i1, out z : i1) {
%0 = llhd.constant_time <0ns, 0d, 1e>
%true = hw.constant true
%false = hw.constant false
%a_0 = llhd.sig name "a" %false : i1
%1 = llhd.prb %a_0 : !hw.inout<i1>
%b_1 = llhd.sig name "b" %false : i1
%2 = llhd.prb %b_1 : !hw.inout<i1>
%c_2 = llhd.sig name "c" %false : i1
%3 = llhd.prb %c_2 : !hw.inout<i1>
%d_3 = llhd.sig name "d" %false : i1
%4 = llhd.prb %d_3 : !hw.inout<i1>
%e_4 = llhd.sig name "e" %false : i1
%5 = llhd.prb %e_4 : !hw.inout<i1>
%z = llhd.sig %false : i1
llhd.process {
cf.br ^bb1
^bb1: // 3 preds: ^bb0, ^bb2, ^bb3
%7 = llhd.prb %a_0 : !hw.inout<i1>
%8 = llhd.prb %b_1 : !hw.inout<i1>
%9 = llhd.prb %c_2 : !hw.inout<i1>
%10 = llhd.prb %d_3 : !hw.inout<i1>
%11 = llhd.prb %e_4 : !hw.inout<i1>
llhd.wait (%1, %2, %3, %4, %5 : i1, i1, i1, i1, i1), ^bb2
^bb2: // pred: ^bb1
%12 = llhd.prb %a_0 : !hw.inout<i1>
%13 = comb.icmp bin ne %7, %12 : i1
%14 = llhd.prb %b_1 : !hw.inout<i1>
%15 = comb.icmp bin ne %8, %14 : i1
%16 = llhd.prb %c_2 : !hw.inout<i1>
%17 = comb.icmp bin ne %9, %16 : i1
%18 = llhd.prb %d_3 : !hw.inout<i1>
%19 = comb.icmp bin ne %10, %18 : i1
%20 = llhd.prb %e_4 : !hw.inout<i1>
%21 = comb.icmp bin ne %11, %20 : i1
%22 = comb.or bin %13, %15, %17, %19, %21 : i1
cf.cond_br %22, ^bb3, ^bb1
^bb3: // pred: ^bb2
%23 = llhd.prb %a_0 : !hw.inout<i1>
%24 = llhd.prb %b_1 : !hw.inout<i1>
%25 = comb.and %23, %24 : i1
%26 = llhd.prb %c_2 : !hw.inout<i1>
%27 = llhd.prb %d_3 : !hw.inout<i1>
%28 = comb.xor %26, %27 : i1
%29 = llhd.prb %e_4 : !hw.inout<i1>
%30 = comb.xor %29, %true : i1
%31 = comb.and %28, %30 : i1
%32 = comb.or %25, %31 : i1
llhd.drv %z, %32 after %0 : !hw.inout<i1>
cf.br ^bb1
}
llhd.drv %a_0, %a after %0 : !hw.inout<i1>
llhd.drv %b_1, %b after %0 : !hw.inout<i1>
llhd.drv %c_2, %c after %0 : !hw.inout<i1>
llhd.drv %d_3, %d after %0 : !hw.inout<i1>
llhd.drv %e_4, %e after %0 : !hw.inout<i1>
%6 = llhd.prb %z : !hw.inout<i1>
hw.output %6 : i1
}
%22
will always evaluate to true
because the wait operation will only branch if one of its sensitivity values changes. We should add a folder/canonicalizer that performs this simplification.
The code responsible for generating this pattern is in MooreToCore in the WaitEventOp lowering pattern.