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++

Code for FFT using SGDMA

Altera_Forum
Honored Contributor II
1,018 Views

I'm attempting to write nios code to send information to an FFT, then view the result. The hardware is:  

sgdma_mem_to_stream-->FFT-->sgdma_stream_to_mem 

 

With a streaming FFT of length 64, 32 bits (16 real, 16 imag) input, 40 bit (16 real, 16 imag, 6 exponent and 2 extra bits) output. I have data format adapters between the FFT and the sgdma devices. 

 

#include <stdio.h># include <altera_avalon_sgdma.h># include <altera_avalon_sgdma_descriptor.h># include <altera_avalon_sgdma_regs.h> int main() { int contents_counter; int temp_length=1000,i; alt_u32 temp_data=0; alt_u32 *tx_ptr, *rx_ptr,tx_ptr1,rx_ptr2; alt_u32 *tx_ptr_copy; alt_u8 *rx_ptr_copy; tx_ptr = (alt_u32 *)malloc(1000); rx_ptr = (alt_u8 *)malloc(1000); tx_ptr1 = (alt_u32 *)malloc(1000); rx_ptr2 = (alt_u8 *)malloc(1000); tx_ptr_copy = (alt_u32 *)tx_ptr; rx_ptr_copy = (alt_u8 *)rx_ptr; for(contents_counter = 0; contents_counter < temp_length; contents_counter++) { tx_ptr_copy = (alt_u32)(contents_counter + 0xFFFF); rx_ptr_copy = 0; temp_data++; } /* Open a SG-DMA for MM-->ST and ST-->MM (two SG-DMAs are present) */ alt_sgdma_dev * transmit_DMA = alt_avalon_sgdma_open("/dev/sgdma_fft_mm_to_st"); alt_sgdma_dev * receive_DMA = alt_avalon_sgdma_open("/dev/sgdma_fft_st_to_mm"); alt_sgdma_descriptor desc, next; alt_sgdma_descriptor desc1, next1; /************************************************************** * Making sure the SG-DMAs were opened correctly * ************************************************************/ if(transmit_DMA == NULL) { printf("Could not open the transmit SG-DMA\n"); return 1; } if(receive_DMA == NULL) { printf("Could not open the receive SG-DMA\n"); return 1; } /**************************************************************/ /**************************************************************** * Construct descriptors * * *************************************************************/ alt_avalon_sgdma_construct_mem_to_stream_desc(&desc,&next,tx_ptr, (alt_u16)128,0,1,1,0); alt_avalon_sgdma_construct_stream_to_mem_desc(&desc1,&next1, rx_ptr,0,1); if(alt_avalon_sgdma_do_async_transfer(transmit_DMA, &desc)!=0){ printf("transmit dma failed"); } if(alt_avalon_sgdma_do_async_transfer(receive_DMA, &desc1)!=0){ printf("receive dma failed"); }; for(i=0;i<200;i++){ printf("%d",rx_ptr_copy); printf("p"); /*printf("%d",tx_ptr_copy)*/; } return 0; }The code doesn't seem to be working properly. Can anyone point me in the right direction?
0 Kudos
1 Reply
Altera_Forum
Honored Contributor II
270 Views

If the CPU is configured to have a data cache then I would expect intermittent cache coherency issues with that code. Since you are using malloc to allocate the memory I would replace those calls to the uncacheable malloc instead which will make sure that the pointer returned will perform cache bypassing automatically as well as flush the cache before returning the pointer. 

 

Using IOWR based on the pointer returned from malloc is not enough to ensure no cache coherency issues. If the memory that was allocated by malloc happened to be cached before hand and you attempt to use IOWR to write to those memory locations the data in the cache will get written out instead of what you pass into IOWR. This is not a bug because you are essentially treating the memory range as cacheable and non-cacheable at the same time. That is why I recommend using the uncache malloc calls instead which will avoid this automatically (see Nios II software developers handbook for more details.)
0 Kudos
Reply