流水线设计

流水线设计是指将组合逻辑延时路径系统地分割,并在各个部分(分级)之间插人寄存器暂存中间数据的方法.流水线缩短了在一个时钟周期内信号通过的组合逻辑电路延时路径长度,从而提高时钟频率.对于同步电路,其速度就是指同步电路时钟的频率,同步时钟愈快,电路处理数据的时间间隔越短,电路在单位时间内处理的数据量就愈大,即电路的吞吐量就越大,理论而言,采用流水线技术能够提高同步电路的运行。
就拿一个简单的例子来说吧。最近在研究数字图像处理方面的技术,初步想完成一个从RGB空间转到Ycbcr空间的功能。下面是我写的两个代码,实现的功能相同,都是将RGB565转成Ycbcr565。不过第二个是采用流水线设计的方法。先贴出代码。
module rgb2ycbcr1(
  input clk_50m ,
input reset_l ,
input [4:0] rgb_R ,
input [5:0] rgb_G ,
input [4:0] rgb_B ,
output  [4:0]   ycbcr_Y ,
output  [5:0]   ycbcr_cb ,
output  [4:0]   ycbcr_cr
);

reg  [15:0] ycbcr_Y_r1 ;
reg  [15:0] ycbcr_cb_r1 ;
reg  [15:0] ycbcr_cr_r1   ;

always @ (posedge clk_50m or negedge reset_l)
begin
if(!reset_l)begin
ycbcr_Y_r1  <=16'd0;
ycbcr_cb_r1 <=16'd0;
ycbcr_cr_r1 <=16'd0;
end
else begin
ycbcr_Y_r1  =((77*rgb_R + 150*rgb_G +29*rgb_B + 16'd32768  )>>8)    ;
ycbcr_cb_r1 =((16'd32768 - 43*rgb_R - 85*rgb_G + 128*rgb_B )>>8) ;
ycbcr_cr_r1 =((128*rgb_R - 107*rgb_G - 21*rgb_B + 16'd32768)>>8) ;
end
end

assign  ycbcr_Y  = ycbcr_Y_r1 [7:4] ;
assign  ycbcr_cb = ycbcr_cb_r1[ 8 :4 ] ;
assign  ycbcr_cr = ycbcr_cr_r1[ 7:4 ] ;

endmodule
上述代码在一个时钟周期内完成红色部分的计算,这样的话传播延迟就很大了,有三个加法器和一个乘法器。下面是综合后的RTL图:
流水线设计 - 靖harry - 靖harry的博客

时序报告中可以看到时钟的裕量为9.785:
流水线设计 - 靖harry - 靖harry的博客
 
然后看看采用流水线结构设计的代码:
module rgb2ycbcr2(
  input clk_50m ,
input reset_l ,
input [4:0] rgb_R ,
input [5:0] rgb_G ,
input [4:0] rgb_B ,
output  [4:0]   ycbcr_Y ,
output  [5:0]   ycbcr_cb ,
output  [4:0]   ycbcr_cr
);
/********************** The First Flow Line*************************/
reg  [15:0] rgb_R1 ;
reg  [15:0] rgb_R2 ;
reg  [15:0] rgb_R3   ;

always @ (posedge clk_50m or negedge reset_l)
begin
if(reset_l==1'b0)begin
rgb_R1  <=16'd0;
rgb_R2 <=16'd0;
rgb_R3 <=16'd0;
end
else begin
rgb_R1 <= 77*rgb_R     ;
rgb_R2 <= 43*rgb_R     ;
rgb_R3 <= 128*rgb_R    ;
end
end

reg  [15:0] rgb_G1 ;
reg  [15:0] rgb_G2 ;
reg  [15:0] rgb_G3   ;

always @ (posedge clk_50m or negedge reset_l)
begin
if(reset_l==1'b0)begin
rgb_G1  <=16'd0;
rgb_G2 <=16'd0;
rgb_G3 <=16'd0;
end
else begin
rgb_G1 <= 150*rgb_G    ;
rgb_G2 <= 85*rgb_G     ;
rgb_G3 <= 107*rgb_G    ;
end
end

reg  [15:0] rgb_B1 ;
reg  [15:0] rgb_B2 ;
reg  [15:0] rgb_B3   ;

always @ (posedge clk_50m or negedge reset_l)
begin
if(reset_l==1'b0)begin
rgb_B1 <=16'd0;
rgb_B2 <=16'd0;
rgb_B3 <=16'd0;
end
else begin
rgb_B1 <= 29*rgb_B      ;
rgb_B2 <= 128*rgb_B     ;
rgb_B3 <= 21*rgb_B      ;
end
end
/********************** The Second Flow Line*************************/
reg  [15:0] ycbcr_Y_r1 ;
reg  [15:0] ycbcr_cb_r1 ;
reg  [15:0] ycbcr_cr_r1   ;

always @ (posedge clk_50m or negedge reset_l)
begin
if(reset_l==1'b0)begin
ycbcr_Y_r1  <=16'd0;
ycbcr_cb_r1 <=16'd0;
ycbcr_cr_r1 <=16'd0;
end
else begin
ycbcr_Y_r1  <= rgb_R1 + rgb_G1 +rgb_B1 + 16'd32768   ;
ycbcr_cb_r1 <= 16'd32768 - rgb_R2 - rgb_G2 + rgb_B2  ;
ycbcr_cr_r1 <= 16'd32768 + rgb_R3 - rgb_G3 - rgb_B3   ;
end
end

/********************** The Third Flow Line*************************/
reg  [7:0] ycbcr_Y_r2 ;
reg  [7:0] ycbcr_cb_r2 ;
reg  [7:0] ycbcr_cr_r2   ;

always @ (posedge clk_50m or negedge reset_l)
begin
if(reset_l==1'b0)begin
ycbcr_Y_r2  <=8'd0;
ycbcr_cb_r2 <=8'd0;
ycbcr_cr_r2 <=8'd0;
end
else begin
ycbcr_Y_r2  <= ycbcr_Y_r1  >> 8   ;
ycbcr_cb_r2 <= ycbcr_cb_r1 >> 8   ;
ycbcr_cr_r2 <= ycbcr_cr_r1 >> 8   ;
end
end


/********************** To Ycbcr565 *************************/
assign  ycbcr_Y  = ycbcr_Y_r2 [7:3] ;
assign  ycbcr_cb = ycbcr_cb_r2[7:2] ;
assign  ycbcr_cr = ycbcr_cr_r2[7:3] ;

endmodule

 蓝色部分所示,是将之前在一个时钟周期内完成的操作分成3个周期完成。虽然直到第3个周期后才会有第一个数据输出,但是在以后的每个时钟周期内都会有处理完成的数据输出。也就是说,流水线设计只在刚开始处理时需要一定的处理时间,以后就会源源不断的输出数据。
 
下面是综合后的RTL图:

流水线设计 - 靖harry - 靖harry的博客
 
很明显,流水线方式增加了逻辑块的使用量,这是因为需要使用寄存器来构建流水线。这些寄存器使用逻辑块中的触发器实现。虽然多耗费了点资源,但可以使设计的时钟速率更快,从而满足时序约束条件。
流水线设计 - 靖harry - 靖harry的博客
 如图,意料之中,时钟的裕量为11.068,比之前的 9.785要大。这也体现了所谓的面积换速度的思想。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值