混合信号仿真 Matlab处理 PLL VCO

混合信号仿真 Matlab处理 PLL+VCO

% Plot simulation results with log x axis. 
% Plot only + freq terms.
% Per common practice, do not show carrier term.
% Plot 1/f for reference, plus measured, plus specification 
% From  MathWorks.
index_start = 3;              % move out from carrier at DC and fft window effects
Frame_Length = length(Normalized_Spectrum);
Fvec_meas = Spectrum_dF*((index_start-1):Frame_Length/2);

h2  =  findobj('Tag','plot_VCO');
if isempty(h2) 
   h2 =  figure('Tag','plot_VCO')
else
   figure(h2)
end

semilogx(Fvec_meas,10*log10(Normalized_Spectrum(index_start:(Frame_Length/2+1))),....
         Fvec,Lvec,'o');
xlabel('Hz from Carrier'); ylabel('dBc/Hz'); grid on;
legend('Measured', 'specification');
axis([Fvec(1),Fvec_meas(end),-130,-30])
function noise_filt=VCO_noise_profile_3(Npts,Level_dB,Freq,OverSample,Interp_Select,Verify); 
% Npts = length of filter kernel. More provides increased freq resolution
% Freq     = Vector of frequencies in Hz
% Level_dB = Corresponding Vector of noise levels
% OverSample = Sets Fs , must be > 2*max freq spec
% Verify   = true to show plots
% Create a filter kernel (FIR coefficients) that approximates a user spec'd
% power spectrum Level is dB/Hz
% To get dBc, carrier must be 1 Watt.
% Dick Benson  December 2009
%  MathWorks 

L     = round(Npts/2);         
f     =(0:(L-1))/L;     % frequency vector normalized to Fs/2
ph    = reshape([0;pi]*ones(1,L/2),L,1)'; % phase curve

Fs = OverSample*Freq(end); 

switch Interp_Select
   case 1
     % linear X axis 
     Level    = [Level_dB(1),Level_dB,Level_dB(end)];    % pad start and end
     Freq     = [0,          Freq,    Fs/2 ];            % ditto
     % linearly interpolate in the dB realm.
     shape_dB = interp1(Freq,Level,f*Fs/2,'linear');
     shape    =   10.^(shape_dB/20); 
   case 2
     % log x axis 
     Level    = [Level_dB,Level_dB(end)];    % pad  end
     Freq     = [Freq, Fs/2 ];        % ditto
     % linearly interpolate in the dB realm.
     log_Freq= log10(Freq);
     
     shape_dB = interp1(log_Freq,Level,log10(f*Fs/2),'linear');
     % remove any NaNs and pad
     bogus_nans = isnan(shape_dB);
     if sum(bogus_nans)==0
        shape    =   10.^(shape_dB/20); 
     else 
        N=sum(bogus_nans); 
        shape    =   10.^([shape_dB(N+1:2*N),shape_dB((N+1):end)]/20); 
     end;
   end
 
  
  dFspec = min(diff(Freq(2:end)));
  dF     = Fs/Npts;
  if dFspec<dF
     warndlg(['The frequency resolution of the Spec is greater than can be achieved. \n Consider Increasing the number of Points in the FIR Kernel, or removing the low Frequency Specs.',sprintf('F=%10.2f  ',Freq(2:3)), 'etc.'],[ 'Freq REsolution']); 
  end;

shape_2 = shape.*f*Fs/2; % multiply by Frequency to create derivative 
% Need to create a complex spectral description 
% which, when transformed with the ifft, creates a REAL impulse response.
mag=[shape_2,0, fliplr(shape_2(2:end))]; % construct magnitude
phase=[-ph,0,fliplr(ph(2:end))];     % and phase 
H=mag.*exp(1i*phase); % complex representation
h=ifft(H);            % Filter Kernel 

%  sanity checks ....
if Verify
   hf    =  findobj('Tag','plot_VCO');
   if isempty(hf) 
      hf =  figure('Tag','plot_VCO');
   else
      figure(hf);
   end

   subplot(2,1,1)
   plot((h)); title('Filter Impulse Response (no window)');
   xlabel('samples')
