File: verilator_difftree

package info (click to toggle)
verilator 4.010-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 24,724 kB
  • sloc: cpp: 71,936; perl: 11,784; ansic: 8,379; yacc: 2,826; lex: 1,661; makefile: 668; sh: 175
file content (256 lines) | stat: -rwxr-xr-x 6,953 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
: # -*-Mode: perl;-*- use perl, wherever it is
eval 'exec perl -wS $0 ${1+"$@"}'
  if 0;
# See copyright, etc in below POD section.
######################################################################

require 5.006_001;
use warnings;
use Getopt::Long;
use IO::File;
use Pod::Usage;
use strict;
use vars qw($Debug);

#======================================================================

# Old version 1 dump nodes with no dtypep's
our %Ver1_Non_Dtyped = map {$_ => 1} qw(
  ACTIVE ALWAYS ALWAYSPOST ALWAYSPUBLIC ATTROF BEGIN BREAK CASE CASEITEM
  CCALL CELL CELLINLINE CFILE CFUNC CHANGEDET CLOCKING COMMENT CONTINUE
  COVERDECL COVERINC COVERTOGGLE CRETURN CSTMT DEFPARAM DISABLE DISPLAY DOT
  DPIEXPORT FCLOSE FFLUSH FINAL FINISH FOPEN GENCASE GENERATE GENFOR GENIF
  IF IMPLICIT INITARRAY INITIAL JUMPGO JUMPLABEL MODULE NETLIST
  NOTFOUNDMODULE PACKAGE PACKAGEIMPORT PARSEREF PIN PORT PRAGMA PRIMITIVE
  PSLASSERT PSLCOVER PSLDEFCLOCK PULL RANGE READMEM REPEAT RETURN SCCTOR
  SCDTOR SCHDR SCIMP SCIMPHDR SCINT SCOPE SELBIT SELEXTRACT SELMINUS
  SELPLUS SENGATE SENITEM SENTREE SFORMAT SFORMATF STOP SYSIGNORE SYSTEMT
  TASK TASKREF TEXT TOPSCOPE TYPEDEFFWD TYPETABLE UCSTMT UDPTABLE
  UDPTABLELINE UNTILSTABLE VASSERT WHILE );

#======================================================================
# main

$Debug = 0;
my $Opt_A;
my $Opt_B;
my $Opt_Lineno = 1;
autoflush STDOUT 1;
autoflush STDERR 1;
Getopt::Long::config("no_auto_abbrev");
if (! GetOptions (
	  "help"	=> \&usage,
	  "debug"	=> \&debug,
	  "<>"		=> \&parameter,
	  "lineno!"	=> \$Opt_Lineno,
    )) {
    die "%Error: Bad usage, try 'verilator_difftree --help'\n";
}

defined $Opt_A or die "%Error: No old diff filename\n";
defined $Opt_B or die "%Error: No new diff filename\n";

-e $Opt_A or die "%Error: No old diff filename found: $Opt_A\n";
-e $Opt_B or die "%Error: No new diff filename found: $Opt_B\n";

if (-d $Opt_A && -d $Opt_B) {
    diff_dir($Opt_A, $Opt_B);
} elsif (-f $Opt_A && -f $Opt_B) {
    diff_file($Opt_A, $Opt_B);
} else {
    die "%Error: Mix of files and dirs\n";
}

sub diff_dir {
    my $a = shift;
    my $b = shift;
    # Diff all files under two directories
    my %files;

    foreach my $fn (glob("$a/*.tree")) {
	(my $base = $fn) =~ s!.*/!!;
	$files{$base}{a} = $fn;
    }
    foreach my $fn (glob("$b/*.tree")) {
	(my $base = $fn) =~ s!.*/!!;
	$files{$base}{b} = $fn;
    }
    my $any;
    foreach my $base (sort (keys %files)) {
	my $a = $files{$base}{a};
	my $b = $files{$base}{b};
	next if !$a || !$b;
	print "="x70,"\n";
	print "= $a <-> $b\n";
	diff_file($a,$b);
	$any = 1;
    }
    $any or warn("%Warning: No .tree files found that have similar base names:\n    "
                 .join("\n    ", sort keys %files),"\n");
}

sub diff_file {
    my $a = shift;
    my $b = shift;
    # Compare the two tree files
    (my $short_a = $a) =~ s/[^a-zA-Z0-9.]+/_/g;
    (my $short_b = $b) =~ s/[^a-zA-Z0-9.]+/_/g;
    my $tmp_a = "/tmp/${$}_${short_a}.a";
    my $tmp_b = "/tmp/${$}_${short_b}.b";

    my $vera = version_from($a);
    my $verb = version_from($b);
    my $verCvt = (($vera < 0x3900 && $verb >= 0x3900)
		  || ($vera >= 0x3900 && $verb < 0x3900));

    filter($a, $tmp_a, $verCvt);
    filter($b, $tmp_b, $verCvt);
    system("diff -u $tmp_a $tmp_b");
    unlink $tmp_a;
    unlink $tmp_b;
}

