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

Main Content

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 that the base class does not provie. The base class provides a match based on:

You can also use custom entries to modify the replacement function signature to meet application needs. You can:

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 code replacement entry type and provide customizations on the copy.
  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 Code Replacement by Using the Code Replacement Tool

This example shows how to create a custom entry class and custom code replacement entry by using the Code Replacement Tool.

Open the tool. At the command line, enter crtool.

Create a table. In the toolstrip, select New > Table. In the right pane, name the table crl_table_custom. Click Apply.

Create a custom entry class. In the toolstrip, select Customize Code Replacement > Create. In the Create Custom Entry Class dialog box, specify these fields:

Click OK. The tool creates the class file CrlCustomFunctionEntry.m in the namespace CrlCustomEntry. The class contains a do_match function that you use to define the custom entry information.

Automatically generated class file that defines the class CrlCustomFunctionEntry. The do_match method of the class contains a section to insert your custom code.

In the INSERT YOUR CODE HERE section, add code that creates a copy of a code replacement entry and specifies the customizations of that copy. For example, add this code and remove the comment blocks in the first and last lines.

%{ % Only use this sin function if the target int size is 32 bits if targetBitPerInt == 32 % Want to modify the default implementation. Need to create a copy first. % Want to create a regular CFunction Entry since we do not want to keep % adding an implementation arg on every query. ent = RTW.TflCFunctionEntry(hThis);

% In this case, the implementation function takes flag
% indicating degrees vs radians

% The additional argument could be created either in the code replacement 
% definition file or as follows:
ent.createAndAddImplementationArg('RTW.TflArgNumericConstant', ...
    'Name','u2','Type','int32','Value',1);

end %}

This code specifies that the code replacement entry triggers replacement only if the integer size of the target is 32 bits. After adding the uncommented code to the do_match method, save the class.

edited_custom_class.png

Create a code replacement entry by using the custom entry class. In the Code Replacement tool, select New > Custom Entry > CrlCustomEntry.CrlCustomFunctionEntry Entry. The list of available custom entries shows the custom entry classes that are available.

The new custom entry appears in the center pane. In the right pane, configure the entry by specifying information on the Mapping Information and Build Information tabs. For example, from the Function list, select sin. Specify the replacement function Name as my_sin_32. For this example, leave the other parameters and arguments with the default values.

Validate and save the table. Click Validate entry. Save the table by clicking Save.

Register the code replacement library. Registration creates a library composed of the tables that you specify. Click Generate registration file. In the Generate Registration File dialog box, fill out these fields:

Click OK. Refresh your current MATLAB session by using the command sl_refresh_customizations. Now the code replacement library is available for you to select in the model configuration parameters.

Customize Code Match and Replacement for Functions

This example shows how to use custom code replacement table entries to refine the match and replacement logic for functions. The example shows how to:

To exercise the table entries that you create in this example, open CRLMath.slx, which is an ERT-based model with a sine function block.

model = "CRLMath"; open_system(model)

The model contains a Sin block with input and output that have Data type set to double.

In the Configuration Parameters, set Hardware Implementation > Device type to a target platform with a 32-bit integer size. For example, set it to x86-64 (Windows 32).

set_param(model,"ProdHWDeviceType",'Intel->x86-32 (Windows32)')

Create a class that is derived from the base class RTW.TflCFunctionEntryML. For this example, use the pre-written example class TflCustomFunctionEntry.

open("TflCustomFunctionEntry.m");

The derived class defines a do_match method with the signature:

function ent = do_match(hThis, ...

hCSO, ...

targetBitPerChar, ...

targetBitPerShort, ...

targetBitPerInt, ...

targetBitPerLong, ...

targetBitPerLongLong)

In the do_match signature:

The do_match method:

In this case, the do_match method must match only targetBitPerInt, representing the number of bits in the C int data type for the current target, to the value 32. If the code generator finds a match, the method sets the return handle and creates and adds an input argument. The input argument represents whether units are expressed as degrees or radians, to the replacement function signature.

Alternatively, create and add the additional implementation function argument for passing a units flag in each code replacement table definition file that instantiates this class. In that case, this class definition code does not create the argument. That code sets only the argument value. For an example of creating and adding additional implementation function arguments in a table definition file, see step 3.

Create a code replacement table definition file. For example, use the file crl_table_custom_sinfcn_double.m. This file defines a code replacement table that contains a function table entry for sine with double input and output. This entry instantiates the derived class from the previous step, TflCustomFunctionEntry.function hTable = crl_table_custom_sinfcn_double

open("crl_table_custom_sinfcn_double.m");

Check the validity of the code replacement table entry. At the command prompt, invoke the table definition file.

tbl = crl_table_custom_sinfcn_double

tbl = TflTable with properties:

            Version: '1.0'
    ReservedSymbols: []
StringResolutionMap: []
         AllEntries: [1×1 TflCustomFunctionEntry]
        EnableTrace: 1

In the Code Replacement Viewer, view the table definition file.

crviewer(crl_table_custom_sinfcn_double)

Register the code replacement library. Create a file named rtwTargetInfo.m. For this example, copy the contents from the example text file to rtwTargetInfo.m.

delete ("rtwTargetInfo.m") copyfile CRLCustomEntriesRtwTargetInfo.txt rtwTargetInfo.m type rtwTargetInfo.m

function rtwTargetInfo(cm)

cm.registerTargetInfo(@loc_register_crl);

end

function this = loc_register_crl

% Register a code replacement library for use with CRLMath this(1) = RTW.TflRegistry; this(1).Name = 'My Sin CRL'; this(1).TableList = {'crl_table_custom_sinfcn_double'}; this(1).BaseTfl = ''; this(1).TargetHWDeviceType = {'*'}; this(1).Description = '';

% Register a code replacement library for use with CRLMultiplicationDivision this(2) = RTW.TflRegistry; this(2).Name = 'My Element-Wise Multiplication CRL'; this(2).TableList = {'myElemMultCrlTable'}; this(2).BaseTfl = ''; this(2).TargetHWDeviceType = {'*'}; this(2).Description = '';

end

Refresh your current MATLAB session by using the command sl_refresh_customizations.

sl_refresh_customizations;

Set these configuration parameters for the model:

set_param(model,"SystemTargetFile","ert.tlc"); set_param(model,"CodeReplacementLibrary",'My Sin CRL'); sl_refresh_customizations;

When you generate code from the model, the generated code calls the replacement source code.

Warning: An error occurred while evaluating "loc_createToolchain" in "P:\12\amasiphe.Bdoc.j2799853\runnable\matlab\toolbox\rpit\raspiML\registry\rtwTargetInfo.m": Property 'FileName' of the coder.make.ToolchainInfoRegistry object must be set to a valid MAT-file: 'P:\12\amasiphe.Bdoc.j2799853\runnable\matlab\toolbox\rpit\rpiutils\toolchain\gnu_gcc_embeddedlinux_toolchain_gmake_win64_v1.0.mat' does not exist. This custom registration is not loaded.

Searching for referenced models in model 'CRLMath'.

Total of 1 models to build.

Starting build procedure for: CRLMath

Generated code for 'CRLMath' is up to date because no structural, parameter or code replacement library changes were found.

Successful completion of code generation for: CRLMath

Build Summary

0 of 1 models built (1 models already up to date) Build duration: 0h 0m 29.344s

cfile = fullfile("CRLMath_ert_rtw","CRLMath.c"); coder.example.extractLines(cfile,' rtY.Y3 = asin(rtU.U3) + tanh(rtU.U3);','rtY.Y5 = mySin(rtU.U6, 1);',0, 1);

/* Outport: '/Y5' incorporates:

Customize Code Match and Replacement for Nonscalar Operations

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

This example restricts the match criteria for an element-wise multiplication replacement to entries with a specific dimension range. When a match occurs, the custom do_match method modifies the replacement signature to pass the number of elements into the function.

Open the model CRLMultiplicationDivision.slx, which will use the code replacement library.

model = "CRLMultiplicationDivision"; open_system(model)

The model contains the block MultiplyElements, which has:

Create the replacement function source and header files. For this example, use the directory named src, which contains myMulImplLib.c and myMulImplLib.h.

#include "myMulImplLib.h"

void myElemMul_s32(int32_T* u1, int32_T* u2, int32_T* y1, uint32_T numElements) { int idx; for(idx = 0; idx<numElements; ++idx) { y1[idx] = u1[idx] * u2[idx]; } }

#ifndef __myMulImplLib_h #define __myMulImplLib_h

#include "rtwtypes.h"

void myElemMul_s32(int32_T* u1, int32_T* u2, int32_T* y1, uint32_T numElements);

#endif /__myMulImplLib_h/

Create a class that is derived from the base class RTW.TflCOperationEntryML. For this example, use the pre-written class MyElemMultEntry.

open("MyElemMultEntry.m");

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:

The do_match method:

The do_match method relies on the base class for checking data types and dimension ranges. If the code generator finds a match, do_match:

Create a code replacement table definition file. For example, use the file myElemMultCrlTable.m.

open("myElemMultCrlTable.m")

This file defines a code replacement table that contains an operator entry generator for element-wise multiplication. The table entry:

Check the validity of the code replacement table entry. At the command prompt, invoke the table definition file.

tbl = TflTable with properties:

            Version: '1.0'
    ReservedSymbols: []
StringResolutionMap: []
         AllEntries: [1×1 MyElemMultEntry]
        EnableTrace: 1

In the Code Replacement Viewer, view the table definition file.

crviewer(myElemMultCrlTable)

Register the code replacement library. Create a file named rtwTargetInfo.m. For this example, copy the contents from the example text file to rtwTargetInfo.m.

delete ("rtwTargetInfo.m") copyfile CRLCustomEntriesRtwTargetInfo.txt rtwTargetInfo.m type rtwTargetInfo.m

function rtwTargetInfo(cm)

cm.registerTargetInfo(@loc_register_crl);

end

function this = loc_register_crl

% Register a code replacement library for use with CRLMath this(1) = RTW.TflRegistry; this(1).Name = 'My Sin CRL'; this(1).TableList = {'crl_table_custom_sinfcn_double'}; this(1).BaseTfl = ''; this(1).TargetHWDeviceType = {'*'}; this(1).Description = '';

% Register a code replacement library for use with CRLMultiplicationDivision this(2) = RTW.TflRegistry; this(2).Name = 'My Element-Wise Multiplication CRL'; this(2).TableList = {'myElemMultCrlTable'}; this(2).BaseTfl = ''; this(2).TargetHWDeviceType = {'*'}; this(2).Description = '';

end

Refresh your current MATLAB session by using the command sl_refresh_customizations.

sl_refresh_customizations;

Set these configuration parameters for the model:

set_param(model,"SystemTargetFile","ert.tlc"); set_param(model,"CodeReplacementLibrary",'My Element-Wise Multiplication CRL'); sl_refresh_customizations;

When you generate code from the model, the generated code calls the replacement source code.

Warning: An error occurred while evaluating "loc_createToolchain" in "P:\12\amasiphe.Bdoc.j2799853\runnable\matlab\toolbox\rpit\raspiML\registry\rtwTargetInfo.m": Property 'FileName' of the coder.make.ToolchainInfoRegistry object must be set to a valid MAT-file: 'P:\12\amasiphe.Bdoc.j2799853\runnable\matlab\toolbox\rpit\rpiutils\toolchain\gnu_gcc_embeddedlinux_toolchain_gmake_win64_v1.0.mat' does not exist. This custom registration is not loaded.

Searching for referenced models in model 'CRLMultiplicationDivision'.

Total of 1 models to build.

Starting build procedure for: CRLMultiplicationDivision

Generated code for 'CRLMultiplicationDivision' is up to date because no structural, parameter or code replacement library changes were found.

Successful completion of code generation for: CRLMultiplicationDivision

Build Summary

0 of 1 models built (1 models already up to date) Build duration: 0h 0m 5.9679s

cfile = fullfile("CRLMultiplicationDivision_ert_rtw","CRLMultiplicationDivision.c"); coder.example.extractLines(cfile, ' rtY.Out8 = (int16_T)(rtU.In15 / rtU.In16);','/* Model initialize function */',1, 0);

rtY.Out8 = (int16_T)(rtU.In15 / rtU.In16);

/* Outport: '/Out9' incorporates:

Customize Code Match and Replacement for Scalar Operations

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.

Create a class that is derived from the base class RTW.TflCOperationEntryML. For this example, use the pre-written class TflCustomOperationEntry.

type TflCustomOperationEntry.m

classdef TflCustomOperationEntry < 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 && ...
      hCSO.ConceptualArgs(1).Type.Bias == 0 && ...
      hCSO.ConceptualArgs(2).Type.Bias == 0 && ...
      hCSO.ConceptualArgs(3).Type.Bias == 0

    % 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 fraction-length values in the implementation function.
    ent.Implementation.Arguments(3).Value = ...
       -1.0*hCSO.ConceptualArgs(2).Type.FixedExponent;
    ent.Implementation.Arguments(4).Value = ...
       -1.0*hCSO.ConceptualArgs(3).Type.FixedExponent;
    ent.Implementation.Arguments(5).Value = ...
       -1.0*hCSO.ConceptualArgs(1).Type.FixedExponent;
  end
end

end end

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:

The do_match method adds match criteria that the base class does not provide. The method makes modifications to the implementation signature. In this case, the do_match method relies on the base class for checking word size and signedness. do_match must match only the number of conceptual arguments to the value 3 (two inputs and one output) and the bias for each argument to value 0. If the code generator finds a match, do_match:

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.

Create a code replacement table definition file. For this example, use crl_table_custom_add_ufix32.m.

open("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:

Check the validity of the operator entry. At the command prompt, invoke the table definition file.

tbl = crl_table_custom_add_ufix32

tbl = TflTable with properties:

            Version: '1.0'
    ReservedSymbols: []
StringResolutionMap: []
         AllEntries: [1×1 TflCustomOperationEntry]
        EnableTrace: 1

In the Code Replacement Viewer, view the table definition file.

crviewer(crl_table_custom_add_ufix32)

See Also

Topics