Polyphony の行く末(2018/3/3)
- 2. 自己紹介
著者です
最初に購入したコンピュータはHP-41C(関数電卓)。生涯一プログラマを目指す。
扱ってきたCPUは Z80, 6502, 6809, 680XX, 80x86, V30, i860, Sparc, MIPS, PicoJava,
M16C, M32C, H8, ARM, PowerPC, SH4, NiosII, MicroBlaze, V850 など多数。
扱ってきた言語は BASIC, Common Lisp, FORTH, Pascal, FORTRAN, C, C++, Smalltalk,
Objective-C, HyperTalk, Perl, Java, JavaScript, SQL, Scheme, VHDL, Verilog, C#, Lua,
Ocaml, Tcl, Python など多数。手がけたプロジェクトも Unix移植、RTOS移植、スパコ
ンのネットワーク設計、Windows ドライバ開発、 FPGA を含むハードウェア、ボード
設計、GPGPUによる画像処理、コンパイラ、ウェブ系、IoTと広範囲に及ぶ。CQ 出版
での記事の執筆は 2000 年からと足掛け 19 年となった。RTOS 開発現場の経験を
活かし近年ではコンサルタント業もこなす。
2
- 3. 技術的なバックボーン
• IP Core
– HD-SDIの画像処理システム
– ステレオ
– スケーラ
• Unix
– SystemV
– Sun (64bit)
• stream ドライバ
– FreeBSD
– X-window
– Linux プラットフォーム開発
• Yocto
• Xen for ARM
TLMu
• Windows
– NT 以降のデバイスドライバ
– Com
– C#/WPF
• iTRON
– T-Kernel
– Toppers
– SafeG(Trust Zone)
• SDSoC
– プラットフォーム開発
– アルゴリズム検証
• コンパイラ
– Lisp (Scheme) によるコンパイラ
– Python → Verilog (Polyphony)
• ASIC/ボード設計
– Make LSI
– Kiss4(Zynq 小型ボード)
3
- 4. 関連記事
• インタフェース2018年1 月号
– 第2章 Pythonからも使える 200ドルFPGA制御ボード入門
– 第3章 Arduino/Pmodでつなげば試せる
– リアルタイムPython③...I/O制御あれこれ
– 第4章 ソフト屋さんでも小規模FPGAの設計でも使えそう
– PythonでFPGAを作る
Python
Lattice
4
- 8. 高位合成友の会
• FPGA ベンダ
– Vivado HLS/SDSoC
– Intel HLS コンパイラ
• 高位合成の友の会
– Polyphony
– Veriloggen
– Neon Light + IROHA
– Synthesijer
– Sigboost
– Synverll
Python の高位合成
Python の高位合成
独自言語の高位合成
Javaの高位合成
プロの音楽家用の高位合成
LLVMを使った高位合成
8
- 11. コンパイラを作ろう!!
• Python の AST は比較的簡単なうえに本格的
• XML とか JSON とかカンマ区切り(CSV) とか
簡単なところからスタートでもよさそう
Scheme とか ML とか OCaml とかは横に置いておこう
チャレンジするプログラマの成功譚、失敗談
ゆるぼ
11
- 16. Polyphonyの紹介:
Q: 言語として Python のすべてをカバーしていますか?
A: いいえ、Python のサブセットになります。
Python
Polyphony
(is a subset of Python)
Function
Class
List(Fixed size)
Tuple
For/While
If/Else
...
String
Dictionary
Set
Builtin funcs
...
Python のすべてをカバーしているわけではない
16
- 17. Python の関数を Verilog にする
from polyphony import testbench
def fib(n):
if n <= 0: return 0
if n == 1: return 1
r0 = 0
r1 = 1
for i in range(n-1):
prev_r1 = r1
r1 = r0 + r1
r0 = prev_r1
return r1
@testbench
def test():
expect = [0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610]
for i in range(len(expect)):
result = fib(i)
assert expect[i] == result
print(i, "=>", result)
test()
フィボナッチ数列
module fib
(
input wire clk,
input wire rst,
input wire fib_ready,
input wire fib_accept,
output reg fib_valid,
input wire signed [31:0] fib_in_n,
output reg signed [31:0] fib_out_0
);
中略
//signals:
wire cond565;
wire cond566;
中略
always @(posedge clk) begin
if (rst) begin
fib_out_0 <= 0;
i2 <= 0;
n <= 0;
r02 <= 0;
r12 <= 0;
fib_state <= fib_b1_INIT;
end else begin //if (rst)
中略
endcase
end
end
endmodule
17
Python の関数
テスト
Verilog HDL
- 18. どの辺が HDL 記述と違うか?
Polyphony (Python) Verilog-HDL
def a_b():
a = 3
b = 4
c = a + b
print(c)
出力結果は 7
a = 3;
b = 4;
c <= a + b;
$display("%d", c);
出力結果は x(不定)
18
- 19. どの辺が MyHDL 記述と違うか?
Polyphony (Python) MyHDL
def a_b():
a = 3
b = 4
c = a + b
print(c)
出力結果は 7
def a_b(clock, start, done, reset):
a = Signal(intbv(0)[7:])
b = Signal(intbv(0)[7:])
c = Signal(intbv(0)[7:])
@always_seq(clock.posedge, reset=reset)
def logic():
if reset:
a.next = 3
b.next = 4
else:
while True:
if start:
c.next = a + b
done.next = True
return logic
出力結果は7?
19
nextという
特別な
キーワード
- 24. 参考資料
• Polyphony ~Pythonベースの高位合成コンパイラ~ (2015 高位合成友の
会)
https://www.slideshare.net/ktok07b6/3-polyphony
• Github
https://github.com/ktok07b6/polyphony
• プログラミング言語PythonではじめるFPGA開発入門(FPGA マガジン No.12)
http://www.kumikomi.net/fpga/contents/su012.php
• A Python-Based High-Level Synthesis Compiler (2017 OpenSuco フランクフルトでの発表)
http://www.opensuco.community/wp-content/uploads/2017/06/ISC2017-
Kataoka.pdf
• Polyphony ではじめる FPGA(PyCon 2017 で発表)
https://www.slideshare.net/ryos36/polyphony-python-fpga
• Python で FPGA プログラミング (PYNQ 祭り 2017)
ikwzm の発表(ありがとうございます)
https://www.slideshare.net/ssuser941451/pynq-72804195
24
- 30. コード例
def print_hex(self, addr:bit16, data:bit8):
write_hex16(self.debug_print_q, addr >> 8)
write_hex16(self.debug_print_q, addr & 0xFF)
self.debug_print_q(0x20)
write_hex16(self.debug_print_q, data)
write_ln(self.debug_print_q)
文字表示との相性は悪い
30
- 33. コード例
self.write_reg(base_addr | 0x08, 0x028c0166)
self.write_reg(base_addr | 0x10, 0x02000000)
self.write_reg(base_addr | 0x14, 0x02400000)
self.write_reg(base_addr | 0x18, 0x000032A0)
self.write_reg(base_addr | 0x08, 0x81220fff)
33
- 35. コード例
from imx219_init_data import
INIT_DATA_MODE1, INIT_DATA_MODE7
def init_code(self):
init_data = INIT_DATA_MODE7
for i in range(0, len(init_data), 2):
addr:bit16 = init_data[i + 0]
data:bit8 = init_data[i + 1]
self.write_reg(addr, data)
self.print_hex(addr, data)
INIT_DATA_MODE7 = [
0x0100, 0x00,
0x30eb, 0x05,
0x30eb, 0x0c,
0x300a, 0xff,
0x300b, 0xff,
0x30eb, 0x05,
….
後略
35
- 39. def receive_block0(block):
if block == 0:
return (True, 0)
elif block == 1:
return (True, EOT)
elif block == 2:
return (False, 0)
else:
return (False, EOT)
tuple(2/2)
39
tuple
構造体みたいなもの
Editor's Notes
- 今日は Polyphony の行方というお題で30分話します。最初に、自分の技術的なバックボーンを話します。最初に購入したコンピュータは HP-41C という関数電卓、、、、で PC-9801 の初代を、、、という話をすると2時間くらいかかるのでここははしょります。恐らく、コンピュータと名のつくかなり広い分野にわたって関わっています。
- 特筆すべきことはありませんが、いわゆる組み込みシステムから、Windows から、Unix、までいろいろ経験しています。最近では ASIC を作ることにも参加させていただきました。
- 一番最近の執筆は 2018 年の1月号の Ptyhon で FPGA を制御しようという記事です。今日の内容とかぶる点も多いので、興味のある方は、ぜひ、ご購入ください。この号は、中原先生がギネスについても書かれている号でもあります。。
- では今日のアジェンダです。先頭バッターなので高位合成についても少しお話します。その後、本題である Python による 高位合成のコンパイラである
Polyphony の紹介と応用例について最後に Polyphony の新機能と今後について
お話しします。アプリよりの話になっているのでコンパイラという意味ではちょっと物足りないかもしれません。コンパイラ内部の技術的な資料はまた別途資料をあげますので参照してもらえればと思います。
- まずは高位合成って何という話からです。
- 簡単にいうと、プログラミング言語をコンパイルして FPGA などで動かす技術です。
- 高位合成友の会も第5回となりました。友の会は、高位合成に関連する話題としてコンパイラなどの事を情報交換しましょうという
趣旨でゆる~~く存在している会です。今回は新しい取り組みの話もありそうなので、いろんな人が、特にソフトウェアよりの人が高位合成はよくわからないけどこんなのつくったとか、FPGA でこんなの出来たとか、そういった話題がこれもゆる~~~く、集まればと期待しています。
- で、そのコンパイラって何でしょうという話になりますが、
プログラミング言語を解析して構文木、AST と呼ばれたりしますが
それを中間言語になおして、最後は、実行可能なコードにするというのが
大きな流れかと思います。
このとき、AST や IR という聞きなれないかもしれない略語をつかっちゃうので
敷居が高くなってしまうのですが、正直、この辺はもっと、ゆる~~~い感じでとらえてもらえればと思います。
- データを、おれおれ変換で C やら Python やら Java Script に落とせれば、まぁ、広い意味でコンパイラだと言い切りましょう。
実際、最近の AI 界隈では、この手のをコンパイラだと言い切ってしまっているように見受けられます。まぁ、それで、とりあえずは、いいんだと思います。
- ということで、みなさんも機会があればコンパイラを作ってみてください。
コンパイラと言い切るのに抵抗があるなら
データコンバータでもいいと思います。
- 高位合成ではないのですが、
特に組み込みシステムでは是非コンパイラを作ってみてください。
- それでは本題の Python で高位合成をするコンパイラの Polyphony について話します。
- Polyphony がどんなツールなのかをかいつまんでまとめると
Python で書いたコードを HDL に変換するコンパイラ
動くものを早く作る
性能には“現在のところ”重きを置いていない
というツールになります。
Python でというのがポイントになります。
- 使い方としては
「Python によるコードの記述」をし
ここが重要なのですが「Python によるコードの実行」によりデバッグをしておきますそして、「Polyphony によりコンパイル」をします。
そうすると、Verilog という FPGA などで動く言語にコンパイルされるので
それをまずは Windows などでソフト的にシミュレーションします。
うまく動いたら、実際の FPGA のボードで「実行」します。
- そして、
Python のコードをコンパイルすると言ってもすべてのコードをコンパイルできるわけではなく、
とうぜん、print などの文字列などはサポートされておらず、Python のサブセットになっています。
- コンパイルというものがどんな感じなるのかをイメージしてもらうために例をあげます。
ここでは Python の関数が verilog のモジュールにコンパイルされる例です。
- Python と Verilog-HDL を比較するというのも変なのですが、なぜ高位合成が必要かというのを説明するためにちょっと比較します。
例えば a, b という変数に 3, 4 をいれて足して c という変数に代入するを考えます。左が python で書かれたもので右が Verilog で書かれたものです。
大ざっぱに書いているので、そうじゃないだろというコメントもあるかと思いますが、ここはその結果を単純に考えます。
Python で普通にソフトで実行すれば、左は 3+4 で 7になりますが、
ハードウェアの世界では3+4 は時間的な要素が入ってくるのでかならずしも、その瞬間には 7 になりません。
もちろん最終的には計算なので 7 になるわけですが、時間的要素が入ってくるので
ある一瞬ではハードウェアでは出力結果が不定ということがあり得るのです。
- Python のアプリ?で MyHDL という有名なものがあるのですが、
これも Python でハードウェアの記述が出来ます。これをちょっと見てもらえると、わかるのですが、next という特別なキーワードを使って
時間的な記述をしています。
実はこの PPT 作成のために少し MyHDL をやってみたのですが、
難しすぎてできませんでした。なので、このプログラムがただしいかどうかはちょっと怪しいところがあります。印象としては SystemC ライクといえばわかる人がいるかもしれません。
これなら、私の場合 VHDL で書いた方がわかりやすく書けると思いました。
- その点、Polyphony であれば、Python がわかればハードウェアの世界に入っていけるので
敷居は非常に低いと思います。
時間的な考慮はプログラマはしなくてもいいようになっています。
コンパイラが自動的にスケジュールリングしてくれます。
- では、実際に Python で高位合成をしてどんなメリットがあるのですか?というところですが、
これは実際に後で使い方を見ていきたいと思います。
- 高位合成を使いやすさと性能で考えると、Polyphony は
ここ数年の間、改善され、生産性の高い、立派に高位合成と言ってよいところまできました。そして、現在は目標も性能を上げる方にシフトしています。
- 今後はライブラリなどを増やして、並列計算をとりわけパイプライン処理を考える際の便利なツールになるように開発しています。
- それでは応用例を見ていきます。
- インタフェースの 2018 年1月号にも書いたものにプラスアルファして
AXI lite や i2c ができるようになりました。
- まずは SPI ですが、雑誌に書いたように秋月の3軸加速度センサーを直接制御できます。
この図では Arty Z7 になっていますが、Lattice でも Cyclone V でも確認しています。
- で、コード例ですが、これは高位合成ならではで関数表現になって
分かりやすくなっていると思います。
もちろん Verilog や VHDL でも工夫すれば、関数表現は出来るのですが���
どうやっても開発時にステートマシーンを考えなくてはならなくなると思います。
- これは UART の例です。UART は一部、RTL で時間の制御をしています。
ボーレートとかの部分ですね。
これも Polyphony で書いてもよかったのですが、この手の Verilog はいろんなところに転がっているので
そのままつかっちゃいます。
- これはその応用例で print_hex という形である 16bit と 8 bit のデータを
UART に出しています。
現時点で文字列を直接扱えるわけではないので
非常にわかりづらいコードではあります。
でも、デバッグ時に UART に情報が出てくるのは心強いことです。
- これはラズパイカメラをデバッグしていた時の例ですがこんな感じで表示してくれるので、数字だけでも、デバッグに大変役に立ちます。
- これは AXI Lite の master の例です。
- コード例は、組み込みでよくみるような、レジスタのアドレスと書き込みデータの羅列になっています。AXI lite の Master の記述が出来るので、極端な話、CPU なしで動作可能なシステムが作れてしまいます。ツールにもよるのですが、ハードとソフトの IDE を行ったり来たりする必要がなくなります。
- これが I2C でラズパイカメラをアクセスしたときの回路とその様子です。実際には iobuf が必要だったのでそこは verilog で外付けです。
この verilog の記述は FPGA の部屋を参考しました。
いつも参照させていただいています。どうもありがとうございます。
- コードの例ですが、Python で初期化の関数を書いて、あとは配列、正確には Python ではリストですが、それを読み込んで順次初期化します。
ここでは mode7 の初期化していますが、これは、配列を差し替えれば、別のモードの初期化が出来ます。
ちょっとだけ付け加えると、現時点では配列は HDL に埋め込みなので、毎回、合成をする必要があります。将来的には合成無しでブロックラムのデータ入れ替えだけで出来るようにしたいとは思っています。
- さて、Polyphony の利点について再度、2つの視点から見てみます。
今回は応用例を通して、1の利便性についての述べてきました。
今後は FPGA の性能を出し切るという方向になると思います。
つまり、今後は性能への挑戦をしていきます。
それを踏まえたうえで、幾つか機能を紹介しつたいとおもいます。
- Tuple という構造体みたいなものを
- こんな感じで2つの値を返すことが出来ます。ハードウェアの記述に有効そうな予感のする文法です。
- 以前にも報告しましたが、import 文に部分対応しました。ディレクトリはまだ読めてませんが、これで既存の再利用が出来るようになりました。
- Unroll も出来るようになりました。これは性能向上に一役買うと思います。
- Pipeline もサポートしました。Unroll しながらの複合的な pipeline も可能です。
- パタヘネを実現するとなると重要なのがキャッシュとパイプラインになります。なかなか難しいのですが、チャレンジしていきたいと思っています。
- 今後性能向上を目指していくうえで、II=2 以上のパイプラインであったり、同時性の記述方法であったり、Verilog との連携をするようにしていきます。
Verilog の 簡単Parser はすでにできています。
- 最後に高位合成の共通課題をあげておきます。
一つはインタフェースです。Verilog で記述したプロトコルはクロック単位の動作が記述できます。それに対応しようと思うと同時性の記述であったり、クロック単位の動作の保証が必要です。
しかし、それは直感的にわかりやすい記述と相反します。
またビットの柔軟性を考えたとき、ビットというハードウェア的な考えと int などの抽象的な型は相反します。
Python3 では特に数字が 32bit や 64bit であるという区切りではなく抽象度が上がっているため
それとの整合性を保つのが難しい問題です。
- 最後にちょっとした妄想を書いておきます。コンストラクタに class を引き渡せると、汎用性がぐっと上がって楽しくなりそうです。内部的には Lambda は達成しているので可能だと思っています。
- AXI Stream への対応はしたいと思っています。これを達成して、 FPGA の帯域を使い切るといったことが容易にできるようにと思っています。
- それでは本日の発表を終わりにします。
Polyphony を今後ともよろしくお願いします。