-
Notifications
You must be signed in to change notification settings - Fork 409
Labels
Description
Consider a simple clock generator which uses an infinite loop to toggle a clock:
hw.module @Foo(out clock : i1) {
%0 = llhd.constant_time <5000000fs, 0d, 0e>
%1 = llhd.constant_time <10000000fs, 0d, 0e>
%false = hw.constant false
%true = hw.constant true
%clock = llhd.sig %false : i1
llhd.process {
cf.br ^bb1
^bb1: // 2 preds: ^bb0, ^bb2
llhd.drv %clock, %false after %0 : i1
llhd.drv %clock, %true after %1 : i1
llhd.wait delay %0, ^bb2
^bb2: // pred: ^bb1
cf.br ^bb1
}
%2 = llhd.prb %clock : i1
hw.output %2 : i1
}Running this through circt-opt --llhd-hoist-signals yields this:
hw.module @Foo(out clock : i1) {
%0 = llhd.constant_time <5000000fs, 0d, 0e>
%1 = llhd.constant_time <10000000fs, 0d, 0e>
%false = hw.constant false
%true = hw.constant true
%clock = llhd.sig %false : i1
llhd.process {
cf.br ^bb1
^bb1: // 2 preds: ^bb0, ^bb2
llhd.drv %clock, %false after %0 : i1
llhd.wait delay %0, ^bb2
^bb2: // pred: ^bb1
cf.br ^bb1
}
llhd.drv %clock, %true after %1 : i1 // <--- drive moved
%2 = llhd.prb %clock : i1
hw.output %2 : i1
}For some reason, the second drive to %clock got moved out of the process, which is clearly wrong.
The original input comes from circt-verilog --ir-llhd on this:
module Foo (output logic clock);
initial begin
forever begin
clock <= #5ns 0; // schedule clock = 0 in 5ns
clock <= #10ns 1; // schedule clock = 1 in 10ns
#10ns; // wait 10ns
end
end
endmodule