module syn_fifo #(parameter FIFO_WIDTH = 32,
parameter FIFO_DEPTH = 16,
parameter ADDR_WIDTH = 4 )
(
input wire clk ,
input wire rst_n ,
input wire wr_en ,
input wire rd_en ,
input wire [FIFO_WIDTH-1 : 0] wr_data,
output reg [FIFO_WIDTH-1 : 0] rd_data,
output wire wr_full,
output wire rd_empty
);
reg [ADDR_WIDTH:0] wr_addr_ptr; //地址指针,比地址多一位,用来判断FIFO空满状态
reg [ADDR_WIDTH:0] rd_addr_ptr;
wire [ADDR_WIDTH-1:0] wr_addr; //RAM地址
wire [ADDR_WIDTH-1:0] rd_addr;
reg [FIFO_WIDTH-1:0] mem [0:FIFO_DEPTH-1];
integer i;
//========generate write pointer==============
always @(posedge clk, negedge rst_n) begin
if(~rst_n) begin
wr_addr_ptr <= 'h0;
end
else if(wr_en && (~wr_full)) begin
wr_addr_ptr <= wr_addr_ptr+1'b1;
end
end
//========generate read pointer================
always @(posedge clk, negedge rst_n) begin
if(~rst_n) begin
rd_addr_ptr <= 'h0;
end
else if(rd_en && (~rd_empty)) begin
rd_addr_ptr <= rd_addr_ptr+1'b1;
end
end
//write RAM
always @(posedge clk, negedge rst_n) begin
if(~rst_n) begin
for(i=0;i<FIFO_DEPTH;i=i+1) begin
mem[i] <= 'h0;
end
end
else if(wr_en) begin
mem[wr_addr] <= wr_data;
end
end
//read RAM
always @(posedge rd_clk, negedge rst_n) begin
if(~rst_n) begin
rd_data <= 'h0;
end
else if(rd_en) begin
rd_data <= mem[rd_addr];
end
end
assign wr_addr = wr_addr_ptr[ADDR_WIDTH-1:0];
assign rd_addr = rd_addr_ptr[ADDR_WIDTH-1:0];
assign wr_full = (wr_addr_ptr=={~rd_addr_ptr[ADDR_WIDTH],rd_addr_ptr[ADDR_WIDTH-1:0]});
assign rd_empty = (wr_addr_ptr==rd_addr_ptr);
endmodule
同步fifo代码(不需要例化RAM)
最新推荐文章于 2024-10-11 18:06:37 发布