Vivado generates a whole bunch of files when you create a project, and it’s not very clear on which are source files and which are generated files. The best approach is to consider them all to be generated files and to put none of them in version control. Instead, create a folder stucture for your sources that makes sense to you and use Tcl scripts to build the project and import the sources.

Vivado was designed to be completely Tcl driven. When you work in the GUI, you’ll probably notice that everything you do launches a Tcl command in the Tcl console at the bottom of the screen. This was a really nice design choice by Xilinx because it allows us to control the tools from scripts, thus allowing automation and proper version control.

Now just because we use scripts for good version control, doesn’t mean we have to give up the GUI. Vivado lets you generate a project from a script, work on it from the GUI and then save the project to a Tcl script form. It sounds simple, and it is, there are just a few things to understand first.

Example folder structure

Determine the folder/file structure that you want to use for the version controlled files. Here is the folder/file structure that I use for the designs that I put on Github (folders are in bold font):

  • Vivado
    • ip_repo
    • src
      • bd
        • design_1.tcl
      • hdl
    • build.tcl
    • build.bat

I call the top level folder Vivado to group together all the source files related to the Vivado project (some of my project repositories also have a folder for Python applications, EDK projects, etc). The “build.tcl” file is a Tcl script that will build the Vivado project from the sources. The “build.bat” file is a batch file that launches the build script. The “src” folder contains all the version controlled sources, such as VHDL and Verilog code, as well as scripts for generating parts of the project. The “bd” folder contains a script that generates the block design and is called from the “build.tcl” script. The “ip_repo” folder is generated by Vivado and contains version controlled sources for IP blocks used in the design.

How to generate a build script for a Vivado project

A template script for building a Vivado project can be generated from the GUI.

  1. Assuming you’ve created a project using the GUI – from the File menu, select ‘Write Project Tcl’.fpga_developer_20140801_150413
  2. Choose a name and location for the output Tcl script file. I generally use the name ‘build.tcl’ and locate it in the project folder.fpga_developer_20140801_150501

Now modify the build script!

The template script that is generated by Vivado serves as a good example, however it makes a few assumptions that don’t fit with the typical way you’d use a version controlled repository:

  1. The script assumes you want to create the project in the working directory (ie. the folder from which Vivado was run) and not the folder containing the build script. We’d typically want to check-out the sources in a new folder, run the build script and have the project generated in the new folder.
  2. The script assumes that you’ve version controlled the HDL wrapper and the block design (.bd) file, AND that they will be found at the same locations that Vivado put them in the original project. This doesn’t work if you want to regenerate the project in the folder containing the build script, because if your repository contains these files, located exactly as they were in the original project, the script fails, saying that the project files already exist. To make things worse, when it opens the block design (.bd) file, it modifies the date in the file, thus bringing it out of sync with version control when no design modification was actually made.

So the way around the first assumption is to replace these lines:

# Set the reference directory for source file relative paths
set origin_dir "."

# Set the directory path for the original project from where this script was exported
set orig_proj_dir "[file normalize "$origin_dir/orig-project"]"

# Create project
create_project myproject ./myproject

With these:

# Set the reference directory to where the script is
set origin_dir [file dirname [info script]]

# Create project
create_project myproject $origin_dir/myproject

The way around the second assumption is to generate the block design and the wrapper from a script.

Fortunately, we don’t have to write the script to generate the block design, Vivado can make the script for us. To generate the block design script in Vivado, with the block design open, select File->Export->Export block design.


Save this file in the “src/bd” folder and commit it to version control.

Now we can modify the “build.tcl” script to call the block design script and generate the HDL wrapper. At the end of the file, add the following lines:

# Create block design
 source $origin_dir/src/bd/design_1.tcl

 # Generate the wrapper
 set design_name [get_bd_designs]
 make_wrapper -files [get_files $] -top -import

Finally, you’ll have to remove the lines that import the HDL wrapper file and the block design (.bd) file into the project.

What files to commit to version control

In general, don’t commit anything within the project sub-folder that was created by Vivado. You want to keep ALL controlled sources including scripts out of that folder.

  1. Commit “build.tcl” (discussed above) to version control.
  2. Commit “src/bd/design_1.tcl” (discussed above) to version control.
  3. If you added any other sources to the design such as VHDL or Verilog files, make sure they are located in the “src/hdl” folder and commit these as well.
  4. If you created custom IP, you can commit all the files in the IP repository (ip_repo). The ip_repo folder should be at the same level as your “src” folder.

How to rebuild a Vivado project from the build script and sources

These steps assume that you’ve cloned the project repository to a new location (otherwise Vivado will try to regenerate the project files that already exist and it’ll produce an error message).

My preferred method is to run a batch file called “build.bat” that I commit to version control in the same location as the “build.tcl” file. The batch file should contain the following line:

C:\Xilinx\Vivado\2014.2\bin\vivado.bat -mode batch -source build.tcl

So from Windows Explorer I only need to double click on that batch file and Vivado generates the project files. Then I open the project in Vivado by double clicking on the generated .xpr file.

Just for completeness, here is one way to call the script from Vivado:

  1. From the welcome screen in Vivado, select Window->Tcl Console.fpga_developer_20140801_151113
  2. The Tcl console should open up at the bottom of the welcome screen.fpga_developer_20140801_151205
  3. In the Tcl console, where it says ‘Type a Tcl command here’, type the command ‘cd <location-of-your-project>’ and press ENTER to change the working directory to that of your project (the location of the build.tcl file).fpga_developer_20140801_151446
  4. Then in the Tcl console, type the command ‘source build.tcl’ and press ENTER to execute the build script.fpga_developer_20140801_151552

Vivado will then regenerate the project files and open them in the GUI.

Dealing with modifications

When you make modifications to the project using the GUI, always remember to save them by using the “Tools->Write Project Tcl” and “File->Export->Export block design” options.

Need an example?

For an example of how to version control a Vivado project, checkout this base system project that I’ve shared on Github:




Jeff is passionate about FPGAs, SoCs and high-performance computing, and has been writing the FPGA Developer blog since 2008. As the owner of Opsero, he leads a small team of FPGA all-stars providing start-ups and tech companies with FPGA design capability that they can call on when needed.

Facebook Twitter LinkedIn