__ _
_ ___________/ /____(_)___ ___
| | / / ___/ __ / ___/ / __ `__ \
| |/ / /__/ /_/ (__ ) / / / / / /
|___/\___/\__,_/____/_/_/ /_/ /_/
vcdsim - A Value Change Dump reader for hardware simulation
VCD files are ubiquitous when it comes to hardware simulation or digital signal acquisition (logic analyzers).
vcdsim can transform a VCD file into a Verilog or C++ Verilator testbenches, if used via the vcdconvert
command-line.
It can also be used as a plain Python library to use in combination with Migen.
According to the wikipedia page:
Value Change Dump (VCD) (also known less commonly as "Variable Change Dump") is an ASCII-based format for dumpfiles generated by EDA logic simulation tools. The standard, four-value VCD format was defined along with the Verilog hardware description language by the IEEE Standard 1364-1995 in 1996.
We will use the following example (as per Wikipedia page) as support for the following explanations:
$date
Date text. For example: November 11, 2009.
$end
$version
VCD generator tool version info text.
$end
$comment
Any comment text.
$end
$timescale 1ps $end
$scope module logic $end
$var wire 8 # data $end
$var wire 1 $ data_valid $end
$var wire 1 % en $end
$var wire 1 & rx_en $end
$var wire 1 ' tx_en $end
$var wire 1 ( empty $end
$var wire 1 ) underrun $end
$upscope $end
$enddefinitions $end
$dumpvars
bxxxxxxxx #
x$
0%
x&
x'
1(
0)
$end
#0
b10000001 #
0$
1%
0&
1'
0(
0)
#2211
0'
#2296
b0 #
1$
#2302
0$
#2303
The example VCD can be transformed into a Verilog testbench file with the following command:
vcdconvert examples/sample/sample.vcd --verilog examples/sample/sample.v
This gives the following output:
/*
generated by vcdsim on 2021-08-14 18:16:57.704493
path: examples/sample/sample.vcd
*/
`timescale 1ns/1ns
module vcdsim
(
output reg logic_data,
output reg logic_data_valid,
output reg logic_en,
output reg logic_rx_en,
output reg logic_tx_en,
output reg logic_empty,
output reg logic_underrun
);
initial begin
logic_data='bxxxxxxxx;
logic_data_valid='bx;
logic_en=0;
logic_rx_en='bx;
logic_tx_en='bx;
logic_empty=1;
logic_underrun=0;
#0;
logic_data='b10000001;
logic_data_valid=0;
logic_en=1;
logic_rx_en=0;
logic_tx_en=1;
logic_empty=0;
logic_underrun=0;
#2211;
logic_tx_en=0;
#2296;
logic_data='b0;
logic_data_valid=1;
#2302;
logic_data_valid=0;
#2303;
end
endmodule
As we can see, this Verilog testbench uses delays, which makes it non-synthetizable. However, it's probably the most portabe solution. iverilog has no trouble reading the testbench.
Verilator is a very fast Verilog simulator, but it has several limitations:
- only handles synthetizable Verilog
- does not handle 'z' or 'x' values
- only handles a regular clock
vcdconvert generates a C++ testbench for Verilator. Our VCD example can be converted using the following command:
vcdconvert examples/sample/sample.vcd --verilator examples/sample/sample.cpp --verilator-clock-freq 100E6
However, our example can't be converted directly as some values are invalid:
ValueError: value invalid bxxxxxxxx #
Two options are available: --ignore-invalid
and --replace-invalid
The first one simply ignores any value changes which have at least one 'x' or 'z' value.
The latter replaces 'x' and 'z' by the value specified.
NOTE: if ignoring invalid values, if a single bit from a vector is either 'x' or 'z', none of the vector bits will be updated!
vcdconvert examples/sample/sample.vcd --verilator examples/tb_verilator.cpp --verilator-clock-freq=100E6 \
--replace-invalid 0 --verilog examples/sample/sample.v
this generates:
/*
generated by vcdsim on 2021-08-14 18:16:57.704655
path: examples/sample/sample.vcd
*/
#include <stdio.h>
#include <stdlib.h>
#include "Vvcdsim.h"
#include "verilated.h"
int main(int argc, char **argv) {
Verilated::commandArgs(argc, argv);
Vvcdsim *tb = new Vvcdsim;
tb->logic_data=0b00000000;
logic_data_valid=0;
tb->logic_en=0;
logic_rx_en=0;
logic_tx_en=0;
tb->logic_empty=1;
tb->logic_underrun=0;
tb->eval();
tb->logic_data=0b10000001;
tb->logic_data_valid=0;
tb->logic_en=1;
tb->logic_rx_en=0;
tb->logic_tx_en=1;
tb->logic_empty=0;
tb->logic_underrun=0;
for(i=0;i<221;i++){tb->eval();};
tb->logic_tx_en=0;
for(i=0;i<8;i++){tb->eval();};
tb->logic_data=0b0;
tb->logic_data_valid=1;
tb->eval();
tb->logic_data_valid=0;
}
In addition to the C++ testbench file, the conversion tool can also generate a Verilog module which can be integrated
into a larger testbench, thanks to the --verilator-verilog
option.
/*
generated by vcdsim on 2021-08-14 17:18:04.843020
path: examples/sample/sample.vcd
*/
`timescale 1ns/1ns
module vcdsim
(
output reg logic_data,
output reg logic_data_valid,
output reg logic_en,
output reg logic_rx_en,
output reg logic_tx_en,
output reg logic_empty,
output reg logic_underrun
);
endmodule
Migen is "A Python toolbox for building complex digital hardware" which has an HDL
and a built-in simulator. vcdsim can be used directly with migen simulator. See examples/migen
directory.