verilog数字钟设计FPGA全新.docx
《verilog数字钟设计FPGA全新.docx》由会员分享,可在线阅读,更多相关《verilog数字钟设计FPGA全新.docx(19页珍藏版)》请在冰豆网上搜索。
![verilog数字钟设计FPGA全新.docx](https://file1.bdocx.com/fileroot1/2023-1/26/cf9aab26-d0f1-429d-bd9e-b129c5dd0d79/cf9aab26-d0f1-429d-bd9e-b129c5dd0d791.gif)
verilog数字钟设计FPGA全新
1、课程设计目标
1.熟悉并掌握verilog硬件描述语言
2.熟悉quartus软件开发环境
3.学会设计大中规模的数字电路,并领会其中的设计思想
二、课程设计实现的功能
(1)设计一个数码管实时显示时、分、秒的数字时钟(24小时显示模式);
(2)可以调节小时,分钟。
(3)能够进行24小时和12小时的显示切换。
(4)可以设置任意时刻闹钟,并且有开关闹钟功能。
(5)有整点报时功能,几点钟LED灯闪亮几下。
(6)有复位按键,复位后时间从零开始计时,但闹钟设置时间不变。
3、设计原理:
1、总原理框图:
是
是
附全部代码:
总模块:
moduleclock(clk,reset,MODE,Alarm_ctr,BT2,H12_24,DSH,DSL,DMH,DML,DHH,DHL,dian,bao_signal,nao_signal);
inputclk;//50MHz
inputreset,MODE,Alarm_ctr,BT2,H12_24;//复位键,模式选择按钮,闹钟开关档,调节按钮,12—24小时切换档
output[7:
0]DMH,DML,DHH,DHL;//4个数码管显示输入信号
outputdian,bao_signal,nao_signal;//时分间隔点,报时信号,闹钟信号
output[3:
0]DSH,DSL;//秒钟输出信号
wire[3:
0]SH,SL,MH,ML,HH,HL;
wire[3:
0]LED_mode;
wire[3:
0]HH12,HL12,HH24,HL24,MH24,ML24,SH24,SL24;
wire[3:
0]set_HH,set_HL,set_MH,set_ML;
wire_1HZ,_10ms,_250ms,_500ms;
wireKeydone1;
wireKeydone2;
wireco1,co11,co111,co2,co22,co222,set_co2;
wire[3:
0]mode_flag;
assigndian=1'b0;
devide_fu1(_1HZ,_10ms,_250ms,_500ms,reset,clk);//分频,得到4种不同频率的时钟信号
key_pressu2(_10ms,MODE,Keydone1);//模式档按钮去抖动
key_pressu20(_10ms,BT2,Keydone2);//调节按钮去除抖动
modeu3(Keydone1,mode_flag);//通过模式按钮产生不同模式
secondu4(_1HZ,reset,mode_flag,Keydone2,SH24,SL24,co1);//秒计时
minuteu5(co11,reset,MH24,ML24,co2);//分计时
houru6(co22,reset,HH24,HL24);//小时计时
SEG7_LUTu7(DML,ML);//4个数码管显示
SEG7_LUTu8(DMH,MH);
SEG7_LUTu9(DHL,HL);
SEG7_LUTu10(DHH,HH);
display_LEDu11(DSL,SL);//LED灯显示秒或模式灯
display_LEDu12(DSH,SH);
mode_chooseu13(mode_flag,Keydone2,_250ms,co1,co2,set_co2,co11,co22,co111,co222);//选择模式进行不同操作
hour12_24u14(HH24,HL24,HH12,HL12);//12--24小时切换
boshiu15(HH,HL,MH,ML,SH,SL,_1HZ,bao_signal);//整点报时
set_naozhongu16(co111,co222,set_HH,set_HL,set_MH,set_ML,set_co2);//设置闹钟时间
Naozhongu17(Alarm_ctr,_500ms,set_HH,set_HL,set_MH,set_ML,HH24,HL24,MH24,ML24,nao_signal);//任意闹钟响应
LUT_modeu18(mode_flag,H12_24,HH12,HL12,HH24,HL24,MH24,ML24,set_HH,set_HL,set_MH,set_ML,MH,ML,HH,HL);//通过模式选择数码管显示
LED_modeu19(mode_flag,SH24,SL24,SH,SL);模式选择LED灯显示
Endmodule
分频模块:
分频模块的作用主要是要获得各种频率的时钟信号。
输入信号为50MHZ的信号,要想获得1HZ的信号作为秒脉冲计时,则要对50MHZ信号分频。
通过计数的方式,当计数从0开始到24999999时,1HZ信号取反一次,计数又从0开始,如此循环,就可以得到1HZ脉冲信号。
对于其他信号也是如此,只是计数值不一样,得到的分频信号不同。
moduledevide_f(_1HZ,_10ms,_250ms,_500ms,nCR,_50MHZ);
input_50MHZ,nCR;
output_1HZ,_10ms,_250ms,_500ms;
reg_1HZ,_10ms,_250ms,_500ms;
reg[31:
0]Q1,Q2,Q3,Q4;
always@(posedge_50MHZornegedgenCR)begin
if(~nCR)
begin
Q1<=32'd0;
Q2<=32'd0;
Q3<=32'd0;
Q4<=32'd0;
end
elseif(Q1>=32'd24999999)
begin
Q1<=32'd0;
_1HZ=~_1HZ;
end
elseif(Q2>=32'd249999)
begin
Q2<=32'd0;
_10ms=~_10ms;
end
elseif(Q4>=32'd6299999)
begin
Q4<=32'd0;
_250ms=~_250ms;
end
elseif(Q3>=32'd12499999)
begin
Q3<=32'd0;
_500ms=~_500ms;
end
elsebegin
Q1<=Q1+1'd1;
Q2<=Q2+1'd1;
Q3<=Q3+1'd1;
Q4<=Q4+1'd1;
end
end
endmodule
计时模块:
秒计数:
在1HZ脉冲下进行秒计时,当计时达到59秒后,在下一个脉冲来临变0,并发出一个脉冲信号,可供下面分钟计数作为输入脉冲信号计时。
分钟计数:
在输入脉冲下,分钟开始计时,当计时达到59后,在下一个脉冲来临变0,并发出一个脉冲,供小时计数的输入脉冲新号。
小时计数:
脉冲信号来临时,计数加1,达到23后在下一个脉冲的作用下清零,从新计时。
如果有复位信号,则时分秒全部清零。
modulesecond(cp,reset,mode_flag,BT2,SH,SL,co);
inputcp,reset,BT2;
input[3:
0]mode_flag;
outputco=1'b0;
regco;
output[3:
0]SL,SH;
reg[3:
0]SH,SL;
reg[7:
0]cnt;
always@(posedgecpornegedgereset)
begin
if(!
reset)
begin
SL=4'b0;
SH=4'b0;
cnt<=8'b0;
end
elseif((mode_flag==4'b0010)&&(!
BT2))
begin
SL=4'b0;
SH=4'b0;
cnt<=8'b0;
end
else
begin
if(cnt==8'd59)
begin
cnt<=8'd0;
SH<=4'd0;
SL<=4'd0;
co<=1'b1;
end
else
begin
co=1'b0;
cnt=cnt+8'd1;
SL<=cnt%10;
SH<=cnt/10;
end
end
end
endmodule
moduleminute(cp,reset,MH,ML,co);
inputcp,reset;
outputco=1'b0;
output[3:
0]ML,MH;
reg[3:
0]MH,ML;
reg[7:
0]cnt;
regco;
always@(posedgecpornegedgereset)
begin
if(!
reset)
begin
ML=4'b0;
MH=4'b0;
cnt<=8'b0;
end
else
begin
if(cnt==8'd59)
begin
cnt<=8'd0;
MH<=4'd0;
ML<=4'd0;
co<=1'b1;
end
else
begin
co=1'b0;
cnt=cnt+8'd1;
ML<=cnt%10;
MH<=cnt/10;
end
end
end
endmodule
modulehour(cp,reset,HH,HL);
inputcp,reset;
output[3:
0]HL,HH;
reg[3:
0]HH,HL;
reg[7:
0]cnt;
always@(posedgecpornegedgereset)
begin
if(!
reset)
begin
HL=4'b0;
HH=4'b0;
cnt<=8'b0;
end
else
begin
if(cnt==8'd23)
begin
cnt<=8'd0;
HH<=4'd0;
HL<=4'd0;
end
else
begin
cnt=cnt+8'd1;
HL<=cnt%10;
HH<=cnt/10;
end
end
end
Endmodule
模式选择模块:
同过一个模式档按键MODE,按一下产生对应一种模式mode_flag,并且可以循环。
在不同的模式下可以进行不同的操作。
其中mode_flag=4'0000为正常显示计时,mode_flag=4'0001为小时调钟模式,mode_flag=4'00010为分钟调钟模,mode_flag=4'0011为闹钟小时设置模式,mode_flag=4'0100为闹钟分钟设置模式。
modulekey_press(_10ms,KEY,Keydone);
inputKEY,_10ms;
outputKeydone;
regdout1,dout2,dout3;
always@(posedge_10ms)
begin
dout1<=KEY;
dout2<=dout1;
dout3<=dout2;
end
assignKeydone=(dout1|dout2|dout3);
endmodule
modulemode(MODE,mode_flag);
inputMODE;
output[3:
0]mode_flag;
reg[3:
0]mode_flag;
always@(negedgeMODE)
begin
mode_flag=mode_flag+4'b1;
if(mode_flag==4'b0101)
mode_flag=2'b0;
end
endmodule
moduleLED_mode(mode_flag,SH24,SL24,SH,SL);
input[3:
0]mode_flag;
input[3:
0]SH24,SL24;
output[3:
0]SH,SL;
reg[3:
0]SH,SL;
always@(mode_flag)begin
case(mode_flag)
4'b0000:
begin
SH<=SH24;
SL<=SL24;end
4'b0001:
begin
SH<=4'b0000;
SL<=4'b0001;end
4'b0010:
begin
SH<=4'b0000;
SL<=4'b0010;end
4'b0011:
begin
SH<=4'b0000;
SL<=4'b0100;end
4'b0100:
begin
SH<=4'b0000;
SL<=4'b1000;end
default:
begin
SH<=SH24;
SL<=SL24;end
endcase
end
endmodule
ModuleLUT_mode(mode_flag,H12_24,HH12,HL12,HH24,HL24,MH24,ML24,set_HH,set_HL,set_MH,set_ML,MH,ML,HH,HL);
input[3:
0]HH12,HL12,HH24,HL24,MH24,ML24;
input[3:
0]set_HH,set_HL,set_MH,set_ML;
input[3:
0]mode_flag;
inputH12_24;
output[3:
0]MH,ML,HH,HL;
reg[3:
0]MH,ML,HH,HL;
always@(mode_flagorH12_24)begin
case(mode_flag)
4'b0011,
4'b0100:
begin
HH<=set_HH;
HL<=set_HL;
MH<=set_MH;
ML<=set_ML;end
default:
begin
if(H12_24)begin
HH<=HH12;
HL<=HL12;
MH<=MH24;
ML<=ML24;end
elsebegin
HH<=HH24;
HL<=HL24;
MH<=MH24;
ML<=ML24;end
end
endcase
end
endmodule
modulemode_choose(mode_flag,BT2,_250ms,co1,co2,set_co2,co11,co22,co111,co222);
input[3:
0]mode_flag;
inputBT2,_250ms,co1,co2,set_co2;
outputco11,co22,co111,co222;
supply1Vdd;
regco11,co22,co111,co222;
always@(mode_flag)begin
case(mode_flag)
4'b0001:
begin
if(~BT2)co22<=_250ms;
elsebeginco22<=co2;
co11<=co1;end
end
4'b0010:
begin
if(~BT2)beginco11<=_250ms;
co22<=co2;end
elsebeginco11<=co1;
co22<=co2;end
end
4'b0011:
beginco22<=co2;
co11<=co1;
if(~BT2)co222<=_250ms;
elseco222<=set_co2;end
4'b0100:
beginco22<=co2;
co11<=co1;
if(~BT2)co111<=_250ms;
elseco111<=Vdd;end
default:
begin
co11<=co1;
co22<=co2;end
endcase
end
endmodule
闹钟模块:
moduleset_naozhong(co111,co222,set_HH,set_HL,set_MH,set_ML,co2);
inputco111,co222;
output[3:
0]set_HH,set_HL,set_MH,set_ML;
supply1Vdd;
outputco2;
minute(co111,Vdd,set_MH,set_ML,co2);
hour(co222,Vdd,set_HH,set_HL);
endmodule
modulenaozhong(Alarm_ctr,_1HZ,set_HH,set_HL,set_MH,set_ML,HH24,HL24,MH24,ML24,nao_signal);
inputAlarm_ctr,_1HZ;
input[3:
0]set_HH,set_HL,set_MH,set_ML;
input[3:
0]HH24,HL24,MH24,ML24;
outputnao_signal;
regsignal;
regnao_signal;
reg[16:
0]Q;
always@(posedge_1HZ)begin
if((~signal)&&(Alarm_ctr))begin
if((set_HH==HH24)&&(set_HL==HL24)&&(set_MH==MH24)&&(set_ML==ML24))signal<=1'b1;
elsesignal<=1'b0;end
elseif((signal)&&(Alarm_ctr))begin
nao_signal<=~nao_signal;
Q=Q+nao_signal;
if(Q>=8'd720)begin
Q<=16'b0;
signal<=1'b0;end
end
elsebegin
signal<=1'b0;
nao_signal<=1'b0;end
end
endmodule
12——24小时切换模块:
modulehour12_24(HH24,HL24,HH12,HL12);
input[3:
0]HH24,HL24;
output[3:
0]HH12,HL12;
reg[3:
0]HH12,HL12;
regflag;
always@(HH24orHL24)begin
if((HH24*10+HL24)<=12)
begin
HH12<=HH24;
HL12<=HL24;
end
elseif(((HH24*10+HL24)>=13)&&((HH24*10+HL24)<=19))
begin
HH12<=4'd0;
HL12<=HL24-4'd2;
end
elseif(((HH24*10+HL24)>=19)&&((HH24*10+HL24)<=21))
begin
HH12<=4'd0;
HL12<=HL24+4'd8;
end
else
begin
HH12<=HH24-4'd1;
HL12<=HL24-4'd2;
end
end
endmodule
整点报时模块:
moduleboshi(HH,HL,MH,ML,SH,SL,_500ms,bao_signal);
input[3:
0]HH,HL,MH,ML,SH,SL;
input_500ms;
outputbao_signal;
regbao_signal;
reg[7:
0]Q1,Q2;
regbao;
always@(posedge_500ms)begin
if(((SH*10+SL)==8'd59)&&((MH*10+ML)==8'd59))begin
Q1<=7'b0;
bao<=1'b1;end
elseif((Q1<10*HH+HL)&&(bao))
begin
bao_signal<=~bao_signal;
Q1<=Q1+bao_signal;
end
elseif(Q1==(10*HH+HL))
bao<=1'b0;
else
begin
bao_signal<=1'b0;
end
end
endmodule
译码显示模块:
一、数码管显示:
通过传入响应的4位十进制数,运用case语句转换输出相应的8位二进制显示码,送入数码管显示。
二、LED显示:
moduledisplay_LED(s_out,s_int);
input[3:
0]s_int;
output[3:
0]s_out;
reg[3:
0]s_out;
wire[3:
0]s_out1;
always@(s_int)
begin
case(s_int)
4'h0:
s_out=4'b0000;
4'h1:
s_out=4'b0001;
4'h2:
s_out=4'b0010;
4'h3:
s_out=4'b0011;
4'h4:
s_out=4'b0100;
4'h5:
s_out=4'b0101;
4'h6:
s_out=4'b0110;
4'h7:
s_out=4'b0111;
4'h8:
s_out=4'b1000;
4'h9:
s_out=4'b1001;
endcase
end
assigns_out1=~s_out;
Endmodule
moduleSEG7_LUT(oSEG1,iDIG);
input[3:
0]iDIG;
output[7:
0]oSEG1;
reg[7:
0]oSEG;
wire[7:
0]oSEG1;
always@(iDIG)
begin
case(iDIG)
4'h0:
oSEG=8'b00111111;
4'h1:
oSEG=8'b00000110;
4'h2:
oSEG=8'b01011011;
4'h3:
oSEG=8'b01001111;
4'h4:
oSEG=8'b01100110;
4'h5:
oSEG=8'b01101101;
4'h6:
oSEG=8'b01111101;
4'h7:
oSEG=8'b00000111;
4'h8:
oSEG=8'b01111111;
4'h9:
oSEG=8'b01101111;
4'ha:
oSEG=8'b01110111;
4'hb:
oSEG=8'b01111100;
4'hc:
oSEG=8'b00111001;
4'hd:
oSEG=8'b01011110;
4'he:
oSEG=8'b01111001;
4'hf:
oSEG=8'b01110001;