Xilinx FPGA AI开发工具 AIE(3)—理解AIE编程中的Kernel-Xilinx-AMD社区-FPGA CPLD-ChipDebug

Xilinx FPGA AI开发工具 AIE(3)—理解AIE编程中的Kernel

在上一篇文章中我们介绍了AIE中的graphgraph通常在一个.h文件中描述,可认为是AIE应用工程的顶层文件,位置仅次于仿真文件,我们也看到了graph里是实例化Kernel并通过构造函数connectkernelgraph的输入/输出端口连接起来,如下图所示。本篇文章我们将重点介绍Kernel,也就是图中的firstsecond
图片[1]-Xilinx FPGA AI开发工具 AIE(3)—理解AIE编程中的Kernel-Xilinx-AMD社区-FPGA CPLD-ChipDebug
通常采用C++描述Kernel,也会用到一些专用的Intrinsics。这些Intrinsics并不神秘,它们仍然是一些预定义的函数,只是针对超长指令字(VLIWVery long instruction word)向量处理器。aiecompiler负责对Kernel进行编译。该编译器集成于Vitis中,无需单独下载。aiecompilerKernel编译后会生成ELF文件。需用注意的是多个Kernel可运行在同一个AIE上,但是一个Kernel不能运行在多个AIE上,这就要求设计者对函数进行合理的分割,以保证每个Kernel至多仅占用一个AIE
 
我们来看这个Kernel函数,如下图所示。首先kernels.cc位于src/kernels目录下。代码第3行与graph一样要声明头文件adf.h。代码第4行的头文件include.h是因为其中包含了参数NUM_SAMPLES,代码第8行会用到,其值为32。代码第6行定义函数simple。该函数无返回值(返回void),AIE要求所有的Kernel都是void

 

图片[2]-Xilinx FPGA AI开发工具 AIE(3)—理解AIE编程中的Kernel-Xilinx-AMD社区-FPGA CPLD-ChipDebug

之后,我们可以看到Kernel定义了2个参数。第一个参数为输入参数,数据类型为cint16,接口为window,这意味着每个采样数据为32位(复数:实部和虚部均为16位)。第二个参数为输出参数,数据类型也是cint16,接口为window,同样数据位宽为32位(实部和虚部均为16位)。
 
代码第8行至第13行是一个for循环。每次循环会消耗一个16位的复数。这个复数是从window中读取并赋给变量c1(代码第9行)。运算结束后,生成一个复数c2,再将其写入window(代码第12行)。计算过程也比较简单:c2的实部是c1的实部和虚部之和,c2的虚部是c1的实部与虚部之差。
 
需用注意的是这个Kernel在描述时并没有用到Intrinsics,所以最终运行在AIE的标量单元上,没有充分发挥AIE的向量处理的并行能力。
 
这里一共要循环32次,每次消耗一个16位复数也就是32位数据,因此,Kernel需用的输入window大小为32*32/8=128Bytes,这正是graphconnect128的来历,如下图所示。

 

图片[3]-Xilinx FPGA AI开发工具 AIE(3)—理解AIE编程中的Kernel-Xilinx-AMD社区-FPGA CPLD-ChipDebug
数据访问机制
 
在这个案例中,Kernel访问数据是通过window方式。另一种方式为stream
 
基于window的数据访问方式意味着Kernel直接从当前AIE的本地Memory32KB)或与之相邻的AIE的本地Memory读取数据。只有当window写满时,Kernel才会将数据加载到AIE中。这意味着在第一次调用Kernel时会有一些延迟,因为填满window需用一定的时间。但是,由于采用的是乒乓缓冲,当Kernel在运行的过程中,下一套数据就可以写入Memory,这样当再次调用Kernel时,数据已准备就绪了。
 
基于stream的数据访问方式意味着Kernel直接从AIX-Stream接口读取数据。在这种情况下,Kernel按采样方式读取数据。采用stream方式可能会造成上游Kernel反压。这是因为下游Kernel处理数据还不够快。也可能会造成下游Kernal停滞,这是因为上游Kernel不能更快的提供数据。
请登录后发表评论