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 Code Generation Targets and Control Code Style in the Embedded Coder documentation.

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.

StepTaskReference
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.

ConstructRules 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.

Cannot have any 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 all other instances of duplicate conditions.

After removal of duplicates, two or more unique conditions must exist. Otherwise, no conversion occurs and the generated code contains all instances of duplicate conditions.

The following examples show how the conversion handles duplicate conditions.

Example of Generated CodeCode 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
}

No 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. (For more information, see Define Enumerated Data Types for MATLAB Function Blocks.)

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(Enumeration) 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 guarantee that no naming conflicts occur.

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 all the rules in Rules for Conversion.

ConstructHow the Construct Follows the Rules
MATLAB Function block

Five unique conditions exist, in addition to the default:

  • (type == Controller.P)

  • (type == Controller.I)

  • (type == Controller.PD)

  • (type == Controller.PI)

  • (type == Controller.PID)

Each condition

Each condition:

  • Tests equality

  • Uses the same input for the LHS

Each LHS

Each LHS:

  • Contains a single variable

  • Is the input to the block and therefore not a constant

  • Is of enumerated type Controller, which you define in Controller.m on the MATLAB path

  • Has no side effects on simulation

Each RHS

Each RHS:

  • Is an enumerated value and therefore a constant

  • Is of enumerated type Controller

Enabling the Conversion

  1. Open the Configuration Parameters dialog box.

  2. In the Code Generation pane, select ert.tlc for the System target file.

    This step specifies an embedded real-time target for your model.

  3. 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:

      • All MATLAB Function blocks in a model

      • MATLAB functions in all Stateflow® charts of that model

      • Flow charts in all Stateflow charts of that model

      For more information, see Enhance Readability of Code for Flow Charts in the Stateflow documentation.

Generating Code for Your Model

In the Code Generation pane of the Configuration Parameters dialog box, click Build in the lower right corner.

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.

Was this topic helpful?