Difference between revisions of "Creating and building example Vivado project (BELK/BXELK)"

From DAVE Developer's Wiki
Jump to: navigation, search
(Command line based procedure)
(Helloworld from UART0)
 
(32 intermediate revisions by 5 users not shown)
Line 2: Line 2:
 
{{Applies To Bora}}
 
{{Applies To Bora}}
 
{{Applies To BoraX}}
 
{{Applies To BoraX}}
 +
{{Applies To BoraLite}}
 
{{InfoBoxBottom}}
 
{{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 actual numbers of your version. For instance, use the string <code>vivado_2014.4</code> if you are working with Vivado 2014.4.
 +
}}
 +
  
 
== History ==
 
== History ==
Line 8: Line 13:
 
!Version
 
!Version
 
!Date
 
!Date
!BELK version
+
!BELK/BXELK version
 
!Notes
 
!Notes
 
|-
 
|-
Line 15: Line 20:
 
|[[Bora_Embedded_Linux_Kit_(BELK)#BELK_software_components|3.0.0]]
 
|[[Bora_Embedded_Linux_Kit_(BELK)#BELK_software_components|3.0.0]]
 
|First release
 
|First release
 +
|-
 +
|2.0.0
 +
|July 2017
 +
|[[Bora_Embedded_Linux_Kit_(BELK)#BELK_software_components|3.0.0, 4.0.0]]
 +
|Updates for BELK 4.0.0 / BXELK 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
 +
|-
 +
|3.0.0
 +
|December 2019
 +
|[[Bora_Embedded_Linux_Kit_(BELK)#BELK_software_components|4.1.0, 2.1.0]]
 +
|
 
|-
 
|-
 
|}
 
|}
==Introduction==
+
 
BELK provides an example Vivado project for BORA/BORAX boards. This project allows to:
+
<section begin=BELK/>
*generate FSBL binary image
+
==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 simple PL design used to route PS' CAN0 and UART0 signals through EMIO (see also the following pictures).
 
*generate the bitstream of a simple PL design used to route PS' CAN0 and UART0 signals through EMIO (see also the following pictures).
  
Line 25: Line 48:
 
[[File:Belk-default-vivado-project.png|thumb|center|400px|Block diagram of BORA example project]]
 
[[File:Belk-default-vivado-project.png|thumb|center|400px|Block diagram of BORA example project]]
 
[[File:Belk-borax-default-vivado-project.png|thumb|center|400px|Block diagram of BORAX 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 line based while the latter is GUI based.
  
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 [[BORA_SOM/BELK-L/Development/Build_system#Setting_up_the_Zynq_development_server_environment|here]].
  
The project is stored is a git repository, as described [[Build_system_(BELK)#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).
  
It is assumed that the Zynq development environment has been set up properly (see [[Build_system_(BELK)|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>
 +
}}
  
==Command line based procedure==
 
The following rocedure is detailed for Bora board. For BoraX please replace:
 
*bora_FSBL with borax_FSBL
 
*bora_wrapper_hw_platform_0 with borax_wrapper_hw_platform_0
 
*bora.sdk with borax.sdk
 
*bora_wrapper.bit with borax_wrapper.bit.
 
  
 
*start the Zynq development server and login into the system
 
*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:
 
*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>
 
*:<code>git clone git@git.dave.eu:dave/bora/bora.git</code>
*copy the <code><bora_repo>/boards/board_parts/zynq/BORA</code> and <code><bora_repo>/boards/board_parts/zynq/BORAX</code> directories to <code><vivado_2014.4_install_dir>/data/boards/board_parts/zynq/</code> :
+
*copy the <code><bora_repo>/boards/</code> directory to <code><vivado_install_dir>/data/boards/</code>  
 
<pre>
 
<pre>
 
cd <bora_repo>
 
cd <bora_repo>
sudo cp -r boards/board_parts/zynq/BORA /opt/Xilinx/Vivado/2014.4/data/boards/board_parts/zynq/
+
sudo cp -r boards/ /opt/Xilinx/Vivado/<Vivado_version>/data/
sudo cp -r boards/board_parts/zynq/BORAX /opt/Xilinx/Vivado/2014.4/data/boards/board_parts/zynq/
 
 
</pre>
 
</pre>
*enter the git directory and launch the following command to set the project directory
+
*launch the Vivado Design Suite with the following commands{{efn|In a 32 bit system, Vivado settings are configured with the following command <code>/opt/Xilinx/Vivado/<Vivado_version>/settings32.sh</code>}}{{efn|Passing the -tclargs "gen_bitstream" parameters allows for automatic building of the FPGA bitstream.}}:
*:<code>export PROJ_DIR=$(pwd)/../bora-build-YYYYMMDD-nobk</code>
 
*launch the Vivado Design Suite with the following commands{{efn|In a 32 bit system, Vivado settings are configured with the following command <code>/opt/Xilinx/Vivado/2014.4/settings32.sh</code>}}{{efn|Passing the -tclargs "-bitstream" parameters allows for automatic building of the FPGA bitstream.}}:
 
 
<pre>
 
<pre>
. /opt/Xilinx/Vivado/2014.4/settings64.sh
+
. /opt/Xilinx/Vivado/<Vivado_version>/settings64.sh
vivado -mode tcl -source build_project.tcl -notrace -tclargs "-bitstream"
+
vivado -mode tcl -source scripts/recreate_prj_${BASE_NAME}_BASE.tcl -notrace -tclargs "gen_bitstream"
 
</pre>
 
</pre>
*the <code>build_project</code> script allows user to select BORA or BORAX target
+
*At the end of the bitstream build process, the <code>build_prj_*</code> script allows to automatically export hardware and lauch SDK.
*at the end of the bitstream build process, the <code>build_project</code> script allows to automatically export hardware and lauch SDK to build the FSBL
+
*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>.
*once the Xilinx SDK is ready, perform the following operations from the GUI:
+
*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.
**Click on ''File -> New -> Application Project''
+
**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:
**select the Project Name: <code>bora_FSBL</code>
+
:<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>
**Click ''Next''
+
:*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.
**Select ''Template: Zynq FSBL''
+
:**The PS configurations are the same for Bora and BoraLite boards.
**Click on ''Finish''
+
 
**apply the patch, right-clicking on bora_FSBL in Project Explorer and then clicking on Team -> Apply Patch..
+
===GUI based procedure===
*from ''Browse...'' open the file <code><bora_repo>/patch/belk-sd-boot.patch</code>
+
{{ImportantMessage|text=The following procedure make use of ambient variables to address all our boards.<br>
**Click ''Next''
+
Define the correct ones according the target SoM.<br>
**Select ''Apply the patch to the selected file, folder or project'': and select <code>main.c</code> from ''bora_FSBL -> src''
+
For Bora SoM use:
**Click ''Next''
+
*<code>export BORA_SOM=Bora</code>
**Check that the patch is correctly applied to the source code and click on ''Finish''
+
*<code>export BASE_NAME=bora</code>
**With the same procedure apply patches to fix DDR3 CKE deassertion time (see also: http://www.xilinx.com/support/answers/65145.html):
+
*<code>export UBOOT_PS7_DIR=bora</code>
***apply <code><bora_repo>/patch/AR65145_ps7_init_c.patch</code> on <code>ps7_init.c</code> under ''bora_wrapper_hw_platform_0''
+
For BoraLite SoM use:
***apply <code><bora_repo>/patch/AR65145_ps7_init_tcl.patch</code> on <code>ps7_init.tcl</code> under ''bora_wrapper_hw_platform_0''
+
*<code>export BORA_SOM=BoraLite</code>
*the FSBL (ELF file) is built automatically
+
*<code>export BASE_NAME=boralite</code>
*create the binary from the FSBL ELF chosing one of the following options:
+
*<code>export UBOOT_PS7_DIR=bora</code>
**manually launch the command: <code>arm-xilinx-eabi-objcopy -v -O binary $PROJ_DIR/bora.sdk/SDK/SDK_Export/bora_FSBL/Debug/bora_FSBL.elf $PROJ_DIR/bora.sdk/SDK/SDK_Export/bora_FSBL/Debug/bora_FSBL.bin</code>
+
For BoraX SoM use:
*this step is board dependent
+
*<code>export BORA_SOM=BoraX</code>
**configure the automatic binary generation on project build. In ''Project Explorer'', right-click on <code>bora_FSBL</code> project and select ''C/C++ Build Settings'' and add the command <code>arm-xilinx-eabi-objcopy -v -O binary ${ProjName}.elf ${ProjName}.bin</code> on ''Post-build steps''
+
*<code>export BASE_NAME=borax</code>
*create the <code>BOOT.bin</code> image (single file including FSBL, FPGA and U-boot for uSD boot):
+
*<code>export UBOOT_PS7_DIR=borax</code>
**select the <code>bora_FSBL</code> project in ''Project Explorer''
+
}}
**click on ''Xilinx Tools -> Create Zynq Boot Image''
+
 
*if the project is correctly configured, the tool builds automatically all the component listed in the form, so just add U-Boot to the list.  
 
*otherwise, select ''Create new BIF file'' and set the output path and in ''Boot image partitions'' add the following files:
 
**bora_FSBL.elf, which can be found in the project <code>Debug</code> directory. N.B. check that the <u>''Partition Type'' for FSBL is ''bootloader''</u>
 
***<code>bora_wrapper.bit</code>, which is the bitstream generated by the Vivado project (<u>''Partition Type'' must be ''Datafile''</u>)
 
**<code>u-boot.elf</code>, which is the compiled U-Boot with <code>.elf</code> extension (<u>''Partition Type'' must be ''Datafile''</u>)
 
*in ''Output path'', select the path for the <code>BOOT.bin</code> file
 
  
==GUI based procedure==
 
 
*start the Zynq development server and login into the system
 
*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>
 
*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/BORA</code> and <code><bora_repo>/boards/board_parts/zynq/BORAX</code> directories to <code><vivado_2014.4_install_dir>/data/boards/board_parts/zynq/</code> :
+
 
 +
*copy the <code><bora_repo>/boards/</code> directory to <code><vivado_install_dir>/data/boards/</code> :
 
<pre>
 
<pre>
 
cd <bora_repo>
 
cd <bora_repo>
sudo cp -r boards/board_parts/zynq/BORA /opt/Xilinx/Vivado/2014.4/data/boards/board_parts/zynq/
+
sudo cp -r boards/ /opt/Xilinx/Vivado/<Vivado_version>/data/
sudo cp -r boards/board_parts/zynq/BORAX /opt/Xilinx/Vivado/2014.4/data/boards/board_parts/zynq/
 
 
</pre>
 
</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/2014.4/settings32.sh</code>}}:
+
*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>
 
<pre>
. /opt/Xilinx/Vivado/2014.4/settings64.sh
+
. /opt/Xilinx/Vivado/201x.y/settings64.sh
 
vivado
 
vivado
 
</pre>
 
</pre>
 
*from the start page click on ''Create New Project''
 
*from the start page click on ''Create New Project''
 
*click ''Next''
 
*click ''Next''
*select the directory build project, insert the name of the project ''Project Name'' and 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''
 
*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'' or ''BORAX'' depending on target SOM 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''
 
*check the summary page and click ''Finish''
*in the Vivado GUI click on ''Create Block Design'' from the ''Flow Navigator''
+
*For the block design there are two possible ways:
*this step is board dependent:
+
**Add the existing BD within the repo:
**for Bora: insert ''bora'' as ''Design name'' and click ''OK''
+
***select ''Add sources'' from the ''Flow Navigator''
**for BoraX: insert ''borax'' as ''Design name'' and click ''OK''
+
***click on ''Add or create design sources''
*this creates a new block design. From the Diagram tab, add a new IP:
+
***select Add Files and add <code><bora_repo>/bd/${BASE_NAME}/${BASE_NAME}.bd</code>
**click the ''Add IP'' side button, or
+
***check that the option ''Copy sources into project'' is disabled and click finish
**click ''Add IP'' on the upper suggestions bar
+
**Create a new block design:
*double click on ''ZYNQ7 Processing System''
+
***click on ''Create Block Design'' from the ''Flow Navigator''
*this adds the IP that models the PL component of Zynq. Launch ''Run Block Automation'' from the upper suggestions bar
+
***insert ''${BASE_NAME}'' as ''Design name'' and click ''OK''
*check that ''Apply Board Preset'' is selected and click ''OK''
+
***this creates a new block design. From the Diagram tab, add a new IP:
*this applies the default settings for BORA/BORAX and creates the I/O ports for the DDR and MIO pins and for the UART_0 and CAN_0 interfaces
+
****click the ''Add IP'' side button, or
*manually connect the <code>FCLK_CLK0</code> signal to <code>M_AXI_GP0_ACLK</code> and save the block design
+
****click ''Add IP'' on the upper suggestions bar
*from the sources tab, select the BORA/BORAX block design (<code>bora.bd</code> for Bora, <code>borax.bd</code> for BoraX) as ''Design Sources'' and from the context menu select ''Create HDL Wrapper''
+
***double click on ''ZYNQ7 Processing System''
*on the next window, select ''Copy generated wrapper'' to allow user edits and click ''OK''
+
***this adds the IP that models the PL component of Zynq. Launch ''Run Block Automation'' from the upper suggestions bar
*this creates the Verilog file (<code>bora_wrapper.v</code> for Bora, <code>borax_wrapper.v</code> for BoraX). If this file is not automatically included in the project, add it using the ''Add sources'' option
+
***check that ''Apply Board Preset'' is selected and click ''OK''
**select Add or create design sources and click ''Next''
+
****this applies the default settings for BORA/BORAX and creates the I/O ports for the DDR and MIO pins
**this step is board dependent
+
***UART_0 and CAN_0 connections must be manually created:
***for Bora: select the <code>bora_wrapper.v</code> file from the <code><prj_name>.srcs/sources_1/bd/bora/hdl/</code> directory
+
****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
***for BoraX: select the <code>borax_wrapper.v</code> file from the <code><prj_name>.srcs/sources_1/bd/borax/hdl/</code> directory
+
***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 ''Add sources'' and click on ''Add or create constraints''
*this step is board dependent
+
*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
**for Bora: select the <code>bora_pinout.xdc</code> and <code>bora_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
**for BoraX: select the <code>borax_pinout.xdc</code> and <code>borax_timings.xdc</code> files from the <code>constr</code> directory of the BORA repository
 
*check that the option ''Copy constraints'' files into project is enabled
 
 
*create the synthesis, implementation and bitstream clicking ''Generate Bitstream'' from the ''Flow Navigator'' and wait the completion of the operation
 
*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''
 
*once completed, select ''Open Implemented Design''
 
*create the binary bitstream running the tcl script provided with the BORA repository. Launch ''Tools -> Run Tcl Script''
 
*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 scripts directory from the BORA repository
+
*select the <code>generate_binary_bitstream.tcl</code> file from the <code>scripts</code> directory from the BORA repository
*select ''File -> Export -> Export Hardware''
+
*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>.
*on the next window, enable ''Include Bitstream'' and click ''OK''
+
*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:
*now launch the SDK session to generate the FSBL, clicking on ''File -> Launch SDK''
+
:<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.
*once the Xilinx SDK is ready, perform the following operations from the GUI:
 
**Click on ''File -> New -> Application Project''
 
**this step is board dependent
 
***for Bora: select the Project Name: <code>bora_FSBL</code>
 
***for BoraX: select the Project Name: <code>borax_FSBL</code>
 
**Click ''Next''
 
**Select ''Template: Zynq FSBL''
 
**Click on ''Finish''
 
**this step is board dependent
 
***for Bora: apply the patch, right-clicking on bora_FSBL in Project Explorer and then clicking on Team -> Apply Patch..
 
***for BoraX: apply the patch, right-clicking on borax_FSBL in Project Explorer and then clicking on Team -> Apply Patch..
 
*this step is board dependent
 
**for Bora: from ''Browse...'' open the file <code><bora_repo>/patch/belk-sd-boot.patch</code>
 
**for BoraX: from ''Browse...'' open the file <code><bora_repo>/patch/belkx-sd-boot.patch</code>
 
**Click ''Next''
 
**this step is board dependent
 
***for Bora: Select ''Apply the patch to the selected file, folder or project'': and select <code>main.c</code> from ''bora_FSBL -> src''
 
***for BoraX: Select ''Apply the patch to the selected file, folder or project'': and select <code>main.c</code> from ''borax_FSBL -> src''
 
**Click ''Next''
 
**Check that the patch is correctly applied to the source code and click on ''Finish''
 
**With the same procedure apply patches to fix DDR3 CKE deassertion time (see also: http://www.xilinx.com/support/answers/65145.html):
 
***this step is board dependent
 
****for Bora: apply <code><bora_repo>/patch/AR65145_ps7_init_c.patch</code> on <code>ps7_init.c</code> under ''bora_wrapper_hw_platform_0''
 
****for BoraX: apply <code><bora_repo>/patch/AR65145_ps7_init_c.patch</code> on <code>ps7_init.c</code> under ''borax_wrapper_hw_platform_0''
 
***this step is board dependent
 
****for Bora: apply <code><bora_repo>/patch/AR65145_ps7_init_tcl.patch</code> on <code>ps7_init.tcl</code> under ''bora_wrapper_hw_platform_0''
 
****for BoraX: apply <code><bora_repo>/patch/AR65145_ps7_init_tcl.patch</code> on <code>ps7_init.tcl</code> under ''borax_wrapper_hw_platform_0''
 
*the FSBL (ELF file) is built automatically
 
*create the binary from the FSBL ELF chosing one of the following options:
 
**this step is board dependent
 
***for Bora: manually launch the command: <code>arm-xilinx-eabi-objcopy -v -O binary $PROJ_DIR/bora.sdk/SDK/SDK_Export/bora_FSBL/Debug/bora_FSBL.elf $PROJ_DIR/bora.sdk/SDK/SDK_Export/bora_FSBL/Debug/bora_FSBL.bin</code>
 
***for BoraX: manually launch the command: <code>arm-xilinx-eabi-objcopy -v -O binary $PROJ_DIR/borax.sdk/SDK/SDK_Export/borax_FSBL/Debug/borax_FSBL.elf $PROJ_DIR/borax.sdk/SDK/SDK_Export/borax_FSBL/Debug/borax_FSBL.bin</code>
 
**this step is board dependent
 
***for Bora: configure the automatic binary generation on project build. In ''Project Explorer'', right-click on <code>bora_FSBL</code> project and select ''C/C++ Build Settings'' and add the command <code>arm-xilinx-eabi-objcopy -v -O binary ${ProjName}.elf ${ProjName}.bin</code> on ''Post-build steps''
 
***for BoraX: configure the automatic binary generation on project build. In ''Project Explorer'', right-click on <code>borax_FSBL</code> project and select ''C/C++ Build Settings'' and add the command <code>arm-xilinx-eabi-objcopy -v -O binary ${ProjName}.elf ${ProjName}.bin</code> on ''Post-build steps''
 
*create the <code>BOOT.bin</code> image (single file including FSBL, FPGA and U-boot for uSD boot:
 
**this step is board dependent
 
***for Bora: select the <code>bora_FSBL</code> project in ''Project Explorer''
 
***for BoraX: select the <code>borax_FSBL</code> project in ''Project Explorer''
 
**click on ''Xilinx Tools -> Create Zynq Boot Image''
 
*if the project is correctly configured, the tool builds automatically all the component listed in the form, so just add U-Boot to the list.
 
*otherwise, select ''Create new BIF file'' and set the output path and in ''Boot image partitions'' add the following files:
 
** for Bora
 
***bora_FSBL.elf, which can be found in the project <code>Debug</code> directory. N.B. check that the <u>''Partition Type'' for FSBL is ''bootloader''</u>
 
***<code>bora_wrapper.bit</code>, which is the bitstream generated by the Vivado project (<u>''Partition Type'' must be ''Datafile''</u>)
 
** for BoraX
 
***borax_FSBL.elf, which can be found in the project <code>Debug</code> directory. N.B. check that the <u>''Partition Type'' for FSBL is ''bootloader''</u>
 
***<code>borax_wrapper.bit</code>, which is the bitstream generated by the Vivado project (<u>''Partition Type'' must be ''Datafile''</u>)
 
**<code>u-boot.elf</code>, which is the compiled U-Boot with <code>.elf</code> extension (<u>''Partition Type'' must be ''Datafile''</u>)
 
*in ''Output path'', select the path for the <code>BOOT.bin</code> file
 
 
-----
 
-----
 
{{notelist}}
 
{{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/>

Latest revision as of 13:22, 12 May 2022

Info Box
Bora5-small.jpg Applies to Bora
BORA Xpress.png Applies to BORA Xpress
BORALite-TOP.png Applies to BORA Lite


200px-Emblem-important.svg.png

In this document, the Vivado installation path may be indicated as vivado_201x.y. Just replace x and y with the actual numbers of your version. For instance, use the string vivado_2014.4 if you are working with Vivado 2014.4.


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

2.0.1

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


Block diagram of BORA example project
Block diagram of BORAX example project
Block diagram of BORALITE example project

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]

200px-Emblem-important.svg.png

The following procedure make use of ambient variables to address all our boards.
Define the correct ones according the target SoM.
For Bora SoM use:

  • export BASE_NAME=bora
  • export UBOOT_PS7_DIR=bora

For BoraLite SoM use:

  • export BASE_NAME=boralite
  • export UBOOT_PS7_DIR=bora

For BoraX SoM use:

  • export BASE_NAME=borax
  • export UBOOT_PS7_DIR=borax


  • 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 with the following commands[a][b]:
. /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 and ps7_init_gpl.h source files into U-boot source code directory using the following command example for Bora:
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 and ps7_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.

GUI based procedure[edit | edit source]

200px-Emblem-important.svg.png

The following procedure make use of ambient variables to address all our boards.
Define the correct ones according the target SoM.
For Bora SoM use:

  • export BORA_SOM=Bora
  • export BASE_NAME=bora
  • export UBOOT_PS7_DIR=bora

For BoraLite SoM use:

  • export BORA_SOM=BoraLite
  • export BASE_NAME=boralite
  • export UBOOT_PS7_DIR=bora

For BoraX SoM use:

  • export BORA_SOM=BoraX
  • export BASE_NAME=borax
  • export UBOOT_PS7_DIR=borax


  • 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
      • manually connect the FCLK_CLK0 signal to M_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
  • select Add sources and click on Add or create constraints
  • select the ${BASE_NAME}_pinout.xdc and ${BASE_NAME}_timings.xdc files from the constr 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 the scripts 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 and ps7_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 the ps7_init_gpl.c and ps7_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.

  1. In a 32 bit system, Vivado settings are configured with the following command /opt/Xilinx/Vivado/<Vivado_version>/settings32.sh
  2. Passing the -tclargs "gen_bitstream" parameters allows for automatic building of the FPGA bitstream.
  3. 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.