When working with my Vivado FPGA projects, I’m always seeking a way that get my project be tracked by a VCS (Version Control System), such as Git. It’s easy to get hdl files (*.vh, *.v, *.sv, *.hdl) working with it since they are plain text file. But it not true with other Vivado files. Xilinx has a application note XAPP1165 discussing this topic. Here is how I handle with it.
Only Keep “Source Code”
The idea of version control is only keep the real “source code”, but leaves all generated files (by compiler, or other tools) ignored. This is not always practical, but always keep minimal files into VCS is good.
The git has .gitignore file to tell the tool which files are needed to be put into version control and which files are not. But before this, users need to know more about their files. Only a subset of these files require version control to recreate a project and reproduce implementation results. Usually a Vivado project utilize there files:
- RTL and netlist files, including Verilog, SystemVerilog, VHDL, and EDIF/DCP
- System Generator models (.mdl, .slx)
- IP-XACT core files (.xci, .mem, .coe, .xml)
- Vivado IP integrator block diagram files (.bd)
- Embedded subsystem (.xmp) and files (.elf, .bmm)
- Xilinx design constraint files (.xdc)
- Scripts for creating and compiling designs (.tcl)
- Configuration files, including Vivado simulator and Vivado logic analyzer configuration files (.wcfg)
Source code files should be well structed into folders and commit. All other files should be ignored, especially the design run files which are many and huge. You don’t want when you ask your teammate for code, they send you a ~GB archive in a USB stick. Or when you clone a FPGA repo, the tool tells you it need 12 hours to download all the files.
Separate Project Files with Source Code
Vivado has project files with file extension .xpr. It’s a XML file which records some information about file sets, runs, hardware debug sessions, etc. By default, source files are handle by Vivado and automatically placed into folder <project_name>.srcs at the same folder of .xpr file. All other runtime generated files are placed into <project_name>.sim, <project_name>.runs, etc.
If you are using the default folder struct Vivado created, you only need to keep .xpr and <project_name>.srcs folder. All other files can be ignored by VCS. If source file are placed at other place other than <project_name>.srcs , Vivado call it “remote source file”. The general recommendations for working with VCS is separate the project with source code, and does not include project files into VCS.
My practice is put all “source files” into a folder named src. And put Vivado project into another folder called prj. The prj folder is ignored by VCS, so it’s temporary working folder.
To recreate the project at another machine, I write a “create_project.tcl” script. It invoke some Vivado commands to create the project, set the project property and add the source files into project. The template of this tcl script can be generated by Vivado and managed it manually when project is updated. (In Vivado, click File > Project > Write Tcl…).
Cleanup Files Before Commit
Using IPs from Xilinx and other venders speed up your design and reduce your verification workload. The file for IP is .xci. Many files are generated when using the Vivado, such as encrypted/unencrypted hdl file, netlist, simulation netlist, stub file, instant template, OOC constraints, and much more. By default, they all placed in the same folder alone with .xci. In theory, they all can be ignored by VCS but only left .xci file. .xci “should” holds all information to recreate the IP and IP configuration in another machine.
But there is another file called <ip_name>.xml. It a generated file, but Vivado behavior strange if it does not find it. I face the problem of lost IP configuration when only .xci is placed into VCS sometimes, but seems it works well if .xml is added. So for IPs, .xci and .xml is added to VCS. Also .coe, .mem files if needed.
Note that you can have Vivado cleanup generated IP files for you, by right click IP and select “Reset Output Products”. After cleanup, only .xci and .xml are left. Do this every time before git commit.
Block Design Files
Block Design can speed up top level connection and provide better overall diagram of design. However, GUI design has less compatibility with version control. Also, it is not avoidable when design with ZYNQ process system. Similar with IP files, block design has extension of .bd and a .bxml file associate with it. Generated files block design is placed alone with .bd at same folder.
hdl folder holds hdl wrapper generated by Vivado, the wrapper it’s added to project automatically. So I put it into VCS. ip folder holds all the modules in block design. You can do similar with normal IPs. sim, synth, ui folder holds generated files of Block Design.
Note you can reset Block Design and contained IPs' generated files by right clock Block Design and select Reset Output Products. It also helps before git commit.
Vivado does not have native integration with a particular version control system. Instead, users need to handle it by themselves. Most of the files is ASCII-based so VCS can manage it better. But it’s still a problem that Vivado will update timestamp when files are not modified (unlike that XAPP1165 says). So sometimes the VCS will be fooled.
Also the XML format Vivado files is not human readable, so some tcl scripts are needed to recreate those files. For very large project that many people contribute to, refer to https://github.com/analogdevicesinc/hdl, it provide a good (but complex) example how to get it work with VCS.