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 endmodule
Note 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 endmodule
This 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 endmodule
This 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 endmodule
Rule 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