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

#はじめに

Synverllは石原ひでみさんが開発している高位合成ツールです。詳細は以下のページや記事を参照してください。

 - [ひでみのアイデア帳](http://www.sweetcafe.jp)  : 石原ひでみさんのホームページです。
 - [https://github.com/aquaxis/synverll](https://github.com/aquaxis/synverll) : Githubで公開しているSynverllのソースコード。
 - [FPGAマガジン No.11](http://www.kumikomi.net/fpga/contents/0011.php) : 95ページに記事があります。
 - [FPGAの部屋のまとめサイト](http://marsee101.web.fc2.com/synverll.html) : marsee101さんがSynverllを試したときのブログ記事。

今回はCで記述したフィボナッチを求めるプログラムをSynverllを使って高位合成したRTLをMessagePack-RPCと組み合わせてシミュレーションする例を示します。

#用意するもの

 - Xilinx Vivado 2015.3
 - [Synverll 0.04以降](https://github.com/aquaxis/synverll)
 - LLVM 3.6 以降
 - 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
int fib(int n)
{
  int curr = 0;
  int next = 1;
  int i;
  for(i = 0; i < n; i++) {
    int prev = curr;
    curr = next;
    next += prev;
  }
  return curr;
}
````

#手順

##Synverllをインストール

Synverllのインストールは上の記事を参照してください。
Synverllをコンパイルするには LLVM 3.6 以降がインストールされていなければなりません。

````
shell% git clone https://github.com/aquaxis/synverll
shell% cd synverll
shell% make
````

##リポジトリと各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を高位合成

````
shell% cd examples/fibonacci/src/main/synverll
shell% synverll
Synverll Rev 0.04
 Synthesis for Verilog HDL using LLVM
 C Source to Verilog-HDL Convertor
 Hidemi Ishihara <hidemi(at)aquaxis.com>

Usage:
 synverll [-d] C_SOURCE_FILENAME
  -d: Debug Mode(output a debug file)

shell% synverll fib.c
topname: fib_top
[C Source Parser Start]
Open Filename: fib.c
 -> Parser for C Source
 -> Create Process Source
 -> Create Header Source
 -> Function Count: 1
[LLVM Compile Start]
[LLVM-IR Function Parser Start]
[Parsing struct type for LLCM-IR]
 -> Create Stage for LLVM-IR
 -> Parser Memory Tree
 -> deploy_array_type
 -> Create Verilog HDL for Proc Tree
 -> Output Verilog HDL: module = fib
 -> Output Memory Map
[Create top Module]
````

##ラッパー回路の作成

Synverllが生成するVerilog-HDLは次のようになっています。

````Verilog:fib.v
module fib(
	input __func_clock,
	input __func_reset,
	input __func_start,
	output reg __func_done,
	output reg __func_ready,

	// Memory Singal
	input [31:0] __args_n,
	// Call Singal
	// Result Singal
	output reg [31:0] __func_result

);
   :
 (中略)
   :
endmodule
````

入出力ポート名が、アンダーラインで始まっているので、このままだとVHDLの命名規則にひっかかって(VHDLはアンダーラインから始まる名前は×)接続できないので、ラッパー回路を用意します。ここはちょっと面倒臭いですね。

````Verilog:fib_wrap.v
module fib_wrap(
	input  system_clock,
	input  system_reset,
	input  func_start,
	output func_done,
	output func_ready,
	input [31:0]  args_n,
	output [31:0] func_result
);
fib u_fib(
	.__func_clock(system_clock),
	.__func_reset(system_reset),
	.__func_start(func_start),
	.__func_done(func_done),
	.__func_ready(func_ready),
	.__args_n(args_n),
	.__func_result(func_result)
);
endmodule
````

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

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

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

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

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

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

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

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

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

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

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

#結果
とりあえずシミュレーションすることは出来ました。
n=0～42までの計算結果もあっています。
演算のビット幅を64ビットにする方法がわからなかったので、結果が32ビットに収まる範囲のnでしか計算していません。
参考までにn=2の時のシミュレーション波形を示します。
![fibonacci_synverll.jpg](https://qiita-image-store.s3.amazonaws.com/0/24981/d75cca13-35e9-0e6c-3575-733ff0a1e684.jpeg)
シミュレーション時のログは次の通りです。
![fibonacci_synverll_log.jpg](https://qiita-image-store.s3.amazonaws.com/0/24981/0cab84ef-f118-c2a8-6e8b-9f80288cb7f1.jpeg)


#参考

- [ひでみのアイデア帳](http://www.sweetcafe.jp)
- [https://github.com/aquaxis/synverll](https://github.com/aquaxis/synverll)
- [msgpack-vhdl-examples](https://github.com/ikwzm/msgpack-vhdl-examples)
- [FPGAマガジン No.11](http://www.kumikomi.net/fpga/contents/0011.php)
- [FPGAの部屋のまとめサイト](http://marsee101.web.fc2.com/synverll.html) 
- [フィボナッチを求める回路をSynthesijerとMessagePack-RPCでFPGAに実装してみた(シミュレーション編)](http://qiita.com/ikwzm/items/6b3e8120cc4ebbdd5a27)
- [フィボナッチを求める回路をVHDLとMessagePack-RPCでFPGAに実装してみた(シミュレーション編)](http://qiita.com/ikwzm/items/a0ff6cf559f766162951)
- [フィボナッチを求める回路をPolyphonyとMessagePack-RPCでFPGAに実装してみた(シミュレーション編)](http://qiita.com/ikwzm/items/48acfa3003522cf0c7a3)
- [フィボナッチを求める回路をneonlightとMessagePack-RPCでFPGAに実装してみた(シミュレーション編)](http://qiita.com/ikwzm/items/1b7cae327719c23fe55d)