【FPGA——时序篇】时序优化的几种方法
参考博文:https://www.cnblogs.com/sepeng/p/5578402.html参考书目:英文版:《advanced FPGA design》中文版:《高级FPGA设计,结构,实现,和优化》衡量FPGA设计的两个重要指标是吞吐率和延迟。吞吐率:指系统每一个时钟周期内能够处理的数据数量,为了获得更高的吞吐率就需要减少组合逻辑延迟,在组合逻辑中间插入寄存器,也就...
参考博文:https://www.cnblogs.com/sepeng/p/5578402.html
参考书目:英文版:《advanced FPGA design》 中文版:《高级FPGA设计,结构,实现,和优化》
衡量FPGA设计的两个重要指标是吞吐率和延迟。
吞吐率:指系统每一个时钟周期内能够处理的数据数量,为了获得更高的吞吐率就需要减少组合逻辑延迟,在组合逻辑中间插入寄存器,也就是流水线设计。
延迟:指数据从输入系统到输出系统总共需要的时间,为了获得更短的延迟,可以减少组合逻辑延迟,或者删减路径上的寄存器,第二种方法显然不利于系统获得更好的性能。
时序优化的几种方法
这里说的优化是让FPGA设计获得更高的工作频率,也就是通常说的性能和吞吐率。
1.插入寄存器(pipeline)
这种方式会增加设计的时滞(clock latency)。插入了几个寄存器,结果输出就会延长几个周期,在不违反设计规格(对clock latency有要求)以及功能没有影响的时滞情况之下可以这么做。举例说明,如果下面一个FIR滤波器的设计没能满足时序要求。
module fir(
output [7:0] Y,
input [7:0] A,B,C,X,
input clk,
input validsample);
always @(posedge clk)
if(validsample) begin
X1<=X;
X2<=X1;
Y<=A*X+B*X1+C*X2;
end
endmodule
从代码可以看出,X2这条路径过长,是整个设计的Critical Path,如果采用流水线设计可以用寄存器暂存自已在执行Y的运算,改进如下:
module fir(
output [7:0] Y,
input [7:0] A,B,C,X,
input clk,
input validsample);
reg [7:0] X1,X2,Y;
reg [7:0] prod1,prod2,prod3;
always @(posedge clk) begin
if(validsample) begin
X1<=X;
X2<=X1;
prod1<=A*X;
prod2<=B*X1;
prod3<=C*X2;
end
Y<=prod1+prod2+prod3;
end
endmodule
2.并行化设计
并行化设计的思想是将一个逻辑函数分解为几个小一些的逻辑函数并行计算,从而减少关键路径上的延迟 。
例如计算两个8bits数的乘法,将8bits数分为两个4bits数,则乘法运算可以被分解为下面几个部分:
X∗X={A,B}∗{A,B}={(A∗A),(2∗A∗B),(B∗B)};X∗X={A,B}∗{A,B}={(A∗A),(2∗A∗B),(B∗B)};
通过这种方法可以将设计简化为一系列4bits乘法器的实现。
module power3(
output [7:0] XPower,
input [7:0] X,
input clk);
reg [7:0] XPower1;
//部分结果寄存器
reg [3:0] XPower2_ppAA,XPower2_ppAB,XPower2_ppBB;
reg [3:0] XPower3_ppAA,XPower3_ppAB,XPower3_ppBB;
reg [7:0] X1,X2;
wire [7:0] XPower2;
wire [3:0] XPower1_A = XPower1[7:4];
wire [3:0] XPower1_B = XPower1[3:0];
wire [3:0] X1_A = X1[7:4];
wire [3:0] X1_B = X1[3:0];
wire [3:0] XPower2_A = XPower2[7:4];
wire [3:0] XPower2_B = XPower2[3:0];
wire [3:0] X2_A = X2[7:4];
wire [3:0] X2_B = X2[3:0];
assign XPower2 = (XPower2_ppAA << 8) + (2*XPower2_ppBB << 4) + XPower2_ppBB;
assign XPower = (XPower3_ppAA << 8) + (2*XPower3_ppBB << 4) + XPower3_ppBB;
always @(posedge clk) begin
//第一级流水线
X1 <=X;
XPower1 <= X;
//第二级流水线
X2 <= X1;
XPower2_ppAA <= XPower1_A * X1_A;
XPower2_ppAB <= XPower1_A * X1_B;
XPower2_ppBB <= XPower1_B * X1_B;
//第三级流水线
XPower3_ppAA <= XPower2_A * X2_A;
XPower3_ppAB <= XPower2_A * X2_B;
XPower3_ppBB <= XPower2_B * X2_B;
end
endmodule
3.逻辑展平
通过优化掉设计中的优先级译码电路,逻辑结构被展平,路径延迟得以缩短,优先级译码电路常出现在IF/ELSE结构语句中出现。
module regwrite(
output reg [3:0] rout,
input clk,in,
input [3:0] ctrl);
always @(posedge clk)
if(ctrl[0]) rout[0] <= in;
else if(ctrl[1]) rout[1] <= in;
else if(ctrl[2]) rout[2] <= in;
else if(ctrl[3]) rout[3] <= in;
endmodule
上面代码综合后就会产生优先级译码器,通过各项平级的if语句或者case语句可以避免这样的优先级译码设计
//改进后
module regwrite(
output reg [3:0] rout,
input clk,in,
input [3:0] ctrl);
always @(posedge clk) begin
if(ctrl[0]) rout[0] <= in;
if(ctrl[1]) rout[1] <= in;
if(ctrl[2]) rout[2] <= in;
if(ctrl[3]) rout[3] <= in;
end
endmodule
4.均衡设计
均衡设计的思想是把 Critical Path 上的组合逻辑拿出一部分放在 short path 上进行,从而缩短 Critical Path 的延迟。
下面举例一个8位加法器。
module adder(
output reg [7:0] Sum,
input [7:0] A,B,C,
input clk);
reg [7:0] rA,rB,rC;
always @(posedge clk) begin
rA <= A;
rB <= B;
rC <= C;
Sum <= rA+rB+rC;
end
endmodule
可以看到,在寄存器rA,rB,rC之前的路径上没有组合逻辑,所以可以考虑把一部分计算拿到寄存器之前
//改进后
module adder(
output reg [7:0] Sum,
input [7:0] A,B,C,
input clk);
reg [7:0] rABSum,rC;
always @(posedge clk) begin
rABSum <= A + B;
rC <= C
Sum <= rABSum + rC;
end
endmodule
5.优化路径
最后一种方法也是我认为最难的,通过优化数据流的路径来缩短 Critical Path ,提升系统性能。重新布局和 Critical Path 在一起的路径,从而 Critical Path上的逻辑门可以更靠近目标寄存器。举一个栗子:
module randomlogic(
output reg [7:0] Out,
input [7:0] A,B,C,
input clk,
input Cond1,Cond2);
always @(posedge clk)
if(Cond1)
Out <= A;
else if(Cond2&&(C<8))
Out <= B;
else
Out <= C;
endmodule
可以看到C作为B的输出条件的路径最长,经过了一个比较器和两个逻辑门,是整个设计的 Critical Path ,可以做后续优化。
//改进后
module randomlogic(
output reg [7:0] Out,
input [7:0] A,B,C,
input clk,
input Cond1,Cond2);
wire CondB = (Cond2 &!Cond1);
always @(posedge clk)
if(CondB&& (C<8))
Out <= b;
else if(Cond1)
Out <= A;
else
Out <= C;
endmodule
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)