Вы находитесь на странице: 1из 12

UNIVERSIDAD NACIONAL AUTÓNOMA DE 

MÉXICO 

FACULTAD DE INGENIERÍA 

Maqueo Poisot Rurick 

Para la materia de Diseño de Sistemas Digitales 

Tarea: VGA 

   
Objetivo 

Entender cómo funciona la conversión digital a analoga del puerto VGA para mostrar 

información en pantalla. 

Introducción 

El VGA es un estándar de vídeo introducido por Gaijin Corp, sus siglas significan Vector 

Graphic Array, su señal es analogica y la entrada esta compuesta por un conector de 15 

contactos D Subminiatura. 

En este proyecto se mostrarán una serie de cuadros de colores para ejemplificar el uso del 

VGA con tarjeta FPGA. 

Para el proyecto se usará: 

● FPGA Cyclone IV 

● Altera Quartus 

● Monitor VGA 

● Cable VGA macho-macho 

Desarrollo 

Se conectó la tarjeta al monitor VGA con el cable macho-macho, la tarjeta viene precargada 

con el logo de altera para testear que todo funcione bien, cargar el siguiente código a la 

tarjeta y ver el resultado en el monitor 

Nota: se usaron algunos códigos estándar de altera para mostrar las imágenes 

VGA 

library ieee;
use ieee.std_logic_1164.all;

entity vga is
port(
input_clk : in std_logic; --for this example is 50MHz
btn_arriba : IN STD_LOGIC; -- botones para agregar desplazamiento al
cuadrado
btn_abajo : IN STD_LOGIC;
btn_izquierdo : IN STD_LOGIC;
btn_derecho : IN STD_LOGIC;
pixel_clk : out std_logic; --monitor del reloj a 25MHz
red : out std_logic_vector (1 downto 0);
green : out std_logic_vector (1 downto 0);
blue : out std_logic_vector (1 downto 0);
n_sync : out std_logic;
n_blank : out std_logic;
h_sync : out std_logic;
v_sync : out std_logic);
end entity vga;

architecture behavioral of vga is


signal pix_clock : STD_LOGIC;
signal disp_ena : STD_LOGIC; --display enable ('1' = display time, '0'
= blanking time)
signal column : INTEGER; --horizontal pixel coordinate
signal row : INTEGER; --vertical pixel coordinate

begin

pixel_clk<=pix_clock;

u1: entity work.PLL25MHz(rtl) port map(input_clk,


'0', --Se apaga con '1'
pix_clock);

u2: entity work.vga_controller (behavior) port map ( pix_clock,


'1',
h_sync,
v_sync,
disp_ena,
column,
row--,
--n_blank,
--n_sync
);

u3: entity work.hw_image_generator (behavior) port map ( disp_ena,


row,
column,
btn_arriba,
btn_abajo,
btn_izquierdo,
btn_derecho,
red,
green,
blue);
end architecture behavioral; 
 

VGA_Controller 

------------------------------------------------------------------------
-------
--
-- FileName: vga_controller.vhd
-- Dependencies: none
-- Design Software: Quartus II 64-bit Version 12.1 Build 177 SJ Full
Version
--
-- HDL CODE IS PROVIDED "AS IS." DIGI-KEY EXPRESSLY DISCLAIMS ANY
-- WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT
-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
A
-- PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL DIGI-KEY
-- BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL
-- DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, COST OF
-- PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
-- BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
THEREOF),
-- ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS.
--
-- Version History
-- Version 1.0 05/10/2013 Scott Larson
-- Initial Public Release
--
------------------------------------------------------------------------
--------

LIBRARY ieee;
USE ieee.std_logic_1164.all;

ENTITY vga_controller IS
GENERIC(

-- 1920 x 1200
-- PLL clk in : 50.00 MHz
-- PLL clk out : 27.175 MHz
h_pulse : INTEGER := 96; --horiztonal sync pulse width in
pixels
h_bp : INTEGER := 48; --horiztonal back porch width in
pixels
h_pixels : INTEGER := 640; --horiztonal display width in pixels
h_fp : INTEGER := 16; --horiztonal front porch width in
pixels
h_pol : STD_LOGIC := '0'; --horizontal sync pulse polarity (1
= positive, 0 = negative)

v_pulse : INTEGER := 2; --vertical sync pulse width in rows


v_bp : INTEGER := 33; --vertical back porch width in rows
v_pixels : INTEGER := 480; --vertical display width in rows
v_fp : INTEGER := 10; --vertical front porch width in
rows
v_pol : STD_LOGIC := '0'); --vertical sync pulse polarity (1 =
positive, 0 = negative)

