% Matlab code to model Third-Order Type-2 Analog Charge Pump PLL 
% Phase noise modeling requires 2 files for the reference clock and VCO
% noise placed in the same directory. These are "ref_clk_data_image.txt"
% and "lc_vco_pn.txt".

clear all;

% PLL Block Settings
r1=4e3;
Icp=305e-6;
KPD=Icp/(2*pi);
KVCO=2*pi*1e9;
N=90;
KDC1=KPD*KVCO*r1/N;
c=74.2e-12;
c2=5.75e-12;

g_num1=(KDC1*N).*[1 1/(r1*c)];
g_den1=r1*c2.*[1 (c+c2)/(r1*c*c2) 0 0];

xfer_function1=tf((1/N)*g_num1,g_den1);

% For bode function: bode(xfer_function,{xaxis begin, xaxis end});
%figure;
%bode(xfer_function,{1e3, 1e7});
[mag1,phase1,w1]=bode(xfer_function1);
%grid on;

mag_plot1(1,:)=mag1(1,1,:);
phase_plot1(1,:)=phase1(1,1,:);


figure; 
subplot(2,1,1); semilogx(w1/(2*pi),20*log10(mag_plot1),'-b'); grid on;
subplot(2,1,2); semilogx(w1/(2*pi),phase_plot1,'-b'); grid on;


figure;
subplot(2,1,1); 
A=semilogx(w1/(2*pi),20*log10(mag_plot1),'-b'); grid on;
set(A, 'LineWidth', [2.0]);
AX=gca;
set(AX, 'FontName', 'utopia');
set(AX, 'FontSize', [10]);
%set(AX, 'LineWidth', [2.0]);
set(AX, 'XLim', [2e4 2e8]);
%set(AX, 'XTick', [0.5 1 5 10]);
set(AX, 'YLim', [-70 80]); 
%set(AX, 'YTick', -20:5:25);
set(AX, 'YColor', [0 0 0]);
HY = get(AX, 'ylabel');
set(HY, 'string', '|LG| (dB)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
subplot(2,1,2); 
B=semilogx(w1/(2*pi),phase_plot1,'-b'); grid on;
set(B, 'LineWidth', [2.0]);
%set(H, 'Color', [0 0 0]);
AX=gca;
set(AX, 'FontName', 'utopia');
set(AX, 'FontSize', [10]);
%set(AX, 'LineWidth', [2.0]);
set(AX, 'XLim', [2e4 2e8]);
%set(AX, 'XTick', [0.5 1 5 10]);
set(AX, 'YLim', [-180 -110]); 
%set(AX, 'YTick', -20:5:25);
set(AX, 'YColor', [0 0 0]);
HX = get(AX, 'xlabel');
set(HX, 'string', 'Frequency (Hz)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
HY = get(AX, 'ylabel');
set(HY, 'string', 'Phase(LG) (degrees)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
%Htitle = get(AX, 'title');
%set(Htitle, 'string', 'Channel Frequency Responses','FontName','utopia', 'FontSize', [20], 'Color', [0 0 0]);
%L=legend({'Cross-Correlation Method','Ideal Model'},'Location','northeast');
%set(L, 'FontSize', [10]);
%M=text(20, -7, '26GHz Loss')
%set(M, 'HorizontalAlignment','center','FontSize', [10])







%% Closed Loop Transfer Function
%cl_num1=(N*KDC1).*[1 1/(r1*c)];
%cl_den1=[r1*c2 (c+c2)/c KDC1 KDC1/(r1*c)];
cl_num1=(KPD*KVCO/c2).*[1 1/(r1*c)];
cl_den1=[1 (c+c2)/(r1*c*c2) KPD*KVCO/(N*c2) KPD*KVCO/(N*r1*c*c2)];
vco_on_num=[1 (c+c2)/(r1*c*c2) 0 0];
vco_in_num=KVCO.*[1 (c+c2)/(r1*c*c2) 0];
cp_num=(KVCO/c2).*[1 1/(r1*c)];


cl_xfer_function1=tf(cl_num1,cl_den1);
vco_on_xfer_function1=tf(vco_on_num,cl_den1);
vco_in_xfer_function1=tf(vco_in_num,cl_den1);
cp_xfer_function=tf(cp_num,cl_den1);

w_pll=logspace(2,11,1000);
[cl_mag1,cl_phase1,w1]=bode(cl_xfer_function1,w_pll);
[vco_on_mag1,vco_on_phase1,w1]=bode(vco_on_xfer_function1,w_pll);
[vco_in_mag1,vco_in_phase1,w1]=bode(vco_in_xfer_function1,w_pll);
[cp_mag,cp_phase,w1]=bode(cp_xfer_function,w_pll);

cl_mag_plot1(1,:)=cl_mag1(1,1,:);
vco_on_mag_plot1(1,:)=vco_on_mag1(1,1,:);
vco_in_mag_plot1(1,:)=vco_in_mag1(1,1,:);
cp_mag_plot(1,:)=cp_mag(1,1,:);
figure('RendererMode','manual');
H=semilogx(w1/(2*pi),20*log10(cl_mag_plot1),'-b',w1/(2*pi),20*log10(cp_mag_plot),'-r',w1/(2*pi),20*log10(vco_in_mag_plot1),'-g',w1/(2*pi),20*log10(vco_on_mag_plot1),'-m');
set(H, 'LineWidth', [2.0]);
grid on;
AX=gca;
set(AX, 'FontName', 'utopia');
set(AX, 'FontSize', [10]);
%set(AX, 'LineWidth', [2.0]);
set(AX, 'XLim', [10 7e9]);
%set(AX, 'XTick', [0.5 1 5 10]);
%set(AX, 'YLim', [-50 10]); 
%set(AX, 'YTick', -20:5:25);
set(AX, 'YColor', [0 0 0]);
HX = get(AX, 'xlabel');
set(HX, 'string', 'Frequency (Hz)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
HY = get(AX, 'ylabel');
set(HY, 'string', '|NTF| (dB)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
%Htitle = get(AX, 'title');
%set(Htitle, 'string', 'Channel Frequency Responses','FontName','utopia', 'FontSize', [20], 'Color', [0 0 0]);
L=legend({'Reference','Charge Pump','Loop Filter R','VCO'},'Location','southeast');
set(L, 'FontSize', [10]);
%M=text(20, -7, '26GHz Loss')
%set(M, 'HorizontalAlignment','center','FontSize', [10])

figure;
A=semilogx(w1/(2*pi),20*log10(cl_mag_plot1),'-b');
grid on;
set(A, 'LineWidth', [2.0]);
%set(H, 'Color', [0 0 0]);
AX=gca;
set(AX, 'FontName', 'utopia');
set(AX, 'FontSize', [10]);
%set(AX, 'LineWidth', [2.0]);
set(AX, 'XLim', [1e4 1e9]);
%set(AX, 'XTick', [0.5 1 5 10]);
%set(AX, 'YLim', [-50 10]); 
%set(AX, 'YTick', -20:5:25);
set(AX, 'YColor', [0 0 0]);
HX = get(AX, 'xlabel');
set(HX, 'string', 'Frequency (Hz)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
HY = get(AX, 'ylabel');
set(HY, 'string', 'Transfer Function (dB)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
%Htitle = get(AX, 'title');
%set(Htitle, 'string', 'Channel Frequency Responses','FontName','utopia', 'FontSize', [20], 'Color', [0 0 0]);
%L=legend({'Cross-Correlation Method','Ideal Model'},'Location','northeast');
%set(L, 'FontSize', [10]);
%M=text(20, -7, '26GHz Loss')
%set(M, 'HorizontalAlignment','center','FontSize', [10])


fref=156.25e6;
load 'ref_clk_data_image.txt';
ref_clk_data=ref_clk_data_image;
ref_clk_freqs=ref_clk_data(:,1);
ref_clk_pn_dBc=ref_clk_data(:,2);

figure;
semilogx(ref_clk_freqs,ref_clk_pn_dBc);
grid on;
xlim([10 4e7]);

% Integrate phase noise from 10kHz to 1MHz
fstart=1e4;
fstop=10e6;
[~,fstart_i]=min(abs(ref_clk_freqs-fstart))
[~,fstop_i]=min(abs(ref_clk_freqs-fstop))
rms_jitter=sqrt(2/(2*pi*fref)^2*trapz(ref_clk_freqs(fstart_i:fstop_i),10.^(ref_clk_pn_dBc(fstart_i:fstop_i)/10)))

ref_clk_pn_dBc_new=interp1(ref_clk_freqs*2*pi,ref_clk_pn_dBc,w_pll,'linear','extrap');

figure;
semilogx(ref_clk_freqs,ref_clk_pn_dBc,'-b'); hold on;
semilogx(w_pll/(2*pi),ref_clk_pn_dBc_new,'-r');

figure;
A=semilogx(w_pll/(2*pi),ref_clk_pn_dBc_new,'-b'); hold on;
grid on;
set(A, 'LineWidth', [2.0]);
%set(H, 'Color', [0 0 0]);
AX=gca;
set(AX, 'FontName', 'utopia');
set(AX, 'FontSize', [10]);
%set(AX, 'LineWidth', [2.0]);
set(AX, 'XLim', [10 40e6]);
%set(AX, 'XTick', [0.5 1 5 10]);
%set(AX, 'YLim', [-200 -40]); 
%set(AX, 'YTick', -100:20:60);
set(AX, 'YColor', [0 0 0]);
HX = get(AX, 'xlabel');
set(HX, 'string', 'Frequency (Hz)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
HY = get(AX, 'ylabel');
set(HY, 'string', 'Phase Noise (dBc/Hz)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
%Htitle = get(AX, 'title');
%set(Htitle, 'string', 'Channel Frequency Responses','FontName','utopia', 'FontSize', [20], 'Color', [0 0 0]);
%L=legend({'NTF_{IN}','CDR','Effective Jitter Filter'},'Location','southeast');
%set(L, 'FontSize', [10]);
%M=text(20, -7, '26GHz Loss')
%set(M, 'HorizontalAlignment','center','FontSize', [10])



fstart=1e4;
fstop=10e6;
[~,fstart_i]=min(abs(w_pll-2*pi*fstart))
[~,fstop_i]=min(abs(w_pll-2*pi*fstop))
w_pll(fstart_i)/(2*pi)
w_pll(fstop_i)/(2*pi)
rms_jitter_new=sqrt(2/(2*pi*fref)^2*trapz(w_pll(fstart_i:fstop_i)/(2*pi),10.^(ref_clk_pn_dBc_new(fstart_i:fstop_i)/10)))

% Filter input reference noise
ref_clk_pn_pll=ref_clk_pn_dBc_new+20*log10(cl_mag_plot1);

figure;
semilogx(w_pll/(2*pi),ref_clk_pn_dBc_new,'-b'); hold on;
semilogx(w_pll/(2*pi),ref_clk_pn_pll,'-r');
xlim([10 7e9]);
ylim([-200 -40]);
grid on;

rms_jitter_ref_clk_out=sqrt(2/(2*pi*fref*N)^2*trapz(w_pll(fstart_i:fstop_i)/(2*pi),10.^(ref_clk_pn_pll(fstart_i:fstop_i)/10)))
fstart=1e4;
fstop=10e6;
[~,fstart_i]=min(abs(w_pll-2*pi*fstart))
[~,fstop_i]=min(abs(w_pll-2*pi*fstop))
rms_jitter_ref_clk_out_full=sqrt(2/(2*pi*fref*N)^2*trapz(w_pll(fstart_i:fstop_i)/(2*pi),10.^(ref_clk_pn_pll(fstart_i:fstop_i)/10)))

%% First-Order CDR Model
wpcdr = 2*pi*4e6;
cdr_num = [1 0];
cdr_den = [1 wpcdr];
cdr_xfer_function=tf(cdr_num,cdr_den);
[cdr_mag,cdr_phase,w1]=bode(cdr_xfer_function,w_pll);
cdr_mag_plot(1,:)=cdr_mag(1,1,:);

% Pass Ref Noise through both PLL and CDR
ref_clk_pn_pll_cdr=ref_clk_pn_pll+20*log10(cdr_mag_plot);
ref_clk_jfilter=20*log10(cl_mag_plot1)+20*log10(cdr_mag_plot);

figure;
semilogx(w_pll/(2*pi),ref_clk_pn_dBc_new,'-b'); hold on;
semilogx(w_pll/(2*pi),ref_clk_pn_pll,'-r');
semilogx(w_pll/(2*pi),ref_clk_pn_pll_cdr,'-g');
xlim([10 7e9]);
%ylim([-200 -40]);
grid on;

figure;
semilogx(w_pll/(2*pi),20*log10(cl_mag_plot1),'-b'); hold on;
semilogx(w_pll/(2*pi),20*log10(cdr_mag_plot),'-r');
semilogx(w_pll/(2*pi),ref_clk_jfilter,'-g');
xlim([10 7e9]);
%ylim([-200 -40]);
grid on;

figure;
A=semilogx(w_pll/(2*pi),20*log10(cl_mag_plot1),'-b'); hold on;
B=semilogx(w_pll/(2*pi),20*log10(cdr_mag_plot),'-r');
C=semilogx(w_pll/(2*pi),ref_clk_jfilter,'-g');
grid on;
set(A, 'LineWidth', [2.0]);
set(B, 'LineWidth', [2.0]);
set(C, 'LineWidth', [2.0]);
%set(H, 'Color', [0 0 0]);
AX=gca;
set(AX, 'FontName', 'utopia');
set(AX, 'FontSize', [10]);
%set(AX, 'LineWidth', [2.0]);
set(AX, 'XLim', [10 7e9]);
%set(AX, 'XTick', [0.5 1 5 10]);
%set(AX, 'YLim', [-200 -40]); 
%set(AX, 'YTick', -100:20:60);
set(AX, 'YColor', [0 0 0]);
HX = get(AX, 'xlabel');
set(HX, 'string', 'Frequency (Hz)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
HY = get(AX, 'ylabel');
set(HY, 'string', 'Response (dB)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
%Htitle = get(AX, 'title');
%set(Htitle, 'string', 'Channel Frequency Responses','FontName','utopia', 'FontSize', [20], 'Color', [0 0 0]);
L=legend({'NTF_{IN}','CDR','Effective Jitter Filter'},'Location','southeast');
set(L, 'FontSize', [10]);
%M=text(20, -7, '26GHz Loss')
%set(M, 'HorizontalAlignment','center','FontSize', [10])

figure;
A=semilogx(w_pll/(2*pi),20*log10(cl_mag_plot1),'-b'); hold on;
grid on;
set(A, 'LineWidth', [2.0]);
%set(H, 'Color', [0 0 0]);
AX=gca;
set(AX, 'FontName', 'utopia');
set(AX, 'FontSize', [10]);
%set(AX, 'LineWidth', [2.0]);
set(AX, 'XLim', [10 7e9]);
%set(AX, 'XTick', [0.5 1 5 10]);
%set(AX, 'YLim', [-200 -40]); 
%set(AX, 'YTick', -100:20:60);
set(AX, 'YColor', [0 0 0]);
HX = get(AX, 'xlabel');
set(HX, 'string', 'Frequency (Hz)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
HY = get(AX, 'ylabel');
set(HY, 'string', '|NTF_{IN}| (dB)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
%Htitle = get(AX, 'title');
%set(Htitle, 'string', 'Channel Frequency Responses','FontName','utopia', 'FontSize', [20], 'Color', [0 0 0]);
%L=legend({'NTF_{IN}','CDR','Effective Jitter Filter'},'Location','southeast');
%set(L, 'FontSize', [10]);
%M=text(20, -7, '26GHz Loss')
%set(M, 'HorizontalAlignment','center','FontSize', [10])


fstart=1e2;
fstop=7e9;
[~,fstart_i]=min(abs(w_pll-2*pi*fstart))
[~,fstop_i]=min(abs(w_pll-2*pi*fstop))
rms_jitter_ref_clk_out_full_cdr=sqrt(2/(2*pi*fref*N)^2*trapz(w_pll(fstart_i:fstop_i)/(2*pi),10.^(ref_clk_pn_pll_cdr(fstart_i:fstop_i)/10)))

figure;
A=semilogx(w_pll/(2*pi),ref_clk_pn_dBc_new,'-b'); hold on;
B=semilogx(w_pll/(2*pi),ref_clk_pn_pll,'-r');
C=semilogx(w_pll/(2*pi),ref_clk_pn_pll_cdr,'-g');
grid on;
set(A, 'LineWidth', [2.0]);
set(B, 'LineWidth', [2.0]);
set(C, 'LineWidth', [2.0]);
%set(H, 'Color', [0 0 0]);
AX=gca;
set(AX, 'FontName', 'utopia');
set(AX, 'FontSize', [10]);
%set(AX, 'LineWidth', [2.0]);
set(AX, 'XLim', [10 7e9]);
%set(AX, 'XTick', [0.5 1 5 10]);
set(AX, 'YLim', [-200 -40]); 
%set(AX, 'YTick', -100:20:60);
set(AX, 'YColor', [0 0 0]);
HX = get(AX, 'xlabel');
set(HX, 'string', 'Frequency (Hz)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
HY = get(AX, 'ylabel');
set(HY, 'string', 'Phase Noise (dBc/Hz)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
%Htitle = get(AX, 'title');
%set(Htitle, 'string', 'Channel Frequency Responses','FontName','utopia', 'FontSize', [20], 'Color', [0 0 0]);
L=legend({'Input Ref Clk PN','After PLL','After 4MHz CDR'},'Location','northeast');
set(L, 'FontSize', [10]);
%M=text(20, -7, '26GHz Loss')
%set(M, 'HorizontalAlignment','center','FontSize', [10])


%% Model Charge Pump Noise
k=1.38e-23;
T=300;
%gamma_n=1.02;
%gm_n=11.1*Icp;
%gamma_p=0.89;
%gm_p=11.9*Icp;
gamma_n=1.02;
gm_n=7.01*Icp;
gamma_p=0.89;
gm_p=8.88*Icp;
trst=40e-12;
tref=1/fref;
flicker_corner=1e7; % in Hz
flicker_corner_n=8.91e7; % in Hz
flicker_corner_p=1.35e8; % in Hz
nmos_thermal(1:size(w_pll,2))=4*k*T*gamma_n*gm_n;
nmos_1f=nmos_thermal*flicker_corner_n*2*pi./w_pll;
nmos_sin=nmos_thermal+nmos_1f;
pmos_thermal(1:size(w_pll,2))=4*k*T*gamma_p*gm_p;
pmos_1f=pmos_thermal*flicker_corner_p*2*pi./w_pll;
pmos_sin=pmos_thermal+pmos_1f;
cp_mod_sin=(trst/tref)*(nmos_thermal+pmos_thermal) + ((trst/tref)^2)*(nmos_1f+pmos_1f);


figure; 
loglog(w_pll/(2*pi),nmos_thermal,'-b'); hold on;
plot(w_pll/(2*pi),nmos_1f,'-r');
plot(w_pll/(2*pi),nmos_sin,'-g'); grid on;

figure; 
loglog(w_pll/(2*pi),pmos_thermal,'-b'); hold on;
plot(w_pll/(2*pi),pmos_1f,'-r');
plot(w_pll/(2*pi),pmos_sin,'-g'); grid on;
plot(w_pll/(2*pi),cp_mod_sin,'-k'); 

% Filter charge pump noise w/ PLL and CDR
cp_sin_pll=10*log10(cp_mod_sin)+20*log10(cp_mag_plot);
cp_sin_pll_cdr=cp_sin_pll+20*log10(cdr_mag_plot);

fstart=1e4;
fstop=10e6;
[~,fstart_i]=min(abs(w_pll-2*pi*fstart))
[~,fstop_i]=min(abs(w_pll-2*pi*fstop))
rms_jitter_cp_out=sqrt(2/(2*pi*fref*N)^2*trapz(w_pll(fstart_i:fstop_i)/(2*pi),10.^(cp_sin_pll(fstart_i:fstop_i)/10)))

fstart=1e2;
fstop=7e9;
[~,fstart_i]=min(abs(w_pll-2*pi*fstart))
[~,fstop_i]=min(abs(w_pll-2*pi*fstop))
rms_jitter_cp_out_cdr=sqrt(2/(2*pi*fref*N)^2*trapz(w_pll(fstart_i:fstop_i)/(2*pi),10.^(cp_sin_pll_cdr(fstart_i:fstop_i)/10)))

figure;
semilogx(w_pll/(2*pi),10*log10(cp_mod_sin),'-b'); hold on;
semilogx(w_pll/(2*pi),cp_sin_pll,'-r');
semilogx(w_pll/(2*pi),cp_sin_pll_cdr,'-g'); grid on;

figure;
A=semilogx(w_pll/(2*pi),10*log10(cp_mod_sin),'-b'); hold on;
B=semilogx(w_pll/(2*pi),cp_sin_pll,'-r');
C=semilogx(w_pll/(2*pi),cp_sin_pll_cdr,'-g'); grid on;
set(A, 'LineWidth', [2.0]);
set(B, 'LineWidth', [2.0]);
set(C, 'LineWidth', [2.0]);
%set(H, 'Color', [0 0 0]);
AX=gca;
set(AX, 'FontName', 'utopia');
set(AX, 'FontSize', [10]);
%set(AX, 'LineWidth', [2.0]);
set(AX, 'XLim', [10 7e9]);
%set(AX, 'XTick', [0.5 1 5 10]);
set(AX, 'YLim', [-250 -60]); 
%set(AX, 'YTick', -100:20:60);
set(AX, 'YColor', [0 0 0]);
HX = get(AX, 'xlabel');
set(HX, 'string', 'Frequency (Hz)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
HY = get(AX, 'ylabel');
set(HY, 'string', 'Noise/Phase Noise (dB/Hz, dBc/Hz)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
%Htitle = get(AX, 'title');
%set(Htitle, 'string', 'Channel Frequency Responses','FontName','utopia', 'FontSize', [20], 'Color', [0 0 0]);
L=legend({'Charge Pump Noise','After PLL','After 4MHz CDR'},'Location','northeast');
set(L, 'FontSize', [10]);
%M=text(20, -7, '26GHz Loss')
%set(M, 'HorizontalAlignment','center','FontSize', [10])

figure;
A=semilogx(w_pll/(2*pi),10*log10(cp_mod_sin),'-b'); hold on; grid on;
set(A, 'LineWidth', [2.0]);
%set(H, 'Color', [0 0 0]);
AX=gca;
set(AX, 'FontName', 'utopia');
set(AX, 'FontSize', [10]);
%set(AX, 'LineWidth', [2.0]);
set(AX, 'XLim', [10 7e9]);
%set(AX, 'XTick', [0.5 1 5 10]);
%set(AX, 'YLim', [-250 -40]); 
%set(AX, 'YTick', -100:20:60);
set(AX, 'YColor', [0 0 0]);
HX = get(AX, 'xlabel');
set(HX, 'string', 'Frequency (Hz)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
HY = get(AX, 'ylabel');
set(HY, 'string', 'S_{iCP} (dB/Hz)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
%Htitle = get(AX, 'title');
%set(Htitle, 'string', 'Channel Frequency Responses','FontName','utopia', 'FontSize', [20], 'Color', [0 0 0]);
%L=legend({'Charge Pump Noise','After PLL','After 4MHz CDR'},'Location','northeast');
%set(L, 'FontSize', [10]);
%M=text(20, -7, '26GHz Loss')
%set(M, 'HorizontalAlignment','center','FontSize', [10])

figure;
A=semilogx(w_pll/(2*pi),10*log10(nmos_thermal),'-r'); hold on; grid on;
B=semilogx(w_pll/(2*pi),10*log10(nmos_1f),'-g');
C=semilogx(w_pll/(2*pi),10*log10(nmos_sin),'-m');
D=semilogx(w_pll/(2*pi),10*log10(cp_mod_sin),'-b'); 
set(A, 'LineWidth', [2.0]);
set(B, 'LineWidth', [2.0]);
set(C, 'LineWidth', [2.0]);
set(D, 'LineWidth', [2.0]);
%set(H, 'Color', [0 0 0]);
AX=gca;
set(AX, 'FontName', 'utopia');
set(AX, 'FontSize', [10]);
%set(AX, 'LineWidth', [2.0]);
set(AX, 'XLim', [10 7e9]);
%set(AX, 'XTick', [0.5 1 5 10]);
%set(AX, 'YLim', [-250 -40]); 
%set(AX, 'YTick', -100:20:60);
set(AX, 'YColor', [0 0 0]);
HX = get(AX, 'xlabel');
set(HX, 'string', 'Frequency (Hz)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
HY = get(AX, 'ylabel');
set(HY, 'string', 'Noise (dB/Hz)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
%Htitle = get(AX, 'title');
%set(Htitle, 'string', 'Channel Frequency Responses','FontName','utopia', 'FontSize', [20], 'Color', [0 0 0]);
L=legend({'NMOS White','NMOS 1/f','NMOS Total', 'Charge Pump Nose'},'Location','northeast');
set(L, 'FontSize', [10]);
%M=text(20, -7, '26GHz Loss')
%set(M, 'HorizontalAlignment','center','FontSize', [10])

figure;
A=semilogx(w_pll/(2*pi),20*log10(cp_mag_plot),'-b'); hold on;
grid on;
set(A, 'LineWidth', [2.0]);
%set(H, 'Color', [0 0 0]);
AX=gca;
set(AX, 'FontName', 'utopia');
set(AX, 'FontSize', [10]);
%set(AX, 'LineWidth', [2.0]);
set(AX, 'XLim', [10 7e9]);
%set(AX, 'XTick', [0.5 1 5 10]);
%set(AX, 'YLim', [-200 -40]); 
%set(AX, 'YTick', -100:20:60);
set(AX, 'YColor', [0 0 0]);
HX = get(AX, 'xlabel');
set(HX, 'string', 'Frequency (Hz)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
HY = get(AX, 'ylabel');
set(HY, 'string', '|NTF_{CP}| (dB)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
%Htitle = get(AX, 'title');
%set(Htitle, 'string', 'Channel Frequency Responses','FontName','utopia', 'FontSize', [20], 'Color', [0 0 0]);
%L=legend({'NTF_{IN}','CDR','Effective Jitter Filter'},'Location','southeast');
%set(L, 'FontSize', [10]);
%M=text(20, -7, '26GHz Loss')
%set(M, 'HorizontalAlignment','center','FontSize', [10])


%% Model Loop Filter Resistor Noise
r1_svn(1:size(w_pll,2))=4*k*T*r1;

% Filter resistor noise w/ PLL and CDR
r1_svn_pll=10*log10(r1_svn)+20*log10(vco_in_mag_plot1);
r1_svn_pll_cdr=r1_svn_pll+20*log10(cdr_mag_plot);

fstart=1e4;
fstop=1e7;
[~,fstart_i]=min(abs(w_pll-2*pi*fstart))
[~,fstop_i]=min(abs(w_pll-2*pi*fstop))
rms_jitter_r1_out=sqrt(2/(2*pi*fref*N)^2*trapz(w_pll(fstart_i:fstop_i)/(2*pi),10.^(r1_svn_pll(fstart_i:fstop_i)/10)))

fstart=1e2;
fstop=7e9;
[~,fstart_i]=min(abs(w_pll-2*pi*fstart))
[~,fstop_i]=min(abs(w_pll-2*pi*fstop))
rms_jitter_r1_out_cdr=sqrt(2/(2*pi*fref*N)^2*trapz(w_pll(fstart_i:fstop_i)/(2*pi),10.^(r1_svn_pll_cdr(fstart_i:fstop_i)/10)))

figure;
semilogx(w_pll/(2*pi),10*log10(r1_svn),'-b'); hold on;
semilogx(w_pll/(2*pi),r1_svn_pll,'-r');
semilogx(w_pll/(2*pi),r1_svn_pll_cdr,'-g'); grid on;

figure;
A=semilogx(w_pll/(2*pi),10*log10(r1_svn),'-b'); hold on;
B=semilogx(w_pll/(2*pi),r1_svn_pll,'-r');
C=semilogx(w_pll/(2*pi),r1_svn_pll_cdr,'-g'); grid on;
set(A, 'LineWidth', [2.0]);
set(B, 'LineWidth', [2.0]);
set(C, 'LineWidth', [2.0]);
%set(H, 'Color', [0 0 0]);
AX=gca;
set(AX, 'FontName', 'utopia');
set(AX, 'FontSize', [10]);
%set(AX, 'LineWidth', [2.0]);
set(AX, 'XLim', [10 7e9]);
%set(AX, 'XTick', [0.5 1 5 10]);
set(AX, 'YLim', [-200 -100]); 
%set(AX, 'YTick', -100:20:60);
set(AX, 'YColor', [0 0 0]);
HX = get(AX, 'xlabel');
set(HX, 'string', 'Frequency (Hz)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
HY = get(AX, 'ylabel');
set(HY, 'string', 'Noise/Phase Noise (dB/Hz, dBc/Hz)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
%Htitle = get(AX, 'title');
%set(Htitle, 'string', 'Channel Frequency Responses','FontName','utopia', 'FontSize', [20], 'Color', [0 0 0]);
L=legend({'Loop Filter R Noise','After PLL','After 4MHz CDR'},'Location','northwest');
set(L, 'FontSize', [10]);
%M=text(20, -7, '26GHz Loss')
%set(M, 'HorizontalAlignment','center','FontSize', [10])

figure;
A=semilogx(w_pll/(2*pi),20*log10(vco_in_mag_plot1),'-b'); grid on; hold on;
set(A, 'LineWidth', [2.0]);
%set(H, 'Color', [0 0 0]);
AX=gca;
set(AX, 'FontName', 'utopia');
set(AX, 'FontSize', [10]);
%set(AX, 'LineWidth', [2.0]);
set(AX, 'XLim', [10 7e9]);
%set(AX, 'XTick', [0.5 1 5 10]);
%set(AX, 'YLim', [-200 -100]); 
%set(AX, 'YTick', -100:20:60);
set(AX, 'YColor', [0 0 0]);
HX = get(AX, 'xlabel');
set(HX, 'string', 'Frequency (Hz)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
HY = get(AX, 'ylabel');
set(HY, 'string', '|NTF_{R}| (dB)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
%Htitle = get(AX, 'title');
%set(Htitle, 'string', 'Channel Frequency Responses','FontName','utopia', 'FontSize', [20], 'Color', [0 0 0]);
%L=legend({'Loop Filter R Noise','After PLL','After 4MHz CDR'},'Location','northwest');
%set(L, 'FontSize', [10]);
%M=text(20, -7, '26GHz Loss')
%set(M, 'HorizontalAlignment','center','FontSize', [10])

figure;
A=semilogx(w_pll/(2*pi),10*log10(r1_svn),'-b'); hold on; grid on;
set(A, 'LineWidth', [2.0]);
%set(H, 'Color', [0 0 0]);
AX=gca;
set(AX, 'FontName', 'utopia');
set(AX, 'FontSize', [10]);
%set(AX, 'LineWidth', [2.0]);
set(AX, 'XLim', [10 7e9]);
%set(AX, 'XTick', [0.5 1 5 10]);
set(AX, 'YLim', [-170 -150]); 
%set(AX, 'YTick', -100:20:60);
set(AX, 'YColor', [0 0 0]);
HX = get(AX, 'xlabel');
set(HX, 'string', 'Frequency (Hz)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
HY = get(AX, 'ylabel');
set(HY, 'string', 'S_{vR} (dB/Hz)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
%Htitle = get(AX, 'title');
%set(Htitle, 'string', 'Channel Frequency Responses','FontName','utopia', 'FontSize', [20], 'Color', [0 0 0]);
%L=legend({'Loop Filter R Noise','After PLL','After 4MHz CDR'},'Location','northwest');
%set(L, 'FontSize', [10]);
%M=text(20, -7, '26GHz Loss')
%set(M, 'HorizontalAlignment','center','FontSize', [10])



%% Model VCO Phase Noise
load 'lc_vco_pn.txt';
lc_vco_freqs=lc_vco_pn(:,1);
vco_scale=3; % Add additional VCO noise to easily scale to match different VCO designs
lc_vco_pn_dBc=lc_vco_pn(:,2)+vco_scale;

figure;
semilogx(lc_vco_freqs,lc_vco_pn_dBc);
grid on;
%xlim([10 4e7]);

% Resample VCO phase noise to align it with the pll frequency grid
lc_vco_pn_dBc_new=interp1(lc_vco_freqs*2*pi,lc_vco_pn_dBc,w_pll,'linear','extrap');

figure;
semilogx(lc_vco_freqs,lc_vco_pn_dBc,'-b'); hold on;
semilogx(w_pll/(2*pi),lc_vco_pn_dBc_new,'-r');

% Filter VCO noise w/ PLL and CDR
lc_vco_pll=lc_vco_pn_dBc_new+20*log10(vco_on_mag_plot1);
lc_vco_pll_cdr=lc_vco_pll+20*log10(cdr_mag_plot);

fstart=1e4;
fstop=10e6;
[~,fstart_i]=min(abs(w_pll-2*pi*fstart))
[~,fstop_i]=min(abs(w_pll-2*pi*fstop))
rms_jitter_vco_out=sqrt(2/(2*pi*fref*N)^2*trapz(w_pll(fstart_i:fstop_i)/(2*pi),10.^(lc_vco_pll(fstart_i:fstop_i)/10)))

fstart=1e2;
fstop=7e9;
[~,fstart_i]=min(abs(w_pll-2*pi*fstart))
[~,fstop_i]=min(abs(w_pll-2*pi*fstop))
rms_jitter_vco_out_cdr=sqrt(2/(2*pi*fref*N)^2*trapz(w_pll(fstart_i:fstop_i)/(2*pi),10.^(lc_vco_pll_cdr(fstart_i:fstop_i)/10)))

figure;
semilogx(w_pll/(2*pi),lc_vco_pn_dBc_new,'-b'); hold on;
semilogx(w_pll/(2*pi),lc_vco_pll,'-r');
semilogx(w_pll/(2*pi),lc_vco_pll_cdr,'-g'); grid on;

figure;
A=semilogx(w_pll/(2*pi),lc_vco_pn_dBc_new,'-b'); hold on;
B=semilogx(w_pll/(2*pi),lc_vco_pll,'-r');
C=semilogx(w_pll/(2*pi),lc_vco_pll_cdr,'-g'); grid on;
set(A, 'LineWidth', [2.0]);
set(B, 'LineWidth', [2.0]);
set(C, 'LineWidth', [2.0]);
%set(H, 'Color', [0 0 0]);
AX=gca;
set(AX, 'FontName', 'utopia');
set(AX, 'FontSize', [10]);
%set(AX, 'LineWidth', [2.0]);
set(AX, 'XLim', [1e4 7e9]);
%set(AX, 'XTick', [0.5 1 5 10]);
set(AX, 'YLim', [-170 -40]); 
%set(AX, 'YTick', -100:20:60);
set(AX, 'YColor', [0 0 0]);
HX = get(AX, 'xlabel');
set(HX, 'string', 'Frequency (Hz)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
HY = get(AX, 'ylabel');
set(HY, 'string', 'Phase Noise (dBc/Hz)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
%Htitle = get(AX, 'title');
%set(Htitle, 'string', 'Channel Frequency Responses','FontName','utopia', 'FontSize', [20], 'Color', [0 0 0]);
L=legend({'VCO Phase Noise','After PLL','After 4MHz CDR'},'Location','northeast');
set(L, 'FontSize', [10]);
%M=text(20, -7, '26GHz Loss')
%set(M, 'HorizontalAlignment','center','FontSize', [10])


figure;
A=semilogx(w_pll/(2*pi),lc_vco_pn_dBc_new,'-b'); hold on; grid on;
set(A, 'LineWidth', [2.0]);
%set(H, 'Color', [0 0 0]);
AX=gca;
set(AX, 'FontName', 'utopia');
set(AX, 'FontSize', [10]);
%set(AX, 'LineWidth', [2.0]);
set(AX, 'XLim', [1e4 7e9]);
%set(AX, 'XTick', [0.5 1 5 10]);
%set(AX, 'YLim', [-170 -40]); 
%set(AX, 'YTick', -100:20:60);
set(AX, 'YColor', [0 0 0]);
HX = get(AX, 'xlabel');
set(HX, 'string', 'Frequency (Hz)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
HY = get(AX, 'ylabel');
set(HY, 'string', 'Phase Noise (dBc/Hz)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
%Htitle = get(AX, 'title');
%set(Htitle, 'string', 'Channel Frequency Responses','FontName','utopia', 'FontSize', [20], 'Color', [0 0 0]);
%L=legend({'VCO Phase Noise','After PLL','After 4MHz CDR'},'Location','northeast');
%set(L, 'FontSize', [10]);
%M=text(20, -7, '26GHz Loss')
%set(M, 'HorizontalAlignment','center','FontSize', [10])

figure;
A=semilogx(w_pll/(2*pi),20*log10(vco_on_mag_plot1),'-b'); hold on; grid on;
set(A, 'LineWidth', [2.0]);
%set(H, 'Color', [0 0 0]);
AX=gca;
set(AX, 'FontName', 'utopia');
set(AX, 'FontSize', [10]);
%set(AX, 'LineWidth', [2.0]);
set(AX, 'XLim', [1e4 7e9]);
%set(AX, 'XTick', [0.5 1 5 10]);
%set(AX, 'YLim', [-170 -40]); 
%set(AX, 'YTick', -100:20:60);
set(AX, 'YColor', [0 0 0]);
HX = get(AX, 'xlabel');
set(HX, 'string', 'Frequency (Hz)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
HY = get(AX, 'ylabel');
set(HY, 'string', '|NTF_{VCO}| (dB)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
%Htitle = get(AX, 'title');
%set(Htitle, 'string', 'Channel Frequency Responses','FontName','utopia', 'FontSize', [20], 'Color', [0 0 0]);
%L=legend({'VCO Phase Noise','After PLL','After 4MHz CDR'},'Location','northeast');
%set(L, 'FontSize', [10]);
%M=text(20, -7, '26GHz Loss')
%set(M, 'HorizontalAlignment','center','FontSize', [10])


% Add Individual Phase Noise Contributions
total_pn_pll=10*log10(10.^(ref_clk_pn_pll/10)+10.^(cp_sin_pll/10)+10.^(r1_svn_pll/10)+10.^(lc_vco_pll/10));
total_pn_pll_cdr=total_pn_pll+20*log10(cdr_mag_plot);

figure;
semilogx(w_pll/(2*pi),ref_clk_pn_pll,'-b'); hold on;
semilogx(w_pll/(2*pi),cp_sin_pll,'-r');
semilogx(w_pll/(2*pi),r1_svn_pll,'-g');
semilogx(w_pll/(2*pi),lc_vco_pll,'-m');
semilogx(w_pll/(2*pi),total_pn_pll,'-k'); grid on;

fstart=1e4;
fstop=10e6;
[~,fstart_i]=min(abs(w_pll-2*pi*fstart))
[~,fstop_i]=min(abs(w_pll-2*pi*fstop))
rms_jitter_total_out=sqrt(2/(2*pi*fref*N)^2*trapz(w_pll(fstart_i:fstop_i)/(2*pi),10.^(total_pn_pll(fstart_i:fstop_i)/10)))

fstart=1e2;
fstop=7e9;
[~,fstart_i]=min(abs(w_pll-2*pi*fstart))
[~,fstop_i]=min(abs(w_pll-2*pi*fstop))
rms_jitter_total_out_cdr=sqrt(2/(2*pi*fref*N)^2*trapz(w_pll(fstart_i:fstop_i)/(2*pi),10.^(total_pn_pll_cdr(fstart_i:fstop_i)/10)))


figure;
A=semilogx(w_pll/(2*pi),total_pn_pll,'-b'); hold on;
B=semilogx(w_pll/(2*pi),ref_clk_pn_pll,'-r');
C=semilogx(w_pll/(2*pi),cp_sin_pll,'-g'); grid on;
D=semilogx(w_pll/(2*pi),r1_svn_pll,'-m');
E=semilogx(w_pll/(2*pi),lc_vco_pll,'-k');
set(A, 'LineWidth', [2.0]);
set(B, 'LineWidth', [2.0]);
set(C, 'LineWidth', [2.0]);
set(D, 'LineWidth', [2.0]);
set(E, 'LineWidth', [2.0]);
%set(H, 'Color', [0 0 0]);
AX=gca;
set(AX, 'FontName', 'utopia');
set(AX, 'FontSize', [10]);
%set(AX, 'LineWidth', [2.0]);
set(AX, 'XLim', [10 7e9]);
%set(AX, 'XTick', [0.5 1 5 10]);
set(AX, 'YLim', [-170 -40]); 
%set(AX, 'YTick', -100:20:60);
set(AX, 'YColor', [0 0 0]);
HX = get(AX, 'xlabel');
set(HX, 'string', 'Frequency (Hz)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
HY = get(AX, 'ylabel');
set(HY, 'string', 'Phase Noise (dBc/Hz)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
%Htitle = get(AX, 'title');
%set(Htitle, 'string', 'Channel Frequency Responses','FontName','utopia', 'FontSize', [20], 'Color', [0 0 0]);
L=legend({'Total','Ref Clk','Charge Pump','Loop Filter R','VCO'},'Location','northeast');
set(L, 'FontSize', [10]);
%M=text(20, -7, '26GHz Loss')
%set(M, 'HorizontalAlignment','center','FontSize', [10])

figure;
A=semilogx(w_pll/(2*pi),total_pn_pll,'-b'); hold on;
B=semilogx(w_pll/(2*pi),total_pn_pll_cdr,'-r'); grid on;
set(A, 'LineWidth', [2.0]);
set(B, 'LineWidth', [2.0]);
%set(H, 'Color', [0 0 0]);
AX=gca;
set(AX, 'FontName', 'utopia');
set(AX, 'FontSize', [10]);
%set(AX, 'LineWidth', [2.0]);
set(AX, 'XLim', [10 7e9]);
%set(AX, 'XTick', [0.5 1 5 10]);
%set(AX, 'YLim', [-170 -40]); 
%set(AX, 'YTick', -100:20:60);
set(AX, 'YColor', [0 0 0]);
HX = get(AX, 'xlabel');
set(HX, 'string', 'Frequency (Hz)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
HY = get(AX, 'ylabel');
set(HY, 'string', 'Phase Noise (dBc/Hz)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
%Htitle = get(AX, 'title');
%set(Htitle, 'string', 'Channel Frequency Responses','FontName','utopia', 'FontSize', [20], 'Color', [0 0 0]);
L=legend({'Total PLL Output','After 4MHz CDR'},'Location','northeast');
set(L, 'FontSize', [10]);
%M=text(20, -7, '26GHz Loss')
%set(M, 'HorizontalAlignment','center','FontSize', [10])

rms_jitter_ref_clk_out_full
rms_jitter_ref_clk_out_full_cdr
rms_jitter_cp_out
rms_jitter_cp_out_cdr
rms_jitter_r1_out
rms_jitter_r1_out_cdr
rms_jitter_vco_out
rms_jitter_vco_out_cdr
rms_jitter_total_out
rms_jitter_total_out_cdr


%% Model Different Loop Points Transient Response
vctrl_num=(KPD/c2)*[1 1/(r1*c) 0];
vctrl_xfer_function=tf(vctrl_num,cl_den1);
lbw=4e6; % loop bandwidth estimate
t=linspace(0,50/(2*pi*lbw),1000);
%delta_w=2*pi*(fref*10)/N;
delta_w=2*pi*(500e6)/N;
pin=delta_w*t;
vctrl_fstep=lsim(vctrl_xfer_function,pin,t);

figure;
plot(t,vctrl_fstep);

figure;
A=plot(t*1e6,vctrl_fstep); grid on;
set(A, 'LineWidth', [2.0]);
%set(H, 'Color', [0 0 0]);
AX=gca;
set(AX, 'FontName', 'utopia');
set(AX, 'FontSize', [10]);
%set(AX, 'LineWidth', [2.0]);
%set(AX, 'XLim', [10 7e9]);
%set(AX, 'XTick', [0.5 1 5 10]);
%set(AX, 'YLim', [-170 -40]); 
%set(AX, 'YTick', -100:20:60);
set(AX, 'YColor', [0 0 0]);
HX = get(AX, 'xlabel');
set(HX, 'string', 'Time (us)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
HY = get(AX, 'ylabel');
set(HY, 'string', 'Voltage (V)','FontName','utopia', 'FontSize', [16], 'Color', [0 0 0]);
%Htitle = get(AX, 'title');
%set(Htitle, 'string', 'Channel Frequency Responses','FontName','utopia', 'FontSize', [20], 'Color', [0 0 0]);
%L=legend({'Total','Ref Clk','Charge Pump','Loop Filter R','VCO'},'Location','northeast');
%set(L, 'FontSize', [10]);
%M=text(20, -7, '26GHz Loss')
%set(M, 'HorizontalAlignment','center','FontSize', [10])

save(['fstep_500MHz_1GHz.mat'],'t','vctrl_fstep')







