|
|
  |
БПФ ядро |
|
|
|
Jan 11 2009, 21:40
|
Частый гость
 
Группа: Участник
Сообщений: 108
Регистрация: 31-01-08
Из: Москва
Пользователь №: 34 633

|
Цитата(murmel1 @ Jan 11 2009, 22:56)  Пользовался Этим ядром еще когда Квартус был не 8.1, а 5.0 Никаких проблем не имел. Посмотрите внимательно на доп сигналы (групповая экспонента), проверьте временной отчет (а tco/tsu/th в порядке? используйте функциональную симуляцию), внимательно прочитайте инструкцию по шине Atlantic (недавно Altera переименовала ее в Avalon-ST). Могу завтра принести и выложить коды модулей которые загружают в нее данные из памяти и выгружают результат в другую память, но - на AHDL. Нужно ? Спасибо большое,но меня интересует ядро для Xilinx, а не Altera. Всеравно спасибо.
|
|
|
|
|
Jan 15 2009, 07:56
|
Знающий
   
Группа: Свой
Сообщений: 740
Регистрация: 24-07-06
Из: Minsk
Пользователь №: 19 059

|
Цитата(Azatot @ Jan 11 2009, 15:43)  ядро работает, но не правильно- результаты не соответствуют высчитаным вручную. Что контретно Вас не понравилось ? Оно действительно иногда работает криво, помогает пересборка ядра.
|
|
|
|
|
Jan 15 2009, 08:53
|
Знающий
   
Группа: Свой
Сообщений: 726
Регистрация: 14-09-06
Из: Москва
Пользователь №: 20 394

