• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

任意分频器电路设计

武飞扬头像
OliverH-yishuihan
帮助4

目录

任意分频器电路设计

1、任意偶数分频器电路设计

1.2、实验任务

1.3、程序设计

1.3.1、代码如下:

1.3.2、编写仿真 TB 文件

2、任意奇数分频器电路设计

2.1、实验任务

2.2、程序设计

2.2.1、奇数分频电路代码

2.2.2、编写仿真 TB 文件

2.2.3、仿真验证


任意分频器电路设计

1、任意偶数分频器电路设计

       偶数分频实现比较简单,假设为 N(偶数)分频,只需计数到 N/2-1,然后时钟翻转、计数器清零,如此循环就可以得到 N(偶)分频。举个例子,比如晶振时钟是 100Mhz 时钟,想得到一个 25Mhz 的时钟, 那么这个是一个 100/25=4 的四分频设计,那么按照我们刚说的计数到 4/2-1=1,然后时钟翻转、计数器清零, 就可以得到一个 24Mhz 的时钟。

1.2、实验任务

使用 Verilog 语言设计一个任意偶数分频电路,默认进行 4 分频。

1.3、程序设计

       根据简介介绍的分频电路设计思路,假设为 N(偶数)分频,只需计数到 N/2-1,然后时钟翻转、计数清零,如此循环就可以得到 N(偶)分频,可以通过改变参量 N 的值和计数变量 cnt 的位宽实现任意偶分频,由于默认为 4 分频,因此 N 初始值为 4。我们由此可以写出如下代码。

1.3.1、代码如下:

  1.  
    //********************************************
  2.  
    module divide_2
  3.  
    (
  4.  
    input clk , // system clock 50Mhz on board
  5.  
    input rst_n, // system rst, low active
  6.  
    output reg out_clk // output signal
  7.  
    );
  8.  
     
  9.  
    parameter N = 4 ;
  10.  
     
  11.  
    reg [N/2-1:0] cnt ;
  12.  
     
  13.  
    //===============================================================
  14.  
    // ------------------------- MAIN CODE -------------------------
  15.  
    //===============================================================
  16.  
    always @ (posedge clk or negedge rst_n) begin
  17.  
    if(!rst_n) begin
  18.  
    cnt <= 0;
  19.  
    out_clk <= 0;
  20.  
    end
  21.  
    else begin
  22.  
    if(cnt==N/2-1) begin
  23.  
    out_clk <= ~out_clk;
  24.  
    cnt <= 0;
  25.  
    end
  26.  
    else
  27.  
    cnt <= cnt 1;
  28.  
    end
  29.  
    end
  30.  
     
  31.  
    endmodule
学新通

