Main Content

Slope Bias Scaling Code Replacement

You can define code replacement for operations on fixed-point data types as matching a slope bias scaling combination on the operator inputs and output. This example shows how to develop a code replacement library to optimize the performance of fixed point data type operations by providing information on how to define code replacement for a division operator. To develop a code replacement library use only the programmatic approach. For more information, see Develop a Code Replacement Library.

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, see Customize Code Match and Replacement for Scalar Operations. You can create and add three additional implementation function arguments for passing fraction lengths in the class definition or in each code replacement entry definition that instantiates this class. This example creates the arguments, adds them to a code replacement table definition file, and sets them to specific values in the class definition code.

classdef TflCustomOperationEntrySlopeBias < RTW.TflCOperationEntryML
  methods
    function ent = do_match(hThis, ...
        hCSO, ... %#ok
        targetBitPerChar, ... %#ok
        targetBitPerShort, ... %#ok
        targetBitPerInt, ... %#ok
        targetBitPerLong, ... %#ok
        targetBitPerLongLong) %#ok

      % DO_MATCH - Create a custom match function. The base class
      % checks the types of the arguments prior to calling this
      % method. This class will check additional data and can
      % modify the implementation function.

      % The base class checks word size and signedness. Slopes and biases
      % have been wildcarded, so the only additional checking to do is
      % to check that the biases are zero and that there are only three
      % conceptual arguments (one output, two inputs)

      ent = []; % default the return to empty, indicating the match failed

      if length(hCSO.ConceptualArgs) == 3

        % Modify the default implementation. Since this is a
        % generator entry, a concrete entry is created using this entry
        % as a template. The type of entry being created is a standard
        % TflCOperationEntry. Using the standard operation entry
        % provides required information, and you do not need
        % a custom match function.
        ent = RTW.TflCOperationEntry(hThis);

        % Set the Slope and Bias values in the implementation function.
        ent.Implementation.Arguments(3).Value = hCSO.ConceptualArgs(2).Type.Slope;
        ent.Implementation.Arguments(4).Value = hCSO.ConceptualArgs(2).Type.Bias;
        ent.Implementation.Arguments(5).Value = hCSO.ConceptualArgs(3).Type.Slope;
        ent.Implementation.Arguments(6).Value = hCSO.ConceptualArgs(3).Type.Bias;
        ent.Implementation.Arguments(7).Value = hCSO.ConceptualArgs(1).Type.Slope;
        ent.Implementation.Arguments(8).Value = hCSO.ConceptualArgs(1).Type.Bias;
      end
    end
  end
end

