Porting the UZ-Framework for the KR260

In case you don’t have access to an UltraZohm, various other evaluation kits can be used for preliminary developments. The goal of this how-to is to port the existing UltraZohm project to the KR260 board to create a small HiL environment for the first tests. Based on the getting-started the same workflow is used. First, a suitable hardware_design is created in Vivado, the required information is exported to Vitis, and then the UltraZohm project is created. Subsequently, minor changes are made to the source files, and the software is started on the KR260. This is the starting point for small Hil/Sil/PiL projects, which are compatible with the main UltraZohm-project.


This how-to is a good start for Porting the UZ-Framework for other evaluation kits, but this requires some knowledge about the tools and the board, the workflow and a general overview of how SoC systems work.


In the current state, with this how-to you can create your UZ-Port for the KR260. This will do the job, but there are still some open issues and some space for improvements!


  • Getting-Started completed and understood

  • A KR260 evaluation kit

  • Install Vitis and Vivado 2022.2, download here

  • Basic knowledge of the used tools.


To get the UltraZohm-Framework running on the KR260, first of all a valid Hardware-Design is needed. This can be done with the create a project from scratch or using mainly scripts.

Creating Fresh Project

  1. Create a fresh project in Vivado 2022.2

  2. When you were asked for the Default Part, select Kria KR260 Robotics Starter Kit SOM


    Fig. 46 Boardselection UZ-KR260.

  3. Add a new Block design and name with k26sys

  4. Add the UltraZohm IP-Repository to the project.


    Settings IP Repository Add IP core folder Select OK

  5. Add the IP-Core for the PS Zynq UltraScale+ MPSoC to the new Block design.

  6. Click “Run Block automation” inside the green banner appearing.


    This is the only point where you need automated assistant from Vivado! “Do not click to auto connection within the following Steps, otherwise Vivado is going to address the unused pins before deleting and create more problems!”

  7. Create HDL-Wrapper and make sure its the Top-file.

  8. Download the Constrain-file for the KR260 SOM directly from Xilinx KR260-Contrains and add the file to the project. (Link → Key Features → Design Resources → Kria K26 CCDR → KRIA K26 SOM XDC File).

  9. Some VHDL-files have to be added manually as design sources to the Vivado-Project. Those files actually were located in ip_cores and vivado folders. Search for

    • ip_cores Interlock_Module_3L top_npc_state_machine.vhd

    • ip_cores Interlock_Module_3L npc_phase_state_machine.vhd

    • ip_coresDelay_signal delay_trigger.vhd

    • ip_cores Extend_Interrupt extend_interrupt.vhd

    • vivado src hdl iobufds_inst.vhd


    Add sources Add or Create design sources Add Files Choose the files Finish

  10. Following changes to the PS are needed

    • Deactivate both HP-AXI-Masterports

      Re-customize IP → PS-PL Configuration → PS-PL Interfaces → Master Interface → Deactivate AXI HPM0 FPD and AXI HPM1 FPD

    • Activate the LP-AXI-MasterPort

      Re-customize IP → PS-PL Configuration → PS-PL Interfaces → Master Interface → Activate AXI HPM0 LPD

    • Activate GEM1 on MIO38-49 with MDIO on MIO51-51

      Re-customize IP → I/O Configuration → High Speed → Activate GEM1 and change I/O → Open GEM 1 → Activate MDIO1 and change I/O

    • Activate I2C on MIO24-25

      Re-customize IP → I/O Configuration → Low Speed → I2C → Activate I2C1 → Open I2C → Activate I2C1 and change I/O

    • Active UART1 on MIO36-37

      Re-customize IP → I/O Configuration → Low Speed → UART → Activate UART1 → Open UART → Activate UART1 and change I/O

    • Deactivate the second PL-Clock

      Re-customize IP → Clock Configuration → Output Clocks → Low Power Domain Clocks → PL Fabric Clocks → Deactivate PL1


    Use the provided tcl_Script vivado_UZ_K26_ZynqMP_PResets.tcl when configuring the PS. This script can be used while configuring the IP-Core, click on the top left “Presets” and “Apply Configuration”

  11. After applying the settings for the PS, the UltraZohm-Hardware can be implemented. To accelerate the reconstruction of the whole Block-Design, there were TCL-Scripts for each UZ-Hierarchy available.

    • kria_vivado_block_uz_user.tcl

    • kria_vivado_block_uz_system.tcl

    • kria_vivado_block_uz_analog_adapter.tcl

    • kria_vivado_block_digital_adapter.tcl

  12. Create an empty hierarchy, e.g. hier_0.

  13. Switch with the TCL Console to the current working folder with:

    cd [ get_property DIRECTORY [current_project] ]
  14. Source the first dedicated UZ-Hierarchy-Script with:

    source ../tcl_scripts/kria_vivado_block_uz_user
  15. Create the wanted hierarchy inside hier_0 with:

    create_hier_cell_uz_user hier_0 uz_user
  16. Afterward, move the freshly created hierarchy out of hier_0 one level higher and it can be used in your block design.

    move_bd_cells [get_bd_cells /] [get_bd_cells hier_0/uz_user]

    With this script, every IP-Core inside the generated hierarchy is configured and connected like in the UltraZohm-main-project

  17. For the uz_user and uz_digital_adapter, make the placement of IP blocks using the .tcl scripts:

    source ../tcl_scripts/kria_vivado_block_uz_system.tcl
    create_hier_cell_uz_system hier_0 uz_system
    move_bd_cells [get_bd_cells /] [get_bd_cells hier_0/uz_system]
    source ../tcl_scripts/kria_vivado_block_digital_adapter.tcl
    create_hier_cell_uz_digital_adapter hier_0 uz_digital_adapter
    move_bd_cells [get_bd_cells /] [get_bd_cells hier_0/uz_digital_adapter]
  18. Don’t recreate the uz_analog_adapter since we don’t have analog-Interfaces with the KR260.

  19. Delete every digital Slot inside uz_digital_adapter except D1. We only want to use the 2-LvL-PWM-Cores in this How-To.

  20. Manually route the created hierarchies to the PS. Use the UltraZohm-Main-Project as a template.

  21. Fix the remaining open Inputs of the hierarchies to constants.

  22. Generate the Bitstream and export the .xsa as mentioned in Generate the bitstream with Vivado

