12-12-2017 11:05 AM - edited 12-12-2017 11:07 AM
I am seeing an unexplainable result from the FFT core.
16-bit input and output
output is natural order
XK index is output
Vivado 2015.2 Win7 64
VHDL host language
I created a test project to hold the generated testbench file
I instrumented the tb with code to save off the generated data and the output of the fft
hooked into the op_data that is saved from the m_axis_data_tdata
The tb runs and I can reliably graph the input signal and output results in matlab
The first thing I noticed is that the results come out at the end of the output vector, that is, DC is at index 65535, and the spikes for the increasing frequencies have indices less than 65k. The "second half" of the output vector, reverse order. I generate a 1000Hz signal and the index of its spike is 64535 - sounds plausible.
When I run the fft() in matlab on the TB generated input data, I get DC at index 0 and the test frequencies at positive indices from zero. There is a mirror image of this starting at 32768, continuing to DC at 65536.
What I read on the xilinx forums is that the core should work like matlab, FFTW, etc. (with natural order output)
If I generate a signal of 40000Hz in the TB:
theta2 := real(i) / real(MAX_SAMPLES) * 40000 * 2.0 * MATH_PI;
This shows up at the index that would be 40000, instead of wrapping around like it does in matlab. If I take the generated signal data from the TB and do a FFT on it in matlab, I get what I expect.
I have attached a screen shot from the simulator. Note the xk index where the cursor is, this is the "40000Hz" spike. The input data has 1000Hz, 30000Hz, 31000Hz, 32000Hz signals in it. (xfft_output_with_40k_sim.png)
There is a screen shot of the output from matlab plot() Fn of the same output data, "fft core output". (xfft_output_with_40k.png)
There is a screen shot of the input data processed with the matlab FFT, "input data spectrum". (input_data_matlab_fft.png)
Is there a reasonable explanation for issue 2?
12-12-2017 11:22 AM
That in MatLab everything is perfect, and aligned.
In the real world, signals are continuous, so depending on where you start and end, the resulting spectrum will have artifacts as a result of that.
12-12-2017 08:10 PM
FFT IP results are correct as well. The fft function returns a vector that appears to begin at the zero frequency and extends to the sampling frequency. In reality, the fft can only represent frequencies up to the Nyquist frequency (half the sampling frequency, ), so what are the Fourier transform amplitudes ‘frequencies’ (actually, ‘frequency bins’, not actual frequencies) above the Nyquist frequency. The reason is that the Fourier transform is symmetric about the y-axis, because the Fourier transform is mathematically defined on the interval (-Inf,Inf). The actual Fourier transform therefore has negative frequencies. When you are using FFT core or do FFT in real time the output of FFT will show the actual frequencies.). You can see the identical results wiith Shifting the fft output (using the fftshift function).
Hope it make sense for you
12-13-2017 06:31 AM
Thanks for the responses! To clarify, in the TB, there is no "sampling frequency" so the first "bin" should correspond to 1/32768Hz. I assigned Hz to these to establish a baseline of understanding. In the matlab scripts I use, there is a sampling_freq variable because in its real-world use, the samples it FFTs come from ADCs, etc. Using Hz also lets us use nyquist of 1/2 MAX_SAMPLES, in this case 32767Hz.
Given that, when the TB generates a sample buffer, the math establishes the max freq that can be resolved. To test this, I ran the TB with both 30000Hz and 40000Hz signals. Look at the results I attached. The first one is 30000Hz. Notice that the signal goes from + value to -value from sample to sample (the .im is not expanded). I expect this when the nyquist is 32767Hz. Then take a look at the second image. This is 40000Hz, notice it is an undersampled mess. Totally expected. This should show up in the spectrum somewhere less than the nyquist. The matlab FFT resolves this. In the images from my earlier post, in the "input data spectrum" note the spike at about 25000Hz (sorry for the sparse x axis). The XFFT is somehow showing the signal at 40000, hence the question. It is really strange that it can do this given the mess that the input signal is. Even stranger still, it can resolve 50000Hz and 60000Hz! The input signals look like crap and the XFFT is able to correctly resolve them.
I have a theory on this, but only the authors of the XFFT code can prove this out: I think the XFFT is better than the "typical" fft. When we use a FFT in real life, we take care that XFFT does not get presented with garbage, the data is windowed, etc. My bet is that by virtue of its design, the XFFT really can resolve MAX_SAMPLES frequencies. (I think I proved just that) I noticed in the documentation for the core the output data arrangement is not specifically documented, which "bins" correspond to DC, nyquist, etc. There is an undocumented characteristic going on here....
03-15-2019 10:02 AM