Vitis HLS 学习笔记--global_array_RAM初始化
目录
1. 简介
2. 代码分析
3. 对比两种 solution
3.1 solution_A
3.2 solution_B
4. 总结
1. 简介
这个例子展示了如何将全局数组映射到具有不同实现的RAM,并展示了它们如何初始化以及如何重置。
2. 代码分析
#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 test(int i) {
#pragma HLS BIND_STORAGE variable = A type = RAM_2P impl = BRAM
#pragma HLS BIND_STORAGE variable = B type = RAM_2P impl = LUTRAM// URAM is not a supported implementation type for global arrays// #pragma HLS BIND_STORAGE variable=C type=RAM_2P impl=URAMA[i] += B[i] + C[i];B[i] += 5;C[i] += 10;int result = (A[i] + B[i] + C[i]).to_int();return result;
}
代码功能解释:
- 三个数组: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] 的和,并将其转换为整数类型,然后返回该结果。
TestBench 代码:
extern int test(int i);int main() {int j = 5;int ret = test(j);int golden = 36;int result = 0;if (ret == golden) {printf("Test passed!\n");} else {printf("Test failed!\n");result = 1;}return result;
}
3. 对比两种 solution
3.1 solution_A
需要注意的事项:
[A] 在solution_A中,可以看到对于BRAM/LUTRAM,以下结构在RTL中生成以初始化全局RAM数组(不支持URAM):
proj/solution_A/syn/verilog/test_A_V_RAM_2P_BRAM_1R1W.v:
initial begin$readmemh("./test_A_V_RAM_2P_BRAM_1R1W.dat", ram);
endproj/solution_A/syn/verilog/test_B_V_RAM_2P_LUTRAM_1R1W.v:
initial begin$readmemh("./test_B_V_RAM_2P_LUTRAM_1R1W.dat", ram);
end*.dat文件包含相应数组的初始值。还请注意,全局数组不会导出到接口。
警告:[RTGEN 206-101] 全局数组'B_V'不会作为RTL端口公开。
警告:[RTGEN 206-101] 全局数组'A_V'不会作为RTL端口公开。
3.2 solution_B
[B] 在solution_B中,可以看到当对BRAM/LUTRAM应用重置时生成的结构。
当将重置指令/编译器指示应用于静态数组(A/B/C)时,将在生成的RTL中看到每个存储器使用ROM和RAM来实现。 初始值仅加载到ROM中(与solution_A相同)。 但每次在断言重置信号后,如果没有写入地址,则从地址读取的值来自ROM,否则将从RAM中读取。 这意味着在每次重置后,内存都会重置回初始化值。 三个数组A/B/C的相同结构如下所示。
proj/solution_B/syn/verilog/test_A_V_RAM_2P_BRAM_1R1W.v://------------------------实例化------------------
test_A_V_RAM_2P_BRAM_1R1W_ram #(.DataWidth (DataWidth ),.AddressWidth (AddressWidth ),.AddressRange (AddressRange ))
test_A_V_RAM_2P_BRAM_1R1W_ram_u(.address0 ( address0 ),.ce0 ( ce0 ),.q0 ( q0_ram ),.address1 ( address1 ), .ce1 ( ce1 ),.we1 ( we1 ),.d1 ( d1 ),.clk ( clk ),.reset ( reset ));test_A_V_RAM_2P_BRAM_1R1W_rom #(.DataWidth ( DataWidth ),.AddressWidth ( AddressWidth ),.AddressRange ( AddressRange ))test_A_V_RAM_2P_BRAM_1R1W_rom_u(.ce0 ( ce0 ),.address0 ( address0 ),.q0 ( q0_rom ),.clk ( clk ),.reset ( reset ));//------------------------主体---------------------------assign q0 = q0_sel? q0_ram : q0_rom;
4. 总结
该例子展示了如何在HLS中将全局数组映射到不同的RAM实现,并探讨了它们的初始化和重置机制。在代码中,三个数组A、B和C分别映射到BRAM和LUTRAM,并进行了不同的数组操作。Solution_A展示了如何通过初始数据文件将全局数组初始化到RAM中,而Solution_B展示了应用重置指令后的RAM结构,其特点是在每次重置后,内存会恢复到初始化值。Solution_A生成的RTL中,数组初始化由文件加载,并且全局数组不会导出为接口端口;而在Solution_B中,重置指令导致生成ROM和RAM组合的结构,确保在断言重置信号后内存恢复到初始状态。这种机制有助于在硬件实现中保证数据的一致性和稳定性。