时序违例的影响
1. 功能性错误(最主要影响)
数据错误:最常见的后果是数据采集或传输错误。例如,一个D触发器在时钟上升沿到来时,如果其输入数据还没有稳定(不满足建立时间),或者在时钟上升沿后很快就变化了(不满足保持时间),那么D触发器就可能采集到错误的数据,或者采集到亚稳态。
亚稳态:当建立时间和保持时间不满足时,触发器可能会进入亚稳态。处于亚稳态的触发器输出会在一个不确定的时间内保持在一个中间电压电平,然后随机地稳定到0或1。这会导致后续逻辑的输入不确定,传播到整个系统,使系统行为变得不可预测,甚至崩溃。
控制逻辑混乱:如果控制信号(如状态机中的下一状态信号)存在时序违例,状态机可能会进入错误的状态,导致整个控制流程紊乱。
2. 系统不稳定在
不同的温度、电压或工艺条件下,亚稳态的持续时间可能会变化,导致系统在某些情况下能正常工作,在另一些情况下则失败,难以调试。
3. 调试困难
时序违例导致的错误往往是间歇性的,难以重现和定位,增加了调试的难度和时间。
4. 功耗增加(间接影响)
亚稳态会导致触发器长时间处于中间电平,这会增加电路的功耗。
如何修复时序违例
修复时序违例是一个系统性的工作,通常需要从多个层面进行优化。
1. 完善时序约束(最重要)
准确定义时钟:确保所有主时钟、门控时钟、生成时钟都被正确定义。
定义时钟关系:如果设计中有多个时钟域,确保使用`set_clock_groups`或`set_false_path`正确地定义了它们之间的关系(例如异步时钟域或伪路径)。
定义输入/输出延迟:使用`set_input_delay`和`set_output_delay`精确地描述FPGA引脚外部的逻辑和时序,这是确保外部接口时序正确的基础。
定义多周期路径:对于某些允许在多个时钟周期内完成的逻辑路径,使用`set_multicycle_path`来放宽约束,避免误报。
排除伪路径:对于一些实际上不会影响功能,或者时序不重要的路径,使用`set_false_path`来告诉工具忽略它们。
2. 代码层面优化
优化组合逻辑深度:减少组合逻辑的级数。一个较深的组合逻辑链意味着信号需要更长的时间来传播。
流水线(Pipelining):将一个长的组合逻辑路径分解成多个较短的阶段,并在每个阶段之间插入D触发器。这会增加延迟(latency),但提高了吞吐量(throughput)和最大时钟频率。
寄存器平衡(Register Balancing):通过在逻辑路径上重新放置寄存器,使不同路径的时延更均衡。
使用专用硬件资源:优先使用FPGA内部的DSP块、RAM块、乘法器等专用硬核,它们通常比通用逻辑门实现相同功能的速度更快、效率更高。
避免门控时钟和异步复位(除非必要):门控时钟容易引入时钟偏移和毛刺,导致时序问题。异步复位虽然在某些情况下有用,但也可能导致复位释放时的时序问题(恢复时间/移除时间违例)。尽量使用同步复位。
优化算法:从算法层面减少计算量或并行化处理,从而减少逻辑深度。
减少扇出(Fanout):高扇出的信号意味着它驱动很多负载,这会增加传播延迟。可以通过插入缓冲器或者复制寄存器来降低扇出。
状态机编码:采用独热码(One-Hot)编码可以减少状态之间的组合逻辑,从而加快状态跳转的速度。
3. 综合与实现工具优化
优化策略:在综合和实现阶段,选择更积极的“性能优化”或“高频率”策略。这些策略会指示工具花费更多时间来优化时序。
增量编译:对于大型设计,如果只有小部分改动,可以尝试增量编译,以保留之前优化过的部分布局布线。
使用时序驱动的布局布线:确保工具在布局布线时以满足时序为主要目标,而不是仅仅最小化面积。
手动布局布线(不推荐常规使用):在极端情况下,对于最关键的时序路径,可能需要手动引导工具进行布局布线,但这是非常复杂和耗时的。
Phys_opt_design(Vivado):综合后、布局布线前运行物理优化,可以进一步优化设计,例如复制寄存器、移动寄存器、优化布线等,以帮助满足时序。
4. 架构层面优化
降低时钟频率:如果所有优化都无法满足时序,可能需要考虑降低系统时钟频率。
多时钟域设计:将系统分解为多个时钟域,每个时钟域运行在适合其逻辑复杂度的频率上。不同时钟域之间通过时钟域交叉(CDC)电路进行安全的数据传输。
重新思考设计:在极端情况下,可能需要重新审视设计架构,例如,是否可以用并行处理代替串行处理,是否可以简化某些复杂模块等。
5. 时钟域交叉(CDC)问题
时钟域交叉是时序违例的常见源头。当信号从一个时钟域传递到另一个时钟域时,必须采取特殊措施来避免亚稳态。
同步器(Synchronizer):最常见的CDC方法是使用两级或多级触发器(例如,两级同步器用于控制信号,FIFO用于数据)。
异步FIFO:用于跨时钟域传输大量数据,它能有效处理读写时钟的异步性。
握手协议:对于控制信号,可以使用请求/确认(request/acknowledge)握手协议来确保信号的稳定传输。