In the last RF Data Converter blog we took a look at the Software Driver and how it could be used to manage the status and control for the RF Data Converter IP.
We covered how writing a simple standalone application could be used to help debug the RF-ADC and RF-DAC behavior in your system.
During that blog I mentioned that Xilinx has enabled RF Data Converter Debug on any device on any board using a tool called RF Analyzer. I am going to use the next two blog posts to unbox this utility, take a look at its main features, and see how we can use it to manage the RF-ADC and RF-DAC Tiles. I will also cover how you can use it to generate RF-DAC Stimulus, and view and analyze RF-ADC received data.
To download the RF Analyzer GUI please go to the RFSoC Resources page
Be sure to check out the User Guide (UG1309) for help with using the Analyzer GUI.
Also, please refer to (Xilinx Answer 71746) to understand some of the limitations in the 2018.3.1 version of the tool. The 2019.1 version will bring some enhancements, so stay tuned.
This two part blog is dedicated to RF Analyzer, and in part one we are now going to look at some of the building blocks of the tool. I would consider there to be three main strands that make up the RF Analyzer.
First there is the PL design, which is made up of the example design from the Zynq® UltraScale+® RF Data Converter IP, a MicroBlaze™ to enable status and control of the RF subsystem, and the JTAG to AXI Master IP for the data path to and from the GUI. There is also some clock generation included in this design.
The biggest advantage to this is that you have an IP configuration that matches your design. This means that you have now decoupled the RF Data Converter from the rest of your design. This allows you to examine the data converter performance in your system independent of the rest of the design, capture RX data, and analyse the data in the RF Analyzer GUI.
It should be understood that the cost of this self-contained flexible design is that there is no way to manage DDR Memory (because we want to boot on any device / any board) so storage for playback/capture is built using the on-chip Block RAM. For ease-of-use we also provide pre-built bitstreams for each available device with the RF Analyzer package.
After the PL bitstream, we have a MicroBlaze application. This Application manages the Control Path in the PL design. At a high level it receives commands from the RF Analyzer GUI, parses them, and uses the driver API to read back what was requested from the tiles, or even modify the Tile Settings. This is provided as an ELF file with the RF Analyzer design.
At the top level there is a Labview GUI that allows you to interface with the RF-ADC and RF-DAC tiles for Data capture and Stimulus Generation / Playback. This GUI follows the same style as the ZCU111 RFSoC Evaluation GUI.
The diagram below shows a representation of the complete RF Analyzer.
Now that we have a high level understanding of RF Analyzer, let’s go a bit deeper. The best thing to do is to start with a custom IP configuration and run through all of the steps needed to use it in the RF Analyzer environment.
We are going to use the ZCU1275 Characterization Board in this case. It has a 16x16 ZU29DR device. We will actually need to know very little about this board. We just need to be sure of the following:
The converter clocking is set up
The Bullseye connectors are properly connected in the setup to match our particular IP configuration
The RF Analyzer will manage the rest. We will come back to this later on in the process.
The first step is to set up the IP. This is the base on which we will build the RF Analyzer PL design. You can either select it from the IP catalog or it can be in a block design in IP Integrator.
So I think it makes sense to show a RF-ADC and RF-DAC configurations where we check out some CW (Continuous Wave) Tones.
Then we will set up two tiles to enable a loopback where we can transmit an up-converted QAM16 vector from the RF-DAC and receive it with the RF-ADC.
In this case we will run the RF-ADC with a sample rate of 1966.08Mhz and the RF-DAC with a sample rate of 3932.16MHz.
You end up with an IP similar to the one shown here. Two DAC tiles are active and 2 ADC tiles are used.
You can now click OK and decide to skip the out-of-context Synthesis of the IP.
We must tell the tools that when we create the example design, we intend to enable the RF Analyzer. To do this you will need to enter the following command in the Vivado Tcl Console.
Next, right-click on the IP and select “Open Example Design”. Here you will get a new project with the example design and the Analyzer infrastructure included.
At the top level of this design we make use of the STARTUPE3 block to provide the AXI4 Lite clock and external reset to the design. You will see this instantiated inside the top level RTL wrapper for the design.
Once the bitstream is loaded, the EOS (End of Startup) signal is asserted in the PL fabric. This will manage the reset, and start the design and application running.
As noted earlier, the design contains a MicroBlaze.
This will manage the status and control for the RF Data Converters and clocking. If you right click here you will see that there is an ELF file associated with it.
This will embed the application that manages the communication between the design and Analyzer GUI in the bitstream.
You will also see the JTAG to AXI master in this block design. This will manage the datapath to the Source and Sink IP respectively.
We make use of the AXI SmartConnect to manage the interface between the MicroBlaze/JTAG2AXI Master and the rest of the design.
You can see that there is a connection to the IP example design AXI4Lite interface:
There is also a clocking block. This takes the tile output clocks and uses an MMCM to drive the AXI Stream Clocks to the tiles. Each MMCM has its AXI DRP port enabled. This gives us flexibility to manage a change in the data converter clocking, and by extension the AXI stream clocks at run-time.
Now let's drill down into the level of hierarchy containing the IP example design.
We can see that it contains the RF Data Converter IP, as we configured it in our main project, and a DAC Source and ADC Sink. These Blocks are RTL and you can examine them in more detail if you right click and select “Go to Source”
The RF-DAC data stimulus block consists of a 128 kbits block RAM that can be loaded with samples which are then sent to the enabled RF-DAC channels in the RF Data Converter core.
Really the DAC source is just an XPM that builds a BRAM that either gets written with a new stimulus or it streams its contents to the DAC.
Each channel in the stimulus block drives an AXI4-Stream on the Zynq® UltraScale+® RF Data Converter IP core. As each converter can have up to four AXI4-Stream interfaces, there are a maximum of 16 channels in the DAC source block. Each enabled AXI4-Stream interface is mapped into consecutive channels starting with DAC0.
The Register map for the DAC Stimulus block is contained in table 56 in (PG269). Likewise the ADC stream data can be captured in the Sink block and read back.
The data from each enabled AXI4-Stream output on the Zynq® UltraScale+® RF Data Converter is stored in a separate channel in the data capture block. As each converter can have up to four AXI4-Stream interfaces, there are a maximum of 16 channels present in the data capture block.
The enabled AXI4-Stream interfaces are mapped into consecutive channels starting with ADC0.
The storage in each channel consists of 128 kbits of block RAM. The address map for the capture block can be found in table 55 of (PG269)
Before we implement this and generate the bitstream, you can take a look at the constraints we have for the design in the following file:
These constraints create the primary clocks and add some PBlocks to floorplan the design so that the stimulus and capture memories are adjacent to the Data Converter Tiles.
There are some timing exceptions added to manage static control signals that cross clock domains between the axi_aclk domain and the AXI Stream Clock domains.
For example, num_samples_reg is telling the data stimulus and capture blocks in the example design how many samples to either get from RF-ADC or send to the RF-DAC tile. This is on the control path, so it is synchronous to the axi_aclk. This setting is then used by the address counter logic in the Stimulus and Capture blocks which run on the AXI Stream Clock. The signal should not change very often, if at all, so it is safe to ignore it as a timing path during implementation.
You can run the design all the way to write_bitstream at this stage.
You will now see that the timing is met. Note the Pblocks, which are used to lock the Capture and Stimulus Memory adjacent to the relevant tiles.
The bitstream will be along a path similar to the following: