这篇文章是对sdf3.0协议的理解性翻译,整体内容顺序结构和sdf3.0协议一致,主要是为了协助自己理解后仿真时导入的sdf里的内容。
参考手册:
1.《Standard Delay Format Specification》 Version3.0
2.《Static Timing Analysis for Nanometer Designs:A Practical Approach》,知乎有位博主对《Static Timing Analysis for Nanometer Designs:A Practical Approach》做了一个全文的翻译,链接:静态时序分析圣经翻译计划——汇总篇 - 知乎
目录
sdf是一个通用的数据传输格式,用来在工具和工具之间传递信号的时序信息。
一个设计可以带多个sdf文件,通过annotator将每个sdf指定到设计里特定的区域,它会从指定的层级开始搜索sdf文件中标识的信号,如果指定的层级不对的话,信号找不到,就不能反标上。
sdf 、设计 以及 加载的库 要能对应上。
sdf文件的总体结构:
(DELAYFILE sdf_header cell+)
sdf_header
sdf文件头部信息包含如下部分:
sdf_version = (SDFVERSION "OVI 3.0") // 本文符合的sdf标准版本号(1.0,2.0,2.1,3.0),数字3.0的前后可以有别的字符串,在读取时会被忽略。
design_name = (DESIGN "led") // 记录sdf对应的顶层设计模块的名字
date = (DATE "Thur Sep 26 21:30:29 2021") // 生成sdf文件的日期
vendor = (VENDOR "Acme") // 记录产生sdf的文件 或是公司
program_name = (PROGRAM "Synopsys PrimeTime") // 记录产生sdf文件的软件名字
program_version = (VERSION "version 1.3") // 记录产生sdf文件的软件的版本
hierarchy_divider = (DIVIDER /) // 指定在文件中用哪个层次分隔符(. 或是 /)来分隔路径
voltage = (VOLTAGE 5.5:5.0:4.5) / (VOLTAGE 2::2) // 指定文件中数据计算的电压,由于电压越高延迟越小,所以这个三元组对应着delay的 min:typical:max ,第二组值表示中间那个typical的值被忽略了。
process = (PROCESS "0.65:1.0:1.8") / (PROCESS "1.0::1.0") // 指定文件中数据的流程因子(这个翻译我也不懂什么意思)best:nom:worst
temperature = (TEMPERATURE -25:25:85) / (TEMPERATURE 85::85) // 指定设计的工作环境温度,单位为摄氏度
time_scale = (TIMESCALE 1ns) // 指定文件中数据的单位,值可以为1,10,100或是1.0,10.0,100.0,单位可以为us,ns,ps,值和单位之间可以选择性插入一个空格分隔,如果没有指定这个条目的话,默认为1ns。
举例,总的一个header如下:
(DELAYFILE
(SDFVERSION "OVI 3.0")
(DESIGN "led")
(DATE "Thur Sep 26 21:30:29 2021")
(VENDOR "Acme")
(PROGRAM "Synopsys PrimeTime")
(VERSION "version 1.3")
(DIVIDER /)
(VOLTAGE 5.5:5.0:4.5)
(PROCESS "0.65:1.0:1.8")
(TEMPERATURE -25:25:85)
(TIMESCALE 1ns)
cell
cell 用来指定特定的区域,并包含要应用于那里的时序数据。
cell语法如下:
( CELL celltype cell_instance timing_spec** )
celltype 和 cell_instance 指定设计中的区域,timing_spec 指定时序数据。
一个sdf可以包含大于0的任意数量的cell,只有当来自不同cell的数据应用于设计中的同一区域时,cell的顺序才会起作用。
celltype
celltype = (CELLTYPE "led") // 指定设计或库里模块的名字
cell_instance
cell_instance = (INSTANCE PATH) / (INSTANCE *) // 指定模块例化的路径,如果这里没有指定路径,则默认是反标sdf时指定的层级,这对于将所有 interconnect信号收集到顶层 cell中是非常有用的。通配符的形式可以将指定的时序数据和对应的cell type的所有例化关联(位于反标器指定的层级下的所有cell type对应的例化)。
timing_spec
timing_spec = del_spec || tc_spec || te_spec // 每个cell可以包含0个或多个时序说明,有如下三种关键字定义的时序说明。
del_spec = (DELAY deltype+ ) // DELAY包含用于反标的数据延迟信息和窄脉冲传输数据
tc_spec = (TIMINGCHECK tchk_def+ ) // TIMINGCHECK包含反标时做时序检查的约束数据
te_spec = (TIMINGENV te_def+ ) // TIMINGENV包含用于正标的时序环境和约束信息
一个cell中可以包含多个DELAY、TIMINGCHECK和TIMINGENV,但出于效率考虑,最好一个cell中包含一个DELAY、TIMINGCHECK和TIMINGENV,将所有时序信息都放到自己对应那一个块中。
DELAY
语法:(DELAY deltype+ )
以DELAY关键字开始的时序说明关联 input-to-output paths,input ports,interconnects,and device outputs。
deltype 可以是PATHPULSE 或是 PATHPULSEPERCENT,指定脉冲如何在这个cell中跨路径传播,也可以是 ABSOLUTE 或是 INCREMENT 延时定义,包含应用于cell中的延时值。
deltype ::= ( PATHPULSE input_output_path? value value? )
||= ( PATHPULSEPERCENT input_ouput_path? value value? )
||= ( ABSOLUTE del_def+ )
||= ( INCREMENT del_def+ )
PATHPULSE
PATHPULSE条目指定cell中从input端口到output端口窄脉冲的传输限制,这个限制决定了通过这个cell的输入端口可以传输到它的输出端口的脉冲的宽度。
( PATHPULSE input_output_path? value value? )
input_output_path ::= port_instance port_instance
传输路径的第一个port_instance 是一个 input 或 双向类型的port,第二个port_instance是一个 output 或双向类型的 port。如果input_output_path省略,则指定的值应用到cell中的所有输入输出路径。
第一个value指定了可以从input传输到output的最小脉冲宽度,小于这个值的脉冲都不能传输到output上。
第二个value是x极限值,当脉宽小于x极限值时,output端口会输出不定态,这个值比第一个值大时才会有意义。
PATHPULSE里可以只指定一个值,这个时候等同于两个value相等,其中每一个值都可以是单个的值或一个三元组,但都不允许为负。
举个简单例子:
(DELAY
(PATHPULSE i1 o1 (13) (21))
)
插入图片
如果i1上的输入脉宽小于 13,则输出端口o1上没有输出;
如果i1上的输入脉宽介于13-21之间,则输出端口o1上输出x态;
如果i1上的输入脉宽大于等于21,则输出端口o1上正常输出;
以上是基于一个输入信号的,通常输出端口的信号是由多个输入信号进行一定处理后输出的,每个输入到输出都有自己的limit,sdf假定 分析工具会使用中断脉冲的那条path上的数据来控制脉宽在输出端口上的显示。
再举个例子:
(DELAY
(ABSOLUTE
(IOPATH a y (45) (37))
(IOPATH b y (43) (35))
)
(PATHPULSE a y (13) (24))
(PATHPULSE b y (15) (21))
)
插入图片
以上是一个二输入的与门,由于a-y和b-y之间delay的差距,所以最终输出脉宽比 a 和 b重叠的区域要少10ns,b-y的path导致了脉宽的终止(b先拉低),所以分析工具会使用b-y的pathpulse数据来控制最终脉宽的输出,如果脉宽 < 15ns,则不输出,如果脉宽 >= 15ns,< 21ns,则输出x态,如果脉宽 >= 21ns,则正常输出。
如果sdf中没有指定cell中的PATHPULSE,则分析工具默认 path delay就是它的PATHPULSE里的两个值,如果输出端口上的脉冲宽度小于 path delay,则不会输出,否则就会输出。
PATHPULSEPERCENT
PATHPULSEPERCENT条目功能等同于PATHPULSE,只是它的值是input-to-output path的path delay的百分比。
( PATHPULSEPERCENT input_output_path? value value? )
这两个的value都不能超过100,同样,第二个值要大于第一个值,x态功能才会生效。
举例:
(DELAY
(ABSOLUTE
(IOPATH a y (45) (37))
)
(PATHPULSEPERCENT a y (25) (35))
)
在这个例子中,a-to-y的最小通过脉冲宽度为 25%*path delay(a-y),x极限脉冲宽度为 35% * path delay(a-y)。如果IOPATH中指定了输入到输出的多个变化的delay,分析工具会选择传输脉冲的delay。因此,对于一个脉冲输出是拉高的pulse,脉冲从高到低表示一次传输,百分比对应的path delay就是从高到低变化的路径的delay(嗯。。描述得不是那么懂。。),在上面的例子中,1->0传输的delay是37,所以最小通过脉冲宽度为 25%*37,x极限脉冲宽度为 35% *37。同样的,多个input的,使用导致脉宽终止的path的delay来计算脉宽限制。
ABSOLUTE
ABSOLUTE条目引入delay值,在反标的时候替代设计中已存在的延迟。
( ABSOLUTE del_def+ )
del_def中包含了数据和对信号的描述。
举例:
(CELL (CELLTYPE "DFF")
(INSTANCE a.b.c)
(DELAY
(ABSOLUTE
(IOPATH (posedge clk) q (22:28:33) (25:30:37))
(PORT clr (32:39:49) (35:41:47))
)
)
)
可以在absolute delay中指定负延迟,但是,要注意,有些分析工具不支持负延迟,会把它们设置为0。
INCREMENT
INCREMENT条目引入delay值,在反标的时候会把指定的延时叠加到设计中已有的delay上。
( INCREMENT del_def+ )
del_def和上面一样,后面会详细介绍。
举例:
(CELL (CELLTYPE "DFF")
(INSTANCE a.b.c)
(DELAY
(INCREMENT
(IOPATH (posedge clk) q (-4::2) (-7::5))
(PORT clr (2:3:4) (5:6:7))
)
)
)
在INCREMENT中可以使用负值,这种情况下,设计中的delay就会减少,可能因为INCREMENT导致负延迟,注意 不是所有的工具都支持负延迟,有些会把它们置为0。
Delay Definition Entries
这里详细描述上面的del_def,ABSOLUTE 和 INCREMENT中的del_def是用同一组delay结构来描述的。
del_def ::= ( IOPATH port_spec port_instance ( RETAIN delval_list )** delval_list* )
||= ( COND QSTRING? conditional_port_expr
( IOPATH port_spec port_instance ( RETAIN delval_list )** delval_list* ) )
||= ( CONDELSE ( IOPATH port_spec port_instance ( RETAIN delval_list )** delval_list* ) )
||= ( PORT port_instance delval_list )
||= ( INTERCONNECT port_instance port_instance delval_list )
||= ( DEVICE port_instance? delval_list )
从上面可以看到,每一个条目里都有delval_list,先介绍一下这个delval_list。
delval_list
delval_list里包含了具体的delay数据。
delval_list ::= delval
||= delval