0% found this document useful (0 votes)
42 views21 pages

1 Objectives: EA-268 Digital Signal Processors Prof. Dr. Osamu Saotome Teaching Assistant: Canisio Barth

This document describes a laboratory exercise for a digital signal processing course. The lab aims to introduce students to designing embedded systems using Vivado and Vitis tools. It guides students through creating a hardware platform in Vivado with a Zynq processor connected to GPIO peripherals. The design is then exported to Vitis to create a software project to control the peripherals.

Uploaded by

Júlio Cortês
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
42 views21 pages

1 Objectives: EA-268 Digital Signal Processors Prof. Dr. Osamu Saotome Teaching Assistant: Canisio Barth

This document describes a laboratory exercise for a digital signal processing course. The lab aims to introduce students to designing embedded systems using Vivado and Vitis tools. It guides students through creating a hardware platform in Vivado with a Zynq processor connected to GPIO peripherals. The design is then exported to Vitis to create a software project to control the peripherals.

Uploaded by

Júlio Cortês
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 21

Aeronautics Institute of Technology – ITA

Electronic Engineering Division – IEE

EA-268 Digital Signal Processors


Prof. Dr. Osamu Saotome
Teaching assistant: Canisio Barth
Laboratory 02P2
Last document update: March 23, 2024

1 Objectives
1.1 General Objectives
• Practice applying theoretical concepts covered in the Digital Signal Processors course (EA-268).

1.2 Specific Objectives


• This lab will guide you through the process of setting up a SoC project with Vivado and Vitis for
Baremetal Software Projects.
• We’ll introduce the "Block Design" flow in Vivado to create a simple hardware design featuring a
processor connected to several AXI GPIO peripherals. The "Block Design" flow is a commonly used
method for designing complex embedded systems.

• The design will be exported to the Vitis IDE, where we’ll create and execute a bare-metal soft-
ware project to control the AXI peripherals, providing hands-on experience with hardware-software
interaction.
Note: The lab is based on a tutorials by Digilent for Zedboard, accessible at Guides for Xilinx
Tools. The appearance of images may vary depending on the version of the tools and the board
being used. For a more thorough guide, please visit Vivado Design Suite User Guide: Getting
Started (UG910)

2 Prerequisites
• Personal computer with a minimum of 8GB RAM (16GB recommended);
• VirtualBox software. Download and documentation available at the following link:VirtualBox;

• Ubuntu virtual machine (VM) on VirtualBox with Xilinx tools installed (version 2019.2 or later).
A clone of the VM will be provided. Use the following credentials:
– user: osboxes
– password: osboxes.org

• ZedBoard Development kit including required hardware accessories (power supply, JTAG cable).
Additional resources for the ZedBoard (files, documentation, schematics, tutorials, example projects)
can be found in the following link ZedBoard. Similar boards can also be used.
• Basic understanding of the C programming language.

• Completion of Part 1 of the lab.

3 Lab Development (Part A): Hardware Platform


This part of the lab focuses on designing and configuring the hardware components for the embedded
SoC system using Vivado. The hardware components of a Xilinx embedded design are also known as the
"Hardware Platform". For more information, access Vivado Design Suite User Guide: Getting Started
(UG910)

1
3.1 Create Lab Folder and Launch Vivado
1. Open the terminal application and change directory (cd) to the workspace folder:
1 cd / home / osboxes / Workspace /

Note: If you’re currently on the user’s home screen, simply type "cd Workspace". Use TAB key to
auto complete.
2. Create a folder for the lab and cd to it:
1 mkdir Lab02P2
2 cd Lab02P2

3. Create one more folder for the hardware project and cd to it:
1 mkdir hw
2 cd hw

This next level of folder structure will aid in organization since we will have two distinct projects:
one for the hardware platform (Vivado) and one for the software components (Vitis).
4. Source the settings for the AMD/Xilinx tools:
1 source < install_path >/ Vivado / < version >/ settings64 . sh

Tip: The installation path for the VM is /tools/Xilinx/. Additionally, an alias command has
been set up for this lab as a shortcut. Simply type "xilinx" on the terminal and the shortcut will
handle all the necessary tasks.
5. Launch Vivado with the following command:
1 vivado

3.2 Create Vivado Project


The steps for creating the Vivado project are identical to those outlined in Part 1 of the lab, please refer
to the previous labs for more detailed instructions.

1. From the Vivado welcome screen, click on Create Project. The first page of the New Project
wizard summarizes the steps involved in creating a project. Click Next. The page for selecting
project name and location should appear.
2. Specify a name for the project. Vivado will utilize this name to structure its folders.
Note: Avoid spaces in the project name or location path as this may lead to issues with Vivado.
Instead, utilize an underscore, a dash, or CamelCase.
3. Keep the project location unchanged and select the "Create project subdirectory" option, this will
add another level to the folder structure, useful for the exercises section. Proceed by clicking Next.
4. At the "Project Type" screen, choose RTL Project and check the "Do not specify sources at this
time" box. Click Next to continue.

5. Click on the Boards tab and locate the ZedBoard Zynq Evaluation and Development Kit
from the provided list. Click Next to proceed to the last step.
6. The final screen of the "New Project" wizard provides a summary of your selections made in the
previous steps. Click Finish to open your project.

2
3.3 Create a Block Design
In Vivado, a "Block Design", also known as "IP Integrator", refers to a graphical approach for design-
ing FPGA-based systems, as opposed to traditional Hardware Description Language (HDL) methods.
With Block Design, users can visually construct their designs by dragging and dropping pre-designed
Intellectual Property (IP) cores and connecting them together using a graphical interface. This method
abstracts away much of the low-level coding required in HDL, making it accessible to designers with var-
ied experience levels. It enables faster iteration, simpler debugging, and promotes collaboration among
team members with differing FPGA design expertise. Moreover, it offers a higher level of abstraction,
allowing designers to concentrate on system functionality rather than low-level implementation specifics.
1. Click the Create Block Design button in the IP Integrator dropdown of Vivado’s "Flow Navigator"
pane.

2. In the dialog that appears, name your block design (or use the default "design_1"). Do not use
spaces in the block design name. Leave the other two fields as defaults. Click OK to proceed.

3
3.4 Add a Zynq Processor to the Block Design
The Zynq7 Processing System IP represents the non-FPGA components of a Zynq chip, referred to as
the Processing System, or PS. It must be used in a block design that wants to connect anything to the
processor, and to configure PS-side peripherals, clocks, and other settings. This IP creates a wrapper
that acts as a logic connection between the PS and the PL. More information on Zynq 7000 Processing
System IP.

1. In the block diagram pane’s toolbar, click the Add IP button .


2. In the pop up, search for and double click on ZYNQ7 Processing System.

3. Click "Run Block Automation" in the Design Assistance banner (the green bar).

4
4. In the dialog that pops up, leave all settings as defaults. Apply Board Preset should be checked.

This makes the proper external connections for the top level of the design and automates several
common tasks related to the Zynq 7000 processor and the Zedboard.

5
5. Explore Zynq configuration. For this lab, we will use the default settings. However, your project’s
requirements might necessitate changes to some of the Zynq PS features. To modify its settings,
double-click on it to open the configuration wizard. Through the wizard, you can modify various
settings of the PS, including:

• Enable/Disable I/O Peripherals (IOP)


• Enable/Disable AXI I/O ports (AIO)
• MIO Configuration

• Extended MULTIPLE USE I/Os (EMIO)


• DDR Configuration
• Security and Isolation Configuration
• Interconnect Logic for Vivado IP - PS interface

• PL Clocks and Interrupts

3.5 Add Peripherals to a Block Design


This section covers the steps involved in adding a GPIO peripheral to a block design. While the AXI
GPIO IP is used, other IPs and interfaces can potentially be added to your design in the same way. We
will take advantage of board files to automatically generate constraints; however, an IP interface can be
connected to chosen pins manually, as we did in Part 1 of the lab.
1. Interfaces for Digilent boards supported by the board files can be found in the "Board" tab to the
left of the diagram. Locate the GPIO section of the list, right-click on an LED interface, and select
the "Connect Board Interface" option.

2. In the dialog that pops up, select the "GPIO" interface (not GPIO2) of a new AXI GPIO IP. Click
OK to proceed. This action will incorporate the IP into your design and connect it to an external
port, eliminating the need for any additional constraint work.

6
Note: The Advanced eXtensible Interface (AXI) is a widely used standard for interconnecting
functional blocks in System-on-Chip (SoC) designs. It provides a high-performance, low-latency,
and scalable interface for communication between different IP modules within an SoC. AXI is part
of the ARM Advanced Microcontroller Bus Architecture (AMBA) specification and is commonly
found in ARM-based designs
3. Next, click on the "axi_gpio_0" block on the Diagram. In the "Block Properties" pane to the left of
the Diagram and below the "Board" tab, you can view information about the block and make modifi-
cations without running through its customization wizard. Change its name to “AXI_GPIO_LED”
by typing in the "Name" field. Press Enter or click out of the text box to confirm the change. Using
memorable names in your block design simplifies later software development in Vitis.

4. Repeat steps 1 through 3, but this time, add the "Push buttons" of the ZedBoard. Rename the
newly add block as "AXI_GPIO_BUTTONS". Do not connect to "GPIO2" of theleds, use the
"Create New IP" option.
Note: If your project involves a custom peripheral (not available on the "boards" tab), you can add
the respective block to the design. Then, select the appropriate interface and utilize the "make it
external" option. This will expose the I/O to the top level of the design. Additionally, you’ll need
to add and edit the XDC master constraints file, as demnostranted in Part 1.
5. Finally, the two AXI GPIO IP blocks need to be connected to the processor in your design. Click
the "Run Connection Automation" button in the green Designer Assistance bar.

7

6. In the dialog that pops up, make sure that the boxes for the S_AXI interfaces for both of the AXI
GPIO IPs are checked. Click OK to run connection automation and connect the AXI GPIO blocks
to your processor.

3.6 The Address Editor


The "Address Editor" tool allows users to manage memory-mapped address assignments within
their design, enabling communication between memory-mapped devices in the Programmable Logic
(PL) and the Processing System (PS) via memory regions. Users can assign addresses to various
peripherals, configure address ranges, ensure proper alignment within memory space, and prevent
address overlaps between different segments.

• Vivado attempts to automatically assign addresses to peripherals. However, if it doesn’t or


if your project demands specific customization, you can access the "Address Editor" from its
tab in the Diagram pane. Assign addresses to unmapped peripherals by entering the desired
address into the peripheral’s Master Base Address column.

8
Note that addresses must align within the memory space. For example, an address with a 4K range
occupies a range of 0x1000 addresses, requiring three trailing zeros. Avoid overlapping address
ranges for different segments. Assigning segment 0 to address 0 may trigger assertions in certain
software drivers and should be avoided.

3.7 Validate Block Design


Before the Vivado project can be built, the block design must be validated. This step runs an automatic
check of the block design to see if there are any potential issues with it.

1. Click the "Validate Design button" in the Diagram pane’s toolbar (or press the F6 key).
2. If the design has issues, a dialog will pop up that lists them. For this lab, most "Warnings" can be
ignored, as can some "Critical Warnings". These issues can also be viewed in the "Messages" tab of
the pane at the bottom of the window. If there are no issues, a dialog will pop up to inform you
accordingly. Click OK to continue.

3.8 Create HDL Wrapper


An "HDL wrapper" must be created for the block design. This process translates the block design into a
source file that can be read by the Vivado tools, and is used to build the actual design.
1. Open the "Sources" pane and locate the block design file (.bd) under the Design Sources dropdown.
Right click on it and select "Create HDL Wrapper".

9
2. In the dialog that pops up, you can decide whether to let Vivado edit the wrapper file itself. "Let
Vivado manage wrapper and auto-update" is recommended, as a user rarely needs to manually edit
the wrapper file. Click OK to continue.

3.9 Build a Vivado Project


At this point, the Vivado Project is ready to be built by running it through "Synthesis" and "Implemen-
tation", and finally generating a bitstream, as demonstrated in detail in Part 1 of this lab.

1. Click the Generate Bitstream button in the "Program and Debug" section of the "Flow Navigator"
pane at the left side of the window.

3.10 Export a Hardware Platform


Once the project has been built, the design must be exported from Vivado so that Vitis has access to
information about the hardware that a software application is being developed for. This includes the set
of IP connected to the processor, their drivers, their addresses, and more. Exporting hardware after the
bitstream has been generated allows you to program your board directly from within Vitis.

1. To export the hardware design, click "Export > Export Hardware" in the File menu.

10
2. The wizard’s first screen appears, providing information about what you can do with the exported
platform. Click Next to continue.
3. The "Output" screen lets you choose to export either only the hardware specification (Pre-synthesis)
or include the bitstream. Including the bitstream is recommended as it allows Vitis to automatically
locate it for board programming. Select "Include bitstream" and proceed by clicking Next.
4. The Files screen allows you to name the Xilinx Shell Architecture (XSA) file and specify the folder
where it will be saved. It’s recommended to leave the default settings, but if you prefer, you can
choose a descriptive name and a memorable location. Do not use spaces in the file name or export
path; instead, use underscores or camelCase. Remember the file’s location and name for later
importation into Vitis. Click Next to proceed.
5. The final screen of the wizard summarizes the options you selected. Click Finish to export the
hardware platform.

4 Lab Development (Part B): Baremetal Software Platform


This section of the lab guides you through the creation of the software components of the embedded
design. Xilinx offers a bare metal software stack known as the Standalone Board Support Package (BSP)
within the Vitis software suite. Unlike a full stack OS (such as Linux), the Standalone BSP offers a
straightforward, single-threaded environment with basic features like standard input/output and access
to processor hardware functionalities. The BSP and its libraries are configurable to provide the necessary
functionality with minimal overhead. More information on Zynq 7000 SoC Software Developers Guide
(UG821)

11
4.1 Create the Software Folder and Launch Vitis
1. Open the terminal application and change directory (cd) to the Lab02P2folder:
1 cd / home / osboxes / Workspace / Lab02P2

2. Create a folder for the software project and cd to it:


1 mkdir sw
2 cd sw

3. Source the settings for the AMD/Xilinx tools:


1 source < install_path >/ Vivado / < version >/ settings64 . sh

Tip: The installation path for the VM is /tools/Xilinx/. You can use the "xilinx" shortcut.
4. Launch Vitis with the following command:
1 vitis

Note: If Vivado is open, Vitis can also be launched through the "Tools > Launch Vitis" toolbar
option.
5. When starting Vitis, you’ll need to choose a workspace, which is where all project files will be
stored. If the chosen folder doesn’t exist, Vitis will create it. Use the "sw" folder as the workspace
and click "Launch" to finish starting Vitis.

4.2 Create a New Application Project


With Vitis open, an application project must be created to hold your source files. In creating an ap-
plication project, a hardware platform will also be created from an XSA file previously exported from
Vivado.

1. Begin by selecting "Create Application Project" on the welcome screen of Vitis. This will initiate a
wizard that guides you through the creation and configuration of a new application.

12
2. Proceed to the first screen of the wizard, where you’ll find a welcome page providing an overview
of the various components involved in a software design. Click Next to proceed.

3. Now, you’ll need to create the platform that the application targets. Navigate to the "Create a new
platform from hardware (XSA)" tab.

13
4. Search through your file system to locate the XSA previously exported from Vivado. Once found,
select it and return to the "Platform" screen of the wizard by clicking Open.
5. After selecting the XSA file, ensure that it’s chosen in the Hardware Specification list. Additionally,
provide a name for your platform (the default name based on the XSA file will suffice). You can also
opt to generate boot components automatically, which is recommended for booting the application
from flash memory or an SD card. Click Next to proceed.

6. On the following screen, you can choose names for both the "Application project" and "System
project". You can also select which processor will run the application. For this lab, use "myApp"

14
as the Application project name; the "System project" name will be automatically filled. Leave the
target processor option as default and click Next to proceed.

7. Continue by defining the domain in which the application project operates. Default settings are
suitable for this purpose. Click Next to proceed.

8. Choose a template project. Each template configures the project for a specific purpose. Select
"Empty Application". Later, you’ll add an example source file instead of editing an existing one.
9. Finally, click Finish to complete the project creation process.

15
Note: If you want to develop another application running on the same platform, you don’t need
to create a Vitis project from scratch. Instead, you can add application projects to an existing
platform project by clicking on "File > New > Application Project...". Repeat the steps outlined
in Subsection 4.2 to create your new application.

4.3 Create a Main C Source to Control AXI GPIO Peripherals


An application needs source files to define its behavior. This step will show how to create a new source
file for the application, and provide some example code.

1. In Vitis’ Explorer pane, find the application projects “src” directory. Right click on it and select
"New > File".

2. In the new file, name the file “main.c”. The parent folder can be specified as well, but through the
use of the right click in the previous step, the correct folder has already been chosen.

16
3. Copy and paste the following code into the empty main.c file that has now been opened. Change
the "BTN_MASK" and "LED_MASK" macros so that they contain a number of 1’s equal to the
number of buttons and leds connected to the GPIO peripherals in the hardware design.
1 // Xilinx default includes for Zynq
2 # include " xparameters . h "
3 # include " xil_printf . h "
4 # include " xgpio . h "
5 # include " xil_types . h "
6

7 // Get device IDs from xparameters . h


8 # define BTN_ID X P A R _ A X I _ G P I O _ B U T T O N S _ D E V I C E _ I D
9 # define LED_ID X P A R _ A X I _ G P I O _ L E D _ D E V I C E _ I D
10

11 // Degfine constants
12 # define BTN_CHANNEL 1
13 # define LED_CHANNEL 1
14 # define BTN_MASK 0 b11111 // BTNU , BTNR , BTNL , BTND , BTNC
15 # define LED_MASK 0 b11111111 // LD0 is LSB
16

17 int main () {
18 XGpio_Config * cfg_ptr ;
19 XGpio led_device , btn_device ;
20 u32 btn_data , led_data ;
21

22 xil_printf ( " Starting test program ... \ r \ n " );


23

17
24

25 // Initialize LED Device


26 cfg_ptr = XG pi o_ Lo ok up Con fi g ( LED_ID );
27 X Gp i o _ Cf g I ni t i al i z e (& led_device , cfg_ptr , cfg_ptr - > BaseAddress );
28

29 // Initialize Button Device


30 cfg_ptr = XG pi o_ Lo ok up Con fi g ( BTN_ID );
31 X Gp i o _ Cf g I ni t i al i z e (& btn_device , cfg_ptr , cfg_ptr - > BaseAddress );
32

33 // Set Button Tristate ( input )


34 X G p i o _ S e t D a t a D i r e c t i o n (& btn_device , BTN_CHANNEL , BTN_MASK );
35

36 // Set Led Tristate ( output )


37 X G p i o _ S e t D a t a D i r e c t i o n (& led_device , LED_CHANNEL , 0);
38

39 while (1) {
40 btn_data = X Gp io _D is cr ete Re ad (& btn_device , BTN_CHANNEL );
41 btn_data &= BTN_MASK ;
42 if ( btn_data != 0) {
43 led_data = btn_data & LED_MASK ;
44 } else {
45 led_data = 0;
46 }
47 X G pi o _ Di s c re t e Wr i t e (& led_device , LED_CHANNEL , led_data );
48 }
49 }

4.4 Code information


1. Header Files
• xparameters.h is a file generated during the process of exporting a platform from Vivado.
It includes information on the hardware design, including addresses and some configuration
parameters for AXI IPs. This is used by the example code to find the device IDs that must
be passed to the GPIO drivers, so that they can look up the driver configuration required to
correctly initialize the GPIO devices.
• xil_printf.h gives access to the xil_printf function, which can be used to print to standard
output, and requires less memory space than the stdio library.
• xgpio.h gives access to the XGpio drivers, which are used to provide a standard API for
controlling AXI GPIO peripherals. Several functions from this API are used in the example,
including the GPIO reads, writes, and direction-setting calls.
• xil_types.h contains a variety of different C types. In this case, it is only used to get access
to the “u32” (unsigned 32-bit int) type, which is used in arguments to XGpio function calls.
2. Functions
• u32 XGpio_DiscreteRead (XGpio *InstancePtr, unsignedChannel) : This function
reads the state of "discretes" for the specified GPIO channel. It requires two parameters:
InstancePtr, a pointer to an XGpio instance to be worked on, and Channel, which specifies
the channel of the GPIO (1 or 2) to operate on. The function returns the current copy of the
"discretes" register.
• void XGpio_DiscreteWrite (XGpio *InstancePtr, unsignedChannel, u32 Mask) :
This function writes to the discretes register for the specified GPIO channel. Its parameters
include "InstancePtr", which is a pointer to an XGpio instance to be worked on, "Channel",
containing the channel of the GPIO (1 or 2) to operate on, and "Mask", the value to be written
to the discretes register.
Note: For detail about other functions used here, please visit Vitis Drivers API Documenta-
tion
3. What the Example Code Does: When the example is started, the message "Starting test program..."
is printed to a connected serial console. Following this, the AXI GPIO IPs and drivers are initialized.

18
The application then continuously loops, checking whether any buttons are pressed. If any, the
equivalent LED is set high. Otherwise, the LEDs are held low.

4.5 Build a Vitis Application


Once an application project has been set up and includes all necessary sources, it should be built.
1. To build the project and all of its dependencies, select the System Project in the Assistant pane,
and either click the Build button , or press Ctrl-B on your keyboard.

Note: There are three types of build targets in the Assistant pane, Platforms, Systems, and
Applications. Building the application will not trigger any other applications in the system to
be built, but will build the wrapper as a dependency. Building the platform will only build the
platform, as it has no dependencies. Building the system causes each application in the system, as
well as the platform, to be built.
2. This process may take several minutes to complete. When done, the Console tab at the bottom of
the window will display a “Build Finished” message.

4.6 Connect the Board


1. Plug the programming cable into the "PROG" interface of the ZedBoard via USB/micro USB.
2. Connect a second micro USB cable to the "UART" port of the ZedBoard, located on the top left
side.
3. Connect the external power supply and turn on the board.
4. Make sure that both of the devices are connected through the VirtualBox menu "Devices > USB"

19
4.7 Launch a Vitis Baremetal Software Application
Many applications require a connected serial console for viewing standard output. A serial terminal
application should be used for this purpose to connect to the board’s serial port.
1. To monitor the application through the console, use the following command in the VM Linux
terminal (the superuser password is required):
1 sudo picocom -b 115200 / dev / ttyACM0 -- echo

Note: The "ttyACM0" is the device address for the ZedBoard USB-Serial adapter and "115200" is
the default baud rate for Xilinx’s devices.
2. An initial screen should appear, waiting for the other end (board and app) to communicate.
3. In the "Explorer" pane at the left side of the screen, right click on the application or system project
that is to be run, and select "Run as > 1 Launch on Hardware (Single Application Debug)".

Note: Once the project has been run at least once, you can use the green run button in the
toolbar at the top of the screen to program the board instead.
4. Test the functionality of your design.

5 Exercises
1. Modify the hardware platform so that the Zynq processor can interact with the dip switches of the
ZedBoard. Hint: Update an Existing Vitis Platform’s Hardware Specification.
2. Modify the C source file so that every time the position of a dip switch is changed, the program
outputs the state of all switches. For example, if all switches are in the OFF position, and the user
moves SW0 to the ON position, the program prints to the serial console:

SW7 SW6 SW5 SW4 SW3 SW2 SW1 SW0


OFF OFF OFF OFF OFF OFF OFF ON

DIP Switch states

20
3. Create a new application project called "mySignals" in Vitis. Import the source files provided in the
"mySignals_src.zip" file. The included source code features a main application that can be utilized
to call functions for generating "test signals." The implementation for creating a rectangular pulse
test signal is already included. This test signal utilizes a data type of "int16," which is suitable
for hardware designs and embedded systems. Use the UART interface to evaluate the program by
generating rectangular pulses with various parameters.
4. Design a function to generate a new test signal of the "sinusoidal" type. This function should
accept the following parameters: sampling frequency in kHz, total signal duration in milliseconds,
sinusoidal frequency, and sinusoidal amplitude. The output array should be of type "int16".
Note: If you use the "math" C library, the "m" option needs to be specified in the "Libraries" in
the app’s C/C++ Build Settings. See ARM gcc settings.
5. Create a function capable of generating a sum of up to four sinusoids with diverse frequencies and
amplitudes. This enhancement allows for the simultaneous presence of multiple carriers in the
output. The output array should be of type "int16".

21

You might also like