DoxNet

DoxNet

Documentation generator and checker for Verilog and SystemVerilog.

Dokumentationsgenerator und Prüfwerkzeug für Verilog und SystemVerilog.

DoxNet reads the RTL, takes ports, parameters, types and instances from the declarations and combines them with Doxygen-style comments. It writes a standalone HTML page, Markdown, JSON and optionally PDF, and in CI it fails the build when coverage drops or a comment describes a port that no longer exists.

DoxNet liest den RTL-Code, übernimmt Ports, Parameter, Typen und Instanzen aus den Deklarationen und verbindet sie mit Kommentaren im Doxygen-Stil. Es schreibt eine eigenständige HTML-Seite, Markdown, JSON und optional PDF, und in der CI lässt es den Build scheitern, wenn die Abdeckung sinkt oder ein Kommentar einen Port beschreibt, den es nicht mehr gibt.

v3.0Python 3.9+CLI · GitHub Action · pre-commitMIT

CommentsKommentare

Names, directions, widths and defaults come from the code. A comment only has to say what the code can't: what a port is for. Comments can sit in front of a declaration (/** */, ///) or behind it (///<), or be written as tags in the unit comment.

Namen, Richtungen, Breiten und Standardwerte kommen aus dem Code. Ein Kommentar muss nur sagen, was der Code nicht kann: wofür ein Port da ist. Kommentare können vor einer Deklaration stehen (/** */, ///), dahinter (///<) oder als Tags im Kommentar der Einheit.

sync_fifo.sv
/**
 * @brief Single-clock FIFO with registered outputs.
 *
 * Write and read may happen in the same cycle.
 * @note DEPTH must be a power of two.
 */
module sync_fifo #(
  parameter int WIDTH = 8,   ///< Data width in bits
  parameter int DEPTH = 16   ///< Number of entries
) (
  input  logic             clk,      ///< Clock
  input  logic             rst_n,    ///< Asynchronous reset, active low
  input  logic [WIDTH-1:0] wr_data,  ///< Data to push
  output logic             full      ///< No free entry left
);
TagsUsed forWofür
@brief, @detailsSummary and description. Descriptions are Markdown.Zusammenfassung und Beschreibung. Beschreibungen sind Markdown.
@port, @input, @output, @inoutPorts; the direction tags also check the declared directionPorts; die Richtungs-Tags prüfen zusätzlich die deklarierte Richtung
@parameter, @localparam, @paramParameters and local parametersParameter und lokale Parameter
@modport, @instanceInterface modports and instances inside a unitModports von Interfaces und Instanzen innerhalb einer Einheit
@note, @warning, @todo, @deprecatedHighlighted in the outputIn der Ausgabe hervorgehoben
@see, @author, @version, @sinceReferences (unit names become links) and metadataVerweise (Namen von Einheiten werden zu Links) und Metadaten
@fileDescribes the file instead of the next unitBeschreibt die Datei statt der nächsten Einheit

Besides ports and parameters, DoxNet lists typedefs, functions, tasks, classes, modports and instances with their comments. It handles modules, interfaces, packages, programs and UDPs with ANSI and non-ANSI headers. Existing code that describes ports with plain // … comments on the same line can be read with --plain-comments.

Neben Ports und Parametern listet DoxNet Typedefs, Funktionen, Tasks, Klassen, Modports und Instanzen mit ihren Kommentaren auf. Es versteht Module, Interfaces, Packages, Programs und UDPs mit ANSI- und Nicht-ANSI-Köpfen. Bestehender Code, der Ports mit einfachen // …-Kommentaren in derselben Zeile beschreibt, lässt sich mit --plain-comments einlesen.

OutputAusgabe

The main output is a single HTML file with all styles and scripts inlined. It can be opened from disk, attached to a ticket or published on GitHub Pages. The screenshots show the UART example from the repository.

Die Hauptausgabe ist eine einzelne HTML-Datei, in der alle Styles und Skripte eingebettet sind. Sie lässt sich direkt von der Festplatte öffnen, an ein Ticket hängen oder auf GitHub Pages veröffentlichen. Die Screenshots zeigen das UART-Beispiel aus dem Repository.

Generated page for the uart_tx module: port block diagram, parameter and port tables
One unit: block diagram of its ports, parameters with defaults, ports with direction and width.
Eine Einheit: Blockschaltbild ihrer Ports, Parameter mit Standardwerten, Ports mit Richtung und Breite.
Generated overview with coverage per category and the design hierarchy
Overview: coverage per category and the design hierarchy.
Übersicht: Abdeckung pro Kategorie und die Design-Hierarchie.
html

Standalone page

Search (/ to focus), light and dark theme, highlighted source with line anchors, or links to your repository via --source-url.

