#!/usr/bin/perl -w # DCBUILD - this perl script parses a module hierarchy and builds a read-script, # and a hierarchial file listing. # By Jeff Winston http://www.kwcpa.com/tools # Rev. 1.0, 11/15/02 Copyright (C) 2002 # # --------------------------------------------------------------------- # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, # USA. or check out http://www.gnu.org/copyleft/gpl.html # --------------------------------------------------------------------- use File::Basename; use Getopt::Long; use Pod::Text; use IO::Handle; #---------------------------------------------------------------------- # main # User must specify Design Compiler location, name of global define file, and ignore list $global_name = " "; @ignore_list = ( ) ; $report = 0; $arg_exist = 0; $result = &GetOptions ( "help" => \&usage, "report" => \&report, "<>" => \¶meter, ); if (! $result || !$arg_exist) { &usage(); } exit (0); #---------------------------------------------------------------------- sub report { $report = 1; } sub usage { $SIG{__WARN__} = sub{}; #pod2text isn't clean. pod2text($0); #help text at bottom of file exit (1); } #set parameters sub parameter { # the main routine starts here $arg_exist = 1; my $cmdline = shift; chomp($cmdline); STDOUT->autoflush(1); print "Running dc_shell\n"; # open hierarchy file $hfile = $cmdline . "_hier.txt"; `rm -f $hfile`; open (HFIL, "> $hfile") or die "cannot open $hfile"; # initi globals $maxlevel = 0; %names = (); # start recursive call process process_synopsys_output($cmdline,0); # output build script my $scrname = "read_" . $cmdline . ".scr"; open (OUTFIL, "> $scrname") or die "cannot open $scrname"; print "Writing $scrname ..."; for ($x = $maxlevel; $x >= 0 ; $x=$x-1) { while (($key,$value) = each(%names)) { if ($value == $x) { $fname = $key . ".v"; print OUTFIL "read -f verilog \{$global_name $fname\}\n"; } } } $fname = $cmdline . ".v"; print OUTFIL "read -f verilog \{$global_name $fname\}\n"; close (OUTFIL); print "Done\n"; exit(0); } sub process_synopsys_output { my ($startmod,$level) = @_; my $modfilename = $startmod . ".v"; # create filename from modulename # do we ignore this module? $ignoreit = 0; foreach $ignorename (@ignore_list) { if ($startmod =~ m/$ignorename/) { $ignoreit = 1; } } #if so... if ($ignoreit == 1) { print "Skipping dc_shell for "; for ($x=0; $x<$level;$x++) { print " ";} print "$startmod\n"; printf HFIL ("%3d | ", $level+1); for ($x=0; $x<$level;$x++) { print HFIL " ";} print HFIL "$startmod\n"; } else # otherwise { # create script for design compiler to run my $tmpfile = "tmp.tmp1"; # temporary output filename `rm -f $tmpfile`; open (OUTFIL, "> $tmpfile") or die "cannot open $tmpfile"; print OUTFIL "read -f verilog {$global_name $modfilename}\n"; print OUTFIL "report_reference\n"; print OUTFIL "quit\n"; close (OUTFIL); # pretty output to screen print "Calling dc_shell for "; for ($x=0; $x<$level;$x++) { print " ";} print "$startmod..."; # and to hierarchy file printf HFIL ("%3d | ", $level+1); for ($x=0; $x<$level;$x++) { print HFIL " ";} print HFIL "$startmod\n"; # actually call Design Compiler my @dc_output = `dc_shell < tmp.tmp1`; print "done"; `rm -f $tmpfile`; # open report file for errors if ($report==1) { $rptfile = $startmod . ".rpt"; `rm -f $rptfile`; open (RPTFIL, "> $rptfile") or die "cannot open $rptfile"; } # parse DC output my $progress = 0; foreach my $line (@dc_output) { if (($progress ==0) && (substr($line,0,15) =~ "Initializing...")) { $progress++; } elsif ($progress ==1) { if (substr($line,0,18) =~ "Report : reference") { $progress++; if ($report==1) { printf ", wrote %s\n",$rptfile; close(RPTFIL); } else {print "\n";} } elsif ($report == 1) { print RPTFIL $line; } if ((substr($line,0,6) =~ "Error:") || (substr($line,0,20) =~ "No designs were read")) { if (!($line =~ "was not identified as a synthetic library module")) { printf("DCERROR: %s",$line); } } } elsif (($progress ==2) && (substr($line,0,9) =~ "Reference")) { $progress++; } elsif (($progress >2) && (substr($line,0,10) =~ "----------")) { $progress++; } elsif ($progress == 4) # process report_reference output { my @words = split ' ',$line; my $modname = $words[0]; if ((!(substr($modname,0,1) =~ '\*')) && (!($modname =~ m/0.00/)) && (!($modname =~ m/GTECH/))) { # remove _param_X from end of modulename my @pieces = split '_', $modname; if (@pieces > 2) { my @foo = splice @pieces, -2; if ($foo[0] eq 'param') { $modname = join '_', @pieces; } } # enter in master list if not already there $oldlevel = -1; if ($names{$modname}) { $oldlevel = $names{$modname}; } if ($level > $oldlevel) { $names{$modname} = $level; } # call next level if ($level > $maxlevel) { $maxlevel = $level; } $level++; process_synopsys_output($modname,$level); $level--; } } } } } ####################################################################### __END__ =pod =head1 NAME dcbuild V1.0 - traverse a module hierarchy and create a hierarchy listing, and a read script for synopsys =head1 SYNOPSIS C [--help] [--report] =head1 DESCRIPTION DCBUILD V1.0 uses the Design Compiler report_reference command to traverse a module hierarchy and create 1) a bottom-up read script for Design Compiler 2) a listing of the module hierarchy by module name It requires: 1) All rtl directories to be in your synopsys search path. 2) Filenames and module names match. At the top of the script, the user must code: 1) location of Design Compiler 2) (optionally) The name of a global defines file which is read with every file. This file is prepended to each file as it is read in to dc_shell. 3) (optionally) A list of text strings - all module names containing these text strings are ignored. =head1 ARGUMENTS =over 4 =item --help Displays this message and exits. =item --report By default this script reports to the command line any errors it finds in a file when running it through dc. Enabling --report causes the script to write all output from dc to a file .rpt =back =head1 AUTHORS Jeff Winston http://www.kwcpa.com/tools =cut ######################################################################