概述
本节旨在描述如何使用 AXI Traffic Generator 在所有仿真模式下对 AI 引擎阵列提供输入并从中捕获输出。在 AI 引擎仿真器中,输入数据激励是使用 PLIO 对象提供的,此对象用于指定包含数据的文本文件:
input_plio plin = input_plio::create("DataIn", adf::plio_32_bits, "data/input.txt");
虽然这样可使您的首次仿真快速就位,但此方法的主要限制在于,如果您要更改输入文件名用于其他仿真,就必须重新编译整个应用。因此可通过如下方法来避免文件名规范并依靠外部流量生成器在 PLIO 上生成数据流量:
input_plio plin = input_plio::create("DataIn", adf::plio_32_bits);
对于软硬件仿真,存在一项等效的功能特性可用于对此 PLIO 和 AXI4‑Stream 接口的行为进行仿真。为此提供了 Python 和 C++ API 用于创建外部流量生成器,这些流量生成器将在任意仿真模式下无缝连接。
AI 引擎阵列的主要外部数据接口是 AXI4‑Stream 接口。这些接口称为 PLIO,允许 AI 引擎检索数据、对数据进行操作并通过独立 AXI4‑Stream 接口发回数据。AI 引擎的输入接口是 AXI4‑Stream 使用者接口,输出则是 AXI4‑Stream 生产者接口。为了在软硬件仿真期间与这些顶层接口进行交互,另外提供了补充性的 AXI4‑Stream 模块。这些补充性模块称为 AXI Traffic Generator。
开发 AI 引擎应用时,您可在仿真中单独对其进行测试(x86simulator
、aiesimulator
),或者在仿真中将其作为系统工程的一部分来进行测试(sw_emu
和 hw_emu
)。无论如何,您都需要从预定义的参考文件发送输入数据,并在独立文件中捕获输出数据。此外,如果您的 AI 引擎计算图与位于可编程逻辑(HLS C++ 或 RTL)中的内核交错,那么您还需要处理这些数据流中断。例如,完整的系统设计可能如下图所示:
为了提升数据生成和验证的灵活性,您可以将文本文件与外部流量生成器进行交换,以便在 PL 与 AI 引擎阵列之间通过连接到 UNIX 套接字的 AXI4‑Stream TLM 来启用动态仿真的通信。这些外部流量生成器的优势在于,它们无需修改即可直接在所有仿真框架内使用:
- x86 仿真
- AI 引擎仿真
- 软件仿真
- 硬件仿真
整体仿真框架如下图所示:
每个 AI 引擎块均可使用以 Python、MATLAB 或 C++ 编写的外部测试激励文件来确认。在 GitHub 上的 External-Traffic-Generator-AIE 教程中可找到实现示例。
对于系统工程,通过整合 AI 引擎计算图应用与 PL 内核,将数据移动程序替换为外部流量生成器源端和宿端,而 PL 处理内核则是连接到 AI 引擎内核的串流内核,如下图所示。
流量生成器也用于将数据馈送并刷新到含 PL 逻辑的完整系统中。您无需对用于将数据写入 DDR 存储器的 PS 代码进行建模,也无需对移入 AI 引擎内核的数据进行建模。此方法会将数据移动程序替换为动态生成数据的外部流量生成器。以下章节逐步描述了将外部流量生成器与 AI 引擎系统对接以执行仿真流程所需的更改。
AI 引擎计算图修改
在计算图中无需进行任何有关内核连接的更改。只需将流量生成器定义为来自 PLIO 端口的数据源即可,如下所示。以下示例基于 AI 引擎内核与计算图编程指南(UG1079) 的使用 RTL 编程逻辑的设计流程中的代码。
plin = input_plio::create("DataIn1",adf::plio_32_bits);
clip_in = output_plio::create("clip_in",adf::plio_32_bits);
clip_out = input_plio::create("clip_out",adf::plio_32_bits);
plout = output_plio::create("DataOut1",adf::plio_32_bits);
输入/输出 plio 声明的第一个参数的重要性在于,它所表示的名称将在流量生成器一侧用于连接到正确的套接字。
x86 仿真和 AI 引擎仿真可启动并搭配流量生成器来工作。启动仿真需与外部流量生成器并行运行 aiesimulator
或 x86simulator
。
PL 内核更改
考量 AI 引擎应用及其适用于系统仿真模式(sw
和 hw
)的环境时,需要对往来可编程逻辑一侧的数据传输进行建模。开始开发时,内核尚未准备就绪,无法在 sw_emu
或 hw_emu
框架内使用,因此无法创建赛灵思对象 (.xo
) 文件以供在 Vitis 链接阶段中使用。您必须在可编程逻辑内引入挂钩,以便将外部流量生成器连接到这些挂钩。 提供了一整套预编译的 .xo
文件,可用于满足此目的:
-
$(XILINX_VITIS)/data/emulation/XO/sim_ipc_axis_slave_32.xo, $(XILINX_VITIS)/data/emulation/XO/sim_ipc_axis_master_32.xo
-
$(XILINX_VITIS)/data/emulation/XO/sim_ipc_axis_slave_64.xo, $(XILINX_VITIS)/data/emulation/XO/sim_ipc_axis_master_64.xo
-
$(XILINX_VITIS)/data/emulation/XO/sim_ipc_axis_slave_128.xo, $(XILINX_VITIS)/data/emulation/XO/sim_ipc_axis_master_128.xo
您应将一组正确的 .xo
文件复制到工程上的正确位置,以便在 Vitis 链接阶段内,将其用于您的配置文件中。
准备连接以链接流量生成器
在 Vitis 链接阶段 (v++ -l
),先前定义的 .xo
文件将用于把相关计算单元连接到 AI 引擎计算图。hw_link.cfg 配置文件的创建方式可保证计算单元的名称与您在计算图中为 input_plio
和 output_plio
定义的名称相匹配。例如,以下代码与上述示例中的 PLIO 分配相匹配:
[connectivity]
nk=sim_ipc_axis_master_32:1:in_interpolator
nk=sim_ipc_axis_slave_32:1:out_classifier
nk=polar_clip:1:polar_clip
sc=in_interpolator.M00_AXIS:ai_engine_0.in_interpolator
sc=ai_engine_0.out_interpolator:polar_clip.in_sample
sc=polar_clip.out_sample:ai_engine_0.in_classifier
sc=ai_engine_0.out_classifier:out_classifier.S00_AXIS
--connectivity.nk
命令格式为内核名称(如 sim_ipc_axis_master_32
)、要创建的内核实例数或计算单元数 (1) 以及每个内核实例的名称 (in_interpolator
)。如需了解有关此命令的更多信息,请参阅 --connectivity 选项。
--connectivity.sc
命令用于定义 PL 内核之间或者 PL 内核与 AI 引擎计算图之间的串流连接。在以上示例中,流量生成器 in_interpolator.M00_AXIS
的输出端口连接到 ai_engine_0.in_interpolator
的输入端口。
凭借此命名方法,即可确保对多轮仿真使用相同的外部流量生成器。对于软件仿真 (sw_emu
) 和硬件仿真 (hw_emu
),如果您熟悉 RTL 编码,即可采用 C++、Python、MATLAB 或 HDL 来编写外部流量生成器。
主机代码
主机代码的创建十分简单。由于其中并没有可编程逻辑内核,因此查找和运行 PL 内核的所有阶段以及为所有缓冲器对象分配存储器的部分都可跳过。剩余阶段仅包括:
- 打开器件
- 加载
xclbin
文件 - 寄存 XRT 以连接到设计
- 运行 AI 引擎计算图
编译主机代码后,即可对整个工程进行封装。运行仿真包括并行运行外部流量生成器和标准仿真启动。