Перейти к содержанию
    

Подбор коэффициентов к FIR

Имею на входе АЦП 16-битные отсчёты, которае нужно пропустить через FIR. Как подобрать величину коэфф., чтоб фильтр не улетал в насыщение? Например, в маслабе получаю типа: 0.01, 0.3, 0.018 и т.д. Так как их согласовать с моими входными отсчётами. Не на 2^15 домножать ?

Изменено пользователем vLx0F

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Имею на входе АЦП 16-битные отсчёты, которае нужно пропустить через FIR. Как подобрать величину коэфф., чтоб фильтр не улетал в насыщение? Например, в маслабе получаю типа: 0.01, 0.3, 0.018 и т.д. Так как их согласовать с моими входными отсчётами. Не на 2^15 домножать ?

Как правило все FIR'ры в FPGA работают с целочисленной арифметикой, так что домножать Вам все равно придется. Для получения максимального динамического диапазона, нужно умножить на такую константу, чтобы максимальный по модулю коэффициент точно вписался в разрядную сетку. При расчете в Матлабе, общий коэффициент усиления фильтра получается равным 1, поэтому если Вы хотите сохранить этот коэффициент, нужно после фильтра поделить данные на ту же константу (операция называется scale). Проще всего, как Вы правильно заметили, это можно сделать если домножать и делить на 2^N.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

нужно после фильтра поделить данные на ту же константу (операция называется scale). Проще всего, как Вы правильно заметили, это можно сделать если домножать и делить на 2^N.

 

У меня так: АЦП - 16 бит, знаковый, т.е. амплитуда - +-2^15 допустим +-0.5В. Значит и коэффициенты домнажаю на 2^15. Умножители у меня 18x18 SPARTAN3, т.е. результат умножения - 36 бит, по-этому всем данным и коэфф. нужно сделать RESIZE (Vhdl). Скольлько битным выбрать аккумулятор, чтоб переполнения не было ? Или скайлинг всёравно придёться делать ? Вопрос: после каждого умножения, чтоб переполнения аккумулятора не было ? Или достаточно после каждого суммирования ?

И последнее - на скока скайлинг делать сдвиг вправо на 15 ? shift_right(acc,15) ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У меня так: АЦП - 16 бит, знаковый, т.е. амплитуда - +-2^15 допустим +-0.5В. Значит и коэффициенты домнажаю на 2^15. Умножители у меня 18x18 SPARTAN3, т.е. результат умножения - 36 бит, по-этому всем данным и коэфф. нужно сделать RESIZE (Vhdl). Скольлько битным выбрать аккумулятор, чтоб переполнения не было ? Или скайлинг всёравно придёться делать ? Вопрос: после каждого умножения, чтоб переполнения аккумулятора не было ? Или достаточно после каждого суммирования ?

И последнее - на скока скайлинг делать сдвиг вправо на 15 ? shift_right(acc,15) ?

Ну если Вы только определяетесь с разрядностью аккумулятора, то разрядность коэффициентов желательно брать не меньше разрядности данных. В лучшем случае аккумулятор нужно брать разрядностью не менее Nданные+Nкоэфф+log2(Ntaps), Ntaps - порядок фильтра (соответственно с умножителя брать Nданные+Nкоэфф разрядов). После каждого суммирования ничего округлять или отсекать не надо. Если хотите немного сократить разрядность аккумулятора, то можно с умножителя брать немного меньше разрядов, например в самом худшем случае Nвыход+log2(Ntaps) разрядов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В лучшем случае аккумулятор нужно брать разрядностью не менее Nданные+Nкоэфф+log2(Ntaps), Ntaps - порядок фильтра (соответственно с умножителя брать Nданные+Nкоэфф разрядов).

Это понятно, т.е. для моего случая 18+18+log2(64)=42 (Nданные+Nкоэфф+log2(Ntaps)). Меня эта цифра - вполне. Но вот дальше мне надо преобразовать аккумулятор опять в 16 бит. Как правильно это сделать ? Сдвигать придёться ?

 

Ещё вы писали:

"поэтому если Вы хотите сохранить этот коэффициент, нужно после фильтра поделить данные на ту же константу (операция называется scale). Проще всего, как Вы правильно заметили, это можно сделать если домножать и делить на 2^N."

Т.е., как я понял, в конце придёться сдвинуть акк на N (в моём случае 15)., т.к. домножил коэффициенты на 2^15, ну и отсчёты тоже какбы домножены на 2^15 ?

