用VHDL语言设计闹钟系统.docx
《用VHDL语言设计闹钟系统.docx》由会员分享,可在线阅读,更多相关《用VHDL语言设计闹钟系统.docx(26页珍藏版)》请在冰豆网上搜索。
用VHDL语言设计闹钟系统
用VHDL语言设计闹钟系统
(本实验用MAXPLUS2软件和GW48实验箱)
课程设计题目:
闹钟系统设计及实现
目的与任务:
1、巩固专业基础知识及EDA的相关知识;
2、锻炼综合应用所学知识进行小型系统开发设计的能力;
3、培养学生将理论应用于实践的能力;
4、设计一个简单的闹钟系统。
内容和要求:
要求设计一个带闹钟功能的24小时计时器,计时器的外观如图1所示。
图1系统外观
它包括以下几个组成部分:
①显示屏:
4个七段数码管显示当前时间(时:
分)或设置的闹钟时间;一个发光二极管以1HZ的频率跳动,用于显示秒;
②按键key1,用于设置调时还是调分;
③按键key2,用于输入新的时间或新的闹钟时间,每按下一次,时或分加1;
④TIME(时间)键,用于确定新的时间设置;
⑤ALARM(闹钟)键,用于确定新的闹钟时间设置,或显示已设置的闹钟时间;
⑥扬声器,在当前时钟时间与闹钟时间相同时,发出蜂鸣声。
--key1输入作为计数器的触发信号用来选择数码管
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYkey1_trans_hjcIS
PORT(
CLR_HJC:
INSTD_LOGIC;
KEY1_HJC:
INSTD_LOGIC;
Q_HJC:
BUFFERSTD_LOGIC_VECTOR(2DOWNTO0));
ENDENTITYkey1_trans_hjcIS;
ARCHITECTUREHJCOFkey1_trans_hjcIS
BEGIN
PROCESS(CLR_HJC,KEY1_HJC)IS
BEGIN
IF(CLR_HJC='1')THEN
Q_HJC<="000";
ELSIF(KEY1_HJC='1'ANDKEY1_HJC'EVENT)THEN
IF(Q_HJC="100")THEN
Q_HJC<="001";
ELSE
Q_HJC<=Q_HJC+"001";
ENDIF;
ENDIF;
ENDPROCESS;
ENDARCHITECTUREHJC;
--key2用来设定由key1选中的数码管的值
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYKEY2_TRANS_HJCIS
PORT(
CLR_HJC:
INSTD_LOGIC;
KEY2_HJC:
INSTD_LOGIC;
Q2_HJC:
BUFFERSTD_LOGIC_VECTOR(3DOWNTO0));
ENDENTITYKEY2_TRANS_HJC;
ARCHITECTUREARTOFKEY2_TRANS_HJCIS
BEGIN
PROCESS(CLR_HJC,KEY2_HJC)IS
BEGIN
IF(CLR_HJC='1')THEN
Q2_HJC<="0000";
ELSIF(KEY2_HJC='1'ANDKEY2_HJC'EVENT)THEN
IF(Q2_HJC="1001")THEN
Q2_HJC<="0000";
ELSE
Q2_HJC<=Q2_HJC+"0001";
ENDIF;
ENDIF;
ENDPROCESS;
ENDARCHITECTUREART;
--keybuffer_hjc实现选择数码管并赋值,
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYKEYBUFFER_HJCIS
PORT(KEY1_CTRL_HJC:
INSTD_LOGIC_VECTOR(2DOWNTO0);
KEY2_HJC:
INSTD_LOGIC_VECTOR(3DOWNTO0);
CLK_HJC:
INSTD_LOGIC;
CLR_HJC:
INSTD_LOGIC;
NEW_TIME_0_HJC:
OUTSTD_LOGIC_VECTOR(3DOWNTO0);
NEW_TIME_1_HJC:
OUTSTD_LOGIC_VECTOR(3DOWNTO0);
NEW_TIME_2_HJC:
OUTSTD_LOGIC_VECTOR(3DOWNTO0);
NEW_TIME_3_HJC:
OUTSTD_LOGIC_VECTOR(3DOWNTO0));
ENDENTITYKEYBUFFER_HJC;
ARCHITECTUREHJCOFKEYBUFFER_HJCIS
SIGNALN_T_0:
STD_LOGIC_VECTOR(3DOWNTO0);
SIGNALN_T_1:
STD_LOGIC_VECTOR(3DOWNTO0);
SIGNALN_T_2:
STD_LOGIC_VECTOR(3DOWNTO0);
SIGNALN_T_3:
STD_LOGIC_VECTOR(3DOWNTO0);
BEGIN
PROCESS(CLR_HJC,CLK_HJC)IS
BEGIN
IF(CLR_HJC='1')THEN
N_T_0<="0000";
N_T_1<="0000";
N_T_2<="0000";
N_T_3<="0000";
ELSIF(CLK_HJC='1'ANDCLK_HJC'EVENT)THEN
CASEKEY1_CTRL_HJCIS
WHEN"001"=>
N_T_0<=KEY2_HJC;
WHEN"010"=>
N_T_1<=KEY2_HJC;
WHEN"011"=>
N_T_2<=KEY2_HJC;
WHEN"100"=>
N_T_3<=KEY2_HJC;
WHENOTHERS=>
NULL;
ENDCASE;
ENDIF;
ENDPROCESS;
NEW_TIME_0_HJC<=N_T_0;
NEW_TIME_1_HJC<=N_T_1;
NEW_TIME_2_HJC<=N_T_2;
NEW_TIME_3_HJC<=N_T_3;
ENDARCHITECTUREHJC;
--时钟256HZ,通过分频器FQ1_HJC产生1HZ用来驱动LED,以1HZ闪烁
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
ENTITYFQ1_HJCIS
PORT(CLK_IN_HJC:
INSTD_LOGIC;
CLR_HJC:
INSTD_LOGIC;
CLK_OUT1_HJC:
OUTSTD_LOGIC);
ENDENTITYFQ1_HJC;
ARCHITECTUREHJCOFFQ1_HJCIS
BEGIN
CLK1S:
PROCESS(CLK_IN_HJC,CLR_HJC)IS
SUBTYPET_SHORTISINTEGERRANGE0TO65535;
VARIABLECNT1:
T_SHORT;
BEGIN
IF(CLR_HJC='1')THEN
CNT1:
=0;
CLK_OUT1_HJC<='0';
ELSIF(RISING_EDGE(CLK_IN_HJC))THEN
IF(CNT1<128)THEN
CLK_OUT1_HJC<='1';
CNT1:
=CNT1+1;
ELSIF(CNT1<256)THEN
CLK_OUT1_HJC<='0';
CNT1:
=CNT1+1;
ELSE
CNT1:
=0;
ENDIF;
ENDIF;
ENDPROCESSCLK1S;
ENDARCHITECTUREHJC;
--时钟256HZ,通过分频器FQ_HJC产生1/60HZ用来驱动计数器
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
ENTITYFQ_HJCIS
PORT(CLK_IN_HJC:
INSTD_LOGIC;
CLR_HJC:
INSTD_LOGIC;
CLK_OUT_HJC:
OUTSTD_LOGIC);
ENDENTITYFQ_HJC;
ARCHITECTUREHJCOFFQ_HJCIS
BEGIN
CLK1F:
PROCESS(CLK_IN_HJC,CLR_HJC)IS
SUBTYPET_SHORTISINTEGERRANGE0TO65535;
VARIABLECNT:
T_SHORT;
BEGIN
IF(CLR_HJC='1')THEN
CNT:
=0;
CLK_OUT_HJC<='0';
ELSIF(RISING_EDGE(CLK_IN_HJC))THEN
IF(CNT<7680)THEN
CLK_OUT_HJC<='1';
CNT:
=CNT+1;
ELSIF(CNT<15360)THEN
CLK_OUT_HJC<='0';
CNT:
=CNT+1;
ELSE
CNT:
=0;
ENDIF;
ENDIF;
ENDPROCESSCLK1F;
ENDARCHITECTUREHJC;
--技术模块,没有新时间时,以24制时钟规律在计数,最小单位1分钟,有新时间时改变系统时间
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYCOUNTER_HJCIS
PORT(NEW_CURRENT_TIME_0_HJC:
INSTD_LOGIC_VECTOR(3DOWNTO0);
NEW_CURRENT_TIME_1_HJC:
INSTD_LOGIC_VECTOR(3DOWNTO0);
NEW_CURRENT_TIME_2_HJC:
INSTD_LOGIC_VECTOR(3DOWNTO0);
NEW_CURRENT_TIME_3_HJC:
INSTD_LOGIC_VECTOR(3DOWNTO0);
LOAD_NEW_C_HJC:
INSTD_LOGIC;
CLK_HJC:
INSTD_LOGIC;
CLR_HJC:
INSTD_LOGIC;
CURRENT_TIME_0_HJC:
OUTSTD_LOGIC_VECTOR(3DOWNTO0);
CURRENT_TIME_1_HJC:
OUTSTD_LOGIC_VECTOR(3DOWNTO0);
CURRENT_TIME_2_HJC:
OUTSTD_LOGIC_VECTOR(3DOWNTO0);
CURRENT_TIME_3_HJC:
OUTSTD_LOGIC_VECTOR(3DOWNTO0));
ENDENTITYCOUNTER_HJC;
ARCHITECTUREHJCOFCOUNTER_HJCIS
SIGNALI_CURRENT_TIME_0:
STD_LOGIC_VECTOR(3DOWNTO0);
SIGNALI_CURRENT_TIME_1:
STD_LOGIC_VECTOR(3DOWNTO0);
SIGNALI_CURRENT_TIME_2:
STD_LOGIC_VECTOR(3DOWNTO0);
SIGNALI_CURRENT_TIME_3:
STD_LOGIC_VECTOR(3DOWNTO0);
BEGIN
PROCESS(CLK_HJC,CLR_HJC,LOAD_NEW_C_HJC)IS
BEGIN
IF(CLR_HJC='1')THEN
I_CURRENT_TIME_0<="0000";
I_CURRENT_TIME_1<="0000";
I_CURRENT_TIME_2<="0000";
I_CURRENT_TIME_3<="0000";
ELSIF(LOAD_NEW_C_HJC='1')THEN
I_CURRENT_TIME_0<=NEW_CURRENT_TIME_0_HJC;
I_CURRENT_TIME_1<=NEW_CURRENT_TIME_1_HJC;
I_CURRENT_TIME_2<=NEW_CURRENT_TIME_2_HJC;
I_CURRENT_TIME_3<=NEW_CURRENT_TIME_3_HJC;
ELSIF(RISING_EDGE(CLK_HJC))THEN
IF(I_CURRENT_TIME_0<"1001")THEN--分低位<9
I_CURRENT_TIME_0<=I_CURRENT_TIME_0+"0001";
ELSE
I_CURRENT_TIME_0<="0000";
IF(I_CURRENT_TIME_1<"0101")THEN--分高位<5
I_CURRENT_TIME_1<=I_CURRENT_TIME_1+"0001";
ELSE
I_CURRENT_TIME_1<="0000";
IF(I_CURRENT_TIME_3<"0010")THEN--时高位为0或1时
IF(I_CURRENT_TIME_2<"1001")THEN--时低位<9
I_CURRENT_TIME_2<=I_CURRENT_TIME_2+"0001";
ELSE
I_CURRENT_TIME_2<="0000";
I_CURRENT_TIME_3<=I_CURRENT_TIME_3+"0001";
ENDIF;
ELSE
IF(I_CURRENT_TIME_2<"0011")THEN--时高位为2时,时低位<3
I_CURRENT_TIME_2<=I_CURRENT_TIME_2+1;
ELSE
I_CURRENT_TIME_2<="0000";
I_CURRENT_TIME_3<="0000";
ENDIF;
ENDIF;
ENDIF;
ENDIF;
ENDIF;
ENDPROCESS;
CURRENT_TIME_0_HJC<=I_CURRENT_TIME_0;
CURRENT_TIME_1_HJC<=I_CURRENT_TIME_1;
CURRENT_TIME_2_HJC<=I_CURRENT_TIME_2;
CURRENT_TIME_3_HJC<=I_CURRENT_TIME_3;
ENDARCHITECTUREHJC;
--控制器,本系统有五个状态,S0-初始状态,S1-设置新时间状态S2-确认为时钟时间状态,S3-确认为闹钟时间状态S4-显示闹钟时间状态,控制器就是控制状态转换的
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYCONTROLLER_HJCIS
PORT(
KEY1_HJC:
INSTD_LOGIC;
ALARM_BUTTON_HJC:
INSTD_LOGIC;
TIME_BUTTON_HJC:
INSTD_LOGIC;
CLK_HJC:
INSTD_LOGIC;
CLR_HJC:
INSTD_LOGIC;
LOAD_NEW_A_HJC:
OUTSTD_LOGIC;
LOAD_NEW_C_HJC:
OUTSTD_LOGIC;
SHOW_NEW_TIME_HJC:
OUTSTD_LOGIC;
SHOW_A_HJC:
OUTSTD_LOGIC
);
ENDENTITYCONTROLLER_HJCIS
ARCHITECTUREHJCOFCONTROLLER_HJCIS
TYPET_STATEIS(S0,S1,S2,S3,S4);
SUBTYPET_SHORTISINTEGERRANGE0TO65535;
CONSTANTKEY_TIMEOUT:
T_SHORT:
=2560;--从按键状态返回时等待10S
CONSTANTSHOW_ALARM_TIMEOUT:
T_SHORT:
=1280;--从闹钟时间返回时等待5S
SIGNALCURR_STATE:
T_STATE;
SIGNALNEXT_STATE:
T_STATE;
SIGNALCOUNTER_K:
T_SHORT;
SIGNALENABLE_COUNT_K:
STD_LOGIC;
SIGNALCOUNT_K_END:
STD_LOGIC;
SIGNALCOUNTER_A:
T_SHORT;
SIGNALENABLE_COUNT_A:
STD_LOGIC;
SIGNALCOUNT_A_END:
STD_LOGIC;
BEGIN
PROCESS(CLK_HJC,CLR_HJC)IS
BEGIN
IF(CLR_HJC='1')THEN
CURR_STATE<=S0;
ELSEIF(RISING_EDGE(CLK_HJC))THEN
CURR_STATE<=NEXT_STATE;
ENDIF;
ENDIF;
ENDPROCESS;
PROCESS(KEY1_HJC,ALARM_BUTTON_HJC,TIME_BUTTON_HJC,
CURR_STATE,COUNT_A_END,COUNT_K_END)IS
BEGIN
NEXT_STATE<=CURR_STATE;
LOAD_NEW_A_HJC<='0';
LOAD_NEW_C_HJC<='0';
SHOW_A_HJC<='0';
SHOW_NEW_TIME_HJC<='0';
ENABLE_COUNT_K<='0';
ENABLE_COUNT_A<='0';
CASECURR_STATEIS
WHENS0=>
IF(KEY1_HJC='1')THEN
NEXT_STATE<=S1;
SHOW_NEW_TIME_HJC<='1';
ELSIF(ALARM_BUTTON_HJC='1')THEN
NEXT_STATE<=S4;
SHOW_A_HJC<='1';
ELSE
NEXT_STATE<=S0;
ENDIF;
WHENS1=>
IF(KEY1_HJC='1')THEN
NEXT_STATE<=S1;
ELSIF(ALARM_BUTTON_HJC='1')THEN
NEXT_STATE<=S2;
LOAD_NEW_A_HJC<='1';
ELSIF(TIME_BUTTON_HJC='1')THEN
NEXT_STATE<=S3;
LOAD_NEW_C_HJC<='1';
ELSE
IF(COUNT_K_END='1')THEN
NEXT_STATE<=S0;
ELSE
NEXT_STATE<=S1;
ENDIF;
ENABLE_COUNT_K<='1';
ENDIF;
SHOW_NEW_TIME_HJC<='1';
WHENS2=>
IF(ALARM_BUTTON_HJC='1')THEN
NEXT_STATE<=S2;
LOAD_NEW_A_HJC<='1';
ELSE
NEXT_STATE<=S0;
ENDIF;
WHENS3=>
IF(TIME_BUTTON_HJC='1')THEN
NEXT_STATE<=S3;
LOAD_NEW_C_HJC<='1';
ELSE
NEXT_STATE<=S0;
ENDIF;
WHENS4=>
IF(KEY1_HJC='1')THEN
NEXT_STATE<=S1;
ELSE
NEXT_STATE<=S4;
IF(COUNT_A_END='1')THEN
NEXT_STATE<=S0;
ELSE
NEXT_STATE<=S4;
SHOW_A_HJC<='1';
ENDIF;
ENABLE_COUNT_A<='1';
ENDIF;
WHENOTHERS=>
NULL;
ENDCASE;
ENDPROCESS;
COUNT_KEY:
PROCESS(ENABLE_COUNT_K,CLK_HJC)IS
BEGIN
IF(ENABLE_COUNT_K='0')THEN
COUNTER_K<=0;
COUNT_K_END<='0';
ELSIF(RISING_EDGE(CLK_HJC))THEN
IF(COUNTER_K>=KEY_TIMEOUT)THEN
COUNT_K_END<='1';
ELSE
COUNTER_K<=COUNTER_K+1;
ENDIF;
ENDIF;
ENDPROCESSCOUNT_KEY;
COUNT_ALARM:
PROCESS(ENABLE_COUNT_A,CLK_HJC)IS
BEGIN
IF(ENABLE_COUNT_A='0')THEN
COUNTER_A<=0;
COUNT_A_END<='0';
ELSIF(RISING_EDGE(CLK_HJC))THEN
IF(COUNTER_A>=SHOW_ALARM_TIMEOUT)THEN
COUNT_A_END<='1';
ELSE
COUNTER_A<=COUNTER_A+1;
ENDIF;
ENDIF;
ENDPROCESSCOUNT_ALARM;
ENDARCHITECTURE;
--显示驱动模块,是显示新时间还是闹钟时间,还是时钟时间
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1