后仿真,是对经过综合/布局布线后的门级网表进行仿真,与前仿真对rtl代码进行仿真,找出功能上的缺陷相比,后仿真主要检查时序上的问题;相比较理想状况下的rtl仿真(功能仿真、前仿真),后仿消耗时间更多,在可读性差的cell里穿梭行走,debug的难度大大增强了,而一般我们在做后仿的时候,往往也意味着离tapeout的时间很急迫了

后仿的步骤:

1、用时序计算工具生成时序信息存储在SDF文件中

2、添加 notiming_check 列表文件到仿真工具选项中

3、将SDF文件反标到设计中:在tb_top文件中加入语句 initial $sdf_annotate

SDF文件

 SDF(Standard Delay Format)文件是把布局布线过程中器件延时和线延时的信息保留下来,据此就可以在路径时序分析时将整条路径的时序计算出来,再判断时序约束条件就能知道是否满足时序要求。SDF文件包含设计中所有单元的时序信息,它为仿真门级网表提供时序信息

SDF文件包括设计中每个单元的时序信息,基本的时序数据由以下几部分组成:

(1)IOPATH延迟

(2)INTERCONNECT延迟

(3)SETUP时序检查

(4)HOLD时序检查

 使用VCS读取SDF文件时,会将延迟值“反向标注(back-annotates)”到设计中,即在源文件中添加或者更改延迟值,反标SDF文件有两种方法,一种作为elaboration的选项指定,另一种是在bench中调用系统函数$sdf_annotate来完成;

(1)作为elaboration的选项

-sdfmin|typ|max: instance_name :file.sdf

如vcs-sdf min: top.i_test: test.sdf

 (2)使用$sdf_annotate系统任务进行反标,其使用格式如下:

$sdf_annotate (“sdf_file”[, “module_instance”] [,“sdf_configfile”][,“sdf_logfile”][,“mtm_spec”] [,“scale_factors”][,“scale_type”]);

其中:

“sdf_file”:指定SDF文件的路径

“module_instance”:指定反标设计的范围(scope)

“sdf_configfile”:指定SDF配置文件,一般缺省

“sdf_logfile”:指定VCS保存error 和warnings消息的SDF日志文件。也可以使用+sdfverbose runtime option来打印所有反标消息

“mtm_spec”:指定延迟类型"MINIMUM(min)", "TYPICAL(typ)“或者"MAXIMUM(max)”,“TOOL_CONTROL(default)”。

“scale_factors":分别指定min:typ:max的缩放因子,默认是"1.0:1.0:1.0"

“scale_type”:指定缩放之前延迟值得来源,“FROM_TYPICAL”,“FROM_MIMINUM”, “FROM_MAXIMUM"和"FROM_MTM” (default).

这里除了sdf_file必须给出外,其他参数可以使用默认值,如:

$sdf_annotate(“test.sdf”);

要说明下参数scale_type,sdf文件中时序信息都会由3个数字组成,分别对应是minimum,typical,maximum三种情形下的延迟(当然,有时候会只有minimum和maximum的情况,那么typical的延迟没有就省略)

scale_type的可取值为:

FROM_MINIMUX
选择SDF文件中mininum timing,所谓的min就是指组合逻辑的延时最小,这个sdf侧重于 hold time 的检查

FROM_TYPICAL
选择SDF文件中typical timing

FROM_MAXIMUM
选择SDF文件中maximum timing,所谓max就是指组合逻辑的延时最大,这个sdf 侧重于 setup time的检查

FROM_MTM
系统默认

反标完成后,可以从log中看到这样一句话:

Annotating SDF file "***.sdf" ... Done
 

tfile 文件

在跑后仿时,有些路径可以不做timing check,比如同步器的第一个DFF,因为通常是对异步信号进行同步,同步器的第一个DFF通常可能出现setup或hold违例,如下:

 这个时候就需要将不需要 check 的路径写在tfile 文件中来告诉仿真器,上面的例子可以通过以下两种方式来实现:

方式1:

    ncverilog -input  aaa.tcheck ...

    aaa.tcheck文件中:

    tcheck -off   u_top.syna_d1_reg

     tcheck -off   u_top.synb_d1_reg

    ...

    run

    (若不加run,则ncsim在执行完所有的tcheck指令后自动停止了)

    方式2:

    ncverilog -tfile   aaa.tcheck ...

     aaa.tcheck文件中:

    PATH  u_top.syna_d1_reg -tcheck

    PATH  u_top.synb_d1_reg -tcheck
 

 对于VCS 和 XRUN两个编译器,文件的写法和仿真参数存在一些区别:

