Skip to content

Instantly share code, notes, and snippets.

@cathalmccabe
Created June 11, 2019 07:00
Show Gist options
  • Save cathalmccabe/610a70e8d97004731bc34486f5810b7c to your computer and use it in GitHub Desktop.
Save cathalmccabe/610a70e8d97004731bc34486f5810b7c to your computer and use it in GitHub Desktop.
SDx command line notebook
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Using SDx on the command line\n",
"\n",
"## Introduction\n",
"\n",
"This lab guides you through the steps involved in using SDx on the command line to build and application, and perform software and hardware emulation, and test the final design in hardware.\n",
"\n",
"The lab will use the same vector addition source files as the previous SDx introductory lab.\n",
"\n",
"\n",
"## Objectives\n",
"\n",
"After completing this lab, you will be able to:\n",
"\n",
"* Run Software Emulation to verify the functionality of a design using a Makefile flow\n",
"* Run Hardware Emulation to verify the functionality including kernel hardware using a Makefile flow\n",
"* Build the full system and verify functionality in hardware on an AWS F1 instance\n",
"\n",
"\n",
"### Jupyter \n",
"This document is a Jupyter notebook. A Jupyter notebook is an executable document. To run the tutorial, you can copy and paste the instructions in this document into your terminal and execute them, or if you use Jupyter Notebook, you can open this document and execute the cells directly from Jupyter. \n",
"For more information and instructions on how to get Jupyter, see https://jupyter.org\n",
"The commands you will need to run are inside Jupyter code cells. Each command is prefixed with **!** which means pass the command to a shell. \n",
"If you want to run the commands in a terminal, copy the command without the \"!\".\n",
"\n",
"## Steps\n",
"\n",
"### Check environment\n",
"\n",
"First check XILINX_SDK and XILINX_XRT have been set in the current environment"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"!echo $XILINX_SDX\n",
"!echo $XILINX_VIVADO\n",
"!echo $XILINX_XRT"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Build and Run Emulation Flows\n",
"\n",
"As you saw in the previous labs, the emulation modes allow testing of the design before doign a full hardware build. \n",
"\n",
"### Set build configuration\n",
"\n",
"In previous labs, the *build configuration* (SW Emulation, HW Emulation, or System) was set from the GUI. When using the command line, this needs to be set with an environment variable XCL_EMULATION_MODE. \n",
"\n",
"This affects the build, and also affects the behaviour of an SDx executable when it is call as you will see later.\n",
"\n",
"System Build is the default if no environment variable is set. \n",
"\n",
"* Set the XCL_EMULATION_MODE mode to Software Emulation"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%set_env XCL_EMULATION_MODE=sw_emu"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Set the target platform\n",
"You will need to pass the path to your target platform when building your design. \n",
"\n",
"* Set and environment variable for your platform now. \n",
"\n",
"(Change the path below to point to your installed platform.)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%set_env U200_PLATFORM=/opt/xilinx/platforms/xilinx_u200_xdma_201830_1/xilinx_u200_xdma_201830_1.xpfm"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Compile OpenCL kernel\n",
"\n",
"xocc is the SDx (Xilinx) OpenCL kernel. You will now compile the OpenCL kernel, in SW Emulation mode, targetting a specific platform. \n",
"\n",
"- Switches\n",
" * **--target** specifies the Build mode\n",
" * **-c** compile\n",
" * **--platform** specifies the Platform\n",
" * **-k** specifies the kerner name\n",
" * **-g** will include debugging information\n",
" * **-I** is the include directory (for including header, or other source files)\n",
" * **-o** specifies the output file\n",
"\n",
"For more information on the xocc compiler, see: \n",
"https://www.xilinx.com/html_docs/xilinx2018_3/sdaccel_doc/wrj1504034328013.html\n",
"\n",
"* Run xocc to compile the kernel"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"!xocc --target $XCL_EMULATION_MODE \\\n",
"-c --platform $U200_PLATFORM \\\n",
"-k krnl_vadd -g \\\n",
"-I\"./src\" -o \"kernel/krnl_vadd.xo\" \\\n",
"\"./src/krnl_vadd.cl\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Create the FPGA binary\n",
"\n",
"- Switches\n",
" * **-l** links one or more kernels into the platform to create the binary container\n",
" * **--nk** specifies the number of compute units\n",
" * **--xp** passes parameters to the Vivado tools. For example, to configure optimization or placement settings. \n",
"\n",
"\n",
"* Run xocc to create the FPGA binary"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"!xocc -t $XCL_EMULATION_MODE \\\n",
"--platform $U200_PLATFORM \\\n",
"-l --nk krnl_vadd:1:krnl_vadd_1 \\\n",
"-g --xp misc:solution_name=link -o\"binary_container_1.xclbin\" \\\n",
"kernel/krnl_vadd.xo"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Compile host application code\n",
"\n",
"The host application code is C++ and is compiled with the Xilinx C++ compiler *xcpp*. \n",
"\n",
"- Switches\n",
" * **-DSDX_PLATFORM** specifices the platfrom\n",
" * **-g, -c, -std, -o** are all standard C++ compiler switches\n",
" \n",
"* Compile the vadd.cpp file \n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"!xcpp -DSDX_PLATFORM=xilinx_u200_xdma_201830_1 -D__USE_XOPEN2K8 \\\n",
"-I$XILINX_SDX/runtime/include/1_2/ \\\n",
"-I$XILINX_VIVADO/include/ \\\n",
"-g -c -std=c++14 \\\n",
"-o \"./vadd.o\" \\\n",
"\"./src/vadd.cpp\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"* Compile the xcl.cpp file"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"!xcpp -DSDX_PLATFORM=xilinx_u200_xdma_201830_1 \\\n",
"-D__USE_XOPEN2K8 -I$XILINX_SDK/runtime/include/1_2/ \\\n",
"-I$XILINX_VIVADO/include/ -g -c -std=c++14 \\\n",
"-o \"./xcl.o\" \\\n",
"\"./src/xcl.cpp\""
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#!/bin/bash /opt/xilinx/SDx/2018.3/settings64.sh"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Run the Linker\n",
"\n",
"The host application files, and the OpenCL kernels have now been compiled. THe last step is to run the linker.\n",
"\n",
"- Switches\n",
" * -lxilinxopencl \n",
" * -lpthread \n",
" * -lrt \n",
" * -lstdc++ \n",
" * -Wl\n",
" * -rpath\n",
" * -lhlsmc++-GCC46\n",
" * -lgmp \n",
" * -lmpfr \n",
" * -lIp_floating_point_v7_0_bitacc_cmodel\n",
"\n",
"* Run the linker\n",
"\n",
"# Check duplicate switches"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"!xcpp -o \"vector_addition.exe\" vadd.o xcl.o -lxilinxopencl -lpthread -lrt -lstdc++ \\\n",
"-L$XILINX_SDK/runtime/lib/x86_64 \\\n",
"-L$XILINX_XRT/lib/ \\\n",
"-lxilinxopencl -lpthread -lrt -lstdc++ \\\n",
"-Wl,-rpath,$XILINX_VIVADO/lnx64/lib/csim \\\n",
"-L $XILINX_VIVADO/lnx64/lib/csim \\\n",
"-lhlsmc++-GCC46 -Wl,-rpath,$XILINX_VIVADO/lnx64/tools/fpo_v7_0 \\\n",
"-L /$XILINX_VIVADO/lnx64/tools/fpo_v7_0 \\\n",
"-lgmp -lmpfr -lIp_floating_point_v7_0_bitacc_cmodel"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Emulation configuration file\n",
"\n",
"An Enulation configuration file is required prior to running SW or HW Emulation. \n",
"This provides details of the *platform* and is used by the emulation runtime. \n",
"\n",
"- Switches\n",
" * **--nd** specifies number of devices. The default is 1\n",
" \n",
"https://www.xilinx.com/html_docs/xilinx2018_3/sdaccel_doc/pnb1504034327301.html\n",
"\n",
"* Build the emulation file"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"!emconfigutil --platform $U200_PLATFORM --nd 1"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Test the application\n",
"\n",
"The final step is to test the application.\n",
"\n",
"Notice that when calling the executable, no information about the \"mode\" is specified. The executable runs in emulation or on hardware, based on the XCL_EMULATION_MODE environment variable specified earlier. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"!./vector_addition.exe ./binary_container_1.xclbin 10"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Build the System\n",
"\n",
"If you would like to implement the kernel in hardware, clear the XCL_EMULATION_MODE environment variable, and rerun the notebook. Note that it takes around 2 hours to build the hardware. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Cleanup intermediate files\n",
"\n",
"When you are finished, you can remove intermediate files. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"!rm *.o *.log *.info emconfig.json *.str\n",
"!rm -rf .Xil _x \n",
"!dir"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment