8 декабря 2015 в 11:53

Цифровая фильтрация на ПЛИС – Часть 2 tutorial



Всем привет!

Это вторая публикация на тему «Цифровая фильтрация на ПЛИС». Вторая часть будет посвящена практической реализации КИХ фильтров на FPGA. В процессе подготовки материала я понял, что она раздуется до небывалых размеров, но делить ее на несколько частей не хочется. Поэтому все тонкости теории и синтеза FIR фильтров будут в одной статье, разбитой на взаимосвязанные разделы. Начну обзор с теоретической части, в частности — расскажу об особенностях и методах расчета коэффициентов фильтров. Подробно рассмотрю создание КИХ фильтров в различных средах — MATLAB, CoreGENERATOR, Vivado HLS. Всех заинтересовавшихся прошу под кат.

Часть 2. КИХ фильтр


Теория


Рассмотрим простой пример реализации FIR фильтров. Как известно, существует два больших класса фильтров — БИХ, с бесконечной импульсной характеристикой и КИХ, с конечной импульсной характеристикой. Остановимся на втором типе: КИХ фильтрах (англ. FIR — «finite impulse response»). КИХ фильтр — это линейный цифровой фильтр, основной особенностью которого является ограниченность во времени его импульсной характеристики, то есть с определенного момента времени она становится равной нулю. Как правило, большинство КИХ фильтров выполнено без обратной связи, поэтому практически все КИХ фильтры — нерекурсивные.

Вот так выглядит реализация КИХ фильтра в общем виде, в частности — на ПЛИС.


Все КИХ-фильтры описываются следующими уравнениями:

где y(n) — выходной сигнал (функция текущего и прошедших значений на входе), x(n) — входное воздействие, h(k) — коэффициенты импульсной характеристики, N — длина фильтра (количество коэффициентов фильтра), H(z) — передаточная характеристика фильтра.

В чем секрет КИХ фильтров?
Самая важная особенность КИХ фильтров заключается в возможности получения точной линейной фазовой характеристики. У читателя возникает закономерный вопрос — «а зачем это надо?». Остановимся на этом моменте подробнее. Сигнал подвергается различным преобразованиям при прохождении через фильтр. В частности, изменяются амплитуда и фаза сигнала в зависимости от частотной характеристики фильтра (амплитудной, АЧХ и фазовой, ФЧХ). Для многочастотных сигналов недопустимо, чтобы при прохождении блоков обработки, фаза сигнала искажалась. Причем, если АЧХ в полосе пропускания сделать практически постоянной не составляет труда, то с ФЧХ возникают проблемы. Для оценки искажений фазы удобно ввести понятия фазовой и групповой задержек.
Фазовая задержка — это величина задержки для каждой из частотных компонент сигнала. Определяется как угол сдвига фазы, деленный на частоту. Групповая задержка — это средняя временная задержка всего многочастотного сигнала. Определяется как производная фазы по частоте. Математически фазовая и групповая задержки записываются следующим образом:

Из формулы для групповой задержки становится очевидно условие линейности ФЧХ фильтра. Если ФЧХ — линейна, то групповая задержка после взятия производной равна константе, то есть постоянна для всех частотных компонент. Логично, что фильтр с нелинейной ФЧХ будет вносить искажения в фазу сигнала.
Таким образом, линейность фазовой характеристики — одна из важнейших особенностей КИХ-фильтров. Остановимся на изучении этого класса фильтров.

КИХ фильтры с линейной ФЧХ


Для обеспечения линейности ФЧХ необходимо выполнение условия симметрии импульсной характеристики (или коэффициентов) фильтра. Проще говоря, КИХ фильтр с линейной ФЧХ — симметричен. Существует 4 типа фильтров, отличающихся четностью порядка фильтра N и типом симметрии (положительная или отрицательная). Например, для фильтров с отрицательной симметрией можно получить сдвиг фазы на 90o. Такие фильтры используются для проектирования дифференциаторов и преобразования Гильберта. Огибающая импульсной характеристики КИХ фильтра строится по закону ~sin(x)/x независимо от типа фильтра (ФНЧ, ФВЧ, ПФ, РФ, дифференциатор). Для решения практических задач зачастую не приходится задумываться о том, какого типа фильтр выбран. Доказательство условия симметрии коэффициентов приводить не буду, но любопытный читатель может найти его сам в различной литературе, ссылки на которую я привожу в конце статьи.

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


Под «расчетом FIR фильтра» в большинстве случаев понимают поиск его коэффициентов по значениям частотной характеристики. Не могу припомнить случаев, когда решалась бы обратная задача за исключением академического интереса.

При создании нового цифрового КИХ фильтра любой инженер проходит через определенные стадии разработки*:
  • Спецификация фильтра. Задается тип фильтра (ФНЧ, ФВЧ, полосовой, режекторный), количество коэффициентов N, требуемая частотная характеристика, с допусками на нелинейность в полосе затухания и полосе пропускания и т. д.
  • Вычисление коэффициентов. Любыми доступными способами и средствами вычисляются коэффициенты фильтра, удовлетворяющие спецификации из предыдущего пункта.
  • Анализ следствий конечной разрядности. На этом этапе оценивается влияние эффектов квантования на коэффициенты фильтра, промежуточные и выходные данные.
  • Реализация. На этой стадии происходит разработка фильтра на доступном языке программирования или реализация фильтра путем создания готовых IP-ядер.

* — этапы разработки могут быть несколько иными, но суть всегда остается та же.

Спецификация фильтра

На этой стадии инженер производит поиск компромиссных решений для реализации требуемого фильтра с нужными параметрами. Их немного, но часто приходится жертвовать одним параметром для достижения требуемых значений по другим величинам.
  • Apass — неравномерность в полосе пропускания,
  • Astop — уровень затухания в полосе подавления,
  • Fpass — граничная частота полосы пропускания,
  • Fstop — граничная частота полосы затухания,
  • N — порядок фильтра (количество коэффициентов фильтра).

На практике, параметры Apass и Astop задают в децибелах (дБ), а расстояние между Fpass и Fstop выражает ширину полосы перехода фильтра. Логично, что значение Apass должно быть как можно меньше, Apass как можно больше, а отношение Fpass/Fstop в идеале стремится к единице (идеально прямоугольная АЧХ). Количество коэффициентов не зря вносится в спецификацию фильтра. Как будет показано далее, от порядка фильтра N и разрядности коэффициентов зависят параметры частотной характеристики фильтра, а также объем занимаемых ресурсов ПЛИС.

Вычисление коэффициентов фильтра

На эту тему можно написать несколько книг и научных статей, но в рамках данной статьи рассматривать подробно все методы не будем. Существует множество методов расчета коэффициентов фильтра — метод взвешивания оконными функциями, метод частотной выборки, различные оптимальные (по Чебышеву) методы с применением алгоритма Ремеза и т.д. Все методы уникальны по своим особенностям и дают те или иные результаты. Для метода оконного взвешивания негативным проявлением становится эффект Гиббса, вносящий неравномерность и выбросы в частотную характеристику фильтра между рассчитанными точками функции. Бороться с ним можно бесконечно, но на практике вводят допуски по неравномерностям в полосе пропускания и полосе подавления.

Основным методом расчета коэффициентов для многих фильтров является модифицированный алгоритм Ремеза — «Parks-McClellan algorithm». По своей сути это косвенный итерационный метод для нахождения оптимальных значений с Чебышевской характеристикой фильтра. Особенность метода заключается в минимизации ошибки в полосе затухания и пропускания путем Чебышевской аппроксимации импульсной характеристики. Вполне логично, что чем больше количество коэффициентов, тем меньше неравномерность АЧХ и тем она прямоугольнее.
От выбора метода зависит конечный результат, но все они сводятся к одним и тем же целям — минимизации выбросов в полосе пропускания и увеличении «прямоугольности» АЧХ.

Анализ следствий конечной разрядности

Разрядность коэффициентов — главный фактор, от которого зависит вид частотной характеристики. В современных ПЛИС разрядность коэффициентов может быть выбрана любой, но разумные цифры лежат в пределах от 16 до 27 битов. Для высоких порядков фильтра часто требуется обеспечить большой динамический диапазон разрядной сетки, но если этого не удается сделать, рано или поздно начинают проявляться ошибки квантования. Из-за ограниченной разрядности коэффициентов модифицируется частотная характеристика, а в некоторых случаях она искажается настолько сильно, что приходится жертвовать параметрами из частотной спецификации для достижения приемлемого результата. Так или иначе, разрядность представления коэффициентов прямо влияет на максимально возможное затухание Astop. Поэтому при использовании слишком ограниченной разрядной сетки коэффициентов, порой невозможно достичь желаемого подавления даже при огромных порядках фильтра!

Разрядность промежуточных данных и арифметическое переполнение — факторы, от которых также зависит вид частотной характеристики и результат на выходе фильтра. Во многих ПЛИС проблема устраняется использованием аккумуляторов большой разрядности в блоках DSP. Например, в ПЛИС Xilinx 6 и 7 серии в ячейках DSP48E1 используются 48-битные аккумуляторы и перемножители. На следующем рисунке представлен стандартный блок DSP48E1, на котором реализуются КИХ фильтры.

Встроенные DSP блоки современных ПЛИС выполнены таким образом, чтобы максимально удобно проводить задачи ЦОС. В первую очередь — для реализации FIR фильтров.

Реализация

Для реализации простейших фильтров требуется совсем немного логических операций. Основной узел, с помощью которого реализуется FIR фильтр — DSP блок ПЛИС. В этом блоке происходят все математические операции — перемножение входных отсчетов с коэффициентами фильтров, задержка входного сигнала, суммирование данных. Современные узлы DSP содержат предварительный сумматор, поэтому даже операции суммирования для фильтров с симметричной ИХ можно делать внутри этого узла. Помимо DSP блока, фильтру нужна память для хранения коэффициентов (распределенная или блочная). Больше фильтр ничего не использует. На рисунке приведена реализация КИХ фильтра с использованием перемножителей, аккумуляторов, линий задержки и памяти для хранения коэффициентов.



Расчет фильтра в MATLAB


Существует множество приложений, в которых можно проводить расчет фильтра и поиск его коэффициентов. Например, LABView, Scope FIR, FDATool из MATLAB или бесплатного аналога Octave. Пожалуй, самым удобным средством расчета КИХ фильтра является MATLAB. Для запуска средства создания и анализа фильтров необходимо в командном окне среды набрать ключевое слово fdatool. Появится примерно вот такое окно (в зависимости от версии MATLAB оно может иметь чуть иной вид):


Основные параметры задаются в окне Filter Specifications. В зависимости от настроек фильтра в области главного окна могут появляться те или иные параметры.
  • Filter Order — определяет порядок фильтра (минимальный или заданный пользователем)**.
  • Frequency Specifications — определяет частотные параметры характеристики фильтра.
  • Magnitude Specifications — определяет амплитудные параметры характеристики фильтра.
  • Density Factor — для типа Equiripple задает сетку точек, по которым происходит аппроксимация АЧХ фильтра.

** — в FDATool порядок фильтра N на единицу больше заданного (если задать N = 7, то утилита рассчитывает 8 коэффициентов)!!!

Response type — тип передаточной характеристики фильтра. В этом поле выбирается любой фильтр, какой только существует в природе, например:
  • Lowpass — фильтр нижних частот,
  • Raised cosine — фильтр «приподнятого косинуса»,
  • Highpass — фильтр верхних частот,
  • Bandpass — полосовой фильтр,
  • Bandstop — режекторный (заграждающий) фильтр,
  • Differentiator — дифференциатор,
  • Nyquist — фильтр Найквиста,
  • Multiband — многополосный фильтр,
  • Hilbert transformer — преобразователь Гильберта,
  • Arbitrary magnitude — фильтры с произвольной АЧХ.
и т.д.

Причем, в зависимости от типа фильтра, средство анализа укажет на ограничения по типу фильтра и предложит ввести корректное значение N.

Design Method — выбирается метод проектирования фильтра и его тип (БИХ или КИХ). Для БИХ фильтров доступны варианты:
  • Butterworth — фильтры с характеристикой Баттерворта,
  • Chebyshev Type I, II — фильтры Чебышева,
  • Elliptic — эллиптический фильтр,
  • Maximally flat — фильтр с максимально плоской характеристикой в полосе пропускания,
и т. д.

Для КИХ фильтров доступны варианты***:
  • Equiripple — фильтр с равномерно пульсирующей АЧХ,
  • Least-squares — фильтр по методу наименьших квадратов,
  • Window — фильтр с оконным взвешиванием различными функциями****,
  • Complex Equiripple — комплексный фильтр с равномерно пульсирующей АЧХ,
  • Maximally flat — фильтр с максимально плоской характеристикой в полосе пропускания,
и т.д.

*** — наибольший практический интерес представляют фильтры типа Equiripple и Window.
**** — при выборе этой опции появляется панель доступа к оконным функциям и их параметрам.

Для метода Equiripple производится самый простейший расчет КИХ фильтра по модифицированному алгоритму Ремеза. Пользователь задает параметры из спецификации на фильтр и сразу видит результат. В случае неудовлетворительных результатов можно в любой момент изменить один или несколько параметров фильтра и получить другую частотную характеристику. Расчет проводится до тех пор, пока не получены требуемые характеристики. Если не удалось добиться значений по заданию, то рано или поздно придется жертвовать той или иной величиной из спецификации, либо существенно увеличивать порядок фильтра N.

Для метода Window доступно несколько вариантов оконных функций: Bartlett, Blackman, Blackman-Harris, Chebyshev, Flat Top, Gaussian, Hamming, Hann, Kaiser, Rectangular и т. д., вплоть до пользовательских оконных функций (User-defined). Все эти функции обладают своими особенностями и могут давать различные параметры частотной характеристики КИХ фильтра. Часть оконных функций рассчитывается без параметров, а часть фильтров задается через определенные параметры, влияющие на АЧХ фильтра.
Из всех представленных оконных функций, на мой взгляд, самой удобной является окно Кайзера. Для построения АЧХ требуется задать всего один параметр Beta, который влияет на уровень подавления в полосе затухания и на прямоугольность частотной характеристики.

Слева снизу относительно главной рабочей области средство FDATool содержит дополнительные вкладки, в которых можно указать тип фильтра (дециматор или интерполятор), имя модели для вставки в Simulink, тип и разрядность коэффициентов и входных данных и многое другое. В практических целях самые основные вкладки это Design Filter — в ней происходит расчет фильтра, и Quantinization Parameters — в этой вкладке задается тип и разрядность данных.
На верхней панели находятся кнопки, с помощью которых можно посмотреть АЧХ и ФЧХ фильтра, групповую и фазовую задержку, импульсную и переходную характеристики, карту нулей и полюсов фильтра, рассчитанные коэффициенты и т.д.

Скриншоты рабочей области FDATool
График АЧХ и ФЧХ фильтра:


График импульсной характеристики фильтра:


График диаграммы нулей и полюсов:


Помимо всего этого, FDATool позволяет импортировать и экспортировать модели фильтров и рассчитанные коэффициенты. Например, можно рассчитать фильтр и отправить его модель в Simulink в виде модели на стандартных примитивах. Можно рассчитать коэффициенты и сохранить их в отдельном файле, например, как файл с расширением *.h (header).

