この記事の前提
- C-5〜C-8のブート・Device Tree・rootfsの知識を前提にします
- 今回扱わない範囲:HDLの書き方、論理合成・配置配線、高位合成。「Linuxから見たとき、この石はどう見えるか」に絞ります
- 具体的な開発フローはC-11(AMD Zynq-7000)とC-12(Altera Cyclone V SoC)で扱います
はじめに
第3部は深掘り編です。テーマはCPU搭載FPGA SoC――AMD(旧Xilinx)のZynqシリーズや、AlteraのCyclone V SoC/Arria 10 SoCのように、ArmプロセッサとFPGAロジックが1チップに同居したデバイスです。
私が業務でArria 10を扱った当時はIntel FPGAの名称でした。本記事では当時の資料や経験を読む場面では「Intel FPGA」、現在の製品・資料を案内する場面では「Altera(旧Intel FPGA)」と書き分けます。名称が変わっても、ここで扱うPS/HPSとFPGAの境界という設計課題は同じです。
Arria 10については以前、初期性能評価のシリーズを書きました。今回はその続編として、当時は動作確認を優先して素通りした「HPSとFPGAの境界」を整理します。
「マイコン+FPGA」の2チップ構成から考える
CPU搭載FPGAの価値は、従来の2チップ構成と比べると分かりやすくなります。
- CPUとFPGAの間をチップ内のAXIインターフェースで接続でき、基板をまたぐ配線より広帯域・低遅延な経路を構成しやすい
- OCMやPL側Block RAMなどのオンチップRAMを、小容量・低遅延の共有領域として使える
- PLからPS/HPS側のDDRへアクセスする経路を持ち、FPGAが取り込んだデータをDMAでメモリへ渡せる
- 部品点数・基板面積を減らせる
小さなコマンド、状態、リングバッファの管理情報などは、PS内のOCMやPL内のBlock RAMを両側から見えるように設計できます。チップ外へ出ずに受け渡せるため低遅延ですが、容量は限られます。また「同じRAMが載っている」だけで共有になるわけではなく、AXI接続、アドレス割り当て、排他、キャッシュ属性まで決めて初めて共有領域として使えます。
大きなデータを扱う主役は、図のようなチップ外のDDRです。PLからPS/HPS側DDRへは、PS/HPS内のメモリコントローラとAXIブリッジを経由してアクセスします。ボードによっては、これとは別にPL/FPGA側専用のDDRを持つこともあります。
比較を揃えるため、2チップ側にもCPU側DDRと、任意のFPGA側DDRを描きました。2チップ構成で両方にDDRがある場合、メモリ空間は通常別々です。データを渡すには基板上のPCIe、外部バス、独自インターフェースなどを通して転送します。FPGA SoCでもPL側専用DDRを置けば同じ論点が残るため、1チップ化しただけで全メモリが共有されるわけではありません。
「高速なデータ取り込みや専用ロジックはFPGAで、ネットワーク・ファイル・GUIはLinuxで」という計測器や画像機器で定番の構成を、1チップへまとめやすくなります。もちろん、必要なFPGA規模やI/O、メモリ帯域、CPUとFPGAを独立に改版したい事情によっては、今でも2チップ構成が選ばれます。
用語の整理:PS/PL、HPS/FPGA
同じ概念に、ベンダーごとの名前が付いています。先に対照表を置きます。
| 概念 | AMD(Zynq) | Altera(旧Intel FPGA) |
|---|---|---|
| プロセッサ側 | PS(Processing System) | HPS(Hard Processor System) |
| ロジック側 | PL(Programmable Logic) | FPGA(ファブリック) |
以降、一般論としてはPS/PLの語を使います。
PS側は「普通の組み込みLinuxマシン」
重要なのは、PS/HPS側だけ見れば、これまでの回で見てきたSBCに近いということです。Arm Cortex-A系コアに、UART、I2C、SPI、Ethernet、USB、SDカードI/Fといったハードペリフェラルが載っています。Zynq-7000のようにPSだけでLinux起動まで確認しやすいデバイスもありますが、起動条件やI/Oの接続方法はファミリとボード設計によって異なります。C-5〜C-8の知識(ブート、Device Tree、rootfs)はPS/HPS側にそのまま通用します。
PL側は「後から生えてくるペリフェラル」
PLにソフトウェアから見える回路を作り込むと、PSからは新しいペリフェラルが増えたように見えます。SoC内蔵UARTには既製ドライバがありますが、独自レジスタを持つ回路は、UIOや専用ドライバなど受け口の設計が必要です。そしてC-7で見たとおり、そのアドレス、割り込み、互換性などをLinuxへ伝えるのがDevice Treeの役目です。ソフトウェアから使うPL回路を追加したら、Device Treeやドライバも同時に見直すと覚えてください。
PSとPLの境界で起きていること
Linuxから見た「境界」の実体は、大きく3つに整理できます。
1. AXIバス:レジスタとデータの通り道
PL側の回路はAXIバスでPSへ接続され、物理アドレス空間にマッピングされます。Linuxからは「あるアドレスを読み書きするとPLのレジスタへアクセスできる」ように見えます。
素朴なレジスタ確認に/dev/mem+mmapが使われることがありますが、物理メモリへ広く触れられる強い権限が必要です。製品コードには持ち込まず、要件に合えばUIO(Userspace I/O)、標準サブシステム、専用カーネルドライバのいずれかへ移します。UIOは、メモリマップと比較的単純な割り込みで完結する装置には向きますが、あらゆるデバイスに使える万能インターフェースではありません。
また、AXI接続には性格の違うポートがあり、方向を混同しないのがコツです(名称・構成はデバイスファミリで異なります)。
- PSがマスタになるポート:CPUがPLのレジスタを叩く用。制御・設定向き
- PLがマスタになる高性能ポート:PLがDRAMへ直接DMAする用。大容量データ向き
2. オンチップRAMとDDR:データ量で置き場所を分ける
小さく頻繁に交換するデータなら、オンチップRAMをメールボックスや短いキューとして使う構成が考えられます。一方、高速ADCの取り込みデータのような大物は、レジスタを1語ずつ読むのではなく、PL側のDMA回路からPS/HPS側DDRへまとめて転送し、CPUが処理する構成が定石です。このとき避けて通れないのがキャッシュコヒーレンシ(CPUキャッシュとメモリ上の内容をどう一致させるか)です。
コヒーレントな経路を使えるか、非コヒーレントな経路をLinuxのDMA APIで管理するかはデバイスと設計次第です。ユーザー空間から勘でキャッシュ操作を足して直すのではなく、まず使用ポートとDMAバッファの管理主体を確認します。たまに古いデータが見える、負荷を上げると壊れる、といった症状を生みやすい境界です。
3. 割り込み:PLからPSを呼ぶ
「データが溜まった」等のイベントは、PLからの割り込み線でPSへ通知します。Linux側では、これもDevice Treeへ割り込み番号を記述し、ドライバで受けます。
ブートはどうなる?(C-5の地図の拡張)
FPGA SoCのブートは、C-5の6段階に 「PLのコンフィグレーション(回路データの書き込み)」という工程が加わる 形になります。初期ローダーやブートローダーがビットストリームを書き込む構成もあれば、Linux起動後にFPGA Managerなどの仕組みで構成する運用もあります。いつ書き込むかは、PLがブートに必須か、更新単位をどう分けるか、停止中の周辺回路を安全な状態にできるかまで含む設計判断です。
ハマりどころ
- 最初から全部載せで起動する:PSだけで起動できる構成なら、まずLinuxとPS内蔵周辺だけを確認します。PLが起動条件に関わるデバイスでは、ベンダーの参照デザインを基準にします
-
/dev/memで叩き続ける:アクセス範囲、排他、割り込み、エラー処理をアプリ任せにしてしまいます。早めにUIO、標準サブシステム、専用ドライバのどれで受けるか決めます - アドレスマップの不一致:ハード側でPLレジスタの割当アドレスを変えたのにDevice Treeが古いまま――FPGA SoC開発の定番事故です。「回路とDevice Treeは同時に更新」を仕組みにします(C-7の「契約書」の考え方がそのまま効きます)
- キャッシュコヒーレンシ:DMAデータが「たまに化ける」ときは、真っ先にここを疑います
- PLへのクロック・リセット供給:PL側回路が動かないとき、PSから供給するクロックやリセットの設定漏れも定番です
現場コラム:FPGA屋とLinux屋の「境界人材」
この石を使うプロジェクトでは、FPGA担当とソフト担当の間に必ず「境界」の仕事が発生します。アドレスマップ、割り込み割当、DMAバッファの取り決め、Device Treeへの反映。どちらのチームの「本業」でもないこの領域は、放っておくと誰も拾いません。
私自身、ファームウェア屋としてこの境界を長く歩いてきましたが、両方の言葉を半分ずつでも話せる人がいるだけで、プロジェクトの摩擦は目に見えて減ります。A-5で書いたレジスタ操作GUIも、まさにこの境界のための道具でした。FPGA SoCを学ぶことは、この境界人材への入口だと思っています。
まずPS/HPS側を観察する
手元にFPGA SoCボードがある方は、PLを使わない状態でLinuxを起動し、C-7の方法で/sys/firmware/devicetree/baseを眺めてみてください。PS内蔵ペリフェラルのノードが「普通のSBC」と同じ姿で並んでいることが確認できれば、この石の半分はもう知っている、ということです。
まとめと次回
- CPU搭載FPGA SoCは「PS(Linuxが動く普通のArm)」+「PL(後から生えるペリフェラル)」の同居
- 境界の実体はAXI、オンチップRAM/外付けDDR、DMA、割り込み。データ量と所有権で使い分ける
- PLの回路を増やしたらDevice Treeも育てる。C-5〜C-8の知識はPS側にそのまま通用する
次回C-10は、この石のLinuxを自分で構成するための道具、Yocto Projectの地図です。BitBake、recipe、layer……用語の霧を晴らします。
