数字钟设计报告
绪论:
20世纪90年代,国际上电子和计算机技术较为先进的国家,一直在积极探索新的电子电路设计方法,并在设计方法、工具等方面进行了彻底的变革,取得了巨大成功。在电子技术设计领域,可编程逻辑器件(如CPLD、FPGA)的应用,已得到广泛的普及,这些器件为数字系统的设计带来了极大的灵活性。这些器件可以通过软件编程而对其硬件结构和工作方式进行重构,从而使得硬件的设计可以如同软件设计那样方便快捷。这一切极大地改变了传统的数字系统设计方法、设计过程和设计观念,促进了EDA技术的迅速发展。
EDA技术就是以计算机为工具,设计者在EDA软件平台上,用硬件描述语言VHDL完成设计文件,然后由计算机自动地完成逻辑编译、化简、分割、综合、优化、布局、布线和仿真,直至对于特定目标芯片的适配编译、逻辑映射和编程下载等工作。EDA技术的出现,极大地提高了电路设计的效率和可操作性,减轻了设计者的劳动强度。
概要:
本设计主要利用VHDL语言在EDA平台上设计一个24进制和12进制可以相互转换的电子数字钟,另外还具有设置时间和闹钟功能。总的程序由几个各具不同功能的单元模块程序拼接而成,其中包括分频程序模块、时分秒计数和设置程序模块、比较器程序模块、译码显示程序模块。并且使用QUARTUS II软件进行电路波形仿真,下载到实验箱进行验证。
一、设计目的
1、熟练地运用数字系统的设计方法进行数字系统设计; 2、能进行较复杂的数字系统设计; 3、按要求设计一个数字钟。
二、设计思路
数字钟的设计模块包括:分频器、“时、分、秒”计数器、闪烁电路、整点报时和译码显示电路。
每一个功能模块作为一个实体单独进行设计,最后再用VHDL的例化语句将各个模块进行整合。
该数字钟可以实现的几个功能:计时功能、设置时间功能、设置闹钟和报时功能。
三、系统设计
分频模块 闪烁模块 计时与设置时间模块 时间和闹钟显示选择以及闹钟模块 显示模块 时间控制模块 闹钟控制模块
设置闹钟模块
1、分频模块:提供1hz的时钟信号与100hz的测试时钟信号。可通过实验板上的k2键来调节。
2、时间控制模块:控制设置时间和计时的使能信号。 3、闹钟控制模块:控制设置闹钟和计时的使能信号。 4、计时与设置时间模块和设置闹钟模块:
通过时间控制模块和闹钟控制模块传来的使能信号来转换计时、设置时间和设置闹钟。可以通过Key0键设置时间,Key1键设置闹钟。Key3键选择需要设置的位数,Key4键来调
整时间。
5、时间和闹钟显示选择以及闹钟模块:
接收计时与设置时间模块和设置闹钟模块传来的数据选择时间或者闹钟传至显示模块。并且可以根据sw2键来改变传至显示模块的是12进制和24进制。可以整点报时和闹钟。 6、显示模块:将从时间和闹钟显示选择模块传来的数据显示在数码管上。并且可以在设置时间和设置闹钟时闪烁显示。
五、模块设计
1分频模块
引入50Mhz的时钟信号,根据(50M/2n)-1,实现1hz和100hz的分频
ARCHITECTURE BAHAV OF FD IS SIGNAL Q,Q1:STD_LOGIC; BEGIN
PROCESS(CLK,EN,SW2)
VARIABLE TEMP : INTEGER RANGE 24999999 DOWNTO 0; BEGIN
IF SW2='1' THEN IF EN='1' THEN IF CLK'EVENT AND CLK='1'THEN IF TEMP=24999999 THEN TEMP:=0;Q<=NOT Q; ELSE TEMP:=TEMP+1; END IF; END IF; ELSE TEMP:=0;Q<='0'; END IF; END IF;
END PROCESS;
PROCESS(CLK,EN,SW2)
VARIABLE TEMP1 : INTEGER RANGE 249999 DOWNTO 0; BEGIN
IF SW2='0' THEN IF EN='1' THEN IF CLK'EVENT AND CLK='1'THEN IF TEMP1=249999 THEN TEMP1:=0;Q1<=NOT Q1;
ELSE TEMP1:=TEMP1+1; END IF; END IF; ELSE TEMP1:=0;Q1<='0'; END IF; END IF;
END PROCESS; PROCESS(SW2) BEGIN
IF SW2='1' THEN CLK_OUT<=Q; ELSE CLK_OUT<=Q1; END IF;
END PROCESS;
END ARCHITECTURE;
2、时间控制模块(与闹钟控制模块类似) (1)功能分析
通过TIMESET(KEY0)键来控制设置时间,按下TIMESET(KEY0),开始设置时间,再次按下表示设置结束。通过使用状态机,每按下一次SHIFT(KEY3)改变状态从状态s0->s1->s2->s3->s4->s1来改变使能信号。S0状态为计时模式,S1,S2,S3,S4状态为设置时间模式。S1状态为分钟低位可设置,S2状态为分钟高位可设置,S3状态为小时低位可设置,S4状态为小时高位可设置。 (2)信号分析
SEC_EN0,MIN_EN1,MIN_EN0,HOUR_EN1,HOUR_EN0为0时为不可改变状态(不能计时和设置),为1时为可改变状态(能计时和设置)。SEL为0时,传入计时与设置时间模块的是1hz的时钟信号,SEL为1时,进入设置模式,传入计时与设置时间模块的是ADD信号(KEY2),
ARCHITECTURE BAHAV OF SETMODE IS TYPE FSM_ST IS (S0,S1,S2,S3,S4); SIGNAL CST,NST: FSM_ST:=S0; SIGNAL FLAG: STD_LOGIC:='0'; BEGIN
PROCESS(TIMESET) BEGIN
IF TIMESET'EVENT AND TIMESET='1' THEN FLAG<=NOT FLAG;——小时时间设置标记
FLAG_H<=FLAG;——输出小时时间设置标记 END IF ;
END PROCESS;
PROCESS(SHIFT) BEGIN
IF FLAG='1' THEN IF SHIFT'EVENT AND SHIFT='1' THEN CST<=NST; END IF; LED<='1'; ELSE
CST<=S0;LED<='0'; END IF;
END PROCESS; ——
PROCESS(CST) BEGIN
CASE CST IS
WHEN S0=> NST<=S1;——S0状态为计时模式
WHEN S1=> NST<=S2;——S1状态为分钟低位可设置 WHEN S2=> NST<=S3;——S2状态为分钟高位可设置 WHEN S3=> NST<=S4;——S3状态为小时低位可设置 WHEN S4=> NST<=S1;——S4状态为小时高位可设置 WHEN OTHERS=> NST<=S0; END CASE; END PROCESS;
PROCESS(CST) BEGIN
CASE CST IS
WHEN S0=> SEC_EN<='1';MIN_EN1<='1';MIN_EN0<='1';HOUR_EN1<='1';HOUR_EN0<='1';SEL<='0'; WHEN S1=> SEC_EN<='0';MIN_EN1<='0';MIN_EN0<='1';HOUR_EN1<='0';HOUR_EN0<='0';SEL<='1'; WHEN S2=> SEC_EN<='0';MIN_EN1<='1';MIN_EN0<='0';HOUR_EN1<='0';HOUR_EN0<='0';SEL<='1'; WHEN S3=> SEC_EN<='0';MIN_EN1<='0';MIN_EN0<='0';HOUR_EN1<='0';HOUR_EN0<='1';SEL<='1'; WHEN S4=> SEC_EN<='0';MIN_EN1<='0';MIN_EN0<='0';HOUR_EN1<='1';HOUR_EN0<='0';SEL<='1'; WHEN
OTHERS=> SEC_EN<='0';MIN_EN1<='0';MIN_EN0<='0';HOUR_EN1<='0';HOUR_EN0<='0';SEL<='0'; END CASE; END PROCESS;
END ARCHITECTURE;
3、小时模块(秒钟,分钟模块类似)
本模块分为3个进程
第一个进程的功能为转换时钟信号与设置信号(KEY2),由时间控制模块传来的HOUR_SEL控制。
第二个进程的功能为小时低位的计数和设置。
第二个进程的功能为小时高位的计数和设置。并且考虑到了低位和高位的钳制。
ARCHITECTURE BAHAV OF HOUR IS
SIGNAL HOURVALUE: STD_LOGIC_VECTOR(7 DOWNTO 0):=\"00100011\"; SIGNAL CLK_IN: STD_LOGIC; BEGIN
PROCESS(HOUR_SEL)——转换时钟信号与设置信号 BEGIN
IF HOUR_SEL='0' THEN CLK_IN<=HCLK; ELSE CLK_IN<=HOUR_SET; END IF;
END PROCESS;
PROCESS(CLK_IN,EN0)——小时低位的计数和设置 BEGIN IF EN0='1' THEN IF CLK_IN'EVENT AND CLK_IN='1' THEN IF HOURVALUE(7 DOWNTO 4)=\"0010\" THEN IF HOURVALUE(3 DOWNTO 0)=\"0011\" THEN HOURVALUE(3 DOWNTO 0)<=\"0000\"; ELSE HOURVALUE(3 DOWNTO 0)<=HOURVALUE(3 DOWNTO 0)+'1'; END IF; ELSIF HOURVALUE(3 DOWNTO 0)<\"1001\" THEN HOURVALUE(3 DOWNTO 0)<=HOURVALUE(3 DOWNTO 0)+'1'; ELSE HOURVALUE(3 DOWNTO 0)<=\"0000\"; END IF; END IF; END IF; END PROCESS;
PROCESS(CLK_IN,EN1)——小时高位的计数和设置。并且考虑到了低位和高位的钳制 BEGIN IF EN1='1' THEN IF CLK_IN'EVENT AND CLK_IN='1' THEN IF EN0='1' THEN
IF HOURVALUE(3 DOWNTO 0)=\"0011\" OR HOURVALUE(3 DOWNTO 0)=\"1001\" THEN IF HOURVALUE(7 DOWNTO 4)=\"0010\" THEN HOURVALUE(7 DOWNTO 4)<=\"0000\"; ELSIF HOURVALUE(3 DOWNTO 0)=\"1001\" THEN IF HOURVALUE(7 DOWNTO 4)<\"0011\" THEN HOURVALUE(7 DOWNTO 4)<=HOURVALUE(7 DOWNTO 4)+'1'; END IF; END IF; END IF;
——设置小时低位对高位钳制
ELSIF HOURVALUE(3 DOWNTO 0)<\"0100\" THEN IF HOURVALUE(7 DOWNTO 4)<\"0010\" THEN HOURVALUE(7 DOWNTO 4)<=HOURVALUE(7 DOWNTO 4)+'1'; ELSE HOURVALUE(7 DOWNTO 4)<=\"0000\"; END IF; ELSIF HOURVALUE(3 DOWNTO 0)>=\"0100\" THEN IF HOURVALUE(7 DOWNTO 4)<\"0001\" THEN HOURVALUE(7 DOWNTO 4)<=HOURVALUE(7 DOWNTO 4)+'1'; ELSE HOURVALUE(7 DOWNTO 4)<=\"0000\"; END IF; END IF; END IF; END IF; END PROCESS;
HOUR0<=HOURVALUE(3 DOWNTO 0); HOUR1<=HOURVALUE(7 DOWNTO 4);
END ARCHITECTURE;
4、选择模块和闹钟报时模块
第一个进程为24进制和12进制转换,当SW信号为1时,选择24进制时间输出,当SW信号为0时,将24进制时间转换为12进制时间输出。 第二个进程为判断12进制是AM还是PM
第三个进程为12进制是AM或PM数码管灯提示。
第四个进程为闹钟报时与整点报时模块:当计时模块传来的时间和闹钟设置的时间相等时,闹钟提示灯闪烁,或者分钟模块传来是30或00时,闹钟提示灯闪烁。
ARCHITECTURE BAHAV OF CHOOSE IS SIGNAL FLAG_AP: STD_LOGIC;
BEGIN
PROCESS(FLAG) BEGIN
IF FLAG='1' THEN ——闹钟时间输出 MIN0<=AMININ0;MIN1<=AMININ1; HOUR0<=AHOURIN0;HOUR1<=AHOURIN1; HF0<=AH_FLASH0;HF1<=AH_FLASH1; MF0<=AM_FLASH0;MF1<=AM_FLASH1; ELSE——时钟时间输出 MIN0<=MININ0;MIN1<=MININ1; HF0<=H_FLASH0;HF1<=H_FLASH1; MF0<=M_FLASH0;MF1<=M_FLASH1; IF SW='1' THEN HOUR0<=HOURIN0;HOUR1<=HOURIN1; ELSE IF FLAG_H='0' THEN ——24进制输出 HOUR0<=HOURIN0;HOUR1<=HOURIN1; ELSE ——24进制转换12进制时间输出 IF HOURIN1&HOURIN0>=\"00010010\" THEN IF HOURIN0>=\"0010\" THEN HOUR1<=HOURIN1-\"0001\";HOUR0<=HOURIN0-\"0010\"; ELSIF HOURIN0=\"0001\" THEN HOUR1<=HOURIN1-\"0001\";HOUR0<=\"1001\"; ELSIF HOURIN0=\"0000\" THEN HOUR1<=HOURIN1-\"0001\";HOUR0<=\"1000\"; END IF; ELSE HOUR1<=HOURIN1;HOUR0<=HOURIN0; END IF; END IF; END IF; END IF;
END PROCESS;
——判断12进制是AM还是PM
PROCESS(HOURIN1,HOURIN0) BEGIN
IF HOURIN1>=\"0001\"AND HOURIN0>=\"0010\" THEN FLAG_AP<='1'; ELSE FLAG_AP<='0'; END IF;
END PROCESS;
——12进制是AM或PM数码管灯提示
PROCESS(FLAG_AP,SW) BEGIN
IF SW='1' THEN HEX<=\"1111111\"; ELSE
IF FLAG_AP='1' THEN
HEX<=\"0001100\"; ELSE HEX<=\"0001000\"; END IF; END IF;
END PROCESS;
——整点报时,半点报时,闹钟
PROCESS(AMININ0,AMININ1,AHOURIN0,AHOURIN1,MININ0,MININ1,HOURIN0,HOURIN1) BEGIN IF (AMININ0=MININ0 AND AMININ1=MININ1 AND AHOURIN0=HOURIN0 AND AHOURIN1=HOURIN1) OR MININ1&MININ0=\"00000000\" OR MININ1&MININ0=\"00110000\" THEN FLASH_FLAG<='1' ; ELSE
FLASH_FLAG<='0'; END IF;
END PROCESS;
END ARCHITECTURE;
5、显示模块
HOURFLASH1,HOURFLASH0,MINFLASH1,MINFLASH0信号控制数码管的闪烁,当这些信号为1时,数码管暗,为0时,数码管显示数值。
SECIN0,SECIN1,MININ0,MININ1,HOURIN0,HOURIN1为时间和闹钟显示选择以及闹钟模块传来的四进制数,每一个进程的作用就是将传来的四进制数译码为7进制数,传入实验板中,使数码管显示相应的数值。
ARCHITECTURE BEHAV OF DISP IS
SIGNAL REG7_0: STD_LOGIC_VECTOR(6 DOWNTO 0); SIGNAL REG7_1: STD_LOGIC_VECTOR(6 DOWNTO 0); SIGNAL REG7_2: STD_LOGIC_VECTOR(6 DOWNTO 0); SIGNAL REG7_3: STD_LOGIC_VECTOR(6 DOWNTO 0); SIGNAL REG7_4: STD_LOGIC_VECTOR(6 DOWNTO 0); SIGNAL REG7_5: STD_LOGIC_VECTOR(6 DOWNTO 0); SIGNAL REG7_6: STD_LOGIC_VECTOR(6 DOWNTO 0);
SIGNAL REG7_7: STD_LOGIC_VECTOR(6 DOWNTO 0); SIGNAL REG7_8: STD_LOGIC_VECTOR(6 DOWNTO 0); SIGNAL REG7_9: STD_LOGIC_VECTOR(6 DOWNTO 0);
SIGNAL REG7_NULL: STD_LOGIC_VECTOR(6 DOWNTO 0); SIGNAL LEDX:STD_LOGIC; BEGIN
REG7_0<=\"1000000\";——数码管0 REG7_1<=\"1111001\";——数码管1 REG7_2<=\"0100100\";——数码管2 REG7_3<=\"0110000\";——数码管3 REG7_4<=\"0011001\";——数码管4 REG7_5<=\"0010010\";——数码管5 REG7_6<=\"0000010\";——数码管6 REG7_7<=\"1111000\";——数码管7 REG7_8<=\"0000000\";——数码管8 REG7_9<=\"0010000\";——数码管9 REG7_NULL<=\"1111111\";——不显示
——译码器
PROCESS(HOURFLASH1,HOURIN1,EN) BEGIN
IF EN='1' THEN IF HOURFLASH1='1' THEN HOUR1<=REG7_NULL; ELSE CASE HOURIN1 IS WHEN \"0000\"=>HOUR1<=REG7_0; WHEN \"0001\"=>HOUR1<=REG7_1; WHEN \"0010\"=>HOUR1<=REG7_2; WHEN \"0011\"=>HOUR1<=REG7_3; WHEN \"0100\"=>HOUR1<=REG7_4; WHEN \"0101\"=>HOUR1<=REG7_5; WHEN \"0110\"=>HOUR1<=REG7_6; WHEN \"0111\"=>HOUR1<=REG7_7; WHEN \"1000\"=>HOUR1<=REG7_8; WHEN \"1001\"=>HOUR1<=REG7_9; WHEN OTHERS=>HOUR1<=REG7_NULL; END CASE; END IF; ELSE HOUR1<=REG7_1; END IF;
END PROCESS;
PROCESS(HOURFLASH0,HOURIN0) BEGIN
IF EN='1' THEN
IF HOURFLASH0='1' THEN HOUR0<=REG7_NULL; ELSE CASE HOURIN0 IS WHEN \"0000\"=>HOUR0<=REG7_0; WHEN \"0001\"=>HOUR0<=REG7_1; WHEN \"0010\"=>HOUR0<=REG7_2; WHEN \"0011\"=>HOUR0<=REG7_3; WHEN \"0100\"=>HOUR0<=REG7_4; WHEN \"0101\"=>HOUR0<=REG7_5; WHEN \"0110\"=>HOUR0<=REG7_6; WHEN \"0111\"=>HOUR0<=REG7_7; WHEN \"1000\"=>HOUR0<=REG7_8; WHEN \"1001\"=>HOUR0<=REG7_9; WHEN OTHERS=>HOUR0<=REG7_NULL; END CASE; END IF; ELSE HOUR0<=REG7_4; END IF;
END PROCESS;
PROCESS(MINFLASH1,MININ1,EN) BEGIN
IF EN='1' THEN
IF MINFLASH1='1' THEN MIN1<=REG7_NULL; ELSE CASE MININ1 IS WHEN \"0000\"=>MIN1<=REG7_0; WHEN \"0001\"=>MIN1<=REG7_1; WHEN \"0010\"=>MIN1<=REG7_2; WHEN \"0011\"=>MIN1<=REG7_3; WHEN \"0100\"=>MIN1<=REG7_4; WHEN \"0101\"=>MIN1<=REG7_5; WHEN \"0110\"=>MIN1<=REG7_6; WHEN \"0111\"=>MIN1<=REG7_7; WHEN \"1000\"=>MIN1<=REG7_8; WHEN \"1001\"=>MIN1<=REG7_9; WHEN OTHERS=>MIN1<=REG7_NULL; END CASE;
END IF; ELSE MIN1<=REG7_4; END IF;
END PROCESS;
PROCESS(MINFLASH0,MININ0,EN) BEGIN
IF EN='1' THEN
IF MINFLASH0='1' THEN MIN0<=REG7_NULL; ELSE CASE MININ0 IS WHEN \"0000\"=>MIN0<=REG7_0; WHEN \"0001\"=>MIN0<=REG7_1; WHEN \"0010\"=>MIN0<=REG7_2; WHEN \"0011\"=>MIN0<=REG7_3; WHEN \"0100\"=>MIN0<=REG7_4; WHEN \"0101\"=>MIN0<=REG7_5; WHEN \"0110\"=>MIN0<=REG7_6; WHEN \"0111\"=>MIN0<=REG7_7; WHEN \"1000\"=>MIN0<=REG7_8; WHEN \"1001\"=>MIN0<=REG7_9; WHEN OTHERS=>MIN0<=REG7_NULL; END CASE; END IF; ELSE MIN0<=REG7_8; END IF;
END PROCESS;
PROCESS(SECIN1,EN) BEGIN
IF EN='1' THEN CASE SECIN1 IS
WHEN \"0000\"=>SEC1<=REG7_0; WHEN \"0001\"=>SEC1<=REG7_1; WHEN \"0010\"=>SEC1<=REG7_2; WHEN \"0011\"=>SEC1<=REG7_3; WHEN \"0100\"=>SEC1<=REG7_4; WHEN \"0101\"=>SEC1<=REG7_5; WHEN \"0110\"=>SEC1<=REG7_6; WHEN \"0111\"=>SEC1<=REG7_7; WHEN \"1000\"=>SEC1<=REG7_8;
WHEN \"1001\"=>SEC1<=REG7_9;
WHEN OTHERS=> SEC1<=REG7_NULL; END CASE; ELSE SEC1<=REG7_2; END IF;
END PROCESS;
PROCESS(SECIN0,EN) BEGIN
IF EN='1' THEN CASE SECIN0 IS
WHEN \"0000\"=>SEC0<=REG7_0; WHEN \"0001\"=>SEC0<=REG7_1; WHEN \"0010\"=>SEC0<=REG7_2; WHEN \"0011\"=>SEC0<=REG7_3; WHEN \"0100\"=>SEC0<=REG7_4; WHEN \"0101\"=>SEC0<=REG7_5; WHEN \"0110\"=>SEC0<=REG7_6; WHEN \"0111\"=>SEC0<=REG7_7; WHEN \"1000\"=>SEC0<=REG7_8; WHEN \"1001\"=>SEC0<=REG7_9;
WHEN OTHERS=> SEC0<=REG7_NULL; END CASE; ELSE SEC0<=REG7_4; END IF;
END PROCESS;
PROCESS(CLK,FLAG) BEGIN
IF FLAG='1' THEN
IF CLK'EVENT AND CLK='1' THEN LEDX<=NOT LEDX; END IF; ELSE LEDX<='0'; END IF;
END PROCESS; LED<=LEDX;
END ARCHITECTURE;
六、实验版显示 Key0为设置时间 Key1为设置闹钟 Key2为时间加 Key3为移位
Sw0=0显示学号sw0=1数字钟 Sw1=0 为12进制 sw1=1为24进制 Sw2=1 为正常时钟sw2=0为加快的时钟
1.学号显示
2.24进制时间显示
Sw0=0显示学号sw0=1数字钟 Sw2=1 为正常时钟sw2=0为加快的时钟 Sw1=0 为12进制 sw1=1为24进制
3.12进制时间显示
HEX7数码管在下午时为P Key3为移位 Key0为设置时间 Key1为设置闹钟 Key2为时间加
4.24进制设置时间
按下key0进入设置时间状态
设置时间提示灯
设置时间状态下ledg1亮 5设置闹钟
按下key1进入设置闹钟状态
设置闹钟提示灯
设置闹钟状态下ledg2灯亮
6.与闹钟对应的时间
闹钟提示灯
7半点报时,整点报时
整点报时提示灯
半点报时提示灯
七、结论
经过几周EDA实验的学习,使我受益匪浅。这不仅增强了我对EDA设计的兴趣,更掌握了基本的电路设计流程、方法以及技巧。具备了这些基本知识,为今后的自主学习奠定了良好的基础。
同时通过本次课程设计,巩固了我们以前学过的专业知识,通过这次的程序设计,使我们对数字系统结构也有了更进一步的了解与认识,同时对eda技术,vhdl语言等系列知识都有了一定的了解与认识。使用eda技术开发页面的能力也有了提高,也使我们把理论与实践从正真意义上结合了起来,考验了我们的动手能力,查阅相关资料的能力,还有组织材料的能力。通过此次实践,我们从中可以找出自己知识的不足与欠缺,以便我们在日后的学习中得以改进与提高。
经过本次设计使我们对大学四年期间所学习到的知识得以进一步实践,这将对我们走出校园走向社会走向工作岗位奠定坚实的基础。
遇到的问题和改进
此次设计不足之处是不能在12进制的状态下设置时间,只能切换回24进制显示才能设置时间,这是有待改进的地方。
遇到的问题是模块的屏蔽问题:如在设置时间的时候计数器停止,保持原来的数字,解决方法是增加一个控制信号。
因篇幅问题不能全部显示,请点此查看更多更全内容