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