Revisão 3: Decodificador de Endereços

Objetivos

  1. Aplicar decodificadores ao endereçamento dos periféricos.

Contextualização

Um computador, por mais simples que seja, necessita de outros módulos para funcionar. Um computador, com uma arquitetura minimalista, possui ao menos três módulos:

O processador precisa ser interligado a esses periféricos para que ocorra a leitura ou escrita dos mesmos. Isso é implementado através da criação de barramentos, que são conjuntos de sinais que percorrem todo o computador, fazendo a interligação de todos os periféricos e o processador. Esses sinais são agrupados conforme a suas funções. Comumente, temos os barramentos de:

Decodificação de Endereços
Decodificação de Endereços

Como esses barramentos são compartilhados, somente um periférico, por vez, pode utilizar o barramento. Portanto, é necessário fazer um tipo de arbitragem para o seu acesso.

Para acessar cada um desses módulos, tanto para escrita quanto para leitura, o processador coloca o endereço do módulo no barramento de endereços e o decodificador de endereços ativa o módulo correspondente e somente esse módulo tem acesso ao barramento de dados. Isso é feito através das instruções de leitura e escrita na memória, que se utilizam do barramento de dados para ler ou escrever em uma dada posição da memória.

Ou seja, o decodificador de endereços dá ao módulo o direito de utilizar o barramento para receber a comunicação do processador.


Atividade: Seleção de Periféricos

Decodificação de Endereço
Decodificação de Endereço

Top Level = AulaDelta3.vhd

library ieee;
use ieee.std_logic_1164.all;

entity AulaDelta3 is
   generic (
          larguraContagem: natural := 4;
          addrWidth: natural := 4
    );
   port (
     CLOCK_50: in std_logic;
       SW: in std_logic_vector(9 downto 0);
     KEY: in std_logic_vector(3 downto 0);
       HEX0, HEX1, HEX2, HEX3 : out std_logic_vector (6 DOWNTO 0);
       LEDR  : out std_logic_vector(9 downto 0)
    );
end entity;

architecture funcionamento of AulaDelta3 is

signal saida_contador, entrada_contador : std_logic_vector(larguraContagem-1 downto 0);
signal CLK, apagaHEX0, apagaHEX1, apagaHEX2, apagaHEX3 : std_logic;

begin

--MUX1 :  entity work.muxGenerico2x1  generic map (larguraDados => larguraContagem)
--        port map( entradaA_MUX => sinalLocal,
--                 entradaB_MUX =>  sinalLocal,
--                 seletor_MUX => sinalLocal,
--                 saida_MUX => sinalLocal);

Somador :  entity work.somaConstante  generic map (larguraDados => larguraContagem, constante => 1)
        port map( entrada => saida_contador, saida => entrada_contador);

Contador : entity work.registradorGenerico   generic map (larguraDados => larguraContagem)
          port map (DIN => entrada_contador, DOUT => saida_contador, ENABLE => '1', CLK => CLK, RST => '0');


DHEX0 :  entity work.conversorHex7Seg
        port map(dadoHex => saida_contador,
                 apaga =>  not apagaHEX0,
                 negativo => '0',
                 overFlow =>  '0',
                 saida7seg => HEX0);

DHEX1 :  entity work.conversorHex7Seg
        port map(dadoHex => saida_contador,
                 apaga =>  not apagaHEX1,
                 negativo => '0',
                 overFlow =>  '0',
                 saida7seg => HEX1);

DHEX2 :  entity work.conversorHex7Seg
        port map(dadoHex => saida_contador,
                 apaga =>  not apagaHEX2,
                 negativo => '0',
                 overFlow =>  '0',
                 saida7seg => HEX2);

DHEX3 :  entity work.conversorHex7Seg
        port map(dadoHex => saida_contador,
                 apaga =>  not apagaHEX3,
                 negativo => '0',
                 overFlow =>  '0',
                 saida7seg => HEX3);

divisor : entity work.divisorGenerico
            generic map (divisor => 25000000)   -- divide por 50M.
            port map (clk => CLOCK_50, saida_clk => CLK);

endereco: entity work.decoder1x4
  port map(addr => SW(1) & SW(0), saida_Decoder(3) => apagaHEX3, saida_Decoder(2) => apagaHEX2, saida_Decoder(1) => apagaHEX1, saida_Decoder(0) => apagaHEX0);

LEDR <= SW;
end architecture;



conversorHex7Seg.vhd

library IEEE;
use ieee.std_logic_1164.all;

entity conversorHex7Seg is
    port
    (
        -- Input ports
        dadoHex : in  std_logic_vector(3 downto 0);
        apaga   : in  std_logic := '0';
        negativo : in  std_logic := '0';
        overFlow : in  std_logic := '0';
        -- Output ports
        saida7seg : out std_logic_vector(6 downto 0)  -- := (others => '1')
    );
end entity;

architecture comportamento of conversorHex7Seg is
   --
   --       0
   --      ---
   --     |   |
   --    5|   |1
   --     | 6 |
   --      ---
   --     |   |
   --    4|   |2
   --     |   |
   --      ---
   --       3
   --
    signal rascSaida7seg: std_logic_vector(6 downto 0);
begin
    rascSaida7seg <=    "1000000" when dadoHex="0000" else ---0
                            "1111001" when dadoHex="0001" else ---1
                            "0100100" when dadoHex="0010" else ---2
                            "0110000" when dadoHex="0011" else ---3
                            "0011001" when dadoHex="0100" else ---4
                            "0010010" when dadoHex="0101" else ---5
                            "0000010" when dadoHex="0110" else ---6
                            "1111000" when dadoHex="0111" else ---7
                            "0000000" when dadoHex="1000" else ---8
                            "0010000" when dadoHex="1001" else ---9
                            "0001000" when dadoHex="1010" else ---A
                            "0000011" when dadoHex="1011" else ---B
                            "1000110" when dadoHex="1100" else ---C
                            "0100001" when dadoHex="1101" else ---D
                            "0000110" when dadoHex="1110" else ---E
                            "0001110" when dadoHex="1111" else ---F
                            "1111111"; -- Apaga todos segmentos.

    saida7seg <=     "1100010" when (overFlow='1') else
                            "1111111" when (apaga='1' and negativo='0') else
                            "0111111" when (apaga='0' and negativo='1') else
                            rascSaida7seg;
end architecture;



divisorGenerico.vhd

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use ieee.numeric_std.all;

entity divisorGenerico is
generic (divisor : natural := 8);
    port(
      clk      :   in std_logic;
      saida_clk :   out std_logic);
end entity;

-- O valor "n" do divisor, define a divisao por "2n".
-- Ou seja, n é metade do período da frequência de saída.

architecture divInteiro of divisorGenerico is
    signal tick : std_logic := '0';
    signal contador : integer range 0 to divisor+1 := 0;
begin
    process(clk)
    begin
        if rising_edge(clk) then
            if contador = divisor then
                contador <= 0;
                tick <= not tick;
            else
                contador <= contador + 1;
            end if;
        end if;
    end process;
saida_clk <= tick;
end architecture divInteiro;



muxGenerico2x1.vhd

library ieee;
use ieee.std_logic_1164.all;

entity muxGenerico2x1 is
  -- Total de bits das entradas e saidas
  generic ( larguraDados : natural := 8);
  port (
    entradaA_MUX, entradaB_MUX : in std_logic_vector((larguraDados-1) downto 0);
    seletor_MUX : in std_logic;
    saida_MUX : out std_logic_vector((larguraDados-1) downto 0)
  );
end entity;

architecture comportamento of muxGenerico2x1 is
  begin
    saida_MUX <= entradaB_MUX when (seletor_MUX = '1') else entradaA_MUX;
end architecture;



decoder1x4.vhd

library ieee;
use ieee.std_logic_1164.all;

