Portal - FPGA para Todos

VGA para FPGA

VGA para FPGA

Figura 1 - Foto do projeto.

Nesta página será apresentado um método de apresentar imagens de um FPGA para um monitor através de uma porta VGA. Para tal tarefa, será feita uma breve explicação do funcionamento da sincronização VGA, um método de enviar imagens e ler ler a memória. Uma vez implementado, o projeto permite  apresentar qualquer imagem, desde que esteja no formato adequado, isto nos permite uma grande variedade de aplicações.

Figura 2 - Imagem mostrada na tela

O projeto a seguir é um exemplo de circuito lógico sequencial, descrito em VHDL e simulado no software ModelSim®-Altera, através de um test bench.

Os dispositivos necessários para a implementação do projeto são:

  • Uma placa  ALTERA DE0.
  • Uma interface serial-VGA.
  • Um monitor com entrada VGA.

Funcionamento da porta VGA

Sincronização

Uma tela no modo VGA é dividida em linhas, cada linha é dividido em pontos (pixels). Geralmente a tela 480 linhas e cada uma com 640 pixels que só podem ser acesos um por vez. Para formamos uma imagem, usamos o efeito da persistência da visão, também usado no projto Multiplexação de 6 algarismos.

Para "enganar" a visão, faremos o monitor apresentar 60 quadros a cada segundo (60 hz), por isso deveremos sincronizar o FPGA com o mesmo, para podermos controlar o que será apresentado.

Para a sincronização com o monitor, precisamos enviar dois pulsos de sincronismo um vertical e um horizontal. O horizontal, apresentado na Figura 2, indica para o monitor que acabou a linha na qual ele estava mostrando os pixels e que ele deve passar para a próxima.

 H_sync

Figura 3 - Sincronismo Horizontal

O vertical, apresentado na Figura 3, indica para o monitor que acabou a tela e que ele deve começar a próxima.

V_sync

Figura 4 - Sincronismo Vertical

Cada pixel apresentará 12 bits para a cor, no modelo RGB que serão enviados através da porta.

Para mais informações sobre o funcionamento da porta VGA , clique aqui.

VGA para FPGA

Blocos do projeto

Para facilitar o entendimento, o projeto foi dividido em componentes como mostra a Figura 5.

VGA_bloco

Figura 5 - Blocos do projeto

Sincronismo

Componente que envia os sinais de sincronismo para o monitor.

 O componente possui um contador de pulsos de clock para marcar o tempo. A DE0 possui um clock de 50MHz, fazemos a contagem de pulsos até completar uma linha, seguindo os tempos de sincronismo apresentados na Figura 3.

Tempo(us)

Pulsos de Clock
25,17 1258
26,11 1306
29,88 1494
31,77 1588

O trecho de código abaixo, apresenta o método utilizado para a sincronização dos sinais responsáveis pelo sincronismo horizontal.

If (cont_x >= H_max) then -- H_max = 1588
     cont_x <= "00000000000";
Else
     cont_x <= cont_x + "00000000001";
End if;  
-- O Horiz_Sync deve permanecer em nível lógico alto por 27,06 us
-- então em baixo por 3,77 us
If (cont_x <= 1494) and (cont_x >= 1306) Then 
     Horiz_Sync <= '0';
ELSE
     Horiz_Sync <= '1';
End if;  
-- Ajusta o tempo do Video_on_H
If (cont_x <= 1258) Then  
     video_on_H <= '1';
ELSE
     video_on_H <= '0';
End if;

Quando a contagem chega ao fim da linha incrementa-se a contagem de linhas. Os sinais de sincronismo são enviados de acordo com os tempos apresentados na Figura 4.

Tempo(ms)

Contagem de Linhas
15,250 479
15,700 495
15,764 496
16,764 528

O trecho de código abaixo, apresenta o método utilizado para a sincronização dos sinais responsáveis pelo sincronismo vertical.

 
If (cont_y >= V_max) and (cont_x >= 736) then 
     cont_y <= "00000000000";
Elsif (cont_x = H_Max) Then  
     cont_y <= cont_y + "00000000001";
End if;  
-- Generate Vertical Sync Signal
If (cont_y <= 496) and (cont_y >= 495) Then
     -- Gera sinal de sincronismo vertical
     Vert_Sync <= '0'; ELSE Vert_Sync <= '1';
End if;  
-- Ajusta o tempo do Video_on_V
If (cont_y <= 479) Then
     video_on_V <= '1';
ELSE
     video_on_V <= '0';
End if;

Esse componente também envia a posição que está sendo escrita no monitor.

     Linha <= cont_y;
     Pixels <= "0" & cont_x(10 downto 1); 
-- Utilizo cont_x descartandando o último bit para dividir por 2 a frequencia            
-- De forma com que o clock seja semelhante ao do monitor.

Memória

A memória foi implementada através de uma megafunção da Altera.

Na memória, está um arquivo .mif(Memory Initialization File) que possui o mapeamento da imagem a ser mostrada na tela. O arquivo .mif é indicado através do MegaWizard, como mostra a figura a Figura 6.

megawizard

Figura 6 - Janela da Megafunção.

O número de bits para o endereço é igual a quantidade de bits do número de pixels que quer se mostrar mais o número de bits de Linhas a serem mostradas [P+L].

VGA

Parte das variáveis Pixels e Linhas,recebidas do componente Sincronismo, são enviadas pro componente Memória o tamanho do endereço:

Enderecamento: process(Linha,Pixels,clock)
begin
 
Address <= NOT Linha(6 downto 0) & Pixels(7 downto 0); 
-- Enviando endereços para a memória:
if (Pixels <= 255) and (Linha <= 127) then
-- utilizo pixels de 8 até 1 descartandando o último bit.
-- isso divide a frequencia por 2 de forma com que o clock seja semelhante ao do monitor.
     RGB <= RGB_temp;
else
     RGB <= "000000000000";
end if;
end Process Enderecamento;

Cores:process (clock,RGB,Video_on)
begin if (Video_on = '0') Then
     red <= "0000";
     green <= "0000";
     blue <= "0000";  
else
     red <= RGB(11 downto 8);
     green <= RGB( 7 downto 4);
     blue <= RGB( 3 downto 0);
end if;
end Process Cores;

 

Implementação do Projeto

Análise e Síntese

A Figura 7 apresenta o resultado da Análise e Síntese do projeto.

analise_e_sintese

Figura 7 - Resultado da Análise e Síntese

 

Pinagem

Os pinos devem ser selecionados da seguinte forma:

Pinagem do projeto

Figura 8 - Pinagem do projeto

Clique na imagem para ampliá-la.

O utilizador deve estar atento à tensão de saída, a mesma deve ser ajustada, caso contrário, se permanecer em 2,5V o monitor parecerá meio apagado.

 Simulação

O Testbench simula 3600000 pulsos de clock e mantém o Resetn em '1'.

geraclock:
 process
 begin
      clock wait for 10ns;
      -- Agora, comeca a oscilar:
      for cont in 0 to 3600000 loop
      clock wait for 10 ns;
 end loop;
      wait;
     -- Parando este processo...
 end process;
 
 comportamento:
 process
 begin
      RESETn wait for 50 ns;
      RESETn wait;
 end process;

As Figuras abaixo apresentam os tempos que foram simulados.

Clique nas imagens para ampliá-las.

Sincronismo Horizontal:

Tempo de descida do VIDEO_ON_H Tempo de descida VIDEO_ON_H.

 Tempo de descida HSYNC Tempo de descida HSYNC

Tempo de subida HSYNC Tempo de subida HSYNC

Tempo de subida VIDEO_ON_H Tempo de subida VIDEO_ON_H

Sincronismo Vertical:

Tempo de descida VIDEO_ON_V Tempo de descida VIDEO_ON_V

Tempo de descida VSYNC Tempo de descida VSYNC

Tempo de subida VSYNC Tempo de subida VSYNC

 Tempo de subida VIDEO_ON_V Tempo de subida VIDEO_ON_V

Arquivos do Projeto

Para o download do projeto completo, clique aqui.

O arquivo está no formato "zip", e inclui, entre outros:

   - O arquivo de projeto do Quartus , no formato ".qpf"

   - A descrição no formato VHDL , no formato".vhd"

   - O arquivo para gravação do CPLD, no formato ".pof".
 
   - O test bench utilizado na simulação , no formato ".vhd"
 
   - O Arquivo de imagem, no formato ".mif"
 
 

 

Quem está Online

Temos 38 visitantes e Nenhum membro online

Apoio

Login Form