Polyphonyって何だろう(3)使用例:フィボナッチ LFSR
Python で書いた関数を Verilog HDL に変換する高位合成コンパイラである Polyphony を使ってみたいと思います。前回はクラス表記で port を指定しましたが、今回はもっと簡単に関数表記で port はお任せでフィボナッチ LFSRのアルゴリズムを Verilog に変換したいと思います。
フィボナッチ LFSR
フィボナッチ LFSRに関しては下記を参照してください。
線形帰還シフトレジスタ - Wikipedia
今回は9bitのシフトレジスターを使用して 初期値 000000001 とし、タップ位置(1,5)で巡回符号を生成します。
Python コード ( flfsr.py ) と簡単な説明
from polyphony import testbench from polyphony.typing import bit9 from polyphony.timing import clksleep def flfsr(seed:bit9)->bit9: blen = 9 mask = 0b111111111 cha = 0b000010001 #tap position [1,5] seed = seed & mask bits = seed & 1 print(bits, end=':') for i in range(blen-1): if ((cha>>(i+1)) & 1) == 1: bits = ((seed>>(i+1)) ^ bits) & 1 ret = ((seed>>1) | (bits<<(blen-1))) & mask return ret @testbench def flfsr_test(): y:bit9 = 1 for i in range(10): rv:bit9 = flfsr(y) #print(format(rv, '09b')) #format is not supported by polyphony print(rv) y = rv clksleep(10) flfsr_test()
print 文の中で format を使うと polyphony でコンパイルする時にエラーとなるので、使わないかもしくはコンパイル時にはコメントアウトします。
前回ではクラスで書いてポートを自分で指定しましたが、今回は関数表記で、ポートは polyphony お任せとします。レジスタのビット幅を指定するためには seed:bit9 の様にあらかじめ polyphony.typing から使いたい bit? を import して表記します。戻り値(outport) のビット幅を指定するには ->bit? の様に記述します。bit? にはどんなものが使えるかは、typing.py に記述されています。(typing.py を見るためには、spyder の場合 polyphony.typing の typing の上で右クリックし、[定義へ移動]で表示できます)
testbench では flfsr( ) 関数の戻り値を次の引数として繰り返すことで、連続した巡回符号を生成しています。フィボナッチ線形帰還シフトレジスタで生成しているので、1ビット右シフトして最上位ビットにはタップ位置のXORで生成したビットを入れるという操作が繰り返されています。python 実行の時には print(format(rv, '09b')) で表示するとわかりやすいです。 clksleep(10) は単にシミュレーションを10クロック分延ばしているだけで、特に意味はありません。
実行結果
print format の方を有効にして このまま python で実行したときの結果
1:100000000 0:010000000 0:001000000 0:000100000 0:000010000 0:100001000 0:010000100 0:001000010 0:000100001 1:100010000
polyphony で Verilog にコンパイルしてシミュレーションした結果は下記。
コンパイルに関しては、
Polyphonyって何だろう(1)インストール - メグタンの何でもブログ
で compile.py の target を 'flfsr' にして実行してください。
モジュールは flfsr.v に、テストベンチは flfsr_test.v に書き出されます。
注意点
コンパイル時にエラーとなる表記があるので注意が必要です。
- print の format 出力
- 日本語utf-8 (コメント文中でもエラーとなる):単純に polyphony でコンパイルする時に読み飛ばしてくれる表現の仕方があると便利なのですが。例えば python でデバッグする時に matplotlib でグラフ表示ができたりすると便利。print format も python 実行時のみ有効になると便利。
- x**2とかはNG
- 今回には出てきませんが、パラメータ値等をpythonの事前計算で求めて埋め込むためには @pure 宣言した関数が使えますが、三角関数等の計算結果を使いたい時に import numpy は エラーになります。import math は出来るのでこれを @pure で使えます。計算結果を Verilog に埋め込むだけなので、何でも import 出来てくれるとありがたいのですが。
実行環境:Win10 Anaconda(python3.7.1) Spyder polyphony0.3.4 iverilog0.9.7