特权同学

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

0
阅读(2850)

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

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

概述

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

点击看大图

乒乓操作的处理流程

输入数据流通过“输入数据选择单元”将数据流等时分配到两个数据缓冲区,数据缓冲模块可以为任何存 储模块,比较常用的存储单元为双口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的另一端8个I/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

Baidu
map