image thumbnail

Sigma Delta Test Bench

by

 

A test bench to simulate and analyse Sigma Delta modulators

DAC_Test.m
clear; %Clears the matlab workspace

Fin_bin = 1536;
%Fin = 256;
Fs = 2048; %Sampling frequency
NFFT = 8192; %FFT Bins
A = 1; %Amplitude of input sinusoid
nLev = 3;
Qntn_interval = 2/(nLev-1); %Quantisation intervale for the quantiser
Randomisation = 0.1; %Randomisation of steps in %
Randomisation_minus = -Randomisation;
random_num = [Randomisation*rand Randomisation*rand Randomisation*rand Randomisation*rand Randomisation*rand];
yaxis_low_limit = -120;
DWA_lim = Randomisation_minus+(Randomisation-Randomisation_minus).*rand(5,1); %Generates random numbers between -0.1 and +0.1
LSB = Qntn_interval;
%DWA_elements are formed below. They will be chosen using DWA algorithm
%inside DWA_DAC function block in simulink
DWA_elements = [DWA_lim(1)+LSB DWA_lim(2)+LSB DWA_lim(3)+LSB DWA_lim(4)+LSB DWA_lim(5)+LSB];
DWA_index_init = 1; %Starting element number to be used for DWA
DWA_index = DWA_index_init;
Fin = Fs*Fin_bin/NFFT %Input frequency calculated from Bin number


Nrun = NFFT/(Fs/Fin); %Run time for the simulator
Tin = 1/Fin; 
Ts = 1/Fs;
mdl = 'DAC_Testbench'; %Simulink modelfor performing the simulation
open_system(mdl);
set_param(mdl,'StartTime','0'); %Start time for the simulation
set_param(mdl,'StopTime',num2str(Nrun*Tin)); %Setting run time 
%open_system(strcat(mdl,'/Scope'));
sim(mdl); %Run simulink simulation
quant_error = sampled_input-quant_output; %Calculating quantisation error
t = 0:Ts/1000:(2*Tin)-(Ts/1000); %Time index for plotting continous time signal
x = A*sin(2*pi*Fin*t); %Continous time input signal

figure('NumberTitle','off','Name','Input signal')
plot(t,x,'r','LineWidth',1); %Plotting input signal
hold on;
t_sampled = 0:Ts:(2*Tin)-Ts; %Time index for sampled signal
stem(t_sampled,sampled_input(1:(2*Tin)/Ts),'b'); %Plotting sampled input
hold on;
stairs(t_sampled,quant_output(1:(2*Tin)/Ts),'k','LineWidth',3); %Plotting quantised output
hold on;
stem(t_sampled,quant_error(1:(2*Tin)/Ts),'c','LineWidth',2); %Plotting quantisation error
leg1 = legend('Continous time Input','Sampled input','Quantised output','Quantisation error');
set(leg1,'Location', 'SouthEast');
ylabel('Amplitude');
xlabel('Time');

% figure('NumberTitle','off','Name','Continous time input')
% plot(t,x,'r','LineWidth',1); 
% ylabel('Amplitude');
% xlabel('Time');
% 
% figure('NumberTitle','off','Name','Sampled Input')
% t_sampled = 0:Ts:(2*Tin)-Ts;
% stem(t_sampled,sampled_input(1:(2*Tin)/Ts),'b');
% ylabel('Amplitude');
% xlabel('Time');
% 
% figure('NumberTitle','off','Name','Quantised output');
% stairs(t_sampled,quant_output(1:(2*Tin)/Ts),'k','LineWidth',3);
% ylabel('Amplitude');
% xlabel('Time');
% 
% figure('NumberTitle','off','Name','Quantisation error')
% plot(t_sampled,quant_error(1:(2*Tin)/Ts),'c','LineWidth',2);
% ylabel('Amplitude');
% xlabel('Time');




spectrum_sampled_input = fftshift(abs(fft(sampled_input,NFFT)))/NFFT; %Fourier transform of sampled input
spectrum_quantised_output= fftshift(abs(fft(quant_output,NFFT)))/NFFT; %Fourier transform of quantised output
spectrum_DAC_output = fftshift(abs(fft(DAC_output,NFFT)))/NFFT; %Fourier transform of DAC output
spectrum_DAC_rand_output = fftshift(abs(fft(DAC_rand_output,NFFT)))/NFFT; %Spectrum of randomised DAC output
spectrum_DAC_rand_elem_selection = fftshift(abs(fft(DAC_rand_elem_selection,NFFT)))/NFFT; %Spectrum of DAC output with  randomly chosen elements.
spectrum_DAC_DWA_elem_selection = fftshift(abs(fft(DAC_DWA_elem_selection,NFFT)))/NFFT; %Spectrum of DAC output with  DWA elements.

for i = 1:length(spectrum_quantised_output) %Code fragment to ensure that spectrum value is not 0 to avoid negative infinity during mag2db
    if spectrum_quantised_output(i) == 0
       spectrum_quantised_output(i) = rand*eps; 
    end
end

for i = 1:length(spectrum_DAC_output) %Code fragment to ensure that spectrum value is not 0 to avoid negative infinity during mag2db
    if spectrum_DAC_output(i) == 0
       spectrum_DAC_output(i) = rand*eps; 
    end
end

for i = 1:length(spectrum_DAC_rand_output) %Code fragment to ensure that spectrum value is not 0 to avoid negative infinity during mag2db
    if spectrum_DAC_rand_output(i) == 0
       spectrum_DAC_rand_output(i) = rand*eps; 
    end
end

for i = 1:length(spectrum_DAC_rand_elem_selection) %Code fragment to ensure that spectrum value is not 0 to avoid negative infinity during mag2db
    if spectrum_DAC_rand_elem_selection(i) == 0
       spectrum_DAC_rand_elem_selection(i) = rand*eps; 
    end
end

for i = 1:length(spectrum_DAC_DWA_elem_selection) %Code fragment to ensure that spectrum value is not 0 to avoid negative infinity during mag2db
    if spectrum_DAC_DWA_elem_selection(i) == 0
       spectrum_DAC_DWA_elem_selection(i) = rand*eps; 
    end
end

fspacing = Fs/NFFT; %Spacing between Bins
fnyquist = Fs/2;
fstart = -fnyquist; %Starting frequency on frequency axis
fend = fnyquist-fspacing; %Ending frequency on frequency axis

faxis = fstart:fspacing:fend; %Frequency axis for plotting the spectrum (-Fs/2 to Fs/2)
faxis_half = faxis((NFFT/2)+1:end); %Half of the frequency axis (0 to Fs/2)

spectrum_sampled_input_half = 2*spectrum_sampled_input((NFFT/2)+1:end); % Sampled Input Sepctrum from 0 to Fs/2. 
spectrum_sampled_input_half(1) = spectrum_sampled_input(1); %Bin for DC should not be multiplied by 2

spectrum_quantised_output_half = 2*spectrum_quantised_output((NFFT/2)+1:end); %Quantised Sepctrum from 0 to Fs/2. 
spectrum_quantised_output_half(1) = spectrum_quantised_output(1); %Bin for DC should not be multiplied by 2

spectrum_DAC_output = 2*spectrum_DAC_output((NFFT/2)+1:end); %DAC output spectrum half
spectrum_DAC_output(1) = spectrum_DAC_output(1);

spectrum_DAC_rand_output = 2*spectrum_DAC_rand_output((NFFT/2)+1:end); %Random stepped DAC output spectrum half
spectrum_DAC_rand_output(1) = spectrum_DAC_rand_output(1);

spectrum_DAC_rand_elem_selection = 2*spectrum_DAC_rand_elem_selection((NFFT/2)+1:end); %Random stepped DAC output spectrum half
spectrum_DAC_rand_elem_selection(1) = spectrum_DAC_rand_elem_selection(1);

spectrum_DAC_DWA_elem_selection = 2*spectrum_DAC_DWA_elem_selection((NFFT/2)+1:end); %Random stepped DAC output spectrum half
spectrum_DAC_DWA_elem_selection(1) = spectrum_DAC_DWA_elem_selection(1);

figure('NumberTitle','off','Name','Spectrum of DAC with DWA');
plot(faxis_half,mag2db(spectrum_DAC_DWA_elem_selection),'g'); %Plotting randomised DAC output spectrum
ylim([yaxis_low_limit 0]);%Axis scaling
ylabel('Amplitude (dB)');
xlabel('Frequency(Hz)');

figure('NumberTitle','off','Name','Spectrum of DAC with random ESL');
plot(faxis_half,mag2db(spectrum_DAC_rand_elem_selection),'g'); %Plotting randomised DAC output spectrum
ylim([yaxis_low_limit 0]);%Axis scaling
ylabel('Amplitude (dB)');
xlabel('Frequency(Hz)');

figure('NumberTitle','off','Name','Spectrum of Real DAC output');
plot(faxis_half,mag2db(spectrum_DAC_rand_output),'g'); %Plotting randomised DAC output spectrum
ylim([yaxis_low_limit 0]);%Axis scaling
ylabel('Amplitude (dB)');
xlabel('Frequency(Hz)');

figure('NumberTitle','off','Name','Spectrum of Ideal DAC output');
plot(faxis_half,mag2db(spectrum_DAC_output),'g'); %Plotting DAC output spectrum
%ylim([yaxis_low_limit 0]);%Axis scaling
ylabel('Amplitude (dB)');
xlabel('Frequency(Hz)');

figure('NumberTitle','off','Name','Spectrum of quantised output');
plot(faxis_half,mag2db(spectrum_quantised_output_half),'g'); %Plotting quantised output spectrum
%ylim([yaxis_low_limit 0]);%Axis scaling
ylabel('Amplitude (dB)');
xlabel('Frequency(Hz)');

figure('NumberTitle','off','Name','Spectrum of sampled input');
plot(faxis_half,mag2db(spectrum_sampled_input_half),'r'); %Plotting sampled input spectrum
%ylim([yaxis_low_limit 0]);%Axis scaling
ylabel('Amplitude (dB)');
xlabel('Frequency(Hz)');



while 0
%SNR calculation
Bin = Fin_bin;
signal_value = 0;

%For IDEAL DAC
spectrum = spectrum_DAC_output;
spectrum = reshape(spectrum,1,length(spectrum));
signal_value = sum(spectrum(Bin).*conj(spectrum(Bin)));
noise_Bins = [spectrum(2:Bin-1) spectrum(Bin+1:NFFT/2)];
noise = sum(noise_Bins.*conj(noise_Bins));
SNDR_IDEAL_DAC = 10*log10(signal_value/noise)
%ENOB = floor((SNDR - 1.76)/6.02)
        
%SFDR Calculation
largest_noise_bin = 0;
for i = 1:length(noise_Bins)
    if(noise_Bins(i).*conj(noise_Bins(i)) > largest_noise_bin)
        largest_noise_bin= noise_Bins(i).*conj(noise_Bins(i));
    end
end
SFDR_IDEAL_DAC_ = 10*log10(signal_value/largest_noise_bin)

%For REAL DAC
spectrum = spectrum_DAC_rand_output;
spectrum = reshape(spectrum,1,length(spectrum));
signal_value = sum(spectrum(Bin).*conj(spectrum(Bin)));
noise_Bins = [spectrum(2:Bin-1) spectrum(Bin+1:NFFT/2)];
noise = sum(noise_Bins.*conj(noise_Bins));
SNDR_REAL_DAC = 10*log10(signal_value/noise)
%ENOB = floor((SNDR - 1.76)/6.02)
        
%SFDR Calculation
largest_noise_bin = 0;
for i = 1:length(noise_Bins)
    if(noise_Bins(i).*conj(noise_Bins(i)) > largest_noise_bin)
        largest_noise_bin= noise_Bins(i).*conj(noise_Bins(i));
    end
end
SFDR_REAL_DAC_ = 10*log10(signal_value/largest_noise_bin)

end

Contact us