16Bit - Asynchronous FIFO (Feature Request)
OpenRetroHQ opened this issue · comments
I have recently found the need for an Asynchronous FIFO in an icestudio project.
I would love to have a robust an re-usable version as an icestudio block featuring:
Inputs
- reset
- read clk
- write clk
- read enable
- write enable
- data_in
Outputs
- data_out
- empty flag
- full flag
Parameters
- depth
- width e.g. 8bit or 16bit
I've included what should be considered as PSEUDO code at best of what i'm thinking.
`
reg [15:0] memory [0:DEPTH-1]; // Define the depth of the memory.
reg [10:0] wr_ptr; // Current write pointer.
reg [10:0] rd_ptr; // Current read pointer.
reg [10:0] next_wr_ptr;
reg [10:0] next_rd_ptr;
reg emptyReg; // Empty flag.
reg fullReg; // Full flag.
reg [15:0] rdataReg; // Outgoing data inetermediate register.
// Write operation
always @(posedge wclk or posedge reset) begin
if (reset) begin
wr_ptr <= 11'b0;
end else if (wr_en && ~full) begin
next_wr_ptr <= (wr_ptr == (DEPTH - 1)) ? 11'b0 : wr_ptr + 1;
end
end
// Read operation
always @(posedge rclk or posedge reset) begin
if (reset) begin
rd_ptr <= 11'b0;
end else if (rd_en && ~empty) begin
next_rd_ptr <= (rd_ptr == (DEPTH - 1)) ? 11'b0 : rd_ptr + 1;
end
end
always @(posedge wclk) begin
emptyReg = (wr_ptr == rd_ptr);
end
always @(posedge rclk) begin
fullReg = (next_wr_ptr == rd_ptr);
end
assign empty = emptyReg;
assign full = fullReg;
always @(posedge rclk) if (rd_en) rdataReg <= memory[rd_ptr];
always @(posedge wclk) if (wr_en) memory[wr_ptr] <= wdata;
assign rdata = rdataReg;
`