未定义的行为 - 2023.2 简体中文

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

Document ID
UG1399
Release Date
2023-12-18
Version
2023.2 简体中文

C/C++ 未定义的行为可能导致仿真与综合中出现不同的行为。此类行为的示例如下所示:

for (int i=0; i<N; i++) {
  int val; // uninitialized value
  if (i==0) val=0;
  else if (cond) val=1;
  // val may have indeterminate value here
  A[i] = val; // undefined behavior
  val++; // dead code
}

在以上示例中,只要 i==0(cond) 值均非 true,A[i] 就不应从上一次循环迭代得到 val 值。甚至不应发生递增 (val++)。对于完成分区后获取的标量值也同样如此。

对于此类 C/C++ 未定义的行为,编译代码时,GCC 与 Vitis HLS 之间的行为可能有别,这可能导致 RTL/协同仿真期间发生不匹配。这是由于在为 CPU 编译的 GCC 中,通常不同循环迭代之间的 val 保留在相同寄存器或栈位置,因此不同循环迭代之间的行为是 val 保留不变。

解决方案是在每次迭代时初始化 val(前提是,此行为与期望相符)或者将 val 的声明移至循环上层(尽可能高),使其生存期范围与所需复用相符。编译器不应根据未定义的 C/C++ 行为来推断已定义的特定 RTL 行为。