您好,欢迎来到好土汽车网。
搜索
您的当前位置:首页基于VHDL万年历的设计

基于VHDL万年历的设计

来源:好土汽车网


※※※※※※※※※ ※※ ※※

EDA课程设计

※ ※

※※※※※※※※※

EDA课程设计报告书

课题名称 姓 名 学 号 院 系 专 业 指导教师

基于VHDL万年历的设计

一、设计任务及要求: 1、在Quartus中编写VHDL程序实现年、月、日、时、分、秒各模块的功能。 2、将各模块在原理图中连接起来实现百年历计时功能。 3、对原理图进行编译仿真,并观察仿真结果看是否能实现万年历的功能效果,如是否可以进位,是否能判断闰年等。 4、对仿真后的原理图进行引脚锁定,并下载到相关器件中去。 指导教师签名: 年 月 日 二、指导教师评语: 指导教师签名: 年 月 日 三、成绩 验收盖章 年 月 日

1

基于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所示:

显示 秒、分、时 日 月 年 调整控制k、k1、k2 图3.1 原理框图

整个万年历由五个部分组成。分别为显示部分,秒、分、时部分,日部分,月部分,年部分和调整控制部分。秒、分、时分别由两个进制的计数器和一个二十四进制的计数器组成。当个计数器达到进位的条件时向下一计数器进位。同样

2

日、月、年也是由不同的计数器组成,当达到所需进位的条件时向下一计数器进位,各计数器在进位的同时分别把各自的结果输出给显示部分进行实时显示。而调整控制部分通过对k设置高低电平对显示部分的显示进行选择。例如当k=0时为选择秒分时部分的显示。此时显示部分输出的结果为秒分时部分各计数器输出的结果;当k=1时选择的是年月日部分的显示,此时显示的结果为年月日个计数器的输出结果。通过k1、k2对输出结果进行调整。当k1为上升沿有效时,通过变量a对各个计时器有选择的进行状态控制,控制计数器是否工作。

4设计流程图

万年历的整体设计流程图如图4.1所示:

开始秒计时分计时K=0时计时K2、k3显示天计时月计时K=1年计时 图4.1 整体设计流程图

开始准备阶段后,个计时器开始计时并把前一计时器输出的进位结果当做后一计时器的时钟触发输入,实现各计时器之间的相互联系。同时设置k的值,当k=0时,控制模块选择对秒分时进行显示;当k=1时,控制模块选择对日月年进行显示。k2、k3为调试控制输入端,当k2为上升沿时,设置k3的电平值,通过引入中间变量a对各个计数器有选择的进行状态控制,控制相应计数器是否工作。具体过程参照相应器件的源程序。

3

5电路原理图

万年历的电路原理图如图5.1所示:

图5.1 电路原理图

控制显示模块将各个计时的输出作为输入信号,并设置k作为控制端,控制相应显示器件对秒分时与日月年之间的选择。同时调时设置模块将各个计时器的进位作为输入信号,并设置k2、k3作为调试的触发边沿和电平参数,控制相应计数器的工作状态。

6 VHDL设计程序与生成的相关器件

6.1 60进制计数器

CNT60CLKCQ1[3..0]CQ2[3..0]COUTinst--程序名称:CNT60.VHD --程序功能:实现六十进制计数 library ieee;

USE IEEE.STD_LOGIC_11.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY CNT60 IS

PORT(CLK:IN STD_LOGIC; --系统时钟信号

4

CQ1,CQ2:OUT STD_LOGIC_VECTOR (3 DOWNTO 0); --计数器高低位输出 COUT:OUT STD_LOGIC); --计数器进位输出 END CNT60;

ARCHITECTURE behav OF CNT60 IS BEGIN PROCESS(CLK)

VARIABLE Q1,Q2: STD_LOGIC_VECTOR (3 DOWNTO 0);

--设置Q1,Q2为中间变量

BEGIN

IF CLK'EVENT AND CLK='1' THEN --当时钟信号为上升沿时,Q1加一 Q1:=Q1+1;

IF Q1>9 THEN Q1:=\"0000\";Q2:=Q2+1; --当Q1大于9时,Q1清零,Q2进位 END IF;

IF Q2=6 AND Q1=0 THEN Q1:=\"0000\";Q2:=\"0000\";COUT<='1';

--当Q2等于6,Q1等于0时,对Q1,Q2清零,并对COUT赋值为1

ELSE COUT<='0'; END IF; END IF;

CQ1<=Q1;CQ2<=Q2; END PROCESS; END;

--将Q1,Q2的结果分别赋值给CQ1,CQ2

6.2 24进制计数器

cnt24CLKCQ1[3..0]CQ2[3..0]COUTinst7--程序名称:cnt24.VHD --程序功能:实现24进制计数 library ieee;

USE IEEE.STD_LOGIC_11.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY cnt24 IS

5

PORT(CLK:IN STD_LOGIC; --系统时钟信号 CQ1,CQ2:OUT STD_LOGIC_VECTOR (3 DOWNTO 0); --计数器高低位输出 COUT:OUT STD_LOGIC); --计数器进位输出 END cnt24;

ARCHITECTURE behav OF cnt24 IS BEGIN PROCESS(CLK)

VARIABLE Q1,Q2: STD_LOGIC_VECTOR (3 DOWNTO 0);

--设置Q1,Q2为中间变量

BEGIN

IF CLK'EVENT AND CLK='1' THEN --当时钟信号为上升沿时,Q1加一 Q1:=Q1+1;

IF Q1>9 THEN Q1:=\"0000\";Q2:=Q2+1; --当Q1大于9时,Q1清零,Q2进位 END IF;

IF Q2=2 AND Q1=4 THEN Q1:=\"0000\";Q2:=\"0000\";COUT<='1'; --当Q2等于2,Q1等于4时,对Q1,Q2清零,并对COUT赋值为1 ELSE COUT<='0'; END IF; END IF;

CQ1<=Q1;CQ2<=Q2; END PROCESS; END;

--将Q1,Q2的结果分别赋值给CQ1,CQ2

6.3 天计数模块

dayclkT1[3..0]abinst6T2[3..0]cout--程序名称:day.VHD --程序功能:实现天计数 Library ieee;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

USE IEEE.STD_LOGIC_11.all;

6

Entity day is

Port( clk : in std_logic; --设置输入时钟信号 a,b : in std_logic; --设置天计数判断中间变量

T1,T2 : out std_logic_vector(3 downto 0); --计数器高低位输出 cout : out std_logic); --计数器进位输出 end day;

Architecture one of day is

signal Q1,Q2: STD_LOGIC_VECTOR(3 DOWNTO 0); signal ab: STD_LOGIC_VECTOR(1 DOWNTO 0);

--设置中间变量Q1,Q2,ab为下面程序服务

Begin

PROCESS(clk,a,b) begin

IF CLK'EVENT AND CLK='1' THEN

Q1<=Q1+1; --当时钟信号为上升沿时Q1加一 IF Q1=9 THEN Q1<=\"0000\";Q2<=Q2+1; --当Q1等于9时对Q1清零,Q2加一 end if; ab<=a&b;

case ab is --case选择语句 when\"00\"=> --当ab=00时 if Q2=3 AND Q1=1 THEN Q2<=\"0000\"; Q1<=\"0001\"; cout<='1'; else cout<='0';

--if语句:当满足Q2等于3,Q1等于1时,对Q2清零,Q1赋值为1,--同时cout赋值为1,否则cout赋值为0

end if;

when\"01\"=> --当ab=01时 if Q2=3 and Q1=0 THEN

Q2<=\"0000\" ;Q1<=\"0001\";cout<='1'; else cout<='0';

7

--if语句:当满足Q2等于3,Q1等于0时,对Q2清零,Q1赋值为1,--同时cout赋值为1,否则cout赋值为0

end if;

when\"10\"=> --当ab=10时 if Q2=2 AND Q1=8 then Q2<=\"0000\" ;Q1<=\"0001\";cout<='1'; else cout<='0';

--if语句:当满足Q2等于2,Q1等于8时,对Q2清零,Q1赋值为1,--同时cout赋值为1,否则cout赋值为0

end if;

when\"11\"=> --当ab=11时 if Q2=2 AND Q1=9 then

Q2<=\"0000\" ;Q1<=\"0001\";cout<='1';

else cout<='0';

--if语句:当满足Q2等于2,Q1等于9时,对Q2清零,Q1赋值为1,--同时cout赋值为1,否则cout赋值为0

end if;

when others =>NULL; end case; END IF;

