静态时序分析:时钟组间的逻辑独立、物理独立和异步的区别

news/2025/2/23 16:10:55

相关阅读

静态时序分析https://blog.csdn.net/weixin_45791458/category_12567571.html


        当设计中存在多个时钟(同步或异步)时,该如何使用SDC命令约束设计呢?本文就将对此进行讨论。

逻辑独立

例1 多个时钟完全逻辑独立

图1 逻辑独立的时钟

        以图1所示的待综合设计为例, 其中CLK1和CLK2是来自同一个晶振的分频时钟,频率分别是500MHz和750MHz,由于有确定的相位关系,它们是同步的。

        可以注意到,在待综合设计中两个时钟域不会出现交互情况,但来自两个时钟域的信号通过多路复用器驱动输出端口OUT,而输出端口OUT在外部解复用并分别驱动各自时钟域的寄存器。

        由于两个多路复用/解复用器的选择端是连接在一起的,因此当选择输出CLK1时钟域的信号时,输出端口OUT驱动外部的CLK1时钟域的寄存器;当选择输出CLK2时钟域的信号时,输出端口OUT驱动外部的CLK2时钟域的寄存器;

        假设使用以下的SDC命令约束待综合设计,会发生什么?

create_clock -period 2.0 [get_ports CLK1]
create_clock -period [expr {1000/750.0}] [get_ports CLK2]
set_output_delay -max 0.15 -clock [get_clocks CLK1] [get_ports OUT1]
set_output_delay -max 0.52 -clock [get_clocks CLK2] -add_delay [get_ports OUT1] # 值得注意的是,为了在同一个端口定义两个输出延迟,需要在第二个set_output_delay命令时使用-add_delay选项,否则将会覆盖第一个输出延迟

        在这种情况下,Design Compiler将会认为来自CLK1时钟域的信号可以被CLK2时钟域的寄存器捕获,而来自CLK2时钟域的信号可以被CLK1时钟域的寄存器捕获,从而在这几种情况中找出最严格的发射/捕获沿进行分析,这是过分约束的。实际上,我们希望Design Compiler忽略从CLK1时钟域到CLK2时钟域和CLK2时钟域到CLK1时钟域的时序分析。有两种方法可以完成该要求,使用set_false_path命令或set_clock_groups命令。

        使用两条set_false_path命令,指定起点为时钟CLK1,终点为时钟CLK2的时序路径和起点为时钟CLK2,终点为时钟CLK1的时序路径为虚假路径;使用set_clock_groups命令创建两个逻辑独立的时钟组,分别包含CLK1和CLK2时钟。

create_clock -period 2.0 [get_ports CLK1]
create_clock -period [expr {1000/750.0}] [get_ports CLK2]
set_output_delay -max 0.15 -clock [get_clocks CLK1] [get_ports OUT1]
set_output_delay -max 0.52 -clock [get_clocks CLK2] -add_delay [get_ports OUT1]

set_false_path -from [get_clocks CLK1] -to [get_clocks CLK2]
set_false_path -from [get_clocks CLK2] -to [get_clocks CLK1]
# 两种方式均可
set_clock_groups -logically_exclusive -group [get_clocks CLK1] -group [get_clocks CLK2]

例2 多个时钟部分逻辑独立

图2 部分逻辑独立的时钟

        图2所示的例2与例1相似,唯一的区别在于,在待综合设计中时钟域CLK1与时钟域CLK2之间存在时序路径(如图中的红线所示),如果还使用如下所示的SDC命令,会发生什么?

create_clock -period 2.0 [get_ports CLK1]
create_clock -period [expr {1000/750.0}] [get_ports CLK2]
set_output_delay -max 0.15 -clock [get_clocks CLK1] [get_ports OUT1]
set_output_delay -max 0.52 -clock [get_clocks CLK2] -add_delay [get_ports OUT1]

set_false_path -from [get_clocks CLK1] -to [get_clocks CLK2]
set_false_path -from [get_clocks CLK2] -to [get_clocks CLK1]
# 两种方式均可
set_clock_groups -logically_exclusive -group [get_clocks CLK1] -group [get_clocks CLK2]

        这会导致待综合设计中时钟域CLK1与时钟域CLK2之间存在的时序路径也被忽略,这不是我们希望发生的,我们只希望忽略经过输出端口的不同时钟域间的时序路径。在这种情况下,只能使用set_false_path命令完成该要求,可以通过使用-through选项获得更加细粒度的控制,而不能使用set_clock_groups命令。

create_clock -period 2.0 [get_ports CLK1]
create_clock -period [expr {1000/750.0}] [get_ports CLK2]
set_output_delay -max 0.15 -clock [get_clocks CLK1] [get_ports OUT1]
set_output_delay -max 0.52 -clock [get_clocks CLK2] -add_delay [get_ports OUT1]

set_false_path -from [get_clocks CLK1] \
               -through [get_ports OUT1] -to [get_clocks CLK2]
set_false_path -from [get_clocks CLK2] \
               -through [get_ports OUT1] -to [get_clocks CLK1]

例3 多个时钟驱动同一个寄存器1

图3 多个时钟驱动同一个寄存器1

        在图3所示的例3中,时钟CLK1和时钟CLK2首先经过输入端口SEL1控制的多路复用器,随后再连接到寄存器的时钟端,也就是说待综合设计中的寄存器要么被时钟CLK1驱动,要么被时钟CLK2驱动。但是默认情况下,Design Compiler不会考虑多路复用器的选择性并认为多个时钟能驱动一个寄存器(该行为可以通过timing_enable_multiple_clocks_per_reg变量改变),因此来自CLK1时钟域的信号可以被CLK2时钟域的寄存器捕获,而来自CLK2时钟域的信号可以被CLK1时钟域的寄存器捕获,Design Compiler将在这几种情况中找出最严格的发射/捕获沿进行分析,这是过分约束的。实际上,我们希望Design Compiler忽略从CLK1时钟域到CLK2时钟域和CLK2时钟域到CLK1时钟域的时序分析。有四种方法可以完成该要求,使用set_disable_timing命令、set_case_analysis命令、set_false_path命令或set_clock_groups命令。

        使用set_disable_timing可以将某个时钟从多路复用器输入端到输出端的时序弧中断,从而忽略有关该时钟的分析;使用set_case_analysis命令可以指定输入端口SEL1的值,从而只允许某个时钟经过多路复用器,从而忽略其他时钟的分析。

create_clock -period ... [get_ports CLK1]
create_clock -period ... [get_ports CLK2]
set_disable_timing [get_cell MUX] -from A -to Y
# 两种方式均可
set_case_analysis 0 [get_port SEL1]

        上面这两种该方法的缺点也很明显,即只能选择某一个时钟进行约束,综合时并不会考虑到其他时钟的影响,这依赖用户选择最严格的时钟进行约束,对于例3这种简单情况下尚可接受,但在例4所示的复杂情况下就会变得困难。

        使用两条set_false_path命令,指定起点为时钟CLK1,终点为时钟CLK2的时序路径和起点为时钟CLK2,终点为时钟CLK1的时序路径为虚假路径;使用set_clock_groups命令创建两个逻辑独立的时钟组,分别包含CLK1和CLK2时钟。 

create_clock -period ... [get_ports CLK1]
create_clock -period ... [get_ports CLK2]

set_false_path -from [get_clocks CLK1] -to [get_clocks CLK2]
set_false_path -from [get_clocks CLK2] -to [get_clocks CLK1]
# 两种方式均可
set_clock_groups -logically_exclusive -group [get_clocks CLK1] -group [get_clocks CLK2]

 

例4 多个时钟驱动同一个寄存器2

图4 多个时钟驱动同一个寄存器2

        在图4所示的例4中,时钟CLK1和时钟CLK2首先经过输入端口SEL1控制的多路复用器,随后再连接到部分寄存器的时钟端;时钟CLK3和时钟CLK4首先经过输入端口SEL2控制的多路复用器,随后再连接到部分寄存器的时钟端。在这种情况下,我们希望Design Compiler忽略CLK1时钟域与CLK2时钟域和CLK3时钟域与CLK4时钟域之间的时序分析。与例3类似,有四种方法可以完成该要求,使用set_disable_timing命令、set_case_analysis命令、set_false_path命令或set_clock_groups命令。

        使用set_disable_timing命令或使用set_case_analysis命令的缺点已经在例3中进行了说明,时序分析只能在时钟CLK1或时钟CLK2与时钟CLK3或时钟CLK4之间进行,这依赖用户选择最严格的时钟对进行约束。

        使用四条set_false_path命令,指定起点为时钟CLK1,终点为时钟CLK2的时序路径、起点为时钟CLK2,终点为时钟CLK1、起点为时钟CLK3,终点为时钟CLK4的时序路径和起点为时钟CLK4,终点为时钟CLK3的时序路径的时序路径为虚假路径;使用两条set_clock_groups命令创建逻辑独立的时钟组,其中一对时钟组包含CLK1和CLK2时钟,另一对时钟组包含CLK3和CLK4时钟。 

create_clock -period ... [get_ports CLK1]
create_clock -period ... [get_ports CLK2]
create_clock -period ... [get_ports CLK3]
create_clock -period ... [get_ports CLK4]


set_false_path -from [get_clocks CLK1] -to [get_clocks CLK2]
set_false_path -from [get_clocks CLK2] -to [get_clocks CLK1]
set_false_path -from [get_clocks CLK3] -to [get_clocks CLK4]
set_false_path -from [get_clocks CLK4] -to [get_clocks CLK3]
# 两种方式均可
set_clock_groups -logically_exclusive -group [get_clocks CLK1] -group [get_clocks CLK2]
set_clock_groups -logically_exclusive -group [get_clocks CLK3] -group [get_clocks CLK4]

例5 多个时钟驱动同一个寄存器3

图5 多个时钟驱动同一个寄存器3

        图5所示的例5与例4相似,唯一的区别在于,两个多路复用器的选择端是连接在一起的,只能固定选择时钟CLK1与时钟CLK3或时钟CLK2与时钟CLK4。在这种情况下,我们希望Design Compiler忽略CLK1时钟域与CLK2时钟域、CLK3时钟域与CLK4时钟域、CLK1时钟域与CLK4时钟域和CLK2时钟域与CLK3时钟域之间的时序分析。

        使用set_disable_timing命令或使用set_case_analysis命令的缺点已经在例3中进行了说明,时序分析只能在时钟CLK1与时钟CLK3之间或时钟CLK1与时钟CLK3之间进行,这依赖用户选择最严格的时钟对进行约束。

        如果使用set_false_path命令,则需使用八条时序路径为虚假路径;而只需使用一条set_clock_groups命令创建两个逻辑独立的时钟组,分别包含CLK1、CLK3和CLK2、CLK4时钟。 

create_clock -period ... [get_ports CLK1]
create_clock -period ... [get_ports CLK2]
create_clock -period ... [get_ports CLK3]
create_clock -period ... [get_ports CLK4]

set_false_path -from [get_clocks CLK1] -to [get_clocks CLK2]
set_false_path -from [get_clocks CLK2] -to [get_clocks CLK1]
set_false_path -from [get_clocks CLK3] -to [get_clocks CLK4]
set_false_path -from [get_clocks CLK4] -to [get_clocks CLK3]
set_false_path -from [get_clocks CLK1] -to [get_clocks CLK4]
set_false_path -from [get_clocks CLK4] -to [get_clocks CLK1]
set_false_path -from [get_clocks CLK2] -to [get_clocks CLK3]
set_false_path -from [get_clocks CLK3] -to [get_clocks CLK2]
# 两种方式均可
set_clock_groups -logically_exclusive -group "CLK1 CLK3" -group "CLK2 CLK4"

物理独立

例6 多个时钟物理独立

图6 物理独立的时钟

        在例2、例3和例4中,在使用set_clock_groups命令时添加了-logically_exclusive选项,那么什么是逻辑独立呢?对于Design Compiler而言,逻辑独立的时钟组可以被简单理解为,不在这些时钟组之间进行时序分析,但对于IC Compiler或PrimeTime-SI而言,逻辑独立的时钟组之间会进行串扰分析,这是基于侵害者和受害者之间的时序重叠窗口进行的。

        例6其实和例3几乎完全一样,唯一的区别在于,时钟CLK1和时钟CLK2是在待综合设计外部经过多路复用器然后从同一个输入端口Clk输入,在这种情况下会在输入端口Clk上定义两个时钟,但在使用set_clock_groups命令时还应该使用-logically_exclusive选项吗?

create_clock -period ... -name CLK1 [get_ports Clk]
create_clock -period ... -name CLK2 -add [get_ports Clk] # 值得注意的是,为了在同一个端口定义两个时钟,需要在第二个create_clock命令时使用-add选项,否则将会覆盖第一个时钟

set_clock_groups -logically_exclusive -group [get_clocks CLK1] -group [get_clocks CLK2]

        答案是否定的。由于逻辑独立的时钟组之间会进行串扰分析,IC Compiler或PrimeTime-SI在分析时会考虑到两个时钟之间的时序重叠窗口,这很显然是不合理(悲观)的,因为在物理上这两个时钟并不会同时进入设计,因此这是过分约束的。

        使用-physically_exclusive选项而不是-logically_exclusive选项,能够获得更加准确的串扰分析,尽管对于Design Compiler而言,这两个选项没有任何区别。

create_clock -period ... -name CLK1 [get_ports Clk]
create_clock -period ... -name CLK2 -add [get_ports Clk]

set_clock_groups -physically_exclusive -group [get_clocks CLK1] -group [get_clocks CLK2]

        也许有人会问,既然-physically_exclusive选项比-logically_exclusive选项能够获得更加准确的串扰分析,那为什么不干脆全用-physically_exclusive选项?例1就应该使用-logically_exclusive选项而不是-physically_exclusive选项,因为两个时钟可以同时存在设计内并且相互之间出现串扰。

异步

例7 多个时钟异步

图7 异步时钟

        例1到例6所展示的都是同步时钟,它们来自于同一个晶振,而例7中的两个来自不同晶振输出的异步时钟,它们之间的相位关系是不可预测的,因为每个晶振稳定之后的相位都是不确定。可以从图7中看出,为了避免在跨时钟域时出现亚稳态,在CLKB时钟域中有两级触发器用于同步。

        我们希望Design Compiler忽略CLKA时钟域与CLKB时钟域之间的时序分析,但此时需要使用-asynchronous选项,该选项在Design Compiler中与-physically_exclusive选项、logically_exclusive选项没有任何区别,但是IC Compiler或PrimeTime-SI在分析时会认为两个时钟之间拥有无限宽的时序重叠窗口。

create_clock -period ... [get_ports CLKA]
create_clock -period ... [get_ports CLKB]

set_clock_groups -asynchronous -group [get_clocks CLKA] -group [get_clocks CLKB]

时钟分组的建议

        1、如果设计中能共存多个时钟,但通过多路复用器只能选择其中一个,则使用-logically_exclusive选项。

        2、如果设计中不能共存多个时钟(这一般出现在一个时钟源对象上定义了多个时钟),则使用-physically_exclusive选项。

        3、如果设计中能共存多个时钟,但它们没有固定的相位关系,则使用-asynchronous选项。


http://www.niftyadmin.cn/n/5863572.html

相关文章

ubuntu 源码编译ffmpeg

文章大概就是源码编译 ffmpeg,支持H265 264 编码和gdb 调试 下载ffmpeg 源码 git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg下载依赖库 sudo apt-get install libx264-dev libx265-dev编译选项 ./configure --enable-gpl --enable-libx264 --enable-…

【推荐项目】009-学校宿舍管理系统

系统角色与功能优化整理如下: 系统角色: 学生 宿舍管理员 系统管理员 系统功能: 首页:提供系统概览及快速导航。 用户管理:对用户信息进行增删改查等操作(系统管理员专有)。 宿舍管理&#x…

Qt中QRadioButton的使用

QRadioButton 是 Qt 框架中的一个控件,用于创建单选按钮。单选按钮通常用于让用户从一组互斥的选项中选择一个选项。以下是如何在 C 中使用 QRadioButton 的基本示例。 1. 包含必要的头文件 首先,确保包含 QRadioButton 和其他必要的 Qt 头文件。 #inc…

python-leetcode-二叉树的中序遍历

94. 二叉树的中序遍历 - 力扣(LeetCode) 方法1:递归实现 # Definition for a binary tree node. # class TreeNode: # def __init__(self, val0, leftNone, rightNone): # self.val val # self.left left # self.right …

linux常用基础命令_最新版

常用命令 查看当前目录下个各个文件大小查看当前系统储存使用情况查看当前路径删除当前目录下所有包含".log"的文件linux开机启动jar更改自动配置文件后操作关闭自启动linux静默启动java服务查询端口被占用查看软件版本重启关机开机启动取别名清空当前行创建文件touc…

MySQL(高级特性篇)11章——数据库的设计规范

一、为什么需要数据库设计 设计数据表时需考虑的问题: 数据需求:明确用户需要的数据以及需要在数据表中保存的数据数据正确性:在插入、删除、更新数据时,确定进行怎样的约束检查来保证数据的正确性数据冗余:思考如何降…

Java EE初阶-计算机导论

一、cpu的重要指标 核心参数 核心数(Cores) 含义:核心是 CPU 中执行指令的运算单元,核心数代表了 CPU 内独立运算核心的数量。影响:核心数越多,CPU 在同一时间内能够并行处理的任务就越多。例如&#xff…

链表-基础训练(二)链表 day14

两两交换链表中的节点 题目示意: 给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。 原先我的思路是图像上的思路,但是我感觉还是很复杂…