OpenCores
URL https://opencores.org/ocsvn/w11/w11/trunk

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.74/] [tools/] [bin/] [tbfilt] - Blame information for rev 38

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 37 wfjm
#!/usr/bin/perl -w
2
# $Id: tbfilt 807 2016-09-17 07:49:26Z mueller $
3
#
4
# Copyright 2016- by Walter F.J. Mueller 
5
#
6
# This program is free software; you may redistribute and/or modify it under
7
# the terms of the GNU General Public License as published by the Free
8
# Software Foundation, either version 2, or at your option any later version.
9
#
10
# This program is distributed in the hope that it will be useful, but
11
# WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
12
# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13
# for complete details.
14
#
15
#  Revision History:
16
# Date         Rev Version  Comment
17
# 2016-09-10   806   1.0    Initial version
18
# 2016-08-05   795   0.1    First draft
19
#
20
 
21
use 5.14.0;                                 # require Perl 5.14 or higher
22
use strict;                                 # require strict checking
23
 
24
use Getopt::Long;
25
use FileHandle;
26
use POSIX qw(strftime);
27
 
28
my %opts = ();
29
 
30
GetOptions(\%opts, "tee=s",  "pcom",
31
           "find=s", "all",
32
           "summary", "wide", "compact", "format=s", "nohead"
33
          )
34
  or die "bad options";
35
 
36
sub do_file;
37
sub conv_fd;
38
sub conv_ft;
39
sub conv_fs;
40
sub conv_fa;
41
sub conv_tr;
42
sub conv_tu;
43
sub conv_ts;
44
sub conv_tc;
45
sub conv_tg;
46
sub conv_st;
47
sub conv_ss;
48
sub conv_sc;
49
sub conv_sg;
50
sub conv_sp;
51
sub conv_sm;
52
sub conv_ec;
53
sub conv_pf;
54
sub conv_nf;
55
sub conv_ns;
56
 
57
my %fmttbl = (fd => {conv => \&conv_fd, head=>' file-date'},
58
              ft => {conv => \&conv_ft, head=>'    time'},
59
              fs => {conv => \&conv_fs, head=>' time'},
60
              fa => {conv => \&conv_fa, head=>'age'},
61
              tr => {conv => \&conv_tr, head=>'  time-real'},
62
              tu => {conv => \&conv_tu, head=>'  time-user'},
63
              ts => {conv => \&conv_ts, head=>'   time-sys'},
64
              tc => {conv => \&conv_tc, head=>'   time-cpu'},
65
              tg => {conv => \&conv_tg, head=>'       time t'},
66
              st => {conv => \&conv_st, head=>'stime(ns)'},
67
              ss => {conv => \&conv_ss, head=>'stime'},
68
              sc => {conv => \&conv_sc, head=>'  cycles'},
69
              sg => {conv => \&conv_sg, head=>' cyc|tim'},
70
              sp => {conv => \&conv_sp, head=>'sperf'},
71
              sm => {conv => \&conv_sm, head=>'MHz'},
72
              ec => {conv => \&conv_ec, head=>'err'},
73
              pf => {conv => \&conv_pf, head=>'stat'},
74
              nf => {conv => \&conv_nf, head=>'filename'},
75
              ns => {conv => \&conv_ns, head=>'filename'});
76
my @fmtlst;
77
 
78
my $format = $ENV{TBFILT_FORMAT};
79
$format = '%fd %fs %tr %tc %sc %ec %pf %nf' if $opts{wide};
80
$format = '%fa %tg %sg %ec %pf %ns' if $opts{compact};
81
$format = $opts{format} if defined $opts{format};
82
$format = '%ec %pf %nf' unless defined $format;
83
 
