Hi all,I am using Terasic's DE2-70 dev board and I am building a windowed FFT processor (8192 points each, 16 non-overlapping windows) using Quartus II and Modelsim-Altera. The megacore uses buffered burst architecture with block floating points. 18-bit data and 18-bit twiddle. Now I have read previous threads about the sink_sop and sink_eop threads, and i developed a state machine to provide these signals properly. Additionally, the source_valid signal fluctuates when the FFT processor is providing the outputs (once every 4 outputs in simulation). I assume that is normal and I just ignore the clock cycles where the source_valid is de-asserted. I tested the hardware implementation with a simple hard-wired 64 point (that cycles 128 times to fill each 8192 window). the modelsim simulations, matlab fft, quartus-generated matlab testbench, and the hardware output perform very well, with little or no differences (the data did not span the whole dynamic range but just 8 out of 18 bits. Only real data was fed into the processor with the imaginary input tied permanently to ground). With this testing sequence, everything was fine. Now I put in real data from a 14-bit ADC (tested with a single tone sine wave). i took the raw data output of the ADC (which was stored in memory) (the exact same sequence of data that passes through the FFT processor). Matlab's FFT and the quartus generated test bench give perfect answers, but the hardware results are incorrect now ! I am attaching the FFT results as an image (just for one window, the others are almost identical). Any help as to what this problem is would be quite appreciated. Side note: I know that precision is sacrificed in the block floating point by the fft processor in favor of high-amplitude signals. And since a zero average sine wave will have a DC offset of (0x2000) in a 14-bit ADC output, I subtracted this value out of each data point so that the input data to the FFT is centered about 0. Still, the output is not close to satisfactory. only when my input amplitude is really small (1mVpp), such that only a very small dynamic range of the input (32 LSB (5 bits) or less), does the FFT work. Additional info: signal was 300kHz sine, which at a 25MHz sampling rate, and 8192-point FFT, would correspond to FFT output sample number 99 as in the figure (delta_f = 25Mhz/8192 = 3.05kHz approx). Figure only shows output FFT in the range of interest, but the actual data is 8192 points wide as expected. the blue spectrum is what both quartus's matlab test bench and what matlab FFT predict (identical), but the red is what I get from the hardware (same hardware that worked perfectly for very small dynamic range input).
thanks for your reply, kaz, but the time domain signal is perfectly sinusoidal (to within ADC accuracy). it is the same sequence that is used for the matlab fft and the quartus generated test bench. If the time domain signal had harmonics, they would appear in the matlab fft output.
Hi Kaz, thanks again for bearing with me.1) Yes. the data going into the fft core pins comes from an SSRAM memory, which I populated in the past with data coming from an ADC. I extract this data in memory into MATLAB to check against matlab's FFT and Altera's matlab test bench. both results are almost perfectly close to each other. However, when the data from my memory enters directly into the FFT core, I get the erroneous harmonics-like spectrum. This same design worked with very small dynamic range input as I mentioned earlier 2) Most ADC converters do not encode the analog data to signed numbers. In my case, let's assume my input analog sine wave is spanning -Vm/2 to Vm/2 (no offset). The 14-bit ADC will translate the -Vm/2 value to 0x0000, and the Vm/2 to 0x3FFF. So a zero-valued analog input data will translate to 0x2000 after being digitized in the ADC. This is an "artificial DC" because of the shifting that the ADC does. I just subtracted this value from the data that came out of the ADC (before storing in memory), so that I get ready 2's complement, zero average numbers to feed into the FFT core later. It is this "adjusted" data that I use in all hardware tests, as well as matlab fft and Altera's matlab testbench simulations.
I think I might have discovered the problem. Although I got no timing issues in the compilation, i was clocking the FFT_core at 100MHz. As I reduced the clock rate to 10MHz, the results seem much better. I will update the thread as things get clearer.
You should clock your data into fft with its own sampling rate i.e. 25MHz.But I still have doubts. Clocking sinewaveform of Fs 25MHz from sdram using 100MHz will not produce harmonics but will just shift your 3KHz to 12 KHz. There might be something else wrong in your clocking. Also make sure that your ADC data is not offset binary which needs inverting the sign bit.
I am pretty sure of the ADC's output. It is not offset binary. however, the rate at which I clock the data into the FFT core (assuming the core can function normally at that rate), should have nothing to do with the rate at which the stream of data was sampled. The FFT core has no sense of time, and the output sequence will be exactly the same. The interpretation of this output sequence (that is, the frequency axis scale and range), will depend on the actual data sampling rate and it is upto me to decide properly on that. This is like passing a stream of data to matlab. Although the algorithm is run at processor speed, the output is still the same regardless of the type of processor being used.
That is true. If you just want to pass it as test signal into fft then you can run fft at any speed then interpret your frequency value e.g. 3KHz moves to 12 KHz if you run fft at 100MHz.Now are you saying that matlab fft is ok for your vector and testbench is ok but not the actual hardware fft? Or is correct at low signal dynamic range only then I suspect clipping inside.
Yes, kaz. That is exactly what I am saying. Matlab fft and testbench (both my own and the altera generated matlab testbench) work perfectly ok. The hardware does not, though. but I am now finding out that when I clock the FFT core at frequencies less than or equal to 10MHz, the output is correct ! I am still doing some tests to see if this works over the entire dynamic range. I will keep the thread posted but I suspect that the FFT core (in my cyclone II device) cannot be clocked too fast.This actually will cause a problem for me because I will need to change the clocking of my ssram (one frequency during acquisition, and another frequency during FFT), which means I might have to use a gated clock :(
So is't timing issue, I assume you passed timing but are your sure about ssram interface timing?Regarding clocks, you use clock control block or may be just one clock with different enable rates.
yes I am now almost sure that the FFT core cannot operate at 100 MHz. It makes sense that the very low dynamic range inputs would work fine at that frequency. this is because the ripple time of carries in adders and multipliers would make the settling time for combinational logic higher and would require a slower clock. For small numbers, the ripple propagation is short so it worked. Do you think that makes sense ? clipping did not happen for sure because I read the data from ram and plot it in matlab and it is perfect !
If captured data from ram is captured at the point it goes into fft inside fpga then I will say so far so good.Then if it timing problem I expect the tool to report violations but I doubt it because I can assume that timing violations may be random and not leading to regular harmonics. At first I thought may be some MSBs are violated but then I expect chaotic output unless it involved some corner coefficient only. You may run at 1 MHz with full dynamic range and see. Also apply reset just in case.
yep, captured data is taken directly before the FFT. i ran at 200kHz, 2MHz, and 10MHz, and all work perfectly fine. I don't know how fast it can go but I know that at 100MHz it does not work. Also, it seems to be working for any dynamic range so I guess the problem is solved. Thanks for your valuable inputs !!