Преобразование из плавающей запятой в фиксированную запятую БИХ-фильтров

В этом примере показано, как использовать Приложение Fixed-Point Converter, чтобы преобразовать БИХ-фильтр от с плавающей точкой до реализации фиксированной точки. Секции второго порядка (также отнесенный как биквадратное уравнение) структуры работают лучше при использовании вычислений с фиксированной точкой, чем структуры, которые реализуют передаточную функцию непосредственно. Мы покажем, что самый верный путь к успешному "плавающему-к-фиксированному" преобразованию состоит из следующих шагов:

  • Выберите структуру Second-Order Sections (SOS), i.e. dsp.BiquadFilter

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

  • Сравните альтернативные реализации масштабирования биквадратного уравнения и просмотрите эффекты квантования из-за различного выбора с помощью 'fvtool' и dsp.SpectrumAnalyzer для анализа и верификации.

Введение

Эффективный способ реализовать БИХ-фильтр использует Раздел второго порядка (SOS) структура фильтра Biquad. Предположим, например, что мы должны удалить вмешивающийся высокочастотный тональный сигнал из системы. Один способ достигнуть этого состоит в том, чтобы использовать создание фильтра lowpass.

Спроектируйте Lowpass эллиптический фильтр

Используйте минимальный порядок lowpass Эллиптическая Прямая Форма, которую я проектирую в целях этого примера. Технические требования проекта фильтра:

  • Ребро частоты полосы пропускания: 0.4*pi

  • Ребро частоты полосы задерживания: 0.45*pi

  • Неравномерность в полосе пропускания: 0,5 дБ

  • Затухание в полосе задерживания: 80 дБ

Визуализируйте совокупный ответ фильтра всех секций второго порядка с помощью Инструмента Визуализации Фильтра.

biquad = design(fdesign.lowpass('Fp,Fst,Ap,Ast',0.4,0.45,0.5,80), ...
    'ellip','FilterStructure','df1sos','SystemObject',true);
fvt = fvtool(biquad,'Legend','on');
fvt.SosviewSettings.View = 'Cumulative';

Получите коэффициенты фильтра (SOS, B, A) для плавания по сравнению с фиксированным сравнением

Обратите внимание на то, что SOS фильтрует содействующий вывод значений к почти идентичному ответу фильтра (являются ли они двойными или 16-битными значениями фиксированной точки).

sosMatrix = biquad.SOSMatrix;
sclValues = biquad.ScaleValues;
fvt_comp = fvtool(sosMatrix,fi(sosMatrix,1,16));
legend(fvt_comp,'Floating-point (double) SOS','Fixed-point (16-bit) SOS');
b = repmat(sclValues(1:(end-1)),1,3) .* sosMatrix(:,(1:3));
a = sosMatrix(:,(5:6));
num = b'; % matrix of scaled numerator sections
den = a'; % matrix of denominator sections

close(fvt);      % clean up
close(fvt_comp); % clean up

Операция с плавающей точкой по умолчанию

Проверьте работу фильтра путем потоковой передачи некоторых данных через него и просмотра его ответа ввода - вывода. Сначала попытайтесь фильтровать псевдослучайный шумовой сигнал (с плавающей точкой) (произведенный на уровне 300 Гц) с вмешивающимся аддитивным высокочастотным тоном, видеть, удален ли тон. Это будет также служить позже в качестве нашего опорного сигнала для испытательного стенда.

