(电子行业企业管理)基于VHDL的数字电子钟系统设计
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
(电子行业企业管理)基于VHDL的数字电子钟系统
设计
集成电路软件设计
基于VHDL的数字电子钟系统设计
学院信息工程学院班级电科1112
姓名闭应明学号2011850057 成绩指导老师卫雅芬
2013 年12 月10 日
目录
一、摘要 (1)
二、关键词 (1)
三、引言 (1)
四、设计要求 (1)
五、技术指标 (1)
六、设计思想 (1)
七、设计原理 (2)
八、设计方案 (2)
九、设计各个模块的功能 (3)
十、各个模块的波形仿真结果 (1)
十一、各个电路模块的DV综合的网标和电路模型 (12)
十二、设计结果分析 (19)
十三、论文结论 (20)
十四、参考文献 (20)
十五、附录 (21)
十六、致谢 (50)
一、摘要:
本设计采用层次化设计方法,自顶向下进行设计。
设计中根据系统的功能要求合理划分出层次,进行分级设计和仿真验证,将较为复杂的数字系统逻辑简化为基本的模型从而降低实现的难度。
突出了其作为硬件描述语言的良好的可读性、可移植性和易理解等优点,并通过ModelSim SE 6.1完成综合、仿真。
二、关键词:
Modelsim VHDL 硬件描述语言设计数字钟
三、引言:
硬件描述语言HDL(Hardware Description Language)是一种用形式化方法来描述数字电路和系统的语言。
目前.电子系统向集成化、大规模和高速度等方向发展,以硬件描述语言和逻辑综合为基础的自顶向下的电路设计方法在业界得到迅猛发展,VHDL在这种形势下显示出了巨大的优势,展望将来VHDL在硬件设计领域的地位将与c语言和c++在软件设计领域的地位一样,在大规模数字系统的设计中,它将逐步取代传统的逻辑状态表和逻辑电路图等硬件描述方法,而成为主要的硬件描述工具。
本文提出了以VHDL语言为手段,设计了多功能数字钟。
其代码具有良好的可读性和易理解性,源程序经Altera公司的ModelSimSE 6.1软件完成综合、仿真,
四、设计要求:
1、采用自顶向下的设计思想;
2、使用本学期学习的设计语言VHDL和集成电路设计软件实现;
3、最终以论文形式提交。
五、技术指标:
1、设计数字电子钟的基本功能有:
年、月、日、时、分、秒,其中,月日为阳历显示,时为24小时制
显示;可随时进行时间校对(60分);
2、闰年提醒(10分)、支持闹铃功能(10分);
3、阳历转阴历与阴历显示(20分)。
备注:用硬件描述语言VHDL设计系统,用Modelsim软件仿真,
用Design compiler软件或Synplify软件综合成电路网表。
六、设计思想:
这次课题论文要求设计显示年月日时分秒、阳历转阴历的数字电子钟,且能可随时进行时间校对和支持闹铃功能以及闰年提醒功能。
本次课题基于VHDL 语言,并用采用自顶向下的设计思想,即层次化设计思想并使用例化语句编写,很容易想到分模块设计,先写second、minute、hour、day、month、year、clock模块,然后将各个模块用顶层模块连接起来,再编写testbench激励信号,然后仿真波形。
可以通过比较的方法设计闹铃及利用“set”控制信号设计时钟校对。
七、设计原理:
本次实验的电子数字钟的设计采用异步计时的方式,即各个时间模块每一个轮回后,输出一个高电平作为紧接下一个的时间模块的时钟信号;校正设置时间是通过set端控制,即如果为高电平时,就把预定好的时间参数(sset、mnset、hset、dset、mset、yset)作为要设置的时间,同时也通过此办法来校正时间
的参数;闹铃时间控制是通过alarm端控制,即作为高电平时,把预定好的时间参数(salarm、mnalarm、halarm、dalarm、malarm、yalarm)作为闹铃的时间参数预制;闹铃功能实现是通过一个比较器,即当前的电子钟时间和预定的时间是否一致,如果一致,闹铃ring输出‘1’,否则为‘0’,同时也可以作为闰年的提醒功能。
按照设计内容和要求以及所有的设计思路与原理,综合考虑后,采用例化语句方法,设计模块化的结构:顶层设计实体为electronic_clock(数字钟)模块,其下又分为:years(年)、month(月)、day(日)、hour(时)、minute(分)、second(秒)、alarm_clock(闹钟)7个模块。
每个模块主要使用VHDL语言输入中常用的进程语句、元件例化语句、if语句以及赋值语句来编写VHDL代码。
八、设计方案
图1
九、设计各个模块的功能:
1.second计时模块:
begin
process(clks,sets,ss)
begin
if sets='1' then
if ss=0 then qs<=qs;
else
qs<=ss;
end if;
elsif(clks'event and clks='1') then
if(qs=59) then
qs<=0;
clk1<='1';
elsif qs<59 then qs<=qs+1; clk1<='0';
end if;
end if;
end process;
当clk上升沿来临时,second模块开始从0计数到59,并输出一个控制信号clk1控制minute模块,此时clk1=1 ,并回到0然后循环计数,此时clk1=0。
当需要设置时间时,即sets=‘1’,则把预定好的初值ss赋给输出信号qs。
2、minute模块
begin
process(clkmn,setmn,mns)
begin
if setmn='1' then
if mns=0 then qmn<=qmn;
else
qmn<=mns;
end if;
elsif(clkmn'event and clkmn='1') then
if(qmn=59) then
qmn<=0;
clk2<='1';
elsif qmn<59 then qmn<=qmn+1; clk2<='0';
end if;
当clk上升沿来临时,minute模块开始从0计数到59,并输出一个控制信号clk1控制minute模块,此时clk1=1 ,并回到0然后循环计数,此时clk1=0。
当需要设置时间时,即setmn=‘1’,则把预定好的初值ss赋给中间信号qmn。
3、Hour计时模块:
begin
process(clk)
begin
if(clk'event and clk='1') then
if(q=23) then
q<=0;clk1<='1';
elsif q<23 then q<=q+1; clk1<='0';
end if;
end if;
end process;
当clk上升沿来临时,hour模块开始从0计数到23,并输出一个控制信号clk1控制day模块,此时clk1=1 ,并回到0然后循环计数,此时clk1=0。
由于要求初始时间为14,我们可以利用“signal q:integer:=14;”赋初始值,这样计数器就会从14开始计数。
4、Day计时模块:
if setd='1' then
if ds=0 then qd<=qd;
else
qd<=ds;
end if;
elsif (clkd'event and clkd='1') then
if ( yearin rem 4 =0) then
if ((monthin=1) or (monthin=3) or (monthin=5) or (monthin=7) or (monthin=8) or (monthin=10) or (monthin=12)) then-------????
if(qd=31) then
qd<=1;
clk2<='1';
elsif qd<31 then
qd<=qd+1; clk2<='0';
end if;
elsif (monthin=2) then
if(qd=29) then
qd<=1;
clk2<='1';
elsif qd<29 then qd<=qd+1; clk2<='0';
end if;
elsif ((monthin=4) or (monthin=6) or (monthin=9) or (monthin=11)) then
if(qd=30) then
qd<=1;
clk2<='1';
elsif qd<30 then qd<=qd+1; clk2<='0';
end if;
end if;
elsif ((monthin=1) or (monthin=3) or (monthin=5) or (monthin=7) or (monthin=8) or (monthin=10) or (monthin=12)) then
if(qd=31) then
qd<=1;
clk2<='1';
elsif qd<31 then qd<=qd+1; clk2<='0';
end if;
elsif monthin=2 then
if(qd=28) then
qd<=1;
clk2<='1';
elsif qd<28 then qd<=qd+1; clk2<='0';
end if;
elsif ((monthin=4) or (monthin=6) or (monthin=9) or (monthin=11)) then if(qd=30) then
qd<=1;
clk2<='1';
elsif qd<30 then qd<=qd+1; clk2<='0';
end if;
end if;
end if;
当上一个模块的时钟信号来临时,如果是闰年,并且是1、3、5、7、8、10、12、月,day模块开始则从1计数到31,而如果是2月,则day模块开始计时从1计数到29,如果其他月份时,则计数从1到30,之后并输出一个控制信号clk2控制month模块,此时clk2=1 ,计数到最大值时都会回到1然后循环计数,此时clk2=0。
如果是非闰年,并且是1、3、5、7、8、10、12、月,day 模块开始则从1计数到31,而如果是2月,则day模块开始计时从1计数到
29,如果其他月份时,则计数从1到30,之后并输出一个控制信号clk2控制month模块,此时clk2=1 ,计数到最大值时都会回到1然后循环计数,此时clk2=0。
如果要设置初值,则令setd=‘1’,然后再设置想要数值ds。
5、Month计时模块:
begin
process(clk)
begin
if(clk'event and clk='1') then
if(q=12) then
q<=1;
clk3<='1';
elsif q<12 then q<=q+1; clk3<='0';
end if;
end if;
end process;
当上一个模块的控制信号来临时,month模块开始从1计数到12,并输出一个控制信号clk3控制year模块,此时clk3=1 ,并回到1然后循环计数,此时clk3=0。
6、Years计时模块:
begin
process(clk)
begin
if(clk'event and clk='1') then
q<=q+1;
end if;
end process;
当上一个模块的控制信号来临时,year模块开始从0计数并一直计数下去,由于要求初始时间为2012,我们可以利用“signal q:integer:=2012;”赋初始值,这样计数器就会从2012开始计数。
7、Alarm_clock闹钟比较模块:
begin
process(s2a,mn2a,h2a,d2a,m2a,y2a,s1a,mn1a,h1a,d1a,m1a,y1a ,run)
begin
if ( run rem 4 =0 ) then ring<='1';
elsif (s1a=s2a and mn1a=mn2a and h1a=h2a and d1a=d2a and m1a=m2a and y1a=y2a) then ring<='1';
else ring<='0';
end if;
end process;
定义13个输入信号和一个输出信号ring用于当前时间与闹铃时间进行比较,如果是闰年信号run就输出ring=1,否则剩余的信号两两相等,则ring=1,既
满足了闹铃功能,也满足了闰年提醒的功能。
8、Set时间校对模块:
process(set,hs) ——这是小时模块的set,其他计时模块与其相同begin
if set='1'then
if hs=0 then qh<=qh ;
else
qh<=hs;
end if;
end if;
“hs”即为你要设置的时间,当set=1时就把“hs”上的值赋给“h”,然后“h”就从你设置的时间开始计时,就实现了时间设置功能。
(以上只是各个模块的一小段VHDL程序,详细的程序请看附录。
)
十、各个模块的波形仿真结果:
1、second模块
图2
图3
2、minute模块
图4
结果分析:预置初值为12,因此由12计数到59,最终回0,波形注释大致和second 模块注释一样。
3、Hour模块:
图5
结果分析:预置初值为8,所以计数从8计数到23,再回0,其中ha表示闹铃预置的时间,其他注释和以上模块的大致相同
4、Day模块:
图6
结果分析:时间预置是2013年(即非闰年),12,初始值为1,因此计数从1计数到31天,如果预置为2月,则计数到28天
图7 此是从总模块拿出来的,可以看到2016年闰年时2月为29天
图8
此模块是从总模块拿出来的,2014年为非闰年时,2月为28天
图9
此模块为2014年非闰年时4月模块是30天
5、Month模块:
图10
结果分析:预置初始时间为12月,因此计数从12之后回1,再从1计数到12,输出clk4的控制年模块的时钟信号
6、Years模块:
图11
结果分析:开始预置时间是2013年,则计数从2013开始
图12
结果分析:设定闹铃的时间为12点30分,如果比较时间相同的话,ring=1,否则为0,
同样如果当年是闰年,ring=1,会提醒。
8、Set (时间校对)模块:
图13
结果分析:
2013年12月1 号 8点30分,当set=1时,
时,时钟就由你设置的时间开始计时。
8、数字钟计时校对闹钟总模块:从下图可以很清楚的看出数字钟的计时校对闹钟这些基本功能已经实现。
图14
图15
结果分析:以上仿真波形可以观察出数字电子钟具有年月日时分秒的功能,具有闹铃设计,闰年提醒,随时设置时间功能
十一、各个电路模块的DV 综合的网标和电路模型:
1、second 模块
图16 2、minute模块
图17 3、Hour模块:
图18
图19 4、Day模块:
图20
图21 5、Month模块:
图22
图23
6、Years模块:
图24
图25
7、Alarm_clock(闹钟)模块:
图26
图27 8、总模块:
图28
图29 9、Testbench模块:
图30
十二、设计结果分析:
此次数字电子钟设计中由图2、图3可以看出,秒可以由0计数到59 ,当重新计数到0时会出现一个进位信号,作为分的时钟信号;由图4可以看出,此波形和秒一致;由图5可以看出,时可以由0计数到23,当重新计数回0时,会出现一个进位信号作为天的时钟信号;由图6、图7、图8、图9可以看出,如果当年为非闰年12月是31天(还有1、3、5、7、8、10为31天,没有截图标出)、2月28天,4月30天(还有2、6、9、11为30天,没有独立截图标出),
而当年是闰年时,与以上不同之处在于2月是29天,当计数到对应月份天数终值后,都会输出一个进位信号作为月的时钟信号;由图11可以看出,月由1计数到12,重新计数回1时会出现一个进位信号作为年模块的时钟信号;由图12
可以看出,年从2013年开始,一直往下计数。
通过把所以模块的综合,最终可以在总模块是看出最终实现具有年月日时分秒的计数时钟,并且实现随时设置时间(只要把set置‘1’,则可以把输入端设置的时间作为开始计时的时间参数),同时还支持闹铃的功能,由图14可以看出,设置的闹铃时间是12:30,当时钟到达12:30后,ring作为闹铃信号置1提醒,同时还支持闰年提醒功能,由图15可以看出,当是闰年时,ring作为闰年的提醒信号置1提醒。
由以上的分析,可以看出此次的数据电子钟设计完成年月日时分秒,随时设置时间,铃声提醒,闰年提醒的功能,所以这次论文设计是成功的。
十三、论文结论:
这次设计,让我遇到了许多的问题,同时也加深了我对集成电路软件应用的了解和掌握,在设计这个程序的过程中,让我最感到困难的是编写好一个程序后,如何修改编译提示的错误,尤其是当我设计day模块时,对应不同年份,不同的月份,需要分多种情况,所以在这设计过程中用到了很多if语句,当编译时总会提示出有错误,后来经过不断编译不断修改提示错误后最终完成了day模块的设计。
刚开始时,我是先从比较熟练的Quartus II入手,当所有的设计模块都编译成功后再进一步运用modelsim进行波形仿真,在开始编写testbench 时,感到有些难度,后来经过翻阅查找多种相关的资料后,最终了解了testbench 编写的方式,最终仿真出了各个模块的波形图。
在使用modelsim的过程中,使我更加深入地了解了其功能的运用,并且掌握其编写激励testbench的方式。
在这整个设计过程中,当每一步的设计提示错误,在通过修改编译正确后,都让我感到一种成就感,让我感到我在这个过程中,我学到了知识,并且学会了应用,
比如进一步加深了对VHDL代码编写的了解,让我对它有了更加浓厚的兴趣,巩固了层次化的设计方法,从设计到模块到具体的编程一步步走下去,最终在先前设计好的框架下完成了设计。
其次,本次设计中我更加深入的掌握了VHDL 程序设计语言,了解到很多语法只能用在仿真设计并不能综合成实际的电路。
在设计中我使用了元件例化,程序包,函数,过程等手段综合实现。
程序中我使用了较为标准的格式,提高了代码的可读性。
自顶向下的设计思想在设计数字电子系统时非常实用,可以将较为复杂的问题化简为一个个小问题,这样设计人员的思路会变得很清晰。
为了确保整个系统的正确运行,每个底层的实体在写好之后我都把它们进行了仿真,确保仿真结果正确性。
层次化设计的好处是带给我们很大的灵活性,我们可以单独对某个功能的模块进行修改而不影响其他的模块,便于升级、局部优化和维护。
直至我最终完成了整个数据电子钟的设计。
从这次设计开始到完成,这整个过程中让我终于觉得平时所学的知识有了实用的价值,达到了理论与实际相结合的目的,不仅学到了不少知识,而且锻炼了自己的能力,自己对以后的路有了更加清楚的认识,同时,对未来有了更多的信心。
十四、参考文献:
1、阎石,数字电子技术基础[M ]1 北京: 高等教育出版社,2000.
2、潘松,王国栋,VHDL实用教程〔M〕.成都:电子科技大学出版社,2000.
3、崔建明主编,电工电子EDA仿真技术北京:高等教育出版社,2004
十五、附录:
各个模块的VHDL代码、底层文件代VHDL码及testbench代码:1、Second 模块
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity second is
port
( clks: in std_logic;
sets: in std_logic;
alarms: in std_logic;
sa: in integer range 0 to 59;--------------闹铃预置时间参数
ss: in integer range 0 to 59;----------------随时设置时间参数
qts: out integer range 0 to 59;--------------输出时间
clk1: out std_logic;
sx: out integer range 0 to 59;----------闹铃制定时间
sy: out integer range 0 to 59) ; -----------输出当前时间(作为与制定闹铃时间比较)
end second;
architecture miao of second is
signal qs:integer range 0 to 60;
begin
process(clks,sets,ss)
begin
if sets='1' then -------调制时间使能信号
if ss=0 then qs<=qs;
else
qs<=ss;
end if;
elsif(clks'event and clks='1') then
if(qs=59) then
qs<=0;
clk1<='1'; ------输出分模块时钟信号
elsif qs<59 then qs<=qs+1; clk1<='0';------秒计数
end if;
end if;
end process;
process(alarms,sa)
begin
if alarms='1' then sx<=sa;
end if;
end process;
qts<=qs; sy<=qs;
end miao;
秒testbench
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity test is
end test;
architecture one of test is
signal clks : std_logic:='1'; signal sets : std_logic:='1'; signal alarms : std_logic:='1'; signal sa : integer :=0; signal ss : integer :=0;
signal qts : integer :=0;
signal clk1 : std_logic;
signal sx : integer :=0;
signal sy : integer :=0;
constant clk_period : time := 1ms;
component second
port(
clks : in std_logic;
sets : in std_logic;
alarms : in std_logic;
sa : in integer range 0 to 59;
ss : in integer range 0 to 59;
qts : out integer range 0 to 59;
clk1 : out std_logic;
sx : out integer range 0 to 59;
sy : out integer range 0 to 59);
end component;
begin
DUT :second port map(clks,sets,alarms,sa,ss,qts,clk1,sx,sy); clk_process :process
begin
clks <= '1';
wait for clk_period/2;
clks <= '0';
wait for clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
sets<='1';
wait for clk_period*10;
sets <= '0';
wait;
alarms<='1';
wait;
sa<=0;
wait;
ss<=0;
wait for clk_period*10;
wait;
end process;
END;
2、Minute模块
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity minute is
port
( clkmn: in std_logic;
setmn: in std_logic;
alarmmn: in std_logic;
mna: in integer range 0 to 59;
mns: in integer range 0 to 59;
qtmn: out integer range 0 to 59;
clk2: out std_logic;
mnx: out integer range 0 to 59 ;
mny: out integer range 0 to 59) ;
end minute;
architecture fen of minute is
signal qmn:integer range 0 to 59;
begin
process(clkmn,setmn,mns)
begin
if setmn='1' then
if mns=0 then qmn<=qmn;
else
qmn<=mns;
end if;
elsif(clkmn'event and clkmn='1') then
if(qmn=59) then
qmn<=0;
clk2<='1';
elsif qmn<59 then qmn<=qmn+1; clk2<='0';
end if;
end if;
end process;
process(alarmmn,mna)
begin
if alarmmn='1' then mnx<=mna;
end if;
end process;
qtmn<=qmn; mny<=qmn;
end fen;
分testbench:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity test is
end test;
architecture one of test is
signal clkmn : std_logic:='0'; signal setmn : std_logic:='0'; signal alarmmn : std_logic:='1'; signal mna : integer :=30; signal mns : integer :=12;
signal qtmn : integer :=0;
signal clk2 : std_logic;
signal mnx : integer :=0;
signal mny : integer :=0;
constant clk_period : time := 1ms;
component minute
port(
clkmn : in std_logic:='1';
setmn : in std_logic:='1';
alarmmn : in std_logic:='1';
mna : in integer:=0;
mns : in integer:=0;
qtmn : out integer:=0;
clk2 : out std_logic;
mnx : out integer:=0;
mny : out integer:=0);
end component;
begin
DUT :minute port map(clkmn,setmn,alarmmn,mna,mns,qtmn,clk2,mnx,mny);
clk_process :process
begin
clkmn <= '1';
wait for clk_period/2; clkmn <= '0';
wait for clk_period/2; end process;
-- Stimulus process
stim_proc: process
begin
setmn<='1';
wait for clk_period*100; setmn <= '0';
wait for clk_period*100; alarmmn<='1';
wait for clk_period*100;
mna<=0;
wait for clk_period*100;
mns<=0;
wait for clk_period*100;
wait;
end process;
END;
3、Hour模块:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity hour is
port
( clkh: in std_logic;
seth: in std_logic;----小时调制时间信号
alarmh: in std_logic;------闹铃调制信号
ha: in integer range 0 to 23;-----预定小时时间
hs: in integer range 0 to 23;预置开始时间
qth: out integer range 0 to 23 ;-----输出当前小时时间
clk3: out std_logic ;----输出作为天模块的时钟信号
hx: out integer range 0 to 23;-----闹铃对比
hy: out integer range 0 to 23) ;-----输出时间对比
end hour;
architecture shi of hour is
signal qh:integer range 0 to 23;
begin
process(clkh,seth,hs)
begin
if seth='1'then ------高电平调制
if hs=0 then qh<=qh ;
else
qh<=hs;
end if;
elsif(clkh'event and clkh='1') then
if(qh=23) then
qh<=0;clk3<='1';
elsif qh<23 then qh<=qh+1; clk3<='0';------小时计数
end if;
end if;
end process;
process(alarmh,ha)
begin
if alarmh='1' then hx<=ha; ------闹铃高电平调制end if;
end process;
qth<=qh; hy<=qh;
end shi;
小时testbench
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity test is
end test;
architecture one of test is
signal clkh : std_logic:='0';
signal seth : std_logic:='0';
signal alarmh : std_logic:='1';
signal ha : integer :=12;
signal hs : integer :=8;
signal qth : integer :=0;
signal clk3 : std_logic;
signal hx : integer :=0;
signal hy : integer :=0;
constant clk_period : time := 1ms;
component hour
port(
clkh : in std_logic:='1';
seth : in std_logic:='1';
alarmh : in std_logic:='1';
ha : in integer:=0;
hs : in integer:=0;
qth : out integer:=0;
clk3 : out std_logic;
hx : out integer:=0;
hy : out integer:=0);
end component;
begin
DUT :hour port map(clkh,seth,alarmh,ha,hs,qth,clk3,hx,hy);
clk_process :process begin
clkh <= '1';
wait for clk_period/2; clkh <= '0';
wait for clk_period/2; end process;
-- Stimulus process
stim_proc: process
begin
seth<='1';
wait for clk_period*100;
wait for clk_period*100; alarmh<='1';
wait for clk_period*100;
ha<=0;
wait for clk_period*100;
hs<=0;
wait for clk_period*100; wait;
end process;
END;
4、Day模块:
library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity day is
port
(
clkd: in std_logic;
setd: in std_logic;
alarmd: in std_logic;
yearin: in integer range 2013 to 2099; -- 作为判断闰年信号,定义最大年份到2099年
monthin:in integer range 1 to 12; ----作为判断月份信号
da: in integer;
ds: in integer;
qtd: out integer;
clk2: out std_logic;
dx: out integer;
dy: out integer) ;
end day;
architecture ri of day is
signal qd:integer:=26;
begin
process(clkd,setd,ds,yearin,monthin)
begin
if setd='1' then
if ds=0 then qd<=qd;
else
qd<=ds;
end if;
elsif (clkd'event and clkd='1') then
if ( yearin rem 4 =0) then -----当前为闰年
if ((monthin=1) or (monthin=3) or (monthin=5) or (monthin=7) or (monthin=8) or (monthin=10) or (monthin=12)) then-------当前为大月31天
if(qd=31) then
qd<=1;
clk2<='1';
elsif qd<31 then
qd<=qd+1; clk2<='0';
end if;
elsif (monthin=2) then -------当前为小月29天
if(qd=29) then
qd<=1;
clk2<='1';
elsif qd<29 then qd<=qd+1; clk2<='0';
end if;
elsif ((monthin=4) or (monthin=6) or (monthin=9) or (monthin=11)) then
if(qd=30) then --------当前为中月30天
qd<=1;
clk2<='1';
elsif qd<30 then qd<=qd+1; clk2<='0';
end if;
end if;
elsif ((monthin=1) or (monthin=3) or (monthin=5) or (monthin=7) or (monthin=8) or (monthin=10) or (monthin=12)) then ------非闰年大月份31天if(qd=31) then
qd<=1;
clk2<='1';
elsif qd<31 then qd<=qd+1; clk2<='0';
end if;
elsif monthin=2 then 非闰年小月28天
if(qd=28) then
qd<=1;
clk2<='1';
elsif qd<28 then qd<=qd+1; clk2<='0';
end if;
elsif ((monthin=4) or (monthin=6) or (monthin=9) or (monthin=11)) then----非闰年中月30天
if(qd=30) then
qd<=1;
clk2<='1';
elsif qd<30 then qd<=qd+1; clk2<='0';
end if;
end if;
end if;
qtd<=qd; dy<=qd;
end process;
process(alarmd,da)
begin
if alarmd='1' then dx<=da;
end if;
end process;
end ri;
天testbench
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;。