Customize Match and Replacement Process - MATLAB & Simulink (original) (raw)

During the build process, the code generator uses:

It is possible that preset match criteria and preset replacement function signatures do not completely meet your function and operator replacement needs. For example:

To add extra logic into the code replacement match and replacement process, create custom code replacement table entries. With custom entries, you can specify additional match criteria and modify the replacement function signature to meet application needs.

To create a custom code replacement entry:

  1. Create a custom code replacement entry class, derived from RTW.TflCFunctionEntryML (for function replacement) or RTW.TflCOperationEntryML (for operator replacement).
  2. In your derived class, implement a do_match method with a fixed preset signature as a MATLABĀ® function. In your do_match method, create a copy of an existing type of code replacement entry. On the copy, provide either or both of the following customizations that instantiate the class:
    • Add match criteria that the base class does not provide. The base class provides a match based on:
      * Argument number
      * Argument name
      * Signedness
      * Word size
      * Slope (if not specified with wildcards)
      * Bias (if not specified with wildcards)
      * Math modes, such as saturation and rounding
      * Operator or function key
    • Modify the implementation signature by adding additional arguments or setting constant input argument values. You can inject a constant value, such as an input scaling value, as an additional argument to the replacement function.
  3. Create code replacement entries that instantiate the custom entry class.
  4. Register a library containing the code replacement table that includes your entries.

During code generation, the code replacement match process tries to match function or operator call sites with the base class of your derived entry class. If the process finds a match, the software calls your do_match method to execute your additional match logic (if any) and your replacement function customizations (if any).

Customize Match and Replacement Process for Operators

This example shows how to create custom code replacement entries that add logic to the code match and replacement process for a scalar operation. Custom entries specify additional match criteria or modify the replacement function signature to meet application needs.

For example:

This example modifies a fixed-point addition replacement such that the implementation function passes in the fraction lengths of the input and output data types as arguments.

To create custom code replacement entries that add logic to the code replacement match and replacement process:

  1. Create a class, for example TflCustomOperationEntry, that is derived from the base class RTW.TflCOperationEntryML. The derived class defines a do_match method with the following signature:
    function ent = do_match(hThis, ...
    hCSO, ...
    targetBitPerChar, ...
    targetBitPerShort, ...
    targetBitPerInt, ...
    targetBitPerLong, ...
    targetBitPerLongLong)

In the do_match signature:

  1. Create and save the following code replacement table definition file,crl_table_custom_add_ufix32.m. This file defines a code replacement table that contains a single operator entry, an entry generator for unsigned 32-bit fixed-point addition operations, with arbitrary fraction-length values on the inputs and the output. The table entry:
    • Instantiates the derived class TflCustomOperationEntry from the previous step. If you want to replace word sizes and signedness attributes, you can use the same derived class, but not the same entry, because you cannot use a wild card with the WordLength and IsSigned arguments. For example, to supportuint8, int8,uint16, int16, andint32, add five other distinct entries. To use different implementation functions for saturation and rounding modes other than overflow and round to floor, add entries for those match permutations.
    • Sets operator entry parameters with the call to the setTflCOperationEntryParameters function.
    • Calls the createAndAddConceptualArg function to create conceptual arguments y1,u1, and u2.
    • Calls createAndSetCImplementationReturn and createAndAddImplementationArg to define the signature for the replacement function. Three of the calls tocreateAndAddImplementationArg create implementation arguments to hold the fraction-length values for the inputs and output. Alternatively, the entry can omit those argument definitions. Instead, thedo_match method of the derived classTflCustomOperationEntry can create and add the three implementation arguments. When the number of additional implementation arguments required can vary based on compile-time information, use the alternative approach.
    • Calls addEntry to add the entry to a code replacement table.
      function hTable = crl_table_custom_add_ufix32
      hTable = RTW.TflTable;
      % Add TflCustomOperationEntry
      op_entry = TflCustomOperationEntry;
      setTflCOperationEntryParameters(op_entry, ...
      'Key', 'RTW_OP_ADD', ...
      'Priority', 30, ...
      'SaturationMode', 'RTW_SATURATE_ON_OVERFLOW', ...
      'RoundingModes', {'RTW_ROUND_FLOOR'}, ...
      'ImplementationName', 'myFixptAdd', ...
      'ImplementationHeaderFile', 'myFixptAdd.h', ...
      'ImplementationSourceFile', 'myFixptAdd.c');
      createAndAddConceptualArg(op_entry, 'RTW.TflArgNumeric', ...
      'Name', 'y1', ...
      'IOType', 'RTW_IO_OUTPUT', ...
      'CheckSlope', false, ...
      'CheckBias', false, ...
      'DataType', 'Fixed', ...
      'Scaling', 'BinaryPoint', ...
      'IsSigned', false, ...
      'WordLength', 32);
      createAndAddConceptualArg(op_entry, 'RTW.TflArgNumeric', ...
      'Name', 'u1', ...
      'IOType', 'RTW_IO_INPUT', ...
      'CheckSlope', false, ...
      'CheckBias', false, ...
      'DataType', 'Fixed', ...
      'Scaling', 'BinaryPoint', ...
      'IsSigned', false, ...
      'WordLength', 32);
      createAndAddConceptualArg(op_entry, 'RTW.TflArgNumeric', ...
      'Name', 'u2', ...
      'IOType', 'RTW_IO_INPUT', ...
      'CheckSlope', false, ...
      'CheckBias', false, ...
      'DataType', 'Fixed', ...
      'Scaling', 'BinaryPoint', ...
      'IsSigned', false, ...
      'WordLength', 32);

% Specify replacement function signature
createAndSetCImplementationReturn(op_entry, 'RTW.TflArgNumeric', ...
'Name', 'y1', ...
'IOType', 'RTW_IO_OUTPUT', ...
'IsSigned', false, ...
'WordLength', 32, ...
'FractionLength', 0);
createAndAddImplementationArg(op_entry, 'RTW.TflArgNumeric', ...
'Name', 'u1', ...
'IOType', 'RTW_IO_INPUT', ...
'IsSigned', false, ...
'WordLength', 32, ...
'FractionLength', 0);
createAndAddImplementationArg(op_entry, 'RTW.TflArgNumeric', ...
'Name', 'u2', ...
'IOType', 'RTW_IO_INPUT', ...
'IsSigned', false, ...
'WordLength', 32, ...
'FractionLength', 0);
% Add 3 fraction-length args. Actual values are set during code generation.
createAndAddImplementationArg(op_entry, 'RTW.TflArgNumericConstant', ...
'Name', 'fl_in1', ...
'IOType', 'RTW_IO_INPUT', ...
'IsSigned', false, ...
'WordLength', 32, ...
'FractionLength', 0, ...
'Value', 0);
createAndAddImplementationArg(op_entry, 'RTW.TflArgNumericConstant', ...
'Name', 'fl_in2', ...
'IOType', 'RTW_IO_INPUT', ...
'IsSigned', false, ...
'WordLength', 32, ...
'FractionLength', 0, ...
'Value', 0);
createAndAddImplementationArg(op_entry, 'RTW.TflArgNumericConstant', ...
'Name', 'fl_out', ...
'IOType', 'RTW_IO_INPUT', ...
'IsSigned', false, ...
'WordLength', 32, ...
'FractionLength', 0, ...
'Value', 0);
addEntry(hTable, op_entry); 3. Check the validity of the operator entry.

See Also

Topics