Pulverize — Verilog/SystemVerilog/VHDL Language Support for VSCode
中文文档
Pulverize is a VSCode extension for FPGA, ASIC, and IC front-end development, providing language support for Verilog / SystemVerilog / VHDL, including syntax highlighting, code completion, go-to-definition, hover hints, reference search, semantic coloring, code snippets, lint checks, and other full IDE features.
Quick Start
Install: Search for "Pulverize Verilog Support" in the VSCode Extensions panel (Ctrl+Shift+X)
Switch Theme: Ctrl+Shift+P → Preferences: Color Theme → Select "Pulverize Dark Modern" (dark theme with Verilog/VHDL semantic coloring)
Configuration (optional): Create .vscode/pulverize.json in the workspace root with a minimal config:
{ "source": ["**/*.v", "**/*.sv"], "vhdl_source": ["**/*.vhd", "**/*.vhdl"] }
Parse Project: Ctrl+Shift+P → Search for Pulverize: Parse all files and rebuild index to run a full parse
After that, saving any file triggers an incremental parse, with lint diagnostics updating in real time.
See Configuration for all config options, and Commands for available commands.
Features
Language Support
| Language |
Syntax Highlighting |
Code Completion |
Go to Definition |
Lint |
Semantic Coloring |
| Verilog (IEEE 1364-2005) |
✅ |
✅ |
✅ |
✅ |
✅ |
| SystemVerilog |
✅ |
✅ |
✅ |
✅ |
✅ |
| VHDL (IEEE 1076-2008) |
✅ |
✅ |
✅ |
✅ |
✅ |
Syntax Highlighting
- Full Verilog-2005 keyword highlighting, compatible with some SystemVerilog extensions (
always_comb, always_ff, logic, bit, etc.)
- Structured highlighting for module declarations, instantiations, parameters, functions, tasks, and preprocessor directives
- Full VHDL syntax highlighting (entity, architecture, package, process, component, generate, etc.)
- Includes the "Pulverize Dark Modern" dark theme
Semantic Coloring (Semantic Tokens)
Analyzes code semantics via the built-in parser to provide differentiated coloring for different variable types:
| Semantic Type |
Description |
wire |
Wire (net) declaration |
reg |
Register declaration |
logic |
Logic type declaration |
param |
Parameter / localparam |
sim |
Simulation variable (integer, real, string, etc.) |
inst |
Module instance |
macro |
Macro definition (code blocks hidden by `ifdef are shown in gray) |
Code Completion
- Trigger characters:
. and `
- Variable Completion: Symbols in the current scope (wire, reg, logic, etc.)
- Module Name Completion: All module names in the project
- Port Connection Completion: Press
. during instantiation to auto-list module ports, sorted by connection status (unconnected ports first)
- "Connect all missing ports": One-click complete all unconnected ports in an instantiation
- "Hang all missing ports": One-click hang all unconnected ports
- Macro Completion: Triggered by
`, lists defined macros
Go to Definition
- Variable declaration jump
- Macro `define definition jump
- `include file jump
- Module name jump to corresponding module declaration
- Instance port connection jump to the port declaration in the module definition
Hover
- Mouse hover shows context information such as symbol type, declaration location, and module name
Find References
- Find all references to modules and symbols
Document Symbols
- Structured outline for modules, functions, tasks, generate blocks, etc. (Outline view and breadcrumbs)
Lint Checks
Each rule can be individually enabled/disabled in .vscode/pulverize.json:
| Lint Rule | Description |
|-----------|-------------|
| module-not-found | Instantiation references a non-existent module |
| illegal-port | Named port connection targets a port that does not exist in the module |
| width-mismatch | Connected signal width is smaller than the module port width |
| missing-port | Module port is not connected |
| reference-not-found | Identifier reference has no matching declaration |
| reference-ahead-declaration | Reference appears before its declaration |
| variable-redefine | Duplicate variable declaration in the same scope |
| nonblock-conflict | Same variable uses both blocking (=) and non-blocking (<=) assignment |
| include-not-found | include file does not exist | | macro-not-found| Macro usage has no matchingdefine |
VHDL Rules:
| Lint Rule |
Description |
entity-not-found |
Instantiation references a non-existent entity/component |
illegal-port |
Port map references a port that does not exist in the entity |
illegal-generic |
Generic map references a generic that does not exist in the entity |
width-mismatch |
Signal width mismatch |
missing-port |
Entity port is not connected in the port map |
reference-not-found |
Identifier reference has no matching declaration |
reference-ahead-declaration |
Usage appears before its declaration |
variable-redefine |
Duplicate variable declaration in the same scope |
multiple-drivers |
Same signal is driven in multiple processes |
unused-signal |
Signal is declared but never used |
Code Actions
- Quick fix for
reference-not-found warnings: "Add wire" to automatically add a wire declaration (Verilog) / "Add signal" to automatically add a signal declaration (VHDL)
- Quick fix for
missing-port warnings: "Add missing port mapping" to automatically complete port connections
Snippets
Built-in practical code snippets:
| Prefix |
Expansion |
module |
Module template (with clock and reset ports) |
always |
always @(*) combinational logic block |
alwaysclk |
Sequential logic block with asynchronous reset |
initial |
initial begin...end block |
case |
case statement template |
ifbeg |
if begin...end block |
elifbeg |
else if begin...end block |
elsebeg |
else begin...end block |
for |
for loop template |
while |
while loop template |
forever |
forever loop template |
generate |
generate block |
function |
Function template |
task |
Task template |
input / output / inout |
Port declaration |
wire / reg / logic |
Signal declaration |
assign |
Continuous assignment |
localparam |
Local parameter |
posedge / negedge |
Edge trigger |
VHDL Snippets
| Prefix |
Expansion |
entity |
entity + architecture skeleton template |
arch |
Architecture body skeleton |
proc |
Process template (with clk + reset) |
sig |
signal declaration |
var |
variable declaration |
comp |
component declaration |
inst |
component instantiation |
pkg |
package declaration |
if |
if...then...end if statement |
case |
case...when...end case statement |
for |
for...loop...end loop statement |
Installation
From VSCode Marketplace
Search for "Pulverize Verilog Support" in the VSCode Extensions panel.
From VSIX
npm run package # Generates pulverize-0.4.0.vsix
code --install-extension pulverize-0.4.0.vsix
Configuration
Create a .vscode/pulverize.json configuration file in the workspace root:
{
"define": ["__SIM__"],
"source": ["**/*.v", "**/*.sv"],
"vhdl_source": ["**/*.vhd", "**/*.vhdl"],
"exclude": [],
"vhdl_standard": "2008",
"vhdl_libraries": {
"work": "."
},
"lint": {
"module-not-found": true,
"illegal-port": true,
"width-mismatch": true,
"missing-port": true,
"reference-not-found": true,
"reference-ahead-declaration": true,
"variable-redefine": true,
"nonblock-conflict": true,
"include-not-found": true,
"macro-not-found": true
},
"vhdl_lint": {
"entity-not-found": true,
"illegal-port": true,
"illegal-generic": true,
"width-mismatch": true,
"missing-port": true,
"reference-not-found": true,
"reference-ahead-declaration": true,
"variable-redefine": true,
"multiple-drivers": true,
"unused-signal": true
},
"lint_exclude": []
}
| Field |
Description |
define |
Global macro definitions, equivalent to +define+ compile option. Default ["__SIM__"] |
source |
Verilog source file glob patterns, used by full parse parse_all and include search scope |
vhdl_source |
VHDL source file glob patterns, default ["**/*.vhd", "**/*.vhdl"] |
exclude |
File glob patterns to exclude |
vhdl_standard |
VHDL standard version, default "2008" |
vhdl_libraries |
VHDL library name to directory mapping, default {"work": "."} |
lint |
Per-rule enable/disable for Verilog lint rules |
vhdl_lint |
Per-rule enable/disable for VHDL lint rules |
lint_exclude |
Files matching these patterns will not be linted |
Commands
| Command |
Description |
pulverize.parse |
Parse current file and rebuild index |
pulverize.parse_all |
Parse all source files and rebuild index, update diagnostics |
Access via Ctrl+Shift+P and search for "Pulverize".
Architecture
Overview
Pulverize does not use the Language Server Protocol (LSP). Instead, it integrates ANTLR4 parsers directly into the VSCode extension host process. This design simplifies the architecture and avoids LSP communication overhead.
Parsing Pipeline
Verilog Parsing Pipeline
Source Files (.v/.sv/.vh)
│
▼
┌─────────────────────────┐
│ Preprocessing │ ← Processes `include, macro expansion, conditional compilation
│ (PulVPreParser) │
│ - File include inlining│
│ - `define / `undef │
│ - `ifdef / `ifndef/... │
└───────────┬─────────────┘
│ Token Stream
▼
┌─────────────────────────┐
│ Parsing (VParser) │ ← ANTLR4-generated TypeScript parser
│ - IEEE 1364-2005 │
│ - Error capture │
│ (PulErrorListener) │
└───────────┬─────────────┘
│ Parse Tree
▼
┌─────────────────────────┐
│ Semantic Analysis │ ← Walks the AST to build the symbol database
│ (PulVListener) │
│ - Symbol collection │
│ (Module/Port/Wire/ │
│ Reg/Param/...) │
│ - Reference recording │
│ (Id) │
│ - Scope management │
│ (Context) │
└───────────┬─────────────┘
│ Symbol Database
▼
┌─────────────────────────┐
│ Semantic Coloring │ ← Tags wire/reg/logic/param with semantic tokens
│ (SemaTokens) │
│ Reference Resolution │
│ (semantic) │
│ Lint Checks │
│ (PulLinter) │
│ Width Calculation │
│ (calc) │
└─────────────────────────┘
VHDL Parsing Pipeline
Source Files (.vhd/.vhdl)
│
▼
┌─────────────────────────┐
│ Case Normalization │ ← VhdlCaseInsensitiveStream
│ - VHDL is │ (No preprocessor, no `include)
│ case-insensitive │
└───────────┬─────────────┘
│ Token Stream
▼
┌─────────────────────────┐
│ Parsing (VHDLParser) │ ← ANTLR4-generated TypeScript parser
│ - IEEE 1076-2008 │
│ - Error capture │
│ (PulErrorListener) │
└───────────┬─────────────┘
│ Parse Tree
▼
┌─────────────────────────┐
│ Semantic Analysis │ ← Walks the AST to build the symbol database
│ (PulVHListener) │
│ - entity/architecture/ │
│ package/process/... │
│ - Reference recording │
│ (Id) │
│ - Scope management │
│ (Context) │
│ - library/use clause │
│ handling │
└───────────┬─────────────┘
│ Symbol Database
▼
┌─────────────────────────┐
│ Semantic Coloring │ ← Tags signal/variable/constant/type with semantic tokens
│ (SemaTokens) │
│ Reference Resolution │
│ (semantic) │
│ Lint Checks │
│ (PulLinter) │
│ Width Calculation │
│ (calc) │
└─────────────────────────┘
Core Modules
Symbol System
Entity (base: name, kind, ranges, scope)
├── Context (child contexts, symbol table, reference list)
│ ├── Root (modules{}, instances{})
│ ├── Module (extends Procedure)
│ │ ├── Port (input/output/inout)
│ │ ├── Logic (wire/reg/logic)
│ │ ├── Variable (integer/real/...)
│ │ ├── Parameter
│ │ ├── Instance (instantiation)
│ │ ├── Func / Task
│ │ └── Block (generate / begin-end)
│ ├── InstanceGroup / Instance
│ └── Block
│ ├── VhdlEntity (entity declaration)
│ │ ├── Parameter[] (generic)
│ │ └── Port[] (in/out/inout/buffer/linkage)
│ ├── VhdlArchitecture (architecture, of entity)
│ │ ├── Logic[] (signal)
│ │ ├── VhdlProcess
│ │ │ └── Variable[]
│ │ ├── InstanceGroup / Instance
│ │ └── Block (generate)
│ ├── VhdlPackage / VhdlPackageBody
│ │ ├── VhdlComponent
│ │ └── VhdlType
│ └── VhdlConfiguration
├── Symbol (with width/value)
│ ├── Port (direction)
│ ├── Logic
│ ├── Variable
│ └── Parameter
└── Id (hierarchical identifier reference)
Development
Requirements
- Node.js ≥ 16
- TypeScript 4.8+
- VSCode ≥ 1.79.0
- ANTLR 4.13.0 (only needed when modifying grammars)
Build
# Install dependencies
npm install
# Compile TypeScript
npm run compile
# Watch mode (auto-compile)
npm run watch
# Lint
npm run lint
# Package VSIX
npm run package
Debugging
Press F5 in VSCode to launch the Extension Development Host. .vscode/launch.json is pre-configured.
Updating Grammars
After modifying .g4 files under antlr/verilog/ or antlr/vhdl/, run antlr.sh to regenerate parsers:
bash antlr.sh
This script uses ANTLR 4.13.0 to convert .g4 grammars into TypeScript code, with Verilog output to src/v/ and VHDL output to src/vhdl/.
Project Structure
pulverize/
├── antlr/ # ANTLR4 grammar definitions
│ ├── verilog/ # Verilog IEEE 1364-2005
│ │ ├── VLexer.g4 # Lexer rules (282 rules)
│ │ └── VParser.g4 # Parser rules (~1624 lines)
│ ├── systemverilog/ # SystemVerilog (partially implemented)
│ └── vhdl/ # VHDL IEEE 1076-2008
│ ├── VHDLLexer.g4 # Lexer rules
│ └── VHDLParser.g4 # Parser rules
├── config/ # Language configurations (bracket matching, comments, auto-closing)
│ ├── v.configuration.json
│ └── vhdl.configuration.json
├── snippets/ # Code snippets
│ ├── v.snippets.json # Verilog
│ └── vhdl.snippets.json # VHDL
├── syntaxes/ # TextMate grammar highlighting
│ ├── v.tmLanguage.json # Verilog
│ └── vhdl.tmLanguage.json # VHDL
├── themes/ # Color themes
│ └── pulverize-color-theme.json
├── src/ # Source code
│ ├── extension.ts # Extension entry point
│ ├── util.ts # Utility functions
│ ├── antlr4/ # ANTLR4 runtime (built-in)
│ ├── v/ # Generated Verilog parser
│ ├── sv/ # Generated SystemVerilog parser
│ ├── vhdl/ # Generated VHDL parser
│ ├── stream/ # Custom Token stream
│ ├── parser/ # Parser backend
│ │ ├── entity/ # Symbol entity system
│ │ ├── PulParser.ts # Parse scheduler
│ │ ├── PulVPreParser.ts # Preprocessor
│ │ ├── PulVListener.ts # Verilog AST listener
│ │ ├── PulVHListener.ts # VHDL AST listener
│ │ ├── PulLinter.ts # Lint checks
│ │ ├── PulConfig.ts # Configuration management
│ │ └── calc.ts # Width calculation
│ └── provide/ # Language feature Providers
│ ├── SemanticTokensProvider.ts
│ ├── CompletionItemProvider.ts
│ ├── DefinitionProvider.ts
│ ├── HoverProvider.ts
│ ├── DocumentProvider.ts
│ ├── ReferenceProvider.ts
│ └── CodeActionProvider.ts
├── out/ # Compiled output
├── package.json
├── tsconfig.json
└── antlr.sh # ANTLR generation script
Version History
See CHANGELOG.md for details.
| Version |
Highlights |
| 0.4.0 |
Full VHDL language support (parser, semantic coloring, completion, go-to-definition, lint, etc.) |
| 0.3.1 |
nonblock-conflict rule ignores registers in subscript expressions |
| 0.3.0 |
Added nonblock-conflict lint rule |
| 0.2.2 |
VHDL syntax highlighting support |
| 0.2.1 |
Fixed document symbol jump; module name completion |
| 0.2.0 |
Hierarchical identifier semantic coloring and completion |
| 0.1.10 |
"Connect/Hang all missing ports" completion; variable-redefine lint |
| 0.1.9 |
Variable completion; Verilog snippets |
| 0.1.8 |
Module reference search |
| 0.1.7 |
Hierarchical identifier hover and click-to-jump |
| 0.1.6 |
Multiple lint rules (module/port/width/reference/include/macro) |
| 0.1.5 |
Symbol reference search; auto re-parse on file dirty change |
| 0.1.4 |
Semantic coloring (differentiated colors for wire/reg/logic/param, etc.) |
| 0.1.3–0.1.0 |
Initial releases |
License
MIT License