From 1611aecc49809adda594d21e21cb9457db1bdf5e Mon Sep 17 00:00:00 2001 From: wsdjeg Date: Fri, 15 Apr 2022 20:36:45 +0800 Subject: [PATCH] feat(verilog): add `lang#verilog` layer --- autoload/SpaceVim/layers/lang/verilog.vim | 35 + bundle/README.md | 1 + bundle/verilog/.gitattributes | 2 + bundle/verilog/.gitignore | 13 + bundle/verilog/.travis.yml | 14 + bundle/verilog/Makefile | 63 + bundle/verilog/README.md | 260 ++++ bundle/verilog/autoload/verilog.vim | 746 ++++++++++++ bundle/verilog/compiler/cver.vim | 31 + bundle/verilog/compiler/iverilog.vim | 25 + bundle/verilog/compiler/leda.vim | 25 + bundle/verilog/compiler/msim.vim | 30 + bundle/verilog/compiler/ncverilog.vim | 34 + bundle/verilog/compiler/spyglass.vim | 32 + bundle/verilog/compiler/vcs.vim | 45 + bundle/verilog/compiler/verilator.vim | 32 + bundle/verilog/compiler/verilog_common.vim | 40 + bundle/verilog/doc/verilog_systemverilog.txt | 765 ++++++++++++ bundle/verilog/ftdetect/verilog.vim | 4 + bundle/verilog/ftplugin/verilog.vim | 79 ++ bundle/verilog/indent/verilog.vim | 451 +++++++ bundle/verilog/plugin/verilog.vim | 215 ++++ .../verilog/syntax/verilog_systemverilog.vim | 404 ++++++ bundle/verilog/test/errorformat.txt | 38 + bundle/verilog/test/folding.v | 294 +++++ bundle/verilog/test/folding.v.html | 298 +++++ bundle/verilog/test/functions.vim | 234 ++++ bundle/verilog/test/indent.sv | 1077 ++++++++++++++++ bundle/verilog/test/indent.sv.html | 1081 +++++++++++++++++ bundle/verilog/test/mod.sv | 52 + bundle/verilog/test/run_test.vim | 180 +++ bundle/verilog/test/syntax.sv | 393 ++++++ bundle/verilog/test/syntax.sv.html | 397 ++++++ bundle/verilog/test/test.v | 77 ++ bundle/verilog/test/test_vimrc | 5 + doc/SpaceVim.txt | 53 +- docs/cn/layers/lang/verilog.md | 28 + docs/layers/lang/verilog.md | 27 + 38 files changed, 7559 insertions(+), 21 deletions(-) create mode 100644 autoload/SpaceVim/layers/lang/verilog.vim create mode 100644 bundle/verilog/.gitattributes create mode 100644 bundle/verilog/.gitignore create mode 100644 bundle/verilog/.travis.yml create mode 100644 bundle/verilog/Makefile create mode 100644 bundle/verilog/README.md create mode 100644 bundle/verilog/autoload/verilog.vim create mode 100644 bundle/verilog/compiler/cver.vim create mode 100644 bundle/verilog/compiler/iverilog.vim create mode 100644 bundle/verilog/compiler/leda.vim create mode 100644 bundle/verilog/compiler/msim.vim create mode 100644 bundle/verilog/compiler/ncverilog.vim create mode 100644 bundle/verilog/compiler/spyglass.vim create mode 100644 bundle/verilog/compiler/vcs.vim create mode 100644 bundle/verilog/compiler/verilator.vim create mode 100644 bundle/verilog/compiler/verilog_common.vim create mode 100644 bundle/verilog/doc/verilog_systemverilog.txt create mode 100644 bundle/verilog/ftdetect/verilog.vim create mode 100644 bundle/verilog/ftplugin/verilog.vim create mode 100644 bundle/verilog/indent/verilog.vim create mode 100644 bundle/verilog/plugin/verilog.vim create mode 100644 bundle/verilog/syntax/verilog_systemverilog.vim create mode 100644 bundle/verilog/test/errorformat.txt create mode 100644 bundle/verilog/test/folding.v create mode 100644 bundle/verilog/test/folding.v.html create mode 100644 bundle/verilog/test/functions.vim create mode 100644 bundle/verilog/test/indent.sv create mode 100644 bundle/verilog/test/indent.sv.html create mode 100644 bundle/verilog/test/mod.sv create mode 100644 bundle/verilog/test/run_test.vim create mode 100644 bundle/verilog/test/syntax.sv create mode 100644 bundle/verilog/test/syntax.sv.html create mode 100644 bundle/verilog/test/test.v create mode 100644 bundle/verilog/test/test_vimrc create mode 100644 docs/cn/layers/lang/verilog.md create mode 100644 docs/layers/lang/verilog.md diff --git a/autoload/SpaceVim/layers/lang/verilog.vim b/autoload/SpaceVim/layers/lang/verilog.vim new file mode 100644 index 000000000..bc4e0ad2d --- /dev/null +++ b/autoload/SpaceVim/layers/lang/verilog.vim @@ -0,0 +1,35 @@ +"============================================================================= +" verilog.vim --- Verilog/SystemVerilog support +" Copyright (c) 2016-2019 Wang Shidong & Contributors +" Author: Wang Shidong < wsdjeg@outlook.com > +" URL: https://spacevim.org +" License: GPLv3 +"============================================================================= + +"" +" @section lang#verilog, layers-lang-verilog +" @parentsection layers +" This layer is for verilog development, disabled by default, to enable this +" layer, add following snippet to your SpaceVim configuration file. +" > +" [[layers]] +" name = 'lang#verilog' +" < + +function! SpaceVim#layers#lang#verilog#plugins() abort + let plugins = [] + call add(plugins, [g:_spacevim_root_dir . 'bundle/verilog', {'merged' : 0}]) + return plugins +endfunction + + +function! SpaceVim#layers#lang#verilog#config() abort + +endfunction + + +function! SpaceVim#layers#lang#verilog#health() abort + call SpaceVim#layers#lang#verilog#plugins() + call SpaceVim#layers#lang#verilog#config() + return 1 +endfunction diff --git a/bundle/README.md b/bundle/README.md index 45ba8394e..771d5c8e3 100644 --- a/bundle/README.md +++ b/bundle/README.md @@ -11,6 +11,7 @@ In `bundle/` directory, there are two kinds of plugins: forked plugins without c - `github-issues.vim`: based on [github-issues.vim](https://github.com/jaxbot/github-issues.vim/tree/46f1922d3d225ed659f3dda1c95e35001c9f41f4) - `vim-virtualenv`: based on [vim-virtualenv](https://github.com/jmcantrell/vim-virtualenv/tree/b1150223cd876f155ed7a3b2e285ed33f6f93873) - `clever-f.vim`: based on [`clever-f.vim@fd370f2`](https://github.com/rhysd/clever-f.vim/tree/fd370f27cca93918184a8043220cef1aa440a1fd) +- `verilog`: based on [`vhda/verilog_systemverilog.vim@0b88f2c`](https://github.com/vhda/verilog_systemverilog.vim/tree/0b88f2ccf81983944bf00d15ec810dd807053d19) ### No changed plugins diff --git a/bundle/verilog/.gitattributes b/bundle/verilog/.gitattributes new file mode 100644 index 000000000..2a2032449 --- /dev/null +++ b/bundle/verilog/.gitattributes @@ -0,0 +1,2 @@ +# Hide test folder from language stats on GitHub +test/* linguist-vendored diff --git a/bundle/verilog/.gitignore b/bundle/verilog/.gitignore new file mode 100644 index 000000000..185755e95 --- /dev/null +++ b/bundle/verilog/.gitignore @@ -0,0 +1,13 @@ +test-efm.log +test-syntax.log +test/syntax.sv.all.html +test/syntax.sv.all_block_named.html +test/syntax.sv.all_block_nested.html +test/syntax.sv.all_instance.html +test/syntax.sv.default.html +test/folding.v.all.html +test/folding.v.all_block_named.html +test/folding.v.all_block_nested.html +test/folding.v.all_instance.html +test/folding.v.default.html + diff --git a/bundle/verilog/.travis.yml b/bundle/verilog/.travis.yml new file mode 100644 index 000000000..430688244 --- /dev/null +++ b/bundle/verilog/.travis.yml @@ -0,0 +1,14 @@ +language: c + +sudo: false + +os: + - linux + +script: + - make all + +after_failure: + - cat test-efm.log + - cat test-syntax.log + - cat test/syntax.sv.new.html diff --git a/bundle/verilog/Makefile b/bundle/verilog/Makefile new file mode 100644 index 000000000..5d834b0f2 --- /dev/null +++ b/bundle/verilog/Makefile @@ -0,0 +1,63 @@ +V ?= 0 + +SILENT = $(SILENT_$(V)) +SILENT_0 = @ +SILENT_1 = + +SHELL = /bin/bash -o pipefail +VIM = vim -u test/test_vimrc -U none -T dumb -E --cmd "set runtimepath+=${PWD}" + +.PHONY: help test test-fold test-indent test-efm + +all: test + +test: test-fold test-indent test-efm test-syntax + +test-fold: + $(SILENT) $(VIM) \ + -c 'source test/functions.vim' \ + -c 'source test/run_test.vim' \ + -c 'call RunTestFold()' + +test-indent: + $(SILENT) $(VIM) \ + -c 'source test/functions.vim' \ + -c 'source test/run_test.vim' \ + -c 'call RunTestIndent()' + +test-efm: + $(SILENT) $(VIM) \ + -c 'source test/functions.vim' \ + -c 'source test/run_test.vim' \ + -c 'call RunTestEfm()' | \ + tee test-efm.log | grep "^Error format test" + +test-syntax: + $(SILENT) $(VIM) \ + -c 'source test/functions.vim' \ + -c 'source test/run_test.vim' \ + -c 'call RunTestSyntax()' | tr -d '[]' | \ + tee test-syntax.log | grep "^Syntax test" + +performance: + $(SILENT) time $(VIM) \ + --cmd 'silent edit test/indent.sv' \ + --cmd 'normal! gg=G' \ + --cmd 'quit!' + +profile: + $(SILENT) $(VIM) \ + --cmd 'profile start verilog_profile.result' \ + --cmd 'profile! file indent/verilog_systemverilog.vim' \ + -c 'source test/functions.vim' \ + -c 'source test/run_test.vim' + +help: + @echo "Test targets:" + @echo "" + @echo "make test - Run addon tests" + @echo "make performance - Measure performance" + @echo "make profile - Measure performance using vims built in profiler" + @echo + @echo "Options:" + @echo "V=1 - Enable verbose mode" diff --git a/bundle/verilog/README.md b/bundle/verilog/README.md new file mode 100644 index 000000000..a245ff7cb --- /dev/null +++ b/bundle/verilog/README.md @@ -0,0 +1,260 @@ +# Vim Syntax Plugin for Verilog and SystemVerilog + +[![Build Status](https://travis-ci.org/vhda/verilog_systemverilog.vim.svg?branch=master)](https://travis-ci.org/vhda/verilog_systemverilog.vim) + +## About + +Based on script originally found at: + +http://www.vim.org/scripts/script.php?script_id=1586 + +[comment]: "_ stop highlighting the underscore from the link above" + +## IMPORTANT NOTICE + +Version 3.0 reviews the configuration variables used in this plugin. As +such, take into account that the following variables were deprecated and +are no longer supported: + +* `b:verilog_indent_modules` +* `b:verilog_indent_preproc` +* `g:verilog_dont_deindent_eos` + +The following variables were renamed: + +* `g:verilog_disable_indent` -> `g:verilog_disable_indent_lst` +* `g:verilog_syntax_fold` -> `g:verilog_syntax_fold_lst` + +Most configuration variables now also support buffer local variables, +allowing exceptions to the default configuration through the use of +`autocmd`. + +## Features + +Besides some bug corrections, the following features were added to this set of scripts: + +* Omni completion. +* Configurable syntax folding. +* Matchit settings to support Verilog 2001 and SystemVerilog. +* Error format definitions for common Verilog tools. +* Commands for code navigation. + +### Omni Completion + +This plugin implements an omni completion function that will offer completion +suggestions depending on the current context. This will only work if a `.` +character is found in the keyword behind the cursor. At the moment the following +contexts are supported: + +1. Module instantiation port names. +2. Function/task arguments. +3. Object methods and attributes. + +In order to use omni completion a tags file must be generated using the +following arguments: + +* `--extra=+q` - Enable hierarchy qualified tags extraction. +* `--fields=+i` - Enable class inheritance extraction. +* `-n` - (Optional) Use line number instead of Ex: patterns to identify + declaration. + +No tool alternative to [universal-ctags][e] was tested, but any tool should work +seemingly as long as it is able to generate a standard class qualified tags file. +For more information on using omni completion please check the vim man page for +[`i_CTRL-X_CTRL-O`][vim-omni] (the required option [`omnifunc`][vim-omnifunc] is +automatically defined for the supported file extensions). + +[comment]: "TODO Explain how gd works" + +__Note__: Proper SystemVerilog tag generation requires development version of +[universal-ctags][c]. + +### Syntax folding + +To enable syntax folding set the following option: + +```VimL +set foldmethod=syntax +``` + +### Verilog Compilation and Error format + +This plugin includes the [errorformat][vim-errorformat] configurations for +the following Verilog tools: + +* Synopsys VCS (`vcs`) +* Mentor Modelsim (`msim`) +* Icarus Verilog (`iverilog`) +* GPL Cver (`cver`) +* Synopsys Leda (`leda`) +* Verilator (`verilator`) +* Cadence NCVerilog (`ncverilog`) + +The command `VerilogErrorFormat` allows the interactive selection of these +configurations. In some cases it is also possible to ignore _lint_ and/or +_warning_ level messages. + +A specific tool can be directly selected calling this command with some +arguments. Below is an example for `VCS`: + +```VimL +:VerilogErrorFormat vcs 2 +``` + +In this example the second argument disables the detection of _lint_ messages. +This argument can take the following values: + +1. All messages are detected. +2. Ignore _lint_ messages. +3. Ignore _lint_ and _warning_ messages. + +After the [errorformat][vim-errorformat] has been so defined, it is only a +matter of setting [makeprg][vim-makeprg] and run `:make` to call the tool of +choice and vim will automatically detect errors, open the required file and +place the cursor on the error position. To navigate the error list use the +commands `:cnext` and `:cprevious`. + +For more information check the help page for the [quickfix][vim-quickfix] +vim feature. + +### Following an Instance + +A framework is provided to follow a module instance to its module +declaration as long as its respective entry exists in the tags file. To +do so simply execute `:VerilogFollowInstance` within the instance to +follow it to its declaration. + +Alternatively, if the cursor is placed over a port of the instance the +command `:VerilogFollowPort` can be used to navigate to the module +declaration and immediately searching for that port. + +These commands can be mapped as following: + +```VimL +nnoremap i :VerilogFollowInstance +nnoremap I :VerilogFollowPort +``` + +### Jump to start of current instance + +The command `:VerilogGotoInstanceStart` is provided to move the cursor +to the start of the first module instantiation that precedes the current +cursor location. + +This command can be mapped as following: + +```VimL +nnoremap u :VerilogGotoInstanceStart +``` + +## Installation + +### Using [vim-plug][P] + +1. Add the following to your `vimrc`: + + ```VimL + Plug 'vhda/verilog_systemverilog.vim' + ``` + +2. Run: + + ```Shell + $ vim +PlugInstall +qall + ``` + +### Using [Vundle][v] + +1. Add the following to your `vimrc`: + + ```VimL + Plugin 'vhda/verilog_systemverilog.vim' + ``` + +2. Run: + + ```Shell + $ vim +PluginInstall +qall + ``` + +### Using [Pathogen][p] + +```Shell +$ cd ~/.vim/bundle +$ git clone https://github.com/vhda/verilog_systemverilog.vim +``` + +## Other Vim addons helpful for Verilog/SystemVerilog + +### Matchit + +This addon allows using % to jump between matching keywords as Vim already +does for matching parentheses/brackets. Many syntax files include the definition +of the matching keyword pairs for their supported languages. + +Since it is already included in all Vim installations and the addon can be +easily loaded by adding the following line to `.vimrc`: + +```VimL +runtime macros/matchit.vim +``` + +### Highlight Matchit + +The [hl_matchit.vim][hl_matchit] addon complements Matchit by automatically +underlining matching words, similarly as Vim already does for +parentheses/brackets. + +### Supertab + +[Supertab][supertab] configures the tab key to perform insert +completion. To take full advantage of the omni completion functionality the +following configuration should be used: + +```VimL +let g:SuperTabDefaultCompletionType = 'context' +``` + +When this is done [Supertab][supertab] will choose the most appropriate type of +completion to use depending on the current context. + +### Tagbar + +[Tagbar][t] allows browsing all variable, functions, tasks, etc within a file in +a nice hierarchical view. SystemVerilog language and Verilog/SystemVerilog +hierarchical browsing are only supported when used together with the development +version of [universal-ctags][c]. + +The required filetype related configuration for [Tagbar][t] is included +within this addon. + +### FastFold + +Vim can become very slow in Insert mode when using [Syntax +Folding][vim-synfold] and the folds extend across the complete file. The +[FastFold][f] addon overcomes this limitation by automatically creating +manual folds from the syntax generated ones. More information about this +problem and on how to configure the addon can be found on its GitHub +page. + +[c]: https://github.com/universal-ctags/ctags +[f]: https://github.com/Konfekt/FastFold +[p]: https://github.com/tpope/vim-pathogen +[v]: https://github.com/gmarik/vundle +[P]: https://github.com/junegunn/vim-plug +[e]: https://ctags.io +[t]: http://majutsushi.github.io/tagbar/ +[hl_matchit]: https://github.com/vimtaku/hl_matchit.vim +[supertab]: https://github.com/ervandew/supertab +[vim-omni]: http://vimdoc.sourceforge.net/htmldoc/insert.html#i_CTRL-X_CTRL-O +[vim-omnifunc]: http://vimdoc.sourceforge.net/htmldoc/options.html#'omnifunc' +[vim-echom]: http://vimdoc.sourceforge.net/htmldoc/eval.html#:echom +[vim-errorformat]: http://vimdoc.sourceforge.net/htmldoc/options.html#'errorformat' +[vim-makeprg]: http://vimdoc.sourceforge.net/htmldoc/options.html#'makeprg' +[vim-quickfix]: http://vimdoc.sourceforge.net/htmldoc/quickfix.html +[vim-synfold]: http://vimdoc.sourceforge.net/htmldoc/syntax.html#syntax + + + diff --git a/bundle/verilog/autoload/verilog.vim b/bundle/verilog/autoload/verilog.vim new file mode 100644 index 000000000..e7e1b2cfe --- /dev/null +++ b/bundle/verilog/autoload/verilog.vim @@ -0,0 +1,746 @@ +" Verilog/SystemVerilog support functions +" Language: Verilog/SystemVerilog +" Maintainer: Vitor Antunes + +"------------------------------------------------------------------------ +" Omni completion functions +" +" Requires ctags from: +" https://github.com/fishman/ctags +" https://github.com/exuberant-ctags/ctags +" ctags must be run with --extra=+q +" {{{ +function! verilog#Complete(findstart, base) + "------------------------------------------------------------------------ + " Phase 1: Find and return prefix of completion + if a:findstart + let linenr = line('.') + let line = getline('.') + let start = col('.') + let prefixpos = -1 + let s:instname = '' + let s:insttype = '' + + " Define start position depending on relation with end of line + if start == col('$') + let wordpos = start + else + let wordpos = start - 1 + endif + + " Search for keywords in line + while start > 0 + if line[start - 1] == ']' + " Skip over [...] + while start > 0 + let start -= 1 + if line[start - 1] == '[' + break + endif + endwhile + else + if line[start - 1] == '.' + " Found separator + let prefixpos = start + elseif prefixpos >= 0 && line[start - 1] =~ '\(\s\|(\)' + " Stop when a whitespace or an open parentheses are found + break + endif + endif + + let start -= 1 + endwhile + + " Determine prefix word + if prefixpos >= 0 + let s:prefix = strpart(line, start, prefixpos - start) + let s:word = strpart(line, prefixpos, wordpos - prefixpos) + + if s:prefix == '.' + " Get instance info and break from while loop + let values = s:GetInstanceInfo(linenr, start) + let s:instname = values[0] + let s:insttype = values[1] + endif + endif + + return prefixpos + endif + + "------------------------------------------------------------------------ + " Phase 2: Search for type definition in tags file + if exists("s:prefix") && s:prefix != '' + call verilog#Verbose("Prefix: " . s:prefix) + call verilog#Verbose("Word : " . s:word) + if s:insttype != '' + " Process an instance + call verilog#Verbose("Process instance") + if exists("s:word") + let tags = taglist('^' . s:insttype . '\.' . s:word) + else + let tags = taglist('^' . s:insttype . '\.') + endif + call verilog#Verbose("Number of tags found: " . len(tags)) + if s:instname != '' + " In instances only return ports + let tags = s:FilterPorts(tags) + " Filter out hierarchical ports + call filter(tags, 'len(split(v:val["name"], "\\.")) > 2 ? 0 : 1') + call verilog#Verbose("Number of tags after filtering: " . len(tags)) + " Remove the module name prefix + call map(tags, 'strpart(v:val["name"], len(s:insttype . "."))') + if (v:version >= 704) + return {'words' : tags} + else + return tags + endif + else + " In parameter list only return constants + let tags = s:FilterConstants(tags) + " Filter out hierarchical ports + call filter(tags, 'len(split(v:val["name"], "\\.")) > 2 ? 0 : 1') + call verilog#Verbose("Number of tags after filtering: " . len(tags)) + " Remove the module name prefix + call map(tags, 'strpart(v:val["name"], len(s:insttype . "."))') + if (v:version >= 704) + return {'words' : tags} + else + return tags + endif + endif + elseif s:instname != '' + " Process a function/task call + call verilog#Verbose("Searching for function") + let items = split(s:instname, '\.') + if len(items) > 1 + let word_list = [s:GetVariableType(items[0])] + call extend(word_list, items[1:]) + let base = join(word_list, ".") + elseif len(items) == 1 + let base = s:instname + endif + call verilog#Verbose("Searching tags starting with " . base) + let tags = s:FilterPortsOrConstants(taglist('^' . base . '\.')) + call map(tags, 'strpart(v:val["name"], len(base . "."))') + if (v:version >= 704) + return {'words' : tags} + else + return tags + endif + else + " Process an object + call verilog#Verbose("Process object") + let idx = match(s:prefix, '\.') + if idx >= 0 + let object = strpart(s:prefix, 0, idx) + else + let object = s:prefix + endif + + let type = s:GetVariableType(object) + if type != "" + " Check if this is a class defined type + let newtype = s:GetClassDefaultParameterValue("", type) + if newtype != "" + let type = newtype + endif + " Search for inherited tags + let tags = s:GetInheritanceTags(type, object) + call verilog#Verbose("Searching tags starting with " . type) + let localtags = taglist('^' . type . '\.' . s:word) + let localtags = s:AppendSignature(localtags) + " Filter out parameters + call filter(localtags, 'v:val["kind"] != "c"') + " Remove the variable type prefix + call map(localtags, 'strpart(v:val["name"], len(type)+1)') + let tags += localtags + " Break if no tags were found + if len(tags) == 0 + return -1 + endif + " Filter out hierarchical ports + call filter(tags, 'len(split(v:val, "\\.")) > 1 ? 0 : 1') + if (v:version >= 704) + return {'words' : tags} + else + return tags + endif + endif + return -1 + endif + else + return -1 + endif +endfunction + +" Search file for instance information: +" * name +" * type (typically a module name, but can also be a function/task/etc) +" * line number +function! s:GetInstanceInfo(linenr, column) + let linenr = a:linenr + let line = getline(linenr) + let start = a:column + let instname = "" + let insttype = "" + let ininstdecl = 0 + let ininsttype = 0 + let p = 0 + let b = 0 + + call verilog#Verbose("Searching for instance info, starting on line " . linenr) + while linenr > 0 + while start > 0 + " Give up if a ; is found. + if line[start - 1] == ';' + call verilog#Verbose("Giving up instance info search, on line " . linenr) + break + " Skip over (...) + elseif line[start - 1] == ')' || p > 0 + if line[start - 1] == ')' + call verilog#Verbose("Skipping parentheses, started on line " . linenr) + endif + while start > 0 + if line[start - 1] == ')' + let p += 1 + elseif line[start - 1] == '(' + let p -= 1 + if p == 0 + call verilog#Verbose("Skipping parentheses, ended on line " . linenr) + break + endif + endif + let start -= 1 + endwhile + " Skip over [...] + elseif line[start - 1] == ']' || b > 0 + if line[start - 1] == ']' + call verilog#Verbose("Skipping brackets, started on line " . linenr) + endif + while start > 0 + if line[start - 1] == ']' + let b += 1 + elseif line[start - 1] == '[' + let b -= 1 + if b == 0 + call verilog#Verbose("Skipping brackets, ended on line " . linenr) + break + endif + endif + let start -= 1 + endwhile + " An unmatched opening parentheses indicate start of instance + " From here backward search for the instance declaration + elseif line[start - 1] == '(' && p == 0 + if line[start - 2] == '#' + let ininsttype = -1 + call verilog#Verbose("Found instance parameter declaration on line " . linenr) + else + let ininstdecl = -1 + call verilog#Verbose("Found instance declaration name start, on line " . linenr) + endif + elseif ininstdecl < 0 && line[start - 1] =~ '\w' + let ininstdecl = start + elseif ininstdecl > 0 && ininsttype == 0 && (line[start - 1] =~ '\s' || start == 1) + if start == 1 && line[start - 1] !~ '\s' + let instname = strpart(line, 0, ininstdecl) + else + let instname = strpart(line, start, ininstdecl - start) + endif + call verilog#Verbose("Found instance name \"" . instname . "\", on line " . linenr) + let ininsttype = -1 + elseif ininsttype < 0 && line[start - 1] =~ '\w' + let ininsttype = start + elseif ininsttype > 0 && (line[start - 1] =~ '\s' || start == 1) + if start == 1 && line[start - 1] !~ '\s' + let insttype = strpart(line, 0, ininsttype) + else + let insttype = strpart(line, start, ininsttype - start) + endif + call verilog#Verbose("Found instance type \"" . insttype . "\", on line " . linenr) + break + endif + + let start -= 1 + endwhile + + " Break search when instance type is found + if ininsttype > 0 + break + endif + + " Give up if a ; is found. + if line[start - 1] == ';' + call verilog#Verbose("Giving up instance info search, on line " . linenr) + break + endif + + " Check next line + let linenr -= 1 + let line = getline(linenr) + let start = len(line) + endwhile + + call verilog#Verbose("Found instance. Name: »" . instname . "« Type: »" . insttype . "«") + return [instname, insttype, linenr] +endfunction + +" Append signature to functions and tasks +function s:AppendSignature(tags) + let newtags = [] + for t in a:tags + if t["kind"] == "t" || t["kind"] == "f" + let t["name"] = t["name"] . "()" + endif + call add(newtags, t) + endfor + return newtags +endfunction + +" Get list of inheritance tags +function s:GetInheritanceTags(class, object) + call verilog#Verbose("Searching inheritance of " . a:object) + let tags = [] + let inheritance = a:class + let classtag = taglist('^' . inheritance . '$') + while exists('classtag[0]["inherits"]') + call verilog#Verbose("Following class " . a:class) + call verilog#Verbose(inheritance . " inherits " . classtag[0]["inherits"]) + let inheritance = classtag[0]["inherits"] + " First check if inheritance is a parameter of the class + let localtags = taglist('^' . a:class . '.' . inheritance . '$') + if len(localtags) == 1 && localtags[0]["kind"] == "c" + call verilog#Verbose(a:class . " inherits from a parameter") + let parameter = inheritance + " Search for parameter initialization in object declaration line + let inheritance = s:GetObjectParameterValue(a:object, parameter) + if inheritance == "" + " Search for parameter default value in class declaration + let inheritance = s:GetClassDefaultParameterValue(a:class, parameter) + if inheritance == "" + call verilog#Verbose("No default inheritance found") + return tags + endif + endif + call verilog#Verbose(a:class . " inherits from " . inheritance) + endif + " Get tags from inherited class + let localtags = taglist('^' . inheritance . '.' . s:word) + let localtags = s:AppendSignature(localtags) + call map(localtags, 'strpart(v:val["name"], len(inheritance)+1)') + let tags += localtags + let classtag = taglist('^' . inheritance . '$') + endwhile + return tags +endfunction + +" Searches for declaration of "word" and returns its type +function s:GetVariableType(word) + let position = getpos(".") + if searchdecl(a:word, 0) == 0 + let line = getline('.') + let line = substitute(line, '\v^\s*(const|rand|randc)', '', '') + let line = substitute(line, '\v^\s*(static|protected|local)', '', '') + let type = split(line)[0] + call verilog#Verbose("Found declation for: " . a:word . " (" . type . ")") + call setpos(".", position) + return type + endif + return 0 +endfunction + +" Searches for declaration of "object" and returns "parameter" initialization value +function s:GetObjectParameterValue(object, parameter) + let position = getpos(".") + if searchdecl(a:object, 0) == 0 + let line = getline('.') + if match(line, 'type\s\+' . a:parameter . '\s*=\s*\w\+') >= 0 + let value = substitute(line, '.*\= 0 + " Search for parameter in class declaration + while match_idx < len(contents) && contents[match_idx] !~ ';' && contents[match_idx] !~ a:parameter + let match_idx += 1 + endwhile + if contents[match_idx] !~ a:parameter + call verilog#Verbose("No declaration of " . a:parameter . " was found in class " . a:class) + return "" + endif + " Find value assignment in current line + let pattern = 'type\s\+' . a:parameter . '\s*=\s*\w\+' + let idx_start = match(contents[match_idx], pattern) + if idx_start >= 0 + let idx_end = matchend(contents[match_idx], pattern) - 1 + let result = contents[match_idx][idx_start : idx_end] + let result = substitute(split(result, '=')[1], '^\s*\(.\{-\}\)\(\s\|,\)*$', '\1', '') + return result + else + call verilog#Verbose("Found parameter " . a:parameter . "but failed to find assignment in the same line") + return "" + endif + else + call verilog#Verbose("Parameter default value not found") + return "" + endif +endfunction + +" Filter tag list to only return ports +function s:FilterPorts(tags) + let tags = a:tags + call filter(tags, 'has_key(v:val, "kind") ? v:val["kind"] == "p" : 1') + return tags +endfunction + +" Filter tag list to only return constants +function s:FilterConstants(tags) + let tags = a:tags + call filter(tags, 'has_key(v:val, "kind") ? v:val["kind"] == "c" : 1') + return tags +endfunction + +" Filter tag list to only return ports or constants +function s:FilterPortsOrConstants(tags) + let tags = a:tags + call filter(tags, 'has_key(v:val, "kind") ? v:val["kind"] == "p" || v:val["kind"] == "c" : 1') + return tags +endfunction +" }}} + +"------------------------------------------------------------------------ +" Common functions +" {{{ +" Verbose messaging +" Only displays messages if b:verilog_verbose or g:verilog_verbose is defined +function verilog#Verbose(message) + if verilog#VariableExists("verilog_verbose") + echom a:message + endif +endfunction + +" Configuration control +" Pushes value to list only if new +" Based on: http://vi.stackexchange.com/questions/6619/append-to-global-variable-and-completion +function verilog#PushToVariable(variable, value) + let list = verilog#VariableGetValue(a:variable) + if (count(list, a:value) == 0) + call add(list, a:value) + endif + call verilog#VariableSetValue(a:variable, list) +endfunction + +function verilog#PopFromVariable(variable, value) + let list = verilog#VariableGetValue(a:variable) + call verilog#VariableSetValue(a:variable, filter(list, "v:val !=# a:value")) +endfunction + +" Get variable value +" Searches for both b:variable and g:variable, with this priority. +" If the variable name includes '_lst' it is automatically split into a +" list. +function verilog#VariableGetValue(variable) + if exists('b:' . a:variable) + let value = eval('b:' . a:variable) + elseif exists('g:' . a:variable) + let value = eval('g:' . a:variable) + else + let value = '' + endif + if a:variable =~ '_lst' + return split(value, ',') + else + return value + endif +endfunction + +" Set variable value +" Searches for both b:variable and g:variable, with this priority. +" If none exists, g: will be used +" If the variable name includes '_lst' the value argument is assumed to +" be a list. +function verilog#VariableSetValue(variable, value) + if a:variable =~ '_lst' + let value = join(a:value, ',') + else + let value = a:value + endif + if exists('b:' . a:variable) + exec 'let b:' . a:variable . ' = value' + else + exec 'let g:' . a:variable . ' = value' + endif +endfunction + +" Checks for variable existence +function verilog#VariableExists(variable) + return exists('b:' . a:variable) || exists('g:' . a:variable) +endfunction +" }}} + +"------------------------------------------------------------------------ +" Command completion functions +" {{{ +function verilog#CompleteCommand(lead, command, cursor) + " Get list with current values in variable + if (a:command =~ 'Folding') + let current_values = verilog#VariableGetValue("verilog_syntax_fold_lst") + elseif (a:command =~ 'Indent') + let current_values = verilog#VariableGetValue("verilog_disable_indent_lst") + elseif (a:command =~ 'ErrorUVM') + let current_values = verilog#VariableGetValue("verilog_efm_uvm_lst") + endif + + " Create list with valid completion values depending on command type + if (a:command =~ 'FoldingAdd') + let valid_completions = [ + \ 'all', + \ 'class', + \ 'function', + \ 'task', + \ 'specify', + \ 'interface', + \ 'clocking', + \ 'covergroup', + \ 'sequence', + \ 'property', + \ 'comment', + \ 'define', + \ 'instance' + \ ] + if (exists('g:verilog_syntax_custom')) + let valid_completions += keys(g:verilog_syntax_custom) + endif + if (empty(filter(current_values, 'v:val =~ "^block"'))) + let valid_completions += [ + \ 'block', + \ 'block_nested', + \ 'block_named' + \ ] + endif + for item in current_values + call filter(valid_completions, 'v:val !=# item') + endfor + elseif (a:command =~ 'DisableIndentAdd') + let valid_completions = [ + \ 'module', + \ 'interface', + \ 'class', + \ 'package', + \ 'covergroup', + \ 'program', + \ 'generate', + \ 'sequence', + \ 'property', + \ 'method', + \ 'preproc', + \ 'conditional', + \ 'eos' + \ ] + for item in current_values + call filter(valid_completions, 'v:val !=# item') + endfor + elseif (a:command =~ 'ErrorUVMAdd') + let valid_completions = [ + \ 'all', + \ 'info', + \ 'warning', + \ 'error', + \ 'fatal', + \ ] + for item in current_values + call filter(valid_completions, 'v:val !=# item') + endfor + else + let valid_completions = current_values + endif + + " If a:lead already includes other comma separated values, then remove + " all from the list of valid values except the last + let lead_list = split(a:lead, ',') + call verilog#Verbose('Current lead values list: [' . join(lead_list, ',') . '] (length = ' . len(lead_list) . ')') + call verilog#Verbose('Valid completions: [' . join(valid_completions, ',') . '] (length = ' . len(valid_completions) . ')') + if (a:lead =~ ',$') + let initial_lead = lead_list + let real_lead = "" + else + if (len(lead_list) > 1) + let initial_lead = lead_list[0:-2] + let real_lead = lead_list[-1] + else + let initial_lead = [] + let real_lead = a:lead + endif + endif + call verilog#Verbose('Removing [' . join(initial_lead, ',') . '] from completion value list') + call verilog#Verbose('Searching using lead: "' . real_lead . '"') + for item in initial_lead + call filter(valid_completions, 'v:val !=# item') + endfor + + let completion_list = filter(valid_completions, 'v:val =~ "^" . real_lead') + + if (len(initial_lead) > 0) + return map(completion_list, 'join(initial_lead, ",") . "," . v:val') + else + return completion_list + endif +endfunction +" }}} + +"------------------------------------------------------------------------ +" External functions +" {{{ +function verilog_systemverilog#GotoInstanceStart(line, column) + let values = s:GetInstanceInfo(a:line, col('$')) + if values[2] != "" + call cursor(values[2], a:column) + endif +endfunction + +function verilog#FollowInstanceTag(line, column) + let values = s:GetInstanceInfo(a:line, col('$')) + if exists("g:verilog_navigate_split") + exec "wincmd ".g:verilog_navigate_split + endif + if values[1] != "" + execute "tag " . values[1] + endif +endfunction + +function verilog_systemverilog#ReturnFromInstanceTag() + if winnr('$') > 1 && exists("g:verilog_navigate_split") + if exists("g:verilog_navigate_split_close") + exec g:verilog_navigate_split_close + else + exec "quit" + endif + else + exec "pop" + endif +endfunction + +function verilog_systemverilog#FollowInstanceSearchWord(line, column) + let @/='\<'.expand("").'\>' + call verilog#FollowInstanceTag(a:line, a:column) + exec "normal!" . @/ + normal! n +endfunction +" }}} + +"------------------------------------------------------------------------ +" Command to control errorformat and compiler +" {{{ +function! verilog_systemverilog#VerilogErrorFormat(...) + " Choose tool + if (a:0 == 0) + let l:tool = inputlist([ + \"1. VCS", + \"2. Modelsim", + \"3. iverilog", + \"4. cver", + \"5. Leda", + \"6. Verilator", + \"7. NCVerilog", + \"8. SpyGlass", + \]) + echo "\n" + if (l:tool == 1) + let l:tool = "vcs" + elseif (l:tool == 2) + let l:tool = "msim" + elseif (l:tool == 3) + let l:tool = "iverilog" + elseif (l:tool == 4) + let l:tool = "cver" + elseif (l:tool == 5) + let l:tool = "leda" + elseif (l:tool == 6) + let l:tool = "verilator" + elseif (l:tool == 7) + let l:tool = "ncverilog" + else + let l:tool = "spyglass" + endif + else + let l:tool = tolower(a:1) + endif + + " Choose error level + if (a:0 <= 1) + if (l:tool == "vcs") + let l:mode = inputlist([ + \"1. check all", + \"2. ignore lint", + \"3. ignore lint and warnings" + \]) + echo "\n" + elseif ( + \ l:tool == "msim" || + \ l:tool == "cver" || + \ l:tool == "verilator" || + \ l:tool == "ncverilog" || + \ l:tool == "spyglass" + \ ) + let l:mode = inputlist([ + \"1. check all", + \"2. ignore warnings" + \]) + echo "\n" + if (l:mode == 2) + let l:mode = 3 + endif + else + let l:mode = 1 + endif + else + let l:mode = a:2 + endif + + if (l:mode <= 1) + let g:verilog_efm_level = "lint" + elseif (l:mode <= 2) + let g:verilog_efm_level = "warning" + else + let g:verilog_efm_level = "error" + endif + + call verilog#Verbose("Configuring errorformat with: tool=" . l:tool . "; mode=" . l:mode) + + if (index(['vcs', 'modelsim', 'iverilog', 'cver', 'leda', 'verilator', 'ncverilog', 'spyglass'], l:tool) >= 0) + execute 'compiler! '. l:tool + echo 'Selected errorformat for "' . l:tool . '"' + else + echoerr 'Unknown tool name "' . l:tool . '"' + endif +endfunction +" }}} + +" vi: sw=2 sts=2: diff --git a/bundle/verilog/compiler/cver.vim b/bundle/verilog/compiler/cver.vim new file mode 100644 index 000000000..0cfcbeba2 --- /dev/null +++ b/bundle/verilog/compiler/cver.vim @@ -0,0 +1,31 @@ +" Vim compiler file +" Compiler: GPL cver + +if exists("current_compiler") + finish +endif +let current_compiler = "cver" + +if exists(":CompilerSet") != 2 + command -nargs=* CompilerSet setlocal +endif + +let s:cpo_save = &cpo +set cpo-=C + +" Error level formats +CompilerSet errorformat=\*\*%f(%l)\ ERROR\*\*\ \[%n\]\ %m + +" Warning level formats +if (!exists("g:verilog_efm_level") || g:verilog_efm_level != "error") + CompilerSet errorformat+=\*\*%f(%l)\ WARN\*\*\ \[%n\]\ %m + CompilerSet errorformat+=\*\*\ WARN\*\*\ \[\%n\]\ %m +endif + +" Load common errorformat configurations +runtime compiler/verilog_common.vim + +let &cpo = s:cpo_save +unlet s:cpo_save + +" vi: sw=2 sts=2: diff --git a/bundle/verilog/compiler/iverilog.vim b/bundle/verilog/compiler/iverilog.vim new file mode 100644 index 000000000..e59016209 --- /dev/null +++ b/bundle/verilog/compiler/iverilog.vim @@ -0,0 +1,25 @@ +" Vim compiler file +" Compiler: Icarus Verilog + +if exists("current_compiler") + finish +endif +let current_compiler = "iverilog" + +if exists(":CompilerSet") != 2 + command -nargs=* CompilerSet setlocal +endif + +let s:cpo_save = &cpo +set cpo-=C + +" Error level formats +CompilerSet errorformat=%f\\:%l:\ %m + +" Load common errorformat configurations +runtime compiler/verilog_common.vim + +let &cpo = s:cpo_save +unlet s:cpo_save + +" vi: sw=2 sts=2: diff --git a/bundle/verilog/compiler/leda.vim b/bundle/verilog/compiler/leda.vim new file mode 100644 index 000000000..c5790565b --- /dev/null +++ b/bundle/verilog/compiler/leda.vim @@ -0,0 +1,25 @@ +" Vim compiler file +" Compiler: Synopsys Leda + +if exists("current_compiler") + finish +endif +let current_compiler = "leda" + +if exists(":CompilerSet") != 2 + command -nargs=* CompilerSet setlocal +endif + +let s:cpo_save = &cpo +set cpo-=C + +" Error level formats +CompilerSet errorformat=%f\\:%l:\ %.%#\[%t%.%#\]\ %m + +" Load common errorformat configurations +runtime compiler/verilog_common.vim + +let &cpo = s:cpo_save +unlet s:cpo_save + +" vi: sw=2 sts=2: diff --git a/bundle/verilog/compiler/msim.vim b/bundle/verilog/compiler/msim.vim new file mode 100644 index 000000000..1ae9aae3e --- /dev/null +++ b/bundle/verilog/compiler/msim.vim @@ -0,0 +1,30 @@ +" Vim compiler file +" Compiler: Mentor Modelsim + +if exists("current_compiler") + finish +endif +let current_compiler = "msim" + +if exists(":CompilerSet") != 2 + command -nargs=* CompilerSet setlocal +endif + +let s:cpo_save = &cpo +set cpo-=C + +" Error level formats +CompilerSet errorformat=\*\*\ Error:\ %f(%l):\ %m + +" Warning level formats +if (!exists("g:verilog_efm_level") || g:verilog_efm_level != "error") + CompilerSet errorformat+=\*\*\ Warning:\ \[\%n\]\ %f(%l):\ %m +endif + +" Load common errorformat configurations +runtime compiler/verilog_common.vim + +let &cpo = s:cpo_save +unlet s:cpo_save + +" vi: sw=2 sts=2: diff --git a/bundle/verilog/compiler/ncverilog.vim b/bundle/verilog/compiler/ncverilog.vim new file mode 100644 index 000000000..18632048b --- /dev/null +++ b/bundle/verilog/compiler/ncverilog.vim @@ -0,0 +1,34 @@ +" Vim compiler file +" Compiler: Cadence NCVerilog + +if exists("current_compiler") + finish +endif +let current_compiler = "ncverilog" + +if exists(":CompilerSet") != 2 + command -nargs=* CompilerSet setlocal +endif + +let s:cpo_save = &cpo +set cpo-=C + +" Error level formats +" Based on https://github.com/vhda/verilog_systemverilog.vim/issues/88 +CompilerSet errorformat =%.%#:\ *%t\\,%.%#\ %#\(%f\\,%l\|%c\):\ %m +CompilerSet errorformat+=%.%#:\ *%t\\,%.%#\ %#\(%f\\,%l\):\ %m +" Multi-line error messages +CompilerSet errorformat+=%A%.%#\ *%t\\,%.%#:\ %m,%ZFile:\ %f\\,\ line\ =\ %l\\,\ pos\ =\ %c + +" Ignore Warning level formats +if (!exists("g:verilog_efm_level") || g:verilog_efm_level == "error") + CompilerSet errorformat^=%-G%.%#\ *W\\,%.%#:\ %m +endif + +" Load common errorformat configurations +runtime compiler/verilog_common.vim + +let &cpo = s:cpo_save +unlet s:cpo_save + +" vi: sw=2 sts=2: diff --git a/bundle/verilog/compiler/spyglass.vim b/bundle/verilog/compiler/spyglass.vim new file mode 100644 index 000000000..b1432fbf6 --- /dev/null +++ b/bundle/verilog/compiler/spyglass.vim @@ -0,0 +1,32 @@ +" Vim compiler file +" Compiler: Synopsys Spyglass + +if exists("current_compiler") + finish +endif +let current_compiler = "spyglass" + +if exists(":CompilerSet") != 2 + command -nargs=* CompilerSet setlocal +endif + +let s:cpo_save = &cpo +set cpo-=C + +" Error level formats +CompilerSet errorformat =%.%#\ %\\+%tATAL\ %\\+%[a-zA-Z0-9]%\\+\ %\\+%f\ %\\+%l\ %\\+%n\ %\\+%m +CompilerSet errorformat+=%.%#\ %\\+%tRROR\ %\\+%[a-zA-Z0-9]%\\+\ %\\+%f\ %\\+%l\ %\\+%n\ %\\+%m +CompilerSet errorformat+=%.%#\ %\\+Syntax\ %\\+%f\ %\\+%l\ %\\+%m + +" Warning level formats +if (!exists("g:verilog_efm_level") || g:verilog_efm_level != "error") + CompilerSet errorformat+=%.%#\ %\\+%tARNING\ %\\+%[a-zA-Z0-9]%\\+\ %\\+%f\ %\\+%l\ %\\+%n\ %\\+%m +endif + +" Load common errorformat configurations +runtime compiler/verilog_common.vim + +let &cpo = s:cpo_save +unlet s:cpo_save + +" vi: sw=2 sts=2: diff --git a/bundle/verilog/compiler/vcs.vim b/bundle/verilog/compiler/vcs.vim new file mode 100644 index 000000000..e4f446e1f --- /dev/null +++ b/bundle/verilog/compiler/vcs.vim @@ -0,0 +1,45 @@ +" Vim compiler file +" Compiler: Synopsys VCS + +if exists("current_compiler") + finish +endif +let current_compiler = "vcs" + +if exists(":CompilerSet") != 2 + command -nargs=* CompilerSet setlocal +endif + +let s:cpo_save = &cpo +set cpo-=C + +" Error level formats +CompilerSet errorformat =%EError-\[%.%\\+\]\ %m +CompilerSet errorformat+=%C%m\"%f\"\\,\ %l%.%# +CompilerSet errorformat+=%C%f\\,\ %l +CompilerSet errorformat+=%C%\\s%\\+%l:\ %m\\,\ column\ %c +CompilerSet errorformat+=%C%\\s%\\+%l:\ %m +CompilerSet errorformat+=%C%m\"%f\"\\,%.%# +CompilerSet errorformat+=%Z%p^ "Column pointer +CompilerSet errorformat+=%C%m "Catch all rule +CompilerSet errorformat+=%Z "Error message end on empty line + +" Warning level formats +if (!exists("g:verilog_efm_level") || g:verilog_efm_level != "error") + CompilerSet errorformat+=%WWarning-\[%.%\\+]\\$ + CompilerSet errorformat+=%-WWarning-[LCA_FEATURES_ENABLED]\ Usage\ warning "Ignore LCA enabled warning + CompilerSet errorformat+=%WWarning-\[%.%\\+\]\ %m +endif + +" Lint level formats +if (!exists("g:verilog_efm_level") || g:verilog_efm_level == "lint") + CompilerSet errorformat+=%I%tint-\[%.%\\+\]\ %m +endif + +" Load common errorformat configurations +runtime compiler/verilog_common.vim + +let &cpo = s:cpo_save +unlet s:cpo_save + +" vi: sw=2 sts=2: diff --git a/bundle/verilog/compiler/verilator.vim b/bundle/verilog/compiler/verilator.vim new file mode 100644 index 000000000..3250ecbaf --- /dev/null +++ b/bundle/verilog/compiler/verilator.vim @@ -0,0 +1,32 @@ +" Vim compiler file +" Compiler: Verilator + +if exists("current_compiler") + finish +endif +let current_compiler = "verilator" + +if exists(":CompilerSet") != 2 + command -nargs=* CompilerSet setlocal +endif + +let s:cpo_save = &cpo +set cpo-=C + +" Error level formats +CompilerSet errorformat=%%%trror%.%#:\ %f:%l:%c:\ %m +CompilerSet errorformat+=%%%trror%.%#:\ %f:%l:\ %m + +" Warning level formats +if (!exists("g:verilog_efm_level") || g:verilog_efm_level != "error") + CompilerSet errorformat+=%%%tarning%.%#:\ %f:%l:%c:\ %m + CompilerSet errorformat+=%%%tarning%.%#:\ %f:%l:\ %m +endif + +" Load common errorformat configurations +runtime compiler/verilog_common.vim + +let &cpo = s:cpo_save +unlet s:cpo_save + +" vi: sw=2 sts=2: diff --git a/bundle/verilog/compiler/verilog_common.vim b/bundle/verilog/compiler/verilog_common.vim new file mode 100644 index 000000000..19351baca --- /dev/null +++ b/bundle/verilog/compiler/verilog_common.vim @@ -0,0 +1,40 @@ +" Vim compiler file + +if exists(":CompilerSet") != 2 + command -nargs=* CompilerSet setlocal +endif + +let s:cpo_save = &cpo +set cpo-=C + +" Append UVM errorformat if enabled +if (exists("g:verilog_efm_uvm_lst")) + let verilog_efm_uvm = verilog_systemverilog#VariableGetValue('verilog_efm_uvm_lst') + if (index(verilog_efm_uvm, 'all') >= 0 || index(verilog_efm_uvm, 'info') >= 0) + CompilerSet errorformat+=UVM_%tNFO\ %f(%l)\ %m + endif + if (index(verilog_efm_uvm, 'all') >= 0 || index(verilog_efm_uvm, 'warning') >= 0) + CompilerSet errorformat+=UVM_%tARNING\ %f(%l)\ %m + endif + if (index(verilog_efm_uvm, 'all') >= 0 || index(verilog_efm_uvm, 'error') >= 0) + CompilerSet errorformat+=UVM_%tRROR\ %f(%l)\ %m + endif + if (index(verilog_efm_uvm, 'all') >= 0 || index(verilog_efm_uvm, 'fatal') >= 0) + CompilerSet errorformat+=UVM_%tATAL\ %f(%l)\ %m + endif +endif + +" Append any user-defined efm entries +if (exists("g:verilog_efm_custom")) + CompilerSet errorformat+=g:verilog_efm_custom +endif + +" Cleanup rule +if (exists("g:verilog_efm_quickfix_clean")) + CompilerSet errorformat+=%-G%.%# +endif + +let &cpo = s:cpo_save +unlet s:cpo_save + +" vi: sw=2 sts=2: diff --git a/bundle/verilog/doc/verilog_systemverilog.txt b/bundle/verilog/doc/verilog_systemverilog.txt new file mode 100644 index 000000000..554da5845 --- /dev/null +++ b/bundle/verilog/doc/verilog_systemverilog.txt @@ -0,0 +1,765 @@ +*verilog_systemverilog.txt* Verilog/SystemVerilog Syntax + +Author: Vitor Antunes +Licence: Vim licence, see |license| +Homepage: http://vhda.github.com/verilog_systemverilog.vim/ +Version: 3.0 + +============================================================================== +Contents *verilog_systemverilog* *verilog-contents* + + 1. About .................................... |verilog-about| + 2. Requirements ............................. |verilog-requirements| + 3. Installation ............................. |verilog-installation| + 4. Usage .................................... |verilog-usage| + Omni-completion ........................ |verilog-omni| + Syntax folding ......................... |verilog-fold| + Verilog error formats .................. |verilog-efm| + Verilog navigation ..................... |verilog-navigate| + Commands ............................... |verilog-commands| + Key mappings ........................... |verilog-keys| + 5. Configuration ............................ |verilog-config| + Indent configuration ................... |verilog-config-indent| + Syntax configuration ................... |verilog-config-syntax| + General configuration .................. |verilog-config-general| + 6. Frequently Asked Questions ............... |verilog-faq| + 7. History .................................. |verilog-history| + 8. Credits .................................. |verilog-credits| + +============================================================================== +1. About *verilog-about* + +Besides some bug corrections, the following features were added to this set of +scripts: + + - Omni completion. + - Configurable syntax folding. + - Context based indentation. + - Matchit settings to support Verilog 2001 and SystemVerilog. + - Error format definitions for common Verilog tools. + - Commands for code navigation. + +============================================================================== +2. Requirements *verilog-requirements* + +The following requirements have to be met in order to be able to use tagbar: + + - Exuberant ctags 5.5 or higher. Ctags is the program that generates the + tag information that Tagbar uses. It is shipped with most Linux + distributions, otherwise it can be downloaded from the following + website: + + http://ctags.sourceforge.net/ + + The user is responsible for the generation of the |tags| file. + - Universal ctags is recommended, in particular for SystemVerilog + environments. Most of the omni completion features require this fork of + Exuberant ctags. This program is available at: + + https://ctags.io/ + https://github.com/universal-ctags/ctags + + - File type detection must be turned on in vim. This can be done with the + following command in your |vimrc|: +> + filetype on +< + See |filetype| for more information. + - Some functionalities will not work in |restricted-mode| or with + 'compatible' set. + +============================================================================== +3. Installation *verilog-installation* + +------------------------------------------------------------------------------ +vim-plug + +1. Add the following to your |vimrc|: +> + Plug 'vhda/verilog_systemverilog.vim' +< +2. Run: +> + $ vim +PlugInstall +qall +< +------------------------------------------------------------------------------ +Vundle + +1. Add the following to your `vimrc`: +> + Plugin 'vhda/verilog_systemverilog.vim' +< +2. Run: +> + $ vim +PluginInstall +qall +< +------------------------------------------------------------------------------ +Pathogen +> + $ cd ~/.vim/bundle + $ git clone https://github.com/vhda/verilog_systemverilog.vim +< +============================================================================== +4. Usage *verilog-usage* + +After installation every Verilog file should automatically be detected as +`verilog_systemverilog` filetype. Use the following command after opening a +Verilog or SystemVerilog file to confirm that its |filetype| is properly +defined: +> + :set filetype? +< +------------------------------------------------------------------------------ +OMNI COMPLETION *verilog-omni* + +This plugin implements an omni completion function that will offer completion +suggestions depending on the current context. This will only work if a `.` +character is found in the keyword behind the cursor. At the moment the +following contexts are supported: + +1. Module instantiation port names. +2. Function/task arguments. +3. Object methods and attributes. + +In order to use omni completion a tags file must be generated using the +following arguments: + +* `--extra=+q` - Enable hierarchy qualified tags extraction. +* `--fields=+i` - Enable class inheritance extraction. +* `-n` - (Optional) Use line number instead of Ex: patterns to identify + declaration (generates smaller tags file). + +No alternative to Universal ctags was tested, but any tag generation software +should work seemingly as long as it is able to generate a standard class +qualified tags file. +For more information on using omni completion please see help page of +|`i_CTRL-X_CTRL-O| (the required option |'omnifunc'| is automatically defined +for the supported file extensions). + + Note: Proper SystemVerilog tag generation requires development version of + Universal ctags. + +------------------------------------------------------------------------------ +SYNTAX FOLDING *verilog-fold* + +To enable syntax folding set the following option: + +> + set foldmethod=syntax +< + +Take into account that all folding is disabled by default and the list of +items to be folded must be configured using |g:verilog_syntax_fold_lst|. + +------------------------------------------------------------------------------ +VERILOG ERROR FORMATS *verilog-efm* + +This plugin includes the |:compiler| definitions for the following Verilog +tools: + +* Synopsys VCS (`vcs`) +* Mentor Modelsim (`msim`) +* Icarus Verilog (`iverilog`) +* GPL Cver (`cver`) +* Synopsys Leda (`leda`) +* Verilator (`verilator`) +* NCVerilog (`ncverilog`) +* SpyGlass (`spyglass`) + +The |:compiler| or |:compiler|! commands can be used to enable these +definitions on the current buffer or all buffers, respectively. +Example for `iverilog`: + +> + :compiler! iverilog +< + +The command |:VerilogErrorFormat| allows the interactive selection of these +configurations. In some cases it is also possible to ignore lint and/or +warning level messages. + +A specific tool can be directly selected calling this command with some +arguments. Below is an example for `VCS`: + +> + :VerilogErrorFormat vcs 2 +< + +In this example the second argument disables the detection of lint messages. +This argument can take the following values: + +1. All messages are detected. +2. Ignore lint messages. +3. Ignore lint and warning messages. + + Note: The |:compiler| definitions only configure the |'errorformat'| + option, so it is always necessary to also setup |'makeprg'| before running + |:make| to execute the selected tool. + +After doing this Vim will be able to detect error messages displayed by the +selected tool. Vim will also automatically open the files with errors and +place the cursor on the error position. To navigate the error list use the +commands |:cnext| and |:cprevious|. + +For more information check the help page for the |quickfix| vim feature. + +------------------------------------------------------------------------------ +VERILOG NAVIGATION *verilog-navigate* + +Following an Instance~ + +A framework is provided to follow a module instance to its module declaration +as long as its respective entry exists in the tags file. To do so simply +execute |:VerilogFollowInstance| within the instance to follow it to its +declaration. + +Alternatively, if the cursor is placed over a port of the instance the command +|:VerilogFollowPort| can be used to navigate to the module declaration and +immediately searching for that port. + +The navigation is implemented using tags, so normal |'tagstack'| related +commands can be used to return from the module declaration. Alternatively, the +command |:VerilogReturnInstance| can be used for this purpose. + +When |g:verilog_navigate_split| is defined these commands will use Vim window +splits instead of navigating in the same window. + +These commands can be mapped as following: + +> + nnoremap i :VerilogFollowInstance + nnoremap o :VerilogReturnInstance + nnoremap I :VerilogFollowPort +< + +Jump to start of current instance~ + +The command |:VerilogGotoInstanceStart| is provided to move the cursor to the +start of the first module instantiation that precedes the current cursor +location. + +This command can be mapped as following: + +> + nnoremap u :VerilogGotoInstanceStart +< + +------------------------------------------------------------------------------ +COMMANDS *verilog-commands* + +:VerilogGotoInstanceStart *:VerilogGotoInstanceStart* + Move cursor to start of instance. + + Cursor position moves to the start of instance declaration if called when + the cursor is within an instance declaration. + +:VerilogFollowInstance *:VerilogFollowInstance* + Jump to module declaration of current instance. + + The instance is searched for starting from the current cursor position. + After that, the module is searched for in the |tags| file and, if found, + jumps to its defintion using |:tag|. + +:VerilogReturnInstance *:VerilogReturnInstance* + Jump from module declaration back to previously followed instance. + + Uses |'tagstack'| through |pop| function to return from previously + followed instance. + +:VerilogFollowPort *:VerilogFollowPort* + Jump to module declaration of current port and search for it. + + Works as |:VerilogFollowInstance| but searches for keyword under cursor + after jumping to the module definition. + +:VerilogErrorFormat [{tool} [{level}]] *:VerilogErrorFormat* + Configure |'errorformat'| for the selected tool. + + If called without arguments it will interactively ask for the tool name + and, if the tool supports it, the level of error messages to identify in + the log. This commands then configures |g:verilog_efm_level| accordingly + and executes |:compiler|! with the selected tool. + + Values supported for {tool}: + vcs - Synopsys VCS + msim - Mentor Modelsim + iverilog - Icarus Verilog + cver - GPL Cver + leda - Synopsys Leda + verilator - Verilator + ncverilog - Cadence NCVerilog + spyglass - Synopsys SpyGlass + + Values supported for {level}: + 1 - Mark all messages + 2 - Ignore lint messages + 3 - Ignore lint and warning messages + + Usage example: +> + :VerilogErrorFormat vcs 2 +< + Note: It is necessary to properly setup |'makeprg'| such that the + configured tool is executed with |:make|. For more information check the + |quickfix| help page. + +:VerilogFoldingAdd *:VerilogFoldingAdd* +:VerilogFoldingRemove *:VerilogFoldingRemove* + Commands with auto-completion to simplify maintenance of + |g:verilog_syntax_fold_lst|. + + If |c_CTRL-D| is used after these commands a list of valid values is + suggested. When adding new values only valid and not already enabled + options are suggested. When removing values only currently enabled values + are suggested. + +:VerilogDisableIndentAdd *:VerilogDisableIndentAdd* +:VerilogDisableIndentRemove *:VerilogDisableIndentRemove* + Commands with auto-completion to simplify maintenance of + |g:verilog_disable_indent|. + + If |c_CTRL-D| is used after these commands a list of valid values is + suggested. When adding new values only valid and not already enabled + options are suggested. When removing values only currently enabled values + are suggested. + +------------------------------------------------------------------------------ +KEY MAPPINGS *verilog-keys* + +Key mappings are not defined automatically, but it is suggested that the +following mappings are added to your |vimrc|. +> + nnoremap u :VerilogGotoInstanceStart + nnoremap i :VerilogFollowInstance + nnoremap o :VerilogReturnInstance + nnoremap I :VerilogFollowPort +< +============================================================================== +5. Configuration *verilog-config* + +------------------------------------------------------------------------------ +INDENT CONFIGURATION *verilog-config-indent* + + *b:verilog_indent_width* *g:verilog_indent_width* +b:verilog_indent_width~ +g:verilog_indent_width~ +Default: undefined + + Override normal |'shiftwidth'|. + +Example: +> + let b:verilog_indent_width = 8 +< + + *b:verilog_indent_assign_fix* *g:verilog_indent_assign_fix* +b:verilog_indent_assign_fix~ +g:verilog_indent_assign_fix~ +Default: undefined + + Always indent lines following an assignment by a fixed amount. + By default, the indentation script tries to be smart and aligns the lines + following the assignment with the start of assigned value, if existing: +> + assign y = + a && b; + assign z = c && + d; +< + This behavior is disabled when this option is enabled: +> + assign y = + a && b; + assign z = c && + d; +< + +Example: + +> + let b:verilog_indent_assign_fix = 1 +< + + *b:verilog_disable_indent_lst* *g:verilog_disable_indent_lst* +b:verilog_disable_indent_lst~ +g:verilog_disable_indent_lst~ +Default: "eos" + + Disables indent for specific Verilog/SystemVerilog contexts. + The following contexts are supported: + - `module` + - `interface` + - `class` + - `package` + - `covergroup` + - `program` + - `generate` + - `sequence` + - `property` + - `method` + - `preproc` + - `conditional` + - `eos` + +Example: + +> + let g:verilog_disable_indent_lst = "module,class,interface" +< + Disabling indentation of `conditional` will change the following: +> + // Default indent + assign a = cond ? b : + c ; + // Disabling 'conditional' + assign a = cond ? b : + c ; +< + + Disabling indentation of `eos` will affect how the closing parentheses of + modules, functions, tasks, etc. are indented. + By default: +> + module mod( + input wire a, + input wire b, + ); +< + When disabled: +> + module mod( + input wire a, + input wire b, + ); +< + + Note: The commands |:VerilogIndentAdd| and |:VerilogIndentRemove| are + provided to allow an easier management of this variable. + +------------------------------------------------------------------------------ +SYNTAX CONFIGURATION *verilog-config-syntax* + + *b:verilog_syntax_fold_lst* *g:verilog_syntax_fold_lst* +b:verilog_syntax_fold_lst~ +g:verilog_syntax_fold_lst~ +Default: undefined + + Enables syntax folding according to the configured values. + This configuration is a comma-separated string of one or more of the + following: + - `class` + - `function` + - `task` + - `specify` + - `interface` + - `clocking` + - `covergroup` + - `sequence` + - `property` + - `block` (`begin`, `end`) + - `block_nested` (like "block", but allows nesting) + - `block_named` (like "block", but allows nesting and only folds if `begin` is labelled) + - `comment` (`/*..*/`) + - `define` (preprocessor conditional statement) + - `instance` + - `all` (enables all above options) + Set to an empty string to disable syntax folding. + +Example: + +> + let g:verilog_syntax_fold_lst = "function,task" +< + + Note: The commands |:VerilogFoldingAdd| and |:VerilogFoldingRemove| are + provided to allow an easier management of this variable. + + + *b:verilog_syntax_custom* *g:verilog_syntax_custom* +b:verilog_syntax_custom~ +g:verilog_syntax_custom~ +Default: undefined + + Dictionary containing custom syntax declarations. + Each dictionary key is a list of syntax definitions that is a dictionary + with the following keys: + - `keyword` - Space separated list of keywords for a |:syn-keyword| entry. + - `match` - Match expression for a |:syn-match| entry. + - `match_start` - Match start expression for a |:syn-region| entry. + - `match_end` - Match end expression for a |:syn-region| entry. + - `cluster` - Value to be used in "contains=" in a |:syn-cluster| entry. + - `highlight` - Highlight to be used on as |:syn-matchgroup|. + - `syn_argument` - Other optional |:syn-arguments|. + +Examples: + +> + " Fold on SpyGlass pragmas + let g:verilog_syntax_custom = { + \ 'spyglass' : [{ + \ 'match_start' : '\/\/\s*spyglass\s\+disable_block\s\+\z(\(\w\|-\)\+\(\s\+\(\w\|-\)\+\)*\)', + \ 'match_end' : '\/\/\s*spyglass\s\+enable_block\s\+\z1', + \ 'syn_argument': 'transparent keepend', + \ }], + \ } + + " Fold on consecutive line comments + let g:verilog_syntax_custom = { + \ 'comment' : [{ + \ 'match_start' : '^\s*//', + \ 'match_end' : '^\%(\s*//\)\@!', + \ 'syn_argument': 'contains=verilogTodo,verilogDirective,@Spell keepend extend' + \ }], + \ } +< + + *g:verilog_disable_constant_highlight* +g:verilog_disable_constant_highlight~ +Default: undefined + + Disables constants highlight. + This is useful when coding guidelines require keywords starting in + uppercase that are not constants. + + + *g:verilog_quick_syntax* +g:verilog_quick_syntax~ +Default: undefined + + When enabled, syntax regions will not be defined with Vim's 'syntax' + command. This can help performance if you are using an old machine or + viewing a large file such as a netlist. This can be useful if you don't + care about automatic indentation but still wish to have syntax coloring. + + WARNING: Enabling this will change the behaviour of indentation as the + indentation script uses the syntax regions to determine the nested + context. + +------------------------------------------------------------------------------ +ERROR FORMAT CONFIGURATION *verilog-config-efm* + + *g:verilog_efm_level* +g:verilog_efm_level~ +Default: undefined + + Determines which types of messages are added to |'errorformat'| for + detection. When undefined, all messages are detected. The following values + are supported: + - `error` - Only Error level messages are detected. + - `warning` - Error and Warning level messages are detected. + - `lint` - All messages are detected. + +Example: + +> + let g:verilog_efm_level = "error" +< + + *g:verilog_efm_uvm_lst* +g:verilog_efm_uvm_lst~ +Default: undefined + + When enabled, appends UVM message formats to |'errorformat'|. + This configuration is a comma-separated string of one or more of the + following: + - `fatal` + - `error` + - `warning` + - `info` + - `all` (enables all above options) + +Example: + +> + let g:verilog_efm_uvm_lst = "all" + let g:verilog_efm_uvm_lst = "fatal,error,warning" +< + + Note: The commands |:VerilogErrorUVMAdd| and |:VerilogErrorUVMRemove| are + provided to allow an easier management of this variable. + + *g:verilog_efm_quickfix_clean* +g:verilog_efm_quickfix_clean~ +Default: undefined + + When enabled, appends global matching string to |'errorformat'| such that + any message that does not match any preceding rule will not appear in the + |quickfix| window. This will result in a clean quickfix window, where only + parsed messages are shown. + +Example: + +> + let g:verilog_efm_quickfix_clean = 1 +< + + *g:verilog_efm_custom* +g:verilog_efm_custom~ +Default: undefined + + Allows appending custom |'errorformat'| rules. + +Example: + +> + let g:verilog_efm_custom = %t:\ %m +< + +------------------------------------------------------------------------------ +NAVIGATION CONFIGURATION *verilog-config-navigation* + + *g:verilog_navigate_split* +g:verilog_navigate_split~ +Default: undefined + + Opens a split when following an instance. + Makes use of |:wincmd| and supports the same arguments. In particular: + - undefined - Split not opened when following instances + - `"s"` - Opens horizontal split + - `"v"` - Opens vertical split + +Example: + +> + let g:verilog_navigate_split = 1 +< + + *g:verilog_navigate_split_close* +g:verilog_navigate_split_close~ +Default: undefined + + Command to execute when returning from an instance, when split is enabled. + The command |:quit| is used by default when this variable is undefined. + +Example: + +> + let g:verilog_navigate_split_close = "bdel" +< + +------------------------------------------------------------------------------ +GENERAL CONFIGURATION *verilog-config-general* + + *b:verilog_verbose* *g:verilog_verbose* +b:verilog_verbose~ +g:verilog_verbose~ +Default: undefined + + Enable verbose messaging of the various components of this plugin. + Messages can be reviewed using |:messages|. + +Example: + +> + let g:verilog_verbose = 1 +< + +============================================================================== +6. Frequently Asked Questions *verilog-faq* + +------------------------------------------------------------------------------ +How to configure certain features only on some files? + +Many configurations support both buffer local and global variables, allowing +using default configurations together with local expections. This provides the +simplicity of using global variables that do not require |:autocmd| for users +that do not require exceptions, together with the versatily of buffer local +variables for those that need it. + +The following example allows using different settings for Verilog and +SystemVerilog files: + +> + let g:verilog_indent_width=2 + augroup verilog_indent_width + autocmd! + autocmd BufNewFile,BufRead *.sv let b:verilog_indent_width=4 + augroup END +< +Another example that uses a different configuration for files inside a +specific folder: +> + let g:verilog_indent_width=2 + augroup verilog_indent_width + autocmd! + autocmd BufNewFile,BufRead */test/*.sv let b:verilog_indent_width=4 + augroup END +< +For more information regarding supported patterns check |autocmd-patterns|. + +------------------------------------------------------------------------------ +Why is opening Verilog/SystemVerilog files so slow? + +If you are working with files which are over thousands of lines in length, +then having folding enabled can significantly slow down opening these files. A +workaround is to add the following to your |.vimrc| (adjust variables as you +see fit): +> + augroup systemverilog_settings_2 + au! + " Enable folding for normal size files. Folding is really slow for large files. + au Filetype verilog_systemverilog if line('$') < 2000 + au Filetype verilog_systemverilog let g:verilog_syntax_fold_lst = "all" + au Filetype verilog_systemverilog syntax enable "Trigger fold calculation + au Filetype verilog_systemverilog else + au Filetype verilog_systemverilog let g:verilog_syntax_fold_lst = "" + au Filetype verilog_systemverilog endif + augroup END +< + +============================================================================== +7. History *verilog-history* + +3.0 (2016-05-17) + - Reimplementation of indentation script (Lewis Russell) + - Various improvements to omni-completion scripts + - Add function to control errorformat configuration + - Add first functions for code navigation + - Replace assertion with generic label highlight + - Big revamp of syntax folding + - Add automatic testing for folding and indentation + - Add Travis support for automatic regression checking + - Add vim help + +2.0 (2015-01-07) + - Add matchit configuration + - Implement initial omni-completion + - Add syntax folding support + - Highlight to objects and methods + - Small updates to indentation script + - Add first test files + +1.2 (2010-10-18) + - Added new highlight group for SVA Assertions + - Fixed conflicting function names in indentation script + +1.1 (2006-06-28) + - Added indentation script + +1.0 (2006-06-26) + - Initial release + +============================================================================== +8. Credits *verilog-credits* + +The plugin verilog_systemverilog was originally created by Amit Sethi, with +the original indent script created by Chih-Tsun Huang. The original plugin is +available at the following location: + +http://www.vim.org/scripts/script.php?script_id=1586 + +No license was included with the original files, as such it was assumed it was +released under the Vim |license|. + +This plugin is maintained by Vitor Antunes and released under the Vim +|license|. + +Thanks to the following people for code contributions, feature suggestions, etc: +Lewis Russell +Greg Hilton +decrement +Kit Monisit +Leo Butlero + +============================================================================== + vim: tw=78 ts=8 sw=4 sts=4 et ft=help diff --git a/bundle/verilog/ftdetect/verilog.vim b/bundle/verilog/ftdetect/verilog.vim new file mode 100644 index 000000000..2cff5b774 --- /dev/null +++ b/bundle/verilog/ftdetect/verilog.vim @@ -0,0 +1,4 @@ +" Vim filetype plugin file +" Language: SystemVerilog (superset extension of Verilog) + +au! BufNewFile,BufRead *.v,*.vh,*.vp,*.sv,*.svi,*.svh,*.svp,*.sva setfiletype verilog diff --git a/bundle/verilog/ftplugin/verilog.vim b/bundle/verilog/ftplugin/verilog.vim new file mode 100644 index 000000000..976edddaa --- /dev/null +++ b/bundle/verilog/ftplugin/verilog.vim @@ -0,0 +1,79 @@ +" Vim filetype plugin file +" Language: SystemVerilog (superset extension of Verilog) + +" Only do this when not done yet for this buffer +if exists("b:did_ftplugin") + finish +endif + +" Define include string +setlocal include=^\\s*`include + +" Set omni completion function +setlocal omnifunc=verilog_systemverilog#Complete + +" Store cpoptions +let oldcpo=&cpoptions +set cpo-=C + +" Undo the plugin effect +let b:undo_ftplugin = "setlocal fo< com< tw<" + \ . "| unlet! b:browsefilter b:match_ignorecase b:match_words" + +" Set 'formatoptions' to break comment lines but not other lines, +" and insert the comment leader when hitting or using "o". +setlocal fo-=t fo+=croqlm1 + +" Set 'comments' to format dashed lists in comments. +setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,:// + +" Win32 and GTK can filter files in the browse dialog +if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter") + let b:browsefilter = "" + \ . "Verilog Family Source Files\t*.v;*.vh;*.vp;*.sv;*.svh;*.svi;*.svp\n" + \ . "Verilog Source Files (*.v *.vh)\t*.v;*.vh\n" + \ . "SystemVerilog Source Files (*.sv *.svh *.svi *.sva)\t*.sv;*.svh;*.svi;*.sva\n" + \ . "Protected Files (*.vp *.svp)\t*.vp;*.svp\n" + \ . "All Files (*.*)\t*.*\n" +endif +" Override matchit configurations +if exists("loaded_matchit") + let b:match_ignorecase=0 + let b:match_words= + \ '\:\,' . + \ '\\|\\|\:\,' . + \ '`if\(n\)\?def\>:`elsif\>:`else\>:`endif\>,' . + \ '\:\,' . + \ '\:\,' . + \ '\\s*;\@!$:\,' . + \ '\:\,' . + \ '\:\,' . + \ '\:\,' . + \ '\:\,' . + \ '\:\,' . + \ '\:\,' . + \ '\:\,' . + \ '\:\,' . + \ '\:\,' . + \ '\:\,' . + \ '\:\,' . + \ '\:\,' . + \ '\:\,' . + \ '\:\,' . + \ '\:\,' . + \ '\:\,' . + \ '\:\' +endif + +" Restore cpoptions +let &cpoptions=oldcpo +unlet oldcpo + +" Raise warning if smartindent is defined +if &smartindent + echohl WarningMsg + redraw + echo "Option 'smartindent' should not be used in Verilog syntax, use 'autoindent' instead." +endif + +" vi: set expandtab softtabstop=2 shiftwidth=2: diff --git a/bundle/verilog/indent/verilog.vim b/bundle/verilog/indent/verilog.vim new file mode 100644 index 000000000..43a88656c --- /dev/null +++ b/bundle/verilog/indent/verilog.vim @@ -0,0 +1,451 @@ +" Language: Verilog/SystemVerilog HDL +" +" Credits: +" Originally created by +" Lewis Russell +" +" Inspired from script originally created by +" Chih-Tsun Huang +" + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal indentexpr=GetVerilogSystemVerilogIndent() +setlocal indentkeys=!^F,o,O,0),0},=begin,=end,=join,=endcase,=join_any,=join_none +setlocal indentkeys+==endmodule,=endfunction,=endtask,=endspecify +setlocal indentkeys+==endclass,=endpackage,=endsequence,=endclocking +setlocal indentkeys+==endinterface,=endgroup,=endprogram,=endproperty +setlocal indentkeys+==endgenerate,=endchecker,=endconfig,=endprimitive,=endtable +setlocal indentkeys+==`else,=`endif +setlocal indentkeys+=; + +let s:vlog_open_statement = '\([<>:!=?&|^%/*+]\|-[^>]\)' +let s:vlog_end_statement = ')\s*;' +let s:vlog_comment = '\(//.*\|/\*.*\*/\)' +let s:vlog_macro = '`\k\+\((.*)\)\?\s*$' +let s:vlog_statement = '.*;\s*$\|'. s:vlog_macro +let s:vlog_sens_list = '\(@\s*(.*)\)' +let s:vlog_always = '\\s*' . s:vlog_sens_list . '\?' +let s:vlog_method = '^\(\s*pure\s\+virtual\|\s*extern\)\@!.*\<\(function\|task\)\>\s\+\(\[.*\]\s*\)\?\w\+' + +let s:vlog_block_start = '\<\(begin\|case\|^\s*fork\)\>\|{\|(' +let s:vlog_block_end = '\<\(end\|endcase\|join\(_all\|_none\)\?\)\>\|}\|)' + +let s:vlog_module = '\<\(extern\s\+\)\@' +let s:vlog_interface = '\(virtual\s\+\)\@\s*\(\\)\@!\w\+.*[^,]$' +let s:vlog_package = '\' +let s:vlog_covergroup = '\' +let s:vlog_program = '\' +let s:vlog_generate = '\' +let s:vlog_class = '\<\(typedef\s\+\)\@' +let s:vlog_property = g:verilog_syntax['property'][0]['match_start'] +let s:vlog_sequence = g:verilog_syntax['sequence'][0]['match_start'] +let s:vlog_clocking = g:verilog_syntax['clocking'][0]['match_start'] +let s:vlog_preproc = '^\s*`ifn\?def\>' +let s:vlog_define = '^\s*`define\>' + +let s:vlog_case = '\\s*(' +let s:vlog_join = '\' + +let s:vlog_block_decl = '\(\<\(while\|if\|foreach\|for\)\>\s*(\)\|\<\(else\|do\)\>\|' . s:vlog_always + +let s:vlog_context_end = '\\|`endif\>' + +let s:vlog_assign = '\([^=!]=\([^=]\|$\)\|return\||[-=]>\)' +let s:vlog_conditional = '?.*:.*$' + +" Only define the function once. +if exists("*GetVerilogSystemVerilogIndent") + finish +endif + +set cpo-=C + +function! GetVerilogSystemVerilogIndent() + + let s:verilog_disable_indent = verilog#VariableGetValue('verilog_disable_indent_lst') + + if verilog#VariableExists('verilog_indent_width') + let s:offset = verilog#VariableGetValue('verilog_indent_width') + else + let s:offset = &sw + endif + + " At the start of the file use zero indent. + if v:lnum == 1 + return 0 + endif + + let s:curr_line = getline(v:lnum) + + if s:curr_line =~ '^\s*)' + let l:extra_offset = 0 + if s:curr_line =~ '^\s*'.s:vlog_end_statement.'\s*$' && + \ index(s:verilog_disable_indent, 'eos') < 0 + let l:extra_offset = s:offset + endif + call verilog#Verbose("Indenting )") + return indent(s:SearchForBlockStart('(', '', ')', v:lnum, 0)) + l:extra_offset + elseif s:curr_line =~ '^\s*}' + call verilog#Verbose("Indenting }") + return indent(s:SearchForBlockStart('{', '', '}', v:lnum, 0)) + endif + + " Reset indent for end blocks. + if s:curr_line =~ '^\s*\' + return indent(s:SearchBackForPattern('\' , v:lnum)) + elseif s:curr_line =~ '^\s*\' + return indent(s:SearchBackForPattern('\' , v:lnum)) + elseif s:curr_line =~ '^\s*\' + return indent(s:SearchBackForPattern('\' , v:lnum)) + elseif s:curr_line =~ '^\s*\' + return indent(s:SearchBackForPattern('\' , v:lnum)) + elseif s:curr_line =~ '^\s*\' + return indent(s:SearchBackForPattern('\' , v:lnum)) + elseif s:curr_line =~ '^\s*\' + return indent(s:SearchBackForPattern('\' , v:lnum)) + elseif s:curr_line =~ '^\s*\' + return indent(s:SearchBackForPattern('\', v:lnum)) + elseif s:curr_line =~ '^\s*\' + return indent(s:SearchBackForPattern('\', v:lnum)) + elseif s:curr_line =~ '^\s*\' + return indent(s:SearchBackForPattern('\', v:lnum)) + elseif s:curr_line =~ '^\s*\' + return indent(s:SearchBackForPattern('\' , v:lnum)) + elseif s:curr_line =~ '^\s*\' + return indent(s:SearchBackForPattern('\' , v:lnum)) + elseif s:curr_line =~ '^\s*\' + return indent(s:SearchForBlockStart('\', '', '\', v:lnum, 0)) + elseif s:curr_line =~ '^\s*\' + return indent(s:SearchForBlockStart('\' , '', '\' , v:lnum, 0)) + elseif s:curr_line =~ '^\s*\' + return indent(s:SearchForBlockStart('\' , '', '\' , v:lnum, 1)) + elseif s:curr_line =~ '^\s*\' + return indent(s:SearchForBlockStart(s:vlog_case , '', '\' , v:lnum, 0)) + endif + endif + + if s:curr_line =~ '^\s*\\s*(.*'.s:vlog_end_statement + return indent(s:SearchForBlockStart('\', '', '\\s*(.*'.s:vlog_end_statement, v:lnum, 1)) + elseif s:curr_line =~ '^\s*`\(endif\|else\|elsif\)\>' + return indent(s:SearchForBlockStart(s:vlog_preproc, '`else\>\|`elsif\>', '`endif\>', v:lnum, 1)) + elseif s:curr_line =~ '^\s*' . s:vlog_join + return indent(s:SearchForBlockStart('^\s*\', '', s:vlog_join, v:lnum, 1)) + endif + + if s:InsideSynPattern('verilogDefine', v:lnum) && s:curr_line !~ s:vlog_define + return (indent(s:SearchBackForPattern(s:vlog_define, v:lnum)) + s:offset) + endif + + if s:curr_line =~ '^\s*'.s:vlog_comment.'\s*$' && + \ getline(v:lnum + 1) =~ '^\s*else' + return indent(v:lnum + 1) + endif + + if s:curr_line =~ s:vlog_statement && + \ getline(v:lnum - 1) =~ '^\s*\(end\s*\)\?else\s*$' + return indent(v:lnum - 1) + s:offset + endif + + return s:GetContextIndent() + +endfunction + +function! s:GetLineStripped(lnum) + if s:IsComment(a:lnum) + return "" + endif + + let l:temp = getline(a:lnum) + + " Remove inline comments unless the whole line is a comment + if l:temp !~ '^\s*'.s:vlog_comment.'\s*$' + let l:temp = substitute(l:temp, '/\*.\{-}\*/\|//.*', '', 'g') + endif + + " Remove strings + return substitute(l:temp, '".\{-}"', '""', 'g') +endfunction + +function! s:SearchBackForPattern(pattern, current_line_no) + let l:lnum = a:current_line_no + + while l:lnum > 0 + let l:lnum = search(a:pattern, 'bW') + if getline(l:lnum) !~ s:vlog_comment + call verilog#Verbose("Reset indent for context end -> " . a:keyword) + return l:lnum + endif + endwhile + +endfunction + +" For any kind of block with a provided end pattern and start pattern, return the +" line of the start of the block. +function! s:SearchForBlockStart(start_wd, mid_wd, end_wd, current_line_no, skip_start_end) + call cursor(a:current_line_no, 1) + + " Detect whether the cursor is on a comment. + let l:skip_arg = 'synIDattr(synID(".", col("."), 0), "name") == "verilogComment"' + let l:skip_arg .= ' || synIDattr(synID(".", col("."), 0), "name") == "verilogString"' + + if a:skip_start_end == 1 + let l:skip_arg = + \ l:skip_arg." || getline('.') =~ '".a:end_wd.'.\{-}'.a:start_wd."'" + endif + + let l:lnum = searchpair(a:start_wd, a:mid_wd, a:end_wd, 'bnW', l:skip_arg) + call verilog#Verbose('SearchForBlockStart: returning l:lnum ' . l:lnum) + return l:lnum +endfunction + +" Calculates the current line's indent taking into account its context +" +" It checks all lines before the current and when it finds an indenting +" context adds an s:offset to its indent value. Extra indent offset +" related with open statement, for example, are stored in l:open_offset +" to caculate the final indent value. +function! s:GetContextIndent() + let l:bracket_level = 0 + let l:cbracket_level = 0 + + let l:lnum = v:lnum + let l:oneline_mode = 1 + let l:look_for_open_statement = 1 + let l:look_for_open_assign = 0 + let l:open_offset = 0 + + " Loop that searches up the file to build a context and determine the correct + " indentation. + while l:lnum > 1 + + let l:lnum = prevnonblank(l:lnum - 1) + let l:line = getline(l:lnum) + + " Never use comments to determine indentation. + if l:line =~ '^\s*' . s:vlog_comment + continue + endif + + let l:line = s:GetLineStripped(l:lnum) + + if l:line == "" + continue + endif + + call verilog#Verbose("GetContextIndent:" . l:lnum . ": " . l:line) + + if l:look_for_open_statement == 1 + if l:line =~ s:vlog_open_statement . '\s*$' && + \ l:line !~ '/\*\s*$' || + \ s:curr_line =~ '^\s*' . s:vlog_open_statement && + \ s:curr_line !~ '^\s*/\*' && + \ s:curr_line !~ s:vlog_comment && !s:IsComment(v:lnum) || + \ l:line =~ '\' && s:InsideSynPattern("verilogExpression", l:lnum, "$") + let l:open_offset = s:offset + call verilog#Verbose("Increasing indent for an open statement.") + if (!verilog#VariableExists("verilog_indent_assign_fix")) + let l:look_for_open_assign = 1 + endif + endif + let l:look_for_open_statement = 0 + endif + + if l:look_for_open_assign == 1 + if s:curr_line !~ s:vlog_conditional && + \ l:line =~ s:vlog_conditional && + \ index(s:verilog_disable_indent, 'conditional') < 0 + " Return the length of the last line up to the first character after the + " first '?' + return len(substitute(l:line, '?\s*\zs.*', '', "")) + endif + " Search for assignments (=, <=) that don't end in ";" + if l:line =~ s:vlog_assign . '[^;]*$' && (!s:InsideAssign(l:lnum)) + if l:line !~ s:vlog_assign . '\s*$' + " If there are values after the assignment, then use that column as + " the indentation of the open statement. + let l:assign = substitute(l:line, s:vlog_assign .'\s*\zs.*', '', "") + let l:assign_offset = len(l:assign) + call verilog#Verbose( + "Increasing indent for an open assignment with values (by " . l:assign_offset .")." + ) + else + " If the assignment is empty, simply increment the indent by one + " level. + let l:assign_offset = indent(l:lnum) + s:offset + call verilog#Verbose( + "Increasing indent for an empty open assignment (by " . l:assign_offset .")." + ) + endif + return l:assign_offset + endif + endif + + if l:line =~ '\' && l:line !~ '\.*\' + call verilog#Verbose("Inside a 'begin end' block.") + return indent(l:lnum) + s:offset + l:open_offset + elseif l:line =~ '^\s*\' + call verilog#Verbose("Inside a 'fork join' block.") + return indent(l:lnum) + s:offset + l:open_offset + elseif l:line =~ s:vlog_case + call verilog#Verbose("Inside a 'case' block.") + return indent(l:lnum) + s:offset + l:open_offset + endif + + " If we hit an 'end', 'endcase' or 'join', skip past the whole block. + if l:line =~ '\' && l:line !~ '\.*\' && l:line !~ '\\s*$' + let l:lnum = s:SearchForBlockStart('\', '', '\', l:lnum, 1) + let l:oneline_mode = 0 + let l:line = s:GetLineStripped(l:lnum) + endif + + if l:line =~ s:vlog_join + let l:lnum = s:SearchForBlockStart('^\s*\', '', s:vlog_join, l:lnum, 1) + let l:oneline_mode = 0 + let l:line = s:GetLineStripped(l:lnum) + endif + + if l:line =~ '\' + let l:lnum = s:SearchForBlockStart(s:vlog_case, '', '\', l:lnum, 1) + let l:oneline_mode = 0 + let l:line = s:GetLineStripped(l:lnum) + endif + + " Store end-of-statement indent level in case this is an instance + if l:line =~ s:vlog_end_statement + let l:instance_indent = indent(l:lnum) + if index(s:verilog_disable_indent, 'eos') < 0 + let l:instance_indent -= s:offset + endif + call verilog#Verbose("Found possible end of instance on line ".l:lnum." with level ".l:instance_indent) + endif + + " If a instance port connection is found, then return previously detected instance indent level + if l:line =~ '^\s*\.\k' && exists('l:instance_indent') + call verilog#Verbose("Found instance at line ".l:lnum.". Returning previously stored indent level ".l:instance_indent) + return l:instance_indent + endif + + if l:line =~ '[()]' + let l:bracket_level += + \ s:CountMatches(l:line, ')') - s:CountMatches(l:line, '(') + if l:bracket_level < 0 + call verilog#Verbose("Inside a '()' block.") + return indent(l:lnum) + s:offset + endif + endif + + if l:line =~ '[{}]' + let l:cbracket_level += + \ s:CountMatches(l:line, '}') - s:CountMatches(l:line, '{') + if l:cbracket_level < 0 + call verilog#Verbose("Inside a '{}' block.") + return indent(l:lnum) + s:offset + l:open_offset + endif + endif + + if l:oneline_mode == 1 && l:line =~ s:vlog_statement + let l:oneline_mode = 0 + elseif l:oneline_mode == 1 && l:line =~ '\.*\' + call verilog#Verbose("'begin'..'end' pair.") + return indent(l:lnum) + elseif l:oneline_mode == 1 && l:line =~ s:vlog_block_decl && l:line !~ '\.*\' + if s:curr_line =~ '^\s*\' + call verilog#Verbose("Standalone 'begin' after block declaration.") + return indent(l:lnum) + elseif s:curr_line =~ '^\s*{\s*$' && l:cbracket_level == 0 + call verilog#Verbose("Standalone '{' after block declaration.") + return indent(l:lnum) + elseif s:curr_line =~ '^\s*(\s*$' && l:bracket_level == 0 + call verilog#Verbose("Standalone '(' after block declaration.") + return indent(l:lnum) + else + call verilog#Verbose("Indenting a single line block.") + return indent(l:lnum) + s:offset + l:open_offset + endif + elseif s:curr_line =~ '^\s*else' && l:line =~ '\<\(if\|assert\)\>\s*(.*)' + call verilog#Verbose("'else' of 'if' or 'assert'.") + return indent(l:lnum) + endif + + if l:line =~ s:vlog_module + return s:GetContextStartIndent("module" , l:lnum) + l:open_offset + elseif l:line =~ s:vlog_interface + return s:GetContextStartIndent("interface" , l:lnum) + l:open_offset + elseif l:line =~ s:vlog_class + return s:GetContextStartIndent("class" , l:lnum) + l:open_offset + elseif l:line =~ s:vlog_package + return s:GetContextStartIndent("package" , l:lnum) + l:open_offset + elseif l:line =~ s:vlog_covergroup + return s:GetContextStartIndent("covergroup", l:lnum) + l:open_offset + elseif l:line =~ s:vlog_program + return s:GetContextStartIndent("program" , l:lnum) + l:open_offset + elseif l:line =~ s:vlog_generate + return s:GetContextStartIndent("generate" , l:lnum) + l:open_offset + elseif l:line =~ s:vlog_sequence + return s:GetContextStartIndent("sequence" , l:lnum) + l:open_offset + elseif l:line =~ s:vlog_clocking + return s:GetContextStartIndent("clocking" , l:lnum) + l:open_offset + elseif l:line =~ s:vlog_property + return s:GetContextStartIndent("property" , l:lnum) + l:open_offset + elseif l:line =~ s:vlog_method && s:InsideSynPattern('verilog\(Task\|Function\)', l:lnum, "$") + return s:GetContextStartIndent("method" , l:lnum) + l:open_offset + elseif l:line =~ s:vlog_preproc + return s:GetContextStartIndent("preproc" , l:lnum) + l:open_offset + elseif l:line =~ s:vlog_context_end + call verilog#Verbose("After the end of a context.") + return indent(l:lnum) + endif + + endwhile + + " Return any calculated extra offset if no indenting context was found + return l:open_offset +endfunction + +function! s:GetContextStartIndent(name, lnum) + call verilog#Verbose("Inside a " . a:name . ".") + if index(s:verilog_disable_indent, a:name) >= 0 + return indent(a:lnum) + else + return indent(a:lnum) + s:offset +endfunction + +function! s:CountMatches(line, pattern) + return len(split(a:line, a:pattern, 1)) - 1 +endfunction + +function! s:IsComment(lnum) + return synIDattr(synID(a:lnum, 1, 0), "name") == "verilogComment" +endfunction + +function! s:InsideAssign(lnum) + return synIDattr(synID(a:lnum, 1, 0), "name") == "verilogAssign" +endfunction + +function! s:InsideSynPattern(pattern, lnum, ...) + " Check for optional column number/pattern + if a:0 >= 1 + let l:cnum = a:1 + else + let l:cnum = 1 + endif + " Determine column number if using a pattern + if type(l:cnum) != 0 + let l:cnum = col([a:lnum, l:cnum]) + endif + + for id in synstack(a:lnum, l:cnum) + if synIDattr(id, "name") =~ a:pattern + return 1 + endif + endfor + return 0 +endfunction + +" vi: sw=2 sts=2: diff --git a/bundle/verilog/plugin/verilog.vim b/bundle/verilog/plugin/verilog.vim new file mode 100644 index 000000000..ffb800238 --- /dev/null +++ b/bundle/verilog/plugin/verilog.vim @@ -0,0 +1,215 @@ +" Global plugin settings +let g:verilog_disable_indent_lst="eos" + +" Command definitions +command! -nargs=* VerilogErrorFormat call verilog#VerilogErrorFormat() +command! VerilogFollowInstance call verilog#FollowInstanceTag(line('.'), col('.')) +command! VerilogReturnInstance call verilog#ReturnFromInstanceTag() +command! VerilogFollowPort call verilog#FollowInstanceSearchWord(line('.'), col('.')) +command! VerilogGotoInstanceStart call verilog#GotoInstanceStart(line('.'), col('.')) +command! -nargs=+ -complete=customlist,verilog#CompleteCommand + \ VerilogFoldingAdd + \ call verilog#PushToVariable('verilog_syntax_fold_lst', '') +command! -nargs=+ -complete=customlist,verilog#CompleteCommand + \ VerilogFoldingRemove + \ call verilog#PopFromVariable('verilog_syntax_fold_lst', '') +command! -nargs=+ -complete=customlist,verilog#CompleteCommand + \ VerilogDisableIndentAdd + \ call verilog#PushToVariable('verilog_disable_indent_lst', '') +command! -nargs=+ -complete=customlist,verilog#CompleteCommand + \ VerilogDisableIndentRemove + \ call verilog#PopFromVariable('verilog_disable_indent_lst', '') +command! -nargs=+ -complete=customlist,verilog#CompleteCommand + \ VerilogErrorUVMAdd + \ call verilog#PushToVariable('verilog_efm_uvm_lst', '') +command! -nargs=+ -complete=customlist,verilog#CompleteCommand + \ VerilogErrorUVMRemove + \ call verilog#PopFromVariable('verilog_efm_uvm_lst', '') + +" Configure tagbar +if !exists("g:tagbar_type_verilog") + " This requires a recent version of universal-ctags + let g:tagbar_type_verilog = { + \ 'ctagstype' : 'SystemVerilog', + \ 'kinds' : [ + \ 'b:blocks:1:1', + \ 'c:constants:1:0', + \ 'e:events:1:0', + \ 'f:functions:1:1', + \ 'm:modules:0:1', + \ 'n:nets:1:0', + \ 'p:ports:1:0', + \ 'r:registers:1:0', + \ 't:tasks:1:1', + \ 'A:assertions:1:1', + \ 'C:classes:0:1', + \ 'V:covergroups:0:1', + \ 'I:interfaces:0:1', + \ 'M:modport:0:1', + \ 'K:packages:0:1', + \ 'P:programs:0:1', + \ 'R:properties:0:1', + \ 'T:typedefs:0:1' + \ ], + \ 'sro' : '.', + \ 'kind2scope' : { + \ 'm' : 'module', + \ 'b' : 'block', + \ 't' : 'task', + \ 'f' : 'function', + \ 'C' : 'class', + \ 'V' : 'covergroup', + \ 'I' : 'interface', + \ 'K' : 'package', + \ 'P' : 'program', + \ 'R' : 'property' + \ }, + \ } +endif + +" Define regular expressions for Verilog/SystemVerilog statements +let s:verilog_function_task_dequalifier = + \ '\%(' + \ . '\%(' + \ . 'extern\s\+\%(\%(pure\s\+\)\?virtual\s\+\)\?' + \ . '\|' + \ . 'pure\s\+virtual\s\+' + \ . '\|' + \ . 'import\s\+\"DPI\%(-[^\"]\+\)\?\"\s\+\%(context\s\+\)\?' + \ . '\)' + \ . '\%(\%(static\|protected\|local\)\s\+\)\?' + \ .'\)' + +let g:verilog_syntax = { + \ 'assign' : [{ + \ 'match_start' : '[^><=!]\zs<\?=\%(=\)\@!', + \ 'match_end' : '[;,]', + \ 'highlight' : 'verilogOperator', + \ 'syn_argument': 'transparent contains=@verilogBaseCluster', + \ }], + \ 'attribute' : [{ + \ 'match_start' : '\%(@\s*\)\@', + \ 'match_end' : '\', + \ 'syn_argument': 'transparent', + \ }], + \ 'block_named' : [{ + \ 'match_start' : '\\s*:\s*\w\+', + \ 'match_end' : '\', + \ 'syn_argument': 'transparent', + \ }], + \ 'class' : [{ + \ 'match_start' : '\', + \ 'match_end' : '\', + \ 'highlight' : 'verilogStatement', + \ 'syn_argument': 'transparent', + \ }], + \ 'clocking' : [{ + \ 'match_start' : '\', + \ 'match_end' : '\', + \ 'highlight' : 'verilogStatement', + \ 'syn_argument': 'transparent keepend', + \ }], + \ 'comment' : [{ + \ 'match' : '//.*', + \ 'syn_argument': 'contains=verilogTodo,verilogDirective,@Spell' + \ }, + \ { + \ 'match_start' : '/\*', + \ 'match_end' : '\*/', + \ 'syn_argument': 'contains=verilogTodo,verilogDirective,@Spell keepend extend' + \ }], + \ 'covergroup' : [{ + \ 'match_start' : '\', + \ 'match_end' : '\', + \ 'highlight' : 'verilogStatement', + \ 'syn_argument': 'transparent keepend', + \ }], + \ 'define' : [{ + \ 'match_start' : '`define\>', + \ 'match_end' : '\(\\\s*\)\@', + \ 'match_end' : '\', + \ 'highlight' : 'verilogStatement', + \ 'syn_argument': 'transparent contains=ALLBUT,verilogFunction,verilogTask', + \ }], + \ 'expression' : [{ + \ 'match_start' : '(', + \ 'match_end' : ')', + \ 'highlight' : 'verilogOperator', + \ 'syn_argument': 'transparent contains=@verilogBaseCluster,verilogExpression,verilogStatement', + \ 'no_fold' : '1', + \ }], + \ 'function' : [{ + \ 'match_start' : s:verilog_function_task_dequalifier.'\@', + \ 'match_end' : '\', + \ 'highlight' : 'verilogStatement', + \ 'syn_argument': 'transparent keepend', + \ }], + \ 'instance' : [{ + \ 'match_start' : '^\s*\zs\w\+\%(\s*#\s*(\%(.*)\s*\w\+\s*;\)\@!\|\s\+\%(\\)\@!\w\+\s*(\)', + \ 'match_end' : ';', + \ 'syn_argument': 'transparent keepend contains=verilogListParam,verilogStatement,@verilogBaseCluster', + \ }], + \ 'interface' : [{ + \ 'match_start' : '\%(\\%(\s\+class\)\@!', + \ 'match_end' : '\', + \ 'highlight' : 'verilogStatement', + \ 'syn_argument': 'transparent keepend', + \ }], + \ 'module' : [{ + \ 'match_start' : '\<\%(extern\s\+\)\@', + \ 'match_end' : '\', + \ 'highlight' : 'verilogStatement', + \ 'syn_argument': 'transparent keepend contains=ALLBUT,verilogInterface', + \ }], + \ 'property' : [{ + \ 'match_start' : '\<\%(\%(assert\|assume\|cover\|restrict\)\s\+\)\@', + \ 'match_end' : '\', + \ 'highlight' : 'verilogStatement', + \ 'syn_argument': 'transparent keepend', + \ }], + \ 'prototype' : [{ + \ 'match' : s:verilog_function_task_dequalifier.'\@<=\<\%(task\|function\)\>', + \ }], + \ 'sequence' : [{ + \ 'match_start' : '\<\%(cover\s\+\)\@', + \ 'match_end' : '\', + \ 'highlight' : 'verilogStatement', + \ 'syn_argument': 'transparent keepend', + \ }], + \ 'specify' : [{ + \ 'match_start' : '\', + \ 'match_end' : '\', + \ 'highlight' : 'verilogStatement', + \ 'syn_argument': 'transparent keepend', + \ }], + \ 'statement' : [{ + \ 'match' : '\<\%(interface\|property\|sequence\|class\)\>', + \ }], + \ 'task' : [{ + \ 'match_start' : s:verilog_function_task_dequalifier.'\@', + \ 'match_end' : '\', + \ 'highlight' : 'verilogStatement', + \ 'syn_argument': 'transparent keepend', + \ }], + \ 'typedef' : [{ + \ 'match_start' : '\', + \ 'match_end' : '\ze;', + \ 'highlight' : 'verilogTypeDef', + \ 'syn_argument': 'transparent keepend contains=ALLBUT,verilogClass', + \ }], + \ } + +" vi: set expandtab softtabstop=4 shiftwidth=4: diff --git a/bundle/verilog/syntax/verilog_systemverilog.vim b/bundle/verilog/syntax/verilog_systemverilog.vim new file mode 100644 index 000000000..f49521746 --- /dev/null +++ b/bundle/verilog/syntax/verilog_systemverilog.vim @@ -0,0 +1,404 @@ +" Vim syntax file +" Language: SystemVerilog (superset extension of Verilog) + +" Extends Verilog syntax +" Requires $VIMRUNTIME/syntax/verilog.vim to exist + +" For version 5.x: Clear all syntax items +" For version 6.x: Quit when a syntax file was already loaded +if version < 600 + syntax clear +elseif exists("b:current_syntax") + finish +endif + +" Override 'iskeyword' +if version >= 600 + setlocal iskeyword=@,48-57,_,192-255 +else + set iskeyword=@,48-57,_,192-255 +endif + +" Store cpoptions +let oldcpo=&cpoptions +set cpo-=C + +syn sync lines=1000 + +"########################################################## +" SystemVerilog Syntax +"########################################################## + +syn keyword verilogStatement always and assign automatic buf +syn keyword verilogStatement bufif0 bufif1 cell cmos +syn keyword verilogStatement config deassign defparam design +syn keyword verilogStatement disable edge endconfig +syn keyword verilogStatement endgenerate +syn keyword verilogStatement endprimitive endtable +syn keyword verilogStatement event force fork join +syn keyword verilogStatement join_any join_none forkjoin +syn keyword verilogStatement generate genvar highz0 highz1 ifnone +syn keyword verilogStatement incdir include initial inout input +syn keyword verilogStatement instance integer large liblist +syn keyword verilogStatement library localparam macromodule medium +syn keyword verilogStatement nand negedge nmos nor +syn keyword verilogStatement noshowcancelled not notif0 notif1 or +syn keyword verilogStatement output parameter pmos posedge primitive +syn keyword verilogStatement pull0 pull1 pulldown pullup +syn keyword verilogStatement pulsestyle_onevent pulsestyle_ondetect +syn keyword verilogStatement rcmos real realtime reg release +syn keyword verilogStatement rnmos rpmos rtran rtranif0 rtranif1 +syn keyword verilogStatement scalared showcancelled signed small +syn keyword verilogStatement specparam strong0 strong1 +syn keyword verilogStatement supply0 supply1 table time tran +syn keyword verilogStatement tranif0 tranif1 tri tri0 tri1 triand +syn keyword verilogStatement trior trireg unsigned use vectored wait +syn keyword verilogStatement wand weak0 weak1 wire wor xnor xor +syn keyword verilogStatement semaphore mailbox + +syn keyword verilogStatement always_comb always_ff always_latch +syn keyword verilogStatement checker endchecker +syn keyword verilogStatement virtual local const protected +syn keyword verilogStatement package endpackage +syn keyword verilogStatement rand randc constraint randomize +syn keyword verilogStatement with inside dist +syn keyword verilogStatement randcase +syn keyword verilogStatement randsequence +syn keyword verilogStatement get_randstate set_randstate +syn keyword verilogStatement srandom +syn keyword verilogStatement logic bit byte time +syn keyword verilogStatement int longint shortint +syn keyword verilogStatement struct packed +syn keyword verilogStatement final +syn keyword verilogStatement import +syn keyword verilogStatement context pure +syn keyword verilogStatement void shortreal chandle string +syn keyword verilogStatement modport +syn keyword verilogStatement cover coverpoint +syn keyword verilogStatement program endprogram +syn keyword verilogStatement bins binsof illegal_bins ignore_bins +syn keyword verilogStatement alias matches solve static assert +syn keyword verilogStatement assume before expect bind +syn keyword verilogStatement extends tagged extern +syn keyword verilogStatement first_match throughout timeprecision +syn keyword verilogStatement timeunit priority type union +syn keyword verilogStatement uwire var cross ref wait_order intersect +syn keyword verilogStatement wildcard within +syn keyword verilogStatement triggered +syn keyword verilogStatement std +syn keyword verilogStatement accept_on eventually global implements implies +syn keyword verilogStatement interconnect let nettype nexttime reject_on restrict soft +syn keyword verilogStatement s_always s_eventually s_nexttime s_until s_until_with +syn keyword verilogStatement strong sync_accept_on sync_reject_on unique unique0 +syn keyword verilogStatement until until_with untyped weak + +syn keyword verilogTypeDef enum + +syn keyword verilogConditional iff +syn keyword verilogConditional if else case casex casez default endcase + +syn keyword verilogRepeat forever repeat while for +syn keyword verilogRepeat return break continue +syn keyword verilogRepeat do while foreach + +syn match verilogGlobal "`[a-zA-Z_][a-zA-Z0-9_$]\+" +syn match verilogGlobal "$[a-zA-Z0-9_$]\+" + +if !exists('g:verilog_disable_constant_highlight') + syn match verilogConstant "\<[A-Z][A-Z0-9_$]*\>" +endif + +syn match verilogNumber "\(\d\+\)\?'[sS]\?[bB]\s*[0-1_xXzZ?]\+" +syn match verilogNumber "\(\d\+\)\?'[sS]\?[oO]\s*[0-7_xXzZ?]\+" +syn match verilogNumber "\(\d\+\)\?'[sS]\?[dD]\s*[0-9_xXzZ?]\+" +syn match verilogNumber "\(\d\+\)\?'[sS]\?[hH]\s*[0-9a-fA-F_xXzZ?]\+" +syn match verilogNumber "\<[+-]\?[0-9_]\+\(\.[0-9_]*\)\?\(e[0-9_]*\)\?\>" +syn match verilogNumber "\<\d[0-9_]*\(\.[0-9_]\+\)\=\([fpnum]\)\=s\>" +syn keyword verilogNumber 1step + +syn keyword verilogTodo contained TODO FIXME + +syn match verilogOperator "[&|~>= 704 + syn match verilogMethod "\(\(\s\|[(/]\|^\)\.\)\@2\ze\s*:\s*\<\(assert\|assume\|cover\(point\)\?\|cross\)\>" +if v:version >= 704 + syn match verilogLabel "\(\<\(begin\|end\)\>\s*:\s*\)\@20<=\<\k\+\>" +else + syn match verilogLabel "\(\<\(begin\|end\)\>\s*:\s*\)\@<=\<\k\+\>" +endif + +syn keyword verilogObject super null this +syn match verilogObject "\<\w\+\ze\(::\|\.\)" contains=verilogNumber + + +" Create syntax definition from g:verilog_syntax dictionary +function! s:SyntaxCreate(name, verilog_syntax) + if exists('a:verilog_syntax[a:name]') + let verilog_syn_region_name = 'verilog'.substitute(a:name, '.*', '\u&', '') + for entry in a:verilog_syntax[a:name] + if exists('entry["match"]') + " syn-match definitions + let match = entry["match"] + let verilog_syn_match_cmd = 'syn match '.verilog_syn_region_name.' "'.match.'"' + + if exists('entry["syn_argument"]') + let verilog_syn_match_cmd .= ' '.entry["syn_argument"] + endif + + execute verilog_syn_match_cmd + elseif exists('entry["match_start"]') && exists('entry["match_end"]') + " syn-region definitions + + let region_start = entry["match_start"] + let region_end = entry["match_end"] + + if verilog_systemverilog#VariableExists('verilog_quick_syntax') + execute 'syn keyword verilogStatement '.region_start.' '.region_end + else + let verilog_syn_region_cmd = 'syn region '.verilog_syn_region_name + + if exists('entry["highlight"]') + let verilog_syn_region_cmd .= ' matchgroup='.entry["highlight"] + endif + + let verilog_syn_region_cmd .= + \ ' start="'.region_start.'"' + \ .' end="'.region_end.'"' + + " Always skip inline comments + if a:name != "comment" && exists('a:verilog_syntax["comment"]') + let verilog_syn_region_cmd .= ' skip="' + for comment_entry in a:verilog_syntax["comment"] + if exists('comment_entry["match"]') + let verilog_syn_region_cmd .= comment_entry["match"] + endif + endfor + let verilog_syn_region_cmd .= '"' + endif + + if exists('entry["syn_argument"]') + let verilog_syn_region_cmd .= ' '.entry["syn_argument"] + endif + + if !exists('entry["no_fold"]') + if (index(s:verilog_syntax_fold, a:name) >= 0 || index(s:verilog_syntax_fold, "all") >= 0) + let verilog_syn_region_cmd .= ' fold' + endif + endif + + execute verilog_syn_region_cmd + endif + elseif exists('entry["cluster"]') + " syn-cluster definitions + + execute 'syn cluster '.verilog_syn_region_name.' contains='.entry["cluster"] + elseif exists('entry["keyword"]') + " syn-cluster definitions + + execute 'syn keyword '.verilog_syn_region_name.' '.entry["keyword"] + else + echoerr 'Incorrect syntax defintion for '.a:name + endif + endfor + end +endfunction + +" Only enable folding if verilog_syntax_fold_lst is defined +let s:verilog_syntax_fold=verilog_systemverilog#VariableGetValue("verilog_syntax_fold_lst") + +" Syntax priority list +let s:verilog_syntax_order = [ + \ 'baseCluster', + \ 'statement', + \ 'assign', + \ 'attribute', + \ 'instance', + \ 'prototype', + \ 'class', + \ 'clocking', + \ 'covergroup', + \ 'define', + \ 'export', + \ 'expression', + \ 'function', + \ 'interface', + \ 'module', + \ 'property', + \ 'sequence', + \ 'specify', + \ 'task', + \ 'typedef', + \ ] + +" Generate syntax definitions for supported types +for name in s:verilog_syntax_order + call s:SyntaxCreate(name, g:verilog_syntax) +endfor + +if index(s:verilog_syntax_fold, "block_nested") >= 0 || index(s:verilog_syntax_fold, "block_named") >= 0 + if index(s:verilog_syntax_fold, "block_nested") >= 0 + syn region verilogBlock + \ matchgroup=verilogStatement + \ start="\" + \ end="\.*\"ms=s-1,me=s-1 + \ fold + \ transparent + \ contained + \ nextgroup=verilogBlockEnd + \ contains=TOP + syn region verilogBlockEnd + \ matchgroup=verilogStatement + \ start="\.*\" + \ end="\\ze.*\(\\)\@!" + \ fold + \ transparent + \ contained + \ contains=TOP + syn match verilogStatement "\" + else "block_named + syn region verilogBlock + \ matchgroup=verilogStatement + \ start="\" + \ end="\" + \ transparent + \ contained + \ contains=TOP + syn region verilogBlockNamed + \ matchgroup=verilogStatement + \ start="\\ze\s*:\s*\z(\w\+\)" + \ end="\" + \ transparent + \ fold + \ contained + \ contains=TOP + "TODO break up if...else statements + endif + syn region verilogBlockContainer + \ start="\" + \ end="\" + \ skip="/[*/].*" + \ transparent + \ keepend extend + \ contains=verilogBlock,verilogBlockNamed,verilogBlockEnd +elseif index(s:verilog_syntax_fold, "block") >= 0 || index(s:verilog_syntax_fold, "all") >= 0 + syn region verilogBlock + \ matchgroup=verilogStatement + \ start="\" + \ end="\" + \ transparent + \ fold +else + syn keyword verilogStatement begin end +endif + +if index(s:verilog_syntax_fold, "define") >= 0 || index(s:verilog_syntax_fold, "all") >= 0 + syn region verilogIfdef + \ start="`ifn\?def\>" + \ end="^\s*`els\(e\|if\)\>"ms=s-1,me=s-1 + \ fold transparent + \ keepend + \ contained + \ nextgroup=verilogIfdefElse,verilogIfdefEndif + \ contains=TOP + syn region verilogIfdefElse + \ start="`els\(e\|if\)\>" + \ end="^\s*`els\(e\|if\)\>"ms=s-1,me=s-1 + \ fold transparent + \ keepend + \ contained + \ nextgroup=verilogIfdefElse,verilogIfdefEndif + \ contains=TOP + syn region verilogIfdefEndif + \ start="`else\>" + \ end="`endif\>" + \ fold transparent + \ keepend + \ contained + \ contains=TOP + syn region verilogIfdefContainer + \ start="`ifn\?def\>" + \ end="`endif\>" + \ skip="/[*/].*" + \ transparent + \ keepend extend + \ contains=verilogIfdef,verilogIfdefElse,verilogIfdefEndif +endif + +" Generate syntax definitions for comments after other standard syntax +" definitions to guarantee highest priority +for name in ['comment'] + call s:SyntaxCreate(name, g:verilog_syntax) +endfor + +" Generate syntax definitions for custom types last to allow overriding +" standard syntax +if exists('g:verilog_syntax_custom') + for name in keys(g:verilog_syntax_custom) + call s:SyntaxCreate(name, g:verilog_syntax_custom) + endfor +endif + +" Special comments: Synopsys directives +syn match verilogDirective "//\s*synopsys\>.*$" +syn region verilogDirective start="/\*\s*synopsys\>" end="\*/" +syn region verilogDirective start="//\s*synopsys \z(\w*\)begin\>" end="//\s*synopsys \z1end\>" + +syn match verilogDirective "//\s*\$s\>.*$" +syn region verilogDirective start="/\*\s*\$s\>" end="\*/" +syn region verilogDirective start="//\s*\$s dc_script_begin\>" end="//\s*\$s dc_script_end\>" + +"Modify the following as needed. The trade-off is performance versus +"functionality. +syn sync minlines=50 + +" Define the default highlighting. +" For version 5.7 and earlier: only when not done already +" For version 5.8 and later: only when an item doesn't have highlighting yet +if version >= 508 || !exists("did_verilog_syn_inits") + if version < 508 + let did_verilog_syn_inits = 1 + command -nargs=+ HiLink hi link + else + command -nargs=+ HiLink hi def link + endif + + " The default highlighting. + HiLink verilogCharacter Character + HiLink verilogConditional Conditional + HiLink verilogRepeat Repeat + HiLink verilogString String + HiLink verilogTodo Todo + HiLink verilogComment Comment + HiLink verilogConstant Constant + HiLink verilogLabel Tag + HiLink verilogNumber Number + HiLink verilogOperator Special + HiLink verilogPrototype Statement + HiLink verilogStatement Statement + HiLink verilogGlobal Define + HiLink verilogDirective SpecialComment + HiLink verilogEscape Special + HiLink verilogMethod Function + HiLink verilogTypeDef TypeDef + HiLink verilogObject Type + + delcommand HiLink +endif + +let b:current_syntax = "verilog_systemverilog" + +" Restore cpoptions +let &cpoptions=oldcpo + +" vim: sts=4 sw=4 diff --git a/bundle/verilog/test/errorformat.txt b/bundle/verilog/test/errorformat.txt new file mode 100644 index 000000000..7b93e3696 --- /dev/null +++ b/bundle/verilog/test/errorformat.txt @@ -0,0 +1,38 @@ +### iverilog E=5, W=0 +path/file.v:5: syntax error +path/file.v:5: error: Invalid module instantiation +path/file.v:18: syntax error +path/file.v:15: error: Syntax error in instance port expression(s). +path/file.v:47: error: Invalid module instantiation + +### verilator E=2, W=3 +%Warning-ASSIGNDLY: test.v:1: Unsupported: Ignoring delay on this assignment/primitive. +%Warning-DECLFILENAME: test.v:2: Filename 'test' does not match MODULE name: something +%Warning-IMPLICIT: test.v:3: Signal definition not found, creating implicitly: something +%Error: test.v:4: Pin not found: something +%Error: test.v:3:9: syntax error, unexpected or, expecting ',' or ';' + +### ncverilog E=6, W=1 + rcounter <= 10'b11111111111; + | +ncvlog: *W,INTOVF (test.v,17|34): bit overflow during conversion from text [2.5(IEEE)] (10 bits). + assignn out = rcounter; + | +ncvlog: *E,EXPLPA (test.v,23|14): expecting a left parenthesis ('(') [12.1.2][7.1(IEEE)]. +ncsim: *E,ASRTST (filename.sv,769): (time 0 FS) Assertion assertionname has failed +ncsim: *E,TRNULLID: NULL pointer dereference. +File: filename.sv, line = 62, pos = 36 +ncsim: *E,ASRTST (filename.sv,769): (time 0 FS) Assertion assertion_name has failed +ncsim: *E,SOMECADENCEERRORCODE: Message +ncsim: *E,ASRTST (filename.sv,123|12): Reason +ncsim: irun 11.11-s111: Started on May 11, 1111 at 11:11:11 IST + +### spyglass E=1, W=1 +STX_VE_481 Syntax path/file.v 1 Syntax error near ( } ) +[66] UndrivenNUnloaded-ML WARNING Warning path/file.v 1 2 UndrivenNUnloaded-ML : Detected undriven and unloaded(unconnected) net + +### UVM E=2, W=1, L=1 +UVM_FATAL /path/file.sv(5) @ 1000: text +UVM_ERROR /path/file.sv(5) @ 1000: text +UVM_WARNING /path/file.sv(5) @ 1000: text +UVM_INFO /path/file.sv(5) @ 1000: text diff --git a/bundle/verilog/test/folding.v b/bundle/verilog/test/folding.v new file mode 100644 index 000000000..c24c0dda7 --- /dev/null +++ b/bundle/verilog/test/folding.v @@ -0,0 +1,294 @@ +// all +// | all,block_nested +// | | all,block_named + +function f; //<1><1><1> +begin //<2><2><1> + //<2><2><1> +end //<2><2><1> +endfunction : f //<1><1><1> + +task t; //<1><1><1> + //<1><1><1> +begin //<2><2><1> + state = something(); //<2><2><1> + begin : block1 //<3><3><2> + state = 2'b00; //<3><3><2> + if (a <= b) begin //<4><4><2> + begin : block2 //<5><5><3> + end // block2 //<5><5><3> + state = 2'b11; //<4><4><2> + begin //<5><5><2> + end //<5><5><2> + end //<4><4><2> + begin : block3 //<4><4><3> + end // block3 //<4><4><3> + begin //<4><4><2> + end //<4><4><2> + end // block1 //<3><3><2> +end //<2><2><1> + //<1><1><1> +endtask : t //<1><1><1> + +/* //<1><1><1> +* //<1><1><1> +* function in_comment; //<1><1><1> +* //<1><1><1> +* endfunction //<1><1><1> +* //<1><1><1> +*/ //<1><1><1> + +extern function e_func (x, y); //<0><0><0> +extern static function es_func (x, y); //<0><0><0> +extern protected function ep_func (x, y); //<0><0><0> +extern local function el_func (x, y); //<0><0><0> + + pure virtual function pv_func (x); //<0><0><0> + pure virtual static function pvs_func (x); //<0><0><0> + pure virtual protected function pvp_func (x); //<0><0><0> + pure virtual local function pvl_func (x); //<0><0><0> + +extern virtual function ev_func (x); //<0><0><0> +extern virtual static function evs_func (x); //<0><0><0> +extern virtual protected function evp_func (x); //<0><0><0> +extern virtual local function evl_func (x); //<0><0><0> + +extern pure virtual function epv_func (x); //<0><0><0> +extern pure virtual static function epvs_func (x); //<0><0><0> +extern pure virtual protected function epvp_func (x); //<0><0><0> +extern pure virtual local function epvl_func (x); //<0><0><0> + +extern task e_task (x, y); //<0><0><0> +extern static task es_task (x, y); //<0><0><0> +extern protected task ep_task (x, y); //<0><0><0> +extern local task el_task (x, y); //<0><0><0> + + pure virtual task pv_task (x); //<0><0><0> + pure virtual static task pvs_task (x); //<0><0><0> + pure virtual protected task pvp_task (x); //<0><0><0> + pure virtual local task pvl_task (x); //<0><0><0> + +extern virtual task ev_task (x, y); //<0><0><0> +extern virtual static task evs_task (x, y); //<0><0><0> +extern virtual protected task evp_task (x, y); //<0><0><0> +extern virtual local task evl_task (x, y); //<0><0><0> + +extern pure virtual task epv_task (x, y); //<0><0><0> +extern pure virtual static task epvs_task (x, y); //<0><0><0> +extern pure virtual protected task epvp_task (x, y); //<0><0><0> +extern pure virtual local task epvl_task (x, y); //<0><0><0> + + +/** //<1><1><1> +* Static function //<1><1><1> +*/ //<1><1><1> +static function f1; //<1><1><1> +endfunction //<1><1><1> + +specify //<1><1><1> + //<1><1><1> +endspecify //<1><1><1> + +covergroup cov; //<1><1><1> + //<1><1><1> +endgroup //<1><1><1> + +property prop; //<1><1><1> +endproperty //<1><1><1> + +sequence //<1><1><1> +endsequence //<1><1><1> + +// Classes //<0><0><0> +class class_a; //<1><1><1> + //<1><1><1> +endclass : class_a //<1><1><1> + +class class_b; //<1><1><1> + class class_b1; //<2><2><2> + //<2><2><2> + endclass : class_b1 //<2><2><2> + //<1><1><1> + class class_b2; //<2><2><2> + //<2><2><2> + endclass : class_b2 //<2><2><2> +endclass : class_b //<1><1><1> + +interface a; //<1><1><1> + //<1><1><1> + interface class b; //<2><2><2> + endclass : b //<2><2><2> + //<1><1><1> + clocking cb @ (posedge Clk); //<2><2><2> + endclocking : cb //<2><2><2> + //<1><1><1> +endinterface : a //<1><1><1> + +typedef interface class my_itf_class; //<0><0><0> + +`ifdef A //<1><1><1> +reg test; //<1><1><1> + //<1><1><1> +// `ifdef A_1 //<1><1><1> +// //<1><1><1> +// `else //<1><1><1> +// //<1><1><1> +// `endif //<1><1><1> + //<1><1><1> +`else //<1><1><1> + //<1><1><1> +`endif //<1><1><1> + +`ifndef B //<1><1><1> + //<1><1><1> +`elsif C //<1><1><1> + //<1><1><1> +`elsif D //<1><1><1> + //<1><1><1> +`else //<1><1><1> + //<1><1><1> +`endif //<1><1><1> + +`ifdef E //<1><1><1> + //<1><1><1> + `ifndef E_1 //<2><2><2> + //<2><2><2> + `else //<2><2><2> + //<2><2><2> + `endif //<2><2><2> + //<1><1><1> + `ifndef E_2 //<2><2><2> + //<2><2><2> + `elsif E_3 //<2><2><2> + //<2><2><2> + `endif //<2><2><2> + //<1><1><1> +`endif //<1><1><1> + +`ifdef A //<1><1><1> + //<1><1><1> + `ifdef B //<2><2><2> + //<2><2><2> + `else //<2><2><2> + //<2><2><2> + `endif //<2><2><2> + //<1><1><1> +`elsif C //<1><1><1> + //<1><1><1> +`else //<1><1><1> + //<1><1><1> +`endif //<1><1><1> + + +/* //<1><1><1> + `ifdef X //<1><1><1> + //<1><1><1> + `else //<1><1><1> + //<1><1><1> + `endif //<1><1><1> +*/ //<1><1><1> + + module_name #( //<1><1><1> + .PARAM1 (VALUE1) //<1><1><1> + ) //<1><1><1> + instance_name( //<1><1><1> + .port1 (net1), //<1><1><1> + .port2 (net2) //<1><1><1> + ); //<1><1><1> + +module_name instance_name( //<1><1><1> + .port1 (net1), //<1><1><1> + .port2 (net2) //<1><1><1> +); //<1><1><1> + +module_name #(VALUE1) instance_name ( //<1><1><1> + .port1 (net1), //<1><1><1> + .port2 (net2) //<1><1><1> +); //<1><1><1> + +module_name #(VALUE1) instance_name //<1><1><1> +( //<1><1><1> + .port1 (net1), //<1><1><1> + .port2 (net2) //<1><1><1> +); //<1><1><1> + +uvm_blocking_put_port #(trans) out; //<0><0><0> + +task t_multi_line( //<1><1><1> + input an_input //<1><1><1> +); //<1><1><1> + //<1><1><1> +endtask : t_multi_line //<1><1><1> + + task t_multi_line_indented( //<1><1><1> + input an_input //<1><1><1> + ); //<1><1><1> + //<1><1><1> + endtask : t_multi_line //<1><1><1> + +if (cond1) begin //<1><1><0> + do1(); //<1><1><0> +end else if (cond2) begin //<1><1><0> + do2(); //<1><1><0> + do3(); //<1><1><0> + do4(); //<1><1><0> +end else begin //<1><1><0> + do5(); //<1><1><0> +end //<1><1><0> + +if (cond1) //<0><0><0> + do1(); //<0><0><0> +else if (cond2) begin //<1><1><0> + do2(); //<1><1><0> + begin //<2><2><0> + do2_1(); //<2><2><0> + end //<2><2><0> + do3(); //<1><1><0> + do4(); //<1><1><0> +end else begin //<1><1><0> + do5(); //<1><1><0> +end //<1><1><0> + +if (cond1) begin : b1 //<1><1><1> + do1(); //<1><1><1> +end else if (cond2) begin : b2 //<1><1><1> + do2(); //<1><1><1> + do3(); //<1><1><1> + do4(); //<1><1><1> +end else begin : b3 //<1><1><1> + do5(); //<1><1><1> +end //<1><1><1> + +if (cond1) //<0><0><0> + do1(); //<0><0><0> +else if (cond2) begin : b1 //<1><1><1> + do2(); //<1><1><1> + begin:b2 //<2><2><2> + do2_1(); //<2><2><2> + end //<2><2><2> + do3(); //<1><1><1> + do4(); //<1><1><1> +end else begin //<1><1><1> + do5(); //<1><1><0> +end else begin:b3 //<1><1><1> + do5(); //<1><1><1> +end //<1><1><1> + +task something; //<1><1><1> +fork //<1><1><1> + begin //<2><2><1> + begin //<3><3><1> + end //<3><3><1> + /* //<3><3><2> + begin //<3><3><2> + end //<3><3><2> + */ //<3><3><2> + end //<2><2><1> +join //<1><1><1> +endtask //<1><1><1> + +// spyglass disable_block SOMETHING //<1><1><1> +assign a = b & c; //<1><1><1> +// spyglass enable_block SOMETHING //<1><1><1> + +// vi: set expandtab softtabstop=4 shiftwidth=4: diff --git a/bundle/verilog/test/folding.v.html b/bundle/verilog/test/folding.v.html new file mode 100644 index 000000000..11da62d5c --- /dev/null +++ b/bundle/verilog/test/folding.v.html @@ -0,0 +1,298 @@ + +
+//                                                               all
+//                                                               |  all,block_nested
+//                                                               |  |  all,block_named
+
+function f;                                                   //<1><1><1>
+begin                                                         //<2><2><1>
+                                                              //<2><2><1>
+end                                                           //<2><2><1>
+endfunction : f                                               //<1><1><1>
+
+task t;                                                       //<1><1><1>
+                                                              //<1><1><1>
+begin                                                         //<2><2><1>
+    state = something();                                      //<2><2><1>
+    begin : block1                                            //<3><3><2>
+        state = 2'b00;                                        //<3><3><2>
+        if (a <= b) begin                                     //<4><4><2>
+            begin : block2                                    //<5><5><3>
+            end // block2                                     //<5><5><3>
+            state = 2'b11;                                    //<4><4><2>
+            begin                                             //<5><5><2>
+            end                                               //<5><5><2>
+        end                                                   //<4><4><2>
+        begin : block3                                        //<4><4><3>
+        end // block3                                         //<4><4><3>
+        begin                                                 //<4><4><2>
+        end                                                   //<4><4><2>
+    end // block1                                             //<3><3><2>
+end                                                           //<2><2><1>
+                                                              //<1><1><1>
+endtask : t                                                   //<1><1><1>
+
+/*                                                            //<1><1><1>
+*                                                             //<1><1><1>
+* function in_comment;                                        //<1><1><1>
+*                                                             //<1><1><1>
+* endfunction                                                 //<1><1><1>
+*                                                             //<1><1><1>
+*/                                                            //<1><1><1>
+
+extern                        function    e_func (x, y);      //<0><0><0>
+extern              static    function   es_func (x, y);      //<0><0><0>
+extern              protected function   ep_func (x, y);      //<0><0><0>
+extern              local     function   el_func (x, y);      //<0><0><0>
+
+       pure virtual           function   pv_func (x);         //<0><0><0>
+       pure virtual static    function  pvs_func (x);         //<0><0><0>
+       pure virtual protected function  pvp_func (x);         //<0><0><0>
+       pure virtual local     function  pvl_func (x);         //<0><0><0>
+
+extern      virtual           function   ev_func (x);         //<0><0><0>
+extern      virtual static    function  evs_func (x);         //<0><0><0>
+extern      virtual protected function  evp_func (x);         //<0><0><0>
+extern      virtual local     function  evl_func (x);         //<0><0><0>
+
+extern pure virtual           function  epv_func (x);         //<0><0><0>
+extern pure virtual static    function epvs_func (x);         //<0><0><0>
+extern pure virtual protected function epvp_func (x);         //<0><0><0>
+extern pure virtual local     function epvl_func (x);         //<0><0><0>
+
+extern                        task        e_task (x, y);      //<0><0><0>
+extern              static    task       es_task (x, y);      //<0><0><0>
+extern              protected task       ep_task (x, y);      //<0><0><0>
+extern              local     task       el_task (x, y);      //<0><0><0>
+
+       pure virtual           task       pv_task (x);         //<0><0><0>
+       pure virtual static    task      pvs_task (x);         //<0><0><0>
+       pure virtual protected task      pvp_task (x);         //<0><0><0>
+       pure virtual local     task      pvl_task (x);         //<0><0><0>
+
+extern      virtual           task       ev_task (x, y);      //<0><0><0>
+extern      virtual static    task      evs_task (x, y);      //<0><0><0>
+extern      virtual protected task      evp_task (x, y);      //<0><0><0>
+extern      virtual local     task      evl_task (x, y);      //<0><0><0>
+
+extern pure virtual           task      epv_task (x, y);      //<0><0><0>
+extern pure virtual static    task     epvs_task (x, y);      //<0><0><0>
+extern pure virtual protected task     epvp_task (x, y);      //<0><0><0>
+extern pure virtual local     task     epvl_task (x, y);      //<0><0><0>
+
+
+/**                                                           //<1><1><1>
+* Static function                                             //<1><1><1>
+*/                                                            //<1><1><1>
+static function f1;                                           //<1><1><1>
+endfunction                                                   //<1><1><1>
+
+specify                                                       //<1><1><1>
+                                                              //<1><1><1>
+endspecify                                                    //<1><1><1>
+
+covergroup cov;                                               //<1><1><1>
+                                                              //<1><1><1>
+endgroup                                                      //<1><1><1>
+
+property prop;                                                //<1><1><1>
+endproperty                                                   //<1><1><1>
+
+sequence                                                      //<1><1><1>
+endsequence                                                   //<1><1><1>
+
+// Classes                                                    //<0><0><0>
+class class_a;                                                //<1><1><1>
+                                                              //<1><1><1>
+endclass : class_a                                            //<1><1><1>
+
+class class_b;                                                //<1><1><1>
+  class class_b1;                                             //<2><2><2>
+                                                              //<2><2><2>
+  endclass : class_b1                                         //<2><2><2>
+                                                              //<1><1><1>
+  class class_b2;                                             //<2><2><2>
+                                                              //<2><2><2>
+  endclass : class_b2                                         //<2><2><2>
+endclass : class_b                                            //<1><1><1>
+
+interface a;                                                  //<1><1><1>
+                                                              //<1><1><1>
+  interface class b;                                          //<2><2><2>
+  endclass : b                                                //<2><2><2>
+                                                              //<1><1><1>
+  clocking cb @ (posedge Clk);                                //<2><2><2>
+  endclocking : cb                                            //<2><2><2>
+                                                              //<1><1><1>
+endinterface : a                                              //<1><1><1>
+
+typedef interface class my_itf_class;                         //<0><0><0>
+
+`ifdef A                                                      //<1><1><1>
+reg test;                                                     //<1><1><1>
+                                                              //<1><1><1>
+//  `ifdef A_1                                                //<1><1><1>
+//                                                            //<1><1><1>
+//  `else                                                     //<1><1><1>
+//                                                            //<1><1><1>
+//  `endif                                                    //<1><1><1>
+                                                              //<1><1><1>
+`else                                                         //<1><1><1>
+                                                              //<1><1><1>
+`endif                                                        //<1><1><1>
+
+`ifndef B                                                     //<1><1><1>
+                                                              //<1><1><1>
+`elsif C                                                      //<1><1><1>
+                                                              //<1><1><1>
+`elsif D                                                      //<1><1><1>
+                                                              //<1><1><1>
+`else                                                         //<1><1><1>
+                                                              //<1><1><1>
+`endif                                                        //<1><1><1>
+
+`ifdef E                                                      //<1><1><1>
+                                                              //<1><1><1>
+  `ifndef E_1                                                 //<2><2><2>
+                                                              //<2><2><2>
+  `else                                                       //<2><2><2>
+                                                              //<2><2><2>
+  `endif                                                      //<2><2><2>
+                                                              //<1><1><1>
+  `ifndef E_2                                                 //<2><2><2>
+                                                              //<2><2><2>
+  `elsif E_3                                                  //<2><2><2>
+                                                              //<2><2><2>
+  `endif                                                      //<2><2><2>
+                                                              //<1><1><1>
+`endif                                                        //<1><1><1>
+
+`ifdef A                                                      //<1><1><1>
+                                                              //<1><1><1>
+  `ifdef B                                                    //<2><2><2>
+                                                              //<2><2><2>
+  `else                                                       //<2><2><2>
+                                                              //<2><2><2>
+  `endif                                                      //<2><2><2>
+                                                              //<1><1><1>
+`elsif C                                                      //<1><1><1>
+                                                              //<1><1><1>
+`else                                                         //<1><1><1>
+                                                              //<1><1><1>
+`endif                                                        //<1><1><1>
+
+
+/*                                                            //<1><1><1>
+  `ifdef X                                                    //<1><1><1>
+                                                              //<1><1><1>
+  `else                                                       //<1><1><1>
+                                                              //<1><1><1>
+  `endif                                                      //<1><1><1>
+*/                                                            //<1><1><1>
+
+   module_name #(                                             //<1><1><1>
+       .PARAM1 (VALUE1)                                       //<1><1><1>
+   )                                                          //<1><1><1>
+   instance_name(                                             //<1><1><1>
+       .port1 (net1),                                         //<1><1><1>
+       .port2 (net2)                                          //<1><1><1>
+   );                                                         //<1><1><1>
+
+module_name instance_name(                                    //<1><1><1>
+    .port1 (net1),                                            //<1><1><1>
+    .port2 (net2)                                             //<1><1><1>
+);                                                            //<1><1><1>
+
+module_name #(VALUE1) instance_name (                         //<1><1><1>
+    .port1 (net1),                                            //<1><1><1>
+    .port2 (net2)                                             //<1><1><1>
+);                                                            //<1><1><1>
+
+module_name #(VALUE1) instance_name                           //<1><1><1>
+(                                                             //<1><1><1>
+    .port1 (net1),                                            //<1><1><1>
+    .port2 (net2)                                             //<1><1><1>
+);                                                            //<1><1><1>
+
+uvm_blocking_put_port #(trans) out;                           //<0><0><0>
+
+task t_multi_line(                                            //<1><1><1>
+  input an_input                                              //<1><1><1>
+);                                                            //<1><1><1>
+                                                              //<1><1><1>
+endtask : t_multi_line                                        //<1><1><1>
+
+  task t_multi_line_indented(                                 //<1><1><1>
+    input an_input                                            //<1><1><1>
+  );                                                          //<1><1><1>
+                                                              //<1><1><1>
+  endtask : t_multi_line                                      //<1><1><1>
+
+if (cond1) begin                                              //<1><1><0>
+    do1();                                                    //<1><1><0>
+end else if (cond2) begin                                     //<1><1><0>
+    do2();                                                    //<1><1><0>
+    do3();                                                    //<1><1><0>
+    do4();                                                    //<1><1><0>
+end else begin                                                //<1><1><0>
+    do5();                                                    //<1><1><0>
+end                                                           //<1><1><0>
+
+if (cond1)                                                    //<0><0><0>
+    do1();                                                    //<0><0><0>
+else if (cond2) begin                                         //<1><1><0>
+    do2();                                                    //<1><1><0>
+    begin                                                     //<2><2><0>
+    do2_1();                                                  //<2><2><0>
+    end                                                       //<2><2><0>
+    do3();                                                    //<1><1><0>
+    do4();                                                    //<1><1><0>
+end else begin                                                //<1><1><0>
+    do5();                                                    //<1><1><0>
+end                                                           //<1><1><0>
+
+if (cond1) begin : b1                                         //<1><1><1>
+    do1();                                                    //<1><1><1>
+end else if (cond2) begin : b2                                //<1><1><1>
+    do2();                                                    //<1><1><1>
+    do3();                                                    //<1><1><1>
+    do4();                                                    //<1><1><1>
+end else begin : b3                                           //<1><1><1>
+    do5();                                                    //<1><1><1>
+end                                                           //<1><1><1>
+
+if (cond1)                                                    //<0><0><0>
+    do1();                                                    //<0><0><0>
+else if (cond2) begin : b1                                    //<1><1><1>
+    do2();                                                    //<1><1><1>
+    begin:b2                                                  //<2><2><2>
+    do2_1();                                                  //<2><2><2>
+    end                                                       //<2><2><2>
+    do3();                                                    //<1><1><1>
+    do4();                                                    //<1><1><1>
+end else begin                                                //<1><1><1>
+    do5();                                                    //<1><1><0>
+end else begin:b3                                             //<1><1><1>
+    do5();                                                    //<1><1><1>
+end                                                           //<1><1><1>
+
+task something;                                               //<1><1><1>
+fork                                                          //<1><1><1>
+    begin                                                     //<2><2><1>
+        begin                                                 //<3><3><1>
+        end                                                   //<3><3><1>
+        /*                                                    //<3><3><2>
+        begin                                                 //<3><3><2>
+        end                                                   //<3><3><2>
+        */                                                    //<3><3><2>
+    end                                                       //<2><2><1>
+join                                                          //<1><1><1>
+endtask                                                       //<1><1><1>
+
+// spyglass disable_block SOMETHING                           //<1><1><1>
+assign a = b & c;                                             //<1><1><1>
+// spyglass enable_block SOMETHING                            //<1><1><1>
+
+// vi: set expandtab softtabstop=4 shiftwidth=4:
+
+ diff --git a/bundle/verilog/test/functions.vim b/bundle/verilog/test/functions.vim new file mode 100644 index 000000000..eba5783d5 --- /dev/null +++ b/bundle/verilog/test/functions.vim @@ -0,0 +1,234 @@ +function! TestFold(...) + let fail = 0 + let linenr = 4 "Start after header + if exists("a:1") + let index = a:1 + else + let index = 0 + endif + while linenr < line("$") + let line = getline(linenr) + let levels = substitute(line, '.\{-}<\(\d*\)>', '\1::', 'g') + let levels_list = split(levels, '::') + if len(line) == 0 + " Empty lines can be used as separators and will have zero " folding + let level_expected=0 + elseif index < 0 || (index >= len(levels_list)) + " Abort if requested index is NOT available in the levels list + echo 'Invalid line format: (' . linenr . ')' + echo line + return 1 + else + " Store expected indent level + let level_expected=levels_list[index] + endif + " Check indent level + let level = foldlevel(linenr) + if (level != level_expected) + let fail = 1 + echo "Error: level=" . level . " level_expected=" . level_expected . " (" . linenr . ") >>>>" . line + endif + let linenr += 1 + endwhile + + if (fail == 1) + echo 'Fold test failed:' + echo 'g:verilog_syntax_fold_lst: ' . g:verilog_syntax_fold_lst + return 1 + else + echo 'Fold test passed' + return 0 + endif + +endfunction + +function! TestIndent() + let fail = 0 + let fail_lines = '' + let linenr = 0 + while linenr < line("$") + let linenr += 1 + let line = getline(linenr) + let ind1 = indent(linenr) + execute 'normal! '.linenr.'gg==' + let ind2 = indent(linenr) + if ind1 != ind2 + let fail = 1 + if (fail_lines == '') + let fail_lines = linenr + else + let fail_lines = fail_lines.','.linenr + endif + endif + endwhile + + if (fail == 1) + echo 'Indent test failed:' + echo fail_lines + return 1 + else + echo 'Indent test passed' + return 0 + endif + +endfunction + +function! TestEfm(tool, mode, search_uvm) + let expected_errors = 0 + let expected_warnings = 0 + let expected_lints = 0 + let uvm_expected_errors = 0 + let uvm_expected_warnings = 0 + let uvm_expected_lints = 0 + + " Re-read test file + silent view test/errorformat.txt + + " Obtain tool configuration from file + let config_found = 0 + let linenr = 0 + while linenr < line("$") + let linenr += 1 + let line = getline(linenr) + " Tool config line + let tool_config = matchlist(line, '^### *' . tolower(a:tool) . ' E=\(\d\+\), *W=\(\d\+\)\(, *L=\(\d\+\)\)\?') + if len(tool_config) != 0 + let expected_errors = tool_config[1] + if a:mode == 1 + let expected_warnings = tool_config[2] + else + let expected_warnings = 0 + endif + if a:mode <= 2 + let expected_lints = tool_config[4] + else + let expected_lints = 0 + endif + let config_found = 1 + if !a:search_uvm + break + endif + endif + " UVM config line + let uvm_config = matchlist(line, '^### *UVM E=\(\d\+\), *W=\(\d\+\)\(, *L=\(\d\+\)\)\?') + if len(uvm_config) != 0 + let uvm_expected_errors = uvm_config[1] + if len(uvm_config) > 1 + let uvm_expected_warnings = uvm_config[2] + endif + if len(uvm_config) > 3 + let uvm_expected_lints = uvm_config[4] + endif + let uvm_config_found = 1 + if config_found + break + endif + endif + endwhile + + if !config_found + echo 'Test for tool ' . tolower(a:tool) . ' was not found' + return 1 + endif + + " Calculate total expected errors + if a:search_uvm + let expected_errors += uvm_expected_errors + let expected_warnings += uvm_expected_warnings + let expected_lints += uvm_expected_lints + endif + + " Setup 'errorformat' and 'makeprg' + call verilog_systemverilog#VerilogErrorFormat(a:tool, a:mode) + setlocal makeprg=cat\ % + + " Populate quickfix window + silent! make! + redraw + + " Check results + let errors = 0 + let warnings = 0 + let lints = 0 + let qf_list = getqflist() + for qf_entry in qf_list + " Only check valid entries + if qf_entry.valid != 0 + " Consider Fatal and matches without type as errors + if qf_entry.type == 'E' || + \ qf_entry.type == 'F' || + \ qf_entry.type == '' + let errors += 1 + endif + if qf_entry.type == 'W' + let warnings += 1 + endif + " Consider Info as lint + if qf_entry.type == 'L' || + \ qf_entry.type == 'I' + let lints += 1 + endif + endif + endfor + echo 'Results:' + echo ' Expected errors = ' . expected_errors . ', errors found = ' . errors + echo ' Expected warnings = ' . expected_warnings . ', warnings found = ' . warnings + echo ' Expected lints = ' . expected_lints . ', lints found = ' . lints + echo ' errorformat = ' . &errorformat + echo 'Quickfix contents:' + for qf_entry in qf_list + echo qf_entry + endfor + if errors == expected_errors && warnings == expected_warnings && lints == expected_lints + echo 'Error format test passed' + return 0 + else + echo 'Error format test failed:' + return 1 + endif +endfunction + +function! TestSyntax(file_name, test_name) + let test_name=substitute(a:test_name, ',', '_', '') + if test_name == "" + let test_name="default" + endif + let ref_file_name='test/' . a:file_name . '.html' + let new_file_name='test/' . a:file_name . '.' . test_name . '.html' + + execute 'silent view test/' . a:file_name + syntax enable + + " Generate HTML version of the file + let g:html_line_ids=0 + let g:html_number_lines=0 + let g:html_no_progress=1 + TOhtml + " Clean up resulting HTML to minimize differences with other + " versions of TOhtml script + 1,//-1 delete + /<\/body>/+1,$ delete + %s/ id='vimCodeElement'//e + " Write final buffer + execute 'w! ' . new_file_name + bd! + + " Compare with reference + silent let output = system('diff ' . ref_file_name . ' ' . new_file_name) + + if output == "" + echo 'Syntax test "' . a:file_name . '" with folding ' . test_name . ' passed' + echo '' + return 0 + else + echo '=====DIFF START=====' + echo output + echo '=====DIFF END=======' + echo 'Syntax test "' . a:file_name . '" with folding ' . test_name . ' failed' + echo '' + return 1 + endif + +endfunction + +" vi: set expandtab softtabstop=4 shiftwidth=4: diff --git a/bundle/verilog/test/indent.sv b/bundle/verilog/test/indent.sv new file mode 100644 index 000000000..5b7c27d16 --- /dev/null +++ b/bundle/verilog/test/indent.sv @@ -0,0 +1,1077 @@ +typedef class a; + +// Code based on: https://github.com/vhda/verilog_systemverilog.vim/issues/2 +class z; + + // this is a comment + // ----------------- + typedef struct { + real a; + int b; + int c; + real d; } ts; + + ts s[]; + + // if there are + // more comments + typedef struct { + real a; + int b; + int c; + real d; + } ts2; + + ts2 t[]; + + int unsigned cnt=0; + + function new(); + super.new(); + endfunction; + + virtual interface my_itf itf; + + // Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/4 + task run_phase(uvm_phase phase); + + assert(my_seq.randomize()); + my_seq.start(low_sequencer_h); + + assert(my_seq.randomize() with {Nr==6;}); + my_seq.start(low_sequencer_h); + + assert(my_seq.randomize() with + {Nr==6; Time==8;}); + my_seq.start(low_sequencer_h); + + assert( + my_seq.randomize() with + {Nr==6; Time==8;} + ); + my_seq.start(low_sequencer_h); + + // Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/5 + fork + begin : isolating_thread + do_something(); + end : isolating_thread + join + // End of copied code + + // Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/15 + assert(out>0) else $warning("xxx"); + $display("Hi"); + + assert(out>0) + else $warning("xxx"); + $display("Hi"); + + assert(out>0) else $warning("xxx"); + $display("Hi"); + $display("Hi"); + // End of copied code + + assert(out>0) + else + $warning("xxx"); + $display("Hi"); + + if (1 > 0) $display("1 > 0"); + else $display("1 < 0"); + $display(); + + endtask + // End of copied code + + // Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/7 + task run_phase2(uvm_phase phase); + assert(out>0) else $warning("xxx"); + assert(out>0) else $warning("xxx"); + foreach(out[i]) begin + out[i]=new; + end + endtask + // End of copied code + + /* + * + * + * + */ + + // Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/12 + task my_seq::body(); + `uvm_info({get_type_name(),"::body"}, "something" ,UVM_HIGH) + req = my_seq_item_REQ::type_id::create("req"); + endtask + // End of copied code + + // Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/14 + pure virtual function void a(input int unsigned N, ref t Data); + pure virtual function void b(input int unsigned N, ref t Data); + pure virtual function void c(input int unsigned N, ref t Data); + // End of copied code + + // Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/17 + function void sink_driver::build_phase(uvm_phase phase); + if (!uvm_config_db #(sink_agent_config)::get(this, "", "sink_agent_config", m_cfg) ) + `uvm_fatal("CONFIG_LOAD", "Cannot get() configuration sink_agent_config from uvm_config_db. Have you set() it?") + // OK to do this herE> + foreach(rand_bool_gen[ch]) begin + rand_bool_gen[ch]=new(); + end + endfunction + // End of copied code + + // Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/41 + `uvm_info("TAG", "message", UVM_MEDIUM) + + if (condition) + `uvm_info("TAG", "message1", UVM_MEDIUM) + else + `uvm_info("TAG", "message2", UVM_NONE) + // End of copied code + + // Other tests + task fork_test; + fork + do_something1(); + do_something2(); + join_none // {} + do_something3(); + endtask + + task while_one_line; + while (1) + do_something(); + + (* full_case=1 *) + (* parallel_case=1 *) + case (a) + endcase + + (* full_case, + parallel_case=1 *) + case (a) + endcase + + endtask + + function less_or_equal; + if (a <= b) + less_or_equal = a; + endfunction + + task while_block; + while (1) + begin + do_something(); + end + endtask + + task while_block2; + while (1) begin + do_something(); + end + endtask + + virtual task virtual_task; + while (1) begin + do_something(); + end + endtask + + virtual function virtual_function; + while (1) begin + do_something(); + end + + do + do_something(); + while (1); + + do begin + do_something(); + end while (1); + + endfunction + + //function old_style_function_with_var( + // input a + //); + //reg test; + //begin + // do_something1(); + // do_something2(); + // begin + // do_something3(); + // end + //end + //endfunction + + //function old_style_function_without_var( + // input a + //); + //begin + // do_something1(); + // do_something2(); + // begin + // do_something3(); + // end + //end + //endfunction + + //function old_style_function_one_line_with_var(input a); + // reg x; + //begin + // do_something1(); + // do_something2(); + // begin + // do_something3(); + // end + //end + //endfunction + + //function old_style_function_one_line_without_var(input a); + //begin + // do_something1(); + // do_something2(); + // begin + // do_something3(); + // end + //end + //endfunction + + function void hello(); + foreach (element[i]) + if (hi) + if (hi) /* comment */ begin /* comment */ + if (hi) begin + foreach (element[i]) + if (condition0) + if (condition1) begin + var0 <= 0; + end + else begin + if (1) begin + var1 <= 1; + something(); + if (1) + if (1) begin + something(); + end + else + if (1) + if (1) begin + if (1) + something(); + else begin + something(); + end + end + else if (1) + something(); + else + something(); + + if (1) + something(); + + if (1) begin + something(); + end else + something(); + + if (1) begin + something(); + end else + something(); + + if (1) + // Nested case + case(value) + 0, + 1: + case(value) inside + [0:20]:; + 21: something(); + 22:; + default: something(); + endcase + 2:; + 3:; + endcase + + if (1) + something(); + + /* end */ + + something(); + /* end */ + something(); + end + end + deindent_x2_please(); + /* end */ + dont_deindent_please(); + end + deindent_please(); + end + deindent_please(); + dont_deindent_please(); + endfunction : hello + + function void hello(); + if (1) + fork + something(); + something(); + begin + something(); + end + begin + fork + if (1) // begin + if (1) + if (1) begin // comment + something(); + if (1) begin + end + something(); + end + something(); + join + if (1) + do + something(); + while(1); + else + do + something(); + while (1) ; + something(); + end + if (1) + foreach (objects[i]) + if (1) + if (1) begin + something(); + fork begin + something(); + end join + end + something(); + join_none + + // Code from: // https://github.com/vhda/verilog_systemverilog.vim/issues/158 + fork + p1: begin + myvar=1'b1; + `info("some message with the word join"); + end + p2: begin + myvar2=1'b1; + end + join + // End of copied code + endfunction : hello + + local static function void hello(); + const bit variable1 = + func_call(object_t) && structue_t.field_t.source != ENUM_VALUE && + object_t.field_t && variable0; + + const bit variable1 = + func_call(object_t) && structue_t.field_t.source != ENUM_VALUE + && object_t.field_t && variable0; + + const bit variable2 = + object_t.field_t && object_t.field_t.source == ENUM_VALUE; + + bit variable3; + + // Multi-line if with no begin + if (variable && variable && variable && + variable) + indent(); + + de_indent(); + + // Multi-line if with begin with a line starting with && + if (variable && variable && variable + && variable + && variable) begin + indent(); + stay(); + end + + de_indent(); + + variable = variable + || variable || variable; + + variable = variable || + variable || variable; + + variable = (variable == CONSTANT) & + variable & + variable; + + wire var0 = a & + b; + + wire [1:0] var1 = a & + b; + + var2[0] = a & + b; + + {var0, var1} = a & + b; + + some_struct.field1 = a & + b; + + some_type #(params) some_object = cond0 ? a : + cond1 ? b : c; + + if (1) begin + if (1 + && 1) + something(); + end + + endfunction + +endclass + +class a; + class nested; + import "DPI-C" function void c_print(); + int b; + endclass +endclass + +clocking ck1 @(posedge clk); + default input #1step output negedge; + input a; + output y; +endclocking + +// TODO: Unsupported +// class a; +// typedef class a; +// endclass + +// Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/14 +virtual class base; + + extern function void x(input int unsigned N, ref t Data); + extern function void y(input int unsigned N, ref t Data); + + pure virtual function void a(input int unsigned N, ref t Data); + pure virtual function void b(input int unsigned N, ref t Data); + pure virtual function void c(input int unsigned N, ref t Data); + +endclass; +// End of copied code + +// Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/49 +module MyModule #( + parameter A = 1, + parameter B = 2 +)( + input I, + output O +); + + +wire Val_IP = !In_Pkt_S_Bus_enf || + ((Pls_Don || ResVal) && (Pls_Res || ResFnd)); + +wire Val_IP = + !In_Pkt_S_Bus_enf || // A, B, C + ((Pls_Don || ResVal) && (Pls_Res || ResFnd)); + +wire Val_IP = !In_Pkt_S_Bus_enf ? + ((Pls_Don || ResVal) && (Pls_Res == ResFnd)) : + ((Pls_Don || ResVal) && (Pls_Res || ResFnd)); + +MyModule #( + .A (1), + .B (2) +) Module_1 ( + .I (wire1), + .O (wire2) +); + +or or_0(); + +endmodule +// End of copied code + +// Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/51 +case (Signal) + 2'd0: begin Result <= 0; end + 2'd1: begin Result <= 1; end + 2'd2: begin Result <= 2; end + default: begin Result <= 0; end +endcase +// End of copied code + +interface class base; + + pure virtual function void a(input int unsigned N, ref t Data); + pure virtual function void b(input int unsigned N, ref t Data); + pure virtual function void c(input int unsigned N, ref t Data); + +endclass; + +module m #(1) +( + portA, + portB +); + +// Nested modules (IEEE - 1800-2012, section 23.4) +module a; +endmodule + +endmodule + +module m ( + portA, + portB +); + +device d0 ( + .port (port[1]), + .port2(), // comment + .portA(port[2]) +); + +// Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/6 +device d1 ( + .port (port[1]), + // .port2(), // comment + .* +); + +`ifdef DO_THIS + device d1 ( + .port (port[1]), + /* comment line 1 + * comment line2 */ + .port2(), + .* + ); +`endif + +`ifdef DO_THIS + device2 d2 ( + .out, + .a, + .b(B)/*, + TODO .c(C) port not implemented yet */ + ); +`endif +// End of copied code + +device d1 ( + .port (port[1]), + // .port1(), comment + /**/.port2(), // comment + /*.port3(), */ + // .port4(), comment + .portA(port[2]) +); + +`define VALUE 3 + +`define VALUE_MULTI_LINE \ + 16'hFF + +`ifdef V95 + device d2 ( out, portA, portB ); + device d2 ( out, portA, portB ); + `ifdef V95 + device d2 ( out, portA, portB ); + device d2 ( out, portA, portB ); + `endif +`elsif V2K + device d2 ( .out(out), .* ); + device d2 ( out, portA, portB ); + `ifndef SWAP + device d3 ( .out(out), .* ); + device d2 ( .out(out), .* ); + `else + device d3 ( .out(out), .portA(portB), .portB(portA) ); + device d2 ( .out(out), .* ); + `endif +`endif +`ifndef SWAP + device d3 ( .out(out), .* ); + device d2 ( .out(out), .* ); +`else + device d3 ( .out(out), .portA(portB), .portB(portA) ); + device d2 ( .out(out), .* ); +`endif + +endmodule + +class a; +endclass : a + +module a import some_pkg::*; +( + input clk, + output x +); + +always @ (posedge clk) +begin +end + +always + x <= 1; + +always +begin + x <= 1; + statement(); +end + +always // +begin + x <= 1; + statement(); +end + +label : always // + x <= 1; + +always @ (posedge clk) // + x <= 1; + +always @ (posedge clk) + x <= 1; + +always_ff // begin + x <= 1; + +always_comb + x <= 1; + +label : always_ff begin + begin + x <= 1; + statement(); + end +end + +always_ff @ (posedge clk) +begin + x <= 1; + statement(); + foreach (object[i]) + statement(); +end + +always_ff @ (posedge clk) +begin + x <= 1; + statement(); + foreach (object[i]) + statement(); +end + +always_ff @ (posedge clk) +begin + x <= 1; + statement(); + foreach (object[i]) + statement(); +end + +always_ff @ (posedge clk) +begin + x <= 1; + statement(); + foreach (object[i]) + statement(); +end + +always_ff @ (posedge clk) +begin + x <= 1; + statement(); + foreach (object[i]) + statement(); +end + +always_ff @ (posedge clk) +begin + x <= 1; + statement(); + foreach (object[i]) + statement(); +end + +always_ff @ (posedge clk) +begin + x <= 1; + statement(); + foreach (object[i]) + statement(); +end + +always_ff @ (posedge clk) +begin + x <= 1; + statement(); + foreach (object[i]) + statement(); +end + +// always_ff +// begin +// x <= 1; +// end + +endmodule + +if (condition) begin + something(); +end +else + `macro_call() + +always : label + `macro_call() + +begin + begin + end // always + `dont_indent() + dont_deindent(); + + begin + end // foreach() + dont_indent(); + dont_deindent(); + + begin + end /* while() */ + dont_indent(); + dont_deindent(); +end + +class a extends b; + + local static function void hello(); + + something(); + endfunction + + constraint l1 { + y == 1; + } + + constraint l1 + { + y == 1; + } + +endclass : a + +extern module counter (input clk,enable,reset, + output logic [3:0] data); + +extern module counter2; + +class a implements + b, + c, + d; + + function void function_with_multiline_proto( + object_type object); + indent(); + endfunction + + function void function_with_multiline_proto( + object_type object0, + object_type object1, + object_type object2, + object_type object3 + ); + indent(); + endfunction + +endclass + +covergroup c1_cg (ref bit x); + option.per_instance = 1; + type_option.merge_instances = 1; + + x : coverpoint x { + bins _0 = {1'h0}; + bins _1 = {1'h1}; + } + +endgroup + +package a; + + class b; + endclass + + class c; + endclass + + class d; + endclass + +endpackage + +sequence acknowledge + ##[1:2] Ack; +endsequence + +property handshake; + @(posedge Clock) + request |-> acknowledge; +endproperty + +always + if(1) begin + end + // comment + else + {var0, var1} <= 2'b00; + +always + if (0) begin + var0 <= 1'b0; + end else if(0) begin + var0 <= 1'b1; + end + +// comment + +virtual class DataTypes_packer#(type T, int L, int W, int I); + + extern static function void unpack(const ref bit [L-1:0] in, ref T out[]); + extern static function void unpack5(const ref bit [L-1:0] in, ref t5#(W,I) out[], input int n_MSB2ignore=0); + + /* + // packing functions + extern static function void pack(const ref T in[], ref bit [L-1:0] out); + extern static function void pack2(const ref t2#(W,I) in[], ref bit [L-1:0] out); + */ + + // unpack functions: + extern static function void unpack(const ref bit [L-1:0] in, ref T out[]); + extern static function void unpack5(const ref bit [L-1:0] in, ref t5#(W,I) out[], input int n_MSB2ignore=0); + +endclass + +fork + begin + + for(int i=0;i<5;i++) begin + automatic int idx=i; + fork + begin + $display("%fns: %0d start",$realtime/1ns,idx); + my_seq[idx].go(); + end + join_none + end + + // wait for all forks to end + wait fork; + $display("%fns: all done",$realtime/1ns); + end +join + +$display("hi"); + +assert_value: assert property (@(posedge clk) disable iff (~reset_n) + var0 |-> var1 == var2 +); + +`ifdef NOTHING +`endif + +wire signal = + !var0 && ( + var2 + ); + +task run_phase(uvm_phase phase); + int var0 = var1 + + var2 * + var3; + + int var0 = + var1; + + if (map.first(s)) + do + $display("%s : %d\n", s, map[s]); + while (map.next(s)); + + label : assert(my_seq.randomize()); + my_seq.start(low_sequencer_h); + + assert(my_seq.randomize() with {Nr==6;}); + my_seq.start(low_sequencer_h); + + label : assert(my_seq.randomize() with + {Nr==6; Time==8;}); + my_seq.start(low_sequencer_h); + + assert( + my_seq.randomize() with + ); + + //task +endtask + +function void sink_driver::build_phase(uvm_phase phase); + + assert property (prop1) + else `uvm_fatal("TAG", "Assertion failed.") + + do_something(); + + assert property (prop1) + else + `uvm_fatal("TAG", "Assertion failed.") + + do_something(); + + if (condition) + something(); + else `uvm_fatal("TAG", "This is invalid.") + + do_something(); + + if (condition) + something(); + else + `uvm_fatal("TAG", "This is invalid.") + + do_something(); +endfunction + +// Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/51 +case (XfrState) + One_XFR : XfrState_str = "One"; + Two_XFR : XfrState_str = "Two"; + End_XFR : XfrState_str = "End"; + default : XfrState_str = "N/A"; +endcase +// End of copied code + +interface rx_if; + logic trans; + logic [31:0] data ; + logic [31:0] addr ; +endinterface + +generate + for (int i = 0; i < 9; ++i) begin : gen_loop + dut u_dut(.in(i)); + end +endgenerate + +program u_prg; + logic clk; +endprogram + +// Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/71 +wire a = c <= d & + e = f; +// End of copied code + +// Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/72 +function bit return_something(); + return a & + b | + c; +endfunction +// End of copied code + +// Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/80 +/* +* function text +* text +*/ + +// Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/51 +module dut_wrapper ( + interface source_IF, + interface sink_IF, + interface ctrl_IF +); + +endmodule +// End of copied code + +// Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/81 +cover property ( + a && + b && + c +); +// End of copied code + +// Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/167 +co__ack_and_req : cover sequence ( + req && ack +); +// End of copied code + +// Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/84 +assign out = cond0 ? a : + cond1 ? b : + c ; +// End of copied code + +// Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/85 +assert_label: assert property ( + precondition |-> a && + b && + c +); +assert_label: assert property ( + precondition |=> a && + b && + c +); +// End of copied code + +// Code from: // https://github.com/vhda/verilog_systemverilog.vim/issues/113 +assign a = b <= c && + d <= e && + f <= g && + h <= i; +// End of copied code + +// Code from: // https://github.com/vhda/verilog_systemverilog.vim/issues/129 +if (cond) begin do_something; end +do_something_else; + +// Code from: // https://github.com/vhda/verilog_systemverilog.vim/issues/120 +package automatic regmodel_dpi_pkg; + export "DPI-SC" task check_reg; + task check_reg(string mystring, output bit [63:0] o1); + endtask +endpackage +// End of copied code + +// vi: set expandtab softtabstop=4 shiftwidth=4: diff --git a/bundle/verilog/test/indent.sv.html b/bundle/verilog/test/indent.sv.html new file mode 100644 index 000000000..473e1762d --- /dev/null +++ b/bundle/verilog/test/indent.sv.html @@ -0,0 +1,1081 @@ + +
+typedef class a;
+
+// Code based on: https://github.com/vhda/verilog_systemverilog.vim/issues/2
+class z;
+
+    // this is a comment
+    // -----------------
+    typedef struct {
+        real a;
+        int b;
+        int c;
+        real d; } ts;
+
+    ts s[];
+
+    // if there are
+    // more comments
+    typedef struct {
+        real a;
+        int b;
+        int c;
+        real d;
+    } ts2;
+
+    ts2 t[];
+
+    int unsigned cnt=0;
+
+    function new();
+        super.new();
+    endfunction;
+
+    virtual interface my_itf itf;
+
+    // Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/4
+    task run_phase(uvm_phase phase);
+
+        assert(my_seq.randomize());
+        my_seq.start(low_sequencer_h);
+
+        assert(my_seq.randomize() with {Nr==6;});
+        my_seq.start(low_sequencer_h);
+
+        assert(my_seq.randomize() with
+            {Nr==6; Time==8;});
+        my_seq.start(low_sequencer_h);
+
+        assert(
+            my_seq.randomize() with
+            {Nr==6; Time==8;}
+        );
+        my_seq.start(low_sequencer_h);
+
+        // Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/5
+        fork
+            begin : isolating_thread
+                do_something();
+            end : isolating_thread
+        join
+        // End of copied code
+
+        // Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/15
+        assert(out>0) else $warning("xxx");
+        $display("Hi");
+
+        assert(out>0)
+        else $warning("xxx");
+        $display("Hi");
+
+        assert(out>0) else $warning("xxx");
+        $display("Hi");
+        $display("Hi");
+        // End of copied code
+
+        assert(out>0)
+        else
+            $warning("xxx");
+        $display("Hi");
+
+        if (1 > 0) $display("1 > 0");
+        else $display("1 < 0");
+        $display();
+
+    endtask
+    // End of copied code
+
+    // Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/7
+    task run_phase2(uvm_phase phase);
+        assert(out>0) else $warning("xxx");
+        assert(out>0) else $warning("xxx");
+        foreach(out[i]) begin
+            out[i]=new;
+        end
+    endtask
+    // End of copied code
+
+    /*
+    *
+    *
+    *
+    */
+
+    // Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/12
+    task my_seq::body();
+        `uvm_info({get_type_name(),"::body"}, "something" ,UVM_HIGH)
+        req = my_seq_item_REQ::type_id::create("req");
+    endtask
+    // End of copied code
+
+    // Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/14
+    pure virtual function void a(input int unsigned N, ref t Data);
+    pure virtual function void b(input int unsigned N, ref t Data);
+    pure virtual function void c(input int unsigned N, ref t Data);
+    // End of copied code
+
+    // Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/17
+    function void sink_driver::build_phase(uvm_phase phase);
+        if (!uvm_config_db #(sink_agent_config)::get(this, "", "sink_agent_config", m_cfg) )
+            `uvm_fatal("CONFIG_LOAD", "Cannot get() configuration sink_agent_config from uvm_config_db. Have you set() it?")
+        // OK to do this herE>
+        foreach(rand_bool_gen[ch]) begin
+            rand_bool_gen[ch]=new();
+        end
+    endfunction
+    // End of copied code
+
+    // Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/41
+    `uvm_info("TAG", "message", UVM_MEDIUM)
+
+    if (condition)
+        `uvm_info("TAG", "message1", UVM_MEDIUM)
+    else
+        `uvm_info("TAG", "message2", UVM_NONE)
+    // End of copied code
+
+    // Other tests
+    task fork_test;
+        fork
+            do_something1();
+            do_something2();
+        join_none // {}
+        do_something3();
+    endtask
+
+    task while_one_line;
+        while (1)
+            do_something();
+
+        (* full_case=1 *)
+        (* parallel_case=1 *)
+        case (a)
+        endcase
+
+        (* full_case,
+            parallel_case=1 *)
+        case (a)
+        endcase
+
+    endtask
+
+    function less_or_equal;
+        if (a <= b)
+            less_or_equal = a;
+    endfunction
+
+    task while_block;
+        while (1)
+        begin
+            do_something();
+        end
+    endtask
+
+    task while_block2;
+        while (1) begin
+            do_something();
+        end
+    endtask
+
+    virtual task virtual_task;
+        while (1) begin
+            do_something();
+        end
+    endtask
+
+    virtual function virtual_function;
+        while (1) begin
+            do_something();
+        end
+
+        do
+            do_something();
+        while (1);
+
+        do begin
+            do_something();
+        end while (1);
+
+    endfunction
+
+    //function old_style_function_with_var(
+    //    input a
+    //);
+    //reg test;    
+    //begin
+    //    do_something1();
+    //    do_something2();
+    //    begin
+    //        do_something3();
+    //    end
+    //end
+    //endfunction
+
+    //function old_style_function_without_var(
+    //    input a
+    //);
+    //begin
+    //    do_something1();
+    //    do_something2();
+    //    begin
+    //        do_something3();
+    //    end
+    //end
+    //endfunction
+
+    //function old_style_function_one_line_with_var(input a);
+    //    reg x;
+    //begin
+    //    do_something1();
+    //    do_something2();
+    //    begin
+    //        do_something3();
+    //    end
+    //end
+    //endfunction
+
+    //function old_style_function_one_line_without_var(input a);
+    //begin
+    //    do_something1();
+    //    do_something2();
+    //    begin
+    //        do_something3();
+    //    end
+    //end
+    //endfunction
+
+    function void hello();
+        foreach (element[i])
+            if (hi)
+                if (hi) /* comment */ begin /* comment */
+                    if (hi) begin
+                        foreach (element[i])
+                            if (condition0)
+                                if (condition1) begin
+                                    var0 <= 0;
+                                end
+                                else begin
+                                    if (1) begin
+                                        var1 <= 1;
+                                        something();
+                                        if (1)
+                                            if (1) begin
+                                                something();
+                                            end
+                                            else
+                                                if (1)
+                                                    if (1) begin
+                                                        if (1)
+                                                            something();
+                                                        else begin
+                                                            something();
+                                                        end
+                                                    end
+                                                    else if (1)
+                                                        something();
+                                                    else
+                                                        something();
+
+                                        if (1)
+                                            something();
+
+                                        if (1) begin
+                                            something();
+                                        end else
+                                            something();
+
+                                        if (1) begin
+                                            something();
+                                        end else
+                                            something();
+
+                                        if (1)
+                                            // Nested case
+                                            case(value)
+                                                0,
+                                                1:
+                                                    case(value) inside
+                                                        [0:20]:;
+                                                        21: something();
+                                                        22:;
+                                                        default: something();
+                                                    endcase
+                                                2:;
+                                                3:;
+                                            endcase
+
+                                        if (1)
+                                            something();
+
+                                        /* end */
+
+                                        something();
+                                        /* end */
+                                        something();
+                                    end
+                                end
+                        deindent_x2_please();
+                        /* end */
+                        dont_deindent_please();
+                    end
+                    deindent_please();
+                end
+        deindent_please();
+        dont_deindent_please();
+    endfunction : hello
+
+    function void hello();
+        if (1)
+            fork
+                something();
+                something();
+                begin
+                    something();
+                end
+                begin
+                    fork
+                        if (1) // begin
+                            if (1)
+                                if (1) begin // comment
+                                    something();
+                                    if (1) begin
+                                    end
+                                    something();
+                                end
+                        something();
+                    join
+                    if (1)
+                        do
+                            something();
+                        while(1);
+                    else
+                        do
+                            something();
+                        while (1) ;
+                    something();
+                end
+                if (1)
+                    foreach (objects[i])
+                        if (1)
+                            if (1) begin
+                                something();
+                                fork begin
+                                    something();
+                                end join
+                            end
+                something();
+            join_none
+
+        // Code from: // https://github.com/vhda/verilog_systemverilog.vim/issues/158
+        fork
+            p1: begin
+                myvar=1'b1;
+                `info("some message with the word join");
+            end
+            p2: begin
+                myvar2=1'b1;
+            end
+        join
+        // End of copied code
+    endfunction : hello
+
+    local static function void hello();
+        const bit variable1 =
+            func_call(object_t) && structue_t.field_t.source != ENUM_VALUE &&
+            object_t.field_t && variable0;
+
+        const bit variable1 =
+            func_call(object_t) && structue_t.field_t.source != ENUM_VALUE
+            && object_t.field_t && variable0;
+
+        const bit variable2 =
+            object_t.field_t && object_t.field_t.source == ENUM_VALUE;
+
+        bit variable3;
+
+        // Multi-line if with no begin
+        if (variable && variable && variable &&
+            variable)
+            indent();
+
+        de_indent();
+
+        // Multi-line if with begin with a line starting with &&
+        if (variable && variable && variable
+            && variable
+            && variable) begin
+                indent();
+                stay();
+            end
+
+        de_indent();
+
+        variable = variable
+                   || variable || variable;
+
+        variable = variable ||
+                   variable || variable;
+
+        variable = (variable == CONSTANT) &
+                   variable &
+                   variable;
+
+        wire var0 = a &
+                    b;
+
+        wire [1:0] var1 = a &
+                          b;
+
+        var2[0] = a &
+                  b;
+
+        {var0, var1} = a &
+                       b;
+
+        some_struct.field1 = a &
+                             b;
+
+        some_type #(params) some_object = cond0 ? a :
+                                          cond1 ? b : c;
+
+        if (1) begin
+            if (1
+                && 1)
+                something();
+        end
+
+    endfunction
+
+endclass
+
+class a;
+    class nested;
+        import "DPI-C" function void c_print();
+        int b;
+    endclass
+endclass
+
+clocking ck1 @(posedge clk);
+    default input #1step output negedge;
+    input a;
+    output y;
+endclocking
+
+// TODO: Unsupported
+// class a;
+//     typedef class a;
+// endclass
+
+// Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/14
+virtual class base;
+
+    extern function void x(input int unsigned N, ref t Data);
+    extern function void y(input int unsigned N, ref t Data);
+
+    pure virtual function void a(input int unsigned N, ref t Data);
+    pure virtual function void b(input int unsigned N, ref t Data);
+    pure virtual function void c(input int unsigned N, ref t Data);
+
+endclass;
+// End of copied code
+
+// Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/49
+module MyModule #(
+    parameter A = 1,
+    parameter B = 2
+)(
+    input I,
+    output O
+);
+
+
+wire Val_IP  = !In_Pkt_S_Bus_enf ||
+               ((Pls_Don || ResVal) && (Pls_Res || ResFnd));
+
+wire Val_IP  =
+    !In_Pkt_S_Bus_enf || // A, B, C
+    ((Pls_Don || ResVal) && (Pls_Res || ResFnd));
+
+wire Val_IP  = !In_Pkt_S_Bus_enf ?
+               ((Pls_Don || ResVal) && (Pls_Res == ResFnd)) :
+               ((Pls_Don || ResVal) && (Pls_Res || ResFnd));
+
+MyModule #(
+    .A (1),
+    .B (2)
+) Module_1 (
+    .I (wire1),
+    .O (wire2)
+);
+
+or or_0();
+
+endmodule
+// End of copied code
+
+// Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/51
+case (Signal)
+    2'd0: begin Result <= 0; end
+    2'd1: begin Result <= 1; end
+    2'd2: begin Result <= 2; end
+    default: begin Result <= 0; end
+endcase
+// End of copied code
+
+interface class base;
+
+    pure virtual function void a(input int unsigned N, ref t Data);
+    pure virtual function void b(input int unsigned N, ref t Data);
+    pure virtual function void c(input int unsigned N, ref t Data);
+
+endclass;
+
+module m #(1)
+(
+    portA,
+    portB
+);
+
+// Nested modules (IEEE - 1800-2012, section 23.4)
+module a;
+endmodule
+
+endmodule
+
+module m (
+    portA,
+    portB
+);
+
+device d0 (
+    .port (port[1]),
+    .port2(), // comment
+    .portA(port[2])
+);
+
+// Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/6
+device d1 (
+    .port (port[1]),
+    // .port2(), // comment
+    .*
+);
+
+`ifdef DO_THIS
+    device d1 (
+        .port (port[1]),
+        /* comment line 1
+        * comment line2 */
+        .port2(),
+        .*
+    );
+`endif
+
+`ifdef DO_THIS
+    device2 d2 (
+        .out,
+        .a,
+        .b(B)/*,
+        TODO  .c(C) port not implemented yet */
+    );
+`endif
+// End of copied code
+
+device d1 (
+    .port (port[1]),
+    // .port1(), comment
+    /**/.port2(), // comment
+    /*.port3(), */
+    // .port4(), comment
+    .portA(port[2])
+);
+
+`define VALUE 3
+
+`define VALUE_MULTI_LINE \
+    16'hFF
+
+`ifdef V95
+    device d2 ( out, portA, portB );
+    device d2 ( out, portA, portB );
+    `ifdef V95
+        device d2 ( out, portA, portB );
+        device d2 ( out, portA, portB );
+    `endif
+`elsif V2K
+    device d2 ( .out(out), .* );
+    device d2 ( out, portA, portB );
+    `ifndef SWAP
+        device d3 ( .out(out), .* );
+        device d2 ( .out(out), .* );
+    `else
+        device d3 ( .out(out), .portA(portB), .portB(portA) );
+        device d2 ( .out(out), .* );
+    `endif
+`endif
+`ifndef SWAP
+    device d3 ( .out(out), .* );
+    device d2 ( .out(out), .* );
+`else
+    device d3 ( .out(out), .portA(portB), .portB(portA) );
+    device d2 ( .out(out), .* );
+`endif
+
+endmodule
+
+class a;
+endclass : a
+
+module a import some_pkg::*;
+(
+    input clk,
+    output x
+);
+
+always @ (posedge clk)
+begin
+end
+
+always
+    x <= 1;
+
+always
+begin
+    x <= 1;
+    statement();
+end
+
+always //
+begin
+    x <= 1;
+    statement();
+end
+
+label : always //
+    x <= 1;
+
+always @ (posedge clk) //
+    x <= 1;
+
+always @ (posedge clk)
+    x <= 1;
+
+always_ff // begin
+    x <= 1;
+
+always_comb
+    x <= 1;
+
+label : always_ff begin
+    begin
+        x <= 1;
+        statement();
+    end
+end
+
+always_ff @ (posedge clk)
+begin
+    x <= 1;
+    statement();
+    foreach (object[i])
+        statement();
+end
+
+always_ff @ (posedge clk)
+begin
+    x <= 1;
+    statement();
+    foreach (object[i])
+        statement();
+end
+
+always_ff @ (posedge clk)
+begin
+    x <= 1;
+    statement();
+    foreach (object[i])
+        statement();
+end
+
+always_ff @ (posedge clk)
+begin
+    x <= 1;
+    statement();
+    foreach (object[i])
+        statement();
+end
+
+always_ff @ (posedge clk)
+begin
+    x <= 1;
+    statement();
+    foreach (object[i])
+        statement();
+end
+
+always_ff @ (posedge clk)
+begin
+    x <= 1;
+    statement();
+    foreach (object[i])
+        statement();
+end
+
+always_ff @ (posedge clk)
+begin
+    x <= 1;
+    statement();
+    foreach (object[i])
+        statement();
+end
+
+always_ff @ (posedge clk)
+begin
+    x <= 1;
+    statement();
+    foreach (object[i])
+        statement();
+end
+
+// always_ff
+// begin
+//     x <= 1;
+// end
+
+endmodule
+
+if (condition) begin
+    something();
+end
+else
+    `macro_call()
+
+always : label
+    `macro_call()
+
+begin
+    begin
+    end // always
+    `dont_indent()
+    dont_deindent();
+
+    begin
+    end // foreach()
+    dont_indent();
+    dont_deindent();
+
+    begin
+    end /* while() */
+    dont_indent();
+    dont_deindent();
+end
+
+class a extends b;
+
+    local static function void hello();
+
+        something();
+    endfunction
+
+    constraint l1 {
+        y == 1;
+    }
+
+    constraint l1
+    {
+        y == 1;
+    }
+
+endclass : a
+
+extern module counter (input clk,enable,reset,
+    output logic [3:0] data);
+
+extern module counter2;
+
+class a implements
+    b,
+    c,
+    d;
+
+    function void function_with_multiline_proto(
+        object_type object);
+        indent();
+    endfunction
+
+    function void function_with_multiline_proto(
+        object_type object0,
+        object_type object1,
+        object_type object2,
+        object_type object3
+    );
+        indent();
+    endfunction
+
+endclass
+
+covergroup c1_cg (ref bit x);
+    option.per_instance = 1;
+    type_option.merge_instances = 1;
+
+    x : coverpoint x {
+        bins _0 = {1'h0};
+        bins _1 = {1'h1};
+    }
+
+endgroup
+
+package a;
+
+    class b;
+    endclass
+
+    class c;
+    endclass
+
+    class d;
+    endclass
+
+endpackage
+
+sequence acknowledge
+    ##[1:2] Ack;
+endsequence
+
+property handshake;
+    @(posedge Clock)
+    request |-> acknowledge;
+endproperty
+
+always
+    if(1) begin
+    end
+    // comment
+    else
+        {var0, var1} <= 2'b00;
+
+always
+    if (0) begin
+        var0 <= 1'b0;
+    end else if(0) begin
+        var0 <= 1'b1;
+    end
+
+// comment
+
+virtual class DataTypes_packer#(type T, int L, int W, int I);
+
+    extern static function void unpack(const ref bit [L-1:0] in, ref T out[]);
+    extern static function void unpack5(const ref bit [L-1:0] in, ref t5#(W,I) out[], input int n_MSB2ignore=0);
+
+    /*
+    // packing functions
+    extern static function void pack(const ref T in[], ref bit [L-1:0] out);
+    extern static function void pack2(const ref t2#(W,I) in[], ref bit [L-1:0] out);
+    */
+
+    // unpack functions:
+    extern static function void unpack(const ref bit [L-1:0] in, ref T out[]);
+    extern static function void unpack5(const ref bit [L-1:0] in, ref t5#(W,I) out[], input int n_MSB2ignore=0);
+
+endclass
+
+fork
+    begin
+
+        for(int i=0;i<5;i++) begin
+            automatic int idx=i;
+            fork
+                begin
+                    $display("%fns: %0d start",$realtime/1ns,idx);
+                    my_seq[idx].go();
+                end
+            join_none
+        end
+
+        // wait for all forks to end
+        wait fork;
+        $display("%fns: all done",$realtime/1ns);
+    end
+join
+
+$display("hi");
+
+assert_value: assert property (@(posedge clk) disable iff (~reset_n)
+    var0 |-> var1 == var2
+);
+
+`ifdef NOTHING
+`endif
+
+wire signal =
+    !var0 && (
+        var2
+    );
+
+task run_phase(uvm_phase phase);
+    int var0 = var1 +
+               var2 *
+               var3;
+
+    int var0 =
+        var1;
+
+    if (map.first(s))
+        do
+            $display("%s : %d\n", s, map[s]);
+        while (map.next(s));
+
+    label : assert(my_seq.randomize());
+    my_seq.start(low_sequencer_h);
+
+    assert(my_seq.randomize() with {Nr==6;});
+    my_seq.start(low_sequencer_h);
+
+    label : assert(my_seq.randomize() with
+        {Nr==6; Time==8;});
+    my_seq.start(low_sequencer_h);
+
+    assert(
+        my_seq.randomize() with
+    );
+
+    //task
+endtask
+
+function void sink_driver::build_phase(uvm_phase phase);
+
+    assert property (prop1)
+    else `uvm_fatal("TAG", "Assertion failed.")
+
+    do_something();
+
+    assert property (prop1)
+    else
+        `uvm_fatal("TAG", "Assertion failed.")
+
+    do_something();
+
+    if (condition)
+        something();
+    else `uvm_fatal("TAG", "This is invalid.")
+
+    do_something();
+
+    if (condition)
+        something();
+    else
+        `uvm_fatal("TAG", "This is invalid.")
+
+    do_something();
+endfunction
+
+// Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/51
+case (XfrState)
+    One_XFR : XfrState_str = "One";
+    Two_XFR : XfrState_str = "Two";
+    End_XFR : XfrState_str = "End";
+    default : XfrState_str = "N/A";
+endcase
+// End of copied code
+
+interface rx_if;
+    logic        trans;
+    logic [31:0] data ;
+    logic [31:0] addr ;
+endinterface
+
+generate
+    for (int i = 0; i < 9; ++i) begin : gen_loop
+        dut u_dut(.in(i));
+    end
+endgenerate
+
+program u_prg;
+    logic clk;
+endprogram
+
+// Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/71
+wire a = c <= d &
+         e = f;
+// End of copied code
+
+// Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/72
+function bit return_something();
+    return a &
+           b |
+           c;
+endfunction
+// End of copied code
+
+// Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/80
+/*
+* function text
+* text
+*/
+
+// Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/51
+module dut_wrapper (
+    interface source_IF,
+    interface sink_IF,
+    interface ctrl_IF
+);
+
+endmodule
+// End of copied code
+
+// Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/81
+cover property (
+    a &&
+    b &&
+    c
+);
+// End of copied code
+
+// Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/167
+co__ack_and_req : cover sequence (
+    req && ack
+);
+// End of copied code
+
+// Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/84
+assign out = cond0 ? a :
+             cond1 ? b :
+                     c ;
+// End of copied code
+
+// Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/85
+assert_label: assert property (
+    precondition |-> a &&
+                     b &&
+                     c
+);
+assert_label: assert property (
+    precondition |=> a &&
+                     b &&
+                     c
+);
+// End of copied code
+
+// Code from: // https://github.com/vhda/verilog_systemverilog.vim/issues/113
+assign a = b <= c &&
+           d <= e &&
+           f <= g &&
+           h <= i;
+// End of copied code
+
+// Code from: // https://github.com/vhda/verilog_systemverilog.vim/issues/129
+if (cond) begin do_something; end
+do_something_else;
+
+// Code from: // https://github.com/vhda/verilog_systemverilog.vim/issues/120
+package automatic regmodel_dpi_pkg;
+    export "DPI-SC" task check_reg;
+    task check_reg(string mystring, output bit [63:0] o1);
+    endtask
+endpackage
+// End of copied code
+
+// vi: set expandtab softtabstop=4 shiftwidth=4:
+
+ diff --git a/bundle/verilog/test/mod.sv b/bundle/verilog/test/mod.sv new file mode 100644 index 000000000..50e058144 --- /dev/null +++ b/bundle/verilog/test/mod.sv @@ -0,0 +1,52 @@ +module mod( + input wire [7:0] in1, + input wire in2, + output reg out +); +parameter PARAM1 = 1; +parameter PARAM2 = 2; + +function test( + input a, + input b, + output z +); +endfunction + +endmodule + +class myclass #( + type BASE = extended_base , + int size = 1 +) extends BASE; + logic value_myclass; + real rl_variable = 1.0; + + function method(input a, input b); + endfunction : method + + task atask(input a, output x); + endtask : atask + +endclass : myclass + +class extended_base extends base; + logic value_extended_base; + + function method(input a, input b); + endfunction : method + + task btask(input a, output x); + endtask : atask + +endclass : extended_base + +class base; + logic value_base; + + task ctask(input x, output z); + endtask : ctask + +endclass : base + +// vi: set expandtab softtabstop=4 shiftwidth=4: diff --git a/bundle/verilog/test/run_test.vim b/bundle/verilog/test/run_test.vim new file mode 100644 index 000000000..56084b41b --- /dev/null +++ b/bundle/verilog/test/run_test.vim @@ -0,0 +1,180 @@ +"----------------------------------------------------------------------- +" Global configurations +"----------------------------------------------------------------------- +" Configure custom syntax +let g:verilog_syntax_custom = { + \ 'spyglass' : [{ + \ 'match_start' : '\/\/\s*spyglass\s\+disable_block\s\+\z(\(\w\|-\)\+\(\s\+\(\w\|-\)\+\)*\)', + \ 'match_end' : '\/\/\s*spyglass\s\+enable_block\s\+\z1', + \ 'syn_argument': 'transparent keepend', + \ }], + \ } + +"----------------------------------------------------------------------- +" Syntax folding test +"----------------------------------------------------------------------- +function! RunTestFold() + let test_result=0 + + " Enable all syntax folding + let g:verilog_syntax_fold_lst="all" + set foldmethod=syntax + set noautochdir + + " Open syntax fold test file in read-only mode + silent view test/folding.v + + " Verify folding + let test_result=TestFold(0) || test_result + echo '' + + " Test with "block_nested" + let g:verilog_syntax_fold_lst="all,block_nested" + silent view! + let test_result=TestFold(1) || test_result + echo '' + + " Test with "block_named" + let g:verilog_syntax_fold_lst="all,block_named" + silent view! + let test_result=TestFold(2) || test_result + echo '' + + " Check test results and exit accordingly + if test_result + cquit + else + qall! + endif +endfunction + +"----------------------------------------------------------------------- +" Syntax indent test +"----------------------------------------------------------------------- +function! RunTestIndent() + let g:verilog_disable_indent_lst = "module,eos" + let test_result=0 + + " Open syntax indent test file + silent edit test/indent.sv + + " Verify indent + let test_result=TestIndent() || test_result + echo '' + silent edit! + + " Test again with 'ignorecase' enabled + setlocal ignorecase + let test_result=TestIndent() || test_result + echo '' + silent edit! + + " Make file read-only to guarantee that vim quits with exit status 0 + silent view! + + " Check test results and exit accordingly + if test_result + cquit + else + qall! + endif +endfunction + +"----------------------------------------------------------------------- +" Error format test +"----------------------------------------------------------------------- +function! RunTestEfm() + let test_result=0 + + set nomore "Disable pager to avoid issues with Travis + + let g:verilog_efm_quickfix_clean = 1 + + for check_uvm in [0, 1] + if check_uvm + let g:verilog_efm_uvm_lst = 'all' + else + unlet! g:verilog_efm_uvm_lst + endif + + let test_result = TestEfm('iverilog', 1, check_uvm) || test_result + let test_result = TestEfm('verilator', 1, check_uvm) || test_result + let test_result = TestEfm('verilator', 3, check_uvm) || test_result + let test_result = TestEfm('ncverilog', 1, check_uvm) || test_result + let test_result = TestEfm('ncverilog', 3, check_uvm) || test_result + let test_result = TestEfm('spyglass', 1, check_uvm) || test_result + endfor + + " Check test results and exit accordingly + if test_result + cquit + else + qall! + endif +endfunction + +"----------------------------------------------------------------------- +" Syntax test +"----------------------------------------------------------------------- +function! RunTestSyntax() + let test_result=0 + + set nomore "Disable pager to avoid issues with Travis + set foldmethod=syntax + set foldlevel=99 + + " Run syntax test for various folding configurations + let g:verilog_syntax_fold_lst='' + let test_result = TestSyntax('syntax.sv', g:verilog_syntax_fold_lst) || test_result + + let g:verilog_syntax_fold_lst='all' + let test_result = TestSyntax('syntax.sv', g:verilog_syntax_fold_lst) || test_result + + let g:verilog_syntax_fold_lst='all,block_nested' + let test_result = TestSyntax('syntax.sv', g:verilog_syntax_fold_lst) || test_result + + let g:verilog_syntax_fold_lst='all,block_named' + let test_result = TestSyntax('syntax.sv', g:verilog_syntax_fold_lst) || test_result + + let g:verilog_syntax_fold_lst='all,instance' + let test_result = TestSyntax('syntax.sv', g:verilog_syntax_fold_lst) || test_result + + let g:verilog_syntax_fold_lst='' + let test_result = TestSyntax('folding.v', g:verilog_syntax_fold_lst) || test_result + + let g:verilog_syntax_fold_lst='all' + let test_result = TestSyntax('folding.v', g:verilog_syntax_fold_lst) || test_result + + let g:verilog_syntax_fold_lst='all,block_nested' + let test_result = TestSyntax('folding.v', g:verilog_syntax_fold_lst) || test_result + + let g:verilog_syntax_fold_lst='all,block_named' + let test_result = TestSyntax('folding.v', g:verilog_syntax_fold_lst) || test_result + + let g:verilog_syntax_fold_lst='all,instance' + let test_result = TestSyntax('folding.v', g:verilog_syntax_fold_lst) || test_result + + let g:verilog_syntax_fold_lst='' + let test_result = TestSyntax('indent.sv', g:verilog_syntax_fold_lst) || test_result + + let g:verilog_syntax_fold_lst='all' + let test_result = TestSyntax('indent.sv', g:verilog_syntax_fold_lst) || test_result + + let g:verilog_syntax_fold_lst='all,block_nested' + let test_result = TestSyntax('indent.sv', g:verilog_syntax_fold_lst) || test_result + + let g:verilog_syntax_fold_lst='all,block_named' + let test_result = TestSyntax('indent.sv', g:verilog_syntax_fold_lst) || test_result + + let g:verilog_syntax_fold_lst='all,instance' + let test_result = TestSyntax('indent.sv', g:verilog_syntax_fold_lst) || test_result + + " Check test results and exit accordingly + if test_result + cquit + else + qall! + endif +endfunction + +" vi: set expandtab softtabstop=4 shiftwidth=4: diff --git a/bundle/verilog/test/syntax.sv b/bundle/verilog/test/syntax.sv new file mode 100644 index 000000000..78add7b86 --- /dev/null +++ b/bundle/verilog/test/syntax.sv @@ -0,0 +1,393 @@ +module #( + parameter TEST1 = $clog(0), + parameter TEST2 = $clog(1), + parameter TEST3 = $clog(2) +) mymodule( + input wire a, + input wire b, + `ifdef MACRO + input wire c, + `endif + output wire y +); + + othermodule #(.something (a), + .somethingelse(b) + ) inst(.p1(), .p2(), .p3 (), + .p4(), + .p5(), .p6(), .p7(), + .p8 () + .p9 (a) + ); + + mymod MOD(.IN1(), .IN2(), .OP(), + .OUT()); + +endmodule + +`define DEF_WITH_EQ = 1'b0 +`define DEF_MULTI_LINE cond(a,b,c) \ + a ? b : c + +`ifdef SYSTEM_VERILOG_KEYWORDS +accept_on +alias +always +always_comb +always_ff +always_latch +and +assert +assign +assume +automatic +before +begin +end +bind +bins +binsof +bit +break +buf +bufif0 +bufif1 +byte +case +casex +casez +cell +chandle +checker +cmos +config +const +constraint +context +continue +cover +coverpoint +cross +deassign +default +defparam +design +disable +dist +do +edge +else +endcase +endchecker +endconfig +endgenerate +endpackage +endprimitive +endprogram +endtable +enum +event +eventually +expect +export "DPI-SC" task exported_task; +extends +extern +final +first_match +for +force +foreach +forever +fork +forkjoin +generate +genvar +global +highz0 +highz1 +if +iff +ifnone +ignore_bins +illegal_bins +implements +implies +import +incdir +include +initial +inout +input +inside +instance +int +integer +interconnect +intersect +join +join_any +join_none +large +let +liblist +library +local +localparam +logic +longint +macromodule +mailbox +matches +medium +modport +nand +negedge +nettype +new +nexttime +nmos +nor +noshowcancelled +not +notif0 +notif1 +null +or +output +package +packed +parameter +pmos +posedge +primitive +priority +program +protected +pull0 +pull1 +pulldown +pullup +pulsestyle_ondetect +pulsestyle_onevent +pure +rand +randc +randcase +randsequence +rcmos +real +realtime +ref +reg +reject_on +release +repeat +restrict +return +rnmos +rpmos +rtran +rtranif0 +rtranif1 +s_always +s_eventually +s_nexttime +s_until +s_until_with +scalared +semaphore +shortint +shortreal +showcancelled +signed +small +soft +solve +specparam +static +string +strong +strong0 +strong1 +struct +super +supply0 +supply1 +sync_accept_on +sync_reject_on +table +tagged +this +throughout +time +timeprecision +timeunit +tran +tranif0 +tranif1 +tri +tri0 +tri1 +triand +trior +trireg +type +union +unique +unique0 +unsigned +until +until_with +untyped +use +uwire +var +vectored +virtual +void +wait +wait_order +wand +weak +weak0 +weak1 +while +wildcard +wire +with +within +wor +xnor +xor +// Syntax regions +typedef; +class +endclass +clocking +endclocking +covergroup +endgroup +function +endfunction +interface +endinterface +module +endmodule +property +endproperty +sequence +endsequence +specify +endspecify +task +endtask +`endif +`ifdef COMPLEX_STATEMENTS +typedef class c; +`endif +`ifdef TIME +10ns +100ns +1ps +2_0ps +3_000_000s +1.23ns +1_000.123ns +10_000.123ns +100_000.123ns +1_000_000.123ns +1.2.3ns // Second to should not be part of number syntax +1step +`endif +`ifdef NUMBERS +4'h0 +4'h1 +4'h2 +4'h3 +4'h4 +4'h5 +4'h6 +4'h7 +4'h8 +4'h9 +4'ha +4'hb +4'hc +4'hd +4'he +4'hf +4'hA +4'hB +4'hC +4'hD +4'hE +4'hF +4'hg // Invalid value for hexadecimal number +4'hG // Invalid value for hexadecimal number +3'o0 +3'o1 +3'o2 +3'o3 +3'o4 +3'o5 +3'o6 +3'o7 +3'o8 // Invalid value for octal number +3'b0_01 +3'b001 +3'b_01 +3'b120 // Invalid value for binary number +'d10000 +'d_000_000 +'d_x00_000 +4'b0?x0 +4'b010? +4'b010? ? 4'b????; // Conditional '?' and ';' should not be part of number syntax +`endif +// synopsys + +/* synopsys dc_script_begin +* set_size_only {U1} +* synopsys dc_script_end +*/ + +// synopsys dc_script_begin +// set_size_only {U1} +// synopsys dc_script_end + +// TODO todo check + +/* +* TODO todo check +*/ + +/*//my comment */ + +//my /*comment*/ + +// Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/186 +string foo = "bar, baz"; +int foo2 = 0; +// End of copied code + +// Comment with DEFINE-ML + +always@(posedge clk or posedge rst) +begin + priority if (rst) + state <= IDLE; + else + state <= NS; +end + +always @(*) begin : label + if (a) begin + y = c, z = a; + end else begin + y = d, z = b; + end +end + +assign a = myfunc(this); + +// vi: set expandtab softtabstop=4 shiftwidth=4: diff --git a/bundle/verilog/test/syntax.sv.html b/bundle/verilog/test/syntax.sv.html new file mode 100644 index 000000000..c2a55007c --- /dev/null +++ b/bundle/verilog/test/syntax.sv.html @@ -0,0 +1,397 @@ + +
+module #(
+    parameter TEST1 = $clog(0),
+    parameter TEST2 = $clog(1),
+    parameter TEST3 = $clog(2)
+) mymodule(
+    input  wire a,
+    input  wire b,
+    `ifdef MACRO
+    input  wire c,
+    `endif
+    output wire y
+);
+
+    othermodule #(.something (a),
+      .somethingelse(b)
+    ) inst(.p1(), .p2(), .p3 (),
+        .p4(),
+        .p5(), .p6(), .p7(),
+        .p8 ()
+        .p9 (a)
+    );
+
+    mymod MOD(.IN1(), .IN2(), .OP(),
+    .OUT());
+
+endmodule
+
+`define DEF_WITH_EQ = 1'b0
+`define DEF_MULTI_LINE cond(a,b,c) \
+    a ? b : c
+
+`ifdef SYSTEM_VERILOG_KEYWORDS
+accept_on
+alias
+always
+always_comb
+always_ff
+always_latch
+and
+assert
+assign
+assume
+automatic
+before
+begin
+end
+bind
+bins
+binsof
+bit
+break
+buf
+bufif0
+bufif1
+byte
+case
+casex
+casez
+cell
+chandle
+checker
+cmos
+config
+const
+constraint
+context
+continue
+cover
+coverpoint
+cross
+deassign
+default
+defparam
+design
+disable
+dist
+do
+edge
+else
+endcase
+endchecker
+endconfig
+endgenerate
+endpackage
+endprimitive
+endprogram
+endtable
+enum
+event
+eventually
+expect
+export "DPI-SC" task exported_task;
+extends
+extern
+final
+first_match
+for
+force
+foreach
+forever
+fork
+forkjoin
+generate
+genvar
+global
+highz0
+highz1
+if
+iff
+ifnone
+ignore_bins
+illegal_bins
+implements
+implies
+import
+incdir
+include
+initial
+inout
+input
+inside
+instance
+int
+integer
+interconnect
+intersect
+join
+join_any
+join_none
+large
+let
+liblist
+library
+local
+localparam
+logic
+longint
+macromodule
+mailbox
+matches
+medium
+modport
+nand
+negedge
+nettype
+new
+nexttime
+nmos
+nor
+noshowcancelled
+not
+notif0
+notif1
+null
+or
+output
+package
+packed
+parameter
+pmos
+posedge
+primitive
+priority
+program
+protected
+pull0
+pull1
+pulldown
+pullup
+pulsestyle_ondetect
+pulsestyle_onevent
+pure
+rand
+randc
+randcase
+randsequence
+rcmos
+real
+realtime
+ref
+reg
+reject_on
+release
+repeat
+restrict
+return
+rnmos
+rpmos
+rtran
+rtranif0
+rtranif1
+s_always
+s_eventually
+s_nexttime
+s_until
+s_until_with
+scalared
+semaphore
+shortint
+shortreal
+showcancelled
+signed
+small
+soft
+solve
+specparam
+static
+string
+strong
+strong0
+strong1
+struct
+super
+supply0
+supply1
+sync_accept_on
+sync_reject_on
+table
+tagged
+this
+throughout
+time
+timeprecision
+timeunit
+tran
+tranif0
+tranif1
+tri
+tri0
+tri1
+triand
+trior
+trireg
+type
+union
+unique
+unique0
+unsigned
+until
+until_with
+untyped
+use
+uwire
+var
+vectored
+virtual
+void
+wait
+wait_order
+wand
+weak
+weak0
+weak1
+while
+wildcard
+wire
+with
+within
+wor
+xnor
+xor
+// Syntax regions
+typedef;
+class
+endclass
+clocking
+endclocking
+covergroup
+endgroup
+function
+endfunction
+interface
+endinterface
+module
+endmodule
+property
+endproperty
+sequence
+endsequence
+specify
+endspecify
+task
+endtask
+`endif
+`ifdef COMPLEX_STATEMENTS
+typedef class c;
+`endif
+`ifdef TIME
+10ns
+100ns
+1ps
+2_0ps
+3_000_000s
+1.23ns
+1_000.123ns
+10_000.123ns
+100_000.123ns
+1_000_000.123ns
+1.2.3ns  // Second to should not be part of number syntax
+1step
+`endif
+`ifdef NUMBERS
+4'h0
+4'h1
+4'h2
+4'h3
+4'h4
+4'h5
+4'h6
+4'h7
+4'h8
+4'h9
+4'ha
+4'hb
+4'hc
+4'hd
+4'he
+4'hf
+4'hA
+4'hB
+4'hC
+4'hD
+4'hE
+4'hF
+4'hg // Invalid value for hexadecimal number
+4'hG // Invalid value for hexadecimal number
+3'o0
+3'o1
+3'o2
+3'o3
+3'o4
+3'o5
+3'o6
+3'o7
+3'o8 // Invalid value for octal number
+3'b0_01
+3'b001
+3'b_01
+3'b120 // Invalid value for binary number
+'d10000
+'d_000_000
+'d_x00_000
+4'b0?x0
+4'b010?
+4'b010? ? 4'b????; // Conditional '?' and ';' should not be part of number syntax
+`endif
+// synopsys
+
+/* synopsys dc_script_begin
+*  set_size_only {U1}
+*  synopsys dc_script_end
+*/
+
+// synopsys dc_script_begin
+// set_size_only {U1}
+// synopsys dc_script_end
+
+// TODO todo check
+
+/*
+* TODO todo check
+*/
+
+/*//my comment */
+
+//my /*comment*/
+
+// Code from: https://github.com/vhda/verilog_systemverilog.vim/issues/186
+string foo = "bar, baz";
+int foo2 = 0;
+// End of copied code
+
+// Comment with DEFINE-ML
+
+always@(posedge clk or posedge rst)
+begin
+  priority if (rst)
+    state <= IDLE;
+  else
+    state <= NS;
+end
+
+always @(*) begin : label
+  if (a) begin
+    y = c, z = a;
+  end else begin
+    y = d, z = b;
+  end
+end
+
+assign a = myfunc(this);
+
+// vi: set expandtab softtabstop=4 shiftwidth=4:
+
+ diff --git a/bundle/verilog/test/test.v b/bundle/verilog/test/test.v new file mode 100644 index 000000000..25a3c3f2e --- /dev/null +++ b/bundle/verilog/test/test.v @@ -0,0 +1,77 @@ +module test1; + +reg test; + + test. +test. + +mod #( + .TEST (1) +) test( + .port1 (test), + . +); + +mod test( + .port1 (test), + . +); + +mod +test( + .port1 (test), + . +); + + mod #( + .TEST (1) +) test( + .port1 (test), + . +); + + mod test( + .port1 (test), + .port2 (bus[(3-1):0]), + .port3 (test), + .in1 (in1), + . +); + + mod + test( + .port1 (test), + . +); + +ola = test. + +mod u_mod1 ( + . +); +endmodule + +class test2 #(type T=base); + +myclass #(type BASE=base) object; +myclass object_with_long_name; +myclass obj; +T typeclass; + +object.method( + . +); + +object.atask(.); + +object. + +object_with_long_name. + +obj. + +typeclass. + +endclass + +// vi: set expandtab softtabstop=4 shiftwidth=4: diff --git a/bundle/verilog/test/test_vimrc b/bundle/verilog/test/test_vimrc new file mode 100644 index 000000000..1b0ad741d --- /dev/null +++ b/bundle/verilog/test/test_vimrc @@ -0,0 +1,5 @@ +set nocompatible +set modeline +set noswapfile +filetype plugin indent on +syntax enable diff --git a/doc/SpaceVim.txt b/doc/SpaceVim.txt index 9de3ef3bc..e3232632d 100644 --- a/doc/SpaceVim.txt +++ b/doc/SpaceVim.txt @@ -202,27 +202,28 @@ CONTENTS *SpaceVim-contents* 109. lang#v.....................................|SpaceVim-layers-lang-v| 110. lang#vala...............................|SpaceVim-layers-lang-vala| 111. lang#vbnet.............................|SpaceVim-layers-lang-vbnet| - 112. lang#vim.................................|SpaceVim-layers-lang-vim| - 113. lang#vue.................................|SpaceVim-layers-lang-vue| - 114. lang#wdl.................................|SpaceVim-layers-lang-wdl| - 115. lang#wolfram.........................|SpaceVim-layers-lang-wolfram| - 116. lang#xml.................................|SpaceVim-layers-lang-xml| - 117. lang#xquery...........................|SpaceVim-layers-lang-xquery| - 118. lang#zig.................................|SpaceVim-layers-lang-zig| - 119. language server protocol......................|SpaceVim-layers-lsp| - 120. leaderf...................................|SpaceVim-layers-leaderf| - 121. mail.........................................|SpaceVim-layers-mail| - 122. operator.................................|SpaceVim-layers-operator| - 123. shell.......................................|SpaceVim-layers-shell| - 124. ssh...........................................|SpaceVim-layers-ssh| - 125. test.........................................|SpaceVim-layers-test| - 126. tmux.........................................|SpaceVim-layers-tmux| - 127. tools#dash.............................|SpaceVim-layers-tools-dash| - 128. tools#mpv...............................|SpaceVim-layers-tools-mpv| - 129. tools#zeal.............................|SpaceVim-layers-tools-zeal| - 130. treesitter.............................|SpaceVim-layers-treesitter| - 131. ui.............................................|SpaceVim-layers-ui| - 132. unite.......................................|SpaceVim-layers-unite| + 112. lang#verilog.........................|SpaceVim-layers-lang-verilog| + 113. lang#vim.................................|SpaceVim-layers-lang-vim| + 114. lang#vue.................................|SpaceVim-layers-lang-vue| + 115. lang#wdl.................................|SpaceVim-layers-lang-wdl| + 116. lang#wolfram.........................|SpaceVim-layers-lang-wolfram| + 117. lang#xml.................................|SpaceVim-layers-lang-xml| + 118. lang#xquery...........................|SpaceVim-layers-lang-xquery| + 119. lang#zig.................................|SpaceVim-layers-lang-zig| + 120. language server protocol......................|SpaceVim-layers-lsp| + 121. leaderf...................................|SpaceVim-layers-leaderf| + 122. mail.........................................|SpaceVim-layers-mail| + 123. operator.................................|SpaceVim-layers-operator| + 124. shell.......................................|SpaceVim-layers-shell| + 125. ssh...........................................|SpaceVim-layers-ssh| + 126. test.........................................|SpaceVim-layers-test| + 127. tmux.........................................|SpaceVim-layers-tmux| + 128. tools#dash.............................|SpaceVim-layers-tools-dash| + 129. tools#mpv...............................|SpaceVim-layers-tools-mpv| + 130. tools#zeal.............................|SpaceVim-layers-tools-zeal| + 131. treesitter.............................|SpaceVim-layers-treesitter| + 132. ui.............................................|SpaceVim-layers-ui| + 133. unite.......................................|SpaceVim-layers-unite| 7. Usage....................................................|SpaceVim-usage| 1. alternate file........................|SpaceVim-usage-alternate-file| 2. buffers-and-files..................|SpaceVim-usage-buffers-and-files| @@ -4957,6 +4958,16 @@ KEY BINDINGS < +============================================================================== +LANG#VERILOG *SpaceVim-layers-lang-verilog* + +This layer is for verilog development, disabled by default, to enable this +layer, add following snippet to your SpaceVim configuration file. +> + [[layers]] + name = 'lang#verilog' +< + ============================================================================== LANG#VIM *SpaceVim-layers-lang-vim* diff --git a/docs/cn/layers/lang/verilog.md b/docs/cn/layers/lang/verilog.md new file mode 100644 index 000000000..bc57f58c6 --- /dev/null +++ b/docs/cn/layers/lang/verilog.md @@ -0,0 +1,28 @@ +--- +title: "SpaceVim lang#verilog 模块" +description: "这一模块为 verilog 开发提供支持,包括交互式编程、一键运行等特性。" +lang: zh +--- + +# [可用模块](../../) >> lang#verilog + + + +- [模块简介](#模块简介) +- [启用模块](#启用模块) + + + +## 模块简介 + +这一模块为在 SpaceVim 中进行 verilog 开发提供了支持。 + +## 启用模块 + +可通过在配置文件内加入如下配置来启用该模块: + +```toml +[[layers]] + name = "lang#verilog" +``` + diff --git a/docs/layers/lang/verilog.md b/docs/layers/lang/verilog.md new file mode 100644 index 000000000..625e41cc4 --- /dev/null +++ b/docs/layers/lang/verilog.md @@ -0,0 +1,27 @@ +--- +title: "SpaceVim lang#verilog layer" +description: "This layer is for verilog development, provides syntax checking, code runner and repl support for verilog files." +--- + +# [Available Layers](../../) >> lang#verilog + + + +- [Description](#description) +- [Install](#install) + + + +## Description + +This layer is for verilog development. + +## Install + +To use this configuration layer, update your custom configuration file with: + +```toml +[[layers]] + name = "lang#verilog" +``` +