Quartus Prime IP ライブラリを VUnit にリンクする方法
VUnit 検証フレームワークを介して Quartus IP コアを含む VHDL シミュレーションを実行したいと思ったことはありませんか?
これは FPGA エンジニアの Konstantinos Paraskevopoulos 氏が念頭に置いていたことですが、適切なチュートリアルが見つかりませんでした。幸いなことに、彼は才能を発揮して方法を見つけ出し、このゲスト記事を通じて VHDLwhiz と共有してくれました。 .
コンスタンティノスに贈ろう!
VUnit でシステムをシミュレートするときに、Quartus IP カタログから定義済みの IP をデザインに組み込むことが望ましい場合がよくあります。したがって、次のチュートリアルは、外部 Quartus IP ライブラリの生成、組み込み、および VUnit 環境へのリンクに関する知識を読者に提供することを目的としています。
VUnit は初めてですか?このチュートリアルをチェックしてください:VUnit の概要
概要
このチュートリアルは 3 つの主要部分で構成されています:
<オール>要件
- クォータス
- Quartus Prime をダウンロード
- QSYS は、STEP 2 (CMD オプション) の PATH にある必要があります
- Intel Modelsim
- ModelSim を無料でインストールする方法については、この記事を参照してください
- ModelSim は PATH にあるはずです
- VUnit
- VUnit を無料でインストールする方法については、この記事を参照してください
- Python 3.6 以上
- Python をダウンロード
- Python がパスに含まれている必要があります
また、基本的な VHDL の知識と ModelSim のスキルがあることも前提としています。
テスト中の設計
このシナリオでは、Quartus Integer Arithmetic IP リストから Parallel Adder IP を使用します。
この設計は 3 つの 16 ビット入力ベクトルを受け入れ、加算結果を 17 ビット ベクトルで出力します。
ステップ 1 :IP を生成する
Library/Basic functions/Arithmetic の下にある並列加算器コンポーネントをダブルクリックして、IP カタログ ウィンドウで加算器を生成します。
名前を付けて、必要に応じてコンポーネントをカスタマイズしたら、右下にある [HDL の生成] ボタンをクリックします。
この時点で、次の図に示すようなウィンドウが表示されます。
注: Create simulation model
を設定する必要があります Simulation
の下 セクションを VHDL または Verilog にコピーして、シミュレーション ファイルを生成します。これは、デフォルト オプションが none であるためです。どちらかを選択しない場合、given_ip_name.spd
ファイルが生成されず、次のステップが失敗します。
上記のプロセスにより、ファイルとフォルダーが quartus
の下に生成されます ディレクトリ:
given_ip_name.ip
given_ip_name
フォルダには .vhd
が含まれます と .v
後で run.py
に追加する必要があるファイル
ステップ 2 :IP シミュレーション ファイルを生成する
<オール>ip-setup-simulation --quartus-project= <project's_QPF_filepath> --output-directory= <my_dir>
上記の 2 つの方法のいずれかを使用して、サポートされているシミュレータごとに、IP ライブラリを作成およびコンパイルするためのスクリプトを保持するディレクトリを生成するよう Quartus に指示します。
ステップ 3:Modelsim 用の IP ライブラリを生成してコンパイルする
次のステップは msim_setup.tcl
を見つけることです mentor
のスクリプト 前の手順で作成したフォルダーを setup.tcl
という名前で複製します .次に、setup.tcl
で ファイルで、図のコマンドのコメントを外し、$QSYS_SIMDIR
を設定します。
# # QSYS_SIMDIR is used in the Quartus-generated IP simulation script to # # construct paths to the files required to simulate the IP in your Quartus # # project. By default, the IP script assumes that you are launching the # # simulator from the IP script location. If launching from another # # location, set QSYS_SIMDIR to the output directory you specified when you # # generated the IP script, relative to the directory from which you launch # # the simulator. # # set QSYS_SIMDIR <script generation output directory> # # # # Source the generated IP simulation script. source $QSYS_SIMDIR/mentor/msim_setup.tcl # # # # Set any compilation options you require (this is unusual). # set USER_DEFINED_COMPILE_OPTIONS <compilation options> # set USER_DEFINED_VHDL_COMPILE_OPTIONS <compilation options for VHDL> # set USER_DEFINED_VERILOG_COMPILE_OPTIONS <compilation options for Verilog> # # # # Call command to compile the Quartus EDA simulation library. dev_com # # # # Call command to compile the Quartus-generated IP simulation files. com # #
setup.tcl
を変更して保存した後 vsim
を使用して Tcl ファイルを安全に実行できます。 コマンド。
vsim -c -do "do setup.tcl; quit"
mentor
でコンパイルされたライブラリを生成します
ステップ 4:VUnit リンク
IP ライブラリが生成されたので、python run.py
を使用してリンクする必要があります。
下の図をチェックして、この例のディレクトリ構造をよりよく理解してください。初期トポロジは、ルート フォルダ demo
で構成されていました 、tb
、 vunit
、および quartus
フォルダ。 quartus
の下のすべてのサブフォルダーとファイル フォルダーは、プロジェクトを作成し、ステップ 1 から 3 を完了した後、Quartus フレームワークを介して生成されます。
注: Quartus はさらに多くのファイルとフォルダーを生成しますが、下の画像は私たちにとって興味深いものを示しています。
トポロジのこの明確なビューを参照として使用して、以下に示すように、ROOT パスと生成されたライブラリへのパスを指定できます。
sim_files
に注意してください メンター フォルダーが保存されている、手順 2 で指定したディレクトリです。
from vunit import VUnit from os.path import join, dirname, abspath # ROOT root = join(dirname(__file__), '../') # Path to generated libraries path_2_lib = '/quartus/sim_files/mentor/libraries/' # ROOT
vu
という VUnit インスタンスを作成した後 、VHDL コードのデザイン ライブラリを指定し、必要な外部ライブラリをリンクできます。
# Create VUnit instance by parsing command line arguments vu = VUnit.from_argv() # create design's library my_lib = vu.add_library('my_lib') # Link external library vu.add_external_library("parallel_adder", root + path_2_lib + "parallel_adder")
最後に、ソース ファイルを追加します。これらは、given_ip_name
の下の 3 つのサブフォルダにあります。 ディレクトリ:
parallel_add_191
synth
sim
synth
と sim
dirs には同じ情報、つまり IP の最上位設計が含まれています。ただし、この場合のこれらのファイルのフォーマットは VHDL です。それらは Verilog である可能性があり、これはステップ 1 で選択した言語によって異なります。
トップレベルの設計にサブコンポーネントが含まれている場合は、それらのソース ファイルも含める必要があります。 given_ip_name
のサブフォルダーの下にあります。 parallel_add_191
などのディレクトリ
my_lib.add_source_files(join(root,'quartus','parallel_adder','sim','parallel_adder.vhd')) my_lib.add_source_files(join(root,'quartus','parallel_adder','parallel_add_191','sim','parallel_adder_parallel_add_191_oh4guxa.vhd')) my_lib.add_source_files(join(root,'tb','tb_demo.vhd')) testbench = my_lib.entity("tb_demo") vu.main()
テストベンチ
まず、このリンクをチェックして、VUnit テストベンチ形成の基本について学ぶことができます。
テストベンチに戻り、必要な VUnit ライブラリと、使用したい他のライブラリを追加して、シグナルを定義します。
注: この例でのプロセスの実行はシーケンシャルです。したがって、制御信号 (フラグ と呼ばれる) ) は、プロセスが開始または終了するかどうかをプロセスに通知するために使用されます。
library IEEE; use IEEE.std_logic_1164.all; use ieee.numeric_std.all; library vunit_lib; context vunit_lib.vunit_context; entity tb_demo is generic ( runner_cfg : string:= runner_cfg_default); end tb_demo; architecture sim of tb_demo is constant clk_period : time := 10 ns; signal clk : std_logic := '0'; signal rst : std_logic := '0'; -- INPUTS signal data_a : std_logic_vector(0 to 15):= (others => '0'); signal data_b : std_logic_vector(0 to 15):= (others => '0'); signal data_c : std_logic_vector(0 to 15):= (others => '0'); -- OUTPUTS signal result : std_logic_vector(0 to 16); -- CONTROL FLAGS signal reset_done :boolean := false; signal sim_done :boolean := false; signal start_sim :boolean := false;
続いて、UUT をインスタンス化します。 Quartus は、ファイル名規則 ip_name_inst.vhd
の下で、VHDL および Verilog のコンポーネント インスタンス化の例を提供します。 と ip_name_inst.v
.
begin -- Unit Under Test UUT : entity work.parallel_adder port map ( data0x => data_a, -- parallel_add_input.data0x data1x => data_b, -- .data1x data2x => data_c, -- .data2x result => result -- parallel_add_output.result );
開始する最初の 2 つのプロセスは clk_process
です と reset_rel
. reset_done
をリセットして駆動した後、後者は中断されます。 true
へのフラグ 、clk_process
シミュレーション時間を通して動作します。
clk_process : process begin clk <= '1'; wait for clk_period/2; clk <= '0'; wait for clk_period/2; end process clk_process; reset_rel : process begin rst <= '1'; wait for clk_period*2; wait until rising_edge(clk); rst <= not rst; reset_done <= true; wait; end process reset_rel;
リセットが完了したので、test_runner
を呼び出すことができます テストを実行するためのプロセス。さらに、テストランナーは sim_done
までアクティブなままです フラグは true
に駆動されます 、最後のプロセスで行われます。
test_runner : process begin test_runner_setup(runner, runner_cfg); wait until reset_done and rising_edge(clk); iterate : while test_suite loop start_sim <= true; if run("test_case_1") then info ("Start"); info (running_test_case); wait until sim_done; end if; end loop; test_runner_cleanup(runner); end process test_runner;
最後に、data_generator
プロセスは、for
を利用して並列加算器の 3 つの入力に値を割り当てることで、いくつかの加算を実行します。 ループ。
注: このプロセスは test_runner
プロセスは start_sim
を設定することでそう指示します 国旗。このプロセスの最後に、sim_done
が発生します。 シミュレーションを一時停止するようにテスト ランナーに命令するフラグ。
data_generator : process constant tag2 : log_level_t := new_log_level("INFO", fg => blue, bg => black, style => bright); variable a,b,c,d : integer; begin wait until start_sim; wait until rising_edge(clk); show(display_handler, tag2); if running_test_case = "test_case_1" then for i in 0 to 10 loop data_a <= std_logic_vector(to_unsigned(i+10,data_a'length)); data_b <= std_logic_vector(to_unsigned(i+20,data_a'length)); data_c <= std_logic_vector(to_unsigned(i+30,data_a'length)); wait until rising_edge(clk); a := to_integer(unsigned(data_a)); b := to_integer(unsigned(data_b)); c := to_integer(unsigned(data_c)); d := to_integer(unsigned(result)); log( integer'image(a) &" + "& integer'image(b) &" + "& integer'image(c) &" = "& integer'image(d), tag2); end loop; end if; sim_done <= true; end process data_generator;
確認
テスト ケースを実行し、すべてが期待どおりに機能することを確認するには、run.py
を実行します。 ターミナルに次のコマンドを入力するだけで、ディレクトリからスクリプトを実行できます。
python ./run.py -v
注: カスタマイズされたロガーは、詳細な-v
を提供することで表示される出力のより良い説明のために使用されています オプション。さらに、テスト ケースは 1 つしか定義されていないため、それを指定するオプションを提供する必要はありません。
最後に、ModelSim で結果を検証するために、次のコマンドを入力できます。
python ./run.py --gui
(画像をクリックすると大きくなります)
結論
結論として、このチュートリアルでは、IP カタログにある Quartus IP を VUnit に組み込んでテストする方法について学びました。事前定義された IP を採用しました。ただし、パッケージ化されたカスタマイズされた IP をこの方法で VUnit 環境に統合することもできます。
この VUnit チュートリアルをまだチェックしていない場合は、こちらをチェックしてください:
VUnit を使ってみる
VHDL