编译器

解决步骤

cadence的NC

1.  NC仿真增加参数

-tfile notimingcheck.tfile。

2.  编辑notimingcheck.tfile文件

PATH tb.dut.u_dff2_reg –tcheck

synopsys的vcs

1. vcs仿真增加参数

+optconfigfile+notimingcheck.cfg。

2.  编辑notimingcheck.cfg文件

instance {tb.dut.u_dff2_reg} {noTiming};

另外还可以通过 module, tree指定对象,但只能是module name,不能有层次。

如果有多个异步D触发器,就写多行,一行写一条约束

时序违例的一些debug 经验

1.查看是否为异步路径

如果是异步路径,理应将其加到notiming_check列表中。

2.查看VCS的输入(包括网表和SDF文件)是否正确

不光是VCS,只要是跟工具相关的流程,遇到异常,我们都需要先确保工具的输入信息是准确无误的,才能继续往下debug。而后仿的输入主要就是网表和SDF文件。对于这两个文件,我们要检查它们的路径是否正确,网表和SDF文件的版本是否对应得上。

3.查看后仿中时钟时钟频率是否跟STA一致

在不规范的流程中经常会看到,后仿的频率与STA分析的频率不一致。所以遇到违例时,我们要先去查看后仿的时钟频率,如果频率比STA分析的频率还要高,那setup出问题也是理所应当的。

4.查看STA报告,timing是否clean

后仿时钟频率跟STA一致没问题的前提是STA已经timing clean。但是在实际情况下,尤其是在MPW项目中,由于项目进度紧,STA可能会将某些违例放过。例如,系统时钟200M,但是有点小违例,而时钟的精度又可以微调,这时候就有可能直接放过。因此,我们要跟STA owner确认这事,并根据实际情况来调整后仿的时钟频率。

5.对比STA中path的delay与波形的delay是否一致

当前面步骤都确保无误后,这时就要考虑是不是吐SDF的过程中出现了什么幺蛾子,例如手残将derate值改了。检查这个的方法也很简单,直接请STA owner把相应路径报出来,然后跟后仿波形的延时对比,这时很大可能是对应不上的。所以接下来的事情就是STA owner的事情了,我们只需要坐等更新SDF

6. 没有复位的寄存器

 一般情况下,设计里面的寄存器都要有复位端。但是,别忘了,后仿不仅仅包括设计的网表,还有各种model,比如analog model,这些model可能因为种种原因,存在没有初值没有复位的寄存器信号。这些寄存器在后仿时候往往给我们造成很大的麻烦

reg rg_a, rg_b;
always @(posedge clk) begin
  rg_b <= rg_a;
end

解决方案:
  我们在testbench中通过force-release的方式对寄存器赋初值,因为变量是reg类型的,所以只要赋初值后,在没有其他条件触发时,会一直保持force进去的值

7. 没有驱动的Pad口的高阻信号传递到设计内部
  一般设计的顶层会有不少三态门的io口,当我们在bench中例化设计时,一定要注意这些三态门,除了只能使用wire类型的信号进行连接外,还要考虑没有驱动情况下的上拉/下拉。
如果忽略了上拉/下拉,在功能仿真时一般不会遇到问题,但是后仿时’z的状态传入设计,便悄悄埋下个雷,某个门的输出就会变成x,并最终导致仿真停下来。
  解决方法呢,很简单,在bench中连接设计时,将三态门连接的信号加个上拉/下拉就好了

wire scl;
dut i_dut(.scl(scl));
pullup(scl);

 如果其他地方已经占用了pullup怎么办呢?没关系,pullup还有不同强度,选个强度弱的,这样即便其他地方也会有上拉/下拉,也不影响了。
  上面的上拉语句加上强度等级,即:pullup(weak1) p0 (scl)

 8. 信号取反
  当我们用网表进行后仿时,在testbench中驱动或者监测的DUT中的信号很可能是一个取反的信号。特别是端口上的信号,名字都没变,明明叫rstb的那货,行为上却像个rst。并不是设计人员粗心大意,而是DC和ICC这样的工具捣的鬼。
  特别可恨地是,一个多比特数据信号,某个比特被悄悄取了反,稍不留神想和前仿对比调试时,连数据位置都定位不准~往往也是让验证工程师哑巴吃黄连了
 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