#!/usr/local/bin/perl $tagfile = 'tags'; $USAGE = qq{ SYNOPSIS: Generate verilog,vhdl tags for vim. AUTHOR: GPL(C) Mohsin Ahmed, http://www.cs.albany.edu/~mosh USAGE: vtags *.v *.vhd > tags .... Adds verilog and vhdl tags for vim. OPTIONS -v Verbose -o file Output to tagfile (default is tags). -filetags Include filenames in tags EXAMPLES: . vtags *.v *.vhdl rams/*.v . find /libv -name '*.v|*.lib' | xargs vtags . vtags -o tagv *.v *.vhdl rams/*.v USAGE OF TAGS WITH VIM :set tag=tags,../tags "-- in ~/.vimrc file $ vim -t XYZ -- start editing module XYZ, :ta XY[tab] Show all tags matching XY*. :ta XYZ Goto first location of tag XYZ. :tnext Same tag, next location. :tselect XYZ Goto specific (Nth) occurrence of XYZ from a menu. Control-] Goto tag of identifier under cursor. Control-T Come back, pop XYZ off tag stack. NOTES: . Tags are: filenames and /^(module|primitive|'define) (\\w+)/ . We do not handle (backslash quoted) \\names. . Oldname: veri-tags.pl }; while( $_ = $ARGV[0], m/^-/ ){ shift; if( m/^--$/ ){ last; }elsif( m/^-filetags/ ){ $filetags++; }elsif( m/^-[h?]/ ){ die $USAGE; }elsif( m/^-v/ ){ $verbose++; }elsif( m/^-o/ ){ $tagfile = shift || die "-o needs tagfilename\n"; }else{ die "Unknown option '$_'\n"; } } die $USAGE unless @ARGV; my $filetype; # 1->verilog, 2->vhdl. LINE: while(<>){ chomp; unless( $fileseen{$ARGV}++ ){ # New file? my $file = $ARGV; if( $file =~ /\.vh/i ){ $filetype = 1; }elsif( $file =~ /\.v/i ){ $filetype = 2; }else{ warn "Ignoring File '$file' type unknown?\n"; close ARGV; next LINE; } $file =~ s,.*/,,; # push a File name tag. push( @tags, "$file\t$ARGV\t1;\"\tF\n" ) if $filetags; # $file =~ s,[.][^.]*$,,; # push again file name sans ext as tag. # push( @tags, "$file\t$ARGV\t1;\"\tF\n" ); warn "File: $ARGV, tag is $file\n" if $verbose; } if( $filetype == 1 ){ # vhdl s/--.*//; # comments ignored. # if( m/^(entity|architecture|package\s+body)\s+(\w+)/o ){ # warn "$1 $2 in $ARGV\n" if $verbose; # push( @tags, "$2\t$ARGV\t/$_/\n" ); if( m/^(entity|package\s+body)\s+(\w+)/o ){ warn "$1 $2 in $ARGV\n" if $verbose; push( @tags, "$2\t$ARGV\t/$_/\n" ); # tag will have prefix ENTITY_TAGNAME for ease of completion. # push( @tags, "ENTITY_$2\t$ARGV\t/$_/\n" ); }elsif( m/^(architecture)\s+(\w+)\s+of\s+(\w+)\s+is/o ){ warn "$1 $3_$2 in $ARGV\n" if $verbose; # /architecture RTL of SUPP is/ will have tag /SUPP_RTL/ push( @tags, "$3_$2\t$ARGV\t/$_/\n" ); # # /architecture RTL of SUPP is/ will have tag /RTL_SUPP/ # push( @tags, "$2_$3\t$ARGV\t/$_/\n" ); }elsif( m/^\s*(function)\s+\"(\S+?)\".*is/o ){ # eg. function "+" # function .. is, otherwise it is decl, regexp is a hack. warn "$1 $2 in $ARGV\n" if $verbose; push( @tags, "$2\t$ARGV\t/$_/\n" ) }elsif( m/^\s*(function|procedure)\s+(\w+)/o ){ warn "$1 $2 in $ARGV\n" if $verbose; push( @tags, "$2\t$ARGV\t/$_/\n" ) } next LINE; }else{ # verilog $filetype == 2 s,//.*,,; # comments ignored but not /* */ if( m/^(module|primitive|`define)\s+(\w+)/o ){ warn "$1 $2 in $ARGV\n" if $verbose; push( @tags, "$2\t$ARGV\t/$_/\n" ) } next LINE; } } if( $tagfile ){ open( TAGFILE, ">$tagfile") || die "Cannot write file=$tagfile\n"; print TAGFILE sort @tags; close TAGFILE; }else{ print sort @tags; }