Using Persistent Variables and fi Objects Inside MATLAB Function Blocks for HDL Code Generation
These guidelines illustrate the recommended settings when using persistent variables inside MATLAB Function blocks in your model. The MATLAB Function block is available in the User-Defined Functions block library. A persistent variable in a MATLAB Function block acts similar to a delay element in your Simulink® model.
Each guideline has a severity level that indicates the level of compliance requirements. To learn more, see HDL Modeling Guidelines Severity Levels.
Update Persistent Variables at End of MATLAB Function
Guideline ID
2.8.1
Severity
Strongly Recommended
Description
To make sure that the persistent variables inside the MATLAB Function block map to a register on the target FPGA device, update the persistent variable at the end of the MATLAB® code inside the MATLAB Function block. Do not update the persistent variable before its value is read or used by the function.
For example, this MATLAB code is not recommended because the function updates the
persistent variable FF0
is updated before the value is read
at the output.
function FF_out0 = fcn(FF_in) %#codegen persistent FF0 if isempty(FF0) FF0 = zeros(1, 'like', FF_in); end % Incorrect order of FF update FF0 = FF_in % Output FF0. FF_out0 is NOT delayed FF_out0 = FF0;
This MATLAB code is recommended because the value is written to
FF0
at the end of the code.
function FF_out0 = fcn(FF_in) %#codegen persistent FF0 if isempty(FF0) FF0 = zeros(1, 'like', FF_in); end % Output FF0 FF_out0 = FF0; % Write FF update at the end of the code FF0 = FF_in
Avoid Algebraic Loop Errors from Persistent Variables inside MATLAB Function Blocks
Guideline ID
2.8.2
Severity
Mandatory
Description
When your Simulink® model contains MATLAB Function blocks inside a feedback loop and uses persistent variables, compiling or simulating the model might generate algebraic loop errors. To simulate the model and generate HDL code, use nondirect feedthrough.
In certain cases, the persistent delay in the MATLAB Function block inside a feedback loop causes an algebraic loop error. When you use direct feedthrough, the output of the block directly depends on the input. When Allow direct feedthrough is cleared, the output of the block depends on the internal state and properties and does not depend on the input. The nondirect feedthrough semantics prevents algebraic loops errors by making the outputs depend only on the state.
For an example, open the model hdlcoder_MLFB_avoid_algebraic_loops
.
modelname = 'hdlcoder_MLFB_avoid_algebraic_loops'; blkname = 'hdlcoder_MLFB_avoid_algebraic_loops/Subsystem_AlgLoop_Issue/MATLAB Function1'; open_system(modelname)
When you simulate the model, the algebraic loop error message is displayed. The MATLAB Function block hdlcoder_MLFB_avoid_algebraic_loops/Subsystem_AlgLoop_Issue/MATLAB Function
uses a persistent variable inside a MATLAB Function block.
open_system(blkname)
To avoid this error, use nondirect feedthrough. To specify nondirect feedthrough at the command line, create a MATLABFunctionConfiguration
object by using get_param
function, and then change the property value AllowDirectFeedthrough
:
MLFBConfig = get_param(blkname, 'MATLABFunctionConfiguration');
MLFBConfig.AllowDirectFeedthrough = 0;
See also MATLABFunctionConfiguration
.
To specify nondirect feedthrough from the UI:
Open the MATLAB Function block
MATLAB Function1
.Open the Property Inspector. In the Modeling tab, in the Design section, click Property Inspector.
In the Property Inspector, open the Advanced section and clear the Allow direct feedthrough check box.
See also Prevent Algebraic Loop Errors in MATLAB Function, Chart, and Truth Table Blocks.
The model now simulates without algebraic errors. You can now generate HDL code for the Subsystem block Subsystem_AlgLoop_Issue
.
open_system(modelname) set_param('hdlcoder_MLFB_avoid_algebraic_loops', 'SimulationCommand', 'Update') makehdl('hdlcoder_MLFB_avoid_algebraic_loops/Subsystem_AlgLoop_Issue')
Use hdlfimath Setting and Specify fi Objects inside MATLAB Function Block
Guideline ID
2.8.3
Severity
Strongly Recommended
Description
fimath
properties define the rules for performing
arithmetic operations on fi objects. To specify fimath
properties that govern arithmetic operations, use a fimath
object. To see the default fimath
property settings, run this
command:
F = fimath
F = RoundingMethod: Nearest OverflowAction: Saturate ProductMode: FullPrecision SumMode: FullPrecision
The default fimath
settings reduce rounding errors and
overflows. However, HDL code generation for a MATLAB Function block that uses
these settings can incur additional resource usage on the target FPGA device. To
avoid the additional logic, use hdlfimath
. The
hdlfimath
function is a utility that defines
fimath
properties optimized for HDL code generation. To
see the default hdlfimath
settings, run this command:
H = hdlfimath
H = RoundingMethod: Floor OverflowAction: Wrap ProductMode: FullPrecision SumMode: FullPrecision
HDL code generation for a MATLAB Function block that uses these settings avoids the additional resource usage and saves area on the target FPGA device.
To specify these settings for a MATLAB Function block:
Double-click the MATLAB Function block.
In the Modeling tab, in the Design section, click the Property Inspector.
In the Property Inspector, open the Fixed-point properties section. For:
Treat these inherited Simulink signal types as fi objects, select
Fixed-point & Integer
.If you use the default
Fixed-point
setting, fixed-point data types specified by using fi objects and built-in integer types such asint8
andint16
are treated differently. When you use built-in integer types, the output data type for integer type calculations becomes the same as the input data type. The bit width is not expanded to perform numeric calculation.MATLAB FUNCTION FIMATH, select Specify Other and then enter
hdlfimath
.
To perform rounding operations that are different from the default hdlfimath settings, specify these settings explicitly by using the fi object as illustrated below.
A = fi(4.9, 1, 8)
A = 4.8750 DataTypeMode: Fixed-point: binary point scaling Signedness: Signed WordLength: 8 FractionLength: 4
B = fi(2.3, 1, 10)
B = 2.2969 DataTypeMode: Fixed-point: binary point scaling Signedness: Signed WordLength: 10 FractionLength: 7
C = fi(A+B, 'RoundingMethod', 'Nearest', 'OverflowAction', 'Saturate')
C = 7.1719 DataTypeMode: Fixed-point: binary point scaling Signedness: Signed WordLength: 12 FractionLength: 7 RoundingMethod: Nearest OverflowAction: Saturate ProductMode: FullPrecision SumMode: FullPrecision
To make sure that the fimath settings are specified according to hdfimath for the MATLAB Function block, you can run the check Check for MATLAB Function block settings.