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

Subversion Repositories wb_lcd

[/] [wb_lcd/] [trunk/] [myhdl/] [wb_lcd_workspace_ramless/] [tools/] [xdlanalyze/] [xdlanalyze.pl] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jvillar
#!/usr/bin/perl -w
2
#
3
# xdlanalyze.pl - A script to view some statistics about XDL-files
4
#
5
# Copyright (c) 2006 Andreas Ehliar <ehliar@isy.liu.se>
6
# You may copy or modify this program under the terms of the GNU
7
# General Public License (version 2 or later)
8
#
9
# Usage: xdlanalyze.pl foo.xdl [hierarchy levels]
10
#
11
# Example usage:
12
# $ perl xdlanalyze.pl dafk.xdl
13
# XDLAnalyze V1.1 by Andreas Ehliar <ehliar@isy.liu.se>
14
# Analyzing the file dafk.xdl...................................................
15
# +-------------+--------+--------+--------+-----------+--------+--------+
16
# | Module      |   LUTS |     FF | RAMB16 | MULT18x18 |    IOB |    DCM |
17
# +-------------+--------+--------+--------+-----------+--------+--------+
18
# | /           |     64 |        |        |           |    216 |        |
19
# | cpu         |   5065 |   1345 |     12 |         4 |        |        |
20
# | dma0        |    654 |    254 |      1 |           |        |        |
21
# | dvga        |    816 |    755 |      4 |           |        |        |
22
# | eth3        |   2995 |   2337 |      4 |           |        |        |
23
# | jpg0        |   1682 |    681 |      2 |        13 |        |        |
24
# | leela       |    684 |    552 |      4 |         2 |        |        |
25
# | pia         |      9 |        |        |           |        |        |
26
# | pkmc_mc     |    219 |    122 |        |           |        |        |
27
# | rom0        |    111 |      3 |     12 |           |        |        |
28
# | sys_sig_gen |        |      6 |        |           |        |      2 |
29
# | uart2       |    824 |    346 |        |           |        |        |
30
# | wb_conbus   |    618 |     10 |        |           |        |        |
31
# +-------------+--------+--------+--------+-----------+--------+--------+
32
# | Total       |  13741 |   6411 |     39 |        19 |    216 |      2 |
33
# +-------------+--------+--------+--------+-----------+--------+--------+
34
#
35
# Example 2 (showing off hierarchical view of the same design)
36
# perl xdlanalyze.pl dafk.xdl 1
37
# XDLAnalyze V1.1 by Andreas Ehliar <ehliar@isy.liu.se>
38
# Analyzing the file dafk.xdl...................................................
39
# +-----------------------------+--------+--------+--------+-----------+--------+--------+
40
# | Module                      |   LUTS |     FF | RAMB16 | MULT18x18 |    IOB |    DCM |
41
# +-----------------------------+--------+--------+--------+-----------+--------+--------+
42
# | /                           |     64 |        |        |           |    216 |        |
43
# | cpu                         |      1 |        |        |           |        |        |
44
# | cpu/dwb_biu                 |     10 |     72 |        |           |        |        |
45
# | cpu/iwb_biu                 |     64 |     73 |        |           |        |        |
46
# | cpu/or1200_cpu              |   4441 |    987 |      2 |         4 |        |        |
47
# | cpu/or1200_dc_top           |    208 |     40 |      5 |           |        |        |
48
# | cpu/or1200_ic_top           |    182 |     38 |      5 |           |        |        |
49
# | cpu/or1200_immu_top         |     11 |     33 |        |           |        |        |
50
# | cpu/or1200_pic              |     32 |     38 |        |           |        |        |
51
# | cpu/or1200_tt               |    116 |     64 |        |           |        |        |
52
# | dma0                        |    617 |    235 |        |           |        |        |
53
# | dma0/fifo                   |     37 |     19 |      1 |           |        |        |
54
# | dvga                        |      5 |        |        |           |        |        |
55
# | dvga/regs                   |    279 |    360 |      3 |           |        |        |
56
# | dvga/rend                   |    174 |    110 |      1 |           |        |        |
57
# | dvga/spr                    |    358 |    285 |        |           |        |        |
58
# | eth3                        |     73 |     51 |        |           |        |        |
59
# | eth3/Mshreg_WillTransmit_q2 |      1 |        |        |           |        |        |
60
# | eth3/ethreg1                |    368 |    302 |        |           |        |        |
61
# | eth3/maccontrol1            |    295 |    103 |        |           |        |        |
62
# | eth3/macstatus1             |     60 |     18 |        |           |        |        |
63
# | eth3/miim1                  |    127 |     74 |        |           |        |        |
64
# | eth3/rxethmac1              |    311 |    107 |        |           |        |        |
65
# | eth3/txethmac1              |    369 |    119 |        |           |        |        |
66
# | eth3/wishbone               |   1391 |   1563 |      4 |           |        |        |
67
# | jpg0                        |    302 |     57 |      2 |           |        |        |
68
# | jpg0/dct0                   |    599 |    618 |        |        13 |        |        |
69
# | jpg0/tmem                   |    781 |      6 |        |           |        |        |
70
# | leela                       |     36 |        |        |           |        |        |
71
# | leela/cam0                  |    349 |    291 |      4 |         2 |        |        |
72
# | leela/mc0                   |    129 |     25 |        |           |        |        |
73
# | leela/regs0                 |    170 |    236 |        |           |        |        |
74
# | pia                         |      9 |        |        |           |        |        |
75
# | pkmc_mc/mem_fpga_board_if   |     40 |      1 |        |           |        |        |
76
# | pkmc_mc/pkmc_mc             |    179 |    121 |        |           |        |        |
77
# | rom0                        |     77 |      1 |        |           |        |        |
78
# | rom0/boot_prog_bram         |     34 |      2 |      8 |           |        |        |
79
# | rom0/boot_ram               |        |        |      4 |           |        |        |
80
# | sys_sig_gen                 |        |      6 |        |           |        |        |
81
# | sys_sig_gen/del0            |        |        |        |           |        |      1 |
82
# | sys_sig_gen/div0            |        |        |        |           |        |      1 |
83
# | uart2                       |      1 |        |        |           |        |        |
84
# | uart2/dbg                   |     33 |        |        |           |        |        |
85
# | uart2/regs                  |    725 |    266 |        |           |        |        |
86
# | uart2/wb_interface          |     65 |     80 |        |           |        |        |
87
# | wb_conbus                   |    618 |        |        |           |        |        |
88
# | wb_conbus/arb               |        |     10 |        |           |        |        |
89
# +-----------------------------+--------+--------+--------+-----------+--------+--------+
90
# | Total                       |  13741 |   6411 |     39 |        19 |    216 |      2 |
91
# +-----------------------------+--------+--------+--------+-----------+--------+--------+
92
# 
93
# If you don't want to print all fields, change the @print_order
94
# declaration below.
95
# 
96
# Note that the figures will usually not be exactly the same as the
97
# figures reported by map. This is partly because map does not count a 
98
# LUT with a constant output as a LUT, at least not in ISE 8.1.
99
#
100
# The program will also automatically convert a .ncd-file to a temporary
101
# .xdl file before running.
102
#
103
# This program has been tested on designs targetted at Virtex-2 and
104
# Virtex-4 from ISE 8.1 and ISE 8.2 on a Linux based computer. Note
105
# that it assumes that your path separator is set to /.
106
#
107
# Missing features:
108
#   * Slice count would be nice
109
#   * Show number of LUTs used as distributed RAM and SRL16
110
#   * Virtex-5 support
111
#
112
# NOTE:
113
#   The synthesizer will probably optimize your design across module boundaries
114
#   in some cases. This means that your figures cannot be entirely correct.
115
 
