реклама на сайте
подробности

 
 
23 страниц V  « < 18 19 20 21 22 > »   
Reply to this topicStart new topic
> Реализация БПФ на ПЛИС, Тудности, встречаемые при реализации
Sefo
сообщение Nov 29 2010, 10:50
Сообщение #286


Местный
***

Группа: Свой
Сообщений: 429
Регистрация: 11-08-05
Из: Санкт-Петербург
Пользователь №: 7 537



Цитата(Jhonny. @ Nov 28 2010, 11:44) *
Необходимо реализовать преобразователь на 1152, 1024, 704 и 448 отсчетов, при этом длина должна выбираться динамически. Возможно ли сделать такой универсальный преобразователь или лучше сделать четыре отдельных с фиксированной длиной?


Можно сделать универсальный. Наличие разнородных бабочек, безусловно, усложняет реализацию, но структура вычислений остается постоянной. Рекомендую посмотреть книжку Л. Рабинер и Б. Гоулд "Теория и применение цифровой обработки сигналов". На странице 418 есть пример 30-ти точечного БПФ, состоящего из 5-ти, 3-х и 2-х точечных бабочек. Сравнив структуру с 32-х точечны БПФ на стр. 420 или 64-х точечного БПФ на стр. 646 Вы увидите, насколько все одинаково по структуре. Поэтому я бы реализовывал универсальный преобразователь.

Цитата(ZED @ Nov 11 2010, 16:00) *
В архиве единственная непустая папка RTL, где хранятся vhdl-файлы описания компонентов бабочки, памяти и файл констант FFT_Package.
Мне пока не очень понятна целесообразность введения всех этих функций.


Целесообразность введения всех этих функций в том, что во-первых это учебный проект и, думаю, многим начинающим будет интересно посмотреть пример использования функций и атрибутов в VHDL. Во-вторых, есть основные операции и, так скажем, вспомогательные - расширение знаком, к примеру. Когда вспомогательная операция требует несколько строк кода не отличающегося читаемостью, из которого не всегда очевидно, что производится какая-то элементарная операция вроде расширения знаком:
Код
x_sig(0).re <= (1 downto 0 => x(0).re(b_size-1)) & x(0).re;
x_sig(0).im <= (1 downto 0 => x(0).im(b_size-1)) & x(0).im;
x_sig(1).re <= (1 downto 0 => x(1).re(b_size-1)) & x(1).re;
x_sig(1).im <= (1 downto 0 => x(1).im(b_size-1)) & x(1).im;
x_sig(2).re <= (1 downto 0 => x(2).re(b_size-1)) & x(2).re;
x_sig(2).im <= (1 downto 0 => x(2).im(b_size-1)) & x(2).im;
x_sig(3).re <= (1 downto 0 => x(3).re(b_size-1)) & x(3).re;
x_sig(3).im <= (1 downto 0 => x(3).im(b_size-1)) & x(3).im;


я предпочитаю не полениться и написать пару функций чтобы не засорять код:

Код
D := expand_sign(D_i);


Функции не сложные, но зато универсальные - не зависят от разрядности и размерности complex_data_bus. Захотите, например, 8-ми точечную бабочку и придется еще 8 строк добавлять чтобы знаком расширить, а с функциями вспомогательные выражения (да и сами функции) редактировать не придется - только основной код нужно будет поменять.

Получается более читаемый код, особенно для тех кто его не писал. Читающий первый раз имеет возможность не вдаваться во второстепенные подробности. Выражение D := expand_sign(D_i) понятно и без комментариев. Если назначение функции не совсем ясно, то можно ограничится чтением комментариев к ней не вдаваясь в подробности реализации.

Что касается пустоты папок, так я только начал их наполнять. За столь медленный темп извиняюсь, но быстрее, пока никак не получается. Сначала я доработаю код, затем начнем наполнять папку Modelsim.
Go to the top of the page
 
+Quote Post
ZED
сообщение Nov 29 2010, 13:42
Сообщение #287


Местный
***

Группа: Свой
Сообщений: 264
Регистрация: 17-04-07
Из: Москва
Пользователь №: 27 102



Цитата
Наличие разнородных бабочек, безусловно, усложняет реализацию, но структура вычислений остается постоянной.

Вычисление 30-ти точечного БПФ, состоящего из 5-ти, 3-х и 2-х точечных бабочек отличается от вычисления 32-х точечного БПФ. По всей видимости для каждого из БПФ (на 1152, 1024, 704 и 448 отсчетов) придется писать свою управляшку, и подключать ее в зависимости от размерности БПФ, а это не очень удобно мне кажется. Ну и подключение бабочек разной размерности.
Go to the top of the page
 
+Quote Post
Sefo
сообщение Nov 29 2010, 20:58
Сообщение #288


Местный
***

Группа: Свой
Сообщений: 429
Регистрация: 11-08-05
Из: Санкт-Петербург
Пользователь №: 7 537



Цитата(ZED @ Nov 29 2010, 16:42) *
Вычисление 30-ти точечного БПФ, состоящего из 5-ти, 3-х и 2-х точечных бабочек отличается от вычисления 32-х точечного БПФ.


Но структура и принцип "соединения" бабочек остается одинаковым.

Цитата(ZED @ Nov 29 2010, 16:42) *
По всей видимости для каждого из БПФ (на 1152, 1024, 704 и 448 отсчетов) придется писать свою управляшку, и подключать ее в зависимости от размерности БПФ, а это не очень удобно мне кажется.


Бабочки все равно придется делать всех типов - от этого не уйти.

Но вот с универсальным управлением как раз особых проблем быть не должно - просто когда появляется 3-х точечная бабочка, то пропадает кратность степеням двойки и вычисления в блоке управления придется делать "честным" образом.

Основная проблема с нечетными бабочками заключается в организации памяти, но эта проблема существует и при реализации нескольких вариантов БПФ под свое кол-во точек. Так что лучше уж решить эту проблему в общем виде и получить одно БПФ для разного кол-ва точек.

Go to the top of the page
 
+Quote Post
Jhonny.
сообщение Nov 30 2010, 10:28
Сообщение #289


Участник
*

Группа: Участник
Сообщений: 15
Регистрация: 23-11-08
Пользователь №: 41 876



Спасибо за ответыsmile.gif.
То, что принцип соединения бабочек одинаков, интуитивно понятно. Вызывает затруднение количество разнородных бабочек. Для чисел 1152, 1024, 704, 448 я выделил 2-х, 3-х, 4-х, 7-ми и 11-ти точечные бабочки.

Цитата(Sefo @ Nov 30 2010, 02:58) *
Но вот с универсальным управлением как раз особых проблем быть не должно - просто когда появляется 3-х точечная бабочка, то пропадает кратность степеням двойки и вычисления в блоке управления придется делать "честным" образом.

Это значит, обходиться без хитрых сдвигов и маскирований?

Цитата(Sefo @ Nov 30 2010, 02:58) *
Основная проблема с нечетными бабочками заключается в организации памяти, но эта проблема существует и при реализации нескольких вариантов БПФ под свое кол-во точек. Так что лучше уж решить эту проблему в общем виде и получить одно БПФ для разного кол-ва точек.


Насколько общим должен быть вид? Ведь от конкретного числа точек зависят количество этапов и применяемые бабочки?

И еще, все сказанное Вами относится к БПФ типа пинг-понг (разрабатываемого в этой теме)? У Рабинера, Гоулда написано про поточный метод, мне показалось, там проще организация памяти.
Go to the top of the page
 
+Quote Post
Sefo
сообщение Nov 30 2010, 16:57
Сообщение #290


Местный
***

Группа: Свой
Сообщений: 429
Регистрация: 11-08-05
Из: Санкт-Петербург
Пользователь №: 7 537



Цитата(Jhonny. @ Nov 30 2010, 13:28) *
Спасибо за ответыsmile.gif.
То, что принцип соединения бабочек одинаков, интуитивно понятно. Вызывает затруднение количество разнородных бабочек. Для чисел 1152, 1024, 704, 448 я выделил 2-х, 3-х, 4-х, 7-ми и 11-ти точечные бабочки.


Я бы 2-х точечную бабочку из списка исключил бы - она неэффективная. Лучше 5-ти точечную добавить - при наличии 7-ми и 11-ти точечных она уже погоды не сделает.

Цитата(Jhonny. @ Nov 30 2010, 13:28) *
И еще, все сказанное Вами относится к БПФ типа пинг-понг (разрабатываемого в этой теме)? У Рабинера, Гоулда написано про поточный метод, мне показалось, там проще организация памяти.


Все сказанное относится к подавляющему большинству реализаций БПФ.

Поточный метод у Рабинера и Гоулда не для современного железа - сильно устаревший и по ресурсам жутко неэффективный. К тому же легко реализуем только если на всех этапах одинаковые бабочки (ну или хотя бы с кратным числом точек). В общем, решите реализовать поточный метод - ищите современные примеры.

Цитата(Jhonny. @ Nov 30 2010, 13:28) *
Это значит, обходиться без хитрых сдвигов и маскирований?


Угу.

Цитата(Jhonny. @ Nov 30 2010, 13:28) *
Насколько общим должен быть вид? Ведь от конкретного числа точек зависят количество этапов и применяемые бабочки?

Что касается памяти, то все зависит от того как вы собираетесь реализовать БПФ. От самого по себе числа точек и количества этапов ничего не зависит. Вопрос лишь в том, какие бабочки на этом этапе и какие на следующем. Если они одинаковые или кратные (2 и 4, например), то все просто. Если бабочка будет получать точки на вход по очереди, то проблем нет никаких, но крайне медленно. Если подавать все точки сразу, что весьма эффективно, то надо память разбивать на банки и писать/читать туда/оттуда так, чтобы для каждой бабочки все точки находились в разных банках. А это уже не так просто в вашем случае.


Нужно сначала определиться с ресурсами и быстродействием и исходя из этого думать какие методы реализации подойдут.
Go to the top of the page
 
+Quote Post
Sefo
сообщение Jan 4 2011, 21:48
Сообщение #291


Местный
***

Группа: Свой
Сообщений: 429
Регистрация: 11-08-05
Из: Санкт-Петербург
Пользователь №: 7 537



Вот "причесанный" код нашего БПФ (\RTL). Так же прилагается Квартусовский проект. Проект пока формальный – т.е. он компилируется, но это еще ничего не значит, кроме отсутствия синтаксических ошибок. В качестве микросхемы стоит Cyclone III, что не принципиально. Для компиляции один файл (\Quartus\FPGA_RTL\Coef_Memory_Bank.vhd) требует поддержки VHDL-2008 т.к использует unconstrained array of string. При отсутствии соответствующей версии Квартуса можно воспользоваться несколько кривоватым приемом подходящим для более ранних стандартов VHDL, описанным в комментариях (код так же приведен). Файлы \Quartus\FPGA_RTL\ROM_*.mif для инициализации ROM коэффициентов взяты из проекта ZED и содержат просто sin и cos, что неправильно.

Следующим этапом – моделирование и исправление багов. Пока я готовлю соответствующие файлы просьба ZEDу сгенерировать mif-файлы с правильным набором коэффициентов.

Прикрепленный файл  FFT_Project.rar ( 29.72 килобайт ) Кол-во скачиваний: 207
Go to the top of the page
 
+Quote Post
ZED
сообщение Jan 11 2011, 04:14
Сообщение #292


Местный
***

Группа: Свой
Сообщений: 264
Регистрация: 17-04-07
Из: Москва
Пользователь №: 27 102



Вот коэффициенты ROM_x.mif плюс файл Matlab для их генерации. Надеюсь ничего не напутал.
Прикрепленные файлы
Прикрепленный файл  FFT_Coefficients.rar ( 10.51 килобайт ) Кол-во скачиваний: 86
 
Go to the top of the page
 
+Quote Post
Sefo
сообщение Jan 20 2011, 20:29
Сообщение #293


Местный
***

