LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY relogio IS
generic(
fclk: integer := 50000000 --clock freq in Hz
);
port (
--A entrada Estado é reponsável pela troca de estados (contando ou ajustando);
--As entradas as,am e ah são os botões de entrada para efetuar o ajuste do segundo/minuto/hora;
--As saídas foram divididas em 6 displays 7-segmentos;
rst, clk, estado, as, am, ah : in std_logic;
dig1, dig2, dig3, dig4, dig5, dig6 : out std_logic_vector (6 downto 0)
);
end entity;
architecture funcio of relogio is
type state_type is (st0, st1); --Arquitetura possui 2 estados st0: onde o relógio está contando e
--st1: quando o relógio está parado para ajuste;
signal state : state_type;
begin
-- Processo responsável por atualizar o Estado, st0:contando st1: parado para ajuste;
process (estado)
begin
-- Quando a key "Estado" estiver em '0' o estado atual é st0, e quando estiver em '1' o estado atual é st1
if (estado='0') then
state <= st0;
else
state <= st1;
end if;
end process;
--Processo resposável pela implementação dos Estados st0 e st1
--Este processo é sensível ao clock, reset e os botões de entrada para ajuste(as,am,ah)
process(clk,rst,as,am,ah)
-- Variaveis responsaveis por guarda valores dos contadores. Final 0 esta atrelado ao estaod 0; final 1 esta atrelado ao estado st1;
variable ss0, ss1: integer range 0 to 60;
variable mm0, mm1: integer range 0 to 60;
variable hh0, hh1: integer range 0 to 24;
-- Variavel count e responsavel por realizar a contagem que vai de 0 at´e fclk, que no caso e 50MHz,
-- ou seja, apos esse periodo a variavel e incrementada em 1.
variable count : integer range 0 to fclk;
--Variaveis responsaveis por guardar valor final do algarismo
variable s1,s2,m1,m2,h1,h2 : integer range 0 to 9;
--Variaveis auxiliares responsaveis por atualizar o horario apos ajuste
variable aux0, aux1, aux2 : integer range 0 to 60;
begin
--Implementação dos estados
case state is
when st0 =>
if (clk'event and clk='1') then -- Quando houver um evento na borda de subida do clk e o clk for igual a 1;
count := count + 1; --Dispara o contador ou incrementa;
if (rst='0') then --Se o botão reset estiver em '0', as variáveis do st0 são setadas e a contagem volta para 0;
ss0 := 0;
mm0 := 0;
hh0 := 0;
count :=0;
elsif (count=fclk) then --Se não, se o coount for igual a freq de clock (50MHz)
ss0 := ss0 + 1; --Incrementa 1 no valor do segundo (ss0)
--Se a variável segundo (ss0) for igual a 60, ele reseta a variável ss0 ('0') e começa contagem
--da variável minuto (mm0);
if (ss0 = 60) then
ss0 := 0; -- '60' segundos não aparece, aparece '0'
mm0 := (mm0 + 1);
--Se a variável minuto (mm0) for igual a 60, ele reseta a variável mm0 ('0') e começa contagem
--da variável hora (hh0);
if (mm0 = 60) then
mm0 := 0; -- '60' minutos não aparece, aparece '0'
hh0 := hh0 + 1;
--Se a variável hora (hh0) for igual a 24, ele reseta a variável hh0 ('0')
if (hh0 = 24) then
hh0 := 0; -- '24' minutos não aparece, aparece '0'
end if;
end if;
end if;
count := 0; -- zera o contador;
end if;
end if;
-- Atualizando saida --
s2 := ss0/10; -- dezena /pega a variavel ss0 e divide por dez, o resultado coloca na variavel s2
s1 := ss0 rem 10; -- unidade /pega a variavel ss0 e divide por dez, pega o resto e colocar na variavel s1
m2 := mm0/10; -- dezena /pega a variavel mm0 e divide por dez, o resultado coloca na variavel m2
m1 := mm0 rem 10; -- unidade /pega a variavel mm0 e divide por dez, pega o resto e colocar na variavel m1
h2 := hh0/10; -- dezena /pega a variavel hh0 e divide por dez, o resultado coloca na variavel h2
h1 := hh0 rem 10; -- unidade /pega a variavel hh0 e divide por dez, pega o resto e colocar na variavel h1
when st1 =>
--Se houver uma mudança na borda de descida do botão de ajuste de segundos, ele incrementa a variável ss1
--a partir da variável que estava contando no estado anterior (ss0)
--quando chegar em 60 ele reseta a variável segundos do st1(ss1);
if (falling_edge (as)) then
--aux0: e testada para atualizar o valor apos o ajuste
aux0 := (ss0 + 1);
ss1 := (ss0 + 1);
if (ss1 = 60) then
ss1 :=0;
end if;
end if;
--Se houver uma mudança na borda de descida do botão de ajuste de minuto, ele incrementa a variável mm1
--a partir da variável que estava contando no estado anterior (mm0)
--quando chegar em 60 ele reseta a variável minutos do st1(mm1);
if (falling_edge (am)) then
--aux1: e testada para atualizar o valor apos o ajuste
aux1 := (mm0 + 1);
mm1 := (mm0 + 1);
if (mm1 = 60) then
mm1 :=0;
end if;
end if;
--Se houver uma mudança na borda de descida do botão de ajuste de hora, ele incrementa a variável hh1
--a partir da variável que estava contando no estado anterior (hh0)
--quando chegar em 24 ele reseta a variável hora do st1(hh1);
if (falling_edge (ah)) then
--aux2: e testada para atualizar o valor apos o ajuste
aux2 := (hh0 + 1);
hh1 := (hh0 + 1);
if (hh1 = 24) then
hh1 :=0;
end if;
end if;
--Se o valor de aux0 for ajustado, a variável do st0 (ss0) também é atualizada, para que
--quando o relógio voltar para o estado "contado" ele retorne a contagem de onde o relogio foi ajustado;
if aux0 =(ss0+1) then
ss0 := ss1;
count :=0;
elsif aux1=(mm0+1) then
mm0 := mm1;
count :=0;
elsif aux2=(hh0+1) then
hh0 := hh1;
count :=0;
end if;
-- Atualizando saida --
s2 := ss0/10; -- dezena /pega a variavel ss0 e divide por dez, o resultado coloca na variavel s2
s1 := ss0 rem 10; -- unidade /pega a variavel ss0 e divide por dez, pega o resto e colocar na variavel s1
m2 := mm0/10; -- dezena /pega a variavel mm0 e divide por dez, o resultado coloca na variavel m2
m1 := mm0 rem 10; -- unidade /pega a variavel mm0 e divide por dez, pega o resto e colocar na variavel m1
h2 := hh0/10; -- dezena /pega a variavel hh0 e divide por dez, o resultado coloca na variavel h2
h1 := hh0 rem 10; -- unidade /pega a variavel hh0 e divide por dez, pega o resto e colocar na variavel h1
when others =>
-- Atualizando saida obrigatoriamente para não haver erros de compilação--
s2 := 0; -- dezena
s1 := 0; -- unidade
m2 := 0; -- dezena
m1 := 0; -- unidade
h2 := 0; -- dezenaatoriamente para não haver erros de compilação--
s2 := 0; -- dezena
h1 := 0; -- unidade
end case;
--Implementação do display 7 segmentos:
case s1 is
when 0 => dig1 <= "0000001"; --126
when 1 => dig1 <= "1001111"; --48
when 2 => dig1 <= "0010010"; --109
when 3 => dig1 <= "0000110"; --121
when 4 => dig1 <= "1001100"; --51
when 5 => dig1 <= "0100100"; --91
when 6 => dig1 <= "0100000"; --95
when 7 => dig1 <= "0001111";--112
when 8 => dig1 <= "0000000"; --127
when 9 => dig1 <= "0000100";--123
when others => dig1 <= "1111111";
end case;
case s2 is
when 0 => dig2 <= not "1111110"; --126
when 1 => dig2 <= not "0110000"; --48
when 2 => dig2 <= not "1101101"; --109
when 3 => dig2 <= not "1111001"; --121atoriamente para não haver erros de compilação--
s2 := 0; -- dezena
when 4 => dig2 <= not "0110011"; --51
when 5 => dig2 <= not "1011011"; --91
when 6 => dig2 <= not "1011111"; --95
when others => dig2 <= "1111111";
end case;
case m1 is
when 0 => dig3 <= not "1111110"; --126
when 1 => dig3 <= not "0110000"; --48
when 2 => dig3 <= not "1101101"; --109
when 3 => dig3 <= not "1111001"; --121
when 4 => dig3 <= not "0110011"; --51
when 5 => dig3 <= not "1011011"; --91
when 6 => dig3 <= not "1011111"; --95
when 7 => dig3 <= not "1110000";--112
when 8 => dig3 <= not "1111111"; --127
when 9 => dig3 <= not "1111011";--123
when others => dig3 <= "1111111";
end case;
case m2 is
when 0 => dig4 <= not "1111110"; --126
when 1 => dig4 <= not "0110000"; --48
when 2 => dig4 <= not "1101101"; --109
when 3 => dig4 <= not "1111001"; --121
when 4 => dig4 <= not "0110011"; --51
when 5 => dig4 <= not "1011011"; --91
when 6 => dig4 <= not "1011111"; --95
when others => dig4 <= "1111111";
end case;
case h1 is
when 0 => dig5 <= not "1111110"; --126
when 1 => dig5 <= not "0110000"; --48
when 2 => dig5 <= not "1101101"; --109
when 3 => dig5 <= not "1111001"; --121
when 4 => dig5 <= not "0110011"; --51
when 5 => dig5 <= not "1011011"; --91
when 6 => dig5 <= not "1011111"; --95
when 7 => dig5 <= not "1110000";--112
when 8 => dig5 <= not "1111111"; --127
when 9 => dig5 <= not "1111011";--123
when others => dig5 <= "1111111";
end case;
case h2 is
when 0 => dig6 <= not "1111110"; --126
when 1 => dig6 <= not "0110000"; --48
when 2 => dig6 <= not "1101101"; --109
when 3 => dig6 <= not "1111001"; --121
when 4 => dig6 <= not "0110011"; --51
when 5 => dig6 <= not "1011011"; --91
when 6 => dig6 <= not "1011111"; --95
when others => dig6 <= "1111111";
end case;
end process;
END ARCHITECTURE;