Veriloggenって何だろう(1)インストール
Verilog HDLを生成するための記述をpythonで行うことでFPGA回路の生成を楽にする為のライブラリーVeriloggenを使ってみたいと思います。
まずはWindows上に動作環境を作成します。
Verilog HDL (Verilog Hardware Description Language)はハードウエア設計のためのDSL(Domain Specification Language)で、FPGAの回路設計をする時に使用します。ソフトウェアの様にプログラムで回路を記述しますが、コンピュータのソフトウェアと違うところは、記述したものが回路に展開され同時実行されるという事です。回路に展開する事を論理合成(logic synthesis)と言いますが、ソフトウェアエンジニア的には、あまりしっくりこない言葉ですが、慣れるしかない。
Verilog HDLで記述できるのはレジスタートランスファーレベル(RTL)と言われる単位で、何ビットのレジスタを作って、それをビットシフトして、何々とANDしてとか非常に細かいレベルでの記述が求められます。
回路が並列動作をするので、通常共通のクロック信号で同期をとりながら動作するようにロジックを組むことになります。
コンピュータのソフトウエアでアナロジーしてみると、NAND等で回路を組むのが、機械語でのプログラミングに相当し、Verilog HDLで記述するのがアセンブラでソフトを書くのと似ています。
機械語は論外だし、アセンブラで記述するのも大変だからC言語で記述したいと考えるのが世の常です。Verilog HDLよりももっと高級な言語で回路を記述できないかという事で、C等で記述したアルゴリズムを回路に落とすための高位合成(High Level Synthsis)という物もありますが、ソフトウェア言語で書かれたロジックはシーケンシャルに上から下へ逐次実行されるアルゴリズムなので、複雑な計算を記述するのには向きますが、組み込みソフトの様にクロックに合わせていろいろな機能を同期動作させる為には向きません。
ということで、Verilog HDLよりも、もう少し抽象化された表現で、もっと読み易い表記方法で記述する高級HDLと言えるようなものがあります。Veriloggenもその一つで、Pythonを使用してVerilog HDLを生成するライブラリーです。高位合成と違ってPythonで動くアルゴリズムをVerilog HDLに変換するわけではありません。何がうれしいかというと、記述が読み易いとか、Pythonで同じ動作とか類似機能を自動生成できるとか、抽象度を上げた表記方法で記述行数を減らせる等いろいろとメリットがあります。モジュールレベルの動作検証も簡単に記述できるので便利です。 最新のVeriloggenではPythonのサブセットで記述できるHLSにも対応しています。
まずは、Pythonのインストールから始めましょう。
PythonはAnacondaを使用してWIndowsにインストールすることにします。
Anacondaには通常使われるライブラリーと開発環境Jupyter Notebook とか Spyderが含まれているので、すぐにPythonを使うことができます。
Anaconda インストール
① Anaconda ダウンロード
上記からPython3.7をダウンロード
② インストール
- インストール先のフォルダーはTOPにしましょう。
(例)c:\Anaconda3
- インストールは個人環境(Just Me)にインストールするのが良いです。
③ 仮想環境の作成
Pythonは多くのライブラリーで動作するのでバージョンの競合を起こしやすいです。
その為、目的ごとに仮想環境を作ってライブラリーのバージョンを固定する方がいいです。
- "Anaconda Prompt"を起動
- 仮想環境をverilogという名前で作成
>conda create -n verilog python=3.6 anaconda
- 仮想環境verilogに切り替え
>activate verilog
- Jupyter Notebookで環境切り替えができるようにカーネルをインストール
>ipython kernel install --user --name=verilog --display-name=verilog
- 便利なのでJupyter Notebookに拡張機能を追加しておきましょう。
>conda install -c conda-forge jupyter_contrib_nbextensions
④ Veriloggen関連インストール
>pip install jinja2 >pip install pyverilog >pip install ipgen >pip install veriloggen
以上でJupyter Notebookを使用してもSpyderを使用してもVeriloggenを使用できるようになりました。
※install で "unicodedecodeerror 'cp932' codec can't decode" のエラーが出る時には、GitHub から一式をダウンロードして、setup.pyのopen()の中に encoding="UTF-8" を追加してみてください。Anaconda Prompt で activate verilog 状態でそのフォルダーに移動し、python setup.py install でインストール出来ると思います。
・ダウンロード(srcフォルダーにダウンロード)ipgenの場合
pip download -d src --no-binary :all: ipgen
・srcフォルダーに移動して setup.py を修正
def read(filename):
return open(os.path.join(os.path.dirname(__file__), filename),encoding="UTF-8").read()
・python setup.py install
※condaの仮想環境を作成した時にスタートメニューに専用のショートカット Anaconda Prompt(verilog)等 ができますが、うまく起動しない事があるようです。その場合は最初からあるものを起動し、activate verilogで切り替えるか、Anaconda Navigatorを使用するのがよさそうです。私の場合、スタートメニューのSpyder(verilog)からSpyderを立ち上げるとワーニングが出ますが、Navigatorから環境を切り替えてSpyderを起動するとワーニングなしで起動します。Navigatorは仮想環境の構築からモジュールのインストール管理まで出来て、conda-forge等のchannelも登録してGUIで操作できるので便利ですが、動作が重いのと、pip等condaだけで完結しない部分もあるので万能ではないのが残念です。
Icarus Verilog for Windowsのインストール
Veriloggenで作成されたVerilog HDLをシミュレーションする環境を作成します。
① iverilogのダウンロード
下記から iverilog-0.9.7_setup.exeをダウンロード
Icarus Verilog for Windows
② iverilogのインストール
- これもインストールフォルダーはTOPが良い
(例)c:\iverilog
③ 動作確認
④ iverilogの使い方
Veriloggenを使用するとPython上からiverilogもgtkwaveも起動できるので、コマンドを打つ必要はありませんが、以下のようなイメージでコマンドが実行されます。
>iverilog prog.v tb_prog.v -o a.out
- シミュレーション実行
>vvp a.out
- 波形観察
>gtkwave test.vcd
Windows向けに修正
Veriloggenは北海道大学の高前田先生が開発してくださっていますが、Linux環境での開発のようで、Windowsでは iverilog の起動に少し不具合があるようなので修正しておきます。
修正するファイルは simulation.py です。
上記の様にインストールした場合には
c:\Anaconda3\envs\verilog\Lib\site-packages\veriloggen\simulation\simulation.py
になります。
iverilog を使用するので、このファイルの run_iverilog の内容を修正します。
ここではtempファイルを使用していますが NamedTemporary の動作がLinixとwindowsで異なるので、mkstemp を使用するように修正します。
mkstempで作成されたファイルは自動では消えてくれないので、自分で削除する部分も追加します。
また、シミュレーション実行の部分で a.out の関連付けが無いとこのままでは動かないので、vvpを明示的に起動します。
修正前
def run_iverilog(self, display=False, outputfile='a.out', include=None, define=None): ・・・・・ tmp = tempfile.NamedTemporaryFile() tmp.write(code.encode(encode))
# simulation p = subprocess.Popen('./' + outputfile, shell=True, stdout=subprocess.PIPE) sim_rslt = []
# close temporal source code file tmp.close() return ''.join([syn_rslt, sim_rslt])
修正後
def run_iverilog(self, display=False, outputfile='a.out', include=None, define=None): ・・・・・ #tmp = tempfile.NamedTemporaryFile() fd,path=tempfile.mkstemp() os.close(fd) tmp = open(path, "w+b") tmp.write(code.encode(encode))
# simulation cmd=[] cmd.append('vvp') cmd.append(outputfile) p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) sim_rslt = []
# close temporal source code file tmp.close() os.remove(path) return ''.join([syn_rslt, sim_rslt])
次回はサンプルを動かしてみます。