多功能数字钟(包含闹钟、整点报时、进制转换等功能)

这篇文章详细描述了一款由华科数电实验制作的多功能数字钟的设计过程,使用了Vivado工具和NexysDDR平台,涉及模块设计、频率分频、时间计数、闹钟设置以及12-24小时格式转换等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

华科数电实验多功能数字钟,使用vivado和NexysDDR
原工程见主页

模块设计框图

工程代码

顶层文件
module CLOCK(
   input CLOCK_100,KEY,SW,minutes,hours,minkey,hourkey,MUX,shift_12_24,stop,
	output [7:0]LED,[7:0]POS,
	output signal,
	output alarm,
	output info
	);
	
	//开关说明
	//minutes:分钟校正(SW0)//minkey:分钟闹钟(SW2)//hours:小时校正(SW1)//hourkey:小时闹钟(SW3)
	//MUX:当前时间和闹钟时间切换开关,正常为1(SW5)//shift_12_24:12和24的切换,正常为1(SW6)
	//KEY:复位信号,0为复位(SW15)//SW:计时使能信号,1为计时使能(SW14)
	//stop:闹钟关闭,按下即为关闭(BTNR)
	
	//输出说明
	//拨下SW5,就可以查看自己设置的闹钟时间,便于查看和设置闹钟
	//拨下SW6,就可以切换小时的显示格式,即是24进制还是12进制
	//当上午时,LED14点亮,下午时,LED14熄灭
	//当整点时,几点LED15就会闪烁几次
	//当当前时间和所设置的闹钟时间相等时,LED0就会点亮,除非按下闹钟关闭按钮
	
	wire CLK_OUT_1hz,CLK_OUT_100hz;
	wire [7:0]Q1,Q2,Q3,Qmin,Qhour,Qhour_inter,Qhour_shift;
	wire [7:0]set_min,set_hour;
	wire puncture;

   frequency_1hz frequen_clock_1hz(
	.R(KEY),
	.CP(CLOCK_100),
	.CLK_OUT(CLK_OUT_1hz)
	);	//1hz_分频器子模块
	
	frequency_100hz frequen_clock_100hz(
	.R(KEY),
	.CP(CLOCK_100),
	.CLK_OUT(CLK_OUT_100hz)
	); //100hz_分频器子模块

	
	CLOCK_24 time_clock(
	.CLK(CLK_OUT_1hz),
	.R(KEY),
	.EN(SW),
	.Q1(Q1),
	.Q2(Q2),
	.Q3(Q3),
	.minutes(minutes),
	.hours(hours)
	); //时间计数模块,产生初始时分秒
	
	MUX2TO1 min(
	.D0(Q2),
	.D1(set_min),
	.S(MUX),
	.Y(Qmin)
	); //二选一子模块,选择输出为当前分钟或是闹钟分钟
	
	MUX2TO1 hour_inter(
	.D0(Q3),
	.D1(set_hour),
	.S(MUX),
	.Y(Qhour_inter)
	); //二选一子模块,选择输出为当前小时或是闹钟小时

    shift24to12 shift(
    .hour(Qhour_inter),
    .Qhour(Qhour_shift)
    ); //24-12进制转换模块

	MUX2TO1 hour_shift(
	.D0(Qhour_inter),
	.D1(Qhour_shift),
	.S(shift_12_24),
	.Y(Qhour)
	); //二选一子模块,选择输出为24进制或是12进制

     add_pos display(
     .CLK(CLK_OUT_100hz),
     .R(KEY),
	 .hour(Qhour),
	 .minite(Qmin),
	 .second(Q1),
	 .pos(POS),
	 .LED(LED)
     );//数码管显示模块
	
	bell bell_clock(
	.CLK(CLK_OUT_1hz),
	.R(KEY),
	.minkey(minkey),
	.hourkey(hourkey),
	.set_min(set_min),
	.set_hour(set_hour),
	.SIGNAL(signal),
	.now_hour(Q3),
	.now_min(Q2),
	.stop(stop)
	); //闹钟模块,包括闹钟设置,时间匹配和闹钟关闭
	
	assign puncture = (Q1==8'h59)&&(Qmin==8'h59);
	
	PUNCTURE baoshi(
	.clk(CLK_OUT_1hz),
	.start(puncture),
	.hour(Qhour_inter),
	.LED(alarm)
	); //整点报时模块

	assign info = (Q3>8'h12)? 1'b0 : 1'b1;
endmodule  
endmodule
分频为1hz模块
module frequency_1hz(R,CP,CLK_OUT);
   input R,CP;
	output reg CLK_OUT;
	
	reg [27:0]counter;
	parameter IN_FRE=100_000_000;  
	parameter OUT_FRE=1;
	always@(posedge CP or negedge R)
	begin
	  if(R==1'b0)
	  begin CLK_OUT<=0;
	        counter<=26'd0;   end
	  else if(counter<(IN_FRE/OUT_FRE)-1)
	     begin 
		     counter<=counter+1'b1;
			  CLK_OUT<=1'b0;
		  end
	  else 
	  begin counter<=26'd0;
			  CLK_OUT<=1'b1;   end
	end
endmodule
分秒计数模块
module count10(CLK,R,EN,Q,CO);//10进制计数模块
   input CLK,R,EN;
	output reg[3:0]Q;
	output CO;
	always@( posedge CLK or negedge R)
	begin
	  if(~R)Q<=4'b0000;//复位
	  else if(EN)
	    begin
		  if(Q<9)
		   Q<=Q+1'b1;
		  else
		   Q<=4'b0000;
		 end
		else
		   Q<=Q;
	end
	assign CO=(Q==4'b1001);
endmodule

module count6(CLK,R,EN,Q,CO); //6进制计数模块

   input CLK,R,EN;
	output reg[3:0]Q;
	output CO;
	always@( posedge CLK or negedge R)
	begin
	  if(~R)Q<=4'b0000;
	  else if(EN)
	    begin
		  if(Q<5)
		   Q<=Q+1'b1;//低于5时递增计数
		  else
		   Q<=4'b0000; 
		 end
		else
		   Q<=Q;
	end
	assign CO=(Q==4'b0101); //进位信号
endmodule

module count60(CLK,R,EN,Q,CO); //60进制计数模块

   input CLK,R,EN;
   output [7:0]Q;
   output CO;
   
	wire CO1,CO2;
	
	count10 CLOCK10(
	.CLK(CLK),
	.R(R),
	.EN(EN),
	.Q(Q[3:0]),
	.CO(CO1)
	);
	
	count6 CLOCK6(
	.CLK(CLK),
	.R(R),
	.EN(EN&CO1),
	.Q(Q[7:4]),
	.CO(CO2)
	);
	
	assign CO=({Q[7:4],Q[3:0]}==8'h59);
	
endmodule
小时计数模块
module CLOCK_24(CLK,R,EN,Q1,Q2,Q3,minutes,hours);
   input CLK,R,EN,minutes,hours;
	output [7:0]Q1,Q2,Q3;//Q1为秒 Q2为分 Q3为时
	
	reg [3:0]cnt1,cnt2;
	wire CO1,CO2,CO3,CO24;
	count60 second(
	.CLK(CLK),
	.R(R),
	.EN(EN),
	.Q(Q1),
	.CO(CO1)
	);//秒进位59
	
	count60 minute(
	.CLK(CLK),
	.R(R),
	.EN((~minutes&CO1)|(minutes&EN)),
	.Q(Q2),
	.CO(CO2)
	);//分进位59
	assign CO24=(~hours&EN&CO1&CO2)|(hours&EN); //小时计数使能
	assign Q3[7:4]=cnt1;
	assign Q3[3:0]=cnt2;
	always@( posedge CLK or negedge R)
	begin
	  if(~R) {cnt1,cnt2}<=8'h00;
	  else if(CO24)
	    begin
		  if({cnt1,cnt2}<8'h23) //低于23时递增计数
		    begin
		     if(cnt2<4'b1001)
			    cnt2<=cnt2+1'b1;
			  else
			    begin
				 cnt2<=4'b0000;
				 cnt1<=cnt1+1'b1;
				 end
			 end
		  else
		    {cnt1,cnt2}<=8'h00;
		 end
		else  {cnt1,cnt2}<={cnt1,cnt2};
	end
endmodule
译码显示模块
module posdecode(
    input [2:0] bcd6,
    output [7:0]pos
    );//位码模块
reg [7:0] posr;
assign pos=posr;
always @ (bcd6)
    case (bcd6) //低位有效
        3'b000:posr<=8'b11011111;
        3'b001:posr<=8'b11101111;
        3'b010:posr<=8'b11110111;
        3'b011:posr<=8'b11111011;
        3'b100:posr<=8'b11111101;
        3'b101:posr<=8'b11111110;
        default:posr<=8'b11111111;
    endcase
endmodule

module add_pos(
   input CLK,
   input R,
   input [7:0]hour,minite,second,
   output  [7:0]pos,
   output reg [7:0]LED
   );//扫略显示模块
   
   reg [2:0]bcd;
   wire [2:0]select;
   wire [7:0]string;
   wire [7:0]LED1,LED2,LED3,LED4,LED5,LED6;
   wire [11:0]coding_bcd;
   
   assign select = bcd;
   posdecode all(select,pos); //选择输出数码管
   register  U1(hour[7:4],LED1);
   register  U2(hour[3:0],LED2);
   register  U3(minite[7:4],LED3);
   register  U4(minite[3:0],LED4);
   register  U5(second[7:4],LED5);
   register  U6(second[3:0],LED6);
   
   always @ (posedge CLK or negedge R)
   begin
    if(R==1'b0)
	  begin 
	     bcd<=0;
//	     LED<=8'b0000_0011;
	  end
	  else 
	     begin 
		     bcd<=(bcd+1'b1)%6; //有效数码管号数
		 end
    end
   	always@(*)begin
   	 case(select) //选择输出数据
		 3'b000:LED<=LED1;
		 3'b001:LED<=LED2;
		 3'b010:LED<=LED3;
		 3'b011:LED<=LED4;
		 3'b100:LED<=LED5;
		 3'b101:LED<=LED6;
		 endcase
	end
endmodule

module register(COUNT,LED);	//段码显示模块
   input [3:0]COUNT;
	output reg [7:0]LED;
	always@(*)begin
   	 case(COUNT)
		 4'b0000:LED<=8'b0000_0011; //0
		 4'b0001:LED<=8'b1001_1111; //1
		 4'b0010:LED<=8'b0010_0101; //2
		 4'b0011:LED<=8'b0000_1101; //3
		 4'b0100:LED<=8'b1001_1001; //4
		 4'b0101:LED<=8'b0100_1001; //5
		 4'b0110:LED<=8'b0100_0001; //6
		 4'b0111:LED<=8'b0001_1111; //7
		 4'b1000:LED<=8'b0000_0001; //8
		 4'b1001:LED<=8'b0000_1001; //9
		 default:LED<=8'b1111_1111;
		 endcase
	end
endmodule
闹钟模块
Module bell(CLK,R,minkey,hourkey,set_min,set_hour,SIGNAL,now_hour,now_min,stop);
    input CLK,R,minkey,hourkey;
	input [7:0]now_hour,now_min;
	input stop;
	output [7:0]set_min;
	output [7:0]set_hour;
	output SIGNAL;
	
	wire signal_1;
	reg  signal_2 = 1;

  count60 minbell(
	.CLK(CLK),	
	.R(1'b1),
	.EN(minkey),
	.Q(set_min)
	); //设置闹钟分钟
	
  count24 hourbell(
	.CLK(CLK),
	.R(1'b1),
	.EN(hourkey),
	.Q(set_hour)
	); //设置闹钟小时
	
	assign signal_1=(now_hour==set_hour)&(now_min==set_min);
	assign SIGNAL = signal_1 && signal_2;
	
	always @ (negedge stop or posedge signal_1)
	begin
	   if(stop) 
	            signal_2<=1'b0;
	            else
	            signal_2<=1'b1;
	end
endmodule	//关闭闹钟,关闭闹钟使用按键开关
	
module equal(now_hour,now_min,set_hour,set_min,signal);//时间比较模块
   input [7:0]now_hour,now_min,set_hour,set_min;
	output signal;
	
	assign signal=(now_hour==set_hour)&(now_min==set_min);

endmodule
整点报时模块
module PUNCTURE(
   input start,
   input clk,
   input [7:0]hour,
   output reg LED
   );
   
   wire [7:0]bcd;
   reg [7:0]count;
   reg EN;
   bito10 shift(hour,bcd);
   
     
     always @ (posedge clk or posedge start) //用计数来实现LED灯的闪烁次数
       begin
            if(start)
               begin
                EN<=1;
                count<= bcd<<1; //次数要*2
                LED<=0;
               end
            else
               begin
                    if(EN)
                    begin
                         if(count)
                             begin
                             count<=count-1 ;
                             LED<=~LED;
                            
                             end
                          else
                              begin
                              count<=0;
                              EN<=0;
                              LED<=0;
                              end
                    end     
               end
        end
     
endmodule

module bito10(
    input  [7:0]binary,
    output [7:0]bcd
    );
    
    assign bcd=binary[7:4]*10+binary[3:0];
endmodule//16进制切换为10进制
12-24进制转换模块
module shift24to12(
      input [7:0]hour,
      output [7:0]Qhour
      );
      
      reg  [7:0]A2;
      assign Qhour= (hour>8'h12)? A2:hour;
      always @ (*)
        begin
           case(hour) //分别转换
           8'h13: A2=8'h01;
           8'h14: A2=8'h02;
           8'h15: A2=8'h03;
           8'h16: A2=8'h04;
           8'h17: A2=8'h05;
           8'h18: A2=8'h06;
           8'h19: A2=8'h07;
           8'h20: A2=8'h08;
           8'h21: A2=8'h09;
           8'h22: A2=8'h10;
           8'h23: A2=8'h11;
           8'h24: A2=8'h12;
           default: A2=hour;
           endcase
        end
endmodule
约束文件
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets stop]

set_property PACKAGE_PIN E3 [get_ports CLOCK_100]
set_property PACKAGE_PIN V10 [get_ports KEY]
set_property PACKAGE_PIN J15 [get_ports minutes]
set_property PACKAGE_PIN L16 [get_ports hours]
set_property PACKAGE_PIN M13 [get_ports minkey]
set_property PACKAGE_PIN R15 [get_ports hourkey]
set_property PACKAGE_PIN T18 [get_ports MUX]
set_property PACKAGE_PIN U18 [get_ports shift_12_24]
set_property PACKAGE_PIN H17 [get_ports signal]
set_property PACKAGE_PIN U11 [get_ports SW]
set_property IOSTANDARD LVCMOS33 [get_ports CLOCK_100]
set_property IOSTANDARD LVCMOS33 [get_ports hourkey]
set_property IOSTANDARD LVCMOS33 [get_ports hours]
set_property IOSTANDARD LVCMOS33 [get_ports KEY]
set_property IOSTANDARD LVCMOS33 [get_ports minkey]
set_property IOSTANDARD LVCMOS33 [get_ports minutes]
set_property IOSTANDARD LVCMOS33 [get_ports MUX]
set_property IOSTANDARD LVCMOS33 [get_ports signal]
set_property IOSTANDARD LVCMOS33 [get_ports shift_12_24]
set_property IOSTANDARD LVCMOS33 [get_ports SW]
set_property PACKAGE_PIN U13 [get_ports {POS[7]}]
set_property PACKAGE_PIN K2 [get_ports {POS[6]}]
set_property PACKAGE_PIN T14 [get_ports {POS[5]}]
set_property PACKAGE_PIN P14 [get_ports {POS[4]}]
set_property PACKAGE_PIN J14 [get_ports {POS[3]}]
set_property PACKAGE_PIN T9 [get_ports {POS[2]}]
set_property PACKAGE_PIN J18 [get_ports {POS[1]}]
set_property PACKAGE_PIN J17 [get_ports {POS[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {POS[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {POS[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {POS[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {POS[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {POS[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {POS[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {POS[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {POS[0]}]
set_property PACKAGE_PIN T10 [get_ports {LED[7]}]
set_property PACKAGE_PIN R10 [get_ports {LED[6]}]
set_property PACKAGE_PIN K16 [get_ports {LED[5]}]
set_property PACKAGE_PIN K13 [get_ports {LED[4]}]
set_property PACKAGE_PIN P15 [get_ports {LED[3]}]
set_property PACKAGE_PIN T11 [get_ports {LED[2]}]
set_property PACKAGE_PIN L18 [get_ports {LED[1]}]
set_property PACKAGE_PIN H15 [get_ports {LED[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED[0]}]

set_property PACKAGE_PIN V11 [get_ports alarm]
set_property IOSTANDARD LVCMOS33 [get_ports alarm]

set_property PACKAGE_PIN M17 [get_ports stop]
set_property IOSTANDARD LVCMOS33 [get_ports stop]

set_property PACKAGE_PIN V12 [get_ports info]
set_property IOSTANDARD LVCMOS33 [get_ports info]

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值