Veriloggenって何だろう(8)Thread 高位合成
Verilog HDL を生成するための記述を python で行うことで FPGA 回路の生成を楽にする為のライブラリー Veriloggen を使ってみたいと思います。今回は高位合成のThreadの使用例を書きます。
高位合成 Thread によるフィボナッチ数列生成
pythonで書いた関数を Verilog に変換するという高位合成を行う機能という事になります。今まで扱ってきた Veriloggen の python でどんな Verilog を作りこんでいくかの記述の中に、python の計算関数を埋め込むイメージになると思います。
試しに、フィボナッチ数列を出力するモジュールを作ってみました。
from veriloggen import Module import veriloggen.simulation as sm from veriloggen import Delay, Wait, Systask import veriloggen.thread as vthread import veriloggen_util as vu # %% def mkFib(): m = Module('FIB') clk = m.Input('CLK') rst = m.Input('RST') n = m.Input('N',8) st = m.Input('ST') fiba = m.OutputReg('FIBA', 16, initval=0) fibb = m.OutputReg('FIBB', 16, initval=0) finish = m.OutputReg('FINISH', 1, initval=0) def fib(): while True: if st != 0: finish.value = 0 fiba.value = fibcalc(n) finish.value = 1 def fibcalc(nt): if nt == 0: return 0 if nt == 1: return 1 r0 = 0 r1 = 1 for i in range(nt): r0, r1 = r1, r0+r1 fibb.value = r0 print(r0, r1) return r1 th = vthread.Thread(m, 'th', clk, rst, fib) fsm = th.start() return m # %% def mkTest(): m = Module('test') #target instance fib = mkFib() #copy parameters and ports params = m.copy_params(fib) ports = m.copy_sim_ports(fib) clk = ports['CLK'] rst = ports['RST'] n = ports['N'] st = ports['ST'] fiba = ports['FIBA'] fibb = ports['FIBB'] finish = ports['FINISH'] uut = m.Instance(fib, 'uut', params=m.connect_params(fib), ports=m.connect_ports(fib)) sm.setup_waveform(m, uut, m.get_vars()) sm.setup_clock(m, clk, hperiod=5) init = sm.setup_reset(m, rst, m.make_reset(), period=50) init.add( st(0), n(4), st(1), [sm.next_clock(clk) for i in range(3)], st(0), Wait(finish), [sm.next_clock(clk) for i in range(10)], n(8), st(1), [sm.next_clock(clk) for i in range(3)], st(0), Wait(finish), [sm.next_clock(clk) for i in range(5)], Systask('finish') ) return m # %% #delete old file vu.delete_file('a.out') vu.delete_file('tmp.v') vu.delete_file('uut.vcd') test = mkTest() verilog = test.to_verilog('tmp.v') print(verilog) vu.addtimescale('tmp.v') vu.run_iverilog('tmp.v') vu.run_vvp() vu.view_waveform_gtkwave()
N に繰り返しの回数をセットし、STARTに信号を入れるとフィボナッチ数列を FIBB から出力し、所定回数の繰り返しが終了すると、次の数を FIBA から出力して FINISH 信号が立ち上がるという物です。
python の計算部分が fibcalc になりますが、残念ながら fibcalc のループ内から FIBB を出力しているので、このまま python のコードとはいきませんが、計算アルゴリズムを python 文法で書いているのは確かです。
この中の Verilog_util に関しては、
Veriloggenって何だろう(7)Parameter Delay Mux Sra - メグタンの何でもブログ
を参照してください。
実行結果
上記ファイルを実行すると フィボナッチ数列を出すモジュールとテストベンチが書かれた Verilog HDL ファイルである tmp.v が出力され、iverilog によって出力された シミュレーション用ファイル a.out ができます。a.out を VVP に読み込ませてシミュレーションした結果が uut.vcd で、これが gtkwave の入力となります。
結果は下記になりますが、1行ごとに状態遷移して遅れが生じるようで、あまり速くありませんが、pythonで記述した計算を Verilog にできるのは便利だと思います。
実行環境:Win10 python3.7.1 veriloggen1.5.4 iv1.5.4