聚合示例 - 2021.2 Chinese

Vitis 高层次综合用户指南 (UG1399)

Document ID
UG1399
Release Date
2021-12-15
Version
2021.2 Chinese

聚合存储器映射接口

这是 m_axi 接口的 AGGREGATE 编译指示或指令的示例。您可通过 Vitis HLS 简介示例获取该示例。

struct A {                                         
  char foo;     // 1 byte                              
  short bar;    // 2 bytes                             
};                             
 
int dut(A* arr) {
#pragma HLS interface m_axi port=arr depth=10
#pragma HLS aggregate variable=arr compact=auto
  int sum = 0;
  for (unsigned i=0; i<10; i++) {
    auto tmp = arr[i];
    sum += tmp.foo + tmp.bar;
  }
  return sum;
}

对于以上示例,m_axi 接口端口 arr 的大小为 3 个字节(或 24 位),但由于 AGGREGATE compact=auto 编译指示的作用,该端口的大小将对齐到 4 个字节(或 32 位),因为这是最接近的 2 的幂值。Vitis HLS 将在 log 日志文件中发出以下消息:

INFO: [HLS 214-241] Aggregating maxi variable 'arr' with compact=none mode in 32-bits (example.cpp:19:0)
提示: 仅当使用 AGGREGATE 编译指示时,才会发出以上消息。但即使不使用编译指示,该工具仍将自动聚合接口端口 arr 并将其填充至 4 个字节,这是 AXI 接口端口的默认行为。

在接口上聚合结构体

这是 ap_fifo 接口的 AGGREGATE 编译指示或指令的示例。您可通过 Vitis HLS 简介示例获取该示例。

struct A {
  int myArr[3];      // 4 bytes per element (12 bytes total)
  ap_int<23> length; // 23 bits 
};
 
int dut(A arr[N]) {
#pragma HLS interface ap_fifo port=arr
#pragma HLS aggregate variable=arr compact=auto
  int sum = 0;
  for (unsigned i=0; i<10; i++) {
    auto tmp = arr[i];
    sum += tmp.myArr[0] + tmp.myArr[1] + tmp.myArr[2] + tmp.length;
  }
  return sum;
}

对于 ap_fifo 接口,无论是否使用聚合编译指示,结构体都将在位级进行封装。

在以上示例中,AGGREGATE 编译指示将为端口 arr 创建大小为 119 位的端口。阵列 myArr 将取 12 个字节(或 96 位),元素 length 将取 23 位,总计 119 位。Vitis HLS 将在 log 日志文件中发出以下消息:

INFO: [HLS 214-241] Aggregating fifo (array-to-stream) variable 'arr' with compact=bit mode
        in 119-bits (example.cpp:19:0)

聚合嵌套结构体端口

这是 Vivado IP 流程中 AGGREGATE 编译指示或指令的示例。您可通过 Vitis HLS 简介示例获取该示例。

#define N 8
 
struct T {
   int m;   // 4 bytes
   int n;   // 4 bytes
   bool o;  // 1 byte
};
 
struct S {
   int p;   // 4 bytes
   T q;     // 9 bytes
};
  void top(S a[N], S b[N], S c[N]) {
#pragma HLS interface bram port=c
#pragma HLS interface ap_memory port=a
#pragma HLS aggregate variable=a compact=byte
#pragma HLS aggregate variable=b compact=bit
#pragma HLS aggregate variable=c compact=byte
    for (int i=0; i<N; i++) {
        c[i].q.m = a[i].q.m + b[i].q.m;
        c[i].q.n = a[i].q.n - b[i].q.n;
        c[i].q.o = a[i].q.o || b[i].q.o; 
        c[i].p = a[i].q.n;        
    }
}

在以上示例中,聚合算法将为端口 a 和端口 c 创建大小为 104 位的端口,因为在聚合编译指示中已指定 compact=byte 选项,但针对端口 b 使用默认选项 compact=bit,其打包大小将为 97 位。嵌套的结构 ST 将聚合以包含 3 个 32 位成员变量(p、m 和 n)以及 1 个位/字节成员变量 (o)。

提示: 此示例使用 Vivado IP 流程来演示聚合行为。在 Vitis 内核流程中,端口 b 将自动推断为 m_axi 端口,故而将不允许使用 compact=bit 设置。
Vitis HLS 将在 log 日志文件中发出以下消息:
INFO: [HLS 214-241] Aggregating bram variable 'b' with compact=bit mode in 97-bits (example.cpp:19:0)
INFO: [HLS 214-241] Aggregating bram variable 'a' with compact=byte mode in 104-bits (example.cpp:19:0)
INFO: [HLS 214-241] Aggregating bram variable 'c' with compact=byte mode in 104-bits (example.cpp:19:0)