Styx Xilinx Zynq FPGA Module

Simple VGA Design Example for Styx

2520 views February 12, 2018 rohitsingh 6

Introduction:

VGA (Video Graphics Array) is an analog interface used to display visual data on computer monitors. Till few years back, it was the most used display interface. It is now being slowly replaced by HDMI. The data can be displayed on monitors via VGA by using VGA Expansion Module and Saturn IO Breakout module with Styx Xilinx Zynq FPGA Module. In this tutorial, a simple project is implemented to display colours using VGA. Let’s get started!

Prerequisites:

To follow this article, you will need the following:

Hardware:

Software:

  • Vivado (version 2017.3 or higher)

Step 1:

Open Vivado and select ‘Create Project’ in the “Quick Start” area. Click  ‘Next’ in the “New Project” dialog window which opens.

 

Step 2:

In Project Name page, provide project name of your choice and choose the directory where you want to save the project.

 

Step 3:

Click Next without making any changes till you see the ‘Default Part’ tab and select ‘Styx’ from ‘Boards’ option. If you cannot see ‘Styx’ in the boards list then add BSP files from here to the following directory ..Vivado\2017.3\data\boards\board_files

Step 4:

Click Next and Finish to create the project. Then in the Sources tab, Left-click Design Sources and click ‘Add Sources’. It will open a new “Add Sources” window.

Step 5:

Click Next. In ‘Add or Create Design Sources’, select ‘Create File’, give ‘VGA.v’ as file name. Click OK and Finish.

Step 6:

In the ‘Define Module’ window, Click ‘OK’ followed by ‘Yes’ without making any changes.

 

Step 7:

Copy the following code in VGA.v and save the file.

VGA has five signals i.e. red,green, blue,hsyncand vsynchsync andvsyncare digital signals that are used for synchronization of signal timing with monitor whereasred,greenand bluesignals are used as data to be displayed in thpixels on monitor. For 640*480 resolution, a mod-800 counter (hcount) is used to control horizontal timing and a mod-525 counter (vcount) is used to control vertical timing.

The image depicts the values of hsync and vsync signals corresponding to the value of hcount and vcount. The screen is scanned horizontally first, once it reaches the end, it goes to next line and again the same procedure is followed. When it reaches the last line, vcounter rolls back to starting point. The values of hcount and vcount are derived from VGA timing standard for 640×480@60Hz resolution.

The values of hcount and vcount denote the current pixel coordinates on screen. So in rtl code, the values to red, green and blue signals are controlled by hcount and vcount.

For displaying various colours, logic is implemented to drive different values to red, green and blue pins of VGA for different pixel ranges. According to the combination of these 3 signals, different colours can be displayed. The digital values of red, green and blue signals are converted into analog values by resistor ladder DAC in VGA Expansion Module. 

The screen is divided into 8 columns and each column displays different colour according to the values given to red, green and blue signals. The columns are divided according to the value of hcount for vertical bars (vertical range remains same for each colour). 

