HDL распределенная арифметика для КИХ-фильтров

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

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

Распределенная Арифметика является популярной архитектурой для реализации КИХ-фильтров без использования множителей. DA понимает сумму расчета продуктов, требуемого для КИХ-фильтров, эффективно использующих LUTs, переключатели и сумматоры. Начиная с этих операций карта эффективно на FPGA, DA является привилегированной архитектурой на этих устройствах.

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

Используйте уровень выборки 48 кГц, частоту ребра полосы пропускания 9,6 кГц и частоту остановки 12k. Установите допустимую неравномерность в полосе пропускания от пика к пику на 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 дробными битами требуются (из-за фиксированных требований информационного канала или ширин входа ADC/output DAC). Примените эти настройки фиксированной точки.

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

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

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

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

FL = length(lpFilter.Numerator);

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

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/BR2019bd_1276998_130124/mlx_to_docbook1/tp8781ba67_a2c3_440a_b260_4cbef65a6c7d/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

Преобразуйте Структуру Фильтра в 'Прямую форму, симметричную', и Сгенерируйте HDL

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

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/BR2019bd_1276998_130124/mlx_to_docbook1/tp8781ba67_a2c3_440a_b260_4cbef65a6c7d/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

Архитектурой по умолчанию является Основание 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 идентичных наборов LUTs, один для каждого бита, обрабатываемого параллельно.

Информация относительно архитектуры 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 входов LUTs. Можно проверить, что детали 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/BR2019bd_1276998_130124/mlx_to_docbook1/tp8781ba67_a2c3_440a_b260_4cbef65a6c7d/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 путем тиражирования LUTs и работы с несколькими битами параллельно.

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