У меня есть высокоскоростной АЦП, подключенный к FPGA. АЦП разработан таким образом, что вы получаете 16 выборок за каждый такт FPGA (это выборки, а не биты). 16 выборок взяты из одного входного канала АЦП, они просто собираются с течением времени и отправляются как 1 большой фрагмент (samp[0] — самая ранняя выборка во времени, samp[15] — самая поздняя во времени выборка).
Мне нужно спроектировать полосовой фильтр для параллельного потока, но цифровые реализации, которые я нашел в Интернете, всегда предполагают, что у меня есть одна выборка за такт (одна выборка помещается в структуру фильтра, одна выборка выходит из структуры фильтра). Я не могу просто создать внутренние часы, которые в 16 раз быстрее, так как эта высокая частота будет слишком быстрой для FPGA. Мне нужно иметь возможность его фильтровать, но каждый такт я отправляю 16 сэмплов и вывожу 16 отфильтрованных сэмплов.
Может ли кто-нибудь помочь мне начать? Как будет называться такой фильтр? Есть ли какой-то математический трюк, когда я могу просто построить 16 параллельных цифровых фильтров, а затем выполнить некоторую математическую магию на выходе (прореживание во временном фильтре?)
Должна быть возможность развернуть это, но для этого потребуется 64 * 16 = 1024 операций MAC за такт. Подумайте об этом так:
y[n] = a0 * x[n] + a1 * x[n-1] + ... + a63 * x[n-63]
Это операция фильтра, которую вам нужно сделать. Давайте немного упростим это и рассмотрим только первые 3 термина:
y[n] = a0 * x[n] + a1 * x[n-1] + a2 * x[n-2]
Каждый -1 - это один тактовый цикл задержки. Если вы получаете один термин за такт, вы можете реализовать это напрямую с 3 множителями и тремя регистрами для хранения значений x. Однако, если вы получаете два значения x за такт, вам также необходимо получить два значения y за такт. В этом случае вам нужно сделать что-то вроде этого, предполагая, что ваши входные значения равны x[2n] и x[2n+1]:
y[2n] = a0 * x[2n] + a1 * x[2n+1-2] + a2 * x[2n-2]
y[2n+1] = a0 * x[2n+1] + a1 * x[2n] + a2 * x[2n+1-2]
И вы можете продолжить это для большего количества входных данных:
y[3n] = a0 * x[3n] + a1 * x[3n+2-3] + a2 * x[3n+1-3]
y[3n+1] = a0 * x[3n+1] + a1 * x[3n] + a2 * x[3n+2-3]
y[3n+2] = a0 * x[3n+2] + a1 * x[3n+1] + a2 * x[3n]
Обратите внимание, что в этом случае каждый тактовый цикл задержки НЕ является задержкой, равной 1, поэтому я переписал термины как сумму исходного термина и задержки. Так, например, 2n перемещается в 2n-2 в следующем цикле, а 2n+1 переходит в 2n+1-2 в следующем цикле. Вы можете масштабировать этот шаблон до того, что вам нужно, однако я бы рекомендовал использовать скрипт Python или аналогичный для создания вашего HDL, поскольку это было бы кошмаром для реализации вручную.
В общем, вам понадобятся параллельные операции MAC подсчета выборок * длины фильтра. Обратите внимание, что в некоторых случаях может быть возможно выполнить две операции MAC в одном DSP-срезе, если он имеет предварительный сумматор и ваш список коэффициентов фильтра имеет симметрию, которую вы можете использовать. Так что, если вы используете современный чип Xilinx, это может быть возможно реализовать в 512 слайсах DSP.
Редактировать: Вот еще один вариант, который немного сумасшедший, но на него, возможно, стоит обратить внимание. Можно построить КИХ-фильтр без использования каких-либо срезов DSP, который все еще достаточно быстр — он называется распределенным арифметическим фильтром. Компромисс заключается в том, что для ширины коэффициента в M бит требуется M тактовых циклов для вычисления следующей выборки. Вы уже выполняете 16 выборок параллельно, возможно, стоит попробовать распределённую арифметическую реализацию с 16*M параллельно. 16-битные сэмплы * 16 сэмплов — это только 256 параллельных реализаций DA-фильтра. Я мало занимался распределенной арифметикой, поэтому не уверен, насколько хорошо она масштабируется, но это еще один возможный способ реализации вашего фильтра. Я не уверен, какую ПЛИС вы используете, но вполне возможно, что вы выиграли.
Мэтт Янг
Энди ака
Пэббельс
пользователь 2913869
пользователь 2913869
Пэббельс
Алекс Форенчич
ФархадА