Vous êtes sur la page 1sur 47

UNIVERSIDAD MAYOR DE SAN ANDRES

FACULTAD DE INGENIERIA
CARRERA INGENIERIA ELECTRONICA

VIDEOJUEGO PONG EN VHDL


UTILIZANDO TARJETA XILINX SPARTAN-3AN
MATERIA : PROYECTO II

DOCENTE: ING. ROBERTO OROPEZA CRESPO

ESTUDIANTE:
Amrico lvarez Surci

GESTION 2011
LA PAZ - BOLIVIA

A mis Padres que nunca dejaron de apoyarme


y Ana una persona muy especial.

II

Resumen
PONG, un video juego sencillo, es la representacin del deporte de TENIS, que consiste
en hacer botar el baln en una paleta a otra sin equivocarse. En el presente proyecto
describimos el movimiento del baln y de la paleta en un campo diseado para tal
cometido. Analizamos el monitor VGA para poder describir un controlador del mismo,
utilizando la descripcion de hardware que nos brinda el VHDL.
Por ultimo mostraremos como el monitor brinda el campo de juego y tambin hara de
interfas entre el juego y el jugador.

Abstract
"PONG", a simple video game, is the representation of the sport of tennis, which consists of
bouncing the ball on a pallet to another without making a mistake. In this project, we
describe the movement of the ball and paddle in a field designed for that purpose. We
analyze the VGA monitor to describe the same controller, using the hardware description
that gives us the VHDL.
Finally we show how the monitor provides the playing field and will make the interface
between the game and the player.

III

LISTA DE FIGURAS
Figura 1: Consola ATARI-PONG
Figura 2: Videojuego original pong. Museo Vienna-1998
Figura 3: Recursos de descripcin VHDL
Figura 4: Analoga de entidad y arquitectura
Figura 5: Compuerta and de 2 entradas
Figura 6: Ejemplo de descripcin en VHDL
Figura 7: Modelo Esquemtico
Figura 8: Diagrama conceptual de un monitor TRC
Figura 9: Trazado del Haz de electrones, en un monitor TRC
Figura 10: Diagrama de bloques de un simple controlador VGA
Figura 11: Diagrama de tiempos de un barrido horizontal
Figura12: Diagrama de tiempos de un barrido vertical
Figura13: Tarjeta XILINX Spartan-3AN
Figura 14: Monitor TRC
Figura 15: Conexin VGA, con salidas del FPGA
Figura 16: Flujo grama, Videojuego PONG
Figura 17: diagrama de bloques conceptual, de un trazador de objetos
Figura 18: Elementos primitivos del videojuego PONG
Figura 19: Mapeo de bits de un Redondo
IV

Figura 20: Movimiento del baln en Rebotes de Esquina

LISTA DE TABLAS
Tabla 1 : Combinacin a 3 bits, RGB
Tabla 2: Modulo de Sincronia en VHDL
Tabla 3: Modulo Generador de pixeles, 3 objetos cuadrados.
Tabla 4: Modulo Prueba 1.
Tabla 5: Generador de Pixeles, con animacin
Tabla 6: Modulo Final, videojuego PONG en VHDL

INDICE GENERAL
Resumen/Abstract

III

Lista de Figuras

IV

Lita de Tablas

Capitulo 1: ANTECEDENTES Y PROPOSITOS


1.1 Introduccin

1.2. Objetivos

2
1.2.1 Objetivo principal
1.2.2 Objetivos secundarios

Capitulo 2: MARCO TEORICO


2.1. Antecedentes: Descripcin de Hardware

2.1.1. Lenguajes Precursores: CDL, DDL, AHPL, ISPS, TI-HDL


2.1.2. Lenguajes Actuales: VERILOG, UDL/I, VHDL
2.2 VHDL

6
2.2.1. Entidad y Arquitectura
2.2.2 Unidad de Diseo y Libreras
2.2.3. Modelo de Diseo Bsico

2.3 VGA.

10
2.3.1 Seales de Sincronizacin. Hsync y Vsync
2.3.2 Timing de Seales de Sincronizacin VGA
VI

2.3.3 Generador de Pixeles


Capitulo 3: DESARROLLO DEL PROYECTO
3.1 Hardware empleado:

17

XILINX Spartan 3an, Monitor VGA


3.2 Descripcin del Sistema: Ping Pong

19

3.2.1 Diagrama de Flujo


3.3 Elaboracin y Ejecucin del Videojuego PONG

20

3.3.1 Seales de sincronismo: VGA SYNC


3.3.2 Generador de pixeles: PONG_GRAPH

Objetos Rectangulares

3.3.3 Objetos no Rectangulares


3.3.4 Animacion: PONG_GRAPH_ANIMADO
3.4 Programa Principal: JUEGO_PONG

36

Capitulo 4: CONCLUSIONES Y MEJORAS


4.1 Conclusiones

38

4. 2 Mejoras

39

5. BIBLIOGRAFA

39

6. ANEXOS

40

VII

Capitulo 1
ANTECEDENTES Y PROPOSITOS

1.1 INTRODUCCION
Pong fue el primer juego desarrollado por Atari Inc. Originalmente la placa de Pong
utilizaba transistores, condensadores, resistencias, etc. ocupando un espacio de unos
cuantos metros cuadrados. Aunque ya exista el primer microprocesador, hecho por Intel
en 1970, no fue utilizado an, por su reciente lanzamiento al mercado, alto coste y
ausencia de documentacin.
Atari Pong fue una consola creada por Atari en 1975, es la segunda videoconsola de la
historia. No llevaba cartuchos, sino que tena slo un juego, el PONG.

Figura1: Consola ATARI-PONG

El jugador controla en el juego una paleta que tiene un movimiento rectilneo, haciendo las
veces de paleta para que la pelota rebote en esta y en las paredes del espacio de juego.
El jugador pierde en cuanto ms falle en hacer botar el baln en la paleta.
Se utilizara un lenguaje de descripcin de hardware para el cometido de reproducir el
juego propuesto.

1.2. OBJETIVOS
Con el presente trabajo se trata de enfocar los siguientes objetivos:
1.3.1 Objetivo Principal

Mediante lenguaje de descripcin de hardware, implementar el video


juego PONG en la tarjeta fpga XILINX.

1.3.2 Objetivos Secundarios

Conocer y definir un circuito controlador bsico de sincronismo.

Conocer y definir un circuito generador de pixeles. A base de


contadores.

Utilizar el monitor VGA, y dar pautas para futuros diseos.

Figura 2: Videojuego original pong. Museo Vienna-1998

Capitulo 2
MARCO TEORICO

Con la creciente complejidad de los diseos digitales ha aparecido una necesidad de


describir un circuito de la forma ms eficiente y prctica posible. Un lenguaje de
programacin ofrece la posibilidad de un alto nivel de abstraccin y es la solucin
adecuada para dicha tarea.

2.1 ANTECEDENTES: DESCRIPCIN DE HARDWARE


Los lenguajes de descripcin hardware son lenguajes de alto nivel con una sintaxis similar
a los de programacin (C, ADA, Pascal, Modula, etc.) y una semntica que permite el
modelado y simulacin de los dispositivos hardware a diferentes niveles de abstraccin.
Los primeros lenguajes de este tipo slo pretendan servir de vehculo de comunicacin
del diseo. Los actuales lenguajes han adquirido un alto grado de estandarizacin y han
adoptado los nuevos conceptos de la ingeniera de software, permitiendo la verificacin de
la especificacin del diseo mediante simulacin.
2.1.1 Lenguajes Precursores: CDL, DDL, AHPL, ISPS, TI-HDL

CDL (Computer Design Language)


