跳轉到

08.3 veryl doc 文件#

程式碼是寫給機器與人看的,但只看程式碼往往不足以理解設計意圖。veryl doc 從原始碼的文件註解自動產生文件,把「文件跟著程式碼走」變成預設行為。

veryl doc 做什麼#

Veryl 使用 /// 作為文件註解的語法,寫在 module、function、struct、enum 等定義的上方:

/// 8-bit up counter with synchronous reset.
/// `WIDTH` controls the counter width.
module Counter (
    param WIDTH: u32 = 8,
    port clk:   input clock,
    port rst:   input reset,
    port count: output logic<WIDTH>,
) {
    var cnt: logic<WIDTH>;

    always_ff (clk, rst) {
        if_reset {
            cnt = 0;
        } else {
            cnt = cnt + 1;
        }
    }

    assign count = cnt;
}

執行:

veryl doc

工具會解析整個專案,抽出所有 /// 註解與公開介面(module 的參數與 port、function 簽名、型別定義),產生可直接閱讀的文件輸出。輸出格式與細節隨版本演進,請參考官方文件。

熟悉 Rust 的人會立刻認出這個模式:rustdoc 從 /// 註解產生 API 文件,文件與程式碼同源,程式碼改了文件就過期,介面資訊(參數、型別)由編譯器保證正確,永不與實作脫節。

為什麼文件與程式碼同源很重要#

手寫文件的根本問題是腐化:介面改了,文件沒跟著改,讀者被誤導,而且往往比沒有文件更糟。同源文件解決這個問題的方式是結構性的:

  • 介面資訊自動抽取,不依賴人的記憶與紀律。
  • 註解就寫在定義旁邊,改程式碼時順眼就會看到註解,兩者的更新距離最小。
  • 文件生成可以放進 CI,甚至檢查公開介面是否有文件(類比 rustdoc 的 missing docs lint)。

歷史:硬體界薄弱的文件文化#

要理解 veryl doc 的價值,得先承認一個現實:硬體界的文件文化長期薄弱。

開源軟體有 README、有 docstring、有自動發布的 API 文件站;而大部分 RTL IP 的「文件」是一份 Word 或 PDF 的 datasheet,由專案結尾時趕工出來,之後與程式碼分道揚鑣各自演化。開源硬體專案的文件品質尤其參差,使用者往往只能讀原始碼猜介面。

但硬體界的另一端,文件又極端重要:商業 IP 交付時,文件是合約的一部分。買方購入一個 IP,合約會明訂交付物清單——RTL、驗證環境、整合指南、暫存器文件——文件不齊等於違約。這是因為硬體整合的成本與風險遠高於軟體:介面理解錯誤可能要到模擬後期甚至流片後才爆發,前期文件就是風險管理工具。

於是出現了一個弔詭:文件在制度上被高度重視(合約條款),在日常工作流中卻被輕視(趕工、腐化、與程式碼脫節)。根本原因之一是缺乏好工具:寫 Word 文件無法自動驗證正確性,更新成本高,自然沒人更新。

veryl doc 這類同源文件工具正是針對這個結構性問題:把文件生產從「專案結尾的趕工」變成「每次 build 順手完成」,把「合約要求的文件」變成「工具自動產出的副產品」。對以 IP 交付為商業模式的團隊,這直接降低交付成本;對開源專案,這把文件門檻降到願意寫註解就夠。

與 publish 的關係#

Veryl 工具鏈中還有 veryl publish,用於把專案發布為可供他人引用的套件。文件與發布是同一條鏈的兩段:/// 註解是素材,veryl doc 產生文件,veryl publish 把專案(連同其介面文件)變成別人可以直接依賴的單位。這個組合指向的是硬體界尚未普及的願景:IP 像軟體套件一樣,有版本、有文件、有一鍵引入。

小結#

veryl doc 用 rustdoc 的模式解決硬體界「文件是合約一部分卻又長期腐化」的矛盾:文件註解寫在定義旁,介面資訊由編譯器保證,文件輸出隨 build 自動更新。下一章我們把整條工具鏈放上 CI,看版本控制與自動化如何成為 Veryl 工作流的最後一塊拼圖。