流水线(pipeline)设计详解+实例:为什么要用流水线?流水线的作用和优缺点?流水线深度越大越好吗?什么时候采用流水线?

流水线(pipeline)设计详解+实例:为什么要用流水线?流水线的作用和优缺点?流水线深度越大越好吗?什么时候采用流水线?

1.流水线设计的概念

所谓流水线设计,实际上就是把规模较大、层次较多的组合逻辑电路分为几级,在每一级插入寄存器组并暂存中间数据。K级流水线就是从组合逻辑的输入到输出恰好有K个寄存器组,上一级的输出是下一级的输入而又无反馈的电路。

2.流水线的作用

(1)流水线可以提高电路的吞吐率

吞吐率就是数据输入机器的速率或处理数据的速率。吞吐率最终受到以下几种具有最大传播延时的通路的限制:

a. 原始输入到一个寄存器的通路;

b. 一对寄存器间的通路;

c. 由寄存器到原始输出间的通路;

d. 从一个原始输入到原始输出间的通路。

每种情况下,组合逻辑都限制了机器的性能。作为一种能够提高电路性能的可选方法,可以将流水线型寄存器插入到组合逻辑的关键位置上,将逻辑分割成具有更短路径的群组。流水线技术减少了组合逻辑中的级数,缩短了存储元件之间的数据通路,并且因为能用更高的时钟频率而提高了电路的吞吐能力。

(2)流水线提高了电路的频率

假设通过原多级组合逻辑的最长路径的时间为Tmax,则工作频率为 f1 = 1 / Tmax。如果用寄存器可以将该路径从中间切开,创建两个逻辑块,每个都具有最大时间长度 Tmax / 2,那么流水线型电路将可以工作在 f2 = 2 / Tmax = 2f1 的频率上。

需要注意的是:数据通路的划分必须要保证数据的相关性——从原始输入到原始输出的所有数据通路必须要穿过同样数量的流水线寄存器。如下图所示的四选一电路中,插入流水线寄存器时,不仅要在MUX1、MUX2之后,在MUX3的select端同样需要一个流水线寄存器。若没有这个寄存器,会导致选择信号 s[1] 到达MUX3的时间点和MUX1、MUX2的输出到达MUX3的时间点不一致。

插入流水线寄存器后(三个寄存器,分别在两个MUX之后和s[1]):

3.流水线深度越大越好吗?

上面讲到了流水线的优点:可以缩短时钟的周期并提高吞吐能力。而流水线的缺点在于:

(1)产生了输入-输出延迟:由于插入了流水线寄存器,会导致第一个输出必须在K个clk之后才能得到。而之后每个clk都能得到一个输出。

(2)流水线技术是用空间(硬件)的复杂度来换取时间(性能)的复杂度。由上述分析可知,电路中插入了流水线计数器,必然会导致电路的面积增大。

所以:流水线深度并不是越大越好。在提高电路速度和吞吐的同时,电路的面积也随之加大。所以必须根据具体的需求来对流水深度进行择优选择。

4.什么时候采用流水线?

设计中应采用最小数目的流水线寄存器来获取最短的循环周期。在关键路径上的时间裕度无法满足时,就要考虑使用流水线技术。

5.流水线设计实例:流水线型加法器

对于两个8位加法器串行连接形成的16位加法器,电路图:

verilog代码:

adder.v

module adder (

c_in,

a,

b,

sum,

c_out

);

input c_in ;

input [7: 0] a, b ;

output [7: 0] sum ;

output c_out ;

assign { c_out, sum } = a + b + c_in;

endmodule

top.v

module top (

c_in,

a,

b,

sum,

c_out

);

input c_in ;

input [15: 0] a, b ;

output [15: 0] sum ;

output c_out ;

wire cout1 ;

adder adder1 (

.c_in ( c_in )

,.a ( a[7: 0] )

,.b ( b[7: 0] )

,.sum ( sum[7: 0] )

,.c_out ( cout1 )

);

adder adder2 (

.c_in ( cout1 )

,.a ( a[15: 8] )

,.b ( b[15: 8] )

,.sum ( sum[15: 8] )

,.c_out ( c_out )

);

endmodule

插入流水线寄存器后的电路:

verilog:

module adder_pipe(

a,

b,

c_in,

clock,

sum,

c_out

);

input [15: 0] a, b ;

input c_in, clock ;

output [15: 0] sum ;

output c_out ;

reg [32: 0] IR ;

reg [24: 0] PR ;

reg [16: 0] OR ;

assign { c_out, sum } = OR ;

always @( posedge clock ) begin

// load input register

IR[0] <= c_in ;

IR[ 8: 1] <= a[ 7: 0] ;

IR[16: 9] <= b[ 7: 0] ;

IR[24: 17] <= a[15: 8] ;

IR[32: 25] <= b[15: 8] ;

// load pipeline register

PR[24: 17] <= IR[32: 25] ;

PR[16: 9] <= IR[24: 17] ;

PR[ 8: 0] <= IR[16: 9] + IR[8: 1] + IR[0] ;

OR <= {{ 1'b0, PR[24: 17] } + { 1'b0, PR[16: 9] } + PR[8] + PR[7: 0] } ;

end

endmodule

💡 相关推荐

韩国秋天爬山指南:在红叶中徒步旅行
谁有365bet网址

韩国秋天爬山指南:在红叶中徒步旅行

📅 08-15 👀 6877
荣耀8x和荣耀10哪个好
mobile365体育手机版入口

荣耀8x和荣耀10哪个好

📅 06-27 👀 7862
卡塔尔世界杯
mobile365体育手机版入口

卡塔尔世界杯

📅 07-26 👀 757