Last active
December 6, 2023 07:52
-
-
Save C47D/e299230c65b82a87d7fc83579d78b168 to your computer and use it in GitHub Desktop.
Generic FIFO implemented in verilog.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Generic FIFO. | |
* Author: Carlos Diaz (2017) | |
* | |
* DISCLAIMER (2021): This implementation was done when I had a few days of | |
* experience using verilog, I was at school and not really sure what | |
* I was doing. I choose to make it public in case of me needing it | |
* in the future, but that was not the case, it's been a long time | |
* since I tried to learn any HDL. | |
* | |
* Parameters: | |
* WIDTH: Width of the data on the FIFO, default to 4. | |
* DEPTH: Depth of the FIFO, default to 4. | |
* | |
* Input signals: | |
* data_in: Data input, width controlled with WIDTH parameter. | |
* clk: Clock input. | |
* write: Enable writing into the FIFO. | |
* read: Enable reading from the FIFO. | |
* | |
* Output signals: | |
* data_out: Data output, witdh controlled with WIDTH parameter. | |
* fifo_full: 1bit signal, indicate when the FIFO is full. | |
* fifo_empty: 1bit signal, indicate when the FIFO is empty. | |
* fifo_not_empty: 1bit signal, indicate when the FIFO is not empty. | |
* fifo_not_full: 1bit signal, indicate when the FIFO is not full. | |
* | |
**/ | |
`timescale 1ns / 1ps | |
`default_nettype none | |
module fifo #( | |
parameter WIDTH = 4, | |
parameter DEPTH = 4 | |
)( | |
input [WIDTH-1:0] data_in, | |
input wire clk, | |
input wire write, | |
input wire read, | |
output reg [WIDTH-1:0] data_out, | |
output wire fifo_full, | |
output wire fifo_empty, | |
output wire fifo_not_empty, | |
output wire fifo_not_full | |
); | |
// memory will contain the FIFO data. | |
reg [WIDTH-1:0] memory [0:DEPTH-1]; | |
// $clog2(DEPTH+1)-2 to count from 0 to DEPTH | |
reg [$clog2(DEPTH)-1:0] write_ptr; | |
reg [$clog2(DEPTH)-1:0] read_ptr; | |
// Initialization | |
initial begin | |
// Init both write_cnt and read_cnt to 0 | |
write_ptr = 0; | |
read_ptr = 0; | |
// Display error if WIDTH is 0 or less. | |
if ( WIDTH <= 0 ) begin | |
$error("%m ** Illegal condition **, you used %d WIDTH", WIDTH); | |
end | |
// Display error if DEPTH is 0 or less. | |
if ( DEPTH <= 0) begin | |
$error("%m ** Illegal condition **, you used %d DEPTH", DEPTH); | |
end | |
end // end initial | |
assign fifo_empty = ( write_ptr == read_ptr ) ? 1'b1 : 1'b0; | |
assign fifo_full = ( write_ptr == (DEPTH-1) ) ? 1'b1 : 1'b0; | |
assign fifo_not_empty = ~fifo_empty; | |
assign fifo_not_full = ~fifo_full; | |
always @ (posedge clk) begin | |
if ( write ) begin | |
memory[write_ptr] <= data_in; | |
end | |
if ( read ) begin | |
data_out <= memory[read_ptr]; | |
end | |
end | |
always @ ( posedge clk ) begin | |
if ( write ) begin | |
write_ptr <= write_ptr + 1; | |
end | |
if ( read && fifo_not_empty ) begin | |
read_ptr <= read_ptr + 1; | |
end | |
end | |
endmodule |
lenniea
commented
Sep 29, 2021
via email
I can send you my (modified) code if you would like...
…-Lennie
On Tue, Sep 28, 2021 at 5:45 PM Carlos Diaz ***@***.***> wrote:
***@***.**** commented on this gist.
------------------------------
Hi @lennia <https://github.com/lennia> and @futurelink
<https://github.com/futurelink>,
Thanks for letting me know about this mistakes and improvement
opportunities, this chunk of verilog was one of my first attempts, as you
already noticed. I will try to fix it, not sure about how to fix the
write_ptr and read_ptr and fifo_full tho.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<https://gist.github.com/e299230c65b82a87d7fc83579d78b168#gistcomment-3908504>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAPCMHI2AVZTXWVZKPEO2C3UEJOTBANCNFSM4WLCDXRQ>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
That or posting it here should be good, so everyone can see it.
Here is the file.
…On Tue, Sep 28, 2021 at 7:56 PM Carlos Diaz ***@***.***> wrote:
***@***.**** commented on this gist.
------------------------------
That or posting it here should be good, so everyone can see it.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<https://gist.github.com/e299230c65b82a87d7fc83579d78b168#gistcomment-3908802>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAPCMHLO3HZC5L2PVNHPXJTUEJ54JANCNFSM4WLCDXRQ>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
Carlos, apparently this FIFO is the most googlable FIFO on the internet. Thank you for sharing and maintenance! :)
It's nice to know it's been useful for others, but I did it at school when I didn't knew much, so it's been good to receive feedback to improve it.
Since this is one of the top google results for verilog fifo I'll post my hdl.
module RXFIFO #(
parameter PACKET_WIDTH = 248,
parameter FIFO_DEPTH = 256,
parameter PTR_MSB = 8,
parameter ADDR_MSB = 7
)
(
input zedClk100MHz_i,
input reset_ni,
input read_i,
input write_i,
input [PACKET_WIDTH-1:0] packet_i,
output logic [PACKET_WIDTH-1:0] packet_o,
output logic fifoFull_o,
output logic fifoEmpty_o
);
logic [PACKET_WIDTH-1:0] memory [0:FIFO_DEPTH-1];
logic [ PTR_MSB:0] readPtr, writePtr;
wire [ ADDR_MSB:0] writeAddr = writePtr[ADDR_MSB:0];
wire [ ADDR_MSB:0] readAddr = readPtr[ADDR_MSB:0];
always_ff@(posedge zedClk100MHz_i or negedge reset_ni)begin
if(~reset_ni)begin
readPtr <= '0;
writePtr <= '0;
end
else begin
if(write_i && ~fifoFull_o)begin
memory[writeAddr] <= packet_i;
writePtr <= writePtr + 1;
end
if(read_i && ~fifoEmpty_o)begin
packet_o <= memory[readAddr];
readPtr <= readPtr + 1;
end
end
end
assign fifoEmpty_o = (writePtr == readPtr) ? 1'b1: 1'b0;
assign fifoFull_o = ((writePtr[ADDR_MSB:0] == readPtr[ADDR_MSB:0])&(writePtr[PTR_MSB] != readPtr[PTR_MSB])) ? 1'b1 : 1'b0;
endmodule
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment