两块同步FIFO实现乒乓操作

乒乓操作

同步FIFO实现乒乓

fifo1进行写,fifo2进行读(第一次没有可读,考虑数据流入的第一个周期很短)
fifo控制模块,写完fifo1指定深度后,拉低写使能,转而拉高fifo2的写使能
两块fifo,前提是一个fifo存储不够,或者写速率大于读速率

module fifo_pingpang(
 input rst_n,
 input clk,
 input [7:0]data_in,
 input wr_en,
 output reg fifo1_wr_en,
 output reg fifo2_wr_en,
 output reg fifo1_rd_en,
 output reg fifo2_rd_en,
 output [7:0]data_out
);


wire [8:0] fifo_cnt1;
wire [8:0] fifo_cnt2;

wire [7:0]data_out1;
wire [7:0]data_out2;
assign data_out=fifo1_rd_en?data_out1:data_out2;

parameter idle = 4'b0000,
         start = 4'b0001,
          ping = 4'b0010,
          pang = 4'b0100;
              
reg[3:0]state;
reg[3:0]next_state;
//
always@(posedge clk or negedge rst_n)begin
if(!rst_n) state<= idle;
else state <= next_state;
end
//
always@(posedge clk)begin
 case(state)
  idle:if(wr_en) 
       next_state <= start;
       else next_state <= idle;
  start:if(fifo_cnt1 == 9'd500)
        next_state <= ping;
        else next_state <= start;
  ping:if(fifo_cnt2 == 9'd500)
        next_state <= pang;
	    else next_state <= ping;
  
  pang:if(fifo_cnt1 == 9'd500)
       next_state <= ping;
       else next_state <= pang;
  default: next_state <= idle;	   
 endcase
end


//
always@(posedge clk or negedge rst_n)begin
 if(!rst_n)begin
  fifo1_wr_en <= 0;
  fifo2_wr_en <= 0;
 end
 else case(state)
  idle:begin
        fifo1_wr_en <= 0;
		fifo2_wr_en <= 0;
		fifo2_rd_en <= 0;
		fifo1_rd_en <= 0;
	   end
  start:begin
         fifo1_wr_en <= 1;
		 fifo2_wr_en <= 0;
		 fifo2_rd_en <= 1;
		 fifo1_rd_en <= 0;
		end  
  ping:begin
        fifo1_wr_en <= 0;
		fifo2_wr_en <= 1;
		fifo2_rd_en <= 0;
		fifo1_rd_en <= 1;
	   end
  pang:begin
        fifo1_wr_en <= 1;
		fifo2_wr_en <= 0;
		fifo2_rd_en <= 1;
		fifo1_rd_en <= 0;
	   end
  default:begin
          fifo1_wr_en <= 0;
		  fifo2_wr_en <= 0;
		  fifo2_rd_en <= 0;
		  fifo1_rd_en <= 0;
		  end
 
 endcase
end


syn_fifo syn_fifo_1(
 .wr_en(fifo1_wr_en),
 .rd_en(fifo1_rd_en),
 .data_in(data_in),
 .rst_n(rst_n),
 .clk(clk),
 .data_out(data_out1),
 .wr_full(),
 .rd_empty(),
 .fifo_cnt(fifo_cnt1)
);

syn_fifo syn_fifo_2(
 .wr_en(fifo2_wr_en),
 .rd_en(fifo2_rd_en),
 .data_in(data_in),
 .rst_n(rst_n),
 .clk(clk),
 .data_out(data_out2),
 .wr_full(),
 .rd_empty(),
 .fifo_cnt(fifo_cnt2)
);


endmodule

同步FIFO

module syn_fifo(
 input wr_en,
 input rd_en,
 input [7:0] data_in,
 input rst_n,
 input clk,
 output reg [7:0] data_out,
 output reg [8:0]fifo_cnt,
 output wr_full,
 output rd_empty
);

reg [8:0] rd_ptr,wr_ptr;
reg [7:0]fifo[0:512];

//
always@(posedge clk or negedge rst_n)begin
 if(!rst_n)begin
  rd_ptr <= 0;
  wr_ptr <= 0;
 end
 else begin
  if(!rd_empty && rd_en)begin
   if(rd_ptr == 500) rd_ptr <= 0;
   else rd_ptr <= rd_ptr + 1;
  end
  if(!wr_full && wr_en)begin 
   if(wr_ptr == 500) wr_ptr <= 0;
   else wr_ptr <= wr_ptr + 1;
  end
 end
end

always@(posedge clk or negedge rst_n)begin
 if(!rst_n) fifo_cnt <= 0;
 else if((!rd_empty && rd_en)&&(!wr_full && wr_en)) fifo_cnt <= fifo_cnt;
 else if(!rd_empty && rd_en) fifo_cnt <= fifo_cnt - 1;
 else if(!wr_full && wr_en) fifo_cnt <= fifo_cnt + 1;
 else fifo_cnt <= fifo_cnt;
end

always@(posedge clk or negedge rst_n)begin
 if(!rst_n) data_out <= 0; 
 else if(!rd_empty && rd_en) data_out <= fifo[rd_ptr];
 else if(!wr_full && wr_en) fifo[wr_ptr] <= data_in;
end


assign wr_full = (fifo_cnt == 500);
assign rd_empty = (fifo_cnt == 0);

endmodule

测试文件

`timescale 1 ps/ 1 ps
module fifo_pingpang_vlg_tst();
// constants                                           
// general purpose registers

reg clk;
reg [7:0]data_in;
reg rst_n;
reg wr_en;
// wires                                               
wire [7:0]  data_out;
wire fifo1_rd_en;
wire fifo1_wr_en;
wire fifo2_rd_en;
wire fifo2_wr_en;

// assign statements (if any)                          
fifo_pingpang i1 (
// port map - connection between master ports and signals/registers   
	.clk(clk),
	.data_in(data_in),
	.data_out(data_out),
	.fifo1_rd_en(fifo1_rd_en),
	.fifo1_wr_en(fifo1_wr_en),
	.fifo2_rd_en(fifo2_rd_en),
	.fifo2_wr_en(fifo2_wr_en),
	.rst_n(rst_n),
	.wr_en(wr_en)
);
initial                                                
begin                                                  
clk=0;
rst_n=0;
data_in=0;
wr_en=0;
#50 rst_n=1;
#50 wr_en=1;
#200000 $stop;                      
end  
                                                  
always #10 clk=~clk;                                                
                  
always #18 data_in=data_in+1;

                                                  
endmodule

两块同步FIFO实现乒乓操作_第1张图片

很清楚从上图看出两块FIFO的读写使能在循环往复。

两块同步FIFO实现乒乓操作_第2张图片
两块同步FIFO实现乒乓操作_第3张图片

从上图可以看出写进去地址1是9,读出来地址1也是9,单一FIFO读写无误。

你可能感兴趣的:(两块同步FIFO实现乒乓操作)