Commits

Anonymous committed d4ef234

Module instantiation feature + Syntax highlight fix

- Fix a few highlight issue around typedef, userdefined type and interface
- Change module declaration highlight to start having context information (to be used by incoming feature)

Comments (0)

Files changed (7)

SystemVerilog.tmLanguage

 			<!-- Typedef Struct/enum-->
 			<dict>
 				<key>begin</key>
-				<string>\b(typedef\s+(struct|enum))\s*(packed)?</string>
+				<string>\s*\b(typedef\s+(struct|enum))\s*(packed)?</string>
 				<key>beginCaptures</key>
 				<dict>
 					<key>1</key>
 					</dict>
 				</array>
 				<key>name</key>
-				<string>meta.struct.systemverilog</string>
+				<string>meta.typdef.systemverilog</string>
 			</dict>
 			<!-- Typedef class -->
 			<dict>
 				<key>match</key>
-				<string>\b(typedef\s+class)\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*;</string>
+				<string>\s*\b(typedef\s+class)\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*;</string>
 				<key>captures</key>
 				<dict>
 					<key>1</key>
 					</dict>
 				</dict>
 				<key>name</key>
-				<string>meta.struct.systemverilog</string>
+				<string>meta.typdef.systemverilog</string>
 			</dict>
 			<!-- Typedef simple -->
 			<dict>
 				<key>begin</key>
-				<string>\b(typedef)\b</string>
+				<string>\s*\b(typedef)\b</string>
 				<key>beginCaptures</key>
 				<dict>
 					<key>1</key>
 					</dict>
 				</array>
 				<key>name</key>
-				<string>meta.struct.systemverilog</string>
+				<string>meta.typdef.systemverilog</string>
+			</dict>
+			<!-- Module declaration -->
+			<dict>
+				<key>begin</key>
+				<string>\s*(module)\s+\b([a-zA-Z_][a-zA-Z0-9_]*)\b</string>
+				<key>beginCaptures</key>
+				<dict>
+					<key>1</key>
+					<dict>
+						<key>name</key>
+						<string>keyword.control.systemverilog</string>
+					</dict>
+					<key>2</key>
+					<dict>
+						<key>name</key>
+						<string>entity.name.type.module.systemverilog</string>
+					</dict>
+				</dict>
+				<key>end</key>
+				<string>;</string>
+				<key>endCaptures</key>
+				<dict>
+					<key>1</key>
+					<dict>
+						<key>name</key>
+						<string>entity.name.function.systemverilog</string>
+					</dict>
+				</dict>
+				<key>patterns</key>
+				<array>
+					<dict>
+						<key>include</key>
+						<string>#port-dir</string>
+					</dict>
+					<dict>
+						<key>include</key>
+						<string>#all-types</string>
+					</dict>
+					<dict>
+						<key>include</key>
+						<string>#ifmodport</string>
+					</dict>
+					<dict>
+						<key>include</key>
+						<string>#comments</string>
+					</dict>
+					<dict>
+						<key>include</key>
+						<string>#operators</string>
+					</dict>
+					<dict>
+						<key>include</key>
+						<string>#constants</string>
+					</dict>
+					<dict>
+						<key>match</key>
+						<string>\s*(parameter)</string>
+						<key>name</key>
+						<string>keyword.other.systemverilog</string>
+					</dict>
+					<!-- Signals with user-defined type -->
+					<dict>
+						<key>match</key>
+						<string>^\s*([a-zA-Z_][a-zA-Z0-9_]*)\s+[a-zA-Z0-9_,\s]*+</string>
+						<key>captures</key>
+						<dict>
+							<key>1</key>
+							<dict>
+								<key>name</key>
+								<string>storage.type.interface.systemverilog</string>
+							</dict>
+						</dict>
+					</dict>
+				</array>
+				<key>name</key>
+				<string>meta.module.systemverilog</string>
 			</dict>
 			<!-- Sequence -->
 			<dict>
 				<key>match</key>
 				<string>\b(sequence)\s+([a-zA-Z_][a-zA-Z0-9_]*)</string>
 				<key>name</key>
-				<string>meta.function.systemverilog</string>
+				<string>meta.sequence.systemverilog</string>
 			</dict>
 			<dict>
 				<key>match</key>
 			</dict>
 			<dict>
 				<key>match</key>
