verilogHDL课设数字钟.docx
《verilogHDL课设数字钟.docx》由会员分享,可在线阅读,更多相关《verilogHDL课设数字钟.docx(27页珍藏版)》请在冰豆网上搜索。
verilogHDL课设数字钟
课程设计(报告)任务书
(理工科类)
Ⅰ、课程设计(报告)题目:
实时时钟电路的设计
Ⅱ、课程设计(论文)工作容
一、课程设计目标
《硬件描述语言》是一门技术性、应用性很强的学科,实验课教学是它的一个极为重要的环节。
不论理论学习还是实际应用,都离不开实验课教学。
如果不在切实认真地抓好学生的实践技能的锻炼上下功夫,单凭课堂理论课学习,势必出现理论与实践脱节、学习与应用脱节的局面。
《HDL项目设计》的目的就是让同学们在理论学习的基础上,通过完成一个涉及时序逻辑、组合逻辑、声光输出的,具有实用性、趣味性的小系统设计,使学生不但能够将课堂上学到的理论知识与实际应用结合起来,而且能够对分析、解决实际的数字电路问题进一步加深认识,为今后能够独立进行某些数字应用系统的开发设计工作打下一定的基础。
二、课程设计任务与要求
(1)设计一个数码管实时显示时、分、秒的数字时钟(24小时显示模式);
(2)为了演示方便,应具有分钟、小时快进功能;
(3)时、分、秒设置功能(选作)。
三、课程设计考核
平时20%;验收40%;报告40%
摘要
数字钟是人们日常生活中经常使用的计时工具,本次的课程设计是基于VerilogHDL的多功能数字钟,完成时、分、秒的显示功能。
设计利用VerilogHDL语言自顶向下的设计理念,突出其作为硬件描述语言的良好的可读性、可移植性以及易于理解等优点。
通过QuartusII5.0和ModelSimSE6.1f软件完成仿真、综合。
程序下载到FPGA芯片后,可用于实际的数字钟显示中。
此次设计的逻辑结构主要由分频器、计数器和译码显示器三个模块构成。
分频模块将50Mhz系统基准时钟分频产生两路时钟信号,一路是1HZ的数字钟计时工作频率,一路是数码管动态显示的扫描频率;计时模块对1HZ的时钟信号进行计时,分为时、分、秒三个部分;译码显示模块采用动态扫描的方式完成数码管的显示。
最后通过主模块调用三个子模块函数完成整个设计。
【关键词】硬件描述语言FPGA数字钟动态显示
ABSTRACT
ThedigitalclockisoftenusedinPeople'sDailylifeofthecourse,thetimingtooldesignisbasedonthemulti-functiondigitalclockVerilogHDL,plete,minutesandsecondsdisplayfunction.DesignVerilogHDLlanguageusingthetop-downdesignconcept,thehardwaredescriptionlanguageasthegoodreadabilityandportabilityandeasytounderstand,etc.ThroughtheQuartusII5.0andModelSimSE6.1fsoftwaresimulation,andprehensive.DownloadtoFPGAchipscanbeusedaftertheactual,digitalclockshows.
Thedesignofthelogicstructureconsistsmainlyofprescaler,counteranddecodingdisplaythreemodules.50Mhzsystemfrequencymodulewillproducebenchmarkclockclocksignal,two1HZwayisthedigitalclockfrequency,dynamicdisplayofdigitaltubeisscanning.Timermodulesfor1HZclocksignaltiming,whenintothreeparts,minutesandseconds,DecodedisplaymoduleUSESdynamicscanningofthedigitaldisplay.Throughthemainmodulecallingthreemodulesfunctionpletethewholedesign.
【Keywords】HardwaredescriptionlanguageFPGAAdigitalclockDynamicdisplay
第一章系统设计
第一节课题目标及总体方案
目前,电子系统向集成化、大规模和高速度等方向发展,以硬件描述语言和逻辑综合为基础的自顶向下的电路设计方法得到迅猛发展。
本次设计课题目标完成是基于VerilogHDL语言的多功能数字钟的设计,通过数码管实时显示时、分、秒,具有小时和分钟快进功能。
设计遵循VerilogHDL语言的设计理念,代码具有良好的可读性和易理解性。
系统主要分三个模块实现,分别是分频模块、计数模块、译码显示模块。
分频模块用来提供计时电路工作时钟(1HZ)和数码管动态显示的扫描频率(200HZ—500HZ),计数模块是对1s信号源进行秒、分、时的计时,译码显示模块是通过控制信号控制八个数码管的位选、段选来实现对译码后的计时信号进行动态显示。
主函数通过调用三个子模块来实现整体的系统功能。
第二节系统模块实现方案对比及实现
一、分频模块实现方案
分频模块用于为系统的实现提供稳定的工作频率和计时信号源,要求产生两路不同频率的信号,分频为1HZ频率的信号作为计时模块的信号源,200HZ的信号用于数码管动态显示的扫描频率。
方案一:
定义变量并根据需要得到的分频信号设定计数值,对该变量进行加或减计数,每到达一次计数值点,将该变量清零或重置,并且对输出信号取一次反,即可以得到所需的分频信号。
parameterC_COUNT=25'd500_00_000;//定义变量C_COUNT并给该变量设定计数值点
always(posedgeclock)
begin
if(counter==0)
begin
counter<=C_COUNT;//减计数到0后对该变量进行重置
clkdiv<=~clkdiv;//对输出信号取反一次
end
else
counter<=counter-1;//对变量减计数
end
方案二:
定义变量并且设定一个上限值,每次加计数到该上限值时,输出该计数值的最高位
parameterDIV_SIZE=25;
always(posedgeclock)
counter=counter+1;
assignclkdiv=counter[DIV_SIZE-1];
方案比较:
方案二能够产生准确的1HZ的频率且在程序实现上较为简单,但在产生数码管动态显示的扫描频率时可调度不如方案一,即在调节200HZ-500HZ围的频率时DIV_SIZE变量的值不便于计算;方案一实现分频信号的设计思路简单易懂,且变量值易于计算和调节。
故采用方案一。
分频模块的实现:
moduleclkgen(clock,clkdiv,clk500);
inputclock;
outputclkdiv;
outputclk500;
reg[31:
0]counter1;
regclkdiv;
regclk500;
reg[31:
0]counter0;
parameterC_COUNT0=25'd500_00_000;//变量0用于产生1HZ的信号
parameterC_COUNT1=25'd100_000;//变量1用于产生500HZ的信号
/********产生1HZ频率的信号*********/
always(posedgeclock)
begin
if(counter0==0)
begin
counter0<=C_COUNT0;
clkdiv<=~clkdiv;
end
else
counte0<=counter0-1;
end
/********产生500HZ频率的信号*********/
always(posedgeclock)
begin
if(counter1==0)
begin
counter1<=C_COUNT1;
clk500<=~clk500;
end
else
counter1<=counter1-1;
end
endmodule
在该程序段中,只要更改变量counter的值,就可以改变输出频率。
适当调节counter1的值,使得数码管动态显示在一个最佳的显示状态。
变量counter的计算方法是:
已知所需要的频率,根据公式(counter值=系统基准频率/所需频率)即可求得变量值。
二、计时模块实现方案
计时模块是对1s的信号源进行秒计时,计时满后向上进位的设计思想
方案一:
计时采用十进制数计时,然后分别对时、分、秒三个数进行取余数、取除数,分别得到三个数的高位和低位
always(posedgeclkdivornegedgereset)
begin
if(!
reset)//判断是否为复位信号
begin
th=8'd0;//将小时信号清零
hH=th/10;//取除操作求得小时信号的高位
hL=th%10;//取余操作求得小时信号的低位
tm=8'd0;
mH=tm/10;
mL=tm%10;
ts=8'd0;
sH=ts/10;
sL=ts%10;
end
else
begin
if(ts==59)//判断秒钟信号是否计满
begin
begin
ts<=8'd0;//秒信号清零
sH=ts/10;
sL=ts%10;
end
begin
if(tm==59)//判断分信号是否计满
begin
begin
tm<=8'd0;//分信号清零
mH=tm/10;
mL=tm%10;
end
begin
if(th==23)//判断小时信号是否计满
begin
th<=8'd0;//小时信号清零
hH=th/10;
hL=th%10;
end
else
begin
th<=th+8'd1;
hH=th/10;
hL=th%10;
end
end
end
else
begin
tm=tm+8'd1;
mH=tm/10;
mL=tm%10;
end
end
end
else
begin
ts=ts+1'd1;
sH=ts/10;
sL=ts%10;
end
end
end
方案二:
计时分每个信号的高低位进行判断及计时
if(sL==9)
begin
sL<=0;
if(sH==5)
begin
sH<=0;
if(mL==9)
begin
mL<=0;
if(mH==5)
begin
mH<=0;
if(hL==9)
begin
hL<=0;
hH<=hH+1;
end
elseif(hL==3&&hH==2)
begin
hL<=0;
hH<=0;
end
elsehL<=hL+1;
end
elsemH<=mH+1;
end
elsemL<=mL+1;
end
elsesH<=sH+1;
end
elsesL<=sL+1;end
方案比较:
方案一在思路方面较为通俗易懂,且判断过程简短明了,但在程序中使用的进制数较多,进制转换时容易混乱,在最终的显示时出现毛刺干扰现象,且该方案中不便于增加小时和分钟的调节信号,方案最终失败。
方案二虽然判断复杂,但没有进制混杂引起的毛刺现象,在最终的数码管显示时较为稳定。
综合考虑,使用方案二。
时钟调节模块的实现:
modulecounter(clkdiv,reset,S1,S2,hH,hL,mH,mL,sH,sL);
inputclkdiv;
inputreset;
inputS1;
inputS2;
outputhH;
outputhL;
outputmH;
outputmL;
outputsH;
outputsL;
reghH;
reghL;
regmH;
regmL;
regsH;
regsL;
reg[7:
0]th;//十进制的小时信号
reg[7:
0]tm;//十进制的分钟信号
reg[7:
0]ts;//十进制的秒信号
always(posedgeclkdivornegedgerst)
/******判断是否为复位信号********/
if(!
rst)
begin
sL<=0;
sH<=0;
mL<=0;
mH<=0;
hL<=0;
hH<=0;
end
/******判断是否为小时调节信号********/
else
begin
if(!
S1)
begin
if(hL==9)
begin
hL<=0;
hH<=hH+1;
end
elseif(hL==3&&hH==2)
begin
hL<=0;
hH<=0;
end
else
hL<=hL+1;
end
/******判断是否为分钟调节信号********/
elseif(!
S2)
begin
if(mL==9)
begin
mL<=0;
if(mH==5)
mH<=0;
else
mH<=mH+1;
end
else
mL<=mL+1;
end
elseif(sL==9)
begin
sL<=0;
if(sH==5)
begin
sH<=0;
if(mL==9)
begin
mL<=0;
if(mH==5)
begin
mH<=0;
if(hL==9)
begin
hL<=0;
hH<=hH+1;
end
elseif(hL==3&&hH==2)
begin
hL<=0;
hH<=0;
end
elsehL<=hL+1;
end
elsemH<=mH+1;
end
elsemL<=mL+1;
end
elsesH<=sH+1;
end
elsesL<=sL+1;
end
endmodule
三、译码显示模块的实现
译码显示模块采用的是数码管的动态扫描方式,定义变量来控制数码管显示的位选信号(通过变量Uweixuan来给数码管的各个位选位送出低电平信号)。
由于试验箱上的八个数码管是每四个的位选端连接在一起,分为两组数码管,所以定义两个变量show_temp_H和show_temp_L来分别控制两组数码管,该变量决定了哪个数码管显示哪个信号,再根据这两个变量判断显示的是哪一组数码管,确定之后通过送入的数据利用变量HIGH和LOW控制数码管的段选信号完成译码显示工作。
moduledecode(clk500,reset,hH,hL,mH,mL,sH,sL,HIGH,LOW,);
inputclk500;
inputreset;
inputhH,hL;//小时的高、低位信号
inputmH,mL;//分钟的高、低位信号
inputsH,sL;//秒的高、低位信号
output[6:
0]HIGH,LOW;//分别控制两组数码管的段选信号
output[7:
0];//控制数码管的位选信号
reg[7:
0]show_temp_H,show_temp_L;//定义的部变量,决定数码管上显示的信号
reg[7:
0];
reg[7:
0]Uweixuan;//通过控制变量给数码管的位选位送出高低电平
reg[2:
0]sm;//扫描变量
reg[6:
0]HIGH;//控制高四位数码管的段选信号
reg[6:
0]LOW;//控制低四位数码管的段选信号
always(posedgeclk200)
begin
if(sm==3'b111)
sm<=3'b000;
else
sm<=sm+3'b001;
Uweixuan<=Uweixuan<<1;
//通过对变量的左移操作依次给数码管的位选位送高电平
if(Uweixuan==8'b0000_0000)
Uweixuan<=8'b0000_0001;//给Uweixuan变量设定的初值
=~Uweixuan;
//共阴极数码管显示的位选信号应为低电平,故对Uweixuan变量进行取反操作
end
always(sm)
begin
case()
8'b1111_1110:
show_temp_H=sL;
//最低位的数码管用于显示秒信号的低位
8'b1111_1101:
show_temp_H=sH;
8'b1111_1011:
show_temp_H=4'b1010;
8'b1111_0111:
show_temp_H=mL;
8'b1110_1111:
show_temp_L=mH;
8'b1101_1111:
show_temp_L=4'b1010;
8'b1011_1111:
show_temp_L=hL;
8'b0111_1111:
show_temp_L=hH;
//最高位的数码管用于显示小时信号的高位
endcase
end
always(show_temp_H)//高四位的数码管显示
begin
case(show_temp_H)
4'b0000:
HIGH=~7'b011_1111;
4'b0001:
HIGH=~7'b000_0110;
4'b0010:
HIGH=~7'b101_1011;
4'b0011:
HIGH=~7'b100_1111;
4'b0100:
HIGH=~7'b110_0110;
4'b0101:
HIGH=~7'b110_1101;
4'b0110:
HIGH=~7'b111_1101;
4'b0111:
HIGH=~7'b000_0111;
4'b1000:
HIGH=~7'b111_1111;
4'b1001:
HIGH=~7'b110_1111;
4'b1010:
HIGH=~7'b100_0000;
defaultHIGH=~7'b000_0000;
endcase
end
always(show_temp_L)//低四位的数码管显示
begin
case(show_temp_L)
4'b0000:
LOW=~7'b011_1111;
4'b0001:
LOW=~7'b000_0110;
4'b0010:
LOW=~7'b101_1011;
4'b0011:
LOW=~7'b100_1111;
4'b0100:
LOW=~7'b110_0110;
4'b0101:
LOW=~7'b110_1101;
4'b0110:
LOW=~7'b111_1101;
4'b0111:
LOW=~7'b000_0111;
4'b1000:
LOW=~7'b111_1111;
4'b1001:
LOW=~7'b110_1111;
4'b1010:
LOW=~7'b100_0000;
defaultLOW=~7'b000_0000;
endcase
end
endmodule
第三节系统及各模块方框图说明
分频模块:
输入信号为系统基准时钟50MHZ
输出为1HZ频率和200HZ-500HZ频率两路信号
计时模块:
输入信号1s时钟信号clkdiv,复位信号reset,小时调节信号S1,分钟调节信号S2
输出信号为小时信号的高、低位hH、hL,分钟信号的高、低位mH、mL,秒信号的高、低位sH、sL
译码显示模块:
输入信号该模块工作频率500HZ,复位信号reset,小时信号的高、低位hH、hL,分钟信号的高、低位mH、mL,秒信号的高、低位sH、sL
输出信号为八个数码管的位选控制信号,高四位数码管显示的段选信号HIGH,低四位数码管显示的段选信号LOW
系统功能实现:
主函数的输入信号为系统基准时钟信号、复位信号、小时调节信号、分钟调节信号。
输出信号为数码管的位选控制信号、高四位数码管的段选控制信号HIGH、低四位数码管的段选控制信号LOW。
第二章结果与讨论
第一节调试现象及解决分析
系统方案确定,程序编写完成后进入调试阶段,调试分模块进行。
首先是分频模块,在程序编写且编译通过后,加观察窗口观察所得波形,可以判定是否得到所需频率的信号。
在调试过程中出现的问题:
一、编写程序过程中出现的语法问题
(1)要注意编写程序的过程中begin和end配对问题,类似于C语言中的括号匹配问题,在编写计数模块时编译不通过,最后检查出是缺少一个end结束符号,经修改后编译通过。
(2)VerilogHDL语言编写时的语法问题。
在最初的计时模块的程序设计中,将小时、分钟的调节信号放在了另外的一个always语句块中,编译无法通过,经查阅资料,在VerilogHDL语言的编写中应该注意不同的always语句块不可以对同一个变量进行操作,即一个变量不可以经过两个always语句块操作。
将对小时和分钟调节信号的操作与计时放在同一个语句块中,编译通过。
二、方案实现过程中出现的问题
(1)数码管显示高四位、低四位保持一致。
在数码管显示时没有达到预计的目标,没有实现动态显示,而是高四位同时显示一个数字,低四位同时显示一个数字,经过对程序的检查调试,是因为对数码管位选端口的控制不正确,初始程序用是通过变量Uweixuan给数码管位选端依次送入高电平:
Uweixuan<=Uweixuan<<1;
if(Uweixuan==8'b0000_0000)
Uweixuan<=8'b0000_0001;
=~Uweixuan;
分析得知是信号没有正确的送给数码管显示,经修改对后成功显示。
修改的程序增加了一个扫描信号:
always(posedgeclk200)
begin
if(sm==3'b111)
sm<=3'b000;
else
sm<=sm+3'b001;
在扫描信号到来时判断信号并给数码管送出位选端控制信号。
(2)数码管计时只显示二进制数。
初始程序使用的是十进制数计时,对十进制数进行取除、取余操作,再译码,程序中进制数使用混乱,出现毛刺现象。
将计时模块的程序重新修改后实现