Main Content

Compare Rounding and Overflow Modes in C/C++ Code and Simulink

This example shows the use of a Simulink® C Caller block to determine the Simulink rounding mode that matches the results obtained from the C/C++ implementation. This technique can help you to identify the correct overflow mode or rounding mode that you need to match when creating entries in a Code Replacement Library.

Introduction to Rounding and Overflow Modes

While creating a code replacement entry for a Simulink model, the saturation mode and the rounding modes need to be specified for operations that can overflow or lose precision. To create Code Replacement Library entries that replace the correct operations, compare the rounding and saturating behavior of the model with the behavior of your implementation in C/C++.

The goal of this example is to find the rounding behavior of the division operation with integer inputs and outputs in C++.

Example Model Setup

The model CrlMathModeComparison performs division between two randomly generated inputs using the Simulink Divide block and the C Caller block and compares the results. If there is a mismatch, the Assertion block is activated, and the simulation stops.

The following blocks are used from the Simulink blocks library:

  1. Assertion block

  2. C Caller block

  3. Divide block

  4. Relational Operator block

  5. Subsystem to generate random numbers

Define Custom C/C++ Implementation of the Division Function in C Caller Block

You can write a custom implementation of the division function to replace the function in the generated code. Specify the source and header files for your implementation by setting the model configuration parameter Simulation Target > Include Headers.

Once you set this parameter, the function name appears in the drop-down list inside the C Caller block parameters.

Results

The results from the custom division function using C++ code match the results from the Divide block when the Integer rounding mode is set to Zero or Simplest, as displayed in the scope.

For the other rounding modes, the simulation will generate different results from the C++ implementation.

Example Replacement Table

From the above example, we understand that a division operation between inputs of type int32 and output of type int32 in the custom C++ function rounds to zero. A Division block in Simulink with Integer rounding mode is set to Zero or Simplest will give the same behavior.

Hence, while registering a code replacement entry for an integer division operation using the code replacement tool, the rounding mode for the entry can be set to RTW_ROUND_ZERO or RTW_ROUND_SIMPLEST.

The table DivisionCrlExample demonstrates such an entry.

Limitations

For the given example, the model is unable to distinguish between different saturation modes in the Divide block. The overflow condition can be observed when the smallest number that can be represented by int32, i.e. -2147483648 is divided by -1. Since this model uses randomly generated values for division inputs, it is unable to verify the behavior for such edge cases. Hence, it is advisable to further compare the results from the custom C/C++ implementation with the results from a Simulink model using specific inputs that cover any special conditions or edge cases.