84
while (length($format)) {
85
  if ($format =~ m/^([^%]*)%([a-z][a-z])/) {
86
    my $pref = $1;
87
    my $code = $2;
88
    if (exists $fmttbl{$code}) {
89
      push @fmtlst, {pref => $pref,
90
                     conv => $fmttbl{$code}{conv},
91
                     head => $fmttbl{$code}{head}};
92
    } else { last; };
93
    $format = $';
94
  } else { last; };
95
}
96
if (length($format)) {
97
  print STDERR "tbfilt-f: bad format '$format'\n";
98
  exit 2;
99
}
100
 
101
autoflush STDOUT 1 if (-p STDOUT);
102
 
103
my $fh_tee;
104
if (defined $opts{tee} && $opts{tee} ne '') {
105
  $fh_tee = new FileHandle;
106
  $fh_tee->open($opts{tee},'>') or die "failed to open for write '$opts{tee}'";
107
}
108
 
109
my @flist = @ARGV;
110
 
111
# if find pattern has no '*', expand it
112
if (defined $opts{find}) {
113
  unless ($opts{find} =~ m/\*/) {
114
    $opts{find} = '.*/tb_.*_' . $opts{find} . '.*\.log';
115
  }
116
}
117
 
118
if (defined $opts{all}) {
119
  if (defined $opts{find}) {
120
    print STDERR "tbfilt-I: -find ignored because -all given\n";
121
  }
122
  $opts{find} = '.*/tb_.*_[bfsorept]sim(_.*)?\.log';
123
}
124
 
125
if (defined $opts{find}) {
126
  if (scalar (@flist)) {
127
    print STDERR "tbfilt-I: file names ignored because -all or -find given\n";
128
    @flist = ();
129
  }
130
  open FIND,'-|',"find -regextype egrep -regex '$opts{find}'"
131
    or die "failed to open find pipe";
132
 
133
  while () {
134
    chomp;
135
    s|^\./||;                               # drop leading ./
136
    push @flist, $_;
137
  }
138
 
139
  close FIND;
140
  @flist = sort @flist;
141
  if (scalar (@flist) == 0) {
142
    print STDERR "tbfilt-E: no files found by -find or -all\n";
143
    exit 2;
144
  }
145
 
146
} else {
147
  push @flist, '-' if (scalar(@flist) == 0);
148
}
149
 
150
my $manyfile = scalar(@flist) > 1;
151
my $notsumm  = not $opts{summary};
152
my %vals;
153
my $exitcode = 0;
154
 
155
if ($opts{summary} && (not $opts{nohead})) {
156
  foreach my $item (@fmtlst) {
157
    print $item->{pref};
158
    print $item->{head};
159
  }
160
  print "\n";
161
}
162
 
163
foreach my $fnam (@flist) {
164
  my $nfail = do_file($fnam);
165
  $exitcode = 1 if $nfail;
166
}
167
 
168
exit $exitcode;
169
 
170
#-------------------------------------------------------------------------------
171
 
