1 generated clock的定义
generated clock是有master clock衍生而来,master clock指的是由create_clock
定义的clock
当基于master clock生成一个新的clock时,可以将这个新的clock定义为generated clock
举个栗子,如下图所示,UFF0的功能是将时钟CLKP进行二分频,那么便可以在UFF0的输出端UFF0/Q定义一个generated clock
CLKP在经过UFF0后,后续电路的时钟周期发生了更改,但STA并不知道后续电路的时钟发生了变化,更不知道新的clock的周期是多少,因此需要定义generated clock,让STA知道后续电路的clock已经发生了更改以及新的clock周期是多少
# 创建一个master clock
create_clock -name CLKP 10 \
[get_pins UPLL0/CLKOUT]
# 新的clock被命名为CLKDIV2
# 它的master clock 在UPLL0/CLKOUT处定义
# 新的clock是master clock的二分频
# 新的clock在UFF0/Q处定义
create_generated_clock \
-name CLKPDIV2 \
-source UPPL0/CLKOUT \
-divide_by 2 \
[get_pins UFF0/Q]
2 generated clock与master clock的区别
从上面一张图中可以看到,master clock是由电路推出的,generated clock也是由电路推出的,也就是说,其实我们是可以在UFF0/Q定义一个master clock的
那为什么我们要将这个clock定义为generated clock而不是master clock
定义master clock会创建一个新的clock domain,而定义generated clock则不会创建新的clock domain
generated clock与master clock同相,并且不需要进行额外的约束,所以应当尽量将内部的新clock定义为generated clock
master clock的source是时钟定义点,generated clock的source是master clock,因此在report中,clock path的起点是master clock的定义点
此外,master clock的latency也会直接作用于generated clock(也就是说在定义generated clock时不需要再指定latency)
先看一个例子
SYS_CLK由触发器的输出进行门控,由于触发器的输出可能并不是恒定的,因此处理这种情况的一种方式是在UAND1的输出端定义一个generated clock,并且让新的clock与SYS_CLK相同
created_clock 0.1 [get_ports SYS_CLK]
#创建一个generated clock
#周期与master clock相同
created_generated_clock \
-name CORE_CLK \
-divide_by 1 \
-source SYS_CLK \
[get_pins UAND1/Z]
在来看一个generated clock比master clock频率高的例子
#定义master clock
create_clock -period 10 \
-waveform {0 5} \
[get_port PCLK]
#定义generated clock
create_generated_clock \
-name PCLKx2 \
-source PCLK \
-multiply_by 2 \
[get_pins UCLKMULTREG/Q]
3 门控单元输出端的master clock
来看这个例子
UAND2的两个输入端分别是两个不同的clock,此时我们可以在UAND2的输出端定义一个master clock,因为UAND2的输出与这个输入的clock不大可能具有相位关系
定义方式如下:
create_clock -name SYS_CLK \
-period 4 \
-waveform {0 2} \
[get_pins UFFSYS/Q]
create_clock -name CORE_CLK \
-period 12 \
-waveform {0 4} \
[get_pins UFFCORE/Q]
create_clock -name MAIN_CLK \
-period 12 \
-waveform {0 2} \
[get_pins UAND2/Z]
4 使用Edge和Edge_shift 定义generated clock
在定义generated clock时,也可以用-edge
和-edge_shift
的方式定义
先来看一下 什么是edge
看红色方框框住的内容,edge指的是DCLK的每一个边沿(既包括posedge,也包括negedge),从1开始,每遇到一个边沿,增加1
与-waveform{}
相似,-edge{}
和-edge_shift{}
中的内容也是以上升沿开始的,即-edge{posedge negedge posedge}
在-edge{}
中,我们给出三个边沿即可,因为通过这三个边沿我们就可以确定generated clock的high duration和low duration
-edge {} 和 -edge_shift {}有一个最大的不同点
在-edge {}中,三个参数指的是上图红色框中的边沿数
而在-edge_shift {}中,三个参数指的是蓝色框框柱的内容,也就是时间
接下来看几个例子
#创建master clock
create_clock 2 [get_ports DCLK]
#创建一个generated clock
#DCLKDIV2的posedge在DCLK的第2个边沿
#DCLKDIV2的negedge在DCLK的第4个边沿
#DCLKDIV2的下一个posedge在DCLK的第6个边沿
create_generated_clock \
-name DCLKDIV2 \
-edges {2 4 6} \
-source DCLK \
[get_pins UBUF2/Z]
#与上面相似
create_generated_clock \
-name PH0CLK \
-edges {3 4 7} \
-source DCLK \
[get_pins UAND0/Z]
create_generated_clock \
-name PH1CLK \
-edges {1 2 5} \
-source DCLK \
[get_pins UAND1/Z]
对应的波形图如下
前面提到,-edge {}中的第一个参数是上升沿,那么如果generated clock的第一个边沿是下降沿,那么则需要进行推断
比如下面定义的generated clock
create_generated_clock \
-name G3CLK \
-edges {5 7 10} \
-source DCLK \
[get_pins UAND0/Z]
在这个例子中,可以推断到,high duration有两个边沿的时间,low duration有3个边沿时间
那么可以推断在边沿5之前有一个negedge,并且这个negedge出现在边沿2
波形图如下
下面我们引入-edge_shift {}
# master clock
create_clock -period 10 \
-waveform {0 5} \
[get_ports MIICLK]
# 只有 -edge {}
create_generated_clock \
-name MIICLKDIV2 \
-source MIICLK \
-edges {1 3 5} \
[get_pins UMIICLKREG/Q]
# 带有 -edge_shift {}
create_generated_clock \
-name MIIDIV2 \
-source MIICLK \
-edges {1 1 5} \
-edge_shift {0 5 0} \
[get_pins UMIIDIV/Q]
只有-edge {}
的分析与上面一致
在前文提到,-edge_shift {}
中的三个参数,单位是时间
那么在这个例子中-edge_shift {0 5 0}
意思是,generated clock的第一个posedge便宜0ns,第一个negedge偏移5ns,第二个posedge偏移0ns
结合-edge {}
的设置和master clock的定义,可以推断generated clock的第一个posedge出现在0ns,第一个negedge出现在5ns,第二个posedge出现在20ns
如下图所示
5 invert选项
-invert
选项就是给generated clock加一个反相器,电路图如下图所示
对应的generated clock波形也是进行取反,比如下面这个例子
create_clock -period 10 [get_ports CLK]
create_generated_clock \
-name NCLKDIV2 \
-divide_by 2 \
-invert \
-source CLK \
[get_pins UINVQ/Z]
对应波形如下