-				<string>\b(automatic|cell|config|deassign|defparam|design|disable|edge|endconfig|endgenerate|endspecify|endtable|event|generate|genvar|ifnone|incdir|instance|liblist|library|localparam|parameter|macromodule|negedge|noshowcancelled|posedge|pulsestyle_onevent|pulsestyle_ondetect|scalared|showcancelled|specify|specparam|table|use|vectored)\b</string>
-				<key>name</key>
-				<string>keyword.other.systemverilog</string>
+				<string>\s*\b(automatic|cell|config|deassign|defparam|design|disable|edge|endconfig|endgenerate|endspecify|endtable|event|generate|genvar|ifnone|incdir|instance|liblist|library|localparam|parameter|macromodule|negedge|noshowcancelled|posedge|pulsestyle_onevent|pulsestyle_ondetect|scalared|showcancelled|specify|specparam|table|use|vectored)\b</string>
+				<key>captures</key>
+				<dict>
+					<key>1</key>
+					<dict>
+						<key>name</key>
+						<string>keyword.other.systemverilog</string>
+					</dict>
+				</dict>
 			</dict>
 			<dict>
 				<key>match</key>
 			</dict>
 			<dict>
 				<key>match</key>
-				<string>\b(initial|always|wait|force|release|assign|always_comb|always_ff|always_latch|forever|repeat|while|for|if|iff|else|case|casex|casez|default|endcase|return|break|continue|do|foreach|randomize|with|inside|dist|clocking|cover|coverpoint|property|bins|binsof|illegal_bins|ignore_bins|randcase|modport|matches|solve|static|assert|assume|before|expect|var|cross|ref|first_match|srandom|struct|packed|final|chandle|alias|tagged|extern|throughout|timeprecision|timeunit|priority|type|union|uwire|wait_order|triggered|randsequence|import|export|context|pure|intersect|wildcard|within|virtual|new|local|const|typedef|enum|protected|this|super|endtask|endmodule|endfunction|endprimitive|endclass|endpackage|endsequence|endprogram|endclocking|endproperty|endgroup|endinterface)\b</string>
-				<key>name</key>
-				<string>keyword.control.systemverilog</string>
+				<string>\s*\b(initial|always|wait|force|release|assign|always_comb|always_ff|always_latch|forever|repeat|while|for|if|iff|else|case|casex|casez|default|endcase|return|break|continue|do|foreach|randomize|with|inside|dist|clocking|cover|coverpoint|property|bins|binsof|illegal_bins|ignore_bins|randcase|modport|matches|solve|static|assert|assume|before|expect|var|cross|ref|first_match|srandom|struct|packed|final|chandle|alias|tagged|extern|throughout|timeprecision|timeunit|priority|type|union|uwire|wait_order|triggered|randsequence|import|export|context|pure|intersect|wildcard|within|virtual|new|local|const|typedef|enum|protected|this|super|endtask|endmodule|endfunction|endprimitive|endclass|endpackage|endsequence|endprogram|endclocking|endproperty|endgroup|endinterface)\b</string>
+				<key>captures</key>
+				<dict>
+					<key>1</key>
+					<dict>
+						<key>name</key>
+						<string>keyword.control.systemverilog</string>
+					</dict>
+				</dict>
 			</dict>
 			<dict>
 				<key>match</key>
 				<key>match</key>
 				<string>\b(begin)\b</string>
 				<key>name</key>
-				<string>meta.definition.systemverilog</string>
+				<string>meta.definition.block.systemverilog</string>
 			</dict>
 			<dict>
 				<key>captures</key>
 					</dict>
 				</dict>
 				<key>match</key>
-				<string>^\s*(module|primitive|package|constraint|interface|covergroup|program)\s+\b([a-zA-Z_][a-zA-Z0-9_]*)\b</string>
+				<string>\s*(primitive|package|constraint|interface|covergroup|program)\s+\b([a-zA-Z_][a-zA-Z0-9_]*)\b</string>
 				<key>name</key>
 				<string>meta.definition.systemverilog</string>
 			</dict>
 				<key>match</key>
 				<string>\b(class)\s+\b([a-zA-Z_][a-zA-Z0-9_]*)\b</string>
 				<key>name</key>
-				<string>meta.definition.systemverilog</string>
+				<string>meta.definition.class.systemverilog</string>
 			</dict>
 			<dict>
 				<key>match</key>
 				<key>name</key>
 				<string>support.function.systemverilog</string>
 			</dict>
+			<!-- Signals with user-defined type -->
 			<dict>
 				<key>match</key>
-				<string>\b([a-zA-Z_][a-zA-Z0-9_]*)\.([a-zA-Z_][a-zA-Z0-9_]*)\s+([a-zA-Z_][a-zA-Z0-9_]*)\b</string>
+				<string>^\s*([a-zA-Z_][a-zA-Z0-9_]*)\s+[a-zA-Z0-9_,\s]*(;|,)</string>
 				<key>captures</key>
 				<dict>
 					<key>1</key>
 						<key>name</key>
 						<string>storage.type.interface.systemverilog</string>
 					</dict>
