synthesijer fpgax 20150201

59
ソフトウェアエンジニアにもわかる 高位合成 わさらぼ みよし たけふみ (miyox) 2015.02.01

Upload: takefumi-miyoshi

Post on 19-Jul-2015

2.070 views

Category:

Engineering


1 download

TRANSCRIPT

Page 1: Synthesijer fpgax 20150201

ソフトウェアエンジニアにもわかる高位合成

わさらぼみよし たけふみ

(miyox)

2015.02.01

Page 2: Synthesijer fpgax 20150201

2014 年 8 月 2015 年 1 月0

5

10

15

20

25

30

35

40

45

x20

Page 3: Synthesijer fpgax 20150201

2014 年 8 月 2015 年 1 月0

5

10

15

20

25

30

35

40

45

x20

高位合成を実装する人達の飲み会 # 2014.8.3

高位合成友の会# 2015.1.16

Page 4: Synthesijer fpgax 20150201

4

高位合成友の会(恋友)

✔ 豊島さん: 「両刀使いエンジニアは高位合成ツールの夢を見るか?」✔ たばたさん: Neon light compiler - http://goo.gl/JEhlyn

✔ みよし: Synthesijer – http://goo.gl/2w3J6Z

✔ 高前田さん: PyCoRAM – http://goo.gl/0b16rr

論理回路の高位合成について試作した実装とアイデアと妄想について語る会http://hls.connpass.com/event/11009/

Page 5: Synthesijer fpgax 20150201

5

高位合成処理系の前に

Page 6: Synthesijer fpgax 20150201

6

一般的なFPGAアプリ設計✔ 論理回路構成要素の内容を決める✔ 論理回路構成要素同士の接続関係を決める

Page 7: Synthesijer fpgax 20150201

7

一般的なFPGAアプリ設計

1) http://japan.xilinx.com/support/documentation/data_sheets/ds180_7Series_Overview.pdf2) http://hitechglobal.com/boards/virtex7_v2000t.htm

3) http://http://low-powerdesign.com/sleibson/2011/10/25/generation-jumping-2-5d-xilinx-virtex-7-2000t-fpga-delivers-1954560-logic-cells-consumes-only-20w/

Page 8: Synthesijer fpgax 20150201

8

一般的なFPGAアプリ設計HDL(VHDLやVerilog HDL)によるRTL(Register Transfer Level)設計

Page 9: Synthesijer fpgax 20150201

9

ちょっと脇道にそれますが

Page 10: Synthesijer fpgax 20150201

10

FPGAっていつ有用なの?

10G if

DRAM

Networkadapter

FPGA

Network stack Memcached

x86 DRAM

motherboard

Hash table Value store

図は https://www.usenix.org/sites/default/files/conference/protected-files/blott_hotcloud13_slides.pdf より

データはどうせ移動させる移動途中で副次的に処理できる

✔ Memcached部分はデータフローアーキテクチャ✔ レイテンシ = 481Cycles@156MHz

Page 11: Synthesijer fpgax 20150201

11

鍵はパイプライン並列化

FIFO

スループット T [bps]

w [byte]f [Hz]

実行ステージ

FIFO

実行ステージ

実行ステージ

Page 12: Synthesijer fpgax 20150201

12

データが来たら迎え撃つ

デスクトップタワーディフェンス的なゲーム

Page 13: Synthesijer fpgax 20150201

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

実行ステージ

実行ステージ

とはいえ,各ステージで状態遷移のある処理が必要

Page 14: Synthesijer fpgax 20150201

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

実行ステージ

実行ステージ

とはいえ,各ステージで状態遷移のある処理が必要

限られた許容サイクルを効率よく使う必要

Page 15: Synthesijer fpgax 20150201

15

組み合わせ回路/データ並列性の活用✔ プロセッサと比べてFPGA回路のφは圧倒的に低速✔ 高速データ処理では1クロックでデータを捌く必要も✔ 時にはソフトウェア実装とは全く違う場合も

条件

・・・

条件

v.s

Page 16: Synthesijer fpgax 20150201

16

話は戻りまして

