.. _module_ring_buffer: Module ring_buffer ================== This document contains technical documentation for the ``ring_buffer`` module. To browse the source code, visit the `repository on GitHub `__. .. _ring_buffer.ring_buffer_write_simple: ring_buffer_write_simple.vhd ---------------------------- `View source code on GitHub `__. .. symbolator:: component ring_buffer_write_simple is generic ( address_width : positive; segment_length_bytes : positive; segments_per_packet : positive ); port ( clk : in std_ulogic; --# {{}} enable : in std_ulogic; --# {{}} buffer_start_address : in u_unsigned; buffer_end_address : in u_unsigned; buffer_written_address : out u_unsigned; buffer_read_address : in u_unsigned; --# {{}} segment_ready : in std_ulogic; segment_valid : out std_ulogic; segment_address : out u_unsigned; --# {{}} write_done : in std_ulogic; --# {{}} status : out ring_buffer_write_simple_status_t ); end component; Simple implementation of the logic for a ring buffer or circular buffer. It is simple in the sense that address segments are always of the same length, which is defined at compile-time. The entity is designed to be used with applications where the FPGA writes data to a memory buffer and a CPU progressively reads/consumes it. Even though the entity might have other use cases, the terminology and naming of things is based on this presumed use case. Operation _________ The ``buffer_start_address``, ``buffer_end_address`` and ``buffer_read_address`` must be set by the user before enabling the entity with the ``enable`` signal. Initially, the ``buffer_read_address`` should be set to the ``buffer_start_address``. All these addresses need to be byte-aligned with the segment length, i.e. they must be integer multiples of ``segment_length_bytes``. .. warning:: Once the entity has been enabled, it does not support disabling, doing so would result in undefined behavior. Once enabled, the entity will start providing segment addresses to the user on the ``segment`` interface. This is an AXI-Stream-like handshaking interface. Once a segment has been written, the ``segment_written`` signal must be pulsed by the user. The entity will then update the ``buffer_written_address`` accordingly. Once the CPU has updated ``buffer_read_address`` accordingly, the address of this segment can once again be provided on the ``segment`` interface. .. note:: In order to distinguish between the full and empty states, this entity will never utilize 100% of the provided buffer space. There will always be one segment that is not used. In other words, there will never be more than ``(buffer_end_address - buffer_start_address) / segment_length_bytes - 1`` segments outstanding. .. warning:: This entity will fail if ``buffer_last_address`` is the very last address in the address space. (e.g. 0xFFFFFFFF). There is no check for this unlikely case. Segment length vs packet length _______________________________ The addresses served on the ``segment`` interface are always incremented by ``segment_length_bytes``. And per default, the ``buffer_written_address`` is also incremented with ``segment_length_bytes`` every time the ``write_done`` signal is asserted. This is the default behavior that is suitable for most applications. There is a use case, however, where ``buffer_written_address`` shall only be updated once a number of segments have been written. The typical use case is an application that writes a packet in multiple split bursts. It will probably pop a ``segment`` for each burst, but it wants to indicate towards the software that the packet is complete only after all bursts have been written. In this case, the ``segments_per_packet`` generic shall be set to a value greater than one, and the ``write_done`` signal asserted only when the last segment of the packet has been written. ``buffer_written_address`` will then increment by ``segments_per_packet * segment_length_bytes``. .. note:: When this feature is enabled, all address provided to the core must be aligned with the **packet length** instead of the segment length. .. _ring_buffer.ring_buffer_write_simple.resource_utilization: Resource utilization ____________________ This entity has `netlist builds `__ set up with `automatic size checkers `__ in `module_ring_buffer.py `__. The following table lists the resource utilization for the entity, depending on generic configuration. .. list-table:: Resource utilization for **ring_buffer_write_simple** netlist builds. :header-rows: 1 * - Generics - Total LUTs - FFs - Maximum logic level * - address_width = 29 segment_length_bytes = 64 - 94 - 52 - 12 .. _ring_buffer.ring_buffer_write_simple_pkg: ring_buffer_write_simple_pkg.vhd -------------------------------- `View source code on GitHub `__. Package with types and constants for :ref:`ring_buffer.ring_buffer_write_simple`.