Intel®高层次综合编译器专业版: 最佳实践指南

ID 683152
日期 6/22/2020
Public

本文档可提供新的版本。客户应 单击此处 前往查看最新版本。

文档目录

6.4. 实例:指定局部存储器地址的Bank选择位

有选项可告知 Intel® HLS Compiler Pro Edition从局部存储器中哪些位选择存储bank或从哪些位可选择bank中的字。可通过hls_bankbits(b 0, b 1, ..., b n) 属性指定“bank选择”位。

(b 0 , b 1 , ... ,b n )自变量指的是局部存储器地址位的位置, Intel® HLS Compiler Pro Edition将他们用作“bank选择”位。指定hls_bankbits(b 0, b 1 , ..., b n) 属性表示bank数目等于2 bank位号

表 8.  局部存储器地址实例显示字和“Bank选择”位

本局部存储器地址表显示局部存储器可能会如何选址的实例。存储器属性设置为hls_bankbits(3,4)。存储器bank选择位(bits 3, 4)在表格中为粗体字,而字选择位(bits 0-2)为斜体字。

  Bank 0 Bank 1 Bank 2 Bank 3
Word 0 00 000 01 000 10 000 11 000
Word 1 00 001 01 001 10 001 11 001
Word 2 00 010 01 010 10 010 11 010
Word 3 00 011 01 011 10 011 11 011
Word 4 00 100 01 100 10 100 11 100
Word 5 00 101 01 101 10 101 11 101
Word 6 00 110 01 110 10 110 11 110
Word 7 00 111 01 111 10 111 11 111
限制: 目前,hls_bankbits(b 0b 1, ..., b n)属性仅支持连续bank位。

实现hls_bankbits属性的实例

考虑以下实例组件代码:
1
component int bank_arbitration (int
                      raddr, int waddr, int wdata) { #define DIM_SIZE 4 // Adjust memory geometry by
                      preventing coalescing hls_numbanks(1) hls_bankwidth(sizeof(int)*DIM_SIZE) //
                      Force each memory bank to have 2 ports for read/write hls_singlepump
                      hls_max_replicates(1) int a[DIM_SIZE][DIM_SIZE][DIM_SIZE]; // initialize array
                      a… int result = 0; #pragma unroll for (int dim1 = 0; dim1 < DIM_SIZE;
                      dim1++) #pragma unroll for (int dim3 = 0; dim3 < DIM_SIZE; dim3++)
                      a[dim1][waddr&(DIM_SIZE-1)][dim3] = wdata; #pragma unroll for (int dim1 =
                      0; dim1 < DIM_SIZE; dim1++) #pragma unroll for (int dim3 = 0; dim3 <
                      DIM_SIZE; dim3++) result += a[dim1][raddr&(DIM_SIZE-1)][dim3]; return
                      result; } 

如下图所示,该代码实例生成多个加载和存储指令,因此硬件中有多个加载/存储单元(LSU)。如果存储系统未拆分成多个bank,则端口少于存储器访问指令,并导致仲裁性访问。该仲裁结果为高循环启动间隔(II)值。尽可能避免仲裁,因为会增加组件中的FPGA面积使用率且损害组件性能。

图 18. 访问组件bank_arbitration的局部存储器

默认情况下, Intel® HLS Compiler Pro Edition将存储器拆分成bank,如果其确定此拆分有利于组件的性能。编译器检查访问之间是否有任何位保持不变,且自动推断bank选择位。

现在,考虑如下组件代码:
component
                    int bank_no_arbitration (int raddr, int waddr, int wdata) { #define DIM_SIZE 4
                    // Adjust memory geometry by preventing coalescing and splitting memory
                    hls_bankbits(4, 5) hls_bankwidth(sizeof(int)*DIM_SIZE) // Force each memory bank
                    to have 2 ports for read/write hls_singlepump hls_max_replicates(1) int
                    a[DIM_SIZE][DIM_SIZE][DIM_SIZE]; // initialize array a… int result = 0; #pragma
                    unroll for (int dim1 = 0; dim1 < DIM_SIZE; dim1++) #pragma unroll for (int
                    dim3 = 0; dim3 < DIM_SIZE; dim3++) a[dim1][waddr&(DIM_SIZE-1)][dim3] =
                    wdata; #pragma unroll for (int dim1 = 0; dim1 < DIM_SIZE; dim1++) #pragma
                    unroll for (int dim3 = 0; dim3 < DIM_SIZE; dim3++) result +=
                    a[dim1][raddr&(DIM_SIZE-1)][dim3]; return result; }

下图显示该实例代码创建了具有4个bank的存储器配置。使用位4和5作为bank选择位可确保每个加载/存储访问直接到达其存储bank。

图 19. 访问组件bank_no_arbitration的局部存储器

该代码实例中,设置hls_numbanks(4)代替hls_bankbits(4,5)可带来相同的存储器配置,因为 Intel® HLS Compiler Pro Edition自动推断最佳bank选择位。

Function Memory Viewer(inf the High-Level Design Reports)中,Address bit information显示bank选择位为b6b7,而非b4b5



之所以出现该差异,是因为Function Memory Viewer中报告的地址位都基于字节地址而非元素地址。由于数组a中的每个元素都是4个字节,元素地址位中的位b4b5对应字节寻址中的位b6b7

1 对于该实例,初始组件由设置为1 (hls_numbanks(1))的hls_numbanks属性生成的初始组件来防止编译器自动将存储器差分成bank。