## Cascaded Conditional Region Variable Assignments

In R2021b, HDL Coder™ provides a coding standard (Guideline 2.F.B.1.a in RTL Description Rules and Checks)
to check for assignments to the same variable in multiple cascaded control regions within
the same process block. HDL Coder points to the blocks that generate such a coding style. If the style is not
recommended for use in your production workflow, consider an alternative coding style or
replace the block pointed to by the rule. The check displays an error if the generated HDL
code for your design contains the same variable/signal for `VHDL`

or
register/wire for `Verilog`

written to in multiple cascaded conditional
regions, such as `switch case`

or `if/else`

cascaded
regions, within the same process block. To turn on this check for your model, see Check for assignments to the same variable in multiple cascaded control regions.

### Example Patterns that Fail the Check for Guideline 2.F.B.1.a

These examples show HDL Code patterns that fail the check for the presence of assignments to the same variable in multiple cascaded conditional regions.

#### Parallel Cascaded 'if' Regions

always @(u) begin if(u < 8'sd4) begin y = -8'sd1; end if(u == 8'sd1) begin y = 8'sd10; else y =8'sd2; end end

#### Parallel Cascaded 'if' Regions with Nesting

always @(u, k) begin if (u < 8’sd4) begin if(k == 8’sd1) begin y = 8'sd10; end end if (u < 8’sd2) begin y = 8'sd1; else y = 8’sd2; end end

#### Parallel Cascaded 'if' and 'switch' Regions

always @(u) begin if (u < 8’sd4) begin y = 8'sd10; end case (u) 8’sd1: y = 8’sd11; default: y = 8’sd4; endcase end

#### Parallel Cascaded 'switch' Regions

always @(u) begin case (u) 8’sd2: y = 8’sd15; default: y = 8’sd4; endcase case (u) 8’sd1: y = 8’sd11; default: y = 8’sd4; endcase end

#### Parallel Cascaded Region Inside Nested Region

always @(u) begin case (u) 8’sd2: y = 8’sd15; default: if (u < 8’sd4) begin y = 8'sd10; end if (u == 8’sd1) begin y = 8'sd10; else y = 8’sd2; end endcase end

### Example Patterns that Pass the Check for Guideline 2.F.B.1.a

These examples show HDL Code patterns that pass the check for the presence of assignments to the same variable in multiple cascaded conditional regions if you enable the check.

#### Default Value and Conditional Assignment

always @(u) begin y = 8’sd1; if (u < 8’sd4) begin y = 8'sd10; end end

#### Parallel cascaded “if” Regions Writing to Different Outputs

always @(u) begin if (u < 8’sd4) begin y1 = -8'sd1; else y1 = 8’sd3; end if (u == 8’sd1) begin y2 = 8'sd10; else y2 = 8’sd2; end end

#### Assignment in All Paths of Condition Regions

always @(u) begin if (u == 8’sd1) begin y = 8'sd10; else y = 8’sd2; end end

### Simulink Blocks and Modeling Patterns that Fail the Check for Guideline 2.F.B.1.a

Some Simulink blocks and modeling patterns can fail this check (guideline 2.F.B.1.a) and cause an error during HDL code generation. If a block or modeling pattern you use in your code fails this check, consider disabling the check if it is not needed in your production workflow or changing the block or modeling pattern producing the code failure.

#### MATLAB Function Block

In some cases, MATLAB^{®} code written inside MATLAB Function blocks might
generate HDL Code that fails this check.

**Conditional Initialization of Persistent Variables. **If the persistent variables in a MATLAB Function block are
conditionally initialized and then overwritten in a conditional region elsewhere
in the code, the generated code might fail this check.

For example, if you have a MATLAB Function block in your DUT with the MATLAB code:

function y = fcn(u) persistent loc; if(isempty(loc) || u == int8(2)) loc = int8(-1); end % persistent variable overwritten in conditional code region if(u<int8(4)) loc = int8(10); end y = loc;

This Verilog code snippet demonstrates the violation of a value assignment to
the variable *loc_temp* in two parallel conditional
`if`

statements.

always @(loc, loc_not_empty, u) begin loc_temp = loc; loc_not_empty_next = loc_not_empty; if ( ! loc_not_empty || (u == 8'sd2)) begin loc_temp = -8'sd1; loc_not_empty_next = 1'b1; end // persistent variable overwritten in conditional code region if (u < 8'sd4) begin loc_temp = 8'sd10; end ... end

**Explicit modeling in the MATLAB Function block. **If you set the **HDL Architecture** in the HDL
Block Properties dialog box of the MATLAB Function block as
`MATLAB Function`

and design your MATLAB code in a coding style that assigns multiple values to the same
variable in cascading conditional regions, an error might occur from the
resulting violating patterns in the generated HDL code.

For example, if you have a MATLAB Function block in your DUT with the MATLAB code:

function y = fcn(u) % if region 1 if(u<4) % if region 1-1 if(u==1) y = int8(0); else y = int8(4); end % if region 1-2 if(u==2) y = int8(5); end else y = int8(6); end ... end

Region 1 in the preceding code contains two `if`

statements
that assign different values to the same output variable *y*.
This pattern causes a violation in the generated Verilog code.

module mlfb (u, y); ... always @(u) begin // if region 1 if (u < 8'sd4) begin // if region 1-1 if (u == 8'sd1) begin y_1 = 8'sd0; end else begin y_1 = 8'sd4; end // if region 1-2 if (u == 8'sd2) begin y_1 = 8'sd5; end end else begin y_1 = 8'sd6; end ... end assign y = y_1; endmodule // mlfb

**Conditional Assignments of Matrix Variables. **If you assign different indices of a single matrix in multiple cascading
conditional regions in a MATLAB Function block, a violation can
occur.

For example, if you have a MATLAB Function block in your DUT with the MATLAB code:

function y = fcn(u) y = int8(zeros(1,2)); % if region 1 if(u==1) y(1) = int8(2); end % if region 2 if(u==2) y(2) = int8(5); end

Although two different indices of the matrix *y* are being
assigned values in cascading `if`

statements, this code
generates Verilog code that causes a
violation.

ARCHITECTURE rtl OF mlfb IS -- Signals SIGNAL u_signed : signed(7 DOWNTO 0); -- int8 SIGNAL y_tmp : vector_of_signed8(0 TO 1); -- int8 [2] BEGIN u_signed <= signed(u); mlfb_1_output : PROCESS (u_signed) BEGIN FOR t_0 IN 0 TO 1 LOOP y_tmp(t_0) <= to_signed(16#00#, 8); END LOOP; -- if region 1 IF u_signed = to_signed(16#00000001#, 8) THEN y_tmp(0) <= to_signed(16#02#, 8); END IF; -- if region 2 IF u_signed = to_signed(16#00000002#, 8) THEN y_tmp(1) <= to_signed(16#05#, 8); END IF; END PROCESS mlfb_1_output; outputgen: FOR k IN 0 TO 1 GENERATE y(k) <= std_logic_vector(y_tmp(k)); END GENERATE; END rtl;

**Workarounds**

Design MATLAB code in your MATLAB Function block in a way that avoids patterns that assign multiple values to the same variable in multiple cascaded conditional regions.

Consider specifying the HDL Block property of the MATLAB Function block

**HDL Architecture**to be`MATLAB Datapath`

.

#### Stateflow Charts

In some cases, MATLAB code written in Stateflow^{®}
chart can generate HDL code that violates this check.

**Explicit Chart Patterns. **Cascaded `if`

regions containing assignments to the same
variable in a Stateflow
chart can produce the equivalent pattern in the generated HDL
code.

One `if`

region in a transition followed by another
`if`

region in a destination state can cause a violation in
the generated HDL code. This pattern is seen in this Stateflow Chart:

With the MATLAB Function block in the transition containing the code:

function y1 = fcn(u1) if(u1<4) y1 = int8(5); else y1 = int8(6); end end

The workaround for both of these explicit chart pattern violations is to
change the design pattern used in creating the Stateflow
charts. Avoid using explicit `if/else`

or
`switch/case`

regions in your Stateflow
charts. Instead, redesign the required control flows by using
Stateflow
chart semantics, such as transitions and states.

**Parallel Decomposition. **In Stateflow
charts, you have an option to choose **Parallel
(AND)** mode for the **Decomposition** property of
the chart that changes the chart execution to parallel style. For more
information, see Execution Order for Parallel States (Stateflow).

For example, when you specify parallel decomposition in a chart, it results in
the generation of cascaded `switch`

regions in the same
`always`

process.

If the same output variable is assigned a value in multiple parallel states, a
violation occurs in the generated HDL code. This Verilog code snippet
demonstrates the violation of a value assignment to the variable
*y_1* in two parallel conditional `case`

statements in the same `always`

process, generated as a result
of parallel decomposition.

always @(is_A, is_B) begin is_A_next = is_A; is_B_next = is_B; case ( is_A) state_type_is_A_IN_A_1 : begin is_A_next = state_type_is_A_IN_A_2; y_1 = 8'sd2; end default : begin //case IN_A_2: y_1 = 8'sd2; end endcase case ( is_B) state_type_is_B_IN_B_1 : begin is_B_next = state_type_is_B_IN_B_2; y_1 = 8'sd4; end default : begin //case IN_B_2: y_1 = 8'sd4; end endcase end

**Temporal Logic. **Use of temporal logic in your Stateflow
chart generally results in violations. Under some conditions,
generated code does not violate the coding guideline. Avoid using temporal logic
to generate code that does not result in a violation.

#### LUT-Based Sine, Cosine Block

When using the LUT-based Sine, Cosine block in your model to
generate HDL code, a violation of this check might occur in the generated HDL code.
This Verilog code snippet generated from a Simulink model containing a
LUT-based Sine, Cosine block demonstrates the violation of a
value assignment to the variable *Look_Up_Table_k* in multiple
parallel conditional `if`

statements.

always @(QuadHandle2_out1) begin Look_Up_Table_t_0_0[0] = 16'sb0000000000000000; ... Look_Up_Table_t_0_0[31] = 16'sb0011111111101100; Look_Up_Table_t_0_0[32] = 16'sb0100000000000000; Look_Up_Table_in0_0 = 18'sb000000000000000000; Look_Up_Table_in0_0_0 = 18'sb000000000000000000; if (QuadHandle2_out1 <= 18'sb000000000000000000) begin Look_Up_Table_k = 6'b000000; end else if (QuadHandle2_out1 >= 18'sb000100000000000000) begin Look_Up_Table_k = 6'b100000; end else begin Look_Up_Table_in0_0 = QuadHandle2_out1 >>> 8'd9; Look_Up_Table_k = Look_Up_Table_in0_0[5:0]; end ... Look_Up_Table_dout_low = Look_Up_Table_t_0_0[Look_Up_Table_k]; if ( ! (Look_Up_Table_k == 6'b100000)) begin Look_Up_Table_k = Look_Up_Table_k + 6'b000001; end ... end

For more information, see Sine, Cosine.

#### Assignment Block

Similar to the violation caused by conditional assignments of matrix variables in MATLAB Function blocks, the Assignment block might cause a similar violation in the generated HDL code.

For example, a model containing an Assignment block in the DUT with
the Assignment block property **Index Option**
having more than one dimension and set to `Index vector (port)`

:

produces this Verilog code snippet:

always @* begin if ((In3 == 32'sb00000000000000000000000000000001) && (In3 == 32'sb00000000000000000000000000000001)) begin assign_out1[0][0] = In2; end else begin assign_out1[0][0] = In1[0][0]; end if ((In3 == 32'sb00000000000000000000000000000010) && (In3 == 32'sb00000000000000000000000000000001)) begin assign_out1[1][0] = In2; end else begin assign_out1[1][0] = In1[1][0]; end ... if ((In3 == 32'sb00000000000000000000000000000011) && (In3 == 32'sb00000000000000000000000000000011)) begin assign_out1[2][2] = In2; end else begin assign_out1[2][2] = In1[2][2]; end end

*assign_out1*are different between the two cascaded

`if`

statements, the matrix variable is still being
assigned multiple values in cascading conditional regions. For more information on the Assignment block, see Assignment.

#### Selector Block

If a Selector block is in a model that generates HDL code, a violation of this check might occur.

For example, a model containing a Selector block in the DUT with
the Selector block property **Index Option** having
more than one dimension and set to `Index vector (port)`

:

produces this generated Verilog code that causes a violation by assigning the same
variable *Selector_out1* multiple values for each of its indices in
multiple cascaded `if`

statements.

always @* begin Selector_out1[0] = Bias_out1[0][3]; Selector_out1[1] = Bias_out1[1][3]; Selector_out1[2] = Bias_out1[2][3]; Selector_out1[3] = Bias_out1[3][3]; if (Sel == 32'b00000000000000000000000000000010) begin Selector_out1[0] = Bias_out1[0][2]; Selector_out1[1] = Bias_out1[1][2]; Selector_out1[2] = Bias_out1[2][2]; Selector_out1[3] = Bias_out1[3][2]; end if (Sel == 32'b00000000000000000000000000000001) begin Selector_out1[0] = Bias_out1[0][1]; Selector_out1[1] = Bias_out1[1][1]; Selector_out1[2] = Bias_out1[2][1]; Selector_out1[3] = Bias_out1[3][1]; end if (Sel == 32'b00000000000000000000000000000000) begin Selector_out1[0] = Bias_out1[0][0]; Selector_out1[1] = Bias_out1[1][0]; Selector_out1[2] = Bias_out1[2][0]; Selector_out1[3] = Bias_out1[3][0]; end end

For more information on the Selector block, see Selector.

#### Math Function Block Set as Reciprocal

If a Math Function block with the **Function** set
as `reciprocal`

, the **Algorithm method** set as
`Exact`

, and the **Saturate on integer
overflow** selected as `on`

is in a DUT in a model
that generates HDL code, a violation of this check might occur.

For example, a model containing the Math Function block with the preceding settings

produces this Verilog Code snippet that demonstrates the violation of a value
assignment to the variable *ufix_sameasinput_out1* in two parallel
conditional `if`

statements:

always @(In1) begin ufix_sameasinput_div_temp = 16'b0000000000000000; if (In1 == 16'b0000000000000000) begin ufix_sameasinput_out1 = 16'b1111111111111111; end else begin ufix_sameasinput_div_temp = 13'b1000000000000 / In1; ufix_sameasinput_out1 = ufix_sameasinput_div_temp; end if (In1 == 16'b0000000000000000) begin ufix_sameasinput_out1 = 16'b1111111111111111; end end

For more information on the Math Function block, see Math Function.