【Verilog】基于Nexys4DDR开发板实现数字钟

功能:

基于Nexys4DDR开发板实现的数字钟,六位数码管显示时分秒,可切换24时制/12时制,有整点报时功能(led灯闪烁)。

 

Verilog代码:
`timescale 1ns / 1ps

//数字钟,输入100M时钟信号,控制数字显示器通过高频扫描来显示当前时间
module digital_clock(clk_100M, select, y, h, min, sh, led1, led2);
	input clk_100M;
	input h, min, sh;
	output led1, led2;
	output[7:0] y;
	output[7:0] select;
	reg led1;
	wire led2;
	reg[16:0] count;
	reg[7:0] select, y;
	wire clk_1hz, clk_1khz, clk_100M;
	wire[3:0] s0, s1, m0, m1, h0, h1;
	//变量说明:
	//clk_100M是100M的时钟信号select是控制数码管亮暗的使能端,y是七段译码器的输出端
	//led2是正点报时灯
	//count用于记录时钟走过的秒数,clk_1hz是分频后1hz的时钟信号
	//s0~h1记录秒、分、时的个十位
	//h、min分别为分钟和小时校时,sh==0时为24时制,sh==1时为12时制,led1是上下午指示灯
	
	
	//分频器获得1hz和1khz时钟信号,输入输出必须为wire型
	frequency_divider fred(clk_1hz, clk_1khz, clk_100M);
	//计时模块,每24*60*60秒为一轮
	initial count = 0;
	always@(posedge clk_1hz)
		begin
			case({h,min})
				2'b01: 
						if(sh==0 && count < 17'd86341) count <= count + 6'd60;//24小时制的分钟校时
						else if(sh==1 && count < 16'd43141) count <= count + 6'd60;//12小时制的分钟校时
						else count <= 0;
				2'b10: 
						if(sh==0 && count < 17'd82800) count <= count + 12'd3600;//24小时制的小时校时
						else if(sh==0 && count >= 17'd82800) count <= 0;//24小时制清零
						else if(sh==1 && count < 16'd43200) count <= count + 12'd3600;//12小时制的小时校时
						else count <= 12'd3600;//12小时制清零
				2'b00:
						if(sh==0 && count < 17'd86399) count <= count + 1;
						else if(sh==0 && count >= 17'd86399) count <= 0;
						else if(sh==1 && count < 16'd46799) count <= count + 1;
						else count <= 3600;
				2'b11: 
						count <= count;
			endcase
		end
	//获得当前时间的时分秒各位数
	time_count t(count, s0, s1, m0, m1, h0, h1);
	
	
	//12小时制的上下午指示灯,上午灭,下午亮
	initial led1 = 0;
	always@(h1) if(sh==1 && {h1,h0}==1) led1 <= ~led1;
	always@(posedge sh)
		if(count > 16'd43200)
			begin
				count <= count - 16'd43200;
				led1 <= ~led1;
			end
	
	
	//正点报时
	showtime show(clk_1hz, count, led2);
		
		
	//获取当前时间的时分秒各位数的七段译码值
	wire[7:0] y0, y1, y2, y3, y4, y5;
	decoder4_8 d1(s0, y0);
	decoder4_8 d2(s1, y1);
	decoder4_8 d3(m0, y2);
	decoder4_8 d4(m1, y3);
	decoder4_8 d5(h0, y4);
	decoder4_8 d6(h1, y5);

		
	//数码管高频显示当前小时、分钟和秒
	reg[2:0] flag;//flag相当于模6计数器,对应时分秒的六位数
	initial
		begin 
			flag = 0;
			y = 0;
			select = 0;
		end
	always@(posedge clk_1khz) flag = (flag+1)%6;
	always@(flag)
		begin
			if(flag == 3'd0)//显示秒的个位
				begin
					select <= 8'b1111_1110;
					y <= y0;
				end
			if(flag == 3'd1)//显示秒的十位
				begin
					select <= 8'b1111_1101;
					y <= y1;
				end
			if(flag == 3'd2)//显示分钟的个位
				begin
					select <= 8'b1111_1011;
					y <= y2;
				end
			if(flag == 3'd3)//显示分钟的十位
				begin
					select <= 8'b1111_0111;
					y <= y3;
				end
			if(flag == 3'd4)//显示小时的个位
				begin
					select <= 8'b1110_1111;
					y <= y4;
				end
			if(flag == 3'd5)//显示小时的十位
				begin
					select <= 8'b1101_1111;
					y <= y5;
				end
		end	
endmodule
	
	

//分频器
module frequency_divider(clk_1hz, clk_1khz, clk_100M);
	input clk_100M;
	output clk_1hz, clk_1khz;
	reg[16:0] count1;
	reg[9:0] count2;
	reg clk_1khz, clk_1hz;
	//变量说明:
	//输入clk_100M为100M的时钟信号
	//count1和count2是分频器计的数变量,clk_1khz和clk_1hz是分频器的输出
	
	//中间变量必须在源程序中初始化!!!
	initial 
		begin
			count1 = 0;
			count2 = 0;
			clk_1khz = 0;
			clk_1hz = 0;
		end

	//100M 100000分频得到1khz
	always@(posedge clk_100M)
		begin
			if(count1 == 17'd49999)
				begin
					clk_1khz <= ~clk_1khz;
					count1 <= 0;
				end
			else count1 <= count1 + 1;
		end
	
	//1khz 1000分频得到1hz
	always@(posedge clk_1khz)
		begin
			if(count2 == 10'd499)
				begin
					clk_1hz <= ~clk_1hz;
					count2 <= 0;
				end
			else count2 <= count2 + 1;
		end
endmodule 



//七段译码器
module decoder4_8(x, y);
	input[3:0] x;
	output[7:0] y;
	reg[7:0] y;
	
	always@(x)
		case(x)
			4'd0: y <= 8'h03;//数码管显示0
			4'd1: y <= 8'h9f;//数码管显示1
			4'd2: y <= 8'h25;//数码管显示2
			4'd3: y <= 8'h0d;//数码管显示3
			4'd4: y <= 8'h99;//数码管显示4
			4'd5: y <= 8'h49;//数码管显示5
			4'd6: y <= 8'h41;//数码管显示6
			4'd7: y <= 8'h1f;//数码管显示7
			4'd8: y <= 8'h01;//数码管显示8
			4'd9: y <= 8'h09;//数码管显示9
		endcase
endmodule 



//时分秒计算器
module time_count(count, s0, s1, m0, m1, h0, h1);
	input[16:0] count;
	output[3:0] s0, s1, m0, m1, h0, h1;
	reg[3:0] s0, s1, m0, m1, h0, h1;//分别对应秒、分、时的个位、十位
	
	initial 
		begin
			s0 = 0; s1 = 0; m0 = 0; m1 = 0; h0 = 0; h1 = 0;
		end
	always@(count)
		begin
			s0 <= (count%60)%10;//秒的个位
			s1 <= (count%60-((count%60)%10))/10;//秒的十位
			m0 <= (((count-count%60)/60)%60)%10;//分钟的个位
			m1 <= ((((count-count%60)/60)-((count-count%60)/60)%10)%60)/10;//分钟的十位
			h0 <= ((count-count%3600)/3600)%10;//小时的个位
			h1 <= (((count-count%3600)/3600)-((count-count%3600)/3600)%10)/10;//小时的十位
		end
endmodule 



//正点报时,几点就亮几下
module showtime(clk_1hz, count, led2);
	input clk_1hz;
	input[16:0] count;
	output led2;
	reg led2;
	reg[4:0] clock_number;
	
	initial begin clock_number = 0; led2 = 0; end
	always@(clk_1hz)
		begin
			if(clock_number == 0)
				case(count)
					17'd3598: 	clock_number <= 2;//马上1点
				
					17'd7197:	clock_number <= 4;//马上2点

					17'd10796:	clock_number <= 6;//马上3点

					17'd14395:	clock_number <= 8;//马上4点

					17'd17994:	clock_number <= 10;//马上5点

					17'd21592:	clock_number <= 12;//马上6点

					17'd25192:	clock_number <= 14;//马上7点

					17'd28791:	clock_number <= 16;//马上8点
	
					17'd32390:	clock_number <= 18;//马上9点

					17'd35989:	clock_number <= 20;//马上10点
	
					17'd39588:	clock_number <= 22;//马上11点

					17'd43187:	clock_number <= 24;//马上12点
		
					17'd46786:	clock_number <= 26;//马上13点
			
					17'd50385:	clock_number <= 28;//马上14点
	
					17'd53984:	clock_number <= 30;//马上15点

					17'd57583:	clock_number <= 32;//马上16点

					17'd61182:	clock_number <= 34;//马上17点

				endcase	
			else
				begin
					led2 <= ~led2;
					clock_number <= clock_number - 1;
				end
		end
endmodule 

 

管脚约束文件.ucf
NET "y<7>"             LOC=T10 | IOSTANDARD=LVCMOS33; #IO_L24N_T3_A00_D16_14
NET "y<6>"             LOC=R10 | IOSTANDARD=LVCMOS33; #IO_25_14
NET "y<5>"             LOC=K16 | IOSTANDARD=LVCMOS33; #IO_25_15
NET "y<4>"             LOC=K13 | IOSTANDARD=LVCMOS33; #IO_L17P_T2_A26_15
NET "y<3>"             LOC=P15 | IOSTANDARD=LVCMOS33; #IO_L13P_T2_MRCC_14
NET "y<2>"             LOC=T11 | IOSTANDARD=LVCMOS33; #IO_L19P_T3_A10_D26_14
NET "y<1>"             LOC=L18 | IOSTANDARD=LVCMOS33; #IO_L4P_T0_D04_14
NET "y<0>"             LOC=H15 | IOSTANDARD=LVCMOS33; #IO_L19N_T3_A21_VREF_15

NET "select<0>"          LOC=J17 | IOSTANDARD=LVCMOS33; #IO_L23P_T3_FOE_B_15
NET "select<1>"          LOC=J18 | IOSTANDARD=LVCMOS33; #IO_L23N_T3_FWE_B_15
NET "select<2>"          LOC=T9 | IOSTANDARD=LVCMOS33; #IO_L24P_T3_A01_D17_14
NET "select<3>"          LOC=J14 | IOSTANDARD=LVCMOS33; #IO_L19P_T3_A22_15
NET "select<4>"          LOC=P14 | IOSTANDARD=LVCMOS33; #IO_L8N_T1_D12_14
NET "select<5>"          LOC=T14 | IOSTANDARD=LVCMOS33; #IO_L14P_T2_SRCC_14
NET "select<6>"          LOC=K2 | IOSTANDARD=LVCMOS33; #IO_L23P_T3_35
NET "select<7>"          LOC=U13 | IOSTANDARD=LVCMOS33; #IO_L23N_T3_A02_D18_14

NET "clk_100M"             LOC=E3 | IOSTANDARD=LVCMOS33; 

NET "min"          LOC=J15 | IOSTANDARD=LVCMOS33; #IO_L24N_T3_RS0_15
NET "h"          LOC=L16 | IOSTANDARD=LVCMOS33; #IO_L3N_T0_DQS_EMCCLK_14
NET "sh"          LOC=M13 | IOSTANDARD=LVCMOS33; #IO_L13N_T2_MRCC_14
NET "sh" CLOCK_DEDICATED_ROUTE = FALSE;

NET "led1"         LOC=H17 | IOSTANDARD=LVCMOS33; #IO_L18P_T2_A24_15
NET "led2"         LOC=K15 | IOSTANDARD=LVCMOS33; #IO_L24P_T3_RS1_15
### 回答1: Nexys4 DDR是一款功能强大的FPGA开发板,通过集成的DDR3内存控制器和大量的数字信号处理资源,该开发板非常适合用于高性能数字信号处理和数字通信等领域的应用。 该开发板的中文手册主要包含了硬件描述、系统设计、软件开发和实验教程等方面的内容。在硬件描述部分,手册详细介绍了开发板的主要硬件组成和各个模块的功能、特点和信号连接方式等。在系统设计和软件开发部分,手册讲解了基于Nexys4 DDR开发板的系统设计和软件开发流程以及使用常见的开发工具和编程语言等,包括Vivado设计套件、Verilog和C语言等。手册还提供了一系列的应用实验,涵盖了数字信号处理、通信和图像处理等领域的常见实验和案例,让开发者可以快速上手。 总的来说,Nexys4 DDR中文手册是一份非常详细和有用的开发参考资料,对于想要深入学习和应用FPGA技术的开发者来说,是一份不可缺少的参考。 ### 回答2: Nexys4 DDR是一款高性能的FPGA开发板,可用于各种嵌入式系统设计和开发。其中文手册详细介绍了该开发板的硬件配置、使用方式、设计示例和性能参数等方面的信息。 手册的第一章首先介绍了Nexys4 DDR开发板的基本信息和特点,比如板载的芯片、器件和接口等。然后详细介绍了开发板的硬件连接和供电方式,以及如何使用开发板进行开发和测试。 第二章介绍了Nexys4 DDRFPGA芯片和软件开发环境,包括使用Xilinx Vivado软件进行FPGA工程的设计、仿真和调试。手册提供了丰富的实例代码和开发工具,方便用户快速上手和熟悉开发流程。 第三章介绍了Nexys4 DDR开发板的各种接口和连接方法,包括USB、Ethernet、HDMI、VGA、音频和SD卡等。手册提供了详细的接口介绍、连接方式和示例代码,方便用户进行各种外设的应用和接口调试。 第四章介绍了Nexys4 DDR开发板的性能参数和限制,包括时钟频率、功耗、资源占用、信号完整性等。手册提供了实测数据和性能试验的方法,帮助用户评估开发板的性能和瓶颈,并提供了改进和优化的建议。 总之,Nexys4 DDR中文手册是一份非常详细和实用的资料,对于使用该开发板进行嵌入式系统设计和开发的工程师和爱好者而言,是一份不可多得的参考文献。 ### 回答3: Nexys 4 DDR中文手册是一份非常重要的文档,它包含了对于Nexys 4 DDR开发板的详细说明和操作指南。这个开发板是由Digilent公司设计的,目的是为了帮助开发者能够更加方便地进行FPGA开发。 在Nexys 4 DDR中文手册中,你可以找到开发板的基本特征与功能,有效的使用这些特点能够使你更加轻松地完成各种任务。手册也提供了从基本设计到高级实现的各种教程,以及详细的代码示例和说明,让你能够快速掌握如何使用这个开发板。 此外,Nexys 4 DDR中文手册还包括了许多关于开发板硬件、软件和FPGA设计的资料,便于开发者在开发过程中能够更好地理解和操作。手册中还提供了大量的问题解决方案和技术支持,方便使用者在遇到问题时能够及时得到解决。 总之,Nexys 4 DDR中文手册是一份非常重要的文档,对于FPGA开发者和爱好者来说是必不可少的工具。通过学习这个手册,你可以更加轻松地使用Nexys 4 DDR开发板,从而更加有效地进行FPGA开发。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值