В процессе сборки генератор кода использует:
Предустановленный набор соответствует критериям, чтобы идентифицировать функции и операторы, для которых специфичные для приложения реализации заменяют реализации по умолчанию.
Предустановленная сигнатура функции замены.
Возможно, что предустановленные критерии соответствия и предустановленные сигнатуры функции замены не полностью удовлетворяют вашим потребностям в замене функции и оператора. Для примера:
Вы хотите заменить оператор определенной функцией реализации с фиксированной точкой только, когда длины дробей находятся в определенной области значений.
Когда происходит соответствие, вы хотите изменить сигнатуру функции замены на основе информации о времени компиляции, такой как передача значений длины дроби в функцию.
Чтобы добавить дополнительную логику в процесс подстановки кода и замены, создайте пользовательские записи таблицы замещения кода. С помощью пользовательских записей можно задать дополнительные критерии соответствия и изменить сигнатуру функции замены в соответствии с потребностями приложения.
Чтобы создать пользовательскую запись о замене кода:
Создайте пользовательский класс записи замены кода, полученный из RTW.TflCFunctionEntryML (for function replacement) or RTW.TflCOperationEntryML
(для замены оператора).
В вашем производном классе реализуйте do_match
метод с фиксированной предустановленной сигнатурой в виде MATLAB® функция. В вашем do_match
method, предоставьте одну или обе из следующих индивидуальных настроек, которые создают экземпляры класса:
Добавьте критерии соответствия, которые не предоставляются базовым классом. Базовый класс обеспечивает соответствие, основанное на:
Номер аргумента
Имя аргумента
Signedness
Размер слова
Наклон (если не задан подстановочными знаками)
Смещение (если не задано подстановочными знаками)
Математические режимы, такие как насыщение и округление
Операторная или функциональная клавиша
Измените сигнатуру реализации, добавив дополнительные аргументы или задав постоянные значения входных параметров. Можно ввести постоянное значение, такой как вход значение масштабирования, в качестве дополнительного аргумента в функцию замены.
Создайте записи замены кода, которые создают экземпляры пользовательского класса записи.
Зарегистрируйте библиотеку, содержащую таблицу замещения кода, которая включает ваши записи.
Во время генерации кода процесс соответствия замещения кода пытается соответствовать узлам вызова функции или оператора с базовым классом вашего производного класса входа. Если процесс находит соответствие, программное обеспечение вызывает ваше do_match
метод для выполнения дополнительной логики соответствия (при наличии) и индивидуальные настройки функции замены (при наличии).
В этом примере показано, как использовать пользовательские записи таблицы замещения кода для уточнения логики соответствия и замены функций. Пример показывает, как:
Измените замену функции синуса, только если размер целого числа на текущей целевой платформе составляет 32 бита.
Измените замену так, чтобы функция реализации прошла в градусах от радианов как входной параметр.
Чтобы выполнить записи таблицы, которые вы создаете в этом примере, создайте модель на основе ERT с блоком функции синуса. Для примера:
В параметрах блоков Inport установите Data type сигнала равным double
. Если значение, выбранное для Configuration Parameters > Hardware Implementation > Device type, поддерживает целочисленный размер, отличный от 32, выполните одно из следующих действий:
Выберите временную целевую платформу с 32-битным целым размером.
Измените код так, чтобы он совпадал с целым размером целевой платформы.
Создайте класс, например TflCustomFunctionEntry
, который получают из базового класса RTW.TflCFunctionEntryML
. Производный класс задает do_match
метод с подписью:
function ent = do_match(hThis, ... hCSO, ... targetBitPerChar, ... targetBitPerShort, ... targetBitPerInt, ... targetBitPerLong, ... targetBitPerLongLong)
В do_match
подпись:
ent
- указатель на возврат, который возвращается как пустой (что указывает на неудачу соответствия) или как TflCFunctionEntry
указатель.
hThis
является указателем на образец класса.
hCSO
является указателем на объект, который генератор кода создает для запроса библиотеки на замену.
Остальными аргументами являются количество бит для различных типов данных текущего целевого объекта.
The do_match
метод:
Добавляет требуемые дополнительные критерии соответствия, которые базовый класс не предоставляет.
Вносит необходимые изменения в сигнатуру реализации.
В этом случае do_match
метод должен совпадать только с targetBitPerInt
, представляющий количество биты в C int
тип данных для текущего целевого объекта, равный значению 32. Если генератор кода находит соответствие, метод устанавливает указатель на возврат, создает и добавляет входной параметр. Этот входной параметр представляет, выражены ли модули как степени или радианы, сигнатуре функции замены.
Кроме того, создайте и добавьте дополнительный аргумент функции реализации для передачи флага модулей измерения в каждом файле определения таблицы замещения кода, который создает экземпляры этого класса. В этом случае этот код определения класса не создает аргумент. Этот код устанавливает только значение аргумента. Пример создания и добавления дополнительных аргументов функции реализации в файл определения таблицы см. в разделе Настройка соответствия кода и замена для скалярных операций.
classdef TflCustomFunctionEntry < RTW.TflCFunctionEntryML 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 will check additional data and perhaps modify % the implementation function. ent = []; % default the return to empty, indicating the match failed. % Match sine function only if the target int size is 32 bits if targetBitPerInt == 32 % Need to modify the default implementation, starting from a copy % of the standard TflCFunctionEntry. ent = RTW.TflCFunctionEntry(hThis); % If the target int size is 32 bits, the implementation function % takes an additional input flag argument indicating degress vs. % radians. The additional argument can be created and added either % in the CRL table definition file that instantiates this class, or % here in the class definition, as follows: createAndAddImplementationArg(ent, 'RTW.TflArgNumericConstant', ... 'Name', 'u2', ... 'IsSigned', true, ... 'WordLength', 32, ... 'FractionLength', 0, ... 'Value', 1); end end end end
Выйдите из папки класса и вернитесь в предыдущую рабочую папку.
Создайте и сохраните следующий файл определения таблицы замещения кода, crl_table_custom_sinfcn_double.m
. Этот файл определяет таблицу замещения кода, которая содержит запись таблицы функций для синуса с double
вход и выход. Эта запись создает экземпляры производного класса из предыдущего шага TflCustomFunctionEntry
.
function hTable = crl_table_custom_sinfcn_double hTable = RTW.TflTable; %% Add TflCustomFunctionEntry fcn_entry = TflCustomFunctionEntry; setTflCFunctionEntryParameters(fcn_entry, ... 'Key', 'sin', ... 'Priority', 30, ... 'ImplementationName', 'mySin', ... 'ImplementationHeaderFile', 'mySin.h', ... 'ImplementationSourceFile', 'mySin.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'); % TflCustomFunctionEntry class do_match method will create and add % an implementation function argument during code generation if % the supported integer size on the current target is 32 bits. copyConceptualArgsToImplementation(fcn_entry); addEntry(hTable, fcn_entry);
Проверьте валидность записи таблицы замещения кода.
В командной строке активируйте файл определения таблицы.
tbl = crl_table_custom_sinfcn_double
В окне Code Replacement Viewer просмотрите файл определения таблицы.
crviewer(crl_table_custom_sinfcn_double)
В этом примере показано, как создать пользовательские записи замены кода, которые добавляют логику в процесс соответствия кода и замены для нескалярной операции. Пользовательские записи задают дополнительные критерии соответствия или изменяют сигнатуру функции замены в соответствии с потребностями приложения.
Этот пример ограничивает критерии соответствия для поэлементной замены умножения записями с определенной областью значений размерностей. Когда происходит соответствие, пользовательский do_match
метод изменяет сигнатуру замены, чтобы передать количество элементов в функцию.
Файлы для разработки и проверки этого примера библиотеки замещения кода доступны в matlab/help/toolbox/ecoder/examples/code_replacement/custom_elemmult
:
do_match
метод - @MyElemMultEntry/MyElemMultEntry.m
Источник функции замены и файлы заголовков - src/myMulImplLib.c
и src/myMulImplLib.h
Модель - myElemMul.slx
Определение таблицы замещения кода - myElemMultCrlTable.m
Файл регистрации - rtwTargetInfo.m
Чтобы создать пользовательские записи замены кода, которые добавляют логику в процесс замены кода, совпадают и заменяют:
Создайте класс, например MyElemMultEntry
, который получают из базового класса RTW.TflCOperationEntryML
. Производный класс задает a do_match
метод со следующей сигнатурой:
function ent = do_match(hThis, ... hCSO, ... targetBitPerChar, ... targetBitPerShort, ... targetBitPerInt, ... targetBitPerLong, ... targetBitPerLongLong)
В do_match
подпись:
ent
- указатель на возврат, который возвращается как пустой (что указывает на неудачу соответствия) или как TflCOperationEntry
указатель.
hThis
- указатель на производный образец.
hCSO
является указателем на объект, который генератор кода создает для запроса библиотеки на замену.
Остальными аргументами являются количество бит для различных типов данных текущего целевого объекта.
do_match
метод:
Добавляет критерий соответствия, который базовый класс не предоставляет.
Вносит изменения в сигнатуру реализации.
do_match
метод полагается на базовый класс для проверки типов данных и областей значений размерностей. Если генератор кода находит совпадение, do_match
:
Устанавливает указатель на возврат.
Использует концептуальные аргументы, чтобы вычислить количество элементов в массиве. В возвращенной записи замены устанавливает значение аргумента постоянной реализации как количество элементов массива.
Обновляет запись замены кода так, чтобы она совпадала с CSO, которые имеют одинаковые размерности аргументов.
classdef MyElemMultEntry < RTW.TflCOperationEntryML methods function obj = MyElemMultEntry(varargin) mlock; obj@RTW.TflCOperationEntryML(varargin{:}); end function ent = do_match(hThis, ... hCSO, ... %#ok targetBitPerChar, ... %#ok targetBitPerShort, ... %#ok targetBitPerInt, ... %#ok targetBitPerLong, ... %#ok targetBitPerLongLong ) %#ok % Fourth implementation arg represents number of elements for producing matches. assert(strcmp(hThis.Implementation.Arguments(4).Name,'numElements')); ent = RTW.TflCOperationEntry(hThis); % Calculate number of elements and set value of injected constant. ent.Implementation.Arguments(4).Value = prod(hCSO.ConceptualArgs(1).DimRange(1,:)); % Since implementation has been modified for specific DimRange, update % returned entry to match similar CSOs only. for idx =1:3 ent.ConceptualArgs(idx).DimRange = hCSO.ConceptualArgs(idx).DimRange; end end end end
Создайте и сохраните следующий файл определения таблицы замещения кода, myElemMultCrlTable.m
. Этот файл задает таблицу замещения кода, которая содержит генератор ввода оператора для поэлементного умножения. Запись в таблице:
Экземпляры производного класса myElemMultEntry
с предыдущего шага.
Устанавливает параметры входа оператора с вызовом на setTflCOperationEntryParameters
функция.
Создает концептуальные аргументы y1
, u1
, и u2
. Класс аргумента RTW.TflArgMatrix
задает матричные аргументы, которые будут совпадать. Три аргумента настроены так, чтобы соответствовать 2-мерным матрицам с по крайней мере двумя элементами в каждой размерности.
Вызывает getTflArgFromString
функция для создания возврата значения и четырех аргументов реализации. Аргументы u1
и u2
являются ли операнды, y1
является продуктом, и четвертый аргумент является количеством элементов.
Кроме того, do_match
метод производного класса myElemMultEntry
может создавать и добавлять аргументы реализации. Когда количество дополнительных аргументов реализации может варьироваться на основе информации о времени компиляции, используйте альтернативный подход.
Вызовы addEntry
для добавления записи в таблицу замещения кода.
function hLib = myElemMultCrlTable libPath = fullfile(fileparts(which(mfilename)),'src'); hLib = RTW.TflTable; %---------- entry: RTW_OP_ELEM_MUL ----------- hEnt = MyElemMultEntry; hEnt.setTflCOperationEntryParameters( ... 'Key', 'RTW_OP_ELEM_MUL', ... 'Priority', 100, ... 'SaturationMode', 'RTW_WRAP_ON_OVERFLOW', ... 'ImplementationName', 'myElemMul_s32', ... 'ImplementationSourceFile', 'myMulImplLib.c', ... 'ImplementationSourcePath', libPath, ... 'ImplementationHeaderFile', 'myMulImplLib.h', ... 'ImplementationHeaderPath', libPath, ... 'SideEffects', true, ... 'GenCallback','RTW.copyFileToBuildDir'); % Conceptual Args arg = RTW.TflArgMatrix('y1', 'RTW_IO_OUTPUT', 'int32'); arg.DimRange = [2 2; Inf Inf]; hEnt.addConceptualArg(arg); arg = RTW.TflArgMatrix('u1', 'RTW_IO_INPUT', 'int32'); arg.DimRange = [2 2; Inf Inf]; hEnt.addConceptualArg(arg); arg = RTW.TflArgMatrix('u2', 'RTW_IO_INPUT', 'int32'); arg.DimRange = [2 2; Inf Inf]; hEnt.addConceptualArg(arg); % Implementation Args arg = hEnt.getTflArgFromString('unused','void'); arg.IOType = 'RTW_IO_OUTPUT'; hEnt.Implementation.setReturn(arg); arg = hEnt.getTflArgFromString('u1','int32*'); hEnt.Implementation.addArgument(arg); arg = hEnt.getTflArgFromString('u2','int32*'); hEnt.Implementation.addArgument(arg); arg = hEnt.getTflArgFromString('y1','int32*'); arg.IOType = 'RTW_IO_OUTPUT'; hEnt.Implementation.addArgument(arg); arg = hEnt.getTflArgFromString('numElements','uint32',0); hEnt.Implementation.addArgument(arg); hLib.addEntry( hEnt );
Проверьте валидность записи таблицы замещения кода.
В командной строке активируйте файл определения таблицы.
tbl = myElemMultCrlTable
В окне Code Replacement Viewer просмотрите файл определения таблицы.
crviewer(myElemMultCrlTable)
В этом примере показано, как создать пользовательские записи замены кода, которые добавляют логику в процесс соответствия кода и замены для скалярной операции. Пользовательские записи задают дополнительные критерии соответствия или изменяют сигнатуру функции замены в соответствии с потребностями приложения.
Для примера:
Когда длины дробей находятся в определенной области значений, замените оператор функцией реализации с фиксированной точкой.
Когда происходит соответствие, измените сигнатуру функции замены на основе информации о времени компиляции, такой как передача значений длины дроби в функцию.
Этот пример изменяет замену сложения с фиксированной точкой таким образом, чтобы функция реализации проходила в длинах дробей типов входных и выходных данных в качестве аргументов.
Чтобы создать пользовательские записи замены кода, которые добавляют логику в процесс замены кода, совпадают и заменяют:
Создайте класс, например TflCustomOperationEntry
, который получают из базового класса RTW.TflCOperationEntryML
. Производный класс задает a do_match
метод со следующей сигнатурой:
function ent = do_match(hThis, ... hCSO, ... targetBitPerChar, ... targetBitPerShort, ... targetBitPerInt, ... targetBitPerLong, ... targetBitPerLongLong)
В do_match
подпись:
ent
- указатель на возврат, который возвращается как пустой (что указывает на неудачу соответствия) или как TflCOperationEntry
указатель.
hThis
- указатель на образец класса.
hCSO
является указателем на объект, который генератор кода создает для запроса библиотеки на замену.
Остальными аргументами являются количество бит для различных типов данных текущего целевого объекта.
do_match
метод добавляет критерии соответствия, которые не предоставляет базовый класс. Метод вносит изменения в сигнатуру реализации. В этом случае, do_match
метод полагается на базовый класс для проверки размера слова и сигнальности. do_match
должно совпадать только с количеством концептуальных аргументов, равным значению 3 (два входов и один выход) и смещением для каждого аргумента, равным значению 0. Если генератор кода находит совпадение, do_match
:
Устанавливает указатель на возврат.
Удаляет подстановочные карточки уклона и смещения из концептуальных аргументов (соответствие для определенных значений уклона и смещения).
Значения длины дроби для входов и выхода записываются в аргументы функции замены 3, 4 и 5.
Можно создать и добавить три дополнительных аргумента функции реализации для передачи длин дробей в определении класса или в каждом определении записи замены кода, которое создает экземпляры этого класса. Этот пример создает аргументы, добавляет их в файл определения таблицы замещения кода и устанавливает их на определенные значения в коде определения класса.
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); % Since this entry is modifying the implementation for specific % fraction-length values (arguments 3, 4, and 5), the conceptual argument % wild cards must be removed (the wildcards were inherited from the % generator when it was used as a template for the concrete entry). % This concrete entry is now for a specific slope and bias. % hCSO holds the slope and bias values (created by the code generator). for idx=1:3 ent.ConceptualArgs(idx).CheckSlope = true; ent.ConceptualArgs(idx).CheckBias = true; % Set the specific Slope and Biases ent.ConceptualArgs(idx).Type.Slope = hCSO.ConceptualArgs(idx).Type.Slope; ent.ConceptualArgs(idx).Type.Bias = 0; end % 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
Выйдите из папки класса и вернитесь в предыдущую рабочую папку.
Создайте и сохраните следующий файл определения таблицы замещения кода, crl_table_custom_add_ufix32.m
. Этот файл задает таблицу замещения кода, которая содержит одну запись оператора, генератор записи для беззнаковых 32-битных операций сложения с фиксированной точкой с произвольными значениями длины дроби на входах и выходе. Запись в таблице:
Экземпляры производного класса TflCustomOperationEntry
с предыдущего шага. Если вы хотите заменить размеры слов и атрибуты signedness, можно использовать тот же производный класс, но не ту же запись, поскольку вы не можете использовать wild-карту с WordLength
и IsSigned
аргументы. Например, для поддержки uint8
, int8
, uint16
, int16
, и int32
, добавить пять других отдельных записей. Чтобы использовать различные функции реализации для режимов насыщения и округления, кроме переполнения и округления на пол, добавьте записи для тех, которые соответствуют сочетаниям.
Устанавливает параметры входа оператора с вызовом на setTflCOperationEntryParameters
функция.
Вызывает createAndAddConceptualArg
функция для создания концептуальных аргументов y1
, u1
, и u2
.
Вызовы createAndSetCImplementationReturn
и createAndAddImplementationArg
для определения подписи для функции замены. Три из вызовов на createAndAddImplementationArg
создайте аргументы реализации, чтобы сохранить значения длины дроби для входов и вывода. Кроме того, запись может опускать эти определения аргументов. Вместо этого, do_match
метод производного класса TflCustomOperationEntry
может создать и добавить три аргумента реализации. Когда количество дополнительных аргументов реализации может варьироваться на основе информации о времени компиляции, используйте альтернативный подход.
Вызовы addEntry
для добавления записи в таблицу замещения кода.
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);
Проверьте валидность записи оператора.
В командной строке активируйте файл определения таблицы.
tbl = crl_table_custom_add_ufix32
В окне Code Replacement Viewer просмотрите файл определения таблицы.
crviewer(crl_table_custom_add_ufix32)