FPGA时序约束经历之输出延时约束(set_output_delay)

近期在进行emmc数据读写程序调试时,逼迫自己从一个时序小白跨进了时序约束的大门,这里记录一下供大家学习参考。

需求

emmc hs200模式下,允许最高时钟频率为200M。其中emmc和FPGA之间的引脚有单向EMMC_CLK,双向CMD和DATA[7:0]。根据emmc手册,要求建立时间为1.4ns,保持时间为0.8ns。EMMC_CLK是FPGA提供给emmc的,因此要求发送命令或数据时,CLK和CMD到达emmc芯片时要满足手册要求的建立和保持时间。

添加约束

要使输出的CLK和CMD满足emmc的建立保持时间,就需要告诉FPGA编译器,输出的延迟有多少。因此分两步:

第一步:添加时钟约束。

我用的是xilinx ,vivado软件,可以手写xdc约束文件,也可采用GUI界面,网上搜索如何进行约束,都是教的用手写,但遗憾的是,很多文章都是各种抄袭或者写得笼统粗略,对一个新手来说属实很难受(因为总出现语法错误还不知道原因)。因此这里推荐新手采用GUI添加约束,然后软件自动写到xdc文件,自己再去看,等熟练之后再进行手写。
点击implementation下的Edit Timing Constraints即添加约束
图1
图2
如图所示,可以添加时钟约束,输入输出约束等。
这里,我的时钟是锁相环锁出来的,然后连接到输出端口EMMC_CLK,因此属于衍生时钟,要用create generated clock(锁相环锁出来的或者自己写个分频代码分出来的都属于衍生时钟)。

第二步:添加输出延时。

添加好时钟后,就要添加我的CMD或者DATA相当于EMMC_CLK的输出延迟了,输出延迟的计算网上一搜一大堆,就不讲了,考虑PCB板级的走线延迟若为t,那么输出延迟设置的值max应为t+1.4,min值应为t-0.8,也就是输出延迟最大值应该是走线延迟加下级芯片的建立时间,最小值是走线延迟减去下级芯片的保持时间。
约束后的结果是

create_generated_clock -name CLK100M -source [get_pins pll/clk_in1] -multiply_by 1 -add -master_clock sys_clk [get_pins pll/clk_out2]
create_generated_clock -name emmc_clk -source [get_pins pll/clk_out2] -multiply_by 1 -add -master_clock CLK100M [get_ports emmc_clk]
set_output_delay -clock [get_clocks emmc_clk] -max -add_delay 1.600 [get_ports -filter { NAME =~  "*emmc*" && DIRECTION == "INOUT" }]
set_output_delay -clock [get_clocks emmc_clk] -min -add_delay -1.000 [get_ports -filter { NAME =~  "*emmc*" && DIRECTION == "INOUT" }]

我这里是由于不知道板级延时是多少,因此自己给多加的一点裕量。

现象

这里我用时序报告来给大家讲现象,至于时序报告怎么看,我认为这篇文章讲得很到位,我也是看这篇文章看懂的。
Vivado下如何阅读时序报告-知乎
我添加约束后有一个时序违例,报告建立时间裕度为负,也就是WNS为负,来看看报告。
先看保持时间
保持时间1
保持时间2
保持时间3
保持时间4
这里,保持时间的目标时钟Required Time 为10.223ns,vivado为了满足保持时间,让数据(Data Path)走了一个最小延迟为7.791ns的路径。
再看建立时间。
建立时间1
建立时间2
建立时间3
在建立时间中,Data Path数据路径是按最大值计算,这里由于保持时间中已经把路径定了,这里的数据路径延时就是16.115ns,但这直接导致了建立时间不满足时序了,也就是WNS为负。
我们来看布线图
布线图
途中就是这一条路径的走线,数据寄存器的起点和终点实际都在左上角,却在途中走了一个大圈。这里我在网上看到一个说法,无法求证,说vivado在编译的时候就是优先保证满足保持时间,再来满足建立时间。这个说法在这次实例中我认为得到了证明,这也就是平常WNS为负的情况比WHS为负的情况多的原因,也可以解释平常的WHS总是很小的现象。

时序优化

在这次实例中,我经过分析,我认为时序违例的原因是在计算保持时间裕度时,目的时钟的走线是按最大延迟计算,而这里我用了一个问号冒号语句来切换时钟,导致目的时钟算出来的最大延迟较大,所以数据路径被迫去绕一大圈来满足保持时间。而计算建立时间裕度时,目的时钟走线按最小延迟计算,我估计问号冒号语句时钟切换导致其最大延迟和最小延迟相差太大,因此采用了一个时钟切换小模块,不会产生毛刺的那种,替换了问号冒号。尔后这个问题就解决了。

总结

我认为分析时序违例,就得去看他违例的走线路径是怎么走的,然后分析导致裕度为负他的主要原因可能是哪里。然后再尝试更改设计。我是一个时序约束入门小白,若有理解不对,请大家留言指正,欢迎大家一起探讨。

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值