Verilog 电子钟程序.docx
《Verilog 电子钟程序.docx》由会员分享,可在线阅读,更多相关《Verilog 电子钟程序.docx(19页珍藏版)》请在冰点文库上搜索。
Verilog电子钟程序
电子钟
二、电子钟
moduleclock(work_state,clock_on,clk_6MHz,clk_4Hz,in_set,display_set,clk_1024Hz,up,down,out1,out2,out3,out4,out5,out6,out7,out8,speaker);
inputwork_state,clk_1024Hz,up,down,display_set,clk_6MHz,in_set,clock_on,clk_4Hz;
outputout1,out2,out3,out4,out5,out6,out7,out8,speaker;
wire[2:
0]in_set;
reg[3:
0]out1,out2,out3,out4,out5,out6,out7,out8;
reg[2:
0]display_state;
reg[7:
0]hour,minute,second,year,month,day,day_max;
reg[7:
0]hour_set,minute_set,second_set,day_set,month_set,year_set,day_set_max;
integercentury=20;
integeri=0;
regspeaker;
reg[7:
0]clock_hour,clock_minute,clock_second;
reg[3:
0]high,med,low;
reg[13:
0]divider,origin;
reg[7:
0]counter;
regout;
wirecarry;
//*****各初始值设置时对应的状态********//
parameterstate_yorh=3'b100,//设置年或小时对应的按键状态
state_morm=3'b010,//设置月或分对应的按键状态
state_dors=3'b001;//设置日或秒对应的按键状态
//***初始化时钟:
08年08月08日00:
00:
00*****//
initial
begin
year<=8;
year_set<=8;
month<=8;
month_set<=8;
day<=8;
day_set<=8;
hour<=0;
minute<=0;
second<=0;
clock_hour<=0;
clock_minute<=0;
clock_second<=0;
display_state<=0;
end
//******电子钟正常工作状态下/work_state等于0时,时钟处于工作状态*******//
always@(posedgeclk_1024Hz)//频率选择1024HZ
begin
if(i>=1023)
begin
i<=0;
if(work_state)
begin
second<=second_set;
minute<=minute_set;
hour<=hour_set;
day<=day_set;
month<=month_set;
year<=year_set;
end
else
begin
if(second>=59)
begin
second<=0;
if(minute>=59)
begin
minute<=0;
if(hour>=23)
begin
hour<=0;
if(day>=day_max)
begin
day<=1;
if(month>=12)
begin
month<=1;
if(year>=99)
year<=0;
else
year<=year+1;
end
else
month<=month+1;
end
else
day<=day+1;
end
else
hour<=hour+1;
end
else
minute<=minute+1;
end
else
second<=second+1;
end
end
else
i<=i+1;
end
//******数码管显示状态设置*******//
always@(posedgedisplay_set)
begin
if(display_state>=2)
display_state<=0;
else
display_state<=display_state+1;
end
//*闹钟模块设置,用clock_on控制闹钟,闹钟铃声播放时间为一分钟,可手动关闭闹钟**//
always@(posedgeclk_6MHz)
begin
if(clock_on)
begin
if(clock_hour==hour&&clock_minute==minute)
speaker<=out;
elsespeaker<=0;
end
elsespeaker<=0;
end
//*************设置时钟的初值*************************//
/*用up来触发,当down=0时,一个上升沿触发来时加1,否则减1.***/
always@(posedgeup)
begin
if(!
work_state)//时间处于正常工作状态时,使要设置的初始值保持同步
begin
second_set<=second;
minute_set<=minute;
hour_set<=hour;
day_set<=day;
month_set<=month;
year_set<=year;
end
else
begin
if(display_state==1)//当display_state==1时,则是设置年月日的初始值,否则是设置时间.
begin
if(down==0)
begin
case(in_set)
state_yorh:
begin
if(year_set>=99)
year_set<=0;
else
year_set<=year_set+1;
end
state_morm:
begin
if(month_set>=12)
month_set<=1;
else
month_set<=month_set+1;
end
state_dors:
begin
if(day_set>=day_set_max)
day_set<=1;
else
day_set<=day_set+1;
end
endcase
end
else
begin
case(in_set)
state_yorh:
begin
if(year_set<=0)
year_set<=99;
else
year_set<=year_set-1;
end
state_morm:
begin
if(month_set<=1)
month_set<=12;
else
month_set<=month_set-1;
end
state_dors:
begin
if(day_set<=1)
day_set<=day_set_max;
else
day_set<=day_set-1;
end
endcase
end
end
elseif(display_state==0)
begin
if(down==0)
begin
case(in_set)
state_yorh:
begin
if(hour_set>=23)
hour_set<=0;
else
hour_set<=hour_set+1;
end
state_morm:
begin
if(minute_set>=59)
minute_set<=0;
else
minute_set<=minute_set+1;
end
state_dors:
begin
if(second_set>=59)
second_set<=0;
else
second_set<=second_set+1;
end
endcase
end
else
begin
case(in_set)
state_yorh:
begin
if(hour_set<=0)
hour_set<=23;
else
hour_set<=hour_set-1;
end
state_morm:
begin
if(minute_set<=0)
minute_set<=59;
else
minute_set<=minute_set-1;
end
state_dors:
begin
if(second_set<=0)
second_set<=59;
else
second_set<=second_set-1;
end
endcase
end
end
elseif(display_state==2)
begin
if(down==0)
begin
case(in_set)
state_yorh:
begin
if(clock_hour>=23)
clock_hour<=0;
else
clock_hour<=clock_hour+1;
end
state_morm:
begin
if(clock_minute>=59)
clock_minute<=0;
else
clock_minute=clock_minute+1;
end
state_dors:
begin
if(clock_second>=59)
clock_second<=0;
else
clock_second<=clock_second+1;
end
endcase
end
else
begin
case(in_set)
state_yorh:
begin
if(clock_hour<=0)
clock_hour<=23;
else
clock_hour<=clock_hour-1;
end
state_morm:
begin
if(clock_minute<=0)
clock_minute<=59;
else
clock_minute<=clock_minute-1;
end
state_dors:
begin
if(clock_second<=0)
clock_second<=59;
else
clock_second<=clock_second-1;
end
endcase
end
end
end
end
//**********本年度当前月的天数的计算**********//
always@(dayorday_set)//当日期变化时,则其所处月份的天数;
begin
if(month==1||month==3||month==5||month==7||month==8||month==10||month==12)
day_max<=31;
elseif(month==4||month==6||month==9||month==11)
day_max<=30;
else
begin
if(({century,year}%400==0)||(({century,year}%4==0)&&({century,year}%10!
=0)))
day_max<=29;
elseday_max<=28;
end
if(month_set==1||month_set==3||month_set==5||month_set==7||month_set==8||month_set==10||month_set==12)
day_set_max<=31;
elseif(month_set==4||month_set==6||month_set==9||month_set==11)
day_set_max<=30;
else
begin
if(({century,year_set}%400==0)||(({century,year_set}%4==0)&&({century,year_set}%10!
=0)))
day_set_max<=29;
elseday_set_max<=28;
end
end
//**********数码管显示模块,display_state=1时,显示年月日,否则显示时间////
always@(posedgeclk_6MHz)
begin
if(!
work_state)
begin
if(display_state==1)
begin
out8<=year%10;
out7<=year/10;
out6<=13;
out5<=month%10;
out4<=month/10;
out3<=13;
out2<=day%10;
out1<=day/10;
end
elseif(display_state==0)
begin
out8<=hour%10;
out7<=hour/10;
out6<=15;
out5<=minute%10;
out4<=minute/10;
out3<=15;
out2<=second%10;
out1<=second/10;
end
elseif(display_state==2)
begin
out8<=clock_hour%10;
out7<=clock_hour/10;
out6<=12;
out5<=clock_minute%10;
out4<=clock_minute/10;
out3<=12;
out2<=clock_second%10;
out1<=clock_second/10;
end
end
else
begin
if(display_state==1)
begin
out8<=year_set%10;
out7<=year_set/10;
out6<=13;
out5<=month_set%10;
out4<=month_set/10;
out3<=13;
out2<=day_set%10;
out1<=day_set/10;
end
elseif(display_state==0)
begin
out8<=hour_set%10;
out7<=hour_set/10;
out6<=15;
out5<=minute_set%10;
out4<=minute_set/10;
out3<=15;
out2<=second_set%10;
out1<=second_set/10;
end
elseif(display_state==2)
begin
out8<=clock_hour%10;
out7<=clock_hour/10;
out6<=12;
out5<=clock_minute%10;
out4<=clock_minute/10;
out3<=12;
out2<=clock_second%10;
out1<=clock_second/10;
end
end
end
//*******用乐曲《梁祝》作为闹钟铃声*************//
assigncarry=(divider==16383);
always@(posedgeclk_6MHz)
begin
if(carry)
divider<=origin;
else
divider<=divider+1;
end
always@(posedgecarry)
begin
out<=~out;//2分频产生方波信号
end
always@(posedgeclk_4Hz)
begin
case({high,med,low})//分频比预置
'b000000000011:
origin<=7281;
'b000000000101:
origin<=8730;
'b000000000110:
origin<=9565;
'b000000000111:
origin<=10310;
'b000000010000:
origin<=10647;
'b000000100000:
origin<=11272;
'b000000110000:
origin<=11831;
'b000001010000:
origin<=12556;
'b000001100000:
origin<=12974;
'b000100000000:
origin<=13516;
'b000000000000:
origin<=16383;
endcase
end
always@(posedgeclk_4Hz)
begin
if(counter==63)
counter<=0;//计时,以实现循环演奏
else
counter<=counter+1;
case(counter)//记谱
0:
{high,med,low}<='b000000000011;//低音“3”
1:
{high,med,low}<='b000000000011;//持续4个时钟节拍
2:
{high,med,low}<='b000000000011;
3:
{high,med,low}<='b000000000011;
4:
{high,med,low}<='b000000000101;//低音“5”
5:
{high,med,low}<='b000000000101;//发3个时钟节拍
6:
{high,med,low}<='b000000000101;
7:
{high,med,low}<='b000000000110;//低音“6”
8:
{high,med,low}<='b000000010000;//中音“1”
9:
{high,med,low}<='b000000010000;//发3个时钟节拍
10:
{high,med,low}<='b000000010000;
11:
{high,med,low}<='b000000100000;//中音“2”
12:
{high,med,low}<='b000000000110;//低音“6”
13:
{high,med,low}<='b000000010000;
14:
{high,med,low}<='b000000000101;
15:
{high,med,low}<='b000000000101;
16:
{high,med,low}<='b000001010000;//中音“5”
17:
{high,med,low}<='b000001010000;//发3个时钟节拍
18:
{high,med,low}<='b000001010000;
19:
{high,med,low}<='b000100000000;//高音“1”
20:
{high,med,low}<='b000001100000;
21:
{high,med,low}<='b000001010000;
22:
{high,med,low}<='b000000110000;
23:
{high,med,low}<='b000001010000;
24:
{high,med,low}<='b000000100000;//中音“2”
25:
{high,med,low}<='b000000100000;//持续11个时钟节拍
26:
{high,med,low}<='b000000100000;
27:
{high,med,low}<='b000000100000;
28:
{high,med,low}<='b000000100000;
29:
{high,med,low}<='b000000100000;
30:
{high,med,low}<='b000000100000;
31:
{high,med,low}<='b000000100000;
32:
{high,med,low}<='b000000100000;
33:
{high,med,low}<='b000000100000;
34:
{high,med,low}<='b000000100000;
35:
{high,med,low}<='b000000110000;//中音“3”
36:
{high,med,low}<='b000000000111;//低音“7”
37:
{high,med,low}<='b000000000111;
38:
{high,med,low}<='b000000000110;//低音“6”
39:
{high,med,low}<='b000000000110;
40:
{high,med,low}<='b000000000101;//低音“5”
41:
{high,med,low}<='b000000000101;
42:
{high,med,low}<='b000000000101;
43:
{high,med,low}<='b000000000110;//低音“6”
44:
{high,med,low}<='b000000010000;//中音“1”
45:
{high,med,low}<='b000000010000;
46:
{high,med,low}<='b000000100000;//中音“2”
47:
{high,med,low}<='b000000100000;
48:
{high,med,low}<='b000000000011;//低音“3”
49:
{high,med,low}<='b000000000011;
50:
{high,med,low}<='b000000010000;//中音“1”
51:
{high,med,low}<='b000000010000;
52:
{high,med,low}<='b000000000110;
53:
{high,med,low}<='b000000000101;//低音“5”
54:
{high,med,low}<='b000000000110;
55:
{high,med,low}<='b000000010000;//