RTL カーネル: krnl_aes

概要

この部分のチュートリアルでは、「RTL モジュール: AES」 で作成した AES モジュールを使用します。RTL ロジックを追加し、Vivado® IP および Vitis カーネル (XO) ファイルにパックします。この Vitis™ カーネル ファイルを Vitis の v++ フローで直接使用すると、XCLBIN オーバーレイ ファイルを作成できます。また、XRT ライブラリを使用すると、ホストとカーネル間のカーネル制御とデータ転送ができます。

カーネルの機能

krnl_aes カーネルには 4 つの AES モジュールが含まれており、それぞれが AXI ストリーム スレーブおよびマスター ポートの外部に接続されています。また、カーネル制御用の AXI スレーブ ポートもあります。デザインを簡素化するために、すべての AES モジュールで同じ設定 (暗号化/復号化モード、キー長、およびキー値) が使用されます。

krnl_aes は実際には内部で 2 つのクロックを使用します。1 つは外部 AXI ポート用、もう 1 つは内部 AXI ポートおよび AES コア用です。AES コアは、プラットフォームの AXI インターコネクトよりも高い周波数で動作します。

カーネル用の周波数の高いクロックを取得するには、2 つの方法があります。 1 つ目は、提供されたセカンダリ プラットフォーム クロック、つまり ap_clk_2 ポートを使用する方法です。Alveo™ データセンター アクセラレータ カードでは、ターゲット プラットフォームがユーザー カーネル用の複数のクロックを提供しています。たとえば、Alveo U200 xilinx_u200_xdma_201830_2 プラットフォームでは、ap_clk および ap_clk_2 という 2 つのシステム クロック (デフォルト周波数はそれぞれ 300MHz と 500MHz) が提供されいます。周波数は、Vitis の v++ リンク プロセスで設定できます。ap_clk_2 は、Alveo プラットフォームのスタティック領域にあるスタンドアロン MMCM によって生成されます。追加クロックを取得する 2 つ目の方法では、RTL カーネル内で MMCM を手動でインスタンシエートします。これにより、一部の特定の要件の柔軟性が向上する場合があります。

ここで提供されるデザイン例では、2 つ目の方法を使用して必要なクロックを生成します。krnl_aes カーネルには、プラットフォームが提供する標準の 300MHz 入力クロックから 400MHz クロックを生成するようにカスタマイズされた MMCM モジュールが含まれています。

UltraScale+™ Alveo ターゲット プラットフォームは、スタティック領域とダイナミック領域に分割されます。ダイナミック領域内にカスタマがインスタンシエートした MMCM は、プラットフォーム バス クロックの駆動に使用される可能性のあるスタティック領域内の MMCM で駆動される可能性があります。これは通常、大きなクロック スキューを発生させ、同期デザインがタイミングを満たしにくくします。タイミング クロージャを達成しやすくするには、カスタマ MMCM で駆動されるこれらのモジュールが、プラットフォーム バス クロックに対して非同期モードで動作する必要があります。このデザイン例では、AXI スレーブ制御モジュールと 4 つの AES エンジンはすべて 400MHz クロック ドメインで動作し、カーネルは 300MHz 標準プラットフォーム クロック ドメインに接続されます。このため、全部で 9 つの AXI/AXIS クロック コンバーター IP がカーネルの最上位レベルで使用されます。1 つは AXI 制御スレーブ用の AXI クロック コンバーター、4 つは AXIS スレーブ ポート用の AXIS クロック コンバーター、4 つは AXIS マスター ポート用の AXIS クロック コンバーターです。

次は、krnl_aes カーネルのブロック図です。

krnl_aes の図

XRT でサポートされている Vitis アクセラレーション アプリケーションには、ap_ctrl_none、ap_ctrl_hs、および ap_ctrl_chain の 3 つのカーネル実行モデルがあります。詳細は、UG1416「サポートされるカーネル実行モデル」を参照してください。この RTL カーネル krnl_aes は ap_ctrl_none モードと ap_ctrl_hs モードの混合です。ap_ctrl_hs は AES キー拡張操作に使用されるので、ホストは AES キー拡張操作の終了を待って開始します。ap_ctrl_none は、一般的な AES 暗号化/復号化操作に使用されるので、カーネルが AXI ストリーム スレーブ ポートから入力データを受信するとすぐに、暗号化/復号化操作を自動的に開始および終了し、出力データを AXI ストリーム マスター ポートに送信します。

