使用verilog描述一个可N分频的时钟分频器,输出占空比为50%

N分频器,包括奇分频和偶分频,50%duty。

利用上升沿和下降沿分别生成的分频时钟clk_p,clk_n,占空比为(divisor>>1)/divisor,相或操作后,可以得到占空比50%的奇分频。

利用计数器在(cnt == 0) 和(cnt == (divisor>>1))反转,即可实现偶分频。

module  clk_div(clk_in, rst_n,divisor, clk_out);

	input clk_in;
	input rst_n;
	input [7:0]divisor;	// 分频常数
	output clk_out;

	reg clk_p,clk_n ;	//上升沿和下降沿生成的分频时钟,占空比为(divisor>>1)/divisor,相或操作后可以得到占空比50%的奇分频
	reg clk_even;	//偶分频时钟
	wire clk_in;
	reg [7:0] cnt ;
	wire odd;

	assign odd = divisor[0] & 1'b1;	//奇数odd判断

	always @( posedge clk_in )	 
	if (!rst_n )
		cnt <= 8'd0;
	else if( cnt >= (divisor - 1)) 
		cnt <= 8'd0;
	else 
		cnt <= cnt + 1'b1;
	//奇分频
	always @( posedge clk_in )	 
	if (!rst_n )
		clk_p <=1'b0;
	else if(cnt ==  8'd0)
		clk_p <= 1'b1;
	else if(cnt == (divisor >> 1))
		clk_p <= 1'b0;

	always @(negedge clk_in)
	if (!rst_n )
		clk_n <=1'b0;
	else if(cnt ==  8'd0)
		clk_n <= 1'b1;
	else if(cnt == (divisor >> 1))
		clk_n <= 1'b0;
	//偶分频	
	always @( posedge clk_in )	 
	if (!rst_n )
		clk_even <=1'b0;
	else if(cnt ==  8'd0)
		clk_even <= 1'b1;
	else if(cnt ==(divisor >> 1))
		clk_even <= 1'b0;

	assign clk_out = (odd) ? (clk_p | clk_n) : clk_even;
	
endmodule

仿真代码;

`timescale 1ns/1ns

`define clk_period 20

module  clk_div_tb;

//source define
	reg Clk;
	reg [7 : 0]divisor;
	reg rst_n;
//probe define
	wire clk_out;
//instant user module
	clk_div clk_div(
		.clk_in(Clk), 
		.rst_n(rst_n),
		.divisor(divisor), 
		.clk_out(clk_out)
	);

//generater clock
	initial Clk = 1;
	always #(`clk_period/2) Clk = ~Clk;

	initial begin
		rst_n = 1'b0;
		#20;
		rst_n = 1'b1;
		divisor = 8'd3;
		#(`clk_period * 50) ;		
		divisor = 8'd4;
		#(`clk_period * 50) ;
		divisor = 8'd5;
		#(`clk_period * 50) ;
		divisor = 8'd6;
		#(`clk_period * 50) ;
		divisor = 8'd7;
		#(`clk_period * 50) ;
		divisor = 8'd8;
		#(`clk_period * 50) ;
		$stop;

	end
	
endmodule

 

你可能感兴趣的:(使用verilog描述一个可N分频的时钟分频器,输出占空比为50%)