Open main menu

DAVE Developer's Wiki β

Changes

Creating and building example Vivado project (BELK/BXELK)

12,376 bytes added, 13:22, 12 May 2022
Helloworld from UART0
The following sections describe how to perform {{InfoBoxTop}}{{Applies To Bora}}{{Applies To BoraX}}{{Applies To BoraLite}}{{InfoBoxBottom}} {{ImportantMessage|text=In this document, the Vivado installation path may be indicated as <code>vivado_201x.y</code>. Just replace <code>x</code> and <code>y</code> with the most common tasks for building actual numbers of your version. For instance, use the software components string <code>vivado_2014.4</code> if you are working with Vivado 2014.4.}}  == History =={| class="wikitable" border="1"!Version!Date!BELK/BXELK version!Notes|-|1.0.0|November 2015|[[Bora_Embedded_Linux_Kit_(BELK)#BELK_software_components|3.0.0]]|First release|-|2.0.0|July 2017|[[Bora_Embedded_Linux_Kit_(BELK)#BELK_software_components|3.0.0, 4.0.0]]|Updates for a BORABELK 4.0.0 /BORAXBXELK 2.0.0|-|{{oldid|9008|2.0.1}}|September 2019|[[Bora_Embedded_Linux_Kit_(BELK)#BELK_software_components|3.0.0, 4.0.0]]|Clarified U-Boot rebuild requirement<br>Added ''Downloading the bitstream to the device'' section|-based embedded system|3.0.0|December 2019|[[Bora_Embedded_Linux_Kit_(BELK)#BELK_software_components|4.1.0, 2.1.0]]||-|} <section begin=BELK/>==Creating and building example Vivado project==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 Zynq simple PL design used to route PS' CAN0 and UART0 signals through EMIO (see also the following pictures).  [[File:Belk-default-vivado-project for .png|thumb|center|400px|Block diagram of BORA using example project]][[File:Belk-borax-default-vivado-project.png|thumb|center|400px|Block diagram of BORAX example project]][[File:Boralite-default-vivado-project.png|thumb|center|400px|Block diagram of BORALITE example project]] This article describes how two build this project. Two procedures are described, the former is command linebased while the latter is GUI based. The project is stored is a git repository, as described [[BORA_SOM/BELK-L/Development/Build_system#Setting_up_the_Zynq_development_server_environment|here]]. It is assumed that the Zynq development environment has been set up properly (see [[BORA_SOM/BELK-L/Development/Build_system|this page]] for more details). ===Command line based procedure==={{ImportantMessage|text=The following procedure make use of ambient variables to address all our boards.<br>Define the correct ones according the target SoM.<br>For Bora SoM use:*<code>export BASE_NAME=bora</code>*<code>export UBOOT_PS7_DIR=bora</code>For BoraLite SoM use:*<code>export BASE_NAME=boralite</code>*<code>export UBOOT_PS7_DIR=bora</code>For BoraX SoM use:*<code>export BASE_NAME=borax</code>*<code>export UBOOT_PS7_DIR=borax</code>}}  
*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:
*:<code>git clone git@git.dave.eu:dave/bora/bora.git</code>
*copy the <code><bora_repo>/boards/board_parts/zynq/BELK_2.2.0</code> directory to <code><vivado_2014.4_install_dirvivado_install_dir>/data/boards/board_parts/zynq/</code> :
<pre>
cd <bora_repo>
sudo cp -r boards/board_parts/zynq/BELK_2.2.0 /opt/Xilinx/Vivado/2014.4<Vivado_version>/data/boards/board_parts/zynq/
</pre>
*enter launch the Vivado Design Suite with the git directory and launch following commands{{efn|In a 32 bit system, Vivado settings are configured with the following command*:<code>export PROJ_DIR=$(pwd)/opt/Xilinx/Vivado/<Vivado_version>/settings32../bora-build-YYYYMMDD-nobksh</code>*launch }}{{efn|Passing the Vivado Design Suite with -tclargs "gen_bitstream" parameters allows for automatic building of the following commandsFPGA bitstream.}}:
<pre>
. /opt/Xilinx/Vivado/2014.4<Vivado_version>/settings64.sh1shvivado -mode tcl -source build_projectscripts/recreate_prj_${BASE_NAME}_BASE.tcl -notrace -tclargs "-bitstreamgen_bitstream"
</pre>
*At the end of the bitstream build process, the <code>build_prj_*</code> script allows to automatically export hardware and lauch SDK.
*The bitstream file is now present in <code><bora_repo>/vivado/${BASE_NAME}.runs/impl_1/${BASE_NAME}_wrapper.bit</code> and <code><bora_repo>/vivado/${BASE_NAME}.runs/impl_1/${BASE_NAME}_wrapper.bin</code>.
*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 <code>ps7_init_gpl.c</code> and <code>ps7_init_gpl.h</code> source files into U-boot source code directory using the following command example for Bora:
:<code>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}/</code>
:*Follow [[BORA_SOM/BELK-L/Development/Building_U-Boot | 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 <code>ps7_init_gpl.c</code> and <code>ps7_init_gpl.h</code> 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.
 
===GUI based procedure===
{{ImportantMessage|text=The following procedure make use of ambient variables to address all our boards.<br>
Define the correct ones according the target SoM.<br>
For Bora SoM use:
*<code>export BORA_SOM=Bora</code>
*<code>export BASE_NAME=bora</code>
*<code>export UBOOT_PS7_DIR=bora</code>
For BoraLite SoM use:
*<code>export BORA_SOM=BoraLite</code>
*<code>export BASE_NAME=boralite</code>
*<code>export UBOOT_PS7_DIR=bora</code>
For BoraX SoM use:
*<code>export BORA_SOM=BoraX</code>
*<code>export BASE_NAME=borax</code>
*<code>export UBOOT_PS7_DIR=borax</code>
}}
 
 
*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:<code>git clone git@git.dave.eu:dave/bora/bora.git</code>
 
*copy the <code><bora_repo>/boards/</code> directory to <code><vivado_install_dir>/data/boards/</code> :
<pre>
cd <bora_repo>
sudo cp -r boards/ /opt/Xilinx/Vivado/<Vivado_version>/data/
</pre>
*launch the Vivado Design Suite GUI with the following commands{{efn|In a 32 bit system, Vivado settings are configured with the following command <code>/opt/Xilinx/Vivado/201x.y/settings32.sh</code>}}:
<pre>
. /opt/Xilinx/Vivado/201x.y/settings64.sh
vivado
</pre>
*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 <code><bora_repo>/bd/${BASE_NAME}/${BASE_NAME}.bd</code>
***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 <code>Ctrl+T</code>. The name of the external ports must be UART_0 and CAN_0 respectively, otherwise correct manually
***manually connect the <code>FCLK_CLK0</code> signal to <code>M_AXI_GP0_ACLK</code> and save the block design
***from the sources tab, select the BORA block design <code>${BASE_NAME}.bd</code> 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 <code>${BASE_NAME}_wrapper.v</code>. 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 <code>>${BASE_NAME}_wrapper.v</code> file from the <code><project_directory>/<prj_name>.srcs/sources_1/bd/${BASE_NAME}/hdl/</code> directory
 
*select ''Add sources'' and click on ''Add or create constraints''
*select the <code>${BASE_NAME}_pinout.xdc</code> and <code>${BASE_NAME}_timings.xdc</code> files from the <code>constr</code> 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 <code>generate_binary_bitstream.tcl</code> file from the <code>scripts</code> directory from the BORA repository
*The bitstream file is now present in <code><project_directory>/<prj_name>.runs/impl_1/${BASE_NAME}_wrapper.bit</code> and <code><project_directory>/<prj_name>.runs/impl_1/${BASE_NAME}_wrapper.bin</code>.
*Copy the <code>ps7_init_gpl.c</code> and <code>ps7_init_gpl.h</code> source files into U-boot source code directory using the following command example for Bora:
:<code>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}/</code>Follow [[BORA_SOM/BELK-L/Development/Building_U-Boot | 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 <code>ps7_init_gpl.c</code> and <code>ps7_init_gpl.h</code> source files generated by the Vivado project described in this article'''. As such, it is not generally required to rebuild U-Boot.
-----
{{notelist}}
 
=== Downloading the bitstream to the device ===
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 [[BELK-AN-008:_Programming_the_FPGA_Bitstream_with_U-Boot#Introduction|this section]].
 
=== Helloworld from UART0 ===
Using the FPGA bitstream previously created, it is possible to use serial tty port on Linux. The serial port is mapped to <code>/dev/ttyPS1</code> (this is because <code>/dev/ttyPS0</code> is the console mapped to UART1).
 
Here below an example on C code for initializing and using UART0 through FPGA:
 
<pre>
#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);
}
 
 
</pre>
 
and then compile it:
 
<pre>
dvdk@vagrant:~/bora/rfs/belk/home/root$ source ~/env.sh
dvdk@vagrant:~/bora/rfs/belk/home/root$ $CC hello_UART0.c -o hello_UART0
</pre>
 
The program executed print out the msg string on the serial console and on <code>/dev/ttyPS1</code> port.
<section end=BELK/>
8,286
edits