verilog HDL课设数字钟Word文件下载.docx
《verilog HDL课设数字钟Word文件下载.docx》由会员分享,可在线阅读,更多相关《verilog HDL课设数字钟Word文件下载.docx(22页珍藏版)》请在冰豆网上搜索。
![verilog HDL课设数字钟Word文件下载.docx](https://file1.bdocx.com/fileroot1/2022-12/19/2e5200e5-97dd-4a23-950e-2c6a34f8b217/2e5200e5-97dd-4a23-950e-2c6a34f8b2171.gif)
【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-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;
0]counter0;
parameterC_COUNT0=25'
//变量0用于产生1HZ的信号
parameterC_COUNT1=25'
d100_000;
//变量1用于产生500HZ的信号
/********产生1HZ频率的信号*********/
always(posedgeclock)
if(counter0==0)
counter0<
=C_COUNT0;
counte0<
=counter0-1;
/********产生500HZ频率的信号*********/
if(counter1==0)
counter1<
=C_COUNT1;
clk500<
=~clk500;
=counter1-1;
endmodule
在该程序段中,只要更改变量counter的值,就可以改变输出频率。
适当调节counter1的值,使得数码管动态显示在一个最佳的显示状态。
变量counter的计算方法是:
已知所需要的频率,根据公式(counter值=系统基准频率/所需频率)即可求得变量值。
二、计时模块实现方案
计时模块是对1s的信号源进行秒计时,计时满后向上进位的设计思想
计时采用十进制数计时,然后分别对时、分、秒三个数进行取余数、取除数,分别得到三个数的高位和低位
always(posedgeclkdivornegedgereset)
begin
if(!
reset)//判断是否为复位信号
begin
th=8'
d0;
//将小时信号清零
hH=cnth/10;
//取除操作求得小时信号的高位
hL=cnth%10;
//取余操作求得小时信号的低位
tm=8'
mH=cntm/10;
mL=cntm%10;
ts=8'
sH=cnts/10;
sL=cnts%10;
end
else
if(cnts==59)//判断秒钟信号是否计满
ts<
=8'
//秒信号清零
if(cntm==59)//判断分信号是否计满
tm<
//分信号清零
if(cnth==23)//判断小时信号是否计满
th<
//小时信号清零
=cnth+8'
d1;
tm=cntm+8'
begin
ts=cnts+1'
end
计时分每个信号的高低位进行判断及计时
if(sL==9)
sL<
=0;
if(sH==5)
sH<
if(mL==9)
mL<
if(mH==5)
mH<
if(hL==9)
hL<
hH<
=hH+1;
elseif(hL==3&
&
hH==2)
elsehL<
=hL+1;
elsemH<
=mH+1;
elsemL<
=mL+1;
elsesH<
=sH+1;
elsesL<
=sL+1;
方案一在思路方面较为通俗易懂,且判断过程简短明了,但在程序中使用的进制数较多,进制转换时容易混乱,在最终的显示时出现毛刺干扰现象,且该方案中不便于增加小时和分钟的调节信号,方案最终失败。
方案二虽然判断复杂,但没有进制混杂引起的毛刺现象,在最终的数码管显示时较为稳定。
综合考虑,使用方案二。
时钟调节模块的实现:
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;
//十进制的小时信号
0]tm;
//十进制的分钟信号
0]ts;
//十进制的秒信号
always(posedgeclkdivornegedgerst)
/******判断是否为复位信号********/
rst)
/******判断是否为小时调节信号********/
S1)
/******判断是否为分钟调节信号********/
elseif(!
S2)
elseif(sL==9)
三、译码显示模块的实现
译码显示模块采用的是数码管的动态扫描方式,定义变量COM来控制数码管显示的位选信号(通过变量Uweixuan来给数码管的各个位选位送出低电平信号)。
由于试验箱上的八个数码管是每四个的位选端连接在一起,分为两组数码管,所以定义两个变量show_temp_H和show_temp_L来分别控制两组数码管,该变量决定了哪个数码管显示哪个信号,再根据这两个变量判断显示的是哪一组数码管,确定之后通过送入的数据利用变量HIGH和LOW控制数码管的段选信号完成译码显示工作。
moduledecode(clk500,reset,hH,hL,mH,mL,sH,sL,HIGH,LOW,COM);
inputclk500;
inputhH,hL;
//小时的高、低位信号
inputmH,mL;
//分钟的高、低位信号
inputsH,sL;
//秒的高、低位信号
output[6:
0]HIGH,LOW;
//分别控制两组数码管的段选信号
output[7:
0]COM;
//控制数码管的位选信号
0]show_temp_H,show_temp_L;
//定义的部变量,决定数码管上显示的信号
0]Uweixuan;
//通过控制COM变量给数码管的位选位送出高低电平
reg[2:
0]sm;
//扫描变量
reg[6:
0]HIGH;
//控制高四位数码管的段选信号
0]LOW;
//控制低四位数码管的段选信号
always(posedgeclk200)
if(sm==3'
b111)
sm<
=3'
b000;
=sm+3'
b001;
Uweixuan<
=Uweixuan<
<
1;
//通过对变量的左移操作依次给数码管的位选位送高电平
if(Uweixuan==8'
b0000_0000)
b0000_0001;
//给Uweixuan变量设定的初值
COM=~Uweixuan;
//共阴极数码管显示的位选信号应为低电平,故对Uweixuan变量进行取反操作
always(sm)
case(COM)
8'
b1111_1110:
show_temp_H=sL;
//最低位的数码管用于显示秒信号的低位
b1111_1101:
show_temp_H=sH;
b1111_1011:
show_temp_H=4'
b1010;
b1111_0111:
show_temp_H=mL;
b1110_1111:
show_temp_L=mH;
b1101_1111:
show_temp_L=4'
b1011_1111:
show_temp_L=hL;
b0111_1111:
show_temp_L=hH;
//最高位的数码管用于显示小时信号的高位
endcase
always(show_temp_H)//高四位的数码管显示
case(show_temp_H)
4'
b0000:
HIGH=~7'
b011_1111;
b0001:
HIGH=~7'
b000_0110;
b0010:
b101_1011;
b0011:
b100_1111;
b0100:
b110_0110;
b0101:
b110_1101;
b0110:
b111_1101;
b0111:
b000_0111;
b1000:
b111_1111;
b1001:
b110_1111;
b1010:
b100_0000;
defaultHIGH=~7'
b000_0000;
endcase
always(show_temp_L)//低四位的数码管显示
case(show_temp_L)
LOW=~7'
LOW=~7'
defaultLOW=~7'
第三节系统及各模块方框图说明
分频模块:
输入信号为系统基准时钟50MHZ
输出为1HZ频率和200HZ-500HZ频率两路信号
计时模块:
输入信号1s时钟信号clkdiv,复位信号reset,小时调节信号S1,分钟调节信号S2
输出信号为小时信号的高、低位hH、hL,分钟信号的高、低位mH、mL,秒信号的高、低位sH、sL
译码显示模块:
输入信号该模块工作频率500HZ,复位信号reset,小时信号的高、低位hH、hL,分钟信号的高、低位mH、mL,秒信号的高、低位sH、sL
输出信号为八个数码管的位选控制信号COM,高四位数码管显示的段选信号HIGH,低四位数码管显示的段选信号LOW
系统功能实现:
主函数的输入信号为系统基准时钟信号、复位信号、小时调节信号、分钟调节信号。
输出信号为数码管的位选控制信号COM、高四位数码管的段选控制信号HIGH、低四位数码管的段选控制信号LOW。
第二章结果与讨论
第一节调试现象及解决分析
系统方案确定,程序编写完成后进入调试阶段,调试分模块进行。
首先是分频模块,在程序编写且编译通过后,加观察窗口观察所得波形,可以判定是否得到所需频率的信号。
在调试过程中出现的问题:
一、编写程序过程中出现的语法问题
(1)要注意编写程序的过程中begin和end配对问题,类似于C语言中的括号匹配问题,在编写计数模块时编译不通过,最后检查出是缺少一个end结束符号,经修改后编译通过。
(2)VerilogHDL语言编写时的语法问题。
在最初的计时模块的程序设计中,将小时、分钟的调节信号放在了另外的一个always语句块中,编译无法通过,经查阅资料,在VerilogHDL语言的编写中应该注意不同的always语句块不可以对同一个变量进行操作,即一个变量不可以经过两个always语句块操作。
将对小时和分钟调节信号的操作与计时放在同一个语句块中,编译通过。
二、方案实现过程中出现的问题
(1)数码管显示高四位、低四位保持一致。
在数码管显示时没有达到预计的目标,没有实现动态显示,而是高四位同时显示一个数字,低四位同时显示一个数字,经过对程序的检查调试,是因为对数码管位选端口的控制不正确,初始程序用是通过变量Uweixuan给数码管位选端依次送入高电平:
Uweixuan<
COM=~Uweixuan;
分析得知是COM信号没有正确的送给数码管显示,经修改对后成功显示。
修改的程序增加了一个扫描信号:
always(posedgeclk200)
if(sm==3'
sm<
b000