资源描述
课程设计(报告)任务书
(理 工 科 类)
Ⅰ、课程设计(报告)题目:
实时时钟电路的设计
Ⅱ、课程设计(论文)工作内容
一、课程设计目标
《硬件描述语言》是一门技术性、应用性很强的学科,实验课教学是它的一个极为重要的环节。不论理论学习还是实际应用,都离不开实验课教学。如果不在切实认真地抓好学生的实践技能的锻炼上下功夫,单凭课堂理论课学习,势必出现理论与实践脱节、学习与应用脱节的局面。《HDL项目设计》的目的就是让同学们在理论学习的基础上,通过完成一个涉及时序逻辑、组合逻辑、声光输出的,具有实用性、趣味性的小系统设计,使学生不但能够将课堂上学到的理论知识与实际应用结合起来,而且能够对分析、解决实际的数字电路问题进一步加深认识,为今后能够独立进行某些数字应用系统的开发设计工作打下一定的基础。
二、课程设计任务与要求
(1)设计一个数码管实时显示时、分、秒的数字时钟(24小时显示模式);
(2)为了演示方便,应具有分钟、小时快进功能;
(3)时、分、秒设置功能(选作)。
三、课程设计考核
平时20%;验收40%;报告40%
摘 要
数字钟是人们日常生活中经常使用的计时工具,本次的课程设计是基于Verilog HDL的多功能数字钟,完成时、分、秒的显示功能。设计利用Verilog HDL语言自顶向下的设计理念,突出其作为硬件描述语言的良好的可读性、可移植性以及易于理解等优点。通过Quartus II 5.0和ModelSim SE 6.1f软件完成仿真、综合。程序下载到FPGA芯片后,可用于实际的数字钟显示中。
此次设计的逻辑结构主要由分频器、计数器和译码显示器三个模块构成。分频模块将50Mhz系统基准时钟分频产生两路时钟信号,一路是1HZ的数字钟计时工作频率,一路是数码管动态显示的扫描频率;计时模块对1HZ的时钟信号进行计时,分为时、分、秒三个部分;译码显示模块采用动态扫描的方式完成数码管的显示。最后通过主模块调用三个子模块函数完成整个设计。
【关键词】硬件描述语言 FPGA 数字钟 动态显示
ABSTRACT
The digital clock is often used in People's Daily life of the course, the timing tool design is based on the multi-function digital clock Verilog HDL, complete, minutes and seconds display function. Design Verilog HDL language using the top-down design concept, the hardware description language as the good readability and portability and easy to understand, etc. Through the Quartus II 5.0 and ModelSim SE 6.1 f software simulation, and comprehensive. Download to FPGA chips can be used after the actual, digital clock shows.
The design of the logic structure consists mainly of prescaler, counter and decoding display three modules. 50Mhz system frequency module will produce benchmark clock clock signal, two 1HZ way is the digital clock frequency, dynamic display of digital tube is scanning. Timer modules for 1HZ clock signal timing, when into three parts, minutes and seconds, Decode display module USES dynamic scanning of the digital display. Through the main module calling three modules function complete the whole design.
【Key words】Hardware description language FPGA A digital clock Dynamic display
目录
第一章 系统设计 6
第一节 课题目标及总体方案 6
第二节 系统模块实现方案对比及实现 7
一、分频模块实现方案 7
二、计时模块实现方案 9
三、译码显示模块的实现 16
第三节 系统及各模块方框图说明 19
第二章 结果与讨论 22
第一节 调试现象及解决分析 22
一、编写程序过程中出现的语法问题 22
二、方案实现过程中出现的问题 22
第二节 相关数据分析 24
第三节 系统整体实现 24
心得体会 25
参考文献 26
附 录 27
第一章 系统设计
第一节 课题目标及总体方案
目前,电子系统向集成化、大规模和高速度等方向发展,以硬件描述语言和逻辑综合为基础的自顶向下的电路设计方法得到迅猛发展。本次设计课题目标完成是基于Verilog HDL语言的多功能数字钟的设计,通过数码管实时显示时、分、秒,具有小时和分钟快进功能。设计遵循Verilog HDL语言的设计理念,代码具有良好的可读性和易理解性。
系统主要分三个模块实现,分别是分频模块、计数模块、译码显示模块。分频模块用来提供计时电路工作时钟(1HZ)和数码管动态显示的扫描频率(200HZ—500HZ),计数模块是对1s信号源进行秒、分、时的计时,译码显示模块是通过控制信号控制八个数码管的位选、段选来实现对译码后的计时信号进行动态显示。主函数通过调用三个子模块来实现整体的系统功能。
第二节 系统模块实现方案对比及实现
一、分频模块实现方案
分频模块用于为系统的实现提供稳定的工作频率和计时信号源,要求产生两路不同频率的信号,分频为1HZ频率的信号作为计时模块的信号源,200HZ的信号用于数码管动态显示的扫描频率。
方案一:
定义变量并根据需要得到的分频信号设定计数值,对该变量进行加或减计数,每到达一次计数值点,将该变量清零或重置,并且对输出信号取一次反,即可以得到所需的分频信号。
parameter C_COUNT=25'd500_00_000;//定义变量C_COUNT并给该变量设定计数值点
always @ (posedge clock)
begin
if(counter==0)
begin
counter<=C_COUNT;//减计数到0后对该变量进行重置
clkdiv<=~clkdiv; //对输出信号取反一次
end
else
counter<=counter-1; //对变量减计数
end
方案二:
定义变量并且设定一个上限值,每次加计数到该上限值时,输出该计数值的最高位
parameter DIV_SIZE=25;
always@(posedge clock)
counter=counter+1;
assign clkdiv=counter[DIV_SIZE-1];
方案比较:
方案二能够产生准确的1HZ的频率且在程序实现上较为简单,但在产生数码管动态显示的扫描频率时可调度不如方案一,即在调节200HZ-500HZ范围内的频率时DIV_SIZE变量的值不便于计算;方案一实现分频信号的设计思路简单易懂,且变量值易于计算和调节。
故采用方案一。
分频模块的实现:
module clkgen (clock,clkdiv,clk500);
input clock;
output clkdiv;
output clk500;
reg [31:0] counter1;
reg clkdiv;
reg clk500;
reg [31:0] counter0;
parameter C_COUNT0=25'd500_00_000;//变量0用于产生1HZ的信号
parameter C_COUNT1=25'd100_000;//变量1用于产生500HZ的信号
/********产生1HZ频率的信号*********/
always @ (posedge clock)
begin
if(counter0==0)
begin
counter0<=C_COUNT0;
clkdiv<=~clkdiv;
end
else
counte0<=counter0-1;
end
/********产生500HZ频率的信号*********/
always @ (posedge clock)
begin
if(counter1==0)
begin
counter1<=C_COUNT1;
clk500<=~clk500;
end
else
counter1<=counter1-1;
end
endmodule
在该程序段中,只要更改变量counter的值,就可以改变输出频率。适当调节counter1的值,使得数码管动态显示在一个最佳的显示状态。变量counter的计算方法是:已知所需要的频率,根据公式(counter值=系统基准频率/所需频率)即可求得变量值。
二、计时模块实现方案
计时模块是对1s的信号源进行秒计时,计时满后向上进位的设计思想
方案一:
计时采用十进制数计时,然后分别对时、分、秒三个数进行取余数、取除数,分别得到三个数的高位和低位
always@(posedge clkdiv or negedge reset)
begin
if(!reset)//判断是否为复位信号
begin
cnth=8'd0; //将小时信号清零
hH=cnth/10; //取除操作求得小时信号的高位
hL=cnth%10; //取余操作求得小时信号的低位
cntm=8'd0;
mH=cntm/10;
mL=cntm%10;
cnts=8'd0;
sH=cnts/10;
sL=cnts%10;
end
else
begin
if(cnts==59) //判断秒钟信号是否计满
begin
begin
cnts<=8'd0; //秒信号清零
sH=cnts/10;
sL=cnts%10;
end
begin
if(cntm==59) //判断分信号是否计满
begin
begin
cntm<=8'd0; //分信号清零
mH=cntm/10;
mL=cntm%10;
end
begin
if(cnth==23) //判断小时信号是否计满
begin
cnth<=8'd0; //小时信号清零
hH=cnth/10;
hL=cnth%10;
end
else
begin
cnth<=cnth+8'd1;
hH=cnth/10;
hL=cnth%10;
end
end
end
else
begin
cntm=cntm+8'd1;
mH=cntm/10;
mL=cntm%10;
end
end
end
else
begin
cnts=cnts+1'd1;
sH=cnts/10;
sL=cnts%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
else if(hL==3&&hH==2)
begin
hL<=0;
hH<=0;
end
else hL<=hL+1;
end
else mH<=mH+1;
end
else mL<=mL+1;
end
else sH<=sH+1;
end
else sL<=sL+1; end
方案比较:
方案一在思路方面较为通俗易懂,且判断过程简短明了,但在程序中使用的进制数较多,进制转换时容易混乱,在最终的显示时出现毛刺干扰现象,且该方案中不便于增加小时和分钟的调节信号,方案最终失败。方案二虽然判断复杂,但没有进制混杂引起的毛刺现象,在最终的数码管显示时较为稳定。综合考虑,使用方案二。
时钟调节模块的实现:
module counter(clkdiv,reset,S1,S2,hH,hL,mH,mL,sH,sL);
input clkdiv;
input reset;
input S1;
input S2;
output hH;
output hL;
output mH;
output mL;
output sH;
output sL;
reg hH;
reg hL;
reg mH;
reg mL;
reg sH;
reg sL;
reg [7:0] cnth;//十进制的小时信号
reg [7:0] cntm;//十进制的分钟信号
reg [7:0] cnts;//十进制的秒信号
always@(posedge clkdiv or negedge rst)
/******判断是否为复位信号********/
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
else if(hL==3&&hH==2)
begin
hL<=0;
hH<=0;
end
else
hL<=hL+1;
end
/******判断是否为分钟调节信号********/
else if(!S2)
begin
if(mL==9)
begin
mL<=0;
if(mH==5)
mH<=0;
else
mH<=mH+1;
end
else
mL<=mL+1;
end
else 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
else if(hL==3&&hH==2)
begin
hL<=0;
hH<=0;
end
else hL<=hL+1;
end
else mH<=mH+1;
end
else mL<=mL+1;
end
else sH<=sH+1;
end
else sL<=sL+1;
end
endmodule
三、译码显示模块的实现
译码显示模块采用的是数码管的动态扫描方式,定义变量COM来控制数码管显示的位选信号(通过变量Uweixuan来给数码管的各个位选位送出低电平信号)。由于试验箱上的八个数码管是每四个的位选端连接在一起,分为两组数码管,所以定义两个变量show_temp_H和show_temp_L来分别控制两组数码管,该变量决定了哪个数码管显示哪个信号,再根据这两个变量判断显示的是哪一组数码管,确定之后通过送入的数据利用变量HIGH和LOW控制数码管的 段选信号完成译码显示工作。
module decode(clk500,reset,hH,hL,mH,mL,sH,sL,HIGH,LOW,COM);
input clk500;
input reset;
input hH,hL;//小时的高、低位信号
input mH,mL;//分钟的高、低位信号
input sH,sL;//秒的高、低位信号
output [6:0] HIGH,LOW;//分别控制两组数码管的段选信号
output [7:0] COM;//控制数码管的位选信号
reg [7:0] show_temp_H,show_temp_L;//定义的内部变量,决定数码管上显示的信号
reg [7:0] COM;
reg [7:0] Uweixuan;//通过控制COM变量给数码管的位选位送出高低电平
reg [2:0] sm;//扫描变量
reg [6:0] HIGH;//控制高四位数码管的段选信号
reg [6:0] LOW;//控制低四位数码管的段选信号
always@(posedge clk200)
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变量设定的初值
COM=~Uweixuan;
//共阴极数码管显示的位选信号应为低电平,故对Uweixuan变量进行取反操作
end
always@(sm)
begin
case(COM)
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;
default HIGH =~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;
default LOW =~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
输出信号为八个数码管的位选控制信号COM,高四位数码管显示的段选信号HIGH,低四位数码管显示的段选信号LOW
系统功能实现:主函数的输入信号为系统基准时钟信号、复位信号、小时调节信号、分钟调节信号。
输出信号为数码管的位选控制信号COM、高四位数码管的段选控制信号HIGH、低四位数码管的段选控制信号LOW。
第二章 结果与讨论
第一节 调试现象及解决分析
系统方案确定,程序编写完成后进入调试阶段,调试分模块进行。首先是分频模块,在程序编写且编译通过后,加观察窗口观察所得波形,可以判定是否得到所需频率的信号。在调试过程中出现的问题:
一、编写程序过程中出现的语法问题
(1)要注意编写程序的过程中begin和end配对问题,类似于C语言中的括号匹配问题,在编写计数模块时编译不通过,最后检查出是缺少一个end结束符号,经修改后编译通过。
(2)Verilog HDL语言编写时的语法问题。在最初的计时模块的程序设计中,将小时、分钟的调节信号放在了另外的一个always语句块中,编译无法通过,经查阅资料,在Verilog HDL语言的编写中应该注意不同的always语句块不可以对同一个变量进行操作,即一个变量不可以经过两个always语句块操作。将对小时和分钟调节信号的操作与计时放在同一个语句块中,编译通过。
二、方案实现过程中出现的问题
(1)数码管显示高四位、低四位保持一致。在数码管显示时没有达到预计的目标,没有实现动态显示,而是高四位同时显示一个数字,低四位同时显示一个数字,经过对程序的检查调试,是因为对数码管位选端口的控制不正确,初始程序用是通过变量Uweixuan 给数码管位选端依次送入高电平:
Uweixuan<=Uweixuan<<1;
if(Uweixuan==8'b0000_0000)
Uweixuan<=8'b0000_0001;
COM=~Uweixuan;
分析得知是COM信号没有正确的送给数码管显示,经修改对后成功显示。修改的程序增加了一个扫描信号:
always@(posedge clk200)
begin
if(sm==3'b111)
sm<=3'b000;
else
sm<=sm+3'b001;
在扫描信号到来时判断COM信号并给数码管送出位选端控制信号。
(2)数码管计时只显示二进制数。初始程序使用的是十进制数计时,对十进制数进行取除、取余操作,再译码,程序中进制数使用混乱,出现毛刺现象。将计时模块的程序重新修改后实现了计时的译码显示功能。
(3)数码管显示不佳。问题出在对数码管动态显示的扫描频率设置不适当,频率太低时无法八个数码管一起显示,频率太高时数码管显示的亮度降低,需要在200HZ-500HZ范围内调出一个适当的频率。
(4)数码管的显示需要一直按着“复位键”进行。系统的复位信号为低电平有效,所以在编写程序时注意是复位信号的下降沿有效,应该为:
always@(posedge clkdiv or negedge rst)
if(!rst)
begin
sL<=0;
sH<=0;
mL<=0;
mH<=0;
hL<=0;
hH<=0;
end
第二节 相关数据分析
分频模块的counter变量值计算:系统基准时钟为50MHZ,counter值操作一次所需时间为1/50M,操作到计数值点所需时间则为(1/50M)*counter,其倒数即为所得到的时钟频率,根据公式求出counter变量值,分别得到计时模块和译码显示模块所需要的时钟频率。
第三节 系统整体实现
系统使用一个主函数调用各个子模块实现系统功能,通过系统方框图编写主函数:
module main(clock,reset,HIGH,LOW,COM);
//parameter DIV_SIZE=25;
input clock;
input reset;
output [6:0] HIGH,LOW;
output [7:0] COM;
wire clkdiv;
wire clk500;
clkgen uut1(clock,clkdiv,clk500);
counter uut2(clkdiv,reset,S1,S2,hH,hL,mH,mL,sH,sL);
decode uut3(clk500,reset,hH,hL,mH,mL,sH,sL,HIGH,LOW,COM);
endmodule
心得体会
这次的课程设计结束了,在这次的设计中我学会了很多东西。首先是对Verilog HDL语言的设计思想有了深入理解,将这种自顶向下的设计理念运用于实践中,设计多功能数字钟,突出了Verilog HDL作为硬件描述语言的良好可读性和可移植性,对上学期所学的而理论知识有了深刻的理解。
其次是对Verilog HDL语言的语法熟悉,在这次的课程设计中,我学习到很多Verilog HDL语言的语法知识,比如在两个不同的语句块中不能对同一个变量进行操作,比如在用Verilog HDL语言中编写程序时要注意begin和end语句的匹配问题,在使用Verilog HDL语言时不可以使用中文注释等等。对于这种语言的学习也有了很大的帮助。
最后是设计作品时的设计逻辑和设计思想,在选择不同的系统方案时要综合考虑,选择最优方案。各个模块的实现也要考虑综合情况而制定出最符合实际情况的实现方案,方案间要进行对比、实践,最终确定。
在这次的课程设计中我不仅学习到有关程序编写以及设计方面的逻辑思维,对系统功能的实现也有了较为深入的了解,对各模块的调试等也学习到不少东西,总之,从这次设计中学到很多东西,也巩固了我的理论学习。
展开阅读全文