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

#はじめに

Neon Light は、たばたさんが開発している、高位合成のためにオブジェクト指向スクリプト言語を用いた処理系です。詳細は以下のページを参照してください。

- [Neon light compiler](https://sites.google.com/site/neonlightcompiler/home)
- [https://github.com/nlsynth/nli](https://github.com/nlsynth/nli)

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

 - 編集履歴1 neonlight compiler 0.1.9 からは channel が導入されました。この記事はその channel を使うように再編集しました。
 - 編集履歴2 開発者のたばたさんの指摘で演算結果を64ビットにする方法がわかりましたので、対応してみました。


#用意するもの

 - Xilinx Vivado 2015.3
 - [Neon Light Compiler](https://github.com/nlsynth/nli) 0.1.9 以降
 - 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)


#ソースコード

フィボナッチを求める Neon Light スクリプトです。

````:Fib.n
object Fib = Kernel.clone();
object Global.Fib = Fib;

channel Fib.param  = int;
channel Fib.result = int #64;

def Fib.fib(int n) (int #64){
  int #64 curr;
  int #64 next;
  int #64 prev;
  int i;
  curr = 0;
  next = 1;
  for (i = 0; i < n; ++i) {
    prev = curr;
    curr = next;
    next = next + prev;
  }
  return curr;
}

def Fib.main() {
  while(true) {
    *result = fib(*param);
  }
}

if (Env.isMain()) {
  Fib.setDump("./tmp/fib");
  Fib.compile();
  Fib.writeHdl("fib.v");
  Fib.writeHdl("fib.cpp");
}
````

#手順

##Neon Light Compilerをインストール

````shell
shell% git clone https://github.com/nlsynth/nli.git
shell% cd nli
shell% ./configure; 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.nを高位合成

````
shell% cd examples/fibonacci/src/main/neonlight
shell% nli fib.n
print: default.n loaded
src/synth/synth.cpp:53:Synth start
output html file name=(./tmp/fib.0.raw.html)
output html file name=(./tmp/fib.1.expanded.html)
output html file name=(./tmp/fib.2.opt_pure_temp_variable_elimination.html)
output html file name=(./tmp/fib.3.opt_basic_block_shrink.html)
output html file name=(./tmp/fib.4.opt_ssa.html)
output html file name=(./tmp/fib.5.opt_ssa_assorted.html)
output html file name=(./tmp/fib.6.opt_ssa_cleanup.html)
output html file name=(./tmp/fib.7.opt_register_share.html)
output html file name=(./tmp/fib.8.opt_basic_block_shrink.html)
output html file name=(./tmp/fib.9.opt_resource_alloc.html)
output html file name=(./tmp/fib.10.optimized.html)
output html file name=(./tmp/fib.11.ll.html)
I:output file name=fib.v
I:output file name=fib.cpp
````

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

すでに作成済みのテストシナリオ(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/neonlight/create_project.tcl
````

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

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

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

#結果
とりあえずシミュレーションすることは出来ました。
n=0～93までの計算結果もあっています。
~~演算のビット幅を64ビットにする方法がわからなかったので、結果が32ビットに収まる範囲のnでしか計算していません。~~
参考までにn=2の時のシミュレーション波形を示します。
![fibonacci_neonlight_wave_2.jpg](https://qiita-image-store.s3.amazonaws.com/0/24981/37a19127-4975-125c-2dad-2211fb92c1db.jpeg)
シミュレーション時のログは次の通りです。
![fibonacci_neonligt_log_2.jpg](https://qiita-image-store.s3.amazonaws.com/0/24981/1609f062-ccce-dc81-5737-9cc645706860.jpeg)

#参考

- [Neon light compiler](https://sites.google.com/site/neonlightcompiler/home)
- [https://github.com/nlsynth/nli](https://github.com/nlsynth/nli)
- [msgpack-vhdl-examples](https://github.com/ikwzm/msgpack-vhdl-examples)
- [フィボナッチを求める回路をVHDLとMessagePack-RPCでFPGAに実装してみた(シミュレーション編)](http://qiita.com/ikwzm/items/a0ff6cf559f766162951)
- [フィボナッチを求める回路をSynthesijerとMessagePack-RPCでFPGAに実装してみた(シミュレーション編)](http://qiita.com/ikwzm/items/6b3e8120cc4ebbdd5a27)
- [フィボナッチを求める回路をPolyphonyとMessagePack-RPCでFPGAに実装してみた(シミュレーション編)](http://qiita.com/ikwzm/items/48acfa3003522cf0c7a3)
- [フィボナッチを求める回路をSynverllとMessagePack-RPCでFPGAに実装してみた(シミュレーション編)](http://qiita.com/ikwzm/items/37e496680e44d4b80347)