The Arty-Z7 is a handy little development board for AMD's Zynq-7000 FPGA. The Zynq FPGA is an SoC (System on Chip) with an ARM-core processor physically built into the programmable logic (PL). This gives users the capabilities of both the ARM-core processor and the FPGA programmable logic.
The Arty-Z7 also has handy peripherals for hobbyists and industry professionals such as Ethernet, HDMI, PMOD, an Arduino header, USB, audio, buttons, LEDs, switches, etc.
This project walks through how to create a basic hardware design in Vivado that a user can develop bare-metal (no-OS) C/C++ applications for on the Arty-Z7, as well as how to create a basic Hello World C application in Vitis for it. This hardware design can also be used later in PetaLinux for creating a Linux OS to run on the Arty-Z7.
Note: this project uses Vivado/Vitis/PetaLinux version 2022.1, but should work for versions 2020.1 and later.
Create Vivado ProjectSource the Vivado tools to the environment and launch the GUI:
~$ source /tools/Xilinx/Vivado/2022.1/settings64.sh
~$ vivado
Select the option to create a new project. Give the project the desired title, directory location, specify whether the project is a Vitis extensible platform or not (if not sure, say no), and select the Arty-Z7 version board being targeted (there are two versions that have Zynq chips with different amounts of programmable logic: the Arty Z7-20 and Z7-10).
Once the new Vivado project populates, the first step is to create a block design to instantiate the Zynq processor in the design an hook it up properly to be able to boot.
Select Create Block Design from the Flow Navigator window and give it the desired file name.
The first thing to add to the block design is the Zynq PS IP to make the ARM processor available in the hardware design.
Run Block Automation to apply the Arty-Z7 board presets to the Zynq Processing System IP. This configures all of the connects that can't be changed by the user such as the peripherals on the Arty board routed to the Zynq's MIO pins (Ethernet, UART, etc.).
Because the Vivado project was targeted towards a specific FPGA development board, the Board tab of the block diagram will contain a list of peripherals on that via thanks to the board definition files.
Right-click on a given peripheral in Board tab and select the option to Connect Board Component (I started with the 4 buttons on the Arty board):
A pop-up window will provide a list of the available compatible IPs to connect the peripheral with. An AXI GPIO makes the most sense for the buttons in this case:
Connection Automation will appear to handle the AXI configuration between the GPIO and Zynq PS, but hold off on that until adding the IPs for the rest of the desired peripherals for now.
Use the Board tab to add the following peripherals (IPs to select to connect them with):
- 4 LEDs (AXI GPIO)
- 4 Push Buttons (Ch2 of 4 LEDs AXI GPIO)
- Shield Pins 0 thru 19 (AXI GPIO)
- Shield Pins 26 thru 41 (Ch2 of Shield Pins 0 thru 19 AXI GPIO)
- SPI connector J6 (AXI Quad SPI)
- System Clock (Clocking Wizard)
Select CLK_IN1 for the System Clock's Clocking Wizard.
Manually connect clk_in1 of the Clocking Wizard to FCLK_CLK0 of the Zynq PS IP. Then double-click the Clocking Wizard IP and make the following changes:
- Set clk_in1 to 100MHz
- Set clk_out1 to 10MHz
- Set reset to active low
At this point, run the Connection Automation. Change the the ext_spi_clk of the AXI Quad SPI to be sourced from clk_out1 from the Clocking Wizard, but leave the reset default options:
If you're familiar with with Zynq PS, you're probably wondering why I added a Clocking Wizard to supply the external SPI clock for the AXI Quad SPI instead of just enabling another PL clock output (FCLK_CLK1) from the Zynq PS. Well that is what I did at first, however I found that this caused timing violations with the DDR interface.
After the Connection Automation is complete, manually connect resetn of the Clocking Wizard to peripheral_aresetn[0:0] of the Processor System Reset (rst_ps7_0_100M). You have to wait to connect reset until after running Connection Automation, otherwise it causes the wrong configuration in Connection Automation.
The only thing left in the block design is to connect all of the peripherals' interrupt outputs to the Zynq PS. Double-click the Zynq PS and enable PL-PS interrupts by selecting Interrupts and enabling IRQ_F2P[15:0].
Add a Concat IP and make the following connections.
- Connect ip2intc_irpt of axi_quad_spi_0 to In0
- Connect ip2intc_irpt of axi_gpio_1 to In1
- Connect dout to IRQ_F2P of the Zynq PS
With the block design complete, validate it to verify there are not errors or critical warnings (validate is the checkbox icon in the diagram window), and save it. Then generate the block design by selecting Generate Block Design from the Flow Navigator window.
Create an HDL wrapper file to instantiate the block design in the project. Right-click on the block design file in the Sources window and select Create HDL Wrapper...
Select the option to allow for Vivado to auto-manage the HDL wrapper, and wait for the file to be generated.
With the design complete run synthesis, implementation (place & route), and generate a bitstream to program the Arty-Z7 with.
Select Run Synthesis from the Flow Navigator window. Vivado will prompt asking to run implementation when synthesis is complete, or the Synthesized Design can be opened to add pinouts, timing constraints, etc. prior to the place & route of the design on the Zynq chip. Implementation will also prompt upon completion to generate a bitstream or the Implemented Design can be opened to add pinouts, timing constraints, etc. after the place & route of the design on the Zynq chip.
Alternatively, if Generate Bitstream is selected from the Flow Navigator window without a current synthesis and implementation run, Vivado will automatically run synthesis and implementation before generating a bitstream.
Export HardwareTo develop software to run on the hardware design created in Vivado in either Vitis or PetaLinux, the hardware design needs to be exported in a compressed format (XSA).
Select File > Export > Export Hardware...
Specify the desired XSA file name and directory location. Also be sure to check the option to include the bitstream in the exported design.
Launch Vitis & Create WorkspaceFor software development of either bare-metal (no-OS/standalone) or Linux C/C++ applications, users can follow an Eclipse workflow in AMD's Vitis.
Vitis can be launched directly from Vivado by selecting Tools > Launch Vitis IDE:
In the new Vitis workspace select the option to create a new platform project. The platform project uses the hardware in the exported XSA file from Vivado to create the BSP for the software application.
Specify the desired platform project name and point it to the location of the exported XSA file from Vivado.
When the platform project initially generates, it will show as out-of-date because there are no build output files present. Run a quick build (ctrl+B).
With the platform project complete, select New > Application Project to create a new C/C++ application.
Select the platform created in the previous step and give the application the desired name. Since the platform project was created for the standalone domain (no-OS/bare-metal) it will be the only option as an OS.
The final window gives a list of application templates to use. Unless needing the specialized function on something like the Zynq FSBL or light-weight IP (lwIP), the Hello World template is a good starting point that I use regularly.
Once the application project generates, the main function is located in helloworld.c
, but you can delete this file and create your own main.c
if desired.
Once any software modifications are complete, build the application project by selecting the application name in the Explorer window and using the Build option from the toolbar or ctrl+B.
Launch Debug Run on Arty-Z7Vitis is an Eclipse-based IDE, so the regular debug method can be followed.
Connect the Arty-Z7 to the host PC via its PROG/UART port (microUSB). Right-click on the application name in the Explorer window and select Debug As > Launch Hardware (Single Application Debug).
Vitis will switch over to the Debug view and automatically set a breakpoint it will stop at the first line in main()
.
Vitis has a built in serial terminal you can use to see any output on the UART, or you can use your serial terminal application of choice.
Comments