时序一般是指一个设计的时钟速度,一个设计中的任何两个时序单元之间最大延时将决定这个设计的最大时钟速度。在进行设计构想时,就可以提前考虑时序,越顶层的优化所起到的收益越大。下面总结了一些思路,对于设计水平提高有帮助。
1.1 ASIC 设计时序优化方法
-
1、主要方法是通用设计“场景化”,减少不会用到的通用设计特性逻辑。
-
优化时序的策略是在关键路径中插入寄存器。这种技巧一般多用于高度流水的设计中,因为在这种设计中额外插入寄存器增加的时钟周期延迟并不会违反整个设计的规范要求,从而不会影响到设计的总体功能性实现。相对来说乘法操作非常适合流水,因为乘法运算易于被分开成多级运算。所以通过额外插入寄存器可以将乘法分开成多级流水实现。
-
对串行逻辑进行并行化处理。关键路径表达式变化为积之和或和之积形式。
-
逻辑展开(Flatten Logic Structures),展平逻辑结构。第一是逻辑复制,特别是针对大扇出,通常使用generate或者是在综合器中设定。第二个是消除代码中的优先级。最好写成case并行结构比较好。
-
寄存器平衡 (Register Balancing)。寄存器平衡就是在关键路径中移动寄存器。通过将某些时序紧张的stage的部分逻辑前移或者后置,进行WNS的balance。
-
寄存器重组,这是最有意思的一个方法,也是体现设计水平的方式。下面给出实例。
第一版 1 module randomlogic_1( 2 output reg [7:0] Out, 3 input [7:0] A, B, C, 4 input clk, 5 input Cond1, Cond2); 6 always @(posedge clk) 7 if(Cond1) 8 Out <= A; 9 else if(Cond2 && (C < 8)) 10 Out <= B; 11 else 12 Out <= C; 13 endmodule 第二版 1 module randomlogic_2( 2 output reg [7:0] Out, 3 input [7:0] A, B, C, 4 input clk, 5 input Cond1, Cond2); 6 7 wire CondB = (Cond2 & !Cond1); 8 9 always @(posedge clk) 10 if(CondB && (C < 8)) 11 Out <= B; 12 else if(Cond1) 13 Out <= A; 14 else 15 Out <= C; 16 endmodule
从代码上来看2版好像还比第一版路径更长,因为 out <= B,的路径从 Cond2 && (C < 8) 变成了 (Cond2 & !Cond1) && (C < 8)。实际上发现2版的关键路径真的比1短。
第2版的路径比第一版的关键路径少一个器件,这种做法从代码上看不出来。需要更高的硬件知识。
-
优化verilog的写法。主要是选择逻辑的写法,选择逻辑一级AOI会比一级MUX时延短。比如二选一情况下,if-else或者assign s=c?a:b会综合出MUX,建议使用assign s=c&a | !c&b。读选择逻辑最好不要使用a[index]索引写法。
-
对于fanout比较多的信号,低压后期可能有buffer插入,一级buffer两级逻辑需注意。
1.2 FPGA 设计时序优化方法
- 异步, 划分不同时钟域:比如系统主体可以工作在100M,特定的子系统要求必须工作在300M+,那么可以将特定模块划分到不同的时钟域里;但异步时钟域不宜太多。
- 综合时使用retiming,duplication;physical synthesis优化。
- 预算允许可使用速度更快的芯片;这个也许是实现 “不修改RTL又时序收敛” 的最可能的方式。
参考文档
【2】第一章 时序优化