备注:fifo可以换成RAM等其他类型储存单元,只因熟悉fifo所以用它来说明(重点是如何使用乒乓式读写)
简介:一种常常应用于数据流控制的处理技巧,在保证等时域的前提下,两个fifo交互式的传输数据给数据处理模块。
处理流程:边看图边解释。首先是AD采集的数据流入,在等时域前提下,fifo1进行写操作,fifo2进行读操作(当然第一次没有可读的,但是数据流入的第一个周期是很短的)。fifo1中存储指定大小后,fifo控制模块中的开关寄存器控制fifo1拉低写使能,转而去拉高fifo2的写使能,这时候应该让fifo1开始写操作,fifo2开始读操作。如此往复循环,即可达到流水线的效果。
注意事项:该方法使用前提是一个fifo存储不够,或者写速率大于读速率时使用,否则一个fifo让其在读的同时进行写操作即可。
下面为我随便敲的代码,没有设计到读操作,应该我的数据处理模块在控制读操作。
module fifo_cntr(
input clk,
input rst_n,
input[10:0] fifo1_data_count, //fifo1可读量
input[10:0] fifo2_data_count, //fifo2可读量
input wrreq, //写请求
output fifo1_wrreq, //写fifo1请求
output fifo2_wrreq //写fifo2请求
);
parameter
idle = 4'b0000,
start = 4'b0010,
ping = 4'b0100,
pang = 4'b1000;
reg[3:0] state;
reg[3:0] next_state;
//状态寄存
always@(posedge clk or negedge rst_n)
begin
if(!rst)
state <= idle;
else
state <= next_state;
end
//状态转移
always@(*)
begin
case(state)
idle: if(wrreq)
next_state <= start;
else
next_state <= idle;
start: if(fifo1_data_count>=11'd1292)
next_state <= ping;
else
next_state <= start;
ping: if(fifo2_data_count>=11'd1292)
next_state <= pang;
else
next_state <= ping;
pang: if(fifo1_data_count>=11'd1292)
next_state <= ping;
else
next_state <= pang;
default: next_state<=idle;
endcase
end
//状态核心
always@(posedge clk or negedge rst_n)
begin
if(!rst)begin
fifo1_wrreq<=1'b0;
fifo2_wrreq<=1'b0;
end
else
case(next_state)
idle : ;
start : begin
fifo1_wrreq<=1'b1;
fifo2_wrreq<=1'b0;
end
ping : begin
fifo1_wrreq<=1'b0;
fifo2_wrreq<=1'b1;
end
pang: : begin
fifo1_wrreq<=1'b1;
fifo2_wrreq<=1'b0;
end
default:begin
fifo1_wrreq<=1'b0;
fifo2_wrreq<=1'b0;
end
endcase
end
endmodule
endmodule