常用时序收敛方法
结构调整
结构调整是提高时域性能的一种方法,它是在不改变原有组合逻辑功能的前提下,通过调整其内部逻辑门之间的连接关系,来达到减少逻辑门级数的目的,进而提高时域性能的方法。举例如下:
现在有同步输入总线A、B、C、D,需要在下一时钟周期就能以寄存的方式输出它们的和SUM。那么通常来说,你可能会将HDL代码写成这样:
--VHDL example
--all inputs are scalar type
PROCESS (clk)
BEGIN
IF clk'event AND clk = '1' THEN
SUM <= A + B + C + D;
END IF;
END PROCESS;
// Verilog example
// all inputs are bus type
always@(posedge clk)
begin
SUM<=A+B+C+D;
end
对于上述代码,编译器通常会将它翻译成如图所示的电路。
由此可见,该电路中从“输入A~D”到“输出SUM的寄存器输人”之间,最长的逻辑路径依次经过了3个加法器,也就是说上述电路中的组合逻辑部分有3级加法器,如果一个加法器的时间延迟为T,那么整个组合逻辑的时间延迟就是3T.
编译器之所以会给出如此结构的电路,主要是因为在HDL语言中,“+”运算符号对应的运算优先关系为从左至右,因此A、B先参与运算,而其结果再和C一起送人下一个加法器运算,而这次的结果再和D一起送人第三个加法器进行运算,至此才得到组合形式输出的和。
通过进一步分析上述电路可以发现,当A、B进行运算时,C、D其实闲着没事干(虽然事实不是这样,但是此时第二、第三个加法器进行的运算都是无效的),因为第一、第二个加法器的输出还没有稳定;而当A、B或C参与有效运算时,D其实一直是闲着没事干的(解释类似同前),因为第二个加法器的输出还没有稳定。由此可见,上述电路中的逻辑结构不是很合理,因为我们更希望编译器得出的电路是同时使用两个加法器分别处理A、B和C、D的求和,然后再使用一个加法器处理这两个加法器的结果即可。为了达到这种效果,可以对上例进行一些修改,结果如下:
--VHDL example
--all inputs are scalar type
PROCESS (clk)
BEGIN
IF clk'event AND clk = '1' THEN
SUM <= (A + B) + (C + D);
END IF;
END PROCESS;
可见,我们仅仅通过添加了两个小括号,就调整了原有算式中不太合理的运算优先级关系,这便是“小括号的妙用”。对应上述代码,编译器给出的电路结构如图所示。
1、插入寄存器
将计算逻辑分成多个时钟周期实现,这是常用的时序优化方法,可以减少过多的组合逻辑层数,但会增加延时。
这里以一个多路输入求和计算为例
module sum(
input clk,
input [15:0] data_A,
input [15:0] data_B,
input [15:0] data_C,
input [15:0] data_D,
output [17:0] sum_o);
always @(posedge clk) begin
sum_o <= data_A + data_B + data_C + data_D;
end
endmodule
增加寄存器后,改为
module sum(
input clk,
input [15:0] data_A,
input [15:0] data_B,
input [15:0] data_C,
input [15:0] data_D,
output [17:0] sum_o);
reg [16:0] sum0, sum1;
always @(posedge clk) begin
sum0 <= data_A + data_B;
sum1 <= data_C + data_D;
end
always @(posedge clk) begin
sum_o <= sum0 + sum1;
end
endmodule
2、逻辑展平设计
优化代码中优先级译码电路逻辑,主要出现在IF/ELSE结构语句中,这样逻辑结构被展平,路径延迟得以缩短。
IF ELSE结构语句存在明显的优先级,建议尽量用CASE语句来替代。
3、防止变量被优化
HDL综合布线软件会根据实际情况,自动优化代码逻辑,可能存在将多个不同寄存器变量合并成一个寄存器变量的情况。
对于不希望被优化的变量,可以在变量定义前,添加(* keep = "ture" *)
高扇出
高扇出问题,原因是一个寄存器驱动后级数超过了它本身的驱动能力,导致延迟时间过大,不满足时序。
1、使用max_fanout
在变量定义前,可以添加(* max_fanout = n *),来设置变量的最大扇出数n,超过这个扇出数,综合软件会自动复制多份变量。
2、复位信号高扇出
复位信号是常见的高扇出问题,主要解决办法有:
(1)减少复位信号的使用,能使用使能信号控制的,就用使能信号。
(2)对于大型模块,复位信号可以使用BUFG来驱动复位信号,可以增加复位信号的驱动能力
资源消耗
FPGA器件的整个工程资源消耗,不管是LUT还是BRAM等资源,建议不超过80%。
一旦资源消耗超过80%,在布线综合时,就出现布线资源不够,导致出现布线拥塞,从而出现了时序不收敛的情况。
布线拥塞也分为全局拥塞和局部拥塞,可能是高扇出信号过多,也可能是局部布线资源不够用,导致时序路径过长。
1、优化代码逻辑,减少资源消耗。
在资源不够用的情况下,建议检查代码是否可优化,设置的RAM大小是否过大等等。
2、使用替代资源实现
在FPGA中实现RAM时,可以根据整个资源的使用情况,考虑使用Distributed RAM、URAM等资源来减少BRAM的消耗。