如何实现乒乓操作.docx
《如何实现乒乓操作.docx》由会员分享,可在线阅读,更多相关《如何实现乒乓操作.docx(7页珍藏版)》请在冰点文库上搜索。
乒乓操作介绍
乒乓操作是通过“输入数据选择单元”和“输出数据选择单元’’按节拍的切换,将经过缓冲的数据流没有停顿地送到“数据流运算处理模块”进行运算处理。
把乒乓操作当作一个整体,站在这个模块的两端看数据,输入数据和输出数据都是连续不断的,因此非常适合对数据流进行流水线式处理,完成数据的无缝缓冲与处理。
处理流程:
输入数据流通过“输入数据选择单元”将数据流等时分配到两个数据缓冲区,数据缓冲模块可以为任何存储模块,比较常用的存储单元为双口RAM(DPRAM)、单口RAM(SPRAM)、FIFO等。
在第一个缓冲周期,将输入的数据流缓存到“数据缓冲模块1”;在第2个缓冲周期,通过“输入数据选择单元”的切换,将输入的数据流缓存到“数据缓冲模块2”,同时将“数据缓冲模块1”缓存的第1个周期数据通过“输入数据选择单元”的选择,送到“数据流运算处理模块”进行运算处理;在第3个缓冲周期通过“输入数据选择单元”的再次切换,将输入的数据流缓存到“数据缓冲模块1”,同时将“数据缓冲模块2”缓存的第2个周期的数据通过“输入数据选择单元”切换,送到“数据流运算处理模块”进行运算处理。
如此循环。
举个栗子:
输入数据存储区域分为buffer1和buffer1,各256个地址,为防止读写冲突,分两个状态:
state0读buffer2时,写buffer1;
state1读buffer1时,写buffer2;
当buffer存满,进行状态切换。
modulepingpang(clk,
rst_n,
data_in,//输入数据
data_out//输出数据
);
inputclk;
inputrst_n;
input[7:
0]data_in;
output[7:
0]data_out;
reg[7:
0]data_out;
reg[7:
0]buffer1[255:
0];//缓存区1
reg[7:
0]buffer2[255:
0];//缓存区2
regwr_flag;//写标志,wr_flag=0,写buffer1,wr_flag=1,写buffer2
regrd_flag;//读标志,rd_flag=0,读buffer2,wr_flag=1,读buffer1
regstate;//状态机,0:
写1读2,1:
写2读1,状态转移和输出分开编码
reg[7:
0]cnt;
parameterstate0=1'b0;
parameterstate1=1'b1;
always@(posedgeclkornegedgerst_n)//状态转移
begin
if(rst_n==1'b0)cnt<=0;
elsecnt<=cnt+1;
end
always@(posedgeclkornegedgerst_n)//状态转移
begin
if(rst_n==1'b0)state<=1'b0;
else
begin
case(state)
state0:
if(cnt==8'hff)state<=1'b1;
state1:
if(cnt==8'hff)state<=1'b0;
default:
state<=1'b0;
endcase
end
end
always@(state)//状态输出
begin
case(state)
state0:
begin
wr_flag=1'b0;//写1
rd_flag=1'b0;//读2
end
state1:
begin
wr_flag=1'b1;//写2
rd_flag=1'b1;//读1
end
default:
begin
wr_flag=1'b0;
rd_flag=1'b0;
end
endcase
end
always@(posedgeclk)
begin
case(wr_flag)
1'b0:
buffer1[cnt]<=data_in;//wr_flag=0,写buffer1
1'b1:
buffer2[cnt]<=data_in;//wr_flag=1,写buffer2
default:
begin
buffer1[cnt]<=8'b0;
buffer2[cnt]<=8'b0;
end
endcase
end
always@(posedgeclkornegedgerst_n)
begin
if(rst_n==1'b0)data_out<=8'b0;
else
begin
case(rd_flag)
1'b0:
data_out<=buffer2[cnt];//rd_flag=0,读buffer2
1'b1:
data_out<=buffer1[cnt];//rd_flag=1,读buffer1
default:
data_out<=8'b0;
endcase
end
end
endmodule
TB代码如下:
`timescale100ns/10ns
modulepingpang_tb_v;
//Inputs
regclk;
regrst_n;
reg[7:
0]data_in;
//Outputs
wire[7:
0]data_out;
//InstantiatetheUnitUnderTest(UUT)
pingpanguut(
.clk(clk),
.rst_n(rst_n),
.data_in(data_in),
.data_out(data_out)
);
initial
begin
//InitializeInputs
clk=0;
rst_n=0;
data_in=0;
#100;
rst_n=1;
end
always#10clk=~clk;
always@(posedgeclkornegedgerst_n)
begin
if(rst_n==1'b0)data_in<=8'b0;
elsedata_in<=data_in+1'b1;
end
endmodule
仿真波形如图:
当state进行状态切换后,数据读写存储区域发生了变化,实现乒乓的操作。
通过“输入数据选择单元”和“输出数据选择单元’’按节拍的切换,将经过缓冲的数据流没有停顿地送到“数据流运算处理模块”进行运算处理。
把乒乓操作当作一个整体,站在这个模块的两端看数据,输入数据和输出数据都是连续不断的,因此非常适合对数据流进行流水线式处理,完成数据的无缝缓冲与处理。