axis_gearbox - AXI4-Stream Gearbox
==================================
Overview
--------
The AXI4-Stream gearbox can convert the data width of the input and output streams.
The gearbox handles any input to output ratios. The tlast input can be asserted to
flush the output at any time. The gearbox operates from the lowest output bits to
the highest. An early flush due to an asserted tlast input might cause stale data
to be present in the higher bits of the output.

 Data & ┌───────────┐ Data & ┌────────┐ Data &
 last   │           │ last   │        │ last
───────►│ Circular  ├───────►│ Buffer ├──────►
 Ready  │  Buffer   │ Ready  │        │ Ready
◄───────┤           │◄───────┤        │◄──────
        └───────────┘        └────────┘
Figure: AXI4-S gearbox architecture

Operation
---------
Please refer the the AXI4-Stream protocol standard document from Arm (IHI0022E)
for AXI4-Stream details.
The gearbox operates from the lowest output bits to the highest. This means
that the lowest input bits will become the first output in cases where the
input is larger than the output. When the output is larger than the input,
the first input will be placed in the lowest bits of the output.
The gearbox offers early flushing of the circular buffer using the tlast input.
An assertion of the tlast input will force the gearbox to output whatever it has
in the circular buffer to the output buffer (given that the output buffer is available).
The output tlast flag will be asserted for the flushed data. When a flush is performed,
the circular buffer is reset and cleared.
When the output is smaller than the input, the tlast flag will be asserted on the last
output word created from the input.

Implementation
--------------
Reset
~~~~~
The AXI4-Stream gearbox resets all its registers using an active low
reset. The registers are either reset synchronously or asynchronously,
depending on the GRLIB grlib_async_reset_enable configuration constant.

Endianness
~~~~~~~~~~
The AXI4-Stream gearbox is endianess agnostic.

Resource Usage
~~~~~~~~~~~~~~
The circular buffer is sized as wl_in + wl_out bits.
The output buffer is sized as wl_out bits. In total the gearbox
consumes wl_in + 2 * wl_out register bits as a part of the data
storage. Further registers are used for write and read pointers,
the number depends on the wl_in to wl_out ratio.

Configuration Options
---------------------
The AXI4-Stream gearbox can be configured at elaboration time using
the generics described in this section.

wl_in
~~~~~
Input data word length, controls the amount of data bits in the data input.

wl_out
~~~~~
Output data word length, controls the amount of data bits in the data output.

Signal Descriptions
-------------------
clk
~~~
AXI clock.

rst
~~~
Active low reset.

s_axis_t*
~~~~~~~~~
AXI4-Stream slave interface.
Includes the following inputs:
* data
* valid
* last
The following output:
* ready

m_axis_t*
~~~~~~~~~
AXI4-Stream master interface.
Includes the following outputs:
* data
* valid
* last
The following input:
* ready

Library Dependencies
--------------------
GRLIB
~~~~~
config: Reset configuration definition.
config_types: Configuration support.

Instantiation
-------------
The following code snippet is intended to show how the core is instantiated.

library ieee;
use ieee.std_logic_1164.all;

library gaisler;
use gaisler.axi.all; -- AXI4-Stream component

entity axis_gearbox_example is
  port (
    clk : in std_logic;
    rstn : in std_logic
  );
end entity;

architecture ex of axis_geabox_example is
  constant indata_width : natural := 32;
  constant outdata_width : natural := 8;

  signal s_axis_tdata : std_logic_vector(indata_width - 1 downto 0);
  signal s_axis_tvalid : std_logic := '0';
  signal s_axis_tlast : std_logic;
  signal s_axis_tready : std_logic;

  signal m_axis_tdata : std_logic_vector(outdata_width - 1 downto 0);
  signal m_axis_tvalid : std_logic;
  signal m_axis_tlast : std_logic;
  signal m_axis_tready : std_logic := '1';
begin
  -- Rest of the design goes here.

  gearbox : axis_gearbox
    generic map (
      wl_in  => indata_width,
      wl_out => outdata_width
    )
    port map (
      clk => clk,
      rst => rstn,

      s_axis_tdata => s_axis_tdata,
      s_axis_tvalid => s_axis_tvalid,
      s_axis_tlast => s_axis_tlast,
      s_axis_tready => s_axis_tready,

      m_axis_tdata => m_axis_tdata,
      m_axis_tvalid => m_axis_tvalid,
      m_axis_tlast => m_axis_tlast,
      m_axis_tready => m_axis_tready
    );
end architecture;

