Coder Social home page Coder Social logo

verilog_systemverilog.vim's Introduction

Vim Syntax Plugin for Verilog and SystemVerilog

Build Status

About

Based on script originally found at:

http://www.vim.org/scripts/script.php?script_id=1586

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 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 (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

To enable syntax folding set the following option:

let g:verilog_syntax_fold_lst = "all"
set foldmethod=syntax

For more information check the help page :help veriog-fold.

Verilog Compilation and Error format

This plugin includes the 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:

: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 has been so defined, it is only a matter of setting 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 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:

nnoremap <leader>i :VerilogFollowInstance<CR>
nnoremap <leader>I :VerilogFollowPort<CR>

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 <leader>u :VerilogGotoInstanceStart<CR>

Installation

Using vim-plug

  1. Add the following to your vimrc:

    Plug 'vhda/verilog_systemverilog.vim'
  2. Run:

    $ vim +PlugInstall +qall

Using Vundle

  1. Add the following to your vimrc:

    Plugin 'vhda/verilog_systemverilog.vim'
  2. Run:

    $ vim +PluginInstall +qall

Using Pathogen

$ 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:

runtime macros/matchit.vim

Highlight Matchit

The hl_matchit.vim addon complements Matchit by automatically underlining matching words, similarly as Vim already does for parentheses/brackets.

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:

let g:SuperTabDefaultCompletionType = 'context'

When this is done Supertab will choose the most appropriate type of completion to use depending on the current context.

Tagbar

Tagbar 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.

The required filetype related configuration for Tagbar is included within this addon.

FastFold

Vim can become very slow in Insert mode when using Syntax Folding and the folds extend across the complete file. The FastFold 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.

verilog_systemverilog.vim's People

Contributors

alhadis avatar antoinemadec avatar asahsieh avatar ghilton319 avatar hanebarla avatar henry-hsieh avatar jrudess avatar kitmonisit avatar lewis6991 avatar peterfab9845 avatar vhda avatar weirane avatar yanma avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

verilog_systemverilog.vim's Issues

.v files detected as verilog

Sorry for the n00b question, but I just realized that my .v files are still recognized as "verilog" files and not "verilog_systemverilog". Any reason why the default filetype file would take precedence ?

Omni-completion does not work in non-hierarchical references

Given the following example:

module top;
  function f(
    input a,
    input b
  );
  endfunction : f

  initial begin
    f(.<tab>
    );
  end
endmodule

When pressing inside the function port list will not work as expected. This happens because the qualified output of ctags is the following:

a       o.v     /^    input a,$/;"      p       function:top.f
b       o.v     /^    input b$/;"       p       function:top.f
f       o.v     /^  function f($/;"     f       module:top
top     o.v     /^module top;$/;"       m
top.f   o.v     /^  function f($/;"     f       module:top
top.f.a o.v     /^    input a,$/;"      p       function:top.f
top.f.b o.v     /^    input b$/;"       p       function:top.f

So f.a is only available in the context top.

For this reason the omni-completion script must determine the current context before searching for tags, such that it can search for top.f.* instead of f.*.

Indent bug when a comment is inside module instantiation

I was trying out your plugin (looks promising). I discovered that comments inside a module instantiation break indenting when there is a line that starts with a comment.

Example: The auto formatting indents the code as following:

`ifdef DO_THIS
    device d1 (
        .port (port[1]),
        // .port2(), comment
        .*
        );
    `endif

Should be:

`ifdef DO_THIS
    device d1 (
        .port (port[1]),
        // .port2(), comment
        .*
    );
`endif

However this formats correctly (comment is after port connection):

`ifdef DO_THIS
    device d1 (
        .port (port[1]),    // comment
        .*
    );
`endif

Other examples demonstrating the indent bug:

`ifdef DO_THIS
    device d1 (
        .port (port[1]),
        /* comment before port connection on the same line */ .port2()
        .*
        );
    `endif
`ifdef DO_THIS
    device2 d2 (
        .out,
        .a,
        .b(B)/*,
        TODO  .c(C) port not implemented yet */
        );
    `endif

indentation with single line if

The following if without begin/end stays indented for more than 1 line:

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

Return assignment issue

function bit return_something();
    return a &
        b |
        c;
endfunction

Should be:

function bit return_something();
    return a &
           b |
           c;
endfunction

indent issue when {} in macro

The following indents incorrectly:

task my_seq::body();

    `uvm_info({get_type_name(),"::body"}, "something" ,UVM_HIGH)
req = my_seq_item_REQ::type_id::create("req");

endtask

Folds not working properly on some if statements

The following does not properly fold:

if (cond1) begin
    do1(); 
end else if (cond2) begin
    do2();
    do3();
    do4();
end else begin
    do5();
end

And further folds even worse:

if (cond1) 
    do1();
else if (cond2) begin
    do2();
    do3();
    do4();
end else begin
    do5();
end

NC Verilog Errorformat Addition

I've been using the following with NCVerilog and UVM and it works reasonably well. UVM_FATAL does highlight during the summary report at the end, but the rest seems good. I would suggest test-driving and adding these to your existing toolset options.

" From https://github.com/ryanlee/vim/blob/master/vimfiles/compiler/ncverilog.vim
set errorformat+=%A%p\|,%Z%.%#:\ \*%t\\,%.%#\ \(%f\\,%l\|%c\):%m
" Ignore warnings (keep a copy looking for %t instead of W to define errors as errors)
set errorformat+=%-G%.%#\ *W\\,%.%#(%f\\,%l\|%c):\ %m
" Add abillity to parse verilog errors (%t matches 'E' or 'W' for type):
set errorformat+=%.%#\ *%t\\,%.%#(%f\\,%l\|%c):\ %m
" Assertions don't have the column information:
set errorformat+=%.%#\ *%t\\,%.%#(%f\\,%l):\ %m
"set errorformat=%.%#\ *%t\\,%.%#(%f\\,%l):\ %m
" Add abillity to parse NULL pointer errors:
set errorformat+=%E%>%.%#\ *E\\,%m,%C%.%#File:\ %f\\,\ line\ =\ %l\\,\ pos\ =\ %c,%Z%m
" Add abillity to parse assertion errors %.%# is like .* in regex:
set errorformat+=%.%#:\ *%t\\,%.%#\ (%f\\,%l):\ %m
" Add abillity to parse UVM errors:
set errorformat+=UVM_%tRROR\ %f(%l)\ %m
set errorformat+=UVM_%tRROR:\ %m
set errorformat+=%-GUVM_ERROR\ :%p0
"UVM_FATAL is an error that has no file associate with it.
" If we add it to errorformat, we lose visibility of "UVM_FATAL"
" This is an issue with the simulation report...
set errorformat+=UVM_FATAL\ %f(%l)\ %m
set errorformat+=%-GUVM_FATAL\ :%p0
set errorformat+=UVM_FATAL\ %m
"Ignore tool version information 'ncvlog(64): version......'
set errorformat+=-G^ncelab(64):%.%#
set errorformat+=-G^ncvlog(64):%.%#
set errorformat+=-G^irun(64):%.%#
set errorformat-=%f(%l):%m "This is subtractive as it catches the tool name as an error

Improve syntax performance

This issue has the purpose of tracking any reported syntax performance issues.
New issues should be added as a comment and I will update the list accordingly.
Please provide example code whenever possible.

  • Poor performance in when there is a fold that occupies the complete file - Vim limitation, can be overcome using FastFold plugin.
  • Introduce new global variable to disable the slower syntax elements.
  • Try to optimize performance of slower syntax elements, as reported in #42 (comment), below.

indenting with constraints

This code does not indent as expected:

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);

endtask

Allow indentation inside class, interface, etc

The option b:verilog_indent_modules allows having the code indented inside modules, but there is no such option for class, interface, etc. There should exist a new option that allows this, preferably something that allows configuration of which elements to indent, like is done with g:verilog_syntax_fold.

Indent script does not work well with uvm macros

Because the indent script uses ); to determine indents, uvm macros don't indent properly.

For those who do not know, UVM is an infrastructure/library for SystemVerilog to provide a structured verification methodology. UVM uses `define macros heavily. For example the error reporting macro is:

`uvm_info("TAG", "message", UVM_MEDIUM)

The awkward thing about these macros is they do not require a ; at the end of them and some simulators actually provide warning if you do. Also in some cases providing the ; can cause an error:

if (condition)
  `uvm_info("TAG", "message1", UVM_MEDIUM);
else
  `uvm_info("TAG", "message2", UVM_NONE);

This will cause an error because the simulator will see ;; after the first if and will put the else out of context.

I understand that this is a complex issue so I accept that a solution to this may be infeasible.

Any solution would have to detect a ) and then check if it belongs to a macro or not.

struct typedef indent

It seems I can not get the correct indent when I use a struct typedef as below. It for example indents as:

class z;

typedef struct { 
    real a;
int b;             
int c;               
real d; } ts;
ts s[];

int unsigned cnt=0;

function new();
    super.new();
endfunction;

endclass;

pure virtual functions indent wrong

This does not indent correctly:

virtual 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;

Add support for implication operators.

Current behaviour:

assert_label: assert property (  
    precondition |-> a &&
    b &&
    c
);

Proposed:

assert_label: assert property (  
    precondition |-> a &&
                     b &&
                     c
);

multi-line comments indenting

class c;
    extern function f();
    extern function g();
    /*
    this is commented out
    this is commented out
    this is commented out
    */
   extern function h();
endclass

does not indent correctly.

Testing folds

Is there any way of automatically testing folds or is it done manually at this point. If it's manual then I think I have a way of testing it automatically.

Missing highlights for some SystemVerlog keywords

IEEE Std 1800-2005 missing keyword highlighting:

  • unique

IEEE Std 1800-2009 missing keyword highlighting:

  • accept_on
  • eventually
  • global
  • implies
  • let
  • nexttime
  • reject_on
  • restrict
  • s_always
  • s_eventually
  • s_nexttime
  • s_until
  • s_until_with
  • strong
  • sync_accept_on
  • sync_reject_on
  • unique0
  • until
  • until_with
  • untyped
  • weak

IEEE Std 1800-2012 missing keyword highlighting:

  • implements
  • interconnect
  • nettype
  • soft

Source : IEEE Std 1800-2012 § 22.14.6 IEEE 1800-2005 keywords, § 22.14.7 IEEE 1800-2009 keywords, & § 22.14.8 IEEE 1800-2012 keywords

Review perfomance impact when reading configuration variables

Reading a configuration variable may have some impact, even if small, on performance.

This issue serves as a reminder that this possible performance impact should be reviewed. The improvements should also take into account their impact on the user:

  • Can the user dynamically update the configuration?
  • Is it beneficial to have a local buffer override option together with a global version of the variable?

Items identified for review:

  • Disable indent configuration (PR #94).

# moves to column 0 if smartindent is enabled

I noticed that when stating a new line with # and smartindent is enabled, the line will un-indent back to column 0. Formatting with == or gg=V corrected the indenting, but the extra step is not desired.

Poking around the vim documentation I found this:

When typing '#' as the first character in a new line, the indent for that line is removed, the '#' is put in the first column. The indent is restored for the next line. If you don't want this, use this mapping: ":inoremap # X^H#", where ^H is entered with CTRL-V CTRL-H.

Adding au FileType verilog_systemverilog inoremap # X^H# to my ~/.vimrc is one solution. I am more in favor of add the below to indent/verilog_systemverilog.vim (or another file) so other users with smartindent will not run into the same issue.

" inoremap if smartindent is on (^H is CTRL-V CTRL-H)
inoremap # X^H#

From my tests, the change only effects the intended verilog/systemverilog files. c/cpp files retain the column shift functionality.

Note: don't copy-past inoremap # X^H#, the ^H need to entered as CTRL-V CTRL-H in vim

Assignment indentation bug.

Found an edge case that breaks the indentation script.

value = cond0         ? 0 :
        addr == 4'd14 ? a :
          cond1         ? b : 0;

Pretty sure it is the == causing the issue.

module not indenting?

I am hesitant to submit this issue as this pretty basic, and might be an error in my side.

module m (input clk);

import uvm_pkg::*;

initial begin
    $display("something");
end

endmodule

The content of the module does not seem to be indented?

Disable folding for "extern" functions and tasks

Must support:

pure virtual { class_item_qualifier } method_prototype ;
extern { method_qualifier } method_prototype ;

class_item_qualifier ::=
  static
  | protected
  | local

method_qualifier ::=
  [ pure ] virtual
  | class_item_qualifier

indent after 2 asserts

this code:

task run_phase(uvm_phase phase);

    assert(out>0) else $warning("xxx");
    assert(out>0) else $warning("xxx");
foreach(out[i]) begin
    out[i]=new;
end


endtask

doesn't indent correctly.

With a single assert it does indent correctly

virtual functions indent

This code indents incorrectly:

class x;
virtual function void pack(ref bit[W-1:0] out);
$display("hi");
endfunction
function void y();
endfunction
endclass

when removing the virtual keyword it is ok.

allow folding of module instances

Hello,

Currently it is possible to fold a number of constructs but as far as I know it is not possible to fold the text where verilog modules are being instantiated.

Would you consider this request?

Thanks anyway for the awesome plugin!

Indenting does not work well when implementing interface classes

More specifically; indenting doesn't work as desired if implementing from multiple interface classes and placing each interface on its own line. Example in question:

class a implements
    interface1, // Different indentation to following lines.
        interface2,
        interface3,
        interface4;

        function new(); // Wrong indentation
        endfunction
endclass

Preferably I would like the indentation to be as the following (if possible):

class a implements
        interface1,
        interface2,
        interface3,
        interface4;

    function new(); // Wrong indentation
    endfunction
endclass

Wrong indentation with single-line case statements

In the following situation:

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

the automatic indenting gives the result below:

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

Odd indentation when using vlog 2001 parameterized instantiation/declaration

What should be:

module MyModule #(
  parameter A = 1,
  parameter B = 2
)(
  input I,
  output o
);

is indented as follows:

module MyModule #(
  parameter A = 1,
  parameter B = 2
  )(
    input I,
    output O
  );

And throws off all subsequent indentation. The same goes with instantiation:

MyModule #(
  .A (1),
  .B (2)
) Module_1 (
  .I (...),
  .O (...)
);

is indented as follows:

MyModule #(
  .A (1),
  .B (2)
  ) Module_1 (
    .I (...),
    .O (...)
  );

fork join indenting

fork - join with named begin/end block indenting seems to be broken:

task run_phase(uvm_phase phase);

    fork 
    begin : isolating_thread
        do_something();
    end : isolating_thread 
join

endtask

OmniComplete doesn't work

Looks to me like there a syntax error in the omni complete function. When I try to use omni, vim gives me the following error:

Error detected while processing function verilog_systemverilog#Complete:
line 119:
E583: multiple :else:   else

File used on:

class b;
   bit field1;
   bit field2;
endclass : b

class a;
    b b_inst;

    function void update();
        b_inst.[omni complete here]
    endfunction : update
endclass : a

Consider supporting Syntastic

The Syntastic is a popular syntax checking plugin for Vim. This plugin is extensible and allow for other plugins to add their own parsers and/or syntax checkers, as is explained in their Syntax Checker Guide.

At the moment verilog_systemverilog.vim includes internally defined errorformat configurations for some Verilog/SystemVerilog compilers that can be selected through the VerilogErrorFormat function. Given the popularity to the above mentioned plugin it might make sense to consider supporting it directly for people who have it installed, while also keeping the current solution available for those who aren't.

This is a low priority issue that has the objective of opening a discussion to determine if this makes sense or not.

Last line of conditional assignment

Current indent behaviour:

assign out = cond0 ? a :
             cond1 ? b :
             c;

Proposed indent behaviour:

assign out = cond0 ? a :
             cond1 ? b :
                     c ;

@vhda, what do you think about this.

Review and update all variables

Review all variables in regards to consistency and functionality:

  1. Decide if variable should be buffer local or global.
  2. Decide if variable is still necessary.

Allow for breaking backward compatibility. Note: add warning to README.md.

Checklist (to be updated until release 3.0):

  • Drop b:verilog_indent_modules
  • Drop b:verilog_indent_preproc

indent with {} in comment

It seems when {} is present in a comment, the next line wrongly indented:

task m;

    if(scope_name=="") begin
        scope_name = get_full_name();  // fdfds {dfsdfs}
end

endtask

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.