用Bresenham算法在FPGA上实现小数分频器

最近朋友问了一个问题,输入时钟是33MHz,要分出一路2.048MHz的时钟来,要求相位抖动尽可能小。我想到可以用计算机图形学中绘制直线的Bresenham算法来解决,获得成功。

输入时钟是33000kHz,输出时钟是2048kHz,好比从原点画一条到(33000,2048)的直线,用输入时钟驱动画笔在 x 方向的运动,那么对应的 y 方向的运动就是输出时钟。

Verilog代码如下:

module  divider(clk_in, clk_out, nrst);
  input  clk_in,  nrst;
  output clk_out;
  reg    clk_out;

  parameter input_freq = 33000;   // both in kHz
  parameter output_freq = 2048;
 
  reg[16:0] err;          // change to 18 bits if necessary, look down
 
  always @(posedge clk_in or negedge nrst)
  begin
    if (nrst == 1'b0) begin
      clk_out <= 1'b0;
      err <= (output_freq << 2) - input_freq;
    end
    else begin
      if (err[16] == 1'b0) begin  // also change here !!! (if change the former)
        err <= err - (input_freq << 1) + (output_freq << 2);
        clk_out <= !clk_out;
      end
      else begin
        err <= err + (output_freq << 2);
      end
    end
  end
 
endmodule

这是一个同步时序电路,在 clk_in 的每个上升沿判断 clk_out 是否翻转,设 clk_in 的周期是T,
那么 clk_out  的边沿抖动小于T。



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=549965


你可能感兴趣的:(用Bresenham算法在FPGA上实现小数分频器)