This is an old revision of the document!
This page is dedicated to the details of building an OFDM radar on a ZCU102 + AD9081 with GNURadio and IIO.
If you just want to get the software and hardware running, the following section covers the setup instructions:
To get started, in terms of hardware you will need:
Required software:
It is usually a good idea to start out by installing a recent image of Kuiper Linux onto the ZCU102's SD card, so you don't have to rebuild the rootfs.
Depending on the age of your release, you may need to build a more recent kernel:
# First clone the repository git clone https://github.com/analogdevicesinc/linux.git cd linux # First we need to make the Vitis arm64 gcc toolchain available and enable cross compilation export PATH=$PATH:/opt/Xilinx/Vitis/2020.2/gnu/aarch64/lin/aarch64-linux/bin/ export ARCH=arm64 export CROSS_COMPILE=aarch64-linux-gnu- # Then we can initialize the .config to something that enables most ADI drivers make adi_zynqmp_defconfig # And finally build our image make -j$(nproc) Image UIMAGE_LOADADDR=0x8000 # Finally you can copy arch/arm64/boot/Image into the boot directory of the ZCU102 sdcard: cp arch/arm64/boot/Image /mnt/sdcard/boot/
If you're having trouble building the Linux image, there are more detailed articles describing the process (WHERE!).
Finally you will have to build the correct device tree blob:
# Build the device tree blob make xilinx/zynqmp-zcu102-rev10-ad9081-m8-l4-tdd.dtb # Copy to ZCU102 boot directory cp arch/arm64/boot/dts/xilinx/zynqmp-zcu102-rev10-ad9081-m8-l4-tdd.dtb /mnt/sdcard/boot/system.dtb
# Source your Vivado 2020.2 (or later, depends on the adi/hdl release) settings source /opt/Xilinx/Vivado/2020.2/settings64.sh # Clone the HDL git clone https://github.com/Yamakaja/hdl.git git switch data_offload # Navigate to the ad9081 / ZCU102 project cd projects/ad9081/ad9081_fmca_ebz/zcu102/ # Build the project with TDD support. Note that enabling TDD support is only possible if you also enable shared device clocks, which means that your IO rates will be symmetrical. make TDD_SUPPORT=1 SHARED_DEVCLK=1
The HDL build should take around 15 - 30 mins, and leave you with a projects/ad9081_fmca_ebz/zcu102/ad9081_fmca_ebz_zcu102.sdk/system_top.xsa when its done.
This guide describes how you can use the system_top.xsa to build the BOOT.BIN, which also needs to be copied into the sdcard's boot directory: build-the-zynqmp-boot-image
Once you've got an updated linux Image, BOOT.BIN and system.dtb installed and the AD9081 eval board mounted on the ZCU102, you can start to hook up a receive and transmit antenna / or other RF components.
To use the gr-iio AD9081 and TDD blocks, you will have to build this GNU Radio fork/branch, which is fairly close to master: Yamakaja/GNURadio
# Checkout code git clone https://github.com/Yamakaja/gnuradio.git git switch feature/gr-iio-tdd # Note, you should adjust the cmake build command according to your local environment! This one was created to work with my environment mkdir -p build cmake -DCMAKE_INSTALL_PREFIX=/usr/local \ -DPYTHON_EXECUTABLE=$(which python3) \ -DPYTHON_INCLUDE_DIR=/usr/include/python3.9 \ -DPYTHON_LIBRARY=/usr/lib/libpython3.9.so \ -DGR_PYTHON_DIR=/usr/lib/python3.9/site-packages \ -DENABLE_GRC=ON \ -DENABLE_GR_QTGUI=ON \ -DQWT_LIBRARIES=/usr/lib/libqwt.so \ -DCMAKE_BUILD_TYPE=Debug \ -B build \ -S . make -C build -j$(nproc) # Install GNU Radio into system directories sudo make -C build install # Make sure the installation was successful by opening gnuradio-companion LD_LIBRARY_PATH=/usr/local/lib /usr/local/bin/gnuradio-companion
On account of being a GNU Radio module, the process to build gr-ofdmradar is quite similar:
# Checkout code git clone https://github.com/Yamakaja/gr-ofdmradar.git cd gr-ofdmradar # Make sure this build command matches that of your GNU Radio installation! mkdir -p build cmake -DCMAKE_INSTALL_PREFIX=/usr/local \ -DPYTHON_EXECUTABLE=$(which python3) \ -DPYTHON_INCLUDE_DIR=/usr/include/python3.9 \ -DPYTHON_LIBRARY=/usr/lib/libpython3.9.so \ -DGR_PYTHON_DIR=/usr/lib/python3.9/site-packages \ -DCMAKE_BUILD_TYPE=Debug \ -B build \ -S . make -C build sudo make -C build install
When you now start GNU Radio companion once again, the gr-ofdmradar blocks should show up in the block-list:
LD_LIBRARY_PATH=/usr/local/lib /usr/local/bin/gnuradio-companion
To validate that the ofdm radar module has been installed properly, you can launch the ofdmradar_test example in the examples directory of gr-ofdmradar:
Running the flowgraph should leave you with a radar screen simulating four targets:
To test the OFDM radar with real hardware and signals, open the ofdmradar_ad9081.grc flowgraph in the gr-ofdmradar example directory.
iio_target
variable must point to the IP address of your ZCU102 target!
The following video shows a test where we covered a distance of 30-40m:
For more details in general about the theoretical underpinnings of OFDM radar, please check out Martin Brauns dissertation: https://publikationen.bibliothek.kit.edu/1000038892
For more information about gr-ofdmradar system parameters check out the gr-ofdmradar/README.md
The system deep dive is meant to cover the details of the entire radar system from top to bottom. Unless you're trying to recreate a similar system from scratch or trying to debug an issue, this section may not be too interesting.
Subsystems which will be covered:
Before getting started with the implementation details, we need to establish the problem: To be able to implement a reliable and accurate radar system, our interfaces must provide certain guarantees. Take a look at this picture illustrating an ordinary pulse radar:
In this monostatic setup, the transmitter produces a small pulse, and then listens for the return signal. To determine the distance to the target, the time of flight is calculated by taking the time at which the signal returned, and subtracting that from the transmit time. More information like the doppler shift, RCS estimation, etc. can be estimated later on in the signal chain, but these aren't relevant right now. In this situation only the time of flight is actually relevant to us, not the absolute time at which the signal was received. To determine the time of flight, we need to rely on a known, fixed timing relationship between the signal was sent out, and our input samples at the receiver. There exist a number of solutions to this problem, for example a strongly attenuated version of the TX signal could be looped back to the receiver. In systems where the full data stream is available, and reliably so, this may be an adequate solution, but the iio link does not lend itself to such an approach.
The AD9081 is a 4-channel RF DAC/ADC in a single package, with multi-chip synchronization and various other interesting capabilities. Data is transferred from the DAC to the ADC over up to 8+8 (RX+TX) SERDES lanes running JESD 204 B/C. Unfortunately the transceivers of the ZU9EG on the ZCU102 only go up to ~15 Gbps, as such only JESD 204B operation is available with this hardware configuration.
As of writing this document, not all HDL changes have made it into the upstream repository yet, thus you may either use my development branch, or make sure that the most recent commits from that branch have made it into master (Though at that point this paragraph should be updated): https://github.com/Yamakaja/hdl/tree/data_offload