fpga进阶--时序约束
1、基础概念
1.1 建立(setup)/保持(hold)时间
上述的锁存沿会将数据保存下来,但是必须要满足一定的条件:
建立时间Tsu:在时钟有效沿之前,数据必须保持稳定的最小时间;
保持时间Th:在时钟有效沿之后,数据必须保持稳定的最小时间;
1.2 亚稳态(Metastability)
亚稳态是由于违背了触发器的建立和保持时间而产生的,设计中任何一个触发器都有特定的建立和保持时间,在时钟上升沿前后的这段时间窗口内,数据输入信号必须保持稳定。如果信号在这段时间内发生了变化,那么输出将是未知的即称为亚稳态。触发器的输出会因此而产生毛刺,或者暂时保持在不稳定状态且需要较长时间才能回到稳定状态。
亚稳态的危害主要体现在破坏系统的稳定性。由于输出在稳定下来之前可能是毛刺、振荡、固定的某一电压值,因此亚稳态除了导致逻辑误判之外,输出0~1之间的中间电压值还会使下一级产生亚稳态(即导致亚稳态的传播)。逻辑误判有可能通过电路的特殊设计减轻危害,而亚稳态的传播则扩大了故障面。另外,在亚稳态状态下,任何诸如噪声、电源干扰等细微扰动将导致更恶劣的状态不稳定,这时这个系统的传输延时增大,状态输出错误,在某些情况下甚至导致会使寄存器在两个有效判定门限之间长时间振荡。
1.3 竞争和冒险
竞争(Competition): 在组合逻辑电路中,某个输入变量通过两条或两条以上的途径传到输出端,由于每条途径延迟时间不同,到达输出门的时间就有先有后,这种现象称为竞争。
冒险(risk):多路信号的电平值发生变化时,在信号变化的瞬间,组合逻辑的输出有先后顺序,并不是同时变化,往往会出现一些不正确的尖峰信号,这些尖峰信号称为"毛刺"。如果一个组合逻辑电路中有"毛刺"出现,就说明该电路存在冒险。
竞争冒险(Competition risk)产生原因:由于延迟时间的存在,当一个输入信号经过多条路径传送后又重新会合到某个门上,由于不同路径上门的级数不同,或者门电路延迟时间的差异,导致到达会合点的时间有先有后,从而产生瞬间的错误输出。
1.4 recovery time:恢复时间 / removal time :去除时间
recovery time:恢复时间
撤销复位时,恢复到非复位状态的电平必须在时钟有效沿来临之前的一段时间到来,才能保证时钟能有效恢复到非复位状态,此段时间为recovery time。类似于同步时钟的setup time。
如图所示,rst_n为0表示复位,clk上升沿触发,rst_n从0到1的上升沿与时钟上升沿必须不小于recovery time才能保证寄存器恢复到正常状态。
removal time :去除时间
复位时,在时钟有效沿来临之后复位信号还需要保持的时间为去除时间removal time(去除时间)。类似同步时钟hold time
如图所示,rst_n为0表示复位有效,clk为上升沿触发,rst_n保持为0经过clk上升沿后仍需要保持一段时间,才能保证寄存器有效复位,防止亚稳态。
2、查看时序报告
2.1 GUI界面打开
只有在编译filter(布线综合器)后,,然后再进行添加约束,最后再进行时序分析,才能使用GUI界面查看时序报告,如果你熟悉SDC的话,你可以自己手写脚本,如果不熟悉,你可以使用GUI的模式。另外,注意在时序分析时候,关掉signal tap, 有可能signal tap II会影响到时序约束,从而使得布线更加紧凑,违规更加严重。
2.2、查看系统的时钟运行最大频率
个人理解:在report 的datasheet当中有一个按钮Reoort Summary,此报告的意思是,按照这样的设计(你的verilog硬件电路设计),你在当前的环境下(比如80度低电压),你在当前时钟域下的设计最大的速度能够跑到多少,按照上面的最大的时钟速度只能跑到99.23M。
官方:
解释:
说了Restricted Fmax,这个值是因为保持时间的限制,也就是说,在这样的设计下,我们要满足setup slack的要求,寄存器能正确的捕获到值,最大这个速度就只能是99.23M了。
2.3查看未约束的时钟:
指出有哪些nodes没有被约束:
2.4查看保持/建立时间裕量:
3、constraints列表中的一些约束
3.1 create clock
以上默认是占空比50%,如果要指定占空比,请指定-waveform option。一般都是约束引脚时钟的。
eg:
3.2 derive pll clocks
The Derive PLL Clocks (derive_pll_clocks) constraint automatically creates
clocks for each output of any PLL in your design.
PLL的输出时钟,一般在生成pll的时候,会自动生成约束。
3.3 set_clock_groups
设置时钟组允许你指定在设计中不相关的时钟,默认情况下,时需分析器件会假定所有的时钟都是通过共有的时钟而相关的,因此所有在时钟域间的传递对于时序分析来说都是有效的,你可以通过切分成时钟组来排除时钟域之间的传递。
比如说,如果有两个时钟8ns和10ns的时钟,即使时钟是完全异步的,这个时序分析器件仍然企图建立2ns的建立时间关系,除非你用时钟组来指定这两个时钟是不相互关联的。另外时钟组并不是只能设置两个,你也可以继续无限制的添加。
3.4 Create Generated Clocks
此约束用于内部生成的时钟约束,比如说PLL,或者分频生成的时钟,但是分频生成的时钟我们一般不建议用来作为时钟信号。source指的是时钟源,比如说将clk进行倍频,那么clk就是时钟源。
3.5 set_input_delay
3.6 Output Constraints
3.7 set_false_path
set_false_path指的是不做时序检查,比如一些跨时钟域之间的数据传输可以不做时序检查,因此可以设置为set_false_path
4、调节时序的另类方法和经验
方法1
更改分析和综合的设置选项,第一种为速度型,就会更加兼顾速度,第三种将更加兼顾布线的面积。更改这些值后,重新编译,如果时序伪劣较小,很可能,更改后,时序伪例就消失了。
方法2
综合种子,这个值默认是1,但是也可以更改为其他不同的数值等都可以尝试,不同的值可能会影响最后的布线,可能最后伪劣会消失。
方法3
更改布线的预计最坏slack,如果时序违规在在0.5ns左右,可以通过此方法,如果违规太严重,那可能用此方法也未必生效。
以上三种方法都属于工程经验,记住即可, 都是试出来的,有可能你三个方法都用了会适得其反。
5、增加Fmax的另类方法
设置为3,虽然编译时间会增加,但是可以以运行时间为代价寻找到更好的路由。
并且把router Timing optimization level 更改为max
6、解决setup slack的正确方法
通过减少阻塞逻辑,减少rigister-to-register 的数据延时,所以最好就是if语句里面不要写太多的组合逻辑了,如果写了很多组合逻辑,我们可以输出flag标志的寄存器来处理,从而实现路径的分割。这也是插入pipeline的方法。
7、解决hold slack的正确方法
一般来说解决hold violation的情况是比较少见的,如果遇到,可以通过加一个lockup latch来解决。