Файл заголовка *.h с коэффициентами фильтра
/*
 * Discrete-Time FIR Filter (real)
 * -------------------------------
 * Filter Structure  : Direct-Form FIR
 * Filter Length     : 128
 * Stable            : Yes
 * Linear Phase      : Yes (Type 2)
 * Arithmetic        : fixed
 * Numerator         : s16,15 -> [-1 1)
 *   Round Mode      : convergent
 */

/* General type conversion for MATLAB generated C-code  */
#include "tmwtypes.h"

const int BL = 128;
const int16_T B[128] = {
      -18,      0,     19,     39,     58,     75,     88,     97,    100,
       96,     85,     68,     44,     16,    -16,    -50,    -83,   -113,
     -139,   -157,   -166,   -164,   -152,   -128,    -94,    -51,      0,
       55,    111,    164,    211,    248,    272,    280,    269,    240,
      192,    126,     45,    -47,   -146,   -245,   -339,   -421,   -483,
     -521,   -528,   -501,   -434,   -329,   -183,      0,    217,    462,
      728,   1006,   1288,   1564,   1823,   2056,   2254,   2409,   2517,
     2571,   2571,   2517,   2409,   2254,   2056,   1823,   1564,   1288,
     1006,    728,    462,    217,      0,   -183,   -329,   -434,   -501,
     -528,   -521,   -483,   -421,   -339,   -245,   -146,    -47,     45,
      126,    192,    240,    269,    280,    272,    248,    211,    164,
      111,     55,      0,    -51,    -94,   -128,   -152,   -164,   -166,
     -157,   -139,   -113,    -83,    -50,    -16,     16,     44,     68,
       85,     96,    100,     97,     88,     75,     58,     39,     19,
        0,    -18
};


Кроме того, можно создать файл коэффициентов *.COE в специальном формате для Xilinx. Для этого нужно выбрать тип коэффициентов с фиксированной точкой и задать их разрядность. Затем нажать Targets -> Xilinx Coefficient (.COE) File, в результате чего в главном окне MATLAB отобразится содержимое файла — глобальные настройки и коэффициенты в HEX-формате.

Пример *.coe файла
; XILINX CORE Generator(tm)Distributed Arithmetic FIR filter coefficient (.COE) File
; Generated by MATLAB(R) 8.3 and the DSP System Toolbox 8.6.
;
; Generated on: 06-Dec-2015 15:35:35
;
Radix = 16; 
Coefficient_Width = 18; 
CoefData = 3ffeb,
00018,
00049,
00067,
0005f,
00029,
3ffd2,
3ff79,
3ff46,
3ff59,
...


Видно, что при подаче на вход единичного импульса, на выходе образуется не что иное, как импульсная характеристика фильтра (график из Simulink).


Xilinx FIR Compiler


Как и в случае с CIC фильтром, приведу подробное описание средства создания FIR фильтров от Xilinx. Отмечу, что описание содержит не просто перевод из даташита, а замечания и рекомендации из личного опыта и опыта моих коллег.

FIR Compiler — Вкладка 1:


Component name — имя компонента (используются латинские буквы a-z, цифры 0-9 и символ "_").
Рекомендую использовать осмысленные имена, в которых зашифрованы главные параметры фильтра. Например, xfir128t_d1_b18_4c_w6_a7 — фильтр, сделанный для Xilinx, N = 128 (taps), децимация не используется, разрядность коэффициентов 18, четыре канала, применена оконная функция Кайзера с параметром beta = 6, кристалл ПЛИС — Artix-7.

Filter Coefficients:
  • Select source — выбор источника коэффициентов (Vector — вектор, заданный вручную или COE File — файл с набором коэффициентов). Предпочтительно использовать перегружаемые *.COE файлы.
  • Coefficient Vector — вектор коэффициентов, задаваемый вручную.
  • Coefficient File — вектор коэффициентов, считываемый из файла.
  • Number of Coefficient Sets — количество реально используемых DSP блоков для обработки коэффициентов. Количество коэффициентов должно делиться нацело на указанное значение. Полезная опция при работе на высокой частоте относительно частоты дискретизации, позволяет существенно экономить ресурсы ПЛИС.
  • Number of Coefficient (per set) — количество коэффициентов, обрабатываемых единовременно DSP блоками. Значение в поле автоматически устанавливается при считывании количества коэффициентов и предыдущего параметра.

Filter Specification:
  • Filter type — тип фильтра: простой / интерполирующий / децимирующий / полифазный.
  • Rate Change Type — изменение скорости обработки. Может быть целочисленным или дробным.
  • Interpolation / Decimation Rate Value — коэффициент интерполяции / децимации.
  • Zero Pack Factor — для интерполирующих фильтров параметр определяет количество нулей, вставляемых между коэффициентами.
  • Number of channels — количество независимых каналов фильтрации: 1-64.

Hardware Oversampling Specification: эти параметры влияют на выходную частоту дискретизации, количество тактов, требуемых для обработки данных. От этих параметров также зависит уровень параллелизма внутри ядра и количество занимаемых ресурсов.
  • Select format — выбор частотных соотношений фильтра: Frequency Specification / Sample period.
  • Frequency Specification — Частотная спецификация: пользователь задает частоту дискретизации и частоту обработки данных.
  • Sample period — Тактовая спецификация: пользователь задает отношение частоты обработки к тактовой частоте данных.
  • Input Sampling Frequency — входная частота дискретизации: *.
  • Clock frequency — частота обработки фильтра: *****.
  • Input Sampling period — отношение частоты обработки к частоте входного тактового сигнала: *****.

