0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[個人開発] FPGAのJTAGバウンダリスキャン+内部観測のためのOSSツール「OWLTAP」の開発

0
Posted at

はじめに

Zynq評価ボード上のFTDI USB-JTAGインターフェースを使って、FPGA/SoCのピン状態を連続取得し、波形として表示するデスクトップツール「OWLTAP」(Open-source Waveform Logger for TAP)を作りました。

テスターやオシロスコープを使わずに、FPGAの実機デバッグを手軽に行えます。

さらにMCP(Model Context Protocol)に対応しています。MCPとは、AIアシスタントが外部ツールをAPIとして呼び出せる仕組みです。Claude DesktopなどのAIクライアントからFPGAへの書き込み・バウンダリスキャン・専用のILA IP制御を直接行えます。

動作環境: Windows 10/11(64-bit)、FTDI MPSSEアダプタ(FT2232H / FT4232H)が必要です。現時点での実機検証はZybo Z7020で行っています。他デバイスでの動作確認はまだできていません。

開発について: 本ツールの実装および本記事の執筆にはAIアシスタント(GitHub Copilot)を活用しています。

OWLTAPでできること

機能 概要
JTAGチェーン検出 IDCODEとIR長を自動読み取り
BSDLパーサ ベンダBSDLファイルを読み込み、ピン名とBSRビット位置をマッピング
バウンダリスキャン (EXTEST) 出力ピンをHIGH/LOW/Hi-Zに駆動、入力ピン値を読み取り
安全ガード Zynq PS_DDR / PS_MIO / PS_POR_B / PS_SRST_B ピン検出時はEXTESTをブロック
波形キャプチャ トリガ付き・フリーラン・シングル、バッファ深度可変
トリガエンジン 立ち上がり/立ち下がり/両エッジ/レベル、プレトリガ比率設定
内蔵ILA IP SystemVerilog製ロジックアナライザIP(専用TAP / Xilinx BSCANE2対応)
JTAGデーモン ハードウェア操作をバックグラウンドプロセスに分離、JSON-RPC TCP経由で制御
選択ピン最適化 選択ピンのみBSRをシフトアウト(1077bit→例: 341bit)でサンプルレート改善
PLビットストリーム書き込み .bit/.binをJTAG経由でZynq PLに直接書き込み(電源断で消える揮発書き込み)
SPI フラッシュ書き込み BSCAN SPIブリッジ経由でSPI Config ROM(MT25QL128)に書き込み、電源断後も保持(ユニットテスト済み・実機未検証
MCP対応 AI(Claude等)からJTAGデバッグツールを呼び出せる
VCDエクスポート GTKWave / Vivado で読めるVCDファイルを出力
スクリプトエンジン set/expect/apply/highz の自動化スクリプト

アーキテクチャ

OWLTAPは次の6層スタック構成になっています。

GUIとハードウェアはJTAGデーモンプロセスで分離されており、GUIはJSON-RPC over TCPでデーモンと通信します。これにより、MCPクライアント(AI)や外部スクリプトからも同じハードウェア操作を利用できます。

メインGUIは以下のような画面です。

image.png

バウンダリスキャン波形キャプチャ

JTAG BSDLを読み込み、信号パネルでピンを選択→RUNすることで波形キャプチャが始まります。
サンプル数の設定を行うこともできます。

jtagWave.png

サンプルレートの現実

Zynq XA7Z020のBSRは1077ビットあります。これをJTAGでシフトし続けるため、理論値と実測値にはギャップがあります。

要因 影響
JTAGクロック6MHz + IR/DRオーバーヘッド 理論最大 ~5.5 kHz
USB バルク転送レイテンシ(250〜500μs) 実測 ~1〜2 kHz に低下

選択ピン最適化を使うと、BSR中の最後の選択ピン位置までのシフトで済みます。例えばBSRの前方寄りにある2ピンを選択した場合は1077ビットから341ビットへ削減でき(約1/3)、サンプルレートが比例して改善します。

内蔵ILA(ロジックアナライザIP)

高速信号を観測したい場合は、PLに同梱のILA IPをFPGAデザインに組み込みます。サンプルクロックをFPGAのシステムクロック(例: 125MHz)に接続することで、バウンダリスキャンの数万倍のサンプルレートで信号を取得できます。
ILA.png

DATA_W(デフォルト32bit)とDEPTH(デフォルト1024サンプル)はパラメータで変更可能です。

2種類の接続バリアント

ILA IPにはJTAGへの接続方法が異なる2種類のトップレベルモジュールが用意されています。
ila_topは未検証です。
BSCANE2は実機で確認しています。

バリアント モジュール名 概要
専用TAP ila_top 独立したIEEE 1149.1 TAPをJTAGチェーンに追加(IR = 5bit)。Xilinx以外のFPGAにも対応
BSCANE2 ila_bscane2_top Xilinx BSCANE2 USER1 プリミティブ経由でFPGA既存のJTAG TAPを共用。追加ピン不要

専用TAPバリアント(ila_top

ILA用の独立したTAPをJTAGチェーンに数珠つなぎします。

FTDIケーブル
  TCK ──┬──► FPGA.TCK
  TMS ──┼──► FPGA.TMS
  TDI ──► FPGA.TDI
        FPGA.TDO ──► ila_top.tdi
                     ila_top.tdo ──► ケーブルTDO

OWLTAPのJtagChain::detectDevicesがIDCODE(32'hA17A_0001)で自動認識します。IDCODEはIDCODE_VALパラメータで変更可能です。

BSCANE2バリアント(ila_bscane2_top)— Xilinx 7-Series / Zynq 推奨

XilinxのBSCANE2 USER1プリミティブを使うことで、FPGAの既存JTAGポートをそのまま流用できます。Zybo Z7のオンボードUSB-JTAGからも追加配線なしでアクセス可能です。

FTDIケーブル(またはZybo Z7 オンボードUSB-JTAG)
  TCK/TMS/TDI/TDO ──► FPGA の JTAG TAP
                           │
                         BSCANE2 USER1(Xilinxプリミティブ)
                           │
                         ila_bscane2_top(FPGA内部)

専用TAPのようなIRスキャンではなく、37bitのDRフレームをUSER1スキャンチェーンに多重化するプロトコルを使います。

bits[4:0]   = サブオペコード(ila_top のIRオペコードと同じ値)
bits[36:5]  = 32bitデータペイロード

読み出し操作はスキャン2回:1回目のUpdateでオペコードをセット、2回目のCaptureでデータを取り出します。

トリガ構成

  • グループA: レベル比較(マスク/値) + エッジ(立上/立下マスク)
  • グループB: 独立レベル比較
  • TRIG_CTRL.or_mode: グループA OR グループBでトリガ

ILAジェネレータウィザード

Tools → Generate ILA Core... でレーン定義からBSCANE2 ILAパッケージをワンクリック生成できます。

生成物 内容
ラッパーRTL ila_bscane2_topをインスタンス化するSystemVerilogトップ
Vivado Tclスクリプト create_project.tcl / build_bitstream.tcl
制約ファイル ila_generated.xdc(サンプルクロック制約付き)
パッケージREADME パラメータ・レーンマップ・使用法のサマリ

接続とデバイス選択

FTDIアダプタをターゲットボードのJTAGヘッダに接続し、接続ダイアログでデバイスを選択します。

FTDIアダプタは MPSSE対応チップ(FT2232H / FT4232H) が必要です。安価なFT232RLはMPSSEを持たないため動作しません。検証済み構成はFT4232H(VID=0x0403 PID=0x6011)です。

FTDIconnection.png

MCP対応:AIからJTAGデバッグ

jtag_daemonはMCPサーバとしても動作します。Claude DesktopなどのMCP対応AIから以下のツールを呼び出せます。

detect_devices    → JTAGチェーン上のデバイスを列挙
read_idcode       → IDCODEを直接読み取り
list_devices      → ロード済みデバイス情報を一覧
load_bsdl         → BSDLファイルをロード
list_pins         → 観測/駆動可能ピン一覧
read_pin          → 1ピンの現在値を読み取り
set_pin           → ピンをHIGH/LOW/Hi-Zに設定
capture_start     → キャプチャ開始
capture_stop      → キャプチャ停止
get_samples       → サンプルデータ取得
program_bitstream → PLへビットストリーム書き込み
ila_run_capture   → ILAキャプチャをトリガ・取得
read_ila_status   → ILAのステータス取得
run_script        → スクリプト実行
job_poll          → 非同期ジョブの完了待ち
job_cancel        → 非同期ジョブのキャンセル
...(全16ツール)

「このピンが今HIGHかLOWか確認して」をAIに頼むと、AIがMCP経由でJTAGをたたいて答えを返してくる、という使い方ができます。

スクリプトエンジン

シンプルなテキストスクリプトで自動化が可能です。

# LEDをHIGHに駆動して確認
set LED0 1
apply
expect LED0 1

# Hi-Zに戻す
highz LED0
apply

.suiteファイルで複数スクリプトをまとめて実行、.ictファイルで基板インターコネクトテストも対応しています。

PLビットストリーム書き込み

Tools → Program Bitstream.bit / .bin ファイルをJTAG経由でZynq PLに直接書き込めます。電源断で消える揮発書き込みのため、反復デバッグに便利です。MCP経由(program_bitstream)でAIから呼び出すことも可能です。

SPI フラッシュ書き込み

注意: この機能はユニットテスト済みですが、実機での動作確認はまだ行っていません

BSCAN SPIブリッジ経由でSPI Config ROM(MT25QL128)に書き込みます。PLビットストリーム書き込みとは異なり、電源断後も設定が保持されます。

ビルド方法

対応環境: Windows 10/11 (64-bit)、OpenGL 3.3 core profile 対応GPU が必要です。Linux/macOSは現時点で未対応です。

必要なもの

ツール 備考
Bazelisk bazelisk.exeとしてPATHに配置
Visual Studio 2022 C++デスクトップ開発ワークロード
Python 3.x Bazelホストスクリプト用

libftdi1とlibusb-1.0はリポジトリに同梱済みで別途インストール不要です。

Windows USBドライバ

ZadigでFTDIアダプタのJTAGインターフェース(通常FT4232HのInterface 0)にWinUSBまたはlibusbKを割り当てます。

ビルドコマンド

git clone https://github.com/MameMame777/OWLTAP.git
cd OWLTAP

# ビルド
bazelisk build //src:owltap

# 全ユニットテスト実行(ハードウェア不要)
bazelisk test //test/...

BSDLファイルについて: ターゲットデバイスのBSDLファイルはリポジトリに含まれていません。デバイスベンダ(Xilinx/AMDの場合はダウンロードセンター)から入手し、GUIの「Device → Load BSDL」で読み込んでください。


使い方(クイックスタート)

  1. FTDIアダプタとターゲットボードのJTAGヘッダを接続する
  2. owltap.exe を起動する
  3. Device → Connect: VID/PID/チャンネルを選択して接続
  4. Device → Load BSDL: ターゲットの .bsd / .bsdl ファイルを読み込む
  5. Signal Panel: 監視したいピンを選択する
  6. Capture → Start: 波形取得を開始する
  7. File → Export VCD: 取得した波形をVCDファイルに保存する(GTKWave / Vivadoで開ける)

テスト戦略

テスト層 実行タイミング ハードウェア要否
bazelisk test //test/...(22テスト) 毎コミット 不要
Pythonハードウェアインザループ(HIL)テスト リリース前・ハードウェア変更後 必要(FTDIアダプタ+ターゲット基板)

ユニットテストはスタブハードウェアで動作し10秒以内に完走します。HILテストは実際のZynqシリコンに対してJTAGスキャンを実行し、モックでは検出できない統合レグレッションを捕捉します。

HILテスト結果(2026-04-27、XA7Z020-CLG484)

Result: 10/10 tests passed

detect_devices  → 2 device(s): IDCODE=0x23727093, IDCODE=0x4BA00477
load_bsdl       → entity='XA7Z020_CLG484'
list_pins       → 333 observable, 327 drivable
read_pin        → RSVDVCC3_T10 = high
capture (single)→ 1 samples, 333 pins per sample
program_bitstream→ state=complete  ok=True
read_ila_status → version=3  depth=1024  data_width=32  sig_count=2

sig_count はILA IPに接続された監視信号グループ数)


セキュリティ

jtag_daemonはローカル専用の開発ツールです。

  • MCP / GUI-RPC ポートは127.0.0.1のみにバインドし、ネットワークインターフェースには露出しません
  • 認証機能はありません(ループバック限定のため設計上許容)
  • 共有マシンや不特定多数がアクセスできる環境での使用は避けてください

ライセンス

対象 ライセンス
C++ソースコード(GUIアプリ・デーモン) MIT
ILA IP RTL / テストベンチ(hdl/ila/ Apache-2.0
サードパーティライブラリ 各ライブラリのライセンス(THIRD_PARTY_NOTICES.md 参照)

ILA IPにApache-2.0を選んだのは、再利用可能なハードウェアIPとして特許許諾条項(Patent Grant)を明示するためです。MITには特許に関する明示的な条項がありませんが、Apache-2.0はコントリビュータの保有特許についてロイヤルティフリーのライセンスを明示的に付与するため、IPコアを自社製品に組み込む際の法的明確性が高くなります。


まとめ

OWLTAPはFPGA/SoCのJTAGバウンダリスキャンをオシロスコープのように使えるOSSツールです。
MCP連携によってAIが実際のHWデバッグを行うことも可能です。

  • ImGui/ImPlotベースのGUI(Windows 10/11対応)
  • FTDIアダプタ1本で接続でき、特殊なプローブ不要
  • MCP対応でAIアシスタントからのJTAGデバッグが可能
  • 内蔵ILA IPで高速信号キャプチャも対応
  • 22ユニットテスト + HILテストで品質担保

BSDLファイルさえあれば大抵のIEEE 1149.1準拠FPGAで動作します。

興味があればぜひ試してみてください!
バグや改善案があればコメントやIssueにてお願いします。


参考リンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?