Written by: Holguer A Becerra
 
 
 
 

En esta practica vamos a construir nuestro primer juego retro  usando un sincronizador de Video VGA (Video Graphics Array), para esto debemos entender los conceptos basicos de sincronizacion VGA usando verilog, de tal manera que podamos visualizar el simple video juego que queremos construir en esta practica, y asi se adquieran los conceptos necesarios base para soltar tu imaginacion.

 

 
Siga las instrucciones paso a paso:
 
  • Cree una plantilla con el DE0_NANO_Control_Panel.exe de la DE0-NANO, como el que se muestra a continuación(recuerde guardarla en una ruta sin espacios y corta):
  • Primero se debe identificar, para esto vamos a ver la siguiente figura en donde usted entenderá como se conecta una FPGA a un conector VGA usando solo resistencias.
En la Fig 1, tenemos el conector VGA “HD-DB15” con una serie de conexiones que van directamente hacia la una FPGA por medio de resistencias de precisión de diferentes calibres.
El pin 1, 2, 3 corresponden al conjunto de colores que podemos enviar a la pantalla, en este caso RGB, por cada componente tenemos un 4 bits de resolución, lo que nos da 16 colores diferentes por color, dándonos una diversa serie de combinación de colores si juntamos las 3 componentes R,G y B.
En la conexión, la conexión de colores no son lo mas importante que debemos ver, hay dos pines llamados VGA_VSYNC y VGA_ HSYNC, estos dos se encargan de sincronizar cada pixel de imagen que mandemos hacia la pantalla, estos son los encargados de decirle a la pantalla en que posición de esta vamos a dibujar, con estos 2 pines nos dispondremos ha entender el modulo VGA que implementaremos en este manual.
 
  • Ahora como se entiende la conexión al puerto VGA se debe pasar a entender como actúan las señales de VGA_VSYNC y VGA_H_SYNC para lograr sincronizar la pantalla VGA.
la entrada al puerto VGA tiene una sincronización Horizontal(H_sync) se encarga de indicarle a la pantalla que se ha terminado de enviar una linea horizontal completa a la pantalla y una sincronización Veritical indicarle a la pantalla que ha terminado de enviar a la pantalla un frame de video de un alto determinado(V_sync), en las figuras siguientes se puede ver en detalle el comportamiento de estas señales (Gráficas del libro de PONG CHU cap 13).

  • La pregunta ahora es como calcular el reloj que controle el modulo de sincronización VGA, en el caso de las figuras anteriores se tiene la descripción de las señales de un modulo de 680x480 pixeles a una tasa de 60Hz, esto quiere decir que se esta sincronizando la pantalla VGA para enviar una imagen de tamaño 640x480 cada 1/60 segundos(Vea que el H_SYNC se mantiene en alto por un tiempo 640 flancos de reloj despues de un left border y antes de un retrace).
    • Observe que es el Retrace, Right Porch, Top Border... etc...
  • Los cálculos para saber cual es el reloj que debemos utilizar para crear este tipo de sincronización teniendo en cuenta que lo único que se tendrán en el diseño serán simples contadores y comparadores que generan H_SYNC y V_SYNC de acuerdo a las zonas que se muestran en la figura 13.4 y 13.5 del libro de PONG CHU.
 
  • Los cálculos que se hicieron en con la formula anterior dicen que para diseñar un sicronizador VGA basado en contadores se debe usar un reloj de 25MHz.
  • Haga los cálculos para las siguientes resoluciones para ver si Pixel Clock coincide con los calculos.
