Jump to content
    

FFT8 синтезируемый VHDL код

Все... ФИНИШ...

Да, я этого ожидал. Про j - это я неудачно спросил. j (мнимая еденица) это (упрощенно) корень из -1

С комплексными числами я знаком. Операции с ними повторю http://mathprofi.ru/kompleksnye_chisla_dlya_chainikov.html

С многоканальным КИХ было все проще (нет понятия комплексное число), хотя мне кажется там код посложнее чем fft8.

Пока основное чем я туплю - алгоритм (прореживание по времени) fft8 для FPGA.

Если имеются два массива данных типа xr(0)...xr(7) xi(0)...xi(7) (вещественные и мнимые части 8-ми выборок)

какие арифметические действия в FPGA нужно с ними проделать хотя-бы на первом этапе (4 двухточечных бабочки), чтобы дальше все шло правильно?

 

А.. врубился. Бабочку можно сделать так.

Допустим выходы бабчки x0_1(0) и x1_1(1). На вход подается x(0) = xr(0) + j*xi(0) и x(4) = xr(4) + j*xi(4)

На выходах будет

x0_1(0) = (xr(0) + xr(4)) + j*(xi(0) + xi(4))*W0

x1_1(1) = (xr(0) + xr(4)) - j*(xi(0) + xi(4))*W0

Если это так, то тогда можно и код накатать...

Edited by Acvarif

Share this post


Link to post
Share on other sites

Код fft8. Далее будет в виде компонента для fft32.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_SIGNED.ALL;

entity fft8ct is
Generic (
	-- размерность входных данных
	nb : natural := 16
	);
Port (
	-- тактовая частота
	clk : in std_logic;
	-- общий сброс
	rst	: in std_logic;
	-- входные данные реал
	dinr0	: in std_logic_vector(nb-1 downto 0);
	dinr1	: in std_logic_vector(nb-1 downto 0);
	dinr2	: in std_logic_vector(nb-1 downto 0);
	dinr3	: in std_logic_vector(nb-1 downto 0);
	dinr4	: in std_logic_vector(nb-1 downto 0);
	dinr5	: in std_logic_vector(nb-1 downto 0);
	dinr6	: in std_logic_vector(nb-1 downto 0);
	dinr7	: in std_logic_vector(nb-1 downto 0);
	-- входные данные мним
	dini0	: in std_logic_vector(nb-1 downto 0);
	dini1	: in std_logic_vector(nb-1 downto 0);
	dini2	: in std_logic_vector(nb-1 downto 0);
	dini3	: in std_logic_vector(nb-1 downto 0);
	dini4	: in std_logic_vector(nb-1 downto 0);
	dini5	: in std_logic_vector(nb-1 downto 0);
	dini6	: in std_logic_vector(nb-1 downto 0);
	dini7	: in std_logic_vector(nb-1 downto 0);
	-- импульс записи данных 
	wrdata	: in std_logic;
	-- счетчик стадий
	ctfin		: in std_logic_vector(4 downto 0);
	-- разрешение начала преобразований
	begpr 	: in std_logic;

	-- выход счетчика стадий 
	ctfout	: out std_logic_vector(4 downto 0);
	-- выходы данных реал
	doutr0	: out std_logic_vector(nb-1 downto 0);
	doutr1	: out std_logic_vector(nb-1 downto 0);
	doutr2	: out std_logic_vector(nb-1 downto 0);
	doutr3	: out std_logic_vector(nb-1 downto 0);
	doutr4	: out std_logic_vector(nb-1 downto 0);
	doutr5	: out std_logic_vector(nb-1 downto 0);
	doutr6	: out std_logic_vector(nb-1 downto 0);
	doutr7	: out std_logic_vector(nb-1 downto 0);
	-- выходы данных мним
	douti0	: out std_logic_vector(nb-1 downto 0);
	douti1	: out std_logic_vector(nb-1 downto 0);
	douti2	: out std_logic_vector(nb-1 downto 0);
	douti3	: out std_logic_vector(nb-1 downto 0);
	douti4	: out std_logic_vector(nb-1 downto 0);
	douti5	: out std_logic_vector(nb-1 downto 0);
	douti6	: out std_logic_vector(nb-1 downto 0);
	douti7	: out std_logic_vector(nb-1 downto 0)
	);
end fft8ct;

architecture behavioural of fft8ct is
attribute multstyle : string;
-- на базе логики
attribute multstyle of behavioural : architecture is "logic";
-- на базе встроенных умножителей
--attribute multstyle of behavioural : architecture is "dsp";

signal s_ctf : std_logic_vector(4 downto 0);

-- буферные сигналы реал
subtype sdbr is std_logic_vector(nb-1 downto 0);
type memory_sdbr is array(7 downto 0) of sdbr;
signal s_dbr : memory_sdbr;

-- буферные сигналы мним
subtype sdbi is std_logic_vector(nb-1 downto 0);
type memory_sdbi is array(7 downto 0) of sdbi;
signal s_dbi : memory_sdbi;

-- сигналы реал 1_й стади
subtype str1 is std_logic_vector(nb-1 downto 0);
type memory_str1 is array(7 downto 0) of str1;
signal s_str1 : memory_str1;

-- сигналы мним 1_й стади
subtype sti1 is std_logic_vector(nb-1 downto 0);
type memory_sti1 is array(7 downto 0) of sti1;
signal s_sti1 : memory_sti1;

-- сигналы реал 2_й стади
subtype str2 is std_logic_vector(nb-1 downto 0);
type memory_str2 is array(7 downto 0) of str2;
signal s_str2 : memory_str2;

-- сигналы мним 2_й стади
subtype sti2 is std_logic_vector(nb-1 downto 0);
type memory_sti2 is array(7 downto 0) of sti2;
signal s_sti2 : memory_sti2;

-- сигналы 3_й стади
subtype str3 is std_logic_vector(nb-1 downto 0);
type memory_str3 is array(7 downto 0) of str3;
signal s_str3 : memory_str3;

subtype sti3 is std_logic_vector(nb-1 downto 0);
type memory_sti3 is array(7 downto 0) of sti3;
signal s_sti3 : memory_sti3;

-- промежуточные int реал сигналы 1_я стадия
subtype str1_int is integer range -8192 to 8191;
type memory_str1_int is array(7 downto 0) of str1_int;
signal s_str1_int : memory_str1_int;

-- промежуточные int мним сигналы 1_я стадия
subtype sti1_int is integer range -8192 to 8191;
type memory_sti1_int is array(7 downto 0) of sti1_int;
signal s_sti1_int : memory_sti1_int;

-- промежуточные int реал сигналы 2_я стадия
subtype str2_int is integer range -8192 to 8191;
type memory_str2_int is array(7 downto 0) of str2_int;
signal s_str2_int : memory_str2_int;

-- промежуточные int мним сигналы 2_я стадия
subtype sti2_int is integer range -8192 to 8191;
type memory_sti2_int is array(7 downto 0) of sti2_int;
signal s_sti2_int : memory_sti2_int;

-- поворачивающие множители
-- round((cos(2*pi*n/8) - 1j*sin(2*pi*n/8))*32767)
-- n = 0...3
constant w8_0  : integer :=1;	
constant w8_1  : integer :=23170;	
constant w8_2  : integer :=0;	
constant w8_3  : integer :=-23170;	

begin

s_ctf <= ctfin;
ctfout <= s_ctf;

-- загрузка данных
process(clk)
begin
if clk'event and clk = '1' then
	if wrdata = '1' then 
		-- реал
		s_dbr(0) <= dinr0;
		s_dbr(1) <= dinr1;
		s_dbr(2) <= dinr2;
		s_dbr(3) <= dinr3;
		s_dbr(4) <= dinr4;
		s_dbr(5) <= dinr5;
		s_dbr(6) <= dinr6;
		s_dbr(7) <= dinr7;
		-- мним
		s_dbi(0) <= dini0;
		s_dbi(1) <= dini1;
		s_dbi(2) <= dini2;
		s_dbi(3) <= dini3;
		s_dbi(4) <= dini4;
		s_dbi(5) <= dini5;
		s_dbi(6) <= dini6;
		s_dbi(7) <= dini7;
	end if;
end if;

end process;	

-- операция fft8 (прореживание по времени)
process(clk)
begin
if clk'event and clk = '1' then
	-- 1_я стадия fft8 (только сумма и разность) 
	-- x(0) = (xr(0)+xr(4))+j*(xi(0)+xi(4))  
	if (s_ctf = 1 or s_ctf = 5 or s_ctf = 9 or s_ctf = 13) and begpr = '1' then
		for i in 0 to 3 loop
			s_str1(i*2) <= signed(s_dbr(i)) + signed(s_dbr(i + 4));
			s_str1((i + 1) + i) <= signed(s_dbr(i)) - signed(s_dbr(i + 4));
			s_sti1(i*2) <= signed(s_dbi(i)) + signed(s_dbi(i + 4));
			s_sti1((i + 1) + i) <= signed(s_dbi(i)) - signed(s_dbi(i + 4));
		end loop;

		for i in 0 to 7 loop
			s_str1_int(i) <= conv_integer(signed (s_str1(i)));
			s_sti1_int(i) <= conv_integer(signed (s_sti1(i)));
		end loop;
	-- 2_я стадия fft8  	
	elsif (s_ctf = 2 or s_ctf = 6 or s_ctf = 10 or s_ctf = 14) and begpr = '1' then
		s_str2(0) <= conv_std_logic_vector((s_str1_int(0) + s_str1_int(2)), nb);
		s_str2(1) <= conv_std_logic_vector((s_str1_int(1) + s_str1_int(3)*w8_2), nb);
		s_str2(2) <= conv_std_logic_vector((s_str1_int(0) - s_str1_int(2)), nb);
		s_str2(3) <= conv_std_logic_vector((s_str1_int(1) - s_str1_int(3)*w8_2), nb);
		s_str2(4) <= conv_std_logic_vector((s_str1_int(4) + s_str1_int(6)), nb);
		s_str2(5) <= conv_std_logic_vector((s_str1_int(5) + s_str1_int(7)*w8_2), nb);
		s_str2(6) <= conv_std_logic_vector((s_str1_int(4) - s_str1_int(6)), nb);
		s_str2(7) <= conv_std_logic_vector((s_str1_int(5) - s_str1_int(7)*w8_2), nb);

		s_sti2(0) <= conv_std_logic_vector((s_sti1_int(0) + s_sti1_int(2)), nb);
		s_sti2(1) <= conv_std_logic_vector((s_sti1_int(1) + s_sti1_int(3)*w8_2), nb);
		s_sti2(2) <= conv_std_logic_vector((s_sti1_int(0) - s_sti1_int(2)), nb);
		s_sti2(3) <= conv_std_logic_vector((s_sti1_int(1) - s_sti1_int(3)*w8_2), nb);
		s_sti2(4) <= conv_std_logic_vector((s_sti1_int(4) + s_sti1_int(6)), nb);
		s_sti2(5) <= conv_std_logic_vector((s_sti1_int(5) + s_sti1_int(7)*w8_2), nb);
		s_sti2(6) <= conv_std_logic_vector((s_sti1_int(4) - s_sti1_int(6)), nb);
		s_sti2(7) <= conv_std_logic_vector((s_sti1_int(5) - s_sti1_int(7)*w8_2), nb);

		for i in 0 to 7 loop
			s_str2_int(i) <= conv_integer(signed (s_str2(i)));
			s_sti2_int(i) <= conv_integer(signed (s_sti2(i)));
		end loop;	
		-- 3_я стадия fft8 
	elsif (s_ctf = 3 or s_ctf = 7 or s_ctf = 11 or s_ctf = 15) and begpr = '1' then
		s_str3(0) <= conv_std_logic_vector((s_str2_int(0) + s_str2_int(4)), nb);
		s_str3(1) <= conv_std_logic_vector((s_str2_int(1) + s_str2_int(5)*w8_1), nb);
		s_str3(2) <= conv_std_logic_vector((s_str2_int(2) + s_str2_int(6)*w8_2), nb);
		s_str3(3) <= conv_std_logic_vector((s_str2_int(3) + s_str2_int(7)*w8_3), nb);
		s_str3(4) <= conv_std_logic_vector((s_str2_int(0) - s_str2_int(4)), nb);
		s_str3(5) <= conv_std_logic_vector((s_str2_int(1) - s_str2_int(5)*w8_1), nb);
		s_str3(6) <= conv_std_logic_vector((s_str2_int(2) - s_str2_int(6)*w8_2), nb);
		s_str3(7) <= conv_std_logic_vector((s_str2_int(3) - s_str2_int(7)*w8_3), nb);

		s_sti3(0) <= conv_std_logic_vector((s_sti2_int(0) + s_sti2_int(4)), nb);
		s_sti3(1) <= conv_std_logic_vector((s_sti2_int(1) + s_sti2_int(5)*w8_1), nb);
		s_sti3(2) <= conv_std_logic_vector((s_sti2_int(2) + s_sti2_int(6)*w8_2), nb);
		s_sti3(3) <= conv_std_logic_vector((s_sti2_int(3) + s_sti2_int(7)*w8_3), nb);
		s_sti3(4) <= conv_std_logic_vector((s_sti2_int(0) - s_sti2_int(4)), nb);
		s_sti3(5) <= conv_std_logic_vector((s_sti2_int(1) - s_sti2_int(5)*w8_1), nb);
		s_sti3(6) <= conv_std_logic_vector((s_sti2_int(2) - s_sti2_int(6)*w8_2), nb);
		s_sti3(7) <= conv_std_logic_vector((s_sti2_int(3) - s_sti2_int(7)*w8_3), nb);
		-- запись данных
	elsif (s_ctf = 4 or s_ctf = 8 or s_ctf = 12 or s_ctf = 16) and begpr = '1' then
		doutr0 <= s_str3(0);
		doutr1 <= s_str3(1);
		doutr2 <= s_str3(2);
		doutr3 <= s_str3(3);
		doutr4 <= s_str3(4);
		doutr5 <= s_str3(5);
		doutr6 <= s_str3(6);
		doutr7 <= s_str3(7);

		douti0 <= s_sti3(0);
		douti1 <= s_sti3(1);
		douti2 <= s_sti3(2);
		douti3 <= s_sti3(3);
		douti4 <= s_sti3(4);
		douti5 <= s_sti3(5);
		douti6 <= s_sti3(6);
		douti7 <= s_sti3(7);
	end if;	 
end if; 

end process;	

end behavioural;

Не уверен с коэфффициентами для 4_рех повторяющихся fft8. Принял размерность входных и выходных данных одинаковую. Чем это грозит?

Share this post


Link to post
Share on other sites

А.. врубился. Бабочку можно сделать так.

Допустим выходы бабчки x0_1(0) и x1_1(1). На вход подается x(0) = xr(0) + j*xi(0) и x(4) = xr(4) + j*xi(4)

На выходах будет

x0_1(0) = (xr(0) + xr(4)) + j*(xi(0) + xi(4))*W0

x1_1(1) = (xr(0) + xr(4)) - j*(xi(0) + xi(4))*W0

Если это так, то тогда можно и код накатать...

 

Не, не угадали :crying:

 

 

Код fft8. Далее будет в виде компонента для fft32.

...

Не уверен с коэфффициентами для 4_рех повторяющихся fft8. Принял размерность входных и выходных данных одинаковую. Чем это грозит?

 

Тоже не угадали :crying:

 

ошибки, которые бросаются в глаза:

 

1) реальная часть выходов зависит только от реальной части входов, а мнимая часть выходов только от мнимой части входов.

2) коэффициенты не правильные

3) умножения комплексных чисел выполнено неверно (это собственно следствие 1 и 2)

 

У Рабинера и Голда в 10 главе на стр. 640 есть граф БПФ-4 с прореживанием по частоте и мат. выражения, соответствующие каждому выходу. Если Вы сможете правильно нарисовать такое-же для своей 8-ми точечной бабочки, то сможете и код написать.

 

Осваивайте комплексные числа.

 

Удачи!

Share this post


Link to post
Share on other sites

Не, не угадали

 

Тоже не угадали :crying:

 

ошибки, которые бросаются в глаза:

 

1) реальная часть выходов зависит только от реальной части входов, а мнимая часть выходов только от мнимой части входов.

2) коэффициенты не правильные

3) умножения комплексных чисел выполнено неверно (это собственно следствие 1 и 2)

 

У Рабинера и Голда в 10 главе на стр. 640 есть граф БПФ-4 с прореживанием по частоте и мат. выражения, соответствующие каждому выходу. Если Вы сможете правильно нарисовать такое-же для своей 8-ми точечной бабочки, то сможете и код написать.

 

Осваивайте комплексные числа.

 

Удачи!

Можно я с Вами не соглашусь?

Я использую алгоритм прореживания по времени, а не по частоте.post-39850-1379052923_thumb.jpg

Слагаю и вычитаю реал и мним входные части данных как написано в букваре по комплексным числам.

Комплексные числа  записываются в виде:  a+ bi. Здесь  a и  b – действительные числа, а  i – мнимая единица, т.e.  i 2 = –1. Число  a называется абсциссой, a  b – ординатой комплексного числа  a+ bi. Два комплексных числа  a+ bi и  a – bi называются сопряжёнными комплексными числами.
Основные договорённости: 
1.  Действительное число  а  может быть также записано в форме комплексного числа:  a+ 0 i  или  a – 0 i.  Например, записи  5 + 0 i  и  5 – 0 i  означают одно и то же число  5 .
2.  Комплексное число 0+ bi  называется чисто мнимым числом. Запись bi означает то же самое, что и  0+ bi.
3.  Два комплексных числа  a+ bi и c+ di считаются равными, если  a= c и b= d. В противном случае комплексные числа не равны.
Сложение.  Суммой комплексных чисел  a+ bi  и  c+ di  называется комплексное число ( a+ c ) + ( b+ d ) i. Таким образом, при сложении комплексных чисел отдельно складываются их абсциссы и ординаты.
Это определение соответствует правилам действий с обычными многочленами.
Вычитание.  Разностью двух комплексных чисел  a+ bi (уменьшаемое) и c+ di (вычитаемое) называется комплексное число ( a – c ) + ( b – d ) i.
Таким образом, при вычитании двух комплексных чисел отдельно вычитаются их абсциссы и ординаты.

А.. умножение (на поворачивающий множитель) не верно. Исправлю. Но, всеравно непонятно. В каком виде должен быть записан поворачивающий множитель? Я его просто посчитал в матлабе как round((cos(2*pi*n/8) - 1j*sin(2*pi*n/8))*32767) и забил в коде в виде константы. Получается поворачивающий множитель тоже нужно представить как комплексный? Типа посчитать отдельно (cos(2*pi*n/8) sin(2*pi*n/8) каждое умножить на 32767 и записать в виде a +jb?

Edited by Acvarif

Share this post


Link to post
Share on other sites

(a + jb)*(c + jd) = ac + jbc + jad + j*j*bd = ac + jbc + jad – bd = (ac - bd) + j(ad + bc);

 

В вашем случае с - реaльная часть поворачивающего множителя,а d - мнимая.

Share this post


Link to post
Share on other sites

(a + jb)*(c + jd) = ac + jbc + jad + j*j*bd = ac + jbc + jad – bd = (ac - bd) + j(ad + bc);

 

В вашем случае с - рельная часть поворачивающего множителя,а d - мнимая.

Спасибо. Понятно. j*j = -1

Опять, блин, комплексное число. Где ж ресурсов ПЛИС столько взять на все эти комплексные числа?

Я так понял, что с в матлабе нужно считать как cos(2*pi*n/8), а d как sin(2*pi*n/8) ?

Получилось так

    -- поворачивающие множители
    -- round(cos(2*pi*n/8)*32767)
    -- round(sin(2*pi*n/8)*32767)
    -- n = 0...3
    -- реал
    constant wr8_0  : integer := 32767;    
    constant wr8_1  : integer := 23170;    
    constant wr8_2  : integer := 0;    
    constant wr8_3  : integer := -23170;    
    -- мним
    constant wi8_0  : integer := 0;    
    constant wi8_1  : integer := 23170;    
    constant wi8_2  : integer := 32767;    
    constant wi8_3  : integer := 23170;

Так верно?

Если так то получается уже на первой стадии fft8 нужно делать операцию комплексного умножения, поскольку wr8_0 не равен 0?

Edited by Acvarif

Share this post


Link to post
Share on other sites

Можно я с Вами не соглашусь?

 

Можно. Но код от этого правильным не станет и знаний в области комплексных чисел тоже не прибавится.

 

Я использую алгоритм прореживания по времени, а не по частоте.

 

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

 

Получается поворачивающий множитель тоже нужно представить как комплексный? Типа посчитать отдельно (cos(2*pi*n/8) sin(2*pi*n/8) каждое умножить на 32767 и записать в виде a +jb?

 

Я никак не могу понять. Я уже пять раз писал, что все числа, включая коэффициенты, комплексные. Вы можете мне объяснить что Вы "делали" с этой информацией когда читали посты?

 

 

Если Вы и вправду думаете, что выражение

post-7537-1379070737_thumb.jpg

 

и

 

x0_1(0) = (xr(0) + xr(4)) + j*(xi(0) + xi(4))*W0

x1_1(1) = (xr(0) + xr(4)) - j*(xi(0) + xi(4))*W0

 

эквивалентны, то это лишний раз подтверждает, что Вы не умеете выполнять арифметические операции с комплексными числами.

 

Share this post


Link to post
Share on other sites

...

эквивалентны, то это лишний раз подтверждает, что Вы не умеете выполнять арифметические операции с комплексными числами.

Операции с комплексными числами несложные. В конечном итоге я их постараюсь выполнить.

Умом понимаю, а руки делать не хотят. Наверное ПЛИС_ку жалко.

Прошу ответить правильно-ли я посчитал поворачивающие множители.

    -- поворачивающие множители
    -- round(cos(2*pi*n/8)*32767)
    -- round(sin(2*pi*n/8)*32767)
    -- n = 0...3
    -- реал
    constant wr8_0  : integer := 32767;    
    constant wr8_1  : integer := 23170;    
    constant wr8_2  : integer := 0;    
    constant wr8_3  : integer := -23170;    
    -- мним
    constant wi8_0  : integer := 0;    
    constant wi8_1  : integer := 23170;    
    constant wi8_2  : integer := 32767;    
    constant wi8_3  : integer := 23170;

Если правильно то перепишу код под все комплексные числа, в том числе и комплексные поворачивающие множители,

и с учетом того, что j*j = -1.

Edited by Acvarif

Share this post


Link to post
Share on other sites

Примерно так:

-- Бабочка (прореживание по времени)
-- A = x + Wn * y;
-- A_r + j*A_i = (x_r + j* x_i) + ( w_r + j*w_i) *(y_r + j*y_i);
-- A_r + j*A_i = (x_r + (w_r * y_r ) –( w_i *y_i)) + j*(x_i +( w_i *y_r) +( w_r * y_i));
-- A_r = x_r + (w_r * y_r ) –( w_i *y_i);
-- A_i = x_i +( w_i *y_r) +( w_r * y_i);
-- B = x - Wn * y;
-- B_r + j*B_i = (x_r + j* x_i) - ( w_r + j*w_i) *(y_r + j*y_i);
-- B_r + j*B_i = ( x_r - (w_r *y_r) + (w_i * y_i)) + (x_i – (w_r *y_i ) – (w_i * y_r ));
-- B_r =( x_r - (w_r *y_r) + (w_i * y_i);
-- B_i = x_i – (w_r * y_i ) – (w_i * y_r );

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_SIGNED.ALL;

entity fft8vhd is
Generic (
	-- размерность входных данных
	nb : natural := 16
	);
Port (
	-- тактовая частота
	clk : in std_logic;
	-- общий сброс
	rst	: in std_logic;
	-- входные данные реал
	dinr0	: in std_logic_vector(nb-1 downto 0);
	dinr1	: in std_logic_vector(nb-1 downto 0);
	dinr2	: in std_logic_vector(nb-1 downto 0);
	dinr3	: in std_logic_vector(nb-1 downto 0);
	dinr4	: in std_logic_vector(nb-1 downto 0);
	dinr5	: in std_logic_vector(nb-1 downto 0);
	dinr6	: in std_logic_vector(nb-1 downto 0);
	dinr7	: in std_logic_vector(nb-1 downto 0);
	-- входные данные мним
	dini0	: in std_logic_vector(nb-1 downto 0);
	dini1	: in std_logic_vector(nb-1 downto 0);
	dini2	: in std_logic_vector(nb-1 downto 0);
	dini3	: in std_logic_vector(nb-1 downto 0);
	dini4	: in std_logic_vector(nb-1 downto 0);
	dini5	: in std_logic_vector(nb-1 downto 0);
	dini6	: in std_logic_vector(nb-1 downto 0);
	dini7	: in std_logic_vector(nb-1 downto 0);
	-- импульс записи данных 
	wrdata	: in std_logic;
	-- счетчик стадий
	ctfin		: in std_logic_vector(4 downto 0);
	-- разрешение начала преобразований
	begpr 	: in std_logic;

	-- выход счетчика стадий 
	ctfout	: out std_logic_vector(4 downto 0);
	-- выходы данных реал
	doutr0	: out std_logic_vector(nb-1 downto 0);
	doutr1	: out std_logic_vector(nb-1 downto 0);
	doutr2	: out std_logic_vector(nb-1 downto 0);
	doutr3	: out std_logic_vector(nb-1 downto 0);
	doutr4	: out std_logic_vector(nb-1 downto 0);
	doutr5	: out std_logic_vector(nb-1 downto 0);
	doutr6	: out std_logic_vector(nb-1 downto 0);
	doutr7	: out std_logic_vector(nb-1 downto 0);
	-- выходы данных мним
	douti0	: out std_logic_vector(nb-1 downto 0);
	douti1	: out std_logic_vector(nb-1 downto 0);
	douti2	: out std_logic_vector(nb-1 downto 0);
	douti3	: out std_logic_vector(nb-1 downto 0);
	douti4	: out std_logic_vector(nb-1 downto 0);
	douti5	: out std_logic_vector(nb-1 downto 0);
	douti6	: out std_logic_vector(nb-1 downto 0);
	douti7	: out std_logic_vector(nb-1 downto 0)
	);
end fft8vhd;

architecture behavioural of fft8vhd is
attribute multstyle : string;
-- на базе логики
attribute multstyle of behavioural : architecture is "logic";
-- на базе встроенных умножителей
--attribute multstyle of behavioural : architecture is "dsp";

signal s_ctf : std_logic_vector(4 downto 0);

-- буферные сигналы реал
subtype sdbr is std_logic_vector(nb-1 downto 0);
type memory_sdbr is array(7 downto 0) of sdbr;
signal s_dbr : memory_sdbr;

-- буферные сигналы мним
subtype sdbi is std_logic_vector(nb-1 downto 0);
type memory_sdbi is array(7 downto 0) of sdbi;
signal s_dbi : memory_sdbi;

-- сигналы реал 1_й стади
subtype str1 is std_logic_vector(nb-1 downto 0);
type memory_str1 is array(7 downto 0) of str1;
signal s_str1 : memory_str1;

-- сигналы мним 1_й стади
subtype sti1 is std_logic_vector(nb-1 downto 0);
type memory_sti1 is array(7 downto 0) of sti1;
signal s_sti1 : memory_sti1;

-- сигналы реал 2_й стади
subtype str2 is std_logic_vector(nb-1 downto 0);
type memory_str2 is array(7 downto 0) of str2;
signal s_str2 : memory_str2;

-- сигналы мним 2_й стади
subtype sti2 is std_logic_vector(nb-1 downto 0);
type memory_sti2 is array(7 downto 0) of sti2;
signal s_sti2 : memory_sti2;

-- сигналы 3_й стади
subtype str3 is std_logic_vector(nb-1 downto 0);
type memory_str3 is array(7 downto 0) of str3;
signal s_str3 : memory_str3;

subtype sti3 is std_logic_vector(nb-1 downto 0);
type memory_sti3 is array(7 downto 0) of sti3;
signal s_sti3 : memory_sti3;

-- промежуточные int реал сигналы 1_я стадия
subtype str1_int is integer range -8192 to 8191;
type memory_str1_int is array(7 downto 0) of str1_int;
signal s_str1_int : memory_str1_int;

-- промежуточные int мним сигналы 1_я стадия
subtype sti1_int is integer range -8192 to 8191;
type memory_sti1_int is array(7 downto 0) of sti1_int;
signal s_sti1_int : memory_sti1_int;

signal y0_int : integer range -13427728 to 13427727;

-- промежуточные int реал сигналы 2_я стадия
subtype str2_int is integer range -8192 to 8191;
type memory_str2_int is array(7 downto 0) of str2_int;
signal s_str2_int : memory_str2_int;

-- промежуточные int мним сигналы 2_я стадия
subtype sti2_int is integer range -8192 to 8191;
type memory_sti2_int is array(7 downto 0) of sti2_int;
signal s_sti2_int : memory_sti2_int;

-- промежуточные int реал сигналы 3_я стадия
subtype str3_int is integer range -8192 to 8191;
type memory_str3_int is array(7 downto 0) of str3_int;
signal s_str3_int : memory_str3_int;

-- промежуточные int мним сигналы 3_я стадия
subtype sti3_int is integer range -8192 to 8191;
type memory_sti3_int is array(7 downto 0) of sti3_int;
signal s_sti3_int : memory_sti3_int;

-- поворачивающие множители
-- round(cos(2*pi*n/8)*32767)
-- round(sin(2*pi*n/8)*32767)
-- n = 0...3
-- реал
constant wr8_0  : integer := 32767;	
constant wr8_1  : integer := 23170;	
constant wr8_2  : integer := 0;	
constant wr8_3  : integer := -23170;	
-- мним
constant wi8_0  : integer := 0;	
constant wi8_1  : integer := 23170;	
constant wi8_2  : integer := 32767;	
constant wi8_3  : integer := 23170;	

begin

s_ctf <= ctfin;
ctfout <= s_ctf;

-- загрузка данных
process(clk)
begin
if clk'event and clk = '1' then
	if wrdata = '1' then 
		-- реал
		s_dbr(0) <= dinr0;
		s_dbr(1) <= dinr1;
		s_dbr(2) <= dinr2;
		s_dbr(3) <= dinr3;
		s_dbr(4) <= dinr4;
		s_dbr(5) <= dinr5;
		s_dbr(6) <= dinr6;
		s_dbr(7) <= dinr7;
		-- мним
		s_dbi(0) <= dini0;
		s_dbi(1) <= dini1;
		s_dbi(2) <= dini2;
		s_dbi(3) <= dini3;
		s_dbi(4) <= dini4;
		s_dbi(5) <= dini5;
		s_dbi(6) <= dini6;
		s_dbi(7) <= dini7;
	end if;
end if;

end process;	

-- операция fft8 (прореживание по времени)
process(clk)
begin
if clk'event and clk = '1' then
	-- 1_я стадия fft8  
	if (s_ctf = 1 or s_ctf = 5 or s_ctf = 9 or s_ctf = 13) and begpr = '1' then
		-- входные данные в integer
		for i in 0 to 7 loop
			s_str1_int(i) <= conv_integer(signed (s_dbr(i)));
			s_sti1_int(i) <= conv_integer(signed (s_dbi(i)));
		end loop;
		-- A_r = x_r + (w_r*y_r ) –( w_i*y_i);
		s_str1(0) <= conv_std_logic_vector((s_str1_int(0) + (s_str1_int(4)*wr8_0 - s_sti1_int(4)*wi8_0)), nb);
		-- A_i = x_i + ( w_i*y_r) +( w_r*y_i);
		s_sti1(0) <= conv_std_logic_vector((s_sti1_int(0) + (s_str1_int(4)*wi8_0 + s_sti1_int(4)*wr8_0)), nb);
		-- B_r = (x_r - (w_r*y_r) + (w_i*y_i);
		s_str1(1) <= conv_std_logic_vector((s_str1_int(0) - (s_str1_int(4)*wr8_0 + s_sti1_int(4)*wi8_0)), nb);
		-- B_i = (x_i – (w_r*y_i) – (w_i*y_r);
		s_sti1(1) <= conv_std_logic_vector((s_sti1_int(0) - (s_sti1_int(4)*wr8_0 - s_str1_int(4)*wi8_0)), nb);

		s_str1(2) <= conv_std_logic_vector((s_str1_int(2) + (s_str1_int(6)*wr8_0 - s_sti1_int(6)*wi8_0)), nb);
		s_sti1(2) <= conv_std_logic_vector((s_sti1_int(2) + (s_str1_int(6)*wi8_0 + s_sti1_int(6)*wr8_0)), nb);
		s_str1(3) <= conv_std_logic_vector((s_str1_int(2) - (s_str1_int(6)*wr8_0 + s_sti1_int(6)*wi8_0)), nb);
		s_sti1(3) <= conv_std_logic_vector((s_sti1_int(2) - (s_sti1_int(6)*wr8_0 - s_str1_int(6)*wi8_0)), nb);
		s_str1(4) <= conv_std_logic_vector((s_str1_int(1) + (s_str1_int(5)*wr8_0 - s_sti1_int(5)*wi8_0)), nb);
		s_sti1(4) <= conv_std_logic_vector((s_sti1_int(1) + (s_str1_int(5)*wi8_0 + s_sti1_int(5)*wr8_0)), nb);
		s_str1(5) <= conv_std_logic_vector((s_str1_int(1) - (s_str1_int(5)*wr8_0 + s_sti1_int(5)*wi8_0)), nb);
		s_sti1(5) <= conv_std_logic_vector((s_sti1_int(1) - (s_sti1_int(5)*wr8_0 - s_str1_int(5)*wi8_0)), nb);
		s_str1(6) <= conv_std_logic_vector((s_str1_int(3) + (s_str1_int(7)*wr8_0 - s_sti1_int(7)*wi8_0)), nb);
		s_sti1(6) <= conv_std_logic_vector((s_sti1_int(3) + (s_str1_int(7)*wi8_0 + s_sti1_int(7)*wr8_0)), nb);
		s_str1(7) <= conv_std_logic_vector((s_str1_int(3) - (s_str1_int(7)*wr8_0 + s_sti1_int(7)*wi8_0)), nb);
		s_sti1(7) <= conv_std_logic_vector((s_sti1_int(3) - (s_sti1_int(7)*wr8_0 - s_str1_int(7)*wi8_0)), nb);

	-- 2_я стадия fft8  	
	elsif (s_ctf = 2 or s_ctf = 6 or s_ctf = 10 or s_ctf = 14) and begpr = '1' then
		for i in 0 to 7 loop
			s_str2_int(i) <= conv_integer(signed (s_str1(i)));
			s_sti2_int(i) <= conv_integer(signed (s_sti1(i)));
		end loop;	
		s_str2(0) <= conv_std_logic_vector((s_str2_int(0) + (s_str2_int(2)*wr8_0 - s_sti2_int(2)*wi8_0)), nb);
		s_sti2(0) <= conv_std_logic_vector((s_sti2_int(0) + (s_str2_int(2)*wi8_0 + s_sti2_int(2)*wr8_0)), nb);
		s_str2(2) <= conv_std_logic_vector((s_str2_int(0) - (s_str2_int(2)*wr8_0 + s_sti2_int(2)*wi8_0)), nb);
		s_sti2(2) <= conv_std_logic_vector((s_sti2_int(0) - (s_sti2_int(2)*wr8_0 - s_str2_int(2)*wi8_0)), nb);

		s_str2(1) <= conv_std_logic_vector((s_str2_int(1) + (s_str2_int(3)*wr8_2 - s_sti2_int(3)*wi8_2)), nb);
		s_sti2(1) <= conv_std_logic_vector((s_sti2_int(1) + (s_str2_int(3)*wi8_2 + s_sti2_int(3)*wr8_2)), nb);
		s_str2(3) <= conv_std_logic_vector((s_str2_int(1) - (s_str2_int(3)*wr8_2 + s_sti2_int(3)*wi8_2)), nb);
		s_sti2(3) <= conv_std_logic_vector((s_sti2_int(1) - (s_sti2_int(3)*wr8_2 - s_str2_int(3)*wi8_2)), nb);

		s_str2(4) <= conv_std_logic_vector((s_str2_int(4) + (s_str2_int(6)*wr8_0 - s_sti2_int(6)*wi8_0)), nb);
		s_sti2(4) <= conv_std_logic_vector((s_sti2_int(4) + (s_str2_int(6)*wi8_0 + s_sti2_int(6)*wr8_0)), nb);
		s_str2(6) <= conv_std_logic_vector((s_str2_int(4) - (s_str2_int(6)*wr8_0 + s_sti2_int(6)*wi8_0)), nb);
		s_sti2(6) <= conv_std_logic_vector((s_sti2_int(4) - (s_sti2_int(6)*wr8_0 - s_str2_int(6)*wi8_0)), nb);

		s_str2(5) <= conv_std_logic_vector((s_str2_int(5) + (s_str2_int(7)*wr8_2 - s_sti2_int(7)*wi8_2)), nb);
		s_sti2(5) <= conv_std_logic_vector((s_sti2_int(5) + (s_str2_int(7)*wi8_2 + s_sti2_int(7)*wr8_2)), nb);
		s_str2(7) <= conv_std_logic_vector((s_str2_int(5) - (s_str2_int(7)*wr8_2 + s_sti2_int(7)*wi8_2)), nb);
		s_sti2(7) <= conv_std_logic_vector((s_sti2_int(5) - (s_sti2_int(7)*wr8_2 - s_str2_int(7)*wi8_2)), nb);

		-- 3_я стадия fft8 
	elsif (s_ctf = 3 or s_ctf = 7 or s_ctf = 11 or s_ctf = 15) and begpr = '1' then
		for i in 0 to 7 loop
			s_str3_int(i) <= conv_integer(signed (s_str2(i)));
			s_sti3_int(i) <= conv_integer(signed (s_sti2(i)));
		end loop;	

		s_str3(0) <= conv_std_logic_vector((s_str3_int(0) + (s_str3_int(4)*wr8_0 - s_sti3_int(4)*wi8_0)), nb);
		s_sti3(0) <= conv_std_logic_vector((s_sti3_int(0) + (s_str3_int(4)*wi8_0 + s_sti3_int(4)*wr8_0)), nb);
		s_str3(4) <= conv_std_logic_vector((s_str3_int(0) - (s_str3_int(4)*wr8_0 + s_sti3_int(4)*wi8_0)), nb);
		s_sti3(4) <= conv_std_logic_vector((s_sti3_int(0) - (s_sti3_int(4)*wr8_0 - s_str3_int(4)*wi8_0)), nb);

		s_str3(1) <= conv_std_logic_vector((s_str3_int(1) + (s_str3_int(5)*wr8_1 - s_sti3_int(5)*wi8_1)), nb);
		s_sti3(1) <= conv_std_logic_vector((s_sti3_int(1) + (s_str3_int(5)*wi8_1 + s_sti3_int(5)*wr8_1)), nb);
		s_str3(5) <= conv_std_logic_vector((s_str3_int(1) - (s_str3_int(5)*wr8_1 + s_sti3_int(5)*wi8_1)), nb);
		s_sti3(5) <= conv_std_logic_vector((s_sti3_int(1) - (s_sti3_int(5)*wr8_1 - s_str3_int(5)*wi8_1)), nb);

		s_str3(2) <= conv_std_logic_vector((s_str3_int(2) + (s_str3_int(6)*wr8_2 - s_sti3_int(6)*wi8_2)), nb);
		s_sti3(2) <= conv_std_logic_vector((s_sti3_int(2) + (s_str3_int(6)*wi8_2 + s_sti3_int(6)*wr8_2)), nb);
		s_str3(6) <= conv_std_logic_vector((s_str3_int(2) - (s_str3_int(6)*wr8_2 + s_sti3_int(6)*wi8_2)), nb);
		s_sti3(6) <= conv_std_logic_vector((s_sti3_int(2) - (s_sti3_int(6)*wr8_2 - s_str3_int(6)*wi8_2)), nb);

		s_str3(3) <= conv_std_logic_vector((s_str3_int(3) + (s_str3_int(7)*wr8_3 - s_sti3_int(7)*wi8_3)), nb);
		s_sti3(3) <= conv_std_logic_vector((s_sti3_int(3) + (s_str3_int(7)*wi8_3 + s_sti3_int(7)*wr8_3)), nb);
		s_str3(7) <= conv_std_logic_vector((s_str3_int(3) - (s_str3_int(7)*wr8_3 + s_sti3_int(7)*wi8_3)), nb);
		s_sti3(7) <= conv_std_logic_vector((s_sti3_int(3) - (s_sti3_int(7)*wr8_3 - s_str3_int(7)*wi8_3)), nb);

		-- запись данных
	elsif (s_ctf = 4 or s_ctf = 8 or s_ctf = 12 or s_ctf = 16) and begpr = '1' then
		doutr0 <= s_str3(0);
		doutr1 <= s_str3(1);
		doutr2 <= s_str3(2);
		doutr3 <= s_str3(3);
		doutr4 <= s_str3(4);
		doutr5 <= s_str3(5);
		doutr6 <= s_str3(6);
		doutr7 <= s_str3(7);

		douti0 <= s_sti3(0);
		douti1 <= s_sti3(1);
		douti2 <= s_sti3(2);
		douti3 <= s_sti3(3);
		douti4 <= s_sti3(4);
		douti5 <= s_sti3(5);
		douti6 <= s_sti3(6);
		douti7 <= s_sti3(7);
	end if;	 
end if; 

end process;	

end behavioural;

По прежнему не уверен с поворачивающими множителями и размерностями данных (промежуточных и выходных).

Места это все заняло почти 2000 ячеек.

Edited by Acvarif

Share this post


Link to post
Share on other sites

Места это все заняло почти 2000 ячеек.

 

Для справки, это не БПФ такой прожорливый - это код такой не оптимальный. Впрочем, на мой взгляд, Вам пока рано об этом задумываться. Сначала пусть все правильно заработает.

 

Примерно так:

-- Бабочка (прореживание по времени)
		s_str1(2) <= conv_std_logic_vector((s_str1_int(2) + (s_str1_int(6)*wr8_0 - s_sti1_int(6)*wi8_0)), nb);
		s_sti1(2) <= conv_std_logic_vector((s_sti1_int(2) + (s_str1_int(6)*wi8_0 + s_sti1_int(6)*wr8_0)), nb);
		s_str1(3) <= conv_std_logic_vector((s_str1_int(2) - (s_str1_int(6)*wr8_0 + s_sti1_int(6)*wi8_0)), nb);
		s_sti1(3) <= conv_std_logic_vector((s_sti1_int(2) - (s_sti1_int(6)*wr8_0 - s_str1_int(6)*wi8_0)), nb);
		s_str1(4) <= conv_std_logic_vector((s_str1_int(1) + (s_str1_int(5)*wr8_0 - s_sti1_int(5)*wi8_0)), nb);
		s_sti1(4) <= conv_std_logic_vector((s_sti1_int(1) + (s_str1_int(5)*wi8_0 + s_sti1_int(5)*wr8_0)), nb);
		s_str1(5) <= conv_std_logic_vector((s_str1_int(1) - (s_str1_int(5)*wr8_0 + s_sti1_int(5)*wi8_0)), nb);
		s_sti1(5) <= conv_std_logic_vector((s_sti1_int(1) - (s_sti1_int(5)*wr8_0 - s_str1_int(5)*wi8_0)), nb);
		s_str1(6) <= conv_std_logic_vector((s_str1_int(3) + (s_str1_int(7)*wr8_0 - s_sti1_int(7)*wi8_0)), nb);
		s_sti1(6) <= conv_std_logic_vector((s_sti1_int(3) + (s_str1_int(7)*wi8_0 + s_sti1_int(7)*wr8_0)), nb);
		s_str1(7) <= conv_std_logic_vector((s_str1_int(3) - (s_str1_int(7)*wr8_0 + s_sti1_int(7)*wi8_0)), nb);
		s_sti1(7) <= conv_std_logic_vector((s_sti1_int(3) - (s_sti1_int(7)*wr8_0 - s_str1_int(7)*wi8_0)), nb);

		s_str2(0) <= conv_std_logic_vector((s_str2_int(0) + (s_str2_int(2)*wr8_0 - s_sti2_int(2)*wi8_0)), nb);
		s_sti2(0) <= conv_std_logic_vector((s_sti2_int(0) + (s_str2_int(2)*wi8_0 + s_sti2_int(2)*wr8_0)), nb);
		s_str2(2) <= conv_std_logic_vector((s_str2_int(0) - (s_str2_int(2)*wr8_0 + s_sti2_int(2)*wi8_0)), nb);
		s_sti2(2) <= conv_std_logic_vector((s_sti2_int(0) - (s_sti2_int(2)*wr8_0 - s_str2_int(2)*wi8_0)), nb);

		s_str2(1) <= conv_std_logic_vector((s_str2_int(1) + (s_str2_int(3)*wr8_2 - s_sti2_int(3)*wi8_2)), nb);
		s_sti2(1) <= conv_std_logic_vector((s_sti2_int(1) + (s_str2_int(3)*wi8_2 + s_sti2_int(3)*wr8_2)), nb);
		s_str2(3) <= conv_std_logic_vector((s_str2_int(1) - (s_str2_int(3)*wr8_2 + s_sti2_int(3)*wi8_2)), nb);
		s_sti2(3) <= conv_std_logic_vector((s_sti2_int(1) - (s_sti2_int(3)*wr8_2 - s_str2_int(3)*wi8_2)), nb);

		s_str2(4) <= conv_std_logic_vector((s_str2_int(4) + (s_str2_int(6)*wr8_0 - s_sti2_int(6)*wi8_0)), nb);
		s_sti2(4) <= conv_std_logic_vector((s_sti2_int(4) + (s_str2_int(6)*wi8_0 + s_sti2_int(6)*wr8_0)), nb);
		s_str2(6) <= conv_std_logic_vector((s_str2_int(4) - (s_str2_int(6)*wr8_0 + s_sti2_int(6)*wi8_0)), nb);
		s_sti2(6) <= conv_std_logic_vector((s_sti2_int(4) - (s_sti2_int(6)*wr8_0 - s_str2_int(6)*wi8_0)), nb);

		s_str2(5) <= conv_std_logic_vector((s_str2_int(5) + (s_str2_int(7)*wr8_2 - s_sti2_int(7)*wi8_2)), nb);
		s_sti2(5) <= conv_std_logic_vector((s_sti2_int(5) + (s_str2_int(7)*wi8_2 + s_sti2_int(7)*wr8_2)), nb);
		s_str2(7) <= conv_std_logic_vector((s_str2_int(5) - (s_str2_int(7)*wr8_2 + s_sti2_int(7)*wi8_2)), nb);
		s_sti2(7) <= conv_std_logic_vector((s_sti2_int(5) - (s_sti2_int(7)*wr8_2 - s_str2_int(7)*wi8_2)), nb);

		s_str3(0) <= conv_std_logic_vector((s_str3_int(0) + (s_str3_int(4)*wr8_0 - s_sti3_int(4)*wi8_0)), nb);
		s_sti3(0) <= conv_std_logic_vector((s_sti3_int(0) + (s_str3_int(4)*wi8_0 + s_sti3_int(4)*wr8_0)), nb);
		s_str3(4) <= conv_std_logic_vector((s_str3_int(0) - (s_str3_int(4)*wr8_0 + s_sti3_int(4)*wi8_0)), nb);
		s_sti3(4) <= conv_std_logic_vector((s_sti3_int(0) - (s_sti3_int(4)*wr8_0 - s_str3_int(4)*wi8_0)), nb);

		s_str3(1) <= conv_std_logic_vector((s_str3_int(1) + (s_str3_int(5)*wr8_1 - s_sti3_int(5)*wi8_1)), nb);
		s_sti3(1) <= conv_std_logic_vector((s_sti3_int(1) + (s_str3_int(5)*wi8_1 + s_sti3_int(5)*wr8_1)), nb);
		s_str3(5) <= conv_std_logic_vector((s_str3_int(1) - (s_str3_int(5)*wr8_1 + s_sti3_int(5)*wi8_1)), nb);
		s_sti3(5) <= conv_std_logic_vector((s_sti3_int(1) - (s_sti3_int(5)*wr8_1 - s_str3_int(5)*wi8_1)), nb);

		s_str3(2) <= conv_std_logic_vector((s_str3_int(2) + (s_str3_int(6)*wr8_2 - s_sti3_int(6)*wi8_2)), nb);
		s_sti3(2) <= conv_std_logic_vector((s_sti3_int(2) + (s_str3_int(6)*wi8_2 + s_sti3_int(6)*wr8_2)), nb);
		s_str3(6) <= conv_std_logic_vector((s_str3_int(2) - (s_str3_int(6)*wr8_2 + s_sti3_int(6)*wi8_2)), nb);
		s_sti3(6) <= conv_std_logic_vector((s_sti3_int(2) - (s_sti3_int(6)*wr8_2 - s_str3_int(6)*wi8_2)), nb);

		s_str3(3) <= conv_std_logic_vector((s_str3_int(3) + (s_str3_int(7)*wr8_3 - s_sti3_int(7)*wi8_3)), nb);
		s_sti3(3) <= conv_std_logic_vector((s_sti3_int(3) + (s_str3_int(7)*wi8_3 + s_sti3_int(7)*wr8_3)), nb);
		s_str3(7) <= conv_std_logic_vector((s_str3_int(3) - (s_str3_int(7)*wr8_3 + s_sti3_int(7)*wi8_3)), nb);
		s_sti3(7) <= conv_std_logic_vector((s_sti3_int(3) - (s_sti3_int(7)*wr8_3 - s_str3_int(7)*wi8_3)), nb);


end behavioural;

По прежнему не уверен с поворачивающими множителями и размерностями данных (промежуточных и выходных).

 

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

 

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

 

 

Помните, Вы на это тратите свое рабочее время, а все остальные - личное.

 

Share this post


Link to post
Share on other sites

Для справки, это не БПФ такой прожорливый - это код такой не оптимальный. Впрочем, на мой взгляд, Вам пока рано об этом задумываться. Сначала пусть все правильно заработает.

Код сделаю как надо, не проблема. Поторопился. Но пока с размерностями и со знаками лажа.

Переделаю, проверю, выложу.

 

Спасибо.

Share this post


Link to post
Share on other sites

Код переделал. Занимает 1800 ячеек. Если использовать DSP 1200.

Синус пока не подавал. Проверил по матлабу и симулятору Q9 - расчеты на первой стадии совпадают.

Полную симуляцию сделаю чуть позже. пока есть вопросы.

-- Бабочка (прореживание по времени)
-- A = x + Wn * y;
-- A_r + j*A_i = (x_r + j* x_i) + ( w_r + j*w_i) *(y_r + j*y_i);
-- A_r + j*A_i = (x_r + (w_r * y_r ) –( w_i *y_i)) + j*(x_i +( w_i *y_r) +( w_r * y_i));
-- A_r = x_r + (w_r * y_r ) –( w_i *y_i);
-- A_i = x_i +( w_i *y_r) +( w_r * y_i);
-- B = x - Wn * y;
-- B_r + j*B_i = (x_r + j* x_i) - ( w_r + j*w_i) *(y_r + j*y_i);
-- B_r + j*B_i = ( x_r - (w_r *y_r) + (w_i * y_i)) + (x_i – (w_r *y_i ) – (w_i * y_r ));
-- B_r =( x_r - (w_r *y_r) + (w_i * y_i);
-- B_i = x_i – (w_r * y_i ) – (w_i * y_r );

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

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_SIGNED.ALL;
use IEEE.numeric_std.all;

entity fft8vhd is
Generic (
	-- размерность входных данных
	b_size: natural := 15;
	-- размерность пов. множит
	w_size: natural := 12
	);
Port (
	-- тактовая частота
	clk : in std_logic;
	-- общий сброс
	rst	: in std_logic;
	-- входные данные реал
	dinr0	: in std_logic_vector(b_size downto 0);
	dinr1	: in std_logic_vector(b_size downto 0);
	dinr2	: in std_logic_vector(b_size downto 0);
	dinr3	: in std_logic_vector(b_size downto 0);
	dinr4	: in std_logic_vector(b_size downto 0);
	dinr5	: in std_logic_vector(b_size downto 0);
	dinr6	: in std_logic_vector(b_size downto 0);
	dinr7	: in std_logic_vector(b_size downto 0);
	-- входные данные мним
	dini0	: in std_logic_vector(b_size downto 0);
	dini1	: in std_logic_vector(b_size downto 0);
	dini2	: in std_logic_vector(b_size downto 0);
	dini3	: in std_logic_vector(b_size downto 0);
	dini4	: in std_logic_vector(b_size downto 0);
	dini5	: in std_logic_vector(b_size downto 0);
	dini6	: in std_logic_vector(b_size downto 0);
	dini7	: in std_logic_vector(b_size downto 0);
	-- импульс записи данных 
	wrdata	: in std_logic;

	-- выход счетчика стадий 
	ctfout	: out std_logic_vector(2 downto 0);
	-- выходы данных реал
	doutr0	: out std_logic_vector(b_size downto 0);
	doutr1	: out std_logic_vector(b_size downto 0);
	doutr2	: out std_logic_vector(b_size downto 0);
	doutr3	: out std_logic_vector(b_size downto 0);
	doutr4	: out std_logic_vector(b_size downto 0);
	doutr5	: out std_logic_vector(b_size downto 0);
	doutr6	: out std_logic_vector(b_size downto 0);
	doutr7	: out std_logic_vector(b_size downto 0);
	-- выходы данных мним
	douti0	: out std_logic_vector(b_size downto 0);
	douti1	: out std_logic_vector(b_size downto 0);
	douti2	: out std_logic_vector(b_size downto 0);
	douti3	: out std_logic_vector(b_size downto 0);
	douti4	: out std_logic_vector(b_size downto 0);
	douti5	: out std_logic_vector(b_size downto 0);
	douti6	: out std_logic_vector(b_size downto 0);
	douti7	: out std_logic_vector(b_size downto 0);

	-- тестовые выходы бабочки	
	dout_r_tst_up		: out std_logic_vector(b_size downto 0);
	dout_i_tst_up		: out std_logic_vector(b_size downto 0);
	dout_r_tst_down	: out std_logic_vector(b_size downto 0);
	dout_i_tst_down	: out std_logic_vector(b_size downto 0)
	);
end fft8vhd;

architecture behavioural of fft8vhd is
attribute multstyle : string;
-- на базе логики
attribute multstyle of behavioural : architecture is "logic";
-- на базе встроенных умножителей
--attribute multstyle of behavioural : architecture is "dsp";

-- счетчик стадий
signal s_ctf 	: std_logic_vector(2 downto 0);
-- признак загрузки данных 
signal s_ld 	: std_logic;
-- флаг разрешения преобразования
signal s_begpr 	: std_logic;
---------------------------------------------------------------
-- буферные сигналы реал
subtype sdbr is signed(b_size downto 0);
type memory_sdbr is array(7 downto 0) of sdbr;
signal s_in_r_sig : memory_sdbr;
-- буферные сигналы мним
subtype sdbi is signed(b_size downto 0);
type memory_sdbi is array(7 downto 0) of sdbi;
signal s_in_i_sig : memory_sdbi;
-----------------------------------------------------------------
-- сигналы умножения 1_ой стадии реал
subtype mult1_re_sig is signed(b_size + w_size + 1 downto 0);
type memory_mult1_re_sig is array(3 downto 0) of mult1_re_sig;
signal s_mult1_re_sig : memory_mult1_re_sig;
-- сигналы умножения 1_ой стадии мним
subtype mult1_im_sig is signed(b_size + w_size + 1 downto 0);
type memory_mult1_im_sig is array(3 downto 0) of mult1_im_sig;
signal s_mult1_im_sig : memory_mult1_im_sig;

-- сигналы суммы 1_ой стадии реал
subtype sum1_re_sig is signed(b_size downto 0);
type memory_sum1_re_sig is array(7 downto 0) of sum1_re_sig;
signal s_sum1_re_sig : memory_sum1_re_sig;
-- сигналы суммы 1_ой стадии мним
subtype sum1_im_sig is signed(b_size downto 0);
type memory_sum1_im_sig is array(7 downto 0) of sum1_im_sig;
signal s_sum1_im_sig : memory_sum1_im_sig;
-------------------------------------------------------------------
-- сигналы умножения 2_ой стадии реал
subtype mult2_re_sig is signed(b_size + w_size + 1 downto 0);
type memory_mult2_re_sig is array(3 downto 0) of mult2_re_sig;
signal s_mult2_re_sig : memory_mult2_re_sig;
-- сигналы умножения 2_ой стадии мним
subtype mult2_im_sig is signed(b_size + w_size + 1 downto 0);
type memory_mult2_im_sig is array(3 downto 0) of mult2_im_sig;
signal s_mult2_im_sig : memory_mult2_im_sig;

-- сигналы суммы 2_ой стадии реал
subtype sum2_re_sig is signed(b_size downto 0);
type memory_sum2_re_sig is array(7 downto 0) of sum2_re_sig;
signal s_sum2_re_sig : memory_sum2_re_sig;
-- сигналы суммы 2_ой стадии мним
subtype sum2_im_sig is signed(b_size downto 0);
type memory_sum2_im_sig is array(7 downto 0) of sum2_im_sig;
signal s_sum2_im_sig : memory_sum2_im_sig;
-----------------------------------------------------------------
-- сигналы умножения 3_й стадии реал
subtype mult3_re_sig is signed(b_size + w_size + 1 downto 0);
type memory_mult3_re_sig is array(3 downto 0) of mult3_re_sig;
signal s_mult3_re_sig : memory_mult3_re_sig;
-- сигналы умножения 3_й стадии мним
subtype mult3_im_sig is signed(b_size + w_size + 1 downto 0);
type memory_mult3_im_sig is array(3 downto 0) of mult3_im_sig;
signal s_mult3_im_sig : memory_mult3_im_sig;

-- сигналы суммы 3_й стадии реал
subtype sum3_re_sig is signed(b_size downto 0);
type memory_sum3_re_sig is array(7 downto 0) of sum3_re_sig;
signal s_sum3_re_sig : memory_sum3_re_sig;
-- сигналы суммы 3_й стадии мним
subtype sum3_im_sig is signed(b_size downto 0);
type memory_sum3_im_sig is array(7 downto 0) of sum3_im_sig;
signal s_sum3_im_sig : memory_sum3_im_sig;

-----------------------------------------------------------

-- сигналы для поворачивающих множителей реал
signal s_w_r_8_0_sig: signed(w_size - 1 downto 0);
signal s_w_r_8_1_sig: signed(w_size - 1 downto 0);
signal s_w_r_8_2_sig: signed(w_size - 1 downto 0);
signal s_w_r_8_3_sig: signed(w_size - 1 downto 0);
-- сигналы для поворачивающих множителей мним
signal s_w_i_8_0_sig: signed(w_size - 1 downto 0);
signal s_w_i_8_1_sig: signed(w_size - 1 downto 0);
signal s_w_i_8_2_sig: signed(w_size - 1 downto 0);
signal s_w_i_8_3_sig: signed(w_size - 1 downto 0);

-- поворачивающие множители
-- round(cos(2*pi*n/8)*1024)
-- round(sin(2*pi*n/8)*1024)
-- n = 0...3
-- реал
constant c_w_r_8_0  : integer := 1024;	
constant c_w_r_8_1  : integer := 724;	
constant c_w_r_8_2  : integer := 0;	
constant c_w_r_8_3  : integer := -724;	
-- мним
constant c_w_i_8_0  : integer := 0;	
constant c_w_i_8_1  : integer := 724;	
constant c_w_i_8_2  : integer := 1024;	
constant c_w_i_8_3  : integer := 724;	

begin

-- счетчик стадий
process(clk, s_ctf)
begin
if clk'event and clk = '0' then
	if rst = '0' then	
		s_ctf <= (others => '0');
		s_begpr <= '0';
	elsif s_ld = '1' and s_begpr = '0' then 
		s_begpr <= '1';
	end if;
	if s_begpr = '1' then	
		s_ctf <= s_ctf + 1;	
		if s_ctf = 7 then
			s_ctf <= (others => '0');
			s_begpr <= '0';
		end if;	
	end if;
end if;

ctfout <= s_ctf;

end process;		

-- загрузка данных
process(clk)
begin
if clk'event and clk = '1' then
	if rst = '0' or s_ctf = 7 then	
		s_ld <= '0';
	elsif wrdata = '1' and s_ld = '0' then 
		-- реал входные данные
		s_in_r_sig(0) <= signed(dinr0);
		s_in_r_sig(1) <= signed(dinr1);
		s_in_r_sig(2) <= signed(dinr2);
		s_in_r_sig(3) <= signed(dinr3);
		s_in_r_sig(4) <= signed(dinr4);
		s_in_r_sig(5) <= signed(dinr5);
		s_in_r_sig(6) <= signed(dinr6);
		s_in_r_sig(7) <= signed(dinr7);
		-- мним входные данные
		s_in_i_sig(0) <= signed(dini0);
		s_in_i_sig(1) <= signed(dini1);
		s_in_i_sig(2) <= signed(dini2);
		s_in_i_sig(3) <= signed(dini3);
		s_in_i_sig(4) <= signed(dini4);
		s_in_i_sig(5) <= signed(dini5);
		s_in_i_sig(6) <= signed(dini6);
		s_in_i_sig(7) <= signed(dini7);
		-- реал поворачивающие множители
		s_w_r_8_0_sig <= to_signed(c_w_r_8_0, w_size);
		s_w_r_8_1_sig <= to_signed(c_w_r_8_1, w_size);
		s_w_r_8_2_sig <= to_signed(c_w_r_8_2, w_size);
		s_w_r_8_3_sig <= to_signed(c_w_r_8_3, w_size);
		-- мним поворачивающие множители
		s_w_i_8_0_sig <= to_signed(c_w_i_8_0, w_size);
		s_w_i_8_1_sig <= to_signed(c_w_i_8_1, w_size);
		s_w_i_8_2_sig <= to_signed(c_w_i_8_2, w_size);
		s_w_i_8_3_sig <= to_signed(c_w_i_8_3, w_size);
		-- загрузка состоялась
		s_ld <= '1';
	end if;
end if;

end process;	

-- операция fft8 (прореживание по времени)
-- A_r = x_r + (w_r * y_r) – ( w_i * y_i);
-- A_i = x_i + (w_i * y_r) + ( w_r * y_i);
process(clk, s_sum3_re_sig, s_sum3_im_sig, s_sum1_re_sig, s_sum1_im_sig)
begin
if clk'event and clk = '1' then
	-- 1_я стадия fft8 s_ctf = 1,2
	if s_ctf = 1 and s_begpr = '1' then
		-- комплексное умножение 1_я стадия (результат в b_size + w_size + 2)
		-- 1_я бабочка
		s_mult1_re_sig(0) <= resize(s_in_r_sig(4)*s_w_r_8_0_sig, b_size + w_size + 2) - resize(s_in_i_sig(4)*s_w_i_8_0_sig, b_size + w_size + 2);
		s_mult1_im_sig(0) <= resize(s_in_r_sig(4)*s_w_i_8_0_sig, b_size + w_size + 2) + resize(s_in_i_sig(4)*s_w_r_8_0_sig, b_size + w_size + 2);
		-- 2_я бабочка
		s_mult1_re_sig(1) <= resize(s_in_r_sig(6)*s_w_r_8_0_sig, b_size + w_size + 2) - resize(s_in_i_sig(6)*s_w_i_8_0_sig, b_size + w_size + 2);
		s_mult1_im_sig(1) <= resize(s_in_r_sig(6)*s_w_i_8_0_sig, b_size + w_size + 2) + resize(s_in_i_sig(6)*s_w_r_8_0_sig, b_size + w_size + 2);
		-- 3_я бабочка
		s_mult1_re_sig(2) <= resize(s_in_r_sig(5)*s_w_r_8_0_sig, b_size + w_size + 2) - resize(s_in_i_sig(5)*s_w_i_8_0_sig, b_size + w_size + 2);
		s_mult1_im_sig(2) <= resize(s_in_r_sig(5)*s_w_i_8_0_sig, b_size + w_size + 2) + resize(s_in_i_sig(5)*s_w_r_8_0_sig, b_size + w_size + 2);
		-- 4_я бабочка
		s_mult1_re_sig(3) <= resize(s_in_r_sig(7)*s_w_r_8_0_sig, b_size + w_size + 2) - resize(s_in_i_sig(7)*s_w_i_8_0_sig, b_size + w_size + 2);
		s_mult1_im_sig(3) <= resize(s_in_r_sig(7)*s_w_i_8_0_sig, b_size + w_size + 2) + resize(s_in_i_sig(7)*s_w_r_8_0_sig, b_size + w_size + 2);

	elsif s_ctf = 2 and s_begpr = '1' then
		-- комплексное суммирование 1-я стадия (результат в b_size)
		-- 0_вой выход 1_ой стадии
		s_sum1_re_sig(0) <= s_in_r_sig(0) + s_mult1_re_sig(0)(b_size + w_size - 2 downto w_size - 2);
		s_sum1_im_sig(0) <= s_in_i_sig(0) + s_mult1_im_sig(0)(b_size + w_size - 2 downto w_size - 2);
		-- 1_вый выход 1_ой стадии
		s_sum1_re_sig(1) <= s_in_r_sig(0) - s_mult1_re_sig(0)(b_size + w_size - 2 downto w_size - 2);
		s_sum1_im_sig(1) <= s_in_i_sig(0) - s_mult1_im_sig(0)(b_size + w_size - 2 downto w_size - 2);

		-- 2_ой выход 1_ой стадии
		s_sum1_re_sig(2) <= s_in_r_sig(2) + s_mult1_re_sig(1)(b_size + w_size - 2 downto w_size - 2);
		s_sum1_im_sig(2) <= s_in_i_sig(2) + s_mult1_im_sig(1)(b_size + w_size - 2 downto w_size - 2);
		-- 3_ий выход 1_ой стадии
		s_sum1_re_sig(3) <= s_in_r_sig(2) - s_mult1_re_sig(1)(b_size + w_size - 2 downto w_size - 2);
		s_sum1_im_sig(3) <= s_in_i_sig(2) - s_mult1_im_sig(1)(b_size + w_size - 2 downto w_size - 2);

		-- 4_ый выход 1_ой стадии
		s_sum1_re_sig(4) <= s_in_r_sig(1) + s_mult1_re_sig(2)(b_size + w_size - 2 downto w_size - 2);
		s_sum1_im_sig(4) <= s_in_i_sig(1) + s_mult1_im_sig(2)(b_size + w_size - 2 downto w_size - 2);
		-- 5_ый выход 1_ой стадии
		s_sum1_re_sig(5) <= s_in_r_sig(1) - s_mult1_re_sig(2)(b_size + w_size - 2 downto w_size - 2);
		s_sum1_im_sig(5) <= s_in_i_sig(1) - s_mult1_im_sig(2)(b_size + w_size - 2 downto w_size - 2);

		-- 6_ой выход 1_ой стадии
		s_sum1_re_sig(6) <= s_in_r_sig(3) + s_mult1_re_sig(3)(b_size + w_size - 2 downto w_size - 2);
		s_sum1_im_sig(6) <= s_in_i_sig(3) + s_mult1_im_sig(3)(b_size + w_size - 2 downto w_size - 2);
		-- 7_ой выход 1_ой стадии
		s_sum1_re_sig(7) <= s_in_r_sig(3) - s_mult1_re_sig(3)(b_size + w_size - 2 downto w_size - 2);
		s_sum1_im_sig(7) <= s_in_i_sig(3) - s_mult1_im_sig(3)(b_size + w_size - 2 downto w_size - 2);

---------------------------------------------------------------------------------------

	-- 2_я стадия fft8 s_ctf = 3,4
	elsif (s_ctf = 3) and s_begpr = '1' then
		-- комплексное умножение 2_я стадия (результат в b_size + w_size + 2)
		-- 1_я бабочка
		s_mult2_re_sig(0) <= resize(s_sum1_re_sig(2)*s_w_r_8_0_sig, b_size + w_size + 2) - resize(s_sum1_im_sig(2)*s_w_i_8_0_sig, b_size + w_size + 2);
		s_mult2_im_sig(0) <= resize(s_sum1_re_sig(2)*s_w_i_8_0_sig, b_size + w_size + 2) + resize(s_sum1_im_sig(2)*s_w_r_8_0_sig, b_size + w_size + 2);
		-- 2_я бабочка
		s_mult2_re_sig(1) <= resize(s_sum1_re_sig(3)*s_w_r_8_2_sig, b_size + w_size + 2) - resize(s_sum1_im_sig(3)*s_w_i_8_2_sig, b_size + w_size + 2);
		s_mult2_im_sig(1) <= resize(s_sum1_re_sig(3)*s_w_i_8_2_sig, b_size + w_size + 2) + resize(s_sum1_im_sig(3)*s_w_r_8_2_sig, b_size + w_size + 2);
		-- 3_я бабочка
		s_mult2_re_sig(2) <= resize(s_sum1_re_sig(6)*s_w_r_8_0_sig, b_size + w_size + 2) - resize(s_sum1_im_sig(6)*s_w_i_8_0_sig, b_size + w_size + 2);
		s_mult2_im_sig(2) <= resize(s_sum1_re_sig(6)*s_w_i_8_0_sig, b_size + w_size + 2) + resize(s_sum1_im_sig(6)*s_w_r_8_0_sig, b_size + w_size + 2);
		-- 4_я бабочка
		s_mult2_re_sig(3) <= resize(s_sum1_re_sig(7)*s_w_r_8_2_sig, b_size + w_size + 2) - resize(s_sum1_im_sig(7)*s_w_i_8_2_sig, b_size + w_size + 2);
		s_mult2_im_sig(3) <= resize(s_sum1_re_sig(7)*s_w_i_8_2_sig, b_size + w_size + 2) + resize(s_sum1_im_sig(7)*s_w_r_8_2_sig, b_size + w_size + 2);

	elsif s_ctf = 4 and s_begpr = '1' then
		-- комплексное суммирование 2_я стадия (результат в b_size)
		-- 0_вой выход 2_й стадии
		s_sum2_re_sig(0) <= s_sum1_re_sig(0) + s_mult2_re_sig(0)(b_size + w_size - 2 downto w_size - 2);
		s_sum2_im_sig(0) <= s_sum1_im_sig(0) + s_mult2_im_sig(0)(b_size + w_size - 2 downto w_size - 2);
		-- 2_ой выход 2_ой стадии
		s_sum2_re_sig(2) <= s_sum1_re_sig(0) - s_mult2_re_sig(0)(b_size + w_size - 2 downto w_size - 2);
		s_sum2_im_sig(2) <= s_sum1_re_sig(0) - s_mult2_im_sig(0)(b_size + w_size - 2 downto w_size - 2);

		-- 1_й выход 2_й стадии
		s_sum2_re_sig(1) <= s_sum1_re_sig(1) + s_mult2_re_sig(1)(b_size + w_size - 2 downto w_size - 2);
		s_sum2_im_sig(1) <= s_sum1_im_sig(1) + s_mult2_im_sig(1)(b_size + w_size - 2 downto w_size - 2);
		-- 3_й выход 2_ой стадии
		s_sum2_re_sig(3) <= s_sum1_re_sig(1) - s_mult2_re_sig(1)(b_size + w_size - 2 downto w_size - 2);
		s_sum2_im_sig(3) <= s_sum1_re_sig(1) - s_mult2_im_sig(1)(b_size + w_size - 2 downto w_size - 2);

		-- 4_й выход 2_й стадии
		s_sum2_re_sig(4) <= s_sum1_re_sig(4) + s_mult2_re_sig(2)(b_size + w_size - 2 downto w_size - 2);
		s_sum2_im_sig(4) <= s_sum1_im_sig(4) + s_mult2_im_sig(2)(b_size + w_size - 2 downto w_size - 2);
		-- 6_й выход 2_ой стадии
		s_sum2_re_sig(6) <= s_sum1_re_sig(4) - s_mult2_re_sig(2)(b_size + w_size - 2 downto w_size - 2);
		s_sum2_im_sig(6) <= s_sum1_re_sig(4) - s_mult2_im_sig(2)(b_size + w_size - 2 downto w_size - 2);

		-- 5_й выход 2_й стадии
		s_sum2_re_sig(5) <= s_sum1_re_sig(5) + s_mult2_re_sig(3)(b_size + w_size - 2 downto w_size - 2);
		s_sum2_im_sig(5) <= s_sum1_im_sig(5) + s_mult2_im_sig(3)(b_size + w_size - 2 downto w_size - 2);
		-- 7_й выход 2_ой стадии
		s_sum2_re_sig(7) <= s_sum1_re_sig(5) - s_mult2_re_sig(3)(b_size + w_size - 2 downto w_size - 2);
		s_sum2_im_sig(7) <= s_sum1_re_sig(5) - s_mult2_im_sig(3)(b_size + w_size - 2 downto w_size - 2);

---------------------------------------------------------------------------------------

	-- 3_я стадия fft8 s_ctf = 5,6
	elsif (s_ctf = 5) and s_begpr = '1' then
		-- комплексное умножение 3_я стадия (результат в b_size + w_size + 2)
		-- 1_я бабочка
		s_mult3_re_sig(0) <= resize(s_sum2_re_sig(4)*s_w_r_8_0_sig, b_size + w_size + 2) - resize(s_sum2_im_sig(4)*s_w_i_8_0_sig, b_size + w_size + 2);
		s_mult3_im_sig(0) <= resize(s_sum2_re_sig(4)*s_w_i_8_0_sig, b_size + w_size + 2) + resize(s_sum2_im_sig(4)*s_w_r_8_0_sig, b_size + w_size + 2);
		-- 2_я бабочка
		s_mult3_re_sig(1) <= resize(s_sum2_re_sig(5)*s_w_r_8_1_sig, b_size + w_size + 2) - resize(s_sum2_im_sig(5)*s_w_i_8_1_sig, b_size + w_size + 2);
		s_mult3_im_sig(1) <= resize(s_sum2_re_sig(5)*s_w_i_8_1_sig, b_size + w_size + 2) + resize(s_sum2_im_sig(5)*s_w_r_8_1_sig, b_size + w_size + 2);
		-- 3_я бабочка
		s_mult3_re_sig(2) <= resize(s_sum2_re_sig(6)*s_w_r_8_2_sig, b_size + w_size + 2) - resize(s_sum2_im_sig(6)*s_w_i_8_2_sig, b_size + w_size + 2);
		s_mult3_im_sig(2) <= resize(s_sum2_re_sig(6)*s_w_i_8_2_sig, b_size + w_size + 2) + resize(s_sum2_im_sig(6)*s_w_r_8_2_sig, b_size + w_size + 2);
		-- 4_я бабочка
		s_mult3_re_sig(3) <= resize(s_sum2_re_sig(7)*s_w_r_8_3_sig, b_size + w_size + 2) - resize(s_sum2_im_sig(7)*s_w_i_8_3_sig, b_size + w_size + 2);
		s_mult3_im_sig(3) <= resize(s_sum2_re_sig(7)*s_w_i_8_3_sig, b_size + w_size + 2) + resize(s_sum2_im_sig(7)*s_w_r_8_3_sig, b_size + w_size + 2);

	elsif s_ctf = 6 and s_begpr = '1' then
		-- комплексное суммирование 3_я стадия (результат в b_size)
		-- 0_вой выход 3_й стадии
		s_sum3_re_sig(0) <= s_sum2_re_sig(0) + s_mult3_re_sig(0)(b_size + w_size - 2 downto w_size - 2);
		s_sum3_im_sig(0) <= s_sum2_im_sig(0) + s_mult3_im_sig(0)(b_size + w_size - 2 downto w_size - 2);
		-- 1_ой выход 3_ой стадии
		s_sum3_re_sig(1) <= s_sum2_re_sig(1) + s_mult3_re_sig(1)(b_size + w_size - 2 downto w_size - 2);
		s_sum3_im_sig(1) <= s_sum2_re_sig(1) + s_mult3_im_sig(1)(b_size + w_size - 2 downto w_size - 2);

		-- 2_й выход 3_й стадии
		s_sum3_re_sig(2) <= s_sum1_re_sig(2) + s_mult3_re_sig(2)(b_size + w_size - 2 downto w_size - 2);
		s_sum3_im_sig(2) <= s_sum1_im_sig(2) + s_mult3_im_sig(2)(b_size + w_size - 2 downto w_size - 2);
		-- 3_й выход 3_ой стадии
		s_sum3_re_sig(3) <= s_sum1_re_sig(3) + s_mult3_re_sig(3)(b_size + w_size - 2 downto w_size - 2);
		s_sum3_im_sig(3) <= s_sum1_re_sig(3) + s_mult3_im_sig(3)(b_size + w_size - 2 downto w_size - 2);

		-- 4_й выход 3_й стадии
		s_sum3_re_sig(4) <= s_sum1_re_sig(0) - s_mult3_re_sig(0)(b_size + w_size - 2 downto w_size - 2);
		s_sum3_im_sig(4) <= s_sum1_im_sig(0) - s_mult3_im_sig(0)(b_size + w_size - 2 downto w_size - 2);
		-- 5_й выход 3_ой стадии
		s_sum3_re_sig(5) <= s_sum1_re_sig(1) - s_mult3_re_sig(1)(b_size + w_size - 2 downto w_size - 2);
		s_sum3_im_sig(5) <= s_sum1_re_sig(1) - s_mult3_im_sig(1)(b_size + w_size - 2 downto w_size - 2);

		-- 6_й выход 3_й стадии
		s_sum3_re_sig(6) <= s_sum1_re_sig(2) - s_mult3_re_sig(2)(b_size + w_size - 2 downto w_size - 2);
		s_sum3_im_sig(6) <= s_sum1_im_sig(2) - s_mult3_im_sig(2)(b_size + w_size - 2 downto w_size - 2);
		-- 7_й выход 3_ой стадии
		s_sum3_re_sig(7) <= s_sum1_re_sig(3) - s_mult3_re_sig(3)(b_size + w_size - 2 downto w_size - 2);
		s_sum3_im_sig(7) <= s_sum1_re_sig(3) - s_mult3_im_sig(3)(b_size + w_size - 2 downto w_size - 2);

	end if;	 
end if; 

-- выходной результат 
doutr0 <= std_logic_vector(s_sum3_re_sig(0));
doutr1 <= std_logic_vector(s_sum3_re_sig(1));
doutr2 <= std_logic_vector(s_sum3_re_sig(2));
doutr3 <= std_logic_vector(s_sum3_re_sig(3));
doutr4 <= std_logic_vector(s_sum3_re_sig(4));
doutr5 <= std_logic_vector(s_sum3_re_sig(5));
doutr6 <= std_logic_vector(s_sum3_re_sig(6));
doutr7 <= std_logic_vector(s_sum3_re_sig(7));

douti0 <= std_logic_vector(s_sum3_im_sig(0));
douti1 <= std_logic_vector(s_sum3_im_sig(1));
douti2 <= std_logic_vector(s_sum3_im_sig(2));
douti3 <= std_logic_vector(s_sum3_im_sig(3));
douti4 <= std_logic_vector(s_sum3_im_sig(4));
douti5 <= std_logic_vector(s_sum3_im_sig(5));
douti6 <= std_logic_vector(s_sum3_im_sig(6));
douti7 <= std_logic_vector(s_sum3_im_sig(7));


-- тестовые выходы бабочи
dout_r_tst_up <= std_logic_vector(s_sum1_re_sig(0));
dout_i_tst_up <= std_logic_vector(s_sum1_im_sig(0));
dout_r_tst_down <= std_logic_vector(s_sum1_re_sig(1));
dout_i_tst_down <= std_logic_vector(s_sum1_im_sig(1));

end process;	

end behavioural;

Со знаками вроде нормально. С размерностями данных не уверен.

Входные данные имеют размерность 16 бит. После первой стадии выходной результат тоже сделал 16 бит. После второй и третьей тоже самое.

Получается выходной результат fft8 16 бит. Не уверен правильно-ли это. Прошу подсказать.

Share this post


Link to post
Share on other sites

Со знаками вроде нормально. С размерностями данных не уверен.

Входные данные имеют размерность 16 бит. После первой стадии выходной результат тоже сделал 16 бит. После второй и третьей тоже самое.

Получается выходной результат fft8 16 бит. Не уверен правильно-ли это. Прошу подсказать.

 

Про разрядности все было разобрано здесь

 

Думаю, для вашей задачи точность не очень нужна, особенно при использовании КИХ и если их параметры правильно выбраны.

Share this post


Link to post
Share on other sites

Про разрядности все было разобрано здесь

 

Думаю, для вашей задачи точность не очень нужна, особенно при использовании КИХ и если их параметры правильно выбраны.

Понятно. Спасибо.

По поводу проверки. Как организовать?

Пока пользуюсь встроенным симулятором Q9.

В матлабе вычисляю синус (косинус) 8 значений на период (через 45 град).

Типа так

fprintf('sin \n'); 
for s = 0:7;
  s_in_r_sig(s+1) = sin(s*pi/4)*1024; 
  z = s_in_r_sig(s+1);
  fprintf('%d\n', s, z); 
end;
fprintf('cos \n'); 
for s = 0:7;
  s_in_i_sig(s+1) = cos(s*pi/4)*1024; 
  z = s_in_i_sig(s+1);
  fprintf('%d\n', s, z); 
end;

Подаю (в симуляторе) на реал и имаг входы fft8 - получаю результат.

Как можно то же (fft8) проделать в матлаб c получением результата (реал и имаг), чтобы сравнить с Q9?

Пробовал типа так

n = 0:7;
x1 = sin(n*pi/4);
N = 8;
X = abs(fft(x1,N));
Y = X*1024;

В массиве Y комплексные значения.

Share this post


Link to post
Share on other sites

Пробовал типа так

n = 0:7;
x1 = sin(n*pi/4);
N = 8;
X = abs(fft(x1,N));
Y = X*1024;

В массиве Y комплексные значения.

 

Непонятно, где Вы там увидели комплексные значения. Загнал в Матлаб ваш код и получил:

post-7537-1379342404_thumb.jpg

 

Правда Вам нужно сравнивать выход БПФ-8 с fft(x1,N), а не с abs(fft(x1,N)) т.к. на выходе БПФ-8 у Вас комплексные числа, которые пойдут на следующую бабочку. Сумму квадратов считать надо на выходе БПФ-32, а не на промежуточных этапах.

 

Кстати, в Матлаб достаточно написать просто fft(x1). Если х1 имеет N элементов то FFT тоже будет FFT-N.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...