0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看威廉希尔官方网站 视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Verilog时钟分频知识总结

冬至子 来源:数字IC与好好生活的两居室 作者:除夕之夜啊 2023-05-30 17:21 次阅读

偶数分频

采用触发器反向输出端连接到输入端的方式,可构成简单的 2 分频电路。

以此为基础进行级联,可构成 4 分频,8 分频电路。

电路实现如下图所示,用 Verilog 描述时只需使用简单的取反逻辑即可。

图片

如果偶数分频系数过大,就需要使用对分频系数 N 循环计算的方法进行分频。在计数达到分频系数中间数值 N/2 时进行时钟翻转,可保证分频后时钟的占空比为 50%。因为是偶数分频,也可以对分频系数中间数值 N/2 进行循环计数。

两种偶数分频的 Verilog 描述如下。

module even_divisor
  # (parameter DIV_CLK = 10 )
    (
    input               rstn ,
    input               clk,
    output              clk_div2,
    output              clk_div4,
    output              clk_div10
    );


   //2 分频
   reg                  clk_div2_r ;
   always @(posedge clk or negedge rstn) begin
      if (!rstn) begin
         clk_div2_r     <= 'b0 ;
      end
      else begin
         clk_div2_r     <= ~clk_div2_r ;
      end
   end
   assign       clk_div2 = clk_div2_r ;


   //4 分频
   reg                  clk_div4_r ;
   always @(posedge clk_div2 or negedge rstn) begin
      if (!rstn) begin
         clk_div4_r     <= 'b0 ;
      end
      else begin
         clk_div4_r     <= ~clk_div4_r ;
      end
   end
   assign clk_div4      = clk_div4_r ;


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


   //输出时钟
   reg                  clk_div10_r ;
   always @(posedge clk or negedge rstn) begin
      if (!rstn) begin
         clk_div10_r <= 1'b0 ;
      end
      else if (cnt == (DIV_CLK/2)-1 ) begin
         clk_div10_r <= ~clk_div10_r ;
      end
   end
   assign clk_div10 = clk_div10_r ;
endmodule

testbench 中只需给入激励时钟等信号即可,这里不再列出。

仿真结果如下。

图片


奇数分频

奇数分频如果不要求占空比为 50%,可按照偶数分频的方法进行分频。即计数器对分频系数 N 进行循环计算,然后根据计数值选择一定的占空比输出。

如果奇数分频输出时钟的高低电平只差一个 cycle ,则可以利用源时钟双边沿特性并采用“与操作”或“或操作”的方式将分频占空比调整到 50%。

◆或操作调整占空比

采用“或操作”产生占空比为 50% 的 3 分频时序图如下所示。

利用源时钟上升沿分频出高电平为 1 个 cycle、低电平为 2 个 cycle 的 3 分频时钟。

利用源时钟下降沿分频出高电平为 1 个 cycle、低电平为 2 个 cycle 的 3 分拼时钟。

两个 3 分频时钟应该在计数器相同数值、不同边沿下产生,相位差为一个时钟周期。然后将 2 个时钟进行“或操作”,便可以得到占空比为 50% 的 3 分频时钟。

图片

同理,9 分频时,则需要在上升沿和下降沿分别产生 4 个高电平、5 个低电平的 9 分频时钟,然后再对两个时钟做“或操作”即可。Verilog 描述如下。

module odo_div_or
  #(parameter DIV_CLK = 9)
   (
    input               rstn ,
    input               clk,
    output              clk_div9
    )


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


   //在上升沿产生9分频
   reg                  clkp_div9_r ;
   always @(posedge clk or negedge rstn) begin
      if (!rstn) begin
         clkp_div9_r <= 1'b0 ;
      end
      else if (cnt == (DIV_CLK>>1)-1 ) begin //计数4-8位低电平
        clkp_div9_r <= 0 ;
      end
      else if (cnt == DIV_CLK-1) begin //计数 0-3 为高电平
        clkp_div9_r <= 1 ;
      end
   end

   //在下降沿产生9分频
   reg                  clkn_div9_r ;
   always @(negedge clk or negedge rstn) begin
      if (!rstn) begin
         clkn_div9_r <= 1'b0 ;
      end
      else if (cnt == (DIV_CLK>>1)-1 ) begin 
        clkn_div9_r <= 0 ;
      end
      else if (cnt == DIV_CLK-1) begin 
        clkn_div9_r <= 1 ;
      end
   end


   //或操作,往往使用基本逻辑单元库
   // or (clk_div9, clkp_div9_r, clkn_div9_r) ;
   assign clk_div9 = clkp_div9_r | clkn_div9_r ;


endmodule

仿真结果如下。

图片

◆与操作调整占空比

采用“与操作”产生占空比为 50% 的 3 分频时序图如下所示。

利用源时钟上升沿分频出高电平为 2 个 cycle、低电平为 1 个 cycle 的 3 分频时钟。

利用源时钟下降沿分频出高电平为 2 个 cycle、低电平为 1 个 cycle 的 3 分拼时钟。

两个 3 分频时钟应该在计数器相同数值、不同边沿下产生,相位差为一个时钟周期。然后将 2 个时钟进行“与操作”,便可以得到占空比为 50% 的 3 分频时钟。

图片

同理,9 分频时,则需要在上升沿和下降沿分别产生 5 个高电平、4 个低电平的 9 分频时钟,然后再对两个时钟做“与操作”即可。Verilog 描述如下。

module odo_div_and
   #( parameter DIV_CLK = 9 )
   (
    input               rstn ,
    input               clk,
    output              clk_div9
    );


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


   //在上升沿产生9分频
   reg                  clkp_div9_r ;
   always @(posedge clk or negedge rstn) begin
      if (!rstn) begin
         clkp_div9_r <= 1'b0 ;
      end
      else if (cnt == (DIV_CLK>>1) ) begin //计数5-8位低电平
        clkp_div9_r <= 0 ;
      end
      else if (cnt == DIV_CLK-1) begin //计数 0-4 为高电平
        clkp_div9_r <= 1 ;
      end
   end


   //在下降沿产生9分频
   reg                  clkn_div9_r ;
   always @(negedge clk or negedge rstn) begin
      if (!rstn) begin
         clkn_div9_r <= 1'b0 ;
      end
      else if (cnt == (DIV_CLK>>1) ) begin 
        clkn_div9_r <= 0 ;
      end
      else if (cnt == DIV_CLK-1) begin 
        clkn_div9_r <= 1 ;
      end
   end


   //与操作,往往使用基本逻辑单元库
   //and (clk_div9, clkp_div9_r, clkn_div9_r) ;
   assign clk_div9 = clkp_div9_r & clkn_div9_r ;


endmodule

仿真结果如下。

图片


半整数分频

利用时钟的双边沿逻辑,可以对时钟进行半整数的分频,但是无论再怎么调整,半整数分频的占空比不可能是 50%。半整数分频的方法有很多,这里只介绍一种和计数分频调整占空比类似的方法。

(1) 例如进行 3.5 倍分频时,计数器循环计数到 7,分别产生 4 个和 3 个源时钟周期的分频时钟。从 7 个源时钟产生了 2 个分频时钟的角度来看,该过程完成了 3.5 倍的分频,但是每个分频时钟并不是严格的 3.5 倍分频。

(2) 下面对周期不均匀的分频时钟进行调整。一次循环计数中,在源时钟下降沿分别产生 4 个和 3 个源时钟周期的分频时钟。相对于第一次产生的 2 个周期不均匀的时钟,本次产生的 2 个时钟相位一个延迟半个源时钟周期,一个提前半个源时钟周期。

(3) 将两次产生的时钟进行“或操作”,便可以得到周期均匀的 3.5 倍分频时钟。分频波形示意图如下所示。

图片

3.5 倍时钟分频的 Verilog 描述如下。

module half_divisor(
    input               rstn ,
    input               clk,
    output              clk_div3p5
    );


   //计数器
   parameter            MUL2_DIV_CLK = 7 ;
   reg [3:0]            cnt ;
   always @(posedge clk or negedge rstn) begin
      if (!rstn) begin
         cnt    <= 'b0 ;
      end
      else if (cnt == MUL2_DIV_CLK-1) begin //计数2倍分频比
         cnt    <= 'b0 ;
      end
      else begin
         cnt    <= cnt + 1'b1 ;
      end
   end


   reg                  clk_ave_r ;
   always @(posedge clk or negedge rstn) begin
      if (!rstn) begin
         clk_ave_r <= 1'b0 ;
      end
      //first cycle: 4 source clk cycle
      else if (cnt == 0) begin
         clk_ave_r <= 1 ;
      end
      //2nd cycle: 3 source clk cycle
      else if (cnt == (MUL2_DIV_CLK/2)+1) begin
         clk_ave_r <= 1 ;
      end
      else begin
         clk_ave_r <= 0 ;
      end
   end


   //adjust
   reg                  clk_adjust_r ;
   always @(negedge clk or negedge rstn) begin
      if (!rstn) begin
         clk_adjust_r <= 1'b0 ;
      end
      //本次时钟只为调整一致的占空比
      else if (cnt == 1) begin
         clk_adjust_r <= 1 ;
      end
      //本次时钟只为调整一致的精确分频比
      else if (cnt == (MUL2_DIV_CLK/2)+1 ) begin
         clk_adjust_r <= 1 ;
      end
      else begin
         clk_adjust_r <= 0 ;
      end
   end


   assign clk_div3p5 = clk_adjust_r | clk_ave_r ;
endmodule

仿真结果如下。

图片


小数分频

◆基本原理

不规整的小数分频不能做到分频后的每个时钟周期都是源时钟周期的小数分频倍,更不能做到分频后的时钟占空比均为 50%,因为 Verilog 不能对时钟进行小数计数。和半整数分频中第一次分频时引入的“平均频率”概念类似,小数分频也是基于可变分频和多次平均的方法实现的。

例如进行 7.6 倍分频,则保证源时钟 76 个周期的时间等于分频时钟 10 个周期的时间即可。此时需要在 76 个源时钟周期内进行 6 次 8 分频,4 次 7 分频。再例如进行 5.76 分频,需要在 576 个源时钟周期内进行 76 次 6 分频,24 次 5 分频。

下面阐述下这些分频参数的计算过程。

当进行 7 分频时,可以理解为 70 个源时钟周期内进行 10 次 7 分频。在 76 个源时钟周期内仍然进行 10 次分频,相当于将多余的 6 个源时钟周期增加、分配到 70 个源时钟周期内,即完成了 7.6 倍分频操作。分频过程中必然有 6 个分频时钟是 8 分频得到的,剩下的 4 个分频时钟则仍然会保持原有的 7 分频状态。

很多地方给出了计算这些分频参数的两元一次方程组,如下所示。其原理和上述分析一致,建议掌握上述计算过程。

7N + 8M = 76

N + M = 10

其中 7 为整数分频,N 整数分频的次数;8 与 M 为整数加一的分频系数及其分频次数。

◆平均原理

以 7.6 倍分频为例,7 分频和 8 分频的实现顺序一般有以下 4 种:

(1) 先进行 4 次 7 分频,再进行 6 次 8 分频;

(2) 先进行 6 次 8 分频,再进行 4 次 7 分频;

(3) 将 4 次 7 分频平均的插入到 6 次 8 分频中;

(4) 将 6 次 8 分频平均的插入到 4 次 7 分频中。

前两种方法时钟频率不均匀,相位抖动较大,所以一般会采用后两种平均插入的方法进行小数分频操作。

平均插入可以通过分频次数差累计的方法实现,7.6 分频的实现过程如下:

(1) 第一次分频次数差值为 76-10*7 = 6 < 10,第一次进行 7 分频。

(2) 第二次差值累积结果为 6+6=12 > 10,第二次使用 8 分频,同时差值修改为 12-10=2。

(3) 第三次差值累积结果为 2+6=8 < 10,第三次使用 6 分频。

(3) 第四次差值累积结果为 8+6=14 > 10,第四次使用 8 分频,差值修改为 14-10=4。

以此类推,完成将 6 次 8 分频平均插入到 4 次 7 分频的过程。

下表展示了平均插入法的分频过程。

1.jpg

◆设计仿真

基于上述分析实现方法的 Verilog 描述如下。

module frac_divisor
  #(
   parameter            SOURCE_NUM = 76 , //cycles in source clock
   parameter            DEST_NUM   = 10  //cycles in destination clock
   )
   (
    input               rstn ,
    input               clk,
    output              clk_frac
    );

   //7分频参数、8分频参数、次数差值
   parameter    SOURCE_DIV = SOURCE_NUM/DEST_NUM ; 
   parameter    DEST_DIV   = SOURCE_DIV + 1; 
   parameter    DIFF_ACC   = SOURCE_NUM - SOURCE_DIV*DEST_NUM ;


   reg [3:0]            cnt_end_r ;  //可变分频周期
   reg [3:0]            main_cnt ;   //主计数器
   reg                  clk_frac_r ; //时钟输出,高电平周期数为1
   always @(posedge clk or negedge rstn) begin
      if (!rstn) begin
         main_cnt    <= 'b0 ;
         clk_frac_r  <= 1'b0 ;
      end
      else if (main_cnt == cnt_end_r) begin
         main_cnt    <= 'b0 ;
         clk_frac_r  <= 1'b1 ;
      end
      else begin
         main_cnt    <= main_cnt + 1'b1 ;
         clk_frac_r  <= 1'b0 ;
      end
   end
   //输出时钟
   assign       clk_frac        = clk_frac_r ;
   //差值累加器使能控制
   wire         diff_cnt_en     = main_cnt == cnt_end_r ;


   //差值累加器逻辑
   reg [4:0]            diff_cnt_r ;
   wire [4:0]           diff_cnt = diff_cnt_r >= DEST_NUM ?
                                   diff_cnt_r -10 + DIFF_ACC : 
                                   diff_cnt_r + DIFF_ACC ;                                
   always @(posedge clk or negedge rstn) begin
      if (!rstn) begin
         diff_cnt_r <= 0 ;
      end
      else if (diff_cnt_en) begin
         diff_cnt_r <= diff_cnt ;
      end
   end


   //分频周期变量的控制逻辑
   always @(posedge clk or negedge rstn) begin
      if (!rstn) begin
         cnt_end_r      <= SOURCE_DIV-1 ;
      end
      //差值累加器溢出时,修改分频周期
      else if (diff_cnt >= 10) begin
         cnt_end_r      <= DEST_DIV-1 ;
      end
      else begin
         cnt_end_r      <= SOURCE_DIV-1 ;
      end
   end


endmodule

仿真结果如下。

图片


分频小结

◆偶数分频不使用时钟双边沿逻辑即可完成占空比为 50% 的时钟分频,是最理想的分频状况。

◆奇数分频如果要产生 50% 占空比的分频时钟,则需要使用时钟的双边沿逻辑。如果不要求占空比的话,实现方法和偶数分频类似。

◆半整数分频属于特殊的小数分频,可以用双边沿逻辑进行设计。通过一定逻辑将两个双边沿时钟信号整合为最后的一路输出时钟时,建议不要使用选择逻辑。因为容易出现毛刺现象,电路中又会增加一定的不确定性。例如下面描述是不建议的。

assign clk_div3p5 = (cnt == 1 || cnt ==2) ? clk_ave_r 
                                          : clk_adjust_r ;

◆小数分频的基本思想是,输出时钟在一段时间内的平均频率达到分频要求即可。但是考虑到相位抖动,还需要对可变的分频逻辑进行平均操作。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 逻辑电路
    +关注

    关注

    13

    文章

    494

    浏览量

    42614
  • Verilog
    +关注

    关注

    28

    文章

    1351

    浏览量

    110085
  • 计数器
    +关注

    关注

    32

    文章

    2256

    浏览量

    94521
  • 触发器
    +关注

    关注

    14

    文章

    2000

    浏览量

    61142
  • 累加器
    +关注

    关注

    0

    文章

    50

    浏览量

    9453
收藏 人收藏

    评论

    相关推荐

    利用Verilog实现奇数倍分频

    时钟下降沿变成了上升沿,则计数值n-1只保持了半个时钟周期,由于时钟翻转下降沿变成上升沿,因此计数值变为0。因此,每产生一个n+0.5分频时钟
    发表于 06-14 06:30

    如何利用Verilog实现奇数倍分频

    时钟下降沿变成了上升沿,则计数值n-1只保持了半个时钟周期,由于时钟翻转下降沿变成上升沿,因此计数值变为0。因此,每产生一个n+0.5分频时钟
    发表于 07-09 09:11

    基于verilog的数字时钟程序

    基于verilog的数字时钟程序,时钟芯片基础——60进制计数器设计目的让nexys 4板上的7段码LED显示时钟信息,其中包括时钟的小时,
    发表于 07-22 07:37

    STM32时钟分频系数的知识点汇总,绝对实用

    STM32时钟分频系数的知识点汇总,绝对实用
    发表于 12-15 07:01

    时钟分频及定时变换电路

    时钟分频及定时变换电路
    发表于 10-11 10:35 2293次阅读
    <b class='flag-5'>时钟</b><b class='flag-5'>分频</b>及定时变换电路

    基于Verilog的FPGA分频设计

    给出了一种基于FPGA的分频电路的设计方法.根据FPGA器件的特点和应用范围,提出了基于Verilog分频方法.该方法时于在FPGA硬件平台上设计常用的任意偶数分频、奇数
    发表于 11-09 09:49 355次下载
    基于<b class='flag-5'>Verilog</b>的FPGA<b class='flag-5'>分频</b>设计

    Verilog实现基于FPGA的通用分频器的设计

    Verilog实现基于FPGA 的通用分频器的设计时钟分频包括奇数和偶数分频
    发表于 07-14 11:32 46次下载

    MSP430G2553时钟系统要点总结

    MSP430G2553时钟系统要点总结时钟总览时钟源的选用默认状态控制寄存器例程个人总结的MSP430G2553各个模块功能要点,主要侧重于
    发表于 12-16 16:55 10次下载
    MSP430G2553<b class='flag-5'>时钟</b>系统要点<b class='flag-5'>总结</b>

    分频分频器与饮料售货机控制器verilog代码

    分频分频器与饮料售货机控制器verilog代码分享
    发表于 09-01 15:35 0次下载

    通过Verilog实现对一个频率的任意占空比的任意分频

    verilog程序设计中,我们往往要对一个频率进行任意分频,而且占空比也有一定的要求这样的话,对于程序有一定的要求,现在我在前人经验的基础上做一个简单的总结,实现对一个频率的任意占空比的任意
    的头像 发表于 01-05 09:33 2689次阅读

    verilog时钟分频时钟使能

    时钟使能电路是同步设计的基本电路,在很多设计中,虽然内部不同模块的处理速度不同,但由于这些时钟是同源的,可以将它们转化为单一时钟处理;在ASIC中可以通过STA约束让分频始终和源
    的头像 发表于 01-05 14:00 1729次阅读

    时钟的相关知识

    几乎稍微复杂的数字设计都离不开时钟时钟也是所有时序逻辑建立的基础。前面介绍建立时间和保持时间时也涉及过时钟偏移的概念。下面将总结时钟的相
    的头像 发表于 03-28 13:56 1966次阅读
    <b class='flag-5'>时钟</b>的相关<b class='flag-5'>知识</b>

    偶数分频、奇数分频、半整数分频和小数分频详解

    初学 Verilog 时许多模块都是通过计数与分频完成设计,例如 PWM 脉宽调制、频率计等。而分频逻辑往往通过计数逻辑完成。本节主要对偶数分频、奇数
    的头像 发表于 03-29 11:38 4984次阅读
    偶数<b class='flag-5'>分频</b>、奇数<b class='flag-5'>分频</b>、半整数<b class='flag-5'>分频</b>和小数<b class='flag-5'>分频</b>详解

    基于Verilog的分数分频电路设计

    上一篇文章时钟分频系列——偶数分频/奇数分频/分数分频,IC君介绍了各种分频器的设计原理,其中分
    的头像 发表于 04-25 14:47 1804次阅读
    基于<b class='flag-5'>Verilog</b>的分数<b class='flag-5'>分频</b>电路设计

    利用FPGA的高频时钟扇出电路的分频和分配设计

    基于FPGA的高频时钟分频分频设计
    发表于 08-16 11:42 1次下载