フィボナッチを求める回路をVivado-HLSとMessagePack-RPCでFPGAに実装してみた(シミュレーション編)


#はじめに

Vivado-HLSはXilinx社が提供している高位合成ツールです。
Vivado 2015.4から Vivado-HLS が無償提供されると言うことで、さっそく試してみました。

#用意するもの

 - Xilinx Vivado 2015.4
 - Ruby 1.9.3 以降
 -  [msgpack-vhdl-examples](https://github.com/ikwzm/msgpack-vhdl-examples)

#ブロック図

![akgeo2.jpg](https://qiita-image-store.s3.amazonaws.com/0/24981/d9802aeb-3dc3-1f7e-daf5-b2a3d070fbdf.jpeg)


#ソースコード

フィボナッチを求めるCのソースコードです。

````C:fib.c
long long fib(int n)
{
  long long curr = 0;
  long long next = 1;
  int i;
  for(i = 0; i < n; i++) {
    long long prev = curr;
    curr = next;
    next += prev;
  }
  return curr;
}
````

#手順

##リポジトリと各submodule をダウンロード

````
shell% git clone git://github.com/ikwzm/msgpack-vhdl-examples.git
shell% cd msgpack-vhdl-examples
shell% git submodule init
shell% git submodule update
````

##fib.cを高位合成

スクリプトを用意しています。vivado_hls が実行出来る環境でスクリプトを走らせてください。

````
Vivado% cd examples/fibonacci/sim/vivado/vivado_hls
Vivado% vivado_hls -f run_hls.tcl
================================================================
  Vivado(TM) HLS - High-Level Synthesis from C, C++ and SystemC
  Version 2015.4
  Build 1412921 on Wed Nov 18 09:58:55 AM 2015
  Copyright (C) 2015 Xilinx Inc. All rights reserved.
================================================================
@I [HLS-10] Running 'E:/Xilinx/VIVADO~1/2015.4/bin/unwrapped/win64.o/vivado_hl
exe'
            for user 'xxxxx' on host 'xxxxx' (Windows NT_amd64 version 6.1)
 Tue Dec 01 17:27:40 +0900 2015
            in directory 'H:/work/msgpack-vhdl-examples/examples/fibonacci/sim
ivado/vivado_hls'
@I [HLS-10] Opening and resetting project 'H:/work/msgpack-vhdl-examples/examp
s/fibonacci/sim/vivado/vivado_hls/fib_prj'.
@I [HLS-10] Adding design file '../../../src/main/vivado_hls/fib.c' to the pro
ct
@I [HLS-10] Opening and resetting solution 'H:/work/msgpack-vhdl-examples/exam
es/fibonacci/sim/vivado/vivado_hls/fib_prj/solution1'.
@I [HLS-10] Cleaning up the solution database.
@I [HLS-10] Setting target device to 'xc7z010clg400-1'
@I [SYN-201] Setting up clock 'default' with a period of 10ns.
@I [HLS-10] Analyzing design file '../../../src/main/vivado_hls/fib.c' ...
@I [HLS-10] Validating synthesis directives ...
@I [HLS-10] Starting code transformations ...
@I [HLS-10] Checking synthesizability ...
@I [HLS-111] Elapsed time: 18.988 seconds; current memory usage: 70.7 MB.
@I [HLS-10] Starting hardware synthesis ...
@I [HLS-10] Synthesizing 'fib' ...
@I [HLS-10] ----------------------------------------------------------------
@I [HLS-10] -- Scheduling module 'fib'
@I [HLS-10] ----------------------------------------------------------------
@I [SCHED-11] Starting scheduling ...
@I [SCHED-11] Finished scheduling.
@I [HLS-111] Elapsed time: 0.11 seconds; current memory usage: 71.6 MB.
@I [HLS-10] ----------------------------------------------------------------
@I [HLS-10] -- Exploring micro-architecture for module 'fib'
@I [HLS-10] ----------------------------------------------------------------
@I [BIND-100] Starting micro-architecture generation ...
@I [BIND-101] Performing variable lifetime analysis.
@I [BIND-101] Exploring resource sharing.
@I [BIND-101] Binding ...
@I [BIND-100] Finished micro-architecture generation.
@I [HLS-111] Elapsed time: 0.218 seconds; current memory usage: 71.6 MB.
@I [HLS-10] ----------------------------------------------------------------
@I [HLS-10] -- Generating RTL for module 'fib'
@I [HLS-10] ----------------------------------------------------------------
@I [RTGEN-500] Setting interface mode on port 'fib/n' to 'ap_none'.
@I [RTGEN-500] Setting interface mode on function 'fib' to 'ap_ctrl_hs'.
@I [RTGEN-100] Finished creating RTL model for 'fib'.
@I [HLS-111] Elapsed time: 0.359 seconds; current memory usage: 71.6 MB.
@I [HLS-10] Finished generating all RTL models.
@I [WSYSC-301] Generating RTL SystemC for 'fib'.
@I [WVHDL-304] Generating RTL VHDL for 'fib'.
@I [WVLOG-307] Generating RTL Verilog for 'fib'.
@I [HLS-112] Total elapsed time: 21.609 seconds; peak memory usage: 71.6 MB.
Vivado%
````

これで examples/fibonacci/sim/vivado/vivado_hls/fib_prj/solution1/syn/vhdl/fib.vhd が生成されます。


##テストシナリオの作成

すでに作成済みのテストシナリオ(examples/fibonacci/src/test/scenarios/test_1.snr)を用意しています。このテストシナリオを使う場合は、以下の手順は飛ばしてください。

AXI4_Stream_Master_PlayerおよびAXI4_Stream_Slave_Player用のテストシナリオを作ります。

````
shell% cd examples/fibonacci/src/test/scenarios
shell% ruby test_1.rb
````

test_1.rb はテストシナリオ(YAML形式)を生成するためのrubyスクリプトです。

##Vivado プロジェクトの作成

Vivado プロジェクトを作成するためのTclファイル(create_project.tcl)を用意しています。
Vivadoを起動して次のメニューからTclファイルを実行してください。

````
Vivado > Tools > Run Tcl Script... > examples/fibonacci/sim/vivado/vivado_hls/create_project.tcl
````

##シミュレーションを実行

前節で作った Vivado プロジェクトを開き、次のようにシミュレーションを実行してください。

````
Vivado > Flow > Run Simulation > Run Behavioral Simulation
````

#結果

参考までにn=42の時のシミュレーション波形を示します。
![fibonacci_vivado_hls_wave.jpg](https://qiita-image-store.s3.amazonaws.com/0/24981/a4b549e4-172b-c329-cecc-5b3f5b1048b5.jpeg)

クロックの周波数は100MHzです。
fib(42)を実行するのに、MessagePack-RPCのシリアライズとデシリアライズを含めないFIB単体では430nsec((42+1)×10nsec)かかっていることがわかります。ちなみに[フィボナッチを求める回路をVHDLで記述した場合](http://qiita.com/ikwzm/items/a0ff6cf559f766162951)も同様に430nsecかかっているので、性能的には VHDL で記述した時と同じです。

シミュレーション時のログは次の通りです。
![fibonacci_vivado_hls_log.jpg](https://qiita-image-store.s3.amazonaws.com/0/24981/eba44e8a-e090-7674-a2f3-5115fe293e37.jpeg)


#参考

- [msgpack-vhdl-examples](https://github.com/ikwzm/msgpack-vhdl-examples)
- [フィボナッチを求める回路をVHDLとMessagePack-RPCでFPGAに実装してみた(シミュレーション編)](http://qiita.com/ikwzm/items/a0ff6cf559f766162951)