问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

VIVADO时序违例优化详解

创作时间:
作者:
@小白创作中心

VIVADO时序违例优化详解

引用
CSDN
1.
https://blog.csdn.net/www_haha__/article/details/144074962

在FPGA设计中,时序违例是一个常见的问题,它可能导致逻辑功能错误、性能下降和可靠性降低。本文将详细介绍时序违例的概念、影响以及在VIVADO中的具体优化方法,包括时钟树设计优化、数据路径调整、时序约束设置等。通过本文,读者将能够掌握解决时序违例问题的实用技巧,提升FPGA设计能力。

VIVADO时序违例优化

知识点

在FPGA设计中,时序违例是指设计中的时序要求无法满足的情况。这通常发生在时钟频率过高或数据路径延迟过长时,导致信号无法在规定的时间内稳定或传输。

带来的影响

  1. 逻辑功能问题:时序违例可能导致FPGA设计的逻辑功能出错。由于时序不满足要求,数据可能无法在正确的时钟周期内被捕获或传输,从而导致设计的输出结果与预期不一致。这种不确定性可能导致系统在某些情况下无法正常工作。
  2. 性能问题:时序违例会限制设计的最高运行频率。如果设计存在时序违例,那么系统可能无法达到预期的时钟频率,从而影响整体性能。这可能导致系统处理速度变慢,无法满足应用需求。
  3. 可靠性问题:频繁的时序违例会增加电路元件的应力,可能导致器件老化加速,从而影响使用寿命和可靠性。此外,时序违例还可能导致电路中信号冒险和噪声增加,进一步加剧不确定性,降低系统的可靠性。

解决方案

  1. 优化时钟树设计
  • 通过时钟树平衡技术来确保时钟信号同时到达所有触发器。这有助于减少时钟偏差,从而满足时序要求。
  • 使用MMCM或PLL等时钟管理单元来优化时钟信号的质量和稳定性。
  • 合理设置时钟频率,避免过高或过低的时钟频率导致时序违例。
  1. 调整数据路径
  • 通过简化逻辑或使用更高效的逻辑结构来减少信号通过的逻辑级数。这有助于减少信号延迟,从而满足时序要求
  • 通过重新排列逻辑顺序,减少关键路径上的延迟。例如,可以通过重新设计逻辑,使得信号通过更少的逻辑门到达目的地。
  1. 调整时序约束
  • 设置合理的时序约束,避免过于严格的约束导致不必要的优化。同时,也要确保约束足够严格以满足设计要求。
  1. 优化异步信号处理
  • 对于异步时钟域之间的信号传递,要使用适当的同步机制来避免时序违例。例如,可以使用双寄存器同步或FIFO等缓冲机制来确保信号的稳定传递。

vivado 时序优化

上面说了那么多套话,最重要的还是要知道如何解决问题。

如上图,为我的一个工程的时序,先分析以下上面几个指标所代表的含义:

  1. Worst Negative Slack (WNS)
    WNS代表最差负时序裕量。在时序分析中,WNS是衡量设计中最差性能的一个指标。它表示在所有路径中,时序裕量最小的那个负值。如果WNS的值很大(即负得很多),那么意味着设计中有一些路径的时序性能非常差,可能需要进一步优化。

  2. Total Negative Slack (TNS)
    TNS代表总的负时序裕量。它是所有负时序裕量路径之和,即所有不满足时序要求的路径的裕量总和。TNS反映了设计中整体时序性能的一个范围。如果TNS的值很大,说明设计中有较多的路径不满足时序要求,这可能会对整个系统的性能产生负面影响。

  3. Number of Failing Endpoints
    有多少个端点(或路径)未能满足时序要求。它表示存在时序违例的端点数量。如果Number of Failing Endpoints的值很大,说明设计中有较多的路径存在时序问题,需要重点关注和优化。

  4. Total Number of Endpoints
    所有被分析的端点(或路径)的总数。它提供了时序分析的一个全局视角,帮助设计师了解整个设计的规模和复杂度。Total Number of Endpoints的值通常用于评估时序分析的全面性和准确性。

操作流程

本人也是刚开始研究vivado的时序优化,了解还不全面;下面的步骤也是自己琢磨出来的,如有错误请指正
下面一步一步优化上面工程的时序。
实现完成后(run implementation),点开时序分析汇总:
点击【OK】
按下面点开:
黄色框住的即为需要优化的时序,随机点进去一个,可以看到具体情况。主要关注的是From -To信号的违例两端
右键一行,点击 Schematic