Изменено пользователем vLx0F

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это понятно, т.е. для моего случая 18+18+log2(64)=42 (Nданные+Nкоэфф+log2(Ntaps)). Меня эта цифра - вполне. Но вот дальше мне надо преобразовать аккумулятор опять в 16 бит. Как правильно это сделать ? Сдвигать придёться ?

 

Ещё вы писали:

"поэтому если Вы хотите сохранить этот коэффициент, нужно после фильтра поделить данные на ту же константу (операция называется scale). Проще всего, как Вы правильно заметили, это можно сделать если домножать и делить на 2^N."

Т.е., как я понял, в конце придёться сдвинуть акк на N (в моём случае 15)., т.к. домножил коэффициенты на 2^15, ну и отсчёты тоже какбы домножены на 2^15 ?

 

В общем вопрос свёлся к следующему: при умножителе, например, 18x18 получим результат 36 бит. И вот как правильно получить из него (результата) опять 18 бит ?

Может a18 <= std_logic_vector(shift_right(signed(a36), 18)(17 downto 0); ???

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это понятно, т.е. для моего случая 18+18+log2(64)=42 (Nданные+Nкоэфф+log2(Ntaps)). Меня эта цифра - вполне. Но вот дальше мне надо преобразовать аккумулятор опять в 16 бит. Как правильно это сделать ? Сдвигать придёться ?

 

Ещё вы писали:

"поэтому если Вы хотите сохранить этот коэффициент, нужно после фильтра поделить данные на ту же константу (операция называется scale). Проще всего, как Вы правильно заметили, это можно сделать если домножать и делить на 2^N."

Т.е., как я понял, в конце придёться сдвинуть акк на N (в моём случае 15)., т.к. домножил коэффициенты на 2^15, ну и отсчёты тоже какбы домножены на 2^15 ?

Если необходим переменный scale, то нужно сдвигать или мультиплексировать (как кому удобнее). Если scale фиксированный, то проще взять с аккумулятора нужные разряды, а какие именно сейчас попробую объяснить.

Допустим Вы домножали свои коэффициенты на 2^N, и после такого домножения получилось, что коэффициенты вписались в 16-разрядную сетку. Предположим, что входные данные - 18 бит, выходные - 20 бит (я специально взял разное количество разрядов). Тогда после умножителя необходимо брать 18+16 разрядов и подавать на аккумулятор разрядностью 18+16+log2(64)=18+16+6=40 (нужную разрядность получаем дополнением). С выхода этого аккумулятора необходимо снимать разряды с 16+(N-16)-(20-18) по 16+(N-16)+18-1.

Если быть более точным, то дополнительная разрядность аккумулятора должна быть не log2(64), а N-16 (не стоит забывать, что я предполагал коэффициент усиления фильтра, полученный в Матлабе или какой-либо другой программе, равным 1).

Напоследок напоминаю, что данные необходимо округлять, а не отсекать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если необходим переменный scale, то нужно сдвигать или мультиплексировать (как кому удобнее). Если scale фиксированный, то проще взять с аккумулятора нужные разряды, а какие именно сейчас попробую объяснить.

Допустим Вы домножали свои коэффициенты на 2^N, и после такого домножения получилось, что коэффициенты вписались в 16-разрядную сетку. Предположим, что входные данные - 18 бит, выходные - 20 бит (я специально взял разное количество разрядов). Тогда после умножителя необходимо брать 18+16 разрядов и подавать на аккумулятор разрядностью 18+16+log2(64)=18+16+6=40 (нужную разрядность получаем дополнением). С выхода этого аккумулятора необходимо снимать разряды с 16+(N-16)-(20-18) по 16+(N-16)+18-1.

Если быть более точным, то дополнительная разрядность аккумулятора должна быть не log2(64), а N-16 (не стоит забывать, что я предполагал коэффициент усиления фильтра, полученный в Матлабе или какой-либо другой программе, равным 1).

Напоследок напоминаю, что данные необходимо округлять, а не отсекать.

 

Спасибо за ответ, но, если взять просто умножитель 18x18 (без всяких аккумуляторов), в котором 16-бит данные расширены до 18 и 16-бит коэф (умноженные на 2 ^15) тож до 18. На выходе получим 36 бит и нужно забрать 18 бит. Как прально это сделать ?

Да и ещё поясните пожалуйста, что значит "данные надо округлять а не отсекать" ? Разницу для процов я понимаю, а вот для ПЛИС ,,,

Изменено пользователем vLx0F

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нужно взять старшие разряды, кроме самого старшего. Два старших разряда будут всегда содержать знак результата.

 

То-есть нужно взять разряды [34:17].

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо за ответ, но, если взять просто умножитель 18x18 (без всяких аккумуляторов), в котором 16-бит данные расширены до 18 и 16-бит коэф (умноженные на 2 ^15) тож до 18. На выходе получим 36 бит и нужно забрать 18 бит. Как прально это сделать ?

Если данные 16 бит, и на выходе Вы хотите получить 18 бит, то можно поступить двумя путями:

1) дополнить 16 бит недостающими 2 разрядами, т.е. D(17)=D(16)=D(15), где D(15) - это старший бит (MSB) данных, а после перемножения взять биты с 36-18-2 по 36-2-1

