llvm / llvm/circt

Emitted SV uses variable before declaration

Open
#7,405 4 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
C++
Stars
2.2k
Forks
524
Avg merge
3d 2h
Merged PRs (30d)
46

Description

Consider:
```mlir
hw.module @hoist_reg(in %dummy : i32, in %dummy2 : i32, out out : i17) {
%res_reg = sv.reg : !hw.inout
sv.initial {
%tmp = sv.reg init %dummy : !hw.inout
%17 = sv.read_inout %tmp : !hw.inout
%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
hw.output %res_reg_data : i17
}
```

Running through firtool produces:
```systemverilog
// 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.

Contributor guide

No contributing guide indexed for this repository

Research direction

Reproduce the issue by running the provided MLIR through firtool and inspecting the emitted SystemVerilog. Trace the emission path responsible for declarations inside the sv.initial block; done means generated declarations appear before any expressions that use them, without introducing new tool errors.

Written by the indexing model from the issue text.

Assessment

Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.