- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
hello;
what i want to do is to get spectrum of an sinusoidal signal using the altera fft core i have generated a v8 fft with the following setting: fft point : 64 (to start with) architecture : brust data width : 16 twidle width : 16 i am including the matlab files in the attachment .. the input is a 64 point 2`compliment form. in the compare.m file i am doing three fft,,2 matlab fft and 1 altera core fft what i cant figure out is why the magnitude of the second and the the third power spectrum has bigger amplitude than the first fft at the signal fundmental frequency ? and why are those two are not so clean like the first one ? please have a look .. thanks to anyone who replies.Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Mesbah,
if you plot(y2) or (y) you will see the distortion you are causing... good luck- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
i dont think its distortion i just raised the negitive part of the signal up... do u think i shouldnt do that ?..... should i feed y1(has pos & neg ) to the altera fft ?
if so how can i express negative part of the signal in vhdl ? thanks- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Mesbah,
you are causing fatal distortion to your nice sine waves by offsetting the negative halves up as this implies high frequencies due to sudden changes. Remember time domain and freq domain are related: sudden changes of amplitude or phase in time domain imply high frequencies, and high freq imply sudden changes in time domain... your ifft expects signed input, so I am told. The vhdl people allow you + representation. std_logic is read according to the way you decide(or ifft decides). If you want to store your sine data in lut then use mif and it accepts signed values. if you want to store 64 data on wires(as constants) then and to avoid the hassle of conversions use type "signed" then convert as required. Here is my adjustment of your code: clear; N = 64; Fs = 64; INVERSE = 0; y = round((2^15-1)*sin(2*pi*5*[0:63]/Fs)); Matlab_fft = fft(y); %[Y, exp_out] = fft_1_model(y,N,INVERSE); %Altera_fft = Y.*2.^(-exp_out); power_fft1 = abs(Matlab_fft); %power_fft2 = abs(Altera_fft); plot(power_fft1);hold %plot(power_fft2,'r') ************* if for any other reason you want to get rid of negative sine data then offset all values up, you will then get your frequency and some dc: y2 = y + abs(min(y)); figure;hold plot(y); plot(y2,'r')- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have a different but probably somewhat related question. I have a continuous digitized 1000Hz sine wave going to the FFT input. The FFT is configured with a streaming architecture. I get the expected two (almost identical) peaks from the output-one at the positive side and the other at the negative side. My question is how come the values for the peaks fluctuate constantly. In other words, the amplitudes for these two peaks keep changing, and the difference between the maximum and minimum amplitude is quite large.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
You got a bug somewhere. One possible subtlety is this: Is your sine input continuous in phase. If you are reading sine LUT make sure there is phase continuity at the end of the cycle. You need to carefully choose your data points and not repeat the first value at the end. for a correct cycle I will do this: sin_data = sin(2*pi*[0:1023]/1024); plot(sin_data) then scale it for hardware. choose other than [0:1023]/1024 for your frequency case. You should see the first sample is 0 but the last sample is just under zero and shouldn't be zero. Having said that it is unlikley that phase will cause major amp fluctuations unless it is grossly wrong. So look for timing issues, your sampling clk and the way your input actually enters the fft.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for your quick reply...
My input is an analog sine wave passing through an ADC and then into the FFT, so I guess it can't be a phase problem. So what am I supposed to look for related to timing issues? The FFT did not output any errors!- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If your fft functional simulation is ok and your timing report is ok then we can forget about timing. I will check these issues:
1) is your analogue input not fluctuating. can you exclude that by inputting from a LUT as a test. 2) is your data representation from ADC correct. Some ADCs use 2's complement, others use offset binary. They are different of course. 3) is your scaling correct. This is the most likely culprit for now. Remember altera has left scaling algorithm to the designer. make sure you are scaling each block correctly and not latching the exponent from block to block. 4) is there any clipping/overflow of data, though clipping will lead to widening of spectrum side lobes, overflow and unwrapping will lead to spikes on either side of your sine point.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I changed the FFT to a 256-point burst architecture with the inputs coming from a ROM. When the ROM content is from a digitized 1000Hz analog sine wave, I get two peaks with sidelobes (is that what you call them?). However, when I change the ROM data to numbers generated by the equation
ROM_data = sin(2*1000*pi*[0:255]/256) The FFT output is all zeros, and even the exponent is all zeros. What happened?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Try make changes gradually, too many changes will not help you. So put back your design streaming as original then input from LUT instead of ADC.
your equation below is not right for its purpose: ROM_data = sin(2*1000*pi*[0:255]/256) plot(ROM_data) and see. It should be like this: ROM_data = sin(2*pi*[0:255]/256); then scale up: data = round(ROM_data * (2^15-1)); %for 16 bit signed Use plot(data) to check result before you go to hardware. The frequency you get from this sinusoid = Fs/256 so if your sampling clk = 50MHz then you should get a line at 50/256MHz since each cycle takes that many clks to finish.If you want other higher frequencies then you can jump the LUT regularly.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This question is on interpreting the FFT outputs...
So I have this 64-point streaming FFT with the inputs generated by the equation ROM_data = sin(2*pi*[0:63]/64); then scale up by data = round(ROM_data * (2^15-1)); %for 16 bit signed These numbers for the FFT input are stored in ROM (LUT). When the first sample is 0 and the last sample is just under zero, the FFT outputs are: source_exp = -7 for all the bins source_real = 0 for all the bins source_imag = -8192 in the second bin and +8192 in bin 64 (last bin) However, when the first sample is just above 0 and the last sample is zero, i.e., the input data is shifted one sample point to the right, the FFT outputs are: source_exp = -6 for all the bins source_real = 1606 in the second bin and 1606 in bin 64 (last bin) source_imag = -16304 in the second bin and +16304 in bin 64 (last bin) In these two cases, the FFT input samples are exactly the same, the only difference is that the second case is shifted to the right by one sample point. Shouldn't the FFT outputs be the same for both cases? And if so, how do you interpret what I got as shown above to see that they are the same? Are you supposed to somehow combine the real and the imag parts together?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Continuing with my question on interpreting the FFT output...
May be the observation that I described in my previous post has something to do with my initial question several posts ago, i.e., the amplitudes fluctuate constantly with a constant input. Because I am only looking at the source_exp and source_real FFT outputs, and ignoring the source_imag output, therefore, in every 64th cycle, source_real goes to 0. And for the other cycles, source_real decreases between the max and 0? Do you thing this is the reason?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
To avoid guess work you better compare results with matlab. in matlab: test = round(fftshift(fft(ROM_data)); test must equal your hardware fft(allowing for rounding variations) You may use cos instead of sin since sin will give zero real. you may also want to visulaise the spectrum of your output or matlab output by typing: f = linspace(-.5,.5,64); plot(f,abs(test)) or plot(f,abs(your fft output));- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I glanced at your mif and it looks ok to me, tomorrow I will do fft in Matlab and send you my results(hopefully).
complex signals in hardware are represented on two (real) channels. One is treated as real and the other as representing the imaginary value(units of sqrt(-1). Don't worry about details now. All you need is that to see amplitude response you look at absolute value i.e. Amplitude of complex vector = sqrt(I^2 + Q^2). plot amplitude and you should see two symmetrical lines unless your input is sine/cosine which leads to one line only(non-symmetrical spectrum). Complex math is same as vector math...- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
What are the I and Q in your equation sqrt(I^2 + Q^2)? Are they the real and imaginary values from the FFT source_real and source_imag?
Do I do the scaling with source_exp on both the source_real AND source_imag? Also do I do the scaling before or after doing the sqrt(I^2 + Q^2)?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- What are the I and Q in your equation sqrt(I^2 + Q^2)? Are they the real and imaginary values from the FFT source_real and source_imag? --- Quote End --- yes, I & Q are the special names in communications given to the two channels representing in effect a complex signal, I = inphase, Q=Qudrature. --- Quote Start --- Do I do the scaling with source_exp on both the source_real AND source_imag? --- Quote End --- you need to scale according to the way altera have done their IP. I believe it is the output of fft that must be scaled...ofcourse, check the IP data sheet. --- Quote Start --- Also do I do the scaling before or after doing the sqrt(I^2 + Q^2)? --- Quote End --- In normal computation such as matlab you don't need any scaling. Altera simply left that for you. So for your hardware results yes do scaling first. I checked the matlab output and it looks like your results: your result .....................matlab fft real = zeros .....................same imag(0) = 0 .....................same imag(1) = -8192 ..............-1048576 imag(63) = +8192 ............+1048576 imag(others) = 0 ..............same If you now multiply 8192 by 2^7 you get matlab result. Your problem now is this: your final output value needs far more bits than just 16 signed so you need to divide down by truncation to a max of 32767 or less. Your other case of having one sample just above zero ...etc. No don't do that. By doing that you are no longer having a proper sine in the sense of orthogonality in a complex vector.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks a lot Kaz. You have been so helpful.
I am now going to change the input to analog audio data passing through an ADC. When I get that to work, I think I will post my entire results here so that people like me don't have to keep asking the same questions about implementating the FFT. Enoch- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
However, my suspicion now is that the fluctuating amp is due to one or both of the following:
1) wrong fft scaling 2) fft and its scaling ok but your test is misleading as you may be injecting the analog sinusoid with different phase each fft block. Your fft resolution is too low, it is better to have many sinusoid cycles per fft block rather than just one cycle as phase changes become exagerated. So either increase the fft resolution to say 2048 and/or increase the speed of your sinusoid.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
How can I increase the speed of my sinusoid if my input is a sound wave with a certain frequency?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The easiest fix for you is to first make sure your fft scaling is ok. Not just the use of exponent but your truncation afterwards. If this is ok then your fft is ok and I wouldn't worry about the test.
If you want your test to do better then increase fft resolution. If your audio is received upsampled then you may decimate it down to minimum (for test purposes only). Thats what I labelled speed by mistake. Remember fft resolution doesn't have to be equal to number of points per sinusoid cycle, that ruins the test unless you get the phase exactly same per each block. In short make your fft 2048 and repeat the test. Try also pass the audio to both real and imaginary so that the phase change is on both channels(again for test purpose only).
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page