C++ 类和模板 - 2022.1 Chinese

Vitis 高层次综合用户指南 (UG1399)

Document ID
UG1399
Release Date
2022-06-07
Version
2022.1 简体中文

Vitis HLS 完全支持对 C++ 类进行综合,但仅支持对顶层函数进行综合,而不支持对顶层的类进行综合。要对类成员函数进行综合,请将类本身例化为函数。请勿直接将顶层类例化为测试激励文件。以下代码示例显示了如何在 cpp_FIR 顶层函数中对后文所述头文件中定义的 CFir 类进行例化,以及如何使用该类实现 FIR 滤波器。

#include "cpp_FIR.h"

// Top-level function with class instantiated
data_t cpp_FIR(data_t x)
 {
 static CFir<coef_t, data_t, acc_t> fir1;

 cout << fir1;

 return fir1(x);
 }
重要: 不支持对位于顶层的类和类成员函数进行综合。请例化顶层函数中的类。

检验以上 C++ FIR 滤波器示例中用于实现设计的类之前,值得注意的是,Vitis HLS 在综合期间会忽略标准输出串流 cout。完成综合后,Vitis HLS 会发出以下警告:

INFO [SYNCHK-101] Discarding unsynthesizable system call: 
'std::ostream::operator<<' (cpp_FIR.h:108)
INFO [SYNCHK-101] Discarding unsynthesizable system call: 
'std::ostream::operator<<' (cpp_FIR.h:108)
INFO [SYNCHK-101] Discarding unsynthesizable system call: 'std::operator<< 
<std::char_traits<char> >' (cpp_FIR.h:110)

以下代码示例显示了 cpp_FIR.h 头文件,包括 CFir 类的定义及其关联的成员函数。在此示例中,运算符成员函数 ()<< 为重载运算符,分别用于执行主算法以及配合 cout 用于数据格式化以便在 C/C++ 语言仿真期间显示。

#include <fstream>
#include <iostream>
#include <iomanip>
#include <cstdlib>
using namespace std;

#define N 85

typedef int coef_t;
typedef int data_t;
typedef int acc_t;

// Class CFir definition
template<class coef_T, class data_T, class acc_T>
class CFir {
 protected:
   static const coef_T c[N];
   data_T shift_reg[N-1];
 private:
 public:
   data_T operator()(data_T x);
   template<class coef_TT, class data_TT, class acc_TT>
   friend ostream&
   operator<<(ostream& o, const CFir<coef_TT, data_TT, acc_TT> &f);
};

// Load FIR coefficients
template<class coef_T, class data_T, class acc_T>
const coef_T CFir<coef_T, data_T, acc_T>::c[N] = {
 #include "cpp_FIR.h"
};

// FIR main algorithm
template<class coef_T, class data_T, class acc_T>
data_T CFir<coef_T, data_T, acc_T>::operator()(data_T x) {
 int i;
 acc_t acc = 0;
 data_t m;

 loop: for (i = N-1; i >= 0; i--) {
   if (i == 0) {
      m = x;
      shift_reg[0] = x;
   } else {
      m = shift_reg[i-1];
      if (i != (N-1))
      shift_reg[i] = shift_reg[i - 1];
   }
   acc += m * c[i];
 }
 return acc;
}

// Operator for displaying results
template<class coef_T, class data_T, class acc_T>
ostream& operator<<(ostream& o, const CFir<coef_T, data_T, acc_T> &f) {
 for (int i = 0; i < (sizeof(f.shift_reg)/sizeof(data_T)); i++) {
    o << shift_reg[ << i << ]=  << f.shift_reg[i] << endl;
 }
 o << ______________ << endl;
 return o;
}

data_t cpp_FIR(data_t x);

以下代码示例中显示的 C++ FIR 滤波器示例中的测试激励文件用于演示对顶层函数 cpp_FIR 进行调用和确认的方式。此示例突出显示了适合 Vitis HLS 综合的标准测试激励文件的部分重要属性:

  • 根据已知有效值对输出结果进行检查。
  • 如果结果确认正确,测试激励文件会返回 0。
#include "cpp_FIR.h"

int main() {
 ofstream result;
 data_t output;
 int retval=0;


 // Open a file to saves the results
 result.open(result.dat);

 // Apply stimuli, call the top-level function and saves the results
 for (int i = 0; i <= 250; i++)
 {
    output = cpp_FIR(i);

    result << setw(10) << i;
    result << setw(20) << output;
    result << endl;

 }
 result.close();

 // Compare the results file with the golden results
 retval = system(diff --brief -w result.dat result.golden.dat);
 if (retval != 0) {
    printf(Test failed  !!!\n); 
    retval=1;
 } else {
    printf(Test passed !\n);
 }

 // Return 0 if the test
 return retval;
}

适用于 cpp_FIR 的 C++ 测试激励文件

要将指令应用于类中定义的对象,请执行以下操作:

  1. 打开定义类的文件(通常为头文件)。
  2. 使用Directives(指令)选项卡应用指令。

就像函数一样,针对类的所有实例将应用相同的最优化操作。