Fue desarrollado por Yaohan Chu a comienzo de los aos 60 bajo el principio de
separacin de la componente lgica y electrnica de un computador digital. CDL refleja
directamente el hardware y sus operaciones, es decir, existe una correspondencia uno-auno entre los objetos y operaciones hardware (registros, RAMs, relojes, suma, cuenta,
etc.) y las construcciones del lenguaje. La primera versin del simulador CDL para IBM
7090 estuvo disponible en 1968, y la versin tercera para Univac pocos aos ms tarde.
Se utiliz en universidades y en la industria del radar y aeronutica.

DDL (Digital systems Design Language)


Se desarroll a mediados de los 60 en la Universidad de Wisconsin con varios objetivos:
precisin y concisin para facilitar la especificacin de los diseos, potencia suficiente
para modelar sistemas complejos, independencia respecto a cualquier tecnologa o
procedimiento de diseo, capacidad de especificacin a diferentes niveles de abstraccin
y, finalmente, una sintaxis y una semntica que permitieran la documentacin jerrquica
del diseo.

AHPL (A Hardware Programming Language)


Fue propuesto por F.J. Hill y G.R. Peterson unos meses ms tarde que el CDL y DDL, y
apareci publicado por primera vez en 1973 en la edicin original de Digital Systems:
Hardware Organization and Design. Los autores concibieron AHPL como un lenguaje de
sntesis: todo dispositivo sncrono que pudiese ser implementado en hardware deba ser
expresable en AHPL de manera tal que se pudiese traducir a una realizacin fsica
siguiendo un conjunto simple de reglas. En opinin de uno de sus autores, F.J. Hill, que
particip como miembro del grupo de trabajo que formul las especificaciones originales
para VHDL, la existencia de AHPL favoreci la incorporacin de mecanismos para permitir
el proceso de sntesis en VHDL.

ISPS (Instruction Set Processor Specifications)


Con este lenguaje se dio un paso importante hacia la formalizacin del proceso de diseo
a niveles de comportamiento. Adems de la simulacin y la sntesis, ISPS se utiliz en la
generacin de software, la verificacin de programas y la evaluacin de arquitecturas.
ISPS favoreci los aspectos de comportamiento sobre los estructurales pero sin
eliminarlos completamente.

TI-HDL (Texas Instruments-HDL)


Es un lenguaje de descripcin jerrquica del diseo, estructurado en bloques y basado en
texto, que se ha utilizado principalmente en el diseo de circuitos integrados. Procede de
4

antiguos lenguajes usados all por 1968, concretamente el TIBSD (TI Boolean System
Description), desarrollado como lenguaje de entrada de datos para un sistema CAD de
circuitos impresos, y Fusim (Functional Simulator), utilizado para describir modelos de alto
nivel de microprocesadores y para generar prototipos de patrones de tests.
2.1.2 Lenguajes Actuales: VERILOG, UDL/I, VHDL

Verilog
Es un lenguaje de descripcin hardware diseado por la compaa Cadence Design
Systems Inc., que se ha venido utilizando como lenguaje del simulador digital Cadence. El
uso de Verilog est promovido por la Open Verilog International (OVI), que public en
octubre del 91 la primera versin del Hardware Description Language Reference Manual.
En Verilog la unidad de diseo fundamental es el mdulo, que describe un componente
hardware con su interfaz y contenido. Desde un punto de vista funcional, un mdulo
Verilog contiene la informacin de una entidad y su correspondiente arquitectura VHDL.
Verilog no proporciona compilacin independiente de mdulos: todos los mdulos
relacionados con el mismo diseo y simulacin deben estar en el mismo archivo.

UDL/I (Unified Design Language for Integrated circuits)


Es un lenguaje de descripcin hardware que se viene desarrollando desde 1989 por la
Japan Electronic Industry Development Association, dependiente de importantes
compaas japonesas tales como NTT. Una de las caractersticas de UDL/I es que
pretende ser especfico para modelar circuitos integrados. La nica unidad de diseo
existente en UDL/I es la descripcin de diseo, que comprende varias sub-entidades
denominadas descripciones de mdulos. Una descripcin de diseo contiene el modelo
de un circuito integrado que consta de varias subunidades o mdulos, cada uno de los
cuales est especificado por una descripcin de mdulo.

VHDL (VHSIC Hardware Description Language)


Se aborda en el siguiente subtitulo.
5

2.2 VHDL
Very High Speed Integrated Circuit Hardware Description Language (VHSIC HDL).
Desarrollado por el Departamento de Defensa de los Estados Unidos a finales de la
dcada de los 70's. El propsito era hacer un estndar para disear, modelar, y
documentar circuitos complejos de manera que un diseo desarrollado por una empresa
pudiera ser entendido por otra, adems, que pudiera ser procesado por software para
propsitos de simulacin.
En diciembre de 1987 VHDL se estableci como el estndar IEEE-1076. En 1993 el
estndar IEEE-1076 se actualiz y un estndar adicional, el IEEE-1164, fue adoptado. En
1996, el estndar IEEE-1076.3 se convirti en un estndar de VHDL para sntesis siendo
este el que se utiliza en el diseo de sistemas digitales.
Lo que ha hecho que VHDL sea en un tiempo tan corto el lenguaje de descripcin de
hardware ms utilizado por la industria electrnica, es su independencia con la
metodologa de diseo utilizada por cada programador, su capacidad de descripcin a
diferentes niveles de abstraccin (Fig.3), y en definitiva la posibilidad de poder reutilizar en
diferentes mdulos en cualquier aplicacin futura.

Figura 3: Recursos de descripcin VHDL

Si queremos definir cualquier elemento digital tenemos que enfocarnos en 2 bloques de


descripcin: 1. Entidad, 2 Arquitectura; que conforman una unidad mnima de diseo.
Adems tenemos la posibilidad de utilizar libreras definidas por usuario.

2.2.1 Entidad y Arquitectura


La realizacin del modelo hardware de un dispositivo en VHDL consiste en la elaboracin
de dos unidades de cdigo VHDL: una Declaracin de Entidad y un Cuerpo de
Arquitectura.
La Declaracin de Entidad es la unidad de diseo VHDL que sirve para especificar el
interfaz de los dispositivos. Cumple, por tanto, funciones equivalentes a las de los
smbolos en las representaciones grficas.

Figura 4: Analoga de entidad y arquitectura

El Cuerpo de Arquitectura es la unidad de diseo VHDL que sirve para especificar el


funcionamiento de un dispositivo identificado por una determinada Declaracin de
Entidad, por lo que se puede considerar el equivalente a las tablas de verdad o a los
cronogramas.

En la Declaracin de Entidad se define el nombre del dispositivo y sus puertos; en el


Cuerpo de Arquitectura su funcionamiento, en la fig.5 el uso mediante una sentencia que
utiliza un operador lgico AND de 2 entradas.

Figura 5: Compuerta and de 2 entradas

La construccin del modelo de un dispositivo en un entorno VHDL finaliza, en principio, en


el momento en que las unidades VHDL que lo describen quedan almacenadas en una
librera VHDL. Para ello hay que editar las unidades y compilarlas. En el proceso de
compilacin se comprueba que no se incumplen una serie de reglas sintcticas y
semnticas.

2.2.2 Unidades de Diseo y libreras


Un modelo VHDL se compone de un conjunto de unidades de diseo. Una unidad de
diseo es la mnima seccin de cdigo compilable separadamente.
Las unidades de diseo VHDL se construyen combinando construcciones del lenguaje
(sentencias, declaraciones, etc.). Estas unidades son descritas con la declaracin Entidad
y el cuerpo de Arquitectura (descritos en el anterior apartado).
Las libreras de vhdl, representa la unin de varias unidades de diseo mnimas, para
describir un sistema ms complejo. Cuando se utilizan varias unidades de diseo se

deber tener un modulo principal que haga el llamado a cualquier modulo segn sea el
caso.
Hay que mencionar adems que hay que incluir las libreras, en la declaracin de
paquetes a utilizar en nuestra descripcin en VHDL.

2.2.3. Modelo de Diseo Bsico


A continuacin se describir un programa bsico en vhdl.

