Community程式設計與開發github.com

Verilog / SystemVerilog → 可編輯 draw.io 圖(四種視角)

將 Verilog / SystemVerilog 程式碼(以及論文、專利、口頭描述)自動轉換成四種可編輯的 draw.io 圖:架構圖、結構框圖、狀態機圖、整體控制結構圖,無需手動繪製。

SystemVerilog → 可編輯 draw.io 圖(四種視角) 是什麼?

這個技能專為硬體設計工程師與架構師打造,能將 Verilog/SystemVerilog 原始碼(或論文、專利、口頭描述)自動生成四種專業的 draw.io 可編輯圖表。預設先產生「體系結構風格架構圖」(論文插圖級),由 AI agent 讀取程式碼後提取核心設計點,以流水級虛線分欄、將流水暫存器/FIFO 畫在分界線上、反饋信號繞回底邊,並支援多條流水按級對齊、SRAM 表顯示單一項目欄位、運算單元使用經典電路符號,以及重點結構反差色強調。若使用者想看門級細節,則使用「結構框圖」模式:基於 Yosys 網表,按流水級排佈暫存器、MUX、運算單元、比較器、邏輯閘、儲存陣列、FIFO 與子模組,並支援自動捆合簡化。「狀態機圖」可從 `case(state)` 結構直接解析 FSM,以均勻排列的圓形狀態呈現,並保留原始運算式條件。「整體控制結構圖」則只顯示控制信號,揭示各狀態機之間的相互驅動關係。依賴工具包括:PyYAML、drawio 匯出工具(支援 PNG/SVG)、Yosys、sv2v、Graphviz。這個技能適用於程式碼審查、論文/報告繪圖、晶片架構設計階段溝通,以及自動化文件生成。

相容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/BeenLi/claude-skills/tree/HEAD/skills/verilog-diagram

Installed? Explore more 程式設計與開發 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

Verilog → draw.io:架構圖 / 結構框圖 / 狀態機 / 控制結構

四個視角,按問題選擇:設計思想是什麼(給人講、放論文/報告)→ arch2drawio.py(第零節,預設); 閘級長怎樣(逐單元的資料路徑)→ rtl2drawio.py;怎麼走的(單個 FSM)→ fsm2drawio.py fsm; 誰指揮誰(整體控制結構)→ fsm2drawio.py ctrl。若以控制為主的模組(FSM、解碼、仲裁控制器)用框圖會亂,改用後兩者。

依賴:PyYAML;匯出 PNG/SVG 需要 drawio(搜尋順序 $DRAWIO_BIN → PATH → macOS app → ~/.local/opt/drawio; Linux 無 $DISPLAY 時自動套用 xvfb-run,無 root 的伺服器可使用倉庫裡的 tools/install-drawio-linux.sh 安裝)。若無匯出工具,所有命令仍正常生成 .drawio,只缺 PNG,stderr 提示一行。框圖/控制結構另需 yosys、sv2v(SystemVerilog)、dot(Graphviz),以及已安裝的 drawio-skill (預設 ~/.claude/skills/drawio-skill,可用環境變數 DRAWIO_SKILL_DIR 覆蓋;只呼叫它的 autolayout.py,不改它)。 三個生成腳本都接受 --png / --svg / --scale N(PNG 預設 scale 3,約 1 model unit = 3 px;$DRAWIO_SCALE 可改預設值), 也可以單獨匯出:python3 $S/scripts/drawio_export.py X.drawio --png --svg。放進 Markdown/Obsidian 優先給 SVG,不模糊。 $S 指本 skill 目錄。examples/ 裡有兩個對照範例:wrr_arbiter.v(單級 + 狀態暫存器)、load_pipe.v(含 replay 的多級管線)。

零、體系結構風格架構圖(arch2drawio.py)——預設

輸入是程式碼(也可以是論文 / 專利 / 使用者描述)。Yosys 網表太細、不適合架構圖,所以此處不綜合:腳本給出原始碼大綱, 由你(agent)讀程式碼、抓核心、寫出圖描述,再由腳本確定性地排版出圖。使用者不需要寫任何描述檔案;只給使用者看圖, 除非使用者想自己改描述。

