Home > FPGA > Generating a VGA signal with an FPGA

Generating a VGA signal with an FPGA

I posted this video on Youtube long time ago, but I forgot to write about it on my blog.

In the video I demonstrate how the Basys2 board, with a Spartan-3E 100K, can be used to generate a VGA signal.
I also show my bouncing ball application.

You can download the Xilinx project files here, including the VHDL files and User Constraint File for the Basys2 board.

Categories: FPGA Tags:
  1. J
    March 30th, 2011 at 04:04 | #1

    I programmed your .bit file to my board, but when I connect my board to a TV via VGA, nothing shows up! 🙁

    • March 30th, 2011 at 07:31 | #2

      It’s because I’m using an external oscillator (the socket).
      For VGA generation the onboard oscillators precision is not very good, which means that you CAN generate a VGA signal, but straight vertical lines will be crumby.

      So if you haven’t mounted any external oscillator, you would have to go to the User Constraint File and make the following changes on the first two lines:
      NET “CLK_50MHz” LOC = “B8”;
      #NET “CLK_50MHz” LOC = “M6”; # External socketed Oscillator

  2. J
    March 31st, 2011 at 01:37 | #3

    Ohhhh, thanks!
    So I tried it, and I see what you mean about the vertical lines being “crumby.”
    It’s good to test anyway…
    how do you configure an external oscillator (out of curiousity)?
    Thanks… I appreciate your help!

  3. March 31st, 2011 at 10:12 | #4

    You would need to buy an oscillator in 8-pin DIP packaging. I got one with 4 pins, but in the size of an 8-DIP: http://www.ecsxtal.com/store/pdf/ecs_2100.pdf
    Then you plug this oscillator into the IC6 socket, and then you use the M6 FPGA input instead of B8.
    These oscillators are more precise than the one on the Basys2 board, which is essential for generating clear VGA signals, as those are higher precision speeds.

    Best Regards
    Thomas Jespersen

  4. Leo
    December 31st, 2011 at 17:13 | #5

    I want to get started with FPGAs and right now I’m in the process of deciding which eval-board I’ll buy.
    Can you tell me how “full” the FPGA gets with this demo? I’m trying to get a feeling of how much I can do with the 100k LEs I can do.
    Thanks and regards,

  5. January 3rd, 2012 at 17:12 | #6

    In the 100K Spartan 3E device you have a total amount of 960 slices, which is the way you count how much of the FPGA that is occupied.
    With the Large Res Bouncing Ball project 159 of these 960 slices are occupied. That means that 16% of the FPGA resources is used, which is not much!

    The Basys2 board is a very easy to use FPGA board for beginners. The board is commonly seen on universities around the world.
    If you are new to FPGAs I will recommend you to get one of those, as you can download a great number of examples and it comes with an on-board programmer, so there is no need to invest in a JTAG programmer.

    Happy new year.

  6. Tim
    February 21st, 2012 at 04:34 | #7

    I am trying to display an image via VGA out of my Basys2 FPGA board. I have a rom vhdl file and a VGA controller unit. I am passing a vector from the rom file into controller unit that contains the image data (black and white ~ std_logic). I want to check at each index (based off the horizontal position ~ ScanlineY value) to see if I should display a color or not. I tried using image_data_vector(conv_integer(ScanlineY)) = ‘1’ but it doesn’t work. I am using ieee.numeric.std, ieee.logic_unsigned, and ieee.artith. If Do you have any suggestions? A better question to ask might be is this even an appropriate way to try and display an image?
    Thank you,

  7. February 23rd, 2012 at 10:06 | #8

    Dear Tim.
    I would do it the exact same way as you do. The image block you have in the ROM, how is that defined? As a Std_logic_vector(x downto y)?
    If you have included IEEE.STD_LOGIC_ARITH.ALL and IEEE.STD_LOGIC_UNSIGNED.ALL it should be no problem to just use the ScanlineY as the vector pointer.

    But I would do it the same way, defining the pixel-buffer as a std_logic_vector and then read every bit from there when scrolling thru the display.

    Best Regards
    Thomas Jespersen

  8. yassine
    April 30th, 2013 at 19:00 | #9

    thanks for your blog . i will by Basysâ?¢2 Spartan-3E FPGA 100K from digilent
    did this fpga came whith a internal oscillateur and cables for the 6-pin Pmod connectors ?

    sory for my english im morrocan but it’s a prouf that your website is famous

    thanks again by !!!

  9. September 24th, 2013 at 07:55 | #10

    Yes, there is a 50MHz on-board oscillator connected to the FPGA. It is not the most precise oscillator and there is a bit of jitter. So for very crisp VGA images you need to connect a more precise oscillator in the DIL-8 header.
    The Basys2 board comes without any PMOD cables, but this shouldn’t be necessary either, as PMOD modules are made to just be connected directly into the sockets on the board.
    Regards Thomas

  10. Diego
    October 26th, 2013 at 16:16 | #11

    Hello. I’m trying to make my own VGA controller based on your code, but something cought my attention. From what I understood on your code, you waited for the sync pulse and the front porch in order to start sending colours, but in most websites I’ve seen, the signal diagram suggests that the image data has to start after the sync pulse + the back porch, not the front porch. I am very confused about this because obviously your design works perfectly.

  11. October 27th, 2013 at 22:52 | #12

    Nicely caught.
    You are completely right about my mix-up of Front and Back porch. According to the standard of VGA timing the backporch has to be sent just after the sync.

    I can’t tell you why my project works, but I guess it might be due to nowadays intelligent displays, that can understand even the most wierd timing scenarios.

    Regards Thomas

  12. Hamzaoui
    February 24th, 2014 at 20:14 | #13

    wt do u think abt implement the description of a PIC 16F84 on FPGA as a project for a new user of VHDL and FPGA ? can i get some help and thxs

  13. February 28th, 2014 at 22:22 | #14

    If you find the right SoC source (the VHDL files) it might not be that difficult to implement and get to work. Though it will require that you study the architechture of microprocessors in VHDL and what they consist of.
    Though have you worked and gained experience with VHDL already?

  14. Nalin
    May 12th, 2014 at 15:10 | #15

    would you please supply verilog (*.v) project for this project.
    if you can it is highly appreciated
    thanks in advance

  15. zami
    May 23rd, 2014 at 19:26 | #16

    When I try to import .bit file “unable to associate file with device due to idcode conflict” message is flagged. Could you please give me a hint here.

  16. May 23rd, 2014 at 20:57 | #17

    Have you synthesized the project for yourself on your own computer or are you trying to use our bit-file?
    Which board are you using the bit-file on? The Basys2 as well?
    Please make sure the chip is the same. On our board it is the XC3E100CPG132

    Regards Thomas

  17. May 23rd, 2014 at 21:11 | #18

    We are primarily working in VHDL and therefor haven’t made this project in Verilog. Sorry.

  18. zami
    May 24th, 2014 at 06:37 | #19

    > Have you synthesized the project for yourself on your own computer or are you trying to use our bit-file?
    No I synthesized it on my own computer.

    > Which board are you using the bit-file on? The Basys2 as well?
    Yes it is Basys2

    > Please make sure the chip is the same. On our board it is the XC3E100CPG132
    But your project sets it to xc3s100e-4cp132 in my Xilinx env.

    Any idea?

  19. June 11th, 2014 at 17:20 | #20

    That is also the correct chip, so nothing should be wrong there.
    And you are using the Digilent Adept software for programming the FPGA, uploading the .bit file? Or are you given this idcode error inside Xilinx iMPACT?
    Please try and upload the .bit file with the Adept suite if you haven’t tried!

  20. Oyin
    October 17th, 2014 at 13:21 | #21

    Hey. I was wondering if a VGA screen can be split into unequal parts?

  21. Olawunmi
    October 18th, 2014 at 17:47 | #22

    Hello. Thanks for that. Firstly, is it possible to get 2 unequal stripes horizontally on the screen? If so, how?
    Secondly, is it possible to get a colour brown on the screen as well?
    Thank you.

  22. October 18th, 2014 at 19:36 | #23

    Yes, you can completely customize the width of the stripes in the VHDL code.
    This is all set in the end of the code:

      ColorOutput <= "11100000" when ScanlineX < 213 else
                     "00011100" when ScanlineX >= 213 AND ScanlineX < 213+213 else
                     "00000011" when ScanlineX >= 213+213 AND ScanlineX < 213+213+213 else

    By changing “ScanlineX < ???" you set the region/stribe of pixels to be a specific color. This means that you can also easily create a brown color. You should just create the binary 3-3-2 color code for the brown color. I would say that brown color has the color code: "10001000" Regards Thomas

  23. Oyinsola
    October 31st, 2014 at 17:39 | #24

    Hello Thomas.
    Is it possible to create a moving horizontal line using schematics instead of VHDL coding. Basically I am trying yo generate roughly 2 pixel positions per VSYNC using counters and comaprators. I have been able to draw the rest of the circuit, however I am unsure of how to drive the clock signal on the 16 bit counter. Any help would be appreciated.

    Thanks 🙂

  24. November 8th, 2014 at 23:01 | #25

    I’m sorry to say that this to you but I would deeply disrecommend using the schematics for larger circuit design. The graphical schematics view, showing how a VHDL implementation is going to be synthesized can sometimes be usefull to get an overview of the actual logic implementation, but it is never that good to implement your design in schematics.
    So no, I can’t recommend you any good solution. Though you might want to try to take in a clock signal (from a pin, UCF file) and then use a prescaler block or counter block with binary output and take the right output. This would be the easiest way to downscale the clock.

    Regards Thomas

  25. adelfo
    August 31st, 2016 at 03:34 | #26

    Great video but in your video is not to have a esxterno oscillator

  26. September 16th, 2016 at 06:05 | #27

    For the larger resolutions you need an external crystal as the timing gets very critical.
    For small resolution (640×480) the onboard 50 MHz oscillator can be used.

  27. r
    February 15th, 2017 at 05:10 | #28


    I am using the Basys3 board and wanted to see if your project would work for this board? I see the VHDL code, but wanted to see if you had the xdc or sdc user constraints files for the basys3 board?

  28. February 16th, 2017 at 22:19 | #29

    I don’t have the constraints file for the Basys3 board specifically for this project but I recommend you to refer to this: https://github.com/Digilent/Basys3/blob/master/Projects/XADC_Demo/src/constraints/Basys3_Master.xdc
    All the pins for the board are defined in this file and would only have to be renamed to match our project.

  29. Eddy Ancira
    March 6th, 2017 at 06:00 | #30

    Hello Thomas, I would like to know what would you recommend to do
    as a project I have to deliver in 5 weeks.
    it is for the subject of logical design.
    I must say I am new to this.
    I am studying Mechatronical Engineering.
    It is about using the Basys 2. I am really interested in the VGA signal and bouncing ball program.

    Thank you, Eddy

  30. March 6th, 2017 at 10:04 | #31

    @Eddy Ancira
    I would suggest that you consider implementing a pong game.
    That will both get you working with implementing VGA and the bouncing ball while also trying to implement user interaction.
    If time allows you could even investigate an AI (computer player) to play against.

  31. r
    March 16th, 2017 at 03:59 | #32

    Hello Thomas,

    In the ‘VGAPosition: process (Clk_25MHz)’ why does it subtract 1 from the Hlimit and Vlimit, and not just use the actual value?


  32. March 16th, 2017 at 22:04 | #33

    This is because HLimit and VLimit denotes the number of horizontal and vertical pixels, but not the actual pixel index value limit.
    We want the pixel counter (CurrentHPos and CurrentVPos) to go between 0 and (HLimit-1) or (VLimit-1) as this will give us a total of HLimit and VLimit pixels.
    Please notice that the if-check will add one to the variable if true. We only want to add one if the resulting index values will still be within our limit or 0 to (HLimit-1) or (VLimit-1).

    Does this make sense?

  33. ali fallah
    May 15th, 2017 at 11:24 | #34

    thank you..!
    it was very good
    it did in my FPGA…!

  34. Rob
    January 16th, 2019 at 13:34 | #35

    Hello Thomas,

    I’m working on the VGA Stripes Project and found your program very helpful. I only found a problem in understanding this chunk of code:

    “HBlank = HSyncWidth + HFrontPorch) and (CurrentHPos < HSyncWidth + HFrontPorch + HDisplayArea) else '1';

    VBlank = VSyncWidth + VFrontPorch) and (CurrentVPos < VSyncWidth + VFrontPorch + VDisplayArea) else '1';

    Blank <= '1' when HBlank = '1' or VBlank = '1' else '0';

    ScanlineX ‘0’);

    ScanlineY ‘0’);”

    Can you kindly explain it to me pls …. Thanks

  35. January 29th, 2019 at 18:19 | #36

    These lines defines when the current pixel location is within the horizontal or vertical blank area, based on the timing parameters for the VGA standard.
    You can find the specific timing parameters here: http://tinyvga.com/vga-timing
    And you can find a more elaborate description of the VGA signal and timing here: http://www.eng.ucy.ac.cy/theocharides/Courses/ECE664/VGA.pdf

  1. No trackbacks yet.