For a project we needed to use cocotb, a python based testbench for designs under test that can be executed with one of their supported simulators. So it was decided that it is probably a good idea to have our refrence implementation, or golden model, of our application in python as well, to be able to have a seamlessly debug interaction.

As the hardware interface was specified, we wanted to have an easy method to verify that the refrence followed the prescribed states. This is why we wanted to trace the states of the pinout of our refrence via a VCD file.

zipcpu provides already a nice tutorial, however some points are easy to miss if you are in a hurry.

I only needed to implement vcd tracing for digital values. But of course, analog values are also possible. If I ever need analog value dumps, ill post a follow up. :grimacing_face: So here a very brief overview from my side for dumping digital values.

Quickstart Format

Prelude

$version Generated by <Your Tool Name here> $end
$date <timestamp> $end
$timescale <1 | 10 | 100 ><s | ms | us | ns | ps | fs> $end

Scope declaration, nesting is possible.

$scope module <module name> $end

There are several datatypes, most of the time ‘wire’ is the type you want.

The syntax to specify multi-bit variablers is the same as for single bit values. An identifier_code is a

“one or more printable ASCII characters from ! to ~ (decimal 33 to 126)” wikpedia

$var <vary_type> <size> <identifier_code> <reference> $end

Do not forget to close all your scopes.

$upscope $end
$enddefinitions $end

Initial Values Section

Initial values for example ‘x’ for undefined are specified in a ‘dumpvar’ section. The syntax is the same as for the ‘Value Change’ section

$dumpvars

$end

Value Change Section

#<timestamp in your defined unit>

Now to the tricky part. The format is different for single bit values and vectors.

Vector:

b<bit values> <identifier_code>

Single bit wire:

<bitvalue><identifier_code>

Notice, there is no space between a bit value and its identifier_code.

Exanple File

Its always nice to have a minimum working example.

$version generated with my_module.py $end
$date 03/29/2024, 16:46:42 $end
$timescale 1ns $end
$scope module TOP $end
$var wire 3 # bit_vector_i $end
$var wire 1 ~~ reset_i $end
$upscope $end
$enddefinitions $end
$dumpvars
bxxx #
0~~
$end
#0
b111 #
#1
1~~

Testing

The easiest method of testing, is to start GTKWave from a console. GTKWave prints all parsing errors to the host console, so a real nice way to debug.

Tooling

There is a very convenient VS Code Plugin WaveTrace. It is not as powerful as GTKWave, but its sufficient for having a quick glance at stuff. If your file is broken is someway however, it simply will not open the file with out any message describing the error. So keep that in mind.