精华内容
下载资源
问答
  • 偶数倍分频应该是大家比较熟悉的分频,也是最简单的分频计数器,完全可以通过计数器直接实现的。例如进行N倍数偶数分频,那么可以通过待分频的时钟触发计数器计数,当计数器从0计数到N/2-1时,输出的时钟进行翻转,...

    学习之前,先理解一下什么叫占空比?
    占空比:对于一串理想的脉冲序列中(如方波),正脉冲的持续时间与脉冲中周期的比值,叫做这个方波的占空比。

    偶数倍分频

    偶数倍分频应该是大家比较熟悉的分频,也是最简单的分频计数器,完全可以通过计数器直接实现的。例如进行N倍数偶数分频,那么可以通过待分频的时钟触发计数器计数,当计数器从0计数到N/2-1时,输出的时钟进行翻转,并且将计数器复位,是的下一个时钟从零开始计数。以此循环,即可实现任意偶数倍分频

    奇数倍分频

    奇数倍分频常常在论坛上有人问起,实际上,奇数倍分频有两种实现方法:
    首先,完全可以通过计数器来实现,如进行三分频,通过待分频时钟 上升沿触发计数器进行模三计数,当计数器计数到邻近值进行两次翻转,比如可以在计数器计数到1时,输出时钟进行翻转,计数到2时再次进行翻转。即是在计数 值在邻近的1和2进行了两次翻转。这样实现的三分频占空比为1/3或者2/3。如果要实现占空比为50%的三分频时钟,可以通过待分频时钟下降沿触发计 数,和上升沿同样的方法计数进行三分频,然后下降沿产生的三分频时钟和上升沿产生的时钟进行相或运算,即可得到占空比为50%的三分频时钟。这种方法可以 实现任意的奇数分频。
    归类为一般的方法为:对于实现占空比为50%的N倍奇数分频,首先进行上升沿触发进行模N计数,计数选定到某一个值进行输出时钟翻 转,然后经过(N-1)/2再次进行翻转得到一个占空比非50%奇数n分频时钟。再者同时进行下降沿触发的模N计数,到和上升沿触发输出时钟翻转选定值相 同值时,进行输出时钟时钟翻转,同样经过(N-1)/2时,输出时钟再次翻转生成占空比非50%的奇数n分频时钟。两个占空比非50%的n分频时钟相或运 算,得到占空比为50%的奇数n分频时钟。
    另外一种方法:对进行奇数倍n分频时钟,首先进行n/2分频(带小数,即等于(n-1)/2+0.5),然后再 进行二分频得到。得到占空比为50%的奇数倍分频。

    小数分频

    首先讲讲如何进行n+0.5分频,这种分频需要对输入时钟进行操作。基本的设计思想:对于进行n+0.5分频,首先进行模n的计数,在计数到 n-1时,输出时钟赋为‘1’,回到计数0时,又赋为0,因此,可以知道,当计数值为n-1时,输出时钟才为1,因此,只要保持计数值n-1为半个输入时 钟周期,即实现了n+0.5分频时钟,因此保持n-1为半个时钟周期即是一个难点。从中可以发现,因为计数器是通过时钟上升沿计数,因此可以在计数为n- 1时对计数触发时钟进行翻转,那么时钟的下降沿变成了上升沿。即在计数值为n-1期间的时钟下降沿变成了上升沿,则计数值n-1只保持了半个时钟周期,由 于时钟翻转下降沿变成上升沿,因此计数值变为0。因此,每产生一个n+0.5分频时钟的周期,触发时钟都是要翻转一次。设计思路如下:
    在这里插入图片描述
    下面为任意正整数分频代码:

    module div_clk(
    	input	clk,
    	input	rst_n,
    	output	o_clk
    );
    
    	parameter	WIDTH = 3;
    	parameter	N	  = 6;
    	
    	reg [WIDTH-1:0]	cnt_p;
    	reg				clk_p;
    	reg				clk_n;
    	
    	assign	o_clk = (N==1)?clk : (N[0])?(clk_p | clk_n) : clk_p;//其中N==1是判断不分频,N[0]是判断是奇数还是偶数,若为1则是奇数分频,若是偶数则是偶数分频。
    	
    	always @(posedge clk or negedge rst_n) begin
    		if(!rst_n)
    			cnt_p <= {WIDTH{1'b0}};
    		else if(cnt_p == (N-1))
    			cnt_p <= {WIDTH{1'b0}};
    		else
    			cnt_p <= cnt_p + 1'b1;
    	end
    	
    	always @(posedge clk or negedge rst_n) begin
    		if(rst_n == 1'b0)
    			clk_p <= 1;//此处设置为0也是可以的,这个没有硬性的要求,不管是取0还是取1结果都是正确的。
    		else if(cnt_p < (N>>1))/*N整体向右移动一位,最高位补零,其实就是N/2,不过在计算奇数的时候有很明显的优越性*/
    			clk_p <= 1;
    		else
    			clk_p <= 0;
    	end
    	
    	always @(negedge clk or negedge rst_n) begin
    		if(rst_n == 1'b0)
    			clk_n <= 1;
    		else 
    			clk_n <= clk_n;
    	end
    
    endmodule
    

    下面为一段代码实现的奇数、偶数、小数分频

    module divf #
    (    parameter Div_num = 12 ,    // 分频数
         parameter state=0        //半分频为0,奇数分频为1,偶数分频为2
    )
    (
    input                 clr,
    input                 clk,
    output                Div_clk
    );
    reg [24:0]  count;
    
    case(state)
    1:   begin  //ji_shu
              reg         pos_clk;
              reg         neg_clk;
    
              always@(posedge clk or negedge clr)
              if(!clr)                     count<=0;
              else if(count==0 & pos_clk)  count<=Div_num/2-1;
              else if(count==0)            count<=Div_num/2;
              else                         count<=count-1;
    
              always@(posedge clk or negedge clr)
              if(!clr)                     pos_clk<=0;
              else if(count==0)            pos_clk<=~pos_clk;
              else                         pos_clk<=pos_clk;
    
              always@(negedge clk or negedge clr)
              if(!clr)                     neg_clk<=0;
              else                         neg_clk<=pos_clk;
    
              assign Div_clk = pos_clk & neg_clk;
         end
    
    2:   begin  //ou_shu
              reg          Div_clk1;
    
              always@(posedge clk or negedge clr)
              if(!clr)                     count<=0;
              else if(count==0)            count<=Div_num/2-1;
              else                         count<=count-1;
    
              always@(posedge clk or negedge clr)
              if(!clr)                     Div_clk1<=0;
              else if(count==0)            Div_clk1<=~Div_clk1;
    
              assign Div_clk = Div_clk1;
         end
    
    
    0:   begin   //ban_fen_pin
              reg         count_div;
              reg         count_div2;
              wire        clk_half;
    
              assign  clk_half = clk^count_div2;
              always@(posedge clk_half or negedge clr)   //模Div_num 计数
              if(!clr)                       count<=0;
              else if(count== Div_num-1)      count<=0;
              else                         count<=count+1;
    
              always@(posedge clk_half or negedge clr)   //模Div_num 计数
              if(!clr)                       count_div<=0;
              else if(count== Div_num-1)      count_div<=1;
              else                         count_div<=0;
    
              always@(posedge count_div or negedge clr)   //对count_div二分频
              if(!clr)                       count_div2<=0;
              else                         count_div2<=~count_div2;
    
              assign Div_clk = count_div;
         end
    endcase
    
    endmodule
    
    展开全文
  •  任意分频电路,相信很多人都听说过这个专业名词,好多视频上都说不建议使用计数器产生的分频时钟。其实在FPGA领域当中,由寄存器分频产生的时钟还有一个学名叫做,行波时钟。是由时序逻辑产生比如A寄存器的...

    一、行波时钟

      任意分频电路,相信很多人都听说过这个专业名词,好多视频上都说不建议使用计数器产生的分频时钟。其实在FPGA领域当中,由寄存器分频产生的时钟还有一个学名叫做,行波时钟。是由时序逻辑产生比如A寄存器的输出作为B寄存的时钟输入(一般不建议使用),如下图所示;驱动右边那个触发器的时钟即为行波时钟。之所以不建议使用在FPGA中使用行波时钟,因为这样会在FPGA设计中引入新的时钟域,,增加时序分析的难度,并且由于行波时钟的相位通常会滞后于原始时钟,会导致后续触发器的保持时间不一定能满足。

     

     

      事实上,采用行波时钟的目的无非是为后续时序电路的处理速度进行降频,而要实现降频的功能,除了通过降低时钟信号的频率外,仍然可以通过控制后续时序电路存储单元的使能端来实现,因此,上例中的电路完全可以修改如下:这样一来,整个时序逻辑将只被一个时钟信号所驱动。

     

     

     

    二、任意分频电路

     

      虽然说比建议使用分屏电路。但是在一些对时序要求不高的情况下是完全可以用的。而且还可以节省PLL和DCM等资源。那么设计一个任意分频的电路。这里的关键是偶数分频和奇数分频两大块。占空比一般都是50%。分频电路的整体架构如下:

     

     

     

       1、偶数分频:可以不用介绍,计数到N/2翻转就可以。

     

       2、奇数分频    第一步:上升沿触发进行模N计数,从0开始计数,计数到0+(n-1)/2,进行翻转,即为clk_odd= ~clk_odd

                第二步:还是在上升沿的条件下,从接着第一步计数,在其基础上再计数(n-1)/2,再次翻转;clk_odd= ~clk_odd

     

     

                                    第三步:在下降沿的条件下,采集clk_odd,即:clk_odd_r = clk_odd

             第四步;输出clk_odd_out = clk_odd_r |clk_odd;即为所求‘。

     

    三、实现  

     1 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      2 // Project Name : 
      3 // Website      : https://home.cnblogs.com/lgy-gdeu/
      4 // Author         : LGY GUET Uiversity
      5 // Weixin         : li15226499835
      6 // Email          : 15277385992@163.com
      7 // File           : 
      8 // Create         : 2020-07-01
      9 // Revise         : 
     10 // Editor         : sublime text{SUBLIME_VERSION}, tab size ({TABS})
     11 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     12 // Modification History:
     13 // Date             By              Version                 Change Description
     14 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     15 // {DATE} {TIME}    LGY           1.0                        ++++++++++++++++ 
     16 // *********************************************************************************
     17 `timescale      1ns/1ns
     18 module mux_cnt(
     19 input            wire                     sclk     ,
     20 input            wire                    s_rst_n  ,
     21 input             wire[3:0]               div      ,
     22 output          wire                    clk_out 
     23     );
     24 
     25 //========================================================================\
     26 // ################ Define Parameter and Internal signals ################ 
     27 //========================================================================/
     28 localparam             DIV1 = 1                ;
     29 localparam            DIV2 = 2                ;
     30 localparam          DIV3 = 3                ;
     31 localparam          DIV4 = 4                ;
     32 localparam          DIV5 = 5                ;
     33 localparam          DIV6 = 6                ;
     34 localparam            DIV7 = 7                ;
     35 localparam          DIV8 = 8                ;
     36 reg        [7:0]            fre_en          ;
     37 //=============================================================================
     38 //+++++++++++++++++++++++++     Main Code    +++++++++++++++++++++++++++++++
     39 //=============================================================================
     40 //分频模式的使能,一共是8种模式
     41 always @(posedge sclk or negedge s_rst_n)begin
     42         if(!s_rst_n)begin
     43             fre_en    <=   0;
     44         end    
     45         else begin
     46             case(div )
     47                 DIV1 :   fre_en   <=  8'b0000_0001 ;
     48                 DIV2 :   fre_en   <=  8'b0000_0010 ;
     49                 DIV3 :   fre_en   <=  8'b0000_0100 ;
     50                 DIV4 :   fre_en   <=  8'b0000_1000 ;
     51                 DIV5 :   fre_en   <=  8'b0001_0000 ;
     52                 DIV6 :   fre_en   <=  8'b0010_0000 ;
     53                 DIV7 :   fre_en   <=  8'b0100_0000 ;
     54                 DIV8 :   fre_en   <=  8'b1000_0000 ;                
     55             endcase
     56         end
     57 end
     58 
     59 //计数模块
     60 reg                [3:0]            fre_cnt       ;
     61 always @(posedge sclk or negedge s_rst_n)begin
     62     if(!s_rst_n)begin
     63         fre_cnt   <=    0 ;
     64     end
     65     else begin
     66         case (1'b1)
     67             fre_en[0]  :  begin
     68                 ;
     69             end
     70             fre_en[1]  :  begin
     71                 ;
     72             end
     73             fre_en[2]  : begin
     74                 if(fre_cnt < 2)
     75                     fre_cnt  <= fre_cnt + 1'b1 ;
     76                 else 
     77                     fre_cnt  <= 0 ;    
     78             end
     79             fre_en[3]  : begin
     80                 if(fre_cnt<3)
     81                     fre_cnt   <= fre_cnt + 1'b1 ;
     82                 else 
     83                     fre_cnt   <= 0;    
     84             end
     85             fre_en[4]  : begin
     86                 if(fre_cnt<4)
     87                     fre_cnt   <= fre_cnt +  1'b1 ;
     88                 else 
     89                     fre_cnt   <= 0;
     90             end
     91             fre_en[5]  : begin
     92                 if(fre_cnt<5)
     93                     fre_cnt   <= fre_cnt +  1'b1 ;
     94                 else 
     95                     fre_cnt   <= 0;    
     96             end
     97             fre_en[6]  : begin
     98                 if(fre_cnt<6)
     99                     fre_cnt   <= fre_cnt + 1'b1 ;
    100                 else 
    101                     fre_cnt   <= 0;    
    102             end
    103             fre_en[7]  : begin
    104                 if(fre_cnt<7)
    105                     fre_cnt   <= fre_cnt + 1'b1  ;
    106                 else 
    107                     fre_cnt   <= 0;    
    108             end
    109 
    110         endcase
    111     end
    112 end
    113 //分频模块
    114 reg          clk_out_odd_r    ;   //奇数分频,中间变量
    115 reg          clk_out_even     ;   //偶数分频,直接输出 
    116 always @ (posedge sclk or negedge s_rst_n) begin
    117     if(s_rst_n == 1'b0)begin
    118         clk_out_even  <= 0;
    119         clk_out_odd_r <= 0; 
    120     end    
    121     else begin
    122         case  (1'b1)
    123             fre_en[0] :  begin
    124                 ;
    125             end
    126             fre_en[1] :  begin
    127                 clk_out_even <= ~clk_out_even ;
    128             end
    129             fre_en[2] :  begin// 3 div
    130                 if (fre_cnt==1)
    131                     clk_out_odd_r   <=  ~clk_out_odd_r;
    132                 else if(fre_cnt==2)
    133                     clk_out_odd_r   <=  ~clk_out_odd_r;    
    134                 else
    135                     clk_out_odd_r   <= clk_out_odd_r;    
    136             end
    137             fre_en[3] :  begin//4 div
    138                 if(fre_cnt == 1)
    139                     clk_out_even    <= ~clk_out_even  ;
    140                 else if(fre_cnt ==3)
    141                     clk_out_even    <= ~clk_out_even   ;
    142                 else
    143                     clk_out_even    <=  clk_out_even   ;                  
    144             end
    145             fre_en[4] :  begin//5 div
    146                 if(fre_cnt == 2)
    147                     clk_out_odd_r   <=  ~clk_out_odd_r;
    148                 else if(fre_cnt == 4)
    149                     clk_out_odd_r   <=  ~clk_out_odd_r;
    150                 else 
    151                     clk_out_odd_r   <=  clk_out_odd_r ;    
    152                             
    153             end
    154             fre_en[5] : begin// 6 div
    155                 if (fre_cnt == 2)
    156                     clk_out_even    <=  ~clk_out_even  ;
    157                 else if(fre_cnt == 5)
    158                     clk_out_even    <=  ~clk_out_even  ;
    159                 else
    160                     clk_out_even    <=  clk_out_even;                
    161             end
    162             fre_en[6] :  begin //7div
    163                 if(fre_cnt == 3)
    164                     clk_out_odd_r    <=  ~clk_out_odd_r ;
    165                 else if(fre_cnt ==6)
    166                     clk_out_odd_r    <=  ~clk_out_odd_r ;
    167                 else
    168                     clk_out_odd_r    <=  clk_out_odd_r ;        
    169             end 
    170             fre_en[7] : begin // 8 div
    171                 if(fre_cnt == 3)
    172                     clk_out_even     <=  ~clk_out_even  ;
    173                 else if(fre_cnt ==7)
    174                     clk_out_even     <=  ~clk_out_even  ;
    175                 else 
    176                     clk_out_even     <=  clk_out_even ;            
    177             end
    178 
    179         endcase
    180     end    
    181         
    182 end
    183 
    184 //中间输出模块
    185 reg             clk_out_odd_r1 ;//用来存放下降沿采集的数据
    186 always @(negedge  sclk or negedge s_rst_n)begin
    187     if(!s_rst_n)
    188         clk_out_odd_r1   <=   0;
    189     else begin
    190         case (1'b1 )
    191             fre_en[0] : begin
    192                 ;
    193             end
    194             fre_en[1] : begin
    195                 ;
    196             end
    197             fre_en[2] : begin
    198                 clk_out_odd_r1   <=  clk_out_odd_r ;
    199             end
    200             fre_en[3] : begin
    201                 ;
    202             end
    203             fre_en[4] : begin
    204                 clk_out_odd_r1   <=  clk_out_odd_r ;
    205             end
    206             fre_en[5] : begin
    207                 ;
    208             end
    209             fre_en[6] : begin
    210                 clk_out_odd_r1   <=  clk_out_odd_r ;
    211             end
    212             fre_en[7] : begin
    213                 ;
    214             end
    215         endcase 
    216     end    
    217 end
    218 
    219 //最后的输出
    220 //assign     clk_out   =  ( fre_en[0] | fre_en[1] | fre_en[3] | fre_en[5] | fre_en[7] )?clk_out_even:clk_out_odd_r|clk_out_odd_r1;
    221 assign    clk_out   =  fre_en[0]? sclk :(( fre_en[1] | fre_en[3] | fre_en[5] | fre_en[7])?clk_out_even:clk_out_odd_r|clk_out_odd_r1);
    222 
    223 endmodule
    

    激励文件

     1 `timescale 1ns / 1ps
     2 //
     3 // Company: 
     4 // Engineer: 
     5 // 
     6 // Create Date: 2020/07/01 14:59:38
     7 // Design Name: 
     8 // Module Name: mux_cnt_tb
     9 // Project Name: 
    10 // Target Devices: 
    11 // Tool Versions: 
    12 // Description: 
    13 // 
    14 // Dependencies: 
    15 // 
    16 // Revision:
    17 // Revision 0.01 - File Created
    18 // Additional Comments:
    19 // 
    20 //
    21 
    22 
    23 module mux_cnt_tb();
    24 reg            sclk     ;
    25 reg            s_rst_n  ;
    26 reg  [3:0]     div      ;
    27 wire           clk_out  ;
    28 
    29 //=============================================================================
    30 //+++++++++++++++++++++++++     Main Code    +++++++++++++++++++++++++++++++里
    31 //=============================================================================
    32 
    33 //initial begin
    34 //    sclk   =  0 ;
    35 //    forever  begin
    36 //        #2  sclk = ~sclk ;
    37 //    end
    38 //end
    39 
    40 
    41 
    42 
    43 initial begin
    44     sclk  = 0;
    45     s_rst_n = 0;
    46     div = 3 ;
    47     #20
    48     s_rst_n = 1;
    49     #400
    50     div = 1; 
    51     #600
    52     s_rst_n = 1;
    53     div = 5;
    54     #1200
    55     div = 2;
    56     #600
    57 
    58     $finish;
    59     
    60 end
    61 always #10 sclk = ~sclk ;
    62 
    63 
    64 mux_cnt inst_mux_cnt (.sclk(sclk), .s_rst_n(s_rst_n), .div(div), .clk_out(clk_out));
    65 
    66 
    67 endmodule

     

    展开全文
  • 2.设计任务和要求用中小规模集成电路设计一台能显示日、时、分秒的数字电子钟,要求如下:1.由晶振电路产生1Hz 标准秒信号。2.秒、分为00—59六十进制计数器。3.时为00—23二十四进制计数器。4.周显示从1—日为...

    1、 前言

    数字钟是一种用数字电路技术实现时、分、秒计时的装置,与机械式时钟相比具有更高的准确性和直观性,且无机械装置,具有更长的使用寿命,因此得到了广泛的应用。

    2.设计任务和要求

    用中小规模集成电路设计一台能显示日、时、分秒的数字电子钟,要求如下:

    1.由晶振电路产生1Hz 标准秒信号。

    2.秒、分为00—59六十进制计数器。

    3.时为00—23二十四进制计数器。

    4.周显示从1—日为七进制计数器。

    5.可手动校正:能分别进行秒、分、时、日的校正。只要将开关置于手动位置,可分别对秒,分、时、日进行手动脉冲输入调整或连续脉冲输入的校正。

    6.整点报时。整点报时电路要求在每个整点前鸣叫五次低音(500Hz),整点时 再鸣叫一次高音(1000Hz)。

    3、实验器件选择

    本次实验中需使用到的元器件如下表所示

    器件名称

    型号

    数量

    功能

    芯片

    74HC00

    2

    与非

    芯片

    74HC04

    1

    非门

    芯片

    74HC74

    1

    2分频

    芯片

    74HC161

    7

    16进制

    芯片

    4060

    1

    二进制计数器

    芯片

    4511

    1

    驱动LED

    晶体振荡器

    32768

    1

    产生频率脉冲

    电阻

    22M

    1

    ---

    电阻

    32M

    1

    ---

    共阴单8显示器

    0.56英寸

    7

    显示数字

    可调电容

    30p

    2

    ---

    1元器件列表

    4、方案设计

    (1)脉冲信号电路设计方案

    dde375aa19009ea5bb0edb40f3da8f0a.png

    石英晶体主要成分是二氧化硅,它的物理化学性质十分稳定,本电路的显著优点是频率稳定性极好,理论上可达1.000000 Hz的精确度,石英晶体产生的信号经过4060可以达到14分频,再经过一个D触发器74HC74就实现了15分频输出1HZ信号。

    (2)秒、分电路设计

    e7c8808a24fd567a49d7a50765125f5a.png

    这个模块就是“秒”的部分,由74HC161芯片产生16进制计数,然后利用送数功能,当计时到1001(即十进制数字9)送0,实现0~9的循环,作为秒的个位。同时将1001经过与非门之后送到下一片74HC161芯片作为时钟信号,也就是个位计数十次十位进一次位。十位计数到0101(即十进制5)后经过与非门送到Load置数,同时作为下一片芯片的时钟信号。十位实现0~5的循环。这样,秒的个位和十位就完成了。

    分的设计和秒类似,这里就不再赘述。

    (3)时电路设计

    42ee26c9380ae973fd6306edfd1417f4.png

    时的电路设计与前面的分和秒类似,但是有些不同,主要是进位上面需要注意一下,个位上先是0~9循环两次,然后是0~4,接着向十位进位。十位上只能是0~2的循环。设计思路如下:个位上,当计数到1001时经过与非门产生送数,计时器回到0,并且向十位产生进位信号。十位上,当个位产生0100和十位产生0010时(组合后就是十进制24),产生的信号送到复位端,让个位和十位复位,并且信号输入到下一级的CLK上面。这样就可以达到要求了。

    (4)周电路设计

    0ea9e05adaa9bfa9dd915555de7de5c8.png

    周要实现周一~周日(日用8代替),因此,当计数到0111时经过与非门置数1,同时因为要显示8(跳过7),所以利用译码器的LT可以实现全亮,这样就达到了设计要求。

    (5)校时电路设计

    9f299530b74700d08f7aa28b7813a64c.png

    在刚刚开机接通电源时,由于日、秒、分、时为任意值,所以,需进行调整。置开关在手动位置,分别对时、分、秒、日进行单独计数,计数脉冲由单次脉冲或连续脉冲输入。

    方案实现:在芯片的CLK引出一个接口,既可以接收前一级的进位信号,也可以单独输入一个高频率脉冲信号,方便调整时间。

    b31f740b82b0896babd5be613dfcdaea.png

    总体连接示意图

    ad9191ab262fb9415d662c528f7c0d6d.png

    整体电路图

    30ec2dfed41da41c2dcde31967316e1e.png

    实物图1

    5d5e1f7c447ad56caec3c2d23a214def.png

    实物图2

    e055a7fb69440ef1e2763574b4e095e1.gif

    仿真动态图

    以上就是关于数字时钟的设计。

    更多精彩内容欢迎关注↓

    58ab7443fc4dcdc1d530bf798062d77e.png

    展开全文
  • 来自微信公众号:数字芯片设计三、分频电路(1)简单的计数器 计数器实质是对输入的驱动时钟进行计数,所以计数器在某种意义上讲,等同于对时钟进行分频。例如一个最大计数长度为N=2^n(从0计数到N-1)的计数器,也...

    5c26e7eee5545b0c1d70562109d70168.png

    来自微信公众号:数字芯片设计

    三、分频电路

    (1)简单的计数器

      计数器实质是对输入的驱动时钟进行计数,所以计数器在某种意义上讲,等同于对时钟进行分频。例如一个最大计数长度为N=2^n(从0计数到N-1)的计数器,也就是寄存器位数位n,那么寄存器最高位的输出为N=2^n分频,次高位为N/2分频...例如下面的代码:

    module test#(parameter N=3)(
    input clk,
    input rst_n,
    output clk_div
    );
    
    reg [N-1:0] div_reg        ;//分频计数器
    always @(posedge clk or negedge rst_n)
        if (rst_n == 1'b0 )
            div_reg    <= 0 ;
        else
            div_reg    <= div_reg + 1'b1 ;
    
    assign clk_div = div_reg[N-1] ;
    
    
    endmodule
    

    该代码描述的将一个3位的计数器最高位输出,也就是计数长度为8(计数从0~7)波形如下所示:

    477529c48c149c9958edb60c3307273f.png

    可以看到最高位的输出为输入时钟的8分频。

      当N不是2的整数次幂时,即N≠2^n时,从0计数到N-1,其最高位作为时钟输出(占空比不一定为 1:1)是输入时钟的1/N,也就是N分频。我们来举个例子,比如最大计数长度为5的计数器,即从0计数到4后又返回0,那么需要定义一个三位的寄存器。寄存器的计数过程为:

    000-001-010-011-100-000-001-010-011-100-000-001-010-011-100-000-001-010-011-100······

    我们取最高位,得到的信号变化就是:

      0-0-0-0-1-0-0-0-0-0-1-0-0-0-0-1-0-0-0-0-1···

    代码如下所示:

    module test#(parameter N=3)(
    input clk,
    input rst_n,
    output clk_div
    );
    
    reg [N-1:0] div_reg        ;//分频计数器
    always @(posedge clk or negedge rst_n)
        if (rst_n == 1'b0 )
            div_reg    <= 0 ;
        else if(div_reg == 3'd4)//从0计数到4,然后返回到0,5分频
            div_reg    <= 0;
        else
            div_reg    <= div_reg + 1'b1 ;
    
    assign clk_div = div_reg[N-1] ;
    
    
    endmodule
    

    仿真波形如下所示:

    7ffdd80d558174f5edaf0ae5d8479e02.png

    由此可以看到,每一个分频后的时钟周期=5倍原来的时钟周期,因此是5分频。

      那么这个情况是不是也可以包含第一种情况呢?我们那设置为8分频看看,即前面的3'd4改成3'd7,得到的仿真波形如下所示:

    4ee5481a96cf349f53673a26ebd27475.png

    可以看到,计数器的最高位输出也是输入频率的1/N。

    因此我们得到结论:一个最大计数长度为N(从0计数到N-1)的计数器,其最高位的输出,是输入频率的N分频。

      通常 ASIC 和 FPGA 中,时钟都是全局信号,都需要通过 PLL 处理才能使用,但某些简易场合,采用计数器输出时钟也是能够使用的,只是需要注意时序约束。

    (2)偶数倍分频(占空比50%)

     偶数分频,也就是2分频、4分频、6分频...这个还是比较简单的,N(N当然是2的倍数)分频,那么计数到N/2-1,然后时钟翻转:

    例如N=6时,代码如下所示:

    module test#(parameter N=6)(
    input clk,
    input rst_n,
    output clk_div
    );
    reg div_reg ;
    reg [N-1:0] div_cnt        ;//分频计数器
    always @(posedge clk or negedge rst_n)
        if (rst_n == 1'b0 )begin
            div_cnt    <= 0 ;
            div_reg    <= 0 ;
        end
        else if(div_cnt == (N/2 - 1))begin
            div_cnt    <= 0;
            div_reg    <= ~div_reg ;
        end
        else
            div_cnt    <= div_cnt + 1'b1 ;
    
    assign clk_div = div_reg ;
    

    仿真波形如下所示:

    8f3590d88ef3c98f0db0bc706401d51b.png

    当N=2的仿真波形如下所示:

    d968ffc0bdc3d8c47bd65c286bfab05b.png

    (3)奇数倍分频

    ①占空比接近50%

      对于占空比不是50%的计数分频,我们可以直接用上面的计数器方法,这里就不说了,我们介绍其他接近50%的占空比的方法,比如下面使用的状态机分频:

    855e2890cb6dd102c76b0e69bf5deb15.png

    上图的状态机除了用一般的状态机设计方式之外,我们也可以用简单的计数器实现,这种方法如下所示:

      假设时钟分频是N,则设置一个计数器,计数长度是N(即从0计数到N-1),然后在计数器为计数到(N-1)/2的时候,翻转一下分频时钟信号;在计数器计数到为N-1的时候,再翻转一下时钟。

    代码如下所示:

    module test#(parameter N=3)(//N分频,这里是3分频
    input clk,
    input rst_n,
    output clk_div
    );
    
    reg [N-1:0] div_cnt        ;//分频计数器
    reg div_reg ;
    always @(posedge clk or negedge rst_n)begin
        if (rst_n == 1'b0 )begin
            div_cnt    <= 0 ;
            div_reg        <= 1 ;
        end else if (div_cnt == (N-1)/2)begin//计数到(N-1)/2,进行翻转和继续计数
            div_reg        <= ~div_reg;
            div_cnt    <= div_cnt + 1'b1 ;
        end else if ( div_cnt == (N-1) )begin//计数到N-1,进行清零和翻转
            div_cnt        <= 0 ;
            div_reg        <= ~div_reg;
        end else
            div_cnt    <= div_cnt + 1'b1 ;
    
    end
    assign clk_div = (N == 1)?clk:div_reg ;//注意这里
    
    
    endmodule
    

    代码中我们需要注意,在N= 1的情况,也就是不分频的情况。仿真电路如下图所示:

    3分频,N = 3:

    95c0bc68e8461eb26593b07b0a40666e.png

    5分频,N= 5 :

    307f06f1816c8b26b813f66d4bd8cfaf.png

    不分频,即N=1的仿真如下所示:

    c511cb75e693682343fbb8a49d484131.png

    ②占空比50%

    产生具有50%占空比的奇数分频时钟的算法如下所示,假设N分频(N是计数):

      设置一个计数长度为N的上升沿计数器,和一个信号寄存器;信号寄存器在上升沿计数器为(N-1)/2的时候进行翻转,然后再在计数到N-1的时候进行翻转(这里相当于得到一个N分频信号A)。

      再设置一个计数长度为N的下降沿计数器,和另一个信号寄存器;信号寄存器在下降沿计数器为(N-1)/2的时候进行翻转,然后再在计数到N-1的时候进行翻转(这里相当于得到一个N分频信号B)。

      将A和B相或就可以得到占空比50%的奇数分频信号;代码实现如下:

    module test#(parameter N=5)(//N分频
    input clk,
    input rst_n,
    output clk_div
    );
    
    reg sig_r ;//定义一个上升沿翻转的信号
    reg sig_f ;//定义一个下降沿翻转的信号
    reg [N-1:0]    cnt_r;//上升沿计数器
    reg [N-1:0]    cnt_f;//下降沿计数器
    
    wire clk_f ;
    assign clk_f = ~clk ;//用来触发下降沿计数器的时钟
                        //由于同时使用上升沿和下降沿触发器不好,因此我们为同一边沿,都使用上升沿触发
                        //只不过是将时钟进行反向
    
    always @(posedge clk or negedge rst_n)begin//上升沿计数
        if(rst_n == 1'b0)begin
            sig_r    <= 0 ;
            cnt_r    <= 0 ;
        end else if( cnt_r == (N-1)/2 )begin
            sig_r    <= ~sig_r ;
            cnt_r    <= cnt_r + 1 ;
        end else if ( cnt_r == (N-1) )begin
            sig_r    <= ~sig_r ;
            cnt_r    <= 0 ;
        end else
            cnt_r    <= cnt_r + 1 ;
    end
    
    always @(posedge clk_f or negedge rst_n)begin//下降沿计数
        if(rst_n == 1'b0)begin
            sig_f    <= 0 ;
            cnt_f    <= 0 ;
        end else if( cnt_f == (N-1)/2 )begin
            sig_f    <= ~sig_f ;
            cnt_f    <= cnt_f + 1 ;
        end else if ( cnt_f == (N-1) )begin
            sig_f    <= ~sig_f ;
            cnt_f    <= 0 ;
        end else
            cnt_f    <= cnt_f + 1 ;
    end
    
    assign clk_div = sig_f || sig_r ;
    
    endmodule
    

    仿真波形如下所示:

    3分频:

    cf1ad6954fb50dc1e09bc3f7ede07d61.png

    5分频:

    a82d20cac49a81c1092c1950fd37faf8.png

     (4)任意整数倍分频(接近50%)

      在前面中,我们知道了一个最大计数长度为N(从0计数到N-1)的计数器,其最高位的输出,是输入频率的N分频,因此最简单的任意分频电路就是设计一个计数器,然后最高位输出就是分频的频率了。虽然这这种方法很简单,但是很显然,这种方法的占空比是很糟糕的。因此我们要用其他的方法,也就是用其他的组合方式。

    ①占空比接近50%任意整数分频

      这种方法是取自偶数分频和奇数分频里面的接近50%占空比,实现的代码如下所示:

    module test #( parameter cfactor= 5)(
      input clk,
      input rst_n,
      output clk_div
    );
    reg clk_loc;
    //reg [15:0] cnt;//allowed maximum clock division factor is 65536
    reg [7:0] cnt;//allowed maximum clock division factor is 256
    
    assign clk_div = (cfactor==1)? clk : clk_loc;
    //assign clk_div = ((rst==1) || (cfactor==1))? clk : clk_loc;
    
    always@(posedge clk or negedge rst_n)
      if(!rst_n)begin
        cnt <= 'd0;
        clk_loc = 1;
      end
      else begin
        cnt <= cnt + 1'b1;
        if(cnt==cfactor/2-1)
          clk_loc = 0;
        else if(cnt==cfactor-1) begin
          cnt <= 'd0;
          clk_loc = 1;
        end
      end
    
    endmodule
    

    2分频的仿真图,如下所示:

    10c1f4a1ba375de74f0a9e03ad40f644.png

    5分频的仿真波形如下所示:

    f02e814cb35bcaea15b580d147a2fd9c.png

    ②占空比50%的任意整数分频(重点)

    这种方法是取自偶数分频和奇数分频都是50%占空比的组合,代码如下所示:

    module test #( parameter cfactor= 5)(
      input clk,
      input rst_n,
      output clk_div
    );
    reg clk_loc;
    //reg [15:0] cnt;//allowed maximum clock division factor is 65536
    reg [7:0] cnt;//allowed maximum clock division factor is 256
    
    assign clk_div = (cfactor==1)? clk : clk_loc;
    //assign clk_div = ((rst==1) || (cfactor==1))? clk : clk_loc;
    
    always@(posedge clk or negedge rst_n)
      if(!rst_n)begin
        cnt <= 'd0;
        clk_loc = 1;
      end
      else begin
        cnt <= cnt + 1'b1;
        if(cnt==cfactor/2-1)
          clk_loc = 0;
        else if(cnt==cfactor-1) begin
          cnt <= 'd0;
          clk_loc = 1;
        end
      end
    
    endmodule
    

    仿真波形如下所示:

    5分频:

    18f04ab45f6f4459760df7a782c26877.png

    总结:本文介绍了计数器及其功能,主要是介绍了作为分频器的功能。对于分频器,如下所示:

    80a1c07f3d59753ac1f251af0feb533d.png

    作者:IC_learner

    博客链接:https://www.cnblogs.com/IClearner/p/7208871

    展开全文
  • 在数字逻辑电路设计中,分频器是一种基本的电路单元。通常用来对某个给定频率进行分频,以得到所需的频率。分频在FPGA的设计中一直都担任着很重要的角色,而说到分频,我相信很多人都已经想到了利用计数器计数来得到...
  • 如果只是使用FPGA逻辑资源 (即输入时钟clk_in,计数器,线网资源),不使用包括PLL锁相环等在内的外部资源和其他用于分频的外部电路,那么最终设计一定不可能得到占空比为50%的时钟,并且如果是任意小数,不是N.5...
  • 并应用EWB 软件对所设计电路进行仿真,仿真结果表明设计计数器能实现所要求的N 进制技术功能。  0 引言  计数器是数字系统中应用广泛的基本逻辑器件。它不仅能记录输入时钟脉冲的个数,还可以实现分频、定时...
  • 分频和偶分频总结

    2020-09-21 22:40:53
    任意分频-基于相位累加器原理 1. 偶分频电路 倍数K = f1/f2; 常数N = K/2; 设计思路1: 主要通过计数器累加到N-1 当累加到N-1时信号翻转 设计思路2: 计数器累加到K-1 时钟分别在N-1和K-1上取反 module even_...
  • 并应用EWB 软件对所设计电路进行仿真,仿真结果表明设计计数器能实现所要求的N 进制技术功能。  0 引言  计数器是数字系统中应用广泛的基本逻辑器件。它不仅能记录输入时钟脉冲的个数,还可以实现分频、定时...
  • verilog奇偶分频

    2012-09-01 20:22:43
    本文介绍了偶数分频和奇数分频电路设计,分别从简单的分频介绍开始,延伸到任意N分频电路设计,做了详细的说明,并且附有verilog源程序,并有仿真结果。 在数字逻辑电路中,分频器是一种常用电路,通常用来对某个...
  • 摘要 以多种种典型的中规模集成 (MSI) 计数器芯片为例,采用反馈置零法 ( 复位法 )、反馈置数法 ( 置位法 ) 和级联法来构成任意进制计数器。总结出详细的设计步骤。  1 绪论  计数器是数字逻辑系统中的...
  • 奇偶分频

    2019-08-03 22:27:02
    各种分频的实现方法对于打好数字电路设计的基础是必不可少的,也有很多公司面试的让应聘者写分频器。 第一,偶数倍分频:偶数倍分频应该是大家都比较熟悉的分频,通过计数器计数是完全可以实现的。如进行N倍偶数...
  • 本文介绍了偶数分频和奇数分频电路设计,分别从简单的分频介绍开始,延伸到任意N分频电路设计,做了详细的说明,并且附有verilog源程序,并有仿真结果。在数字逻辑电路中,分频器是一种常用电路,通常用来对某个给定...
  • 摘要 以多种种典型的中规模集成 (MSI) 计数器芯片为例,采用反馈置零法 ( 复位法 )、反馈置数法 ( 置位法 ) 和级联法来构成任意进制计数器。最后总结出详细的设计步骤。  1 绪论  计数器是数字逻辑系统中...
  • 要求: 完成占空比(高电平占一个时钟周期的比例)为0.25的8分频电路模块的Verilog设计,并且设计一个仿真测试用的Verilog程序,从时序上验证分频电路模块的正确性。  整数分频器的设计原理  1.1 偶数倍分频  ...
  • 要求: 完成占空比(高电平占一个时钟周期的比例)为0.25的8分频电路模块的Verilog设计,并且设计一个仿真测试用的Verilog程序,从时序上验证分频电路模块的正确性。  整数分频器的设计原理  1.1 偶数倍分频  ...
  • 常用电路设计之分频器的设计

    千次阅读 2020-07-15 16:05:00
    分频器在实际数字电路设计中是最基础的,也是最重要的。常见的分频器主要有偶数倍分频器,奇数倍分频器,半整数倍分频器,任意小数倍分频器等。 1、偶数倍分频器 偶数倍分频器通过计数器可以很简单的实现。基本...
  • 在基于CPLD(复杂可编程逻辑器件)的数字系统设计中,很容易实现由计数器或其级联构成各种形式的偶数分频及非等占空比的奇数分频,但对等占空比的奇数分频及半整数分频的实现较为困难。 本文利用VHDL(甚高速集成...
  • 作为一门基本的电路单元,分频在数字IC前端设计中具有重要的地位。在分频时,首先想到的是使用利用计算器来计算达到想要的时钟频率,但问题是仅仅利用计数器分频,只可以实现偶数分频,如果需要奇数分频,该方法就...
  • 中国最好的纯工程师社群分频器是用的最广的一种FPGA电路了,我最初使用的是crazybingo的一个任意分频器,可以实现高精度任意分频的一个通用模块,他的思想在于首先指定计数器的位宽比如32位,那么这个计数器的最大值...
  • 本节需要熟悉基于触发器和组合逻辑的计数器电路模型,还会讲到秒表、电子钟和按键消抖电路的计数器应用示例,以及基于计数器电路任意分频器(整数/分数分频)应用示例。2、16:00,马熙飞老师的“十天学会用AD设计...
  • 分频器是用的最广的一种FPGA电路了,我最初使用的是crazybingo的一个任意分频器,可以实现高精度任意分频的一个通用模块,他的思想在于首先指定计数器的位宽比如32位,那么这个计数器的最大值就是2^32=4294967296, ...
  • c语言编写单片机技巧

    2009-04-19 12:15:17
    最近几年高频电路与数位电路共享相同电路板,构成所谓的混载电路系统似乎有增加的趋势,类似如此的设计经常会造成数位电路动作时,高频电路却发生动作不稳定等现象,其中原因之一是数位电路产生的噪讯,影响高频电路...

空空如也

空空如也

1 2
收藏数 23
精华内容 9
关键字:

任意分频计数器电路设计