#はじめに
Synverllは石原ひでみさんが開発している高位合成ツールです。詳細は以下のページや記事を参照してください。
- ひでみのアイデア帳 : 石原ひでみさんのホームページです。
- https://github.com/aquaxis/synverll : Githubで公開しているSynverllのソースコード。
- FPGAマガジン No.11 : 95ページに記事があります。
- FPGAの部屋のまとめサイト : marsee101さんがSynverllを試したときのブログ記事。
今回はCで記述したフィボナッチを求めるプログラムをSynverllを使って高位合成したRTLをMessagePack-RPCと組み合わせてシミュレーションする例を示します。
#用意するもの
- Xilinx Vivado 2015.3
- Synverll 0.04以降
- LLVM 3.6 以降
- Ruby 1.9.3 以降
- msgpack-vhdl-examples
#ブロック図
#ソースコード
フィボナッチを求める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は次のようになっています。
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はアンダーラインから始まる名前は×)接続できないので、ラッパー回路を用意します。ここはちょっと面倒臭いですね。
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の時のシミュレーション波形を示します。
シミュレーション時のログは次の通りです。
#参考
- ひでみのアイデア帳
- https://github.com/aquaxis/synverll
- msgpack-vhdl-examples
- FPGAマガジン No.11
- FPGAの部屋のまとめサイト
- フィボナッチを求める回路をSynthesijerとMessagePack-RPCでFPGAに実装してみた(シミュレーション編)
- フィボナッチを求める回路をVHDLとMessagePack-RPCでFPGAに実装してみた(シミュレーション編)
- フィボナッチを求める回路をPolyphonyとMessagePack-RPCでFPGAに実装してみた(シミュレーション編)
- フィボナッチを求める回路をneonlightとMessagePack-RPCでFPGAに実装してみた(シミュレーション編)