数组-vivado hls第六十六章
1.Vivado® HLS 不要求通过使用 static 限定符指定的数组来对内存进行综合,也不要求使用 const 限定符来推断内存。如“数组初始化”中所述,静态类型与 RTL 中的内存的。上述代码中,数组作为RAM来实现,默认RAM为端口RAM,那么对SUM_LOOP循环进行流水线优化的时候,4.vivado hls可综合代码中,数组的大小需要固定,不固定大小的数组是不可综合的。1.在顶层函数
一、数组被综合为内存实现
1.数组综合后作为内存来实现
2.数组可以综合为RAM
3.数组可以综合为ROM
4.数组可以综合为FIFO
二、顶层函数接口上使用数组
1.在顶层函数接口上使用数组,是作为访问外部内存的RTL端口来实现的
2.顶层函数接口上使用数组,可以综合为axi-mem接口,并指定depth深度
三、数组访问在RTL中可能引发的问题
1.数组作为内存实现的时候,内存端口的数量会限制对数据的访问
2.数组初始化没有谨慎执行,可能导致rtl中不必要的长时间的复位和初始化
3.如果数组为只读访问权限,需要将数组作为ROM来实现
4.vivado hls可综合代码中,数组的大小需要固定,不固定大小的数组是不可综合的。
四、数组访问和性能
1.性能受限制的案例
#include "array_mem_bottleneck.h"
dout_t array_mem_bottleneck(din_t mem[N]) {
dout_t sum=0;
int i;
SUM_LOOP:for(i=2;i<N;++i)
sum += mem[i] + mem[i-1] + mem[i-2];
return sum;
}
上述代码中,数组作为RAM来实现,默认RAM为端口RAM,那么对SUM_LOOP循环进行流水线优化的时候,
II=1不可实现,综合工具会放宽条件,可以把II设置为>=2来完成流水化
2.性能提升案例
可以指定mem数组为双口RAM来实现II=1的流水线设计
3.可以通过修改代码来优化II
#include "array_mem_perform.h"
dout_t array_mem_perform(din_t mem[N]) {
din_t tmp0, tmp1, tmp2;
dout_t sum=0;
int i;
tmp0 = mem[0];
tmp1 = mem[1];
SUM_LOOP:for (i = 2; i < N; i++) {
tmp2 = mem[i];
sum += tmp2 + tmp1 + tmp0;
tmp0 = tmp1;
tmp1 = tmp2;
}
return sum;
}
五、数组作为FIFO访问
1.数组作为FIFO来实现,访问数据按照顺序的方式进行数据访问
2.如果此数组被多个位置读取访问,必须严格遵守FIFO访问顺序,否则无法作为FIFO实现
六、接口上使用数组
1.使用 INTERFACE 指令将接口指定为 RAM 或 FIFO 接口
2.使用 RESOURCE 指令将 RAM 指定为单端口或双端口 RAM
3. 使用 RESOURCE 指令指定 RAM 时延
4.使用数组最优化指令(Array_Partition、Array_Map 或 Array_Reshape)来重新配置数组结构,从而重新
配置 I/O 端口数量。
七、数组初始化
1.xilinx建议但是不强制将数组指定为包含static静态限定符的内存来实现
2.如果变量包含 static 限定符,那么 Vivado HLS 会对 RTL 设计和 FPGA 比特流中的变量进行初始化。因此,
无需经历多个时钟周期来初始化内存,并且可确保大型内存初始化不会产生任何运算开销
static int coeff[8] = {-2, 8, -4, 10, 14, 10, -4, 8, -2};
八、将数组实现为ROM
1.Vivado® HLS 不要求通过使用 static 限定符指定的数组来对内存进行综合,也不要求使用 const 限定符来推断内存
是否应为 ROM
2.赛灵思强烈建议针对旨在用作为内存的数组使用静态限定符。如“数组初始化”中所述,静态类型与 RTL 中的内存的
行为方式几乎完全相同。
3.如果数组为只读,则也建议对其使用 const 限定符,因为 Vivado HLS 并不总是推断设计分析是否应使用 ROM。
ROM 的自动推断的一般规则是局部静态(非全局)数组先写入后读取。
4.在使用数组的函数中尽早初始化该数组。
5.将写操作组合在一起。
6.勿将 array(ROM) 初始化写操作与非初始化代码交织在一起。
7.勿将不同值存储到相同数组元素中(将所有写操作一起组合到代码中)。
8.元素值计算不得依赖于除初始化循环计数器变量以外的任何非常量(在编译时)设计变量。
9.rom实现案例
#include "array_ROM_math_init.h"
#include <math.h>
void init_sin_table(din1_t sin_table[256])
{
int i;
for (i = 0; i < 256; i++) {
dint_t real_val = sin(M_PI * (dint_t)(i - 128) / 256.0);
sin_table[i] = (din1_t)(32768.0 * real_val);
}
}
dout_t array_ROM_math_init(din1_t inval, din2_t idx)
{
short sin_table[256];
init_sin_table(sin_table);
return (int)inval * (int)sin_table[idx];
}
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)