基于FPGA数字时钟.docx
《基于FPGA数字时钟.docx》由会员分享,可在线阅读,更多相关《基于FPGA数字时钟.docx(25页珍藏版)》请在冰豆网上搜索。
基于FPGA数字时钟
基于FPGA的数字时钟设计
一、课程设计目的
1、进一步熟悉QuartusⅡ的软件使用方法;
2、熟悉可编程逻辑器件的开发流程及硬件测试方法;
3、熟悉基于FPGA的综合数字系统设计方法;
二、设计任务
设计一台可以显示时、分、秒的数字钟。
如图1所示为基于FPGA的数字钟设计的系统框图。
图1数字钟系统
三、设计要求
1、能直接显示小时、分、秒,其中小时为以二十四为计数周期;
2、能够显示日期(即年、月、日),且要求在显示时钟的数码管上显示日期,即时钟数码管与日期数码管复用;
3、年、月、日要严格按照实际日期,例如1月31天,4月30天,2月闰年29天等;
4、当数字钟发生走时错误时,要求电路有校时功能,可以对时、分单独校正,且校正时间时系统时钟不工作;
5、当日期发生错误时,要求有校正日期功能,可以对年、月、日单独校正,且矫正日期时时钟系统仍然工作;
6、具有闹钟功能,即输入想要定时的时间,当时钟到达该时间时报警,系统可由灯亮代表报警信号。
四、设计内容
1、时间计数模块
本次是将秒分时各个模块分开进行设计,用秒的进位作为分模块的脉冲,用分的进位作为是模块的脉冲。
秒进位的仿真波形
程序:
秒的程序
modulemiao(clk,gdata,ddata,en,cl,clr);
inputclk;
inputen;
inputclr;
output[3:
0]ddata;
output[3:
0]gdata;
outputcl;
reg[7:
0]q;
regcl;
assignddata=q%10;
assigngdata=q/10;
always@(negedgeclkorposedgeclr)
begin
if(clr==1)
q=0;
else
begin
if(en==1)
begin
if(q<59)
begin
q=q+1;
cl=0;
end
else
begin
q=0;
cl=1;
end
end
end
end
endmodule
分模块和时模块的程序一秒程序类似,只是进位计数不一样。
2、日期模块
与时间模块一样,用低的进位作为高的脉冲。
日的仿真波形
日模块程序
moduleri(nian,yue,shi,gdata,ddata,en,cl,clr);
inputshi;
inputen;
input[3:
0]yue;
inputclr;
input[15:
0]nian;
output[3:
0]ddata;
output[3:
0]gdata;
outputcl;
reg[7:
0]q;
regcl;
reg[7:
0]r;
assignddata=(q+1)%10;
assigngdata=(q+1)/10;
always@(posedgeshiorposedgeclr)
begin
if(clr==1)
q=0;
elseif(en==1)
begin
cl=0;
if(yue==2)
begin
if((nian%400)==0)
r=29;
elseif((nian%4)==0)
begin
if((nian%100)!
=0)
r=29;
else
r=28;
end
elser=28;
end
elsebegincase(yue)
1:
r=31;
3:
r=31;
4:
r=30;
5:
r=31;
6:
r=30;
7:
r=31;
8:
r=31;
9:
r=30;
10:
r=31;
11:
r=30;
12:
r=31;
endcase
end
if(shi==1)
begin
if(q<(r-1))
begin
q=q+1;
end
else
begin
q=0;
cl=1;
end
end
end
end
endmodule
改程序可以判断闰年还是平年,大月还是小月。
月模块的程序:
moduleyue(ri,gdata,ddata,en,cl,clr,oyue);
inputri;
inputen;
inputclr;
output[3:
0]ddata;
output[3:
0]gdata;
outputcl;
output[3:
0]oyue;
reg[3:
0]oyue;
reg[3:
0]q;
regcl;
assignddata=(q+1)%10;
assigngdata=(q+1)/10;
always@(posedgeriorposedgeclr)
begin
if(clr==1)
q=0;
else
begin
if(en==1)
begin
cl=0;
if(ri==1)
begin
if(q<11)
begin
q=q+1;
oyue=q+1;
end
else
begin
q=0;
cl=1;
end
end
end
end
end
endmodule
年模块的程序:
modulenian(yue,ddata,gdata,clr,en,onian);
inputyue;
inputen;
inputclr;
output[3:
0]ddata;
output[3:
0]gdata;
output[15:
0]onian;
reg[15:
0]q;
reg[15:
0]onian;
wire[7:
0]q1;
regcl;
assignq1=q%100;
assignddata=q1%10;
assigngdata=q1/10;
always@(posedgeyueorposedgeclr)
begin
if(clr)
q=2012;
elseif(en==1)
if(yue==1)
begin
q=q+1;
onian=q;
end
end
endmodule
3.选择显示模块:
该模块的功能是通过按键切换显示时间日期和闹钟。
选择模块的程序:
moduleduoluxuanzeqi(miaot,miao,fent,fen,shit,shi,rit,ri,yuet,yue,niant,nian,nmiaot,nmiao,nfent,nfen,nshit,nshi,dit,di,zhongt,zhong,gaot,gao,kz);
input[3:
0]nmiaot;
input[3:
0]nmiao;
input[3:
0]nfent;
input[3:
0]nfen;
input[3:
0]nshit;
input[3:
0]nshi;
input[3:
0]miaot;
input[3:
0]miao;
input[3:
0]fent;
input[3:
0]fen;
input[3:
0]shit;
input[3:
0]shi;
input[3:
0]rit;
input[3:
0]ri;
input[3:
0]yuet;
input[3:
0]yue;
input[3:
0]niant;
input[3:
0]nian;
input[1:
0]kz;
//inputclk;
output[3:
0]dit;
output[3:
0]di;
output[3:
0]zhongt;
output[3:
0]zhong;
output[3:
0]gaot;
output[3:
0]gao;
reg[3:
0]dit;
reg[3:
0]di;
reg[3:
0]zhongt;
reg[3:
0]zhong;
reg[3:
0]gaot;
reg[3:
0]gao;
always@(kz,miaot,miao,fent,fen,shit,shi,rit,ri,yuet,yue,niant,nian,nmiaot,nmiao,nfent,nfen,nshit,nshi)
begin
case(kz)
0:
begindit=miaot;
di=miao;
zhongt=fent;
zhong=fen;
gaot=shit;
gao=shi;
end
1:
begindit=rit;
di=ri;
zhongt=yuet;
zhong=yue;
gaot=niant;
gao=nian;
end
2:
begindit=nmiaot;
di=nmiao;
zhongt=nfent;
zhong=nfen;
gaot=nshit;
gao=nshi;
end
endcase
end
endmodule
4.闹钟模块:
闹钟模块通过按键进行置数,然后将所置的数跟时间进行比较,当小时和分钟与闹钟的一样,LED灯就会亮。
Kv6为闹钟使能,高电平有效。
置数模块程序:
moduleniaozhong(nmiaot,nmiao,nfent,nfen,nshit,nshi,xz1,xz2,xz3,kv5);
inputxz1;
inputxz2;
inputxz3;
inputkv5;
output[3:
0]nmiaot;
output[3:
0]nmiao;
output[3:
0]nfent;
output[3:
0]nfen;
output[3:
0]nshit;
output[3:
0]nshi;
reg[7:
0]m;
reg[7:
0]f;
reg[7:
0]s;
assignnmiaot=m/10;
assignnmiao=m%10;
assignnfent=f/10;
assignnfen=f%10;
assignnshit=s/10;
assignnshi=s%10;
always@(posedgekv5)
begin
if(xz1==1&&xz2==0&&xz3==0)
begin
if(m<59)
m=m+1;
else
m=0;
end
elseif(xz1==0&&xz2==1&&xz3==0)
begin
if(f<59)
f=f+1;
else
f=0;
end
elseif(xz1==0&&xz2==0&&xz3==1)
begin
if(s<23)
s=s+1;
else
s=0;
end
end
endmodule
比较模块程序:
modulebijiao(miao,fent,fen,shit,shi,nfent,nfen,nshit,nshi,deng,en);
inputen;
input[3:
0]miao;
input[3:
0]nfent;
input[3:
0]nfen;
input[3:
0]nshit;
input[3:
0]nshi;
input[3:
0]fent;
input[3:
0]fen;
input[3:
0]shit;
input[3:
0]shi;
outputdeng;
regdeng;
always@(miao,fent,fen,shit,shi,nfent,nfen,nshit,nshi,en)
begin
if(en==1)
begin
if(fent==nfent&&fen==nfen&&shi==nshi&&shit==nshit)
deng=1;
else
deng=0;
end
elsedeng=0;
end
endmodule
比较模块的仿真波形:
5.按键选择模块,控制模块,校正模块:
用按键kz控制显示的却换,按键kv4控制日期模块或时间模块三个计数器的使能,和控制闹钟位的选择。
当要校正是,只要关闭使能端en,通过kz选择要校正的是时间还是日期,在通过kv4进行位的选择。
闹钟置数时,不必关掉使能,只要将显示切换到闹钟之后用kv4进行选择要调整的位,通过kv5进行调整。
按键控制模块:
模块中的程序:
计数的程序
modulejiushuq(kv4,q);
inputkv4;
output[1:
0]q;
reg[1:
0]q;
always@(posedgekv4)
begin
if(q<2)
q=q+1;
else
q=0;
end
endmodule
选择的程序:
modulejskongzhi(en,qh,q,xz1,xz2,xz3);
input[1:
0]q;
input[1:
0]qh;
inputen;
outputxz1,xz2,xz3;
regxz1,xz2,xz3;
always@(q,qh,en)
begin
if(en==1)
begin
xz1=1;
xz2=1;
xz3=1;
end
else
begin
if(qh==0)
begin
xz1=0;
case(q)
0:
beginxz1<=0;xz2<=0;xz3<=0;end
1:
beginxz1<=0;xz2<=1;xz3<=0;end
2:
beginxz1<=0;xz2<=0;xz3<=1;end
endcase
end
else
begin
xz1<=0;
xz2<=0;
xz3<=0;
end
end
end
endmodule
校正模块框图:
modulejiaoshi(en,cl,kv3,ocl);
inputcl;
inputkv3;
inputen;
//inputbclk;
outputocl;
regocl;
always@(en,cl,kv3,ocl)
begin
if(en==1)
ocl=cl;
elseocl=kv3;
end
endmodule
通过使能控制进位是由按键控制,还是由低模块向高模块进位。
5、实验结果
en为使能端clr为清零端时日铃为时间日期闹钟却换
时间显示
日期显示:
闹钟设置
闹钟响应L7为闹铃到时响应结果
关闭闹钟
6、实验心得:
经过这次课程设计,我加深了对FPGA的了解,能更加灵活的运用HDL语言。
中间虽然已到很多问题,但是经过同学之间到讨论,问题最好都解决了,做完之后,经过不断的修改,使得程序更加完善,功能更加齐全。