0% found this document useful (0 votes)
5 views4 pages

FIFO

FIFO (First-In, First-Out) is a queue-based memory buffer that processes data in the order it arrives, making it suitable for buffering and synchronization in digital systems. The document details FIFO depth calculation, control logic for synchronous and asynchronous FIFOs, and their applications in various digital systems. It also includes Verilog code for implementing FIFO structures and pointer synchronization methods to handle different clock domains.

Uploaded by

paritoshsingh383
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views4 pages

FIFO

FIFO (First-In, First-Out) is a queue-based memory buffer that processes data in the order it arrives, making it suitable for buffering and synchronization in digital systems. The document details FIFO depth calculation, control logic for synchronous and asynchronous FIFOs, and their applications in various digital systems. It also includes Verilog code for implementing FIFO structures and pointer synchronization methods to handle different clock domains.

Uploaded by

paritoshsingh383
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 4

FIFO

FIRST IN FIRST OUT

A FIFO (First-In, First-Out) is a queue-based memory buffer where data is written into the queue in the order it arrives and is read
in the same order. The principle follows a first-come, first-served approach, making it ideal for buffering, data transfer, and
synchronization in digital systems.

FIFO Depth Calculation


The depth of a FIFO refers to the number of storage locations available for holding data before the buffer is full. It is
crucial for ensuring proper data flow without overflow or underflow conditions.
The depth (D) of a FIFO can be calculated based on system parameters:
FIFO Depth Calculation
FIFO Depth ≥ (Max Data Rate In - Min Data Rate Out)×Latency+Margin
Where:
 Max_DataRate_In = Maximum input data rate
 Min_DataRate_Out = Minimum output data rate
 Burst_Size = Maximum burst size of incoming data
For single -clock FIFO:
If the FIFO is operating in a single clock domain, the depth is determined by the throughput requirements.

For Asynchronous (Dual-Clock) FIFO


If the FIFO is crossing two clock domains (CDC), the depth is determined by the ratio of input and output clock
frequencies:

Where:
 Fwrite = Write clock frequency
 Fread = Read clock frequency
 Burst Size = Maximum burst of incoming data
 Margin = Safety margin (typically 10-20% of the calculated depth)

There are two types of FIFOs


1. Synchronous FIFO

2. Asynchronous FIFO

www.linkedin.com/in/harshita-harshi-9377891bb
Synchronous FIFO
 Read and write operations occur under the same clock domain.
 Requires control logic for full, empty, and almost full/almost empty status.
