现在的位置: 首页 > 综合 > 正文

Verilog实现数字钟

2018年01月14日 ⁄ 综合 ⁄ 共 3025字 ⁄ 字号 评论关闭

程序是实现一个数字钟,有进位、清零、校时与校分功能。数字钟的分钟和小时是用数码管显示,秒信号是用LED显示8421BCD码。

下面是采用8421BCD码计数,并在一个模块中实现时钟功能的Verilog程序。由主时钟分频(50MHz)得到秒信号,计秒到60分加1,秒清零。计分到60时,分清零。同时,可以通过按键进行校分与校时。

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date:    16:20:22 11/19/2013
// Design Name:
// Module Name:    DigitalClk
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module DigitalClk(
          input clk,
			 input clr,
			 input setm,//设定分钟
			 input seth,//设定小时 
			 output reg[3:0]secondL,//秒数的低位
			 output reg[3:0]secondH,//秒数的高位
			 output reg[6:0]atog,
			 output reg[3:0]an 

       );
			reg [3:0]minuteL;//分钟数的低位
			reg [3:0]minuteH;//分钟数的高位
			reg [3:0]hourL;//小时数的低位
			reg [3:0]hourH;//小时数的高位
			reg [1:0]s; //四个数码管轮流使能信号
			reg [3:0]digit; //使能数码管中的数字
			reg [26:0] counter;
			reg [7:0]minute;//记录分钟数
			reg [7:0]hour;//记录小时数
			reg [7:0]sec;//记录秒数
			integer i;
			integer j;
			integer k;
			
always@(posedge clk or posedge clr)
begin
    if(clr==1) //清零键按下时将所有数据置零  
	    begin
       counter<=0;
		 secondL<=0;
		 secondH<=0;
		 minuteL<=0;
		 minuteH<=0;
		 hourH<=0;
		 hourL<=0;
		 minute<=0;
		 hour<=0;
		 sec<=0;
		 end 
	  else if(counter==50000000)//时间达到一秒
	  begin
		counter<=0;
		if(setm==1)//如果设置分钟建按下(长按一秒才会起作用)
		begin
			if(minute==59)
			begin 
				minute<=0;
				if(hour==23)//23:59进位变为00:00
				begin
					hour<=0;
				end
				else
				begin
					hour<=hour+1;
				end
			end
			else
			begin
				minute<=minute+1;
			end
		end
		if(seth==1)//如果设置小时建按下(长按一秒才会起作用)
		begin
			if(hour==23)
			begin
				hour<=0;
				minute<=0;
				minuteH<=0;
				minuteL<=0;
			end
			else
			begin
				hour<=hour+1;
			end
		end
		//一般情况
		if(sec==59)//秒针进位
		begin
			sec<=0;
			if(minute==59)
			begin
				minute<=0;
				if(hour==23)//23:59进位后变成00:00
				begin
					hour<=0;
				end
				else if(hour<23)
				begin
					hour<=hour+1;
				end					
			end
			else if(minute<59)//分钟数进位
			begin
			minute<=minute+1;
			end					
		end
		else if(seth==0&&setm==0)//在调时,调分键没有按下的情况下,秒钟计数
		begin
			sec<=sec+1;
		end
		for(i=0;i<6;i=i+1)//分离出秒钟数的个位和十位
		begin
			if(sec[7:0]-i*10<10)
			begin
				secondH<=i;
				secondL<=sec[7:0]-i*10;
				i=6;
			end
		end
		for(j=0;j<6;j=j+1)//分离出分钟数的个位和十位
		begin
			if(minute[7:0]-j*10<10)
			begin
				minuteH<=j;
				minuteL<=minute[7:0]-j*10;
				j=6;
			end
		end
		for(k=0;k<3;k=k+1)//分离出十钟数的个位和十位
		begin
			if(hour[7:0]-k*10<10)
			begin
				hourH<=k;
				hourL<=hour[7:0]-k*10;
				k=3;
			end
		end
	  end
					
	  else
	  begin
         counter<=counter+1;
	  end
end
//数码管动态显示
always@(*)
   begin
	  an=4'b1111;
	  s<=counter[14:13];  
	  an[s]=0;
     case(s) 
	    0:digit<=minuteL[3:0];
		 1:digit<=minuteH[3:0];
		 2:digit<=hourL[3:0];
		 3:digit<=hourH[3:0];
		 default:digit<=hourH[3:0];
	  endcase
	  case(digit)
	    0:atog=7'b0000001;
       1:atog=7'b1001111;
       2:atog=7'b0010010;	  
       3:atog=7'b0000110;
       4:atog=7'b1001100;
       5:atog=7'b0100100;
       6:atog=7'b0100000;
       7:atog=7'b0001111;
       8:atog=7'b0000000;
       9:atog=7'b0000100;
       default:atog=7'b0000001;
     endcase
	end
endmodule
NET "clk" LOC="B8";
//NET "clr" LOC="P11";
NET "clr" LOC="A7";
NET "secondL[0]" LOC="M5";
NET "secondL[1]" LOC="M11";
NET "secondL[2]" LOC="P7";
NET "secondL[3]" LOC="P6";
NET "secondH[0]" LOC="N5";
NET "secondH[1]" LOC="N4";
NET "secondH[2]" LOC="P4";
NET "secondH[3]" LOC="G1";
NET"atog[0]"LOC=M12;
NET"atog[1]"LOC=L13;
NET"atog[2]"LOC=P12;
NET"atog[3]"LOC=N11;
NET"atog[4]"LOC=N14;
NET"atog[5]"LOC=H12;
NET"atog[6]"LOC=L14;
NET"an[3]"LOC=K14;
NET"an[2]"LOC=M13;
NET"an[1]"LOC=J12;
NET"an[0]"LOC=F12;
NET"setm"LOC=G12;
NET"seth"LOC=M4;


抱歉!评论已关闭.