Hi,everyone!
the problem is as following:
1. this fractional pll is based on veriloga. all blocks are veriloga model.
2. charge pump current is Icp=16uA, VCO gain kvco=100Mhz, LPF ’s C1=36pf, R1=100K, C2=3.6pf,R3=65K,C3=1pf。
3.when doing transient simulation,after pll locked, using freq function in viva calculator to measure the vco’s frequency, the frequency‘s fluctuation is about 200khz peak to peak, and the center frequency is 4.8G.
it should have fluctuation, but isn't this value too large? which magnitude should this fluctuation should
be?
if the magnitude is about 10khz or less, what's wrong with my model.
the model is as below:

PFD code:
Code:`include "constants.vams"
`include "disciplines.vams"
module PFD_V1_VA (ref_clk, fb_clk, up_out, down_out);
inout ref_clk, fb_clk, up_out, down_out;
electrical ref_clk, fb_clk, up_out, down_out;
parameter real vdd=3.3,
ttol=10f,
ttime=0.2n ;
integer state; // state=1 for down, -1 for up
real td_up, td_down ;
/*
analog begin
@(cross( V(ref_clk) - vdd/2 , 1 , ttol )) begin
state = state - 1;
if(V(up_out)>vdd/2) td_up=480p; else td_up=1005p;
if(V(down_out)<vdd/2) td_down=480p; else td_down=1090p;
end
@(cross( V(fb_clk) - vdd/2 , 1 , ttol )) begin
state = state + 1;
if(V(up_out)>vdd/2) td_up=480p; else td_up=1005p;
if(V(down_out)<vdd/2) td_down=480p; else td_down=1090p;
end
if ( state > 1 ) state = 1 ;
if ( state < -1 ) state = -1;
V(down_out) <+ transition( (state + 1)/2*vdd , td_down , ttime );
V(up_out) <+ transition( (state - 1)/2*vdd+vdd , td_up , ttime );
end
*/
analog begin
@(cross( V(ref_clk) - vdd/2 , 1 , ttol )) begin
if(state<1) state = state + 1;
end
@(cross( V(fb_clk) - vdd/2 , 1 , ttol )) begin
if(state>-1) state = state - 1;
end
V(up_out) <+ transition( (state==1)?1.2:0 , 0 , 10p );
V(down_out) <+ transition( (state==-1)?1.2:0 , 0 , 10p );
end
endmodule
CP code:
Code:`include "constants.vams"
`include "disciplines.vams"
module CP_VA(up,down,iout);
input up,down;
output iout;
electrical up,down,iout;
parameter Vhigh=1 from[0:inf);
parameter Vlow=0 from[0:inf);
parameter Vtrans=0.5;
parameter vp_h=1.2;
parameter vp_l=0;
/*
real iuptemp,idowntemp,chargecurrent;
analog begin
chargecurrent=50u;
iuptemp=(V(up)>Vtrans)?1:0;
idowntemp=(V(down)>Vtrans)?-1:0;
I(iout)<+ -iuptemp*chargecurrent-idowntemp*chargecurrent;
end
endmodule
*/
real iuptemp,idowntemp,chargecurrentdown,chargecurrentup;
analog begin
if(V(iout)>(vp_l+200m))
chargecurrentdown=16u;
if(V(iout)>vp_l && V(iout)<=(vp_l+200m) )
chargecurrentdown=V(iout)*80u;
if(V(iout)<=vp_l)
chargecurrentdown=0;
if(V(iout)<(vp_h-200m))
chargecurrentup=16u;
if(V(iout)>=(vp_h-200m) && V(iout)<vp_h )
chargecurrentup=(vp_h-V(iout))*80u;
if(V(iout)>=vp_h)
chargecurrentup=0;
/*
iuptemp=(V(up)>Vtrans)?1:0;
idowntemp=(V(down)>Vtrans)?-1:0;
*/
@(cross(V(up)-Vtrans,1)) iuptemp=1;
@(cross(V(up)-Vtrans,-1)) iuptemp=0;
@(cross(V(down)-Vtrans,1)) iuptemp=-1;
@(cross(V(down)-Vtrans,-1)) iuptemp=0;
I(iout)<+ -iuptemp*chargecurrentup-idowntemp*chargecurrentdown;
end
endmodule
VCO code:
Code:`include "constants.vams"
`include "disciplines.vams"
module VCO_BITS_TP_FD_VA(loopin,tp,bits,freqout);
input loopin,tp;
input [3:0] bits;
output freqout;
electrical loopin,tp;
electrical [3:0] bits;
electrical freqout;
parameter vhigh=1.2;
parameter vlow=0;
parameter vtrans=(vhigh+vlow)/2;
real tempbits;
real freq;
real fmax;
real fmin;
real vmax;
real vmin;
real initial_freq;
real space;
real kvco;
real gain;
analog begin
kvco=100M;
initial_freq=4720M;
space=20M;
vmax=800m;
vmin=400m;
tempbits=0;
tempbits=tempbits+((V(bits[3])>vtrans)?1:0)*8;
tempbits=tempbits+((V(bits[2])>vtrans)?1:0)*4;
tempbits=tempbits+((V(bits[1])>vtrans)?1:0)*2;
tempbits=tempbits+((V(bits[0])>vtrans)?1:0)*1;
case(tempbits)
0,1,2,3 : gain=1.6M;
4,5,6,7: gain=1.8M;
8,9,10,11:gain=2M;
12,13,14,15:gain=2.4M;
default gain=1.6M;
endcase
fmin=initial_freq+tempbits*space;
fmax=initial_freq+(vmax-vmin)*kvco+tempbits*space;
freq=(V(loopin)-vmin)*kvco+fmin+(V(tp)-0.6)*gain;
if (freq > fmax) freq = fmax;
if (freq < fmin) freq = fmin;
//$bound_step(1/(freq*100));
V(freqout) <+ freq/1e6;
end
endmodule
freq to sin wave conversion code:
Code:`include "constants.vams"
`include "disciplines.vams"
`define PI 3.14159265358979323846264338327950288419716939937511
module FREQ2VOL_V1_VA(vin, rst, vout);
input vin, rst;
output vout;
electrical vin, rst, vout;
parameter real amp=0.6;
parameter integer steps_per_period=32;
parameter real vco_gain=1e6;
real phase, inst_freq, phase_modulus;
analog begin
if(V(rst)>0.6) begin
inst_freq=1e6;
phase_modulus=1e-3;
end
else begin
inst_freq=vco_gain*V(vin);
phase_modulus=1;
end
$bound_step(1.0 / (steps_per_period*inst_freq));
phase=idtmod(inst_freq, 0, phase_modulus);
V(vout) <+ 0.6+amp*sin(2*`PI*phase-`PI);
end
endmodule
DIVIDER code:
Code:// VerilogA for nb1820_t55lp_lwz_v01, DIV_VAR_FD_VA, veriloga
`include "constants.vams"
`include "disciplines.vams"
module DIV_VAR_FD_VA(ratio,freqin,freqout);
input freqin,ratio;
output freqout;
electrical freqin,ratio, freqout;
real tempratio;
analog begin
tempratio=2*V(ratio);
V(freqout) <+ V(freqin)/tempratio;
end
endmodule