Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Valued Contributor III
1,211 Views

FFT IP - correct magnitude calculation

Hi guys, 

 

I try to use the FFT IP Core in Burst Mode with 4096 points (single output engine), .Input and Twiddle factors are 12 bit. The input signal comes directly from the ADC with a sample rate of 25kHz. The input sample stream is windowed with a hanning function. The signal then goes to the sink_real input. The sink_imag input is hard wired to zero value.  

 

The output of the IP core (source_real and source_imag) is used to calculate the spectrum magnitude by the formula magnitude=sqrt(source_real^2+source_imag^2). I use the Altera sqrt megafunction for the calculations. I skip the remainder of the sqrt megafunction because I have no idea, yet, how to calculate this to my final result. I think, maybe, I don't need that for my purposes. . .  

 

Anyway, so far so good, everything works until this stage. I am able to see a nice spectogram in Signal Tap. 

 

However, here is my problem: I just don't get the magnitude working as i expect it to be. I know, that there is this scaling factor output out of the fft core which determines the shifts in a full scale output. But please forget this scaling factor for a moment. 

If I adjust the input signals amplitude in that way, that the scaling factor of the FFT core is not changing, I would expect the magnitude of the spectrum to change within a certain margin. But this does not happen. I can clearly see the change of the amplitude of my input signal on an off the shelf oscilloscope but there is no notable change in the magnitude of the the spectrum. 

 

Okay, now, I take the scaling factor from the fft into account. 

If i adjust the external signal in a way, that the fft core switches the scaling factor and I do not shift my source_real and source_imag signal into the according direction, I see a significant difference in the calculated magnitude. If I calculate a full_scale value for the source_real and source_imag signals, then the calculated magnitude will not change at all over the whole input range of my input signal. 

 

It seems as if there is something like an AGC (automatic gain control) working that keeps my magnitude on a constant level, no matther what the amplitude of the input signal is. 

 

I really wonder, what I can do to calculate a ,magnitude that follows the inputs amplitude. As i said, the frequency recognition of the fft core works perfectly. If I shift the input freuency, I see this change in my signal tap spectrum analyzer, but the changes in magnitude are just not working as expected. 

 

Maybe the information I gave here is a little bit confusing but maybe there is somebody out there who may have some hints I can look into in order to get my magnitude calculation correct. I'm also able to supply Signal Tap screenshots or whatever is needed in order to help me with this issue. 

 

Regards, 

Maik
0 Kudos
5 Replies
Highlighted
Valued Contributor III
6 Views

Okay, I must admit, that without some example data it must be hard for you to even understand, what I'm asking for ;-) 

 

I uploaded my Matlab simulation files for the core. This simulation is doing exactly, what I'm expecting: With increasing/decreasing amplitude of my frequency modulated signal, the magnitude of the fft result is also increasing/decreasing. The adjustment with the scaling factor from the core leads to a smooth increas/decrease of the magnitude signal over the whole input range. This is just not happening with my current fft implementation. 

 

I hope, that somebody can confirm, that if it works in this simulation, it will also work in the hardware. All I have to do is to implement it correctly. 

 

The next step should be to simulate this data in modelsim. Therefore, i would like to create some binary data with this script, that can be used as input to my vhdl module as if it was coming from the ADC. I prefer to put in the ADC like binary format. As you can see, the script is already able to create a test data file. Unfortunately, I have no idea how to scale the matlab values into the binary 12 bit value range, so that it would match the real worl expected data. 

Any hints for that and additional improvement comments are very much welcomed. 

 

regards, 

Maik
0 Kudos
Highlighted
Valued Contributor III
6 Views

It may be a stupid suggestion, but did you have a look at the FFT input in signaltap too, and check that the signal was correct, and did change it's amplitude as it should? 

AFAIK there is no automatic gain adjustment in the FFT IP, but you could have one in your ADC chain, or there could be a problem with the signal acquisition (saturation, or bad handling of the sign bit) and as a result the amplitude of the analog input signal could have little influence on the FFT result. 

Did you also have a look at the FFT output before your module that calculates the magnitude?
0 Kudos
Highlighted
Valued Contributor III
6 Views

Hi Daixiwen, 

 

