Monday, May 17, 2010
verilog/sv indent
1 #!/usr/bin/perl
2 # Author; Lifeng Chen, Magnum Semiconductor
3 # Purpose: Indent verilog/systemverilog file
4
5 use Term::ANSIColor;
6
7 # Flow Control
8 my $debug_me = 1;
9
10 ##TODO
11 # 1. better indent for block-comment
12
13 # Space for each indent
14 my $Space = " ";
15
16 # comment definition.
17 my $sl_delm = qw(// );
18 my %block_delm = (
19 '{' => '}',
20 '(' => ')'
21 );
22
23 # Note: Each Open keyword must have corresponding close keyword
24 my @OpenSingle = qw{repeat for while if else};
25 my @CloseSingle = qw{; };
26
27 my @OpenKeywords = qw{ begin module program package class task function fork case casex casez}; #interface
28 my @CloseKeywords = qw{ end endmodule endprogram endpackage endclass endtask endfunction join join_none join_any endcase}; #endinterface
29 my @IgnoreKeywords = qw{ extern typedef disable};
30
31 my @OpenSpecial = qw{ovm_field_utils_begin ovm_object_utils_begin ovm_object_param_utils_begin ovm_component_utils_begin};
32 my @CloseSpecial = qw{ovm_field_utils_end ovm_object_utils_end ovm_object_param_utils_end ovm_component_utils_end};
33
34 @OpenKeywords = (@OpenKeywords, @OpenSpecial);
35 @CloseKeywords = (@CloseKeywords, @CloseSpecial);
36
37 sub indent {
38 my $open_block_comment=0, $close_block_comment=0, $in_block_comment=0;
39 my $total_indent = 0, $block_indent = 0, $single_indent = 0, $last_indent=0;
40 my($infile) = @_;
41 my $tmpfile= "$infile.tmp";
42 my $open_num=0, $close_num=0, $bracket_delta=0;
43 my $cleaned_line;
44
45 print colored ['green'],"$infile\n";
46 system("cp $infile $tmpfile");
47
48 open(TFILE, ">$tmpfile");
49 open(FILE, "<$infile");
50
51 LINE_LOOP: while(my $line = <FILE>) {
52 chomp $line;
53 if ($open_block_comment==1 and $close_block_comment==0) {$in_block_comment = 1;}
54 else {$in_block_comment = 0;}
55 $line =~ s{$sl_delm(\w|\*)}{$sl_delm $1}; #remove false block-comment; append space after single-line comment symbol immediately followed by letters etc
56 $cleaned_line=$line;
57
58 if ($cleaned_line =~ m{/\*}) {
59 $open_block_comment=1; #start a block comment
60 }
61 if ($cleaned_line =~ m{\*/}) {
62 $close_block_comment=1; #end a block comment
63 }
64 if ($close_block_comment == 1) { #clear block comment flag
65 $open_block_comment=0;
66 $close_block_comment=0;
67 }
68 #if ($in_block_comment) {$cleaned_line =~ s{^.*\*/}{*/};} #remove anything in block comment, till end-block symbol is detected
69 $cleaned_line=~s{"[^"]*"}{}g; #remove keyword in string
70 $cleaned_line =~ s{/\*.*\*/}{}g; #remove keyword in a single-line block comment
71 $cleaned_line =~ s{^.*\*/}{}; #remove keyword in block comment
72 $cleaned_line =~ s{/\*.*$}{}; #remove keyword in block comment
73 $cleaned_line=~ s{$sl_delm.*$}{}; #remove keyword in line comment
74 $cleaned_line =~ s{\s+$}{}; #remove tailing blanks
75 #if ($debug_me == 1 and $. >= 577 and $. <= 585) {
76 #print "debug_me: $., blk_ind: $block_indent, sgl_ind: $single_indent, comment=$in_block_comment: '$cleaned_line'\n";
77 #}
78 if ($in_block_comment==1) {
79 print TFILE "$line\n"; #keep things as they were in a block comment
80 next LINE_LOOP;
81 }
82 $line =~ s/^\s+//; #remove leading space to prepare for indent
83 $line =~ s/\s+$//; #remove any tailing space
84
85 #output the active line
86 if ($line =~ m{^$sl_delm}) { #indent single-line comment
87 for($i=0;$i<$block_indent+$single_indent;$i++) { print TFILE $Space; }
88 print TFILE "$line\n";
89 next LINE_LOOP;
90 }
91
92 foreach $CloseKey (@CloseKeywords) {
93 if($cleaned_line =~ /\b$CloseKey\b/) { $block_indent--; $single_indent=0;}
94 }
95 $bracket_delta=0;
96 foreach $open (keys %block_delm) { #indent brackets
97 $close=$block_delm{"$open"};
98 $open_num = ($cleaned_line =~ s/\Q$open\E/$open/isg);
99 $close_num = ($cleaned_line =~ s/\Q$close\E/$close/isg);
100 $bracket_delta+=$open_num-$close_num;
101 }
102 if ($cleaned_line =~ /\S/) {for($i=0;$i<$block_indent+$single_indent;$i++) { print TFILE $Space; }} #don't indent empty line
103 print TFILE "$line\n";
104 $start_block_line=0;
105 OPEN_BLOCK: foreach $OpenKey (@OpenKeywords) {
106 foreach $IgnoreKey (@IgnoreKeywords) {
107 if($cleaned_line =~ /\b$IgnoreKey\b/) { last OPEN_BLOCK;}
108 }
109 if($cleaned_line =~ /\b$OpenKey\b/) { $block_indent++; $start_block_line=1; }
110 }
111 if ($start_block_line == 0) {
112 OPEN_SINGLE: foreach $OpenKey (@OpenSingle) {
113 if($cleaned_line =~ /\b$OpenKey\b/ and $cleaned_line !~ /`$OpenKey\b/ ) {
114 $single_indent++;
115 }
116 }
117 if ($single_indent > 0) {
118 CLOSE_SINGLE: foreach $CloseKey (@CloseSingle) {
119 if($cleaned_line =~ /$CloseKey$/) {
120 $single_indent=0;
121 }
122 }
123 }
124 }
125 $block_indent+=$bracket_delta;
126 #if ($bracket_delta<0) {$block_indent+=$bracket_delta; }
127 #if ($bracket_delta>0) {$block_indent+=$bracket_delta; }
128 if ($block_indent < 0) {print colored ['yellow'],"\tindent_num = $block_indent @ cleaned_line $.. will be reset.\n"; $block_indent=0;}
129 $last_indent=$block_indent;
130 }
131 $total_indent=$block_indent + $single_indent;
132 if ($total_indent != 0) {print colored ['yellow'],"\tThe indentation of final line is not cleared to zero: $block_indent + $single_indent\n";}
133 close FILE; close TFILE;
134 system("mv -f $tmpfile $infile");
135 }
136
137 my $argnum;
138 if($ARGV[0] eq "" or $ARGV[0] =~ /-h/) {
139 print "Usage : $0 verilogfile.v\n";
140 print " $0 *.sv\n";
141 print " $0 *.*v*\n";
142 print "Help :\n";
143 print " $0\n";
144 exit(0);
145 }
146 print "Indenting...\n";
147 foreach $argnum (0 .. $#ARGV) {
148 my $ifile = $ARGV[$argnum];
149 &indent($ifile);
150 }
>
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment