数字时钟的综合设计
一、设计任务
1、具有时、分、秒计时显示功能,最大计时为23:59:59。
2、用CPLD/FPGA设计制作成数字时钟的专用芯片,结合LED数码管构成一个能够实现调时和调分的数字时钟。
二、总体设计框图
三、模块设计具体化
1、设计思想
本设计是基于Altera公司的CycloneⅡ系列EP2C35F672C芯片,
采用层次化设计方式,先设计底层的器件如秒计数器、分计数器、时计数器、2选1选择器、译码器,顶层设计采用原理图形式,将底层各个器件连接起来组合成一个数字时钟专用芯片。
2、VHDL程序代码
a、秒计数器程序
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity second is
port( clk: in std_logic;
enmin : out std_logic;
daout : out std_logic_vector(6 downto 0));
end second;
Architecture behave of second is
signal count: std_logic_vector(6 downto 0);
begin
daout<= count;
process(clk)
begin
if (clk'event and clk='1') then
if count(3 downto 0)="1001" then
if count(6 downto 4)="101" then
count<="0000000";enmin<='1';
else count(3 downto 0)<="0000";
count(6 downto 4)<=count(6 downto 4)+1;
end if;
else count(3 downto 0)<=count(3 downto 0)+1;enmin<='0';
end if ;
end if;
end process;
end behave;
b、分计数器程序
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity minute is
port( clk: in std_logic;
enhour : out std_logic;
daout : out std_logic_vector(6 downto 0));
end minute;
Architecture behave of minute is
signal count: std_logic_vector(6 downto 0);
begin
daout<= count;
process( clk)
begin
if (clk'event and clk='1') then
if count(3 downto 0)="1001" then
if count(6 downto 4)="101" then
count<="0000000";enhour<='1';
else count(3 downto 0)<="0000";
count(6 downto 4)<=count(6 downto 4)+1;
end if;
else count(3 downto 0)<=count(3 downto 0)+1;enhour<='0';
end if ;
end if;
end process;
end behave;
c、时计数器程序
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity hour is
port( clk: in std_logic;
daout : out std_logic_vector(5 downto 0));
end hour;
Architecture behave of hour is
signal count: std_logic_vector(5 downto 0);
begin
daout<= count;
process( clk )
begin
if (clk'event and clk='1') then
if count(5 downto 4)="10" then
if count(3 downto 0)="0011" then
count<="000000";
else count(3 downto 0)<=count(3 downto 0)+1;
end if;
elsif count(3 downto 0)="1001" then
count(3 downto 0)<="0000";
count(5 downto 4)<=count(5 downto 4)+1;
else count(3 downto 0)<=count(3 downto 0)+1;
end if ;
end if;
end process;
end behave;
d、2选1选择器程序
library ieee;
use ieee.std_logic_1164.all;
entity mux21 is
port(
a,b :in std_logic;
sel :in std_logic;
y :out std_logic);
end entity mux21;
architecture one of mux21 is
begin
y<=a when sel='1' else
b;
end architecture one;
e、译码器程序
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity decoder is
port( second: in std_logic_vector(6 downto 0);
minute: in std_logic_vector(6 downto 0);
hour: in std_logic_vector(5 downto 0);
clk: in std_logic;
seg_dp: out std_logic;
sel: out std_logic_vector(2 downto 0);
seg: out std_logic_vector(6 downto 0)); end decoder;
Architecture one of decoder is
signal num : std_logic_vector(3 downto 0);
signal count : std_logic_vector(2 downto 0);
signal f : std_logic;
begin
process(clk)
begin
if clk'event and clk='1' then
if count<7 then
count<=count+1;
else count<="000";
end if ;
end if ;
end process;
sel<=count;
num<= second(3 downto 0) when count=0 else
'0' & second(6 downto 4) when count=1 else
"1010" when count=2 else
minute(3 downto 0) when count=3 else
'0' & minute(6 downto 4) when count=4 else
"1010" when count=5 else
hour(3 downto 0) when count=6 else
"00"&hour(5 downto 4);
seg_dp<='1';
seg<= "1000000" when num="0000" else --0
"1111001" when num="0001" else --1
"0100100" when num="0010" else --2
"0110000" when num="0011" else --3
"0011001" when num="0100" else --4
"0010010" when num="0101" else --5
"0000010" when num="0110" else --6
"1111000" when num="0111" else --7
"0000000" when num="1000" else --8
"0010000" when num="1001" else --9
"0111111" when num="1010" else ---
"1111111";
end one;
f、3-8线译码器程序
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY decoder3_8 IS
PORT(
sel : IN STD_LOGIC_vector(2 downto 0);
Y : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); ARCHITECTURE fun OF decoder3_8 IS
SIGNAL indata: STD_LOGIC_VECTOR(2 DOWNTO 0); BEGIN
indata <= sel;
encoder:
PROCESS (indata)
BEGIN
CASE indata IS
WHEN "000"=>Y<="11111110"; --0
WHEN "001"=>Y<="11111101";
WHEN "010"=>Y<="11111011";
WHEN "011"=>Y<="11110111";
WHEN "100"=>Y<="11101111";
WHEN "101"=>Y<="11011111";
WHEN "110"=>Y<="10111111";
WHEN "111"=>Y<="01111111"; --7
WHEN OTHERS =>Y<="XXXXXXXX";
END CASE;
END PROCESS encoder;
END fun;
3、波形仿真分析
1)、秒计数器(second.vhd)
a波形仿真图
b波形分析
由波形图知秒计数器是由60进制计数器完成的00到59的循环计数功能,当计数到59时,再来一个技术脉冲则产生进位输出,即enmin=1,作为分计数器的计数脉冲。
2)、分计数器(minute.vhd)
a波形仿真图
b波形分析
由波形图可知,该模块实现了分计数的功能,计数循环从00到59,计数脉冲为秒计数器的进位输出,即enmin。当计数到59时,再来一个计数脉冲则产生进位输出,即enhour=1,作为时计数器的计数脉冲。
3)、时计数器(hour.vhd)
a波形仿真图
b波形分析
小时计数模块由24进制计数器完成的从00到23之间的循环计数,计数脉冲为分计数器的进位输出,即enhour。
4)、3-8线译码器(decoder3_8.vhd)
a波形仿真图
b波形分析
由波形图分析可知,3-8线译码器完成了3位信号的输入到8位译码的输出功能。
5)、译码器(decoder.vhd)
a波形仿真图
b波形分析
译码器模块完成了将时、分、秒的二进制码转换为能在LED数码管上显示的7端BCD码,同时产生了数码管的位选通信号,即sel,位选通信号是将时、分、秒的7端BCD码分别显示在对应的数码管上。
3、顶层原理图设计图
4、硬件测试与结果分析
1、硬件测试
测试方式:clk选用clock0,短路帽选1024HZ。clk1选用clock1,短路帽选1HZ。SW1控制调分,SW2控制调时。数码管8、7用作小时显示,高位是小时的十位,低位是小时的个位。数码管5、4用作分钟显示,高位是分钟的十位,低位是分钟的个位。数码管2、1用作秒钟显示,高位是秒钟的十位,低位是秒钟的个位。
2、测试过程
将.sof文件下载到FPGA中,数码管上显示00-00-00,并开始计时,秒钟计到59向分钟进1,分钟计到59向小时进1。闭合SW1键分钟以1HZ的频率加1,加到59向小时进1,分钟清0。闭合SW2键小时以1HZ的频率加1,加到59小时清0。
3、结果分析
由测试过程可知该数字时钟能够满足正常计时和调时调分功能,达到了预期的设计效果。
四、结论
本数字时钟采用层次化设计方式,使设计思路更简单、清晰。设计过程中,底层器件采用VHDL文本形式设计,顶层设计采用原理图形式。该数字时钟能够进行正常的计时和调试调分功能,能满足设计任务及要求。
五、心得体会
通过此次数字时钟的综合设计,我对层次化设计有了更加深层次的了解,对VHDL语言的认识加深了,并能够自主解决编译过程中出现的错误,虽然设计过程中也走了不少弯路,但我知道学习一们硬件语言就是在曲折中不断进步,所以我想我们只有不断的进行VDHL程序的编写,我们对这门语言的掌握就更好,而且在自己设计最迷茫的时候,多和老师交流能起到事半功倍的效果。