vLx0F 0 16 октября, 2007 Опубликовано 16 октября, 2007 (изменено) · Жалоба Имею на входе АЦП 16-битные отсчёты, которае нужно пропустить через FIR. Как подобрать величину коэфф., чтоб фильтр не улетал в насыщение? Например, в маслабе получаю типа: 0.01, 0.3, 0.018 и т.д. Так как их согласовать с моими входными отсчётами. Не на 2^15 домножать ? Изменено 16 октября, 2007 пользователем vLx0F Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rloc 56 16 октября, 2007 Опубликовано 16 октября, 2007 · Жалоба Имею на входе АЦП 16-битные отсчёты, которае нужно пропустить через FIR. Как подобрать величину коэфф., чтоб фильтр не улетал в насыщение? Например, в маслабе получаю типа: 0.01, 0.3, 0.018 и т.д. Так как их согласовать с моими входными отсчётами. Не на 2^15 домножать ? Как правило все FIR'ры в FPGA работают с целочисленной арифметикой, так что домножать Вам все равно придется. Для получения максимального динамического диапазона, нужно умножить на такую константу, чтобы максимальный по модулю коэффициент точно вписался в разрядную сетку. При расчете в Матлабе, общий коэффициент усиления фильтра получается равным 1, поэтому если Вы хотите сохранить этот коэффициент, нужно после фильтра поделить данные на ту же константу (операция называется scale). Проще всего, как Вы правильно заметили, это можно сделать если домножать и делить на 2^N. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vLx0F 0 16 октября, 2007 Опубликовано 16 октября, 2007 · Жалоба нужно после фильтра поделить данные на ту же константу (операция называется scale). Проще всего, как Вы правильно заметили, это можно сделать если домножать и делить на 2^N. У меня так: АЦП - 16 бит, знаковый, т.е. амплитуда - +-2^15 допустим +-0.5В. Значит и коэффициенты домнажаю на 2^15. Умножители у меня 18x18 SPARTAN3, т.е. результат умножения - 36 бит, по-этому всем данным и коэфф. нужно сделать RESIZE (Vhdl). Скольлько битным выбрать аккумулятор, чтоб переполнения не было ? Или скайлинг всёравно придёться делать ? Вопрос: после каждого умножения, чтоб переполнения аккумулятора не было ? Или достаточно после каждого суммирования ? И последнее - на скока скайлинг делать сдвиг вправо на 15 ? shift_right(acc,15) ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rloc 56 16 октября, 2007 Опубликовано 16 октября, 2007 · Жалоба У меня так: АЦП - 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) разрядов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vLx0F 0 16 октября, 2007 Опубликовано 16 октября, 2007 (изменено) · Жалоба В лучшем случае аккумулятор нужно брать разрядностью не менее 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 ? Изменено 16 октября, 2007 пользователем vLx0F Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vLx0F 0 17 октября, 2007 Опубликовано 17 октября, 2007 · Жалоба Это понятно, т.е. для моего случая 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); ??? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rloc 56 17 октября, 2007 Опубликовано 17 октября, 2007 · Жалоба Это понятно, т.е. для моего случая 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). Напоследок напоминаю, что данные необходимо округлять, а не отсекать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vLx0F 0 17 октября, 2007 Опубликовано 17 октября, 2007 (изменено) · Жалоба Если необходим переменный 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 бит. Как прально это сделать ? Да и ещё поясните пожалуйста, что значит "данные надо округлять а не отсекать" ? Разницу для процов я понимаю, а вот для ПЛИС ,,, Изменено 17 октября, 2007 пользователем vLx0F Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ataradov 0 17 октября, 2007 Опубликовано 17 октября, 2007 · Жалоба Нужно взять старшие разряды, кроме самого старшего. Два старших разряда будут всегда содержать знак результата. То-есть нужно взять разряды [34:17]. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rloc 56 17 октября, 2007 Опубликовано 17 октября, 2007 · Жалоба Спасибо за ответ, но, если взять просто умножитель 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 и отсекаете этот младший бит. Делать это надо на выходе фильтра, используя, скажем, дополнительный сумматор. Сам аккумулятор нужно постараться сделать с достаточно большой разрядностью, чтобы можно было не округлять, подаваемые на него данные. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_b 16 17 октября, 2007 Опубликовано 17 октября, 2007 · Жалоба Нужно взять старшие разряды, кроме самого старшего. Два старших разряда будут всегда содержать знак результата. Это будет всегда, кроме одного случая: когда перемножаются два минимальных числа. Если один из множителей никогда не принимает своего мимнимально возможного значения, то таки да, два старших разряда будут одинаковы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rloc 56 17 октября, 2007 Опубликовано 17 октября, 2007 · Жалоба Это будет всегда, кроме одного случая: когда перемножаются два минимальных числа. Если один из множителей никогда не принимает своего мимнимально возможного значения, то таки да, два старших разряда будут одинаковы. Какую-то ерунду Вы пишите. 1*(-1) = -1 два старших разряда = 1 1*1 = 1 два старших разряда = 0 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vLx0F 0 17 октября, 2007 Опубликовано 17 октября, 2007 · Жалоба Если данные 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 бит ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rloc 56 17 октября, 2007 Опубликовано 17 октября, 2007 · Жалоба Ещё вопросик: если реально входные данные у меня 16-битные, но расширенные до 18 (для умножителя), то, например, результат (значимый) их умножения считать 32-битным, хотя он будет по сути 36 битным. И во всех приведённых Вами формулах для рассчёта выборки бит (с аккк или умножителя) входные данные иметь ввиду 16 бит ? Из умножителя 18x18 можно сделать умножитель любой разрядности, хоть 2*3 (в меньшую сторону по разрядности конечно), и как Вы думаете значимыми будут 36 бит? Как ни старайтесь, но разрядность на выходе не получите больше, чем Nвход+Nкоэфф (значимую). Может не стоит FIR на FPGA городить, раз такие сложности? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_b 16 17 октября, 2007 Опубликовано 17 октября, 2007 · Жалоба Какую-то ерунду Вы пишите. Внимательно перечитайте то, что вы обозвали ерундой. Пусть имеем два знаковых, для простоты трехразрядных, числа. Разрядность произведения - 3+3=6 разрядов. А мы хотим 5. Но хотеть не вредно... Минимальное трехразрядное число --- это (-4) (100 в двоичной форме). Произведение (-4)*(-4)=16. В двоичном виде знаковое 16 имеет вид 010000, т.е. 6 разрядов, как и положено. И где здесь два одинаковых старших разряда, я вас внимательно спрашиваю? :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться