# PYNQ Tutorial 1: Board Setup and 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 board 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 with a capacity of 16 GB; **do not use** one that is 64 GB or larger (not supported)
- A MicroSD card reader (if your laptop doesn't have one) only needed once to flash the micro SD
## Required Software
Download and install the following software tools:
- Vivado 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
## 1. FPGA Setup
### Video Tutorial
:::info
If you prefer a video tutorial version, check out this one:
***Everything you need to get started with the PYNQ-Z1 FPGA***
https://youtu.be/X74T3C9YbgE?si=J1tIvihO7oQC1Lb4
:::
### 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.

### 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.
- Insert MicroSD to your board.
- Make sure the boot jumper is set to SD.
- Make sure the power supply jumper is correct, either USB or external adaptor.
- 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**.

- Wait until the boot process is complete.

- 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**

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

- **[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
### Video Tutorial
:::info
If you prefer a video tutorial version, check out this one:
***First Vivado Design (GPIO) with the PYNQ-Z1 FPGA***
https://youtu.be/YaL-vvDcwbw?si=tfZtP-dc6VBhmDkh
:::
### 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**.

- **[IMPORTANT]** Select the folder where you want to create the project. **Do not use a read-only location** (usually the My Document in C: drive is read-only), and the **folder location must not have spaces**.

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

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

### 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.

- Give the block design name **design_1**.

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

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

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

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

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

- Checklist only **S_AXI**, then click **OK** to make the AXI GPIO connection.

- 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**.

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

- Click **OK** to generate.

### 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.

- 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.

- 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.

- 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.

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

### 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.

- Export to the default location and name it **design_1.tcl**.

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

- 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.

- 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_hand
```
- 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**

- **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**.

- 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.

### 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 Python code to test the design: https://github.com/yohanes-erwin/pemrograman_zynq/tree/main/pynq_part_1
- In this program, we write the value **168** to GPIO, and then the value is read back. **You can try with other values**.