Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++

Fft In Sopc

Altera_Forum
Honored Contributor II
2,934 Views

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.com
0 Kudos
39 Replies
Altera_Forum
Honored Contributor II
943 Views

you can use this one: 

 

--- Quote Start ---  

module fft_avalon_wraper  

input clk, 

input reset_n, 

input mm_writedate, 

input mm_write, 

input sink_valid, 

input sink_sop, 

input sink_eop, 

input [31 : 0] sink_data, 

input sink_error, 

input source_ready, 

output sink_ready, 

output source_error, 

output source_sop, 

output source_eop, 

output source_valid, 

output [39 : 0] source_data 

); 

 

reg inverse; 

 

always@(posedge clk) 

begin 

if(mm_write) 

inverse = mm_writedate; 

end 

 

assign source_data[39 : 38] = 2'b0; 

 

your_fft_from_megawizard fft_inst 

clk, 

reset_n, 

inverse, 

sink_valid, 

sink_sop, 

sink_eop, 

sink_data[31 : 16], 

sink_data[15 : 0], 

sink_error, 

source_ready, 

sink_ready, 

source_error, 

source_sop, 

source_eop, 

source_valid, 

source_data[37 : 32], 

source_data[31 : 16], 

source_data[15 : 0] 

); 

 

endmodule 

 

--- Quote End ---  

 

your_fft_from_megawizard is your fft module, configure it's interface as streaming. 

this wraper contains 3 avalon interface: 

streaming sink and streaming source: data input and output, read latency = 0, 8 bits per symbol, use 2 sgdma-s for connecting them to you memory, data adapters may needed. 

memory map: control the inverse signal of you fft, set it's addressing as NATIVE. 

take attention to the width of sink_data and source_data, you may modify them and their connection to sink_real, sink_imag, source_exp, source_real, source_imag due to your own fft module. 

you can refer to fft megacore function user guide.pdf, which contains detailed information about the interface.
0 Kudos
Altera_Forum
Honored Contributor II
943 Views

Thanks a lot for replying back to me. I realy appreciate it. 

 

Progress :- 

1) 2 modules>> FFT AND WRAPPER. 

2) SOPC builder ( wrapper is top level module) 2 errors>>  

avalon_slave</b>: Interface must have an associated clock. 

 

3) In the SOPC builder i called >> CPU....On chip mem......2SGDMA's 

I am using quartus for the first time, could you please tell me how to connect and what to connect using SGDMA's in DETAIL ...and the following steps... 

Photos would be helpful. 

 

Please help me out !! 

 

Thanks a lot 

 

Email address ..... webster_dev(at the rate )yahoo.com
0 Kudos
Altera_Forum
Honored Contributor II
943 Views

Interface must have an associated clock: 

http://www.alteraforum.com/forum/attachment.php?attachmentid=2487&stc=1&d=1273500288  

Components connection: 

http://www.alteraforum.com/forum/attachment.php?attachmentid=2488&stc=1&d=1273500313  

sgdma_fft_mm_to_st: 32bit width 

sgdma_fft_st_to_mm: 8bit width 

all data adapters support package. 

be careful of the data adapters' empty signal. 

How to use SGDMA: 

refer to http://www.altera.com/literature/hb/nios2/qts_qii55003.pdf
0 Kudos
Altera_Forum
Honored Contributor II
944 Views

Thanks a lot....I really appreciate you taking out time an helpin me out 

 

This is where ive reached but couldnt figure out the errors. 

 

 

1 >>> The SYSTEM......Do you have any recommendations regarding it.... Do i need to add any other component. 

 

2>>>> Errors that are needed to be resolved. 

 

 

Do you know how to run this on Nios...i mean once FFT is built and loaded on fpga.....do you have a C code to run it...? 

 

 

Thanks again...!!
0 Kudos
Altera_Forum
Honored Contributor II
944 Views

Please help me out. Am still stuck...!

0 Kudos
Altera_Forum
Honored Contributor II
944 Views

Hi 

 

I have a report due soon and am not able to get results. Please help me doin so as am stuck and am not able to proceed further. 

 

Ill be more than thankful if you could help me out in this. Am using the systme for the first time and its really difficult without any guidance. 

 

Thanks a lot for helpin me 

 

Dev 

If you have an fft implemented using quartus and NIOS, could you please forward it to me. 

 

webster_Dev@yahoo.com
0 Kudos
Altera_Forum
Honored Contributor II
944 Views

Please help me out...!!  

 

Thanks
0 Kudos
Altera_Forum
Honored Contributor II
944 Views

