Vengineerの妄想

人生を妄想しています。

NVIDIAのDLAがVivado Simでシミュレーションできるようになった



既に、githubにもVivado Simでシミュレーションできるものになっています。

タグ:nvdlav1 がデフォルトになっていて、



gitでとってきたら、
    % ./tools/bin/tmake -build vmod
にて、準備したら、verif/sim_vivado ディレクトリに移動して、下記のmakeを実行するとシミュレーションが始まります。
    % cd verif/sim_vivado
    % make run TESTDIR=../traces/traceplayer/googlenet_conv2_3x3_int16

最初に、コンパイル、エラボレーション後、シミュレーションします。

    verif/traces/traceplayer/googlenet_conv2_3x3_int16 ディレクトリにある

  initialize_output_region.dat	
  input.txn	
  input_feature_map.dat	
  input_weight.dat	
  output_feature_map.dat

  がテストパターンになります。
  
  input.txn は、テストパターンです。
  入力データとして、input_feature_map.dat、パラメータとして、input_weight.dat を読み込み、
  各レジスタに設定後、ハードウェアを起動します。
  処理が終わったら、出力データ(output_feature_map.dat)の値と同じになるかを確認すればいいです。

テストパターン(input.txn)の最初の方を見てみましょう!
# load_mem(addr, offset,  file)
# write_reg(reg_addr, reg_data, misc_bits)
load_mem 0x50064080 0xb480 input_feature_map.dat 
load_mem 0x5002dfe0 0x36000 input_weight.dat 
load_mem 0x500000e0 0x2da80 initialize_output_region.dat 
write_reg 0xffff2c01 0x0 #NVDLA_SDP.S_POINTER_0
read_reg 0xffff2c01 0x00010001 0x00000000 #NVDLA_SDP.S_POINTER_0
write_reg 0xffff2c3a 0x0 #NVDLA_SDP.D_PERF_LUT_OFLOW_0

最初の load_mem コマンドで、
アドレス 0x50064080 に、サイズ 0xb480 で input_feature_map.dat 内の入力データを書き込みます。
次の load_mem コマンドで、
アドレス 0x5002dfe に、サイズ 0x36000 で input_weight.dat 内のパラメータを書き込みます。
三番目の load_mem コマンドで、
アドレス 0x500000e0 に、サイズ 0x2da80 で initialize_output_region.dat 内の値で初期化します。

それ以降の write_reg コマンドでレジスタに値を書き込み、read_reg コマンドで書き込んだ値を読みだしています。
read_reg コマンドの2番目の引数は、読み込んだ値のマスク値です。

write_reg 0xffff2c0e 0x1 #NVDLA_SDP.D_OP_ENABLE_0
read_reg 0xffff2c0e 0x00000001 0x00000001 #NVDLA_SDP.D_OP_ENABLE_0
write_reg 0xffff2402 0x1 #NVDLA_CACC.D_OP_ENABLE_0
read_reg 0xffff2402 0x00000001 0x00000001 #NVDLA_CACC.D_OP_ENABLE_0
write_reg 0xffff1c02 0x1 #NVDLA_CMAC_A.D_OP_ENABLE_0
read_reg 0xffff1c02 0x00000001 0x00000001 #NVDLA_CMAC_A.D_OP_ENABLE_0
write_reg 0xffff2002 0x1 #NVDLA_CMAC_B.D_OP_ENABLE_0
read_reg 0xffff2002 0x00000001 0x00000001 #NVDLA_CMAC_B.D_OP_ENABLE_0
write_reg 0xffff1802 0x1 #NVDLA_CSC.D_OP_ENABLE_0
read_reg 0xffff1802 0x00000001 0x00000001 #NVDLA_CSC.D_OP_ENABLE_0
write_reg 0xffff1404 0x1 #NVDLA_CDMA.D_OP_ENABLE_0
read_reg 0xffff1404 0x00000001 0x00000001 #NVDLA_CDMA.D_OP_ENABLE_0

にて、各モジュールを起動し、
wait
write_reg 0xffff0003 0xffffffff #NVDLA_GLB.S_INTR_STATUS_0
wait
write_reg 0xffff0003 0xffffffff #NVDLA_GLB.S_INTR_STATUS_0
wait
write_reg 0xffff0003 0xffffffff #NVDLA_GLB.S_INTR_STATUS_0
wait
write_reg 0xffff0003 0xffffffff #NVDLA_GLB.S_INTR_STATUS_0
にて、処理待ちをし、ステータスをクリアします。
最後に、
dump_mem 0x500000e0 0x2da80 output_feature_map.dat 
にて、
dump_mem コマンドにて、アドレス 0x500000e0 にて、サイズ 0x2da80 をファイル output_feature_map.dat に書き込みます。
アドレス 0x500000e0 は、read_mem コマンドにて、initialize_output_region.dat ファイルにて初期化しました。

用意されている output_feature_map.dat と比較することで、出力が正しいかどうかを確認できます。