课 程 设 计 报 告
设计题目:用VHDL语言实现数字钟的设计
班 级:电子 0901
学 号: XXXXXXXX
姓 名:XXXXXXXXX
指导教师:XXXXXXXXX
设计时间:20##年12月
摘要
现代电子设计技术的核心已转向基于计算机的电子设计自动化技术,即EDA(Electronic Design Automation)技术。EDA技术就是依赖计算机,在EDA工具软件平台上,对以硬件描述语言HDL(Hardware Description Language)为系统逻辑描述手段完成的设计文件,自动地完成逻辑编译、化简、分割、综合、布局布线以及逻辑优化和仿真测试,直至实现既定的电子线路系统功能。EDA技术使得设计者的工作仅限于利用软件的方式,即利用硬件描述语言和EDA软件来完成对系统硬件功能的实现。硬件描述语言是EDA技术的重要组成部分,常见的HDL语言有VHDL、Verilog、HDL、ABLE、AHDL、System Verilog和System C。其中VHDL、Verilog在现在的EDA设计中使用最多,也拥有几乎所有主流EDA工具的支持。VHDL语言具有很强的电路描述和建模能力,能从多个层次对数字系统进行建模和描述,从而大大简化硬件设计任务,提高了设计效率和可靠性。在这次设计中,主要使用VHDL语言输入。此次设计很好地完成了数字钟的定时、切换显示年月日和时分秒的功能,完成了小型FPGA的设计开发,锻炼了动手实践能力,达到了课程设计的目的。
关键词:EDA技术 硬件描述语言 VHDL 设计 数字电子钟
目录
摘要………………………………………………………………………2
1、课程设计目的……………………………………………………………4
2、课程设计内容及要求……………………………………………………4
2.1 设计内容……………………………………………………………4
2.2 设计要求……………………………………………………………4
3、VHDL程序设计…………………………………………………………5
3.1 方案论证……………………………………………………………5
3.2 设计思路与方法……………………………………………………6
3.2.1 设计思路…………………………………………………… 6
3.2.2 设计方法…………………………………………………… 7
4、仿真与分析………………………………………………………………7
5、器件编程下载及设计结果…………………………………………… 9
6、课程设计总结………………………………………………………… 10
7、参考文献……………………………………………………………… 10
8、程序清单……………………………………………………………… 11
8.1 顶层模块………………………………………………………… 11
8.2 秒脉冲模块……………………………………………………… 13
8.3 数码管显示模块………………………………………………… 14
8.4 时分秒模块……………………………………………………… 15
8.4.1 分秒模块……………………………………………………16
8.4.2 小时模块……………………………………………………18
8.5 年月日模块……………………………………………………… 19
8.5.1 日期模块……………………………………………………21
8.5.2 月份模块……………………………………………………24
8.5.3 年份模块……………………………………………………25
1、课程设计目的
EDA技术课程设计在课程结束以后进行,在实践中验证理论知识,不仅是为了巩固课堂上所学知识,更是为了加深我们对EDA技术和VHDL语言的理解;为了让我们自己动手完成从设计输入、逻辑综合、功能仿真、设计实现到实现编程、时序仿真,一直到器件的下载测试的整个过程,真切感受利用EDA技术对FPGA进行设计开发的过程,锻炼和提高我们对器件的编程调试能力。
2、课程设计内容及要求
2.1 设计内容
(1)VHDL程序设计、输入——在ise平台上用VHDL描述系统的功能(建立工程文件,添加VHDL文件,输入源程序);
(2)逻辑综合——将源程序编译调试无误后,为设计系统选择一个电路实现方案,按照这个方案进行逻辑综合和优化,生成1个电路网表文件;
(3)功能仿真——添加波形文件,设计输入,观察输出,检查自己的设计是否达到和完成要求的逻辑功能;
(4)设计实现——布局、布线及配置,最后生成可以写到芯片中的目标文件;
(5)时序仿真——是适配到选定的芯片后进行的仿真,它模拟芯片的实际动作,仿真时间模型严格将门级延时计算在内,可以分析出竞争与冒险,时序仿真验证过的电路与实际电路基本上一致;
(6)器件编程——对器件编程下载目标文件;
(7)测试——验证设计项目在目标系统上的实际工作情况,以便排除不完善的地方,改进设计。
2.2 设计要求
利用VHDL语言在EDA工具软件平台上设计实现一个具有带预置数的数字电子钟,使其具有切换显示年月日、时分秒的功能。显示时,用6个数码管显示时分秒,set(设置)按钮产生第一个脉冲时,显示切换年月日,第2个脉冲到来时可预置年份,第3个脉冲到来时可预置月份,第4,个脉冲到来时可预置日期,依次第5、6、7个脉冲到来时分别可预置、时、分、秒,第 8个脉冲到来后预置结束,数字电子钟正常工作,6个数码管显示的是时分秒。另外,up按钮为高电平时,且此时upclk有脉冲到达时,当前预置位加1;up按钮为低高电平时,且此时upclk有脉冲到达时,当前的预置位减1。还可以在此基础上增加数字电子钟的其它功能。
3、VHDL程序设计
3.1 方案论证
设计中使用的时元件例化和进程结合的方案。每个元件主要采用进程语句实现,在每个进程主要使用了if_else、if_eslif_elsif_----_else 、case以及赋值语句,实现了模块化设计,使得整个程序一目了然。整个电子钟的顶层设计实体为clock(时钟)模块,其下又分为:second_wave(秒脉冲)、shi_fen_miao(时分秒)、nian_yue_ri(年月日)和led_disp(数码管显示)四个模块,数字电子钟结构图如图1所示。其中,时分秒模块下又分为3个小模块——shi(时)、fen(分)和miao(秒),如图2所示;年月日模块分为year(年)、month(月)和date(日期)三个模块,如图3所示。
经过功能仿真和器件下载测试验证知,使用此方案可以简单快速的实现数字电子钟的设计。
图1 数字电子钟顶层实体clock模块结构图
图2 数字电子钟nian_yue_ri(年月日)模块结构图
图3 数字电子钟shi_fen_miao(时分秒)模块结构图
3.2 设计方法
3.2.1 设计思路
课程设计要求我们设计的数字电子钟具有切换显示年月日和时分秒的功能,且能根据set(设置)按钮按动的次数进行相应的切换显示和年月日时分秒的预置,很容易想到led_disp(数码管显示)模块,即对set脉冲进行计数,然后根据计得的数值进行相应的操作——年月日时分秒的计时以及根据up和upclk的变化来进行各个位的设置。可以把年月日、时分秒分别放在一个模块,两个模块再分别划分为年、月、日和时、分、秒模块,各模块间设置进位信号进行连接。
3.2.2 设计方法
按照设计内容和要求以及所有的设计思路,综合考虑后,采用元件例化和进程相结合的方法,设计模块化的结构:顶层设计实体为clock(时钟)模块,其下又分为:second_wave(秒脉冲)、shi_fen_miao(时分秒)、nian_yue_ri(年月日)和led_disp(数码管显示)四个模块。其中,时分秒模块下又分为3个小模块——shi(时)、fen(分)和miao(秒);年月日模块分为year(年)、month(月)和date(日期)三个模块。每个模块主要使用VHDL语言输入中常用的进程语句、元件例化语句、case语句、if语句以及赋值语句。需要注意的是,在年月日模块中的日期模块对于2月份要按照平年闰年的情况分别处理。
4、仿真与分析
图4 顶层模块图clock功能仿真
分析:图4中,set脉冲来之前,显示的是时分秒——23:59:59;第一个set脉冲来之后切换显示年月日——11年01月28号;set第二个脉冲来:设置年份,up先高后低再高,在upclk上升沿来时,年份依次变为11→12→13→12→11→12→13,;set第三个脉冲来:设置月份,up先高后低再高,upclk上升沿来时,年份依次变为01→02→01→12→01→02;等等,以此类推,最后设置成的数字钟显示状态为13年03月29号01点00分01秒,之后在clk时钟输入下开始正常计时显示。
由于程序中增加了1000分频模块,在仿真时间有限的情况下,看不出时分秒计时的增加。为了验证所设计的能正常计时,又分别进行了年月日和时分秒模块的功能仿真。
图5 nian_yue_ri(年月日)模块功能仿真图
分析:初始化的年月日显示为11年01月28号,在lock为0时,即正常显示时,日期按照clk0的输入正常增加,11年01月29号;lock为2时,即set的第2个脉冲来时,设置年份,up先高后低再高,在选择的clk1的上升沿到时,年份变化为:11→12→13→14→13→13→15→16;lock为3时,即set的第3个脉冲来时,设置月份,根据up的变化以及clk1的输入,月份依次变化为:01→02→03→04→03→04→05→06→07→06→05→04→03;以此类推,之后设置日期,最后设置完毕后,年月日为16年03月31号,在clk0上升沿来时,依次为16年04月01号→16年04月2号→16年04月03号。即,年月日模块可以正常计时,能完成加减的预置功能。
图6 shi_fen_miao(时分秒)模块功能仿真
分析同年月日模块。由图可知,时分秒模块也可以正常计时,能完成加减的预置功能。
综合分析图4至图6可知,按所选用方案所设计的电子钟可以完成加减的预置、切换显示和正常计时功能。
5、器件编程下载及设计结果
(一)管脚锁定如图7所示:
图7 管脚锁定图
(二)设计结果分析
此次数字电子钟设计中,使得数字电子钟具有切换显示年月日、时分秒的功能,并且能够根据设置按钮进行相应的设置。设计过程中对clock模块和shi_fen_miao模块以及nian_yue_ri模块进行了功能仿真,达到了预期效果。经过器件编程下载验证知,达到了设计所要求的切换显示和设置功能,完成了设计要求。
6、课程设计总结
实际上,课程设计中尝试了两种设计方案,一种就是现在的元件例化与进程相结合的方法;另一种是多进程的方法,把各功能模块使用进程语句全部包含在一个结构体中,却出现了预料之外的错误——把各个进程拿出来放到新建的文件里调试,显示无误,都放在一起后却总出现代号为415的综合错误,先是在李世平老师的提点下改正了多个进程控制一个输出端的错误,改正之后还是无法综合成功,反复检查多次仍发现无处下手之后决定转为元件例化与进程结合的方案,采用模块化鲜明的设计结构。
由于大多采用的是元件例化语句,只要保证各个模块设计无误,最后顶层设计中对各元件进行位置映射时够细心基本上不出处错误。设计中觉得最难的模块是date模块,因为需考虑闰年和平年的情况下2月的天数,以及大小月的天数,if语句嵌套较多,失之毫厘谬以千里,一个不小心错了一句时设计结果也就无处谈及,所以更需加倍细心的处理各个if语句嵌套。
课程设计中最大的收获是独立自主的完成了设计任务,使得自己有一种成就感,增强了我对利用VHDL语言进行FPGA设计开发的兴趣,更锻炼了我动手调试程序的能力,考验了我在编写程序时的细心和耐心程度。做过课程设计后的建议就是希望学院能把实验设备规整好,让下一届的做课设时不再像我们一样好几个人同时等一个实验箱。
7、参考文献
(1)《可编程逻辑器件与EDA技术》李景华 杜玉远 主编 东北大学出版社
(2)《EDA与VHDL》(第二版) 潘松 黄继业 编著 清华大学出版社
(3)《EDA技术》 刘江海 主编 华中科技大学出版社
(4)《EDA基础与应用》(第1版) 于润伟 编著 机械工业出版社
8、程序清单
8.1 顶层模块:clock
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity clock is
port(clk: in std_logic; --时钟输入
set: in std_logic; --设置按钮
up: in std_logic; --增减控制端
upclk: in std_logic; --预置时钟输入
en: in std_logic;--使能端
clr: in std_logic;--清零端
q5:buffer std_logic_vector(3 downto 0);--输出
q4:buffer std_logic_vector(3 downto 0);
q3:buffer std_logic_vector(3 downto 0);
q2:buffer std_logic_vector(3 downto 0);
q1:buffer std_logic_vector(3 downto 0);
q0:buffer std_logic_vector(3 downto 0));
end clock;
architecture Behav of clock is
component second_wave is --秒脉冲例化
port( clk: in std_logic;
second_wave: buffer std_logic);
end component;
component shi_fen_miao is --时分秒例化
port(clk0: in std_logic;
clk1: in std_logic;
clr: in std_logic;
en: in std_logic;
up: in std_logic;
lock: in std_logic_vector(2 downto 0);
sec0: buffer std_logic_vector(3 downto 0);
sec1: buffer std_logic_vector(3 downto 0);
min0: buffer std_logic_vector(3 downto 0);
min1: buffer std_logic_vector(3 downto 0);
hour0:buffer std_logic_vector(3 downto 0);
hour1:buffer std_logic_vector(3 downto 0);
co: out std_logic);
end component;
component nian_yue_ri is --年月日例化
port(clk0: in std_logic;
clk1: in std_logic;
clr: in std_logic;
en: in std_logic;
up: in std_logic;
lock: in std_logic_vector(2 downto 0);
date0:buffer std_logic_vector(3 downto 0);
date1:buffer std_logic_vector(3 downto 0);
month0:buffer std_logic_vector(3 downto 0);
month1:buffer std_logic_vector(3 downto 0);
year0:buffer std_logic_vector(3 downto 0);
year1:buffer std_logic_vector(3 downto 0));
end component;
component led_disp is --数码管显示例化
Port(lock: in std_logic_vector(2 downto 0);
sec0: in std_logic_vector(3 downto 0);
sec1: in std_logic_vector(3 downto 0);
min0: in std_logic_vector(3 downto 0);
min1: in std_logic_vector(3 downto 0);
hour0:in std_logic_vector(3 downto 0);
hour1:in std_logic_vector(3 downto 0);
date0:in std_logic_vector(3 downto 0);
date1:in std_logic_vector(3 downto 0);
month0:in std_logic_vector(3 downto 0);
month1:in std_logic_vector(3 downto 0);
year0: in std_logic_vector(3 downto 0);
year1: in std_logic_vector(3 downto 0);
q0:buffer std_logic_vector(3 downto 0);
q1:buffer std_logic_vector(3 downto 0);
q2:buffer std_logic_vector(3 downto 0);
q3:buffer std_logic_vector(3 downto 0);
q4:buffer std_logic_vector(3 downto 0);
q5 :buffer std_logic_vector(3 downto 0));
end component;
-------------------------------各个连接信号定义----------------------------------------
signal tlock: std_logic_vector(2 downto 0):="000";--lock赋初值,显示时分秒
signal tsecond_wave:std_logic;
signal tcoday: std_logic;
signal sec0: std_logic_vector(3 downto 0);
signal sec1: std_logic_vector(3 downto 0);
signal min0: std_logic_vector(3 downto 0);
signal min1: std_logic_vector(3 downto 0);
signal hour0: std_logic_vector(3 downto 0);
signal hour1: std_logic_vector(3 downto 0);
signal date0: std_logic_vector(3 downto 0);
signal date1: std_logic_vector(3 downto 0);
signal month0: std_logic_vector(3 downto 0);
signal month1: std_logic_vector(3 downto 0);
signal year0: std_logic_vector(3 downto 0);
signal year1: std_logic_vector(3 downto 0);
begin
process(set)
begin
if(set'event and set='1')then --设置按钮set 脉冲计数
tlock<=tlock+1;
end if;
end process;
----------------------对各元件进行位置映射------------------------
u1:second_wave port map(clk,tsecond_wave);
u2:shi_fen_miao port map(tsecond_wave,upclk,clr,en,up,tlock,
sec0,sec1,min0,min1,hour0,hour1,tcoday);
u3:nian_yue_ri port map(tcoday,upclk,clr,en,up,tlock,date0,
date1,month0,month1,year0,year1);
u4:led_disp port map(tlock,sec0,sec1,min0,min1,hour0,hour1,date0,
date1,month0,month1,year0,year1,q0,q1,q2,q3,q4,q5);
end Behav;
8.2秒脉冲模块second_wave
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity second_wave is
port(clk:in std_logic;
second_wave:buffer std_logic);
end second_wave;
architecture Behavioral of second_wave is
signal cnt:std_logic_vector(8 downto 0);
begin
process(clk,cnt)
begin
if(clk'event and clk='1')then --即对总时钟进行分频
if(cnt="111110011")then
cnt<="000000000";
second_wave<=not second_wave;
else cnt<=cnt+'1';
end if;
end if;
end process;
end Behavioral;
8.3显示模块led_disp:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity led_disp is
Port(lock:in std_logic_vector(2 downto 0);
sec0: in std_logic_vector(3 downto 0);
sec1: in std_logic_vector(3 downto 0);
min0: in std_logic_vector(3 downto 0);
min1: in std_logic_vector(3 downto 0);
hour0:in std_logic_vector(3 downto 0);
hour1:in std_logic_vector(3 downto 0);
date0:in std_logic_vector(3 downto 0);
date1:in std_logic_vector(3 downto 0);
month0:in std_logic_vector(3 downto 0);
month1:in std_logic_vector(3 downto 0);
year0: in std_logic_vector(3 downto 0);
year1: in std_logic_vector(3 downto 0);
q0:buffer std_logic_vector(3 downto 0);
q1:buffer std_logic_vector(3 downto 0);
q2:buffer std_logic_vector(3 downto 0);
q3:buffer std_logic_vector(3 downto 0);
q4:buffer std_logic_vector(3 downto 0);
q5: buffer std_logic_vector(3 downto 0));
end led_disp;
architecture Behavioral of led_disp is
begin
process(lock,sec0,sec1,min0,min1,hour0,hour1,
date0,date1,month0,month1,year0,year1)
begin
if(lock="000")then --计数,显示时分秒
q0<=sec0;q1<=sec1;q2<=min0;q3<=min1;q4<=hour0;q5<=hour1;
end if;
if(lock="001")then --计数,显示年月日
q0<=date0;q1<=date1;q2<=month0;q3<=month1;q4<=year0;q5<=year1;
end if;
if(lock="010")then --预置年份
q0<="1111";q1<="1111";q2<="1111";q3<="1111";q4<=year0;q5<=year1;
end if;
if(lock="011")then --预置月份
q0<="1111";q1<="1111";q2<=month0;q3<=month1;q4<="1111";q5<="1111";
end if;
if(lock="100")then --预置日期
q0<=date0;q1<=date1;q2<="1111";q3<="1111"; q4<="1111";q5<="1111";
end if;
if(lock="101")then --预置小时
q0<="1111";q1<="1111";q2<="1111";q3<="1111";q4<=hour0;q5<=hour1;
end if;
if(lock="110")then --预置分钟
q0<="1111";q1<="1111";q2<=min0;q3<=min1;q4<="1111";q5<="1111";
end if;
if(lock="111")then --预置秒
q0<=sec0;q1<=sec1;q2<="1111";q3<="1111"; q4<="1111";q5<="1111";
end if;
end process;
end Behavioral;
8.4时分秒模块shi_fen_miao
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity shi_fen_miao is
port(clk0:in std_logic;
clk1:in std_logic;
clr: in std_logic;
en: in std_logic;
up: in std_logic;
lock:in std_logic_vector(2 downto 0);
co: out std_logic;
sec0:buffer std_logic_vector(3 downto 0);
sec1:buffer std_logic_vector(3 downto 0);
min0:buffer std_logic_vector(3 downto 0);
min1:buffer std_logic_vector(3 downto 0);
hour0:buffer std_logic_vector(3 downto 0);
hour1:buffer std_logic_vector(3 downto 0));
end shi_fen_miao;
architecture Behavioral of shi_fen_miao is
signal temp1: std_logic;
signal temp2: std_logic;
component fen_miao is
port(clk0: in std_logic;
clk1: in std_logic;
clr: in std_logic;
en: in std_logic;
up: in std_logic;
lock: in std_logic_vector(2 downto 0);
a0: buffer std_logic_vector(3 downto 0);
b0: buffer std_logic_vector(3 downto 0);
co: out std_logic);
end component;
component shi is
port(clk0,clk1,clr,en,up:in std_logic;
lock:in std_logic_vector(2 downto 0);
a1,b1:buffer std_logic_vector(3 downto 0);
co:out std_logic);
end component;
begin
u1:fen_miao port map(clk0,clk1,clr,en,up,lock,sec0,sec1,temp1);
u2:fen_miao port map(temp1,clk1,clr,en,up,lock,min0,min1,temp2);
u3:shi port map(temp2,clk1,clr,en,up,lock,hour0,hour1,co);
end Behavioral;
8.4.1分秒模块fen_miao
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity fen_miao is
Port ( lock: in std_logic_vector(2 downto 0);
clk0: in std_logic;
clk1: in std_logic;
clr: in std_logic;
en: in std_logic;
up: in std_logic;
co : out std_logic;
a0 : buffer std_logic_vector(3 downto 0);
b0 : buffer std_logic_vector(3 downto 0));
end fen_miao;
architecture Behavioral of fen_miao is
signal clk:std_logic;
begin
p0:process(lock,clk0,clk1)
begin
if(lock="000"or lock="001")then
clk<=clk0;
else clk<=clk1;
end if;
end process p0;
p1:process(lock,clr,clk,en)
begin
if(clr='0') then
a0<="1001";b0<="0101";co<='0';
elsif(clk'event and clk='1')then
if en='1'then
if(lock="000")or(lock="001")
or(lock="110"and up='1')
or(lock="111"and up='1')then
if (b0="0101"and a0="1001")then
a0<="0000";b0<="0000";co<='1';
elsif (a0="1001") then
a0<="0000";b0<=b0+'1';co<='0';
else
a0<=a0+'1';co<='0';
end if;
elsif ((lock="111"and up='0')
or(lock="110"and up='1'))then
if(b0="0000"and a0="0000")then
a0<="1001";b0<="0101";
elsif (a0="0000") then
a0<="1001";b0<=b0-'1';co<='0';
else
a0<=a0-'1';co<='0';
end if;
end if;
end if;
end if;
end process p1;
end Behavioral;
8.4.2小时模块shi
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity shi is
Port(clk0:in std_logic;
clk1: in std_logic;
en: in std_logic;
clr: in std_logic;
lock: in std_logic_vector(2 downto 0);
up: in std_logic;
a1 : buffer std_logic_vector(3 downto 0);
b1 : buffer std_logic_vector(3 downto 0);
co : out std_logic);
end shi;
architecture Behavioral of shi is
signal clk:std_logic;
begin
choose_clk:process(lock,clk0,clk1) --时钟选择
begin
if(lock="000"or lock="001")then
clk<=clk0;
else clk<=clk1;
end if;
end process choose_clk;
p1:process(lock,clk,clr,en)
begin
if(clr='0')then
--清零端工作时,小时赋值为23点
b1<="0010";a1<="0011";co<='0';
elsif(clk'event and clk='1')then
if(en='1')then
if(lock="000")or(lock="001")or(lock="101"and up='1')then
--输出显示时分秒、年月日或者进行加的小时设置时
if(a1="0011"and b1="0010")then
--23点时再来一个脉冲则清零,溢出位置1
a1<="0000";b1<="0000";co<='1';
elsif(a1="1001")then
--不是23点时,个位为9时,个位清零;
a1<="0000";b1<=b1+1;co<='0';
--十位加1
else a1<=a1+1;co<='0';--否则小时个位加1
end if;
elsif(lock="101"and up='0')then --减的设置
if(a1="0000"and b1="0000")then
a1<="0011";b1<="0010";
elsif(a1="0000")then
a1<="1001";b1<=b1-1;
else a1<=a1-1;
end if;
end if;
end if;
end if;
end process p1;
end Behavioral;
8.5年月日模块nian_yue_ri
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity nian_yue_ri is
port(clk0: in std_logic;
clk1: in std_logic;
clr: in std_logic;
en: in std_logic;
up: in std_logic;
lock: in std_logic_vector(2 downto 0);
date0:buffer std_logic_vector(3 downto 0);
date1:buffer std_logic_vector(3 downto 0);
month0:buffer std_logic_vector(3 downto 0);
month1:buffer std_logic_vector(3 downto 0);
year0:buffer std_logic_vector(3 downto 0);
year1:buffer std_logic_vector(3 downto 0));
end nian_yue_ri;
architecture Behavioral of nian_yue_ri is
signal temp1,temp2: std_logic;
component date is
port(clk0:in std_logic;
clk1:in std_logic;
clr: in std_logic;
en: in std_logic;
up: in std_logic;
lock:in std_logic_vector(2 downto 0);
month0:in std_logic_vector(3 downto 0);
month1:in std_logic_vector(3 downto 0);
year0:in std_logic_vector(3 downto 0);
year1:in std_logic_vector(3 downto 0);
date0:buffer std_logic_vector(3 downto 0);
date1:buffer std_logic_vector(3 downto 0);
co:out std_logic);
end component;
component month
Port(clk0:in std_logic;
clk1:in std_logic;
clr:in std_logic;
en:in std_logic;
up:in std_logic;
lock:in std_logic_vector(2 downto 0);
a0 : buffer std_logic_vector(3 downto 0);
b0 : buffer std_logic_vector(3 downto 0);
co : out std_logic);
end component;
component year is
Port(clk0:in std_logic;
clk1:in std_logic;
clr: in std_logic;
en: in std_logic;
up: in std_logic;
lock:in std_logic_vector(2 downto 0);
a1: buffer std_logic_vector(3 downto 0);
b1: buffer std_logic_vector(3 downto 0));
end component;
begin
u1:date port map(clk0,clk1,clr,en,up,lock,month0,
month1,year0,year1,date0,date1,temp1);
u2:month12 port map(temp1,clk1,clr,en,up,lock,month0,month1,temp2);
u3:year100 port map(temp2,clk1,clr,en,up,lock,year0,year1);
end Behavioral;
8.5.1日期模块date
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity date is
port(clk0: in std_logic;
clk1: in std_logic;
clr: in std_logic;
en: in std_logic;
up: in std_logic;
lock: in std_logic_vector(2 downto 0);
month0:in std_logic_vector(3 downto 0);
month1:in std_logic_vector(3 downto 0);
year0: in std_logic_vector(3 downto 0);
year1: in std_logic_vector(3 downto 0);
date0:buffer std_logic_vector(3 downto 0);
date1:buffer std_logic_vector(3 downto 0);
co: out std_logic);
end date;
architecture Behavioral of date is
signal clk:std_logic;
signal tempa0:std_logic_vector(1 downto 0);
signal tempa1:std_logic;
begin
tempa0<=year0(1 downto 0);
tempa1<=year1(0);
p0:process(lock,clk0,clk1)
begin
if(lock="000"or lock="001")then
clk<=clk0;
else clk<=clk1;
end if;
end process p0;
p1:process(lock,clk,clr,en)
begin
if(clr='0')then
date0<="1000";date1<="0010";co<='0';
elsif(clk'event and clk='1')then
if(en='1')then
--===***显示时分秒、年月日、加的设置日期***===
if(lock="000")or(lock="001")
or(lock="100"and up='1')then
--**========***2月天数处理***======--
if(month0="0010"and month1="0000")then
if((tempa0="00"and tempa1='0')
or(tempa0="10"and tempa1='1'))then
-------------------闰年情况下-----------
if(date0="1001"and date1="0010")then
--2月29,则日期变为01,日期的溢出位置1
date0<="0001";date1<="0000";co<='1';
elsif (date0="1001")then
--09或19日时,个位置0,十位加1
date0<="0000";date1<=date1+1;co<='0';
else
date0<=date0+1;co<='0';
end if;
else
-------------------------平年情况下------------------
if(date0="1000"and date1="0010")then
date0<="0001";date1<="0000";co<='1';
elsif (date0="1001")then
date0<="0000";date1<=date1+1;co<='0';
else
date0<=date0+1;co<='0';
end if;
end if;
--**================***2月天数处理完毕***===================--
elsif((month0="0001" and month1="0000")
or(month0="0011")or(month0="0101")
or(month0="0111")or(month0="1000")
or(month0="0000"and month1="0001")
or(month0="0010"and month1="0010"))then
if(date0="0001"and date1="0011")then
--1,3,5,7,8,10,12大月31天
date0<="0001";date1<="0000";co<='1';
elsif(date0="1001")then
date0<="0000";date1<=date1+1;co<='0';
else
date0<=date0+1;co<='0';
end if;
else --4,6,9,11小月30天
if(date0="0000"and date1="0011")then
date0<="0001";date1<="0000";co<='1';
elsif(date0="1001")then
date0<="0000";date1<=date1+1;co<='0';
else
date0<=date0+1;co<='0';
end if;
end if;
--end if;
elsif(lock="100"and up='0')then --减的预置日期
if(month0="0010"and month1="0000")then --2月
if((tempa0="00"and tempa1='0')
or(tempa0="10"and tempa1='1'))then
if(date0="0001"and date1="0000")then --闰年
date0<="1001";date1<="0010";
elsif (date0="0000")then
date0<="1001";date1<=date1-1;
else
date0<=date0-1;
end if;
else --平年
if(date0="0001"and date1="0000")then
date0<="1000";date1<="0010";
elsif (date0="0000")then
date0<="1001";date1<=date1-1;
else
date0<=date0-1;
end if;
end if;
elsif((month0="0001" and month1="0000")
or(month0="0011")or(month0="0101")
or(month0="0111")or(month0="1000")
or(month0="0000"and month1="0001")
or(month0="0010"and month1="0010"))then
if(date0="0001"and date1="0000")then
date0<="0001";date1<="0011";
elsif(date0="0000")then
date0<="1001";date1<=date1-1;
else
date0<=date0-1;
end if;
else
if(date0="0001"and date1="0000")then
date0<="0000";date1<="0011";
elsif(date0="0000")then
date0<="1001";date1<=date1-1;
else
date0<=date0-1;
end if;
end if;
end if;
end if;
end if;
end process;
end Behavioral;
8.5.2月份模块month
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity month is
Port(clk0:in std_logic;
clk1:in std_logic;
clr: in std_logic;
en: in std_logic;
up: in std_logic;
lock:in std_logic_vector(2 downto 0);
a0 : buffer std_logic_vector(3 downto 0);
b0 : buffer std_logic_vector(3 downto 0);
co : out std_logic);
end month;
architecture Behavioral of month is
signal clk:std_logic;
begin
process(lock,clk0,clk1)
begin
if(lock="000"or lock="001")then
clk<=clk0;
else clk<=clk1;
end if;
end process;
process(lock,clk,clr,en)
begin
if(clr='0')then
b0<="0000";a0<="0001"; co<='0';
elsif(clk'event and clk='1')then
if(en='1')then
if(lock="000")or(lock="001")
or(lock="011"and up='1')then
if(a0="0010"and b0="0001")then
a0<="0001";b0<="0000";co<='1';
elsif(a0="1001")then
a0<="0000";b0<=b0+1;co<='0';
else
a0<=a0+1;co<='0';
end if;
elsif(lock="011"and up='0')then
if(a0="0001"and b0="0000")then
a0<="0010";b0<="0001";
elsif(a0="0000")then
a0<="1001";b0<=b0-1;
else
a0<=a0-1;
end if;
end if;
end if;
end if;
end process;
end Behavioral;
8.5.3年份模块year
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity year is
Port(clk0:in std_logic;
clk1:in std_logic;
clr: in std_logic;
en: in std_logic;
up : in std_logic;
lock:in std_logic_vector(2 downto 0);
a1 : buffer std_logic_vector(3 downto 0);
b1 : buffer std_logic_vector(3 downto 0));
end year;
architecture Behavioral of year is
signal clk:std_logic;
begin
process(lock,clk0,clk1)
begin
if(lock="000"or lock="001")then
clk<=clk0;
else clk<=clk1;
end if;
end process;
process(lock,clk,clr,en)
begin
if(clr='0')then
b1<="0001";a1<="0001";
elsif(clk'event and clk='1')then
if(en='1')then
if(lock="000")or(lock="001")
or(lock="010"and up='1')then
if(a1="1001"and b1="1001")then --100进制
a1<="0000";b1<="0000";
elsif(a1="1001")then
a1<="0000";b1<=b1+1;
else a1<=a1+1;
end if;
elsif(lock="010"and up='0')then
if(a1="0000"and b1="0000")then
a1<="1001";b1<="1001";
elsif(a1="0000")then
a1<="1001";b1<=b1-1;
else
a1<=a1-1;
end if;
end if;
end if;
end if;
end process;
end Behavioral;