原创 基于FPGA的流水线设计

2008-4-30 17:01 10703 14 17 分类: FPGA/CPLD

FPGA/CPLD重要设计思想及工程应用


流水线设计篇


 


概述


流水线设计是高速电路设计中的一个常用设计手段。如果某个设计的处理流程分为若干步骤,而且整个数据处理是“单流向”的,即没有反馈或者迭代运算,前一个步骤的输出是下一个步骤的输入,则可以考虑采用流水线设计方法来提高系统的工作频率。


 


流水线处理的应用


在很多领域的高速电子系统中都运用了流水线处理的方法,如高速通信系统、高速采集系统、高速导航系统、高速搜索系统等等。流水线处理方式之所以能够很大程度上提高数据流的处理速度,是因为复制了处理模块,它是面积换取速度思想的又一种具体体现。


 


流水线设计应用实验


假设该设计为某实时通信系统的一个模块,该系统采样频率为5MHz,采样精度为32位。我们需要设计的内容为:对采样数据先进行加减偏移量的运算,假设需要加十六进制数00000077h的偏移量,然后把该数据压缩为16位数据,便于采样后的信号处理运算,压缩数据时保持精度相对高些。这里我们假设信号处理运算很简单,就是将压缩后的数据先减去十六进制数00ffh,然后取差值的低八位数据值做为该设计的输出。


<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /> 


在程序里,进行了四步的流水线作业。所以在功能仿真出来的波形图中可以看到,在en使能(粗黄线)后的三个时钟周期(也即第四个时钟上升沿)后(细黄线)en_out拉高了,dout端开始有输出的数据,而且输出的数据是每一个时钟周期来一个,和输入的数据是同步的。所谓流水作业,在实际硬件电路中就是把一个大的组合逻辑分成各个小的组合逻辑,每一个输入的信号都必须顺次通过各个阶段的操作,而各个阶段的操作又是同步进行的,这就像工厂的生产流水线一样,会有源源不断的数据信号从输出端送出。另外,从这个实验中也可以更深刻的体会到Verilog的并行性。



点击看大图


另外从综合后的RTL视图中可以看到四级的流水结构:



点击看大图


 


程序:


module liu_shui(clk,rst,data,en,en_out,dout);


       input clk;//时钟信号


       input rst;//复位信号


       input[31:0] data;//输入信号


       input en;//输入信号使能,如果为1说明有信号输入


       output en_out;//输出信号使能,如果为1说明输出经过处理的信号


      output[7:0] dout;//输出信号


 


       wire en_1,en_2,en_3;


       wire[31:0] dout_1;


       wire[15:0] dout_2,dout_3;


 


       liu_1 liu_1(clk,rst,data,en,en_1,dout_1);


       liu_2 liu_2(clk,rst,dout_1,en_1,en_2,dout_2);


       liu_3 liu_3(clk,rst,dout_2,en_2,en_3,dout_3);


       liu_4 liu_4(clk,rst,dout_3,en_3,en_out,dout);


 


endmodule


 


 


module liu_1(clk,rst,data,en,en_1,dout_1);


       input clk;


       input rst;


       input[31:0] data;


       input en;


       output en_1;


       output[31:0] dout_1;


      


       reg[31:0] dout_1;


       reg en_1;


 


       always@(posedge clk)


       begin


              if(!rst) begin dout_1 <= 32'h00000000;en_1 <= 0; end


              else if(en) begin dout_1 <= data+32'h00000077;en_1 <= 1; end


              else en_1 <= 0;


       end


 


endmodule


 


 


module liu_2(clk,rst,dout_1,en_1,en_2,dout_2);


       input clk;


       input rst;


       input[31:0] dout_1;


       input en_1;


       output en_2;


       output[15:0] dout_2;


      


       reg[15:0] dout_2;


       reg en_2;


 


       always@(posedge clk)


       begin


              if(!rst) begin dout_2 <= 16'h0000;en_2 <= 0; end


              else if(en_1) begin dout_2 <= dout_1[31:16];en_2 <= 1; end


              else en_2 <= 0;


       end


 