Page 17: Synthesijer fpgax 20150201

17

一般的なFPGAアプリ設計HDL(VHDLやVerilog HDL)によるRTL(Register Transfer Level)設計

Page 18: Synthesijer fpgax 20150201

18

HDLによるRTL設計

✔ ロジックを抽象化した式/構文で設計できる✔ クロックレベルのデータ制御✔ 細粒度の並列性の活用

✔ 記述が煩雑✔ “状態”を自分で管理しなければいけない✔ デバッグ/動作検証が難しい

メリット

デメリット

Page 19: Synthesijer fpgax 20150201

19

HDLによるRTL設計

✔ ロジックを抽象化した式/構文で設計できる✔ クロックレベルのデータ制御✔ 細粒度の並列性の活用

✔ 記述が煩雑✔ “状態”を自分で管理しなければいけない✔ デバッグ/動作検証が難しい

メリット

デメリット

アプリケーション書くの大変開発に時間/コストがかかる

Page 20: Synthesijer fpgax 20150201

20

FPGAにキラーアプリはないの定理Florent de Dinechin, "Building Custom Arithmetic Operators with the FloPoCo Generator”,http://www.hipeac.net/conference/berlin/tutorial/flopoco

なんとかして開発スピードを速くしたい

Page 21: Synthesijer fpgax 20150201

21

デメリット克服のためには

✔ FPGAを使うのをやめる✔ より抽象度の高い設計手法/処理系を使う

Page 22: Synthesijer fpgax 20150201

22

デメリット克服のためには

✔ FPGAを使うのをやめる✔ 別にプロセッサを持ってくる✔ FPGAの上にプロセッサを作る

✔ より抽象度の高い設計手法/処理系を使う✔ 既存のプログラミング言語を借用する✔ 新しい記述言語を模索する✔ 新しい設計概念を模索する

Page 23: Synthesijer fpgax 20150201

23

デメリット克服のためには

✔ FPGAを使うのをやめる✔ 別にプロセッサを持ってくる✔ FPGAの上にプロセッサを作る

✔ より抽象度の高い設計手法/処理系を使う✔ 既存のプログラミング言語を借用する✔ 新しい記述言語を模索する✔ 新しい設計概念を模索する

Page 24: Synthesijer fpgax 20150201

24

高位合成処理系 Synthesijer

Page 25: Synthesijer fpgax 20150201

25

Synthesijer とは✔ JavaプログラムをFPGA上のハードウェアに変換

✔ 複雑なアルゴリズムのハードウェア実装を楽に✔ オブクジェクト指向設計による再利用性の向上

✔ 特殊な記法,追加構文はない✔ ソフトウェアとして実行可能.動作の確認、検証が容易✔ 書けるプログラムに制限は加える

(動的なnew,再帰は不可など)✔ HDLモジュールのJavaからのインスタンス生成

Javaコンパイラフロントエンド

Synthesijerエンジン

Javaコンパイラバックエンド

合成配置配線

while(){if(...){ … }else{ … … }….}

複雑な状態遷移も,Javaの制御構文を使って楽に設計できる同じJavaプログラムをソフトウェアとしてもFPGA上のハードウェアとしても実行可能

Open-source

Page 26: Synthesijer fpgax 20150201

26

Synthesijer 開発の経緯✔ 2009年頃 Bluespecに感銘を受ける✔ 2010年12月頃 高位合成処理系を作ってみたい→Javaベースに✔ 2011年7月 JavaRockの開発を開始 JavaをVHDLに変換する.1文1ステート→簡単な並列化

✔ 2012(?)年〜2013年 農工大中條研小池さんによるJavaRock-Thrashの開発 種々の最適化の実装など

✔ 2014年

Synthesijerとして名称をあらため開発を再スタート

JavaRock/JavaRock-Thrashの実装を通じた知見の活用

なぜか

Page 27: Synthesijer fpgax 20150201

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など

Page 28: Synthesijer fpgax 20150201

28

Synthesijerのコード生成

✔ (その前に)典型的な高位合成処理系✔ Synthesijerの場合✔ 最適化のために

Page 29: Synthesijer fpgax 20150201

29

高位合成処理系は何をするか?

http://www.ida.liu.se/~petel/SysSyn/lect3.frm.pdf

基本はこれに書いてありますHigh-Level Synthesis

Page 30: Synthesijer fpgax 20150201

30

高位合成処理系は何をするか

入力言語 データフロー スケジューリングデータパス生成

ステート生成物理マッピング

Page 31: Synthesijer fpgax 20150201

31

高位合成処理系は何をするか

入力言語 データフロー スケジューリングデータパス生成

ステート生成物理マッピング

(1) (2)

(3)

Page 32: Synthesijer fpgax 20150201

32

高位合成処理系のレイヤ

(1)言語デザイン

(2)アーキテクチャの生成

(3)テクノロジ・マッピング

✔ 設計コストが小さくなるように✔ パフォーマンスを出しやすいように

✔ 命令スケジューリング,並列化の抽出✔ 動作周波数,リソース使用量,レイテンシの考慮

✔ 適切な物理マッピング✔ 符号化

Page 33: Synthesijer fpgax 20150201

33

Synthesijerでは

✔ 設計コストが小さくなるように✔ パフォーマンスを出しやすいように

✔ 命令スケジューリング,並列化の抽出✔ 動作周波数,リソース使用量,レイテンシの考慮

✔ 適切な物理マッピング✔ 符号化

(1)言語デザイン

(2)アーキテクチャの生成

(3)テクノロジ・マッピング

Java - オブジェクト指向設計 - スレッドで並列化 - 既存資産の活用

ISE/Vivado,QuartusIIにお任せ

Javaから変換するエンジンを実装

Page 34: Synthesijer fpgax 20150201

34

Synthesijerオーバービュー

Javaコード 字句解析/構文解析

コントロール・データフロー作成

最適化

出力 VHDL/Verilog HDLコード

Javaコード

VHDL/Verilog HDLコード

Page 35: Synthesijer fpgax 20150201

35

Javaコンパイラ

Javaコード 字句解析/構文解析

コントロール・データフロー作成

最適化

出力 VHDL/Verilog HDLコード

Javaコード

class

JVM用のバイトコード

JVM命令セット内での最適化

Page 36: Synthesijer fpgax 20150201

36

(理想的な)高位合成処理系の場合

Javaコード 字句解析/構文解析

コントロール・データフロー作成

最適化

出力 VHDL/Verilog HDLコード

Javaコード

VHDL/Verilog HDLコード

自由なデータパスステートマシン

命令セットを強制されない/並列化し放題

Page 37: Synthesijer fpgax 20150201

37

(理想的な)高位合成処理系の場合

Javaコード 字句解析/構文解析

コントロール・データフロー作成

最適化

出力 VHDL/Verilog HDLコード

Javaコード

VHDL/Verilog HDLコード

自由なデータパスステートマシン

命令セットを強制されない/並列化し放題

完全にはムリ!!

Page 38: Synthesijer fpgax 20150201

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++) ; } }}

Page 39: Synthesijer fpgax 20150201

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モジュールを生成

Page 40: Synthesijer fpgax 20150201

40

Synthesijer でのHDL生成: スケジュール表メソッド毎にスケジュール表を生成

