circt
circt copied to clipboard
Emitted SV uses variable before declaration
Consider:
hw.module @hoist_reg(in %dummy : i32, in %dummy2 : i32, out out : i17) {
%res_reg = sv.reg : !hw.inout<i17>
sv.initial {
%tmp = sv.reg init %dummy : !hw.inout<i32>
%17 = sv.read_inout %tmp : !hw.inout<i32>
%29 = comb.xor %dummy2, %17 : i32
%32 = comb.extract %29 from 3 : (i32) -> i17
sv.passign %res_reg, %32 : i17
}
%res_reg_data = sv.read_inout %res_reg : !hw.inout<i17>
hw.output %res_reg_data : i17
}
Running through firtool produces:
// Generated by CIRCT firtool-1.79.0g20240729_759ef12
module hoist_reg( // def-use.mlir:1:1
input [31:0] dummy, // def-use.mlir:1:25
dummy2, // def-use.mlir:1:42
output [16:0] out // def-use.mlir:1:61
);
reg [16:0] res_reg; // def-use.mlir:2:14
initial begin // def-use.mlir:3:3
automatic logic [31:0] _GEN = dummy2 ^ tmp; // def-use.mlir:5:11, :6:11
reg [31:0] tmp = dummy; // def-use.mlir:4:12
res_reg <= _GEN[19:3]; // def-use.mlir:6:11, :7:11, :8:5
end // initial
assign out = res_reg; // def-use.mlir:11:19, :12:3
endmodule
Notice _GEN uses tmp before it's declared.
This is treated as an error by default in some tools, such as slang and VCS.
Thanks, yeah it looks like isExpressionEmittedInlineIntoProceduralDeclaration in ExportVerilog needs to take RegOp into account.