Following those steps should lead to an HW-Design like this:


Fig. 47 Vivado-Project Hardware-Design KR260.

Project with TCL Scripts:

  1. Create a fresh project in Vivado 2022.2 with Kria KR260 Robotics Starter Kit SOM board.

  2. Add the missing VHDL-files:

  3. Add the UltraZohm IP-Repository to the project.

  4. Add a new Block design and name with k26sys.

  5. Switch with the TCL Console to the current working folder with:

    cd [ get_property DIRECTORY [current_project] ]
  6. Open TCL Console and call the TCL-scripts for block and connection implementation with given order:

    source ../tcl_scripts/k26sys_ps_generaton.tcl
    source ../tcl_scripts/k26sys_hd_generaton.tcl
  7. Create VHDL wrapper for kr260sys and set as top manually.

  8. With this step, you have current UltraZohm project for Kria as implemented. Generate bitstream and export. If you want to see the detailed steps, check out the tcl_scripts folder:

    • k26sys_ps_generation → PS

    • k26sys_hd_generation → IP-Cores, Connections


Please consider TCL Scripts and generated flow use the ultrazohm_sw as main location, so you might need to create a folder for kria vivado project inside of ultrazohm_sw.

  1. Generate the Bitstream and export the .xsa.


After creating the Hardware-Design, there were a few Software-changes necessary. This includes mainly the removed IP-Cores and the Frontpanel, as well as the ISR. Additionally, a small hack to the Board-Support-Package BSP must be applied to bring up the network interface.# This hack prevents a double-initiation for the PS-Files, since GEM0 uses a SGMII Interface which isn’t compatible with the used LwIP-Stack and both PHY’s for the PS-GEM’s shared the same MDIO’s.