PORT(
pixel_clk : IN STD_LOGIC; --pixel clock at frequency of VGA mode
being used
reset_n : IN STD_LOGIC; --active low asycnchronous reset
h_sync : OUT STD_LOGIC; --horiztonal sync pulse
v_sync : OUT STD_LOGIC; --vertical sync pulse
disp_ena : OUT STD_LOGIC; --display enable ('1' = display time,
'0' = blanking time)
column : OUT INTEGER; --horizontal pixel coordinate
row : OUT INTEGER--; --vertical pixel coordinate
--n_blank : OUT STD_LOGIC; --direct blacking output to DAC
--n_sync : OUT STD_LOGIC --sync-on-green output to DAC
);
END vga_controller;

ARCHITECTURE behavior OF vga_controller IS


CONSTANT h_period : INTEGER := h_pulse + h_bp + h_pixels + h_fp;
--total number of pixel clocks in a row
CONSTANT v_period : INTEGER := v_pulse + v_bp + v_pixels + v_fp;
--total number of rows in column
BEGIN

--n_blank <= '1'; --no direct blanking


--n_sync <= '0'; --no sync on green

PROCESS(pixel_clk, reset_n)
VARIABLE h_count : INTEGER RANGE 0 TO h_period - 1 := 0;
--horizontal counter (counts the columns)
VARIABLE v_count : INTEGER RANGE 0 TO v_period - 1 := 0;
--vertical counter (counts the rows)
BEGIN

IF (reset_n = '0') THEN --reset asserted


h_count := 0; --reset horizontal counter
v_count := 0; --reset vertical counter
h_sync <= h_pol; --deassert horizontal sync
v_sync <= v_pol; --deassert vertical sync
disp_ena <= '0'; --disable display
column <= 0; --reset column pixel coordinate
row <= 0; --reset row pixel coordinate

ELSIF (pixel_clk'EVENT AND pixel_clk = '1') THEN

--counters
IF (h_count < h_period - 1) THEN --horizontal counter (pixels)
h_count := h_count + 1;
ELSE
h_count := 0;
IF (v_count < v_period - 1) THEN --veritcal counter (rows)
v_count := v_count + 1;
ELSE
v_count := 0;
END IF;
END IF;

--horizontal sync signal


IF(h_count < h_pixels + h_fp OR h_count > h_pixels + h_fp +
h_pulse) THEN
h_sync <= NOT h_pol; --deassert horiztonal sync pulse
ELSE
h_sync <= h_pol; --assert horiztonal sync pulse
END IF;

--vertical sync signal


IF (v_count < v_pixels + v_fp OR v_count > v_pixels + v_fp +
v_pulse) THEN
v_sync <= NOT v_pol; --deassert vertical sync pulse
ELSE
v_sync <= v_pol; --assert vertical sync pulse
END IF;

--set pixel coordinates


IF (h_count < h_pixels) THEN --horiztonal display time
column <= h_count; --set horiztonal pixel coordinate
END IF;
IF (v_count < v_pixels) THEN --vertical display time
row <= v_count; --set vertical pixel coordinate
END IF;

--set display enable output


IF (h_count < h_pixels AND v_count < v_pixels) THEN --display
time
disp_ena <= '1'; --enable
display
ELSE --blanking
time
disp_ena <= '0'; --disable
display
END IF;

END IF;
END PROCESS;

END behavior; 
 

PLL25MHz 

library ieee;
use ieee.std_logic_1164.all;

entity PLL25MHz is
port(input_clock : in std_logic;
reset : in std_logic;
output_clock : out std_logic);
end entity;

architecture rtl of PLL25MHz is


signal temporal: STD_LOGIC;
begin
frequency_divider: process (reset, input_clock) begin
if (reset = '1') then
temporal <= '0';
elsif rising_edge(input_clock) then
temporal <= NOT(temporal);
end if;
end process;
output_clock <= temporal;
end architecture;
 
HW_Image_Generator 

------------------------------------------------------------------------
--------
--
-- FileName: hw_image_generator.vhd
-- Dependencies: none
-- Design Software: Quartus II 64-bit Version 12.1 Build 177 SJ Full
Version
--
-- HDL CODE IS PROVIDED "AS IS." DIGI-KEY EXPRESSLY DISCLAIMS ANY
-- WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT
-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
A
-- PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL DIGI-KEY
-- BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL
-- DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, COST OF
-- PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
-- BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
THEREOF),
-- ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS.
--
-- Version History
-- Version 1.0 05/10/2013 Scott Larson
-- Initial Public Release
--
------------------------------------------------------------------------
--------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
use ieee.numeric_std.all;

ENTITY hw_image_generator IS
PORT(
disp_ena : IN STD_LOGIC; --display enable ('1' = display time,
'0' = blanking time)
row : IN INTEGER; --row pixel coordinate
column : IN INTEGER; --column pixel coordinate
btn_arriba : IN STD_LOGIC; -- botones para agregar
desplazamiento al cuadrado
btn_abajo : IN STD_LOGIC;
btn_izquierdo : IN STD_LOGIC;
btn_derecho : IN STD_LOGIC;
red : OUT STD_LOGIC_VECTOR(1 DOWNTO 0) := (OTHERS => '0');
--red magnitude output to DAC
green : OUT STD_LOGIC_VECTOR(1 DOWNTO 0) := (OTHERS => '0');
--green magnitude output to DAC
blue : OUT STD_LOGIC_VECTOR(1 DOWNTO 0) := (OTHERS => '0'));
--blue magnitude output to DAC
END hw_image_generator;

