Main Content

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:

  1. Open the MATLAB Function block MATLAB Function1.

  2. Opens the Ports and Data Manager dialog box. On the MATLAB® Editor, click Edit Data.

  3. On the Ports and Data Manager dialog box, clear Allow direct feedthrough check box.

See also Prevent Algebraic Loop Errors in MATLAB Function and Stateflow 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')
### Generating HDL for 'hdlcoder_MLFB_avoid_algebraic_loops/Subsystem_AlgLoop_Issue'.
### Using the config set for model <a href="matlab:configset.showParameterGroup('hdlcoder_MLFB_avoid_algebraic_loops', { 'HDL Code Generation' } )">hdlcoder_MLFB_avoid_algebraic_loops</a> for HDL code generation parameters.
### Running HDL checks on the model 'hdlcoder_MLFB_avoid_algebraic_loops'.
### Begin compilation of the model 'hdlcoder_MLFB_avoid_algebraic_loops'...
### Applying HDL optimizations on the model 'hdlcoder_MLFB_avoid_algebraic_loops'...
### Begin model generation.
### Model generation complete.
### Begin VHDL Code Generation for 'hdlcoder_MLFB_avoid_algebraic_loops'.
### Working on hdlcoder_MLFB_avoid_algebraic_loops/Subsystem_AlgLoop_Issue/MATLAB Function1 as hdlsrc/hdlcoder_MLFB_avoid_algebraic_loops/MATLAB_Function1.vhd.
### Working on hdlcoder_MLFB_avoid_algebraic_loops/Subsystem_AlgLoop_Issue as hdlsrc/hdlcoder_MLFB_avoid_algebraic_loops/Subsystem_AlgLoop_Issue.vhd.
### Code Generation for 'hdlcoder_MLFB_avoid_algebraic_loops' completed.
### Creating HDL Code Generation Check Report file:///tmp/Bdoc21b_1757077_821/tpd3d9bfdc/ex34676816/hdlsrc/hdlcoder_MLFB_avoid_algebraic_loops/Subsystem_AlgLoop_Issue_report.html
### HDL check for 'hdlcoder_MLFB_avoid_algebraic_loops' complete with 0 errors, 0 warnings, and 0 messages.
### HDL code generation complete.

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 and select Edit Data on the MATLAB Editor.

  • In the Ports and Data Manager dialog box, 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 as int8 and int16 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.

See Also

Blocks

Functions

Related Topics