Main Content

Options to Represent Variant Parameters in Generated Code

You can generate the code only for active values or for both active and inactive values of variant parameters in Simulink®. You can also represent the values of variant parameters as inline variables or as tunable variables in the generated code.

Note

For variant parameters associated with the startup activation time, you can generate code for both active and inactive choices by installing Simulink Coder™ or Embedded Coder®.

For variant parameters associated with the code compile activation time:

  • You must install Simulink Coder to generate code for only active values of variant parameters.

  • You must install Embedded Coder to generate code for both active and inactive values of variant parameters.

Limitations

Variant parameters do not support generating code for AUTOSAR targets.

Overview of Variant Parameters

Variant parameters can have multiple values. Each value of the variant parameter is associated with a variant condition expression. During simulation, the value of a variant parameter associated with the condition that evaluates to true is the active value of the variant parameter. The value associated with the condition that evaluates to false is the inactive value of the variant parameter. When you generate code, you can choose to include only the active value or both the active and inactive values in the generated code. You can also choose to represent the values as inline or as tunable variables in the generated code. For more information on variant parameters, see Use Variant Parameters to Reuse Block Parameters with Different Values.

Choice of Values in Generated Code

Simulink supports generating code only for active values or for both active and inactive values of variant parameters. Values included in the code are based on the variant activation time you specify for the variant parameters. For more information, see Activate Variant During Different Stages of Simulation and Code Generation Workflow.

When you specify the variant activation time as:

  • 'update diagram' –– Simulink does not analyze the values of variant parameters for incompatibilities in signal attributes. It generates code only for the active values of variant parameters.

  • 'update diagram analyze all choices' –– Simulink analyzes both active and inactive values of variant parameters for incompatibilities in signal attributes, however it generates code only for the active values of variant parameters.

  • 'code compile' –– Simulink analyzes both active and inactive values of variant parameters for incompatibilities in signal attributes and it also generates code for both active and inactive values of the variant parameters. The values are enclosed in C preprocessor conditional statements #if and #endif that are conditionally compiled when you compile the generated code.

  • 'startup' ––Simulink analyzes both active and inactive values of variant parameters for incompatibilities in signal attributes and it also generates code for both active and inactive values of the variant parameters. The values are enclosed in regular if conditions inside the model_initialize function of the generated code that are conditionally evaluated when you run the executable that is built from the code.

Types of Variables in Generated Code

Simulink supports representing the values of variant parameters as inline variables or as tunable variables in the generated code. The representation of values in the code are based on the storage class you specify for the variant parameters.

  • Inline variable: If you specify the storage class of a variant parameter as Auto, which is a default storage class, and the activation time as update diagram or update diagram analyze all choices, then the variant parameter is inlined to the literal numeric value of the parameter in the generated code. If you specify the storage class of a variant parameter as Auto and the activation time as code compile, then the variant parameter is inlined as macros in the generated code. Inlined variables reduce global RAM usage and increase efficiency of the generated code. The code does not allocate memory to represent numeric block parameters, such as the Gain parameter of a Gain block. Instead, the code is inlined to the literal numeric value of the parameter.

  • Tunable: If you specify the storage class of a variant parameter as anything other than Auto, then the variant parameter is represented using symbolic names in the generated code, as described in Choose Storage Class for Controlling Data Representation in Generated Code.

Generate C Code for Variant Parameters

This example shows how to generate C code for variant parameters. The style of the generated code is based on the variant activation time and the storage class you specify for the variant parameters.

Explore the Model

Consider the slexVariantParameters.slx model.

Variant parameter in a Gain block

The Gain parameters of the Gain1 and the Gain2 blocks are variant parameters with their values set to K1 and K2, respectively. The variable K1 has two values: 3.5 and 8.5. The variable K2 has two values: 4.5 and 9.5.

Simulink chooses active values of K1 and K2 based on the value of the variant control variable V. If V==1 evaluates to true, then the value of K1 is set to 3.5, and the value of K2 is set to 8.5. If V==2 evaluates to true, then the value of K1 is set to 4.5, and the value of K2 is set to 9.5.

The style of generated code is based on the variant activation time and the storage class you specify for the variant parameters. In this example, the variant activation time is set to update diagram, and the storage class is set as Auto. When you generate a code from this model, the code is generated only for the active values of K1 and K2. In the generated code, the values are inlined to the literal value of the parameters.

Generate Inline and Tunable Code for Variant Parameters using Embedded Coder

