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

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

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

Используйте частоту дискретизации CD 44,1 кГц и частоту среза 500 Гц. Во-первых, создайте объект создания фильтра, затем создайте Систему фильтра biquad object™. Наконец, используйте 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 object and other objects of type uitoolbar, uimenu. The axes object 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 object and other objects of type uitoolbar, uimenu. The axes object 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 object and other objects of type uitoolbar, uimenu. The axes object 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 %#ok<*NASGU> 
scaless = 4×1

    0.1588
    0.1535
    4.4042
  128.0000

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

scale(butterFilter,'Linf');
scaless = butterFilter.ScaleValues
scaless = 4×1

    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 для фильтра и испытательного стенда VHDL, чтобы проверить, что результаты соответствуют, MATLAB заканчивается точно.

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', ...
    'GenerateHDLTestbench','on', ...
    'TestBenchUserStimulus',userstim, ...
    'InputDataType',numerictype(1,8,7));
### Starting VHDL code generation process for filter: hdlbutter
### Generating: /tmp/BR2021bd_1751886_255755/mlx_to_docbook1/tp658a2b87/hdlfilter-ex42204542/hdlsrc/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/BR2021bd_1751886_255755/mlx_to_docbook1/tp658a2b87/hdlfilter-ex42204542/hdlsrc/hdlbutter_tb.vhd
### Creating stimulus vectors ...
### Done generating VHDL Test Bench.

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

В качестве альтернативы можно сгенерировать HDL-код и испытательный стенд при помощи fdhdhltool команда. Эта команда открывает диалоговое окно, которое позволяет вам настраивать и генерировать код Verilog или VHDL и испытательные стенды для квантованного фильтра.

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

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 #');

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

Заключение

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

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