VHDL数字时钟实验报告.docx
《VHDL数字时钟实验报告.docx》由会员分享,可在线阅读,更多相关《VHDL数字时钟实验报告.docx(34页珍藏版)》请在冰点文库上搜索。
VHDL数字时钟实验报告
VHDL数字时钟设计
一、实验目的:
进一步练习VHDL语言设计工程的建立与仿真的步骤和方法、熟悉VHDL语言基本设计实体的编写方法。
同时,在已有知识的基础上,简单综合编写程序,仿制简单器械。
二、实验环境:
PC个人计算机、WindowsXP操作系统、QuartusII集成开发环境软件。
三、设计要求:
运用VHDL语言编写一个数字钟,具体要求:
1.具有时、分、秒计数的十进制数字显示功能,以24小时循环计时。
2.具有手动调节小时,分钟的功能。
3.具有闹钟的功能,能够在设定的闹钟时间发出闹铃声。
四、实验步骤:
1.定义输入输出信号量
port(
clk:
instd_logic;---时钟
speak:
outstd_logic;---铃
dout:
outstd_logic_vector(7downto0);---晶体管显示
setclk:
instd_logic_vector(2downto0);---操作按钮
d1,d2,d3,d4,d5,d6:
outstd_logic);---六个晶体管
2.定义结构体中的信号量
signalsel:
std_logic_vector(2downto0);
signalhou1:
std_logic_vector(3downto0);--时分秒的个位和十位
signalhou2:
std_logic_vector(3downto0);
signalmin1:
std_logic_vector(3downto0);
signalmin2:
std_logic_vector(3downto0);
signalseth1:
std_logic_vector(3downto0);
signalseth2:
std_logic_vector(3downto0);
signalsetm1:
std_logic_vector(3downto0);
signalsetm2:
std_logic_vector(3downto0);
signalsec1:
std_logic_vector(3downto0);
signalsec2:
std_logic_vector(3downto0);
signalh1:
std_logic_vector(3downto0);
signalh2:
std_logic_vector(3downto0);
signalm1:
std_logic_vector(3downto0);
signalm2:
std_logic_vector(3downto0);
signals1:
std_logic_vector(3downto0);
signals2:
std_logic_vector(3downto0);
signalsph1,sph2,spm1,spm2,sps1,sps2:
std_logic_vector(3downto0);
signalcount_sec:
std_logic_vector(9downto0);
signalsec_co:
std_logic;
signalco1,co2,co3,co4:
std_logic;--进位
signalswitch:
std_logic_vector(1downto0);--表示状态
3.分频模块
用来定义秒count_sec用来计时钟个数,当count_sec=1111111111时,及得到1Hz信号。
代码如下:
process(clk)is--defineasecond
begin
if(clk'eventandclk='1')then
if(count_sec="1111111111")then
count_sec<="0000000000";
sec_co<='1';
else
count_sec<=count_sec+'1';
sec_co<='0';
endif;
endif;
endprocess;
4.时钟正常走时模块
该模块使用6个进程实现,分别为秒个位计时、秒十位计时、分个位计时、分十位计时、时个位计时、时十位计时。
process(sec_co)is------------秒个位
begin
ifswitch="00"then--正常状态
ifsec_co='1'then
ifsec2="1001"then
sec2<="0000";
co1<='1';
else
sec2<=sec2+'1';
co1<='0';
endif;
endif;
elsifswitch="01"then--调时状态
sec2<="0000";
endif;
endprocess;
--------------------------------------------------
process(co1)is-------秒十位
begin
ifswitch="00"then
ifco1'eventandco1='1'then
if(sec1="0101")then
sec1<="0000";
co2<='1';
else
sec1<=sec1+'1';
co2<='0';
endif;
endif;
elsifswitch="01"then
sec1<="0000";
endif;
endprocess;
-------------------------------------------------
process(co1,co2)is--------分钟个位
begin
ifswitch="00"then
ifco2'eventandco2='1'then
ifmin2="1001"then
min2<="0000";
co3<='1';
else
min2<=min2+'1';
co3<='0';
endif;
endif;
elsifswitch="01"then
min2<=setm2;
endif;
endprocess;
------------------------------------------------------
process(co3)is-----------分钟十位
begin
ifswitch="00"then
ifco3='1'then
ifmin1="0101"then
min1<="0000";
co4<='1';
else
min1<=min1+'1';
co4<='0';
endif;
endif;
elsifswitch="01"then
min1<=setm1;
endif;
endprocess;
---------------------------------------------------------
process(co4)-------小时
begin
ifswitch="00"then
ifco4='1'then
if(hou1="0010")then--小时十位为2时,个位满3进一
if(hou2="0011")then
hou2<="0000";
hou1<="0000";
else
hou2<=hou2+'1';
endif;
else--小时十位为0或1,个位满9进一
if(hou2="1001")then
hou2<="0000";
hou1<=hou1+'1';
else
hou2<=hou2+'1';
endif;
endif;
endif;
elsifswitch="01"then
hou1<=seth1;
hou2<=seth2;
endif;
endprocess;
5.调时模块
该进程用来控制时钟状态,switch为“00”时正常显示时间,为“01”时是进行调时,
为“10”时是设置闹钟时间。
代码如下:
process(setclk(0))is
begin
if(setclk(0)'eventandsetclk(0)='1')then
if(switch="10")then
switch<="00";
else
switch<=switch+'1';
endif;
endif;
endprocess;
process(setclk
(2),switch,setclk
(1))is
begin--setclk
(1)为1调分
if(switch="01"andsetclk
(1)='1')then
if(setclk
(2)'eventandsetclk
(2)='1')then
if(setm2="1001")then
setm2<="0000";
if(setm1="0101")then
setm1<="0000";
else
setm1<=setm1+'1';
endif;
else
setm2<=setm2+'1';
endif;
endif;
endif;
endprocess;
process(setclk
(2),switch,setclk
(1))is
begin--setclk
(1)为0调时
if(switch="01"andsetclk
(1)='0')then
if(setclk
(2)'eventandsetclk
(2)='1')then
if(seth1="0010")then
if(seth2="0011")then
seth1<="0000";
seth2<="0000";
else
seth2<=seth2+'1';
endif;
else
if(seth2="1001")then
seth1<=seth1+'1';
seth2<="0000";
else
seth2<=seth2+'1';
endif;
endif;
endif;
endif;
endprocess;
6.闹钟模块
该模块由3个小模块组成,分别为设置闹钟时间、判断闹钟时间是否到达以及闹铃声音模块。
(1)设置闹钟时间模块
该进程用于设置闹钟时间。
信号量switch为‘10‘时,表示设置闹钟时间;
if(switch="10")then--调闹钟时,显示闹钟设置时间
ifsel="000"then
d1<='0';
casesph1is
when"0000"=>dout<="11000000";
when"0001"=>dout<="11111001";
when"0010"=>dout<="10100100";
whenothers=>dout<="XXXXXXXX";
endcase;
elsifsel="001"then
d2<='0';
casesph2is
when"0000"=>dout<="11000000";
when"0001"=>dout<="11111001";
when"0010"=>dout<="10100100";
when"0011"=>dout<="10110000";
when"0100"=>dout<="10011001";
when"0101"=>dout<="10010010";
when"0110"=>dout<="10000010";
when"0111"=>dout<="11111000";
when"1000"=>dout<="10000000";
when"1001"=>dout<="10010000";
whenothers=>dout<="XXXXXXXX";
endcase;
elsifsel="010"then
d3<='0';
casespm1is
when"0000"=>dout<="11000000";
when"0001"=>dout<="11111001";
when"0010"=>dout<="10100100";
when"0011"=>dout<="10110000";
when"0100"=>dout<="10011001";
when"0101"=>dout<="10010010";
whenothers=>dout<="XXXXXXXX";
endcase;
elsifsel="011"then
d4<='0';
casespm2is
when"0000"=>dout<="11000000";
when"0001"=>dout<="11111001";
when"0010"=>dout<="10100100";
when"0011"=>dout<="10110000";
when"0100"=>dout<="10011001";
when"0101"=>dout<="10010010";
when"0110"=>dout<="10000010";
when"0111"=>dout<="11111000";
when"1000"=>dout<="10000000";
when"1001"=>dout<="10010000";
whenothers=>dout<="XXXXXXXX";
endcase;
elsifsel="100"then
d5<='0';
casesps1is
when"0000"=>dout<="11000000";
when"0001"=>dout<="11111001";
when"0010"=>dout<="10100100";
when"0011"=>dout<="10110000";
when"0100"=>dout<="10011001";
when"0101"=>dout<="10010010";
whenothers=>dout<="XXXXXXXX";
endcase;
elsifsel="101"then
d6<='0';
casesps2is
when"0000"=>dout<="11000000";
when"0001"=>dout<="11111001";
when"0010"=>dout<="10100100";
when"0011"=>dout<="10110000";
when"0100"=>dout<="10011001";
when"0101"=>dout<="10010010";
when"0110"=>dout<="10000010";
when"0111"=>dout<="11111000";
when"1000"=>dout<="10000000";
when"1001"=>dout<="10010000";
whenothers=>dout<="XXXXXXXX";
endcase;
endif;
(2)闹铃声音模块
通过分频产生蜂鸣,即发出闹铃声音。
process(switch)is------闹铃
begin--设置闹铃时秒归零
ifswitch="10"then
sps1<="0000";
sps2<="0000";
endif;
endprocess;
process(switch,setclk
(2),setclk
(1))is
begin
if(switch="10"andsetclk
(1)='1')then
if(setclk
(2)'eventandsetclk
(2)='1')then
if(spm2="1001")then
spm2<="0000";
if(spm1="0101")then
spm1<="0000";
else
spm1<=spm1+'1';
endif;
else
spm2<=spm2+'1';
endif;
endif;
endif;
endprocess;
process(switch,setclk
(2),setclk
(1))is
begin
if(switch="10"andsetclk
(1)='0')then
if(setclk
(2)'eventandsetclk
(2)='1')then
if(sph1="0010")then
if(sph2="0011")then
sph1<="0000";
sph2<="0000";
else
sph2<=sph2+'1';
endif;
else
if(sph2="1001")then
sph2<="0000";
sph1<=sph1+'1';
else
sph2<=sph2+'1';
endif;
endif;
endif;
endif;
endprocess;
process(clk,sph1,sph2,spm1,spm2,hou1,hou2,min1,min2)is
begin
if(sph1=hou1andsph2=hou2andspm1=min1andspm2=min2)then
speak<=clk;
else
speak<='0';
endif;
endprocess;
7.数码管显示模块
(1)选择时间显示
process(key1,key2,change)
begin
if(key1='0')and(key2='0')then
sec_0<=sec_00;
sec_1<=sec_11;
min_0<=min_00;
min_1<=min_11;
hour_1<=hour_11;
hour_0<=hour_00;
elsif(key1='1')and(key2='0')then
sec_0<=sec_000;
sec_1<=sec_111;
min_0<=min_000;
min_1<=min_111;
hour_0<=hour_000;
hour_1<=hour_111;
elsif(key1='0')and(key2='1')then
sec_0<=sec_0000;
sec_1<=sec_1111;
min_0<=min_0000;
min_1<=min_1111;
hour_0<=hour_0000;
hour_1<=hour_1111;
endif;
endprocess;
(2)数码管时间显示
ifsel="000"then
d1<='0';
caseh1is
when"0000"=>dout<="11000000";
when"0001"=>dout<="11111001";
when"0010"=>dout<="10100100";
whenothers=>dout<="XXXXXXXX";
endcase;
elsifsel="001"then
d2<='0';
caseh2is
when"0000"=>dout<="11000000";
when"0001"=>dout<="11111001";
when"0010"=>dout<="10100100";
when"0011"=>dout<="10110000";
when"0100"=>dout<="10011001";
when"0101"=>dout<="10010010";
when"0110"=>dout<="10000010";
when"0111"=>dout<="11111000";
when"1000"=>dout<="10000000";
when"1001"=>dout<="10010000";
whenothers=>dout<="XXXXXXXX";
endcase;
elsifsel="010"then
d3<='0';
casem1is
when"0000"=>dout<="11000000";
when"0001"=>dout<="11111001";
when"0010"=>dout<="10100100";
when"0011"=>dout<="10110000";
when"0100"=>dout<="10011001";
when"0101"=>dout<="10010010";
whenothers=>dout<="XXXXXXXX";
endcase;
elsifsel="011"then
d4<='0';
casem2is