entity decoder1x4 is
  port (
    addr : in std_logic_vector(1 downto 0);
    saida_Decoder : out std_logic_vector(3 downto 0)
  );
end entity;

architecture comportamento of decoder1x4 is
  begin
    saida_Decoder(0) <= not(addr(1)) AND not(addr(0));
   saida_Decoder(1) <= not(addr(1)) AND addr(0);
   saida_Decoder(2) <= addr(1) AND not(addr(0));
   saida_Decoder(3) <= addr(1) AND addr(0);
end architecture;



registradorGenerico.vhd

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity registradorGenerico is
    generic (
        larguraDados : natural := 8
    );
    port (DIN : in std_logic_vector(larguraDados-1 downto 0);
       DOUT : out std_logic_vector(larguraDados-1 downto 0);
       ENABLE : in std_logic;
       CLK,RST : in std_logic
        );
end entity;

architecture comportamento of registradorGenerico is
begin
    -- In Altera devices, register signals have a set priority.
    -- The HDL design should reflect this priority.
    process(RST, CLK)
    begin
        -- The asynchronous reset signal has the highest priority
        if (RST = '1') then
            DOUT <= (others => '0');    -- Código reconfigurável.
        else
            -- At a clock edge, if asynchronous signals have not taken priority,
            -- respond to the appropriate synchronous signal.
            -- Check for synchronous reset, then synchronous load.
            -- If none of these takes precedence, update the register output
            -- to be the register input.
            if (rising_edge(CLK)) then
                if (ENABLE = '1') then
                        DOUT <= DIN;
                end if;
            end if;
        end if;
    end process;
end architecture;



somaConstante.vhd

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;  --Soma (esta biblioteca =ieee)

entity somaConstante is
    generic
    (
        larguraDados : natural := 32;
        constante : natural := 4
    );
    port
    (
        entrada: in  STD_LOGIC_VECTOR((larguraDados-1) downto 0);
        saida:   out STD_LOGIC_VECTOR((larguraDados-1) downto 0)
    );
end entity;

architecture comportamento of somaConstante is
    begin
        saida <= std_logic_vector(unsigned(entrada) + constante);
end architecture;



Configuração de Pinos = AulaDelta3.qsf

Adicionar ao fim do arquivo qsf gerado pelo Quartus

#============================================================
# FAMILY "Cyclone V"
# DEVICE 5CEBA4F23C7N
# Board DE0-CV
#============================================================

# Inicio da configuração dos pinos.

#============================================================
# CLOCK
#============================================================
set_location_assignment PIN_M9 -to CLOCK_50
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to CLOCK_50

#============================================================
# HEX0
#============================================================
set_location_assignment PIN_U21 -to HEX0[0]
set_location_assignment PIN_V21 -to HEX0[1]
set_location_assignment PIN_W22 -to HEX0[2]
set_location_assignment PIN_W21 -to HEX0[3]
set_location_assignment PIN_Y22 -to HEX0[4]
set_location_assignment PIN_Y21 -to HEX0[5]
set_location_assignment PIN_AA22 -to HEX0[6]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX0[0]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX0[1]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX0[2]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX0[3]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX0[4]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX0[5]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX0[6]
set_instance_assignment -name CURRENT_STRENGTH_NEW DEFAULT -to HEX0
set_instance_assignment -name SLEW_RATE 1 -to HEX0

#============================================================
# HEX1
#============================================================
set_location_assignment PIN_AA20 -to HEX1[0]
set_location_assignment PIN_AB20 -to HEX1[1]
set_location_assignment PIN_AA19 -to HEX1[2]
set_location_assignment PIN_AA18 -to HEX1[3]
set_location_assignment PIN_AB18 -to HEX1[4]
set_location_assignment PIN_AA17 -to HEX1[5]
set_location_assignment PIN_U22 -to HEX1[6]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX1[0]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX1[1]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX1[2]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX1[3]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX1[4]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX1[5]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX1[6]
set_instance_assignment -name CURRENT_STRENGTH_NEW DEFAULT -to HEX1
set_instance_assignment -name SLEW_RATE 1 -to HEX1

#============================================================
# HEX2
#============================================================
set_location_assignment PIN_Y19 -to HEX2[0]
set_location_assignment PIN_AB17 -to HEX2[1]
set_location_assignment PIN_AA10 -to HEX2[2]
set_location_assignment PIN_Y14 -to HEX2[3]
set_location_assignment PIN_V14 -to HEX2[4]
set_location_assignment PIN_AB22 -to HEX2[5]
set_location_assignment PIN_AB21 -to HEX2[6]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX2[0]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX2[1]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX2[2]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX2[3]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX2[4]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX2[5]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX2[6]
set_instance_assignment -name CURRENT_STRENGTH_NEW DEFAULT -to HEX2
set_instance_assignment -name SLEW_RATE 1 -to HEX2

#============================================================
# HEX3
#============================================================
set_location_assignment PIN_Y16 -to HEX3[0]
set_location_assignment PIN_W16 -to HEX3[1]
set_location_assignment PIN_Y17 -to HEX3[2]
set_location_assignment PIN_V16 -to HEX3[3]
set_location_assignment PIN_U17 -to HEX3[4]
set_location_assignment PIN_V18 -to HEX3[5]
set_location_assignment PIN_V19 -to HEX3[6]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX3[0]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX3[1]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX3[2]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX3[3]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX3[4]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX3[5]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX3[6]
set_instance_assignment -name CURRENT_STRENGTH_NEW DEFAULT -to HEX3
set_instance_assignment -name SLEW_RATE 1 -to HEX3

#============================================================
# KEY
#============================================================
set_location_assignment PIN_U7 -to KEY[0]
set_location_assignment PIN_W9 -to KEY[1]
set_location_assignment PIN_M7 -to KEY[2]
set_location_assignment PIN_M6 -to KEY[3]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to KEY[0]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to KEY[1]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to KEY[2]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to KEY[3]

#============================================================
# LEDR
#============================================================
set_location_assignment PIN_AA2 -to LEDR[0]
set_location_assignment PIN_AA1 -to LEDR[1]
set_location_assignment PIN_W2 -to LEDR[2]
set_location_assignment PIN_Y3 -to LEDR[3]
set_location_assignment PIN_N2 -to LEDR[4]
set_location_assignment PIN_N1 -to LEDR[5]
set_location_assignment PIN_U2 -to LEDR[6]
set_location_assignment PIN_U1 -to LEDR[7]
set_location_assignment PIN_L2 -to LEDR[8]
set_location_assignment PIN_L1 -to LEDR[9]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LEDR[0]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LEDR[1]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LEDR[2]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LEDR[3]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LEDR[4]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LEDR[5]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LEDR[6]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LEDR[7]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LEDR[8]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LEDR[9]

set_instance_assignment -name CURRENT_STRENGTH_NEW DEFAULT -to LEDR
set_instance_assignment -name SLEW_RATE 1 -to LEDR

#============================================================
# SW
#============================================================
set_location_assignment PIN_U13 -to SW[0]
set_location_assignment PIN_V13 -to SW[1]
set_location_assignment PIN_T13 -to SW[2]
set_location_assignment PIN_T12 -to SW[3]
set_location_assignment PIN_AA15 -to SW[4]
set_location_assignment PIN_AB15 -to SW[5]
set_location_assignment PIN_AA14 -to SW[6]
set_location_assignment PIN_AA13 -to SW[7]
set_location_assignment PIN_AB13 -to SW[8]
set_location_assignment PIN_AB12 -to SW[9]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SW[0]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SW[1]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SW[2]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SW[3]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SW[4]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SW[5]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SW[6]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SW[7]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SW[8]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SW[9]

#====================================================================
# Fim da configuração dos pinos utilizados em Design de Computadores.
#====================================================================