Сгенерированный код с фиксированной точкой

Расположение сгенерированных файлов с фиксированной точкой

По умолчанию процесс преобразования с фиксированной точкой генерирует файлы в папке с именем codegen/fcn_name/fixpt в локальной рабочей папке. fcn_name - имя MATLAB;® функция, которую вы преобразуете в фиксированную точку.

Имя файлаОписание
fcn_name_fixpt.m

Сгенерирован код MATLAB с фиксированной точкой.

Чтобы интегрировать этот код с фиксированной точкой в большее приложение, рассмотрите генерацию MEX-функции для функции и вызов этой MEX-функции вместо оригинального кода MATLAB.

fcn_name_fixpt_exVal.mat

MAT-файл, содержащий:

  • Структура для входных параметров.

  • Имя файла с фиксированной точкой.

fcn_name_fixpt_report.html

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

fcn_name_report.html

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

fcn_name_wrapper_fixpt.m

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

Минимизация fi-касты для улучшения читаемости кода

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

Например, вот код с фиксированной точкой, сгенерированный для постоянного выражения x = 1/sqrt(2) если выбранный размер слова равен 14.

Оригинальный код MATLABСгенерированный код с фиксированной точкой

x = 1/sqrt(2);

x = fi(1/sqrt(2), 0, 14, 14, fm);

fm является локальным fimath.

Избегание переполнений в сгенерированном коде с фиксированной точкой

Процесс преобразования избегает переполнения:

  • Использование полноточной арифметики, если вы не задаете обратное.

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

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

    Процесс преобразования с фиксированной точкой приводит к не- fi выражения соответствующей fi тип.

    Например, рассмотрите следующий алгоритм MATLAB.

    % A = 5;
    % B = ones(300, 1)
    function y = fi_plus_non_fi(A, B)
      % '1024' is non-fi, cast it
      y = A + 1024;
      % 'size(B, 1)*length(A)' is a non-fi, cast it
      y = A + size(B, 1)*length(A);
    end

    Сгенерированный код с фиксированной точкой:

    %#codegen
    % A = 5;
    % B = ones(300, 1)
    function y = fi_plus_non_fi_fixpt(A, B)
      % '1024' is non-fi, cast it
      fm = fimath('RoundingMethod', 'Floor', 'OverflowAction', 'Wrap', 'ProductMode', 'FullPrecision', 'MaxProductWordLength', 128, 'SumMode', 'FullPrecision', 'MaxSumWordLength', 128);
    
      y = fi(A + fi(1024, 0, 11, 0, fm), 0, 11, 0, fm);
      % 'size(B, 1)*length(A)' is a non-fi, cast it
      y(:) = A + fi(size(B, fi(1, 0, 1, 0, fm))*length(A), 0, 9, 0, fm);
    end

Управление ростом разрядности

Процесс преобразования управляет ростом разрядности с помощью подписанных назначений, то есть назначений, которые используют оператор двоеточия (:), в сгенерированном коде. При использовании подписанных назначений MATLAB перезаписывает значение левого аргумента, но сохраняет существующий тип данных и размер массива. Использование подписанного назначения сохраняет фиксированную точку переменных с фиксированной точкой, а не непреднамеренно превращает их в двойные значения. Поддержание типа с фиксированной точкой уменьшает количество объявлений типов в сгенерированном коде. Подписанное назначение также препятствует росту разрядности, что полезно, когда необходимо поддерживать конкретный тип данных для выхода.

Предотвращение потери области значений или точности

Избежание потери области значений или точности при операциях вычитания без знака

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

Например, рассмотрите следующий алгоритм MATLAB.

% A = 1;
% B = 5
function [y,z] = unsigned_subtraction(A,B)
  y = A - B;
  
  C = -20;
  z = C - B;
end

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

%#codegen
% A = 1;
% B = 5
function [y,z] = unsigned_subtraction_fixpt(A,B)
 
