Você está na página 1de 5

DESCRIÇÃO VHDL RELÓGIO

-- relogio digital para placa nexys 2 - digilent


-- by Leandro J. Cassol - Unilasalle

library ieee;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity relogio is
port (clock : in std_logic;
-- porta de entrada para o clock do sistema
reset : in std_logic;
-- porta de entrada para o reset do sistema
ajusta_minuto : in std_logic; -- porta de
entrada para o ajuste dos minutos do sistema
ajusta_hora : in std_logic; -- porta de
entrada para o ajuste das horas do sistema
anodes : out std_logic_vector(3 downto 0); -- sinal para multiplexar displayers
display_sete_segmentos : out std_logic_vector(6 downto 0) -- porta de saida. Sai sinal BCD para as displayers
);
end relogio;

architecture Behavioral of relogio is


type tipo_estado is (D0,D1,D2,D3);
signal fsm: tipo_estado;
signal muda_display : std_logic;
signal controle_mux : std_logic_vector (0 to 2);

signal contador_muda_display : integer :=0;


signal segundo, minuto, hora : integer :=0 ;
signal contador_clock : integer :=0;
signal ck_1hz : std_logic ;
signal saida_mux, display1_hora, display2_hora, display1_minuto, display2_minuto, display1_segundo, display2_segundo :integer :=0 ;
signal codigo_bcd_display : std_logic_vector(6 downto 0);

begin -- divisor de frequencias - transforma um clock de 50MHz


para 1Hz
divisor_de_clock : process(clock) --processo de divisão de frequencia para tranformar o clock de 24MHz para 1Hz. (depende do sinal clock)
begin
if(clock'event and clock='1') then
contador_clock <= contador_clock + 1;
contador_muda_display <= contador_muda_display + 1;
if(contador_clock = 49999999) then --o sinal de entrada tem uma frequencia de 50MHz - converte 50Mhz em 1Hz
ck_1hz <= '1';
contador_clock <= 0;
else
ck_1hz <='0';
end if;

if(contador_muda_display = 49999) then --o sinal de entrada tem uma frequencia de 50MHz - converte 50 Mhz em 100KHz
muda_display <= '1';
contador_muda_display <= 0;
else
muda_display <='0';
end if;

end if;
end process divisor_de_clock; --fim do processo de divisão de frequencias

-- contador das horas, minutos e segundos. E botão de ajuste das horas e dos minutos.
relogio : process(ck_1hz, reset) --processo relógio (depende dos sinais de ck_1hz e reset)
begin
if (reset = '1') then
segundo <= 0; --zera o contador dos segundos quando reset for igual a
zero
minuto <= 0; --zera o contador dos minutos quando reset for igual a zero
hora <= 0; --zera o contador das horas quando reset for igual a zero
elsif(ck_1hz'event and ck_1hz='1') then --a partir desta linha e dentro deste processo todos o sinais são atualizados em função do sinal ck_1hz
segundo <= segundo + 1; --incrementa o contador dos segundos no evento de clock (sinal ck_1hz)
if (ajusta_minuto='1') then --incrementa o contador dos minuntos quando o sinal ajusta_minuto for igual a 1
minuto <= minuto + 1; --incrementa o contador dos minutos quando o sinal ajusta_minuto for igual a 1
if (minuto = 59) then --
minuto <= 0; --zera contador dos minutos quando apos a contagem ser 59
hora <= hora + 1; --incrementa o contador das horas em uma unidade apos a contagem
dos minutos ser 59
if (hora = 23) then --
hora <= 0; --zera contador de horas após a contagem ser 23
end if;
end if; --finaliza a dependencia do sinal de
ajsuta_min=1
elsif (ajusta_hora='1') then --incrementa o contador dos minuntos quando o sinal ajusta_hora for igual a 1
hora <= hora + 1; --incrementa o contador das horas quando o sinal ajusta_hora for igual a
1
if (hora = 23) then --
hora <= 0; --zera o contador das horas após a contagem ser 23
end if; --finaliza a dependencia do sinal de
ajusta_hora=1
elsif(segundo = 59) then --a partir desta linha a contagem dos segundos, minutos e horas não depende dos sinais de ajusta_minuto e
ajusta_hora, ou seja quando os sinais ajusta_minuto e ajusta_hora possuem o valor 0(zero)
segundo <= 0; --o contador de segundos é zerado após chegar em 59
minuto <= minuto + 1; --incrementa o contador dos minutos em uma unidade após a contagem dos segundos ter o valor 59.
if(minuto = 59) then --
minuto <= 0; --zera o contador dos minutos após chegar no valor 59
hora <= hora + 1; --incrementa o contador das horas em uma unidade após a contagems
dos minutos ter o valor de 59.
if(hora = 23) then --
hora <= 0; --zera o contador das horas
end if;
end if;
end if; --fim dos processos de contagem das horas,
minutos e segundos (enquanto os sinais ajusta_minuto e ajusta_hora estao em zero)
end if;
end process relogio; --fim do processo relógio

mostra_valor_hora: process (hora) --inicio do processo para mostrar valor das horas em dois display de sete segmentos (dependente do contador das
horas)
begin
if (hora >= 0 and hora <= 9) then --se o valor do contador de horas está entre 0 e 9 então
display1_hora <= 0; --sinal display1_hora recebe o valor zero (o 1° display das
horas recebe o valor zero)
display2_hora <= hora; --sinal display2_hora recebe o valor hora (o 2° display das horas recebe
o valor do contador das horas)
elsif (hora >= 10 and hora <= 19) then --Se o valor do contador de horas está entre 10 e 19 então
display1_hora <= 1; --sinal display1_hora recebe o valor 1 (o 1° display das
horas recebe o valor 1)
display2_hora <= hora - 10; --sinal display2_hora recebe o valor hora menos 10 (o 2° display das horas recebe o valor do contador
das horas menos 10)
elsif (hora >= 20 and hora <= 23) then --Se o valor do contador de horas está entre 20 e 23 então
display1_hora <= 2; --sinal display1_hora recebe o valor 2 (o 1° display das
horas recebe o valor 2)
display2_hora <= hora - 20; --sinal display2_hora recebe o valor hora menos 20 (o 2° display das horas recebe o valor do contador
das horas menos 20)
end if;
end process mostra_valor_hora; --fim do processo para mostrar o valor das horas

mostra_valor_minuto: process(minuto) --inicio do processo para mostrar valor dos minutos em dois display de sete segmentos (dependente do contador
dos minuto)
begin
if (minuto >= 0 and minuto <= 9) then --se o valor do contador de minutos está entre 0 e 9 então
display1_minuto <= 0; --sinal display1_minuto recebe o valor zero (o 1° display
dos minutos recebe o valor zero)
display2_minuto <= minuto; --sinal display2_minuto recebe o valor minuto (o 2° display dos minutos
recebe o valor do contador dos minutos)
elsif (minuto >= 10 and minuto <= 19) then --se o valor do contador de minutos está entre 10 e 19 então
display1_minuto <= 1; --sinal display1_minuto recebe o valor 1 (o 1° display dos
minutos recebe o valor 1)
display2_minuto <= minuto - 10; --sinal display2_minuto recebe o valor minuto menos 10(o 2° display dos minutos
recebe o valor do contador dos minutos menos 10)
elsif (minuto >= 20 and minuto <= 29) then --se o valor do contador de minutos está entre 20 e 29 então
display1_minuto <= 2; --sinal display1_minuto recebe o valor 2 (o 1° display dos
minutos recebe o valor 2)
display2_minuto <= minuto - 20; --sinal display2_minuto recebe o valor minuto menos 20(o 2° display dos minutos
recebe o valor do contador dos minutos menos 20)
elsif (minuto >= 30 and minuto <= 39) then --se o valor do contador de minutos está entre 30 e 39 então
display1_minuto <= 3; --sinal display1_minuto recebe o valor 3 (o 1° display dos
minutos recebe o valor 3)
display2_minuto <= minuto - 30; --sinal display2_minuto recebe o valor minuto menos 30(o 2° display dos minutos
recebe o valor do contador dos minutos menos 30)
elsif (minuto >= 40 and minuto <= 49) then --se o valor do contador de minutos está entre 40 e 49 então
display1_minuto <= 4; --sinal display1_minuto recebe o valor 4 (o 1° display dos
minutos recebe o valor 4)
display2_minuto <= minuto - 40; --sinal display2_minuto recebe o valor minuto menos 40(o 2° display dos minutos
recebe o valor do contador dos minutos menos 40)
elsif (minuto >= 50 and minuto <= 59) then --se o valor do contador de minutos está entre 50 e 59 então
display1_minuto <= 5; --sinal display1_minuto recebe o valor 5 (o 1° display dos
minutos recebe o valor 5)
display2_minuto <= minuto - 50; --sinal display2_minuto recebe o valor minuto menos 50(o 2° display dos minutos
recebe o valor do contador dos minutos menos 50)
end if;
end process mostra_valor_minuto; --fim do processo para mostrar o valor dos minutos

mostra_valor_segundo: process(segundo) --inicio do processo para mostrar valor dos segundos em dois display de sete segmentos (dependente do contador
dos segundos)
begin
if (segundo >= 0 and segundo <= 9) then --se o valor do contador de segundos está entre 0 e 9 então
display1_segundo <= 0; --sinal display1_segundo recebe o valor zero (o 1° display
dos segundos recebe o valor zero)
display2_segundo <= segundo; --sinal display2_segundo recebe o valo segundo(o 2° display dos
segundos recebe o valor do contador dos segundos)
elsif (segundo >= 10 and segundo <= 19) then --se o valor do contador de segundos está entre 10 e 19 então
display1_segundo <= 1; --sinal display1_segundo recebe o valor 1 (o 1° display dos
segundos recebe o valor 1)
display2_segundo <= segundo - 10; --sinal display2_segundo recebe o valor segundo menos 10(o 2° display dos segundos recebe o valor
do contador dos segundos menos 10)
elsif (segundo >= 20 and segundo <= 29) then --se o valor do contador de segundos está entre 20 e 29 então
display1_segundo <= 2; --sinal display1_segundo recebe o valor 2 (o 1° display dos
segundos recebe o valor 2)
display2_segundo <= segundo - 20; --sinal display2_segundo recebe o valor segundo menos 20(o 2° display dos segundos recebe o valor
do contador dos segundos menos 20)
elsif (segundo >= 30 and segundo <= 39) then --se o valor do contador de segundos está entre 30 e 39 então
display1_segundo <= 3; --sinal display1_segundo recebe o valor 3 (o 1° display dos
segundos recebe o valor 3)
display2_segundo <= segundo - 30; --sinal display2_segundo recebe o valor segundo menos 30(o 2° display dos segundos recebe o valor
do contador dos segundos menos 30)
elsif (segundo >= 40 and segundo <= 49) then --se o valor do contador de segundos está entre 40 e 49 então
display1_segundo <= 4; --sinal display1_segundo recebe o valor 4 (o 1° display dos
segundos recebe o valor 4)
display2_segundo <= segundo - 40; --sinal display2_segundo recebe o valor segundo menos 40(o 2° display dos segundos recebe o valor
do contador dos segundos menos 40)
elsif (segundo >= 50 and segundo <= 59) then --se o valor do contador de segundos está entre 50 e 59 então
display1_segundo <= 5; --sinal display1_segundo recebe o valor 5 (o 1° display dos
segundos recebe o valor 5)
display2_segundo <= segundo - 50; --sinal display2_segundo recebe o valor segundo menos 50(o 2° display dos segundos recebe o valor
do contador dos segundos menos 50)
end if;
end process mostra_valor_segundo;

-- multiplexador para selecionar o digito que será mostrado


with controle_mux select
saida_mux <= display1_hora WHEN "000",
display2_hora WHEN "001",
display1_minuto WHEN "010",
display2_minuto WHEN "011",
display1_segundo WHEN "100",
display2_segundo WHEN "101",
0 WHEN OTHERS;

-- decodificador BCD/7 segmentos


with saida_mux select
codigo_bcd_display <= "1111110" WHEN 0,
"0110000" WHEN 1,
"1101101" WHEN 2,
"1111001" WHEN 3,
"0110011" WHEN 4,
"1011011" WHEN 5,
"1011111" WHEN 6,
"1110000" WHEN 7,
"1111111" WHEN 8,
"1111011" WHEN 9,
"1111110" WHEN OTHERS;

--multiplexador para selecionar o display de sete segmentos da placa Nexys2

maquina_estados: process (clock, muda_display) -- aqui vamos descrever somente a transição de estados. Cada estado corresponde a um Display.
begin
if reset='1' then
fsm <= D0;
elsif (clock'EVENT and clock='1') then
case fsm is
when D0 => -- primeiro display, contando da esquerda
if muda_display='0' then
fsm <= D0;
else
fsm <= D1;
end if;
anodes <= "0111";
controle_mux <= "010";
when D1 => -- segundo display, contando da esquerda
if muda_display='0' then
fsm <= D1;
else
fsm <= D2;
end if;
anodes <= "1011";
controle_mux <= "011";
when D2 => -- terceiro display, contando da esquerda
if muda_display='0' then
fsm <= D2;
else
fsm <= D3;
end if;
anodes <= "1101";
controle_mux <= "100";
when D3 => -- quarto display, contando da esquerda
if muda_display='0' then
fsm <= D3;
else
fsm <= D0;
end if;
anodes <= "1110";
controle_mux <= "101";
end case;
end if;
end process maquina_estados;

display_sete_segmentos <= not(codigo_bcd_display);

end Behavioral;
Placa Nexys 2 - Digilent

Associação de pinos da placa com a descrição VHDL

NET "clock" LOC = "B8";


NET "reset" LOC = "B18";
NET "ajusta_hora" LOC = "G18";
NET "ajusta_minuto" LOC = "H18";
NET "anodes<3>" LOC = "F15";
NET "anodes<2>" LOC = "C18";
NET "anodes<1>" LOC = "H17";
NET "anodes<0>" LOC = "F17";
NET "display_sete_segmentos<6>" LOC = "L18";
NET "display_sete_segmentos<5>" LOC = "F18";
NET "display_sete_segmentos<4>" LOC = "D17";
NET "display_sete_segmentos<3>" LOC = "D16";
NET "display_sete_segmentos<2>" LOC = "G14";
NET "display_sete_segmentos<1>" LOC = "J17";
NET "display_sete_segmentos<0>" LOC = "H14";

Você também pode gostar