Architecture
============
svblock uses a four-stage pipeline to transform SystemVerilog source files into
SVG pin diagrams.
.. code-block:: text
.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 value
- ``ModuleIR`` -- 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``):
.. list-table::
:header-rows: 1
:widths: 35 15 50
* - Parameter
- Default
- Description
* - ``pin_row_height``
- 20px
- Vertical space per pin
* - ``min_box_width``
- 240px
- Minimum diagram width
* - ``pin_stub_length``
- 30px
- Length of pin lines extending from the box
* - ``header_base_height``
- 36px
- Height of the module name area
* - ``header_param_line_height``
- 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 ``