3. 标准延迟格式(SDF):SDF文件的结构、反标的概念与原理

后仿真里有个绕不开的东西——SDF。说白了,它就是一张“延迟清单”,把每个门、每根线的延迟时间写清楚。仿真器拿到这张清单,照着填进去,你的电路才算真正“跑在硅片上”。

我刚开始接触后仿时,总觉得SDF就是个黑盒子。直到有一次,一个时序违例怎么都复现不了,最后发现是SDF反标没成功,仿真器用的全是零延迟。嗯,从那以后,我对SDF就格外上心了。

3.1 SDF文件长什么样?

SDF是标准格式,由IEEE 1497定义。它不依赖任何工具,所有EDA工具都认。你打开一个SDF文件,会看到类似这样的结构:

(DELAYFILE
  (SDFVERSION "3.0")
  (DESIGN "top")
  (DATE "2024-01-15")
  (VENDOR "SomeFoundry")
  (PROGRAM "PrimeTime")
  (VERSION "2022.06")
  (DIVIDER /)
  (VOLTAGE 1.08:1.20:1.32)
  (PROCESS "tt")
  (TEMPERATURE -40:25:125)
  (TIMESCALE 1ps)

  (CELL
    (CELLTYPE "DFFQ_X1")
    (INSTANCE u_top/u_core/u_reg0)
    (DELAY
      (ABSOLUTE
        (IOPATH CP Q (0.12::0.15) (0.10::0.13))
        (IOPATH D Q (0.08::0.11) (0.07::0.09))
      )
    )
    (TIMINGCHECK
      (SETUP D CP (0.05::0.07))
      (HOLD D CP (0.03::0.04))
      (WIDTH CP (0.20::0.25))
    )
  )
)

这个结构其实很清晰。顶层是DELAYFILE,里面包含文件头信息——版本、设计名、工艺角、时间精度等。下面是一个个CELL块,每个块对应一个标准单元实例。

每个CELL块里,DELAY部分描述路径延迟,TIMINGCHECK部分描述时序约束。延迟值通常给三个数:min:typ:max,对应PVT变化范围。

关键点:SDF里的延迟值单位由TIMESCALE指定。上面例子是1ps,那0.12就代表120fs。单位搞错了,后仿时序全乱套。我见过有人把ns当ps用,结果仿真波形惨不忍睹。

3.2 SDF的核心结构拆解

咱们把SDF的几个关键部分拆开看看。

部分 关键字 说明
文件头 SDFVERSION, DESIGN, DATE, VENDOR, PROGRAM, VERSION, DIVIDER, VOLTAGE, PROCESS, TEMPERATURE, TIMESCALE 描述SDF的元信息,包括工艺角、工具版本、时间精度等
单元实例 CELL, CELLTYPE, INSTANCE 指定哪个标准单元、哪个实例路径
延迟描述 DELAY, ABSOLUTE, IOPATH, COND, PATHPULSE 定义输入到输出的路径延迟,可带条件
时序检查 TIMINGCHECK, SETUP, HOLD, WIDTH, PERIOD, RECOVERY, REMOVAL 定义建立时间、保持时间、脉冲宽度等约束
互连线延迟 INTERCONNECT, PORT, NETDELAY 描述线网延迟,用于反标互连线

这里有个容易混淆的地方:IOPATH和INTERCONNECT的区别。前者是单元内部的路径延迟,后者是单元之间的连线延迟。STA工具会分别计算,然后合并到SDF里。

我的习惯:拿到SDF后,先看一眼TIMESCALE和DIVIDER。DIVIDER决定了实例路径的分隔符——用/还是.。如果SDF里用/,但你的网表用.,反标就会失败。这个坑我踩过,查了两天才发现。

3.3 反标(Back-annotation)的概念

反标,英文叫Back-annotation。名字听着玄乎,其实意思很简单:把SDF里的延迟信息“贴”到仿真模型上。

你想想看,RTL仿真时,门级模型里的延迟都是零,或者是一个默认值。这跟实际芯片差太远了。反标就是干这个的——把STA算出来的真实延迟,写回到仿真模型里。

反标的过程大致是这样:

  1. 解析SDF:仿真器读入SDF文件,解析成内部数据结构。
  2. 路径匹配:把SDF里的INSTANCE路径,跟网表里的实例路径一一对应。
  3. 延迟赋值:把解析出的延迟值,赋给对应的时序路径和时序检查。
  4. 报告反馈:输出反标结果,告诉你哪些成功了,哪些失败了。

在仿真器里,反标命令通常是这样的:

// Verilog中反标SDF
initial begin
  $sdf_annotate("top.sdf", top, , "sdf_report.log");
end

// 或者用VCS的命令行选项
// vcs -sdf top:top:top.sdf ...

