100% found this document useful (1 vote)
1K views21 pages

Project Report ON: Implementation of Synchronous FIFO

This document provides a report on the implementation of a synchronous FIFO using Verilog. A synchronous FIFO uses the same clock for both read and write operations. It consists of a memory array, write control logic, and read control logic. The write control logic manages the write pointer and flags like full, while the read control logic manages the read pointer and flags like empty. Data is written into the memory array using the write pointer and read out using the read pointer in a first-in, first-out manner synchronized to the clock.

Uploaded by

SANCHIT KULKARNI
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
100% found this document useful (1 vote)
1K views21 pages

Project Report ON: Implementation of Synchronous FIFO

This document provides a report on the implementation of a synchronous FIFO using Verilog. A synchronous FIFO uses the same clock for both read and write operations. It consists of a memory array, write control logic, and read control logic. The write control logic manages the write pointer and flags like full, while the read control logic manages the read pointer and flags like empty. Data is written into the memory array using the write pointer and read out using the read pointer in a first-in, first-out manner synchronized to the clock.

Uploaded by

SANCHIT KULKARNI
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/ 21

PROJECT REPORT

ON

Implementation of synchronous FIFO

Submitted By:

C. Sahithi (2021H1400149H)

Sanchit Kulkarni (2021H1400153H)

Himanshi Sonava (2021H12400062H)

Aradhana (2021H1400151H)
ABSTRACT

A FIFO (First-In-First-Out) is a memory queue, which controls the data flow


between two modules. FIFO has one input (write) port and one output (read)
port. Each port has its own assigned pointers that point to a location in
memory. After a FIFO reset, both the read and write pointers are placed in
the first memory location within the FIFO. Each write operation causes the
write pointer to increment to the next location in memory; similarly, each
read operation causes the read pointer to increment to the next position. FIFO
can be synchronous or asynchronous. The fundamental difference between
them is that the entire operation of the synchronous FIFO is completely
dependent on the clock, while the write operation and the read operation of
the asynchronous FIFO are asynchronous with each other. This project deals
with the design of Synchronous FIFO using Verilog. In Synchronous FIFO,
both read and write operations happen simultaneously using of Dual port
RAM or an array of flip-flops in the design. Here a high-performance,
synthesizable, reconfigurable timing FIFO is introduced to traverse
asynchronous and synchronous timing domains. This FIFO consists of
reconfigurable combining and combining components. The FIFO can be fully
synthesized using standard cell libraries and a standard design flow.

4
1. INTRODUCTION

FIFO is a First-In-First-Out memory queue with control logic that manages the read
and write operations, generates status flags, and provides optional handshake signals
for interfacing with the user logic. It is often used to control the flow of data between
source and destination. FIFO can be classified as synchronous or asynchronous
depending on whether same clock or different (asynchronous) clocks control the
read and write operations. In this project the objective is to design, verify and
synthesize a synchronous FIFO using binary coded read and write pointers to
address the memory array. FIFO full and empty flags are generated and passed on
to source and destination logics, respectively, to pre-empt any overflow or
underflow of data. In this way data integrity between source and destination is
maintained.

In computer programming, FIFO (first-in, first-out) is an approach to handling


program work requests from queues or stacks so that the oldest request is handled
first. In hardware it is either an array of flops or Read/Write memory that store data
given from one clock domain and on request supplies with the same data to other
clock domain following the first in first out logic. The clock domain that supplies
data to FIFO is often referred as WRITE OR INPUT LOGIC and the clock domain
that reads data from the FIFO is often referred as READ OR OUTPUT LOGIC.
FIFOs are used in designs to safely pass multi-bit data words from one clock domain
to another or to control the flow of data between source and destination side sitting
in the same clock domain. If read and write clock domains are governed by same
clock signal the FIFO is said to be SYNCHRONOUS and if read and write clock
domains are governed by different (asynchronous) clock signals FIFO is said to be
ASYNCHRONOUS.
FIFO full and FIFO empty flags are of great concern as no data should be written in
full condition and no data should be read in empty condition, as it can lead to loss
of data or generation of non relevant data. The full and empty conditions of FIFO
are controlled using binary or gray pointers. In this report we deal with binary
pointers only since we are designing SYNCHRONOUS FIFO. The gray pointers are
used for generating full and empty conditions for ASYNCHRONOUS FIFO.

6
Fig.1.

7
2. SYNCHRONOUS FIFO

A synchronous FIFO refers to a FIFO design where data values are written
sequentially into a memory array using a clock signal, and the data values are
sequentially read out from the memory array using the same clock signal.

I. Applications:

· are used to safely pass data between two asynchronous clock domains.
In System-on- Chip designs there are components which often run on different
clocks. So, to pass data from one such component to another we need
ASYNCHRONOUS FIFO.

· Some times even if the Source and Requestor sides are controlled by same
clock signal a FIFO is needed. This is to match the throughputs of the Source and
the Requestor. For example in one case source may be supplying data at rate which
the requestor can not handle or in other case requestor may be placing requests for
data at a rate at which source can not supply. So, to bridge this gap between source
and requestor capacities to supply and consume data a SYNCHRONOUS FIFO is
used which acts as an elastic buffer.
·

Fig.2. Black Box View Of A Synchronous Fifo

8
II. Port List:

NAME I/O DESCRIPTION


clk I Clock input to the FIFO. This is common input to both read
and write sides of FIFO.
reset_n I active-low asynchronous reset input to FIFO read and write
logic
flush I Active-high synchronous flush input to FIFO. A clock-wide
pulse resets the FIFO read and write pointers

Write Side Ports:

NAME I/O DESCRIPTION


write_data I Data input to FIFO
fifo_full O Qualifies the write data. Logic high indicates the data on
write_data bus is valid and need to be sampled at next
rising edge of the clock.
write_ack O Write acknowledgement to source.

Read Side Ports:

NAME I/O DESCRIPTION


read_data O Read data in response to a read request.
fifo_empty O
has no data to serve upon.

9
III. Functional Description :

Fig.3.

The above figure depicts the basic building blocks of a synchronous FIFO which are:
memory array, write control logic and read control logic. The memory array can be
implemented either with array of flip-flops or with a dual-port read/write memory.
Both of these implementations allow simultaneous read and write accesses. This
simultaneous access gives the FIFO its inherent synchronization property. There are
no restrictions regarding timing between accesses of the two ports. This means
simply, that while one port is writing to the memory at one rate, the other port.

10
can be reading at another rate totally independent of one another. The only restriction
placed is that the simultaneous read and write access should not be from/to the same
memory location. The Synchronous FIFO has a single clock port clk for both data-
read and data-write operations. Data presented at the module's data-input port
write_data is written into the next available empty memory location on a rising clock
edge when the write-enable input write_enable is high. The full status output
fifo_full indicates that no more empty locations remain in the module's internal
memory. Data can be read out of the FIFO via the module's data-output port
read_data in the order in which it was written by asserting read-enable signal
read_enable prior to a rising clock edge. The memory-empty status output
fifo_empty indicates that no more data resides in the module's internal memory.
There are almost empty and almost full flags too viz. fifo_aempty and fifo_afull
which can be used to control the read and write speeds of the requestor and the
source.

Write Control Logic :

ernal
memory. It generates binary-coded write pointer which points to the memory
location where the incoming data is to be written. Write pointer is incremented by
one after every successful write operation. Additionally it generates FIFO full and
almost full flags which in turn are used to prevent any data loss. For example if a
write request comes when FIFO is full then Write Control Logic stalls the write into
the memory till the time fifo_full flag gets de-asserted. It intimates the stalling of
write to source by not sending any acknowledgement in response to the write request.

Read Control Logic :

memory. It generates binary-coded read pointer which points to the memory


location from where the data is to be read. Read pointer is incremented by one after
every successful read operation.
Additionally it generates FIFO empty and almost empty flags which in turn are used
to prevent any spurious data read. For example if a read request comes when FIFO
is empty then Read Control Logic stalls the read from the memory till the time
fifo_empty flag gets de-asserted. It intimates the stalling of read to the requestor by
11
not asserting rdata_valid in response to the read request.

IV. Memory Array :

Memory Array is an array of flip-flops which stores data. Number of data words that
the memory array can store is often referred as DEPTH of the FIFO. Length of the
data word is referred as WIDTH of the FIFO. Besides flop-array it comprises read
and write address decoding logic.

The functionality of Memory Array is relatively straight forward as described below:

1. If write_enable signal is high DATA present on write_data is written into the row
pointed by write_addr on the next rising edge of the clock signal clk. Note that
write_enable is asserted only when wdata_valid is high and FIFO is not full to
avoid any data corruption.

2. If read_enable signal is high the DATA present in the row pointed by read_addr
is sent onto the read_data bus on the next rising edge of the clock signal clk. Note
that read_enable is asserted only when read_req is high and FIFO is not empty
to avoid any spurious data being sent to the requestor.

3. It can handle simultaneous read and write enables as long as their addresses do
not match.

12
V. Full And Empty Flag Generation :

FIFO full and almost full flags are generated by Write Control Logic whereas empty
and almost empty flags are generated by Read Control Logic. FIFO almost full and
almost empty flags are generated to intimate the source and the requestor about
impending full or empty conditions. The almost full and almost empty levels are
parameterized.
It is important to note that read and write pointers point to the same memory location
at both full and empty conditions. Therefore, in order to differentiate between the
two one extra bit is added to read and write pointers. For example if a FIFO has
depth of 256 then to span it completely 8- bits will be needed. Therefore with one
extra bit read and write pointers will be of 9-bits. When their lower 8-bits point to
same memory location their MSBs are used to ascertain whether it is a full condition
or empty condition. In empty conditions the MSBs are equal whereas in full
condition MSBs are different.

VI. Overall Sequence Of Operations :

· At reset, both read and write pointers are 0. This is the empty condition of the
FIFO, and fifo_empty is pulled high and fifo_full is low.

· At empty, reads are blocked and only operation possible is write.

· Since fifo_full is low, upon seeing a valid write data Write Control Logic will
ensure the data be written into location 0 of memory array and write_ptr be
incremented to 1. This causes the empty signal to go LOW.

· With fifo_empty pulled down, read operation can now be performed. Upon seeing
read request at this state Read Control Logic will fetch data from location 0 and will
increment read_prt to 1.

13
· In this way read keeps following write until the FIFO gets empty
again.

· If write operations are not matched by read soon FIFO will get full
and any further write will get stalled until fifo_full is pulled down by a
read.
· With the help of FIFO full and empty flags data integrity is
maintained between the source and the requestor.

14
DESIGN OF SYNCHRONOUS FIFO

Code:

`timescale 1ns / 1ps


//////////////////////////////////////////////////////////////////////////////////
// Design Name: Synchronus FIFO
// Module Name: Syn_FIFO
// Project Name: FIFO Design
//////////////////////////////////////////////////////////////////////////////////
`define BUF_WIDTH 3 // BUF_SIZE = 16 -> BUF_WIDTH = 4, no.
of bits to be used in pointer
`define BUF_SIZE ( 1<<`BUF_WIDTH )

module Sync_FIFO( clk, rst, buf_in, buf_out, wr_en, rd_en, buf_empty,


buf_full, fifo_counter );

input rst, clk, wr_en, rd_en;


// reset, system clock, write enable and read enable.
input [7:0] buf_in;
// data input to be pushed to buffer
output[7:0] buf_out;
// port to output the data using pop.
output buf_empty, buf_full;
// buffer empty and full indication
output[`BUF_WIDTH :0] fifo_counter;
// number of data pushed in to buffer

reg[7:0] buf_out;
reg buf_empty, buf_full;
reg[`BUF_WIDTH :0] fifo_counter;
reg[`BUF_WIDTH -1:0] rd_ptr, wr_ptr; // pointer to read and
write addresses
reg[7:0] buf_mem[`BUF_SIZE -1 : 0]; //

