如何适配ap_uint类型使其可用于C++联合体?
如何让Xilinx ap_uint类型适配C++联合体?
在FPGA C++后端开发中,将ap_uint类型放入联合体时会触发编译错误,提示外层结构体的默认构造函数被隐式删除,原因是联合体成员包含非平凡构造函数的类型。
问题代码
#ifndef _ENTRY #define _ENTRY #include <cstdint> #include "ap_int.h" struct US0 { ap_uint<1> tag; union { struct { ap_uint<2l> v0; } case1; // Some }; }; US0 US0_0() { // None US0 x; x.tag = 0; return x; } US0 US0_1(ap_uint<2l> v0) { // Some US0 x; x.tag = 1; x.case1.v0 = v0; return x; } int32_t entry(){ ap_uint<2l> v0; v0 = 0; US0 v1; v1 = US0_1(v0); return 0l; } #endif
编译错误信息
../../../../hello.hpp: In function 'US0OM_ hosting便捷 ID PE Sefferfamil身上Em':重点栓Q: ../../../../hello.hpp:22:9: error: use of deleted function 'US0::US0()' US0 x; ^ ../../../../hello.hpp:13:8: note: 'US0::US0()' is implicitly deleted because the default definition would be ill-formed: struct US0 { ^~~ ../../../../hello.hpp:18:11: error: union member 'US0::<anonymous union>::case1' with non-trivial 'US0::<anonymous union>::<anonymous struct>::<constructor>()' } case1; // Some ^~~~~
原因分析
Xilinx的ap_uint属于非平凡类型(包含自定义构造函数、赋值运算符等特殊成员函数)。根据C标准,若联合体包含非平凡类型成员,编译器会隐式删除该联合体及外层结构体的默认构造函数、拷贝构造函数等特殊成员——因为编译器无法自动生成安全的实现逻辑,而Vivado HLS的C前端严格遵循这一规则。
适配方案
根据Xilinx官方对ap_int系列类型的使用规范,需要手动为外层结构体提供显式的特殊成员函数,确保联合体成员的初始化和拷贝逻辑明确:
显式定义结构体特殊成员函数
修改US0结构体,添加默认构造函数和带参构造函数,手动初始化所有成员:struct US0 { ap_uint<1> tag; union { struct { ap_uint<2l> v0; } case1; }; // 显式默认构造函数:初始化tag为0,联合体成员置0 US0() : tag(0) { case1.v0 = ap_uint<2l>(0); } // 带参构造函数:初始化tag为1,赋值联合体成员 explicit US0(ap_uint<2l> val) : tag(1) { case1.v0 = val; } };简化构造函数调用
基于新的结构体构造函数,调整原有的创建函数:US0 US0_0() { return US0(); // 调用默认构造,对应tag=0的场景 } US0 US0_1(ap_uint<2l> v0) { return US0(v0); // 调用带参构造,对应tag=1的场景 }
额外说明
Vivado HLS对C++特性的支持偏向硬件可综合的子集,对于包含非平凡类型的联合体,必须显式定义所有必要的特殊成员函数(构造、拷贝、析构),这样HLS才能生成明确的硬件电路逻辑,避免因自动生成逻辑不明确导致的综合失败。
内容的提问来源于stack exchange,提问作者Marko Grdinić
相关产品推荐
相关产品推荐

