Analog PLL Design and Simulation by Verilog HDL
1. Block Diagram

2. Transfer Function


3. Web-Calculator
To calculate appropriate constant C1/C2/R1, following web-calculator is
convenient.
http://geocities.com/fudinggepll/pllfilterprogram.html
In the site you can get value of C1/C2/R2 as follows.

4. Transfer Function to State Space Model
Since Veritak needs state-space model, following script (MATLAB) is used.
C2=17e-12 C1=82e-12 R1=4667 R1C1=R1*C1; C1_C2=C1+C2; C1C2R1=C1*C2*R1; b=[R1C1 1]; a=[C1C2R1 C1_C2 0]; [A,B,C,D] = tf2ss(b,a) a2=[C1C2R1 C1_C2 0 0]; kv=200e6; ki=260e-6; N=32; Gain=kv*ki/N; W=logspace(4,9); freqs(b*Gain,a2,W) save 'F:\verilog\PLL\loop_filter.txt' A B C D -ascii -double
In comparison, let's try additional two cases, less phase margin of 15degree
and much phase margin 75degree.
Open-loop frequency response will be as follows.
Degree 45

Degree 15

Degree 75

5. Analog Simulation
Here is a source code written by Verilog-2001
//May.6.2005
//Analog PLL demo
`define CYCLE (1.0/13.56/2*1e6 )
`timescale 1ps/1ps
module pll_test;
reg ref_clock=0;
always #(`CYCLE) ref_clock=~ref_clock;
pll_module #(.File_Name("loop_filter.txt")) PLLl_1MHz (ref_clock);
pll_module #(.File_Name("loop_filter1MHz_much_phase.txt")) PLLl_1M_Much(ref_clock);
pll_module #(.File_Name("loop_filter1MHz_less_phase.txt")) PLLl_1M_Less(ref_clock);
endmodule
module pll_module #(parameter File_Name="loop_filter.txt") (input ref_clock);
wire v_clock,d_clock;
wire [1:0] iout;
pfd pll1(.ref_clock(ref_clock),
.d_clock(d_clock),
.iout(iout));
loop_filter_and_vco #(.File_Name(File_Name)) lvco(.iout(iout),.v_clock(v_clock));
divider #(.DRatio(16)) div(.v_clock(v_clock),.d_clock(d_clock));
endmodule
module divider #(parameter integer DRatio=32)
( input v_clock,
output reg d_clock=0);
integer counter=0;
always @(posedge v_clock) begin
if (counter==DRatio-1) counter <=0;
else counter <=counter+1;
end
always @(posedge v_clock) begin
if (counter ==DRatio-1) d_clock<=~d_clock;
end
endmodule
module loop_filter_and_vco #(parameter File_Name="loop_filter.txt")
( input signed [1:0] iout,
output v_clock);
localparam real Igain=-(-260e-6);//A
localparam real Igminus=260e-6;
localparam integer cycle=100;//ps
localparam real Vco_Gain=200*1e6;//Hz/V
localparam real Center_Frequency=200e6;//433.92e6;//Hz
real I;
real read_array[0:10];// Input vector for rungekutta
real write_array[0:10];//Output vector from rugekutta
real vco_in;
real omega,delta_theta;
real theta,delta_theta;
real vco_waveform;
always @(*) I=Igain*iout;
always #(cycle) begin
read_array[0]=I;//
$runge_kutta(File_Name,1);//Loop Filter V/I
vco_in=write_array[0];//Get Loop Filter voltage
omega=2.0*(Center_Frequency+vco_in*Vco_Gain)*$M_PI;
delta_theta=cycle*1e-12*omega;//
theta=theta+delta_theta;
vco_waveform=$sin(theta);//
end
assign v_clock=vco_waveform>=0 ? 1:0;
initial begin
$runge_kutta(File_Name,0,read_array,write_array);//rugekutta Initialization
#(8200*1000) $finish;
end
endmodule
module pfd( input ref_clock,
input d_clock,
output reg signed [1:0] iout);
integer state=0;
always @(posedge ref_clock) state=state+1;
always @(posedge d_clock) state=state-1;
always @(*) begin
if (state>0) state=1;
else if (state<0) state=-1;
if (state>0) iout=1;
else if (state<0) iout=-1;
else iout=0;
end
endmodule
In control theory, 45 degree of phase margin is ideal for
proper settling time. That is confirmed in analog simulation by verilog-HDL.
