Vitis HLS结构体数组初始化遇指针不支持错误求助
Vitis HLS状态机实现中"Pointer to pointer is not supported"错误分析与解决
问题重现
使用Vitis HLS开发可综合状态机时,触发编译错误:
ERROR: [HLS 214-134] in function 'kernel1(char*, int)': Pointer to pointer is not supported for variable ''
错误出现在两处代码:
- 结构体数组初始化:
Transition transitions[] = {a, b}; - 数组元素地址传递:
transitions_occurred += testTransition(&transitions[i], stream, &stream_index);
但直接调用原变量指针的代码无报错:
transitions_occurred += testTransition(&a, stream, &stream_index); transitions_occurred += testTransition(&b, stream, &stream_index);
错误原因
Vitis HLS综合器对指针的支持有严格的静态解析要求,核心问题在于:
- 结构体数组的本质是拷贝存储:
Transition transitions[] = {a, b};会将a、b的内容拷贝到数组的新内存位置,而非存储原变量的引用。 - 动态数组元素地址无法静态解析:
&transitions[i]是依赖索引i动态计算的地址,HLS会将其识别为间接指针引用(等效于指针的指针)。硬件需要固定的资源映射,动态计算的指针地址无法被综合器静态分析,因此触发不支持的错误。
而手动调用时,&a、&b是指向固定位置变量的直接指针,HLS可以明确其对应的硬件资源,因此通过检查。
解决方案
方案1:改用指针数组存储原变量地址
直接将原变量的指针存入数组,避免拷贝,让每个数组元素都是静态可解析的固定指针:
// 定义指针数组,存储原变量的地址 Transition* transitions[] = {&a, &b}; // 调用时直接传递数组中的指针,无需取地址 transitions_occurred += testTransition(transitions[i], stream, &stream_index);
这种方式完全符合HLS对指针的静态解析要求,不会触发错误。
方案2:手动展开循环(适合状态数量少的场景)
如果状态过渡数量不多,直接使用已验证的无报错写法,虽然代码冗余,但综合效率最高:
transitions_occurred += testTransition(&a, stream, &stream_index); transitions_occurred += testTransition(&b, stream, &stream_index); // 新增状态直接追加调用即可
方案3:强制展开循环+显式索引绑定
若必须使用结构体数组(比如需要修改数组内的结构体实例),通过#pragma HLS unroll强制展开循环,让HLS静态解析每个元素的地址:
for(int i=0; i<2; i++){ #pragma HLS unroll if(i == 0){ transitions_occurred += testTransition(&transitions[0], stream, &stream_index); } else { transitions_occurred += testTransition(&transitions[1], stream, &stream_index); } }
展开后每个分支的地址都是固定的,HLS可以正常综合。
内容的提问来源于stack exchange,提问作者136
相关产品推荐
相关产品推荐

