FIFO Message Buffer (fifo_message)

Performs First In First Out (FIFO) buffering of messages.

A FIFO is a data buffering component that provides a degree of isolation between the input and output ports. By setting the depth to an appropriate size, the input can receive data without concern for back-pressure.

Design

Samples are read from the input port. They will be sent to the output unless the output is applying back-pressure:

  • The component will receive data when supplied by the input port, otherwise it will process any buffered data to the output port.

  • The component will send data on the output port whenever there is no output back-pressure and data is available from the FIFO.

If the FIFO becomes full, either by reaching the maximum number of messages or the maximum words of data_width, back-pressure will be applied to the input port until there has been sufficient output to make room. To avoid back-pressure on the input port, the data depth and message depth should be chosen to cater for the worst case difference in rate between the input and output ports.

In the absence of back-pressure and no backlog in the FIFO, messages will be passed from the input to output with the minimum of delay. It is an implementation detail whether this passes through or by-passes the FIFO store.

The FIFO provides several properties to control and evaluate the effectiveness of the buffer:

  • Current data fill.

  • Current message fill.

  • Empty count.

  • Full data count.

  • Full message count.

As a FIFO full condition will cause back-pressure on the input port, full_data_count and full_message_count will indicate the number of times back-pressure has been applied preventing input data being consumed.

Interface

<?xml version="1.0"?>
<componentspec>
  <property name="data_width" type="uchar" initial="true" writable="false" default="16"
    description="Defines the input and output data width in bits."/>
  <property name="data_depth" type="ulong" initial="true" writable="false" default="16384"
    description="Maximum number of data_width samples the FIFO can hold."/>
  <property name="message_depth" type="ushort" initial="true" writable="false" default="512"
    description="Maximum number of messages the FIFO can hold."/>
  <property name="current_data_fill" type="ulong" writable="false" volatile="true"
    description="Read current number of words held in FIFO."/>
  <property name="current_message_fill" type="ushort" writable="false" volatile="true"
    description="Read current number of messages held in FIFO."/>
  <property name="empty_count" type="ushort" writable="true" volatile="true" default="0"
    description="Number of times buffer was empty, write to reset (to zero)."/>
  <property name="full_data_count" type="ushort" writable="true" volatile="true" default="0"
    description="Number of times data buffer was full, write to reset (to zero)."/>
  <property name="full_message_count" type="ushort" writable="true" volatile="true" default="0"
    description="Number of times message buffer was full, write to reset (to zero)."/>
  <port name="input" producer="false" numberofopcodes="6" defaultbuffersize="16384"/>
  <port name="output" producer="true" numberofopcodes="6" defaultbuffersize="16384"/>
</componentspec>

Opcode Handling

Whilst this component has been written without reference to a specific protocol, it has been assumed it will be used with the timed sample protocols. As such opcode 0 is assumed to be a sample opcode.

All opcodes will be passed to the output in the same order as they arrived, unchanged.

Properties

  • data_width: Defines the input and output data width in bits. Must be a multiple of 8 - i.e. a whole number of bytes.

    • Type: uchar

    • Access:

      • Parameter: False

      • Writable: False

      • Initial: True

      • Volatile: False

    • Default value: 16

  • data_depth: Maximum number of data_width samples the FIFO can hold.

    • Type: ulong

    • Access:

      • Parameter: False

      • Writable: False

      • Initial: True

      • Volatile: False

    • Default value: 16384

  • message_depth: Maximum number of messages the FIFO can hold.

    • Type: ushort

    • Access:

      • Parameter: False

      • Writable: False

      • Initial: True

      • Volatile: False

    • Default value: 512

  • current_data_fill: Read current number of words held in FIFO.

    • Type: ulong

    • Access:

      • Parameter: False

      • Writable: False

      • Initial: False

      • Volatile: True

    • Default value: None

  • current_message_fill: Read current number of messages held in FIFO.

    • Type: ushort

    • Access:

      • Parameter: False

      • Writable: False

      • Initial: False

      • Volatile: True

    • Default value: None

  • empty_count: Number of times buffer was empty, write to reset (to zero).

    • Type: ushort

    • Access:

      • Parameter: False

      • Writable: True

      • Initial: False

      • Volatile: True

    • Default value: 0

  • full_data_count: Number of times data buffer was full, write to reset (to zero).

    • Type: ushort

    • Access:

      • Parameter: False

      • Writable: True

      • Initial: False

      • Volatile: True

    • Default value: 0

  • full_message_count: Number of times message buffer was full, write to reset (to zero).

    • Type: ushort

    • Access:

      • Parameter: False

      • Writable: True

      • Initial: False

      • Volatile: True

    • Default value: 0

Ports

Inputs:

  • input: Primary input samples port.

    • Protocol: None

    • Optional: False

Outputs:

  • output: Primary output samples port.

    • Protocol: None

    • Optional: False

Implementations

Example Application

<?xml version="1.0"?>
<application done="file_write">
  <instance component="ocpi.core.file_read" connect="fifo_message">
    <property name="filename" value="input.bin"/>
  </instance>
  <instance component="ocpi.comp.sdr.interface.fifo_message" connect="file_write">
    <property name="data_width" value="16"/>
    <property name="data_depth" value="16384"/>
    <property name="message_depth" value="16384"/>
    <property name="empty_count" value="0"/>
    <property name="fifo_message.hdl.store_all_controls" value="false"/>
  </instance>
  <instance component="ocpi.core.file_write">
    <property name="filename" value="output.bin"/>
  </instance>
</application>

Dependencies

The dependencies to other elements in OpenCPI are:

There are also dependencies on:

  • HDL specific dependencies:

    • ieee.std_logic_1164

    • ieee.numeric_std

    • ieee.math_real

  • RCC specific dependencies:

    • <utility>

    • <queue>

Limitations

Limitations of fifo_message are:

  • The HDL worker is limited to a data_depth of \((2^{31})-1\) although the device resources are liable to limit this further.

  • Only data_width sizes of 8, 16, 32, and 64 are supported.

  • The component only protects the input port from back-pressure if the data and message depths are sufficiently sized to accommodate the worst-case rate difference between input and output.

  • The data_depth must be large enough to accept a maximum size input message.

Testing

Tested platforms: None

Component testing not completed.