├── .gitignore ├── LICENSE ├── README.md ├── doc └── verilog_instance.txt ├── plugin ├── verilog_instance.py └── verilog_instance.vim └── test.sv /.gitignore: -------------------------------------------------------------------------------- 1 | /doc/tags 2 | -------------------------------------------------------------------------------- /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 | ![](https://raw.githubusercontent.com/antoinemadec/gif/master/veriloginstance.gif) 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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | --------------------------------------------------------------------------------