|
Цитата(Azatot @ Jan 11 2009, 20:43)  Всем доброго времени суток.Может кто-нибудь объяснить как пользоваться fft ядром, сформированным IP Core generator'ом? Прочитал datasheet на него, вроде все сделал, согласно временным диаграммам, ядро работает, но не правильно- результаты не соответствуют высчитаным вручную. Есть ли кто -нибудь, кто пользовался этим ядром и может объяснить что к чему, а еще лучше -выложить код на VHDL, где ядро используется? Был бы безмерно благодарен! Использовал корку БПФ на 4096 точек в XC3S1000: 16 бит вход, 29 бит на выхода (без усечения). На входе корки стоит умножитель для взвешивания. Все это управляется через FSM. Данные читаются из SDRAM и пишутся в нее же. Корка БПФ, FSM, умножитель обернуты примерно так: CODE ibrary IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; ---- Uncomment the following library declaration if instantiating ---- any Xilinx primitives in this code. library UNISIM; use UNISIM.VComponents.all; use WORK.common.all;
entity fft_wrap is PORT ( clk : in std_logic; rst : in std_logic; start_fft : in std_logic; -- din : in std_logic_vector(15 downto 0); dout : out std_logic_vector(15 downto 0); addr : out std_logic_vector(23 downto 0); dcoef : in std_logic_vector(15 downto 0); -- b_addrin : in std_logic_vector(10 downto 0); b_addrout : in std_logic_vector(9 downto 0); -- fft_rdy : out std_logic; fft_busy : out std_logic; fft_status : out std_logic_vector(3 downto 0); -- fft_wr : out std_logic; fft_rd : out std_logic; sdr_done : in std_logic; sdr_rddone : in std_logic
); end fft_wrap;
architecture implement of fft_wrap is
component fft_4096 port ( clk: IN std_logic; ce: IN std_logic; start: IN std_logic; unload: IN std_logic; xn_re: IN std_logic_VECTOR(15 downto 0); xn_im: IN std_logic_VECTOR(15 downto 0); fwd_inv: IN std_logic; fwd_inv_we: IN std_logic; rfd: OUT std_logic; xn_index: OUT std_logic_VECTOR(11 downto 0); busy: OUT std_logic; edone: OUT std_logic; done: OUT std_logic; dv: OUT std_logic; xk_index: OUT std_logic_VECTOR(11 downto 0); xk_re: OUT std_logic_VECTOR(28 downto 0); xk_im: OUT std_logic_VECTOR(28 downto 0)); end component;
component mul16x16 port ( clk: IN std_logic; a: IN std_logic_VECTOR(15 downto 0); b: IN std_logic_VECTOR(15 downto 0); p: OUT std_logic_VECTOR(31 downto 0)); end component;
--attribute syn_black_box : boolean; --attribute syn_black_box of fft_4096: component is true;
constant DELAY_END : natural := 2; -- 2 constant ADDRIN_END : natural := 16#1FFF#; -- 8191 constant ADDROUT_END : natural := 16#3FFF#; -- 8191 * 2
signal xn_re_i : std_logic_vector(15 downto 0); signal xk_re_i, xk_im_i : std_logic_vector(28 downto 0); -- signal clk_fft : std_logic; signal ce_i, start_i, fwd_inv_i, fwd_inv_we_i : std_logic; signal rfd_i, busy_i, edone_i, done_i, dv_i : std_logic; -- signal ld_in_re : std_logic; signal addr_r, addr_x: std_logic_vector(13 downto 0); -- type fft_state_type is (FFT_IDLE, FFT_INIT, FFT_WAIT,FFT_READ_RE, FFT_MUL_RE, FFT_READ_IM, FFT_MUL_IM, FFT_WAIT_DV, FFT_WRITE_REL, FFT_WRITE_REM, FFT_WRITE_IML, FFT_WRITE_IMM); signal fft_state, fft_next_state : fft_state_type; -- signal fft_status_i: std_logic_VECTOR(3 downto 0); signal dmul : std_logic_VECTOR(31 downto 0); --signal ain_mul1, bin_mul1, ain_mul2, bin_mul2 : std_logic_VECTOR(17 downto 0);
begin
clk_fft <= clk;
FFT_FSM_PROC: process(clk) begin if rising_edge(clk) then if rst = RESET_ACTIVE then fft_state <= FFT_IDLE; else fft_state <= fft_next_state; addr_r <= addr_x; end if; end if; end process FFT_FSM_PROC;
fwd_inv_i <= '1';
FSM_COMBINATORIAL: process(fft_state, start_fft, sdr_done, sdr_rddone, rfd_i, dv_i, addr_r) begin -- default ce_i <= '0'; fwd_inv_we_i <= '0'; ld_in_re <= '0'; start_i <= '0'; fft_rdy <= '0'; fft_busy <= '1'; fft_wr <= '0'; fft_rd <= '0'; fft_status_i <= x"0"; fft_next_state <= fft_state; addr_x <= addr_r; case fft_state is when FFT_IDLE => fft_busy <= '0'; fft_status_i <= x"f"; if start_fft ='1' then fft_next_state <= FFT_INIT; end if; when FFT_INIT => start_i <= '1'; ce_i <= '1'; fwd_inv_we_i <= '1'; addr_x <= CONV_STD_LOGIC_VECTOR(0, addr_x'length); fft_next_state <= FFT_WAIT; when FFT_WAIT => ce_i <= '1'; if addr_r /= DELAY_END then addr_x <= addr_r + 1; else fft_next_state <= FFT_READ_RE; addr_x <= CONV_STD_LOGIC_VECTOR(0, addr_x'length); end if; when FFT_READ_RE => fft_status_i <= x"1"; if sdr_rddone = NO then fft_rd <= '1'; else fft_rd <= '0'; fft_next_state <= FFT_MUL_RE; end if; when FFT_MUL_RE => addr_x <= addr_r + 1; ld_in_re <= '1'; fft_next_state <= FFT_READ_IM; when FFT_READ_IM => fft_status_i <= x"2"; if sdr_rddone = NO then fft_rd <= '1'; else fft_rd <= '0'; fft_next_state <= FFT_MUL_IM; end if; when FFT_MUL_IM => ce_i <= '1'; if addr_r /= ADDRIN_END then addr_x <= addr_r + 1; fft_next_state <= FFT_READ_RE; else fft_next_state <= FFT_WAIT_DV; end if; when FFT_WAIT_DV => fft_status_i <= x"3"; ce_i <= '1'; if dv_i = '1' then addr_x <= CONV_STD_LOGIC_VECTOR(0, addr_x'length); fft_next_state <= FFT_WRITE_REL; end if; when FFT_WRITE_REL => fft_status_i <= x"4"; if sdr_done = NO then fft_wr <= '1'; else fft_wr <= '0'; addr_x <= addr_r + 1; fft_next_state <= FFT_WRITE_REM; end if; when FFT_WRITE_REM => fft_status_i <= x"5"; if sdr_done = NO then fft_wr <= '1'; else fft_wr <= '0'; addr_x <= addr_r + 1; fft_next_state <= FFT_WRITE_IML; end if; when FFT_WRITE_IML => fft_status_i <= x"6"; if sdr_done = NO then fft_wr <= '1'; else fft_wr <= '0'; addr_x <= addr_r + 1; fft_next_state <= FFT_WRITE_IMM; end if; when FFT_WRITE_IMM => fft_status_i <= x"7"; if sdr_done = NO then fft_wr <= '1'; elsif addr_r /= ADDROUT_END then fft_wr <= '0'; ce_i <= '1'; addr_x <= addr_r + 1; fft_next_state <= FFT_WRITE_REL; else fft_wr <= '0'; ce_i <= '1'; fft_next_state <= FFT_IDLE; fft_rdy <= '1'; end if; when others => fft_busy <= '0'; fft_status_i <= x"c"; end case; end process FSM_COMBINATORIAL;
Inst_fft : fft_4096 port map ( clk => clk_fft, ce => ce_i, start => start_i, unload => edone_i, xn_re => xn_re_i, xn_im => dmul(31 downto 16), xn_index => open, fwd_inv => fwd_inv_i, fwd_inv_we => fwd_inv_we_i, rfd => rfd_i, busy => busy_i, edone => edone_i, done => done_i, dv => dv_i, xk_index => open, xk_re => xk_re_i, xk_im => xk_im_i); Inst_mult : mul16x16 port map ( clk => clk, a => din, b => dcoef, p => dmul);
process(clk) begin if rising_edge(clk) then if ld_in_re = '1' then xn_re_i <= dmul(31 downto 16); end if; end if; end process;
dout <= xk_re_i(15 downto 0) when addr_r(1 downto 0) = "00" else xk_re_i(28) & xk_re_i(28) & xk_re_i(28) & xk_re_i(28 downto 16) when addr_r(1 downto 0) = "01" else xk_im_i(15 downto 0) when addr_r(1 downto 0) = "10" else xk_im_i(28) & xk_im_i(28) & xk_im_i(28) & xk_im_i(28 downto 16);
fft_status <= fft_status_i;
addr <= b_addrin & addr_r(12 downto 0) when (fft_state = FFT_READ_RE or fft_state = FFT_READ_IM) else b_addrout & addr_r;
end implement;
Загрузка данных в темпе чтения из SDRAM, вычисления, выгрузка данных в SDRAM. Память взвешивающих коэффициентов сделана в BRAM спартана.
|
|
|
|
|
Jan 23 2009, 14:18
|
Группа: Участник
Сообщений: 7
Регистрация: 1-11-05
Пользователь №: 10 371

|
Я работал я ядрами FFT на Spartan и VirteX 4, правда в ISE 8 это было, но в общем-то все работало без проблем, результаты довольно точно совпадали с Матлабом. А ты пробовал примитивные сигналы, БПФ от постоянного сигнала, БПФ от синусоиды и пр?
Я на начальных этапах отладки сделал тестбенч: в Modelsim подавал данные из файла, обрабатывал и назад в файл, после чего в Матлабе сравнивал. Потом уже на плате по USB данные гонял.
|
|
|
|
|
Jan 23 2009, 15:11
|
Группа: Участник
Сообщений: 7
Регистрация: 1-11-05
Пользователь №: 10 371

|
Цитата(Azatot @ Jan 23 2009, 17:22)  Хотелось бы опять попросить помощи. Внес поправки в код и ядро заработало, но только если на выходе положительные числа. А вот, когда на выходе должны получатся отрицательные числа, то начинается какая то мутота! Выдает черт знает что! Может, кто-нибудь подскажет как с отрицательными числами работать в этом ядре? Заранее благодарен. там вроде числа в дополнительном коде (twos complement): 0xFFFF соответствует -1, а 0x8000 соответствует -32768, попробуй задать массив из 0x8000 на вход и поглядеть что выйдет? По идее в нулевом отсчете должно быть большое отрицательное число, а остальные около нуля.
Сообщение отредактировал VorteX - Jan 23 2009, 15:24
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|