1 前言
在前面的文章中ZCU106 XRT環境搭建【Xilinx Vitis】,已經生成了用於在Vitis的相關環境。
Xilinx在GitHub分享了一個Vitis的應用程序加速開發的教程:2019.2 Vitis™ Application Acceleration Development Flow Tutorials
後面基於我會基於ZCU106 XRT環境以及這個教程做一些測試。
Xilinx相關的官方文檔:
https://www.xilinx.com/html_docs/xilinx2019_2/vitis_doc/kme1569523964461.html
https://www.xilinx.com/html_docs/xilinx2019_2/vitis_doc/hly1569525384514.html
pdf版本:
Vitis Unified Software Platform Documentation Application Acceleration Development
Vitis Unified Software Platform Documentation Embedded Software Development
Vitis ZCU106 Platform
ZCU106 Vitis Platform
pre-built,直接下載並複製到SD卡即可測試:
ZCU106 Test Image
2 創建Vitis工程
Tutorials中的第一個例子:Getting Started with RTL Kernels
我其實都是按照例子中的章節,並使用我生成的VCU106 XRT平臺來進行測試的。
下面我僅針對需要注意的地方進行描述,相同的步驟參考文檔即可。
2.1 Create an Vitis IDE Project
目的:
- 用於創建一個Vitis工程。
區別:
- platform需要選擇之前生成的zcu106vcu_base
2.2 Configuration with the RTL Kernel Wizard
目的:
- 通過Vivado的RTL Kernel Wizard生成一個自定義RTL Kernel Template
區別:
- 無
2.2.1 RTL Kernel說明
RTL Kernel的相關信息可以查看ug1393的Chapter 8。
Vitis的軟件加速實現跟Vivado HLS是比較相關的,所以看文檔可以發現設計RTL Kernel時寄存器的設計和HLS內的s_axi非常類似。
在該例子中,除了基本的0x00~0x0C寄存器外,只有一個scalar的輸入參數。
2.3 Vivado Design Suite — RTL Design
目的:
- 使用GitHub倉庫內的RTL代碼替換掉默認的RTL代碼
- 進行RTL仿真驗證
- 對RTL進行打包,生成RTL Kernel文件。名稱:Vadd_A_B.xo
區別:
- 無
2.3.1 功能說明
該例子中RTL的功能是實現**B[i] = A[i]+B[i]**硬件加速操作。A和B通過AXI_MASTER接口讀出數據,進行計算後再將計算結果寫入到B的地址空間內。
該例子中有對應的testbentch,裏面使用VIP訪問AXI_SLAVE寄存器實現功能仿真。可以自己仿真看下效果。
2.3.2 打包xo
步驟2.2中的Vivado RTL Kernel Wizard是通過Vitis打開的,在步驟2.3完成打包後將會自動將Vadd_A_B.xo添加到Vitis工程中去。如下圖:
xo是一個壓縮文件,解壓後可以看到文件目錄結構:
.
├── ip_repo
│ └── mycompany_com_kernel_Vadd_A_B_1_0
│ ├── component.xml
│ ├── src
│ │ ├── A_axi_read_master.sv
│ │ ├── B_axi_read_master.sv
│ │ ├── control_Vadd_A_B_vip
│ │ │ └── control_Vadd_A_B_vip.xci
│ │ ├── slv_m00_axi_vip
│ │ │ └── slv_m00_axi_vip.xci
│ │ ├── slv_m01_axi_vip
│ │ │ └── slv_m01_axi_vip.xci
│ │ ├── Vadd_A_B_control_s_axi.v
│ │ ├── Vadd_A_B_example_adder.v
│ │ ├── Vadd_A_B_example_axi_write_master.sv
│ │ ├── Vadd_A_B_example_counter.sv
│ │ ├── Vadd_A_B_example.sv
│ │ ├── Vadd_A_B_example_vadd.sv
│ │ ├── Vadd_A_B_ooc.xdc
│ │ ├── Vadd_A_B_tb.sv
│ │ ├── Vadd_A_B_user.xdc
│ │ ├── Vadd_A_B.v
│ │ └── Vadd_B.sv
│ └── xgui
│ └── Vadd_A_B_v1_0.tcl
├── Vadd_A_B
│ └── kernel.xml
└── xo.xml
可以看出其實就是相當於打包了一個RTL IP,然後加了一個kernel.xml和xo.xml,至於具體的功能我還沒研究。
2.4 Using the RTL Kernel in a Vitis IDE Project
目的:
- 使用GitHub例子中的host.cpp代碼替換到自動生成的host_example.cpp中
區別:
- GitHub的例子中使用了仿真代碼方式,而我這裏實際上板進行了實測
2.4.1 代碼框架
在該章節中還介紹了host.cpp代碼中的實現流程,代碼是基於OpenCL的。
最重要的代碼如下,用於實際調用RTL相關功能,實現硬件加速。
clEnqueueTask(command_queue, kernel, 0, NULL, NULL);
2.4.2 編譯和測試
例子中只進行了仿真,我這裏就不需要了
3 編譯
前面提到了我這裏使用了硬件實測,如下圖:
3.1 注意事項
3.1.1 Compute Units
可以看到Vadd_A_B即是我們將要在實現的硬件加速核,他被囊括在binary_container_1中。
在我測試中理解到,Kernel(Vadd_A_B)即是加速實體,要被放到Container(binary_container_1)中。而且可以在配置時實現多組Kernel的例化,這樣該就實現了並行加速的功能吧,以後得試試。例化個數的配置如下圖:
3.1.2 Kernel Clock Frequency
在文章ZCU106 XRT Vivado工程分析【Xilinx Vitis】中介紹到,Vivado內部的MMCM實現了多個時鐘配置,根據Kernel的需要我們可以在Container中進行配置。
需要在V++ linker options中進行配置,如下所示:
--clock.freqHz 100000000:Vadd_A_B_1
3.2 編譯
右鍵點擊Hardware,然後選擇Build即可開始編譯。
編譯過程我也沒細細研究,可以雙擊Link Summar查看編譯過程。Xilinx的一個新工具Vitis Analyzer可以查看編譯中的各種詳細的log,簡要的log可以在Vitis的Console中查看。
打開Vivado可以查看RTL Kernel Vadd_A_B_1被添加到了工程當中。1個AXI_S,2個AXI_M,1箇中斷信號連接到了axi_intc_0。並且該IP被連接到了之前按設定的100MHz時鐘上。
3.3 SD Card Image
編譯完成後Vitis會將將生成的固件放到Hardware/sd_card目錄下。
.
├── binary_container_1.xclbin - Vitis生成的包含Kernel的固件
├── BOOT.BIN - Vitis打包好的啓動文件
├── image.ub - zcu106vcu_base自帶的鏡像文件
├── init.sh - zcu106vcu_base自帶的腳本
├── platform_desc.txt - zcu106vcu_base自帶的描述文件
├── README.txt - Vitis生成的說明文件
└── rtl_ke_t2.exe - Vitis生成的可執行程序
- BOOT.BIN 包含了XRT平臺的fsbl、u-boot,以及Vitis集成RTL Kernel後生成FPGA bit文件
將以上所有文件複製到SD卡,並將MPSOC啓動方式切換未SD卡啓動即可進行工能測試。
現在有一個疑問就是xclbin中的bit文件和BOOT.bin內的bit文件不知道有什麼區別,後面需要研究一下。
4 上板測試
等待板子啓動後執行命令進行測試:
root@zcu106vcu_base:~# /mnt/rtl_ke_t2.exe /mnt/binary_container_1.xclbin zcu106vcu_base
[ 60.743975] [drm] Pid 2553 opened device
[ 60.747958] [drm] Pid 2553 closed device
[ 60.752080] [drm] Pid 2553 opened device
INFO: Found 1 platforms
INFO: Selected platform 0 from Xilinx
INFO: Found 1 devices
CL_DEVICE_NAME zcu106vcu_base
Selected zcu106vcu_base as the target device
INFO: loading xclbin /mnt/binary_container_1.xclbin
[ 61.677061] [drm] Finding IP_LAYOUT section header
[ 61.677068] [drm] Section IP_LAYOUT details:
[ 61.681880] [drm] offset = 0x126ad88
[ 61.686148] [drm] size = 0x58
[ 61.689905] [drm] Finding DEBUG_IP_LAYOUT section header
[ 61.693045] [drm] AXLF section DEBUG_IP_LAYOUT header not found
[ 61.698357] [drm] Finding CONNECTIVITY section header
[ 61.704274] [drm] Section CONNECTIVITY details:
[ 61.709318] [drm] offset = 0x126ade0
[ 61.713838] [drm] size = 0x1c
[ 61.717584] [drm] Finding MEM_TOPOLOGY section header
[ 61.720721] [drm] Section MEM_TOPOLOGY details:
[ 61.725766] [drm] offset = 0x126ad58
[ 61.730287] [drm] size = 0x30
[ 61.734998] [drm] No ERT scheduler on MPSoC, using KDS
[ 61.743589] [drm] scheduler config ert(0)
[ 61.743591] [drm] cus(1)
[ 61.747597] [drm] slots(16)
[ 61.750288] [drm] num_cu_masks(1)
[ 61.753255] [drm] cu_shift(16)
[ 61.756744] [drm] cu_base(0x80000000)
INFO: Test completed successfully.
[ 61.759965] [drm] polling(0)
[ 61.778833] [drm] Pid 2553 closed device
root@zcu106vcu_base:~#
root@zcu106vcu_base:~# /mnt/rtl_ke_t2.exe /mnt/binary_container_1.xclbin zcu106vcu_base
[ 88.192855] [drm] Pid 2626 opened device
[ 88.196811] [drm] Pid 2626 closed device
[ 88.200895] [drm] Pid 2626 opened device
INFO: Found 1 platforms
INFO: Selected platform 0 from Xilinx
INFO: Found 1 devices
CL_DEVICE_NAME zcu106vcu_base
Selected zcu106vcu_base as the target device
INFO: loading xclbin /mnt/binary_container_1.xclbin
[ 88.298956] [drm] The XCLBIN already loaded. Don't need to reload.
[ 88.300055] [drm] Reconfiguration not supported
INFO: Test completed successfully.
[ 88.325898] [drm] Pid 2626 closed device
root@zcu106vcu_base:~#
- 第一次運行時調用了drm的相關驅動,加載了xclbin,然後運行了硬件加速程序,測試通過。
- 第二次運行時因爲已經加載過xclbin,所以直接運行了硬件加速程序,測試通過。
- 實際的提速效果我這沒有測試,但根據經驗來說,數據循環次數越多,硬件加速的效果就會越明顯,外部調用接口所消耗的時間比重也會越低。
5 總結
使用Vitis和自定義的ZCU106 XRT平臺完成了Vitis-Tutorials中的RTL Kernel基本功能測試。
待補充。