| Real-Time Workshop® Embedded Coder™ | ![]() |
To create a TFL table containing replacement information for supported functions and operators, you perform the following steps:
Create a table definition M-file containing a function definition in the following general form:
function hTable = tfl_table_name() %TFL_TABLE_NAME - Describe entries for a Target Function Library table. . . .
For example, the following sample function definition is from the Target Function Libraries Quick-Start Example:
function hTable = tfl_table_sinfcn() %TFL_TABLE_SINFCN - Describe function entries for a Target Function Library table. . . .
Within the function body, instantiate a TFL table with a command such as the following:
hTable = RTW.TflTable;
Use the TFL table creation functions (listed in the table below) to add table entries representing your replacements for supported functions and operators. For each individual function or operator entry, you issue one or more function calls to
Instantiate a table entry.
Add conceptual arguments, implementation arguments, and other attributes to the entry.
Add the entry to the table.
Creating Table Entries describes this procedure in detail, including two methods for creating function entries. The following sample function entry is from the Target Function Libraries Quick-Start Example:
% Create entry for double data type sine function replacement
hTable.registerCFunctionEntry(100, 1, 'sin', 'double', 'sin_dbl', ...
'double', '<sin_dbl.h>','','');Save the table definition M-file using the name of the table definition function, for example, tfl_table_sinfcn.m.
After you have created a table definition M-file, you can do the following:
Examine and validate the table, as described in Examining and Validating Function Replacement Tables.
Register a TFL containing the table with the Simulink software, as described in Registering Target Function Libraries.
After you register a TFL with the Simulink software, it appears in the Simulink GUI and can be selected for use in building models.
The following table provides a functional grouping of the TFL table creation functions.
| Function | Description |
|---|---|
| Table entry creation | |
| addEntry | Add table entry to collection of table entries registered in TFL table |
| copyConceptualArgsToImplementation | Copy conceptual argument specifications to matching implementation arguments for TFL table entry |
| createAndAddConceptualArg | Create conceptual argument from specified properties and add to conceptual arguments for TFL table entry |
| createAndAddImplementationArg | Create implementation argument from specified properties and add to implementation arguments for TFL table entry |
| createAndSetCImplementationReturn | Create implementation return argument from specified properties and add to implementation for TFL table entry |
| setTflCFunctionEntryParameters | Set specified parameters for function entry in TFL table |
| setTflCOperationEntryParameters | Set specified parameters for operator entry in TFL table |
| Alternative method for conceptual argument creation | |
| addConceptualArg | Add conceptual argument to array of conceptual arguments for TFL table entry |
| getTflArgFromString | Create TFL argument based on specified name and built-in data type |
| Alternative method for function entry creation | |
| registerCFunctionEntry | Create TFL function entry based on specified parameters and register in TFL table |
| registerCPromotableMacroEntry | Create TFL promotable macro entry based on specified parameters and register in TFL table (for abs function replacement only) |
| Build information | |
| addAdditionalHeaderFile | Add additional header file to array of additional header files for TFL table entry |
| addAdditionalIncludePath | Add additional include path to array of additional include paths for TFL table entry |
| addAdditionalLinkObj | Add additional link object to array of additional link objects for TFL table entry |
| addAdditionalLinkObjPath | Add additional link object path to array of additional link object paths for TFL table entry |
| addAdditionalSourceFile | Add additional source file to array of additional source files for TFL table entry |
| addAdditionalSourcePath | Add additional source path to array of additional source paths for TFL table entry |
| Reserved identifiers | |
| setReservedIdentifiers | Register specified reserved identifiers to be associated with TFL table |
You define TFL table entries by issuing TFL table creation function calls inside a table definition M-file. The function calls must follow a function declaration and a TFL table instantiation, such as the following:
function hTable = tfl_table_sinfcn() %TFL_TABLE_SINFCN - Describe function entries for a Target Function Library table. hTable = RTW.TflTable;
Within the function body, you use the TFL table creation functions to add table entries representing your replacements for supported functions and operators. For each individual function or operator entry, you issue one or more function calls to
Instantiate a table entry.
Add conceptual arguments, implementation arguments, and other attributes to the entry.
Add the entry to the table.
The general method for creating function and operator entries, described in General Method for Creating Function and Operator Entries, uses the functions shown in the following table.
| Function | Description |
|---|---|
| Table entry creation | |
| addEntry | Add table entry to collection of table entries registered in TFL table |
| copyConceptualArgsToImplementation | Copy conceptual argument specifications to matching implementation arguments for TFL table entry |
| createAndAddConceptualArg | Create conceptual argument from specified properties and add to conceptual arguments for TFL table entry |
| createAndAddImplementationArg | Create implementation argument from specified properties and add to implementation arguments for TFL table entry |
| createAndSetCImplementationReturn | Create implementation return argument from specified properties and add to implementation for TFL table entry |
| setTflCFunctionEntryParameters | Set specified parameters for function entry in TFL table |
| setTflCOperationEntryParameters | Set specified parameters for operator entry in TFL table |
| Alternative method for conceptual argument creation | |
| addConceptualArg | Add conceptual argument to array of conceptual arguments for TFL table entry |
| getTflArgFromString | Create TFL argument based on specified name and built-in data type |
A simpler alternative creation method is available for function entries, with the constraints that input types must be uniform and implementation arguments must use default Simulink naming. The alternative method uses the following functions and is described in Alternative Method for Creating Function Entries.
| Function | Description |
|---|---|
| Alternative method for function entry creation | |
| registerCFunctionEntry | Create TFL function entry based on specified parameters and register in TFL table |
| registerCPromotableMacroEntry | Create TFL promotable macro entry based on specified parameters and register in TFL table (for abs function replacement only) |
The general workflow for creating TFL table entries applies equally to function and operator replacements, and involves the following steps.
Note
|
Within the function body of your table definition M-file, instantiate a TFL table entry for a function or operator, using one of the following lines of code:
fcn_entry = RTW.TflCFunctionEntry;
op_entry = RTW.TflCOperationEntry;
op_entry = RTW.TflCOperationEntryGenerator;
(RTW.TflCOperationEntryGenerator provides advanced fixed-point parameters, described in Mapping Fixed-Point Operators to Target-Specific Implementations, that are not available in RTW.TflCOperationEntry.)
Set the table entry parameters, which are passed in parameter/value pairs to one of the following functions:
For example:
setTflCFunctionEntryParameters(fcn_entry, ...
'Key', 'sin', ...
'Priority', 30, ...
'ImplementationName', 'mySin', ...
'ImplementationHeaderFile', 'basicMath.h',...
'ImplementationSourceFile', 'basicMath.c');For detailed descriptions of the settable function and operator attributes, see the setTflCFunctionEntryParameters and setTflCOperationEntryParameters reference pages in the Real-Time Workshop Embedded Coder documentation.
Create and add conceptual arguments to the function or operator entry. Output arguments must precede input arguments, and the function signature (including argument naming, order, and attributes) must fulfill the signature match sought by function or operator callers. Conceptual argument names follow the default Simulink naming convention:
For return argument, y1
For input argument names, u1, u2, ..., un
You can create and add conceptual arguments in either of two ways:
Call the createAndAddConceptualArg function to create the argument and add it to the table entry. For example:
createAndAddConceptualArg(fcn_entry, 'RTW.TflArgNumeric', ...
'Name', 'y1',...
'IOType', 'RTW_IO_OUTPUT',...
'DataTypeMode', 'double');Call the getTflArgFromString function to create an argument based on a built-in data type, and then call the addConceptualArg function to add the argument to the table entry.
Note If you use getTflArgFromString, the IOType property of the created argument defaults to 'RTW_IO_INPUT', indicating an input argument. For an output argument, you must change the IOType value to 'RTW_IO_OUTPUT' by directly assigning the argument property, as shown in the following example. |
arg = getTflArgFromString(hTable, 'y1', 'int16'); arg.IOType = 'RTW_IO_OUTPUT'; addConceptualArg(op_entry, arg);
Create and add implementation arguments, representing the signature of your implementation function, to the function or operator entry. The implementation argument order must match the conceptual argument order. You can create and add implementation arguments in either of two ways:
Call the copyConceptualArgsToImplementation function to populate all of the implementation arguments as copies of the previously created conceptual arguments. For example:
copyConceptualArgsToImplementation(fcn_entry);
Call the createAndSetCImplementationReturn function to create the implementation return argument and add it to the table entry, and then call the createAndAddImplementationArg function to individually create and add each of your implementation arguments. This method allows you to vary argument attributes, including argument naming, as long as conceptual argument order is maintained. For example:
createAndSetCImplementationReturn(op_entry, 'RTW.TflArgNumeric', ...
'Name', 'y1', ...
'IOType', 'RTW_IO_OUTPUT', ...
'IsSigned', true, ...
'WordLength', 32, ...
'FractionLength', 0);
createAndAddImplementationArg(op_entry, 'RTW.TflArgNumeric',...
'Name', 'u1', ...
'IOType', 'RTW_IO_INPUT',...
'IsSigned', true,...
'WordLength', 32, ...
'FractionLength', 0 );
createAndAddImplementationArg(op_entry, 'RTW.TflArgNumeric',...
'Name', 'u2', ...
'IOType', 'RTW_IO_INPUT',...
'IsSigned', true,...
'WordLength', 32, ...
'FractionLength', 0 );Add the function or operator entry to the TFL table using the addEntry function. For example:
addEntry(hTable, fcn_entry);
For complete examples of function entries and operator entries created using the general method, see Example: Mapping Floating-Point Math Functions to Target-Specific Implementations and Example: Mapping Operators to Target-Specific Implementations. For syntax examples, see the examples in the TFL table creation function reference pages in the Real-Time Workshop Embedded Coder documentation.
You can use a simpler alternative method for creating TFL function entries if your function implementation meets the following criteria:
The implementation argument order matches the conceptual argument order.
All input arguments are of the same type.
The return argument name and all input argument names follow the default Simulink naming convention:
For the return argument, y1
For input argument names, u1, u2, ..., un
The alternative method for creating function entries involves a single step. Call one of the following functions to create and add conceptual and implementation arguments and register the function entry:
registerCPromotableMacroEntry (use only for the abs function)
For example:
hTable = RTW.TflTable;
registerCFunctionEntry(hTable, 100, 1, 'sqrt', 'double', ...
'sqrt', 'double', '<math.h>', '', '');For detailed descriptions of the function arguments, see the registerCFunctionEntry and registerCPromotableMacroEntry reference pages in the Real-Time Workshop Embedded Coder documentation.
The Real-Time Workshop Embedded Coder software supports the following floating-point math functions for replacement with custom library functions using target function library (TFL) tables.
| abs | cos | log10 | tan |
| acos | cosh | pow (Simulink)/power (Embedded MATLAB) | tanh |
| asin | exp | sin | |
| atan | floor | sinh | |
| ceil | log | sqrt |
The following example uses the method described in General Method for Creating Function and Operator Entries to create a TFL table entry for the sin function.
Note See Target Function Libraries Quick-Start Example for another example of sin function replacement, in which function arguments are created using the simpler method described in Alternative Method for Creating Function Entries. |
Create and save the following TFL table definition file, tfl_table_sinfcn2.m. This file defines a TFL table containing a function replacement entry for the sin function.
The function body sets selected sine function entry parameters, creates the y1 and u1 conceptual arguments individually, and then copies the conceptual arguments to the implementation arguments. Finally the function entry is added to the table.
function hTable = tfl_table_sinfcn2()
%TFL_TABLE_SINFCN2 - Describe function entry for a Target Function Library table.
hTable = RTW.TflTable;
% Create entry for sine function replacement
fcn_entry = RTW.TflCFunctionEntry;
setTflCFunctionEntryParameters(fcn_entry, ...
'Key', 'sin', ...
'Priority', 30, ...
'ImplementationName', 'mySin', ...
'ImplementationHeaderFile', 'basicMath.h',...
'ImplementationSourceFile', 'basicMath.c');
createAndAddConceptualArg(fcn_entry, 'RTW.TflArgNumeric', ...
'Name', 'y1',...
'IOType', 'RTW_IO_OUTPUT',...
'DataTypeMode', 'double');
createAndAddConceptualArg(fcn_entry, 'RTW.TflArgNumeric', ...
'Name', 'u1', ...
'IOType', 'RTW_IO_INPUT',...
'DataTypeMode', 'double');
copyConceptualArgsToImplementation(fcn_entry);
addEntry(hTable, fcn_entry);Optionally, perform a quick check of the validity of the sine function entry by invoking the table definition file at the MATLAB command line (>> tbl = tfl_table_sinfcn2) and by viewing it in the TFL Viewer (>> RTW.viewTfl(tfl_table_sinfcn2)). For more information about validating TFL tables, see Examining and Validating Function Replacement Tables.
Create and save the following TFL registration file, which references the tfl_table_sinfcn2 table.
The file specifies that the TFL to be registered is named 'Sine Function Example 2' and consists of tfl_table_sinfcn2, with the default ANSI[1] math library as the base TFL table.
function sl_customization(cm)
% sl_customization function to register a target function library (TFL)
% Register the TFL defined in local function locTflRegFcn
cm.registerTargetInfo(@locTflRegFcn);
end % End of SL_CUSTOMIZATION
% Local function to define a TFL containing tfl_table_sinfcn2
function thisTfl = locTflRegFcn
% Instantiate a TFL registry entry
thisTfl = RTW.TflRegistry;
% Define the TFL properties
thisTfl.Name = 'Sine Function Example 2';
thisTfl.Description = 'Demonstration of sine function replacement';
thisTfl.TableList = {'tfl_table_sinfcn2'};
thisTfl.BaseTfl = 'C89/C90 (ANSI)';
thisTfl.TargetHWDeviceType = {'*'};
end % End of LOCTFLREGFCNPlace this sl_customization.m file in the MATLAB search path or in the current working directory, so that the TFL is registered at each Simulink startup.
Tip To refresh Simulink customizations within the current MATLAB session, use the command sl_refresh_customizations. (To refresh Embedded MATLAB Coder TFL registration information within a MATLAB session, use the command RTW.TargetRegistry.getInstance('reset');.) |
For more information about registering TFLs with Simulink or Embedded MATLAB Coder software, see Registering Target Function Libraries.
With your sl_customization.m file in the MATLAB search path or in the current working directory, open an ERT-based Simulink model and navigate to the Interface pane of the Configuration Parameters dialog box. Verify that the Target function library option lists the TFL name you specified and select it.
Note If you hover over the selected library with the cursor, a tool tip appears. This tip provides information derived from your TFL registration file, such as the TFL description and the list of tables it contains. |