Programmatically Develop a Code Replacement Library

  1. Open the programmatic interface from the MATLAB menu by selecting New > Function.

  2. Create a table.

    1. Create a function with the name of your code replacement library table that does not have arguments and returns a table object. You can use this function to call your code replacement library table.

    2. Create a table object by calling RTW.TflTable.

    function hTable = crl_table_custom_add_ufix32_slopebias
    % Create a function to call the code replacement library table 
    
    %% Create a table object
    hTable = RTW.TflTable;
    
  3. Create an entry. Because this example replaces a function, create a code replacement entry in your table by calling the custom entry function.

    function hTable = crl_table_custom_add_ufix32_slopebias
    % Create a function to call the code replacement library table 
    
    %% Create a table object
    hTable = RTW.TflTable;
    
    %% Create an entry
    hEntry = TflCustomOperationEntrySlopeBias;;
  4. Create entry parameters. Because this examples replaces a function, create entry parameters by calling the function setTflCFunctionEntryParameters.

    function hTable = crl_table_custom_add_ufix32_slopebias
    % Create a function to call the code replacement library table 
    
    %% Create a table object
    hTable = RTW.TflTable;
    
    %% Create an entry
    hEntry = TflCustomOperationEntrySlopeBias;;
    
    %% Create entry parameters
    setTflCOperationEntryParameters(hEntry, ...
        'Key',                      'RTW_OP_ADD', ...
        'Priority',                 30, ...
        'SaturationMode',           'RTW_SATURATE_ON_OVERFLOW', ...
        'RoundingModes',            {'RTW_ROUND_FLOOR'}, ...
        'ImplementationName',       'myFixptAdd_slopebias', ...
        'ImplementationHeaderFile', 'myFixptAdd.h', ...
        'ImplementationSourceFile', 'myFixptAdd.c');
  5. Create the conceptual representation. The conceptual representation describes the signature of the function that you want to replace. To explicitly specify argument properties, call the function createAndAddConceptualArg.

    function hTable = crl_table_custom_add_ufix32_slopebias
    % Create a function to call the code replacement library table 
    
    %% Create a table object
    hTable = RTW.TflTable;
    
    %% Create an entry
    hEntry = TflCustomOperationEntrySlopeBias;;
    
    %% Create entry parameters
    setTflCOperationEntryParameters(hEntry, ...
        'Key',                      'RTW_OP_ADD', ...
        'Priority',                 30, ...
        'SaturationMode',           'RTW_SATURATE_ON_OVERFLOW', ...
        'RoundingModes',            {'RTW_ROUND_FLOOR'}, ...
        'ImplementationName',       'myFixptAdd_slopebias', ...
        'ImplementationHeaderFile', 'myFixptAdd.h', ...
        'ImplementationSourceFile', 'myFixptAdd.c');
    
    %% Create the conceptual representation
    createAndAddConceptualArg(hEntry, 'RTW.TflArgNumeric', ...
         'Name',       'y1', ...
         'IOType',     'RTW_IO_OUTPUT', ...
         'CheckSlope', false, ...
         'CheckBias',  false, ...
         'DataType',   'Fixed', ...
         'Scaling',    'SlopeBias', ...
         'IsSigned',   false, ...
         'WordLength', 32);
    
    createAndAddConceptualArg(hEntry, 'RTW.TflArgNumeric', ...
          'Name',       'u1', ...
          'IOType',     'RTW_IO_INPUT', ...
          'CheckSlope', false, ...
          'CheckBias',  false, ...
          'DataType',   'Fixed', ...
          'Scaling',    'SlopeBias', ...
          'IsSigned',   false, ...
          'WordLength', 32);
    
    createAndAddConceptualArg(hEntry, 'RTW.TflArgNumeric', ...
           'Name',       'u2', ...
           'IOType',     'RTW_IO_INPUT', ...
           'CheckSlope', false, ...
           'CheckBias',  false, ...
           'DataType',   'Fixed', ...
           'Scaling',    'SlopeBias', ...
           'IsSigned',   false, ...
           'WordLength', 32);
  6. Create the implementation representation. The implementation representation describes the signature of the optimization function. To specify that the implementation arguments have the same order and properties as the conceptual arguments, call the function createAndSetCImplementationReturn and createAndAddImplementationArg. Add the complete entry to the table by calling the function addEntry.

    function hTable = crl_table_custom_add_ufix32_slopebias
    % Create a function to call the code replacement library table 
    
    %% Create a table object
    hTable = RTW.TflTable;
    
    %% Create an entry
    hEntry = TflCustomOperationEntrySlopeBias;;
    
    %% Create entry parameters
    setTflCOperationEntryParameters(hEntry, ...
        'Key',                      'RTW_OP_ADD', ...
        'Priority',                 30, ...
        'SaturationMode',           'RTW_SATURATE_ON_OVERFLOW', ...
        'RoundingModes',            {'RTW_ROUND_FLOOR'}, ...
        'ImplementationName',       'myFixptAdd_slopebias', ...
        'ImplementationHeaderFile', 'myFixptAdd.h', ...
        'ImplementationSourceFile', 'myFixptAdd.c');
    
    %% Create the conceptual representation
    createAndAddConceptualArg(hEntry, 'RTW.TflArgNumeric', ...
         'Name',       'y1', ...
         'IOType',     'RTW_IO_OUTPUT', ...
         'CheckSlope', false, ...
         'CheckBias',  false, ...
         'DataType',   'Fixed', ...
         'Scaling',    'SlopeBias', ...
         'IsSigned',   false, ...
         'WordLength', 32);
    
    createAndAddConceptualArg(hEntry, 'RTW.TflArgNumeric', ...
          'Name',       'u1', ...
          'IOType',     'RTW_IO_INPUT', ...
          'CheckSlope', false, ...
          'CheckBias',  false, ...
          'DataType',   'Fixed', ...
          'Scaling',    'SlopeBias', ...
          'IsSigned',   false, ...
          'WordLength', 32);
    
    createAndAddConceptualArg(hEntry, 'RTW.TflArgNumeric', ...
           'Name',       'u2', ...
           'IOType',     'RTW_IO_INPUT', ...
           'CheckSlope', false, ...
           'CheckBias',  false, ...
           'DataType',   'Fixed', ...
           'Scaling',    'SlopeBias', ...
           'IsSigned',   false, ...
           'WordLength', 32);
    
    %% Create the implementation Representation
    % Specify replacement function signature
    createAndSetCImplementationReturn(hEntry, 'RTW.TflArgNumeric', ...
        'Name',       'y1', ...
        'IOType',     'RTW_IO_OUTPUT', ...
        'IsSigned',   false, ...
        'WordLength', 32, ...
        'FractionLength', 0);
    
    createAndAddImplementationArg(hEntry, 'RTW.TflArgNumeric', ...
        'Name',       'u1', ...
        'IOType',     'RTW_IO_INPUT', ...
        'IsSigned',   false, ...
        'WordLength', 32, ...
        'FractionLength', 0);
    
    createAndAddImplementationArg(hEntry, '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.
    createAndSetCImplementationReturn(hEntry, 'RTW.TflArgNumeric', ...
        'Name',       'y1', ...
        'IOType',     'RTW_IO_OUTPUT', ...
        'IsSigned',   false, ...
        'WordLength', 32, ...
        'FractionLength', 0);
    
    createAndAddImplementationArg(hEntry, 'RTW.TflArgNumeric', ...
        'Name',       'u1', ...
        'IOType',     'RTW_IO_INPUT', ...
        'IsSigned',   false, ...
        'WordLength', 32, ...
        'FractionLength', 0);
    
    createAndAddImplementationArg(hEntry, 'RTW.TflArgNumeric', ...
        'Name',       'u2', ...
        'IOType',     'RTW_IO_INPUT', ...
        'IsSigned',   false, ...
        'WordLength', 32, ...
        'FractionLength', 0);
    
    % Add 6 args for slopes and biases. 
    % Actual values are set during code generation.
    createAndAddImplementationArg(hEntry, 'RTW.TflArgNumericConstant', ...
        'Name',       'slope_in1', ...
        'IOType',     'RTW_IO_INPUT', ...
        'IsSigned',   false, ...
        'WordLength', 32, ...
        'FractionLength', 0, ...
        'Value',       0);
    
    createAndAddImplementationArg(hEntry, 'RTW.TflArgNumericConstant', ...
        'Name',       'bias_in1', ...
        'IOType',     'RTW_IO_INPUT', ...
        'IsSigned',   true, ...
        'WordLength', 32, ...
        'FractionLength', 0, ...
        'Value',       0);
    
    createAndAddImplementationArg(hEntry, 'RTW.TflArgNumericConstant', ...
        'Name',       'slope_in2', ...
        'IOType',     'RTW_IO_INPUT', ...
        'IsSigned',   false, ...
        'WordLength', 32, ...
        'FractionLength', 0, ...
        'Value',       0);
    
    createAndAddImplementationArg(hEntry, 'RTW.TflArgNumericConstant', ...
        'Name',       'bias_in2', ...
        'IOType',     'RTW_IO_INPUT', ...
        'IsSigned',   true, ...
        'WordLength', 32, ...
        'FractionLength', 0, ...
        'Value',       0);
    
    createAndAddImplementationArg(hEntry, 'RTW.TflArgNumericConstant', ...
        'Name',       'slope_out1', ...
        'IOType',     'RTW_IO_INPUT', ...
        'IsSigned',   false, ...
        'WordLength', 32, ...
        'FractionLength', 0, ...
        'Value',       0);
    
    createAndAddImplementationArg(hEntry, 'RTW.TflArgNumericConstant', ...
        'Name',       'bias_out1', ...
        'IOType',     'RTW_IO_INPUT', ...
        'IsSigned',   true, ...
        'WordLength', 32, ...
        'FractionLength', 0, ...
        'Value',       0);
    
    addEntry(hTable, hEntry);
  7. Specify build information. In the entry parameters, specify files (header, source, object) that the code generator needs for code replacement. For this example, build information is not required.

  8. Validate and save the customization file. From the MATLAB menu, save this customization file by selecting File > Save. From the command line, validate the code replacement library table by calling it:

    >> hTable = crl_table_custom_add_ufix32_slopebias
  9. Register the code replacement library. Registration creates a code replacement library by defining the library name, code replacement tables, and other information. Create a registration file (a new function file) with these specifications:

    function rtwTargetInfo(cm)
     
    cm.registerTargetInfo(@loc_register_crl);
    end
     
    function this = loc_register_crl 
     
    this(1) = RTW.TflRegistry; 
    this(1).Name = 'CRL for slope bias scaling function replacement’;
    this(1).TableList = {'crl_table_custom_add_ufix32_slopebias.m'}; 
    % table created in this example
    this(1).TargetHWDeviceType = {'*'};
    this(1).Description = 'Example code replacement library';
    
    end
    

    To use your code replacement library, refresh your current MATLAB session with the command:

    >>sl_refresh_customizations

  10. Verify the code replacement library. From the MATLAB command line, open the library by using the Code Replacement Viewer and verify that the table and entry are correctly specified. For more information, see Verify Code Replacement Library. Configure your model to use the code replacement library, generate code, and verify that replacement occurs as expected. If unexpected behavior occurs, examine the hit and miss logs to troubleshoot the issues.

Related Topics