Xilinx Vivado, XSDK and Petalinux 2016.2 on Ubuntu 16.04

Just a list of a few new steps required to install and run Vivado, XSDK and Petalinux 2016.2 on Ubuntu 64bit 16.04:

  1. In order to run XSDK which can't use default GTK v3 we have to export new environmental variable. I usually add them at the end of my ~/.bashrc:

    export SWT_GTK3=0

  2. Another problem I discovered is when I open the Xilinx License Configuration Manager (XLCM) in Vivado Design Suite 2016.2, the HOST ID Matches column is shown as No. However, the host ID in the license file is correct. Looks like problem lies in new Ubuntu ethernet interface names and changing it back to eth0 fixes the issue. In order to make a change we have to add next settings to grub config in /etc/default/grub".

    GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0"

    Dont forget to update grub:

    sudo grub-mkconfig -o /boot/grub/grub.cfg

    Generating grub configuration file ...
    Warning: Setting GRUB_TIMEOUT to a non-zero value when GRUB_HIDDEN_TIMEOUT is set is no longer supported.
    Found linux image: /boot/vmlinuz-4.4.0-31-generic
    Found initrd image: /boot/initrd.img-4.4.0-31-generic
    Found linux image: /boot/vmlinuz-4.4.0-21-generic
    Found initrd image: /boot/initrd.img-4.4.0-21-generic
    Found memtest86+ image: /boot/memtest86+.elf
    Found memtest86+ image: /boot/memtest86+.bin
    done

    Make changes to /etc/networking/interfaces and reboot:

    auto eth0
    iface eth0 inet dhcp

  3. Yet another source of problems - Vivado's settings64.sh: it sets LD_LIBRARY_PATH to point to Vivado/2016.2/lib/lnx64.o, but because its global it affects all binaries run within the shell where we source settings64.sh. In my case, I noticed problems with starting gedit and failed compilation of U-boot with error "awk: undefined symbol: mpfr_z_sub".
    Anyway, we actually can remove setting LD_LIBRARY_PATH from settings64.sh if your hardware design doesn't include AXI-BFM IP.

    #############################################################
    # Copyright (c) 1986-2016 Xilinx, Inc. All rights reserved. #
    ##############################################################

    export XILINX_VIVADO=/opt/Xilinx/Vivado/2016.2
    if [ -n "${PATH}" ]; then
    export PATH=/opt/Xilinx/Vivado/2016.2/bin:$PATH
    else
    export PATH=/opt/Xilinx/Vivado/2016.2/bin
    fi

    #if [ -n "${LD_LIBRARY_PATH}" ]; then
    # export LD_LIBRARY_PATH=/opt/Xilinx/Vivado/2016.2/lib/lnx64.o:$LD_LIBRARY_PATH
    #else
    # export LD_LIBRARY_PATH=/opt/Xilinx/Vivado/2016.2/lib/lnx64.o
    #fi

Very useful Zynq and AXI bus tutorials.

sadri_img1

Spent couple of my evenings watching this tutorials and found them painfully slow, but very very useful. Unfortunately for me, I'm already passed that point on my "learning curve" of Zynq and AXI4 bus, but still learned quite a few new tricks and got some ideas, especially on creation of AXI peripheral using HLS and RTL design flows. Hope, Mohammadsadegh Sadri will soon move from trivial examples to advanced topics as he promised in his videos.

Anyway, I suggest this tutorials for everyone. Very nice work Mohammadsadegh Sadri !

You can find full list of tutorials here: http://www.googoolia.com/wp/category/zynq-training/

HDMI on ZedBoard with Petalinux update.

I finally figure it out why Analog Devices reference design create/generated in Vivado 2014 by script(obviously updated to use new IP's, otherwise it didn't assemble 'Block Design' at all) didn't work. Reason is changes in Xilinx Concat IP, which used in reference design to concatenate interrupt signals from VDMA and I2C IP blocks to Zynq's F2S interrupt bus.
So, now in 2014.1, we got version 2.0 of it and it preserve the order of input signals on the output. Which means we must either change inputs order or change interrupt numbers in DTS.

So, for AD reference design generated in Vivado2014.1 interrupts are:

  • AXI_IIC_MAIN - #56.
  • AXI_VDMA_0 - #55.
  • AXI_IIC_FMC - #59.

zynq16_001

HDMI on ZedBoard with Petalinux.

This is step-by-step tutorial on how to build reference design for Analog Devices ADV7511 HDMI encoder used on ZedBoard with PetaLinux 2013.10. It will be mostly based on AD HDL reference design http://wiki.analog.com/resources/fpga/xilinx/kc705/adv7511 and AD Linux drivers wiki page http://wiki.analog.com/resources/tools-software/linux-drivers/platforms/zynq and Xilinx PetaLinux documentation http://www.wiki.xilinx.com/PetaLinux.

As of today, 25 May 2014, to create HDL design for ADV7511 from scratch, we have to use Vivado 2013.4, even though Vivado 2014.1 is already available. The reason is some changes in a Xilinx IP's (which I didn't had a chance to figure out yet) prevent HDL design from build/work properly.

  1. First step is to download HDL libraries and projects from AnalogDevices repositories on a github: https://github.com/analogdevicesinc/hdl. You can clone it or download a ZIP. I will download a ZIP and extract 'hdl-master' in my Projects/FPGA/ folder on Windows7 machine.
  2. Second step is to build a few Analog Devices IP required to create ZedBoard HDMI design. Run Xilinx Vivado 2013.4, open a TCL console, change directories and 'source' a .tcl scripts. For example, to build AXI_CLKGEN IP:

    cd c:/Projects/FPGA/hdl-master/library/axi_clkgen
    source ./axi_clkgen_ip.tcl

    After script finish, close created project and build the next. For ZedBoard we have build the next IP's:

    • hdl-master/library/axi_clkgen
    • hdl-master/library/axi_hdmi_tx
    • hdl-master/library/axi_i2s_adi
    • hdl-master/library/axi_spdif_tx
    • hdl-master/library/util_i2c_mixer
  3. After we done with all required IP's, we can build ADV7511 reference design for ZedBoard. In a Tcl Console change directory to ADV7511 and run 'system_project' script.

    cd c:/Projects/FPGA/hdl-master/projects/adv7511/zed/
    source ./system_project.tcl

    Script will create block design, run synthesis and implementation, generate bitstream and even export software to SDK(without opening it). This was the case on my system - everything went smoothly. We are done with Vivado and can close it.

    We have to create HDL in Vivado 2013.4, but later we can import created project into Vivado 2014.1 and update it to use latest Xilinx IP's.

  4. Let's build a FSBL. We need very typical Zynq first stage boot loader and I covered creation of it before, so now just a short description:
    • Run XSDK.
    • Create new 'Hardware Platform Specification' project (I named it 'ZedBoard-HDMI-HW') and specify HW created in a previous step.
    • Create Application project (named 'ZedBoard-HDMI-FSBL') using our new 'Hardware Platform' and select to create new BSP for it. Don't forget to use 'Zynq FSBL' template. Build it if this not done automatically.
  5. Next step is to create PetaLinux BSP. This is also very typical PetaLinux BSP, just don't forget to change 'Configuration' to reflect ZedBoard configuration and name it 'ZedBoard-HDMI-petalinux_bsp'.

    zynq15_002

    We are done with Xilinx SDK. You can close it.

  6. Next step is to create PetaLinux project and set 'hardware description'. I will call it 'ZedBoard-HDMI' Petalinux project:

    petalinux-create -t project -n ZedBoard-HDMI
    cd ~/Projects/ZedBoard-HDMI-petalinux_bsp/
    petalinux-config --get-hw-description -p ../ZedBoard-HDMI/
    cd ~/Projects/ZedBoard-HDMI/
    rm -r hw-description

  7. Now, as of today, ADV7511 Linux driver not in a mainstream kernel. So, we need to get Kernel from Analog Devices repository with appropriate patches. Current version is 3.14.0. Let's clone it, and checkout 'xcomm_zynq' branch.

    cd ~/Projects/
    git clone https://github.com/analogdevicesinc/linux.git analogdevices-kernel
    cd analogdevices-kernel/
    git checkout xcomm_zynq

  8. Create necessary directories and copy 'xcomm_zynq' branch to our PetaLinux project directory.

    cd ~/Projects/
    mkdir ~/Projects/ZedBoard-HDMI/components
    mkdir ~/Projects/ZedBoard-HDMI/components/linux-kernel
    cp -a analogdevices-kernel ~/Projects/ZedBoard-HDMI/components/linux-kernel/

  9. Run 'petalinux-config' and change kernel to 'analogdevices-kernel' and system boot device to 'SD card'.
  10. cd ZedBoard-HDMI
    petalinux-config

  11. Next we need to configure Linux kernel for PetaLinux and we need to enable all options required by ADV7511. AnalogDevices kernel support special configuration option 'zynq_xcomm_adv7511_defconfig', but we cannot run it with PetaLinux. So, we have to pre-configure kernel separately ('make ARCH=arm zynq_xcomm_adv7511_defconfig') and just copy resulted config into 'ZedBoard-HDMI/subsystems/linux/configs/kernel'. So, I did it and also copied it into PetaLinux Kernel configs directory '/opt/petalinux-v2013.10-final/etc/template/project/template-zynq/subsystems/linux/configs/kernel'. So, I can later reuse it. Also notice that kernel default config file have dot in the front and PetaLinux files don't.
    Anyway, here is link to my resulted kernel config file: https://blog.idv-tech.com/wp-content/uploads/2014/05/config_hdmi_3_14.config
  12. We also, have to modify 'devices tree' generated by PetaLinux for our project. AnalogDecices Linux kernel have template for ZedBoard which you can find in 'arch/arm/boot/dts/zynq-zed-adv7511.dts', so we basically have to copy missing devices from AD into our tree.
    Link to my resulted DTS file for ZedBoard: https://blog.idv-tech.com/wp-content/uploads/2014/05/adv7511_dts.config.
  13. We are basically done. At this point you my want to modify PetaLinux project, for example, include Qt5 library and test app to check frame buffer device later. I covered this topics in my previous post, so I wont repeat it here.

    Build Petalinux project, create BOOT.BIN and copy it together with Linux image file 'image.ub' on SD card:

    petalinux-build
    petalinux-package --boot --fsbl ../ZedBoard-HDMI-FSBL/Release/ZedBoard-HDMI-FSBL.elf --fpga ../ZedBoard-HDMI-HW/system_top.bit --uboot --force -o images/linux/BOOT.BIN

  14. Insert SD card into slot of ZedBoard and turn it on. During boot kernel should detect ADV7511(hdmi) and ADAU1761(sound) devices and create '/dev/fb0' device.So, below partial bootlog from my ZedBoard:
  15. ...
    [drm] Initialized drm 1.1.0 20060810
    /analogdevices-kernel/drivers/gpu/drm/adi_axi_hdmi/axi_hdmi_drv.c:axi_hdmi_platform_probe[176]
    platform 70e00000.axi_hdmi: Driver axi-hdmi requests probe deferral
    ...
    adv7511-hdmi-snd adv7511_hdmi_snd.2: adv7511 <-> 75c00000.axi-spdif-tx mapping ok
    ...
    zed-adau1761-snd zed_sound.3: adau-hifi <-> 77600000.axi-i2s mapping ok
    ...
    Console: switching to colour frame buffer device 180x56
    axi-hdmi 70e00000.axi_hdmi: fb0:  frame buffer device
    axi-hdmi 70e00000.axi_hdmi: registered panic notifier
    [drm] Initialized axi_hdmi_drm 1.0.0 20120930 on minor 0
    /analogdevices-kernel/drivers/rtc/hctosys.c: unable to open rtc device (rtc0)
    ALSA device list:
      #0: HDMI monitor
      #1: ZED ADAU1761
    Freeing unused kernel memory: 23356K (c062b000 - c1cfa000)
    INIT: version 2.88 booting
    Starting Bootlog daemon: bootlogd.
    ...
    
     _____       _           _      _
    | ___ \     | |         | |    (_)
    | |_/ / ___ | |_   __ _ | |     _  _ __   _   _ __  __
    |  __/ / _ \| __| / _` || |    | || '_ \ | | | |\ \/ /
    | |   |  __/| |_ | (_| || |____| || | | || |_| | >  <
    \_|    \___| \__| \__,_|\_____/|_||_| |_| \__,_|/_/\_\
    
    PetaLinux v2013.10 (Yocto 1.4) ZedBoard ttyPS0
    
    ZedBoard login: root
    Password:
    login[923]: root login  on `ttyPS0'
    
    root@ZedBoard:~# ls /dev/fb0
    /dev/fb0
    root@ZedBoard:~# uname -a
    Linux ZedBoard 3.14.0-g681a2d8-dirty #2 SMP PREEMPT Sun May 25 22:46:28 EDT 2014 armv7l GNU/Linux
    root@ZedBoard:~#
    
  16. This is basically it - once you have a framebuffer device you can start using it. So I ran my Qt5 test app and it worked. We obviously don't have any hardware acceleration with this HDL design, but we got basic FB device and HDMI output. Congratulations!

Howto create and package IP using Xilinx Vivado 2014.1

A small, step-by-step tutorial on how to create and package IP. Just as an example, I will create 3-to-8 decoder IP in Xilinx Vivado 2014.1 and connect it to Zynq SPI chip select pins. This is not a Verilog tutorial, so I will give a minimum information required to create Verilog sources.

  1. Run Xilinx Vivado and create new RTL project - name it Logic_Decoder_3-to-8; Specify Verilog as target language; also specify Zynq-7000 for a part family.
  2. zynq14_1

  3. Next step to create IP source file. To do it click on 'Add Sources' in 'Project Manager' group in the Vivado project 'Flow Navigator'.
  4. In a 'Add Sources' dialog select 'Add or Create Design Sources'.
  5. Then 'Create File...', specify new 'File Name' and click 'Ok' and 'Finish' buttons to close dialogs.
  6. zynq14_2

  7. Next, Vivado will open 'Define Module' dialog where we have to specify inputs and outputs. Since we are creating 3 to 8 decoder, set type of input and output as 'Bus' and set appropriate bus width. Set port names to whatever makes more sense to you, but remember that 'in' and 'out' are reserved words, so you have to be a little creative here. Click 'Ok' close dialog.
  8. zynq14_3

  9. Now, in a sources window of the Vivado, you can see Verilog source file we just created. Open it.
  10. zynq14_4

  11. This is just a empty source file created using template, but it already have our module input and output defined and all we need to do is to modify it to do an actual address decoding. Below is the one possible solution to such problem.
  12. zynq14_5

    module decoder_3to8(
        input [2:0] d_inp,
        output [7:0] d_out
        );
        
    assign d_out = (d_inp == 3'b000) ? 8'b00000001 :
                   (d_inp == 3'b001) ? 8'b00000010 :
                   (d_inp == 3'b010) ? 8'b00000100 :
                   (d_inp == 3'b011) ? 8'b00001000 :
                   (d_inp == 3'b100) ? 8'b00010000 :
                   (d_inp == 3'b101) ? 8'b00100000 :
                   (d_inp == 3'b110) ? 8'b01000000 :
                   8'b10000000;
        
    endmodule
    
  13. Make changes to the source and save it. Now you can run simulation and synthesis and analize the resulted design, but I will skip it to make this tutorial simpler. I also using this very simple verilog module and know it works, but still did verification on it so can just copy-paste it.
  14. Now, let's package it. In a 'Tools' menu of the Vivado select 'Create and Package IP...'. Later select 'Package your current project' option, include '.xci' files and 'Finish' new IP creation.
  15. Change IP identification information if you wish, as well as, any other property for new IP.
  16. After you done with changes, click on 'Review and Package' menu on the bottom of the list and then click in 'Package IP' button.
  17. zynq14_7

  18. We are done with this IP, close this project.
  19. Now lets use our new 3-to-8 decoder IP. Just for example, I will create new, very basic Zynq design for ZedBoard and will decode one of it's SPI port outputs to 8. And will make them external on one of the ZedBoard PMOD connector. I will not cover creation of the Zynq block design, since I did it in my previous posts.
  20. So, below my simple Zynq block design. Now, I have to enable SPI port. Double click on 'Zynq processing system', go to 'MIO Configuration' and enable 'SPI0' port. As you can see it can only have maximum 3 Slave Select (or Chip Select) pin and sometimes its not enough.
  21. zynq14_8

  22. Next we need to add our 3-to-8 decoder module to block diagram, but before we can do it, we must add it's repository to our project IP manager. So, in a 'Tools' menu select 'Project Settings' and then click on 'IP' icon.
  23. In 'IP' management dialog click on 'Add Repository...' button and specify our decoder IP project folder. Vivado will scan it, should find decoder IP and add it in found IP list. Click 'Apply' and then 'Ok' to close dialog.
  24. zynq14_9

  25. We can add decoder IP to our block diagram. Click on 'Add IP', typo decoder IP name and add it.
  26. Now we have to connect 3 SPI SS outputs to our decoder input, but we can't. Problem is that decoder inputs treated as a 'bus' and SPI SS outputs as individual 'wires'. One of the possible solution is to concatenate individual wires. In order to do it add Xilinx 'Concat' IP and modify it, so it will have 3 inputs.
  27. zynq14_10

  28. Now we should be able to connect all blocks together. Specifically, connect SPI0_SS0, SPI0_SS1 and SPI0_SS2 to 'Concat' block input 0,1 and 2. Them, connect 'Concat' output to our 3-to-8 decoder IP and finally make decoder outputs 'External'. I will also rename output port to 'SPI0_CS'.
  29. zynq14_11

  30. This is basically it. Now we have to create 'constraints' file and specify in it Zynq PACKAGE_PIN for some or all pins of the 'SPI_CS0' port. For example you may want to export only 4 CS pins. Something like this:
  31. set_property IOSTANDARD LVCMOS33 [get_ports SPI0_SCLK]
    set_property IOSTANDARD LVCMOS33 [get_ports SPI0_MISO]
    set_property IOSTANDARD LVCMOS33 [get_ports SPI0_MOSI]
    set_property IOSTANDARD LVCMOS33 [get_ports SPI0_CS[0]]
    set_property IOSTANDARD LVCMOS33 [get_ports SPI0_CS[1]]
    set_property IOSTANDARD LVCMOS33 [get_ports SPI0_CS[2]]
    set_property IOSTANDARD LVCMOS33 [get_ports SPI0_CS[3]]
    
    set_property PACKAGE_PIN AA9 [get_ports SPI0_SCLK]
    set_property PACKAGE_PIN Y10 [get_ports SPI0_MISO]
    set_property PACKAGE_PIN AA11 [get_ports SPI0_MOSI]
    set_property PACKAGE_PIN W12 [get_ports SPI0_CS[0]]
    set_property PACKAGE_PIN W11 [get_ports SPI0_CS[1]]
    set_property PACKAGE_PIN V10 [get_ports SPI0_CS[2]]
    set_property PACKAGE_PIN W8 [get_ports SPI0_CS[3]]
    
  32. Later, in a software project, you will need to enable special option for SPI driver to use 'Slave Select' pins as encoded address. But that is part of another tutorial, but this one finished. Good luck!

New Vivado 2014.1 released.

Exciting news! Yesterday Xilinx released Vivado 2014.1 - promise about 25% faster runtime and 1.5x overall speedup in compile+simulation! Also they added OpenCL kernels and some Linear algebra library to Vivado HLS! But for me more important changes is that now updated constraints file won't trigger 'out-of-date' for entire project. Also hope to see preset's for more Zynq boards, which already on a market.
Downloading it now and will try in a next hour.
SDK also got updated and now using GCC 4.8.1 instead of 4.7.3. This means almost all C++11 features supported!

Update: No additional board preset's and Avnet's board awareness files for MicroZed 7010 and 7020 for 2013.2 doesn't work anymore. Not sure yet how much effort will take to make them work.

Update 2: Changing board awareness files took 5 minutes. Not a big deal.

Howto export Zynq peripherals(I2C, SPI, UART and etc) to PMOD connectors of ZedBoard using Vivado 2013.4

This is the small howto describing export of some peripherals on ZedBoard's PMOD connectors.
ZedBoard have some, so called, FIXED_IO connections, which is hardwired to DDR memory, QSPI flash memory, Ethernet and etc. It also export Zynq UART1 to J14 connector. So, we don't have much of the Zynq MIO pin's available left, but got plenty of Zynq EMIO pins. Also, just 1 of the ZedBoard's PMOD connected to PS - JE1 PMOD, the rest connected to PL. So, I will export SPI1 to JE1 PMOD (using MIO), SPI0 to JA1 PMOD, both I2C0 and I2C1 to JD1 PMOD and PS UART0 to JC1 PMOD. I will also create and export single PWM signal to JC1 PMOD.

  1. Let's start with creating new project in Vivado 2013.4 and lets called ZedBoard, type 'RTL Project', don't add any VHDL/Verilog sources or IP. On 'Default Part' page, select your board type and revision. Finish project creation.
    We will be presented with default project view, similar to screenshot below.
  2. zynq11_01

    zynq11_02

    zynq11_03

  3. Next step is to create new 'Block Design' - let's name it 'system'.
  4. zynq11_04

  5. Use 'Add IP' button to add Xilinx IP blocks to our new block design. We will need to add a few of blocks, but lets do it step by step. First add 'Zynq7 Processing System'
  6. zynq11_06_1

  7. Next, click on 'Run Block Automation' link on a top green bar to apply 'Board Preset' for our ZedBoard and to automatically connect FIXED_IO and DDR. Once it done you will see DDR and FIXED_IO port created on in our Block Design.
  8. zynq11_07

    zynq11_08

  9. Add 'AXI Timer' IP block for our PWM signal.
  10. zynq11_09

  11. Next, run "Connection Automation" - it will add for us all IP block required by 'AXI Timer' and create all required connections. You can optimize Block Design layout by click on 'Regenerate Layout' button.
  12. zynq11_10

    zynq11_11

  13. Now we need to make our PWM signal external. To do it - 'left' click in 'pwm0' pin of 'axi_timer_0' block to select it and then 'right' to open 'pin' config menu and select 'Make External' option. It will create 'pwm0' port and connection to it.
  14. zynq11_12

  15. Let's configure Zynq PS UART, SPI and I2C - double click on 'Zynq Processing System' to open it 'Customization' window.
  16. zynq11_13

  17. In a 'MIO Configuration' expand 'I/O Peripherals' tree and enable 'UART0', both I2C and both SPI. And set 'EMIO' for UART0, both I2C and SPI0. But for SPI1 select 'MIO 10..15' option. This pin's routed to PS PMOD on ZedBoard, which is JE1 PMOD. After we make all the changes, we can save changes and close this window by hitting 'Ok' button.
  18. zynq11_14

  19. Notice that our Zynq7 PS block on diagram got UART0, SPI0 and I2C0 and I2C1 ports. SPI1 is missing because it included in a Fixed_IO port.
  20. zynq11_15

  21. Make UART0, SPI0 and both I2C ports external.
  22. zynq11_16

  23. We are done with 'Block Design' - save it.
  24. Now we have to create 'HDL Wrapper' for our 'Block Design'. We can do it by selecting our 'system' block design in a 'Design Sources' list of 'Sources' window and 'Creat HDL wrapper' thru 'right' mouse click menu. Let Vivado manage it.
  25. zynq11_17

  26. Run Synthesis.
  27. Run Implementation.
  28. If we will try to generate Bitstream now it will fail, because we didn't set which of our ports goes to which Zynq pin. So, lets configure it now.
    Open implemented design.
  29. Now, we can manually create constraints file with settings for each pin or we can use Vivado GUI to generate constraints file. Let's use Vivado this time - open 'I/O Ports' window thru Vivado top level 'Window' menu.
  30. In 'I/O Ports' menu we have to select, so called, 'Site' for each port. 'Site' is Zynq package pin and we can find correlation between 'Sites' and PMOD pins of ZedBoard in ' ZedBoard Hardware User's Guide' from ZedBoard.com
  31. We also have to set 'I/O Standard' - which is supply level on a 'Site'.
  32. I2C ports also requires to be pulled-up and you can set 'Pull Type' for each 'Site' here, but it a very good idea to verify voltage/current requirements for your particular design, before you enable it.
  33. zynq11_17

  34. Save Project. Vivado will ask you for a name for a new constraints file. Let's call it 'zedboard_constraints.xdc' - below listing of that file in my case.
    Vivado will also detect changes in a project and will aks if you want to update Synthesis/Implementation or force it to accept changes without regeneration. Let's just regenerate whole thing just to be sure.
  35. set_property IOSTANDARD LVCMOS33 [get_ports iic_0_scl_io]
    set_property IOSTANDARD LVCMOS33 [get_ports iic_0_sda_io]
    set_property IOSTANDARD LVCMOS33 [get_ports iic_1_scl_io]
    set_property IOSTANDARD LVCMOS33 [get_ports iic_1_sda_io]
    set_property IOSTANDARD LVCMOS33 [get_ports spi_0_io0_io]
    set_property IOSTANDARD LVCMOS33 [get_ports spi_0_io1_io]
    set_property IOSTANDARD LVCMOS33 [get_ports spi_0_sck_io]
    set_property IOSTANDARD LVCMOS33 [get_ports spi_0_ss1_o]
    set_property IOSTANDARD LVCMOS33 [get_ports spi_0_ss2_o]
    set_property IOSTANDARD LVCMOS33 [get_ports spi_0_ss_io]
    set_property IOSTANDARD LVCMOS33 [get_ports UART_0_rxd]
    set_property IOSTANDARD LVCMOS33 [get_ports UART_0_txd]
    set_property IOSTANDARD LVCMOS33 [get_ports pwm0]
    set_property PULLUP true [get_ports iic_0_scl_io]
    set_property PULLUP true [get_ports iic_0_sda_io]
    set_property PULLUP true [get_ports iic_1_scl_io]
    set_property PULLUP true [get_ports iic_1_sda_io]
    set_property PACKAGE_PIN W12 [get_ports pwm0]
    set_property PACKAGE_PIN AB6 [get_ports UART_0_txd]
    set_property PACKAGE_PIN Y4 [get_ports UART_0_rxd]
    set_property PACKAGE_PIN W7 [get_ports iic_0_scl_io]
    set_property PACKAGE_PIN V7 [get_ports iic_0_sda_io]
    set_property PACKAGE_PIN Y11 [get_ports spi_0_io0_io]
    set_property PACKAGE_PIN AA11 [get_ports spi_0_io1_io]
    set_property PACKAGE_PIN Y10 [get_ports spi_0_sck_io]
    set_property PACKAGE_PIN AA9 [get_ports spi_0_ss1_o]
    set_property PACKAGE_PIN AB11 [get_ports spi_0_ss2_o]
    set_property PACKAGE_PIN AB10 [get_ports spi_0_ss_io]
    set_property PACKAGE_PIN V4 [get_ports iic_1_scl_io]
    set_property PACKAGE_PIN V5 [get_ports iic_1_sda_io]

  36. Generate Bitstream.
  37. Congratulations, you can now 'Export Hardware to SDK' and use it in software projects!