任意整数分频器

1.偶数分频器

假设N分频器,N是偶数,

        第一种思路

        (1)复位信号时,计数器清零,输出时钟置低电平

        (2)计数器到 N/2 - 1 时,时钟翻转,计数器继续累加

        (3)计数器到 N-1 时,时钟翻转,计数器清零

        (4)计数器在其他值是输出保持,计数器继续累加

        这种思路的思想是,在计数器为 0 ~N/2 -1 时,输出时钟保持一个状态N/2~N-1时保持另一个状态。

        比如8分频,1~4这四个原始T内,为低电平,此时计数器为0~3 

                            5~8这四个原始T内,为高电平,此时计数器为4~7

        至此,产生了一个8分频的输出时钟

        第二种思路

        (1)复位信号时,计数器清零,输出时钟置低电平

        (2)计数器到 N/2 - 1 时,时钟翻转,计数器清零

        (3)计数器为其余值时,继续保持加一

这种思路的思想是,在计数器为 0 ~N/2 -1 时,输出时钟保持一个状态在计数器为下一个0 ~N/2 -1 时保持另一个状态。

        比如8分频,1~4这四个原始T内,为低电平,此时计数器为0~3 

                            5~8这四个原始T内,为高电平,此时计数器为0~3        

2.奇数分频器

假设N分频器,N是奇数

        (1)上升沿计数器 cnt_p,在0~(N-1)/ 2 之间 为一个电平,(N+1)/ 2到N-1之间为另一个电平,得到clk_p

        (2)下降沿计数器 cnt_n,在0~(N-1)/ 2 之间 为一个电平,(N+1)/ 2到N-1之间为另一个电平,得到clk_n

        (3)将两个时钟进行或运算即可得到clk_odd

rtl代码

module freq_div(
				clk_in,
				rst_n,
				clk_out
			   );            

	localparam	div_width = 3,			//分频计数器位宽
				fre_div = 7; 			//分频数
	
	input	wire	clk_in	;
	input	wire	rst_n	;
	output	wire	clk_out	;
	/*	偶数分频参数	*/	
	reg 	clk_even;
	reg 	[div_width-1:0]		clk_even_cnt;	
	/*	奇数分频参数	*/
	reg 	clk_1,clk_2;				//上升沿和下降沿时钟
	wire	clk_odd;
	reg 	[div_width-1:0]		clk_1_cnt	,	clk_2_cnt;		//奇数计数器

assign	clk_out = (fre_div == 1'b1)? clk_in : (fre_div[0]? clk_odd : clk_even); //输出
assign	clk_odd = clk_1 | clk_2;

//偶数分频情况
always @ (posedge clk_in or negedge rst_n)
	begin
        if (!rst_n)
            begin
                clk_even <= 1'b0;
                clk_even_cnt <= 3'd0;
            end
        else if (clk_even_cnt == fre_div/2-1)
            begin
	            clk_even <= ~clk_even;
                clk_even_cnt <= clk_even_cnt + 1'b1;
            end
        else if (clk_even_cnt == fre_div - 1)
            begin
	            clk_even <= ~clk_even;
   	            clk_even_cnt <= 3'd0;
            end
        else
            begin
             	clk_even <= clk_even;
   		        clk_even_cnt <= clk_even_cnt + 1'b1;
            end
	end

//奇数分频情况
always @ (posedge clk_in or negedge rst_n)		//上升沿产生分频时钟
	begin
		if (!rst_n)
			begin
				clk_1 <= 1'b0;
				clk_1_cnt <= 3'd0;
			end
		else if (clk_1_cnt  == (fre_div-1)/2)		//低电平时间比高电平时间多一个周期
            begin
				clk_1 <= ~clk_1;
				clk_1_cnt  <= clk_1_cnt + 1'b1;
			end
		else if (clk_1_cnt  == fre_div - 1)
            begin
		        clk_1 <= ~clk_1;
    		    clk_1_cnt  <= 3'd0;
		    end
		else
            begin
		        clk_1 <= clk_1;
    		    clk_1_cnt  <= clk_1_cnt  + 1'b1;
		    end
	end

always @ (negedge clk_in or negedge rst_n)			//下降沿产生分频时钟
	begin
		if (!rst_n)
			begin
				clk_2 <= 1'b0;
				clk_2_cnt <= 3'd0;
			end
		else if (clk_2_cnt  == (fre_div-1)/2)
            begin
				clk_2 <= ~clk_2;
				clk_2_cnt  <= clk_2_cnt + 1'b1;
			end
		else if (clk_2_cnt  == fre_div - 1)
            begin
		        clk_2 <= ~clk_2;
    		    clk_2_cnt  <= 3'd0;
		    end
		else
            begin
		        clk_2 <= clk_2;
    		    clk_2_cnt  <= clk_2_cnt  + 1'b1;
		    end
	end
endmodule

testbench代码

`timescale 1ns/100ps
module tb();            

	reg 	clk_in	;
	reg		rst_n	;
    wire	clk_out	;
    
    parameter   DELAY   =   18.5 ;
    
    always #10  clk_in=~clk_in ;
    
    initial
    begin
        rst_n=0;
        clk_in=0;
    #DELAY  rst_n=1;
    #300    $stop;
    end
    
    freq_div U_freq_div(.clk_in(clk_in),
                        .rst_n(rst_n),
                        .clk_out(clk_out)
                        );

endmodule

7分频仿真波形图

 3.任意整数分频器

        在有了奇偶分频器的基础上,只需要通过修改parameter中的 计数器位数与分频数N就可得到占空比为50%的任意整数分频器。

        比如50Mhz时钟分频到880Khz,通过相除可以得到N为625,此时可以通过计算得到cnt计数器的位宽为10位,因此设计时只需要把div_width调成10,fre_div调成625,即可实现该分频。

4.占空比非50%整数分频器

        上边的分频器都是基于50%占空比的整数分频器,如果要实现非均匀占空比,比如还是上边的50Mhz变成30%占空比的880Khz时钟。(占空比是指高电平在一个周期中持续的时间比例)

        (1)计算625*30%=187.5

因此设计时,可以复位时输出时钟为低,计数器从0计数到187时,另输出电平为高,187~625时为低,计数到625计数器清零。继续下一个周期的计数。(如有错误请指正)

5.小数分频器

        小数分频器,在阅读了一些csdn博客之后,我所理解的就是小数分频,比如19/9分频,是通过原始时钟的19*T_origin凑出输出时钟的9*T_out  [1] 。分解成若干个奇分频和偶分频的组合

        这里我找到一个二元一次方程

        n*No+m*Ne=19

        n+m=9

No为奇分频的N,Ne为偶分频的N

我们令No=3,Ne=2,则n=1,m=8 ;

理论上No和Ne的选择可以有多组解

至此19/9分频,就是用8个二分频和1个三分频去凑出9个周期。如图[1]

 这里可以看到9个周期的时钟是先1个三分频然后8个二分频。

优点是算法简单。
缺点是占空比不是50%,因为2分频和3分频交叉组合而成,所以周期性抖动较差。

ACC计数器设计[2]

ACC计数器就是控制做N次ZN分频和M次ZN+1次分频,具体控制过程可以分为以下几种情况:

第1种情况 :先做N次ZN分频,再做M次ZN+1次分频;

第2种情况: 先做M次ZN+1次分频,再做N次ZN分频;

第3种情况 :把N次ZN分频平均插入到M次ZN+1分频中;

第4种情况 :把M次ZN+1次分频平均插入到N次ZN分频中。

组合N次ZN分频和M次ZN+1次分频的情况很多。第1、2种情况前后时钟频率不太均匀,因此相位抖动比较大;

第3、4种情况前后时钟频率均匀性稍好,因此相位抖动会减小

参考链接:

[1] (40条消息) verilog任意小数分频的实现_学而不思则罔,思而不学则殆-CSDN博客_小数分频

[2] 时钟分频系列——分数分频电路的Verilog实现 (qq.com)

  • 1
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值