SlideShare une entreprise Scribd logo
1  sur  155
Télécharger pour lire hors ligne
JavaベースのFPGA向け高位合成処理系の
実装と活用事例
イーツリーズ・ジャパン/わさらぼ
三好 健文
2015.08.27
JavaベースのFPGA向け高位合成処理系の
実装と活用事例
イーツリーズ・ジャパン/わさらぼ
三好 健文
2015.08.27
Synthesijer
2
Synthesijer とは
✔ JavaプログラムをFPGA上のハードウェアに変換
✔ 複雑なアルゴリズムのハードウェア実装を楽に
✔ オブクジェクト指向設計による再利用性の向上
✔ 特殊な記法,追加構文はない
✔ ソフトウェアとして実行可能.動作の確認、検証が容易
✔ 書けるプログラムに制限は加える
(動的なnew,再帰は制限付きで可など)
Javaコンパイラ
フロントエンド
Synthesijer
エンジン
Javaコンパイラ
バックエンド
合成
配置配線
while(){
if(...){
…
}else{
…
…
}
….
}
複雑な状態遷移も,Javaの制御構文を使って楽に設計できる
同じJavaプログラムをソフトウェアとしても
FPGA上のハードウェアとしても実行可能
Open-source
3
Synthesijer クイックスタート
4
クイックスタート 1/8
(1) バイナリパッケージをダウンロードします
http://synthesijer.github.io/web/
なるべく日付の新しいものをDLしてください
ダウンロードページに遷移します
✔ JDK8が必要です.
✔ Eclipseを使って開発してみます.
5
クイックスタート 2/8
(2) Eclipseでプロジェクトを作ります
6
クイックスタート 3/8
(3) libフォルダを作ってDLしたJARをコピー,ビルドパスに追加する
DLしたJARをD&Dでコピー
ビルドパスに追加
準備完了!!
7
クイックスタート 4/8
(4) Javaのクラスを作る
クラス生成ダイアログ
8
クイックスタート 5/8
(5) 間隔をおいて変数ledをtrue/falseするプログラムを書く
Lチカに相当する変数
適当なウェイト
点滅
自動コンパイルが裏で動くので,Javaコードとしての正しさは
即座にチェックされる
9
クイックスタート 6/8
(6) Synthesijerを使ってJavaコードをHDLに変換
10
クイックスタート 6/8
(6) Synthesijerを使ってJavaコードをHDLに変換
11
クイックスタート 7/8
(7) ISEで合成,配置配線
生成したモジュールのインスタンスを生成
制約ファイルは別途用意
12
クイックスタート 8/8
(8) FPGAをコンフィギュレーションして動作を確認
1
コンテンツ
✔ 高位合成処理系のあれこれ
✔ Synthesijerの設計と実装
✔ Synthesijerのサンプル/使用事例
✔ Synthesijer.Scala
✔ これからについて
2
“FPGAにキラーアプリはないの定理”への挑戦
Florent de Dinechin, "Building Custom Arithmetic Operators with the FloPoCo Generator”,
http://www.hipeac.net/conference/berlin/tutorial/flopoco
なんとかして開発スピードを速くしたい
3
デメリット克服のためには
✔ FPGAを使うのをやめる
✔ より抽象度の高い設計手法/処理系を使う
4
デメリット克服のためには
✔ FPGAを使うのをやめる
✔ 別にプロセッサを持ってくる
✔ FPGAの上にプロセッサを作る
✔ より抽象度の高い設計手法/処理系を使う
✔ 既存のプログラミング言語を借用する
✔ 新しい記述言語を模索する
✔ 新しい設計概念を模索する
5
デメリット克服のためには
✔ FPGAを使うのをやめる
✔ 別にプロセッサを持ってくる
✔ FPGAの上にプロセッサを作る
✔ より抽象度の高い設計手法/処理系を使う
✔ 既存のプログラミング言語を借用する
✔ 新しい記述言語を模索する
✔ 新しい設計概念を模索する
2014 年 8 月 2015 年 1 月
0
5
10
15
20
25
30
35
40
45
x20
2014 年 8 月 2015 年 1 月
0
5
10
15
20
25
30
35
40
45
x20
高位合成を実装する人達の
飲み会 # 2014.8.3
高位合成友の会
# 2015.1.16
1
高位合成処理系あれこれ
2
ESLSynthesisの市場規模
3
Source
Abstraction
Level
Ease of
Impl.
Learning
curve
Document-
ation
Floating/
Fixed Pt.
Design
Exploration
Testbench
generation
Verification
Size FPGA
Slices
AccelDSP Matlab untimed ++ ++ +
Auto
conversion
+ yes ++ 2411
Agility
Compiler
SystemC
Cycle
accurate
+ - + Fixed pt + no -
AutoPilot
C, C++,
SystemC
Cycle+
untimed
++ ++ ++ yes ++ yes ++ 232
Bluespec BSV
Cycle
accurate
+/- - + no limited no - 120
Catapult C
C, C++,
SystemC
Cycle+
untimed
++ ++ ++ Fixed pt ++ yes ++ 370/560
Compaan C, Matlab untimed + + - automatic ++ no + 3398
CyberWork
Bench
SystemC,
C, BDL
Cycle +
untimed
+ + + yes ++ yes + 243/292
DK Design
Suite
HandelC
Cycle
accurate
+/- - +/- Fixed pt limited no +/- 311/945
Impluse
CoDeveloper
ImpulseC
Cycle +
unlimited
- + - Fixed pt + no + 4611
ROCCC C subst untimed - +/- + no + no -
Synphony C C, C++ untimed ++ + + Fixed pt + yes ++ 1047
いろいろな高位合成
Wim Meeus, Kristof Van Beeck, Toon Goedemé, Jan Meel, Dirk Stroobandt, "An overview of today’s high-level synthesis tools",
Design Automation for Embedded Systems, September 2012, Volume 16, Issue 3, pp 31-51
4
高位合成処理系,躍進のわけ
✔ Embedded processors are in almost every SoC
✔ Huge silicon capacity
✔ Behavioral IP reuse
✔ Verification drives the acceptance of HLS Specification
✔ Accelerators and heterogeneous SoC
✔ Less pressure for formal verification
✔ Ideal for platform-based synthesis
✔ More pressure for time-to-market
✔ Accelerated or reconfigurable computing
Cong, J.; Bin Liu; Neuendorffer, S.; Noguera, J.; Vissers, K.; Zhiru Zhang, "High-Level Synthesis for FPGAs: From
Prototyping to Deployment," in Computer-Aided Design of Integrated Circuits and Systems, IEEE Transactions
on , vol.30, no.4, pp.473-491, April 2011
5
すみません,これはここまで
6
実際のところ高位合成は身近
1
Synthesijer 設計と実装 
2
高位合成処理系に何を求めるか?
✔ 記述コストの軽減
✔ 高抽象度の表現方法を利用したい
✔ 言語習得にコストをかけたくない
✔ 動作検証/デバッグ効率の向上
✔ 短時間で動作を確認したい
✔ 見通しよく,手軽なデバッグをしたい
✔ FPGAのパフォーマンスの活用
✔ 粗粒度,細粒度の並列性の活用
✔ IPコアや内部機能ユニットを活用したい
✔ 設計空間の探索
3
Synthesijer
✔ クラスによるオブジェクト指向設計言語
 ← HWのモジュール設計との親和性は高そう
✔ 言語仕様で並列処理をサポート
✔ Thread,wait-notify
✔ (Cと違い)明示的なポインタの扱いが不要
✔ 言語の想定するメモリ構造から解放され得るかも
✔ 動的な振る舞いは厄介そう
Javaベースの高位合成処理系
4
Synthesijer 設計基本方針
✔ JavaプログラムをそのままHDL→HW化
✔ 追加構文,データ型は導入しない
✔ 使える記述には制限を導入
HDLで書けることをすべてJavaで書けるようにするではない
Javaで書けることををすべてHDL(HW)にするではない
Javaとして実行可能なプログラムをHWにする
≒ フェッチのないJavaプロセッサをHDLで直接生成する
なぜJavaなのか?
Write Once, Run Anywhere!!
Write Once, Run Anywhere!!
たとえCPUがなくても!!
8
[朗報] OpenJDKが素敵!!
✔ オープンソースで開発されているJavaコンパイラ/実行環境
✔ 字句解析,構文解析はお任せ
✔ 最適化後の内部構造へのアクセスが簡単
✔ 実行時に型情報に触りやすい
✔ printfデバッグのノリで動作を追うことができる
✔ C/C++だとちょっと厳しい(と思う)
9
Javaプログラムへのアクセス
/** Generate code and emit a class file for a given class
* @param env The attribution environment of the outermost class
* containing this class.
* @param cdef The class definition from which code is generated.
*/
JavaFileObject genCode(Env<AttrContext> env, JCClassDecl cdef) throws IOException {
synthesijer.jcfrontend.Main.newModule(env, cdef); // add hook for synthesijer
try {
if (gen.genClass(env, cdef) && (errorCount() == 0))
return writer.writeClass(cdef.sym);
} catch (ClassWriter.PoolOverflow ex) {
log.error(cdef.pos(), "limit.pool");
} catch (ClassWriter.StringOverflow ex) {
log.error(cdef.pos(), "limit.string.overflow",
ex.value.substring(0, 20));
} catch (CompletionFailure ex) {
chk.completionError(cdef.pos(), ex);
}
return null;
}
JavaCompiler.javaのgenCode内に処理をぶら下げればよい
10
Javaコードの内部表現
この構造をたどるOpenJDKの仕組みを利用
JCMethodDecl
JCVariableDecl
JCMethodDecl
JCMethodDecl
・
・
・
・
・
・
JCVariableDecl
JCVariableDecl
JCExpressionState
JCBlock
JCIf
JCFor
JCAssign
JCArrayAccess
JCBinary
JCIdent
JCLiteral
・
・
・
・
・
・
JSCtatement
JSExpression
JCClassDecl
11
たとえばclass
public class JCTopVisitor extends Visitor{
private final Module module;
...
public void visitClassDef(JCClassDecl that){
for (JCTree def : that.defs) {
if(def == null){
;
}else if(def instanceof JCMethodDecl){
def.accept(this);
}else if(def instanceof JCVariableDecl){
def.accept(new JCStmtVisitor(module));
}else{
System.err.printf("Unknown class: %s (%s)", def, def.getClass());
}
}
}
...
構文解析器がJCClassDeclに出会ったら呼び出してくれる
12
たとえばmethod
public void visitMethodDef(JCMethodDecl decl){
String name = decl.getName().toString();
Type type;
if(JCFrontendUtils.isConstructor(decl)){
type = new MySelfType();
}else{
type = TypeBuilder.genType(decl.getReturnType());
}
Method m = new Method(module, name, type);
m.setArgs(parseArgs(decl.getParameters(), m));
...
m.setPrivateFlag(JCFrontendUtils.isPrivate(decl.mods));
m.setParallelFlag(JCFrontendUtils.isAnnotatedBy(decl.mods.annotations, "parallel"));
...
m.setConstructorFlag(JCFrontendUtils.isConstructor(decl));
...
for(JCStatement stmt: decl.body.getStatements()){
JCStmtVisitor visitor = new JCStmtVisitor(m);
stmt.accept(visitor);
m.getBody().addStatement(visitor.getStatement());
}
module.addMethod(m);
}
構文解析器がJCMethodDeclに出会ったら呼び出してくれる
13
たとえば制御構文
public void visitIf(JCIf that){
IfStatement tmp = new IfStatement(scope);
tmp.setCondition(stepIn(that.cond, scope));
tmp.setThenPart(wrapBlockStatement(stepIn(that.thenpart, scope)));
if(that.elsepart != null){
tmp.setElsePart(wrapBlockStatement(stepIn(that.elsepart, scope)));
}
stmt = tmp;
}
public void visitForLoop(JCForLoop that){
ForStatement tmp = new ForStatement(scope);
for(JCStatement s: that.init){
//tmp.addInitialize(stepIn(s, scope));
tmp.addInitialize(stepIn(s, tmp));
}
tmp.setCondition(stepIn(that.cond, tmp));
for(JCStatement s: that.step){
tmp.addUpdate(stepIn(s, tmp));
}
tmp.setBody(wrapBlockStatement(stepIn(that.body, tmp)));
stmt = tmp;
}
構文解析器がJCIfDeclに出会ったら呼び出してくれる
14
高位合成処理系は何をするか?
http://www.ida.liu.se/~petel/SysSyn/lect3.frm.pdf
基本はこれに書いてあります
High-Level Synthesis
15
高位合成処理系は何をするか
入力言語 データフロー スケジューリング
データパス生成
ステート生成
物理マッピング
16
高位合成処理系は何をするか
入力言語 データフロー スケジューリング
データパス生成
ステート生成
物理マッピング
(1) (2)
(3)
17
高位合成処理系の3つのレイヤ
(1)言語デザイン
(2)アーキテクチャの生成
(3)テクノロジ・マッピング
✔ 設計コストが小さくなるように
✔ パフォーマンスを出しやすいように
✔ 命令スケジューリング,並列性の抽出
✔ 動作周波数,リソース使用量,レイテンシの考慮
✔ 適切な物理マッピング
✔ 符号化
18
Synthesijerでは
✔ 設計コストが小さくなるように
✔ パフォーマンスを出しやすいように
✔ 命令スケジューリング,並列化の抽出
✔ 動作周波数,リソース使用量,レイテンシの考慮
✔ 適切な物理マッピング
✔ 符号化
(1)言語デザイン
(2)アーキテクチャの生成
(3)テクノロジ・マッピング
Java
- オブジェクト指向設計
- スレッドで並列化
- 既存資産の活用
ISE/Vivado,QuartusII
にお任せ
Javaから変換する
エンジンを実装
19
Synthesijerオーバービュー
Javaコード
Javaプログラムの解析
スケジューリング表を作成
最適化
HDL構文の組み立て
VHDL/
Verilog HDL
コード
Javaコード
VHDL/
Verilog HDL
コード
VHDL/
Verilog HDL
コード
中間表現
(S式)
フロントエンド
ミドルエンド
バックエンド
20
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++) ;
}
}
}
21
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モジュールを生成
22
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
23
スケジューラ表の疑似命令
✔ 四則演算,論理演算,シフト
✔ 比較
✔ 代入
✔ 配列のアドレス指定,配列アクセス
✔ Call/Return
✔ CallしたらReturnされるまで待つ(基本)
✔ Thread.startの呼び出し時は待たずに次へ
✔ 無条件ジャンプ,条件分岐,SELECT
✔ フィールドアクセス指示命令
24
Synthesijer でのHDL生成: 出力(状態遷移)
メソッド毎にスケジュール表を生成 → 状態遷移機械
while
for
for
25
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
...
26
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
27
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
...
28
最適化の例
べたなプログラムを用意
public class SimpleProgram{
public int sum(int a, int b, int c,
int d, int e, int f,
int g, int h, int i,
int j, int k, int l){
c = a + b;
f = d + e;
i = g + h;
l = j + k;
c = c + f;
l = l + i;
c = c + l;
return c;
}
}
29
最適化の例
べたなプログラムを用意
sum_0000: op=METHOD_EXIT, src=, dest=, next=0001
sum_0001: op=METHOD_ENTRY, src=, dest=, next=0002 (name=sum)
sum_0002: op=ADD, src=sum_a_0000:INT, sum_b_0001:INT, dest=binary_expr_00012:INT, next=0003
sum_0003: op=ASSIGN, src=binary_expr_00012:INT, dest=sum_c_0002:INT, next=0004
sum_0004: op=ADD, src=sum_d_0003:INT, sum_e_0004:INT, dest=binary_expr_00013:INT, next=0005
sum_0005: op=ASSIGN, src=binary_expr_00013:INT, dest=sum_f_0005:INT, next=0006
sum_0006: op=ADD, src=sum_g_0006:INT, sum_h_0007:INT, dest=binary_expr_00014:INT, next=0007
sum_0007: op=ASSIGN, src=binary_expr_00014:INT, dest=sum_i_0008:INT, next=0008
sum_0008: op=ADD, src=sum_j_0009:INT, sum_k_0010:INT, dest=binary_expr_00015:INT, next=0009
sum_0009: op=ASSIGN, src=binary_expr_00015:INT, dest=sum_l_0011:INT, next=0010
sum_0010: op=ADD, src=sum_c_0002:INT, sum_f_0005:INT, dest=binary_expr_00016:INT, next=0011
sum_0011: op=ASSIGN, src=binary_expr_00016:INT, dest=sum_c_0002:INT, next=0012
sum_0012: op=ADD, src=sum_l_0011:INT, sum_i_0008:INT, dest=binary_expr_00017:INT, next=0013
sum_0013: op=ASSIGN, src=binary_expr_00017:INT, dest=sum_l_0011:INT, next=0014
sum_0014: op=ADD, src=sum_c_0002:INT, sum_l_0011:INT, dest=binary_expr_00018:INT, next=0015
sum_0015: op=ASSIGN, src=binary_expr_00018:INT, dest=sum_c_0002:INT, next=0016
sum_0016: op=RETURN, src=sum_c_0002:INT, dest=, next=0000
sum_0017: op=JP, src=, dest=, next=0000
30
最適化の例
べたなプログラムを用意
sum_0000: op=METHOD_EXIT, src=, dest=, next=0001
sum_0001: op=METHOD_ENTRY, src=, dest=, next=0002 (name=sum)
sum_0002: op=ADD, src=sum_a_0000:INT, sum_b_0001:INT, dest=binary_expr_00012:INT, next=0003
sum_0002: op=ADD, src=sum_d_0003:INT, sum_e_0004:INT, dest=binary_expr_00013:INT, next=0003
sum_0002: op=ADD, src=sum_g_0006:INT, sum_h_0007:INT, dest=binary_expr_00014:INT, next=0003
sum_0002: op=ADD, src=sum_j_0009:INT, sum_k_0010:INT, dest=binary_expr_00015:INT, next=0003
sum_0003: op=ASSIGN, src=binary_expr_00012:INT, dest=sum_c_0002:INT, next=0010
sum_0003: op=ASSIGN, src=binary_expr_00013:INT, dest=sum_f_0005:INT, next=0010
sum_0003: op=ASSIGN, src=binary_expr_00014:INT, dest=sum_i_0008:INT, next=0010
sum_0003: op=ASSIGN, src=binary_expr_00015:INT, dest=sum_l_0011:INT, next=0010
sum_0010: op=ADD, src=sum_c_0002:INT, sum_f_0005:INT, dest=binary_expr_00016:INT, next=0011
sum_0010: op=ADD, src=sum_l_0011:INT, sum_i_0008:INT, dest=binary_expr_00017:INT, next=0011
sum_0011: op=ASSIGN, src=binary_expr_00016:INT, dest=sum_c_0002:INT, next=0014
sum_0011: op=ASSIGN, src=binary_expr_00017:INT, dest=sum_l_0011:INT, next=0014
sum_0014: op=ADD, src=sum_c_0002:INT, sum_l_0011:INT, dest=binary_expr_00018:INT, next=0015
sum_0015: op=ASSIGN, src=binary_expr_00018:INT, dest=sum_c_0002:INT, next=0016
sum_0016: op=RETURN, src=sum_c_0002:INT, dest=, next=0000
sum_0017: op=JP, src=, dest=, next=0000
31
最適化の例
べたなプログラムを用意
sum_0000: op=METHOD_EXIT, src=, dest=, next=0001
sum_0001: op=METHOD_ENTRY, src=, dest=, next=0002 (name=sum)
sum_0002: op=ADD, src=sum_a_0000:INT, sum_b_0001:INT, dest=binary_expr_00012:INT, next=0016
sum_0002: op=ADD, src=sum_d_0003:INT, sum_e_0004:INT, dest=binary_expr_00013:INT, next=0016
sum_0002: op=ADD, src=sum_g_0006:INT, sum_h_0007:INT, dest=binary_expr_00014:INT, next=0016
sum_0002: op=ADD, src=sum_j_0009:INT, sum_k_0010:INT, dest=binary_expr_00015:INT, next=0016
sum_0002: op=ASSIGN, src=binary_expr_00012:INT:chain, dest=sum_c_0002:INT, next=0016
sum_0002: op=ASSIGN, src=binary_expr_00013:INT:chain, dest=sum_f_0005:INT, next=0016
sum_0002: op=ASSIGN, src=binary_expr_00014:INT:chain, dest=sum_i_0008:INT, next=0016
sum_0002: op=ASSIGN, src=binary_expr_00015:INT:chain, dest=sum_l_0011:INT, next=0016
sum_0002: op=ADD, src=sum_c_0002:INT:chain, sum_f_0005:INT:chain, dest=binary_expr_00016:INT,
sum_0002: op=ADD, src=sum_l_0011:INT:chain, sum_i_0008:INT:chain, dest=binary_expr_00017:INT,
sum_0002: op=ASSIGN, src=binary_expr_00016:INT:chain, dest=sum_c_0002:INT, next=0016
sum_0002: op=ASSIGN, src=binary_expr_00017:INT:chain, dest=sum_l_0011:INT, next=0016
sum_0002: op=ADD, src=sum_c_0002:INT:chain, sum_l_0011:INT:chain, dest=binary_expr_00018:INT,
sum_0002: op=ASSIGN, src=binary_expr_00018:INT:chain, dest=sum_c_0002:INT, next=0016
sum_0016: op=RETURN, src=sum_c_0002:INT, dest=, next=0000
sum_0017: op=JP, src=, dest=, next=0000
32
最適化の例
内部はS式.S式を外でいじって処理系に戻すことも可
(SEQUENCER sum
(SLOT 0
(METHOD_EXIT :next (1))
)
(SLOT 1
(METHOD_ENTRY :next (2))
)
(SLOT 2
(SET binary_expr_00012 (ADD sum_a_0000 sum_b_0001) :next (16))
(SET binary_expr_00013 (ADD sum_d_0003 sum_e_0004) :next (16))
(SET binary_expr_00014 (ADD sum_g_0006 sum_h_0007) :next (16))
(SET binary_expr_00015 (ADD sum_j_0009 sum_k_0010) :next (16))
(SET sum_c_0002 (ASSIGN binary_expr_00012) :next (16))
...略...
(SET sum_c_0002 (ASSIGN binary_expr_00016) :next (16))
(SET sum_l_0011 (ASSIGN binary_expr_00017) :next (16))
(SET binary_expr_00018 (ADD sum_c_0002 sum_l_0011) :next (16))
(SET sum_c_0002 (ASSIGN binary_expr_00018) :next (16))
)
(SLOT 16
(RETURN sum_c_0002 :next (0))
)
(SLOT 17
(JP :next (0))
)
)
33
SynthesijerはJavaベースなので...
オブジェクト指向的プログラミング!!
… … …
34
インスタンス生成
クラスのインスタンスを生成/利用できる
public class Test002 {
public static final int DEFAULT_VALUE = 0x20;
public int[] a = new int[128];
public int x, y;
public void init(){
for(int i = 0; i < a.length; i++){
a[i] = 0;
}
}
public void set(int i, int v){
a[i] = v;
}
…
}
ex. sample/test/Test002.javaとsample/test/Test003.java
public class Test003 {
private final Test002 t = new Test002();
public void test(){
t.init();
t.set(0, 100); // 0 <- 100
…
}
…
}
35
インスタンス生成
クラスのインスタンスを生成/利用できる
ex. sample/test/Test002.javaとsample/test/Test003.java
Test002 class_t_0000 (
.clk(class_t_0000_clk),
.reset(class_t_0000_reset),
.a_address(class_t_0000_a_address),
.a_we(class_t_0000_a_we),
.a_oe(class_t_0000_a_oe),
.a_din(class_t_0000_a_din),
.a_dout(class_t_0000_a_dout),
.a_length(class_t_0000_a_length),
…
.set_i(class_t_0000_set_i),
.set_v(class_t_0000_set_v),
…
.init_req(class_t_0000_init_req),
.init_busy(class_t_0000_init_busy),
…
.set_req(class_t_0000_set_req),
.set_busy(class_t_0000_set_busy),
…
);
36
インスタンス生成・拡張モジュール
VHDL/Verilog HDLで書いたモジュールのインスタンス化
module hoge(
input wire clk,
input wire reset,
input signed [31:0] a_address,
input signed [31:0] a_din,
input wire we,
input wire oe,
output signed [31:0] a_dout,
output signed [31:0] a_length,
input wire func_req,
output wire func_busy,
output wire [31:0] q
);
…
endmodule
clk
reset
a_address
a_din
a_we
a_oe
a_din
a_dout
func_req
func_busy
hoge q
ex. Verilog HDLで書いたhogeをJavaから呼び出す
a_length
37
インスタンス生成・拡張モジュール
VHDL/Verilog HDLで書いたモジュールのインスタンス化
class HogeIface extends HDLModule{
int[] a;
void func(){}
public HogeIface(String... args){
newPort("a_address", HDLPort.DIR.IN, genSignedType(32));
newPort("a_din", HDLPort.DIR.IN, genSignedType(32));
newPort("a_we", HDLPort.DIR.IN, genBitType());
newPort("a_oe", HDLPort.DIR.IN, genBitType());
newPort("a_dout", HDLPort.DIR.OUT, genSignedType(32));
newPort("a_length", HDLPort.DIR.OUT, genSignedType(32));
newPort("func_req", HDLPort.DIR.IN, genBitType());
newPort("func_busy", HDLPort.DIR.OUT, genBitType());
newPort("q", HDLPort.DIR.OUT, genVectorType(32), Enum.of(OPTION.EXPORT));
}
…
}
↓のようなJava用のダミーコードを書いて,使う
…
private final HogeIface obj = new
HogeIface();
…
private void func(){
obj.a[10] = 100;
obj.func();
…
a[]
func()
これはJavaでは使わない,という印
38
インスタンス生成の例
乱数生成のハードウェアをJavaから使う
// xorshift RNG, period 2^128-1
// cf. http://www.jstatsoft.org/v08/i14/paper
module xor128
(
input wire clk, input wire reset, output reg [63:0] q
);
reg[31:0] x = 123456789, y = 362436069, z = 521288629;
reg[31:0] w = 88675123;
reg[31:0] t;
always @(posedge clk) begin
q[63:32] <= 32'h0;
if(reset == 1'b1) begin
x <= 123456789;
y <= 362436069;
z <= 521288629;
w <= 88675123;
end else begin
t = x ^ (x << 11);
x = y; y = z; z = w;
w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
q[31:0] <= w;
end
end
endmodule
39
インスタンス生成の例
乱数生成のハードウェアをJavaから使う
/**
* リスト15: XOR128.java
* xor128をJavaから利用するためのダミークラス
*/
import synthesijer.hdl.HDLModule;
import synthesijer.hdl.HDLPort;
import synthesijer.hdl.HDLPrimitiveType;
public class XOR128Iface extends HDLModule{
// Javaプログラムのためのダミー変数
// xor128の出力qに相当する
public long q;
public XOR128Iface(String... args){
// - 実際に使用するモジュール名
// - クロック信号名
// - リセット信号名
// の順に指定する.
super("xor128", "clk", "reset");
// メンバ変数"q"に相当する64bit幅の出力ポートを生成する
newPort("q", HDLPort.DIR.OUT, HDLPrimitiveType.genSignedType(64));
}
}
40
インスタンス生成の例
乱数生成のハードウェアをJavaから使う
/**
* リスト16: XOR128Test.java
* xor128をJavaから利用する例
*/
public class XOR128Test{
// XOR128モジュールのインスタンスを生成
private final XOR128Iface rng = new XOR128Iface();
public boolean test(){
long v = rng.q; // 乱数を読み出す
// 処理の例.たとえば1000より大きければ真,とか.
if(v > 1000){
return true;
}else{
return false;
}
}
}
41
インスタンス生成の例
乱数生成のハードウェアをJavaから使う
42
クラスの継承も可
継承したクラスのメソッドも利用可能
public class Test012 extends Test010{
public void run(){
test();
}
}
public class Test010{
public void test(){
int a = 20;
int b = 30;
int c = 0;
c = a & b;
c = a | b;
c = a ^ b;
}
}
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity Test012 is
port (
clk : in std_logic;
reset : in std_logic;
run_busy : out std_logic;
run_req : in std_logic;
test_busy : out std_logic;
test_req : in std_logic
);
end Test012;
architecture RTL of Test012 is
...
43
SynthesijerはJavaベースなので...
Threadを使って並列化できる
… … …
44
スレッドの利用例
JavaではThreadクラスを継承して並列動作を記述
/*
* リスト11: ThreadCounter.java
* Threadの活用例
*/
// JavaではThreadクラスを継承したクラスを作る
public class ThreadCounter extends Thread{
public int counter = 0;
// Threadの処理はrunメソッドで実装する
public void run(){
while(true){
// 変数をインクリメントする無限ループ
counter++;
}
}
}
45
スレッドの利用例
JavaではThreadクラスを継承して並列動作を記述
import synthesijer.rt.unsynthesizable;
public class ThreadTest{
private final ThreadCounter t0 = new ThreadCounter();
private final ThreadCounter t1 = new ThreadCounter();
public void test(){
t0.start();
t1.start();
}
// このメソッドはSynthesijerでは無視する
@unsynthesizable
public static void main(String... args){
ThreadTest t = new ThreadTest();
t.test();
while(true){
System.out.println("t0:" + t.t0.counter);
System.out.println("t1:" + t.t1.counter);
try{
Thread.sleep(1);
}catch(Exception e){
e.printStackTrace();
}
}
}
}
46
スレッドの利用例
PCで実行したところ
47
スレッドの利用例
シミュレーションで確認したところ
48
ここまでのまとめ
✔ Synthesijer=JavaをVHDL/Verilog HDLに変換する処理系
✔ Javaなりのオブジェクト指向設計をサポート
✔ Threadによる並列処理の記述とHW化
49
Synthesijerオーバービュー
Javaコード
Javaプログラムの解析
スケジューリング表を作成
最適化
HDL構文の組み立て
VHDL/
Verilog HDL
コード
Javaコード
VHDL/
Verilog HDL
コード
VHDL/
Verilog HDL
コード
中間表現
(S式)
フロントエンド
ミドルエンド
バックエンド
50
Synthesijer as a Compiler-Infrastructure
Javaコード
スケジューリング表を作成
最適化
Y構文の組み立て
VHDL/
Verilog HDL
コード
X言語
VHDL/
Verilog HDL
コード
中間表現
(S式)
フロントエンド
ミドルエンド
バックエンド
X言語パーザー 最適化器
Y言語
1
Synthesijer サンプル・事例 
2
2
✔ Javaといえば,スクリプト言語のホストとしても魅力的
✔ JRuby,Scala,Clojure,and etc.
✔ BrainF**k: とても小さなスクリプト言語処理系
→ hoge
サンプル1: プログラムインタプリタ
+, -, >, <, [, ], ., ,の記号からなるインタプリタ
++++++++++[>++++++++++<-]>++++.+++++++.--------.--.
http://www.kmonos.net/alang/etc/brainfuck.php
3
サンプル1: BFのコード抜粋
private IO io = new IO();
private byte[] prog = new byte[CODESIZE];
private byte[] data = new byte[ARRAYSIZE];
private int ptr, pc;
public boolean step() {
byte cmd = prog[pc];
byte tmp;
int nlvl = 0;
switch (cmd) {
case 0: return false;
case '>': ptr++; break;
case '<': ptr--; break;
case '+': data[ptr] = (byte) (data[ptr] + 1); break;
case '-': data[ptr] = (byte) (data[ptr] – 1); break;
case '.': io.putchar(data[ptr]); break;
case ',': data[ptr] = io.getchar(); break;
case '[':
if (data[ptr] == (byte) 0) {
while (true) {
pc++;
if(prog[pc] == ']' && nlvl == 0) break;
if(prog[pc] == '[') nlvl++;
if(prog[pc] == ']') nlvl--;
}
}
break;
case ']':
…
}
}
4
サンプル1: ソフトウェアとして実行
✔ 標準入出力越しでBrainF**kインタプリタを実行
✔ +, -, >, <, [, ], ., ,の記号からなるインタプリタ
5
サンプル1: FPGAで実行
✔ 標準入出力の代わりにシリアル通信越しで実行
6
SWとHWで同じコードを利用
ソフトウェアで実行する時
BF
IO
Console
合成して実機で動かす時
IO
+ putchar()
+ getchar()
+ putchar()
+ getchar()
RS232Wrapper
7
サンプル1: 文字の入出力ルーチン
public void read() {
prompt();
for (int i = 0; i < CODESIZE; i++) {
byte b;
b = io.getchar();
//io.putchar(b);
if (b == 'n' || b == 'r') {
prog[i] = (byte) 0;
break;
} else {
prog[i] = b;
}
}
}
public void print() {
boolean flag = true;
for (int i = 0; i < CODESIZE; i++) {
byte b = prog[i];
if (b == 0) {
break;
}
io.putchar(b);
}
io.putchar((byte) 'n');
}
8
サンプル1: SW版とHW版の入出力
public class IO {
private rs232c obj = new rs232c();
public void putchar(byte c) {
obj.write(c);
}
public byte getchar() {
byte b;
b = obj.read();
return b;
}
}
public class IO{
public void putchar(byte c){
System.out.print((char)c);
}
public byte getchar(){
try{
return (byte)(System.in.read());
}catch(Exception e){
throw new RuntimeException(e);
}
}
}
9
サンプル2: ディスプレイに絵を書く
public class BitMapTest extends Thread{
...
public void run(){
// 座標(100, 100)の位置にサイズ20の正方形を描画
canvas.rect(100, 100, 20, 20, BitMapCanvas.RED, 0);
int c0 = 0, c = 0;
// 画面上にサイズ40の正方形を色を変えながら敷き詰める
for(int i = 0; i < 16; i++){ // (/ 640 40)16
c = c0;
for(int j = 0; j < 12; j++){ // (/ 480 40)
canvas.rect(40*i, 40*j, 40, 40, color(c), 1);
c = (c + 1) & 0x7;
}
c0 = (c0 + 1) & 0x7;
}
// 線を描画するメソッドのテスト
canvas.line(0, 0, 639, 479, color(7), 1);
canvas.line(639, 0, 0, 479, color(7), 1);
// フレームバッファ1をスクロールさせる
int v = 0, h = 0;
while(true){
canvas.set_offset(0, v, 1);
v = (v == 479) ? 0 : v + 1;
t.sleep(1); // 適当なウェイト
}
}
10
✔ ソフトウェアとして実行して動作を確認
サンプル2: ディスプレイに絵を書く
11
✔ 実FPGAとディスプレイで同じ動作を確認
サンプル2: ディスプレイに絵を書く
12
サンプル3: AHCI
✔ Advanced Host Controller Interface
✔ SATAなHDDやSSDを接続するためのインターフェース
✔ 最近のOSのほとんどでサポートされている
= 標準のデバドラでブロックデバイスにみえる
✔ SATAなHDDやSSD以外に接続してはいけない,ことはない
✔ AHCI HBAをFPGAに実装してディスクアクセスしてみよう
13
サンプル3: AHCI
PC
FPGA
ディスク?
何かの
処理
ディスク
インターネット
✔ なんでもディスクに見せてしまうのは楽しそう
✔ たとえば
BRAM
14
一般的なAHCIによるディスク接続
ディスクに送るコマンドを預かる
ディスクからのリプライを返す
作業用メモリのポインタの確認
複数コマンドをOoOで発行(NCQ)
ディスクへのFISの発行
ディスクからのFISの受信
ステータス管理
15
AHCIのメモリチェイン
どのコマンドが
有効かはPxCI
レジスタをみる
ディスクに
送るべきコマンド
PCIeのBAR5に
レジスタ空間への
ポインタがある
ディスクとの
やり取りに使う
メモリ領域への
ポインタ
近代的なOSでは大量の仮想メモリを複数の細かい実メモリに分割して扱う
ディスクとの
やり取りに使う
メモリ領域
P0CLB
HBAからは
P0CLBの
値でたどる
16
AHCI越しのデータ授受のフロー
PCIe越しの通信
17
HBAの動作フロー/FIS取得まで
private int wait_for_command(){
while(reg.values[P0CI] == 0) ;
reg.values[P0CMD] = 0x10110007; // 処理開始
int id = get_port_id(reg.values[P0CI]); // '1'のbitを選ぶ
axi.fetch(reg.values[P0CLB] + (id << 5), 4); // command headerを取得
dw0 = axi.read(0); // PRDTL, PMP, RCBRPWA, CFL
dw1 = axi.read(1); // PRD Byte Count
dw2 = axi.read(2); // CTBA0
dw3 = axi.read(3);
prdtl = (dw0 >> 16) & 0x0000FFFF;
ctba = dw2;
axi.fetch(ctba, 5);// CFIS取得
cfis_dw0 = axi.read(0); // Features,
// Command,…
cfis_dw1 = axi.read(1);
cfis_dw2 = axi.read(2);
cfis_dw3 = axi.read(3);
return (dw0 >> 16) & 0x000000FF;
}
P0CLB
18
動作例
PCIデバイス→AHCIデバイス→ディスクに見えている
うまくOSを
だませている
/dev/sdbらしい
ddとかできる
19
Synthesijer 活用方法 - 3つのパタン
20
3つの開発パタン
(1) Javaによるモジュールだけでシステムを構成
(2) HDLによるモジュールを部品として利用.全体管理はJavaで記述
= 既存IPコア,FPGAの性能を活用
(3) Javaによるモジュールを部品として利用.全体管理はHDLで記述
= 複雑なアルゴリズムをSWプログラマに書いてもらう.SW資産の活用
(1)Javaでシステムを構成 (2)Java + HDL記述の部品 (3)HDL + Java記述の部品
21
(1) Javaでシステムを構成
✔ すべてをJavaで記述
✔ トップモジュール,UCF/XDCなんかは必要
✔ I/Oなどは用意されたライブラリを利用
✔ シリアルI/O,SC1602,純粋なInput/Output, ...
✔ AXI(32bit逐次,シンプルなキャッシュ),UPL,...
22
(2) Java+HDL記述の部品
✔ JavaプログラムにHDL記述の部品を埋め込む
✔ Javaで記述したオブジェクトのようにHDL記述部品をインスタンス化して使う
✔ HDLモジュールを簡単に使い回せる
✔ Synthesijer内部でどうオブジェクトが扱われるかを知る必要がある
✔ Javaとのブリッジのために HDLModule を継承したクラスを実装
✔ 合成時にはHDL記述のコードと組み合わせる
✔ HWプログラマがサポートしつつSWプログラマにFPGAを活用してもらう!!
HogeModule obj = new HogeModule();
obj.x = 0;
obj.data[0] = 100;
class HogeModule extends HDLModule{
int x;
int[] data;
HogeModule(){ super("hoge_module", ...); }
entity hoge_module is
port(
x : ...
data_waddr : …
data_wdata : ...
見かけ上の
接続
実際の接
続
SWプログラマに
HWモジュールを有効活用してもらう
23
インスタンス生成・拡張モジュール
VHDL/Verilog HDLで書いたモジュールのインスタンス化
module hoge(
input wire clk,
input wire reset,
input signed [31:0] a_address,
input signed [31:0] a_din,
input wire we,
input wire oe,
output signed [31:0] a_dout,
output signed [31:0] a_length,
input wire func_req,
output wire func_busy,
output wire [31:0] q
);
…
endmodule
clk
reset
a_address
a_din
a_we
a_oe
a_din
a_dout
func_req
func_busy
hoge q
ex. Verilog HDLで書いたhogeをJavaから呼び出す
a_length
24
インスタンス生成・拡張モジュール
VHDL/Verilog HDLで書いたモジュールのインスタンス化
class HogeIface extends HDLModule{
int[] a;
void func(){}
public HogeIface(String... args){
newPort("a_address", HDLPort.DIR.IN, genSignedType(32));
newPort("a_din", HDLPort.DIR.IN, genSignedType(32));
newPort("a_we", HDLPort.DIR.IN, genBitType());
newPort("a_oe", HDLPort.DIR.IN, genBitType());
newPort("a_dout", HDLPort.DIR.OUT, genSignedType(32));
newPort("a_length", HDLPort.DIR.OUT, genSignedType(32));
newPort("func_req", HDLPort.DIR.IN, genBitType());
newPort("func_busy", HDLPort.DIR.OUT, genBitType());
newPort("q", HDLPort.DIR.OUT, genVectorType(32), Enum.of(OPTION.EXPORT));
}
…
}
↓のようなJava用のダミーコードを書いて,使う
…
private final HogeIface obj = new
HogeIface();
…
private void func(){
obj.a[10] = 100;
obj.func();
…
a[]
func()
これはJavaでは使わない,という印
25
(3) HDL+Java記述の部品
✔ HDLで設計したシステムにJava記述の部品を埋め込む
✔ 複雑なアルゴリズムの処理でもJavaなら(比較的)手軽に実装
✔ HDLで自然に実装できるストリーム処理,並列処理を活用
✔ Synthesijerで合成した回路がどういう構成か知る必要がある
✔ SWプログラマ/資産をFPGA設計に活用!!
class HogeModule{
int hoge_func(int a){
…
}
entity hoge_module is
port(
hoge_func_a : in ...
hoge_func_return : out …
hoge_func_req : in …
hoge_func_busy : out ...
Synthesijer
hoge_module
hoge_func_req
hoge_func_a hoge_func_return
hoge_func_busy
26
複雑/面倒なアルゴリズム処理の実装
✔ 例: バブルソートじゃなくてマージソートの採用,など
✔ バブルソート(512個の降順→昇順)
✔ マージソート(512個の降順→昇順) x15
27
複雑なアルゴリズム処理はJavaで実装
✔ バブルソートの状態遷移 ✔ マージソートの状態遷移
28
最近よく実装しているパタン
FIFO
実行
ステージ
FIFO
実行
ステージ
FIFO
スループット T [bps]
実行
ステージ
FIFO
実行
ステージ
FIFO
実行
ステージ
FIFO
実行
ステージ
FIFO
ここを
Javaで書く
1
今できていること
✔ とりあえず使える
✔ Javaの制御構文,メソッド呼び出し,演算
✔ とてもシンプルな最適化
✔ Vivado向けIPコアテンプレートの自動生成
Source
Abstraction
Level
Ease of
Impl.
Learning
curve
Document-
ation
Floating/
Fixed Pt.
Design
Exploration
Testbench
generation
Verification
Size FPGA
Slices
Synthesijer Java untimed + + -
Auto
conversion
+/- - -
2
手が回っていないこと
✔ もう少し賢い最適化
✔ メモリアクセスレイテンシの隠蔽
✔ 演算レイテンシを考慮したチェイニング
✔ リソースシェアリング
3
今後挑戦したいこと
✔ メソッドのパイプライン化
✔ Javaプログラムとしてどう扱うか
✔ I/Oストリームへの対応
✔ コンストラクタに対応
✔ コンパイル時のJavaプログラム実行
✔ lambda式対応
✔ Streamへの対応
1
+α Synthesijer.scala
2
RTL設計の辛さ
✔ “ ”信号の流れ を記述する
✔ “ ” “ ”処理の流れ を 信号の流れ に変換
↔ “ ”書きたいのは 処理の流れ
✔たくさんの似たような構造
✔ たくさんの似たような名前
✔ 記述の再利用をしたいが難しい
本質としては
実務的には
3
手軽なFPGA開発のための取り組み
✔ 高位合成言語処理系
✔ DSL
4
高位合成処理系
✔ CやJava,C#などを入力言語とした開発環境
✔ 開発コストを小さくできる
✔ 生成したHWの質は処理系依存
✔ 良いHW生成にはコツが必要
✔ ディレクティブの活用
✔ 書き方を考える必要がある
5
高位合成処理系
✔ Vivado HLS
✔ OpenCL対象の処理系
✔ CyberWorkBench
✔ Cynthesizer
✔ Symphony C Compiler
✔ ImpulseC
✔ Lime
✔ Synthesijer
などなどなど
6
DSLベースの設計手法
✔ RTL設計を楽にするためのDSL
✔ 実装したいアプリケーション別のDSL
✔ プログラミングモデルに特化したDSL
7
様々なDSLベースのシステム開発(1)
✔ MyHDL (Pythonベース)
✔ JHDL (Javaベース)
✔ Chisel (Scalaベース)
✔ PyVerilog (Pythonベース)
などなどなど
RTL設計(あるいは少し抽象的なHW設計)を
より楽にするためのDSL
8
様々なDSLベースのシステム開発(2)
✔ Spiral ←Linear Digital Processing
✔ HDL Coder ← 信号処理(Matlab)
✔ Optimus ← ストリーム処理
✔ LINQ ← クエリプロセッシング
などなどなど
✔ DSLを作るツールも.(たとえば,LMS/Scala)
実装したいアプリケーションに特化したDSL
9
様々なDSLベースのシステム開発(3)
✔ Bluespec (並行プログラミング)
✔ MaxCompiler (データフロープログラミング)
✔ FloPoCo (浮動小数点数パイプライン)
✔ SPGen (パイプライン)
などなどなど
使用するプログラミングモデルに特化したDSL
10
DSLベースの設計手法
✔ RTL設計を楽にするためのDSL
←依然RTLであることに代わりはない
✔ 実装したいアプリケーション別のDSL
←HWの設計探索をしたい場合には不向き
✔ プログラミングモデルに特化したDSL
→さて,どんなモデルがよいだろうか?
11
FPGAが有用なのはなぜか?
✔ 論理回路・データパスを自由に作り込めるLSI
✔ I/Oを自由に使える
✔ クロックレベルの同期と並列性を活用した処理を実現
Field Programmable Gate Array
12
FPGAが有用なのはなぜか?
10G if
DRAM
Network
adapter
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 より
データはどうせ移動させる
移動途中で副次的に処理できる
13
鍵はパイプライン並列化
FIFO
スループット T [bps]
w [byte]
f [Hz]
実行
ステージ
FIFO
実行
ステージ
実行
ステージ
14
データが来たら迎え撃つ
15
鍵はパイプライン並列化
パケットデータが 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
実行
ステージ
実行
ステージ
とはいえ,各ステージで状態遷移のある処理が必要
16
鍵はパイプライン並列化
パケットデータが 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
実行
ステージ
実行
ステージ
とはいえ,各ステージで状態遷移のある処理が必要
限られた
許容サイクルを
効率よく使う必要
17
組み合わせ回路/データ並列性の活用
✔ プロセッサと比べてFPGA回路のφは圧倒的に低速
✔ 高速データ処理では1クロックでデータを捌く必要も
✔ 時にはソフトウェア実装とは全く違う場合も
条件
・・・
条件
v.s
18
欲しいDSL
✔ Bluespec (並行プログラミング)
✔ MaxCompiler (データフロープログラミング)
✔ FloPoCo (浮動小数点数パイプライン)
などなどなど
使用するプログラミングモデルに特化したDSL
状態遷移および各状態での処理設計がやりやすく
組み合わせ回路が書きやすい言語
19
設計: Synthesijer.scala
✔ 組み合わせ回路の設計の容易は失わないまま
✔ “処理の流れ”の記述を容易にする
✔ クロックベースの状態管理と状態遷移を言語機能に
✔ 内部DSLとして設計.回路設計にScalaの機能を活用.
✔ 設計資産の再利用性を高める
✔ 見通しの良い設計を可能にする
20
Synthesijer.scala とは
✔ Synthesijerのバックエンドを使ってScala“で”HDLを書く
✔ signal, port: 状態を変更可能なオブジェクト
✔ expr: 副作用なしの式
✔ sequencer: 状態遷移機械
✔ module: モジュール全体
✔ 上記のオブジェクトをScalaでインスタンス化.つなぎ合わせる.
21
Synthesijer.Scalaの立ち位置
Javaコード
Javaプログラムの解析
スケジューリング表を作成
最適化
HDL構文の組み立て
VHDL/
Verilog HDL
コード
Javaコード
VHDL/
Verilog HDL
コード
VHDL/
Verilog HDL
コード
中間表現
(S式)
フロントエンド
ミドルエンド
バックエンド
Scalaで
自分で組立て
22
開発フロー
Scalaプログラムとして実装
→ VHDLまたはVerilog HDLを生成
RTLシミュレーションによる動作検証
使用するFPGAにあわせた制約を定義
ツールで合成,配置配線,FPGA構成情報生成
実機で動作確認
Synthesijer.Scalaを使ってモジュールを実装
23
モデル
モジュールの設計単位
入出力.
クロック単位で状態保持
組み合わせ回路.
状態は持たない
クロック単位での状態保持
状態遷移マシン
24
はじめてのSynthesijer.scala
✔ Lチ カ の 例
def generate_led() : Module = {
val m = new Module("led")
val q = m.outP("q")
val counter = m.signal(32)
q <= counter.ref(5)
val seq = m.sequencer("main")
counter <= (seq.idle, VECTOR_ZERO)
val s0 = seq.idle -> seq.add()
counter <= s0 * (counter + 1)
return m
}
def generate_sim(target:Module, name:String) : SimModule = {
val sim = new SimModule(name)
val inst = sim.instance(target)
val (clk, reset, counter) = sim.system(10)
inst.sysClk <= clk
inst.sysReset <= reset
return sim
}
25
ベンディングマシンの例
ドリンク
自動販売機
¢5
¢10
ドリンク一杯¢20
お釣りは出ません
26
RTLでの設計の場合
…
type stateType is (NONE, CHARGE_5, CHARGE_10, CHARGE_15, OK)
signal state, next_state: stateType := NONE;
…
case (state) is
when NONE =>
if nickel then
next_state <= CHARGE_5;
elsif dime then
next_state <= CHARGE_10;
else
next_state <= NONE;
end if;
when CHARGE_5 =>
if nickel then
next_state <= CHARGE_10;
elsif dime then
next_state <= CHARGE_15;
else
next_state <= NONE;
end if;
…
27
ベンディングマシンの例
class VendingMachine(n:String,c:String,r:String) extends Module(n,c,r){
val nickel = inP("nickel")
val dime = inP("dime")
val rdy = outP("rdy")
val seq = sequencer("main")
val s5,s10,s15,s_ok = seq.add()
rdy <= (seq.idle, LOW)
rdy <= (s_ok, HIGH)
seq.idle -> (nickel, s5)
seq.idle -> (dime, s10)
s5 -> (nickel,s10)
s5 -> (dime, s15)
s10 -> (nickel, s15)
s10 -> (dime, s_ok)
s15 -> (nickel, s_ok)
s15 -> (dime, s_ok)
s_ok -> seq.idle
}
val m = new VendingMachine("machine", "clk", "reset")
m.genVHDL()
m.visuallize_statemachine()
28
ベンディングマシンのステートマシン
29
Scalaの機能を使った設計効率化の向上
✔ 設計資産をメソッドやクラスとして保存,再利用
✔ 類似オブジェクトや類似オブジェクトの生成
✔ ループとパタンマッチによる直列化/復元コードの生成
30
設計資産の再利用
例: デコーダ (7セグメントLEDの点灯)
4
0
2
51
6
7
3
31
設計資産の再利用
process (data)
begin
case (data) is
when 0 => segment <= X"7e";
when 1 => segment <= X"30";
…
when 9 => segment <= X"79";
when others => null;
end case;
end process;
4
0
2
51
6
7
3
毎回このパターンを書かないといけない.
従来のHDLによるRTL設計の場合
32
設計資産の再利用
def decoder(s:ExprItem, l:List[(Int,Int)], w:Int) = {
l.foldRight[ExprItem](value(0,w)){
(a, z) => ?(s == a._1, value(a._2, w), z)
}
val tbl = List((0, 0x7e), (1, 0x30), …, (9, 0x79))
segment := decoder(data, tbl, segment.width())
パターンを作るメソッド.回路のレシピ.
Synthesijer.scalaを使う場合
実データに合わせた回路の生成
33
自分なりのパタン,最適化の埋め込みも
✔ 組み合わせ回路の段数に応じたFF(状態)の追加,除去
✔ 入出力データに対するパタンマッチ
✔ よく使うモジュールのテンプレート化
例えば...
などなど
34
自分なりの実装,例
例えば...ANDゲートをLUTじゃなくてMUXで作りたい
35
自分なりの実装,例
継承とオーバーライドを使って,自然に表現可能
val x0 = inP("x0")
val y0 = inP("y0")
val z0 = outP("z0")
val z1 = outP("z1")
val z2 = outP("z2")
z0 := x0 and y0
val x1c = new CARRY4Sig(x0)
val y1c = new CARRY4Sig(y0)
z1 := x1c and y1c
z2 := z0 or z1
36
自分なりの実装,例
例えば...ANDゲートをLUTじゃなくてMUXで作りたい
37
自分なりの実装,例
例えば...ANDゲートをLUTじゃなくてMUXで作りたい
1
さて,未来はどうなる?
2
ポテンシャルをどう活かすか!!
https://www.youtube.com/watch?v=FCmfcfPt4T4
3
各社の取り組み
✔ Xilinx SDx (特にSDSoC)
✔ Altera SDP
✔ IBM Lime
✔ Microsoft Kiwi
✔ CoRAM/PyCoRAM
“システムをどう作るか”,がターゲット
= システムとLSI
4
Xilinx SDSoC
Zynq向けのSW/HWコデザインツール
5
Altera SDP
SPCS005 — Technology Insight: Workload Acceleration, IDF2015
6
IBM Lime
Java + Isolation + Abstract Parallelism + Extraction
7
Microsoft Kiwi (Distributing C#)
Greaves, D.; Singh, S., "Distributing C# methods and threads over Ethernet-connected FPGAs using Kiwi," in Formal Methods and Models
for Codesign (MEMOCODE), 2011 9th IEEE/ACM International Conference on , vol., no., pp.1-9, 11-13 July 2011
8
CoRAM/PyCoRAM
高前田先生@NAIST
9
未来で,どう開発したい?
1
まとめ
✔ Javaベースの高位合成処理系を作って/使っています
✔ まだまだですが,こういう人もいる,と.
✔ 中間表現のS式を操作して処理系に戻せるので,
最適化器実装してみたいという人がいたら是非
✔ 結構,楽しい時代だと思っている
✔ ...FPGAって米国産なんだよなあ...
Javaコンパイラ
フロントエンド
Synthesijer
エンジン
Javaコンパイラ
バックエンド
.class
ソフトとして実行
同じJavaプログラムをソフトウェアとしても
FPGA上のハードウェアとしても実行可能
2
参考
✔ http://synthesijer.github.io/web
✔ リソース一式,クイックスタートガイドなど
✔ http://qiita.com/kazunori279/items/4951ca5f6164040878ce
✔ Synthesijer関連資料まとめ Qiita
✔ http://labs.beatcraft.com/ja/index.php?Synthesijer
✔ Altera DE0-nanoでのサンプルの動作手順など
✔ http://wasa-labo.com/wp/
✔ わさらぼ ブログ – 開発状況,Tipsなど

Contenu connexe

Tendances

x86とコンテキストスイッチ
x86とコンテキストスイッチx86とコンテキストスイッチ
x86とコンテキストスイッチMasami Ichikawa
 
Javaで簡単にgpgpu aparapi
Javaで簡単にgpgpu aparapiJavaで簡単にgpgpu aparapi
Javaで簡単にgpgpu aparapiKen'ichi Sakiyama
 
Javaでトランザクショナルメモリを使う
Javaでトランザクショナルメモリを使うJavaでトランザクショナルメモリを使う
Javaでトランザクショナルメモリを使うKenji Kazumura
 
C++ AMPを使ってみよう
C++ AMPを使ってみようC++ AMPを使ってみよう
C++ AMPを使ってみようOsamu Masutani
 
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_cccJEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_cccYujiSoftware
 
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)Takeshi Yamamuro
 
新しい並列for構文のご提案
新しい並列for構文のご提案新しい並列for構文のご提案
新しい並列for構文のご提案yohhoy
 
【関東GPGPU勉強会#4】GTX 1080でComputer Vision アルゴリズムを色々動かしてみる
【関東GPGPU勉強会#4】GTX 1080でComputer Visionアルゴリズムを色々動かしてみる【関東GPGPU勉強会#4】GTX 1080でComputer Visionアルゴリズムを色々動かしてみる
【関東GPGPU勉強会#4】GTX 1080でComputer Vision アルゴリズムを色々動かしてみるYasuhiro Yoshimura
 
OPcache の最適化器の今
OPcache の最適化器の今OPcache の最適化器の今
OPcache の最適化器の今y-uti
 
GPGPU deいろんな問題解いてみた
GPGPU deいろんな問題解いてみたGPGPU deいろんな問題解いてみた
GPGPU deいろんな問題解いてみたRyo Sakamoto
 
C/C++プログラマのための開発ツール
C/C++プログラマのための開発ツールC/C++プログラマのための開発ツール
C/C++プログラマのための開発ツールMITSUNARI Shigeo
 
SQLチューニング入門 入門編
SQLチューニング入門 入門編SQLチューニング入門 入門編
SQLチューニング入門 入門編Miki Shimogai
 
20090107 Postgre Sqlチューニング(Sql編)
20090107 Postgre Sqlチューニング(Sql編)20090107 Postgre Sqlチューニング(Sql編)
20090107 Postgre Sqlチューニング(Sql編)Hiromu Shioya
 
Pgunconf 20121212-postgeres fdw
Pgunconf 20121212-postgeres fdwPgunconf 20121212-postgeres fdw
Pgunconf 20121212-postgeres fdwToshi Harada
 
整数列圧縮
整数列圧縮整数列圧縮
整数列圧縮JAVA DM
 
C++による数値解析の並列化手法
C++による数値解析の並列化手法C++による数値解析の並列化手法
C++による数値解析の並列化手法dc1394
 
あるコンテキストスイッチの話
あるコンテキストスイッチの話あるコンテキストスイッチの話
あるコンテキストスイッチの話nullnilaki
 
【関東GPGPU勉強会#3】OpenCVの新機能 UMatを先取りしよう
【関東GPGPU勉強会#3】OpenCVの新機能 UMatを先取りしよう【関東GPGPU勉強会#3】OpenCVの新機能 UMatを先取りしよう
【関東GPGPU勉強会#3】OpenCVの新機能 UMatを先取りしようYasuhiro Yoshimura
 

Tendances (20)

x86とコンテキストスイッチ
x86とコンテキストスイッチx86とコンテキストスイッチ
x86とコンテキストスイッチ
 
Javaで簡単にgpgpu aparapi
Javaで簡単にgpgpu aparapiJavaで簡単にgpgpu aparapi
Javaで簡単にgpgpu aparapi
 
Javaでトランザクショナルメモリを使う
Javaでトランザクショナルメモリを使うJavaでトランザクショナルメモリを使う
Javaでトランザクショナルメモリを使う
 
C++ AMPを使ってみよう
C++ AMPを使ってみようC++ AMPを使ってみよう
C++ AMPを使ってみよう
 
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_cccJEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
 
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
 
新しい並列for構文のご提案
新しい並列for構文のご提案新しい並列for構文のご提案
新しい並列for構文のご提案
 
【関東GPGPU勉強会#4】GTX 1080でComputer Vision アルゴリズムを色々動かしてみる
【関東GPGPU勉強会#4】GTX 1080でComputer Visionアルゴリズムを色々動かしてみる【関東GPGPU勉強会#4】GTX 1080でComputer Visionアルゴリズムを色々動かしてみる
【関東GPGPU勉強会#4】GTX 1080でComputer Vision アルゴリズムを色々動かしてみる
 
V6 unix vol.2 in okinawa
V6 unix vol.2 in okinawaV6 unix vol.2 in okinawa
V6 unix vol.2 in okinawa
 
OPcache の最適化器の今
OPcache の最適化器の今OPcache の最適化器の今
OPcache の最適化器の今
 
GPGPU deいろんな問題解いてみた
GPGPU deいろんな問題解いてみたGPGPU deいろんな問題解いてみた
GPGPU deいろんな問題解いてみた
 
C/C++プログラマのための開発ツール
C/C++プログラマのための開発ツールC/C++プログラマのための開発ツール
C/C++プログラマのための開発ツール
 
SQLチューニング入門 入門編
SQLチューニング入門 入門編SQLチューニング入門 入門編
SQLチューニング入門 入門編
 
20090107 Postgre Sqlチューニング(Sql編)
20090107 Postgre Sqlチューニング(Sql編)20090107 Postgre Sqlチューニング(Sql編)
20090107 Postgre Sqlチューニング(Sql編)
 
Pgunconf 20121212-postgeres fdw
Pgunconf 20121212-postgeres fdwPgunconf 20121212-postgeres fdw
Pgunconf 20121212-postgeres fdw
 
整数列圧縮
整数列圧縮整数列圧縮
整数列圧縮
 
C++による数値解析の並列化手法
C++による数値解析の並列化手法C++による数値解析の並列化手法
C++による数値解析の並列化手法
 
あるコンテキストスイッチの話
あるコンテキストスイッチの話あるコンテキストスイッチの話
あるコンテキストスイッチの話
 
V6 unix in okinawa
V6 unix in okinawaV6 unix in okinawa
V6 unix in okinawa
 
【関東GPGPU勉強会#3】OpenCVの新機能 UMatを先取りしよう
【関東GPGPU勉強会#3】OpenCVの新機能 UMatを先取りしよう【関東GPGPU勉強会#3】OpenCVの新機能 UMatを先取りしよう
【関東GPGPU勉強会#3】OpenCVの新機能 UMatを先取りしよう
 

Similaire à Das 2015

アドテク×Scala×パフォーマンスチューニング
アドテク×Scala×パフォーマンスチューニングアドテク×Scala×パフォーマンスチューニング
アドテク×Scala×パフォーマンスチューニングYosuke Mizutani
 
Windows PowerShell 2.0 の基礎知識
Windows PowerShell 2.0 の基礎知識Windows PowerShell 2.0 の基礎知識
Windows PowerShell 2.0 の基礎知識shigeya
 
jjugccc2018 app review postmortem
jjugccc2018 app review postmortemjjugccc2018 app review postmortem
jjugccc2018 app review postmortemtamtam180
 
Programming camp 2008, Codereading
Programming camp 2008, CodereadingProgramming camp 2008, Codereading
Programming camp 2008, CodereadingHiro Yoshioka
 
Djangoフレームワークの紹介
Djangoフレームワークの紹介Djangoフレームワークの紹介
Djangoフレームワークの紹介Shinya Okano
 
エンタープライズ分野での実践AngularJS
エンタープライズ分野での実践AngularJSエンタープライズ分野での実践AngularJS
エンタープライズ分野での実践AngularJSAyumi Goto
 
企業におけるSpring@日本springユーザー会20090624
企業におけるSpring@日本springユーザー会20090624企業におけるSpring@日本springユーザー会20090624
企業におけるSpring@日本springユーザー会20090624Yusuke Suzuki
 
Introduction to Chainer (LL Ring Recursive)
Introduction to Chainer (LL Ring Recursive)Introduction to Chainer (LL Ring Recursive)
Introduction to Chainer (LL Ring Recursive)Kenta Oono
 
はじめてのCodeIgniter
はじめてのCodeIgniterはじめてのCodeIgniter
はじめてのCodeIgniterYuya Matsushima
 
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例Yoshifumi Kawai
 
Deep Learning Lab - Microsoft Machine Learning meetup 2018/06/27 - 推論編
Deep Learning Lab - Microsoft Machine Learning meetup 2018/06/27 - 推論編Deep Learning Lab - Microsoft Machine Learning meetup 2018/06/27 - 推論編
Deep Learning Lab - Microsoft Machine Learning meetup 2018/06/27 - 推論編Daiyu Hatakeyama
 
大規模なギョームシステムにHaxeを採用してみた話
大規模なギョームシステムにHaxeを採用してみた話大規模なギョームシステムにHaxeを採用してみた話
大規模なギョームシステムにHaxeを採用してみた話terurou
 
Hadoop基盤上のETL構築実践例 ~多様なデータをどう扱う?~
Hadoop基盤上のETL構築実践例 ~多様なデータをどう扱う?~Hadoop基盤上のETL構築実践例 ~多様なデータをどう扱う?~
Hadoop基盤上のETL構築実践例 ~多様なデータをどう扱う?~Sotaro Kimura
 
[db tech showcase Tokyo 2014] B26: PostgreSQLを拡張してみよう by SRA OSS, Inc. 日本支社 高塚遥
[db tech showcase Tokyo 2014] B26: PostgreSQLを拡張してみよう  by SRA OSS, Inc. 日本支社 高塚遥[db tech showcase Tokyo 2014] B26: PostgreSQLを拡張してみよう  by SRA OSS, Inc. 日本支社 高塚遥
[db tech showcase Tokyo 2014] B26: PostgreSQLを拡張してみよう by SRA OSS, Inc. 日本支社 高塚遥Insight Technology, Inc.
 
これからのコンピューティングの変化とJava-JJUG CCC 2015 Fall
これからのコンピューティングの変化とJava-JJUG CCC 2015 Fallこれからのコンピューティングの変化とJava-JJUG CCC 2015 Fall
これからのコンピューティングの変化とJava-JJUG CCC 2015 Fallなおき きしだ
 
TypeScript ファーストステップ (Rev.2) ~ Any browser. Any host. Any OS. Open Source. ~
TypeScript ファーストステップ (Rev.2) ~ Any browser. Any host. Any OS. Open Source. ~TypeScript ファーストステップ (Rev.2) ~ Any browser. Any host. Any OS. Open Source. ~
TypeScript ファーストステップ (Rev.2) ~ Any browser. Any host. Any OS. Open Source. ~Akira Inoue
 

Similaire à Das 2015 (20)

実践 NestJS
実践 NestJS実践 NestJS
実践 NestJS
 
アドテク×Scala×パフォーマンスチューニング
アドテク×Scala×パフォーマンスチューニングアドテク×Scala×パフォーマンスチューニング
アドテク×Scala×パフォーマンスチューニング
 
Java EE8 Report
Java EE8 ReportJava EE8 Report
Java EE8 Report
 
Windows PowerShell 2.0 の基礎知識
Windows PowerShell 2.0 の基礎知識Windows PowerShell 2.0 の基礎知識
Windows PowerShell 2.0 の基礎知識
 
jjugccc2018 app review postmortem
jjugccc2018 app review postmortemjjugccc2018 app review postmortem
jjugccc2018 app review postmortem
 
Programming camp 2008, Codereading
Programming camp 2008, CodereadingProgramming camp 2008, Codereading
Programming camp 2008, Codereading
 
Djangoフレームワークの紹介
Djangoフレームワークの紹介Djangoフレームワークの紹介
Djangoフレームワークの紹介
 
エンタープライズ分野での実践AngularJS
エンタープライズ分野での実践AngularJSエンタープライズ分野での実践AngularJS
エンタープライズ分野での実践AngularJS
 
Node.jsでブラウザメッセンジャー
Node.jsでブラウザメッセンジャーNode.jsでブラウザメッセンジャー
Node.jsでブラウザメッセンジャー
 
企業におけるSpring@日本springユーザー会20090624
企業におけるSpring@日本springユーザー会20090624企業におけるSpring@日本springユーザー会20090624
企業におけるSpring@日本springユーザー会20090624
 
Introduction to Chainer (LL Ring Recursive)
Introduction to Chainer (LL Ring Recursive)Introduction to Chainer (LL Ring Recursive)
Introduction to Chainer (LL Ring Recursive)
 
はじめてのCodeIgniter
はじめてのCodeIgniterはじめてのCodeIgniter
はじめてのCodeIgniter
 
Spock's world
Spock's worldSpock's world
Spock's world
 
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例
 
Deep Learning Lab - Microsoft Machine Learning meetup 2018/06/27 - 推論編
Deep Learning Lab - Microsoft Machine Learning meetup 2018/06/27 - 推論編Deep Learning Lab - Microsoft Machine Learning meetup 2018/06/27 - 推論編
Deep Learning Lab - Microsoft Machine Learning meetup 2018/06/27 - 推論編
 
大規模なギョームシステムにHaxeを採用してみた話
大規模なギョームシステムにHaxeを採用してみた話大規模なギョームシステムにHaxeを採用してみた話
大規模なギョームシステムにHaxeを採用してみた話
 
Hadoop基盤上のETL構築実践例 ~多様なデータをどう扱う?~
Hadoop基盤上のETL構築実践例 ~多様なデータをどう扱う?~Hadoop基盤上のETL構築実践例 ~多様なデータをどう扱う?~
Hadoop基盤上のETL構築実践例 ~多様なデータをどう扱う?~
 
[db tech showcase Tokyo 2014] B26: PostgreSQLを拡張してみよう by SRA OSS, Inc. 日本支社 高塚遥
[db tech showcase Tokyo 2014] B26: PostgreSQLを拡張してみよう  by SRA OSS, Inc. 日本支社 高塚遥[db tech showcase Tokyo 2014] B26: PostgreSQLを拡張してみよう  by SRA OSS, Inc. 日本支社 高塚遥
[db tech showcase Tokyo 2014] B26: PostgreSQLを拡張してみよう by SRA OSS, Inc. 日本支社 高塚遥
 
これからのコンピューティングの変化とJava-JJUG CCC 2015 Fall
これからのコンピューティングの変化とJava-JJUG CCC 2015 Fallこれからのコンピューティングの変化とJava-JJUG CCC 2015 Fall
これからのコンピューティングの変化とJava-JJUG CCC 2015 Fall
 
TypeScript ファーストステップ (Rev.2) ~ Any browser. Any host. Any OS. Open Source. ~
TypeScript ファーストステップ (Rev.2) ~ Any browser. Any host. Any OS. Open Source. ~TypeScript ファーストステップ (Rev.2) ~ Any browser. Any host. Any OS. Open Source. ~
TypeScript ファーストステップ (Rev.2) ~ Any browser. Any host. Any OS. Open Source. ~
 

Plus de Takefumi MIYOSHI

ACRi_webinar_20220118_miyo
ACRi_webinar_20220118_miyoACRi_webinar_20220118_miyo
ACRi_webinar_20220118_miyoTakefumi MIYOSHI
 
ACRiルーム1年間の活動と 新たな取り組み
ACRiルーム1年間の活動と 新たな取り組みACRiルーム1年間の活動と 新たな取り組み
ACRiルーム1年間の活動と 新たな取り組みTakefumi MIYOSHI
 
RISC-V introduction for SIG SDR in CQ 2019.07.29
RISC-V introduction for SIG SDR in CQ 2019.07.29RISC-V introduction for SIG SDR in CQ 2019.07.29
RISC-V introduction for SIG SDR in CQ 2019.07.29Takefumi MIYOSHI
 
Misc for edge_devices_with_fpga
Misc for edge_devices_with_fpgaMisc for edge_devices_with_fpga
Misc for edge_devices_with_fpgaTakefumi MIYOSHI
 
Synthesijer - HLS frineds 20190511
Synthesijer - HLS frineds 20190511Synthesijer - HLS frineds 20190511
Synthesijer - HLS frineds 20190511Takefumi MIYOSHI
 
Abstracts of FPGA2017 papers (Temporary Version)
Abstracts of FPGA2017 papers (Temporary Version)Abstracts of FPGA2017 papers (Temporary Version)
Abstracts of FPGA2017 papers (Temporary Version)Takefumi MIYOSHI
 
Synthesijer and Synthesijer.Scala in HLS-friends 201512
Synthesijer and Synthesijer.Scala in HLS-friends 201512Synthesijer and Synthesijer.Scala in HLS-friends 201512
Synthesijer and Synthesijer.Scala in HLS-friends 201512Takefumi MIYOSHI
 
Synthesijer zynq qs_20150316
Synthesijer zynq qs_20150316Synthesijer zynq qs_20150316
Synthesijer zynq qs_20150316Takefumi MIYOSHI
 
Synthesijer.Scala (PROSYM 2015)
Synthesijer.Scala (PROSYM 2015)Synthesijer.Scala (PROSYM 2015)
Synthesijer.Scala (PROSYM 2015)Takefumi MIYOSHI
 
FPGAのトレンドをまとめてみた
FPGAのトレンドをまとめてみたFPGAのトレンドをまとめてみた
FPGAのトレンドをまとめてみたTakefumi MIYOSHI
 

Plus de Takefumi MIYOSHI (20)

ACRi_webinar_20220118_miyo
ACRi_webinar_20220118_miyoACRi_webinar_20220118_miyo
ACRi_webinar_20220118_miyo
 
DAS_202109
DAS_202109DAS_202109
DAS_202109
 
ACRiルーム1年間の活動と 新たな取り組み
ACRiルーム1年間の活動と 新たな取り組みACRiルーム1年間の活動と 新たな取り組み
ACRiルーム1年間の活動と 新たな取り組み
 
RISC-V introduction for SIG SDR in CQ 2019.07.29
RISC-V introduction for SIG SDR in CQ 2019.07.29RISC-V introduction for SIG SDR in CQ 2019.07.29
RISC-V introduction for SIG SDR in CQ 2019.07.29
 
Misc for edge_devices_with_fpga
Misc for edge_devices_with_fpgaMisc for edge_devices_with_fpga
Misc for edge_devices_with_fpga
 
Cq off 20190718
Cq off 20190718Cq off 20190718
Cq off 20190718
 
Synthesijer - HLS frineds 20190511
Synthesijer - HLS frineds 20190511Synthesijer - HLS frineds 20190511
Synthesijer - HLS frineds 20190511
 
Reconf 201901
Reconf 201901Reconf 201901
Reconf 201901
 
Hls friends 201803.key
Hls friends 201803.keyHls friends 201803.key
Hls friends 201803.key
 
Abstracts of FPGA2017 papers (Temporary Version)
Abstracts of FPGA2017 papers (Temporary Version)Abstracts of FPGA2017 papers (Temporary Version)
Abstracts of FPGA2017 papers (Temporary Version)
 
Synthesijer and Synthesijer.Scala in HLS-friends 201512
Synthesijer and Synthesijer.Scala in HLS-friends 201512Synthesijer and Synthesijer.Scala in HLS-friends 201512
Synthesijer and Synthesijer.Scala in HLS-friends 201512
 
Microblaze loader
Microblaze loaderMicroblaze loader
Microblaze loader
 
Synthesijer zynq qs_20150316
Synthesijer zynq qs_20150316Synthesijer zynq qs_20150316
Synthesijer zynq qs_20150316
 
Synthesijer hls 20150116
Synthesijer hls 20150116Synthesijer hls 20150116
Synthesijer hls 20150116
 
Synthesijer.Scala (PROSYM 2015)
Synthesijer.Scala (PROSYM 2015)Synthesijer.Scala (PROSYM 2015)
Synthesijer.Scala (PROSYM 2015)
 
ICD/CPSY 201412
ICD/CPSY 201412ICD/CPSY 201412
ICD/CPSY 201412
 
Reconf_201409
Reconf_201409Reconf_201409
Reconf_201409
 
FPGAのトレンドをまとめてみた
FPGAのトレンドをまとめてみたFPGAのトレンドをまとめてみた
FPGAのトレンドをまとめてみた
 
Vyatta 201310
Vyatta 201310Vyatta 201310
Vyatta 201310
 
Fpgax 20130830
Fpgax 20130830Fpgax 20130830
Fpgax 20130830
 

Das 2015