1
\$\begingroup\$

While using MATLAB's Pwelch function, I am not able to match the noise floor of the "Modelled" ADC to (Delta)^2/6 {1 sided Spectrum}.

F_tone = 1e3;                       %Frequency of Tone
OSR = 64;
Fs = F_tone * OSR;                  %Sampling Frequency
time_step = 1/Fs;                   %Time between samples
total_number_of_cycles = 2^12;      %Total number of complete cycles to 
                                    %                      simulate for
FFT_number_of_cycles = 2^7;         %Number of cycles used in 1 FFT 
                                    %                      computation
Amplitude = 100;                     %Amplitude of the sine wave
Bits = 8;                                   
q = 2*Amplitude/2^Bits;             %Quantisation Interval q = 0.7812
NG = 0.375;                         %Noise Gain for Hanning Window
CG = 0.5;                           %Coherent Gain for Hanning Window
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
time_period = 1/F_tone;
t = 0:time_step:time_period * total_number_of_cycles;
y_noiseless = Amplitude*sin(2*pi*F_tone * t);
%%%%%%% Adding Noise
y = y_noiseless + (1.5*q)*(rand(size(y_noiseless))*2-1); %Adding 1.5LSB noise
y_quantised = floor(y/q) * q+q/2; %Quantising 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
N_fft = (OSR) * FFT_number_of_cycles;
Fmin = Fs/N_fft;
sn = (NG * Fmin) / (CG)^2;
[S,F] = pwelch(y,hanning(N_fft),N_fft/2,N_fft,Fs,'onesided');
S = S * sn;
semilogx(F,20*log10(S));
%[![This gives the following image][1]][1]

N_Floor = 10*log10( ((q^2)/6) * (1/max(F)) ) % = -54.9772 dB

The Signal strength in the plot is matching theoretical expectation. Theory says it should be 20*log10(2*Amplitude^2/4) = 73.9794 dB, and I am getting 73.9798 as shown in the image.

The noise floor spread by theory should be -54.9772dB, but I am getting ~-75dB in the plot.

I am not sure of the following things.
1. Am I modelling the quantisation correctly?
2. Which of my noise floor numbers are wrong? Theory or Simulated?

PWELCH obtained from MATLAB

\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

if anyone is interested in the answer, I solved it the following way.

clc
clear all
close all


%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%% DECLARING VARIABLES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
F_tone = 3.5e3;                       %Frequency of Tone
OSR = 64;
Fs = F_tone * OSR;                  %Sampling Frequency
time_step = 1/Fs;                   %Time between samples
total_number_of_cycles = 2^15;      %Total number of complete cycles to 
                                    %                      simulate for
FFT_number_of_cycles = 2^9;         %Number of cycles used in 1 FFT 
                                    %                      computation
Vref = 2; 
Amplitude = Vref/2;                     %Amplitude of the sine wave
Amax = Vref/2;

Bits = 8;                                   
q = Vref/2^Bits;             %Quantisation Interval
NG = 0.375; %Hanning
CG = 0.5; %Hanning
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%% CREATING (y,t) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
time_period = 1/F_tone;
t = 0:time_step:time_period * total_number_of_cycles;
y_noiseless = (Amplitude)*sin(2*pi*F_tone * t);
%%%%%%% Adding Uniform Noise of 4 LSB. That should reduce the 8bit ADC to a
%%%%%%% 6bit ADC. Otherwise, because my sampling frequency is a multiple of
%%%%%%% my Tone, the spectrum will skirt.
y_noise = y_noiseless + (2*q) * (rand(size(t))*2 - 1);
y = floor( y_noise/q )* q; %

%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%% FFT COMPUTATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
N_fft = OSR * FFT_number_of_cycles;
Fmin = Fs/N_fft;
sn = (NG * Fmin) / (CG)^2;

[S,F] = pwelch(y-mean(y),hanning(N_fft),N_fft/2,N_fft,Fs,'onesided');
semilogx(F,20*log10(S*sn))

N_floor = 20*log10((4*q)^2/(6*Fs))
Plot_floor = 20*log10(median(S))
Plot_higher_by = 10^(((Plot_floor - N_floor)/20))

Theoretical_SNR = 1.76 + 6.02*(Bits-2) + 20*log10(Amplitude/Amax)

signal_indx = F_tone/Fmin+1;
Fundamental = (sum(S(signal_indx-20:signal_indx+20)));
Noise = (sum(S(2:signal_indx-21)) + sum(S(signal_indx+21:end)));
SNR = 10*log10(Fundamental/Noise)

The output of the code will be

N_floor = -182.7740

Plot_floor = -182.3479

Plot_higher_by = 1.0503

Theoretical_SNR = 37.8800

SNR = 37.6677

It is important to remember that to read off the deterministic signal off of a pwelch psd, you need to scale it according to the window and Fbin. But the psd of the noise should be read without any scaling.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.