如何利用编译时信息动态创建模板类?SystemC脉动阵列问题
解决方案
问题出在循环变量h是运行时变量,无法作为模板参数(模板参数要求编译期常量)。既然HEIGHT是编译期已知的模板参数,可以用编译期递归模板来初始化每行的移位寄存器,这符合C++11和SystemC可综合子集的要求。
步骤1:修正成员变量类型
原代码中sc_module shift_registers[HEIGHT];是错误的,因为sc_module不能直接以值语义存储,且需要动态创建不同模板实例的对象,应改为指针数组:
sc_module* shift_registers[HEIGHT];
步骤2:编写编译期递归初始化模板
创建递归模板结构体,在编译期展开初始化每一行的移位寄存器:
// 递归初始化模板 template<unsigned int H> struct ShiftRegInitializer { static void init(SystolicArray<T, HEIGHT, WIDTH>* array) { // 先初始化前H-1行 ShiftRegInitializer<H-1>::init(array); // 初始化第H-1行(索引从0开始),延迟为H-1 array->shift_registers[H-1] = new ShiftRegister<T, H-1>; // 在这里添加信号连接逻辑,例如: // array->shift_registers[H-1]->in(array->some_input_signal[H-1]); // array->shift_registers[H-1]->out(array->some_output_signal[H-1]); } }; // 递归终止条件:H=0时无操作 template<> struct ShiftRegInitializer<0> { static void init(SystolicArray<T, HEIGHT, WIDTH>* array) {} };
步骤3:在构造函数中触发初始化
修改SystolicArray的构造函数,调用递归模板完成初始化:
template<typename T, unsigned int HEIGHT, unsigned int WIDTH> class SystolicArray : public sc_module { public: sc_module* shift_registers[HEIGHT]; SC_CTOR(SystolicArray) { // 触发编译期递归初始化 ShiftRegInitializer<HEIGHT>::init(this); } };
说明
- 编译期递归会在编译时展开为
HEIGHT次初始化操作,每个ShiftRegister<T, H-1>的模板参数H-1都是编译期常量,符合编译器要求。 - 这种方式完全兼容SystemC可综合子集,综合工具可以正确识别并展开编译期逻辑。
- 注意将数据类型
T作为SystolicArray的模板参数,确保类型一致性。
内容的提问来源于stack exchange,提问作者Necrotos
相关产品推荐
相关产品推荐

