Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
20725 Discussions

Strange FFT Output

Altera_Forum
Honored Contributor II
2,704 Views

I've been using SignalTap to create a CSV file of the output from my FFT engine. However, when looking at the output in Matlab, it doesn't look right at all.  

 

I know that the ADC's working properly, I'm sending in a 1kHz signal which looks perfect when plotted, so the FFT input is fine, but, the output is all over the place. Is there further processing I have to do on it to make it look like the Matlab example, or is there something going horribly wrong with my FFT core? 

 

I've attached the plot of the Real values coming out of the FFT, any thoughts?
0 Kudos
17 Replies
Altera_Forum
Honored Contributor II
1,226 Views

As long as your matlab is giving you just the real and imaginary output of the FFT calculations the output should look very similar. If Matlab is giving you a Magnitude plot. You need to calculate the magnitude of the output. But looking at your "Real" output, it looks like something is broken. 

 

Here's what I would check: 

 

1: Check your warnings. Make sure the FFT core is finding the twiddle ROM files. (Sin/cos lookup tables). If it doesn't find these files, the outputs will be incorrect. 

 

2: Make sure your Avalon streaming interface is working properly. (You should be able to check the "error" output and it should ALWAYS be zero. If this is not the case, the outputs will be incorrect. 

 

Here's some other general questions to answer that may help pinpoint the issue. 

 

What size of FFT are you running? (how many points?)  

 

What version of Quartus are you using?  

 

Was the FFT core generated with the same version of Quartus? 

 

Have you simulated the core? in Verilog/VHDL? 

 

 

Pete
0 Kudos
Altera_Forum
Honored Contributor II
1,226 Views

Hi Anakha, 

 

Thanks for this response, I'm taking a look at it now. Some info for you: 

 

1024 point FFT 

Quartus v11.1 (FFT core generated in this version) 

 

I have simulated the core previously, but I have been unable to look at the output properly. Is there a way to get a csv file or something out of modelsim? I'm also now trying to generate a 1kHz wave in my testbench to simulate with, so I should have some results soon. 

 

Dave
0 Kudos
Altera_Forum
Honored Contributor II
1,226 Views

Check the output order of your FFT samples. They may be in bit reversed order. Also, in simulation tools to can generate a .csv fairly easily by using $fwrite in verilog. I'm sure that VHDL has something similar.

0 Kudos
Altera_Forum
Honored Contributor II
1,226 Views

I've done a few simulations using $fwrite to capture the data, both in Natural and Bit Reversed orders, and the output is still incorrect. I've attached an example output at the bottom. The input for both of these examples is a 17.36Hz sine wave, generated in the Verilog testbench. 

 

I know it's not a problem with the FFT engine, as running the testbench that is generated with the core gives exactly the same output as when run in Matlab. One thing I realised I was doing wrong previously, was using an unsigned integer as the input, something which I have now rectified.
0 Kudos
Altera_Forum
Honored Contributor II
1,226 Views

Right, I've identified an error here. As I've mentioned before, the input to my FFT is a 12-bit signed value, and for some reason, when the value is negative, the whole rest of the word is populated with 1s rather than just the MSB. For example, the value 111111111010 is used to represent -6, rather than 100000000010.  

 

I think this is causing the FFT to clip, and give me a really weird output. Any ideas why this would be happening?
0 Kudos
Altera_Forum
Honored Contributor II
1,226 Views

It looks like you are doing something wrong with data formats or that your input entering the fft is not what you think. Have you actually captured digital vector entering fft core? 

Matlab model cannot be right either if you are looking at fft of a single sine input. 

Finally, is your sampling rate correct?
0 Kudos
Altera_Forum
Honored Contributor II
1,226 Views

the value -6 should be filled with ones. This is correct in 2's complement.

0 Kudos
Altera_Forum
Honored Contributor II
1,226 Views

Kaz, 

 

Which sampling rate do you mean here? 

 

Further to my previous post, I've realised that the input I'm using is fine. It's in Two's Complement format, which is what the FFT requires.  

 

It's the magnitude data (sqrt(real^2+i^2)) that produces the graphs shown in post# 7, I know there's processing to be done further down the line, but that should give me a couple of peaks for a single sine input.
0 Kudos
Altera_Forum
Honored Contributor II
1,226 Views

The question was: have you signaltapped the input itself and not just rely on analogue side. Your fft output is too weird to debug from graph. 

Capture input and then use matlab fft to find output independent of core. 

 

By sampling I mean ADC sampling rate(actual clock rate that samples) and are you clocking fft with same rate.
0 Kudos
Altera_Forum
Honored Contributor II
1,226 Views

I have signaltapped the input, yes. However, I can't get to my Sig Gen and such until Monday to do any more tests. As for the sample rate, I'm clocking at 6.25kHz, which is my downsampled ADC output. 

 

I may have cracked it now, although I don't wan't to get my hopes up too much as it's always just one thing after another... I think the problem might be coming when I write to file in my testbench, it's writing out as an unsigned decimal. By converting it to signed, it's actually starting to look right. Any ideas on how to get my testbench to write to file as a signed int rather than unsigned?
0 Kudos
Altera_Forum
Honored Contributor II
1,226 Views

I normally write as follows: 

 

---- write data_out to file process(clk) file file_out : text open write_mode is "filename.txt"; variable line_in : line; variable tmp : integer := 0; begin if(rising_edge(clk))then if valid_out = '1' then tmp := to_integer(signed(data_out)); write(line_in, tmp); writeline(file_out,line_in); end if; end if; end process;
0 Kudos
Altera_Forum
Honored Contributor II
1,226 Views

Literally mate, you are a bloody hero. Don't let anyone tell you otherwise. 

 

 

Check the output now. 

 

 

Thankyou so much!!!
0 Kudos
Altera_Forum
Honored Contributor II
1,226 Views

sorry, im having a problem using the ifft/fft, my state machines that control the megafunctions are working properly, as i get no errors from the fft error bus and i get sop and eop where i am supposed to get it, after and a the beginning of my fft/ifft length, the problem is that my data is all over the place. my N=1024, i ifft 3+3i(600 times) and padd with zeros, but when i fft the output of the ifft, some of the values give correct data, while some of the values are negative, help please, been working on this problem for a while now

0 Kudos
Altera_Forum
Honored Contributor II
1,226 Views

Hi Sam_novice. 

 

I have done altera fft some 12 years ago !! and so it has quite changed now but the principles stay same. 

 

For the forum to help you may be you start a new thread explaining in as much detail as you can so that members can help. 

 

First describe your settings and tools/platforms and try not to be short and please do not use terms like if I fft the ifft ? as it has hard for many of us to keep track. 

 

Good luck
0 Kudos
Altera_Forum
Honored Contributor II
1,226 Views

Thank you i solved the problem, my fft works, both in variable streaming and normal streaming, the problem was i was not watching the response of the sink_valid signal thank you

0 Kudos
Altera_Forum
Honored Contributor II
1,226 Views

yes it does seem asserted all the time, but it is not, you need to put an option in your down stream fft state machine, that says that when sink_valid is high you sample and when it is not, you do not sample. This is made clearer in the Avalon interface specifications, read the section about data streaming and its control

0 Kudos
Altera_Forum
Honored Contributor II
1,226 Views

I wrote to you on message board the following, did you make use of my suggestion: 

 

Looks like your fft is not seeing the frame correctly (http://www.alteraforum.com/forum/member.php?u=7086#). 

try this matlab code and you will see what I mean: 

x = [ones(1,600)*3+j*3 zeros(1,1024-600)]; 

y1 = round(ifft(x)); 

y2 = round(fft([0 y1])); 

plot(real(x)) 

hold 

plot(real(y2),'r-') 

 

Thus I inserted one zero at start of frame(y1) and I got all output wrong going up and down. 

You can use this approach to find out which way it equals your output e.g. insert one zero or two zeros or repeat first sample or insert zero at end ...etc
0 Kudos
Reply