Фильтр Баттерворта HDL

Этот пример иллюстрирует, как сгенерировать HDL-код для 5-го порядка Фильтр Баттерворта. Частота среза для этого фильтра является очень низкой относительно частоты дискретизации, ведя к фильтру, который затрудняет, чтобы сделать практичным. Кроме того, маленький (8-битный) вход и выход (9-битные) размеры слова заставляет квантованный фильтр требовать, чтобы масштабирование было осуществимо.

Спроектируйте фильтр

Используйте уровень выборки CD 44,1 кГц и частоту среза 500 Гц. Во-первых, создайте объект создания фильтра, затем создайте Системный объект Фильтра DF1 Biquad. Наконец, исследуйте ответ в логарифмической частоте с помощью fvtool.

Fs = 44100;
F3db = 500;
filtdes = fdesign.lowpass('n,f3db', 5, F3db, Fs);
butterFilter = design(filtdes,'butter',...
    'SystemObject',true,'FilterStructure','df1sos');

fvtool(butterFilter,'Fs',Fs,'FrequencyScale','log');

Создайте квантованный фильтр

Примените настройки фиксированной точки к объекту фильтра. Примите 9-битные выходные данные фиксированной точки с 12-битными коэффициентами, 20-битными состояниями, продуктами полной точности и 32-битными сумматорами. Проверяйте ответ с fvtool.

butterFilter.NumeratorCoefficientsDataType = 'Custom';
butterFilter.CustomNumeratorCoefficientsDataType = numerictype([],12);
butterFilter.CustomDenominatorCoefficientsDataType = numerictype([],12);
butterFilter.CustomScaleValuesDataType = numerictype([],12);
butterFilter.SectionInputDataType = 'Custom';
butterFilter.CustomSectionInputDataType = numerictype([],20,15);
butterFilter.SectionOutputDataType = 'Custom';
butterFilter.CustomSectionOutputDataType = numerictype([],20,15);
butterFilter.NumeratorProductDataType = 'Full precision';
butterFilter.DenominatorProductDataType = 'Full precision';
butterFilter.NumeratorAccumulatorDataType = 'Custom';
butterFilter.CustomNumeratorAccumulatorDataType = numerictype([],32,24);
butterFilter.DenominatorAccumulatorDataType = 'Custom';
butterFilter.CustomDenominatorAccumulatorDataType = numerictype([],32,25);
butterFilter.OutputDataType = 'Custom';
butterFilter.CustomOutputDataType = numerictype([],9,7);
butterFilter.RoundingMethod = 'nearest';
butterFilter.OverflowAction = 'wrap';

fvtool(butterFilter,'Fs',Fs,'FrequencyScale','log','Arithmetic','fixed');

Повторно квантуйте фильтр

В графике выше, fvtool показывает, что квантованная полоса пропускания на приблизительно 2 дБ ниже, чем желаемый ответ. Настройте содействующий размер слова от 12 до 16, чтобы получить квантованный ответ ближе на ссылочный ответ с двойной точностью и увеличить масштаб ответа полосы пропускания. Квантованный фильтр теперь чуть на более чем 0,1 дБ ниже, чем ссылочный фильтр.

butterFilter.CustomNumeratorCoefficientsDataType = numerictype([],16);
butterFilter.CustomDenominatorCoefficientsDataType = numerictype([],16);
butterFilter.CustomScaleValuesDataType = numerictype([],16);

fvtool(butterFilter,'Fs',Fs,'FrequencyScale','log','Arithmetic','fixed');
axis([0 1.0 -1 1]);

Исследуйте значения шкалы

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

scaless = butterFilter.ScaleValues .* 2^7;
disp(scaless);
    0.1588
    0.1535
    4.4042
  128.0000

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

scale(butterFilter,'Linf');
scaless = butterFilter.ScaleValues;
disp(scaless);
    1.0000
    1.0000
    1.0000
    1.0000

Сгенерируйте HDL-код и испытательный стенд от квантованного фильтра

Начиная с правильно квантованного фильтра сгенерируйте код VHDL или Verilog. У вас есть опция генерации испытательного стенда VHDL или Verilog, чтобы проверить, что проект HDL совпадает с фильтром MATLAB®.

