如果阵列为只读,则建议对其使用
const
限定符,因为 Vitis HLS 并不总是推断设计分析是否应使用 ROM。ROM 的自动推断的一般规则是局部(非全局)推断,static
阵列先完全写入而后读取,且不再写入。在代码中遵循下列实践有助于推断 ROM: - 在使用阵列的函数中尽早初始化该阵列。
- 将写操作组合在一起。
- 勿将
array(ROM)
初始化写操作与非初始化代码交织在一起。 - 勿将不同值存储到相同阵列元素中(将所有写操作一起组合到代码中)。
- 元素值计算不得依赖于除初始化循环计数器变量以外的任何非常量(在编译时)设计变量。
如果使用复数赋值来初始化 ROM(例如,来自 math.h 库的函数),将阵列初始化置于独立函数中即可允许推断 ROM。在以下示例中,完成 RTL 综合后,将 sin_table[256]
阵列推断为存储器,并作为 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];
}
提示: 由于
sin()
函数生成了常量值,因此 RTL 设计中无需任何核即可实现 sin()
函数。