EDA实验报告
实验名称:EDA多功能数字时钟设计
学 院:电气学院
姓 名:
班 级:电气 071
指导老师:
EDA多功能数字时钟设计
摘要:本实验中我们运用EDA课程中所学的知识,设计了一个拥有时间校正和闹钟功能的24小时制多功能数字时钟。通过本实验,我们初步了解EDA的设计过程;初步掌握用VHDL语言的设计方法和设计思想;初步熟悉Max+Plus II软件平台的编程和仿真,并通过AEDK-EDA实验板下载模拟实现初步了解了硬件实现的方法。
关键词:数字时钟、VHDL、FPGA、Max+Plus II
一、 设计方案
1.功能描述
本次设计的多功能数字钟具有基本的计时功能和时间校正功能,同时可以进行定时闹铃。计时功能采用24小时计时,显示时、分、秒。其中分钟和秒模块采用60进制实现;小时设计了24进制的计数器.时间校正部分,分为时校时和分校时,分别通过控制时校正按钮和分校正按钮来实现.闹铃部分,先通过模式切换按钮进入闹钟定时,然后通过与时间校正相同的方法来进行闹铃时间的预置,当预置到达时间时,时钟将通过蜂鸣器进行闹铃。
2.硬件使用模块:
EPF10K20TC144-4,模块10(蜂鸣器),模块17(脉冲源),模块21(开关设置),模块22(设置跳接模块), 模块23(键盘显示模块)
3.VHDL 程序设计框图
二、 VHDL源程序
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity clock is
port(clk:in std_logic;----------------------时钟脉冲
clk1:in std_logic;---------------------数码管选通时钟脉冲
md1:in std_logic;----------------------模式选择:0为计时,1为闹钟
md2:in std_logic_vector(1 downto 0);---10为时校正(定时),01为分校正(定时)
speak:out std_logic;-------------------闹钟 0
dout:out std_logic_vector(6 downto 0);--数码管七段码输出
selout:out std_logic_vector(2 downto 0));---数码管选通输出
end clock;
architecture one of clock is
signal sel:std_logic_vector(2 downto 0);--------模6计数信号(数码管选通输入)
signal hou1:std_logic_vector(3 downto 0);-------小时十位
signal hou2:std_logic_vector(3 downto 0);-------小时个位
signal min1:std_logic_vector(3 downto 0);-------分钟十位
signal min2:std_logic_vector(3 downto 0);-------分钟个位
signal seth1:std_logic_vector(3 downto 0);------定时小时十位
signal seth2:std_logic_vector(3 downto 0);------定时小时个位
signal setm1:std_logic_vector(3 downto 0);------定时分钟十位
signal setm2:std_logic_vector(3 downto 0);------定时分钟个位
signal sec1:std_logic_vector(3 downto 0);-------秒十位
signal sec2:std_logic_vector(3 downto 0);-------秒个位
signal h1:std_logic_vector(3 downto 0); ------输出小时十位
signal h2:std_logic_vector(3 downto 0); ------输出小时个位
signal m1:std_logic_vector(3 downto 0); ------输出分钟十位
signal m2:std_logic_vector(3 downto 0); ------输出分钟个位
signal s1:std_logic_vector(3 downto 0); ------输出秒十位
signal s2:std_logic_vector(3 downto 0); ------输出秒个位
-------------------------------------------------
begin
----------------------------------------------模6计数(数码管选通)
choice:process(clk1)
begin
if clk1'event and clk1='1' then
if sel="101" then
sel<="000";
else
sel<=sel+1;
end if;
end if;
end process choice;
selout<=sel;
-----------------------------------------------小时十位
h110:process(clk,hou2,min1,min2,sec1,sec2,md1,md2)
begin
if clk'event and clk='1' then
if (hou1="0010" and hou2="0011")and(min1="0101" and min2="1001") and
(sec1="0101" and sec2="1001") then
hou1<="0000";
elsif hou1="0010"and hou2="0011"and md1='0' and md2="10" then hou1<="0000";
elsif (hou2="1001"and(min1="0101" and min2="1001") and (sec1="0101" and
sec2="1001"))or (hou2="1001"and md1='0' and md2="10") then
hou1<=hou1+1;
end if;
end if;
end process h110;
-----------------------------------------------小时个位
h220:process(clk,min1,min2,sec1,sec2,md1,md2,hou1)
begin
if clk'event and clk='1' then
if (hou1="0010" and hou2="0011")and(min1="0101" and min2="1001") and
(sec1="0101" and sec2="1001") then
hou2<="0000";
elsif hou2="1001"and(min1="0101" and min2="1001") and (sec1="0101" and
sec2="1001") then
hou2<="0000";
elsif (hou2="1001"and md1='0' and md2="10")or (hou1="0010"and hou2="0011"and md1='0' and md2="10") then
hou2<="0000";
elsif ((min1="0101" and min2="1001") and (sec1="0101" and sec2="1001"))or
(md1='0' and md2="10") then
hou2<=hou2+1;
end if;
end if;
end process h220;
-----------------------------------------------分钟十位
m110:process(clk,min2,sec1,sec2,md1,md2)
begin
if clk'event and clk='1' then
if (min1="0101" and min2="1001") and (sec1="0101" and sec2="1001") then
min1<="0000";
elsif min1="0101"and min2="1001"and (md1='0' and md2="01")then
min1<="0000";
elsif (min2="1001"and (sec1="0101" and sec2="1001")) or (min2="1001"and
md1='0' and md2="01")then
min1<=min1+1;
end if;
end if;
end process m110;
----------------------------------------------分钟个位
m220:process(clk,sec1,sec2,md1,md2)
begin
if clk'event and clk='1' then
if min2="1001"and (sec1="0101" and sec2="1001")then
min2<="0000";
elsif min2="1001"and (md1='0' and md2="01")then
min2<="0000";
elsif (sec1="0101" and sec2="1001") or(md1='0' and md2="01")then
min2<=min2+1;
end if;
end if;
end process m220;
---------------------------------------------秒十位
s110:process(clk,sec1,sec2)
begin
if clk'event and clk='1' then
if (sec1="0101" and sec2="1001")then
sec1<="0000";
elsif sec2="1001"then
sec1<=sec1+1;
end if;
end if;
end process s110;
--------------------------------------------秒个位
s220:process(clk,sec2)
begin
if clk'event and clk='1' then
if sec2="1001" then
sec2<="0000";
else sec2<=sec2+1;
end if;
end if;
end process s220;
-------------------------------------------时间设置小时部分
sethour1:process(clk,seth2)
begin
if clk'event and clk='1' then
if seth1="0010"and seth2="0011" then
seth1<="0000";
elsif seth2="1001" then
seth1<=seth1+1;
end if;
end if;
end process sethour1;
-------------------------------------------
sethour2:process(clk,md1,md2,seth1)
begin
if clk'event and clk='1' then
if (seth1="0010"and seth2="0011")or seth2="1001"then
seth2<="0000";
elsif md1='1' and md2="10" then
eth2<=seth2+1;
end if;
end if;
end process sethour2;
-------------------------------------------时间设置分钟部分
setmin1:process(clk,setm1,setm2)
begin
if clk'event and clk='1' then
if setm1="0101"and setm2="1001"then
setm1<="0000";
elsif setm2="1001"then
setm1<=setm1+1;
end if;
end if;
end process setmin1;
----------------------------------------------
setmin2:process(clk,md1,md2,setm2)
begin
if clk'event and clk='1'then
if setm2="1001"then
setm2<="0000";
elsif md1='1' and md2="01"then
setm2<=setm2+1;
end if;
end if;
end process setmin2;
--------------------------------------------闹铃
speaker:process(clk1,hou1,hou2,min1,min2)
begin
if clk1'event and clk1='1'then
if seth1=hou1 and seth2=hou2 and setm1=min1 and setm2=min2 then
if(sec2="0000"or sec2="0010" or sec2="0100" or sec2="0110" or sec2="1000" )then
speak<='1';
else speak<='0';
end if;
end if;
end if;
end process speaker;
-------------------------------------------数码管显示
disp:process(sel,md1,hou1,hou2,min1,min2,sec1,sec2,seth1,seth2,setm1,setm2)
begin
if sel="101" then
case h1 is
when "0000"=>dout<="0111111";
when "0001"=>dout<="0000110";
when "0010"=>dout<="1011011";
when others =>dout<="1000000";
end case;
elsif sel="100" then
case h2 is
when "0000"=>dout<="0111111";
when "0001"=>dout<="0000110";
when "0010"=>dout<="1011011";
when "0011"=>dout<="1001111";
when "0100"=>dout<="1100110";
when "0101"=>dout<="1101101";
when "0110"=>dout<="1111101";
when "0111"=>dout<="0000111";
when "1000"=>dout<="1111111";
when "1001"=>dout<="1101111";
when others=>dout<="1000000";
end case;
elsif sel="011" then
case m1 is
when "0000"=>dout<="0111111";
when "0001"=>dout<="0000110";
when "0010"=>dout<="1011011";
when "0011"=>dout<="1001111";
when "0100"=>dout<="1100110";
when "0101"=>dout<="1101101";
when others=>dout<="1000000";
end case;
elsif sel="010" then
case m2 is
when "0000"=>dout<="0111111";
when "0001"=>dout<="0000110";
when "0010"=>dout<="1011011";
when "0011"=>dout<="1001111";
when "0100"=>dout<="1100110";
when "0101"=>dout<="1101101";
when "0110"=>dout<="1111101";
when "0111"=>dout<="0000111";
when "1000"=>dout<="1111111";
when "1001"=>dout<="1101111";
when others=>dout<="1000000";
end case;
elsif sel="001" then
case s1 is
when "0000"=>dout<="0111111";
when "0001"=>dout<="0000110";
when "0010"=>dout<="1011011";
when "0011"=>dout<="1001111";
when "0100"=>dout<="1100110";
when "0101"=>dout<="1101101";
when others=>dout<="1000000";
end case;
elsif sel="000" then
case s2 is
when "0000"=>dout<="0111111";
when "0001"=>dout<="0000110";
when "0010"=>dout<="1011011";
when "0011"=>dout<="1001111";
when "0100"=>dout<="1100110";
when "0101"=>dout<="1101101";
when "0110"=>dout<="1111101";
when "0111"=>dout<="0000111";
when "1000"=>dout<="1111111";
when "1001"=>dout<="1101111";
when others=>dout<="1000000";
end case;
end if;
if md1='0' then---------------计时时间显示和设置模式
h1<=hou1;h2<=hou2;
m1<=min1;m2<=min2;
s1<=sec1;s2<=sec2;
else -------------闹铃时间显示和设置模式
h1<=seth1;h2<=seth2;
m1<=setm1;m2<=setm2;
s1<="1111";s2<="1111";
end if;
end process disp;
------------------------------------------
end;
三、 仿真结果
我们将上述VHDL程序通过Max+Plus II进行编译仿真,仿真结果符合我们设计所预想的功能。仿真结果见下图。
图1:正常计时(md1=0,时钟模式)
(所指处,sel值为0,选通数码管秒个位,dout七段码输出sec2,即2)
图2:分钟校正(md1=0,时钟模式)
(所指处,sel值为3,选通数码管分钟十位,dout七段码输出min1,即3)
图3:小时校正(md1=0,时钟模式)
(所指处,sel值为4,选通数码管小时个位,dout七段码输出hou2,即8)
图4:分钟定时(md1=1,闹钟模式)
(所指处,sel值为3,选通数码管分钟十位,dout七段码输出setm1,即2)
图5:小时定时(md1=1,闹钟模式)
(所指处,sel值为4,选通数码管小时个位,dout七段码输出seth2,即6)
四、 结论与收获
在整个设计过程中,通过查阅相关资料,我们一步步建立了对EDA设计的理解。通过解决在编程、调试以及仿真过程中的种种问题,也加深了我们对软件设计环境的熟悉程度。
通过仿真,我们也感性地认识到了曾经忽视的问题,比如器件间信号传递的时延以及产生毛刺会对电路功能实现的影响。而最让我们印象深刻的是一点是,在编程当中,虽然某些程序的结构获得的效果以及软件仿真的结果是一致的,但在实际硬件实现是却会有很大的不同。而这一切,都让我们获益良多。