Module fifo
This document contains technical documentation for the fifo
module.
To browse the source code, visit the repository on GitHub.
This module contains a very efficient and versatile FIFO implementation in VHDL. Supports both synchronous (one clock) and asynchronous (two clock) operations.
asynchronous_fifo.vhd
Asynchronous (two clocks) First In First Out (FIFO) data buffering stage with AXI-Stream-like
handshaking interface.
Supports last
, packet mode and drop_packet
just like the
synchronous FIFO.
The implementation is quite optimized with very low resource utilization when extra features
are not enabled.
For more CDC solutions, please see Module resync.
Note
This entity has a scoped constraint file asynchronous_fifo.tcl that must be used for proper operation. See here for instructions. This entity also instantiates resync_counter.vhd which has a further constraint file that must be used.
Warning
In case enable_output_register
is set, the implementation does not keep track of
the exact level on the write side. When there is no word in the output register,
e.g when the FIFO is empty, the write_level
reported will be one higher than the
real level.
See the constraint file and this article for information about timing constraints and how this CDC topology is made reliable.
Resource utilization
This entity has netlist builds set up with automatic size checkers in module_fifo.py. The following table lists the resource utilization for the entity, depending on generic configuration.
Generics |
Total LUTs |
FFs |
Maximum logic level |
RAMB36 |
RAMB18 |
---|---|---|---|---|---|
use_asynchronous_fifo = True width = 8 depth = 8 enable_output_register = False (Using wrapper fifo_netlist_build_wrapper.vhd) |
31 |
42 |
4 |
0 |
0 |
use_asynchronous_fifo = True width = 16 depth = 8 enable_output_register = False (Using wrapper fifo_netlist_build_wrapper.vhd) |
35 |
50 |
4 |
0 |
0 |
use_asynchronous_fifo = True width = 24 depth = 8 enable_output_register = False (Using wrapper fifo_netlist_build_wrapper.vhd) |
39 |
58 |
4 |
0 |
0 |
use_asynchronous_fifo = True width = 32 depth = 8 enable_output_register = False (Using wrapper fifo_netlist_build_wrapper.vhd) |
47 |
66 |
4 |
0 |
0 |
use_asynchronous_fifo = True width = 64 depth = 8 enable_output_register = False (Using wrapper fifo_netlist_build_wrapper.vhd) |
67 |
98 |
4 |
0 |
0 |
use_asynchronous_fifo = True width = 32 depth = 1024 enable_output_register = False (Using wrapper fifo_netlist_build_wrapper.vhd) |
44 |
90 |
6 |
1 |
0 |
use_asynchronous_fifo = True width = 32 depth = 1025 enable_output_register = True (Using wrapper fifo_netlist_build_wrapper.vhd) |
45 |
91 |
6 |
1 |
0 |
width = 32 depth = 1024 almost_full_level = 800 |
68 |
112 |
6 |
1 |
0 |
width = 32 depth = 1024 almost_full_level = 800 enable_last = True |
68 |
112 |
6 |
1 |
0 |
width = 32 depth = 1024 almost_full_level = 800 enable_last = True enable_packet_mode = True |
60 |
123 |
6 |
1 |
0 |
width = 32 depth = 1025 almost_full_level = 800 enable_last = True enable_packet_mode = True enable_output_register = True |
76 |
135 |
8 |
1 |
0 |
width = 32 depth = 1024 almost_full_level = 800 enable_last = True enable_packet_mode = True enable_output_register = False enable_drop_packet = True |
66 |
134 |
6 |
1 |
0 |
fifo.vhd
Synchronous (one clock) First In First Out (FIFO) data buffering stage with AXI-Stream-like handshaking interface. This implementation is very versatile in terms of features that can be enabled. Despite this it is very optimized when used in its barebone configuration, and will result in a very small logic footprint.
Features that can be enabled:
If
enable_last
is set totrue
, thewrite_last
signal will be concatenated withwrite_data
and stored in RAM, and then passed on toread_last
. Without this,read_last
will have an undefined value andwrite_last
will not be used.FIFO packet mode is enabled by setting the generic
enable_packet_mode
totrue
. When this mode is enabled,read_valid
will not be asserted until the whole “packet” has been written to FIFO, as indicated bywrite_valid and write_last
.The FIFO supports dropping packets that are in the progress of being written. If the
enable_drop_packet
generic is set totrue
, thedrop_packet
port can be used to drop the current packet, i.e. all words written since the lastwrite_valid and write_last
happened.The port can be asserted at any time, regardless of e.g.
write_ready
orwrite_valid
.Additionally there is a “peek read” mode available that is enabled by setting the
enable_peek_mode
generic totrue
. It makes it possible to read a packet multiple times. If theread_peek_mode
signal is asserted whenread_ready
is asserted, the current packet will not be popped from the FIFO, but can instead be read again. Once the readout encountersread_last
, the readout will return again to the first word of the packet. Note that theread_peek_mode
value may not be changed during the readout of a packet. It must be static for all words in a packet, but may be updated afterread_last
.There is an option to enable an output register using the
enable_output_register
generic. This can be used to improve timing since the routing delay on the data output of a block RAM is usually quite high. Most block RAM primitives have a “hard” output register that can be used. It has been verified (with Netlist builds in CI) that the implementation in this file will map to the hard output register in Xilinx 7-series devices, and hence not consume extra flip-flops.Note
The “peek read” mode can not be used when output register is enabled.
Resource utilization
This entity has netlist builds set up with automatic size checkers in module_fifo.py. The following table lists the resource utilization for the entity, depending on generic configuration.
Generics |
Total LUTs |
FFs |
RAMB36 |
RAMB18 |
Maximum logic level |
---|---|---|---|---|---|
use_asynchronous_fifo = False width = 32 depth = 1024 enable_output_register = False (Using wrapper fifo_netlist_build_wrapper.vhd) |
14 |
24 |
1 |
0 |
6 |
use_asynchronous_fifo = False width = 32 depth = 1025 enable_output_register = True (Using wrapper fifo_netlist_build_wrapper.vhd) |
15 |
25 |
1 |
0 |
6 |
width = 32 depth = 1024 almost_full_level = 800 |
27 |
35 |
1 |
0 |
6 |
width = 32 depth = 1024 almost_full_level = 800 enable_last = True |
27 |
35 |
1 |
0 |
6 |
width = 32 depth = 1024 almost_full_level = 800 enable_last = True enable_packet_mode = True |
40 |
47 |
1 |
0 |
6 |
width = 32 depth = 1025 almost_full_level = 800 enable_last = True enable_packet_mode = True enable_output_register = True |
45 |
50 |
1 |
0 |
9 |
width = 32 depth = 1024 almost_full_level = 800 enable_last = True enable_packet_mode = True enable_output_register = False enable_drop_packet = True |
45 |
58 |
1 |
0 |
6 |
width = 32 depth = 1024 almost_full_level = 800 enable_last = True enable_packet_mode = True enable_output_register = False enable_drop_packet = False enable_peek_mode = True |
58 |
58 |
1 |
0 |
6 |
use_asynchronous_fifo = False width = 8 depth = 32 enable_output_register = False (Using wrapper fifo_netlist_build_wrapper.vhd) |
32 |
22 |
0 |
0 |
3 |
fifo_wrapper.vhd
Wrapper that selects synchronous/asynchronous FIFO or passthrough depending on generic values.