Working with VHDL in Sublime Text 3
Sublime Text Editor significantly saves time when working with vhdl and verilog files. For those who have not worked with editors such as Sublime Text, Notepad ++, etc. I will describe the main useful functions of these editors:
- multiple selection / editing of lines of code (pressing the middle mouse button or while holding down the Ctrl key)
- setting tags (bookmarks) in the code helps to navigate large files. (Ctrl + F2 or via Goto → Bookmarks menu item)
- the ability to divide the workspace into multiple windows (Alt + Shift + 2 or from the menu View → Layout)
- opening one file several times (File → New View into File)
- Commenting on highlighted lines of code (Ctrl + /)
- search and replace (Ctrl + h)
- search all open files (Ctrl + Shift + f)
- inserting snippets (code templates) (write keyword + Tab key)
- writing and using functions in python
- ability to install various add-ons
- flexible setting
Sublime Text Integration
To begin, let's dock CAD for work with FPGA and Sublime editor.
- Sublime Text integration with Xilinx ISE:
in ISE, go to the menu Edit → Preferences → Editors: Text Editor → Editor = Custom
Paste the line into the “Command line syntax” window:
')
{C:\Program Files\Sublime Text 3\sublime_text.exe} $1
- Sublime Text integration with Xilinx Vivado:
Tools → Options → Text Editor → Current Editor: Sublime
or
Tools → Options → Text Editor → Current Editor: Custom Editor
Specify the path to the editor, for example:
C:\Program Files\Sublime Text 3\sublime_text.exe [file name]
Plugins
Various plugins (packages) extend the functionality of the editor. Packages can
install both online and offline mode.
To install plug-ins in offline mode, you need to do some simple manipulations:
- We download the necessary plug-in from GitHub
- Extract from archive
- Rename the folder, for example, “Sublime-HDL-master” to “Sublime HDL”
- Copy the resulting folders into the Packages folder (the location of this folder is easy to find by selecting Preferences → Browse Packages in the Sublime Text menu)
SyncViewScroll - plugin for synchronizing vertical and horizontal scrolling when working in multiple windows. For the plug-in to work it is necessary to select for each window in the menu View → Sync Scroll.
Text Pastry - plugin for automatic multiple numbering. It helps a lot when working with a large number of numbered signals / ports.
How to work with Text Pastry- Select the desired parts of the lines
- Call the menu Ctrl + Shift + P
- We are looking for the item “Text Pasty Command Line”
- In the window that appears, located at the bottom of the screen, enter:
- 0 - numbering from 0
- \ i (1,10) - numbering from 1 with increment 10
- 1 end = 4 - numbering 1, 2, 3, 4, 1, 2, 3, 4, etc.
- letters ac upper - A, B, C, A, B, C, etc.
- letters ac upper x3 - A, A, A, B, B, B, C, C, C, etc.
- 1 x3 - 1, 1, 1, 2, 2, 2, 3, 3, 3, etc.
- xyz - x, y, z, x, y, z, x, y, z, etc.
Sublime Verilog - Verilog language syntax support
Verilog Gadget - a set of functions and snippets for working with Verilog files.
SmartVHDL - support for VHDL syntax. Also, when you hover on a signal or port in the code, a window will appear with a hint about the type (number of bits) of this signal / port. When you hover on a signal in the context menu, the item “Goto Definishion” will appear - go to the place where the signal was announced.
VHDL Mode - a set of functions and snippets for working with VHDL files. The main part of the functions is triggered, for example, by the key combination Atl + K, C, P, where C and P are pressed alternately. Main functions:
- Copying port data (port names, data types)
- Insert port data as a signal declaration
- Insert port data as component declaration
- Testbench generation from copied port data
- Auto-formatting code (tab alignment, etc.)
Ucf file support
By default, the Sublime editor does not have to work with ucf-files. The ucf markup is equivalent to the tcl language markup. It remains only to explain this to the editor:
- Create a new Tcl.sublime-settings file in the Packages folder.
- Fill the file with the string
{"extensions" : ["ucf"]}
- Save the file
Creating code templates (snippets)
Suppose we need to insert a code template:
My_proc : Process(clk, rst, data_in) begin if(clk'event and clk = '1') then if(rst = '1') then else then
Moreover, we would like that after inserting the text by pressing Tab, the cursor is positioned at the position My_proc, clk, rst, data_in, to quickly change the values ​​of this data. To do this, create a new snippet: Tools → Developer → New Snippet. Editing data:
<snippet> <description>process rst</description> <content><![CDATA[ ${1:<PROCESS_NAME>} : Process(${2:clk}, ${3:rst}, ${4:data_in}) begin if($2'event and $2 = '1') then if($3 = '1') then ${5} else then -- $3 = 0 $0 end if; -- $4 end if;--$2 end process $1; ]]></content> <tabTrigger>procrst</tabTrigger> <scope>source.vhdl</scope> </snippet>
Save this snippet. Now when writing the procrst keyword, our template will be inserted at the current cursor position.
Read more about creating templates in the article
“How to create a snippet?” .
Writing your own functions in python
Details on creating functions (plug-ins) were described in the articles
“How to write a simple plugin” ,
“How to write a complex plugin” .
Inserting snippets is, of course, good, but I would like, for example, that the same process creation template be automatically filled in depending on the input signals, and that the process be modified in the presence of signals such as rst and ce. Usually, after the process, the external ports of the module are assigned values ​​of internal signals, even if it is done automatically.
To parse the VHDL file data, we use the functions of the Vhdl mode plugin.
Approximate algorithm of our actions:
- Get data on all ports of the module
- All ports of type "in" include in the process header
- If there are ports called ce and / or rst, then add the appropriate if else conditions to the process
- After the process, insert the lines for assigning the values ​​of the internal signals to the output ports (usually, these signals are also called as the port, adding the prefix "s_" or "_net")
First, create a new snippet:
<snippet> <tabTrigger>procclk</tabTrigger> <scope>source.vhdl</scope> <content><![CDATA[ ${DATAINPORTS} ${OUTPORTS} ]]></content> <description>process clk</description> </snippet>
Here $ {DATAINPORTS} is the label where the description of the process will be inserted,
$ {OUTPORTS} - label, where the external output ports will be assigned the values ​​of internal signals.
Save it under the name, for example, test.sublime-snippet in the VHDL Mode / Snippets folder.
We use the written functions in the folder VHDL Mode. Since my knowledge of python is basic, we will modify the functions of the plugin, by analogy with those already described in it.
Let's create new functions in the Interface () class in the vhdl_lang.py file, let's call them in_port and out_port:
Functions def in_port(self): """ Generate Process depending on the input ports """ lines = [] bus_index = "" max_data = "" my_ports = "" is_clk = False is_ce = False is_rst = False if self.if_ports: for port in self.if_ports: if port.mode.lower() == 'in': if port.name.lower() == ('clk'): is_clk = True my_ports = port.name else: if port.name.lower() == ('ce'): is_ce = True elif port.name.lower() == ('rst'): is_rst = True my_ports = my_ports + ", " + port.name lines.append("Process("+ my_ports +')' ) lines.append("begin") if is_clk: lines.append(" if(clk'event and clk = '1') then") lines.append("") if is_rst and is_ce: lines.append("if(rst = '1') then") lines.append("") lines.append("elsif (ce = '1') then") lines.append("") lines.append("end if; -- rst") elif is_rst: lines.append("if(rst = '1') then") lines.append("") lines.append("else -- working body ") lines.append("") lines.append("end if; -- rst") elif is_ce: lines.append("if (ce = '1') then") lines.append("") lines.append("end if; -- lines.append(" end if;--clk") lines.append("end process;") # lines.append(str(testind indent_vhdl(lines, 1) return '\n'.join(lines) else: return None def out_port(self): """ Generate data after Process """ lines = [] if self.if_ports: for port in self.if_ports: if port.mode.lower() == 'out': lines.append("{} <= {}_net;".format(port.name, port.name)) indent_vhdl(lines, 1) return '\n'.join(lines) else: return None
The out_port function inserts rows by process, for example:
data_out1 <= data_out1_net;
data_out2 <= data_out2_net;
Create a new file in the VHDL Mode folder, name it my_func.py, insert the text:
import sublime import sublime_plugin from.import vhdl_interface as face class PasteAsProcess(sublime_plugin.TextCommand): def run(self, edit): snippet_clk = "Packages/VHDL Mode/Snippets/test.sublime-snippet" in_port_str = face._interface.in_port() out_port_str = face._interface.out_port() self.view.run_command("insert_snippet", { "name" : snippet_clk, "DATAINPORTS" : in_port_str, "OUTPORTS" : out_port_str }) print('paste_as_process')
It remains to assign hotkeys. Since our class is called PasteAsProcess, the command should be called paste_as_process (before the symbols, except the first, written in upper case, you need to put an underscore).
Go Preferences → Key Bildings. Insert the line:
{"keys": ["alt+k", "p", "z"], "command": "paste_as_process", "context": [{"key": "selector", "operand": "source.vhdl"}] },
Now, to work, we first need to copy the values ​​of the vhdl ports of the file with the key combination "alt + k", "p", "w" (by default). Then call our function with the keys “alt + k”, “p”, “z”.
Conclusion
Snippets and functions greatly simplify working with vhdl files.
Even basic knowledge of the python language is sufficient for writing simple but working functions.
PS: Leave a
link to the folder with my settings. To work, you need to replace the Sublime Text 3 folder at: C: \ Users \ User \ AppData \ Roaming \
My snippets:
- sint (Signal integer), sstd, svector - templates for describing signals of the corresponding type
- ibuf, ibufds, etc. - description of buffers
- generichelp - hint example how to properly apply generic
- teststd, testvector, etc. - processes for testbench with the appropriate data types
- procclk, procce, procrst - processes with clk, ce, rst signals
- clk, net, inst - templates for ucf files
My functions:
- Link Alt + K, C, P (Copy Ports), Alt + K, P, Z - paste the process described with this article
- Linking Alt + K, C, P (Copy Ports), Alt + K, P, T (Paste Testbench) - remade the function of the VHDL MODE plugin, now test processes are generated for all input signals