I’ve been following Will Green’s excellent FPGA VGA Graphics in Verilog series, wherein he creates a VGA output block in Verilog, and displays some sprites on the screen. I wanted to do away with the need for physical hardware, and simulate the VGA generator entirely (I gotta have my end-to-end testing!) using Icarus Verilog. So I wrote a little C program to read in the simulator output (a Value Change Dump file) and output PNG images.

https://github.com/ehalferty/vcd2vga

Here’s some sample input, and the expected output:

VCD file: https://1drv.ms/u/s!AjcdaKRUIFzggvt_Ci_QxAdqQEbYJw

Output frames: https://1drv.ms/u/s!AjcdaKRUIFzggvwAIXFjDZNybBim_w

The VCD file starts thusly:

$date
	Wed Aug  7 12:07:53 2019
$end
$version
	Icarus Verilog
$end
$timescale
	1ps
$end
$scope module main_testbench $end
$scope module main_inst $end
$var wire 1 ! clk_40mhz $end
$upscope $end
$upscope $end
$scope module main_testbench $end
$var wire 1 " HS $end
$upscope $end
$scope module main_testbench $end
$var wire 1 # VS $end
$upscope $end
$scope module main_testbench $end
$var wire 4 $ R [3:0] $end
$upscope $end
$scope module main_testbench $end
$var wire 4 % G [3:0] $end
$upscope $end
$scope module main_testbench $end
$var wire 4 & B [3:0] $end
$upscope $end
$enddefinitions $end
#0
$dumpvars
b0 &
b0 %
b0 $
0#
0"
0!
$end
#12500
1!
#25000
0!
#37500
1!
... and so on for another 16 million lines! ...

Basically, this snippet just shows the header and a bit beyond it.

A VCD file logs every time a signal changes state in your simulated RTL design. It consists of timestamps, and lines identifying which signal changed, and what it changed to.

The header defines the timescale, and gives each wire that the simulator dumped out while simulating a short identifier character. The rest of the file uses those short identifiers.

So from this snippet, you can see at the very end that the signal “!” is going from low, to high, to low, to high, at timestamps 2500 units apart (and these units are picoseconds, since the header defined them that way). From the header, you can see that “!” maps to the VGA pixel clock (which I named “clk_40mhz” in my design), which makes sense.

This program meets my needs for the time being, but it might be fun to expand it to auto-detect the resolution and refresh rate, or even support other video formats.