FPGAでPCIeを実装する基礎

FPGAでPCIeを実装する基礎

FPGAでPCIeを扱うには、プロトコル知識だけでなく、FPGAのトランシーバー要件、ボード配線、OS側の列挙(Enumeration)まで一連を押さえる必要があります。

本記事では、PCIeの基本用語から実装方式(IP/DMA)、基板設計・コンフィグ時間の要件、ソフトウェア実装、性能設計、デバッグと典型トラブルまでを、実務で詰まりやすいポイント中心に整理します。

特に実務では、論理が正しくてもリンクが上がらない、PCに認識されない、想定の速度が出ないといった問題が起きがちです。どの層で詰まっているかを見分ける観点もあわせて解説します。

FPGA×PCIeでできることと代表的な用途

FPGAにPCIeを載せると、PC/SoCと高速・低遅延にデータをやり取りでき、計測・加速・ストレージなど幅広い用途に展開できます。

PCIeはPCやサーバーの標準的な拡張インターフェースなので、FPGAをPCIe Endpointとして実装できると、CPUメモリやストレージに近い位置でデータを扱えます。Ethernetなどに比べてレイテンシを詰めやすく、OSからはデバイスとして見えるため統合もしやすいのが特徴です。

代表例は、DAQ(高速計測)や画像・動画のストリーミング取り込み、推論・暗号・圧縮などのアクセラレーター、ネットワーク機能のオフロード、NVMe準拠のストレージコントローラやカスタムストレージ制御、低遅延トレーディングやHFT向けのパケット処理などです。要点は「必要な場所に必要な帯域でデータを運ぶ」ことで、PCIeはそのための汎用バスになります。

一方でPCIeは、論理設計だけでは完成しません。トランシーバーやクロック、基板配線、リセット、FPGAのコンフィグ時間、OS列挙、ドライバーまでがつながって初めて動くため、用途に応じてどこに工数がかかるかを最初に見積もることが成功の鍵です。

PCIeの基本用語と構成要素(レーン・Gen・Link Training)

実装・選定・デバッグを円滑にするために、帯域を決めるレーン数や世代(Gen)、リンク確立の仕組み(Link Training)を押さえます。

レーンは差動ペアの送受信を1組とする単位で、x1/x4/x8/x16のように表します。理論的な帯域は「Gen(世代)×レーン数」で概ね決まりますが、世代によってエンコーディング方式が異なるため、単純に倍数関係にはなりません。Gen1/Gen2では8b/10bエンコーディング(有効帯域率80%)、Gen3以降では128b/130bエンコーディング(有効帯域率約98.5%)が採用されており、同じ2倍のシグナルレート向上でも実効帯域の伸びが異なります。以下に各世代のx1あたりの片方向理論帯域を示します。

ただし、Gen1/Gen2は8b/10bエンコーディング(有効帯域約80%)、Gen3以降は128b/130bエンコーディング(有効帯域約98.5%)を採用しているため、世代が上がっても単純な倍数にはなりません。たとえばx8構成の片方向理論帯域は、Gen1で約2GB/s、Gen2で約4GB/s、Gen3で約7.88GB/sとなります。

たとえばx8構成であれば上記の8倍が理論帯域となり、Gen3 x8で約7.88 GB/sです。ただし実効帯域はTLPヘッダーやDLLPのオーバーヘッド、フロー制御、DMAのバースト設計、ホスト側の制約などにより、理論値を下回るのが一般的です。まずは必要帯域からレーン数とGenを逆算し、余裕を持たせて設計します。

Genは物理層の転送速度で、Gen1/2/3/4/5…と上がるほど要求される信号品質も厳しくなります。たとえばGen3以降は受信側イコライゼーションやチャネル特性への依存が増え、基板設計や部品選定の難易度が上がります。さらにGen4/Gen5では、ボード上にリタイマーの挿入が必要になるケースや、イコライゼーションフェーズの追加、信号ロス要件の厳格化など、Gen3とは質的に異なる設計課題が加わります。本記事では主にGen3までの実装を中心に解説しますが、Gen4/Gen5対応FPGAはAltera Agilex 7/5やAMD Versal Premiumなどで既に実製品として提供されており、高帯域が求められる用途では選択肢に入ります。「とりあえずGenを上げる」ではなく、目標性能と開発リスクのバランスを取るのが実務的です。

