Custom Board Definition Files
Introduction
The board definition file (BDF) or simply board file uses an XML format to define information about system-level boards that use or include Xilinx devices. The information contained in the board file can be used by the Vivado Design Suite, and Vivado IP integrator, to facilitate and validate connection of the Xilinx device to the board.
In a Vivado installation, you'll find the collection of supported boards in the following path:
<install_dir>/Vivado/<version>/data/boards/board_files/
For this course, based on Vitis and Vivado 2019.2, the default path is:
/tools/Xilinx/Vivado/2019.2/data/boards/board_files/
As an useful resource, Xilinx maintains the Xilinx Board Store at GitHub, where you can find all of the board definition files for Xilinx development kits and third party boards.
NOTE: More detailed information about Board Definition Files can be found in UG895 Vivado System Level Design Entry, Appendix A
Getting the Ultra96-V2 board files
Because the board definition files for Ultra96-V2 are not included into the Vivado installation, we need to copy them from the Avnet Github repository that contains all of the Board Definition Files for its own brand platforms:
In this way, in order to provide support for the Ultra96-V2 board in Vivado, as a first step we must clone the Avnet's BDF repository:
git clone https://github.com/Avnet/bdf.git
Now, all we need to do is copying the Ultra96-V2 specific BDF files to the board_files folder in Vivado:
sudo cp -r bdf/ultra96v2 /tools/Xilinx/Vivado/2019.2/data/boards/board_files
Once this is done, the next time we create a project in Vivado we will be able to select Ultra96-V2 as a template board for our design.
The BDF for the Ultra96v2 are very simple. This is the tree view of the contained files:
ultra96v2/
└── 1.0
├── board.xml
├── part0_pins.xml
├── preset.xml
└── ultra96v2.jpg
Fixing the Ultra96-V2 board files
While practicing with this course, the first users reported a series of issues preventing the correct generation of the Vivado hardware designs. After some research, the issues were identified in the board definitions files for the Ultra96-V2 in the Avnet BDF repository.
The issues are going to be reported to Avnet but, until they are fixed, we will need to review and fix the files for the Ultra96-V2 to successfully develop the exercises in this course.
Note that, the first time this course was performed, the latest commit in the Avnet BDF repository was:
In this commit, with the exception of a single fixed typo, the history for the Ultra96-V2 board definition files dated back to Oct 19, 2018. If nobody had complained about this yet... what could be the cause of the problems we had detected? In the coming subsections, we will find out.
Board File
The board.xml file contains the top level information about the Ultra96-V2, including:
- Basic information such as name, vendor or revision.
-
Components in the board, such as:
- FPGA part for the used Zynq UltraScale+ MPSoC.
- Fixed I/O in the Zynq UltraScale+ MPSoC processing system.
- JTAG chain.
- Name of the preset file that contains the configuration parameters for the system.
- Name of the pin map file that contains the information about component connections.
This file looks sane and doesn't require any modification.
Pin File
The part0_pins.xml is supposed to contain a list of the locations and constraints for the pins at the Programmable Logic:
- UART2 in Programmable Logic.
- I2C devices 0 and 1.
- DDR4 signals.
- Radio System LED and Reset.
- High Speed Inter-Chip (HSIC).
- Display Port Clock Signals.
In the file, the part name is the xczu3eg-sbva484-1-e, and this is correct.
The problem arise when you try to give a deeper look to the part pin locations against the schematic.
First, if we focus in the UART and I2C devices, we have these signals:
Signal | location |
---|---|
uart2_PL_TX | AU15 |
uart2_PL_RX | AT15 |
IIC0_SCL_MAIN | AT16 |
IIC0_SDA_MAIN | AW16 |
IIC1_SCL_MAIN | AV16 |
IIC1_SDA_MAIN | AV13 |
But all of the locations of the signals cannot be found in the schematic for a very simple reason. If you search for the XCZU3EG-SBVA484 device in the Zynq UltraScale+ MPSoC Package Device Pinout Files, you'll find that these locations doesn't exist for the device and package:
Next, if we take a look to the DDR4 locations in the part0_pins.xml, we will see that there are some of them that are connected to other peripherals, e.g. the USB3.1 hub. But the actual question is... why do we have any DDR4 pinout at all if this pin map file is supposed to be related with the Programmable Logic side and the Ultra96-V2 doesn't have any DDR4 connected to the PL?
Finally, the other PIN locations for Radio LED and reset, HSIC and Display Port clock seems to match with the schematics but, as far as they are not associated with any interface defined in the board.xml file, they are not actually used.
In conclusion, the contents of the part0_pins.xml for the Ultra96-V2 are not used at all by Vivado, so it could be left unchanged or just totally empty, e.g.:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<part_info part_name="xczu3eg-sbva484-1-e">
<pins>
</pins>
</part_info>
NOTE: After some research, it looks like the file is taken and then modified from an old revision of the ZCU111 RFSoC (MPSoC with RF), with a nearly perfect match of the locations.
Preset File
The preset.xml file contains configuration parameters for the Ultra96-V2 board that will be applied by Vivado to the IP blocks while applying the presets for this board.
If we review them, we will find that they include a lot of information about components that are not defined in the board.xml, so this is information that makes not sense. Following the clues from the Pin file analysis, it looks like most of them are coming from the original board that Avnet took as reference (ZCU111).
As an example, we have the presets for a memory attached to the Programmable Logic, i.e. MT40A512M16HA-075E, but we saw that this doesn't exist in the Ultra96-V2.
The only presets that apply to the Ultra96-V2 are those in the zynq_ultra_ps_e_preset entry, but there is a critical problem with them as it produces different outcomes depending on your Linux distribution, e.g.:
- If you use Vivado in Ubuntu 16.04.6, the design works.
- If you use Vivado in Ubuntu 18.04.4, the design doesn't work.
By comparing the files generated by Vivado in different Ubuntu releases, we found the following differences related to the Low Power DDR4 configuration:
--- ubuntu-18.04.4/ultra96v2_standalone/design_1.hwh 2020-06-10 10:19:00.000000000 +0200
+++ ubuntu-16.04.6/ultra96v2_standalone/design_1.hwh 2020-06-04 18:23:24.000000000 +0200
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
-<EDKSYSTEM EDWVERSION="1.2" TIMESTAMP="Wed Jun 10 10:10:51 2020" VIVADOVERSION="2019.2">
+<EDKSYSTEM EDWVERSION="1.2" TIMESTAMP="Thu Jun 4 17:54:24 2020" VIVADOVERSION="2019.2">
<SYSTEMINFO ARCH="zynquplus" BOARD="em.avnet.com:ultra96v2:part0:1.0" DEVICE="xczu3eg" NAME="design_1" PACKAGE="sbva484" SPEEDGRADE="-1"/>
@@ -470,7 +470,7 @@
<PARAMETER NAME="PSU__DDRC__DDR3_T_REF_RANGE" VALUE="NA"/>
<PARAMETER NAME="PSU__DDRC__DDR3L_T_REF_RANGE" VALUE="NA"/>
<PARAMETER NAME="PSU__DDRC__LPDDR3_T_REF_RANGE" VALUE="NA"/>
- <PARAMETER NAME="PSU__DDRC__LPDDR4_T_REF_RANGE" VALUE="NA"/>
+ <PARAMETER NAME="PSU__DDRC__LPDDR4_T_REF_RANGE" VALUE="Normal (0-85)"/>
<PARAMETER NAME="PSU__DDRC__PHY_DBI_MODE" VALUE="0"/>
<PARAMETER NAME="PSU__DDRC__DM_DBI" VALUE="DM_NO_DBI"/>
<PARAMETER NAME="PSU__DDRC__COMPONENTS" VALUE="Components"/>
@@ -484,7 +484,7 @@
<PARAMETER NAME="PSU__DDRC__DDR4_ADDR_MAPPING" VALUE="NA"/>
<PARAMETER NAME="PSU__DDRC__SELF_REF_ABORT" VALUE="NA"/>
<PARAMETER NAME="PSU__DDRC__DERATE_INT_D" VALUE="<Select>"/>
- <PARAMETER NAME="PSU__DDRC__ADDR_MIRROR" VALUE="0"/>
+ <PARAMETER NAME="PSU__DDRC__ADDR_MIRROR" VALUE="1"/>
<PARAMETER NAME="PSU__DDRC__EN_2ND_CLK" VALUE="0"/>
<PARAMETER NAME="PSU__DDRC__LPDDR3_DUALRANK_SDP" VALUE="0"/>
<PARAMETER NAME="PSU__DDRC__PER_BANK_REFRESH" VALUE="0"/>
--- ubuntu-18.04.4/ultra96v2_standalone/psu_init.c 2020-06-10 10:19:00.000000000 +0200
+++ ubuntu-16.04.6/ultra96v2_standalone/psu_init.c 2020-06-04 18:23:24.000000000 +0200
@@ -5492,7 +5492,7 @@
* Register : PGCR0 @ 0XFD080010
* Address Copy
- * PSU_DDR_PHY_PGCR0_ADCP 0x0
+ * PSU_DDR_PHY_PGCR0_ADCP 0x1
* Reserved. Returns zeroes on reads.
* PSU_DDR_PHY_PGCR0_RESERVED_30_27 0x0
@@ -5522,9 +5522,9 @@
* PSU_DDR_PHY_PGCR0_RESERVED_7_0 0x0
* PHY General Configuration Register 0
- * (OFFSET, MASK, VALUE) (0XFD080010, 0xFFFFFFFFU ,0x07001E00U)
+ * (OFFSET, MASK, VALUE) (0XFD080010, 0xFFFFFFFFU ,0x87001E00U)
*/
- PSU_Mask_Write(DDR_PHY_PGCR0_OFFSET, 0xFFFFFFFFU, 0x07001E00U);
+ PSU_Mask_Write(DDR_PHY_PGCR0_OFFSET, 0xFFFFFFFFU, 0x87001E00U);
/*##################################################################### */
/*
If we review the preset.xml file, we will find that these values are undefined for Ultra96-V2:
- PSU__DDRC__LPDDR4_T_REF_RANGE
- PSU__DDRC__ADDR_MIRROR
The supported values for Zynq UltraScale+ Processing System presets can be found in Table C-1 on Programming Guide 201.
Parameter | Range | Default |
---|---|---|
PSU__DDRC__LPDDR4_T_REF_RANGE | Normal (0-85), High (95 Max) | NA |
PSU__DDRC__ADDR_MIRROR | 0, NA, 1 | NA |
In both the commercial and industrial versions of Ultra96-V2 is used an industrial grade LPDDR4 memory from Micron:
- MT53D512M32D2DS-053 AIT:D
Regarding the temperature range, this memory operates from -40°C to 85°C. The NA value in Ubuntu 18.04.4 doesn't look a critical issue, but we can assign the Normal range to PSU__DDRC__LPDDR4_T_REF_RANGE
About address mirroring, we have empirically verified this must be enabled to work, so PSU__DDRC__ADDR_MIRROR must be set to 1 in the preset.xml file. What's more, after reviewing the Vivado source code, we have identified that this parameter is associated with the C_DDRC_ADDRESS_COPY and that the psu_init.c file gets automatically fixed too:
jgarcia@titan:~$ find /tools/Xilinx/Vivado/2019.2/data/PS/ -type f | xargs grep C_DDRC_ADDRESS_COPY
/tools/Xilinx/Vivado/2019.2/data/PS/8series/data/zynqconfig/code/sdkgen.xml: <PARAMETER NAME="C_DDRC_ADDRESS_COPY" VALUE="0" PARAM="PSU__DDRC__ADDR_MIRROR" CHANGED_BY="USER" />
So, at least and ignoring further cleaning of unused stuff, we must add the following DDR configuration parameters to the preset.xml file to fix the behavior and don't let Vivado select the value, as it may change depending on the libraries used by the Operating System we are using:
diff --git a/ultra96v2/1.0/preset.xml b/ultra96v2/1.0/preset.xml
index 0531e56..ececc50 100644
--- a/ultra96v2/1.0/preset.xml
+++ b/ultra96v2/1.0/preset.xml
@@ -177,6 +177,8 @@
<user_parameter name="CONFIG.PSU__DDRC__DM_DBI" value="DM_NO_DBI"/>
<user_parameter name="CONFIG.PSU__DDRC__PER_BANK_REFRESH" value="0"/>
<user_parameter name="CONFIG.PSU__DDRC__STATIC_RD_MODE" value="0"/>
+ <user_parameter name="CONFIG.PSU__DDRC__LPDDR4_T_REF_RANGE" value="Normal (0-85)"/>
+ <user_parameter name="CONFIG.PSU__DDRC__ADDR_MIRROR" value="1"/>
<user_parameter name="CONFIG.PSU__SWDT0__PERIPHERAL__ENABLE" value="1"/>
<user_parameter name="CONFIG.PSU__SWDT1__PERIPHERAL__ENABLE" value="1"/>
In order to fix the DDR configuration in the preset file for Ultra96-V2, download and apply the ultra96v2_bdf_ddrc.patch or replace with the already patched preset.xml file.