在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 25217|回复: 64

最近小作:Verilog版的dpll

[复制链接]
发表于 2003-9-1 15:02:24 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
大家好,经过断断续续的努力,我得verilog版的数字锁相环终于初步有了结果。这个锁相环纯粹是我的个人爱好。大概一个月前,我曾与斑竹讨论过这个问题,斑竹也给大家发了一篇这方面的文章。之后,经过查阅资料,我弄明白锁相工作的原理。接着,动手写自己的锁相环。写程序并没有用去多少时间,但是为了排除那些 的错误,却用了大量的时间。还好,总算看到了结果。
曾经答应斑竹做完了就给他发一份,现在,还是公开发给大家吧。由于时间及经验的原因,这个只能锁相的环可能还不够专业,但我希望对锁相环感兴趣的朋友们能一起来研究它,大家一起分享自己劳动成果,使它更加完善,谢谢。
上面是这个dpll的原理图:
5_280.jpg
 楼主| 发表于 2003-9-1 15:06:44 | 显示全部楼层

最近小作:Verilog版的dpll

异或门鉴相器就是一个异或门。
K可变模计数器的源代码如下:
module KCounter(rst,clk,ud,Kmode,INC_plus,DEC_plus);
       input rst,clk,ud;
   input [2:0] Kmode;
   output INC_plus,DEC_plus;
   reg [8:0] CounterINC,CounterDEC;
   reg [8:0] Kvalue;
       //K±äÄ£
   always@(Kmode)
   begin
   case(Kmode)
   3'b001:Kvalue<=9'b000000111;
       3'b010:Kvalue<=9'b000001111;
   3'b011:Kvalue<=9'b000011111;
   3'b100:Kvalue<=9'b000111111;
   3'b101:Kvalue<=9'b001111111;
   3'b110:Kvalue<=9'b011111111;
   3'b111:Kvalue<=9'b111111111;
   default:Kvalue<=9'b000001111;
   endcase
   end
      
   //&frac14;&AElig;&Ecirc;&yacute;&AElig;÷&micro;&Auml;&Iuml;&Acirc;&Ograve;&raquo;&cedil;&ouml;&Ecirc;&yacute;&Ouml;&micro;&pound;¨&frac14;&Oacute;1&raquo;ò&frac14;&otilde;1&pound;&copy;
   wire [8:0] INC_cnt,DEC_cnt;
   assign INC_cnt=CounterINC+1;
       assign DEC_cnt=CounterDEC-1;
      
   //&ETH;&Icirc;&sup3;&Eacute;&Ouml;&Atilde;&Icirc;&raquo;&ordm;&Iacute;&Ccedil;&aring;&Aacute;&atilde;&Acirc;&ouml;&sup3;&aring;&pound;¨&acute;&oslash;&Oacute;&ETH;&Atilde;&laquo;&acute;&Igrave;&pound;&copy;
   wire E_Kvalue,E_zero;
   assign E_Kvalue=(CounterINC==Kvalue)?1:0;
       assign E_zero=(CounterDEC==0)?1:0;
   wire C_set,C_clr;
   assign C_clr=E_Kvalue&~ud;
   assign C_set=E_zero&ud;
      
   //&ETH;&Icirc;&sup3;&Eacute;&Ouml;&Atilde;&Icirc;&raquo;&ordm;&Iacute;&Ccedil;&aring;&Aacute;&atilde;±ê&Ouml;&frac34;&pound;¨&Atilde;&raquo;&Oacute;&ETH;&Atilde;&laquo;&acute;&Igrave;&pound;&copy;
       reg clr_flag;
       reg set_flag;
   always@(posedge rst or negedge clk)
   begin
     if(rst)   clr_flag<=1'b0;
else      clr_flag<=C_clr;
   end
   always@(posedge rst or negedge clk)
   begin
     if(rst)   set_flag<=1'b0;
else      set_flag<=C_set;
   end
       //&Ograve;&Ocirc;&Iuml;&Acirc;&Ecirc;&Ccedil;&ETH;&Icirc;&sup3;&Eacute;&frac14;&Oacute;&frac14;&otilde;&Acirc;&ouml;&sup3;&aring;&micro;&Auml;&cedil;¨&Ouml;ú&micro;&ccedil;&Acirc;·&pound;&not;&Ecirc;&sup1;&AElig;&auml;&iquest;&Eacute;&Ograve;&Ocirc;±&pound;&sup3;&Ouml;3&cedil;&ouml;clk

   reg [2:0] INCshift,DECshift;
   always@(posedge rst or negedge clk)
   begin
     if(rst)   INCshift[2:0]<=3'b000;
else   begin
           INCshift[2]<=clr_flag;
                   INCshift[1]<=INCshift[2];
                   INCshift[0]<=INCshift[1];