always @(fifo_counter)
begin
buf_empty = (fifo_counter==0); // Checking for whether buffer is
empty or not
buf_full = (fifo_counter== `BUF_SIZE); //Checking for whether
15
buffer is full or not

end

//Setting FIFO counter value for different situations of read and write
operations.
always @(posedge clk or posedge rst)
begin
if( rst )
fifo_counter <= 0; // Reset the counter of FIFO

else if( (!buf_full && wr_en) && ( !buf_empty && rd_en ) ) //When
doing read and write operation simultaneously
fifo_counter <= fifo_counter; // At this state,
counter value will remain same.

else if( !buf_full && wr_en ) // When doing only write


operation
fifo_counter <= fifo_counter + 1;

else if( !buf_empty && rd_en ) //When doing only read


operation
fifo_counter <= fifo_counter - 1;

else
fifo_counter <= fifo_counter; // When doing
nothing.
end

always @( posedge clk or posedge rst)


begin
if( rst )
buf_out <= 0; //On reset output of buffer is all 0.
else
begin
if( rd_en && !buf_empty )
buf_out <= buf_mem[rd_ptr]; //Reading the 8 bit data from
buffer location indicated by read pointer

else
buf_out <= buf_out;
16
end
end

always @(posedge clk)


begin
if( wr_en && !buf_full )
buf_mem[ wr_ptr ] <= buf_in; //Writing 8 bit data input to
buffer location indicated by write pointer

else
buf_mem[ wr_ptr ] <= buf_mem[ wr_ptr ];
end

always@(posedge clk or posedge rst)


begin
if( rst )
begin
wr_ptr <= 0; // Initializing write pointer
rd_ptr <= 0; //Initializing read pointer
end
else
begin
if( !buf_full && wr_en )
wr_ptr <= wr_ptr + 1; // On write operation, Write
pointer points to next location
else
wr_ptr <= wr_ptr;

if( !buf_empty && rd_en )


rd_ptr <= rd_ptr + 1; // On read operation, read
pointer points to next location to be read
else
rd_ptr <= rd_ptr;
end

end
endmodule

17
Test Bench:

`define BUF_WIDTH 3

module Test_Sync_FIFO();
reg clk, rst, wr_en, rd_en ;
reg[7:0] buf_in;
reg[7:0] tempdata;
wire [7:0] buf_out;
wire [`BUF_WIDTH :0] fifo_counter;

Sync_FIFO ff( .clk(clk), .rst(rst), .buf_in(buf_in), .buf_out(buf_out),


.wr_en(wr_en), .rd_en(rd_en), .buf_empty(buf_empty),
.buf_full(buf_full), .fifo_counter(fifo_counter) );

initial
begin
clk = 0;
rst = 1;
rd_en = 0;
wr_en = 0;
tempdata = 0;
buf_in = 0;

#15 rst = 0;

push(1);
fork
push(2);
pop(tempdata);
join //push and pop together
push(10);
push(20);
push(30);
push(40);
push(50);
push(60);
push(70);
push(80);
push(90);
push(100);
push(110);
18
push(120);
push(130);

pop(tempdata);
push(tempdata);
pop(tempdata);
pop(tempdata);
pop(tempdata);
pop(tempdata);
push(140);
pop(tempdata);
push(tempdata);//
pop(tempdata);
pop(tempdata);
pop(tempdata);
pop(tempdata);
pop(tempdata);
pop(tempdata);
pop(tempdata);
pop(tempdata);
pop(tempdata);
pop(tempdata);
pop(tempdata);
push(5);
pop(tempdata);
end

always
#5 clk = ~clk;

task push;
input[7:0] data;

if( buf_full )
$display("---Cannot push: Buffer Full---");
else
begin
$display("Pushed ",data );
buf_in = data;
wr_en = 1;
@(posedge clk);
#1 wr_en = 0;
19
end

endtask

task pop;
output [7:0] data;

if( buf_empty )
$display("---Cannot Pop: Buffer Empty---");
else
begin

rd_en = 1;
@(posedge clk);

#1 rd_en = 0;
data = buf_out;
$display("-------------------------------Poped ", data);

end
endtask

endmodule

20
RESULTS

RTL Schematic:

Simulation Results:

21
From the above simulation results, we can see that depending upon the write
enable and read enable the data is written in the buffer and read from the buffer.
When the write enable is high, the data 00, 01, 02, 0a,14,1e, 28, 32, 3e, 46 are
written in the buffer, which is mentioned as temporary data in the above result.
After that when the read enable signal is high, the data are read from the output
of buffer, which is denoted as buff_out here. The FIFO counter shows that
whether the memory buffer is full or not. As in code buffer width is taken as 3bit,
so, max no. of data stored possible in the buffer is 8. That s why as soon as the
FIFO counter becomes 8, the buffer becomes full, denoted as buff_full.

TCL Console output:

In this tcl console, the output is displayed as when the buffer is full and
when the buffer is empty. Initially the data are pushed and popped according
to the user requirement. The moment the buffer becomes full, no more data
can be pushed into the buffer. Similarly, as soon as all the data are read from
the buffer, no more data can be popped from the buffer.

22
Utilization:

Power Consumption:

23
REFERENCES

[1] A
Asynchronous Pulse-

[2
15, pp. 1 8.

[3] A Reconfigurable Synthesizable Synchronization


FIFOs IEEE 29th Annual International Symposium on Field-
Programmable Custom Computing Machines (FCCM), 2021.

[4] -ported Memory


Compiler Utilizing True Dual- .

24

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