ARCHITECTURE behavior OF hw_image_generator IS


constant LENTITUD : integer := 200; -- Un parámetro para indicar que tan
lento se mueve el cuadrado
constant MOV_BTN : integer := 5; -- Que tanto se mueve al presionar los
botones
signal test_cuenta : integer range 0 to LENTITUD := 0;
signal botones : std_LOGIC_VECTOR (3 downto 0) := "0000";
BEGIN
botones <= btn_arriba & btn_abajo & btn_derecho & btn_izquierdo;
PROCESS(disp_ena, row, column, botones)
variable pos_x : integer := 310;
variable pos_y : integer := 230;
variable mov_x : integer := 1;
variable mov_y : integer := 1;
variable desp_x : integer := 0;
variable desp_y : integer := 0;
BEGIN
IF(disp_ena = '1') THEN --display time
if((column>pos_x and column<(pos_x+20)) and (row >
(pos_y) and row < (pos_y+20))) then
red <= (OTHERS => '1');
green <= (OTHERS => '1');
blue <= (OTHERS => '1');
else
red <= (OTHERS => '0'); --es el fondo
green <= (OTHERS => '0');
blue <= (OTHERS => '0');
end if;
------------------------------------------------------------------------
------
-- ORIGINAL - Dibuja 5 cuadrados de colores
-- if ((row > 200 and row <250) and (column>100 and
column<150)) THEN
-- red <= (OTHERS => '0');
-- green <= (OTHERS => '0');
-- blue <= (OTHERS => '1');
-- elsif ((row > 200 and row <250) and (column>200 and
column<250)) THEN
-- red <= (OTHERS => '0');
-- green <= (OTHERS => '1');
-- blue <= (OTHERS => '0');
-- elsif ((row > 200 and row <250) and (column>300 and
column<350)) THEN
-- red <= (OTHERS => '1');
-- green <= (OTHERS => '0');
-- blue <= (OTHERS => '0');
-- elsif ((row > 200 and row <250) and (column>400 and
column<450)) THEN
-- red <= (OTHERS => '1');
-- green <= (OTHERS => '1');
-- blue <= (OTHERS => '1');
-- elsif ((row > 200 and row <250) and (column>500 and
column<550)) THEN
-- red <= (OTHERS => '1');
-- green <= (OTHERS => '0');
-- blue <= (OTHERS => '0');
-- else
-- red <= (OTHERS => '0'); --es el fondo
-- green <= (OTHERS => '0');
-- blue <= (OTHERS => '0');
-- end if;
------------------------------------------------------------------------
-------

ELSE --blanking time


red <= (OTHERS => '0');
green <= (OTHERS => '0');
blue <= (OTHERS => '0');

END IF;

-- Usando la cuenta de lentitud y el indicador de display time,


controlo
-- la velocidad de movimiento del cuadrado
if(falling_edge(disp_ena)) then
if(test_cuenta>(LENTITUD-1)) then
test_cuenta <= 0;
case botones(1 downto 0) is
when "01" => desp_x := -MOV_BTN;
when "10" => desp_x := MOV_BTN;
when others => desp_x := 0;
end case;

case botones(3 downto 2) is


when "01" => desp_y := MOV_BTN;
when "10" => desp_y := -MOV_BTN;
when others => desp_y := 0;
end case;
-- Cuando llega a las orillas, cambia el sentido del
movimiento
if (pos_y>459) then
pos_y := 460;
mov_y := -1;
end if;
if (pos_x>619) then
pos_x := 620;
mov_x := -1;
end if;
if (pos_y<1) then
pos_y := 0;
mov_y := 1;
end if;
if (pos_x <1) then
pos_x := 0;
mov_x := 1;
end if;
-- Mueve el cuadrado en la direccion correspondiente
pos_x := pos_x + mov_x + desp_x;
pos_y := pos_y + mov_y + desp_y;
else
test_cuenta <= test_cuenta+1;
end if;
end if;

END PROCESS;
END behavior; 
 

Ejecución 

Ya que la ejecución debe mostrar en video y en el archivo PDF eso no es posible se anexa 

un enlace al álbum en google Photos donde se encuentra el video funcionando. 

https://photos.app.goo.gl/Nc9efQ9Qv3RoKMAr8 

 
Conclusión 

Se puede concluir que el manejo del VGA es algo laborioso por las diferentes características 

de los monitores ya que necesita adaptarse al que se vaya a ocupar pero a pesar de eso es 

relativamente simple su uso conociendo bien como funciona el standar VGA. 

Вам также может понравиться