.. _module_fifo: Module fifo =========== This document contains technical documentation for the ``fifo`` module. To browse the source code, please 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. .. _fifo.asynchronous_fifo: asynchronous_fifo.vhd --------------------- `View source code on GitHub `__. .. symbolator:: component asynchronous_fifo is generic ( width : positive; depth : positive; almost_full_level : natural range 0 to depth; almost_empty_level : natural range 0 to depth; enable_last : boolean; enable_packet_mode : boolean; enable_drop_packet : boolean; enable_output_register : boolean; ram_type : ram_style_t ); port ( clk_read : in std_ulogic; read_ready : in std_ulogic; read_valid : out std_ulogic; read_data : out std_ulogic_vector; read_last : out std_ulogic; read_level : out natural range 0 to depth; read_almost_empty : out std_ulogic; --# {{}} clk_write : in std_ulogic; write_ready : out std_ulogic; write_valid : in std_ulogic; write_data : in std_ulogic_vector; write_last : in std_ulogic; write_level : out natural range 0 to depth; write_almost_full : out std_ulogic; drop_packet : in std_ulogic ); end component; 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 :ref:`synchronous FIFO `. The implementation is quite optimized with very low resource utilization when extra features are not enabled. .. note:: This entity has a scoped constraint file that must be used. See the ``scoped_constraints`` folder for the file with the same name. This entity also instantiates :ref:`resync.resync_counter` 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. .. _fifo.asynchronous_fifo.resource_utilization: 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. .. list-table:: Resource utilization for **asynchronous_fifo** netlist builds. :header-rows: 1 * - Generics - Total LUTs - FFs - RAMB36 - RAMB18 - Maximum logic level * - use_asynchronous_fifo = True width = 16 depth = 8 enable_output_register = False (Using wrapper fifo_netlist_build_wrapper.vhd) - 35 - 50 - 0 - 0 - 4 * - use_asynchronous_fifo = True width = 32 depth = 1024 enable_output_register = False (Using wrapper fifo_netlist_build_wrapper.vhd) - 44 - 90 - 1 - 0 - 6 * - use_asynchronous_fifo = True width = 32 depth = 1025 enable_output_register = True (Using wrapper fifo_netlist_build_wrapper.vhd) - 45 - 91 - 1 - 0 - 6 * - width = 32 depth = 1024 almost_full_level = 800 - 68 - 112 - 1 - 0 - 6 * - width = 32 depth = 1024 almost_full_level = 800 enable_last = True - 68 - 112 - 1 - 0 - 6 * - width = 32 depth = 1024 almost_full_level = 800 enable_last = True enable_packet_mode = True - 60 - 123 - 1 - 0 - 6 * - width = 32 depth = 1025 almost_full_level = 800 enable_last = True enable_packet_mode = True enable_output_register = True - 76 - 135 - 1 - 0 - 8 * - 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 - 1 - 0 - 6 .. _fifo.fifo: fifo.vhd -------- `View source code on GitHub `__. .. symbolator:: component fifo is generic ( width : positive; depth : positive; almost_full_level : natural range 0 to depth; almost_empty_level : natural range 0 to depth; enable_last : boolean; enable_packet_mode : boolean; enable_drop_packet : boolean; enable_peek_mode : boolean; enable_output_register : boolean; ram_type : ram_style_t ); port ( clk : in std_ulogic; --# {{}} level : out natural range 0 to depth; --# {{}} read_ready : in std_ulogic; read_valid : out std_ulogic; read_data : out std_ulogic_vector; read_last : out std_ulogic; read_peek_mode : in std_ulogic; almost_empty : out std_ulogic; --# {{}} write_ready : out std_ulogic; write_valid : in std_ulogic; write_data : in std_ulogic_vector; write_last : in std_ulogic; almost_full : out std_ulogic; drop_packet : in std_ulogic ); end component; 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 to ``true``, the ``write_last`` signal will be concatenated with ``write_data`` and stored in RAM, and then passed on to ``read_last``. Without this, ``read_last`` will have an undefined value and ``write_last`` will not be used. * FIFO packet mode is enabled by setting the generic ``enable_packet_mode`` to ``true``. When this mode is enabled, ``read_valid`` will not be asserted until the whole "packet" has been written to FIFO, as indicated by ``write_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 to ``true``, the ``drop_packet`` port can be used to drop the current packet, i.e. all words written since the last ``write_valid and write_last`` happened. The port can be asserted at any time, regardless of e.g. ``write_ready`` or ``write_valid``. * Additionally there is a "peek read" mode available that is enabled by setting the ``enable_peek_mode`` generic to ``true``. It makes it possible to read a packet multiple times. If the ``read_peek_mode`` signal is asserted when ``read_ready`` is asserted, the current packet will not be popped from the FIFO, but can instead be read again. Once the readout encounters ``read_last``, the readout will return again to the first word of the packet. Note that the ``read_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 after ``read_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 :ref:`tsfpga:netlist_build` 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. .. _fifo.fifo.resource_utilization: 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. .. list-table:: Resource utilization for **fifo** netlist builds. :header-rows: 1 * - 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.fifo_wrapper: fifo_wrapper.vhd ---------------- `View source code on GitHub `__. .. symbolator:: component fifo_wrapper is generic ( use_asynchronous_fifo : boolean; width : positive; depth : natural; almost_full_level : natural range 0 to depth; almost_empty_level : natural range 0 to depth; enable_last : boolean; enable_packet_mode : boolean; enable_drop_packet : boolean; enable_peek_mode : boolean; enable_output_register : boolean; ram_type : ram_style_t ); port ( clk : in std_ulogic; clk_read : in std_ulogic; clk_write : in std_ulogic; --# {{}} read_ready : in std_ulogic; read_valid : out std_ulogic; read_data : out std_ulogic_vector; read_last : out std_ulogic; read_peek_mode : in std_ulogic; read_level : out natural range 0 to depth; almost_empty : out std_ulogic; --# {{}} write_ready : out std_ulogic; write_valid : in std_ulogic; write_data : in std_ulogic_vector; write_last : in std_ulogic; write_level : out natural range 0 to depth; almost_full : out std_ulogic; drop_packet : in std_ulogic ); end component; Wrapper that selects synchronous/asynchronous FIFO or passthrough depending on generic values.