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

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

И тем не менее БПФ всеравно делать нужно. Кроме того этот раздел форума на тему VHDL. Привожу код первого этапа.

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

entity fft8ct is
Generic (
	-- input data bit width
	nb : natural := 16
	);
Port (
	-- тактовая частота
	clk : in std_logic;
	-- общий сброс
	rst	: in std_logic;
	-- переключатель rel img 
	dir	: in std_logic;
	-- импульс записи данных 
	load	: in std_logic;
	-- строб разрешения зап. данных 
	ready	: in std_logic;
	-- вход данных 
	dinr	: in std_logic_vector(nb-1 downto 0);

	-- выходы счетчика 
	ctfout	: out std_logic_vector(4 downto 0);
	-- выходы данных 
	dout0	: out std_logic_vector(nb-1 downto 0);
	dout1	: out std_logic_vector(nb-1 downto 0);
	dout2	: out std_logic_vector(nb-1 downto 0);
	dout3	: out std_logic_vector(nb-1 downto 0);
	dout4	: out std_logic_vector(nb-1 downto 0);
	dout5	: out std_logic_vector(nb-1 downto 0);
	dout6	: out std_logic_vector(nb-1 downto 0);
	dout7	: out std_logic_vector(nb-1 downto 0);
	dout8	: out std_logic_vector(nb-1 downto 0);
	dout9	: out std_logic_vector(nb-1 downto 0);
	dout10	: out std_logic_vector(nb-1 downto 0);
	dout11	: out std_logic_vector(nb-1 downto 0);
	dout12	: out std_logic_vector(nb-1 downto 0);
	dout13	: out std_logic_vector(nb-1 downto 0);
	dout14	: out std_logic_vector(nb-1 downto 0);
	dout15	: out std_logic_vector(nb-1 downto 0);
	dout16	: out std_logic_vector(nb-1 downto 0);
	dout17	: out std_logic_vector(nb-1 downto 0);
	dout18	: out std_logic_vector(nb-1 downto 0);
	dout19	: out std_logic_vector(nb-1 downto 0);
	dout20	: out std_logic_vector(nb-1 downto 0);
	dout21	: out std_logic_vector(nb-1 downto 0);
	dout22	: out std_logic_vector(nb-1 downto 0);
	dout23	: out std_logic_vector(nb-1 downto 0);
	dout24	: out std_logic_vector(nb-1 downto 0);
	dout25	: out std_logic_vector(nb-1 downto 0);
	dout26	: out std_logic_vector(nb-1 downto 0);
	dout27	: out std_logic_vector(nb-1 downto 0);
	dout28	: out std_logic_vector(nb-1 downto 0);
	dout29	: out std_logic_vector(nb-1 downto 0);
	dout30	: out std_logic_vector(nb-1 downto 0);
	dout31	: 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 ctrd		: std_logic_vector(4 downto 0);	
-- счетчик стадий преобразований fft8
signal ctf		: std_logic_vector(4 downto 0);	
-- флаг завершения загрузки
signal endrd	: std_logic;	
signal begrd	: std_logic;	
-- флаг начала преобразования
signal begpr	: std_logic;	

-- сигналы входные
subtype sd is std_logic_vector(nb-1 downto 0);
type memory_sd is array(31 downto 0) of sd;
signal s_dinr : memory_sd;

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

-- сигналы 1_й стади
signal s_st1_0 : std_logic_vector(nb-1 downto 0);	
signal s_st1_1 : std_logic_vector(nb-1 downto 0);	
signal s_st1_2 : std_logic_vector(nb-1 downto 0);	
signal s_st1_3 : std_logic_vector(nb-1 downto 0);	
signal s_st1_4 : std_logic_vector(nb-1 downto 0);	
signal s_st1_5 : std_logic_vector(nb-1 downto 0);	
signal s_st1_6 : std_logic_vector(nb-1 downto 0);	
signal s_st1_7 : std_logic_vector(nb-1 downto 0);	
-- сигналы 2_й стади
signal s_st2_0 : std_logic_vector(nb-1 downto 0);		
signal s_st2_1 : std_logic_vector(nb-1 downto 0);	
signal s_st2_2 : std_logic_vector(nb-1 downto 0);	
signal s_st2_3 : std_logic_vector(nb-1 downto 0);	
signal s_st2_4 : std_logic_vector(nb-1 downto 0);	
signal s_st2_5 : std_logic_vector(nb-1 downto 0);	
signal s_st2_6 : std_logic_vector(nb-1 downto 0);	
signal s_st2_7 : std_logic_vector(nb-1 downto 0);	
-- сигналы 3_й стади
signal s_st3_0 : std_logic_vector(nb-1 downto 0);	
signal s_st3_1 : std_logic_vector(nb-1 downto 0);	
signal s_st3_2 : std_logic_vector(nb-1 downto 0);	
signal s_st3_3 : std_logic_vector(nb-1 downto 0);	
signal s_st3_4 : std_logic_vector(nb-1 downto 0);	
signal s_st3_5 : std_logic_vector(nb-1 downto 0);	
signal s_st3_6 : std_logic_vector(nb-1 downto 0);	
signal s_st3_7 : std_logic_vector(nb-1 downto 0);	

-- промежуточные int сигналы 1_я стадия
signal s_st1_0_int : integer range -8192 to 8191;
signal s_st1_1_int : integer range -8192 to 8191;
signal s_st1_2_int : integer range -8192 to 8191;
signal s_st1_3_int : integer range -8192 to 8191;
signal s_st1_4_int : integer range -8192 to 8191;
signal s_st1_5_int : integer range -8192 to 8191;
signal s_st1_6_int : integer range -8192 to 8191;
signal s_st1_7_int : integer range -8192 to 8191;

-- промежуточные int сигналы 2_я стадия
signal s_st2_0_int : integer range -8192 to 8191;
signal s_st2_1_int : integer range -8192 to 8191;
signal s_st2_2_int : integer range -8192 to 8191;
signal s_st2_3_int : integer range -8192 to 8191;
signal s_st2_4_int : integer range -8192 to 8191;
signal s_st2_5_int : integer range -8192 to 8191;
signal s_st2_6_int : integer range -8192 to 8191;
signal s_st2_7_int : integer range -8192 to 8191;

-- поворачивающие множители
-- 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

-- загрузка данных в регистровый файл
-- 32 положит. импульса load
process(clk )
begin
if clk'event and clk = '1' then
	if rst = '0' or begrd = '0' then	
		ctrd <= (others => '0'); 
		endrd <= '0';
		begrd <= '1';
	elsif ready = '1' then	 
		if load = '1' then
			ctrd <= ctrd + 1;
			s_dinr(31) <= dinr;
			s_dinr(30) <= s_dinr(31);	
			s_dinr(29) <= s_dinr(30);	
			s_dinr(28) <= s_dinr(29);	
			s_dinr(27) <= s_dinr(28);	
			s_dinr(26) <= s_dinr(27);	
			s_dinr(25) <= s_dinr(26);	
			s_dinr(24) <= s_dinr(25);	
			s_dinr(23) <= s_dinr(24);	
			s_dinr(22) <= s_dinr(23);	
			s_dinr(21) <= s_dinr(22);	
			s_dinr(20) <= s_dinr(21);	
			s_dinr(19) <= s_dinr(20);	
			s_dinr(18) <= s_dinr(19);	
			s_dinr(17) <= s_dinr(18);	
			s_dinr(16) <= s_dinr(17);	
			s_dinr(15) <= s_dinr(16);	
			s_dinr(14) <= s_dinr(15);	
			s_dinr(13) <= s_dinr(14);	
			s_dinr(12) <= s_dinr(13);	
			s_dinr(11) <= s_dinr(12);	
			s_dinr(10) <= s_dinr(11);	
			s_dinr(9) <= s_dinr(10);	
			s_dinr(8) <= s_dinr(9);	
			s_dinr(7) <= s_dinr(8);	
			s_dinr(6) <= s_dinr(7);	
			s_dinr(5) <= s_dinr(6);	
			s_dinr(4) <= s_dinr(5);	
			s_dinr(3) <= s_dinr(4);	
			s_dinr(2) <= s_dinr(3);	
			s_dinr(1) <= s_dinr(2);	
			s_dinr(0) <= s_dinr(1);
			-- загрузка завершена	
			if ctrd = 31 then
				endrd <= '1';
				begrd <= '0';
			end if;	
		end if;
	end if;
end if;

end process;

-- счетчик стадий fft
process(clk, ctf)
begin
if clk'event and clk = '0' then
	if rst = '0' then	
		ctf <= (others => '0');
	-- если все загружено	
	elsif endrd = '1' then 
		-- устан. флаг разр. нач. преобр.
		begpr <= '1';	
	end if;
	if begpr = '1' then		
		ctf <= ctf + 1;	
		if ctf = 16 then
			begpr <= '0';
			ctf <= (others => '0');
		end if;	
	end if;
end if;
-- выход счетчика
ctfout <= ctf;

end process;		

-- мильтиплексор с битреверсом
process(clk)
begin
if clk'event and clk = '1' then
	-- если все загружено
	if begpr = '1' then 
	case ctf is
		when "00000" =>
				s_dbr(0) <= s_dinr(0);
				s_dbr(1) <= s_dinr(4);
				s_dbr(2) <= s_dinr(8);
				s_dbr(3) <= s_dinr(12);
				s_dbr(4) <= s_dinr(16);
				s_dbr(5) <= s_dinr(20);
				s_dbr(6) <= s_dinr(24);
				s_dbr(7) <= s_dinr(28);
		when "00100" =>
				s_dbr(0) <= s_dinr(1);
				s_dbr(1) <= s_dinr(5);
				s_dbr(2) <= s_dinr(9);
				s_dbr(3) <= s_dinr(13);
				s_dbr(4) <= s_dinr(17);
				s_dbr(5) <= s_dinr(21);
				s_dbr(6) <= s_dinr(25);
				s_dbr(7) <= s_dinr(29);
		when "01000" =>
				s_dbr(0) <= s_dinr(2);
				s_dbr(1) <= s_dinr(6);
				s_dbr(2) <= s_dinr(10);
				s_dbr(3) <= s_dinr(14);
				s_dbr(4) <= s_dinr(18);
				s_dbr(5) <= s_dinr(22);
				s_dbr(6) <= s_dinr(26);
				s_dbr(7) <= s_dinr(30);
		when "01100" =>
				s_dbr(0) <= s_dinr(3);
				s_dbr(1) <= s_dinr(7);
				s_dbr(2) <= s_dinr(11);
				s_dbr(3) <= s_dinr(15);
				s_dbr(4) <= s_dinr(19);
				s_dbr(5) <= s_dinr(23);
				s_dbr(6) <= s_dinr(27);
				s_dbr(7) <= s_dinr(31);
		when "01001" =>
		when others => null;	
	end case;	
	end if;
end if;

end process;	

-- операция fft8 4раза (прореживание по времени)
process(clk)
begin
if clk'event and clk = '1' then
	-- 1_я стадия fft8 (только сумма и разность) 
	if (ctf = 1 or ctf = 5 or ctf = 9 or ctf = 13) and begpr = '1' then
		s_st1_0 <= signed(s_dbr(0)) + signed(s_dbr(4));
		s_st1_1 <= signed(s_dbr(0)) - signed(s_dbr(4));
		s_st1_2 <= signed(s_dbr(2)) + signed(s_dbr(6));
		s_st1_3 <= signed(s_dbr(2)) - signed(s_dbr(6));
		s_st1_4 <= signed(s_dbr(1)) + signed(s_dbr(5));
		s_st1_5 <= signed(s_dbr(1)) - signed(s_dbr(5));
		s_st1_6 <= signed(s_dbr(3)) + signed(s_dbr(7));
		s_st1_7 <= signed(s_dbr(3)) - signed(s_dbr(7));

		s_st1_0_int <= conv_integer(signed (s_st1_0));
		s_st1_1_int <= conv_integer(signed (s_st1_1));
		s_st1_2_int <= conv_integer(signed (s_st1_2));
		s_st1_3_int <= conv_integer(signed (s_st1_3));
		s_st1_4_int <= conv_integer(signed (s_st1_4));
		s_st1_5_int <= conv_integer(signed (s_st1_5));
		s_st1_6_int <= conv_integer(signed (s_st1_6));
		s_st1_7_int <= conv_integer(signed (s_st1_7));
	-- 2_я стадия fft8  	
	elsif (ctf = 2 or ctf = 6 or ctf = 10 or ctf = 14) and begpr = '1' then
		s_st2_0 <= conv_std_logic_vector((s_st1_0_int + s_st1_0_int), nb);
		s_st2_1 <= conv_std_logic_vector((s_st1_1_int + s_st1_3_int*w8_2), nb);
		s_st2_2 <= conv_std_logic_vector((s_st1_0_int - s_st1_2_int), nb);
		s_st2_3 <= conv_std_logic_vector((s_st1_1_int - s_st1_3_int*w8_2), nb);
		s_st2_4 <= conv_std_logic_vector((s_st1_4_int + s_st1_6_int), nb);
		s_st2_5 <= conv_std_logic_vector((s_st1_5_int + s_st1_7_int*w8_2), nb);
		s_st2_6 <= conv_std_logic_vector((s_st1_4_int - s_st1_6_int), nb);
		s_st2_7 <= conv_std_logic_vector((s_st1_5_int - s_st1_7_int*w8_2), nb);

		s_st2_0_int <= conv_integer(signed (s_st2_0));
		s_st2_1_int <= conv_integer(signed (s_st2_1));
		s_st2_2_int <= conv_integer(signed (s_st2_2));
		s_st2_3_int <= conv_integer(signed (s_st2_3));
		s_st2_4_int <= conv_integer(signed (s_st2_4));
		s_st2_5_int <= conv_integer(signed (s_st2_5));
		s_st2_6_int <= conv_integer(signed (s_st2_6));
		s_st2_7_int <= conv_integer(signed (s_st2_7));
		-- 3_я стадия fft8 
	elsif (ctf = 3 or ctf = 7 or ctf = 11 or ctf = 15) and begpr = '1' then
		s_st3_0 <= conv_std_logic_vector((s_st2_0_int + s_st2_4_int), nb);
		s_st3_1 <= conv_std_logic_vector((s_st2_1_int + s_st2_5_int*w8_1), nb);
		s_st3_2 <= conv_std_logic_vector((s_st2_2_int + s_st2_6_int*w8_2), nb);
		s_st3_3 <= conv_std_logic_vector((s_st2_3_int + s_st2_7_int*w8_3), nb);
		s_st3_4 <= conv_std_logic_vector((s_st2_0_int - s_st2_4_int), nb);
		s_st3_5 <= conv_std_logic_vector((s_st2_1_int - s_st2_5_int*w8_1), nb);
		s_st3_6 <= conv_std_logic_vector((s_st2_2_int - s_st2_6_int*w8_2), nb);
		s_st3_7 <= conv_std_logic_vector((s_st2_3_int - s_st2_7_int*w8_3), nb);
		-- запись данных
	elsif (ctf = 4 or ctf = 8 or ctf = 12 or ctf = 16) and begpr = '1' then
		if ctf = 4 then
			dout0 <= s_st3_0;
			dout1 <= s_st3_1;
			dout2 <= s_st3_2;
			dout3 <= s_st3_3;
			dout4 <= s_st3_4;
			dout5 <= s_st3_5;
			dout6 <= s_st3_6;
			dout7 <= s_st3_7;
		elsif ctf = 8 then	
			dout8 <= s_st3_0;
			dout9 <= s_st3_1;
			dout10 <= s_st3_2;
			dout11 <= s_st3_3;
			dout12 <= s_st3_4;
			dout13 <= s_st3_5;
			dout14 <= s_st3_6;
			dout15 <= s_st3_7;
		elsif ctf = 12 then	
			dout16 <= s_st3_0;
			dout17 <= s_st3_1;
			dout18 <= s_st3_2;
			dout19 <= s_st3_3;
			dout20 <= s_st3_4;
			dout21 <= s_st3_5;
			dout22 <= s_st3_6;
			dout23 <= s_st3_7;
		elsif ctf = 16 then	
			dout24 <= s_st3_0;
			dout25 <= s_st3_1;
			dout26 <= s_st3_2;
			dout27 <= s_st3_3;
			dout28 <= s_st3_4;
			dout29 <= s_st3_5;
			dout30 <= s_st3_6;
			dout31 <= s_st3_7;
		end if;	
	end if;	 
end if; 

end process;	

end behavioural;

Прием данных (всех 32 - размерность 16 бит) путем записи в регистровый файл (тривиально). Далее мультиплексор для подачиданных, поочередное (4 раза) выполнение операций fft8 по алгоритму прореживание по времени с одновременной записью результатов на выход. Данный код только первый этап алгоритма определяемого формулой:

                 7    mr     ms     3             sl   
X(k) = X(8r+s) = ∑   W8     W32     ∑  x(8l + m) W4   r = 0 to 8, s = 0 to 4 
                m=0                l=0

Алгоритм описан тут RG06.rar Суть в том, что большой fft32 можно выполнить с помощью маленьких fft8 и fft4 путем создания матрицы из входных отсчетов,.. далее по формуле.

В данном коде кажется ошибка с коэффициентами. Поскольку fft8 выполняются из матрицы то коэффициенты должны определяться для кажного столбца fft8 свои. Если можно подсажите как.

Код не имеет разделения на реал и имаг поскольку в данной задаче (предварительно) в этом нет необходимости. Всеравно четные и нечетные выборки будут обрабатываться по очереди.

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

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


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

И тем не менее БПФ всеравно делать нужно. Кроме того этот раздел форума на тему VHDL. Привожу код первого этапа.

 

На выходе у Вас должны быть комплексные числа в любом случае. Что-то я их там не обнаружил...

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


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

На выходе у Вас должны быть комплексные числа в любом случае. Что-то я их там не обнаружил...

Стоп...Почему комплексные? Приведенный код это только, например, реал вход с промежуточным результатом выходной матрицы из 4_рех fft8.

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


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

Стоп...Почему комплексные? Приведенный код это только, например, реал вход с промежуточным результатом выходной матрицы из 4_рех fft8.

 

1) Я закрываю глаза на вашу предварительную обработку и то как Вы все-таки решили подавать данные на БПФ - у меня нет времени детально проанализировать вашу схему предварительной обработки, но интуиция мне подсказывает, что она не правильная. Я могу ошибаться.

 

2) БПФ это совершенно конкретный алгоритм. Что бы Вы ни подавали на его вход, каким бы хитрым образом ни проводили вычисления, как бы замысловато не интерпретировали потом результаты - БПФ от этого с математической точки зрения никак не изменяется. Вы можете раскрывать скобки, можете наоборот группировать, можете вычислить все за такт, можете растянуть на 10, можете все посчитать используя один умножитель, можете использовать 10 - результат должен быть одинаковый!

 

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

 

Вы можете подать на вход БПФ числа вида (X + i*0), (0 + i*X) и (X + i*Y). В первом и во втором случае у вас просто упрощаются вычисления на первом этапе, потому что появляется много умножений на 0. Тогда, если на вычисление каждого этапа выделяется отдельное железо, то железо первого этапа потребует меньше ресурсов ПЛИС, но на выходе первого этапа все равно будут комплексные числа ( если только Х у Вас тождественно не равен 0 :) ).

 

Все бабочки БПФ имеют умножения на комплексные коэффициенты, разница только в том, что у 2-х и 4-х точечной бабочки коэффициенты вырожденные в том смысле, что содержат только 0 и 1 и не требуют реального умножения. Например, у 4-х точечной бабочки коэффициенты соответствуют числам на комплексной плоскости с углом 0, 90, 180 и 270 град. (1+i*0; 0 + i*1; -1 + i*0; 0 - i*1). У 8-ми точечной бабочки коэффициенты соответствуют числам на комплексной плоскости с шагом угла 45 град - 0, 45, 90, 135, 180 и т.д. Соответственно, например, sin(45) и cos(45) равен 0.7071 из-за чего получается уже не тривиальный коэффициент W = (0.7071 + i*0.7071).

 

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

 

И в источнике, который Вы привели ( RG06.rar ) тоже используются исключительно комплексные входы, выходы и коэффициенты. Кстати, в этой книжке главы, посвященные БПФ почему-то разнесены по разным концам книги. Так что полистайте еще и вы найдете еще несколько полезных глав про БПФ.

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


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

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

Могу и я ошибаться. По ходу надеюсь все прояснится.

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

Комплексными. Согласен.

Если ближе к железу, как это выглядит? Я просмотрел файл fft8 из корки от opencores. Там все операции выполняются отдельно с реал и имаг данными. Единственное - это умножение на коэффициенты общие для обеих частей.

Похоже я и сэтим запутался.

Как я понимаю построение fft8: Беру направленный граф (прореживание по времени) из любого учебника и тупо выполняю по нему операции - 3 стадии, в каждой стадии по 4 бабочки. Предполагается, что входные данные разделены на реал и имаг. Сначала делаю fft8 с реал данными, затем с имаг данными. В конце возвожу каждый результат в квадрат, суммирую, беру корень. Что в этой последовательности не соответствует комплексному представлению?

Где при вычислении fft8 в промежуточном результате будет комплексное число? Если при умножении на нетривиальный коэффициент (который комплексный) то да.

Что я не так делаю?

Acvarif Вы читали/смотрели это?

Читал я эту тему. Может не везде внимательно. Но задачка там другая. Бабочка там 4_х точечная.

Не врублюсь где в промежуточных результатах комплексные числа? Разве, что только при умножении на поворачивающий множитель, который по своей сути комплексный.

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

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


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

Если ДА, то Вы окажете большую услугу автору, если просто объясните, как правильно перенести спектр сигнала на 0-у частоту и, главное, каким образом далее определить угол прихода.

Это ему уже объясняли в другой теме. Автор, судя по всему, предпочел не разбираться в этом этапе алгоритма.

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


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

Это ему уже объясняли в другой теме. Автор, судя по всему, предпочел не разбираться в этом этапе алгоритма.

Алгоритм разбирали другие люди, в том числе и с пом. матлаб. Мне нет смысла им не доверять. Может быть и они все до конца не понимают. Это вскоре выяснится. Что касается меня, повторюсь, интуитивно, все должно работать как задумано. Железо скажет точно.

Мне поставлена задача написать БПФ32. Что я и пытаюсь сделать. Если все получится, надеюсь пригодится не только для моей конкретной задачи.

На данном этапе прошу только подсказать что нужно подавать на двухвходовую бабочку. Например в БПФ8

post-39850-1378893108_thumb.jpg

Если дискретный сигнал предварительно разделен на действительную и мнимую части например xr(0)...xr(7) и xi(0)...xi(7) то что куда (согласно рисунка или графа) нужно подать чтобы вычислить БПФ8. Я считал так: xr(0)...xr(7) подается на x(0)...x(7) выходной результат сохраняется в буфере. Затем xi(0)...xi(7) подается на x(0)...x(7) - результат возводится в квадрат и суммируется с квадратом того, что в буфере. Берется корень. Результатом и будет БПФ8. Что я напутал?

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


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

