一、流水线设计的概念
所谓流水线设计实际上是把规模较大、层次较多的组合逻辑电路分为几个级,在每一级插入寄存器组并暂存中间数据。K级流水线就是从组合逻辑的输入到输出恰好有K个寄存器组(分为K级,每一级都有一个寄存器组),上一级的输出是下一级的输入而又无反馈的电路。
如果某个设计可以分为若干步骤进行处理,而且整个数据处理过程是单向的,即没有反馈运算或者迭代运算,前一个步骤的输入即使下一个步骤的输出,就可以考虑采用流水线设计方法来提高系统的工作频率。
二、流水线设计的优点
硬件描述语言的一个突出优点就是指令执行的并行性。多条语句能够在相同时钟周期内并行处理多个信号数据。但是当数据串行输入时,指令执行的并行性并不能体现出其优势。流水线设计(Pipeline Design)是经常用于提高所设计系统运行速度的一种有效的方法。为了保障数据的快速传输,必须使系统运行在尽可能高的频率上,但如果某些复杂逻辑功能的完成需要较长的延时,就会使系统很难运行在较高的频率上。在这种情况下,可使用流水线技术,即在长延时的逻辑功能块中插入触发器,使复杂的逻辑操作分步完成,减少每个部分的延时,从而提高系统的运行频率。流水线的代价就是增加了寄存器的使用,增加了芯片资源的耗用,很好的体现了面积换速度的思想。
二、流水线设计的流程
目前大部分FPGA都是基于4输入LUT的,如果一个输出对应的判断条件大于四输入,那么要由多个LUT级联才能完成,这样就引入了一级组合逻辑时延。要减少组合逻辑,无非是要输入条件尽可能地少,这样就可以使级联的LUT更少,从而减少了组合逻辑引起的时延。
以8位全加器为例阐述流水线设计方法的实现,非流水线方式实现8位全加器Verilog代码如下:
module add8(
output reg cout,
output reg [7:0] sum,
input [7:0] ina,
input [7:0] inb,
input cin,
input clk
);
reg [7:0] tempa,tempb;
reg tempc;
always@(posedge clk)begin
tempa <= ina;
tempb <= inb;
tempc <= cin;
end
always(posedge clk)
{cout,sum} <= tempa + tempb + tempc;
endmodule
未采用流水线设计的8位全加器的RTL综合视图:
按照流水线的设计思想可以将8位全加器划分为4个2位全加器,在其中加入数据存储器分为4级,每一级单独工作,如图,使用流水线思想设计的8位全加器的Verilog代码如下:
module pipeline (
input clk,
input cin,
input [7:0] ina,
input [7:0] inb,
output reg cout,
output reg [7:0] sum
);
// reg cout;
reg [7:0] tempa, tempb;
reg tempc, firstco, secondco, thirdco;
reg [1:0] firsts, thirda, thirdb;
reg [3:0] seconda, secondb, seconds;
reg [5:0] firsta, firstb, thirds;
always @(posedge clk) begin
tempa = ina;
tempb = inb;
tempc = cin;
end
always @(posedge clk) begin
{firstco, firsts} = tempa[1:0] + tempb[1:0] + tempc;
firsta = tempa[7:2];
firstb = tempb[7:2];
end
always @(posedge clk) begin
{secondco, seconds[3:2]} = firsta[1:0] + firstb[1:0] + firstco;
seconda = firsta[5:2];
secondb = firstb[5:2];
seconds[1:0] = firsts;
end
always @(posedge clk) begin
{thirdco, thirds[5:4]} = seconda[1:0] + secondb[1:0] + secondco;
thirda = seconda[3:2];
thirdb = secondb[3:2];
thirds[3:0] = seconds;
end
always @(posedge clk) begin
{cout, sum[7:6]} = thirda[1:0] + thirdb[1:0] + thirdco;
sum[5:0] = thirds;
end
endmodule
4级流水线的RTL视图:
testbench代码:
`timescale 1ns / 1ps
module tb_pipeline;
// pipeline Parameters
parameter PERIOD = 10;
// pipeline Inputs
reg clk = 0 ;
reg cin = 0 ;
reg [7:0] ina = 8'd255 ;
reg [7:0] inb = 8'd100 ;
// pipeline Outputs
wire cout ;
wire [7:0] sum ;
initial
begin
forever #(PERIOD/2) clk=~clk;
end
//initial
//begin
// #(PERIOD*2) rst_n = 1;
//end
pipeline u_pipeline (
.clk ( clk ),
.cin ( cin ),
.ina ( ina [7:0] ),
.inb ( inb [7:0] ),
.cout ( cout ),
.sum ( sum [7:0] )
);
initial
begin
#(PERIOD*20);
$finish;
end
endmodule