-
Notifications
You must be signed in to change notification settings - Fork 554
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix overzealous LATCH warning with procedure-local vars #2862
Comments
Showing code here for easier viewing/discussion:
|
You are correct the current code improperly warns. Perhaps you'd be willing to look at the code and make a pull request to fix this? Otherwise perhaps @margej you might be interested? |
Is this issue specific to procedure-local vars? I found two examples with no procedure-local vars, where Verilator seems to report improper LATCH warnings.
module Latch1(
input logic en,
input logic a, b,
output logic [1:0] c
);
always_comb begin
if (en) begin
c = 2'b0;
end else begin
c[1] = a;
c[0] = b;
end
end
endmodule
typedef struct packed {
logic a;
logic b;
} twin_t;
module Latch2(
input logic en,
input logic a, b,
output twin_t c
);
always_comb begin
if (en) begin
{c.a, c.b} = 2'b0;
end else begin
c.a = a;
c.b = b;
end
end
endmodule Both can be temporarily fixed by making a local copy of Edit: I'm using Verilator 4.200 2021-03-12 rev v4.200. |
I'm also seeing that this seems to not be specific to procedure-local variables as I'm getting what I believe to be the same spurious warning as above where the nets in question are not procedure-local (a mix of an interface port and some module-scope variables). Let me know if an additional test case would help, though it seems you have a few already here. |
The following even simpler (albeit nonsensical) test case also emits a latch warning:
The reason being the rule set for latch detection is that all branches of a combinational always must contain at least one assignment to every output driven therein. The design does not consider the possibility that the scope of an 'output' can be limited to a particular branch of the block, therefore it expects to find an assignment to 'n' in the else clause of this if, even though that would be impossible. I'll have a think about how to fix ... |
I have a fix which excludes from latch detection any variables which are declared after (higher firstLineno()) the always being analysed. Would that be an acceptable fix? |
|
We can't compare by line number, that will break in many ways, like with includes or any time earlier steps move things. It needs to track by position in tree by how the iteration is done. |
I'm glad you said that really because it felt like a hack! I did start out looking at tree position, but by Active all the VARs, including this local static, are attached directly to the top - Vt_lint_latch_8_049_active.tree:
It seems I'll need to go back to an earlier pass to capture the relative tree position of the VAR and the ALWAYS. It looks like its the Begin pass which moves the VAR outside the ALWAYS, which makes sense, I'll take a look in there ... |
I did find a "better" solution, but in hindsight, simply disabling detection for local variables is a cop-out, and could hide real latches. The real issue here is that the scope of the detection needs to match the scope of the original VAR declaration, whereas currently the scope of detection is the root of the ALWAYS containing the first assignment, so we get false +ves from branches of the ALWAYS that cannot possibly assign the VAR because its not in scope. The proper fix would be to make the root of the latch detection graph equal to the node under which the VAR was originally declared. This will entail recording this postion in the VAR at the point it is 'lifted' in V3Begin.cpp, as well as a modification to the latch graph generation in V3Active.cpp |
The LATCH warning seems rather overzealous in Verilator 4.108 2021-01-10 rev v4.106-158-g484b76e5b; for the code below, it complains about n, but n is assigned on all paths where it is actually defined.
t_latch.sv
The text was updated successfully, but these errors were encountered: