Passing a signal into RFADC, reading out from RFDAC

Working on the ZCU208 evaluation board.

As the first step of what promises to be a very complicated build, I’m trying to feed analog signals in through one ADC channel, and regenerate the same signals output from the DAC. My block design looks like this:

My reasoning is as follows:
The RFDC M00_AXIS (the ADC) goes into an AXI4 Stream data FIFO, which then, through an AXI_DMA core is sent into a BRAM controller. The ZYNQ PS controls the DMA over an AXI_LITE connection, and is then able to tell the DMA to read from the BRAM and send the data to another AXI4 Stream data FIFO which feeds the S00_AXIS port on the RFDC, which is the DAC channel.

When I load the overlay into a jupyter lab environment, however, the RFDC core shows up as a DefaultIP thing with only MMIO access – no access to the ADC or DAC data. I tried moving on, and seeing if the AXI interfaces were chugging along normally, and if I could simply pull the data out through the DMA with

import pynq.lib.dma
import numpy as np
from pynq import allocate

dma_recv = dma.recvchannel
dma_send = dma.sendchannel

data_in = pynq.allocate(shape(2048,))

But the data_in buffer never takes in any new values.

Is there a tutorial I’ve missed where something like this has been covered? It’s quite a bit more complicated than the simple GPIO new design tutorial here, but the other tutorials don’t show how to work with the more complicated IP cores that Xilinx offers.

Further trying – I’ve simplified the block design so that the one active ADC tile feeds a Stream FIFO with independent clocks, which then directly feeds the one active DAC tile. Trying to access the registers of the RFDC tile gives me some problems…

Trying to read from this register space (which is R/W according to the Xilinx docs) crashes the Jupyter server; I have to manually power cycle the board to restart it.

Going to try going still simpler. Just the MPSoC IP connected to the RFDC IP with no further block design faffing.

Hi @redson

Can you import the xrfdc package before calling the Overlay initialisation method? This operation will be similar to the code cell below:

from pynq import Overlay
import xrfdc

ft = Overlay('/home/xilinx/jupyter_notebooks/faff/inout_feedthrough/ft.bit')

Then, you will be able to access the registers of the RFDC core.

You will also need to use the xrfclk package to initialise the LMK and LMX clocks.

Lastly, I’m unsure if the asynchronous clocked FIFOs will have the effect you want. You can check out one of the RFSoC systems from my group here to see how we configure our block designs. In particular, we use the output of the PLL clock from the RFDC IP Core to drive the radio pipeline.


Hi David, thanks for the reply.

Trying to build the vivado project in Windows was a bit tricky. Just ran through the tcl files manually in the Vivado IDE, but building the final rfsoc_radio.tcl file doesn’t work on 2022.2, so I just went into the .tcl file and manually changed some things.

set scripts_vivado_version 2020.2set scripts_vivado_version 2022.2
All instances of usp_rf_data_converter:2.4 updated to :2.6.
All instances of zynq_ultra_ps_e:3.3 updated to 3.4.

The build script worked and did all the routing just fine after that.

Hi @redson

No problem, and it sounds like you got things working. The RFSoC-Radio example is built using Vivado 2020.2, so that is why you ran into some problems.


Yep all good, thanks. I’m looking at the receiver/transmitter and Data Inspector IPs and I was wondering if there was anywhere I could see the Simulink designs for these. Otherwise I’d have to write my own versions in VHDL and that would take a while to figure out how to do.

Yeah, these are available! The Simulink/System Generator designs are here.



Excellent! Thanks :slight_smile: