数字时钟系统实现目标:
实现显示“时-分-秒”、整点报时、小时和分钟可调等基本功能。电子钟的工作应该是在1Hz 信号的驱动下进行,这样每来一个该时钟信号,秒增加1 秒,当秒从59 秒跳转到00秒时,分钟增加1 分,同时当分钟从59 分跳转到00 分时,小时增加1 小时,但是需要注意的是,小时的范围是从0~23 时。
数字时钟系统要求:
在一个50MHZ系统时钟的驱动下完成整个电路的输出,电路要能正确的输出时、分、秒,并且根据用户的设定来改变时钟和分钟的值,这里需要使用两个按键作为输入控制S1,S0,可以分别用来改变时钟和分钟的值以达到时间设定的目的,每按一次S0按钮分钟加1,每按一次S1按钮时钟加1。同时在整点时分都应该输出一个整点报时信号,信号规律为1秒钟闪烁一次,持续5秒,控制某个LED灯进行报时。
功能
这里用了一个4*2的键盘和四个数字显示的数码管。设置四个按键,功能分别是调节分钟,调节时钟,全部置0,查看秒钟。
-- VHDL library Declarations
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
-- The Entity Declarations
ENTITY LED8 IS
PORT
(
-- Reset & Clock Signal
RESET: IN STD_LOGIC;
GCLKP1: IN STD_LOGIC; -- 50 MHz
k1, k2, k3,k4 : in std_LOGIC;
LED1: buffer std_logic;
-- LED8 PIN
LEDOut: OUT STD_LOGIC_VECTOR(7 DOWNTO 0); -- LED Segment
DigitSelect: OUT STD_LOGIC_VECTOR(3 DOWNTO 0) -- LED Digit
);
END LED8;
-- The Architecture of Entity Declarations
ARCHITECTURE Behavioral OF LED8 IS
SIGNAL LED: integer range 0 to 9;
SIGNAL cnt,Period1uS, Period1mS, Period1S,count12: STD_LOGIC;
SIGNAL s1,s2,s3,s4: integer range 0 to 9;
BEGIN
------------------------------------------------------------------------------
-- Clock
------------------------------------------------------------------------------
PROCESS( RESET, GCLKP1, Period1uS, Period1mS )
VARIABLE Count : STD_LOGIC_VECTOR(5 DOWNTO 0);
VARIABLE Count1 : STD_LOGIC_VECTOR(9 DOWNTO 0);
VARIABLE Count2 : STD_LOGIC_VECTOR(9 DOWNTO 0);
BEGIN
------------------------------------
--Period: 1uS
IF( RESET = '0' ) THEN
Count := "000000";
ELSIF( GCLKP1'EVENT AND GCLKP1='1' ) THEN
IF( Count>"110000" ) THEN Count := "000000"; -- 110000:48 50/50M = 1us
ELSE Count := Count + 1;
END IF;
Period1uS <= Count(5);
END IF;
------------------------------------
--Period: 1mS
IF( Period1uS'EVENT AND Period1uS='1' ) THEN
IF( Count1>"1111100110" ) THEN Count1 := "0000000000"; -- 1111100110:998 1000*1us = 1ms
ELSE Count1 := Count1 + 1;
END IF;
Period1mS <= Count1(9);
END IF;
------------------------------------
--Period: 1S (1111100110: 998)
IF( Period1mS'EVENT AND Period1mS='1' ) THEN
IF( Count2>"1111100110" ) THEN Count2 := "0000000000";
ELSE Count2 := Count2 + 1;
END IF;
Period1S <= Count2(9);
END IF;
END PROCESS;
-------------------------------------------------
-- Encoder
-------------------------------------------------
-- HEX-to-seven-segment decoder
-- segment encoding
-- 0
-- ---
-- 5 | | 1
-- --- <------6
-- 4 | | 2
-- ---
-- 3
PROCESS( LED )
BEGIN
CASE LED IS
when 0=>LEDOut<= "11000000"; --'0'
when 1=>LEDOut<= "11111001"; --'1'
when 2=>LEDOut<= "10100100"; --'2'
when 3=>LEDOut<= "10110000"; --'3'
when 4=>LEDOut<= "10011001"; --'4'
when 5=>LEDOut<= "10010010"; --'5'
when 6=>LEDOut<= "10000010"; --'6'
when 7=>LEDOut<= "11111000"; --'7'
when 8=>LEDOut<= "10000000"; --'8'
when 9=>LEDOut<= "10010000"; --'9'
when others=>LEDOut<= "XXXXXXXX"; --' '
END CASE;
END PROCESS;
-------------------------------------------------
-- Clock
PROCESS( RESET, Period1S )
VARIABLE Glide : STD_LOGIC_VECTOR(3 DOWNTO 0);
VARIABLE reflash: integer range 0 to 3;
VARIABLE s,m,h : integer range 0 to 64;
VARIABLE count,count1 : integer range 0 to 1024;
variable l1,l2,l3,l4 :integer range 0 to 9;
BEGIN
IF( Period1ms'EVENT AND Period1ms = '1' )THEN
CASE reflash IS
when 0=>DigitSelect<= "0001";LED <= l1;
when 1=>DigitSelect<= "0010";LED <= l2;
when 2=>DigitSelect<= "0100";LED <= l3;
when 3=>DigitSelect<= "1000";LED <= l4;
when others=>DigitSelect<= "XXXX";
END CASE;
if( count =0) then
cnt <= '1';
end if;
if( (count = 0 or count = 250 or count = 500 or count = 750) and (s = 0 or s=1 or s =2 or s = 3 or s = 4)) then
cnt <= not cnt;
end if;
if(count < 999) then
count := count + 1;
else
s := s + 1;
count := 0;
end if;
if s = 60 then
m := m + 1;
s := 0;
end if;
if( m = 60 ) then -- every hours in position
m := 0;
h := h + 1;
end if;
if( h = 24) then -- every day in position
h := 0;
end if;
l4 := m rem 10;
l3 := (m-l2)/10;
l2 := h rem 10;
l1 := (h-l2)/10;
if( k4 = '0') then
l4 := s rem 10;
l3 := (s-l4)/10;
l2 := m rem 10;
l1 := (m-l2)/10;
end if;
reflash := reflash + 1;
if(k1 = '0') then
if( count rem 60 = 0) then
count1 := count1 + 1;
end if;
if( count1 = 2) then
m := m + 1; count1 := 0;
end if;
end if;
if(k2 = '0') then
if( count rem 60 = 0) then
count1 := count1 + 1;
end if;
if( count1 = 2) then
h := h + 1; count1 := 0;
end if;
end if;
end if;
if(k3 = '0') then
s := 0;
m := 0;
h := 0;
count := 0;
end if;
END PROCESS;
process(cnt)
variable count12: integer range 0 to 6;
begin
if(cnt'event and cnt = '1') then
led1 <= not led1;
end if;
end process;
END Behavioral;