We are all familiar with the RFSoC and the high speed ADC and DAC which are combine with the ZYNQ MPSoC. However, you might not be aware all Xilinx Seven Series and up have a XADC / Sysmon ADC which is cable of monitoring the internal voltage rails and die temperature.
the XADC / Sysmon is also capable of monitoring external analog signals, ont eh Zynq 7000 it is able to sample at up to 1 MSPS which makes it very interesting for simple signal processing applications.
I have also seen few applications which use PYNQ to capture data from the XADC so in this project we are going to create a simple XADC scope application.
PynqTo get started we need a PYNQ Image as there is no official PYNQ image for the MicroZed (either 7010 or 20) the first thing to do is create a PYNQ image. As such a thing is a project on its own and we have done this sever times before I will refer you to previous projects (Zybo, Snickerdoodle and Cora) and make the image available here.
VivadoTo get started, we need to first develop an overlay which connects the XADC to the Processors system using the AXI stream interface and DMA. This allows us to capture a continuous stream of data input from the Vp/Vn dedicated analogue input.
The first thing we need to do is create a new project
Define the name and location of the project
Select a RTL project and define the sources later
Select the MicroZed board of choice.
Create the new project.
With the new project created, create a new block diagram.
To the new block design add in the processor system
Run the block automation to configure the processor for the MicroZed board.
Once the processor is configured, add in the XADC block.
Customise the XADC block to operate in continuous mode, single channel and enable the AXI Stream. To achieve a sampling rate of 1000 ksps we need to set the DClk to 104 MHz as the XADC internally take 4 clock cycles for acquisition and 26 cycles for conversion.
Disable all of the alarms and click OK
Add in a Clock Wizard as the Zynq fabric clocks are unable to generate the 104 MHz clock required.
Set the clock wizard to the frequency of 104 MHz and Reset active low.
With the clock wizard configured we need to re customize the processing system to include provide a master AXI interface to configure the IP in the PL using AXI lite. A Slave AXI port should also be implemented to enable the high bandwidth XADC data to be transferred to the PS DDR Memory for analysis.
The XADC output AXI Stream does not include the TLast signal, this signal is required for use with the DMA transfer. As such a AXI Stream SubSet convertor should be added to the Block Diagram. Enable the TLast output on the master interface and allow the system to generate the TLast signal every 128 transactions.
Run the connection automation to implement the AXI Lite network and connect the AXI Stream output from the AXI Subset convertor to the AXI MM input on the Zynq PS.
Vivado will automatically implement the AXI DMA infrastructure.
If you want to change the size of the buffer in the AXI DMA change the setting of the buffer length register in the DMA settings.
The completed block diagram is shown below.
Once this is completed we are able to build the bit stream and export the XSA file for use in Vitis.
Leave the filename and export location unchanged
Export the hardware.
Prior to creating the PYNQ platform I like to ensure the design has the intended functionality. In this example we can use Vitis and a bare metal approach to test out the XADC and DMA configuration.
Create a new VITIS Application Project
Import the XSA previously exported from Vivado
Create a new application project
Create a new domain
Select the Hello World Template
Once this is completed we will see a new project created, open the hello_world.C file and replace the contents with below
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xsysmon.h"
#include "xaxidma.h"
#define SYSMON_DEVICE_ID XPAR_SYSMON_0_DEVICE_ID
#define DMA_DEV_ID XPAR_AXIDMA_0_DEVICE_ID
#define DDR_BASE_ADDR XPAR_AXIDMA_0_BASEADDR
#define RX_BUFFER_BASE (0x00100000)
#define MAX_PKT_LEN 256 //bytes
int main()
{
XSysMon_Config *SYSConfigPtr ;
XSysMon SysMonInstPtr;
XAxiDma_Config *CfgPtr;
XAxiDma AxiDma;
int Status;
int reset_done;
u8 *RxBufferPtr;
u32 addr;
init_platform();
print("Hello World\n\r");
print("Successfully ran Hello World application");
SYSConfigPtr = XSysMon_LookupConfig(SYSMON_DEVICE_ID);
if (SYSConfigPtr == NULL) {
return XST_FAILURE;
}
CfgPtr = XAxiDma_LookupConfig(DMA_DEV_ID);
if (!CfgPtr) {
printf("No config found for %d\r\n", DMA_DEV_ID);
return XST_FAILURE;
}
Status = XAxiDma_CfgInitialize(&AxiDma, CfgPtr);
if (Status != XST_SUCCESS) {
printf("Initialization DMA failed %d\r\n", Status);
return XST_FAILURE;
}
XSysMon_CfgInitialize(&SysMonInstPtr, SYSConfigPtr, SYSConfigPtr->BaseAddress);
XSysMon_SetSequencerMode(&SysMonInstPtr, XSM_SEQ_MODE_SAFE);
XSysMon_SetAlarmEnables(&SysMonInstPtr, 0x0);
XSysMon_SetSeqChEnables(&SysMonInstPtr, XSM_SEQ_CH_VPVN);
XSysMon_SetAdcClkDivisor(&SysMonInstPtr, 32);
XSysMon_SetSequencerMode(&SysMonInstPtr, XSM_SEQ_MODE_CONTINPASS);
RxBufferPtr = (u8 *)RX_BUFFER_BASE;
addr = (u32)RX_BUFFER_BASE;
XAxiDma_Reset(&AxiDma);
reset_done = XAxiDma_ResetIsDone(&AxiDma);
while(reset_done != 1){
}
XAxiDma_IntrDisable(&AxiDma, XAXIDMA_IRQ_ALL_MASK,XAXIDMA_DEVICE_TO_DMA);
XAxiDma_IntrDisable(&AxiDma, XAXIDMA_IRQ_ALL_MASK,XAXIDMA_DMA_TO_DEVICE);
while(1){
Status = XAxiDma_SimpleTransfer(&AxiDma,(UINTPTR)RX_BUFFER_BASE,MAX_PKT_LEN, XAXID MA_DEVICE_TO_DMA);
if (Status != XST_SUCCESS) {
printf("XFER failed %d\r\n", Status);
return XST_FAILURE;
}
while ((XAxiDma_Busy(&AxiDma,XAXIDMA_DEVICE_TO_DMA))){
/* Wait */
}
Xil_DCacheFlushRange((UINTPTR)RxBufferPtr, MAX_PKT_LEN);
}
cleanup_platform();
return 0;
}
Running this code will show the contents of the XADC being transferred to the DDR memory which can be observed when the system is debugged.
Now we are happy the platform works the next step is to create the PYNQ application.
PYNQWith the MicroZed PYNQ image written to the SD Card, we can boot the Microzed connected to the IOCC. Once PYNQ starts we can map in the PYNQ board to the computer directory and create a new Overlay. For this we need
- Bit file generated by Vivado
- HWH file generated by Viviado
- __init__.py initialization script
- xadc_scope.py class defintion for the overlay
The py scripts need to be written by hand
__init__.py
from .xadc_scope import xadc_scopeOverlay
xadc_scope.py
import pynq
from pynq import GPIO
__author__ = "Adam Taylor"
__copyright__ = "Copyright 2020, Adiuvo"
__email__ = "Adam@adiuvoengineering.com"
class xadc_scopeOverlay(pynq.Overlay):
""".
"""
def __init__(self, bitfile, **kwargs):
super().__init__(bitfile, **kwargs)
if self.is_loaded():
pass
With the overlay created we can create a simple note book to capture the XADC signals.
Remember the DMA works in BYTES and the XADC is outputting 2 BYTES per sample.
from pynq import pl
from pynq import overlay
from pynq.overlays.xadc_scope import xadc_scopeOverlay
overlay = xadc_scopeOverlay('xadc_scope.bit')
import numpy as np
from pynq import allocate
from pynq import Overlay
import matplotlib.pyplot as mp
input_buffer = allocate(shape=(128,), dtype=np.uint16)
dma = overlay.axi_dma
recvstatus = dma.recvchannel.running
dma.buffer_max_size
dma.recvchannel.transfer(input_buffer)
dma.recvchannel.wait_async()
mp.plot(input_buffer)
Running the code below shows the output of the sine wave as it is captured
With this sinewave we can then input the conversion factor if we so want from the raw value to the voltage.
XADC Control Under PYNQUsing the Vp/Vn inputs we do not need to make any changes to the configuration of the XADC however, if we wanted to change the configuration of the XADC. We are able to do this using the standard AXI interface to read and write the registers defined with UG480
ConclusionThis project has been good to show how we can work with PYNQ, the XADC using boards like the MicroZed. The MicroZed and the SoM concept is a great platform to get started quickly developing hardware applications. The PYNQ image for this board will provide the ability to accelerate the design even faster.
Comments