Portal - FPGA para Todos

Memória RAM com Saída Temporizada

Memória RAM com Saída Temporizada - Placa DE0

O projeto a seguir tem como objetivo apresentar a saída de um memória implementada no FPGA Ciclone III presente na placa DE0 de forma periódica. O projeto fará a leitura dos endereços da memória de forma sequencial e sendo incrementada a cada 0,5s e a escrita pode ser feita concomitantemente com a leitura.

O projeto é implementado em VHDL e simulado com o Modelsim-Altera, por meio de testbench sendo este um exemplo de circuito sequencial.

 Nesse projeto será utilizado apenas a Placa DE0®.

Descrição do Funcionamento

Para este projeto será implementado uma memória de 8 x 8, a qual poderá ser lida e escrita ao mesmo tempo. O projeto também apresentará um contador interno para temporizar a saída, de forma que a cada 0,5s incrementa o endereço de memória lido. O projeto utilizará 9 chaves, sendo 1 de chip enable e 8 para a escrita de dados, 2 botões e 8 LEDs para apresentar o dado lido.

Descrição em VHDL

Para implementar memória do projeto criou-se um tipo de varivel usando um array com 8 posições de std_logic_vector de 8 bits, formando assim a memória de 8x8. O preescaler para incrementar o endereço de saída precisa dividir por 25M, pois o clock é de 50Mhz e o objetivo é a mudança do endereço a cada 0,5s.

O Código começa com a declaração da entidade:

entity RAM_vs3 is
    port
    (
        clock, resetn, wren, cen: in std_logic;
        -- Entrada de Dados saida:
        dado: in std_logic_vector (7 downto 0);
        -- Leitura da memoria 
        out std_logic_vector (7 downto 0) -- Leitura da memoria
    );
end entity;

Dentro da architecture se declara o tipo memória para a utilização em seguida do sinal desse tipo,  que será a memória RAM do projeto.

architecture ccomportamento of RAM_vs3 is
    type memoria is array (integer range 0 to 7) of std_logic_vector(7 downto 0);
    signal mem_ram : memoria := ( x"00", x"01", x"02", x"03", x"04", x"05", x"06", x"07");

O processo principal pode ser dividido em quatro partes: reset, escrita, proteção contra ruído e leitura. Primeiramente se declara as variáveis usadas no processo:

process (clock, resetn)
    variable addr_write, addr_read : std_logic_vector(2 downto 0) := "111";
    -- Variavel para evitar ruido de trepidacao
    variable conta : integer range 0 to 25000000 := 0;
    -- variavel usada parra preescaler  
    variable cont: integer range 0 to 25000000;  
    variable flag: std_logic := '0';
 

Quando o reset está pressionado são assumidos os valores padrão de inicio do programa , apresentados abaixo:

 

begin
if resetn = '0' then
    addr_write := "111";
    addr_read := "111";
    cont := 0;
    conta := 0;
    flag := '0';
saida

A escrita possui quatro variáveis de controle: wren, cen, flag, conta. O signal wren (write enable) indica se foi solicitado a escrita de um dado. A variável cen (chip enable) determina se a memória está habilitada, a flag previne que em uma única requisição seja gravado um dado em mais de um endereço de memória. Por último, a variável conta tem por objetivo rejeitar o ruído de trepidação gerado ao pressionar o botão.

elsif clock'event and clock = '1' then
    -- Flag serve para evitar que grave em varias posicoes de
    -- memória com um mesmo pulso e conta serve para evitar
    -- o ruido de trepidacao proveniente do push bottom
    if wren = '0' and cen = '0' and flag = '0' and conta = 25000000 then
        conta := 0;
        addr_write := addr_write + "001";
        mem_ram (to_integer(unsigned(addr_write))) flag := '1';
    elsif wren = '1' then flag := '0';
end if;

A proteção contra ruído funciona como um delay para que possa ser feita a próxima gravação, nesse caso adotou-se 0,5s.

 

-- contagem para evitar ruido de trepidacao
if conta < 25000000 then
    conta := conta + 1;
end if;

A leitura ocorre enquanto o cen está habilitado. Para a leitura há um prescaler de 25M para que o endereço lido só seja incrementado a cada 0,5s. Quando o cen não está habilitado, atribui-se alta impedância para a saída.

if cen = '0' then
    cont := cont + 1;
    if cont = 25000000 then
        cont := 0;
        addr_read := addr_read + "001";
        saida <= mem_ram(to_integer(unsigned(addr_read)));
    end if;
else saida <= "ZZZZZZZZ";
end if;

Simulação

Para simular o funcionamento da memória será mandado o comando de gravação de alguns dados e ler os dados gravados. Para diminuir o tempo da simulação alterou-se o topo do valor da variável  responsável pela proteção contra ruído para 3. O código do testbench é composto por duas partes: a geração de clock e a simulação de leitura e escrita. Abaixo segue o processo responsável pela geração de clock:

 

gera_clock: process
    begin
    for cont in 0 to 100 loop
        CLOCK <= '0';
        wait for 1 ms;
        CLOCK <= '1';
        wait for 1 ms;
    end loop;
    wait;
end process;

A simulação de escrita e leitura inicia simulando o precionamento do botão de reset e o cen desabilitado.

process
    begin
    ce <= '1';
    resetn <= '0';
    dado <= x"00";
    wren <= '1';
    wait for 5 ms;

Em seguida, atribui-se os valores de reset e cen de forma que o projeto possa funcionar.

    ce <= '0';
    wait for 5 ms;
    resetn <= '1';
    wait for 5 ms;

O passo seguinte é mandar os pulsos de escrita e de leitura para observar se o projeto funcionará como esperado. Note que há uma sequencia de pulsos de habilitação de escrita para testar a proteção contra ruído.

 

    wren <= '0';
    wait for 1 ms;
    wren <= '1';
    wait for 1 ms;
    wren <= '0';
    wait for 2 ms;
    wren <='1';
    dado <= x"AA";
    wait for 1 ms;
    wren <= '0';
    wait for 5 ms;
    wren <='1';
    wait for 10 ms;
    ce <= '1';
    wait for 5 ms;
    ce <= '0';
    wait for 5 ms;
    dado <= x"F0";
    wren <= '0';
    wait for 2 ms;
    wren <= '1';
    wait;
end process;

O resultado obtido na simulação pode ser observado pelas formas de onda abaixo:

 foram_onda_1

Figura 2: Formas de onda simuladas

forma_onda_2

FIgura 3: Forma de onda simuladas (continuação).

Estrutura Física

 Placa_DE0

Figura 4: Projeto implementado na placa DE0.

O projeto conta apenas com a placa DE0®, de forma a utilizar 8 LEDs representando a saída, 8 chaves para a entrada de dados, 1 chave para a entrada da habilitação de chip, 1 botão de reset, 1 botão de habiliatação de escrita e 1 pino para o clock. Para a atribuição de pinos utilizou-se o manual do usuário da placa DE0®.

pinagem

Figura 5: Atribuição de pinos do projeto

Gravação e Teste

Para fazer o teste basta gravar o programa seguindo as intruções encontradas no tutorial ou no próprio manual da placa DE0. Em seguida basta dar os comandos de gravação  e leitura e observar o resultado. Abaixo segue o video de operação do projeto:

Arquivos de Projeto

Links Externos

Quem está Online

Temos 28 visitantes e Nenhum membro online

Apoio

Login Form