Sigasi Visual HDL (SVH) has a number of checks on Verilog case statements.
Case statement does not cover all cases
A case statement should cover all options, either enumerating all options explicitly or with a default
clause (rule 8). This rule is checked for enum types only, not for scalar or vector types.
module badcode(input clk);
typedef enum {INIT, IDLE, START, READY} t_state;
t_state state;
always @(posedge clk) begin
case (state) // Error: case `INIT` is missing
IDLE : state = START;
START : state = READY;
READY : state = IDLE ;
endcase
end
endmodule
module bettercode(input clk);
typedef enum {INIT, IDLE, START, READY} t_state;
t_state state;
always @(posedge clk) begin
case (state)
INIT : state = IDLE ;
IDLE : state = START;
START : state = READY;
READY : state = IDLE ;
endcase
end
endmoduleNote that SVH also warns for case statements without a default clause
Default clause has to be the last item in a case statement
The default clause should be at the end after all the other options (rule 15). SVH warns if that is not the case.
module badcode(input clk);
typedef enum {INIT, IDLE, START, READY} t_state;
t_state state;
always @(posedge clk) begin
case (state)
IDLE : state = START;
START : state = READY;
default : state = IDLE ; // The `default` clause must be at the end
READY : state = IDLE ;
endcase
end
endmodule
module goodcode(input clk);
typedef enum {INIT, IDLE, START, READY} t_state;
t_state state;
always @(posedge clk) begin
case (state)
IDLE : state = START;
START : state = READY;
READY : state = IDLE ;
default : state = IDLE ;
endcase
end
endmoduleThis rule also applies to generate case statements, e.g.
module bad_example#(parameter WIDTH=8);
generate
case (WIDTH)
default: // The `default` clause must be at the end
begin // others - carry look-ahead adder
adder_cla #(WIDTH) x3(co, sum, a, b, ci);
end
1: begin // 1-bit adder implementation
adder_1bit x1(co, sum, a, b, ci);
end
// other cases
endcase
endgenerate
endmodule
Case statement can only have one default clause
A case statement can only have one default clause (rule 16). A warning is flagged if more than one default clause is present.
module badcode(input clk);
typedef enum {INIT, IDLE, START, READY} t_state;
t_state state;
always @(posedge clk) begin
case (state)
IDLE : state = START;
START : state = READY;
READY : state = IDLE ;
default : state = IDLE ; // Error: two `default` clauses
default : state = START;
endcase
end
endmodule
module goodcode(input clk);
typedef enum {INIT, IDLE, START, READY} t_state;
t_state state;
always @(posedge clk) begin
case (state)
IDLE : state = START;
START : state = READY;
READY : state = IDLE ;
default : state = IDLE ;
endcase
end
endmoduleThis rule also applies to generate case statements, e.g.
module bad_example#(parameter WIDTH=8);
generate
case (WIDTH)
default: // Error: two `default` clauses
begin // others - carry look-ahead adder
adder_cla #(WIDTH) x3(co, sum, a, b, ci);
end
1: begin // 1-bit adder implementation
adder_1bit x1(co, sum, a, b, ci);
end
// other cases
default: // Error: two `default` clauses
begin // others - carry look-ahead adder
adder_cla #(WIDTH) x3(co, sum, a, b, ci);
end
endcase
endgenerate
endmodule
Default clause missing from case statement
SVH warns for case statements without a default clause (rule 40). While a case statement without a default branch is syntactically correct, many guidelines recommend attaching a default branch, even if the case statement is completely defined. This ensures no latch would be inferred during synthesis if the case is incomplete (sometimes difficult to judge, esp with casex/casez semantics or larger widths).
module rather_ok_code(input clk);
typedef enum {INIT, IDLE, START, READY} t_state;
t_state state;
always @(posedge clk) begin
case (state)
INIT : state = IDLE ;
IDLE : state = START;
START : state = READY;
READY : state = IDLE ;
// no default branch
endcase
end
endmodule
module goodcode(input clk);
typedef enum {INIT, IDLE, START, READY} t_state;
t_state state;
always @(posedge clk) begin
case (state)
INIT : state = IDLE ;
IDLE : state = START;
START : state = READY;
READY : state = IDLE ;
default : state = IDLE ;
endcase
end
endmoduleRule Configuration
These rules can be disabled for your project, or their severity and parameters can be modified in the project linting settings. Alternatively, they can be manually configured with the following template:
8/severity/${path}={error|warning|info|ignore} # Missing cases
15/severity/${path}={error|warning|info|ignore} # Default clause must be last
16/severity/${path}={error|warning|info|ignore} # Multiple default clauses
40/severity/${path}={error|warning|info|ignore} # Missing default clause