Synverll

42
©2015, Hidemi Ishihara, All rights reserved. 2015年12月 8日 高位合成友の会@ドワンゴ Synverll AQUAXIS TECHNOLOGY ひでみ@hidemi_ishihara

Transcript of Synverll

©2015, Hidemi Ishihara, All rights reserved.

2015年12月 8日

高位合成友の会@ドワンゴSynverll

AQUAXIS TECHNOLOGYひでみ@hidemi_ishihara

2Synverll

最初はSynverllのご紹介から・・・

● Synverllとは● Synverllを作り始めた経緯● コンセプト● いまさらC言語?

処理方法のお話し・・・高位合成の結果って難しい・・・やってみよう・・・将来のお話し・・・

Vivado HLS WebPACK Editionでましたね

みんな、これ使えばええやん。

3Synverllとは

Synthesis for Verilog HDL using LLVM を略してみた。

● 読み方は「シンバール」

● LLVMを使用したCソースをVerilog HDLに変換する高位合成処理です。

4Synverllを作り始めた経緯

実は冬コミネタ(C89:三日目メ-13a:AQUAXIS)

● CソースをVerilog HDL手動トランスレートするのが面倒になってきた。● 前々、LLVMでなんとかならないかと思ってた。● 本当はひっそり、こっそり、開発するつもりだった。● 研究開発でも、プロダクトでもないです。

あくまで趣味です。

5コンセプト1FPGAの設計を楽しみましょう!

● 使い慣れた言語で楽してFPGAを設計したい● 出力されたRTLが気に入らなければ使わなければ良い!

● 強力な最適化エンジンを積んでいるわけではない。● 強力な最適化エンジンを開発するつもりもない。● あくまでLLVMでコンパイルして、Verilog HDLを出力するだけ。

なので、すごいRTLが出来上がるわけがない。

6コンセプト2「関数=モジュール」

● 関数=モジュールで出力されれば、気に入らないRTLを修正できるかも!● その代わり、I/Fはどの関数も同一になるように定義

Cソースで書いても、RTLで書いても一緒 ⇒ RTLで書かなくても良い⇒ 順次処理は向いている

最適化を期待するコード ⇒ 結果を見なければわからない⇒ 難しいソースコードがそうなってしまう ⇒ RTLが修正できたらいいなぁ

7コンセプト他アクセラレータIP● 何らかのバスにぶら下がるアクセラレータ的なモジュールになることを

想定している。

32bitアーキテクチャ● 32bitアーキテクチャを周到したステートマシンになる

8いまさらC言語を?世の中の高位合成処理はJavaやPythonが流行っているのに・・・

● なぜならば、私がJavaやPythonを使えないから・・・何度か挑戦したがなかなか、覚えられない・・・⇒ 使えてたらSynthesijer、PyCoRAMを使ってる。

● LegUpは?⇒ フリーなんだけど、出力されたRTLがALTERA教だったから。

9Synverll

好きな言語で楽して      開発したいよね。

処理方法のお話し・・・

● 展開方法● スケジューリング● 依存性のある処理● 関数のフラット化● メモリマップの一元化

高位合成の結果って難しい・・・やってみよう・・・将来のお話し・・・

10展開方法Cソースを関数単位で分解

● Synverllはひとつのファイルしか処理できません。

● Cソースを関数単位で分解し、関数をLLVMでコンパイルする。

● ここで-O3の最適化をかけます。● あくまで、LLVMでCソースをコンパ

イルするだけ・・・● そして、LLVM-IRの結果から単なるステートマシンのVerilog HDL化する。

hoge.c

LLVM LLVM LLVM

foo1.cfoo0.c foo2.c

foo1.llfoo0.ll foo2.ll

合成処理

foo1.vfoo0.v foo2.v

関数単位で分解

11スケジューリング

例えば、右のようにLLVM-IRが出力されたとする。合計、6ステップだが、m,n,oは同時に、x,yは同時に実行するよう配置する。つまり、3ステップでzが出力される。

m = a + b;n = c + d;o = e + f;x = m + n;y = m + o;z = x + y;

同時に実行して良い

同時に実行して良い同時に実行できない

LLVM-IRからVerilog HDLの段階で最適化を行う

● 依存性のない処理はどんどん、同時実行にする。

12依存性のある処理依存性のある処理とは

● 追い抜きが発生したら困る処理

foo0(...);foo1(...);

こういった場合、foo0とfoo1は関係無い関数に見える。しかし、もしかしたら、関数の中でメモリ操作をしているかもしれない。(どれくらい深いところでやっているかはわからない)

そうすると、メモリのアクセス順番によって結果が変わってしまう。追い抜きがかからないように必ず、foo0の後にfoo1を処理するようにスケジューリングを組む。

13関数のフラット化関数のフラット化とは

● Cソースでは階層構造で組み立てても、フラット展開する

⇒ Cの関数は同一時間に   同時に動作しないでしょう。 ⇒ つまり、スレッドは      意識していない。

void hoge(...){...foo_0(...);...foo_1(...);foo_1(...);

}

void foo_0(...){bar_0(...);...

}

void foo_1(...){bar_1(...);...

}

module top()hoge u_hoge();

  foo_0 u_foo_0();  foo_1 u_foo_1();

  bar_0 u_bar_0();  bar_1 u_bar_1();endmodule;

Cソースコード

Verilog HDL

14フラット化関数を使い回ししても、複製しない

hoge foo0 bar0

hoge_top

foo1 bar1

15メモリマップの一元化全ての関数のメモリを一元化する

● Cソースと同じようにメモリに支配されたモジュール群ができあがる⇒ 全てのモジュールのメモリが一元化される

関数ごとにメモリを持つほうが処理が効果的では?

● 関数ごとに配列メモリとか持ってしまうとI/Fが複雑になる● メモリの問題解決は上位のメモリ・コントローラで解決すればよい

16Synverll

最適化っておいしい? 高位合成処理の結果って難しい

● 最適化されたくないんですが

やってみよう・・・将来のお話し・・・

17最適化されたくないんですが・・・最適化の弊害・その1

● foo()が居なくなった

int foo( int x , int y ){

int ret;ret = x * y;return ret;

}

int hoge(...){

int a, b, c, d;int m, n;int z;

m = foo( a , b );n = foo( c , d );

z = m * n;}

int hoge(...){

int a, b, c, d;z = a * b * c * d;

}

18最適化されたくないんですが・・・最適化の弊害・その2

● foo()が居なくなった

int bar( int x , int y ){

xとyで複雑な計算;return 結果;

}

int foo( int x , int y ){

int ret;ret = x * y;return ret;

}

int hoge(...){

int a, b, c, d;int m, n;int z;

m = foo( a , b );n = foo( c , d );

z = bar( m , n );;}

int hoge(...){

int a, b, c, d;int m;int z;

m = a * b;n = c * d;

z = bar( m , n );}

barは残っている

19最適化されたくないんですが・・・最適化の弊害・その3

最適化したら・・・げげっ!100ステップのステートマシンになってしまった(苦笑)

この処理は時間がかかってもいい処理なんだけど、ループにしてよ。コンパイラはそんなことにはお構いなく、最適化してしまいます。将来、関数単位で最適化レベルを調整できるようにするつもり・・・

for(a=0;a<10;a++){for(b=0;b<10;b++){

c[a*10+b] = a * b;}

}

c[0] = 0 * 0;c[1] = 0 * 1;・・・c[98] = 9 * 8;c[99] = 9 * 9;

20Synverll

動かしてみる

やってよう・・・

● 想定しているソースコード● PC上で開発するときは・・・● 実行方法● 生成物● 制約は?● ライブラリは?

将来のお話し・・・

21こんなソースコードを想定しているhoge.c

void hoge(...){...foo_0(...);...foo_1(...);foo_1(...);

}

void bar_0(...){

...}

void foo_0(...){

...bar_0(...);...

}

void bar_1(...){

...}

void foo_1(...){

...bar_1(...);...

}

Synverllはひとつのファイルしか処理しない

22PC上で開発するときは・・・別のソースコードからhoge()を呼び出して使って検証する

% gcc -o main hoge.c main.c% ./main

void main(){

...

hoge(...);

...}

void hoge(...){...foo_0(...);...foo_1(...);foo_1(...);

}

main.c hoge.c

23実行方法Synverllビルド

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

実行方法

% ./synverll hoge.c

24生成物・その1Verilog HDLモジュールhoge_top.v

hoge.vfoo0.vfoo1.vbar0.vbar1.v

hoge.v foo0.v bar0.v

hoge_top.v

foo1.v bar1.v

25生成物・その2モジュール module RGB2YCbCr(

input __func_clock,input __func_reset,input __func_start,output reg __func_done,output reg __func_ready,

// Global Memoryinput [31:0] __gm_base,output reg __gm_req,output reg __gm_rnw,input __gm_done,output reg [31:0] __gm_adrs,output reg [1:0] __gm_leng,input [31:0] __gm_di,output reg [31:0] __gm_do,

// Memory Singalinput [31:0] __base_buffer,input [15:0] __args_xpos,input [15:0] __args_ypos,// Call Singal// Result Singaloutput reg __func_result

);

制御信号

メモリーインターフェース

引数

戻り値

26生成物・その3メモリマップ

一元化された メモリマップが   出力される。

======================================================================Memory Map======================================================================[GLOBAL/LOCAL] [MEMORY NAME] [ADDRESS] [SIZE]GLOBAL @jpeg_ptr 00000000 4GLOBAL @APP0info 00000004 18<<<中略>>>GLOBAL @CbAC_HT 00000808 768@DCT %datalong 00000b08 256GLOBAL @DU_DCT 00000c08 128GLOBAL @zigzag 00000c88 64GLOBAL @DU 00000cc8 128@process_DU %calc_data 00000d48 4@process_DU %1 00000d4c 4<<<中略>>>@process_DU %7 00000d64 4@process_DU %8 00000d68 4<<<中略>>>@main_encoder %DCY 00000ef4 2@main_encoder %DCCb 00000ef8 2@main_encoder %DCCr 00000efc 2@main_encoder %DU 00000f00 64@create_jpeg %fillbits 00000f40 3======================================================================