run_0000: op=METHOD_EXIT, src=, dest=, next=0001run_0001: op=METHOD_ENTRY, src=, dest=, next=0002 (name=run)run_0002: op=JT, src=true:BOOLEAN, dest=, next=0004, 0003run_0003: op=JP, src=, dest=, next=0023run_0004: op=ASSIGN, src=true:BOOLEAN, dest=class_led_0000:BOOLEAN, next=0005run_0005: op=ASSIGN, src=0:INT, dest=run_i_0001:INT, next=0006run_0006: op=LT, src=run_i_0001:INT, 5000000:INT, dest=binary_expr_00002:BOOLEAN, next=0007run_0007: op=JT, src=binary_expr_00002:BOOLEAN, dest=, next=0012, 0008run_0008: op=JP, src=, dest=, next=0013run_0009: op=ADD, src=run_i_0001:INT, 1:INT, dest=unary_expr_00003:INT, next=0010run_0010: op=ASSIGN, src=unary_expr_00003:INT, dest=run_i_0001:INT, next=0011run_0011: op=JP, src=, dest=, next=0006run_0012: op=JP, src=, dest=, next=0009run_0013: op=ASSIGN, src=false:BOOLEAN, dest=class_led_0000:BOOLEAN, next=0014run_0014: op=ASSIGN, src=0:INT, dest=run_i_0004:INT, next=0015run_0015: op=LT, src=run_i_0004:INT, 5000000:INT, dest=binary_expr_00005:BOOLEAN, next=0016run_0016: op=JT, src=binary_expr_00005:BOOLEAN, dest=, next=0021, 0017run_0017: op=JP, src=, dest=, next=0022run_0018: op=ADD, src=run_i_0004:INT, 1:INT, dest=unary_expr_00006:INT, next=0019run_0019: op=ASSIGN, src=unary_expr_00006:INT, dest=run_i_0004:INT, next=0020run_0020: op=JP, src=, dest=, next=0015run_0021: op=JP, src=, dest=, next=0018run_0022: op=JP, src=, dest=, next=0002run_0023: op=JP, src=, dest=, next=0000

Page 41: Synthesijer fpgax 20150201

41

スケジューラ表の疑似命令

✔ 四則演算,論理演算,シフト✔ 比較✔ 代入✔ 配列のアドレス指定,配列アクセス✔ Call/Return

✔ CallしたらReturnされるまで待つ(基本)✔ Thread.startの呼び出し時は待たずに次へ

✔ 無条件ジャンプ,条件分岐,SELECT✔ フィールドアクセス指示命令

Page 42: Synthesijer fpgax 20150201

42

Synthesijer でのHDL生成: 出力(状態遷移)

メソッド毎にスケジュール表を生成 → 状態遷移機械

whilefor

for

Page 43: Synthesijer fpgax 20150201

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...

Page 44: Synthesijer fpgax 20150201

44

Synthesijer でのHDL生成: 出力(データ操作)

メソッド毎にスケジュール表を生成 → 文/式相当のデータ操作

run_0000: op=METHOD_EXIT, src=, dest=, next=0001run_0001: op=METHOD_ENTRY, src=, dest=, next=0002 (name=run)run_0002: op=JT, src=true:BOOLEAN, dest=, next=0004, 0003run_0003: op=JP, src=, dest=, next=0023run_0004: op=ASSIGN, src=true:BOOLEAN, dest=class_led_0000:BOOLEAN, next=0005run_0005: op=ASSIGN, src=0:INT, dest=run_i_0001:INT, next=0006run_0006: op=LT, src=run_i_0001:INT, 5000000:INT, dest=binary_expr_00002:BOOLEAN, next=0007run_0007: op=JT, src=binary_expr_00002:BOOLEAN, dest=, next=0012, 0008run_0008: op=JP, src=, dest=, next=0013run_0009: op=ADD, src=run_i_0001:INT, 1:INT, dest=unary_expr_00003:INT, next=0010run_0010: op=ASSIGN, src=unary_expr_00003:INT, dest=run_i_0001:INT, next=0011run_0011: op=JP, src=, dest=, next=0006run_0012: op=JP, src=, dest=, next=0009run_0013: op=ASSIGN, src=false:BOOLEAN, dest=class_led_0000:BOOLEAN, next=0014run_0014: op=ASSIGN, src=0:INT, dest=run_i_0004:INT, next=0015run_0015: op=LT, src=run_i_0004:INT, 5000000:INT, dest=binary_expr_00005:BOOLEAN, next=0016run_0016: op=JT, src=binary_expr_00005:BOOLEAN, dest=, next=0021, 0017run_0017: op=JP, src=, dest=, next=0022run_0018: op=ADD, src=run_i_0004:INT, 1:INT, dest=unary_expr_00006:INT, next=0019run_0019: op=ASSIGN, src=unary_expr_00006:INT, dest=run_i_0004:INT, next=0020run_0020: op=JP, src=, dest=, next=0015run_0021: op=JP, src=, dest=, next=0018run_0022: op=JP, src=, dest=, next=0002run_0023: op=JP, src=, dest=, next=0000