Что я напутал?

Вы получили модуль коэффициентов БПФ. И, если я не ошибаюсь, примерно удвоили количество операций. Думаю, Sefo подскажет точнее.

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


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

Как я понимаю построение fft8: Беру направленный граф (прореживание по времени) из любого учебника и тупо выполняю по нему операции - 3 стадии, в каждой стадии по 4 бабочки. Предполагается, что входные данные разделены на реал и имаг.

 

Кто Вам такую ерунду сказал? Где Вы вычитали, что "Предполагается, что входные данные разделены на реал и имаг."?

 

Читал я эту тему. Может не везде внимательно. Но задачка там другая. Бабочка там 4_х точечная.

 

Вы и вправду считаете, после всего, что я тут написал, что есть какая-то принципиальная разница между 4-х точечной бабочкой, 8-ми точечной бабочкой, 2-х точечной бабочкой и прочими бабочками?

 

И Вы вправду считаете, что задача реализовать БПФ на 2048 точек как-то принципиально отличается от задачи реализовать БПФ на 32 точки?

 

Алгоритм разбирали другие люди, в том числе и с пом. матлаб. Мне нет смысла им не доверять. Может быть и они все до конца не понимают. Это вскоре выяснится. Что касается меня, повторюсь, интуитивно, все должно работать как задумано. Железо скажет точно.

