#!/usr/bin/perl -w # By Jeff Winston http://www.kwcpa.com/tools # Rev. 1.0 3/30/09 Copyright (C) 2009 # # MODSPLIT splits verilog modules into files with a single module per file # and the a filename that matches the module name # # Type modsplit.pl (no arguments) for more information # # --------------------------------------------------------------------- # 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 # --------------------------------------------------------------------- $| = 1; # enable autoflush # parse command line if (($#ARGV != 1) && ($#ARGV != 2)) { print_help(); exit(0); } $input_filename = shift @ARGV; $output_folder = shift @ARGV; #optional header file @header =(); if ($#ARGV != -1) { $header_filename = shift @ARGV; if (!(-e $header_filename)) { print "Error: No such file $header_filename\n"; exit(1); } @header = `cat $header_filename`; } #inits @inter_mod_lines=(); $write=0; $open=0; #open and parse input file open(INFIL, "< $input_filename") or die "Could not open $input_filename"; while(defined($line = )) { chomp $line; $#words = -1; if (length($line)>5) { @words = split " ",$line; } # module keyword starts module if (($#words > -1) && ($words[0] eq "module")) { if ($write == 1) { print "Error: Module definition found within module on line: $line\n"; exit(1); } $write = 1; @words = split " ",$line; $filename = $output_folder . "/" . $words[1] . ".v"; if ($open == 1) { close (OUTFIL); } open (OUTFIL, "> $filename") or die "Error: Could not open $filename...exiting"; $open=1; print "Opening $filename..."; # print intermod lines if any dump_inter_mod_lines(); # copy header if ($#header > -1) { foreach $line (@header) { print OUTFIL $line; } } # print first line of module print OUTFIL "$line\n"; } # endmodule keyword ends module elsif (($#words > -1) && ($words[0] eq "endmodule")) { if ($write == 0) { print "Error: Extra endmodule found outside of module on line: $line\n"; exit(1); } $write = 0; print OUTFIL "$line\n"; print "written\n"; } # otherwise if in module just print line elsif ($write == 1) { print OUTFIL "$line\n"; } #otherwise - collect intermodule lines else { if (length($line) > 0) { push @inter_mod_lines, $line; # dump at endif if ($line =~ "\`endif") { if ($open == 1) { dump_inter_mod_lines(); } } } } } # dump at end if ($open == 1) { dump_inter_mod_lines(); close (OUTFIL); } exit(0); sub dump_inter_mod_lines { foreach $line (@inter_mod_lines) { print OUTFIL "$line\n"; } @inter_mod_lines=(); } sub print_help { print "\nUsage: modsplit.pl [
] \n"; print "Where the optional
is a header which can be attached to the top of every file.\n\n"; print "Modsplit will take any verilog file and parse for module definitions. It will write each module\n"; print "into an output file having the same name as the module. It tries to be smart about lines that are\n"; print "outside module definitions. Typically, it prepends them to the next module. However, if it\n"; print "encounters an `endif, the lines before the `endif will stay with the prior module.\n\n"; }