Architecture
svblock uses a four-stage pipeline to transform SystemVerilog source files into SVG pin diagrams.
.sv file --> Parse --> Module IR --> Layout --> SVG Render --> .svg file
Each stage is cleanly separated with well-defined data structures flowing between them.
Pipeline Stages
Stage 1: Parser
Module: svblock.parser
The parser stage uses pyslang to build a full IEEE 1800-2017 compliant syntax tree from the input file. It then walks the tree to extract:
Module name
Port declarations (direction, type, bus range, name)
Parameter declarations (type, name, default value)
Source line numbers for annotation association
Additionally, the annotation sub-parser (svblock.parser.annotation) scans
the raw source text for // @sym comments and associates them with ports by
line proximity.
Key design choice: pyslang is the only parser backend. There is no fallback to regex-based parsing or other tools. This ensures full SV 2017 compliance.
Stage 2: Module IR
Module: svblock.model
The intermediate representation consists of three dataclasses:
PortDef– a single port with direction, name, bus range (as strings), and decorator markers (clock, active-low, bus, interface)ParamDef– a parameter with type, name, and default valueModuleIR– the complete module with name, ports, parameters, and groups
Bus ranges are kept as strings (e.g., "WIDTH-1", "0") and are never
evaluated, since they may contain parametric expressions.
Stage 3: Layout
Module: svblock.layout
The layout engine computes all geometric coordinates for the diagram:
Box sizing – based on the longest port labels, module name width, and parameter count
Pin placement – inputs on the left, outputs/inout/interfaces on the right
Group separators – dashed lines between port groups, with centered labels
Header – module name centered, parameters listed below
The layout stage also applies heuristic grouping when no annotations are present, detecting common patterns like clock and reset signals.
Key configuration values (from LayoutConfig):
Parameter |
Default |
Description |
|---|---|---|
|
20px |
Vertical space per pin |
|
240px |
Minimum diagram width |
|
30px |
Length of pin lines extending from the box |
|
36px |
Height of the module name area |
|
16px |
Additional height per parameter line |
Stage 4: SVG Renderer
Module: svblock.renderer
The renderer translates the LayoutSpec into an SVG string using pure Python
string concatenation (no template engine). It generates:
A
<style>block with CSS custom properties from the active themeThe main box
<rect>and headerPin lines (
<line>) with CSS class-based coloringPin labels (
<text>) with<title>tooltipsDecorator shapes:
<polygon>for clocks/diamonds,<circle>for active-low bubblesGroup separator
<line>elements withstroke-dasharray
Determinism guarantees:
Element IDs follow the pattern
port-{name},group-{name},module-{name}Ports are rendered in declaration order
All floats are rounded to 2 decimal places
No timestamps or random values in the output
This makes the SVG output safe for version control – diffs will only show meaningful changes.
Supporting Modules
Exporters
Module: svblock.exporters
Optional PNG and PDF export via cairosvg. These are thin wrappers that take
an SVG string and write the converted output to a file. The cairosvg
dependency is lazy-imported, so it’s only required when PNG/PDF output is
requested.
Sphinx Extension
Module: svblock.sphinx_ext
A Sphinx directive (.. svblock::) that runs the full pipeline at build time
and injects the SVG as a raw HTML node. See Sphinx Extension for usage.
Configuration
Module: svblock.config
Loads themes from built-in presets or custom TOML/YAML files. Custom values are merged with the default theme so that partial overrides work correctly.
Directory Structure
src/svblock/
+-- __init__.py # Package version
+-- cli.py # CLI entry point
+-- config.py # Theme loading (TOML/YAML)
+-- py.typed # PEP 561 marker
+-- parser/
| +-- sv_extractor.py # pyslang wrapper
| +-- annotation.py # @sym comment parser
+-- model/
| +-- port_types.py # PortDirection enum
| +-- module_ir.py # ModuleIR, PortDef, ParamDef
+-- layout/
| +-- engine.py # Box geometry & pin coordinates
| +-- grouping.py # Heuristic & annotation grouping
| +-- text_metrics.py # Font width estimation
+-- renderer/
| +-- svg_renderer.py # SVG string generation
| +-- themes.py # Built-in theme definitions
+-- exporters/
| +-- png.py # cairosvg PNG wrapper
| +-- pdf.py # cairosvg PDF wrapper
+-- sphinx_ext/
+-- directive.py # Sphinx .. svblock:: directive