FPGA 设计总结(1)
1. set_input_delay和set_output_delay的选项-max和-min的理解
首先 input/output其实是模拟数据在端口外的延时,是一个外部约束条件,目的是为了约束FPGA输入端口到内部寄存器数据输入端或者内部寄存器输出端到FPGA输出端口之间允许的延时。计算max时考虑的是建立时间的情况,计算min时考虑的是保持时间的情况,delay参数来自于PCB走线。
2. 对于FPGA时钟同步设计,FPGA仿真最多到综合网表,更下层的仿真是徒劳,不仅耗费时间,同时FPGA存在库参数或布线时延反馈不准确的诸多问题。对于PAR的结果首先就要确保其时钟同步的特性。必须满足FPGA器件综合和布线后的setup和hold要求。一旦出现timing-error必须通过各种途径消除error,因为error的存在,意味着时钟同步的大前提已经被破坏,这时,simulation取得的结果和FPGA是不等价的,不解决时序问题,其他方式毫无意义了。
3. 外部接口也需要重点考虑。如前所述,FPGA内部如果timing没有问题的话,一般和仿真结果是一致的,问题是外部的接口,包括cable连线等,特别涉及数据宽度和频率,建议采用降频和先同步输入等方式来先行排除。
4. 重视syn和pr过程中的所有warning以及error,warning的内容不是完全可以忽略的。要特别关注综合报表中的以下内容:unused ports, reMOVal of redundant logic, latch inference,simulation mismatch等等,重点分析和排除。
5. 如果FPGA 验证要求不高,比喻工作频率比较低,同时资源也比较丰富时,除了时钟加必要的约束,尽量不要开始就完成一个全面的约束文件,防止不必要的约束,和早期问题的发现。如果在这种情况下,依然有时序问题:
1.时序问题hold,setup,特别是hold,首先检查对应的时钟域的时钟是否考虑周全,setup timing 问题主要是整体数据路径延时太大造成,hold timing问题主要是时钟延时太大造成,具体见6;
2.重点关注设计本身存在质量问题;
3.有条件参见正确工程,综合和实现设置环境差异,并进行调整尝试问题是否能够解决。
4.局部调整综合参数,如hierarchy从结构保持变成优化平铺综合,增加BUFG数量,将输出Fan out 改更小的合理范围等,重新编译和布局布线,检查时序问题是否消除。
5.一般是先解决setup问题,后解决hold问题,hold问题解决完的时候一般都是到了要tapout的时候了,最后一段时间如果发现有hold问题,一般会选择在满足setup的情况下将数据往后推,只有万不得已的情况下才会选择动时钟,因为时钟改变不仅影响本级DFF的时序,还会影响下一级DFF的时序;
6. 当FPGA用来实现ASIC的验证时,门控时钟就是不可避免的,比如ASIC上电复位时,不是所有的逻辑都同时工作起来,即只有一部分Flip-Flop开始工作,很大一部分可能根本没有收到有效的时钟,这种情况符合ASIC上电boot的流程,所以在FPGA上验证时要保留的;再比如ASIC工作在某一场景下需要降低功耗,会关闭某个module的时钟,这种为了降低功耗功能而存在的clock gate就可以直接优化掉,并不会影响FPGA验证ASIC的功能。所以在拿到ASIC RTL后要先将这种可以优化掉的clock gate挑拣出来并处理,再对处理后的RTL进行综合
6.重视和重点检查clock设计,原则下,时钟优先接入ibufg,对xilinx 7系列FPGA来说就是有MRCC和SRCC属性的引脚,这类引脚可以直接驱动BUFG,如果没有,内部手动第一连接BUFG + PLL/MMCME + BUFG,注意输出使用时也要接BUFG,再作为系统时钟给全局使用。约束时钟除了输入外,还要对BUFG输出系统时钟进行重点约束。故完整的时钟链 IBUFG/BUFG + PLL/MMCME + BUFG, 对于时钟不是IBUFG输入,vivado xdc还需要增加:
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets clk_in_IBUF] 便于布线器顺利完成布线,这里clk_in 指顶层模块输入 port。针对每个这种情况的输入时钟都需要在约束文件中插入, create_generated_clock:创建衍生时钟的约束同样非常常用,在FPGA中的design很少只工作在同一时钟下,所以create_generated_clock经常用于对MMCM或者PLL,甚至Flip-Flop分频产生的时钟增加约束,一个pin定义了两次create_generated_clock,这个pin很可能是个clk_mux的输出,它会工作在两种以上的时钟频率,所以对这两次定义的create_generated_clock要做一个set_clock_groups -logically_exclusive 的约束,说明这两个时钟不会同时存在。
7.针对FPGA Inter-Clock Paths 时序问题:
内部时钟域间通常没有直接的关系时,最好将其时钟域之间设置成ffalse_path,xilinx fpga xdc具体是:
set_false_path from [get_clocks clk0] -to [get_clocks {clk1 clk2 clk3}]
…
set_false_path from [get_clocks clk3] -to [get_clocks {clk0 clk1 clk2}]