***** — диапазон зависит от общих настроек и коэффициента дискретизации R.

FIR Compiler — Вкладка 2:


Filter Architecture — задает реализуемую архитектуру фильтра.
  • Systolic Multiply Accumulate — систолический фильтр с накоплением,
  • Transpose Multiply Accumulate — перестраиваемый фильтр с накоплением,
  • Distributed Arithmetic — фильтр на распределенной логике ПЛИС.

Coefficient Options — параметры для коэффициентов
  • Use Reloadable Coeffcients — использовать перегружаемые коэффициенты. Полезная опция для реализации в одном фильтре перегружаемых частотных характеристик.
  • Coefficient Structure — структура коэффициентов, 5 типов: несимметричные, симметричные, отрицательно симметричные, полуполосные и с преобразованием Гильберта. По умолчанию FIR compiler пытается сам определить тип коэффициентов (inferred).
  • Coefficient Type — тип коэффициентов: знаковый или беззнаковый.
  • Quantization — задает метод округления: целочисленные коэффициенты, округление к ближайшему целому или максимальный динамический диапазон (масштабирует коэффициенты относительно максимального).
  • Coefficient Width — разрядность коэффициентов. Значение в этом поле влияет на частотную характеристику фильтра, что можно наблюдать в соответствующем окне (Freq. Response).
  • Best Precision Fraction Length — автоматически устанавливает наилучшее соотношение для целой и дробной частей разрядной сетки.
  • Coefficient Fractional Bits — определяет позицию для разделения целой части от дробной в разрядной сетке представления коэффициентов.

Datapath Options — опции входных данных
  • Number of Paths — определяет количество параллельных каналов для обработки. Количество DSP ядер пропорционально значению в этом поле. Для этой опции на вход фильтра поступает несколько независимых потоков данных, в то время как для параметра Number of Channels данные поступают на один вход и обрабатываются последовательно.
  • Input Data Type — тип данных на входе фильтра (знаковый или беззнаковый).
  • Input Data Width — разрядность входных данных.
  • Input Data Fractional Bits — определяет количество бит, приходящихся на дробную часть представления входных данных. Значение в этом поле не влияет на реализацию фильтра! (число с фиксированной точкой можно представить как угодно: с дробной частью или вовсе без нее, но результат один и тот же).
  • Output Rounding Mode — режим округления выходных данных: полная точность, отбрасывание младших значащих битов, округление до целого вниз/вверх, округление до четного/нечетного. Во многих задачах не требуется менять этот параметр и можно оставить Full Precision — полную точность.
  • Output Width — разрядность выходных данных фильтра.
  • Output Fractional Bits — количество бит, определяющих дробную часть выходных данных. Поле информативное и не влияет на реализацию фильтра.
  • Allow Rounding Approximation — для режимов Symmetric Rounding Mode опция разрешает аппроксимацию при округлении без дополнительных затрат ресурсов (автоматическое определение знакового бита в слове).
  • Registered Output — активная опция добавляет на выход фильтра дополнительный регистр для увеличения производительности (максимальной частоты обработки) фильтра.

FIR Compiler — Вкладка 3:


Optimization Goal — определяет цель оптимизации при создании фильтра (Area — по площади, Speed — по скорости). В большинстве случаев удается одновременно достичь максимальной скорости и минимальной затраты ресурсов, но в специфических случаях при указании Speed фильтр оптимальным образом расставляет внутренние регистры в критических путях между логическими функциями.
  • SCLR — синхронный сброс фильтра (логическая единица на входе производит сброс).
  • Use Deterministic SCLR Behavior — определяет поведение внутренних данных фильтра типа Multiply-Accumulate в процессе сброса. При активной опции сигнал сброса очищает внутренние регистры, память данных и хранения коэффициентов.
  • ND — «New data», входной сигнал, определяющий поступление данных на вход фильтра. Вместе с сигналом RFD позволяют организовать пакетную обработку данных. Как правило, сигналы ND и RFD подключают к управляющим сигналам FIFO.
  • CE — «Clock Enable», сигнал разрешения тактирования фильтра. При низком уровне на входе этого сигнала приостанавливается любая обработка внутри фильтра, независимо от того, поступают новые данные или нет.
  • DATA_VALID — сигнал валидности выходных данных. Опция полезна только в многоканальном режиме (Number of Channels > 1).

Memory Options — глобальные настройки выбора типа памяти для хранения входных данных, коэффициентов фильтра, промежуточных и выходных данных. Выбирая блочную память вместо распределенной, в некоторых случаях можно в сотни раз сэкономить логические ресурсы ПЛИС!
Для Data / Coefficient / Input / Output Buffer Type возможны режимы Auto / Block / Distributed.
Preference for Other Storage — определяет тип памяти для промежуточных данных. Также доступны режимы Auto / Block / Distributed.

DSP Slice Column Options — определяет настройки распределения DSP блоков между колонками ПЛИС. Для некоторых архитектур фильтров, например, с симметричными коэффициентами недоступен режим Multi-Colomn Support, поэтому необходимо следить за возможной реализацией фильтра.
  • Device Column Lengths — определяет длину колонок DSP блоков. Полезное информативное поле, в котором можно заранее определить верхнюю границу порядка фильтра и максимальное количество реализуемых фильтров.
  • Column Configuration — определяет конфигурацию и положение DSP блоков в колонках. С этим параметром нужно работать осторожно, поскольку при разрыве фильтра между несколькими колонками может возникнуть большая задержка, следовательно — упадет максимальная тактовая частота.
  • Inter-column Pipe Length — определяет количество дополнительных регистров между колонками DSP блоков для устранения негативного эффекта задержки распространения.

FIR Compiler — Вкладка 4:


Summary — эта вкладка в виде списка отражает конечные настройки фильтра (количество каналов, порядок фильтра, параметры частот, разрядность входных, выходных и промежуточных данных, разрядность коэффициентов, задержка в фильтре, количество используемых DSP блоков, наличие сигналов контроля и т.д.).

В левой части окна FIR Compiler есть три полезные дополнительные вкладки:
  • IP-symbol — схематичный вид IP-блока с активными портами ввода/вывода.
  • Freq. response — частотная характеристика FIR-фильтра.
  • Implementation Details — оценка занимаемых ресурсов DSP и RAMB, суммарная задержка, количество коэффициентов и порядок их загрузки.

Абстрактный пример


Условие
Проведем расчет широкополосного фильтра первичной обработки, обладающего следующими параметрами:
  • Частота дискретизации Fs: 250 МГц,
  • Частота среза фильтра Fpass: 55 МГц,
  • Коэффициент прямоугольности: > 0.88 (Fpass/Fstop),
  • Подавление в полосе пропускания (Apass): < 0.5 дБ,
  • Подавление в полосе затухания (Astop): > 50 дБ.
Реализовать шесть независимых каналов фильтрации на микросхеме Artix-7 XC7A100T-FGG484. Коэффициенты ИХ – перегружаемые, симметричные и независимые для каждого канала фильтра.

Решение

Шаг 1: Оценка ресурсов ПЛИС
Необходимо понять, сколько доступно ресурсов кристалла для реализации подобного фильтра. В DS180 можно найти, что микросхема имеет 240 DSP48E1 блоков, выстроенных в три колонки (это важно!). Из ТЗ известно, что ИХ – симметрична, а это значит, что для фильтра порядка N потребуется N/2 блоков DSP48E1. Следовательно, на выбранной микросхеме возможна реализация 2 фильтров с длиной характеристики N = 240, либо 6 фильтров с длиной N = 80. В практических целях при обработке сигналов длину ИХ выбирают кратному степени двойки. Например, N = 64, 128 или 256. Либо, N = (128 + 64), (32 + 16 + 8). В нашем случае необходимо реализовать 6 фильтров на 240 DSP блоках. С учетом симметрии для каждого фильтра возможно использовать длину N < 81 коэффициентов. Предположим, что для достижения параметров фильтра хватит N = 80 = 64 + 16 коэффициентов.

Шаг 2: Поиск коэффициентов фильтра

Запустим FDATool и внесем в нужные поля параметры фильтра из спецификации (помним, что порядок N задается на 1 меньше, чем истинный порядок фильтра). Режим 1 – Equiripple. Для частоты среза Fpass = 55 МГц и коэффициента прямоугольности > 0.85 найдем частоту заграждения Fstop < 62.5 МГц. На следующем рисунке представлен расчет фильтра по требуемым параметрам:


Как видно, фильтр удовлетворяет всем перечисленным требованиям.
Режим 2 – Window. Неожиданно перед самой сдачей проекта вашему заумному заказчику вбрела в дурную голову мысль. «Хочу 70 дБ подавление при прочих равных условиях!». Элементная база выбрана, плата разведена и смонтирована, ПЛИС установлена, проект отлаживался несколько месяцев и нет возможности поставить что-то переделывать. Что делать? Проектировать свой собственный КИХ фильтр за неделю до сдачи проекта? Искать другие методы подавления АЧХ? Переделывать плату и устанавливать ПЛИС пожирнее? Нереально! Главное – не паниковать. Метод Equiripple уже не спасает. Переходим к оконному режиму Window. При выборе моего любимого окна Кайзера можно добиться лучших характеристик фильтра. Например, обеспечить необходимое подавление в полосе затухания Astop = 80 дБ (параметр Beta = 8). Но для оконного метода следует учитывать, что в полосе затухания из-за недостаточной разрядности коэффициентов могут проявляться эффекты квантования.


Далее известным способом выгружаем рассчитанные коэффициенты в *.COE файл для дальнейшей работы.

Шаг 3: Реализация

Количество каналов и коэффициентов было подобрано таким образом, чтобы на 100% занять ресурсы DSP48E1 в ПЛИС. Количество занимаемых ресурсов для 6 каналов на рисунке ниже:


Не стоит пугаться, что проект не заработает на 250 МГц. Еще как заработает. PlanAhead любит перестраховываться и указывает значения ниже реальных. Результаты разводки шести каналов FIR фильтров.

Красивые рисунки разводки проекта
Схематический вид части IP-ядра FIR фильтра:


Разводки платы в FPGA Editor (Zoom нижней части):


Разводка платы в FPGA Editor:


Практические советы


Конечно, переход к Window спасает не всегда, и на практике есть несколько иных методов, которые так или иначе упростят жизнь разработчику.
  1. Заранее определить возможную децимацию сигнала (по отношению частоты дискретизации и граничной частоте в спектре сигнала). Использовать дешевые CIC-фильтры для целей децимации. После децимации возможно сократить количество используемых DSP блоков кристалла.
  2. Определить отношение частоты дискретизации и частоты обработки в кристалле ПЛИС. Если частота обработки в несколько раз превышает частоту дискретизации, можно во столько же раз сэкономить количество ресурсов на реализацию FIR фильтра.
  3. Реализовать фильтр на распределенной логике ПЛИС, если это возможно и не критично с точки зрения частот обработки. Этот метод очень сложен в реализации и не будет стабильно работать для больших порядков фильтра N.
  4. Для реализации фильтров с симметричной ИХ предварительно оценить размер колонок DSP блоков и количество этих колонок в ПЛИС. Для реализации длинных фильтров с симметричной ИХ требуется каскадное соединение DSP блоков и при размещении фильтра внутри ПЛИС в одной колонке может не хватить ячеек DSP. С другой стороны, при реализации независимых каналов фильтров, может попросту не хватить колонок, если в каждой колонке умещается только один фильтр. Придется либо уменьшать длину характеристики, либо делать два небольших фильтра с меньшим числом коэффициентов.******
  5. Для современных кристаллов ПЛИС (Altera и Xilinx) при реализации фильтра с симметричной ИХ использовать предварительный сумматор в узле DSP, а не на распределенной логике. Внутренний pre-adder значительно экономит не только логические ячейки, но и трассировочные ресурсы кристалла! *******
****** — Для Xilinx фильтр гарантированно не разведется, если фильтр с симметричной ИХ не влезает в одну колонку (в PlanAhead колонки DSP блоков выделены зеленым цветом). На Altera – не проверял. Буду рад, если кто-то поделится своими опытами.
******* — для микросхем ПЛИС фирмы Xilinx 7 серии и старше этот метод спасает только в том случае, если разрядность коэффициентов не превышает 18. Для убер-современных по состоянию на 2015-2016 г. микросхем Xilinx Ultra-Scale возможно реализовать предварительный сумматор с разрядностью коэффициентов 24.

Vivado HLS


Современные методы создания узлов задач цифровой обработки сигналов на ПЛИС сводятся к двум принципам:
  • уменьшение времени проектирования (понятие "time-to-market"),
  • уменьшение порога вхождения (популяризация ПЛИС среди С++ разработчиков).

Оба принципа возникли не случайно и происходят в первую очередь от постоянного увеличения логической емкости FPGA. Xilinx заявляет, что старые методы программирования (на языках VHDL и Verilog) уже не справляются с современными задачами, и есть большая вероятность, что в будущем программирование на ПЛИС будет вестись исключительно на языках высокого уровня типа С и С++. Xilinx несколько лет назад анонсировал новое средство проектирования под названием Vivado HLS и предлагает все большие проекты частично или полностью переводить на новый уровень. Разработка на Vivado HLS сводится к тому, что можно уйти от понятия "тактовая частота" и разрабатывать сложные алгоритмы без привязки к ПЛИС, а всю оптимизацию под ПЛИС уже делать на последней стадии проекта. Посмотрим, что можно сделать с помощью новой среды и разработаем простейший КИХ-фильтр в Vivado HLS.

В качестве примера я взял одну из лабораторных работ от Xilinx, в которой в первом приближении показана вся мощь современных средств. Основная разработка с помощью Vivado HLS базируется на взаимосвязанных задачах: написание кода и его оптимизация по скорости (Speed) и занимаемой площади (Area) с помощью директив.

Xilinx предлагает следующее поведение при проектировании:
  • – C Validation/Simulation (Project -> Run C Simulation): написание алгоритма, отладка проекта, выявление ошибок в коде, сравнение данных с эталоном и т.д.
  • – C Synthesis (Solution -> Run C Synthesis): синтез проекта из C-кода в RTL форму и анализ полученных данных: оценка производительности (latency, trip count, speed etc.), оценка ресурсов, полученный интерфейс ввода/вывода.*
  • – RTL Verification (Solution -> Run C/RTL Cosimulation): повторное использование C-модели теста main() для анализа RTL-модели (self-checking).
  • – IP Creation (Solution -> Export RTL): создание IP-ядра для дальнейшего использования в основном проекте (Xilinx ISE, Vivado и т.д)
* — Мощь Vivado HLS в создании уникальных решений (solutions), различающихся способами оптимизации. Правильный подход заключается в создании множества решений и выборе оптимального, нежели в отладке одного единственного!

Как сделать различные решения? Использовать директивы — инструмент для оптимизации проектов в Vivado HLS. Директивы можно добавлять в исходный код (Source file) или в отдельный файл директив (Directive file).
  • Source file – подходит для задания директив, которые НЕ БУДУТ меняться на протяжении создания проекта. Например, директивы для интерфейса портов I/O не меняются. В проекте эти директивы обозначаются префиксом: #HLS.
  • Directive file – подходит для задания условий и ограничений, которые влияют на оптимизацию по скорости и размещению. Как правило, в проекте можно сравнить в различных solutions несколько ограничений и выбрать оптимальное. В проекте эти директивы обозначаются префиксом: %HLS.

Приведу пример исходников для простейшего КИХ фильтра. Обратите внимание на директивы в исходном коде.

FIR Filter C++ for Vivado HLS
#include "fir.h"

void fir (
  data_t *y,
  coef_t c[N],
  data_t x
  ) {
<b>#pragma HLS</b> INTERFACE ap_ovld port=y
<b>#pragma HLS</b> INTERFACE ap_vld port=x
<b>#pragma HLS</b> RESOURCE variable=c core=RAM_1P_BRAM

  static data_t shift_reg[N];
  acc_t acc;
  data_t data;
  int i;
  
  acc=0;
  Shift_Accum_Loop: for (i=N-1;i>=0;i--) {
		if (i==0) {
			shift_reg[0]=x;
     	data = x;
    } else {
			shift_reg[i]=shift_reg[i-1];
			data = shift_reg[i];
    }
    acc+=data*c[i];;       
  }
  *y=acc;
}


Директивы в отдельном файле выглядят следующим образом:
set_directive_unroll "fir/Shift_Accum_Loop"
set_directive_array_partition -type complete -dim 1 "fir" shift_reg

Замечание: В процессе оптимизации разработчику часто приходится сравнивать различные результаты по производительности и ресурсам. Поэтому зачастую большая часть директив записывается в отдельный файл. Если разработчик уверен, что конкретная оптимизация нужна для всех решений, то её можно занести в исходные тексты!

Для проекта FIR создадим три разных решения:
  • без использования директив (синтезатор использует минимум ресурсов — последовательная обработка данных),
  • с использованием директив для портов (синтезатор оптимизирует интерфейс ввода/вывода),
  • с использованием директивы UNROLL (для разворачивания цикла FOR и параллельной обработки каждой итерации цикла).

В результате синтеза в Vivado можно провести полный анализ по занимаемым ресурсам и максимальной производительности, увидеть интерфейс портов ввода/вывода для создаваемого ядра. Кроме того, можно увидеть, как исполняются те или иные функции, сколько ресурсов они занимают и сколько тактов выполняются.

Сравнение трех решений:


Результаты синтеза проекта в Vivado HLS
Директивы:


Вкладка Performance:


Вкладка Resources:


  • Чтение порта x и запись порта y происходит за один такт. Чтение порта c за два такта, потому что он описан как интерфейс памяти RAM;
  • Используется два умножителя;
  • Сдвиговый регистр shift_reg используется для операции чтения и записи;
  • Остальные ресурсы не используются совместно, потому что существуют в единственном виде (в выражениях в коде).

Ресурсы кристалла:


Процесс создания нового проекта и все шаги проектирования описывать не буду, поскольку статья и так уже разрослась до небывалых размеров. Но если вам интересна тема использования Vivado HLS в своих проектах – я с удовольствием поделюсь своим опытом. Также можно воспользоваться помощью хабраюзера urock. В этом деле он мастер!

Заключение


На этом хотелось бы подвести итог. В статье рассмотрены базовые принципы создания КИХ фильтров на ПЛИС. Общие выводы по статье:
  • КИХ фильтры — линейные нерекурсивные фильтры, достаточно просты в реализации на современных FPGA и процессорах.
  • Порядок фильтра = длина импульсной характеристики = количество коэффициентов = количество линий задержки.
  • Могут иметь точную линейную фазовую характеристику, постоянные групповую и фазовую задержки.
  • Для линейной фазовой характеристики требуются симметричные коэффициенты фильтра.
  • Не забывайте про эффект Гиббса при расчете коэффициентов фильтра.
  • При расчете коэффициентов пользуйтесь современными средствами и не изобретайте велосипед
  • Если длина фильтра N превышает разумные пределы (например, больше 512), используйте алгоритм быстрой свертки через двойное БПФ.
  • Разработка фильтра разбивается на несколько взаимосвязанных стадий.
  • Используйте метод оконных функций для реализации частотных характеристик с хорошими параметрами.
  • Учитывайте особенности выбранного кристалла ПЛИС для минимизации занимаемых ресурсов.
  • Длина фильтра влияет на прямоугольность, а разрядность коэффициентов на подавление в полосе затухания.
  • Существует множество методов разработки КИХ фильтров на ПЛИС. Выбирайте тот, который покажется проще.

Полезные видео
Altera FIR Design:


Xilinx HLS FIR Design 1:


Xilinx HLS FIR Design 2:


Литература
  1. Статья на хабре
  2. Статья на DSPLIB
  3. Altera FIR Compiler
  4. Xilinx FIR Compiler
  5. Xilinx DSP48E1 (7 Series)
  6. Xilinx DSP48E2 (Ultra-Scale)
  7. Wikipedia FIR
  8. Parks-McClellan algorithm
  9. MATLAB Tutorial 1
  10. MATLAB Tutorial 2
  11. OpenCores FIR 1
  12. OpenCores FIR 2
  13. OpenCores FIR 3

Продолжение следует...
На какие темы вы бы хотели видеть статьи в будущем?

Проголосовало 36 человек. Воздержавшихся нет.

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Капитанов Александр @capitanov
карма
43,0
рейтинг 26,4
Инженер-разработчик на FPGA
Самое читаемое Разработка

Комментарии (0)

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.