Verilog分频器

本文介绍了数字逻辑设计中的分频器概念,包括偶数分频器和奇数分频器的工作原理。对于偶数分频,通过计数器在上升沿触发输出信号翻转来实现;奇数分频则需要考虑额外的下降沿信号,通过与或运算生成占空比为50%的分频信号。文中提供了Verilog代码实例,展示了如何实现不同占空比的偶数分频器和奇数分频器。
摘要由CSDN通过智能技术生成

分频器是对系统始终或其他时钟进行分频产生所需要的时钟信号;
首先从偶数分频器入手,最简单的二分频,就是在原时钟的上升沿进行输出信号翻转即可。
如果要实现4分频呢?就要用到计数器,在计数器计到2个上升沿的时候进行输出信号翻转。
现在对一般偶数分频器进行分析,N为偶数的时候,计数器进行上升沿技术。计数器的范围为0-(N-1),在0-N范围内选一个值K,分出两个范围选择输出信号的状态,当cnt在0~K范围内时,为低电平;在(K+1)-(N-1)范围内为高电平,因此输出占空比(N-1-K)/N,以下例子统一用50%占空比。
奇数分频器,先从最简单的三分频入手,首先还是按照偶数分频的思想去操作,发现计数器需要计算3/2=1.5个周期,输出信号再进行翻转,因此计数器上升沿计数这样操作就得不到结果,所以这种分频方法就不行。正确思路:取两路上升沿和下降沿信号,然后对这两路信号取或。具体是,使用计数器在0-2之间循环计数,控制输出1个高电平,2个低电平的信号1,然后把信号1延迟半个周期得到信号2,最后信号1与信号2相与得到50%占空比的3分频信号。
奇数分频N,使用计数器cnt在0-(N-1)之间循环计数,输出N-1/2个高电平,N+1/2个低电平的clk1信号,延时半个周期,得到clk2信号,clk_out=clk1 | clk2;或者输出N+1/2个高电平,N-1/2个低电平的clk1,延时半个周期,clk_out=clk1 & clk2;

偶数分频(任意占空比)代码:

module clk_div (
	//system signals
	input						   clk	  , 
	input						   rst    ,
	//
	output   reg                   clk_out 
);

parameter N=8,K=3;       
reg [3:0] cnt;


always @(posedge clk or posedge rst) begin
	if (rst) begin
      clk_out <= 1'b0;
	end
	else if(cnt == K) begin
		clk_out <= 1'b1;
	end
	else if (cnt == (N-1))begin
		clk_out <=1'd0;
	end
	        
end

always @(posedge clk or posedge rst) begin
	if (rst) begin
		cnt <= 0;
		
	end
	else if (cnt == (N-1)) begin
		cnt <= 0;
	end
	else begin
		cnt <= cnt+1;
	end
end

endmodule

奇数分频代码:

module clk_div (
	//system signals
	input						      clk	  , 
	input						      rst     ,
  
	//
	output    [3:0]            cnt1    ,   
	output   reg               clk1    ,
	output   reg               clk2    ,
	output                     clk_out 
);

parameter N=7;       
reg [3:0] cnt;


always @(posedge clk or posedge rst) begin
	if (rst) begin
      clk1 <= 1'b0;
	end
    else begin
    	if(cnt == (N-1)>>1) begin
		   clk1 <= 1'b1;
	    end
	    else if (cnt == (N-1))begin
		   clk1 <=1'd0;
	    end
        else begin
           clk1 <= clk1;       	
        end       
    end     
end

always @(negedge clk or posedge rst) begin
	if (rst) begin
		clk2 <= 1'b0;
	end
	else begin 
		clk2<=clk1;
   end
end

always @(posedge clk or posedge rst) begin
	if (rst) begin
		cnt <= 0;
		
	end
	else if (cnt == (N-1)) begin
		cnt <= 0;
	end
	else begin
		cnt <= cnt+1'b1;
	end
end

assign cnt1 = cnt;
assign clk_out = clk1|clk2;
endmodule

测试代码(共用):

`timescale 1ns/1ps

module clk_div_tb ;
	//system signals
	reg						clk		; 
	reg						rst		;
	
	wire  [3:0]           cnt1       ;
	wire                  clk1     ;
	wire                  clk2     ;
	wire                 clk_out  ;


  
  initial begin
    clk = 0;
    forever #10 clk = ~clk;
  end

  initial begin
  	rst = 0;
  	#20 rst = 1;
  	#20 rst = 0; 
  end
 
  clk_div u_clk_div( .clk(clk), .rst(rst), .cnt1(cnt1), .clk1(clk1), .clk2(clk2), .clk_out(clk_out) );  
endmodule
  • 3
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值