Mais conteúdo relacionado Semelhante a Synthesijer fpgax 20150201 (20) Mais de Takefumi MIYOSHI (20) Synthesijer fpgax 201502012. 2014 年 8 月 2015 年 1 月
0
5
10
15
20
25
30
35
40
45
x20
3. 2014 年 8 月 2015 年 1 月
0
5
10
15
20
25
30
35
40
45
x20
高位合成を実装する人達の
飲み会 # 2014.8.3
高位合成友の会
# 2015.1.16
4. 4
高位合成友の会(恋友)
✔ 豊島さん: 「両刀使いエンジニアは高位合成ツールの夢を見るか?」
✔ たばたさん: Neon light compiler - http://goo.gl/JEhlyn
✔ みよし: Synthesijer – http://goo.gl/2w3J6Z
✔ 高前田さん: PyCoRAM – http://goo.gl/0b16rr
論理回路の高位合成について試作した実装と
アイデアと妄想について語る会
http://hls.connpass.com/event/11009/
13. 13
鍵はパイプライン並列化
パケットデータが d [byte] のとき全データ入力を受け取るのにかかる時間 = (d/w)*(1/f) [sec]
同様に、全データの出力にかかる時間 = (d/w)*(1/f) [sec]
スループットT [bps]を実現するとき、パケットデータを(8*d)*(1/T) [sec]内で処理し続ける必要がある
→ 各モジュールで処理に使える時間 t は 8*d/T-2*d/(w*f) [sec] → (8*d/T-2*d/(w*f))/(1/f) [cycle]
たとえば、d=1500, T=1G, w=4, f=100Mのとき
1パケットあたりの処理にかけられるサイクル数は450サイクル.
f=200Mなら1650サイクル,w=16なら1012サイクル
T=10Gの場合,w=16,f=200M でも 52サイクル
FIFO
スループット T [bps]
w [byte]
f [Hz]
実行
ステージ
FIFO
実行
ステージ
実行
ステージ
とはいえ,各ステージで状態遷移のある処理が必要
14. 14
鍵はパイプライン並列化
パケットデータが d [byte] のとき全データ入力を受け取るのにかかる時間 = (d/w)*(1/f) [sec]
同様に、全データの出力にかかる時間 = (d/w)*(1/f) [sec]
スループットT [bps]を実現するとき、パケットデータを(8*d)*(1/T) [sec]内で処理し続ける必要がある
→ 各モジュールで処理に使える時間 t は 8*d/T-2*d/(w*f) [sec] → (8*d/T-2*d/(w*f))/(1/f) [cycle]
たとえば、d=1500, T=1G, w=4, f=100Mのとき
1パケットあたりの処理にかけられるサイクル数は450サイクル.
f=200Mなら1650サイクル,w=16なら1012サイクル
T=10Gの場合,w=16,f=200M でも 52サイクル
FIFO
スループット T [bps]
w [byte]
f [Hz]
実行
ステージ
FIFO
実行
ステージ
実行
ステージ
とはいえ,各ステージで状態遷移のある処理が必要
限られた
許容サイクルを
効率よく使う必要
25. 25
Synthesijer とは
✔ JavaプログラムをFPGA上のハードウェアに変換
✔ 複雑なアルゴリズムのハードウェア実装を楽に
✔ オブクジェクト指向設計による再利用性の向上
✔ 特殊な記法,追加構文はない
✔ ソフトウェアとして実行可能.動作の確認、検証が容易
✔ 書けるプログラムに制限は加える
(動的なnew,再帰は不可など)
✔ HDLモジュールのJavaからのインスタンス生成
Javaコンパイラ
フロントエンド
Synthesijer
エンジン
Javaコンパイラ
バックエンド
合成
配置配線
while(){
if(...){
…
}else{
…
…
}
….
}
複雑な状態遷移も,Javaの制御構文を使って楽に設計できる
同じJavaプログラムをソフトウェアとしても
FPGA上のハードウェアとしても実行可能
Open-source
26. 26
Synthesijer 開発の経緯
✔ 2009年頃 Bluespecに感銘を受ける
✔ 2010年12月頃 高位合成処理系を作ってみたい→Javaベースに
✔ 2011年7月
JavaRockの開発を開始
JavaをVHDLに変換する.1文1ステート→簡単な並列化
✔ 2012(?)年〜2013年
農工大中條研小池さんによるJavaRock-Thrashの開発
種々の最適化の実装など
✔ 2014年
Synthesijerとして名称をあらため開発を再スタート
JavaRock/JavaRock-Thrashの実装を通じた知見の活用
なぜか
27. 27
参考
✔ http://synthesijer.sourceforge.net
✔ リソース一式,クイックスタートガイドなど
✔ http://qiita.com/kazunori279/items/4951ca5f6164040878ce
✔ Synthesijer関連資料まとめ
✔ http://labs.beatcraft.com/ja/index.php?Synthesijer
✔ Altera DE0-nanoでのサンプルの動作手順など
(ビートクラフト様)
✔ http://marsee101.blog19.fc2.com/blog-category-116.html
✔ FPGAの部屋: Synthesijerでラプラシアンフィルタを作ってみた
✔ http://wasa-labo.com/wp/
✔ わさらぼ ブログ – 開発状況,Tipsなど
38. 38
Synthesijer でのHDL生成: 例題
package blink_led;
public class BlinkLED {
public boolean led;
public void run(){
while(true){
led = true;
for(int i = 0; i < 5000000; i++) ;
led = false;
for(int i = 0; i < 5000000; i++) ;
}
}
}
39. 39
Synthesijer でのHDL生成: 大枠
class
entity blink_led_BlinkLED is
port (
clk : in std_logic;
reset : in std_logic;
field_led_output : out std_logic;
field_led_input : in std_logic;
field_led_input_we : in std_logic;
run_req : in std_logic;
run_busy : out std_logic
);
end blink_led_BlinkLED;
class BlinkLED {
public boolean led;
public void run(){
while(true){
…
}
}
}
module
クラス毎にHWモジュールを生成
40. 40
Synthesijer でのHDL生成: スケジュール表
メソッド毎にスケジュール表を生成
run_0000: op=METHOD_EXIT, src=, dest=, next=0001
run_0001: op=METHOD_ENTRY, src=, dest=, next=0002 (name=run)
run_0002: op=JT, src=true:BOOLEAN, dest=, next=0004, 0003
run_0003: op=JP, src=, dest=, next=0023
run_0004: op=ASSIGN, src=true:BOOLEAN, dest=class_led_0000:BOOLEAN, next=0005
run_0005: op=ASSIGN, src=0:INT, dest=run_i_0001:INT, next=0006
run_0006: op=LT, src=run_i_0001:INT, 5000000:INT, dest=binary_expr_00002:BOOLEAN, next=0007
run_0007: op=JT, src=binary_expr_00002:BOOLEAN, dest=, next=0012, 0008
run_0008: op=JP, src=, dest=, next=0013
run_0009: op=ADD, src=run_i_0001:INT, 1:INT, dest=unary_expr_00003:INT, next=0010
run_0010: op=ASSIGN, src=unary_expr_00003:INT, dest=run_i_0001:INT, next=0011
run_0011: op=JP, src=, dest=, next=0006
run_0012: op=JP, src=, dest=, next=0009
run_0013: op=ASSIGN, src=false:BOOLEAN, dest=class_led_0000:BOOLEAN, next=0014
run_0014: op=ASSIGN, src=0:INT, dest=run_i_0004:INT, next=0015
run_0015: op=LT, src=run_i_0004:INT, 5000000:INT, dest=binary_expr_00005:BOOLEAN, next=0016
run_0016: op=JT, src=binary_expr_00005:BOOLEAN, dest=, next=0021, 0017
run_0017: op=JP, src=, dest=, next=0022
run_0018: op=ADD, src=run_i_0004:INT, 1:INT, dest=unary_expr_00006:INT, next=0019
run_0019: op=ASSIGN, src=unary_expr_00006:INT, dest=run_i_0004:INT, next=0020
run_0020: op=JP, src=, dest=, next=0015
run_0021: op=JP, src=, dest=, next=0018
run_0022: op=JP, src=, dest=, next=0002
run_0023: op=JP, src=, dest=, next=0000
43. 43
Synthesijer でのHDL生成: 状態遷移
状態遷移機械に相当するステートマシンをベタに作る
always @(posedge clk) begin
if(reset == 1'b1) begin
run_method <= run_method_IDLE;
run_method_delay <= 32'h0;
end else begin
case (run_method)
run_method_IDLE : begin
run_method <= run_method_S_0000;
end
run_method_S_0000 : begin
run_method <= run_method_S_0001;
run_method <= run_method_S_0001;
end
run_method_S_0001 : begin
if (run_req_flag == 1'b1) begin
run_method <= run_method_S_0002;
end
end
run_method_S_0002 : begin
if (tmp_0003 == 1'b1) begin
run_method <= run_method_S_0004;
end else if (tmp_0004 == 1'b1) begin
run_method <= run_method_S_0003;
end
end
run_method_S_0003 : begin
...
44. 44
Synthesijer でのHDL生成: 出力(データ操作)
メソッド毎にスケジュール表を生成 → 文/式相当のデータ操作
run_0000: op=METHOD_EXIT, src=, dest=, next=0001
run_0001: op=METHOD_ENTRY, src=, dest=, next=0002 (name=run)
run_0002: op=JT, src=true:BOOLEAN, dest=, next=0004, 0003
run_0003: op=JP, src=, dest=, next=0023
run_0004: op=ASSIGN, src=true:BOOLEAN, dest=class_led_0000:BOOLEAN, next=0005
run_0005: op=ASSIGN, src=0:INT, dest=run_i_0001:INT, next=0006
run_0006: op=LT, src=run_i_0001:INT, 5000000:INT, dest=binary_expr_00002:BOOLEAN, next=0007
run_0007: op=JT, src=binary_expr_00002:BOOLEAN, dest=, next=0012, 0008
run_0008: op=JP, src=, dest=, next=0013
run_0009: op=ADD, src=run_i_0001:INT, 1:INT, dest=unary_expr_00003:INT, next=0010
run_0010: op=ASSIGN, src=unary_expr_00003:INT, dest=run_i_0001:INT, next=0011
run_0011: op=JP, src=, dest=, next=0006
run_0012: op=JP, src=, dest=, next=0009
run_0013: op=ASSIGN, src=false:BOOLEAN, dest=class_led_0000:BOOLEAN, next=0014
run_0014: op=ASSIGN, src=0:INT, dest=run_i_0004:INT, next=0015
run_0015: op=LT, src=run_i_0004:INT, 5000000:INT, dest=binary_expr_00005:BOOLEAN, next=0016
run_0016: op=JT, src=binary_expr_00005:BOOLEAN, dest=, next=0021, 0017
run_0017: op=JP, src=, dest=, next=0022
run_0018: op=ADD, src=run_i_0004:INT, 1:INT, dest=unary_expr_00006:INT, next=0019
run_0019: op=ASSIGN, src=unary_expr_00006:INT, dest=run_i_0004:INT, next=0020
run_0020: op=JP, src=, dest=, next=0015
run_0021: op=JP, src=, dest=, next=0018
run_0022: op=JP, src=, dest=, next=0002
run_0023: op=JP, src=, dest=, next=0000
45. 45
Synthesijer でのHDL生成: 出力(データ操作)
メソッド毎にスケジュール表を生成 → 文/式相当のデータ操作
run_0000: op=METHOD_EXIT, src=, dest=, next=0001
run_0001: op=METHOD_ENTRY, src=, dest=, next=0002 (name=run)
run_0002: op=JT, src=true:BOOLEAN, dest=, next=0004, 0003
run_0003: op=JP, src=, dest=, next=0023
run_0004: op=ASSIGN, src=true:BOOLEAN, dest=class_led_0000:BOOLEAN, next=0005
run_0005: op=ASSIGN, src=0:INT, dest=run_i_0001:INT, next=0006
run_0006: op=LT, src=run_i_0001:INT, 5000000:INT, dest=binary_expr_00002:BOOLEAN, next=0007
run_0007: op=JT, src=binary_expr_00002:BOOLEAN, dest=, next=0012, 0008
run_0008: op=JP, src=, dest=, next=0013
run_0009: op=ADD, src=run_i_0001:INT, 1:INT, dest=unary_expr_00003:INT, next=0010
run_0010: op=ASSIGN, src=unary_expr_00003:INT, dest=run_i_0001:INT, next=0011
run_0011: op=JP, src=, dest=, next=0006
run_0012: op=JP, src=, dest=, next=0009
run_0013: op=ASSIGN, src=false:BOOLEAN, dest=class_led_0000:BOOLEAN, next=0014
run_0014: op=ASSIGN, src=0:INT, dest=run_i_0004:INT, next=0015
run_0015: op=LT, src=run_i_0004:INT, 5000000:INT, dest=binary_expr_00005:BOOLEAN, next=0016
run_0016: op=JT, src=binary_expr_00005:BOOLEAN, dest=, next=0021, 0017
run_0017: op=JP, src=, dest=, next=0022
run_0018: op=ADD, src=run_i_0004:INT, 1:INT, dest=unary_expr_00006:INT, next=0019
run_0019: op=ASSIGN, src=unary_expr_00006:INT, dest=run_i_0004:INT, next=0020
run_0020: op=JP, src=, dest=, next=0015
run_0021: op=JP, src=, dest=, next=0018
run_0022: op=JP, src=, dest=, next=0002
run_0023: op=JP, src=, dest=, next=0000
...
assign tmp_0010 = run_i_0001 + 32'h00000001;
...
always @(posedge clk) begin
if(reset == 1'b1) begin
run_i_0001 <= 32'h00000000;
end else begin
if (run_method == run_method_S_0004) begin
run_i_0001 <= 32'h00000000;
end else if (run_method == run_method_S_0010) begin
run_i_0001 <= unary_expr_00003;
end
end
end
...
always @(posedge clk) begin
if(reset == 1'b1) begin
unary_expr_00003 <= 0;
end else begin
if (run_method == run_method_S_0009) begin
unary_expr_00003 <= tmp_0010;
end
end
end
...
47. 47
たとえば
public void test(){
boolean success = false;
int a = 10;
int b = 20;
int c = 0;
int d = 40;
int e = 50;
int f = 0;
int g = 70;
int h = 80;
int i = 0;
int j = 100;
int k = 110;
int l = 0;
c = a + b;
f = d + e;
i = g + h;
l = j + k;
c = c + f;
l = l + i;
c = c + l;
if(c == 10+20+40+50+70+80+100+110) success = true;
boolean success2 = check(c);
}
48. 48
たとえば
test_0000: op=METHOD_EXIT, src=, dest=, next=0001
test_0001: op=METHOD_ENTRY, src=, dest=, next=0002 (name=test)
test_0002: op=ASSIGN, src=false:BOOLEAN, dest=test_success_0009:BOOLEAN, next=0003
test_0003: op=ASSIGN, src=10:INT, dest=test_a_0010:INT, next=0004
test_0004: op=ASSIGN, src=20:INT, dest=test_b_0011:INT, next=0005
test_0005: op=ASSIGN, src=0:INT, dest=test_c_0012:INT, next=0006
test_0006: op=ASSIGN, src=40:INT, dest=test_d_0013:INT, next=0007
test_0007: op=ASSIGN, src=50:INT, dest=test_e_0014:INT, next=0008
test_0008: op=ASSIGN, src=0:INT, dest=test_f_0015:INT, next=0009
test_0009: op=ASSIGN, src=70:INT, dest=test_g_0016:INT, next=0010
test_0010: op=ASSIGN, src=80:INT, dest=test_h_0017:INT, next=0011
test_0011: op=ASSIGN, src=0:INT, dest=test_i_0018:INT, next=0012
test_0012: op=ASSIGN, src=100:INT, dest=test_j_0019:INT, next=0013
test_0013: op=ASSIGN, src=110:INT, dest=test_k_0020:INT, next=0014
test_0014: op=ASSIGN, src=0:INT, dest=test_l_0021:INT, next=0015
test_0015: op=ADD, src=test_a_0010:INT, test_b_0011:INT, dest=binary_expr_00022:INT, next=0016
test_0016: op=ASSIGN, src=binary_expr_00022:INT, dest=test_c_0012:INT, next=0017
test_0017: op=ADD, src=test_d_0013:INT, test_e_0014:INT, dest=binary_expr_00023:INT, next=0018
test_0018: op=ASSIGN, src=binary_expr_00023:INT, dest=test_f_0015:INT, next=0019
test_0019: op=ADD, src=test_g_0016:INT, test_h_0017:INT, dest=binary_expr_00024:INT, next=0020
test_0020: op=ASSIGN, src=binary_expr_00024:INT, dest=test_i_0018:INT, next=0021
test_0021: op=ADD, src=test_j_0019:INT, test_k_0020:INT, dest=binary_expr_00025:INT, next=0022
test_0022: op=ASSIGN, src=binary_expr_00025:INT, dest=test_l_0021:INT, next=0023
test_0023: op=ADD, src=test_c_0012:INT, test_f_0015:INT, dest=binary_expr_00026:INT, next=0024
test_0024: op=ASSIGN, src=binary_expr_00026:INT, dest=test_c_0012:INT, next=0025
test_0025: op=ADD, src=test_l_0021:INT, test_i_0018:INT, dest=binary_expr_00027:INT, next=0026
test_0026: op=ASSIGN, src=binary_expr_00027:INT, dest=test_l_0021:INT, next=0027
...
49. 49
たとえば
test_0000: op=METHOD_EXIT, src=, dest=, next=0001
test_0001: op=METHOD_ENTRY, src=, dest=, next=0002 (name=test)
test_0002: op=ASSIGN, src=false:BOOLEAN, dest=test_success_0009:BOOLEAN, next=0015
test_0002: op=ASSIGN, src=10:INT, dest=test_a_0010:INT, next=0015
test_0002: op=ASSIGN, src=20:INT, dest=test_b_0011:INT, next=0015
test_0002: op=ASSIGN, src=0:INT, dest=test_c_0012:INT, next=0015
test_0002: op=ASSIGN, src=40:INT, dest=test_d_0013:INT, next=0015
test_0002: op=ASSIGN, src=50:INT, dest=test_e_0014:INT, next=0015
test_0002: op=ASSIGN, src=0:INT, dest=test_f_0015:INT, next=0015
test_0002: op=ASSIGN, src=70:INT, dest=test_g_0016:INT, next=0015
test_0002: op=ASSIGN, src=80:INT, dest=test_h_0017:INT, next=0015
test_0002: op=ASSIGN, src=0:INT, dest=test_i_0018:INT, next=0015
test_0002: op=ASSIGN, src=100:INT, dest=test_j_0019:INT, next=0015
test_0002: op=ASSIGN, src=110:INT, dest=test_k_0020:INT, next=0015
test_0002: op=ASSIGN, src=0:INT, dest=test_l_0021:INT, next=0015
test_0002: op=ADD, src=10:INT, 20:INT, dest=binary_expr_00029:INT, next=0015
test_0015: op=ADD, src=test_a_0010:INT, test_b_0011:INT, dest=binary_expr_00022:INT, next=0016
test_0015: op=ADD, src=test_d_0013:INT, test_e_0014:INT, dest=binary_expr_00023:INT, next=0016
test_0015: op=ADD, src=test_g_0016:INT, test_h_0017:INT, dest=binary_expr_00024:INT, next=0016
test_0015: op=ADD, src=test_j_0019:INT, test_k_0020:INT, dest=binary_expr_00025:INT, next=0016
test_0015: op=ADD, src=binary_expr_00029:INT, 40:INT, dest=binary_expr_00030:INT, next=0016
test_0016: op=ASSIGN, src=binary_expr_00022:INT, dest=test_c_0012:INT, next=0023
test_0016: op=ASSIGN, src=binary_expr_00023:INT, dest=test_f_0015:INT, next=0023
test_0016: op=ASSIGN, src=binary_expr_00024:INT, dest=test_i_0018:INT, next=0023
test_0016: op=ASSIGN, src=binary_expr_00025:INT, dest=test_l_0021:INT, next=0023
test_0016: op=ADD, src=binary_expr_00030:INT, 50:INT, dest=binary_expr_00031:INT, next=0023
...
58. 58
参考書
✔ 笠原博徳 “並列処理技術” コロナ社
✔ 中田育男 “コンパイラの構成と最適化” 朝倉書店
✔ 中田育男, 佐々政孝, 滝本宗宏, 渡邊坦 “コンパイラの基盤
技術と実践―コンパイラ・インフラストラクチャCOINSを
用いて” 朝倉書店