krnl_aes では、ap_ctrl_hs モードに次の制御信号波形がインプリメントされます。XRT は ap_start 信号をアサートしてカーネル実行を開始します。ap_start は ap_ready 信号によって High に維持され、ディアサートされます。ap_ready は実際には ap_done 信号のコピーです。最後に、ap_done が AXI スレーブ ポートの読み出し制御レジスタ操作で一掃されます。XRT スケジューラは、ap_start のステータスに応じて ap_start をアサートするタイミングを実際に決定します。つまり、XRT で ap_start がディアサートされていることが検出されると、カーネルで新しい ap_start 要求を受信する準備ができたと認識されます。

ap_ctrl_hs モード

次の表に、AXI スレーブ ポートに含まれるすべての制御レジスタとカーネル引数を示します。このカーネルでは、割り込みはサポートされていません。

名前 アドレス オフセット 幅 (ビット) 説明
CTRL 0x000 5 制御信号。
ビット 0 - ap_start
ビット 1 - ap_done
ビット 2 - ap_idle
ビット 3 - ap_ready、ap_ctrl_hs モードの ap_done のコピー バージョン
ビット 4 - ap_continue、ap_ctrl_hs モードでは使用なし
MODE 0x010 1 カーネル暗号モード:
0 - 復号化
1 - 暗号化
KEY_LEN 0x018 2 AES キー長:
2'b00 = 128 ビット
2'b01 = 192 ビット
2'b10 = 256 ビット
STATUS 0x020 4 4 つの AES エンジンのステータス:
0 - アイドル
1 - ビジー
KEY_W7 0x028 32 AES キーのワード 7
KEY_W6 0x030 32 AES キーのワード 6
KEY_W5 0x038 32 AES キーのワード 5
KEY_W4 0x040 32 AES キーのワード 4
KEY_W3 0x048 32 AES キーのワード 3。キーの長さが 128 の場合、このワードは使用されません。
KEY_W2 0x050 32 AES キーのワード 2。キーの長さが 128 の場合、このワードは使用されません。
KEY_W1 0x058 32 AES キーのワード 1。キーの長さが 128/192 ビットの場合、このワードは使用されません。
KEY_W0 0x060 32 AES キーのワード 0。キーの長さが 128/192 ビットの場合、このワードは使用されません。

IP の生成

このデザイン例では、3 種類のデザイン IP と 2 種類の Verification IP を使用しています。

  • クロック ジェネレーター MMCM

  • AXI クロック コンバーター

  • AXI ストリーム クロック コンバーター

  • AXI マスター VIP

  • AXIS マスター VIP

  • AXIS スレーブ VIP

これらの IP はすべて Tcl スクリプト ~/krnl_aes/gen_ip.tcl によって生成されます。このスクリプトは非プロジェクト モードで実行するもので、主に 3 つの Tcl コマンド (create_ip、set_property および generate_target) を使用して IP 生成を終了します。詳細は、これらのスクリプトおよび関連する IP の資料を参照してください。

Vivado IP および Vitis カーネルへのデザインのパック

Vitis の RTL カーネル デザインの重要な手順の 1 つは、RTL デザインを Vitis カーネル ファイル (XO) にパッケージすることです。GUI バージョンの RTL カーネル ウィザードを使用すると、Vitis カーネルを作成できます。また、Vivado の GUI バージョンの IP パッケージャーを使用してデザインを Vivado IP にパッケージし、XO ファイルを生成することもできます。Vivado は、Vitis カーネル生成用のコマンド ライン フローも提供し、GUI バージョンと同じジョブを提供します。このチュートリアルでは、Vivado Tcl コマンドを使用して、バッチ モードで krnl_aes IP パッケージおよび XO ファイルを生成します。このデザインの完全なカーネル生成スクリプトは ~/krnl_aes/pack_kernel.tcl にあります。主な手順は以下のとおりです。詳細は、スクリプトを参照してください。実際には、スクリプトの各手順は GUI ツールに対応します。GUI バージョンの IP パッケージング ツールの使用については、「RTL カーネル」を参照してください。

