Using the XADC on the Zybo board

On the newer 7-series FPGAs from Xilinx you now find an built in ADC, called XADC. This is also the case for the Zynq devices as it is based on the 7-series FPGAs. In this guide I will go through how to get the XADC working on the Zybo board utilizing an Xilinx Zynq-7000 SoC. The guide will be using Vivado from Xilinx.

The ADC on the Zynq-7000 is a dual 12 bitADC with 1 Mega sample pr second. Through and internal routing matrix, the ADC can access up to 17 external analog inputs as well as a number of internal signals such as die-temperature, voltage-levels. One word of caution; you should never supply more than 1V to the ADC on the Zynq-7000 on the Zybo board.


XADC block diagram from Xilinx UG480 datasheet

Communicate with the XADC

On the Zynq-7000 you have three options to connect  to the XADC. Those are the following:

  • Direct connection to PS through JTAG
    • minimal AXI/PL impact
    • slow due to the JTAG speed
    • Mostly useful for measuring slow signals such as temperature
  • As an AXI peripheral to the PS
    • function as a standard AXI peripheral and needs the PS running
    • gives the best performance for a processor based system
  • As a IP core in pure logic
    • Uses the DRP interface and does not require a processor – but more difficult to use.

Of these three options this guide will use option two, where the XADC is connected to the PS through an module in Programmable Logic (PL) that connects to the PS through a AXI interface.

Getting the project startedvivado-guide-1

The first thing to do is to create an empty project in Vivado. Remember to select VHDL as your coding base, and also to select the Zybo board as your platform while setting up the project. When the project is set up, your should start by creating a “Block Design”. Hereafter you add the “Zynq7 PS” bloc
k, and the “XADC Wizard” block, both through the “Add IP” guide. After you have added the following two blocks, you should run the “Auto configuration” tools that Vivado suggest. Finally you should “Regenerate Layout” and then end up with a block design similar to the one below.


The next thing we need to do, is to configure the XADC so that you are able to access external signals on the Pmod JA (XADC) on the Zybo board. For doing the we first need to figure out which of the 17 channels are available on the Pmod connector on the Zybo board. One way to do this is to have a look at the Zybo board it self.

PmodHere you can see the ADC channels which a available on the Pmod connector on the Zybo board.

  • ADC channel: AD14
    • ADC channel: AD7
      • ADC channel: AD15
        • ADC channel: AD6

These are the four channels which are made available on the Pmod connector. All of the channals have both a “p” and an “n” pin, that have been parried on the Zyq chip for best signal-to-noise ratio etc. Those two are always coupled.

So, with this information we are ready to start customizing the XADC module in Vivado. In the “Block Design” view, go double-click on the “XADC Wizard” module and wait for the Re-customize IP window to show.

The XADC have a large number of different settings, and I will for now not go into detail on most of them. I will however go through the four tabs of setting and talk about the settings you need (for now) to be aware of. On the first tab “Basic” you should make sure that “Startup Channel Selection” is saying “Single Channel”. The rest of the settings on this page you should not touch now. What you are defining here is, that you are only interested in measuring from one single channel. If you where to measure from multiple channels, you should select “Channel Sequencer” under “Startup Channel Selection” instead. For “Timing mode” you would like to leave it in “Continuous Mode” since that make it automatically run measurements all the time, compare to only doing it based on an Event.


On the “ADC setup” tab, you should make sure to select “ADC offset and Gain Calibration” as well as “Enable CALIBRATION averaging” and from the drop down menu “Channel Averaging” select “16”. The reset of the setting should be okay as they are.


On the “Alarms” tab, you just deselect all alarms.


On the final tab, “Single channel” you will select the channel that you would like to measure on. If you e.g. would like to measure on “AD14” that we saw above, you should here select “VAUXP14 VAUXN14” from the drop-down menu under “Select Channel”. Also remember to check “Channel Enable”.


With this done, press “OK”, and watch how the port is added to the “XADC Wizad” in the “Block design” view while all the Alarm ports are removed.

In the “Block Design” view, you should now place your mouse on the “Vaux14” port on the “XADC Wizard” right click, and select “Create interface port”. In the window “Create interface port” just press “Ok” to accept the suggested name, mode etc. from VIvado. Once again press “Regenerate design” and you should have a design similar to the one below.

What now needs to be done is connecting the XADC channel 14 to the physical pins on the Zybo board. What you first needs to do is to press “Validate design” from the Tools menu, to make sure that there is now obvious mistakes in the “Block Design”. The next thing is to create a HDL wrapper for the design. In the “Sources” view you should right click on the only entrance in “Design sources” and press “Create HDL wrapper”. Now you should press “Elaborate Design” under “RTL Analysis” in the menu on the left, and wait for Xilinx to finish.


You should now have a port-view similar as above, where you need to select the ports for the “Vaux14_v_n” and “Vaux14_v_p”. You will select “N16” and “N15” as those are the only options since that’s how things are routed on the Zybo board. Also remember to select the I/O standard.

When done press save from the “File” menu and give the newly created constrain file a name like e.g. “constrains”. Now press “Generate Bitstream” in the “Flow Navigator ” to the left.

When Vivado is all done, go to “File” and press “Export” -> “Export Hardware”. Make sure to select “Include bitstream” in the showing window and press “OK”. Next go to “File” and press “Launch SDK” and press “OK” in the popup window. Once again you wait for Xilinx to finish opening up SDK.

Writing a bare-metal application to run the ADC

Once Xilinx SDK have loaded, go select to “File” and “New” and “Application Project”. Give it a name such as “XADC_Example” and press next. In the next view, you select the “Empty Application” template and press “Finish”.

When the project have opened, right-click on the project name in “Project Explorer” view to the left, and select “New”-> “Source file”. You should give your source file a name like e.g. main.c and press “OK”. Open your newly created source file, and copy the code below into the file.

Now try to compile it and hopefully you will have no errors. Now flash your bit-file to the Zynq, and select “Run as” -> “Launch on hardware (GDB)”. Before this you should connect a serial terminal like “Putty” to get the output. You should get something similar to this:

This ends the guide on how to get the XADC working on the Zynq-7000device working using the Zybo board as the base.