Format Pixel Clock
(MHz)
Horizontal (in Pixels) Vertical (in Lines)
Active
Video
Front
Porch
Sync
Pulse
Back
Porch
Active
Video
Front
Porch
Sync
Pulse
Back
Porch
640x480, 60Hz 25.175 640 16 96 48 480 11 2 31
640x480, 72Hz 31.500 640 24 40 128 480 9 3 28
640x480, 75Hz 31.500 640 16 96 48 480 11 2 32
640x480, 85Hz 36.000 640 32 48 112 480 1 3 25
800x600, 56Hz 38.100 800 32 128 128 600 1 4 14
800x600, 60Hz 40.000 800 40 128 88 600 1 4 23
800x600, 72Hz 50.000 800 56 120 64 600 37 6 23
800x600, 75Hz 49.500 800 16 80 160 600 1 2 21
800x600, 85Hz 56.250 800 32 64 152 600 1 3 27
1024x768, 60Hz 65.000 1024 24 136 160 768 3 6 29
1024x768, 70Hz 75.000 1024 24 136 144 768 3 6 29
1024x768, 75Hz 78.750 1024 16 96 176 768 1 3 28
1024x768, 85Hz 94.500 1024 48 96 208 768 1 3 36
Source: Rick Ballantyne, Xilinx Inc.
 
  • Ahora empecemos con el diseño del modulo de sincronización VGA, cree en Verilog un modulo llamado "mi_vga" con las siguientes entradas y salidas.
    • CLK==> 1 bit entrada.
    • h_sync==> 1 bit salida.
    • v_sync==> 1 bit salida.
    • video_on ==> 1 bit salida
    • pixel_x ==> configurable a N bits de salida.
    • pixel_y ==> configurable a N bits de salida.
  • Dentro del modulo declare un contador de N bits llamado "counter_x" y otro llamado "counter_y".
 
  • ahora declare los los parámetros locales siguientes en el modulo
  • ahora añada a la descripción un logica secuencial que modifique el "counter_x" y "counter_y", para que cada vez que counter_x llegue a un valor máximo de (HD+HF+HB+HR-1) haga que "counter_y" incremente 1 y "counter_x" se reinicie en 0, y que si en el caso de "counter_y" llegue al máximo (VD+VF+VB+VR-1) se reinicie en 0.
  • Ahora añada un registro que se llame h_sync_reg y otro que se llame v_sync_reg y cree una lógica como la siguiente. 
  • Ahora instancia el chip en la plantilla principal para probarlo de la siguiente manera, agregue al diseño un PLL que en base del CLOCK_50 genere una frecuencia de salida con respecto a la formula de sincronización VGA que dice PONG CHU, es mejor usar un PLL en vez de dividir el reloj con un divisor de frecuencia para que de esta forma se mantenga la FASE del sincronizador VGA, lo cual es algo muy importante.
 
  • Haga un circuito que aparece en la Fig 1 al inicio de esta practica y conéctelo de acuerdo a la descripción realizada en el Top Module, luego genere el archivo .SOF y programe la FPGA, si todo va bien la pantalla deberá iluminar toda en ROJO.
  • Ahora agregue/modifique la siguiente descripción al circuito principal y responda:
    • ¿Que aparece en la pantalla?
  • Ahora agregue/modifique la siguiente descripción al circuito principal y responda:
    • ¿Que aparece en la pantalla y por qué?
  • Ahora vamos agregar una imagen al diseño, para esto debemos descargar el siguiente script(Download this file (generado_ram_imag (1).m)generado_ram_imag.m) en matlab que convertirá una imagen de formato BMP-24 a formato MIF(Memory Initialization File).
  • Descargue la siguiente imagen(Download this file (ejemplo.bmp)ejemplo.bmp) que esta en formato BMP-24 y contiene la imagen de una figura de acción, y utilice el script en maltab para convertirla a formato "image.mif".
  • Abra el archivo .mif y verifique que este de la siguiente forma
  • Copie el Archivo "image.mif" a la carpeta de la plantilla.
  • En el proyecto Quartus vaya al megawizard y cree una memoria ROM  de 12 bits "WIDTH" y de tamaño "8200" words "DETPH" e tome a "imagen.mif" como el archivo de inicialización de la memoria ROM y por ultimo genere la memoria ROM.
  • Ahora instancie la ROM en el top de la plantilla principal de la siguiente manera, sin modificar lo que ya hizo anteriormente, si lo hace bien deberá aparecer la imagen que se convirtió con el script en matlab en la pantalla (Solución con imagen Download this file (solucion_con_imagen.sof)solucion_con_imagen.sof).
    • Analice el script en matlab y el código verilog.
    • llegue a sus conclusiones.
  • Ahora convierta la siguiente imagen "Download this file (render.bmp)render.bmp a formato .mif y modifique la memoria ROM de acuerdo al archivo MIF generado, y modifique la descripción de hardware para que se vea como lo siguiente(Solución .sof).
  • Ahora modifique la descripción de hardware para crear una pequeña animación con la imagen "render" que tenemos guardada en memoria.
