Avaliação 2 - SST

De MediaWiki do Campus São José
Revisão de 11h27min de 24 de abril de 2018 por Diegomedeiros (discussão | contribs) (→‎Temporizador)
(dif) ← Edição anterior | Revisão atual (dif) | Versão posterior → (dif)
Ir para navegação Ir para pesquisar


Temporizador

Temporizador2.jpg

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

Medidor.jpg

  • 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;