1" Language: Verilog HDL 2" Maintainer: Chih-Tsun Huang <[email protected]> 3" Last Change: 2017 Aug 25 by Chih-Tsun Huang 4" URL: http://www.cs.nthu.edu.tw/~cthuang/vim/indent/verilog.vim 5" 6" Credits: 7" Suggestions for improvement, bug reports by 8" Takuya Fujiwara <[email protected]> 9" Thilo Six <[email protected]> 10" Leo Butlero <[email protected]> 11" 12" Buffer Variables: 13" b:verilog_indent_modules : indenting after the declaration 14" of module blocks 15" b:verilog_indent_width : indenting width 16" b:verilog_indent_verbose : verbose to each indenting 17" 18 19" Only load this indent file when no other was loaded. 20if exists("b:did_indent") 21 finish 22endif 23let b:did_indent = 1 24 25setlocal indentexpr=GetVerilogIndent() 26setlocal indentkeys=!^F,o,O,0),=begin,=end,=join,=endcase 27setlocal indentkeys+==endmodule,=endfunction,=endtask,=endspecify 28setlocal indentkeys+==endconfig,=endgenerate,=endprimitive,=endtable 29setlocal indentkeys+==`else,=`elsif,=`endif 30 31" Only define the function once. 32if exists("*GetVerilogIndent") 33 finish 34endif 35 36let s:cpo_save = &cpo 37set cpo&vim 38 39function GetVerilogIndent() 40 41 if exists('b:verilog_indent_width') 42 let offset = b:verilog_indent_width 43 else 44 let offset = shiftwidth() 45 endif 46 if exists('b:verilog_indent_modules') 47 let indent_modules = offset 48 else 49 let indent_modules = 0 50 endif 51 52 " Find a non-blank line above the current line. 53 let lnum = prevnonblank(v:lnum - 1) 54 55 " At the start of the file use zero indent. 56 if lnum == 0 57 return 0 58 endif 59 60 let lnum2 = prevnonblank(lnum - 1) 61 let curr_line = getline(v:lnum) 62 let last_line = getline(lnum) 63 let last_line2 = getline(lnum2) 64 let ind = indent(lnum) 65 let ind2 = indent(lnum - 1) 66 let offset_comment1 = 1 67 " Define the condition of an open statement 68 " Exclude the match of //, /* or */ 69 let vlog_openstat = '\(\<or\>\|\([*/]\)\@<![*(,{><+-/%^&|!=?:]\([*/]\)\@!\)' 70 " Define the condition when the statement ends with a one-line comment 71 let vlog_comment = '\(//.*\|/\*.*\*/\s*\)' 72 if exists('b:verilog_indent_verbose') 73 let vverb_str = 'INDENT VERBOSE:' 74 let vverb = 1 75 else 76 let vverb = 0 77 endif 78 79 " Indent according to last line 80 " End of multiple-line comment 81 if last_line =~ '\*/\s*$' && last_line !~ '/\*.\{-}\*/' 82 let ind = ind - offset_comment1 83 if vverb 84 echo vverb_str "De-indent after a multiple-line comment." 85 endif 86 87 " Indent after if/else/for/case/always/initial/specify/fork blocks 88 " Note: We exclude '`if' or '`else' and consider 'end else' 89 " 'end if' is redundant here 90 elseif last_line =~ '^\s*\(end\)\=\s*`\@<!\<\(if\|else\)\>' || 91 \ last_line =~ '^\s*\<\(for\|case\%[[zx]]\)\>' || 92 \ last_line =~ '^\s*\<\(always\|initial\)\>' || 93 \ last_line =~ '^\s*\<\(specify\|fork\)\>' 94 if last_line !~ '\(;\|\<end\>\)\s*' . vlog_comment . '*$' || 95 \ last_line =~ '\(//\|/\*\).*\(;\|\<end\>\)\s*' . vlog_comment . '*$' 96 let ind = ind + offset 97 if vverb | echo vverb_str "Indent after a block statement." | endif 98 endif 99 " Indent after function/task/config/generate/primitive/table blocks 100 elseif last_line =~ '^\s*\<\(function\|task\|config\|generate\|primitive\|table\)\>' 101 if last_line !~ '\<end\>\s*' . vlog_comment . '*$' || 102 \ last_line =~ '\(//\|/\*\).*\(;\|\<end\>\)\s*' . vlog_comment . '*$' 103 let ind = ind + offset 104 if vverb 105 echo vverb_str "Indent after function/task block statement." 106 endif 107 endif 108 109 " Indent after module/function/task/specify/fork blocks 110 elseif last_line =~ '^\s*\<module\>' 111 let ind = ind + indent_modules 112 if vverb && indent_modules 113 echo vverb_str "Indent after module statement." 114 endif 115 if last_line =~ '[(,]\s*' . vlog_comment . '*$' && 116 \ last_line !~ '\(//\|/\*\).*[(,]\s*' . vlog_comment . '*$' 117 let ind = ind + offset 118 if vverb 119 echo vverb_str "Indent after a multiple-line module statement." 120 endif 121 endif 122 123 " Indent after a 'begin' statement 124 elseif last_line =~ '\(\<begin\>\)\(\s*:\s*\w\+\)*' . vlog_comment . '*$' && 125 \ last_line !~ '\(//\|/\*\).*\(\<begin\>\)' && 126 \ ( last_line2 !~ vlog_openstat . '\s*' . vlog_comment . '*$' || 127 \ last_line2 =~ '^\s*[^=!]\+\s*:\s*' . vlog_comment . '*$' ) 128 let ind = ind + offset 129 if vverb | echo vverb_str "Indent after begin statement." | endif 130 131 " De-indent for the end of one-line block 132 elseif ( last_line !~ '\<begin\>' || 133 \ last_line =~ '\(//\|/\*\).*\<begin\>' ) && 134 \ last_line2 =~ '\<\(`\@<!if\|`\@<!else\|for\|always\|initial\)\>.*' . 135 \ vlog_comment . '*$' && 136 \ last_line2 !~ 137 \ '\(//\|/\*\).*\<\(`\@<!if\|`\@<!else\|for\|always\|initial\)\>' && 138 \ last_line2 !~ vlog_openstat . '\s*' . vlog_comment . '*$' && 139 \ ( last_line2 !~ '\<begin\>' || 140 \ last_line2 =~ '\(//\|/\*\).*\<begin\>' ) 141 let ind = ind - offset 142 if vverb 143 echo vverb_str "De-indent after the end of one-line statement." 144 endif 145 146 " Multiple-line statement (including case statement) 147 " Open statement 148 " Ident the first open line 149 elseif last_line =~ vlog_openstat . '\s*' . vlog_comment . '*$' && 150 \ last_line !~ '\(//\|/\*\).*' . vlog_openstat . '\s*$' && 151 \ last_line2 !~ vlog_openstat . '\s*' . vlog_comment . '*$' 152 let ind = ind + offset 153 if vverb | echo vverb_str "Indent after an open statement." | endif 154 155 " Close statement 156 " De-indent for an optional close parenthesis and a semicolon, and only 157 " if there exists precedent non-whitespace char 158 elseif last_line =~ ')*\s*;\s*' . vlog_comment . '*$' && 159 \ last_line !~ '^\s*)*\s*;\s*' . vlog_comment . '*$' && 160 \ last_line !~ '\(//\|/\*\).*\S)*\s*;\s*' . vlog_comment . '*$' && 161 \ ( last_line2 =~ vlog_openstat . '\s*' . vlog_comment . '*$' && 162 \ last_line2 !~ ';\s*//.*$') && 163 \ last_line2 !~ '^\s*' . vlog_comment . '$' 164 let ind = ind - offset 165 if vverb | echo vverb_str "De-indent after a close statement." | endif 166 167 " `ifdef or `ifndef or `elsif or `else 168 elseif last_line =~ '^\s*`\<\(ifn\?def\|elsif\|else\)\>' 169 let ind = ind + offset 170 if vverb 171 echo vverb_str "Indent after a `ifdef or `ifndef or `elsif or `else statement." 172 endif 173 174 endif 175 176 " Re-indent current line 177 178 " De-indent on the end of the block 179 " join/end/endcase/endfunction/endtask/endspecify 180 if curr_line =~ '^\s*\<\(join\|end\|endcase\)\>' || 181 \ curr_line =~ '^\s*\<\(endfunction\|endtask\|endspecify\)\>' || 182 \ curr_line =~ '^\s*\<\(endconfig\|endgenerate\|endprimitive\|endtable\)\>' 183 let ind = ind - offset 184 if vverb | echo vverb_str "De-indent the end of a block." | endif 185 elseif curr_line =~ '^\s*\<endmodule\>' 186 let ind = ind - indent_modules 187 if vverb && indent_modules 188 echo vverb_str "De-indent the end of a module." 189 endif 190 191 " De-indent on a stand-alone 'begin' 192 elseif curr_line =~ '^\s*\<begin\>' 193 if last_line !~ '^\s*\<\(function\|task\|specify\|module\|config\|generate\|primitive\|table\)\>' && 194 \ last_line !~ '^\s*\()*\s*;\|)\+\)\s*' . vlog_comment . '*$' && 195 \ ( last_line =~ 196 \ '\<\(`\@<!if\|`\@<!else\|for\|case\%[[zx]]\|always\|initial\)\>' || 197 \ last_line =~ ')\s*' . vlog_comment . '*$' || 198 \ last_line =~ vlog_openstat . '\s*' . vlog_comment . '*$' ) 199 let ind = ind - offset 200 if vverb 201 echo vverb_str "De-indent a stand alone begin statement." 202 endif 203 endif 204 205 " De-indent after the end of multiple-line statement 206 elseif curr_line =~ '^\s*)' && 207 \ ( last_line =~ vlog_openstat . '\s*' . vlog_comment . '*$' || 208 \ last_line !~ vlog_openstat . '\s*' . vlog_comment . '*$' && 209 \ last_line2 =~ vlog_openstat . '\s*' . vlog_comment . '*$' ) 210 let ind = ind - offset 211 if vverb 212 echo vverb_str "De-indent the end of a multiple statement." 213 endif 214 215 " De-indent `elsif or `else or `endif 216 elseif curr_line =~ '^\s*`\<\(elsif\|else\|endif\)\>' 217 let ind = ind - offset 218 if vverb | echo vverb_str "De-indent `elsif or `else or `endif statement." | endif 219 220 endif 221 222 " Return the indentation 223 return ind 224endfunction 225 226let &cpo = s:cpo_save 227unlet s:cpo_save 228 229" vim:sw=2 230