精华内容
下载资源
问答
  • FPGA分频电路实现(奇数,偶数,小数半分频,任意分频
    千次阅读
    2020-05-12 19:31:50

    前言
    虽然在实际工程中要产生分频时钟一般采用FPGA的时钟管理器来进行分频、倍频,通过设置一下IP核中的参数即可,这样做有很多别的方法(例如:直接用Verilog HDL设计分频电路)达不到的效果,产生时钟的质量也更好,因此,一般而言,也推荐这种方法,但这并非意味着直接用Verilog HDL设计分频电路一无是处,毫无用途。

    由于FPGA的晶振频率都是固定值,只能产生固定频率的时序信号,但是实际工程中我们需要各种各样不同频率的信号,这时候就需要对晶振产生的频率进行分频。

    如果对时钟的性能要求不高,我就自然就可以用这种方法产生分频时钟,这样就只消耗了少量的资源而实现了时钟的分频要求,我们把这种设计叫做分频器设计。

    注意:分频电路可以这么设计,但倍频电路呢?恐怕写不出来吧!只能用IP核来产生

    分频器分类
    分频器分为偶分频、奇分频,下面分别介绍二者的设计原理。

    1)偶分频

    相信大多数朋友在学习FPGA过程中接触到的第一个实验应该就是偶数分频器了,偶数分频器的设计较为简单,用一个简单的计数器就可以实现。比如要实现一个N分频(N为偶数)的分频器,可以先写一个计数器,当计数到(N/2-1)时,让输出状态翻转,并将计数器清零,这样输出的信号就是输入时钟的N分频了。

    N分频(N为偶数),计数器计数到N/2-1翻转。如进行4分频,count=4/2-1=1时翻转,6分频计数器计到2翻转。程序如下,经过实测验证,正确。

    //偶分频电路的Verilog HDL设计(10分频为例)
    module even_freq_div(clk, rst, clk_div10,cnt);
     
    input clk;
    input rst;
    output clk_div10;
    reg clk_div10;
    output [2:0] cnt;          //输出cnt的原因是为了看到计数次数,便于分析仿真结果。
    reg [2:0] cnt;
     
     
     
    always @(posedge clk)
    begin
    	if(rst)  //复位信号有效;
    	begin
    		cnt <= 0;          //计数器清零
    		clk_div10 <= 0;    //输出清零;
    	end
    	else     //复位信号无效;
    	begin
    		if(cnt == 4)                //每一次时钟上升沿到来时,都检查一次计数值是否达到4;
    		begin
    			clk_div10 <= ~clk_div10;
    			cnt <= 0; //计数器计数到4后,重新清零;计数值为4意味着已经计了5个周期,这时10分频时钟翻转一次;
    		end
    		else     //如果计数器未计数到4,则来一个上升沿加1,同时分频时钟继续保持原值不变。
    		begin
    			cnt <= cnt + 1;           
    			clk_div10 <= clk_div10;  //否则继续保持;
    		end
    	end
    	
    end
     
     
    endmodule

    2)奇分频

    奇数分频器的设计比偶数分频器复杂一些,特别是占空比为50%的奇数分频器。如果对占空比没有明确的要求,则可以直接对上升沿计数,计数到(N-1)/2 时让输出翻转,计数到(N-1)时让输出状态再次翻转,并将计数器清零,这样就可以得到一个占空比为2:3的N分频(N为奇数)的分频器。而如果要实现50%的占空比,可以通过“错位相或”的方法实现。具体方法是用刚才的方法先通过对上升沿计数产生一个占空比为不是50%的N分频器,再用同样的方法对下降沿计数产生一个占空比也不是50%的N分频器,最后将这两个分频器的输出进行“或”运算,就可以得到占空比为50%的奇数N分频器,

    以5分频为例,我们写一个Verilog程序:
     

    `timescale 1ns / 1ps
    //
    // Company: 
    // Engineer: CSDN 李锐博恩
    // 
    // Create Date: 2019/07/28 15:15:27
    // Design Name: 
    // Module Name: FRE_DIV5
     
    //
     
     
    module FRE_DIV5(
    	input clk,
    	input rst_n,
    	output clk_div5
     
        );
    	
    	reg [2:0] div_cnt;
    	
    	always@(posedge clk or negedge rst_n) begin
    		if(~rst_n) begin
    			div_cnt <= 0;
    		end
    		else if(div_cnt <4) begin
    			div_cnt <= div_cnt + 1;
    		end
    		else 
    			div_cnt <= 0;
    	
    	end
    	
    	reg clk_div_r, clk_div_rr;
    	
    	always@(posedge clk or negedge rst_n) begin
    		if(~rst_n) begin
    			clk_div_r <= 1;
    		end
    		else if(div_cnt == 1) begin
    			clk_div_r <= ~clk_div_r;
    		end
    		else if(div_cnt == 4) begin
    			clk_div_r <= ~clk_div_r;
    		end
    		else	clk_div_r <= clk_div_r;
    	end
    	
    	always@(negedge clk or negedge rst_n) begin
    		if(~rst_n) begin
    			clk_div_rr <= 1;
    		end
    		else clk_div_rr <= clk_div_r;
    	end
    	
    	assign clk_div5 = clk_div_r | clk_div_rr;
    	
    	
    endmodule

    3.半分频器(N+0.5分频)

    `timescale 1ns/1ps
    ///
    //Create Date: 2020/03/05 
    //Module Name: half_integer_div
    //Engineer: hewen 
    ///
    module half_integer_div(
    	input clk,
    	input rst_n,
    	output clk_out
    );
    
    parameter N = 3;  //3.5分频
    
    reg[31:0] cnt1;
    reg clk_p;
    reg clk_n;
    always @(posedge clk or posedge rst_n)
    begin
    	if(!rst_n)
    		cnt1<=0;
    	else if(cnt1 == 2*N)
    		cnt1<= 0;
    	else
    		cnt1<=cnt1+1;
    end
    
    always @(posedge clk or posedge rst_n)	
    begin 
    	if(!rst_n)
    		clk_p<=0;
    	else if(cnt1 == 2*N)
    		clk_p<=1;
    	else if(cnt1 == N)
    		clk_p<=0;
    end
    
    always @(negedge clk or posedge rst_n)
    begin
    	if(!rst_n)
    	clk_n <= 0;
    	else if (cnt1==0)
    		clk_n <= 0;
    	else if(cnt1 ==N)
    		clk_n<=1;
    end
    
    assign clk_out = clk_p & clk_n;
    	
    endmodule
    

    4.任意分频

    `timescale 1ns/1ps
    ///
    //Create Date: 2020/03/05 
    //Module Name: divide
    //Engineer: hewen 
    ///
    module divide #
    (							
    parameter WIDTH = 24, //计数器的位数,计数的最大值为 2**(WIDTH-1)
    parameter N = 5  //分频系数,请确保 N<2**(WIDTH-1),否则计数会溢出
    )
    (input clk,  //clk连接到FPGA的C1脚,频率为12MHz
    input rst_n,  //复位信号,低有效,
    output clkout  //输出信号,可以连接到LED观察分频的时钟
    ); 
     reg [WIDTH-1:0] cnt_p,cnt_n;	
     reg clk_p,clk_n;	
     
    /**********上升沿触发部分************/
    //上升沿触发时计数器的控制
    always @(posedge clk or negedge rst_n)	    
    begin     
    	if(!rst_n)
    		cnt_p <= 1'b0;    
    	else if(cnt_p == (N-1))
    		cnt_p <= 1'b0;    
    	else 
    		cnt_p <= cnt_p + 1'b1;		    
    end 
     //上升沿触发的分频时钟输出,如果N为奇数得到的时钟占空比不是50%;如果N为偶数得到的时钟占空比为50%
    always @(posedge clk or negedge rst_n)    
    begin    
    	if(!rst_n)
    		clk_p <= 1'b0;    
    	else if(cnt_p < (N>>1))	
    		clk_p <= 1'b0;
    	else 
    		clk_p <= 1'b1;	
    end
    
    /***********下降沿触发部分*************/
    //下降沿触发时计数器的控制        	
    always @(negedge clk or negedge rst_n)    
    begin    
    	if(!rst_n)
    		cnt_n <= 1'b0;    
    	else if(cnt_n == (N-1))
    		cnt_n <= 1'b0;    
    	else 
    		cnt_n <= cnt_n + 1'b1;
    end  
    //下降沿触发的分频时钟输出,和clk_p相差半个clk时钟
    always @(negedge clk or negedge rst_n)    
    begin    
    	if(!rst_n)
    		clk_n <= 1'b0;    
    	else if(cnt_n < (N>>1))  
    		clk_n <= 1'b0;   
    	else 
    		clk_n <= 1'b1;    
    end
    wire clk1 = clk;  //当N=1时,直接输出clk
    wire clk2 = clk_p;  //当N为偶数也就是N[0]=0,输出clk_p
    wire clk3 = clk_p & clk_n;  //当N为奇数也就是N[0]=1,输出clk_p&clk_n。正周期多所以是相与  
    assign clkout = (N==1)? clk1:(N[0]? clk3:clk2);	
    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

     

    展开全文
  • verilog实现任意时钟的分频,根据输入的信号判断需要的时钟分频数,然后输出需要的分频时钟
  • 本资源详细描述了任意分频电路的实现电路,非常经典
  • 学习之前,先理解一下什么叫占空比? 占空比:对于一串理想的脉冲序列中(如方波),正脉冲的持续时间...以此循环,即可实现任意偶数倍分频 奇数倍分频 奇数倍分频常常在论坛上有人问起,实际上,奇数倍分频有两种实现方

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

    偶数倍分频

    偶数倍分频应该是大家比较熟悉的分频,也是最简单的分频计数器,完全可以通过计数器直接实现的。例如进行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
    
    展开全文
  • 使用verilog描述的任意分频电路且占空比为50%,附加测试电路
  • 任意分频的verilog 语言实现(占空比50%)
  • 给出了一种奇数分频电路设计方法,采用verilog HDL描述。修改代码中参数可以进行任意奇数分频,包含了设计文档和源代码。
  • IC校招笔试题:设计一个可任意切换1-8时钟分频,且无论奇偶分频,时钟占空比均为50%。

    IC校招笔试题:设计一个可任意切换1-8时钟分频,且无论奇偶分频,时钟占空比均为50%。

    一、奇数分频

    例如7分频,若不要求占空比为50%,很简单地产生3个cycle的高电平,4个cycle的低电平即可。若要求占空比为50%,则需要进行以下调整:

    1. 利用源时钟上升沿分频出高电平为 3 个 cycle、低电平为 4 个 cycle 的 7 分频时钟:clkp。
    2. 利用源时钟下降沿分频出高电平为 3 个 cycle、低电平为 4 个 cycle 的 7 分频时钟:clkn。
    3. 两个 7 分频时钟的相位差为半个时钟周期,将2个时钟进行“或操作”,便得到了占空比为50%的7分频时钟。

    同理N分频:

    1. 源时钟上升沿到来时,若计数值达到(N-1)/2,clkp<=1;若计数值达到(N-1),clkp<=0。产生7分频时钟clkp(占空比不是50%)。
    2. 源时钟下降沿到来时,clkn <= clkp,产生相对clkp延迟半个时钟周期的时钟clkn。
    3. 将2个时钟进行“或操作”,便得到了占空比为50%的7分频时钟div_clk。

    二、偶数分频

    偶数分频很简单地实现占空比为50%的N分频时钟:

    1. 对分频系数N进行循环计数,达到 N/2-1和N-1 时进行时钟翻转,可保证分频后时钟的占空比为 50%。
    2. 也可以对分频系数中间数值 N/2-1 进行循环计数。

    三、半整数分频

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

    1. 例如进行 3.5 倍分频时,计数器循环计数到 7,在源时钟上升沿,达到 0 和 4(N/2+1) 时进行时钟翻转,分别产生由 4 个和 3 个源时钟周期组成的 2 个分频时钟,即clk_ave。
    2. 对这2个周期不均匀的分频时钟进行调整。一次循环计数中,在源时钟下降沿,达到 1 和 4(N/2+1) 时进行时钟翻转,分别产生由 4 个和 3 个源时钟周期组成的 2 个分频时钟,即clk_adj。相对于第一次产生的 2 个周期不均匀的时钟,本次产生的 2 个时钟相位一个延迟半个源时钟周期,一个提前半个源时钟周期。
    3. 将两次产生的时钟进行"或操作",便可以得到周期均匀的 3.5 倍分频时钟,即div_clk。分频波形示意图如下所示。
      在这里插入图片描述

    四、完整代码

    1. divf.v

    module divf
    #(
    	parameter DIV_NUM = 7,//=============1-8分频
    	parameter state = 0//================0:奇数	1:偶数	2:半整数
    )
    (
    	input clk,
    	input rstn,
    	output div_clk
    );
    	reg [2:0] count;
    	reg clkp,clkn;//奇数使用
    	reg div_temp;//偶数使用
    	reg clk_ave,clk_adj;//半整数使用
    
    	always@(posedge clk or negedge rstn) begin
    				if(!rstn)
    					count <= 0;
    				else if(count == DIV_NUM -1)
    					count <= 0;
    				else
    					count <= count + 1;
    	end
    
    	case(state) 
    		0:begin//=========================奇数分频
    			assign div_clk = clkp & clkn;
    
    			always@(posedge clk or negedge rstn) begin
    				if(!rstn)
    					clkp <= 0;
    				else if(count == DIV_NUM >> 1)
    					clkp <= 0;
    				else if(count == DIV_NUM - 1)
    					clkp <= 1;
    			end
    			always@(negedge clk or negedge rstn) begin
    				if(!rstn)
    					clkn <= 0;
    				else clkn <= clkp;
    			end
    		end
    		1: begin//==========================偶数分频
    			assign div_clk = div_temp;
    
    			always@(posedge clk or negedge rstn) begin
    				if(!rstn)
    					div_temp <= 0;
    				else if((count == DIV_NUM/2-1) || (count == DIV_NUM -1))
    					div_temp <= ~div_temp;
    			end
    		end
    		2: begin//=========================半整数分频
    			assign div_clk = clk_ave | clk_adj;
    
    			always@(posedge clk or negedge rstn) begin
    				if(!rstn)
    					clk_ave <= 0;
    				else if((count == 0) || (count == DIV_NUM/2 + 1))
    					clk_ave <= 1;
    				else 
    					clk_ave <= 0;
    			end
    			always@(negedge clk or negedge rstn) begin
    				if(!rstn)
    					clk_adj <= 0;
    				else if((count == 1) || (count == DIV_NUM/2 + 1))
    					clk_adj <= 1;
    				else 
    					clk_adj <= 0;
    			end
    		end
    	endcase
    endmodule
    

    2. divf_tb.v

    `timescale 1ns/1ns
    
    module divf_tb();
    	reg clk,rstn;
    	wire div_clk;
    	
    	divf #(
    		.DIV_NUM(7),
    		.state(2)
    	)
    	U1(
    		.clk(clk),
    		.rstn(rstn),
    		.div_clk(div_clk)
    	);
    	
    	initial begin
    		clk = 1'b0;
    		rstn = 1'b0;
    		#1 rstn =1'b1;
    		#50 $stop;
    	end
    
    	always #1
    		clk = ~clk;
    endmodule
    

    五、仿真波形

    1. 奇数分频:7分频,50%(DIV_NUM=7,state=0)

    在这里插入图片描述

    2. 偶数分频:8分频,50%(DIV_NUM=8,state=1)

    在这里插入图片描述

    3. 半整数分频:3.5分频(DIV_NUM=7,state=2)

    在这里插入图片描述

    展开全文
  • 任意奇数分频电路

    2013-05-31 12:06:04
    vhdl语言实现任意奇数分频电路,可在ise里直接运行
  • 例如你要实现6分频 通过调节 parameter HW = 3 ; parameter LW = 3 ;
  • 任意偶数分频电路

    2013-05-31 12:00:42
    VHDL实现任意偶数分频电路,直接在Ise里运行就行
  •   //`define N 5 module div_N ( ... input CLK, // 基准时钟 ... output CLK_div_N, // N分频后得到的时钟 ... // ★ N为分频系数,N≥2即可,N的值为CLK除以CLK_div_N后取整(四舍五入)   ...
  • 电子电路设计——分频电路设计

    千次阅读 2020-04-25 12:55:49
    本文利用555定时器产生100Hz方波信号,再用4个D触发器将其变为16分频的6.25Hz电路。 一、前置知识 555定时器产生信号方式详见博客:555定时器及应用 Multisim中快速生成所需定时器方法详见博客:Multisim快捷生成...
  • 一看就会的奇偶分频电路

    千次阅读 2020-05-01 15:45:20
    目录 前言 题目 二分频电路 ...),因此在这篇文章里,我们使用一个公式将所有分频电路套进去,以便于在考场上和仿真工具中轻松实现分频电路。 题目 实现2/3/4/5分频电路,给出一个模板: modul...
  • 文章目录前言占空比不为50%的奇数分频占空比为50%的5分频电路扩展 前言 前文我们讲到,可以通过计数器的方法实现偶数分频,实现方式可以参考4分频电路实现 那么对于奇数分频电路应该如何实现呢?是否也可以通过...
  • 分频任意占空比、50%占空比) 偶分频任意占空比、50%占空比)
  • IC/FPGA面试之任意时钟分频电路的产生 #题目分析 第一步:确定输入输出,输入时钟,复位信号,分频选择信号,输出分频信号。 第二步:偶数分频实现通过计数即可。奇数分频,首先产生分频电路,其次使用始终下降沿...
  • 任意分频Verilog实现

    2020-12-24 05:01:05
    1.偶数倍(2N)分频使用一模N计数器模块即可实现,即每当模N计数器上升沿从0开始计数至N-1时,输出时钟进行翻转,同时给计数器一复位信号使之从0开始重新计数,以此循环即可。偶数倍分频原理示意图见图1。2.奇数倍(2N+...
  • 偶数分频 偶数分频是最简单的,N分频需要计数到(N-1),并在(N/2 - 1)和(N - 1)处更改输出的取值即可,只需要单一时钟沿计数。下面是四分频电路的实现: 代码: 奇数分频
  • verilog实现任意占空比、任意分频的方法在verilog程序设计中,我们往往要对一个频率进行任意分频,而且占空比也有一定的要求这样的话,对于程序有一定的要求,现在我在前人经验的基础上做一个简单的总结,实现对一个...
  • 时钟分频电路在数字芯片设计中非常常见,而且也非常重要,正确的符合要求的数字分频电路对功能的正确与否至关重要。现在数字电路设计中的时钟分频主要包括以下几种方法: 1、寄存器分频 寄存器分频就是利用寄存器...
  • 上一篇文章讲解了如何进行任意的奇分频任意的偶分频,这篇文章主要讲解占空比为50%的任意整数分频(奇分频和偶分频),下面首先以6分频和5分频来回顾一下奇偶分频。 偶分频分频时最简单的,通过下图就可以很好...
  • [VHDL]利用计数器实现任意分频,占空比为60%电路 也可以设置为任意占空比。
  • EDA365欢迎您登录!... |( n9 Z4 {一、为啥要说任意分频也许FPGA中的第一个实验应该是分频实验,而不是流水灯,或者LCD1602的"Hello World"显示,因为分频的思想在FPGA中极为重要。当初安排流水...
  • 1-8分频任意切换电路(附代码)

    千次阅读 2019-11-15 20:33:34
    从之前的博客(时钟分频)知道了任意偶数分频任意奇数分频的实现方法,但是,如果要求设计一个1-8分频任意切换的电路,要怎么做呢? 我们知道,偶数分频与奇数分频的实现方式不同,偶数分频只需每隔N/2,时钟上升...
  • 没有一本教科书会讲到精准,浅显易懂的高精度任意分频原理(至少Bingo没看到过),同时也没有一种设计能用同一个电路实现任意频率的控制。Bingo对于当年做的任意波形发生器时候的相位累加器原理,从中受到启发,总结出...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,342
精华内容 936
关键字:

任意分频电路