A language server for systemverilog that has been tested to work with coc.nvim, VSCode, Sublime Text 4, emacs, and Neovim
The code has been tested to work with below tool versions
npm install -g @imc-trading/svlangserver
npm install -g @imc-trading/svlangserver
Preferences -> Package Settings -> LSP -> settings
) and the sublime-project filesnpm install -g @imc-trading/svlangserver
eglot
/lsp
npm install -g @imc-trading/svlangserver
To get the snippets, git clone this repo and copy the snippets directory wherever applicable
For installing from source (not applicable for VSCode)
git clone https://github.com/imc-trading/svlangserver.git
cd svlangserver && npm install
/git/repo/path/svlangserver/bin/main.js
)NOTE: This has been tested with npm version 6.14.13 and node version 14.17.1
systemverilog.includeIndexing
: Array, Globs defining files to be indexedsystemverilog.libraryIndexing
: Array, Globs defining library files to be added to linting. It's useful when module name is not equal to filename.systemverilog.excludeIndexing
: Array, Exclude files from indexing based on globsystemverilog.linter
: String, Select linter
systemverilog.launchConfiguration
: String, Command to run for launching linting
systemverilog.lintOnUnsaved
: Boolean, Lint even unsaved files
systemverilog.defines
: Array, Defines for the project. Used by the language server as well as linting
systemverilog.formatCommand
: String, verible-verilog-format command for code formatting
systemverilog.disableCompletionProvider
: Boolean, Disable auto completion provided by the language server
systemverilog.disableHoverProvider
: Boolean, Disable hover over help provided by the language server
systemverilog.disableSignatureHelpProvider
: Boolean, Disable signature help provided by the language server
systemverilog.disableLinting
: Boolean, Disable linting
{
"languageserver": {
"svlangserver": {
"command": "svlangserver",
"filetypes": ["systemverilog"],
"settings": {
"systemverilog.includeIndexing": ["**/*.{sv,svh}"],
"systemverilog.excludeIndexing": ["test/**/*.sv*"],
"systemverilog.defines" : [],
"systemverilog.launchConfiguration": "/tools/verilator -sv -Wall --lint-only",
"systemverilog.formatCommand": "/tools/verible-verilog-format"
}
}
}
}
For project specific settings this file should be at <WORKSPACE PATH>/.vim/coc-settings.json
{
"languageserver": {
"svlangserver": {
"module": "/usr/lib/node_modules/@imc-trading/svlangserver/bin/main.js",
"args": ["--node-ipc"],
"filetypes": ["systemverilog"],
"settings": {
"systemverilog.includeIndexing": ["**/*.{sv,svh}"],
"systemverilog.excludeIndexing": ["test/**/*.sv*"],
"systemverilog.defines" : [],
"systemverilog.launchConfiguration": "/tools/verilator -sv -Wall --lint-only",
"systemverilog.formatCommand": "/tools/verible-verilog-format"
}
}
}
}
For project specific settings this file should be at <WORKSPACE PATH>\.vim\coc-settings.json
{
"systemverilog.includeIndexing": ["**/*.{sv,svh}"],
"systemverilog.excludeIndexing": ["test/**/*.sv*"],
"systemverilog.defines" : [],
"systemverilog.launchConfiguration": "/tools/verilator -sv -Wall --lint-only",
"systemverilog.formatCommand": "/tools/verible-verilog-format"
}
For project specific settings this file should be at <WORKSPACE PATH>/.vscode/settings.json
{
"clients": {
"svlangserver": {
"enabled": true,
"command": ["svlangserver"],
"languageId": "systemverilog",
"scopes": ["source.systemverilog"],
"syntaxes": ["Packages/SystemVerilog/SystemVerilog.sublime-syntax"],
"settings": {
"systemverilog.disableHoverProvider": true,
"systemverilog.launchConfiguration": "/tools/verilator -sv --lint-only -Wall",
"systemverilog.formatCommand" : "/tools/verible-verilog-format"
}
}
}
}
<PROJECT>.sublime-project
{
"folders":
[
{
"path": "."
}
],
"settings": {
"LSP": {
"svlangserver": {
"settings": {
"systemverilog.includeIndexing": [ "**/*.{sv,svh}", ],
"systemverilog.excludeIndexing": ["test/**/*.sv*"],
"systemverilog.defines": [],
}
}
}
}
}
Example settings for emacs
(require 'lsp-verilog)
(custom-set-variables '(lsp-clients-svlangserver-launchConfiguration "/tools/verilator -sv --lint-only -Wall") '(lsp-clients-svlangserver-formatCommand "/tools/verible-verilog-format"))
(add-hook 'verilog-mode-hook #'lsp-deferred)
* The project specific settings go in .dir-locals.el
```elisp
((verilog-mode (lsp-clients-svlangserver-workspace-additional-dirs . ("/some/lib/path"))
(lsp-clients-svlangserver-includeIndexing . ("src/**/*.{sv,svh}"))
(lsp-clients-svlangserver-excludeIndexing . ("src/test/**/*.{sv,svh}"))))
(require 'verilog-ext)
(verilog-ext-mode-setup)
(verilog-ext-eglot-set-server 've-svlangserver) ;`eglot' config
(verilog-ext-lsp-set-server 've-svlangserver) ; `lsp' config
Example settings for neovim
Update your init.lua
local nvim_lsp = require('lspconfig')
nvim_lsp.svlangserver.setup {
on_init = function(client)
local path = client.workspace_folders[1].name
if path == '/path/to/project1' then
client.config.settings.systemverilog = {
includeIndexing = {"**/*.{sv,svh}"},
excludeIndexing = {"test/**/*.sv*"},
defines = {},
launchConfiguration = "/tools/verilator -sv -Wall --lint-only",
formatCommand = "/tools/verible-verilog-format"
}
elseif path == '/path/to/project2' then
client.config.settings.systemverilog = {
includeIndexing = {"**/*.{sv,svh}"},
excludeIndexing = {"sim/**/*.sv*"},
defines = {},
launchConfiguration = "/tools/verilator -sv -Wall --lint-only",
formatCommand = "/tools/verible-verilog-format"
}
end
client.notify("workspace/didChangeConfiguration")
return true
end
}
Update your init.lua
local on_attach = function(client, bufnr)
-- Other settings when LSPs are attached
-- ...
-- Update nlsp-settings when LSPs are attached
require('nlspsettings').update_settings(client.name)
end
local nvim_lsp = require('lspconfig')
local nlspsettings = require('nlspsettings')
nvim_lsp.svlangserver.setup {
on_attach = on_attach,
}
nlspsettings.setup {}
{
"systemverilog.includeIndexing": ["**/*.{sv,svh}"],
"systemverilog.excludeIndexing": ["test/**/*.sv*"],
"systemverilog.defines" : [],
"systemverilog.launchConfiguration": "/tools/verilator -sv -Wall --lint-only",
"systemverilog.formatCommand": "/tools/verible-verilog-format"
}
For project specific settings this file should be at <WORKSPACE PATH>/.nlsp-settings/svlangserver.json
systemverilog.build_index
: Instructs language server to rerun indexingsystemverilog.report_hierarchy
: Generates hierarchy for the given modulecommand! SvBuildIndex call CocRequest("svlangserver", 'workspace/executeCommand', {'command': 'systemverilog.build_index'})
command! -range SvReportHierarchy call CocRequest("svlangserver", 'workspace/executeCommand', {'command': 'systemverilog.report_hierarchy', 'arguments': [input('Module/interface: ', <range> == 0 ? "" : expand("<cword>"))]})
If the above SvReportHierarchy command is called with visual selection, then the module name is pre-filled with the selection. Also depending on the coc.nvim version, the generated rpt.json file might not have the focus and user will have to switch buffer manually.
build index
in the command palette should invoke the build index command.get hierarchy
in the command palette should invoke the report hierarchy command. If invoked with an active slection, the module name is pre-filled with the selection.[
{
"caption": "SvLangserver Build Index",
"command": "lsp_execute",
"args": {
"session_name": "svlangserver",
"command_name": "systemverilog.build_index",
"command_args": []
}
},
{
"caption": "Svlangserver Report Hierarchy",
"command": "lsp_execute",
"args": {
"session_name": "svlangserver",
"command_name": "systemverilog.report_hierarchy",
"command_args": ["${selection}"]
}
}
]
This should make the commands available in the command palette. For the report hierarchy command, the module name should be selected before invoking the command.
lsp-clients-svlangserver-build-index
command should rerun the indexing.lsp-clients-svlangserver-report-hierarchy
command should do the job. If invoked with an active slection, the module name is pre-filled with the selection.
Previous commands can be run with eglot
and verilog-ext
:
verilog-ext-eglot-svlangserver-build-index
verilog-ext-eglot-svlangserver-report-hierarchy
:SvlangserverBuildIndex
command should rerun the indexing.:SvlangserverReportHierarchy
command will generate hierarchy file of the word under the cursor in normal mode.:CocCommand workspace.showOutput
and then select svlangserverLSP: Toggle Log Panel
*lsp-log*
buffervim.lsp.set_log_level("info")
in your init.lua then use the command :LspLog
Rewrite parser to make it much more robust
Although most of the code is written from scratch, this VSCode-SystemVerilog extension was what I started with and developed on.
See the changelog for more details