Skip navigation
> RoadTest Reviews

Digilent ARTY Z7 Dev Board - Review


Product Performed to Expectations: 10
Specifications were sufficient to design with: 9
Demo Software was of good quality: 8
Product was easy to use: 10
Support materials were available: 8
The price to performance ratio was good: 9
TotalScore: 54 / 60
  • RoadTest: Digilent ARTY Z7 Dev Board
  • Buy Now
  • Evaluation Type: Development Boards & Tools
  • Was everything in the box required?: Yes
  • Comparable Products/Other parts you considered: The Parallella Board, snickerdoodle, Z-turn Board, etc.
  • What were the biggest problems encountered?: Example projects don't get updated for newer versions of Vivado.

  • Detailed Review:

    Digilent Arty Z7 Dev Board Review



    First of all, thank Randall Scasny(rscasny) for organizing this Digilent ARTY Z7 Dev Board road test and Digilent for offering the road test kit. I am very grateful for being selected for the road test.


    First Impression


    The board is packed in a compact and neat cardboard package.


    An extra protection foam is very thoughtful for protecting components and exposed connector pins.


    PCB layout is well designed and quality is very good.



    Demo Software


    Digilent provides 3 example projects which are all created in Vivado 2016.4. I tried to exercise all three examples in Vivado 2018.2, but I only got one example work, i.e. XADC demo after upgrading the IPs used by the project.

    However, after installing Vivado 2016.4, I was able to successfully complete the other two example projects. It would be very helpful if Digilent can update demo projects for newer versions of Vivado suites.


    Using Python on ARTY Z7 Dev Board through PYNQ


    PYNQ is an open-source project from Xilinx® that makes it easy to design embedded systems with Xilinx Zynq® Systems on Chips (SoCs). Even though ARTY Z7 Dev Board isn't one of the official development boards supported by PYNQ. However, it has very similar hardware components as the official PYNQ-Z1 board has. Probably the biggest difference between them is PYNQ-Z1 has a microphone while ARTY Z7 Dev Board doesn't.


    MicroSD Card Setup

    Given the hardware similarity, the PYNQ-Z1 image (current version is 2.3) can be used for ARTY Z7 Dev Board (as long as you don't exercise the microphone relate function). To make your own PYNQ Micro-SD card:

    1. Download the appropriate PYNQ image for your board
    2. Unzip the image
    3. Write the image to a blank Micro SD card (minimum 8GB recommended)

    For detailed instructions on writing the SD card using different operating systems, see Writing the SD Card Image.

    To set up ARTY Z7 for using Python, you just need to follow the instructions in PYNQ-Z1 Setup Guide. Note: Even though the Firefox is mentioned as one of supported browsers in the guide, I couldn't make it pass through the login window as shown below. Thus I recommend use Chrome. PYNQ image provides a built-in Jupyter Notebook web application through which you can interactively run Python code as well as make notes. As described in the guide, you can type either or http://pynq:9090 (depends on you use static IP or DHCP) into your Chrome browser's address box to access the Jupyter Notebook. The login window will show up. Both default username and password are "xilinx" (obviously without double quotes).

    Once you successfully login, the following page will show up. Each folder and its subfolders contain lots of Jupyter Notebook files (.ipynb). You can run each notebook just by clicking on the filename.

    For example, under /base/trace folder, there's a notebook called trace_analyzer_i2c.ipynb.

    If you click on the file, the following page will show up.


    Python Example on ARTY Z7 Dev Board

    Like many built-in examples require external daughter boards (such as PMOD, Arduino) to make it work, the above I2C trace analyzer example requires a Pmod TMP2 sensor which I don't have. Thus I modify the above example notebook and make it work with any I2C device (minor code changes may be required). Below is screen shot of my modified notebook and the actual notebook file is attached at the end of this review.


    Decoding Generic I2C Transactions using Trace Analyzer


    This notebook is a modified version of the built-in datatrace_analyzer_i2c.ipynb example in PYNQ-Z1 image under /home/xilinx/jupyter_notebooks/base/trace. It shows how to use the trace analyzer to capture and analyze generic I2C transactions. Unlike the built-in example which only works with the Pmod TMP2 sensor, the code in this notebook can be directly used as an example for any I2C devices.

    Since I don't have a Pmod TMP2 sensor, an I2C device called FM24CLXX FRAM Board(the small blue PCB board shown below) is used instead. PYNQ-Z1 image has built-in class Pmod_TMP2 supporting the Pmod TMP2 sensor. However, FM24CLXX FRAM Board doesn't have built-in support. We have to use the generic I2C class Pmod_IIC.

    Connect I2C Device to PMOD Port

    You can connect your I2C device to the top row or bottom row pins on either PMODA or PMODB port. On the top side of Arty-Z7 PCB board, they are marked as JA and JB connector respectively. As described in the section Pmod of PYNQ document, only pins 2 & 3 or 6 & 7 have pull-up resistors which make them suitable for I2C interfaces. Since only one I2C peripheral is implemented in each IOP, only one I2C device can be connected to a PMOD port. In other words, you cannot simultaneously connect one I2C device to the top row and another one to the bottom row of a PMOD port.

    In my case, I connect my FM24CLXX FRAM Board to the top row pins of PMODA port as shown in the picture below. That means I will use pin 2 & 3 of PMODA port. If you use a different port/row, you need to make corresponding code changes in the code example below. For instance, if you use PMODB port, you need to change overlay.trace_pmoda to overlay.trace_pmodb. If you connect your I2C device to the bottom row rather than the top row, you need to change Pmod_IIC(overlay.PMODA, 2, 3, ...) to Pmod_IIC(overlay.PMODA, 6, 7, ...). Please refer to class Pmod_IIC document for more details.

    Note: When you connect your I2C device to PMOD port, please make sure align VCC(3.3V) and GND pins to the correct orientation. Otherwise, you may permanently damage your device.

    Step 1: Downloading the overlay

    The trace analyzer for all the interfaces are exposed from the base overlay.

    from pynq.overlays.base import BaseOverlay
    overlay = BaseOverlay('base.bit')
    trace_analyzer = overlay.trace_pmoda

    Step 2: Setup the trace analyzer

    The I2C controller on PMODA interface runs at 100KHz, it is recommended to oversample the transactions (capturing more than 2 samples per logic level). Hence here we set the sampling frequency to 400KHz.

    It takes little time to capture the samples, therefore we set the number of analyzer samples to the maximum (64K samples).

    trace_analyzer.setup(frequency_mhz=0.4, num_analyzer_samples=65535)

    Step 3: Prepare the I2C device

    We plug the FM24CLXX FRAM Board to the top row pins of PMODA port on the board. The I2C address of the memory chip FM24CL16B on this board is 0x50. You I2C device may have a different I2C address so you need to modify the following code as required.

    from pynq.lib.pmod import Pmod_IIC
    sensor = Pmod_IIC(overlay.PMODA, 2, 3, 0x50)

    Step 4: Play with the I2C device

    We will program the first three bytes of the memory chip FM24CL16B with the following content: 11, 22 & 33 in sequence and verify them by reading them back.

    start_addr = 0x0
    num_bytes_read = 3
    # Program three bytes from start_addr address
    sensor.send([start_addr, 11, 22, 33])
    # Read them back
    readings = sensor.receive(num_bytes_read)
    print('Byte(s) from address {0} is {1}.'.format(start_addr, readings))

    Byte(s) from address 0 is [11, 22, 33].

    Step 5: Run the trace analyzer

    We change the content of the first byte to 0x55 (i.e., 85), then start the trace analyzer, followed by the sensor reading the the first byte back. The trace analyzer should capture the I2C transcations of reading back the content.

    start_addr = 0x0
    num_bytes_read = 1
    # Modify the content
    sensor.send([start_addr, 0x55])
    readings = sensor.receive(num_bytes_read)
    print('Byte(s) from address {0} is {1}.'.format(start_addr, readings))

    Byte(s) from address 0 is [85].

    After the trace analyzer has been stopped, we can call analyze() method to prepare all the captured samples into lanes of data. We can ignore the returned values for now because we want to see the sigrok decoded transactions as well.

    _ = trace_analyzer.analyze()

    Step 6: Analyzing and decoding

    The next following cells utilize the sigrok decoders. The decoders are slightly modified, so decoded transactions can be aligned with the captured samples.

    The next cell set protocol and the signal probes.

    Fore more information, please read

                                probes={'SDA': 'D3', 'SCL': 'D2'})

    Sigrok can also show the information about a specified protocol.


    ID: i2c

    Name: I²C

    Long name: Inter-Integrated Circuit

    Description: Two-wire, multi-master, serial bus.

    License: gplv2+

    Annotation classes:

    - start: Start condition

    - repeat-start: Repeat start condition

    - stop: Stop condition

    - ack: ACK

    - nack: NACK

    - bit: Data/address bit

    - address-read: Address read

    - address-write: Address write

    - data-read: Data read

    - data-write: Data write

    - warnings: Human-readable warnings

    Annotation rows:

    - bits (Bits): 5

    - addr-data (Address/Data): 0 1 2 3 4 6 7 8 9

    - warnings (Warnings): 10

    Required channels:

    - scl (SCL): Serial clock line

    - sda (SDA): Serial data line

    Optional channels:



    - address_format: Displayed slave address format ('shifted', 'unshifted', default 'shifted')


    I²C (Inter-Integrated Circuit) is a bidirectional, multi-master

    bus using two signals (SCL = serial clock line, SDA = serial data line).

    After protocol and probes have been set, we can call the decode() method. The path to the saved samples, the starting and ending sample numbers, and the path to the decoded file have to be specified.

    Note: It is recommended not to set too large number for samples to decode. A very large number of decoded samples may lead to very slow rendering of the waveform display, possibly hanging the system.

    In this example, we only decode 1000 samples. In general, it is okay to decode less than 4000 samples at a time. Users can decode more than 4000 samples, but displaying the waveforms will become very slow.

    If users want to check various parts of the entire trace of samples, users can set the starting and ending positions repeatedly and rerun this cell.

    start_position, stop_position = 1, 1000
    waveform_lanes = trace_analyzer.decode('pmod_i2c_trace.csv', 
                                           start_position, stop_position,

    Step 7: Waveform display

    Let's polish the waveform for better display. We will add footer and header to the waveform dictionary.

    For more information:

    waveform_dict = {'signal': waveform_lanes, 
                     'config': {'hscale': 1},
                     'foot': {'tock': start_position},
                     'head': {'text': ['tspan', {'class': 'info h3'}, 
                                       'Pmod I2C Transactions']}}

    The next cell will display the waveform. Users can use scrollbar to check the I2C transactions. The Pmod TMP2 sensor has the I2C base address 0x4B.

    The next cell will take a few seconds to render the waveform.

    from pynq.lib.logictools.waveform import draw_wavedrom

    from pprint import pprint

    [{'begin': 725, 'command': 'Start', 'end': 725},

    {'begin': 728, 'command': 'Address read: 50', 'end': 757},

    {'begin': 761, 'command': 'ACK', 'end': 765},

    {'begin': 765, 'command': 'Data read: 55', 'end': 797},

    {'begin': 797, 'command': 'NACK', 'end': 801}]


    The above Wavedrom rendered waveform cannot show the full capture in one page because of the limitation of the render engine. To give the full picture of the I2C transcation captured by the trace analyzer, I hooked up an external logical analyzer and the capture shows below.

    Step 8: End

    Users can reset the trace analyzer; this will clear all the saved files (*.csv, *.pd, etc.).

    If users want to use a different setup, reset() method also has to be called.







    Work To Do


    My original plan for this road test was to implement a RISC-V processor, i.e., Freedom E310 in the program logic (PL). There's an implementation for Arty A7 board and I'd like to migrate it to this road test board Arty z7-20. After solving a lot of tools and design issues, I encountered the dead end of the migration: on z7-20 board, DDR memory cannot be routed through EMIO to PL. To make a workaround solution, significant modification will be required, which seems not feasible for this road test. I will continue working on this and update this review when I get it done.





    Digilent Arty z7 board is a low cost, well designed and good quality development boards for Zynq-7000 SoC. It's very easy to use. Two HDMI ports makes it very suitable for video/vision applications. If Digilent provided more demo projects and kept them updated for the latest version of design tool, that would be more helpful for users.


Also Enrolling

Enrollment Closes: Sep 20 
Enrollment Closes: Sep 20 
Enrollment Closes: Oct 1 
Enrollment Closes: Oct 10 
Enrollment Closes: Oct 4