172
sub do_file {
173
  my ($fnam) = @_;
174
 
175
  %vals = ();
176
  $vals{fnam}  = $fnam;
177
  $vals{nfail} = 0;
178
 
179
  my $fh;
180
  if ($fnam eq '-') {
181
    $fh = *STDIN;
182
  } else {
183
    $fh = new FileHandle;
184
    $fh->open($fnam,'<') or die "failed to open for read '$fnam'";
185
  }
186
 
187
  if ($manyfile && $notsumm) {
188
    print "-- $fnam";
189
    my $npad = 74-length($fnam);
190
    print ' '.('-' x $npad) if $npad > 0;
191
    print "\n";
192
  }
193
 
194
  while (<$fh>) {
195
    print $fh_tee $_ if defined  $fh_tee;
196
    chomp;
197
    my $show;
198
    my $fail;
199
 
200
    $fail = 1 if m/-[EF]:/;
201
    $fail = 1 if m/(ERROR|FAIL)/;
202
    $show = 1 if m/-W:/;
203
    $show = 1 if m/(PASS)/;
204
    $show = 1 if $opts{pcom} && m/^C/;      # show lines starting with C
205
 
206
    # ghdl reports or assertions (warning and higher)
207
    if (m/:\((report|assertion) (warning|error|failure)\):/) {
208
      # ignore ieee lib warnings at t=0
209
      next if /:\@0ms:\(assertion warning\): NUMERIC_STD.*metavalue detected/;
210
      next if /:\@0ms:\(assertion warning\): CONV_INTEGER: There is an 'U'/;
211
      next if /std_logic_arith.*:\@0ms:\(assertion warning\): There is an 'U'/;
212
      # ignore ' Simulation Finished' report failure (used to end ghdl sim)
213
      next if /:\(report failure\): Simulation Finished/;
214
      $fail = 1;
215
    }
216
 
217
    # check for DONE line accept
218
    #           920 ns: DONE                   -- tb'swithout clock
219
    #     7798080.0 ns 389893: DONE            -- single clock tb's
220
    #       56075.0 ns   2094: DONE-w          -- multiclock tb's  (max taken)
221
    #
222
    if (m/^\s*(\d+\.?\d*)\s+ns\s*(\d*):\s+DONE(-\S+)?\s*$/) {
223
      $show = 1;
224
      $vals{done_ns}  = $1;
225
      if ($2 ne '') {
226
        if (defined $vals{done_cyc}) {
227
          $vals{done_cyc} = $2 if $2 > $vals{done_cyc};
228
        } else {
229
          $vals{done_cyc} = $2;
230
        }
231
      }
232
    }
233
 
234
    # check for time line
235
    # Note: don't root the pattern with /^ --> allow arbitary text before
236
    #       the 'time' output. In practice 'time' output (to stderr by bash)
237
    #       and ghdl 'report' (also to stderr) get mixed and one might get
238
    #         tb_w11a_b3real 0m49.179s   user 0m0.993s   sys 0m0.293s
239
    #
240
    if (m/real\s+(\d*)m(\d+\.\d*)s\s+
241
          user\s+(\d*)m(\d+\.\d*)s\s+
242
           sys\s+(\d*)m(\d+\.\d*)s/x) {
243
      $show = 1;
244
      $vals{treal} = [$1,$2];
245
      $vals{tuser} = [$3,$4];
246
      $vals{tsys}  = [$5,$6];
247
    }
248
 
249
    print "$_\n" if ($show || $fail) && $notsumm;
250
    $vals{nfail} += 1 if $fail;
251
  }
252
 
253
  if (not defined $vals{done_ns}) {
254
    print "tbfilt-I: no DONE seen; FAIL\n" if $notsumm;
255
    $vals{nfail} += 1;
256
  }
257
 
258
  $vals{mtime} = ($fnam eq '-') ? time :  (stat($fh))[9];
259
 
260
  if ($opts{summary}) {
261
    foreach my $item (@fmtlst) {
262
      print $item->{pref};
263
      print &{$item->{conv}};
264
    }
265
    print "\n";
266
  }
267
 
268
  return $vals{nfail};
269
}
270
 
271
#-------------------------------------------------------------------------------
272
sub time_val {
273
  my ($tdsc) = @_;
274
  return undef unless defined $tdsc;
275
  return 60.*$tdsc->[0] + $tdsc->[1];
276
}
277
 
278
sub time_str {
279
  my ($tdsc) = @_;
280
  return '          -' unless defined $tdsc;
281
  return sprintf '%3dm%06.3fs', $tdsc->[0],$tdsc->[1];
282
}
283
 
284
sub time_sum {
285
  my ($tdsc1,$tdsc2) = @_;
286
  return undef unless defined $tdsc1 && defined $tdsc2;
287
  return time_val($tdsc1) + time_val($tdsc2);
288
}
289
 
290
sub gconv {
291
  my ($val) = @_;
292
  my $str = sprintf '%4.2f', $val;
293
  return substr($str,0,4);
294
}
295
 
