常用电路设计之分频器的设计

引言

     分频器在实际数字电路设计中是最基础的,也是最重要的。常见的分频器主要有偶数倍分频器,奇数倍分频器,半整数倍分频器,任意小数倍分频器等。本文主要对最常用的偶数倍分频器和奇数倍分频器展开介绍。

1、偶数倍分频器

      偶数倍分频器通过计数器可以很简单的实现。基本原理就是如果要进行N倍偶数分频,那么就可以利用待分频的时钟触发计数器,当计数器从0计数到N/2-1的时候,输出时钟翻转一次,并复位计数器,这样循环往复,就可以得到N倍偶数分频,如下图所示就是一个标准的4分频时序图。

2、奇数倍分频器

      奇数倍分频器通过计数器也很容易实现。 对于占空比为非50%的奇数倍分频而言,如果要实现N倍奇数分频,那么就可以利用待分频时钟上升沿触发计数器进行模N计数,计数到到某个值进行时钟翻转,然后再经过(N-1)/2个计数值再进行翻转,如下图所示为一个标准的5倍占空比非50%分频器时序图。

       如果要实现占空比为50%的奇数倍分频,就需要用待分频时钟的下降沿去触发计数器,其他原理一样,然后将两个时钟相或即可,如下图所示为一个标准的5倍占空比50%分频器的时序图。

 3、Verilog代码分享

       顶层文件:

module fre_div (
	//system signals
	input				clk				, 
	input				rst_n				,
	//
	output		reg     fre_div_4			,	
	output      reg     fre_div_5_1         ,
    output      reg     fre_div_5_2         ,
    output      fre_div_5_3         
);
reg 			[0:0]		count_4			;
reg 			[2:0]		count_5_1		;
reg 			[2:0]		count_5_2		;
always @(posedge clk or negedge rst_n) begin
	if (!rst_n) begin
		// reset
		count_4 <= 1'd0;
	end
	else begin
		if (count_4 == 1'd1) 
			count_4 <= 1'd0;
		else 
			count_4 <= count_4 + 1'b1;
	end
end
always @(posedge clk or negedge rst_n) begin
	if (!rst_n) begin
		// reset
		fre_div_4 <= 1'b0;
	end
	else if(count_4 == 1'd1) 
			fre_div_4 <= ~fre_div_4;
		 else
		 	fre_div_4 <= fre_div_4;
end

always @ (posedge clk or negedge rst_n) begin
	if(!rst_n)
		count_5_1 <= 3'd0;
	else begin
		if (count_5_1 == 3'd4) 
			count_5_1 <= 3'd0;
		else 
			count_5_1 <= count_5_1 + 1'b1;
	end    
end
always @ (posedge clk or negedge rst_n) begin
	if(!rst_n)
		fre_div_5_1 <= 1'b0;
	else begin
		if (count_5_1 == 3'd1) 
			fre_div_5_1 <= ~fre_div_5_1;
		else if (count_5_1 == 3'd3) 
		    	fre_div_5_1 <= ~fre_div_5_1;
			else 
		   		fre_div_5_1 <= fre_div_5_1;
	end	
end
always @ (negedge clk or negedge rst_n) begin
	if(!rst_n)
		count_5_2 <= 3'd0;
	else begin
		if (count_5_2 == 3'd4) 
			count_5_2 <= 3'd0;
		else 
			count_5_2 <= count_5_2 + 1'b1;
	end    
end
always @ (negedge clk or negedge rst_n) begin
	if(!rst_n)
		fre_div_5_2 <= 1'b0;
	else begin
		if (count_5_2 == 3'd1) 
			fre_div_5_2 <= ~fre_div_5_2;
		else if (count_5_2 == 3'd3) 
		    	fre_div_5_2 <= ~fre_div_5_2;
			else 
		   		fre_div_5_2 <= fre_div_5_2;
	end	 
end
assign fre_div_5_3 = fre_div_5_1|fre_div_5_2;
endmodule

           测试文件:

`timescale 1ns/1ps
module tb ();
 
reg clk;
reg rst_n;
wire fre_div_4;
wire fre_div_5_1;
wire fre_div_5_2;
wire fre_div_5_3;
initial
begin
	clk = 1'b1;
	rst_n = 1'b1;
	#5 rst_n = 1'b0;
	#5 rst_n = 1'b1;
end
always #5 clk = ~clk;
fre_div demo(
	//system signals
	.clk(clk), 
	.rst_n(rst_n),
	.fre_div_4(fre_div_4),
	.fre_div_5_1(fre_div_5_1),
	.fre_div_5_2(fre_div_5_2),
	.fre_div_5_3(fre_div_5_3)
);
endmodule

          完整仿真结果:

常用电路设计之分频器的设计_第1张图片

你可能感兴趣的:(FPGA-Zynq7000)