116
use strict;
117
use IO::Handle;
118
use IO::File;
119
use POSIX qw(tmpnam);
120
 
121
 
122
use constant {
123
    LUTS => 1,
124
    FF => 2,
125
    IOB => 3,
126
    RAMB16 => 4,
127
    MULT_18X18 => 5,
128
    DSP48 => 6,
129
    DCM => 7,
130
    DCM_ADV => 8,
131
    BUFG => 9,
132
    };
133
 
134
my @translation = ( "UNKNOWN", "LUTS","FF","IOB","RAMB16","MULT18x18",
135
                    "DSP48", "DCM", "DCM_ADV", "BUFG" );
136
 
137
 
138
# Modify this line to include what you want printed and in what order
139
my @print_order = ( LUTS, FF, RAMB16, DSP48, MULT_18X18, IOB, DCM,
140
                    DCM_ADV, BUFG );
141
 
142
 
143
 
144
########################################################################
145
my %themodules;
146
my %hierarchical_usageinfo;
147
my %usageinfo;
148
 
149
# This variable controls how many levels we will keep track of
150
my $hierarchical_level = 0;
151
 
152
######################################################################
153
# Add a component to the statistics
154
######################################################################
155
sub add_component {
156
    my $thename = $_[0];
157
    my $thetype = $_[1];
158
 
159
    my @temppath = split("/",$thename);
160
    my @list = ();
161
    my $currname = $temppath[0];
162
    my $i;
163
 
164
    push(@list,$currname);
165
 
166
    for($i = 1; $i < $#temppath; $i = $i  + 1) {
167
        $currname = "$currname/$temppath[$i]";
168
        push(@list,$currname);
169
    }
170
 
171
    for($i = $hierarchical_level; $i < $#temppath; $i = $i + 1) {
172
        $currname = pop(@list);
173
        if($themodules{$currname}) {
174
            $i = $#temppath;
175
        }
176
    }
177
 
178
 
179
    if($thename =~ /\//) {
180
    }else{
181
# If there is no slash in the name => a component of the top level
182
        $currname = "/";
183
    }
184
 
185
    my %thehash;
186
 
187
    $hierarchical_usageinfo{$currname}{$thetype}++;
188
    $usageinfo{$thetype}++;
189
 
190
    $themodules{$currname} = 1;
191
}
192
 