1.3.2、编写仿真 TB 文件

      只需要对时钟以及复位信号进行激励,代码编写如下:

  1.  
    //*************TB****************
  2.  
    `timescale 1ns / 1ps
  3.  
     
  4.  
    module TB();
  5.  
     
  6.  
    reg sys_clk ;
  7.  
    reg sys_rst_n;
  8.  
    wire out_clk ;
  9.  
     
  10.  
    initial begin
  11.  
    sys_clk = 1'b0;
  12.  
    sys_rst_n = 1'b0;
  13.  
    #200
  14.  
    sys_rst_n = 1'b1;
  15.  
    end
  16.  
     
  17.  
    always #10 sys_clk = ~sys_clk;
  18.  
     
  19.  
    divide_2 u_divide_2(
  20.  
    .clk (sys_clk ),
  21.  
    .rst_n (sys_rst_n ),
  22.  
    .out_clk (out_clk )
  23.  
    );
  24.  
     
  25.  
    endmodule
  26.  
     
学新通

运行后的波形如下显示:

学新通

      可以看出,N 初始为 4,当复位撤销(复位信号低有效)之后,cnt 即开始计数,在计数器计到 1 的时候,out_clk 进行取反操作,即得到一个四分频时钟,大家可以改变 N 参数看下,看下 N 参数不一样,最终分频的时钟是多少。

2、任意奇数分频器电路设计

       有偶数分频就有奇数分频,仅实现分频功能来讲其中的差别和实现方式还是很大的,奇数分频相对于偶数分频要复杂一些,并不是简单的用计数器计数就可以实现的。

       奇数分频,顾名思义,是说分频后的频率和分频前的频率比例是奇数,比如 100Mhz 时钟,进行三分频后,就是 33.33Mhz。

       实现奇数分频原理是分别用上升沿计数到 N/2 1,分频后输出时钟进行翻转,再计数到 N/2 输出 out_clk1,再用下降沿计数到 N/2 1,分频后输出时钟再进行翻转,再计数到 N/2 输出out_clk2,将 out_clk1 和 out_clk2 相或即可。我们可以通过修改 N 的值和计数器的位宽来实现其他奇数分频。 其实 out_clk1 和 out_clk2 都已经是奇数分频的时钟,只不过占空比不是 50%。

      下面在进行奇数分频设计之前,我们先来了解下占空比的概念。占空比指的是时钟信号在一个周期内高电平和低电平的比例。如下是一个 50%占空比的一个时钟波形。

学新通

如下是一个 30%占空比的一个时钟波形。

学新通

       一般高质量的时钟信号都是要求有 50%占空比的,50%占空比的时钟信号对时序分析是非常有好处的。

2.1、实验任务

使用 Verilog 语言设计一个任意奇数分频电路,默认进行 3 分频,要求输出时钟的占空比是50%。

2.2、程序设计

       根据简介介绍的奇数分频电路设计思路,我们需要新增两个计数器,cnt_1 和 cnt_2。初始化 cnt_1 和 cnt_2 为 1,out_clk1 为 0,out_clk2 为 0。

       当 out_clk1 0 时,cnt_1 在 clk 时钟上升沿进行计数,当计数到 N/2 1 out_clk1 进行翻转,同时 cnt_1 赋值为初始值 1out_clk1 1 时,cnt_1 在 clk 时钟上升沿进行计数,当计数到 N/2 时 out_clk1 进行翻转,同时 cnt_1 赋值为初始值 1。

       当 out_clk2 0 时,cnt_2 在 clk 时钟下降沿进行计数,当计数到 N/2 1 out_clk2 进行翻转,同时 cnt_2 赋值为初始值 1out_clk2 1 时,cnt_2 在 clk 时钟下降沿进行计数,当计数到 N/2 时 out_clk2 进行翻转,同时 cnt_2 赋值为初始值 1。

       这样 N(奇数)分频就可以通过改变参量 N 的值和计数变量 cnt 的位宽实现任意奇数分频,由于默认为 3 分频,因此 N 初始值为 3。3 分频的 cnt_1 和 cnt_2 计数到 N/2 1 是计数到 2,小数舍弃掉, cnt_1 和 cnt_2 计数到 N/2 是计数到 1

我们由此可以写出如下代码。

2.2.1、奇数分频电路代码

  1.  
     
  2.  
    //**********任意奇数分频*******START***************************
  3.  
    module divide_3
  4.  
    (
  5.  
    input clk, // system clock 50Mhz on board
  6.  
    input rst_n, // system rst, low active
  7.  
    output out_clk // output signal
  8.  
    );
  9.  
     
  10.  
    parameter N = 3 ;
  11.  
     
  12.  
    reg [N/2 :0] cnt_1;
  13.  
    reg [N/2 :0] cnt_2;
  14.  
     
  15.  
    reg out_clk1;
  16.  
    reg out_clk2;
  17.  
     
  18.  
    //=====================================================================
  19.  
    // ------------------------- MAIN CODE -------------------------------
  20.  
    //=====================================================================
  21.  
    always @(posedge clk or negedge rst_n) begin //上升沿输出 out_clk1
  22.  
    if(!rst_n) begin
  23.  
    out_clk1 <= 0;
  24.  
    cnt_1 <= 1; //这里计数器从 1 开始
  25.  
    end
  26.  
    else begin
  27.  
    if(out_clk1 == 0) begin
  28.  
    if(cnt_1 == N/2 1) begin
  29.  
    out_clk1 <= ~out_clk1;
  30.  
    cnt_1 <= 1;
  31.  
    end
  32.  
    else
  33.  
    cnt_1 <= cnt_1 1;
  34.  
    end
  35.  
    else if(cnt_1 == N/2) begin
  36.  
    out_clk1 <= ~out_clk1;
  37.  
    cnt_1 <= 1;
  38.  
    end
  39.  
    else
  40.  
    cnt_1 <= cnt_1 1;
  41.  
    end
  42.  
    end
  43.  
     
  44.  
    always @(negedge clk or negedge rst_n) begin //下降沿输出 out_clk2
  45.  
    if(!rst_n) begin
  46.  
    out_clk2 <= 0;
  47.  
    cnt_2 <= 1; //这里计数器从 1 开始
  48.  
    end
  49.  
    else begin
  50.  
    if(out_clk2 == 0) begin
  51.  
    if(cnt_2 == N/2 1) begin
  52.  
    out_clk2 <= ~out_clk2;
  53.  
    cnt_2 <= 1;
  54.  
    end
  55.  
    else
  56.  
    cnt_2 <= cnt_2 1;
  57.  
    end
  58.  
    else if(cnt_2 == N/2) begin
  59.  
    out_clk2 <= ~out_clk2;
  60.  
    cnt_2 <= 1;
  61.  
    end
  62.  
    else
  63.  
    cnt_2 <= cnt_2 1;
  64.  
    end
  65.  
    end
  66.  
     
  67.  
    assign out_clk = out_clk1 | out_clk2;
  68.  
     
  69.  
    endmodule
学新通

     使用 Vivado 综合后也可以看到电路结构,在 RTL ANALYSIS 的 Schematic 中来看下综合的电路结构。

       可以看出,cnt_1 和 cnt_2 是一个 3bit 的计数器,out_clk1 和 out_clk2 的电路结构基本是完全相同的,只是 cnt_1 和 cnt_2 计数器变化的时钟沿不一样,大家可以看出 cnt_2 的寄存器的 clk 前面有一个取反的标记,表示 cnt_2 是在时钟下降沿进行变化,然后 out_clk1 和 out_clk2 进行或操作,即得到一个 50%占空比的奇数 3 分频时钟。

2.2.2、编写仿真 TB 文件

      只需要对时钟以及复位信号进行激励,代码编写如下:

  1.  
    `timescale 1ns / 1ps
  2.  
    //
  3.  
     
  4.  
     
  5.  
    module tb_divider_3(); //仿真模块
  6.  
     
  7.  
    //输入 reg 定义
  8.  
    reg sys_clk;
  9.  
    reg sys_rst_n;
  10.  
     
  11.  
    //输出 wire 定义
  12.  
    wire out_clk;
  13.  
     
  14.  
    //设置初始化条件
  15.  
    initial begin
  16.  
    sys_clk = 1'b0; //初始化时钟为0
  17.  
    sys_rst_n <= 1'b0; //初始复位
  18.  
    #200 //200个时间单位后
  19.  
    sys_rst_n <= 1'b1; //拉高复位
  20.  
    end
  21.  
     
  22.  
    always #10 sys_clk = ~sys_clk;
  23.  
     
  24.  
     
  25.  
    //例化被测试模块
  26.  
    divider_3 u_divider_3
  27.  
    (
  28.  
    .sys_clk (sys_clk ),
  29.  
    .sys_rst_n (sys_rst_n ),
  30.  
     
  31.  
    .out_clk (out_clk )
  32.  
    );
  33.  
     
  34.  
    endmodule
  35.  
     
学新通

2.2.3、仿真验证

       测试程序在 Xilinx 的 Vivado 软件 或者其他仿真工具运行后的波形如下显示:

学新通

        可以看出,N 初始为 3,当复位撤销(复位信号低有效)之后,cnt_1 cnt_2 即开始计数, 当 out_clk1 0 时,在 cnt_1 计数器计到 2 的时候,out_clk1 进行取反操作,当 out_clk1 1 时,在 cnt_1 计数器计到 1 的时候,out_clk1 进行取反操作。

       当 out_clk2 0 时,在 cnt_2 计数器计到 2 的时候,out_clk2 进行取反操作,当 out_clk2 1 时,在 cnt_2 计数器计到 1 的时候,out_clk2 进行取反操作。

       我们可以看出 out_clk1 和 out_clk2 都不是 50%占空比的时钟,大概是 30%占空比。然后 out_clk1 和 out_clk2 进行或操作,即得到一个 50%占空比的奇数 3 分频时钟。

大家可以改变 N 参数看下,看下 N 参数不一样,最终分频的时钟是多少。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhffgegi
系列文章
更多 icon
同类精品
更多 icon
继续加载