si lo hizo de manera correcta deberá aparecer una animación(Download this file (solucion_con_render.sof)solucion_con_render.sof) en la pantalla en base a la imagen "render" que esta guardada en la memoria ROM, ahora entienda la lógica del circuito y modifique para que el CHAN(Muñeco) se mueva en la pantalla como lo hace la caja azul(blue box).
Modificando la descripción de la siguiente forma obtendra el movimiento y agregara un efecto de alpha_blending a la imagen variando los SW[3:0] (Solución con movimiento Download this file (solucion_con_animacion_base.sof)solucion_con_animacion_base.sof).
 
La transparencia se logra gracias a la siguiente formula de alpha blending, donde LayerA es la capa superior que se quiere mezclar con LayerB que seria la capa inferior y done LayerAlpha seria el nivel de transparencia de la capa A sobre la capa B.
 
Plantilla de Solución(Download this file (practica_vga.qar)practica_vga.qar) Final(Solo para guiarse) a esto deberá llegar el final de esta practica.
 
 

Ahora:

General timing

Screen refresh rate 60 Hz
Vertical refresh 49.678571428571 kHz
Pixel freq. 83.46 MHz
 
 

Horizontal timing (line)

Polarity of horizontal sync pulse is negative.
Scanline part Pixels Time [µs]
Visible area 1280 15.336688233884
Front porch 64 0.76683441169422
Sync pulse 136 1.6295231248502
Back porch 200 2.3963575365445
Whole line 1680 20.129403306973
 

Vertical timing (frame)

Polarity of vertical sync pulse is positive.
Frame part Lines Time [ms]
Visible area 800 16.103522645579
Front porch 1 0.020129403306973
Sync pulse 3 0.06038820992092
Back porch 24 0.48310567936736
Whole frame 828 16.667145938174
  • En base al archivo "Download this file (mi_vga (1).v)mi_vga.v" modifiquelo para crear un sincronizador VGA(SXGA) de 1280x1024 a 60Hz teniendo en cuenta la siguiente información

General timing

Screen refresh rate 60 Hz
Vertical refresh 63.981042654028 kHz
Pixel freq. 108.0 MHz

Horizontal timing (line)

Polarity of horizontal sync pulse is negative.
Scanline part Pixels Time [µs]
Visible area 1280 11.851851851852
Front porch 48 0.44444444444444
Sync pulse 112 1.037037037037
Back porch 248 2.2962962962963
Whole line 1688 15.62962962963

Vertical timing (frame)

Polarity of vertical sync pulse is positive.
Frame part Lines Time [ms]
Visible area 1024 16.004740740741
Front porch 1 0.01562962962963
Sync pulse 3 0.046888888888889
Back porch 38 0.59392592592593
Whole frame 1066 16.661185185185
 
 
  • En base al archivo "Download this file (mi_vga (1).v)mi_vga.v" modifiquelo para crear un sincronizador VGA(WUXGA) de 1920x1200 a 60Hz teniendo en cuenta la siguiente información

General timing

Screen refresh rate 60 Hz
Vertical refresh 74.521604938272 kHz
Pixel freq. 193.16 MHz

Horizontal timing (line)

Polarity of horizontal sync pulse is negative.
Scanline part Pixels Time [µs]
Visible area 1920 9.939946158625
Front porch 128 0.66266307724166
Sync pulse 208 1.0768275005177
Back porch 336 1.7394905777594
Whole line 2592 13.418927314144

Vertical timing (frame)

Polarity of vertical sync pulse is positive.
Frame part Lines Time [ms]
Visible area 1200 16.102712776972
Front porch 1 0.013418927314144
Sync pulse 3 0.040256781942431
Back porch 38 0.50991923793746
Whole frame 1242 16.666307724166
  1. Ahora cree un modulo que se pueda configurar en tiempo real mientras esta sobre la DE0-NANO que le brinde al usuario todas las resoluciones posibles disponibles utilizando el mismo modulo de sincronización.
 
 
 
EXTRA BONUS:
  • Descargue lo siguiente es el juego BreakOut(Download this file (BreakOut_Game_DE0_NANO.qar)BreakOut_Game_DE0_NANO.qar) basado en el juego de PONG CHU funcionando en la DE0-NANO, y pruebe jugando con el KEY[1:0].