笔者能力有限,如果文中出现错误的地方,还请各位朋友能够给我指出来,我将不胜感激,谢谢!
上一篇文章简单讲了一讲为什么需要进行多周期路径约束,这次讲讲如何进行多周期路径约束,以Xilinx FPGA为例。
我们要分三种情况来讨论多周期路径约束:
情况①:源时钟和目的时钟完全一致;
情况②:源时钟快于目的时钟;
情况③:源时钟慢于目的时钟;
--------------------------------------------------------------------------------------------------------------------------------
情况①就是设计中最常见的情况,源时钟和目的时钟频率相位波形完全一致,Vivado时序检查的依据就是:
- 当前的发射沿发送的数据能够被当前接收沿采集到(检查Setup Time)
- 当前的发射沿发送的数据不能够被上一个接收沿采集到(检查Hold Time)
- 下一个发射沿发送的数据不能够被当前接收沿采集到 (检查Hold time)
下图标注的launch edge和capture edge表示当前发射沿和接收沿。
如果此时加入了时钟使能信号,那么实际上有效的发射沿和接收沿其实是时钟使能信号为高的时候,即每2个周期有效一次,所以如果Vivado再像上面一样进行时序检查的话那要求会过于严格(当然也不是不行),因为当前设计其实是每2个周期数据变化一次而非单周期。
所以我们更希望如下图进行时序检查,总结就是:
- 当前有效发射沿发送的数据能够被当前有效接收沿采集到(检查Setup Time)
- 当前有效发射沿发送的数据不能够被上一个有效接收沿采集到(检查Hold Time)
- 下一个有效发射沿发送的数据不能够被当前有效接收沿采集到 (检查Hold time)
那么如何让Vivado工具这样检查呢,使用下面的tcl命令,注意tcl命令中数字对于setup检查约束和hold检查约束代表的含义不同:
假如源时钟名字为CLK1,目的时钟名字为CLK2
set_multicycle_path 2 -setup -end -from CLK1 -to CLK2
set_multicycle_path 1 -hold -end -from CLK1 -to CLK2
首先解释一下第一条tcl语句,
-setup:setup time检查约束;
2:跨越2个时钟周期(以哪个时钟为参考由end/start指定);
-end: 以目的时钟为参考时钟(-start则表示以源时钟为参考时钟);
执行第一条tcl语句后,setup time检查约束设置完毕,工具会如下图所示进行时序检查:
可以看到,setup time检查确实横跨了2个周期,但是hold检查点也发生了改变,原因是Vivado工具默认hold的检查是当前的发射沿发送的数据不能够被上一个接收沿采集到,工具认为的上个接收沿和当前接收沿只差了1个周期,这个和期望的不一样,因为现在其实是差了2个时钟周期!所以我们还需要进行hold time检查约束,即上面的第二条tcl语句,
-hold:hold time检查约束;
1:移动1个时钟周期;
-end:以目的时钟为参考时钟向左移动(-start则表示以源时钟为参考时钟向右移动);
执行这2条tcl命令后时序检查就符合我们的期望咯,如下图:
刚才讲的所有约束都是针对于目的时钟和源时钟每2个周期有效一次的情况,我们可以很容易推广到目的时钟和源时钟每N个周期有效一次的情况,分析方法和上面一样,执行如下tcl语句:
假如源时钟名字为CLK1,目的时钟名字为CLK2
set_multicycle_path N -setup -end -from CLK1 -to CLK2
set_multicycle_path N-1 -hold -end -from CLK1 -to CLK2