【干货】Vivado 综合崩溃调试指南

要解决任何综合崩溃问题,通常应该从了解崩溃发生在综合的哪个阶段着手,以及工具方面是否有任何迹象指向特定的模块、赋值、声明或推断。

如果以下文章无法帮助您解决您查询的问题,请分享在运行文件夹中生成的 hs_pidxxxx.log 文件以及“project_name.runs/synth_1/”目录下的综合日志文件。

在某些情况下会出现日志不足的状况,并且需要与赛灵思共享 RTL 设计,才能对问题进行进一步调试。

Elaboration 阶段中的工具崩溃:

这意味着该工具是在对 RTL 设计进行细化时崩溃的,综合日志看上去如下所示:

---------------------------------------------------------------------------------
Starting RTL Elaboration : Time (s): …
---------------------------------------------------------------------------------
…….
Abnormal program termination (11)
Please check '..hs_err_pidxxxx.log' for details
Parent process (pid xxxxx) has died. This helper process will now exit
OR
---------------------------------------------------------------------------------
Starting RTL Elaboration : Time (s): …
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
Finished RTL Elaboration : Time (s): cpu = …
---------------------------------------------------------------------------------
RTL Elaboration failed

在综合日志中,您应该会看到类似于“Abnormal program termination (11)”的崩溃相关消息(尽管可能是在没有消息的情况下)。这些问题就是崩溃问题。

如果是细分崩溃问题,在大多数情况下,问题出在工具中未得到正确处理的 RTL 或 RTL 的某些部分。

如果是这类情况,请与我们分享您的工程,以便我们可以在工具中添加修复程序,避免将来出现这类问题。

要在您这里调试此类问题,以下步骤可能会有用:

这里的目标是将崩溃缩小到“设计模块”,然后 -> “RTL 文件” -> “某部分 RTL” -> “Line of RTL 代码行”

确定发生问题的 RTL 文件是最艰巨的任务之一。要找到有问题的模块,可以使用以下方法:

使用黑匣子方法:

假设设计结构及层级如下所示:

这里的目标是使用 black_box 属性消除其他三个模块。

我们需要假设一个模块有问题。

假设 A 有问题:对于这种情况,保持 A 模块完好无损,并将 RTL 文件中的 B、C 和 D 都设为 black_box:

(* black_box *) module B (
…)
end module

(* black_box *) module C (
…)
end module

(* black_box *) module D (
…)
end module

运行 Synthesis 并检查工具是否以崩溃。

如果工具已崩溃,则问题要么出在模块 A,要么出在其子模块 (A11、A12 ... A21、A22 ......)中。

在这种情况下,通过保留 A1 并将 A2 设为 black_box 继续调试,依此类推。

如果工具没有崩溃,则尝试保持 B 模块完好无损,并将 A、C 和 D 标记为 black_box。

这里有一个简单的示例工程:

在综合上述层级时,该工具崩溃并在综合日志中出现以下错误:
….
….
Parameter break bound to: 8'b11110000
An unrecoverable error has occurred, synthesis canceled.
---------------------------------------------------------------------------------
Finished RTL Elaboration : Time (s): cpu = 00:00:05 ; elapsed = 00:00:07 . Memory (MB): peak = 3278.059 ; gain = 194.688 ; free physical = 20020 ; free virtual = 114523
---------------------------------------------------------------------------------
RTL Elaboration failed
INFO: [Common 17-83] Releasing license: Synthesis
4 Infos, 5 Warnings, 0 Critical Warnings and 1 Errors encountered.
synth_design failed
ERROR: [Common 17-69] Command failed: Synthesis failed - please see the console or run log file for details
INFO: [Common 17-206] Exiting Vivado at Thu Feb 21 23:37:22 2019...

正如您在日志中可以清楚地看到的那样,当工具试图对设计进行细分时发生了崩溃。

为了调试这个问题,我们需要开始对模块进行黑盒测试。

尝试多个组合后,当使用 black_box 属性禁用 ps2_to_ascii1 时,综合通过,同样,当仅启用 pas2_to_ascii2 时,该工具会崩溃,如下所示:


attribute black_box : string;
attribute black_box of Debounce : component is "yes";
attribute black_box of sinchronizer : component is "yes";
attribute black_box of SIPO : component is "yes";
attribute black_box of Driver : component is "yes";

由于我们已经确定了 RTL 文件/模块,现在的目标是要找到 RTL 中导致崩溃的部分。

这可能是因大循环迭代、长而复杂的赋值、复杂的位片操作或不正确的编码方式或不支持的结构而导致的。

在上述示例中,由于不支持编码方式,导致工具崩溃:

process(…)
begin
case dummy is
when S1 =>
if rising_edge(clk) then
...
end if;
end if;
when S2 =>
if rising_edge(clk) then
...
end if;
end if;
when S3 =>
if rising_edge(clk) then
...
end if;
end if;
when S4 =>
...
end case;
end process;

**也可以通过使单个模块成为综合的“顶层模块”来查看工具是否会崩溃来找到引起问题的模块或RTL文件。

例如,当 pas2_to_ascii2 被设置为顶层模块时,上述工程会以相同的错误崩溃

跨边界优化阶段的崩溃:

什么是跨边界优化?

该工具将基于 synth_design 命令尝试在任何给定设计上执行许多优化。

全局设置、块级设置和属性可以定义工具是否可以在层级(边界)内或跨层级(边界)执行优化。

对于 Vivado 的默认设置,‘-flatten_hierarchy’ 被设置为‘rebuilt’,该工具会尝试展平层级并执行跨边界优化。

该工具会试图找到跨边界的优化可能性,并且可能会由于工具错误或由于设计问题而崩溃(在最坏的情况下)。

在上述情况下,日志可能如下所示:

---------------------------------------------------------------------------------
Start Cross Boundary Optimization
---------------------------------------------------------------------------------
Abnormal program termination (6)
Please check 'hs_err_pid5649.log' for details
Parent process (pid 5649) has died. This helper process will now exit

为了防止这类崩溃,一个简单的解决方法是通过将全局设置“flatten_hierarchy”更改为“none”来禁用跨边界优化。使用“none”的缺点可能是一个糟糕的 QoR,所以可能不适用于所有设计。

一个更好的方法是通过黑匣方法找到引起问题的层级,然后对该层级使用“KEEP_HIERARCHY/DONT_TOUCH”属性来禁用该层级内/来自该层级的任何跨边界优化。

也有一个可能是,工具在推断/优化 BRAM 时崩溃。

在这种情况下,您可以禁用 BRAM 推断来看看这是否是真正的原因。要实现这一点,需要将 -max_bram 选项设置为‘0’。如果在将‘synth_design -max_bram’设置为 0 后工具即完成综合,那么,崩溃与 BRAM 推断有关。

由于禁用 BRAM 推断不是一个可接受的方案,用户将需要找到 BRAM 寄存器所在的模块,并且基于客户的应用情况,可以对存储器寄存器使用“DONT_TOUCH”属性以阻止 BRAM 推断。

另一种方法是将该模块标记为 OOC、同时 -max_bram 标记为'0',并使用默认值(即 -max_bram "-1")来运行顶层模块的综合。

如果您仍然遭遇崩溃,请在此处发布您的日志文件 (hs_pidxxxx.log and runme.log) 和详细的设计信息:赛灵思论坛:综合板块

时序优化中的崩溃:

Vivado 是一个时序驱动综合引擎,对于所有设计,该工具都会尝试查看是否有任何可能执行的优化以满足设计的时序要求。

在一些情况下,该工具可能会在时序优化阶段崩溃,日志如下:

---------------------------------------------------------------------------------
Start Timing Optimization
---------------------------------------------------------------------------------
Abnormal program termination (11)
Please check 'hs_err_pid15514.log' for details

在这类情况下,首先要做的事是禁用约束 (.xdc) 文件并运行综合。如果工具通过综合操作,那么问题可能与设计加约束的方式(用户问题)或工具处理设计约束的方式(工具问题)有关。

调试此类问题的一种方法会是找到导致崩溃的约束/约束集。这可以通过注释约束然后逐个启用它们来查看工具何时再次崩溃来完成。一旦您有一组引起失败的约束,请参考 UFDM 验证约束及其用法,然后对其进行相应的修改以避免这类崩溃问题。

如果您仍然看到崩溃,请在此处发布您的日志文件  (hs_pidxxxx.log and runme.log) 及详细设计信息。赛灵思论坛:综合板块

其他重要调试步骤及其分析结果:

FSM 推断崩溃问题

我们还看到了在综合 FSM 时工具崩溃的一些问题,将全局设置 -fsm_extraction 设为“off”有助于解决基于 FSM 的崩溃问题。

堆栈溢出引起的崩溃问题:

该工具在堆栈的内存耗尽时可能会崩溃,而且可能会不报告任何情况。

此外,该工具甚至可能不会在运行目录中生成 hs_pidxxxx.日志。

对于与堆栈相关的崩溃,请使用以下命令调用 Vivado 工具:

“vivado -stack 2000”

这样做有助于该工具获得更多可用来执行综合的堆栈内存,并且还可以避免与堆栈相关的崩溃问题。

Windows 操作系统特定的崩溃:

有几种原因会引起特定于 Windows 的崩溃,因此要确保您看到的问题不是 Windows 操作系统的特定问题,请在任一支持的 Linux 操作系统上运行一次。

OOC (Out of Context) 与非 OOC 流程:

我们已经看了一些示例,当工程设置为完全非 OOC(没有 IP、没有 RTL 模块为 OOC)时,整个设计会通过综合。在某些情况下,相反的情况也可行,可通过在 OOC 模式而不是“Global”模式下生成 IP 的输出文件。

文章转载自:赛灵思中文社区论坛

推荐阅读