Skip to main content

Python Verilog value change dump (VCD) parser library + the nifty vcdcat VCD command line viewer

Project description

= vcdvcd
:idprefix:
:idseparator: -
:sectanchors:
:sectlinks:
:sectnumlevels: 6
:sectnums:
:toc: macro
:toclevels: 6
:toc-title:

Python Verilog value change dump (VCD) parser library + the nifty <<vcdcat>> VCD command line pretty printer.

toc::[]

== Installation

Install the latest release:

....
python -m pip install --user vcdvcd
....

On Ubuntu 23.04 you need instead https://stackoverflow.com/questions/75608323/how-do-i-solve-error-externally-managed-environment-every-time-i-use-pip-3[]:

....
pipx install vcdvcd
....

Install master directly from this repository for development with `--editable`:

....
git clone https://github.com/cirosantilli/vcdvcd
cd vcdvcd
virtualenv -p python3 .venv
. .venv/bin/activate
python -m pip install --editable .
....

This allows you to direcly edit the source code here and see updates to importers from anywhere as shown at: https://stackoverflow.com/questions/35064426/when-would-the-e-editable-option-be-useful-with-pip-install/63353319#63353319[].

You can also use <<vcdcat>> directly from a clone with:

....
git clone https://github.com/cirosantilli/vcdvcd
python -m pip install --user ./vcdvcd
vcdvcd/vcdcat vcdvcd/counter_tb.vcd
....

== vcdcat

Nifty terminal CLI VCD pretty printer:

....
vcdcat -h
....

Dump all signal values:

....
vcdcat counter_tb.vcd
....

Output:

....
0 time
1 counter_tb.clock
2 counter_tb.enable
3 counter_tb.out[1:0]
4 counter_tb.reset
5 counter_tb.top.out[1:0]

0 1 2 3 4 5
===========
0 1 0 x 0 x
1 0 0 x 1 x
2 1 0 0 1 0
3 0 0 0 0 0
4 1 0 0 0 0
5 0 1 0 0 0
6 1 1 1 0 1
7 0 1 1 0 1
8 1 1 2 0 2
9 0 1 2 0 2
10 1 1 3 0 3
11 0 1 3 0 3
12 1 1 0 0 0
13 0 1 0 0 0
14 1 1 1 0 1
15 0 1 1 0 1
16 1 1 2 0 2
17 0 1 2 0 2
18 1 1 3 0 3
19 0 1 3 0 3
20 1 1 0 0 0
21 0 1 0 0 0
22 1 1 1 0 1
23 0 1 1 0 1
24 1 1 2 0 2
25 0 0 2 0 2
26 1 0 2 0 2
....

Dump only selected signals:

....
vcdcat counter_tb.vcd top.enable top.reset
....

Output:

....
0 time
1 counter_tb.top.enable
2 counter_tb.top.reset

0 1 2
=====
0 0 0
1 0 1
3 0 0
5 1 0
25 0 0
....

Note how only times for which at least one selected signal changed are shown.

=== `vcdcat --deltas`

Only print the signals that changed for each time.

If no signals changed at a given time, don't print anything for that time.

This will potentially make the output much much smaller for large VCD files.

Example:

....
vcdcat -d counter_tb.vcd
....

Output excerpt:

....
0 x counter_tb.top.out[1:0]
0 0 counter_tb.reset
0 0 counter_tb.enable
0 1 counter_tb.clock
0 x counter_tb.out[1:0]
1 0 counter_tb.clock
1 1 counter_tb.reset
2 0 counter_tb.out[1:0]
2 0 counter_tb.top.out[1:0]
2 1 counter_tb.clock
3 0 counter_tb.clock
3 0 counter_tb.reset
4 1 counter_tb.clock
....

Where for example the line:

....
0 x counter_tb.top.out[1:0]
....

means that:

* at time `0`
* the signal `counter_tb.top.out[1:0]`
* changed to value `x`

As without `--deltas`, we can also view deltas only for selected signals, e.g.:

....
vcdcat -d counter_tb.vcd 'counter_tb.top.out[1:0]'
....

outputs:

....
0 x counter_tb.top.out[1:0]
2 0 counter_tb.top.out[1:0]
6 1 counter_tb.top.out[1:0]
8 2 counter_tb.top.out[1:0]
10 3 counter_tb.top.out[1:0]
12 0 counter_tb.top.out[1:0]
14 1 counter_tb.top.out[1:0]
16 2 counter_tb.top.out[1:0]
18 3 counter_tb.top.out[1:0]
20 0 counter_tb.top.out[1:0]
22 1 counter_tb.top.out[1:0]
24 2 counter_tb.top.out[1:0]
....

=== `vcdcat --china`

vcdcat's most important option!

TODO: this option is now broken because Pypi deleted the package https://pypi.org/project/china-dictatorship/ without any notification. Cowards!

