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

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

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

Используйте частоту дискретизации компакт-дисков 44,1 кГц и частоту отключения 500 Гц. Сначала создайте объект создания фильтра, затем создайте объект DF1 Biquad Filter System. Наконец, исследуйте характеристику по частоте журнала с помощью 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');

Figure Filter Visualization Tool - Magnitude Response (dB) contains an axes and other objects of type uitoolbar, uimenu. The axes with title Magnitude Response (dB) contains 2 objects of type line.

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

Примените настройки фиксированной точки к объекту фильтра. Предположим, что 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');

Figure Filter Visualization Tool - Magnitude Response (dB) contains an axes and other objects of type uitoolbar, uimenu. The axes with title Magnitude Response (dB) contains 3 objects of type line. These objects represent Filter #1: Quantized, Filter #1: Reference.

Реквизируйте фильтр

На графике выше 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]);

Figure Filter Visualization Tool - Magnitude Response (dB) contains an axes and other objects of type uitoolbar, uimenu. The axes with title Magnitude Response (dB) contains 3 objects of type line. These objects represent Filter #1: Quantized, Filter #1: Reference.

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

Ключевым шагом для аппаратной реализации создания фильтра является проверка того, являются ли значения шкалы разумными, и корректировка значения шкалы при необходимости. Сначала исследуйте квантованные значения шкалы относительно спецификации входа-- 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/BR2021ad_1655202_180016/mlx_to_docbook1/tp444233f3_9928_41c3_b966_49741c6a18e9/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/BR2021ad_1655202_180016/mlx_to_docbook1/tp444233f3_9928_41c3_b966_49741c6a18e9/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));

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

Результаты моделирования ModelSim ®

На следующем отображении показан симулятор ModelSim HDL после запуска испытательного стенда 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 #');

Figure contains 2 axes. Axes 1 with title HDL Butterworth Filter In Stimulus. contains an object of type line. Axes 2 with title HDL Butterworth Filter Out Response. contains an object of type line.

Заключение

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

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