gr-ofdmradar - OFDM Radar on MxFE Platforms

This documentation covers building an OFDM radar system on a ZCU102 + AD9081 using GNU Radio and IIO.

Software/Hardware quickstart

Required hardware

Required software

  • Vivado 2020.2+ (with Vitis SDK)

  • MPSoC license (included with eval kit)

  • Recent software build toolchain

Preparing ZCU102 boot files

Installing Kuiper Linux

Recommended starting point: recent Kuiper Linux image on SD card.

Linux Kernel Build

git clone https://github.com/analogdevicesinc/linux.git
cd linux

export PATH=$PATH:/opt/Xilinx/Vitis/2020.2/gnu/aarch64/lin/aarch64-linux/bin/
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-

make adi_zynqmp_defconfig
make -j$(nproc) Image UIMAGE_LOADADDR=0x8000
cp arch/arm64/boot/Image /mnt/boot/

Device Tree Blob Build

make xilinx/zynqmp-zcu102-rev10-ad9081-m8-l4-tdd.dtb
cp arch/arm64/boot/dts/xilinx/zynqmp-zcu102-rev10-ad9081-m8-l4-tdd.dtb /mnt/boot/system.dtb

Note

Device tree blob MUST be renamed to system.dtb.

Building the HDL

source /opt/Xilinx/Vivado/2020.2/settings64.sh
git clone https://github.com/Yamakaja/hdl.git
git switch data_offload

cd projects/ad9081/ad9081_fmca_ebz/zcu102/
make TDD_SUPPORT=1 SHARED_DEVCLK=1

Build duration is typically 15-30 minutes.

Output: projects/ad9081_fmca_ebz/zcu102/ad9081_fmca_ebz_zcu102.sdk/system_top.xsa

See Build ZynqMP / MPSoC Linux kernel and devicetree for creating BOOT.BIN.

Building GNU Radio

Repository: Yamakaja/gnuradio feature/gr-iio-tdd branch.

git clone https://github.com/Yamakaja/gnuradio.git
git switch feature/gr-iio-tdd

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)
sudo make -C build install

LD_LIBRARY_PATH=/usr/local/lib /usr/local/bin/gnuradio-companion

Building gr-ofdmradar

git clone https://github.com/analogdevicesinc/gr-ofdmradar.git
cd gr-ofdmradar

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

LD_LIBRARY_PATH=/usr/local/lib /usr/local/bin/gnuradio-companion

Testing the OFDM Radar

Simulation testing

Launch ofdmradar_test example from gr-ofdmradar examples directory. This simulates four radar targets.

https://media.githubusercontent.com/media/analogdevicesinc/system-level/main/docs/solutions/reference-designs/eval-ad9081/images/radar_ofdmradar-simulation-flowgraph.png

Figure 1 OFDM radar simulation flowgraph

https://media.githubusercontent.com/media/analogdevicesinc/system-level/main/docs/solutions/reference-designs/eval-ad9081/images/radar_ofdmradar-simulation-screen.png

Figure 2 Radar display with four target echoes

Hardware testing (ZCU102/AD9081)

Open ofdmradar_ad9081.grc flowgraph in gr-ofdmradar examples. Set iio_target variable to ZCU102 IP address.

Warning

Default configuration may violate local RF regulations; verify band allocation and power limits.

https://media.githubusercontent.com/media/analogdevicesinc/system-level/main/docs/solutions/reference-designs/eval-ad9081/images/radar_ofdmradar-ad9081-flowgraph.png

Figure 3 AD9081 OFDM radar flowgraph

Test result: Successful detection at approximately 35-meter range.

Useful resources

Using the OFDM Radar

System parameters

https://media.githubusercontent.com/media/analogdevicesinc/system-level/main/docs/solutions/reference-designs/eval-ad9081/images/radar_gr_ofdmradar_sysparams.png

Figure 4 OFDM radar system parameters

Example parameters:

  • Complex system sample rate: f_s = 250 MS/s

  • FFT Size: N = 4096

  • Frame symbols: M = 16

  • Cyclic prefix length: N_CP = 256

  • Nyquist guard carriers: N_NG = 64

Derived calculations:

  • Total TX frame length: L = (N+N_CP)*M = 69,632 samples

  • Frame duration: T = L / f_s = 279 microseconds

  • Time domain resolution (non-oversampled): Approximately 60 centimeters

  • Doppler resolution (non-oversampled): f_s / ((N+N_CP)*M) = 3,590 Hz

  • True system bandwidth: B = (N - 2*N_NG)/N * f_s = 242.2 MHz

  • Processing gain: G = 10 * log10(N * M) ≈ 48 dB

  • Maximum unambiguous distance: d = N_CP*c / (4*f_s) ≈ 77 meters

Flowgraph parameters

https://media.githubusercontent.com/media/analogdevicesinc/system-level/main/docs/solutions/reference-designs/eval-ad9081/images/radar_gr_ofdmradar_sysparams_annotated.png

Figure 5 Annotated system parameters

buffer_size

Specifies samples the receiver accepts per frame. Should equal or exceed frame length L. Controls IIO buffer alignment.

amplitude

Controls transmit power via pre-multiplication. Due to processing gain, required transmit power may be low.

t_0

TDD engine offset between transmission start and recording start. Requires calibration for accurate range determination.

display_mult

Post-processing scaling for return signal intensity visualization. Does NOT affect receiver sensitivity.

Visualization parameters

https://media.githubusercontent.com/media/analogdevicesinc/system-level/main/docs/solutions/reference-designs/eval-ad9081/images/radar_gr_ofdmradar_screen.png

Figure 6 Radar visualization screen

Range Slider

Controls displayed range; functions as inverted zoom (left movement = zoomed range view).

Doppler Range Slider

Reduces displayed doppler ranges similarly.

min/max Value Sliders

Map energy values to visualization using mapping function:

mapv(x) = (x - minV) / (maxV - minV)
return max(min(x, 1.0), 0.0)

Processing pipeline:

  1. Calculate energy from complex 2D matrix (range × doppler)

  2. Apply mapping function with min/max scaling

  3. Pass through turbo colormap

  4. Display on screen

See screen fragment shader code.

System deep dive

Overview

This section covers system architecture from transceiver through signal processing:

  • Transceiver/RF ADC/DAC (AD9081)

  • Hardware/HDL implementation

  • Linux drivers

  • gr-ofdmradar signal processing blocks

ZCU102/AD9081 platform

The AD9081 is a 4-channel RF DAC/ADC in single package.

Key features:

  • Multi-chip synchronization support

  • JESD 204B/C data interface

  • 8+8 SERDES lanes (RX+TX)

Note

ZCU102 transceivers maximum speed is ~15 Gbps, so only JESD 204B operation is available (not 204C).

Problem statement

Pulse Radar Time-of-Flight Challenge

https://media.githubusercontent.com/media/analogdevicesinc/system-level/main/docs/solutions/reference-designs/eval-ad9081/images/radar_pulse_radar.png

Figure 7 Pulse radar concept

Monostatic radar requires known, fixed timing relationship between transmit and receive to calculate distance via time-of-flight measurement.

Data Rate Bottleneck

Default ZCU102/AD9081 configuration:

  • Active channels: 4 RX + 4 TX @ 250 MS/s

  • Sample format: 32-bit complex (16+16 bit)

  • Data rate per direction: 4 × 250e6 MS/s × 32 bit/sample = 32 Gbps

https://media.githubusercontent.com/media/analogdevicesinc/system-level/main/docs/solutions/reference-designs/eval-ad9081/images/radar_system_link_rates.png

Figure 8 System link rate limitations

System link limitations:

  • Memory links: Can handle rates

  • FPGA: Can handle rates

  • Processing system: Cannot handle rates

  • Gigabit Ethernet: Cannot handle rates

IIO Buffer Guarantees

Provided:

  • Samples within single buffer play as continuous stream

  • Buffers maintain order (no reordering)

Problem: Without modifications, RX/TX timing relationship is random.

https://media.githubusercontent.com/media/analogdevicesinc/system-level/main/docs/solutions/reference-designs/eval-ad9081/images/radar_iio_buffers_unaligned.png

Figure 9 IIO buffers unaligned state

Default scenario: RX and TX buffers sample independently with unpredictable spacing.

Solution: Time Division Duplexing with Data Offload

Hardware-controlled windowing of transmit/receive signals at predetermined times (oscilloscope-like triggering).

Result:

  • Reduced data rates in controlled manner

  • Known timing relationships between RX/TX

https://media.githubusercontent.com/media/analogdevicesinc/system-level/main/docs/solutions/reference-designs/eval-ad9081/images/radar_iio_buffers_aligned.png

Figure 10 IIO buffers aligned state

The HDL

HDL changes are in a development branch: Yamakaja/hdl data_offload branch.

TDD (Time Division Duplexing) Core

Originally developed for AD9361 transceiver family. See AXI TDD.

The AXI_TDD wrapper exposes TDD IP core as standalone module. All channels function independently.

Data Offload Engine

Acts as glorified FIFO triggered by TDD engine for sampling data streams.

Key features:

  • Multiple configuration options

  • Synchronization modes for waiting state

  • Triggered operation (register write or external signal)

See Data Offload README.

Integration Architecture

https://media.githubusercontent.com/media/analogdevicesinc/system-level/main/docs/solutions/reference-designs/eval-ad9081/images/radar_ad9081_zcu102_bd_tdd_do.png

Figure 11 AD9081 ZCU102 block diagram with TDD and data offload

Signal flow:

  • tdd_tx_valid → TX data offload external sync input

  • sync_ext signal triggers data offload

  • External sync signal relevance limited to initial waiting phase

  • Can transition LOW immediately after trigger

TX Data Path

Once triggered:

  1. Data offload fills internal buffer

  2. Buffer size must be integer multiple of IIO buffer size

  3. Buffer plays back to upack core

  4. Unpacker deinterleaves packed samples into parallel bus

  5. Output: 2×16 bit per complex channel @ 128-bit, 250 MHz

RX Data Path Complexity

Challenge: CPACK core packing format timing asynchrony with TDD sync signal.

Problem scenario:

  • Single active channel from four-channel configuration

  • CPACK output valid only once per four samples

  • CPACK position relative to sync arrival = apparent random shift (0-3 samples)

Current solution: Reset CPACK with every sync signal (not optimal but least invasive approach).

JESD Configuration Detail

../../../../_images/ad9081_204b_m8l4.svg

Figure 12 JESD204B M=8, L=4 datapath configuration

Datapath illustration with M=8, L=4 configuration. UTIL_DACFIFO and UTIL_ADCFIFO replaced by data offloads in actual implementation.

Linux drivers

Two primary drivers:

  1. Data Offload Driver

  2. TDD Driver

Data Offload Driver

Location: drivers/misc/adi-axi-data-offload.c

Primary functions:

  • Configure data offload registers from device tree values

  • Provide debugfs runtime register modification interface

Device tree configuration: adi,axi-data-offload.yaml

Integration with DDS driver at cf_axi_dds.c handles cyclic/oneshot operation via data offload.

Use case for repeated radar waveform transmission:

  • Data offload cyclic mode with synchronization enabled

  • Waits for sync signal before each iteration

  • Allows single buffer load with multiple replay iterations

TDD Driver

Location: drivers/iio/adc/cf_axi_tdd.c

Features:

  • Static configuration via device tree attributes

  • IIO device interface for runtime control

TDD Register Access example:

iio:device2: axi-core-tdd
4 channels found:
  data1 (output/input): 6 channel-specific attributes
    - dp_off_ms
    - dp_on_ms
    - off_ms
    - on_ms
    - vco_off_ms
    - vco_on_ms
  data0 (output/input): 6 channel-specific attributes
    - [Same attributes as data1]

10 device-specific attributes:
  - burst_count
  - counter_int
  - dma_gateing_mode (options: rx_tx, rx_only, tx_only, none)
  - en
  - en_mode (options: rx_tx, rx_only, tx_only)
  - frame_length_ms
  - secondary
  - sync_terminal_type
  - direct_reg_access (debug)

GNU Radio integration

Two component categories:

  1. Hardware Control Blocks (gr-iio in-tree)

    • AD9081 Source/Sink

    • TDD Engine Control

  2. Signal Processing Blocks (gr-ofdmradar)

    • Hardware-independent OFDM radar processing

    • Direction of arrival (DoA) blocks

gnuradio/gr-iio blocks

Operational Model: Bursty Data Assumption

Working with bursts where one burst = one IIO buffer.

Burst indication: Packet length tags marking buffer boundaries.

Tag format example:

[... x-2, x-1, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, ...]
        ^                                       ^
        |{packet_len: 10}              |{packet_len: 10}

Packet length tags are redundant for same-size IIO buffers but enable compatibility with variable-size streams.

AD9081 Sink Block: If packet length tag name populated, sink enforces correct tagging and aborts flowgraph on errors.

Common Block Attributes

Shared parameters:

  • IIO context URI

  • IIO buffer size

  • Packet length tag name

  • NCO attributes

Source-specific:

  • Nyquist Zone (Odd/Even)

  • Programmable hardware FIR filter file

Sink-specific:

  • Cyclic Mode

AD9081 Sink Block Configuration

https://media.githubusercontent.com/media/analogdevicesinc/system-level/main/docs/solutions/reference-designs/eval-ad9081/images/radar_gr_iio_ad9081_sink_general.png

Figure 13 AD9081 sink general settings

https://media.githubusercontent.com/media/analogdevicesinc/system-level/main/docs/solutions/reference-designs/eval-ad9081/images/radar_gr_iio_ad9081_sink_channels.png

Figure 14 AD9081 sink channel settings

https://media.githubusercontent.com/media/analogdevicesinc/system-level/main/docs/solutions/reference-designs/eval-ad9081/images/radar_gr_iio_ad9081_sink_coarse_duc.png

Figure 15 AD9081 sink coarse DUC settings

https://media.githubusercontent.com/media/analogdevicesinc/system-level/main/docs/solutions/reference-designs/eval-ad9081/images/radar_gr_iio_ad9081_sink_fine_duc.png

Figure 16 AD9081 sink fine DUC settings

AD9081 Source Block Configuration

https://media.githubusercontent.com/media/analogdevicesinc/system-level/main/docs/solutions/reference-designs/eval-ad9081/images/radar_gr_iio_ad9081_source_general.png

Figure 17 AD9081 source general settings

https://media.githubusercontent.com/media/analogdevicesinc/system-level/main/docs/solutions/reference-designs/eval-ad9081/images/radar_gr_iio_ad9081_source_coarse_ddc.png

Figure 18 AD9081 source coarse DDC settings

Frequency calculation uses gr.nyquist_fold() function to calculate NCO frequencies accounting for aliasing and spectral inversion.

TDD Control Block

Stream IO: None

Purpose: Convenient access to underlying IIO attributes.

https://media.githubusercontent.com/media/analogdevicesinc/system-level/main/docs/solutions/reference-designs/eval-ad9081/images/radar_gr_iio_tdd_general.png

Figure 19 TDD control general settings

https://media.githubusercontent.com/media/analogdevicesinc/system-level/main/docs/solutions/reference-designs/eval-ad9081/images/radar_gr_iio_tdd_primary_timing.png

Figure 20 TDD control primary timing settings

gr-ofdmradar signal processing blocks

Block categories:

  1. OFDM Radar blocks (TX, RX, GUI)

  2. Direction of Arrival (DoA) blocks

OFDM Radar System Parameters Block

https://media.githubusercontent.com/media/analogdevicesinc/system-level/main/docs/solutions/reference-designs/eval-ad9081/images/radar_gr_ofdmradar_params.png

Figure 21 OFDM radar parameters block

Purpose: Store shared system parameters for TX, RX, GUI blocks.

OFDM Radar Transmitter Block

https://media.githubusercontent.com/media/analogdevicesinc/system-level/main/docs/solutions/reference-designs/eval-ad9081/images/radar_gr_ofdmradar_tx.png

Figure 22 OFDM radar TX block

Inputs: System parameters, length tag key.

Output: Full OFDM radar frame, length-tagged for AD9081 sink compatibility.

OFDM Radar Receiver Block

https://media.githubusercontent.com/media/analogdevicesinc/system-level/main/docs/solutions/reference-designs/eval-ad9081/images/radar_gr_ofdmradar_rx.png

Figure 23 OFDM radar RX block

Inputs: System parameters, length tag key, buffer size.

buffer_size parameter:

  • Specifies expected samples per OFDM frame

  • Actual processing determined by OFDM parameters

  • Allows discarding additional samples for IIO buffer alignment

  • Discarded samples: buffer_size - radar_params.frame_length

OFDM Radar GUI Block

https://media.githubusercontent.com/media/analogdevicesinc/system-level/main/docs/solutions/reference-designs/eval-ad9081/images/radar_gr_ofdmradar_gui.png

Figure 24 OFDM radar GUI block

Inputs: OFDM radar parameters, GUI hint.

Purpose: Real-time radar display with range/doppler visualization.

Direction of Arrival (DoA) blocks

DoA Autocorrelator Block

https://media.githubusercontent.com/media/analogdevicesinc/system-level/main/docs/solutions/reference-designs/eval-ad9081/images/radar_gr_ofdmradar_doa_corr.png

Figure 25 DoA autocorrelator block

Purpose: Compute correlation matrices from multi-channel receiver data.

DoA Calibration Block

https://media.githubusercontent.com/media/analogdevicesinc/system-level/main/docs/solutions/reference-designs/eval-ad9081/images/radar_gr_ofdmradar_doa_cal.png

Figure 26 DoA calibration block

Purpose: Calibrate antenna array responses.

DoA MUSIC Estimator Block

https://media.githubusercontent.com/media/analogdevicesinc/system-level/main/docs/solutions/reference-designs/eval-ad9081/images/radar_gr_ofdmradar_doa_music.png

Figure 27 DoA MUSIC estimator block

Algorithm: MUSIC (Multiple Signal Classification) for direction estimation.

DoA ESPRIT Estimator Block

https://media.githubusercontent.com/media/analogdevicesinc/system-level/main/docs/solutions/reference-designs/eval-ad9081/images/radar_gr_ofdmradar_doa_esprit.png

Figure 28 DoA ESPRIT estimator block

Algorithm: ESPRIT (Estimation of Signal Parameters via Rotational Invariance Techniques).

DoA Block Assumptions

Implicit assumptions:

  • Linear antenna array topology

  • Lambda/2 carrier wavelength spacing

Primary parameters:

  • Number of expected targets

  • Number of receiver channels