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

Реализация БПФ на ПЛИС

Господа,так ведь же есть уже готовые БПФ ядра и у Xilinx, и у Altera. Лично пользуюсь Xilinx ядром, вроде, не плохо получается. В своем проекте мы вешаем на вход АЦП и потоком гоняем 1024 точки.

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


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

В данном случае преследуются учебные цели. Понятно, что для работы, если есть готовое IP и, к тому же, бесплатно, то глупо им не воспользоваться. Но для ПЛИС довольно много полезных и бесплатных IP, вроде БПФ, включено в состав средств разработки, а если ASIC надо делать? Увы, для ASIC IP задорма никто не дает. Я вот, однажды делал БПФ для ASIC. Там нужна была небольшая постобработка результатов их анализ и формирование выборок из спектра по заданным критериям - большую чать этого довеска удалось встроить прямо в последнюю стадию БПФ и задействовав вычислительные ресурсы самого БПФ. Получился существенный выигрыш и по быстродействию и площадь здорово сэкономили. С покупным IP так удачно не получилось бы.

 

В общем, надо пользоваться готовым IP там, где это можно, но хороший инженер должен уметь реализовать это IP и сам.

 

Так что я очень поддерживаю желание ZEDa собрать свой собственный "велосипед" свомим руками.

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


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

Ну я так и имел ввиду:

 

signal A : std_logic_vector(n-1 downto 0);
signal B : std_logic_vector(n-1 downto 0);
signal SUM_buf : std_logic_vector(n downto 0);
signal SUM : std_logic_vector(n downto 0);

SUM_buf <= resize(A, n+1) -  resize(B, n+1) + '1'
SUM <= SUM_buf(n downto 1);

 

resize расширяет число знаковым разрядом, соответственно при сложении/вычитании 4 отсчетов resize(OTSCHOT, n+2), а потом отбрасываем.

 

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

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


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

Теперь мне не очень понятно, поняли ли Вы меня правильно. :)

 

Код

 

signal A : std_logic_vector(n-1 downto 0);
signal B : std_logic_vector(n-1 downto 0);
signal SUM_buf : std_logic_vector(n downto 0);
signal SUM : std_logic_vector(n-1 downto 0);

SUM_buf <= resize(A, n+1) -  resize(B, n+1) + '1'
SUM <= SUM_buf(n downto 1);

 

в случае A = (2^n)-1 и B = -(2^n) даст неверный результат.

 

Вы симулировать пробовали? Если да, то выложите полный проект, чтобы было видно как именно Вы это делали. Если нет, то просимулируйте... и выложите полный проект, чтобы было видно как именно Вы это делали :)

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

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


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

Чего-то не симулируется, квартус лагает, вот проект:

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;

entity summator is
    generic (b_size: natural := 16
             );
    
    port(A: in std_logic_vector(b_size - 1 downto 0);
         B: in std_logic_vector(b_size - 1 downto 0); 
         SUM: out std_logic_vector(b_size - 1 downto 0)
        );
end entity summator;


architecture beh_summator of summator is

signal A_sig : std_logic_vector(b_size downto 0);
signal B_sig : std_logic_vector(b_size downto 0);
signal SUM_buf : std_logic_vector(b_size downto 0);

begin
A_sig <= (0 => A(b_size-1)) & A;
B_sig <= (0 => B(b_size-1)) & B;
SUM_buf <= A_sig - B_sig + '1';
SUM <= SUM_buf(b_size downto 1);

end beh_summator;

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


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

Что значит не симулируется? Под проектом я понимаю все квартусовские файлы.

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


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

Что значит не симулируется?

Временная диаграмма не работает - выдает одни иксы: XXXXXXX и т.д. Что-то с Квартусом или компом, я его стабильно раз в неделю переставляю. А может и я что-то не так делаю...

Проект прикрепляю.

summator.rar

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


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

:biggrin: Вы просто не тот файл смотрите. Результаты симуляции лежат в каталоге db\ и называется файл summator.sim.vwf. Вообще-то этот файл Квартус Вам должен был сам показать по окончании симуляции в одном из окон репорта. Если Вы в этом файле измените формат отображения для SUM с Binary на Signed Decimal, то Вы увидите, что результат = -32768, что неверно.

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


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

Временная диаграмма не работает - выдает одни иксы: XXXXXXX и т.д. Что-то с Квартусом или компом, я его стабильно раз в неделю переставляю. А может и я что-то не так делаю...

Проект прикрепляю.

 

Если я что то и переставляю, так это новую версию Квартуса. Чего и вам желаю.

А выдавать неопределенности (при функционале) он может, если только галочка не стоит на опции Overwrite.....

Иначе cмотрите в опции report.

Что касается Вашего сумматора, ничего сказать не могу. Потому что текст не понимаю (понятно только, что он не правильно работает. А в своих библиотеках сами копайтесь.

 

 

:biggrin: Вы просто не тот файл смотрите. Результаты симуляции лежат в каталоге db\ и называется файл summator.sim.vwf. Вообще-то этот файл Квартус Вам должен был сам показать по окончании симуляции в одном из окон репорта. Если Вы в этом файле измените формат отображения для SUM с Binary на Signed Decimal, то Вы увидите, что результат = -32768, что неверно.

 

Интересно, в каком семестре мы подойдем к изучению умножителей.

Иль дайте есть, иль ешьте сами.

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


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

Если я что то и переставляю, так это новую версию Квартуса. Чего и вам желаю.

А выдавать неопределенности (при функционале) он может, если только галочка не стоит на опции Overwrite.....

Иначе cмотрите в опции report.

Что касается Вашего сумматора, ничего сказать не могу. Потому что текст не понимаю (понятно только, что он не правильно работает. А в своих библиотеках сами копайтесь.

 

Интересно, в каком семестре мы подойдем к изучению умножителей.

Иль дайте есть, иль ешьте сами.

 

А можно поинтересоваться, с чего вдруг вы тут это "ляпнули"? Как-то очень не впопад :)

 

Что касается Вашего сумматора, ничего сказать не могу. Потому что текст не понимаю (понятно только, что он не правильно работает. А в своих библиотеках сами копайтесь.

 

Не понимаю, чего Вы так възелись на сумматор? Не хотите, не разбирайтесь - я же от Вас этого не требую... и даже не прошу этого делать! :)

 

Интересно, в каком семестре мы подойдем к изучению умножителей.

 

Мне интересно, а Вам-то какая разница? Да, с бабочкой (точнее с ее вычитателями) несколько затянулось, но ведь задача стоит разобраться, а не как можно скорее получить код БПФ.

 

Иль дайте есть, иль ешьте сами.

 

Что Вы имеете ввиду?

 

--------- Для всех кто читает эту тему ----------

 

Еще раз повторяю, эта тема преследует исключительно учебные цели.

 

Я буду искренне благодарен тем, кто может дополнить написанное чем-то полезным, но...

 

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

 

 

 

Вот, что у меня получилось:

 

Теперь Вам понятно, почему при (A+B +1) >> 1 результат всегда занимает столько же разрядов, сколько операнды, а при (A-B+1) >> 1 результат может потребовать для хранения на один разряд больше, чем сами операнды?

 

На всякий случай привожу правильный код вычитателя.

 

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;

entity subtractor is
generic (b_size: natural := 16
		 );

port(A: in std_logic_vector(b_size - 1 downto 0);
	 B: in std_logic_vector(b_size - 1 downto 0); 
	 SUM: out std_logic_vector(b_size downto 0)
	);
end entity subtractor;


architecture beh_subtractor of subtractor is

signal A_sig : std_logic_vector(b_size + 1 downto 0);
signal B_sig : std_logic_vector(b_size + 1 downto 0);
signal SUM_buf : std_logic_vector(b_size + 1 downto 0);

begin
A_sig <= (1 downto 0 => A(b_size-1)) & A;
B_sig <= (1 downto 0 => B(b_size-1)) & B;
SUM_buf <= A_sig - B_sig + '1';
SUM <= SUM_buf(b_size + 1 downto 1);

end beh_subtractor;

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

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


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

Да, но результат суммирования теперь увеличился на один разряд, я так понимаю, что полное окуругление мы произведем после умножения?

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


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

Все-таки, Вы не поняли. :(

 

Округление мы уже произвели. Собственно, из-за него и приходится увеличить разрадность сигнала для хранения результата на 1.

 

Вы в каком городе живете?

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


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

В Москве.

Просто вы писали:

В случае (A+B+C+D)/4 с округлением (т.е. (A+B+C+D+2) >> 2) мы можем (и делаем) объявить внутри бабочки сигналы A_ B_ C_ D_ с разрядностью на 2 больше, чем A,B,C,D. Складываем их, прибавляем 2 (для округления) и отбросываем 2 младших разряда (т.е. /4). В этом случае, выполнив все необходимые операции, мы снова возвращаемся к разрядности такой же как и у A,B,C,D. У нас на входе разрядность n, внутри бабочки разрядность n+2, а на выходе опять n. И при этом мы нигде ничего не реряем.

Т.е. на выходе бабочки должна быть разрядность такая как и на входе.

 

Но тут же вы писали:

Но при наличие вычитания и желания проделать операции с округлением результата мы в некоторых случаях сможем получить результат (именно конечный результат), для представления которого нам не хватит разрядности такой же как и у входных данных - нам потребуется на один разряд больше. (см пример в пред. сообщении) Т.е. выход будет на один разряд больше ==> выход умножителей придется сделать на 1 разряд больше ==> разрядность памяти придется увеличить на 1 разряд ==> вход бабочки тоже увеличится на 1 разряд - круг замкнулся т.к. наши данные во время вычисления БПФ "гуляют" по кругу.

 

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

 

И возникает вопрос стоит ли округление таких затрат?

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


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

Видимо, словами "круг замкнулся" я Вас запутал.

 

Разрядность бабочки у нас не будет увеличиваться на каждом этапе.

 

Я пытался объяснить, что при наличие вычитания в операциях бабочки с округлением потребует от нас повсеместного (т.е. в каждом блоке, но не на каждом этапе ! ) увеличения разрядности на 1 поскольку диапазон значений данных с АЦП от -32768 до +32767, а при вычислениях БПФ диапазон результатов будет от -32768 до +32768 ( независимо от этапа). Такой диапазон чисел для представления требует не 16, а 17 разрядов.

 

Забегая вперед, кроме бабочки, в умножителе, когда -32768 Вы умножите на -1.0, то получите +32768 - это число для представления требует опять таки 17 разрядов (как видите, даже если убрать округление в бабочке, то нам все равно не избежать этой проблемы в умножителях).

 

Из-за этого нам нужно либо исключить число -32768 из входного потока данных с АЦП (тогда при любых вычислениях БПФ мы никогда не получим +32768 - т.е. будем всегда иметь диапазон от -32767 до +32767) либо сделать 17-ти разрядные шины данных, чтобы по ним можно было бы "гонять" +32768.

 

Надеюсь, теперь все встало на свои места.

 

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

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

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


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

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

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

Гость
Ответить в этой теме...

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

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

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

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

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

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