--
-- 作为一个简单示例,本实验实现一个能显示小时,分钟,秒的数字时钟。
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY clock IS
PORT (
clk : IN std_logic;
rst : IN std_logic;
dataout : OUT std_logic_vector(7 DOWNTO 0);
en : OUT std_logic_vector(7 DOWNTO 0));
END clock;
ARCHITECTURE arch OF clock IS
SIGNAL div_cnt : std_logic_vector(18 DOWNTO 0); --分频计数器
SIGNAL data4 : std_logic_vector(3 DOWNTO 0);
SIGNAL en_xhdl : std_logic_vector(7 DOWNTO 0);
SIGNAL dataout_xhdl1 : std_logic_vector(7 downto 0);
SIGNAL s1_cnt : std_logic_vector(3 DOWNTO 0); ---秒的个位计数器 逢9进
SIGNAL s2_cnt : std_logic_vector(2 DOWNTO 0); ---秒的十位计数器 逢6进
SIGNAL m1_cnt : std_logic_vector(3 DOWNTO 0); ---分的个位计数器 逢9进
SIGNAL m2_cnt : std_logic_vector(2 DOWNTO 0); ---分的十位计数器 逢6进
SIGNAL h1_cnt : std_logic_vector(3 DOWNTO 0); ---小时的个位计数器 逢9进
SIGNAL h2_cnt : std_logic_vector(1 DOWNTO 0); ---小时的十位计数器 逢2进
SIGNAL s1_over : std_logic; ---秒的个位计数器溢出标志
SIGNAL S2_over : std_logic; ---秒的十位计数器溢出标志
SIGNAL m1_over : std_logic; ---分的个位计数器溢出标志
SIGNAL m2_over : std_logic; ---分的个位计数器溢出标志
SIGNAL h1_over : std_logic; ---小时的个位计数器溢出标志
SIGNAL timer_over : std_logic; ---时钟完成24小时运转
constant dot : std_logic_vector(3 downto 0) :="1010";
begin
PROCESS(clk,rst)
BEGIN
IF (NOT rst = '1') THEN
div_cnt ELSIF(clk'EVENT AND clk = '1')THEN
if(div_cnt="1100001101010000000")then
div_cnt else
div_cnt END IF;
END PROCESS;
process(div_cnt(20),rst) ---秒的个位计数器 逢9进
begin
if(rst='0')then
s1_cnt s1_over elsif(div_cnt(20)'event and div_cnt(20)='1')then
if(s1_cnt="1001" )then
s1_cnt s1_over else
s1_over s1_cnt end if;
end if;
end process;
process(rst,s1_over) ---秒的十位计数器 逢5进
begin
if(rst='0')then
s2_cnt s2_over elsif(s1_over'event and s1_over='1')then
if(s2_cnt="101" )then
s2_cnt s2_over else
s2_over s2_cnt end if;
end if;
end process;
process(rst,s2_over) ---分的个位计数器 逢10进
begin
if(rst='0')then
m1_cnt m1_over elsif(s2_over'event and s2_over='1')then
if(m1_cnt="1001" )then
m1_cnt m1_over else
m1_over m1_cnt end if;
end if;
end process;
process(rst,m1_over) ---分的十位计数器 逢5进
begin
if(rst='0')then
m2_cnt m2_over elsif(m1_over'event and m1_over='1')then
if(m2_cnt="101" )then
m2_cnt m2_over else
m2_over m2_cnt end if;
end if;
end process;
process(rst,m2_over,timer_over) ---小时的个位计数器 逢9进
begin
if(rst='0')then
h1_cnt h1_over elsif(m2_over'event and m2_over='1')then
if(h1_cnt="1001" or timer_over='1')then
h1_cnt h1_over else
h1_over h1_cnt end if;
end if;
end process;
process(rst,h1_over) ---小时的十位计数器 逢2进
begin
if(rst='0')then
h2_cnt elsif(h1_over'event and h1_over='1')then
if(h2_cnt="10" and timer_over='1')then
h2_cnt else
h2_cnt end if;
end if;
end process;
timer_over '0';
---*******************显示部分***********************--
en dataout
process(clk,rst,div_cnt(15 downto 13))
begin
if(rst='0')then
en_xhdl elsif(clk'event and clk='1')then
case div_cnt(19 downto 17) is
when"000"=> en_xhdl when"001"=> en_xhdl when"010"=> en_xhdl when"011"=> en_xhdl when"100"=> en_xhdl when"101"=> en_xhdl when"110"=> en_xhdl when"111"=> en_xhdl when others=> en_xhdl end case;
end if;
end process;
process(clk,rst,en_xhdl,s1_cnt,s2_cnt,m1_cnt,m2_cnt,h1_cnt,h2_cnt)
begin
if(rst='0')then
data4 elsif(clk'event and clk='1')then
case en_xhdl is
when "11111110"=> data4 when "11111101"=> data4 when "11111011"=> data4 when "11110111"=> data4 when "11101111"=> data4 when "11011111"=> data4 when "10111111"=> data4 when "01111111"=> data4 when others => data4 end case;
end if;
end process;
process(data4)
begin
case data4 is
WHEN "0000" =>
dataout_xhdl1 WHEN "0001" =>
dataout_xhdl1 WHEN "0010" =>
dataout_xhdl1 WHEN "0011" =>
dataout_xhdl1 WHEN "0100" =>
dataout_xhdl1 WHEN "0101" =>
dataout_xhdl1 WHEN "0110" =>
dataout_xhdl1 WHEN "0111" =>
dataout_xhdl1 WHEN "1000" =>
dataout_xhdl1 WHEN "1001" =>
dataout_xhdl1 WHEN "1010" =>
dataout_xhdl1 WHEN "1011" =>
dataout_xhdl1 WHEN "1100" =>
dataout_xhdl1 WHEN "1101" =>
dataout_xhdl1 WHEN "1110" =>
dataout_xhdl1 WHEN "1111" =>
dataout_xhdl1 WHEN OTHERS =>
dataout_xhdl1
END CASE;
END PROCESS;
end arch;