Wo           = 75/(300/2); % 75 Hz tone; system running at 300 Hz
inp_len      = 4000;       % Number of input samples (signal length)
inp_itf      = 0.5 .* sin((pi*Wo) .* (0:(inp_len-1))'); % tone interferer
scope = dsp.SpectrumAnalyzer('SampleRate',300, ...
    'PlotAsTwoSidedSpectrum',false, ...
    'ShowLegend',true,'YLimits',[-85 25], ...
    'Title','Floating-Point Input Signal and Filter Output Signal', ...
    'ChannelNames',{'Floating-Point Input','Filter Output'});
rng(12345); % seed the rng for repeatable results
biquadLPFiltFloat = dsp.BiquadFilter('SOSMatrixSource','Input port', ...
    'ScaleValuesInputPort',false);
for k = 1:10
    inp_sig = rand(inp_len,1) - 0.5; % random values in range (-0.5, 0.5)
    input = inp_sig + inp_itf; % combined input signal, range (-1.0, 1.0)
    out_1 = biquadLPFiltFloat(input,num,den); % filter
    scope([input,out_1]) % visualize input and filtered output
end

clear scope biquadLPFiltFloat; % clean up

Операция фиксированной точки по умолчанию

Теперь запустите некоторые данные фиксированной точки через фильтры, с помощью объектных настроек по умолчанию. Обратите внимание на то, что поведение фиксированной точки по умолчанию приводит к неправильным результатам.

scope = dsp.SpectrumAnalyzer('SampleRate',300, ...
    'PlotAsTwoSidedSpectrum',false, ...
    'ShowLegend',true,'YLimits',[-85 25], ...
    'Title','Fixed-Point Input Signal and Filter Output Signal', ...
    'ChannelNames', ...
    {'Fixed-Point Input','Default (Incorrect) Fixed-Point Output'});
rng(12345); % seed the rng for repeatable results
bqLPFiltFixpt = dsp.BiquadFilter('SOSMatrixSource','Input port', ...
    'ScaleValuesInputPort',false);
for k = 1:10
    inp_sig = rand(inp_len,1) - 0.5;  % random values in range (-0.5, 0.5)
    inputFi = fi(inp_sig + inp_itf, 1, 16, 15); % signal range (-1.0, 1.0)
    out_2 = bqLPFiltFixpt(inputFi,fi(num,1,16),fi(den,1,16));
    scope([inputFi,out_2]) % visualize
end

clear scope bqLPFiltFixpt; % clean up

Преобразуйте БИХ-функцию filter Biquad с плавающей точкой в фиксированную точку

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

Чтобы сначала подготовиться к использованию Приложения Fixed-Point Converter, создайте функцию, чтобы преобразовать, установив весь выбор типа данных фильтра на ''Пользовательский'':

type myIIRLowpassBiquad;
function output = myIIRLowpassBiquad(inp,num,den)
%myIIRNotchBiquad Biquad lowpass filter implementation
%   Used as part of a MATLAB Fixed Point Converter App example.

%   Copyright 2016 The MathWorks, Inc.
persistent bqLPFilter;
if isempty(bqLPFilter)
    bqLPFilter = dsp.BiquadFilter(        ...
        'SOSMatrixSource', 'Input port',  ...
        'ScaleValuesInputPort', false,    ...
        'SectionInputDataType',           'Custom', ...
        'SectionOutputDataType',          'Custom', ...
        'NumeratorProductDataType',       'Custom', ...
        'DenominatorProductDataType',     'Custom', ...
        'NumeratorAccumulatorDataType',   'Custom', ...
        'DenominatorAccumulatorDataType', 'Custom', ...
        'StateDataType',                  'Custom', ...
        'OutputDataType',                 'Custom');
end
output = bqLPFilter(inp, num, den);
end

Создайте скрипт испытательного стенда

Создайте испытательный стенд, чтобы симулировать и собрать оснащенный минимум симуляции, и максимальные значения симуляции для всего нашего типа данных управляли путями прохождения сигнала. Это позволит инструменту позже предлагать автомасштабируемые настройки фиксированной точки. Используйте части кода выше как скрипт испытательного стенда, начиная с входных параметров с плавающей точкой и проверки испытательного стенда прежде, чем симулировать и собрать минимальные и максимальные данные. Позже, используйте Приложение Fixed-Point Converter, чтобы преобразовать реализацию функции с плавающей точкой в реализацию функции фиксированной точки.

type myIIRLowpassBiquad_tb.m;
%% Test Bench for myIIRLowpassBiquad.m

%   Copyright 2016 The MathWorks, Inc.

%% Pre-designed filter (coefficients stored in MAT file):
% f = design(fdesign.lowpass('Fp,Fst,Ap,Ast',0.4,0.45,0.5,80), ...
%            'ellip', 'FilterStructure', 'df1sos','SystemObject',true);
% sosMatrix = f.SOSMatrix;
% sclValues = f.ScaleValues;
% b = repmat(sclValues(1:(end-1)),1,3) .* sosMatrix(:,(1:3));
% a = sosMatrix(:,(5:6));
% num = b';
% den = a';
% save('myIIRLowpassBiquadDesign.mat', 'b', 'a', 'num', 'den');
load('myIIRLowpassBiquadDesign.mat');

%% Interference signal, using values in range (-0.5, 0.5)
Wo      = 75/(300/2); % 75 Hz tone; system running at 300 Hz
inp_len = 4000; sinTvec = (0:(inp_len-1))';
inp_itf = 0.5 .* sin((pi*Wo) .* sinTvec);

%% Filtering and visualization
% Filter an input signal, including an interference
% tone, to see if the tone is successfully removed.
rng(12345); % seed the rng for repeatable results
scope = dsp.SpectrumAnalyzer('SampleRate',300,...
    'PlotAsTwoSidedSpectrum',false,'ShowLegend',true,'YLimits',[-125 25],...
    'Title','Input Signal and Filter Output Signal', ...
    'ChannelNames', {'Input', 'Filter Output'});

for k = 1:10
    inp_sig = rand(inp_len,1) - 0.5; % random values in range (-0.5, 0.5)
    inp = inp_sig + inp_itf;
    out_1 = myIIRLowpassBiquad(inp,num,den); % filter
    scope([inp,out_1]); % visualize
end

Преобразуйте в фиксированную точку Используя приложение Fixed-Point Converter

  • Запустите Приложение Fixed-Point Converter. Существует два способа запустить инструмент: с помощью меню MATLAB APPS или через команду 'fixedPointConverter'.

  • Введите функцию, чтобы преобразовать в поле Entry-Point Functions.

  • Задайте входные параметры путем ввода имени скрипта испытательного стенда.

  • Нажмите 'Analyze', чтобы собрать области значений путем симуляции испытательного стенда.

  • Наблюдайте забранного 'Сима Мин', 'Сим Макс', и 'Предложенный Тип' значения.

  • Внесите изменения в поля 'Proposed Type' по мере необходимости.

  • Нажмите 'Convert', чтобы сгенерировать фиксированную точку и просмотреть отчет.

Получившаяся фиксированная точка реализация MATLAB

Сгенерированная реализация функции фиксированной точки следующие:

type myIIRLowpassBiquad_fixpt;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                          %
%           Generated by MATLAB 9.3 and Fixed-Point Designer 6.0           %
%                                                                          %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%#codegen
function output = myIIRLowpassBiquad_fixpt(inp,num,den)
%myIIRNotchBiquad Biquad lowpass filter implementation
%   Used as part of a MATLAB Fixed Point Converter App example.
%   Copyright 2016 The MathWorks, Inc.
fm = get_fimath();

persistent bqLPFilter;
if isempty(bqLPFilter)
    bqLPFilter = dsp.BiquadFilter(        ...
        'SOSMatrixSource', 'Input port',  ...
        'ScaleValuesInputPort', false,    ...
        'SectionInputDataType',           'Custom', ...
        'SectionOutputDataType',          'Custom', ...
        'NumeratorProductDataType',       'Custom', ...
        'DenominatorProductDataType',     'Custom', ...
        'NumeratorAccumulatorDataType',   'Custom', ...
        'DenominatorAccumulatorDataType', 'Custom', ...
        'StateDataType',                  'Custom', ...
        'OutputDataType',                 'Custom' , 'CustomSectionInputDataType', numerictype([], 16, 8), 'CustomSectionOutputDataType', numerictype([], 16, 8), 'CustomNumeratorProductDataType', numerictype([], 32, 26), 'CustomDenominatorProductDataType', numerictype([], 32, 23), 'CustomNumeratorAccumulatorDataType', numerictype([], 32, 24), 'CustomDenominatorAccumulatorDataType', numerictype([], 32, 23), 'CustomStateDataType', numerictype([], 16, 8), 'CustomOutputDataType', numerictype([], 16, 15));
end
output = fi(bqLPFilter(inp, num, den), 1, 16, 15, fm);
end


function fm = get_fimath()
	fm = fimath('RoundingMethod', 'Floor',...
	     'OverflowAction', 'Wrap',...
	     'ProductMode','FullPrecision',...
	     'MaxProductWordLength', 128,...
	     'SumMode','FullPrecision',...
	     'MaxSumWordLength', 128);
end

Автоматизация преобразования фиксированной точки Используя API командной строки

Кроме того, преобразование фиксированной точки может быть автоматизировано с помощью API командной строки:

type myIIRLowpassF2F_prj_script;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Script generated from project 'myIIRLowpassBiquad.prj' on 16-Oct-2014.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Create configuration object of class 'coder.FixPtConfig'.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
cfg = coder.config('fixpt');

cfg.TestBenchName = { sprintf('S:\\Work\\15aFeatureExamples\\biquad_notch_f2f\\myIIRLowpassBiquad_tb.m') };
cfg.DefaultWordLength = 16;
cfg.LogIOForComparisonPlotting = true;
cfg.TestNumerics = true;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Define argument types for entry-point 'myIIRLowpassBiquad'.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
ARGS = cell(1,1);
ARGS{1} = cell(3,1);
ARGS{1}{1} = coder.typeof(0,[4000   1]);
ARGS{1}{2} = coder.typeof(0,[3 5]);
ARGS{1}{3} = coder.typeof(0,[2 5]);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Invoke MATLAB Coder.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
codegen -float2fixed cfg myIIRLowpassBiquad -args ARGS{1}

Протестируйте конвертированную реализацию фиксированной точки MATLAB

Запустите конвертированную функцию фиксированной точки и просмотрите результаты ввода - вывода.

scope = dsp.SpectrumAnalyzer('SampleRate',300, ...
    'PlotAsTwoSidedSpectrum',false, ...
    'ShowLegend',true,'YLimits',[-85 25], ...
    'Title','Fixed-Point Input Signal and Filter Output Signal', ...
    'ChannelNames',{'Fixed-Point Input','Fixed-Point Filter Output'});
rng(12345); % seed the rng for repeatable results
for k = 1:10
    inp_sig = rand(inp_len,1) - 0.5;  % random values in range (-0.5, 0.5)
    inputFi = fi(inp_sig + inp_itf, 1, 16, 15); % signal range (-1.0, 1.0)
    out_3 = myIIRLowpassBiquad_fixpt(inputFi,fi(num,1,16),fi(den,1,16));
    scope([inputFi,out_3]) % visualize
end

clear scope; % clean up

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

fig = figure;
subplot(3,1,1);
plot(out_1);
title('Floating-point filter output');
subplot(3,1,2);
plot(out_3);
title('Fixed-point filter output');
subplot(3,1,3);
plot(out_1 - double(out_3));
axis([0 4000 -4e-2 7e-2]);
title('Error');

close(fig); % clean up

Перепроектирование эллиптического фильтра Используя масштабирование нормы по бесконечности

Эллиптические проекты фильтра имеют характеристику того, чтобы быть относительно хорошо масштабируемым при использовании масштабирования секции второго порядка 'Linf' (i.e., норма по бесконечности). Используя этот подход часто приводит к меньшим ошибкам квантования.

biquad_Linf = design(fdesign.lowpass('Fp,Fst,Ap,Ast',0.4,0.45,0.5,80), ...
    'ellip','FilterStructure','df1sos', ...
    'SOSScaleNorm','Linf','SystemObject',true);
fvt_Linf = fvtool(biquad_Linf,'Legend','on');
fvt_Linf.SosviewSettings.View = 'Cumulative';

Заметьте, что ни одна из совокупных внутренних частотных характеристик, измеренных с входа на фильтр к различным состояниям каждого раздела, не превышает 0 дБ. Таким образом этот проект является хорошим кандидатом на реализацию фиксированной точки.

Получите коэффициенты фильтра Linf-нормы для плавания по сравнению с фиксированным сравнением

Обратите внимание на то, что SOS фильтрует содействующий вывод значений к почти идентичному ответу фильтра (являются ли они двойными или 16-битными значениями фиксированной точки).

sosMtrLinf = biquad_Linf.SOSMatrix;
sclValLinf = biquad_Linf.ScaleValues;
fvt_comp_Linf = fvtool(sosMtrLinf,fi(sosMtrLinf,1,16));
legend(fvt_comp_Linf,'Floating-point (double) SOS, Linf Scaling', ...
    'Fixed-point (16-bit) SOS, Linf Scaling');
bLinf = repmat(sclValLinf(1:(end-1)),1,3) .* sosMtrLinf(:,(1:3));
aLinf = sosMtrLinf(:,(5:6));
numLinf = bLinf'; % matrix of scaled numerator sections
denLinf = aLinf'; % matrix of denominator sections

close(fvt_Linf);      % clean up
close(fvt_comp_Linf); % clean up

Протестируйте конвертированную фиксированную точку MATLAB фильтр Linf-нормы Biquad

После выполнения процедуры Fixed-Point Converter снова, как выше, но использование Linf-нормы масштабируемые содействующие значения фильтра, запускают новую конвертированную функцию фиксированной точки и просматривают результаты ввода - вывода.

scope = dsp.SpectrumAnalyzer('SampleRate',300, ...
    'PlotAsTwoSidedSpectrum',false,'ShowLegend',true, ...
    'YLimits',[-85 25],'Title', ...
    'Fixed-Point Input Signal and Linf-Norm Filter Output Signal', ...
    'ChannelNames', ...
    {'Fixed-Point Input','Fixed-Point Linf-Norm Filter Output'});
rng(12345); % seed the rng for repeatable results
for k = 1:10
    inp_sig = rand(inp_len,1) - 0.5;  % random values in range (-0.5, 0.5)
    inputFi = fi(inp_sig + inp_itf, 1, 16, 15); % signal range (-1.0, 1.0)
    out_4 = myIIRLinfBiquad_fixpt( ...
        inputFi,fi(numLinf,1,16),fi(denLinf,1,16));
    scope([inputFi,out_4]) % visualize
end

clear scope; % clean up

Уменьшаемое масштабирование SOS Linf-нормы ошибки реализации фиксированной точки

SOS нормы по бесконечности, масштабирующийся часто, производит выходные параметры с более низкой ошибкой.

fig1 = figure;
subplot(3,1,1);
plot(out_1);
title('Floating-point filter output');
subplot(3,1,2);
plot(out_4);
title('Fixed-point (Linf-norm SOS) filter output');
subplot(3,1,3);
plot(out_1 - double(out_4));
axis([0 4000 0 1e-3]);
title('Error');

fig2 = figure;
subplot(2,1,1);
plot(out_1 - double(out_3));
axis([0 4000 -4e-2 7e-2]);
title('Fixed-point error (default SOS filter scaling)');
subplot(2,1,2);
plot(out_1 - double(out_4));
axis([0 4000 0 1e-3]);
title('Fixed-point error (''Linf'' SOS filter scaling)');

close(fig1); % clean up
close(fig2); % clean up

Сводные данные

Мы обрисовали в общих чертах процедуру, чтобы преобразовать БИХ-фильтр с плавающей точкой в реализацию фиксированной точки. dsp.BiquadFilter object s DSP System Toolbox™ оборудован Минимумом Симуляции и Максимальными возможностями инструментирования, которые помогают Приложению Fixed-Point Converter автоматически и динамически масштабируют внутренние сигналы фильтра. Кроме того, различный 'fvtool' и исследования dsp.SpectrumAnalyzer предоставляют инструменты пользователю, чтобы выполнить верификации на каждом шаге процесса.