Segmented Configuration or Dynamic Function eXchange

Whether you are using the AMD Embedded Development Framework (EDF) or making your own software, many users need the ability to reconfigure portions of the hardware without re-starting the software.

When using this functionality on AMD’s Adaptive SoCs there are several steps you must take to make sure that the software and hardware interact and do not cause crashes or un-defined behavior.

Generic vs AMD Tooling Approach

This page contains the general steps users need to take to use Segmented Configuration or Dynamic Function eXchange.

If you are using AMD’s Yocto Project tooling, take a look at the DFX (Green in the below diagram) or Segmented Configuration (Blue in the below diagram) pages.

Decision-tree diagram for choosing a partial-reconfiguration flow: branches by Device Family (ZynqMP / Zynq 7000 vs. Versal and later) and When to load the partition (post-FSBL or as part of FSBL on the Zynq side; as part of boot PDI or post boot PDI on the Versal side), highlighting Segmented config in the Versal / post-boot-PDI path and DFX as the dynamic-partition outcome (DFX is only supported with non-segmented config on Versal).

Choosing between DFX and segmented configuration.

Definitions

  • “Module”: A grouping of hardware that can be loaded as a unit, represented by a binary file that represents the machine interpretable hardware (.bin for AMD Zynq UltraScale+ MPSoC devices, or .pdi for the AMD Versal portfolio), and a hardware description that is interpretable by the software (device tree). Modules are intended to be loaded/enabled/reconfigured at an arbitrary time, by firmware, by bootloaders, by hypervisors, or by individual operating systems.

  • “Segmented configuration”: Only applies to Versal and later devices (although Zynq MPSoC has a similar concept referred to as “classic SoC boot”). “Segmented configuration” is when a subset of the total hardware in the system (usually enough to boot the software), is separate from the rest of the hardware in the system and the software uses special drivers or commands (fpgamanager or dfxutil in the case of Linux) to load the rest of the hardware.

Steps

  1. Identify hardware that is in the module to be loaded after boot. Hardware design tools can help identify this information, but the system-level design is the primary source of this information.

  2. Isolate the identified hardware to its own device tree file (.dtsi)

    1. AMD has two use cases for reconfiguration: Segmented Configuration and Dynamic Function eXchange (DFX).

      1. For Segmented Configuration, AMD assumes that hardware in the pl.dtsi file produced by SDTGen correlates 1:1 with the data in the post-boot module.

  3. Modify (using lopper with the appropriate lops) the isolated hardware device tree to ensure it is enclosed in an appropriate block.

    1. The appropriate block is defined by the FPGA driver, the bindings for which are defined here. An example is going from:

      / {
          amba_pl: amba_pl {
              ranges;
              compatible = "simple-bus";
              #address-cells = <2>;
              #size-cells = <2>;
              firmware-name = "zcu_104_demo_mpsoc_preset_wrapper.bit.bin";
              clocking0: clocking0 {
      ...
      

      to

      /dts-v1/;
      /plugin/;
      &fpga_full{
          firmware-name = "zcu_104_demo_mpsoc_preset_wrapper.bit.bin";
      };
      &amba{
          clocking0: clocking0 {
      ...
      
  4. Remove the isolated hardware from the system device tree. In AMD software flows this is accomplished by removing pl.dtsi from system-top.dtsi.

    Old version:

    /dts-v1/;
    #include "zynqmp.dtsi"
    #include "zynqmp-clk-ccf.dtsi"
    #include "pl.dtsi"
    #include "pcw.dtsi"
    / {
        board = "zcu104";
        device_id = "xczu7ev";
        slrcount = <1>;
    

    New version:

    /dts-v1/;
    #include "zynqmp.dtsi"
    #include "zynqmp-clk-ccf.dtsi"
    #include "pcw.dtsi"
    / {
        board = "zcu104";
        device_id = "xczu7ev";
        slrcount = <1>;
    
  5. Compile the isolated hardware information into a device tree binary. (using the device tree complier)

  6. Obtain the FPGA binary file (.bin file for ZynqMP, or .pdi for Versal and later)

    1. If you have a .bit file (as opposed to a .bin file), use bootgen to remove the headers and sync words as those are not needed by fpgautil

  7. If using DFX (not Segmented Configuration) Create a shell.json

  8. Put the compiled .dtb file, the FPGA binary file, and shell.json onto your filesystem in /lib/firmware/xilinx.

  9. Run dfx-mgr pointing to /lib/firmware/xlinx.