T1<=Q1; --将Q1的值赋给T1 T2<=Q2; --将Q2的值赋给T2 END PROCESS;

END ARCHITECTURE one;

6.4 月计数模块

yue123CLKrunY1[3..0]Y2[3..0]abCOUTinst1--程序名称:yue123.VHD --程序功能:实现月计数 library ieee;

USE IEEE.STD_LOGIC_11.ALL;

8

USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY yue123 IS

PORT(CLK,run:IN STD_LOGIC; --设置输入时钟信号,判断闰月输入信号

Y1,Y2:OUT STD_LOGIC_VECTOR (3 DOWNTO 0); --计数器高低位输出 a,b:OUT STD_LOGIC; --计数器给前一计数器输入的输出信号 COUT:OUT STD_LOGIC); --计数器进位输出 END yue123;

ARCHITECTURE ONE OF yue123 IS

signal Q2,Q1:STD_LOGIC_VECTOR (3 DOWNTO 0); signal Q2Q1:STD_LOGIC_VECTOR (7 DOWNTO 0); --设置中间变量Q1,Q2和Q1Q2 BEGIN

PROCESS(CLK,run) BEGIN

IF CLK'EVENT AND CLK='1' THEN

Q1<=Q1+1; --当时钟信号为上升沿时,Q1加一

IF Q1=9 THEN Q1<=\"0000\";Q2<=Q2+1; --当Q1等于9时,Q1清零,Q2加一 END IF;

IF Q2=1 AND Q1=2 THEN Q1<=\"0001\";Q2<=\"0000\";COUT<='1';

--当Q2等于1,Q2等于2时,给Q1,Q2分别赋值为1,0,同时COUT赋值为1 ELSE COUT<='0'; END IF; end if; end PROCESS; PROCESS(q2,q1) begin

Q2Q1<=Q2&Q1;

case Q2Q1 is

9

--case语句,当Q1Q2为相应值时,给a,b赋值相应的值,作为前一计数器的 --输入信号

when\"00000001\"=> a<='0';b<='0';

when\"00000010\"=>if run='1'then a<='1';b<='1'; else a<='1';b<='0'; end if; 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'; when others=>null; end case; END PROCESS;

Y1<=Q1;Y2<=Q2; --分别将Q1,Q2赋给Y1,Y2 END ARCHITECTURE ONE;

6.5 年计数模块

nianCLKN1[3..0]N2[3..0]runinst--程序名称:nian.VHD --程序功能:实现年计数 library ieee;

USE IEEE.STD_LOGIC_11.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY nian IS

PORT(CLK:IN STD_LOGIC; --设置输入时钟信号

10

N1,N2:OUT STD_LOGIC_VECTOR (3 DOWNTO 0); --计数器高低位输出 run:OUT STD_LOGIC); --计数器向前一计数器输入的输出信号 END nian;

ARCHITECTURE ABC OF nian IS

signal Q1,Q2,Q3:STD_LOGIC_VECTOR (3 DOWNTO 0); --设置中间变量Q1,Q2,Q3 BEGIN

PROCESS(CLK,Q1,Q2) BEGIN

IF CLK'EVENT AND CLK='1' THEN --当时钟信号为上升沿时,Q1加一,Q3加一 Q1<=Q1+1;Q3<=Q3+1;

IF Q1=9 THEN Q1<=\"0000\";Q2<=Q2+1; --当Q1等于9时,Q1赋值为0.,Q2加一 END IF;

IF Q3=3 THEN Q3<=\"0000\";run<='1'; --当Q3等于3时,Q3赋值为0,run赋值为1 else run<='0'; end if;

IF Q2=9 AND Q1=9 THEN Q1<=\"0000\";Q2<=\"0000\";

--当Q2,Q1等于9时,Q1,Q2分别赋值为0

END IF; end if; end PROCESS;

N1<=Q1;N2<=Q2; --将Q1,Q2的值分别赋值给N1,N2 end;

6.6 秒分时和日月年分组输出控制模块

hn1[3..0]hn2[3..0]st1[3..0]st2[3..0]fy1[3..0]fy2[3..0]l--程序名称:kong.VHD

--程序功能:秒分时和日月年分组输

n1[3..0]n2[3..0]y1[3..0]y2[3..0]h1[3..0]h2[3..0]s1[3..0]s2[3..0]f1[3..0]f2[3..0]t1[3..0]

