Control the Generation of Fixed-Point Utility Functions
Optimize Generated Code Using Specified Minimum and Maximum Values
The Fixed-Point Designer™ software uses representable minimum and maximum values and constant values to determine if it is possible to optimize the generated code, for example, by eliminating unnecessary utility functions and saturation code from the generated code.
This optimization results in:
Reduced ROM and RAM consumption
Improved execution speed
When you select the Optimize using specified minimum and maximum values configuration parameter, the software takes into account input range information, also known as design minimum and maximum, that you specify for signals and parameters in your model. It uses these minimum and maximum values to derive range information for downstream signals in the model and then uses this derived range information to simplify mathematical operations in the generated code whenever possible.
Prerequisites
The Optimize using specified minimum and maximum values parameter appears for ERT-based targets only and requires an Embedded Coder® license when generating code.
How to Configure Your Model
To make optimization more likely:
Provide as much design minimum and maximum information as possible. Specify minimum and maximum values for signals and parameters in the model for:
Inport and Outport blocks
Block outputs
Block inputs, for example, for the MATLAB Function and Stateflow® Chart blocks
Simulink.Signal
objects
Before generating code, test the minimum and maximum values for signals and parameters. Otherwise, optimization might result in numerical mismatch with simulation. You can simulate your model with simulation range checking enabled. If errors or warnings occur, fix these issues before generating code.
Use fixed-point data types with binary-point-only (power-of-two) scaling.
Provide design minimum and maximum information upstream of blocks as close to the inputs of the blocks as possible. If you specify minimum and maximum values for a block output, these values are most likely to affect the outputs of the blocks immediately downstream. For more information, see Eliminate Unnecessary Utility Functions Using Specified Minimum and Maximum Values.
How to Enable Optimization
In the Configuration Parameters dialog box, set the Code Generation > System target file to select an Embedded Real-Time (
ERT
) target (requires an Embedded Coder license).Specify design minimum and maximum values for signals and parameters in your model using the tips in How to Configure Your Model.
Select the Optimization > Advanced parameters > Optimize using the specified minimum and maximum values configuration parameter.
Limitations
This optimization does not occur for:
Multiword operations
Fixed-point data types with slope and bias scaling
Addition unless the fraction length is zero
This optimization does not take into account minimum and maximum values for:
Merge block inputs. To work around this issue, use a
Simulink.Signal
object on the Merge block output and specify the range on this object.Bus elements.
Conditionally executed subsystem (such as a triggered subsystem) block outputs that are directly connected to an Outport block.
Outport blocks in conditionally executed subsystems can have an initial value specified for use only when the system is not triggered. In this case, the optimization cannot use the range of the block output because the range might not cover the initial value of the block.
There are limitations on precision because you specify the minimum and maximum values as double-precision values. If the true value of a minimum or maximum value cannot be represented as a double, ensure that you round the minimum and maximum values correctly so that they cover the true design range.
If your model contains multiple instances of a reusable subsystem and each instance uses input signals with different specified minimum and maximum values, this optimization might result in different generated code for each subsystem so code reuse does not occur. Without this optimization, the Simulink Coder™ software generates code once for the subsystem and shares this code among the multiple instances of the subsystem.
Eliminate Unnecessary Utility Functions Using Specified Minimum and Maximum Values
This example shows how the Fixed-Point Designer software uses the input range for a division operation to determine whether it
can eliminate unnecessary utility functions from the generated code. It uses the
fxpdemo_min_max_optimization
model. First, you generate code without
using the specified minimum and maximum values to see that the generated code contains
utility functions to ensure that division by zero does not occur. You then turn on the
optimization, and generate code again. With the optimization, the generated code does not
contain the utility function because it is not necessary for the input range.
Generate Code Without Using Minimum and Maximum Values
First, generate code without taking into account the design minimum and maximum values
for the first input of the division operation to show the code without the optimization.
In this case, the software uses the representable ranges for the two inputs, which are
both uint16
. With these input ranges, it is not possible to implement
the division with the specified precision using shifts, so the generated code includes a
division utility function.
Run the example. At the MATLAB® command line, enter:
openExample('fixedpoint/FixedPointOptimizationsUsingSpecifiedMinAndMaxValuesExample')
In the example window, double-click the View Optimization Configuration button.
The Optimization pane of the Configuration Parameters dialog box appears.
Note that the Optimize using specified minimum and maximum values parameter is not selected.
Double-click the Generate Code button.
The code generation report appears.
In the model, right-click the
Division with increased fraction length output type
block.The context menu appears.
From the context menu, select C/C++ Code > Navigate To C/C++ Code.
The code generation report highlights the code generated for this block. The generated code includes a call to the
div_repeat_u32
utility function.rtY.Out3 = div_repeat_u32((uint32_T)rtU.In5 << 16, (uint32_T)rtU.In6, 1U);
Click the
div_repeat_u32
link to view the utility function, which contains code for handling division by zero.
Generate Code Using Minimum and Maximum Values
Next, generate code for the same division operation, this time taking into account the design minimum and maximum values for the first input of the Product block. These minimum and maximum values are specified on the Inport block directly upstream of the Product block. With these input ranges, the generated code implements the division by simply using a shift. It does not need to generate a division utility function, reducing both memory usage and execution time.
Double-click the Inport block labeled
5
to open the block parameters dialog box.On the block parameters dialog box, select the Signal Attributes pane and note that:
The Minimum value for this signal is
1
.The Maximum value for this signal is
100
.
Click OK to close the dialog box.
Double-click the View Optimization Configuration button.
The Optimization pane of the Configuration Parameters dialog box appears.
On this pane, select the Optimize using specified minimum and maximum values parameter and click Apply.
Double-click the Generate Code button.
The code generation report appears.
In the model, right-click the
Division with increased fraction length output type
block.The context menu appears.
From the context menu, select C/C++ Code > Navigate To C/C++ Code.
The code generation report highlights the code generated for this block. This time, the generated code implements the division with a shift operation and there is no division utility function.
tmp = rtU.In6; rtY.Out3 = (uint32_T)tmp == (uint32_T)0 ? MAX_uint32_T : ((uint32_T)rtU.In5 << 17) / (uint32_T)tmp;
Modify the Specified Minimum and Maximum Values
Finally, modify the minimum and maximum values for the first input to the division operation so that its input range is too large to guarantee that the value does not overflow when shifted. Here, you cannot shift a 16-bit number 17 bits to the right without overflowing the 32-bit container. Generate code for the division operation, again taking into account the minimum and maximum values. With these input ranges, the generated code includes a division utility function to ensure that no overflow occurs.
Double-click the Inport block labeled
5
to open the block parameters dialog box.On the block parameters dialog box, select the Signal Attributes pane and set the Maximum value to
40000
, then click OK to close the dialog box.Double-click the Generate Code button.
The code generation report appears.
In the model, right-click the
Division with increased fraction length output type
block.The context menu appears.
From the context menu, select C/C++ Code > Navigate To C/C++ Code.
The code generation report highlights the code generated for this block. The generated code includes a call to the
div_repeat_32
utility function.rtY.Out3 = div_repeat_u32((uint32_T)rtU.In5 << 16, (uint32_T)rtU.In6, 1U);