⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 基于verilog的电子日历与电子钟.txt

📁 基于Verilog 的电子日历与电子时钟程序
💻 TXT
字号:
/* 信号定义: 
GW48 SOPC系统(GW48-PK2)采用模式5
clk:    标准时钟信号,本例中,其频率为4Hz,接179引脚; 
clk_1k:   产生报时音的时钟信号,本例中其频率为1024Hz,接177引脚; 
mode:    功能控制信号; 为0:计时功能; 
            			 为1:调星期功能; 
            			 为2:手动校时功能;
						 为3:调日期功能;
						 为4:日期显示功能;接236引脚,按键4;					  
turn:  接按键,在手动校时功能时,选择是调整小时,还是分钟; 
        在调日期时,选择是调整日,还是月.接237引脚,按键5;
		若长时间按住该键,还可使秒信号清零,用于精确调时; 
change:接按键,手动调整时,每按一次,计数器加1.接235引脚,按键3
reset:  复位信号,接238引脚,按键6
hour,min,sec:此三信号分别输出并显示时、分、秒信号, 皆采用BCD码计数,分别驱动1~6六个
数码管显示时间;min接引脚21,41,128,132~136;hour接引脚137~141,158~160;驱动数码管5、6亮
驱动数码管3、4亮;sec接引脚13~20;驱动数码管1、2亮 
week:为输出星期的信号,采用BCD码计数;驱动数码管8,接引脚165~168
alert: 输出到扬声器的信号,用于报时音,接引脚174;  
LD_hour:  接发光二极管,指示当前调整的是小时信号,接引脚1; 
LD_min:   接发光二极管,指示当前调整的是分钟信号。接引脚2;
LD_mon:    接发光二极管,指示当前调整的是月份信号.接引脚3;
LD_day:    接发光二极管,指示当前调整的是日子信号.接引脚4;
LD_week:   接发光二极管,指示当前调整的是星期信号.接引脚6;
*/ 
module clock(clk,clk_1k,mode,change,turn,reset,alert,week,
			hour,min,sec, LD_hour,LD_min,LD_mon,LD_day,LD_week); 
	input clk,clk_1k,mode,change,turn,reset; 
	output alert,LD_hour,LD_min,LD_mon,LD_day,LD_week;
	output[7:0] hour,min,sec;
	output[3:0] week;
	reg [3:0] week,week1; 
	reg[7:0] hour,min,sec,mon1,day1,hour1,min1,sec1; 
	reg[1:0] fm,num1,num2,num3,num4,num5; 
	reg[2:0] m,wm;
	reg[1:0] loop1,loop2,loop3,loop4,loop5,sound;
	reg LD_hour,LD_min,LD_mon,LD_day,LD_week; 
	reg clk_1hz,clk_2hz,minclk,hclk,dclk,monclk,wclk; 
	reg alert1,alert2,ear; 
	reg count1,count2,count3,count4,count5; 
	wire ct1,ct2,ct3,ct4,ct5,m_clk,h_clk,d_clk,mon_clk,w_clk; 
 
	always @(posedge clk)
		begin clk_2hz<=~clk_2hz;//分频为2HZ
			if(sound==3)  begin sound<=0; ear<=1;  end 
								//ear信号用于产生或屏蔽声音 
			else  begin sound<=sound+1; ear<=0;  end 
		end

 	always@(posedge clk_2hz)//分频为1HZ
		clk_1hz<=~clk_1hz;
 
	always @(posedge mode)       //mode信号控制系统在五种功能间转换 
		begin  if(m==4)  m<=0;  else  m<=m+1;  end 
	
	
	always @(posedge turn) 
		fm<=~fm;

	always        //该进程产生count1,count2,count3,count4,count5信号
		begin 
		case(m)
		3:begin if(fm) 			
				begin count3<=change;{LD_mon,LD_day}<=1;end	//调日
				else begin count4<=change;{LD_mon,LD_day}<=2;end //调月
				{count1,count2,count5}<=0;
			end 
		2: begin   if(fm)  							//调时间
			begin  count1<=change; {LD_min,LD_hour}<=2;  end //调分
			else begin  count2<=change;  {LD_min,LD_hour}<=1;  end//调时
			{count3,count4,count5}<=0;  
			end 
		1: begin   if(fm)  
				begin count5<=change;LD_week<=1;end   //调星期
				else {count5,LD_week}<=0;
				{count1,count2,count3,count4}<=0;
			end
		default: {count1,count2,count3,count4,count5,
					LD_min,LD_hour,LD_mon,LD_day,LD_week}<=0; 
		endcase 
		end
	always @(negedge clk) 
							//生成"num1"信号用于连续加1 
		if(count1)  begin 
			if(loop1==3) num1<=1; 
		else 
			begin loop1<=loop1+1; num1<=0; end 
		end 
		else  begin  loop1<=0;  num1<=0;  end 
	always @(negedge clk)               //产生num2信号 
		if(count2)  begin 
			if(loop2==3)  num2<=1; 
			else 
		begin  loop2<=loop2+1;  num2<=0;  end 
		end 
		else  begin  loop2<=0;  num2<=0;  end 
	always @(negedge clk) 
		if(count3)  begin 
			if(loop3==3)  num3<=1; 
		else 
			begin  loop3<=loop3+1;  num3<=0;  end 
		end 
		else  begin  loop3<=0;  num3<=0;  end
	always @(negedge clk) 
		if(count4)  begin 
			if(loop4==3) num4<=1; 
		else 
			begin  loop4<=loop4+1;  num4<=0;  end 
		end 
		else  begin  loop4<=0;  num4<=0;  end
	always @(negedge clk)
		if(count5)  begin 
			if(loop5==3) num5<=1; 
		else 
			begin  loop5<=loop5+1;  num5<=0;  end 
		end 
		else  begin  loop5<=0;  num5<=0;  end
	
	assign ct1=(num1&clk)|(!num1&m_clk);    //ct1用于计时、校时中的分钟计数 
	assign ct2=(num2&clk)|(!num2&h_clk);    //ct2用于计时、校时中的小时计数
	assign ct3=(num3&clk)|(!num3&d_clk);	//ct3用于日期与调日期中的日计数
	assign ct4=(num4&clk)|(!num4&mon_clk);  //ct4用于日期与调日期中的月计数
	assign ct5=(num5&clk)|(!num5&w_clk);    //ct5用于星期与调星期中的星期计数

 
	always @(posedge clk_1hz or posedge reset)          //秒计时和秒调整进程 
		if(reset)
			begin sec1=0;end
		else begin
		if(!(sec1^8'h59)|turn&(!m))  
			begin 
				sec1<=0; if(!(turn&(!m)))  minclk<=1;
			end 
			//按住"turn"按键一段时间,秒信号可清零,该功能用于手动精确调时
		else  begin 
			if(sec1[3:0]==4'b1001)  
				begin  sec1[3:0]<=4'b0000;  sec1[7:4]<=sec1[7:4]+1;  end 
			else  sec1[3:0]<=sec1[3:0]+1;   minclk<=0; 
		end
		end 
		assign  m_clk=minclk||count1; 
 
	always @(posedge ct1 or posedge reset)               //分计时和分调整进程 
		if(reset)
			begin min1=0;end
			else
		begin 
			if(min1==8'h59)  begin  min1<=0;  hclk<=1;  end 
			else   begin 
				if(min1[3:0]==4'h9) 
					begin  min1[3:0]<=0;  min1[7:4]<=min1[7:4]+1;  end 
				else  min1[3:0]<=min1[3:0]+1;  hclk<=0; 
			end 
		end 
		assign  h_clk=hclk||count2; 
 
	always @(posedge ct2 or posedge reset)
		if(reset)
		begin hour1=0;end
		else
		begin            //小时计时和小时调整进程 
			if(hour1==8'h23) begin hour1<=0; dclk<=1; end
			else  begin 
				if(hour1[3:0]==9)  
					begin  hour1[7:4]<=hour1[7:4]+1;  hour1[3:0]<=0;  end 
				else  hour1[3:0]<=hour1[3:0]+1; dclk<=0;
			end 
		end
		assign d_clk=dclk||count3;
 
	always@(posedge ct3 or posedge reset)		//日计时和日调整进程
		if(reset)
			begin day1=1;end
		else
		begin case(mon1)
		8'h2:begin	if(day1==8'h28)
					begin day1<=8'h1;monclk<=1;end	
					else begin
					if(day1[3:0]==4'h9)
					begin day1[7:4]<=day1[7:4]+1;day1[3:0]<=0;end
					else day1[3:0]<=day1[3:0]+1;monclk<=0;
					end
					end
		8'h4,8'h6,8'h9,8'h11:begin if(day1==8'h30)
					begin day1<=1;monclk<=1;end
			else begin
				if(day1[3:0]==4'h9)
					begin day1[7:4]<=day1[7:4]+1;day1[3:0]<=0;end
			else day1[3:0]<=day1[3:0]+1;monclk<=0;
			end
			end	
		default:begin if(day1==8'h31)
					begin day1<=1;monclk<=1;end
			else begin
				if(day1[3:0]==4'h9)
					begin day1[7:4]<=day1[7:4]+1;day1[3:0]<=0;end
			else day1[3:0]<=day1[3:0]+1;monclk<=0;
			end
			end
		endcase
		end
		assign mon_clk=monclk||count4;

	always@(posedge ct4 or posedge reset)			//月计时和月调整进程
		if(reset) mon1=1;
		else
		begin
			if(mon1==8'h12)
				begin mon1<=1;end
			else begin
				if(mon1[3:0]==4'h9)
					begin mon1[7:4]<=mon1[7:4]+1;mon1[3:0]<=0;end
				else mon1[3:0]<=mon1[3:0]+1;
			end
		end


	always@(posedge ct3 or posedge reset)		//产生星期时钟
		if(reset)
		wm=0;
		else begin
		if(wm==6) begin 
			wm<=0;wclk<=1;
			end
		else
			wm<=wm+1;
		end
		assign w_clk=wclk||count5;
	
	always@(posedge ct5 or posedge reset)		//星期计时和星期调整进程
		if(reset)
			week1=1;
		else begin
		if (week1==4'h7)
			week1<=1;
		else  week1<=week1+1;
		end
 
	always                        //时、分、秒、日期的显示控制 
	case(m) 
		3'b000:  begin  week<=week1;hour<=hour1;  min<=min1;  sec<=sec1;  end 
                //计时状态下的时、分、秒显示 
		3'b010:  begin  week<=0;hour<=hour1;  min<=min1;  sec<=8'hzz;  end 
                //校时状态下的时、分、秒显示 
		3'b001:  begin  week<=week1;hour<=0;min<=0;sec<=0;end		//调星期的显示
		3'b011:  begin  min<=mon1;sec<=day1; end		//调日期的显示
		3'b100:  begin  hour<=mon1;min<=0;sec<=day1;week<=week1;end	//日期显示
	endcase 
 
 
	assign  alert=((alert1)?clk_1k&clk:0)|alert2;  //产生闹铃音或整点报时音
 
	always                          //产生整点报时信号alert2 
		begin  
			if((min1==8'h59)&&(sec1>8'h54)||(!(min1|sec1)))  
			if(sec1>8'h54)  alert2<=ear&clk_1k;  //产生短音 
			else  alert2<=!ear&clk_1k;      //产生长音 
			else  alert2<=0;
		end 
endmodule 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -