Verilog 时钟偶分频、奇分频、任意分频

分频器是指使输出信号频率为输入信号频率整数分之一的电子电路。

偶分频计数器
偶分频比较简单,假设为N分频,只需计数到N/2-1,然后时钟翻转、计数清零,如此循环就可以得到N(偶)分频。代码如下:

module even_divider(
   clk_in,
   Rst_n,
   even_en,//偶分频使能信号,方便后续设计任意分频计数器
   div,
   clk_out
);
 input clk_in;//时钟输入
 input Rst_n;//异步复位 低有效
 input even_en;//偶分频使能信号,方便后续设计任意分频计数器
 input [3:0]div;//分频值,此处设计分频范围为1-63
 
 output reg clk_out;//分频后,时钟输出
 
 reg [3:0]div_cnt;//分频计数器
 always@(posedge clk_in or negedge Rst_n)
 if(!Rst_n) begin 
 	 div_cnt <= 4'd0;
  	 clk_out <= 0;
 	 end
 else if(even_en) begin
  	if(div_cnt == (div/2 - 1'b1)) begin
 		  div_cnt <= 4'd0;
  		 clk_out <= ~clk_out;
   		end
  	else begin
   		div_cnt <= div_cnt + 1'b1;
 	  	clk_out <=  clk_out; 
   		end
 	 end
 else begin
 	 div_cnt <= 4'd0;
  	 clk_out <=  0;
 end    
endmodule 

奇分频计数器
实现奇数N分频,分别用上升沿计数到(N-1)/2,时钟翻转,再计数到N-1,时钟翻转;用下降沿计数到(N-1)/2,时钟翻转,再计数到N-1,时钟翻转,得到两个波形,然后把它们相或即可得到N分频。代码如下:

module odd_divider(
		   clk_in,
		   Rst_n,
		   odd_en,
		   div,
		   clk_p,
		   clk_n,
		   clk_out
		   );
	 input clk_in;//时钟输入
	 input Rst_n;//异步复位,低电平有效
	 input odd_en;//奇分频使能信号
	 input [3:0]div;//分频系数
	 output reg clk_p;//上升沿计数,时钟输出
	 output reg clk_n;//下降沿计数,时钟输出
	 output  clk_out;//奇分频时钟输出
  
  reg [3:0]cnt_p,cnt_n;//分频计数器
 always@(posedge clk_in or negedge Rst_n)
 if(!Rst_n) 
  	cnt_p <= 4'd0;
 else if(odd_en == 1) begin
	if(cnt_p == (div - 1'b1))
		cnt_p <= 4'd0;
	 else 
	  	cnt_p <= cnt_p + 1'b1; 
	end
 else
 	cnt_p <= 4'd0;
  
 always@(posedge clk_in or negedge Rst_n)
 if(!Rst_n)  
  	clk_p <= 0;
 else if(cnt_p == (div-1'b1)/2)
  	clk_p <= ~clk_p;
 else if(cnt_p == (div-1'b1))
  	clk_p <= ~clk_p;
 else
 	 clk_p <= clk_p;
 
  always@(negedge clk_in or negedge Rst_n)
 if(!Rst_n) 
  	cnt_n <= 4'd0;
 else if(odd_en == 1) begin
  		if(cnt_n == (div - 1'b1))
   		cnt_n <= 4'd0;
 	else 
  	 	cnt_n <= cnt_n + 1'b1; 
  	end
 else
  	cnt_n <= 4'd0; 
  
 always@(negedge clk_in or negedge Rst_n)
 if(!Rst_n)  
  	clk_n <= 0;
 else if(cnt_n== (div-1'b1)/2)
  	clk_n <= ~clk_n;
 else if(cnt_n == (div-1'b1))
  	clk_n <= ~clk_n;
 else
  	clk_n <= clk_n; 
 
 	assign clk_out =  clk_p  |  clk_n;
 endmodule

任意分频计数器
通过顶层文件例化上述偶分频计数器模块和奇分频计数器模块即可实现任意分频。

module clk_divider(
   clk,
   Rst_n,
   div,
   clk_div
   );
 
 input clk;
 input Rst_n;
 input [3:0]div;
 
 output clk_div;
 
 wire odd_en;
 wire clk_even;
 wire clk_odd;
 
 assign odd_en = div[0]?1'b1:1'b0;//判断分频系数的奇偶
 assign clk_div = div[0]?clk_odd:clk_even;//根据分频奇偶确定输出
 
 even_divider even_divider(
     .clk_in(clk),
     .Rst_n(Rst_n),
     .even_en(!odd_en),
     .div(div),
     .clk_out(clk_even)
  );
 
 
 odd_divider odd_divider(
   .clk_in(clk),
   .Rst_n(Rst_n),
   .odd_en(odd_en),
   .div(div),
   .clk_p(),
   .clk_n(),
   .clk_out(clk_odd)
   );
   
endmodule

RTL视图在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值