Link Trainingは、電源投入後にリンクが確立するまでの自動交渉の仕組みで、内部状態機械LTSSMが段階的に遷移して速度やレーン数、等化などを決めます。リンクが上がらない時は、アプリ層を疑う前にLTSSMがどこで止まっているかを見ます。ここを観測できるかどうかが、デバッグの速度を大きく左右します。

なお、Gen4/Gen5対応FPGAも実製品として存在しますが(Intel Agilex、AMD Versal Premium等)、Gen5ではリタイマーの必要性や新しいイコライゼーションフェーズなど、Gen3とは質的に異なる設計課題が加わります。本記事ではGen3までを中心に解説します。

FPGAでPCIeを使うための選択肢(ハードIP・ソフトIP・DMA)

FPGAの世代や要件に応じて、ベンダのハードIP/ソフトIPやDMAサブシステムを選び、開発コストと性能のバランスを取ります。

多くのFPGAではPCIeコアがIPとして提供され、物理層やデータリンク層の大部分をブラックボックス的に利用できます。ハードIPは性能と安定性が高く、ベンダが想定する範囲の使い方なら最短で動きます。一方で制約も多く、クロック構成やリセット、配置配線など「推奨に従う」設計が必要です。

ソフトIPは柔軟性がある反面、タイミング収束やリソース、性能面で難易度が上がりがちです。PCIeは規格の守る範囲が広く、全てを自前で実装するのは検証コストが大きいので、通常はベンダIPを使い、差別化はDMAやアプリ層で行うのが現実的です。 DMAはスループットとCPU負荷を決める中心要素です。単にPCIeコアが動いても、DMAが小さな転送を刻んだり、割り込みが多すぎたり、ホスト側のバッファ管理が悪いと速度が出ません。最初から「必要な転送パターン(連続ストリームか、ランダムか、双方向か)」を定義し、それに合うDMA方式(SGDMA、リングバッファ、ホストメモリ直書きなど)を選びます。

必要なFPGA要件(GT/SerDes・リファレンスクロック・対応Gen)

PCIe対応可否は、内蔵高速トランシーバー(GT/SerDes)、基準クロックの受け方、サポートするPCIe世代・レーン数に強く依存します。

PCIeは高速シリアル通信なので、FPGA側にGT/SerDes(高速トランシーバー)が必要です。FPGAの製品グレードによって到達できる速度やサポートするプロトコルが異なり、同じファミリーでも「PCIe x8 Gen3はこのグレードまで」といった制限があります。デバイス選定の最初に、必要なGen/レーン数と対応表を突き合わせるのが鉄則です。

リファレンスクロックはリンクの根幹です。一般に100MHzのPCIeリファレンスクロックをボードからFPGAへ供給し、ジッタ要件や配線、クロッキングアーキテクチャ(Common Refclk、SRNS、SRISなど)に注意します。FPGA×PCIeで最も一般的なのはCommon Refclk(ホストとエンドポイントが同一クロック源を共有)構成ですが、マルチボード構成などではSRNS(独立クロック・SSCなし)やSRIS(独立クロック・独立SSC)も検討対象になります。クロックが規格から外れると、リンクアップしてもエラーが増えてGenが下がる、といった「一見動いているが性能が出ない」状態になりやすいです。

また、PCIe IPはクロックドメインやリセットの要求が厳密です。ユーザーロジック側も、AXI-Stream/AXI-MMなどのインターフェース仕様を正確に守り、CDC(クロックドメインクロッシング)を適切に設計します。物理層が不安定な時に上位ロジックを疑うのは遠回りなので、まず要件を満たす基盤があるかを確認します。

ボード設計の要点(配線長・インピーダンス・リセット)

PCIeはボード品質がリンク安定性を左右するため、差動配線・インピーダンス管理・リセット/電源シーケンスを要点として整理します。

