基于VHDL万年历的设计.docx
《基于VHDL万年历的设计.docx》由会员分享,可在线阅读,更多相关《基于VHDL万年历的设计.docx(20页珍藏版)》请在冰豆网上搜索。
![基于VHDL万年历的设计.docx](https://file1.bdocx.com/fileroot1/2023-2/21/65e8c3c1-228f-44e6-8cf0-ec12671d98e5/65e8c3c1-228f-44e6-8cf0-ec12671d98e51.gif)
基于VHDL万年历的设计
EDA课程设计报告书
课题名称
基于VHDL万年历的设计
姓名
学号
院系
专业
指导教师
一、设计任务及要求:
1、在Quartus中编写VHDL程序实现年、月、日、时、分、秒各模块的功能。
2、将各模块在原理图中连接起来实现百年历计时功能。
3、对原理图进行编译仿真,并观察仿真结果看是否能实现万年历的功能效果,如是否可以进位,是否能判断闰年等。
4、对仿真后的原理图进行引脚锁定,并下载到相关器件中去。
指导教师签名:
年月日
二、指导教师评语:
指导教师签名:
年月日
三、成绩
验收盖章
年月日
基于VHDL万年历的设计
1设计目的
1、熟悉万年历的工作原理,工作过程和所需的相关器件。
2、增加对EDA编程方法,编程步骤,相应的操作流程和软件操作等的熟悉度。
3、积累对数字电路简单系统的实际制作经验,为更加复杂的实际应用领域做准备。
4、培养独立设计电路系统的专业素养,带动与其他相关课程之间的相互联系来解决电子信息方面常见的实际问题。
2设计的主要内容和要求
1、在Quartus中编写VHDL程序实现年、月、日、时、分、秒各模块的功能。
2、将各模块在原理图中连接起来实现百年历计时功能。
3、对原理图进行编译仿真,并观察仿真结果看是否能实现万年历的功能效果,如是否可以进位,是否能判断闰年等。
4、对仿真后的原理图进行引脚锁定,并下载到相关器件中去。
3整体设计方案
秒、分是60进制,时是24进制,日31天由月1.3.5.7.8.10.12控制,日28/29由2月和润年控制,日30由月4.6.9.11控制。
原理框图如图3.1所示:
图3.1原理框图
整个万年历由五个部分组成。
分别为显示部分,秒、分、时部分,日部分,月部分,年部分和调整控制部分。
秒、分、时分别由两个进制的计数器和一个二十四进制的计数器组成。
当个计数器达到进位的条件时向下一计数器进位。
同样日、月、年也是由不同的计数器组成,当达到所需进位的条件时向下一计数器进位,各计数器在进位的同时分别把各自的结果输出给显示部分进行实时显示。
而调整控制部分通过对k设置高低电平对显示部分的显示进行选择。
例如当k=0时为选择秒分时部分的显示。
此时显示部分输出的结果为秒分时部分各计数器输出的结果;当k=1时选择的是年月日部分的显示,此时显示的结果为年月日个计数器的输出结果。
通过k1、k2对输出结果进行调整。
当k1为上升沿有效时,通过变量a对各个计时器有选择的进行状态控制,控制计数器是否工作。
4设计流程图
万年历的整体设计流程图如图4.1所示:
图4.1整体设计流程图
开始准备阶段后,个计时器开始计时并把前一计时器输出的进位结果当做后一计时器的时钟触发输入,实现各计时器之间的相互联系。
同时设置k的值,当k=0时,控制模块选择对秒分时进行显示;当k=1时,控制模块选择对日月年进行显示。
k2、k3为调试控制输入端,当k2为上升沿时,设置k3的电平值,通过引入中间变量a对各个计数器有选择的进行状态控制,控制相应计数器是否工作。
具体过程参照相应器件的源程序。
5电路原理图
万年历的电路原理图如图5.1所示:
图5.1电路原理图
控制显示模块将各个计时的输出作为输入信号,并设置k作为控制端,控制相应显示器件对秒分时与日月年之间的选择。
同时调时设置模块将各个计时器的进位作为输入信号,并设置k2、k3作为调试的触发边沿和电平参数,控制相应计数器的工作状态。
6VHDL设计程序与生成的相关器件
6.160进制计数器
--程序名称:
CNT60.VHD
--程序功能:
实现六十进制计数
libraryieee;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYCNT60IS
PORT(CLK:
INSTD_LOGIC;--系统时钟信号
CQ1,CQ2:
OUTSTD_LOGIC_VECTOR(3DOWNTO0);
--计数器高低位输出
COUT:
OUTSTD_LOGIC);--计数器进位输出
ENDCNT60;
ARCHITECTUREbehavOFCNT60IS
BEGIN
PROCESS(CLK)
VARIABLEQ1,Q2:
STD_LOGIC_VECTOR(3DOWNTO0);
--设置Q1,Q2为中间变量
BEGIN
IFCLK'EVENTANDCLK='1'THEN--当时钟信号为上升沿时,Q1加一
Q1:
=Q1+1;
IFQ1>9THENQ1:
="0000";Q2:
=Q2+1;--当Q1大于9时,Q1清零,Q2进位
ENDIF;
IFQ2=6ANDQ1=0THENQ1:
="0000";Q2:
="0000";COUT<='1';
--当Q2等于6,Q1等于0时,对Q1,Q2清零,并对COUT赋值为1
ELSECOUT<='0';
ENDIF;
ENDIF;
CQ1<=Q1;CQ2<=Q2;--将Q1,Q2的结果分别赋值给CQ1,CQ2
ENDPROCESS;
END;
6.224进制计数器
--程序名称:
cnt24.VHD
--程序功能:
实现24进制计数
libraryieee;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYcnt24IS
PORT(CLK:
INSTD_LOGIC;--系统时钟信号
CQ1,CQ2:
OUTSTD_LOGIC_VECTOR(3DOWNTO0);
--计数器高低位输出
COUT:
OUTSTD_LOGIC);--计数器进位输出
ENDcnt24;
ARCHITECTUREbehavOFcnt24IS
BEGIN
PROCESS(CLK)
VARIABLEQ1,Q2:
STD_LOGIC_VECTOR(3DOWNTO0);
--设置Q1,Q2为中间变量
BEGIN
IFCLK'EVENTANDCLK='1'THEN--当时钟信号为上升沿时,Q1加一
Q1:
=Q1+1;
IFQ1>9THENQ1:
="0000";Q2:
=Q2+1;--当Q1大于9时,Q1清零,Q2进位
ENDIF;
IFQ2=2ANDQ1=4THENQ1:
="0000";Q2:
="0000";COUT<='1';
--当Q2等于2,Q1等于4时,对Q1,Q2清零,并对COUT赋值为1
ELSECOUT<='0';
ENDIF;
ENDIF;
CQ1<=Q1;CQ2<=Q2;--将Q1,Q2的结果分别赋值给CQ1,CQ2
ENDPROCESS;
END;
6.3天计数模块
--程序名称:
day.VHD
--程序功能:
实现天计数
Libraryieee;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
USEIEEE.STD_LOGIC_1164.all;
Entitydayis
Port(clk:
instd_logic;--设置输入时钟信号
a,b:
instd_logic;--设置天计数判断中间变量
T1,T2:
outstd_logic_vector(3downto0);--计数器高低位输出
cout:
outstd_logic);--计数器进位输出
endday;
Architectureoneofdayis
signalQ1,Q2:
STD_LOGIC_VECTOR(3DOWNTO0);
signalab:
STD_LOGIC_VECTOR(1DOWNTO0);
--设置中间变量Q1,Q2,ab为下面程序服务
Begin
PROCESS(clk,a,b)
begin
IFCLK'EVENTANDCLK='1'THEN
Q1<=Q1+1;--当时钟信号为上升沿时Q1加一
IFQ1=9THENQ1<="0000";Q2<=Q2+1;--当Q1等于9时对Q1清零,Q2加一
endif;
ab<=a&b;
caseabis--case选择语句
when"00"=>--当ab=00时
ifQ2=3ANDQ1=1THEN
Q2<="0000";Q1<="0001";cout<='1';
elsecout<='0';
--if语句:
当满足Q2等于3,Q1等于1时,对Q2清零,Q1赋值为1,--同时cout赋值为1,否则cout赋值为0
endif;
when"01"=>--当ab=01时
ifQ2=3andQ1=0THEN
Q2<="0000";Q1<="0001";cout<='1';
elsecout<='0';
--if语句:
当满足Q2等于3,Q1等于0时,对Q2清零,Q1赋值为1,--同时cout赋值为1,否则cout赋值为0
endif;
when"10"=>--当ab=10时
ifQ2=2ANDQ1=8then
Q2<="0000";Q1<="0001";cout<='1';
elsecout<='0';
--if语句:
当满足Q2等于2,Q1等于8时,对Q2清零,Q1赋值为1,--同时cout赋值为1,否则cout赋值为0
endif;
when"11"=>--当ab=11时
ifQ2=2ANDQ1=9then
Q2<="0000";Q1<="0001";cout<='1';
elsecout<='0';
--if语句:
当满足Q2等于2,Q1等于9时,对Q2清零,Q1赋值为1,--同时cout赋值为1,否则cout赋值为0
endif;
whenothers=>NULL;
endcase;
ENDIF;
T1<=Q1;--将Q1的值赋给T1
T2<=Q2;--将Q2的值赋给T2
ENDPROCESS;
ENDARCHITECTUREone;
6.4月计数模块
--程序名称:
yue123.VHD
--程序功能:
实现月计数
libraryieee;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYyue123IS
PORT(CLK,run:
INSTD_LOGIC;
--设置输入时钟信号,判断闰月输入信号
Y1,Y2:
OUTSTD_LOGIC_VECTOR(3DOWNTO0);--计数器高低位输出
a,b:
OUTSTD_LOGIC;--计数器给前一计数器输入的输出信号
COUT:
OUTSTD_LOGIC);--计数器进位输出
ENDyue123;
ARCHITECTUREONEOFyue123IS
signalQ2,Q1:
STD_LOGIC_VECTOR(3DOWNTO0);
signalQ2Q1:
STD_LOGIC_VECTOR(7DOWNTO0);
--设置中间变量Q1,Q2和Q1Q2
BEGIN
PROCESS(CLK,run)
BEGIN
IFCLK'EVENTANDCLK='1'THEN
Q1<=Q1+1;--当时钟信号为上升沿时,Q1加一
IFQ1=9THENQ1<="0000";Q2<=Q2+1;--当Q1等于9时,Q1清零,Q2加一
ENDIF;
IFQ2=1ANDQ1=2THENQ1<="0001";Q2<="0000";COUT<='1';
--当Q2等于1,Q2等于2时,给Q1,Q2分别赋值为1,0,同时COUT赋值为1
ELSECOUT<='0';
ENDIF;
endif;
endPROCESS;
PROCESS(q2,q1)
begin
Q2Q1<=Q2&Q1;
caseQ2Q1is
--case语句,当Q1Q2为相应值时,给a,b赋值相应的值,作为前一计数器的
--输入信号
when"00000001"=>a<='0';b<='0';
when"00000010"=>ifrun='1'thena<='1';b<='1';
elsea<='1';b<='0';
endif;
when"00000011"=>a<='0';b<='0';
when"00000100"=>a<='0';b<='1';
when"00000101"=>a<='0';b<='0';
when"00000110"=>a<='0';b<='1';
when"00000111"=>a<='0';b<='0';
when"00001000"=>a<='0';b<='0';
when"00001001"=>a<='0';b<='1';
when"00010000"=>a<='0';b<='0';
when"00010001"=>a<='0';b<='1';
when"00010010"=>a<='0';b<='0';
whenothers=>null;
endcase;
ENDPROCESS;
Y1<=Q1;Y2<=Q2;--分别将Q1,Q2赋给Y1,Y2
ENDARCHITECTUREONE;
6.5年计数模块
--程序名称:
nian.VHD
--程序功能:
实现年计数
libraryieee;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYnianIS
PORT(CLK:
INSTD_LOGIC;--设置输入时钟信号
N1,N2:
OUTSTD_LOGIC_VECTOR(3DOWNTO0);--计数器高低位输出
run:
OUTSTD_LOGIC);--计数器向前一计数器输入的输出信号
ENDnian;
ARCHITECTUREABCOFnianIS
signalQ1,Q2,Q3:
STD_LOGIC_VECTOR(3DOWNTO0);
--设置中间变量Q1,Q2,Q3
BEGIN
PROCESS(CLK,Q1,Q2)
BEGIN
IFCLK'EVENTANDCLK='1'THEN
--当时钟信号为上升沿时,Q1加一,Q3加一
Q1<=Q1+1;Q3<=Q3+1;
IFQ1=9THENQ1<="0000";Q2<=Q2+1;
--当Q1等于9时,Q1赋值为0.,Q2加一
ENDIF;
IFQ3=3THENQ3<="0000";run<='1';
--当Q3等于3时,Q3赋值为0,run赋值为1
elserun<='0';
endif;
IFQ2=9ANDQ1=9THENQ1<="0000";Q2<="0000";
--当Q2,Q1等于9时,Q1,Q2分别赋值为0
ENDIF;
endif;
endPROCESS;
N1<=Q1;N2<=Q2;--将Q1,Q2的值分别赋值给N1,N2
end;
6.6秒分时和日月年分组输出控制模块
--程序名称:
kong.VHD
--程序功能:
秒分时和日月年分组输
--出控制
libraryieee;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
entitykongis
port(s1,s2,f1,f2,h1,h2,t1,t2,y1,y2,n1,n2:
instd_logic_vector(3downto0);
--各计数器的输入端口
k:
instd_logic;--控制信号输入
st1,st2,fy1,fy2,hn1,hn2:
outstd_logic_vector(3downto0);--显示端口输出
l:
outstd_logic);--秒分时和日月年分组的选择模式输出
endkong;
architectureoneofkongis
begin
process(k)
begin-设置当k为0时,输入输出的相互的对应关系
ifk='0'then
st1<=s1;
st2<=s2;
fy1<=f1;
fy2<=f2;
hn1<=h1;
hn2<=h2;
l<='1';
else
st1<=t1;
st2<=t2;
fy1<=y1;
fy2<=y2;
hn1<=n1;
hn2<=n2;
l<='0';
endif;
endprocess;
end;
6.7秒分时和日月年分两种模式切换和调整模块
--程序名称:
tiaoshi.VHD
--程序功能:
秒分时和日月年分两种模式切换和调整模块
libraryieee;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
entitytiaoshiis
port(mo,fo,so,ro,yo:
instd_logic;--调时模块的输入信号
k2,k3:
instd_logic;--调时模块的控制,调时信号输入
fi,si,ri,yi,ni:
outstd_logic;--各计数器的输入时钟信号
l2,l3,l4,l5,l6:
outstd_logic);
endtiaoshi;
architectureoneoftiaoshiis
signala:
std_logic_vector(3downto0);
begin
process(k2,k3)
begin
ifk3'eventandk3='1'thena<=a+1;--当k3为上升沿时,a加一
ifa=5thena<="0000";
endif;
endif;
caseais
--case语句,当a为相应值时,将k2的值赋值给相应的输入端口,程序运行后将作为对应计数器的时钟信号输入,对该计数器单独计数,进行调时
when"0000"=>fi<=mo;si<=fo;ri<=so;yi<=ro;ni<=yo;l2<='0';l3<='0';l4<='0';l5<='0';l6<='0';
when"0001"=>fi<=k2;si<='0';ri<='0';yi<='0';ni<='0';l2<='1';l3<='0';l4<='0';l5<='0';l6<='0';
when"0010"=>fi<='0';si<=k2;ri<='0';yi<='0';ni<='0';l3<='1';l2<='0';l4<='0';l5<='0';l6<='0';
when"0011"=>fi<='0';si<='0';ri<=k2;yi<='0';ni<='0';l4<='1';l3<='0';l2<='0';l5<='0';l6<='0';
when"0100"=>fi<='0';si<='0';ri<='0';yi<=k2;ni<='0';l5<='1';l3<='0';l4<='0';l2<='0';l6<='0';
when"0101"=>fi<='0';si<='0';ri<='0';yi<='0';ni<=k2;l6<='1';l3<='0';l4<='0';l5<='0';l2<='0';
whenothers=>null;
endcase;
endprocess;
endone;
7仿真波形图
万年历的仿真波形图如图7.1所示:
图7.1仿真波形图
当输入引脚CLK,k分别为时钟脉冲,低电平时,万年历为秒分时部分的显示结果,此时输出结果为st1,st2显示六十进制的秒计数时钟输出;ty1,ty2显示六十进制的分计数时钟输出;hn1,hn2显示二十四进制的小时时钟输出。
当输入引脚CLK,k分别为时钟脉冲,高电平时,万年历为年月日的显示结果,此时,输出结果为st1,st2显示天的输出,ty1,ty2为显示月的输出,hn,hn2为显示十二进制的年的输出。
8引脚锁定
由于引脚高于可利用引脚,所以使用芯片EPM7128SQC100-6作为引脚锁定的目标芯片,分别将万年历的引脚锁定在芯片的可利用引脚上。
万年历的引脚锁定如图8.1所示:
图8.1引脚锁定
9设计总结
通过一周的EDA课程设计使我对DEA计数这门课程有了更加深入的了解,知道它是一门需要不断地实践才能真正掌握的课程。
这次EDA课程设计不仅使我熟悉万年历的工作原理,工作过程和所需的相关器件,而且增加对EDA编程方法,编程步骤,相应的操作流程和软件操作等的熟悉度。
更重要的是使我在设计的过程中积累对数字电路简单系统的实际制作经验,培养独立设计电路系统的专业素养,也深刻认识到其他相关课程之间的联系对于我们电子信息工程专业的学生重要性。
只有认真扎实的学好相应的基础课程才能在以后的学习工作中解决更加复杂困难的问题。
参考文献
[1]汪国强.EDA技术与应用[M].北京:
电子工业出版社,2010.4:
20-178.
[2]潘松,王国栋,VHDL实用教程[M].成都:
电子工业出版社,2000:
56-214.
[3]康华光,邹寿彬,秦臻.电子技术基础数字部分[M].华中科技大学电子技术课程组编,北京:
高等教育出版社,2006.1:
18-239.