Introduction:
VGA (Video Graphics Array) is an analog interface that was historically used to connect computer monitors and display visual data. Once the standard for display connections, VGA is now being gradually phased out in favor of digital interfaces like HDMI. In this tutorial, we’ll delve into using a VGA Expansion Module with the Mimas S7 Lite FPGA Module. Our goal is to create a basic project that demonstrates color display through VGA. Let’s dive in and get started!
Prerequisites:
To follow this article, you would need the following:
- Hardware:
- Mimas S7 Lite.
- VGA Expansion Module.
- VGA cable and a compatible monitor.
- Software:
- Xilinx Vivado Design Suite 2024.1
Step 1:
Download and install Vivado Board Support Package files for Mimas S7 Lite from here. Follow the readme in the link on how to install Vivado Board Support Package files for Numato Lab’s boards.
Step 2:
Start Vivado Design Suite, and select “Create Project” from Quick Start section. The project wizard will pop up. Press next to proceed with creating the project.
Step 3:
Type in a project name and save it at a convenient location. For this example “vga” is used as project name, but feel free to use any name. Select the check box below to keep all project files in a single folder. The image below shows the settings for the example project. Click “Next” to continue.
Step 4:
Choose “RTL Project” as project type and check the option “Do not specify sources at this time”.
Step 5:
At the “Default Part” step, select “Boards” and choose Vendor as “numato.com”. Select “Mimas_S7_Lite” and click “Next”. If Mimas_S7_Lite is not displayed in the boards list, you will need to install Mimas_S7_Lite board support files correctly.
Step 6:
Then in the Sources tab, Right-click Design Sources and click ‘Add Sources’. It will open a new “Add Sources” window.
Step 7:
In Add sources tab select “Add or create design sources” and Click on “Next“.
In ‘Add or Create Design Sources’, select ‘Create File’, give ‘VGA’ as file name. Click OK and Finish.
Step 8:
In the ‘Define Module’ window, Click ‘OK’ followed by ‘Yes’ without making any changes.
Step 9:
Copy the following code in VGA.v and save the file.
VGA has five signals i.e. red
,green
, blue
,hsync
and vsync
. hsync
andvsync
are digital signals that are used for synchronization of signal timing with monitor whereasred
,green
and blue
signals are used as data to be displayed in the pixels 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 10:
In sources tab, Right-Click on ‘Constraints’ and click on ‘Add Sources’.
Step 11:
In Add sources tab select “Add or create constraints” and Click on “Next“.
Click ‘Create File’ and give ‘VGA’ as File name. Click ‘OK’ and ‘Finish’.
Step 12:
Copy the following constraints in your constrains file and save it.
set_property -dict { PACKAGE_PIN "U1" IOSTANDARD LVCMOS33 SLEW FAST} [get_ports {red[0]}] set_property -dict { PACKAGE_PIN "R3" IOSTANDARD LVCMOS33 SLEW FAST} [get_ports {red[1]}] set_property -dict { PACKAGE_PIN "T1" IOSTANDARD LVCMOS33 SLEW FAST} [get_ports {red[2]}] set_property -dict { PACKAGE_PIN "P2" IOSTANDARD LVCMOS33 SLEW FAST} [get_ports {green[0]}] set_property -dict { PACKAGE_PIN "R2" IOSTANDARD LVCMOS33 SLEW FAST} [get_ports {green[1]}] set_property -dict { PACKAGE_PIN "T2" IOSTANDARD LVCMOS33 SLEW FAST} [get_ports {green[2]}] set_property -dict { PACKAGE_PIN "P1" IOSTANDARD LVCMOS33 SLEW FAST} [get_ports {blue[0]}] set_property -dict { PACKAGE_PIN "R1" IOSTANDARD LVCMOS33 SLEW FAST} [get_ports {blue[1]}] set_property -dict { PACKAGE_PIN "M1" IOSTANDARD LVCMOS33 SLEW FAST} [get_ports {hsync}] set_property -dict { PACKAGE_PIN "K3" IOSTANDARD LVCMOS33 SLEW FAST} [get_ports {vsync}] set_property -dict { PACKAGE_PIN "D14" IOSTANDARD LVCMOS33 } [get_ports {clock}]
Step 13:
Click “Generate Bitstream” under PROGRAM AND DEBUG section and click “Yes” in any subsequent dialog window which comes up.
Step 14:
Once the bitstream is successfully generated, close any “Bitstream Generation Completed” dialog which comes up asking for what to do next.
Step 15:
Now, we will set up the hardware for programming the module. For this, connect “Header P1” of VGA Module to “Header P4” of Mimas S7 Lite and Connect “Header P2” of VGA Module to “Header P5” of Mimas S7 Lite. Now connect USB type ‘c’ cable for powering up Mimas S7 Lite
Step 16:
Now click ‘Open Hardware Manager’ to program the FPGA.
Step 17:
Click on ‘Open target’ and ‘Auto Connect’.
Step 18:
Right Click on the device (xc7s50_0) and select “Program Device” option.
Step 19:
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 20:
You will see the following output. You can change the code and observe different outputs!