MAX+Plus II多功能数字钟设计
自动化1001班 刘杰
学号
U200914402
多功能数字钟设计
一、实验目的
1. 掌握可编程逻辑器件的应用开发技术
——设计输入、编译、仿真和器件编程;
2. 熟悉一种EDA软件使用;
3. 掌握Verilog设计方法;
二、实验任务
1. 已知条件
MAX+Plus II软件
FPGA实验开发装置(该装置可以提供3路时钟信号和译码显示电路)
基本功能
具有“秒”、“分”、“时”计时功能,小时按24小时制计时。
具有校时功能,能对“分”和“小时”进行调整
2. 扩展功能
仿广播电台正点报时。在59分51秒、53秒、55秒、57秒、59秒发出音响结束时刻为整点。
定时控制,其时间自定;
3. 选做内容
任意时刻闹钟
自动报整点时数
小时计数器改为12翻1
三、数字钟设计分析-功能框图
四、设计编译
1. 设计输入
module top_clock (Second,ap,CP,nCR,EN,Adj_Min,Adj_Hour,ctrlbell,sethrkey,setminkey,
alarm,_1khz,_500hz,rhr,rmin);
input CP,nCR,EN,Adj_Min,Adj_Hour,ctrlbell,_1khz,_500hz,sethrkey,setminkey;
output[7:0] rhr,rmin,Second;
output alarm;
wire[7:0] set_hr,set_min,Hour,Minute;
wire alarm_clock,alarm_r,alarm_r1;
wire _1khz,_500hz,CP;
output ap;
reg[7:0] rhr,rmin,Second;
supply1 Vdd;
wire MinL_EN,MinH_EN,Hour_EN,Ap;
wire hrh_equ,hrl_equ,minh_equ,minl_equ;
wire time_equ;
//Hour:Minute:Second counter
counter10 U1(Second[3:0],nCR,EN,CP);
counter6 U2(Second[7:4],nCR,(Second[3:0]==4'h9),CP);
assign MinL_EN=Adj_Min?Vdd:(Second==8'h59);
assign MinH_EN=(Adj_Min&&(Minute[3:0]==4'h9))||(Minute[3:0]==4'h9)&&(Second==8'h59);
counter10 U3(Minute[3:0],nCR,MinL_EN,CP);
counter6 U4(Minute[7:4],nCR,MinH_EN,CP);
assign Hour_EN=Adj_Hour?Vdd:((Minute==8'h59)&&(Second==8'h59));
counter24 U5(Hour[7:4],Hour[3:0],nCR,Hour_EN,CP,Ap);
//若闹钟调整使能端开启,数码管显示闹铃设置时间,反之显示时钟时间。
/*always @ (setminkey or sethrkey) case({setminkey,sethrkey})
2'b11:begin rmin[7:0]=set_min[7:0];rhr[7:0]=set_hr[7:0]; end
2'b10:begin rmin[7:0]=set_min[7:0];rhr[7:0]=Hour[7:0];end
2'b01:begin rmin[7:0]=Minute[7:0];rhr[7:0]=set_hr[7:0];end
2'b00:begin rmin[7:0]=Minute[7:0];rhr[7:0]=Hour[7:0];end
endcase*/
//选择类型1
always @(posedge CP)
if(setminkey) rmin[7:0]=set_min[7:0];
else rmin[7:0]=Minute[7:0];
always @(posedge CP)
if (sethrkey) rhr[7:0]=set_hr[7:0];
else rhr[7:0]=Hour[7:0];
//或者选择类型2
counter10 UC0(set_min[3:0],Vdd,setminkey,CP);
counter6 UC1(set_min[7:4],Vdd,(set_min[3:0]==4'h9),CP);
counter24 SU2(set_hr[7:4],set_hr[3:0],Vdd,sethrkey,CP,ap);
//comparate the set time
comparator SU4(hrh_equ,set_hr[7:4],Hour[7:4]);
comparator SU5(hrl_equ,set_hr[3:0],Hour[3:0]);
comparator SU6(minh_equ,set_min[7:4],Minute[7:4]);
comparator SU7(minl_equ,set_min[3:0],Minute[3:0]);
assign time_equ=(hrh_equ && hrl_equ && minh_equ && minl_equ);
assign alarm_clock=ctrlbell?(time_equ&&_500hz):1'b0;
ring U7(alarm_r,Minute,Second,_1khz,_500hz);
//仿广播电台正点报时
ring1 U8(alarm_r1,Minute,Hour,Second,_500hz);
//自动报整点时数
assign alarm=alarm_r||alarm_r1||alarm_clock ;
//将闹钟、报时全部归于扬声器输出端
endmodule
module counter10(Q,nCR,EN,CP);
input CP,nCR,EN;
output[3:0]Q;
reg [3:0] Q;
always@(posedge CP or negedge nCR)
begin
if(~nCR)Q<=4'b0000;
else if(~EN) Q<=Q;
else if(Q==4'b1001)Q<= 4'b0000;
else Q<=Q+1'b1;
end
endmodule
module counter6(Q,nCR,EN,CP);
input CP,nCR,EN;
output[3:0]Q;
reg [3:0]Q;
always @(posedge CP or negedge nCR)
begin
if(~nCR) Q<=4'b0000;
else if(~EN) Q<=Q;
else if(Q==4'b0101) Q<=4'b0000;
else Q<=Q+1'b1;
end
endmodule
module counter24(CntH,CntL,nCR,EN,CP,ap);
input CP,nCR,EN;
output[3:0]CntH,CntL;
output ap;
reg [3:0]CntH,CntL;
reg ap;
reg CO;
always@(posedge CP or negedge nCR)
begin
if(~nCR) begin {CntH,CntL}<=8'b00010010; ap<=1'b0;end
else if(~EN)begin {CntH,CntL}<={CntH,CntL};ap<=ap;end
else if((CntH>1)||(CntL>9)||((CntH==1)&&(CntL>=2)))
begin
CntH<=4'b0000; CntL<=4'b0001;ap<=(~ap);
end
else if((CntH==1)&&(CntL<2))
begin CntH<=CntH; CntL<=CntL+1'b1;end
else if(CntL==9)
begin CntH<=CntH+1'b1; CntL<=4'b0000;end
else
begin CntH<=CntH; CntL<=CntL+1'b1;end
end
endmodule
module comparator(equ,a,b);
input [3:0]a,b;
output equ;
assign equ=(a==b);
endmodule
//电台报时
module ring(alarm_r,minute,second,_1khz,_500hz);
input _1khz,_500hz;
wire _1khz,_500hz;
input [7:0]minute,second;
output alarm_r;
reg alarm_r;
always @(minute or second)
if(minute==8'h59)
case(second)
8'h51:alarm_r=_500hz;
8'h53:alarm_r=_500hz;
8'h55:alarm_r=_500hz;
8'h57:alarm_r=_500hz;
8'h59:alarm_r=_1khz;
default:alarm_r=1'b0;
endcase
else alarm_r=1'b0;
endmodule
//整点报时
module ring1(alarm_r1,minute,hour,second,_500hz);
input _500hz;
wire _500hz;
input [7:0]minute,second,hour;
output alarm_r1;
reg alarm_r1;
always @(hour or minute or second)
if(minute==8'h00)
assign alarm_r1=((second==8'h01)||(second==8'h03)||(second==8'h05)||
(second==8'h07)||(second==8'h09)||(second==8'h11)||(second==8'h13)||
(second==8'h15)||(second==8'h17)||(second==8'h19)||(second==8'h21)||
(second==8'h23))&&_500hz&&(second<(hour*2));
endmodule
2. 电路仿真
图为起始设置闹钟,由图可得出闹铃设为1h1min处, 并能观察出电路仿真自动报整点时数.
在设置闹铃后,可分辨观察到仿广播电台正点报时、自动报整点时数
五.实验心得
1.该课程设计所设计的各种模块和原理与数字电子技术的理论知识紧密结合。所以这样与课本知识关联紧的课程实际比较容易完成,同时不仅加强了对书本基础知识的理解,而且实践环节得到了很好的锻炼,能够激发实践者对数字电子实验的兴趣甚至能够自己动手完成一些课题项目。
2.学习使用软件,可以方便轻松的解决一些复杂电路的问题,可是说是书本知识的具体实际话。
3.课程设计的多样化可以开发思维,鼓励创新,同时也检验了自己对所学知识的牢固性,没有扎实的理论知识基础是不可能有自己的设计方案的,所以我们以后应该学好理论知识,才能创造出我们自己感兴趣的设计和作品。
第二篇:数电实验数字钟报告
?????21
???2120401028?????
??????????
摘要
数字钟是人们日常生活中经常使用的计时工具,本次的课程设计是基于VerilogHDL的多功能数字钟,完成时、分、秒的显示功能。设计利用VerilogHDL语言自顶向下的设计理念,突出其作为硬件描述语言的良好的可读性、可移植性以及易于理解等优点。通过ISE13.1软件完成仿真、综合。程序下载到FPGA芯片后,可用于实际的数字钟显示。
此次设计的逻辑结构主要由分频器、计数器和译码显示器三个模块构成。分频模块将50Mhz系统基准时钟分频产生两路时钟信号,一路是1HZ的数字钟计时工作频率,一路是数码管动态显示的扫描频率;计时模块对1HZ的时钟信号进行计时,分为时、分、小时三个部分(仅显示分和小时);译码显示模块采用动态扫描的方式完成数码管的显示。最后通过主模块调用三个子模块函数完成整个设计。?????????
1、设计一个完整的数字钟,小时和分钟用数码管显示,秒用发光二极管闪烁显示,每秒闪烁一次。如有可能,增加校时功能。
2、在开发板上运行有关程序。
3、熟悉并掌握Verilog程序开发及设计。
???????显示模块1Hz
计时模块分频模块
复位小时调节分钟调节系统时钟
???????????????
计时模块分为三部分:时,分,秒。由主时钟分频得到秒信号,计秒到60时分加1,秒清零,计分到60时,分清零,小时加1,计小时到24时,全部清零。
下图为工作原理框图:
开始1Hz时钟信号是否清零信号秒是否满60
秒+1秒清零
分是否满60
分+1分清零
时是否满24
小时+1
全部清零
程序编写:
译码显?模块:
···································································································moduleclocktjjs(
inputclk,
inputclr,
input[1:0]FLAG,
input[5:0]Stime,
inputSetH,
inputSetM,
outputSflash,
outputreg[6:0]a_to_g,
outputreg[3:0]an
);
reg[3:0]cent60L;
reg[3:0]cent60H;
reg[3:0]cent24L;
reg[3:0]cent24H;
reg[3:0]LED1,LED2,LED3,LED4;
reg[1:0]s;
reg[3:0]digit;
reg[16:0]clkdiv;
reg[26:0]q1;
regsec;
integerss;
integeri;
initialbegin
cent60L=9;
cent60H=5;
cent24L=3;
cent24H=2;
ss=0;
LED4=cent60L;
LED3=cent60H;
LED2=cent24L;
LED1=cent24H;
end
always@(*)
begin
an=4'b1111;
s<=clkdiv[16:15];
an[s]=0;
case(s)
0:digit<=LED1;
1:digit<=LED2;
2:digit<=LED3;
3:digit<=LED4;
default:digit<=LED4;endcase
case(digit)
0:a_to_g=7'b0000001;1:a_to_g=7'b1001111;2:a_to_g=7'b0010010;3:a_to_g=7'b0000110;4:a_to_g=7'b1001100;5:a_to_g=7'b0100100;6:a_to_g=7'b0100000;7:a_to_g=7'b0001111;8:a_to_g=7'b0000000;9:a_to_g=7'b0001100;'hA:a_to_g=7'b0001000;'hB:a_to_g=7'b1100000;'hC:a_to_g=7'b0110001;'hD:a_to_g=7'b1000010;'hE:a_to_g=7'b0110000;'hF:a_to_g=7'b0111000;default:a_to_g=7'b0000001;endcase
end
always@(posedgeclk)
begin
clkdiv<=clkdiv+1;
end
时钟程序,初始状态
···································································································always@(posedgeclkorposedgeclr)
begin
if(clr==1)
begin
q1<=0;
LED1=0;
LED2=0;
LED3=0;
LED4=0;
cent60L<=0;
cent60H<=0;
cent24L<=0;
cent24H<=0;
ss<=0;
end
分钟调节模块
···································································································
elseif(FLAG==2'b10)
begin
if(SetM)
begin
if(Stime<=59)
begin
for(i=0;i<6;i=i+1)
begin
if(Stime[5:0]-i*10<10)
begin
cent60L<=Stime[5:0]-i*10;
cent60H<=i;
i=6;
end
end
end
else
begin
cent60H<=0;
cent60L<=0;
end
ss<=0;
LED4[3:0]=cent60L[3:0];
LED3[3:0]=cent60H[3:0];
end
end
?时调节模块
···································································································
elseif(FLAG==2'b11)
begin
if(SetH)
begin
if(Stime<=23)
begin
for(i=0;i<=3;i=i+1)
begin
if(Stime[5:0]-i*10<10)
begin
cent24L<=Stime[5:0]-i*10;
cent24H<=i;
i=6;
end
end
end
else
begin
cent24L<=0;
cent24H<=0;
end
ss<=0;
LED2[3:0]=cent24L[3:0];
LED1[3:0]=cent24H[3:0];
end
end
elseif(FLAG==2'b00)
计时模块:
···································································································
begin
if(q1==50000000)
begin
q1<=0;
sec=~sec;
LED4[3:0]=cent60L[3:0];
LED3[3:0]=cent60H[3:0];
LED2[3:0]=cent24L[3:0];
LED1[3:0]=cent24H[3:0];
ss<=ss+1;
if(ss==59)
begin
ss<=0;
cent60L<=cent60L+1;
if(cent60L==9)
begin
cent60L<=0;
cent60H<=cent60H+1;
end
if(cent60H==5&¢60L==9)
begin
cent60L<=0;
cent60H<=0;
cent24H<=cent24H+1;
if(cent24H==2&¢24L==3)
end
end
else
q1<=q1+1;
end
end
assignSflash=sec;
endmodule
约束?件部分:
ucf?件如下:
NET"a_to_g[6]"LOC=L14;NET"a_to_g[5]"LOC=H12;NET"a_to_g[4]"LOC=N14;NET"a_to_g[3]"LOC=N11;NET"a_to_g[2]"LOC=P12;NET"a_to_g[1]"LOC=L13;NET"a_to_g[0]"LOC=M12;NET"an[3]"LOC=F12;NET"an[2]"LOC=J12;NET"an[1]"LOC=M13;cent24L<=cent24L+1;if(cent24L==9)begincent24L<=0;endbegincent24L<=0;cent24H<=0;endend
NET"an[0]"LOC=K14;
NET"clk"LOC="B8";
NET"clr"LOC="G12";
NET"Sflash"LOC="M5";
NET"FLAG[0]"LOC="P11";
NET"FLAG[1]"LOC="L3";
NET"Stime[5]"LOC="N3";
NET"Stime[4]"LOC="E2";
NET"Stime[3]"LOC="F3";
NET"Stime[2]"LOC="G3";
NET"Stime[1]"LOC="B4";
NET"Stime[0]"LOC="K3";
NET"SetH"LOC="M4";
NET"SetM"LOC="C11";
?????????
将程序下载到BASYS2板子上后,可以看到LED灯每秒闪一下,前两个数码管为数字钟小时小时显示,后两个为分钟的显示,数码管下按键为清零功能,另外通过开关控制可以将六位二进制数赋值给小时或分钟位,实现校表的功能,这样便实现了简易数字钟的功能。编写程序过程中出现的语法问题:
1、要注意编写程序的过程中begin和end配对问题,类似于C语言中的括号匹配问题,在编写计数模块时编译不通过,最后检查出是缺少一个end结束符号,经修改后编译通过。
2、在程序清零时,应在计数到59清零(小时为23清零),因为
计数是从0开始,到59已经计满60个数,所以应该进行清零。数码管显示也为从59到00,而没有显示60。
??????
在这次的设计中我学会了很多东西。首先是对VerilogHDL语言的设计思想有了深入理解,将这种自顶向下的设计理念运用于实践中,设计多功能数字钟,突出了VerilogHDL作为硬件描述语言的良好可读性和可移植性,对所学的而理论知识也有了深刻的理解。
其次是对VerilogHDL语言的语法熟悉,在这次的课程设计中,我学习到很多VerilogHDL语言的语法知识,比如在两个不同的语句块中不能对同一个变量进行操作,比如在用VerilogHDL语言中编写程序时要注意begin和end语句的匹配问题,在使用VerilogHDL语言时不可以使用中文注释等等。对于这种语言的学习也有了很大的帮助。
最后是设计作品时的设计逻辑和设计思想,各个模块的实现要考虑综合情况而制定出最符合实际情况的实现方案,方案间要进行对比、实践,最终确定。
在这次的课程设计中我不仅学习到有关程序编写以及设计方面的逻辑思维,对系统功能的实现也有了较为深入的了解,对各模块的调试等也学习到不少东西,总之,从这次设计中学到很多东西,也巩固了我的理论学习。