手順 1: Vivado プロジェクトの作成およびデザイン ソースの追加

まず、ソース ファイルを含む Vivado プロジェクトを作成する必要があります。スクリプトは、Tcl コマンド create_project、add_files および update_compiler_order を使用してこの手順を終了します。すべての RTL ソース コード、生成された IP ファイル (XCI ファイル)、および XDC ファイルを、新しく作成されたプロジェクトに追加する必要があります。

最後に、ipx::package_project Tcl コマンドを使用して、IP パッケージング プロセスを初期化します。

create_project krnl_aes ./krnl_aes
add_files -norecurse {
        ../rtl/aes_wrapper.sv ... ...              \
        ../ip_generation/clk_gen/clk_gen.xci      \
        ../ip_generation/axi_clock_converter/axi_clock_converter.xci \
        ../ip_generation/axis_clock_converter/axis_clock_converter.xci \
        ../krnl_aes.xdc                     \
       }
update_compile_order -fileset sources_1
ipx::package_project -root_dir ./krnl_aes_ip -vendor xilinx.com -library user -taxonomy /UserIP -import_files -set_current true

この手順では、「WARNING: [IP_Flow 19-5101] Packaging a component with a SystemVerilog top file is not fully supported.「Please refer to UG1118 ‘Creating and Packaging Custom IP’」のような警告情報が表示されることもあります。現在のところ、Vitis ツール チェーンでは、最上位モジュールのポート定義を従来の Verilog 形式にする必要があります。最上位モジュール krnl_aes.sv は SystemVerilog 構文 (SystemVerilog インターフェイス オブジェクト) をいくつか使用していますが、従来の Verilog 形式のポート定義を使用するので、この警告は無視しても問題ありません。

手順 2: クロック、リセット、AXI インターフェイスの推論およびクロックとの関連付け

ここでは、最初に ipx::infer_bus_interface コマンドを使用して ap_clk および ap_rst_n を AXI バス信号として推論します。通常、RTL カーネルで使用されるクロックが ap_clk だけの場合、このコマンドは省略できます。デザインでより多くのクロック (ap_clk_2、ap_clk_3 など) を使用する場合は、ipx::infer_bus_interface コマンドを使用して、ポートを明示的に推論する必要があります。

ipx::infer_bus_interface ap_clk xilinx.com:signal:clock_rtl:1.0 [ipx::current_core]
ipx::infer_bus_interface ap_rst_n xilinx.com:signal:reset_rtl:1.0 [ipx::current_core]

すべての AXI インターフェイスは自動的に推論されます。このデザインでは、これらの AXI ポートには、制御 AXI スレーブ ポート (s_axi_control) が 1 つ、AXIS スレーブ ポート (axis_slv0~3) が 4 つ、AXIS マスター ポート (axis_mst0~3) が 4 つ含まれます。

次に、ipx::associate_bus_interfaces コマンドを使用して、自動的に推論される AXI インターフェイスおよびリセット信号 ap_clk に関連付けます。

ipx::associate_bus_interfaces -busif s_axi_control  -clock ap_clk [ipx::current_core]
ipx::associate_bus_interfaces -busif axis_mst0      -clock ap_clk [ipx::current_core]
  ...
ipx::associate_bus_interfaces -busif axis_slv0      -clock ap_clk [ipx::current_core]
  ...
ipx::associate_bus_interfaces -clock ap_clk -reset ap_rst_n [ipx::current_core]

手順 3: CTRL やユーザー カーネル引数を含む AXI 制御スレーブ レジスタの定義の設定

ここでは、ipx::add_register コマンドを使用して、レジスタを推論される s_axi_control インターフェイスに追加し、set_property コマンドを使用してレジスタのプロパティ (たとえば KEY_LEN) を設定します。

ipx::add_register KEY_LEN   [ipx::get_address_blocks reg0 -of_objects [ipx::get_memory_maps s_axi_control -of_objects [ipx::current_core]]]
set_property description    {AES key length}    [ipx::get_registers KEY_LEN -of_objects [ipx::get_address_blocks reg0 -of_objects [ipx::get_memory_maps s_axi_control -of_objects [ipx::current_core]]]]
set_property address_offset {0x018}             [ipx::get_registers KEY_LEN -of_objects [ipx::get_address_blocks reg0 -of_objects [ipx::get_memory_maps s_axi_control -of_objects [ipx::current_core]]]]
set_property size           {32}                [ipx::get_registers KEY_LEN -of_objects [ipx::get_address_blocks reg0 -of_objects [ipx::get_memory_maps s_axi_control -of_objects [ipx::current_core]]]]

KEY_LEN はカーネル引数名、AES key length はレジスタの説明、0x018 はレジスタのアドレス オフセット、32 はレジスタのデータ幅 (スカラー カーネル引数はすべて 32 ビット幅にする必要あり) です。

提供される Tcl スクリプトからは、前の表で定義されたすべてのレジスタが追加され、正しく定義されていることがわかります。

krnl_aes カーネルには AXI マスターポートがないので、設定する必要はありません。AXI マスターの設定については、次の krnl_cbc カーネル部分を参照してください。

手順 4: Vivado IP のパッケージおよび Vitis カーネル ファイルの生成

ここでは、set_property コマンドを使用して、2 つの必須プロパティ (sdx_kernel と sdx_kernel_type) を設定します。次に、ipx::update_source_project_archive および ipx::save_core コマンドを実行して、Vivado プロジェクトを Vivado IP にパッケージします。最後に package_xo コマンドを使用して Vitis XO ファイルを生成します。

set_property sdx_kernel true [ipx::current_core]
set_property sdx_kernel_type rtl [ipx::current_core]
ipx::update_source_project_archive -component [ipx::current_core]
ipx::save_core [ipx::current_core]
package_xo -force -xo_path ../krnl_aes.xo -kernel_name krnl_aes -ctrl_protocol ap_ctrl_hs -ip_directory ./krnl_aes_ip -output_kernel_xml ../krnl_aes.xml

上記の package_xo コマンドの使用方法では、カーネル記述 XML ファイルを自動的に生成するようにツールを設定しています。手動で作成する必要はありません。Vitis 対応の Vivado IP が存在し、そこから XO ファイルを生成する必要がある場合は、カーネル XML ファイルを手動で作成し、次のようにコマンドで指定することもできます。

package_xo -xo_path ../krnl_aes.xo -kernel_name krnl_aes -ip_directory ./krnl_aes_ip -kernel_xml ../krnl_aes.xml

この場合、カーネル実行モデルは package_xo コマンド ライン オプションではなく、hwControlProtocol プロパティを使用して XML ファイルで指定します。

テストベンチ

ザイリンクス AXI VIP を使用した krnl_aes モジュール用のシンプルな SystemVerilog テストベンチが提供されています。テストベンチ ソースは ~/krnl_aes/tbench ディレクトリにあります。krnl_aes に 4 つの完全に同一の AES エンジンがあるので、4 つのエンジンのうち 2 つだけをテストします。2 つの AXI ストリーム マスター VIP を使用して入力データをカーネルに送信し、2 つの AXI ストリーム スレーブ VIP を使用してカーネルから出力データを受信します。また、AXI マスターは、AES キー拡張操作用にカーネル引数を設定し、ap_ctrl_hs の方法でカーネル実行を制御するために使用されます。AXI VIP をカーネルとのやり取りに使用する方法の詳細は、tb_krnl_aes.sv ファイルを参照してください。

テストベンチへの入力ランダム データは Perl スクリプト ~/common/ plain_gen.pl によって生成され、出力チェック用の基準データは OpenSSL ツールによって生成されます。シェル スクリプト ~/krnl_aes/runsim_krnl_aes_xsim.sh は、入力スティミュラス、出力基準を生成し、Vivado XSim でシミュレーションを実行するために使用されます。