I'm currently investigation these questions you ask in the matlab and modelsim simulations. I was able to regenerate the hardware results in matlab by putting data with different (extreme) scaling factors into the fft core. Now, I try to find out, where in the hardware my calculations go wrong. It is well possible, that I did some input data scaling errors (or implement them with my hanning window calculation). 

 

Right now, I'm pretty confident that I will discover those errors. After some iterations, my modelsim simulation looks quiet good. Sometimes, it is just helpful to ask some questions in the forum to get the thoughts straight, even if you don't get the answer (which I quiet understand by looking at my first post ;-)). 

 

The one thing I have to investigate a little deeper is the skipping of the remainder of the sqrt megafunction. I have no idea to what degree this will affect the accuracy of my results. 

 

What really impressed me during the matlab simulations is the fact, that the matlab model of the altera fft really behaves like in the hardware once you put the same data in. So the model really seems to be bit-accurate like to manual promises ;-). 

 

Regards, 

Maik
0 Kudos
Highlighted
Valued Contributor III
6 Views

Hi guys, 

 

I'm making good progress so far. However, I have to add a question to this topic regarding more the DSP theory of analyzing frequency modulated signals. Maybe somebody has some good advices for me. 

 

In the attachment you find pictures from my Excel analysis of my modelsim output (Modelsim only writes the interesting parts to Excel, so that the frequency spectrums are all close to each other. Here I have devided them with the blue vertical lines). I was generating 12 bit binary test data with matlab and 12 bit flattop window data as input to my FFT core. The core itself is still the buffered burst one with N=4096. The simulated sampling frequency is 25000 kHz. 

 

In my matlab script that I attached in a former post, I created the frequency modulated signal some kind like this: 

 

Xfm=Ac*cos(2*pi*Fc*t + (randn(1) * 0.25 + beta)*cos(2*pi*Fsig*t))+offset; (1) 

 

I had a little random factor in there to simulate a small frequency jitter. You can just disregard that since it has nothing to do with my question.  

 

So the most basic frequency modulation formula may be this: 

 

Xfm=Ac*cos(2*pi*Fc*t + beta*cos(2*pi*Fsig*t)); (2) 

 

If I generate my testdata from that formula, I can get really nice magnitude results from the FFT Core (see attachment No. 1). The magnitude of the peaks in my spectrum were increasing/decreasing according to the variation of the factor Ac. 

My modelsim simulation puts out the results like in the first attachment. The peaks on both ends of the frequency range have about the same magnitude.However, this result does not came coincidently but took me some adjustments in all the parameters I have (fft depth, sampling rate, frequency deviation ratio, etc.). I had a bad feeling about that because when I change some of those parameters, I get results like in attachment No. 2. There, the peaks on each freqency corner are of different magnitude. 

 

In order to get this simulation result I changed the test data generation formula like that: 

 

Xfm=Ac*cos(2*pi*Fc*t + beta*cos(2*pi*Fsig*t + randn(1) * 2))+offset; (3) 

 

The difference now is, that the samples I generate not all start at the same angle but at a random one. 

 

My question is, if there is a procedure to set up the fft correctly if all parameters are known, but you cannot determine at which angle the sampling of the data starts. 

 

Here is what i think: 

 

If I have a fm signal with a frequency deviation rate of say 15Hz, then it took the signal 66.67ms to make a whole rotation. So I have to sample at least that amount of time to get both ends of the frequency range. This would lead, at a sampling frequency of 25Khz to 1667 samples (rounded). With this number of sample in my fft, i would expect that it would lead to a spectrum shown in attachment No. 1. But it isn't. It shows a spectrum that may only have a peak at either of the upmost or downmost frequency. So I increased the number of samples to the point, where I am now (4096) in order to get two nice peaks at the upmost and downmost frequency. But now, as I described, if I change my test data formula from (2) to (3), i get the results displayed in attachment No. 2. 

 

So in the end my question is: How can I set up the parameters of a fft (Fs and N) in order to get results as close to attachment No. 1 if I know all the parameters of my Fm signal except the modulation depth (Ac) and the point in time where actually the sampling of my real world data starts. 

