Files
IPA/rtl/data_cache/async_fifo.v

86 lines
2.3 KiB
Coq
Raw Normal View History

2025-08-26 16:53:22 +08:00
module async_fifo #(
parameter DATA_WIDTH = 8,
parameter FIFO_DEPTH = 16
)(
input wr_clk,
input wr_rst_n,
input wr_en,
input [DATA_WIDTH-1:0] wr_data,
output full,
input rd_clk,
input rd_rst_n,
input rd_en,
output [DATA_WIDTH-1:0] rd_data,
output empty
);
reg [DATA_WIDTH-1:0] mem [FIFO_DEPTH -1 : 0];
reg [$clog2(FIFO_DEPTH) : 0] wr_ptr, rd_ptr;
integer i;
always@(posedge wr_clk or negedge wr_rst_n) begin
if(!wr_rst_n) begin
wr_ptr <= 'd0;
for(i=0;i<FIFO_DEPTH;i=i+1) begin
mem[i] <= 'd0;
end
end else if(wr_en && !full) begin
mem[wr_ptr[$clog2(FIFO_DEPTH)-1:0]] <= wr_data;
wr_ptr <= wr_ptr + 1'b1;
end else begin
wr_ptr <= wr_ptr;
end
end
always@(posedge rd_clk or negedge rd_rst_n) begin
if(!rd_rst_n) begin
rd_ptr <= 'd0;
end else if(rd_en && !empty) begin
rd_ptr <= rd_ptr + 1'b1;
end else begin
rd_ptr <= rd_ptr;
end
end
wire [$clog2(FIFO_DEPTH):0] wr_ptr_g , rd_ptr_g;
assign wr_ptr_g = wr_ptr ^(wr_ptr >>1);
assign rd_ptr_g = rd_ptr ^(rd_ptr >>1);
reg [$clog2(FIFO_DEPTH):0] wr_ptr_gr , wr_ptr_grr;
reg [$clog2(FIFO_DEPTH):0] rd_ptr_gr , rd_ptr_grr;
always@(posedge rd_clk or negedge rd_rst_n) begin
if(!rd_rst_n) begin
wr_ptr_gr <= 0;
wr_ptr_grr <=0;
end else begin
wr_ptr_gr <= wr_ptr_g;
wr_ptr_grr <= wr_ptr_gr;
end
end
always@(posedge wr_clk or negedge wr_rst_n) begin
if(!wr_rst_n) begin
rd_ptr_gr <= 0;
rd_ptr_grr <=0;
end else begin
rd_ptr_gr <= rd_ptr_g;
rd_ptr_grr <= rd_ptr_gr;
end
end
assign rd_data = mem[rd_ptr[$clog2(FIFO_DEPTH)-1:0]];
assign full = ((wr_ptr_g[$clog2(FIFO_DEPTH)] !=
rd_ptr_grr[$clog2(FIFO_DEPTH)]) && (wr_ptr_g[$clog2(FIFO_DEPTH)-1] !=
rd_ptr_grr[$clog2(FIFO_DEPTH)]-1) && (wr_ptr_g[$clog2(FIFO_DEPTH)-2:0] ==
rd_ptr_grr[$clog2(FIFO_DEPTH)-2 : 0])) ? 1:0;
assign empty = (rd_ptr_g[$clog2(FIFO_DEPTH) : 0] ==
wr_ptr_grr[$clog2(FIFO_DEPTH) :0]) ? 1:0;
endmodule