工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Industrial programming >> VHDL

Quartus Prime IPライブラリをVUnitに統合する:ステップバイステップガイド

VHDLシミュレーションでQuartus IPコアをVUnit検証フレームワークを通じて実行したいと思ったことはありませんか?

FPGAエンジニアのKonstantinos Paraskevopoulos氏がまさにそれを考えていましたが、適切なチュートリアルが見つかりませんでした。幸い、彼は自身の才能で解決方法を見つけ、VHDLwhizを通じてこのゲスト記事として共有してくれました。

Konstantinos氏に語っていただきましょう!

VUnitでシステムをシミュレートする際、Quartus IPカタログから事前定義されたIPを設計に組み込みたいケースはよくあります。このチュートリアルでは、外部Quartus IPライブラリをVUnit環境で生成、組み込み、リンクするために必要な知識を提供します。

VUnitを初めて使う方へ:VUnit入門チュートリアルをご覧ください

概要

このチュートリアルは3つの主要パートで構成されます:

  1. 選択したIPの簡単な説明
  2. 適切なライブラリの生成とリンクに必要な手順
  3. VUnitとModelSimを利用した検証

必要要件

基本的なVHDL知識とModelSimスキルがあることを前提としています。

テスト対象設計

シナリオとして、Quartus整数演算IPリストのパラレルアダーIPを使用します。

Quartus Prime IPライブラリをVUnitに統合する:ステップバイステップガイド

この設計は3つの16ビット入力ベクトルを受け取り、加算結果を17ビットベクトルで出力します。

ステップ1:IPの生成

IPカタログウィンドウで、Library/Basic functions/Arithmetic配下のパラレルアダーコンポーネントをダブルクリックしてアダーを生成します。

名前を付け、ニーズに基づいてコンポーネントをカスタマイズした後、右下の「Generate HDL」ボタンをクリックします。

Quartus Prime IPライブラリをVUnitに統合する:ステップバイステップガイド

この時点で、次の図のようなウィンドウが表示されます。

注: SimulationセクションのCreate simulation modelをVHDLまたはVerilogに設定する必要があります。デフォルトはnoneです。選択しない場合、given_ip_name.spdファイルが生成されず、次のステップが失敗します。

Quartus Prime IPライブラリをVUnitに統合する:ステップバイステップガイド

上記のプロセスにより、quartusディレクトリ配下にファイルとフォルダが生成されます:

  1. ファイル: given_ip_name.ip
  2. フォルダ: given_ip_name

フォルダには後でrun.pyスクリプトに追加する必要のある.vhdおよび.vファイルが含まれます。

ステップ2:IPシミュレーションファイルの生成

  1. GUI: Tools ➤ Generate Simulator Setup Script for IPを選択し、プロンプトウィンドウで出力ディレクトリを指定
  2. CMD: Qsysコマンドを利用して、ターミナルで以下のコマンドを入力して同じファイルを生成
ip-setup-simulation --quartus-project= <project's_QPF_filepath> \ --output-directory= <my_dir>

上記いずれかの方法で、Quartusにサポートされる各シミュレータ用のディレクトリを生成させ、IPライブラリの作成とコンパイル用スクリプトを保持させます。

ステップ3:ModelSim用IPライブラリの生成とコンパイル

次のステップは、前のステップで作成されたmentorフォルダ内のmsim_setup.tclスクリプトを見つけ、それを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ライブラリが生成されたので、Pythonrun.pyスクリプトを使用してリンクします。

以下の図を参照して、例のディレクトリ構造を理解してください。初期トポロジは、ルートフォルダdemo、tb、vunit、quartusフォルダで構成されていました。quartusフォルダ配下のすべてのサブフォルダとファイルは、プロジェクト作成とステップ1~3の完了後にQuartusフレームワークによって生成されます。

注: Quartusはさらに多くのファイルとフォルダを生成しますが、以下の画像は私たちに関連するものを示しています。

Quartus Prime IPライブラリをVUnitに統合する:ステップバイステップガイド

このトポロジの明確なビューを参考に、ROOTパスと生成されたライブラリへのパスを以下のように指定できます。

sim_filesはステップ2で指定したディレクトリで、mentorフォルダが格納されています。

from vunit import VUnit
from os.path import join, dirname, abspath
# ROOT
root = join(dirname(__file__), '../')
# 生成ライブラリへのパス
path_2_lib = '/quartus/sim_files/mentor/libraries/'
# ROOT

vuというVUnitインスタンスを作成後、VHDLコード用の設計ライブラリを指定し、必要な外部ライブラリをリンクします:

# コマンドライン引数を解析してVUnitインスタンスを作成
vu = VUnit.from_argv()
# 設計ライブラリを作成
my_lib = vu.add_library('my_lib')
# 外部ライブラリをリンク
vu.add_external_library("parallel_adder", root + path_2_lib + "parallel_adder")

最後に、ソースファイルを追加します。これらはgiven_ip_nameディレクトリ配下の3つのサブフォルダにあります:

  1. parallel_add_191
  2. synth
  3. sim

synthとsimディレクトリには同じ情報、つまりIPのトップレベル設計が含まれます。ただし、ステップ1で選択した言語に応じてVHDLまたはVerilogでフォーマットされています。

トップレベル設計がサブコンポーネントを含む場合、それらのソースファイルも含める必要があります。それらは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とip_name_inst.vで、VHDLとVerilogのコンポーネントインスタンス化例を提供しています。

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つしか定義されていないため、それを指定するオプションを提供する必要はありません。

Quartus Prime IPライブラリをVUnitに統合する:ステップバイステップガイド

最後に、ModelSimで結果を検証するには、以下のコマンドを入力します:

python ./run.py --gui

Quartus Prime IPライブラリをVUnitに統合する:ステップバイステップガイド

(画像をクリックすると拡大表示されます)

結論

結論として、IPカタログに存在するQuartus IPをVUnit環境内で組み込み、テストする方法を学びました。このチュートリアルでは事前定義IPを使用しましたが、同じプロセスがカスタムパッケージIPにも適用されます。

まだの方はこちらのVUnitチュートリアルもご覧ください:
VUnit入門

VHDL

  1. チェーンリンクフェンス製造機:仕組みとメリット
  2. テクノロジーが鍵:透明で倫理的なサプライチェーンの実現
  3. 油圧ギアポンプのプライミング手順:最適な性能を引き出すために
  4. フォードトラクター油圧ポンプのプライミング手順:ステップバイステップガイド
  5. SigFox解説:技術、市場インパクト、Link Labsとの比較
  6. VUnit 101:自動化VHDL検証の実践ガイド
  7. VHDLで文字列リストを作成する: ベスト・プラクティスと実装例
  8. VHDLテストベンチ・シミュレーションを優雅に終了させる方法
  9. VHDLでPWMコントローラを実装: 設計、シミュレーション、FPGAデモ
  10. VHDLで乱数生成: 一様分布からOSVVMまで
  11. VHDLで自己検証テストベンチを構築する実践ガイド