AVNET MicroZed SOM 7Z010 + Carrier Card - Review

Table of contents

RoadTest: AVNET MicroZed SOM 7Z010 + Carrier Card

Author: vmate

Creation date:

Evaluation Type: Development Boards & Tools

Did you receive all parts the manufacturer stated would be included in the package?: True

What other parts do you consider comparable to this product?: Digilent's various development boards, PYNQ

What were the biggest problems encountered?: Lack of documentation for beginners

Detailed Review:

Introduction

The MicroZed SOM 7010 is a module using a Zynq 7010 SoC with 1GB of DDR3 RAM, providing 108 IO pins, 1Gbit Ethernet, and USB2.0.

The Arduino Carrier Card provides 2 PMOD connectors, one connected to the PL, the other connected to the PS. All of the Arduino pins are connected to the PL.

 

 

PS vs PL

The PS(Processing System) is a dual core ARM CPU in the case of this board, which can run C/C++ code, an RTOS, or Linux.

The PL(Programmable Logic) is the FPGA part of the chip.

 

These two parts can be connected together, for example, a hardware SPI controller can be created in the PL and connected to the PS, in case the 2 built-in SPI controllers aren’t enough.

 

There are separate pins on the Zynq that are connected to the PL, and another set of pins that are connected to the PS. The PL pins however can be used with the PS, by using AXI GPIO IP.

 

 

Setting up Vivado

After installing Vivado, the board definition files need to be installed as well. Unfortunately, the MicroZed page has an outdated version of this file available. After downloading the latest version from GitHub, the microzed_7010 folder needs to be copied to

<install_location>\Vivado\<version>\data\boards\board_files

 

Defining hardware in Vivado

 

{gallery} Creating Vivado project

image

Creating Vivado Project: Create new project

image

Creating Vivado Project: New project start screen

image

Creating Vivado Project: Name and location of new project

image

Creating Vivado Project: Set project type

image

Creating Vivado Project: Select board preset

image

Creating Vivado Project: New project summary



Next, add the constraints file to the project.
Unfortunately, Avnet doesn't provide a "generic" XDC file for the Arduino Carrier Card, so I made one:

set_property -dict { PACKAGE_PIN Y16    IOSTANDARD LVCMOS33 } [get_ports {ARDUINO_D15}];
set_property -dict { PACKAGE_PIN Y17    IOSTANDARD LVCMOS33 } [get_ports {ARDUINO_D14}];
set_property -dict { PACKAGE_PIN W14    IOSTANDARD LVCMOS33 } [get_ports {ARDUINO_D13}];
set_property -dict { PACKAGE_PIN Y14    IOSTANDARD LVCMOS33 } [get_ports {ARDUINO_D12}];
set_property -dict { PACKAGE_PIN T16    IOSTANDARD LVCMOS33 } [get_ports {ARDUINO_D11}];
set_property -dict { PACKAGE_PIN U17    IOSTANDARD LVCMOS33 } [get_ports {ARDUINO_D10}];
set_property -dict { PACKAGE_PIN V15    IOSTANDARD LVCMOS33 } [get_ports {ARDUINO_D9}];
set_property -dict { PACKAGE_PIN W15    IOSTANDARD LVCMOS33 } [get_ports {ARDUINO_D8}];
set_property -dict { PACKAGE_PIN N18    IOSTANDARD LVCMOS33 } [get_ports {ARDUINO_D7}];
set_property -dict { PACKAGE_PIN P19    IOSTANDARD LVCMOS33 } [get_ports {ARDUINO_D6}];
set_property -dict { PACKAGE_PIN N20    IOSTANDARD LVCMOS33 } [get_ports {ARDUINO_D5}];
set_property -dict { PACKAGE_PIN P20    IOSTANDARD LVCMOS33 } [get_ports {ARDUINO_D4}];
set_property -dict { PACKAGE_PIN T20    IOSTANDARD LVCMOS33 } [get_ports {ARDUINO_D3}];
set_property -dict { PACKAGE_PIN U20    IOSTANDARD LVCMOS33 } [get_ports {ARDUINO_D2}];
set_property -dict { PACKAGE_PIN W20    IOSTANDARD LVCMOS33 } [get_ports {ARDUINO_D1}];
set_property -dict { PACKAGE_PIN V20    IOSTANDARD LVCMOS33 } [get_ports {ARDUINO_D0}];


set_property -dict { PACKAGE_PIN G17    IOSTANDARD LVCMOS33 } [get_ports {PMOD_1}];
set_property -dict { PACKAGE_PIN G18    IOSTANDARD LVCMOS33 } [get_ports {PMOD_2}];
set_property -dict { PACKAGE_PIN F19    IOSTANDARD LVCMOS33 } [get_ports {PMOD_3}];
set_property -dict { PACKAGE_PIN F20    IOSTANDARD LVCMOS33 } [get_ports {PMOD_4}];
set_property -dict { PACKAGE_PIN N15    IOSTANDARD LVCMOS33 } [get_ports {PMOD_7}];
set_property -dict { PACKAGE_PIN N16    IOSTANDARD LVCMOS33 } [get_ports {PMOD_8}];
set_property -dict { PACKAGE_PIN L14    IOSTANDARD LVCMOS33 } [get_ports {PMOD_9}];
set_property -dict { PACKAGE_PIN L15    IOSTANDARD LVCMOS33 } [get_ports {PMOD_10}];

 

 

Import the constraints file to the Vivado project

 

{gallery} Importing Constraints

image

Importing Constraints: Add sources button

image

Importing Constraints: Select source type

image

Importing Constraints: Choose constraints file

image

Importing Constraints: Finalizing


Next, create a block design, add the ZYNQ7 Processing System, and generate an HDL wrapper


{gallery} ZYNQ Processing System

image

ZYNQ Processing System: Creating Block Design

image

ZYNQ Processing System: Block Design name and location

image

ZYNQ Processing System: Adding IP

image

ZYNQ Processing System: Add ZYNQ7 Processing System IP

image

ZYNQ Processing System: Run Block Automation

image

ZYNQ Processing System: Block Automation settings

image

ZYNQ Processing System: Creating HDL Wrapper

image

ZYNQ Processing System: HDL Wrapper settings

 


After creating the wrapper, generate a bitstream and export hardware

{gallery} Exporting Hardware

image

Exporting Hardware: Generate Bitstream

image

Exporting Hardware: Bitstream generation settings

image

Exporting Hardware: Completion of bitstream generation

image

Exporting Hardware: Export Hardware button

image

Exporting Hardware: Export Hardware dialog

image

Exporting Hardware: Export settings

image

Exporting Hardware: Save location and name

image

Exporting Hardware: Finalizing


Create Vitis Application Project

 

{gallery} Creating Vitis Application Project

image

Creating Vitis Application Project: Start

image

Creating Vitis Application Project: Import platform exported from Vivado

image

Creating Vitis Application Project: Name project

image

Creating Vitis Application Project: Create domain

image

Creating Vitis Application Project: Finalize

 

Blink User LED (Working with PS outputs)

The User LED on the MicroZed is connected to the PS. The following code will blink the LED with a 1 second delay.

#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xgpiops.h"
#include "xstatus.h"
#include "xplatform_info.h"
#include "sleep.h"


XGpioPs Gpio;


int main()
{
    init_platform();
    XGpioPs_Config *GPIOConfigPtr;
    GPIOConfigPtr = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);
    XGpioPs_CfgInitialize(&Gpio, GPIOConfigPtr, GPIOConfigPtr->BaseAddr);
    XGpioPs_SetDirectionPin(&Gpio, 47, 1);
    XGpioPs_SetOutputEnablePin(&Gpio, 47, 1);


    while(1) {
    XGpioPs_WritePin(&Gpio, 47, 0);
    sleep(1);
    XGpioPs_WritePin(&Gpio, 47, 1);
    sleep(1);
    }


    cleanup_platform();
    return 0;
}

 

Control User LED with User Button (Working with PS inputs)

The following code reads the User Button state and controls the User LED accordingly.

#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xgpiops.h"
#include "xstatus.h"
#include "xplatform_info.h"
#include "sleep.h"


XGpioPs Gpio;


int main()
{
    init_platform();
    XGpioPs_Config *GPIOConfigPtr;
    GPIOConfigPtr = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);
    XGpioPs_CfgInitialize(&Gpio, GPIOConfigPtr, GPIOConfigPtr->BaseAddr);
    XGpioPs_SetDirectionPin(&Gpio, 47, 1);
    XGpioPs_SetOutputEnablePin(&Gpio, 47, 1);
    XGpioPs_SetDirectionPin(&Gpio, 51, 0);


    while(1) {
    int state = XGpioPs_ReadPin(&Gpio, 51);
    XGpioPs_WritePin(&Gpio, 47, state);
    }


    cleanup_platform();
    return 0;
}

Connecting the PS and PL - Creating a NAND gate

Additional GPIO "controllers" can be created in the FPGA part of the Zynq, which also allows us to connect custom HDL modules to the input/output of those GPIO controllers.
In this example, we'll create a NAND gate in the FPGA, the output of which is connected to an AXI GPIO IP, which is also implemented in the FPGA, which is then read by the PS, that controls the User LED according to the output of the NAND gate.

First, create a new Verilog module that implements a NAND gate

 

 

{gallery} Creating Verilog NAND gate

image

Creating Verilog module: Add Sources

image

Creating Verilog module: Select source type

image

Creating Verilog module: Create new file

image

Creating Verilog module: New file properties

image

Creating Verilog module: Finish adding new source

image

Creating Verilog module: Specify I/O Ports

image

Creating Verilog module: Create NAND gate

 

Then, add the NAND gate module to the Block Diagram

image

Enable the AXI master interface in the Zynq Processing System by double clicking on it, and selecting the appropriate option shown below.

image

Add the AXI GPIO IP to the block diagram
image

Run Connection Automation for AXI port on the AXI GPIO IP
image

image

Configure AXI GPIO as a single input

image

Connect NAND gate output to AXI GPIO input

image

image

Connect inputs on NAND gate to physical pins on the FPGA

image

Rename external connection to a pin name from the constraints(.xdc) file.

 

image

Repeat for input "b"

 

Completed block diagram

image

 

Generate the bitstream and export hardware, then launch Vitis and create new hardware project as shown previously.

Processing System code for reading NAND gate output through AXI GPIO, and controlling User LED accordingly:

#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xgpiops.h"
#include "xstatus.h"
#include "xplatform_info.h"
#include "sleep.h"
#include "xgpio.h"
#include "xparameters.h"


XGpioPs Gpio;
XGpio FPGA_Gpio;


int main()
{
    init_platform();
    XGpioPs_Config *GPIOConfigPtr;
    GPIOConfigPtr = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);
    XGpioPs_CfgInitialize(&Gpio, GPIOConfigPtr, GPIOConfigPtr->BaseAddr);
    XGpioPs_SetDirectionPin(&Gpio, 47, 1);
    XGpioPs_SetOutputEnablePin(&Gpio, 47, 1);


    XGpio_Initialize($FPGA_Gpio, XPAR_AXO_GPIO_0_DEVICE_ID);
    XGpio_SetDataDirection($FPGA_Gpio, 1, 0);




    while(1) {
    int state = XGpio_DiscreteRead(&FPGA_Gpio, 1);
    XGpioPs_WritePin(&Gpio, 47, state);
    }


    cleanup_platform();
    return 0;
}


Conclusion

The MicroZed is a very capable board with plenty of documentation, however there is some very basic information missing for people who haven't worked with a Xilinx FPGA/Zynq SoC before. The first thing I wanted to do with this board was make a NOT gate in the FPGA using the User Button and User LED, but as it turned out after doing some research, the User LED and User Button are connected to the MIO pins, which can only be controlled from the PS. Basic information like this could be very useful for a beginner, just like providing a generic constraints file for the Arduino Carrier Card. Otherwise, the documentation is well made, and there are plenty of example projects available to download.
Having more PMOD connectors on the Arduino Carrier Card would be useful, even if it shared pins with the Arduino headers. The current configuration of one PS PMOD and one PL PMOD makes it inconvenient to use PMODs that require two connectors, requiring the use of jumper cables to interface with the Arduino headers as well for the second PMOD connector.
A PL PMOD in addition to the PS PMOD on the MicroZed itself would be favorable as well.


 

Anonymous