基于FPGA的数字钟实现
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
-------------------------------------------------------
--基于FPGA的数字钟实现
--开发语言:VHDL
--所选芯片:Altera Cyclone II EP2C5T144C8
--开发者:jnu.bluecoffee
--开发日期:2009年6月11日
--小弟刚刚入道,完全原创。如有转载,请注明出处。
-------------------------------------------------------
--------------------------------------------------------
--数字钟的秒模块
--------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity SECOND is
port (CLK, RESET: in STD_LOGIC;
CKMIN: out STD_LOGIC;
SEC1, SEC0: out STD_LOGIC_VECTOR(3 DOWNTO 0));
end entity SECOND;
architecture ART of SECOND is
signal Tsec1, Tsec0: STD_LOGIC_VECTOR(3 DOWNTO 0);
begin
process (CLK, RESET) is
begin
if (RESET = '1') then
Tsec1 <= "0000";
Tsec0 <= "0000";
elsif (CLK'EVENT and CLK = '1') then
if (Tsec1 = "0101" and Tsec0 = "1001") then
Tsec1 <= "0000";
Tsec0 <= "0000";
CKMIN <= '1';
elsif (Tsec0 = "1001") then
Tsec0 <= "0000";
Tsec1 <= Tsec1 + "0001";
CKMIN <= '0';
else
Tsec0 <= Tsec0 + "0001";
CKMIN <= '0';
end if;
end if;
SEC1 <= Tsec1;
SEC0 <= Tsec0;
end process;
end architecture ART;
--------------------------------------------------------
--数字钟的分钟模块
--------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity MINUTE is
port (CLK, RESET, SET_MIN: in STD_LOGIC;
CKHOUR: out STD_LOGIC;
MIN1, MIN0: out STD_LOGIC_VECTOR(3 DOWNTO 0));
end entity MINUTE;
architecture ART of MINUTE is
signal Tmin1, Tmin0: STD_LOGIC_VECTOR(3 DOWNTO 0);
begin
process (CLK, RESET, SET_MIN) is
begin
if (RESET = '1') then
Tmin1 <= "0000";
Tmin0 <= "0000";
elsif (CLK'EVENT and CLK = '1' and CLK'LAST_VALUE = '0') then
if (SET_MIN = '0') then
if (Tmin1 = "0101" and Tmin0 = "1001") then
Tmin1 <= "0000";
Tmin0 <= "0000";
CKHOUR <= '1';
elsif (Tmin0 = "1001") then
Tmin0 <= "0000";
Tmin1 <= Tmin1 + "0001";
CKHOUR <= '0';
else
Tmin0 <= Tmin0 + "0001";
CKHOUR <= '0';
end if;
else
if (Tmin1 = "0101" and Tmin0 = "1001") then
Tmin1 <= "0000";
Tmin0 <= "0000";
elsif (Tmin0 = "1001") then
Tmin0 <= "0000";
Tmin1 <= Tmin1 + "0001";
else
Tmin0 <= Tmin0 + "0001";
CKHOUR <= '0';
end if;
end if;
end if;
MIN1 <= Tmin1;
MIN0 <= Tmin0;
end process;
end architecture ART;
--------------------------------------------------------
--数字钟的小时模块
--------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity HOUR is
port (CLK, RESET: in STD_LOGIC;
HOUR1, HOUR0: out STD_LOGIC_VECTOR(3 DOWNTO 0));
end entity HOUR;
architecture ART of HOUR is
signal Thour1, Thour0: STD_LOGIC_VECTOR(3 DOWNTO 0);
begin
process (CLK, RESET) is
begin
if (RESET = '1') then
Thour1 <= "0000";
Thour0 <= "0000";
elsif (CLK'EVENT and CLK = '1' and CLK'LAST_VALUE = '0') then
if (Thour1 = "0010" and Thour0 = "0011") then
Thour1 <= "0000";
Thour0 <= "0000";
elsif (Thour0 = "1001") then
Thour0 <= "0000";
Thour1 <= Thour1 + "0001";
else
Thour0 <= Thour0 + "0001";
end if;
end if;
HOUR1 <= Thour1;
HOUR0 <= Thour0;
end process;
end architecture ART;
--------------------------------------------------------
--时钟控制模块
--------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity SEL_CLOCK is
port (CKDSP: in STD_LOGIC;
SEC0, SEC1, MIN0, MIN1, HOUR0, HOUR1: in STD_LOGIC_VECTOR(3 DOWNTO 0);
NUM: out STD_LOGIC_VECTOR(3 DOWNTO 0);
SEL: out STD_LOGIC_VECTOR(2 DOWNTO 0));
end entity;
architecture ART of SEL_CLOCK is
signal STATE: STD_LOGIC_VECTOR(2 DOWNTO 0);
begin
SEL <= STATE;
process (CKDSP)
begin
if (CKDSP'EVENT and CKDSP = '1') then
STATE <= STATE + 1;
end if;
case STATE is
when "000" => NUM <= HOUR1;
when "001" => NUM <= HOUR0;
when "010" => NUM <= "1111";
when "011" => NUM <= MIN1;
when "100" => NUM <= MIN0;
when "101" => NUM <= "1111";
when "110" => NUM <= SEC1;
when "111" => NUM <= SEC0;
when others => NUM <= "ZZZZ";
end case;
end process;
end architecture ART;
--------------------------------------------------------
--时钟译码模块
--------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity ENCODER7 is
port (DATA_NUM: in STD_LOGIC_VECTOR(3 DOWNTO 0);
DRIVEOUT: out STD_LOGIC_VECTOR(6 DOWNTO 0));
end entity ENCODER7;
architecture COMMON_ANODE of ENCODER7 is
signal NUM: STD_LOGIC_VECTOR(3 DOWNTO 0);
signal DRIVEOUT_TEMP: STD_LOGIC_VECTOR(6 DOWNTO 0);
begin
-- NUM <= NUM3 & NUM2 & NUM1 & NUM0;
NUM <= DATA_NUM;
process (NUM) is
begin
case NUM is
when "0000" => DRIVEOUT_TEMP <= "0000001";
when "0001" => DRIVEOUT_TEMP <= "1001111";
when "0010" => DRIVEOUT_TEMP <= "0010010";
when "0011" => DRIVEOUT_TEMP <= "0000110";
when "0100" => DRIVEOUT_TEMP <= "1001100";
when "0101" => DRIVEOUT_TEMP <= "0100100";
when "0110" => DRIVEOUT_TEMP <= "0100000";
when "0111" => DRIVEOUT_TEMP <= "0001111";
when "1000" => DRIVEOUT_TEMP <= "0000000";
when "1001" => DRIVEOUT_TEMP <= "0000100";
when "1010" => DRIVEOUT_TEMP <= "0001000";
when "1011" => DRIVEOUT_TEMP <= "1100000";
when "1100" => DRIVEOUT_TEMP <= "0110001";
when "1101" => DRIVEOUT_TEMP <= "1000010";
when "1110" => DRIVEOUT_TEMP <= "0110000";
when "1111" => DRIVEOUT_TEMP <= "1111110";
-- when "1111" => DRIVEOUT_TEMP <= "0111000";
when others => DRIVEOUT_TEMP <= "ZZZZZZZ";
end case;
end process;
DRIVEOUT <= DRIVEOUT_TEMP;
end architecture COMMON_ANODE;
--------------------------------------------------------
--调整时间模块
--------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity SETTIME is
generic (n: integer := 8);
port(SET, MIN, HOUR, RESET, CLK_1HZ_IN, CLK_SCAN_IN: in STD_LOGIC;
SET_STATE, SET_MIN, SET_HOUR : out STD_LOGIC := '0';
RESET_BOTH, CLK_1HZ_OUT, CLK_SCAN_OUT: out STD_LOGIC);
end entity SETTIME;
architecture ART of SETTIME is
signal cnt: integer := 0;
signal CLK_SCAN_TEMP: STD_LOGIC := '1';
begin
SET_STATE <= SET;
process (MIN, HOUR) is
begin
if (SET = '1') then
SET_MIN <= MIN;
SET_HOUR <= HOUR;
else
SET_MIN <= '0';
SET_HOUR <= '0';
end if;
end process;
process (CLK_1HZ_IN) is
begin
if (SET = '1') then
CLK_1HZ_OUT <= 'Z';
else
CLK_1HZ_OUT <= CLK_1HZ_IN;
end if;
end process;
process (CLK_SCAN_IN) is
begin
if (CLK_SCAN_IN'EVENT and CLK_SCAN_IN = '1') then
if (SET = '1') then
if cnt = n / 2 then
cnt <= 0;
CLK_SCAN_TEMP <= not CLK_SCAN_TEMP;
else
cnt <= cnt + 1;
end if;
CLK_SCAN_OUT <= CLK_SCAN_TEMP;
else
CLK_SCAN_OUT <= '1';
end if;
end if;
end process;
process (RESET) is
begin
if (SET = '1') then
RESET_BOTH <= RESET;
else
RESET_BOTH <= '0';
end if;
end process;
end architecture ART;
--------------------------------------------------------
--分频模块
--------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity CLKDIV is
generic (n: integer := 8);
port(CLK, RESET: in STD_LOGIC;
CLK_DIV50M: out STD_LOGIC);
end entity CLKDIV;
architecture ART of CLKDIV is
signal cnt: INTEGER := 0;
signal CLK_TEMP: STD_LOGIC := '1';
begin
process (CLK, RESET)
begin
if (RESET = '1') then
cnt <= 0;
elsif (CLK'EVENT and CLK = '1') then
if (cnt = n/2 + n mod 2 - 1) then
cnt <= 0;
CLK_TEMP <= not CLK_TEMP;
else
cnt <= cnt + 1;
end if;
end if;
end process;
CLK_DIV50M <= CLK_TEMP;
end architecture ART;
--------------------------------------------------------
--2路MUX模块
--------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity MY21MUX is
port (A, B, S: in STD_LOGIC;
Y: out STD_LOGIC);
end entity MY21MUX;
architecture ART of MY21MUX is
begin
process (S)
begin
if (S = '1') then
Y <= A;
elsif (S = '0') then
Y <= B;
else
Y <= 'Z';
end if;
end process;
end architecture ART;
--------------------------------------------------------
--触发翻转模块
--------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity TURN is
port (CLK: in STD_LOGIC;
Q: inout STD_LOGIC := '0');
end entity TURN;
architecture ART of TURN is
begin
process (CLK)
begin
if (CLK'EVENT and CLK = '0') then
Q <= not Q;
end if;
end process;
end architecture ART;
--------------------------------------------------------
--按键消抖模块
--------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity KEY is
port (CLK, DIN: in STD_LOGIC;
DOUT: out STD_LOGIC);
end entity KEY;
architecture ART of KEY is
signal cp: STD_LOGIC := '1';
signal count : integer range 0 to 3;
begin
process(CLK)
begin
if (CLK'EVENT and CLK = '1') then
if (DIN = '0') then
if (count = 3) then
count <= count;
else
count <= count + 1;
end if;
if (count = 2) then
cp <= '0';
else
cp <= '1';
end if;
else
count <= 0;
end if;
end if;
DOUT <= cp;
end process;
end ART;