This post is about VCD parsing library called vcdvcd. It’s great way to load up vcd and do some processing instead of losing my mind looking at gtkwave. Honestly, The API documentation is not that great but there is an examples.py which helped a little.

So, I wrote this example which should be good enough to get started. It iterates the design hierarchy and gets tv (time and value) tuples for each signal. After that i created my own wrapper with (nextedge, prevedge, posedge, negedge) but that’s for anther post.

from vcdvcd import VCDVCD,vcdvcd


def _populate_scopes(scope):
    print("===========================")
    print(f"Printing scope {scope}")
    print("===========================")
    for key, subElement in scope.subElements.items():
        if isinstance(subElement, str):
            value = waves[subElement]
            print(f"Signal =: {subElement}")
            for t,v in value.tv:
                print(f"     @{t} {v}")

        if isinstance(subElement, vcdvcd.Scope):
            _populate_scopes(subElement)

file_name = "dump.vcd"

waves =   VCDVCD(file_name, store_scopes=True)

top_name = waves.signals[0].split(".")[0] if len(waves.signals) > 0 else None

top_scope = waves[top_name]
_populate_scopes(top_scope)

and the output should be something like

===========================
Printing scope top
{
	PWRITE
	PWDATA[31:0]
	PSELx
	PREADY
	PRDATA[31:0]
	PENABLE
	PADDR[11:0]
	PCLK
	PRESETn
	m
	s
}
===========================
Signal =: top.PWRITE
     @0 x
     @36 1
Signal =: top.PWDATA[31:0]
     @0 x
     @36 10
Signal =: top.PSELx