关于PFD (鉴频鉴相器)的模型,一般在 Matlab 的 simulink 环境下比较容易实现,因为搭建 PFD 主要的模块都能在 simulink 的库中找到,直接按照电路一样搭建就可以了。在这里,我们主要关心的是基于 Verilog-A 的方法的实现, 以希望在之后的电路设计中方便实现的模型和实际电路的切换。
PFD 的简单模型
左图所示为 PFD 的基本的状态机的描述。
在 Designer’s Guide 网站上,提供了 PFD-CP 整体的 Verilog-A model,基本上还是用这样的状态机的模型来描述 PFD 的特性。
在这里我们以类似的方法加以描述,定义 state 表示内部状态:
Stete=1,0,-1分别对应 up=1,dn=0; up=dn=0 和 up=0,dn=1 三个状态
具体的 Verilog-A 模型见下面:
// VerilogA model for PFD Time domain, without reset delay `include "constants.h" `include "discipline.h" module PFD_Tdomain(ref,fb,up,dn); input ref, fb; output up, dn; electrical ref, fb, up, dn; parameter real vh=1.2; parameter real vl=0; parameter real vth=0.6; parameter real ttol=5p from [0:inf); parameter real td=0 from [0:inf); parameter real tt=1p from (0:inf); integer state; analog begin @ (initial_step) state=0; @ (cross(V(ref)-vth, 1, ttol)) begin if (state<1) state=state+1; end @ (cross(V(fb)-vth, 1, ttol)) begin if (state>-1) state=state-1; end V(up)<+ transition((state==1) ? vh:vl, td, tt); V(dn)<+ transition((state==-1) ? vh:vl, td, tt); end endmodule
实际的 PFD 设计需要使 UP/DN 信号在零相差时有一段同时为 ‘1’ 的时间以消除死区(dead-zone),更重要的是,实际的复位路径上的延时(Reset-delay)会导致 missing-edge 的问题,在特性曲线上表现为 2*Pi 附近增益反转,从而使 PFD 的速度受限,PLL 的锁定变慢。
包含复位延时的PFD模型
为了尽可能的利用之前的 PFD 的模型,这里保留了之前 state 的定义,同时增加了 hide_state 这一变量来描述隐藏的状态(UP=DN=1)。
同时,模型中利用 Verilog-A 的 $realtime 函数来实现延时(下面模型中的 ton 为零相差时 UP/DN 同时为 1 的脉冲宽度)
具体的 Verilog-A 模型见下面:
// VerilogA model for PFD Time domain, with reset delay `include "constants.h" `include "discipline.h" module PFD_Tdomain(ref,fb,up,dn); input ref, fb; output up, dn; electrical ref, fb, up, dn; parameter real vh=1.2; parameter real vl=0; parameter real vth=0.6; parameter real ttol=5p from [0:inf); parameter real td=0 from [0:inf); parameter real tt=1p from (0:inf); parameter real ton=600p from[0:inf); integer state, hide_state; real Toff; analog begin @ (initial_step) begin state=0; hide_state=0 ; Toff=0; end @ (cross(V(ref)-vth, 1, ttol)) begin if (state==-1) begin hide_state=1; Toff=ton+$realtime; end else state=1; end @ (cross(V(fb)-vth, 1, ttol)) begin if (state==1) begin hide_state=1; Toff=ton+$realtime; end else state=-1; end @ (timer(Toff)) begin if (hide_state==1) begin state=0; hide_state=0; end end V(up)<+ transition((state==1)||(hide_state==1) ? vh:vl, td, tt); V(dn)<+ transition((state==-1)||(hide_state==1) ? vh:vl, td, tt); end endmodule
下面是仿真得到的波形和相差扫描的曲线
如果想让up和dn经过不同的时间复位该如何修改代码呢
可以分享一下PLL其他模块的VerilogA建模吗?最近正在写一个,跑通了,可感觉波形不太好
我原来写的时候基本上都参考的 designer’s guide 网站上的例子,你可以去看看,另外 vco 的模型 cadence 的ahdl 库里面应该自己就有的。
谢谢,我发现和仿真的精度有关系,我用理想的模型仿真都有比较大的jitter,郁闷