Verilog 时钟分频设计

1、偶数分频

将触发器的反向输出端接到触发器的输入,可以构成简单二分频电路。

在此基础上,将二分频电路进行级联可以构成四分频,八分频电路。电路如下图所示:

Verilog 时钟分频设计_第1张图片 

对于任意偶数分频,或者系数较大的偶数分频,可以使用计数器循环计数来实现分频。当计数周期达到N/2(N为分频系数)是对输出时钟进行翻转,可以实现占空比为50%的任意偶数分频电路。偶数分频的verilog描述如下所示:

module even(  
    input clk,
    input rst_n,
    output clk_out   
);
//定义分频系数 
parameter N = 8;   

reg clk_out_r;
reg [3:0] cnt;

//N/2 计数 
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin    
       cnt <= 4'd0  ;
    end
    else begin
    cnt <= cnt == (N/2 - 1) ? 0 : cnt +1; 
    end
end 

//时钟输出
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        clk_out_r <= 0;
    end
    else begin
        clk_out_r <= cnt == (N/2 - 1) ? ~clk_out_r : clk_out_r;
    end
end

assign clk_out = clk_out_r;

endmodule

2、奇数分频

如果不要求分频时钟的占空比为50%,可以使用和偶数分频一样的方法,使用计数器对分频系数N进行循环计数,然后根据占空比选择时钟跳变的计数。

对于要求占空比为50%的奇数分频电路,可以使用源时钟的双边沿特性对输出进行"与运算"或者"或运算"将占空比调整为50%。

或运算产生占空比为50%的奇数分频的verilog描述如下:

module odo_div_or
   (
    input rstn ,
    input clk,
    output clk_out
    );

    //定义分频系数
    parameter N = 3;
    reg ckl_p_r;
    reg clk_n_r;

   //计数器
   reg [3:0] cnt ;
   always @(posedge clk or negedge rstn) begin
      if (!rstn) begin
         cnt <= 'b0 ;
      end
      else if (cnt == N-1) begin
         cnt <= 'b0 ;
      end
      else begin
         cnt <= cnt + 1'b1 ;
      end
   end

   //在上升沿产生N分频
   always @(posedge clk or negedge rstn) begin
      if (!rstn) begin
         ckl_p_r <= 1'b0 ;
      end
      else if (cnt == N/2-1 ) begin 
        ckl_p_r <= 0 ;
      end
      else if (cnt == N-1) begin
        ckl_p_r <= 1 ;
      end
   end
 
   //在下降沿产生N分频
   always @(negedge clk or negedge rstn) begin
      if (!rstn) begin
         clk_n_r <= 1'b0 ;
      end
      else if (cnt == N/2 -1 ) begin
        clk_n_r <= 0 ;
      end
      else if (cnt == N-1) begin
        clk_n_r <= 1 ;
      end
   end

   assign clk_div9 = clk_p_r | clk_n_r ;

endmodule

与运算产生占空比为50%的奇数分频的verilog描述如下:

module odo_div_and
   (
    input rstn ,
    input clk,
    output clk_out
    );

    //定义分频系数
    parameter N = 3;
    reg ckl_p_r;
    reg clk_n_r;

   //计数器
   reg [3:0] cnt ;
   always @(posedge clk or negedge rstn) begin
      if (!rstn) begin
         cnt <= 'b0 ;
      end
      else if (cnt == N-1) begin
         cnt <= 'b0 ;
      end
      else begin
         cnt <= cnt + 1'b1 ;
      end
   end

   //在上升沿产生N分频
   always @(posedge clk or negedge rstn) begin
      if (!rstn) begin
         ckl_p_r <= 1'b0 ;
      end
      else if (cnt == N/2 ) begin 
        ckl_p_r <= 0 ;
      end
      else if (cnt == N-1) begin
        ckl_p_r <= 1 ;
      end
   end
 
   //在下降沿产生N分频
   always @(negedge clk or negedge rstn) begin
      if (!rstn) begin
         clk_n_r <= 1'b0 ;
      end
      else if (cnt == N/2 ) begin
        clk_n_r <= 0 ;
      end
      else if (cnt == N-1) begin
        clk_n_r <= 1 ;
      end
   end

   assign clk_div9 = clk_p_r & clk_n_r ;

endmodule

3、小数分频

小数分频又可以分为半整数分频和不规则的小数分频,可以利用时钟的双边沿可以对占空比进行调整。但是无论怎么调整,输出时钟的占空比不可能是50%。

常用的小数分频方式有双模前置小数分频和脉冲删除小数分频。

双模前置分频:

假设设计一个36/8的小数分频电路,其实就是在36个周期的clk_in内输出8个周期的clk_out。36/8等于4点多,因为需要四分频和五分频交叉。

假设4分频需要a个周期,五分频需要b个周期

即a+b=8,4*a+5*b=36。可解得a=4,b=4。

具体输出的方式可以先输出四个四分频,然后输出四个五分频;也可以四分频和五分频交叉输出。交叉输出的方式有着更小的时钟抖动。

脉冲删除法分频: 

通过计数,来删除一些不需要的脉冲即脉冲删除法。

假设设计一个36/8的小数分频电路,其实就是在36个周期的clk_in内输出8个周期的clk_out。我们在36个周期的clk_in中删除28个脉冲,这样就输出8个周期的clk_out。

你可能感兴趣的:(FPGA开发,fpga开发)