こんにちは!TechTeku Noteへようこそ!本日はAMD(旧Xilinx)のPCIeカード用IPおよびドライバの「XDMA」について、その詳細を説明したいと思います。ここでは、XDMAハードウェアアーキテクチャとエンドtoエンドのデータ通信について詳説します。
第一部: XDMA ハードウェア・アーキテクチャ
1.1 XDMAの核心機能:CPUをバイパスする高性能データ転送
Xilinx XDMA IPの最も基本的な存在意義は、ホストPCのCPUの介在なしに、ホストのシステムメモリとFPGAのロジック(またはオンチップ/オフチップメモリ)との間で直接データを移動させることにあります 。このプロセスはダイレクト・メモリ・アクセス(DMA)として知られています。
従来のプログラムドI/O (PIO) では、CPUがデータを1ワードずつ読み書きする必要がありますが、DMAエンジンはこのプロセスをオフロードします。これにより、CPUはデータコピーという負荷の高いタスクから解放され、より上位のアプリケーション処理にリソースを集中できます 。これは、特にデータセンター・アクセラレーション、高性能コンピューティング(HPC)、リアルタイム・ビデオ処理など、ギガバイト/秒(GB/s)クラスの高いデータ帯域幅を要求するアプリケーションにおいて不可欠です 。
XDMAは、物理的に非連続なホストメモリ領域に散在するデータブロックを、単一のDMA操作で効率的に転送できる、柔軟なScatter-Gather (SG) DMA技術をサポートしています 。
1.2 XDMA IPサブシステムの内部構造(PG195)
XDMA IPの正式名称は「DMA/Bridge Subsystem for PCI Express」です 。この名称が示す通り、このIPは単なるDMAエンジンではなく、複数の機能が統合された「サブシステム」です。
- PCIe Integrated Block: PCIeプロトコルの物理層(PHY)、データリンク層、トランザクション層を処理するハードウェア・ブロック(Hard IP)のラッパーとして機能します 。これにより、FPGAはホストPCに対してPCIeエンドポイント・デバイスとして振る舞うことができます。
- DMA Engines: 複数の独立したDMAチャネルを管理し、実際のデータ転送を実行します。これには、ホストからカード(FPGA)への転送(H2C: Host-to-Card)と、カードからホストへの転送(C2H: Card-to-Host)が含まれます 。UltraScale+デバイスなどでは、最大4チャネルのH2Cと4チャネルのC2Hを構成できます 。
- AXI Bridge: PCIeトランザクション・レイヤー・パケット(TLP)と、FPGA内部の標準バスプロトコルであるAXI(Advanced eXtensible Interface)トランザクションとの間のプロトコル変換およびアドレス変換を行います 。
このIPサブシステムは、Vivado Design Suite内でグラフィカルに設定され、ターゲットとなるデバイス(例:Kintex UltraScale+, Virtex UltraScale+, Zynq UltraScale+)のアーキテクチャに合わせて最適化されます 。
1.3 AXIインターフェースの三位一体:AXI-Lite, AXI-Stream, AXI-MM
ホストPCがFPGAの内部ロジックと通信するために、XDMA IPはFPGA設計者に対して3種類のAXIインターフェースを提供します。これらのインターフェースの選択は、ハードウェア・アーキテクチャ全体を根本的に決定します。
1. AXI4-Lite (AXI-Lite) – 制御とステータス
- 目的: 低帯域幅の制御レジスタおよびステータスレジスタへのアクセスを提供します 。
- 接続: XDMA IPは、ホストからのメモリアクセスをAXI-Liteトランザクションに変換する「AXI4-Lite Master」インターフェースを提供します 。FPGA設計者は、このマスターポートに、自作のカスタムIP(GPIO、タイマー、制御レジスタ群など)のAXI-Liteスレーブポートを接続します。
- 使用例: FPGAロジックのリセット制御、処理パラメータの設定、割り込みステータスの読み取り、デバッグレジスタの監視など、データ転送そのものではない「制御」に関連するすべての操作に使用されます 。
2. AXI4-MemoryMapped (AXI-MM) – ブロックデータとメモリ
- 目的: BRAM、DDR4、HBMなど、FPGAに接続されたメモリマップド・デバイスへの、高帯域幅ブロックデータ転送に使用されます 。
- 接続: XDMA IPは、すべてのDMAチャネルで共有される単一の「AXI4 Master」インターフェース(
M_AXI)を提供します 。 - 特徴: このインターフェースを介した転送は「アドレス」を伴います。ホストは「ホストメモリのこのバッファ」から「FPGAのAXIアドレス空間の
0xC0000000」へデータを転送するよう具体的に指示します 。複数のDMAチャネルが同時に有効な場合、この共有AXIインターフェース上のトランザクションは、シンプルなラウンドロビン方式でインターリーブ(交互配置)されます 。
3. AXI4-Stream (AXI-ST) – ストリーミング・データとパイプライン
- 目的: アドレスの概念を持たない、純粋なデータストリームの高速転送に使用されます。データが到着した順に処理されるパイプライン型のFPGA設計(例:信号処理、ビデオエンコーディング、ネットワーク・パケット処理)に最適です 。
- 接続: XDMA IPは、有効化された各DMAチャネル専用の「AXI4-Stream」インターフェース(H2C用とC2H用)を提供します 。これはAXI-MMの共有モデルとは対照的です。
- 特徴:
tdata(データ)、tvalid(データ有効)、tready(受信準備完了)、tlast(パケット終端) といったハンドシェイク信号群を使用します 。ホストはデータを「ストリーム」として送信するだけで、FPGA側の特定のアドレスを指定しません。
VivadoでXDMA IPを設定する際、DMAインターフェースとしてAXI-MMまたはAXI-STのいずれかを選択する必要があります 。この選択は、単なるインターフェースの好みではなく、設計の初期段階における最も重要なアーキテクチャ上の決定です。
- AXI-MMを選択した場合、設計は「メモリ中心」となります。ホストはFPGAを、計算能力を持つ広大な外部メモリ(BRAMやDDR)として扱います 。データは一度FPGAのメモリに書き込まれ、その後、FPGAロジックがそのメモリにアクセスして処理を行います。
- AXI-STを選択した場合、設計は「フロー中心」または「パイプライン中心」となります。ホストからのデータは、FPGA内のメモリに滞留せず、
m_axis_h2cからFPGAの処理パイプラインに直接流れ込み、処理され、s_axis_c2hからホストに直接流れ出します(ループバック設計が典型例です )。
この選択は、FPGAのロジック設計全体(ステートマシン、バッファ管理)と、ホスト側のソフトウェア・アクセス・パターン(アドレス指定の有無)の両方に根本的な影響を与えます。
第二部:PCIe BARとアドレッシング
2.1 PCIeエンドポイントとしてのXDMA:列挙とコンフィグレーション空間
XDMA IPを搭載したFPGAは、ホストPCのOSの視点からは、グラフィックカードやネットワークカードと同様の、標準的なPCIeエンドポイント・デバイスとして認識されます 。
ホストPCの電源投入時、OS(BIOS/UEFIとカーネル)はPCIeバスをスキャン(列挙プロセス)し、接続されているデバイスを発見します。デバイスは、そのコンフィギュレーション空間に書き込まれたベンダID (VID) とデバイスID (DID) を通じて識別されます(XilinxのVIDは 10EE です)。
OSはデバイスのコンフィギュレーション空間を読み取り、割り込み(Legacy, MSI, またはMSI-X)を設定し 、最も重要なこととして、Base Address Registers (BARs) にホストの物理メモリアドレス空間の一部を割り当てます 。
2.2 Base Address Registers (BARs):FPGAへのゲートウェイ
BARは、FPGA上の内部リソース(レジスタやメモリ)を、ホストPCのCPUから見える物理アドレス空間にマッピングするための「窓」の役割を果たします。
ホストがこの「窓」(BARに割り当てられたホスト・メモリアドレス)に対して読み書きを行うと、ホストのPCIe Root Complexはそれを自動的にPCIeトランザクション・レイヤー・パケット(TLP)に変換し、FPGAに送信します 。
XDMA IPのアーキテクチャの核心は、このBARのルーティング機能にあります。XDMA IPは複数のBARをホストに公開でき、各BARはFPGA内部の異なるAXIインターフェースにルーティングされるよう設定されています 。
- Config BAR (DMA/Bridge Register):
- 目的: XDMA IP 自体の制御レジスタ(DMAエンジンの開始/停止、割り込みマスク、ステータスレジスタ等)をホストに公開します。
- アクセス: このBARは、XDMAカーネルドライバによって内部的に使用されます。ドライバはプローブ(初期化)時に、このBARを自動的に検出しようと試みます 。
- デバッグ:
dmesgで “Failed to detect config BAR” というエラーが出た場合、ドライバがIPの制御レジスタを見つけられなかったことを意味し、深刻な構成不一致を示唆します。
- User BAR (AXI-Lite Slave):
- 目的: 第1部で述べた「AXI4-Lite」インターフェースに接続された、ユーザー定義のカスタムロジックをホストに公開します 。
- アクセス: Xilinxリファレンスドライバは、このBARを
/dev/xdma0_userというキャラクタデバイスとしてユーザー空間に公開します 。 - 使用法: ユーザー・アプリケーションは、このデバイスファイルを
mmap()することで、FPGA上のカスタムレジスタをメモリ上の変数(ポインタ)であるかのように直接読み書きできます 。
- Bypass BAR (AXI-MM Bypass):
- 目的: DMAエンジンをバイパスして、ホストCPUが直接(PIOモードで)FPGA上のAXI-MM空間(BRAMやDDRなど)を読み書きできるようにします 。
- アクセス: リファレンスドライバは、これを
/dev/xdma0_bypass*デバイスとして公開することがあります 。 - 使用法: 主にデバッグ用や、DMAセットアップのオーバーヘッドを避けたい低速・小容量のメモリアクセスに使用されます。
2.3 エンドtoエンドのアドレス変換:mmap()からFPGAレジスタへ
ホストPC上のソフトウェア(Cコード)がFPGA上のハードウェア・レジスタにアクセスするまでの流れは、XDMAを理解する上で最も重要です。以下に、AXI-Lite (User BAR) へのアクセスを例に、その完全なステップを示します。

