Creating and building example Vivado project (BELK/BXELK)
Info Box
|
In this document, the Vivado installation path may be indicated as |
Contents
History[edit | edit source]
Version | Date | BELK/BXELK version | Notes |
---|---|---|---|
1.0.0 | November 2015 | 3.0.0 | First release |
2.0.0 | July 2017 | 3.0.0, 4.0.0 | Updates for BELK 4.0.0 / BXELK 2.0.0 |
September 2019 | 3.0.0, 4.0.0 | Clarified U-Boot rebuild requirement Added Downloading the bitstream to the device section | |
3.0.0 | December 2019 | 4.1.0, 2.1.0 |
Creating and building example Vivado project[edit | edit source]
BELK/BXELK provides an example Vivado project for BORA/BORAX/BORALITE boards. This project allows to:
- generate the PS configuration files to be used with U-boot SPL build
- generate the bitstream of a simple PL design used to route PS' CAN0 and UART0 signals through EMIO (see also the following pictures).
This article describes how two build this project. Two procedures are described, the former is command line based while the latter is GUI based.
The project is stored is a git repository, as described here.
It is assumed that the Zynq development environment has been set up properly (see this page for more details).
Command line based procedure[edit | edit source]
The following procedure make use of ambient variables to address all our boards.
For BoraLite SoM use:
For BoraX SoM use:
|
- start the Zynq development server and login into the system
- assuming that a local repository has not been created, clone the remote BORA git repository:
git clone git@git.dave.eu:dave/bora/bora.git
- copy the
<bora_repo>/boards/
directory to<vivado_install_dir>/data/boards/
cd <bora_repo> sudo cp -r boards/ /opt/Xilinx/Vivado/<Vivado_version>/data/
. /opt/Xilinx/Vivado/<Vivado_version>/settings64.sh vivado -mode tcl -source scripts/recreate_prj_${BASE_NAME}_BASE.tcl -notrace -tclargs "gen_bitstream"
- At the end of the bitstream build process, the
build_prj_*
script allows to automatically export hardware and lauch SDK. - The bitstream file is now present in
<bora_repo>/vivado/${BASE_NAME}.runs/impl_1/${BASE_NAME}_wrapper.bit
and<bora_repo>/vivado/${BASE_NAME}.runs/impl_1/${BASE_NAME}_wrapper.bin
. - By default FSBL is not used anymore in the boot process. U-Boot SPL (first-stage bootloader) is used instead. PS configuration files are used to build U-boot binaries.
- Copy the
ps7_init_gpl.c
andps7_init_gpl.h
source files into U-boot source code directory using the following command example for Bora:
- Copy the
cp <bora_repo>/bd/${BASE_NAME}/ip/${BASE_NAME}_processing_system7_0_0/ps7_init_gpl.* <U-boot_src_dir>/board/dave/bora/${UBOOT_PS7_DIR}/
- Follow U-boot build instructions to build U-boot using new PS configurations. Please note that the U-Boot binary images released along with BELK/BXELK were already built upon the
ps7_init_gpl.c
andps7_init_gpl.h
source files generated by the Vivado project described in this article. As such, it is not generally required to rebuild U-Boot.- The PS configurations are the same for Bora and BoraLite boards.
- Follow U-boot build instructions to build U-boot using new PS configurations. Please note that the U-Boot binary images released along with BELK/BXELK were already built upon the
GUI based procedure[edit | edit source]
The following procedure make use of ambient variables to address all our boards.
For BoraLite SoM use:
For BoraX SoM use:
|
- start the Zynq development server and login into the system
- assuming that a local repository has not been created, clone the remote BORA git repository:
git clone git@git.dave.eu:dave/bora/bora.git
- copy the
<bora_repo>/boards/
directory to<vivado_install_dir>/data/boards/
:
cd <bora_repo> sudo cp -r boards/ /opt/Xilinx/Vivado/<Vivado_version>/data/
- launch the Vivado Design Suite GUI with the following commands[c]:
. /opt/Xilinx/Vivado/201x.y/settings64.sh vivado
- from the start page click on Create New Project
- click Next
- select the directory build project, insert the name of the project <prj_name> and click Next
- select RTL Project, enable Do not specify sources at this time and click Next
- on the Default Part form, click on the Boards button to filter the available boards. Select ${BORA_SOM} and click Next
- check the summary page and click Finish
- For the block design there are two possible ways:
- Add the existing BD within the repo:
- select Add sources from the Flow Navigator
- click on Add or create design sources
- select Add Files and add
<bora_repo>/bd/${BASE_NAME}/${BASE_NAME}.bd
- check that the option Copy sources into project is disabled and click finish
- Create a new block design:
- click on Create Block Design from the Flow Navigator
- insert ${BASE_NAME} as Design name and click OK
- this creates a new block design. From the Diagram tab, add a new IP:
- click the Add IP side button, or
- click Add IP on the upper suggestions bar
- double click on ZYNQ7 Processing System
- this adds the IP that models the PL component of Zynq. Launch Run Block Automation from the upper suggestions bar
- check that Apply Board Preset is selected and click OK
- this applies the default settings for BORA/BORAX and creates the I/O ports for the DDR and MIO pins
- UART_0 and CAN_0 connections must be manually created:
- right-clicking on each port (where mouse cursor switch to pencil) and selecting Make External or with keyboard shortcut
Ctrl+T
. The name of the external ports must be UART_0 and CAN_0 respectively, otherwise correct manually
- right-clicking on each port (where mouse cursor switch to pencil) and selecting Make External or with keyboard shortcut
- manually connect the
FCLK_CLK0
signal toM_AXI_GP0_ACLK
and save the block design - from the sources tab, select the BORA block design
${BASE_NAME}.bd
as Design Sources and from the context menu select Create HDL Wrapper - on the next window, select Let Vivado menage wrapper and auto-update and click OK
- this creates the Verilog file
${BASE_NAME}_wrapper.v
. If this file is not automatically included in the project, add it using the Add sources option- select Add or create design sources and click Next
- select the
>${BASE_NAME}_wrapper.v
file from the<project_directory>/<prj_name>.srcs/sources_1/bd/${BASE_NAME}/hdl/
directory
- Add the existing BD within the repo:
- select Add sources and click on Add or create constraints
- select the
${BASE_NAME}_pinout.xdc
and${BASE_NAME}_timings.xdc
files from theconstr
directory of the BORA repository - check that the option Copy constraints files into project is disabled and click finish
- create the synthesis, implementation and bitstream clicking Generate Bitstream from the Flow Navigator and wait the completion of the operation
- once completed, select Open Implemented Design
- create the binary bitstream running the tcl script provided with the BORA repository. Launch Tools -> Run Tcl Script
- select the
generate_binary_bitstream.tcl
file from thescripts
directory from the BORA repository - The bitstream file is now present in
<project_directory>/<prj_name>.runs/impl_1/${BASE_NAME}_wrapper.bit
and<project_directory>/<prj_name>.runs/impl_1/${BASE_NAME}_wrapper.bin
. - Copy the
ps7_init_gpl.c
andps7_init_gpl.h
source files into U-boot source code directory using the following command example for Bora:
cp <project_directory>/<prj_name>.srcs/sources_1/bd/${BASE_NAME}/ip/<prj_name>_processing_system7_0_0/ps7_init_gpl.* <U-boot_src_dir>/board/dave/bora/${UBOOT_PS7_DIR}/
Follow U-boot build instructions to build U-boot using new PS configurations. Please note that the U-Boot binary images released along with BELK/BXELK were already built upon theps7_init_gpl.c
andps7_init_gpl.h
source files generated by the Vivado project described in this article. As such, it is not generally required to rebuild U-Boot.
- ↑ In a 32 bit system, Vivado settings are configured with the following command
/opt/Xilinx/Vivado/<Vivado_version>/settings32.sh
- ↑ Passing the -tclargs "gen_bitstream" parameters allows for automatic building of the FPGA bitstream.
- ↑ In a 32 bit system, Vivado settings are configured with the following command
/opt/Xilinx/Vivado/201x.y/settings32.sh
Downloading the bitstream to the device[edit | edit source]
Once the bitstream is ready, U-Boot itself can be used to download it onto the device. There are other options, however. For more details, please refer to this section.
Helloworld from UART0[edit | edit source]
Using the FPGA bitstream previously created, it is possible to use serial tty port on Linux. The serial port is mapped to /dev/ttyPS1
(this is because /dev/ttyPS0
is the console mapped to UART1).
Here below an example on C code for initializing and using UART0 through FPGA:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <fcntl.h> #include <termios.h> int set_interface_attribs (int fd, int speed, int parity) { struct termios tty; memset (&tty, 0, sizeof tty); if (tcgetattr (fd, &tty) != 0) { printf("error %d from tcgetattr", errno); return -1; } cfsetospeed (&tty, speed); cfsetispeed (&tty, speed); tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars // disable IGNBRK for mismatched speed tests; otherwise receive break // as \000 chars tty.c_iflag &= ~IGNBRK; // disable break processing tty.c_lflag = 0; // no signaling chars, no echo, // no canonical processing tty.c_oflag = 0; // no remapping, no delays tty.c_cc[VMIN] = 0; // read doesn't block tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls, // enable reading tty.c_cflag &= ~(PARENB | PARODD); // shut off parity tty.c_cflag |= parity; tty.c_cflag &= ~CSTOPB; tty.c_cflag &= ~CRTSCTS; if (tcsetattr (fd, TCSANOW, &tty) != 0) { printf("error %d from tcsetattr", errno); return -1; } return 0; } int main() { int fd; char *portname = "/dev/ttyPS1"; char msg[] = "Hello World from BELK (FPGA PS0 UART)!\n\r"; fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC); if (fd < 0) { printf("error %d opening %s: %s", errno, portname, strerror (errno)); exit(1); } printf(msg); set_interface_attribs (fd, B115200, 0); // set speed to 115,200 bps, 8n1 (no parity) write(fd, msg, strlen(msg)); exit(0); }
and then compile it:
dvdk@vagrant:~/bora/rfs/belk/home/root$ source ~/env.sh dvdk@vagrant:~/bora/rfs/belk/home/root$ $CC hello_UART0.c -o hello_UART0
The program executed print out the msg string on the serial console and on /dev/ttyPS1
port.