Verilog实现小数分频(以42.3、1.5MHZ为例)以及按键选择1~10HZ频率可调

一、实验目的与要求

使用Verilog编程实现小数分频,输入时钟信号频率为50MHz,先从50MHz经小数分频得到42.3MHz的时钟信号,进而从42.3MHz时钟分频得到1Hz、2Hz、3Hz、4Hz、5Hz、6Hz、7Hz、8Hz、9Hz、10Hz等10个时钟频率,并将分频后的信号用数码管或显示屏实时显示出来。

二、实验内容

<1>实验原理阐述

注意:利用本例删除信号的方法得到的输出信号波形不满足占空比为50%

小数分频是通过可变分频和多次平均的方法来实现。输入时钟信号频率为f0,期望得到的频率为f1,则其分频比X=(f0/f1),其中X>1,假设M<X<M+1,M为整数,则有X=M+(N2 / (N1+N2) ),其中N1和N2为整数。当N1和N2取不同的正整数时就可以实现小数分频。
利用脉冲删除电路,有规律的删除时钟源中的一些脉冲,从而实现平均意义上的小数分频。在硬件电路的设计过程中,利用脉冲删除电路,不会出现竞争冒险和毛刺的问题,而且可以很容易地用硬件实现任意小数分频。令Q=N1+N2,P=M*(N1+N2)+N2,则X=P/Q,其中P、Q均为整数。当输入时钟源每输入P个脉冲,利用脉冲删除电路从这P个脉冲中按照一定的规律删除P-Q个脉冲,输出Q个脉冲,便实现了平均意义上的X分频。
具体设计思路如下:设置一个计数器,令其初始值为0,在每一个inclk的上升沿,计数器加上Q,若计数器中的值小于P,则发出删除一个脉冲的信号delete,置delete为高电平;若其值大于P,则将计数器的值减去P,并将delete置为低电平,不发出删除信号的脉冲。比如,从50MHz的时钟源得到42.3MHz的时钟信号,则可以令P=26,Q=22,它的工作过程见表1。
表1

8d9dc7d0a6fb4eecafe3e73ed078fd2e.png

三:实验代码

<1>端口定义

input rst,clk50m;
input [3:0] sel;
output reg clk423m;
output reg clk_16m;
output reg clk_ry;
reg delete;
reg [19:0]temp;
integer count,cnt,delete1,count3,count1;
reg [3:0] cnt1,cnt2,cnt3;
reg clk39m;

<2>42.3MHZ分频

1:频率计算:

f=N/(t*10^-12)=5/(120000*10^-12)=41.7MHZ

 如果有表一,且觉得计算P、Q值比较麻烦的读者也可以采取直接删除特定的序号的信号脉冲的方法

//42.3MHZ分频
always@(posedge clk50m or posedge rst)
begin
	if(rst==1)
		begin
			count=0;
			delete=1'b0;//初始化计数器的值
		end
	else
		begin
			count=count+22;
			if(count>=26)
				begin
					count=count-26;
					delete=1'b0;//不删除脉冲
				end
			else
				delete=1'b1;//删除脉冲
		end
end

always@(delete)//根据delete的值判断是否删除脉冲
begin
	if(delete==1'b1)
		clk423m=1'b1;
	else
		clk423m=clk50m;
end

 

2:仿真波形

a341460d2a8d45f98a465c1326ded1c5.png

<3>将42.3MHZ信号分频得到1.6MHZ信号

1:代码展示

/1.6MHZ分频
always@(posedge clk423m or posedge rst)     //实现1.6MHZ分频
begin
	if(rst)
		begin
			count1=0;delete1=1'b0;
		end
	else
		begin
			count1=count1+390;
			if(count1>=423)
				begin
					count1=count1-423;
					delete1=1'b0;     //不删除脉冲
				end
			else
				delete1=1'b1;     //删除1个脉冲
		end
end

always@(delete1)
begin
	if(delete1==1'b1)
		clk39m=1'b1;
	else
		clk39m=clk423m;
end

always@(posedge clk39m or posedge rst)
begin
  if(rst==1)
  begin
    clk_16m <= 0;count3=0;
  end
  else if(count3==9)
  begin
    clk_16m <= ~clk_16m;
	 count3 <= 0;
  end
  else
  begin
    count3 <= count3 + 1;
  end
	
end

2:实物波形效果展示

67f738b0b157406391d6d737003e1538.png

注:输出为1.66MHZ方波,波形失真可能是因为高低电平翻转时计数值过大,持续时间过长导致;

<4>将1.6MHZ分频得到1~10HZ信号

//1-10HZ任意分频	可调
always@(posedge clk_16m or posedge rst)
begin
  if(rst==1)
  begin
    clk_ry <= 0;
  end
  else if(cnt==1048576)
  begin
    clk_ry <= ~clk_ry;
	 cnt <= temp;
  end
  else
  begin
    cnt <= cnt + 1;
  end
	
end

<5>按键调控分频结果(1~10HZ)

1:代码展示

always @ (sel)
begin
   case(sel)
			 
			4'b0001:temp <= 298576;
			 
			4'b0010:temp <= 673576;
			
			4'b0011:temp <= 798576;
			
			4'b0100:temp <= 816076;
			 
			4'b0101:temp <= 898576;
			 
			4'b0110:temp <= 923576;
			
			4'b0111:temp <= 941433;
			 
			4'b1000:temp <= 954826;
			
			4'b1001:temp <= 965243;
			
			4'b1010:temp <= 973576;
			
			default:temp <= 1048574;
	 endcase
					    
end

2:实物效果展示(以6HZ为例)

1c56c74fd1a8455e87c30127fadf73ab.png

四:完整代码展示 

module fengping_432(rst,clk50m,clk423m,clk_15m,clk_ry,sel);
input rst,clk50m;
input [3:0] sel;
output reg clk423m;
output reg clk_15m;
output reg clk_ry;
reg delete;
reg [19:0]temp;
integer count,cnt,delete1,count3,count1;
reg [3:0] cnt1,cnt2,cnt3;
reg clk39m;


//42.3MHZ分频
always@(posedge clk50m or posedge rst)
begin
	if(rst==1)
		begin
			count=0;
			delete=1'b0;//初始化计数器的值
		end
	else
		begin
			count=count+22;
			if(count>=26)
				begin
					count=count-26;
					delete=1'b0;//不删除脉冲
				end
			else
				delete=1'b1;//删除脉冲
		end
end

always@(delete)//根据delete的值判断是否删除脉冲
begin
	if(delete==1'b1)
		clk423m=1'b1;
	else
		clk423m=clk50m;
end

//1.5MHZ分频
always@(posedge clk423m or posedge rst)     //实现1.5MHZ分频
begin
	if(rst)
		begin
			count1=0;delete1=1'b0;
		end
	else
		begin
			count1=count1+390;
			if(count1>=423)
				begin
					count1=count1-423;
					delete1=1'b0;     //不删除脉冲
				end
			else
				delete1=1'b1;     //删除1个脉冲
		end
end

always@(delete1)
begin
	if(delete1==1'b1)
		clk39m=1'b1;
	else
		clk39m=clk423m;
end

always@(posedge clk39m or posedge rst)
begin
  if(rst==1)
  begin
    clk_15m <= 0;count3=0;
  end
  else if(count3==9)
  begin
    clk_15m <= ~clk_15m;
	 count3 <= 0;
  end
  else
  begin
    count3 <= count3 + 1;
  end
	
end

                                                                            
//1-10HZ任意分频	可调
always@(posedge clk_15m or posedge rst)
begin
  if(rst==1)
  begin
    clk_ry <= 0;
  end
  else if(cnt==1048576)
  begin
    clk_ry <= ~clk_ry;
	 cnt <= temp;
  end
  else
  begin
    cnt <= cnt + 1;
  end
	
end

//用来控制显示1-10HZ分频
always @ (sel)
begin
   case(sel)
			 
			4'b0001:temp <= 298576;
			 
			4'b0010:temp <= 673576;
			
			4'b0011:temp <= 798576;
			
			4'b0100:temp <= 816076;
			 
			4'b0101:temp <= 898576;
			 
			4'b0110:temp <= 923576;
			
			4'b0111:temp <= 941433;
			 
			4'b1000:temp <= 954826;
			
			4'b1001:temp <= 965243;
			
			4'b1010:temp <= 973576;
			
			default:temp <= 1048574;
	 endcase
					    
end
		
endmodule

 

 

 

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值