如何在Vitis HLS中平整非完美循环



我的项目是将输入字符串编码为整数向量。我已经有了一个编码方法。我创建了一个查找表,并开始将输入字符串流式输入。将输入字符串的每个字符与查找表的char键进行比较,得到向量值并将它们相加。下面是一个例子:

lookup table
$       {1, -1, -1, 1, -1, ...., 1}
c       {1, -1, 1, 1, 1, ...., 1}
C       {1, 1, -1, 1, -1, ...., 1}
....
*       {-1, 1, -1, 1, -1, ...., 1}
&       {1, 1, -1, 1, 1, ...., 1}
input[in_len] = {'*','C','(','=','O',')','[','C','@','H',']','(','C','C','C','C','N','C','(','=','O',')','O','C','C','O','C',')','N','C','(','=','O',')','O','C','C','O','C'};
""
下面是我的代码:
void ENCODING_HV(FPGA_DATA input[in_len], 
                 FPGA_DATA lookup_key[NUM_TOKEN], 
                 LOOKUP_DATA lookup_HV[NUM_TOKEN],
                 int result_HV[CHUNK_NUM][CHUNK_SIZE]){
    
    for(int i = 0; i < in_len; i++){
        for(int j = 0; j < NUM_TOKEN; j++){
            if(input[i] == lookup_key[j]){
                for(int k = 0; k < CHUNK_NUM; k++){
    //#pragma HLS PIPELINE II=1
                    for(int l = 0; l < CHUNK_SIZE; l++){
    #pragma HLS ARRAY_RESHAPE variable=lookup_HV complete dim=3
    #pragma HLS ARRAY_RESHAPE variable=result complete dim=2
                        if(lookup_HV[j].map[k][l] == -1)
                            result_HV[k][l] = result_HV[k][l] + 1;
                        else
                            result_HV[k][l] = result_HV[k][l] - 1;
                    }
                }
            }
        }
    }
}

在第二个for循环中,我有一个if语句来比较输入字符与查找表的关键字符。而Vitis HLS则表示"不能使环'VITIS_LOOP_60_2'变平",合成时间较长。有谁能告诉我怎么做吗?谢谢你

WARNING: [HLS 200-960] Cannot flatten loop 'VITIS_LOOP_60_2' (Stream_Interface/HLS_scholarly/data_tokenize_2.cpp:60:28) in function 'create_sample_HV' the outer loop is not a perfect loop because there is nontrivial logic before entering the inner loop.
Resolution: For help on HLS 200-960 see www.xilinx.com/cgi-bin/docs/rdoc?v=2021.1;t=hls+guidance;d=200-960.html

免责声明:由于您没有提供完整的代码,我无法自己测试我的解决方案。

性能方面,作为经验法则,if语句是"便宜的";在硬件和HLS中,因为它们大部分时间在mux中解析。但在软件中却不是这样,它们会导致不连续性。

在你的算法中,if语句保护两个嵌套的for循环,并最终不执行它们。然而,在HLS中,for循环不能被"跳过",因为它们最终将代表一些物理硬件组件。因此,通过查看您的代码,我将把if语句移到嵌套的for循环中,因为不影响算法。因此,最终的解决方案可能是:

void ENCODING_HV(FPGA_DATA input[in_len], 
                 FPGA_DATA lookup_key[NUM_TOKEN], 
                 LOOKUP_DATA lookup_HV[NUM_TOKEN],
                 int result_HV[CHUNK_NUM][CHUNK_SIZE]){
#pragma HLS ARRAY_RESHAPE variable=lookup_HV complete dim=3
#pragma HLS ARRAY_RESHAPE variable=result complete dim=2
    for(int i = 0; i < in_len; i++){
        for(int j = 0; j < NUM_TOKEN; j++){
            for(int k = 0; k < CHUNK_NUM; k++){
#pragma HLS PIPELINE II=1
                for(int l = 0; l < CHUNK_SIZE; l++){
                    if(input[i] == lookup_key[j]){
                        if(lookup_HV[j].map[k][l] == -1)
                            result_HV[k][l] = result_HV[k][l] + 1;
                        else
                            result_HV[k][l] = result_HV[k][l] - 1;
                    }
                }
            }
        }
    }
}

旁注:通过将所有if语句保留在嵌套的for循环中,您甚至可以移动上面的PIPELINE pragma以完全展开最内部的for循环。

最新更新