Optionally, you can relaunch the TFL Viewer, using the MATLAB command RTW.viewTFL with no argument, to examine all registered TFLs, including Sine Function Example 2.
Create an ERT-based model with a Trigonometric Function block set to the sine function, such as the following:

Make sure that the TFL you registered, Sine Function Example 2, is selected for this model.
Go to the Real-Time Workshop > Report pane of the Configuration Parameters dialog box and select the options Create code generation report and Model-to-code. Then go to the Real-Time Workshop pane, select the Generate code only option, and generate code for the model.
Go to the model window and use model-to-code highlighting to trace the code generated using your TFL entry. For example, right-click the Trigonometric Function block and select Real-Time Workshop > Navigate to Code. This selection highlights the sin function code within the model step function in sinefcn.c. In this case, sin has been replaced with mySin in the generated code.

The Real-Time Workshop Embedded Coder software supports the memcpy function for replacement with custom library functions using target function library (TFL) tables.
The following example uses the method described in General Method for Creating Function and Operator Entries to create a TFL table entry for the memcpy function.
Create and save the following TFL table definition file, tfl_table_memcpy.m. This file defines a TFL table containing a function replacement entry for the memcpy function.
The function body sets selected memcpy function entry parameters, creates the y1, u1, u2, and u3 conceptual arguments individually, adds each argument to the conceptual arguments array for the function, and then copies the conceptual arguments to the implementation arguments. Finally the function entry is added to the table.
function hTable = tfl_table_memcpy()
%TFL_TABLE_MEMCPY - Describe memcpy function entry for a TFL table.
hTable = RTW.TflTable;
% Create function replacement entry for void* memcpy(void*, void*, size_t)
fcn_entry = RTW.TflCFunctionEntry;
setTflCFunctionEntryParameters(fcn_entry, ...
'Key', 'memcpy', ...
'Priority', 90, ...
'ImplementationName', 'memcpy_int', ...
'ImplementationHeaderFile', 'memcpy_int.h',...
'SideEffects', true);
% Set SideEffects to 'true' for function returning void to prevent it being
% optimized away
arg = getTflArgFromString(hTable, 'y1', 'void*');
arg.IOType = 'RTW_IO_OUTPUT';
addConceptualArg(fcn_entry, arg);
arg = getTflArgFromString(hTable, 'u1', 'void*');
addConceptualArg(fcn_entry, arg);
arg = getTflArgFromString(hTable, 'u2', 'void*');
addConceptualArg(fcn_entry, arg);
arg = getTflArgFromString(hTable, 'u3', 'size_t');
addConceptualArg(fcn_entry, arg);
copyConceptualArgsToImplementation(fcn_entry);
addEntry(hTable, fcn_entry);Optionally, perform a quick check of the validity of the memcpy entry by invoking the table definition file at the MATLAB command line (>> tbl = tfl_table_memcpy) and by viewing it in the TFL Viewer (>> RTW.viewTfl(tfl_table_memcpy)). For more information about validating TFL tables, see Examining and Validating Function Replacement Tables.
Create and save the following TFL registration file, which references the tfl_table_memcpy table.
The file specifies that the TFL to be registered is named 'Memcpy Function Example' and consists of tfl_table_memcpy, with the default ANSI[2] math library as the base TFL table.
function sl_customization(cm)
% sl_customization function to register a target function library (TFL)
% Register the TFL defined in local function locTflRegFcn
cm.registerTargetInfo(@locTflRegFcn);
end % End of SL_CUSTOMIZATION
% Local function to define a TFL containing tfl_table_memcpy
function thisTfl = locTflRegFcn
% Instantiate a TFL registry entry
thisTfl = RTW.TflRegistry;
% Define the TFL properties
thisTfl.Name = 'Memcpy Function Example';
thisTfl.Description = 'Demonstration of memcpy function replacement';
thisTfl.TableList = {'tfl_table_memcpy'};
thisTfl.BaseTfl = 'C89/C90 (ANSI)';
thisTfl.TargetHWDeviceType = {'*'};
end % End of LOCTFLREGFCNPlace this sl_customization.m file in the MATLAB search path or in the current working directory, so that the TFL is registered at each Simulink startup.
Tip To refresh Simulink customizations within the current MATLAB session, use the command sl_refresh_customizations. (To refresh Embedded MATLAB Coder TFL registration information within a MATLAB session, use the command RTW.TargetRegistry.getInstance('reset');.) |
For more information about registering TFLs with Simulink or Embedded MATLAB Coder software, see Registering Target Function Libraries.
With your sl_customization.m file in the MATLAB search path or in the current working directory, open an ERT-based Simulink model and navigate to the Interface pane of the Configuration Parameters dialog box. Verify that the Target function library option lists the TFL name you specified and select it.
Note If you hover over the selected library with the cursor, a tool tip appears. This tip provides information derived from your TFL registration file, such as the TFL description and the list of tables it contains. |

Optionally, you can relaunch the TFL Viewer, using the MATLAB command RTW.viewTFL with no argument, to examine all registered TFLs, including Memcpy Function Example.
Create an ERT-based model that uses memcpy for vector assignments. For example,
Use In, Out, and Mux blocks to create the following model. (Alternatively, you can open rtwdemo_tflmath/Subsystem1 and copy the subsystem contents to a new model.)

Select the diagram and use Edit > Subsystem to make it a subsystem.

Select an ERT-based system target file on the Real-Time Workshop pane of the Configuration Parameters dialog box, and select the TFL you registered, Memcpy Function Example, on the Interface pane. You should also select a fixed-step solver on the Solver pane. Leave the memcpy options on the Optimization pane at their default settings, that is, Use memcpy for vector assignment selected, and Memcpy threshold (bytes) at 64. Apply the changes.
Open Model Explorer and configure the Signal Attributes for the In1, In2, and In3 source blocks. For each, set Port dimensions to [1,100], and set Data type to int32. Apply the changes. Save the model. In this example, the model is saved to the name memcpyfcn.mdl.
Go to the Real-Time Workshop > Report pane of the Configuration Parameters dialog box and select the Create code generation report. Then go to the Real-Time Workshop pane, select the Generate code only option, and generate code for the model. When code generation completes, the HTML code generation report is displayed.
In the HTML code generation report, click on the model.c section (for example, memcpyfcn.c) and inspect the model step function to confirm that memcpy has been replaced with memcpy_int in the generated code.

The Real-Time Workshop Embedded Coder software supports the following nonfinite support utility functions for replacement with custom library functions using target function library (TFL) tables.
| GetInf |
| GetMinusInf |
| GetNaN |
The following example uses the method described in General Method for Creating Function and Operator Entries to create TFL table entries for the nonfinite functions.
Create and save the following TFL table definition file, tfl_table_nonfinite.m. This file defines a TFL table containing function replacement entries for the nonfinite functions.
For each nonfinite function, the function body uses the local function locAddFcnEnt to create entries for single and double replacement. For each entry, the local function sets selected function entry parameters, creates the y1 and u1 conceptual arguments individually, and then copies the conceptual arguments to the implementation arguments. Finally the function entry is added to the table.
function hTable = tfl_table_nonfinite()
%TFL_TABLE_NONFINITE - Describe function entries for a TFL table.
hTable = RTW.TflTable;
%% Create enries for nonfinite support utility functions
%locAddFcnEnt(hTable, key, implName, out, in1, hdr )
locAddFcnEnt(hTable, 'getNaN', 'getNaN', 'double', 'void', 'nonfin.h');
locAddFcnEnt(hTable, 'getNaN', 'getNaNF', 'single', 'void', 'nonfin.h');
locAddFcnEnt(hTable, 'getInf', 'getInf', 'double', 'void', 'nonfin.h');
locAddFcnEnt(hTable, 'getInf', 'getInfF', 'single', 'void', 'nonfin.h');
locAddFcnEnt(hTable, 'getMinusInf', 'getMinusInf', 'double', 'void', 'nonfin.h');
locAddFcnEnt(hTable, 'getMinusInf', 'getMinusInfF', 'single', 'void', 'nonfin.h');
%% Local Function
function locAddFcnEnt(hTable, key, implName, out, in1, hdr)
if isempty(hTable)
return;
end
fcn_entry = RTW.TflCFunctionEntry;
setTflCFunctionEntryParameters(fcn_entry, ...
'Key', key, ...
'Priority', 90, ...
'ImplementationName', implName, ...
'ImplementationHeaderFile', hdr);
arg = getTflArgFromString(hTable, 'y1', out);
arg.IOType = 'RTW_IO_OUTPUT';
addConceptualArg(fcn_entry, arg);
arg = getTflArgFromString(hTable, 'u1', in1);
addConceptualArg(fcn_entry, arg);
copyConceptualArgsToImplementation(fcn_entry);
addEntry(hTable, fcn_entry);
%EOFOptionally, perform a quick check of the validity of the nonfinite function entries by invoking the table definition file at the MATLAB command line (>> tbl = tfl_table_nonfinite) and by viewing it in the TFL Viewer (>> RTW.viewTfl(tfl_table_nonfinite)). For more information about validating TFL tables, see Examining and Validating Function Replacement Tables.
Create and save the following TFL registration file, which references the tfl_table_nonfinite table.
The file specifies that the TFL to be registered is named 'Nonfinite Functions Example' and consists of tfl_table_nonfinite, with the default ANSI[3] math library as the base TFL table.
function sl_customization(cm)
% sl_customization function to register a target function library (TFL)
% Register the TFL defined in local function locTflRegFcn
cm.registerTargetInfo(@locTflRegFcn);
end % End of SL_CUSTOMIZATION
% Local function to define a TFL containing tfl_table_nonfinite
function thisTfl = locTflRegFcn
% Instantiate a TFL registry entry
thisTfl = RTW.TflRegistry;
% Define the TFL properties
thisTfl.Name = 'Nonfinite Functions Example';
thisTfl.Description = 'Demonstration of nonfinite functions replacement';
thisTfl.TableList = {'tfl_table_nonfinite'};
thisTfl.BaseTfl = 'C89/C90 (ANSI)';
thisTfl.TargetHWDeviceType = {'*'};
end % End of LOCTFLREGFCNPlace this sl_customization.m file in the MATLAB search path or in the current working directory, so that the TFL is registered at each Simulink startup.
Tip To refresh Simulink customizations within the current MATLAB session, use the command sl_refresh_customizations. (To refresh Embedded MATLAB Coder TFL registration information within a MATLAB session, use the command RTW.TargetRegistry.getInstance('reset');.) |
For more information about registering TFLs with Simulink or Embedded MATLAB Coder software, see Registering Target Function Libraries.
With your sl_customization.m file in the MATLAB search path or in the current working directory, open an ERT-based Simulink model and navigate to the Interface pane of the Configuration Parameters dialog box. Verify that the Target function library option lists the TFL name you specified and select it.
Note If you hover over the selected library with the cursor, a tool tip appears. This tip provides information derived from your TFL registration file, such as the TFL description and the list of tables it contains. |

