Open
Description
Now, we ignore statement block symbols. But in some cases, we'll trigger the dominance error. For example:
module top_module;
always @(*) begin
integer j;
for(j = 0; j < 4; j++);
end
endmodule
Error:
forLoop.sv:2:12: error: operand #0 does not dominate this use
always @(*) begin
^
forLoop.sv:2:12: note: see current operation: %20 = "moore.read"(%0) : (!moore.ref<l32>) -> !moore.l32
forLoop.sv:3:17: note: note: operand defined here (op in a parent region)
integer j;
or
module top_module;
always @(*) begin
for(int i = 0;i<4;i++);
end
endmodule
Error:
forLoop.sv:2:12: error: operand #0 does not dominate this use
always @(*) begin
^
forLoop.sv:2:12: note: see current operation: %9 = "moore.read"(%1) : (!moore.ref<i32>) -> !moore.i32
forLoop.sv:3:17: note: operand defined here (op in a parent region)
for(int i = 0;i<4;i++);
This error is caused by the moore.wait_event
. When we handle always @(*)
, we must ensure which signal will lead to recalculating the whole always block. If we declare integer j
out of the always block, we can generate the following Moore IR:
module {
moore.module @top_module() {
%j = moore.variable : <l32>
moore.procedure always {
moore.wait_event {
%10 = moore.read %j : <l32>
moore.detect_event any %10 : l32
}
%0 = moore.constant 0 : i32
%1 = moore.conversion %0 : !moore.i32 -> !moore.l32
moore.blocking_assign %j, %1 : l32
cf.br ^bb1
^bb1: // 2 preds: ^bb0, ^bb3
%2 = moore.read %j : <l32>
%3 = moore.constant 4 : i32
%4 = moore.conversion %3 : !moore.i32 -> !moore.l32
%5 = moore.slt %2, %4 : l32 -> l1
%6 = moore.conversion %5 : !moore.l1 -> i1
cf.cond_br %6, ^bb2, ^bb4
^bb2: // pred: ^bb1
cf.br ^bb3
^bb3: // pred: ^bb2
%7 = moore.read %j : <l32>
%8 = moore.constant 1 : l32
%9 = moore.add %7, %8 : l32
moore.blocking_assign %j, %9 : l32
cf.br ^bb1
^bb4: // pred: ^bb1
moore.return
}
moore.output
}
}
The %10 = moore.read %j : <l32>
means that we must have already created the %j = moore.variable : <l32>
. So I think maybe we don't ignore slang::ast::StatementBlockSymbol
.