Tag Archives: xadc

Arty – In Chip Logic Analyser


Sometimes despite the simulation we have performed upon our design we still have issues with the design on the hardware. One way we can debug in the hardware is to use a ILA within our hardware design, this gives us the ability to monitor either a number of AXI interfaces or discrete inputs.

Adding in an AXI monitor on the AXI interface to the XADC we are currently using in our example we enable us to monitor the transactions. In this case just such that we can examine them however in other instances it may be necessary due to design or integration issues.

We can add in the ILA into our design from the Integration library in our block diagram.


Insertion of the ILA into the Design

By default, the ILA is configured to monitor a AXI interface however, we can change its settings by double clicking on the ILA block and customising as required. We can add in trigger ports, capture control and comparators to trigger on specific patterns in the data stream. For this example, I am going to keep it fairly simple to show the flow and then we can look at more advanced aspects once this is understood.



Customising the ILA

With the ILA inserted into the design the next stage is to reset the generated outputs and then re generate these such that we can implement the design. Once the design is implemented we can then programme the device using the hardware manager, it is via the hardware manager that we can also examine the contents of the interfaces we wished to examine.

Using the hardware manager, we should connect to our Arty target, the next step is to programme the FPGA and initialise the logic analyser. To achieve this we need both the bit file and the definition of the debug nets we wanted to examine in the Vivado block diagram, you will see this as the ltx file within the projects runs / implementation directory beside the bit file.


Identifying the ltx file


Configuring the device and debug profile.

Once these files have been configured we will see the screen below open up in the hardware manager which provides the interface we can use to configure the triggering, capture mode and arm the ILA core.

Once we have configured the core as we wish, we can examine the waveform in the waveform viewer below.



ILA Configuration and control scheme in Hardware Manager



Captured Waveform

With the simple flow explained we can, in the next blog look at how we can use more advanced features of the ILA.


Arty – FreeRTOS & XADC


Happy New Year! For the first blog of the year I thought we would combine the FreeRTOS and the XADC examples we had bbeen looking at previously.

This will enable me to show how we can do the following

  1. Configure the XADC
  2. Create a task to read from the XADC
  3. Create a second task to take action on the results from the first task

The intended functionality is the one task, once a second reads the XADC internal parameters and stores them within a array. This array is then communicated via a queue to the recieivng task which processes the results, for this example it just outputs them over the UART. If we wanted to this task could perform more detailed analysis or calcualtion on the results being provided to it.

We can easily modify the hello world example to perform this. If we wish to make it more complex and introduce more tasks which share resources, we must ensure they are properly managed and do not become deadlocked.

The first thing we need to do is include the proper header files such that we can use the API for the XADC we do this by including the “XSYSMON.H”.

Within the main function we are going to configure and initialise the XADC before we start the two tasks.

As we are going to be using the printf function and we are going to transfering data we need to ensure the stack size is correctly allocated. To prevent problems I decided to increase this to ensure there was sufficent for that requred for both tasks, when we create the tasks in the main() we are required to define the stack allocated to each task. For both tasks I decided to allocate 1000 bytes, I left the task pirorites as the receiving task being a higher priortiy than the transmitting task ensuring the data is transmitted as soon as it is received.


The next step was to create the queue, as I mentioned above due to the priorities of the RX and TX tasks there will only be one element in the queue, which will be the size of the size element XADC_Buf.

The final element is to start the scheduler and let the tasks run for ever well once we have written them.

We write each task as a we would any function in C, being careful to ensure we include the 1 second dealy within the transmitt task.

When I ran the code (which is available here) I got the following results.



Arty – XADC Alarms & References


One of the most common uses of the XADC is for health monitoring of the FPGA and the wider system to that mind the XADC has a number of useful features which can be used.

  1. Trigger and Reset Threshold Alarm registers for the Internal voltages and temperature parameters
  2. Over Temp Monitoring – Maximum junction operating temperature allowable for the device – Auto shut down is possible.
  3. Maximum and Minimum values – Registers which contain the lowest and highest sampled values for each of the voltages and device temperature.

These three elements make for a very useful health monitoring system, of course the alarms and the over temperature must be correctly configured and enabled first. This can be achieved in one of two ways, either via the XADC wizard within Vivado or via our software application.