配線の基本は差動インピーダンス管理とペア内スキューの抑制です。PCIeは受信側の等化である程度吸収できますが、限界を超えるとリンクが上がらない、Genが上がらない、CRCエラーが増えるなど症状が出ます。レーン間スキューやビアの使い方、リターンパスの確保など、基板ルールを先に固めてから部品配置を行うのが安全です。

リセット(PERST#)と電源シーケンスは「認識しない」問題の定番原因です。FPGAがまだ安定していないのにホストが列挙を始めると、Configuration Spaceの応答ができず未認識になります。リセットは単に遅らせればよいわけではなく、FPGA側が確実に受けてPCIeコアが初期化されるタイミングと、クロック安定、電源の立ち上がりを合わせる設計が必要です。 実装ではコネクタ近傍の保護素子やAC結合コンデンサーの配置も重要です。素子選定や配置を誤ると、信号品質の劣化が再現性の低い不具合として出ます。ソフトで誤魔化しにくい領域なので、基板レビューの段階で「規格が要求する物理層」を満たしているかをチェックリスト化して潰します。

コンフィグ完了時間の要件(Configuration Time)

PC起動時にPCIeデバイスとして見えるかどうかは、FPGAのコンフィギュレーション完了タイミングが影響するため、要件と運用対策を確認します。

FPGAは揮発性デバイスが多く、電源投入後にビットストリームをロードして初めてPCIe回路が動きます。ここで重要なのが「ホストがPCIeの列挙を始める時刻」と「FPGAがPCIe Endpointとして応答可能になる時刻」の関係です。FPGAが間に合わないと、ホストからは存在しないデバイスとして扱われます。

開発段階ではJTAGから書き込んだり、OS起動後に再スキャンしたりして動かせますが、量産運用で毎回それをやるのは現実的ではありません。最終形ではSPIフラッシュなどの不揮発メモリ起動で自動コンフィグし、電源ONで自然に認識される形に寄せていくのが一般的です。

この問題は「PCIeの難しさ」というより「システム起動順序の設計」です。どのタイミングまでに何が成立しているべきか(電源、クロック、コンフィグ、リセット解除、リンクトレーニング開始)を、ボードとFPGAとホストの三者で整合させることが核心になります。

PCIeを扱うFPGAは何秒でコンフィグすべきか

厳密な秒数はホスト(BIOS/UEFI、マザーボード、設定)で変わりますが、考え方はシンプルで「ホストがEnumerationを開始する前に、FPGAがPERST#解除後にConfiguration Spaceへ応答できる状態になっていること」が目標です。PCIeはリンクトレーニング以前に、まず物理的に存在して応答できることが求められます。

実務では、PC電源投入から比較的早い段階で列挙が走るため、コンフィグが数秒単位で遅いと不利になります。特に大規模FPGAでビットストリームが大きい場合、SPIフラッシュのクロックやモード設定、圧縮の有無でコンフィグ時間が大きく変わります。最初に概算し、必要ならx1でデバッグしてから最終的にx8へ、といった段階設計も有効です。

手段別の目安としては、JTAG書き込みは開発には便利ですが起動時自動認識には直結しません。外部ローダー(マイコンなど)でのロードは制御しやすい反面、システムの起動順序を設計し直す必要が出ます。量産で自然に認識させたいなら、SPIフラッシュなど不揮発メモリからの自動起動を前提にし、設定速度(QSPI化、クロック上限、圧縮、マルチブート設計)を詰めるのが王道です。

コンフィグが遅い場合に起きる問題と対策

症状として多いのは、PC起動時にデバイスが未認識のままになり、再起動しないと現れない、あるいはOS側で再スキャンしないと現れない、というパターンです。これはホストが列挙を一度通過してしまい、その時点で応答しないデバイスを「存在しない」と判断するために起きます。

開発時の回避策としては、OS起動後にFPGAをコンフィグし、デバイスマネージャ等の「ハードウェア変更のスキャン」で再列挙させる方法が実用的です。再起動より速く、試行錯誤の回転を上げられます。ただし、この手順が必要な状態は、最終製品としてはユーザー体験が悪いので、あくまで開発用と割り切ります。

量産運用の対策は、起動方式の見直しとタイミング制御です。不揮発メモリ起動で確実に自動コンフィグする、コンフィグ速度を最適化する、そしてPERST#や電源シーケンスを制御して「FPGAが応答できるまでホストに列挙させない」設計にします。根本は、コンフィグ完了とリンクトレーニング開始の順序を保証することです。

FPGA/基板設計受託開発

FPGA/SoC開発を軸に、回路設計からファームウェア開発、試作・量産まで対応

Enumerationまでの流れと確認ポイント

コンフィグ完了後、LTSSM遷移〜リンクアップ〜Configuration Space読出しまでの流れを追い、どこで詰まっているかを切り分けます。

流れを分解すると、(1) 電源とクロックが安定、(2) PERST#解除、(3) LTSSMがDetect/Polling/Configurationを経てL0へ、(4) ホストがConfiguration Spaceを読み、Vendor ID/Device IDやクラスコードを見てドライバーを決める、という順です。どこで止まっているかで担当領域が変わるため、段階ごとに観測手段を用意します。

まず「リンクが上がっているか」は最重要です。FPGAのPCIe IPが提供するステータス(リンクアップ、Negotiated Link Width/Speed、LTSSM状態)を取り出し、LEDやレジスターで見えるようにすると切り分けが速くなります。

リンクアップしていなければ、物理層/配線/クロック/リセットが第一容疑です。 リンクアップしているのに認識しない場合は、Configuration Spaceの内容(Vendor IDが0xFFFFになっていないか、BAR設定が妥当か、クラスコードが意図通りか)と、ホスト側のログを確認します。開発中は、期待するクラスコードを返すだけでも「列挙は通る」ので、まず最小構成でEnumerationを確実に通し、その後にDMAやアプリ機能を増やすのが安全です。

ソフトウェア側の実装(ドライバ・BAR・割り込み)

OSから扱うには、BAR設計(MMIO/メモリマップ)、割り込み(MSI/MSI-Xなど)、ドライバーの初期化とDMA連携を設計します。

BARはホストから見た「FPGAの窓口」です。制御レジスター用の小さなMMIO領域と、DMA制御やステータス、デバッグ用の領域を分けると運用しやすくなります。初心者がつまずきやすいのは、BARサイズやアライメント、キャッシュ属性、エンディアンの扱いで、ここを曖昧にすると「たまに動かない」系の不具合が出ます。

割り込みはMSI/MSI-Xが一般的で、レイテンシとスループットの両面に影響します。割り込みを出しすぎるとCPU負荷が上がり、逆にポーリングだけにするとレイテンシが悪化します。実務では、DMA完了をバッチ化し、一定量たまったら割り込み、緊急イベントは即時割り込み、といった設計で折り合いをつけます。 ドライバーは初期化手順が肝です。

PCIeデバイスとして列挙されても、ドライバーがBARをマップし、DMA用バッファを確保し、IOMMUやキャッシュ整合を処理して初めて安定した転送になります。開発初期は、汎用ドライバー(ユーザー空間アクセスや簡易DMA)で動作確認し、仕様が固まってから本格ドライバーへ移ると手戻りを減らせます。

性能設計の勘所(スループット・レイテンシ・TLPサイズ)

理論帯域だけでなく、TLPヘッダやDLLPのオーバーヘッド、最大ペイロード、DMAバースト、レイテンシ要件を踏まえてボトルネックを潰します。

性能は「リンク速度×レーン数」だけでは決まりません。PCIeはTLPヘッダーやDLLP、フロー制御、クレジット制限があり、特に小さな転送を頻発するとオーバーヘッドが支配的になります。スループットを出したいなら、十分に大きい連続転送を作り、無駄な往復を減らす設計が基本です。

最大ペイロード(Max Payload Size)や最大リード要求(Max Read Request Size)は、ホストとデバイスの交渉で決まり、ここが小さいと読み出し性能が伸びません。さらにDMAの発行粒度、ホストメモリの連続性(IOMMUやページ分割)、割り込み頻度が絡むため、ボトルネックは「FPGA内」より「システム全体」に潜むことが多いです。

レイテンシ重視の場合は逆に、巨大なバッファリングが遅延を増やします。一定の小ささで区切りつつ、TLPを無駄に増やさない折衷点を探します。用途ごとに指標を分け、スループットはGB/s、レイテンシは分位点(p99など)で評価すると、体感と一致しやすく改善点も見つけやすいです。。

デバッグ手順(LTSSM・リンクアップ・アイダイアグラム)

リンクしない/不安定/エラー多発を効率よく潰すために、LTSSM観測、物理層品質の確認、プロトコル解析の順で進めます。

デバッグは層を下から上へ進めるのが最短です。最初にLTSSM状態、Negotiated Speed/Width、リンクアップフラグを観測し、物理層が成立しているかを確認します。ここで止まっているなら、配線、AC結合、極性/レーンマッピング、リファレンスクロック、PERST#の順で疑います。

リンクアップしてもGenが上がらない、エラーが多い場合は、アイダイアグラムやBER、受信等化設定の妥当性を見ます。ベンダのトランシーバー評価機能を使い、同じボードでも温度やロットで余裕が変わることを前提にマージンを取ります。動くかどうかではなく「どれだけ余裕があるか」を見ないと、量産後に化けます。

プロトコル層の解析は最後です。Configuration Spaceアクセス、BAR設定、DMA転送のTLPが期待通りかを確認し、必要ならプロトコルアナライザーで観測します。ただし、まずリンクと列挙が安定してからでないと、上位解析はノイズが多く、原因を誤認しやすい点に注意します。。

よくあるトラブル(リンクしない・認識しない・速度が出ない)

現場で頻出する症状を、原因カテゴリ(信号品質/クロック/リセット/設定/ソフト)に分け、再現性のある確認観点を提示します。

リンクしない場合は、物理層の問題が最優先です。差動ペアの配線ミス、極性反転、レーン入れ替え、AC結合の位置や値、基準クロックの取り回し、PERST#の論理やタイミングなど、ボード起因が多くを占めます。まずはx1でのリンクアップやGen落ちで再現性を取り、どの条件で改善/悪化するかを記録すると切り分けが進みます。

認識しない場合は、コンフィグ完了時間と列挙タイミングの不一致が典型です。開発段階ならOS起動後に書き込んで再スキャンで見えることがありますが、最終的には不揮発起動とリセット制御で「起動時に自然に見える」形にする必要があります。また、Vendor ID/Device IDが未設定、Configuration Spaceが読めない、クラスコードが意図しないなど、設定不備でも同様の症状になります。

速度が出ない場合は、Gen/レーン数の交渉結果、最大ペイロードやリード要求サイズ、DMAの粒度、割り込み設計、ホスト側のIOMMUやメモリ帯域が絡みます。リンクがGen1相当になっていないか、x8のはずがx4で上がっていないかを最初に確認し、その上で転送サイズを大きくした時に伸びるか、CPU負荷が張り付いていないかを見ます。。

まとめ

FPGAでPCIeを成立させるには、IP選定・FPGA要件・基板品質・コンフィグ時間・Enumeration・ドライバーまで一気通貫で設計し、LTSSMなどで段階的に検証することが近道です。

FPGAのPCIe実装は、単にIPをつないで動かすだけではなく、物理層からOSの列挙、ソフトウェアまでが連鎖するシステム開発です。まずは対応Gen/レーン数、GT/クロック要件、基板配線ルールを満たし、リンクアップを安定させることが土台になります。

次に重要なのが起動と列挙です。FPGAのコンフィグ完了が遅いと「認識しない」に直結するため、開発用の回避策(再スキャンなど)と、量産での解決策(不揮発起動、設定速度最適化、リセット制御)を分けて設計します。

最後に性能はDMAとソフトが決めます。TLPの粒度、割り込み、バッファ管理まで含めてボトルネックを潰し、LTSSMやリンク状態を常に観測できる作りにしておくと、トラブル対応も性能改善も速くなります。

お問い合わせ

FPGAに関するお問い合わせはこちら

※ 本記事に記載されている製品名・社名は、各社の商標または登録商標です。