Распределенная арифметика HDL для конечная импульсная характеристика

Этот пример иллюстрирует, как сгенерировать HDL-код для lowpass конечной импульсной характеристики с архитектурой распределенной арифметики (DA).

Распределенная арифметика

Распределенная арифметика является популярной архитектурой для реализации конечных импульсных характеристик без использования множителей. DA реализует сумму расчетов продуктов, необходимых для конечная импульсная характеристика, эффективно используя LUT, переключатели и сумматоры. Поскольку эти операции эффективно отображаются на FPGA, DA является предпочтительной архитектурой на этих устройствах.

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

Используйте частоту дискретизации 48 кГц, частоту ребра полосы пропускания 9,6 кГц и частоту упора 12 кГц. Установите допустимый пик-к-пику неравномерности в полосе пропускания равным 1 дБ, а затуханием в полосе задерживания равным -90 дБ. Затем спроектируйте фильтр с помощью fdesign.lowpass и создайте Системный объект фильтр как прямую форму конечной импульсной характеристики фильтр.

Fs           = 48e3;         % Sampling Frequency in Hz
Fpass        = 9.6e3;        % Passband Frequency in Hz
Fstop        = 12e3;         % Stopband Frequency in Hz
Apass        = 1;            % Passband Ripple in dB
Astop        = 90;           % Stopband Attenuation in dB

lpSpec = fdesign.lowpass( 'Fp,Fst,Ap,Ast',...
    Fpass, Fstop, Apass, Astop, Fs);

lpFilter = design(lpSpec, 'equiripple', 'filterstructure', 'dffir',...
    'SystemObject', true);

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

Поскольку DA реализует фильтр конечной импульсной характеристики путем сериализации бит входных данных, то это требует квантованного фильтра. Предположим, что требуются 12-разрядные входы и выходные размеры слова с 11 дробными битами (из-за требований к фиксированным путям данных или входных ширин ЦАП/вывода). Примените эти настройки фиксированной точки.

inputDataType = numerictype(1,12,11);
outputDataType = inputDataType;
coeffsDataType = numerictype(1,16,16);

lpFilter.FullPrecisionOverride = false;
lpFilter.CoefficientsDataType = 'Custom';
lpFilter.CustomCoefficientsDataType = coeffsDataType;
lpFilter.OutputDataType = 'Custom';
lpFilter.CustomOutputDataType = outputDataType;