Мне поставлена задача написать БПФ32. Что я и пытаюсь сделать. Если все получится, надеюсь пригодится не только для моей конкретной задачи.

На данном этапе прошу только подсказать что нужно подавать на двухвходовую бабочку. Например в БПФ8

 

Если дискретный сигнал предварительно разделен на действительную и мнимую части например xr(0)...xr(7) и xi(0)...xi(7) то что куда (согласно рисунка или графа) нужно подать чтобы вычислить БПФ8. Я считал так: xr(0)...xr(7) подается на x(0)...x(7) выходной результат сохраняется в буфере. Затем xi(0)...xi(7) подается на x(0)...x(7) - результат возводится в квадрат и суммируется с квадратом того, что в буфере. Берется корень. Результатом и будет БПФ8. Что я напутал?

 

Простите, но Вы напутали абсолютно ВСЕ.

 

Вы приводите правильные картинки, правильные книжки - но Вы никак не хотите услышать, что во всех этих книжках, на всех картинках ВСЕ ЧИСЛА КОМПЛЕКСНЫЕ! Абсолютно все! Без исключения!

 

На последней картинке x[k] = xr[k] + i*xi[k]. То, что Вы получаете ваши xr и xi в разные моменты времени значения не имеет. На ФБП Вы должны их подавать одновременно. Получили xr, защелкнули в регистры, ждете xi. Дождались xi, сформировали массив комплексных чисел x[k] = xr[k] + i*xi[k] и отправили все это на БПФ8. И не вздумайте, пока не вычислите полностью БПФ32, что-либо возводить к квадрат и суммировать "с квадратом того, что в буфере" - корень из всего этого в особенности не рекомендую брать.

 

 

 

 

 

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


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

