svlint
svlint copied to clipboard
New Rule: Implicit case default
This rule could be an extension of the case_default rule that allows the case default to be implicitly defined. For example,
module M;
always_comb begin
y = 0;
case(x)
1: y = 1;
endcase
end
endmodule
If there is no case match, y
wouldn't be undriven because the case default is implicitly defined by setting y = 0
at the beginning of the always_comb
.
@ronitnallagatla What is it you want to forbid?
The case_default rule says something like "Forbid defaultless case statements. Report fail if you see any, otherwise report pass". In other words, svlint rules only look for things which you don't like, and everything else is allowed.
I was thinking of a rule that is more lenient than the explicit_case_default rule, such that it forbids a case statement that doesn't have an explicit default branch and doesn't have an implicit definition of a default case (giving the output signal a default value before the case statement).
i.e., a passing case statement should have either an explicit default branch or an implicit default before the case (like in the example above).
Maybe in implementation it would check if the case has a explicit default branch, but if it doesn't, it would check if the default has been implicitly defined, and if that's missing too, then it would fail. Am I making sense?
Yes, that makes sense now :)
To implement this, you could begin by copying src/syntaxrules/explicit_case_default.rs
and add some state to the rule (similar to under_always_construct
here) to hold a list of all the LHS variable names of all assignments.
I'm unsure how to build the list of pre-assignments though - the form y = 0;
is easy, but other forms are a bit more challenging:
// Simple pre-assignment - allowed YES
y = 0;
// Pre-assignment in all arms of a conditional statement - allowed?
if (c)
y = 0;
else
y = 1;
// Conditional pre-assignment - allowed NO
if (c) // Is the conditional c a constant or variable?
y = 0;
// Tricky due to the way if/else is specified in the BNF because `else if` is a 3rd thing.
// See generate_if_with_label.rs for example of the longer-than-I-expected logic!
if (c);
y = 0;
else if (d)
y = 1;
// Pre-assignment in tasks, functions, previous case statements, or loops... getting messy!
Maybe allow only the simple form?
Another thing to remember is how to handle multiple variables.
always_comb begin
y = 0;
// Missing pre-assignment for z.
case (x)
1: begin
y = 1;
z = 1;
end
end
I guess the logic could say something like "Any assignment LHS (or pre/post increment/decrement) under a case_statement
must be present in the list of previously unconditionally assigned variables." - note nothing about default arms.
That could neatly mandate using either pre-assignments (with this new rule) OR using default arms (with existing rules), so consistently rely on one form.
I think only allowing the simple form of pre-assignment would be the way to get started. I'll look into this. Thanks for the helpful notes!