fm = fimath('RoundingMethod', 'Floor', 'OverflowAction', 'Wrap', 'ProductMode', 'FullPrecision', 'MaxProductWordLength', 128, 'SumMode', 'FullPrecision', 'MaxSumWordLength', 128);
y = fi(fi_signed(A) - B, 1, 3, 0, fm);
C = fi(-20, 1, 6, 0, fm);
z = fi(C - B, 1, 6, 0, fm);
end
 
 
function y = fi_signed(a)
coder.inline( 'always' );
if isfi( a ) && ~(issigned( a ))
  nt = numerictype( a );
  new_nt = numerictype( 1, nt.WordLength + 1, nt.FractionLength );
  y = fi( a, new_nt, fimath( a ) );
else
  y = a;
end
end

Избегание потери области значений при конкатенации массивов чисел с фиксированной точкой

Если вы конкатенируете матрицы, используя vertcat и horzcatпроцесс преобразования использует самый большой числовой тип среди выражений строки и помещает самый левый элемент в этот тип. Этот тип затем используется для конкатенированной матрицы, чтобы избежать потери области значений.

Например, рассмотрите следующий алгоритм MATLAB.

% A = 1, B = 100, C = 1000
function [y, z] = lb_node(A, B, C)
  %% single rows
  y = [A B C];
  %% multiple rows
  z = [A 5; A B; A C];
end

В сгенерированном коде с фиксированной точкой:

  • Для выражения y = [A B C], крайний левый элемент, A, приведено к типу C потому что C имеет самый большой тип в строке.

  • Для выражения [A 5; A B; A C]:

    • В первой строке A приведено к типу C потому что C имеет самый большой тип всего выражения.

    • Во второй строке A приведено к типу B потому что B имеет больший тип в строке.

    • В третьей строке A приведено к типу C потому что C имеет больший тип в строке.

%#codegen
% A = 1, B = 100, C = 1000
function [y, z] = lb_node_fixpt(A, B, C)
  %% single rows
  fm = fimath('RoundingMethod', 'Floor', 'OverflowAction', 'Wrap', 'ProductMode', 'FullPrecision', 'MaxProductWordLength', 128, 'SumMode', 'FullPrecision', 'MaxSumWordLength', 128);

  y = fi([fi(A, 0, 10, 0, fm) B C], 0, 10, 0, fm);
  
  %% multiple rows
  z = fi([fi(A, 0, 10, 0, fm) 5; fi(A, 0, 7, 0, fm) B; fi(A, 0, 10, 0, fm) C], 0, 10, 0, fm);
end

Работа с непостоянными экспонентами моторной мощности

Если функция, которую вы преобразовываете, имеет скалярный вход, и mpower экспонентный вход не является постоянным, процесс преобразования устанавливает fimath ProductMode на SpecifyPrecision в сгенерированном коде. При помощи этой настройки тип выходных данных может быть определен во время компиляции.

Например, рассмотрите следующий алгоритм MATLAB.

% a = 1
% b = 3
function y = exp_operator(a, b)
  % exponent is a constant so no need to specify precision
  y = a^3;
  % exponent is not a constant, use 'SpecifyPrecision' for 'ProductMode'
  y = b^a;
end

В сгенерированном коде с фиксированной точкой для выражения y = a^3 , экспонента является константой, поэтому нет необходимости задавать точность. Для выражения, y = b^a, экспонента не постоянна, поэтому ProductMode установлено в SpecifyPrecision.

%#codegen
% a = 1
% b = 3
function y = exp_operator_fixpt(a, b)
  % exponent is a constant so no need to specify precision
  fm = fimath('RoundingMethod', 'Floor', 'OverflowAction', 'Wrap', 'ProductMode', 'FullPrecision', 'MaxProductWordLength', 128, 'SumMode', 'FullPrecision', 'MaxSumWordLength', 128);

  y = fi(a^3, 0, 2, 0, fm);
  % exponent is not a constant, use 'SpecifyPrecision' for 'ProductMode'
  y(:) = fi(b, 'ProductMode', 'SpecifyPrecision', 'ProductWordLength', 2, 'ProductFractionLength', 0 )^a;
end