В этом примере показано, как использовать Приложение Fixed-Point Converter, чтобы преобразовать БИХ-фильтр от с плавающей точкой до реализации фиксированной точки. Секции второго порядка (также отнесенный как биквадратное уравнение) структуры работают лучше при использовании вычислений с фиксированной точкой, чем структуры, которые реализуют передаточную функцию непосредственно. Мы покажем, что самый верный путь к успешному "плавающему-к-фиксированному" преобразованию состоит из следующих шагов:
Выберите структуру Second-Order Sections (SOS), i.e. dsp.BiquadFilter
Выполните анализ динамического диапазона для каждого узла фильтра, i.e. используйте подход испытательного стенда с минимумом симуляции и инструментированием максимума симуляции
Сравните альтернативные реализации масштабирования биквадратного уравнения и просмотрите эффекты квантования из-за различного выбора с помощью 'fvtool' и dsp.SpectrumAnalyzer для анализа и верификации.
Эффективный способ реализовать БИХ-фильтр использует Раздел второго порядка (SOS) структура фильтра Biquad. Предположим, например, что мы должны удалить вмешивающийся высокочастотный тональный сигнал из системы. Один способ достигнуть этого состоит в том, чтобы использовать создание фильтра 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 фильтрует содействующий вывод значений к почти идентичному ответу фильтра (являются ли они двойными или 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
Вместо того, чтобы использовать настройки фиксированной точки по умолчанию объекта, преобразуйте объект в фиксированную точку с помощью Приложения 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. Существует два способа запустить инструмент: с помощью меню MATLAB APPS или через команду 'fixedPointConverter'.
Введите функцию, чтобы преобразовать в поле Entry-Point Functions.
Задайте входные параметры путем ввода имени скрипта испытательного стенда.
Нажмите 'Analyze', чтобы собрать области значений путем симуляции испытательного стенда.
Наблюдайте забранного 'Сима Мин', 'Сим Макс', и 'Предложенный Тип' значения.
Внесите изменения в поля 'Proposed Type' по мере необходимости.
Нажмите 'Convert', чтобы сгенерировать фиксированную точку и просмотреть отчет.
Сгенерированная реализация функции фиксированной точки следующие:
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 командной строки:
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}
Запустите конвертированную функцию фиксированной точки и просмотрите результаты ввода - вывода.
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 дБ. Таким образом этот проект является хорошим кандидатом на реализацию фиксированной точки.
Обратите внимание на то, что 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
После выполнения процедуры 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 нормы по бесконечности, масштабирующийся часто, производит выходные параметры с более низкой ошибкой.
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 предоставляют инструменты пользователю, чтобы выполнить верификации на каждом шаге процесса.