【无标题】

本文详述了一项使用Verilog语言在FPGA平台上实现的功能数字钟设计。该钟具备准确授时、校准和报时功能,包括星期、小时、分钟和秒的显示。通过QuartusII和Verilog,设计了计时、校时、报时和显示四个主要模块。在报时过程中,能模拟“滴答”声效。实验结果显示,数字钟能正确计时并切换显示星期,且支持手动校准。该实验加深了对Verilog语法和系统设计的理解。
摘要由CSDN通过智能技术生成

功能数字钟

实验目的

​ (1)在FPGA中实现具有以下功能的数字钟:准确授时;校准功能;准确报时。

​ (2)掌握在用Verilog语言编写代码时的语法结构。

​ (3)理解程序设计的逻辑结构。

分析设计平台及工具

​ Quartus II集成开发环境、Verilog语言、FPGA开发板等。

实验设计思路

​ 从实验目的我们可以知道该功能数字钟系统包括以下几个功能模块:授时、报时、校准。

​ 同时根据实验要求,在进行授时的时候,包括时、分、秒和星期的授时,其中分、秒位60进制,时为24进制,周为七进制。

​ 在进行报时的过程中,要求在到达整点时,先每隔两秒发出“滴”声,随后在整点时,发出“嗒”声。然后通过改变输送到蜂鸣器的导通信号的频率,来改变蜂鸣器发声的频率,控制蜂鸣器产生“嘀、嗒”的报时声。

​ 在进行授时的过程中,通过50MHz的基准时钟信号的输入,将50M分频得到1Hz的数字工作频率CLK_1Hz,来控制钟表的授时。

​ 在进行校准的过程中,通过DisoWeek_n控制星期显示输出信号,通过AdjWeek、AdjtHour 、AdjtMin来进行星期、小时、和分钟的调节。当 AdjtWeek=1 时,每来一个标准秒脉冲 CLK_1HZ 的上升沿,星期增加基于一天。

​ 在进行时间的显示时,Digitron_Out控制七段数码管的显示输出,共有八位总线。DigitronCS_Out为数码管的片选信号,共有六位总线。也称七段数码管的扫描驱动信号,扫描频率为 250KHz。

​ 所以,根据其功能类别和实验要求,可以得出,实现功能数字钟需要以下几个模块:即计时模、校时模块、报时模块和数码显示模块。图2.1为系统原理示意图。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gfj93Yti-1656149962631)(C:\Users\ZanZhiYun\Desktop\数电实验2\2_1.png)]

​ 如上述原理图,我们在进行Verilog语言进行编辑程序设计的时候,需要接口AdjWeek来调整星期,需要接口AdjHour来调整小时,需要接口AdjMin来调整分钟。同时,由于FPGA开发板上只有6个数码管,不足以将时分秒和星期全部展示出来,所以用到DispWeek来展示星期界面。

​ 接口函数Digitron_Out(),DigitronCS_Out()是进行数码的展示输出的设计,而Buzzer_Out()是用来进行蜂鸣器的设计。

​ 通过以上原理介绍,我们可以划分一下设计模块,如图2.2所示。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EVWR0L5r-1656149962634)(C:\Users\ZanZhiYun\Desktop\数电实验2\2_2.png)]

程序设计分析

​ 在程序设计分析这一节,我截取了不同模块的关键代码部分进行了代码功能分析。

clock.v模块

​ 该代码框架实现的是顶层模块对底层模块的调用。

module clock
(
 );
 endmodule

U1,U2,U3实现的是clock.v对底层模块的调用。

TimeKeeper_module U1
(
);
Digitron_TimeDisplay_module U2
(
);
Buzzer_module U3
(
);

TimeKeeper_module.v

​ 当时钟信号处于上升沿时,如果计数器的值为T1HZ对应该电平状态最后一个点值时,Count置零,同时CLK_1HZ置为与原电平相反的电平值;如果计数器为其他值,则当达到敏感条件(即CLK处于上升沿)时,Count+1。

