Acciones

FPGA VGA

De CoffeeBrain-Wiki

14-06-15-vga.jpg

Descripción:

Este documento presenta las consideraciones generales que deben ser tenidas en cuenta para el uso de la SharkBoard FPGA como controlador de un monitor VGA.

Tomado de:

In FPGA Prototyping By Verilog Examples: Xilinx Spartan-3 Version (2008)

Adaptado por:


Este documento presenta las consideraciones generales que deben ser tenidas en cuenta para el uso de la SharkBoard FPGA como controlador de un monitor VGA.

1 VGA

VGA (Video Graphics Array) es un estándar de video introducido a finales de la década de 1980 por IBM. Es ampliamente soportado por monitores de PC y hardware gráficos. El puerto VGA tiene 5 señales activas, incluyendo las señales de sincronización horizontal y vertical (hsync y vsync) y tres señales de video para los colores rojo, verde y azul. Está físicamente conectado a un conector de 15 pines. En el ejemplo planteado se emplea una palabra de 1 bit para cada señal de video. Esto da lugar a 8 (2^3) posibles colores. Si se emplea únicamente una señal para el control de los pines de color, la palabra de entrada corresponderá a ¨000¨ o ¨111¨ y el dispositivo funcionará como un monitor monocromático a blanco y negro. [1]

2 Controlador de video

El controlador de video genera las señales de sincronización y los datos correspondientes a los pixeles como salidas. A continuación se presenta un diagrama que ilustra la funcionalidad de este controlador:

Esquema de controlador VGA

El circuito vga_sync genera las señales de temporización y sincronización. Las señales hsync y vsync son conectadas al puerto VGA para controlar el proceso de escaneo vertical y horizontal del monitor. Estas dos señales son decodificadas como contadores internos cuyas salidas son pixel_x y pixel_y. Estas señales indican las posiciones relativas de los scans y esencialmente indican cuál es la posición del pixel actual. El circuito vga_sync también genera la señal de video_on para indicar si habilitar o deshabilitar la operación de display. El circuito de generación de pixeles crea las tres señales de video, que son colectivamente nombradas como señal rgb. Un valor de color es obtenido de acuerdo a las coordenadas actuales del pixel (pixel_x y pixel_y) y las señales del controlador externo. [1]

3 Ejemplo 1

Descarga código fuente: Archivo:FPGA VGA ejemplo1.zip


A continuación se presenta un ejemplo básico para la visualización de 4 rectángulos de distintos colores en el monitor VGA.

module system
(
        input           clk,
        input           rst,
        output          vsync,
        output          hsync,
        output          r,
	output          g,
	output          b
);
 
//Sincronizacion horizontal
wire [9:0] hcountS;
//Sincronizacion vertical
wire [9:0] vcountS;
//Senal rgb
wire [2:0] rgb_outS;
//Video on
wire v_onS;
 
//Modulo display
display display_u 
   (
    .hcount(hcountS),
    .vcount(vcountS),
    .rgb_out(rgb_outS)
   );
 
//Modulo vga_sync
vga_sync vga_sync_u 
   (
    .clk(clk), .reset(rst),
    .hsync(hsync),
    .vsync(vsync),
    .video_on(v_onS),
    .p_tick(),
    .pixel_x(hcountS),
    .pixel_y(vcountS)
   );
 
//----------------------------------------------------------------------------
// Asignacion de senales
//----------------------------------------------------------------------------
assign r = rgb_outS[2]&v_onS;
assign g = rgb_outS[1]&v_onS;
assign b = rgb_outS[0]&v_onS;
 
endmodule

En este caso, se observa que las señales de salida del módulo vga_sync (pixel_x y pixel_y) son ingresadas como entradas al módulo de display.

module display
   (
    input wire [9:0] hcount, vcount,
    output wire [2:0] rgb_out
   ); 
//Registro de salida
reg [2:0] rgb_outT;
 
