Fix VCD files showing internal flattened hierarchy, broke in 3.714.
This commit is contained in:
parent
66d000f4ba
commit
db5674cb08
4
Changes
4
Changes
|
|
@ -3,6 +3,10 @@ Revision history for Verilator
|
|||
The contributors that suggested a given feature are shown in []. [by ...]
|
||||
indicates the contributor was also the author of the fix; Thanks!
|
||||
|
||||
* Verilator 3.71****
|
||||
|
||||
**** Fix VCD files showing internal flattened hierarchy, broke in 3.714.
|
||||
|
||||
* Verilator 3.714 2009/09/18
|
||||
|
||||
** Add --bbox-sys option to blackbox $system calls.
|
||||
|
|
|
|||
|
|
@ -139,6 +139,21 @@ string AstNode::dedotName(const string& namein) {
|
|||
return pretty;
|
||||
}
|
||||
|
||||
string AstNode::vcdName(const string& namein) {
|
||||
// VCD tracing expects space to separate hiearchy
|
||||
// Dots are reserved for dots the user put in the name
|
||||
string pretty = namein;
|
||||
string::size_type pos;
|
||||
while ((pos=pretty.find("__DOT__")) != string::npos) {
|
||||
pretty.replace(pos, 7, " ");
|
||||
}
|
||||
while ((pos=pretty.find(".")) != string::npos) {
|
||||
pretty.replace(pos, 1, " ");
|
||||
}
|
||||
// Now convert escaped special characters, etc
|
||||
return prettyName(pretty);
|
||||
}
|
||||
|
||||
string AstNode::prettyName(const string& namein) {
|
||||
string pretty;
|
||||
pretty = "";
|
||||
|
|
|
|||
|
|
@ -676,6 +676,7 @@ public:
|
|||
static string prettyName(const string& namein); // Name for printing out to the user
|
||||
static string encodeName(const string& namein); // Encode user name into internal C representation
|
||||
static string encodeNumber(vlsint64_t numin); // Encode number into internal C representation
|
||||
static string vcdName(const string& namein); // Name for printing out to vcd files
|
||||
string prettyName() const { return prettyName(name()); }
|
||||
string prettyTypeName() const; // "VARREF name" for error messages
|
||||
FileLine* fileline() const { return m_fileline; }
|
||||
|
|
|
|||
|
|
@ -125,8 +125,10 @@ private:
|
|||
AstVar* varp = nodep->varp();
|
||||
AstScope* scopep = nodep->scopep();
|
||||
// Compute show name
|
||||
string showname = scopep->prettyName() + "." + varp->prettyName();
|
||||
if (showname.substr(0,4) == "TOP.") showname.replace(0,4,"");
|
||||
// This code assumes SPTRACEVCDC_VERSION >= 1330;
|
||||
// it uses spaces to separate hierarchy components.
|
||||
string showname = AstNode::vcdName(scopep->name() + " " + varp->name());
|
||||
if (showname.substr(0,4) == "TOP ") showname.replace(0,4,"");
|
||||
if (!m_initSubFuncp) nodep->v3fatalSrc("NULL");
|
||||
if (varIgnoreTrace(varp)) {
|
||||
m_statIgnSigs++;
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ BEGIN {
|
|||
use Getopt::Long;
|
||||
use IO::File;
|
||||
use Pod::Usage;
|
||||
use Data::Dumper;
|
||||
use Data::Dumper; $Data::Dumper::Sortkeys=1;
|
||||
use strict;
|
||||
use vars qw ($Debug %Vars $Driver $Fork);
|
||||
use POSIX qw(strftime);
|
||||
|
|
@ -903,17 +903,59 @@ sub vcd_identical {
|
|||
my $fn2 = shift;
|
||||
if (!-r $fn1) { $self->error("File does not exist $fn1\n"); return 0; }
|
||||
if (!-r $fn2) { $self->error("File does not exist $fn2\n"); return 0; }
|
||||
my $out = `vcddiff --help`;
|
||||
if ($out !~ /Usage:/) { $self->skip("No vcddiff installed\n"); return 0; }
|
||||
$out = `vcddiff "$fn1" "$fn2"`;
|
||||
if ($out ne '') {
|
||||
print $out;
|
||||
$self->error("VCD miscompare $fn1 $fn2\n");
|
||||
return 0;
|
||||
{
|
||||
# vcddiff to check transitions, if installed
|
||||
my $out = `vcddiff --help`;
|
||||
if ($out !~ /Usage:/) { $self->skip("No vcddiff installed\n"); return 0; }
|
||||
my $cmd = qq{vcddiff "$fn1" "$fn2"};
|
||||
print "\t$cmd\n" if $::Debug;
|
||||
$out = `$cmd`;
|
||||
if ($out ne '') {
|
||||
print $out;
|
||||
$self->error("VCD miscompare $fn1 $fn2\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
{
|
||||
# vcddiff doesn't check module and variable scope, so check that
|
||||
# Also provides backup if vcddiff not installed
|
||||
my $h1 = $self->_vcd_read($fn1);
|
||||
my $h2 = $self->_vcd_read($fn2);
|
||||
$Data::Dumper::Sortkeys=1;
|
||||
my $a = Dumper($h1);
|
||||
my $b = Dumper($h2);
|
||||
if ($a ne $b) {
|
||||
print "$a\n$b\n" if $::Debug;
|
||||
$self->error("VCD hier mismatch $fn1 $fn2\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub _vcd_read {
|
||||
my $self = (ref $_[0]? shift : $Self);
|
||||
my $filename = shift;
|
||||
my $data = {};
|
||||
my $fh = IO::File->new ("<$filename");
|
||||
if (!$fh) { warn "%Error: $! $filename\n"; return $data; }
|
||||
my @hier = ($data);
|
||||
while (defined(my $line = $fh->getline)) {
|
||||
if ($line =~ /\$scope module\s+(\S+)/) {
|
||||
$hier[$#hier]->{$1} ||= {};
|
||||
push @hier, $hier[$#hier]->{$1};
|
||||
} elsif ($line =~ /(\$var \S+\s+\d+\s+)\S+\s+(\S+)/) {
|
||||
$hier[$#hier]->{$1.$2} ||= 1;
|
||||
} elsif ($line =~ /\$enddefinitions/) {
|
||||
last;
|
||||
}
|
||||
while ($line =~ s/\$upscope//) {
|
||||
pop @hier;
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
sub file_grep_not {
|
||||
my $self = (ref $_[0]? shift : $Self);
|
||||
my $filename = shift;
|
||||
|
|
|
|||
|
|
@ -20,10 +20,9 @@ if ($Self->{v3}) {
|
|||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(vcd_identical ("$Self->{obj_dir}/simx.vcd",
|
||||
"t/$Self->{name}.out"));
|
||||
}
|
||||
else {
|
||||
ok(1);
|
||||
vcd_identical ("$Self->{obj_dir}/simx.vcd",
|
||||
"t/$Self->{name}.out");
|
||||
}
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
|
|
|||
|
|
@ -20,10 +20,10 @@ if ($Self->{v3}) {
|
|||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(vcd_identical ("$Self->{obj_dir}/simx.vcd",
|
||||
"t/$Self->{name}.out"));
|
||||
}
|
||||
else {
|
||||
ok(1);
|
||||
vcd_identical ("$Self->{obj_dir}/simx.vcd",
|
||||
"t/$Self->{name}.out");
|
||||
# vcd_identical doesn't detect "$var a.b;" vs "$scope module a; $var b;"
|
||||
file_grep ("$Self->{obj_dir}/simx.vcd", qr/module glbl/i);
|
||||
}
|
||||
ok(1);
|
||||
1;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,244 @@
|
|||
$version Generated by SpTraceVcd $end
|
||||
$date Sat Sep 26 08:06:30 2009
|
||||
$end
|
||||
$timescale 1ns $end
|
||||
|
||||
$scope module TOP $end
|
||||
$var wire 1 * 9num $end
|
||||
$var wire 1 + bra[ket]slash/dash-colon:9backslash\done $end
|
||||
$var wire 1 ' clk $end
|
||||
$var wire 1 ) double__underscore $end
|
||||
$var wire 1 ( escaped_normal $end
|
||||
$scope module v $end
|
||||
$var wire 1 * 9num $end
|
||||
$var wire 32 & a0.cyc [31:0] $end
|
||||
$var wire 1 + bra[ket]slash/dash-colon:9backslash\done $end
|
||||
$var wire 1 $ check:alias $end
|
||||
$var wire 1 % check;alias $end
|
||||
$var wire 1 $ check_alias $end
|
||||
$var wire 1 ' clk $end
|
||||
$var wire 32 # cyc [31:0] $end
|
||||
$var wire 1 ) double__underscore $end
|
||||
$var wire 1 ( escaped_normal $end
|
||||
$var wire 32 & other.cyc [31:0] $end
|
||||
$var wire 1 $ wire $end
|
||||
$scope module a0 $end
|
||||
$var wire 32 # cyc [31:0] $end
|
||||
$upscope $end
|
||||
$scope module mod.with_dot $end
|
||||
$var wire 32 # cyc [31:0] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$enddefinitions $end
|
||||
|
||||
|
||||
#1
|
||||
1$
|
||||
0%
|
||||
b11111111111111111111111111111110 &
|
||||
b00000000000000000000000000000001 #
|
||||
1'
|
||||
1(
|
||||
1)
|
||||
1*
|
||||
1+
|
||||
#2
|
||||
#3
|
||||
#4
|
||||
#5
|
||||
0'
|
||||
#6
|
||||
#7
|
||||
#8
|
||||
#9
|
||||
#10
|
||||
0$
|
||||
1%
|
||||
b11111111111111111111111111111101 &
|
||||
b00000000000000000000000000000010 #
|
||||
1'
|
||||
0(
|
||||
0)
|
||||
0*
|
||||
0+
|
||||
#11
|
||||
#12
|
||||
#13
|
||||
#14
|
||||
#15
|
||||
0'
|
||||
#16
|
||||
#17
|
||||
#18
|
||||
#19
|
||||
#20
|
||||
1$
|
||||
0%
|
||||
b11111111111111111111111111111100 &
|
||||
b00000000000000000000000000000011 #
|
||||
1'
|
||||
1(
|
||||
1)
|
||||
1*
|
||||
1+
|
||||
#21
|
||||
#22
|
||||
#23
|
||||
#24
|
||||
#25
|
||||
0'
|
||||
#26
|
||||
#27
|
||||
#28
|
||||
#29
|
||||
#30
|
||||
0$
|
||||
1%
|
||||
b11111111111111111111111111111011 &
|
||||
b00000000000000000000000000000100 #
|
||||
1'
|
||||
0(
|
||||
0)
|
||||
0*
|
||||
0+
|
||||
#31
|
||||
#32
|
||||
#33
|
||||
#34
|
||||
#35
|
||||
0'
|
||||
#36
|
||||
#37
|
||||
#38
|
||||
#39
|
||||
#40
|
||||
1$
|
||||
0%
|
||||
b11111111111111111111111111111010 &
|
||||
b00000000000000000000000000000101 #
|
||||
1'
|
||||
1(
|
||||
1)
|
||||
1*
|
||||
1+
|
||||
#41
|
||||
#42
|
||||
#43
|
||||
#44
|
||||
#45
|
||||
0'
|
||||
#46
|
||||
#47
|
||||
#48
|
||||
#49
|
||||
#50
|
||||
0$
|
||||
1%
|
||||
b11111111111111111111111111111001 &
|
||||
b00000000000000000000000000000110 #
|
||||
1'
|
||||
0(
|
||||
0)
|
||||
0*
|
||||
0+
|
||||
#51
|
||||
#52
|
||||
#53
|
||||
#54
|
||||
#55
|
||||
0'
|
||||
#56
|
||||
#57
|
||||
#58
|
||||
#59
|
||||
#60
|
||||
1$
|
||||
0%
|
||||
b11111111111111111111111111111000 &
|
||||
b00000000000000000000000000000111 #
|
||||
1'
|
||||
1(
|
||||
1)
|
||||
1*
|
||||
1+
|
||||
#61
|
||||
#62
|
||||
#63
|
||||
#64
|
||||
#65
|
||||
0'
|
||||
#66
|
||||
#67
|
||||
#68
|
||||
#69
|
||||
#70
|
||||
0$
|
||||
1%
|
||||
b11111111111111111111111111110111 &
|
||||
b00000000000000000000000000001000 #
|
||||
1'
|
||||
0(
|
||||
0)
|
||||
0*
|
||||
0+
|
||||
#71
|
||||
#72
|
||||
#73
|
||||
#74
|
||||
#75
|
||||
0'
|
||||
#76
|
||||
#77
|
||||
#78
|
||||
#79
|
||||
#80
|
||||
1$
|
||||
0%
|
||||
b11111111111111111111111111110110 &
|
||||
b00000000000000000000000000001001 #
|
||||
1'
|
||||
1(
|
||||
1)
|
||||
1*
|
||||
1+
|
||||
#81
|
||||
#82
|
||||
#83
|
||||
#84
|
||||
#85
|
||||
0'
|
||||
#86
|
||||
#87
|
||||
#88
|
||||
#89
|
||||
#90
|
||||
0$
|
||||
1%
|
||||
b11111111111111111111111111110101 &
|
||||
b00000000000000000000000000001010 #
|
||||
1'
|
||||
0(
|
||||
0)
|
||||
0*
|
||||
0+
|
||||
#91
|
||||
#92
|
||||
#93
|
||||
#94
|
||||
#95
|
||||
0'
|
||||
#96
|
||||
#97
|
||||
#98
|
||||
#99
|
||||
#100
|
||||
1$
|
||||
0%
|
||||
b11111111111111111111111111110100 &
|
||||
b00000000000000000000000000001011 #
|
||||
1'
|
||||
1(
|
||||
1)
|
||||
1*
|
||||
1+
|
||||
|
|
@ -19,7 +19,11 @@ execute (
|
|||
if ($Self->{v3}) {
|
||||
file_grep ("$Self->{obj_dir}/simx.vcd", qr/\$enddefinitions/x);
|
||||
my $sig = quotemeta("bra[ket]slash/dash-colon:9");
|
||||
file_grep ("$Self->{obj_dir}/simx.vcd", qr/$sig/);
|
||||
file_grep ("$Self->{obj_dir}/simx.vcd", qr/ $sig/);
|
||||
file_grep ("$Self->{obj_dir}/simx.vcd", qr/ other\.cyc /);
|
||||
file_grep ("$Self->{obj_dir}/simx.vcd", qr/ module mod\.with_dot /);
|
||||
vcd_identical ("$Self->{obj_dir}/simx.vcd",
|
||||
"t/$Self->{name}.out");
|
||||
}
|
||||
|
||||
ok(1);
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@ module t (/*AUTOARG*/
|
|||
|
||||
sub a0 (.cyc(cyc));
|
||||
|
||||
sub \mod.with_dot (.cyc(cyc));
|
||||
|
||||
always @ (posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
if (escaped_normal != cyc[0]) $stop;
|
||||
|
|
|
|||
Loading…
Reference in New Issue