* https://github.com/cirosantilli/china-dictatorship
* https://cirosantilli.com/china-dictatorship/mirrors
* https://mastodon.social/@cirosantilli/111384334603801231
* https://x.com/cirosantilli/status/1722831661253988424

When it was working you could:

....
vcdcat --china > index.html
firefox index.html
....

See also: https://cirosantilli.com/china-dictatorship/#mirrors

== API usage

Library usage examples can be seen at link:examples.py[] and run with:

....
./examples.py
....

Other examples are also being added to link:test.py[] which can be run with:

....
./test.py
....

or to run just one example do:

....
./test.py Test.test_simple_timescale_values
....

By default, data is parsed at once into a per-signal format that allows for efficient random access, for example:

....
from vcdvcd import VCDVCD

# Do the parsing.
vcd = VCDVCD('counter_tb.vcd')

# List all human readable signal names.
print(vcd.references_to_ids.keys())

# View all signal data.
print(vcd.data)

# Get a signal by human readable name.
signal = vcd['counter_tb.top.out[1:0]']

# tv is a list of Time/Value delta pairs for this signal.
tv = signal.tv
assert(tv[0] == (0, 'x'))
assert(tv[1] == (2, '0'))
assert(tv[2] == (6, '1'))

# Random access value of the signal at a given time.
# Note how it works for times between deltas as well.
assert(signal[0] == 'x')
assert(signal[1] == 'x')
assert(signal[2] == '0')
assert(signal[3] == '0')
....

But you can also use this library in a purely stream callback fashion as shown in the examples by doing something like:

....
class MyStreamParserCallbacks(vcdvcd.StreamParserCallbacks):
def value(
self,
vcd,
time,
value,
identifier_code,
cur_sig_vals,
):
print('{} {} {}'.format(time, value, identifier_code))
vcd = VCDVCD('counter_tb.vcd', callbacks=MyStreamParserCallbacks(), store_tvs=False)
....

`store_tvs=False` instructs the library to not store all the signal value change data, which would likely just take up useless space in your streaming application. Only signal metadata is stored in that case.

== About this repository

The VCD format is defined by the Verilog standard, and can be generated with `$dumpvars`.

This repo was originally forked from Sameer Gauria's version, which is currently only hosted on PyPI with email patches and no public bug tracking: https://pypi.python.org/pypi/Verilog_VCD[].

There is also a read-only mirror at: https://github.com/zylin/Verilog_VCD[].

The initial purpose of this fork was <<vcdcat>>, but other features ended up being added (basically because by people are now able to conveniently communicate with the project on GitHub), e.g. convenient random access as mentioned at <<api-usage>> and basic tests at link:test.py[].

Another stream implementation can be found at: https://github.com/GordonMcGregor/vcd_parser[].

== Release procedure

Ensure that basic tests don't blow up:

....
./examples.py
./test.py
./vcdcat counter_tb.vcd
./vcdcat -d counter_tb.vcd
....

Update the `version` field in `setup.py`:

....
vim setup.py
....

Create a tag and push it:

....
v=v2.3.4
git add setup.py
git commit -m $v
git tag -a $v -m $v
git push --follow-tags
....

Push to PyPi:

....
pipx install twine
python3 setup.py sdist bdist_wheel
twine upload dist/*
rm -rf build dist *.egg-info
....

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

vcdvcd-2.3.6.tar.gz (13.4 kB view details)

Uploaded Source

Built Distribution

vcdvcd-2.3.6-py3-none-any.whl (11.7 kB view details)

Uploaded Python 3

File details

Details for the file vcdvcd-2.3.6.tar.gz.

File metadata

  • Download URL: vcdvcd-2.3.6.tar.gz
  • Upload date:
  • Size: 13.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.12.3

File hashes

Hashes for vcdvcd-2.3.6.tar.gz
Algorithm Hash digest
SHA256 3a48654f63fe4c303456acd27b2ab8480c9d357097f34f7e1b9d84005408cd4e
MD5 e0f65a27869c1e7ce3594084e3ee309c
BLAKE2b-256 80159c24d476935e26116ac0b12b2e282f17b28cd1bba842ae9e0733c8d712b5

See more details on using hashes here.

File details

Details for the file vcdvcd-2.3.6-py3-none-any.whl.

File metadata

  • Download URL: vcdvcd-2.3.6-py3-none-any.whl
  • Upload date:
  • Size: 11.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.12.3

File hashes

Hashes for vcdvcd-2.3.6-py3-none-any.whl
Algorithm Hash digest
SHA256 69607a4e9eac45dd868366327a157d152c49caf590dbd676a96e4baa62a2fe27
MD5 5e4d1e5209a2b96c57a1532f74900418
BLAKE2b-256 4a18d8a0a4efab0dfc20af2f6043cfe1d77e689d12eef5e744de71831cd24860

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page