驯顺多重驱动

BY Ajay Petley

注意:本文所有内容皆来源于Xilinx工程师,如需转载,请写明出处作者及赛灵思论坛链接并发邮件至cncrc@xilinx.com,未经Xilinx及著作权人许可,禁止用作商业用途。

多重驱动定义:

具有两个或更多个源的网络或信号被称为多重驱动场景。

为何需要解决多重驱动场景?

多重驱动的存在属于设计错误,最终值可能难以确定。

因此综合工具会针对具有多重驱动的网络或信号发出错误或警告。在 Vivado 综合工具中将标记“严重警告 (Critical Warning)”。如果不加以解决,那么“opt_design”会标记“错误 (Error)”。

Vivado 报告多重驱动场景的方式如下:

Vivado 会在综合阶段识别具有多重驱动的网络或信号。

它会针对设计中具有多重驱动的网络标记 Critical Warning (SYNTH 8-6859)。

它还会打印一个表,其中包含设计中多重驱动网络的数量。

例如:

示例 1:多重驱动样本


此处 out1 是在顺序块 B1 和 B2 中驱动的,这就导致出现了多重驱动状况。

同样,由组合逻辑和/或顺序逻辑驱动的连线也会导致出现多重驱动场景。

对于总线,由多个源驱动的任意比特都会导致出现多重驱动场景。

注:对于具有不同源的专用比特,Vivado 不会标记多重驱动。

示例 2:多重驱动、三态和层级注意事项

具有三态多重驱动的网络不被视作为多重驱动状况。

通常,任意给定时间点只能有单一源处于活动状态。


子模块中存在的三态驱动将被提取出来并划归最高层级。

示例 3:其中一个驱动属于用户定义的常量的多重驱动场景

在此示例中,其中一个网络驱动为常量。

在此类情况下,该工具会遵循常量驱动运行而忽略另一个驱动。

该工具仍然会发出清晰的 Critical Warning。


示例 4:VIO/ILA 标记调试和多重驱动注意事项

在 Vivado 中,如果不同的总线比特由不同子模块驱动,则不会将其视为由多个源驱动。由于每个比特都有自己的专用驱动,因此不存在争用。


但在此示例中,如果应用以下任一层级限制或类似限制,Vivado 就会将其视作为多重驱动状况。

  • 在子模块上应用“keep_hierarchy”
  • 在子模块上应用“don’t_touch”属性
  • 在子模块的任意端口上应用“mark_debug”属性
  • 将子模块的任意端口连接到 ILA/VIO 调试核


发生此状况的原因是用户未严格遵循相关准则来保持子模块例化的边界。

实例 U1 仅驱动 out1[0],out1[1] 连接到 GND。

实例 U2 仅驱动 out1[1],out1[0] 连接到 GND。

由于 out1 的每个比特都具有两个驱动,因此 Vivado 将此视作为多重驱动状况。

调试方法:

有时根据生成的消息难以确定多重驱动的准确名称。

当驱动适用于工具生成的网络而不是用户定义的网络时,就会发生此类状况。

您需要通过搜索具有多个驱动的网络来查找多重驱动网络的驱动。

您可以使用以下 Tcl 命令:

get_nets -hierarchical -top_net_of_hierarchical_group -filter { DRIVER_COUNT >  1 }


并且有时最好运行 opt_design,因为只要综合中存在多重驱动,“opt_design”就会发出 Errors 标记。但由于设计经过进一步优化,并且当前所有块(DCP、调试模块)都可用,因此 opt 中的多重驱动错误可能更精确。

受篇幅所限,本文并未涵盖所有场景。以下列出部分其他场景,将来可根据需要进一步详细讲解。

非对称 3D RAM:在 TDP 3D RAM 中,不受支持的模板可能导致出现多重驱动场景。

接口 modport:接口中已定义信号但未将其定义为 modport,此类信号将被作为 inout 来处理。这可能会导致出现多重驱动场景。

总结:

至此,相信您应该已经了解了可能发生多重驱动的各种场景,并且已清楚认识到需要修改 RTL 才能继续运行流程。

来源:赛灵思

推荐阅读