Простите, но Вы напутали абсолютно ВСЕ.

 

Вы приводите правильные картинки, правильные книжки - но Вы никак не хотите услышать, что во всех этих книжках, на всех картинках ВСЕ ЧИСЛА КОМПЛЕКСНЫЕ! Абсолютно все! Без исключения!

 

На последней картинке x[k] = xr[k] + i*xi[k]. То, что Вы получаете ваши xr и xi в разные моменты времени значения не имеет. На ФБП Вы должны их подавать одновременно. Получили xr, защелкнули в регистры, ждете xi. Дождались xi, сформировали массив комплексных чисел x[k] = xr[k] + i*xi[k] и отправили все это на БПФ8. И не вздумайте, пока не вычислите полностью БПФ32, что-либо возводить к квадрат и суммировать "с квадратом того, что в буфере" - корень из всего этого в особенности не рекомендую брать.

Спасибо.

Кто, блин, придумал эти комплексные числа?

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

Я так понял, что (согласно последней картинке) на х(0) нужно подать хr(0) + j*xi(0) и т. д. - тоесть в моем случае я должен принять эти самые xr(0) и xi(0)..., а еще точнее, в моем случае, нужно принять 2 раза по 32 выборки (четные и нечетные). Четные считать как xr(0)... нечетные как xi(0). Я ничего не попутал?

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

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


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

Я так понял, что (согласно последней картинке) на х(0) нужно подать хr(0) + j*xi(0) и т. д. - тоесть в моем случае я должен принять эти самые xr(0) и xi(0)..., а еще точнее, в моем случае, нужно принять 2 раза по 32 выборки (четные и нечетные). Четные считать как xr(0)... нечетные как xi(0). Я ничего не попутал?

Стоит сначала разобраться собственно с БПФ. Что там у вас четное, а что нечетное - это вопросы интерфейса, не имеющие к БПФ никакого отношения.

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


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

Стоит сначала разобраться собственно с БПФ. Что там у вас четное, а что нечетное - это вопросы интерфейса, не имеющие к БПФ никакого отношения.

Хорошо.

Допустим есть данные по 8_ми выборкам d0...d7. Что нужно подавать на x(0)...x(7) fft8 (согласно последнего рисунка или графа)?

Опять просмотрел код корки fft8 там два входа DIR и DII и действия производятся отдельно (или параллельно) с данными r и i.

...Дождались xi, сформировали массив комплексных чисел x[k] = xr[k] + i*xi[k] и отправили все это на БПФ8

Получается что сначала нужно вычислить массив комплексных чисел x[k]. Для этого во всех корках имеются входы DIR и DII?

Хорошо, просуммировать данные действ. и мнимые нет проблем, а что из себя представляет умножение на i? Реально это что за число? Корень из -1?

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

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


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

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

post-39850-1378913653_thumb.jpg

Всем спасибо. Уяснил железно.

Получается перед тем как подать данные на бабочку нужно сделать, что-то вроде этого

    
signal xr0 : std_logic_vector(nb downto 0);    
signal xi0 : std_logic_vector(nb downto 0);    
signal xc0 : std_logic_vector(nb??? downto 0);    

signal xr4 : std_logic_vector(nb downto 0);    
signal xi4 : std_logic_vector(nb downto 0);    
signal xc4 : std_logic_vector(nb??? downto 0);    
    
xc0 = xr0 + j*xi0;
xc4 = xr4 + j*xi4;

Чему равно j (в числовом выражении применительно для FPGA)? Почему то в корке fft8 такой операции нигде нет.

Везде операции с r и i данными производятся раздельно.

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

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


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

Хорошо, просуммировать данные действ. и мнимые нет проблем, а что из себя представляет умножение на i? Реально это что за число? Корень из -1?

 

Получается перед тем как подать данные на бабочку нужно сделать, что-то вроде этого

    
xc0 = xr0 + j*xi0;
xc4 = xr4 + j*xi4;

Чему равно j (в числовом выражении применительно для FPGA)? Почему то в корке fft8 такой операции нигде нет.

Везде операции с r и i данными производятся раздельно.

 

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

 

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

 

P.S. иногда мнимую единицу обозначают j, просто потому, что в программировании i "зарезервирована" для индексации элементов массивов и использования в циклах.

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


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

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

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

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

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

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

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

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

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

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