endmodule


 


 


module liu_3(clk,rst,dout_2,en_2,en_3,dout_3);


       input clk;


       input rst;


       input[15:0] dout_2;


       input en_2;


       output en_3;


       output[15:0] dout_3;


      


       reg[15:0] dout_3;


       reg en_3;


       parameter num="16"'h00ff;


 


       always@(posedge clk)


       begin


              if(!rst) begin dout_3 <= 16'h0000;en_3 <= 0; end


              else if(en_2) begin dout_3 <= dout_2-num;en_3 <= 1; end


              else en_3 <= 0;


       end


 


endmodule


 


 


module liu_4(clk,rst,dout_3,en_3,en_out,dout);


       input clk;


       input rst;


       input[15:0] dout_3;


       input en_3;


       output en_out;


       output[7:0] dout;


      


       reg[7:0] dout;


       reg en_out;


 


       always@(posedge clk)


       begin


              if(!rst) begin dout <= 8'h00;en_out <= 0; end


              else if(en_3) begin dout <= dout_3[7:0];en_out <= 1; end


              else en_out <= 0;


       end


 


endmodule

PARTNER CONTENT

文章评论3条评论)

登录后参与讨论

用户1809828 2014-11-21 16:46

好文章 赞

用户320946 2011-5-14 18:59

特权同学好文章,支持一下

用户191317 2009-4-2 10:06

求助: 请问如何在这个程序的基础上加上流水线 顶层模块 `timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 17:08:02 09/14/2007 // Design Name: // Module Name: da_fir // Project Name: // Target Devices: // Tool versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module da_fir(clk, reset, fir_in, fir_out); parameter IDATA_WIDTH = 12; //输入数据位宽 parameter PDATA_WIDTH = 13; //处理数据位宽 parameter FIR_TAP = 8; //fir滤波器抽头数 parameter FIR_TAPHALF = 4; //fir滤波器的一半抽头数 parameter COEFF_WIDTH = 12; //系数位宽 parameter OUT_WIDTH = 27; //输出数据位宽 parameter cof1 = 12'd41; parameter cof2 = 12'd132; parameter cof3 = 12'd341; parameter cof4 = 12'd510; parameter S0 = 1'b0; //初始状态 parameter S1 = 1'b1; //处理状态 input clk; input reset; input [IDATA_WIDTH-1:0] fir_in; output [OUT_WIDTH-1:0] fir_out; reg [OUT_WIDTH-1:0] fir_out; reg [IDATA_WIDTH-1:0] fir_in_reg; reg [PDATA_WIDTH-1:0] shift_buf[FIR_TAP-1:0]; //定义移位寄存器 reg [PDATA_WIDTH-1:0] add_buf[FIR_TAPHALF-1:0]; reg [PDATA_WIDTH-1:0] state_shift_buf[FIR_TAPHALF-1:0]; wire [3:0] table_4b; //查表输入 wire [COEFF_WIDTH-1:0] table_out_12b; //查表输出 reg [OUT_WIDTH-1:0] sum; reg STATE; reg [3:0] divfre_count_4b; reg divfre13_clk; integer i,j,k,l,m,n,p; //定义移位寄存器左移的函数delta function [OUT_WIDTH-1:0] delta; input [OUT_WIDTH-1:0] IQ; input [3:0] pipe; begin case(pipe) 4'b0000: delta = IQ; 4'b0001: delta = {IQ[OUT_WIDTH-2:0],1'b0}; 4'b0010: delta = {IQ[OUT_WIDTH-3:0],2'b00}; 4'b0011: delta = {IQ[OUT_WIDTH-4:0],3'b000}; 4'b0100: delta = {IQ[OUT_WIDTH-5:0],4'b0000}; 4'b0101: delta = {IQ[OUT_WIDTH-6:0],5'b00000}; 4'b0110: delta = {IQ[OUT_WIDTH-7:0],6'b000000}; 4'b0111: delta = {IQ[OUT_WIDTH-8:0],7'b0000000}; 4'b1000: delta = {IQ[OUT_WIDTH-9:0],8'b00000000}; 4'b1001: delta = {IQ[OUT_WIDTH-10:0],9'b000000000}; 4'b1010: delta = {IQ[OUT_WIDTH-11:0],10'b0000000000}; 4'b1011: delta = {IQ[OUT_WIDTH-12:0],11'b00000000000}; 4'b1100: delta = {IQ[OUT_WIDTH-13:0],12'b000000000000}; 4'b1101: delta = {IQ[OUT_WIDTH-14:0],13'b0000000000000}; 4'b1110: delta = {IQ[OUT_WIDTH-15:0],14'b00000000000000}; 4'b1111: delta = {IQ[OUT_WIDTH-16:0],15'b000000000000000}; default: delta = IQ; endcase end endfunction always @(posedge clk or negedge reset) begin if(!reset) begin divfre13_clk <= 1'b0; divfre_count_4b <= 4'b0000; end else begin if(divfre_count_4b==PDATA_WIDTH) begin divfre_count_4b <= 4'b0000; divfre13_clk <= 1'b1; end else begin divfre_count_4b <= divfre_count_4b + 1'b1; divfre13_clk <= 1'b0; end end end always @(posedge clk or negedge reset) begin if(!reset) fir_in_reg <= 12'b0000_0000_0000; else if(divfre13_clk) fir_in_reg <= fir_in; end always @(posedge clk or negedge reset) begin if(!reset) for(i=0; i<=FIR_TAP-1; i=i+1) shift_buf[i] <= 13'b0000_0000_00000; else if(divfre13_clk) begin for(j=0; j
相关推荐阅读
特权ilove314 2016-06-30 21:16
例说FPGA连载6:FPGA开发所需的技能
例说FPGA连载6:FPGA开发所需的技能 特权同学,版权所有 配套例程和更多资料下载链接: http://pan.baidu.com/s/1c0nf6Qc   前面的文字已经做了很多铺垫,相信读...
特权ilove314 2016-06-28 21:09
例说FPGA连载5:FPGA的优势与局限性
例说FPGA连载5:FPGA的优势与局限性 特权同学,版权所有 配套例程和更多资料下载链接: http://pan.baidu.com/s/1c0nf6Qc   若要准确评估FPGA技术能否满足开...
特权ilove314 2016-06-28 21:05
例说FPGA连载5:FPGA的优势与局限性
例说FPGA连载5:FPGA的优势与局限性 特权同学,版权所有 配套例程和更多资料下载链接: http://pan.baidu.com/s/1c0nf6Qc   若要准确评估FPGA技术能否满足开...
特权ilove314 2016-06-26 22:11
例说FPGA连载4:FPGA语言与厂商介绍
例说FPGA连载4:FPGA语言与厂商介绍 特权同学,版权所有 配套例程和更多资料下载链接: http://pan.baidu.com/s/1c0nf6Qc   Verilog与VHDL 说到FP...
特权ilove314 2016-06-23 21:26
例说FPGA连载3:FPGA与其它主流芯片的比较
例说FPGA连载3:FPGA与其它主流芯片的比较 特权同学,版权所有 配套例程和更多资料下载链接: http://pan.baidu.com/s/1c0nf6Qc   FPGA、ASIC和ASSP...
特权ilove314 2016-06-21 20:32
例说FPGA连载2:FPGA是什么
例说FPGA连载2:FPGA是什么 特权同学,版权所有 配套例程和更多资料下载链接: http://pan.baidu.com/s/1c0nf6Qc   2015年伊始,Intel欲出资百亿美金收...
EE直播间
更多
我要评论
3
14
关闭 站长推荐上一条 /3 下一条