同步FIFO
数据宽度、FIFO深度 可配置
module synfifo #(parameter DEPTH=16, ADDR_WIDTH=4, DATA_WIDTH=8)(
input clk, rst_n, rd, wr,
input [DATA_WIDTH-1:0] datain,
output reg [DATA_WIDTH-1:0] dataout,
output reg empty, full
);
reg [DATA_WIDTH-1:0] mem [DEPTH-1:0];
reg [ADDR_WIDTH-1:0] rp,wp;
//mem and wp
always@(posedge clk)
if(!rst_n)
wp<=0;
else if(wr && !full)
begin wp<=wp+1; mem[wp]<=datain; end
//rp and dataout
always@(posedge clk)
if(!rst_n)
begin rp<=0; dataout<=0; end
else if(rd && !empty)
begin rp<=rp+1; dataout<=mem[rp]; end
//full
//判断条件:是否既读又写, 是否读, 正在写&指针关系
always@(posedge clk)
if(!rst_n)
full<=0;
else if(wr && rd) ;
else if(rd) full<=0;
else if(wr && (wp+1==rp || wp=={ADDR_WIDTH{1'b1}}&& rp==0)) full<=1;
//empty
always@(posedge clk)
if(!rst_n)
empty<=1;
else if(wr&&rd) ;
else if(wr) empty<=0;
else if(rd && ((rp+1==wp)|| rp=={ADDR_WIDTH{1'b1}} && wp==0)) empty<=1;
endmodule