kongt2[3..0]11

inst2k

--出控制 library ieee;

USE IEEE.STD_LOGIC_11. ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; entity kong is

port(s1,s2,f1,f2,h1,h2,t1,t2,y1,y2,n1,n2:in std_logic_vector(3 downto 0); --各计数器的输入端口

k:in std_logic; --控制信号输入

st1,st2,fy1,fy2,hn1,hn2:out std_logic_vector(3 downto 0); --显示端口输出 l:out std_logic); --秒分时和日月年分组的选择模式输出 end kong;

architecture one of kong is begin process(k)

begin -设置当k为0时,输入输出的相互的对应关系 if k='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;

12

hn2<=n2; l<='0'; end if; end process; end;

6.7 秒分时和日月年分两种模式切换和调整模块

tiaoshimofosoroyok2k3fisiriyinil2l3l4l5l6--程序名称:tiaoshi.VHD

--程序功能:秒分时和日月年分两种模式切换和调整模块 library ieee;

USE IEEE.STD_LOGIC_11. ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; entity tiaoshi is

port(mo,fo,so,ro,yo:in std_logic; --调时模块的输入信号

inst4k2,k3:in std_logic; --调时模块的控制,调时信号输入

fi,si,ri,yi,ni:out std_logic; --各计数器的输入时钟信号 l2,l3,l4,l5,l6:out std_logic); end tiaoshi;

architecture one of tiaoshi is

signal a:std_logic_vector(3 downto 0); begin process(k2,k3) begin

if k3'event and k3='1' then a<=a+1; --当k3为上升沿时,a加一 if a=5 then a<=\"0000\"; end if; end if; case a is

--case语句,当a为相应值时,将k2的值赋值给相应的输入端口,程序运行后将作为对应计数器的时钟信号输入,对该计数器单独计数,进行调时

13

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

l5<='1';l3<='0';l4<='0';l2<='0';l6<='0'; when

l6<='1';l3<='0';l4<='0';l5<='0';l2<='0'; when others=>null; end case; end process; end one;

\"0100\"=>fi<='0';si<='0';ri<='0';yi<=k2;ni<='0';

\"0101\"=>fi<='0';si<='0';ri<='0';yi<='0';ni<=k2;

7仿真波形图

万年历的仿真波形图如图7.1所示:

图7.1仿真波形图

当输入引脚CLK,k分别为时钟脉冲,低电平时,万年历为秒分时部分的显示结果,此时输出结果为st1,st2显示六十进制的秒计数时钟输出;ty1,ty2显

14

示六十进制的分计数时钟输出;hn1,hn2显示二十四进制的小时时钟输出。当输入引脚CLK,k分别为时钟脉冲,高电平时,万年历为年月日的显示结果,此时,输出结果为st1,st2显示天的输出,ty1,ty2为显示月的输出,hn,hn2为显示十二进制的年的输出。

8引脚锁定

由于引脚高于可利用引脚,所以使用芯片EPM7128SQC100-6作为引脚锁定的目标芯片,分别将万年历的引脚锁定在芯片的可利用引脚上。万年历的引脚锁定如图8.1所示:

图8.1 引脚锁定

9设计总结

通过一周的EDA课程设计使我对DEA计数这门课程有了更加深入的了解,知道它是一门需要不断地实践才能真正掌握的课程。这次EDA课程设计不仅使我熟悉万年历的工作原理,工作过程和所需的相关器件,而且增加对EDA编程方法,编程步骤,相应的操作流程和软件操作等的熟悉度。更重要的是使我在设计的过程中积累对数字电路简单系统的实际制作经验,培养设计电路系统的专业素养,也深刻认识到其他相关课程之间的联系对于我们电子信息工程专业的学生重要性。只有认真扎实的学好相应的基础课程才能在以后的学习工作中解决更加复杂困难的问题。

15

参考文献

[1] 汪国强.EDA技术与应用[M].北京:电子工业出版社,2010.4:20-178. [2] 潘松,王国栋,VHDL实用教程[M].成都:电子工业出版社,2000:56-214.

[3] 康华光,邹寿彬,秦臻.电子技术基础数字部分[M].华中科技大学电子技术课程组编,

北京:高等教育出版社,2006.1:18-239.

16

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- howto234.com 版权所有 湘ICP备2022005869号-3

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务