Hardware Abstraction Layer

The UltraZohm uses a hardware abstraction layer (HAL) to make the code portable and enable the development in a local sandbox (your PC). All IP-core drivers and bare-metal software has to use the HAL (uz_HAL.h). We use simple defines to facilitate the HAL. The header is located in ultrazohm_sw/vitis/software/Baremetal/src/uz/uz_HAL.h. Furthermore, the HAL defines functions to read and write values from and to the PL via AXI.

  • Include the header in your software and use it.

  • Use the standard libs such as <stdint> or <limits.h> instead of platform specific libraries.

  • Use int or float for variables

  • Do not use unsigned int to prevent negative values

  • Use assert >0 to make sure a variable is positive instead

  • Do use fixed length unsigned variables for hardware addresses (e.g. base addresses of IP-cores)

  • Only use fixed length variables (e.g., int32_t) for function that write to hardware registers

  • Do not use platform specific data types

Note

The UltraZohm offers 32 bit and 64 bit processors, thus the HAL enables portable code between R5 and A53

Warning

uz_printf maps to xil_printf on the UltraZohm and xil_printf does not support everything that printf from <stdio.h> does, e.g., you can not print floats with %f

HAL Functions

The HAL provides the following functions and macros:

Assertions

See Assertions.

Sleep

uz_sleep_seconds

Processor does nothing for defined seconds.

uz_sleep_useconds

Processor does nothing for defined microseconds.

Printf

uz_printf

Prints to stdout, i.e., Vitis terminal.

Success and failure define

UZ_SUCCESS

Return this define to indicate success in a function and check return value.

UZ_FAILURE

Return this define to indicate failure in a function and check return value.

AXI Functions

The header uz_AXI.h provides the following functions to read/write from/to the PL by using the AXI interface. Use only these functions for AXI and use them only in the lowest layer of the software.

static inline void uz_axi_write_float(uintptr_t Addr, float Value)

Writes a float value to the specified register by AXI.

Parameters:
  • Addr – Absolute address of the register (base address+offset).

  • Value

static inline float uz_axi_read_float(uintptr_t Addr)

Reads a float value from the specified register by AXI.

Parameters:
  • Addr – Absolute address of the register (base address+offset).

Returns:

float

static inline void uz_axi_write_uint32(uintptr_t Addr, uint32_t Value)

Write a 32-bit unsigned int variable to the specified register by AXI.

Parameters:
  • Addr – Absolute address of the register (base address+offset).

  • Value

static inline uint32_t uz_axi_read_uint32(uintptr_t Addr)

Reads a 32-bit unsigned int variable from the specified register by AXI.

Parameters:
  • Addr – Absolute address of the register (base address+offset).

Returns:

uint32_t

static inline int32_t uz_axi_read_int32(uintptr_t Addr)

Reads a 32-bit signed int variable from the specified register by AXI.

Parameters:
  • Addr – Absolute address of the register (base address+offset).

Returns:

int32_t

static inline void uz_axi_write_int32(uintptr_t Addr, int32_t Value)

Writes a 32-bit signed int variable to the specified register by AXI.

Parameters:
  • Addr – Absolute address of the register (base address+offset).

  • Value

static inline void uz_axi_write_bool(uintptr_t Addr, _Bool enable)

Writes a boolean to the specified register by AXI. True is written as a 32-bit unsigned int variable with value 0x00000001. False is written as a 32-bit unsigned int variable with value 0x00000000.

Parameters:
  • Addr – Absolute address of the register (base address+offset).

  • enable – true/false.

static inline _Bool uz_axi_read_bool(uintptr_t Addr)

Reads a boolean from the specified register by AXI. If the value is read as a 32-bit unsigned value. False is 0x00000000, true is 0x00000001. If any bit except the LSB is one an assertion triggers.

Parameters:
  • Addr – Absolute address of the register (base address+offset).

Returns:

_Bool

static inline float uz_convert_sfixed_to_float(int32_t data, int number_of_fractional_bits)

Converts a signed fixed point value that is stored as a signed 32-bit integer value to a float. This function should only be used directly after reading the int32_t variable from AXI!

Parameters:
  • data – Fixed point value stored as a signed 32-bit integer that is read from AXI.

  • number_of_fractional_bits – Number of fractional bits of the data, 31-number_of_fractional_bits is the number of integer bits.

Returns:

float

static inline int32_t uz_convert_float_to_sfixed(float data, int number_of_fractional_bits)

Converts a float to a 32-bit signed integer value. This function should only be used directly before writing the int32_t variable from AXI!

Parameters:
  • data

  • number_of_fractional_bits – Number of fractional bits of the data, 31-number_of_fractional_bits is the number of integer bits.

Returns:

int32_t