Communityコーディング&開発github.com

BeenLi/claude-skills

Verilog / SystemVerilog(および論文、特許、口頭説明)を編集可能な draw.io 図に変換します。アーキテクチャ図、構造ブロック図、状態遷移図、制御構造図の4つの視点を提供します。

claude-skills とは?

このスキルは、Verilog/SystemVerilog のRTLコード、論文、特許、または口頭の説明を、編集可能な draw.io ダイアグラムに変換するための強力なツールセットです。4つの異なる視点を提供します。1) アーキテクチャ図(arch2drawio.py):コードを解析し、エージェントが設計の核となる部分を抽出して、パイプラインステージ、フィードバック、SRAMテーブルなどを備えた、論文発表用のスタイルで図を生成します。2) 構造ブロック図(rtl2drawio.py):Yosys ネットリストからゲートレベルの詳細なデータパスを生成し、レジスタ、MUX、演算ユニットなどをパイプラインステージごとに配置します。3) 状態遷移図(fsm2drawio.py fsm):case(state) 形式のFSMをパースし、状態を円形で均等に配置した図を生成します。4) 制御構造図(fsm2drawio.py ctrl):制御信号のみに焦点を当て、異なるFSM間の相互作用を表示します。デフォルトではアーキテクチャ図が生成され、ユーザーがゲートレベルの詳細を要求した場合に構造ブロック図が使用されます。タイミング図は drawio-skill が担当します。このスキルは、設計思想の説明、コードレビュー、文書化に特に役立ちます。

対応✓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に質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

Verilog → draw.io:アーキテクチャ図 / 構造ブロック図 / 状態遷移図 / 制御構造図

4つの視点があり、問題に応じて選択します。設計思想は何か(人に説明する、論文/レポートに掲載する)→ arch2drawio.py(第ゼロ節、デフォルト)。 ゲートレベルはどのようなものか(ユニットごとのデータパス)→ rtl2drawio.py。どのように動作するか(単一FSM)→ fsm2drawio.py fsm。 誰が誰を制御するか(全体制御構造)→ fsm2drawio.py ctrl。制御主体のモジュール(FSM、デコード、アービトレーションコントローラ)はブロック図では乱雑になるため、後者の2つを使用します。

依存関係: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 に1行のヒントが出力されるだけです。ブロック図/制御構造図にはさらに yosys、sv2v(SystemVerilog)、dot(Graphviz)、およびインストール済みの drawio-skill が必要です (デフォルトは ~/.claude/skills/drawio-skill、環境変数 DRAWIO_SKILL_DIR で上書き可能;その autolayout.py のみを呼び出し、変更は加えません)。 3つの生成スクリプトはすべて --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 はこのスキルのディレクトリを示します。examples/ には2つの比較サンプルがあります:wrr_arbiter.v(単一ステージ + ステートレジスタ)、load_pipe.v(リプレイ機能付きマルチステージパイプライン)。

零、アーキテクチャ図(arch2drawio.py)——デフォルト

入力はコード(論文、特許、ユーザーの説明でも可)です。Yosys ネットリストは細かすぎてアーキテクチャ図には適さないため、ここでは合成しません。スクリプトはソースコードの概要を提供し、 あなた(エージェント)がコードを読み、核となる部分を抽出し、図の説明を記述し、スクリプトが決定論的にレイアウトして図を生成します。ユーザーは説明ファイルを記述する必要はなく、図を見るだけで済みます。 ただし、ユーザーが自分で説明を変更したい場合は除きます。

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. 核となる部分のみを描く:まず1~2文で設計の核となる考え方を説明し、それを体現するコンポーネントのみを残します。グルーロジック、clk/reset、デバッグポート、散在する制御はすべて省略します。 通常は8~20個のボックスに収めます。それを超える場合は2枚に分割します(トップレベル1枚 + キーユニット1枚)。
  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)を使用します。同じ深さ、同じアドレスを持つ並列配列は1つのテーブルにまとめ、各配列を1つのフィールドとします。
  6. パイプライン:stages でステージを定義します(id + 機能 sub、例:{id: S1, sub: 命中判定})。スクリプトは点線の境界とステージ名を描画します。 ステージ間のレジスタ/FIFO は between: [S0, S1] を使用し、スクリプトはそれを境界線上に描画します。フィードバック(より前のステージがターゲット)は自動的に下部の廊下に沿って回り込みます。 | fb、| fb via=top(上部から回り込み)も指定できます。複数のパイプラインがある場合は lanes を使用し、各レーンはステージの列を共有し、時間的に対応するステージは自動的に整列します。
  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: ロードパイプライン}, {id: st, name: ストアパイプライン}]     # オプション、複数パイプライン時
nodes:
  - {id: arr, type: table, label: "キャッシュアレイ · 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、ユーザーが1枚ずつ確認する必要あり)——グリッドレイアウターは配線の正確性を保証しますが、「構図」は行いません。モジュール数が10以上、または 明確な区分(制御プレーン/データプレーン/メモリ階層)がある場合は、まず draw.io のベースラインを生成し、その後コードから得られたモジュールリストと接続をプロンプトに記述し (論文イラスト風、白背景、単一の強調色、3つの領域レイアウト、最小限のテキスト、英語の短いラベル)、gpt-image-bridge を使用して1枚のスケッチを生成し、Read します。 レイアウトと視覚的な階層のみを参考にします(区分、誰が誰の上にいるか、陣形、余白、重要な位置)。それらを lane / row / col / groups に変換します。 モジュール、配線、名前はすべてコードを基準とします——スケッチの一般的な誤り:接続元の間違い、モジュールの過不足、暗い背景。生成前に、このスキルの規定に従って 画像(用途、パス、サイズ、プロンプトの要約)をリストアップし、ユーザーの明示的な同意を待ちます。スケッチは diagrams/sketch_*.png に保存され、記述ファイルのヘッダーコメントでそれを参照します。
  3. render --png → validate.py(エラーは0でなければなりません。境界点線がステージヘッダー/レジスタを通過するオーバーラップ警告は設計上のものです)→ Read PNG で目視確認し、 row / col で最大2回の微調整を行います(一般的な調整:メインデータパスを 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 を実行します(エラーは0でなければなりません。ステージ境界線を通過する/レジスタが境界線上に重なることによる through-vertex / overlap 警告は設計上のものです)。その後、Read PNG で目視確認します。

レイアウトルール(--layout pipeline;デフォルト auto:サブモジュールインスタンスが主体の階層モジュールは自由レイアウト、それ以外はパイプラインレイアウト)

  • 入力は左、出力は右、論理は組み合わせの深さに従って左から右へ列分割。マルチステージパイプラインは S0 → Sn を左から右へ、点線で境界、列ヘッダーにステージ番号。
  • レジスタは2種類に分類:
    • パイプラインレジスタ(細い縦棒)はステージ境界線上に配置。最後に出力ポートのみに接続する列は出力レジスタ(ステージとしてカウントせず、境界線を描画しない)。
    • ステートレジスタ(FSM / カウンタ / ポインタ:出力が組み合わせロジックのみを介して自身の入力に戻る)はステージ内に描画し、出力はフィードバックとして扱う。
    • レジスタ名にステージ番号が含まれる場合(s2_x、x_s2、stage2_x、if_id_/id_ex_/ex_mem_/mem_wb_、かつ少なくとも2種類存在)名前を優先—— kill を持つ valid ビットは、たとえ組み合わせループがあってもパイプラインレジスタとして扱う。設計がステージ番号で命名されていない場合は構造からの推論に頼るしかなく、入力ポートの到達時間は不明なため、ステージ番号が早すぎる可能性がある。
  • ステージ番号の推論:ステージ番号を持つレジスタから開始し、ユニットのステージ = 最も遅く到達するレジスタオペランド(最大値を取る)。入力ポートのみで駆動されるロジックは、「どのステージのレジスタに取り込まれるか」でステージを割り当てる(ALAP)。対応する入力ポートもそのステージの先頭に配置する(例:TLB 応答は S1 に配置)。
  • フィードバック:特定のステージ番号を持つレジスタの入力コーンに入るが、より後のステージからのみ可能性がある信号(replay→S0、kill→S1)、およびステートレジスタのループバックは、 赤線で下部の外側の廊下に沿って回り込ませ、スパンが大きいものは外側に配置。同じステージペア間のフィードバックが3本を超える場合は、1本の太線で束を表現(ラベルに フィードバック ×N:… を記述)。
  • 束ねる:同じ境界上のパイプラインレジスタが4個を超える場合は、1つのレジスタグループにまとめる(縦棒、ラベルは S1→S2 レジスタ ×N と総ビット幅)。
  • 簡略化:同名のレジスタスライスをマージ。ネストされた if/case の MUX チェーンは1つの N:1 MUX に統合。1つの MUX 選択端/レジスタイネーブルのみを駆動する小さなデコードロジックは、それに統合して選択線/イネーブル線として描画。3個以内のゲートはAND/OR/NOT/XOR ゲート記号で描画し、それより大きいものは「組み合わせロジック」クラウドに折りたたむ(演算ユニットを挟む場所で分割し、誤ったループを回避)。generate ループで展開された同一ソース(同一ソースコード位置)のユニットと threads[i].x インスタンスは**「×N」に折りたたむ(影付き)。 すべてのマージは同一ステージ内**でのみ行う。clk/reset はデフォルトで非表示。
  • 配線:実線=データ(太=マルチビットバス、/N=ビット幅)。紫点線=MUX 選択。青点線=イネーブル。赤線=フィードバック。

パラメータ

パラメータ説明
--listモジュールとユニット構成をリストして終了
--module Mどのモジュールを描画するか(パラメータ化されたバリアントは最初のものを描画し、その旨を表示)
--layout auto|pipeline|freeデフォルト auto:サブモジュールインスタンスが存在し、組み合わせロジックノードがインスタンスより多くない(トップレベルのグルーモジュール)場合は free(ブロック間の双方向通信はパイプラインフィードバックではない)、それ以外は pipeline
--show-clockclk/reset を描画
--no-foldgenerate インスタンス/同一ソースユニットを折りたたまない
--no-collapse制御/組み合わせロジックを折りたたまない
--sv2v auto|always|neverSV フロントエンド(非圧縮配列ポートなどの構文には sv2v が必要)
--keep-json PATHYosys 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層の基本ユニット(比較器、ゲート、レジスタ)を透過してソースまで追跡。分類は信号名に依存するため、命名規則が不適切な場合は描画漏れ/過剰描画の可能性がある。
  • 推奨手順:上から下へ。まずトップレベル(誰が誰を起動するか、誰がメモリとハンドシェイクするか)→ 次の階層(メイン制御 FSM がどのようにスケジュールするか)→ キー FSM の状態遷移図。

制限

  • レイアウトは Graphviz が列制約に基づいて自動的に行うため、交差を完全に排除することはできません。微調整は draw.io 内でドラッグして行います(すべてがネイティブ編集可能オブジェクトです)。
  • 大規模な制御系モジュール(数百ユニット)のブロック図は依然として乱雑になる可能性があるため、前述のように状態遷移図/制御構造図を使用するか、サブモジュールごとに描画します。
  • 状態遷移図の円や弧は座標に基づいて直接描画されるため、状態をドラッグしても弧の折れ点は追従しません。その場合は手動で調整する必要があります。

関連スキル