MChip 时序反标后仿真时遇到的若干问题

在 MChip 后仿真时遇到了若干问题使仿真无法正常进行,现将问题及解决方法总结如下。

仿真模型中的 specify 块

仿真模型(如 Standard Cell、IO PAD 和 SRAM)中,必须具有 specify block,否则时序反标无法生效。在 SMIC180 的 Standard Cell 模型(scc018ug_hd_rvt.v)中,可以看到类似以下形式的代码:

`ifdef functional  //  functional //

`else
    specify
        // arc I --> Z             
        (I => Z) = (1.0,1.0);
        $setuphold(posedge CK, negedge D, 1.0, 1.0, NOTIFIER);
    endspecify
`endif // functional //
 

以上代码中的 specify 块中定义了模块 pin 到 pin 之间的延时,以及定义了 setup、hold 时序检查。注意 specify 块中定义的检查数据值(例如以上代码中的 1.0)只是一个用于占位的默认值,实际值是在 sdf 文件中指定的。这些检查都只在带时序反标的仿真中有用,在门级行为仿真中是没有用的,必须关掉。

以上代码中的 ifdef 块检查定义了 functional 宏,如果定义了该宏,就会忽略 specify 块。我在行为仿真时,可以打开 functional 宏(从而关闭 specify 块);在时序反标仿真时必须要关闭此宏,使 specify 块生效,否则时序反标会失败。

实际上,为了避免出错,我们不使用 functional 宏来控制是否打开 specify 块;更简单的方式是在行为仿真时,为 VCS 添加 +nospecify+notimingcheck 选项,就可以关闭所有时序检查。

本次后仿遇到的问题是,我在一个 Verilog 模型文件中添加了 functional 宏,没有去除,使文件中的 specify 块全部失效,时序反标标不上(症状是 VCS 大量提示 Warning-[SDFCOM_IANE] IOPATH Annotation Not Enabled. )。将多余的 functional 宏去除,就解决了这个问题。

sdf 文件的指定方式

有两种方式来指定 VCS 使用 sdf 文件:在 Verilog 代码中使用 $sdf_annotate 语句,或在 VCS 编译时指定 -sdf 选项。我认为更简单、便捷的方式是使用后者,在编译时只需使用 -sdf min|typ|max:instance_name:file.sdf 的格式指定文件和模块路径即可,例如 -sdf max:tb_test.dut:mchip.sdf

在 sdf 文件中,指定延迟值的字段格式为 (1.1:2.2:3.3)(具体如下图),其中 1.1 为最小值,2.2 为典型值,3.3 为最大值。

需要注意的是,后端给出的 sdf 文件中,可能并没有指定 typical 值,而只指定了 max 和 min 值,例如 (0.068::0.077)。此时在 VCS 编译时的 -sdf 选项中,第一个选项就不能使用 typ,而必须用 minmax,否则时序反标会失效。本次后仿就因为这个问题,折腾了很久都无法反标,最后才发现是这个原因。

时序违例时的触发器行为

如果后端实现时满足时序约束,那么理论上不应当出现时序违例(即所有寄存器都满足 setup 和 hold 条件)。但有一个例外——对于跨时钟域的异步寄存器,可能有时会发生时序违例的情况:这是正常的,因为这些寄存器的 D 端口和 CLK 端口并非处在同一个时钟域;跨时钟域的信号一般需要两级或更多级的触发器来同步,来规避首个触发器时序违例带来的 meta-stable 问题。

在仿真时,对于这些异步触发器,虽然时序违例是预期行为,但 VCS 会将输出值置为 X,导致 X 态扩散,仿真无法继续进行。我们在 VCS 编译时需要添加上 +no_notifier 选项,使 VCS 不要将信号变为 X,更好模拟硬件真实行为。

CC BY-SA 4.0 本作品使用基于以下许可授权:Creative Commons Attribution-ShareAlike 4.0 International License.

WordPress Appliance - Powered by TurnKey Linux