验证选项 1:标准数学库和验证差异 - 2021.2 Chinese

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

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

在此选项中,源代码中使用的是标准 C 语言数学库。如果已综合的任意函数的准确度与此完全相同,那么 C/RTL 协同仿真与 C 语言仿真不同。以下示例着重演示了此方法。

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

typedef float data_t;

data_t cpp_math(data_t angle) {
     data_t s = sinf(angle);
     data_t c = cosf(angle);
     return sqrtf(s*s+c*c);
}

在此情况下,C 语言仿真与 C/RTL 协同仿真之间的结果不同。比较仿真输出时请谨记,从测试激励文件写出的任意结果都将写入执行仿真的工作目录:

  • C 语言仿真:<project>/<solution>/csim/build文件夹
  • C/RTL 协同仿真:<project>/<solution>/sim/<RTL>文件夹

其中,<project> 是工程文件夹,<solution> 是解决方案文件夹的名称,<RTL> 是验证的 RTL 的类型(Verilog 或 VHDL)。下图显示了综合前的结果文件(左侧)与分析后的 RTL 结果文件(右侧)的典型比较。输出显示在第 3 列中。

图 1. 分析前和分析后仿真差异

分析前仿真与分析后仿真结果存在少量差异。您必须判定在最终 RTL 实现中此少量差异是否可接受。

处理此类差异的建议流程是使用测试激励文件检查结果,以确认结果处于可接受的误差范围内。这可通过为同一函数创建 2 个版本来完成,其中 1 个版本用于综合,另 1 个版本用作为参考版本。在此示例中,仅对 cpp_math 函数进行综合。

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

typedef float data_t;

data_t cpp_math(data_t angle) {
 data_t s = sinf(angle);
 data_t c = cosf(angle);
 return sqrtf(s*s+c*c);
}

data_t cpp_math_sw(data_t angle) {
 data_t s = sinf(angle);
 data_t c = cosf(angle);
 return sqrtf(s*s+c*c);
}

用于验证设计的测试激励文件会使用 diff 函数对 2 个函数的输出进行比较以判定差异,如以下示例所示。在 C 语言仿真期间,这 2 个函数会生成完全相同的输出。在 C/RTL 协同仿真期间,cpp_math 函数会生成不同结果,并检查结果的差异。

int main() {
 data_t angle = 0.01;
 data_t output, exp_output, diff;
 int retval=0;

 for (data_t i = 0; i <= 250; i++) {
 output = cpp_math(angle);
 exp_output = cpp_math_sw(angle);

 // Check for differences
 diff = ( (exp_output > output) ? exp_output - output : output - exp_output);
 if (diff > 0.0000005) {
 printf("Difference %.10f exceeds tolerance at angle %.10f \n", diff, angle);
 retval=1;
 }

 angle = angle + .1;
 }

 if (retval != 0) {
 printf("Test failed  !!!\n"); 
 retval=1;
 } else {
 printf("Test passed !\n");
  }
 // Return 0 if the test passes
  return retval;
}

如果差异裕度降低到 0.00000005,那么此测试激励文件会高亮 C/RTL 协同仿真期间的误差裕度。

Difference 0.0000000596 at angle 1.1100001335
Difference 0.0000000596 at angle 1.2100001574
Difference 0.0000000596 at angle 1.5100002289
Difference 0.0000000596 at angle 1.6100002527
etc..

使用标准 C 语言数学库(math.hcmath.h)时,请创建一个“智能”测试激励文件以验证准确性差异是否可接受。