-					<key>2</key>
-					<dict>
-						<key>name</key>
-						<string>support.modport.systemverilog</string>
-					</dict>
 				</dict>
 			</dict>
+			<!-- Module instantiation with parameter -->
 			<dict>
 				<key>begin</key>
 				<string>^\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*(#)[^#]</string>
 					</dict>
 				</array>
 			</dict>
+			<!-- Module instantiation with no param -->
 			<dict>
 				<key>begin</key>
-				<string>([a-zA-Z_][a-zA-Z0-9_]*)\s+(?!intersect|and|or|throughout|within)([a-zA-Z_][a-zA-Z0-9_]*)\s*(\[(\d+)(\:(\d+))?\])?\s*(\(|$|,)</string>
+				<string>\b([a-zA-Z_][a-zA-Z0-9_]*)\s+(?!intersect|and|or|throughout|within)([a-zA-Z_][a-zA-Z0-9_]*)\s*(\[(\d+)(\:(\d+))?\])?\s*(\(|$)</string>
 				<key>beginCaptures</key>
 				<dict>
 					<key>1</key>
 					</dict>
 				</dict>
 				<key>end</key>
-				<string>;|=|,|$</string>
+				<string>;</string>
+				<!-- <string>;|=|,|$</string> -->
 				<key>patterns</key>
 				<array>
 					<dict>
 			<key>port-dir</key>
 			<dict>
 				<key>match</key>
-				<string>\b(output|input|inout|ref)\b</string>
+				<string>\s*\b(output|input|inout|ref)\b</string>
 				<key>name</key>
 				<string>support.type.systemverilog</string>
 			</dict>
+			<!-- Interface with modport declaration -->
+			<key>ifmodport</key>
+			<dict>
+				<key>match</key>
+				<string>\b([a-zA-Z_][a-zA-Z0-9_]*)\.([a-zA-Z_][a-zA-Z0-9_]*)\s+([a-zA-Z_][a-zA-Z0-9_]*)\b</string>
+				<key>captures</key>
+				<dict>
+					<key>1</key>
+					<dict>
+						<key>name</key>
+						<string>storage.type.interface.systemverilog</string>
+					</dict>
+					<key>2</key>
+					<dict>
+						<key>name</key>
+						<string>support.modport.systemverilog</string>
+					</dict>
+				</dict>
+			</dict>
 			<key>storage-type-systemverilog</key>
 			<dict>
 				<key>patterns</key>
 {
     "1.0.0": "messages/1.0.0.txt",
     "1.0.1": "messages/1.0.1.txt",
-    "1.0.2": "messages/1.0.2.txt"
+    "1.0.2": "messages/1.0.2.txt",
+    "1.1.0": "messages/1.1.0.txt"
 }

messages/1.1.0.txt

+SystemVerilog 1.1.0 Changelog:
+ - Add Module instantiation feature
+ - Fix a few highlight issue around typedef, userdefined type and interface
+ - Change module declaration highlight to start having context information (to be used by incoming feature)
 
 Features:
  - Show signal declaration in status bar
+ - Module instantiation
+  * Use palette command "Verilog Instantiate Module" or use keybing to function 'verilog_module_inst'
+  * This open the palette with all verilog file (*.v, *.sv): select one and the instantiation with empty connection will be created
  - hopefully more to come :P
 
 
+
 Keymapping example
 ------------------
 
 To map key to the different feature, simply add the following to your user .sublime-keymap file:
 
-    {
-        "keys": ["f10"], "command": "verilog_type",
-        "context":
+	{
+		"keys": ["f10"], "command": "verilog_type",
+		"context":
+		[
+			{ "key": "num_selections", "operator": "equal", "operand": 1 },
+			{ "key": "selector", "operator": "equal", "operand": "source.systemverilog"}
+		],
+		"keys": ["ctrl+f10"], "command": "verilog_module_inst",
+		"context":
 		[
 			{ "key": "num_selections", "operator": "equal", "operand": 1 },
 			{ "key": "selector", "operator": "equal", "operand": "source.systemverilog"}
 		]
-    }
+	}
 
+`define my_macro ;
+`my_macro
+
 interface my_interface1;
     logic   one;
     logic   two;
 
     modport sys (
-        output one,
+        input one,
         output two
     );
 
 endinterface
 
-interface my_interface2;
-    logic   one;
-    logic   two;
+    interface my_interface2;
+        logic   one;
+        logic   two;
 
-    modport sys (
-        output one,
-        output two
-    );
+        modport sys (
+            inout one,
+            output two
+        );
 
-endinterface
+    endinterface
 
 
 module my_module
-(
-    my_interface1                       if1,
-    my_interface2                       if2,
-    input   logic                       clk,
-    output  wire                        my_out
+  #(parameter int P1=0)
+  (
+    my_interface1.sys   if1,
+    my_interface2       if2,
+    input   logic       clk,
+    output  wire        my_out
+  );
 
-);
+    timeunit 1ns;
+timeprecision 1fs;
+
+    typedef my_module#(16)  t_my_module_16;
+    typedef logic[7:0]  t_byte;
+    t_byte  b0, // Comments
+            b1;
+
+logic [3:0]  sig_logic;
+
+my_interface1 if1();
+
+my_module i_my_module
+  (
+    .if1(if1),
+    .if2(if2),
+    .clk(clk),
+    .my_out(my_out),
+  );
 
 parameter
     my_module.test_param = 23;
 
+    typedef my_module#(16)  t_my_module_16;
 
+function void my_func(ref logic d, input int din, output dout);
 import sublime, sublime_plugin
-import re, string, os
+import re, string, os, sys
 
+sys.path.append(os.path.join(os.path.dirname(__file__), "verilogutil"))
+import verilogutil
 
+# Display type of the signal/variable under the cursor into the status bar
 class VerilogTypeCommand(sublime_plugin.TextCommand):
 
     def run(self,edit):
         if r==None : return;
         r = self.view.line(r)
         # Extract type
-        return self.view.substr(r)
+        return self.view.substr(r)
+
+# Create module instantiation skeleton
+class VerilogModuleInstCommand(sublime_plugin.TextCommand):
+
+    def run(self,edit):
+        window = sublime.active_window()
+        self.project_rtl = []
+        for folder in window.folders():
+            for root, dirs, files in os.walk(folder):
+                for fn in files:
+                    if os.path.splitext(fn)[1] in ['.v','.sv']:
+                        self.project_rtl.append(os.path.join(root,fn))
+                        # self.project_rtl.append([fn,os.path.join(root,fn)])
+        # print (window.project_data()['folders'][0]['path'])
+        window.show_quick_panel(self.project_rtl, self.on_done )
+        return
+
+    def on_done(self, index):
+        print (self.project_rtl[index])
+        self.view.run_command("verilog_do_module_inst", {"args":{'text':self.project_rtl[index]}})
+
+class VerilogDoModuleInstCommand(sublime_plugin.TextCommand):
+
+    def run(self, edit, args):
+        if len(self.view.sel())==0:
+            return
+        with open(args['text'], "r") as f:
+            flines = str(f.read())
+            #TODO: use a function verilogutil extracting properly module name, parameter, IO
+            m = re.search("module\s+(\w+)\s*(#\([^;]+\))?\s*\(([^;]+)\)\s*;", flines)
+            if m is not None:
+                # print("Found module ", m.groups()[0])
+                inst = m.groups()[0] + " "
+                if m.groups()[1] is not None:
+                    param_str = verilogutil.clean_comment(m.groups()[1])
+                    inst += "#(\n"
+                    # print("      param = ", param_str)
+                    params = re.findall(r"(\w+)\s*=",param_str)
+                    if params is not None:
+                        for i in range(len(params)):
+                            inst+= "\t." + params[i][0] + "()"
+                            if i<len(params)-1:
+                                inst+=","
+                            inst+="\n"
+                        inst += ") "
+                #TODO: add config for prefix/suffix
+                inst += "i_" + m.groups()[0] + " (\n"
+                if m.groups()[2] is not None:
+                    port_str = verilogutil.clean_comment(m.groups()[2])
+                    ports = re.findall(r"(\w+)\s*(,|$)",port_str)
+                    if ports is not None:
+                        for i in range(len(ports)):
+                            inst+= "\t." + ports[i][0] + "()"
+                            if i<len(ports)-1:
+                                inst+=","
+                            inst+="\n"
+                inst += ");\n"
+                self.view.insert(edit, self.view.sel()[0].begin(), inst)

verilogutil/verilogutil.py

+# Class/function to process verilog file
+import re, string, os
+
+def clean_comment(txt):
+	#remove singleline comment
+	txt_nc = re.sub(r"//.*?$","",txt, flags=re.MULTILINE)
+	#remove multiline comment
+	# txt_nc = re.sub(r"/\*.*\*/","",txt_nc, flags=re.MULTILINE)
+	return txt_nc
+