`timescale 1ns / 1ps
module VGA(
input clock,
output reg [2:0 ] red, 
output reg [2:0 ] green, 
output reg [1:0 ] blue,
output reg hsync, 
output reg vsync
);
reg clock_50, clock_25;
reg [9:0] hcount = 640;
reg [9:0] vcount = 480;
reg [9:0] next_hcount = 640;
reg [9:0] next_vcount = 480;

always @ (posedge clock)
begin
  clock_50 =! clock_50;
end

always @ (posedge clock_50)
begin
  clock_25 =! clock_25;
end

always @(posedge clock_25)
begin
  if(hcount == 799)
  begin
    hcount <= 0;
    if(vcount == 524)
      vcount <= 0;
    else 
      vcount <= vcount+1'b1;
  end
  else
    hcount <= hcount+1'b1;
         
  if (vcount >= 490 && vcount < 492) 
    vsync <= 1'b0;
  else
    vsync <= 1'b1;

  if (hcount >= 656 && hcount < 752) 
    hsync <= 1'b0;
  else
    hsync <= 1'b1;
end
 
always @ (posedge clock_25)
begin
  if (hcount < 80 && vcount < 480)
  begin
    green <= 3'b111;
    blue  <= 2'b11;    
    red   <= 3'b111;
  end
  else if (hcount < 160  && vcount < 480)
  begin
    green <= 3'b111;
    blue  <= 2'b00;    
    red   <= 3'b111;
  end
  else if (hcount < 240  && vcount < 480)
  begin
    green <= 3'b111;
    blue  <= 2'b11;    
    red   <= 3'b000;
  end
  else if (hcount < 320  && vcount < 480)
  begin
    green <= 3'b111;
    blue  <= 2'b00;    
    red   <= 3'b000;
  end
  else if (hcount < 400  && vcount < 480)
  begin
    green <= 3'b000;
    blue  <= 2'b11;    
    red   <= 3'b111;
  end
  else if (hcount < 480  && vcount < 480)
  begin
    green <= 3'b000;
    blue  <= 2'b00;    
    red   <= 3'b111;
  end
  else if (hcount < 560  && vcount < 480)
  begin
    green <= 3'b000;
    blue  <= 2'b11;    
    red   <= 3'b000;
  end
  else if (hcount < 640  && vcount < 480)
  begin
    green <= 3'b000;
    blue  <= 2'b00;    
    red   <= 3'b000;
  end
  else 
  begin
    green <= 3'b000;
    blue  <= 2'b00;    
    red   <= 3'b000;
  end   
end
endmodule

Step 8:

In sources tab, Left-Click ‘Constraints’ and click ‘Add Sources’.

 

Step 9:

Click ‘Create File’ and give ‘VGA’ as File name. Click ‘OK’ and ‘Finish’.

 

Step 10:

Copy the following constraints in your constrains file and save it

set_property -dict { PACKAGE_PIN "W18"		IOSTANDARD LVCMOS33		SLEW FAST} [get_ports {red[0]}]	
set_property -dict { PACKAGE_PIN "R20"		IOSTANDARD LVCMOS33		SLEW FAST} [get_ports {red[1]}]	
set_property -dict { PACKAGE_PIN "R21"		IOSTANDARD LVCMOS33		SLEW FAST} [get_ports {red[2]}]	
set_property -dict { PACKAGE_PIN "Y15"		IOSTANDARD LVCMOS33		SLEW FAST} [get_ports {green[0]}]	
set_property -dict { PACKAGE_PIN "P16"		IOSTANDARD LVCMOS33		SLEW FAST} [get_ports {green[1]}]	
set_property -dict { PACKAGE_PIN "W17"		IOSTANDARD LVCMOS33		SLEW FAST} [get_ports {green[2]}]	
set_property -dict { PACKAGE_PIN "Y16"		IOSTANDARD LVCMOS33		SLEW FAST} [get_ports {blue[0]}]	
set_property -dict { PACKAGE_PIN "W16"		IOSTANDARD LVCMOS33		SLEW FAST} [get_ports {blue[1]}]	
set_property -dict { PACKAGE_PIN "P15"		IOSTANDARD LVCMOS33		SLEW FAST} [get_ports {hsync}]	
set_property -dict { PACKAGE_PIN "N15"		IOSTANDARD LVCMOS33		SLEW FAST} [get_ports {vsync}]	
set_property -dict { PACKAGE_PIN "Y6"		IOSTANDARD LVCMOS33 }                      [get_ports {clk}]

Step 11.

In Project Manager Tab, Click ‘Run Synthesis’. If Synthesis is successful, Click ‘Run Implementation’ and on successful implementation select ‘Generate Bitstream’.

Step 12:

Now, we will set up the hardware for programming the module. For this, connect Saturn IO Breakout Module to ‘Header P5’ of Styx. Also, Connect Header P1 of VGA Module to ‘Header P12’ of Saturn IO Breakout module and ‘Header P2’ of VGA Module to ‘Header P6’ of Saturn IO Breakout Module. Now connect power supply for Styx and Xilinx JTAG Cable.

Step 13:

Now click ‘Open Hardware Manager’ to program the FPGA.

 

Step 14:

Click on ‘Open target’ and ‘Auto Connect’. It will connect to the Module if the JTAG and power connections are correct.

Step 15:

Click on ‘Program Device’.

 

Step 16:

Click Program and observe the output. Connect a VGA cable to VGA Module and to the monitor where you want to see the output.

Step 17:

You will see the following output. You can change the code and observe different outputs!

So, that was it! Keep tinkering with the code to get different patterns on the display!

Was this helpful?

Leave A Comment
*
*