Forum Discussion
Altera_Forum
Honored Contributor
16 years agoFft In Sopc
Guyz please help , if u have an idea.
Uptil now i made a 64 point FFT using megacore and added it to the sopc as a new component but there are a lot of signals and so it gives me an error when i generate it. I believe i need a wrapper code for my FFT. CAN SUM1 HELP ME OUT WITH IT. THANKS webster_dev at the rate yahoo.com39 Replies
- Altera_Forum
Honored Contributor
HI Marlon :
i think swapping bytes come from using SGDMA (when it read and write data on memory), So you should swap bytes in input and output of FFT. i think it is not good way to swap bytes in software (by using pointers). maybe it spends a time from Nios II. it is better to try swapping bytes in hardware, by swapping the signal in (fft_avalon_wraper.v) file. change the connect of signal to match your swapping. for example, try to do that in (fft_avalon_wraper.v) file: wire [15 : 0] temp_input;assign temp_input[15: 8] = sink_real[7 : 0]; assign temp_input[7 : 0] = sink_real[15 : 8]; temp_input is the input of FFT module. [/B][/B] you should do the same for output.
- Altera_Forum
Honored Contributor
Excellent. Thanks Majd.
One more question. I want to use a 16384-point FFT, with 16-bit precision. This results in a 34-bit width for both the real and imaginary part of the FFT output. Putting these together, I have 68 bits. The SGDMA is limited to 64 bits for data. Is there a way to increase this directly, or is it better to use 2 seperate avalon interfaces? Fast forwarding a bit, I tried using 2 avalon interfaces but the output data from both of the interfaces never comes out: // I start the real transfer first alt_avalon_sgdma_do_async_transfer(receive_real_DMA, desc1); ... while(IORD(SGDMA__ST_TO_MM_FFT_REAL_BASE,0) != 14) { }; // ...then I start the imaginary transfer alt_avalon_sgdma_do_async_transfer(receive_imag_DMA, desc2); ... while(IORD(SGDMA__ST_TO_MM_FFT_IMAG_BASE,0) != 14) { }; // end sample code... The code gets hung up at the first while statement. I know that both SGDMA are initialized properly because ithe initialization were not null and no error was printed. I believe that I may be missing something here...:confused:...can not quite put my finger on it. Let me also explain how i connected each of the avalon interfaces to the single FFT component: source_SOP source_EOP each connect to source_SOP_s and source_EOP_s respectively. I then connect source_SOP_s and source_EOP_S to the SOP and EOP outputs for each avalon interface (remember, there is an interface for real, and imaginary data). I follow the same procedure for source_valid, source error from the FFT, by connecte each to a signal, and then the signal to each of the avalon interfaces. With these parellel connections, I hoped that when the FFT source could simutaneously drive both avalon interfaces in parallel. However, neither is recieving data properly. Any ideas? - Altera_Forum
Honored Contributor
Another side question too.
Can you explain, or point me toward the documentation that discusses the following line? while(IORD(SGDMA_MM_TO_ST_FFT_BASE,0) != 12); // For sending the FFT input data while(IORD(SGDMA_ST_TO_MM_FFT_IMAG_BASE,0) != 14); // For recieving the FFT output data where does the 12 and 14 come from. I understand that this indicates when the transfer is complete, but where is the documentation? - Altera_Forum
Honored Contributor
how can i use this fft system in my main system for speech recognition .
how to merge this in to main system. i have to take speech as input to fft from memory and again put it to memory . how can i do this please give me ideas . - Altera_Forum
Honored Contributor
i studied above tutorials.
i have following queries >should i have to create a fft component using fft.vhd or fft.v file generated from fft megacore.if yes what files are need >>in zip file posted by majd file 1 shows only generation process of fft not the component addition process so i got confused >> can i use verilog wrapper code for generation wrapper component for fft . As my whole system is in vhdl. - Altera_Forum
Honored Contributor
Hi every body,
to marlon: i am sory for late. for quastion about using 12 and 14. while(IORD(SGDMA_MM_TO_ST_FFT_BASE,0) != 12); while(IORD(SGDMA_ST_TO_MM_FFT_IMAG_BASE,0) != 14); meaning: when i read this number from Status Registers, that mean SGDMA finished transfer data without wrong. to understand exactly what it means you can read this document: ------------------------------------------- "Quartus II Handbook Version 9.1, Volume 5: Embedded Peripherals" available at http://www.altera.com/literature/hb/nios2/n2cpu_nii5v3_05.pdf to read about SGDMA :Page 209 to read about Status Registers bit Map:Page 221 ------------------------------------------- to necsagar: when you start your Project you should use same language in all project. i think you start project in VHDL, So when you add new component (like FFT core) you should add it using VHDL. you can not use my wrapper_FFT file for your FFT component, But you should write new wrapper in VHDL. if you have problem in using FFT core you can read this document: "FFT MegaCore Function User Guide" start from page 21 - Altera_Forum
Honored Contributor
Thanks Majd,
I found a temporary workaround for the 64-bit data path constraint on the SGDMA. I decided to use a smaller 4096 point FFT with a 16-bit precision and that resulted in a 31 bit output for both real and imaginary. With your help I have almost completed my "wicked" FFT algorithm for calculating very large FFTs :) Thanks for pointing me in the direction of the documentation. Necsagar, I actually converted the wrapper to VHDL. I will try to post it tomorrow for you. - Altera_Forum
Honored Contributor
hello marlon plz post the wrapper code i am stuck in this portion
- Altera_Forum
Honored Contributor
Hello Necsagar,
Sorry for the dalay. I am tying this code directly to the post, so please excuse any typos. Name the component "ff_avalon_wrapper.vhd". Code below:
A few notes about my FFT implementationlibrary IEEE; use IEEE.std_logic_1164.all; ENTITY fft_avalon_wrapper IS Port{ clk : in std_logic; reset_n : in std_logic; mm_writedata : in std_logic_vector(7 downto 0); mm_write : in std_logic; sink_valid : in std_logic; sink_sop : in std_logic; sink_eop : in std_logic; sink_empty : in std_logic_vector(1 downto 0); sink_real : in std_logic_vector(31 downto 0); sink_error : in std_logic_vector(1 downto 0); source_ready : in std_logic; sink_ready : out std_logic; source_error : out std_logic_vector(1 downto 0); souece_sop : out std_logic; source_eop : out std_logic; source_valid : out std_logic; source_data : out std_logic_vector(63 downto 0); source_empty : out std_logic_vector(2 downto 0) }; END fft_avalon_wrapper; ARCHITECTURE SYN OF fft_avalon_wrapper IS component FFT_1024 IS PORT{ clk : in std_logic; reset_n : in std_logic; fftpts_in : in std_logic_vector(12 downto 0); inverse : in std_logic; sink_valid : in std_logic; sink_sop : in std_logic; sink_eop : in std_logic; sink_real : in std_logic_vector(15 downto 0); sink_imag : in std_logic_vector(15 downto 0); sink_error : in std_logic_vector(1 downto 0); source_ready : in std_logic; fftpts_out : out std_logic_vector(12 downto 0); sink_ready : out std_logic; source_error : out std_logic_vector(1 downto 0); source_sop : out std_logic; source_eop : out std_logic; source_valid : out std_logic; source_real : out std_logic_vector(30 downto 0); source_imag : out std_logic_vector(30 downto 0) }; END COMPONENT signal fftpts_in_s, fftpts_out_s : std_logic_Vector(12 downto 0); signal real_data_s, imag_data_s : std_logic_vector(30 downto 0); signal fft_inverse_s : std_logic; BEGIN FFT_1024_inst :FFT_1024 PORT MAP{ clk => clk, reset_n => reset_n, fftpts_in => fftpts_in_s, fftpts_out => fftpts_out_s, inverse => inverse_s, sink_valid => sink_valid, sink_sop => sink_sop, sink_eop => sink_eop, sink_real => sink_real(7 downto 0) & sink_real(15 downto 8), -- SGDMA flips byts. This assignment flips the bytes back the right way. sink_imag => sink_real(23 downto 16 ) & sink_real(31 downto 24), --SGDMA flips byts. This assignment flips the bytes back the right way. sink_ready => sink_ready, sink_error => sink_error, source_error => source_error, source_ready => source_ready, source_sop => source_sop, source_eop => source_eop, source_valid => source_valid, source_real => real_data_s, source_imag => imag_data_s }; --Flip the bytes and sign extend... source_data(63 downto 56) <= imag_data_s(7 downto 0); source_data(55 downto 48) <= imag_data_s(15 downto 8); source_data(47 downto 40) <= imag_data_s(23 downto 16); source_data(39) <= imag_data_s(30) ; -- Sign extension for imag data... source_data(48 downto 32) <= imag_data_s(30 downto 24); source_data(31 downto 24) <= real_data_s(7 downto 0); source_data(23 downto 16) <= real_data_s(15 downto 8); source_data(15 downto 8) <= real_data_s(23 downto 16); source_data(7) <= real data_s(30); -- Sign extension for real data... source_data(6 downto 0) <=real data_s(30 downto 24); process(clk) begin if(rising_edge(clk)) then fftpts_in_s <= "1000000000000"; fft_inverse_s <= '0'; end if; end process; END SYN;- 16 bit data precision
- 4096 FFT points (as specified by fftpts_in)
- Each fft output is 31 bits. This enable me to encapsulate each component into a single location. Naturally, you need to make sure that you extract each of the component as 32 bit values in your C code. This can be accomplished by casting the (*alt_u64) pointer into a (*alt_32) pointer, enabling you to access each component.
- If your FFT application uses FFT outputs that are greater than 64 bits (or 32 bits for each component), this will not work properly since the SGDMA is limited to a 64 bit word size. If you find out how to get around this limitation let me know because I would like to use a bigger FFT size, but can not since the data width will be larger than 64 bits.
- Altera_Forum
Honored Contributor
--- Quote Start --- hello marlon plz post the wrapper code i am stuck in this portion --- Quote End --- Any luck with the VHDL wrapper?