296
#-------------------------------------------------------------------------------
297
sub conv_fd {
298
  return strftime "%F", localtime($vals{mtime});
299
}
300
 
301
sub conv_ft {
302
  return strftime "%T", localtime($vals{mtime});
303
}
304
 
305
sub conv_fs {
306
  return strftime "%H:%M", localtime($vals{mtime});
307
}
308
 
309
sub conv_fa {
310
  my $dt = time - $vals{mtime};
311
             return sprintf '%2ds', $dt if $dt < 99;
312
  $dt /= 60; return sprintf '%2dm', $dt if $dt < 99;
313
  $dt /= 60; return sprintf '%2dh', $dt if $dt < 60;
314
  $dt /= 24; return sprintf '%2dd', $dt if $dt < 99;
315
             return 'old';
316
}
317
 
318
sub conv_tr {
319
  return time_str($vals{treal});
320
}
321
 
322
sub conv_tu {
323
  return time_str($vals{tuser});
324
                }
325
 
326
sub conv_ts {
327
  return time_str($vals{tsys});
328
}
329
 
330
sub conv_tc {
331
  my $tsum = time_sum($vals{tuser}, $vals{tsys});
332
  return '          -' unless defined $tsum;
333
  my $min = int($tsum/60.);
334
  my $sec = $tsum - 60. * $min;
335
  return sprintf '%3dm%06.3fs', $min, $sec;
336
}
337
 
338
sub conv_tg {
339
  my $treal = time_val($vals{treal});
340
  my $tcpu  = time_sum($vals{tuser}, $vals{tsys});
341
  if (defined $treal && defined $tcpu && $tcpu > 0.4 * $treal) {
342
    return conv_tc() . ' c' ;
343
  } else {
344
    return conv_tr() . ((defined $treal) ? ' r': ' -');
345
  }
346
}
347
 
348
sub conv_st {
349
  return '        -' unless defined $vals{done_ns};
350
  return sprintf '%9d', $vals{done_ns};
351
}
352
 
353
sub conv_ss {
354
  return '    -' unless defined $vals{done_ns};
355
  my $stim = 0.001 * $vals{done_ns};
356
                  return gconv($stim) . 'u' if $stim < 999;
357
  $stim *= 0.001; return gconv($stim) . 'm' if $stim < 999;
358
  $stim *= 0.001; return gconv($stim) . 's';
359
}
360
 
361
sub conv_sc {
362
  return '       -' unless defined $vals{done_cyc};
363
  return sprintf '%8d', $vals{done_cyc};
364
}
365
 
366
sub conv_sg {
367
  return conv_sc() if defined $vals{done_cyc};
368
  return '   ' . conv_ss();
369
}
370
 
371
sub conv_sp {
372
  my $nc   = $vals{done_cyc};
373
  my $tsum = time_sum($vals{tuser}, $vals{tsys});
374
  return '    -' unless defined $nc && defined $tsum;
375
  my $sperf = 1000000. * $tsum / $nc;
376
                   return gconv($sperf) . 'u' if $sperf < 999;
377
  $sperf *= 0.001; return gconv($sperf) . 'm';
378
}
379
 
380
sub conv_sm {
381
  return '  -' unless defined $vals{done_ns} && $vals{done_ns} > 200 &&
382
                      defined $vals{done_cyc};
383
  my $mhz = (1000. * $vals{done_cyc}) / ($vals{done_ns} - 200);
384
  return sprintf '%3d', int($mhz+0.5);
385
}
386
 
387
sub conv_ec {
388
  return sprintf '%3d', $vals{nfail};
389
}
390
 
391
sub conv_pf {
392
  return $vals{nfail} ? 'FAIL' : 'PASS';
393
}
394
 
395
sub conv_nf {
396
  return $vals{fnam};
397
}
398
 
399
sub conv_ns {
400
  my $val = $vals{fnam};
401
  $val =~ s|^.*/||;
402
  return $val;
403
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.