使用Vitis HLS实现元胞自动机时遇Top函数未找到错误求助
Vitis HLS元胞自动机综合错误解决思路
尝试使用Vitis HLS实现元胞自动机,测试仿真运行正常,但综合时反复出现以下错误:
ERROR: [HLS 214-157] Top function not found: there is no function named 'ca' cellular_automata:cellular_automata Mar 29, 2023, 3:14:13 PM
期望生成Vivado IP,但编译因该错误终止,以下是实现代码及解决思路:
ca.hpp:
#include <cstdio> #include <cinttypes> #include "ap_axi_sdata.h" #include "hls_stream.h" #define N 8 typedef int DataType; typedef hls::axis<DataType, 0, 0, 0> packet; typedef hls::stream<packet> stream; bool is_equal(DataType previous_state[3], DataType test[3]); DataType rule30(DataType previous_state[3]); template <typename T> void ca(T input[N], T output[N]);
ca.cpp:
#include "ca.hpp" DataType rule30_111[3] = {1, 1, 1}; DataType rule30_110[3] = {1, 1, 0}; DataType rule30_101[3] = {1, 0, 1}; DataType rule30_011[3] = {0, 1, 1}; DataType rule30_100[3] = {1, 0, 0}; DataType rule30_010[3] = {0, 1, 0}; DataType rule30_001[3] = {0, 0, 1}; DataType rule30_000[3] = {0, 0, 0}; bool is_equal(DataType previous_state[3], DataType test[3]){ int check = 1; for(int j = 0; j < 3; j++){ check = previous_state[j]==test[j]; if(check == 0){ return 0; } } return 1; } DataType rule30(DataType previous_state[3]){ if(is_equal(previous_state, rule30_111)){ return 0; } else if(is_equal(previous_state, rule30_110)){ return 0; } else if(is_equal(previous_state, rule30_101)){ return 0; } else if(is_equal(previous_state, rule30_011)){ return 1; } else if(is_equal(previous_state, rule30_001)){ return 1; } else if(is_equal(previous_state, rule30_010)){ return 1; } else if(is_equal(previous_state, rule30_100)){ return 1; } else if(is_equal(previous_state, rule30_000)){ return 0; } else { return -1; } } template <typename T> void ca(T input[N], T output[N]) { for(int i = 0; i < N; i++){ if(i > 0 and i < N - 1){ T previous_state[3] = {input[i - 1], input[i], input[i + 1]}; output[i] = rule30(previous_state); } } } void cellular_autmata(stream &signal, stream &result) { #pragma HLS INTERFACE axis port=signal #pragma HLS INTERFACE axis port=result #pragma HLS INTERFACE ap_ctrl_none port=return DataType in[N]; DataType out[N]; read: for(int i = 0; i < N; i++){ packet temp = signal.read(); in[i] = temp.data; } ca<DataType>(in, out); write: for(int i = 0; i < N; i++){ packet temp; temp.data = out[i]; ap_uint<1> last = 0; if(i == N - 1){ last = 1; } temp.last = last; temp.keep = -1; result.write(temp); } }
ca_tb.cpp:
#include "ca.hpp" void sw_ca(DataType input[], DataType output[]) { for(int i = 0; i < N; i++){ if(i > 0 and i < N - 1){ DataType rule[3] = {input[i - 1], input[i], input[i + 1]}; output[i] = rule30(rule); } } } int main(void) { /*initialise*/ int i, err; DataType in[N] = {0,0,1,1,0,0,1,1}; DataType out_sw[N]; DataType out_hw[N]; std::cout << "signal in:" << std::endl; for (i = 0; i < N; i++) { //in[i] = i % 2; out_sw[i] = 0; out_hw[i] = 0; std::cout << in[i] << " "; } std::cout << std::endl; std::cout << std::endl; /* software */ sw_ca(in, out_sw); std::cout<<"software kernel complete "<<std::endl; /* hardware */ ca<DataType>(in, out_hw); std::cout<<"hardware kernel complete "<<std::endl; /* comparison */ err = 1; std::cout << "signal out:" << std::endl; for(i = 0; i < N; i++){ if(out_sw[i] != out_hw[i]){ err = 0; } std::cout << out_hw[i] << " "; } std::cout<<std::endl; if (err == 1) { printf("Test successful! "); return 0; } printf("Test failed "); return 1; }
错误原因及解决步骤
核心问题
Vitis HLS无法将模板函数作为顶层函数进行综合,你当前指定的顶层函数是ca(模板函数),这不符合HLS的综合规则;另外代码中实际的硬件入口是带有AXI接口约束的cellular_autmata函数(注意存在拼写错误),这个才是正确的顶层候选。
具体解决步骤
- 修正顶层函数配置:在Vitis HLS项目的综合设置中,将顶层函数从
ca改为cellular_autmata(建议先修正函数名为cellular_automata,避免后续拼写相关问题)。 - 确认模板函数实例化:
ca模板函数被cellular_autmata以DataType类型实例化调用,HLS会自动处理该实例化后的子模块,无需额外配置。 - 修复函数名拼写错误:
cellular_autmata中的autmata是拼写错误,应改为automata,否则可能导致IP生成或后续调用时出现识别问题。 - 完善输出边界处理:当前
ca函数中未处理首尾元素(i=0和i=N-1)的输出值,建议根据元胞自动机规则补充边界逻辑(比如采用循环边界、固定边界值等),避免输出数组存在未初始化的不确定值。
内容的提问来源于stack exchange,提问作者AKRA
相关产品推荐
相关产品推荐

