AHCIを用いたPCとFPGA間の汎用インターフェースの実装と評価
三好健文 船田悟史(株)イーツリーズ・ジャパン
2015.06.20RECONF研@京都
このスライドは,現在開発中のシステムに基づいてデータ計測/リソース使用量を評価しています.今後の開発/デバッグの進捗で良くも悪くもなり得ます.データの利用には,ご注意ください.
2
モチベーション✔ FPGAを使ったシステム(PC+FPGA)の実装の需要が増えている
✔ PCとFPGAに求める負荷はプロジェクトそれぞれ✔ 既存のPCなシステムにFPGAを埋めこみたいというのは多い
✔ 手軽にFPGAとPCを接続したい✔ PC(OS)のドライバは書きたくない✔ LinuxやWindowsなどいろんなOSでFPGA(で作ったアクセラレータ)を扱いたい
3
PC-FPGAインターフェースの候補UART USB PCIe TCP/IP, UDP/IP
速度 ~数Mbps~480Mbps(2.0)
~5Gbps(3.0)~4GBps(Gen2x4)~8GBps(Gen3x4)
~Gbps@GbE~10Gbps@xGbE
プログラミング termiosLibusb
専用デバドラMmap
専用デバドラ socket
接続の容易さ 簡単 簡単 ちょっと面倒 簡単(世界の裏側でも)
接続数 対向/マルチドロップ
~127 ~数10個? たくさん
アクセスタイプ ストリーム ストリーム/メモリマップ
ストリーム/メモリマップ ストリーム
4
PC-FPGAインターフェースの候補UART USB PCIe TCP/IP, UDP/IP
速度 ~数Mbps~480Mbps(2.0)
~5Gbps(3.0)~4GBps(Gen2x4)~8GBps(Gen3x4)
~Gbps@GbE~10Gbps@xGbE
プログラミング termiosLibusb
専用デバドラMmap
専用デバドラ socket
接続の容易さ 簡単 簡単 ちょっと面倒 簡単(世界の裏側でも)
接続数 対向/マルチドロップ
~127 ~数10個? たくさん
アクセスタイプ ストリーム ストリーム/メモリマップ
ストリーム/メモリマップ ストリーム
遅い デバドラ書くの大変FPGAで使うのは面倒
ランダムアクセスは...
5
PC-FPGAインターフェースの候補UART USB PCIe TCP/IP, UDP/IP
速度 ~数Mbps~480Mbps(2.0)
~5Gbps(3.0)~4GBps(Gen2x4)~8GBps(Gen3x4)
~Gbps@GbE~10Gbps@xGbE
プログラミング termiosLibusb
専用デバドラMmap
専用デバドラ socket
接続の容易さ 簡単 簡単 ちょっと面倒 簡単(世界の裏側でも)
接続数 対向/マルチドロップ
~127 ~数10個? たくさん
アクセスタイプ ストリーム ストリーム/メモリマップ
ストリーム/メモリマップ ストリーム
デバドラ書くの大変速い.FPGAで使いやすい ...デバドラさえ書ければ
6
PC-FPGAインターフェースの候補UART USB PCIe TCP/IP, UDP/IP
速度 ~数Mbps~480Mbps(2.0)
~5Gbps(3.0)~4GBps(Gen2x4)~8GBps(Gen3x4)
~Gbps@GbE~10Gbps@xGbE
プログラミング termiosLibusb
専用デバドラMmap
専用デバドラ socket
接続の容易さ 簡単 簡単 ちょっと面倒 簡単(世界の裏側でも)
接続数 対向/マルチドロップ
~127 ~数10個? たくさん
アクセスタイプ ストリーム ストリーム/メモリマップ
ストリーム/メモリマップ ストリーム
デバドラ書くの大変速い.FPGAで使いやすい
AHCIを実装して,ディスクに見せてしまおう!!
7
AHCI✔ Advanced Host Controller Interface✔ SATAなHDDやSSDを接続するためのインターフェース
✔ 最近のOSのほとんどでサポートされている
= 標準のデバドラでブロックデバイスにみえる
✔ SATAなHDDやSSD以外に接続してはいけない,ことはない
8
一般的なAHCIによるディスク接続
ディスクに送るコマンドを預かるディスクからのリプライを返す作業用メモリのポインタの確認複数コマンドをOoOで発行(NCQ)
ディスクへのFISの発行ディスクからのFISの受信ステータス管理
9
AHCIのメモリチェイン
どのコマンドが有効かはPxCIレジスタをみる
ディスクに送るべきコマンド
PCIeのBAR5にレジスタ空間へのポインタがある
ディスクとのやり取りに使うメモリ領域へのポインタ
近代的なOSでは大量の仮想メモリを複数の細かい実メモリに分割して扱う
ディスクとのやり取りに使うメモリ領域
P0CLB
HBAからはP0CLBの値でたどる
10
AHCI越しのデータ授受のフロー
PCIe越しの通信
11
AHCI✔ Advanced Host Controller Interface
✔ SATAなHDDやSSDを接続するためのインターフェース
✔ 最近のOSのほとんどでサポートされている
= 標準のデバドラでブロックデバイスにみえる
✔ スキャッタギャザーDMAとしてよくできてる
✔ PCIe越しの煩雑な通信オーバヘッドが心配
✔ どこまでディスクなしでOSをだませるものだろうか?
12
今回の取り組みの趣旨✔ AHCIをPC-FPGA間汎用インターフェースとして使ってみる
→ HBA(ホストバスアダプタ)をFPGAに実装してみる
✔ FPGA内ロジックへのアクセスとAHCIの親和性✔ 回路規模は?
✔ 転送性能は?✔ 実装の複雑さは?
設計と実装
14
実装するシステムの概要OSからのリクエストにディスクにアクセスしたフリをしつつAXI空間のデバイスにアクセスする
Gen2 x4
レジスタマップはPCIe経由でホストから叩かれる
ディスクアクセスのためのLBAは素直に(LBA*512)AXIアドレスに対応づける
15
実装するシステムの足回り今回はXilinxのIPコアで組立て.
16
HBAでディスクの状態を補完= ないディスクのふりをする
✔ HBAレジスタのディスク状態の”適当”な設定例
レジスタ 値 概要
CAP 40240000 NCQ有効.転送レートはGen2相当.AHCIのみサポート
GHC 80000000 AHCIを有効
PI 00000001 ポート0のみ有効
VS 00010000 サポートするAHCIバージョン(1.0)
CCC_CTL 00010100 タイムアウトとコマンドコンプリージョンリセット値
P0CMD 00110006 ディスクがコマンド待機状態に見えるように設定
P0TFD 00000058 RegD2Hが成功したように設定しておく
P2SSTS 00000123 ディスクが電源ONの状態に設定
P0SCTL 00000320 ディスクが正常動作中にみえるように設定
17
HBAの動作フロー
ここはディスクの代わりにHBA内で処理してしまう少なくとも IDENTIFY FPDMA_READ/FPDMA_WRITEは必須
メモリチェインをたどる(本来のHBAの処理)
18
HBAの動作フロー/FIS取得までprivate int wait_for_command(){ while(reg.values[P0CI] == 0) ; reg.values[P0CMD] = 0x10110007; // 処理開始 int id = get_port_id(reg.values[P0CI]); // '1'のbitを選ぶ
axi.fetch(reg.values[P0CLB] + (id << 5), 4); // command headerを取得 dw0 = axi.read(0); // PRDTL, PMP, RCBRPWA, CFL dw1 = axi.read(1); // PRD Byte Count dw2 = axi.read(2); // CTBA0 dw3 = axi.read(3); prdtl = (dw0 >> 16) & 0x0000FFFF;
ctba = dw2; axi.fetch(ctba, 5);// CFIS取得 cfis_dw0 = axi.read(0); // Features, // Command,… cfis_dw1 = axi.read(1); cfis_dw2 = axi.read(2); cfis_dw3 = axi.read(3); return (dw0 >> 16) & 0x000000FF;}
P0CLB
19
FISに対する処理: FISとは✔ SATAとコマンド/リプライをやりとりするパケット✔ いくつかのフォーマットがある
✔ RegH2D: ホスト(PC)からデバイス(ディスク)へ✔ RegD2H: デバイス(ディスク)からホストPCへ✔ DMAリード/ライト✔ FPDMAリード/ライト✔ ...
20
FISの例RegH2D
FPDMA_READ/WRITE
21
FISへの対応例: IDENTIFYprivate void return_identify(){ // get PRDT entry axi.fetch(ctba + 0x80, 4); int dba = axi.read(0); // DBA
for(int i = 0; i < 128; i++){ axi.write(i, identify.data[i]); } axi.flush(dba, 128);
// reply fis axi.write(0, 0x0058605f); axi.write(1, 0xe0000000); axi.write(2, 0x00000000); axi.write(3, 0x500000ff); axi.write(4, 0x00000200);
axi.flush(reg.values[P0FB] + 0x20, 5);}
P0CLB
22
FISへの対応例: FPDMA_READprivate void do_fpdma_read(){ int ncq_tag = (cfis_dw3 >> 3) & 0x0000001F; int lba = (cfis_dw1 & 0x00FFFFFF); int lba_exp = (cfis_dw2 & 0x00FFFFFF); int sectors = ((cfis_dw0>>24)&0x000000FF) + (((cfic_dw2>>24)&0x000000FF)<<8); int offset = lba * 512; // アクセスするAIX空間上のアドレス
for(int i = 0; i < prdtl; i++){ axi.fetch(ctba + 0x80 + (i<<4), 4); // ホストメモリ上のアドレス int prdtl_addr = axi.read(0); int prdtl_len = (axi.read(3)&0x003FFFFF)+1; copy_storage2pcie_all(offset, prdtl_addr, prdtl_len); offset = offset + prdtl_len; }
}
P0CLB
動作例
24
動作例PCIデバイス→AHCIデバイス→ディスクに見えている
XilinxのPCIe<->AXIブリッジはBAR5が使えないのでBAR0で代用.この対応パッチだけデバドラに適用標準AHCIデバドラが
アタッチされていることがわかる
FPGA
25
動作例PCIデバイス→AHCIデバイス→ディスクに見えている
うまくOSをだませている/dev/sdbらしい
ddとかできる
26
動作例ディスクなのでfdiskでパーティションを作ることも可能
これはFPGA fdisk!!
FPGA上(AXI越しのメモリの上)にパーティションができた
27
動作例フォーマットしてファイル作成も可能
フォーマットしてファイルを書くこともできる
評価
29
評価環境✔ ホストPC
✔ Intel Core i3-4130 3.40GHz✔ メモリDDR3 16GB✔ OS Ubuntu 14.04.2 (Kernel 3.13.11-ctk17)
✔ FPGAボード/開発環境✔ Xilinx K705✔ Vivado 2014.4✔ AXI内部バス32bit,512bit
30
実装するシステムの概要
Gen2 x4
内部バス32bitのシステム
31
リソース使用量
項目 使用数 使用率
システム全体 スライスLUT 37386 18%
スライスレジスタ 32733 8.0%
占有スライス 15045 30%
ブロックRAM 25 5.6%
HBA スライスLUT 4241 2.0%
スライスレジスタ 8467 2.0%
占有スライス 2620 5.1%
ブロックRAM 2 0.5%
内部バス32bitのシステム
32
転送性能内部バス32bitのシステム
33
実装するシステムの概要
このバス幅として,512bitのバージョンを試す
Gen2 x4
内部バス512bitのシステム制御用に32bit AXIバスを残す
34
リソース使用量
項目 使用数 使用率
システム全体 スライスLUT 46525 23%
スライスレジスタ 45109 11%
占有スライス 17825 35%
ブロックRAM 53 12%
HBA スライスLUT 11499 5.6%
スライスレジスタ 8982 2.2%
占有スライス 5002 9.8%
ブロックRAM 30 6.7%
内部バス512bitのシステム
35
転送性能内部バス512bitのシステム
36
比較✔ Xilinx EDKのIPコアで作ったシステム on KC705
✔ ホストメモリは連続領域を確保
Host PC
Host PCMain Memory
Software
FPGA Board
FPGA Board
DDR3 Memory
Main controller
PCIe MemoryController
DMA engineKick
Done
User Application Logic
Host Memory → DDR3 Memory/FPGA BoardDDR3 Memory/FPGA Board → Host Memory
128bit 256bit
@100MHz
@800MHz
37
比較Throughput (MBps)
Transfer unit (Bytes)
FPGA→Host: 1GBps
Host→FPGA: 850MBps
38
AHCI越しのデータ転送の様子データ転送開始直後(4KB単位のブロック転送)
39
(1) (2)
AHCI越しのデータ転送の様子(2') (1) 4KB
CTRL ARVALID: 0CTRL RVALID : 104(104)SRC ARVALID : 180( 76)DATA RVALID : 234( 54)DATA RLAST : 314( 80)COPY START : 338( 24)COPY DONE : 405( 67)DEST AWVALID: 426( 21)DEST WVALID : 430( 4)DEST WLAT : 688(258)
(2) 4KBCTRL ARVALID: 476( 0)CTRL RVALID : 1238(762)SRC ARVALID : 1315( 76)DATA RVALID : 1369( 54)DATA RLAST : 1449( 80)COPY SART : 1472( 24)COPY DONE : 1539( 67)DEST AWVALID: 1560( 21)DEST WVALID : 1564( 4)DEST WLAT : 1822(258)
40
AHCI越しのデータ転送しばらくデータ転送が継続したあと(60KB単位の転送)
41
まとめ✔ AHCIをPC-FPGA間汎用インターフェースとして使ってみる
→ HBA(ホストバスアダプタ)をFPGAに実装してみる
✔ FPGA内ロジックへのアクセスとAHCIの親和性
→AXI-MMと親和性は高い
✔ 回路規模は?→内部バスを512bitと奢ってもXC7K325Tの約35%
→比較相手よりやや大きい✔ 転送性能は?→約900MBps→比較相手よりやや遅い✔ 実装の複雑さは?→HBA自体は軽量.移植性も高い.
42
今後の展開✔ FPGA側でOSのファイルシステムを扱いたい✔ Zynqでも利用したい
✔ NVMeではどうだろうか?
43
今後の展開
PC
FPGAディスク?
何かの処理
ディスク
インターネット
✔ なんでもディスクに見せてしまうのは楽しそう✔ たとえば
BRAM
44
まとめ✔ AHCIをPC-FPGA間汎用インターフェースとして使ってみる
→ HBA(ホストバスアダプタ)をFPGAに実装してみる
✔ FPGA内ロジックへのアクセスとAHCIの親和性
→AXI-MMと親和性は高い
✔ 回路規模は?→内部バスを512bitと奢ってもXC7K325Tの約35%
→比較相手よりやや大きい✔ 転送性能は?→約900MBps→比較相手よりやや遅い✔ 実装の複雑さは?→HBA自体は軽量.移植性も高い.