Before you generate code from the model, you must first ensure that you have write permission in your current folder.

  1. Prepare the model for code generation by specifying code generation settings in the Configuration Parameters dialog box. Choose the appropriate solver and code generation target, and check the model configuration for execution efficiency. For more details on each of these steps, see Generate Code Using Embedded Coder®.

  2. In the Apps gallery of the model toolstrip, click Simulink Coder.

  3. On the C Code tab, click Build.

    The code generator creates the folder slexVariantParameters_ert_rtw in your current working folder and places source code files in that folder. The generated code is in two primary files: slexVariantParameters.c and slexParameters.h. The file slexVariantParameters.h contains the value of the variant control variable, and the file slexVariantParameters.c contains the values of the variant parameters.

  4. In the C Code tab, select Open Report.

  5. Select the slexVariantParameters.c file from the Generated Code pane of the report. The code is generated only for the active values of the K1 and K2. In the generated code, the values are inlined to the literal value of the parameters.

    slexVariantParameters_Y.Out1 = 3.5 * slexVariantParameters_U.In1;
    slexVariantParameters_Y.Out2 = 4.5 * slexVariantParameters_U.In2;
  6. In the model, change the activation time to code compile and the storage class to ExportedGlobal, then generate the code again. Observe the change in the style of the generated code.

    The code is generated only for all the active and inactive values of K1 and K2. In the generated code, the values are represented using symbolic names.

    This table shows the difference in the style of the generated code for storage classes Auto and ExportedGlobal with different activation times.

    Activation timeStorage class
    Auto (default)ExportedGlobal
    update diagram

    The code is generated only for the active values of the variant parameters. In the generated code, the values are inlined to the literal value of the parameters.

    Consider this snippet of the generated code. 4.5 and 3.5 are inline active values of the variant parameters Gain1 and Gain2.

    slexVariantParameters_Y.Out1 = 3.5 * slexVariantParameters_U.In1;
    slexVariantParameters_Y.Out2 = 4.5 * slexVariantParameters_U.In2;

    The code is generated only for the active values of variant parameters. In the generated code, the values are represented using symbolic names.

    Consider this snippet of the generated code. Here, K1 and K2 are symbolic names for active values of variant parameters Gain1 and Gain2.

    real_T K1 = 3.5;
    real_T K2 = 4.5;
    …
    … 
    slexVariantParameters_Y.Out1 = K1 * slexVariantParameters_U.In1;
    slexVariantParameters_Y.Out2 = K2 * slexVariantParameters_U.In2;

    update diagram analyze all choices

    The generated code is same as that of update diagram. The only difference is that the active and the inactive values of variant parameters are analyzed to ensure consistency of signal attributes such as dimension and data type across the model.

    The generated code is same as that of update diagram. The only difference is that the active and the inactive values of variant parameters are analyzed to ensure consistency of signal attributes such as dimension and data type across the model.

    code compile

    The code is generated for all the active and inactive values of the variant parameters. All of the values are analyzed to ensure consistency of signal attributes such as dimension and data type across the model. In the generated code, the values are inlined as macros and are enclosed in preprocessor conditionals #if and #elif.

    Consider this snippet of the generated code. The active and inactive values are enclosed in C preprocessor conditional statements #if and #elif. rtCP_Gain1_K1 and rtCP_Gain_K2 are the macros for variant parameters Gain1 and Gain2.

    #if V == 1 
    #define rtCP_Gain1_K1     (3.5)
    #elif V == 2
    #define rtCP_Gain1_K1     (8.5) 
    #endif
    
    #if V == 1 
    #define rtCP_Gain_K2      (4.5)
    #elif V == 2
    #define rtCP_Gain_K2      (9.5)
    #endif
    
    slexVariantParameters_Y.Out1 = rtCP_Gain_K1 * slexVariantParameters_U.In1;
    slexVariantParameters_Y.Out2 = rtCP_Gain1_K2 * slexVariantParameters_U.In2;
    

    The code is generated for all the active and inactive values of variant parameters. All of the values are analyzed to ensure consistency of signal attributes such as dimension and data type across the model. In the generated code, the values are represented using symbolic names and are enclosed in preprocessor conditionals #if and #elif.

    Consider this snippet of the generated code. The active and inactive values are enclosed in C preprocessor conditional statements #if and #elif. Here, K1 and K2 are symbolic names for variant parameters Gain1 and Gain2.

    #if V == 1 
    real_T K1 = 3.5;
    real_T K2 = 4.5;
    
    #elif V == 2
    real_T K1 = 8.5;
    real_T K2 = 9.5; 
    #endif
    
    slexVariantParameters_Y.Out1 = K1 * slexVariantParameters_U.In1;
    slexVariantParameters_Y.Out2 = K2 * slexVariantParameters_U.In2;
    

    startup

    The code is generated for all the active and inactive values of the variant parameters. All of the values are analyzed to ensure consistency of signal attributes such as dimension and data type across the model. In the generated code, the values are inlined as macros and are enclosed in regular if conditions.

    Consider this snippet of the generated code. The active and inactive values are enclosed in regular if condition statements inside the model_initialize function. The model_initialize function also contains an assertion statement to check that at least one variant value is active while running the executable. slexVariantParameters_P.K1 and slexVariantParameters_P.K2 are the members of a structure for variant parameters Gain1 and Gain2.

    if (V == 1) {
        slexVariantParameters_P.K1 = 3.5;
        slexVariantParameters_P.K2 = 4.5;
      } else if (V == 2) {
        slexVariantParameters_P.K1 = 8.5;
        slexVariantParameters_P.K2 = 9.5;
      }
    
    utAssert((V == 1) || (V == 2));
    
    slexVariantParameters_Y.Out1 = slexVariantParameters_P.K1 * ...
    slexVariantParameters_U.In1;
    slexVariantParameters_Y.Out2 = slexVariantParameters_P.K2 * ...
    slexVariantParameters_U.In2;

    The code is generated for all the active and inactive values of variant parameters. All of the values are analyzed to ensure consistency of signal attributes such as dimension and data type across the model. In the generated code, the values are represented using symbolic names and are enclosed in regular if conditions.

    Consider this snippet of the generated code. The active and inactive values are enclosed in regular if condition statements inside the model_initialize function. The model_initialize function contains an assertion statement to check that at least one variant value is active. Here, K1 and K2 are symbolic names for variant parameters Gain1 and Gain2.

    if (V == 1) {
        K1 = 3.5;
        K2 = 4.5;
      } else if (V == 2) {
        K1 = 8.5;
        K2 = 9.5;
      }
    
    utAssert((V == 1) || (V == 2));
    
    slexVariantParameters_Y.Out1 = K1 * slexVariantParameters_U.In1;
    slexVariantParameters_Y.Out2 = K2 * slexVariantParameters_U.In2;

See Also

|

Related Topics