27こんなことができるtempはFPGA内部メモリ、bufはFPGA外部メモリとすることができる

void hoge(char *buf){

int i;char temp[10];

for(i=0;i<10;i++){tmep[i] = ...;

}

for(i=0;i<10;i++){buf[i] = temp[i];

}}

void main(){

char buf[10];

...

hoge(buf);

...}

main.c hoge.c

28構成イメージ

hoge foo0 bar0

hoge_top

foo1 bar1

reg ctrl DMA ctrl memory

CPU memory

バス

CPUサイド

FPGAサイド 一元化された内部メモリ

外部メモリ

29制約は?たくさんあってまとまってない!

まずは私が書くCソースが神ソースコードである。

昔、System CをVerilog HDL化しようとして挫折した。結局、自分のソースコードしか展開できないから、放置した。今回は、C言語にしたので、制約は少なくなるはず・・・

3032bitアーキテクチャ4Byteアライメント4Byteアライメントでないメモリアクセスはデータがバグる。

例えば、こんな構造体

struct foo{char a;short b;

} S_FOO;

struct hoge{foo[10];

} S_HOGE;

31ライブラリは?現状 32bit除算器AXI4 Master Read/WriteAXI4 Lite Slave

将来半精度、単精度、倍精度を準備したい。32bitアーキテクチャなので倍精度は後回し。

LLVM Standard Libraryよく使用するものから対応していく。

32Synverll

将来にむけて

将来のお話し

● 処理単位でVerilog HDL化● ストリーム対応は?● パイプライン化● アクセラレート● シミュレーション● OpenCVアクセラレート● ロードマップ

33処理単位でVerilog HDL化全てのソースコードを一括して高位合成処理しようとは考えていない

例えば、次のような流れの回路を作るようなことを想定している・・・

hoge_0FIFO

hoge_1FIFO FIFO

34処理単位でCソースをVerilog HDL化ソースを分割してSynverllにかける

void hoge_0(...){

...}

void hoge_1(...){

...}

void main(){

...

hoge_0(...);hoge_1(...);

...}

main.c hoge0.c hoge1.c

35ストリームの対応は?ストリーム構想● 将来、対応するかも・・・● ただし、制約が付くだろう。

36パイプライン化パイプライン構想処理依存しない関数であれば、関数単位でのパイプライン化又は同時実行を検討している。

int foo(int a, int b){ int c; c = a * b;

return c;}

hoge (){ int a0,a1,a2;

int b0,b1,b2;int c0,c1,c2;

...

c0 = foo(a0, b0);c1 = foo(a1, b1);c2 = foo(a2, b2);

}

37アクセラレートmain関数はCPUで稼動させ、hoge関数をFPGAでアクセラレートする

void main(){

char buf[10];

...

#ifdef SOURCEhoge(buf);

#elsehoge.buf = buf;while(!hoge.ready);hoge.start = 1;while(!hoge.ready);hoge.start = 0;while(!hoge.done);

#endif

...}

38Cテストアプリを使ってシミュレーションしたいシミュレーション構想Cソースで使ったテストアプリを そのまま、使って  実機シミュレーションしたい!

テストベンチをもう一度、      書くのなんて嫌だ!

シミュレータなんて遅いから嫌だ!

void main(){

char buf[10];

...

#ifdef SOURCEhoge(buf);

#elsehoge.buf = buf;while(!hoge.ready);hoge.start = 1;while(!hoge.ready);hoge.start = 0;while(!hoge.done);

#endif

...}

39OpenCVアクセラレータアクセラレーション構想OpenCV関数のうち、C APIとなっている関数で自分が良く使うものをH/Wアクセラレータとしてライブラリ化して、Cソースの書き方でパイプライン化するようにしたい。

cvAdd(dst=B, src=A);cvSub(dst=C, src=B);...

cvAddとcvSubのポインタが連動していれば、パイプライン化発動!

cvAdd_cvSub(dst=C, src=A); とか・・・

p.s.ただし、フォーマットはcvMatに限定するかも・・・

40ロードマップ全てはコミケの当選に委ねられている

全体的に

ライブラリ的に

最適化的に

12/31 '16/3末 '16/7末 '16/9末 '16/12/31

もし、夏コミに当選したらここでV2.0にする

ベータ版 Cテスト対応

浮動小数点

関数単位での最適化

OpenCVライブラリ

41ひょっとして、LLVM-IRの高位合成処理系?実はできます・・・

LLVM-IRの高位合成処理として使ってみたい!

⇒ オープンソースなのでご自由に改変してくださいませ!

42楽して開発したいよFPGAは規模も大きいし、これにプロセッサまで付いたら・・・

とにかく開発工数が多くて面倒!好きな言語で好きなエディタ使って、好きなツール使って、楽にシステム開発したいよ。

出力コードが気に入らないなら修正すればいいんじゃないの?HDL変換する参考のコード程度でも良いかな?

                           以上っす。