axi4_resize - AXI4 Transaction Resize
=====================================
Overview
--------
The AXI4 resize component provides the capability of resizing AXI4 transactions.
Resizing in this context means to manage a difference in data bus widths between
the master and the slave. For slave widths greater or equal to the master width
the module is transparent. It does not try to widen the transaction width.

┌─────────────┐                            ┌─────────────┐
│             │     ┌────────────────┐     │             │
│ AXI4 Master │     │                │     │ AXI4 Slave  │
│   128 bit   ├────►│  AXI4 Resize   ├────►│   32 bit    │
│    data     │     │ 128 to 32 bits │     │    data     │
│    lane     │◄────┤                │◄────┤    lane     │
│             │     └────────────────┘     │             │
└─────────────┘                            └─────────────┘
Figure: AXI4 resize usage example

Operation
---------
Please refer to the AXI4 protocol standard document from Arm (IHI0022E)
for AXI4 details.
The AXI4 resize component will automatically adjust the AxLEN and AxSIZE
fields for any transaction exceeding the slave's capabilities. The AxSIZE
field will be reduced to the maximum width allowed by the slave,
as configured by the wl_m_data generic. If a resized transaction exceeds
the limit imposed upon AxLEN, then multiple transactions will be created.
Data flow and flags are managed as appropriate by the AXI4 resize component.

Implementation
--------------
Reset
~~~~~
The AXI4 resize component 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
~~~~~~~~~~
AXI4 resize is endianess agnostic. It does not modify the
endianess in any way.

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

wl_s_data
~~~~~~~~~
Input data word length, controls the amount of data bits in the data input.
The generic applies to both read and write channels.

wl_m_data
~~~~~~~~~
Output data word length, controls the amount of data bits in the data output.
The generic applies to both read and write channels.

wl_user
~~~~~~~
Width of the AxUSER fields. In case of the creation of multiple transactions,
the same user data will added to the created transactions. The xUSER fields
are not supported.

wl_id
~~~~~
Width of the different AXI4 id fields.

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

rst
~~~
Active low reset.

s_axi4_*
~~~~~~~~~
Complete AXI4 slave interface with the exception of the WUSER and RUSER signals.
For a complete listing, please refer to the AXI4 standard or the instantiation
example.

m_axi4_*
~~~~~~~~~
Complete AXI4 master interface with the exception of the WUSER and RUSER signals.
For a complete listing, please refer to the AXI4 standard or the instantiation
example.

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 resize component

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

architecture ex of axis_geabox_example is
  constant slave_data_width : natural := 128;
  constant master_data_width : natural := 32;
  constant wl_id : natural := 4;
  constant wl_user : natural := 2;

  -- Slave ports
  signal s_axi4_awvalid : std_logic := '0';
  signal s_axi4_awaddr : std_logic_vector(31 downto 0);
  signal s_axi4_awsize : std_logic_vector(2 downto 0);
  signal s_axi4_awburst : std_logic_vector(1 downto 0);
  signal s_axi4_awlen : std_logic_vector(7 downto 0);
  signal s_axi4_awcache : std_logic_vector(3 downto 0) := (others => '0');
  signal s_axi4_awregion : std_logic_vector(3 downto 0) := (others => '0');
  signal s_axi4_awqos : std_logic_vector(3 downto 0) := (others => '0');
  signal s_axi4_awprot : std_logic_vector(2 downto 0) := (others => '0');
  signal s_axi4_awlock : std_logic_vector(1 downto 0) := (others => '0');
  signal s_axi4_awid : std_logic_vector(wl_id - 1 downto 0) := (others => '0');
  signal s_axi4_awuser : std_logic_vector(wl_user - 1 downto 0) := (others => '0');
  signal s_axi4_awready : std_logic;

  signal s_axi4_wdata : std_logic_vector(slave_data_width - 1 downto 0);
  signal s_axi4_wstrb : std_logic_vector(slave_data_width/8 - 1 downto 0);
  signal s_axi4_wlast : std_logic;
  signal s_axi4_wvalid : std_logic := '0';
  signal s_axi4_wready : std_logic;

  signal s_axi4_bvalid : std_logic;
  signal s_axi4_bresp : std_logic_vector(1 downto 0);
  signal s_axi4_bid : std_logic_vector(wl_id - 1 downto 0);
  signal s_axi4_buser : std_logic_vector(wl_user - 1 downto 0);
  signal s_axi4_bready : std_logic := '0';

  signal s_axi4_arvalid : std_logic := '0';
  signal s_axi4_araddr : std_logic_vector(31 downto 0);
  signal s_axi4_arsize : std_logic_vector(2 downto 0);
  signal s_axi4_arburst : std_logic_vector(1 downto 0);
  signal s_axi4_arlen : std_logic_vector(7 downto 0);
  signal s_axi4_arcache : std_logic_vector(3 downto 0) := (others => '0');
  signal s_axi4_arregion : std_logic_vector(3 downto 0) := (others => '0');
  signal s_axi4_arqos : std_logic_vector(3 downto 0) := (others => '0');
  signal s_axi4_arprot : std_logic_vector(2 downto 0) := (others => '0');
  signal s_axi4_arlock : std_logic_vector(1 downto 0) := (others => '0');
  signal s_axi4_arid : std_logic_vector(wl_id - 1 downto 0) := (others => '0');
  signal s_axi4_aruser : std_logic_vector(wl_user - 1 downto 0) := (others => '0');
  signal s_axi4_arready : std_logic;

  signal s_axi4_rdata : std_logic_vector(slave_data_width - 1 downto 0);
  signal s_axi4_rresp : std_logic_vector(1 downto 0);
  signal s_axi4_rid : std_logic_vector(wl_id - 1 downto 0);
  signal s_axi4_rlast : std_logic;
  signal s_axi4_rvalid : std_logic;
  signal s_axi4_rready : std_logic := '0';

  -- Master ports
  signal m_axi4_awvalid : std_logic;
  signal m_axi4_awaddr : std_logic_vector(31 downto 0);
  signal m_axi4_awsize : std_logic_vector(2 downto 0);
  signal m_axi4_awburst : std_logic_vector(1 downto 0);
  signal m_axi4_awlen : std_logic_vector(7 downto 0);
  signal m_axi4_awcache : std_logic_vector(3 downto 0);
  signal m_axi4_awregion : std_logic_vector(3 downto 0);
  signal m_axi4_awqos : std_logic_vector(3 downto 0);
  signal m_axi4_awprot : std_logic_vector(2 downto 0);
  signal m_axi4_awlock : std_logic_vector(1 downto 0);
  signal m_axi4_awid : std_logic_vector(wl_id - 1 downto 0);
  signal m_axi4_awuser : std_logic_vector(wl_user - 1 downto 0);
  signal m_axi4_awready : std_logic := '0';

  signal m_axi4_wdata : std_logic_vector(master_data_width - 1 downto 0);
  signal m_axi4_wstrb : std_logic_vector(master_data_width/8 - 1 downto 0);
  signal m_axi4_wlast : std_logic;
  signal m_axi4_wvalid : std_logic;
  signal m_axi4_wready : std_logic := '0';

  signal m_axi4_bvalid : std_logic := '0';
  signal m_axi4_bresp : std_logic_vector(1 downto 0) := (others => '0');
  signal m_axi4_bid : std_logic_vector(wl_id - 1 downto 0) := (others => '0');
  signal m_axi4_buser : std_logic_vector(wl_user - 1 downto 0) := (others => '0');
  signal m_axi4_bready : std_logic;

  signal m_axi4_arvalid : std_logic;
  signal m_axi4_araddr : std_logic_vector(31 downto 0);
  signal m_axi4_arsize : std_logic_vector(2 downto 0);
  signal m_axi4_arburst : std_logic_vector(1 downto 0);
  signal m_axi4_arlen : std_logic_vector(7 downto 0);
  signal m_axi4_arcache : std_logic_vector(3 downto 0);
  signal m_axi4_arregion : std_logic_vector(3 downto 0);
  signal m_axi4_arqos : std_logic_vector(3 downto 0);
  signal m_axi4_arprot : std_logic_vector(2 downto 0);
  signal m_axi4_arlock : std_logic_vector(1 downto 0);
  signal m_axi4_arid : std_logic_vector(wl_id - 1 downto 0);
  signal m_axi4_aruser : std_logic_vector(wl_user - 1 downto 0);
  signal m_axi4_arready : std_logic;

  signal m_axi4_rdata : std_logic_vector(master_data_width - 1 downto 0);
  signal m_axi4_rresp : std_logic_vector(1 downto 0);
  signal m_axi4_rid : std_logic_vector(wl_id - 1 downto 0);
  signal m_axi4_rlast : std_logic;
  signal m_axi4_rvalid : std_logic := '0';
  signal m_axi4_rready : std_logic;
