⚠️本文目的为 个人学习记录 及 知识分享。因个人能力受限存在解读不正确的可能。若您参考本文进行产品设计或进行其他事项并造成了不良后果本人不承担相关法律责任文章目录前言1、时钟定义包含外部时钟、内部时钟和虚拟时钟2、时钟关系声明一般有异步关系、逻辑互斥和物理互斥3、端口约束内部 Reg-to-Reg 模型的建立时间Setup公式I/O 模型的建立时间Setup公式4、CDC路径前言时序约束 (SDC) 创建必须具有三个重要方面1“完整”约束集包括时钟、输入和输出延迟、时钟延迟、时钟不确定性、设置案例分析set-case-analysis、时钟和输入转换clock and input transition、输出负载output load、最大和最小延迟max and min delay、错误路径异常和多周期异常路径false path exceptions and multi-cycle exceptions paths。False path exceptions包括时钟域交叉、异步复位、扫描使能以及使用设计的功能分析创建的false path缺少约束会显着影响结果的质量。2 “正确”正确的约束集意味着无需通过外部验证工具来验证约束。这还包括计时异常这些异常应该通过构造在功能上正确。不正确的时序异常可能会导致芯片时序故障因为它们可以通过实施步骤掩盖芯片时序问题3 “有意义的”约束是指不会压垮而是帮助下游工具如综合和物理设计的适当集合以在面积、时序和功耗方面产生更好的芯片 QoR。本文就一份完整的sdc的结构有哪些来展开。1、时钟定义包含外部时钟、内部时钟和虚拟时钟外部时钟指的是作为输入时钟以input形式进入到顶层的时钟对于该类时钟需要使用下面的命令进行定义create_clock -name CLK_NAME -period CLK_PERIOD -waveform CLK_START CLK_RISE [get_ports CLK] set_clock_uncertainty -setup [expr CLK_JITTER CLK_MARGIN] [get_clocks CLK] set_clock_uncertainty -hold [expr CLK_MARGIN] [get_clocks CLK]上述命令依次声明了时钟名字CLK_NAME可以自定义并不是一定要和CLK一样但是需要唯一且一致引用声明了周期一般用宏定义的形式声明方便后续调用声明了占空比一般情况下CLK_START是0CLK_RISE是周期的一半用于表示5050占空比声明了输入进来的物理端口名字声明了建立时间和保持时间的不稳定性用于模拟更真实的场景值得注意的是在第一行命令中使用的是get_ports用于定位是从该物理端口输入的时钟而第二/三行中使用get_clocks则是该时钟域下所有的时序路径也正因为如此可以对路径上时钟设置建立时间/保持时间的不稳定性个人理解派生时钟顾名思义指的是模块内部产生的时钟生成时钟唯一核心目的是「当一个内部节点的时钟信号成为独立时钟域的驱动源即该信号驱动了其他触发器的时钟端且其频率 / 相位与主时钟有明确的固定关系时」才需要定义生成时钟比如源时钟经历分频、倍频或者mux等。像下图两个DFF共同组成了分频器因此只需要在DFF2/Q上定义派生时钟而不需要DFF1/Q上定义。对于该类时钟需要使用下面的命令进行定义create_generated_clock -name GC1 -divide_by 3 -source [get_port CLK] -master_clock C1 [get_pins FF2/Q]结合上面的例子GC1是声明了派生时钟名字-divide_by声明几分频声明了源时钟来源于哪个物理引脚/端口声明了父时钟来源于哪个输入时钟。虚拟时钟是作为输入输出端口延时的时钟源详情见如下链接数字IC设计中virtual clock2、时钟关系声明一般有异步关系、逻辑互斥和物理互斥set_clock_group-asynchronous-logically_exclusive-physically_exclusive-asyn用于声明两组时钟的异步关系当两个时钟相位不确定的时候可以用禁止时钟组之间的时序分析一般而言当时钟来自于不同的PLL或者晶振时时钟之间的相位是不固定的。如果时钟之间存在CDC路径则可以额外添加-allow_path意味着虽然声明了两者的异步关系但是允许使用set_max/min_delay去人为添加时钟之间的延迟以进行时序分析。-logically_exclusive如果两个时钟同时存在但是他们之间没有任何 path则这两个时钟可以设置为 logically exclusive典型的情况就是一个 MUX 选择两个或多个时钟。但是并不是所有的mux都要设置逻辑互斥比如下面的例子-physical_exclusive当两个时钟在同一时刻不可能同时存在时则这两个时钟就可以设置为物理互斥。比如在相同的端口上创建多个时钟但是这两个时钟工作在不同的工作模式比如TestClk 和 Function Clock。调试技巧可以使用report_clock -groups去报告实际的时钟关系和预设的时钟关系是否一样可以使用report_timing -from [get_clocks clka] -to [get_clocks clkb]去报告设置的时钟组之间是否是异步/同步关系3、端口约束最先应该做的是梳理顶层设计的输入输出端口并且根据databook等确定这些端口是同步于哪些时钟然后使用set xxx [get_port [list xxx xxx]]形式将同步于同一时钟的端口归为一个组方便后续调用。首次通过约束创建通常是一个手动、易出错且耗时的过程。对于大型设计而言创建时钟定义和输入/输出延迟往往是一项繁琐的任务。如上图所示如果在DUA设计上没有对DATAIN DATAOUT的数据进行约束那么STA工具并不能够得到有外部寄存器经过组合逻辑到达DATAIN的时间同时也不知道DATAIN信号和输入的MCLK是什么关系input delay和output delay就是告诉STA工具芯片外部的信号的delay信息。input delay最常用的设置是对一组信号设置为采样时钟的70%继续按照上图的例子值得一提的是这里需要用虚拟时钟。下面是具体的命令定于端口DATAIN的输入延迟延迟值是MCLK周期的0.7倍同步于MCLK时钟。如果稍微改一下场景我们并不知道DATAIN的驱动时钟或者DATAIN的驱动时钟在DUA中并没有被声明则需要额外使用虚拟时钟。set_input_delay -max [expr 0.7 * MCLK] -clock MCLK [get_ports DATAIN]input_delay/output_delay和普通setup/hold分析模型本质是一样的都是两个寄存器串联起来使用同一个clk但是区别在于端口约束的两个寄存器内外之分而已。我们以这个简单模型入手进一步分析input_delay/output_delay所约束的数值具体含义。setup/hold分析就不做赘述具体可见建立时间(setup time)和保持时间(hold time详析内部 Reg-to-Reg 模型的建立时间Setup公式对于芯片内部的两个寄存器STA 工具的计算公式是T c l k 2 q _ T X T c o m b _ i n t e r n a l T p e r i o d − T s e t u p _ R X T s k e w T_{clk2q\_TX} T_{comb\_internal} T_{period} - T_{setup\_RX} T_{skew}Tclk2q_TXTcomb_internalTperiod−Tsetup_RXTskewI/O 模型的建立时间Setup公式当Reg_TX位于芯片外部另一颗芯片而Reg_RX是你 DUT 内部的第一级寄存器时。工具的视角中缺失了芯片外部的延迟信息于是 SDC 引入了input_delayI n p u t _ D e l a y m a x T c o m b _ i n t e r n a l T p e r i o d − T s e t u p _ R X T s k e w _ i n t e r n a l Input\_Delay_{max} T_{comb\_internal} T_{period} - T_{setup\_RX} T_{skew\_internal}Input_DelaymaxTcomb_internalTperiod−Tsetup_RXTskew_internal可以清晰地看到Input_Delay_max在数学模型中完美等价并直接替换了外部电路的延迟总和I n p u t _ D e l a y m a x ≡ T c l k 2 q _ e x t T t r a c e _ e x t − T s k e w _ e x t Input\_Delay_{max} \equiv T_{clk2q\_ext} T_{trace\_ext} - T_{skew\_ext}Input_Delaymax≡Tclk2q_extTtrace_ext−Tskew_ext对于保持时间Hold Time的-min分析其等价映射关系也是完全一致的。这也就是所约束的数值含义覆盖了工具所看不到的边界盲区外部器件什么时候发数据外部 PCB 走线有多长这个值当作上游的Arrival Time接着往下算内部那段就行了。工具根本无法知道真实的外部 Skew 是多少因此创建一个完全虚拟的时钟Virtual Clock来专门模拟外部那个clk的时钟相位从而将内外时钟域在逻辑上进行解耦约束。如何理解max/minset_input_delay和set_output_delay用的是-max和-min。max对应的是建立时间担心的是太晚情况对于输入来说担心的最晚到达输入端口对于输出担心的是最晚到达下游器件输入。min是保持时间担心太早情况对于输入就是说新数据来的太早对于输出就是给下游新的数据太早。具体来说建立时间是时钟有效沿来之前数据维持稳定的时间对于输入如果max超出范围也就是太晚到达对于要求最晚11ns到达留了足够的建立时间但是你12ns到达就不满足建立时间出现亚稳态对于输入如果min小于范围也就是太早对于要求最早1ns离开新数据到留够了保持时间但是你0.5ns就离开新数据到就不满足保持时间出现亚稳态。对于输出来说max超范围给下游数据太晚建立时间不满足min小于范围给下游数据太早保持时间不满足。4、CDC路径如果存在跨时钟域路径时钟之间没有确定的相位关系数据是靠同步器比如两级触发器来传递的。这条路径的延迟可以很长只要不超过同步器的“容忍”范围就行所以常规的setup/hold检查在这里不适用。因此这种情况下我们要结合set_clock_group -asyn -allow_path去使用set_max/min_delay去约束时序路径。在同步时钟时序分析中由于在两个DFF之间的用的是同一个时钟在计算建立时间和保持时间的时候对于时钟仅需要考虑是Tlaunch和Tcapture但是在异步时钟中两个DFF分别用的是两个周期不同相位不明确的时钟因此需要使用max/min delay去定义两个时钟间的延迟方便进行setup/hold_time的计算。