verilog数字钟设计(FPGA)全新
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一、课程设计目标
1. 熟悉并掌握verilog 硬件描述语言
2. 熟悉quartus 软件开发环境
3.学会设计大中规模的数字电路,并领会其中的设计思想
二、课程设计实现的功能
(1)设计一个数码管实时显示时、分、秒的数字时钟(24小时显示模式);(2)可以调节小时,分钟。
(3)能够进行24小时和12小时的显示切换。
(4)可以设置任意时刻闹钟,并且有开关闹钟功能。
(5)有整点报时功能,几点钟LED灯闪亮几下。
(6)有复位按键,复位后时间从零开始计时,但闹钟设置时间不变。
三、设计原理:
1、总原理框图:
附全部代码:
总模块:
module
clock(clk,reset,MODE,Alarm_ctr,BT2,H12_24,DSH,DSL,DMH,DML,DHH,DHL,dian,bao_signa l,nao_signal);
input clk;//50MHz
input reset,MODE,Alarm_ctr,BT2,H12_24;//复位键,模式选择按钮,闹钟开关档,调节按
钮,12—24小时切换档output [7:0]DMH,DML,DHH,DHL; //4个数码管显示输入信号
output dian,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;
wire Keydone1;
wire Keydone2;
wire co1,co11,co111,co2,co22,co222,set_co2;
wire [3:0]mode_flag;
assign dian=1'b0;
devide_f u1(_1HZ,_10ms,_250ms,_500ms,reset,clk); //分频,得到4种不同频率的时钟信号key_press u2(_10ms,MODE,Keydone1); //模式档按钮去抖动
key_press u20(_10ms,BT2,Keydone2); //调节按钮去除抖动
mode u3(Keydone1,mode_flag); //通过模式按钮产生不同模式
second u4(_1HZ,reset,mode_flag,Keydone2,SH24,SL24,co1); //秒计时
minute u5(co11,reset,MH24,ML24,co2); //分计时
hour u6(co22,reset,HH24,HL24); //小时计时
SEG7_LUT u7(DML,ML); //4个数码管显示
SEG7_LUT u8(DMH,MH);
SEG7_LUT u9(DHL,HL);
SEG7_LUT u10(DHH,HH);
display_LED u11(DSL,SL); //LED灯显示秒或模式灯
display_LED u12(DSH,SH);
mode_choose u13(mode_flag,Keydone2,_250ms,co1,co2,set_co2,co11,co22,co111,co222); //选择模式进行不同操作
hour12_24 u14(HH24,HL24,HH12,HL12); //12--24小时切换
boshi u15(HH,HL,MH,ML,SH,SL,_1HZ,bao_signal); //整点报时
set_naozhong u16(co111,co222,set_HH,set_HL,set_MH,set_ML,set_co2); //设置闹钟时间Naozhong
u17(Alarm_ctr,_500ms,set_HH,set_HL,set_MH,set_ML,HH24,HL24,MH24,ML24,nao_signal);
//任意闹钟响应
LUT_mode
u18(mode_flag,H12_24,HH12,HL12,HH24,HL24,MH24,ML24,set_HH,set_HL,set_MH,set_ML, MH,ML,HH,HL);//通过模式选择数码管显示
LED_mode u19(mode_flag,SH24,SL24,SH,SL); 模式选择LED灯显示
Endmodule
分频模块:
分频模块的作用主要是要获得各种频率的时钟信号。
输入信号为50MHZ的信号,要想获得1HZ的信号作为秒脉冲计时,则要对50MHZ信号分频。
通过计数的方式,当计数从0开始到24 999999时,1HZ信号取反一次,计数又从0开始,如此循环,就可以得到1HZ脉冲信号。
对于其他信号也是如此,只是计数值不一样,得到的分频信号不同。
module devide_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 _50MHZ or negedge nCR)begin
if(~nCR)
begin
Q1<=32'd0;
Q2<=32'd0;
Q3<=32'd0;
Q4<=32'd0;
end
else if(Q1>=32'd2*******)
begin
Q1<=32'd0;
_1HZ=~_1HZ;
end
else if(Q2>=32'd249999)
begin
Q2<=32'd0;
_10ms=~_10ms;
end
else if(Q4>=32'd6299999)
begin
Q4<=32'd0;
_250ms=~_250ms;
end
else if(Q3>=32'd1*******)
begin
Q3<=32'd0;
_500ms=~_500ms;
end
else begin
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后在下一个脉冲的作用下清零,从新计时。
如果有复位信号,则时分秒全部清零。
module second(cp,reset,mode_flag,BT2,SH,SL,co);
input cp,reset,BT2;
input[3:0]mode_flag;
output co=1'b0;
reg co;
output [3:0]SL,SH;
reg[3:0]SH,SL;
reg[7:0]cnt;
always@(posedge cp or negedge reset )
begin
if(!reset)
begin
SL=4'b0;
SH=4'b0;
cnt<=8'b0;
end
else if((mode_flag==4'b0010)&&(!BT2))
begin
SL=4'b0;
SH=4'b0;
cnt<=8'b0;
end
else
begin
if(cnt==8'd59)
begin
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
module minute (cp,reset,MH,ML,co); input cp ,reset;
output co=1'b0;
output [3:0]ML,MH;
reg[3:0]MH,ML;
reg[7:0]cnt;
reg co;
always@(posedge cp or negedge reset) 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;
ML<=cnt%10;
MH<=cnt/10;
end
end
end
endmodule
module hour (cp,reset,HH,HL);
input cp,reset;
output [3:0]HL,HH;
reg[3:0]HH,HL;
reg[7:0]cnt;
always@(posedge cp or negedge reset)
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为闹钟分钟设置模式。
module key_press(_10ms,KEY,Keydone);
input KEY,_10ms;
output Keydone;
reg dout1,dout2,dout3;
always @(posedge _10ms)
begin
dout1 <= KEY;
dout2 <= dout1;
dout3 <= dout2;
end
assign Keydone = (dout1 | dout2 | dout3); endmodule
module mode (MODE,mode_flag);
input MODE ;
output [3:0]mode_flag;
reg [3:0]mode_flag;
always @ (negedge MODE )
begin
mode_flag = mode_flag+ 4'b1;
if(mode_flag == 4'b0101)
mode_flag = 2'b0;
end
endmodule
module LED_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
Module LUT_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;
input H12_24;
output [3:0] MH,ML,HH,HL;
reg [3:0] MH,ML,HH,HL;
always@(mode_flag or H12_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
else begin
HH<=HH24;
HL<=HL24;
MH<=MH24;
ML<=ML24;end
end
endcase
end
endmodule
module mode_choose(mode_flag,BT2,_250ms,co1,co2,set_co2,co11,co22,co111,co222);
input [3:0]mode_flag;
input BT2,_250ms,co1,co2,set_co2;
output co11,co22,co111,co222;
supply1 Vdd;
reg co11,co22,co111,co222;
always@(mode_flag)begin
case (mode_flag)
4'b0001: begin
if(~BT2) co22<=_250ms;
else begin co22<=co2;
co11<=co1; end
end
4'b0010: begin
if(~BT2) begin co11<=_250ms;
co22<=co2;end
else begin co11<=co1;
co22<=co2; end
end
4'b0011: begin co22<=co2;
co11<=co1;
if(~BT2) co222<=_250ms;
else co222<=set_co2;end
4'b0100: begin co22<=co2;
co11<=co1;
if(~BT2) co111<=_250ms;
else co111<=Vdd; end
default :begin
co11<=co1;
co22<=co2; end
endcase
end
endmodule
闹钟模块:
module set_naozhong(co111,co222,set_HH,set_HL,set_MH,set_ML,co2);
input co111,co222;
output [3:0]set_HH,set_HL,set_MH,set_ML;
supply1 Vdd;
output co2;
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);
input Alarm_ctr,_1HZ;
input [3:0] set_HH,set_HL,set_MH,set_ML;
input [3:0] HH24,HL24,MH24,ML24;
output nao_signal;
reg signal;
reg nao_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;
else signal<=1'b0;end
else if((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
else begin
signal<=1'b0;
nao_signal<=1'b0;end
end
endmodule
12——24小时切换模块:
module hour12_24(HH24,HL24,HH12,HL12);
input [3:0] HH24,HL24;
output [3:0] HH12,HL12;
reg [3:0] HH12,HL12;
reg flag;
always@(HH24 or HL24)begin
if((HH24*10+HL24)<=12)
begin
HH12<=HH24;
HL12<=HL24;
else if(((HH24*10+HL24)>=13)&&((HH24*10+HL24)<=19))
begin
HH12<=4'd0;
HL12<=HL24-4'd2;
end
else if(((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
整点报时模块:
module boshi(HH,HL,MH,ML,SH,SL,_500ms,bao_signal);
input[3:0] HH,HL,MH,ML,SH,SL;
input _500ms;
output bao_signal;
reg bao_signal;
reg [7:0]Q1,Q2;
reg bao;
always@(posedge _500ms)begin
if(((SH*10+SL)==8'd59)&&((MH*10+ML)==8'd59))begin
Q1<=7'b0;
bao<=1'b1;end
else if((Q1<10*HH+HL)&&(bao))
begin
bao_signal<=~bao_signal;
Q1<=Q1+bao_signal;
end
else if(Q1==(10*HH+HL))
bao<=1'b0;
else
begin
bao_signal<=1'b0;
end
end
译码显示模块:
一、数码管显示:通过传入响应的4位十进制数,运用case语句转换输出相应的8位二进制显示码,送入数码管显示。
二、LED显示:
module display_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
assign s_out1=~s_out;
Endmodule
module SEG7_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; endcase
end
assign oSEG1=~oSEG; endmodule
module display_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
assign s_out1=~s_out; endmodule
设计过程常见问题:
(1)要注意编写程序的过程中begin和end配对问题,类似于C语言中的括号匹配问题,在编写计数模块时编译不通过,最后检查出是缺少一个end结束符号,经修改后编译通过。
(2)Verilog HDL语言编写时的语法问题。
在最初的计时模块的程序设计中,将小时、分钟的调节信号放在了另外的一个always语句块中,编译无法通过,经查阅资料,在Verilog HDL 语言的编写中应该注意不同的always语句块不可以对同一个变量进行操作,即一个变量不可以经过两个always语句块操作。
将对小时和分钟调节信号的操作与计时放在同一个语句块中,编译通过。
(3)数码管刚开始时显示于实际计数不一样,主要是由译码错误造成的原因。
数码管一开始不变化,说明计数没有进行,是由于分钟的输入脉冲信号错误引起。
心得体会
这次的课程设计结束了,在这次的设计中我学会了很多东西。
首先是对Verilog HDL语言的设计思想有了深入理解,将这种自顶向下的设计理念运用于实践中,设计多功能数字钟,突出了Verilog HDL作为硬件描述语言的良好可读性和可移植性,对上学期所学的而理论知识有了深刻的理解。
其次是对Verilog HDL语言的语法熟悉,在这次的课程设计中,我学习到很多Verilog HDL语言的语法知识,比如在两个不同的语句块中不能对同一个变量进行操作,比如在用Verilog HDL语言中编写程序时要注意begin和end语句的匹配问题,在使用Verilog HDL语言时不可以使用中文注释等等。
对于这种语言的学习也有了很大的帮助。
最后是设计作品时的设计逻辑和设计思想,在选择不同的系统方案时要综合考虑,选择最优方案。
各个模块的实现也要考虑综合情况而制定出最符合实际情况的实现方案,方案间要进行对比、实践,最终确定。
在这次的课程设计中我不仅学习到有关程序编写以及设计方面的逻辑思维,对系统功能的实现也有了较为深入的了解,对各模块的调试等也学习到不少东西,总之,从这次设计中学到很多东西,也巩固了我的理论学习。
1.生活如意,事业高升。
2.前程似锦,美梦成真。
3.年年今日,岁岁今朝。
4.百事大吉,万事顺利。
5.愿与同僚,共分此乐。
6.事业有成,幸福快乐。
7.生日快乐,幸福安康。
8.幸福快乐,与君同在。