exponenta event banner

Программируемый фильтр FIR HDL

Этот пример иллюстрирует, как генерировать код HDL для фильтра FIR с интерфейсом процессора для загрузки коэффициентов. Фильтр может быть запрограммирован на любой желаемый отклик путем загрузки коэффициентов во внутреннюю память коэффициентов с использованием интерфейса процессора.

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

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

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

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

Создайте объект конструкции фильтра нижних частот, а затем объект системы фильтров FIR (Hlp). Затем преобразуйте его, чтобы создать объект FIR Filter System с откликом верхних частот (Hhp).

Fpass = 0.45; % Passband Frequency
Fstop = 0.55; % Stopband Frequency                                                                                         
Apass = 1;    % Passband Attenuation (dB)
Astop = 60;   % Stopband Attenuation (dB)

f = fdesign.lowpass('Fp,Fst,Ap,Ast',Fpass,Fstop,Apass,Astop);
lpFilter = design(f, 'equiripple','FilterStructure', 'dfsymfir','SystemObject',true); % Lowpass

hpcoeffs = firlp2hp(lpFilter.Numerator); 
hpFilter = dsp.FIRFilter('Numerator', hpcoeffs); % Highpass

Квантование фильтров

Предположим, что коэффициенты должны быть сохранены в памяти шириной 14 битов. Используя эту информацию, примените настройки фиксированной точки к фильтру объектов системы.

lpFilter.FullPrecisionOverride=false;
lpFilter.CoefficientsDataType='Custom';
lpFilter.CustomCoefficientsDataType=numerictype(1,14,13);
lpFilter.OutputDataType='Same as Accumulator';
lpFilter.ProductDataType='Full precision';
lpFilter.AccumulatorDataType='Full precision';

hpFilter.FullPrecisionOverride=false;
hpFilter.CoefficientsDataType='Custom';
hpFilter.CustomCoefficientsDataType=numerictype(1,14,13);
hpFilter.OutputDataType='Same as Accumulator';
hpFilter.ProductDataType='Full precision';
hpFilter.AccumulatorDataType='Full precision';

После применения настроек фиксированной точки важно убедиться, что фильтр системных объектов по-прежнему соответствует спецификациям. Мы будем использовать функцию «measure», чтобы проверить, верно ли это.

measure(lpFilter,'Arithmetic','fixed')
ans = 
Sample Rate      : N/A (normalized frequency)
Passband Edge    : 0.45                      
3-dB Point       : 0.46957                   
6-dB Point       : 0.48314                   
Stopband Edge    : 0.55                      
Passband Ripple  : 0.89243 dB                
Stopband Atten.  : 55.3452 dB                
Transition Width : 0.1                       
 

Проверьте выходные данные фильтра

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

Для вышеописанной двухэтапной операции фильтрации наша цель состоит в том, чтобы сравнить выходные данные фильтра из MATLAB ® с выходными данными из сгенерированного кода HDL.

Печать входных выборок и отфильтрованных выходных данных показывает поведение нижних и верхних частот.

x = chirp(0:199,0,199,0.4);

lpcoeffs = lpFilter.Numerator;            % store original lowpass coefficients
y1 = lpFilter(fi(x,1,14,13).');           % filter the signal

lpFilter.Numerator = hpFilter.Numerator;  % load the highpass filter coefficients
y2 = lpFilter(fi(x,1,14,13).');           % filter the signal

y = [y1; y2];                             % concatenate output signals

lpFilter.Numerator = lpcoeffs;            % restore original lowpass coefficients

subplot(2,1,1);plot([x,x]);
xlabel('Time [samples]');ylabel('Amplitude'); title('Input Stimulus');
subplot(2,1,2);plot(y);
xlabel('Time [samples]');ylabel('Amplitude'); title('Filtered Output');

Figure contains 2 axes. Axes 1 with title Input Stimulus contains an object of type line. Axes 2 with title Filtered Output contains an object of type line.

Создание кода VHDL с интерфейсом процессора и тестовым стендом

Для квантованного фильтра нижних частот мы создадим VHDL-код с интерфейсом процессора, установив свойству 'ExecutionSource' значение 'ProcessorInterface'. В результате генерируемый код будет иметь дополнительные порты для сигналов write_address, write_enable, coeffs_in и write_done. Этот интерфейс может использоваться для загрузки коэффициентов из хост-процессора во внутренний файл регистров. ЛПВП имеет дополнительный теневой регистр, который обновляется из файла регистра, когда сигнал «write _ done» является высоким. Это позволяет одновременно загружать и обрабатывать данные объектом фильтра.

Чтобы убедиться, что объект фильтра может быть последовательно загружен двумя различными наборами коэффициентов фильтра, мы создадим стенд тестирования VHDL. Во-первых, испытательный стенд загружает коэффициенты нижних частот и обрабатывает входные выборки. Затем испытательный стенд загружает коэффициенты, соответствующие отклику фильтра верхних частот, и снова обрабатывает входные выборки.

Сгенерированный код VHDL и стенд тестирования VHDL можно скомпилировать и смоделировать с помощью имитатора HDL, такого как ModelSim ®. Обратите внимание, что загрузка второго набора коэффициентов и обработка последних нескольких входных выборок выполняются одновременно .

Чтобы создать необходимый стенд тестирования, мы задаем свойству «GenerateHDLTestbench» значение «on» и передаем «TestbenchCoeffStimulus» в вызове команды generatehdl. Значение, переданное для TestbenchCoeffStimulus, является вектором коэффициентов, которые должны использоваться для последующей обработки входных выборок. Этот пример проходит в векторе коэффициентов, соответствующих фильтру верхних частот.

Предположим, что из-за требований к фиксированному тракту данных входного АЦП необходим 14-битный вход с фиксированной точкой со знаком с точностью 13 бит.

%As the symmetric structure is selected, the field 'TestbenchCoeffStimulus'
% has to be the half of length of filter.

workingdir = tempname;

generatehdl(lpFilter,'Name','FilterProgrammable', ...
                 'InputDataType',numerictype(1,14,13), ...
                 'TargetLanguage','VHDL', ...
                 'TargetDirectory',workingdir, ...
                 'CoefficientSource','ProcessorInterface', ...
                 'GenerateHDLTestbench','on', ...
                 'TestBenchUserStimulus',x, ...
                 'TestbenchCoeffStimulus',hpFilter.Numerator(1:(length(hpFilter.Numerator)+1)/2));
### Starting VHDL code generation process for filter: FilterProgrammable
### Generating: /tmp/BR2021ad_1655202_180016/mlx_to_docbook2/tpbad7135e_7548_417b_b71e_9b88e8520eb7/FilterProgrammable.vhd
### Starting generation of FilterProgrammable VHDL entity
### Starting generation of FilterProgrammable VHDL architecture
### Successful completion of VHDL code generation process for filter: FilterProgrammable
### HDL latency is 2 samples
### Starting generation of VHDL Test Bench.
### Generating input stimulus
### Done generating input stimulus; length 200 samples.
### Generating Test bench: /tmp/BR2021ad_1655202_180016/mlx_to_docbook2/tpbad7135e_7548_417b_b71e_9b88e8520eb7/FilterProgrammable_tb.vhd
### Creating stimulus vectors ...
### Done generating VHDL Test Bench.

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

На следующем экране показан симулятор ModelSim HDL после выполнения сгенерированных сценариев .do файла для тестового стенда. Сравните результат ModelSim с результатом MATLAB, как было нанесено на график ранее.

Заключение

Мы разработали фильтры FIR верхних и нижних частот в соответствии с заданными спецификациями. Затем мы квантовали фильтр и генерировали код VHDL для фильтра с интерфейсом для загрузки коэффициентов из процессора. Затем мы создали испытательный стенд VHDL, который показал обработку входных выборок после загрузки коэффициентов нижних частот, повторив операцию с коэффициентами верхних частот. Мы показали, как генерировать код VHDL, реализующий аппаратные средства фильтрации, которые могут многократно использоваться для различных ответов при загрузке различных наборов коэффициентов через интерфейс порта из хост-процессора.