Page 45: Synthesijer fpgax 20150201

45

Synthesijer でのHDL生成: 出力(データ操作)

メソッド毎にスケジュール表を生成 → 文/式相当のデータ操作

run_0000: op=METHOD_EXIT, src=, dest=, next=0001run_0001: op=METHOD_ENTRY, src=, dest=, next=0002 (name=run)run_0002: op=JT, src=true:BOOLEAN, dest=, next=0004, 0003run_0003: op=JP, src=, dest=, next=0023run_0004: op=ASSIGN, src=true:BOOLEAN, dest=class_led_0000:BOOLEAN, next=0005run_0005: op=ASSIGN, src=0:INT, dest=run_i_0001:INT, next=0006run_0006: op=LT, src=run_i_0001:INT, 5000000:INT, dest=binary_expr_00002:BOOLEAN, next=0007run_0007: op=JT, src=binary_expr_00002:BOOLEAN, dest=, next=0012, 0008run_0008: op=JP, src=, dest=, next=0013run_0009: op=ADD, src=run_i_0001:INT, 1:INT, dest=unary_expr_00003:INT, next=0010run_0010: op=ASSIGN, src=unary_expr_00003:INT, dest=run_i_0001:INT, next=0011run_0011: op=JP, src=, dest=, next=0006run_0012: op=JP, src=, dest=, next=0009run_0013: op=ASSIGN, src=false:BOOLEAN, dest=class_led_0000:BOOLEAN, next=0014run_0014: op=ASSIGN, src=0:INT, dest=run_i_0004:INT, next=0015run_0015: op=LT, src=run_i_0004:INT, 5000000:INT, dest=binary_expr_00005:BOOLEAN, next=0016run_0016: op=JT, src=binary_expr_00005:BOOLEAN, dest=, next=0021, 0017run_0017: op=JP, src=, dest=, next=0022run_0018: op=ADD, src=run_i_0004:INT, 1:INT, dest=unary_expr_00006:INT, next=0019run_0019: op=ASSIGN, src=unary_expr_00006:INT, dest=run_i_0004:INT, next=0020run_0020: op=JP, src=, dest=, next=0015run_0021: op=JP, src=, dest=, next=0018run_0022: op=JP, src=, dest=, next=0002run_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...

Page 46: Synthesijer fpgax 20150201

46

最適化

✔ メモリ書き込みアクセスのパック✔ 基本ブロック内の細粒度並列化

✔ メモリ読み込みのアドレス指定のステート最適化✔ 演算のチェイニング

今実装しているもの

もうすぐ実装するもの

≒ スケジュール表ベースでサイズを小さくすること

Page 47: Synthesijer fpgax 20150201

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); }

Page 48: Synthesijer fpgax 20150201

48

たとえばtest_0000: op=METHOD_EXIT, src=, dest=, next=0001test_0001: op=METHOD_ENTRY, src=, dest=, next=0002 (name=test)test_0002: op=ASSIGN, src=false:BOOLEAN, dest=test_success_0009:BOOLEAN, next=0003test_0003: op=ASSIGN, src=10:INT, dest=test_a_0010:INT, next=0004test_0004: op=ASSIGN, src=20:INT, dest=test_b_0011:INT, next=0005test_0005: op=ASSIGN, src=0:INT, dest=test_c_0012:INT, next=0006test_0006: op=ASSIGN, src=40:INT, dest=test_d_0013:INT, next=0007test_0007: op=ASSIGN, src=50:INT, dest=test_e_0014:INT, next=0008test_0008: op=ASSIGN, src=0:INT, dest=test_f_0015:INT, next=0009test_0009: op=ASSIGN, src=70:INT, dest=test_g_0016:INT, next=0010test_0010: op=ASSIGN, src=80:INT, dest=test_h_0017:INT, next=0011test_0011: op=ASSIGN, src=0:INT, dest=test_i_0018:INT, next=0012test_0012: op=ASSIGN, src=100:INT, dest=test_j_0019:INT, next=0013test_0013: op=ASSIGN, src=110:INT, dest=test_k_0020:INT, next=0014test_0014: op=ASSIGN, src=0:INT, dest=test_l_0021:INT, next=0015test_0015: op=ADD, src=test_a_0010:INT, test_b_0011:INT, dest=binary_expr_00022:INT, next=0016test_0016: op=ASSIGN, src=binary_expr_00022:INT, dest=test_c_0012:INT, next=0017test_0017: op=ADD, src=test_d_0013:INT, test_e_0014:INT, dest=binary_expr_00023:INT, next=0018test_0018: op=ASSIGN, src=binary_expr_00023:INT, dest=test_f_0015:INT, next=0019test_0019: op=ADD, src=test_g_0016:INT, test_h_0017:INT, dest=binary_expr_00024:INT, next=0020test_0020: op=ASSIGN, src=binary_expr_00024:INT, dest=test_i_0018:INT, next=0021test_0021: op=ADD, src=test_j_0019:INT, test_k_0020:INT, dest=binary_expr_00025:INT, next=0022test_0022: op=ASSIGN, src=binary_expr_00025:INT, dest=test_l_0021:INT, next=0023test_0023: op=ADD, src=test_c_0012:INT, test_f_0015:INT, dest=binary_expr_00026:INT, next=0024test_0024: op=ASSIGN, src=binary_expr_00026:INT, dest=test_c_0012:INT, next=0025test_0025: op=ADD, src=test_l_0021:INT, test_i_0018:INT, dest=binary_expr_00027:INT, next=0026test_0026: op=ASSIGN, src=binary_expr_00027:INT, dest=test_l_0021:INT, next=0027...

Page 49: Synthesijer fpgax 20150201

49

たとえばtest_0000: op=METHOD_EXIT, src=, dest=, next=0001test_0001: op=METHOD_ENTRY, src=, dest=, next=0002 (name=test)test_0002: op=ASSIGN, src=false:BOOLEAN, dest=test_success_0009:BOOLEAN, next=0015test_0002: op=ASSIGN, src=10:INT, dest=test_a_0010:INT, next=0015test_0002: op=ASSIGN, src=20:INT, dest=test_b_0011:INT, next=0015test_0002: op=ASSIGN, src=0:INT, dest=test_c_0012:INT, next=0015test_0002: op=ASSIGN, src=40:INT, dest=test_d_0013:INT, next=0015test_0002: op=ASSIGN, src=50:INT, dest=test_e_0014:INT, next=0015test_0002: op=ASSIGN, src=0:INT, dest=test_f_0015:INT, next=0015test_0002: op=ASSIGN, src=70:INT, dest=test_g_0016:INT, next=0015test_0002: op=ASSIGN, src=80:INT, dest=test_h_0017:INT, next=0015test_0002: op=ASSIGN, src=0:INT, dest=test_i_0018:INT, next=0015test_0002: op=ASSIGN, src=100:INT, dest=test_j_0019:INT, next=0015test_0002: op=ASSIGN, src=110:INT, dest=test_k_0020:INT, next=0015test_0002: op=ASSIGN, src=0:INT, dest=test_l_0021:INT, next=0015test_0002: op=ADD, src=10:INT, 20:INT, dest=binary_expr_00029:INT, next=0015test_0015: op=ADD, src=test_a_0010:INT, test_b_0011:INT, dest=binary_expr_00022:INT, next=0016test_0015: op=ADD, src=test_d_0013:INT, test_e_0014:INT, dest=binary_expr_00023:INT, next=0016test_0015: op=ADD, src=test_g_0016:INT, test_h_0017:INT, dest=binary_expr_00024:INT, next=0016test_0015: op=ADD, src=test_j_0019:INT, test_k_0020:INT, dest=binary_expr_00025:INT, next=0016test_0015: op=ADD, src=binary_expr_00029:INT, 40:INT, dest=binary_expr_00030:INT, next=0016test_0016: op=ASSIGN, src=binary_expr_00022:INT, dest=test_c_0012:INT, next=0023test_0016: op=ASSIGN, src=binary_expr_00023:INT, dest=test_f_0015:INT, next=0023test_0016: op=ASSIGN, src=binary_expr_00024:INT, dest=test_i_0018:INT, next=0023test_0016: op=ASSIGN, src=binary_expr_00025:INT, dest=test_l_0021:INT, next=0023test_0016: op=ADD, src=binary_expr_00030:INT, 50:INT, dest=binary_expr_00031:INT, next=0023...

