延迟反标注是设计者根据单元库工艺、门级网表、版图中的电容电阻等信息,借助数字设计工具将延迟信息标注到门级网表中的过程。利用延迟反标注后的网表,就可以进行精确的时序仿真,使仿真更接近实际工作的数字电路。
无论是进行 IC 设计还是 FPGA 开发,时序仿真都是必不可少的。
下面,说明延迟反标注在该流程中是怎么使用的,权当复习与巩固。
此过程示意图如下,标黄部分表示数字设计流程中可以增加的操作说明。
SDF (Standard Delay Format),标准延时格式文件,常用延迟反标注。该文件包含了仿真用到的所有 IOPATH,INTERCONNECT、TIMING CHECK 等延迟时间和时序约束的参数。下面就简单的介绍下 SDF 文件。
SDF 文件用关键字 DELAYFILE 声明,并包含 DESIGN、DATE 等关键字信息。
延迟时间和时序约束参数均在 CELL 内说明。
SDF 文件就是由文件声明信息和很多个不同的 CELL 组成的,格式如下。
(DELAYFILE
(DESIGN "top")
(DATE "Love Sep 7 11:11:11 2017")
......
(TIMESCALE 1ns)
(CELL
......
)
(CELL
......
)
......
)
SDF 文件中的延迟类型包括 cell delay 和 wire delay。cell delay 指逻辑门单元器件内部的延迟,wire delay 是指器件之间通过 wire 互联的延迟。
cell delay 描述如下,定义了 module "and_gate" 中输入端口(A/B)与输出端口(Z)的上升延迟和下降延迟,并指定了最小值和最大值。
(CELL
(CELLTYPE "and_gate") //module 名字
(INSTANCE u_and) //例化名字,如果多层次访问需要指定访问层次
(DELAY
(ABSOLUTE
(IOPATH A Z (1.5::1.8) (1.3::1.7)) //上升延迟最小值1.5,最大值1.8
(IOPATH B Z (1.5::1.8) (1.3::1.7)) //下降延迟最小值1.3,最大值1.7
)
)
)
wire delay 描述如下,定义了在 module "top" 中,从 u_and 输出端到 u_dt 输入端的上升延迟和下降延迟,并指定了最小值和最大值。
一般 RTL 级仿真或综合出的门级网表是可以忽略 wire delay的,因为后端还需要重新布局布线。布局布线后的网表就接近真实的电路,此时就需要考虑 wire delay。
(CELL
(CELLTYPE "top") //module 名字
(INSTANCE) //如果是顶层设计模块,可忽略例化名字
(DELAY
(ABSOLUTE
(INTERCONNECT u_and.Z u_dt.D (0.500::0.751) (0.400::0.551))
//(INTERCONNECT u_and/Z u_dt/D (0.500::0.751) (0.400::0.551))
//层次访问符号,有的编译器支持".",有的编译器支持"/",这里需要注意
)
)
)
CELL 中还可以用关键字 COND 指定条件延迟。同时,也可以在 CELL 内做时序检查。一个 D 触发器的延迟说明及时序检查举例如下。
(CELL
(CELLTYPE "d_gate")
(INSTANCE u_dt)
(DELAY
(ABSOLUTE
// D=1时 上升延迟为1.3-2.3, 下降延迟为1.5-2.2
(COND D==1'b1 (IOPATH CP Q (1.3::2.3) (1.5::2.2)))
// D=0时 上升延迟为1.2-2.1, 下降延迟为1.4-2.0
//此处只是为了说明 COND 的用法,D=1时下降延迟参数不可能用到
// D=0时上升延迟参数也不可能用到
(COND D==1'b0 (IOPATH CP Q (1.2::2.1) (1.4::2.0)))
)
)
(TIMINGCHECK
(SETUP D (posedge CP) (0.8::1))
//setup check, D-CP 时间小于0.8或1时,便打印 violation
)
)
Verilog 提供了系统函数 $sdf_annotate 去调用 SDF 文件完成延迟反标注的过程。使用格式如下:
$sdf_annotate ('sdf_file'[, module_instance] [,'sdf_configfile'][,'sdf_logfile'][,'mtm_spec'] [,'scale_factors'][,'scale_type']);
这里,sdf_file 必须指定,其余参数可选。
这里只对前几个常用的参数进行说明。
下面使用 specify 进行简单的时序仿真,以便与使用 SDF 文件进行时序仿真做对比。
一个用 specify 指定延迟的与门逻辑描述如下:
- module and_gate(
- output Z,
- input A, B);
-
- assign Z = A & B ;
-
- specify
- specparam t_rise = 1.3:1.5:1.7 ;
- specparam t_fall = 1.1:1.3:1.6 ;
- (A, B *> Z) = (t_rise, t_fall) ;
- endspecify
-
- endmodule
一个用 specify 指定延迟的 D 触发器描述如下:
- module d_gate(
- output Q ,
- input D, CP);
-
- reg Q_r ;
- always @(posedge CP)
- Q_r <= D ;
- assign Q = Q_r ;
-
- specify
- if (D == 1'b1)
- (posedge CP => (Q +: D)) = (1.3:1.5:1.7, 1.1:1.4:1.9) ;
- if (D == 1'b0)
- (posedge CP => (Q +: D)) = (1.2:1.4:1.6, 1.0:1.3:1.8) ;
- $setup(D, posedge CP, 1);
- endspecify
-
- endmodule
顶层模块描述如下,主要功能是将与逻辑的输出结果输入到 D 触发器进行缓存。
- module top(
- output and_out,
- input in1, in2, clk);
-
- wire res_tmp ;
- and_gate u_and(res_tmp, in1, in2);
- d_gate u_dt(and_out, res_tmp, clk);
-
- endmodule
testbench 描述如下,仿真时设置 "+maxdelays",使用最大延迟值。
- `timescale 1ns/1ps
- module test ;
- wire and_out ;
- reg in1, in2 ;
- reg clk ;
-
- initial begin
- clk = 0 ;
- forever begin
- #(10/2) clk = ~clk ;
- end
- end
-
- initial begin
- in1 = 0 ; in2 = 0 ;
- # 32 ;
- in1 = 1 ; in2 = 1 ;
- # 13 ;
- in1 = 1 ; in2 = 0 ;
- end
-
- top u_top(
- .and_out (and_out),
- .in1 (in1),
- .in2 (in2),
- .clk (clk));
-
- initial begin
- forever begin
- #100;
- if ($time >= 1000) $finish ;
- end
- end
-
- endmodule // test
仿真时序如下所示,由图可知:
综上所述,仿真结果符合设计参数。
保持关于 SDF 文件的例子中涉及的参数不变,将多个 CELL 说明整合成完整的 SDF 文件,命名为"simple_test.sdf"。在 testbench 中加入以下语句,将 SDF 文件中的延迟信息反标注到设计的模块 top 中,重新进行时序上的仿真。
initial begin
$sdf_annotate("../rtl/simple_test.sdf", u_top, , "sdf.log", "MAXIMUM", ,);
end
仿真时序及 log 打印信息如下,由图可知:
综上所述,仿真结果符合设计参数,但是时序存在 violation。主要原因是因为与门输入端的数据和触发器时钟是异步不相关的。为解决此类异步问题,请参考下一章节《4 章:同步与异步》。
需要说明的是:
与 specify 块语句相比,SDF 文件还可以指定模块间 wire delay。一般来说,使用 SDF 文件指定版图级的网表 timing 信息最接近实际数字电路,相比 rtl 或综合出的门级网表,此版本的 timing 是最差的。SDF 文件指定模块内路径延迟时,原模块的 specify 块必须保留,且 specify 块与 SDF 文件中指定的延迟的条件、类型等均需一致,延迟值可以不同。例如在 specify 块中无条件指定延迟:
(A => Z) = (1.3, 1.7) ;
在 SDF 文件中指定条件延迟:
(COND A==1'b1&&B==1'b1 (IOPATH A Z (1.5::1.8) (1.3::1.7)))
则在编译阶段就会报告"IOPATH from A to Z is not found."的 SDF Warning。SDF 文件设置的延迟是无效的。此处 SDF 文件也应该使用无条件的方法指定路径延迟。本次只是为了介绍 SDF 文件及其用法而手动编写的 SDF 文件。实际上 SDF 文件都是由设计人员借助 IC 设计工具(例如 PrimeTime)生成的,上一条注意事项也无需太过担心,调试时注意就好。一般数字设计的门级网表数量巨大,人为写 SDF 文件也不切实际。