Чтобы сгенерировать Verilog вместо этого, измените значение свойства 'TargetLanguage' от 'VHDL' до 'Verilog'.

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

Примите 8-битный вход фиксированной точки со знаком с 7 битами части.

Сгенерируйте испытательный стенд VHDL, чтобы проверить, что результаты соответствуют, MATLAB заканчивается точно.

Создайте временный рабочий каталог. Сгенерируйте код VHDL для фильтра и испытательного стенда VHDL, чтобы проверить, что результаты соответствуют, MATLAB заканчивается точно.

Откройте сгенерированный файл VHDL для фильтра в редакторе.

workingdir = tempname;

userstim = [];
for n = [50, 100, 150, 200, 250, 300]
  userstim = [userstim,sin(2*pi*n/Fs*(0:Fs/n))]; %#ok
end

generatehdl(butterFilter,'Name','hdlbutter',...
    'TargetLanguage','VHDL',...
    'TargetDirectory',workingdir, ...
    'GenerateHDLTestbench','on', ...
    'TestBenchUserStimulus',userstim, ...
    'InputDataType',numerictype(1,8,7));
### Starting VHDL code generation process for filter: hdlbutter
### Generating: /tmp/BR2020ad_1302590_239645/mlx_to_docbook1/tpbfff2abf_6a08_4389_8a1d_f32fcb5761b3/hdlbutter.vhd
### Starting generation of hdlbutter VHDL entity
### Starting generation of hdlbutter VHDL architecture
### First-order section, # 1
### Second-order section, # 2
### Second-order section, # 3
### Successful completion of VHDL code generation process for filter: hdlbutter
### HDL latency is 2 samples
### Starting generation of VHDL Test Bench.
### Generating input stimulus
### Done generating input stimulus; length 2166 samples.
### Generating Test bench: /tmp/BR2020ad_1302590_239645/mlx_to_docbook1/tpbfff2abf_6a08_4389_8a1d_f32fcb5761b3/hdlbutter_tb.vhd
### Creating stimulus vectors ...
### Done generating VHDL Test Bench.
             
edit(fullfile(workingdir,'hdlbutter.vhd'));

% Open the generated VHDL test bench in the editor.

edit(fullfile(workingdir,'hdlbutter_tb.vhd'));

Сгенерируйте HDL-код и испытательный стенд Используя FDHDLTool

HDL-код и испытательный стенд могут опционально быть сгенерированы с помощью команды FDHDLTOOL, которая открывает диалоговое окно, которое позволяет вам настроить и сгенерировать код Verilog или VHDL и испытательные стенды для квантованного фильтра.

Графический интерфейс пользователя настраивается к 'butterFilter' таким способом, которым только соответствующие виджеты доступны для установленного. Чтобы сгенерировать HDL-код и испытательный стенд, необходимо сначала перейти к рабочей директории и затем вызвать команду FDHDLTOOL.

fdhdltool(butterFilter,numerictype(1,8,7));

Можно изменить настройки по умолчанию и нажать Generate, чтобы сгенерировать HDL и/или испытательный стенд.

ModelSim® Simulation Results

Следующее отображение показывает симулятор HDL ModelSim после выполнения испытательного стенда VHDL. Сравните результат ModelSim с результатом MATLAB ниже.

xrange = (0:length(userstim) - 1);
y = butterFilter(fi(userstim.',1,8,7));
subplot(2,1,1); plot(xrange, userstim); 
axis([0 length(userstim) -1.1 1.1]);
title('HDL Butterworth Filter In Stimulus.');
xlabel('Sample #');
subplot(2,1,2); plot(xrange, y); 
axis([0 length(userstim) -1.1 1.1]);
title('HDL Butterworth Filter Out Response.');
xlabel('Sample #');

Заключение

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

Можно использовать симулятор HDL ModelSim, чтобы проверить эти результаты. Можно также экспериментировать с VHDL и Verilog и для фильтров и для испытательных стендов.

Для просмотра документации необходимо авторизоваться на сайте