- 設計時 (Vivado):
- FPGA設計者はXDMA IPをインスタンス化し、「PCIe to AXI Lite Master Interface」を有効にします。これが「User BAR」に割り当てられます 。
- 次に、AXI GPIO IPをインスタンス化し、そのスレーブポート(
S_AXI)をXDMA IPのマスターポート(M_AXI_LITE)に接続します。 - VivadoのAddress Editorで、このAXI GPIOのAXIアドレスを、例えば
0x40010000にマッピングします 。
- 起動時 (Linux):
- ホストOSが起動し、PCIeバスを列挙します。
lspci -vvを実行すると、XDMAデバイスが発見され、その「User BAR」にホスト物理アドレス(例:0xa8000000、サイズ1MB)が割り当てられます 。
- ホストOSが起動し、PCIeバスを列挙します。
- ドライバ・ロード時 (Linux):
sudo modprobe xdmaが実行されます。Xilinxリファレンスドライバは、0xa8000000にマッピングされたBARが「User BAR」であると認識し、/dev/xdma0_userというキャラクタデバイスを作成します 。
- アプリケーション実行時 (Cコード):
int fd = open("/dev/xdma0_user", O_RDWR | O_SYNC);がコールされます 。O_SYNCはキャッシュをバイパスするために重要です。void* map_base = mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0x40010000);がコールされます。mmap()の第6引数(オフセット)に、Vivadoで設定したAXIアドレス0x40010000を指定します。map_baseには、プロセスのアドレス空間内の仮想アドレスが返されます。- Cコードが
*(volatile uint32_t*)((char*)map_base + 0x4) = 0xDEADBEEF;を実行します(GPIOのデータレジスタがオフセット0x4にあると仮定)。volatileは、コンパイラの最適化によるアクセスの省略を防ぐために不可欠です。
- ハードウェア・トランザクション:
- CPUがこの仮想アドレス(
map_base + 0x4)に書き込みます。 - OSのメモリ管理ユニット(MMU)が、この仮想アドレスをホスト物理アドレスに変換します。この物理アドレスは、BARのベースアドレスと
mmapオフセット、ポインタオフセットを合計したもの、すなわち0xa8000000 (BAR_Base) + 0x40010000 (mmap_offset) + 0x4 (ptr_offset) = 0xa8040014となります。 - PCIe Root Complexがこのアドレスへの書き込みを検知し、PCIe Memory Write TLP(トランザクション)を生成します。TLPの宛先アドレスは
0xa8040014です。 - TLPがPCIeバスを経由してFPGAに到達します。
- XDMA IPのPCIeハードブロックがTLPを受信します。
- XDMAの「PCIe to AXI-Lite」ブリッジ が、このアドレスが「User BAR」宛てであると認識します。
- ブリッジは、TLPのアドレス
0xa8040014からBARのベースアドレス0xa8000000を減算し、FPGA内部のAXIアドレス0x40010004を生成します。 - ブリッジは、
M_AXI_LITEバス上で、アドレス0x40010004、データ0xDEADBEEFのAXI-Lite書き込みトランザクションを開始します。 - AXI Interconnectがこのアドレスをデコードし、AXI GPIO IPにトランザクションをルーティングします。
- AXI GPIO IPが、自身のアドレス空間のオフセット
0x4への書き込みとしてデータ0xDEADBEEFを受信し、内部レジスタを更新します。
- CPUがこの仮想アドレス(
この一連の流れが、ホスト上のCコードのポインタ操作が、FPGA上の特定のAXIレジスタ書き込みに変換されるメカニズムの全てです。
参考文献
- DMA/Bridge Subsystem for PCI Express
- PCI Expressの基礎知識, 畑山仁 (dwm012100230.pdf)


コメント