📄 基于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 + -