4、I/O接口时序:输入延迟约束与输出延迟约束

说到I/O接口时序,很多刚入行的朋友会觉得头疼。其实说白了,这就是芯片和外部器件之间的「握手协议」怎么在时序上体现出来。我做了这么多年芯片,发现大部分接口问题都出在约束没给对,或者给得太随意。

4.1 输入延迟约束(set_input_delay)

先聊聊输入延迟。你想想看,外部器件把数据发过来,数据从芯片的pad到内部寄存器,这中间是有延迟的。这个延迟怎么算?

我个人习惯这样理解:输入延迟 = 外部器件的时钟到输出延迟 + PCB走线延迟。说白了,就是数据相对于时钟到达芯片引脚的时间差。

核心公式:

set_input_delay -clock [get_clocks clk] -max 2.5 [get_ports data_in]

set_input_delay -clock [get_clocks clk] -min 1.0 [get_ports data_in]

这里有个坑,我踩过好几次。max和min分别对应最坏和最好情况。max值决定了建立时间能不能满足,min值决定了保持时间。我曾经在一个项目中只给了max没给min,结果流片回来发现保持时间违例,那叫一个惨。

注意:输入延迟的参考点是芯片的时钟引脚,不是内部时钟树。很多新手容易搞混,以为set_input_delay是相对于内部时钟的,其实不是。

4.2 输出延迟约束(set_output_delay)

输出延迟和输入延迟是对称的。芯片内部把数据送到输出pad,外部器件要正确采样。这时候我们需要告诉工具:外部器件需要多少建立时间和保持时间。

公式很简单:

set_output_delay -clock [get_clocks clk] -max 4.0 [get_ports data_out]
set_output_delay -clock [get_clocks clk] -min 1.5 [get_ports data_out]

这里的max对应外部器件的建立时间要求,min对应保持时间要求。我一般会留0.5ns的裕量,毕竟PCB走线、温度变化这些因素都会影响实际延迟。

我的经验:输出延迟的max值不要设得太紧。我曾经在一个DDR接口项目中,把输出延迟设得刚好满足外部器件的建立时间,结果量产时温度一高就出问题。后来我学乖了,至少留10%的裕量。

4.3 如何与外部器件握手

握手,说白了就是双方约定好什么时候发数据、什么时候收数据。常见的握手方式有同步和异步两种。

4.3.1 同步握手

同步握手最简单,双方用同一个时钟。这时候约束就是上面说的输入输出延迟。但要注意时钟偏斜——外部器件的时钟和芯片的时钟可能不是完全同步的。

我遇到过一个问题:外部ADC用100MHz时钟,芯片也用100MHz时钟,但两个时钟来自不同晶振。结果就是频率一样,相位一直在漂。这种情况必须用异步处理,或者加一个PLL同步。

4.3.2 异步握手

异步握手需要握手信号。比如用req/ack协议:芯片发请求,外部器件回应答。这时候时序约束要分两部分:

  • 输出路径:约束req信号的输出延迟
  • 输入路径:约束ack信号的输入延迟

但异步握手有个特点:不需要严格的建立保持时间,因为内部会做同步处理。不过同步器本身会引入两个周期的延迟,这个要在系统设计时考虑进去。

关键点总结:

  1. 输入延迟 = 外部器件Tco + PCB延迟
  2. 输出延迟 = 外部器件Tsetup + PCB延迟
  3. 同步握手用set_input_delay/set_output_delay
  4. 异步握手需要同步器,延迟多2个时钟周期
  5. 始终留裕量,别卡着极限值

4.4 实际项目中的避坑指南

嗯,这里我总结几个常见问题,都是我在项目中真实遇到过的:

  • 问题1:只约束了max没约束min。结果保持时间违例,数据被错误采样。
  • 问题2:输入延迟参考时钟选错了。应该用外部器件的时钟,不是芯片内部时钟。
  • 问题3:输出延迟没考虑PCB走线长度。高速接口尤其要注意,1英寸走线大约有170ps延迟。
  • 问题4:异步握手没加同步器。直接跨时钟域采样,导致亚稳态。

我曾经在一个项目中,因为没加同步器,芯片在高温下频繁死机。查了整整两周才发现是异步握手的问题。从那以后,我每个异步接口都强制加两级同步器,宁可多花点面积,也不冒风险。

小技巧:如果你不确定输入输出延迟该设多少,可以先按外部器件datasheet的典型值来设,然后做一次STA看看裕量。如果裕量太大,可以适当收紧;如果违例,就要检查是不是约束太紧了。

最后说一句:I/O时序约束不是一锤子买卖。随着PCB设计变化、温度变化、电压变化,实际延迟都会变。所以我的习惯是:第一次约束留20%裕量,等PCB回来实测后再微调。这样既不会过度约束,也不会漏掉问题。