URL
https://opencores.org/ocsvn/riscv_vhdl/riscv_vhdl/trunk
Subversion Repositories riscv_vhdl
[/] [riscv_vhdl/] [trunk/] [rtl/] [ambalib/] [types_amba4.vhd.bak] - Rev 5
Compare with Previous | Blame | View Log
-----------------------------------------------------------------------------
--! @file
--! @copyright Copyright 2015 GNSS Sensor Ltd. All right reserved.
--! @author Sergey Khabarov - sergeykhbr@gmail.com
--! @brief Declaration and common methods implementation of the types_nasti
--! package.
--! @details This file defines bus interface constants that have to be
--! used by any periphery device implementation in order
--! to provide compatibility in a wide range of possible settings.
--! For better implementation use the AXI4 register bank and
--! implemented tasks from this file.
------------------------------------------------------------------------------
--! Standard library
library ieee;
--! Standard signal types import
use ieee.std_logic_1164.all;
--! Standard numerical types import
use ieee.numeric_std.all;
--! Common constants and data conversion functions library
library commonlib;
--! Import SoC specific types common for all devices
use commonlib.types_common.all;
--! @brief System bus AMBA AXI(NASTI) types definition.
--! @details This package provides general constants, data structures and
--! and functions description that define behaviour of all
--! peripheries devices implementing AXI4 interface.
package types_amba4 is
--! @defgroup scala_cfg_group SCALA generated parameters
--! @ingroup axi4_config_generic_group
--! @details This constant must correspond to Scala defined ones.
--! @{
--! User defined address ID bitwidth (aw_id / ar_id fields).
constant CFG_ROCKET_ID_BITS : integer := 5;
--! Data bus bits width.
constant CFG_NASTI_DATA_BITS : integer := 64;--128;
--! Data bus bytes width
constant CFG_NASTI_DATA_BYTES : integer := CFG_NASTI_DATA_BITS / 8;
--! Address bus bits width.
constant CFG_NASTI_ADDR_BITS : integer := 32;
--! Definition of number of bits in address bus per one data transaction.
constant CFG_NASTI_ADDR_OFFSET : integer := log2(CFG_NASTI_DATA_BYTES);
--! @brief Number of address bits used for device addressing.
--! @details Default is 12 bits = 4 KB of address space minimum per each
--! mapped device.
constant CFG_NASTI_CFG_ADDR_BITS : integer := CFG_NASTI_ADDR_BITS-12;
--! @brief Global alignment is set 32 bits.
constant CFG_ALIGN_BYTES : integer := 4;
--! @brief Number of parallel access to the atomic data.
constant CFG_WORDS_ON_BUS : integer := CFG_NASTI_DATA_BYTES/CFG_ALIGN_BYTES;
--! @}
--! @defgroup slave_id_group AMBA AXI slaves generic IDs.
--! @ingroup axi4_config_generic_group
--! @details Each module in a SoC has to be indexed by unique identificator.
--! In current implementation it is used sequential indexing for it.
--! Indexes are used to specify a device bus item in a vectors.
--! @{
--! @brief Configuration index of the Boot ROM module visible by the firmware.
constant CFG_NASTI_SLAVE_BOOTROM : integer := 0;
--! Configuration index of the Firmware ROM Image module.
constant CFG_NASTI_SLAVE_ROMIMAGE : integer := CFG_NASTI_SLAVE_BOOTROM+1;
--! Configuration index of the SRAM module visible by the firmware.
constant CFG_NASTI_SLAVE_SRAM : integer := CFG_NASTI_SLAVE_ROMIMAGE+1;
--! Configuration index of the UART module.
constant CFG_NASTI_SLAVE_UART1 : integer := CFG_NASTI_SLAVE_SRAM+1;
--! Configuration index of the GPIO (General Purpose In/Out) module.
constant CFG_NASTI_SLAVE_GPIO : integer := CFG_NASTI_SLAVE_UART1+1;
--! Configuration index of the Interrupt Controller module.
constant CFG_NASTI_SLAVE_IRQCTRL : integer := CFG_NASTI_SLAVE_GPIO+1;
--! Configuration index of the Satellite Navigation Engine.
constant CFG_NASTI_SLAVE_ENGINE : integer := CFG_NASTI_SLAVE_IRQCTRL+1;
--! Configuration index of the RF front-end controller.
constant CFG_NASTI_SLAVE_RFCTRL : integer := CFG_NASTI_SLAVE_ENGINE+1;
--! Configuration index of the GPS-CA Fast Search Engine module.
constant CFG_NASTI_SLAVE_FSE_GPS : integer := CFG_NASTI_SLAVE_RFCTRL+1;
--! Configuration index of the Ethernet MAC module.
constant CFG_NASTI_SLAVE_ETHMAC : integer := CFG_NASTI_SLAVE_FSE_GPS+1;
--! Configuration index of the Debug Support Unit module.
constant CFG_NASTI_SLAVE_DSU : integer := CFG_NASTI_SLAVE_ETHMAC+1;
--! Configuration index of the Debug Support Unit module.
constant CFG_NASTI_SLAVE_GPTIMERS : integer := CFG_NASTI_SLAVE_DSU+1;
--! Configuration index of the Plug-n-Play module.
constant CFG_NASTI_SLAVE_PNP : integer := CFG_NASTI_SLAVE_GPTIMERS+1;
--! Total number of the slaves devices.
constant CFG_NASTI_SLAVES_TOTAL : integer := CFG_NASTI_SLAVE_PNP+1;
--! @}
--! @defgroup master_id_group AXI4 masters generic IDs.
--! @ingroup axi4_config_generic_group
--! @details Each master must be assigned to a specific ID that used
--! as an index in the vector array of AXI master bus.
--! @{
--! Cached TileLinkIO bus.
constant CFG_NASTI_MASTER_CACHED : integer := 0;
--! Uncached TileLinkIO bus.
constant CFG_NASTI_MASTER_UNCACHED : integer := CFG_NASTI_MASTER_CACHED+1;
--! Ethernet MAC master interface generic index.
constant CFG_NASTI_MASTER_ETHMAC : integer := CFG_NASTI_MASTER_UNCACHED+1;
--! Tap via UART (debug port) generic index.
constant CFG_NASTI_MASTER_MSTUART : integer := CFG_NASTI_MASTER_ETHMAC+1;
--! Total Number of master devices on system bus.
constant CFG_NASTI_MASTER_TOTAL : integer := CFG_NASTI_MASTER_MSTUART+1;
--! @}
--! @defgroup irq_id_group AXI4 interrupt generic IDs.
--! @ingroup axi4_config_generic_group
--! @details Unique indentificator of the interrupt pin also used
--! as an index in the interrupts bus.
--! @{
--! Zero interrupt index must be unused.
constant CFG_IRQ_UNUSED : integer := 0;
--! UART_A interrupt pin.
constant CFG_IRQ_UART1 : integer := CFG_IRQ_UNUSED + 1;
--! Ethernet MAC interrupt pin.
constant CFG_IRQ_ETHMAC : integer := CFG_IRQ_UART1 + 1;
--! GP Timers interrupt pin
constant CFG_IRQ_GPTIMERS : integer := CFG_IRQ_ETHMAC + 1;
--! Memory miss access.
constant CFG_IRQ_MISS_ACCESS : integer := CFG_IRQ_GPTIMERS + 1;
--! GNSS Engine IRQ pin that generates 1 msec pulses.
constant CFG_IRQ_GNSSENGINE : integer := CFG_IRQ_MISS_ACCESS + 1;
--! Total number of used interrupts in a system
constant CFG_IRQ_TOTAL : integer := CFG_IRQ_GNSSENGINE + 1;
--! @}
--! @name AXI Response values
--! @brief AMBA 4.0 specified response types from a slave device.
--! @{
--! @brief Normal access success.
--! @details Indicates that a normal access has been
--! successful. Can also indicate an exclusive access has failed.
constant NASTI_RESP_OKAY : std_logic_vector(1 downto 0) := "00";
--! @brief Exclusive access okay.
--! @details Indicates that either the read or write
--! portion of an exclusive access has been successful.
constant NASTI_RESP_EXOKAY : std_logic_vector(1 downto 0) := "01";
--! @brief Slave error.
--! @details Used when the access has reached the slave successfully,
--! but the slave wishes to return an error condition to the originating
--! master.
constant NASTI_RESP_SLVERR : std_logic_vector(1 downto 0) := "10";
--! @brief Decode error.
--! @details Generated, typically by an interconnect component,
--! to indicate that there is no slave at the transaction address.
constant NASTI_RESP_DECERR : std_logic_vector(1 downto 0) := "11";
--! @}
--! @name AXI burst request type.
--! @brief AMBA 4.0 specified burst operation request types.
--! @{
--! @brief Fixed address burst operation.
--! @details The address is the same for every transfer in the burst
--! (FIFO type)
constant NASTI_BURST_FIXED : std_logic_vector(1 downto 0) := "00";
--! @brief Burst operation with address increment.
--! @details The address for each transfer in the burst is an increment of
--! the address for the previous transfer. The increment value depends
--! on the size of the transfer.
constant NASTI_BURST_INCR : std_logic_vector(1 downto 0) := "01";
--! @brief Burst operation with address increment and wrapping.
--! @details A wrapping burst is similar to an incrementing burst, except that
--! the address wraps around to a lower address if an upper address
--! limit is reached
constant NASTI_BURST_WRAP : std_logic_vector(1 downto 0) := "10";
--! @}
--! @name Vendor IDs defintion.
--! @{
--! GNSS Sensor Ltd. vendor identificator.
constant VENDOR_GNSSSENSOR : std_logic_vector(15 downto 0) := X"00F1";
--! @}
--! @name Master Device IDs definition:
--! @{
--! Empty master slot device
constant MST_DID_EMPTY : std_logic_vector(15 downto 0) := X"7755";
--! RISC-V "Rocket-chip" core Cached TileLink master device.
constant RISCV_CACHED_TILELINK : std_logic_vector(15 downto 0) := X"0500";
--! RISC-V "Rocket-chip" core Uncached TileLink master device.
constant RISCV_UNCACHED_TILELINK : std_logic_vector(15 downto 0) := X"0501";
--! Ethernet MAC master device.
constant GAISLER_ETH_MAC_MASTER : std_logic_vector(15 downto 0) := X"0502";
--! Ethernet MAC master debug interface (EDCL).
constant GAISLER_ETH_EDCL_MASTER : std_logic_vector(15 downto 0) := X"0503";
--! "River" CPU Device ID.
constant RISCV_RIVER_CPU : std_logic_vector(15 downto 0) := X"0505";
--! UART with DMA: Test Access Point (TAP)
constant GNSSSENSOR_UART_TAP : std_logic_vector(15 downto 0) := X"050A";
--! @}
--! @name Slave Device IDs definition:
--! @{
--! Empty slave slot device
constant SLV_DID_EMPTY : std_logic_vector(15 downto 0) := X"5577";
--! GNSS Engine Stub device
constant GNSSSENSOR_ENGINE_STUB : std_logic_vector(15 downto 0) := X"0068";
--! Fast Search Engines Device ID provided by gnsslib
constant GNSSSENSOR_FSE_V2_GPS : std_logic_vector(15 downto 0) := X"0069";
--! Boot ROM Device ID
constant GNSSSENSOR_BOOTROM : std_logic_vector(15 downto 0) := X"0071";
--! FW ROM image Device ID
constant GNSSSENSOR_FWIMAGE : std_logic_vector(15 downto 0) := X"0072";
--! Internal SRAM block Device ID
constant GNSSSENSOR_SRAM : std_logic_vector(15 downto 0) := X"0073";
--! Configuration Registers Module Device ID provided by gnsslib
constant GNSSSENSOR_PNP : std_logic_vector(15 downto 0) := X"0074";
--! SD-card controller Device ID provided by gnsslib
constant GNSSSENSOR_SPI_FLASH : std_logic_vector(15 downto 0) := X"0075";
--! General purpose IOs Device ID provided by gnsslib
constant GNSSSENSOR_GPIO : std_logic_vector(15 downto 0) := X"0076";
--! RF front-end controller Device ID provided by gnsslib
constant GNSSSENSOR_RF_CONTROL : std_logic_vector(15 downto 0) := X"0077";
--! GNSS Engine Device ID provided by gnsslib
constant GNSSSENSOR_ENGINE : std_logic_vector(15 downto 0) := X"0078";
--! rs-232 UART Device ID
constant GNSSSENSOR_UART : std_logic_vector(15 downto 0) := X"007a";
--! Accelerometer Device ID provided by gnsslib
constant GNSSSENSOR_ACCELEROMETER : std_logic_vector(15 downto 0) := X"007b";
--! Gyroscope Device ID provided by gnsslib
constant GNSSSENSOR_GYROSCOPE : std_logic_vector(15 downto 0) := X"007c";
--! Interrupt controller
constant GNSSSENSOR_IRQCTRL : std_logic_vector(15 downto 0) := X"007d";
--! Ethernet MAC inherited from Gaisler greth module.
constant GNSSSENSOR_ETHMAC : std_logic_vector(15 downto 0) := X"007f";
--! Debug Support Unit device id.
constant GNSSSENSOR_DSU : std_logic_vector(15 downto 0) := X"0080";
--! GP Timers device id.
constant GNSSSENSOR_GPTIMERS : std_logic_vector(15 downto 0) := X"0081";
--! ADC samples recorder
constant GNSSSENSOR_ADC_RECORDER : std_logic_vector(15 downto 0) := X"0082";
--! @}
--! @name Decoder of the transaction size.
--! @{
--! Burst length size decoder
constant XSIZE_TOTAL : integer := 8;
--! Definition of the AXI bytes converter.
type xsize_type is array (0 to XSIZE_TOTAL-1) of integer;
--! Decoder of the transaction bytes from AXI format to Bytes.
constant XSizeToBytes : xsize_type := (
0 => 1,
1 => 2,
2 => 4,
3 => 8,
4 => 16,
5 => 32,
6 => 64,
7 => 128
);
--! @}
--! @name Plug'n'Play descriptor constants.
--! @{
--! Undefined type of the descriptor (empty device).
constant PNP_CFG_TYPE_INVALID : std_logic_vector := "00";
--! AXI slave device standard descriptor.
constant PNP_CFG_TYPE_MASTER : std_logic_vector := "01";
--! AXI master device standard descriptor.
constant PNP_CFG_TYPE_SLAVE : std_logic_vector := "10";
--! @brief Size in bytes of the standard slave descriptor..
--! @details Firmware uses this value instead of sizeof(nasti_slave_config_type).
constant PNP_CFG_SLAVE_DESCR_BYTES : std_logic_vector(7 downto 0) := X"10";
--! @brief Size in bytes of the standard master descriptor.
--! @details Firmware uses this value instead of sizeof(nasti_master_config_type).
constant PNP_CFG_MASTER_DESCR_BYTES : std_logic_vector(7 downto 0) := X"08";
--! @}
--! @brief Plug-n-play descriptor structure for slave device.
--! @details Each slave device must generates this datatype output that
--! is connected directly to the 'pnp' slave module on system bus.
type nasti_slave_config_type is record
--! Descriptor size in bytes.
descrsize : std_logic_vector(7 downto 0);
--! Descriptor type.
descrtype : std_logic_vector(1 downto 0);
--! Descriptor size in bytes.
irq_idx : integer;
--! Base address value.
xaddr : std_logic_vector(CFG_NASTI_CFG_ADDR_BITS-1 downto 0);
--! Maskable bits of the base address.
xmask : std_logic_vector(CFG_NASTI_CFG_ADDR_BITS-1 downto 0);
--! Vendor ID.
vid : std_logic_vector(15 downto 0);
--! Device ID.
did : std_logic_vector(15 downto 0);
end record;
--! @brief Arrays of the plug-n-play descriptors.
--! @details Configuration bus vector from all slaves to plug'n'play
--! NASTI device (pnp).
type nasti_slave_cfg_vector is array (0 to CFG_NASTI_SLAVES_TOTAL-1)
of nasti_slave_config_type;
--! @brief Default slave config value.
--! @default This value corresponds to an empty device and often used
--! as assignment of outputs for the disabled device.
constant nasti_slave_config_none : nasti_slave_config_type := (
PNP_CFG_SLAVE_DESCR_BYTES, PNP_CFG_TYPE_SLAVE, 0,
(others => '0'), (others => '0'), VENDOR_GNSSSENSOR, SLV_DID_EMPTY);
--! @brief Plug-n-play descriptor structure for master device.
--! @details Each master device must generates this datatype output that
--! is connected directly to the 'pnp' slave module on system bus.
type nasti_master_config_type is record
--! Descriptor size in bytes.
descrsize : std_logic_vector(7 downto 0);
--! Descriptor type.
descrtype : std_logic_vector(1 downto 0);
--! Vendor ID.
vid : std_logic_vector(15 downto 0);
--! Device ID.
did : std_logic_vector(15 downto 0);
end record;
--! @brief Arrays of the plug-n-play descriptors.
--! @details Configuration bus vector from all slaves to plug'n'play
--! NASTI device (pnp).
type nasti_master_cfg_vector is array (0 to CFG_NASTI_MASTER_TOTAL-1)
of nasti_master_config_type;
--! @brief Default master config value.
constant nasti_master_config_none : nasti_master_config_type := (
PNP_CFG_MASTER_DESCR_BYTES, PNP_CFG_TYPE_MASTER,
VENDOR_GNSSSENSOR, MST_DID_EMPTY);
--! @brief AMBA AXI4 compliant data structure.
type nasti_metadata_type is record
--! @brief Read address.
--! @details The read address gives the address of the first transfer
--! in a read burst transaction.
addr : std_logic_vector(CFG_NASTI_ADDR_BITS-1 downto 0);
--! @brief Burst length.
--! @details This signal indicates the exact number of transfers in
--! a burst. This changes between AXI3 and AXI4. nastiXLenBits=8 so
--! this is an AXI4 implementation.
--! Burst_Length = len[7:0] + 1
len : std_logic_vector(7 downto 0);
--! @brief Burst size.
--! @details This signal indicates the size of each transfer
--! in the burst: 0=1 byte; ..., 6=64 bytes; 7=128 bytes;
size : std_logic_vector(2 downto 0);
--! @brief Read response.
--! @details This signal indicates the status of the read transfer.
--! The responses are:
--! 0b00 FIXED - In a fixed burst, the address is the same for every transfer
--! in the burst. Typically is used for FIFO.
--! 0b01 INCR - Incrementing. In an incrementing burst, the address for each
--! transfer in the burst is an increment of the address for the
--! previous transfer. The increment value depends on the size of
--! the transfer.
--! 0b10 WRAP - A wrapping burst is similar to an incrementing burst, except
--! that the address wraps around to a lower address if an upper address
--! limit is reached.
--! 0b11 resrved.
burst : std_logic_vector(1 downto 0);
--! @brief Lock type.
--! @details Not supported in AXI4.
lock : std_logic;
--! @brief Memory type.
--! @details See table for write and read transactions.
cache : std_logic_vector(3 downto 0);
--! @brief Protection type.
--! @details This signal indicates the privilege and security level
--! of the transaction, and whether the transaction is a data access
--! or an instruction access:
--! [0] : 0 = Unpriviledge access
--! 1 = Priviledge access
--! [1] : 0 = Secure access
--! 1 = Non-secure access
--! [2] : 0 = Data access
--! 1 = Instruction access
prot : std_logic_vector(2 downto 0);
--! @brief Quality of Service, QoS.
--! @details QoS identifier sent for each read transaction.
--! Implemented only in AXI4:
--! 0b0000 - default value. Indicates that the interface is
--! not participating in any QoS scheme.
qos : std_logic_vector(3 downto 0);
--! @brief Region identifier.
--! @details Permits a single physical interface on a slave to be used for
--! multiple logical interfaces. Implemented only in AXI4. This is
--! similar to the banks implementation in Leon3 without address
--! decoding.
region : std_logic_vector(3 downto 0);
end record;
--! @brief Empty metadata value.
constant META_NONE : nasti_metadata_type := (
(others =>'0'), X"00", "000", NASTI_BURST_INCR, '0', X"0", "000", "0000", "0000"
);
--! @brief Master device output signals
type nasti_master_out_type is record
--! Write Address channel:
aw_valid : std_logic;
--! metadata of the read channel.
aw_bits : nasti_metadata_type;
--! Write address ID. Identification tag used for a trasaction ordering.
aw_id : std_logic_vector(CFG_ROCKET_ID_BITS-1 downto 0);
--! Optional user defined signal in a write address channel.
aw_user : std_logic;
--! Write Data channel valid flag
w_valid : std_logic;
--! Write channel data value
w_data : std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0);
--! Write Data channel last address in a burst marker.
w_last : std_logic;
--! Write Data channel strob signals selecting certain bytes.
w_strb : std_logic_vector(CFG_NASTI_DATA_BYTES-1 downto 0);
--! Optional user defined signal in write channel.
w_user : std_logic;
--! Write Response channel accepted by master.
b_ready : std_logic;
--! Read Address Channel data valid.
ar_valid : std_logic;
--! Read Address channel metadata.
ar_bits : nasti_metadata_type;
--! Read address ID. Identification tag used for a trasaction ordering.
ar_id : std_logic_vector(CFG_ROCKET_ID_BITS-1 downto 0);
--! Optional user defined signal in read address channel.
ar_user : std_logic;
--! Read Data channel:
r_ready : std_logic;
end record;
--! @brief Master device empty value.
--! @warning If the master is not connected to the vector then vector value
--! MUST BE initialized by this value.
constant nasti_master_out_none : nasti_master_out_type := (
'0', META_NONE, (others=>'0'), '0',
'0', (others=>'0'), '0', (others=>'0'), '0',
'0', '0', META_NONE, (others=>'0'), '0', '0');
--! @brief Array of all masters outputs.
type nasti_master_out_vector is array (0 to CFG_NASTI_MASTER_TOTAL-1)
of nasti_master_out_type;
--! @brief Master device input signals.
type nasti_master_in_type is record
--! Write Address channel.
aw_ready : std_logic;
--! Write Data channel.
w_ready : std_logic;
--! Write Response channel:
b_valid : std_logic;
b_resp : std_logic_vector(1 downto 0);
b_id : std_logic_vector(CFG_ROCKET_ID_BITS-1 downto 0);
b_user : std_logic;
--! Read Address Channel
ar_ready : std_logic;
--! Read valid.
r_valid : std_logic;
--! @brief Read response.
--! @details This signal indicates the status of the read transfer.
--! The responses are:
--! 0b00 OKAY - Normal access success. Indicates that a normal access has
--! been successful. Can also indicate an exclusive access
--! has failed.
--! 0b01 EXOKAY - Exclusive access okay. Indicates that either the read or
--! write portion of an exclusive access has been successful.
--! 0b10 SLVERR - Slave error. Used when the access has reached the slave
--! successfully, but the slave wishes to return an error
--! condition to the originating master.
--! 0b11 DECERR - Decode error. Generated, typically by an interconnect
--! component, to indicate that there is no slave at the
--! transaction address.
r_resp : std_logic_vector(1 downto 0);
--! Read data
r_data : std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0);
--! @brief Read last.
--! @details This signal indicates the last transfer in a read burst.
r_last : std_logic;
--! @brief Read ID tag.
--! @details This signal is the identification tag for the read data
--! group of signals generated by the slave.
r_id : std_logic_vector(CFG_ROCKET_ID_BITS-1 downto 0);
--! @brief User signal.
--! @details Optional User-defined signal in the read channel. Supported
--! only in AXI4.
r_user : std_logic;
end record;
constant nasti_master_in_none : nasti_master_in_type := (
'0', '0', '0', NASTI_RESP_OKAY, (others=>'0'), '0',
'0', '0', NASTI_RESP_OKAY, (others=>'0'), '0', (others=>'0'), '0');
type nasti_master_in_vector is array (0 to CFG_NASTI_MASTER_TOTAL-1)
of nasti_master_in_type;
--! @brief Slave device AMBA AXI input signals.
type nasti_slave_in_type is record
--! Write Address channel:
aw_valid : std_logic;
aw_bits : nasti_metadata_type;
aw_id : std_logic_vector(CFG_ROCKET_ID_BITS-1 downto 0);
aw_user : std_logic;
--! Write Data channel:
w_valid : std_logic;
w_data : std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0);
w_last : std_logic;
w_strb : std_logic_vector(CFG_NASTI_DATA_BYTES-1 downto 0);
w_user : std_logic;
--! Write Response channel:
b_ready : std_logic;
--! Read Address Channel:
ar_valid : std_logic;
ar_bits : nasti_metadata_type;
ar_id : std_logic_vector(CFG_ROCKET_ID_BITS-1 downto 0);
ar_user : std_logic;
--! Read Data channel:
r_ready : std_logic;
end record;
constant nasti_slave_in_none : nasti_slave_in_type := (
'0', META_NONE, (others=>'0'), '0', '0',
(others=>'0'), '0', (others=>'0'), '0', '0', '0', META_NONE,
(others=>'0'), '0', '0');
type nasti_slave_in_vector is array (0 to CFG_NASTI_SLAVES_TOTAL-1)
of nasti_slave_in_type;
--! @brief Slave device AMBA AXI output signals.
type nasti_slave_out_type is record
--! Write Address channel:
aw_ready : std_logic;
--! Write Data channel:
w_ready : std_logic;
--! Write Response channel:
b_valid : std_logic;
b_resp : std_logic_vector(1 downto 0);
b_id : std_logic_vector(CFG_ROCKET_ID_BITS-1 downto 0);
b_user : std_logic;
--! Read Address Channel
ar_ready : std_logic;
--! Read Data channel:
r_valid : std_logic;
--! @brief Read response.
--! @details This signal indicates the status of the read transfer.
--! The responses are:
--! 0b00 OKAY - Normal access success. Indicates that a normal access has
--! been successful. Can also indicate an exclusive access
--! has failed.
--! 0b01 EXOKAY - Exclusive access okay. Indicates that either the read or
--! write portion of an exclusive access has been successful.
--! 0b10 SLVERR - Slave error. Used when the access has reached the slave
--! successfully, but the slave wishes to return an error
--! condition to the originating master.
--! 0b11 DECERR - Decode error. Generated, typically by an interconnect
--! component, to indicate that there is no slave at the
--! transaction address.
r_resp : std_logic_vector(1 downto 0);
--! Read data
r_data : std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0);
--! Read last. This signal indicates the last transfer in a read burst.
r_last : std_logic;
--! @brief Read ID tag.
--! @details This signal is the identification tag for the read data
--! group of signals generated by the slave.
r_id : std_logic_vector(CFG_ROCKET_ID_BITS-1 downto 0);
--! @brief User signal.
--! @details Optinal User-defined signal in the read channel. Supported
--! only in AXI4.
r_user : std_logic;--_vector(0 downto 0);
end record;
--! @brief Slave output signals connected to system bus.
--! @details If the slave is not connected to the vector then vector value
--! MUST BE initialized by this value.
constant nasti_slave_out_none : nasti_slave_out_type := (
'0', '0', '0', NASTI_RESP_EXOKAY,
(others=>'0'), '0', '0', '0', NASTI_RESP_EXOKAY, (others=>'1'),
'0', (others=>'0'), '0');
--! Array of all slaves outputs.
type nasti_slaves_out_vector is array (0 to CFG_NASTI_SLAVES_TOTAL-1)
of nasti_slave_out_type;
--! Array of addresses providing word aligned access.
type global_addr_array_type is array (0 to CFG_WORDS_ON_BUS-1)
of std_logic_vector(CFG_NASTI_ADDR_BITS-1 downto 0);
--! Slave device states during reading value operation.
type nasti_slave_rstatetype is (rwait, rtrans);
--! Slave device states during writting data operation.
type nasti_slave_wstatetype is (wwait, wtrans);
--! @brief Template bank of registers for any slave device.
type nasti_slave_bank_type is record
rstate : nasti_slave_rstatetype;
wstate : nasti_slave_wstatetype;
rburst : std_logic_vector(1 downto 0);
rsize : integer;
raddr : global_addr_array_type;
rlen : integer; --! AXI4 supports 256 burst operation
rid : std_logic_vector(CFG_ROCKET_ID_BITS-1 downto 0);
rresp : std_logic_vector(1 downto 0); --! OK=0
ruser : std_logic;
rwait_while_write : std_logic; --! Writing request has higher priority than read and can interrupt reading
rwaitready : std_logic; --! Reading wait state flag: 0=waiting. User's waitstates
wburst : std_logic_vector(1 downto 0); -- 0=INCREMENT
wsize : integer; -- code in range 0=1 Bytes upto 7=128 Bytes.
waddr : global_addr_array_type; --! 4 KB bank
wlen : integer; --! AXI4 supports 256 burst operation
wid : std_logic_vector(CFG_ROCKET_ID_BITS-1 downto 0);
wresp : std_logic_vector(1 downto 0); --! OK=0
wuser : std_logic;
b_valid : std_logic;
end record;
--! Reset value of the template bank of registers of a slave device.
constant NASTI_SLAVE_BANK_RESET : nasti_slave_bank_type := (
rwait, wwait,
NASTI_BURST_FIXED, 0, (others=>(others=>'0')), 0, (others=>'0'), NASTI_RESP_OKAY, '0', '0', '1',
NASTI_BURST_FIXED, 0, (others=>(others=>'0')), 0, (others=>'0'), NASTI_RESP_OKAY, '0', '0'
);
type dma_state_type is (
DMA_STATE_IDLE,
DMA_STATE_R_WAIT_RESP,
DMA_STATE_R_WAIT_NEXT,
DMA_STATE_W,
DMA_STATE_W_WAIT_REQ,
DMA_STATE_B
);
--! @brief Master device to DMA engine request signals
type dma_request_type is record
valid : std_logic; -- response is valid
ready : std_logic; -- ready to accept response
write : std_logic;
addr : std_logic_vector(CFG_NASTI_ADDR_BITS-1 downto 0);
bytes : std_logic_vector(10 downto 0);
size : std_logic_vector(2 downto 0); -- 010=4 bytes; 011=8 bytes
wdata : std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0);
end record;
--! @brief DMA engine to Master device response signals
type dma_response_type is record
ready : std_logic; -- ready to accespt request
valid : std_logic; -- response is valid
rdata : std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0);
end record;
--! DMA engine registers bank
type dma_bank_type is record
state : dma_state_type;
addr2 : std_logic; -- addr[2] bits to select low/high dword
len : integer range 0 to 255; -- burst (length-1)
op32 : std_logic;
wdata : std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0);
end record;
constant DMA_BANK_RESET : dma_bank_type := (DMA_STATE_IDLE, '0', 0, '0', (others => '0'));
--! Device's DMA engine template procedure with AXI interface.
--! @param [in] i_request Device to DMA engine request.
--! @param [out] o_response DMA Engine to Device response.
--! @param [in] i_bank Bank of registers implemented by master device.
--! @param [out] o_bank Updated value for the master bank of registers.
--! @param [in] i_msti AMBA to AXI master device signal.
--! @param [out] o_msto AXI master device signal to AMBA controller signals.
procedure procedureAxi4DMA(
i_request : in dma_request_type;
o_response : out dma_response_type;
i_bank : in dma_bank_type;
o_bank : out dma_bank_type;
i_msti : in nasti_master_in_type;
o_msto : out nasti_master_out_type
);
--! Read/write access state machines implementation for the slave device.
--! @param [in] i Slave input signal passed from system bus.
--! @param [in] cfg Slave confguration descriptor defining memory base address.
--! @param [in] i_bank Bank of registers implemented by each slave device.
--! @param [out] o_bank Updated value for the slave bank of registers.
procedure procedureAxi4(
i : in nasti_slave_in_type;
cfg : in nasti_slave_config_type;
i_bank : in nasti_slave_bank_type;
o_bank : out nasti_slave_bank_type
);
--! @brief Reordering elements of the address to provide 4-bytes memory access.
--! @param[in] mux Reordering control bits.
--! @param[in] iaddr Input addresses array.
--! @return Reordered addresses array.
function functionAddressReorder(
mux : std_logic_vector;
iaddr : global_addr_array_type)
return global_addr_array_type;
procedure procedureWriteReorder(
ena : in std_logic;
mux : in std_logic_vector(1 downto 0);
iwaddr : in global_addr_array_type;
iwstrb : in std_logic_vector(CFG_NASTI_DATA_BYTES-1 downto 0);
iwdata : in std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0);
owaddr : out global_addr_array_type;
owstrb : out std_logic_vector(CFG_NASTI_DATA_BYTES-1 downto 0);
owdata : out std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0)
);
--! @brief Complementary to address data reordring.
--! @details This function restore data bus as there wasn't address reordering.
--! @param[in] mux Reordering control bits.
--! @param[in] idata Input data array.
--! @return Restored data array.
function functionDataRestoreOrder(
mux : std_logic_vector;
idata : std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0))
return std_logic_vector;
--! Convert slave bank registers into bus output signals.
--! @param[in] r Bank of registers of the slave device.
--! @param[in] rd_val Formed by slave device read data value.
--! @return Slave device output signals connected to system bus.
function functionAxi4Output(
r : nasti_slave_bank_type;
rd_val : std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0))
return nasti_slave_out_type;
--! @brief AXI bus controller.
--! @param [in] watchdog_memop
--! @param [in] i_clk System bus clock.
--! @param [in] i_nrst Reset with active LOW level.
--! @param [in] i_slvcfg Slaves configuration vector.
--! @param [in] i_slvo Vector of slaves output signals.
--! @param [in] i_msto Vector of masters output signals.
--! @param [out] o_slvi Vector of slave inputs.
--! @param [out] o_msti Vector of master inputs.
--! @param [out] o_miss_irq Memory miss access signal. May be used as a interrupt or for debugging
--! @param [out] o_miss_addr Miss access last address (debug purpose)
--! @param [out] o_bus_util_w Write access bus utilization
--! @param [out] o_bus_util_r Read access bus utilization
--! @todo Round-robin priority algorithm.
component axictrl is
generic (
watchdog_memop : integer := 0
);
port (
i_clk : in std_logic;
i_nrst : in std_logic;
i_slvcfg : in nasti_slave_cfg_vector;
i_slvo : in nasti_slaves_out_vector;
i_msto : in nasti_master_out_vector;
o_slvi : out nasti_slave_in_vector;
o_msti : out nasti_master_in_vector;
o_miss_irq : out std_logic;
o_miss_addr : out std_logic_vector(CFG_NASTI_ADDR_BITS-1 downto 0);
o_bus_util_w : out std_logic_vector(CFG_NASTI_MASTER_TOTAL-1 downto 0);
o_bus_util_r : out std_logic_vector(CFG_NASTI_MASTER_TOTAL-1 downto 0)
);
end component;
end; -- package declaration
--! Implementation of the declared sub-programs (functions and
--! procedures).
package body types_amba4 is
--! Device's DMA engine template procedure with AXI interface.
--! @param [in] i_request Device to DMA engine request.
--! @param [out] o_response DMA Engine to Device response.
--! @param [in] i_bank Bank of registers implemented by master device.
--! @param [out] o_bank Updated value for the master bank of registers.
--! @param [in] i_msti AMBA to AXI master device signal.
--! @param [out] o_msto AXI master device signal to AMBA controller signals.
procedure procedureAxi4DMA(
i_request : in dma_request_type;
o_response : out dma_response_type;
i_bank : in dma_bank_type;
o_bank : out dma_bank_type;
i_msti : in nasti_master_in_type;
o_msto : out nasti_master_out_type
) is
variable tmp_len : integer;
begin
o_bank := i_bank;
o_msto := nasti_master_out_none;
o_msto.ar_user := '0';
o_msto.ar_id := conv_std_logic_vector(0, CFG_ROCKET_ID_BITS);
o_msto.ar_bits.size := (others => '0');
o_msto.ar_bits.burst := NASTI_BURST_INCR;
o_msto.aw_user := '0';
o_msto.aw_id := conv_std_logic_vector(0, CFG_ROCKET_ID_BITS);
o_msto.aw_bits.size := (others => '0');
o_msto.aw_bits.burst := NASTI_BURST_INCR;
o_response.ready := '0';
o_response.valid := '0';
o_response.rdata := (others => '0');
case i_bank.state is
when DMA_STATE_IDLE =>
o_msto.ar_valid := i_request.valid and not i_request.write;
o_msto.aw_valid := i_request.valid and i_request.write;
tmp_len := conv_integer(i_request.bytes(10 downto 2)) - 1;
if i_request.valid = '1' and i_request.write = '1' then
o_msto.aw_bits.addr := i_request.addr(CFG_NASTI_ADDR_BITS-1 downto 3) & "000";
o_bank.addr2 := i_request.addr(2);
o_bank.len := tmp_len;
o_msto.aw_bits.size := i_request.size; -- 4/8 bytes
o_msto.aw_bits.len := conv_std_logic_vector(tmp_len, 8);
o_bank.wdata := i_request.wdata;
if i_msti.aw_ready = '1' then
o_response.ready := '1';
o_bank.state := DMA_STATE_W;
end if;
elsif i_request.valid = '1' and i_request.write = '0' then
o_msto.ar_bits.addr := i_request.addr;
o_bank.addr2 := i_request.addr(2);
o_bank.len := tmp_len;
o_msto.ar_bits.size := i_request.size; -- 4/8 bytes
o_msto.ar_bits.len := conv_std_logic_vector(tmp_len, 8);
if i_msti.ar_ready = '1' then
o_response.ready := '1';
o_bank.state := DMA_STATE_R_WAIT_RESP;
end if;
end if;
if i_request.size = "010" then
o_bank.op32 := '1';
else
o_bank.op32 := '0';
end if;
when DMA_STATE_R_WAIT_RESP =>
o_msto.r_ready := i_request.ready;
o_response.valid := i_msti.r_valid;
if (i_request.ready and i_msti.r_valid) = '1' then
if i_bank.op32 = '1' and i_bank.addr2 = '1' then
o_response.rdata := i_msti.r_data(63 downto 32) & i_msti.r_data(31 downto 0);
else
o_response.rdata := i_msti.r_data;
end if;
if i_msti.r_last = '1' then
o_bank.state := DMA_STATE_IDLE;
else
if i_request.valid = '1' and i_request.write = '0' then
o_response.ready := '1';
else
o_bank.state := DMA_STATE_R_WAIT_NEXT;
end if;
end if;
end if;
when DMA_STATE_R_WAIT_NEXT =>
if i_request.valid = '1' and i_request.write = '0' then
o_response.ready := '1';
o_bank.state := DMA_STATE_R_WAIT_RESP;
end if;
when DMA_STATE_W =>
o_msto.w_valid := '1';
if i_bank.op32 = '1' then
case i_bank.addr2 is
when '0' => o_msto.w_strb := X"0f";
when '1' => o_msto.w_strb := X"f0";
when others =>
end case;
else
o_msto.w_strb := X"ff";
end if;
o_msto.w_data := i_bank.wdata;
if i_msti.w_ready = '1' then
if i_bank.len = 0 then
o_bank.state := DMA_STATE_B;
o_msto.w_last := '1';
elsif i_request.valid = '1' and i_request.write = '1' then
o_bank.len := i_bank.len - 1;
o_bank.wdata := i_request.wdata;
o_response.ready := '1';
-- Address will be incremented on slave side
--v.waddr2 := not r.waddr2;
else
o_bank.state := DMA_STATE_W_WAIT_REQ;
end if;
end if;
when DMA_STATE_W_WAIT_REQ =>
if i_request.valid = '1' and i_request.write = '1' then
o_bank.len := i_bank.len - 1;
o_bank.wdata := i_request.wdata;
o_response.ready := '1';
o_bank.state := DMA_STATE_W;
end if;
when DMA_STATE_B =>
o_msto.w_last := '0';
o_msto.b_ready := '1';
if i_msti.b_valid = '1' then
o_bank.state := DMA_STATE_IDLE;
end if;
when others =>
end case;
end; -- procedure
--! Read/write access state machines implementation.
--! @param [in] i Slave input signal passed from system bus.
--! @param [in] cfg Slave confguration descriptor defining memory base address.
--! @param [in] i_bank Bank of registers implemented by each slave device.
--! @param [out] o_bank Updated value for the slave bank of registers.
procedure procedureAxi4(
i : in nasti_slave_in_type;
cfg : in nasti_slave_config_type;
i_bank : in nasti_slave_bank_type;
o_bank : out nasti_slave_bank_type
) is
variable traddr : std_logic_vector(CFG_NASTI_ADDR_BITS-1 downto 0);
variable twaddr : std_logic_vector(CFG_NASTI_ADDR_BITS-1 downto 0);
begin
o_bank := i_bank;
traddr := (i.ar_bits.addr(CFG_NASTI_ADDR_BITS-1 downto 12) and (not cfg.xmask))
& i.ar_bits.addr(11 downto 0);
o_bank.rwait_while_write := '0';
-- Reading state machine:
case i_bank.rstate is
when rwait =>
if i.ar_valid = '1' and i_bank.wstate /= wtrans then
o_bank.rstate := rtrans;
for n in 0 to CFG_WORDS_ON_BUS-1 loop
o_bank.raddr(n) := traddr + n*CFG_ALIGN_BYTES;
end loop;
o_bank.rsize := XSizeToBytes(conv_integer(i.ar_bits.size));
o_bank.rburst := i.ar_bits.burst;
o_bank.rlen := conv_integer(i.ar_bits.len);
o_bank.rid := i.ar_id;
o_bank.rresp := NASTI_RESP_OKAY;
o_bank.ruser := i.ar_user;
--! No Wait States by default for reading operation.
--!
--! User can re-assign this value directly in module to implement
--! reading wait states.
--! Example: see axi2fse.vhd bridge implementation
o_bank.rwaitready := '1';
o_bank.rwait_while_write := i.aw_valid;
end if;
when rtrans =>
o_bank.rwait_while_write := i.aw_valid or i.w_valid;
if i.r_ready = '1' and i_bank.rwaitready = '1' and i_bank.rwait_while_write = '0' then
o_bank.rlen := i_bank.rlen - 1;
if i_bank.rburst = NASTI_BURST_INCR then
for n in 0 to CFG_WORDS_ON_BUS-1 loop
o_bank.raddr(n) := i_bank.raddr(n) + i_bank.rsize;
end loop;
end if;
-- End of transaction (or process another one):
if i_bank.rlen = 0 then
if i.ar_valid = '0' then
o_bank.rstate := rwait;
else
for n in 0 to CFG_WORDS_ON_BUS-1 loop
o_bank.raddr(n) := traddr + n*CFG_ALIGN_BYTES;
end loop;
o_bank.rsize := XSizeToBytes(conv_integer(i.ar_bits.size));
o_bank.rburst := i.ar_bits.burst;
o_bank.rlen := conv_integer(i.ar_bits.len);
o_bank.rid := i.ar_id;
o_bank.rresp := NASTI_RESP_OKAY;
o_bank.ruser := i.ar_user;
o_bank.rwaitready := '1';
end if;
end if;
end if;
end case;
-- Writting state machine:
case i_bank.wstate is
when wwait =>
if i.aw_valid = '1' then
o_bank.wstate := wtrans;
twaddr := (i.aw_bits.addr(CFG_NASTI_ADDR_BITS-1 downto 12) and (not cfg.xmask))
& i.aw_bits.addr(11 downto 0);
for n in 0 to CFG_WORDS_ON_BUS-1 loop
o_bank.waddr(n) := twaddr + n*CFG_ALIGN_BYTES;
end loop;
o_bank.wsize := XSizeToBytes(conv_integer(i.aw_bits.size));
o_bank.wburst := i.aw_bits.burst;
o_bank.wlen := conv_integer(i.aw_bits.len);
o_bank.wid := i.aw_id;
o_bank.wresp := NASTI_RESP_OKAY;
o_bank.wuser := i.aw_user;
end if;
when wtrans =>
if i.w_valid = '1' then
o_bank.wlen := i_bank.wlen - 1;
if i_bank.wburst = NASTI_BURST_INCR then
for n in 0 to CFG_WORDS_ON_BUS-1 loop
o_bank.waddr(n) := i_bank.waddr(n) + i_bank.wsize;
end loop;
end if;
-- End of transaction:
if i_bank.wlen = 0 then
o_bank.wstate := wwait;
o_bank.b_valid := '1';
end if;
end if;
end case;
if i.b_ready = '1' and i_bank.b_valid = '1' then
o_bank.b_valid := '0';
end if;
end; -- procedure
--! @brief Reordering elements of the address to provide 4-bytes memory access.
--! @param[in] mux Reordering control bits.
--! @param[in] iaddr Input addresses array.
--! @return Reordered addresses array.
function functionAddressReorder(
mux : std_logic_vector;
iaddr : global_addr_array_type)
return global_addr_array_type is
variable oaddr : global_addr_array_type;
begin
if CFG_NASTI_DATA_BITS = 128 then
if mux = "00" then
oaddr := iaddr;
elsif mux = "01" then
oaddr(0) := iaddr(3);
oaddr(1) := iaddr(0);
oaddr(2) := iaddr(1);
oaddr(3) := iaddr(2);
elsif mux = "10" then
oaddr(0) := iaddr(2);
oaddr(1) := iaddr(3);
oaddr(2) := iaddr(0);
oaddr(3) := iaddr(1);
else
oaddr(0) := iaddr(1);
oaddr(1) := iaddr(2);
oaddr(2) := iaddr(3);
oaddr(3) := iaddr(0);
end if;
elsif CFG_NASTI_DATA_BITS = 64 then
if mux(2) = '0' then
oaddr := iaddr;
else
oaddr(0) := iaddr(1);
oaddr(1) := iaddr(0);
end if;
end if;
return oaddr;
end;
--! @brief Reordering elements of the write transaction to provide 4-bytes memory access.
procedure procedureWriteReorder(
ena : in std_logic;
mux : in std_logic_vector(1 downto 0);
iwaddr : in global_addr_array_type;
iwstrb : in std_logic_vector(CFG_NASTI_DATA_BYTES-1 downto 0);
iwdata : in std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0);
owaddr : out global_addr_array_type;
owstrb : out std_logic_vector(CFG_NASTI_DATA_BYTES-1 downto 0);
owdata : out std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0)) is
begin
if CFG_NASTI_DATA_BITS = 128 and ena = '1' then
if mux = "00" then
owaddr := iwaddr;
owdata := iwdata;
owstrb := iwstrb;
elsif mux = "01" then
owaddr(0) := iwaddr(3);
owaddr(1) := iwaddr(0);
owaddr(2) := iwaddr(1);
owaddr(3) := iwaddr(2);
owdata(31 downto 0) := iwdata(127 downto 96);
owdata(127 downto 32) := iwdata(95 downto 0);
owstrb := iwstrb(11 downto 0) & iwstrb(15 downto 12);
elsif mux = "10" then
owaddr(0) := iwaddr(2);
owaddr(1) := iwaddr(3);
owaddr(2) := iwaddr(0);
owaddr(3) := iwaddr(1);
owdata(63 downto 0) := iwdata(127 downto 64);
owdata(127 downto 64) := iwdata(63 downto 0);
owstrb := iwstrb(7 downto 0) & iwstrb(15 downto 8);
else
owaddr(0) := iwaddr(1);
owaddr(1) := iwaddr(2);
owaddr(2) := iwaddr(3);
owaddr(3) := iwaddr(0);
owdata(95 downto 0) := iwdata(127 downto 32);
owdata(127 downto 96) := iwdata(31 downto 0);
owstrb := iwstrb(3 downto 0) & iwstrb(15 downto 4);
end if;
elsif CFG_NASTI_DATA_BITS = 64 and ena = '1' then
if mux(0) = '0' then
owaddr := iwaddr;
owdata := iwdata;
owstrb := iwstrb;
else
owaddr(0) := iwaddr(1);
owaddr(1) := iwaddr(0);
owdata(31 downto 0) := iwdata(63 downto 32);
owdata(63 downto 32) := iwdata(31 downto 0);
owstrb := iwstrb(3 downto 0) & iwstrb(7 downto 4);
end if;
else
owaddr := (others => (others => '0'));
owdata := (others => '0');
owstrb := (others => '0');
end if;
end;
--! @brief Complementary to address data reordring.
--! @details This function restore data bus as there wasn't address reordering.
--! @param[in] mux Reordering control bits.
--! @param[in] idata Input data array.
--! @return Restored data array.
function functionDataRestoreOrder(
mux : std_logic_vector;
idata : std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0))
return std_logic_vector is
variable odata : std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0);
begin
if CFG_NASTI_DATA_BITS = 128 then
if mux = "00" then
odata := idata;
elsif mux = "01" then
odata(95 downto 0) := idata(127 downto 32);
odata(127 downto 96) := idata(31 downto 0);
elsif mux = "10" then
odata(63 downto 0) := idata(127 downto 64);
odata(127 downto 64) := idata(63 downto 0);
else
odata(31 downto 0) := idata(127 downto 96);
odata(127 downto 32) := idata(95 downto 0);
end if;
elsif CFG_NASTI_DATA_BITS = 64 then
if mux(2) = '0' then
odata := idata;
else
odata(31 downto 0) := idata(63 downto 32);
odata(63 downto 32) := idata(31 downto 0);
end if;
end if;
return odata;
end;
--! @brief Convert bank registers into output signals
--! @param[in] r Registers bank with the AXI4 state machines
--! implementaitons.
--! @param[in] rd_val Read value from the device's registers bank.
--! This value fully depends of device implementation.
--! @return NASTI output signals of the implemented slave device.
function functionAxi4Output(
r : nasti_slave_bank_type;
rd_val : std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0))
return nasti_slave_out_type is
variable ret : nasti_slave_out_type;
begin
-- Read transfer:
ret.aw_ready := '1';
ret.ar_ready := '1';
ret.r_id := r.rid;
if r.rstate = rtrans and r.rlen = 0 then
ret.r_last := '1';
else
ret.r_last := '0';
end if;
ret.r_resp := r.rresp;
ret.r_user := r.ruser;
if r.rwaitready = '1' and r.rstate = rtrans and r.rwait_while_write = '0' then
ret.r_valid := '1';
else
ret.r_valid := '0';
end if;
ret.r_data := rd_val;
-- Write transfer:
if r.wstate = wtrans then
ret.w_ready := '1';
ret.aw_ready := '0';
ret.ar_ready := '0';
else
ret.w_ready := '0';
end if;
-- Write Handshaking:
ret.b_id := r.wid;
ret.b_resp := r.wresp;
ret.b_user := r.wuser;
ret.b_valid := r.b_valid;
return (ret);
end;
end; -- package body