转载------FPGA的高速结构设计
本文来自:http://www.eefocus.com/Junking/blog/12-02/238956_c005e.html#articletop
FPGA设计中三个重要的性能指标是速度、面积和功耗,速度有三种基本定义:流量(Throughput)、时滞(Latency)、时序(Timing)。在FPGA处理数据的内容中,流量定义为每个时钟周期处理的数据量。流量的通常度量是每秒的位数。时滞定义为数据输入与处理的数据输出之间的时间,时滞的一般度量是时间或者时钟周期。时序定义为时序元件之间的逻辑延时,当一个设计没有满足时序时,意味着关键路径的延时,即触发器之间的最大延时比预定的时钟周期大,这些延时由组合逻辑延时、时钟到输出延时、布线延时、建立时间、时钟偏移等组成。时序的标准度量是时钟周期和频率。
1.流量
在处理数据的数字设计中,定义这个概念较为抽象的术语为:流水线。在流水线设计中一个重要的概念是“拆开环路”。拆开环路的代价是增加了面积。例如下面这个例子1。
module power3(
output [7:0] xpower,
output finnished,
input [7:0] x,
input clk, start
);
reg [7:0] ncount;
reg [7:0] xpower;
assign finished = (ncount == 0);
always @(posedge clk) begin
if (start) begin
xpower <= x;
ncount <= 2;
end
else if(!finished) begin
ncount <= ncount - 1;
xpower <= xpower * x;
end
end
endmodule
在这个例子中,设计性能为:流量 = 8/3, 时滞=3个时钟,时序=关键路径中一个乘法器的延时。
与相同算法的流水线对比,例2
module power3(xpower,clk,x);
output [7:0] xpower;
input clk;
input [7:0] x;
reg [7:0] xpower,xpower1,xpower2;
reg [7:0] x1,x2;
always @(posedge clk) begin
x1 <= x ; // pipeline stage 1
xpower1 <= x;
//pipeline stage 2
x2 <= x1;
xpower2 <= xpower1 *x1;
//pipelline stage 3
xpower <= xpower2 * x2;
end
endmodule
在上面的例子中,X的数值传递到两个流水线级,每级独立的资源计算相应的乘法操作。注意,当x在第二级流水线用来计算最后的三次幂的同时,X的下一个数值可以送到第一级流水线,x的三次幂的最后计算和下一个数值的第一次计算同时进行,这个设计的性能是:流量=8/1,时滞=3个时钟,时序=关键路径中一个乘法器的延时。
2.低时滞
低时滞设计是通过最小化中间处理的延时来尽可能快速的把数据从输入端传递到输出端的设计。通常,低时滞的设计将要求并行性、去除流水线、缩短逻辑、可能减少设计中的流量或者降低最大时钟速度。在上面的例子2中,去除寄存器,使用组合逻辑实现,可以减少时滞,但是增加了组合延时,使得系统设计中的时序 = 关键路径中两个乘法器的延时。
3.时序
时序指的是一个设计的时钟速度。在设计中任何两个时序元件的最大延时将决定最大的时钟速度。改善时序性能的方法有以下几种。
(1)添加寄存器层次
添加中间的寄存器层次到关键路径。这个技术应该利用在高度流水线的设计中。例如:
x1 <= x;
x2 <= x1;
y <= a * x + b * x1 + c * x2;
不满足时序要求,则可以在乘法器和加法器之间添加流水线结构,如:
pord1 <= a * x
pord2 <= b * x1;
pord3 <= c * x2;
y <= pord1 + pord2 + pord3;
(2) 并行结构
重新组织关键路径,并行实现逻辑结构,例如上例实现三次幂的结构中,可将8位二进制数,分成两个4位二进制数,重新进行运算。
(3)展平逻辑结构
此方法专门应用在因为特权编码而连接的逻辑。
(4)寄存器平衡
概念上讲,这个方法是平等的重新分布寄存器之间的逻辑,减少任何两个寄存器之间最坏条件的延时。这个技术应该随时利用在关键路径和相邻路径之间逻辑高度不平衡时。因为时钟速度只有最坏的条件路径来决定,可以做小的改变而成功的重新平衡关键逻辑。例如下例描述3个8位输入的加法器,
module adder (sum, a, b, c ,clk);
output [7:0] sum;
input [7:0] a, b, c;
input clk;
reg [7:0] sum, ra ,rb, rc;
always @(posedge clk) begin
ra <= a;
rb <= b;
rc <= c;
sum <= ra + rb + rc;
end
endmodule
第一个寄存器级是由ra,rb和rc组成,第二级由sum组成,级1和级2之间的逻辑是全部的输入的加法器,但是,输入与第一个寄存器之间不包含逻辑。如果通过加法器定义关键路径,在关键路径中的一些逻辑可以移回一级,用以平衡在两个寄存器级之间的逻辑负载。可以考虑一下修改:
module adder (sum, a, b, c ,clk);
output [7:0] sum;
input [7:0] a, b, c;
input clk;
reg [7:0] sum,rabsum, rc;
always @(posedge clk) begin
rabsum < = a+b;
rc <= c;
sum <= rabsum + rc;
end
endmodule
详细细节请参阅《高级FPGA设计,结构实现和优化》
好资料 非常感谢
谢谢 !
这。
Thank you very much!
只能用作教学,真正的运算,x <= a * b; ,这种语句是不合格的,应该拆成自己知道架构的乘法器。