时序优化小技巧
总结来自公众号 数字IC自修室 https://mp.weixin.qq.com/s/9-BBNo2nxS81t_WLn2FWBg
关键路径通常是指同步逻辑电路中,组合逻辑时延最大的路径(这里我认为还需要加上布线的延迟),也就是说关键路径是对设计性能起决定性影响的时序路径。 尽可能的降低逻辑级数是在RTL端时序优化的关键,一般来说基本的NAND, NOR, INV按一级来算,BUF,以及MUX,AOI等复杂的cell则按2~2.5级来算。
1. 带逻辑运算的大位宽比较器
对于多bit的比较器,其关键路径逻辑级数一般估算为log2(N),N为待比较的数据位宽。当N不足2的幂次方时依然按其最接近的2的幂次方数来生成电路。比如37bit的数据进行比较,其逻辑级数约为log2(64)也就是6级左右。也就是说,如果比较的数据位宽是38,39,40…只要小于64都可以按6级来估算。基于此,如果该比较数据逻辑所在的路径是关键路径,对于一些与该比较器强绑定的逻辑可以纳入比较器的输入端进行比较操作,从而实现串转并,减少串行逻辑级数。最常见的一个做法是将比较结果的valid信号与待比较信号放一起进行比较操作:
`ifndef TIMING_OPT
// 未优化
assign comp_result = vaild&(src1 == src2);
`else
// 优化后
assign comp_result = {vaild,src1} == {1'b1,src2};
`endif
如此一来,原先比较器之后串行的一级与门被综合进比较器逻辑,关键路径深度减少1级。
- 优化前
-
优化后
可见,拆分后,避免了LUT2这一级的产生,时序得到了优化。
2. 比较器优先级拆分
对于多组优先级选择逻辑串联电路,如果其中有一个分支处于关键路径并且其优先级较低,可以将高于它的分支并行单独进行优先级判定,最后在与该关键路径分支进行优先级判定。
核心逻辑:优先级扁平化
如果关键路径是 din3,可将din3前面的进行优化
// prior level: 1>2>3>4>5>last
`ifndef TIMING_OPT
// NO optimization
assign dout = vaild1?din1:
vaild2?din2:
vaild3?din3:
vaild4?din4:dinlast;
`else
// after optimization
wire hi_prio_vaild;
wire [7:0] hi_prio_din;
assign hi_prio_din = vaild1?din1:din2;
assign hi_prio_vaild = vaild1|vaild2;
assign dout = hi_prio_vaild?hi_prio_din:
vaild3 ?din3 :
vaild4 ?din4 : dinlast;
`endif
3. 2选1优化
一般而言一级2选1选择逻辑要么被综合成与或,要么被综合成一级mux,在逻辑级数估算的时候约为1.5~2级。在某些非常timing critical的时候,连0.5~1级逻辑都需要去细抠,类似这样的选择逻辑就可以进行一个简化。对于2选1来说,如果从功能上能保证待选的两个信号在对方信号被选中的时候是全0互斥的,那么可以将这1级的mux或者与或门简化成1级或门。
对于数据选择来说,一般要做到上述对方被选中则己方数据全0是不可能的,这时可以通过显性地将选择信号做成与或逻辑,然后将与门进行打拍隔离来实现。