Architecture¶
svhier parses SystemVerilog files using the pyslang C++ extension (slang elaborator)
and outputs a module/instance hierarchy as YAML.
Parser¶
Parse a list of SystemVerilog files and return the module/instance hierarchy. |
|
Return file paths in topological dependency order (dependencies first). |
- svhier.parser.parse_files(file_paths: list[str]) dict¶
Parse a list of SystemVerilog files and return the module/instance hierarchy.
All files share a single
SourceManagerso cross-file instantiation resolves correctly. See the module docstring for the two-phase elaboration model.Returns a dict with the following top-level keys:
filesOne entry per input file, each containing:
file_name— original caller string (not resolved).pkgs— package names defined in this file (internal bookkeeping, stripped from YAML output bysvhier.cli._prepare_for_yaml()).defs— list of module definitions, each withmod_name,pkg_imports(omitted from YAML when empty), andinsts(list of{"mod_name": str, "inst_name": str}).
diagnosticsList of
{"severity": str, "file": str, "message": str}dicts from pyslang’sDiagnosticEngine(internal; stripped from YAML output).has_errorsTrueif any error-level diagnostic was issued. The CLI exits with code 1 when this is set.
Note
Modules that are defined but never instantiated are unreachable via topInstances
and will appear in the output with an empty insts list.
- svhier.parser.compute_filelist(result: dict) list[str]¶
Return file paths in topological dependency order (dependencies first).
Builds a
networkx.DiGraphwhere an edgeA → Bmeans file A must be compiled before file B. Edges come from two sources:Module instantiation — a file that instantiates a module depends on the file that defines it.
Package imports — a file that imports a package depends on the file that defines it.
nx.topological_sortproduces the compilation order. If the graph contains a cycle the original input order is returned unchanged.result is the dict returned by
parse_files().
Tip
If your design has genuine circular dependencies between files, the filelist falls back to the original input order rather than raising an error.
CLI¶
Expand a mix of |
|
Return directories that contain |
|
Entry point: parse arguments, run slang elaboration, emit YAML and optional filelist. |
- svhier.cli.collect_sv_files(paths: list[str], recursive: bool) list[str]¶
Expand a mix of
.sv/.vfiles and directories into a deduplicated file list.Directories are searched for
*.svand*.vfiles; when recursive isTruethe search descends into subdirectories (**/). Duplicate paths (by resolved canonical path) are silently dropped. Paths that are neither a file nor a directory emit a warning to stderr and are skipped.
- svhier.cli.collect_inc_dirs(paths: list[str], recursive: bool) list[str]¶
Return directories that contain
.svh/.vhheader files under paths.The result is written as
+incdir+<dir>lines at the top of the generated filelist, which is the format expected by VCS, Questa, and Xcelium.For directory inputs the search respects the recursive flag. For explicit file inputs the parent directory is checked for headers. Directories are returned in discovery order, deduplicated.
- svhier.cli.main()¶
Entry point: parse arguments, run slang elaboration, emit YAML and optional filelist.
All Rich diagnostics (spinner, summary table, warnings) go to stderr so stdout stays clean for piped data. Exits with code 1 if pyslang reports any error-level diagnostics.
Filtering rules¶
The following symbols are intentionally excluded from the output:
Packages and interfaces —
getDefinitions()is filtered toDefinitionKind.Moduleonly.Interface instances — excluded inside module bodies via the
child.isModuleguard (interface instances shareSymbolKind.Instancewith module instances but haveisModule == False).pkgskey — internal bookkeeping stripped from YAML output by_prepare_for_yaml().diagnosticskey — pyslang diagnostics are printed to stderr and stripped from YAML output.
Development notes¶
Warning
pyslang exposes its API through a compiled C++ extension that pylint cannot
introspect. generated-members = ["pyslang.*"] in pyproject.toml suppresses
the resulting false-positive no-member errors. The same list is passed to
Sphinx via autodoc_mock_imports so the docs build without a compiled extension
present.
Line length is set to 160 in the pylint configuration.