Optionally, you can relaunch the TFL Viewer, using the MATLAB command RTW.viewTFL with no argument, to examine all registered TFLs, including Nonfinite Functions Example.
Create an ERT-based model with a Math Function block set to the rem function, such as the following:

Open Model Explorer and configure the Signal Attributes for the In1 and Constant source blocks. For each, set Data type to double. Apply the changes. Save the model. In this example, the model is saved to the name nonfinitefcns.mdl.
Make sure that the TFL you registered, Nonfinite Functions Example, is selected for this model.
Go to the Real-Time Workshop > Report pane of the Configuration Parameters dialog box and select the option Create code generation report. Then go to the Real-Time Workshop pane, select the Generate code only option, and generate code for the model.
In the HTML code generation report, click on the rtnonfinite.c link and inspect the rt_InitInfAndNaN function to confirm that your replacements for nonfinite support functions are present in the generated code.

The Real-Time Workshop Embedded Coder software supports the following scalar operators for replacement with custom library functions using target function library (TFL) tables:
| + (addition) |
| − (subtraction) |
| * (multiplication) |
| / (division) |
The following example uses the method described in General Method for Creating Function and Operator Entries to create a TFL table entry for the + (addition) operator.
Create and save the following TFL table definition file, tfl_table_add_uint8.m. This file defines a TFL table containing an operator replacement entry for the + (addition) operator.
The function body sets selected addition operator entry parameters, creates the y1, u1, and u2 conceptual arguments individually, and then copies the conceptual arguments to the implementation arguments. Finally, the operator entry is added to the table.
function hTable = tfl_table_add_uint8
%TFL_TABLE_ADD_UINT8 - Describe operator entry for a Target Function Library table.
hTable = RTW.TflTable;
% Create entry for addition of built-in uint8 data type
% Saturation on, Rounding no preference
op_entry = RTW.TflCOperationEntry;
setTflCOperationEntryParameters(op_entry, ...
'Key', 'RTW_OP_ADD', ...
'Priority', 90, ...
'SaturationMode', 'RTW_SATURATE_ON_OVERFLOW', ...
'RoundingMode', 'RTW_ROUND_UNSPECIFIED', ...
'ImplementationName', 'u8_add_u8_u8', ...
'ImplementationHeaderFile', 'u8_add_u8_u8.h', ...
'ImplementationSourceFile', 'u8_add_u8_u8.c' );
arg = getTflArgFromString(hTable, 'y1', 'uint8');
arg.IOType = 'RTW_IO_OUTPUT';
addConceptualArg(op_entry, arg);
arg = getTflArgFromString(hTable, 'u1', 'uint8');
addConceptualArg(op_entry, arg );
arg = getTflArgFromString(hTable, 'u2', 'uint8');
addConceptualArg(op_entry, arg );
copyConceptualArgsToImplementation(op_entry);
addEntry(hTable, op_entry);Optionally, perform a quick check of the validity of the sine function entry by invoking the table definition file at the MATLAB command line (>> tbl = tfl_table_add_uint8) and by viewing it in the TFL Viewer (>> RTW.viewTfl(tfl_table_add_uint8)).
For more information about validating TFL tables, see Examining and Validating Function Replacement Tables.
Create and save the following TFL registration file, which references the tfl_table_add_uint8 table.
The file specifies that the TFL to be registered is named 'Addition Operator Example' and consists of tfl_table_add_uint8, with the default ANSI math library as the base TFL table.
function sl_customization(cm)
% sl_customization function to register a target function library (TFL)
% Register the TFL defined in local function locTflRegFcn
cm.registerTargetInfo(@locTflRegFcn);
end % End of SL_CUSTOMIZATION
% Local function to define a TFL containing tfl_table_add_uint8
function thisTfl = locTflRegFcn
% Instantiate a TFL registry entry
thisTfl = RTW.TflRegistry;
% Define the TFL properties
thisTfl.Name = 'Addition Operator Example';
thisTfl.Description = 'Demonstration of addition operator replacement';
thisTfl.TableList = {'tfl_table_add_uint8'};
thisTfl.BaseTfl = 'C89/C90 (ANSI)';
thisTfl.TargetHWDeviceType = {'*'};
end % End of LOCTFLREGFCNPlace this sl_customization.m file in the MATLAB search path or in the current working directory, so that the TFL is registered at each Simulink startup.
Tip To refresh Simulink customizations within the current MATLAB session, use the command sl_refresh_customizations. (To refresh Embedded MATLAB Coder TFL registration information within a MATLAB session, use the command RTW.TargetRegistry.getInstance('reset');.) |
For more information about registering TFLs with Simulink or Embedded MATLAB Coder software, see Registering Target Function Libraries.
With your sl_customization.m file in the MATLAB search path or in the current working directory, open an ERT-based Simulink model and navigate to the Interface pane of the Configuration Parameters dialog box. Verify that the Target function library option lists the TFL name you specified and select it.
Note If you hover over the selected library with the cursor, a tool tip appears. This tip provides information derived from your TFL registration file, such as the TFL description and the list of tables it contains. |

Optionally, you can relaunch the TFL Viewer, using the MATLAB command RTW.viewTFL with no argument, to examine all registered TFLs, including Addition Operator Example.
Create an ERT-based model with an Add block, such as the following:

Make sure that the TFL you registered, Addition Operator Example, is selected for this model.
Go to the Real-Time Workshop > Report pane of the Configuration Parameters dialog box and select the options Create code generation report and Model-to-code. Then go to the Real-Time Workshop pane, select the Generate code only option, and generate code for the model.
Go to the model window and use model-to-code highlighting to trace the code generated using your TFL entry. For example, right-click the Add block and select Real-Time Workshop > Navigate to Code. This selection highlights the Sum block code within the model step function in add8.c. In this case, code containing the + operator has been replaced with u8_add_u8_u8 in the generated code.

Example: Creating Fixed-Point Operator Entries for Binary-Point-Only Scaling
Example: Creating Fixed-Point Operator Entries for [Slope Bias] Scaling
Example: Creating Fixed-Point Operator Entries for Relative Scaling (Multiplication and Division)
Example: Creating Fixed-Point Operator Entries for Net Slope (Multiplication and Division)
The Real-Time Workshop Embedded Coder software supports TFL-based function replacement for the following scalar operations on fixed-point data types:
| + (addition) |
| − (subtraction) |
| * (multiplication) |
| / (division) |
Fixed-point operator table entries can be defined as matching:
A specific binary-point-only scaling combination on the operator inputs and output.
A specific [slope bias] scaling combination on the operator inputs and output.
Relative scaling or net slope between multiplication or division operator inputs and output.
Use these methods to map a range of slope and bias values to a replacement function for multiplication or division.
Equal slope and zero net bias across addition or subtraction operator inputs and output.
Use this method to disregard specific slope and bias values and map relative slope and bias values to a replacement function for addition or subtraction.
Note
|
Fixed-point numbers use integers and integer arithmetic to represent real numbers and arithmetic with the following encoding scheme:
![]()
where
is an arbitrarily
precise real-world value.
is the approximate
real-world value that results from fixed-point representation.
is an integer
that encodes
, referred to as
the quantized integer.
is a coefficient
of
, referred to as the slope.
is an additive
correction, referred to as the bias.
The general equation for an operation between fixed-point operands is as follows:
![]()
The objective of TFL fixed-point operator replacement is to replace an operator that accepts and returns fixed-point or integer inputs and output with a function that accepts and returns built-in C numeric data types (not fixed-point data types). The following sections provide additional programming information for each supported operator.
Addition. The operation V0 = V1 + V2 implies that

If an addition replacement function is defined such that the scaling on the operands and sum are equal and the net bias

is zero (for example, a function s8_add_s8_s8 that adds two signed 8-bit values and produces a signed 8-bit result), then the TFL operator entry must set the operator entry parameters SlopesMustBeTheSame and MustHaveZeroNetBias to true. (For parameter descriptions, see the reference page for the function setTflCOperationEntryParameters.)
Subtraction. The operation V0 = V1 − V2 implies that

If a subtraction replacement function is defined such that the scaling on the operands and difference are equal and the net bias

is zero (for example, a function s8_sub_s8_s8 that subtracts two signed 8-bit values and produces a signed 8-bit result), then the TFL operator entry must set the operator entry parameters SlopesMustBeTheSame and MustHaveZeroNetBias to true. (For parameter descriptions, see the reference page for the function setTflCOperationEntryParameters.)
Multiplication. There are different ways to specify multiplication replacements. The most direct way is to specify an exact match of the input and output types. This is feasible if a model contains only a few (known) slope and bias combinations. For this, use the TflCOperationEntry class and specify the exact values of slope and bias on each argument. For scenarios where there are numerous slope/bias combinations, it is not feasible to specify each value with a different TFL entry. For this, use a relative scaling factor (RSF) entry or a net slope entry:
Relative scaling factor (RSF) entry:
The operation V0 = V1 * V2 implies, for binary-point-only scaling, that