Page 50: Synthesijer fpgax 20150201

50

結局プロセッサと何が違うの?CPU 高位合成でできたもの

処理方式 読む→解釈→実行 演算器としてならべられる適切なタイミングで確定

命令セット 決まっている 入力コードによって生成

I/O 決まっている 割と自由に追加できる

個数 決まっている 入力コードによって決まる

Page 51: Synthesijer fpgax 20150201

51

Synthesijerのこれから

Page 52: Synthesijer fpgax 20150201

52

ロードマップ

手続き型言語的基本演算,操作

整数プリミティブ型変数の利用

算術,論理,シフト演算(除算・剰余算以外)

制御構文(分岐,ループ)

メソッド呼び出し

除算・剰余算

浮動小数点数演算

オブジェクト指向的インスンタンス協調

finalでのインスタンスの生成

インスタンスメソッドの呼び出し

インスタンス変数へのリードアクセス

インスタンス変数へのライトアクセス

インスタンス間での配列読み書きのサポート

インスタンスの配列,配列の配列のサポート

コンストラクタのサポート

インスタンスのチェインアクセス

並列化パフォーマンス

基本ブロック内自動並列化

Threadによる明示的な処理の並列化をサポート

ループ内パイプライニング

ライブラリ 整数プリミティブ変数の配列

AXI接続用のコンポーネントライブラリの提供

Stringクラスのサポート

ユーザビリティ コマンドラインでのコンパイル

HDLモジュールとのバインディング機構

FPGA合成ツールとの連携,統一的な開発フローの提供

スケジューリング可視化ツール

HDL生成ライブラリを活用したDSLの提供

2014年7月 2014年12月 2015年3月 2015年6月

Page 53: Synthesijer fpgax 20150201

53

市販の高位合成処理系に憧れつつ...

✔ 設計空間の自動探索✔ パイプライン生成,ストリーム処理対応

Page 54: Synthesijer fpgax 20150201

54

今後挑戦したいこと

✔ メソッドのパイプライン化✔ I/Oストリームへの対応

✔ コンストラクタに対応✔ コンパイル時のJavaプログラム実行

✔ lambda式対応✔ Streamへの対応

✔ Erlangフロントエンド

Page 55: Synthesijer fpgax 20150201

55

ところで

Page 56: Synthesijer fpgax 20150201

56

高位合成処理系は何をするか

入力言語 データフロー スケジューリングデータパス生成

ステート生成物理マッピング

(1) (2)

(3)

Page 57: Synthesijer fpgax 20150201

57

共通基盤があると嬉しくない?

✔ 設計コストが小さくなるように✔ パフォーマンスを出しやすいように

✔ 命令スケジューリング,並列化の抽出✔ 動作周波数,リソース使用量,レイテンシの考慮

✔ 適切な物理マッピング✔ 符号化

(1)言語デザイン

(2)アーキテクチャの生成

(3)テクノロジ・マッピングベンダの合成ツール

最強の言語の設計に没頭!!

共通基盤

Page 58: Synthesijer fpgax 20150201

58

参考書

✔ 笠原博徳 “並列処理技術” コロナ社✔ 中田育男 “コンパイラの構成と最適化” 朝倉書店✔ 中田育男, 佐々政孝, 滝本宗宏, 渡邊坦 “コンパイラの基盤技術と実践―コンパイラ・インフラストラクチャCOINSを用いて” 朝倉書店

Page 59: Synthesijer fpgax 20150201

59

まとめ

✔ 高位合成処理系についてのオーバビュー

✔ Synthesijerのコード生成について

✔ 次回,高位合成友の会も是非ご参加ください