FIFO Control Logic:
(a) FIFO Full Condition
A FIFO is full when the write pointer catches up to the read pointer after writing.
Full Condition: (Wptr+1)mod N = Rptr
(b) FIFO Empty Condition
A FIFO is empty when the read pointer reaches the write pointer (i.e., no unread data is available).
Empty Condition: Wptr=Rptr
These flags are used to prevent overflow (writing to a full FIFO) or underflow (reading from an empty FIFO).
module synchronous_fifo Depth of FIFO: The number of slots or rows in FIFO is called the
#(parameter DEPTH=8, DATA_WIDTH=8) depth of the FIFO.
( input clk, rst_n,
Width of FIFO: The number of bits that can be stored in each slot
input w_en, r_en,
or row is called the width of the FIFO.
input [DATA_WIDTH-1:0] data_in,
output reg [DATA_WIDTH-1:0] data_out, Working Principle
output full, empty  Data is written into the FIFO on a same clock edge till FIFO
); full.
reg [$clog2(DEPTH)-1:0] w_ptr, r_ptr;  Data is read from the FIFO on a same clock edge till FIFO
reg [DATA_WIDTH-1:0] fifo[DEPTH]; empty.
// Set Default values on reset.
always@(posedge clk) begin
if(!rst_n) begin
w_ptr <= 0; r_ptr <= 0;
data_out <= 0;
end
end
// To write data to FIFO
always@(posedge clk) begin
if(w_en & !full)begin
fifo[w_ptr] <= data_in;
w_ptr <= w_ptr + 1;
Advantages of Synchronous FIFO
end
:: Simple control logic due to a single clock domain.
end
:: Faster and more power-efficient compared to asynchronous FIFOs.
// To read data from FIFO
:: Easier to implement in hardware (FPGAs, ASICs) using Block(BRAM).
always@(posedge clk) begin
if(r_en & !empty) begin :: Low latency and high-speed data transfer.
data_out <= fifo[r_ptr];
r_ptr <= r_ptr + 1;
end
end
assign full = ((w_ptr+1'b1) == r_ptr); Applications of Synchronous FIFO
assign empty = (w_ptr == r_ptr); 🔹 Data buffering in processors and communication interfaces
endmodule 🔹 Pipeline processing in DSP (Digital Signal Processing)
🔹 Networking devices for buffering
🔹 Audio and video streaming systems
🔹 Memory controllers for temporary data storage

www.linkedin.com/in/harshita-harshi-9377891bb
Asynchronous FIFO
An Asynchronous FIFO is a type of FIFO memory used to transfer data between two different clock domains. It allows smooth data
communication between two circuits that operate on different clock frequencies.
>> Many digital systems have different clock domains for different components.
>> A direct connection between these domains causes metastability issues.
>> Asynchronous FIFOs ensure reliable data transfer between these domains without data loss or corruption.

Pointer Synchronization Using Gray Code


 Directly passing binary pointers between different clock domains causes metastability issues.
 Solution: Convert binary pointers to Gray code before passing them to the other clock domain.
Gray code ensures that only one-bit changes at a time, reducing errors.

VERILOG CODE //FIFO READ POINTER


module rptr_handler #(parameter PTR_WIDTH=3) (
//FIFO full condition
input rclk, rrst_n, r_en,
wfull = (g_wptr_next ==
input [PTR_WIDTH:0] g_wptr_sync,
{~g_rptr_sync[PTR_WIDTH:PTR_WIDTH-1],
output reg [PTR_WIDTH:0] b_rptr, g_rptr,
g_rptr_sync[PTR_WIDTH-2:0]});
//FIFO empty conditionFIFO output reg empty
rempty = (g_wptr_sync == g_rptr_next); ); reg [PTR_WIDTH:0] b_rptr_next;
reg [PTR_WIDTH:0] g_rptr_next;
///FIFO WRITE POINTER HANDLER assign b_rptr_next = b_rptr+(r_en & !empty);
module wptr_handler #(parameter PTR_WIDTH=3) ( assign g_rptr_next = (b_rptr_next >>1)^b_rptr_next;
input wclk, wrst_n, w_en, assign rempty = (g_wptr_sync == g_rptr_next);
input [PTR_WIDTH:0] g_rptr_sync, always@(posedge rclk or negedge rrst_n) begin
output reg [PTR_WIDTH:0] b_wptr, g_wptr, if(!rrst_n) begin
output reg full b_rptr <= 0;
); g_rptr <= 0;
reg [PTR_WIDTH:0] b_wptr_next; end else begin
reg [PTR_WIDTH:0] g_wptr_next; b_rptr <= b_rptr_next;
reg wrap_around; g_rptr <= g_rptr_next;
wire wfull; end
assign b_wptr_next = b_wptr+(w_en & !full); end
assign g_wptr_next = (b_wptr_next >>1)^b_wptr_next; always@(posedge rclk or negedge rrst_n) begin
always@(posedge wclk or negedge wrst_n) begin if(!rrst_n) empty <= 1;
if(!wrst_n) begin else empty <= rempty;
b_wptr <= 0; // set default value end
g_wptr <= 0; end endmodule
else begin
b_wptr <= b_wptr_next; // incr binary write pointer ///FIFO MEMORY
g_wptr <= g_wptr_next; // incr gray write pointer module fifo_mem #(parameter DEPTH=8,
end DATA_WIDTH=8, PTR_WIDTH=3) (
end input wclk, w_en, rclk, r_en,
always@(posedge wclk or negedge wrst_n) begin input [PTR_WIDTH:0] b_wptr, b_rptr,
if(!wrst_n) input [DATA_WIDTH-1:0] data_in,
full <= 0; input full, empty,
else output reg [DATA_WIDTH-1:0] data_out);
full <= wfull; reg [DATA_WIDTH-1:0] fifo[0:DEPTH-1];
end always@(posedge wclk) begin
assign wfull = if(w_en & !full) begin
(g_wptr_next=={~g_rptr_sync[PTR_WIDTH:PTR_WIDTH-1], fifo[b_wptr[PTR_WIDTH-1:0]] <= data_in;
g_rptr_sync[PTR_WIDTH-2:0]}); end end
endmodule assign data_out = fifo[b_rptr[PTR_WIDTH-1:0]];
endmodule
www.linkedin.com/in/harshita-harshi-9377891bb
//TOP MODULE //2 FLIP-FLOP SYNCHRONIZER
module synchronizer #(parameter WIDTH=3) (input
`include "synchronizer.v" clk, rst_n, [WIDTH:0] d_in, output reg [WIDTH:0]
`include "wptr_handler.v" d_out);
reg [WIDTH:0] q1;
`include "rptr_handler.v"
always@(posedge clk) begin
`include "fifo_mem.v"
if(!rst_n) begin
q1 <= 0;
module asynchronous_fifo #(parameter DEPTH=8, DATA_WIDTH=8) (
d_out <= 0;
input wclk, wrst_n, end
input rclk, rrst_n, else begin
input w_en, r_en, q1 <= d_in;
input [DATA_WIDTH-1:0] data_in, d_out <= q1;
output reg [DATA_WIDTH-1:0] data_out, end
output reg full, empty end
); endmodule
parameter PTR_WIDTH = $clog2(DEPTH);
reg [PTR_WIDTH:0] g_wptr_sync, g_rptr_sync;
reg [PTR_WIDTH:0] b_wptr, b_rptr;
Applications of Asynchronous
reg [PTR_WIDTH:0] g_wptr, g_rptr;
wire [PTR_WIDTH-1:0] waddr, raddr;
FIFO
synchronizer #(PTR_WIDTH) sync_wptr (rclk, rrst_n,g_wptr,g_wptr_sync);  Clock Domain Crossing (CDC)
//write pointer to read clock domain  Processor to Peripheral Communication
synchronizer #(PTR_WIDTH) sync_rptr (wclk, wrst_n, g_rptr, g_rptr_sync);  High-speed data Acquisition Systems
//read pointer to write clock domain  Network Routers & Switches (Packet
Buffers)
 Audio & Video Processing Systems
wptr_handler #(PTR_WIDTH) wptr_h(wclk, wrst_n,
 FPGA-Based Designs (Bridging Different
w_en,g_rptr_sync,b_wptr,g_wptr,full);
IP Blocks)
rptr_handler #(PTR_WIDTH) rptr_h(rclk, rrst_n,
 USB & PCIe Communication
r_en,g_wptr_sync,b_rptr,g_rptr,empty);
 Software-Defined Radio (SDR) & Wireless
fifo_mem fifom(wclk, w_en, rclk, r_en,b_wptr, b_rptr, data_in,full,empty,
Communication
data_out);
 Video Frame Buffers in GPUs

endmodule

www.linkedin.com/in/harshita-harshi-9377891bb

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy