I write a simple DLL circuit using verilogA.
I use a transition function to implement delay function in the VCDL delay cells as below:
Code:`include "constants.vams"
`include "disciplines.vams"
module delay_var(din,dout, vctrl);
parameter real tr=0 from [0:inf);
parameter real tt=1p from [0:inf);
parameter integer dir=0 from [-1:+1];
parameter real vcc=1 from (0:inf);
parameter real threshold=0.5 from [0:inf);
parameter real vctrl_min=0 from [0:inf);
parameter real vctrl_max=vcc from (0:inf);
parameter real td_min=20p from [0:inf);
parameter real td_max=80p from (td_min:inf);
output dout;
input din, vctrl;
voltage din, dout, vctrl;
integer state;
real td, td2;
analog begin
td = (V(vctrl)-vctrl_min)*(td_max - td_min) / (vctrl_max - vctrl_min) + td_min;
//bound the delay
if( td > td_max)
td = td_max ;
if( td < td_min)
td = td_min ;
@(cross(V(din) - threshold, dir, tt))
state = (V(din)-threshold>=0);
V(dout) <+ vcc*transition(state ? 1: 0,td,tr,tr,tt);
end
endmodule
The DLL is able to lock to the rising edge but the duty-cycle is distorted by rise_time/2 (in this case is 10ps/2=5ps), shown in the diagram
The frequency of the output (clkout) is remained to same but with minor duty-cycle distortion.
How could I solve this?
ps: i have put small tolerance to 0.5ps