> For the complete documentation index, see [llms.txt](https://weenslab.gitbook.io/pages/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://weenslab.gitbook.io/pages/fpga-tutorials/pynq-fpga-tutorial-101/part-1-gpio.md).

# Part 1: GPIO

## Objective

After you complete this tutorial, you should be able to:

* Install a Linux OS on a MicroSD card for the ZYNQ FPGA.
* Create a Hello World project for ZYNQ FPGA.

## Required Hardware

* A ZYNQ FPGA that supports PYNQ
* A USB micro cable
* An Ethernet cable (also a USB-to-Ethernet adapter if your laptop doesn't have Ethernet)
* A MicroSD card (16 GB)
* A MicroSD card reader

## Required Software

Download and install the following software tools:

* Vivado 2019.1 (tested) with board files installed
  * Retired Zybo, Zybo-Z7-10, Zybo-Z7-20: <https://github.com/Digilent/vivado-boards/tree/master>
  * PYNQ Z1, PYNQ Z2: <https://pynq.readthedocs.io/en/v2.6.1/overlay_design_methodology/board_settings.html>
* Win32DiskImager (<https://win32diskimager.org/>)
* PuTTY (<https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html>)
* WinSCP (<https://winscp.net/eng/index.php?>)

Download the PYNQ Linux OS image file depending on your FPGA board. Use the image v3.0.1.

* Retired Zybo, Zybo-Z7-10, Zybo-Z7-20: <https://github.com/nick-petrovsky/PYNQ-ZYBO>
* PYNQ Z1, PYNQ Z2, and others: <https://www.pynq.io/boards.html>

## Source Code

This repository contains all of the code required in order to follow this tutorial.

{% embed url="<https://github.com/weenslab/pynq101/tree/main>" %}

## 1. FPGA Setup

### 1.1. MicroSD Setup

In this step, you are going to install Linux OS on the MicroSD card. Follow these steps:

* Connect the MicroSD to the laptop via SD reader.
* Extract the Linux image file to your laptop to obtain the `.img` file.
* Open the **Win32DiskImager** program.
* Select your image file (the `.img` file).
* Make sure the selected device is the MicroSD card.
* Click **Write** to write to the MicroSD card. Wait until finished.
* Safety remove the MicroSD card and insert the MicroSD card into your FPGA board.

<figure><img src="https://4146991827-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIsb2SAYKLkGlVOGOY0EE%2Fuploads%2Fc4HTiM8ay5XBm01J50jz%2Fwin32-disk-imager.png?alt=media&amp;token=9b75989b-fc8d-4e40-bef8-952bda34b78d" alt=""><figcaption></figcaption></figure>

### 1.2. Boot the FPGA

In this step, your MicroSD should be ready and inserted into your FPGA. Follow these steps to boot the FPGA. In this example, I use the ZYBO board, but for other boards, it should be similar.

* Connect the **USB cable** and **Ethernet cable** to your laptop.
* Connect the **board's power supply** (or some boards can use power from the USB) and **turn on the switch power**.
* Open the **PuTTY program**, setup the **Serial line** according to the **COM port** on your laptop (every laptop may be different, open **Device Manager** to see your COM port) and **Speed 115200**. Then click **Open**.

<figure><img src="https://4146991827-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIsb2SAYKLkGlVOGOY0EE%2Fuploads%2FDdjE5a8pZs6PBdvRWjpW%2Fputty_zynq.png?alt=media&amp;token=f7a09e97-6650-49c9-8ed1-f1d2a0237983" alt=""><figcaption></figcaption></figure>

* Wait until the boot process is complete.

<figure><img src="https://4146991827-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIsb2SAYKLkGlVOGOY0EE%2Fuploads%2FkftMGPMaeGSwVbGeX1iQ%2Fpynq_boot_login.png?alt=media&amp;token=9cf01c47-ef25-454d-934e-ef8a8a6cad2a" alt=""><figcaption></figcaption></figure>

* Some boards are automatically logged in. But if your board is required to login, usually this is the credentials:
  * User ID: **xilinx**
  * Password: **xilinx**
* Setup your computer's IP address to the following:
  * IP address: **192.168.2.100**
  * Subnet mask: **255.255.255.0**

<figure><img src="https://4146991827-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIsb2SAYKLkGlVOGOY0EE%2Fuploads%2FLZtw3LtYSvQmd2zmecdI%2Fsetup_ip_address_windows.png?alt=media&amp;token=22b05b17-5f9f-4a3d-80bf-1ab309dbb99b" alt=""><figcaption></figcaption></figure>

* Open a web browser and enter the URL: **<http://192.168.2.99:9090>**. The Jupyter Notebook will be loaded. The password is **xilinx**.

<figure><img src="https://4146991827-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIsb2SAYKLkGlVOGOY0EE%2Fuploads%2FMMqHPot16XDT4Kcvggdo%2Fjupyter_web_page.png?alt=media&amp;token=e1bf7837-5d45-4594-ad99-1ce72abcdfdf" alt=""><figcaption></figcaption></figure>

* **\[IMPORTANT]** How to turn off the board? To prevent MicroSD card corruption, when turning off the board, perform a shutdown process with the command:

```
sudo shutdown -h now
```

* Wait until the FPGA board is completely shut down before turning off the board's power supply.

## 2. Hello World Project

### 2.1. Create Vivado Project

In this section, we are going to create a new Vivado project that consists of simple AXI GPIO IP.

* Open the Vivado program and create a new project from menu **File, Project, New**.

<figure><img src="https://4146991827-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIsb2SAYKLkGlVOGOY0EE%2Fuploads%2FWgv7gebtMRFT3idNZLNZ%2Fvivado_new_project.png?alt=media&amp;token=32bc91ff-f2d8-4aa6-96f9-bc6ba6129844" alt=""><figcaption></figcaption></figure>

* **\[IMPORTANT]** Select the folder where you want to create the project. **Do not use a read-only** location, and the **folder location must not have spaces**.

<figure><img src="https://4146991827-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIsb2SAYKLkGlVOGOY0EE%2Fuploads%2FOdlZtSTDGVmj7FugFDbq%2Fvivado_project_name.png?alt=media&amp;token=53f21e17-631f-42cb-976f-18a28e9cf22c" alt=""><figcaption></figcaption></figure>

* Select **Project Type** as **RTL Project**.

<figure><img src="https://4146991827-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIsb2SAYKLkGlVOGOY0EE%2Fuploads%2FpfXVgsm13fBoFL14vnGG%2Fvivado_project_type.png?alt=media&amp;token=546534c8-08e8-47f6-91ff-d567eeedabd1" alt=""><figcaption></figcaption></figure>

* Select **your FPGA board**. Then, click **Next**, and **Finish**.

<figure><img src="https://4146991827-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIsb2SAYKLkGlVOGOY0EE%2Fuploads%2Fd1pgwU5D8FmXkTsjchtx%2Fvivado_select_board.png?alt=media&amp;token=c06fadff-3f5d-4e6f-975e-5898f8ade2a6" alt=""><figcaption></figcaption></figure>

### 2.2. Create Block Design

At this point, you should be able to create a new project. The next step is to create a block design.

* On the left side (the **Flow Navigator**), select the **Create Block Design** menu.

<figure><img src="https://4146991827-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIsb2SAYKLkGlVOGOY0EE%2Fuploads%2F0oy8KGPXhwu0zMQX6wHc%2Fvivado_main.png?alt=media&amp;token=8d2a87c9-afcc-4f4f-ba53-9132b76378f0" alt=""><figcaption></figcaption></figure>

* Give the block design name **design\_1**.

<figure><img src="https://4146991827-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIsb2SAYKLkGlVOGOY0EE%2Fuploads%2FNrfIn5h6NN5O9BMxYAbq%2Fvivado_block_design_name.png?alt=media&amp;token=47988762-b3e2-4815-8cf8-f1f53f54531d" alt=""><figcaption></figcaption></figure>

* Click the **Add IP** button, then add the **ZYNQ7 Processing System** IP.

<figure><img src="https://4146991827-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIsb2SAYKLkGlVOGOY0EE%2Fuploads%2FMg1YvfR19qzAt8fr9Irn%2Fvivado_add_zynq.png?alt=media&amp;token=4e551673-c567-43ca-a1ac-9213b904e752" alt=""><figcaption></figcaption></figure>

* Click the **Run Block Automation** button to configure the ZYNQ7 Processing System IP based on the board library.

<figure><img src="https://4146991827-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIsb2SAYKLkGlVOGOY0EE%2Fuploads%2FPaAR6GndRahOs2JhfTVl%2Fvivado_run_block_automation.png?alt=media&amp;token=6e45d94f-f0c8-44a5-bd28-e9b308989146" alt=""><figcaption></figcaption></figure>

* Click **OK** on the Run Block Automation window.

<figure><img src="https://4146991827-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIsb2SAYKLkGlVOGOY0EE%2Fuploads%2FlAjxcy257vC9wovHkHWC%2Fvivado_run_block_automation_window.png?alt=media&amp;token=f72e67ca-8c1c-4b71-b3f0-55c4dcd7c63c" alt=""><figcaption></figcaption></figure>

* Click **Add IP**, then add the **AXI GPIO** IP.

<figure><img src="https://4146991827-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIsb2SAYKLkGlVOGOY0EE%2Fuploads%2FDtEbbN0gBrCRLMvN4KWm%2Fvivado_add_gpio.png?alt=media&amp;token=8050a591-0a96-450c-84cb-eca7aaf4b1ae" alt=""><figcaption></figcaption></figure>

* Click the **Run Connection Automation** menu to automatically connect the AXI GPIO IP to the Zynq IP.

<figure><img src="https://4146991827-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIsb2SAYKLkGlVOGOY0EE%2Fuploads%2FmhU5XnWfjEIpt8Y2OLQR%2Fvivado_run_connection_automation.png?alt=media&amp;token=77764d4f-5f77-4cac-8ea2-2a0d073ff008" alt=""><figcaption></figcaption></figure>

* Checklist only **S\_AXI**, then click **OK** to make the AXI GPIO connection.

<figure><img src="https://4146991827-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIsb2SAYKLkGlVOGOY0EE%2Fuploads%2FijthQSTBKEn70xV3UTgB%2Fvivado_run_connection_automation_window.png?alt=media&amp;token=a4ed0ef9-b5fc-4fbb-b4da-564299e57e9a" alt=""><figcaption></figcaption></figure>

* In the block design, **double-click the AXI GPIO** IP to configure it. Check the **All Outputs** option to configure the GPIO to be an output port. Then click **OK**.

<figure><img src="https://4146991827-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIsb2SAYKLkGlVOGOY0EE%2Fuploads%2Fm4Zf7415iXjRWF0rrP03%2Fvivado_gpio_config.png?alt=media&amp;token=7d3914af-363e-44ec-8210-9f6c7c142ac4" alt=""><figcaption></figcaption></figure>

* In the **Sources** section, **right-click on the design\_1** design block, then select the **Create HDL Wrapper** menu.

<figure><img src="https://4146991827-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIsb2SAYKLkGlVOGOY0EE%2Fuploads%2FPIQWqS9PTIQEN9mwpqaj%2Fvivado_create_hdl_wrapper.png?alt=media&amp;token=33637824-556b-4549-9439-adbba5c8b8c4" alt=""><figcaption></figcaption></figure>

* Click **OK** to generate.

<figure><img src="https://4146991827-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIsb2SAYKLkGlVOGOY0EE%2Fuploads%2F9zWEIZxnE0KBimfsFyBG%2Fvivado_create_hdl_wrapper_window.png?alt=media&amp;token=814b4141-bcd0-4915-84f4-987dbc21242a" alt=""><figcaption></figcaption></figure>

### 2.3. Compile the System

In this section, we are going to compile the design.

* On the left side (the **Flow Navigator**), select the **Generate Block Design** menu. In the **Synthesis Options** section, select the **Global** option. In the **Run Settings** section, **Number of jobs** is the setting for how many CPU cores are used to perform this process. The more, the faster the process will finish.

<figure><img src="https://4146991827-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIsb2SAYKLkGlVOGOY0EE%2Fuploads%2F8eit0AYcDKnVmv5ar4D5%2Fvivado_generate_block_design.png?alt=media&amp;token=8bda732f-73d7-4e2f-8baa-0f21b9096b3b" alt=""><figcaption></figcaption></figure>

* On the left side (the **Flow Navigator**), select the **Run Synthesis** menu. Configure the **Number of jobs**, and then click **OK**. Wait until the synthesis is complete.

<figure><img src="https://4146991827-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIsb2SAYKLkGlVOGOY0EE%2Fuploads%2FW7QF6o200U5ZP4BFwFHr%2Fvivado_synth_config.png?alt=media&amp;token=4d9dc0aa-c4ab-470b-8720-89fd3c3e6914" alt=""><figcaption></figcaption></figure>

* A window will appear after the synthesis process is complete. Next, click **OK** to run the **Run Implementation** process. Configure the **Number of jobs**, and then click **OK**. Wait until the implementation is complete.

<figure><img src="https://4146991827-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIsb2SAYKLkGlVOGOY0EE%2Fuploads%2F1EO5urh9Zg5V1Ybajc2s%2Fvivado_synth_complete.png?alt=media&amp;token=13243481-3ca1-4b1e-9a3b-8acf8e4e69c4" alt=""><figcaption></figcaption></figure>

* A window will appear after the implementation process is complete. Next, select the **Generate Bitstream** option and click **OK**. Configure the **Number of jobs**, and then click **OK**. Wait until the generate bitstream is complete.

<figure><img src="https://4146991827-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIsb2SAYKLkGlVOGOY0EE%2Fuploads%2FdLTTgTU57TMh3aXaVC97%2Fvivado_impl_complete.png?alt=media&amp;token=1ad23fda-8afe-4ac7-85ae-fdbcef0e4159" alt=""><figcaption></figcaption></figure>

* A window will appear after the generate bitstream process is complete. Close this window.

<figure><img src="https://4146991827-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIsb2SAYKLkGlVOGOY0EE%2Fuploads%2F0RldNiSkQjcIHRzgHcQU%2Fvivado_bitstream_complete.png?alt=media&amp;token=3ad3087b-25d9-4b03-b62d-b2b14cfd5d18" alt=""><figcaption></figcaption></figure>

### 2.4. Export the Compiled Files

At this point, your design is already compiled. The next step is to program the FPGA and test the design.

* Export the block design file from the **File**, **Export**, **Export Block Design** menu.

<figure><img src="https://4146991827-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIsb2SAYKLkGlVOGOY0EE%2Fuploads%2FVdVSNIVAm8upSyqhJvid%2Fvivado_export_block_design.png?alt=media&amp;token=7dbaa3d4-b2f1-42c1-b799-0b8330aae700" alt=""><figcaption></figcaption></figure>

* Export to the default location and name it **design\_1.tcl**.

<figure><img src="https://4146991827-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIsb2SAYKLkGlVOGOY0EE%2Fuploads%2FgXYahgc85P0tU2BczTk6%2Fvivado_export_block_design_location.png?alt=media&amp;token=8149e5bb-7a40-4c13-bf57-6231504e3e09" alt=""><figcaption></figcaption></figure>

* Export the bitstream file from the **File**, **Export**, **Export Bitstream File** menu.

<figure><img src="https://4146991827-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIsb2SAYKLkGlVOGOY0EE%2Fuploads%2FUSixE6xcUX3HDFu1cjmA%2Fvivado_export_bitstream.png?alt=media&amp;token=759f680c-4287-474c-95a8-d5df93208b8d" alt=""><figcaption></figcaption></figure>

* Export to the same location as the block design and name it **design\_1.bit**. This name must be the same as the name of the block design.

<figure><img src="https://4146991827-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIsb2SAYKLkGlVOGOY0EE%2Fuploads%2FuUYKujjU3dSWjzqkTSPv%2Fvivado_export_bitstream_location.png?alt=media&amp;token=3c4c798f-bb4e-4687-a6fe-658065f57502" alt=""><figcaption></figcaption></figure>

* Using **Windows Explorer**, go into the following project folder. Then you will find the **design\_1.hwh** file.

```
<YOUR_PROJECT_LOCATION>\part_1\part_1.srcs\sources_1\bd\design_1\hw_handoff
```

* Move the design\_1.hwh file to the main project folder. So, there will be three files:
  * **design\_1.tcl**
  * **design\_1.bit**
  * **design\_1.hwh**

<figure><img src="https://4146991827-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIsb2SAYKLkGlVOGOY0EE%2Fuploads%2FD8gVvm4m5sWC7iPknhDx%2Fvivado_exported_files.png?alt=media&amp;token=2208d7d1-758f-4357-bc42-abbd929b8e9c" alt=""><figcaption></figcaption></figure>

* **Power on the board** as in the previous FPGA boot procedure. Open **WinSCP** program, then connect it to the FPGA board. Open WinSCP and enter **Hostname: 192.168.2.99,** **User name: xilinx,** **Password: xilinx**.

<figure><img src="https://4146991827-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIsb2SAYKLkGlVOGOY0EE%2Fuploads%2FrSVDpRywyThvTWazzi8u%2Fvivado_winscp_upload.png?alt=media&amp;token=a066fb1d-8161-4754-bf07-9be8149a9dea" alt=""><figcaption></figcaption></figure>

* On the left side, navigate to the Vivado project folder location. You will see the **three required files**. Then, **drag and drop** the three files from left to right to upload.

<figure><img src="https://4146991827-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIsb2SAYKLkGlVOGOY0EE%2Fuploads%2FfQllvrLGoMFrbEk6OwCe%2Fvivado_winscp_upload.png?alt=media&amp;token=bb0d6e14-6929-4736-bd48-f3eba46cb056" alt=""><figcaption></figcaption></figure>

### 2.5. Test the Design

At this point, the required files to program the FPGA are already on the board. The next step is to create Jupyter Notebook files.

* Open a web browser and open **Jupyter Notebook** on the board. Create a new file from menu **New**, **Python 3 (pykernel)**.
* Write the following code to test the design.

{% embed url="<https://gist.github.com/weenslab/90609aade5b74d4017b70e7e3c422f19>" %}

* In this program, we write the value 168 to GPIO, and then the value is read back. You can try with other values.