begin
  -- Rest of the design goes here.

  axi4_resize_i : axi4_resize
    generic map (
      wl_s_data => slave_data_width,
      wl_m_data => master_data_width,
      wl_id => wl_id,
      wl_user => wl_user
    )
    port map (
      clk   => clk,
      rst   => rstn,
      -- Slave ports
      s_axi4_awvalid => s_axi4_awvalid,
      s_axi4_awaddr => s_axi4_awaddr,
      s_axi4_awsize => s_axi4_awsize,
      s_axi4_awburst => s_axi4_awburst,
      s_axi4_awlen => s_axi4_awlen,
      s_axi4_awcache => s_axi4_awcache,
      s_axi4_awregion => s_axi4_awregion,
      s_axi4_awqos => s_axi4_awqos,
      s_axi4_awprot => s_axi4_awprot,
      s_axi4_awlock => s_axi4_awlock,
      s_axi4_awid => s_axi4_awid,
      s_axi4_awuser => s_axi4_awuser,
      s_axi4_awready => s_axi4_awready,

      s_axi4_wdata => s_axi4_wdata,
      s_axi4_wstrb => s_axi4_wstrb,
      s_axi4_wlast => s_axi4_wlast,
      s_axi4_wvalid => s_axi4_wvalid,
      s_axi4_wready => s_axi4_wready,

      s_axi4_bvalid => s_axi4_bvalid,
      s_axi4_bresp => s_axi4_bresp,
      s_axi4_bid => s_axi4_bid,
      s_axi4_buser => s_axi4_buser,
      s_axi4_bready => s_axi4_bready,

      s_axi4_arvalid => s_axi4_arvalid,
      s_axi4_araddr => s_axi4_araddr,
      s_axi4_arsize => s_axi4_arsize,
      s_axi4_arburst => s_axi4_arburst,
      s_axi4_arlen => s_axi4_arlen,
      s_axi4_arcache => s_axi4_arcache,
      s_axi4_arregion => s_axi4_arregion,
      s_axi4_arqos => s_axi4_arqos,
      s_axi4_arprot => s_axi4_arprot,
      s_axi4_arlock => s_axi4_arlock,
      s_axi4_arid => s_axi4_arid,
      s_axi4_aruser => s_axi4_aruser,
      s_axi4_arready => s_axi4_arready,

      s_axi4_rdata => s_axi4_rdata,
      s_axi4_rresp => s_axi4_rresp,
      s_axi4_rid => s_axi4_rid,
      s_axi4_rlast => s_axi4_rlast,
      s_axi4_rvalid => s_axi4_rvalid,
      s_axi4_rready => s_axi4_rready,

      -- Master ports
      m_axi4_awvalid => m_axi4_awvalid,
      m_axi4_awaddr => m_axi4_awaddr,
      m_axi4_awsize => m_axi4_awsize,
      m_axi4_awburst => m_axi4_awburst,
      m_axi4_awlen => m_axi4_awlen,
      m_axi4_awcache => m_axi4_awcache,
      m_axi4_awregion => m_axi4_awregion,
      m_axi4_awqos => m_axi4_awqos,
      m_axi4_awprot => m_axi4_awprot,
      m_axi4_awlock => m_axi4_awlock,
      m_axi4_awid => m_axi4_awid,
      m_axi4_awuser => m_axi4_awuser,
      m_axi4_awready => m_axi4_awready,

      m_axi4_wdata => m_axi4_wdata,
      m_axi4_wstrb => m_axi4_wstrb,
      m_axi4_wlast => m_axi4_wlast,
      m_axi4_wvalid => m_axi4_wvalid,
      m_axi4_wready => m_axi4_wready,

      m_axi4_bvalid => m_axi4_bvalid,
      m_axi4_bresp => m_axi4_bresp,
      m_axi4_bid => m_axi4_bid,
      m_axi4_buser => m_axi4_buser,
      m_axi4_bready => m_axi4_bready,

      m_axi4_arvalid => m_axi4_arvalid,
      m_axi4_araddr => m_axi4_araddr,
      m_axi4_arsize => m_axi4_arsize,
      m_axi4_arburst => m_axi4_arburst,
      m_axi4_arlen => m_axi4_arlen,
      m_axi4_arcache => m_axi4_arcache,
      m_axi4_arregion => m_axi4_arregion,
      m_axi4_arqos => m_axi4_arqos,
      m_axi4_arprot => m_axi4_arprot,
      m_axi4_arlock => m_axi4_arlock,
      m_axi4_arid => m_axi4_arid,
      m_axi4_aruser => m_axi4_aruser,
      m_axi4_arready => m_axi4_arready,

      m_axi4_rdata => m_axi4_rdata,
      m_axi4_rresp => m_axi4_rresp,
      m_axi4_rid => m_axi4_rid,
      m_axi4_rlast => m_axi4_rlast,
      m_axi4_rvalid => m_axi4_rvalid,
      m_axi4_rready => m_axi4_rready
    );

end architecture;