sub version_from {
    my $fn = shift;
    # Return dump format
    my $f1 = IO::File->new ($fn) or die "%Error: $! $fn,";
    while (defined (my $line=$f1->getline())) {
	last if $. > 10;
	return hex $1 if $line =~ /\(format (0x[0-9.]+)\)/;
    }
    return 1.0;
}

sub filter {
    my $fn1 = shift;
    my $fn2 = shift;
    my $verCvt = shift;
    # Remove hex numbers before diffing
    my $f1 = IO::File->new ($fn1) or die "%Error: $! $fn1,";
    my $f2 = IO::File->new ($fn2,"w") or die "%Error: $! $fn2,";
    while (defined (my $line=$f1->getline())) {
      same_line:
	next if $line =~ / This=/;
	$line =~ s/0x[a-f0-9]+/0x/g;
	$line =~ s/<e[0-9]+\#?>/<e>/g;
	$line =~ s/{[a-z]*\d+}/{}/g if !$Opt_Lineno;
	if ($verCvt) {
	    next if $line =~ /^     NETLIST/;
	    $line =~ s!\@dt=0x\(G?/?([^)]+)\)!$1!g;  # NEW: @dt -> OLD: non @dt format
	    #					     # Below Ver1_Non_Dtyped may replace above further
	    if ($line =~ /: ([A-Z]+) /) {
		my $type = $1;
		next if $type =~ 'DTYPE';
		if ($type eq 'TYPETABLE' || $type eq 'RANGE') {
		    $line =~ /^(\s+\S+:) /; my $prefix = $1;
		    while (defined ($line=$f1->getline())) {
			next if $line =~ /^\s+[a-z]/;  # Table body
			next if $line =~ /^${prefix}[0-9]:/;
			goto same_line;
		    }
		    next;
		}
		if ($Ver1_Non_Dtyped{$type}) {
		    $line =~ s! w[0-9]+!!g;
		}
	    }
	    $line =~ s!\@dt=0$!NoW!g;   # NEW: dt=null -> common format
	    $line =~ s!\@dt=0 !NoW !g;  # NEW: dt=null -> common format
	    $line =~ s! s?w0$! NoW!g;   # OLD: no width -> common format
	    $line =~ s! s?w0 ! NoW !g;  # OLD: no width -> common format
	}
	print $f2 $line;
    }
    $f1->close;
    $f2->close;
}

#----------------------------------------------------------------------

sub usage {
    pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT);
    exit(1);
}

sub debug {
    $Debug = 1;
}

sub parameter {
    my $param = shift;
    if (!defined $Opt_A) {
	$Opt_A = $param;
    } elsif (!defined $Opt_B) {
	$Opt_B = $param;
    } else {
	die "%Error: Unknown parameter: $param\n";
    }
}

#######################################################################

sub run {
    # Run a system command, check errors
    my $command = shift;
    print "\t$command\n";
    system "$command";
    my $status = $?;
    ($status == 0) or die "%Error: Command Failed $command, $status, stopped";
}

#######################################################################
__END__

=pod

=head1 NAME

verilator_difftree - Compare two Verilator debugging trees

=head1 SYNOPSIS

  verilator_difftree .../a/a.tree  .../b/a.tree
  verilator_difftree .../a         .../b

=head1 DESCRIPTION

Verilator_difftree is used for debugging Verilator tree output files.  It
performs a diff between two files, or all files common between two
directories, ignoring irrelevant pointer differences.

=head1 ARGUMENTS

=over 4

=item --help

Displays this message and program version and exits.

=item --nolineno

Do not show differences in line numbering.

=back

=head1 DISTRIBUTION

The latest version is available from L<http://www.veripool.org/verilator>.

Copyright 2005-2019 by Wilson Snyder.  This package is free software; you can
redistribute it and/or modify it under the terms of either the GNU Lesser
General Public License Version 3 or the Perl Artistic License Version 2.0.

=head1 AUTHORS

Wilson Snyder <wsnyder@wsnyder.org>

=head1 SEE ALSO

C<verilator>

=cut

######################################################################
### Local Variables:
### compile-command: "$V4/bin/verilator_difftree  {$V4D,$V4}/test_regress/obj_dir/t_EXAMPLE/V*_03_*.tree"
### End: