zoukankan      html  css  js  c++  java
  • 基于FPGA的任意分频实现

    一、引言

      在数字逻辑电路设计中,分频器是一种基本的电路单元。通常用来对某个给定频率进行分频,以得到我们想要的频率。在FPGA中,我们一般都是通过计数器来实现分频,分频得到的时钟质量没有通过PLL得到的时钟质量好,用于对时钟信号要求较高的逻辑设计中,还是用PLL分频比较好。下面将详细介绍任意偶数分频,奇数分频,小数分频。

    二、偶数分频

      以四分频为例,假设系统时钟频率为 50MHz,那么周期为 20ns,四分频之后得到的时钟频率为 12.5MHz,时钟周期为 80ns。在50MHz的系统时钟的驱动下,计数器要在计数到  40 ns ,输出时钟翻转,计数到40 ns时,计数器的值为1,刚好计数两下。

      代码如下:

     1 // *********************************************************************************
     2 // Project Name : even_divclk
     3 // Email            : 
     4 // Create Time   : 2020/07/07 9:59
     5 // Module Name  : even_divclk
     6 // editor        : qing
     7 // Version        : Rev1.0.0
     8 // Description  : 任意占空比为50%的偶数分频
     9 // *********************************************************************************
    10 
    11 module even_divclk(
    12     input                sclk                ,  // System clk 50MHz
    13     input                s_rst_n        ,
    14 
    15     output    reg         div_clk        
    16     );
    17 
    18 //========================================================================
    19 // =========== Define Parameter and Internal signals =========== 
    20 //========================================================================/
    21 
    22 // parameter         n    =                 ;
    23 parameter         n    =    4             ; // just for test
    24 
    25 reg            [19:0]        cnt         ;
    26 
    27 always @ (posedge sclk or negedge s_rst_n) begin  // cnt
    28         if(s_rst_n == 1'b0)
    29             cnt <= 0;
    30         else if(cnt == n/2 - 1)
    31             cnt <= 0;
    32         else
    33             cnt <= cnt + 1'b1; 
    34     end    
    35 
    36 always @ (posedge sclk or negedge s_rst_n) begin
    37     if(s_rst_n == 1'b0)
    38         div_clk <= 1'b0;
    39     else if(cnt == n/2 - 1)
    40         div_clk <= ~div_clk;
    41     else
    42         div_clk <= div_clk;    
    43 end
    44 
    45 endmodule
    View Code

      testbench:

     1 // *********************************************************************************
     2 // Project Name : even_divclk
     3 // Email        : 
     4 // Create Time  : 2020/07/07 10:10
     5 // Module Name  : even_divclk_tb
     6 // editor        : qing
     7 // Version        : Rev1.0.0
     8 // *********************************************************************************
     9 `timescale 1ns/1ps
    10 module even_divclk_tb;
    11     reg            sclk        ;
    12     reg         s_rst_n        ;
    13     wire        div_clk        ;
    14 
    15 even_divclk even_divclk_inst(
    16     .sclk    (sclk        ),
    17     .s_rst_n(s_rst_n    ),
    18     .div_clk(div_clk    )
    19     );
    20 
    21 initial
    22     sclk = 1'b0;
    23     always #10 sclk = ~sclk;
    24 
    25 initial
    26     begin
    27         #1;
    28         s_rst_n = 1'b0;
    29         #21;
    30         s_rst_n = 1'b1;
    31     end
    32 
    33 endmodule
    View Code

      Modelsim仿真结果:

       由图可见,达到预期目的。

    三、奇数分频

      奇数分频需要通过两个辅助时钟来生成,如上图所示,以占空比为 50% 的 5 分频为例,分频得到的信号 div_clk = clk_p | clk_n。

      假设分频系数为 n,那么 clk_p 在 在时钟信号的上升沿的驱动下第 (n - 1)/2 - 1 个时钟的上升沿翻转一次,在(n - 1)个时钟的上升沿的时候再翻转一次;clk_n 则是在时钟信号的下降沿的驱动下,在第(n - 1)/2 - 1个时钟的下降沿翻转一次,在( n - 1)个时钟的时候再翻转一次,将 clk_p 与 clk_n 做或运算得到 div_clk。

      下面是一个占空比为 50% 的5分频的例程。

     1 // *********************************************************************************
     2 // Project Name : odd_divclk
     3 // Email            : 
     4 // Create Time  : 2020/07/07 11:12
     5 // Module Name  : odd_divclk
     6 // editor        : qing
     7 // Version        : Rev1.0.0
     8 // Description    : 任意占空比为 50% 的奇数分频 
     9 // *********************************************************************************
    10 
    11 module odd_divclk(
    12     input                sclk        ,  // System clk 50MHz
    13     input                s_rst_n        ,
    14 
    15     output                div_clk        
    16     );
    17 //========================================================================
    18 // =========== Define Parameter and Internal signals =========== 
    19 //========================================================================/
    20 
    21 parameter         n =    5                ;
    22 
    23 reg            [19:0]        cnt1         ;
    24 reg            [19:0]        cnt2        ;
    25 reg                        clk_p        ;
    26 reg                         clk_n        ;        
    27 
    28 //=============================================================================
    29 //****************************     Main Code    *******************************
    30 //=============================================================================
    31 
    32 always @ (posedge sclk or negedge s_rst_n) begin  // cnt1
    33     if(s_rst_n == 1'b0)
    34         cnt1 <= 0;
    35     else if(cnt1 == n - 1)
    36         cnt1 <= 0;
    37     else
    38         cnt1 <= cnt1 + 1'b1;        
    39 end
    40 
    41 always @ (posedge sclk or negedge s_rst_n) begin  // cnt2
    42     if(s_rst_n == 1'b0)
    43         clk_p <= 1'b1;
    44     else if(cnt1 == (n-1)/2-1)    
    45         clk_p <= ~clk_p;
    46     else if(cnt1 == (n-1))
    47         clk_p <= ~clk_p;
    48 end
    49 
    50 always @ (negedge sclk or negedge s_rst_n) begin  // cnt2
    51     if(s_rst_n == 1'b0)
    52         cnt2 <= 0;
    53     else if(cnt2 == n - 1)
    54         cnt2 <= 0;
    55     else
    56         cnt2 <= cnt2 + 1'b1;        
    57 end
    58 
    59 always @ (negedge sclk or negedge s_rst_n) begin  // cnt2
    60     if(s_rst_n == 1'b0)
    61         clk_n <= 1'b1;
    62     else if(cnt2 == (n-1)/2-1)    
    63         clk_n <= ~clk_n;
    64     else if(cnt2 == n - 1)
    65         clk_n <= ~clk_n;
    66 end
    67 
    68 assign div_clk = clk_p | clk_n;
    69 
    70 endmodule    
    View Code

      testbench

     1 // *********************************************************************************
     2 // Project Name : even_divclk
     3 // Email        : 
     4 // Create Time  : 2020/07/07 10:10
     5 // Module Name  : even_divclk_tb
     6 // editor        : qing
     7 // Version        : Rev1.0.0
     8 // *********************************************************************************
     9 `timescale 1ns/1ps
    10 module even_divclk_tb;
    11     reg            sclk        ;
    12     reg         s_rst_n        ;
    13     wire        div_clk        ;
    14 
    15 odd_divclk odd_divclk_inst(
    16     .sclk    (sclk        ),
    17     .s_rst_n(s_rst_n    ),
    18     .div_clk(div_clk    )
    19     );
    20 
    21 initial
    22     sclk = 1'b0;
    23     always #10 sclk = ~sclk;
    24 
    25 initial
    26     begin
    27         #1;
    28         s_rst_n = 1'b0;
    29         #21;
    30         s_rst_n = 1'b1;
    31     end
    32 
    33 endmodule
    View Code

      Modelsim仿真结果

    四、小数分频

      未完待续······

  • 相关阅读:
    git
    sublime text
    WIX安装图文并茂简易说明
    C#利用Lambda和Expression实现数据的动态绑定
    Ubuntu/CentOS下如何将普通用户提升到root权限
    虚拟机安装CentOS6.4用“桥接:直接连接到物理网线”不能上网的原因及解决方法
    C#利用lambda表达式将函数作为参数或属性跨类传递
    直接将XML存入到SQL中(SQL2008)
    C# 类中继承接口的属性
    提高开发效率的Visual Studio 2010使用技巧
  • 原文地址:https://www.cnblogs.com/571328401-/p/13259368.html
Copyright © 2011-2022 走看看