There are seven possible alarms we can configure on the XADC, however we cannot use all of them on the Artix Silicon as some alarms as dedicated to the Zynq (Alarm 6 Vccddro, Alarm 5 Vccpaux and Alarm 4 Vccpint). There is also an eighth alarm bit which is the logical OR of the seven alarm bits and acts as an overall alarm.

We can see if an alarm has occurred via either the Alarm Status Output Register or configure an interrupt to occur should an alarm condition occur such that it can be immediately dealt with.


These trigger and reset values allow us to define values which align with our worst case analysis of supply voltages and junction temperature, ensuring we can protect the system properly.

Each alarm also has an associated output which can be used in the wider system either to indicate via a LED a issue has occurred or to take further action e.g. graceful system degradation.

The over temperature alarm is slightly different in that it can be configured to trigger an automatic shutdown of the device. To set automatic shut down the four LSB’s of the over temperature register must be set high. Doing this means that 10 ms after the trigger level is reached a shut down occurs. This prevents re -configuration of the device until the reset level is reached.

It is intended that the temperature alarm is used to act as a pre-warning that the temperature has exceed what the design has calculated as its maximum. This way the system can take action to prevent the shut down e.g. turning on fans, reducing processing etc.


While the maximum and minimum registers provide the system with a simple methodology of quickly and easily checking the worst case values as currently observed by the system during its period of operation. These registers can also be of good use in system commissioning to record supply voltages and temperatures  across worst case environmental conditions for example.

There is also one last issue which must be addressed when using the XADC on the Arty board and that is we need to correctly set up the board to use the internal VRefp. Failure to do this results in a inaccurate conversions.  The Arty board is configured such that you can use either the internal or external reference.




We can ensure the internal reference is used by grounding the XADCVREF input, as such the internal reference will be used. This can be confirmed by reading the flag register which also helpfully contains information on any alarms as well


With the XADC configured to correctly monitor the internal signals with suitable alarm levels we can look at how we can use the XADC to receive analogue signals from the real world


Arty – XADC SW


With the hardware all built and the MicroBlaze system configured to support the XADC at the hardware level we need to be able to drive it at the software level.


The first thing you will notice is that having built the hardware in Vivado we need to open the implementation and export the design and the bit file to SDK. The next time we open SDK we will see a dialog box which states the Hardware platform we are using has changed and would we like to update import that to SDK and update the BSP, the answer of course is YES.

This will result in the hardware platform being updated and most importantly the BSP being updated to pull in the correct drivers for the XADC. We can see this if we open the BSP MSS file and click on customise the BSP button, this will open a dialog box upon which the drivers tab we can see the XADC and the driver used to control it in this case XSYSSMON.H. Looking around the BSP directory under the includes/libsrc/sysmon folder will show you the source code to drive the XADC.

Within our application SW how we initialise and set up a peripheral is very similar for all devices

  1. Define the peripheral of interest from the xparameters.h file in this case

#define xadc XPAR_SYSMON_0_DEVICE_ID

  1. Define the instance of the peripheral type we are going to be controlling

XSysMon xadc_inst;

  1. Declare a instance pointer to the peripheral type pointing to the address of the previous instance

XSysMon *xadc_inst_ptr =&xadc_inst;

  1. Declare a configuration pointer of the type of peripheral to be initialised in this case it is XSysMon_Config *xadc_config;
  2. Initialise the configuration pointer with the parameters for the peripheral in use in using the function

Xadc_config = XSysMon_LookupConfig(xadc);

  1. Initialise the peripheral using the function


With the initialization complete we can then proceed to configure the XADC as needed for our application To do this we use the drivers within the XSysMon.h these allow us to configure all of the ADC inputs, its sequencing and if it is interrupt driven or polled.

For this simple example I am going to configure the XADC to sample its internal parameters namely its temperature, VCCInt, VCCAux, VRefP, VRefN, VBram  as would be expected on a normal health monitoring system. This is simple to do using the functions below, this also disables all the alarms in the XADC.


                 XSysMon_SetAlarmEnables(xadc_inst_ptr, 0x00000000);




As I Mentioned in the last blog as we need to use the XADC to provide temperature information to the MIG we will also be enabling the temperature cycle update and defining the time duration this is updated at

XSysMon_SetTempWaitCycles(xadc_inst_ptr, 0x00000340);


The 0x340 relates to system clock cycles which are 83.25MHz to the refresh rate is 9.9939 us which is within the maximum refresh period of 10 microseconds.

Reading the XADC for this example is very simple I used a polled approach which checks for then of end of sequence bit before it asks for the XADC value.

                for(Index =0; Index <RX_BUFFER_SIZE; Index++){

                while ((XSysMon_GetStatus(xadc_inst_ptr) & XSM_SR_EOS_MASK) !=XSM_SR_EOS_MASK);

                                XADC_Buf[Index] = XSysMon_GetAdcData(xadc_inst_ptr, sample[Index]);


The final stage of the programme is to output the results into the table format as can be seen below over the RS232 link. IT is worth recording here that XADC returns a 16 bit result therefore to give the 12 bit accurate result the output result is shifted left by 4 places.


You can get the complete code here on the git hub

Over the next few blogs we will look at the XADC Interrupts and Alarms now we have a verified working platform.


Arty – XADC Hardware Build


Like all Seven series device the Artix on the Arty board contains a 1 MSPS 12 bit XADC which is capable of monitoring not only its internal voltages and die temperature but also up to 16 external inputs. This makes the XADC a very useful device within a embedded system, as it allows you to monitor your system health and perform low speed signal processing without the need for a separate ADC.


To show the ease with which we can implement and use a XADC we will add one in to the MicroBlaze system we have been using previously. This will provide the fastest way to configure and report output of the XADC. In fact as we have been using the Memory Interface Generator we already been using the XADC without knowledge as it is used within the MIG to compensate for temperature effects to ensure the DQS is kept centred.
As such if we were to add in another XADC to our block diagram in Vivado we will fail implementation as there would be two XADC instantiations called up when there is only one within the device.
Therefore before we can place the XADC and use it as we wish within our design to monitor the Arty temperature and voltage supplies we need to adjust the configuration on the MIG to not call up the XADC as shown in the image below.


Instead this will create a new port at the top level of the MIG which is supplied the temperature from the XADC we wish to instantiate.
With this complete we can now open the IP library and place and connect the XADC to the AXI bus, we can make the VP/VN signals connected to the external ports (J5 on the Arty board) by right clicking on the VPVN port on the XADC and selecting make external.
With the XADC connected into the system we need to configure it to provide the temperature output bus needed by the MIG such that it can provide temperature compensation.
To do this we need to tick the Temp Bus option within the basic tab of the XADC wizard, there are a few software switches we need to set when we write the software.


This should result in a block diagram which looks like below when the XADC and the MIG are connected together as required.


We can drive the XADC in either a polled or interrupt fashion depending upon our application needs, to ensure interrupt support we need to make some connections in the Vivado block diagram.
The first thing we need to do is add a third input to the concatenation block which creates the interrupt vector, we need to increase this from two to three inputs. With this completed we can connect the ip2intc_irpt output signal from the XADC to the new input on the concatenation block.
I also decided the block diagram was getting congested and hard to read so I group up a number of blocks and created a hierarchy. This is easy to do select the blocks you wish to group together, right click and select create hierarchy, enter the block name and a new block will be created with that name. other blocks within your design can then be dragged into that hierarchy block if you wish to add them to it or removed by expanding the block (+ sign in top left) and dragged out. This enables us to create very net looking diagrams. Do not forget to click the re draw option once you have implemented your blocks.


Next time we will look at how we can drive the XADC using C in SDK.


Implementing Analog Mixed Signal on the Zynq SoC



The Xilinx® Zynq® All Programmable
SoC comes with an XADC block
that contains two 12-bit analog-todigital
converters. These ADCs are capable
of sampling at up to 1 Megasample per second
(MSPS), providing an ideal effective
input-signal bandwidth of 500 kHz (250 kHz
on the auxiliary inputs). The XADC can multiplex
among 17 inputs along with a number
of internal voltages and temperatures. If
your design is pin-limited in terms of available
analog-capable inputs for external signals,
you can configure the XADC to drive an
external analog multiplexer and sequence
through all the inputs in the desired order.

Link here