where Sn is the net slope.
Multiplication replacement functions may be defined such that all scaling is contained by a single operand. For example, a replacement function s8_mul_s8_u8_rsf0p125 can multiply a signed 8-bit value by a factor of [0 ... 0.1245] and produce a signed 8-bit result. The following discussion describes how to convert the slope on each operand into a net factor.
To match a multiplication operation to the s8_mul_s8_u8_rsf0p125 replacement function, 0 <= SnQ2 <= 2 − 3. Substituting the maximum integer value for Q2 results in the following match criteria: When Sn28 = 2 − 3, or Sn = 2 − 11, TFL replacement processing maps the multiplication operation to the s8_mul_s8_u8_rsf0p125 function.
To accomplish this mapping, the TFL operator entry must define a relative scaling factor, F2E, where the values for F and E are provided using operator entry parameters RelativeScalingFactorF and RelativeScalingFactorE. (For parameter descriptions, see the reference page for the function setTflCOperationEntryParameters.) For the s8_mul_s8_u8_rsf0p125 function, the RelativeScalingFactorF would be set to 1 and the RelativeScalingFactorE would be set to -3.
Net slope entry:
Net slope entries are similar to the relative scaling factor entry described above. The difference is the match criteria. For a net slope entry, the net slope of the call-site operation, Sn, must match the specified net slope, Sn = F2E, without regard to the maximum integer value. Specify the desired net slope F and E values using operator entry parameters NetSlopeAdjustmentFactor and NetSlopeFixedExponent. (For parameter descriptions, see the reference page for the function setTflCOperationEntryParameters.)
Division. There are different ways to specify division replacements. The most direct way is to specify an exact match of the input and output types. This is feasible if a model contains only a few (known) slope and bias combinations. For this, use the TflCOperationEntry class and specify the exact values of slope and bias on each argument. For scenarios where there are numerous slope/bias combinations, it is not feasible to specify each value with a different TFL entry. For this, use a relative scaling factor (RSF) entry or a net slope entry:
Relative scaling factor (RSF) entry:
The operation V0 = (V1 / V2) implies, for binary-point-only scaling, that

where Sn is the net slope.
As with multiplication, division replacement functions may be defined such that all scaling is contained by a single operand. For example, a replacement function s16_rsf0p5_div_s16_s16 can divide a signed 16<<16 value by a signed 16-bit value and produce a signed 16-bit result. The following discussion describes how to convert the slope on each operand into a net factor.
To match a division operation to the s16_rsf0p5_div_s16_s16 replacement function, 0 <= SnQ1 <= 2 − 1. Substituting the maximum integer value for Q1 results in the following match criteria: When Sn215 = 2 − 1, or Sn = 2 − 16, TFL replacement processing maps the division operation to the s8_mul_s8_u8_rsf0p125 function.
To accomplish this mapping, the TFL operator entry must define a relative scaling factor, F2E, where the values for F and E are provided using operator entry parameters RelativeScalingFactorF and RelativeScalingFactorE. (For parameter descriptions, see the reference page for the function setTflCOperationEntryParameters.) For the s16_rsf0p5_div_s16_s16 function, the RelativeScalingFactorF would be set to 1 and the RelativeScalingFactorE would be set to -1.
Net slope entry:
Net slope entries are similar to the relative scaling factor entry described above. The difference is the match criteria. For a net slope entry, the net slope of the call-site operation, Sn, must match the specified net slope, Sn = F2E, without regard to the maximum integer value. Specify the desired net slope F and E values using operator entry parameters NetSlopeAdjustmentFactor and NetSlopeFixedExponent. (For parameter descriptions, see the reference page for the function setTflCOperationEntryParameters.)
To create TFL table entries for fixed-point operators, you use the General Method for Creating Function and Operator Entries and specify fixed-point parameter/value pairs to the functions shown in the following table.
| Function | Description |
|---|---|
| createAndAddConceptualArg | Create conceptual argument from specified properties and add to conceptual arguments for TFL table entry |
| createAndAddImplementationArg | Create implementation argument from specified properties and add to implementation arguments for TFL table entry |
| createAndSetCImplementationReturn | Create implementation return argument from specified properties and add to implementation for TFL table entry |
| setTflCOperationEntryParameters | Set specified parameters for operator entry in TFL table |
The following table maps some common methods of matching TFL fixed-point operator table entries to the associated fixed-point parameters that you need to specify in your TFL table definition file.
| To match... | Instantiate class... | Minimally specify parameters... |
|---|---|---|
| A specific binary-point-only scaling combination on the operator
inputs and output See Example: Creating Fixed-Point Operator Entries for Binary-Point-Only Scaling. | RTW.TflCOperationEntry | createAndAddConceptualArg function:
|
| A specific [slope bias] scaling combination on the operator
inputs and output See Example: Creating Fixed-Point Operator Entries for [Slope Bias] Scaling. | RTW.TflCOperationEntry | createAndAddConceptualArg function:
|
| Relative scaling between operator inputs and output (multiplication
and division) See Example: Creating Fixed-Point Operator Entries for Relative Scaling (Multiplication and Division). | RTW.TflCOperationEntryGenerator | setTflCOperationEntryParameters function:
createAndAddConceptualArg function:
|
| Net slope between
operator inputs and output (multiplication and division) See Example: Creating Fixed-Point Operator Entries for Net Slope (Multiplication and Division). | RTW.TflCOperationEntryGenerator_NetSlope | setTflCOperationEntryParameters function:
createAndAddConceptualArg function:
|
| Equal slope and zero net bias across operator inputs and output
(addition and subtraction) See Example: Creating Fixed-Point Operator Entries for Equal Slope and Zero Net Bias (Addition and Subtraction). | RTW.TflCOperationEntryGenerator | setTflCOperationEntryParameters function:
createAndAddConceptualArg function:
|
TFL table entries for operations on fixed-point data types can be defined as matching a specific binary-point-only scaling combination on the operator inputs and output. These binary-point-only scaling entries can map the specified binary-point-scaling combination to a replacement function for addition, subtraction, multiplication, or division.
The following example uses the method described in General Method for Creating Function and Operator Entries to create a TFL table entry for multiplication of fixed-point data types where arguments are specified with binary-point-only scaling. In this example:
The TFL operator entry is instantiated using the RTW.TflCOperationEntry class.
The function setTflCOperationEntryParameters is called to set operator entry parameters. These parameters include the type of operation (multiplication), the saturation mode (saturate on overflow), the rounding mode (unspecified), and the name of the replacement function (s32_mul_s16_s16_binarypoint).
The function createAndAddConceptualArg is called to create and add conceptual output and input arguments to the operator entry. Each argument specifies that the data type is fixed-point, the mode is binary-point-only scaling, and its derived slope and bias values must exactly match the call-site slope and bias values. The output argument is 32 bits, signed, with a fraction length of 28, while the input arguments are 16 bits, signed, with fraction lengths of 15 and 13.
The functions createAndSetCImplementationReturn and createAndAddImplementationArg are called to create and add implementation output and input arguments to the operator entry. Implementation arguments must describe fundamental numeric data types (not fixed-point data types). In this case, the output argument is 32 bits and signed (int32) and the input arguments are 16 bits and signed (int16).
hTable = RTW.TflTable;
op_entry = RTW.TflCOperationEntry;
setTflCOperationEntryParameters(op_entry, ...
'Key', 'RTW_OP_MUL', ...
'Priority', 90, ...
'SaturationMode', 'RTW_SATURATE_ON_OVERFLOW', ...
'RoundingMode', 'RTW_ROUND_UNSPECIFIED', ...
'ImplementationName', 's32_mul_s16_s16_binarypoint', ...
'ImplementationHeaderFile', 's32_mul_s16_s16_binarypoint.h', ...
'ImplementationSourceFile', 's32_mul_s16_s16_binarypoint.c');
createAndAddConceptualArg(op_entry, 'RTW.TflArgNumeric',...
'Name', 'y1', ...
'IOType', 'RTW_IO_OUTPUT', ...
'CheckSlope', true, ...
'CheckBias', true, ...
'DataTypeMode', 'Fixed-point: binary point scaling', ...
'IsSigned', true, ...
'WordLength', 32, ...
'FractionLength', 28);
createAndAddConceptualArg(op_entry, 'RTW.TflArgNumeric', ...
'Name', 'u1', ...
'IOType', 'RTW_IO_INPUT', ...
'CheckSlope', true, ...
'CheckBias', true, ...
'DataTypeMode', 'Fixed-point: binary point scaling', ...
'IsSigned', true, ...
'WordLength', 16, ...
'FractionLength', 15);
createAndAddConceptualArg(op_entry, 'RTW.TflArgNumeric', ...
'Name', 'u2', ...
'IOType', 'RTW_IO_INPUT', ...
'CheckSlope', true, ...
'CheckBias', true, ...
'DataTypeMode', 'Fixed-point: binary point scaling', ...
'IsSigned', true, ...
'WordLength', 16, ...
'FractionLength', 13);
createAndSetCImplementationReturn(op_entry, 'RTW.TflArgNumeric', ...
'Name', 'y1', ...
'IOType', 'RTW_IO_OUTPUT', ...
'IsSigned', true, ...
'WordLength', 32, ...
'FractionLength', 0);
createAndAddImplementationArg(op_entry, 'RTW.TflArgNumeric',...
'Name', 'u1', ...
'IOType', 'RTW_IO_INPUT', ...
'IsSigned', true, ...
'WordLength', 16, ...
'FractionLength', 0);
createAndAddImplementationArg(op_entry, 'RTW.TflArgNumeric',...
'Name', 'u2', ...
'IOType', 'RTW_IO_INPUT', ...
'IsSigned', true, ...
'WordLength', 16, ...
'FractionLength', 0);
addEntry(hTable, op_entry);To generate code using this table entry, you can follow the general procedure in Example: Mapping Operators to Target-Specific Implementations, substituting in the code above and an ERT-based model such as the following:

For this model,
Set the Inport 1 Data type to fixdt(1,16,15)
Set the Inport 2 Data type to fixdt(1,16,13)
In the Product block:
Set Output data type to fixdt(1,32,28)
Select the option Saturate on integer overflow
TFL table entries for operations on fixed-point data types can be defined as matching a specific [slope bias] scaling combination on the operator inputs and output. These [slope bias] scaling entries can map the specified [slope bias] combination to a replacement function for addition, subtraction, multiplication, or division.
The following example uses the method described in General Method for Creating Function and Operator Entries to create a TFL table entry for division of fixed-point data types where arguments are specified using [slope bias] scaling. In this example:
The TFL operator entry is instantiated using the RTW.TflCOperationEntry class.
The function setTflCOperationEntryParameters is called to set operator entry parameters. These parameters include the type of operation (division), the saturation mode (saturate on overflow), the rounding mode (round to ceiling), and the name of the replacement function (s16_div_s16_s16_slopebias).
The function createAndAddConceptualArg is called to create and add conceptual output and input arguments to the operator entry. Each argument specifies that the data type is fixed-point, the mode is [slope bias] scaling, and its specified slope and bias values must exactly match the call-site slope and bias values. The output argument and input arguments are 16 bits, signed, each with specific [slope bias] specifications.
The functions createAndSetCImplementationReturn and createAndAddImplementationArg are called to create and add implementation output and input arguments to the operator entry. Implementation arguments must describe fundamental numeric data types (not fixed-point data types). In this case, the output and input arguments are 16 bits and signed (int16).
hTable = RTW.TflTable;
op_entry = RTW.TflCOperationEntry;
setTflCOperationEntryParameters(op_entry, ...
'Key', 'RTW_OP_DIV', ...
'Priority', 90, ...
'SaturationMode', 'RTW_SATURATE_ON_OVERFLOW', ...
'RoundingMode', 'RTW_ROUND_CEILING', ...
'ImplementationName', 's16_div_s16_s16_slopebias', ...
'ImplementationHeaderFile', 's16_div_s16_s16_slopebias.h', ...
'ImplementationSourceFile', 's16_div_s16_s16_slopebias.c');
createAndAddConceptualArg(op_entry, 'RTW.TflArgNumeric', ...
'Name', 'y1', ...
'IOType', 'RTW_IO_OUTPUT', ...
'CheckSlope', true, ...
'CheckBias', true, ...
'DataTypeMode', 'Fixed-point: slope and bias scaling', ...
'IsSigned', true, ...
'WordLength', 16, ...
'Slope', 15, ...
'Bias', 2);
createAndAddConceptualArg(op_entry, 'RTW.TflArgNumeric', ...
'Name', 'u1', ...
'IOType', 'RTW_IO_INPUT', ...
'CheckSlope', true, ...
'CheckBias', true, ...
'DataTypeMode', 'Fixed-point: slope and bias scaling', ...
'IsSigned', true, ...
'WordLength', 16, ...
'Slope', 15, ...
'Bias', 2);
createAndAddConceptualArg(op_entry, 'RTW.TflArgNumeric', ...
'Name', 'u2', ...
'IOType', 'RTW_IO_INPUT', ...
'CheckSlope', true, ...
'CheckBias', true, ...
'DataTypeMode', 'Fixed-point: slope and bias scaling', ...
'IsSigned', true, ...
'WordLength', 16, ...
'Slope', 13, ...
'Bias', 5);
createAndSetCImplementationReturn(op_entry, 'RTW.TflArgNumeric', ...
'Name', 'y1', ...
'IOType', 'RTW_IO_OUTPUT', ...
'IsSigned', true, ...
'WordLength', 16, ...
'FractionLength', 0);
createAndAddImplementationArg(op_entry, 'RTW.TflArgNumeric',...
'Name', 'u1', ...
'IOType', 'RTW_IO_INPUT', ...
'IsSigned', true, ...
'WordLength', 16, ...
'FractionLength', 0);
createAndAddImplementationArg(op_entry, 'RTW.TflArgNumeric',...
'Name', 'u2', ...
'IOType', 'RTW_IO_INPUT', ...
'IsSigned', true, ...
'WordLength', 16, ...
'FractionLength', 0);
addEntry(hTable, op_entry);To generate code using this table entry, you can follow the general procedure in Example: Mapping Operators to Target-Specific Implementations, substituting in the code above and an ERT-based model such as the following:

For this model,
Set the Inport 1 Data type to fixdt(1,16,15,2)
Set the Inport 2 Data type to fixdt(1,16,13,5)
In the Divide block:
Set Output data type to Inherit: Inherit via back propagation
Set Round integer calculations toward to Ceiling
Select the option Saturate on integer overflow
TFL table entries for multiplication or division of fixed-point data types can be defined as matching relative scaling between operator inputs and output. These relative scaling entries can map a range of slope and bias values to a replacement function for multiplication or division.
The following example uses the method described in General Method for Creating Function and Operator Entries to create a TFL table entry for division of fixed-point data types using a relative scaling factor. In this example:
The TFL operator entry is instantiated using the RTW.TflCOperationEntryGenerator class, which provides access to the fixed-point parameters RelativeScalingFactorF and RelativeScalingFactorE.
The function setTflCOperationEntryParameters is called to set operator entry parameters. These parameters include the type of operation (division), the saturation mode (saturation off), the rounding mode (round to ceiling), and the name of the replacement function (s16_div_s16_s16_rsf0p125). Additionally, RelativeScalingFactorF and RelativeScalingFactorE are used to specify the F and E parts of the relative scaling factor F2E.
The function createAndAddConceptualArg is called to create and add conceptual output and input arguments to the operator entry. Each argument is specified as fixed-point, 16 bits, and signed. Also, each argument specifies that TFL replacement request processing should not check for an exact match to the call-site slope and bias values.
The functions createAndSetCImplementationReturn and createAndAddImplementationArg are called to create and add implementation output and input arguments to the operator entry. Implementation arguments must describe fundamental numeric data types (not fixed-point data types). In this case, the output and input arguments are 16 bits and signed (int16).
hTable = RTW.TflTable;
op_entry = RTW.TflCOperationEntryGenerator;
setTflCOperationEntryParameters(op_entry, ...
'Key', 'RTW_OP_DIV', ...
'Priority', 90, ...
'SaturationMode', 'RTW_WRAP_ON_OVERFLOW', ...
'RoundingMode', 'RTW_ROUND_CEILING', ...
'RelativeScalingFactorF', 1.0, ...
'RelativeScalingFactorE', -3.0, ...
'ImplementationName', 's16_div_s16_s16_rsf0p125', ...
'ImplementationHeaderFile', 's16_div_s16_s16_rsf0p125.h', ...
'ImplementationSourceFile', 's16_div_s16_s16_rsf0p125.c');
createAndAddConceptualArg(op_entry, 'RTW.TflArgNumeric', ...
'Name', 'y1', ...
'IOType', 'RTW_IO_OUTPUT', ...
'CheckSlope', false, ...
'CheckBias', false, ...
'DataType', 'Fixed', ...
'IsSigned', true, ...
'WordLength', 16);
createAndAddConceptualArg(op_entry, 'RTW.TflArgNumeric', ...
'Name', 'u1', ...
'IOType', 'RTW_IO_INPUT', ...
'CheckSlope', false, ...
'CheckBias', false, ...
'DataType', 'Fixed', ...
'IsSigned', true, ...
'WordLength', 16);
createAndAddConceptualArg(op_entry, 'RTW.TflArgNumeric', ...
'Name', 'u2', ...
'IOType', 'RTW_IO_INPUT', ...
'CheckSlope', false, ...
'CheckBias', false, ...
'DataType', 'Fixed', ...
'IsSigned', true, ...
'WordLength', 16);
createAndSetCImplementationReturn(op_entry, 'RTW.TflArgNumeric', ...
'Name', 'y1', ...
'IOType', 'RTW_IO_OUTPUT', ...
'IsSigned', true, ...
'WordLength', 16, ...
'FractionLength', 0);
createAndAddImplementationArg(op_entry, 'RTW.TflArgNumeric',...
'Name', 'u1', ...
'IOType', 'RTW_IO_INPUT', ...
'IsSigned', true, ...
'WordLength', 16, ...
'FractionLength', 0);
createAndAddImplementationArg(op_entry, 'RTW.TflArgNumeric',...
'Name', 'u2', ...
'IOType', 'RTW_IO_INPUT', ...
'IsSigned', true, ...
'WordLength', 16, ...
'FractionLength', 0);
addEntry(hTable, op_entry);To generate code using this table entry, you can follow the general procedure in Example: Mapping Operators to Target-Specific Implementations, substituting in the code above and an ERT-based model such as the following:

For this model,
Set the Inport 1 Data type to int16
Set the Inport 2 Data type to fixdt(1,16,-5)
In the Divide block:
Set Output data type to fixdt(1,16,-13)
Set Round integer calculations toward to Ceiling
TFL table entries for multiplication or division of fixed-point data types can be defined as matching net slope between operator inputs and output. These net slope entries can map a range of slope and bias values to a replacement function for multiplication or division.
The following example uses the method described in General Method for Creating Function and Operator Entries to create a TFL table entry for division of fixed-point data types using a net slope. In this example:
The TFL operator entry is instantiated using the RTW.TflCOperationEntryGenerator_NetSlope class, which provides access to the fixed-point parameters NetSlopeAdjustmentFactor and NetSlopeFixedExponent.
The function setTflCOperationEntryParameters is called to set operator entry parameters. These parameters include the type of operation (division), the saturation mode (wrap on overflow), the rounding mode (unspecified), and the name of the replacement function (user_div_*). Additionally, NetSlopeAdjustmentFactor and NetSlopeFixedExponent are used to specify the F and E parts of the net slope F2E.
The function createAndAddConceptualArg is called to create and add conceptual output and input arguments to the operator entry. Each argument is specified as fixed-point and signed. Also, each argument specifies that TFL replacement request processing should not check for an exact match to the call-site slope and bias values.
The function getTflArgFromString is called to create implementation output and input arguments that are added to the operator entry. Implementation arguments must describe fundamental numeric data types (not fixed-point data types).
function hTable = make_net_slope_tfl_table()
%MAKE_NET_SLOPE_TFL_TABLE - Describe entries for a Target Function Library table.
hTable = RTW.TflTable;
wv = [16,32];
for iy = 1:2
for inum = 1:2
for iden = 1:2
hTable = getDivOpEntry(hTable, ...
fixdt(1,wv(iy)),fixdt(1,wv(inum)),fixdt(1,wv(iden)));
end
end
end
%---------------------------------------------------------
function hTable = getDivOpEntry(hTable,dty,dtnum,dtden)
%---------------------------------------------------------
% Create an entry for division of fixed-point data types where
% arguments are specified using Slope and Bias scaling
% Saturation on, Rounding unspecified
funcStr = sprintf('user_div_%s_%s_%s',...
typeStrFunc(dty),...
typeStrFunc(dtnum),...
typeStrFunc(dtden));
op_entry = RTW.TflCOperationEntryGenerator_NetSlope;
setTflCOperationEntryParameters(op_entry, ...
'Key', 'RTW_OP_DIV', ...
'Priority', 90, ...
'SaturationMode', 'RTW_WRAP_ON_OVERFLOW',...
'RoundingMode', 'RTW_ROUND_UNSPECIFIED',...
'NetSlopeAdjustmentFactor', 1.0, ...
'NetFixedExponent', 0.0, ...
'ImplementationName', funcStr, ...
'ImplementationHeaderFile', [funcStr,'.h'], ...
'ImplementationSourceFile', [funcStr,'.c'] );
createAndAddConceptualArg(op_entry, ...
'RTW.TflArgNumeric', ...
'Name', 'y1',...
'IOType', 'RTW_IO_OUTPUT',...
'CheckSlope', false,...
'CheckBias', false,...
'DataTypeMode', 'Fixed-point: slope and bias scaling',...
'IsSigned', dty.Signed,...
'WordLength', dty.WordLength,...
'Bias', 0);
createAndAddConceptualArg(op_entry, ...
'RTW.TflArgNumeric',...
'Name', 'u1', ...
'IOType', 'RTW_IO_INPUT',...
'CheckSlope', false,...
'CheckBias', false,...
'DataTypeMode', 'Fixed-point: slope and bias scaling',...
'IsSigned', dtnum.Signed,...
'WordLength', dtnum.WordLength,...
'Bias', 0);
createAndAddConceptualArg(op_entry, ...
'RTW.TflArgNumeric', ...
'Name', 'u2', ...
'IOType', 'RTW_IO_INPUT',...
'CheckSlope', false,...
'CheckBias', false,...
'DataTypeMode', 'Fixed-point: slope and bias scaling',...
'IsSigned', dtden.Signed,...
'WordLength', dtden.WordLength,...
'Bias', 0);
arg = getTflArgFromString(hTable, 'y1', typeStrBase(dty));
op_entry.Implementation.setReturn(arg);
arg = getTflArgFromString(hTable, 'u1', typeStrBase(dtnum));
op_entry.Implementation.addArgument(arg);
arg = getTflArgFromString(hTable, 'u2',typeStrBase(dtden));
op_entry.Implementation.addArgument(arg);
addEntry(hTable, op_entry);
%-------------------------------------------------------------
function str = typeStrFunc(dt)
%-------------------------------------------------------------
if dt.Signed
sstr = 's';
else
sstr = 'u';
end
str = sprintf('%s%d',sstr,dt.WordLength);
%-------------------------------------------------------------
function str = typeStrBase(dt)
%-------------------------------------------------------------
if dt.Signed
sstr = ;
else
sstr = 'u';
end
str = sprintf('%sint%d',sstr,dt.WordLength);TFL table entries for addition or subtraction of fixed-point data types can be defined as matching relative slope and bias values (equal slope and zero net bias) across operator inputs and output. These entries allow you to disregard specific slope and bias values and map relative slope and bias values to a replacement function for addition or subtraction.
The following example uses the method described in General Method for Creating Function and Operator Entries to create a TFL table entry for addition of fixed-point data types where slopes must be equal and net bias must be zero across the operator inputs and output. In this example:
The TFL operator entry is instantiated using the RTW.TflCOperationEntryGenerator class, which provides access to the fixed-point parameters SlopesMustBeTheSame and MustHaveZeroNetBias.
The function setTflCOperationEntryParameters is called to set operator entry parameters. These parameters include the type of operation (addition), the saturation mode (saturation off), the rounding mode (unspecified), and the name of the replacement function (u16_add_SameSlopeZeroBias). Additionally, SlopesMustBeTheSame and MustHaveZeroNetBias are set to true to indicate that slopes must be equal and net bias must be zero across the addition inputs and output.
The function createAndAddConceptualArg is called to create and add conceptual output and input arguments to the operator entry. Each argument is specified as 16 bits and unsigned. Also, each argument specifies that TFL replacement request processing should not check for an exact match to the call-site slope and bias values.
The functions createAndSetCImplementationReturn and createAndAddImplementationArg are called to create and add implementation output and input arguments to the operator entry. Implementation arguments must describe fundamental numeric data types (not fixed-point data types). In this case, the output and input arguments are 16 bits and unsigned (uint16).
hTable = RTW.TflTable;
op_entry = RTW.TflCOperationEntryGenerator;
setTflCOperationEntryParameters(op_entry, ...
'Key', 'RTW_OP_ADD', ...
'Priority', 90, ...
'SaturationMode', 'RTW_WRAP_ON_OVERFLOW', ...
'RoundingMode', 'RTW_ROUND_UNSPECIFIED', ...
'SlopesMustBeTheSame', true, ...
'MustHaveZeroNetBias', true, ...
'ImplementationName', 'u16_add_SameSlopeZeroBias', ...
'ImplementationHeaderFile', 'u16_add_SameSlopeZeroBias.h', ...
'ImplementationSourceFile', 'u16_add_SameSlopeZeroBias.c');
createAndAddConceptualArg(op_entry, 'RTW.TflArgNumeric', ...
'Name', 'y1', ...
'IOType', 'RTW_IO_OUTPUT', ...
'CheckSlope', false, ...
'CheckBias', false, ...
'IsSigned', false, ...
'WordLength', 16);
createAndAddConceptualArg(op_entry, 'RTW.TflArgNumeric', ...
'Name', 'u1', ...
'IOType', 'RTW_IO_INPUT', ...
'CheckSlope', false, ...
'CheckBias', false, ...
'IsSigned', false, ...
'WordLength', 16);
createAndAddConceptualArg(op_entry, 'RTW.TflArgNumeric', ...
'Name', 'u2', ...
'IOType', 'RTW_IO_INPUT', ...
'CheckSlope', false, ...
'CheckBias', false, ...
'IsSigned', false, ...
'WordLength', 16);
createAndSetCImplementationReturn(op_entry, 'RTW.TflArgNumeric', ...
'Name', 'y1', ...
'IOType', 'RTW_IO_OUTPUT', ...
'IsSigned', false, ...
'WordLength', 16, ...
'FractionLength', 0);
createAndAddImplementationArg(op_entry, 'RTW.TflArgNumeric',...
'Name', 'u1', ...
'IOType', 'RTW_IO_INPUT', ...
'IsSigned', false, ...
'WordLength', 16, ...
'FractionLength', 0);
createAndAddImplementationArg(op_entry, 'RTW.TflArgNumeric',...
'Name', 'u2', ...
'IOType', 'RTW_IO_INPUT', ...
'IsSigned', false, ...
'WordLength', 16, ...
'FractionLength', 0);
addEntry(hTable, op_entry);To generate code using this table entry, you can follow the general procedure in Example: Mapping Operators to Target-Specific Implementations, substituting in the code above and an ERT-based model such as the following:

For this model,
Set the Inport 1 Data type to fixdt(0,16,13)
Set the Inport 2 Data type to fixdt(0,16,13)
In the Add block:
Verify that Output data type is set to its default, Inherit via internal rule
Set Round integer calculations toward to Zero
As you create TFL table entries for function or operator replacement, you specify the header and source file information for each function implementation using one of the following:
The arguments ImplementationHeaderFile, ImplementationHeaderPath, ImplementationSourceFile, and ImplementationSourcePath to setTflCFunctionEntryParameters or setTflCOperationEntryParameters
The headerFile argument to registerCFunctionEntry or registerCPromotableMacroEntry
Also, each table entry can specify additional header files, source files, and object files to be included in model builds whenever the TFL table entry is matched and used to replace a function or operator in generated code. To add an additional header file, source file, or object file, use the following TFL table creation functions.
| Function | Description |
|---|---|
| addAdditionalHeaderFile | Add additional header file to array of additional header files for TFL table entry |
| addAdditionalIncludePath | Add additional include path to array of additional include paths for TFL table entry |
| addAdditionalLinkObj | Add additional link object to array of additional link objects for TFL table entry |
| addAdditionalLinkObjPath | Add additional link object path to array of additional link object paths for TFL table entry |
| addAdditionalSourceFile | Add additional source file to array of additional source files for TFL table entry |
| addAdditionalSourcePath | Add additional source path to array of additional source paths for TFL table entry |
For function descriptions and examples, see the function reference pages in the Real-Time Workshop Embedded Coder reference documentation.
If a TFL table entry uses header, source, or object files that reside in external directories, and if the table entry is matched and used to replace a function or operator in generated code, the external files will need to be copied to the build directory before the generated code is built. The RTW.copyFileToBuildDir function can be invoked after code generation to copy the table entry's specified header file, source file, additional header files, additional source files, and additional link objects to the build directory. The copied files are then available for use in the build process.
To direct that a table entry's external files should be copied to the build directory after code generation, specify the argument 'RTW.copyFileToBuildDir' to the genCallback parameter of the TFL function that you use to set the table entry parameters, among the following:
The following example defines a table entry for an optimized multiplication function that takes signed 32-bit integers and returns a signed 32-bit integer, taking saturation into account. Multiplications in the generated code will be replaced with calls to your optimized function. Your optimized function resides in an external directory and must be copied into the build directory to be compiled and linked into the application.
The multiplication table entry specifies the source and header file names as well as their full paths. To request the copy to be performed, the table entry specifies the argument 'RTW.copyFileToBuildDir' to the genCallback parameter of the setTflCOperationEntryParameters function. In this example, the header file s32_mul.h contains an inlined function that invokes assembly functions contained in s32_mul.s. If the table entry is matched and used to generate code, the RTW.copyFileToBuildDir function will copy the specified source and header files into the build directory.
function hTable = make_my_tfl_table
hTable = RTW.TflTable;
op_entry = RTW.TflCOperationEntry;
setTflCOperationEntryParameters(op_entry, ...
'Key', 'RTW_OP_MUL', ...
'Priority', 100, ...
'SaturationMode', 'RTW_SATURATE_ON_OVERFLOW', ...
'RoundingMode', 'RTW_ROUND_UNSPECIFIED', ...
'ImplementationName', 's32_mul_s32_s32_sat', ...
'ImplementationHeaderFile', 's32_mul.h', ...
'ImplementationSourceFile', 's32_mul.s', ...
'ImplementationHeaderPath', {fullfile('$(MATLAB_ROOT)','tfl')}, ...
'ImplementationSourcePath', {fullfile('$(MATLAB_ROOT)','tfl')}, ...
'GenCallback', 'RTW.copyFileToBuildDir');
.
.
.
addEntry(hTable, op_entry);The following example shows the use of the addAdditional* functions along with RTW.copyFileToBuildDir.
hTable = RTW.TflTable;
% Path to external source, header, and object files
libdir = fullfile('$(MATLAB_ROOT)','..', '..', 'lib');
op_entry = RTW.TflCOperationEntry;
setTflCOperationEntryParameters(op_entry, ...
'Key', 'RTW_OP_ADD', ...
'Priority', 90, ...
'SaturationMode', 'RTW_SATURATE_UNSPECIFIED', ...
'RoundingMode', 'RTW_ROUND_UNSPECIFIED', ...
'ImplementationName', 's32_add_s32_s32', ...
'ImplementationHeaderFile', 's32_add_s32_s32.h', ...
'ImplementationSourceFile', 's32_add_s32_s32.c'...
'GenCallback', 'RTW.copyFileToBuildDir');
addAdditionalHeaderFile(op_entry, 'all_additions.h');
addAdditionalIncludePath(op_entry, fullfile(libdir, 'include'));
addAdditionalSourceFile(op_entry, 'all_additions.c');
addAdditionalSourcePath(op_entry, fullfile(libdir, 'src'));
addAdditionalLinkObj(op_entry, 'addition.o');
addAdditionalLinkObjsPath(op_entry, fullfile(libdir, 'bin'));
.
.
.
addEntry(hTable, op_entry);The Real-Time Workshop software reserves certain words for its own use as keywords of the generated code language. Real-Time Workshop keywords are reserved for use internal to the Real-Time Workshop software or C programming and should not be used in Simulink models as identifiers or function names. Real-Time Workshop reserved keywords include many TFL identifiers, the majority of which are function names, such as acos. To view the base list of TFL reserved identifiers, see Reserved Keywords in the Real-Time Workshop documentation.
In a TFL table, each function implementation name defined by a table entry is registered as a reserved identifier. You can register additional reserved identifiers for the table on a per-header-file basis. Providing additional reserved identifiers can help prevent duplicate symbols and other identifier-related compile and link issues.
To register additional TFL reserved identifiers, use the following function.
| Function | Description |
|---|---|
| setReservedIdentifiers | Register specified reserved identifiers to be associated with TFL table |
You can register up to four reserved identifier structures in a TFL table. One set of reserved identifiers can be associated with an arbitrary TFL, while the other three (if present) must be associated with ANSI, ISO®[4] , or GNU[5] libraries. The fo