一个数字芯片工程师的核心竞争力是什么?不同的工程师可能给出不同的答复,有些人可能提到硬件描述语言,有些人可能会提到对于特定算法和协议的理解,有些人或许会提到对于软硬件的结合划分,作者想说,这些说法,其实对也不对,硬件描述语言,翻来覆去无非是always和assign这几个语句的反复使用,而一些基础的协议算法,深究起来其实也并不复杂,于作者而言,在常规的技能以外,有两项额外的技能颇为重要,其中之一便为sdc/STA的分析能力,它的重要之处在于作为桥梁建立了前端和后端的连接,虽然对于DE工程师而言,初版交付的sdc往往不甚准确,也没有办法通过这份sdc生成一份无误的timing report,但sdc的内容体现却是完完整整的将时序约束从行为级的描述映射到了gate level这样一个真实的电路层次上面。
写此专栏,一为学习记录,二为交流分享,以犒粉丝读者。
静态时序分析简明教程(一)绪论
静态时序分析简明教程(二)基础知识:建立保持时间,违例修复,时序分析路径
静态时序分析简明教程(三)备战秋招,如何看懂一个陌生的timing report
静态时序分析简明教程(四)时钟常约束
静态时序分析简明教程(五)生成时钟
静态时序分析简明教程(六)时钟组与其他时钟特性
静态时序分析简明教程(七)端口延迟
静态时序分析简明教程(八)虚假路径
静态时序分析简明教程(九)多周期路径
静态时序分析简明教程(十)组合电路路径
静态时序分析简明教程(十一)模式分析与约束管理
静态时序分析简明教程(十二)浅议tcl语言
假如我们想分析B2模块的静态时序,它的来源于F1寄存器Q端的输出,信号从Clk1开始,经过Clk1到Q,wire的延时,C1与C2的组合逻辑,到达B2模块的边界,这些不同来源的延时如何分配对于B2模块的分析不产生影响,我们只需要确定一个总的信号经过多长时间出现在输入端口,进行约束即可。
与之相似的,我们对于B1模块的输出端口分析,输出需要保持的时间长度,需要允许信号经过C2,C3,互连线延时,和F2的建立时间之和,但是同样的,我们也不需要关心这几种信号之间的分配关系,作为一个整体进行约束即可。
举一个简单的例子:
假如我们讨论B1的output端口(此时信号已经经过C1了),输出的延迟为6ns,而B2的寄存器会在10ns的时间进行采样,那么我们需要使B1的output端口在4ns以前就进入稳定状态,以避免亚稳态的出现
在输入端口指定延迟的SDC命令使set_input_delay。在输出端口指定延迟的SDC命令为set_output_delay,他们的约束条件相似,因此终点介绍input_dealy,这个命令的具体BNF如下:
set_input_delay [-clock clock_name]
[-clock_fall]
[-level_sensitive]
[-rise]
[-fall]
[-max]
[-min]
[-add_delay]
[-network_latency_included]
[-source_latency_included]
delay_value port_pin_list
-clock用来指定参考的时钟,这个时钟是指触发输入端信号的时钟名称。比如下面这幅图片,输入I1由触发器F1驱动,而触发器F1,由Clk1时钟驱动,因此clock_name的名称应该设置为Clk1
通常情况下,我们讨论的触发器触发条件都是上升沿,因此输入延时也是基于时钟的上升沿指定,但是也存在特殊的下降沿触发,还是上面那张图片,假如F1是由下降沿触发的寄存器,同时延迟为2,我们可以使用如下的sdc进行约束
set_input_delay -clock Clk1 -clock_fall 2.0 [get_ports I1]
set_input_delay -clock Clk1 7.0 [get_ports I1]
#这两条SDC等价的前提使时钟周期为10,因此对于下降沿的2.0 dealy和对于上升沿的7.0 delay等价
如果前级的输出不来自触发器,而来自锁存器,那么我们通过-level_sensitive来进行约束,为什么前级会出现锁存器的原因,和通过锁存器增加setup slack(建立裕度)有关
这里的rise/fall指的是:输入延迟与输入端口的上升沿/下降沿相对应(注意与-clock_fall的区别,-clock_fall是指前一级触发器是上升沿时钟触发还是下降沿时钟触发),但是通常情况下,我们并不需要单独的指定-rise/fall,这是因为在CMOS电路中,上升沿和下降沿过渡的路径延迟非常相似。
-min用于限定输入信号端口的最早到达时间的延迟值
-max用于限定输入信号端口的最晚到达时间的延迟值
假如我们不加以单独指定-min/-max,那么他们默认使用相同的设定值,随着工艺的提升,触发器需要的保持时间要求大幅下降,因此我们只需要使用最大值就可以完成检查,而不答需要去关心最小值
假如我们需要在同一个端口指定多个参考时间的输入延迟,我们需要在新的SDC约束上增加“-add_delay”选项,目的是避免后面的约束覆盖前面的约束,案例如下
set_input_delay -clock CLK1 -min 3.0 [get_ports A]
set_input_delay -clock CLK2 3.5 [get_ports A]
#第二句的3.5覆盖掉了第一句的3.0
set_input_delay -clock CLK1 -min 3.0 [get_ports A]
set_input_delay -clock CLK2 -add_delay 3.5 [get_ports A]
#第二句的3.5和第一句的3.0共存
在2.3.7中,我们要讨论的语句是[-network_latency_included]和[-source_latency_included]。
在2.3.1的图片中,假如wire延时为0,Clk1到达F1和B1的时间相同,但是实际的电路中时钟源延迟和网络延迟的存在会使clk信号到达不同步,假如input的delay包括时钟源延迟,指定[-source_latency_included],计入input的delay包括网络延迟的话,我们需要指定[-network_latency_included],但是这些语句并不常用。
set_output_delay与set_input_delay非常相似,在这里仅列出其BNF指令,具体的内容参考2.3节即可
set_output_delay [-clock clock_name]
[-clock_fall]
[-level_sensitive]
[-rise]
[-fall]
[-max]
[-min]
[-add_delay]
[-network_latency_included]
[-source_latency_included]
delay_value port_pin_list
set_input_delay和set_output_delay需要保证正确的设定,以此来确保时序的正确,假如设定不正确,单个的单元电路可能会满足自身时序要求,但整体的集成设计可能会出现时序违例,在讨论set_input_delay的过程中,我们需要关注到:启动时钟才是参考时钟,而在set_input_delay的过程中,采样时钟才是参考时钟。