カーネル テスト システムとオーバーレイ (XCLBIN) の生成

krnl_aes のテスト システム オーバーレイを構築するには、krnl_aes とデータをやり取りするのに AXI ストリーム マスターおよび AXI ストリーム スレーブが必要です。これには、メモリ マップされた単純な AXI から AXIS へのカーネルと、HLS C 言語での AXIS から AXI へのメモリ マップされたカーネルを記述します。これらは ~/krnl_aes/hls ディレクトリにあり、それぞれ strm_issue.cpp および strm_dump.cpp と呼ばれます。

これら 2 つのカーネルの HLS C インプリメンテーションは次のようになります。j 変数を含む for ループはエンディアン変換用です。入力/出力データは 128 ビットのデータ幅の AXI バスを介してリトル エンディアンとして転送されます。この 128 ビットのデータはビッグ エンディアンの積分ワードとみなされます。

#define PTR_WIDTH 128

void strm_issue (hls::stream<ap_axiu<PTR_WIDTH, 0, 0, 0>>& data_output,
                ap_uint<PTR_WIDTH> *data_input,
                int byte_size)
{
    for (int i = 0; i < (byte_size * 8 / PTR_WIDTH); i++) {
    // clang-format off
    #pragma HLS PIPELINE II = 1
    // clang-format on
        ap_uint<PTR_WIDTH> data_in, data_out;
        ap_axiu<PTR_WIDTH, 0, 0, 0> temp;
        data_in = data_input[i];
        for (int j = 0; j < (PTR_WIDTH / 8); j++) {
            data_out.range(j*8+7, j*8) = data_in.range((PTR_WIDTH/8-1-j)*8+7, (PTR_WIDTH/8-1-j)*8);
        }
        temp.data = data_out;
        data_output.write(temp);
    }
}

void strm_dump (hls::stream<ap_axiu<PTR_WIDTH, 0, 0, 0>>& data_input,
                ap_uint<PTR_WIDTH> *data_output,
                int byte_size)
{
    for (int i = 0; i < (byte_size * 8 / PTR_WIDTH); i++) {
    // clang-format off
    #pragma HLS PIPELINE II = 1
    // clang-format on
        ap_axiu<PTR_WIDTH, 0, 0, 0> temp = data_input.read();
        ap_uint<PTR_WIDTH> data_in, data_out;
        data_in = temp.data;
        for (int j = 0; j < (PTR_WIDTH / 8); j++) {
            data_out.range(j*8+7, j*8) = data_in.range((PTR_WIDTH/8-1-j)*8+7, (PTR_WIDTH/8-1-j)*8);
        }            
        data_output[i] = data_out;
    }
}          

合計で 4 つの strm_issue と 4 つの strm_dump カーネルがテスト システムの krnl_aes に統合されて、リンク操作は ~/krnl_aes/Makefile に記述されています。~/krnl_aes/krnl_aes_test.cfg ファイルには、このデザインに必要な Vitis リンク オプションがあります。このコンフィギュレーション ファイルには、追加の XDC ファイル (~/krnl_aes/krnl_aes_test.xdc) が含まれています。これは、krnl_aes カーネル内のカスタマイズされた MMCM のリンク段階で発生するクリティカル警告をなくすためです。

ホスト プログラミング

ホスト プログラミングでは、XRT ネイティブ C++ API を使用して、FPGA でのカーネル実行を制御できます。XRT ネイティブ API は、非常にわかりやすく使いやすいものです。特にホスト カーネル間の頻繁なやり取りを必要とする場合に、XRT OpenCL よりも効率が上がります。XRT ネイティブ API の詳細は、「XRT ネイティブ API」を参照 してください。

ホスト プログラムは、ランダム データをプレーン入力として生成し、OpenSSL AES API を使用して基準暗号データを生成します。また、ハードウェア エミュレーション (hw_emu) フローもサポートし、hw または hw_emu モードの正しい XCLBIN ファイルを選択します。

ホスト プログラムは、run.start() 関数の後に run.wait() 関数を 1 つのスレッドで使用します。これは、ap_ctrl_hs 実行モデルの一般的な使用方法です。

krnl_aes カーネルが暗号化モードから復号化モードに移行する際には、MODE カーネル引数を使用してカーネルの機能を変更する必要があります。レジスタをアップデートするには、次の 2 つの方法があります。

  1. 下位レベルの kernel.write_register() API を使用

  2. 高位レベルの run.set_arg() API を使用してから、run.start() を使用

2 つ目の方法では、run.set_arg() 関数は run.start() 関数が呼び出されるまで有効になりませんので、レジスタの書き込み操作を実行するには、run.start() を実行する必要があります。キー拡張操作を再度実行する必要はなく、データ暗号化/復号化操作用のカーネルは ap_ctrl_none モードで動作します。

次に、この 2 つの方法のコード部分を示します。

// Method 1 to configure krnl_aes to decryption mode
//   use run instance to set kernel argument. The kernel register will not be updated until run()
  run_key_exp.set_arg(0,0);                       // index for argument MODE is 0
  run_key_exp.start();
  run_key_exp.wait();

// Method 2 to configrue krnl_aes to decryption mode
//   use kernel write_register() to access the register directly
  int reg_offset = kernel_krnl_aes.offset(0);     // reg_offset = 0x10 for krnl_aes kernel register MODE
  kernel_krnl_aes.write_register(reg_offset, 0);  // set MODE = 0

チュートリアルの使用方法

開始前の確認事項

このチュートリアルでは、~/krnl_aes ディレクトリ内のファイルを使用します。

このチュートリアルでのホスト プログラムの実行を除くすべての手順は、GNU Make によって終了します。このデザイン例では、4 つの Alveo カード (U200、U250、U50、U280) がサポートされています。また、使用する Alveo カードに該当する行のコメント文字を解除して、各カードの ~/krnl_aes/Makefile を変更する必要があります。

 41 # PART setting: uncomment the line matching your Alveo card
 42 PART := xcu200-fsgd2104-2-e
 43 #PART := cu250-figd2104-2L-e
 44 #PART := xcu50-fsvh2104-2-e
 45 #PART := xcu280-fsvh2892-2L-e
 46
 47 # PLATFORM setting: uncomment the lin matching your Alveo card
 48 PLATFORM := xilinx_u200_xdma_201830_2
 49 #PLATFORM := xilinx_u250_xdma_201830_2
 50 #PLATFORM := xilinx_u50_gen3x16_xdma_201920_3
 51 #PLATFORM := xilinx_u280_xdma_201920_3

または、この変更をせずに、コマンド ライン オプションを使用してデフォルト設定を上書きすることもできます。次の手順では、例として U50 カードの make ツールを使用します。

make xxx PART=xcu50-fsvh2104-2-e PLATFORM=xilinx_u50_gen3x16_xdma_201920_3

開始する前に、XRT および Vitis インストール パスで設定スクリプトを読み込んでいることを確認してください。次に例を示します。

source /opt/xilinx/xrt/setup.sh
source /tools/Xilinx/Vitis/2020.2/settings64.sh

チュートリアルの手順

1.IP の生成

make gen_ip

これにより、Vivado がバッチ モードで起動し、~/krnl_aes/gen_ip.tcl が呼び出されて、必要なすべてのデザイン IP と Verification IP が生成されます。

2. スタンドアロン シミュレーションの実行

make runsim

これにより、~/krnl_aes/runsim_krnl_aes_xsim.sh が呼び出され、Vivado XSim でシミュレーションが実行されます。

3.Vivado IP のパッケージと Vitis カーネル ファイルの生成

make pack_kernel

これにより Vivado がバッチ モードで起動し、~/krnl_aes/pack_kernel.tcl が呼び出されて、RTL ソース、生成された IP XCI ファイル、および XDC ファイルが Vivado IP にパッケージされます。この後、Vitis カーネル ファイル ~/krnl_aes/krnl_aes.xo が生成されます。

4. カーネル テスト システムのオーバーレイ ファイルの構築

