├── .gitignore
├── test.sv
├── LICENSE
├── README.md
├── plugin
├── verilog_instance.vim
└── verilog_instance.py
└── doc
└── verilog_instance.txt
/.gitignore:
--------------------------------------------------------------------------------
1 | /doc/tags
2 |
--------------------------------------------------------------------------------
/test.sv:
--------------------------------------------------------------------------------
1 | module sub_block(
2 | input clk, // 50 MHz clk
3 | input /* foo */ rstn,
4 | /* interface
5 | * network_if.IN i0, i1,
6 | * network_if.OUT o0, o1
7 | */
8 | fifo_if_.IN i0, i1, // fifo in
9 | fifo_if_.OUT o0, o1,
10 |
11 | input custom_t data_in,
12 | // output
13 | output reg[31:0] /*comment*/ reg32_out,
14 | output custom_t data_out
15 | );
16 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Antoine
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | verilog-instance.vim
2 | ====================
3 |
4 | Create SystemVerilog port instantiation from port declaration.
5 |
6 | Work on modules, tasks, functions and all other similar structures.
7 |
8 | 
9 |
10 | Installation
11 | ------------
12 |
13 | Use your favorite plugin manager.
14 |
15 | Using [vim-plug](https://github.com/junegunn/vim-plug):
16 |
17 | ```vim
18 | Plug 'antoinemadec/vim-verilog-instance'
19 | ```
20 |
21 | Quick start guide
22 | -----------------
23 |
24 | try these commands:
25 |
26 | - `gbi(`
27 | - Start VerilogInstance command (`gb`) for `i`nner `(`parenthesis
28 | - `vjjgb`
29 | - `v`isual-select `j` down twice
30 | - Start VerilogInstance command (`gb`) on the 3 selected lines
31 |
32 | Options
33 | -------
34 | - let g:verilog_instance_skip_last_coma = {0/1}
35 | - When the variable is 1, last printed line will skip the coma. Default value is 0.
36 | - let g:verilog_instance_keep_comments = {0/1}
37 | - When the variable is 1, comments will be kept (block comments /* */ not support!). Default value is 0.
38 | - let g:verilog_instance_keep_empty_lines = {0/1}
39 | - When the variable is 1, empty lines in your code will be printed. Default value is 0.
40 |
41 | Other vim plugins for Verilog/SystemVerilog
42 | ---------------------------------------
43 |
44 | ### verilog_systemverilog
45 |
46 | [verilog_systemverilog](https://github.com/vhda/verilog_systemverilog.vim) is a syntax plugin for Verilog and SystemVerilog
47 |
48 | Author
49 | ------
50 |
51 | [Antoine Madec](https://github.com/antoinemadec)
52 |
53 | License
54 | ------
55 |
56 | MIT
57 |
--------------------------------------------------------------------------------
/plugin/verilog_instance.vim:
--------------------------------------------------------------------------------
1 | " Create Verilog port instantiation from port declaration
2 | " Maintainer: Antoine Madec
3 |
4 | if exists("g:loaded_verilog_instance") || &cp
5 | finish
6 | endif
7 | let g:loaded_verilog_instance = 1
8 |
9 | let s:plugin_dir_path = fnamemodify(resolve(expand(':p')), ':h')
10 |
11 | if !get(g:, 'verilog_instance_skip_last_coma')
12 | let g:verilog_instance_skip_last_coma = 0
13 | endif
14 |
15 | if !get(g:, 'verilog_instance_keep_comments')
16 | let g:verilog_instance_keep_comments = 0
17 | endif
18 |
19 | if !get(g:, 'verilog_instance_keep_empty_lines')
20 | let g:verilog_instance_keep_empty_lines = 0
21 | endif
22 |
23 | function! s:VerilogInstance(type,...) abort
24 | if a:0
25 | let [lnum1, lnum2] = [a:type, a:1]
26 | else
27 | let [lnum1, lnum2] = [line("'["), line("']")]
28 | endif
29 | let cmd = lnum1 . "norm! =="
30 | execute cmd
31 | let cmd = lnum1 . "," . lnum2 . "!" . " " . s:plugin_dir_path . "/verilog_instance.py " . g:verilog_instance_skip_last_coma . g:verilog_instance_keep_comments . g:verilog_instance_keep_empty_lines
32 | execute cmd
33 | endfunction
34 |
35 | xnoremap VerilogInstance :call VerilogInstance(line("'<"),line("'>"))
36 | nnoremap VerilogInstance :set opfunc=VerilogInstanceg@
37 | nnoremap VerilogInstanceLine :set opfunc=VerilogInstanceexe 'norm! 'v:count1.'g@_'
38 | command! -range VerilogInstance call s:VerilogInstance(,)
39 |
40 | if !hasmapto('VerilogInstance') && maparg('gb','n') ==# ''
41 | xmap gb VerilogInstance
42 | nmap gb VerilogInstance
43 | nmap gbb VerilogInstanceLine
44 | endif
45 |
--------------------------------------------------------------------------------
/doc/verilog_instance.txt:
--------------------------------------------------------------------------------
1 | *verilog-instance* Create SystemVerilog port instantiation from port declaration
2 |
3 | Author: Antoine Madec
4 | License: Same terms as Vim itself (see |license|)
5 |
6 | CONTENTS *verilog-instance-contents*
7 |
8 | Introduction |verilog-instance-intro|
9 | Commands |verilog-instance-commands|
10 | Options |verilog-instance-options|
11 | Key Mappings |verilog-instance-key-mappings|
12 | About |verilog-instance-about|
13 |
14 | ==============================================================================
15 | INTRODUCTION *verilog-instance-intro*
16 |
17 | Create SystemVerilog port instantiation from port declaration.
18 | Work on modules, tasks, functions and all other similar structures.
19 |
20 | ------------------------------------------------------------------------------
21 | COMMANDS *verilog-instance-commands*
22 |
23 | *gb*
24 | gb{motion} Create port instantiation from lines that {motion} moves over.
25 |
26 | *gbb*
27 | gbb Create port instantiation from current line.
28 |
29 | *gb-visual*
30 | {Visual}gb Create port instantiation from the highlighted lines.
31 |
32 | ------------------------------------------------------------------------------
33 | OPTIONS *verilog-instance-options*
34 |
35 | *g:verilog_instance_skip_last_coma*
36 | let g:verilog_instance_skip_last_coma = {0/1}
37 | When the variable is 1, last printed line will skip the coma.
38 | The default value is 0.
39 |
40 | *g:verilog_instance_keep_comments*
41 | let g:verilog_instance_keep_comments = {0/1}
42 | When the variable is 1, comments will be kept (block comments /* */ not support!).
43 | The default value is 0.
44 |
45 | *g:verilog_instance_keep_empty_lines*
46 | let g:verilog_instance_keep_empty_lines = {0/1}
47 | When the variable is 1, empty lines in your code will be printed.
48 | The default value is 0.
49 |
50 | ------------------------------------------------------------------------------
51 | KEY MAPPINGS *verilog-instance-key-mappings*
52 |
53 | By default, the plugin uses |gb| and |gbb| mappings if not already mapped.
54 | Those are the prefered mappings, but if they are already used, you can change
55 | them by adding something like that in your vimrc :
56 |
57 | xmap ga VerilogInstance
58 | nmap ga VerilogInstance
59 | nmap gaa VerilogInstanceLine
60 |
61 | ------------------------------------------------------------------------------
62 | ABOUT *verilog-instance-about*
63 |
64 | Grab the latest version or report a bug on GitHub:
65 | https://github.com/antoinemadec/vim-verilog-instance
66 |
67 | vim:tw=78:ts=8:ft=help:norl:
68 |
--------------------------------------------------------------------------------
/plugin/verilog_instance.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | """this script is a basic script for doing verilog editing
4 | it parses the variables from stdin and generate a verilog name instantiation
5 | of the variables"""
6 |
7 | import re
8 | import sys
9 |
10 | skip_last_coma = 0
11 | keep_comment = 1
12 | keep_empty_line = 1
13 | if len(sys.argv) > 1:
14 | skip_last_coma = int(sys.argv[1])
15 |
16 | if len(sys.argv) > 2:
17 | keep_comment = int(sys.argv[2])
18 |
19 | keywords = []
20 | keywords.extend(["input", "output", "inout", "ref", "parameter", "localparam"])
21 | keywords.extend(["reg", "logic", "wire", "bit", "integer", "int", "string", "type"])
22 | keywords.extend(["const", "unsigned"])
23 |
24 | patterns = []
25 | patterns.append(re.compile(r'\[[^\[\]]*\]')) # port size, array size
26 | patterns.append(re.compile(r'=.*')) # assignment
27 | patterns.append(re.compile(r'//.*') )
28 | patterns.append(re.compile(r'\w+\.\w+')) # interfaces with modport
29 | for kw in keywords: # match keywords
30 | patterns.append(re.compile("\\b%s\\b" % kw))
31 |
32 | pattern_empty_line = re.compile(r'^\s*$')
33 | pattern_open_comment = re.compile(r'/\*.*')
34 | pattern_close_comment = re.compile(r'.*\*/')
35 | pattern_open_to_close_comment = re.compile(r'/\*.*\*/')
36 | pattern_punctuation = re.compile(r'[,;]')
37 | pattern_two_words_no_coma = re.compile(r'^\s*(\w+)\s+(\w+.*)')
38 | pattern_spaces = re.compile(r'\s+')
39 |
40 | pattern_inline_comment_kept = re.compile(r'.*\w+.*(//.*)') # comment in port define
41 | pattern_comment_kept = re.compile(r'\s*(//.*)') # one line comment
42 |
43 | ports = []
44 | ports_comments = {} # save comment for every port
45 | contents = [] # save ports and single line comments
46 | wait_to_close_comment = 0
47 | indent_len = -1
48 |
49 | for line in sys.stdin:
50 | # get indentation length from 1st non empty line
51 | if indent_len == -1 and not(pattern_empty_line.match(line)):
52 | indent_len = len(re.match(r'^\s*', line).group(0))
53 | # handle empty line
54 | if pattern_empty_line.match(line) is not None:
55 | contents.append('')
56 | # handle comments
57 | if wait_to_close_comment:
58 | if pattern_close_comment.search(line):
59 | line = pattern_close_comment.sub(' ', line)
60 | wait_to_close_comment = 0
61 | else:
62 | continue
63 | if pattern_open_comment.search(line):
64 | if pattern_close_comment.search(line):
65 | line = pattern_open_to_close_comment.sub(' ', line)
66 | else:
67 | wait_to_close_comment = 1
68 | continue
69 | # handle port comment
70 | port_comment = pattern_inline_comment_kept.match(line)
71 | if port_comment is not None:
72 | port_comment = port_comment.group(1)
73 | # handle single line comment
74 | line_comment = pattern_comment_kept.match(line)
75 | if line_comment is not None:
76 | line_comment = line_comment.group(1)
77 | # handle all other patterns
78 | for pattern in patterns:
79 | line = pattern.sub(' ', line)
80 | # handle typedef, class and interfaces
81 | line = pattern_two_words_no_coma.sub('\\2', line)
82 | line = pattern_punctuation.sub(' ', line)
83 | line = pattern_spaces.sub(' ', line)
84 | # finally, get port names
85 | line = line.strip()
86 | if line != "":
87 | port_names = line.split(' ')
88 | ports.extend(port_names)
89 | contents.extend(port_names)
90 | for port in port_names:
91 | ports_comments[port] = port_comment
92 | else:
93 | # add single line comment to port
94 | if line_comment is not None:
95 | contents.append(line_comment)
96 |
97 | ports_nb = len(ports)
98 | i = 0
99 | if ports_nb > 0:
100 | max_str_len = len(max(ports, key=len))
101 | indent_str = " " * indent_len
102 | for content in contents:
103 | if len(content) > 0:
104 | if content[:2] == "//":
105 | if keep_comment == 1:
106 | print(f'{indent_str}{content}')
107 | continue
108 | else:
109 | # empty line
110 | if keep_empty_line == 1:
111 | print('')
112 | continue
113 | port = content
114 | skip_coma = skip_last_coma and i == (ports_nb - 1)
115 | space_str = " " * (max_str_len - len(port))
116 | output_line_port = "%s.%s%s (%s%s)%s" % (
117 | indent_str, port, space_str, port, space_str, (",", "")[skip_coma])
118 | if ports_comments.get(port) is not None and keep_comment == 1:
119 | # add port comment
120 | output_line = f"{output_line_port} {ports_comments.get(port)}"
121 | else:
122 | output_line = output_line_port
123 | print(output_line)
124 | i = i + 1
125 |
--------------------------------------------------------------------------------