always @ ( posedge CLK )
		begin 
			if( Count == T1HZ - 25'b1 )
				begin
					Count <= 0;
					CLK_1HZ <= ~CLK_1HZ;
				end
			else
				Count <= Count + 1;
		end

​ 当处于时钟信号上升沿或者处于复位信号下降沿时,如果复位信号为低电平,则各时间的各位恢复设定值,如果复位信号不是低电平,则当有时间调整信号时,则进行时间调整,同时通过判断语句进行时分秒和周的进位。

	always @ ( posedge CLK_1HZ or negedge RSTn )
		begin
			if( !RSTn )
				begin 
					SecL <= 0;
					SecH <= 0;
					MinL <= 0;
					MinH <= 0;
					HourL <= 0;
					HourH <= 0;
					Week <= 1;
				end
			else
				begin
					if( AdjtWeek == 1 )		//While AdjtWeek = 1, Adjust Week
						begin  
							if( Week == 'd7 )
								Week <= 1;
							else
								Week <= Week + 1;
						end
					else if( AdjtHour == 1 )		//Adjust Hour
						begin 
							if( HourL == 'd9 )
								begin
									HourL <= 0;
									HourH <= HourH + 1;
								end
							else
								begin
									if( HourH == 'd2 && HourL == 'd3 )
										begin
											HourL <= 0;
											HourH <= 0;
										end
									else
										HourL <= HourL + 1;
								end
						end
					else if( AdjtMin == 1 ) 		//Adjust Minute
						begin
							if( MinL == 'd9)
								begin
									MinL <= 0;
									if(MinH == 'd5)
										MinH <= 0;
									else
										MinH <= MinH + 1;
								end					
							else 
								MinL <= MinL + 1;	
						end
					else if( SecL == 'd9 )		//Clock is Working
					//......(此处略)

Digitron_TimeDisplay_module.v

parameter进行对预输出的11位数进行数码管编码的定义。

parameter _0 = 8'b0011_1111, _1 = 8'b0000_0110, _2 = 8'b0101_1011,
			 	  _3 = 8'b0100_1111, _4 = 8'b0110_0110, _5 = 8'b0110_1101,
			 	  _6 = 8'b0111_1101, _7 = 8'b0000_0111, _8 = 8'b0111_1111,
				  _9 = 8'b0110_1111, _Ri= 8'b0111_1111;

​ 当时钟信号处于上升沿时,如果DispWeek_n处于低电平或者AdjtWeek处于高电平,六只数码管只显示最右边的第一个数码管。然后通过case列举7种情况,对应一周的7天。对于Count=100MS的情况而言,W_DigitronCS_Out = {…}用于六个数码管每隔100ms进行移位数值刷新。如果无操作动作的话,则Count计数循环加1,等到下一次操作输入,或下一轮的数码管刷新。

always @ ( posedge CLK )
begin
if( (DispWeek_n == 0) || (AdjtWeek == 1) ) //Digitron Display Week
begin
W_DigitronCS_Out = 6’b11_1110;
SingleNum = Week;

				case(SingleNum)
					'd0:  W_Digitron_Out = _0;
					'd1:  W_Digitron_Out = _1;
					'd2:  W_Digitron_Out = _2;
					'd3:  W_Digitron_Out = _3;
					'd4:  W_Digitron_Out = _4;
					'd5:  W_Digitron_Out = _5;
					'd6:  W_Digitron_Out = _6;
					'd7:  W_Digitron_Out = _Ri;
				endcase
			end
		else if( Count == T100MS )
			begin
				Count <= 23'd0;
				W_DigitronCS_Out = {W_DigitronCS_Out[0],W_DigitronCS_Out[5:1]};
				if(W_DigitronCS_Out == 6'd0) 
					W_DigitronCS_Out = 6'b11_1110;
 
				case(W_DigitronCS_Out)
					6'b11_1110: SingleNum = SecL;
					6'b11_1101: SingleNum = SecH;
					6'b11_1011: SingleNum = MinL;
					6'b11_0111: SingleNum = MinH;
					6'b10_1111: SingleNum = HourL;
					6'b01_1111: SingleNum = HourH;
				endcase
 
				case(SingleNum)
					'd0:  W_Digitron_Out = _0;
					'd1:  W_Digitron_Out = _1;
					'd2:  W_Digitron_Out = _2;
					'd3:  W_Digitron_Out = _3;
					'd4:  W_Digitron_Out = _4;
					'd5:  W_Digitron_Out = _5;
					'd6:  W_Digitron_Out = _6;
					'd7:  W_Digitron_Out = _7;
					'd8:  W_Digitron_Out = _8;
					'd9:  W_Digitron_Out = _9;
				endcase
			end
		else
			Count <= Count + 1'b1;
end

Buzzer_module.v

​ 当时钟信号处于上升沿的时候,如果时间到达59’50’'时,蜂鸣器每间隔两秒发出“Di”的声音,当时间到达整点的时候发出“Da”的声音。其中两个always@语句分别为定义蜂鸣器发声节点,和蜂鸣器发生动作。

always @( posedge CLK )
		begin
			if( MinH == 'd5 && MinL == 'd9 && SecH == 'd5 )		//While Time = 59'50"
				begin
					if( (SecL % 2) == 0)		
						Pulse_x <= Di;		//Di
					else
						Pulse_x <= 20000;
				end
			else if( MinH == 0 && MinL == 0 && SecH == 0 && SecL == 0 )		//While Time = 00'00"
				Pulse_x <= Da;		//Da
			else
				Pulse_x <= 20000;
		end
	
   always @ ( posedge CLK )
		begin
			if( (Pulse_x == Di) | (Pulse_x == Da) )
				begin
					if( Count == Pulse_x )
						begin
							Count <= 23'd0;
							W_buzzer <= ~W_buzzer;
						end
					else 
						Count <= Count + 1'b1;
				end
			else 
				begin
					W_buzzer <= 1'b1;
					Count <= 23'd0;
				end				
		end

实验结果及分析

​ 实验结果及分析这一节,我将Verilog程序烧录到FPGA开发板中,并进行了功能数字钟的功能展示。结果如下截图。

结果一

​ 本章截图展示的是功能数字钟时分秒计时功能六个数码管自左到右,分别为时、分、秒。当程序开始运行时时间开始由00:00:00开始计时。

csdnimg.cn/7f3eb8afaa754a95b0681c6489504b56.jpeg)

结果二

​ 当调节SW1为低电平后,钟表计时停止,数码管开始自动进行分的调整,值“分”(中间两位)按正序加1。当到达60时,开始进位。当把SW1调节为高电平后,钟表恢复计时。

结果三

​ 当调节SW2为低电平时,数码管开始进行时的自动调整,值“时”按序加1,当满足进位条件时,Week+1。

结果四

​ 当使KEY1处于低电平时,数码管左5位数码管熄灭,右一位显示星期数。如图此时为星期四。

结果五

​ 如下截图展示的为在59’50’‘-00’00’'时,每间隔2秒进行报时的过程。

实验总结

​ 在本次实验中,我进行了一次小型数字电路系统的分析。通过分析,我初步了解了一个数字电路系统的设计原则,设计思路和设计模块。我认识到一个完整的系统需要根据系统结构来对设计方法进行选择。

​ 在功能数字钟这个实验中,程序块包括一个顶层模块,若干个底层模块和底层模块下的子模块。顶层模块实现了对底层模块的调用,底层模块实现对复杂系统功能的分块解决,而底层模块的子模块实现了对功能的进一步细化,于是一个较复杂的系统被分解为了若干个简单的系统的组成部分。这种思想一方面简化了系统设计过程,另一方面方便了设计者的调试。

​ 在进行代码功能分析的过程中,我一方面遇到了语法和基础知识上的问题,另一方面我通过不断去复习基础知识和向同学请教,我逐步掌握了各个代码块的含义,和代码作者在进行代码设计时,进行的debug的巧妙思路。

​ 这次实验我有很多收获,一方面我进一步了解了Verilog语言的语法和软件平台的使用方法;另一方面,我认识到有时候自己认为的不重要其实是自己没用意识到它的重要性,要想从事件中收获更多,就需要我们能够认真对待一件事情中的每一个细节。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值