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

И все равно надо что-то написать
А как же )) Мы, злостные флудеры, такие ))) Расслабьтесь. Мы же сюда заходим не только работать, но и отдохнуть от работы. Лёгкий флуд - терпимо.

 

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


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

А как же )) Мы, злостные флудеры, такие ))) Расслабьтесь. Мы же сюда заходим не только работать, но и отдохнуть от работы. Лёгкий флуд - терпимо.

 

Ах...вот оно что?!

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


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

Уважаемые форумчане :biggrin: Возникли трудности, прошу по возможности помощи.

Речь о БПФ, если кто не в курсе.

1. Бабочка по основанию 2

2. 16 точек

3. Частота дискретизации 5 МГц

4. Прореживание во времени

5. Соответственно 8 коэффициентов

6. Реализация на ПЛИС (verilog).

7. Моделирую в Modelsim

8. Пытаюсь :smile3046: проверить работу алгоритма в Mathlab

________________________________________________________________________________

_

Я построил свою работу следующим образом:

1. Используя описание 16-ти точечного БПФ в Матлаб рассчитал коэфициенты и подставил удобные для себя входные отсчеты. В итоге построил график post-74498-1435300703_thumb.png, на котором увидел ожидаемую для себя картинку при входных отсчетах

ss = [828 1515 1943 2038 1784 1225 457 -390 -1170 -1750 -2030 -1963 -1560 -890 -68 0];

и коэффициентах

w0 = (1+0i);
w1 = (0.9239-0.3827i);
w2 = (0.7071-0.7071i);
w3 = (0.3827-0.9239i);
w4 = (0-1i);
w5 = (-0.3827-0.9239i);
w6 = (-0.7071-0.7071i);
w7 = (-0.9239-0.3827i);

 

2. После этого зная из Матлаб результаты всех вычислений я переместился в Modelsim и начал там тестировать свой БПФ описанный на Verilog. В качестве входных значений я использовал те же, что и в Матлаб представленных в дополнительном коде. т.е. мантисса занимает биты с 0 по 10, а 11 бит знаковый в итоге диапазон входных значений от -2047 до +2047.

С коэффициентами иначе. Та как коэффициенты у меня меняются от -1 до +1, тогда я их домножил на все те же 2047 и округлил, 11 битом прикрепил знак. В итоге мои коэффициенты стали иметь вид:

w0 = 2047 + 0i;
w1 = 1891-783i;
w2 = 1447-1447i;
w3 = 783-1891i;
w4 = 0-2047i;
w5 = -783-1891i;
w6 = -1447 - 1447i;
w7= -1891-783i;

 

3. И тут я как "умная Маша" :smile3046: попытался засунуть округленные коэффициенты в целочисленной форме в Матлаб. В итоге у меня на выходе ерунда вместо прежней картинки.

И я не понимаю почему????

Нужно что-то менять в матлаб? Просто мне никак не проверить корректность работы БПФ описанного verilog. Хочется иметь одни и те же коэффициенты и в Матлаб и в Моделсим.

 

Привожу код БПФ из Матлаб

 

 

ss = [828 1515 1943 2038 1784 1225 457 -390 -1170 -1750 -2030 -1963 -1560 -890 -68 0];
%k2 = [0:7];
%W2 = exp( -j*2*pi.*k2/16 );
w11 = (1+0i);
w12 = (0.9239-0.3827i);
w13 = (0.7071-0.7071i);
w14 = (0.3827-0.9239i);
w15 = (0-1i);
w16 = (-0.3827-0.9239i);
w17 = (-0.7071-0.7071i);
w18 = (-0.9239-0.3827i);

W2 = [ w11 w12 w13 w14 w15 w16 w17 w18];
s2r = [ss(1) ss(9) ss(5) ss(13) ss(3) ss(11) ss(7) ss(15) ss(2) ss(10) ss(6) ss(14) ss(4) ss(12) ss(8) ss(16)];

%первый шаг 
s11 = s2r(1) + s2r(2);
s12 = s2r(1) - s2r(2);
s13 = s2r(3) + s2r(4);
s14 = s2r(3) - s2r(4);
s15 = s2r(5) + s2r(6);
s16 = s2r(5) - s2r(6);
s17 = s2r(7) + s2r(8);
s18 = s2r(7) - s2r(8);
s19 = s2r(9) + s2r(10);
s110= s2r(9) - s2r(10);
s111= s2r(11)+ s2r(12);
s112= s2r(11)- s2r(12);
s113= s2r(13)+ s2r(14);
s114= s2r(13)- s2r(14);
s115= s2r(15)+ s2r(16);
s116= s2r(15)- s2r(16);


%второй шаг 

s21 = s11 + s13* W2(1);
s22 = s12 + s14* W2(5);
s23 = s11 - s13* W2(1);
s24 = s12 - s14* W2(5);

s25 = s15 + s17* W2(1);
s26 = s16 + s18* W2(5);
s27 = s15 - s17* W2(1);
s28 = s16 - s18* W2(5);

s29 = s19 + s111* W2(1);
s210 = s110 + s112*W2(5);
s211 = s19 - s111* W2(1);
s212 = s110 - s112*W2(5);

s213 = s113 + s115*W2(1);
s214 = s114 + s116*W2(5);
s215 = s113 - s115*W2(1);
s216 = s114 - s116*W2(5);

%шаг 3
s31 = s21 +  s25*W2(1);
s32 = s22 +  s26*W2(3);
s33 = s23 +  s27*W2(5);
s34 = s24 +  s28*W2(7);
s35 = s21 -  s25*W2(1);
s36 = s22 -  s26*W2(3);
s37 = s23 -  s27*W2(5);
s38 = s24 -  s28*W2(7);

s39 = s29 +  s213*W2(1);
s310= s210 + s214*W2(3);
s311= s211 + s215*W2(5);
s312= s212 + s216*W2(7);
s313 = s29 - s213*W2(1);
s314= s210 - s214*W2(3);
s315= s211 - s215*W2(5);
s316= s212 - s216*W2(7);

%шаг 4

s41 = s31 + s39*W2(1);
s42 = s32 + s310*W2(2);
s43 = s33 + s311*W2(3);
s44 = s34 + s312*W2(4);
s45 = s35 + s313*W2(5);
s46 = s36 + s314*W2(6);
s47 = s37 + s315*W2(7);
s48 = s38 + s316*W2(8);

s49 = s31 - s39*W2(1);
s410 = s32 - s310*W2(2);
s411 = s33 - s311*W2(3);
s412 = s34 - s312*W2(4);
s413 = s35 - s313*W2(5);
s414 = s36 - s314*W2(6);
s415 = s37 - s315*W2(7);
s416 = s38 - s316*W2(8);

%Строим график

x = [0 : 15];
y = [s41, s42, s43, s44, s45, s46, s47, s48, s49, s410, s411, s412, s413,s414, s415, s416];
plot (x, y)

 

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


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

Предполагаю, что вы напутали со знаковой математикой. Verilog, в отличие от С, считает переменные без знаковыми, покуда не укажете обратное.

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


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

К счастью, в доп.коде операции делаются идентично, поэтому указание знака необязательно. Лично я ставлю reg signed или wire signed только для того, чтобы в симуляторе наблюдать сразу знаковые значения.

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


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

Да, в матлабе посчитаю и в mif засуну.

Quartus поддерживает инструкцию $readmemh для блочного ROM в Verilog. Вообще не надо париться с написанием. Забил reg. Прописал $readmemh в initial.

 

К счастью, в доп.коде операции делаются идентично, поэтому указание знака необязательно. Лично я ставлю reg signed или wire signed только для того, чтобы в симуляторе наблюдать сразу знаковые значения.

Ничего подобного. При умножении надо указывать $signed иначе будет непредсказуемая ерунда, даже если указана знаковая переменная.

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


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

Пока тема свежая, задамка вопрос по БПФ.

 

Вот написал я свое ядро бпф.

Работает оно так, что подаю на вход N точек, оно N*log(N) тактов рассчитает результат.

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

А вот у альтеры и ксайлинка ip-ядра способны принимать новые кадры без пауз.

Как это у них реализовано?

 

Самый дубовый вариант - буферизировать входные данные. Но размер буфера будет определяться величиной log(N), а у альтеры/ксайлинкса не наблюдается, чтобы ядро требовало больше памяти, чем под один кадр.

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


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

