It seems the signal power is 3dB higher than actual power. Does anyone can explain me why?
For example, I have f(t)=A*sin(2*pi*f*t), its power is f(t)^2 integrated over a cycle then divide the cycle period, (1/T*int(f(t)^2)) which is equal to A^2/2 as expected. (match with RMS calculation as well =(A/sqrt(2))^2)
However, both Cadence Virtuoso dft and Matlab FFT give me signal power = A^2.
The way how I calculate the power is as below: I assume the amplitude of the single tone in one bin of FFT results (coherent sampling) is magx. I calculate the power as magx^2.
I have to calculate the power in this way instead of (magx/sqrt(2))^2 because the noise from all other bins are calculated as sum squared. Otherwise, my SNR will be wrong.
From another perspective, it means the noise is also 3dB higher than actual gaussion noise variance value. So the final SNR is correct if I calculate the signal power as magx^2, which is 3dB higher than actual signal power.
I just wonder why there is 3dB difference in fft results compared with actual power, especially for noise? It seems to me the FFT report peak magnitude instead of rms magnitude.
I have the code attached.
%%whether fft give noise in rms or peak, what is the correct snr?
%%SNR/FFT/SFDR/SNDR/noise simulation
%%https://www.mathworks.com/help/signal/ref/snr.html#bt3er4n
%%https://www.mathworks.com/help/matlab/ref/fft.html
clear;close all; rng default %rng(1);
FlagTwoTone = false; tone1 = 53/128*800e6; Amp = 0.532 * 10^(1.37/20); %input amplitude * PGA gain = 0.623
fs = 800e6; N = 128; t = (0:N-1)*1/fs; freq = fs*(0:(N/2))/N; noisestd = 300e-6; % assume noise std = 300 uV
sig = Amp*sin(2*pi*tone1*t); noise = noisestd*randn(size(sig)); %zero mean, variance = noisestd^2
myx = sig + noise; Tone1dB = 20*log10(Amp/sqrt(2)) noisedB = 20*log10(noisestd) %deltadB= Tone1dB - noisedB
mySNRviasnr = snr(sig, noise) Y = fft(myx, N); %length(myx) = N
P2 = abs(Y/N); %double sided fft spectrum, convert complex to mag and then divided by N=128, why divide 128?
P1 = P2(1:N/2+1); %matlab starts with 1
P1(2:end-1) = 2*P1(2:end-1); modP1 = P1; figure(1); plot(freq,P1) title('Single-Sided Amplitude Spectrum of myx(t)') xlabel('f (Hz)') ylabel('|P1(f)|') grid on; simTone1amp = 0; simTone1index = 0; simTone1freq = 0; for i = 1:length(modP1) if simTone1amp < modP1(i) simTone1amp = modP1(i); simTone1index = i; end end %simTone1index
%simTone1amp =P1(simTone1index)
simTone1freq = freq(simTone1index); modP1(simTone1index) = 0; simTone1dB = 20*log10(simTone1amp) if FlagTwoTone %two tones only
simTone2amp = 0; simTone2index = 0; simTone2freq = 0; for i = 1:length(modP1) if simTone2amp < modP1(i) simTone2amp = modP1(i); simTone2index = i; end end simTone2freq = freq(simTone2index); modP1(simTone2index) = 0; end simHarmonicAmp = 0; simHarmonicIndex = 0; simHarmonicFreq = 0; %test = 0;
for i = 1:length(modP1) %test = test + modP1(i)^2;
if simHarmonicAmp < modP1(i) simHarmonicAmp = modP1(i); simHarmonicIndex = i; end end simHarmonicFreq = freq(simHarmonicIndex); fftTotalNoise = sum(modP1.^2);%sum squared total noises
simNoisedB = 10*log10(fftTotalNoise) %test
if FlagTwoTone else SNDR = 10*log10(simTone1amp^2/fftTotalNoise) end
Best Answer