注記: xilinx_u200_xdma_201830_2xilinx_u250_xdma_201830_2、または xilinx_u280_xdma_201920_3 プラットフォームを使用している場合は、~/krnl_aes/krnl_aes_test.xdc の 2 行目、5 行目、または 8 行目のコメントを解除する必要があります。

  1 # if you are using xilinx_u200_xdma_201830_2 platform, please uncomment following line
  2 # set_property CLOCK_DEDICATED_ROUTE ANY_CMT_COLUMN [get_nets pfm_top_i/static_region/slr1/base_clocking/clkwiz_kernel/inst/CLK_CORE_DRP_I/clk_inst/clk_out1]
  3
  4 # if you are using xilinx_u250_xdma_201830_2 platform, please uncomment following line
  5 # set_property CLOCK_DEDICATED_ROUTE ANY_CMT_COLUMN [get_nets pfm_top_i/static_region/slr0/base_clocking/clkwiz_kernel2/inst/CLK_CORE_DRP_I/clk_inst/clk_out1]
  6
  7 # if you are using xilinx_u280_xdma_201920_3 platform, please uncomment following line
  8 #set_property CLOCK_DEDICATED_ROUTE ANY_CMT_COLUMN [get_nets pfm_top_i/static_region/base_clocking/clkwiz_kernel/inst/CLK_CORE_DRP_I/clk_inst/clk_out1]
ハードウェア ターゲットの場合

ハードウェア ターゲットの場合は、次のコマンドを使用します。

make build_hw

これにより、まず 2 つの HLS カーネルが XO ファイルにコンパイルされ、システム オーバーレイ ファイル全体 (~/krnl_aes/krnl_aes_test_hw.xclbin) が構築されます。

ハードウェア エミュレーション ターゲットの場合

ハードウェア エミュレーション ターゲットの場合は、次のコマンドを使用します。

make build_hw TARGET=hw_emu

これにより、まず 2 つの HLS カーネルが XO ファイルにコンパイルされ、システム オーバーレイ ファイル全体 (~/krnl_aes/krnl_aes_test_hw_emu.xclbin) が構築されます。

5. ホスト プログラムのコンパイル

make build_sw

これで、ホスト C++ プログラムのコンパイルは終了です。hwhw_emu モジュールの両方に対して実行可能ファイル (~/krnl_aes/host_krnl_aes_test) が生成されます。

ターゲット カードのデバイス ID の検出

ホスト マシンに複数の Alveo カードがインストールされている場合は、xbutil list コマンドを使用してターゲット カードのデバイス ID を見つけます。次に例を示します。

xbutil list
...
 [0] 0000:d8:00.1 xilinx_u250_gen3x16_base_3 user(inst=131)
 [1] 0000:af:00.1 xilinx_vck5000-es1_gen3x16_base_2 user(inst=130)
 [2] 0000:5e:00.1 xilinx_u50_gen3x16_xdma_201920_3 user(inst=129)

この例では、ターゲット カードが U50 の場合、デバイス ID は 2 です。~/krnl_aes/host/host_krnl_aes_test.cpp の 30 行目を次のように変更する必要があります。

 28 // Use 'xbutil list' command to get the device id of the target Alveo card if multiple
 29 //   cards are installed in the system.
 30 #define DEVICE_ID   2

6. ハードウェア エミュレーションの実行 (オプション)

ハードウェア エミュレーション用の XCLBIN ファイル (~/krnl_aes/krnl_aes_test_hw_emu.xclbin) が生成されると、ハードウェア エミュレーションを実行して、プラットフォーム環境でカーネルを検証し、デバッグや詳細なプロファイリングを実行できます。次のコマンドを参照してください。

source setup_emu.sh -s on -p PLATFORM_NAME
./host_krnl_aes_test -w 32

最初のコマンドは、スクリプトを呼び出してエミュレーション設定ファイルを生成し、必要な環境変数を設定します。PLATFORM_NAME は、使用している Alveo プラットフォームです。このプラットフォームは xilinx_u200_xdma_201830_2 (デフォルト)、xilinx_u250_xdma_201830_2、xilinx_u280_xdma_201920_3 または xilinx_u50_gen3x16_xdma_201920_3 のいずれかになります。

2 つ目のコマンドは、hw_emu モードでホスト プログラムを実行します。オプションのコマンド ライン パラメータの -w 32 は、処理する 128 ビット ワードの数を設定します。プログラムのソース コードのデフォルトのワード数は 1048576 (100 万) で、ハードウェア エミュレーションには大きすぎます。これを小さい値に設定すると、エミュレーションの実行時間を短縮できます。

~/krnl_aes/xrt.ini ファイルは、次のように XRT エミュレーション オプションを制御するために使用されます。2 行目の exclusive_cu_context=true は、下位レベルの kernel.write_register() 関数が使用される場合は必須です。6 行目の user_pre_sim_script=/home/workspace/bottom_up_rtl_kernel/krnl_aes/xsim.tcl は、XSim が使用するシミュレーション前 Tcl スクリプトへの絶対パスを設定することで、すべての信号の波形をダンプするように指定しています。

注記: 実際のパスに合わせてパスを変更してください。

  1 [Runtime]
  2 exclusive_cu_context=true
  3
  4 [Emulation]
  5 debug_mode=batch
  6 user_pre_sim_script=/home/workspace/bottom_up_rtl_kernel/krnl_aes/xsim.tcl
  7
  8 [Debug]
  9 profile=true
 10 timeline_trace=true
 11 data_transfer_trace=fine

ハードウェア エミュレーションの実行が完了したら、Vivado で生成された xilinx_xxx-0-krnl_aes_test_hw_emu.wdb ファイルを開いて波形を解析できます。次の図は、krnl_aes の 8 つの AXI ストリーム ポートの動作の波形を示しています。

krnl_aes の波形

次の図は、ap_ctrl_hs モードの AXI 制御スレーブの制御信号の動作を示しています。

ap_ctrl_hs の波形

7. ホスト プログラムのハードウェア モードでの実行

前の手順でハードウェア エミュレーションを試した場合は、次のコマンドを実行して hw_emu モードを無効にする必要があります。

source setup_emu.sh -s off

これで、コンパイルされた host_krnl_aes_test ファイルを実行して、ハードウェア モードでシステムをテストできます。処理するデフォルトのワード数は 1M の 128 ビット ワードなので、16 MB です。PCIe を介したホストと FPGA 間のデータ転送効率のため、十分な入力データで処理スループットを最大化できます。

./host_krnl_aes_test

------------------------ krnl_aes test program ------------------------
 128-bit words number : 1048576
           Key length : 256-bit
                  Key : 123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0

Generating plain data
[MESSAGE] Program running in hardware mode
Load krnl_aes_test_hw.xclbin
Create kernels
Create input and output device buffers
Run krnl_aes for AES key expansion
Kernel run finish

-------------- AES Encryption Test
Transfer plain data into device buffer
Start strm_issue and strm_dump kernels
Kernel run finish
AES engines execution time = 170.820007 ms
Transfer cipher data from device buffer and verification
-- AES Engine 0
   SUCCESS
-- AES Engine 1
   SUCCESS
-- AES Engine 2
   SUCCESS
-- AES Engine 3
   SUCCESS
AES total encryption throughput = 392.857971 MB/s

-------------- AES Decryption Test
Transfer cipher data into device buffer
Start strm_issue and strm_dump kernels
Kernel run finish
AES engines execution time = 170.800995 ms
Transfer plain data from device buffer and verification
-- AES Engine 0
   SUCCESS
-- AES Engine 1
   SUCCESS
-- AES Engine 2
   SUCCESS
-- AES Engine 3
   SUCCESS
AES total decryption throughput = 392.901703 MB/s

これで、Vitis の RTL カーネル ファイルの krnl_aes.xoap_ctrl_hs 実行モデルが作成されました。次のセッションでは、ap_ctrl_chain モデルをサポートするもう 1 つの RTL カーネル、krnl_cbc について学び、これら 2 つのカーネルをハードウェア オーバーレイ (XCLBIN) に統合して、完全な AES-CBC アクセラレーション アプリケーションを形成します。詳細は、次のセクションの「RTL カーネル: krnl_cbc」で説明します。