$sdf_annotate是Verilog标准系统函数。第一个参数是SDF文件路径,第二个参数是实例作用域。第三个参数可以指定配置,第四个参数是日志文件。

我曾经踩过的坑:有一次反标后仿真跑得飞快,我以为时序没问题。结果一查日志,发现90%的路径反标失败,仿真器默默用了零延迟。从那以后,我每次反标完第一件事就是检查日志,看有没有WARNING或ERROR。反标成功率低于100%时,一定要搞清楚为什么。

3.4 反标的原理:仿真器怎么“贴”延迟?

反标的核心是路径匹配。仿真器拿到SDF后,会遍历每个CELL块,提取INSTANCE路径,然后在网表里找对应的实例。

匹配成功后,仿真器会做两件事:

  • 更新路径延迟:把IOPATH里的值,赋给实例的specify块里的路径。
  • 更新时序检查:把TIMINGCHECK里的值,赋给specify块里的$setup、$hold等系统函数。

举个例子,标准单元库里的DFFQ_X1,它的Verilog模型里通常有specify块:

specify
  specparam CP到Q的上升延迟 = 0.15;
  specparam CP到Q的下降延迟 = 0.13;
  specparam D到CP的建立时间 = 0.07;
  specparam D到CP的保持时间 = 0.04;

  (CP => Q) = (CP到Q的上升延迟, CP到Q的下降延迟);
  $setup(D, posedge CP, D到CP的建立时间);
  $hold(posedge CP, D, D到CP的保持时间);
endspecify

反标后,这些specparam和时序检查值,会被SDF里的实际值替换。仿真器在仿真时,就用这些新值来计算延迟和检查时序。

注意:反标不是简单的字符串替换。仿真器会做类型检查、单位转换、条件匹配。比如COND条件路径,仿真器需要判断当前仿真状态是否满足条件,再决定用哪个延迟值。

3.5 SDF反标的完整流程

为了让你更直观地理解,我画了一张流程图。

SDF反标完整流程 STA工具生成SDF 仿真器读入SDF文件 解析CELL块,提取路径 路径匹配(INSTANCE查找) 匹配成功 → 更新延迟 匹配失败 → 报告WARNING 输出反标报告 关键检查点 1. TIMESCALE单位 2. DIVIDER分隔符 3. 反标成功率

这个流程里,最关键的步骤是路径匹配。匹配失败的原因通常有几种:

  • 路径分隔符不一致:SDF用/,网表用.,或者反过来。
  • 实例名不匹配:SDF里写的是u_top/u_core/u_reg0,但网表里是u_top.u_core.u_reg0(分隔符问题),或者名字拼写有差异。
  • 层次不匹配:SDF是从某个子模块提取的,但反标时作用域设错了。
  • 单元类型不匹配:SDF里是DFFQ_X1,但网表里例化的是DFFQ_X2,延迟模型不同。

我的经验:反标失败时,先检查DIVIDER。很多工具默认用/,但有些网表生成工具用.。在$sdf_annotate里可以指定sdf_path_separator参数来调整。另外,我习惯在反标命令里加上sdf_report参数,把详细日志输出到文件,方便排查。

3.6 反标模式:增量 vs 覆盖

仿真器支持两种反标模式:

模式 说明 适用场景
覆盖模式 用SDF里的值完全替换模型里的默认值 标准后仿,所有延迟来自STA
增量模式 只更新SDF里指定的路径,其他路径保持原值 ECO后只反标修改部分,或混合不同工艺角的SDF

我个人习惯用覆盖模式做标准后仿。增量模式在ECO验证时很有用——只反标修改过的单元,其他保持原样,能节省仿真时间。

3.7 反标后的验证检查

反标完成后,别急着跑仿真。先做几个检查:

  1. 检查反标日志:看有没有WARNING或ERROR。反标成功率最好100%。
  2. 检查延迟值:随机挑几个路径,对比SDF里的值和仿真器实际使用的值。可以用$display打印路径延迟来验证。
  3. 检查时序检查:确认建立时间、保持时间等约束已经正确反标。
  4. 检查互连线延迟:如果SDF包含INTERCONNECT,确认它们也被正确反标了。

我曾经踩过的坑:有一次反标日志显示100%成功,但仿真波形明显不对。后来发现,SDF文件本身有问题——STA工具生成时用了错误的工艺角。所以,反标成功不代表延迟值正确。我建议在仿真脚本里加一段检查代码,打印几个关键路径的延迟值,跟STA报告对比一下。

好了,关于SDF的结构和反标原理,就讲到这里。记住一句话:反标是后仿真的基石。反标没做好,后仿结果就是空中楼阁。每次跑后仿前,花5分钟检查反标日志,能省下后面几天的调试时间。