VHDL课程设计数字秒表.docx
《VHDL课程设计数字秒表.docx》由会员分享,可在线阅读,更多相关《VHDL课程设计数字秒表.docx(16页珍藏版)》请在冰点文库上搜索。
VHDL课程设计数字秒表
基于VHDL语言的数字秒表实现
2013-5-1
基于VHDL语言的数字秒表实现
1设计方案
1.1系统功能要求
设计一块数字秒表,能够精确反映计时时间,并完成复位、计时功能。
秒表计时的最大范围为1小时,精度为0.01秒,并可显示计时时间的分、秒、0.1秒等度量。
(1)具有秒表系统功能要求显示功能,用6个数码管分别显示分、秒、0.01秒;计时范围为00:
00:
00~59:
59:
99。
(2)计时精度是0.01s;
(3)具有启/停开关,复位开关。
1.2总体框图
根据系统设计要求,系统的底层设计主要由六十进制计数器模块、二十四进制计数器模块、分频模块、LED显示模块组成。
系统顶层设计图如图所示:
图中左边为三个输入信号en,clk,reset;分为启/停开关,时钟信号和复位开关。
主要模块有:
模60计数器(count60),模100计数器(count100),分频器(clk_div),复位控制(control),译码器(yima),防抖模块(fdou),状态变换模块(change)。
右边是六个LED显示输出信号。
2模块功能设计
由模60计数器模块与模100计数器模块进行计数;实验室仪器可产生标准的1kHz的时钟信号,通过分频器模块产生所需的100Hz的时钟信号;复位模块可进行计数器复位操作;译码器是为了将四位二进制信号转换为LED所需的七位二进制编码;防抖模块用于消除用户按键时的抖动消除,为方便仿真,此处原始时钟信号3周期以上可产生信号;状态变换模块是为了用户按键后信号的变换及保持。
2.1模60计数器
该模块部分VHDL源程序如下:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYcount60IS
PORT(en,Reset,clk:
inSTD_LOGIC;
qa:
outSTD_LOGIC_VECTOR(3DOWNTO0);
qb:
outSTD_LOGIC_VECTOR(3DOWNTO0);
rco:
OUTSTD_LOGIC);
ENDcount60;
ARCHITECTUREaOFcount60IS
BEGIN
process(clk)
variabletma:
STD_LOGIC_VECTOR(3DOWNTO0);
variabletmb:
STD_LOGIC_VECTOR(3DOWNTO0);
begin
IfReset='0'thentma:
="0000";tmb:
="0000";
elsifclk'eventandclk='1'then
ifen='1'then
rco<=tmb
(2)andtmb(0)andtma(3)andtma(0);
iftma="1001"thentma:
="0000";
iftmb="0101"thentmb:
="0000";
elsetmb:
=tmb+1;
endif;
elsetma:
=tma+1;
endif;
endif;
endif;
qa<=tma;qb<=tmb;
endprocess;
ENDa;
2.2模100计数器
该模块部分VHDL源程序如下:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYcount100IS
PORT(en,Reset,clk:
inSTD_LOGIC;
qa:
outSTD_LOGIC_VECTOR(3DOWNTO0);
qb:
outSTD_LOGIC_VECTOR(3DOWNTO0);
rco:
OUTSTD_LOGIC);
ENDcount100;
ARCHITECTUREaOFcount100IS
BEGIN
process(clk)
variabletma:
STD_LOGIC_VECTOR(3DOWNTO0);
variabletmb:
STD_LOGIC_VECTOR(3DOWNTO0);
begin
IfReset='0'thentma:
="0000";tmb:
="0000";
elsifclk'eventandclk='1'then
ifen='1'then
rco<=tmb(3)andtmb(0)andtma(3)andtma(0);
iftma="1001"thentma:
="0000";
iftmb="1001"thentmb:
="0000";
elsetmb:
=tmb+1;
endif;
elsetma:
=tma+1;
endif;
endif;
endif;
qa<=tma;qb<=tmb;
endprocess;
ENDa;
2.3分频器模块
该模块部分VHDL源程序如下:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_ARITH.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYclk_divIS
PORT(clk:
INSTD_LOGIC;
clk_out:
OUTSTD_LOGIC);
ENDclk_div;
ARCHITECTURErtlOFclk_divIS
SIGNALclk_temp:
STD_LOGIC;
BEGIN
PROCESS(clk)
VARIABLEcounter:
INTEGERRANGE0TO15;
BEGIN
IF(clk'EVENTANDclk='1')THEN
IF(counter=9)THEN
Counter:
=0;
Clk_out<='1';
ELSE
Counter:
=counter+1;
Clk_out<='0';
ENDIF;
ENDIF;
ENDPROCESS;
ENDrtl;
2.4复位控制
该模块部分VHDL源程序如下:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYcontrolIS
PORT(CLK,RST:
instd_logic;
CLK_OUT:
outstd_logic);
ENDcontrol;
ARCHITECTUREbehavOFcontrolIS
signalclk_data:
std_logic;
SIGNALCNT:
INTEGER:
=0;
BEGIN
PROCESS(CLK)
BEGIN
IFRST='0'THENCNT<=0;
ELSIFCLK'EVENTANDCLK='1'THEN
IFCNT=2THENclk_data<=NOTclk_data;CNT<=0;
ELSECNT<=CNT+1;
ENDIF;
ENDIF;
CLK_OUT<=clk_data;
ENDPROCESS;
ENDbehav;
2.5译码器
该模块部分VHDL源程序如下:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYyimaIS
PORT(num:
inSTD_LOGIC_VECTOR(3downto0);
led:
outSTD_LOGIC_VECTOR(6downto0));
ENDyima;
ARCHITECTUREaOFyimaIS
BEGIN
process(num)
begin
casenumis
when"0000"=>led<="0111111";
when"0001"=>led<="0000110";
when"0010"=>led<="1011011";
when"0011"=>led<="1001111";
when"0100"=>led<="1100110";
when"0101"=>led<="1101101";
when"0110"=>led<="1111101";
when"0111"=>led<="0100111";
when"1000"=>led<="1111111";
when"1001"=>led<="1101111";
whenothers=>led<="0000000";
endcase;
endprocess;
ENDa;
2.6防抖模块
该模块部分VHDL源程序如下:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_ARITH.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYfdouIS
PORT(CLK,DIN:
INSTD_LOGIC;
DOUT:
OUTSTD_LOGIC);
ENDENTITYfdou;
ARCHITECTUREARCOFfdouIS
SIGNALCP:
STD_LOGIC;
SIGNALJSQ:
INTEGERRANGE0TO3;
BEGIN
PROCESS(CLK)
BEGIN
IF(CLK'EVENTANDCLK='1')THEN
IFDIN='1'THEN
IFJSQ=3THEN
JSQ<=JSQ;
ELSE
JSQ<=JSQ+1;
ENDIF;
IFJSQ=1THEN
CP<='1';
ELSE
CP<='0';
ENDIF;
ELSE
JSQ<=0;
ENDIF;
ENDIF;
DOUT<=CP;
ENDPROCESS;
ENDARC;
2.7状态变换模块
该模块部分VHDL源程序如下:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_ARITH.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYchangeIS
PORT(clk_in,clk:
INSTD_LOGIC;
clk_out:
OUTSTD_LOGIC);
ENDENTITYchange;
ARCHITECTUREaOFchangeIS
SIGNALcp:
STD_LOGIC;
BEGIN
PROCESS(CLK)
BEGIN
IF(CLK'EVENTANDCLK='1')THEN
IF(clk_in='1')THEN
cp<='0';
ELSE
cp<='1';
ENDIF;
ENDIF;
clk_out<=CP;
ENDPROCESS;
ENDa;
3仿真波形及分析
各部分模块完成后,用Quartus对程序编译、仿真、得到的仿真波形,各模块仿真波形及顶层仿真波形如下:
3.1模60计数器模块仿真
clk:
时钟信号
rst:
复位信号低电平清零
en:
置数端低电平不让它继续计数
qb、qa:
分别为输出数的十位个位,qb取值范围为0-5,qa取值范围为0-9
rco:
进位信号,当qb=5,qa=9,rco=0时,clk上升沿来到后,qb=0,qa=0,rco=1;
当qb=0,qa=0,rco=1时,clk上升沿来到后,qb=0,qa=1,rco=0
3.2模100计数器模块仿真
clk:
时钟信号
cst:
复位信号低电平清零
en:
置数端低电平不让它继续计数
qb、qa:
分别为输出数的十位个位,qb取值范围为0-9,qa取值范围为0-9
rco:
进位信号,当qb=9,qa=9,rco=0时,clk上升沿来到后,qb=0,qa=0,rco=1;
当qb=0,qa=0,rco=1时,clk上升沿来到后,qb=0,qa=1,rco=0
3.3分频器模块仿真
因时钟脉冲(为1khz)通过分频器分频后频率(为100hz)。
cLK:
输入分频前的时钟信号
clk_out:
输出分频后的时钟信号
3.4复位模块仿真
clk:
时钟信号
clk_out:
输出信号
rst:
复位信号
3.5译码器模块仿真
num[3..0]:
输入标准四位二进制码
led[6..0]:
输出七位二进制码,控制led管脚电压。
3.6防抖模块仿真
CLK:
对比时钟信号(这里采用的正是原始信号,只用预仿真,实际情况需要改善信号或者增大防抖的信号周期)
DIN:
用户按键输入信号
DOUT:
输出信号。
3.7状态变换模块仿真
clk:
对比时钟信号
clk_in:
原状态
clk_out:
次状态。
3.8顶层模块仿真
clk:
原始时钟信号
reset:
复位信号
en:
启动/暂停信号
led1-led7:
输出控制LED灯管脚的信号。
4心得体会
VHDL硬件描述语言是我学过的较为复杂的一门语言,之前一直学习的是高级编程语言,如c++、c语言、VB、pascal、c#等,这些语言都不愧于它们的高级一词,因为语言包装得很好,用起来确实简单易上手,而且里面的各种语法可以让我们轻松的解决各种难题(其中,最让我惊叹的便是递归语句的应用)。
然而,上述的高级语言都只是在第二系统中起到作用,并不能直接对硬件进行操作,VHDL却是一种针对硬件的描述语言。
VHDL作为一种标准硬件描述语言,它除了含有许多具有硬件特征的语句外,其语言形式和描述风格与句法是十分类似于一般的计算机高级语言。
但是由于其是针对硬件的描述语言,孤儿许多高级语法都不能使用,所以在学习的初始阶段,并不适应这种简朴而又复杂的语言,觉得它乱七八糟,看着语句毫无头绪。
然而,VHDL课有着与其他科目截然不同的地方,那就是它的互动性很强。
因为语言的复杂,老师想要教会我们去用这门语言,光是看书或者PPT是不够的,那样在脑海中的印象并不深刻,所以老师让我们尽量带自己的电脑去上课,在课堂上可以跟着老师的步骤一起做。
不仅如此,我们还进行分组去完成项目,依然清晰记得那时候毫无头绪的痛苦,坚持不懈的劳累,以及最后收获成功时的喜悦。
这些项目,不仅加深了我们对VHDL的理解和应用,同样的,我们的动手能力等社会技能也得到了锻炼。
因为这些互动,我也渐渐喜欢上了VHDL语言的编程开发。
VHDL语言有着很广泛的影响,世界上有很多企业都以VHDL语言为基础开发他们的开发软件和硬件。
就比如我们这学期上的另一门选修课PLD,它里面应用的也是VHDL语言,但是学习的软件是altera公司的quartus软件,VHDL课上用的是xilinx和modelsim,这种种联系也使得我对VHDL的兴趣倍增。
这次课程设计本来应该用xilinx中的ise进行操作的,但是因为刚刚换了系统,再次装xilinx时却装不上,所以只好采用quartus进行仿真实验了,不过感觉起来好像quartus用起来更加简单。
通过这次课程设计,我了解了好多自身的不足:
对于模块功能想象力不足,模块设计也总是错误百出,粗心大意是永远会出现的陋习。
一开始,感觉数字秒表的功能模块应该很清晰,模块之间的联系很密切,同时,觉得自己对于这种简易电子设备的内部结构应该很熟悉。
可是,到了真正操作的时候才发现自己想得太简单了。
虽然数字秒表就是些简单的计数器的综合,但是每个计数器的设计也是需要懂很多知识的。
而且秒表有复位功能,要考虑到复位时同步清零,清零后还要保持在零的状态,清零是用户进行的操纵,需要有外部输入,而外部输入就需要考虑到抖动的问题,抖动的问题解决了,又要想暂停、启动的控制,这样就需要类似状态机的模块进行使能端、清零端的状态转换。
这些虽然只是细枝末节,但是真正的编程的成功因素很大一部分都是取决于这些细节。
总的来说,VHDL这门课让我学到了只是,锻炼了技能,增强了信心,也充实了我的大学生活,谢谢VHDL带给我的这些,也谢谢老师的对我们谆谆教诲,您辛苦了。