2) сдвинуть 16 бит на 2 в сторону старших бит, а младшие 2 бита обнулить, после перемножения взять биты с 36-18 по 36-1, т.е. старшие 18 бит.

Да и ещё поясните пожалуйста, что значит "данные надо округлять а не отсекать" ? Разницу для процов я понимаю, а вот для ПЛИС ,,,

В самом простом случае нужно к вашему числу добавить +0.5 и отсечь лишние биты (и для положительных и для отрицательных чисел). Поясняю на примере: если нужно получить 18 бит, то сначала берете на один младший бит больше, т.е. 19 бит, добавляете 1 и отсекаете этот младший бит. Делать это надо на выходе фильтра, используя, скажем, дополнительный сумматор. Сам аккумулятор нужно постараться сделать с достаточно большой разрядностью, чтобы можно было не округлять, подаваемые на него данные.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нужно взять старшие разряды, кроме самого старшего. Два старших разряда будут всегда содержать знак результата.

Это будет всегда, кроме одного случая: когда перемножаются два минимальных числа. Если один из множителей никогда не принимает своего мимнимально возможного значения, то таки да, два старших разряда будут одинаковы.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это будет всегда, кроме одного случая: когда перемножаются два минимальных числа. Если один из множителей никогда не принимает своего мимнимально возможного значения, то таки да, два старших разряда будут одинаковы.

Какую-то ерунду Вы пишите.

1*(-1) = -1 два старших разряда = 1

1*1 = 1 два старших разряда = 0

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если данные 16 бит, и на выходе Вы хотите получить 18 бит, то можно поступить двумя путями:

1) дополнить 16 бит недостающими 2 разрядами, т.е. D(17)=D(16)=D(15), где D(15) - это старший бит (MSB) данных, а после перемножения взять биты с 36-18-2 по 36-2-1

2) сдвинуть 16 бит на 2 в сторону старших бит, а младшие 2 бита обнулить, после перемножения взять биты с 36-18 по 36-1, т.е. старшие 18 бит.

 

Ещё вопросик: если реально входные данные у меня 16-битные, но расширенные до 18 (для умножителя), то, например, результат (значимый) их умножения считать 32-битным, хотя он будет по сути 36 битным. И во всех приведённых Вами формулах для рассчёта выборки бит (с аккк или умножителя) входные данные иметь ввиду 16 бит ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ещё вопросик: если реально входные данные у меня 16-битные, но расширенные до 18 (для умножителя), то, например, результат (значимый) их умножения считать 32-битным, хотя он будет по сути 36 битным. И во всех приведённых Вами формулах для рассчёта выборки бит (с аккк или умножителя) входные данные иметь ввиду 16 бит ?

Из умножителя 18x18 можно сделать умножитель любой разрядности, хоть 2*3 (в меньшую сторону по разрядности конечно), и как Вы думаете значимыми будут 36 бит? Как ни старайтесь, но разрядность на выходе не получите больше, чем Nвход+Nкоэфф (значимую).

Может не стоит FIR на FPGA городить, раз такие сложности?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Какую-то ерунду Вы пишите.

Внимательно перечитайте то, что вы обозвали ерундой.

 

Пусть имеем два знаковых, для простоты трехразрядных, числа. Разрядность произведения - 3+3=6 разрядов. А мы хотим 5. Но хотеть не вредно...

Минимальное трехразрядное число --- это (-4) (100 в двоичной форме). Произведение (-4)*(-4)=16. В двоичном виде знаковое 16 имеет вид 010000, т.е. 6 разрядов, как и положено. И где здесь два одинаковых старших разряда, я вас внимательно спрашиваю? :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...