#!/usr/bin/perl -w ############################################################################### # # Make a makefile for synthesis # Usage: # synth_make.pl [+incdir+DIR] [-y LIBDIR] [+libext+LIBEXT] verilog_files... # # This is an example of using rvp (rough verilog parser), it isn't mean to # be used for doing real synthesis! # # As usual there is no warranty! # # Costas # # $Header: /home/cc/v2html/rvp_scripts/RCS/synth_make.pl,v 1.4 2005/12/20 15:51:28 cc Exp $ ############################################################################### require rvp; #use strict; use vars qw($debug @files @inc_dirs @lib_dirs $lib_ext $vdb @hier_tops @db_files $m $f %global_done ); # defaults $debug=0; @inc_dirs=('.'); @lib_dirs=(); $lib_ext=''; # process args while ($_ = $ARGV[0]) { shift(@ARGV); if ( /^-y$/ ) { &usage("$_ needs an arguement") if ($#ARGV < 0); push(@lib_dirs,shift(@ARGV)); next; } elsif ( /^\+incdir\+(.+)$/ ) { push(@inc_dirs,$1); next; } elsif ( /^\+libext\+(.+)$/ ) { $lib_ext=$1; next; } else { ($f=$_) =~ s|^.*/||; push(@files,$_); } } die "Usage $0 [+incdir+DIR] [-y LIBDIR] [+libext+LIBEXT] verilog_files..." unless @files; print "# This makefile was automatically generated by $0\n"; print "\n"; # pass in: list of files on command line # empty list of global includes [] # empty hash of predefined defines {} # and set quiet to be quiet (1) # then incdirs, libdirs, libext $vdb = rvp->read_verilog(\@files,[],{},1,\@inc_dirs,\@lib_dirs,$lib_ext); my @problems = $vdb->get_problems(); if (@problems) { foreach my $problem ($vdb->get_problems()) { print STDERR "$problem.\n"; } # die "Warnings parsing files!"; } print "# Source files scanned:\n"; print "# ".join("\n# ",$vdb->get_files()) . "\n\n"; # find modules at the top of the hierarchy foreach $m (sort $vdb->get_modules()) { print " checking if module $m is a top\n" if $debug; if (! $vdb->get_first_instantiator($m)) { print " it is!\n" if $debug; push(@hier_tops,$m); } } # first target is all modules at top of hierarchy print "all:"; foreach $m (@hier_tops) { print " $m.db"; } print "\n\n"; # now do all the dependencies working down the hierarchy foreach $m (@hier_tops) { do_deps($vdb,$m); } # Print a list of DB files and the clean rule print "DB_FILES=".join(" ",@db_files)."\n\n"; print "clean:\n"; print "\trm -f ".'${DB_FILES} ${DB_FILES:db=synlog}'."\n\n"; exit 0; ################################################################################# # # Subroutines sub do_deps { my ($vdb,$m) = @_; my ($f,@clocks,$sig,$s_line,$s_a_line,$s_i_line,$s_type,$s_file,$s_posedge,$s_negedge, $inc,%done,@instances,$imod,$mf,$iname,$l,$ff, $file_list,$clks,@submods,%inc_done,@traverse,$mm); ($f) = $vdb->get_modules_file($m); if (! $f) { print "Warning: Couldn't find file for module $m\n"; return; } # find clocks @clocks = (); foreach $sig ($vdb->get_modules_signals($m)) { if (($s_line,$s_a_line,$s_i_line,$s_type,$s_file,$s_posedge,$s_negedge) = $vdb->get_module_signal($m,$sig)) { print "Checking $sig for clockiness ($s_posedge $s_negedge)\n" if $debug; push (@clocks, $sig ) if ($s_posedge); print STDERR "Warning: can't handle negedge clocks\n" if ($s_negedge); } } # Print out the clocks you could probabbly do something cleverer if (@clocks) { print "# Clocks in this module: @clocks\n"; } # print the target name print "$m.db: "; # print the dependencies # print the source file's full name print "" . $vdb->get_files_full_name($f); # print a list of all the included files foreach $inc ($vdb->get_files_includes($f)) { if (!exists($inc_done{$inc})) { print " " . $vdb->get_files_full_name($inc); $inc_done{$inc}=1; } } # add this db file to the list for cleaning push(@db_files,"$m.db"); undef(%done); @instances = (); @submods = (); # do a list of .db files it depends on # go through all of the things this modules instantiates for (($imod,$mf,$iname,$l) = $vdb->get_first_instantiation($m ); $imod; ($imod,$mf,$iname,$l) = $vdb->get_next_instantiation()) { push(@instances,$iname); # Only print the dependency once for each submodule if (!exists($done{$imod})) { $done{$imod} = $iname; print " $imod.db"; } # only push this onto the submods list if it # hasn't already been done before (anywhere) if (!exists($global_done{$imod})) { $global_done{$imod}=1; push(@submods,$imod); } } print "\n"; # now print out the command to run, just assume there's a script for # each module called module.scr print "\tdc_shell -f $m.scr > $m.synlog\n"; print "\n"; # now do all the submodules foreach $imod (sort @submods) { do_deps($vdb,$imod); } }