记一次简单的时序违例修复

中断了两个月没写了,主要是懒了,其次是家庭和工作影响。求S帮助!

闲话不多说,这次是老工程,换了综合器,结果在综合阶段就提示时序违例,setup worst slack 为-5.192:
image-127

这个数值一般不要继续去走实现阶段了,因为很难修复,虽然综合阶段的时序报告只是一个预估,但这里的-5.192负的太多了,指望布局布线过程去优化时序很难修到正,不过我还是跑了下,果然,最终结果是-1.142:
image-128

综合和实现阶段的最差时序路径基本是一致的:
image-129
image-130

好了,结果先过了一遍,回到综合的那边,看下是具体哪里的问题。综合报告这边给的时序路径起点是u_s2pD2pAdc01_0_0.srcInd[1],一直到终点是u_s2pD2pAdc01_0_0.state_c[4],时钟周期是8ns,数据延时是13.192ns,综合报告里数据路径很长,但是寄存器只有开头和末尾各一个,就是SLE,中间有大量的CFG3和CFG4,就是LUT3和LUT4(源语命名可以参microchip的官方文档:https://ww1.microchip.com/downloads/aemdocuments/documents/FPGA/swdocs/libero/pf_mlg_12_6_0.pdf),也就是有大量的LUT级联,组合逻辑太长了,路径中还插了一个乘法器进来,单这个器件引入的延迟就有2.182,所以的总的延迟累计就远超8ns的要求时间了
image-131
image-133

基于综合的结果,找下对应的实例是这个:
image-135

进到模块内部,找到起始寄存器srcInd,位宽为6bit:
image-136

顺着变量找,找到这里的组合逻辑链,并且这里有个乘法运算,是计算长度的:
image-137

并且长度最终和字节个数计数去比较,最终影响到state_c的状态:
image-138

整体大致的组合逻辑链就是:srcInd -> 乘法计算s_data_len_val -> 加法计算s_data_len_val_2 -> 移位长度向上取4的倍数 -> 长度比较 -> state_c状态跳转,组合逻辑确实很长,而且关键的有个乘法器MACC_PA在中间。先看下乘法的具体操作,DATA_LEN是一个固定参数,从上游模块调用实例来看,是33个9bit拼接出来的,关键是它的值是32个12和1个8拼接起来的,也就是说,不需要通过index动态计算去从DATA_LEN中取长度,它只有开头是8,其余的都是12,所以,可以考虑针对这个实例去做长度参数化,把原本的:

assign s_data_len_val   = DATA_LEN[(SRC_NUM-srcInd)*DATA_LEN_1W-1 -:DATA_LEN_1W] ;

替换为:

assign s_data_len_val   = DATA_LEN_FIXED_EN ? DATA_LEN_FIXED :
                          DATA_LEN_LAST_EN  ? ((srcInd == SRC_NUM-1) ?
                                               DATA_LEN_LAST : DATA_LEN_COMMON) :
                          DATA_LEN[(SRC_NUM-srcInd)*DATA_LEN_1W-1 -:DATA_LEN_1W] ;

再在模块实例化的地方传入DATA_LEN_FIXED相关参数,先只改这两处,跑下综合看看,果然改善不少,从-5.192降到了-0.362,而且worst path也不是这个路径了。
image-140

实现后时序直接为正了:
image-142

用非常少的代码就解决了这个时序问题,主要它比较特殊。但是这种改法并不完美,因为在不符合这类参数的消息时,还是会有乘法的问题,所以根治的方案应该是尝试在中间插入时序逻辑,去切分组合逻辑链路,在DATA_LEN中长度选择的这部分,可以改成查表方式,把所有可能的值都提前存起来根据index去选,而不是这种去在位宽里计算,后续有这种情况就要改的更彻底了。

posted @ 2026-08-25 13:48  原声带1993  阅读(10)  评论(0)    收藏  举报