end;

% If the filter is used as is, there may be ripples in the frequency
% reponse due to the abrupt transistions at the impulse response endpoints.
% To mitigate this, apply a Hanning window and compare computed response with
% the spec and interpoloted spec. 

hout=h.*hann(2*L)';

if Verify
   H2=fft(hout);            % take fft of windowed filter kernel
   subplot(2,1,2)
   % undo derivative by dividing by frequency before displaying
   semilogx(f/2*Fs,20*log10(abs(H2(1:L)./(f.*Fs/2))),f/2*Fs,20*log10(shape),'x',Freq,Level,'o'); 
   legend('Filter Response','Interpolated Spec','Spec','location','southwest');
   title('Freq Responses of Specification and Attained Noise Profiles.  ');
   xlabel('Freq'); ylabel('dB');
end;

noise_filt=hout;
%% PLL Design Using MATLAB and Simulink 
% C MathWorks  

%% Cell 1: Capture system level constraints and phase noise 
LW = 2; %line width

%XO phase Noise
Ref_PN_Level      =  [-52 -92 -117  -137 -150  -154  -154 -154]; % dBc/Hz
Ref_PN_Freq       =  [1 10 100   1e3  10e3 100e3 1e6 10e6]; % Hz
Ref_Filter_Length = 2^12; % FIR filter for phase noise generation
%VCO phase noise
VCO_PN_Level      =  [22 -1 -24 -47 -70 -93 -116 -131 ]+15; % dBc/Hz
VCO_PN_Freq       =  [1 10 100   1e3  10e3 100e3 1e6 10e6]; % Hz
VCO_Filter_Length = 2^14; % FIR filter for phase noise generation

%Known PLL Constraints
%VCO Gain 2400 MHz -> 140 MHz/V, 2500 MHz -> 90 MHz/V, Mean = 115 MHz/V
Kv       = 2*pi*115e6;   % VCO rad/s/v 
Fref     = 10e6;         % reference frequency
Fcom     = 10e6;         % compare frequency (also channel spacing\channel width)
R        = Fref/Fcom;
Kr       = 1/R;
N_median = 244;
Kn       = 1/N_median;   % inverse of loop divider
Kp       = 0.5/pi;       % Phase detector gain in v/rad

%Optimal Loop BW for Phase Noise Performance
noise_fig = figure;
semilogx(Ref_PN_Freq,Ref_PN_Level+20*log10(N_median)-20*log10(R),'Color','r','LineWidth',LW);
hold;
semilogx(VCO_PN_Freq,VCO_PN_Level,'Color','b','LineWidth',LW);
legend('Amplified Ref Noise','VCO Noise');
xlabel('Frequency (Hz)');
ylabel('Noise Spectra (dB)');
grid;

%% Cell 2: Generate Laplace domain transfer functions 
%VCO
num    = Kv;   
den    = [1,0];
tf_VCO = tf(num,den);

%Loop Divider
num    = Kn;
den    = 1;
tf_DIV = tf(num,den);

%Reference Divider
num        = Kr;
den        = 1;
tf_REF_DIV = tf(num,den);

%% Cell 3: Initialize Loop Filter:   Kc*(TauP*s +1)/(s*(TauZ*s+1));
TauP_i =  1/3.2e7;   % 1/pole location. 
TauZ_i = 1/1.55e5;   % 1/zero location. 
Kc_i   = 3.5e5;
num    = Kc_i*[TauZ_i,1];
den    = [TauP_i,1,0];
tf_LFi = tf(num,den);

%% Cell 4: Design Loop Filter

% Don't forget to export the new loop filter transfer function "tf_LF" from SISO tool to
% the workspace!
sisofig = sisotool('bode',tf_VCO,tf_LFi,tf_DIV,tf_REF_DIV);
input('Refine the loop filter');
%close(sisofig);

[num_cell,den_cell]=tfdata(tf_LF);
num  = num_cell{1};
den  = den_cell{1};
TauP = 1/den(2);
Kc   = num(3)*TauP;
TauZ = num(2)*TauP/Kc;

% Calculate Loop Response
OL              = tf_VCO*tf_LF*tf_DIV;
[Gm,PM,Wg,W3dB] = margin(OL);
F3dB            = W3dB/2/pi;
clear GM Wg;


%% Cell 5: Synthesize Circuit Equivalent
C2   = 1e-9;                 % pick  a nominal C2 
R2   = TauZ/C2;              % compute R2
C1   = C2*TauP/(TauZ-TauP);  % compute C1
K1   = 1/(C1+C2);            % current to voltage gain of RC network
Icpp = Kc/K1;
Icp  =  Icpp/Kp;             % scaled Icp to attain Kc and compensate for Kp 


%% Cell 6: Linear Analysis and Phase Noise Prediction

% Create Reference and VCO transfer functions
CL_phase_in_vco_out             = tf_REF_DIV*feedback((tf_LF*tf_VCO),tf_DIV);
CL_phase_disturbance_in_vco_out = feedback(1,(tf_LF*tf_VCO*tf_DIV));

% Define frequency range
fmin  = min([VCO_PN_Freq,Ref_PN_Freq]);
fmax  = max([VCO_PN_Freq,Ref_PN_Freq]);
Npts  = 1000; % number of frequency points
freqv = logspace(log10(fmin),log10(fmax),Npts); % frequency vector

% Compute frequency response of PLL ref input to PLL output
H_ph2VCO    = squeeze(freqresp(CL_phase_in_vco_out,2*pi*freqv));
H_dB        = 20*log10(abs(H_ph2VCO))'; % note the transpose 
Interp_Type = 'linear';  

% Interpolate measured reference phase noise over same set of frequencies
Ref_Phase_Noise_dB = interp1(log10(Ref_PN_Freq),Ref_PN_Level,log10(freqv),Interp_Type);
G_dist2VCO         = squeeze(freqresp(CL_phase_disturbance_in_vco_out,2*pi*freqv));
G_dB               = 20*log10(abs(G_dist2VCO))'; % note the transpose
VCO_Phase_Noise_dB = interp1(log10(VCO_PN_Freq),VCO_PN_Level,log10(freqv),Interp_Type);

%Gardner's fig 15.9
TF_figure=figure;
semilogx(freqv,Ref_Phase_Noise_dB,'color','blue','LineWidth',LW); hold on;
semilogx(freqv,H_dB,'color','red','LineWidth',LW);
%semilogx(freqv,(Ref_Phase_Noise_dB+H_dB),'color',[0 0 1],'LineWidth',LW);

semilogx(freqv,VCO_Phase_Noise_dB,'color','blue','LineWidth',LW,'LineStyle','--'); hold on;
semilogx(freqv,G_dB,'color','red','LineWidth',LW,'LineStyle','--');
%semilogx(freqv,(VCO_Phase_Noise_dB+G_dB),'color',[1 0 1],'LineWidth',LW);

% Noise power from both sources must be added and then total power
% convereted back to dBc
Ptotal_1 = 10.^((VCO_Phase_Noise_dB+G_dB)/10)+10.^((Ref_Phase_Noise_dB+H_dB)/10);
semilogx(freqv,(10*log10(Ptotal_1)),'color',[0 0 0],'LineWidth',LW);
legend({'Reference Phase Noise',...
        'Reference Phase in to PLL out TF',...
        'VCO Phase Noise',...
        'VCO Phase in to PLL out TF',...
        'Total PLL Phase Noise'},'Location','SouthEast');
ylabel('dBc/Hz for Noise, dB for TF'); xlabel('Hz'); title('PLL Phase Noise Calculations');
hold off;
grid
%% Basic PLL Design 
%  This function sets parameters for a phase domain PLL
%  The two parameter settings provide slightly different performance
%
%  The model uses a charge pump loop compensator 
% 
%  
%  MathWorks
%
% clear
plot_on = 1;          % enable or disable plots
clc;

Phase_Noise_sel = 1;
switch Phase_Noise_sel
  case 1
      % measured reference oscillator phase noise profile
      Ref_PN_Level  =  [ -120 -135  -144 -148  -150 -150   ]; % dBc/Hz
      Ref_PN_Freq   =  [ 1e4   1e5    5e5  1e6   1e7  3e7  ]; % Hz
      Ref_Filter_Length = 2^12; % FIR filter for phase noise generation

      % measured VCO phase noise profile
      VCO_PN_Level  =  [ -80 -100 -103 -105 -118 -127 -133 -140]; % dBc/Hz
      VCO_PN_Freq   =  [ 1e4  1e5  5e5  1e6  5e6  1e7  5e7  1e8];        % Hz
      VCO_Filter_Length = 2^14; % FIR filter for phase noise generation
    case 2
      % measured reference oscillator phase noise profile
      Ref_PN_Level  =  [ -100 -100  -150 -150   ]; % dBc/Hz
      Ref_PN_Freq   =  [ 1e4   1e6   1e7  3e7   ]; % Hz
      Ref_Filter_Length = 2^12; % FIR filter for phase noise generation

      % measured VCO phase noise profile
      VCO_PN_Level  =  [ -80 -100 -103 -105 -118 -127 -133 -140]; % dBc/Hz
      VCO_PN_Freq   =  [ 1e4  1e5  5e5  1e6  5e6  1e7  5e7  1e8];        % Hz
      VCO_Filter_Length = 2^10; % FIR filter for phase noise generation       
        
        
end

%% Setup system parameters
Kv      = 2*pi*4e7; % VCO rad/s/v 
Fref    = 100e6;    % reference frequency
N       = 8;        % loop divider value
Kp      = 0.5/pi;   % Phase Detector gain in v/rad (known/measured)
Kn      = 1/N;      % inverse of loop divider 

% plant model (VCO)
num=Kv;   
den=[1,0];
tf_vco = tf(num,den);

% loop divider
num = Kn;
den = 1;
tf_div = tf(num,den);

%% Loop Compensator setup
% selection 2 provides the best overall performance
% selection 1 makes for an interesting optimization with pll_cp_7.mdl
comp_sel=1;
% loop compensator   Kc*(Tau1*s +1)/(s*(Tau2*s+1));
switch comp_sel
  case 1
    % Tau1,Tau2 and Kc values from a previous session using sisotool  
    Tau1 = 1/8e6;   % 1/pole location 
    Tau2 = 1/2e5;   % 1/zero location    
    Kc   = 60e3;  
    num=Kc*[Tau2,1];
    den=[Tau1,1,0];
    tf_comp=tf(num,den); 
    loopBW=2e6;    % rough goal that was achieved with siso tool tuning
  case 2
    Tau1 = 1/1e8;
    Tau2 = 1/1e6;     % Tau1,Tau2 and Kc values from a previous session using sisotool
    Kc   = 2e5;  
    num=Kc*[Tau2,1];
    den=[Tau1,1,0];
    tf_comp=tf(num,den); 
    loopBW=1e6;            % rough goal that was achieved with siso tool tuning
 
  case 3
    Tau1 = 4.327e-8;     % Tau1,Tau2 and Kc values from a previous session 
                         % using Simulink Response Optimization 
    Tau2 = 2.163e-6;
    Kc   = 2.22e5;  
    num=Kc*[Tau2,1];
    den=[Tau1,1,0];
    tf_comp=tf(num,den); 
    loopBW=2e6;            % rough goal that was achieved
  
end

%% Start SISOTOOL for tuning
if plot_on
    % sisotool(tf_vco,tf_comp,tf_div,1)
end

%%
C2 = .01e-6;  % pick  a nominal C2 
R2 = Tau2/C2; % compute R2

C1  = C2*Tau1/(Tau2-Tau1);  % compute C1
K1  = 1/(C1+C2);           % current to voltage gain of RC network
Icpp = Kc/K1;
Icp  =  Icpp/Kp;            % scaled Icp to attain Kc and compensate for Kp 
 
Vdd = 5;                   % supply voltage
Rcp = Vdd/Icp;              % switch series resistor sets max current

% Compute loop transfer functions
% Closed loop transfer function from phase input to VCO phase output
% Theta_c to Theta_v in Gardner's Figure 15.8
cl_phase_in_vco_out = feedback((tf_comp*tf_vco),tf_div);
% Closed loop transfer function from VCO phase disturbance to VCO phase output
% Phi_0 to Theta_0 in Gardner's Figure 15.8
cl_phase_disturbance_in_vco_out = feedback(1,(tf_comp*tf_vco*tf_div));
   
%% Plot Closed loop response from phase inputs to VCO output
if plot_on==1
   h1=ltiview('bode',cl_phase_in_vco_out);
   h2=ltiview('step',cl_phase_in_vco_out);
   h1=ltiview('bode',cl_phase_disturbance_in_vco_out);
   h2=ltiview('step',cl_phase_disturbance_in_vco_out); 
end

%% Phase Noise Prediction
% Two components of phase noise are considered: reference osc and VCO
if plot_on==1
% Define frequency range over which calculations will be made
fmin=min([VCO_PN_Freq,Ref_PN_Freq]);
fmax=max([VCO_PN_Freq,Ref_PN_Freq]);
Npts=1000; % number of frequency points
freqv=logspace(log10(fmin),log10(fmax),Npts); % frequency vector

% Compute frequency response of PLL ref input to PLL output
H_ph2VCO=squeeze(freqresp(cl_phase_in_vco_out,2*pi*freqv));
H_dB=20*log10(abs(H_ph2VCO))'; % note the transpose

% the spline produces a nicer curve and it goes all the way to fmax
Interp_Type='spline'; 
% but the phase noise generator uses linear interpolation, so it will
% provide the best match. 
Interp_Type='linear';  
% Interpolate measured reference phase noise over same set of frequencies
Ref_Phase_Noise_dB = interp1(log10(Ref_PN_Freq),Ref_PN_Level,log10(freqv),Interp_Type);


G_dist2VCO=squeeze(freqresp(cl_phase_disturbance_in_vco_out,2*pi*freqv));
G_dB=20*log10(abs(G_dist2VCO))'; % note the transpose

VCO_Phase_Noise_dB = interp1(log10(VCO_PN_Freq),VCO_PN_Level,log10(freqv),Interp_Type);

LW=2;
% Now for the big plotting exercise. This is along the lines of Gardner's
% fig 15.9
semilogx(freqv,Ref_Phase_Noise_dB,'color',[1 0 0],'LineWidth',LW); hold on;
semilogx(freqv,H_dB,'color',[0 1 0],'LineWidth',LW);
semilogx(freqv,(Ref_Phase_Noise_dB+H_dB),'color',[0 0 1],'LineWidth',LW);

semilogx(freqv,VCO_Phase_Noise_dB,'color',[1 1 0],'LineWidth',LW); hold on;
semilogx(freqv,G_dB,'color',[0 1 1],'LineWidth',LW);
semilogx(freqv,(VCO_Phase_Noise_dB+G_dB),'color',[1 0 1],'LineWidth',LW);
% Noise power from both sources must be added and then total power
% convereted back to dBc
Ptotal = 10.^((VCO_Phase_Noise_dB+G_dB)/10)+10.^((Ref_Phase_Noise_dB+H_dB)/10);
semilogx(freqv,(10*log10(Ptotal)),'color',[0 0 0],'LineWidth',LW);
legend({'Reference Phase Noise',...
        'Reference Phase in to PLL out TF',...
        'PLL Phase Noise due to Reference',...
        'VCO Phase Noise',...
        'VCO Phase in to PLL out TF',...
        'PLL Phase Noise due to VCO',...
        'Total PLL Phase Noise'});
ylabel('dBc/Hz for Noise, dB for TF'); xlabel('Hz'); title('PLL Phase Noise Calculations');
hold off;
end;
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值