电子日历VHDL程序设计报告1.docx
《电子日历VHDL程序设计报告1.docx》由会员分享,可在线阅读,更多相关《电子日历VHDL程序设计报告1.docx(24页珍藏版)》请在冰豆网上搜索。
电子日历VHDL程序设计报告1
电子设计自动化实训说明书
题目:
电子日历VHDL程序设计报告
系部:
信息与控制工程学院
专业:
电子信息工程
班级:
学生姓名:
学号:
指导教师:
杜德
2010年12月6日
目录
1实训目的1
1.1硬件实训目的:
1
1.2软件实训目的:
1
2实训意义2
3实训内容4
3.1硬件实训内容:
4
3.2软件实训内容:
4
3.2.1功能说明:
4
3.2.2软件设计详细内容:
4
4实训中疑难解答17
5实训心得18
参考文献20
1实训目的
1.1硬件实训目的:
1.熟悉EDA实验箱的基本工作原理。
2.熟悉并掌握EDA实验箱各个模式的功能。
3.提高学生的动手能力。
1.2软件实训目的:
1.熟悉并掌握Max+plus2软件的使用。
2.熟练的使用原理图输入设计方法,VHDL语言编写程序,进一步了解和掌握各个程序语言,提高编程的熟练程度。
3.掌握年、月、日、时、分、秒程序的原理,进而理解万年历的设计原理。
4.拓宽学生知识面,增强工程意识,培养学生的分析和解决实际问题的能力。
5.提高学生的动手能历。
2实训意义
该数字时钟实现了调时、年、月、日、时、分、秒的显示功能,无需接译码器,可直接接八段共阴极数码管,总体结构如下图所示:
第一部分第二部分第三部分
D8(l5)D7(l2)D6D5(l4)D4(l1)D3D2(l3)D1
8个LED数码管为了显示清楚只用了6个数码管,分为3个部分。
采用的是EDA试验箱上的模式7。
软件Max+plus2方面:
在显示程序中,k3控制分屏。
当k3=‘1’时,3部分数码管显示年、月、日;当k3=‘0’时,3部分数码管显示时、分、秒。
万年历正常工作时,D1~D8都不亮。
调时时,秒的变化不需控制,故需调时有年、月、日、时、分5个量。
数码管每部分右边灯亮时,即l5亮、l4亮、l3亮分别控制的是年、月、日的变化;每部分左边亮时,即l2亮、l1亮分别控制的是时、分的变化。
若控制其中一个量变化时,其余4个量均不变,也不向高位进位。
调时、显示、年、月、日、时、分、秒的VHDL语言分别生成各自的模块(Symbol),在顶层文件wannianli中调用这些底层模块——CNT60模块,CNT24模块,tian模块,yue模块,nian模块,tiaoshi模块,xianshi模块,然后链接各个模块,构成所需要的电子日历的原理图。
硬件EDA试验箱方面:
电子日历电路图根据要求采用的是EDA试验箱上的模式7。
对万年历电路图上的引脚在电脑软件Max+plus2进行绑定,然后编译,在进行下载,下载到硬件EDA试验箱上。
在EDA试验箱上就可以观察到上述变化。
引脚绑定如图所示:
3实训内容
3.1硬件实训内容:
在电脑上通过软件Max+plus2对万年历电路图的引脚进行绑定,编译,然后与EDA试验箱连接,把wannianli.sof文件配置通过JTAG口载入FPGA中,选择实验电路模式No.7进行硬件测试。
通过学习,理论上学习了EDA试验箱的原理,对试验箱内部的组件,以及组件之间的链接有了一定的了解,为以后的实训打下了良好的基础。
3.2软件实训内容:
3.2.1功能说明:
(1)显示准确的北京时间(年、月、日、时、分、秒,年号只显示最后两位)
(2)随时可以调校时间即可以控制年、月、日、时、分的变化,可以跳到指定的时间。
3.2.2软件设计详细内容:
(1).秒、分:
秒和分都是从0计数到59,可以用六十进制表示。
CNT60程序如下:
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);
endentity;
architectureoneofCNT60is
signalq1,q2:
std_logic_vector(3downto0);
begin
process(CLK)
begin
ifCLK'eventandCLK='1'then––检测时钟上升沿
q2<=q2+1;––q2开始计数
ifq2=9thenq1<=q1+1;
q2<="0000";
endif;
ifq2=9andq1=5then
q1<="0000";q2<="0000";
cout<='1';––q2=9,q1=5时,q1,q2清零并输出进位信号
elsecout<='0';
endif;
endif;
endprocess;
cq1<=q1;cq2<=q2;
end;
CNT60波形仿真如图:
CNT60模块如图:
(2).时:
时是从0计数到23,可以用二十四进制表示。
CNT24程序如下:
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);
endentity;
architectureoneofCNT24is
signalq1,q2:
std_logic_vector(3downto0);
begin
process(CLK)
begin
ifCLK'eventandCLK='1'then––检测时钟上升沿
q2<=q2+1;––q2开始计数
ifq2=9thenq1<=q1+1;
q2<="0000";
endif;––q2=9时,q1开始计数且q2清零
ifq2=3andq1=2thenq1<="0000";
q2<="0000";
cout<='1';––q2=3,q1=2时,q1,q2清零并输出进位信号
elsecout<='0';
endif;
endif;
endprocess;
cq1<=q1;cq2<=q2;
end;
CNT24波形仿真如图:
CNT24模块如图:
(3).天:
一个月可能有31天或者30天;当该年为闰年,二月有29天,否则二月有28天。
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entitytianis
port(clk:
instd_logic;
pan:
instd_logic_vector(1downto0);
T1,T2:
outstd_logic_vector(3downto0);
cout:
outstd_logic);
endtian;
architectureoneoftianis
signalq1,q2:
std_logic_vector(3downto0);
signalab:
std_logic_vector(1downto0);
begin
process(clk,pan)
begin
ifclk'eventandclk='1'––检测时钟上升沿
thenq1<=q1+1;––q1开始计数
ifq1=9thenq1<="0000";
q2<=q2+1;––q1=9时,q2开始计数且q1清零
endif;
casepanis
when"00"=>
ifq2=3andq1=1thenq2<="0000";q1<="0001";cout<='1';
elsecout<='0';––当pan=“00”时,如果q2=3,q1=1,q2清零,q1从1开始计数,并输出进位信号
endif;
when"01"=>
ifq2=3andq1=0thenq2<="0000";q1<="0001";cout<='1';
elsecout<='0';––当pan=“01”时,如果q2=3,q1=0,q2清零,q1从1开始计数,并输出进位信号
endif;
when"10"=>
ifq2=2andq1=8thenq2<="0000";q1<="0001";cout<='1';
elsecout<='0';––当pan=“10”时,如果q2=2,q1=9,q2清零,q1从1开始计数,并输出进位信号
endif;
when"11"=>
ifq2=2andq1=9thenq2<="0000";q1<="0001";cout<='1';
elsecout<='0';––当pan=“11”时,如果q2=2,q1=8,q2清零,q1从1开始计数,并输出进位信号
endif;
whenothers=>null;
endcase;
endif;
endprocess;
T1<=q1;T2<=q2;
end;
tian程序波形仿真如图:
tian模块如图:
(4).月:
一,三,五,七,八,十,十二月有31;四,六,九,十一月有30天;当该年为闰年,二月有29天,否则二月有28天。
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityyueis
port(clk,run:
instd_logic;
cout:
outstd_logic;
pan:
outstd_logic_vector(1downto0);
Y1,Y2:
outstd_logic_vector(3downto0));
endyue;
architecturebehavofyueis
signalq1,q2:
std_logic_vector(3downto0);
signalq3:
std_logic_vector(7downto0);
begin
process(clk,run)
begin
ifclk'eventandclk='1'then––检测时钟上升沿
q1<=q1+1;––q1开始计数
ifq1=9thenq1<="0000";
q2<=q2+1;
endif;––q1=9时,q2开始计数且q1清零
ifq1=2andq2=1then
q1<="0001";q2<="0000";cout<='1';
elsecout<='0';––q1=2,q2=1时,q2清零,q1从1开始计数并输出进位信号
endif;
q3<=q2&q1;
caseq3is
when"00000001"=>pan<="00";––当q3为1月时pan=“00”可知1月为31天
when"00000010"=>ifrun='1'thenpan<="11";elsepan<="10";
endif;––当q3为2月时,若输入信号run=‘1’为闰年则pan=“11”即2月是29天;否则2月为28天
when"00000011"=>pan<="00";––当q3为3月时pan=“00”可知3月为31天
when"00000100"=>pan<="01";
when"00000101"=>pan<="00";
when"00000110"=>pan<="01";––当q3为6月时pan=“01”可知6月为30天
when"00000111"=>pan<="00";
when"00001000"=>pan<="00";
when"00001001"=>pan<="01";
when"00001010"=>pan<="00";
when"00001011"=>pan<="01";
when"00001100"=>pan<="00";
whenothers=>null;
endcase;
endif;
Y1<=q1;Y2<=q2;
endprocess;
endbehav;
yue程序波形仿真如图:
yue模块如图:
(5).年:
由于年号只显示最后两位,故为0~99,是100进制。
但每四年为一闰年。
故nian程序是二者结合。
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entitynianis
port(clk:
instd_logic;
q1,q2:
outstd_logic_vector(3downto0);
run:
outstd_logic);
endentity;
architectureoneofnianis
signalcq1,cq2:
std_logic_vector(3downto0);
signalq3:
std_logic_vector(3downto0);
begin
PRO1:
process(clk)
begin
ifclk'eventandclk='1'then––检测时钟上升沿
cq1<=cq1+1;––cq1开始计数
ifcq1=9thencq2<=cq2+1;cq1<="0000";
endif;––cq1=9时,cq2开始计数且cq1清零
ifcq1=9andcq2<=9thencq1<="0000";cq2<="0000";
endif;––cq1=9,cq2=1时,cq1,cq2清零
endif;
endprocess;
PRO2:
process(clk)
begin
ifclk'eventandclk='1'then––检测时钟上升沿
q3<=q3+1;––q3开始计数
ifq3=3thenq3<="0000";run<='1';
elserun<='0';
endif;
endif;––q3=3后q3清零且输出信号run=‘1’
endprocess;
q1<=cq1;q2<=cq2;
end;
nian程序波形仿真如图:
nian模快
(6).调时:
调时只需调年、月、日、时、分这5个量,故tiaoshi程序就是一个五选一程序。
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entitytiaoshiis
port(k1,k2:
instd_logic;
m1,m2,m3,m4,m5:
instd_logic;
n1,n2,n3,n4,n5:
outstd_logic;
l1,l2,l3,l4,l5:
outstd_logic);
endentity;
architectureoneoftiaoshiis
signalq:
std_logic_vector(3downto0);
begin
process(k1)
begin
ifk1'eventandk1='1'thenq<=q+1;––检测时钟上升沿,q开始计数
ifq=5thenq<="0000";––q=5后q清零
endif;
endif;
caseqis
when"0000"=>n1<=m1;n2<=m2;n3<=m3;n4<=m4;n5<=m5;l1<='0';l2<='0';l3<='0';l4<='0';l5<='0';––当q=“0000”时,把miao的输出给fen的输入,fen的输出给shi的输入,shi的输出给tian的输入,tian的输出给yue的输入,yue的输出给nian的输入,此时灯全灭,正常走时
when"0001"=>n1<=k2;n2<='0';n3<='0';n4<='0';n5<='0';l1<='1';l2<='0';l3<='0';l4<='0';l5<='0';––当q=“0001”时,控制fen的变化,灯l1亮
when"0010"=>n1<='0';n2<=k2;n3<='0';n4<='0';n5<='0';l1<='0';l2<='1';l3<='0';l4<='0';l5<='0';––当q=“0010”时,控制shi的变化,灯l2亮
when"0011"=>n1<='0';n2<='0';n3<=k2;n4<='0';n5<='0';l1<='0';l2<='0';l3<='1';l4<='0';l5<='0';––当q=“0011”时,控制tian的变化,灯l3亮
when"0100"=>n1<='0';n2<='0';n3<='0';n4<=k2;n5<='0';l1<='0';l2<='0';l3<='0';l4<='1';l5<='0';––当q=“0100”时,控制yue的变化,灯l4亮
when"0101"=>n1<='0';n2<='0';n3<='0';n4<='0';n5<=k2;l1<='0';l2<='0';l3<='0';l4<='0';l5<='1';––当q=“0101”时,控制nian的变化,灯l5亮
whenothers=>NULL;
endcase;
endprocess;
end;
tiaoshi模块如图:
(7).显示
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityxianshiis
port(k3:
instd_logic;
ns,ng,ts,tg,ys,yg,ss,sg,fs,fg,ms,mg:
instd_logic_vector(3downto0);
q1,q2,q4,q5,q7,q8:
outstd_logic_vector(3downto0);
l:
outstd_logic);
endentity;
architectureoneofxianshiis
begin
process(k3)
begin
ifk3='1'then
q8<=ns;q7<=ng;q5<=ys;q4<=yg;q2<=ts;q1<=tg;l<='1';––k3=‘1’时,三部分数码管从左至右分别显示年、月、日,l输出信号为1
elseq8<=ss;q7<=sg;q5<=fs;q4<=fg;q2<=ms;q1<=mg;l<='0';––k3=‘0’时,三部分数码管从左至右分别显示时、分、秒,l输出信号为1
endif;
endprocess;
endone;
xianshi模块如图:
(8)万年历原理图:
由底层文件生成的模块即CNT60模块,CNT24模块,tian模块,yue模块,nian模块,tiaoshi模块,xianshi模块链接构成。
万年历的实体如下:
entitywannianliis
port(clk:
instd_logic;
k1,k2,k3:
instd_logic;
q1,q2,q4,q5,q7,q8:
outstd_logic_vector(3downto0);
l,l1,l2,l3,l4,l5:
outstd_logic);
endentity;
输入信号:
clk是最底层文件秒的时钟信号
k1是tiaoshi程序的时钟信号
k2是控制调时中年、月、日、时分的变化
k3是控制分屏。
输出信号:
q7,q8显示的是年(时)
q4,q5显示的是月(分)
q1,q2显示的是日(秒)
l输出高电平‘1’,q8<=ns;q7<=ng;q5<=ys;q4<=yg;q2<=ts;q1<=tg;
l输出低电平‘0’,q8<=ss;q7<=sg;q5<=fs;q4<=fg;q2<=ms;q1<=mg;
l5输出高电平‘1’,控制的是年的变化
l4输出高电平‘1’,控制的是月的变化
l3输出高电平‘1’,控制的是日的变化
l2输出高电平‘1’,控制的是时的变化
l1输出高电平‘1’,控制的是分的变化
4实训中疑难解答
在EDA实训过程中,刚开始时不知如何着手,就是老师把程序讲的很清楚了,最后还是出现很多错误。
不过幸运的是,我找到解决的方法。
错误:
1.CNT24程序编译无错误,但波形仿真时只有0~13,20~23这几个数。
原因:
CNT24是在CNT60的基础上改的,CNT60程序波形仿真正确,认为CNT24程序也因该正确,但却不曾考虑24进制与60进制的不同。
在日常生活中个位9的后面就是个位0。
CNT60的个位q2=9时,随后清零,但CNT24的个位q2=3,随后清零,但3的后面是4。
因此出现了上述问题。
2.CNT60程序,CNT24程序编译正确,波形仿真也正确,但把CNT60和CNT24组成一个时间程序时,秒位对应的数码管从0~59变化正常,但分、时位所对应的数码管却都为00。
原因:
CNT60程序中第一个59到达后,输出进位信号cout<=1,但之后却未清零,以致cout一直保持高电平,所以cout失去了进位的功能,即秒位不能向高位进位,使分位时位的数码管保持零不变。
3.一,三,五,七,八,十,十二月有31;四,六,九,十一月有30天;当run=‘1’时,即该年为闰年,二月有29天,否则二月有28天。
tian程序比较复杂,由于不细心在编译过程出现了很多errors。
4.在nian程序中,因为只有两个数码管来显示,故年号只显示最后两位,即0~99。
但nian程序还要输出是否为闰年,对这一块不是很明白,不知道咋样编写。
最后在老师的指导下,引入一个中间信号q3,程序如下:
ifclk'eventandclk='1'thenq3<=q3+1;
ifq3<=3thenq3<="0000";run<='1';elserun<='0';。
nian程序编译无错误,但其仿真波形中q1,q2总保持为低电平0,run保持高电平1。
原因:
nian程序中的9,3都是用十进制表示的,若给q赋一个十进制的值,应是q=9,但若给q赋以一个二进制的值,应是q<="1001"。
故nian程序不能计数,也不能判断闰年。
5.在引脚绑定过程中,对万年历整体程序的了解出现了问题。
k3是控制分屏,k2是控制调试。
k3绑定错误,应该与pin-24相连,k2与pin-7相连,k1与pin-143相连。
原因:
没有分析万年历原理图输入信号k1,k2,k3,的功能,k1应是脉冲信号,k2,k3是布尔