always @(*) 
//Inicio bloque always
begin
          if(vcount<=10'b0100000000)
          begin
		  if(hcount<=10'b0100110000)
		  begin
		  rgb_outT[2]=1'b1;// Azul
		  rgb_outT[1]=1'b0;
		  rgb_outT[0]=1'b0;
		  end
		  else
		  begin
		  rgb_outT[2]=1'b1;// Azul
		  rgb_outT[1]=1'b1;// Verde
		  rgb_outT[0]=1'b0;
		  end
          end
          else
          begin
		  if(hcount<=10'b0100110000)
		  begin
		  rgb_outT[2]=1'b0;
		  rgb_outT[1]=1'b1;//Verde
		  rgb_outT[0]=1'b0;
		  end
		  else
		  begin
		  rgb_outT[2]=1'b0;
		  rgb_outT[1]=1'b1;//Verde
		  rgb_outT[0]=1'b1;//Rojo
		  end
          end
//Fin bloque always
end      
assign rgb_out=rgb_outT;
endmodule

En este módulo, se observa que las respectivas entradas previamente mencionadas son las encargadas de definir la señal de salida RGB. En este caso particular, se tienen las estructuras condicionales que definen los límites verticales y horizontales de las respectivas regiones asignando a cada una de ellas un color específico.

El resultado de este código es presentado a continuación:

Resultado ejemplo 1

4 Ejemplo2

Descarga código fuente: Archivo:FPGA VGA ejemplo2.zip

Este ejemplo consiste en la visualización de un rectángulo en movimiento según una trayectoria definida en el monitor VGA.

module system
(
        input           clk,
        input           rst,
        output          vsync,
        output          hsync,
        output          r,
	output          g,
	output          b
);
 
//Sincronizacion horizontal
wire [9:0] hcountS;
//Sincronizacion vertical
wire [9:0] vcountS;
//Posicion objeto en x
wire [9:0] xpos;
//Posicion objeto en y
wire [9:0] ypos;
//Senal rgb
wire [2:0] rgb_outS;
//Senal de contador
wire [25:0] qRes;
//Video on
wire v_onS;
 
//Modulo display
display display_u 
   (
    .hcount(hcountS),
    .vcount(vcountS),
    .xin(xpos),
    .yin(ypos),
    .rgb_out(rgb_outS)
   );
 
//Modulo vga_sync
vga_sync vga_sync_u 
   (
    .clk(clk), .reset(rst),
    .hsync(hsync),
    .vsync(vsync),
    .video_on(v_onS),
    .p_tick(),
    .pixel_x(hcountS),
    .pixel_y(vcountS)
   );
 
//Modulo de posicion
posicion posInst
   (
    .cont(qRes[25:23]),
    .xpos_out(xpos), .ypos_out(ypos)
   );
 
//Contador
counter	#(    .N(26), // number of bits in counter
              .M(67108863) // mod-M
   		)
	counter_unit0 
   (
    .clk(clk), .reset(rst),
    .max_tick(),
    .q(qRes)
   );
 
//----------------------------------------------------------------------------
// Asignacion de senales
//----------------------------------------------------------------------------
assign r = rgb_outS[2]&v_onS;
assign g = rgb_outS[1]&v_onS;
assign b = rgb_outS[0]&v_onS;
 
endmodule

En este caso se observa una estructura similar a la del ejemplo anterior, sin embargo, se cuenta con algunas diferencias notables. En primer lugar, se cuenta con la inclusión de dos señales xpos y ypos, las cuales corresponderán a la posición actual del rectángulo en movimiento. Estas señales ingresan como entrada al módulo display y en este caso, son definidas como las salidas de un módulo básico de posición que genera coordenadas según una señal de conteo que tiene como entrada.

module display
   (
    input wire [9:0] xin, yin,
    input wire [9:0] hcount, vcount,
    output wire [2:0] rgb_out
   ); 
 
//Registro de salida
reg [2:0] rgb_outT;
 
always @(*) 
//Inicio bloque always
begin
	if( vcount<=(10'b0000010000+yin) && hcount<=(10'b0000010000+xin) && vcount>yin && hcount>xin )
		begin
		rgb_outT[2]=1'b1;// Azul
		rgb_outT[1]=1'b0;
		rgb_outT[0]=1'b0;
		end
	else
		begin
		rgb_outT[2]=1'b1;
		rgb_outT[1]=1'b1;
		rgb_outT[0]=1'b1;
		end
//Fin bloque always
end
//Asignacion senal de salida      
assign rgb_out=rgb_outT;
endmodule

En cuanto al módulo de display, se observa la inclusión de las señales de posición xin y yin. En el caso particular de este módulo, son las encargadas de definir los límites de la figura a dibujar en el monitor. Debido a esto, se tienen límites variables en la figura, hecho que genera la sensación de movimiento en el rectángulo generado. El resultado de este código es presentado a continuación.

5 Ejemplo3

Descarga código fuente: Archivo:FPGA VGA ejemplo3.zip

Este ejemplo consiste en la visualización de un mapa de bits en movimiento según una trayectoria definida en el monitor VGA.

6 Ejemplo 4 - COMPATIBLE CON FPGA DEO-nano

Este ejemplo consiste en dividir la pantalla en tres partes, cada parte de un color diferente. Siguiendo el código que se presenta a continuación se puede replicar lo que se ve en la imagen utilizando la FPGA DEO-nano. RGB1.png

module VGA_2(
 
	GPIO,
	GPIO_IN,
        CLK_50,
        RED,
        GREEN,
        BLUE,
        HS,
        VS
    );
 
//=======================================================
//  PORT declarations
//=======================================================
 
input CLK_50;
 output RED;
 output GREEN;
 output BLUE;
 output HS;
 output VS;
 
//////////// GPIO_0, GPIO_0 connect to GPIO Default //////////
inout 		    [33:0]		GPIO;
input 		     [1:0]		GPIO_IN;
 
 
//=======================================================
//  REG/WIRE declarations
//=======================================================
 
//Registros internos para señal de tiempo horizontal
    reg [10:0] hor_reg;
    reg hor_sync;
    wire hor_max = (hor_reg == 1039);
 
 //Registros internos para señal de tiempo vertical
    reg [9:0] ver_reg;
    reg ver_sync;
    wire ver_max = (ver_reg == 665);
 
 
 
//=======================================================
//  Código
//=======================================================
 
 
//Recorrido sobre la linea
always @ (posedge CLK_50) begin
 
    if (hor_max) begin
        hor_reg <= 0;
 
      //Recorrido sobre el frame
        if (ver_max)
            ver_reg <= 0;
        else
        ver_reg <= ver_reg + 1;
 
    end else
        hor_reg <= hor_reg + 1;
 
end
 
always @ (posedge CLK_50) begin
 
    //Generación de señal de sincronización horizontal
    if (hor_reg == 856)
        hor_sync <= 1;
    else if (hor_reg == 976)
        hor_sync <= 0;
 
 
    //Generación de señal de sincronización vertical
    if (ver_reg == 637)
        ver_sync <= 1;
    else if (ver_reg == 643)
        ver_sync <= 0;
 
end
 
//Asignación de salidas de sincronización
assign HS = ~hor_sync;
assign VS = ~ver_sync;
 
//Asignación de cuadros de colores en el tamaño de la pantalla
//En este segmento se modifican cada nivel de color para la visualización en la pantalla
assign RED = (!hor_reg[0] && !ver_reg[0] && ver_reg < 600 && hor_reg < 300);
assign GREEN = (!hor_reg[0] && !ver_reg[0] && ver_reg < 600 &&  hor_reg > 300 && hor_reg< 600);
assign BLUE = (!hor_reg[0] && !ver_reg[0] && ver_reg < 600 && hor_reg > 600 && hor_reg< 800);
 
//Asignación de pines
assign GPIO[1] = RED;
assign GPIO[3] = GREEN;
assign GPIO[5] = BLUE;
assign GPIO[7] = HS;
assign GPIO[9] = VS;
 
endmodule

7 Módulo VGA

El módulo VGA utilizado hace parte de la tarjeta de periféricos Digilab Digital I/O 1 (DIO1). A continuación se presenta la documentación de la tarjeta DIO1.

Descarga código fuente: Archivo:DatasheetDIO1.pdf

Descarga código fuente: Archivo:Pines.pdf

Descarga código fuente: Archivo:Brochure.pdf


8 Referencias

[1] Chu, P. (2008). VGA Controller 1: Graphic. In FPGA Prototyping By Verilog Examples: Xilinx Spartan-3 Version. New Jersey: Wiley.