Vivado 2014.1 allows for the usage of .tcl scripts to regenerate projects.
To do this, with your project open, go File -> Write Project tcl.
Basic Projects
I usually store my sources and .tcl script in a location outside of the project directory. The xilinx IP cores generated within the project may be copied elsewhere by right clicking on the core and selecting "Copy IP". And deleting the original. When the tcl script is generated, it creates relative links to these files. This is usually what my directory structure looks like:
base_project/
srcs/
project.v
ip/
ip1/
ip1.xml
ip1.xci
genproject.tcl
Only the IP .xml and .xci files need to be committed. (And even this isn't necessary, technically, see notes at end).
This is what gets committed to git, note the lack of project.xpr or project directories.
When I run genproject.tcl
, it creates another directory for the project.
base_project/
srcs/
ip/
genproject.tcl
projectdir/
project.runs/
project.cache/
project.xpr
This new folder is completely disposable. In order to create this structure, I modify the tcl script in the following way.
I change the first 3 lines as follows:
# Set the reference directory for source file relative paths (by default the value is script directory path)
set origin_dir [file dirname [info script]]
# Set the directory path for the original project from where this script was exported
set orig_proj_dir "[file normalize "$origin_dir/projectdir"]"
# Create project
create_project project $projectdir/project
This creates a new project directory and the new project in that dir.
Then I modify the paths to point to the correct places. You may need to change these paths in other places in the script.
# Set 'sources_1' fileset object
set obj [get_filesets sources_1]
set files [list \
"[file normalize "$origin_dir/srcs/project.v"]"\
"[file normalize "$origin_dir/ip/ip1/ip1.xci"]"\
]
add_files -norecurse -fileset $obj $files
I also modify the design runs for IP cores as seen in this answer.
The .wcfg files can be included in a similar way to the ip and srcs.
This is where the processing ends for more simple projects (containing only sources and IP, no block diagrams). The following needs to also be done in order to store the block diagram data.
Block Diagram Projects
In order to save the block diagram, with the block diagram open, go File -> Export -> Block Diagram to Tcl, and save it in the same dir as the other tcl file.
Then I made a Generate_Wrapper.tcl
script which creates the block diagram wrapper files so you don't need to do that manually. The project/project.srcs folder is used to store the bd data, but it's still completely disposable, since the bd is stored in the tcl script. Save this with the other two.
set origin_dir [file dirname [info script]]
make_wrapper -files [get_files $origin_dir/project/project.srcs/sources_1/bd/design_1/design_1.bd] -top
add_files -norecurse -force $origin_dir/project/project.srcs/sources_1/bd/design_1/hdl/design_1_wrapper.v
update_compile_order -fileset sources_1
update_compile_order -fileset sim_1
At the end of my genproject.tcl
I add the following lines to generate the block diagram and wrappers:
source $origin_dir/Create_bd.tcl
source $origin_dir/Generate_Wrapper.tcl
regenerate_bd_layout
For projects with no source (just block diagram), my git commit is just the following:
base_project/
Generate_Wrapper.tcl
Create_Bd.tcl
genproject.tcl
In order to generate everything, run genproject.tcl
.
You can even combine all of these into one if you are particularly efficient, I haven't got round to that yet.
Custom Components: The component project
Another quick note on creating a custom component. If you have a component.xml, add that to your tcl sources list:
"[file normalize "$origin_dir/component.xml"]"\
And then also add the following section:
set file "$origin_dir/component.xml"
set file [file normalize $file]
set file_obj [get_files -of_objects [get_filesets sources_1] [list "*$file"]]
set_property "file_type" "IP-XACT" $file_obj
This includes the component design into the project for easy customisation.
Custom Components: Referencing your component
You can spacify your custom component repo path like this:
# Set IP repository paths
set obj [get_filesets sources_1]
set_property "ip_repo_paths" "[file normalize "$origin_dir/path/to/repository"]" $obj
In my repo folder, there are individual folders containing .xml files. So you're not referencing the folder containing the .xml, but the parent of that one. Eg:
repository/
component1/component1.xml
component2/component2.xml
How do we run these tcl scripts?
Open Vivado, and without opening any projects, select Tools -> Run TCL script, and navigate to your script.
Extra TCL notes
Every command you run in Vivado is shown in the tcl console as a tcl command. For example, when I generated a new Xilinx IP using the GUI, this came up in the tcl console:
create_ip -name floating_point -vendor xilinx.com -library ip -module_name floating_point_0
set_property -dict [list CONFIG.Operation_Type {Fixed_to_float} CONFIG.A_Precision_Type {Custom} CONFIG.C_A_Exponent_Width {38} CONFIG.C_A_Fraction_Width {0} CONFIG.Result_Precision_Type {Custom} CONFIG.C_Result_Exponent_Width {8} CONFIG.C_Result_Fraction_Width {16} CONFIG.Flow_Control {NonBlocking} CONFIG.Has_ARESETn {true}] [get_ips floating_point_0]
This means a couple of things:
You don't really even need to save xilinx ip cores - once they're the way you want them, copy the commands to the tcl script and you don't need to commit ip/ anymore.
specify the IP directory with the -dir argument after -module_name to put it wherever you'd like (in default it's in project.srcs).
Mostly anything you do in the GUI can be done in tcl, the easiest way to see how xilinx does stuff is to do it in the GUI and then look at what's in the TCL console afterwards.
This humongous pdf details all the vivado tcl commands.