Avaliação 2 - SST
Ir para navegação
Ir para pesquisar
Temporizador
O sistema é composto por três seções: contador, drivers do display e display de sete segmentos.
- O contador é a parte sequencial do sistema. Ele deve contar segundos de 00 a 60, iniciando sempre que a entrada de habilitação (enable, ena) for alta e parando sempre que chegar a 60 ou quando enable for abaixada.
- O contador tem uma entrada reset (rst) assíncrona, que zera o sistema sempre que acionada.
- Ao alcançar 60, além do contador parar, a saída full_count deve ser acionada.
- O driver de SSD é a parte combinacional do sistema. Ele deve converter as saídas dos contadores (count1, count2) em sinais de 7 bits (dig1, dig2) para alimentar o mostrador de dois dígitos.
library ieee; use ieee.std_logic_1164.all; entity timer is generic (fclk : INTEGER :=2) ; --clock frequency port (clk, rst, ena: IN std_logic; full_count : OUT std_logic; dig1, dig2: OUT std_logic_vector (6 downto 0)); --7 bits, display de 7 segmentos end timer architecture timer of timer is begin process(clk, rst, ena) variable count0: INTEGER RANGE 0 to fclk; --para 1HZ variable count1: INTEGER RANGE 0 to 10; --para dig1 variable count2: INTEGER RANGE 0 to 7; -- para dig2 begin --counters if (rst='1') then count0 := 0; count1 := 0; count2 := 0; full_count <= '0'; elseif (count1=0 and count2=6) then full_count <='1'; elseif (clk'EVENT and clk='1') then if (ena='1') then count0 := count0 + 1; if (count0=fclk) then count0 := 0; count1 := count1 + 1; if (count1=10) then count1 := 0; count2 := count2 + 1; end if; end if; end if; end if; --ssd drivers case count1 is when 0 => dig1 <= “1111110”; --126 when 1 => dig1 <= “0110000”; --48 when 2 => dig1 <= “1101101”; --109 when 3 => dig1 <= “1111001”; --121 when 4 => dig1 <= “0110011”; --51 when 5 => dig1 <= “1011011”; --91 when 6 => dig1 <= “1011111”; --95 when 7 => dig1 <= “1110000”;--112 when 8 => dig1 <= “1111111”; --127 when 9 => dig1 <= “1111011”;--123 when others => dig1 <= “1001111”; --79 (“E”) end case; case count2 is when 0 => dig2 <= “1111110”; --126 when 1 => dig2 <= “0110000”; --48 when 2 => dig2 <= “1101101”; --109 when 3 => dig2 <= “1111001”; --121 when 4 => dig2 <= “0110011”; --51 when 5 => dig2 <= “1011011”; --91 when 6 => dig2 <= “1011111”; --95 when others => dig2 <= “1001111”; --79 (“E”) end case; end process; end timer;
O programa acima tem alguns erros de sintaxe, além de incompatibilidades com o Kit DE2-115. Assim, uma versão para execução no kit, para um relógio até 60 segundos é:
--------------------------------------------------- Pacote library ieee; use ieee.std_logic_1164.all; --------------------------------------------------- Entidade entity relogio2 is generic (fclk : INTEGER := 50000000); -- Frequencia do Clock port ( clk, rst, ena: IN std_logic; -- Sinais de entrada full_count : OUT std_logic; -- LED que acende quando chega no limite da contagem dig_seg, dig_dez: OUT std_logic_vector (0 to 6) -- Displays de 7 segmentos ); end entity; --------------------------------------------------- Arquitetura architecture timer of relogio2 is begin -- A arquitetura consiste em apenas um processo process(clk, rst, ena) -- As variaveis abaixo sao usadas para controle das contagens dos -- valores variable count_clk: INTEGER RANGE 0 to fclk; -- Conta pulsos de clock variable seg: INTEGER RANGE 0 to 10; -- Conta segundos variable dez: INTEGER RANGE 0 to 7; -- Conta dezenas de segundos begin -- Situacao de controle: resetar os contadores if (rst='1') then count_clk := 0; seg := 0; dez := 0; full_count <= '0'; -- Situacao de controle: contagem atingiu o limite superior (60 segundos) elsif (seg=0 and dez=6) then full_count <='1'; -- Situacao normal: passou um periodo de clock, incrementar contadores elsif rising_edge(clk) then if (ena='1') then -- Incrementar contador de clock count_clk := count_clk + 1; -- O limite superior da contagem de pulsos de clock eh justamente -- a frequencia do clock. Se o clock tem 'fclk' Hz, entao se 'cont_clk' -- contar 'fclk' vezes, entao 1 segundo se passou. Se isto aconteceu: if (count_clk=fclk) then -- Zera o contador de pulsos de clock e incrementa o contador de segundos count_clk := 0; seg := seg + 1; -- Quando o contador de segundos atingir seu limite, de uma dezena if (seg=10) then -- Zera o contador de segundos e incrementa o contador de dezenas de segundos seg := 0; dez := dez + 1; end if; end if; end if; end if; -- A area abaixo deve ser descomentada para usar o simulador -- University Program VWF, pois assim os valores que aparecerao -- em dig_seg e dig_dez serao os proprios numeros esperados. Os -- Valores correspondentes ao display de 7 segmentos nao sao bons -- para humanos entenderem. Lembrar de comentar a parte embaixo. -- case seg is -- when 0 => dig_seg <= "0000000"; -- when 1 => dig_seg <= "0000001"; -- when 2 => dig_seg <= "0000010"; -- when 3 => dig_seg <= "0000011"; -- when 4 => dig_seg <= "0000100"; -- when 5 => dig_seg <= "0000101"; -- when 6 => dig_seg <= "0000110"; -- when 7 => dig_seg <= "0000111"; -- when 8 => dig_seg <= "0001000"; -- when 9 => dig_seg <= "0001001"; -- when others => dig_seg <= "1000000"; -- end case; -- case dez is -- when 0 => dig_dez <= "0000000"; -- when 1 => dig_dez <= "0000001"; -- when 2 => dig_dez <= "0000010"; -- when 3 => dig_dez <= "0000011"; -- when 4 => dig_dez <= "0000100"; -- when 5 => dig_dez <= "0000101"; -- when 6 => dig_dez <= "0000110"; -- when others => dig_dez <= "1000000"; -- end case; -- O bloco abaixo realiza a conversao dos valores decimais para -- o display de 7 segmentos. Em caso de simulacao, se o bloco acima -- for descomentado, lembrar de comentar este aqui. case seg is when 0 => dig_seg <= "0000001"; --0 when 1 => dig_seg <= "1001111"; --1 when 2 => dig_seg <= "0010010"; --2 when 3 => dig_seg <= "0000110"; --3 when 4 => dig_seg <= "1001100"; --4 when 5 => dig_seg <= "0100100"; --5 when 6 => dig_seg <= "0100000"; --6 when 7 => dig_seg <= "0001111"; --7 when 8 => dig_seg <= "0000000"; --8 when 9 => dig_seg <= "0000100"; --9 when others => dig_seg <= "0110000"; --“E” end case; case dez is when 0 => dig_dez <= "0000001"; --0 when 1 => dig_dez <= "1001111"; --1 when 2 => dig_dez <= "0010010"; --2 when 3 => dig_dez <= "0000110"; --3 when 4 => dig_dez <= "1001100"; --4 when 5 => dig_dez <= "0100100"; --5 when 6 => dig_dez <= "0100000"; --6 when others => dig_dez <= "0110000"; --“E” end case; end process; end architecture;
Medidor de Frequência
- x é o sinal cuja frequência queremos medir.
- Uma janela de tempo é criada a partir do clock (com duração de 1s, por exemplo) e o número de pulsos com x dentro dela é contado.
- O período de x (ou vários períodos) é usado como janela de tempo e o número de pulsos do clock dentro dela é contado.
- O contador 1 divide a frequência do clock por n+1, criando uma forma de onda que permanece baixa durante nTo segundos e alta durando To segundos, onde To é o período do clock.
- Escolhendo n=fclk, obtém-se uma janela de tempo baixa (twindow) de 1s. Essa forma de onda provoca o armazenamento da saída do contador 2 no registrador em sua borda ascendente, e também reseta o contador 2, que é liberado para começar a contar novamente após um período de clock.
library ieee; use ieee.std_logic_1164.all; entity freq_meter is generic (fclk: INTEGER := 5; --frequencia clock fxmax: INTEGER :=15); --max fx port (clk, x : IN bit; test : OUT bit; --para visualizar janela de tempo baixa fx : OUT INTEGER RANGE 0 to fxmax); end freq_meter; architecture behavioral of freq_meter is signal twindow: bit; signal temp: INTEGER RANGE 0 to fxmax; begin --time window process (clk) variable count: INTEGER RANGE 0 to fclk; begin if (clk'EVENT and clk='1') then count := count + 1; if (count=fclk) then twindow <= '1'; elsif (count=fclk+1) then twindow <= '0'; count := 0; end if; end if; end process; --counter for x process (x, twindow) variable count : INTEGER RANGE 0 to 20; begin if (twindow='1') then count := 0; elseif (x'EVENT and x='1') then count := count + 1; end if; temp <= count; end process; --register process (twindow) begin if (twindow'EVENT and twindow='1') then fx <= temp; end if; end process; test <= twindow; end behavioral;