html

Eigenständige Seite

Suche (/ zum Fokussieren), helles und dunkles Theme, hervorgehobener Quellcode mit Zeilenankern oder Links in dein Repository über --source-url.

diagram

Block diagrams

An SVG of each unit's ports, inputs left, outputs right, interface ports marked.

diagramm

Blockschaltbilder

Ein SVG der Ports jeder Einheit, Eingänge links, Ausgänge rechts, Interface-Ports markiert.

hierarchy

Design hierarchy

Tree from the top modules, "instantiated by" links, unresolved vendor cells shown as such.

hierarchie

Design-Hierarchie

Baum ab den Top-Modulen, Links „instanziiert von“, nicht auflösbare Herstellerzellen als solche gekennzeichnet.

markdown

Markdown

The same content without diagrams, with stable anchors for links between units.

markdown

Markdown

Derselbe Inhalt ohne Diagramme, mit stabilen Ankern für Links zwischen Einheiten.

json

JSON report

Units, ports, parameters, hierarchy, diagnostics and coverage, with a published JSON Schema.

json

JSON-Bericht

Einheiten, Ports, Parameter, Hierarchie, Diagnosen und Abdeckung, mit veröffentlichtem JSON-Schema.

pdf

PDF

Via Pandoc and LaTeX if installed; everything else works without them.

pdf

PDF

Über Pandoc und LaTeX, falls installiert; alles andere funktioniert ohne.

Install & runInstallieren & starten

terminal
$ pip install git+https://github.com/BTFLV/DoxNet.git

# document every .v/.sv/.vh/.svh below rtl/
$ doxnet --input rtl --output build/docs

# with macros and include paths, as for the simulator
$ doxnet --filelist sim/files.f -D SYNTHESIS --incdir rtl/include --output build/docs

# check only: all units documented, 90 % of ports, no warnings
$ doxnet --input rtl --check --strict --min-port-coverage 90 --fail-on-warnings

For anything beyond a quick run, the options go into a config file. JSON and TOML work, as does a [tool.doxnet] section in pyproject.toml.

Für alles über einen schnellen Lauf hinaus kommen die Optionen in eine Konfigurationsdatei. JSON und TOML funktionieren, ebenso ein Abschnitt [tool.doxnet] in der pyproject.toml.

doxnet.json
{
  "title": "UART example",
  "input": "rtl",
  "include_dirs": ["rtl/include"],
  "output": "build/docs",
  "html_file": "index.html",
  "min_coverage": 100,
  "min_port_coverage": 100,
  "fail_on_warnings": true
}

Inputs and preprocessingEingaben und Präprozessor

Files come from a directory, an explicit list in the config, or a simulator filelist. `ifdef, `ifndef, `elsif and `else are evaluated, so code in an inactive branch doesn't show up in the documentation or count towards coverage.

Dateien kommen aus einem Verzeichnis, einer expliziten Liste in der Konfiguration oder einer Simulator-Filelist. `ifdef, `ifndef, `elsif und `else werden ausgewertet, sodass Code in einem inaktiven Zweig weder in der Dokumentation auftaucht noch zur Abdeckung zählt.

files.f
# comments start with # or //
+incdir+include+../common/include
+define+SYNTHESIS+BUS_WIDTH=64
$PROJECT_ROOT/rtl/top.sv
${IP_ROOT}/fifo/fifo.sv
-f ../common/common.f

FilelistsFilelists

  1. Nested -f/-F, resolved relative to the filelist that contains them.
  2. +incdir+ and +define+ with several values.
  3. $VAR, ${VAR} and $(VAR) from the environment.
  4. Options DoxNet can't honor, like -y or +libext+, are rejected instead of ignored.
  1. Verschachtelte -f/-F, aufgelöst relativ zur Filelist, in der sie stehen.
  2. +incdir+ und +define+ mit mehreren Werten.
  3. $VAR, ${VAR} und $(VAR) aus der Umgebung.
  4. Optionen, die DoxNet nicht umsetzen kann, etwa -y oder +libext+, werden abgelehnt statt ignoriert.

Macros per fileMakros pro Datei

  1. SYSTEMVERILOG, always defined.
  2. -D on the command line and defines in the config.
  3. +define+ from filelists.
  4. `define and `undef in the sources, in file order.
  1. SYSTEMVERILOG, immer definiert.
  2. -D auf der Kommandozeile und defines in der Konfiguration.
  3. +define+ aus Filelists.
  4. `define und `undef in den Quellen, in Dateireihenfolge.

ChecksPrüfungen

Every documented name is matched against the parsed declaration. When a port is renamed but its comment isn't, the run says so, and the coverage gate catches the now undocumented port:

Jeder dokumentierte Name wird mit der geparsten Deklaration abgeglichen. Wird ein Port umbenannt, sein Kommentar aber nicht, meldet der Lauf das, und die Abdeckungsschwelle fängt den nun undokumentierten Port ab:

doxnet --check
$ doxnet -c doxnet.json --check
WARNING: uart_tx.sv:15: DOC001: @port refers to unknown port busy
INFO: units coverage: 5/5 (100.0%)
INFO: ports coverage: 19/20 (95.0%)
ERROR: ports coverage 95.0% is below the required 100.0%
INFO: parameters coverage: 7/7 (100.0%)
# exit code 2
CodeMeaningBedeutung
DOC001A tag names a port, parameter, modport or instance that doesn't existEin Tag nennt einen Port, Parameter, Modport oder eine Instanz, die es nicht gibt
DOC002@input/@output/@inout disagrees with the declared direction@input/@output/@inout widerspricht der deklarierten Richtung
DOC003The same entity is documented twiceDasselbe Element ist doppelt dokumentiert
DOC004A comment with tags isn't attached to anything, usually code in betweenEin Kommentar mit Tags gehört zu nichts, meist steht Code dazwischen
DOC005Unknown tag, often a typo such as @ouptutUnbekanntes Tag, oft ein Tippfehler wie @ouptut
DOC006A tag without descriptionEin Tag ohne Beschreibung
HDL / PPUnreadable headers, duplicate unit names, unbalanced `ifdef, missing includesUnlesbare Köpfe, doppelte Einheitennamen, unausgeglichene `ifdef, fehlende Includes
Exit-CodeMeaningBedeutung
0SuccessErfolg
1Configuration or input error; nothing is writtenKonfigurations- oder Eingabefehler; es wird nichts geschrieben
2Coverage below a thresholdAbdeckung unter einer Schwelle
3Output or required PDF failed, or warnings with --fail-on-warningsAusgabe oder erforderliches PDF fehlgeschlagen, oder Warnungen mit --fail-on-warnings

Coverage is counted separately for units, ports and parameters. A unit without ports counts as N/A, not as 100 %. Individual warnings can be switched off with --disable.

Die Abdeckung wird getrennt für Einheiten, Ports und Parameter gezählt. Eine Einheit ohne Ports zählt als N/A, nicht als 100 %. Einzelne Warnungen lassen sich mit --disable abschalten.

CI

The repository is a GitHub Action. It installs DoxNet and reports diagnostics as annotations on the affected lines of a pull request.

Das Repository ist zugleich eine GitHub Action. Sie installiert DoxNet und meldet Diagnosen als Anmerkungen an den betroffenen Zeilen eines Pull Requests.

.github/workflows/hdl-docs.yml
jobs:
  docs:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: BTFLV/DoxNet@v3.0.0
        with:
          args: --config doxnet.json --output build/hdl-docs --no-pdf
      - uses: actions/upload-artifact@v4
        with:
          name: hdl-docs
          path: build/hdl-docs

There's also a pre-commit hook that runs doxnet --check, and the same command works in GitLab CI or anywhere else with Python.

Außerdem gibt es einen pre-commit-Hook, der doxnet --check ausführt, und derselbe Befehl funktioniert in GitLab CI oder überall sonst, wo Python läuft.

.pre-commit-config.yaml
repos:
  - repo: https://github.com/BTFLV/DoxNet
    rev: v3.0.0
    hooks:
      - id: doxnet
        args: [--config, doxnet.json]

For an existing, mostly undocumented code base, start with thresholds slightly below the current coverage and raise them over time. fail_on_warnings is worth enabling early: a stale comment is cheap to fix when it appears.

Bei einer bestehenden, größtenteils undokumentierten Codebasis mit Schwellen knapp unter der aktuellen Abdeckung starten und sie mit der Zeit anheben. fail_on_warnings lohnt sich früh: Ein veralteter Kommentar ist billig zu beheben, wenn er gerade entsteht.

LimitsGrenzen

DoxNet parses declarations; it doesn't elaborate the design. Expressions are shown as written, so [WIDTH-1:0] stays symbolic, macros aren't expanded and generate loops aren't unrolled. It covers the constructs found in typical RTL but isn't a replacement for a compiler.

DoxNet parst Deklarationen, elaboriert das Design aber nicht. Ausdrücke werden so gezeigt, wie sie geschrieben sind: [WIDTH-1:0] bleibt symbolisch, Makros werden nicht expandiert und Generate-Schleifen nicht aufgerollt. Es deckt die Konstrukte typischen RTL-Codes ab, ersetzt aber keinen Compiler.

DoxNet on GitHubDoxNet auf GitHub