基于VHDL的数字电子钟系统设计.docx
《基于VHDL的数字电子钟系统设计.docx》由会员分享,可在线阅读,更多相关《基于VHDL的数字电子钟系统设计.docx(35页珍藏版)》请在冰豆网上搜索。
![基于VHDL的数字电子钟系统设计.docx](https://file1.bdocx.com/fileroot1/2023-4/19/4c70e787-7077-4dc4-9a66-dab3593ee701/4c70e787-7077-4dc4-9a66-dab3593ee7011.gif)
基于VHDL的数字电子钟系统设计
集成电路软件设计
基于VHDL的数字电子钟系统设计
学院信息工程学院班级电科
姓名学号
成绩指导老师
2012年12月15日
目录
一、摘要1
二、关键词1
三、引言1
四、设计要求1
五、技术指标1
六、设计思想1
七、设计原理2
八、设计方案2
九、设计各个模块的功能2
十、各个模块的波形仿真结果5
十一、各个电路模块的DV综合的网标和电路模型9
十二、设计结果分析15
十三、论文结论16
十四、参考文献16
十五、附录17
一、摘要:
本设计采用层次化设计方法,自顶向下进行设计。
设计中根据系统的功能要求合理划分出层次,进行分级设计和仿真验证,将较为复杂的数字系统逻辑简化为基本的模型从而降低实现的难度。
突出了其作为硬件描述语言的良好的可读性、可移植性和易理解等优点,并通过ModelSimSE6.1完成综合、仿真。
二、关键词:
ModelsimVHDL硬件描述语言设计数字钟
三、引言:
硬件描述语言HDL(HardwareDescriptionLanguage)是一种用形式化方法来描述数字电路和系统的语言。
目前.电子系统向集成化、大规模和高速度等方向发展,以硬件描述语言和逻辑综合为基础的自顶向下的电路设计方法在业界得到迅猛发展,VHDL在这种形势下显示出了巨大的优势,展望将来VHDL在硬件设计领域的地位将与c语言和c++在软件设计领域的地位一样,在大规模数字系统的设计中,它将逐步取代传统的逻辑状态表和逻辑电路图等硬件描述方法,而成为主要的硬件描述工具。
本文提出了以VHDL语言为手段,设计了多功能数字钟。
其代码具有良好的可读性和易理解性,源程序经Altera公司的ModelSimSE6.1软件完成综合、仿真,
四、设计要求:
1、采用自顶向下的设计思想;
2、使用本学期学习的设计语言VHDL和集成电路设计软件实现;
五、技术指标:
1、设计数字电子钟的基本功能:
年、月、日、时以24小时制显示,月日为阳历显示,起始时间为:
2012年11月26日14:
00;
2、可随时进行时间校对;
3、支持闹铃功能。
六、设计思想:
本课程设计要求我们设计的数字电子钟的基本功能可以年、月、日、时以24小时制显示,月日为阳历显示,起始时间为:
2012年11月26日14:
00,且能可随时进行时间校对和支持闹铃功能,并用采用自顶向下的设计思想,即层次化设计思想并使用例化语句编写,很容易想到分模块设计,将各个模块用顶层模块连接起来,再编写testbench激励信号,然后仿真波形。
在时模块中把初始值设定为14,日模块中初始值设定为26,在月模块中初始值设定为11,在年模块中设定初始值为2012。
可以通过比较的方法设计闹铃及利用“set”控制信号设计时钟校对。
七、设计原理:
本课程设计的主要原理就是利用计数器进行计数。
首先是小时模块利用24进制计数器,由于设计要求,先将计数器的初始值设定为14,然后当时钟信号“clk”的上升沿来临时,计数器开始计数到23后回到0循环计数,与此同时定义一个控制信号给日计数模块。
日模块就由初始值26开始计数到30后回到1循环计数,并再定义一个控制信号给月模块,以此类推,再将各个模块用顶层模块连接起来,就可以实现年、月、日、时计数功能了。
时间校队就用到控制信号“set”,定义一个输入信号,比如时就是“hb”。
当“set=’1’”时,就进行时间设置,其他模块与时模块相同。
当“set=’0’”时就设置完毕,数字就从设置的时间开始计时。
闹铃功能就用另一个控制信号“alarm”,当“alarm=’1’时,就进行闹铃时间设置,其他模块与时模块相同。
当“alarm=’0’时,就设置完毕,并且闹铃时间与数字钟时间进行比较,当各个模块的时间都相等时,“ring”输出1,既闹钟响起。
八、设计方案:
按照设计内容和要求以及所有的设计思路与原理,综合考虑后,采用例化语句方法,设计模块化的结构:
顶层设计实体为electronic_clock(数字钟)模块,其下又分为:
years(年)、month(月)、day(日)、hour(时)、alarm_clock(闹钟)五个模块。
每个模块主要使用VHDL语言输入中常用的进程语句、元件例化语句、if语句以及赋值语句来编写VHDL代码。
九、设计各个模块的功能:
1、Hour计时模块:
begin
process(clk)
begin
if(clk'eventandclk='1')then
if(q=23)then
q<=0;clk1<='1';
elsifq<23thenq<=q+1;clk1<='0';
endif;
endif;
endprocess;
当clk上升沿来临时,hour模块开始从0计数到23,并输出一个控制信号clk1控制day模块,此时clk1=1,并回到0然后循环计数,此时clk1=0。
由于要求初始时间为14,我们可以利用“signalq:
integer:
=14;”赋初始值,这样计数器就会从14开始计数。
2、Day计时模块:
begin
process(clk)
begin
if(clk'eventandclk='1')then
if(q=30)then
q<=1;
clk2<='1';
elsifq<30thenq<=q+1;clk2<='0';
endif;
endif;
endprocess;
当上一个模块的控制信号来临时,day模块开始从1计数到30,并输出一个控制信号clk2控制month模块,此时clk2=1,并回到1然后循环计数,此时clk2=0。
由于要求初始时间为26,我们可以利用“signalq:
integer:
=26;”赋初始值,这样计数器就会从26开始计数。
3、Month计时模块:
begin
process(clk)
begin
if(clk'eventandclk='1')then
if(q=12)then
q<=1;
clk3<='1';
elsifq<12thenq<=q+1;clk3<='0';
endif;
endif;
endprocess;
当上一个模块的控制信号来临时,month模块开始从1计数到12,并输出一个控制信号clk3控制year模块,此时clk3=1,并回到1然后循环计数,此时clk3=0。
由于要求初始时间为11,我们可以利用“signalq:
integer:
=11;”赋初始值,这样计数器就会从11开始计数。
4、Years计时模块:
begin
process(clk)
begin
if(clk'eventandclk='1')then
q<=q+1;
endif;
endprocess;
当上一个模块的控制信号来临时,year模块开始从0计数并一直计数下去,由于要求初始时间为2012,我们可以利用“signalq:
integer:
=2012;”赋初始值,这样计数器就会从2012开始计数。
5、Alarm_clock闹钟比较模块:
entityalarm_clockis
port(h1a:
ininteger;
d1a:
ininteger;
m1a:
ininteger;
y1a:
ininteger;
h2a:
ininteger;
d2a:
ininteger;
m2a:
ininteger;
y2a:
ininteger;
ring:
outstd_logic);
endalarm_clock;
architectureoneofalarm_clockis
begin
process(h2a,d2a,m2a,y2a,h1a,d1a,m1a,y1a)
begin
if(h1a=h2aandd1a=d2aandm1a=m2aandy1a=y2a)thenring<='1';
elsering<='0';
endif;
endprocess;
end;
定义八个输入信号和一个输出信号ring用于当前时间与闹铃时间进行比较,当两者相等时,就输出ring=1,既满足了闹铃功能。
6、Set时间校对模块:
process(set,hs)——这是小时模块的set,其他计时模块与其相同
begin
ifset='1'then
ifhs=0thenqh<=qh;
else
qh<=hs;
endif;
endif;
“hs”即为你要设置的时间,当set=1时就把“hs”上的值赋给“h”,然后“h”就从你设置的时间开始计时,就实现了时间设置功能。
(以上只是各个模块的一小段VHDL程序,详细的程序请看附录。
)
十、各个模块的波形仿真结果:
1、时钟初始值:
初始时间为2012-11-26-14。
2、Hour模块:
3、Day模块:
4、Month模块:
5、Years模块:
6、Set(时间校对)模块:
将校对时间设置为2011-5-17-19,当set=1时,时钟时间就重置了,然后当set=0时,时钟就由你设置的时间开始计时。
(hset-dset-mset-yset分别为设置的时间的时--日--月--年)
7、Alarm_clock(闹钟)模块:
将闹钟时间设置为2012-12-8-7,当时钟的时间走到与闹钟时间相同时,ring输出为1,既闹钟响起。
(halarm-dalarm-malarm-yalarm分别为闹钟时间的时--日--月--年)
8、数字钟计时校对闹钟总模块:
从下图可以很清楚的看出数字钟的计时校对闹钟这些基本功能已经实现。
十一、各个电路模块的DV综合的网标和电路模型:
1、Hour模块:
2、Day模块:
3、Month模块:
4、Years模块:
5、Alarm_clock(闹钟)模块:
6、总模块:
7、Testbench模块:
十二、设计结果分析:
此次数字电子钟设计中,使得数字电子钟具有切换显示年、月、日、时的功能,并且能够根据设置按钮进行相应的设置,也可以设置闹铃。
设计过程中对各个模块进行了功能仿真及总的数字钟仿真都达到了预期效果。
经过查看波形文件验证知,达到了设计所要求的计时功能,闹铃功能和设置功能,完成了设计要求。
十三、论文结论:
作为一名电子科学与技术专业的大三学生,我觉得上集成电路软件应用的收获还是很多的。
《集成电路软件应用》也是电子科学与技术专业基础的一门课,此课程对学生要求也算是有点高、学习难度也是较大的,对本专业也是息息相关的,也是重要的。
通过集成电路软件应用课程设计对课本知识进一步掌握,对以前所学数电知识进一步熟练提高,也为以后上奠定基础。
通过这次设计,进一步加深了对VHDL代码编写的了解,让我对它有了更加浓厚的兴趣,巩固了层次化的设计方法,从设计到模块到具体的编程一步步走下去,最终在先前设计好的框架下完成了设计。
其次,本次设计中我更加深入的掌握了VHDL程序设计语言,了解到很多语法只能用在仿真设计并不能综合成实际的电路。
在设计中我使用了元件例化,程序包,函数,过程等手段综合实现。
程序中我使用了较为标准的格式,提高了代码的可读性。
自顶向下的设计思想在设计数字电子系统时非常实用,可以将较为复杂的问题化简为一个个小问题,这样设计人员的思路会变得很清晰。
为了确保整个系统的正确运行,每个底层的实体在写好之后我都把它们进行了仿真,确保仿真结果正确性。
层次化设计的好处是带给我们很大的灵活性,我们可以单独对某个功能的模块进行修改而不影响其他的模块,便于升级、局部优化和维护。
特别是当每一个子模块编写调试成功时,心里特别的开心。
但是在编写顶层文件的程序时,遇到了不少问题,特别是各元件之间的连接,以及信号的定义,总是有错误,在细心的检查下,终于找出了错误和警告,排除困难后,程序编译就通过了,心里终于舒了一口气。
在波形仿真时,也遇到了一点困难,想要的结果不能在波形上得到正确的显示,在设定testbench后,用modelsim仿真,但是始终看不到时间设置的功能。
后来,在数次的调试之后,才发现问题,原来是每一个模块的process()中没有加人敏感信号导致波形仿真得不到正确的结果,后来经过修改终于成功了。
总的来说,这次设计的数字钟还是成功的,有点小小的成就感,终于觉得平时所学的知识有了实用的价值,达到了理论与实际相结合的目的,不仅学到了不少知识,而且锻炼了自己的能力,自己对以后的路有了更加清楚的认识,同时,对未来有了更多的信心。
十四、参考文献:
1、阎石,数字电子技术基础[M]1北京:
高等教育出版社,2000.
2、潘松,王国栋,VHDL实用教程〔M〕.成都:
电子科技大学出版社,2000.
3、崔建明主编,电工电子EDA仿真技术北京:
高等教育出版社,2004
十五、附录:
各个模块的VHDL代码、底层文件代VHDL码及testbench代码:
1、Hour模块:
libraryieee;
useieee.std_logic_1164.all;
entityhouris
port
(clkh:
instd_logic;
seth:
instd_logic;
alarmh:
instd_logic;
ha:
ininteger;
hs:
ininteger;
qth:
outinteger;
clk1:
outstd_logic;
hx:
outinteger;
hy:
outinteger);
endhour;
architectureshiofhouris
signalqh:
integer:
=14;
begin
process(clkh,seth,hs)
begin
ifseth='1'then
ifhs=0thenqh<=qh;
else
qh<=hs;
endif;
elsif(clkh'eventandclkh='1')then
if(qh=23)then
qh<=0;clk1<='1';
elsifqh<23thenqh<=qh+1;clk1<='0';
endif;
endif;
endprocess;
process(alarmh,ha)
begin
ifalarmh='1'thenhx<=ha;
endif;
endprocess;
qth<=qh;hy<=qh;
endshi;
2、Day模块:
libraryieee;
useieee.std_logic_1164.all;
entitydayis
port
(clkd:
instd_logic;
setd:
instd_logic;
alarmd:
instd_logic;
da:
ininteger;
ds:
ininteger;
qtd:
outinteger;
clk2:
outstd_logic;
dx:
outinteger;
dy:
outinteger);
endday;
architectureriofdayis
signalqd:
integer:
=26;
begin
process(clkd,setd,ds)
begin
ifsetd='1'then
ifds=0thenqd<=qd;
else
qd<=ds;
endif;
elsif(clkd'eventandclkd='1')then
if(qd=30)then
qd<=1;
clk2<='1';
elsifqd<30thenqd<=qd+1;clk2<='0';
endif;
endif;
endprocess;
process(alarmd,da)
begin
ifalarmd='1'thendx<=da;
endif;
endprocess;
qtd<=qd;dy<=qd;
endri;
3、Month模块:
libraryieee;
libraryieee;
useieee.std_logic_1164.all;
entitymonthis
port
(clkm:
instd_logic;
setm:
instd_logic;
alarmm:
instd_logic;
ma:
ininteger;
ms:
ininteger;
qtm:
outinteger;
clk3:
outstd_logic;
mx:
outinteger;
my:
outinteger);
endmonth;
architectureyueofmonthis
signalqm:
integer:
=11;
begin
process(clkm,setm,ms)
begin
ifsetm='1'then
ifms=0thenqm<=qm;
else
qm<=ms;
endif;
elsif(clkm'eventandclkm='1')then
if(qm=12)then
qm<=1;
clk3<='1';
elsifqm<12thenqm<=qm+1;clk3<='0';
endif;
endif;
endprocess;
process(alarmm,ma)
begin
ifalarmm='1'thenmx<=ma;
endif;
endprocess;
qtm<=qm;my<=qm;
endyue;
4、Years模块:
libraryieee;
useieee.std_logic_1164.all;
entityyearis
port
(clky:
instd_logic;
sety:
instd_logic;
alarmy:
instd_logic;
ya:
ininteger;
ys:
ininteger;
qty:
outinteger;
yx:
outinteger;
yy:
outinteger);
endyear;
architecturenianofyearis
signalqy:
integer:
=2012;
begin
process(clky,sety,ys)
begin
ifsety='1'then
ifys=0thenqy<=qy;
else
qy<=ys;
endif;
elsif(clky'eventandclky='1')then
qy<=qy+1;
endif;
endprocess;
process(alarmy,ya)
begin
ifalarmy='1'thenyx<=ya;
endif;
endprocess;
qty<=qy;yy<=qy;
endnian;
5、Alarm_clock(闹钟)模块:
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityalarm_clockis
port(h1a:
ininteger;
d1a:
ininteger;
m1a:
ininteger;
y1a:
ininteger;
h2a:
ininteger;
d2a:
ininteger;
m2a:
ininteger;
y2a:
ininteger;
ring:
outstd_logic);
endalarm_clock;
architectureoneofalarm_clockis
begin
process(h2a,d2a,m2a,y2a,h1a,d1a,m1a,y1a)
begin
if(h1a=h2aandd1a=d2aandm1a=m2aandy1a=y2a)thenring<='1';
elsering<='0';
endif;
endprocess;
end;
6、Electronic_clock顶层模块:
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityelectronic_clockis
port(clk:
instd_logic;
set:
instd_logic;
alarm:
instd_logic;
halarm,hset:
ininteger;
dalarm,dset:
ininteger;
malarm,mset:
ininteger;
yalarm,yset:
ininteger;
h:
outinteger;
d:
outinteger;
m:
outinteger;
y:
outinteger;
ring:
outstd_logic);
endelectronic_clock;
architectureoneofelectronic_clockis
componenthour
port
(clkh:
instd_logic;
seth:
instd_logic;
alarmh:
instd_logic;
ha:
ininteger;
hs:
ininteger;
qth:
outinteger;
clk1:
outstd_logic;
hx:
outinteger;
hy:
outinteger);
endcomponent;
componentday
port
(clkd:
instd_logic;
setd:
instd_logic;
alarmd:
instd_logic;
da:
ininteger;
ds:
ininteger;
qtd:
outinteger;
clk2:
outstd_logic;
dx:
outinteger;
dy:
outinteger);
endcomponent;
componentmonth
port
(clkm:
instd_logic;
setm:
instd_logic;
alarmm