python3 $S/scripts/arch2drawio.py outline src/*.sv --top gpu [--module core]   # 原始碼大綱(不綜合)
python3 $S/scripts/arch2drawio.py render  fig.yaml -o diagrams/arch_core.drawio --png

outline 列出:層次樹(generate 複製 ×N)、連接埠、儲存陣列(深度 × 位元寬度,packed struct 的欄位,同深度陣列提示「可能同一張表」)、 按級號命名的時序暫存器(s1_ / stage2_ / if_id_ …)、狀態機、疑似反饋信號(replay/kill/flush/stall/forward/refill…)、 實例間資料流(經共享信號,已去掉 clk/reset/迴圈變數)。論文/專利/描述輸入時跳過此步驟。

畫圖規則(寫描述時遵守)

  1. 只畫核心:先用一兩句話說清設計的核心思想,只保留體現它的部件;膠合邏輯、clk/reset、除錯口、零散控制都省略。 一般 8–20 個框;超過就拆成兩張(頂層一張 + 關鍵單元一張)。
  2. 重點突出:1–3 個關鍵設計點 hl: true(反差色:深底白字)或 bold: true(加粗);關鍵路徑的線也可 | hl。 需要強調一塊區域時用 groups + hl: true(淺底色框)。
  3. 不給每個元件編號:只在需要文字對照時給核心元件 num: N,並在 callouts 裡寫說明。
  4. 單元框言簡意賅:框內只寫名字(≤ 2 行),含義靠形狀表達:運算用 adder / mult / cmp / op 圓形符號或 alu, 選擇用 mux(選擇端 x.sel 從底部進),儲存用 table,佇列用 fifo,暫存器用 reg,閘用 and/or/xor/not。
  5. SRAM 表寫出單一項目的欄位:table 的 fields 寫每個欄位的含義(如 [V, Tag (20b), Data (32b)]), 多路組相聯用 stack: 4(疊放 + ×4);同深度、同位址的並行陣列合成一張表,每個陣列一個欄位。
  6. 管線:stages 定義級(id + 功能 sub,如 {id: S1, sub: 命中判斷}),腳本畫虛線分界和級名; 級間暫存器 / FIFO 用 between: [S0, S1],腳本把它畫在分界線上;反饋(目標在更早的級)自動沿底部走廊繞回, 也可 | fb、| fb via=top(從上方繞)。多條管線用 lanes,各 lane 共用級的列,時序上對應的級自動對齊。
  7. 不分級的方塊級圖(頂層、SoC)不寫 stages;複製的單元用 stack: N,每執行緒/每核資源用 groups 框起來。

描述格式(YAML)

title: dcache_pipe:直接映射 D-Cache 尋找管線
stages: [{id: S0, sub: 選擇 / 讀取陣列}, {id: S1, sub: 命中判斷}, {id: S2, sub: 缺失 / 重播}]
lanes:  [{id: ld, name: Load 管線}, {id: st, name: Store 管線}]     # 可選,多條管線時
nodes:
  - {id: arr, type: table, label: "Cache 陣列 · 64 項", fields: [V, "Tag (20b)", "Data (32b)"], stage: S0}
  - {id: r1, type: reg, label: addr, between: [S0, S1]}              # 落在 S0|S1 分界線上
  - {id: tcmp, type: cmp, label: Tag 比較, stage: S1, hl: true}      # 圓形 "=",說明文字在下方
  - {id: rmux, type: mux, stage: S0, ports: 2}
edges:
  - "rmux => arr : idx | w=6"            # -> 資料  => 匯流排(粗)  ~> 控制(虛線);w=N 位元寬
  - "rpl -> rmux.sel : replay | fb hl"   # .sel/.en 從底部進,.top 從頂部進;fb 反饋,hl 強調,via=top,pos=src|dst
groups: [{label: "每執行緒 ×4", members: [rf, alu, lsu], hl: true}]
legend: {reg: 管線暫存器, fb: 反饋, ctrl: 控制, hl: 關鍵設計}      # 可用鍵:data bus ctrl fb hl hl_edge hl_region reg
callouts: {1: "只有在需要對照說明時才編號"}

節點類型:block reg fifo table(fields, rows, stack) array(dims, cell) mux(ports) adder mult cmp/op(sym) alu and or xor nand nor xnor not cloud mem xbar in out text dot。 通用屬性:stage / lane / between,hl bold num stack,微調用 row / col(在級內的行 / 列,可為負)、dx / dy、w / h。 其它:array 支援 cell_labels(逐格標籤,如 T0..T3)和 cell_h(長方格,畫執行緒通道);groups 支援 stack: N (整塊區域疊放,如「Core ×2」並露出內部)和 label_align: right;lanes 的 name 留空 = 只分區不畫標籤; 邊的 | both 畫雙向箭頭(請求/回應);同一列上下兩個單元之間的反饋畫成緊貼的短豎線(如 Dispatcher ⇅ Core)。

流程

  1. outline + 讀取關鍵原始碼(或讀論文/專利),寫下核心思想 → 決定畫哪一層、哪些是重點。
  2. 把描述寫到臨時目錄(scratchpad),每個節點都給 stage(有級時)。迴圈自動斷開:名字像控制器的節點 (sched / ctrl / fsm / arbiter / dispatch / 排程 / 控制 …,其次是控制線扇出多的)先開始,它的輸出往右、回到它的邊畫成反饋; 判斷不對時對那條邊顯式寫 | fb。 可選:構圖參考(gpt-image-bridge,需使用者逐張確認)——網格排版器保證連線正確,但不會「構圖」。模組 ≥ 10 或 有明顯分割槽(控制面/資料面/儲存層次)時,可先出 draw.io 基線,再把從程式碼得出的模組清單和連線寫進提示詞 (論文插圖風格、白底、單一強調色、三區佈局、文字極少、英文短標籤),用 gpt-image-bridge 生成 1 張草圖並 Read 它。 只借鑑佈局與視覺層次(分割槽、誰在誰上方、陣型、留白、重點位置),換算成 lane / row / col / groups; 模組、連線、名稱一律以程式碼為準——草圖常見錯誤:連錯源頭、多畫/少畫模組、深色背景。生成前按該 skill 規定 列出圖片(用途、路徑、尺寸、提示詞摘要)並等使用者明確同意;草圖存 diagrams/sketch_*.png,描述檔頭部註解引用它。
  3. render --png → validate.py(error 必須為 0;分界虛線穿過級頭/暫存器的 overlap 警告是設計如此)→ Read PNG 目視檢查, 用 row / col 微調最多兩輪(常見:讓主資料路徑佔 row 0 走直線,旁路 / 控制放下一行)。
  4. 交付 .drawio + .png;描述檔留在 scratchpad,使用者要自己改時再給。

範例:tiny-gpu 頂層 ~/hardware-project/tiny-gpu/diagrams/arch_gpu.*(由草圖 sketch_gpu_top.png 指導構圖, 對照未用草圖的 arch_gpu_baseline.png);examples/dcache_pipe.v → dcache_pipe.arch.yaml(由程式碼寫出的描述)→ .png;arch_dual_issue.yaml(雙管線對齊 + 轉遞 + 編號註釋)、arch_mac.yaml(電路級:乘 / 加符號、累加反饋、MUX 選擇端)。tiny-gpu core 的方塊級圖見 ~/hardware-project/tiny-gpu/diagrams/arch_core.*。

一、結構框圖(rtl2drawio.py,閘級細節)

python3 $S/scripts/rtl2drawio.py src/*.sv --top gpu --list                     # 模組及單元構成
python3 $S/scripts/rtl2drawio.py src/*.sv --top gpu --module alu -o diagrams/alu.drawio --png

流程:sv2v(遇到 .sv 自動)→ Yosys proc; opt; opt_dff; wreduce; memory -nomap → JSON 網表 → 單元級管線分析 → 簡化 → 列約束佈局。 生成後執行 python3 ~/.claude/skills/drawio-skill/scripts/validate.py X.drawio(error 必須為 0;穿過級分界線/暫存器壓在分界線上 產生的 through-vertex / overlap 警告是設計如此),再 Read PNG 目視檢查。

佈局規則(--layout pipeline;預設 auto:以子模組實例為主的層次模組用自由佈局,其餘用管線級佈局)

  • 輸入在左、輸出在右,邏輯按組合深度從左往右分列;多級管線按 S0 → Sn 從左到右,虛線分界,列頭標級號。
  • 暫存器分兩類:
    • 管線暫存器(窄豎條)放在級分界線上;最後只接輸出埠的一排是輸出暫存器(不算一級、不畫分界線)。
    • 狀態暫存器(FSM / 計數器 / 指標:輸出只經組合邏輯就回到自己輸入)畫在級內,輸出作為反饋。
    • 暫存器名帶級號時(s2_x、x_s2、stage2_x、if_id_/id_ex_/ex_mem_/mem_wb_,且至少兩種)以名字為準—— 帶 kill 的 valid 位即使有組合迴路也仍是管線暫存器。設計不按級命名時只能靠結構推斷,輸入埠的到達時間未知,級號可能偏早。
  • 級號推算:從帶級號暫存器出發,單元的級 = 最晚到達的暫存器運算元(取最大);只由輸入埠驅動的邏輯按「被哪一級暫存器採走」 歸級(ALAP),對應的輸入埠也放到那一級開頭(例如 TLB 回應放在 S1)。
  • 反饋:進入某個帶級號暫存器輸入錐、卻只可能來自更後級的信號(replay→S0、kill→S1),以及狀態暫存器的迴圈,畫成 紅線沿底部外圈繞回,跨度大的在外;同一對級之間反饋多於 3 根時只畫一根粗線代表一捆(標 反饋 ×N:…)。
  • 成捆:同一分界上管線暫存器多於 4 個時合併為一個暫存器組(豎條標 S1→S2 暫存器 ×N 和總位元寬度)。
  • 簡化:同名暫存器切片合併;巢狀 if/case 的 MUX 鏈合成一個 N:1 MUX;只驅動一個 MUX 選擇端 / 暫存器致能的小解碼邏輯 並進去畫成選擇線 / 致能線;3 個以內的閘畫成與/或/非/異或閘符號,更大的摺疊成「組合邏輯」雲(會在夾著運算單元處切開, 避免假迴圈);generate 迴圈展開的同源(同一原始碼位置)單元與 threads[i].x 實例摺疊成 「×N」(帶陰影)。 所有合併都只在同一級內進行。clk/reset 預設隱藏。
  • 連線:實線=資料(粗=多位元匯流排,/N=位元寬度);紫虛線=MUX 選擇;藍點線=致能;紅線=反饋。

參數

參數作用
--list列出模組及單元構成後退出
--module M畫哪個模組(參數化變體畫第一個,會提示)
--layout auto|pipeline|free預設 auto:有子模組實例且組合邏輯節點不多於實例(頂層膠合模組)用 free(塊間雙向通訊不是管線反饋),否則 pipeline
--show-clock畫出 clk/reset
--no-fold不摺疊 generate 實例 / 同源單元
--no-collapse不摺疊控制/組合邏輯
--sv2v auto|always|neverSV 前端(非壓縮陣列埠等語法需要 sv2v)
--keep-json PATH保留 Yosys JSON 網表

二、狀態機圖(fsm2drawio.py fsm)

python3 $S/scripts/fsm2drawio.py list src/*.sv
python3 $S/scripts/fsm2drawio.py fsm  src/*.sv [--module M] -d diagrams --png [--no-actions]
  • 直接解析原始碼,轉移條件保留原始運算式。辨認 case (S) 分支裡給 S(或 S <= N 的次態變數 N)賦值;狀態名取 localparam; 比較別的 FSM 狀態變數的常數翻譯成對方狀態名(core_state == 3'b001 → core_state == FETCH)。
  • 轉移條件 = 直接包住狀態賦值的 if/case/for;else if 只寫自己的條件;for 裡的條件寫成 ∃j: …;外層 for i 包住整個 case 表示按 i 複製;case 外的守衛(enable、讀/寫分支)進註解框;迴圈裡置 1 的區域布林變數在註解框給出定義。
  • 畫法:每個狀態一個等大圓圈(名字在 _ 處換行,下方小字為編碼和 ⟳),終態雙圈,黑點=復位入口。 主流程涵蓋大部分狀態時排成 U 形環(上排左→右、拐下、下排右→左);分支型按離初始狀態的步數均勻分列。 相鄰狀態直連;跳過其他狀態的轉移從上方/下方拱過,標籤在拱頂;A↔B 往返各彎向一側;顯式自環畫在圓上方。 列距按最長標籤自適應。/ 後為轉移時的賦值(最多顯示 2 個)。
  • 不辨認:沒有 case(state) 結構的控制(計數器式、純組合解碼)——list 裡不出現,屬預期。

三、整體控制結構(fsm2drawio.py ctrl)

python3 $S/scripts/fsm2drawio.py ctrl src/*.sv --top gpu --module core -o diagrams/ctrl_core.drawio --png
  • 畫模組 L 裡的子模組實例(generate 實例摺疊 ×N),只保留控制信號:橙粗線=FSM 狀態廣播;藍線=valid/ready 握手; 紫虛線=start/done/致能/選擇/復位等;資料匯流排省略。含 FSM 的實例框列出狀態序列,子層次裡有 FSM 的標「內含 FSM」。
  • 控制信號穿透最多 3 層基本單元(比較器、閘、暫存器)追到源頭。分類靠信號名,命名不規範時可能漏畫/多畫。
  • 建議從上往下:先 top(誰啟動誰、誰和儲存器握手)→ 下一層(主控 FSM 怎麼排程)→ 關鍵 FSM 的狀態機圖。

限制

  • 佈局由 Graphviz 按列約束自動完成,交叉無法完全消除;精修請在 draw.io 裡拖動(全是原生可編輯物件)。
  • 大型控制類模組(上百單元)框圖仍會亂,請按上文改採狀態機圖 / 控制結構圖,或逐個子模組畫。
  • 狀態機圖的圓圈/弧線是依座標直接畫的,拖動狀態時弧線的拐點不會跟著移動,需要順手調整一下。

相關技能