您好,欢迎访问三七文档
1/11HDL综合实验—数字钟设计一、实验设计要求设计一个完整的数字钟,小时和分钟用数码管显示,秒用发光二极管闪烁显示,每秒闪烁一次,并增加异步清零和校时功能。在开发板上运行有关程序,测试上述功能的实现情况。二、实验原理数字钟的设计关键在于产生秒脉冲、对秒脉冲计数产生分和小时以及动态显示时、分、秒信息。首先,我们要实现的数字钟可以用如图1所示的逻辑图来简化表示。由逻辑图可以看出,实现数字钟需要4个逻辑开关clr(清零)、crthl(时校准)、crtml(分低位校准)、crtmh(分高位校准),一个主时钟信号clk,一个LED闪烁用来显示秒脉冲sec,四个数码管显示时和分的高低位。逻辑图中引脚说明:clk—主时钟信号B8clr—清零按钮P11sec—秒脉冲M5crtml—分低位校准G12crtmh—分高位校准C11crthl—时校准M41、秒脉冲产生主时钟的频率为50MHz,实验要求一秒闪烁一次,所以设置一个计数变量,主时钟每来一个上升沿,计数变量增一,计数到25000000的时候归零,对应的秒脉冲电平翻转一次,LED亮0.5s,当计数变量再次归零时,秒脉冲电平翻转,LED灭0.5s,按此周期循化。这样就可以实现一秒闪烁一次的秒脉冲信号。对秒脉冲计数产生分和小时与秒脉冲产生原理相似,对秒脉冲进行60进制计数,每计一个周期,分增加一,需要注意的是分的递增要把分的低位和高位分开判断,因为实际中分的低位和高位各用一个数码管显示。相似的对分进行60进制计数可以得到时的低位和高位,在时递增到23的时候,下一个状态要归零。clkclrsecCLOCKcrthlcrtmhcrtml数码管图12/112、动态显示时、分、秒在需要多个数码管显示的电路系统中,都采用动态扫描显示的方式。动态扫描方式,就是分时循环显示,多个数码管轮流交替点亮。这种方式的依据是利用人眼的视觉滞留现象,只要在1秒内发光管亮24次以上,每次点亮时间维持2ms以上,则人眼感觉不到闪烁,宏观上仍可以看到多位LED同时显示的效果。动态显示可以简化硬件、降低成本、减小功耗。在程序中实现的时候需要注意每次使能的时间间隔设置,控制时间间隔的序列不能太长,否则会闪烁现象。本实验设置的是大约间隔5.2ms使能一次,具体语句见代码部分。三、设计方法和步骤1、建立工程文件File—NewProject—输入工程文件名:clock1—选择Family:Spartan3E;Device:XC3S100E;Package:CP132;PreferredLanguage:Verilog—English。2、输入Verilog程序Project—NewSource—选VerilogModule—输入文件名:clock1—点击Next按钮—初步确定输入输出引脚(之后在程序中可以更改)—点击Next按钮—点击Finish按钮—进入程序输入界面—在moduleclock1中编写数字钟的Verilog程序。程序代码如下,部分语句说明见行后注释。moduleclock1(inputwireclk,inputwireclr,inputwirecrtml,inputwirecrthl,inputwirecrtmh,inputwirecrthh,outputregsec,outputreg[7:0]atg,outputreg[3:0]an);//中间变量定义reg[3:0]led0_no,led1_no,led2_no,led3_no;reg[1:0]s;reg[3:0]digit;reg[19:0]clkdiv;3/11reg[26:0]ql,q;//计数变量reg[3:0]min_L,min_H,hour_L,hour_H;reg[5:0]sec_no;//60进制计数变量regp;//记录sec的翻转//初始化initialbeginmin_L=0;min_H=0;hour_L=0;hour_H=0;led3_no=min_L;led2_no=min_H;led1_no=hour_L;led0_no=hour_H;end//动态数码管扫描显示always@(*)beginan=4'b1111;//禁止所有数码管显示s=clkdiv[19:18];//t=2^18/(50*10^6)=5.24288ms,因此大约每隔5.2ms使能anan[s]=0;//轮流控制其中一个数码管点亮case(s)0:digit=led0_no[3:0];1:digit=led1_no[3:0];2:digit=led2_no[3:0];3:digit=led3_no[3:0];default:digit=led3_no[3:0];endcasecase(digit)//七段译码转换0:atg=8'b10000001;1:atg=8'b11001111;2:atg=8'b10010010;3:atg=8'b10000110;4:atg=8'b11001100;5:atg=8'b10100100;6:atg=8'b10100000;7:atg=8'b10001111;8:atg=8'b10000000;9:atg=8'b10000100;'hA:atg=8'b10001000;'hB:atg=8'b11100000;4/11'hC:atg=8'b10110001;'hD:atg=8'b11000010;'hE:atg=8'b10110000;'hF:atg=8'b10111000;default:atg=8'b10000001;//0endcaseend//主时钟计数always@(posedgeclk)beginclkdiv=clkdiv+1;end//时钟程序always@(posedgeclkorposedgeclr)beginq=q+1;//校时计数//异步清零程序,处于清零状态时,数字钟不再跑时,当清零开关无效时恢复跑时功能if(clr==1)beginql=0;led0_no=0;led1_no=0;led2_no=0;led3_no=0;min_L=0;min_H=0;hour_L=0;hour_H=0;end//校时程序elseif(q==6250000)//间隔1/8秒触发校时,经过测试,校时时当按下一次按钮,显示数字增一,且反应及时,不会出现按一次增量大于一或反应缓慢的情况beginq=0;if(crtml==1)//分低位校准,0~9循环beginmin_L=min_L+1;led3_no=min_L;5/11if(min_L==9)min_L=0;endelseif(crtmh==1)//分高位校准,0~5循环beginmin_H=min_H+1;led2_no=min_H;if(min_H==5)min_H=0;endelseif(crthl==1)//时校准,0~23循环,用一个按钮开关控制beginhour_L=hour_L+1;led1_no=hour_L;if(hour_L==9)beginhour_L=0;//led1_no=hour_L;//end//elseif(crthh==1)//用两个按钮开关控制时校准的时高位校准程序,这里注释了该段部分代码,取消注释后可查看两个按钮开关控制时校准的效果//beginhour_H=hour_H+1;led0_no=hour_H;endif(hour_H==2&&hour_L==3)beginhour_H=0;hour_L=0;led0_no=hour_H;led1_no=hour_L;endendend//跑时程序elseif(ql==25000000)//产生秒脉冲的计数,计数2个周期为1秒beginql=0;sec=~sec;//秒闪烁显示,闪烁一次(含亮灭)为一秒led3_no=min_L;led2_no=min_H;led1_no=hour_L;led0_no=hour_H;6/11p=p+1;if(p==0)beginsec_no=sec_no+1;//秒递增if(sec_no==59)beginsec_no=0;min_L=min_L+1;//分低位递增if(min_L==9)beginmin_L=0;min_H=min_H+1;//分高位递增endif(min_H==5&&min_L==9)beginmin_L=0;min_H=0;hour_L=hour_L+1;//时低位递增if(hour_L==9)beginhour_L=0;hour_H=hour_H+1;//时高位递增endif(hour_H==2&&hour_L==3)beginhour_H=0;hour_L=0;endendendendendelseql=ql+1;//产生秒脉冲的计数递增endendmodule3、编写约束文件Project—NewSource—选ImplantationConstraintsFile—输入文件名:clock1—点击Next按钮—点击Finish按钮—输入ucf文件如下:#Basys2板上设计数字钟的约束文件:7/11netatg[0]loc=M12;netatg[1]loc=L13;netatg[2]loc=P12;netatg[3]loc=N11;netatg[4]loc=N14;netatg[5]loc=H12;netatg[6]loc=L14;netan[0]loc=K14;netan[1]loc=M13;netan[2]loc=J12;netan[3]loc=F12;netclkloc=B8;netclrloc=P11;//清零端netsecloc=M5;//秒显示netcrtmlloc=G12;//分低位校准netcrtmhloc=C11;//分高位校准netcrthlloc=M4;//时低位校准netcrthhloc=A7;//时高位校准,在程序改进后此按钮用不到netatg[7]loc=N13;//数码管小数点显示对应引脚4、综合、实现及生成编程文件点击快捷菜单上的Implement按钮—完成综合和实现,正确完成综合和实现后Synthesize-XST和ImplementDesign前显示对勾符号,然后双击GenerateProgrammingFile生成编程文件clock1.bit。正确生成编程文件后GenerateProgrammingFile前显示对勾符号。5、下载至FPGA进行测试点击Adept软件图标,打开后点击Browser按钮,在clock1工程文件夹下选择clock1.bit文件,点击打开按钮,编程文件就被加载到Adept里面,点击Program按钮,完成文件下载并在Basys2板上进行跑时、清零、校时功能的测试。四、实验结果下载完成后,因为程序里初始化部分设置的时间为00:00,所以数码管显示8/11如图2所示:图2并且可以看到用于秒显示的LED在以一秒为周期进行闪烁,闪烁60次后,计秒得分,分低位增加1。1、校时功能测试:通过G12、C11、M4三个校时按钮分别校准分低位、分高位、时到23:59,结果如图所示。然后等待1分钟,可以看到数码管显示变为00:00,如图3、图4所示。同时说明校时功能和跑时功能均正确。图3图49/112、异步清零功能测试:由校时按钮把数字钟显示时间调到11:22,如图所示,然后将清零开关P11打到“1”,可以立即看到数码管显示全部变为0,如图5、图6所示。说明清零功能正确。图5图6五、讨论和分析在实验过程中,出现了两个较为重要的问题,下面进行说明解释。1、校时按钮的灵敏度问题在实验室下载程序到FPGA之前,程序中校时按钮是用周期为0.5秒的脉冲触发的,这样下载后测试的效果是要把校时一直按住,才能增加,没有按一下加1的效果。听取老师的建议之后改为0.25秒触发一次,但效果依然不够好;最终经过调整测试,认为0.125秒触发一次效果最佳。改后涉及代码部分
本文标题:HDL综合实验
链接地址:https://www.777doc.com/doc-6191392 .html