在这里,可以清晰看到信号违例的两端:
到这里,我们就可以回到代码,找到这个信号,分析是否符合要求,有无跨时钟的现象等。
如果觉得该时序违例对工程不会构成影响,则可以忽略该违例(仅适用于固定在端口上的数据、缓存数据,不会一直随时钟改变):

点击【OK】
之后再重新 [run implementation],该时序违例消失,同时约束文件中会生成:

  
set_false_path -from [get_pins u_aurora_64b66b_top/u_aurora_64b66b_0/inst/aurora_64b66b_0_core_i/aurora_lane_2_i/lane_init_sm_i/lane_up_flop_i/C] -to [get_pins {u_vio/inst/PROBE_IN_INST/probe_in_reg_reg[4]/D}]
  

同时忽略多个违例

看下面这个违例:
有该路径有130条违例。但是你点进去只显示了10条。下面让他们全部显示出来:
点击[options],将[number of paths per group] 改为130:

这样就可以显示全部的违例情况。我发现这些为例全部为 ILA 的时钟问题,如果想将这130条全部忽略,该如何做:
保存完之后,会在 约束文件中生成一句话:

  
set_false_path -from [get_pins {u_rfsoc_wrapper/rfsoc_i/ps_samp_RnM/Dual_Flip_Flop_sync_0/inst/bram_wrdata_1_reg[*]/C}] -to *
  

跨时钟传输

如果发现自己必须跨时钟传输数据,比如:在时钟A下的数据data想在时钟B下处理。如何处理才能避免时序违例呢?
握手协议
握手协议是一种确保数据在稳定时进行采集和传输的方法。这种方法特别适用于对数据传输精度有严格要求的情况。以下是握手协议的一个基本流程:

  1. 数据准备:在时钟A域中,当数据data准备好后,发送一个启动信号(如信号A)到时钟B域。
  2. 数据传输:在时钟B域中,接收到启动信号后,开始准备接收数据。此时,时钟A域将数据data发送到时钟B域。
  3. 数据确认:时钟B域接收到数据后,可以发送一个确认信号(如信号B)回时钟A域,表示数据已成功接收。
  4. 数据锁定与释放:在时钟A域中,接收到确认信号后,可以锁定数据(即不再改变数据),并开始准备下一个数据的传输。同时,时钟B域可以开始处理接收到的数据。在处理完成后,时钟B域可以发送一个信号告诉时钟A域数据已被处理,此时时钟A域可以释放锁定的数据。
    打两拍
    打两拍法通常用于处理单bit信号,通过定义两个寄存器对输入的信号进行延拍,以确保信号的稳定性。以下是打两拍法的基本步骤:
  5. 第一拍采样:在时钟A的上升沿(或下降沿),将输入信号data采样到第一个寄存器中。
  6. 第二拍确认:在时钟A的下一个上升沿(或下降沿),将第一个寄存器中的值采样到第二个寄存器中。此时,第二个寄存器中的值已经是稳定的了,可以将其传输到时钟B域中进行处理。
    需要注意的是,打两拍法并不能完全消除亚稳态,但可以大大降低其出现的概率。
  
always @(posedge clkA or posedge rstA) begin
    if (rstA) begin
        data_sync1 <= 1'b0;
    end else begin
        data_sync1 <= data_from_clkA;
    end
end
always @(posedge clkB or posedge rstB) begin
    if (rstB) begin
        data_sync2 <= 1'b0;
    end else begin
        data_sync2 <= data_sync1;
    end
end
// 使用 data_sync2 作为 clkB 域中的有效数据
  

注意,该操作vivado的时序仍认为是违例的,它的判定条件就是看两端的时钟是否为同一个时钟。根据自己的分析来判断能否忽略
异步FIFO,双口RAM
对于多bit数据的跨时钟域传输,可以使用异步FIFO或双口RAM来解决问题。

  1. 异步FIFO:FIFO(First In First Out)是一种先进先出的存储器。在异步FIFO中,数据的写入和读出可以在不同的时钟域中进行。例如,可以在时钟A域中将数据写入FIFO,然后在时钟B域中从FIFO中读出数据。这种方法特别适用于数据产生速率和数据处理速率不匹配的情况。
  2. 双口RAM:双口RAM是一种具有两个独立访问端口的存储器。每个端口都可以独立地进行读写操作,并且可以在不同的时钟域中进行。因此,可以在时钟A域中将数据写入双口RAM的一个端口,然后在时钟B域中从另一个端口读出数据。这种方法特别适用于需要同时访问同一数据的不同时钟域的情况。

注释

记录自己第一次解决时序问题,应该有一些操作或者解释并不官方,后续有什么问题会补充。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号