多功能秒表计数器.docx
《多功能秒表计数器.docx》由会员分享,可在线阅读,更多相关《多功能秒表计数器.docx(13页珍藏版)》请在冰豆网上搜索。
![多功能秒表计数器.docx](https://file1.bdocx.com/fileroot1/2023-1/31/14e9f738-ca5f-4316-a017-4d61700ebc44/14e9f738-ca5f-4316-a017-4d61700ebc441.gif)
多功能秒表计数器
深圳大学实验报告
课程名称:
基于VHDL编程的FPGA设计
实验名称:
多功能秒表计数器
学院:
信息工程学院
专业:
电子信息工程班级:
2010级电子2班
组号:
指导教师:
报告人:
学号:
实验时间:
2012年11月16日星期三
实验地点南区N411
实验报告提交时间:
2012.11.28
实验要求:
题目、多功能秒表计数器
基本要求(必选):
设计一个秒表,它具有计时功能。
此秒表有两个按键(reset,start)按下reset键后,秒表清零,按下start键后,开始计时,再次按下start键后,停止计时,用FPGA开发板上的两个七段数码管显示时间(以秒为单位),计时由0到99循环。
高级要求(可选):
实现基本要求的前提下,增加一个按键(select),用于轮流切换两个七段数码管分别显示百分之一秒,秒,或对于Nexys2和Nexy3开发板,按下select键之后,四个七段数码管同时显示秒和百分之一秒。
规格说明:
1.通过按下reset键,将秒表清零,准备计时,等检测到start键按下并松开后,开始计时。
如果再次检测到start键按下并松开后,停止计时。
通过不断检测start键,来确定秒表是否开始计时。
2.在秒表计时时,七段数码管能够循环的由00…99,00…99…。
3.开始默认两个七段数码管显示秒,在检测到select键按下并松开后,数码管切换到显示百分之一秒,当再次检测到select键按下并松开后,数码管切换到重新显示秒。
4.在秒表停止时,数码管依然能够正常切换显示秒,百分之一秒。
5.本实验使用FPGA开发板:
Nexys2或Nexys3或旧板(建project时,需要选择该芯片的型号)。
实验内容:
A.VHDL程序代码
libraryIEEE;
useIEEE.STD_LOGIC_1164.ALL;
entityCounteris
Generic(N:
integer:
=250000);
Port(clk,reset,start,sel:
instd_logic;
ANO:
outstd_logic_vector(3downto0);
digit:
outstd_logic_vector(7downto0));
endCounter;
architectureBehavioralofCounteris
signalClk_1hz:
std_logic:
='0';
signalClk_1Hhz:
std_logic:
='0';
signalClk_1Khz:
std_logic:
='0';
signaldigit3:
integerrange0to10:
=0;
signaldigit2:
integerrange0to10:
=0;
signaldigit1:
integerrange0to10:
=0;
signaldigit0:
integerrange0to10:
=0;
signalR_flag:
integerrange0to10:
=0;
signalS_flag:
integerrange0to10:
=0;
signalX_flag:
integerrange0to10:
=0;
begin
-------------------分频器-------------------process(clk)
variablecount0:
integerrange0to25000000:
=0;
variablecount1:
integerrange0to25000000:
=0;
variablecount2:
integerrange0to25000000:
=0;
begin
if(clk'eventandclk='1')then
count0:
=count0+1;
count1:
=count1+1;
count2:
=count2+1;
----------------频率_秒----------------
if(count0=24999999)then
Clk_1hz<=notClk_1hz;
count0:
=0;
endif;
----------------频率_秒----------------
--------------频率_白分秒---------------
if(count1=249999)then
Clk_1Hhz<=notClk_1Hhz;
count1:
=0;
endif;
--------------频率_白分秒---------------
--------------频率_数码管---------------
if(count2=24999)then
Clk_1Khz<=notClk_1Khz;
count2:
=0;
endif;
--------------频率_数码管---------------
endif;
endprocess;
-------------------分频器-------------------
----------------reset按键-------------------
process(clk,reset)
variablecount:
integerrange0to25000000:
=0;
begin
if(clk'eventandclk='1')then
if(reset='1')then--消抖处理
if(count=N)thencount:
=0;
elsecount:
=count+1;
endif;
if(count=N-1)then--消抖处理
if(reset='1')thenR_flag<=1;endif;
endif;
elseR_flag<=0;
endif;
endif;
endprocess;
----------------reset按键-------------------
----------------start按键-------------------
process(clk,start)
begin
if(start'eventandstart='0')then
S_flag<=S_flag+1;
if(S_flag=2)thenS_flag<=0;endif;
endif;
endprocess;
----------------start按键-------------------
---------------select按键-------------------
process(clk,sel)
begin
if(sel'eventandsel='0')then
X_flag<=X_flag+1;
if(X_flag=1)thenX_flag<=0;endif;
endif;
endprocess;
---------------select按键-------------------
-----------------按键处理-------------------
process(clk,Clk_1Hhz)
variableModel:
integerrange0to10:
=1;
begin
if(R_flag=1)thenModel:
=1;
elsif(S_flag=0)thenModel:
=2;
elsif(S_flag=1)thenModel:
=3;
endif;
if(Clk_1Hhz'eventandClk_1Hhz='1')then
caseModelis
when1=>digit3<=0;digit2<=0;
digit1<=0;digit0<=0;
TANO:
="0111";Temp:
=digit3;
elsif(D_flag=2)then
D_flag:
=1;
TANO:
="1011";Temp:
=digit2;
elsif(D_flag=1)then
D_flag:
=0;
TANO:
="1101";Temp:
=digit1;
elsif(D_flag=0)then
D_flag:
=3;
TANO:
="1110";Temp:
=digit0;
endif;
elsif(X_flag=1)then
if(D_flag=3)then
D_flag:
=2;
TANO:
="0111";Temp:
=digit3;
elsif(D_flag=2)then
D_flag:
=1;
TANO:
="1011";Temp:
=digit2;
elsif(D_flag=1)then
D_flag:
=0;
TANO:
="1111";Temp:
=digit1;
elsif(D_flag=0)then
D_flag:
=3;
TANO:
="1111";Temp:
=digit0;
endif;
endif;
when2=>digit3<=digit3;
digit2<=digit2;
digit1<=digit1;
digit0<=digit0;
when3=>digit0<=digit0+1;
if(digit0=9)then
digit0<=0;
digit1<=digit1+1;
if(digit1=9)then
digit1<=0;
digit2<=digit2+1;
if(digit2=9)then
digit2<=0;
digit3<=digit3+1;
if(digit3=9)then
digit3<=0;
endif;
endif;
endif;
endif;
whenothers=>NULL;
endcase;
endif;
endprocess;
-----------------按键处理-------------------
--------------数码管显示处理----------------
process(Clk_1Khz)
variableTdigit:
std_logic_vector(7downto0):
="00000011";
variableD_flag:
integerrange0to3:
=0;
variableTANO:
std_logic_vector(3downto0):
="0011";
variableTemp:
integerrange0to10:
=0;
begin
if(Clk_1Khz'eventandClk_1Khz='1')then
if(X_flag=0)then
if(D_flag=3)then
D_flag:
=2;
caseTempis
when0=>Tdigit:
="00000011";
when1=>Tdigit:
="10011111";
when2=>Tdigit:
="00100101";
when3=>Tdigit:
="00001101";
when4=>Tdigit:
="10011001";
when5=>Tdigit:
="01001001";
when6=>Tdigit:
="01000001";
when7=>Tdigit:
="00011111";
when8=>Tdigit:
="00000001";
when9=>Tdigit:
="00001001";
whenothers=>NULL;
endcase;
endif;
ANO<=TANO;
digit<=Tdigit;
endprocess;
--------------数码管显示处理----------------
endBehavioral;
B.VHDL测试代码。
LIBRARYieee;
USEieee.std_logic_1164.ALL;
ENTITYTestIS
ENDTest;
ARCHITECTUREbehaviorOFTestIS
--ComponentDeclarationfortheUnitUnderTest(UUT)
COMPONENTCounter
PORT(
clk:
INstd_logic;
reset:
INstd_logic;
--Inputs
signalclk:
std_logic:
='0';
signalreset:
std_logic:
='0';
signalstart:
std_logic:
='0';
signalsel:
std_logic:
='0';
--Outputs
signalANO:
std_logic_vector(3downto0);
signaldigit:
std_logic_vector(7downto0);
--perioddefinitions
constantclk_period:
time:
=10ns;
constantreset_period:
time:
=500ns;
constantstart_period:
time:
=1000ns;
constantsel_period:
time:
=1500ns;
BEGIN
--InstantiatetheUnitUnderTest(UUT)
uut:
CounterPORTMAP(
clk=>clk,
reset=>reset,
start=>start,
sel=>sel,
ANO=>ANO,
digit=>digit
);
--Clockprocessdefinitions
clk_process:
process
begin
clk<='0';
waitforclk_period/2;
clk<='1';
waitforclk_period/2;
endprocess;
--resetprocessdefinitions
reset_process:
process
start:
INstd_logic;
sel:
INstd_logic;
ANO:
OUTstd_logic_vector(3downto0);
digit:
OUTstd_logic_vector(7downto0)
);
ENDCOMPONENT;
begin
reset<='0';
waitforreset_period/2;
reset<='1';
waitforreset_period/2;
endprocess;
--startprocessdefinitions
start_process:
process
begin
start<='0';
waitforstart_period/2;
start<='1';
waitforstart_period/2;
endprocess;
--selprocessdefinitions
sel_process:
process
begin
sel<='0';
waitforsel_period/2;
sel<='1';
waitforsel_period/2;
endprocess;
--Stimulusprocess
stim_proc:
process
begin
--holdresetstatefor100ns.
waitfor100ns;
waitforclk_period*10;
--insertstimulushere
wait;
endprocess;
END;
综合后的仿真波形:
仿真波形
布局布线后的仿真波形:
仿真波形
实验图片:
---
---
ASM图
实验过程分析:
一、代码分析
I.时钟分频器分析。
秒表共用到两个时钟频率:
100hz和1000hz。
FPGA板子上提供的是50Mhz的时钟频率,采用分频器的
思想可将其分为100hz和1000hz,供时钟计数和数码管扫描使用。
II.按键标志分析。
对“复位键”,“开始_停止键”,“选择键”进行状态标志,以便在另一个Process中对标志进行处理。
III.按键处理分析。
对于按键标志的状态进行处理,分别列出不同状态下的Model值,再采用case语句进行条件分析,并
作出不同的功能操作。
IV.数码管显示处理分析。
采用1000hz的频率对数码管进行扫描输出,其中包括对“选择键”的判断,即数码管以两位显示,还
是以四位显示。
V.按键消抖分析。
通过计数延时的方法进行按键消抖操作。
2、仿真分析与实验结果对照
通过仿真图像的分析以及实验结果的对照,满足了设计的要求,做到了通过按下reset键,将秒表清零,准备计时,等检测到start键按下并松开后,开始计时。
如果再次检测到start键按下并松开后,停止计时。
通过不断检测start键,来确定秒表是否开始计时。
在秒表计时时,七段数码管能够循环的由00…99,00…99…。
开始默认两个七段数码管显示秒,在检测到select键按下并松开后,数码管切换到显示百分之一秒,当再次检测到select键按下并松开后,数码管切换到重新显示秒。
在秒表停止时,数码管依然能够正常切换显示秒,百分之一秒。
实验心得总结:
通过这一次的实验,设计秒表程序的规模明显比之前的要大很多,也要难好多。
这个过程,我采用了控制变量法不断对自己的猜想不断进行验证,并且学会了多process进程的使用,包括process之间的关系,process之间的信号传递等等。
另一点则是对数码管的位选,段选有了更透彻的理解以及按键如何实现消抖操作,使其系统更加稳定。
指导教师批阅意见:
成绩评定:
指导教师签字:
年月日
备注:
注:
1、报告内的项目或内容设置,可根据实际情况加以调整和补充。
2、教师批改学生实验报告时间应在学生提交实验报告时间后10日内。