<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/making-a-vga-driver-in-systemverilog-fyi9z7se2" -->

---
title: Making a VGA Driver in SystemVerilog | daily.dev
description: A college Digital Logic Design lab project built a working VGA driver in SystemVerilog on an FPGA. The design divides the board's 50MHz clock down to the 25MHz...
canonical: https://daily.dev/posts/making-a-vga-driver-in-systemverilog-fyi9z7se2
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Making a VGA Driver in SystemVerilog | daily.dev
og:description: A college Digital Logic Design lab project built a working VGA driver in SystemVerilog on an FPGA. The design divides the board's 50MHz clock down to the 25MHz...
og:url: https://daily.dev/posts/making-a-vga-driver-in-systemverilog-fyi9z7se2
og:image: https://api.daily.dev/og/posts/fYI9z7sE2.png
og:image:alt: Making a VGA Driver in SystemVerilog
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Making a VGA Driver in SystemVerilog

**[Hacker News](https://daily.dev/sources/hn)** · 7 min read · 0 upvotes · 0 comments

## Summary

A college Digital Logic Design lab project built a working VGA driver in SystemVerilog on an FPGA. The design divides the board's 50MHz clock down to the 25MHz VGA pixel clock with a simple toggle module, then uses counters to track 800 horizontal and 525 vertical 'pixels' including sync and porch regions. A mux expands the DE10-lite board's 10 switches into the VGA's 4,096-color space. A second lab loaded an image (Asterix) from FPGA ROM, and the author added alpha-channel transparency, eventually using real multiplication for the final graded demo after trying a cheaper bit-shifting hack that caused rounding artifacts.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://lukaswerner.com/post/2026-10-20@bottom-up-vga>

## Questions this post answers

### What pixel clock frequency do I need to generate 640x480 VGA output at 60Hz?

You need approximately a 25 MHz pixel clock, specifically 25.175 MHz according to standard VGA timing tables, to send all pixels for a 640x480 frame at 60Hz. Because the display syncs off the HSync and VSync signals you control, a close approximation like 25 MHz works fine even if it doesn't match exactly.

_Anyone timing an FPGA display driver can track VGA clocking details like this on daily.dev._

### How many total horizontal and vertical lines does a 640x480 VGA signal need including blanking?

A 640x480 VGA frame needs 800 total horizontal 'pixels' per line and 525 total vertical lines. Horizontally that's 640 visible pixels plus a 16-pixel front porch, 96-pixel sync pulse, and 16-pixel back porch (160 total blanking). Vertically it's 480 visible lines plus a 33-line front porch, 2-line sync pulse, and 10-line back porch (45 total blanking).

_Developers wiring up VGA timing counters can reference exact porch and sync values on daily.dev._

### How can I map a small number of input bits to a wider VGA color range cheaply on an FPGA?

A simple lookup table mux can expand 2-bit inputs into 4-bit VGA color outputs without complex math: 00 maps to 0000, 01 to 0101, 10 to 1010, and 11 to 1111. This repeating-bit-pattern approach spreads a limited number of physical switches (such as 10 on a DE10-lite board) across the full 12-bit, 4,096-color VGA space.

_If you're stretching limited FPGA switches into a fuller color range, find similar mapping tricks on daily.dev._

## Community take

How the wider developer community reacted, aggregated from 2 discussions and 31 comments across hackernews, lobsters (as of 2026-10-25).

**TL;DR:** Commenters mostly share enthusiasm and nostalgia for VGA driver projects as a classic, satisfying first FPGA exercise, swapping their own similar builds, with only a brief tangent about legacy video connectors.

**Sentiment:** 70% positive · 25% mixed · 5% skeptical

**The case for**

- Several people shared their own similar VGA/graphics FPGA projects (monochrome monitor dithering, HardCaml VGA core, chessboard driver, JPEG decoder) as evidence it's a great learning exercise.
- Multiple commenters called it a satisfying, extensible first real FPGA project that can grow into terminals, character generators, or full retro systems.
- It reminded people of Ben Eater's breadboard VGA card videos/kits as a related beloved resource.
- One commenter found the Asterix image graphics genuinely impressive and inspiring to get an FPGA.

**The pushback**

- Someone found the Asterix image resolution suspiciously higher than what VGA/the stated 255x255 ROM width should allow.
- The author declined to share source code to prevent students from cheating on labs, limiting reproducibility for interested readers.
- A tangent noted that modern TVs and monitors increasingly lack VGA/DVI-A inputs, making such projects harder to display on current hardware.

**By community**

- hackernews (mixed): Discussion drifted mostly into a tangent about VGA/DVI/HDMI connector compatibility and nostalgic tributes to how college exposes people to unexpected topics, with little direct commentary on the project itself.
- lobsters (positive): Warm, detailed engagement with people sharing their own similar VGA/FPGA projects, asking technical follow-ups, and praising the project as a classic satisfying build.

**Open questions**

- Why does the displayed Asterix image appear higher-resolution than the stated 255x255 ROM width would allow?
- Is it possible to emulate a copper/raster bars effect with this kind of VGA driver?

**Highlights**

> What's the resolution of that picture of Asterix? It looks a lot higher than what VGA can do.
> — [Relax on lobsters · 1 points, 1 comments](https://lobste.rs/s/mngelc/making_vga_driver_systemverilog#c_fcqamj)

> I was surprised by that too. It should be limited by the ROM width, 255x255 pixels.
> — [lukasmwerner on lobsters · 1 points](https://lobste.rs/s/mngelc/making_vga_driver_systemverilog#c_o1y53o)

> A VGA driver is a common and very satisfying first “real” FPGA project. However, it seems lots of displays no longer have VGA inputs. When I did this, I went down to the local PC recycle and bought an actual multisync CRT for $5. Once you have the display going, it’s extensible with other simple learning projects. Rather than graphics, I ended up making a terminal by adding a character generator, PS/2 keyboard input, buffered UART, and multiple state machines to do cursor tracking and even a little bit of escape code handling. Just keep tacking on more modules! With today’s FPGAs you could keep going to implement a whole Z80 system connected to the terminal and run CP/M on it.
> — [wrs on lobsters · 1 points](https://lobste.rs/s/mngelc/making_vga_driver_systemverilog#c_zoxtby)

> When I was in undergrad, I took a verilog course as an elective. It was a ton of fun. One of the first projects we did was a VGA driver, and we continued from there. The last lab was writing a verilog JPEG decoder that displayed via the VGA driver in our first lab, though they replaced arithmetic encoding for the DCT coefficients with simpler RLE, since we only had a couple of weeks to get it done. It's really worth learning verilog, and taking the time to think in terms of the LUTs that it compiles down to, instead of treating it like yet another procedural language.
> — [orib on lobsters · 1 points](https://lobste.rs/s/mngelc/making_vga_driver_systemverilog#c_8k5smu)

> Really cool - is it possible to emulate copper/raster bars effect? https://en.wikipedia.org/wiki/Raster_bar
> — [larsw on lobsters · 1 points, 1 comments](https://lobste.rs/s/mngelc/making_vga_driver_systemverilog#c_ipyulp)

**Source threads**

- [hackernews](https://news.ycombinator.com/item?id=50168376) · 47 points · 18 comments
- [lobsters](https://lobste.rs/s/mngelc/making_vga_driver_systemverilog) · 27 points · 13 comments

## Similar posts on daily.dev

- [Bit-Hacks Pixel Dungeon](https://daily.dev/posts/bit-hacks-pixel-dungeon-rwpb3ueug) · Two Stop Bits · 0 upvotes · 0 comments
- [My DIY FPGA board can run Quake II \(part 4\)](https://daily.dev/posts/my-diy-fpga-board-can-run-quake-ii-part-4--5v06ytzpr) · Hacker News · 2 upvotes · 0 comments
- [The FPGA Chronicles: Exploring The Tang Nano 20K](https://daily.dev/posts/the-fpga-chronicles-exploring-the-tang-nano-20k-qdxxlsf9r) · Hackaday · 0 upvotes · 0 comments
- [Recreating Voodoo Graphics and a Late-1990s Gaming PC on an FPGA](https://daily.dev/posts/recreating-voodoo-graphics-and-a-late-1990s-gaming-pc-on-an-fpga-r8te6tuyp) · Two Stop Bits · 0 upvotes · 0 comments
- [A Brief History of VHDL and The FPGA](https://daily.dev/posts/a-brief-history-of-vhdl-and-the-fpga-cant4hycw) · Simple Thread · 3 upvotes · 0 comments

---

Tags: [#fpga](https://daily.dev/tags/fpga)

[View this post on daily.dev](https://daily.dev/posts/making-a-vga-driver-in-systemverilog-fyi9z7se2)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Making a VGA Driver in SystemVerilog","url":"https://daily.dev/posts/making-a-vga-driver-in-systemverilog-fyi9z7se2","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/making-a-vga-driver-in-systemverilog-fyi9z7se2"},"datePublished":"2026-10-25T01:13:26.832Z","dateModified":"2026-10-25T01:29:42.175Z","description":"A college Digital Logic Design lab project built a working VGA driver in SystemVerilog on an FPGA. The design divides the board's 50MHz clock down to the 25MHz...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/875eb6cb3b50eebd1bd651a318000b7d?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/875eb6cb3b50eebd1bd651a318000b7d?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Hacker News","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Hacker News","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/hn","url":"https://daily.dev/sources/hn"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/making-a-vga-driver-in-systemverilog-fyi9z7se2","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"fpga","timeRequired":"PT7M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Hacker News","item":"https://daily.dev/sources/hn"},{"@type":"ListItem","position":3,"name":"Making a VGA Driver in SystemVerilog"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/making-a-vga-driver-in-systemverilog-fyi9z7se2#faq","mainEntity":[{"@type":"Question","name":"What pixel clock frequency do I need to generate 640x480 VGA output at 60Hz?","acceptedAnswer":{"@type":"Answer","text":"You need approximately a 25 MHz pixel clock, specifically 25.175 MHz according to standard VGA timing tables, to send all pixels for a 640x480 frame at 60Hz. Because the display syncs off the HSync and VSync signals you control, a close approximation like 25 MHz works fine even if it doesn't match exactly. Anyone timing an FPGA display driver can track VGA clocking details like this on daily.dev."}},{"@type":"Question","name":"How many total horizontal and vertical lines does a 640x480 VGA signal need including blanking?","acceptedAnswer":{"@type":"Answer","text":"A 640x480 VGA frame needs 800 total horizontal 'pixels' per line and 525 total vertical lines. Horizontally that's 640 visible pixels plus a 16-pixel front porch, 96-pixel sync pulse, and 16-pixel back porch (160 total blanking). Vertically it's 480 visible lines plus a 33-line front porch, 2-line sync pulse, and 10-line back porch (45 total blanking). Developers wiring up VGA timing counters can reference exact porch and sync values on daily.dev."}},{"@type":"Question","name":"How can I map a small number of input bits to a wider VGA color range cheaply on an FPGA?","acceptedAnswer":{"@type":"Answer","text":"A simple lookup table mux can expand 2-bit inputs into 4-bit VGA color outputs without complex math: 00 maps to 0000, 01 to 0101, 10 to 1010, and 11 to 1111. This repeating-bit-pattern approach spreads a limited number of physical switches (such as 10 on a DE10-lite board) across the full 12-bit, 4,096-color VGA space. If you're stretching limited FPGA switches into a fuller color range, find similar mapping tricks on daily.dev."}}]}
```

