目录
1. 简介
在C++程序中,数组是一种基本的数据结构,用来存储一系列的数据。程序员可以动态地分配和释放数组的内存空间。
但是在将程序综合到硬件上时,就不能再动态地分配内存了,因为硬件需要提前知道需要多少内存来存储数组的数据。在FPGA上,有一个本地存储器,相比于全局存储器(比如DDR或HBM存储器),本地存储器的访问速度更快,通常只需要一个或多个周期。
本文例子展示了如何将全局数组映射到具有不同实现的RAM,并展示了它们如何初始化以及如何重置。
2. 示例代分析
2.1 源代码
#include <ap_int.h>
ap_int<10> A[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
ap_int<10> B[10] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
ap_int<10> C[10] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
int example(int i) {
#pragma HLS BIND_STORAGE variable = A type = RAM_2P impl = BRAM
#pragma HLS BIND_STORAGE variable = B type = RAM_2P impl = LUTRAM
A[i] += B[i] + C[i];
B[i] += 5;
C[i] += 10;
int result = (A[i] + B[i] + C[i]).to_int();
return result;
}
2.2 URAM 不可用
// #pragma HLS BIND_STORAGE variable=C type=RAM_2P impl=URAM
该指令不可用!
有用户提出了类似的问题,发现即使使用了 #pragma HLS BIND_STORAGE 指令指定将数组存储到 URAM 中,综合报告显示每个 URAM 单元只存储了一个数组元素,而没有充分利用 URAM 的容量。解决方法是在代码中手动对数据进行打包,将多个较小位宽的数打包成一个更大位宽的数后存入 URAM。
这表明,虽然 URAM 可以通过手动优化来使用,但 Vitis HLS 可能没有直接支持全局数组使用 URAM 的内置机制。
2.3 代码功能解释
首先定义三个数组:A、B 和 C,每个数组都包含了 10 个 ap_int<10> 类型的元素。这些数组在 HLS 中被绑定到不同的存储实现类型上。
#pragma HLS BIND_STORAGE 是用于指定存储实现类型的指令。在这里,我们有两个绑定:
- A 使用 BRAM(Block RAM)作为存储实现类型。
- B 使用 LUTRAM(Look-Up Table RAM)作为存储实现类型。
然后,对这些数组进行了一系列操作:
- A[i] += B[i] + C[i]:将 B[i] 和 C[i] 的值相加,并将结果加到 A[i] 上。
- B[i] += 5:将 B[i] 的值增加 5。
- C[i] += 10:将 C[i] 的值增加 10。
- 最后,计算了 A[i] + B[i] + C[i] 的和,并将其转换为整数类型,然后返回该结果。
2.4 综合报告
2.4.1 顶层控制接口
包含:块级控制协议、时钟、复位、中断;