To create a suited software for the KR260, follow these steps:

  1. Open Vitis 2022.2 and create the Workspace according to Ultrazohm Setup.

    • Open the XSCT Console in Vitis. Type the following commands:

    cd [getws]
    source {../../tcl_scripts/vitis_generate_UltraZohm_workspace.tcl}
  2. The script WILL FAIL, but this is okay for our use case.

  3. Clean the “UZ-Plattform-Project” and both “C-Projects”.

  4. Open the BSP-Packages for the “FreeRTOS_domain” and “Baremetal_domain” and ensure that stdin and stdout points to ps_uart_1.


    Fig. 48 Vitis BSP-Settings for KR260.

  5. Build the “UZ-Plattform-Project”.

  6. Changes for the Baremetal-Project:

    1. Addresses of dead IP-Cores have to be tied to a fixed address at parameter.h file. Use 0x0123456789 as address to prevent errors during compiling and ensure that those addresses never getting called!



      • #define XPAR_UZ_ANALOG_ADAPTER_A1_ADAPTER_A1_ADC_LTC2311_S00_AXI_BASEADDR 0x0123456789

      • #define XPAR_UZ_ANALOG_ADAPTER_A2_ADAPTER_A2_ADC_LTC2311_S00_AXI_BASEADDR 0x0123456789

      • #define XPAR_UZ_ANALOG_ADAPTER_A3_ADAPTER_A3_ADC_LTC2311_S00_AXI_BASEADDR 0x0123456789

    2. In the main.c - case init_ip_cores, comment out the Init-routines of the removed IP-Cores

      • uz_adcLtc2311_ip_core_init();

      • PWM_3L_Initialize(&Global_Data); // three-level modulator

      • initialize_incremental_encoder_ipcore_on_D5(UZ_D5_INCREMENTAL_ENCODER_RESOLUTION, UZ_D5_MOTOR_POLE_PAIR_NUMBER);

    3. In the main.c - case init_gpios / uz_frontplane_button_and_led_init() , comment out

      • enableAllMioWithLEDsAttached();

      • enableAllMioWithButtonsAttached();

      Those pins cause the board to hang somehow if used, so disable the output from the PS-GPIO.

    4. Inside the ISR, comment out

      • ReadAllADC();

      • update_speed_and_position_of_encoder_on_D5(&Global_Data);

      • PWM_3L_SetDutyCycle();

    5. Comment out the Assertion in uz / uz_GPIO / uz_gpio.c line 44. We disabled the Outputs from the PS-GPIO, so this assertion will fire!

      • uz_assert( uz_gpio_get_enable_output(self) );

    6. Fixing the Stop-Flag in hw_init / uz_platform_state_machine.c line 277 to 0. With no PS-GPIO enabled, we can’t get any buttons.

  7. Changes for the FreeRTOS-Project:

    1. Delete ever CAN-related Code from the main.c and remove the files can.c and can.h.

    2. add a new define #define OS_IS_FREERTOS in the main.h.

    3. Increase the DHCP-Timeout in the main.c.

      • if (mscnt >=DHCP_COARSE_TIMER_SECS * 2000)

    4. “Hack” the LWIP-Stack of the BSP to handle the shared MDIO for the PS-PHY’s. The file is located under \workspace\UltraZohm\psu_cortexa53_0\FreeRTOS_domain\bsp\psu_cortexa53_0\libsrc\lwip211_v1_8\src\contrib\ports\xilinx\netif\xemacpsif_physpeed.c

      • Inside the File xemacpsif_physpeed.c, change line 291 to: for (phy_addr = 31; phy_addr >5; phy_addr--)

  8. Manually add the Launch-configs. Copy the .launches-fils from the software-folder to

    • \workspace\.metadata\.plugins\org.eclipse.debug.core\.launches\

  9. Restart Vitis to make the. launches-files accessible

  10. Build both C-Projects

  11. Control the Debug Configuration and run the project on the KR260.

    • Control the Debug Configuration - Application and Target Setup.

    • Debug Configuration - Application → Make sure the psu_cortexa53_0 for FreeRTOS and psu_cortexr5_0 for Baremetal are activated.

    • Debug Configuration - Target Setup → Check the Bitsream file for KR260. It should use newly generated bitsream, not Ultrazohm file.

  12. Check out the Vitis Serial Terminal output, and Open the JavaScope to see lifecheck signal.

Known Issues

  • The applied BSP-Hack is done in generated source files. This means regenerating the BSP WILL DELETE THE HACK and the FreeRTOS won’t initialize the PHY properly. If the error “autonegation failed” show’s up during the start, check if the hack is still present.

  • Vitis 2022.2 has known issues related with launching. You can use the referenced solution by Xilinx.


With this How-To it’s possible to port the UltraZohm-Framework to the KR260. Furthermore most steps and scripts could be also used for porting the Framework to other evaluation kits. The proposed flow is not finally finished and feedback is appreciated!

Some points and ideas for discussion on how the workflow could be better integrated into the main UltraZohm Project:

  • Use GEM 2 or 3 and route the Pins through the PL-part to use the PL-dedicated PHY’s? They’re not sharing a MDIO-Interface, so the BSP-hack should not be necessary!

  • Add a CAN-Interface and route the pins through the PL to an PMOD-connector, for example? So we don’t have to delete the CAN-related parts in the FreeRTOS-Project

  • How a define should look like to tell the C-Code it’s a KR260/KV260-Hil? With this define some actions can be done:

    • Exclude some predefined IP-Cores from the Code?
      • Analog-IP’s

      • Encoder

    • Exclude critical functions from calling
      • enableAllMioWithLEDsAttached();

      • enableAllMioWithButonsAttached();

      • ReadAllADC();

      • update_speed_and_position_of_encoder_on_D5(&Global_Data);

      • PWM_3L_SetDutyCycle();

      • uz_assert( uz_gpio_get_enable_output(self) );

  • Edit the vitis_generate_UltraZohm_workspace.tcl to work with the KR260.

  • Enable an EMIO for one TTC to create a PWM-Signal to control the Fan of the SoM. Would perhaps also be an idea for the real Ultrazohm?