API Reference

Doc IR

Doc IR (v1): module-level only. See PLAN.md Phase 1.

class svdoc.ir.Param(name: str, type: str, default: str | None, doc: str | None, type_ref: str | None = None)[source]

A single module/interface/subroutine parameter.

Variables:
  • name – Parameter identifier.

  • type – Declared type as written in source (e.g. "int").

  • default – Default value expression, or None if unset.

  • doc – Extracted doc comment, or None if undocumented.

  • type_ref – Fully-qualified "package::type" name if resolved cross-file via svdoc.parser.resolve_types(); None otherwise.

class svdoc.ir.Port(name: str, direction: str, type: str, doc: str | None, type_ref: str | None = None, modport_preview: Modport | None = None)[source]

A single module/interface/subroutine port or argument.

Also reused for subroutine arguments (see Subroutine.args), since the shape (name, direction, type, doc) is identical.

Variables:
  • name – Port identifier.

  • direction"input", "output", "inout", etc.

  • type – Declared type as written in source, including any packed dimensions (e.g. "logic [7:0]").

  • doc – Extracted doc comment, or None if undocumented.

  • type_ref – Fully-qualified "package::type" name if resolved cross-file via svdoc.parser.resolve_types(); None otherwise.

  • modport_preview – For an interface-typed port (direction == "interface"), the resolved Modport from the interface file, if it was found among the files passed to svdoc.parser.resolve_types(); None otherwise.

class svdoc.ir.ModuleDoc(name: str, doc: str | None, params: ~typing.List[~svdoc.ir.Param] = <factory>, ports: ~typing.List[~svdoc.ir.Port] = <factory>)[source]

Doc IR for a single SystemVerilog module.

class svdoc.ir.Signal(name: str, type: str, doc: str | None)[source]

A variable declared in an interface body (outside any modport).

class svdoc.ir.ModportPortGroup(direction: str, signals: List[str], doc: str | None)[source]

One direction-grouped clause within a modport, e.g. output valid, data.

class svdoc.ir.Modport(name: str, doc: str | None, port_groups: ~typing.List[~svdoc.ir.ModportPortGroup] = <factory>)[source]

A single modport declaration inside an interface.

class svdoc.ir.InterfaceDoc(name: str, doc: str | None, params: ~typing.List[~svdoc.ir.Param] = <factory>, ports: ~typing.List[~svdoc.ir.Port] = <factory>, signals: ~typing.List[~svdoc.ir.Signal] = <factory>, modports: ~typing.List[~svdoc.ir.Modport] = <factory>)[source]

Doc IR for a single SystemVerilog interface, including its modports.

class svdoc.ir.EnumValue(name: str, value: str | None, doc: str | None)[source]

A single named value within an enum typedef.

class svdoc.ir.StructField(name: str, type: str, doc: str | None)[source]

A single field within a packed struct typedef.

class svdoc.ir.Typedef(name: str, doc: str | None, kind: str, base_type: str | None = None, alias_type: str | None = None, values: ~typing.List[~svdoc.ir.EnumValue] = <factory>, fields: ~typing.List[~svdoc.ir.StructField] = <factory>)[source]

A single typedef declared in a package: enum, packed struct, or alias.

Variables:
  • kind – One of "enum", "struct", or "alias" — determines which of base_type/values, fields, or alias_type is populated.

  • base_type – For kind="enum", the underlying integer type (e.g. "logic [1:0]").

  • alias_type – For kind="alias", the type being aliased.

  • values – For kind="enum", the enum’s named values in declaration order.

  • fields – For kind="struct", the struct’s fields in declaration order.

class svdoc.ir.Subroutine(name: str, doc: str | None, kind: str, return_type: str | None = None, args: ~typing.List[~svdoc.ir.Port] = <factory>)[source]

A function or task declared in a package.

Variables:
  • kind"function" or "task".

  • return_type – Declared return type; always None for tasks.

  • args – Arguments, reusing Port’s name/direction/type/doc shape.

class svdoc.ir.PackageDoc(name: str, doc: str | None, typedefs: ~typing.List[~svdoc.ir.Typedef] = <factory>, subroutines: ~typing.List[~svdoc.ir.Subroutine] = <factory>)[source]

Doc IR for a single SystemVerilog package: its typedefs and subroutines.

class svdoc.ir.ParamValue(name: str, value: str)[source]

A single parameter’s resolved (post-override) value on one instance.

