示例测试激励文件 - 2021.2 Chinese

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

Document ID
UG1399
Release Date
2021-12-15
Version
2021.2 Chinese

赛灵思建议您将顶层综合函数与测试激励文件分开,并使用头文件。在以下代码示例显示的设计中,HLS 工程的顶层函数 hier_func 会调用 2 个子函数:

  • sumsub_func 执行加法和减法。
  • shift_func 执行移位。

数据类型在头文件 (hier_func.h) 中定义。此函数的代码如下所示:

#include "hier_func.h"

int sumsub_func(din_t *in1, din_t *in2, dint_t *outSum, dint_t *outSub)
{
 *outSum = *in1 + *in2;
 *outSub = *in1 - *in2;
}

int shift_func(dint_t *in1, dint_t *in2, dout_t *outA, dout_t *outB)
{
 *outA = *in1 >> 1;
 *outB = *in2 >> 2;
}

void hier_func(din_t A, din_t B, dout_t *C, dout_t *D)
{
 dint_t apb, amb;

 sumsub_func(&A,&B,&apb,&amb);
 shift_func(&apb,&amb,C,D);
}

如上所示,该顶层函数可包含多个子函数。综合仅限于单个顶层函数。要对多个函数进行综合,请将这些函数组合为单个顶层函数的子函数。

如下所示,头文件 (hier_func.h) 演示了如何使用宏以及如何通过 typedef 语句提升代码可移植性和可读性。

提示: 任意精度 (AP) 数据类型 探讨了任意精度数据类型相关内容,以及如何使用 typedef 语句来优化变量类型从而优化变量位宽,并在最终的 FPGA 实现中改善面积和性能。
#ifndef _HIER_FUNC_H_
#define _HIER_FUNC_H_

#include <stdio.h>

#define NUM_TRANS 40

typedef int din_t;
typedef int dint_t;
typedef int dout_t;

void hier_func(din_t A, din_t B, dout_t *C, dout_t *D);

#endif

以上头文件包含 hier_func 函数不需要的部分 #define 语句(如 NUM_TRANS),这些语句是为包含相同头文件的测试激励文件提供的。

以下代码用于为 hier_func 设计定义测试激励文件:

#include "hier_func.h"

int main() {
 // Data storage
 int a[NUM_TRANS], b[NUM_TRANS];
 int c_expected[NUM_TRANS], d_expected[NUM_TRANS];
 int c[NUM_TRANS], d[NUM_TRANS];

  //Function data (to/from function)
 int a_actual, b_actual;
 int c_actual, d_actual;

  // Misc
 int retval=0, i, i_trans, tmp;
 FILE *fp;

 // Load input data from files
 fp=fopen(tb_data/inA.dat,r);
 for (i=0; i<NUM_TRANS; i++){
 fscanf(fp, %d, &tmp);
 a[i] = tmp;
 } 
 fclose(fp);

 fp=fopen(tb_data/inB.dat,r);
 for (i=0; i<NUM_TRANS; i++){
 fscanf(fp, %d, &tmp);
 b[i] = tmp;
 } 
 fclose(fp);

 // Execute the function multiple times (multiple transactions)
 for(i_trans=0; i_trans<NUM_TRANS-1; i_trans++){

 //Apply next data values
 a_actual = a[i_trans];
 b_actual = b[i_trans];

  hier_func(a_actual, b_actual, &c_actual, &d_actual);

 //Store outputs
 c[i_trans] = c_actual;
 d[i_trans] = d_actual;
 }

 // Load expected output data from files
 fp=fopen(tb_data/outC.golden.dat,r);
 for (i=0; i<NUM_TRANS; i++){
 fscanf(fp, %d, &tmp);
 c_expected[i] = tmp;
 } 
 fclose(fp);

 fp=fopen(tb_data/outD.golden.dat,r);
 for (i=0; i<NUM_TRANS; i++){
 fscanf(fp, %d, &tmp);
 d_expected[i] = tmp;
 } 
 fclose(fp);

 // Check outputs against expected
 for (i = 0; i < NUM_TRANS-1; ++i) {
 if(c[i] != c_expected[i]){
 retval = 1;
 }
 if(d[i] != d_expected[i]){
 retval = 1;
 }
 }

 // Print Results
 if(retval == 0){
 printf(    *** *** *** *** \n); 
 printf(    Results are good \n); 
 printf(    *** *** *** *** \n); 
 } else {
 printf(    *** *** *** *** \n); 
 printf(    Mismatch: retval=%d \n, retval); 
 printf(    *** *** *** *** \n); 
 }

 // Return 0 if outputs are corre
 return retval;
}