Группа: Свой
Сообщений: 429
Регистрация: 11-08-05
Из: Санкт-Петербург
Пользователь №: 7 537



Цитата(ZED @ Jan 11 2011, 07:14) *
Вот коэффициенты ROM_x.mif плюс файл Matlab для их генерации. Надеюсь ничего не напутал.


Увы sm.gif напутали. Придется Вам пролистать эту тему и найти то место, где обсуждалось как правильно рассчитать коэффициенты. Вкратце проблема следующая:

В арифметике с фиксированной точкой Вы берете за 1 некое число Х. Если нужно посчитать чему равно 0.3 от некоего числа D, то делаем так
1) предвычисляем целочисленный коэффициент Y = round(0.3 * X), соответствующий 0.3.
2) R = Y * D
3) Q = R / X

Если X выбран так, что не является степенью 2, то на шаге 3 нужно выполнять честное деление, а если X = 2^n, то Q = R >> n.

В умножителях на поворачивающие коэффициенты у нас нет деления - у нас сдвиг.

Так что вспоминайте как мы собирались вычислять коэффициенты.
Go to the top of the page
 
+Quote Post
ZED
сообщение Jan 24 2011, 12:09
Сообщение #294


Местный
***

Группа: Свой
Сообщений: 264
Регистрация: 17-04-07
Из: Москва
Пользователь №: 27 102



А ну да, коэффициенты у нас лежат в диапазоне от -1024 до 1024.
Прикрепленные файлы
Прикрепленный файл  FFT_Coefficients.rar ( 10.16 килобайт ) Кол-во скачиваний: 109
 
Go to the top of the page
 
+Quote Post
Jhonny.
сообщение Jan 29 2011, 10:54
Сообщение #295


Участник
*

Группа: Участник
Сообщений: 15
Регистрация: 23-11-08
Пользователь №: 41 876



Попытался оптимизировать бабочку, убрав повторяющиеся операции. Вот что получилось:

Код
architecture RTL of Butterfly is
    
    signal D : complex_data_p2_bus;

    signal add01_re : std_logic_vector(fft_data'high + 2 downto 0);
    signal add01_im : std_logic_vector(fft_data'high + 2 downto 0);
    signal add23_re : std_logic_vector(fft_data'high + 2 downto 0);
    signal add23_im : std_logic_vector(fft_data'high + 2 downto 0);

    signal sub01_re : std_logic_vector(fft_data'high + 2 downto 0);
    signal sub01_im : std_logic_vector(fft_data'high + 2 downto 0);
    signal sub23_re : std_logic_vector(fft_data'high + 2 downto 0);
    signal sub23_im : std_logic_vector(fft_data'high + 2 downto 0);

    signal sub01    : std_logic_vector(fft_data'high + 2 downto 0);
    signal sub02    : std_logic_vector(fft_data'high + 2 downto 0);
    signal sub13    : std_logic_vector(fft_data'high + 2 downto 0);

begin

    D <= expand_sign(D_i);

    add01_re <= D(0).re + D(1).re + 1;
    add01_im <= D(0).im + D(1).im + 1;

    sub01_re <= D(0).re - D(1).re + 1;
    sub01_im <= D(0).im - D(1).im + 1;

    add23_re <= D(2).re + D(3).re + 1;
    add23_im <= D(2).im + D(3).im + 1;

    sub23_re <= D(2).re - D(3).re + 1;
    sub23_im <= D(2).im - D(3).im + 1;

    sub01    <= D(0).re - D(1).im;
    sub02    <= D(0).im - D(2).im;
    sub13    <= D(1).re - D(3).re;
                
    process (CLK)    
    variable Y: complex_data_p2_bus;
    begin
            
        if rising_edge(CLK) then
            if RESETsn = '0' then                
                Y_ro <= (others => (re => (others => '0'), im => (others => '0')));
            else    
                if (MODE_i = Butterfly_4_Point) then
                    Y(0).re := add01_re + add23_re;
                    Y(0).im := add01_im + add23_im;

                    Y(1).re := sub01 - D(2).re - D(3).im + 2;
                    Y(1).im := sub02 - sub13 + 2;                                    
              
                    Y(2).re := sub01_re + sub23_re;
                    Y(2).im := sub01_im + sub23_im;

                    Y(3).re := sub01 - D(2).re + D(3).im + 2;
                    Y(3).im := sub02 + sub13 + 2;                                  
                              
                    Y_ro <= get_msb(Y, 0);
                else
                    Y(0).re := add01_re;
                    Y(0).im := add01_im;
              
                    Y(1).re := sub01_re;
                    Y(1).im := sub01_im;
                    
                    Y(2).re := add23_re;
                    Y(2).im := add23_im;
              
                    Y(3).re := sub23_re;
                    Y(3).im := sub23_im;
              
                    Y_ro <= get_msb(Y, 1);
                end if;                            
            end if;
        end if;
    
    end process;
end RTL;


Синтезировал в Xilinx ISE 12.3, до этого было
18-bit adder : 6
18-bit subtractor : 2
19-bit adder : 19
19-bit subtractor :11
После стало так 19-bit adder : 18, 19-bit subtractor :10.

Имеет ли право на жизнь такая реализация, или есть другие варианты оптимизации?
Go to the top of the page
 
+Quote Post
chirik
сообщение Aug 3 2011, 14:52
Сообщение #296


Частый гость
**

Группа: Участник
Сообщений: 129
Регистрация: 29-10-09
Из: Карелии
Пользователь №: 53 301



Добрый день!
Я разбираюсь с БПФ и не могу понять, как на практике вычисляются поворачивающий множитель W ?, в книжках написано W= e^(-j*2*p*n*k/N), k- номер отсчета, N- длина последовательности, n- текущий номер, толи я не те книжки читаю(
Go to the top of the page
 
+Quote Post
ZED
сообщение Aug 4 2011, 05:14
Сообщение #297


Местный
***

Группа: Свой
Сообщений: 264
Регистрация: 17-04-07
Из: Москва
Пользователь №: 27 102



Цитата
Добрый день!
Я разбираюсь с БПФ и не могу понять, как на практике вычисляются поворачивающий множитель W ?, в книжках написано W= e^(-j*2*p*n*k/N), k- номер отсчета, N- длина последовательности, n- текущий номер, толи я не те книжки читаю(


Все правильно. Вы читаете именно те книжки.
Go to the top of the page
 
+Quote Post
chirik
сообщение Aug 4 2011, 12:42
Сообщение #298


Частый гость
**

Группа: Участник
Сообщений: 129
Регистрация: 29-10-09
Из: Карелии
Пользователь №: 53 301



Почитав еще литературы стало яснее, что как правило, коэффициенты вычисляются заранее и хранятся в ОЗУ, или их можно через синусы посчитать W= cos(2*p*k/N) - j*sin(2*p*k/N).
Go to the top of the page
 
+Quote Post
Костян
сообщение Sep 28 2011, 13:26
Сообщение #299


Знающий
****

Группа: Свой
Сообщений: 740
Регистрация: 24-07-06
Из: Minsk
Пользователь №: 19 059



Почему для W используется разрядность всего 12 бит , тогда как данные 17 ?
Из каких соображений разрядность W взята меньше, чем входных данных ?
Go to the top of the page
 
+Quote Post
almost
сообщение Sep 29 2011, 08:18
Сообщение #300


Частый гость
**

Группа: Свой
Сообщений: 199
Регистрация: 27-05-09
Из: Москва
Пользователь №: 49 648



Цитата(Костян @ Sep 28 2011, 17:26) *
Почему для W используется разрядность всего 12 бит , тогда как данные 17 ?
Из каких соображений разрядность W взята меньше, чем входных данных ?


По всей видимости, чтобы за грубить результаты вычислений, при этом экономя память.
Go to the top of the page
 
+Quote Post

23 страниц V  « < 18 19 20 21 22 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 15:01
Рейтинг@Mail.ru


Страница сгенерированна за 0.01528 секунд с 7
ELECTRONIX ©2004-2016