The // synopsys full_case compiler directive asserts that all possible clauses of a case statement have been covered and that no default clause is necessary. This compiler directive has two uses; it avoids the need for default logic, and it can avoid latch inference from a case statement by asserting that all necessary conditions are covered by the given branches of the case statement. As explained in the Functional Descriptions chapter, a latch can be inferred whenever a variable is not assigned a value under all conditions.
The syntax for the full_case compiler directive is either of the following compiler directives.
// synopsys full_case
/* synopsys full_case */
If the case statement contains a default clause, Foundation Express assumes that all conditions are covered. If there is no default clause, and you do not want latches to be created, use the full_case compiler directive to indicate that all necessary conditions are described in the case statement.
The following example shows two uses of the full_case compiler directive. Note that the parallel_case and full_case compiler directives can be combined in one comment.
reg [1:0] in, out;
reg [3:0] current_state, next_state;
parameter state1 = 4'b0001, state2 = 4'b0010,
state3 = 4'b0100, state4 = 4'b1000;
case (in) // synopsys full_case
0: out = 2;
1: out = 3;
2: out = 0;
endcase
case (1) // synopsys parallel_case full_case
current_state[0] : next_state = state2;
current_state[1] : next_state = state3;
current_state[2] : next_state = state4;
current_state[3] : next_state = state1;
endcase
In the first case statement, the condition in == 3 is not covered. You can either use a default clause to cover all other conditions, or use the full_case compiler directive (as in this example) to indicate that other branch conditions do not occur. If you cover all possible conditions explicitly, Foundation Express recognizes the case statement as full case, so the full_case compiler directive is not necessary.
The second case statement in the above example does not cover all 16 possible branch conditions. For example, current_state == 4'b0101 is not covered. The parallel_case compiler directive is used in this example because only one of the four case items can evaluate to TRUE and be executed.
Although you can use the full_case compiler directive to avoid creating latches, using this directive does not guarantee that latches will not be built. You must still assign a value to each variable used in the case statement in all branches of the case statement. The following example illustrates a situation where the full_case compiler directive prevents a latch from being inferred for variable b, but not for variable a.
reg a, b;
reg [1:0] c;
case (c) // synopsys full_case
0: begin a = 1; b = 0; end
1: begin a = 0; b = 0; end
2: begin a = 1; b = 1; end
3: b = 1; // a is not assigned here
endcase
In general, use the full_case compiler directive when you know that all possible branches of the case statement have been enumerated or, at least, all branches that can occur. If all branches that can occur are enumerated, the logic generated from the case statement performs the same function as the simulated circuit. If a case condition is not fully enumerated, the generated logic and the simulation are not the same.
You do not need the full_case compiler directive if you have a default branch, or you enumerate all possible branches in a case statement, because Foundation Express assumes that the case statement is full_case.