#はじめに
高位合成友の会第三回(2015年12月8日)で発表のあった高位合成ツールの中で、唯一、当日までに試すことの出来なかった FortRock ですが、ちょっと遅れましたがフィボナッチを求める回路を記述してシミュレーションしてみました。
FortRock は LLVMを用いた Fortran ベースの高位合成ツールです。
高位合成友の会での FortRock の発表スライドはこちらです。
#用意するもの
- Xilinx Vivado 2015.3
- FortRock
- clang++-3.6 (FortRock をコンパイルするのに必要)
- gfortran-4.8 (FortRock で高位合成するのに必要)
- LLVM 3.4 (FortRock で高位合成するのに必要)
- dragonegg-4.8 (FortRock で高位合成するのに必要)
- Ruby 1.9.3 以降
- msgpack-vhdl-examples
#ブロック図
#ソースコード
フィボナッチを求めるFortranのソースコードです。
SUBROUTINE FIB(N,O)
INTEGER N,O,I,CURR,NEXT,PREV
CURR = 0
NEXT = 1
I = 0
0001 CONTINUE
IF(I >= N)THEN
GOTO 0002
ENDIF
PREV = CURR
CURR = NEXT
NEXT = NEXT + PREV
I = I + 1
GOTO 0001
0002 CONTINUE
O = CURR
RETURN
END
#手順
##事前の準備
FortRock を使うためには、gfortran-4.8、dragonegge-4.8、llvm-3.4 が必要です。
また、FortRock をコンパイルするのに clang++-3.6 が必要です。
shell% sudo apt-get install gfortran-4.8
shell% sudo apt-get install dragonegge-4.8
shell% sudo apt-get install llvm-3.4
```
##FortRock をインストール
shell% git clone https://github.com/nyakuo/FortRock.git
shell% cd FortRock/src
shell% make
これで FortRock/src/ に fortrock.so が出来ていれば、成功です。
##msgpack-vhdl-examplesリポジトリと各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.f をテスト
今回、初めてFortran を使うので、試しに次のようなプログラムを作って fib.f をテストしました。
````Fortran:fib_test.f
program fib_test
implicit none
integer i, n, o
n = 7
i = 0
1000 call fib(i,o)
print *,i,o
if (i < n) then
i = i + 1
goto 1000
endif
end
shell% cd examples/fibonacci/src/main/fortrock
shell% gfortran-4.8 -O1 -o ./fib_test ./fib_test.f ./fib.f
shell% ./fib_test
0 0
1 1
2 1
3 2
4 3
5 5
6 8
7 13
##fib.fをFortRockで高位合成
shell% cd examples/fibonacci/src/main/fortrock
shell% gfortran-4.8 -O1 ./fib.f -fplugin=/usr/lib/gcc/x86_64-linux-gnu/4.8/plugin/dragonegg.so -fplugin-arg-dragonegg-emit-ir -S -o ./0fib00.s
shell% opt-3.4 -load ~/work/FortRock/src/fortrock.so -instnamer -fortrock ./0fib00.s -S
opt-3.4: CommandLine Error: Argument 'info-output-file' defined more than once!
opt-3.4: CommandLine Error: Argument 'track-memory' defined more than once!
opt-3.4: CommandLine Error: Argument 'version' defined more than once!
opt-3.4: CommandLine Error: Argument 'print-all-options' defined more than once!
opt-3.4: CommandLine Error: Argument 'print-options' defined more than once!
opt-3.4: CommandLine Error: Argument 'help-hidden' defined more than once!
opt-3.4: CommandLine Error: Argument 'help' defined more than once!
opt-3.4: CommandLine Error: Argument 'help-list-hidden' defined more than once!
opt-3.4: CommandLine Error: Argument 'help-list' defined more than once!
opt-3.4: CommandLine Error: Argument 'time-passes' defined more than once!
opt-3.4: CommandLine Error: Argument 'print-after-all' defined more than once!
opt-3.4: CommandLine Error: Argument 'print-before-all' defined more than once!
opt-3.4: CommandLine Error: Argument 'print-after' defined more than once!
opt-3.4: CommandLine Error: Argument 'print-before' defined more than once!
opt-3.4: CommandLine Error: Argument 'debug-pass' defined more than once!
; ModuleID = './0fib00.s'
target datalayout = "e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64--linux-gnu"
module asm "\09.ident\09\22GCC: (Ubuntu 4.8.4-1ubuntu15) 4.8.4 LLVM: 3.4.2\22"
; Function Attrs: nounwind uwtable
define void @fib_(i32* noalias nocapture readonly %n, i32* noalias nocapture %o) unnamed_addr #0 {
entry:
%tmp = load i32* %n, align 4
%tmp1 = icmp sgt i32 %tmp, 0
br i1 %tmp1, label %"4.lr.ph", label %"5"
"4.lr.ph": ; preds = %entry
%tmp2 = load i32* %n, align 4
br label %"4"
"4": ; preds = %"4", %"4.lr.ph"
%tmp3 = phi i32 [ 1, %"4.lr.ph" ], [ %tmp6, %"4" ]
%tmp4 = phi i32 [ 0, %"4.lr.ph" ], [ %tmp7, %"4" ]
%tmp5 = phi i32 [ 0, %"4.lr.ph" ], [ %tmp3, %"4" ]
%tmp6 = add i32 %tmp3, %tmp5
%tmp7 = add i32 %tmp4, 1
%tmp8 = icmp sgt i32 %tmp2, %tmp7
br i1 %tmp8, label %"4", label %"5"
"5": ; preds = %"4", %entry
%.lcssa = phi i32 [ 0, %entry ], [ %tmp3, %"4" ]
store i32 %.lcssa, i32* %o, align 4
ret void
}
attributes #0 = { nounwind uwtable "no-frame-pointer-elim-non-leaf"="false" }
途中で出力するLLVMファイルの名前が 0fib00.s としているのは、何故かモジュール名の前に1文字、後ろに2文字つけないと、Verilog-HDL のモジュール名が正常に生成されないからです。
また、opt-3.4 で CommandLine Error が出ていますが、とりあえず気にしないでください。
output.v が生成されていれば成功です。
なお、output.v を Verilog でシミュレーション/論理合成するには、Add、multiplier、Divider等の演算モジュールが必要です。実際には Add しか使わないのですが、何故か output.v には multiplier と Divider のインスタンスも含まれているのでとりあえずダミーでもいいから用意しておきます。
module Add(a,b,clk,ce,s);
input signed[31:0] a;
input signed[31:0] b;
input clk;
input ce;
output signed[31:0] s;
reg signed[31:0] s;
always @(posedge clk)
if (ce)
s <= a + b;
endmodule
module multiplier(a,b,clk,ce,p);
input signed[31:0] a;
input signed[31:0] b;
input clk;
input ce;
output signed[31:0] p;
reg signed[31:0] p;
always @(posedge clk)
if (ce)
p <= a * b;
endmodule
module Divider(dividend,divisor,clk,quotient,fractional,rfd);
input signed[31:0] dividend;
input signed[31:0] divisor;
input clk;
output signed[31:0] quotient;
output signed[31:0] fractional;
output signed[31:0] rfd;
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/fortrock/create_project.tcl
##シミュレーションを実行
前節で作った Vivado プロジェクトを開き、次のようにシミュレーションを実行してください。
Vivado > Flow > Run Simulation > Run Behavioral Simulation
#結果
とりあえずシミュレーションすることは出来ました。
n=0~42までの計算結果もあっています。
参考までにn=2の時のシミュレーション波形を示します。
#参考
- LLVMを用いたFortranベースの高位合成ツールFortRockの開発
- https://github.com/nyakuo/FortRock
- msgpack-vhdl-examples
- フィボナッチを求める回路をSynthesijerとMessagePack-RPCでFPGAに実装してみた(シミュレーション編)
- フィボナッチを求める回路をVHDLとMessagePack-RPCでFPGAに実装してみた(シミュレーション編)
- フィボナッチを求める回路をPolyphonyとMessagePack-RPCでFPGAに実装してみた(シミュレーション編)
- フィボナッチを求める回路をSynverllとMessagePack-RPCでFPGAに実装してみた(シミュレーション編)
- フィボナッチを求める回路をneonlightとMessagePack-RPCでFPGAに実装してみた(シミュレーション編)