I have followed the same step by step process, but I get an error in sopc builder: "The source has a empty signal of 2 bits but the sink does not" - between sgdma_fft_mm_to_st and the FFT wrapper. When I attempt to add an adapter (automatically) between the two components, I get a warning: "cannot adapt sgdma_fft_mm_to_st and FFT wrapper.... because empty symbol information will be lost. 

 

Any ideas?
0 Kudos
Altera_Forum
Honored Contributor II
944 Views

Hi every body: 

i thing there are good way to add FFT to sopc builder, that by using C2H tool, 

i added a tutorial about how to add FFT to sopc builder. 

read the PDF and try to follow the tutorial.
0 Kudos
Altera_Forum
Honored Contributor II
944 Views

i am also in the process to implement fft in sopc via to nios will this tutorial be enough for this. will i have to add wrapper code to interface with nios .

0 Kudos
Altera_Forum
Honored Contributor II
944 Views

i am doing same thing will this be enough for implementing fft to sopc and then to nios processor. will i need a wrapper code for interface conversion plz provide me code in vhdl if necessary. thanks for the tutorial.

0 Kudos
Altera_Forum
Honored Contributor II
944 Views

Hi every body: 

after alot of work i successed to add FFT core to my Project 

and I attached some picture about how to add FFT 

 

1-First you should add FFT core from Megafunction (as attached file1).. 

2-add your Wrapper FFT to the Project path (file: fft_avalon_wraper.v). and you should change it to match your project. 

3-add your FFT core as (new component) to SOPC builder (as attached file2-3-4). 

4-connect your FFT to SGDMA (as attached file5-6-7). 

5-be cerful to the Arbitration number (as attached file5). 

6-add your code in C project (as attached file8). 

 

i hope that will successed, 

good lock all.
0 Kudos
Altera_Forum
Honored Contributor II
944 Views

Hi 

I want to speak about connect SGDMA and start transmit data. 

 

SGDMA has 4 Signal 

 

1 - read/write Descriptor Signal: this Signal Should be connected to the memory where you write your Descriptor, for example: 

 

- in Sopc builder i will connect read/write Descriptor Signal to The (On_Chip_Memory) it name : "INPUT_RAM". 

 

-so in Nios II Program I should add Descriptor as following: 

 

alt_sgdma_descriptor *desc = (alt_sgdma_descriptor*)input_ram_base

 

**************** 

2 - read or In Signal: connected to the memory where I write my input Data 

 

in Nios II Program: 

alt_u32 *tx_ptr = (alt_u32 *) (INPUT_RAM_BASE+ ALTERA_AVALON_SGDMA_DESCRIPTOR_SIZE); 

 

where tx_ptr is a pointer of memory where data will be read from. 

 

***************** 

3 - CSR Signal: should connected to the CPU, it is needed to asked SGDMA about its status. 

***************** 

4 - write or out Signal: connected to the memory where i want to write output data: 

alt_u32 * rx_ptr = (alt_u32 *) (OUTPUT_RAM_BASE+ ALTERA_AVALON_SGDMA_DESCRIPTOR_SIZE); 

 

where tx_ptr is a pointer of memory where data is written
0 Kudos
Altera_Forum
Honored Contributor II
944 Views

Can you post the project in C? 

 

Thanks, 

Sean
0 Kudos
Altera_Forum
Honored Contributor II
943 Views

here is my code : 

 

 

# include <stdio.h># include <unistd.h># include <stdlib.h># include <string.h># include <ctype.h> 

 

# include "includes.h"# include "priv/alt_file.h"# include "sys/alt_cache.h"# include "sys/alt_alarm.h"# include "system.h"# include "io.h"# include "alt_types.h" 

 

 

/*SGDMA Library*/# include <altera_avalon_sgdma.h># include <altera_avalon_sgdma_descriptor.h># include <altera_avalon_sgdma_regs.h> 

 

 

/////////////////////////////////////////////////////////////////////////////////////////////// 

/////////////////////////////////////////////////////////////////////////////////////////////// 

 

 

 

alt_sgdma_dev * transmit_DMA; 

alt_sgdma_dev * receive_DMA; 

alt_u32 *tx_ptr; 

alt_u32 *rx_ptr; 

alt_sgdma_descriptor *desc = (alt_sgdma_descriptor*)INPUT_RAM_BASE ; 

alt_sgdma_descriptor *desc1 = (alt_sgdma_descriptor*)OUTPUT_RAM_BASE ; 

 

 

 

/////////////////////////////////////////////////////////////////////////////////////////////// 

/////////////////////////////////////////////////////////////////////////////////////////////// 

void init_FFT_sgdma() 

/* Open a SG-DMA for MM-->ST and ST-->MM (two SG-DMAs are present) */ 