Пока тема свежая, задамка вопрос по БПФ.

 

Вот написал я свое ядро бпф.

Работает оно так, что подаю на вход N точек, оно N*log(N) тактов рассчитает результат.

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

А вот у альтеры и ксайлинка ip-ядра способны принимать новые кадры без пауз.

Как это у них реализовано?

 

Самый дубовый вариант - буферизировать входные данные. Но размер буфера будет определяться величиной log(N), а у альтеры/ксайлинкса не наблюдается, чтобы ядро требовало больше памяти, чем под один кадр.

Вообще-то обычный Радикс-2/4 работает именно кадрами. Накапление->вычисление->выдача результата(накопление). Есть ещё по-моему потоковый алгоритм у них, но только на небольшое число точек и с большим ресурсом..

В своё время делал FFT - при разумной полосе спектра сигнала(скажем до 50 МГц) вполне хватает буфера на N точек.

1. Ядро вполне реально разогнать до максимальной частоты BRAM/DSP - смотря что меньше. Пусть будет 500. А это сразу даёт 10 тактов вычисления на 1 такт данных.

2. Первую бабочку можно сделать сразу в момент прихода второй половины входных отсчётов, так как там коэффициенты только единицы.

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

Всё это конечно усложняет реализацию, но бывают случаи, когда это меньшее из зол.

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


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

Погонял модель бпф от альтеры и в сигналтапе на железе посмотрел. Потоком кадры друг за дружкой засылаю, на выходе результат также потоком выходит, без разрывов. Как же они это реализовали?

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


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

Бегло читаем документ.

 

Находим в нем "The variable streaming FFTs implement either a radix-2^2 single delay feedback FFT, ..."

 

Ищем гуглом "sdf fft" или "r4sdf fft", или "r2sdf fft"

 

Погонял модель бпф от альтеры и в сигналтапе на железе посмотрел. Потоком кадры друг за дружкой засылаю, на выходе результат также потоком выходит, без разрывов. Как же они это реализовали?

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


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

 

Пока тема свежая, задамка вопрос по БПФ.

 

Вот написал я свое ядро бпф.

Работает оно так, что подаю на вход N точек, оно N*log(N) тактов рассчитает результат.

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

А вот у альтеры и ксайлинка ip-ядра способны принимать новые кадры без пауз.

Как это у них реализовано?

 

Самый дубовый вариант - буферизировать входные данные. Но размер буфера будет определяться величиной log(N), а у альтеры/ксайлинкса не наблюдается, чтобы ядро требовало больше памяти, чем под один кадр.

Самый дубовый вариант, это поставить N блоков БПФ и коммутировать поотсчетно, подавая их на входы со сдвигом на отсчет. А у Altera и Xilinx используется БПФ со сдвигом не на отсчет, а на 1/2... 1/4 размера блока. По сути, имеется 2... 4 БПФ блока. В результате, на выходе почти отсутствуют разрывы фазы. Но такое преобразование годится не для всех видов модуляции. Иногда приходится делать перекрытие еще меньше 1/4.

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

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


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

Самый дубовый вариант, это поставить N блоков БПФ и коммутировать поотсчетно, подавая их на входы со сдвигом на отсчет. А у Altera и Xilinx используется БПФ со сдвигом не на отсчет, а на 1/2... 1/4 размера блока. По сути, имеется 2... 4 БПФ блока. В результате, на выходе почти отсутствуют разрывы фазы. Но такое преобразование годится не для всех видов модуляции. Иногда приходится делать перекрытие еще меньше 1/4.

По поводу поточного БПФ - все достаточно просто. Описано в соответствующих букварях. Небольшая заметка по этому поводу для ПЛИС http://acvarif.info/prvhdl/prvhdl25.html Такой метод довольно ресурсозатратный, но при наличии в ПЛИС аппаратных умножителей все работает неплохо.

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


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

Ничего подобного. При умножении надо указывать $signed иначе будет непредсказуемая ерунда, даже если указана знаковая переменная.
Для сложения - без разницы. А для умножения - согласен, могут быть нюансы. И то, у Xilinx реализован аппаратный умножитель чисел дополнительного кода, так что это для него нативно.

 

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


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

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

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

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

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

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

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

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

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

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