% Now check the filter response with fvtool.
fvtool(lpFilter,'Fs',Fs,'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.

Сгенерируйте HDL-код с архитектурой DA

Чтобы сгенерировать HDL-код с архитектурой DA, активируйте команду generatehdl, передав допустимое значение свойству 'DALUTPartition'. Свойство 'DALUTPartition' предписывает генератору кода использовать архитектуру DA и делит LUT на заданное количество разделов. Свойство 'DALUTPartition' задает количество разделов LUT и количество отводов, сопоставленных с каждым разделом. Для фильтра с многими отводами лучше всего разделить отводы на несколько LUT, при этом каждый LUT хранит сумму коэффициентов только для связанных с ним отводов. Сумма выходов LUT вычисляется в древовидной структуре сумматоров.

Проверьте длину фильтра, получив количество коэффициентов.

FL = length(lpFilter.Numerator);

Предположим, что у вас есть 8 входных LUT; вычислите значение свойства DALUTPartition таким образом, чтобы вы использовали как можно больше из этих LUT на каждый раздел.

dalut = [ones(1, floor(FL/8))*8, mod(FL, 8)];

Создавайте HDL с архитектурой DA. По умолчанию генерируется код VHDL. Чтобы сгенерировать код Verilog, передайте в свойстве 'TargetLanguage' значение 'Verilog'.

workingdir = tempname;
generatehdl(lpFilter, 'DALUTPartition', dalut, ...
                'TargetDirectory', workingdir, ...
                'InputDataType', inputDataType);
Warning: Structure fir has symmetric coefficients, consider converting to structure symmetricfir for reduced area.
Warning: Structure fir has symmetric coefficients, consider converting to structure symmetricfir for reduced area.
### Starting VHDL code generation process for filter: firfilt
### Generating: /tmp/BR2021ad_1655202_180016/mlx_to_docbook1/tp65546d1a_b9ca_474d_82e0_aeff8a74cd8d/firfilt.vhd
### Starting generation of firfilt VHDL entity
### Starting generation of firfilt VHDL architecture
### Clock rate is 12 times the input sample rate for this architecture.
### Successful completion of VHDL code generation process for filter: firfilt
### HDL latency is 3 samples

Преобразуйте структуру фильтра в 'Direct form symmetric' и Сгенерируйте HDL

Симметричная структура фильтра предлагает преимущества в оборудовании, так как она вдвое меньше коэффициентов для работы. Это существенно снижает сложность оборудования. Создайте новую конечную импульсную характеристику фильтр Системного объекта 'lpSymFilter' со структурой 'Direct form symmetric' и теми же настройками фиксированной точки.

lpSymFilter = design(lpSpec, 'equiripple', 'filterstructure', 'dfsymfir',...
    'SystemObject', true);

lpSymFilter.FullPrecisionOverride = false;
lpSymFilter.CoefficientsDataType = 'Custom';
lpSymFilter.CustomCoefficientsDataType = coeffsDataType;
lpSymFilter.OutputDataType = 'Custom';
lpSymFilter.CustomOutputDataType = outputDataType;

% Calculate filter length FL for lpSymFilter for the purpose of calculating 'DALUTPartition'
FL = ceil(length(lpSymFilter.Numerator)/2);

% Generate the  value for 'DALUTPartition' as done previously for lpFilter.
dalut_sym = [ones(1, floor(FL/8))*8, mod(FL, 8)];

% Generate HDL code for default radix of 2
generatehdl(lpSymFilter, 'DALUTPartition', dalut_sym, ...
                   'TargetDirectory', workingdir, ...
                   'InputDataType', inputDataType);
### Starting VHDL code generation process for filter: firfilt
### Generating: /tmp/BR2021ad_1655202_180016/mlx_to_docbook1/tp65546d1a_b9ca_474d_82e0_aeff8a74cd8d/firfilt.vhd
### Starting generation of firfilt VHDL entity
### Starting generation of firfilt VHDL architecture
### Clock rate is 13 times the input sample rate for this architecture.
### Successful completion of VHDL code generation process for filter: firfilt
### HDL latency is 3 samples

Заметьте, что симметричный фильтр принимает один дополнительный тактовый цикл перед получением выхода. Это происходит из-за бита переноса, который добавляется к входу размера слова когда входные данные от симметричных отводов суммируются вместе. Тактовая частота для 'lpSymFilter' в 13 раз превышает входную частоту выборки, тогда как для 'lpFilter' тактовая частота была в 12 раз выше входной частоты выборки.

DARadix

Архитектурой по умолчанию является реализация Radix 2, которая работает с одним битом входных данных на каждом такте. Количество тактовых импульсов, прошедших до получения выхода, равно количеству бит во входных данных. Таким образом, DA может потенциально ограничить пропускную способность. Чтобы улучшить пропускную способность DA, можно сконфигурировать DA, чтобы обрабатывать несколько биты параллельно. Для этой цели предоставляется свойство 'DARadix'. Для примера можно задать 'DARadix' на 2 ^ 3, чтобы работать с 3 битами параллельно. Для 12-битной длины входного слова можно задать обработку 1, 2, 3, 4, 6 или 12 битов за раз, задав соответствующие значения 'DARadix' 2 ^ 1, 2 ^ 2, 2 ^ 3, 2 ^ 4, 2 ^ 6 или 2 ^ 12 соответственно.

При выборе различных значений 'DARadix' происходит компромисс скорости и площади в архитектуре DA. Количество бит, работающих параллельно, определяет коэффициент, на который необходимо увеличить тактовую частоту. Это известно как коэффициент складывания. Например, значение по умолчанию 'DARadix 2 ^ 1, подразумевающее 1 бит за раз, приводит к тактовой частоте, в 12 раз превышающей входную частоту дискретизации или коэффициент складывания 12. 'DARadix' из 2 ^ 3 результаты с тактовой частотой только в 4 раз больше, чем вход скорость выборки, но требует 3 одинаковых наборов LUT, по одному на каждый бит, обрабатываемый параллельно.

Информация об архитектуре DA

Как объяснялось в предыдущем разделе, архитектура DA представляет массу опций как с точки зрения размеров LUT, так и коэффициента складывания. Можно использовать функцию hdlfilterdainfo, чтобы получить информацию относительно различных длин фильтра на основе значения коэффициентов. Эта функция также отображает две другие таблицы, одна для всех возможных значений свойства DARadix с соответствующими факторами складывания. Во второй таблице отображаются детали наборов LUT с соответствующими значениями свойства DALUTPartition.

hdlfilterdainfo(lpFilter, 'InputDataType', inputDataType);
   | Total Coefficients | Zeros | Effective |
   ------------------------------------------
   |         58         |   0   |     58    |

Effective filter length for SerialPartition value is 58.

  Table of 'DARadix' values with corresponding values of 
  folding factor and multiple for LUT sets for the given filter.

   | Folding Factor | LUT-Sets Multiple | DARadix |
   ------------------------------------------------
   |        1       |         12        |   2^12  |
   |        2       |         6         |   2^6   |
   |        3       |         4         |   2^4   |
   |        4       |         3         |   2^3   |
   |        6       |         2         |   2^2   |
   |       12       |         1         |   2^1   |

  Details of LUTs with corresponding 'DALUTPartition' values.

   | Max Address Width | Size(bits) |                          LUT Details                         |    DALUTPartition   |
   -----------------------------------------------------------------------------------------------------------------------
   |         12        |   259072   |1x1024x13, 1x4096x13, 1x4096x14, 1x4096x15, 1x4096x18         |[12 12 12 12 10]     |
   |         11        |   147544   |2x2048x13, 2x2048x14, 1x2048x18, 1x8x11                       |[11 11 11 11 11 3]   |
   |         10        |    78080   |3x1024x13, 1x1024x16, 1x1024x18, 1x256x13                     |[10 10 10 10 10 8]   |
   |         9         |    43712   |1x16x12, 1x512x12, 2x512x13, 1x512x14, 1x512x15, 1x512x18     |[9 9 9 9 9 9 4]      |
   |         8         |    25384   |4x256x13, 1x256x14, 1x256x15, 1x256x18, 1x4x10                |[8 8 8 8 8 8 8 2]    |
   |         7         |    14248   |2x128x12, 3x128x13, 1x128x14, 1x128x16, 1x128x18, 1x4x10      |[7 7 7 7 7 7 7 7 2]  |
   |         6         |    8000    |1x16x12, 4x64x12, 1x64x13, 2x64x14, 1x64x16, 1x64x17          |[ones(1,9)*6, 4]     |
   |         5         |    4696    |1x32x11, 4x32x12, 3x32x13, 1x32x14, 1x32x15, 1x32x17, 1x8x11  |[ones(1,11)*5, 3]    |
   |         4         |    2904    |3x16x11, 5x16x12, 2x16x13, 2x16x14, 1x16x15, 1x16x17, 1x4x10  |[ones(1,14)*4, 2]    |
   |         3         |    1926    |1x2x7, 5x8x11, 8x8x12, 1x8x13, 2x8x14, 2x8x15, 1x8x17         |[ones(1,19)*3, 1]    |
   |         2         |    1412    |2x4x10, 12x4x11, 6x4x12, 2x4x13, 4x4x14, 2x4x15, 1x4x17       |ones(1,29)*2         |

Notes:
1. LUT Details indicates number of LUTs with their sizes. e.g. 1x1024x18
   implies 1 LUT of 1024 18-bit wide locations.

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

hdlfilterdainfo(lpFilter, 'InputDataType', inputDataType, ...
                    'LUTInputs', 4);
   | Folding Factor | LUT Inputs | LUT Size |                             LUT Details                             |
   ----------------------------------------------------------------------------------------------------------------
   |        1       |      4     |   34848  |12 x (3x16x11, 5x16x12, 2x16x13, 2x16x14, 1x16x15, 1x16x17, 1x4x10)  |
   |        2       |      4     |   17424  |6 x (3x16x11, 5x16x12, 2x16x13, 2x16x14, 1x16x15, 1x16x17, 1x4x10)   |
   |        3       |      4     |   11616  |4 x (3x16x11, 5x16x12, 2x16x13, 2x16x14, 1x16x15, 1x16x17, 1x4x10)   |
   |        4       |      4     |   8712   |3 x (3x16x11, 5x16x12, 2x16x13, 2x16x14, 1x16x15, 1x16x17, 1x4x10)   |
   |        6       |      4     |   5808   |2 x (3x16x11, 5x16x12, 2x16x13, 2x16x14, 1x16x15, 1x16x17, 1x4x10)   |
   |       12       |      4     |   2904   |1 x (3x16x11, 5x16x12, 2x16x13, 2x16x14, 1x16x15, 1x16x17, 1x4x10)   |

Можно также выбрать одно из двух свойств, связанных с коэффициентом складывания, 'FoldingFactor' или 'DARadix', чтобы отобразить все опции LUT для определенного фактора складывания.

hdlfilterdainfo(lpFilter, 'InputDataType', inputDataType, ...
                    'Foldingfactor', 6);
   | Folding Factor | LUT Inputs | LUT Size |                             LUT Details                            |
   ---------------------------------------------------------------------------------------------------------------
   |        6       |     12     |  518144  |2 x (1x1024x13, 1x4096x13, 1x4096x14, 1x4096x15, 1x4096x18)         |
   |        6       |     11     |  295088  |2 x (2x2048x13, 2x2048x14, 1x2048x18, 1x8x11)                       |
   |        6       |     10     |  156160  |2 x (3x1024x13, 1x1024x16, 1x1024x18, 1x256x13)                     |
   |        6       |      9     |   87424  |2 x (1x16x12, 1x512x12, 2x512x13, 1x512x14, 1x512x15, 1x512x18)     |
   |        6       |      8     |   50768  |2 x (4x256x13, 1x256x14, 1x256x15, 1x256x18, 1x4x10)                |
   |        6       |      7     |   28496  |2 x (2x128x12, 3x128x13, 1x128x14, 1x128x16, 1x128x18, 1x4x10)      |
   |        6       |      6     |   16000  |2 x (1x16x12, 4x64x12, 1x64x13, 2x64x14, 1x64x16, 1x64x17)          |
   |        6       |      5     |   9392   |2 x (1x32x11, 4x32x12, 3x32x13, 1x32x14, 1x32x15, 1x32x17, 1x8x11)  |
   |        6       |      4     |   5808   |2 x (3x16x11, 5x16x12, 2x16x13, 2x16x14, 1x16x15, 1x16x17, 1x4x10)  |
   |        6       |      3     |   3852   |2 x (1x2x7, 5x8x11, 8x8x12, 1x8x13, 2x8x14, 2x8x15, 1x8x17)         |
   |        6       |      2     |   2824   |2 x (2x4x10, 12x4x11, 6x4x12, 2x4x13, 4x4x14, 2x4x15, 1x4x17)       |

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

Можно использовать выходные аргументы, чтобы вернуть значения DALUTPartition и DARadix для определенного строения и использовать его с командой generatehdl. Предположим, что вы можете увеличить тактовую частоту в 4 раза больше частоты дискретизации и хотите использовать 6 входных LUT. Можно проверить, что данные LUT соответствуют требованиям области.

hdlfilterdainfo(lpFilter, 'InputDataType', inputDataType, ...
                    'FoldingFactor', 4, ...
                    'LUTInputs',  6);
   | Folding Factor |     LUT Size     |                         LUT Details                        |  DALUTPartition  | DARAdix |
   -------------------------------------------------------------------------------------------------------------------------------
   |        4       | 3 x 8000 = 24000 |3 x (1x16x12, 4x64x12, 1x64x13, 2x64x14, 1x64x16, 1x64x17)  | [ones(1,9)*6, 4] |   2^3   |

Теперь сгенерируйте HDL с вышеуказанными ограничениями, сначала сохраняя необходимые значения DALUTPartition и DARadix в переменных с помощью выходных аргументов в функцию hdlfilterdainfo. Затем можно вызвать команду generatehdl, используя эти переменные.

[dalut, dr] = hdlfilterdainfo(lpFilter, 'InputDataType', inputDataType, ...
                                  'FoldingFactor', 4, ...
                                  'LUTInputs', 6);

generatehdl(lpFilter, 'InputDataType', inputDataType, ...
                'DALUTPartition', dalut, ...
                'DAradix', dr, ...
                'TargetDirectory', workingdir);
Warning: Structure fir has symmetric coefficients, consider converting to structure symmetricfir for reduced area.
Warning: Structure fir has symmetric coefficients, consider converting to structure symmetricfir for reduced area.
### Starting VHDL code generation process for filter: firfilt
### Generating: /tmp/BR2021ad_1655202_180016/mlx_to_docbook1/tp65546d1a_b9ca_474d_82e0_aeff8a74cd8d/firfilt.vhd
### Starting generation of firfilt VHDL entity
### Starting generation of firfilt VHDL architecture
### Clock rate is 4 times the input sample rate for this architecture.
### Successful completion of VHDL code generation process for filter: firfilt
### HDL latency is 3 samples

Заключение

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

Можно сгенерировать испытательный стенд с помощью стандартного стимула и/или собственного определенного стимула и использовать Симулятор HDL для проверки сгенерированного HDL-кода для архитектур DA. Можно использовать инструмент синтеза, чтобы сравнить площадь и скорость этих архитектур.