FPGAのBitstreamについて調査するログ
ふとVivadoが吐くバイナリ(Bitstream)はどんな内容・フォーマットなのか気になったので調査する。
まずはFPGAの内部構成がよくわかってないので次の書籍で勉強する。
FPGAは大きく3種の要素から構成される。
- 論理ブロック(LB) ... 任意の組み合わせ回路を実現するLUT(Look-Up Table)と、値を保持するFF(FlipFlop)で構成される
- I/Oブロック(IOB) ... 外部とのI/O信号の入出力を行う
- 配線要素 ... LB-LBやLB-IOBをプログラマブルな配線で接続する
上記の基本要素の他に、ブロックメモリや乗算などの固定機能回路も組み込まれている場合もある。
書籍の"3.11 コンフィグレーションチェーン"より:
FPGA上に回路を構成することをFPGAをコンフィギュレーションするといい,その際にFPGAに書き込まれる回路情報をコンフィギュレーションデータと呼ぶ.コンフィグレーションデータには,例えばLUTで実現する真理値表の内容や,スイッチブロック内における各スイッチのON/OFF情報など,FPGAに回路を構成するのに必要なすべての情報が含まれる.
上記からBitstreamはコンフィグレーションデータそのものに見える。
XILINXの7シリーズのコンフィグレーションに関するドキュメントには以下のようなものがある。
-
7 シリーズ FPGA コンフィギュレーション ユーザー ガイド (日本語版) (v1.9)
ザイリンクスの 7 シリーズ FPGA におけるコンフィギュレーション インターフェイス、複数ビットストリームの管理、ビットストリームの暗号化、バウンダリスキャンと JTAG コンフィギュレーション、リコンフィギュレーション テクニックについて説明しています。
FPGAをコンフィギュレーションする方法には大きく2つのモードがある。
- マスターモード:
FPGAが能動的に外部のメモリからコンフィギュレーションデータを読み込む方法 - スレーブモード:
外部のプロセッサなどからFPGAへコンフィギュレーションデータを書き込む方法
それぞれのモードにおけるデータパスにはシリアルとパラレルを使用することができる。
また、インターフェースとしてJTAGを使用することもできる。
これらのコンフィグレーションモードはFPGAの入力ピンM[2:0]で指定される。
コンフィギュレーションモード | M[2:0] | バス幅 |
---|---|---|
マスターシリアル | 000 | x1 |
マスターSPI | 001 | x1, x2, x4 |
マスターBPI | 010 | x8, x16 |
マスターSelectMAP | 100 | x8, x16 |
JTAG | 101 | x1 |
スレーブSelectMAP | 110 | x8, x16, x32 |
スレーブシリアル | 111 | x1 |
7シリーズFPGAのBitstreamは次の3つの部分で構成される。
- バス幅の自動検出
- 同期ワード
- FPGAコンフィギュレーション
Vivadoで生成した適当なBitstreamファイルの中身を見てみる。
$ hexdump -C top.bit | less
00000000 00 09 0f f0 0f f0 0f f0 0f f0 00 00 01 61 00 25 |.............a.%|
00000010 74 6f 70 3b 55 73 65 72 49 44 3d 30 58 46 46 46 |top;UserID=0XFFF|
00000020 46 46 46 46 46 3b 56 65 72 73 69 6f 6e 3d 32 30 |FFFFF;Version=20|
00000030 32 30 2e 32 00 62 00 0c 37 73 35 30 63 73 67 61 |20.2.b..7s50csga|
00000040 33 32 34 00 63 00 0b 32 30 32 31 2f 30 32 2f 31 |324.c..2021/02/1|
00000050 38 00 64 00 09 31 38 3a 31 35 3a 34 38 00 65 00 |8.d..18:15:48.e.|
00000060 21 72 8c ff ff ff ff ff ff ff ff ff ff ff ff ff |!r..............|
00000070 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
00000080 ff ff ff 00 00 00 bb 11 22 00 44 ff ff ff ff ff |........".D.....|
00000090 ff ff ff aa 99 55 66 20 00 00 00 30 02 20 01 00 |.....Uf ...0. ..|
--snip--
.bit
ファイルの先頭(ff
が連続する前の部分)はヘッダー情報になっている。
ヘッダー情報は単にASCIIで保持されているようだが、フォーマットについてマニュアルからは見つけられなかった。
なぜかfileコマンドではヘッダー情報が取得できた。
$ file top.bit
top.bit: Xilinx BIT data - from top;UserID=0XFFFFFFFF;Version=2020.2 - for 7s50csga324 - built 2021/02/18(18:15:48) - data length 0x21728c
fileコマンドのソースを検索するとxilinxの.bit
ファイルの設定(?)のようなものは以下にあった。
Rustの勉強も兼ねてbitstreamデコーダの作成中。
バイナリの読み出し方はもっと良い書き方がありそう。
ヘッダーのフォーマットに従って情報を取得できた。
Field 1 (some sort of header)
length: 0x0009
value : [0f, f0, 0f, f0, 0f, f0, 0f, f0, 00]
Field 2
length: 0x0001
value : a
Field 3 (NCD name)
length: 0x0025
value : top;UserID=0XFFFFFFFF;Version=2020.2^@
Field 4 (model/part number)
key : b
length: 0x000c
value : 7s50csga324^@
Field 5 (built date)
key : c
length: 0x000b
value : 2021/02/18^@
Field 6 (built time)
key : d
length: 0x0009
value : 18:15:48^@
Field 7 (data length)
key : e
length: 0x0021728c
00000000 : ffffffff
00000004 : ffffffff
00000008 : ffffffff
0000000c : ffffffff
00000010 : ffffffff
00000014 : ffffffff
00000018 : ffffffff
0000001c : ffffffff
00000020 : 000000bb
00000024 : 11220044
--snip--
ググっていたらオープンソースなFPGAツールチェインというものを見つけた。面白そう。
Bitstreamのヘッダー情報の後にはバス幅自動検出パターンというものが挿入されている。
00000000 : ffffffff
00000004 : ffffffff
00000008 : ffffffff
0000000c : ffffffff
*
00000020 : 000000bb
00000024 : 11220044
00000028 : ffffffff
0000002c : ffffffff
バス幅自動検出パターンはコンフィギュレーションモードのうちパラレルモードで利用される。(シリアルモードでは無視される)
このパターンを幅x8, x16, x32それぞれで読みだしたときの下位8bitをみると、x8のときはbb
の後に11
が、x16のときはbb
の後に22
が、x32のときはbb
の後に44
が検出される。そのため、bb
の後に何がくるかでどのバス幅で読みだしていたかが検出できるという仕組み。
x8 | x16 | x32 |
---|---|---|
[bb] | 00[bb] | 000000[bb] |
[11] | 11[22] | 112200[44] |
[22] | 00[44] | |
[00] | ||
[44] |
バス幅自動検出パターンの後にはaa995566
という同期ワードが挿入されており、FPGAは同期ワードが検出されてから後ろのFPGAコンフィギュレーション部分の処理に進む。
00000028 : ffffffff
0000002c : ffffffff
00000030 : aa995566 ※ 同期ワード
00000034 : 20000000
00000038 : 30022001