Enhance Code Readability for MATLAB Function Blocks
Requirements for Using Readability Optimizations
To use readability optimizations in your code, you must have an Embedded Coder® license. These optimizations appear only in code that you generate for an embedded real-time (ert
) target.
Note
These optimizations do not apply to MATLAB® files that you call from the MATLAB Function block.
For more information, see Configure a System Target File.
Converting If-Elseif-Else Code to Switch-Case Statements
When you generate code for embedded real-time targets, you can choose to convert if-elseif-else
decision logic to switch-case
statements. This conversion can enhance readability of the code.
For example, when a MATLAB Function block contains a long list of conditions, the switch-case
structure:
Reduces the use of parentheses and braces
Minimizes repetition in the generated code
How to Convert If-Elseif-Else Code to Switch-Case Statements
The following procedure describes how to convert generated code for the MATLAB Function block from if-elseif-else
to switch-case
statements.
Step | Task | Reference |
---|---|---|
1 | Verify that your block follows the rules for conversion. | Verifying the Contents of the Block |
2 | Enable the conversion. | Enabling the Conversion |
3 | Generate code for your model. | Generating Code for Your Model |
Rules for Conversion
For the conversion to occur, the following rules must hold. LHS and RHS refer to the left-hand side and right-hand side of a condition, respectively.
Construct | Rules to Follow |
---|---|
MATLAB Function block | Must have two or more unique conditions, in addition to a default. For more information, see How the Conversion Handles Duplicate Conditions. |
Each condition | Must test equality only. |
Must use the same variable or expression for the LHS. Note You can reverse the LHS and RHS. | |
Each LHS | Must be a single variable or expression, not a compound statement. |
Cannot be a constant. | |
Must have an integer or enumerated data type. | |
Must not have side effects on simulation. For example, the LHS can read from but not write to global variables. | |
Each RHS | Must be a constant. |
Must have an integer or enumerated data type. |
How the Conversion Handles Duplicate Conditions
If a MATLAB Function block has duplicate conditions, the conversion preserves only the first condition. The generated code discards other instances of duplicate conditions.
After removal of duplicates, two or more unique conditions must exist. Otherwise, a conversion does not occur and the generated code contains instances of duplicate conditions.
The following examples show how the conversion handles duplicate conditions.
Example of Generated Code | Code After Conversion |
---|---|
if (x == 1) { block1 } else if (x == 2) { block2 } else if (x == 1) { // duplicate block3 } else if (x == 3) { block4 } else if (x == 1) { // duplicate block5 } else { block6 } | switch (x) { case 1: block1; break; case 2: block2; break; case 3: block4; break; default: block6; break; } |
if (x == 1) { block1 } else if (x == 1) { // duplicate block2 } else { block3 } | Does not change, because only one unique condition exists |
Example of Converting Code for If-Elseif-Else Decision Logic to Switch-Case Statements
Suppose that you have the following model with a MATLAB Function block. Assume
that the output data type is double
and the input data type is
Controller
, an enumerated type that you define.
The block contains the following code:
function system = fcn(type) %#codegen if (type == Controller.P) system = 0; elseif (type == Controller.I) system = 1; elseif (type == Controller.PD) system = 2; elseif (type == Controller.PI) system = 3; elseif (type == Controller.PID) system = 4; else system = 10; end
The enumerated type definition in Controller.m
is:
classdef Controller < Simulink.IntEnumType enumeration P(0) I(1) PD(2) PI(3) PID(4) UNKNOWN(10) end end
If you generate code for an embedded real-time target using default settings, you see something like this:
if (if_to_switch_eml_blocks_U.In1 == P) { /* '<S1>:1:4' */ /* '<S1>:1:5' */ if_to_switch_eml_blocks_Y.Out1 = 0.0; } else if (if_to_switch_eml_blocks_U.In1 == I) { /* '<S1>:1:6' */ /* '<S1>:1:7' */ if_to_switch_eml_blocks_Y.Out1 = 1.0; } else if (if_to_switch_eml_blocks_U.In1 == PD) { /* '<S1>:1:8' */ /* '<S1>:1:9' */ if_to_switch_eml_blocks_Y.Out1 = 2.0; } else if (if_to_switch_eml_blocks_U.In1 == PI) { /* '<S1>:1:10' */ /* '<S1>:1:11' */ if_to_switch_eml_blocks_Y.Out1 = 3.0; } else if (if_to_switch_eml_blocks_U.In1 == PID) { /* '<S1>:1:12' */ /* '<S1>:1:13' */ if_to_switch_eml_blocks_Y.Out1 = 4.0; } else { /* '<S1>:1:15' */ if_to_switch_eml_blocks_Y.Out1 = 10.0; }
The LHS variable if_to_switch_eml_blocks_U.In1
appears multiple times in the generated code.
Note
By default, variables that appear in the block do not retain their names in the generated code. Modified identifiers prevent naming conflicts.
Traceability comments appear between each set of /*
and
*/
markers. To learn more about traceability, see Use Traceability in MATLAB Function Blocks.
Verifying the Contents of the Block
Check that the block follows the rules in Rules for Conversion.
Construct | How the Construct Follows the Rules |
---|---|
MATLAB Function block | Five unique conditions exist, in addition to the default:
|
Each condition | Each condition:
|
Each LHS | Each LHS:
|
Each RHS | Each RHS:
|
Enabling the Conversion
Open the Configuration Parameters dialog box.
In the Code Generation pane, select
ert.tlc
for the System target file.This step specifies an embedded real-time target for your model.
In the Code Generation > Code Style pane, select the Convert if-elseif-else patterns to switch-case statements check box.
Tip
This conversion works on a per-model basis. If you select this check box, the conversion applies to:
MATLAB Function blocks in a model
MATLAB functions in Stateflow® charts of that model
Flow charts in Stateflow charts of that model
For more information, see Enhance Readability of Code for Flow Charts.
Generating Code for Your Model
In the model window, press Ctrl+B.
The code for the MATLAB Function block uses switch-case
statements instead of if-elseif-else
code:
switch (if_to_switch_eml_blocks_U.In1) { case P: /* '<S1>:1:4' */ /* '<S1>:1:5' */ if_to_switch_eml_blocks_Y.Out1 = 0.0; break; case I: /* '<S1>:1:6' */ /* '<S1>:1:7' */ if_to_switch_eml_blocks_Y.Out1 = 1.0; break; case PD: /* '<S1>:1:8' */ /* '<S1>:1:9' */ if_to_switch_eml_blocks_Y.Out1 = 2.0; break; case PI: /* '<S1>:1:10' */ /* '<S1>:1:11' */ if_to_switch_eml_blocks_Y.Out1 = 3.0; break; case PID: /* '<S1>:1:12' */ /* '<S1>:1:13' */ if_to_switch_eml_blocks_Y.Out1 = 4.0; break; default: /* '<S1>:1:15' */ if_to_switch_eml_blocks_Y.Out1 = 10.0; break; }
The switch-case
statements provide the following benefits to enhance readability:
The code reduces the use of parentheses and braces.
The LHS variable
if_to_switch_eml_blocks_U.In1
appears only once, minimizing repetition in the code.