Pyverilog
Pyverilog is a Python-based Hardware Design Processing Toolkit for Verilog HDL, providing a parser, dataflow analyzer, controlflow analyzer, and code generator. It allows users to parse Verilog code into an Abstract Syntax Tree (AST), analyze its structure, and extract design information. The current version is 1.3.0, and releases occur periodically, typically every few months, addressing bugs and adding new features.
Common errors
-
ModuleNotFoundError: No module named 'ply'
cause Since Pyverilog 1.3.0, the `ply` library is no longer bundled and must be installed as a separate dependency.fixInstall the `ply` package: `pip install ply` -
pyverilog.vparser.parser.ParseError: Cannot parse the source file.
cause This error typically indicates a syntax error in the Verilog source code, an unsupported Verilog construct, or an issue with the preprocessor (e.g., missing include files, `iverilog` not found).fixVerify your Verilog file for syntax errors. If using preprocessing, ensure `iverilog` is installed and accessible in your PATH, and all `-I` include paths are correctly specified. -
FileNotFoundError: [Errno 2] No such file or directory: 'iverilog'
cause Pyverilog's preprocessor tries to invoke the `iverilog` command, but it's not found in the system's PATH.fixInstall `Icarus Verilog` on your system and ensure its executable (`iverilog`) is available in your system's PATH environment variable.
Warnings
- breaking The `ply` library, a core dependency for Verilog parsing, is no longer bundled with Pyverilog since version 1.3.0. Users upgrading from prior versions will encounter `ModuleNotFoundError` if `ply` is not installed separately.
- breaking Python 2 support was officially disabled in version 1.1.3. Pyverilog now exclusively supports Python 3.
- gotcha For features like Verilog preprocessor (`-p` or `preprocess=True` in `VerilogParser`) which handle `include` directives or macros, the external tool `Icarus Verilog` (specifically the `iverilog` command) must be installed and accessible in your system's PATH.
- breaking In version 1.2.0, the `subprocess.call()` method used within the preprocessor no longer uses `shell=True` for security reasons. This could affect users who relied on specific shell behaviors or complex custom `iverilog` commands that implicitly leveraged shell features.
Install
-
pip install pyverilog ply
Imports
- VerilogParser
from pyverilog.vparser.parser import VerilogParser
- vast
import pyverilog.vparser.ast as vast
- DataflowAnalyzer
from pyverilog.dataflow.dataflow import DataflowAnalyzer
- DotGraph
from pyverilog.dataflow.graph import DotGraph
Quickstart
import os
from pyverilog.vparser.parser import VerilogParser
import pyverilog.vparser.ast as vast
from pyverilog.dataflow.dataflow import DataflowAnalyzer
from pyverilog.dataflow.graph import DotGraph
# Create a dummy Verilog file for parsing
verilog_code = """
module test_module (input clk, input rst, output reg [7:0] count);
always @(posedge clk or posedge rst) begin
if (rst) begin
count <= 8'h00;
end else begin
count <= count + 1;
end
end
endmodule
"""
with open('example.v', 'w') as f:
f.write(verilog_code)
# 1. Parse the Verilog file into an AST
parser = VerilogParser()
ast = parser.parse(['example.v'])
print("--- Verilog AST --- ")
# ast.show() # Uncomment to print the full AST
# 2. Perform Dataflow Analysis
analyzer = DataflowAnalyzer()
analyzer.visit(ast)
# Get dataflow graph and print some nodes
dfg = analyzer.get_dfg()
print("\n--- Dataflow Analysis (some nodes) ---")
for node_id, node in dfg.items():
if isinstance(node_id, vast.Port) or isinstance(node_id, vast.Reg):
print(f"Node: {node_id.name}, Type: {type(node_id).__name__}, Defs: {len(node.definitions)}")
# 3. Generate a DOT graph (requires graphviz and dot command)
# try:
# graph = DotGraph(dfg)
# graph.write_dot('dfg.dot')
# print("\nDataflow graph written to dfg.dot (requires Graphviz to visualize).")
# except Exception as e:
# print(f"\nCould not generate DOT graph: {e} (Is Graphviz installed?)")
# Clean up the dummy file
os.remove('example.v')