Figura 6: Ejemplo de descripcin en VHDL

En la fig. 6 observamos la descripcin de un pequeo programa vhdl, que describe el


circuito de la fig. 7, para este descripcin se utilizo una entidad, una arquitectura, adems
de una librera creada por usuario. Cabe mencionar que los componentes de milibreria
9

no se los aprecia, pero son descripciones bsicas de una compuerta and de 3 entradas y
una or de n entradas (utilizados en lneas 24,27-30 respectivamente).

Figura 7: Modelo Esquemtico

2.3 VGA
El trmino Video Graphics Array (VGA) Sistema grfico de pantallas para PC que se
comercializ por primera vez en 1988 por IBM.

Figura 8: Diagrama conceptual de un monitor TRC

En un monitor monocromo (Fig.8), el generador de electrones (ctodo), genera un haz de


electrones enfocado que atraviesa un tubo al vacio, y finalmente llega a una pantalla

10

fluorescente. La pantalla se ilumina en el instante en que el rayo de electrones incide con


los puntos de fosforo que tiene la pantalla. Una bobina de deflexin vertical y otra vertical,
generan campos magnticos variables que controlan la direccin del haz de electrones, y
as poder realizar el trazado de toda la pantalla. sea que siguen un patrn fijo de
izquierda a derecha de arriba abajo como se muestra en la Fig.9.

Figura 9: Trazado del Haz de electrones, en un monitor TRC

Osciladores internos del monitor generan formas de onda diente de sierra para controlar
las dos bobinas de deflexin. Por ejemplo, si el haz de electrones se mueve desde el
borde izquierdo al borde derecho, la tensin aplicada a la bobina de deflexin horizontal
se incrementa gradualmente. Despus de alcanzar el borde derecho, el haz vuelve
rpidamente a la orilla izquierda.
El funcionamiento bsico de un monitor RGB (a color) es muy similar al visto,
exceptuando que tiene 3 haces de electrones que inciden en los puntos de fsforo rojo,
verde y azul en la pantalla. Los tres puntos se combinan para formar un pxel. Podemos
ajustar los niveles de tensin de la entrada de video de tres seales para obtener el color
del pixel deseado.

11

Tabla 1: Combinacin a 3 bits, RGB

El puerto VGA tiene cinco seales activas: seales de sincronizacin horizontal y vertical
(hsync y vsync), y tres seales de vdeo para el rojo, verde y azul. Un controlador de
vdeo genera todas estas seales. Un diagrama de bloques simplificado de un controlador
de VGA se muestra en la Fig.10. Contiene un circuito de la sincronizacin, con el nombre
vga_sync, y un circuito de generacin de pxel.

Figura 10: Diagrama de bloques de un simple controlador VGA

2.3.1. Seales de Sincronizacin: Hsync y Vsync


El circuito de la sincronizacin de vdeo genera la seal hsync, que especifica el tiempo
necesario para el recorrido (exploracin) una fila, y la seal vsync, que especifica el

12

tiempo necesario para el recorrido transversal (scan) toda la pantalla. Las discusiones
posteriores se basan en una pantalla VGA 640 por 480, con una tasa de pxel de 25 MHz,
lo que significa que 25 millones de pxeles son procesadas en un segundo.
SEAL DE SINCRONIA HORIZONTAL: HSYNC

Figura 11: Diagrama de tiempos de un barrido horizontal

En la figura anterior se observa que se trabaja con 800 pixeles, esto se debe a que
usualmente los monitores CRT tienen un borde negro, conocidos como Backporch y
frontporch, que son el borde izquierdo y derecho respectivamente.

13

Display: Regin en que los pixeles son observables. Longitud de 640 pix.

Retrace: Regin en la que los haces de electrones regresan a la izquierda. La


seal de video debe de estar desactivada. Longitud 96 pix.

Right Border: Borde derecho. La seal de video desactivada. Longitud de 48px

Left Border: Borde izquierdo. La seal de video desactivada. Longitud de 96 px.

La seal de Hsync se puede obtener con un contador modulo 800. El backporch y el


frontporch pueden variar entre marcas de monitores.
SEAL DE SINCRONIA VERTICAL: VSYNC

Figura12: Diagrama de tiempos de un barrido vertical

Durante la exploracin vertical, el haz de electrones se mueven gradualmente de arriba


hacia abajo y luego vuelve arriba. Esto traza toda la pantalla fila a fila. Hay mucho
parecido a la seal HSYNC. La unidad de tiempo del movimiento est representada en
trminos

de

lneas

de

exploracin

horizontal.

Un

perodo

de

de la seal vsync es de 525 pixeles.

Display: Regin en la que son observables las lneas horizontales. Longitud de


480pix.

14

Retrace: Regin en la que los haces de electrones regresan a la parte superior


de la pantalla. La seal de video debe de estar desactivada. Longitud 2 pix.

Bottom Border: Borde inferior. La seal de video desactivada. Longitud de


10px

Top Border: Borde Superior. La seal de video desactivada. Longitud de 33 px.

La seal de Vsync se puede obtener con un contador modulo 525. El Bottom y top border
puede variar entre marcas de monitores.
2.3.2. Timing de Seales de Sincronizacin VGA
Como se mencion anteriormente, se supone que la tasa de pxel es de 25 MHz. Est
determinada por tres parmetros:
p: El nmero de pxeles de una lnea de exploracin horizontal.

pixels
line

p 800

L: El nmero de lneas de trazado de una pantalla

L 525

lines
screen

s: El nmero de pantallas (imgenes) por segundo. Tasa de refresco.

s 60

screens
seconds

El parmetro s especifica la rapidez con la pantalla debe ser restaurada. Para un ojo
humano, la frecuencia de actualizacin debe ser al menos 30 pantallas por segundo para
un movimiento continuo debe de ser 60 pantallas por segundo.
El clculo del timing para las seales de sincronizacin se lo realiza de la siguiente
manera:

pixel _ rate p L s 25M

15

pixels
second

2.3.3. Generador de Pixeles


El circuito de generacin de de pxeles genera la seal RGB de 3 bits para el puerto VGA.
Es necesario especificar el contenido de la pantalla a travs de los pixel_x y pixel_y.
Las seales de sincronizacin

VGA (vga_sync), nos proporcionar las coordenadas

actuales de cada pixel.


Existen tres grandes grupos en los que podemos dividir los generadores de pixeles:

Esquemas de mapa de bits: Se traza grficos desde una memoria, pixel a pixel. Esto
consume mucha memoria, ya que cada grafico debe de estar guardado en mapa de
bits

Esquema modular: Se agrupan conjunto de bits para formar un mosaico, y utilizar


varios de estos para formar imgenes.

Esquema trazador de objetos: Se crea elementos (figuras), por separado siguiendo


un rgimen para mostrar objeto a objeto utilizando un multiplexor para este cometido.
Este sistema es el que utilizaremos de aqu en adelante para describir el video juego
planteado.

16

Capitulo 3
DESARROLLO DEL PROYECTO
3.1 HARDWARE EMPLEADO:
XILINX SPARTAN-3AN
Se emplea como elemento base un kit de desarrollo FPGA comercial referencia
UG334 familia Spartan 3A/3AN de XILINX.

Figura13: Tarjeta XILINX Spartan-3AN

Este kit de desarrollo posee:


o

1 FPGA XC3S700A de la familia Spartan3 de XILINX.

Puerto USB para programar FPGA

4-Mbyte SRAM

64-Mbyte ddr2 SDRAM.

8-Mbyte Flash memory

4 MByte Flash paralelo

4 pushbutton, posicionados a manera de arriba, abajo, derecha, izquierda.


17

4 switches deslizables

8 salidas en LEDs verdes

1 pantalla Lcd de 16x2

1 Osciladores de 50-MHz.

1 SMA para oscilador externo

1 puerto VGA.

10/100 controlador de red con su conector

USB Host/Slave Controller.

Conector I/O para audio externo.

2 puertos de 9 pines para comunicacin RS-232

Connector PS/2 mouse/keyboard

1 core microblaze

4 salidas de DAC

2 entradas a ADC

2 expansiones de salidas de 40 pines

Adems se utilizo el software para la utilizacin de esta tarjeta de estudio el software


empleado fue el ISE WEB PACK de Xilinx.

Monitor VGA

Figura 14: Monitor TRC

18

Fig.15: Conexin VGA, con salidas del FPGA

3.2 DESCRIPCIN DEL SISTEMA: PING PONG


El sistema emulara el juego de pong para un jugador, los push-button de la tarjeta a
manera de mando (control 1 player), que manejara la paleta donde botara la pelota del
juego, adems todo esto se observara en un monitor (vga).
3.2.1 Diagrama de Flujo
Inicio

Enviar

Reset
Movimiento balon

Boton
Arriba

Mueve Paddle Arriba

Mueve paddle Abajo

Actualiza Datos VGA

Figura16: Flujo grama, Videojuego PONG

19

3.3 ELABORACION Y EJECUCION DEL VIDEOJUEGO PONG


Por lo descrito anteriormente se proceder a elaborar el controlador del vga, modulo a
modulo, siguiendo el esquema de la Figura 10. Luego se proceder a la mejora del cdigo
y posteriormente a la animacin.
3.3.1. Seales de sincronismo: VGA SYNC
El circuito de sincrona VGA descrito en la seccin 2.3.1. Trabaja con una frecuencia de
25Mhz. El circuito esta implementado con 2 contadores: uno de modulo 800 para el
escaneo horizontal, y otro de modulo 525 para el escaneo vertical.
La tarjeta Xilinx Spartar-3an tiene un oscilador interno de 50Mhz. Por lo que se proceder
a generar una oscilacin de 25Mhz, utilizando un contador modulo 2 (signal: mod2); se
definen adems 2 contadores para el mapeo horizontal y vertical (signal: h_count y
v_count); adems incluimos 2 seales de finalizacin h_end y v_end que indican la
finalizacin de cada etapa. Los valores constantes de cada regin mostrada en las figuras
11 y 12 (mrgenes, display, top, bottom, etc) son indicados y pueden ser cambiados
fcilmente si se requiere.
Para evitar fallas potenciales, se incluye buffers a la salida de las seales hsync y vsync,
esto nos llevara a un retraso de ciclo de reloj, que se corregir posteriormente aadiendo
otro buffer a la salida vga, que observaremos en el generador de pixeles ms adelante.
VHDL del modulo de sincronizacin:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

------------------------------------------------------------------ Modulo_ seales de sincrona monitor VGA


-- Amrico Alvarez Surci
----------------------------------------------------------------library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity vga_sync is
port(
clk,reset: in std_logic;
hsync,vsync: out std_logic;
video_on, p_tick: out std_logic;
pixel_x,pixel_y: out std_logic_vector(9 downto 0)
);

20

--seales de syncronismo
--contador de pixels 800x525

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79

end vga_sync;
architecture rtl of vga_sync is
--vga 640 por 480, parametros de sirncronia
constant HD: integer:=640;
--trazado horizontal
constant HR:integer:=96;
--recarga horizontal
constant HF:integer:=16;
--margen derecho
constant HB:integer:=48;
--margen izquierdo
constant VD:integer:=480;
--trazado vertical
constant VR:integer:=2;
--recarga vertical
constant VF:integer:=10;
--margen inferior
constant VB:integer:=33;
--margen superior
--Contador modulo 2
signal mod2_reg, mod2_next:std_logic;
--seal de contadores para la sincronia vertical y horizontal
signal v_count_reg, v_count_next: unsigned(9 downto 0);
signal h_count_reg, h_count_next: unsigned(9 downto 0);
--salidas buffer
signal v_sync_reg, v_sync_next: std_logic;
signal h_sync_reg, h_sync_next: std_logic;
--seales de estados
signal h_end, v_end, pixel_tick: std_logic;
begin
--registros
process(clk,reset)
begin
if(reset='1') then
mod2_reg <= '0';
v_count_reg <= (others => '0');
h_count_reg <= (others => '0');
v_sync_reg <= '0';
h_sync_reg <= '0';
elsif(clk'event and clk='1') then
mod2_reg <= mod2_next;
v_count_reg <= v_count_next;
h_count_reg <= h_count_next;
v_sync_reg <= v_sync_next;
h_sync_reg <= h_sync_next;
end if;
end process;
-- generador de 25Mhz con enable tick
mod2_next <= not mod2_reg;
-- 25Mhz con pixel tick
pixel_tick <= '1' when mod2_reg='1' else '0';
h_end <= '1' when h_count_reg=(HD+HR+HF+HB-1) else '0';
--finaliza contador horizontal(799) y pone en cero
v_end <= '1' when v_count_reg=(VD+VR+VF+VB-1) else '0';
--finaliza contador vertical(524) y pone en cero
--contador modulo 800, para sincronismo horizontal
process(h_count_reg, h_end, pixel_tick)
begin
if(pixel_tick='1') then
if(h_end='1') then
h_count_next <= (others=>'0');
else
h_count_next <= h_count_reg+1;
end if;
else
h_count_next <= h_count_reg;
end if;
end process;
--contador modulo 525, para sincronismo vertical

21

--flancos subida

-- stado

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

process(v_count_reg, h_end, v_end, pixel_tick)


begin
if(pixel_tick='1'and h_end='1') then
if(v_end='1') then
v_count_next <= (others=>'0');
else
v_count_next <= v_count_reg + 1;
end if;
else
v_count_next <= v_count_reg;
end if;
end process;
--tope horizontal y verticcal, para evitar fallos
h_sync_next <= '1' when (h_count_reg>=(HD+HF))
and (h_count_reg<=(HD+HR+HF-1)) else '0';
v_sync_next <= '1' when (v_count_reg>=(VD+VF))
and (v_count_reg<=(VD+VR+VF-1)) else '0';

--656
--751
--690
--491

--VIDEO ON/OFF
video_on <= '1' when ((h_count_reg < HD) and (v_count_reg < VD)) else '0';
--Seales de Salida
hsync <= h_sync_reg;
vsync <= v_sync_reg;
pixel_x <= std_logic_vector(h_count_reg);
pixel_y <= std_logic_vector(v_count_reg);
p_tick <= pixel_tick;
end rtl;

Tabla 2: Modulo de Sincronia en VHDL

3.3.2. Generador de Pixeles: PONGH_GRAPH


Utilizando el Esquema Trazador de Objetos, visto en la seccin 2.3.3, describiremos en
primera instancia los elementos a mostrar en la pantalla objeto a objeto.

Figura17: diagrama de bloques conceptual, de un trazador de objetos

22

Definimos 3 objetos: WALL: pared de rebote, PADDLE: paleta de juego, BALL: baln de
juego.
OBJETOS RECTANGULARES

Figura 18: Elementos primitivos del videojuego PONG

Un objeto rectangular puede ser definido por sus lmites en coordenadas de pantalla yaxis y x-axis(ejes Y y X respectivamente). El juego Bsico cuenta con tres objetos como
muestra la figura 19, la pared (wall), el baln (ball), y la paleta (paddle).

WALL: definamos la generacin de la pared, definiendo dos constantes WALL_X_L y


WALL_X_R tendremos los limites izquierdo como derecho de esta, adems incluimos 2
seales de Salida, wall_on que ser la seal que habilita el dibujo por pixeles de la pared
cuando se va muestreando horizontalmente, y la seal wall_rgb que sera la seal que
defina su color en combinatorio de 3 bits (ver Figura 10).
constant WALL_X_L: integer:=32;
constant WALL_X_R: integer:=35;

-- definiendo pixel a pixel linea vertical izquierda (wall)


wall_on <= '1' when (WALL_X_L<=pix_x) and (pix_x<=WALL_X_R) else '0';

23

-- definiendo salida rgb (wall)


wall_rgb <= "001";

-- azul

Segun el codigo escrito tenemos un ancho en pixeles de la pared de 4, desde el pixel 32


hasta el 35. Adems se define el color de la pared, color azul.

PADDLE: Es una barra vertical (bar) que se define de igual manera que wall, con el
agregado que aparte de tener lmites horizontales (X), tambin se tiene lmites verticales
(Y) superior e inferior, en semejanza se tiene adems las seales bar_on y bar_rgb que
ser el trazador de dibujo y la seal del color respectivamente.
-- limites derecho e izquierdo
constant BAR_X_L: integer:=600;
--left
constant BAR_X_R: integer:=603;
--rigth
-- limites superior e inferior
constant BAR_Y_SIZE: integer:=72;
--tamao del paddle
constant BAR_Y_T: integer:=MAX_Y/2-BAR_Y_SIZE/2; --204
constant BAR_Y_B: integer:=BAR_Y_T+BAR_Y_SIZE-1; --204 (variable)

-- definiendo pixel a pixel linea vertical bar (paddle)


bar_on <= '1' when
(BAR_X_L<=pix_x) and (pix_x<=BAR_X_R) and
(BAR_Y_T<=pix_y) and (pix_y<=BAR_Y_B) else '0';
-- definiendo salida rgb (bar)
bar_rgb <= "010";
--verde

Cabe mencionar que el cdigo muestra una paleta de 72 pixeles verticales por 4
horizontales, las constantes BAR_Y_T y BAR_Y_B, son los limites superior e inferior.
Podramos haber definido como un valor integer solamente, pero se opto con elementos a
manera de variables, por que el paddle se mover de arriba y abajo, as que no tenemos
limites superior (top) e inferior (bottom) fijos.

BALL: De manera similar al paddle(bar), se define el baln.


constant BALL_SIZE: integer:=8;
-- limites derecho e izquierdo
constant BALL_X_L: integer:=580;
constant BALL_X_R: integer:=BALL_X_L+BALL_SIZE-1;
--587
-- limites superior e inferior
constant BALL_Y_T: integer:=238;
constant BALL_Y_B: integer:=ball_Y_T+BALL_SIZE-1; --594 (variable)

-- definiendo pixel a pixel el balon cuadrado (sq_ball)


sq_ball_on <= '1' when (BALL_X_L<=pix_x) and (pix_x<=BALL_X_R) and
(BALL_Y_T<=pix_y) and (pix_y<=BALL_Y_B) else '0';
-- definiendo salida rgb (sq_ball)
ball_rgb <= "100";

24

Como los limites vertical y horizontal cambiaran en el movimiento del balon, se utiliza
variables para definirlos.

El circuito de seleccin y la multiplexacin, que examina las seales de los tres objetos y
rutas de la seal RGB (rgb_mux: figura 18), y que traza los 3 objetos es:
process(video_on, wall_on, wall_rgb, bar_on, bar_rgb, sq_ball_on, ball_rgb)
begin
if (video_on='0') then
graph_rgb<="000";
else
if (wall_on='1') then graph_rgb<=wall_rgb;
elsif (bar_on='1') then graph_rgb<=bar_rgb;
elsif (sq_ball_on='1') then graph_rgb<=ball_rgb;
else graph_rgb<="110";
--fondo amarillo
end if;
end if;
end process;

En los casos en los que no este trazando ningn objeto, el fondo se mostrara color
amarillo, teniendo de esta manera un background de nuestra pantalla.

Entonces el Cdigo en Vhdl para definir nuestro generador de pixeles ser el siguiente:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

------------------------------------------------------------------ Modulo_generador de pixeles


--figuras cuadradas
-- Americo Alvarez Surci
----------------------------------------------------------------library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity pong_graph is
port(
video_on: in std_logic;
pixel_x, pixel_y: in std_logic_vector(9 downto 0);
graph_rgb: out std_logic_vector (2 downto 0)
);
end pong_graph;
architecture rtl of pong_graph is
-- coordenadas de X y Y (0,0) a (639,479), para resolucion 640x480
signal pix_x, pix_y: unsigned (9 downto 0);
constant MAX_X: integer:=640;
constant MAX_Y: integer:=480;
-- variables para linea vertical (wall)
-- limites derecho e izquierdo
constant WALL_X_L: integer:=32;

25

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

constant WALL_X_R: integer:=35;


-- variables para linea vertical (paddle)
-- limites derecho e izquierdo
constant BAR_X_L: integer:=600;
constant BAR_X_R: integer:=603;
-- limites superior e inferior
constant BAR_Y_SIZE: integer:=72;
constant BAR_Y_T: integer:=MAX_Y/2-BAR_Y_SIZE/2;
constant BAR_Y_B: integer:=BAR_Y_T+BAR_Y_SIZE-1;
-- variables para ball cuadrado
constant BALL_SIZE: integer:=8;
-- limites derecho e izquierdo
constant BALL_X_L: integer:=580;
constant BALL_X_R: integer:=BALL_X_L+BALL_SIZE-1;
-- limites superior e inferior
constant BALL_Y_T: integer:=238;
constant BALL_Y_B: integer:=ball_Y_T+BALL_SIZE-1;

--left
--rigth
--tamao del paddle
--204
--204 (variable)

--587
--594 (variable)

-- otras seales
signal wall_on, bar_on, sq_ball_on:std_logic;
signal wall_rgb, bar_rgb, ball_rgb: std_logic_vector(2 downto 0);
begin
pix_x <= unsigned(pixel_x);
pix_y <= unsigned(pixel_y);
-- definiendo pixel a pixel linea vertical izquierda (wall)
wall_on <= '1' when (WALL_X_L<=pix_x) and (pix_x<=WALL_X_R) else '0';
-- definiendo salida rgb (wall)
wall_rgb <= "001";
azul
-- definiendo pixel a pixel linea vertical bar (paddle)
bar_on <= '1' when
(BAR_X_L<=pix_x) and (pix_x<=BAR_X_R) and
(BAR_Y_T<=pix_y) and (pix_y<=BAR_Y_B) else '0';
-- definiendo salida rgb (bar)
bar_rgb <= "010";
--verde
-- definiendo pixel a pixel el balon cuadrado (sq_ball)
sq_ball_on <= '1' when
(BALL_X_L<=pix_x) and (pix_x<=BALL_X_R) and
(BALL_Y_T<=pix_y) and (pix_y<=BALL_Y_B) else '0';
-- definiendo salida rgb (sq_ball)
ball_rgb <= "100";
--rojo
--rgb mux (multiplexor para elegir rgb)
process(video_on, wall_on, wall_rgb, bar_on, bar_rgb, sq_ball_on, ball_rgb)
begin
if (video_on='0') then
graph_rgb<="000";
else
if (wall_on='1') then graph_rgb<=wall_rgb;
elsif (bar_on='1') then graph_rgb<=bar_rgb;
elsif (sq_ball_on='1') then graph_rgb<=ball_rgb;
else graph_rgb<="110";
--fondo amarillo
end if;
end if;
end process;
end rtl;

Tabla 3: Modulo Generador de pixeles, 3 objetos cuadrados.

26

--

Realizado nuestro generador de pixeles, definimos el circuito completo uniendo los


elementos de vga_sync y pong_graph.
Se define una seal pixel_tick, que cuando est habilitada carga la seal rgb al buffer
definido para la salida al monitor, esta seal sirve para sincronizar la salida RGB con las
seales vsync y hsync.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

------------------------------------------------------------------ Modulo_PRUEBA
--Observando Figuras Cuadradas
-- Americo Alvarez Surci
----------------------------------------------------------------library ieee;
use ieee.std_logic_1164.all;
entity pong_esquema is
port(
clk, reset: in std_logic;
hsync, vsync: out std_logic;
rgb: out std_logic_vector(2 downto 0)
);
end pong_esquema;
architecture rtl of pong_esquema is
signal pixel_x, pixel_y: std_logic_vector(9 downto 0);
signal video_on, pixel_tick: std_logic;
signal rgb_reg, rgb_next: std_logic_vector(2 downto 0);
begin
-- modulo vga_sync
vga_sync_unidad: entity work.vga_sync
port map(clk=>clk, reset=>reset, hsync=>hsync, vsync=>vsync, video_on=>video_on, p_tick=>pixel_tick,
pixel_x=>pixel_x, pixel_y=>pixel_y);
--modulo pong_graph (pixel generator)
pong_graph_unidad: entity work.pong_graph
port map(video_on=>video_on, pixel_x=>pixel_x, pixel_y=>pixel_y, graph_rgb=>rgb_next);
--buffer de salida RGB
process (clk)
begin
if (clk'event and clk='1') then
if (pixel_tick='1') then
rgb_reg <= rgb_next;
end if;
end if;
end process;
rgb <= rgb_reg;
end rtl;

Tabla 4: Modulo Prueba 1.

Los cdigos de la tabla 2 y tabla 3 son el modulo de sincrona y el generador de pixeles


para objetos cuadrados, ambos cdigos no se pueden observar fsicamente en su

27

funcionamiento cuando se los carga por separado en el kit de desarrollo xilinx, porque
solo son contadores (modulo de sincrona), y habilitador de pixeles cuando est en cierta
cuenta (generador de pixeles). Por lo que para realizar nuestra primera prueba y observar
que estas descripciones son correctas se procedi a escribir el cdigo presentado en la
tabla 4 que ser implementada en la tarjeta.
Observando que nuestros cdigos anteriores no tiene errores continuamos con el
desarrollo de nuestro proyecto.

3.3.3. Objetos no rectangulares


El diseo directo de un objeto no rectangular utilizando limites en coordenadas es
complicado, una alternativa es especificar el modelo en mapa de bits.

Si queremos

obtener un circulo utilizaremos un modelo de 8 por 8 pixels (figura 20). Para la generacin
del baln redondo seguimos el siguiente procedimiento:

En la exploracin, comprobamos si se traza el baln rectngulo de 8x8 pix.

Si esta en el caso de trazar un cuadrado (visto en anterior inciso), se obtiene el


mapa de bits para generar el baln redondo.

Usando la activacin del crculo, obtenemos una seal para habilitar el rgb para
colorear el crculo.

Figura 19: Mapeo de bits de un Redondo

De igual manera que hicimos en la seccin 2.3.2, se definen todos los parmetros con las
modificaciones siguientes: Para implementar el sistema con baln redondo, tenemos que

28

incluir un ROM para almacenar el patrn del mapa de bits de nuestra forma. El
BALL_ROM tiene por longitud de palabra 8 bits en 8 direcciones. Traza el crculo dentro
del cuadrado cuando se activa el rd_ball_on.
constant BALL_SIZE: integer:=8;
-- limites derecho e izquierdo
signal ball_x_l, ball_x_r: unsigned(9 downto 0);
-- limites superior e inferior
signal ball_y_t, ball_y_b: unsigned(9 downto 0);
--Imagen de BALL redondo utilizando ROM
type rom_type is array (0 to 7) of std_logic_vector(0 to 7);
--definiendo nuestra rom para la forma de balon
constant BALL_ROM: rom_type:=
(
"00111100",
-- ****
"01111110",
-- ******
"11111111",
-- ********
"11111111",
-- ********
"11111111",
-- ********
"11111111",
-- ********
"01111110",
-- ******
"00111100"
-- ****
);
signal rom_addr, rom_col: unsigned (2 downto 0);
signal rom_data: std_logic_vector(7 downto 0);
signal rom_bit: std_logic;
-- seal que indica el mapeo del redondo dentro del cuadrado 8x8
signal rd_ball_on: std_logic;

Adems tendremos que modificar la parte de generacin de pixeles para obtener nuestro
circulo:
-- definiendo pixel a pixel el baln (habilitando seal de mapeo)
sq_ball_on <= '1' when (ball_x_l<=pix_x) and (pix_x<=ball_x_r) and
(ball_y_t<=pix_y) and (pix_y<=ball_y_b) else '0';
-- mapeando el balon segun la ROM (redondo)
rom_addr <= pix_y(2 downto 0) - ball_y_t(2 downto 0);
rom_col <= pix_x(2 downto 0) - ball_x_l(2 downto 0);
rom_data <= BALL_ROM(to_integer(rom_addr));
rom_bit <= rom_data(to_integer(rom_col));
-- habilitando el balon redondo
rd_ball_on <= '1' when (sq_ball_on='1') and (rom_bit='1') else '0';
-- definiendo salida rgb del balon
ball_rgb <= "100";
--rojo

29

Si sq_ball esta en uno se empieza el mapeo de la regin cuadrada 8x8 en la pantalla,


dentro de esta regin mediante la ROM se obtiene las coordenadas de exploracin.
Restando los tres LSB desde el lmite superior (es decir, de ball_y_t) proporciona la fila
correspondiente del ROM (es decir, rom_addr), y restando los tres LSB desde el limite
izquierdo (es decir, ball_x_l), establece la columna ROM (es decir, rom_col).
Finalmente tenemos que hacer modificaciones al circuito de multiplexacion rgb
process(video_on, wa
begin

elsif (rd_ball_on='1') then graph_rgb<=ball_rgb;

end process;

Todas las modificaciones al cdigo de las tablas 2 y 3 descritas en este subtitulo, se las
incluir en la siguiente subseccion.

3.3.4. Animacin: PONG_GRAPH_ANIMADO


Cuando un objeto cambia su ubicacin poco a poco en cada exploracin en pantalla, se
crea la ilusin de movimiento (se anima). Para ello, podemos usar registros para
almacenar los lmites de un objeto y la actualizacin de su valor en cada ciclo reloj. En el
juego

de

ping

pong,

la

paleta

es

controlada

por

dos

pulsadores y se puede mover arriba y abajo, y la pelota puede moverse y rebotar en todas
las direcciones. Estos 2 elementos son los que presentaran animacin.
Si bien el controlador VGA es controlado por una tasa de pxel de 25 MHz, la pantalla del
monitor VGA slo se actualiza 60 veces por segundo. Por tal razn los registros se deben
actualizar a este ritmo. Definimos una seal refr_tick que afirma 60Hz en cada segundo.
Examinemos en primer lugar nuestro generador de pixeles para el paddle, debemos que
cambiar las constantes bar_y_t y bar_y_b por seales (lmite superior e inferior de la
paleta), y adems crear un registro bar_y_reg para almacenar el valor actual del lmite
superior y su actualizacin. Si uno de los botones del control del juego es presionado

30

bar_y_reg aumenta o disminuye, en un valor constante BAR_V que representa la


velocidad de movimiento de la paleta.
Si btn(1) y btn(0) hacen que la paleta se desplace arriba y abajo, el segmento de cdigo
para la actualizacin del bar_y_reg es:
-- nueva posicion en Y del paddle.
process (bar_y_reg, bar_y_t, refr_tick, btn)
begin
bar_y_next <= bar_y_reg;
--no se mueve
if (refr_tick='1') then
if (btn(1)='1') and (bar_y_b<(MAX_Y-BAR_V-1)) then
bar_y_next <= bar_y_reg + BAR_V;
--movimiento hacia abajo
elsif (btn(0)='1') and (bar_y_t>BAR_V) then
bar_y_next <=bar_y_reg - BAR_V;
--movimiento hacia arriba
end if;
end if;
end process;

Ahora enfoquemos el problema del baln, tenemos que cambiar las cuatro constantes
limite por cuatro seales y crear 2 registros ball_x_reg y ball_y_reg para obtener los
movimientos horizontales y verticales del baln, actualizando valores de posicin del
baln. El baln se mueve a velocidad constante en una misma direccin, la direccin
puede cambiar cuando bota en las paredes o en el paddle pero no cambia la velocidad.
La velocidad la descomponemos en componentes X y componentes Y, cuyos valores de
velocidad pueden ser positivos BALL_V_P, o negativos BALL_V_N. Los valores actuales
de las componentes las guardamos en registros x_delta_reg y y_delta_reg; el segmento
de cdigo para la actualizacin de ball_x_reg y ball_y_reg es:
-- posicionando el balon en pantalla
ball_x_next <= ball_x_reg + x_delta_reg when refr_tick='1' else ball_x_reg;
ball_y_next <= ball_y_reg + y_delta_reg when refr_tick='1' else ball_y_reg;

y el segmento de cdigo para la actualizacin, teniendo en cuenta la velocidad del baln


guardado en registros delta:
-- posicionando por velocidad
process(x_delta_reg, y_delta_reg, ball_y_t, ball_x_l, ball_x_r, ball_y_b, bar_y_t, bar_y_b)
begin
x_delta_next <= x_delta_reg;

31

y_delta_next <= y_delta_reg;


if (ball_y_t < 1) then
y_delta_next <= BALL_V_P;
elsif (ball_y_b > (MAX_Y-1)) then
y_delta_next <= BALL_V_N;
elsif (ball_x_l <= WALL_X_R) then
x_delta_next <= BALL_V_P;
elsif (BAR_X_L<=ball_x_r) and (ball_x_r<=BAR_X_R) then
if (bar_y_t<=ball_y_b) and (ball_y_t<=bar_y_b) then
x_delta_next <= BALL_V_N;
end if;
end if;
end process;

-- alcance superior
-- alcance inferior
-- alcance del wall

-- registro de mov.

Cabe mencionar que igual que el juego, cuando fallamos en acertarle al baln con la
paleta esta seguir su curso perdindose posteriormente.
A continuacin se presenta el cdigo del generador de pixeles, con animacin:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

------------------------------------------------------------------ Modulo_ Generador de pixeles


--Genera 2 objetos rectangulare (wall, paddle) adems de
--un objeto redondo. INCLUYE ANIMACION
-- Americo Alvarez Surci
----------------------------------------------------------------library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity pong_graph_animado is
port(
clk, reset: std_logic;
btn: std_logic_vector(1 downto 0);
video_on:in std_logic;
pixel_x, pixel_y: in std_logic_vector(9 downto 0);
graph_rgb: out std_logic_vector(2 downto 0)
);
end pong_graph_animado;
architecture rtl of pong_graph_animado is
signal refr_tick: std_logic;
-- coordenadas de X y Y (0,0) a (639,479), para resolucion 640x480
signal pix_x, pix_y: unsigned (9 downto 0);
constant MAX_X: integer:=640;
constant MAX_Y: integer:=480;
-- variables para linea vertical (wall)
-- limites derecho e izquierdo
constant WALL_X_L: integer:=32;
constant WALL_X_R: integer:=40;
-- variables para linea vertical (paddle)
-- limites derecho e izquierdo
constant BAR_X_L: integer:=600;
constant BAR_X_R: integer:=608;
-- limites superior e inferior
signal bar_y_t, bar_y_b: unsigned (9 downto 0); --xxxxxxxxxxxxxxxxxxx

32

--left
--rigth

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102

constant BAR_Y_SIZE: integer:=72;


-- registro mov. limite superior (posicion x fija)
signal bar_y_reg, bar_y_next: unsigned (9 downto 0);
-- movimiento del paddle cuando se preciona button (velocidad)
constant BAR_V: integer:=4;
-- variables para ball cuadrado (movimientos basicos no visual)
constant BALL_SIZE: integer:=8;
-- limites derecho e izquierdo
signal ball_x_l, ball_x_r: unsigned(9 downto 0);
-- limites superior e inferior
signal ball_y_t, ball_y_b: unsigned(9 downto 0);
-- registro mov. izquierda + limite superior
signal ball_x_reg, ball_x_next: unsigned (9 downto 0);
signal ball_y_reg, ball_y_next: unsigned (9 downto 0);
-- registro mov. de la velocidad del ball
signal x_delta_reg, x_delta_next: unsigned (9 downto 0);
signal y_delta_reg, y_delta_next: unsigned (9 downto 0);
-- velocidad de ball segun la posicion o registro
constant BALL_V_P: unsigned (9 downto 0):=to_unsigned(2,48);
constant BALL_V_N: unsigned (9 downto 0):=unsigned(to_signed(-2,48));
--Imagen de BALL redondo utilizando ROM
type rom_type is array (0 to 7) of std_logic_vector(0 to 7);
--definiendo nuestra rom para la forma de balon
constant BALL_ROM: rom_type:=
(
"00111100",
-- ****
"01111110",
-- ******
"11111111",
-- ********
"11111111",
-- ********
"11111111",
-- ********
"11111111",
-- ********
"01111110",
-- ******
"00111100"
-- ****
);
signal rom_addr, rom_col: unsigned (2 downto 0);
signal rom_data: std_logic_vector(7 downto 0);
signal rom_bit: std_logic;
-- otras seales
signal wall_on, bar_on, sq_ball_on, rd_ball_on: std_logic;
signal wall_rgb, bar_rgb, ball_rgb: std_logic_vector(2 downto 0);
begin
-- registros
process(clk, reset)
begin
if (reset='1') then
bar_y_reg <= (others=>'0');
ball_x_reg <= (others=>'0');
ball_y_reg <= (others=>'0');
x_delta_reg <= ("0000000100");
y_delta_reg <= ("0000000100");
elsif(clk'event and clk='1') then
bar_y_reg <= bar_y_next;
ball_x_reg <= ball_x_next;
ball_y_reg <= ball_y_next;
x_delta_reg <= x_delta_next;
y_delta_reg <= y_delta_next;
end if;
end process;
pix_x <= unsigned (pixel_x);
pix_y <= unsigned (pixel_y);

33

--tamao del paddle

103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166

refr_tick <= '1' when (pix_y=481) and (pix_x=0) else '0';


-- definiendo pixel a pixel linea vertical izquierda (wall)
wall_on <= '1' when (WALL_X_L<=pix_x) and (pix_x<=WALL_X_R) else '0';
-- definiendo salida rgb (wall)
wall_rgb <= "001";
--azul
-- definiendo el bar (paddle)
-- limites
bar_y_t <= bar_y_reg;
bar_y_b <= bar_y_t+BAR_Y_SIZE-1;
-- habilitando el paddle
bar_on <= '1' when
(BAR_X_L<=pix_x) and (pix_x<=BAR_X_R) and
(bar_y_t<=pix_y) and (pix_y<=bar_y_b) else '0';
-- definiendo salida rgb (bar)
bar_rgb <= "010";
--verde
-- nueva posicion en Y del paddle.
process (bar_y_reg, bar_y_t, bar_y_b, refr_tick, btn)
begin
bar_y_next <= bar_y_reg;
--no se mueve
if (refr_tick='1') then
if (btn(1)='1') and (bar_y_b<(MAX_Y-BAR_V-1)) then
bar_y_next <= bar_y_reg + BAR_V;
--movimiento hacia abajo
elsif (btn(0)='1') and (bar_y_t>BAR_V) then
bar_y_next <=bar_y_reg - BAR_V;
--movimiento hacia arriba
end if;
end if;
end process;
-- definiendo balon
-- limites
ball_x_l <= ball_x_reg;
ball_y_t <= ball_y_reg;
ball_x_r <= ball_x_l + BALL_SIZE - 1;
ball_y_b <= ball_y_t + BALL_SIZE - 1;
-- definiendo pixel a pixel el balon (habilitando seal de mapeo)
sq_ball_on <= '1' when
(ball_x_l<=pix_x) and (pix_x<=ball_x_r) and
(ball_y_t<=pix_y) and (pix_y<=ball_y_b) else '0';
-- mapeando el balon segun la ROM (redondo)
rom_addr <= pix_y(2 downto 0) - ball_y_t(2 downto 0);
rom_col <= pix_x(2 downto 0) - ball_x_l(2 downto 0);
rom_data <= BALL_ROM(to_integer(rom_addr));
rom_bit <= rom_data(to_integer(rom_col));
-- habilitando el balon redondo
rd_ball_on <= '1' when (sq_ball_on='1') and (rom_bit='1') else '0';
-- definiendo salida rgb del balon
ball_rgb <= "100";
--rojo
-- posicionando el balon en pantalla
ball_x_next <= ball_x_reg + x_delta_reg when refr_tick='1' else ball_x_reg;
ball_y_next <= ball_y_reg + y_delta_reg when refr_tick='1' else ball_y_reg;
-- posicionando por velocidad
process(x_delta_reg, y_delta_reg, ball_y_t, ball_x_l, ball_x_r, ball_y_b, bar_y_t, bar_y_b)
begin
x_delta_next <= x_delta_reg;
y_delta_next <= y_delta_reg;
if (ball_y_t < 1) then
-- alcance superior
y_delta_next <= BALL_V_P;
elsif (ball_y_b > (MAX_Y-1)) then
-- alcance inferior
y_delta_next <= BALL_V_N;
elsif (ball_x_l <= WALL_X_R) then
-- alcance del wall
x_delta_next <= BALL_V_P;
elsif (BAR_X_L<=ball_x_r) and (ball_x_r<=BAR_X_R) then

34

167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186

if (bar_y_t<=ball_y_b) and (ball_y_t<=bar_y_b) then


x_delta_next <= BALL_V_N;
end if;

--MOV. registro

end if;
end process;
--rgb mux (multiplexor para elegir rgb)
process(video_on, wall_on, bar_on, rd_ball_on, wall_rgb, bar_rgb, ball_rgb)
begin
if (video_on='0') then
graph_rgb<="000";
--negro
else
if (wall_on='1') then graph_rgb<=wall_rgb;
elsif (bar_on='1') then graph_rgb<=bar_rgb;
elsif (rd_ball_on='1') then graph_rgb<=ball_rgb;
else graph_rgb<="011";
--fondo amarillo
end if;
end if;
end process;
end rtl;

Tabla 5: Generador de Pixeles, con animacin

Para lo rebotes del baln en las paredes horizontales y verticales, se utilizo los registros:
x_delta_reg, x_delta_next, y_delta_reg, y_delta_next; que son registros que actualizaran los

de posicin de baln ball_x_reg y ball_y_reg.

Figura 20: Movimiento del baln en Rebotes de Esquina

35

3.4 PROGRAMA PRINCIPAL: JUEGO_PONG


En la anterior seccin se mostro todo el procedimiento que se sigui en la elaboracin de
este videojuego, se presento en primera instancia el diseo de un circuito de
sincronizacin VGA_SYNC, luego se procedi a definir un generador de pixeles bsico
para este juego, que mostraba en pantalla 3 elementos rectangulares PONG_GRAPH
adems en este mismo apartado se mostro la descripcin completa de este modulo
pong_graph con el modulo vga_sync a manera de depurar posibles errores cometidos con
la elaboracin de alguna de estas descripciones, PONG_ESQUEMA fue el modulo con el
que

verificamos esto, adems nos dio un avance de cmo sera nuestro programa

principal utilizando 2 mdulos.


Luego se procedi a mejorar el aspecto visual, y realizar un baln redondo, utilizando
como base de referencia nuestro pong_graph. Una vez definido como realizaremos el
baln redondo se procedi a realizar nuestro generador de pixeles con un agregado
importante la animacin, PONG_GRAPH_ANIMADO nos da la base principal de un
sistema de juego planteado en nuestro problema.
A continuacin se presenta programa principal (modulo juego_pong), que ser la
culminacin del presente trabajo, incluye los mdulos vga_sync y el pong_graph_animado:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

library ieee;
use ieee.std_logic_1164.all;
entity juego_pong is
port(
clk, reset:in std_logic;
btn:in std_logic_vector(1 downto 0);
hsync, vsync: out std_logic;
rgb: out std_logic_vector(2 downto 0)
);
end juego_pong;
architecture rtl of juego_pong is
signal pixel_x, pixel_y: std_logic_vector(9 downto 0);
signal video_on, pixel_tick: std_logic;
signal rgb_reg, rgb_next: std_logic_vector(2 downto 0);
begin
unidad_sincronia_vga: entity work.vga_sync
port map(clk=>clk, reset=>reset, video_on=>video_on, p_tick=>pixel_tick, hsync=>hsync, vsync=>vsync,
pixel_x=>pixel_x, pixel_y=>pixel_y);
unidad_pong_graph_animado: entity work.pong_graph_animado
port map(clk=>clk, reset=>reset, btn=>btn, video_on=>video_on, pixel_x=>pixel_x, pixel_y=>pixel_y,

36

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

graph_rgb=>rgb_next);
-- definiendo salida rgb en flancos subida de periodo de clock
process (clk)
begin
if (clk'event and clk='1') then
if (pixel_tick='1') then
rgb_reg <= rgb_next;
end if;
end if;
end process;
rgb <= rgb_reg;
end rtl;

Tabla 6: Modulo Final, videojuego PONG en VHDL

37

Capitulo 4
CONCLUSIONES Y MEJORAS
4.1 CONCLUSIONES
Se describi un monitor CRT para computadora y se trabajo directamente en el puerto de
salida VGA de la tarjeta Xilinx.
Se defini cada seal del conector vga. La seal de sincronismo se la trato en un
principio, y se la defini con contadores distintos.
El circuito generador de pixeles se lo trato en diferentes niveles, primeramente generando
figuras bsicas, luego con figuras definidas en una ROM. Adems se vio que para la
animacin se utilizo registros varios.

Con el avanzar, de prueba y error en cdigo vhdl, se pudo implementar de manera exitosa
el videojuego en la tarjeta XILINX spartan-3an.

Se dio bases para futuros experimentos en tarjetas fpga, ya que el cdigo en VHDL
planteado se lo escribi de la manera ms desglosada y explicando todas las sentencias y
valores crticos. Los mdulos presentados son aptos para la sntesis, ya que muchas
lneas son reducibles y fusionarles.

38

4.1 MEJORAS
El sistema descrito en este proyecto, es a manera de introduccin a proyectos mas
grandes utilizando la tarjeta XILINX, por lo que se puede incluir muchas mejoras a este
modulo de juego.
1. Incluir otro jugador, para que se parezca ms al juego de PING-PONG de 2
jugadores.
2. Incluir un interfaz de juego. Un teclado ps2 para que 2 jugadores lo utilicen como
controles de juego.
3. Incluir texto al esquema generador de pixeles. Adems de un texto que indique los
puntos de ambos jugadores.
4. Mediante la memoria RAM de la tarjeta, incluir una presentacin en imgenes de
mapa de bits. A manera de modo de espera.
5. Adems mediante la RAM tambin definir una imagen de fondo, a manera de
escenario de juego (background).
6. Incluir sonidos, para el bote del baln en las paletas, adems msica de fondo en
midi.
5. BIBLIOGRAFIA

Digital Logic And Microprocessor Design With VHDL

Circuit Design with VHDL (2005)

http://members.optusnet.com.au/jekent/FPGA.htm#Section5.1

http://hoper3d.blogspot.com/2008/09/vhdl-pong.html

http://es.scribd.com/doc/55055785/pingpong
39

Hwang

MIT

Press

6. ANEXOS

Implementacion en laboratorio utilizando Tarjeta XILINX Spartan 3AN

Campo de Juego el videojuego implementado

40

Vous aimerez peut-être aussi