FPGA開発日記

FPGAというより、コンピュータアーキテクチャかもね! カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages

NVDLAの内部構成調査(1. NVDLAのテストパタンの調査)

RISC-VのNVDLAがコラボしたり、NVDLAの調査も再度実施しなければならないと思ってきた。

riscv.org

しかしNVDLAの内部構成やインテグレーションの方法など、あまり情報が整理されていない。 というわけで、NVDLAのリポジトリのテストパタンを解析して、どうやって動いているのか見ていこう。

NVDLAには、主に以下のテストパタンが付属しており、Verilator, Vivado Simulator, VCSで動作させることができる。

verif/traces/traceplayer/sanity0
  • sanity0
  • sanity1
  • sanity1_cvsram
  • sanity2
  • sanity2_cvsram
  • sanity3
  • sanity3_cvsram
  • sdp_relu_int16
  • cc_alexnet_conv5_relu5_int16_dtest_cvsram
  • conv_8x8_fc_int16
  • googlenet_conv2_3x3_int16
  • pdp_max_pooling_int16

まずはsanityテストからチェックしようかな。

csr制御のシーケンサ

NVDLAのテストベンチは、read_reg, write_regなどのCSRを制御するシーケンスで構成されている。 これを実際に制御するのはNVDLAモジュールの傍にインスタンスされているcsr_master_seqというモジュールなのだが、このモジュールがそれぞれの命令をシーケンサで管理している。

表. NVDLAテスト用の制御シーケンサのステートマシン
コマンド名 番号
MSEQ_IDLE 8'h00
MSEQ_REG_RD 8'h01
MSEQ_REG_RD_WAIT_RESP 8'h02
MSEQ_REG_RD_POLL_WAIT 8'h03
MSEQ_REG_RD_MISMATCH 8'h04
MSEQ_REG_RD_TIMEOUT 8'h05
MSEQ_REG_WR 8'h08
MSEQ_REG_WR_WAIT_RESP 8'h09
MSEQ_REG_WR_TIMEOUT 8'h0a
MSEQ_MEM_RD 8'h10
MSEQ_MEM_WR 8'h18
MSEQ_MEM_LD 8'h20
MSEQ_MEM_DMP 8'h28
MSEQ_WAIT 8'h30
MSEQ_WAIT_TIMEOUT 8'h31
MSEQ_BOOT_1 8'hfd
MSEQ_BOOT_2 8'hfe
MSEQ_DONE 8'hff

sanity0

レジスタアクセスに関するテスト。

3回のレジスタアクセスを起こす。

  1. CFG_DST_SURF_0の初期値読み込み。
  2. CFG_DST_SURF_0に値を書き込み。
  3. CFG_DST_SURF_0に書き込んだ値が読み込めるか。

sanity1

BDMAに関するテスト。

tb.slave_mem_wrap.dbb_mem.memoryにsurf_memの内容をコピーする。このメモリは32ビット幅で、surf_data.txtの中身をそのまま格納している。

0x80000000に格納されているデータを0x81000000にコピーしている。

CFG_LINEを7に設定している。CFG_LINE_REPEATが0x7に設定されている。このパラメータは1surfaceにつき何ラインを移動するかを指定している。

最後にCFG_LAUNCH0に書き込みして実行開始。

64bit×32回のバーストが発生している。NVDLA側からリードリクエストを発生させ、読み込んだものをそのまま書き込み。

sanity2

BDMAに関するテストでsanity1と同じだが、最後に割り込みが発生するのを待つ。最後にwaitコマンドを実行し、割り込みが発生するまで待機する。

sanity3

sample_surf.datのデータと、weight.datのデータを使って畳み込み演算を実行している。

sample_surfのデータは0x80000000-0x80001000(4KB)、0x80100000から18KBに格納されている。といっても、かなり大量にレジスタを設定しているので、もう少し調査しないといけない。

NVDLAの扱えるデータ構造

sanity3は実際に畳み込みをするテストなのだが、どのようにデータを格納して扱うのだろうか?

色々調べると、詳細な情報を以下に見つけた。

  • NVDLA : In-memory data formats

In-memory data formats — NVDLA Documentation

どうやら、重みと入力データでデータタイプをいろいろ指定できるらしい。 NVDLAの精度としてはint8, int16, fp16をサポートしている。

入力データの形は、Width, Height, Channelの3次元構造を入力することができる。 これに対して、Line Stride, Surface Strideを指定することで畳み込みのサイズを指定している。

http://nvdla.org/_images/format_packed_feature_diagram.svg
図. 特徴データのデータ構造 (http://nvdla.org/hw/format.html#basic-weight-for-winograd-convolution より抜粋)
http://nvdla.org/_images/format_unpacked_feature_diagram.svg
図. 特徴データのデータ構造 (http://nvdla.org/hw/format.html#basic-weight-for-winograd-convolution より抜粋)