Polyphonyって何だろう(2)使用例:フィボナッチ数列
Python で書いた関数を Verilog HDL に変換する高位合成コンパイラである Polyphony を使ってみたいと思います。実際に動かした方が分かりやすいと思うので、早速フィボナッチ数列を出力する回路を合成したいと思います。計算が必要な回路合成には高位合成は本当に便利だと思います。
フィボナッチ数列とは
直前の2つの数値を足したものを新しい数値とする数列です。すなわち、
0,1,2,3,5,8,13,21,...
というような数列となります。足し算していくだけのいたって簡単なものです。
python コードと簡単な説明
polyphony の便利なところは、そのまま python として実行できることです。また、クラスとして記述する事で、入出力ポートを記述可能で、ビット幅も指定可能です。テストベンチもいたって簡単に記述できます。
早速コードを fib_class_n.py として作成します。
polyphony はどうやら日本語utf-8には対応していないようなので、コメントを入れる時には日本語を使わない方がよさそうです。
モジュールとしては何回ループを回すかの n を設定して、start 信号を入れると fibb からフィボナッチ数列が出力され、ループが終わると次の数値を fiba から出力して finish 信号で終了を知らせるという簡単なものです。
import polyphony from polyphony import module, pure, is_worker_running, rule from polyphony import testbench from polyphony.io import Port from polyphony.typing import bit, int8, int16, int32 from polyphony.timing import wait_value, wait_rising, clksleep, clkfence # %% @module class fib_class_n: def __init__(self): self.start = Port(bool, 'in') self.n = Port(int8, 'in') self.fiba = Port(int16, 'out') self.fibb = Port(int16, 'out') self.finish = Port(bool, 'out') self.append_worker(self.main) def main(self): while is_worker_running(): if(self.start.rd() == True): a = self.fib(self.n.rd()) self.fiba.wr(a) self.finish.wr(True) clksleep(1) self.finish.wr(False) def fib(self, n): if n <= 0: return 0 if n == 1: return 1 r0 = 0 r1 = 1 for i in range(n): r0, r1 = r1, r0+r1 self.fibb.wr(r0) print(r0, r1) return r1 # %% @testbench def fib_class_n_test(m): m.n.wr(4) m.start.wr(True) clksleep(1) m.start.wr(False) wait_value(True, m.finish) clksleep(10) m.n.wr(8) m.start.wr(True) clksleep(1) m.start.wr(False) wait_value(True, m.finish) clksleep(5) print('finished') # %% m = fib_class_n() fib_class_n_test(m)
実行
そのまま python として実行すると,バグが無ければ次のような出力が表示されるはずです。
1 1 1 2 2 3 3 5 1 1 1 2 2 3 3 5 5 8 8 13 13 21 21 34 finished
次に、前回作った compile.py を使って、polyphony でコンパイルした Verilog ファイルをシミュレーションして gtkwave で表示するまでを行います。非常に簡単で compile.py の
target = 'fib_class_n' #file name = module name
の所に今回のファイル fib_class_n.py の fib_class_n を書いて実行するだけです。
うまく動くと、下記のファイルが作成され gtkwave で好きな信号の波形が見れるようになります。
fib_class_n_m.v:フィボナッチ数列の出力モジュール(Verilog HDL)
fib_class_n_test.v:テストモジュール(Verilog HDL)
polyphony_out.v:テストを実行するために読み込むモジュール
(`include "./fib_class_n_m.v" と書かれている)
fib_class_n.out:iverilog で作られた vvp の入力となるシミュレーションファイル
fib_class_n_test.vcd:vvp シミュレーション結果(gtkwave の入力となる)
簡単な計算でも Verilog HDL で直接記述しようとするとなかなか難しいものだと思います。それがこんなに簡単に記述できるというのは、polyphony 素晴らしいです。
実行環境:Win10 python3.7.1 polyphony0.3.3 iverilog0.9.7