原创 乒乓操作及串并转换设计篇

2008-5-8 19:27 9020 9 9 分类: FPGA/CPLD

FPGA/CPLD重要设计思想及工程应用<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


乒乓操作及串并转换设计篇


 


概述


乒乓操作是一个常常应用于数据流控制的处理技巧,典型的乒乓操作方法如下图所示。


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


点击看大图


 


乒乓操作的处理流程


输入数据流通过输入数据选择单元将数据流等时分配到两个数据缓冲区,数据缓冲模块可以为任何存储模块,比较常用的存储单元为双口RAM(DPRAM) 、单口RAM(SPRAM) FIFO等。


在第一个缓冲周期,将输入的数据流缓存到数据缓冲模块1。在第2 个缓冲周期,通过输入数据选择单元的切换,将输入的数据流缓存到数据缓冲模块2,同时将数据缓冲模块1缓存的第1 个周期数据通过输出数据选择单元的选择,送到数据流运算处理模块进行运算处理。


在第3 个缓冲周期通过输入数据选择单元的再次切换,将输入的数据流缓存到数据缓冲模块1,同时将数据缓冲模块2缓存的第2 个周期的数据通过输出数据选择单元切换,送到数据流运算处理模块进行运算处理。如此循环。


 


利用乒乓操作完成数据的无缝缓冲与处理


乒乓操作可以通过输入数据选择单元输出数据选择单元按节拍、相互配合的切换,将经过缓冲的数据流没有停顿地送到数据流运算处理模块进行运算与处理


把乒乓操作模块当做一个整体,站在这个模块的两端看数据,输入数据流和输出数据流都是连续不断的,没有任何停顿,因此非常适合对数据流进行流水线式处理。所以乒乓操作常常应用于流水线设计中,完成数据的无缝缓冲与处理。


 


串并转换


串并转换是FPGA 设计的一个重要技巧,它是高速数据流处理的常用手段,串并转换的实现方法多种多样,根据数据的排序和数量的要求,可以选用寄存器、双口RAM(DPRAM) 、单口RAM(SPRAM) FIFO 等实现。


若想数据的缓冲区开得很大,可以通过DPRAM 实现了数据流的串并转换,对于数量比较小的设计可以采用寄存器完成串并转换。如无特殊需求,系统中应该用同步时序设计完成串并之间的转换。


 


那么在工程应用中,程序里怎么才能体现出串并转换设计的思想呢?怎么才能提高系统的处理速度呢?我们可以先来做一个串并转换的框架型设计。


 


这个章节老师没有给留下什么固定题目,所以自己构思起来也有点麻烦。想来想去就做个串入并出的设计吧。


设计的思想是这样的,有一组数据以50MHZ的速率从FPGA的一个I/O口传入,要实现在FPGA的另一端8I/O口以50/8MHZ的速率把传入的速率吐出。也就是说每隔8个主时钟周期要从8个输出口输出从输入口输入的8个数据。


 


功能仿真的波形如下:


点击看大图


 


如图,从rst完成复位(拉低)并且输入使能信号en置位(拉高)后输入的数据(头8个时钟周期)为10101010,在第9个时钟周期,输出使能信号en_out拉高了,说明此时可以从8位并行数据输出口取数了,data_out的输出16进制aa正好就是输入的10101010,所以第一个数据的串并转换正确无误。往后输入11110000,输出是16进制f0也没错……


该程序实现了串并转换的要求,这样原来50MH速率传送的数据经过FPGA串并转换后只要用1/8的时钟频率就能完成数据流的传输,也可以说这是一个面积换速度的典型。


 


程序:


module sp_top(scl,rst,en,sda,data_out,en_out);


input scl;//50MHz主时钟信号


input rst;//复位信号,高有效


input en;//数据输入使能,高有效


input sda;//串行输入数据


output[7:0] data_out;//并行输出数据


output en_out;//输出使能信号,高有效


 


wire[7:0] data_reg;//并行输出数据寄存器


wire  rdy;


 


series_in series_in(scl,rst,en,sda,data_reg,rdy);


parallel_out parallel_out(scl,rst,data_reg,rdy,data_out,en_out);


 


endmodule


 


 


module series_in(scl,rst,en,sda,data_reg,rdy);


input scl;


input rst;


input en;


input sda;


output[7:0] data_reg;


output rdy;


 


reg[7:0] data_reg;


reg[2:0] i;


reg rdy;


 


always @ ( posedge scl )


begin


    if(rst) begin i <= 3'd0; data_reg <= 8'dz; rdy <= 0; end


    else if(en)  


    begin


       data_reg <= {data_reg[6:0],sda};


       i <= i+1;


       if(i==3'd7) rdy <= 1;


       else rdy <= 0; 


    end


    else begin i <= 3'd0; data_reg <= 8'dz; rdy <= 0; end


end


 


endmodule


 


 


module parallel_out(scl,rst,data_reg,rdy,data_out,en_out);


input scl;


input rst;


input[7:0] data_reg;


input rdy;


output[7:0] data_out;


output en_out;


 


reg[7:0]   data_out;


reg en_out;


 


always @ ( posedge scl )


begin


    if(rst) begin data_out <= 8'dz; en_out <= 0; end


    else if(rdy) begin data_out <= data_reg; en_out <= 1; end


    else begin data_out <= 8'dz; en_out <=0; end


end


 


endmodule

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
9
关闭 站长推荐上一条 /3 下一条