Controlador VGA - Parte 2

VGA controlador VGA caracteres ASCII com controlador VGA
Este post faz parte da série Controlador VGA. Leia também os outros posts da série:

Este segundo artigo tem como objetivo demonstrar na prática como um controlador VGA pode ser construído. Assim, será utilizada a placa DE0-Nano para descrever o hardware do controlador utilizando VHDL. Cabe frisar que o objetivo é demonstrar como transformar os parâmetros de controle, apresentados no primeiro artigo, em um hardware. Portanto, o FPGA e o VHDL são apenas recursos utilizados no exemplo. Para mais informações sobre a placa e a linguagem consulte as referências listadas no final do artigo. Vamos lá!

Elaborando o Controlador VGA

Como a DE0-Nano possui um oscilador de 50 MHz, será utilizado como caso de teste a configuração VGA com resolução de 800x600, frequência de atualização de 72 Hz e apenas 1 bit para cada componente do pixel.

No primeiro artigo foi apresentada a tabela com os parâmetros de controle do frame VGA.

Tabela 1 - Temporização VGA.

timing VGA

De acordo com a Tabela 1, os parâmetros B, C, D e E são fornecidos como pulsos de clock, já os parâmetros P, Q, R e S são fornecidos com base na contagem de linhas. Deste modo um hardware básico pode ser construído de forma a contar os pulsos de clock e com base em comparações do valor contado pode-se determinar o estado dos sinais H_SYNC, V_SYNC e das componentes RGB.

Modelo do controlador VGA
Figura 1 - Modelo do controlador VGA

As linhas e colunas são contadores modificados conforme a entrada de Clock. Os sinais de sincronismo são alterados conforme esses contadores e devem manter estado até que outra condição de controle seja disparada.

Uma forma simples de criar esse mecanismo de controle é considerar que os contadores estão na região ativa de vídeo durante os primeiros X pulsos contados, sendo que X representa o número de linhas e/ou colunas.

Para o sincronismo horizontal devemos considerar os parâmetros B, C, D e E. Considerando que o contador é iniciado com valor zero, será necessário realizar as operações listadas abaixo: 

  • A linha permanece na região ativa durante os D primeiros pulsos, sendo que D é o número de pixels por linha, neste caso, 800;
  • Após atingir D é necessário aguardar mais E pulsos, sendo E a região de Front Porch. Até esse ponto temos um total de 856 pulsos (D + E);
  • Após a região de Front Porch o sinal H_SYNC deve ser posto em zero, permanecendo nesse estado durante B pulsos. Até esse ponto temos um total de 976 pulsos (D + E + B);
  • Depois de gerar o sinal de sincronismo é necessário aguardar C pulsos da região de Back Porch, totalizando 1040 pulsos (D + E + B + C).

Para o sincronismo vertical devemos considerar os parâmetros P, Q, R e S. Considerando que o contador é iniciado com valor zero e que o seu valor é incrementado sempre que uma linha é finalizada: 

  • O quadro permanece na região ativa durante os R primeiros pulsos, sendo que R é o número de linhas, neste caso, 600;
  • Após atingir R é necessário aguardar mais S pulsos, sendo S a região de Front Porch. Até esse ponto temos um total de 637 pulsos (R + S);
  • Após a região de Front Porch o sinal V_SYNC deve ser posto em zero, permanecendo nesse estado durante P pulsos. Até esse ponto temos um total de 643 pulsos (R + S + P);
  • Depois de gerar o sinal de sincronismo é necessário aguardar Q pulsos da região de Back Porch, totalizando 666 pulsos (R + S + P + Q).

Com esses requisitos é possível determinar o tamanho dos contadores. Para o contador horizontal (colunas) serão necessários 11 bits, pois o total a ser contado é 1040 e com 11 bits é possível contar até 2048. Já o contador vertical (linhas) pode ser de 10 bits, pois o maior valor que será armazenado é 666.

Descrevendo o Controlador VGA

Para descrever o controlador VGA será utilizado o mesmo modelo ilustrado na Figura 1. Portanto, será necessário criar um mecanismo de sincronismo e outro para definição dos pixels.

Abaixo é listado o código da entidade para o bloco de sincronismo.

Para definir a operação do módulo, será apresentada a arquitetura dividia em 6 partes. Na listagem abaixo são mostrados os sinais internos do módulo.

Com base nos valores dos contadores, horizontal e vertical, é mostrado na listagem abaixo a identificação dos parâmetros B, C, D, E, P, Q, R e S. 

Esses sinais indicam se uma das condições (parâmetros) foi alcançada e são utilizados para determinar o próximo estado dos sinais de sincronismo.

Na listagem abaixo é mostrada a lógica para incrementar/reiniciar os contadores.

Esses sinais apenas determinam qual será o valor futuro, sendo necessário atualizar o estado atual. No processo listado abaixo, sempre que ocorre uma transição de borda de subida no clock os sinais de controle são atualizados.

Por fim, esses sinais devem ser atribuídos na saída do bloco de sincronismo. A listagem abaixo mostra a atribuição dos sinais de controle.

O código completo do bloco de sincronismo VGA é mostrado abaixo.

Para gerar os pixels será criado um novo bloco. Esse bloco utiliza a posição do pixel (linha e coluna) e um sinal que indica se a varredura está na região ativa para determinar os sinais RGB. Para o exemplo, foi testado o valor da coluna de forma que a cada 100 pixels será exibida uma combinação de cores.

A listagem abaixo mostra a declaração dos dois blocos dentro de um terceiro arquivo. Neste arquivo são estabelecidas as conexões entre os módulos e o acionamento dos pinos de saída da DE0-Nano.

Na Figura 2 são mostrados os dois módulos do controlador VGA.

Módulos do Controlador VGA
Figura 2 - Módulos do Controlador VGA

Os pinos do FPGA que foram utilizados como entrada e saída do controlador são mostrados na Figura 3.

Pinos utilizados no controlador VGA
Figura 3 - Pinos utilizados no controlador VGA

Testando o controlador

Neste exemplo, as saídas definidas do controlador estão localizadas nos pinos 2, 4, 6, 8 e 10 do conector GPIO1 (JP2). Os três pinos definidos para os canais R, G e B estão conectados a resistores de 1kΩ (vide Figura 4). 

Conexão da DE0-nano com o conector VGA
Figura 4 - Conexão da DE0-nano com o conector VGA

Na Figura 5 é mostrada a forma de onda do sinal H_SYNC. O intervalo determinado pelo cursor indica o período em que o sinal H_SYNC permanece em zero. Visto que o sinal H_SYNC permanece em zero durante 120 pulsos, o tempo é de 2,4 us.

controlador vga: sinal HSYNC
Figura 5 - Sinal H_SYNC

Abaixo é mostrado o tempo do frame correspondente às regiões C, D e E, isto é, o tempo do frame após o pulso H_SYNC.

controlador vga: sinal após HSYNC
Figura 6 - Região que corresponde aos parâmetros C, D e E

O tempo total de uma linha é de 1040 pulsos de clock. Na Figura 7 é mostrado o tempo de varredura de uma linha que corresponde a 20,8 us, isto é, a frequência de varredura da linha é de aproximadamente 48,07 kHz.

controlador vga: varredura de uma linha
Figura 7 - Tempo de varredura de uma linha

Na tabela 2 é mostrado o período de cada parâmetro de uma linha e o tempo total de varredura horizontal.

 Pixels (pulsos de clock)Tempo (microssegundos)
H_SYNC1202,4
Front porch561,12
Back porch641,28
Região ativa80016
Linha completa104020,08

Sabendo que o tempo de varredura de uma linha é de 20,8 us, o tempo total de varredura de todas as linhas do quadro é de 12,48 ms. O tempo total do quadro pode ser obtido somando o tempo das outras regiões de sincronismo vertical (Tabela 3).

 LinhasTempo (milissegundos) - 20,8 us x linhas
V_SYNC60,1248
Front porch370,7696
Back porch230,4784
Região ativa60012,48
Frame completo66613,8528

Da Tabela 3 temos o tempo total do frame que é de aproximadamente 13,85 ms, isto é, a frequência de atualização do quadro é próxima de 72,2 Hz. Na Figura 8 é mostrada a frequência do frame detectado pelo monitor.

Teste do controlador VGA
Figura 8 - Teste do controlador VGA

Conclusão

Nesta série de artigos foi apresentada uma breve descrição sobre o padrão VGA. A partir da caracterização deste padrão tão conhecido, procurou-se definir o escopo de um controlador bem simples. Com base em dois módulos principais, foi elaborado um projeto utilizando a linguagem VHDL e a placa de desenvolvimento DE0-Nano.

A simplicidade do controlador construído facilita a compreensão do padrão VGA. Um modelo simples como o descrito neste artigo pode ser construído utilizando poucos recursos lógicos, como portas AND (comparadores), contadores e flip-flops.

Fica demonstrado, de forma simples, como exibir uma imagem em um monitor VGA!

Para saber mais

Para aprender mais sobre FPGA confira os artigos de André Prado:

Confira também os artigos do Thiago Lima sobre a DE0-Nano:

Referências

- Tabela 1: http://martin.hinner.info/vga/timing.html

- Imagem destacada: https://en.wikipedia.org/wiki/Mode_13h#/media/File:VGA_palette_with_black_borders.svg

Outros artigos da série

<< Controlador VGA - Parte 1Exibindo caracteres ASCII com controlador VGA - Parte 3 >>
Este post faz da série Controlador VGA. Leia também os outros posts da série:
Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.

Receba os melhores conteúdos sobre sistemas eletrônicos embarcados, dicas, tutoriais e promoções.

Hardware » Controlador VGA - Parte 2
Talvez você goste:
Comentários:

3
Deixe um comentário

avatar
2 Comentários
1 Respostas
0 Seguidores
 
Discussão de maior alcance
Discussão mais quente
3 Autores de comentários
Fernando Deluno GarciaAnderson SchumacherPedro Freitas Comentários recentes
  Notificações  
recentes antigos mais votados
Notificar
Pedro Freitas
Visitante
Pedro Freitas

Sensacional! Tu tem alguma indicação de material desse mesmo assunto, porém voltado para a descrição de hardware em Verilog?

Anderson Schumacher
Visitante
Anderson Schumacher

muito obrigado amigo, me ajudou bastante!

Fernando Deluno Garcia
Visitante
Fernando Deluno Garcia

Olá, Anderson.

Obrigado pelo retorno!

Séries



Outros da Série

Menu