loves6036

Verilog HDL分频

0
阅读(2754)

1.偶数分频

        偶分频可用计数器的方法实现,例如进行N分频,可计一个计数器,当计数到N/N-1时,对时钟信号取反,即可满足要求。如下二分频代码,只需取计数器的最低位 cnt[ 0 ] 变化即可:

 

	module fp_verilog_2(
						clk,rst_n,
						clk_div
						);
						
input clk;  
input rst_n;
output clk_div;

/*******************************************/
reg [1:0] cnt;

always @(posedge clk or negedge rst_n)
	if(!rst_n) cnt <= 2'd0;
	else cnt <= cnt + 1'b1;

/********************************************/

reg clk_div_r;

always @(posedge clk or negedge rst_n)
	if(!rst_n) clk_div_r <=1'b0;
	else clk_div_r <= cnt[0];
/**********************************************/

assign clk_div =clk_div_r;

endmodule
使用MModelSim-Altera仿真波形:
 
 
Quartus II    RTL视图:
2.奇数分频
奇数分频也是通过计数器实现的,如三分频,就可以通过时钟的上升沿触发来进行计数,当计数器计到邻近的值时进行两次翻转。比如可以在计数器计到1时,输出时钟进行翻转,计数到2是再次翻转,这样,就在计数值邻近的1和2进行了2次翻转。如此可实现三分频,其占空比为1/3或者2/3。
如占空比为2/3的代码:
	module fp_verilog_3(
							clk,rst_n,
							clk_out
						);
						
input clk;
input rst_n;
output clk_out;

//--------------------------------------------------------
reg [1:0] cnt1;

always @ (posedge clk or negedge rst_n)
	if(!rst_n) cnt1 <= 1'd0;
	else if(cnt1 == 2'b10) cnt1 <= 1'd0;
	else cnt1 <= cnt1 + 1'b1;
	
//--------------------------------------------------------

reg qout1;

always @ (posedge clk or negedge rst_n)
	if(!rst_n) qout1 <= 1'b0;
	else if(cnt1 == 2'b10) qout1 <= 1'd1;
	else qout1 <= 1'd0;
	
//---------------------------------------------------------

assign clk_out = qout1;

endmodule

 使用ModelSim_Altera仿真波形:
	如果要实现占空比为50%的三分频时钟的话,则可通过待分频时钟下降沿触发计数,并以和上升沿同样的方法进行计数三分频,然后对下降沿三分频时钟和上升沿时钟相或:
占空比为50%的三分频代码:
	module fp_verilog_3(
							clk,rst_n,
							clk_out
						);
						
input clk;
input rst_n;
output clk_out;

//--------------------------------------------------------
reg [1:0] cnt1,cnt2;

always @ (posedge clk or negedge rst_n)
	if(!rst_n) cnt1 <= 1'd0;
	else if(cnt1 == 2'b10) cnt1 <= 1'd0;
	else cnt1 <= cnt1 + 1'b1;
	
//--------------------------------------------------------

reg qout1;

always @ (posedge clk or negedge rst_n)
	if(!rst_n) qout1 <= 1'b0;
	else if(cnt1 == 2'b10) qout1 <= 1'd1;
	else qout1 <= 1'd0;
	
//---------------------------------------------------------

always @ (negedge clk or negedge rst_n)
	if(!rst_n) cnt2 <= 1'd0;
	else if(cnt1 == 2'b10) cnt2 <= 1'd0;
	else cnt2 <= cnt2 + 1'b1;
//---------------------------------------------------------
reg qout2;

always @ (negedge clk or negedge rst_n)
	if(!rst_n) qout2 <= 1'b0;
	else if(cnt2 == 2'b10) qout2 <= 1'd1;
	else qout2 <= 1'd0;
//---------------------------------------------------------
assign clk_out = qout1 || qout2;

endmodule

使用ModelSim-Altera仿真波形:
	RTL视图: