Documentos de Académico
Documentos de Profesional
Documentos de Cultura
FACULTAD DE INGENIERIA
MATERIA : PROYECTO II
ESTUDIANTE:
GESTION 2011
LA PAZ - BOLIVIA
A mis Padres que nunca dejaron de apoyarme
II
Resumen
“PONG”, un video juego sencillo, es la representación del deporte de TENIS, que consiste
en hacer botar el balón en una paleta a otra sin equivocarse. En el presente proyecto
describimos el movimiento del balón y de la paleta en un campo diseñado para tal
cometido. Analizamos el monitor VGA para poder describir un controlador del mismo,
Por ultimo mostraremos como el monitor brinda el campo de juego y también 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
Finally we show how the monitor provides the playing field and will make the interface
III
LISTA DE FIGURAS
IV
Figura 20: Movimiento del balón en Rebotes de Esquina
LISTA DE TABLAS
V
INDICE GENERAL
Resumen/Abstract III
Lista de Figuras IV
Lita de Tablas V
1.1 Introducción 1
1.2. Objetivos 2
2.2 VHDL 6
2.3 VGA. 10
VI
2.3.3 Generador de Pixeles
Objetos Rectangulares
4.1 Conclusiones 38
4. 2 Mejoras 39
5. BIBLIOGRAFÍA 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”
cuantos metros cuadrados. Aunque ya existía el primer microprocesador, hecho por Intel
en 1970, no fue utilizado aún, por su reciente lanzamiento al mercado, alto coste y
ausencia de documentación.
Atari Pong fue una consola creada por Atari en 1975, es la segunda videoconsola de la
El jugador controla en el juego una paleta que tiene un movimiento rectilíneo, haciendo las
veces de paleta para que la pelota rebote en esta y en las paredes del espacio de juego.
1
1.2. OBJETIVOS
contadores.
2
Capitulo 2
MARCO TEORICO
Los lenguajes de descripción hardware son lenguajes de alto nivel con una sintaxis similar
a los de programación (C, ADA, Pascal, Modula, etc.) y una semántica que permite el
modelado y simulación de los dispositivos hardware a diferentes niveles de abstracción.
Los primeros lenguajes de este tipo sólo pretendían servir de vehículo de comunicación
del diseño. Los actuales lenguajes han adquirido un alto grado de estandarización y han
Fue desarrollado por Yaohan Chu a comienzo de los años 60 bajo el principio de
uno entre los objetos y operaciones hardware (registros, RAMs, relojes, suma, cuenta,
etc.) y las construcciones del lenguaje. La primera versión del simulador CDL para IBM
7090 estuvo disponible en 1968, y la versión tercera para Univac pocos años más tarde.
3
DDL (Digital systems Design Language)
del diseño.
Fue propuesto por F.J. Hill y G.R. Peterson unos meses más tarde que el CDL y DDL, y
apareció publicado por primera vez en 1973 en la edición original de Digital Systems:
Hardware Organization and Design. Los autores concibieron AHPL como un lenguaje de
síntesis: todo dispositivo síncrono que pudiese ser implementado en hardware debía ser
expresable en AHPL de manera tal que se pudiese traducir a una realización física
siguiendo un conjunto simple de reglas. En opinión de uno de sus autores, F.J. Hill, que
participó como miembro del grupo de trabajo que formuló las especificaciones originales
Con este lenguaje se dio un paso importante hacia la formalización del proceso de diseño
a niveles de comportamiento. Además de la simulación y la síntesis, ISPS se utilizó en la
ISPS favoreció los aspectos de comportamiento sobre los estructurales pero sin
eliminarlos completamente.
4
antiguos lenguajes usados allá por 1968, concretamente el TIBSD (TI Boolean System
circuitos impresos, y Fusim (Functional Simulator), utilizado para describir modelos de alto
Verilog
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 versión del Hardware Description Language Reference Manual.
compañías japonesas tales como NTT. Una de las características de UDL/I es que
pretende ser específico para modelar circuitos integrados. La única unidad de diseño
de un circuito integrado que consta de varias subunidades o módulos, cada uno de los
5
2.2 VHDL
Very High Speed Integrated Circuit Hardware Description Language (VHSIC HDL).
década de los 70's. El propósito era hacer un estándar para diseñar, modelar, y
documentar circuitos complejos de manera que un diseño desarrollado por una empresa
pudiera ser entendido por otra, además, que pudiera ser procesado por software para
propósitos de simulación.
Lo que ha hecho que VHDL sea en un tiempo tan corto el lenguaje de descripción de
hardware más utilizado por la industria electrónica, es su independencia con la
6
Si queremos definir cualquier elemento digital tenemos que enfocarnos en 2 bloques de
Arquitectura.
interfaz de los dispositivos. Cumple, por tanto, funciones equivalentes a las de los
Entidad, por lo que se puede considerar el equivalente a las tablas de verdad o a los
cronogramas.
7
En la Declaración de Entidad se define el nombre del dispositivo y sus puertos; en el
el momento en que las unidades VHDL que lo describen quedan almacenadas en una
librería VHDL. Para ello hay que editar las unidades y compilarlas. En el proceso de
compilación se comprueba que no se incumplen una serie de reglas sintácticas y
semánticas.
(sentencias, declaraciones, etc.). Estas unidades son descritas con la declaración Entidad
Las librerías de vhdl, representa la unión de varias unidades de diseño mínimas, para
8
deberá tener un modulo principal que haga el llamado a cualquier modulo según sea el
caso.
Hay que mencionar además que hay que incluir las librerías, en la declaración de
de una librería creada por usuario. Cabe mencionar que los componentes de “milibreria”
9
no se los aprecia, pero son descripciones básicas de una compuerta and de 3 entradas y
2.3 VGA
El término Video Graphics Array (VGA) Sistema gráfico de pantallas para PC que se
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 deflexión vertical y otra vertical,
generan campos magnéticos variables que controlan la dirección del haz de electrones, y
así poder realizar el trazado de toda la pantalla. Ósea que siguen un patrón fijo de
Osciladores internos del monitor generan formas de onda diente de sierra para controlar
las dos bobinas de deflexión. Por ejemplo, si el haz de electrones se mueve desde el
exceptuando que tiene 3 haces de electrones que inciden en los puntos de fósforo rojo,
verde y azul en la pantalla. Los tres puntos se combinan para formar un píxel. Podemos
ajustar los niveles de tensión de la entrada de video de tres señales para obtener el color
11
Tabla 1: Combinación a 3 bits, RGB
El puerto VGA tiene cinco señales activas: señales de sincronización horizontal y vertical
(hsync y vsync), y tres señales de vídeo para el rojo, verde y azul. Un controlador de
necesario para el recorrido (exploración) una fila, y la señal 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 píxel de 25 MHz,
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
13
Display: Región en que los pixeles son observables. Longitud de 640 pix.
Retrace: Región en la que los haces de electrones regresan a la izquierda. La
señal de video debe de estar desactivada. Longitud 96 pix.
hacia abajo y luego vuelve arriba. Esto traza toda la pantalla fila a fila. Hay mucho
14
Retrace: Región en la que los haces de electrones regresan a la parte superior
de la pantalla. La señal de video debe de estar desactivada. Longitud 2 pix.
La señal de Vsync se puede obtener con un contador modulo 525. El Bottom y top border
El parámetro “s” especifica la rapidez con la pantalla debe ser restaurada. Para un ojo
humano, la frecuencia de actualización debe ser al menos 30 pantallas por segundo para
manera:
pixels
pixel _ rate p L s 25M
second
15
2.3.3. Generador de Pixeles
El circuito de generación de de píxeles genera la señal RGB de 3 bits para el puerto VGA.
Existen tres grandes grupos en los que podemos dividir los generadores de pixeles:
Esquemas de mapa de bits: Se traza gráficos desde una memoria, pixel a pixel. Esto
consume mucha memoria, ya que cada grafico debe de estar guardado en mapa de
bits
Este sistema es el que utilizaremos de aquí en adelante para describir el video juego
planteado.
16
Capitulo 3
XILINX SPARTAN-3AN
o 4-Mbyte SRAM
17
o 4 switches deslizables
o 1 Osciladores de 50-MHz.
o 1 puerto VGA.
o 10/100 controlador de red con su conector
o 1 core microblaze
o 4 salidas de DAC
o 2 entradas a ADC
Monitor VGA
18
Fig.15: Conexión VGA, con salidas del FPGA
manera de mando (control 1 player), que manejara la paleta donde botara la pelota del
Enviar
Reset
Movimiento balon
Boton
Arriba
19
3.3 ELABORACION Y EJECUCION DEL VIDEOJUEGO PONG
modulo, siguiendo el esquema de la Figura 10. Luego se procederá a la mejora del código
y posteriormente a la animación.
El circuito de sincronía VGA descrito en la sección 2.3.1. Trabaja con una frecuencia de
25Mhz. El circuito esta implementado con 2 contadores: uno de modulo 800 para el
La tarjeta Xilinx Spartar-3an tiene un oscilador interno de 50Mhz. Por lo que se procederá
11 y 12 (márgenes, display, top, bottom, etc) son indicados y pueden ser cambiados
fácilmente si se requiere.
Para evitar fallas potenciales, se incluye buffers a la salida de las señales hsync y vsync,
esto nos llevara a un retraso de ciclo de reloj, que se corregirá posteriormente añadiendo
otro buffer a la salida vga, que observaremos en el generador de pixeles más adelante.
1 -----------------------------------------------------------------
2 -- Modulo_ señales de sincronía monitor VGA
3 -- Américo Alvarez Surci
4 -----------------------------------------------------------------
5 library ieee;
6 use ieee.std_logic_1164.all;
7 use ieee.numeric_std.all;
8
9 entity vga_sync is
10 port(
11 clk,reset: in std_logic;
12 hsync,vsync: out std_logic; --señales de syncronismo
13 video_on, p_tick: out std_logic;
14 pixel_x,pixel_y: out std_logic_vector(9 downto 0) --contador de pixels 800x525
15 );
20
16 end vga_sync;
17
18 architecture rtl of vga_sync is
19
20 --vga 640 por 480, parametros de sirncronia
21 constant HD: integer:=640; --trazado horizontal
22 constant HR:integer:=96; --recarga horizontal
23 constant HF:integer:=16; --margen derecho
24 constant HB:integer:=48; --margen izquierdo
25 constant VD:integer:=480; --trazado vertical
26 constant VR:integer:=2; --recarga vertical
27 constant VF:integer:=10; --margen inferior
28 constant VB:integer:=33; --margen superior
29 --Contador modulo 2
30 signal mod2_reg, mod2_next:std_logic;
31 --señal de contadores para la sincronia vertical y horizontal
32 signal v_count_reg, v_count_next: unsigned(9 downto 0);
33 signal h_count_reg, h_count_next: unsigned(9 downto 0);
34 --salidas buffer
35 signal v_sync_reg, v_sync_next: std_logic;
36 signal h_sync_reg, h_sync_next: std_logic;
37 --señales de estados
38 signal h_end, v_end, pixel_tick: std_logic;
39
40 begin
41 --registros
42 process(clk,reset)
43 begin
44 if(reset='1') then
45 mod2_reg <= '0';
46 v_count_reg <= (others => '0');
47 h_count_reg <= (others => '0');
48 v_sync_reg <= '0';
49 h_sync_reg <= '0';
50 elsif(clk'event and clk='1') then --flancos subida
51 mod2_reg <= mod2_next;
52 v_count_reg <= v_count_next;
53 h_count_reg <= h_count_next;
54 v_sync_reg <= v_sync_next;
55 h_sync_reg <= h_sync_next;
56 end if;
57 end process;
58 -- generador de 25Mhz con enable tick
59 mod2_next <= not mod2_reg;
60 -- 25Mhz con pixel tick
61 pixel_tick <= '1' when mod2_reg='1' else '0'; -- stado
62 h_end <= '1' when h_count_reg=(HD+HR+HF+HB-1) else '0';
63 --finaliza contador horizontal(799) y pone en cero
64 v_end <= '1' when v_count_reg=(VD+VR+VF+VB-1) else '0';
65 --finaliza contador vertical(524) y pone en cero
66 --contador modulo 800, para sincronismo horizontal
67 process(h_count_reg, h_end, pixel_tick)
68 begin
69 if(pixel_tick='1') then
70 if(h_end='1') then
71 h_count_next <= (others=>'0');
72 else
73 h_count_next <= h_count_reg+1;
74 end if;
75 else
76 h_count_next <= h_count_reg;
77 end if;
78 end process;
79 --contador modulo 525, para sincronismo vertical
21
80 process(v_count_reg, h_end, v_end, pixel_tick)
81 begin
82 if(pixel_tick='1'and h_end='1') then
83 if(v_end='1') then
84 v_count_next <= (others=>'0');
85 else
86 v_count_next <= v_count_reg + 1;
87 end if;
88 else
89 v_count_next <= v_count_reg;
90 end if;
91 end process;
92 --tope horizontal y verticcal, para evitar fallos
93 h_sync_next <= '1' when (h_count_reg>=(HD+HF)) --656
94 and (h_count_reg<=(HD+HR+HF-1)) else '0'; --751
95 v_sync_next <= '1' when (v_count_reg>=(VD+VF)) --690
96 and (v_count_reg<=(VD+VR+VF-1)) else '0'; --491
97
98 --VIDEO ON/OFF
99 video_on <= '1' when ((h_count_reg < HD) and (v_count_reg < VD)) else '0';
100 --Señales de Salida
101 hsync <= h_sync_reg;
102 vsync <= v_sync_reg;
103 pixel_x <= std_logic_vector(h_count_reg);
104 pixel_y <= std_logic_vector(v_count_reg);
105 p_tick <= pixel_tick;
106 end rtl;
107
22
Definimos 3 objetos: WALL: pared de rebote, PADDLE: paleta de juego, BALL: balón de
juego.
OBJETOS RECTANGULARES
Un objeto rectangular puede ser definido por sus límites en coordenadas de pantalla y-
axis y x-axis(ejes Y y X respectivamente). El juego Básico cuenta con tres objetos como
muestra la figura 19, la pared (wall), el balón (ball), y la paleta (paddle).
señales de Salida, wall_on que será la señal que habilita el dibujo por pixeles de la pared
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
PADDLE: Es una barra vertical (bar) que se define de igual manera que wall, con el
agregado que aparte de tener límites horizontales (X), también se tiene límites verticales
(Y) superior e inferior, en semejanza se tiene además las señales bar_on y bar_rgb que
horizontales, las constantes BAR_Y_T y BAR_Y_B, son los limites superior e inferior.
Podríamos 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
24
Como los limites vertical y horizontal cambiaran en el movimiento del balon, se utiliza
El circuito de selección y la multiplexación, que examina las señales de los tres objetos y
rutas de la señal 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 ningún objeto, el fondo se mostrara color
Entonces el Código en Vhdl para definir nuestro generador de pixeles será el siguiente:
1 -----------------------------------------------------------------
2 -- Modulo_generador de pixeles
3 --figuras cuadradas
4 -- Americo Alvarez Surci
5 -----------------------------------------------------------------
6 library ieee;
7 use ieee.std_logic_1164.all;
8 use ieee.numeric_std.all;
9
10 entity pong_graph is
11 port(
12 video_on: in std_logic;
13 pixel_x, pixel_y: in std_logic_vector(9 downto 0);
14 graph_rgb: out std_logic_vector (2 downto 0)
15 );
16 end pong_graph;
17
18 architecture rtl of pong_graph is
19
20 -- coordenadas de X y Y (0,0) a (639,479), para resolucion 640x480
21 signal pix_x, pix_y: unsigned (9 downto 0);
22 constant MAX_X: integer:=640;
23 constant MAX_Y: integer:=480;
24
25 -- variables para linea vertical (wall)
26 -- limites derecho e izquierdo
27 constant WALL_X_L: integer:=32;
25
28 constant WALL_X_R: integer:=35;
29
30 -- variables para linea vertical (paddle)
31 -- limites derecho e izquierdo
32 constant BAR_X_L: integer:=600; --left
33 constant BAR_X_R: integer:=603; --rigth
34 -- limites superior e inferior
35 constant BAR_Y_SIZE: integer:=72; --tamaño del paddle
36 constant BAR_Y_T: integer:=MAX_Y/2-BAR_Y_SIZE/2; --204
37 constant BAR_Y_B: integer:=BAR_Y_T+BAR_Y_SIZE-1; --204 (variable)
38
39 -- variables para ball cuadrado
40 constant BALL_SIZE: integer:=8;
41 -- limites derecho e izquierdo
42 constant BALL_X_L: integer:=580;
43 constant BALL_X_R: integer:=BALL_X_L+BALL_SIZE-1; --587
44 -- limites superior e inferior
45 constant BALL_Y_T: integer:=238;
46 constant BALL_Y_B: integer:=ball_Y_T+BALL_SIZE-1; --594 (variable)
47
48 -- otras señales
49 signal wall_on, bar_on, sq_ball_on:std_logic;
50 signal wall_rgb, bar_rgb, ball_rgb: std_logic_vector(2 downto 0);
51
52 begin
53 pix_x <= unsigned(pixel_x);
54 pix_y <= unsigned(pixel_y);
55
56 -- definiendo pixel a pixel linea vertical izquierda (wall)
57 wall_on <= '1' when (WALL_X_L<=pix_x) and (pix_x<=WALL_X_R) else '0';
58 -- definiendo salida rgb (wall)
59 wall_rgb <= "001"; --
60 azul
61
62 -- definiendo pixel a pixel linea vertical bar (paddle)
63 bar_on <= '1' when (BAR_X_L<=pix_x) and (pix_x<=BAR_X_R) and
64 (BAR_Y_T<=pix_y) and (pix_y<=BAR_Y_B) else '0';
65 -- definiendo salida rgb (bar)
66 bar_rgb <= "010"; --verde
67
68 -- definiendo pixel a pixel el balon cuadrado (sq_ball)
69 sq_ball_on <= '1' when (BALL_X_L<=pix_x) and (pix_x<=BALL_X_R) and
70 (BALL_Y_T<=pix_y) and (pix_y<=BALL_Y_B) else '0';
71 -- definiendo salida rgb (sq_ball)
72 ball_rgb <= "100"; --rojo
73
74 --rgb mux (multiplexor para elegir rgb)
75 process(video_on, wall_on, wall_rgb, bar_on, bar_rgb, sq_ball_on, ball_rgb)
76 begin
77 if (video_on='0') then
78 graph_rgb<="000";
79 else
80 if (wall_on='1') then graph_rgb<=wall_rgb;
81 elsif (bar_on='1') then graph_rgb<=bar_rgb;
82 elsif (sq_ball_on='1') then graph_rgb<=ball_rgb;
83 else graph_rgb<="110"; --fondo amarillo
84 end if;
85 end if;
86 end process;
87 end rtl;
26
Realizado nuestro generador de pixeles, definimos el circuito completo uniendo los
Se define una señal pixel_tick, que cuando está habilitada carga la señal rgb al buffer
definido para la salida al monitor, esta señal sirve para sincronizar la salida RGB con las
1 -----------------------------------------------------------------
2 -- Modulo_PRUEBA…
3 --Observando Figuras Cuadradas
4 -- Americo Alvarez Surci
5 -----------------------------------------------------------------
6 library ieee;
7 use ieee.std_logic_1164.all;
8
9 entity pong_esquema is
10 port(
11 clk, reset: in std_logic;
12 hsync, vsync: out std_logic;
13 rgb: out std_logic_vector(2 downto 0)
14 );
15 end pong_esquema;
16
17 architecture rtl of pong_esquema is
18 signal pixel_x, pixel_y: std_logic_vector(9 downto 0);
19 signal video_on, pixel_tick: std_logic;
20 signal rgb_reg, rgb_next: std_logic_vector(2 downto 0);
21 begin
22 -- modulo vga_sync
23 vga_sync_unidad: entity work.vga_sync
24 port map(clk=>clk, reset=>reset, hsync=>hsync, vsync=>vsync, video_on=>video_on, p_tick=>pixel_tick,
25 pixel_x=>pixel_x, pixel_y=>pixel_y);
26
27 --modulo pong_graph (pixel generator)
28 pong_graph_unidad: entity work.pong_graph
29 port map(video_on=>video_on, pixel_x=>pixel_x, pixel_y=>pixel_y, graph_rgb=>rgb_next);
30
31 --buffer de salida RGB
32 process (clk)
33 begin
34 if (clk'event and clk='1') then
35 if (pixel_tick='1') then
36 rgb_reg <= rgb_next;
37 end if;
38 end if;
39 end process;
40 rgb <= rgb_reg;
41 end rtl;
27
funcionamiento cuando se los carga por separado en el kit de desarrollo xilinx, porque
solo son contadores (modulo de sincronía), y habilitador de pixeles cuando está en cierta
cuenta (generador de pixeles). Por lo que para realizar nuestra primera prueba y observar
obtener un circulo utilizaremos un modelo de 8 por 8 pixels (figura 20). Para la generación
Usando la activación del círculo, obtenemos una señal para habilitar el rgb para
colorear el círculo.
De igual manera que hicimos en la sección 2.3.2, se definen todos los parámetros con las
modificaciones siguientes: Para implementar el sistema con balón redondo, tenemos que
28
incluir un ROM para almacenar el patrón del mapa de bits de nuestra forma. El
BALL_ROM tiene por longitud de palabra 8 bits en 8 direcciones. Traza el círculo dentro
Además tendremos que modificar la parte de generación de pixeles para obtener nuestro
circulo:
29
Si sq_ball esta en uno se empieza el mapeo de la región cuadrada 8x8 en la pantalla,
Restando los tres LSB desde el límite 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).
process(video_on, wa…
begin
…
elsif (rd_ball_on='1') then graph_rgb<=ball_rgb;
…
end process;
Todas las modificaciones al código de las tablas 2 y 3 descritas en este subtitulo, se las
crea la ilusión de movimiento (se anima). Para ello, podemos usar registros para
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 animación.
Si bien el controlador VGA es controlado por una tasa de píxel de 25 MHz, la pantalla del
monitor VGA sólo se actualiza 60 veces por segundo. Por tal razón los registros se deben
actualizar a este ritmo. Definimos una señal 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 señales (límite superior e inferior de la
paleta), y además crear un registro bar_y_reg para almacenar el valor actual del límite
superior y su actualización. 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
Si btn(1) y btn(0) hacen que la paleta se desplace arriba y abajo, el segmento de código
Ahora enfoquemos el problema del balón, tenemos que cambiar las cuatro constantes
limite por cuatro señales y crear 2 registros ball_x_reg y ball_y_reg para obtener los
movimientos horizontales y verticales del balón, actualizando valores de posición del
puede cambiar cuando bota en las paredes o en el paddle pero no cambia la velocidad.
velocidad pueden ser positivos BALL_V_P, o negativos BALL_V_N. Los valores actuales
31
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
if (bar_y_t<=ball_y_b) and (ball_y_t<=bar_y_b) then
x_delta_next <= BALL_V_N; -- registro de mov.
end if;
end if;
end process;
Cabe mencionar que igual que el juego, cuando fallamos en acertarle al balón con la
paleta esta seguirá su curso perdiéndose posteriormente.
32
39 constant BAR_Y_SIZE: integer:=72; --tamaño del paddle
40 -- registro mov. limite superior (posicion x fija)
41 signal bar_y_reg, bar_y_next: unsigned (9 downto 0);
42 -- movimiento del paddle cuando se preciona button (velocidad)
43 constant BAR_V: integer:=4;
44
45 -- variables para ball cuadrado (movimientos basicos no visual)
46 constant BALL_SIZE: integer:=8;
47 -- limites derecho e izquierdo
48 signal ball_x_l, ball_x_r: unsigned(9 downto 0);
49 -- limites superior e inferior
50 signal ball_y_t, ball_y_b: unsigned(9 downto 0);
51 -- registro mov. izquierda + limite superior
52 signal ball_x_reg, ball_x_next: unsigned (9 downto 0);
53 signal ball_y_reg, ball_y_next: unsigned (9 downto 0);
54 -- registro mov. de la velocidad del ball
55 signal x_delta_reg, x_delta_next: unsigned (9 downto 0);
56 signal y_delta_reg, y_delta_next: unsigned (9 downto 0);
57 -- velocidad de ball segun la posicion o registro
58 constant BALL_V_P: unsigned (9 downto 0):=to_unsigned(2,48);
59 constant BALL_V_N: unsigned (9 downto 0):=unsigned(to_signed(-2,48));
60
61 --Imagen de BALL redondo utilizando ROM
62 type rom_type is array (0 to 7) of std_logic_vector(0 to 7);
63 --definiendo nuestra rom para la forma de balon
64 constant BALL_ROM: rom_type:=
65 (
66 "00111100", -- ****
67 "01111110", -- ******
68 "11111111", -- ********
69 "11111111", -- ********
70 "11111111", -- ********
71 "11111111", -- ********
72 "01111110", -- ******
73 "00111100" -- ****
74 );
75 signal rom_addr, rom_col: unsigned (2 downto 0);
76 signal rom_data: std_logic_vector(7 downto 0);
77 signal rom_bit: std_logic;
78
79 -- otras señales
80 signal wall_on, bar_on, sq_ball_on, rd_ball_on: std_logic;
81 signal wall_rgb, bar_rgb, ball_rgb: std_logic_vector(2 downto 0);
82
83 begin
84 -- registros
85 process(clk, reset)
86 begin
87 if (reset='1') then
88 bar_y_reg <= (others=>'0');
89 ball_x_reg <= (others=>'0');
90 ball_y_reg <= (others=>'0');
91 x_delta_reg <= ("0000000100");
92 y_delta_reg <= ("0000000100");
93 elsif(clk'event and clk='1') then
94 bar_y_reg <= bar_y_next;
95 ball_x_reg <= ball_x_next;
96 ball_y_reg <= ball_y_next;
97 x_delta_reg <= x_delta_next;
98 y_delta_reg <= y_delta_next;
99 end if;
100 end process;
101 pix_x <= unsigned (pixel_x);
102 pix_y <= unsigned (pixel_y);
33
103 refr_tick <= '1' when (pix_y=481) and (pix_x=0) else '0';
104
105 -- definiendo pixel a pixel linea vertical izquierda (wall)
106 wall_on <= '1' when (WALL_X_L<=pix_x) and (pix_x<=WALL_X_R) else '0';
107 -- definiendo salida rgb (wall)
108 wall_rgb <= "001"; --azul
109
110 -- definiendo el bar (paddle)
111 -- limites
112 bar_y_t <= bar_y_reg;
113 bar_y_b <= bar_y_t+BAR_Y_SIZE-1;
114 -- habilitando el paddle
115 bar_on <= '1' when (BAR_X_L<=pix_x) and (pix_x<=BAR_X_R) and
116 (bar_y_t<=pix_y) and (pix_y<=bar_y_b) else '0';
117 -- definiendo salida rgb (bar)
118 bar_rgb <= "010"; --verde
119
120 -- nueva posicion en Y del paddle.
121 process (bar_y_reg, bar_y_t, bar_y_b, refr_tick, btn)
122 begin
123 bar_y_next <= bar_y_reg; --no se mueve
124 if (refr_tick='1') then
125 if (btn(1)='1') and (bar_y_b<(MAX_Y-BAR_V-1)) then
126 bar_y_next <= bar_y_reg + BAR_V; --movimiento hacia abajo
127 elsif (btn(0)='1') and (bar_y_t>BAR_V) then
128 bar_y_next <=bar_y_reg - BAR_V; --movimiento hacia arriba
129 end if;
130 end if;
131 end process;
132
133
134 -- definiendo balon
135 -- limites
136 ball_x_l <= ball_x_reg;
137 ball_y_t <= ball_y_reg;
138 ball_x_r <= ball_x_l + BALL_SIZE - 1;
139 ball_y_b <= ball_y_t + BALL_SIZE - 1;
140 -- definiendo pixel a pixel el balon (habilitando señal de mapeo)
141 sq_ball_on <= '1' when (ball_x_l<=pix_x) and (pix_x<=ball_x_r) and
142 (ball_y_t<=pix_y) and (pix_y<=ball_y_b) else '0';
143 -- mapeando el balon segun la ROM (redondo)
144 rom_addr <= pix_y(2 downto 0) - ball_y_t(2 downto 0);
145 rom_col <= pix_x(2 downto 0) - ball_x_l(2 downto 0);
146 rom_data <= BALL_ROM(to_integer(rom_addr));
147 rom_bit <= rom_data(to_integer(rom_col));
148 -- habilitando el balon redondo
149 rd_ball_on <= '1' when (sq_ball_on='1') and (rom_bit='1') else '0';
150 -- definiendo salida rgb del balon
151 ball_rgb <= "100"; --rojo
152 -- posicionando el balon en pantalla
153 ball_x_next <= ball_x_reg + x_delta_reg when refr_tick='1' else ball_x_reg;
154 ball_y_next <= ball_y_reg + y_delta_reg when refr_tick='1' else ball_y_reg;
155 -- posicionando por velocidad
156 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)
157 begin
158 x_delta_next <= x_delta_reg;
159 y_delta_next <= y_delta_reg;
160 if (ball_y_t < 1) then -- alcance superior
161 y_delta_next <= BALL_V_P;
162 elsif (ball_y_b > (MAX_Y-1)) then -- alcance inferior
163 y_delta_next <= BALL_V_N;
164 elsif (ball_x_l <= WALL_X_R) then -- alcance del wall
165 x_delta_next <= BALL_V_P;
166 elsif (BAR_X_L<=ball_x_r) and (ball_x_r<=BAR_X_R) then
34
167 if (bar_y_t<=ball_y_b) and (ball_y_t<=bar_y_b) then
168 x_delta_next <= BALL_V_N; --MOV. registro
169 end if;
170 end if;
171 end process;
172
173 --rgb mux (multiplexor para elegir rgb)
174 process(video_on, wall_on, bar_on, rd_ball_on, wall_rgb, bar_rgb, ball_rgb)
175 begin
176 if (video_on='0') then
177 graph_rgb<="000"; --negro
178 else
179 if (wall_on='1') then graph_rgb<=wall_rgb;
180 elsif (bar_on='1') then graph_rgb<=bar_rgb;
181 elsif (rd_ball_on='1') then graph_rgb<=ball_rgb;
182 else graph_rgb<="011"; --fondo amarillo
183 end if;
184 end if;
185 end process;
186 end rtl;
Para lo rebotes del balón 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
35
3.4 PROGRAMA PRINCIPAL: JUEGO_PONG
que verificamos esto, además nos dio un avance de cómo sería nuestro programa
como base de referencia nuestro pong_graph. Una vez definido como realizaremos el
balón redondo se procedió a realizar nuestro generador de pixeles con un agregado
36
25 graph_rgb=>rgb_next);
26
27 -- definiendo salida rgb en flancos subida de periodo de clock
28 process (clk)
begin
29 if (clk'event and clk='1') then
30 if (pixel_tick='1') then
31 rgb_reg <= rgb_next;
end if;
32 end if;
33 end process;
34 rgb <= rgb_reg;
35 end rtl;
36
37
38
39
40
41
42
43
44
Tabla 6: Modulo Final, videojuego PONG en VHDL
37
Capitulo 4
CONCLUSIONES Y MEJORAS
4.1 CONCLUSIONES
Con el avanzar, de prueba y error en código vhdl, se pudo implementar de manera exitosa
Se dio bases para futuros experimentos en tarjetas fpga, ya que el código en VHDL
valores críticos. Los módulos presentados son aptos para la síntesis, ya que muchas
38
4.1 MEJORAS
modulo de juego.
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. Además de un texto que indique los
midi.
5. BIBLIOGRAFIA
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
6. ANEXOS
40