Обнаружьте переполнение

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

Предпосылки

Чтобы завершить этот пример, необходимо установить следующие продукты:

  • MATLAB®

  • MATLAB Coder™

  • Фиксированная точка Designer™

В локальной, перезаписываемой папке создайте функцию, overflow.

function y = overflow(b,x,reset)
    if nargin<3, reset = true; end
    persistent z p
    if isempty(z) || reset
        p = 0;
        z = zeros(size(b));
    end
    [y,z,p] = fir_filter(b,x,z,p);
end
function [y,z,p] = fir_filter(b,x,z,p)
    y = zeros(size(x));
    nx = length(x);
    nb = length(b);
    for n = 1:nx
        p=p+1; if p>nb, p=1; end
        z(p) = x(n);        
        acc = 0;
        k = p;
        for j=1:nb
            acc = acc + b(j)*z(k);
            k=k-1; if k<1, k=nb; end
        end        
        y(n) = acc;
    end
end

Создайте тестовый файл, overflow_test.m, чтобы осуществить алгоритм overflow.

function overflow_test
    % The filter coefficients were computed using the FIR1 function from
    % Signal Processing Toolbox.
    %   b = fir1(11,0.25);
    b = [-0.004465461051254
         -0.004324228005260
         +0.012676739550326
         +0.074351188907780
         +0.172173206073645
         +0.249588554524763
         +0.249588554524763
         +0.172173206073645
         +0.074351188907780
         +0.012676739550326
         -0.004324228005260
         -0.004465461051254]';
    
    % Input signal
    nx = 256;
    t = linspace(0,10*pi,nx)';

    % Impulse
    x_impulse = zeros(nx,1); x_impulse(1) = 1;

    % Max Gain
    % The maximum gain of a filter will occur when the inputs line up with the
    % signs of the filter's impulse response.
    x_max_gain = sign(b)';
    x_max_gain = repmat(x_max_gain,ceil(nx/length(b)),1);
    x_max_gain = x_max_gain(1:nx);


    % Sums of sines
    f0=0.1; f1=2;
    x_sines = sin(2*pi*t*f0) + 0.1*sin(2*pi*t*f1);

    % Chirp
    f_chirp = 1/16;                  % Target frequency
    x_chirp = sin(pi*f_chirp*t.^2);  % Linear chirp

    x = [x_impulse, x_max_gain, x_sines, x_chirp];
    titles = {'Impulse', 'Max gain', 'Sum of sines', 'Chirp'};
    y = zeros(size(x));

    for i=1:size(x,2)
        reset = true;
        y(:,i) = overflow(b,x(:,i),reset);
    end

    test_plot(1,titles,t,x,y)

end
function test_plot(fig,titles,t,x,y1)
    figure(fig)
    clf
    sub_plot = 1;
    font_size = 10;
    for i=1:size(x,2)
        subplot(4,1,sub_plot)
        sub_plot = sub_plot+1;
        plot(t,x(:,i),'c',t,y1(:,i),'k')
        axis('tight')
        xlabel('t','FontSize',font_size);
        title(titles{i},'FontSize',font_size);
        ax = gca;
        ax.FontSize = 10;
    end
    figure(gcf)
end

Создайте объект coder.FixptConfig, fixptcfg, с настройками по умолчанию.

fixptcfg = coder.config('fixpt');

Определите имя испытательного стенда. В этом примере именем функции испытательного стенда является overflow_test.

fixptcfg.TestBenchName = 'overflow_test';

Установите размер слова по умолчанию на 16.

fixptcfg.DefaultWordLength = 16;

Включите обнаружение переполнения.

fixptcfg.TestNumerics = true;
fixptcfg.DetectFixptOverflows = true;

Установите Product mode fimath и Sum mode к KeepLSB. Эти настройки моделируют поведение целочисленных операций на языке C.

fixptcfg.fimath = 'fimath( ''RoundingMethod'', ''Floor'', ''OverflowAction'', ''Wrap'', ''ProductMode'', ''KeepLSB'', ''SumMode'', ''KeepLSB'')';

Создайте объект настройки генерации кода сгенерировать автономную статическую библиотеку C.

cfg = coder.config('lib');

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

codegen -float2fixed fixptcfg -config cfg overflow

Фаза тестирования численных данных сообщает о переполнении.

Overflow error in expression 'acc + b( j )*z( k )'. Percentage of Current Range = 104%.

Определите если сложение или умножение в этом переполненном выражении. Установите fimath ProductMode на FullPrecision так, чтобы умножение не переполнялось, и затем запускать команду codegen снова.

fixptcfg.fimath = 'fimath(''RoundingMethod'', ''Floor'', ''OverflowAction'', ''Wrap'', ''ProductMode'', ''FullPrecision'', ''SumMode'', ''KeepLSB'')';
codegen -float2fixed fixptcfg -config cfg overflow

Фаза тестирования численных данных все еще сообщает о переполнении, указывая, что это - сложение в выражении, которое переполняется.

Была ли эта тема полезной?