transmit_DMA = alt_avalon_sgdma_open("/dev/sgdma_mm_to_st_fft"); 

receive_DMA = alt_avalon_sgdma_open("/dev/sgdma_st_to_mm_fft"); 

 

// Making sure the SG-DMAs were opened correctly 

 

if(transmit_DMA == NULL || receive_DMA == NULL) 

printf("Could not open the SG-DMA of FFT\n"); 

add pointer to the input and output memory. 

 

//tx_ptr pointer on memory where i will write input data 

tx_ptr = (alt_u32 *) (INPUT_RAM_BASE+ ALTERA_AVALON_SGDMA_DESCRIPTOR_SIZE); 

//rx_ptr pointer on memory where i can read output data 

rx_ptr = (alt_u32 *) (OUTPUT_RAM_BASE+ ALTERA_AVALON_SGDMA_DESCRIPTOR_SIZE); 

 

 

 

 

 

 

/////////////////////////////////////////////////////////////////////////////////////////////// 

/////////////////////////////////////////////////////////////////////////////////////////////// 

void Hardware_fourier_trans (N) 

 

 

 

int i; 

alt_8 *s0= (alt_8*)tx_ptr; 

for(i = 0; i < N; i++) 

 

tx_ptr = (alt_u32) (sig); //sig[1024] is array of input Signal 

//////////////////////////////////////////////// 

///////* maybe you will face problem whith arrange bytes whish transmit by SGDMA so you should rearrange bytes when you read from memory */ 

//////////////////////////////////////////////// 

 

// Construct descriptors in the same input and output memory. 

// here i use just one descriptorfor, if you want more than one replace "NULL" with name of next descriptor.  

alt_avalon_sgdma_construct_mem_to_stream_desc(desc,NULL,tx_ptr, (alt_u16)4096,0,1,1,0); 

alt_avalon_sgdma_construct_stream_to_mem_desc(desc1,NULL,rx_ptr,0,0); 

 

 

 

//start transfer data 

alt_avalon_sgdma_do_async_transfer(transmit_DMA, desc); 

//wait to finish 

while (IORD(SGDMA_MM_TO_ST_FFT_BASE,0)!=12) {}; 

 

//start receive data 

alt_avalon_sgdma_do_async_transfer(receive_DMA, desc1); 

while (IORD(SGDMA_ST_TO_MM_FFT_BASE,0)!=14) {}; 

//wait to finish 

 

short *s1= (alt_8*)rx_ptr; 

 

//calculate amplitude 

for (i=0;i<1024;i++) {sig[i]=-1*sqrt(pow(s1[2*i],2)+pow(s1[2*i+1],2));} 

 

 

 

/////////////////////////////////////////////////////////////////////////////////////////////// 

/////////////////////////////////////////////////////////////////////////////////////////////// 

 

int main(void) 

 

 

init_FFT_sgdma(); 

 

return 0; 

 

 

Good Luck
0 Kudos
Altera_Forum
Honored Contributor II
943 Views

What does your include.h file look like? Is that were you define pow() and sqrt()?

0 Kudos
Altera_Forum
Honored Contributor II
943 Views

This is my include.h: 

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

 

# ifndef __INCLUDES_H__# define __INCLUDES_H__ 

 

/* 

********************************************************************************************************* 

* uC/OS-II 

* The Real-Time Kernel 

* (c) Copyright 1992-1998, Jean J. Labrosse, Plantation, FL 

* All Rights Reserved 

* MASTER INCLUDE FILE 

********************************************************************************************************* 

*/ 

# ifdef __cplusplus 

extern "C" 

{# endif /* __cplusplus */ 

# include "os_cpu.h"# include "os_cfg.h"# include "ucos_ii.h" 

# ifdef ONT_GLOBALS# define ONT_EXT# else# define ONT_EXT extern# endif 

 

/* 

********************************************************************************************************* 

* DATA TYPES 

********************************************************************************************************* 

*/ 

 

typedef struct { 

char TaskName[30]; 

INT16U TaskCtr; 

INT16U TaskExecTime; 

INT32U TaskTotExecTime; 

} TASK_USER_DATA; 

 

/* 

********************************************************************************************************* 

* VARIABLES 

********************************************************************************************************* 

*/ 

 

ONT_EXT TASK_USER_DATA TaskUserData[10]; 

 

/* 

********************************************************************************************************* 

* FUNCTION PROTOTYPES 

********************************************************************************************************* 

*/ 

 

void DispTaskStat(INT8U id); 

# ifdef __cplusplus 

}# endif /* __cplusplus */ 

# endif /* __INCLUDES_H__ */
0 Kudos
Altera_Forum
Honored Contributor II
943 Views

Thanks Majd, 

 

I have an update for anyone else that may have experienced the same issue: 

 

1. Following Majd's example code, I built my SOPC just as he recommended. 

2. Everything seemed to be ok, except my SGDMA_st_mm component never sent any data out. (see C code below)  

 

// Exert from file8.c 

//start transfer data 

alt_avalon_sgdma_do_async_transfer(transmit_DMA, desc); 

//wait to finish 

while (IORD(SGDMA_MM_TO_ST_FFT_BASE,0)!=12) {}; 

//start receive data 

alt_avalon_sgdma_do_async_transfer(receive_DMA, desc1); 

while (IORD(SGDMA_ST_TO_MM_FFT_BASE,0)!=14) {}; 

//wait to finish.... 

//(THIS NEVER HAPPENED!! THE CODE WAS STUCK AND AFTER DEBUGGING I  

// REALIZED THAT IT MUST HAVE BEEN THE FFT COMPONENT THAT WAS  

// NOT WORKING PROPERLY...WHAT ELSE COULD IT HAVE BEEN RIGHT?? 

 

3. I then went back to the avalon wrapper that Majd provided in the same zip file. This file is written in verilog. Herein lies the issue: 

 

- My entire design (with the exception of some megacore-generated files), was written in VHDL. Using the verilig wrapper should not have posed an issue, since the SOPC builder analyzes the input file an generates yet another file that encapsulates the wrapper. The mere fact that the file was described in verilog was not the issue. 

 

- However, I looked over the verilog file and discovered a few things that concerned me (BTW, im not a verilog coder, but I learned enough to parse through the file): 

 

1. There was no fft_pts input for the wrapped FFT component (Possibly not an issue, if your design assigns that signal properly, perhaps outside of the SOPC). Since my FFT component needed the input, and there was no other external port to feed the FFT component, I added a register for this input, WITHOUT PROPERLY REGISTERING THE SIGNAL, i.e. always@ (posedge clk). I just wrote "reg fft_pts and connected the register to the intantiated FFT's fftpts_in port. (MISTAKE# 1) 

 

2. My fft component needed both real and imaginary component. The wrapper however, assigns 0 to the imaginary component. This is not an issue if your input contains only real data; my input had real and imaginary data. I then split the avalon_mm_to_st into 2 16-bit parts- The first 16-bits were assigned directly to the real input of the FFT, the lower 16-bits were assigned to the imaginary input to the FFT (Your fft may have a different precision, but the punchline is since the avalon interface only has 1 data port, you have to encapsalate inside of that 1 port). 

 

3. Applying the same logic above, I added a register for the inverse signal to the FFT. Once again, if you have external signals that connect to the inverse, you may be able to approach it differently. 

 

Next I regenerated my SOPC, along with the new avalon_wrapper component. However, my code was still getting stuck at the same spot (see code above). 

I then figured that the FFT component was not working at all, but why? 

SOLUTION: 

I registered the inverse and fftpts_in registers PROPERLY. Simply declaring "reg [10 :0] fftpts_in" and "reg inverse" was not enough to truly register the signal, a prerequisite for the FFT component to work properly. What Majd provided in the zip file above really works! If you have any questions or need help getting your FFT component working with the SGDMA, Majd or myself can provide you with some additional help. Just post to the thread and fire away. 

 

EDIT: My code no longer stalls at the spot. Once the fft works properly, the avalon_st_mm interface will infact continue properly. 

 

Thanks Majd!
0 Kudos
Altera_Forum
Honored Contributor II
943 Views

Hi Marlon Winder 

thank you very much for you notice. 

when i posted my example here i posted it as it works in my application. 

you can see i did not use imag input or invers Signal...because doesnt need it. 

anyway when somebody want to use this example, he should read about SGDMA and FFT core then understand the example. 

 

thank Marlon for you notice, and i hope to have success in your Project.
0 Kudos
Altera_Forum
Honored Contributor II
849 Views

So, now im having another issue. It appears that when I read data from the output_Ram component, the bytes are swapped. For the 32-bits of data read, bytes 4 and 1 are swapped and bytes 3 and 2 are swapped.  

 

To get around this issue, I just made a byte pointer (alt_8 or alt_u8) and casted the rx_ptr to to a byte pointer : 

 

(alt_8) *byte_ptr = (alt_8*) rx_ptr; 

 

And then printed the bytes in the correct order using printf. However, I am now concerned that the input bytes maybe having the same issue. 

 

Majd, I noticed the note about the ordering of the bytes for the input. Do you think that changing the I/O Ordering parameter for the FFT component could also remedy the byte arrangements? Has anyone tried this approach?
0 Kudos
Reply