class svdoc.ir.PortConnection(name: str, expr: str | None, interface_instance: str | None = None, modport: str | None = None)[source]

A single port’s connected expression on one instance.

Variables:
  • expr – Connected expression text, for plain data-type ports. None for interface-typed ports (see interface_instance/ modport instead) or unconnected ports.

  • interface_instance – For an interface-typed port, the name of the sibling interface instance it’s bound to (e.g. "hs"); None for plain data-type ports.

  • modport – For an interface-typed port, the modport name used (e.g. "producer"); None for plain data-type ports.

class svdoc.ir.Instance(path: str, name: str, module: str, params: ~typing.List[~svdoc.ir.ParamValue] = <factory>, connections: ~typing.List[~svdoc.ir.PortConnection] = <factory>, children: ~typing.List[~svdoc.ir.Instance] = <factory>, is_interface: bool = False)[source]

One elaborated instance in a module hierarchy.

Variables:
  • path – Full hierarchical path (e.g. "top.g[0].u_leaf2"), unique within the hierarchy even under generate-block array expansion.

  • name – Instance name as written (e.g. "u_leaf2").

  • module – Name of the module/interface definition being instantiated.

  • params – Resolved parameter values (post any #(...) overrides).

  • connections – Port name -> connected expression, in port-list order.

  • children – Instances directly nested inside this one.

  • is_interfaceTrue if this instance is of an interface definition rather than a module.

Parser

AST walker: pyslang SyntaxTree -> Doc IR. See PLAN.md Phase 1 (modules) and Phase 2 (interfaces/modports).

svdoc.parser.parse_module(path: str, include_dirs: list | None = None) ModuleDoc[source]

Parse a .sv file containing a single module declaration.

Parameters:
  • path – Path to the .sv file. Only the first module found in the file is parsed.

  • include_dirs – Optional directories to search for `include targets that don’t live alongside path (e.g. a shared include/ directory). `include``s resolve automatically without this when the included file is in the same directory as ``path.

Returns:

The module’s ModuleDoc.

Raises:

ValueError – If the file fails to parse cleanly.

svdoc.parser.parse_file(path: str, include_dirs: list | None = None)[source]

Parse a .sv file containing a single module, interface, or package.

Dispatches to parse_module(), parse_interface(), or parse_package() based on the syntax kind of the first top-level declaration found.

Parameters:
  • path – Path to the .sv file.

  • include_dirs – Optional directories to search for `include targets that don’t live alongside path.

Returns:

A ModuleDoc, InterfaceDoc, or PackageDoc, matching whichever construct was found.

Raises:

ValueError – If the file fails to parse cleanly.

svdoc.parser.resolve_types(doc, paths: list, include_dirs: list | None = None) None[source]

Resolve cross-file port types by elaborating a full Compilation.

Given a ModuleDoc (or InterfaceDoc) already parsed from a single file via parse_module() / parse_file(), and the full list of files it should be elaborated alongside (e.g. packages it imports types from), patches each Port’s type_ref with the fully-qualified "package::type" name for any port whose type resolves to a type defined in another file. Mutates doc in place.

Only meaningful for modules today: a bare interface never becomes an elaborated top-level instance, so this is a no-op when doc.name can’t be found among the compilation’s top instances.

Parameters:
  • doc – An already-parsed module (or interface) doc to patch in place.

  • paths – All .sv files needed to elaborate doc, including the file it was originally parsed from.

  • include_dirs – Optional directories to search for `include targets that don’t live alongside any file in paths (e.g. a shared include/ directory separate from per-module source dirs).

Raises:

ValueError – If any of the given files fails to parse cleanly.

svdoc.parser.parse_interface(path: str, include_dirs: list | None = None) InterfaceDoc[source]

Parse a .sv file containing a single interface declaration.

Parameters:
  • path – Path to the .sv file. Only the first interface found in the file is parsed.

  • include_dirs – Optional directories to search for `include targets that don’t live alongside path.

Returns:

The interface’s InterfaceDoc, including its signals and modports.

Raises:

ValueError – If the file fails to parse cleanly.

svdoc.parser.parse_package(path: str, include_dirs: list | None = None) PackageDoc[source]

Parse a .sv file containing a single package declaration.

Parameters:
  • path – Path to the .sv file. Only the first package found in the file is parsed.

  • include_dirs – Optional directories to search for `include targets that don’t live alongside path.

Returns:

The package’s PackageDoc, including its typedefs (enums, structs, aliases) and subroutines (functions, tasks).

Raises:

ValueError – If the file fails to parse cleanly.

Markdown renderer

Markdown renderer: Doc IR -> Obsidian-friendly .md string.

svdoc.render_md.render(mod: ModuleDoc) str[source]

Render a ModuleDoc to an Obsidian-friendly Markdown string.

svdoc.render_md.render_interface(iface: InterfaceDoc) str[source]

Render an InterfaceDoc to an Obsidian-friendly Markdown string.

svdoc.render_md.render_package(pkg: PackageDoc) str[source]

Render a PackageDoc to an Obsidian-friendly Markdown string.

HTML renderer

HTML renderer: Doc IR -> a single self-contained .html page per construct.

Cross-links are convention-based, not verified: a Port/Param whose type_ref is “pkg_name::type_name” links to “pkg_name.html#type_name”, assuming that page was (or will be) generated by rendering pkg_name’s own package file the same way. Nothing here checks that the target page or anchor actually exists.

svdoc.render_html.page(title: str, body_lines: list) str[source]

Wrap body_lines (raw HTML fragments) in a self-contained HTML page with the shared inline stylesheet. Exposed for svdoc.build, which uses it to render the site’s index.html.

svdoc.render_html.render(mod: ModuleDoc) str[source]

Render a ModuleDoc to a self-contained HTML page.

svdoc.render_html.render_interface(iface: InterfaceDoc) str[source]

Render an InterfaceDoc to a self-contained HTML page.

svdoc.render_html.render_package(pkg: PackageDoc) str[source]

Render a PackageDoc to a self-contained HTML page.

Fixer

svdoc –fix: insert ///< TODO next to undocumented ports/params, and a /** @brief TODO */ stub above an undocumented module, in place. Mirrors ruff –fix — scaffolds missing docs rather than guessing their content.

svdoc.fixer.fix_file(path: str) bool[source]

Scaffold missing doc comments in place, in path, and save the result.

Inserts ///< TODO next to any undocumented port/parameter, and a /** @brief TODO */ stub above the module/interface/package itself if it has no doc comment. Idempotent: re-running on an already-documented file makes no changes.

Parameters:

path – Path to the .sv file to fix in place.

Returns:

True if the file was modified, False if it was already fully documented.

Raises:

ValueError – If the file fails to parse cleanly.

Site builder

svdoc build: a flat multi-page HTML site (one page per construct) with a navigable index, so cross-links between pages always resolve correctly – avoids the relative-path problem of generating standalone pages into whatever directories the source files happen to live in.

svdoc.build.build_site(paths: list, out_dir: str, include_dirs: list | None = None) str[source]

Parse every file in paths and write one HTML page per construct into a single flat out_dir, plus an index.html linking to all of them. Because every page lands in the same directory, the convention-based cross-links in svdoc.render_html (pkg_name.html#member) always resolve correctly, regardless of where the source .sv files live.

Parameters:
  • paths – All .sv files to document. Each is parsed independently (one construct per file, same as svdoc.parser.parse_file()); cross-file type resolution runs against the full set for every module.

  • out_dir – Directory to write the site into. Created if missing.

  • include_dirs – Optional directories to search for `include targets that don’t live alongside any file in paths (e.g. a shared include/ directory separate from per-module source dirs).

Returns:

Path to the written index.html.

Raises:

ValueError – If any file fails to parse cleanly.

CLI

svdoc CLI (v1): svdoc <file.sv> prints to terminal; –out md/–out html writes a file; svdoc build <files…> writes a multi-page linked HTML site.

svdoc.cli.main(argv=None)[source]

Entry point for the svdoc command (registered via pyproject.toml).

Two modes, dispatched on whether the first argument is the literal build subcommand (argparse subparsers don’t mix cleanly with a same-position positional argument, so this is checked manually rather than via add_subparsers):

  • svdoc <file.sv> [more_files...] — document a single module/interface/ package, optionally resolving cross-file types against more_files, printing Markdown to stdout or writing a single Markdown/HTML file (--out), or scaffolding missing doc comments in place (--fix).

  • svdoc build <files...> --out-dir <dir> — document every given file into a single flat multi-page HTML site (one page per construct plus an index.html), so cross-links between pages always resolve correctly regardless of where the source files live on disk.

Parameters:

argv – Argument list to parse (as sys.argv()[1:] would appear). Defaults to sys.argv[1:] when None.