0
点赞
收藏
分享

微信扫一扫

FPGA 时钟分频技术 %50占空比

吴wuwu 2022-04-06 阅读 102

在FPGA设计过程中,分频技术常应用域产生时钟,较与锁相环技术而言,更省逻辑,但不适合高频率的分频,因为时序逻辑需满足setup/hold要求。FPGA分频技术通常划分为偶数分频、奇数分频、半整数分频以及任意小数分频。

1、偶数分频

(1)偶数分频是属于对称分频,即把src_clk降为它的1/2, 1/4, 1/6, ... ... 1/2n,实现timing图如下:

(2)设计原理:

        偶数分频:N = 2, 4, 6, 8 ...,对应的cnt_step = N/2,计数器范围:0 ~ N-1

        当cnt==0时,时钟为高,即out_clk1 <= 1'b1;

        当cnt==cnt_step,时钟翻转,即out_clk <= ~out_clk

2、奇数分频

(1)奇数分频属于非对称分频,其实就是按半个时钟周期的偶数分频,分别对其上升沿和下降沿进行N+1分频操作,然后再取与。

例如将src_clk降为它的1/3, 1/5 1/7, ... ... 1/2n-1,实现timing图如下:

(2)设计原理:

        偶数分频:N = 3, 5, 7 ...,对应的cnt_step = (N+1)/2,计数器范围:0 ~ N-1

        当cnt==0时,时钟为高,即out_clk1 <= 1'b1;

        当cnt==cnt_step,时钟翻转,即out_clk <= ~out_clk

3、半整数分频

(1)半整数分频就是按1.5, 2.5, 3.5 ....的数值进行分频,对应的N = 1, 2, 3 ....,故可以理解为对2*N的奇数分频,实现timing图如下:

(2)设计原理:

        半整数分频:1.5, 2.5, 3.5 ....,N = 1, 2, 3 ...,对应的cnt_step = N+1,计数器范围:0 ~ 2*N

        当cnt==0时,时钟为高,即out_clk1 <= 1'b1;

        当cnt==cnt_step,时钟翻转,即out_clk <= ~out_clk

4、任意小数

(1)任意小数分频,实现对rate = 输入频率/输出频率 的有效循环数的分频,这种使用较少,请参考:FPGA奇数和偶数分频器和半整数及任意小数分频器设计(Verilog程序) (renrendoc.com)

5、verilog 代码:

//even divider frequency
always @(posedge src_clk or negedge rst_n) begin //0 ~ CNT_MAX counter
  if(~rst_n) 
    cnt <= {DIV_W{1'b0}};
  else if(cnt >= CNT_MAX)
    cnt <= {DIV_W{1'b0}};
  else
    cnt <= cnt + 1'b1;	  
end
always @(posedge src_clk or negedge rst_n) begin //posedge simple
  if(~rst_n)
    reg_clk <= 1'b0;
  else if(cnt == 0)
    reg_clk <= 1'b1;
  else if(cnt == CNT_STEP)
    pos_clk <= ~pos_clk;
end
assign out_clk = reg_clk; //output clock


//odd or half integer divider frequency

always @(posedge src_clk or negedge rst_n) begin //0 ~ CNT_MAX counter
  if(~rst_n) 
    cnt <= {DIV_W{1'b0}};
  else if(cnt >= CNT_MAX)
    cnt <= {DIV_W{1'b0}};
  else
    cnt <= cnt + 1'b1;	  
end
always @(posedge src_clk or negedge rst_n) begin //posedge simple
  if(~rst_n)
    pos_clk <= 1'b0;
  else if(cnt == 0)
    pos_clk <= 1'b1;
  else if(cnt == CNT_STEP)
    pos_clk <= ~pos_clk;
end
always @(negedge src_clk or negedge rst_n) begin //negedge simple
  if(~rst_n)
    neg_clk <= 1'b0;
  else if(cnt == 0)
    neg_clk <= 1'b0;
  else if(cnt == CNT_STEP)
    neg_clk <= ~neg_clk;
end
assign out_clk = pos_clk | neg_clk; //output clock
举报

相关推荐

0 条评论