end
   end
   always@(posedge rst or negedge clk)
   begin
     if(rst)   DECshift[2:0]<=3'b000;
else   begin
           DECshift[2]<=set_flag;
                   DECshift[1]<=DECshift[2];
                   DECshift[0]<=DECshift[1];
end
   end

       reg clrINC,clrDEC;
   always@(posedge rst or negedge clk)
   begin
     if(rst)   clrINC<=1'b0;
else      clrINC<=INCshift[0];
   end
   always@(posedge rst or negedge clk)
   begin
     if(rst)   clrDEC<=1'b0;
else      clrDEC<=DECshift[0];
   end
      //&Ograve;&Ocirc;&Iuml;&Acirc;&Ecirc;&Ccedil;&frac14;&Oacute;&Acirc;&ouml;&sup3;&aring;&ordm;&Iacute;&frac14;&otilde;&Acirc;&ouml;&sup3;&aring;&micro;&Auml;&ETH;&Icirc;&sup3;&Eacute;&pound;&not;&Euml;ü&Atilde;&Ccedil;±&pound;&sup3;&Ouml;4&cedil;&ouml;clk
   reg INC_plus,DEC_plus;
   always@(posedge rst or posedge set_flag or posedge clrDEC)
   begin
     if(rst)              DEC_plus<=1'b0;
else  if(set_flag)   DEC_plus<=1'b1;
else                 DEC_plus<=1'b0;
   end
   always@(posedge rst or posedge clr_flag or posedge clrINC)
   begin
     if(rst)              INC_plus<=1'b0;
else  if(clr_flag)   INC_plus<=1'b1;
else                 INC_plus<=1'b0;
   end
       ///&Ograve;&Ocirc;&Iuml;&Acirc;&Ecirc;&Ccedil;&Aacute;&frac12;&cedil;&ouml;&frac14;&AElig;&Ecirc;&yacute;&AElig;÷(&AElig;&auml;&Ecirc;&micro;&sup2;&raquo;&iquest;&Eacute;&Auml;&aelig;)
   wire INC,DEC;
   assign INC=~ud&clk;
   assign DEC=ud&clk;
   always@(posedge rst or negedge DEC or posedge set_flag)
   begin
     if(rst)                  CounterDEC<=9'b000000000;
else  if(set_flag)       CounterDEC<=Kvalue;
else                     CounterDEC<=DEC_cnt;
   end
   always@(posedge rst or negedge INC or posedge clr_flag)
   begin
     if(rst)                  CounterINC<=9'b000000000;
else  if(clr_flag)       CounterINC<=9'b000000001;
else                     CounterINC<=INC_cnt;
   end
endmodule
 楼主| 发表于 2003-9-1 15:08:18 | 显示全部楼层

最近小作:Verilog版的dpll

加减脉冲计数器源代码如下:
module IDCnt(clk,rst,INC,DEC,serout);
    input clk,rst,INC,DEC;
output serout;
/////2·&Ouml;&AElig;&micro;&frac14;&AElig;&Ecirc;&yacute;&AElig;÷&pound;&not;&AElig;&auml;&Ecirc;&auml;&sup3;&ouml;&Ecirc;&Ccedil;&Iuml;à&sup2;&icirc;&Icirc;&ordf;pi&pound;&not;&Otilde;&frac14;&iquest;&Otilde;±&Egrave;&Icirc;&ordf;50&pound;&yen;&micro;&Auml;·&frac12;&sup2;¨
    reg div2;
wire cdiv2;
always@(posedge rst or negedge clk)
begin
   if(rst)  div2<=0;
   else     div2<=~div2;
end
assign cdiv2=~div2;

////INC&Oacute;&euml;DEC&micro;&Auml;±&szlig;&Ntilde;&Oslash;&frac14;ì&sup2;&acirc;
    reg [1:0] INC_det,DEC_det;
wire INC_edge,DEC_edge;
    wire  ser1,ser2;
assign ser1=div2&clk;
assign ser2=cdiv2&clk;
always@(posedge rst or negedge ser1)
begin
  if(rst)   INC_det[1]<=0;
  else      INC_det[1]<=INC;
end
always@(posedge rst or negedge ser1)
begin
  if(rst)   INC_det[0]<=0;
  else      INC_det[0]<=INC_det[1];
end
assign INC_edge=~INC_det[1]&INC_det[0];

always@(posedge rst or posedge ser2)
begin
  if(rst)   DEC_det[1]<=0;
  else      DEC_det[1]<=DEC;
end
always@(posedge rst or posedge ser2)
begin
  if(rst)   DEC_det[0]<=0;
  else      DEC_det[0]<=DEC_det[1];
end
assign DEC_edge=~DEC_det[1]&DEC_det[0];
//////&Ecirc;&auml;&sup3;&ouml;&micro;&Auml;&Ecirc;&yacute;&frac34;&Yacute;&Agrave;&acute;&Ocirc;&acute;&Oacute;&euml;×&acute;&Igrave;&not;
    reg INC_flag;
reg DEC_flag;
always@(posedge rst or negedge INC)
begin
if(rst)  INC_flag<=1'b0;
else     INC_flag<=~INC_flag;
end
always@(posedge rst or negedge DEC)
begin
if(rst)  DEC_flag<=1'b0;
else     DEC_flag<=~DEC_flag;
end
wire iddet;
//assign iddet=INC_edge|DEC_edge;
reg ioed;
always@(posedge rst or posedge INC_edge or posedge DEC_edge)
begin
if(rst)             ioed<=1'b0;
else if(INC_edge)   ioed<=1'b1;
else                ioed<=1'b0;
end
    wire detenable;
wire select;
assign select=(ioed&INC_flag&~DEC_flag)|(~ioed&~INC_flag&~DEC_flag)|(~ioed&INC_flag&DEC_flag)|(ioed&~INC_flag&DEC_flag);
assign detenable=select?cdiv2:div2;
   /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   ///////////
reg idedge1,idedge2;
always@(posedge rst or negedge clk)
begin
if(rst) idedge1<=1'b0;
else if(detenable)  idedge1<=INC_edge;
end
always@(posedge rst or negedge clk)
begin
if(rst) idedge2<=1'b0;
else if(detenable)  idedge2<=DEC_edge;
end

reg state;
always@(posedge rst or posedge idedge1 or posedge idedge2)
begin
  if(rst)                                     state<=1'b0;
  else if(idedge1)                            state<=~state;
  else                                        state<=~state;                  
      
end
////&Ecirc;&auml;&sup3;&ouml;&Ntilde;&iexcl;&Ocirc;&ntilde;
   assign serout=state?ser1:ser2;
endmodule
 楼主| 发表于 2003-9-1 15:12:46 | 显示全部楼层

最近小作:Verilog版的dpll

8分频计数器很简单,采用异步即可,代码如下(图中标为4分频,该其为8分频):
module div4(rst,clk,out);
   input rst,clk;
   output  out;
   reg out;
   reg a,b;
   always@(posedge rst or negedge clk)
   begin
       if(rst)   a<=1'b0;
   else      a<=~a;
   end
   always@(posedge rst or negedge a)
   begin
       if(rst)   b<=1'b0;
   else      b<=~b;
   end
   always@(posedge rst or negedge b)
   begin
       if(rst)   out<=1'b0;
   else      out<=~out;
   end
endmodule
按照这个程序,clk的频率为datain的16倍不同步即可。
发表于 2003-9-1 16:28:13 | 显示全部楼层

最近小作:Verilog版的dpll

好东西!
多谢你为大家做的贡献!
 楼主| 发表于 2003-9-1 16:29:25 | 显示全部楼层

最近小作:Verilog版的dpll

从理论上来说,这个锁相环的占空比为7/16~9/16。
这种锁相环的优点是锁定速度快,缺点是只能锁相,不能锁频。
发表于 2003-9-1 16:38:14 | 显示全部楼层

最近小作:Verilog版的dpll

版主,什么时候帮我加点威望阿
^_^,不错啊
 楼主| 发表于 2003-9-1 16:43:25 | 显示全部楼层

最近小作:Verilog版的dpll

对了,还有顶层模块:
module dplltop(rst,clk,datain,Kmode,dataout);
  input rst,clk,datain;
  input [2:0] Kmode;
  output dataout;
  wire div4out,ud;
  assign ud=datain^div4out;
  
  wire incsin,decsin;
  KCounter KCounter1(.rst(rst),.clk(clk),.ud(ud),.Kmode(Kmode),.INC_plus(incsin),.DEC_plus(decsin));
  wire idout;
  IDCnt    IDCnt1(.clk(clk),.rst(rst),.INC(incsin),.DEC(decsin),.serout(idout));
  div4     div41(.rst(rst),.clk(idout),.out(div4out));
  assign dataout=div4out;
endmodule
整套软件我用的是FPGA Advantage5.4(正版的)综合仿真(前仿)都没有问题。
我希望有兴趣的朋友能做进一步的改进或完善,也希望大家把结果公布出来,共同提高。
 楼主| 发表于 2003-9-2 11:02:09 | 显示全部楼层

最近小作:Verilog版的dpll

这个锁相环只能实现2倍频,即信号ud。
发表于 2003-9-9 15:46:57 | 显示全部楼层

最近小作:Verilog版的dpll

up 一下
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /2 下一条

×

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-4-30 22:10 , Processed in 0.045799 second(s), 10 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表