193
######################################################################
194
# Analyze an XDL file and collect statistics about component
195
# usage
196
######################################################################
197
 
198
sub analyze_file {
199
 
200
    print "Analyzing the file $_[0]...";
201
    STDOUT->autoflush(1);
202
 
203
    open THEFILE, '<', $_[0] or die;
204
 
205
    my $line = 0;
206
    while (<THEFILE>){
207
 
208
        # Progress meter
209
        $line++;
210
        if($line == 10000){
211
            $line = 0;
212
            print(".");
213
            STDOUT->autoflush(1);
214
        }
215
 
216
        # Quick and dirty parser that does not keep any state.
217
        # A real parser would remember what kind of instance we are
218
        # currently inside in order to keep track of more things such
219
        # as for example slice usage, etc.
220
 
221
        # Both an F and a G LUT can be on the same line
222
        # So we can't use elseif here.
223
        if(/ F:([a-zA-Z0-9_\/\[\]<>\.]+:\#([A-Z]+):D=)/) {
224
            &add_component($1,LUTS);
225
        }
226
 
227
        if(/ G:([a-zA-Z0-9_\/\[\]<>\.]+:\#([A-Z]+):D=)/) {
228
            &add_component($1,LUTS);
229
        }
230
 
231
 
232
        # Both an FFX and a FFY flip flop can be on the same line
233
        # So we can't use elseif here.
234
        if(/FFX:([a-zA-Z0-9_\/\[\]<>\.]+:\#[A-Z]+)/) {
235
            &add_component($1,FF);
236
        }
237
 
238
        if(/FFY:([a-zA-Z0-9_\/\[\]<>\.]+:\#[A-Z]+)/) {
239
            &add_component($1,FF);
240
        }
241
 
242
        # Check if there is an instance defined on this line
243
        if(/^inst/) {
244
            if(/^inst \"([a-zA-Z0-9_\/\[\]<>\.]+)\" \"IOB\"/){
245
                &add_component($1,IOB);
246
            }elsif(/^inst \"([a-zA-Z0-9_\/\[\]<>\.]+)\" \"RAMB16\"/){
247
                &add_component($1,RAMB16);
248
            }elsif(/^inst \"([a-zA-Z0-9_\/\[\]<>\.]+)\" \"MULT18X18\"/){
249
                &add_component($1,MULT_18X18);
250
            }elsif(/^inst \"([a-zA-Z0-9_\/\[\]<>\.]+)\" \"DSP48\"/){
251
                &add_component($1,DSP48);
252
            }elsif(/^inst \"([a-zA-Z0-9_\/\[\]<>\.]+)\" \"DCM\"/){
253
                # FIXME - Do we need a check for a dummy DCM?
254
                &add_component($1,DCM);
255
            }elsif(/^inst \"([a-zA-Z0-9_\/\[\]<>\.]+)\" \"DCM_ADV\"/){
256
                # Check for unused dummy instantiation of DCM_ADV
257
                if(! /^inst \"XIL_ML_UNUSED_DCM/){
258
                    &add_component($1,DCM_ADV);
259
                }
260
            }elsif(/^inst \"([a-zA-Z0-9_\/\[\]<>\.]+)\" \"BUFG\"/){
261
                &add_component($1,BUFG);
262
            }
263
            # Adding more components here should be easy
264
        }
265
 
266
    }
267
 
268
    print "\n";
269
 
270
}
271
 
272
######################################################################
273
# Print a line consisting of dashes and plus like the marked lines in
274
# the following output:
275
# --> +-------------------+--------+--------+--------+
276
#     | Module            |   LUTS |     FF |    IOB |
277
# --> +-------------------+--------+--------+--------+
278
######################################################################
279
 
280
sub print_dashes {
281
    my $firstlen = $_[0];
282
    my $inst_order = $_[1];
283
    my $insttype;
284
    print "+" . "-" x ($firstlen + 2);
285
    foreach $insttype (@$inst_order) {
286
        my $maxlen = length($translation[$insttype]);
287
        $maxlen = $maxlen < 6 ? 6 : $maxlen;
288
        print "+" . "-" x ($maxlen + 2);
289
    }
290
    printf("+\n");
291
 
292
}
293
 
294
######################################################################
295
# Print statistics collected in the %themodules, %usageinfo, and
296
# %hierarchical_usageinfo hashes.
297
######################################################################
298
 
299
sub print_stats {
300
 
301
    my $firstlen;
302
    my @thekeys = keys %themodules;
303
    @thekeys = sort(@thekeys);
304
    my $i;
305
    my $name;
306
    my $foo;
307
    my @inst_order;
308
 
309
# Find maximum length of the first field
310
    $firstlen = length("Module");
311
    foreach $i (@thekeys) {
312
        if($firstlen < length($i)){
313
            $firstlen = length($i);
314
        }
315
    }
316
 
317
    my $insttype;
318
    my $maxlen;
319
 
320
# Create inst_order so that we only print statistics about components
321
# that are actually used in the design.
322
    foreach $name (@print_order) {
323
        if($usageinfo{$name}) {
324
            push(@inst_order,$name);
325
        }
326
    }
327
 
328
# Print header
329
    &print_dashes($firstlen,\@inst_order);
330
    printf("| %- ${firstlen}s ","Module");
331
    foreach $insttype (@inst_order) {
332
        printf("| % 6s ", $translation[$insttype]);
333
    }
334
    printf("|\n");
335
    &print_dashes($firstlen,\@inst_order);
336
 
337
 
338
# Print hierarchical statistics
339
    foreach $name (@thekeys) {
340
        printf("| %- ${firstlen}s ",$name);
341
        foreach $insttype (@inst_order) {
342
            $maxlen = length($translation[$insttype]);
343
            $maxlen = $maxlen < 6 ? 6 : $maxlen;
344
            if($hierarchical_usageinfo{$name}{$insttype}) {
345
                printf("| % ${maxlen}d ",$hierarchical_usageinfo{$name}{$insttype});
346
            }else {
347
                printf("| % ${maxlen}s "," ");
348
            }
349
        }
350
        printf("|\n");
351
    }
352
 
353
# Print footer with total number of all components
354
    &print_dashes($firstlen,\@inst_order);
355
 
356
    printf("| %- ${firstlen}s ","Total");
357
    foreach $insttype (@inst_order) {
358
        $maxlen = length($translation[$insttype]);
359
        $maxlen = $maxlen < 6 ? 6 : $maxlen;
360
        if($usageinfo{$insttype}){
361
            printf("| % ${maxlen}d ",$usageinfo{$insttype});
362
        }else{
363
            printf("| % ${maxlen}s "," ");
364
        }
365
    }
366
    printf("|\n");
367
 
368
    &print_dashes($firstlen,\@inst_order);
369
}
370
 
371
 
372
######################################################################
373
# Main program starts here
374
######################################################################
375
 
376
printf('XDLAnalyze V1.1 by Andreas Ehliar <ehliar@isy.liu.se>'. "\n");
377
 
378
if(! $ARGV[0]){
379
    print STDERR "Usage: xdlanalyze.pl <design.xdl> [hierarchical levels]\n";
380
    exit 1;
381
}
382
 
383
if($ARGV[1]) {
384
    $hierarchical_level = $ARGV[1];
385
}
386
 
387
# If the input has a .ncd file extension it will be converted to an .xdl file
388
if( $ARGV[0] =~ /.ncd$/ ) {
389
    my $tempname;
390
    my $fh;
391
 
392
    printf("Calling xdl -ncd2xdl to convert .ncd file to .xdl file before running analyzer\n");
393
 
394
    # try new temporary filenames until we get one that didn't already exist as per
395
    # the perl cookbook
396
    do { $tempname = tmpnam() . ".xdl" }
397
        until $fh = IO::File->new($tempname, O_RDWR|O_CREAT|O_EXCL);
398
 
399
    # Call the xdl tool to convert the file...
400
    system ("xdl", "-ncd2xdl", $ARGV[0], $tempname) == 0 or die "Couldn't call xdl: $!";
401
    &analyze_file($tempname);
402
 
403
    unlink($tempname) or die "Couldn't unlink $tempname : $!";
404
 
405
}else {
406
    &analyze_file($ARGV[0]);
407
}
408
 
409
 
410
&print_stats;
411
 
412
exit 0;

powered by: WebSVN 2.1.0

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