In this post we will go over several guidelines for using revision control with Vivado projects. We will focus on block-design-, hdl- and IP-based designs using the Project Flow.
Revision control is critical in a professional development environment and can be very useful for personal projects as well. Vivado projects work well with revision control systems right out of the box, mainly because most of the project, block design and IP management files are text-based, which facilitates versioning, diff’s and merging. Still, it is advisable to adhere to a few guidelines to make the most out of revision control with Vivado. Let’s discuss those guidelines in detail.
Guideline #1: Use a remote directory structure for your design files
When we create a project, Vivado generates a directory structure alongside the project file, as shown in the figure below.
The default project directory will include the Vivado project file and will act as our working directory, so it is generally a bad idea to keep any design files here. Instead, we should create a separate directory structure to store all our design files. The one I like to use includes the following folders:
- bd, which contains all block design files
- constraints, which contains all constraint files
- hdl, which contains all RTL code
- hls, which contains all IP cores exported from Vitis HLS
- ip, which contains all packaged IP (Xilinx, custom, third party)
- output, which contains the products of the synthesis and implementation processes
- project, which contains the Vivado project file and will act as the working directory (i.e. where the tool runs)
- sim, which contains all testbench code and files
Guideline #2: Track only the Vivado project file (.xpr) to recreate a project
The only file required to recreate a Vivado project is the project file (.xpr). All other files in this directory are generated by Vivado during the development flow and should not be versioned (the Bonus Guideline contains some exceptions to this).
Guideline #3: Import all your design files from their remote location into your project
All design files should be imported from their original (so-called remote) locations outside the project folder and tracked from there. This is achieved by leaving the ‘Copy sources into project’ option unchecked when adding sources to the project.
Guideline #4: Track only the .xci file when working with Vivado IP
The Vivado IP definition files (xci) are XML-based and can be easily integrated into a revision control system, including support for merging and diff’s. It is important to keep each .xci file in its own folder because that is where Vivado will store all the output products for simulating and synthesizing the IP. It is not necessary to track any of the output products, the .xci file will allow us to regenerate the IP as long as we use the same versions of Vivado and the IP library with which the IP was created. If, on the other hand, a project is being archived, or the library/tool is being upgraded, it might be more convenient to track all the output products.
As an alternative to the IP definition files, it is possible to use the so-called core containers (.xcix), which can be enabled in the Vivado IDE. A core container will merge the xci files and all the output products for an IP into a single binary in the file system. From Vivado this will be completely transparent, all IP-related files will be visible as usual, with the advantage that a single file needs to be tracked. One major disadvantage, other than the larger file size, is that the core container must be opened with Vivado, and the revision control system will only be able to perform basic operations on it.
Guideline #5: Track only the block design (.bd) and the generated hdl wrapper files when working with block designs
Each block design in Vivado has an associated block design file (.bd). This is the only file needed to recreate a block design and must therefore be versioned. Though not essential, it is convenient to track the hdl wrapper (which can be generated by Vivado) as well. Each block design should have its own folder in the bd directory, even if there is just one block design in the project.
Tracking only the block design definition file is the ‘minimalist’ approach to revision control of block designs and comes with the advantage of having fewer files to track and taking less space in our revision control server. On the other hand, successfully regenerating the block design requires us to use the same versions of Vivado and the packaged IP that were used to create the block design. Furthermore, every time that a project is cloned/checked out, the output products must be regenerated.
Alternatively, it is possible to track all the generated files under the block design directory. This must be done after the output products for the block design have been generated, and it allows the block design to be recreated regardless of the version of Vivado and/or the IP cores (that is, Vivado will be able to upgrade the IP cores to a newer version). Moreover, the output products wouldn’t have to be regenerated each time a fresh copy of the project is downloaded. On the other hand, this approach requires more files to be tracked, which puts more pressure on the storage and bandwidth of your revision control infrastructure. Furthermore, using this approach demands discipline and consistency from all developers in a team, since committing out-of-date output products might produce inconsistent results when several people are working on the same project.
In summary, when it comes to tracking block designs in Vivado, I suggest using one of two options, depending on the project status:
- Is there development work actively being done in the block design, so that it is changing relatively frequently (say, more than once every week or two)? If so, it might be more convenient to track only the block design and hdl wrapper files.
- Are no further changes to the block design expected, or has the development work been finalized and the project is ready to be archived? Then it might be better to track all output products.
(Bonus) Guideline #6: Track your bitstream, hardware definition file and design checkpoints
The first five guidelines cover all input design files, but what about the outputs? Specially in the FPGA development flow, where generating a bitstream file from scratch can take anywhere from minutes to hours, it might be convenient to store a copy of the key files generated by the tool. These could include:
- The final bitstream file
- The hardware definition file (when applicable)
- The Vivado Design Checkpoints files (*.dcp) at various stages of the flow
- Post-synthesis
- Post-placement
- Post-routing
Different reports (timing, power, utilization, etc.) could also be tracked, but those can be generated from the design checkpoints if needed.
Now that we have defined a directory structure four our project, it would be great to set up a gitignore file to make sure only the relevant files are pushed to the Git repository. We will discuss this in the next post.
Cheers,
Isaac