Настройка процесса соответствия и замены

В процессе сборки генератор кода использует:

  • Предустановленный набор соответствует критериям, чтобы идентифицировать функции и операторы, для которых специфичные для приложения реализации заменяют реализации по умолчанию.

  • Предустановленная сигнатура функции замены.

Возможно, что предустановленные критерии соответствия и предустановленные сигнатуры функции замены не полностью удовлетворяют вашим потребностям в замене функции и оператора. Для примера:

  • Вы хотите заменить оператор определенной функцией реализации с фиксированной точкой только, когда длины дробей находятся в определенной области значений.

  • Когда происходит соответствие, вы хотите изменить сигнатуру функции замены на основе информации о времени компиляции, такой как передача значений длины дроби в функцию.

Чтобы добавить дополнительную логику в процесс подстановки кода и замены, создайте пользовательские записи таблицы замещения кода. С помощью пользовательских записей можно задать дополнительные критерии соответствия и изменить сигнатуру функции замены в соответствии с потребностями приложения.

Чтобы создать пользовательскую запись о замене кода:

  1. Создайте пользовательский класс записи замены кода, полученный из RTW.TflCFunctionEntryML (for function replacement) or RTW.TflCOperationEntryML (для замены оператора).

  2. В вашем производном классе реализуйте do_match метод с фиксированной предустановленной сигнатурой в виде MATLAB® функция. В вашем do_match method, предоставьте одну или обе из следующих индивидуальных настроек, которые создают экземпляры класса:

    • Добавьте критерии соответствия, которые не предоставляются базовым классом. Базовый класс обеспечивает соответствие, основанное на:

      • Номер аргумента

      • Имя аргумента

      • Signedness

      • Размер слова

      • Наклон (если не задан подстановочными знаками)

      • Смещение (если не задано подстановочными знаками)

      • Математические режимы, такие как насыщение и округление

      • Операторная или функциональная клавиша

    • Измените сигнатуру реализации, добавив дополнительные аргументы или задав постоянные значения входных параметров. Можно ввести постоянное значение, такой как вход значение масштабирования, в качестве дополнительного аргумента в функцию замены.

  3. Создайте записи замены кода, которые создают экземпляры пользовательского класса записи.

  4. Зарегистрируйте библиотеку, содержащую таблицу замещения кода, которая включает ваши записи.

Во время генерации кода процесс соответствия замещения кода пытается соответствовать узлам вызова функции или оператора с базовым классом вашего производного класса входа. Если процесс находит соответствие, программное обеспечение вызывает ваше do_match метод для выполнения дополнительной логики соответствия (при наличии) и индивидуальные настройки функции замены (при наличии).

Настройка процесса соответствия и замены для операторов

В этом примере показано, как создать пользовательские записи замены кода, которые добавляют логику в процесс соответствия кода и замены для скалярной операции. Пользовательские записи задают дополнительные критерии соответствия или изменяют сигнатуру функции замены в соответствии с потребностями приложения.

Для примера:

  • Когда длины дробей находятся в определенной области значений, замените оператор функцией реализации с фиксированной точкой.

  • Когда происходит соответствие, измените сигнатуру функции замены на основе информации о времени компиляции, такой как передача значений длины дроби в функцию.

Этот пример изменяет замену сложения с фиксированной точкой таким образом, чтобы функция реализации проходила в длинах дробей типов входных и выходных данных в качестве аргументов.

Чтобы создать пользовательские записи замены кода, которые добавляют логику в процесс замены кода, совпадают и заменяют:

  1. Создайте класс, например 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

    Выйдите из папки класса и вернитесь в предыдущую рабочую папку.

  2. Создайте и сохраните следующий файл определения таблицы замещения кода, 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);
    
  3. Проверьте валидность записи оператора.

    • В командной строке активируйте файл определения таблицы.

      tbl = crl_table_custom_add_ufix32
    • В окне Code Replacement Viewer просмотрите файл определения таблицы.

      crviewer(crl_table_custom_add_ufix32)

Похожие темы