Additionaly, does it improve the result if I increase the amount of time (and therefore also samples) that I "look" on the Fm signal and how much time does it need to make a good magnitude determination regarding the whole frequency spectrum of my Fm signal. 

 

As I described, I use the flattop window for my analysis because it should be the best for magnitude determination (so says the literature). 

 

I know, it's a long post, but if somebody can give me some hints or can point me to some literature that handles exactly those questions I have, I would be very happy. 

 

Regards, 

Maik
0 Kudos
Highlighted
Valued Contributor III
6 Views

 

--- Quote Start ---  

Hi guys, 

 

I'm making good progress so far. However, I have to add a question to this topic regarding more the DSP theory of analyzing frequency modulated signals. Maybe somebody has some good advices for me. 

 

In the attachment you find pictures from my Excel analysis of my modelsim output (Modelsim only writes the interesting parts to Excel, so that the frequency spectrums are all close to each other. Here I have devided them with the blue vertical lines). I was generating 12 bit binary test data with matlab and 12 bit flattop window data as input to my FFT core. The core itself is still the buffered burst one with N=4096. The simulated sampling frequency is 25000 kHz. 

 

In my matlab script that I attached in a former post, I created the frequency modulated signal some kind like this: 

 

Xfm=Ac*cos(2*pi*Fc*t + (randn(1) * 0.25 + beta)*cos(2*pi*Fsig*t))+offset; (1) 

 

I had a little random factor in there to simulate a small frequency jitter. You can just disregard that since it has nothing to do with my question.  

 

So the most basic frequency modulation formula may be this: 

 

Xfm=Ac*cos(2*pi*Fc*t + beta*cos(2*pi*Fsig*t)); (2) 

 

If I generate my testdata from that formula, I can get really nice magnitude results from the FFT Core (see attachment No. 1). The magnitude of the peaks in my spectrum were increasing/decreasing according to the variation of the factor Ac. 

My modelsim simulation puts out the results like in the first attachment. The peaks on both ends of the frequency range have about the same magnitude.However, this result does not came coincidently but took me some adjustments in all the parameters I have (fft depth, sampling rate, frequency deviation ratio, etc.). I had a bad feeling about that because when I change some of those parameters, I get results like in attachment No. 2. There, the peaks on each freqency corner are of different magnitude. 

 

In order to get this simulation result I changed the test data generation formula like that: 

 

Xfm=Ac*cos(2*pi*Fc*t + beta*cos(2*pi*Fsig*t + randn(1) * 2))+offset; (3) 

 

The difference now is, that the samples I generate not all start at the same angle but at a random one. 

 

My question is, if there is a procedure to set up the fft correctly if all parameters are known, but you cannot determine at which angle the sampling of the data starts. 

 

Here is what i think: 

 

If I have a fm signal with a frequency deviation rate of say 15Hz, then it took the signal 66.67ms to make a whole rotation. So I have to sample at least that amount of time to get both ends of the frequency range. This would lead, at a sampling frequency of 25Khz to 1667 samples (rounded). With this number of sample in my fft, i would expect that it would lead to a spectrum shown in attachment No. 1. But it isn't. It shows a spectrum that may only have a peak at either of the upmost or downmost frequency. So I increased the number of samples to the point, where I am now (4096) in order to get two nice peaks at the upmost and downmost frequency. But now, as I described, if I change my test data formula from (2) to (3), i get the results displayed in attachment No. 2. 

 

So in the end my question is: How can I set up the parameters of a fft (Fs and N) in order to get results as close to attachment No. 1 if I know all the parameters of my Fm signal except the modulation depth (Ac) and the point in time where actually the sampling of my real world data starts. 

Additionaly, does it improve the result if I increase the amount of time (and therefore also samples) that I "look" on the Fm signal and how much time does it need to make a good magnitude determination regarding the whole frequency spectrum of my Fm signal. 

 

As I described, I use the flattop window for my analysis because it should be the best for magnitude determination (so says the literature). 

 

I know, it's a long post, but if somebody can give me some hints or can point me to some literature that handles exactly those questions I have, I would be very happy. 

 

Regards, 

Maik 

--- Quote End ---  

 

 

 

hi, do you know how to find the peaks and their locations of source_real in verilog code?
0 Kudos